diff --git a/composer.json b/composer.json index d36f905..1e0ad81 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ } }, "config": { - "vendor-dir": "htdocs/wp-content/vendor", + "vendor-dir": "html/wp-content/vendor", "allow-plugins": { "composer/installers": true } diff --git a/htdocs/wp-content/uploads/.gitkeep b/htdocs/wp-content/uploads/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/htdocs/wp-config-local-sample.php b/html/wp-config-local-sample.php old mode 100755 new mode 100644 similarity index 100% rename from htdocs/wp-config-local-sample.php rename to html/wp-config-local-sample.php diff --git a/htdocs/wp-config.php b/html/wp-config.php old mode 100755 new mode 100644 similarity index 100% rename from htdocs/wp-config.php rename to html/wp-config.php diff --git a/htdocs/wp-content/index.php b/html/wp-content/index.php similarity index 100% rename from htdocs/wp-content/index.php rename to html/wp-content/index.php diff --git a/htdocs/wp-content/mu-plugins/domain_mapping.php b/html/wp-content/mu-plugins/domain_mapping.php similarity index 100% rename from htdocs/wp-content/mu-plugins/domain_mapping.php rename to html/wp-content/mu-plugins/domain_mapping.php diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/css/chimpmatic-lite-deactivate.css b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/css/chimpmatic-lite-deactivate.css new file mode 100644 index 0000000..c81259d --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/css/chimpmatic-lite-deactivate.css @@ -0,0 +1,469 @@ +/** + * Deactivation survey modal styles. + * + * @package contact-form-7-mailchimp-extension + * @author renzo.johnson@gmail.com + * @copyright 2014-2026 https://renzojohnson.com + * @license GPL-3.0+ + */ + +:root { + --cmatic-modal-overlay-bg: rgba(0, 0, 0, 0.6); + --cmatic-modal-bg: #fff; + --cmatic-modal-max-width: 600px; + --cmatic-modal-border-radius: 8px; + --cmatic-modal-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); + --cmatic-primary-color: #0073aa; + --cmatic-primary-hover: #005a87; + --cmatic-secondary-color: #f0f0f1; + --cmatic-secondary-hover: #dcdcde; + --cmatic-text-color: #1e1e1e; + --cmatic-text-light: #646970; + --cmatic-border-color: #dcdcde; + --cmatic-error-color: #d63638; + --cmatic-success-color: #00a32a; + --cmatic-transition: all 0.3s ease; +} + +.cmatic-modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100000; + overflow-y: auto; +} + +.cmatic-modal--active { + display: flex; + align-items: center; + justify-content: center; +} + +.cmatic-modal--active .cmatic-modal__overlay { + animation: modalOverlayFadeIn 0.3s ease; +} + +.cmatic-modal--active .cmatic-modal__dialog { + animation: modalSlideUp 0.5s cubic-bezier(0.16, 1, 0.3, 1); +} + +@keyframes modalOverlayFadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes modalSlideUp { + from { opacity: 0; transform: translateY(100px); } + to { opacity: 1; transform: translateY(0); } +} + +.cmatic-modal--closing .cmatic-modal__overlay { + animation: modalOverlayFadeOut 0.3s ease; +} + +.cmatic-modal--closing .cmatic-modal__dialog { + animation: modalSlideDown 0.3s ease; +} + +@keyframes modalOverlayFadeOut { + from { opacity: 1; } + to { opacity: 0; } +} + +@keyframes modalSlideDown { + from { opacity: 1; transform: translateY(0); } + to { opacity: 0; transform: translateY(50px); } +} + +.cmatic-modal-open { + overflow: hidden; +} + +.cmatic-modal__overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: var(--cmatic-modal-overlay-bg); + z-index: -1; + backdrop-filter: blur(5px); +} + +.cmatic-modal__dialog { + position: relative; + max-width: var(--cmatic-modal-max-width); + width: 90%; + background: var(--cmatic-modal-bg); + border-radius: var(--cmatic-modal-border-radius); + box-shadow: var(--cmatic-modal-shadow); + margin: 20px auto; +} + +.cmatic-modal__header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 6px 24px; + border-bottom: 1px solid var(--cmatic-border-color); +} + +.cmatic-modal__header h2 { + margin: 0; + font-size: 16px; + font-weight: 600; + color: var(--cmatic-text-color); +} + +.cmatic-modal__header .button { + margin-left: auto; + margin-right: 12px; +} + +.cmatic-modal__close { + background: none; + border: none; + font-size: 28px; + line-height: 1; + color: var(--cmatic-text-light); + cursor: pointer; + padding: 0; + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + transition: var(--cmatic-transition); +} + +.cmatic-modal__close:hover, +.cmatic-modal__close:focus { + background: var(--cmatic-secondary-color); + color: var(--cmatic-text-color); +} + +.cmatic-modal__body { + padding: 24px; + max-height: calc(100vh - 300px); + overflow-y: auto; +} + +.cmatic-modal__body > h3 { + margin: 0 0 20px; + font-size: 16px; + font-weight: 600; + color: var(--cmatic-text-color); +} + +.cmatic-reasons { + display: flex; + flex-direction: column; + gap: 12px; +} + +.cmatic-reason-btn { + background: linear-gradient(135deg, #f5f7fa 0%, #f8f9fa 100%); + border: 2px solid transparent; + padding: 16px 20px; + border-radius: 12px; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + font-size: 14px; + color: var(--cmatic-text-color); + text-align: left; + font-family: inherit; + width: 100%; + line-height: 1.5; + position: relative; + overflow: hidden; +} + +.cmatic-reason-btn:hover { + background: linear-gradient(135deg, #e8f0fe 0%, #f1f8ff 100%); + border-color: #f0f6fc; +} + +.cmatic-reason-btn.selected { + background: linear-gradient(135deg, #f0f6fc 0%, #f0f6fc 100%); + border-color: #d8dde3; + color: var(--cmatic-text-color); + font-weight: 500; + box-shadow: 0 6px 16px rgba(26, 115, 232, 0.3); +} + +.cmatic-reason-btn:focus-visible { + outline: 2px solid var(--cmatic-primary-color); + outline-offset: 2px; +} + +.cmatic-input-wrapper { + margin-top: 12px; + animation: slideDown 0.3s ease; +} + +@keyframes slideDown { + from { opacity: 0; transform: translateY(-10px); } + to { opacity: 1; transform: translateY(0); } +} + +.cmatic-input-field { + width: 100%; + padding: 10px 14px; + border-radius: 6px; + font-size: 14px; + font-family: inherit; +} + +.cmatic-input-field:focus { + outline: none; +} + +.cmatic-input-field[type="text"] { + display: block; +} + +select.cmatic-input-field { + cursor: pointer; + appearance: none; + background-color: #fff; + background-image: url(data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23646970' d='M6 9L1 4h10z'/%3E%3C/svg%3E); + background-repeat: no-repeat; + background-position: right 14px center; + background-size: 12px; + padding-right: 40px; +} + +.cmatic-char-counter { + margin-top: 4px; + font-size: 12px; + color: var(--cmatic-text-light); + text-align: right; +} + +.cmatic-error-message { + display: none; + margin-top: 16px; + padding: 12px; + background: #fcf0f1; + border: 1px solid var(--cmatic-error-color); + border-radius: 4px; + color: var(--cmatic-error-color); + font-size: 14px; +} + +.cmatic-error-message--visible { + display: block; +} + +.cmatic-modal__footer { + display: flex; + align-items: center; + justify-content: space-between; + flex-direction: row; + padding: 20px 24px; + border-top: 1px solid var(--cmatic-border-color); + gap: 16px; +} + +.cmatic-modal__footer .button { + margin-left: auto; +} + +.cmatic-skip-link { + color: var(--cmatic-text-light); + font-size: 13px; + text-decoration: none; + cursor: pointer; + transition: color 0.2s ease; + padding: 4px 8px; +} + +.cmatic-skip-link:hover { + color: var(--cmatic-text-color); + text-decoration: underline; +} + +@media (max-width: 640px) { + .cmatic-modal__dialog { + width: 95%; + margin: 10px auto; + } + + .cmatic-modal__header, + .cmatic-modal__body, + .cmatic-modal__footer { + padding: 16px; + } + + .cmatic-modal__footer { + flex-direction: column; + gap: 12px; + } + + .cmatic-modal__footer .button { + width: 100%; + order: 1; + } + + .cmatic-skip-link { + order: 2; + margin-top: 8px; + } + + .cmatic-reason-btn { + padding: 14px 16px; + } + + .cmatic-reasons { + gap: 10px; + } +} + +.cmatic-modal__footer .button:focus-visible { + outline: 2px solid var(--cmatic-primary-color); + outline-offset: 2px; +} + +@media (prefers-contrast: high) { + .cmatic-modal__dialog { + border: 2px solid currentcolor; + } +} + +@media (prefers-reduced-motion: reduce) { + * { + transition: none !important; + } +} + +/* ========================================================================== + Submission Feedback + ========================================================================== */ + +.cmatic-modal__feedback { + display: flex; + align-items: flex-start; + gap: 12px; + padding: 16px; + margin-bottom: 16px; + border-radius: 8px; + background: #f0f6fc; + border: 1px solid #c3c4c7; +} + +.cmatic-modal__feedback-icon { + flex-shrink: 0; + width: 24px; + height: 24px; +} + +.cmatic-modal__feedback-icon .dashicons { + font-size: 24px; + width: 24px; + height: 24px; +} + +.cmatic-modal__feedback-content { + flex: 1; + min-width: 0; +} + +.cmatic-modal__feedback-title { + font-weight: 600; + font-size: 14px; + color: var(--cmatic-text-color); + margin-bottom: 4px; +} + +.cmatic-modal__feedback-details { + font-size: 13px; + color: var(--cmatic-text-light); +} + +/* Sent vs Received comparison table */ +.cmatic-modal__feedback-table { + width: 100%; + border-collapse: collapse; + margin-top: 10px; + font-size: 13px; +} + +.cmatic-modal__feedback-table th, +.cmatic-modal__feedback-table td { + padding: 6px 10px; + text-align: left; + border-bottom: 1px solid #e0e0e0; +} + +.cmatic-modal__feedback-table th { + background: rgba(0, 0, 0, 0.03); + font-weight: 600; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--cmatic-text-light); +} + +.cmatic-modal__feedback-table .field-key { + font-weight: 600; + color: var(--cmatic-text-color); +} + +.cmatic-modal__feedback-table .field-empty { + color: #999; + font-style: italic; +} + +.cmatic-modal__feedback-table .field-mismatch { + background: #fff8e5; +} + +.cmatic-modal__feedback-table .field-mismatch td { + border-bottom-color: #f0c36d; +} + +/* Success state */ +.cmatic-modal__feedback--success { + background: #edfaef; + border-color: var(--cmatic-success-color); +} + +.cmatic-modal__feedback--success .cmatic-modal__feedback-icon .dashicons { + color: var(--cmatic-success-color); +} + +.cmatic-modal__feedback--success .cmatic-modal__feedback-title { + color: #006d1b; +} + +/* Error state */ +.cmatic-modal__feedback--error { + background: #fcf0f1; + border-color: var(--cmatic-error-color); +} + +.cmatic-modal__feedback--error .cmatic-modal__feedback-icon .dashicons { + color: var(--cmatic-error-color); +} + +.cmatic-modal__feedback--error .cmatic-modal__feedback-title { + color: #8a1f1f; +} + +/* Skipped state */ +.cmatic-modal__feedback--skipped { + background: #fff8e5; + border-color: #dba617; +} + +.cmatic-modal__feedback--skipped .cmatic-modal__feedback-icon .dashicons { + color: #996800; +} + +.cmatic-modal__feedback--skipped .cmatic-modal__feedback-title { + color: #614200; +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/css/chimpmatic-lite.css b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/css/chimpmatic-lite.css new file mode 100644 index 0000000..8529e34 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/css/chimpmatic-lite.css @@ -0,0 +1,1559 @@ +/** + * Admin panel styles. + * + * @package contact-form-7-mailchimp-extension + * @author renzo.johnson@gmail.com + * @copyright 2014-2026 https://renzojohnson.com + * @license GPL-3.0+ + */ + +.chimpmatic-lite { + #contact-form-editor-tabs { + border-color: #b5bec7; + } + + section#Chimpmatic { + .metabox-holder { + padding: 0; + } + } +} + +#contact-form-editor-tabs { + #Chimpmatic-tab[aria-selected="true"] { + background-color: #fff; + } +} + +.chimpmatic-lite { + section#Chimpmatic { + border-color: #b5bec7; + padding: 0; + background-color: #f2f4f6; + } +} + +.cmatic-content { + padding: 0 20px; +} + +.cmatic-field-group { + background-color: rgba(255, 255, 255, .95); + border: 1px solid #e5e5e5; + border-radius: 8px; + margin-bottom: 20px; + padding: 12px 20px 20px; +} + +.cmatic-panel-toggles, +.mce-custom-fields { + background-color: rgba(255, 255, 255, .95); + border: 1px solid #e5e5e5; + border-radius: 8px; + padding: 12px 20px 20px; + box-shadow: 0 1px 1px rgba(0, 0, 0, .04); + margin-bottom: 20px; +} + +.cmatic-panel-toggles { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +#chimpmatic-lite-panel .highlight { + color: #999; + padding: 9px 20px; + margin-bottom: 14px; + background-color: #fafafc; + border: 1px solid #e1e1e8; + border-radius: 4px; +} + +#chimpmatic-lite-panel .highlight, +#chimpmatic-lite-panel pre, +#chimpmatic-lite-panel pre code { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} + +#chimpmatic-lite-panel pre code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + word-break: normal; + white-space: pre-wrap; + line-height: 1.42857143; +} + +#chimpmatic-lite-panel .button { + padding: 0 25px; +} + +#cmatic-api { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} + +#chimpmatic-lite-panel #cme-container th { + width: 170px; +} + +.description p { + font-size: 12px !important; + line-height: 1.25em !important; + margin-top: 0 !important; + font-style: italic !important; +} + +.mc-code { + font-size: 11px; + color: #999; + display: block; +} + +#MailChimp-Extension { + position: relative; +} + +.mce-main-fields { + position: relative; +} + +.mce-container { + padding: 16px; +} + +.mce-container small { + font-style: italic; +} + +.postbox-inner { + padding: 5px 20px; +} + +#cme-container .form-table th { + width: 200px; + padding: 19px 10px 10px 0; +} + +#cme-container .form-table td { + padding-bottom: 10px; +} + +#cme-container.vc-advanced-settings .form-table th { + width: 150px; +} + +.cm-form-table { + padding-top: 20px; + margin-top: 20px; +} + +.cm-form-table th, +.cm-form-table td { + padding: 8px 5px; +} + +.wp-core-ui .cm-submit { + background-color: #460479; + border: 1px solid #6f1a3f; + color: #fff; + width: 100%; + margin-bottom: 8px; + padding: 1px 5px; + font-size: 24px; + border-radius: 53px; + transition: all 0.4s ease-in-out; + text-align: center; +} + +.wp-core-ui .cm-submit:hover { + background-color: #ee3455; + border-color: #ee3455; + color: #fff; +} + +li#chimpmatic-lite-panel-tab, +#chimpmatic-lite-panel-tab { + border-top: 1px solid #01b7ff; + background: rgba(255, 255, 255, 0.5) url(../images/postal-marks.png) center top no-repeat; +} + +.mc-lateral { + box-shadow: 0 0 0 1px rgba(200, 215, 225, .5), 0 1px 2px #e9eff3; +} + +.contact-form-editor-panel .mc-lateral { + display: none; +} + +.mc-lateral::after { + content: ''; + display: table; + clear: both; +} + +.metabox-holder .mc-lateral h3 { + font-size: 19px; + padding: 25px 15px 13px !important; + background-color: #f9f9f9; + text-align: center; + color: #000; +} + +.metabox-holder .mc-lateral h3::before { + display: block; + position: absolute; + right: 0; + left: 0; + background-size: 70px 9px; + width: 100%; + height: 9px; + content: ''; + top: -1px; + z-index: 2; +} + +.metabox-holder .mc-lateral .inside { + padding: 0 15px 25px !important; + margin-top: 0; +} + +.holder-img { + position: relative; + background-color: rgba(0, 0, 0, 0.05); +} + +.holder-img img { + display: block; + max-width: 100%; +} + +.audience-name a { + text-decoration: none; +} + +.lin-to-pro { + position: absolute; + width: 100%; + height: 100%; + z-index: -99; + text-align: center; + text-decoration: none; + background-color: rgba(0, 0, 0, 0.45); + box-sizing: border-box; + opacity: 0; + color: #fff !important; + border-radius: 3px; +} + +.lin-to-pro span { + margin: auto; + padding: 1rem 3rem; + text-align: center; + font-size: 4em; +} + +.lin-to-pro span span { + display: block; + margin-top: 25px; + background: #00be28; + border: 1px solid #00a523; + border-width: 1px 1px 2px; + padding: 5px 20px; + border-radius: 3px; + font-size: 14px; + line-height: 21px; + font-weight: 500; +} + +.holder-img:hover .lin-to-pro { + top: 0; + left: 0; + z-index: 999; + opacity: 1; + display: flex; +} + +.mce-main-fields, +.cmatic-field-group { + .description { + display: block; + color: #777; + padding-left: 0.7em; + } +} + +.need-api { + margin-bottom: 10px; +} + +#cmatic-fields label { + display: inline-block; + vertical-align: bottom; +} + +#wpcf7-mailchimp-list { + max-width: unset; +} + +.chm-select { + margin-bottom: 7px; +} + +.atags { + display: block; +} + +.mcee-container label { + display: block; + margin-bottom: 5px; +} + +.mcee-container .glocks { + display: inline-block; + margin-left: 8px; + vertical-align: middle; +} + +.atags { + margin-top: 20px; +} + +.atags input { + width: 90% !important; + margin-top: 5px; +} + +.cm-form { + display: block; + width: 100%; +} + +.cm-form input { + max-width: 100%; + margin-bottom: 10px; +} + +.cm-pricing { + text-align: center; + display: block; + width: 100%; +} + +.a-support { + color: #222; + background: #f7f7f7; + box-shadow: inset 0 1px 0 #fff, 0 1px 0 rgba(0, 0, 0, .08); + vertical-align: top; + display: inline-block; + text-decoration: none; + font-size: 13px; + line-height: 26px; + height: 28px; + margin: 0; + padding: 0 10px 1px; + cursor: pointer; + border: 1px solid #ccc; + border-radius: 3px; + white-space: nowrap; + box-sizing: border-box; +} + +ul#contact-form-editor-tabs>li a:focus, +.a-support:focus, +a.helping-field { + outline: none; + box-shadow: none; +} + +.a-support:focus { + color: #0073aa; +} + +.a-support::after { + right: 0; + content: '\f333'; + font: 400 20px/1 dashicons; + speak: none; + display: inline-block; + padding: 3px 0 0 5px; + bottom: 2px; + position: relative; + vertical-align: bottom; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; + color: #0073aa; +} + +.donate { + border: 1px solid #46b450 !important; + background-color: #46b450 !important; + display: inline-block; + padding: 3px 10px; + text-decoration: none; + color: #fff; + border-radius: 3px; + border-color: #43ab4b #3c9943 #3c9943 !important; + box-shadow: 0 2px 0 #3c9943 !important; + text-shadow: 0 -1px 1px #3c9943, 1px 0 1px #3c9943, 0 1px 1px #3c9943, -1px 0 1px #3c9943 !important; +} + +.donate:hover { + background-color: #4cc255; + color: #fff; +} + +.donate-2019 { + font-size: 17px; + position: absolute; + right: 15px; + top: 0; + padding: 5px 30px 3px !important; + letter-spacing: 1px; +} + +.dops-button { + background: #fff; + border: solid #d5d5d5; + border-width: 1px 1px 2px; + color: #414141; + cursor: pointer; + display: inline-block; + margin: 0; + outline: 0; + overflow: hidden; + font-weight: 500; + text-overflow: ellipsis; + text-decoration: none; + vertical-align: top; + box-sizing: border-box; + font-size: 14px; + line-height: 21px; + border-radius: 4px; + padding: 7px 14px 9px; + appearance: none; +} + +.dops-button.is-primary { + background: #00be28; + border-color: #00a523; + color: #fff; + padding: 5px 20px; + margin-top: 15px; + margin-bottom: 15px; + float: right; +} + +.dops-button.is-primary:hover { + background: #00a523; + border-color: #008b1d; +} + +span.chmm { + font-size: 14px; + line-height: 1.2em; + margin-left: 1em; + border-radius: 3px; +} + +span.chmm .dashicons, +span.chmm .dashicons-no { + line-height: 1.37em; +} + +span.valid { + background-color: #46b450; + color: #fff; +} + +span.invalid { + background-color: #dd3d36; + color: #fff; +} + +.misc-pub-section.chimpmatic-info { + line-height: 1.6; +} + +.chimpmatic-info .chmm { + font-weight: 500; + font-size: 13px; + margin-left: 0; +} + +.chimpmatic-info .chmm.valid { + color: #00a32a; + background-color: transparent; +} + +.chimpmatic-info .chmm.invalid { + color: #d63638; + background-color: transparent; +} + +.chimpmatic-info .mc-stats { + font-family: Monaco, Consolas, monospace; + font-size: 12px; +} + +.mc-tool-activated { + background-color: #00be28 !important; + color: #fff !important; + font-size: 13px; +} + +.mc-tool-not-activated { + background-color: #dd3d36 !important; + color: #fff !important; + font-size: 13px; +} + +.mce-red, +.mce-required { + color: #dd3d36; + font-weight: 400; +} + +.mce-type { + color: #999 !important; +} + +.cm-lite { + color: #121212; + font-size: 0.87em; + background-color: rgba(255, 255, 255, 0.85); + border-radius: 3px; + padding: 0 10px; + box-shadow: inset 0 0 3px rgba(0, 0, 0, .15); + transition: all 0.4s ease-in-out; + display: inline-block; +} + +.cm-lite.cm-status-neutral { + color: #646970; + background-color: rgba(255, 255, 255, 0.85); + border: 1px solid #dcdcde; +} + +.cm-lite.cm-status-connected { + color: #fff; + background-color: #00a32a; + border: 1px solid #008a20; + box-shadow: 0 0 8px rgba(0, 163, 42, 0.4); + animation: badge-pulse 0.6s ease-in-out; +} + +.cm-lite.cm-status-error { + color: #fff; + background-color: #d63638; + border: 1px solid #b32d2e; + box-shadow: 0 0 8px rgba(214, 54, 56, 0.4); + animation: badge-pulse 0.6s ease-in-out; +} + +.cmatic-out { + display: none; +} + +@keyframes badge-pulse { + 0% { transform: scale(1); } + 50% { transform: scale(1.05); } + 100% { transform: scale(1); } +} + +.promo-2022 { + padding: 15px; + background-color: #f0f4f5; +} + +.promo-2022 h1 { + text-align: center; + font-size: 43px; + font-weight: 900; + display: block; + clear: both; + color: #ee3455; + margin: 0 0 0.2407911001em; + background-image: linear-gradient(to right, #ee3455 0%, #bb2c6b 50%, #460479 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + -webkit-box-decoration-break: clone; +} + +.promo-2022 h1 span { + font-size: 35px; +} + +.dev-cta { + margin-top: 35px; + padding: 40px 10px 30px; + border: 1px solid #efefef; + background: unset; +} + +.dev-cta::before { + display: block; + position: absolute; + right: 0; + left: 0; + background: #fff url(../images/newsletter-stripe.svg) repeat-x; + background-size: 70px 9px; + width: 100%; + height: 9px; + content: ''; + top: 0; + z-index: 2; +} + +.dev-cta .welcome-panel-content { + padding-left: 9em; + min-height: unset; +} + +.dev-cta .welcome-panel-content::before { + content: "\f488"; + color: #ddd; + display: inline-block; + position: absolute; + z-index: 1; + left: 0; + top: 50%; + margin-top: -0.5em; + font-size: 7em; + line-height: 1; + font-family: dashicons; + text-decoration: inherit; + font-weight: 400; + font-style: normal; + vertical-align: top; + text-align: center; + transition: color .1s ease-in 0; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.bg-f2 { + display: block; + margin-top: 0 !important; + background-color: #1a212b; +} + +.bg-f2 * { + color: #fff !important; +} + +.bg-f2::before, +.bg-f2::after { + content: ' '; + display: table; + width: 100%; + clear: both; +} + +.bg-f2 ul { + list-style-type: square; + list-style-position: inside; + list-style-image: none; +} + +.metabox-holder .bg-f2 h3 { + background-color: transparent !important; + padding: 10px 0 10px !important; + font-size: 25px; + font-weight: 900; + margin-bottom: 0; + letter-spacing: 1px; +} + +.vc-notice { + position: relative; + z-index: 0; + padding-top: 32px; + padding-bottom: 22px; + background-color: #fff; +} + +.vc-notice h2 { + color: #000; +} + +.vc-notice::before { + display: block; + position: absolute; + right: 0; + left: 0; + background: #fff url(../images/newsletter-stripe.svg) repeat-x; + background-size: 70px 9px; + width: 100%; + height: 9px; + content: ''; + top: 0; +} + +.vc-notice .welcome-panel-content { + position: relative; + z-index: 2; + justify-content: initial; + min-height: unset; +} + +.vc-notice .welcome-panel-column-container { + grid-template-columns: repeat(2, 1fr); + margin-top: 0; + padding: 0; +} + +.vc-notice .welcome-panel-column { + background-color: #f6f6f6; + display: block; + padding: 15px 20px; +} + +.vc-notice .welcome-panel-column>* { + display: block; +} + +.vc-notice::after { + content: "\f488"; + color: #ddd; + display: inline-block; + position: absolute; + z-index: 1; + right: 5%; + bottom: 10%; + font-size: 7em; + transform: scaleX(-1); + filter: fliph; + line-height: 1; + font-family: dashicons; + text-decoration: inherit; + font-weight: 400; + font-style: normal; + vertical-align: top; + text-align: center; + transition: color .1s ease-in 0; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.vc-advanced-settings, +.vc-logs { + display: none; +} + +.vc-logs .mce-custom-fields { + background: #0d1b2a; + font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', 'Droid Sans Mono', 'Source Code Pro', monospace; + font-size: 12px; + color: #e0e1dd; + border-radius: 6px; + padding: 0; + overflow: hidden; +} + +.vc-logs .vc-logs-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 16px; + border-bottom: 1px solid #1b2838; + background: #0a1628; +} + +.vc-logs .vc-logs-title { + color: #778da9; + font-weight: 500; + font-size: 12px; +} + +.vc-logs .vc-logs-actions { + display: flex; + gap: 8px; + align-items: center; +} + +.vc-logs .vc-logs-separator { + color: #415a77; + font-size: 12px; +} + +.vc-logs .vc-toggle-filter { + color: #00a32a; + text-decoration: none; + font-size: 12px; +} + +.vc-logs .vc-toggle-filter:hover { + color: #00c853; + text-decoration: underline; +} + +.vc-logs .vc-clear-logs { + color: #e63946; + text-decoration: none; + font-size: 12px; +} + +.vc-logs .vc-clear-logs:hover { + color: #ff6b6b; + text-decoration: underline; +} + +.vc-logs .mce-custom-fields pre { + margin: 0; + padding: 16px; + background: transparent; + overflow-x: auto; + max-height: 400px; + overflow-y: auto; + white-space: pre-wrap; + word-wrap: break-word; +} + +.vc-logs .mce-custom-fields code { + background: transparent; + color: #e0e1dd; + font-family: inherit; + font-size: inherit; +} + +#chimpmatic-response { + background-color: rgba(0, 0, 0, 0.05); +} + +#chimpmatic-response h5 { + font-size: 15px; + margin-bottom: 0; +} + +#chimpmatic-response ul { + margin-top: 10px; +} + +div#plugin-information, +div#section-holder { + padding-right: 10px; +} + +#plugin-information .section, +#section-holder .section { + overflow: hidden; +} + +#plugin-information .section img, +#section-holder .section img { + position: relative; + max-width: 100%; +} + +.blue, +.spartan-blue { + color: #0073aa; +} + +.red-icon { + color: #dd3d36; +} + +.reds { + color: #ff4500 !important; + font-weight: 900 !important; +} + +.anew { + color: #ff4500; + font-weight: 800; +} + +.smiles { + font-weight: 700; + font-style: normal; +} + +.pr10 { + padding-right: 10px; +} + +.mt0 { + margin-top: 0; +} + +.vc-hidden-start, +.to-hide { + display: none; +} + +.chmp-inactive { + display: none; + height: 0; + width: 100%; +} + +.chmp-inactive::before .chmp-inactive::after { + content: ''; + display: table; + clear: both; +} + +.chmp-active { + display: block; + height: auto; +} + +.chm-titles { + margin-bottom: 0.15em; +} + +.chm-legend { + margin-bottom: 0.45em; +} + +.mce-support { + border-top: 1px solid rgba(0, 0, 0, 0); +} + +.p-hr-s { + margin-top: 0.5rem; + height: 0.5rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.05); +} + +a.helping-field { + font-weight: 700; + padding-left: 4px; + padding-right: 20px; + text-decoration: none; +} + +a.helping-hand:hover, +a.helping-field:hover, +a.helping-field:hover .red-icon::before { + color: #444; +} + +#chm_panel_principal .spinner, +.mce-custom-fields .spinner { + float: none; + margin-top: 0; +} + +.cmatic-api-wrap { + position: relative; + display: inline-block; + width: 364px; +} + +.cmatic-api-wrap input { + padding-right: 30px; + width: 100%; + box-sizing: border-box; +} + +.cmatic-eye { + position: absolute; + right: 5px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + padding: 0; + cursor: pointer; + color: #a7aaad; +} + +.cmatic-api-wrap input:not(:placeholder-shown) + .cmatic-eye { + color: #3c434a; +} + +.cmatic-eye:hover { + color: #1d2327; +} + +.cmatic-audiences select { + width: 364px; +} + +#chm_activalist, +#mce_fetch_fields { + min-width: 160px; +} + +@media only screen and (min-width: 768px) { + .mcee-container { + display: inline-block; + width: 49.5%; + box-sizing: border-box; + padding-right: 2rem; + margin-bottom: 1.25rem; + } + + .mcee-container > div[id^="gg-select"], + .mcee-container > div[id^="GDPR-select"] { + width: 100%; + } + + .mcee-container select { + margin-top: 0; + margin-bottom: 0; + width: 100%; + max-width: 100%; + } + + .mce-custom-fields .md-half { + display: inline-block; + width: 49%; + vertical-align: top; + } +} + +.cmatic-header { + background: #fff; + border-bottom: 1px solid #c5d1d9; + margin: 0 0 20px 0; +} + +.cmatic-header__inner { + display: flex; + align-items: center; + justify-content: space-between; + padding: 14px 20px; +} + +.cmatic-header__brand { + display: flex; + align-items: center; + gap: 10px; +} + +.cmatic-header__title { + font-size: 18px; + font-weight: 600; + color: #1d2327; + letter-spacing: -0.3px; +} + +.cmatic-header__badge { + font-size: 10px; + font-weight: 700; + padding: 3px 8px; + border-radius: 4px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.cmatic-header__badge--pro, +.cmatic-header__badge--lite { + background: #4d5d6d; + color: #fff; +} + +.cmatic-header__version { + font-size: 12px; + color: #646970; + font-weight: 400; +} + +.cmatic-header__actions { + display: flex; + align-items: center; +} + +.cmatic-header__review { + display: flex; + align-items: center; + gap: 8px; + color: #646970; + text-decoration: none; + font-size: 13px; + transition: color 0.2s; +} + +.cmatic-header__review:hover { + color: #1d2327; +} + +.cmatic-sparkles { + display: inline-block; + vertical-align: middle; + margin-left: 6px; + width: 80px; + height: 16px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 16'%3E%3Cpath fill='%23EFBF04' d='M8 0l2.5 5 5.5.8-4 3.9.9 5.3L8 12.5 3.1 15l.9-5.3-4-3.9L5.5 5zM24 0l2.5 5 5.5.8-4 3.9.9 5.3-4.9-2.5-4.9 2.5.9-5.3-4-3.9 5.5-.8zM40 0l2.5 5 5.5.8-4 3.9.9 5.3-4.9-2.5-4.9 2.5.9-5.3-4-3.9 5.5-.8zM56 0l2.5 5 5.5.8-4 3.9.9 5.3-4.9-2.5-4.9 2.5.9-5.3-4-3.9 5.5-.8zM72 0l2.5 5 5.5.8-4 3.9.9 5.3-4.9-2.5-4.9 2.5.9-5.3-4-3.9 5.5-.8z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-size: contain; +} + +.cmatic-header__status { + display: flex; + align-items: center; + gap: 6px; + margin-left: 12px; + padding-left: 12px; + border-left: 1px solid #c5d1d9; +} + +.cmatic-header__status-dot { + width: 8px; + height: 8px; + border-radius: 50%; +} + +.cmatic-header__status-dot--connected { + background: #00a32a; +} + +.cmatic-header__status-dot--disconnected { + background: #d63638; +} + +.cmatic-header__status-text { + font-size: 12px; + color: #646970; +} + +.cmatic-tags-grid { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 18px; +} + +.cmatic-tag-chip { + display: inline-flex; + align-items: center; + gap: 6px; + /* padding: 4px 10px; */ + border: 1px solid #c3c4c7; + border-radius: 25px; + background: #f6f7f7; + cursor: pointer; + font-size: 12px; + transition: all 0.15s ease; + user-select: none; + color: #50575e; + line-height: 1em; +} + +.cmatic-tag-chip:hover { + border-color: #2271b1; + background: #f6f7f7; +} + +.cmatic-tag-chip input[type="checkbox"] { + display: none; +} + +.cmatic-tag-chip.selected { + background: #f0f6fc; + border-color: #2271b1; + color: #2271b1; +} + +.cmatic-tag-name { + font-weight: 500; + font-family: monospace; +} + +.cmatic-tag-type { + font-size: 9px; + text-transform: uppercase; + font-weight: 600; + padding: 2px 2px; + border-radius: 15px; + letter-spacing: 0.3px; + color: #000; +} + +.cmatic-toggle { + position: relative; + display: inline-block; + width: 44px; + height: 24px; + vertical-align: middle; +} + +.cmatic-toggle input { + opacity: 0; + width: 0; + height: 0; +} + +.cmatic-toggle-slider { + position: absolute; + cursor: pointer; + inset: 0; + background: #c3c4c7; + border-radius: 24px; + transition: .3s; +} + +.cmatic-toggle-slider:before { + content: ""; + position: absolute; + height: 18px; + width: 18px; + left: 3px; + bottom: 3px; + background: #fff; + border-radius: 50%; + transition: .3s; +} + +.cmatic-toggle input:checked + .cmatic-toggle-slider { + background: #2271b1; +} + +.cmatic-toggle input:checked + .cmatic-toggle-slider:before { + transform: translateX(20px); +} + +.cmatic-toggle.is-saving .cmatic-toggle-slider { + opacity: 0.6; + cursor: wait; +} + +.cmatic-toggle-label { + margin-left: 10px; + vertical-align: middle; + color: #1d2327; + font-size: 12px; + font-weight: normal; +} + +.cmatic-toggle-row { + display: flex; + align-items: center; + gap: 10px; +} + +.cmatic-title-with-toggle { + display: flex; + justify-content: space-between; + align-items: center; +} + +.cmatic-help-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 16px; + height: 16px; + font-size: 11px; + font-weight: 600; + color: #646970; + background: #f0f0f1; + border-radius: 50%; + text-decoration: none; + line-height: 1; +} + +.cmatic-help-icon:hover { + color: #2271b1; + background: #f0f6fc; +} + +.cmatic-test-form-wrap { + padding: 16px; + background: #fafafa; + border: 1px solid #dcdcde; + border-radius: 4px; +} + +.cmatic-test-form-wrap .wpcf7 { + max-width: 100%; +} + +.cmatic-test-form-wrap .wpcf7-form-control-wrap { + display: block; + margin-bottom: 12px; +} + +.cmatic-test-form-wrap input[type="text"], +.cmatic-test-form-wrap input[type="email"], +.cmatic-test-form-wrap input[type="tel"], +.cmatic-test-form-wrap input[type="url"], +.cmatic-test-form-wrap input[type="number"], +.cmatic-test-form-wrap input[type="date"], +.cmatic-test-form-wrap textarea, +.cmatic-test-form-wrap select { + width: 100%; + max-width: 100%; +} + +.cmatic-test-form-wrap input[type="submit"] { + background: #2271b1; + border-color: #2271b1; + color: #fff; + padding: 8px 20px; + font-size: 14px; + border-radius: 4px; + cursor: pointer; + transition: background 0.15s; +} + +.cmatic-test-form-wrap input[type="submit"]:hover { + background: #135e96; + border-color: #135e96; +} + +.cmatic-test-form-wrap .wpcf7-response-output { + margin: 16px 0 0; + padding: 12px 16px; + border-radius: 4px; +} + +.cmatic-test-form-wrap .wpcf7-mail-sent-ok { + border-color: #00a32a; + background: #edfaef; +} + +.cmatic-test-form-wrap .wpcf7-mail-sent-ng, +.cmatic-test-form-wrap .wpcf7-validation-errors { + border-color: #d63638; + background: #fcf0f1; +} + +.cmatic-hidden, +.mce-hidden { + display: none !important; +} + +.cmatic-defaults-fields-notice { + margin: 12px 0 4px; + padding: 10px 14px; + background: #f0f6fc; + border-left: 4px solid #72aee6; + border-radius: 2px; +} + +.cmatic-defaults-fields-notice.cmatic-visible { + display: block; +} + +.cmatic-defaults-fields-notice .cmatic-notice { + margin: 0; + font-size: 13px; + color: #1d2327; + line-height: 1.5; +} + +.cmatic-defaults-fields-notice .helping-field { + margin-left: 4px; +} + +.mce-fade-in { + animation: mceFadeIn 0.5s ease-in forwards; +} + +@keyframes mceFadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +.cmatic-lookup-summary { + padding: 8px 10px; + margin: 10px 0; + border-left: 4px solid; + border-radius: 2px; + font-size: 12px; +} +.cmatic-lookup-summary.cmatic-found { + border-color: #00a32a; + background: #edfaef; +} +.cmatic-lookup-summary.cmatic-not-found { + border-color: #dba617; + background: #fcf9e8; +} + +.cmatic-result-card { + border: 1px solid #ddd; + border-radius: 4px; + margin: 8px 0; + overflow: hidden; +} + +.cmatic-card-header { + padding: 10px 12px; + background: #f6f7f7; + font-size: 12px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.cmatic-card-header.cmatic-expandable { + cursor: pointer; + transition: background 0.2s; +} +.cmatic-card-header.cmatic-expandable:hover { + background: #eef0f2; +} + +.cmatic-chevron { + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + border-top: 5px solid #50575e; + transition: transform 0.2s; + margin-left: 8px; +} +.cmatic-card-header.cmatic-expanded .cmatic-chevron { + transform: rotate(180deg); +} + +.cmatic-card-body { + padding: 12px; + border-top: 1px solid #eee; + display: none; + font-size: 11px; +} +.cmatic-card-body.cmatic-visible { + display: block; +} + +.cmatic-status-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + margin-right: 6px; +} +.cmatic-status-subscribed { background: #00a32a; } +.cmatic-status-unsubscribed { background: #d63638; } +.cmatic-status-pending { background: #dba617; } +.cmatic-status-not-found { background: #c3c4c7; } + +.cmatic-header-left, +.cmatic-header-right { + display: flex; + align-items: center; +} + +.cmatic-badge { + display: inline-block; + padding: 2px 8px; + border-radius: 3px; + font-size: 11px; + font-weight: 500; +} +.cmatic-badge-success { background: #00a32a; color: #fff; } +.cmatic-badge-warning { background: #dba617; color: #fff; } +.cmatic-badge-neutral { background: #dcdcde; color: #50575e; } + +.cmatic-section-header { + font-size: 10px; + font-weight: 600; + color: #50575e; + margin: 12px 0 4px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.cmatic-field-table { + width: 100%; + border-collapse: collapse; + margin: 8px 0; +} +.cmatic-field-table th, +.cmatic-field-table td { + padding: 4px 6px; + text-align: left; + border-bottom: 1px solid #f0f0f1; + font-size: 11px; +} +.cmatic-field-table th { + font-weight: 600; + color: #50575e; + width: 35%; +} +.cmatic-field-table tr:last-child th, +.cmatic-field-table tr:last-child td { + border-bottom: none; +} + +.cmatic-tag-list { + display: flex; + flex-wrap: wrap; + gap: 4px; + margin: 6px 0; +} +.cmatic-tag-chip { + display: inline-block; + padding: 7px 6px; + background: #f0f0f1; + border: 1px solid #c3c4c7; + border-radius: 10px; + font-size: 10px; +} + +.cmatic-empty { + color: #787c82; + font-style: italic; + font-size: 10px; +} + +.cmatic-meta-list { + margin: 0; + padding: 0; + list-style: none; +} +.cmatic-meta-list li { + padding: 3px 0; + font-size: 10px; + color: #50575e; +} + +.cmatic-not-pro { + filter: blur(4px); + user-select: none; + cursor: pointer; +} + +tr.cmatic-not-pro:hover, +[data-section].cmatic-not-pro:hover { + background: #f9f9f9; +} + +.cmatic-upsell-tooltip { + position: absolute; + background: #1d2327; + color: #fff; + padding: 10px 14px; + border-radius: 4px; + font-size: 12px; + line-height: 1.4; + max-width: 220px; + z-index: 10000; + box-shadow: 0 2px 8px rgba(0,0,0,0.2); + animation: cmatic-fade-in 0.2s ease; +} + +.cmatic-upsell-tooltip::before { + content: ''; + position: absolute; + top: -6px; + left: 20px; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #1d2327; +} + +.cmatic-upsell-tooltip a { + color: #72aee6; + text-decoration: none; + font-weight: 500; +} + +.cmatic-upsell-tooltip a:hover { + text-decoration: underline; +} + +@keyframes cmatic-fade-in { + from { opacity: 0; transform: translateY(-4px); } + to { opacity: 1; transform: translateY(0); } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/newsletter-stripe.svg b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/newsletter-stripe.svg new file mode 100644 index 0000000..08fbe27 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/newsletter-stripe.svg @@ -0,0 +1 @@ + diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/postal-marks.png b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/postal-marks.png new file mode 100644 index 0000000..d5f337b Binary files /dev/null and b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/postal-marks.png differ diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/postal-stamp.png b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/postal-stamp.png new file mode 100644 index 0000000..302787a Binary files /dev/null and b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/images/postal-stamp.png differ diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite-deactivate.js b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite-deactivate.js new file mode 100644 index 0000000..2978e1c --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite-deactivate.js @@ -0,0 +1,383 @@ +/** + * Deactivation survey modal. + * + * @package contact-form-7-mailchimp-extension + * @author renzo.johnson@gmail.com + * @copyright 2014-2026 https://renzojohnson.com + * @license GPL-3.0+ + */ + +(function () { + 'use strict'; + + const config = window.cmaticDeactivate || {}; + let deactivateUrl = ''; + let modalElement = null; + let pluginsCache = null; + const MAX_RETRIES = 3; + + document.addEventListener('DOMContentLoaded', () => { + init(); + }); + + function init() { + const deactivateLink = findDeactivateLink(); + if (!deactivateLink) return; + + deactivateUrl = deactivateLink.href; + buildModal(); + attachEventListeners(deactivateLink); + } + + function findDeactivateLink() { + const row = document.querySelector(`tr[data-slug="${config.pluginSlug}"]`); + return row ? row.querySelector('.deactivate a') : null; + } + + function buildModal() { + modalElement = document.getElementById('cmatic-deactivate-modal'); + if (!modalElement) return; + + modalElement.innerHTML = ` +
+
+
+

${config.strings.title}

+ +
+
+

${config.strings.description}

+
+
+ ${buildReasonsList()} +
+ +
+
+ +
+ `; + } + + function buildReasonsList() { + return config.reasons.map(reason => { + return ` + + `; + }).join(''); + } + + function buildInputField(reasonId, inputType) { + const reason = config.reasons.find(r => r.id === reasonId); + if (!reason) return ''; + + let inputHtml = ''; + if (inputType === 'plugin-dropdown') { + inputHtml = ``; + } else if (inputType === 'textfield') { + inputHtml = ``; + } + + if (inputHtml) { + return `
${inputHtml}
`; + } + return ''; + } + + async function fetchPluginsList() { + if (pluginsCache) return pluginsCache; + + try { + const response = await fetch(config.pluginsUrl, { + method: 'GET', + headers: { + 'X-WP-Nonce': config.restNonce, + }, + }); + + if (response.ok) { + pluginsCache = await response.json(); + return pluginsCache; + } + } catch (error) { + console.error('ChimpMatic: Failed to fetch plugins list', error); + } + return []; + } + + function populatePluginDropdown(selectElement, plugins) { + let optionsHtml = ''; + if (plugins && plugins.length > 0) { + plugins.forEach(plugin => { + optionsHtml += ``; + }); + } + selectElement.innerHTML = optionsHtml; + selectElement.disabled = false; + } + + function attachEventListeners(deactivateLink) { + deactivateLink.addEventListener('click', handleDeactivateClick); + modalElement.querySelector('.cmatic-modal__close').addEventListener('click', closeModal); + modalElement.querySelector('.cmatic-skip-link').addEventListener('click', handleSkip); + modalElement.querySelector('#cmatic-deactivate-form').addEventListener('submit', handleSubmit); + modalElement.querySelectorAll('.cmatic-reason-btn').forEach(btn => btn.addEventListener('click', handleReasonClick)); + document.addEventListener('keydown', handleKeydown); + modalElement.querySelector('.cmatic-modal__overlay').addEventListener('click', handleOverlayClick); + } + + function handleDeactivateClick(evt) { + evt.preventDefault(); + openModal(); + } + + function openModal() { + modalElement.classList.add('cmatic-modal--active'); + document.body.classList.add('cmatic-modal-open'); + const firstBtn = modalElement.querySelector('.cmatic-reason-btn'); + if (firstBtn) firstBtn.focus(); + trapFocus(); + + setTimeout(() => { + const skipLink = modalElement.querySelector('.cmatic-skip-link'); + if (skipLink) { + skipLink.style.display = 'inline'; + skipLink.style.animation = 'fadeIn 0.3s ease'; + } + }, 10000); + } + + function closeModal() { + modalElement.classList.add('cmatic-modal--closing'); + + setTimeout(() => { + modalElement.classList.remove('cmatic-modal--active', 'cmatic-modal--closing'); + document.body.classList.remove('cmatic-modal-open'); + resetForm(); + }, 300); + } + + function handleSkip(evt) { + evt.preventDefault(); + + const skipData = { + reason_id: 0, + reason_text: '', + }; + + const submitBtn = modalElement.querySelector('.cmatic-submit-btn'); + const skipLink = modalElement.querySelector('.cmatic-skip-link'); + submitBtn.disabled = true; + submitBtn.textContent = cmaticData.i18n.submitting; + skipLink.style.display = 'none'; + + fetch(cmaticData.restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': cmaticData.nonce, + }, + body: JSON.stringify(skipData), + }).finally(() => { + window.location.href = deactivateUrl; + }); + } + + async function handleReasonClick(evt) { + const clickedBtn = evt.currentTarget; + const reasonId = parseInt(clickedBtn.dataset.reasonId, 10); + const inputType = clickedBtn.dataset.inputType; + + modalElement.querySelectorAll('.cmatic-reason-btn').forEach(btn => { + btn.classList.remove('selected'); + btn.setAttribute('aria-pressed', 'false'); + const nextEl = btn.nextElementSibling; + if (nextEl && nextEl.classList.contains('cmatic-input-wrapper')) { + nextEl.remove(); + } + }); + + clickedBtn.classList.add('selected'); + clickedBtn.setAttribute('aria-pressed', 'true'); + + if (inputType && inputType !== '') { + const inputHtml = buildInputField(reasonId, inputType); + if (inputHtml) { + clickedBtn.insertAdjacentHTML('afterend', inputHtml); + const input = clickedBtn.nextElementSibling.querySelector('.cmatic-input-field'); + + if (inputType === 'plugin-dropdown' && input) { + const plugins = await fetchPluginsList(); + populatePluginDropdown(input, plugins); + input.focus(); + } else if (input) { + setTimeout(() => input.focus(), 100); + } + } + } + + hideValidationError(); + } + + async function handleSubmit(evt) { + evt.preventDefault(); + if (!validateForm()) return; + + const selectedBtn = modalElement.querySelector('.cmatic-reason-btn.selected'); + const reasonId = parseInt(selectedBtn.dataset.reasonId, 10); + const inputWrapper = selectedBtn.nextElementSibling; + const inputField = inputWrapper && inputWrapper.classList.contains('cmatic-input-wrapper') + ? inputWrapper.querySelector('.cmatic-input-field') + : null; + const reasonText = inputField ? inputField.value.trim() : ''; + + setButtonsDisabled(true); + + try { + await submitFeedback(reasonId, reasonText); + } catch (error) { + console.error('ChimpMatic: Failed to submit feedback', error); + } + window.location.href = deactivateUrl; + } + + function validateForm() { + const selectedBtn = modalElement.querySelector('.cmatic-reason-btn.selected'); + if (!selectedBtn) { + showValidationError(config.strings.errorRequired); + return false; + } + + const inputWrapper = selectedBtn.nextElementSibling; + if (!inputWrapper || !inputWrapper.classList.contains('cmatic-input-wrapper')) { + hideValidationError(); + return true; + } + + const inputField = inputWrapper.querySelector('.cmatic-input-field'); + if (!inputField) { + hideValidationError(); + return true; + } + + if (inputField.type === 'text' && inputField.value.trim() === '') { + showValidationError(config.strings.errorDetails); + inputField.focus(); + return false; + } + + if (inputField.tagName === 'SELECT' && inputField.value === '') { + showValidationError(config.strings.errorDropdown); + inputField.focus(); + return false; + } + + hideValidationError(); + return true; + } + + async function submitFeedback(reasonId, reasonText, retry = 0) { + const response = await fetch(config.restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': config.restNonce, + }, + body: JSON.stringify({ reason_id: reasonId, reason_text: reasonText }), + }); + + if (!response.ok) { + if (retry < MAX_RETRIES) { + const delay = Math.pow(2, retry) * 1000; + await new Promise(resolve => setTimeout(resolve, delay)); + console.warn(`ChimpMatic: Retry ${retry + 1}/${MAX_RETRIES}`); + return submitFeedback(reasonId, reasonText, retry + 1); + } + throw new Error('Failed to submit feedback'); + } + + return response.json(); + } + + function showValidationError(message) { + const errorEl = modalElement.querySelector('.cmatic-error-message'); + errorEl.textContent = message; + errorEl.classList.add('cmatic-error-message--visible'); + } + + function hideValidationError() { + const errorEl = modalElement.querySelector('.cmatic-error-message'); + errorEl.textContent = ''; + errorEl.classList.remove('cmatic-error-message--visible'); + } + + function handleKeydown(evt) { + if (!modalElement.classList.contains('cmatic-modal--active')) return; + if (evt.key === 'Escape') { + evt.preventDefault(); + closeModal(); + } + } + + function handleOverlayClick() { + const textInputs = modalElement.querySelectorAll('input[type="text"]'); + const selects = modalElement.querySelectorAll('select'); + const hasContent = Array.from(textInputs).some(input => input.value.trim() !== '') || + Array.from(selects).some(select => select.value !== ''); + if (hasContent) { + const confirmed = confirm('You have unsaved feedback. Close anyway?'); + if (confirmed) closeModal(); + } else { + closeModal(); + } + } + + function trapFocus() { + const focusableElements = modalElement.querySelectorAll('button, input, select, [tabindex]:not([tabindex="-1"])'); + if (focusableElements.length === 0) return; + + const firstFocusable = focusableElements[0]; + const lastFocusable = focusableElements[focusableElements.length - 1]; + + function handleTabKey(evt) { + if (evt.key !== 'Tab') return; + if (evt.shiftKey && document.activeElement === firstFocusable) { + evt.preventDefault(); + lastFocusable.focus(); + } else if (!evt.shiftKey && document.activeElement === lastFocusable) { + evt.preventDefault(); + firstFocusable.focus(); + } + } + + modalElement.addEventListener('keydown', handleTabKey); + } + + function resetForm() { + modalElement.querySelectorAll('.cmatic-reason-btn').forEach(btn => { + btn.classList.remove('selected'); + btn.setAttribute('aria-pressed', 'false'); + const nextEl = btn.nextElementSibling; + if (nextEl && nextEl.classList.contains('cmatic-input-wrapper')) { + nextEl.remove(); + } + }); + hideValidationError(); + setButtonsDisabled(false); + const skipLink = modalElement.querySelector('.cmatic-skip-link'); + if (skipLink) skipLink.style.display = 'none'; + } + + function setButtonsDisabled(disabled) { + modalElement.querySelectorAll('.button').forEach(button => button.disabled = disabled); + } +})(); diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite-notices.js b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite-notices.js new file mode 100644 index 0000000..3492559 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite-notices.js @@ -0,0 +1,56 @@ +/** + * Admin notices handler. + * + * @package contact-form-7-mailchimp-extension + * @author renzo.johnson@gmail.com + * @copyright 2014-2026 https://renzojohnson.com + * @license GPL-3.0+ + */ + +'use strict'; + +(function() { + document.addEventListener('DOMContentLoaded', function() { + + if (typeof chimpmaticNotices === 'undefined') { + return; + } + + document.addEventListener('click', function(event) { + if (event.target.classList.contains('notice-dismiss')) { + const noticeElement = event.target.closest('#mce-notice'); + + if (noticeElement) { + event.preventDefault(); + dismissNotice(noticeElement); + } + } + }); + + async function dismissNotice(noticeElement) { + try { + const response = await fetch(`${chimpmaticNotices.restUrl}/notices/dismiss`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticNotices.restNonce + } + }); + + const data = await response.json(); + + if (response.ok && data.success) { + noticeElement.style.transition = 'opacity 0.3s ease-out'; + noticeElement.style.opacity = '0'; + + setTimeout(() => { + noticeElement.style.display = 'none'; + }, 300); + } + + } catch (error) { + console.error('[ChimpMatic Lite] Dismiss notice error:', error); + } + } + }); +})(); diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite.js b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite.js new file mode 100644 index 0000000..ae6884b --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic-lite.js @@ -0,0 +1,2041 @@ +/** + * Console logging handler. + * + * @package contact-form-7-mailchimp-extension + * @author renzo.johnson@gmail.com + * @copyright 2014-2026 https://renzojohnson.com + * @license GPL-3.0+ + */ + +'use strict'; + +(function() { + if (typeof chimpmaticLite === 'undefined' || !chimpmaticLite.loggingEnabled) { + return; + } + + const originalConsole = { + log: console.log, + info: console.info, + warn: console.warn, + error: console.error, + debug: console.debug + }; + + async function sendLogToServer(level, message, ...args) { + let formattedMessage = message; + let dataString = ''; + + if (args.length > 0) { + try { + dataString = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)).join(' | '); + formattedMessage += ' ' + dataString; + } catch (e) { + dataString = '[Unable to stringify arguments]'; + } + } + + try { + await fetch(`${chimpmaticLite.restUrl}logs/browser`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body: JSON.stringify({ level, message: formattedMessage, data: dataString }) + }); + } catch (error) { + originalConsole.error('[ChimpMatic Lite] Failed to send log to server:', error); + } + } + + ['log', 'info', 'warn', 'error', 'debug'].forEach(level => { + console[level] = function(...args) { + originalConsole[level].apply(console, args); + const message = args[0] ? String(args[0]) : ''; + sendLogToServer(level, message, ...args.slice(1)); + }; + }); +})(); + +document.addEventListener('DOMContentLoaded', function() { + if (typeof chimpmaticLite === 'undefined') { + return; + } + + const isProFieldPanelActive = !!document.getElementById('chm_panel_gencamposygrupos'); + let cachedLists = chimpmaticLite.lists && chimpmaticLite.lists.length > 0 ? chimpmaticLite.lists : []; + + function getFormId() { + const dataContainer = document.getElementById('cmatic_data'); + return dataContainer?.dataset?.formId ? parseInt(dataContainer.dataset.formId, 10) || 0 : 0; + } + + async function fetchMailchimpLists(formId, apiKey) { + const response = await fetch(`${chimpmaticLite.restUrl}lists`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body: JSON.stringify({ form_id: formId, api_key: apiKey }) + }); + + const data = await response.json(); + if (!response.ok) throw new Error(data.message || 'Failed to fetch lists'); + return data; + } + + async function getDebugLog(filtered = true) { + const url = filtered + ? `${chimpmaticLite.restUrl}logs` + : `${chimpmaticLite.restUrl}logs?filter=0`; + + const response = await fetch(url, { + method: 'GET', + headers: { 'X-WP-Nonce': chimpmaticLite.restNonce } + }); + + const data = await response.json(); + if (!response.ok) throw new Error(data.message || 'Failed to fetch log'); + return data; + } + + async function clearDebugLog() { + const response = await fetch(`${chimpmaticLite.restUrl}logs/clear`, { + method: 'POST', + headers: { 'X-WP-Nonce': chimpmaticLite.restNonce } + }); + + const data = await response.json(); + if (!response.ok) throw new Error(data.message || 'Failed to clear log'); + return data; + } + + function findBestMatch(mergeTag, fieldName, cf7Tags) { + if (!mergeTag || !cf7Tags || cf7Tags.length === 0) return null; + + const normalize = str => String(str).toLowerCase().replace(/[^a-z0-9]/g, ''); + const normalizedTag = normalize(mergeTag); + const normalizedName = normalize(fieldName); + + const keywordMappings = { + email: ['email', 'mail', 'correo'], + emailaddress: ['email', 'mail'], + fname: ['name', 'firstname', 'first', 'nombre', 'your-name'], + firstname: ['name', 'firstname', 'first', 'nombre'], + lname: ['lastname', 'last', 'apellido', 'surname'], + lastname: ['lastname', 'last', 'apellido'], + name: ['name', 'nombre', 'your-name'], + fullname: ['name', 'fullname', 'nombre'], + phone: ['phone', 'tel', 'telefono', 'mobile', 'cell'], + mobilephone: ['phone', 'tel', 'mobile', 'cell'], + address: ['address', 'direccion', 'street'], + address1: ['address', 'address1', 'street'], + address2: ['address2', 'apt', 'suite'], + city: ['city', 'ciudad'], + state: ['state', 'province', 'region', 'estado'], + zip: ['zip', 'postal', 'postcode'], + country: ['country', 'pais'], + company: ['company', 'organization', 'empresa', 'org'], + website: ['website', 'url', 'web', 'sitio'], + birthday: ['birthday', 'birth', 'dob', 'cumpleanos'], + message: ['message', 'comments', 'mensaje', 'nota', 'your-message'] + }; + + for (const [mcKeyword, cf7Keywords] of Object.entries(keywordMappings)) { + if (normalizedTag.includes(mcKeyword) || normalizedName.includes(mcKeyword)) { + for (const cf7Keyword of cf7Keywords) { + const match = cf7Tags.find(tag => normalize(tag.name || tag).includes(cf7Keyword)); + if (match) return match.name || match; + } + } + } + + for (const tag of cf7Tags) { + const tagName = normalize(tag.name || tag); + if (normalizedTag.includes(tagName) || tagName.includes(normalizedTag)) return tag.name || tag; + if (normalizedName.includes(tagName) || tagName.includes(normalizedName)) return tag.name || tag; + } + + return null; + } + + function applyFuzzyMatching(mergeFields) { + const cf7Tags = []; + const sampleDropdown = document.getElementById('wpcf7-mailchimp-field4'); + if (sampleDropdown) { + Array.from(sampleDropdown.options).forEach(option => { + if (option.value && option.value.trim() !== '' && option.value !== ' ') { + cf7Tags.push({ name: option.value }); + } + }); + } + + if (cf7Tags.length === 0) return; + + const fieldMappings = [ + { id: 'field3', index: 0 }, + { id: 'field4', index: 1 }, + { id: 'field5', index: 2 }, + { id: 'field6', index: 3 } + ]; + + const changedFields = []; + + fieldMappings.forEach(mapping => { + const mergeField = mergeFields[mapping.index]; + if (!mergeField) return; + + const dropdown = document.getElementById(`wpcf7-mailchimp-${mapping.id}`); + if (!dropdown) return; + + if (dropdown.value && dropdown.value.trim() !== '' && dropdown.value !== ' ') return; + + const bestMatch = findBestMatch(mergeField.tag, mergeField.name, cf7Tags); + if (bestMatch) { + dropdown.value = bestMatch; + changedFields.push({ field: mapping.id, value: bestMatch }); + + Array.from(dropdown.options).forEach(opt => { + opt.defaultSelected = (opt.value === bestMatch); + }); + } + }); + + if (changedFields.length > 0) { + saveFieldMappings(changedFields); + } + } + + async function saveFieldMappings(fields) { + const formId = getFormId(); + if (!formId || fields.length === 0) return; + + for (const { field, value } of fields) { + try { + await fetch(chimpmaticLite.restUrl + 'form/field', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body: JSON.stringify({ form_id: formId, field, value }) + }); + } catch (error) { + console.error('Failed to save field mapping:', field, error); + } + } + } + + function updateFieldLabels(mergeFields) { + const fieldMappings = [ + { id: 'field3', index: 0 }, + { id: 'field4', index: 1 }, + { id: 'field5', index: 2 }, + { id: 'field6', index: 3 } + ]; + + fieldMappings.forEach(mapping => { + const label = document.querySelector(`label[for="wpcf7-mailchimp-${mapping.id}"]`); + const container = label ? label.closest('.mcee-container') : null; + + if (mergeFields[mapping.index]) { + const field = mergeFields[mapping.index]; + if (label) { + const requiredBadge = field.tag === 'EMAIL' ? 'Required' : ''; + label.innerHTML = `${field.name} - *|${field.tag}|* ${field.type} ${requiredBadge}`; + } + if (container) container.style.display = ''; + } else { + if (container) container.style.display = 'none'; + } + }); + + applyFuzzyMatching(mergeFields); + } + + function updateFieldsNotice(totalMergeFields, liteLimit, audienceName) { + const notice = document.getElementById('cmatic-fields-notice'); + if (!notice) return; + + const noticeText = notice.querySelector('.cmatic-notice'); + + if (totalMergeFields > liteLimit) { + if (noticeText) { + const docsLink = notice.querySelector('a'); + const linkHtml = docsLink ? ' ' + docsLink.outerHTML : ''; + const name = audienceName ? '' + audienceName + ' ' : ''; + noticeText.innerHTML = 'Your ' + name + 'audience has ' + totalMergeFields + ' merge fields. Chimpmatic Lite supports up to ' + liteLimit + ' field mappings.' + linkHtml; + } + notice.classList.remove('cmatic-hidden'); + notice.classList.add('cmatic-visible'); + } else { + notice.classList.remove('cmatic-visible'); + notice.classList.add('cmatic-hidden'); + } + } + + function renderListsDropdown(listsData, currentSelection) { + const { api_valid, lists, total } = listsData; + + if (lists && lists.length > 0) { + cachedLists = lists; + } + + const dataContainer = document.getElementById('cmatic_data'); + if (dataContainer) dataContainer.dataset.apiValid = api_valid ? '1' : '0'; + + const label = document.getElementById('cmatic-audiences-label'); + if (label) { + label.textContent = api_valid && total > 0 ? `Total Mailchimp Audiences: ${total}` : 'Mailchimp Audiences'; + } + + let optionsHtml = ''; + let selectedAudience = ''; + + if (api_valid && total > 0) { + selectedAudience = currentSelection; + if (!selectedAudience && lists.length > 0) selectedAudience = lists[0].id; + + lists.forEach((list, index) => { + const selected = selectedAudience === list.id ? ' selected' : ''; + const optionText = `${index + 1}:${list.member_count} ${list.name} ${list.field_count} fields #${list.id}`; + optionsHtml += ``; + }); + + const selectedList = lists.find(l => l.id === selectedAudience) || lists[0]; + updateFieldsNotice(selectedList.field_count, chimpmaticLite.liteFieldsLimit || 4, selectedList.name); + } + + return optionsHtml; + } + + function updateApiStatus(isValid) { + // Update sidebar status + const versionInfo = document.getElementById('chimpmatic-version-info'); + if (versionInfo) { + const statusText = versionInfo.querySelector('.chmm'); + if (statusText) { + if (isValid) { + statusText.classList.remove('invalid'); + statusText.classList.add('valid'); + statusText.textContent = 'API Connected'; + } else { + statusText.classList.remove('valid'); + statusText.classList.add('invalid'); + statusText.textContent = 'API Inactive'; + } + } + } + + // Update header status dot + const headerDot = document.querySelector('.cmatic-header__status-dot'); + const headerText = document.querySelector('.cmatic-header__status-text'); + if (headerDot) { + if (isValid) { + headerDot.classList.remove('cmatic-header__status-dot--disconnected'); + headerDot.classList.add('cmatic-header__status-dot--connected'); + } else { + headerDot.classList.remove('cmatic-header__status-dot--connected'); + headerDot.classList.add('cmatic-header__status-dot--disconnected'); + } + } + if (headerText) { + headerText.textContent = isValid ? 'API Connected' : 'API Inactive'; + } + } + + function updateLiteBadgeStatus(status) { + const liteBadge = document.querySelector('.cm-lite'); + if (!liteBadge) return; + + liteBadge.classList.remove('cm-status-neutral', 'cm-status-connected', 'cm-status-error'); + + if (status === 'connected') liteBadge.classList.add('cm-status-connected'); + else if (status === 'error') liteBadge.classList.add('cm-status-error'); + else liteBadge.classList.add('cm-status-neutral'); + } + + async function getSecureApiKey(apiKeyInput, formId) { + const isMasked = apiKeyInput.dataset.isMasked === '1'; + const hasKey = apiKeyInput.dataset.hasKey === '1'; + const inputValue = apiKeyInput.value.trim(); + + if (!isMasked) { + return inputValue; + } + + if (!hasKey) { + return ''; + } + + try { + const response = await fetch( + `${chimpmaticLite.restUrl}api-key/${formId}`, + { + method: 'GET', + headers: { + 'X-WP-Nonce': chimpmaticLite.restNonce, + 'Content-Type': 'application/json' + } + } + ); + + if (!response.ok) { + console.error('ChimpMatic: Failed to fetch API key'); + return ''; + } + + const data = await response.json(); + return data.api_key || ''; + } catch (err) { + console.error('ChimpMatic: Error fetching API key', err); + return ''; + } + } + + const fetchListsButton = document.getElementById('chm_activalist'); + if (fetchListsButton) { + fetchListsButton.addEventListener('click', async function(event) { + event.preventDefault(); + + const apiKeyInput = document.getElementById('cmatic-api'); + const selectElement = document.getElementById('wpcf7-mailchimp-list'); + + if (!apiKeyInput || !selectElement) return; + + const formId = getFormId(); + const apiKey = await getSecureApiKey(apiKeyInput, formId); + + if (!apiKey) { + if (typeof showInlineMessage === 'function') { + showInlineMessage(fetchListsButton, 'Enter API key first', 'warning'); + } + updateApiStatus(false); + updateLiteBadgeStatus('neutral'); + return; + } + + if (!formId || formId <= 0) { + if (typeof showInlineMessage === 'function') { + showInlineMessage(fetchListsButton, 'Save form first', 'warning'); + } + updateApiStatus(false); + updateLiteBadgeStatus('neutral'); + return; + } + + const originalText = fetchListsButton.value || fetchListsButton.textContent; + fetchListsButton.disabled = true; + if (fetchListsButton.tagName === 'INPUT') fetchListsButton.value = 'Syncing Audiences...'; + else fetchListsButton.textContent = 'Syncing Audiences...'; + + try { + const data = await fetchMailchimpLists(formId, apiKey); + + const currentSelection = selectElement.value || ''; + selectElement.innerHTML = renderListsDropdown(data, currentSelection); + + attachFetchFieldsListeners(); + + const newListDropdown = document.getElementById('wpcf7-mailchimp-list'); + if (newListDropdown && newListDropdown.value) { + if (isProFieldPanelActive) { + newListDropdown.dispatchEvent(new Event('change', { bubbles: true })); + } else { + fetchFieldsForSelectedList(); + } + } + + if (data.api_valid) { + updateApiStatus(true); + updateLiteBadgeStatus('connected'); + + document.querySelectorAll('.chmp-inactive').forEach(el => { + el.classList.remove('chmp-inactive'); + el.classList.add('chmp-active'); + }); + + const newUserSection = document.getElementById('chmp-new-user'); + if (newUserSection) { + newUserSection.classList.remove('chmp-active'); + newUserSection.classList.add('chmp-inactive'); + } + } else { + updateApiStatus(false); + updateLiteBadgeStatus('error'); + + document.querySelectorAll('.chmp-active').forEach(el => { + el.classList.remove('chmp-active'); + el.classList.add('chmp-inactive'); + }); + + const newUserSection = document.getElementById('chmp-new-user'); + if (newUserSection) { + newUserSection.classList.remove('chmp-inactive'); + newUserSection.classList.add('chmp-active'); + } + } + + if (fetchListsButton.tagName === 'INPUT') fetchListsButton.value = 'Synced ✓'; + else fetchListsButton.textContent = 'Synced ✓'; + + setTimeout(() => { + if (fetchListsButton.tagName === 'INPUT') fetchListsButton.value = originalText; + else fetchListsButton.textContent = originalText; + fetchListsButton.disabled = false; + }, 1000); + + } catch (error) { + if (fetchListsButton.tagName === 'INPUT') fetchListsButton.value = originalText; + else fetchListsButton.textContent = originalText; + fetchListsButton.disabled = false; + alert(chimpmaticLite.i18n.error); + } + }); + } + + const apiKeyInput = document.getElementById('cmatic-api'); + if (apiKeyInput && fetchListsButton) { + function isValidApiKey(key) { + if (key.length !== 36 || key.charAt(32) !== '-') return false; + if (!/^[a-f0-9]{32}$/i.test(key.substring(0, 32))) return false; + const dc = key.substring(33).toLowerCase(); + const validDCs = ['us1','us2','us3','us4','us5','us6','us7','us8','us9','us10','us11','us12','us13','us14','us15','us16','us17','us18','us19','us20','us21']; + return validDCs.includes(dc); + } + + function debounce(func, wait) { + let timeout; + return function(...args) { + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, args), wait); + }; + } + + apiKeyInput.addEventListener('paste', function() { + setTimeout(() => { + if (isValidApiKey(apiKeyInput.value.trim())) fetchListsButton.click(); + }, 50); + }); + + apiKeyInput.addEventListener('input', function() { + updateLiteBadgeStatus('neutral'); + }); + + apiKeyInput.addEventListener('input', debounce(function() { + const apiKey = apiKeyInput.value.trim(); + if (isValidApiKey(apiKey)) { + fetchListsButton.click(); + } else if (apiKey === '') { + const formId = getFormId(); + if (formId) { + fetch(`${chimpmaticLite.restUrl}settings/reset`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body: JSON.stringify({ form_id: formId }) + }) + .then(response => response.json()) + .then(() => { + const selectElement = document.getElementById('wpcf7-mailchimp-list'); + if (selectElement) selectElement.innerHTML = ''; + const label = document.getElementById('cmatic-audiences-label'); + if (label) label.textContent = 'Mailchimp Audiences'; + const fieldsContainer = document.getElementById('cmatic-fields'); + if (fieldsContainer) fieldsContainer.innerHTML = ''; + updateLiteBadgeStatus('neutral'); + + document.querySelectorAll('.chmp-active').forEach(el => { + el.classList.remove('chmp-active'); + el.classList.add('chmp-inactive'); + }); + + const newUserSection = document.getElementById('chmp-new-user'); + if (newUserSection) { + newUserSection.classList.remove('chmp-inactive'); + newUserSection.classList.add('chmp-active'); + } + }); + } + } + }, 500)); + } + + function initToggleAutoSave() { + const globalFields = ['debug', 'backlink', 'auto_update', 'telemetry']; + const toggles = document.querySelectorAll('.cmatic-toggle input[data-field]'); + if (toggles.length === 0) return; + + toggles.forEach(function(toggle) { + toggle.addEventListener('change', async function() { + const field = this.dataset.field; + + if (!globalFields.includes(field)) return; + + const enabled = this.checked; + const wrapper = this.closest('.cmatic-toggle'); + + if (wrapper) wrapper.classList.add('is-saving'); + + try { + const response = await fetch(chimpmaticLite.restUrl + 'settings/toggle', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body: JSON.stringify({ field, enabled }) + }); + + const data = await response.json(); + if (wrapper) wrapper.classList.remove('is-saving'); + if (data.success) { + // Sync defaultChecked to prevent CF7 beforeunload warning + this.defaultChecked = this.checked; + } else { + this.checked = !enabled; + } + } catch (error) { + if (wrapper) wrapper.classList.remove('is-saving'); + this.checked = !enabled; + } + }); + }); + } + + initToggleAutoSave(); + + function initSelectAutoSave() { + const selects = document.querySelectorAll('select.chm-select[data-field]'); + if (selects.length === 0) return; + + const perFormFields = ['double_optin', 'sync_tags']; + + selects.forEach(function(select) { + select.addEventListener('change', async function() { + const field = this.dataset.field; + const value = this.value === '1'; + const wrapper = this.closest('.mcee-container'); + + if (wrapper) wrapper.classList.add('is-saving'); + + try { + let url, body; + + if (perFormFields.includes(field)) { + const formId = getFormId(); + if (!formId) { + if (wrapper) wrapper.classList.remove('is-saving'); + this.value = value ? '0' : '1'; + return; + } + const rootUrl = chimpmaticLite.restUrl.replace('chimpmatic-lite/v1/', ''); + url = rootUrl + 'cmatic/form/setting'; + body = JSON.stringify({ form_id: formId, field, value }); + } else { + url = chimpmaticLite.restUrl + 'settings/toggle'; + body = JSON.stringify({ field, enabled: value }); + } + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body + }); + + const data = await response.json(); + if (wrapper) wrapper.classList.remove('is-saving'); + if (data.success) { + // Sync defaultSelected to prevent CF7 beforeunload warning + Array.from(this.options).forEach(function(opt) { + opt.defaultSelected = opt.selected; + }); + } else { + this.value = value ? '0' : '1'; + } + } catch (error) { + if (wrapper) wrapper.classList.remove('is-saving'); + this.value = value ? '0' : '1'; + } + }); + }); + } + + initSelectAutoSave(); + + const debugLogButton = document.querySelector('.cme-trigger-log:not(.cmatic-accordion-btn)'); + if (debugLogButton) { + debugLogButton.addEventListener('click', async function(event) { + event.preventDefault(); + + const logPanelContainer = document.getElementById('eventlog-sys'); + const logPanel = document.getElementById('log_panel'); + const advancedSettings = document.querySelector('.vc-advanced-settings'); + const advancedToggleButton = document.querySelector('.vc-view-advanced'); + const testContainer = document.getElementById('cmatic-test-container'); + const testSubmissionBtn = document.querySelector('.vc-test-submission'); + + if (!logPanelContainer || !logPanel) return; + + const isLogVisible = window.getComputedStyle(logPanelContainer).display !== 'none'; + + if (isLogVisible) { + logPanelContainer.style.transition = 'opacity 0.5s ease-out'; + logPanelContainer.style.opacity = '0'; + + setTimeout(() => { + logPanelContainer.style.display = 'none'; + logPanelContainer.style.removeProperty('opacity'); + logPanelContainer.style.removeProperty('transition'); + }, 500); + + this.setAttribute('aria-expanded', 'false'); + } else { + if (advancedSettings) { + const isAdvancedVisible = window.getComputedStyle(advancedSettings).display !== 'none'; + if (isAdvancedVisible) { + advancedSettings.style.transition = 'opacity 0.5s ease-out'; + advancedSettings.style.opacity = '0'; + + setTimeout(() => { + advancedSettings.style.display = 'none'; + advancedSettings.style.removeProperty('opacity'); + advancedSettings.style.removeProperty('transition'); + }, 500); + + if (advancedToggleButton) advancedToggleButton.setAttribute('aria-expanded', 'false'); + } + } + + if (testContainer) { + const isTestVisible = window.getComputedStyle(testContainer).display !== 'none'; + if (isTestVisible) { + testContainer.style.transition = 'opacity 0.5s ease-out'; + testContainer.style.opacity = '0'; + + setTimeout(() => { + testContainer.style.display = 'none'; + testContainer.style.removeProperty('opacity'); + testContainer.style.removeProperty('transition'); + }, 500); + + if (testSubmissionBtn) testSubmissionBtn.setAttribute('aria-expanded', 'false'); + } + } + + logPanel.textContent = chimpmaticLite.i18n.loading; + logPanelContainer.style.opacity = '0'; + logPanelContainer.style.display = 'block'; + logPanelContainer.style.transition = 'opacity 0.5s ease-in'; + + setTimeout(() => { logPanelContainer.style.opacity = '1'; }, 50); + this.setAttribute('aria-expanded', 'true'); + + try { + const data = await getDebugLog(); + logPanel.textContent = data.success ? (data.logs || data.message) : 'Error: ' + (data.message || 'Unknown error'); + } catch (error) { + logPanel.textContent = chimpmaticLite.i18n.error; + } + } + }); + } + + const advancedToggleButton = document.querySelector('.vc-view-advanced:not(.cmatic-accordion-btn)'); + if (advancedToggleButton) { + advancedToggleButton.addEventListener('click', function(event) { + event.preventDefault(); + + const advancedSettings = document.querySelector('.vc-advanced-settings'); + const logPanelContainer = document.getElementById('eventlog-sys'); + const debugLogBtn = document.querySelector('.cme-trigger-log'); + const testContainer = document.getElementById('cmatic-test-container'); + const testSubmissionBtn = document.querySelector('.vc-test-submission'); + + if (!advancedSettings) return; + + const isVisible = window.getComputedStyle(advancedSettings).display !== 'none'; + + if (isVisible) { + advancedSettings.style.transition = 'opacity 0.5s ease-out'; + advancedSettings.style.opacity = '0'; + + setTimeout(() => { + advancedSettings.style.display = 'none'; + advancedSettings.style.removeProperty('opacity'); + advancedSettings.style.removeProperty('transition'); + }, 500); + + this.setAttribute('aria-expanded', 'false'); + } else { + if (logPanelContainer) { + const isLogVisible = window.getComputedStyle(logPanelContainer).display !== 'none'; + if (isLogVisible) { + logPanelContainer.style.transition = 'opacity 0.5s ease-out'; + logPanelContainer.style.opacity = '0'; + + setTimeout(() => { + logPanelContainer.style.display = 'none'; + logPanelContainer.style.removeProperty('opacity'); + logPanelContainer.style.removeProperty('transition'); + }, 500); + + if (debugLogBtn) debugLogBtn.setAttribute('aria-expanded', 'false'); + } + } + + if (testContainer) { + const isTestVisible = window.getComputedStyle(testContainer).display !== 'none'; + if (isTestVisible) { + testContainer.style.transition = 'opacity 0.5s ease-out'; + testContainer.style.opacity = '0'; + + setTimeout(() => { + testContainer.style.display = 'none'; + testContainer.style.removeProperty('opacity'); + testContainer.style.removeProperty('transition'); + }, 500); + + if (testSubmissionBtn) testSubmissionBtn.setAttribute('aria-expanded', 'false'); + } + } + + advancedSettings.style.opacity = '0'; + advancedSettings.style.display = 'block'; + advancedSettings.style.transition = 'opacity 0.5s ease-in'; + + setTimeout(() => { advancedSettings.style.opacity = '1'; }, 50); + this.setAttribute('aria-expanded', 'true'); + } + }); + } + + const clearLogsButton = document.querySelector('.vc-clear-logs'); + if (clearLogsButton) { + clearLogsButton.addEventListener('click', async function(event) { + event.preventDefault(); + + const logPanel = document.getElementById('log_panel'); + const originalText = this.textContent; + + this.disabled = true; + this.textContent = 'Clearing Logs...'; + + try { + const data = await clearDebugLog(); + + if (data.success && data.cleared) { + this.textContent = 'Cleared'; + if (logPanel) logPanel.textContent = 'Debug log cleared.'; + } else { + this.textContent = 'Cleared'; + if (logPanel) logPanel.textContent = data.message || 'Debug log was already empty.'; + } + + setTimeout(() => { + this.textContent = 'Clear Logs'; + this.disabled = false; + }, 2000); + } catch (error) { + this.textContent = 'Clearing Log Error'; + setTimeout(() => { + this.textContent = 'Clear Logs'; + this.disabled = false; + }, 3000); + } + }); + } + + (function initAccordionPanels() { + const accordionContainer = document.querySelector('.cmatic-panel-toggles'); + if (!accordionContainer) return; + + const panelConfig = { + 'eventlog-sys': { + filtered: true, + onOpen: async function(panel) { + const logPanel = document.getElementById('log_panel'); + const toggleLink = panel.querySelector('.vc-toggle-filter'); + const config = panelConfig['eventlog-sys']; + + if (toggleLink && !toggleLink.hasAttribute('data-listener')) { + toggleLink.setAttribute('data-listener', 'true'); + toggleLink.addEventListener('click', async function(e) { + e.preventDefault(); + config.filtered = !config.filtered; + this.textContent = config.filtered ? 'Show All' : 'Plugin Only'; + this.setAttribute('data-filtered', config.filtered ? '1' : '0'); + + if (logPanel) { + logPanel.textContent = chimpmaticLite.i18n?.loading || 'Loading...'; + try { + const data = await getDebugLog(config.filtered); + logPanel.textContent = data.success ? (data.logs || data.message) : 'Error: ' + (data.message || 'Unknown error'); + } catch (error) { + logPanel.textContent = chimpmaticLite.i18n?.error || 'Error loading logs'; + } + } + }); + } + + if (logPanel && typeof chimpmaticLite !== 'undefined') { + logPanel.textContent = chimpmaticLite.i18n?.loading || 'Loading...'; + try { + const data = await getDebugLog(config.filtered); + logPanel.textContent = data.success ? (data.logs || data.message) : 'Error: ' + (data.message || 'Unknown error'); + } catch (error) { + logPanel.textContent = chimpmaticLite.i18n?.error || 'Error loading logs'; + } + } + } + }, + 'cmatic-test-container': { + useModal: true + } + }; + + function hidePanel(panel, button) { + if (!panel) return; + const isVisible = window.getComputedStyle(panel).display !== 'none'; + if (!isVisible) return; + + panel.style.transition = 'opacity 0.5s ease-out'; + panel.style.opacity = '0'; + + setTimeout(() => { + panel.style.display = 'none'; + panel.style.removeProperty('opacity'); + panel.style.removeProperty('transition'); + }, 500); + + if (button) button.setAttribute('aria-expanded', 'false'); + } + + function showPanel(panel, button, config) { + if (!panel) return; + + panel.style.opacity = '0'; + panel.style.display = 'block'; + panel.style.transition = 'opacity 0.5s ease-in'; + + setTimeout(() => { panel.style.opacity = '1'; }, 50); + if (button) button.setAttribute('aria-expanded', 'true'); + + if (config && config.onOpen) { + config.onOpen(panel); + } + } + + function closeAllPanels() { + const buttons = accordionContainer.querySelectorAll('.cmatic-accordion-btn'); + buttons.forEach(btn => { + const panelId = btn.getAttribute('aria-controls'); + if (panelId) { + const panel = document.getElementById(panelId); + hidePanel(panel, btn); + } + }); + } + + accordionContainer.addEventListener('click', function(event) { + const button = event.target.closest('.cmatic-accordion-btn'); + if (!button) return; + + event.preventDefault(); + + const panelId = button.getAttribute('aria-controls'); + if (!panelId) return; + + const config = panelConfig[panelId] || {}; + + if (config.useModal) { + return; + } + + const panel = document.getElementById(panelId); + if (!panel) return; + + const isExpanded = button.getAttribute('aria-expanded') === 'true'; + + if (isExpanded) { + hidePanel(panel, button); + } else { + closeAllPanels(); + + setTimeout(() => { + showPanel(panel, button, config); + }, 100); + } + }); + + const buttons = accordionContainer.querySelectorAll('.cmatic-accordion-btn'); + buttons.forEach(btn => { + const panelId = btn.getAttribute('aria-controls'); + const config = panelConfig[panelId] || {}; + if (panelId && !config.useModal) { + const panel = document.getElementById(panelId); + if (panel) { + panel.style.display = 'none'; + } + } + btn.setAttribute('aria-expanded', 'false'); + }); + })(); + + function relocateSidebarElements() { + const moveElements = document.querySelectorAll('.mce-move'); + const submitDiv = document.getElementById('submitdiv'); + const postboxContainer = document.querySelector('.postbox-container'); + + if (!moveElements.length || !submitDiv || !postboxContainer) return; + + let insertAfter = submitDiv; + + moveElements.forEach((el) => { + if (insertAfter.nextSibling) { + postboxContainer.insertBefore(el, insertAfter.nextSibling); + } else { + postboxContainer.appendChild(el); + } + insertAfter = el; + + el.classList.add('mce-fade-in'); + el.classList.remove('mce-hidden'); + }); + } + + relocateSidebarElements(); + + async function fetchFieldsForSelectedList() { + if (isProFieldPanelActive) return; + + const listDropdown = document.getElementById('wpcf7-mailchimp-list'); + const fetchFieldsButton = document.getElementById('mce_fetch_fields'); + const formId = getFormId(); + + if (!listDropdown || !listDropdown.value || !formId) return; + + const listId = listDropdown.value; + const originalText = fetchFieldsButton ? (fetchFieldsButton.value || fetchFieldsButton.textContent) : 'Sync Fields'; + + if (fetchFieldsButton) { + fetchFieldsButton.disabled = true; + if (fetchFieldsButton.tagName === 'INPUT') fetchFieldsButton.value = 'Syncing Fields...'; + else fetchFieldsButton.textContent = 'Syncing Fields...'; + } + + try { + const response = await fetch(`${chimpmaticLite.restUrl}merge-fields`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body: JSON.stringify({ form_id: formId, list_id: listId }) + }); + + const data = await response.json(); + + if (data.success && data.merge_fields) { + updateFieldLabels(data.merge_fields); + applyFuzzyMatching(data.merge_fields); + const listDropdownEl = document.getElementById('wpcf7-mailchimp-list'); + const selectedId = listDropdownEl ? listDropdownEl.value : ''; + const selectedList = cachedLists.find(l => l.id === selectedId); + const fieldCount = selectedList ? selectedList.field_count : 0; + const audienceName = selectedList ? selectedList.name : ''; + updateFieldsNotice(fieldCount, chimpmaticLite.liteFieldsLimit || 4, audienceName); + + if (fetchFieldsButton) { + if (fetchFieldsButton.tagName === 'INPUT') fetchFieldsButton.value = 'Synced ✓'; + else fetchFieldsButton.textContent = 'Synced ✓'; + + setTimeout(() => { + if (fetchFieldsButton.tagName === 'INPUT') fetchFieldsButton.value = originalText; + else fetchFieldsButton.textContent = originalText; + fetchFieldsButton.disabled = false; + }, 1000); + } + } else { + alert('Failed to load fields. Please try again.'); + if (fetchFieldsButton) { + if (fetchFieldsButton.tagName === 'INPUT') fetchFieldsButton.value = originalText; + else fetchFieldsButton.textContent = originalText; + fetchFieldsButton.disabled = false; + } + } + } catch (error) { + alert('Error loading fields. Check console for details.'); + if (fetchFieldsButton) { + if (fetchFieldsButton.tagName === 'INPUT') fetchFieldsButton.value = originalText; + else fetchFieldsButton.textContent = originalText; + fetchFieldsButton.disabled = false; + } + } + } + + function attachFetchFieldsListeners() { + const listDropdown = document.getElementById('wpcf7-mailchimp-list'); + if (listDropdown) { + listDropdown.removeEventListener('change', handleListChange); + listDropdown.addEventListener('change', handleListChange); + } + + const fetchFieldsButton = document.getElementById('mce_fetch_fields'); + if (fetchFieldsButton) { + fetchFieldsButton.removeEventListener('click', handleFetchFieldsClick); + fetchFieldsButton.addEventListener('click', handleFetchFieldsClick); + } + } + + function handleListChange(e) { + const selectedList = e.target.value; + const fetchFieldsButton = document.getElementById('mce_fetch_fields'); + const listDropdown = e.target; + + if (isProFieldPanelActive) return; + + Array.from(listDropdown.options).forEach(opt => { + opt.defaultSelected = (opt.value === selectedList); + }); + + if (selectedList) { + if (fetchFieldsButton) fetchFieldsButton.disabled = false; + + for (let i = 3; i <= 8; i++) { + const dropdown = document.getElementById(`wpcf7-mailchimp-field${i}`); + if (dropdown) dropdown.value = ' '; + } + + fetchFieldsForSelectedList(); + } else { + if (fetchFieldsButton) fetchFieldsButton.disabled = true; + } + } + + async function handleFetchFieldsClick(event) { + if (isProFieldPanelActive) return; + event.preventDefault(); + await fetchFieldsForSelectedList(); + } + + attachFetchFieldsListeners(); + + const initialListDropdown = document.getElementById('wpcf7-mailchimp-list'); + const initialFetchButton = document.getElementById('mce_fetch_fields'); + if (initialListDropdown && initialListDropdown.options.length > 0) { + if (!initialListDropdown.value || initialListDropdown.value === '' || initialListDropdown.value === ' ') { + initialListDropdown.value = initialListDropdown.options[0].value; + if (initialFetchButton) initialFetchButton.disabled = false; + } else { + if (initialFetchButton && initialFetchButton.disabled) initialFetchButton.disabled = false; + } + } + + if (chimpmaticLite.mergeFields && chimpmaticLite.mergeFields.length > 0) { + updateFieldLabels(chimpmaticLite.mergeFields); + } + + function initLicenseResetButton() { + const button = document.getElementById('cmatic-license-reset-btn'); + const messageDiv = document.getElementById('cmatic-license-reset-message'); + + if (!button || !messageDiv) return; + + button.addEventListener('click', async function(e) { + e.preventDefault(); + + button.disabled = true; + button.textContent = 'Resetting...'; + messageDiv.innerHTML = ''; + + try { + const response = await fetch(chimpmaticLite.licenseResetUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.nonce + }, + credentials: 'same-origin', + body: JSON.stringify({ type: 'nuclear' }) + }); + + const data = await response.json(); + + if (data.success) { + button.textContent = 'Done Resetting'; + messageDiv.innerHTML = '✓ ' + escapeHtml(data.message) + '
' + + 'Deleted ' + data.deleted_counts.options + ' options and ' + + data.deleted_counts.transients + ' transients'; + + setTimeout(function() { + button.textContent = 'Reset License Data'; + button.disabled = false; + messageDiv.innerHTML = ''; + }, 3000); + } else { + button.textContent = 'Reset License Data'; + button.disabled = false; + messageDiv.innerHTML = '✗ Error: ' + + escapeHtml(data.message || 'Unknown error occurred') + ''; + + setTimeout(function() { messageDiv.innerHTML = ''; }, 5000); + } + } catch (error) { + button.textContent = 'Reset License Data'; + button.disabled = false; + messageDiv.innerHTML = '✗ Network error: ' + + escapeHtml(error.message) + ''; + + setTimeout(function() { messageDiv.innerHTML = ''; }, 5000); + } + }); + } + + function escapeHtml(text) { + const div = document.createElement('div'); + div.textContent = text; + return div.innerHTML; + } + + initLicenseResetButton(); + + let formHandlerAttached = false; + + function openTestModal() { + const modal = document.getElementById('cmatic-test-modal'); + if (!modal) return; + + modal.classList.add('cmatic-modal--active'); + document.body.classList.add('cmatic-modal-open'); + + const form = modal.querySelector('.wpcf7 form'); + if (form && !form.querySelector('input[name="_cmatic_test_modal"]')) { + const hidden = document.createElement('input'); + hidden.type = 'hidden'; + hidden.name = '_cmatic_test_modal'; + hidden.value = '1'; + form.appendChild(hidden); + } + + if (!formHandlerAttached) { + if (form) { + attachTestFormHandler(form); + formHandlerAttached = true; + } + } + + const closeBtn = modal.querySelector('.cmatic-modal__close'); + if (closeBtn) closeBtn.focus(); + } + + function closeTestModal() { + const modal = document.getElementById('cmatic-test-modal'); + if (!modal) return; + + modal.classList.remove('cmatic-modal--active'); + document.body.classList.remove('cmatic-modal-open'); + } + + function attachTestFormHandler(form) { + form.addEventListener('submit', async function(e) { + e.preventDefault(); + + const submitBtn = form.querySelector('input[type="submit"], button[type="submit"]'); + const headerSubmitBtn = document.querySelector('.cmatic-modal__submit'); + const responseOutput = form.querySelector('.wpcf7-response-output') || createResponseOutput(form); + const formId = form.querySelector('input[name="_wpcf7"]')?.value; + + if (!formId) { + showResponse(responseOutput, 'error', 'Form ID not found.'); + return; + } + + const originalBtnText = submitBtn?.value || submitBtn?.textContent; + if (submitBtn) { + submitBtn.disabled = true; + if (submitBtn.tagName === 'INPUT') { + submitBtn.value = 'Sending...'; + } else { + submitBtn.textContent = 'Sending...'; + } + } + + if (headerSubmitBtn) { + headerSubmitBtn.disabled = true; + headerSubmitBtn.textContent = 'Submitting...'; + headerSubmitBtn.classList.remove('cmatic-modal__submit--success', 'cmatic-modal__submit--error'); + } + + responseOutput.textContent = ''; + responseOutput.className = 'wpcf7-response-output'; + responseOutput.style.display = 'none'; + hideChimpmaticFeedback(); + + let isSuccess = false; + + try { + const formData = new FormData(form); + const restUrl = chimpmaticLite.restUrl.replace('chimpmatic-lite/v1/', '') + 'contact-form-7/v1/contact-forms/' + formId + '/feedback'; + + const response = await fetch(restUrl, { + method: 'POST', + body: formData, + credentials: 'same-origin' + }); + + const data = await response.json(); + + if (data.chimpmatic) { + showChimpmaticFeedback(data.chimpmatic); + } + + if (data.status === 'mail_sent') { + isSuccess = true; + showResponse(responseOutput, 'success', data.message || 'Message sent successfully.'); + form.reset(); + refreshDebugLogsAfterSubmission(); + } else if (data.status === 'validation_failed' || data.status === 'mail_failed') { + showResponse(responseOutput, 'error', data.message || 'There was an error sending your message.'); + if (data.invalid_fields) { + data.invalid_fields.forEach(field => { + const wrap = form.querySelector(`.wpcf7-form-control-wrap[data-name="${field.field}"]`); + if (wrap) { + const tip = document.createElement('span'); + tip.className = 'wpcf7-not-valid-tip'; + tip.textContent = field.message; + wrap.appendChild(tip); + } + }); + } + } else { + showResponse(responseOutput, 'error', data.message || 'An error occurred.'); + } + } catch (error) { + console.error('Test form submission error:', error); + showResponse(responseOutput, 'error', 'Network error. Please try again.'); + } finally { + if (submitBtn) { + submitBtn.disabled = false; + if (submitBtn.tagName === 'INPUT') { + submitBtn.value = originalBtnText; + } else { + submitBtn.textContent = originalBtnText; + } + } + + if (headerSubmitBtn) { + headerSubmitBtn.disabled = false; + if (isSuccess) { + headerSubmitBtn.textContent = 'Success!'; + headerSubmitBtn.classList.add('cmatic-modal__submit--success'); + } else { + headerSubmitBtn.textContent = 'Error'; + headerSubmitBtn.classList.add('cmatic-modal__submit--error'); + } + setTimeout(() => { + headerSubmitBtn.textContent = 'Submit'; + headerSubmitBtn.classList.remove('cmatic-modal__submit--success', 'cmatic-modal__submit--error'); + }, 2000); + } + } + }); + + form.addEventListener('input', function(e) { + const wrap = e.target.closest('.wpcf7-form-control-wrap'); + if (wrap) { + const tip = wrap.querySelector('.wpcf7-not-valid-tip'); + if (tip) tip.remove(); + } + }); + } + + function createResponseOutput(form) { + const output = document.createElement('div'); + output.className = 'wpcf7-response-output'; + output.setAttribute('aria-live', 'polite'); + form.appendChild(output); + return output; + } + + function showResponse(element, type, message) { + element.textContent = message; + element.style.display = 'block'; + element.className = 'wpcf7-response-output'; + if (type === 'success') { + element.classList.add('wpcf7-mail-sent-ok'); + element.style.borderColor = '#00a32a'; + element.style.background = '#edfaef'; + } else { + element.classList.add('wpcf7-mail-sent-ng'); + element.style.borderColor = '#d63638'; + element.style.background = '#fcf0f1'; + } + } + + function showChimpmaticFeedback(chimpmatic) { + const modal = document.getElementById('cmatic-test-modal'); + if (!modal) return; + + const feedback = modal.querySelector('.cmatic-modal__feedback'); + if (!feedback) return; + + const icon = feedback.querySelector('.cmatic-modal__feedback-icon'); + const title = feedback.querySelector('.cmatic-modal__feedback-title'); + const details = feedback.querySelector('.cmatic-modal__feedback-details'); + + feedback.classList.remove('cmatic-modal__feedback--success', 'cmatic-modal__feedback--error', 'cmatic-modal__feedback--skipped'); + + if (chimpmatic.success === true) { + feedback.classList.add('cmatic-modal__feedback--success'); + icon.innerHTML = ''; + title.textContent = chimpmatic.message; + + const sent = chimpmatic.merge_vars || {}; + const received = chimpmatic.received || {}; + const allKeys = new Set([...Object.keys(sent), ...Object.keys(received)]); + + if (allKeys.size > 0) { + let tableHtml = ''; + tableHtml += ''; + + for (const key of allKeys) { + const sentVal = sent[key] !== undefined ? escapeHtml(String(sent[key])) : '—'; + const recvVal = received[key] !== undefined ? escapeHtml(String(received[key])) : '—'; + const mismatch = sent[key] !== undefined && received[key] !== undefined && String(sent[key]) !== String(received[key]); + const rowClass = mismatch ? ' class="field-mismatch"' : ''; + tableHtml += ''; + } + + tableHtml += '
FieldSentReceived
' + escapeHtml(key) + '' + sentVal + '' + recvVal + '
'; + details.innerHTML = tableHtml; + } else { + details.innerHTML = ''; + } + } else if (chimpmatic.skipped === true) { + feedback.classList.add('cmatic-modal__feedback--skipped'); + icon.innerHTML = ''; + title.textContent = 'Subscription skipped'; + details.textContent = chimpmatic.message; + } else { + feedback.classList.add('cmatic-modal__feedback--error'); + icon.innerHTML = ''; + title.textContent = 'Subscription failed'; + details.textContent = chimpmatic.message; + } + + feedback.style.display = 'flex'; + } + + function hideChimpmaticFeedback() { + const modal = document.getElementById('cmatic-test-modal'); + if (!modal) return; + + const feedback = modal.querySelector('.cmatic-modal__feedback'); + if (feedback) { + feedback.style.display = 'none'; + } + } + + async function refreshDebugLogsAfterSubmission() { + await new Promise(resolve => setTimeout(resolve, 500)); + + const logPanelContainer = document.getElementById('eventlog-sys'); + const logPanel = document.getElementById('log_panel'); + const debugLogBtn = document.querySelector('.cme-trigger-log'); + + if (!logPanelContainer || !logPanel) return; + + const isLogVisible = window.getComputedStyle(logPanelContainer).display !== 'none'; + if (!isLogVisible) { + logPanel.textContent = chimpmaticLite.i18n.loading; + logPanelContainer.style.opacity = '0'; + logPanelContainer.style.display = 'block'; + logPanelContainer.style.transition = 'opacity 0.5s ease-in'; + setTimeout(() => { logPanelContainer.style.opacity = '1'; }, 50); + if (debugLogBtn) debugLogBtn.setAttribute('aria-expanded', 'true'); + } + + try { + const data = await getDebugLog(); + logPanel.textContent = data.success ? (data.logs || data.message) : 'Error: ' + (data.message || 'Unknown error'); + } catch (error) { + logPanel.textContent = chimpmaticLite.i18n.error; + } + } + + document.addEventListener('click', function(event) { + const btn = event.target.closest('.vc-test-submission'); + if (!btn) return; + + event.preventDefault(); + openTestModal(); + }); + + document.addEventListener('click', function(event) { + const closeBtn = event.target.closest('#cmatic-test-modal .cmatic-modal__close'); + if (!closeBtn) return; + + event.preventDefault(); + closeTestModal(); + }); + + document.addEventListener('click', function(event) { + const overlay = event.target.closest('#cmatic-test-modal .cmatic-modal__overlay'); + if (!overlay) return; + + closeTestModal(); + }); + + document.addEventListener('keydown', function(event) { + if (event.key === 'Escape') { + const modal = document.getElementById('cmatic-test-modal'); + if (modal && modal.classList.contains('cmatic-modal--active')) { + closeTestModal(); + } + } + }); + + document.addEventListener('click', function(event) { + const submitBtn = event.target.closest('#cmatic-test-modal .cmatic-modal__submit'); + if (!submitBtn) return; + + event.preventDefault(); + const modal = document.getElementById('cmatic-test-modal'); + if (!modal) return; + + const form = modal.querySelector('.wpcf7 form'); + if (!form) return; + + form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); + }); +}); + +document.addEventListener('DOMContentLoaded', function() { + const eye = document.querySelector('.cmatic-eye'); + const input = document.getElementById('cmatic-api'); + if (!eye || !input) return; + + let cachedRealKey = null; + + eye.addEventListener('click', async function(e) { + e.preventDefault(); + const icon = this.querySelector('.dashicons'); + const isMasked = input.dataset.isMasked === '1'; + const hasKey = input.dataset.hasKey === '1'; + + if (isMasked && hasKey) { + if (!cachedRealKey) { + const formId = typeof chimpmaticLite !== 'undefined' ? chimpmaticLite.formId : 0; + if (!formId) { + console.warn('ChimpMatic: No form ID available'); + return; + } + + try { + eye.style.opacity = '0.5'; + const response = await fetch( + `${chimpmaticLite.restUrl}api-key/${formId}`, + { + method: 'GET', + headers: { + 'X-WP-Nonce': chimpmaticLite.restNonce, + 'Content-Type': 'application/json' + } + } + ); + + if (!response.ok) { + throw new Error('Failed to fetch API key'); + } + + const data = await response.json(); + cachedRealKey = data.api_key || ''; + } catch (err) { + console.error('ChimpMatic: Error fetching API key', err); + eye.style.opacity = '1'; + return; + } + eye.style.opacity = '1'; + } + + input.value = cachedRealKey; + input.dataset.isMasked = '0'; + icon.classList.remove('dashicons-visibility'); + icon.classList.add('dashicons-hidden'); + } else { + input.value = input.dataset.maskedKey; + input.dataset.isMasked = '1'; + icon.classList.remove('dashicons-hidden'); + icon.classList.add('dashicons-visibility'); + } + }); + + const form = input.closest('form'); + if (form) { + form.addEventListener('submit', async function(e) { + const isMasked = input.dataset.isMasked === '1'; + const hasKey = input.dataset.hasKey === '1'; + + if (isMasked && hasKey) { + if (cachedRealKey) { + input.value = cachedRealKey; + } else { + const formId = typeof chimpmaticLite !== 'undefined' ? chimpmaticLite.formId : 0; + if (formId) { + e.preventDefault(); + try { + const response = await fetch( + `${chimpmaticLite.restUrl}api-key/${formId}`, + { + method: 'GET', + headers: { + 'X-WP-Nonce': chimpmaticLite.restNonce, + 'Content-Type': 'application/json' + } + } + ); + + if (response.ok) { + const data = await response.json(); + cachedRealKey = data.api_key || ''; + input.value = cachedRealKey; + } + } catch (err) { + console.error('ChimpMatic: Error fetching API key for submit', err); + } + form.submit(); + } + } + } + }); + } + + (function initContactLookup() { + const lookupBtn = document.getElementById('cmatic-lookup-btn'); + const emailInput = document.getElementById('cmatic-lookup-email'); + const resultsContainer = document.getElementById('cmatic-lookup-results'); + const formContainer = emailInput ? emailInput.closest('div') : null; + + if (!lookupBtn || !emailInput || !resultsContainer || !formContainer) { + return; + } + + function showForm() { + formContainer.classList.remove('cmatic-hidden'); + resultsContainer.classList.add('cmatic-hidden'); + resultsContainer.innerHTML = ''; + emailInput.value = ''; + emailInput.focus(); + } + + function formatDate(dateStr) { + if (!dateStr) return null; + const date = new Date(dateStr); + return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }); + } + + function getStatusInfo(status) { + const statusMap = { + 'subscribed': { class: 'cmatic-status-subscribed', badge: 'cmatic-badge-success', label: 'Subscribed' }, + 'unsubscribed': { class: 'cmatic-status-unsubscribed', badge: 'cmatic-badge-neutral', label: 'Unsubscribed' }, + 'pending': { class: 'cmatic-status-pending', badge: 'cmatic-badge-warning', label: 'Pending' }, + 'cleaned': { class: 'cmatic-status-unsubscribed', badge: 'cmatic-badge-neutral', label: 'Cleaned' }, + 'archived': { class: 'cmatic-status-not-found', badge: 'cmatic-badge-neutral', label: 'Archived' }, + 'not_subscribed': { class: 'cmatic-status-not-found', badge: 'cmatic-badge-neutral', label: 'Not Found' } + }; + return statusMap[status] || { class: 'cmatic-status-not-found', badge: 'cmatic-badge-neutral', label: status }; + } + + function renderMergeFields(mergeFields) { + if (!mergeFields || Object.keys(mergeFields).length === 0) { + return 'No fields'; + } + + const fieldLabels = { + 'EMAIL': 'Email', 'FNAME': 'First Name', 'LNAME': 'Last Name', + 'PHONE': 'Phone', 'ADDRESS': 'Address', 'BIRTHDAY': 'Birthday', + 'COMPANY': 'Company', 'WEBSITE': 'Website', 'AGE': 'Age', + 'GENDER': 'Gender', 'ZIPCODE': 'Zip Code', 'MMERGE3': 'Field 3', + 'MMERGE4': 'Field 4', 'MMERGE5': 'Field 5', 'MMERGE6': 'Field 6' + }; + + let rows = ''; + for (const [key, value] of Object.entries(mergeFields)) { + const fieldKey = key.toLowerCase(); + if (typeof value === 'object' && value !== null) { + if (value.addr1 || value.city || value.state || value.zip || value.country) { + const addrParts = [value.addr1, value.addr2, value.city, value.state, value.zip, value.country].filter(Boolean); + const label = fieldLabels[key] || key; + rows += `${label}${addrParts.length ? addrParts.join(', ') : '—'}`; + } + continue; + } + const label = fieldLabels[key] || key; + const displayValue = (value && value !== '') ? value : '—'; + rows += `${label}${displayValue}`; + } + + if (!rows) return 'No fields configured'; + return `${rows}
`; + } + + function renderTags(tags) { + if (!tags || tags.length === 0) { + return '
No tags
'; + } + return '
' + + tags.map(tag => `${tag}`).join('') + + '
'; + } + + function renderInterests(interests) { + if (!interests || Object.keys(interests).length === 0) { + return '
No groups assigned
'; + } + let html = '
'; + for (const [category, items] of Object.entries(interests)) { + const catKey = category.toLowerCase().replace(/\s+/g, '-'); + const itemsArray = Array.isArray(items) ? items : [items]; + html += `
${category}: `; + html += itemsArray.map(i => `${i}`).join(' '); + html += '
'; + } + html += '
'; + return html; + } + + function renderMarketingPermissions(permissions) { + if (!permissions) { + return '
No GDPR permissions
'; + } + + const isArray = Array.isArray(permissions); + + if (isArray && permissions.length === 0) { + return '
No GDPR permissions
'; + } + if (!isArray && Object.keys(permissions).length === 0) { + return '
No GDPR permissions
'; + } + + let rows = ''; + + if (!isArray) { + let idx = 0; + for (const [key, value] of Object.entries(permissions)) { + const displayVal = Array.isArray(value) ? value.join(', ') : value; + rows += `Permission ${idx + 1}${displayVal}`; + idx++; + } + return `${rows}
`; + } + + if (typeof permissions[0] === 'string') { + permissions.forEach((hash, idx) => { + rows += `Permission ${idx + 1}${hash}`; + }); + return `${rows}
`; + } + + permissions.forEach((perm, idx) => { + const permKey = perm.marketing_permission_id || `gdpr-${idx}`; + const enabled = perm.enabled ? '✓ Yes' : '✗ No'; + rows += `${perm.text || perm.marketing_permission_id}${enabled}`; + }); + return `${rows}
`; + } + + function getLanguageName(code) { + if (!code) return '—'; + const languages = { + 'en': 'English', 'es': 'Spanish', 'fr': 'French', 'de': 'German', + 'pt': 'Portuguese', 'it': 'Italian', 'nl': 'Dutch', 'ru': 'Russian', + 'ja': 'Japanese', 'zh': 'Chinese', 'ko': 'Korean', 'ar': 'Arabic', + 'hi': 'Hindi', 'pl': 'Polish', 'tr': 'Turkish', 'vi': 'Vietnamese', + 'th': 'Thai', 'sv': 'Swedish', 'da': 'Danish', 'fi': 'Finnish', + 'no': 'Norwegian', 'cs': 'Czech', 'el': 'Greek', 'he': 'Hebrew', + 'hu': 'Hungarian', 'id': 'Indonesian', 'ms': 'Malay', 'ro': 'Romanian', + 'sk': 'Slovak', 'uk': 'Ukrainian', 'bg': 'Bulgarian', 'hr': 'Croatian', + 'ca': 'Catalan', 'et': 'Estonian', 'lv': 'Latvian', 'lt': 'Lithuanian', + 'sl': 'Slovenian', 'sr': 'Serbian', 'tl': 'Tagalog', 'fa': 'Persian' + }; + return languages[code.toLowerCase()] || code.toUpperCase(); + } + + function renderPreferences(result) { + let rows = ''; + + const emailType = result.email_type ? result.email_type.toUpperCase() : '—'; + rows += `Email format${emailType}`; + + const language = getLanguageName(result.language); + rows += `Language${language}`; + + const vip = result.vip ? 'Yes' : 'No'; + rows += `VIP${vip}`; + + if (result.member_rating !== null && result.member_rating !== undefined) { + const stars = '★'.repeat(result.member_rating) + '☆'.repeat(5 - result.member_rating); + rows += `Contact rating${stars}`; + } else { + rows += `Contact rating—`; + } + + rows += `Email client${result.email_client || '—'}`; + + if (result.location && (result.location.country_code || result.location.timezone)) { + const locParts = []; + if (result.location.country_code) locParts.push(result.location.country_code); + if (result.location.region) locParts.push(result.location.region); + if (result.location.timezone) locParts.push(`(${result.location.timezone})`); + rows += `Location${locParts.join(' ') || '—'}`; + } else { + rows += `Location—`; + } + + const smsConsent = result.consents_to_one_to_one_messaging === true ? 'Yes' : + (result.consents_to_one_to_one_messaging === false ? 'No' : '—'); + rows += `SMS consent${smsConsent}`; + + return `${rows}
`; + } + + function renderResultCard(result, isFirst) { + const statusInfo = getStatusInfo(result.status); + const isFound = result.found; + + let html = '
'; + + if (isFound) { + const expandedClass = isFirst ? ' cmatic-expanded' : ''; + html += `
`; + } else { + html += '
'; + } + + html += ` +
+ + ${result.list_name} +
+
+ ${statusInfo.label} + ${isFound ? '' : ''} +
+
`; + + if (isFound) { + const visibleClass = isFirst ? ' cmatic-visible' : ''; + html += `
`; + + html += '
Contact Info
'; + html += `
`; + html += `
Source${result.source || '—'}
`; + html += renderMergeFields(result.merge_fields); + html += `
`; + + html += '
Tags
'; + html += renderTags(result.tags); + + html += '
Groups
'; + html += renderInterests(result.interests); + + html += '
GDPR / Marketing Permissions
'; + html += renderMarketingPermissions(result.marketing_permissions); + + html += '
Details
'; + html += ''; + html += ``; + html += ``; + html += ``; + html += ``; + html += ``; + html += '
Subscribed${result.subscribed ? formatDate(result.subscribed) : '—'}
Signup date${result.timestamp_signup ? formatDate(result.timestamp_signup) : '—'}
IP signup${result.ip_signup || '—'}
Last changed${result.last_changed ? formatDate(result.last_changed) : '—'}
Unsubscribe reason${result.unsubscribe_reason || '—'}
'; + + html += '
Preferences
'; + html += renderPreferences(result); + + html += '
'; + } + + html += '
'; + return html; + } + + function renderResults(data) { + let html = ''; + + const summaryClass = data.found ? 'cmatic-found' : 'cmatic-not-found'; + html += `
${data.message}
`; + + const sortedResults = [...data.results].sort((a, b) => { + if (a.found && !b.found) return -1; + if (!a.found && b.found) return 1; + return 0; + }); + + let firstFound = true; + sortedResults.forEach(result => { + html += renderResultCard(result, result.found && firstFound); + if (result.found) firstFound = false; + }); + + html += '
'; + html += 'New Lookup'; + html += '
'; + + return html; + } + + function applyLiteBlur() { + const freeMergeFieldCount = 6; + + const proOnlyFields = [ + 'source', 'ip_signup', 'subscribed', 'timestamp_signup', + 'member_rating', 'location', 'email_client', 'vip', + 'language', 'email_type', 'sms_consent' + ]; + + const proOnlySections = ['tags', 'groups', 'gdpr', 'preferences']; + + const contactInfoSection = resultsContainer.querySelector('[data-section="contact-info"]'); + if (contactInfoSection) { + const mergeFieldRows = contactInfoSection.querySelectorAll('tr[data-field]'); + let mergeFieldIndex = 0; + mergeFieldRows.forEach(row => { + if (mergeFieldIndex >= freeMergeFieldCount) { + const val = row.querySelector('.cmatic-val'); + if (val) val.classList.add('cmatic-not-pro'); + } + mergeFieldIndex++; + }); + } + + proOnlyFields.forEach(field => { + const rows = resultsContainer.querySelectorAll(`tr[data-field="${field}"]`); + rows.forEach(row => { + const val = row.querySelector('.cmatic-val'); + if (val) val.classList.add('cmatic-not-pro'); + }); + }); + + proOnlySections.forEach(section => { + const elements = resultsContainer.querySelectorAll(`[data-section="${section}"]`); + elements.forEach(el => { + el.querySelectorAll('.cmatic-val, .cmatic-empty, .cmatic-tag-chip').forEach(child => { + child.classList.add('cmatic-not-pro'); + }); + }); + }); + + const blurredElements = resultsContainer.querySelectorAll('.cmatic-not-pro'); + blurredElements.forEach(el => { + el.addEventListener('click', showUpsellTooltip); + }); + } + + function showUpsellTooltip(e) { + e.preventDefault(); + e.stopPropagation(); + + const existing = document.querySelector('.cmatic-upsell-tooltip'); + if (existing) existing.remove(); + + const tooltip = document.createElement('div'); + tooltip.className = 'cmatic-upsell-tooltip'; + tooltip.innerHTML = ` + Pro Feature
+ Unlock full contact insights with ChimpMatic Pro.

+ Upgrade to Pro → + `; + + const rect = e.currentTarget.getBoundingClientRect(); + const scrollTop = window.pageYOffset || document.documentElement.scrollTop; + tooltip.style.position = 'absolute'; + tooltip.style.top = (rect.bottom + scrollTop + 8) + 'px'; + tooltip.style.left = rect.left + 'px'; + + document.body.appendChild(tooltip); + + setTimeout(() => { + document.addEventListener('click', function closeTooltip(evt) { + if (!tooltip.contains(evt.target)) { + tooltip.remove(); + document.removeEventListener('click', closeTooltip); + } + }); + }, 10); + } + + lookupBtn.addEventListener('click', async function() { + const email = emailInput.value.trim(); + const formId = emailInput.dataset.formId; + + if (!email) { + resultsContainer.innerHTML = '
Please enter an email address.
'; + resultsContainer.classList.remove('cmatic-hidden'); + return; + } + + lookupBtn.disabled = true; + lookupBtn.textContent = 'Looking up...'; + resultsContainer.innerHTML = '
Checking all audiences...
'; + resultsContainer.classList.remove('cmatic-hidden'); + + try { + const response = await fetch(chimpmaticLite.restUrl + 'contact/lookup', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': chimpmaticLite.restNonce + }, + body: JSON.stringify({ + email: email, + form_id: parseInt(formId, 10) + }) + }); + + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.message || 'Search failed'); + } + + formContainer.classList.add('cmatic-hidden'); + resultsContainer.innerHTML = renderResults(data); + + const newLookupLink = document.getElementById('cmatic-new-lookup'); + if (newLookupLink) { + newLookupLink.addEventListener('click', function(e) { + e.preventDefault(); + showForm(); + }); + } + + if (!data.is_pro) { + applyLiteBlur(); + } + + } catch (error) { + resultsContainer.innerHTML = `
Error: ${error.message}
`; + } finally { + lookupBtn.disabled = false; + lookupBtn.textContent = 'Lookup'; + } + }); + + emailInput.addEventListener('keypress', function(e) { + if (e.key === 'Enter') { + lookupBtn.click(); + } + }); + })(); +}); diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic.js b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic.js new file mode 100644 index 0000000..7a21f94 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/assets/js/chimpmatic.js @@ -0,0 +1,1359 @@ +/** + * Admin JavaScript. + * + * @package contact-form-7-mailchimp-extension + * @author renzo.johnson@gmail.com + * @copyright 2014-2026 https://renzojohnson.com + * @license GPL-3.0+ + */ + +/** + * Fix CF7's beforeunload detection for dynamically populated selects. + * + * CF7 compares defaultValue vs value to detect changes. PHP-generated selects + * with selected="selected" have undefined defaultValue causing false positives. + * This syncs defaultValue to current value on page load. + */ +document.addEventListener('DOMContentLoaded', function() { + const form = document.getElementById('wpcf7-admin-form-element'); + if (!form) return; + + // Sync select defaultValue to prevent false "unsaved changes" warnings + form.querySelectorAll('select').forEach(function(select) { + if (select.value && select.defaultValue !== select.value) { + // Set defaultValue for select (affects selectedIndex tracking) + Array.from(select.options).forEach(function(opt) { + opt.defaultSelected = opt.selected; + }); + } + }); + + // Sync checkbox values (browsers set value="on" but defaultValue="") + form.querySelectorAll('input[type="checkbox"]').forEach(function(cb) { + if (cb.value && !cb.defaultValue) { + cb.defaultValue = cb.value; + } + }); +}); + +function getFormId() { + const dataContainer = document.getElementById('cmatic_data'); + if (dataContainer && dataContainer.dataset.formId) { + return parseInt(dataContainer.dataset.formId, 10) || 0; + } + return 0; +} + +function getApiValid() { + const dataContainer = document.getElementById('cmatic_data'); + return dataContainer?.dataset?.apiValid || '0'; +} + +/** + * Show inline status message near an element (non-invasive alternative to alert). + * + * @param {HTMLElement} targetElement Element to show message near. + * @param {string} message Message text. + * @param {string} type 'error', 'warning', or 'success'. + * @param {number} duration Auto-hide after ms (0 = manual close). + */ +function showInlineMessage(targetElement, message, type = 'warning', duration = 5000) { + // Remove any existing message + const existingMsg = targetElement.parentNode.querySelector('.cmatic-inline-msg'); + if (existingMsg) existingMsg.remove(); + + const msg = document.createElement('span'); + msg.className = `cmatic-inline-msg cmatic-msg-${type}`; + msg.textContent = message; + msg.style.cssText = ` + display: inline-block; + margin-left: 10px; + padding: 4px 10px; + border-radius: 3px; + font-size: 13px; + animation: cmatic-fade-in 0.3s ease; + `; + + if (type === 'error') { + msg.style.background = '#f8d7da'; + msg.style.color = '#721c24'; + msg.style.border = '1px solid #f5c6cb'; + } else if (type === 'warning') { + msg.style.background = '#fff3cd'; + msg.style.color = '#856404'; + msg.style.border = '1px solid #ffeeba'; + } else { + msg.style.background = '#d4edda'; + msg.style.color = '#155724'; + msg.style.border = '1px solid #c3e6cb'; + } + + targetElement.parentNode.insertBefore(msg, targetElement.nextSibling); + + if (duration > 0) { + setTimeout(() => { + msg.style.opacity = '0'; + msg.style.transition = 'opacity 0.3s ease'; + setTimeout(() => msg.remove(), 300); + }, duration); + } +} + +/** + * Securely get the API key - fetches from REST endpoint if masked. + * CVE-2025-68989 fix: API key no longer stored in data-real-key attribute. + * @returns {Promise} The API key. + */ +async function getApiKey() { + const apiInput = document.getElementById('cmatic-api'); + if (!apiInput) return ''; + + const isMasked = apiInput.dataset.isMasked === '1'; + const hasKey = apiInput.dataset.hasKey === '1'; + const inputValue = apiInput.value.trim(); + + // If not masked, the input contains the real key (user just typed/pasted it). + if (!isMasked) { + return inputValue; + } + + // If masked but no key exists in DB, return empty. + if (!hasKey) { + return ''; + } + + // Masked with existing key - fetch the real key from secure endpoint. + const formId = getFormId(); + if (!formId) return ''; + + try { + // Use Lite endpoint (works for both Lite and PRO). + const restUrl = typeof chimpmaticLite !== 'undefined' + ? chimpmaticLite.restUrl + : getRestUrl().replace('chimpmatic/v1/', 'chimpmatic-lite/v1/'); + const nonce = typeof chimpmaticLite !== 'undefined' + ? chimpmaticLite.restNonce + : (typeof wpApiSettings !== 'undefined' ? wpApiSettings.nonce : ''); + + const response = await fetch( + `${restUrl}api-key/${formId}`, + { + method: 'GET', + headers: { + 'X-WP-Nonce': nonce, + 'Content-Type': 'application/json' + } + } + ); + + if (!response.ok) { + console.error('ChimpMatic: Failed to fetch API key'); + return ''; + } + + const data = await response.json(); + return data.api_key || ''; + } catch (err) { + console.error('ChimpMatic: Error fetching API key', err); + return ''; + } +} + +function setApiValid(value) { + const dataContainer = document.getElementById('cmatic_data'); + if (dataContainer) { + dataContainer.dataset.apiValid = value ? '1' : '0'; + } +} + +function getRestUrl() { + if (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) { + return wpApiSettings.root + 'chimpmatic/v1/'; + } + return '/wp-json/chimpmatic/v1/'; +} + +const REST_ENDPOINTS = { + SETTINGS_SAVE: 'settings/save', + SETTINGS_CONFIG: 'settings/config', + AUDIENCES: 'mailchimp/audiences', + FIELDS: 'mailchimp/fields', + GROUPS: 'mailchimp/groups', + INTERESTS: 'mailchimp/interests', + EXPORT_USERS: 'export/users', + NOTICES_DISMISS: 'notices/dismiss', + TELEMETRY_TOGGLE: 'telemetry/toggle' +}; + +const actionToEndpoint = { + 'wpcf7_chm_savetool': 'settings/save', + 'wpcf7_chm_savetool_cfg': 'settings/config', + 'wpcf7_chm_loadlistas': 'mailchimp/audiences', + 'wpcf7_chm_loadcampos': 'mailchimp/fields', + 'wpcf7_chm_loadgrupos': 'mailchimp/groups', + 'wpcf7_chm_get_interest': 'mailchimp/interests', + 'wpcf7_chm_exporuser': 'export/users' +}; + +async function chmRequest(actionOrEndpoint, data = {}) { + const endpoint = actionToEndpoint[actionOrEndpoint] || actionOrEndpoint; + return await chmRestRequest(endpoint, data); +} + +async function chmRestRequest(endpoint, data = {}) { + const url = getRestUrl() + endpoint; + + try { + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + body: JSON.stringify(data), + credentials: 'same-origin' + }); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const result = await response.json(); + return result.html || result.data || ''; + } catch (error) { + console.error('[Chimpmatic] Error:', error); + throw error; + } +} + +// Save Tool Configuration +document.addEventListener('click', function(event) { + if (event.target && event.target.id === 'chm_submitme') { + event.preventDefault(); + + const data = { + tool_key: document.getElementById('wpcf7-mailchimp-tool_key')?.value || '', + chm_idformxx: getFormId(), + uemail: document.getElementById('wpcf7-mailchimp-uemail')?.value || '', + prod_id: document.getElementById('wpcf7-mailchimp-prod-id')?.value || '' + }; + + chmRequest('wpcf7_chm_savetool', data) + .then(response => { + const panel = document.getElementById('chm_panel_principal'); + if (panel) panel.innerHTML = response; + }) + .catch(error => { + alert('Error: ' + error.message); + }); + } +}); + +// Save Tool Config +document.addEventListener('click', function(event) { + if (event.target && event.target.id === 'chm_submitme_cfg') { + event.preventDefault(); + + const data = { + tool_key: document.getElementById('wpcf7-mailchimp-tool_key')?.value || '', + uemail: document.getElementById('wpcf7-mailchimp-uemail')?.value || '', + prod_id: document.getElementById('wpcf7-mailchimp-prod-id')?.value || '' + }; + + chmRequest('wpcf7_chm_savetool_cfg', data) + .then(response => { + const liveElements = document.querySelectorAll('.chimp-live'); + liveElements.forEach(el => el.innerHTML = response); + }) + .catch(error => { + alert('Error: ' + error.message); + }); + } +}); + +// Connect and Fetch Your Audiences (Load Lists) +document.addEventListener('click', function(event) { + if (event.target && event.target.id === 'chm_activalist') { + event.preventDefault(); + + const button = event.target; + if (button.disabled) return; + + const panel = button.closest('.cmatic-field-group') || button.closest('.mce-custom-fields'); + let apiKeyElement = panel ? panel.querySelector('#cmatic-api') : null; + if (!apiKeyElement) { + apiKeyElement = document.getElementById('cmatic-api'); + } + + const apiKey = apiKeyElement?.value || ''; + if (!apiKey || apiKey.trim() === '') { + showInlineMessage(button, 'Enter API key first', 'warning'); + return; + } + + const formId = getFormId(); + if (!formId || formId <= 0) { + showInlineMessage(button, 'Save form first', 'warning'); + return; + } + + const data = { + tool_key: document.getElementById('wpcf7-mailchimp-tool_key')?.value || '', + chm_idformxx: formId, + chimpapi: apiKey + }; + + const originalText = button.value; + button.value = 'Syncing...'; + button.disabled = true; + + chmRequest('wpcf7_chm_loadlistas', data) + .then(response => { + const listPanel = document.getElementById('chm_panel_listamail'); + if (listPanel) { + listPanel.innerHTML = response; + } + + const valor = getApiValid(); + let attrclass = ''; + let chm_valid = ''; + + if (valor === '1') { + attrclass = 'spt-response-out spt-valid'; + chm_valid = '

ChimpmaticAPI Connected

'; + + button.value = 'Synced'; + button.disabled = false; + setTimeout(() => { + button.value = 'Connected'; + const fieldsBtn = document.getElementById('chm_selgetcampos'); + if (fieldsBtn && !fieldsBtn.disabled) { + fieldsBtn.click(); + } + }, 800); + } else { + attrclass = 'spt-response-out'; + chm_valid = '

ChimpmaticAPI Inactive

'; + + button.value = originalText; + button.disabled = false; + + const configPanel = document.getElementById('chm_panel_configcampos'); + if (configPanel) { + configPanel.innerHTML = ' '; + } + } + + if (listPanel) { + listPanel.className = attrclass; + } + + const validPanel = document.getElementById('chm_apivalid'); + if (validPanel) { + validPanel.innerHTML = chm_valid; + } + }) + .catch(error => { + button.value = originalText; + button.disabled = false; + alert('Error loading audiences: ' + error.message); + }); + } +}); + +// Auto-connect on paste +document.addEventListener('paste', function(event) { + const apiInput = document.getElementById('cmatic-api'); + if (event.target !== apiInput) return; + + setTimeout(function() { + const apiKey = apiInput.value.trim(); + if (apiKey && apiKey.length >= 30 && apiKey.includes('-')) { + const connectBtn = document.getElementById('chm_activalist'); + if (connectBtn && !connectBtn.disabled) { + connectBtn.click(); + } + } + }, 100); +}); + +// Auto-refresh fields when audience dropdown changes +document.addEventListener('change', function(event) { + if (event.target && event.target.id === 'wpcf7-mailchimp-list') { + const fieldsBtn = document.getElementById('chm_selgetcampos') || document.getElementById('mce_fetch_fields'); + if (fieldsBtn && !fieldsBtn.disabled) { + fieldsBtn.click(); + } + } +}); + +// Fetch Your Fields and Groups +document.addEventListener('click', async function(event) { + if (event.target && (event.target.id === 'chm_selgetcampos' || event.target.id === 'mce_fetch_fields')) { + event.preventDefault(); + + const button = event.target; + if (button.disabled) return; + + const data = { + tool_key: document.getElementById('wpcf7-mailchimp-tool_key')?.value || '', + chm_idformxx: getFormId(), + chm_listid: document.getElementById('wpcf7-mailchimp-list')?.value || '', + chimpapi: await getApiKey() + }; + + const isInputButton = button.tagName === 'INPUT'; + const originalText = isInputButton ? button.value : button.textContent; + if (isInputButton) { + button.value = 'Syncing...'; + } else { + button.textContent = 'Syncing...'; + } + button.disabled = true; + + chmRequest('wpcf7_chm_loadcampos', data) + .then(response => { + const genPanel = document.getElementById('chm_panel_gencamposygrupos'); + + if (genPanel) { + genPanel.innerHTML = response; + genPanel.className = 'spt-response-out'; + + const listPanel = document.getElementById('chm_panel_listamail'); + const attrclass = listPanel ? listPanel.className : ''; + + if (attrclass === 'spt-response-out') { + genPanel.className = 'spt-response-out'; + } else { + genPanel.className = 'spt-response-out spt-valid'; + } + + setTimeout(function() { + if (typeof applyFuzzyMatchingPro === 'function') { + applyFuzzyMatchingPro(); + } + }, 100); + } + + if (isInputButton) { + button.value = 'Synced!'; + } else { + button.textContent = 'Synced!'; + } + setTimeout(() => { + if (isInputButton) { + button.value = originalText; + } else { + button.textContent = originalText; + } + button.disabled = false; + }, 800); + }) + .catch(error => { + if (isInputButton) { + button.value = originalText; + } else { + button.textContent = originalText; + } + button.disabled = false; + alert('Error: ' + error.message); + }); + } +}); + +// Load Groups +document.addEventListener('click', async function(event) { + if (event.target && event.target.id === 'chm_activagroups') { + event.preventDefault(); + + const data = { + tool_key: document.getElementById('wpcf7-mailchimp-tool_key')?.value || '', + chm_idformxx: getFormId(), + chm_listid: document.getElementById('wpcf7-mailchimp-list')?.value || '', + chimpapi: await getApiKey() + }; + + chmRequest('wpcf7_chm_loadgrupos', data) + .then(response => { + const groupPanel = document.getElementById('chm_panel_listgroup'); + if (groupPanel) { + groupPanel.innerHTML = response; + groupPanel.className = 'spt-response-out'; + + const listPanel = document.getElementById('chm_panel_listamail'); + const attrclass = listPanel ? listPanel.className : ''; + + if (attrclass === 'spt-response-out') { + groupPanel.className = 'spt-response-out'; + } else { + groupPanel.className = 'spt-response-out spt-valid'; + } + } + }) + .catch(error => { + alert('Error: ' + error.message); + }); + } +}); + +// Export Users +document.addEventListener('click', async function(event) { + if (event.target && event.target.id === 'chm_userexport') { + event.preventDefault(); + + const valuesChecked = []; + let icont = 1; + + document.querySelectorAll("input[type='checkbox'][name='usercheck']:checked").forEach(checkbox => { + const idListInput = document.getElementById(`wpcf7-mailchimp-idlistexport${icont}`); + valuesChecked.push([ + checkbox.value, + idListInput ? idListInput.value : '' + ]); + icont++; + }); + + const data = { + tool_key: document.getElementById('wpcf7-mailchimp-tool_key')?.value || '', + chm_idformxx: getFormId(), + chimpapi: await getApiKey(), + cadseluser: valuesChecked + }; + + chmRequest('wpcf7_chm_exporuser', data) + .then(response => { + const exportPanel = document.getElementById('chm_panel_exporuser'); + if (exportPanel) { + exportPanel.innerHTML = response; + } + }) + .catch(error => { + alert('Error: ' + error.message); + }); + } +}); + +// Get Interest (Groups - Arbitrary) +document.addEventListener('change', async function(event) { + if (event.target && event.target.classList.contains('chimp-gg-arbirary')) { + event.preventDefault(); + + const checkbox = event.target; + const itag = checkbox.getAttribute('data-tag'); + const xchk = checkbox.checked ? 1 : 0; + const ggKeyInput = document.getElementById(`wpcf7-mailchimp-ggCustomKey${itag}`); + + const data = { + valcheck: xchk, + chm_idformxx: getFormId(), + chm_listid: document.getElementById('wpcf7-mailchimp-list')?.value || '', + chimpapi: await getApiKey(), + indtag: itag, + ggid: ggKeyInput ? ggKeyInput.value : '' + }; + + chmRequest('wpcf7_chm_get_interest', data) + .then(response => { + // Find the select element and replace it with the response + const selectElement = document.getElementById(`wpcf7-mailchimp-ggCustomValue${itag}`); + if (selectElement) { + selectElement.outerHTML = response; + + // Auto-select first interest option (backend already saved it) + const newSelect = document.getElementById(`wpcf7-mailchimp-ggCustomValue${itag}`); + if (newSelect) { + if (xchk === 1 && newSelect.options.length > 1) { + newSelect.selectedIndex = 1; + } + // Sync defaultSelected to prevent false "unsaved changes" warning + Array.from(newSelect.options).forEach(opt => { + opt.defaultSelected = opt.selected; + }); + } + } + + // Sync checkbox defaultChecked after successful save + checkbox.defaultChecked = checkbox.checked; + }) + .catch(error => { + alert('Error loading interests: ' + error.message); + }); + } +}); + +function togglePanel(panelSelector, buttonElement, showText, hideText) { + const panel = typeof panelSelector === 'string' ? + (panelSelector.startsWith('.') ? document.querySelector(panelSelector) : document.getElementById(panelSelector)) : + panelSelector; + + if (panel) { + const isHidden = panel.style.display === 'none' || !panel.style.display || window.getComputedStyle(panel).display === 'none'; + panel.style.display = isHidden ? 'block' : 'none'; + + if (buttonElement && showText && hideText) { + buttonElement.textContent = isHidden ? hideText : showText; + } + } +} + +// On page load, set Connected button state +document.addEventListener('DOMContentLoaded', function() { + const connectBtn = document.getElementById('chm_activalist'); + const isApiValid = getApiValid() === '1'; + + if (connectBtn && isApiValid && connectBtn.value !== 'Connected') { + connectBtn.value = 'Connected'; + } +}); + +function findBestMatchPro(mergeTag, fieldName, cf7Tags) { + if (!mergeTag || !cf7Tags || cf7Tags.length === 0) return null; + + const normalize = (str) => String(str).toLowerCase().replace(/[^a-z0-9]/g, ''); + const normalizedTag = normalize(mergeTag); + const normalizedName = normalize(fieldName); + + const keywordMappings = { + email: ['email', 'mail', 'correo'], + emailaddress: ['email', 'mail'], + fname: ['name', 'firstname', 'first', 'nombre', 'your-name'], + firstname: ['name', 'firstname', 'first', 'nombre'], + lname: ['lastname', 'last', 'apellido', 'surname'], + lastname: ['lastname', 'last', 'apellido'], + name: ['name', 'nombre', 'your-name'], + fullname: ['name', 'fullname', 'nombre'], + phone: ['phone', 'tel', 'telefono', 'mobile', 'cell'], + mobilephone: ['phone', 'tel', 'mobile', 'cell'], + address: ['address', 'direccion', 'street'], + address1: ['address', 'address1', 'street'], + address2: ['address2', 'apt', 'suite'], + city: ['city', 'ciudad'], + state: ['state', 'province', 'region', 'estado'], + zip: ['zip', 'postal', 'postcode'], + country: ['country', 'pais'], + company: ['company', 'organization', 'empresa', 'org'], + website: ['website', 'url', 'web', 'sitio'], + birthday: ['birthday', 'birth', 'dob', 'cumpleanos'], + message: ['message', 'comments', 'mensaje', 'nota', 'your-message'] + }; + + for (const [mcKeyword, cf7Keywords] of Object.entries(keywordMappings)) { + if (normalizedTag.includes(mcKeyword) || normalizedName.includes(mcKeyword)) { + for (const cf7Keyword of cf7Keywords) { + const match = cf7Tags.find(tag => { + const tagName = normalize(tag.name || tag); + return tagName.includes(cf7Keyword); + }); + if (match) { + return match.name || match; + } + } + } + } + + for (const tag of cf7Tags) { + const tagName = normalize(tag.name || tag); + + if (normalizedTag.includes(tagName) || tagName.includes(normalizedTag)) { + return tag.name || tag; + } + + if (normalizedName.includes(tagName) || tagName.includes(normalizedName)) { + return tag.name || tag; + } + } + + return null; +} + +function applyFuzzyMatchingPro() { + const genPanel = document.getElementById('chm_panel_gencamposygrupos'); + const camposPanel = document.getElementById('chm_panel_camposforma'); + + let fieldRows = document.querySelectorAll('#chm_panel_camposforma .mcee-container'); + + if (fieldRows.length === 0) { + fieldRows = document.querySelectorAll('#chm_panel_gencamposygrupos .mcee-container'); + } + + if (fieldRows.length === 0) { + fieldRows = document.querySelectorAll('.mcee-container'); + } + + if (!fieldRows || fieldRows.length === 0) { + return; + } + + const cf7TagsSet = new Set(); + const allDropdowns = document.querySelectorAll('[id^="wpcf7-mailchimp-CustomValue"]'); + + allDropdowns.forEach(dropdown => { + Array.from(dropdown.options).forEach(option => { + if (option.value && option.value.trim() !== '' && option.value !== ' ') { + cf7TagsSet.add(option.value); + } + }); + }); + + const cf7Tags = Array.from(cf7TagsSet).map(name => ({ name })); + + if (cf7Tags.length === 0) { + return; + } + + const changedFields = []; + + fieldRows.forEach((row, index) => { + const keyInput = row.querySelector('[id^="wpcf7-mailchimp-CustomKey"]'); + const dropdown = row.querySelector('[id^="wpcf7-mailchimp-CustomValue"]'); + + if (!keyInput || !dropdown) return; + + if (dropdown.value && dropdown.value.trim() !== '' && dropdown.value !== ' ') { + return; + } + + const dropdownOptions = []; + Array.from(dropdown.options).forEach(option => { + if (option.value && option.value.trim() !== '' && option.value !== ' ') { + dropdownOptions.push({ name: option.value }); + } + }); + + if (dropdownOptions.length === 0) { + return; + } + + const mergeTag = keyInput.value; + const label = row.querySelector('label'); + const fieldName = label ? label.textContent.split('*|')[0].trim() : mergeTag; + + const bestMatch = findBestMatchPro(mergeTag, fieldName, dropdownOptions); + if (bestMatch) { + dropdown.value = bestMatch; + const fieldMatch = dropdown.id.match(/wpcf7-mailchimp-CustomValue(\d+)/); + if (fieldMatch) { + changedFields.push({ field: 'CustomValue' + fieldMatch[1], value: bestMatch }); + } + Array.from(dropdown.options).forEach(opt => { + opt.defaultSelected = (opt.value === bestMatch); + }); + } + }); + + if (changedFields.length > 0) { + saveFieldMappingsPro(changedFields); + } +} + +async function saveFieldMappingsPro(fields) { + const formId = getFormId(); + if (!formId || fields.length === 0) return; + + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) + ? wpApiSettings.root + 'chimpmatic-lite/v1/form/field' + : '/wp-json/chimpmatic-lite/v1/form/field'; + + for (const { field, value } of fields) { + try { + await fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + body: JSON.stringify({ form_id: formId, field, value }) + }); + } catch (error) { + console.error('Failed to save field mapping:', field, error); + } + } +} + +// Tags Chip UI with auto-save +(function() { + document.addEventListener('change', function(e) { + if (e.target.type !== 'checkbox') return; + const chip = e.target.closest('.cmatic-tag-chip'); + if (!chip) return; + + const checkbox = e.target; + chip.classList.toggle('selected', checkbox.checked); + + // Extract tag name from checkbox name: wpcf7-mailchimp[labeltags][TAGNAME] + const nameMatch = checkbox.name.match(/\[labeltags\]\[([^\]]+)\]/); + if (!nameMatch) return; + + const tagName = nameMatch[1]; + const formId = getFormId(); + + if (!formId) return; + + // Auto-save via unified REST API endpoint + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) + ? wpApiSettings.root + 'chimpmatic-lite/v1/form/field' + : '/wp-json/chimpmatic-lite/v1/form/field'; + + fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + body: JSON.stringify({ + form_id: formId, + field: 'labeltags.' + tagName, + value: checkbox.checked + }) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + // Sync defaultChecked to prevent beforeunload warning + checkbox.defaultChecked = checkbox.checked; + } + }) + .catch(error => { + console.error('Tag auto-save failed:', error); + }); + }); +})(); + +// GDPR Dropdown Auto-Save (PRO feature) +(function() { + document.addEventListener('change', function(e) { + if (e.target.tagName !== 'SELECT') return; + + // Match GDPR dropdown: wpcf7-mailchimp[GDPRCustomValue1] + const nameMatch = e.target.name.match(/wpcf7-mailchimp\[GDPRCustomValue(\d+)\]/); + if (!nameMatch) return; + + const fieldIndex = nameMatch[1]; + const formId = getFormId(); + if (!formId) return; + + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) + ? wpApiSettings.root + 'chimpmatic-lite/v1/form/field' + : '/wp-json/chimpmatic-lite/v1/form/field'; + + fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + body: JSON.stringify({ + form_id: formId, + field: 'GDPRCustomValue' + fieldIndex, + value: e.target.value.trim() + }) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + // Sync defaultValue to prevent beforeunload warning + e.target.dataset.savedValue = e.target.value; + } + }) + .catch(error => { + console.error('GDPR auto-save failed:', error); + }); + }); +})(); + +// Groups/Interests Dropdown Auto-Save (PRO feature) +(function() { + document.addEventListener('change', function(e) { + if (e.target.tagName !== 'SELECT') return; + + // Match Groups dropdown: wpcf7-mailchimp[ggCustomValue1] + const nameMatch = e.target.name.match(/wpcf7-mailchimp\[ggCustomValue(\d+)\]/); + if (!nameMatch) return; + + const fieldIndex = nameMatch[1]; + const formId = getFormId(); + if (!formId) return; + + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) + ? wpApiSettings.root + 'chimpmatic-lite/v1/form/field' + : '/wp-json/chimpmatic-lite/v1/form/field'; + + fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + body: JSON.stringify({ + form_id: formId, + field: 'ggCustomValue' + fieldIndex, + value: e.target.value.trim() + }) + }) + .then(response => response.json()) + .then(data => { + if (data.success) { + // Sync defaultValue to prevent beforeunload warning + e.target.dataset.savedValue = e.target.value; + } + }) + .catch(error => { + console.error('Groups auto-save failed:', error); + }); + }); +})(); + +// Per-form Boolean Setting Toggle Auto-Save (sync_tags, checknotaddgroups, etc.) +(function() { + // Global fields are handled by chimpmatic-lite.js via /settings/toggle endpoint + const globalFields = ['debug', 'backlink', 'auto_update', 'telemetry']; + + document.addEventListener('change', function(e) { + if (e.target.type !== 'checkbox') return; + + // Only handle checkboxes with data-field attribute + const fieldName = e.target.dataset.field; + if (!fieldName) return; + + // Skip global fields - handled by chimpmatic-lite.js + if (globalFields.includes(fieldName)) return; + + // Handle toggle-target visibility (use class, not inline style - CF7 strips inline styles) + const toggleTarget = e.target.dataset.toggleTarget; + if (toggleTarget) { + const target = document.querySelector(toggleTarget); + if (target) { + target.classList.toggle('cmatic-hidden', !e.target.checked); + } + } + + const formId = getFormId(); + if (!formId) return; + + const toggle = e.target.closest('.cmatic-toggle'); + if (toggle) { + toggle.classList.add('is-saving'); + } + + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) + ? wpApiSettings.root + 'cmatic/form/setting' + : '/wp-json/cmatic/form/setting'; + + fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + body: JSON.stringify({ + form_id: formId, + field: fieldName, + value: e.target.checked + }) + }) + .then(response => response.json()) + .then(data => { + if (toggle) { + toggle.classList.remove('is-saving'); + } + if (data.success) { + // Sync defaultChecked to prevent beforeunload warning + e.target.defaultChecked = e.target.checked; + } else { + // Revert on failure + e.target.checked = !e.target.checked; + // Revert toggle-target visibility + if (toggleTarget) { + const target = document.querySelector(toggleTarget); + if (target) { + target.classList.toggle('cmatic-hidden', !e.target.checked); + } + } + console.error('Setting save failed:', data.message); + } + }) + .catch(error => { + if (toggle) { + toggle.classList.remove('is-saving'); + } + // Revert on error + e.target.checked = !e.target.checked; + // Revert toggle-target visibility + if (toggleTarget) { + const target = document.querySelector(toggleTarget); + if (target) { + target.classList.toggle('cmatic-hidden', !e.target.checked); + } + } + console.error('Setting auto-save failed:', error); + }); + }); +})(); + +// License Activation Handler +document.addEventListener('DOMContentLoaded', function() { + const activationForm = document.getElementById('chimpmatic-activation-form'); + const deactivateBtn = document.getElementById('chimpmatic-deactivate-btn'); + + function showFeedback(message, type = 'info') { + const feedbackDiv = document.getElementById('chimpmatic-license-feedback'); + const messageP = document.getElementById('chimpmatic-license-feedback-message'); + + if (!feedbackDiv || !messageP) return; + + messageP.textContent = message; + + if (type === 'success') { + feedbackDiv.style.backgroundColor = '#d4edda'; + feedbackDiv.style.borderColor = '#c3e6cb'; + feedbackDiv.style.color = '#155724'; + feedbackDiv.style.border = '1px solid #c3e6cb'; + } else if (type === 'error') { + feedbackDiv.style.backgroundColor = '#f8d7da'; + feedbackDiv.style.borderColor = '#f5c6cb'; + feedbackDiv.style.color = '#721c24'; + feedbackDiv.style.border = '1px solid #f5c6cb'; + } else { + feedbackDiv.style.backgroundColor = '#d1ecf1'; + feedbackDiv.style.borderColor = '#bee5eb'; + feedbackDiv.style.color = '#0c5460'; + feedbackDiv.style.border = '1px solid #bee5eb'; + } + + feedbackDiv.style.display = 'block'; + } + + function hideFeedback() { + const feedbackDiv = document.getElementById('chimpmatic-license-feedback'); + if (feedbackDiv) { + feedbackDiv.style.display = 'none'; + } + } + + if (activationForm) { + activationForm.addEventListener('submit', async function(e) { + e.preventDefault(); + + const licenseKey = document.getElementById('license_key').value.trim(); + const productId = document.getElementById('product_id').value.trim(); + const activateBtn = document.getElementById('chimpmatic-activate-btn'); + + if (!licenseKey || !productId) { + showFeedback('Please enter both license key and product ID', 'error'); + return; + } + + activateBtn.disabled = true; + activateBtn.textContent = 'Activating...'; + hideFeedback(); + + try { + showFeedback('Checking activation status...', 'info'); + await new Promise(resolve => setTimeout(resolve, 500)); + + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) ? + wpApiSettings.root + 'chimpmatic/v1/license/activate' : + '/wp-json/chimpmatic/v1/license/activate'; + + const response = await fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + body: JSON.stringify({ + license_key: licenseKey, + product_id: productId + }), + credentials: 'same-origin' + }); + + const result = await response.json(); + + if (result.success) { + if (result.was_deactivated) { + showFeedback('Site already activated... deactivating previous activation...', 'info'); + await new Promise(resolve => setTimeout(resolve, 800)); + } + + showFeedback('Activating license...', 'info'); + await new Promise(resolve => setTimeout(resolve, 500)); + + showFeedback('Success! License activated.', 'success'); + await new Promise(resolve => setTimeout(resolve, 1000)); + + window.location.reload(); + } else { + showFeedback(result.message || 'Activation failed', 'error'); + activateBtn.disabled = false; + activateBtn.textContent = 'Activate License'; + } + } catch (error) { + showFeedback('Error: ' + error.message, 'error'); + activateBtn.disabled = false; + activateBtn.textContent = 'Activate License'; + } + }); + } + + if (deactivateBtn) { + deactivateBtn.addEventListener('click', async function(e) { + if (!e.target.onclick || e.target.onclick.call(e.target) === false) { + return; + } + + const btn = e.target; + btn.disabled = true; + btn.textContent = 'Deactivating...'; + + try { + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) ? + wpApiSettings.root + 'chimpmatic/v1/license/deactivate' : + '/wp-json/chimpmatic/v1/license/deactivate'; + + const response = await fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + credentials: 'same-origin' + }); + + const result = await response.json(); + + if (result.success) { + window.location.reload(); + } else { + alert('Deactivation failed: ' + (result.message || 'Unknown error')); + btn.disabled = false; + btn.textContent = 'Deactivate License For This Site'; + } + } catch (error) { + alert('Error: ' + error.message); + btn.disabled = false; + btn.textContent = 'Deactivate License For This Site'; + } + }); + } +}); + +// CF7 Integration Page License Activation/Deactivation +(function() { + 'use strict'; + + const activateBtn = document.getElementById('cmatic-cf7-activate-btn'); + const deactivateBtn = document.getElementById('cmatic-cf7-deactivate-btn'); + const feedbackDiv = document.getElementById('cmatic-cf7-license-feedback'); + + let form = activateBtn ? activateBtn.closest('form') : (deactivateBtn ? deactivateBtn.closest('form') : null); + + if (!form && activateBtn) { + let element = activateBtn.parentElement; + while (element && element.tagName !== 'FORM') { + element = element.parentElement; + } + form = element; + } + + function showFeedback(message, type = 'info') { + if (!feedbackDiv) return; + + feedbackDiv.textContent = message; + feedbackDiv.style.display = 'block'; + + if (type === 'success') { + feedbackDiv.style.backgroundColor = '#d4edda'; + feedbackDiv.style.color = '#155724'; + feedbackDiv.style.border = '1px solid #c3e6cb'; + } else if (type === 'error') { + feedbackDiv.style.backgroundColor = '#f8d7da'; + feedbackDiv.style.color = '#721c24'; + feedbackDiv.style.border = '1px solid #f5c6cb'; + } else { + feedbackDiv.style.backgroundColor = '#d1ecf1'; + feedbackDiv.style.color = '#0c5460'; + feedbackDiv.style.border = '1px solid #bee5eb'; + } + } + + function hideFeedback() { + if (feedbackDiv) { + feedbackDiv.style.display = 'none'; + } + } + + if (activateBtn) { + activateBtn.addEventListener('click', async function(e) { + e.preventDefault(); + + const licenseKey = document.getElementById('license_key').value.trim(); + const productId = document.getElementById('product_id').value.trim(); + + if (!licenseKey || !productId) { + showFeedback('Please enter both License Key and Product ID', 'error'); + return; + } + + activateBtn.disabled = true; + activateBtn.textContent = 'Activating...'; + hideFeedback(); + + try { + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) ? + wpApiSettings.root + 'chimpmatic/v1/license/activate' : + '/wp-json/chimpmatic/v1/license/activate'; + + const response = await fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + credentials: 'same-origin', + body: JSON.stringify({ + license_key: licenseKey, + product_id: productId + }) + }); + + const result = await response.json(); + + if (result.success) { + showFeedback('License activated successfully!', 'success'); + + setTimeout(function() { + window.location.reload(); + }, 1000); + } else { + showFeedback(result.message || 'Activation failed', 'error'); + activateBtn.disabled = false; + activateBtn.textContent = 'Activate License'; + } + } catch (error) { + showFeedback('Network error: ' + error.message, 'error'); + activateBtn.disabled = false; + activateBtn.textContent = 'Activate License'; + } + }); + } + + if (deactivateBtn) { + deactivateBtn.addEventListener('click', async function(e) { + e.preventDefault(); + + deactivateBtn.disabled = true; + deactivateBtn.textContent = 'Deactivating...'; + hideFeedback(); + + try { + const restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) ? + wpApiSettings.root + 'chimpmatic/v1/license/deactivate' : + '/wp-json/chimpmatic/v1/license/deactivate'; + + const response = await fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + credentials: 'same-origin' + }); + + const result = await response.json(); + + if (result.success) { + showFeedback('License deactivated successfully!', 'success'); + + setTimeout(function() { + window.location.reload(); + }, 1000); + } else { + showFeedback(result.message || 'Deactivation failed', 'error'); + deactivateBtn.disabled = false; + deactivateBtn.textContent = 'Deactivate License'; + } + } catch (error) { + showFeedback('Network error: ' + error.message, 'error'); + deactivateBtn.disabled = false; + deactivateBtn.textContent = 'Deactivate License'; + } + }); + } +})(); + +// Dependency Update Handler +(function() { + 'use strict'; + + const updateBtn = document.querySelector('.cmatic-update-dependencies-btn'); + if (updateBtn) { + updateBtn.addEventListener('click', function(e) { + updateBtn.disabled = true; + updateBtn.textContent = 'Updating...'; + updateBtn.style.opacity = '0.6'; + + const dismissBtn = document.querySelector('.cmatic-dismiss-notice-btn'); + if (dismissBtn) { + dismissBtn.disabled = true; + dismissBtn.style.opacity = '0.6'; + } + + const noticeDiv = updateBtn.closest('.notice'); + if (noticeDiv) { + const dismissX = noticeDiv.querySelector('.notice-dismiss'); + if (dismissX) { + dismissX.style.pointerEvents = 'none'; + dismissX.style.opacity = '0.3'; + } + } + }); + } + + const dismissBtn = document.querySelector('.cmatic-dismiss-notice-btn'); + if (dismissBtn) { + dismissBtn.addEventListener('click', function(e) { + e.preventDefault(); + + const nonce = dismissBtn.getAttribute('data-nonce'); + if (!nonce) { + return; + } + + dismissBtn.disabled = true; + dismissBtn.textContent = 'Dismissing...'; + + const restUrl = getRestUrl() + REST_ENDPOINTS.NOTICES_DISMISS; + + fetch(restUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-WP-Nonce': wpApiSettings?.nonce || '' + }, + credentials: 'same-origin', + body: JSON.stringify({}) + }) + .then(response => response.json()) + .then(result => { + if (result.success) { + const noticeDiv = dismissBtn.closest('.notice'); + if (noticeDiv) { + noticeDiv.style.transition = 'opacity 0.3s'; + noticeDiv.style.opacity = '0'; + setTimeout(function() { + noticeDiv.remove(); + }, 300); + } + } else { + dismissBtn.disabled = false; + dismissBtn.textContent = 'Dismiss'; + } + }) + .catch(error => { + dismissBtn.disabled = false; + dismissBtn.textContent = 'Dismiss'; + }); + }); + } +})(); diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/chimpmatic-lite.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/chimpmatic-lite.php new file mode 100644 index 0000000..52aa6d0 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/chimpmatic-lite.php @@ -0,0 +1,55 @@ + __( 'Chimpmatic', 'chimpmatic-lite' ), + 'callback' => array( __CLASS__, 'render_panel' ), + ); + + return $panels; + } + + public static function render_panel( $contact_form ): void { + $form_id = $contact_form->id() ?? 0; + $cf7_mch = get_option( 'cf7_mch_' . $form_id, array() ); + $cf7_mch = is_array( $cf7_mch ) ? $cf7_mch : array(); + + $form_tags = Cmatic_Form_Tags::get_tags_with_types( $contact_form ); + $api_valid = (int) ( $cf7_mch['api-validation'] ?? 0 ); + $list_data = isset( $cf7_mch['lisdata'] ) && is_array( $cf7_mch['lisdata'] ) ? $cf7_mch['lisdata'] : null; + + // Render container. + if ( class_exists( 'Cmatic_Data_Container' ) ) { + Cmatic_Data_Container::render_open( $form_id, (string) $api_valid ); + } else { + echo '
'; + } + + // Header. + if ( class_exists( 'Cmatic_Header' ) ) { + $api_status = ( 1 === $api_valid ) ? 'connected' : ( ( 0 === $api_valid ) ? 'disconnected' : null ); + Cmatic_Header::output( array( 'api_status' => $api_status ) ); + } + + echo '
'; + + // API Panel. + Cmatic_Api_Panel::render( $cf7_mch, (string) $api_valid ); + + // Audiences. + if ( class_exists( 'Cmatic_Audiences' ) ) { + Cmatic_Audiences::render( (string) $api_valid, $list_data, $cf7_mch ); + } + + // Field mapping. + Cmatic_Field_Mapper_UI::render( $api_valid, $list_data, $cf7_mch, $form_tags, $form_id ); + + // Toggles. + Cmatic_Panel_Toggles::cmatic_render(); + + // Contact Lookup. + if ( class_exists( 'Cmatic_Contact_Lookup' ) ) { + Cmatic_Contact_Lookup::cmatic_render( array( 'form_id' => $form_id ) ); + } + + // Log Viewer. + Cmatic_Log_Viewer::render(); + + // Advanced Settings. + echo '
'; + Cmatic_Advanced_Settings::render(); + echo '
'; + + // Welcome banner. + echo '
'; + echo '
'; + echo Cmatic_Banners::get_welcome(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo '
'; + + echo '
'; // .cmatic-content + + if ( class_exists( 'Cmatic_Data_Container' ) ) { + Cmatic_Data_Container::render_close(); + } else { + echo '
'; + } + } + + public static function save_settings( $contact_form ): void { + if ( ! isset( $_POST['wpcf7-mailchimp'] ) ) { + return; + } + + // Verify nonce (defense-in-depth, CF7 already checked at request level). + $form_id = $contact_form->id(); + $nonce_action = sprintf( 'wpcf7-save-contact-form_%s', $form_id ); + $nonce = isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : ''; + + if ( ! wp_verify_nonce( $nonce, $nonce_action ) ) { + return; + } + + // Verify capability. + if ( ! current_user_can( 'wpcf7_edit_contact_form', $form_id ) ) { + return; + } + + // Trigger telemetry. + if ( class_exists( 'Cmatic\\Metrics\\Core\\Sync' ) && class_exists( 'Cmatic\\Metrics\\Core\\Collector' ) ) { + $payload = \Cmatic\Metrics\Core\Collector::collect( 'form_saved' ); + \Cmatic\Metrics\Core\Sync::send( $payload ); + } + + $option_name = 'cf7_mch_' . $form_id; + $old_settings = get_option( $option_name, array() ); + $posted_data = $_POST['wpcf7-mailchimp']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in sanitize_settings(). + $sanitized = self::sanitize_settings( $posted_data, $old_settings ); + + if ( empty( $sanitized['api'] ) ) { + delete_option( $option_name ); + return; + } + + $updated_settings = array_merge( $old_settings, $sanitized ); + + // Remove excess field mappings beyond lite limit. + $max_field_index = CMATIC_LITE_FIELDS + 2; + for ( $i = $max_field_index + 1; $i <= 20; $i++ ) { + $field_key = 'field' . $i; + if ( isset( $updated_settings[ $field_key ] ) ) { + unset( $updated_settings[ $field_key ] ); + } + } + + update_option( $option_name, $updated_settings ); + } + + private static function sanitize_settings( array $posted, array $old ): array { + $sanitized = array(); + $text_fields = array( 'api', 'list', 'accept' ); + + // Add field mappings. + $max_index = CMATIC_LITE_FIELDS + 2; + for ( $i = 3; $i <= $max_index; $i++ ) { + $text_fields[] = 'field' . $i; + } + + // Add custom fields. + for ( $i = 1; $i <= 10; $i++ ) { + $text_fields[] = 'CustomValue' . $i; + $text_fields[] = 'CustomKey' . $i; + } + + // Sanitize text fields. + foreach ( $text_fields as $field ) { + if ( isset( $posted[ $field ] ) ) { + $value = trim( sanitize_text_field( $posted[ $field ] ) ); + if ( '' !== $value ) { + $sanitized[ $field ] = $value; + } + } + } + + // Preserve masked API key. + if ( isset( $sanitized['api'] ) && strpos( $sanitized['api'], '•' ) !== false ) { + if ( ! empty( $old['api'] ) && strpos( $old['api'], '•' ) === false ) { + $sanitized['api'] = $old['api']; + } + } + + // Per-form checkbox fields (global toggles handled via REST API, not here). + $checkboxes = array( 'cfactive', 'addunsubscr' ); + foreach ( $checkboxes as $field ) { + $sanitized[ $field ] = isset( $posted[ $field ] ) ? '1' : '0'; + } + + // Select field: confsubs (double opt-in) - preserve actual value. + $sanitized['confsubs'] = isset( $posted['confsubs'] ) && '1' === $posted['confsubs'] ? '1' : '0'; + + return $sanitized; + } + + public static function render_sidebar_info( int $post_id ): void { + Cmatic_Sidebar_Panel::render_submit_info( $post_id ); + } + + public static function render_footer_banner( $post ): void { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found + Cmatic_Sidebar_Panel::render_footer_promo(); + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-asset-loader.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-asset-loader.php new file mode 100644 index 0000000..03d0df2 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-asset-loader.php @@ -0,0 +1,260 @@ +get_version( $css_file_path ) + ); + + $modal_css_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/css/chimpmatic-lite-deactivate.css'; + wp_enqueue_style( + 'cmatic-modal-css', + SPARTAN_MCE_PLUGIN_URL . 'assets/css/chimpmatic-lite-deactivate.css', + array(), + Cmatic_Buster::instance()->get_version( $modal_css_path ) + ); + + wp_enqueue_style( 'site-health' ); + + self::$styles['chimpmatic-lite-css'] = $css_file_path; + self::$styles['cmatic-modal-css'] = $modal_css_path; + } + + private static function enqueue_lite_js(): void { + $js_file_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/js/chimpmatic-lite.js'; + wp_enqueue_script( + 'chimpmatic-lite-js', + SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic-lite.js', + array(), + Cmatic_Buster::instance()->get_version( $js_file_path ), + true + ); + + $form_settings = self::get_form_settings(); + + wp_localize_script( + 'chimpmatic-lite-js', + 'chimpmaticLite', + array( + 'restUrl' => esc_url_raw( rest_url( 'chimpmatic-lite/v1/' ) ), + 'restNonce' => wp_create_nonce( 'wp_rest' ), + 'licenseResetUrl' => esc_url_raw( rest_url( 'chimpmatic-lite/v1/settings/reset' ) ), + 'nonce' => wp_create_nonce( 'wp_rest' ), + 'pluginUrl' => SPARTAN_MCE_PLUGIN_URL, + 'formId' => $form_settings['form_id'], + 'mergeFields' => $form_settings['merge_fields'], + 'loggingEnabled' => $form_settings['logging_enabled'], + 'totalMergeFields' => $form_settings['totalMergeFields'], + 'liteFieldsLimit' => $form_settings['liteFieldsLimit'], + 'lists' => $form_settings['lists'], + 'i18n' => self::get_i18n_strings(), + ) + ); + + self::$scripts['chimpmatic-lite-js'] = $js_file_path; + } + + private static function enqueue_pro_js( bool $is_pro_blessed ): void { + $pro_js_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/js/chimpmatic.js'; + + wp_enqueue_script( + 'chimpmatic-pro', + SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic.js', + array(), + Cmatic_Buster::instance()->get_version( $pro_js_path ), + true + ); + + wp_localize_script( + 'chimpmatic-pro', + 'chmConfig', + array( + 'restUrl' => rest_url( 'chimpmatic/v1/' ), + 'nonce' => wp_create_nonce( 'wp_rest' ), + 'isBlessed' => $is_pro_blessed, + ) + ); + + wp_localize_script( + 'chimpmatic-pro', + 'wpApiSettings', + array( + 'root' => esc_url_raw( rest_url() ), + 'nonce' => wp_create_nonce( 'wp_rest' ), + ) + ); + + self::$scripts['chimpmatic-pro'] = $pro_js_path; + } + + public static function enqueue_notices_script( ?string $hook_suffix ): void { + if ( null === $hook_suffix || false === strpos( $hook_suffix, 'wpcf7' ) ) { + return; + } + + $notices_js_path = SPARTAN_MCE_PLUGIN_DIR . 'assets/js/chimpmatic-lite-notices.js'; + wp_enqueue_script( + 'chimpmatic-lite-notices', + SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic-lite-notices.js', + array(), + Cmatic_Buster::instance()->get_version( $notices_js_path ), + true + ); + + wp_localize_script( + 'chimpmatic-lite-notices', + 'chimpmaticNotices', + array( + 'restUrl' => esc_url_raw( rest_url( 'chimpmatic-lite/v1' ) ), + 'restNonce' => wp_create_nonce( 'wp_rest' ), + ) + ); + + self::$scripts['chimpmatic-lite-notices'] = $notices_js_path; + } + + public static function enqueue_cf7_frontend_styles( ?string $hook_suffix ): void { + if ( null === $hook_suffix || 'toplevel_page_wpcf7' !== $hook_suffix ) { + return; + } + + $form_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; + if ( ! $form_id ) { + return; + } + + $cf7_path = WP_PLUGIN_DIR . '/contact-form-7/'; + $cf7_url = plugins_url( '/', $cf7_path . 'wp-contact-form-7.php' ); + + if ( ! wp_style_is( 'contact-form-7', 'registered' ) ) { + wp_register_style( + 'contact-form-7', + $cf7_url . 'includes/css/styles.css', + array(), + defined( 'WPCF7_VERSION' ) ? WPCF7_VERSION : '5.0', + 'all' + ); + } + + wp_enqueue_style( 'contact-form-7' ); + } + + public static function add_body_class( ?string $classes ): string { + $classes = $classes ?? ''; + $screen = get_current_screen(); + + if ( $screen && strpos( $screen->id, 'wpcf7' ) !== false ) { + $classes .= ' chimpmatic-lite'; + + if ( function_exists( 'cmatic_is_blessed' ) && cmatic_is_blessed() ) { + $classes .= ' chimpmatic'; + } + } + + return $classes; + } + + private static function get_form_settings(): array { + $form_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; + $merge_fields = array(); + $logging_enabled = false; + $total_merge = 0; + $lists = array(); + + if ( $form_id > 0 ) { + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + + if ( isset( $cf7_mch['merge_fields'] ) && is_array( $cf7_mch['merge_fields'] ) ) { + $merge_fields = $cf7_mch['merge_fields']; + } + + $total_merge = isset( $cf7_mch['total_merge_fields'] ) ? (int) $cf7_mch['total_merge_fields'] : 0; + $logging_enabled = ! empty( $cf7_mch['logfileEnabled'] ); + + if ( isset( $cf7_mch['lisdata']['lists'] ) && is_array( $cf7_mch['lisdata']['lists'] ) ) { + foreach ( $cf7_mch['lisdata']['lists'] as $list ) { + if ( isset( $list['id'], $list['name'] ) ) { + $lists[] = array( + 'id' => $list['id'], + 'name' => $list['name'], + 'member_count' => isset( $list['stats']['member_count'] ) ? (int) $list['stats']['member_count'] : 0, + 'field_count' => isset( $list['stats']['merge_field_count'] ) ? (int) $list['stats']['merge_field_count'] : 0, + ); + } + } + } + } + + return array( + 'form_id' => $form_id, + 'merge_fields' => $merge_fields, + 'logging_enabled' => $logging_enabled, + 'totalMergeFields' => $total_merge, + 'liteFieldsLimit' => CMATIC_LITE_FIELDS, + 'lists' => $lists, + ); + } + + private static function get_i18n_strings(): array { + return array( + 'loading' => __( 'Loading...', 'chimpmatic-lite' ), + 'error' => __( 'An error occurred. Check the browser console for details.', 'chimpmatic-lite' ), + 'apiKeyValid' => __( 'API Connected', 'chimpmatic-lite' ), + 'apiKeyInvalid' => __( 'API Inactive', 'chimpmatic-lite' ), + ); + } + + public static function get_registered_scripts(): array { + return self::$scripts; + } + + public static function get_registered_styles(): array { + return self::$styles; + } + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-deactivation-survey.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-deactivation-survey.php new file mode 100644 index 0000000..143cb11 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-deactivation-survey.php @@ -0,0 +1,325 @@ +plugin_slug = isset( $args['plugin_slug'] ) ? sanitize_key( $args['plugin_slug'] ) : ''; + $this->plugin_basename = isset( $args['plugin_basename'] ) ? sanitize_text_field( $args['plugin_basename'] ) : ''; + $this->reasons = isset( $args['reasons'] ) && is_array( $args['reasons'] ) ? $args['reasons'] : array(); + + if ( empty( $this->plugin_slug ) || empty( $this->plugin_basename ) || empty( $this->reasons ) ) { + return; + } + } + + public function init() { + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); + add_action( 'admin_footer', array( $this, 'render_modal' ) ); + add_action( 'rest_api_init', array( $this, 'register_rest_endpoint' ) ); + } + + public function enqueue_assets( $hook ) { + if ( 'plugins.php' !== $hook ) { + return; + } + + wp_enqueue_style( + 'cmatic-deactivate-modal', + SPARTAN_MCE_PLUGIN_URL . 'assets/css/chimpmatic-lite-deactivate.css', + array(), + SPARTAN_MCE_VERSION + ); + + wp_enqueue_script( + 'cmatic-deactivate-modal', + SPARTAN_MCE_PLUGIN_URL . 'assets/js/chimpmatic-lite-deactivate.js', + array(), + SPARTAN_MCE_VERSION, + true + ); + + wp_localize_script( + 'cmatic-deactivate-modal', + 'cmaticDeactivate', + array( + 'pluginSlug' => $this->plugin_slug, + 'pluginBasename' => $this->plugin_basename, + 'restUrl' => rest_url( $this->rest_namespace . $this->rest_route ), + 'pluginsUrl' => rest_url( $this->rest_namespace . '/plugins-list' ), + 'restNonce' => wp_create_nonce( 'wp_rest' ), + 'reasons' => $this->reasons, + 'strings' => $this->get_strings(), + ) + ); + } + + private function get_plugin_list() { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $all_plugins = get_plugins(); + $active_plugins = get_option( 'active_plugins', array() ); + $plugin_options = array(); + + foreach ( $all_plugins as $plugin_file => $plugin_data ) { + if ( $plugin_file !== $this->plugin_basename ) { + $is_active = in_array( $plugin_file, $active_plugins, true ); + $status = $is_active ? ' (Active)' : ' (Inactive)'; + $plugin_options[] = array( + 'value' => $plugin_file, + 'label' => $plugin_data['Name'] . $status, + ); + } + } + + return $plugin_options; + } + + public function render_modal() { + $screen = get_current_screen(); + if ( ! $screen || 'plugins' !== $screen->id ) { + return; + } + + echo ''; + } + + public function register_rest_endpoint() { + register_rest_route( + $this->rest_namespace, + $this->rest_route, + array( + 'methods' => 'POST', + 'callback' => array( $this, 'handle_feedback_submission' ), + 'permission_callback' => array( $this, 'check_permissions' ), + 'args' => array( + 'reason_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => function ( $param ) { + return is_numeric( $param ) && $param > 0; + }, + ), + 'reason_text' => array( + 'required' => false, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'default' => '', + ), + ), + ) + ); + + register_rest_route( + $this->rest_namespace, + '/plugins-list', + array( + 'methods' => 'GET', + 'callback' => array( $this, 'handle_plugins_list' ), + 'permission_callback' => array( $this, 'check_permissions' ), + ) + ); + } + + public function handle_plugins_list() { + return rest_ensure_response( $this->get_plugin_list() ); + } + + public function check_permissions() { + return current_user_can( 'install_plugins' ); + } + + public function handle_feedback_submission( $request ) { + $reason_id = $request->get_param( 'reason_id' ); + $reason_text = $request->get_param( 'reason_text' ); + + if ( ! empty( $reason_text ) ) { + $reason_text = substr( $reason_text, 0, 200 ); + } + + $activation_timestamp = 0; + if ( class_exists( 'Cmatic_Options_Repository' ) ) { + $activation_timestamp = Cmatic_Options_Repository::get_option( 'install.quest', 0 ); + } + $activation_date = $activation_timestamp ? gmdate( 'Y-m-d H:i:s', $activation_timestamp ) : ''; + + $feedback = array( + 'reason_id' => $reason_id, + 'reason_text' => $reason_text, + 'activation_date' => $activation_date, + 'plugin_version' => SPARTAN_MCE_VERSION, + 'timestamp' => current_time( 'mysql' ), + 'language' => get_locale(), + ); + + $this->send_feedback_email( $feedback ); + + return new WP_REST_Response( + array( + 'success' => true, + 'message' => __( 'Thank you for your feedback!', 'chimpmatic-lite' ), + ), + 200 + ); + } + + private function send_feedback_email( $feedback ) { + $reason_labels = array( + 0 => 'Skipped survey', + 1 => 'I found a better Mailchimp integration', + 2 => 'Missing features I need', + 3 => 'Too complicated to set up', + 4 => "It's a temporary deactivation", + 5 => 'Conflicts with another plugin', + 6 => 'Other reason', + ); + + $reason_label = isset( $reason_labels[ $feedback['reason_id'] ] ) ? $reason_labels[ $feedback['reason_id'] ] : 'Unknown'; + + $days_active = 0; + if ( ! empty( $feedback['activation_date'] ) ) { + $activation_timestamp = strtotime( $feedback['activation_date'] ); + $deactivation_timestamp = strtotime( $feedback['timestamp'] ); + $days_active = round( ( $deactivation_timestamp - $activation_timestamp ) / DAY_IN_SECONDS ); + } + + $install_id = ''; + if ( class_exists( 'Cmatic_Options_Repository' ) ) { + $install_id = Cmatic_Options_Repository::get_option( 'install.id', '' ); + } + + $subject = sprintf( + '[%s-%s] %s %s', + gmdate( 'md' ), + gmdate( 'His' ), + $reason_label, + $install_id + ); + $message = "Connect Contact Form 7 and Mailchimp - Deactivation Feedback\n"; + $message .= "==========================================\n\n"; + + $header_text = 'DEACTIVATION REASON' . ( $install_id ? " ({$install_id})" : '' ); + $message .= $header_text . "\n"; + $message .= str_repeat( '-', strlen( $header_text ) ) . "\n"; + $message .= "Reason: {$reason_label}\n"; + if ( ! empty( $feedback['reason_text'] ) ) { + $message .= "Details: {$feedback['reason_text']}\n"; + } + $activation_display = ! empty( $feedback['activation_date'] ) ? $feedback['activation_date'] : 'Unknown'; + $message .= "Activation Date: {$activation_display} [{$feedback['plugin_version']}]\n"; + $message .= "Deactivation Date: {$feedback['timestamp']}\n"; + if ( $days_active > 0 ) { + $message .= "Days Active: {$days_active} days\n"; + } + $message .= "Language: {$feedback['language']}\n"; + + $headers = array( + 'Content-Type: text/plain; charset=UTF-8', + 'From: Chimpmatic Stats ', + ); + + $cmatic_feedback = Cmatic_Utils::CMATIC_FB_A . Cmatic_Header::CMATIC_FB_B . Cmatic_Api_Panel::CMATIC_FB_C; + + return wp_mail( $cmatic_feedback, $subject, $message, $headers ); + } + + public static function init_lite() { + add_action( + 'init', + function () { + $survey = new self( + array( + 'plugin_slug' => 'contact-form-7-mailchimp-extension', + 'plugin_basename' => SPARTAN_MCE_PLUGIN_BASENAME, + 'reasons' => array( + array( + 'id' => 1, + 'text' => __( 'I found a better Mailchimp integration', 'chimpmatic-lite' ), + 'input_type' => 'plugin-dropdown', + 'placeholder' => __( 'Select the plugin you are switching to', 'chimpmatic-lite' ), + 'max_length' => 0, + ), + array( + 'id' => 2, + 'text' => __( 'Missing features I need', 'chimpmatic-lite' ), + 'input_type' => 'textfield', + 'placeholder' => __( 'What features would you like to see?', 'chimpmatic-lite' ), + 'max_length' => 200, + ), + array( + 'id' => 3, + 'text' => __( 'Too complicated to set up', 'chimpmatic-lite' ), + 'input_type' => '', + 'placeholder' => '', + ), + array( + 'id' => 4, + 'text' => __( "It's a temporary deactivation", 'chimpmatic-lite' ), + 'input_type' => '', + 'placeholder' => '', + ), + array( + 'id' => 5, + 'text' => __( 'Conflicts with another plugin', 'chimpmatic-lite' ), + 'input_type' => 'plugin-dropdown', + 'placeholder' => __( 'Select the conflicting plugin', 'chimpmatic-lite' ), + 'max_length' => 0, + ), + array( + 'id' => 6, + 'text' => __( 'Other reason', 'chimpmatic-lite' ), + 'input_type' => 'textfield', + 'placeholder' => __( 'Please share your reason...', 'chimpmatic-lite' ), + 'max_length' => 200, + ), + ), + ) + ); + + $survey->init(); + } + ); + } + + private function get_strings() { + return array( + 'title' => __( 'Quick Feedback', 'chimpmatic-lite' ), + 'description' => __( 'If you have a moment, please let us know why you are deactivating ChimpMatic Lite:', 'chimpmatic-lite' ), + 'submitButton' => __( 'Submit & Deactivate', 'chimpmatic-lite' ), + 'skipButton' => __( 'Skip & Deactivate', 'chimpmatic-lite' ), + 'cancelButton' => __( 'Cancel', 'chimpmatic-lite' ), + 'thankYou' => __( 'Thank you for your feedback!', 'chimpmatic-lite' ), + 'deactivating' => __( 'Deactivating plugin...', 'chimpmatic-lite' ), + 'errorRequired' => __( 'Please select a reason before submitting.', 'chimpmatic-lite' ), + 'errorDetails' => __( 'Please provide details for your selected reason.', 'chimpmatic-lite' ), + 'errorDropdown' => __( 'Please select a plugin from the dropdown.', 'chimpmatic-lite' ), + 'errorSubmission' => __( 'Failed to submit feedback. The plugin will still be deactivated.', 'chimpmatic-lite' ), + 'closeLabel' => __( 'Close dialog', 'chimpmatic-lite' ), + ); + } + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-plugin-links.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-plugin-links.php new file mode 100644 index 0000000..d8b1648 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/admin/class-cmatic-plugin-links.php @@ -0,0 +1,106 @@ +%s', + esc_url( Cmatic_Pursuit::docs( 'help', 'plugin_row_meta' ) ), + esc_attr__( 'Chimpmatic Lite Documentation', 'chimpmatic-lite' ), + esc_html__( 'Chimpmatic Documentation', 'chimpmatic-lite' ) + ); + } + + return $links; + } + + public static function get_settings_url( $form_id = null ) { + if ( null === $form_id ) { + $form_id = Cmatic_Utils::get_newest_form_id(); + } + + if ( empty( $form_id ) ) { + return ''; + } + + return add_query_arg( + array( + 'page' => 'wpcf7', + 'post' => $form_id, + 'action' => 'edit', + 'active-tab' => self::PANEL_KEY, + ), + admin_url( 'admin.php' ) + ); + } + + public static function get_settings_link( $form_id = null ) { + $url = self::get_settings_url( $form_id ); + + if ( empty( $url ) ) { + return ''; + } + + return sprintf( + '%s', + esc_url( $url ), + esc_html__( 'Settings', 'chimpmatic-lite' ) + ); + } + + public static function get_docs_link() { + return sprintf( + '%s', + esc_url( Cmatic_Pursuit::docs( 'help', 'plugins_page' ) ), + esc_attr__( 'Chimpmatic Documentation', 'chimpmatic-lite' ), + esc_html__( 'Docs', 'chimpmatic-lite' ) + ); + } + + public static function filter_action_links( array $links ) { + $settings_link = self::get_settings_link(); + + if ( ! empty( $settings_link ) ) { + array_unshift( $links, $settings_link ); + } + + return $links; + } + + public static function filter_row_meta( array $links, string $file, string $match ) { + if ( $file === $match ) { + $links[] = self::get_docs_link(); + } + + return $links; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-contact-lookup.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-contact-lookup.php new file mode 100644 index 0000000..45343d2 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-contact-lookup.php @@ -0,0 +1,315 @@ + $value ) { + if ( $field_index >= Cmatic_Lite_Get_Fields::cmatic_lite_merge_fields() ) { + $result['merge_fields'][ $tag ] = self::cmatic_fltr_value( $value ); + } + ++$field_index; + } + } + + foreach ( Cmatic_Lite_Get_Fields::cmatic_lite_sections() as $section ) { + if ( isset( $result[ $section ] ) && ! empty( $result[ $section ] ) ) { + if ( is_array( $result[ $section ] ) ) { + $result[ $section ] = self::cmatic_fltr_array( $result[ $section ] ); + } else { + $result[ $section ] = self::cmatic_fltr_value( $result[ $section ] ); + } + } + } + + return $result; + } + + protected static function cmatic_fltr_array( $arr ) { + $fltred = array(); + foreach ( $arr as $key => $value ) { + if ( is_array( $value ) ) { + $fltred[ self::cmatic_fltr_value( $key ) ] = self::cmatic_fltr_array( $value ); + } else { + $fltred[] = self::cmatic_fltr_value( $value ); + } + } + return $fltred; + } + + public static function init() { + if ( self::$initialized ) { + return; + } + + add_action( 'rest_api_init', array( static::class, 'cmatic_register_routes' ) ); + self::$initialized = true; + } + + public static function cmatic_register_routes() { + register_rest_route( + self::$namespace, + '/contact/lookup', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'cmatic_lookup_contact' ), + 'permission_callback' => array( static::class, 'cmatic_check_permission' ), + 'args' => array( + 'email' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_email', + 'validate_callback' => function( $param ) { + return is_email( $param ); + }, + ), + 'form_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ), + ), + ) + ); + } + + public static function cmatic_check_permission() { + if ( ! current_user_can( 'manage_options' ) ) { + return new WP_Error( + 'rest_forbidden', + __( 'You do not have permission to access this endpoint.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + return true; + } + + public static function cmatic_lookup_contact( $request ) { + $email = strtolower( $request->get_param( 'email' ) ); + $form_id = $request->get_param( 'form_id' ); + + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + $api_key = $cf7_mch['api'] ?? ''; + + if ( empty( $api_key ) ) { + return new WP_Error( + 'no_api_key', + __( 'No API key configured. Please connect to Mailchimp first.', 'chimpmatic-lite' ), + array( 'status' => 400 ) + ); + } + + if ( ! preg_match( '/^([a-f0-9]{32})-([a-z]{2,3}\d+)$/', $api_key, $matches ) ) { + return new WP_Error( + 'invalid_api_key', + __( 'Invalid API key format.', 'chimpmatic-lite' ), + array( 'status' => 400 ) + ); + } + + $key = $matches[1]; + $dc = $matches[2]; + + $lists_url = "https://{$dc}.api.mailchimp.com/3.0/lists?count=50&fields=lists.id,lists.name"; + $lists_resp = Cmatic_Lite_Api_Service::get( $key, $lists_url ); + + if ( is_wp_error( $lists_resp[2] ) || 200 !== wp_remote_retrieve_response_code( $lists_resp[2] ) ) { + return new WP_Error( + 'api_error', + __( 'Failed to retrieve audiences from Mailchimp.', 'chimpmatic-lite' ), + array( 'status' => 500 ) + ); + } + + $lists_data = $lists_resp[0]; + $lists = $lists_data['lists'] ?? array(); + + if ( empty( $lists ) ) { + return rest_ensure_response( + array( + 'success' => true, + 'email' => $email, + 'found' => false, + 'message' => __( 'No audiences found in your Mailchimp account.', 'chimpmatic-lite' ), + 'results' => array(), + ) + ); + } + + $subscriber_hash = md5( $email ); + $results = array(); + $found_count = 0; + + foreach ( $lists as $list ) { + $list_id = $list['id']; + $list_name = $list['name']; + + $member_url = "https://{$dc}.api.mailchimp.com/3.0/lists/{$list_id}/members/{$subscriber_hash}"; + $member_resp = Cmatic_Lite_Api_Service::get( $key, $member_url ); + + $status_code = wp_remote_retrieve_response_code( $member_resp[2] ); + + if ( 200 === $status_code ) { + $member_data = $member_resp[0]; + ++$found_count; + + $interests = array(); + $interests_url = "https://{$dc}.api.mailchimp.com/3.0/lists/{$list_id}/interest-categories?count=100"; + $interests_resp = Cmatic_Lite_Api_Service::get( $key, $interests_url ); + $interests_status = wp_remote_retrieve_response_code( $interests_resp[2] ); + + if ( 200 === $interests_status && ! empty( $interests_resp[0]['categories'] ) ) { + foreach ( $interests_resp[0]['categories'] as $category ) { + $cat_id = $category['id']; + $cat_title = $category['title']; + $cat_interest = array(); + + $cat_interests_url = "https://{$dc}.api.mailchimp.com/3.0/lists/{$list_id}/interest-categories/{$cat_id}/interests?count=100"; + $cat_interests_resp = Cmatic_Lite_Api_Service::get( $key, $cat_interests_url ); + + if ( 200 === wp_remote_retrieve_response_code( $cat_interests_resp[2] ) && ! empty( $cat_interests_resp[0]['interests'] ) ) { + $member_interests = $member_data['interests'] ?? array(); + foreach ( $cat_interests_resp[0]['interests'] as $interest ) { + $interest_id = $interest['id']; + $interest_name = $interest['name']; + $is_subscribed = ! empty( $member_interests[ $interest_id ] ); + if ( $is_subscribed ) { + $cat_interest[] = $interest_name; + } + } + } + + if ( ! empty( $cat_interest ) ) { + $interests[ $cat_title ] = $cat_interest; + } + } + } + + $results[] = array( + 'list_id' => $list_id, + 'list_name' => $list_name, + 'found' => true, + 'status' => $member_data['status'] ?? 'unknown', + 'email' => $member_data['email_address'] ?? $email, + 'merge_fields' => $member_data['merge_fields'] ?? array(), + 'tags' => array_column( $member_data['tags'] ?? array(), 'name' ), + 'interests' => $interests, + 'marketing_permissions' => $member_data['marketing_permissions'] ?? array(), + 'source' => $member_data['source'] ?? null, + 'ip_signup' => $member_data['ip_signup'] ?? null, + 'timestamp_signup' => $member_data['timestamp_signup'] ?? null, + 'subscribed' => $member_data['timestamp_opt'] ?? null, + 'last_changed' => $member_data['last_changed'] ?? null, + 'unsubscribe_reason' => $member_data['unsubscribe_reason'] ?? null, + 'language' => $member_data['language'] ?? null, + 'email_type' => $member_data['email_type'] ?? null, + 'vip' => $member_data['vip'] ?? false, + 'email_client' => $member_data['email_client'] ?? null, + 'location' => $member_data['location'] ?? null, + 'member_rating' => $member_data['member_rating'] ?? null, + 'consents_to_one_to_one_messaging' => $member_data['consents_to_one_to_one_messaging'] ?? null, + ); + } elseif ( 404 === $status_code ) { + $results[] = array( + 'list_id' => $list_id, + 'list_name' => $list_name, + 'found' => false, + 'status' => 'not_subscribed', + ); + } + } + + $is_pro = self::cmatic_is_pro_active(); + + if ( ! $is_pro ) { + $results = array_map( array( static::class, 'cmatic_fltr_pro_fields' ), $results ); + } + + Cmatic_Options_Repository::set_option( 'features.contact_lookup_used', true ); + do_action( 'cmatic_subscription_success', $form_id, $email ); + + return rest_ensure_response( + array( + 'success' => true, + 'email' => $email, + 'found' => $found_count > 0, + 'found_count' => $found_count, + 'total_lists' => count( $lists ), + 'is_pro' => $is_pro, + 'message' => $found_count > 0 + ? sprintf( + /* translators: %1$d: found count, %2$d: total lists */ + __( 'Contact found in %1$d of %2$d audiences.', 'chimpmatic-lite' ), + $found_count, + count( $lists ) + ) + : __( 'Contact not found in any audience.', 'chimpmatic-lite' ), + 'results' => $results, + ) + ); + } + + public static function cmatic_render( $args = array() ) { + $defaults = array( + 'form_id' => 0, + ); + $args = wp_parse_args( $args, $defaults ); + ?> +
+
+

+

+ +
+ + +
+ +
+
+
+ 'GET', + 'callback' => array( static::class, 'get_logs' ), + 'permission_callback' => array( static::class, 'check_permission' ), + 'args' => array( + 'filter' => array( + 'required' => false, + 'type' => 'string', + 'default' => '1', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => function ( $param ) { + return in_array( $param, array( '0', '1' ), true ); + }, + ), + ), + ) + ); + + register_rest_route( + self::$namespace, + '/logs/clear', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'clear_logs' ), + 'permission_callback' => array( static::class, 'check_permission' ), + ) + ); + + register_rest_route( + self::$namespace, + '/logs/browser', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'log_browser_console' ), + 'permission_callback' => array( static::class, 'check_permission' ), + 'args' => array( + 'level' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => function ( $param ) { + return in_array( $param, array( 'log', 'info', 'warn', 'error', 'debug' ), true ); + }, + ), + 'message' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'data' => array( + 'required' => false, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_textarea_field', + ), + ), + ) + ); + } + + public static function check_permission() { + return current_user_can( 'manage_options' ); + } + + public static function get_log_prefix() { + return static::$log_prefix; + } + + public static function get_log_path() { + if ( defined( 'WP_DEBUG_LOG' ) && is_string( WP_DEBUG_LOG ) ) { + return WP_DEBUG_LOG; + } + return WP_CONTENT_DIR . '/debug.log'; + } + + public static function get_logs( $request ) { + $log_path = static::get_log_path(); + $prefix = static::get_log_prefix(); + $apply_filter = '1' === $request->get_param( 'filter' ); + + if ( ! file_exists( $log_path ) ) { + return new WP_REST_Response( + array( + 'success' => false, + 'message' => __( 'Debug log file not found. Ensure WP_DEBUG_LOG is enabled.', self::$text_domain ), + 'logs' => '', + 'filtered' => $apply_filter, + ), + 200 + ); + } + + $lines = static::read_last_lines( $log_path, self::$max_lines ); + + if ( $apply_filter ) { + $output = array(); + foreach ( $lines as $line ) { + if ( strpos( $line, $prefix ) !== false ) { + $output[] = $line; + } + } + } else { + $output = array_filter( + $lines, + function ( $line ) { + return '' !== trim( $line ); + } + ); + } + + if ( empty( $output ) ) { + $message = $apply_filter + ? sprintf( + /* translators: %1$s: prefix, %2$d: number of lines checked */ + __( 'No %1$s entries found in the recent log data. Note: This viewer only shows the last %2$d lines of the log file.', self::$text_domain ), + $prefix, + self::$max_lines + ) + : __( 'Debug log is empty.', self::$text_domain ); + + return new WP_REST_Response( + array( + 'success' => true, + 'message' => $message, + 'logs' => '', + 'count' => 0, + 'filtered' => $apply_filter, + ), + 200 + ); + } + + return new WP_REST_Response( + array( + 'success' => true, + 'message' => '', + 'logs' => implode( "\n", $output ), + 'count' => count( $output ), + 'filtered' => $apply_filter, + ), + 200 + ); + } + + public static function clear_logs( $request ) { + $log_path = static::get_log_path(); + + if ( ! file_exists( $log_path ) ) { + return new WP_REST_Response( + array( + 'success' => true, + 'cleared' => false, + 'message' => __( 'Debug log file does not exist.', self::$text_domain ), + ), + 200 + ); + } + + if ( ! wp_is_writable( $log_path ) ) { + return new WP_REST_Response( + array( + 'success' => false, + 'cleared' => false, + 'message' => __( 'Debug log file is not writable.', self::$text_domain ), + ), + 500 + ); + } + + $file_handle = fopen( $log_path, 'w' ); + + if ( false === $file_handle ) { + return new WP_REST_Response( + array( + 'success' => false, + 'cleared' => false, + 'message' => __( 'Failed to clear debug log file.', self::$text_domain ), + ), + 500 + ); + } + + fclose( $file_handle ); + + if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { + error_log( + sprintf( + '[%s] [ChimpMatic Lite] Debug log cleared by user: %s', + gmdate( 'd-M-Y H:i:s' ) . ' UTC', + wp_get_current_user()->user_login + ) + ); + } + + return new WP_REST_Response( + array( + 'success' => true, + 'cleared' => true, + 'message' => __( 'Debug log cleared successfully.', self::$text_domain ), + ), + 200 + ); + } + + public static function log_browser_console( $request ) { + $level = $request->get_param( 'level' ); + $message = $request->get_param( 'message' ); + $data = $request->get_param( 'data' ); + + $level_map = array( + 'log' => 'INFO', + 'info' => 'INFO', + 'warn' => 'WARNING', + 'error' => 'ERROR', + 'debug' => 'DEBUG', + ); + + $wp_level = $level_map[ $level ] ?? 'INFO'; + $log_message = sprintf( + '[%s] %s [Browser Console - %s] %s', + gmdate( 'd-M-Y H:i:s' ) . ' UTC', + static::$log_prefix, + strtoupper( $level ), + $message + ); + + if ( ! empty( $data ) ) { + $log_message .= ' | Data: ' . $data; + } + if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { + error_log( $log_message ); + } + $logfile_enabled = (bool) get_option( CMATIC_LOG_OPTION, false ); + $logger = new Cmatic_File_Logger( 'Browser-Console', $logfile_enabled ); + $logger->log( $wp_level, 'Browser: ' . $message, $data ? json_decode( $data, true ) : null ); + + return new WP_REST_Response( + array( + 'success' => true, + 'logged' => true, + ), + 200 + ); + } + + protected static function read_last_lines( $filepath, $lines = 500 ) { + $handle = fopen( $filepath, 'r' ); + if ( ! $handle ) { + return array(); + } + + $result = array(); + $chunk = 4096; + $file_size = filesize( $filepath ); + if ( 0 === $file_size ) { + fclose( $handle ); + return array(); + } + $pos = $file_size; + $buffer = ''; + while ( $pos > 0 && count( $result ) < $lines ) { + $read_size = min( $chunk, $pos ); + $pos -= $read_size; + fseek( $handle, $pos ); + $buffer = fread( $handle, $read_size ) . $buffer; + $buffer_lines = explode( "\n", $buffer ); + $buffer = array_shift( $buffer_lines ); + $result = array_merge( $buffer_lines, $result ); + } + if ( 0 === $pos && ! empty( $buffer ) ) { + array_unshift( $result, $buffer ); + } + fclose( $handle ); + return array_slice( $result, -$lines ); + } + + public static function enqueue_assets( $hook ) { + } + + protected static function get_inline_js() { + $namespace = self::$namespace; + + return << __( 'Submission Logs', self::$text_domain ), + 'clear_text' => __( 'Clear Logs', self::$text_domain ), + 'placeholder' => __( 'Click "View Debug Logs" to fetch the log content.', self::$text_domain ), + 'class' => '', + ); + + $args = wp_parse_args( $args, $defaults ); + ?> + + array( + 'type' => 'boolean', + 'pro_only' => false, + 'nested' => 'labeltags', + ), + 'field(\\d+)' => array( + 'type' => 'string', + 'pro_only' => false, + 'direct' => true, + ), + 'customKey(\\d+)' => array( + 'type' => 'string', + 'pro_only' => false, + 'direct' => true, + ), + 'customValue(\\d+)' => array( + 'type' => 'string', + 'pro_only' => false, + 'direct' => true, + ), + 'GDPRCheck(\\d+)' => array( + 'type' => 'boolean', + 'pro_only' => true, + 'direct' => true, + ), + 'GDPRCustomValue(\\d+)' => array( + 'type' => 'string', + 'pro_only' => true, + 'direct' => true, + ), + 'ggCheck(\\d+)' => array( + 'type' => 'boolean', + 'pro_only' => true, + 'direct' => true, + ), + 'ggCustomValue(\\d+)' => array( + 'type' => 'string', + 'pro_only' => true, + 'direct' => true, + ), + ); + + public static function init() { + if ( self::$initialized ) { + return; + } + add_action( 'rest_api_init', array( static::class, 'register_routes' ) ); + self::$initialized = true; + } + + public static function register_routes() { + register_rest_route( + self::$namespace, + '/tags/toggle', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'toggle_tag' ), + 'permission_callback' => array( static::class, 'check_admin_permission' ), + 'args' => array( + 'form_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ), + 'tag' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'enabled' => array( + 'required' => true, + 'type' => 'boolean', + 'sanitize_callback' => 'rest_sanitize_boolean', + ), + ), + ) + ); + + register_rest_route( + self::$namespace, + '/form/field', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'save_field' ), + 'permission_callback' => array( static::class, 'check_form_permission' ), + 'args' => array( + 'form_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ), + 'field' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'value' => array( + 'required' => false, + 'default' => null, + ), + ), + ) + ); + + register_rest_route( + self::$cmatic_namespace, + '/form/setting', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'save_setting' ), + 'permission_callback' => array( static::class, 'check_admin_permission' ), + 'args' => array( + 'form_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => function ( $param ) { + return is_numeric( $param ) && $param > 0; + }, + ), + 'field' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_key', + ), + 'value' => array( + 'required' => true, + 'type' => 'boolean', + 'sanitize_callback' => function ( $value ) { + return Cmatic_Utils::validate_bool( $value ); + }, + ), + ), + ) + ); + } + + public static function check_admin_permission( $request ) { + if ( ! current_user_can( 'manage_options' ) ) { + return new WP_Error( + 'rest_forbidden', + esc_html__( 'You do not have permission to access this endpoint.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + $nonce = $request->get_header( 'X-WP-Nonce' ); + if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) { + return new WP_Error( + 'rest_cookie_invalid_nonce', + esc_html__( 'Cookie nonce is invalid.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + return true; + } + + public static function check_form_permission( $request ) { + $form_id = $request->get_param( 'form_id' ); + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $form_id ) ) { + return new WP_Error( + 'rest_forbidden', + esc_html__( 'You do not have permission to access the API key.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + $nonce = $request->get_header( 'X-WP-Nonce' ); + if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) { + return new WP_Error( + 'rest_cookie_invalid_nonce', + esc_html__( 'Cookie nonce is invalid.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + return true; + } + + public static function toggle_tag( $request ) { + $form_id = $request->get_param( 'form_id' ); + $tag = $request->get_param( 'tag' ); + $enabled = $request->get_param( 'enabled' ); + + if ( ! $form_id || ! $tag ) { + return new WP_Error( + 'missing_params', + __( 'Missing required parameters.', 'chimpmatic-lite' ), + array( 'status' => 400 ) + ); + } + + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + + if ( ! isset( $cf7_mch['labeltags'] ) || ! is_array( $cf7_mch['labeltags'] ) ) { + $cf7_mch['labeltags'] = array(); + } + + if ( $enabled ) { + $cf7_mch['labeltags'][ $tag ] = '1'; + } else { + unset( $cf7_mch['labeltags'][ $tag ] ); + } + + update_option( $option_name, $cf7_mch ); + + return rest_ensure_response( + array( + 'success' => true, + 'tag' => $tag, + 'enabled' => $enabled, + 'message' => $enabled + ? sprintf( __( 'Tag [%s] enabled.', 'chimpmatic-lite' ), $tag ) + : sprintf( __( 'Tag [%s] disabled.', 'chimpmatic-lite' ), $tag ), + ) + ); + } + + public static function save_field( $request ) { + $form_id = $request->get_param( 'form_id' ); + $field = $request->get_param( 'field' ); + $value = $request->get_param( 'value' ); + + $matched_config = null; + $matched_key = null; + + foreach ( self::$field_patterns as $pattern => $config ) { + if ( preg_match( '/^' . $pattern . '$/', $field, $matches ) ) { + $matched_config = $config; + $matched_key = isset( $matches[1] ) ? $matches[1] : null; + break; + } + } + + if ( null === $matched_config ) { + return new WP_Error( + 'invalid_field', + sprintf( __( 'Field "%s" is not allowed.', 'chimpmatic-lite' ), $field ), + array( 'status' => 400 ) + ); + } + + if ( $matched_config['pro_only'] && ! defined( 'CMATIC_VERSION' ) ) { + return new WP_Error( + 'pro_required', + __( 'This field requires ChimpMatic PRO.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + if ( 'boolean' === $matched_config['type'] ) { + $value = rest_sanitize_boolean( $value ); + } elseif ( 'string' === $matched_config['type'] ) { + $value = trim( sanitize_text_field( $value ) ); + } + + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + + if ( isset( $matched_config['nested'] ) ) { + $nested_key = $matched_config['nested']; + if ( ! isset( $cf7_mch[ $nested_key ] ) ) { + $cf7_mch[ $nested_key ] = array(); + } + + if ( $value ) { + $cf7_mch[ $nested_key ][ $matched_key ] = true; + } else { + unset( $cf7_mch[ $nested_key ][ $matched_key ] ); + } + } elseif ( null === $value || '' === $value ) { + unset( $cf7_mch[ $field ] ); + } else { + $cf7_mch[ $field ] = $value; + } + + update_option( $option_name, $cf7_mch ); + + return rest_ensure_response( + array( + 'success' => true, + 'field' => $field, + 'value' => $value, + 'message' => __( 'Field saved successfully.', 'chimpmatic-lite' ), + ) + ); + } + + public static function save_setting( $request ) { + $form_id = $request->get_param( 'form_id' ); + $field = $request->get_param( 'field' ); + $value = $request->get_param( 'value' ); + + $allowed_fields = array( + 'sync_tags' => array( + 'label' => __( 'Sync Tags', 'chimpmatic-lite' ), + 'pro_only' => false, + ), + 'double_optin' => array( + 'label' => __( 'Double Opt-in', 'chimpmatic-lite' ), + 'pro_only' => false, + ), + ); + + /** + * Filter the allowed per-form setting fields. + * + * Pro can extend this to add GDPR, Groups/Interests, etc. + * + * @since 0.9.69 + * + * @param array $allowed_fields Associative array of field_name => config. + * @param int $form_id The CF7 form ID. + */ + $allowed_fields = apply_filters( 'cmatic_form_setting_fields', $allowed_fields, $form_id ); + + if ( ! array_key_exists( $field, $allowed_fields ) ) { + return new WP_Error( + 'invalid_field', + sprintf( + /* translators: %s: field name */ + __( 'Field "%s" is not a valid setting.', 'chimpmatic-lite' ), + $field + ), + array( 'status' => 400 ) + ); + } + + $field_config = $allowed_fields[ $field ]; + + if ( ! empty( $field_config['pro_only'] ) && ! defined( 'CMATIC_VERSION' ) ) { + return new WP_Error( + 'pro_required', + sprintf( + /* translators: %s: field label */ + __( '%s requires ChimpMatic Pro.', 'chimpmatic-lite' ), + $field_config['label'] + ), + array( 'status' => 403 ) + ); + } + + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + + if ( ! is_array( $cf7_mch ) ) { + $cf7_mch = array(); + } + + $cf7_mch[ $field ] = $value ? 1 : 0; + + update_option( $option_name, $cf7_mch ); + + return rest_ensure_response( + array( + 'success' => true, + 'form_id' => $form_id, + 'field' => $field, + 'value' => (bool) $value, + 'message' => $value + ? sprintf( + /* translators: %s: field label */ + __( '%s enabled.', 'chimpmatic-lite' ), + $field_config['label'] + ) + : sprintf( + /* translators: %s: field label */ + __( '%s disabled.', 'chimpmatic-lite' ), + $field_config['label'] + ), + ) + ); + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-lists.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-lists.php new file mode 100644 index 0000000..2ef8a8c --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-lists.php @@ -0,0 +1,375 @@ + 'POST', + 'callback' => array( static::class, 'get_lists' ), + 'permission_callback' => array( static::class, 'check_form_permission' ), + 'args' => array( + 'form_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => function ( $param ) { + return is_numeric( $param ) && $param > 0; + }, + ), + 'api_key' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + 'validate_callback' => function ( $param ) { + return preg_match( '/^[a-f0-9]{32}-[a-z]{2,3}\d+$/', $param ); + }, + ), + ), + ) + ); + + register_rest_route( + self::$namespace, + '/merge-fields', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'get_merge_fields' ), + 'permission_callback' => array( static::class, 'check_form_permission' ), + 'args' => array( + 'form_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ), + 'list_id' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ) + ); + + register_rest_route( + self::$namespace, + '/api-key/(?P\d+)', + array( + 'methods' => 'GET', + 'callback' => array( static::class, 'get_api_key' ), + 'permission_callback' => array( static::class, 'check_form_permission' ), + 'args' => array( + 'form_id' => array( + 'required' => true, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => function ( $param ) { + return is_numeric( $param ) && $param > 0; + }, + ), + ), + ) + ); + } + + public static function check_form_permission( $request ) { + $form_id = $request->get_param( 'form_id' ); + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $form_id ) ) { + return new WP_Error( + 'rest_forbidden', + esc_html__( 'You do not have permission to access the API key.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + $nonce = $request->get_header( 'X-WP-Nonce' ); + if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) { + return new WP_Error( + 'rest_cookie_invalid_nonce', + esc_html__( 'Cookie nonce is invalid.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + return true; + } + + public static function get_lists( $request ) { + $form_id = $request->get_param( 'form_id' ); + $api_key = $request->get_param( 'api_key' ); + + if ( ! Cmatic_Options_Repository::get_option( 'api.sync_attempted' ) ) { + Cmatic_Options_Repository::set_option( 'api.sync_attempted', time() ); + } + $current_count = (int) Cmatic_Options_Repository::get_option( 'api.sync_attempts_count', 0 ); + Cmatic_Options_Repository::set_option( 'api.sync_attempts_count', $current_count + 1 ); + + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + + if ( ! is_array( $cf7_mch ) ) { + $cf7_mch = array(); + } + + $logfile_enabled = (bool) get_option( CMATIC_LOG_OPTION, false ); + + try { + $validation_result = Cmatic_Lite_Api_Service::validate_key( $api_key, $logfile_enabled ); + $api_valid = $validation_result['api-validation'] ?? 0; + + $lists_result = ( 1 === (int) $api_valid ) ? Cmatic_Lite_Api_Service::get_lists( $api_key, $logfile_enabled ) : array( 'lisdata' => array() ); + $lists_data = $lists_result['lisdata'] ?? array(); + $merge_fields_data = $lists_result['merge_fields'] ?? array(); + + $lists = array(); + if ( $api_valid === 1 && isset( $lists_data['lists'] ) && is_array( $lists_data['lists'] ) ) { + foreach ( $lists_data['lists'] as $list ) { + if ( is_array( $list ) && isset( $list['id'], $list['name'] ) ) { + $member_count = isset( $list['stats']['member_count'] ) ? intval( $list['stats']['member_count'] ) : 0; + $field_count = isset( $list['stats']['merge_field_count'] ) ? intval( $list['stats']['merge_field_count'] ) : 0; + + $lists[] = array( + 'id' => $list['id'], + 'name' => $list['name'], + 'member_count' => $member_count, + 'field_count' => $field_count, + ); + } + } + } + + $excluded_types = array( 'address', 'birthday', 'imageurl', 'zip' ); + $merge_fields = array(); + + $merge_fields[] = array( + 'tag' => 'EMAIL', + 'name' => 'Subscriber Email', + 'type' => 'email', + ); + + if ( isset( $merge_fields_data['merge_fields'] ) && is_array( $merge_fields_data['merge_fields'] ) ) { + $fields_to_process = $merge_fields_data['merge_fields']; + + usort( + $fields_to_process, + function ( $a, $b ) { + return ( $a['display_order'] ?? 0 ) - ( $b['display_order'] ?? 0 ); + } + ); + + $count = 1; + foreach ( $fields_to_process as $field ) { + $field_type = strtolower( $field['type'] ?? '' ); + $field_tag = $field['tag'] ?? ''; + + if ( $field_tag === 'EMAIL' ) { + continue; + } + + if ( in_array( $field_type, $excluded_types, true ) ) { + continue; + } + + if ( $count >= CMATIC_LITE_FIELDS ) { + break; + } + + $merge_fields[] = array( + 'tag' => $field_tag, + 'name' => $field['name'] ?? '', + 'type' => $field_type, + ); + ++$count; + } + } + + $settings_to_save = array_merge( + $cf7_mch, + $validation_result, + $lists_result, + array( + 'api' => $api_key, + 'merge_fields' => $merge_fields, + ) + ); + update_option( $option_name, $settings_to_save ); + + // Record first successful connection after form settings are saved. + if ( 1 === (int) $api_valid && ! Cmatic_Options_Repository::get_option( 'api.first_connected' ) ) { + Cmatic_Options_Repository::set_option( 'api.first_connected', time() ); + } + + if ( ! empty( $lists_result['lisdata'] ) ) { + Cmatic_Options_Repository::set_option( 'lisdata', $lists_result['lisdata'] ); + Cmatic_Options_Repository::set_option( 'lisdata_updated', time() ); + } + + return rest_ensure_response( + array( + 'success' => true, + 'api_valid' => $api_valid === 1, + 'lists' => $lists, + 'total' => count( $lists ), + 'merge_fields' => $merge_fields, + ) + ); + + } catch ( Exception $e ) { + $logger = new Cmatic_File_Logger( 'REST-API-Error', true ); + $logger->log( 'ERROR', 'REST API list loading failed.', $e->getMessage() ); + + return new WP_Error( + 'api_request_failed', + esc_html__( 'Failed to load Mailchimp lists. Check debug log for details.', 'chimpmatic-lite' ), + array( 'status' => 500 ) + ); + } + } + + public static function get_merge_fields( $request ) { + $form_id = $request->get_param( 'form_id' ); + $list_id = $request->get_param( 'list_id' ); + + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + $api_key = $cf7_mch['api'] ?? ''; + $logfile_enabled = (bool) get_option( CMATIC_LOG_OPTION, false ); + + if ( empty( $api_key ) ) { + return new WP_Error( + 'missing_api_key', + esc_html__( 'API key not found. Please connect to Mailchimp first.', 'chimpmatic-lite' ), + array( 'status' => 400 ) + ); + } + + try { + $merge_fields_result = Cmatic_Lite_Api_Service::get_merge_fields( $api_key, $list_id, $logfile_enabled ); + $merge_fields_data = $merge_fields_result['merge_fields'] ?? array(); + + $excluded_types = array( 'address', 'birthday', 'imageurl', 'zip' ); + $merge_fields = array(); + + $merge_fields[] = array( + 'tag' => 'EMAIL', + 'name' => 'Subscriber Email', + 'type' => 'email', + ); + + $raw_field_count = 0; + + if ( isset( $merge_fields_data['merge_fields'] ) && is_array( $merge_fields_data['merge_fields'] ) ) { + $fields_to_process = $merge_fields_data['merge_fields']; + $raw_field_count = count( $fields_to_process ) + 1; + + usort( + $fields_to_process, + function ( $a, $b ) { + return ( $a['display_order'] ?? 0 ) - ( $b['display_order'] ?? 0 ); + } + ); + + $count = 1; + foreach ( $fields_to_process as $field ) { + $field_type = strtolower( $field['type'] ?? '' ); + $field_tag = $field['tag'] ?? ''; + + if ( $field_tag === 'EMAIL' ) { + continue; + } + + if ( in_array( $field_type, $excluded_types, true ) ) { + continue; + } + + if ( $count >= CMATIC_LITE_FIELDS ) { + break; + } + + $merge_fields[] = array( + 'tag' => $field_tag, + 'name' => $field['name'] ?? '', + 'type' => $field_type, + ); + ++$count; + } + } + + $cf7_mch['merge_fields'] = $merge_fields; + $cf7_mch['list'] = $list_id; + $cf7_mch['total_merge_fields'] = $raw_field_count; + update_option( $option_name, $cf7_mch ); + + if ( ! Cmatic_Options_Repository::get_option( 'api.audience_selected' ) ) { + Cmatic_Options_Repository::set_option( 'api.audience_selected', time() ); + } + + if ( class_exists( 'Cmatic\\Metrics\\Core\\Sync' ) && class_exists( 'Cmatic\\Metrics\\Core\\Collector' ) ) { + $payload = \Cmatic\Metrics\Core\Collector::collect( 'list_selected' ); + \Cmatic\Metrics\Core\Sync::send_async( $payload ); + } + + return rest_ensure_response( + array( + 'success' => true, + 'merge_fields' => $merge_fields, + ) + ); + + } catch ( Exception $e ) { + return new WP_Error( + 'api_request_failed', + esc_html__( 'Failed to load merge fields. Check debug log for details.', 'chimpmatic-lite' ), + array( 'status' => 500 ) + ); + } + } + + public static function get_api_key( $request ) { + $form_id = $request->get_param( 'form_id' ); + $option_name = 'cf7_mch_' . $form_id; + $cf7_mch = get_option( $option_name, array() ); + + if ( ! is_array( $cf7_mch ) ) { + $cf7_mch = array(); + } + + $api_key = isset( $cf7_mch['api'] ) ? $cf7_mch['api'] : ''; + + return rest_ensure_response( + array( + 'success' => true, + 'api_key' => $api_key, + ) + ); + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-reset.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-reset.php new file mode 100644 index 0000000..d434b38 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-reset.php @@ -0,0 +1,178 @@ + 'POST', + 'callback' => array( static::class, 'reset_settings' ), + 'permission_callback' => array( static::class, 'check_admin_permission' ), + 'args' => array( + 'type' => array( + 'required' => false, + 'type' => 'string', + 'default' => 'form', + 'enum' => array( 'form', 'nuclear' ), + 'sanitize_callback' => 'sanitize_text_field', + ), + 'form_id' => array( + 'required' => false, + 'type' => 'integer', + 'sanitize_callback' => 'absint', + ), + ), + ) + ); + } + + public static function check_admin_permission( $request ) { + if ( ! current_user_can( 'manage_options' ) ) { + return new WP_Error( + 'rest_forbidden', + esc_html__( 'You do not have permission to access this endpoint.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + $nonce = $request->get_header( 'X-WP-Nonce' ); + if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) { + return new WP_Error( + 'rest_cookie_invalid_nonce', + esc_html__( 'Cookie nonce is invalid.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + return true; + } + + public static function reset_settings( $request ) { + $type = $request->get_param( 'type' ); + + if ( 'nuclear' === $type ) { + return self::nuclear_reset( $request ); + } + + $form_id = $request->get_param( 'form_id' ); + if ( ! $form_id ) { + return new WP_Error( + 'missing_form_id', + __( 'Form ID is required for form reset.', 'chimpmatic-lite' ), + array( 'status' => 400 ) + ); + } + + $option_name = 'cf7_mch_' . $form_id; + delete_option( $option_name ); + + return rest_ensure_response( + array( + 'success' => true, + 'message' => __( 'Form settings cleared successfully.', 'chimpmatic-lite' ), + ) + ); + } + + public static function nuclear_reset( $request ) { + global $wpdb; + + $current_user = wp_get_current_user(); + $username = $current_user->user_login ?? 'unknown'; + $deleted_counts = array(); + + $options_deleted = 0; + foreach ( self::$license_options as $option ) { + if ( delete_option( $option ) ) { + ++$options_deleted; + } + } + $deleted_counts['options'] = $options_deleted; + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching + $transients_deleted = $wpdb->query( + "DELETE FROM {$wpdb->options} + WHERE option_name LIKE '_transient_%chimpmatic%' + OR option_name LIKE '_transient_timeout_%chimpmatic%' + OR option_name LIKE '_site_transient_%chimpmatic%' + OR option_name LIKE '_site_transient_timeout_%chimpmatic%' + OR option_name LIKE 'site_transient_%chimpmatic%' + OR option_name LIKE '_transient_%cmatic%' + OR option_name LIKE '_transient_timeout_%cmatic%' + OR option_name LIKE '_site_transient_%cmatic%' + OR option_name LIKE '_site_transient_timeout_%cmatic%' + OR option_name LIKE 'site_transient_%cmatic%'" + ); + $deleted_counts['transients'] = (int) $transients_deleted; + $cache_flushed = false; + if ( function_exists( 'wp_cache_flush' ) ) { + $cache_flushed = wp_cache_flush(); + } + $deleted_counts['cache_flushed'] = $cache_flushed; + delete_site_transient( 'update_plugins' ); + update_option( 'chimpmatic_license_status', 'deactivated' ); + + return rest_ensure_response( + array( + 'success' => true, + 'message' => 'License data completely wiped (nuclear reset)', + 'deleted_counts' => $deleted_counts, + 'performed_by' => $username, + 'timestamp' => current_time( 'mysql' ), + 'actions_taken' => array( + 'Deleted ' . $options_deleted . ' license options', + 'Deleted ' . $transients_deleted . ' cached transients', + 'Flushed object cache: ' . ( $cache_flushed ? 'yes' : 'no' ), + 'Cleared plugin update cache', + 'Set license status to deactivated', + ), + ) + ); + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-settings.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-settings.php new file mode 100644 index 0000000..221e78d --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-rest-settings.php @@ -0,0 +1,212 @@ + array( + 'type' => 'cmatic', + 'path' => 'debug', + ), + 'backlink' => array( + 'type' => 'cmatic', + 'path' => 'backlink', + ), + 'auto_update' => array( + 'type' => 'cmatic', + 'path' => 'auto_update', + ), + 'telemetry' => array( + 'type' => 'cmatic', + 'path' => 'telemetry.enabled', + ), + ); + + /** @var array Field labels for user messages. */ + protected static $field_labels = array( + 'debug' => 'Debug Logger', + 'backlink' => 'Developer Backlink', + 'auto_update' => 'Auto Update', + 'telemetry' => 'Usage Statistics', + ); + + public static function init() { + if ( self::$initialized ) { + return; + } + add_action( 'rest_api_init', array( static::class, 'register_routes' ) ); + self::$initialized = true; + } + + public static function register_routes() { + register_rest_route( + self::$namespace, + '/settings/toggle', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'toggle_setting' ), + 'permission_callback' => array( static::class, 'check_admin_permission' ), + 'args' => array( + 'field' => array( + 'required' => true, + 'type' => 'string', + 'sanitize_callback' => 'sanitize_text_field', + ), + 'enabled' => array( + 'required' => true, + 'type' => 'boolean', + 'sanitize_callback' => 'rest_sanitize_boolean', + ), + ), + ) + ); + + register_rest_route( + self::$namespace, + '/notices/dismiss', + array( + 'methods' => 'POST', + 'callback' => array( static::class, 'dismiss_notice' ), + 'permission_callback' => array( static::class, 'check_admin_permission' ), + 'args' => array( + 'notice_id' => array( + 'required' => false, + 'type' => 'string', + 'default' => 'news', + 'sanitize_callback' => 'sanitize_text_field', + 'enum' => array( 'news', 'upgrade' ), + ), + ), + ) + ); + + } + + public static function check_admin_permission( $request ) { + if ( ! current_user_can( 'manage_options' ) ) { + return new WP_Error( + 'rest_forbidden', + esc_html__( 'You do not have permission to access this endpoint.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + $nonce = $request->get_header( 'X-WP-Nonce' ); + if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) { + return new WP_Error( + 'rest_cookie_invalid_nonce', + esc_html__( 'Cookie nonce is invalid.', 'chimpmatic-lite' ), + array( 'status' => 403 ) + ); + } + + return true; + } + + public static function toggle_setting( $request ) { + $field = $request->get_param( 'field' ); + $enabled = $request->get_param( 'enabled' ); + + if ( ! array_key_exists( $field, self::$allowed_settings ) ) { + return new WP_Error( + 'invalid_field', + __( 'Invalid settings field.', 'chimpmatic-lite' ), + array( 'status' => 400 ) + ); + } + + $field_config = self::$allowed_settings[ $field ]; + + if ( 'telemetry' === $field ) { + self::handle_telemetry_toggle( $enabled ); + } + + Cmatic_Options_Repository::set_option( $field_config['path'], $enabled ? 1 : 0 ); + + $label = self::$field_labels[ $field ] ?? ucfirst( str_replace( '_', ' ', $field ) ); + + return rest_ensure_response( + array( + 'success' => true, + 'field' => $field, + 'enabled' => $enabled, + 'message' => $enabled + ? sprintf( __( '%s enabled.', 'chimpmatic-lite' ), $label ) + : sprintf( __( '%s disabled.', 'chimpmatic-lite' ), $label ), + ) + ); + } + + protected static function handle_telemetry_toggle( $enabled ) { + if ( class_exists( 'Cmatic\\Metrics\\Core\\Storage' ) && class_exists( 'Cmatic\\Metrics\\Core\\Tracker' ) ) { + $storage_enabled = \Cmatic\Metrics\Core\Storage::is_enabled(); + if ( ! $enabled && $storage_enabled ) { + \Cmatic\Metrics\Core\Tracker::on_opt_out(); + } + if ( $enabled && ! $storage_enabled ) { + \Cmatic\Metrics\Core\Tracker::on_re_enable(); + } + } + } + + public static function toggle_telemetry( $request ) { + $enabled = $request->get_param( 'enabled' ); + + self::handle_telemetry_toggle( $enabled ); + Cmatic_Options_Repository::set_option( 'telemetry.enabled', $enabled ); + + return rest_ensure_response( + array( + 'success' => true, + 'enabled' => $enabled, + 'message' => $enabled + ? esc_html__( 'Telemetry enabled. Thank you for helping improve the plugin!', 'chimpmatic-lite' ) + : esc_html__( 'Telemetry disabled.', 'chimpmatic-lite' ), + ) + ); + } + + public static function dismiss_notice( $request ) { + $notice_id = $request->get_param( 'notice_id' ); + + switch ( $notice_id ) { + case 'upgrade': + Cmatic_Options_Repository::set_option( 'ui.upgrade_clicked', true ); + $message = __( 'Upgrade notice dismissed.', 'chimpmatic-lite' ); + break; + + case 'news': + default: + Cmatic_Options_Repository::set_option( 'ui.news', false ); + $message = __( 'Notice dismissed successfully.', 'chimpmatic-lite' ); + break; + } + + return rest_ensure_response( + array( + 'success' => true, + 'message' => esc_html( $message ), + 'dismissed' => $notice_id, + ) + ); + } + + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-submission-feedback.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-submission-feedback.php new file mode 100644 index 0000000..08020a6 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/api/class-cmatic-submission-feedback.php @@ -0,0 +1,203 @@ + $value ) { + if ( ! empty( $value ) || '0' === $value || 0 === $value ) { + $received[ $key ] = $value; + } + } + } + + if ( ! empty( $api_response['tags'] ) && is_array( $api_response['tags'] ) ) { + $tag_names = array_column( $api_response['tags'], 'name' ); + if ( ! empty( $tag_names ) ) { + $received['TAGS'] = implode( ', ', $tag_names ); + } + } + + if ( ! empty( $merge_vars['INTERESTS'] ) ) { + $received['INTERESTS'] = '✓ ' . $merge_vars['INTERESTS']; + } elseif ( ! empty( $api_response['interests'] ) && is_array( $api_response['interests'] ) ) { + $enabled_count = count( array_filter( $api_response['interests'] ) ); + if ( $enabled_count > 0 ) { + $received['INTERESTS'] = '✓ ' . $enabled_count . ( 1 === $enabled_count ? ' group' : ' groups' ); + } + } + + if ( ! empty( $merge_vars['GDPR'] ) ) { + $received['GDPR'] = '✓ ' . $merge_vars['GDPR']; + } elseif ( ! empty( $api_response['marketing_permissions'] ) && is_array( $api_response['marketing_permissions'] ) ) { + $enabled_count = 0; + $total_count = count( $api_response['marketing_permissions'] ); + foreach ( $api_response['marketing_permissions'] as $permission ) { + if ( ! empty( $permission['enabled'] ) ) { + ++$enabled_count; + } + } + $received['GDPR'] = '✓ ' . $enabled_count . ' of ' . $total_count . ( 1 === $total_count ? ' permission' : ' permissions' ); + } + + if ( ! empty( $api_response['location'] ) && is_array( $api_response['location'] ) ) { + $lat = $api_response['location']['latitude'] ?? 0; + $lng = $api_response['location']['longitude'] ?? 0; + if ( 0 !== $lat || 0 !== $lng ) { + $received['LOCATION'] = round( $lat, 4 ) . ', ' . round( $lng, 4 ); + } + } + + if ( ! empty( $api_response['language'] ) ) { + $received['LANGUAGE'] = strtoupper( $api_response['language'] ); + } + + if ( ! empty( $api_response['email_type'] ) ) { + $received['EMAIL_TYPE'] = strtoupper( $api_response['email_type'] ); + } + + if ( ! empty( $api_response['status'] ) ) { + $received['STATUS'] = ucfirst( $api_response['status'] ); + } + + return array( + 'success' => true, + 'email' => $email, + 'status' => $status, + 'status_text' => self::get_status_text( $status ), + 'merge_vars' => $merge_vars, + 'received' => $received, + 'message' => self::get_success_message( $email, $status ), + ); + } + + public static function failure( $reason, $detail = '', $email = '' ) { + return array( + 'success' => false, + 'reason' => $reason, + 'detail' => $detail, + 'email' => $email, + 'message' => self::get_failure_message( $reason, $detail ), + ); + } + + public static function skipped( $reason ) { + return array( + 'success' => null, + 'skipped' => true, + 'reason' => $reason, + 'message' => self::get_skip_message( $reason ), + ); + } + + private static function get_status_text( $status ) { + $statuses = array( + 'subscribed' => __( 'Subscribed', 'chimpmatic-lite' ), + 'pending' => __( 'Pending Confirmation', 'chimpmatic-lite' ), + 'unsubscribed' => __( 'Unsubscribed', 'chimpmatic-lite' ), + ); + return isset( $statuses[ $status ] ) ? $statuses[ $status ] : $status; + } + + private static function get_success_message( $email, $status ) { + if ( 'pending' === $status ) { + /* translators: %s: email address */ + return sprintf( __( '%s added - awaiting confirmation email.', 'chimpmatic-lite' ), $email ); + } + /* translators: %s: email address */ + return sprintf( __( '%s subscribed successfully!', 'chimpmatic-lite' ), $email ); + } + + private static function get_failure_message( $reason, $detail = '' ) { + $messages = array( + 'invalid_email' => __( 'Invalid email address provided.', 'chimpmatic-lite' ), + 'already_subscribed' => __( 'This email is already subscribed.', 'chimpmatic-lite' ), + 'permanently_deleted' => __( 'This email was permanently deleted and cannot be re-imported.', 'chimpmatic-lite' ), + 'previously_unsubscribed' => __( 'This email previously unsubscribed and cannot be re-added.', 'chimpmatic-lite' ), + 'compliance_state' => __( 'This email is in a compliance state and cannot be subscribed.', 'chimpmatic-lite' ), + 'api_error' => __( 'Mailchimp API error occurred.', 'chimpmatic-lite' ), + 'network_error' => __( 'Network error connecting to Mailchimp.', 'chimpmatic-lite' ), + ); + + $message = isset( $messages[ $reason ] ) ? $messages[ $reason ] : __( 'Subscription failed.', 'chimpmatic-lite' ); + + if ( ! empty( $detail ) ) { + $message .= ' ' . $detail; + } + + return $message; + } + + private static function get_skip_message( $reason ) { + $messages = array( + 'acceptance_not_checked' => __( 'Opt-in checkbox was not checked.', 'chimpmatic-lite' ), + 'no_api_configured' => __( 'Mailchimp API is not configured for this form.', 'chimpmatic-lite' ), + ); + return isset( $messages[ $reason ] ) ? $messages[ $reason ] : __( 'Subscription skipped.', 'chimpmatic-lite' ); + } + + public static function parse_api_error( $api_response, $email = '' ) { + $title = isset( $api_response['title'] ) ? $api_response['title'] : ''; + $detail = isset( $api_response['detail'] ) ? $api_response['detail'] : ''; + + if ( strpos( strtolower( $title ), 'member exists' ) !== false ) { + return self::failure( 'already_subscribed', '', $email ); + } + + if ( strpos( strtolower( $detail ), 'permanently deleted' ) !== false ) { + return self::failure( 'permanently_deleted', '', $email ); + } + + if ( strpos( strtolower( $detail ), 'compliance state' ) !== false ) { + return self::failure( 'compliance_state', '', $email ); + } + + if ( strpos( strtolower( $title ), 'forgotten email' ) !== false ) { + return self::failure( 'permanently_deleted', '', $email ); + } + + return self::failure( 'api_error', $detail, $email ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/bootstrap.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/bootstrap.php new file mode 100644 index 0000000..b1bd97d --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/bootstrap.php @@ -0,0 +1,17 @@ +init(); diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-activator.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-activator.php new file mode 100644 index 0000000..092bf40 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-activator.php @@ -0,0 +1,215 @@ +version = $version; + $this->options = new Cmatic_Options_Repository(); + $this->install_data = new Cmatic_Install_Data( $this->options ); + $this->migration = new Cmatic_Migration( $this->options, $version ); + $this->pro_status = new Cmatic_Pro_Status( $this->options ); + $this->redirect = new Cmatic_Redirect( $this->options ); + $this->lifecycle_signal = new Cmatic_Lifecycle_Signal(); + } + + public function activate() { + $this->do_activation( true ); + } + + public function ensure_initialized() { + // Fast check - auto-loaded option, near-zero cost. + if ( get_option( self::INITIALIZED_FLAG ) ) { + // Flag exists, but verify data is actually complete. + $install_id = $this->options->get( 'install.id' ); + if ( ! empty( $install_id ) ) { + return; // Data exists, truly initialized. + } + // Flag exists but data is missing - delete flag and continue. + delete_option( self::INITIALIZED_FLAG ); + } + + // Run initialization (idempotent). + $this->do_activation( false ); + } + + private function do_activation( $is_normal_activation ) { + // 1. BULLETPROOF: Ensure install_id and quest exist FIRST. + $this->install_data->ensure(); + + // 2. Migrate legacy options (safe to run multiple times). + $this->migration->run(); + + // 3. Update Pro plugin status. + $this->pro_status->update(); + + // 4. Record activation in lifecycle. + $this->record_activation(); + + // 5. Send lifecycle signal (only on normal activation, not fallback). + if ( $is_normal_activation ) { + $this->lifecycle_signal->send_activation(); + } + + // 6. Schedule redirect (only on normal activation). + if ( $is_normal_activation ) { + $this->redirect->schedule(); + } + + // 7. Mark plugin as active (for missed deactivation detection). + $this->options->set( 'lifecycle.is_active', true ); + + // 8. Mark as initialized (auto-loaded option for fast checks). + add_option( self::INITIALIZED_FLAG, true ); + + // 9. Fire action for extensibility. + do_action( 'cmatic_activated', $is_normal_activation ); + } + + private function record_activation() { + $activations = $this->options->get( 'lifecycle.activations', array() ); + $activations = is_array( $activations ) ? $activations : array(); + $activations[] = time(); + + $this->options->set( 'lifecycle.activations', $activations ); + $this->options->set( 'lifecycle.is_reactivation', count( $activations ) > 1 ); + } + + public function get_redirect() { + return $this->redirect; + } + + public function get_pro_status() { + return $this->pro_status; + } + + public static function is_initialized() { + return (bool) get_option( self::INITIALIZED_FLAG ); + } + + public static function clear_initialized_flag() { + return delete_option( self::INITIALIZED_FLAG ); + } + + public function verify_lifecycle_state(): void { + $thinks_active = $this->options->get( 'lifecycle.is_active', false ); + + // If we think we're inactive (or never set), nothing to check. + if ( ! $thinks_active ) { + return; + } + + // Check if plugin is actually active in WordPress. + if ( ! function_exists( 'is_plugin_active' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $actually_active = is_plugin_active( SPARTAN_MCE_PLUGIN_BASENAME ); + + // If state matches reality, all is well. + if ( $actually_active ) { + return; + } + + // MISMATCH DETECTED: We think we're active, but WordPress says no. + // This means deactivation hook was missed (update, FTP delete, etc). + $this->handle_missed_deactivation(); + } + + private function handle_missed_deactivation(): void { + // 1. Update state flag FIRST. + $this->options->set( 'lifecycle.is_active', false ); + + // 2. Record missed deactivation (for analytics). + $missed = $this->options->get( 'lifecycle.missed_deactivations', array() ); + $missed = is_array( $missed ) ? $missed : array(); + $missed[] = array( + 'timestamp' => time(), + 'type' => 'self_healing', + ); + $this->options->set( 'lifecycle.missed_deactivations', $missed ); + + // 3. Clear cron (idempotent). + Cmatic_Cron::unschedule(); + + // 4. Send telemetry signal (if class exists). + $this->lifecycle_signal->send_deactivation(); + + // 5. Clear initialized flag so next activation runs fully. + delete_option( self::INITIALIZED_FLAG ); + + // 6. Fire action for extensibility. + do_action( 'cmatic_missed_deactivation_handled' ); + } + + public static function register_hooks( string $plugin_file, string $version ): void { + // Activation hook. + register_activation_hook( + $plugin_file, + function () use ( $version ) { + $activator = new self( $version ); + $activator->activate(); + } + ); + + // Deactivation hook. + register_deactivation_hook( + $plugin_file, + function () { + $deactivator = new Cmatic_Deactivator(); + $deactivator->deactivate(); + } + ); + + // CRITICAL FALLBACK: Catch missed activations AND deactivations on admin_init. + add_action( + 'admin_init', + function () use ( $version ) { + $activator = new self( $version ); + + // Check for missed deactivation FIRST (before initialization). + $activator->verify_lifecycle_state(); + + // Then ensure initialized (existing fallback). + $activator->ensure_initialized(); + $activator->get_redirect()->maybe_redirect(); + }, + 5 + ); + + // Update Pro status on plugins_loaded (late priority). + add_action( + 'plugins_loaded', + function () use ( $version ) { + $activator = new self( $version ); + $activator->get_pro_status()->update(); + }, + 99 + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-container.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-container.php new file mode 100644 index 0000000..0463be8 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-container.php @@ -0,0 +1,69 @@ +options = new Cmatic_Options_Repository(); + $this->lifecycle_signal = new Cmatic_Lifecycle_Signal(); + } + + public function deactivate() { + // Mark inactive FIRST (state must update before cleanup). + $this->options->set( 'lifecycle.is_active', false ); + + $this->record_deactivation(); + $this->lifecycle_signal->send_deactivation(); + + do_action( 'cmatic_deactivated' ); + } + + private function record_deactivation() { + $deactivations = $this->options->get( 'lifecycle.deactivations', array() ); + $deactivations = is_array( $deactivations ) ? $deactivations : array(); + $deactivations[] = time(); + + $this->options->set( 'lifecycle.deactivations', $deactivations ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-install-data.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-install-data.php new file mode 100644 index 0000000..8b22f27 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-install-data.php @@ -0,0 +1,124 @@ +options = $options; + } + + public function ensure() { + $data = $this->options->get_all(); + $changed = false; + + if ( ! isset( $data['install'] ) || ! is_array( $data['install'] ) ) { + $data['install'] = array(); + $changed = true; + } + + if ( empty( $data['install']['id'] ) ) { + $wp_cached = get_option( 'cmatic', array() ); + if ( is_array( $wp_cached ) && ! empty( $wp_cached['install']['id'] ) ) { + $data['install']['id'] = $wp_cached['install']['id']; + } else { + $data['install']['id'] = $this->generate_install_id(); + } + $changed = true; + } + + $quest = isset( $data['install']['quest'] ) ? (int) $data['install']['quest'] : 0; + if ( $quest < self::MIN_VALID_TIMESTAMP ) { + $data['install']['quest'] = $this->determine_quest( $data ); + $changed = true; + } + + if ( $changed ) { + $this->options->save( $data ); + } + } + + public function get_install_id() { + $install_id = $this->options->get( 'install.id', '' ); + + if ( empty( $install_id ) ) { + $wp_cached = get_option( 'cmatic', array() ); + if ( is_array( $wp_cached ) && ! empty( $wp_cached['install']['id'] ) ) { + $install_id = $wp_cached['install']['id']; + $this->options->set( 'install.id', $install_id ); + return $install_id; + } + + $install_id = $this->generate_install_id(); + $this->options->set( 'install.id', $install_id ); + } + + return $install_id; + } + + public function get_quest() { + $quest = (int) $this->options->get( 'install.quest', 0 ); + + if ( $quest >= self::MIN_VALID_TIMESTAMP ) { + return $quest; + } + + $quest = $this->determine_quest( $this->options->get_all() ); + $this->options->set( 'install.quest', $quest ); + + return $quest; + } + + private function generate_install_id() { + return bin2hex( random_bytes( 6 ) ); + } + + private function determine_quest( $data ) { + $candidates = array(); + + // 1. Legacy mce_loyalty (highest priority - original timestamp). + $loyalty = $this->options->get_legacy( 'mce_loyalty' ); + if ( is_array( $loyalty ) && ! empty( $loyalty[0] ) ) { + $candidates[] = (int) $loyalty[0]; + } + + // 2. Lifecycle activations. + $activations = isset( $data['lifecycle']['activations'] ) ? $data['lifecycle']['activations'] : array(); + if ( ! empty( $activations ) && is_array( $activations ) ) { + $candidates[] = (int) min( $activations ); + } + + // 3. Telemetry opt-in date. + $opt_in = isset( $data['telemetry']['opt_in_date'] ) ? (int) $data['telemetry']['opt_in_date'] : 0; + if ( $opt_in >= self::MIN_VALID_TIMESTAMP ) { + $candidates[] = $opt_in; + } + + // 4. API first connected. + $api_first = isset( $data['api']['first_connected'] ) ? (int) $data['api']['first_connected'] : 0; + if ( $api_first >= self::MIN_VALID_TIMESTAMP ) { + $candidates[] = $api_first; + } + + // 5. First submission. + $sub_first = isset( $data['submissions']['first'] ) ? (int) $data['submissions']['first'] : 0; + if ( $sub_first >= self::MIN_VALID_TIMESTAMP ) { + $candidates[] = $sub_first; + } + + // 6. Fallback to current time. + return ! empty( $candidates ) ? min( $candidates ) : time(); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-migration.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-migration.php new file mode 100644 index 0000000..308a2b8 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-migration.php @@ -0,0 +1,196 @@ +options = $options; + $this->version = $version; + } + + public function run() { + $data = $this->options->get_all(); + + $data['version'] = $this->version; + + $this->migrate_install( $data ); + $this->migrate_stats( $data ); + $this->migrate_ui( $data ); + $this->migrate_cmatic_options( $data ); + $this->migrate_api_data( $data ); + + $data['migrated'] = true; + + $this->options->save( $data ); + $this->cleanup_legacy_options(); + } + + public function is_migrated() { + return (bool) $this->options->get( 'migrated', false ); + } + + private function migrate_install( &$data ) { + if ( ! isset( $data['install'] ) ) { + $data['install'] = array(); + } + + if ( ! isset( $data['install']['plugin_slug'] ) ) { + $data['install']['plugin_slug'] = 'contact-form-7-mailchimp-extension'; + } + + if ( ! isset( $data['install']['activated_at'] ) && ! empty( $data['install']['quest'] ) ) { + $data['install']['activated_at'] = gmdate( 'Y-m-d H:i:s', (int) $data['install']['quest'] ); + } + } + + private function migrate_stats( &$data ) { + if ( ! isset( $data['stats'] ) ) { + $data['stats'] = array(); + } + + if ( ! isset( $data['stats']['sent'] ) ) { + $data['stats']['sent'] = (int) $this->options->get_legacy( 'mce_sent', 0 ); + } + } + + private function migrate_ui( &$data ) { + if ( isset( $data['ui'] ) ) { + return; + } + + $panel_title = $this->options->get_legacy( 'mce_conten_tittle_master', '' ); + $panel_content = $this->options->get_legacy( 'mce_conten_panel_master', '' ); + + $data['ui'] = array( + 'news' => (bool) $this->options->get_legacy( 'mce_show_update_news', true ), + 'notice_banner' => (bool) $this->options->get_legacy( 'mce_show_notice', true ), + 'welcome_panel' => array( + 'title' => $panel_title ? $panel_title : 'Chimpmatic Lite is now ' . $this->version . '!', + 'content' => $panel_content ? $panel_content : '', + ), + ); + } + + private function migrate_cmatic_options( &$data ) { + $old_auto_update = get_option( 'chimpmatic-update' ); + if ( false !== $old_auto_update && ! isset( $data['auto_update'] ) ) { + $data['auto_update'] = ( '1' === $old_auto_update ) ? 1 : 0; + } + + $old_debug = get_option( 'cmatic_log_on' ); + if ( false !== $old_debug && ! isset( $data['debug'] ) ) { + $data['debug'] = ( 'on' === $old_debug || '1' === $old_debug ) ? 1 : 0; + } + + $old_redirect = get_option( 'cmatic_do_activation_redirect' ); + if ( false !== $old_redirect && ! isset( $data['activation_redirect'] ) ) { + $data['activation_redirect'] = (bool) $old_redirect; + } + + $old_news_count = get_option( 'cmatic_news_retry_count' ); + if ( false !== $old_news_count ) { + if ( ! isset( $data['news'] ) ) { + $data['news'] = array(); + } + if ( ! isset( $data['news']['retry_count'] ) ) { + $data['news']['retry_count'] = (int) $old_news_count; + } + } + + $old_last_run = get_option( 'csyncr_last_weekly_run' ); + if ( false !== $old_last_run ) { + if ( ! isset( $data['telemetry'] ) ) { + $data['telemetry'] = array(); + } + if ( ! isset( $data['telemetry']['last_run'] ) ) { + $data['telemetry']['last_run'] = (int) $old_last_run; + } + } + } + + private function migrate_api_data( &$data ) { + // Skip if already set. + if ( ! empty( $data['api']['first_connected'] ) ) { + return; + } + + // First, try to use existing api.setup_first_success timestamp. + $setup_first_success = isset( $data['api']['setup_first_success'] ) ? (int) $data['api']['setup_first_success'] : 0; + if ( $setup_first_success > 1000000000 ) { + if ( ! isset( $data['api'] ) ) { + $data['api'] = array(); + } + $data['api']['first_connected'] = $setup_first_success; + return; + } + + // Fallback: Check if any form has a successful API connection. + global $wpdb; + $form_options = $wpdb->get_results( + "SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE 'cf7_mch_%'", + ARRAY_A + ); + + if ( empty( $form_options ) ) { + return; + } + + foreach ( $form_options as $row ) { + $form_data = maybe_unserialize( $row['option_value'] ); + if ( is_array( $form_data ) && ! empty( $form_data['api-validation'] ) && 1 === (int) $form_data['api-validation'] ) { + // Found a form with valid API - backfill first_connected with current time. + if ( ! isset( $data['api'] ) ) { + $data['api'] = array(); + } + $data['api']['first_connected'] = time(); + return; + } + } + } + + private function cleanup_legacy_options() { + foreach ( self::LEGACY_MCE_OPTIONS as $option ) { + $this->options->delete_legacy( $option ); + } + + foreach ( self::LEGACY_CMATIC_OPTIONS as $option ) { + delete_option( $option ); + } + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-plugin.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-plugin.php new file mode 100644 index 0000000..0887c74 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/core/class-cmatic-plugin.php @@ -0,0 +1,191 @@ +file = $file; + $this->version = $version; + $this->dir = plugin_dir_path( $file ); + $this->basename = plugin_basename( $file ); + } + + public function init(): void { + $this->load_core_dependencies(); + $this->register_lifecycle_hooks(); + $this->load_module_dependencies(); + $this->initialize_components(); + $this->load_late_dependencies(); + $this->initialize_late_components(); + } + + private function load_core_dependencies(): void { + // Load interfaces first. + require_once $this->dir . 'includes/interfaces/interface-cmatic-options.php'; + require_once $this->dir . 'includes/interfaces/interface-cmatic-logger.php'; + require_once $this->dir . 'includes/interfaces/interface-cmatic-api-client.php'; + + // Load container. + require_once $this->dir . 'includes/core/class-cmatic-container.php'; + + // Load services. + require_once $this->dir . 'includes/services/class-cmatic-options-repository.php'; + require_once $this->dir . 'includes/services/class-cmatic-pro-status.php'; + require_once $this->dir . 'includes/services/class-cmatic-redirect.php'; + require_once $this->dir . 'includes/services/class-cmatic-lifecycle-signal.php'; + require_once $this->dir . 'includes/core/class-cmatic-install-data.php'; + require_once $this->dir . 'includes/core/class-cmatic-migration.php'; + require_once $this->dir . 'includes/core/class-cmatic-activator.php'; + require_once $this->dir . 'includes/core/class-cmatic-deactivator.php'; + require_once $this->dir . 'includes/services/class-cmatic-cf7-dependency.php'; + require_once $this->dir . 'includes/services/class-cmatic-pro-syncer.php'; + require_once $this->dir . 'includes/services/class-cmatic-api-key-importer.php'; + } + + private function register_lifecycle_hooks(): void { + Cmatic_Activator::register_hooks( $this->file, $this->version ); + } + + private function load_module_dependencies(): void { + $modules = array( + // Utils. + 'utils/class-cmatic-utils.php', + 'utils/class-cmatic-lite-get-fields.php', + 'utils/class-cmatic-pursuit.php', + 'utils/class-cmatic-file-logger.php', + 'utils/class-cmatic-remote-fetcher.php', + 'utils/class-cmatic-buster.php', + // Services. + 'services/class-cmatic-cf7-tags.php', + 'services/class-cmatic-cron.php', + 'services/class-cmatic-api-service.php', + 'services/class-cmatic-form-tags.php', + // Submission handling (load before handler). + 'services/submission/class-cmatic-email-extractor.php', + 'services/submission/class-cmatic-status-resolver.php', + 'services/submission/class-cmatic-merge-vars-builder.php', + 'services/submission/class-cmatic-response-handler.php', + 'services/submission/class-cmatic-mailchimp-subscriber.php', + 'services/class-cmatic-submission-handler.php', + // REST API Controllers. + 'api/class-cmatic-rest-lists.php', + 'api/class-cmatic-rest-settings.php', + 'api/class-cmatic-rest-form.php', + 'api/class-cmatic-rest-reset.php', + // Admin. + 'admin/class-cmatic-plugin-links.php', + 'admin/class-cmatic-deactivation-survey.php', + 'admin/class-cmatic-asset-loader.php', + 'admin/class-cmatic-admin-panel.php', + // API. + 'api/class-cmatic-log-viewer.php', + 'api/class-cmatic-contact-lookup.php', + 'api/class-cmatic-submission-feedback.php', + // UI. + 'ui/class-cmatic-header.php', + 'ui/class-cmatic-api-panel.php', + 'ui/class-cmatic-audiences.php', + 'ui/class-cmatic-data-container.php', + 'ui/class-cmatic-panel-toggles.php', + 'ui/class-cmatic-tags-preview.php', + 'ui/class-cmatic-banners.php', + 'ui/class-cmatic-form-classes.php', + 'ui/class-cmatic-field-mapper.php', + 'ui/class-cmatic-sidebar-panel.php', + 'ui/class-cmatic-advanced-settings.php', + ); + + foreach ( $modules as $module ) { + $path = $this->dir . 'includes/' . $module; + if ( file_exists( $path ) ) { + require_once $path; + } + } + } + + private function initialize_components(): void { + // Boot service container. + Cmatic_Lite_Container::boot(); + + // Core services (no dependencies). + Cmatic_CF7_Dependency::init(); + Cmatic_Pro_Syncer::init(); + + // Logging. + Cmatic_Log_Viewer::init( 'chimpmatic-lite', '[ChimpMatic Lite]', 'chimpmatic-lite' ); + + // REST API Controllers. + Cmatic_Rest_Lists::init(); + Cmatic_Rest_Settings::init(); + Cmatic_Rest_Form::init(); + Cmatic_Rest_Reset::init(); + + // API Services. + Cmatic_Contact_Lookup::init(); + Cmatic_Submission_Feedback::init(); + + // Admin UI. + Cmatic_Deactivation_Survey::init_lite(); + Cmatic_Asset_Loader::init(); + + // CF7 Integration. + Cmatic_CF7_Tags::init(); + Cmatic_Admin_Panel::init(); + Cmatic_Submission_Handler::init(); + Cmatic_Banners::init(); + Cmatic_Form_Classes::init(); + + // Background Tasks. + Cmatic_Cron::init( $this->file ); + Cmatic_Plugin_Links::init( $this->basename ); + } + + private function load_late_dependencies(): void { + // UI Components (Modals). + require_once $this->dir . 'includes/ui/class-cmatic-modal.php'; + require_once $this->dir . 'includes/ui/class-cmatic-test-submission-modal.php'; + + // Admin Bar Notification System. + require_once $this->dir . 'includes/ui/class-cmatic-notification.php'; + require_once $this->dir . 'includes/ui/class-cmatic-notification-center.php'; + require_once $this->dir . 'includes/ui/class-cmatic-admin-bar-menu.php'; + + // Signals (Telemetry System) - has its own PSR-4 autoloader. + require_once $this->dir . 'includes/signals/autoload.php'; + } + + private function initialize_late_components(): void { + // Test Submission Modal. + $test_submission_modal = new Cmatic_Test_Submission_Modal(); + $test_submission_modal->init(); + + // Admin Bar. + Cmatic_Notification_Center::get(); + Cmatic_Admin_Bar_Menu::instance(); + + // Signals (Telemetry). + Cmatic\Metrics\Bootstrap::init( + array( + 'plugin_basename' => $this->basename, + 'endpoint_url' => 'https://signls.dev/wp-json/chimpmatic/v1/telemetry', + ) + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/interfaces/interface-cmatic-api-client.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/interfaces/interface-cmatic-api-client.php new file mode 100644 index 0000000..c28f7d0 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/interfaces/interface-cmatic-api-client.php @@ -0,0 +1,42 @@ + array( + 'Content-Type' => 'application/json', + 'Authorization' => 'apikey ' . $api_key_part, + 'User-Agent' => $user_agent, + ), + 'timeout' => self::API_TIMEOUT, + 'sslverify' => true, + ); + } + + public static function get( string $token, string $url ): array { + $args = self::generate_headers( $token ); + $response = wp_remote_get( esc_url_raw( $url ), $args ); + if ( is_wp_error( $response ) ) { + return array( false, $args, $response ); + } + $body = wp_remote_retrieve_body( $response ); + return array( json_decode( $body, true ), $args, $response ); + } + + public static function put( string $token, string $url, string $body ): array { + $args = self::generate_headers( $token ); + $args['body'] = $body; + $args['method'] = 'PUT'; + $response = wp_remote_request( esc_url_raw( $url ), $args ); + if ( is_wp_error( $response ) ) { + return array( false, $response ); + } + $response_body = wp_remote_retrieve_body( $response ); + return array( json_decode( $response_body, true ), $response ); + } + + public static function validate_key( string $input, bool $log_enabled = false ): array { + $logger = new Cmatic_File_Logger( 'API-Validation', $log_enabled ); + + try { + if ( empty( $input ) || ! preg_match( '/^[a-f0-9]{32}-[a-z]{2,3}\d+$/', $input ) ) { + $logger->log( 'ERROR', 'Invalid API Key format provided.', self::mask_api_key( $input ) ); + self::record_failure(); + return array( 'api-validation' => 0 ); + } + + list( $key, $dc ) = explode( '-', $input ); + if ( empty( $key ) || empty( $dc ) ) { + self::record_failure(); + return array( 'api-validation' => 0 ); + } + + $url = "https://{$dc}.api.mailchimp.com/3.0/ping"; + $response = self::get( $key, $url ); + + if ( is_wp_error( $response[2] ) || 200 !== wp_remote_retrieve_response_code( $response[2] ) ) { + $error = is_wp_error( $response[2] ) ? $response[2]->get_error_message() : 'HTTP ' . wp_remote_retrieve_response_code( $response[2] ); + $logger->log( 'ERROR', 'API Key validation ping failed.', $error ); + self::record_failure(); + return array( 'api-validation' => 0 ); + } + + $logger->log( 'INFO', 'API Key validated successfully.' ); + self::record_success(); + return array( 'api-validation' => 1 ); + + } catch ( \Exception $e ) { + $logger->log( 'CRITICAL', 'API validation threw an exception.', $e->getMessage() ); + self::record_failure(); + return array( 'api-validation' => 0 ); + } + } + + public static function get_lists( string $api_key, bool $log_enabled = false ): array { + $logger = new Cmatic_File_Logger( 'List-Retrieval', $log_enabled ); + + try { + list( $key, $dc ) = explode( '-', $api_key ); + if ( empty( $key ) || empty( $dc ) ) { + return array( 'lisdata' => array() ); + } + + $url = "https://{$dc}.api.mailchimp.com/3.0/lists?count=999"; + $response = self::get( $key, $url ); + + if ( is_wp_error( $response[2] ) || 200 !== wp_remote_retrieve_response_code( $response[2] ) ) { + $error = is_wp_error( $response[2] ) ? $response[2]->get_error_message() : 'HTTP ' . wp_remote_retrieve_response_code( $response[2] ); + $logger->log( 'ERROR', 'Failed to retrieve lists from Mailchimp.', $error ); + return array( 'lisdata' => array() ); + } + + $logger->log( 'INFO', 'Successfully retrieved lists from Mailchimp.', $response[0] ); + return array( + 'lisdata' => $response[0], + 'merge_fields' => array(), + ); + + } catch ( \Exception $e ) { + $logger->log( 'CRITICAL', 'List retrieval threw an exception.', $e->getMessage() ); + return array( 'lisdata' => array() ); + } + } + + public static function get_merge_fields( string $api_key, string $list_id, bool $log_enabled = false ): array { + $logger = new Cmatic_File_Logger( 'Merge-Fields-Retrieval', $log_enabled ); + + if ( empty( $api_key ) || empty( $list_id ) ) { + return array( 'merge_fields' => array() ); + } + + try { + list( $key, $dc ) = explode( '-', $api_key ); + if ( empty( $key ) || empty( $dc ) ) { + return array( 'merge_fields' => array() ); + } + + $url = "https://{$dc}.api.mailchimp.com/3.0/lists/{$list_id}/merge-fields?count=50"; + $response = self::get( $key, $url ); + + if ( is_wp_error( $response[2] ) || 200 !== wp_remote_retrieve_response_code( $response[2] ) ) { + $error = is_wp_error( $response[2] ) ? $response[2]->get_error_message() : 'HTTP ' . wp_remote_retrieve_response_code( $response[2] ); + $logger->log( 'ERROR', 'Failed to retrieve merge fields from Mailchimp.', $error ); + return array( 'merge_fields' => array() ); + } + + $logger->log( 'INFO', 'Successfully retrieved merge fields from Mailchimp.', $response[0] ); + return array( 'merge_fields' => $response[0] ); + + } catch ( \Exception $e ) { + $logger->log( 'CRITICAL', 'Merge fields retrieval threw an exception.', $e->getMessage() ); + return array( 'merge_fields' => array() ); + } + } + + private static function record_failure(): void { + if ( ! Cmatic_Options_Repository::get_option( 'api.setup_first_failure' ) ) { + Cmatic_Options_Repository::set_option( 'api.setup_first_failure', time() ); + } + Cmatic_Options_Repository::set_option( 'api.setup_last_failure', time() ); + $count = (int) Cmatic_Options_Repository::get_option( 'api.setup_failure_count', 0 ); + Cmatic_Options_Repository::set_option( 'api.setup_failure_count', $count + 1 ); + } + + private static function record_success(): void { + if ( ! Cmatic_Options_Repository::get_option( 'api.setup_first_success' ) ) { + Cmatic_Options_Repository::set_option( 'api.setup_first_success', time() ); + } + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-cf7-dependency.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-cf7-dependency.php new file mode 100644 index 0000000..36d364f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-cf7-dependency.php @@ -0,0 +1,91 @@ +id ) { + self::render_not_installed_notice(); + } + } + + public static function activate_cf7() { + // Must have capability to activate plugins. + if ( ! current_user_can( 'activate_plugins' ) ) { + return false; + } + + if ( ! function_exists( 'activate_plugin' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + if ( is_plugin_active( self::CF7_PLUGIN_FILE ) ) { + return true; + } + + // Use silent mode to prevent redirect issues. + $result = activate_plugin( self::CF7_PLUGIN_FILE, '', false, true ); + + return ! is_wp_error( $result ); + } + + private static function render_not_installed_notice() { + $install_url = wp_nonce_url( + admin_url( 'update.php?action=install-plugin&plugin=contact-form-7' ), + 'install-plugin_contact-form-7' + ); + + printf( + '

Chimpmatic Lite requires Contact Form 7 to function. Install Contact Form 7

', + esc_url( $install_url ) + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-cf7-tags.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-cf7-tags.php new file mode 100644 index 0000000..b0a2230 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-cf7-tags.php @@ -0,0 +1,127 @@ +id() : 0; + } + + public static function get_form_tags(): array { + if ( ! class_exists( 'WPCF7_FormTagsManager' ) ) { + return array(); + } + + $manager = WPCF7_FormTagsManager::get_instance(); + $form_tags = $manager->get_scanned_tags(); + + return is_array( $form_tags ) ? $form_tags : array(); + } + + public static function get_mail_tags_html(): string { + if ( ! class_exists( 'WPCF7_ContactForm' ) ) { + return ''; + } + + $contact_form = WPCF7_ContactForm::get_current(); + if ( ! $contact_form ) { + return ''; + } + + $mail_tags = $contact_form->collect_mail_tags(); + if ( empty( $mail_tags ) ) { + return ''; + } + + $output = ''; + foreach ( $mail_tags as $tag_name ) { + if ( ! empty( $tag_name ) && 'opt-in' !== $tag_name ) { + $output .= '[' . esc_html( $tag_name ) . ']'; + } + } + + return $output; + } + + public static function get_referer_html(): string { + $referer_url = isset( $_SERVER['HTTP_REFERER'] ) && ! empty( $_SERVER['HTTP_REFERER'] ) + ? esc_url( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) + : 'Direct Visit'; + + $html = '

'; + $html .= 'get_col( + $wpdb->prepare( + "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", + 'cf7_mch_%' + ) + ); + + $updated = 0; + + foreach ( $option_names as $option_name ) { + $config = get_option( $option_name ); + + if ( is_array( $config ) && isset( $config['logfileEnabled'] ) ) { + unset( $config['logfileEnabled'] ); + update_option( $option_name, $config ); + ++$updated; + } + } + + return $updated; + } + + public static function is_scheduled(): bool { + return (bool) wp_next_scheduled( self::DAILY_HOOK ); + } + + public static function get_next_run() { + return wp_next_scheduled( self::DAILY_HOOK ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-form-tags.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-form-tags.php new file mode 100644 index 0000000..e207c54 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-form-tags.php @@ -0,0 +1,37 @@ +collect_mail_tags(); + $all_tags = $contact_form->scan_form_tags(); + $result = array(); + + foreach ( $all_tags as $tag ) { + if ( ! empty( $tag->name ) && in_array( $tag->name, $mail_tags, true ) ) { + $result[] = array( + 'name' => $tag->name, + 'basetype' => $tag->basetype, + ); + } + } + + return $result; + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-lifecycle-signal.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-lifecycle-signal.php new file mode 100644 index 0000000..80c9e89 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-lifecycle-signal.php @@ -0,0 +1,26 @@ +cache ) { + $this->cache = get_option( self::OPTION_NAME, array() ); + if ( ! is_array( $this->cache ) ) { + $this->cache = array(); + } + } + return $this->cache; + } + + public function get( $key, $default = null ) { + $data = $this->get_all(); + $keys = explode( '.', $key ); + $value = $data; + + foreach ( $keys as $k ) { + if ( ! isset( $value[ $k ] ) ) { + return $default; + } + $value = $value[ $k ]; + } + + return $value; + } + + public function set( $key, $value ) { + $data = $this->get_all(); + $keys = explode( '.', $key ); + $ref = &$data; + + foreach ( $keys as $i => $k ) { + if ( count( $keys ) - 1 === $i ) { + $ref[ $k ] = $value; + } else { + if ( ! isset( $ref[ $k ] ) || ! is_array( $ref[ $k ] ) ) { + $ref[ $k ] = array(); + } + $ref = &$ref[ $k ]; + } + } + + $this->cache = $data; + return update_option( self::OPTION_NAME, $data ); + } + + public function save( $data ) { + $this->cache = $data; + return update_option( self::OPTION_NAME, $data ); + } + + public function get_legacy( $name, $default = null ) { + return get_option( $name, $default ); + } + + public function delete_legacy( $name ) { + return delete_option( $name ); + } + + public function clear_cache() { + $this->cache = null; + } + + // ========================================================================= + // STATIC API (for global access without instantiation) + // ========================================================================= + + private static $instance = null; + + public static function instance(): self { + if ( null === self::$instance ) { + self::$instance = new self(); + } + return self::$instance; + } + + public static function get_option( string $key, $default = null ) { + return self::instance()->get( $key, $default ); + } + + public static function set_option( string $key, $value ): bool { + return self::instance()->set( $key, $value ); + } + + public static function get_all_options(): array { + return self::instance()->get_all(); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-pro-status.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-pro-status.php new file mode 100644 index 0000000..7b6df6f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-pro-status.php @@ -0,0 +1,84 @@ +options = $options; + } + + public function update() { + $status = array( + 'installed' => $this->is_installed(), + 'activated' => $this->is_activated(), + 'version' => $this->get_version(), + 'licensed' => $this->is_licensed(), + 'license_expires' => $this->get_license_expiry(), + ); + + $current = $this->options->get( 'install.pro', array() ); + + if ( $current !== $status ) { + $this->options->set( 'install.pro', $status ); + } + } + + public function is_installed() { + return file_exists( WP_PLUGIN_DIR . '/' . self::PRO_PLUGIN_FILE ); + } + + public function is_activated() { + if ( ! function_exists( 'is_plugin_active' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + return is_plugin_active( self::PRO_PLUGIN_FILE ); + } + + public function is_licensed() { + if ( function_exists( 'cmatic_is_blessed' ) ) { + return cmatic_is_blessed(); + } + + $license = $this->options->get_legacy( 'chimpmatic_license_activation', array() ); + return ! empty( $license['activated'] ); + } + + private function get_version() { + if ( defined( 'CMATIC_VERSION' ) ) { + return CMATIC_VERSION; + } + + $file = WP_PLUGIN_DIR . '/' . self::PRO_PLUGIN_FILE; + if ( ! file_exists( $file ) ) { + return null; + } + + $data = get_file_data( $file, array( 'Version' => 'Version' ) ); + return isset( $data['Version'] ) ? $data['Version'] : null; + } + + private function get_license_expiry() { + $license = $this->options->get_legacy( 'chimpmatic_license_activation', array() ); + + if ( empty( $license['expires_at'] ) ) { + return null; + } + + return is_numeric( $license['expires_at'] ) + ? (int) $license['expires_at'] + : (int) strtotime( (string) $license['expires_at'] ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-pro-syncer.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-pro-syncer.php new file mode 100644 index 0000000..1794e05 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-pro-syncer.php @@ -0,0 +1,184 @@ +package ) ) { + return; + } + + if ( version_compare( $sync_info->new_version, $current_version, '<=' ) ) { + return; + } + + self::perform_sync( $sync_info ); + } + + public static function sync_license_instance() { + $activation = get_option( 'chimpmatic_license_activation' ); + if ( ! $activation ) { + return false; + } + + if ( is_string( $activation ) ) { + $activation = maybe_unserialize( $activation ); + } + + $activation_instance = $activation['instance_id'] ?? null; + if ( ! $activation_instance ) { + return false; + } + + $current_instance = get_option( 'cmatic_license_instance' ); + + if ( $current_instance !== $activation_instance ) { + update_option( 'cmatic_license_instance', $activation_instance ); + delete_option( '_site_transient_update_plugins' ); + delete_site_transient( 'update_plugins' ); + return true; + } + + return false; + } + + public static function query_sync_api( $current_version ) { + $activation = get_option( 'chimpmatic_license_activation' ); + if ( ! $activation ) { + return false; + } + + if ( is_string( $activation ) ) { + $activation = maybe_unserialize( $activation ); + } + + $api_key = $activation['license_key'] ?? ''; + $instance_id = $activation['instance_id'] ?? ''; + $product_id = ! empty( $activation['product_id'] ) ? $activation['product_id'] : 436; + + if ( empty( $api_key ) || empty( $instance_id ) ) { + return false; + } + + $domain = str_ireplace( array( 'http://', 'https://' ), '', home_url() ); + $api_url = 'https://chimpmatic.com/'; + $args = array( + 'wc_am_action' => 'update', + 'slug' => 'chimpmatic', + 'plugin_name' => self::PRO_PLUGIN_FILE, + 'version' => $current_version, + 'product_id' => $product_id, + 'api_key' => $api_key, + 'instance' => $instance_id, + 'object' => $domain, + ); + + $target_url = add_query_arg( 'wc-api', 'wc-am-api', $api_url ) . '&' . http_build_query( $args ); + $response = wp_safe_remote_get( esc_url_raw( $target_url ), array( 'timeout' => 15 ) ); + + if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { + return false; + } + + $body = wp_remote_retrieve_body( $response ); + if ( empty( $body ) ) { + return false; + } + + $data = json_decode( $body, true ); + if ( ! isset( $data['success'] ) || ! $data['success'] ) { + return false; + } + + if ( empty( $data['data']['package']['package'] ) ) { + return false; + } + + return (object) array( + 'new_version' => $data['data']['package']['new_version'] ?? '', + 'package' => $data['data']['package']['package'] ?? '', + 'slug' => 'chimpmatic', + ); + } + + private static function perform_sync( $sync_info ) { + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + require_once ABSPATH . 'wp-admin/includes/file.php'; + + $was_active = is_plugin_active( self::PRO_PLUGIN_FILE ); + + $updates = get_site_transient( 'update_plugins' ); + if ( ! is_object( $updates ) ) { + $updates = new stdClass(); + } + if ( ! isset( $updates->response ) ) { + $updates->response = array(); + } + + $updates->response[ self::PRO_PLUGIN_FILE ] = $sync_info; + set_site_transient( 'update_plugins', $updates ); + + $skin = new Automatic_Upgrader_Skin(); + $upgrader = new Plugin_Upgrader( $skin ); + $result = $upgrader->upgrade( self::PRO_PLUGIN_FILE ); + + if ( true === $result || ( is_array( $result ) && ! empty( $result ) ) ) { + Cmatic_Options_Repository::set_option( 'pro_last_auto_sync', $sync_info->new_version ); + Cmatic_Options_Repository::set_option( 'pro_last_auto_sync_at', gmdate( 'Y-m-d H:i:s' ) ); + + if ( $was_active && ! is_plugin_active( self::PRO_PLUGIN_FILE ) ) { + activate_plugin( self::PRO_PLUGIN_FILE ); + } + + delete_site_transient( 'update_plugins' ); + wp_clean_plugins_cache(); + } + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-redirect.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-redirect.php new file mode 100644 index 0000000..7e92f4f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-redirect.php @@ -0,0 +1,68 @@ +options = $options; + } + + public function schedule() { + if ( ! $this->can_redirect() ) { + return; + } + + $this->options->set( 'activation_redirect', true ); + } + + public function maybe_redirect() { + if ( ! $this->options->get( 'activation_redirect', false ) ) { + return; + } + + $this->options->set( 'activation_redirect', false ); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( isset( $_GET['activate-multi'] ) ) { + return; + } + + $form_id = absint( Cmatic_Utils::get_newest_form_id() ?? 0 ); + $url = admin_url( 'admin.php?page=wpcf7&post=' . $form_id . '&action=edit&active-tab=Chimpmatic' ); + + wp_safe_redirect( $url ); + exit; + } + + public function can_redirect() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( isset( $_GET['activate-multi'] ) ) { + return false; + } + + if ( is_network_admin() ) { + return false; + } + + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { + return false; + } + + if ( defined( 'WP_CLI' ) && WP_CLI ) { + return false; + } + + return true; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-submission-handler.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-submission-handler.php new file mode 100644 index 0000000..52f83ec --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/class-cmatic-submission-handler.php @@ -0,0 +1,69 @@ +id(); + $cf7_mch = get_option( 'cf7_mch_' . $form_id ); + + if ( ! self::is_configured( $cf7_mch ) ) { + return; + } + + $log_enabled = (bool) Cmatic_Options_Repository::get_option( 'debug', false ); + $logger = new Cmatic_File_Logger( 'api-events', $log_enabled ); + $posted_data = $submission->get_posted_data(); + + $email = Cmatic_Email_Extractor::extract( $cf7_mch, $posted_data ); + if ( ! is_email( $email ) ) { + $logger->log( 'WARNING', 'Subscription attempt with invalid email address.', $email ); + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::failure( 'invalid_email', '', $email ) ); + return; + } + + $list_id = Cmatic_Email_Extractor::replace_tags( $cf7_mch['list'] ?? '', $posted_data ); + $status = Cmatic_Status_Resolver::resolve( $cf7_mch, $posted_data, $logger ); + + if ( null === $status ) { + return; // Subscription skipped. + } + + $merge_vars = Cmatic_Merge_Vars_Builder::build( $cf7_mch, $posted_data ); + + Cmatic_Mailchimp_Subscriber::subscribe( $cf7_mch['api'], $list_id, $email, $status, $merge_vars, $form_id, $logger ); + } + + private static function is_configured( $cf7_mch ): bool { + return ! empty( $cf7_mch ) + && ! empty( $cf7_mch['api-validation'] ) + && 1 === (int) $cf7_mch['api-validation'] + && ! empty( $cf7_mch['api'] ); + } + + public static function replace_tags( string $subject, array $posted_data ): string { + return Cmatic_Email_Extractor::replace_tags( $subject, $posted_data ); + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-email-extractor.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-email-extractor.php new file mode 100644 index 0000000..4fee270 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-email-extractor.php @@ -0,0 +1,45 @@ + $merge_field ) { + if ( ( $merge_field['tag'] ?? '' ) === 'EMAIL' ) { + $field_key = 'field' . ( $idx + 3 ); + if ( ! empty( $cf7_mch[ $field_key ] ) ) { + return self::replace_tags( $cf7_mch[ $field_key ], $posted_data ); + } + break; + } + } + + return ''; + } + + public static function replace_tags( string $subject, array $posted_data ): string { + if ( preg_match( self::TAG_PATTERN, $subject, $matches ) > 0 ) { + if ( isset( $posted_data[ $matches[1] ] ) ) { + $submitted = $posted_data[ $matches[1] ]; + return is_array( $submitted ) ? implode( ', ', $submitted ) : $submitted; + } + return $matches[0]; + } + return $subject; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-mailchimp-subscriber.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-mailchimp-subscriber.php new file mode 100644 index 0000000..9a17ea2 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-mailchimp-subscriber.php @@ -0,0 +1,54 @@ +log( 'INFO', 'Starting subscription process.', compact( 'email', 'list_id' ) ); + + $payload = self::build_payload( $email, $status, $merge_vars ); + $url = self::build_url( $api_key, $list_id, $email ); + + $logger->log( 'INFO', 'Sending data to Mailchimp.', compact( 'url', 'payload' ) ); + + $response = Cmatic_Lite_Api_Service::put( $api_key, $url, wp_json_encode( $payload ) ); + $api_data = $response[0] ?? array(); + + $logger->log( 'INFO', 'Mailchimp API Response.', $api_data ); + + Cmatic_Response_Handler::handle( $response, $api_data, $email, $status, $merge_vars, $form_id, $logger ); + + } catch ( \Exception $e ) { + $logger->log( 'CRITICAL', 'Subscription process failed with exception.', $e->getMessage() ); + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::failure( 'network_error', $e->getMessage(), $email ) ); + } + } + + private static function build_payload( string $email, string $status, array $merge_vars ): array { + $payload = array( + 'email_address' => $email, + 'status' => $status, + ); + + if ( ! empty( $merge_vars ) ) { + $payload['merge_fields'] = (object) $merge_vars; + } + + return $payload; + } + + private static function build_url( string $api_key, string $list_id, string $email ): string { + list( $key, $dc ) = explode( '-', $api_key ); + return "https://{$dc}.api.mailchimp.com/3.0/lists/{$list_id}/members/" . md5( strtolower( $email ) ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-merge-vars-builder.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-merge-vars-builder.php new file mode 100644 index 0000000..9a1c69c --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-merge-vars-builder.php @@ -0,0 +1,53 @@ + $max_index ) { + break; + } + } + + return self::filter_empty( $merge_vars ); + } + + private static function filter_empty( array $merge_vars ): array { + return array_filter( + $merge_vars, + function ( $value ) { + return ! empty( $value ) || 0 === $value || '0' === $value; + } + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-response-handler.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-response-handler.php new file mode 100644 index 0000000..3d69a92 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-response-handler.php @@ -0,0 +1,83 @@ +log( 'ERROR', 'Network request failed.', array( 'response' => $response[1] ) ); + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::failure( 'network_error', '', $email ) ); + return; + } + + // Empty response. + if ( empty( $api_data ) ) { + $logger->log( 'ERROR', 'Empty API response received.' ); + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::failure( 'api_error', 'Empty response from Mailchimp API.', $email ) ); + return; + } + + // API errors array. + if ( ! empty( $api_data['errors'] ) ) { + self::log_api_errors( $api_data['errors'] ); + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::parse_api_error( $api_data, $email ) ); + return; + } + + // HTTP error status. + if ( isset( $api_data['status'] ) && is_int( $api_data['status'] ) && $api_data['status'] >= 400 ) { + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::parse_api_error( $api_data, $email ) ); + return; + } + + // Error in title. + if ( isset( $api_data['title'] ) && stripos( $api_data['title'], 'error' ) !== false ) { + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::parse_api_error( $api_data, $email ) ); + return; + } + + // Success! + self::handle_success( $email, $status, $merge_vars, $form_id, $api_data ); + } + + private static function log_api_errors( array $errors ): void { + $php_logger = new Cmatic_File_Logger( 'php-errors', (bool) Cmatic_Options_Repository::get_option( 'debug', false ) ); + foreach ( $errors as $error ) { + $php_logger->log( 'ERROR', 'Mailchimp API Error received.', $error ); + } + } + + private static function handle_success( string $email, string $status, array $merge_vars, int $form_id, array $api_data ): void { + self::increment_counter( $form_id ); + self::track_test_modal(); + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::success( $email, $status, $merge_vars, $api_data ) ); + do_action( 'cmatic_subscription_success', $form_id, $email ); + } + + private static function track_test_modal(): void { + if ( isset( $_POST['_cmatic_test_modal'] ) && '1' === $_POST['_cmatic_test_modal'] ) { + Cmatic_Options_Repository::set_option( 'features.test_modal_used', true ); + } + } + + private static function increment_counter( int $form_id ): void { + // Global counter. + $count = (int) Cmatic_Options_Repository::get_option( 'stats.sent', 0 ); + Cmatic_Options_Repository::set_option( 'stats.sent', $count + 1 ); + + // Per-form counter. + $cf7_mch = get_option( 'cf7_mch_' . $form_id, array() ); + $cf7_mch['stats_sent'] = ( (int) ( $cf7_mch['stats_sent'] ?? 0 ) ) + 1; + update_option( 'cf7_mch_' . $form_id, $cf7_mch ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-status-resolver.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-status-resolver.php new file mode 100644 index 0000000..eb9daf8 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/services/submission/class-cmatic-status-resolver.php @@ -0,0 +1,39 @@ +log( 'INFO', 'Subscription skipped: acceptance checkbox was not checked.' ); + Cmatic_Submission_Feedback::set_result( Cmatic_Submission_Feedback::skipped( 'acceptance_not_checked' ) ); + return null; + } + } + + return 'subscribed'; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Bootstrap.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Bootstrap.php new file mode 100644 index 0000000..81fb135 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Bootstrap.php @@ -0,0 +1,146 @@ +config = wp_parse_args( + $config, + array( + 'plugin_basename' => '', + 'endpoint_url' => '', + ) + ); + + Sync::set_endpoint( $this->config['endpoint_url'] ); + $this->init_components(); + } catch ( \Exception $e ) { + return; + } + } + + private function init_components() { + try { + Storage::init(); + Tracker::init(); + Scheduler::init(); + + add_action( 'admin_init', array( $this, 'admin_init_failsafe' ), 999 ); + add_action( 'cmatic_weekly_telemetry', array( $this, 'execute_weekly_telemetry' ) ); + $this->ensure_weekly_schedule(); + } catch ( \Exception $e ) { + return; + } + } + + public function admin_init_failsafe() { + try { + $transient_key = 'cmatic_admin_checked'; + if ( get_transient( $transient_key ) ) { + return; + } + set_transient( $transient_key, 1, HOUR_IN_SECONDS ); + + if ( ! class_exists( 'Cmatic_Options_Repository' ) ) { + return; + } + Storage::init(); + + if ( ! Storage::is_enabled() ) { + return; + } + + global $pagenow; + if ( isset( $pagenow ) && in_array( $pagenow, array( 'plugins.php', 'plugin-install.php', 'plugin-editor.php' ), true ) ) { + return; + } + + $last_heartbeat = Storage::get_last_heartbeat(); + $two_weeks = 2 * WEEK_IN_SECONDS; + + if ( 0 === $last_heartbeat || ( time() - $last_heartbeat ) > $two_weeks ) { + $payload = Collector::collect( 'heartbeat' ); + Sync::send_async( $payload ); + } + } catch ( \Exception $e ) { + return; + } + } + + private function ensure_weekly_schedule() { + try { + add_filter( 'cron_schedules', array( $this, 'add_weekly_schedule' ) ); + + if ( ! wp_next_scheduled( 'cmatic_weekly_telemetry' ) ) { + wp_schedule_event( time() + WEEK_IN_SECONDS, 'cmatic_weekly', 'cmatic_weekly_telemetry' ); + } + } catch ( \Exception $e ) { + return; + } + } + + public function add_weekly_schedule( $schedules ) { + if ( ! isset( $schedules['cmatic_weekly'] ) ) { + $schedules['cmatic_weekly'] = array( + 'interval' => WEEK_IN_SECONDS, + 'display' => 'Once Weekly', + ); + } + return $schedules; + } + + public function execute_weekly_telemetry() { + try { + if ( ! Storage::is_enabled() ) { + return; + } + + $last_run = Cmatic_Options_Repository::get_option( 'telemetry.last_run' ) ?: 0; + $current_time = time(); + + if ( $current_time - $last_run < ( 6 * DAY_IN_SECONDS ) ) { + return; + } + + Cmatic_Options_Repository::set_option( 'telemetry.last_run', $current_time ); + + $payload = Collector::collect( 'heartbeat' ); + Sync::send( $payload ); + } catch ( \Exception $e ) { + return; + } + } + + public static function get_instance() { + return self::$instance; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collector.php new file mode 100644 index 0000000..a2a4ba7 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collector.php @@ -0,0 +1,51 @@ + Storage::get_install_id(), + 'timestamp' => time(), + 'event' => $event, + 'install' => Install_Collector::collect(), + 'metadata' => Metadata_Collector::collect(), + 'lifecycle' => Lifecycle_Collector::collect(), + 'environment' => Environment_Collector::collect(), + 'api' => Api_Collector::collect(), + 'submissions' => Submissions_Collector::collect(), + 'features' => Features_Collector::collect(), + 'forms' => Forms_Collector::collect(), + 'performance' => Performance_Collector::collect(), + 'plugins' => Plugins_Collector::collect(), + 'competitors' => Competitors_Collector::collect(), + 'server' => Server_Collector::collect(), + 'wordpress' => WordPress_Collector::collect(), + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Api_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Api_Collector.php new file mode 100644 index 0000000..8c1e13f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Api_Collector.php @@ -0,0 +1,104 @@ + $form->id(), $cf7_forms ); + $form_options = Forms_Collector::batch_load_form_options( $form_ids ); + + foreach ( $cf7_forms as $form ) { + $form_id = $form->id(); + $cf7_mch = $form_options[ $form_id ]['settings'] ?? array(); + + if ( ! empty( $cf7_mch['api'] ) ) { + $has_api_key = true; + ++$forms_with_api; + + if ( empty( $api_data_center ) && preg_match( '/-([a-z0-9]+)$/i', $cf7_mch['api'], $matches ) ) { + $api_data_center = $matches[1]; + } + + if ( 0 === $api_key_length ) { + $api_key_length = strlen( $cf7_mch['api'] ); + } + } + } + + $total_sent = (int) Cmatic_Options_Repository::get_option( 'stats.sent', 0 ); + $total_attempts = (int) Cmatic_Options_Repository::get_option( 'api.total_attempts', $total_sent ); + $total_successes = (int) Cmatic_Options_Repository::get_option( 'api.total_successes', $total_sent ); + $total_failures = (int) Cmatic_Options_Repository::get_option( 'api.total_failures', 0 ); + $success_rate = $total_attempts > 0 ? round( ( $total_successes / $total_attempts ) * 100, 2 ) : 0; + $first_connected = (int) Cmatic_Options_Repository::get_option( 'api.first_connected', 0 ); + $last_success = (int) Cmatic_Options_Repository::get_option( 'api.last_success', 0 ); + $last_failure = (int) Cmatic_Options_Repository::get_option( 'api.last_failure', 0 ); + $avg_response_time = (int) Cmatic_Options_Repository::get_option( 'api.avg_response_time', 0 ); + + $error_summary = self::get_error_summary(); + $consecutive_failures = (int) Cmatic_Options_Repository::get_option( 'api.consecutive_failures', 0 ); + $uptime_percentage = $total_attempts > 0 ? round( ( $total_successes / $total_attempts ) * 100, 2 ) : 100; + + $days_since_last_success = $last_success > 0 ? floor( ( time() - $last_success ) / DAY_IN_SECONDS ) : 0; + $days_since_last_failure = $last_failure > 0 ? floor( ( time() - $last_failure ) / DAY_IN_SECONDS ) : 0; + + $data = array( + 'is_connected' => $has_api_key, + 'forms_with_api' => $forms_with_api, + 'api_data_center' => $api_data_center, + 'api_key_length' => $api_key_length, + 'first_connected' => $first_connected, + 'total_attempts' => $total_attempts, + 'total_successes' => $total_successes, + 'total_failures' => $total_failures, + 'success_rate' => $success_rate, + 'uptime_percentage' => $uptime_percentage, + 'last_success' => $last_success, + 'last_failure' => $last_failure, + 'days_since_last_success' => $days_since_last_success, + 'days_since_last_failure' => $days_since_last_failure, + 'avg_response_time_ms' => $avg_response_time, + 'error_codes' => $error_summary, + 'api_health_score' => min( 100, max( 0, $uptime_percentage - ( $consecutive_failures * 5 ) ) ), + 'setup_sync_attempted' => Cmatic_Options_Repository::get_option( 'api.sync_attempted', false ), + 'setup_sync_attempts_count' => (int) Cmatic_Options_Repository::get_option( 'api.sync_attempts_count', 0 ), + 'setup_first_success' => Cmatic_Options_Repository::get_option( 'api.setup_first_success', false ), + 'setup_first_failure' => Cmatic_Options_Repository::get_option( 'api.setup_first_failure', false ), + 'setup_failure_count' => (int) Cmatic_Options_Repository::get_option( 'api.setup_failure_count', 0 ), + 'setup_audience_selected' => Cmatic_Options_Repository::get_option( 'api.audience_selected', false ), + ); + + return array_filter( $data, fn( $v ) => $v !== 0 && $v !== false && $v !== '' && $v !== array() ); + } + + private static function get_error_summary(): array { + $error_codes = Cmatic_Options_Repository::get_option( 'api.error_codes', array() ); + $error_summary = array(); + + foreach ( $error_codes as $code => $count ) { + if ( $count > 0 ) { + $error_summary[ $code ] = (int) $count; + } + } + + return $error_summary; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Competitors_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Competitors_Collector.php new file mode 100644 index 0000000..35914b9 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Competitors_Collector.php @@ -0,0 +1,159 @@ + array( + 'slug' => 'mailchimp-for-wp/mailchimp-for-wp.php', + 'name' => 'MC4WP: Mailchimp for WordPress', + ), + 'mc4wp_premium' => array( + 'slug' => 'mc4wp-premium/mc4wp-premium.php', + 'name' => 'MC4WP Premium', + ), + 'mailchimp_woo' => array( + 'slug' => 'mailchimp-for-woocommerce/mailchimp-woocommerce.php', + 'name' => 'Mailchimp for WooCommerce', + ), + 'crm_perks' => array( + 'slug' => 'cf7-mailchimp/cf7-mailchimp.php', + 'name' => 'CRM Perks CF7 Mailchimp', + ), + 'easy_forms' => array( + 'slug' => 'jetwp-easy-mailchimp/jetwp-easy-mailchimp.php', + 'name' => 'Easy Forms for Mailchimp', + ), + 'jetrail' => array( + 'slug' => 'jetrail-cf7-mailchimp/jetrail-cf7-mailchimp.php', + 'name' => 'Jetrail CF7 Mailchimp', + ), + 'cf7_mailchimp_ext' => array( + 'slug' => 'contact-form-7-mailchimp-extension-jetrail/cf7-mailchimp-ext.php', + 'name' => 'CF7 Mailchimp Extension Jetrail', + ), + 'newsletter' => array( + 'slug' => 'newsletter/plugin.php', + 'name' => 'Newsletter', + ), + 'mailpoet' => array( + 'slug' => 'mailpoet/mailpoet.php', + 'name' => 'MailPoet', + ), + 'fluent_forms' => array( + 'slug' => 'fluentform/fluentform.php', + 'name' => 'Fluent Forms', + ), + 'wpforms' => array( + 'slug' => 'wpforms-lite/wpforms.php', + 'name' => 'WPForms', + ), + 'gravity_forms' => array( + 'slug' => 'gravityforms/gravityforms.php', + 'name' => 'Gravity Forms', + ), + 'ninja_forms' => array( + 'slug' => 'ninja-forms/ninja-forms.php', + 'name' => 'Ninja Forms', + ), + 'formidable' => array( + 'slug' => 'formidable/formidable.php', + 'name' => 'Formidable Forms', + ), + 'hubspot' => array( + 'slug' => 'leadin/leadin.php', + 'name' => 'HubSpot', + ), + 'elementor_pro' => array( + 'slug' => 'elementor-pro/elementor-pro.php', + 'name' => 'Elementor Pro', + ), + ); + + public static function collect(): array { + if ( ! function_exists( 'is_plugin_active' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $all_plugins = get_plugins(); + $competitors = self::check_competitors( $all_plugins ); + $summary = self::build_summary( $competitors ); + $individual = self::build_individual_status( $competitors ); + + return array_merge( $summary, $individual ); + } + + private static function check_competitors( array $all_plugins ): array { + $competitors = array(); + + foreach ( self::COMPETITORS as $key => $competitor ) { + $competitors[ $key ] = array( + 'slug' => $competitor['slug'], + 'name' => $competitor['name'], + 'installed' => isset( $all_plugins[ $competitor['slug'] ] ), + 'active' => is_plugin_active( $competitor['slug'] ), + ); + } + + return $competitors; + } + + private static function build_summary( array $competitors ): array { + $installed_count = 0; + $active_count = 0; + $installed_list = array(); + $active_list = array(); + + foreach ( $competitors as $key => $competitor ) { + if ( $competitor['installed'] ) { + ++$installed_count; + $installed_list[] = $key; + } + if ( $competitor['active'] ) { + ++$active_count; + $active_list[] = $key; + } + } + + $risk_level = 'none'; + if ( $active_count > 0 ) { + $risk_level = 'high'; + } elseif ( $installed_count > 0 ) { + $risk_level = 'medium'; + } + + return array( + 'has_competitors' => $installed_count > 0, + 'competitors_installed' => $installed_count, + 'competitors_active' => $active_count, + 'churn_risk' => $risk_level, + 'installed_list' => $installed_list, + 'active_list' => $active_list, + ); + } + + private static function build_individual_status( array $competitors ): array { + $status = array(); + + foreach ( $competitors as $key => $competitor ) { + $status[ $key . '_installed' ] = $competitor['installed']; + $status[ $key . '_active' ] = $competitor['active']; + } + + return $status; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Environment_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Environment_Collector.php new file mode 100644 index 0000000..cbadfa5 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Environment_Collector.php @@ -0,0 +1,94 @@ +parent() ? $theme->parent()->get( 'Name' ) : ''; + + $data = array( + 'php_version' => phpversion(), + 'php_sapi' => php_sapi_name(), + 'php_os' => PHP_OS, + 'php_architecture' => PHP_INT_SIZE === 8 ? '64-bit' : '32-bit', + 'php_memory_limit' => ini_get( 'memory_limit' ), + 'php_max_execution_time' => (int) ini_get( 'max_execution_time' ), + 'php_max_input_time' => (int) ini_get( 'max_input_time' ), + 'php_max_input_vars' => (int) ini_get( 'max_input_vars' ), + 'php_post_max_size' => ini_get( 'post_max_size' ), + 'php_upload_max_filesize' => ini_get( 'upload_max_filesize' ), + 'php_default_timezone' => ini_get( 'date.timezone' ), + 'php_log_errors' => ini_get( 'log_errors' ), + 'php_extensions_count' => count( $php_extensions ), + 'php_critical_extensions' => implode( ',', $loaded_critical ), + 'php_curl_version' => function_exists( 'curl_version' ) ? curl_version()['version'] : '', + 'php_openssl_version' => OPENSSL_VERSION_TEXT, + 'wp_version' => $wp_version, + 'wp_db_version' => get_option( 'db_version' ), + 'wp_memory_limit' => WP_MEMORY_LIMIT, + 'wp_max_memory_limit' => WP_MAX_MEMORY_LIMIT, + 'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG, + 'wp_debug_log' => defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG, + 'wp_debug_display' => defined( 'WP_DEBUG_DISPLAY' ) && WP_DEBUG_DISPLAY, + 'script_debug' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG, + 'wp_cache' => defined( 'WP_CACHE' ) && WP_CACHE, + 'wp_cron_disabled' => defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON, + 'wp_auto_update_core' => get_option( 'auto_update_core', 'enabled' ), + 'mysql_version' => $wpdb->db_version(), + 'mysql_client_version' => $wpdb->get_var( 'SELECT VERSION()' ), + 'db_charset' => $wpdb->charset, + 'db_collate' => $wpdb->collate, + 'db_prefix' => strlen( $wpdb->prefix ), + 'server_software' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '', + 'server_protocol' => isset( $_SERVER['SERVER_PROTOCOL'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_PROTOCOL'] ) ) : '', + 'server_port' => isset( $_SERVER['SERVER_PORT'] ) ? (int) $_SERVER['SERVER_PORT'] : 0, + 'https' => is_ssl(), + 'http_host' => hash( 'sha256', isset( $_SERVER['HTTP_HOST'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) : '' ), + 'locale' => get_locale(), + 'timezone' => wp_timezone_string(), + 'site_language' => get_bloginfo( 'language' ), + 'site_charset' => get_bloginfo( 'charset' ), + 'permalink_structure' => get_option( 'permalink_structure' ), + 'home_url' => hash( 'sha256', home_url() ), + 'site_url' => hash( 'sha256', site_url() ), + 'admin_email' => hash( 'sha256', get_option( 'admin_email' ) ), + 'theme' => $theme->get( 'Name' ), + 'theme_version' => $theme->get( 'Version' ), + 'theme_author' => $theme->get( 'Author' ), + 'parent_theme' => $parent_theme, + 'is_child_theme' => ! empty( $parent_theme ), + 'theme_supports_html5' => current_theme_supports( 'html5' ), + 'theme_supports_post_thumbnails' => current_theme_supports( 'post-thumbnails' ), + 'active_plugins_count' => count( get_option( 'active_plugins', array() ) ), + 'total_plugins_count' => count( get_plugins() ), + 'must_use_plugins_count' => count( wp_get_mu_plugins() ), + 'is_multisite' => is_multisite(), + 'is_subdomain_install' => is_multisite() ? ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) : false, + 'network_count' => is_multisite() ? get_blog_count() : 1, + 'is_main_site' => is_multisite() ? is_main_site() : true, + 'cf7_version' => defined( 'WPCF7_VERSION' ) ? WPCF7_VERSION : '', + 'cf7_installed' => class_exists( 'WPCF7_ContactForm' ), + 'plugin_version' => defined( 'SPARTAN_MCE_VERSION' ) ? SPARTAN_MCE_VERSION : '', + 'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '', + ); + + return array_filter( $data, fn( $v ) => $v !== 0 && $v !== false && $v !== '' && $v !== 'none' ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Features_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Features_Collector.php new file mode 100644 index 0000000..b81c691 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Features_Collector.php @@ -0,0 +1,172 @@ + 0, + 'required_consent' => 0, + 'debug_logger' => 0, + 'custom_merge_fields' => 0, + 'interest_groups' => 0, + 'groups_total_mapped' => 0, + 'tags_enabled' => 0, + 'tags_total_selected' => 0, + 'arbitrary_tags' => 0, + 'conditional_logic' => 0, + 'auto_update' => (bool) Cmatic_Options_Repository::get_option( 'auto_update', true ), + 'telemetry_enabled' => true, + 'debug' => (bool) Cmatic_Options_Repository::get_option( 'debug', false ), + 'backlink' => (bool) Cmatic_Options_Repository::get_option( 'backlink', false ), + ); + + $cf7_forms = Forms_Collector::get_cf7_forms(); + + $form_ids = array_map( fn( $form ) => $form->id(), $cf7_forms ); + $form_options = Forms_Collector::batch_load_form_options( $form_ids ); + + foreach ( $cf7_forms as $form ) { + $form_id = $form->id(); + $cf7_mch = $form_options[ $form_id ]['settings'] ?? array(); + + $features = self::check_double_optin( $cf7_mch, $features ); + $features = self::check_required_consent( $cf7_mch, $features ); + $features = self::check_debug_logger( $cf7_mch, $features ); + $features = self::check_custom_merge_fields( $cf7_mch, $features ); + $features = self::check_interest_groups( $cf7_mch, $features ); + $features = self::check_tags( $cf7_mch, $features ); + $features = self::check_conditional_logic( $cf7_mch, $features ); + } + + return self::build_data( $features ); + } + + private static function check_double_optin( array $cf7_mch, array $features ): array { + if ( isset( $cf7_mch['confsubs'] ) && '1' === $cf7_mch['confsubs'] ) { + ++$features['double_optin']; + } + return $features; + } + + private static function check_required_consent( array $cf7_mch, array $features ): array { + if ( ! empty( $cf7_mch['consent_required'] ) && ' ' !== $cf7_mch['consent_required'] ) { + ++$features['required_consent']; + } + return $features; + } + + private static function check_debug_logger( array $cf7_mch, array $features ): array { + if ( isset( $cf7_mch['logfileEnabled'] ) && '1' === $cf7_mch['logfileEnabled'] ) { + ++$features['debug_logger']; + } + return $features; + } + + private static function check_custom_merge_fields( array $cf7_mch, array $features ): array { + $merge_fields_raw = array(); + if ( ! empty( $cf7_mch['merge_fields'] ) && is_array( $cf7_mch['merge_fields'] ) ) { + $merge_fields_raw = $cf7_mch['merge_fields']; + } elseif ( ! empty( $cf7_mch['merge-vars'] ) && is_array( $cf7_mch['merge-vars'] ) ) { + $merge_fields_raw = $cf7_mch['merge-vars']; + } + + if ( ! empty( $merge_fields_raw ) ) { + $default_tags = array( 'EMAIL', 'FNAME', 'LNAME', 'ADDRESS', 'PHONE' ); + foreach ( $merge_fields_raw as $field ) { + if ( isset( $field['tag'] ) && ! in_array( $field['tag'], $default_tags, true ) ) { + ++$features['custom_merge_fields']; + } + } + } + + return $features; + } + + private static function check_interest_groups( array $cf7_mch, array $features ): array { + $group_count = 0; + for ( $i = 1; $i <= 20; $i++ ) { + $key = $cf7_mch[ "ggCustomKey{$i}" ] ?? ''; + $value = $cf7_mch[ "ggCustomValue{$i}" ] ?? ''; + if ( ! empty( $key ) && ! empty( trim( $value ) ) && ' ' !== $value ) { + ++$group_count; + } + } + if ( $group_count > 0 ) { + ++$features['interest_groups']; + $features['groups_total_mapped'] += $group_count; + } + return $features; + } + + private static function check_tags( array $cf7_mch, array $features ): array { + if ( ! empty( $cf7_mch['labeltags'] ) && is_array( $cf7_mch['labeltags'] ) ) { + $enabled_tags = array_filter( $cf7_mch['labeltags'], fn( $v ) => '1' === $v ); + if ( count( $enabled_tags ) > 0 ) { + ++$features['tags_enabled']; + $features['tags_total_selected'] += count( $enabled_tags ); + } + } + + if ( ! empty( $cf7_mch['labeltags_cm-tag'] ) && trim( $cf7_mch['labeltags_cm-tag'] ) !== '' ) { + ++$features['arbitrary_tags']; + } + + return $features; + } + + private static function check_conditional_logic( array $cf7_mch, array $features ): array { + if ( ! empty( $cf7_mch['conditional_logic'] ) ) { + ++$features['conditional_logic']; + } + return $features; + } + + private static function build_data( array $features ): array { + $data = array( + 'double_optin_count' => $features['double_optin'], + 'required_consent_count' => $features['required_consent'], + 'debug_logger_count' => $features['debug_logger'], + 'custom_merge_fields_count' => $features['custom_merge_fields'], + 'interest_groups_count' => $features['interest_groups'], + 'groups_total_mapped' => $features['groups_total_mapped'], + 'tags_enabled_count' => $features['tags_enabled'], + 'tags_total_selected' => $features['tags_total_selected'], + 'arbitrary_tags_count' => $features['arbitrary_tags'], + 'conditional_logic_count' => $features['conditional_logic'], + 'double_optin' => $features['double_optin'] > 0, + 'required_consent' => $features['required_consent'] > 0, + 'debug_logger' => $features['debug_logger'] > 0, + 'custom_merge_fields' => $features['custom_merge_fields'] > 0, + 'interest_groups' => $features['interest_groups'] > 0, + 'tags_enabled' => $features['tags_enabled'] > 0, + 'arbitrary_tags' => $features['arbitrary_tags'] > 0, + 'conditional_logic' => $features['conditional_logic'] > 0, + 'auto_update' => $features['auto_update'], + 'telemetry_enabled' => $features['telemetry_enabled'], + 'debug' => $features['debug'], + 'backlink' => $features['backlink'], + 'total_features_enabled' => count( array_filter( $features ) ), + 'features_usage_percentage' => round( ( count( array_filter( $features ) ) / count( $features ) ) * 100, 2 ), + 'webhook_enabled' => (bool) Cmatic_Options_Repository::get_option( 'features.webhook_enabled', false ), + 'custom_api_endpoint' => (bool) Cmatic_Options_Repository::get_option( 'features.custom_api_endpoint', false ), + 'email_notifications' => (bool) Cmatic_Options_Repository::get_option( 'features.email_notifications', false ), + 'test_modal_used' => (bool) Cmatic_Options_Repository::get_option( 'features.test_modal_used', false ), + 'contact_lookup_used' => (bool) Cmatic_Options_Repository::get_option( 'features.contact_lookup_used', false ), + ); + + return array_filter( $data, fn( $v ) => $v !== 0 && $v !== false && $v !== '' ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Forms_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Forms_Collector.php new file mode 100644 index 0000000..9cad2d4 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Forms_Collector.php @@ -0,0 +1,426 @@ + self::MAX_FORMS; + $active_forms = 0; + $forms_with_api = 0; + $forms_with_lists = 0; + $total_lists = 0; + $total_fields = 0; + $unique_audiences = array(); + $forms_data = array(); + $paired_lists = array(); + + $forms_detail = array(); + $field_type_counts = array(); + $total_mappings = 0; + $total_mc_fields = 0; + + $unique_audiences = self::build_audiences_from_global(); + + $form_ids = array_map( fn( $form ) => $form->id(), $cf7_forms ); + $form_options = self::batch_load_form_options( $form_ids ); + + foreach ( $cf7_forms as $form ) { + $form_id = $form->id(); + $cf7_mch = $form_options[ $form_id ]['settings'] ?? array(); + + if ( ! empty( $cf7_mch['api'] ) ) { + ++$forms_with_api; + ++$active_forms; + } + + $selected_list = self::get_selected_list( $cf7_mch ); + + if ( ! empty( $selected_list ) && isset( $unique_audiences[ $selected_list ] ) ) { + $unique_audiences[ $selected_list ]['is_paired'] = true; + $paired_lists[ $selected_list ] = true; + } + + $audience_count = 0; + $has_list = false; + if ( isset( $cf7_mch['lisdata']['lists'] ) && is_array( $cf7_mch['lisdata']['lists'] ) ) { + $audience_count = count( $cf7_mch['lisdata']['lists'] ); + $has_list = $audience_count > 0; + $total_lists += $audience_count; + if ( $has_list ) { + ++$forms_with_lists; + } + } + + $form_fields = $form->scan_form_tags(); + $total_fields += count( $form_fields ); + + $form_field_details = self::extract_field_details( $form_fields, $field_type_counts ); + + list( $form_mappings, $unmapped_cf7, $unmapped_mc, $mapped_cf7_fields, $form_mc_fields, $form_total_mappings ) = + self::extract_mappings( $cf7_mch, $form_field_details ); + + $total_mc_fields += $form_mc_fields; + $total_mappings += $form_total_mappings; + + $form_features = self::extract_form_features( $cf7_mch ); + + if ( count( $forms_detail ) < 50 ) { + $forms_detail[] = array( + 'form_id' => hash( 'sha256', (string) $form_id ), + 'field_count' => count( $form_field_details ), + 'fields' => $form_field_details, + 'paired_audience_id' => ! empty( $selected_list ) ? hash( 'sha256', $selected_list ) : null, + 'mappings' => $form_mappings, + 'unmapped_cf7_fields' => $unmapped_cf7, + 'unmapped_mc_fields' => $unmapped_mc, + 'features' => $form_features, + ); + } + + $forms_data[] = array( + 'form_id' => hash( 'sha256', (string) $form_id ), + 'has_api' => ! empty( $cf7_mch['api'] ), + 'has_list' => $has_list, + 'audience_count' => $audience_count, + 'field_count' => count( $form_fields ), + 'has_double_opt' => isset( $cf7_mch['confsubs'] ) && '1' === $cf7_mch['confsubs'], + 'has_consent' => ! empty( $cf7_mch['accept'] ) && ' ' !== $cf7_mch['accept'], + 'submissions' => (int) ( $form_options[ $form_id ]['submissions'] ?? 0 ), + 'last_submission' => (int) ( $form_options[ $form_id ]['last_submission'] ?? 0 ), + ); + } + + $avg_fields_per_form = $processed_forms > 0 ? round( $total_fields / $processed_forms, 2 ) : 0; + $avg_lists_per_form = $forms_with_lists > 0 ? round( $total_lists / $forms_with_lists, 2 ) : 0; + + list( $oldest_form, $newest_form ) = self::get_form_age_range( $cf7_forms ); + + $audience_data = array_values( $unique_audiences ); + $total_unique_audiences = count( $audience_data ); + $total_contacts = array_sum( array_column( $audience_data, 'member_count' ) ); + + return array( + 'total_forms' => $total_forms, + 'processed_forms' => $processed_forms, + 'active_forms' => $active_forms, + 'forms_with_api' => $forms_with_api, + 'forms_with_lists' => $forms_with_lists, + 'inactive_forms' => $processed_forms - $active_forms, + 'total_audiences' => $total_unique_audiences, + 'audiences' => $audience_data, + 'total_contacts' => $total_contacts, + 'avg_lists_per_form' => $avg_lists_per_form, + 'max_lists_per_form' => $total_lists > 0 ? max( array_column( $forms_data, 'audience_count' ) ) : 0, + 'total_fields_all_forms' => $total_fields, + 'avg_fields_per_form' => $avg_fields_per_form, + 'min_fields_per_form' => $processed_forms > 0 ? min( array_column( $forms_data, 'field_count' ) ) : 0, + 'max_fields_per_form' => $processed_forms > 0 ? max( array_column( $forms_data, 'field_count' ) ) : 0, + 'oldest_form_created' => $oldest_form, + 'newest_form_created' => $newest_form, + 'days_since_oldest_form' => $oldest_form > 0 ? floor( ( time() - $oldest_form ) / DAY_IN_SECONDS ) : 0, + 'days_since_newest_form' => $newest_form > 0 ? floor( ( time() - $newest_form ) / DAY_IN_SECONDS ) : 0, + 'forms_with_submissions' => count( array_filter( $forms_data, fn( $f ) => $f['submissions'] > 0 ) ), + 'forms_never_submitted' => count( array_filter( $forms_data, fn( $f ) => 0 === $f['submissions'] ) ), + 'forms_with_double_opt' => count( array_filter( $forms_data, fn( $f ) => $f['has_double_opt'] ) ), + 'forms_with_consent' => count( array_filter( $forms_data, fn( $f ) => $f['has_consent'] ) ), + 'total_submissions_all_forms' => array_sum( array_column( $forms_data, 'submissions' ) ), + 'form_utilization_rate' => $processed_forms > 0 ? round( ( $active_forms / $processed_forms ) * 100, 2 ) : 0, + 'forms_detail' => $forms_detail, + 'forms_truncated' => $forms_truncated, + 'forms_detail_truncated' => $processed_forms > 50, + 'field_types_aggregate' => $field_type_counts, + 'mapping_stats' => array( + 'total_cf7_fields' => $total_fields, + 'total_mc_fields' => $total_mc_fields, + 'mapped_fields' => $total_mappings, + 'mapping_rate' => $total_fields > 0 ? round( ( $total_mappings / $total_fields ) * 100, 2 ) : 0, + ), + ); + } + + public static function get_cf7_forms(): array { + if ( ! class_exists( 'WPCF7_ContactForm' ) ) { + return array(); + } + + $post_ids = get_posts( + array( + 'post_type' => 'wpcf7_contact_form', + 'posts_per_page' => self::MAX_FORMS, + 'post_status' => 'publish', + 'fields' => 'ids', + 'orderby' => 'modified', + 'order' => 'DESC', + ) + ); + + $forms = array(); + foreach ( $post_ids as $post_id ) { + $form = \WPCF7_ContactForm::get_instance( $post_id ); + if ( $form ) { + $forms[] = $form; + } + } + + return $forms; + } + + public static function get_total_form_count(): int { + if ( ! class_exists( 'WPCF7_ContactForm' ) ) { + return 0; + } + + global $wpdb; + + return (int) $wpdb->get_var( + "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = 'wpcf7_contact_form' AND post_status = 'publish'" + ); + } + + public static function batch_load_form_options( array $form_ids ): array { + global $wpdb; + + if ( empty( $form_ids ) ) { + return array(); + } + + $option_names = array(); + foreach ( $form_ids as $form_id ) { + $option_names[] = 'cf7_mch_' . $form_id; + $option_names[] = 'cf7_mch_submissions_' . $form_id; + $option_names[] = 'cf7_mch_last_submission_' . $form_id; + } + + $placeholders = implode( ', ', array_fill( 0, count( $option_names ), '%s' ) ); + $query = $wpdb->prepare( + "SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name IN ({$placeholders})", + ...$option_names + ); + + $results = $wpdb->get_results( $query, ARRAY_A ); + + $options_map = array(); + foreach ( $results as $row ) { + $options_map[ $row['option_name'] ] = maybe_unserialize( $row['option_value'] ); + } + + $form_options = array(); + foreach ( $form_ids as $form_id ) { + $form_options[ $form_id ] = array( + 'settings' => $options_map[ 'cf7_mch_' . $form_id ] ?? array(), + 'submissions' => $options_map[ 'cf7_mch_submissions_' . $form_id ] ?? 0, + 'last_submission' => $options_map[ 'cf7_mch_last_submission_' . $form_id ] ?? 0, + ); + } + + return $form_options; + } + + private static function build_audiences_from_global(): array { + $unique_audiences = array(); + $global_lisdata = Cmatic_Options_Repository::get_option( 'lisdata', array() ); + + if ( ! empty( $global_lisdata['lists'] ) && is_array( $global_lisdata['lists'] ) ) { + foreach ( $global_lisdata['lists'] as $list ) { + $list_id = $list['id'] ?? ''; + if ( empty( $list_id ) ) { + continue; + } + + $unique_audiences[ $list_id ] = array( + 'audience_id' => hash( 'sha256', $list_id ), + 'member_count' => (int) ( $list['stats']['member_count'] ?? 0 ), + 'merge_field_count' => (int) ( $list['stats']['merge_field_count'] ?? 0 ), + 'double_optin' => ! empty( $list['double_optin'] ), + 'marketing_permissions' => ! empty( $list['marketing_permissions'] ), + 'campaign_count' => (int) ( $list['stats']['campaign_count'] ?? 0 ), + 'is_paired' => false, + ); + } + } + + return $unique_audiences; + } + + private static function get_selected_list( array $cf7_mch ): string { + $selected_list = $cf7_mch['list'] ?? ''; + if ( is_array( $selected_list ) ) { + $selected_list = $selected_list[0] ?? ''; + } + return $selected_list; + } + + private static function extract_field_details( array $form_fields, array &$field_type_counts ): array { + $form_field_details = array(); + $form_field_limit = 30; + + foreach ( $form_fields as $ff_index => $tag ) { + if ( $ff_index >= $form_field_limit ) { + break; + } + + $basetype = ''; + if ( is_object( $tag ) && isset( $tag->basetype ) ) { + $basetype = $tag->basetype; + } elseif ( is_array( $tag ) && isset( $tag['basetype'] ) ) { + $basetype = $tag['basetype']; + } + + $field_name = ''; + if ( is_object( $tag ) && isset( $tag->name ) ) { + $field_name = $tag->name; + } elseif ( is_array( $tag ) && isset( $tag['name'] ) ) { + $field_name = $tag['name']; + } + + if ( ! empty( $field_name ) && ! empty( $basetype ) ) { + $form_field_details[] = array( + 'name' => $field_name, + 'type' => $basetype, + ); + + if ( ! isset( $field_type_counts[ $basetype ] ) ) { + $field_type_counts[ $basetype ] = 0; + } + ++$field_type_counts[ $basetype ]; + } + } + + return $form_field_details; + } + + private static function extract_mappings( array $cf7_mch, array $form_field_details ): array { + $form_mappings = array(); + $unmapped_cf7 = 0; + $unmapped_mc = 0; + $mapped_cf7_fields = array(); + $total_mc_fields = 0; + $total_mappings = 0; + + for ( $i = 1; $i <= 20; $i++ ) { + $mc_tag = $cf7_mch[ 'CustomKey' . $i ] ?? ''; + $mc_type = $cf7_mch[ 'CustomKeyType' . $i ] ?? ''; + $cf7_field = trim( $cf7_mch[ 'CustomValue' . $i ] ?? '' ); + + if ( ! empty( $mc_tag ) ) { + ++$total_mc_fields; + if ( '' !== $cf7_field ) { + $form_mappings[] = array( + 'cf7_field' => $cf7_field, + 'mc_tag' => $mc_tag, + 'mc_type' => $mc_type, + ); + $mapped_cf7_fields[] = $cf7_field; + ++$total_mappings; + } else { + ++$unmapped_mc; + } + } + } + + foreach ( $form_field_details as $field ) { + if ( ! in_array( $field['name'], $mapped_cf7_fields, true ) ) { + ++$unmapped_cf7; + } + } + + return array( $form_mappings, $unmapped_cf7, $unmapped_mc, $mapped_cf7_fields, $total_mc_fields, $total_mappings ); + } + + private static function extract_form_features( array $cf7_mch ): array { + $form_features = array(); + + if ( isset( $cf7_mch['confsubs'] ) && '1' === $cf7_mch['confsubs'] ) { + $form_features['double_optin'] = true; + } + + if ( ! empty( $cf7_mch['consent_required'] ) && ' ' !== $cf7_mch['consent_required'] ) { + $form_features['required_consent'] = true; + } + + if ( isset( $cf7_mch['logfileEnabled'] ) && '1' === $cf7_mch['logfileEnabled'] ) { + $form_features['debug_logger'] = true; + } + + if ( ! empty( $cf7_mch['labeltags'] ) && is_array( $cf7_mch['labeltags'] ) ) { + $enabled_tags = array_filter( $cf7_mch['labeltags'], fn( $v ) => '1' === $v ); + if ( count( $enabled_tags ) > 0 ) { + $form_features['tags_enabled'] = true; + } + } + + $form_group_count = 0; + for ( $gi = 1; $gi <= 20; $gi++ ) { + $gkey = $cf7_mch[ "ggCustomKey{$gi}" ] ?? ''; + $gvalue = $cf7_mch[ "ggCustomValue{$gi}" ] ?? ''; + if ( ! empty( $gkey ) && ! empty( trim( $gvalue ) ) && ' ' !== $gvalue ) { + ++$form_group_count; + } + } + if ( $form_group_count > 0 ) { + $form_features['interest_groups'] = true; + } + + $form_merge_fields_raw = array(); + if ( ! empty( $cf7_mch['merge_fields'] ) && is_array( $cf7_mch['merge_fields'] ) ) { + $form_merge_fields_raw = $cf7_mch['merge_fields']; + } elseif ( ! empty( $cf7_mch['merge-vars'] ) && is_array( $cf7_mch['merge-vars'] ) ) { + $form_merge_fields_raw = $cf7_mch['merge-vars']; + } + + if ( ! empty( $form_merge_fields_raw ) ) { + $default_tags = array( 'EMAIL', 'FNAME', 'LNAME', 'ADDRESS', 'PHONE' ); + $custom_field_count = 0; + foreach ( $form_merge_fields_raw as $mfield ) { + if ( isset( $mfield['tag'] ) && ! in_array( $mfield['tag'], $default_tags, true ) ) { + ++$custom_field_count; + } + } + if ( $custom_field_count > 0 ) { + $form_features['custom_merge_fields'] = true; + } + } + + if ( ! empty( $cf7_mch['conditional_logic'] ) ) { + $form_features['conditional_logic'] = true; + } + + return $form_features; + } + + private static function get_form_age_range( array $cf7_forms ): array { + $oldest_form = 0; + $newest_form = 0; + + foreach ( $cf7_forms as $form ) { + $created = get_post_field( 'post_date', $form->id(), 'raw' ); + $timestamp = strtotime( $created ); + + if ( 0 === $oldest_form || $timestamp < $oldest_form ) { + $oldest_form = $timestamp; + } + if ( 0 === $newest_form || $timestamp > $newest_form ) { + $newest_form = $timestamp; + } + } + + return array( $oldest_form, $newest_form ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Install_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Install_Collector.php new file mode 100644 index 0000000..0ac7c50 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Install_Collector.php @@ -0,0 +1,32 @@ + Cmatic_Options_Repository::get_option( 'install.plugin_slug', 'contact-form-7-mailchimp-extension' ), + 'quest' => Storage::get_quest(), + 'pro' => array( + 'installed' => (bool) Cmatic_Options_Repository::get_option( 'install.pro.installed', false ), + 'activated' => (bool) Cmatic_Options_Repository::get_option( 'install.pro.activated', false ), + 'version' => Cmatic_Options_Repository::get_option( 'install.pro.version', null ), + 'licensed' => (bool) Cmatic_Options_Repository::get_option( 'install.pro.licensed', false ), + 'license_expires' => Cmatic_Options_Repository::get_option( 'install.pro.license_expires', null ), + ), + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Lifecycle_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Lifecycle_Collector.php new file mode 100644 index 0000000..70b582c --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Lifecycle_Collector.php @@ -0,0 +1,90 @@ + 0 ) { + $days_since_first = floor( ( time() - $first_activated ) / DAY_IN_SECONDS ); + } + + $avg_session_length = self::calculate_avg_session_length( $activations, $deactivations ); + + $version_history = Cmatic_Options_Repository::get_option( 'lifecycle.version_history', array() ); + $previous_version = Cmatic_Options_Repository::get_option( 'lifecycle.previous_version', '' ); + $days_since_last_upgrade = $last_upgrade > 0 ? floor( ( time() - $last_upgrade ) / DAY_IN_SECONDS ) : 0; + + $active_session = empty( $deactivations ) || $last_activated > $last_deactivated; + + $data = array( + 'activation_count' => count( $activations ), + 'deactivation_count' => count( $deactivations ), + 'upgrade_count' => count( $upgrades ), + 'first_activated' => $first_activated, + 'last_activated' => $last_activated, + 'last_deactivated' => $last_deactivated, + 'last_upgrade' => $last_upgrade, + 'days_since_first_activation' => (int) $days_since_first, + 'days_since_last_upgrade' => (int) $days_since_last_upgrade, + 'avg_session_length_seconds' => $avg_session_length, + 'total_sessions' => count( $activations ), + 'previous_version' => $previous_version, + 'version_history_count' => count( $version_history ), + 'install_method' => Cmatic_Options_Repository::get_option( 'lifecycle.install_method', 'unknown' ), + 'days_on_current_version' => $last_upgrade > 0 ? floor( ( time() - $last_upgrade ) / DAY_IN_SECONDS ) : $days_since_first, + 'activation_timestamps' => $activations, + 'deactivation_timestamps' => $deactivations, + 'upgrade_timestamps' => $upgrades, + ); + + $data = array_filter( $data, fn( $v ) => $v !== 0 && $v !== '' && $v !== 'unknown' ); + $data['active_session'] = $active_session; + + return $data; + } + + private static function calculate_avg_session_length( array $activations, array $deactivations ): int { + if ( count( $activations ) === 0 || count( $deactivations ) === 0 ) { + return 0; + } + + $total_session_time = 0; + $session_count = 0; + + foreach ( $activations as $index => $activation_time ) { + if ( isset( $deactivations[ $index ] ) ) { + $total_session_time += $deactivations[ $index ] - $activation_time; + ++$session_count; + } + } + + if ( $session_count > 0 ) { + return (int) floor( $total_session_time / $session_count ); + } + + return 0; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Metadata_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Metadata_Collector.php new file mode 100644 index 0000000..94b678a --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Metadata_Collector.php @@ -0,0 +1,36 @@ + 0 ? time() - $first_installed : 0; + $failed_count = (int) Cmatic_Options_Repository::get_option( 'telemetry.failed_count', 0 ); + + return array( + 'schedule' => Cmatic_Options_Repository::get_option( 'telemetry.schedule', 'frequent' ), + 'frequent_started_at' => (int) Cmatic_Options_Repository::get_option( 'telemetry.frequent_started_at', 0 ), + 'is_reactivation' => Storage::is_reactivation(), + 'disabled_count' => (int) Cmatic_Options_Repository::get_option( 'telemetry.disabled_count', 0 ), + 'opt_in_date' => (int) Cmatic_Options_Repository::get_option( 'telemetry.opt_in_date', 0 ), + 'last_heartbeat' => (int) Cmatic_Options_Repository::get_option( 'telemetry.last_heartbeat', 0 ), + 'failed_heartbeats' => $failed_count, + 'total_uptime_seconds' => $total_uptime, + 'telemetry_version' => SPARTAN_MCE_VERSION, + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Performance_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Performance_Collector.php new file mode 100644 index 0000000..a112e19 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Performance_Collector.php @@ -0,0 +1,140 @@ + 0 ? round( ( $memory_peak / $memory_limit_bytes ) * 100, 2 ) : 0; + + $db_queries = get_num_queries(); + $db_time = timer_stop( 0, 3 ); + + $page_load_time = isset( $_SERVER['REQUEST_TIME_FLOAT'] ) ? ( microtime( true ) - floatval( $_SERVER['REQUEST_TIME_FLOAT'] ) ) * 1000 : 0; + + list( $object_cache_hits, $object_cache_misses ) = self::get_object_cache_stats(); + + $plugin_load_time = (float) Cmatic_Options_Repository::get_option( 'performance.plugin_load_time', 0 ); + $api_avg_response = (float) Cmatic_Options_Repository::get_option( 'performance.api_avg_response', 0 ); + + $data = array( + 'memory_current' => $memory_current, + 'memory_peak' => $memory_peak, + 'memory_limit' => $memory_limit, + 'memory_limit_bytes' => $memory_limit_bytes, + 'memory_usage_percent' => $memory_usage_percent, + 'memory_available' => max( 0, $memory_limit_bytes - $memory_peak ), + 'php_max_execution_time' => (int) ini_get( 'max_execution_time' ), + 'page_load_time_ms' => round( $page_load_time, 2 ), + 'plugin_load_time_ms' => round( $plugin_load_time, 2 ), + 'db_queries_count' => $db_queries, + 'db_query_time_seconds' => (float) $db_time, + 'db_size_mb' => self::get_database_size(), + 'api_avg_response_ms' => round( $api_avg_response, 2 ), + 'api_slowest_response_ms' => (int) Cmatic_Options_Repository::get_option( 'performance.api_slowest', 0 ), + 'api_fastest_response_ms' => (int) Cmatic_Options_Repository::get_option( 'performance.api_fastest', 0 ), + 'object_cache_enabled' => wp_using_ext_object_cache(), + 'object_cache_hits' => $object_cache_hits, + 'object_cache_misses' => $object_cache_misses, + 'object_cache_hit_rate' => ( $object_cache_hits + $object_cache_misses ) > 0 ? round( ( $object_cache_hits / ( $object_cache_hits + $object_cache_misses ) ) * 100, 2 ) : 0, + 'opcache_enabled' => self::is_opcache_enabled(), + 'opcache_hit_rate' => self::get_opcache_hit_rate(), + ); + + return array_filter( $data, fn( $v ) => $v !== 0 && $v !== 0.0 && $v !== false && $v !== null && $v !== '' ); + } + + private static function is_opcache_enabled(): bool { + if ( ! function_exists( 'opcache_get_status' ) ) { + return false; + } + $status = @opcache_get_status(); + return false !== $status && is_array( $status ); + } + + public static function convert_to_bytes( $value ): int { + $value = trim( $value ); + if ( empty( $value ) ) { + return 0; + } + $last = strtolower( $value[ strlen( $value ) - 1 ] ); + $value = (int) $value; + + switch ( $last ) { + case 'g': + $value *= 1024; + // Fall through. + case 'm': + $value *= 1024; + // Fall through. + case 'k': + $value *= 1024; + } + + return $value; + } + + private static function get_database_size(): float { + global $wpdb; + + $size = $wpdb->get_var( + $wpdb->prepare( + 'SELECT SUM(data_length + index_length) / 1024 / 1024 + FROM information_schema.TABLES + WHERE table_schema = %s', + DB_NAME + ) + ); + + return round( (float) $size, 2 ); + } + + private static function get_opcache_hit_rate(): float { + if ( ! function_exists( 'opcache_get_status' ) ) { + return 0; + } + + $status = @opcache_get_status(); + if ( false === $status || ! is_array( $status ) || ! isset( $status['opcache_statistics'] ) ) { + return 0; + } + + $stats = $status['opcache_statistics']; + $hits = isset( $stats['hits'] ) ? (int) $stats['hits'] : 0; + $misses = isset( $stats['misses'] ) ? (int) $stats['misses'] : 0; + + if ( ( $hits + $misses ) === 0 ) { + return 0; + } + + return round( ( $hits / ( $hits + $misses ) ) * 100, 2 ); + } + + private static function get_object_cache_stats(): array { + $object_cache_hits = 0; + $object_cache_misses = 0; + + if ( function_exists( 'wp_cache_get_stats' ) ) { + $cache_stats = wp_cache_get_stats(); + $object_cache_hits = isset( $cache_stats['hits'] ) ? $cache_stats['hits'] : 0; + $object_cache_misses = isset( $cache_stats['misses'] ) ? $cache_stats['misses'] : 0; + } + + return array( $object_cache_hits, $object_cache_misses ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Plugins_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Plugins_Collector.php new file mode 100644 index 0000000..15ff89f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Plugins_Collector.php @@ -0,0 +1,135 @@ + count( $all_plugins ), + 'active_plugins' => count( $active_plugins ), + 'inactive_plugins' => count( $all_plugins ) - count( $active_plugins ), + 'mu_plugins' => count( $mu_plugins ), + 'premium_plugins' => $plugin_stats['premium'], + 'cf7_addons' => $plugin_stats['cf7'], + 'mailchimp_plugins' => $plugin_stats['mailchimp'], + 'security_plugins' => $plugin_stats['security'], + 'cache_plugins' => $plugin_stats['cache'], + 'seo_plugins' => $plugin_stats['seo'], + 'has_woocommerce' => $known_plugins['woocommerce'], + 'has_elementor' => $known_plugins['elementor'], + 'has_jetpack' => $known_plugins['jetpack'], + 'has_wordfence' => $known_plugins['wordfence'], + 'has_yoast_seo' => $known_plugins['yoast_seo'], + 'plugin_list' => $plugin_list, + ); + + return array_filter( $data, fn( $v ) => $v !== 0 && $v !== false && $v !== '' && $v !== array() ); + } + + private static function build_plugin_list( array $all_plugins, array $active_plugins, array $mu_plugins ): array { + $plugin_list = array(); + $network_active = is_multisite() ? get_site_option( 'active_sitewide_plugins', array() ) : array(); + + foreach ( $all_plugins as $plugin_path => $plugin_data ) { + $is_active = in_array( $plugin_path, $active_plugins, true ); + $is_network = isset( $network_active[ $plugin_path ] ); + + $status = 'inactive'; + if ( $is_network ) { + $status = 'network-active'; + } elseif ( $is_active ) { + $status = 'active'; + } + + $dir = dirname( $plugin_path ); + + $plugin_list[] = array( + 'slug' => '.' !== $dir ? $dir : basename( $plugin_path, '.php' ), + 'name' => $plugin_data['Name'], + 'version' => $plugin_data['Version'], + 'author' => wp_strip_all_tags( $plugin_data['Author'] ), + 'status' => $status, + ); + } + + foreach ( $mu_plugins as $mu_plugin_path => $mu_plugin_data ) { + $plugin_list[] = array( + 'slug' => basename( $mu_plugin_path, '.php' ), + 'name' => $mu_plugin_data['Name'], + 'version' => $mu_plugin_data['Version'], + 'author' => wp_strip_all_tags( $mu_plugin_data['Author'] ), + 'status' => 'mu-plugin', + ); + } + + return $plugin_list; + } + + private static function get_plugin_stats( array $all_plugins ): array { + $stats = array( + 'premium' => 0, + 'cf7' => 0, + 'mailchimp' => 0, + 'security' => 0, + 'cache' => 0, + 'seo' => 0, + ); + + foreach ( $all_plugins as $plugin_path => $plugin_data ) { + $name = strtolower( $plugin_data['Name'] ); + + if ( strpos( $name, 'pro' ) !== false || strpos( $name, 'premium' ) !== false ) { + ++$stats['premium']; + } + if ( strpos( $name, 'contact form 7' ) !== false ) { + ++$stats['cf7']; + } + if ( strpos( $name, 'mailchimp' ) !== false ) { + ++$stats['mailchimp']; + } + if ( strpos( $name, 'security' ) !== false || strpos( $name, 'wordfence' ) !== false || strpos( $name, 'sucuri' ) !== false ) { + ++$stats['security']; + } + if ( strpos( $name, 'cache' ) !== false || strpos( $name, 'wp rocket' ) !== false || strpos( $name, 'w3 total cache' ) !== false ) { + ++$stats['cache']; + } + if ( strpos( $name, 'seo' ) !== false || strpos( $name, 'yoast' ) !== false ) { + ++$stats['seo']; + } + } + + return $stats; + } + + private static function get_known_plugins(): array { + return array( + 'woocommerce' => is_plugin_active( 'woocommerce/woocommerce.php' ), + 'elementor' => is_plugin_active( 'elementor/elementor.php' ), + 'jetpack' => is_plugin_active( 'jetpack/jetpack.php' ), + 'wordfence' => is_plugin_active( 'wordfence/wordfence.php' ), + 'yoast_seo' => is_plugin_active( 'wordpress-seo/wp-seo.php' ), + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Server_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Server_Collector.php new file mode 100644 index 0000000..a14ebde --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Server_Collector.php @@ -0,0 +1,90 @@ + 0 ? round( ( $disk_used / $disk_total ) * 100, 2 ) : 0; + + $hostname = self::get_hostname(); + $architecture = self::get_architecture(); + + return array( + 'load_average_1min' => isset( $server_load[0] ) ? round( (float) $server_load[0], 2 ) : 0, + 'load_average_5min' => isset( $server_load[1] ) ? round( (float) $server_load[1], 2 ) : 0, + 'load_average_15min' => isset( $server_load[2] ) ? round( (float) $server_load[2], 2 ) : 0, + 'disk_usage_percent' => $disk_usage_percent, + 'disk_total_gb' => $disk_total ? round( $disk_total / 1024 / 1024 / 1024, 2 ) : 0, + 'server_ip' => hash( 'sha256', isset( $_SERVER['SERVER_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_ADDR'] ) ) : '' ), + 'server_hostname' => hash( 'sha256', $hostname ), + 'server_os' => PHP_OS, + 'server_architecture' => $architecture, + ); + } + + private static function get_load_average(): array { + if ( ! function_exists( 'sys_getloadavg' ) ) { + return array( 0, 0, 0 ); + } + + $load = @sys_getloadavg(); + if ( false !== $load && is_array( $load ) ) { + return $load; + } + + return array( 0, 0, 0 ); + } + + private static function get_disk_space(): array { + $disk_free = 0; + $disk_total = 0; + + if ( function_exists( 'disk_free_space' ) ) { + $free = @disk_free_space( ABSPATH ); + if ( false !== $free ) { + $disk_free = $free; + } + } + + if ( function_exists( 'disk_total_space' ) ) { + $total = @disk_total_space( ABSPATH ); + if ( false !== $total ) { + $disk_total = $total; + } + } + + return array( $disk_free, $disk_total ); + } + + private static function get_hostname(): string { + if ( ! function_exists( 'gethostname' ) ) { + return ''; + } + + $name = @gethostname(); + return false !== $name ? $name : ''; + } + + private static function get_architecture(): string { + if ( ! function_exists( 'php_uname' ) ) { + return ''; + } + + $arch = @php_uname( 'm' ); + return false !== $arch ? $arch : ''; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Submissions_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Submissions_Collector.php new file mode 100644 index 0000000..a9eee99 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/Submissions_Collector.php @@ -0,0 +1,116 @@ + 0 ) { + $days_active = max( 1, floor( ( time() - $first_activated ) / DAY_IN_SECONDS ) ); + } + + $total_submissions = $total_sent + $total_failed; + $avg_per_day = $days_active > 0 ? round( $total_submissions / $days_active, 2 ) : 0; + $success_rate = $total_submissions > 0 ? round( ( $total_sent / $total_submissions ) * 100, 2 ) : 100; + + $days_since_first = $first_submission > 0 ? floor( ( time() - $first_submission ) / DAY_IN_SECONDS ) : 0; + $days_since_last = $last_submission > 0 ? floor( ( time() - $last_submission ) / DAY_IN_SECONDS ) : 0; + $hours_since_last = $last_submission > 0 ? floor( ( time() - $last_submission ) / HOUR_IN_SECONDS ) : 0; + + list( $busiest_hour, $max_submissions ) = self::get_busiest_hour(); + list( $busiest_day, $max_day_submissions ) = self::get_busiest_day(); + + $this_month = (int) Cmatic_Options_Repository::get_option( 'submissions.this_month', 0 ); + $last_month = (int) Cmatic_Options_Repository::get_option( 'submissions.last_month', 0 ); + $peak_month = (int) Cmatic_Options_Repository::get_option( 'submissions.peak_month', 0 ); + + $consecutive_successes = (int) Cmatic_Options_Repository::get_option( 'submissions.consecutive_successes', 0 ); + $consecutive_failures = (int) Cmatic_Options_Repository::get_option( 'submissions.consecutive_failures', 0 ); + + $data = array( + 'total_sent' => $total_sent, + 'total_failed' => $total_failed, + 'total_submissions' => $total_submissions, + 'successful_submissions_count' => $total_sent, + 'failed_count' => $total_failed, + 'success_rate' => $success_rate, + 'first_submission' => $first_submission, + 'last_submission' => $last_submission, + 'last_success' => $last_success, + 'last_failure' => $last_failure, + 'days_since_first' => $days_since_first, + 'days_since_last' => $days_since_last, + 'hours_since_last' => $hours_since_last, + 'avg_per_day' => $avg_per_day, + 'avg_per_week' => round( $avg_per_day * 7, 2 ), + 'avg_per_month' => round( $avg_per_day * 30, 2 ), + 'busiest_hour' => $busiest_hour, + 'busiest_day' => $busiest_day, + 'submissions_busiest_hour' => $max_submissions, + 'submissions_busiest_day' => $max_day_submissions, + 'this_month' => $this_month, + 'last_month' => $last_month, + 'peak_month' => $peak_month, + 'month_over_month_change' => $last_month > 0 ? round( ( ( $this_month - $last_month ) / $last_month ) * 100, 2 ) : 0, + 'consecutive_successes' => $consecutive_successes, + 'consecutive_failures' => $consecutive_failures, + 'longest_success_streak' => (int) Cmatic_Options_Repository::get_option( 'submissions.longest_success_streak', 0 ), + 'active_forms_count' => (int) Cmatic_Options_Repository::get_option( 'submissions.active_forms', 0 ), + 'forms_with_submissions' => count( Cmatic_Options_Repository::get_option( 'submissions.forms_used', array() ) ), + ); + + return array_filter( $data, fn( $v ) => $v !== 0 && $v !== 0.0 ); + } + + private static function get_busiest_hour(): array { + $hourly_distribution = Cmatic_Options_Repository::get_option( 'submissions.hourly', array() ); + $busiest_hour = 0; + $max_submissions = 0; + + foreach ( $hourly_distribution as $hour => $count ) { + if ( $count > $max_submissions ) { + $max_submissions = $count; + $busiest_hour = (int) $hour; + } + } + + return array( $busiest_hour, $max_submissions ); + } + + private static function get_busiest_day(): array { + $daily_distribution = Cmatic_Options_Repository::get_option( 'submissions.daily', array() ); + $busiest_day = 0; + $max_day_submissions = 0; + + foreach ( $daily_distribution as $day => $count ) { + if ( $count > $max_day_submissions ) { + $max_day_submissions = $count; + $busiest_day = (int) $day; + } + } + + return array( $busiest_day, $max_day_submissions ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/WordPress_Collector.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/WordPress_Collector.php new file mode 100644 index 0000000..71b81c6 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Collectors/WordPress_Collector.php @@ -0,0 +1,50 @@ +get_var( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = 'revision'" ); + + $data = array( + 'posts_published' => isset( $post_counts->publish ) ? (int) $post_counts->publish : 0, + 'posts_draft' => isset( $post_counts->draft ) ? (int) $post_counts->draft : 0, + 'pages_published' => isset( $page_counts->publish ) ? (int) $page_counts->publish : 0, + 'media_items' => isset( $media_counts->inherit ) ? (int) $media_counts->inherit : 0, + 'comments_pending' => isset( $comment_counts->moderated ) ? (int) $comment_counts->moderated : 0, + 'comments_spam' => isset( $comment_counts->spam ) ? (int) $comment_counts->spam : 0, + 'users_total' => isset( $user_count['total_users'] ) ? (int) $user_count['total_users'] : 0, + 'users_administrators' => isset( $user_count['avail_roles']['administrator'] ) ? (int) $user_count['avail_roles']['administrator'] : 0, + 'users_editors' => isset( $user_count['avail_roles']['editor'] ) ? (int) $user_count['avail_roles']['editor'] : 0, + 'users_authors' => isset( $user_count['avail_roles']['author'] ) ? (int) $user_count['avail_roles']['author'] : 0, + 'users_subscribers' => isset( $user_count['avail_roles']['subscriber'] ) ? (int) $user_count['avail_roles']['subscriber'] : 0, + 'categories_count' => is_wp_error( $category_count ) ? 0 : (int) $category_count, + 'tags_count' => is_wp_error( $tag_count ) ? 0 : (int) $tag_count, + 'revisions_count' => (int) $revision_count, + ); + + $data = array_filter( $data, fn( $v ) => $v !== 0 ); + $data['auto_updates_enabled'] = (bool) get_option( 'auto_update_plugins', false ); + + return $data; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Scheduler.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Scheduler.php new file mode 100644 index 0000000..168ac7c --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Scheduler.php @@ -0,0 +1,184 @@ + 2 * MINUTE_IN_SECONDS, + 'display' => 'Every 2 Minutes', + ); + + $schedules['cmatic_10min'] = array( + 'interval' => 10 * MINUTE_IN_SECONDS, + 'display' => 'Every 10 Minutes', + ); + + $interval_hours = Storage::get_heartbeat_interval(); + $schedules['cmatic_sparse'] = array( + 'interval' => $interval_hours * HOUR_IN_SECONDS, + 'display' => 'Every ' . $interval_hours . ' Hours', + ); + + return $schedules; + } + + public static function execute_heartbeat() { + if ( ! Storage::is_enabled() ) { + return; + } + $schedule = Storage::get_schedule(); + $started_at = Storage::get_frequent_started_at(); + $elapsed = $started_at > 0 ? time() - $started_at : 0; + + if ( 'super_frequent' === $schedule && $elapsed >= ( 15 * MINUTE_IN_SECONDS ) ) { + self::transition_to_frequent(); + } elseif ( 'frequent' === $schedule && $elapsed >= ( 1 * HOUR_IN_SECONDS ) ) { + self::transition_to_sparse(); + } + + self::sync_global_lisdata(); + $payload = Collector::collect( 'heartbeat' ); + Sync::send( $payload ); + } + + private static function transition_to_frequent() { + Storage::set_schedule( 'frequent' ); + + $timestamp = wp_next_scheduled( 'cmatic_metrics_heartbeat' ); + if ( $timestamp ) { + wp_unschedule_event( $timestamp, 'cmatic_metrics_heartbeat' ); + } + + wp_schedule_event( time(), 'cmatic_10min', 'cmatic_metrics_heartbeat' ); + } + + private static function transition_to_sparse() { + Storage::set_schedule( 'sparse' ); + + $timestamp = wp_next_scheduled( 'cmatic_metrics_heartbeat' ); + if ( $timestamp ) { + wp_unschedule_event( $timestamp, 'cmatic_metrics_heartbeat' ); + } + + $interval_hours = Storage::get_heartbeat_interval(); + wp_schedule_single_event( + time() + ( $interval_hours * HOUR_IN_SECONDS ), + 'cmatic_metrics_heartbeat' + ); + } + + public static function ensure_schedule() { + if ( ! Storage::is_enabled() ) { + return; + } + + if ( wp_next_scheduled( 'cmatic_metrics_heartbeat' ) ) { + return; + } + + $schedule = Storage::get_schedule(); + $started_at = Storage::get_frequent_started_at(); + $elapsed = $started_at > 0 ? time() - $started_at : 0; + + if ( 'super_frequent' === $schedule ) { + if ( $elapsed >= ( 15 * MINUTE_IN_SECONDS ) ) { + self::transition_to_frequent(); + } else { + wp_schedule_event( time(), 'cmatic_2min', 'cmatic_metrics_heartbeat' ); + } + } elseif ( 'frequent' === $schedule ) { + if ( Storage::is_frequent_elapsed() ) { + self::transition_to_sparse(); + } else { + wp_schedule_event( time(), 'cmatic_10min', 'cmatic_metrics_heartbeat' ); + } + } else { + $interval_hours = Storage::get_heartbeat_interval(); + $last_heartbeat = Storage::get_last_heartbeat(); + $next_heartbeat = $last_heartbeat + ( $interval_hours * HOUR_IN_SECONDS ); + + if ( $next_heartbeat < time() ) { + $next_heartbeat = time(); + } + + wp_schedule_single_event( $next_heartbeat, 'cmatic_metrics_heartbeat' ); + } + } + + public static function schedule_next_sparse() { + if ( 'sparse' !== Storage::get_schedule() ) { + return; + } + + $timestamp = wp_next_scheduled( 'cmatic_metrics_heartbeat' ); + if ( $timestamp ) { + wp_unschedule_event( $timestamp, 'cmatic_metrics_heartbeat' ); + } + + $interval_hours = Storage::get_heartbeat_interval(); + wp_schedule_single_event( + time() + ( $interval_hours * HOUR_IN_SECONDS ), + 'cmatic_metrics_heartbeat' + ); + } + + public static function clear_schedule() { + $timestamp = wp_next_scheduled( 'cmatic_metrics_heartbeat' ); + if ( $timestamp ) { + wp_unschedule_event( $timestamp, 'cmatic_metrics_heartbeat' ); + } + } + + private static function sync_global_lisdata() { + global $wpdb; + $form_options = $wpdb->get_results( + "SELECT option_value FROM {$wpdb->options} + WHERE option_name LIKE 'cf7_mch_%' + AND option_value LIKE '%lisdata%' + LIMIT 50" + ); + + $best_lisdata = null; + $best_list_count = 0; + + if ( ! empty( $form_options ) ) { + foreach ( $form_options as $row ) { + $cf7_mch = maybe_unserialize( $row->option_value ); + if ( ! is_array( $cf7_mch ) || empty( $cf7_mch['lisdata']['lists'] ) ) { + continue; + } + + $list_count = count( $cf7_mch['lisdata']['lists'] ); + if ( $list_count > $best_list_count ) { + $best_list_count = $list_count; + $best_lisdata = $cf7_mch['lisdata']; + } + } + } + + // Always update - either with found data or empty array to clear stale data. + Cmatic_Options_Repository::set_option( 'lisdata', $best_lisdata ?? array() ); + Cmatic_Options_Repository::set_option( 'lisdata_updated', time() ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Storage.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Storage.php new file mode 100644 index 0000000..6c3c2a6 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Storage.php @@ -0,0 +1,151 @@ + true, + 'opt_in_date' => time(), + 'disabled_count' => 0, + 'heartbeat_interval' => 48, + 'schedule' => 'frequent', + 'frequent_started_at' => time(), + 'last_heartbeat' => 0, + 'heartbeat_count' => 0, + 'failed_count' => 0, + 'last_payload_hash' => '', + 'last_error' => '', + ); + + foreach ( $defaults as $key => $value ) { + Cmatic_Options_Repository::set_option( "telemetry.{$key}", $value ); + } + } + + public static function is_enabled() { + return (bool) Cmatic_Options_Repository::get_option( 'telemetry.enabled', true ); + } + + public static function get_schedule() { + return Cmatic_Options_Repository::get_option( 'telemetry.schedule', 'frequent' ); + } + + public static function set_schedule( $schedule ) { + Cmatic_Options_Repository::set_option( 'telemetry.schedule', $schedule ); + + if ( 'frequent' === $schedule ) { + Cmatic_Options_Repository::set_option( 'telemetry.frequent_started_at', time() ); + } + } + + public static function get_heartbeat_interval() { + return (int) Cmatic_Options_Repository::get_option( 'telemetry.heartbeat_interval', 48 ); + } + + public static function get_last_heartbeat() { + return (int) Cmatic_Options_Repository::get_option( 'telemetry.last_heartbeat', 0 ); + } + + public static function update_last_heartbeat( $timestamp = null ) { + if ( null === $timestamp ) { + $timestamp = time(); + } + Cmatic_Options_Repository::set_option( 'telemetry.last_heartbeat', $timestamp ); + } + + public static function increment_heartbeat_count() { + $count = (int) Cmatic_Options_Repository::get_option( 'telemetry.heartbeat_count', 0 ); + Cmatic_Options_Repository::set_option( 'telemetry.heartbeat_count', $count + 1 ); + } + + public static function increment_failed_count() { + $count = (int) Cmatic_Options_Repository::get_option( 'telemetry.failed_count', 0 ); + Cmatic_Options_Repository::set_option( 'telemetry.failed_count', $count + 1 ); + } + + public static function increment_disabled_count() { + $count = (int) Cmatic_Options_Repository::get_option( 'telemetry.disabled_count', 0 ); + Cmatic_Options_Repository::set_option( 'telemetry.disabled_count', $count + 1 ); + } + + public static function get_frequent_started_at() { + return (int) Cmatic_Options_Repository::get_option( 'telemetry.frequent_started_at', 0 ); + } + + public static function is_frequent_elapsed() { + $started_at = self::get_frequent_started_at(); + if ( 0 === $started_at ) { + return false; + } + $elapsed = time() - $started_at; + return $elapsed >= ( 1 * HOUR_IN_SECONDS ); + } + + public static function record_activation() { + } + + public static function record_deactivation() { + } + + public static function is_reactivation() { + return (bool) Cmatic_Options_Repository::get_option( 'lifecycle.is_reactivation', false ); + } + + public static function get_activation_count() { + $activations = Cmatic_Options_Repository::get_option( 'lifecycle.activations', array() ); + return is_array( $activations ) ? count( $activations ) : 0; + } + + public static function get_deactivation_count() { + $deactivations = Cmatic_Options_Repository::get_option( 'lifecycle.deactivations', array() ); + return is_array( $deactivations ) ? count( $deactivations ) : 0; + } + + public static function get_install_id(): string { + $install_id = \Cmatic_Options_Repository::get_option( 'install.id', '' ); + if ( ! empty( $install_id ) ) { + return $install_id; + } + + $install_data = new \Cmatic_Install_Data( \Cmatic_Options_Repository::instance() ); + return $install_data->get_install_id(); + } + + public static function get_quest(): int { + $quest = (int) \Cmatic_Options_Repository::get_option( 'install.quest', 0 ); + if ( $quest >= \Cmatic_Install_Data::MIN_VALID_TIMESTAMP ) { + return $quest; + } + + $install_data = new \Cmatic_Install_Data( \Cmatic_Options_Repository::instance() ); + return $install_data->get_quest(); + } + + public static function save_error( $error ): void { + Cmatic_Options_Repository::set_option( 'telemetry.last_error', $error ); + } + + public static function save_payload_hash( $hash ) { + Cmatic_Options_Repository::set_option( 'telemetry.last_payload_hash', $hash ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Sync.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Sync.php new file mode 100644 index 0000000..e34ca4e --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Sync.php @@ -0,0 +1,182 @@ + wp_json_encode( $request ), + 'headers' => array( 'Content-Type' => 'application/json' ), + 'timeout' => 5, + ) + ); + + return self::handle_response( $response, $payload ); + } catch ( \Exception $e ) { + return false; + } + } + + public static function send_async( $payload ) { + try { + if ( empty( self::$endpoint_url ) ) { + return; + } + + $request = self::prepare_request( $payload ); + + wp_remote_post( + self::$endpoint_url, + array( + 'body' => wp_json_encode( $request ), + 'headers' => array( 'Content-Type' => 'application/json' ), + 'timeout' => 5, + 'blocking' => false, + ) + ); + + Storage::update_last_heartbeat(); + } catch ( \Exception $e ) { + return; + } + } + + private static function prepare_request( $payload ) { + $install_id = Storage::get_install_id(); + $timestamp = time(); + $payload_json = wp_json_encode( $payload ); + $signature = Signature::generate( $install_id, $timestamp, $payload_json ); + + return array( + 'install_id' => $install_id, + 'timestamp' => $timestamp, + 'signature' => $signature, + 'public_key' => Signature::get_public_key(), + 'payload_json' => $payload_json, + ); + } + + private static function handle_response( $response, $payload ) { + if ( is_wp_error( $response ) ) { + self::handle_failure( $response->get_error_message(), $payload ); + return false; + } + + $code = wp_remote_retrieve_response_code( $response ); + + if ( 200 !== $code && 201 !== $code ) { + $body = wp_remote_retrieve_body( $response ); + self::handle_failure( "HTTP {$code}: {$body}", $payload ); + return false; + } + + self::handle_success( $payload ); + return true; + } + + private static function handle_success( $payload ) { + Storage::update_last_heartbeat(); + + $payload_hash = md5( wp_json_encode( $payload ) ); + Storage::save_payload_hash( $payload_hash ); + Storage::save_error( '' ); + + if ( 'sparse' === Storage::get_schedule() ) { + Scheduler::schedule_next_sparse(); + } + } + + private static function handle_failure( $error, $payload ) { + Storage::update_last_heartbeat(); + Storage::increment_failed_count(); + Storage::save_error( $error ); + + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + error_log( "[ChimpMatic Metrics] Heartbeat failed: {$error}" ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log + } + + if ( 'sparse' === Storage::get_schedule() ) { + Scheduler::schedule_next_sparse(); + } + } + + public static function send_lifecycle_signal( $event ) { + $options = get_option( 'cmatic', array() ); + + $default_enabled = 'activation' === $event; + $telemetry_enabled = $options['telemetry']['enabled'] ?? $default_enabled; + if ( ! $telemetry_enabled ) { + return; + } + + $install_id = $options['install']['id'] ?? ''; + if ( empty( $install_id ) ) { + return; + } + + global $wpdb; + $payload = array( + 'event' => $event, + 'install_id' => $install_id, + 'version' => defined( 'SPARTAN_MCE_VERSION' ) ? SPARTAN_MCE_VERSION : '1.0.0', + 'site_url' => home_url(), + 'timestamp' => time(), + 'wp_version' => get_bloginfo( 'version' ), + 'php' => PHP_VERSION, + 'mysql_version' => $wpdb->db_version(), + 'software' => array( + 'server' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : 'unknown', // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated + ), + ); + + $timestamp = time(); + $payload_json = wp_json_encode( $payload ); + $signature = Signature::generate( $install_id, $timestamp, $payload_json ); + + $request = array( + 'install_id' => $install_id, + 'timestamp' => $timestamp, + 'signature' => $signature, + 'public_key' => Signature::get_public_key(), + 'payload_json' => $payload_json, + ); + + wp_remote_post( + 'https://signls.dev/wp-json/chimpmatic/v1/telemetry', + array( + 'body' => wp_json_encode( $request ), + 'headers' => array( 'Content-Type' => 'application/json' ), + 'timeout' => 5, + 'blocking' => true, + ) + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Tracker.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Tracker.php new file mode 100644 index 0000000..9763b51 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/signals/Core/Tracker.php @@ -0,0 +1,82 @@ +register_hooks(); + } + + private function register_hooks() { + add_action( 'admin_bar_menu', array( $this, 'add_menu' ), 95 ); + add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) ); + add_action( 'admin_footer', array( $this, 'render_upgrade_click_script' ) ); + add_action( 'wp_footer', array( $this, 'render_upgrade_click_script' ) ); + } + + private function can_show_menu() { + return current_user_can( 'manage_options' ) && is_admin_bar_showing(); + } + + private function is_pro_active() { + return function_exists( 'cmatic_is_blessed' ) && cmatic_is_blessed(); + } + + private function is_pro_installed_not_licensed() { + if ( ! defined( 'CMATIC_VERSION' ) ) { + return false; + } + return ! $this->is_pro_active(); + } + + private function has_plugin_update() { + $updates = get_site_transient( 'update_plugins' ); + if ( ! $updates || ! isset( $updates->response ) ) { + return false; + } + return isset( $updates->response['contact-form-7-mailchimp-extension/chimpmatic-lite.php'] ) + || isset( $updates->response['chimpmatic/chimpmatic.php'] ); + } + + private function should_show_upgrade_badge() { + return ! Cmatic_Options_Repository::get_option( 'ui.upgrade_clicked', false ); + } + + private function get_license_activation_url() { + return admin_url( 'admin.php?page=wpcf7-integration&service=0_chimpmatic&action=setup' ); + } + + private function get_update_url() { + return admin_url( 'plugins.php?plugin_status=upgrade' ); + } + + public function add_menu( WP_Admin_Bar $wp_admin_bar ) { + if ( ! $this->can_show_menu() ) { + return; + } + + $this->add_root_menu( $wp_admin_bar ); + $this->add_submenu_items( $wp_admin_bar ); + } + + private function add_root_menu( WP_Admin_Bar $wp_admin_bar ) { + $badge_count = 0; + + if ( $this->has_plugin_update() ) { + ++$badge_count; + } + + if ( ! $this->is_pro_active() && $this->should_show_upgrade_badge() ) { + ++$badge_count; + } + + $icon_svg = 'data:image/svg+xml;base64,' . $this->get_icon_base64(); + $icon_styles = 'width:26px;height:30px;float:left;background:url(\'' . esc_attr( $icon_svg ) . '\') center/20px no-repeat;'; + + $title = '

'; + + if ( $badge_count > 0 ) { + $title .= $this->get_notification_counter( $badge_count ); + } + + $wp_admin_bar->add_menu( + array( + 'id' => self::MENU_IDENTIFIER, + 'title' => $title, + 'href' => false, + ) + ); + } + + private function add_submenu_items( WP_Admin_Bar $wp_admin_bar ) { + if ( $this->has_plugin_update() ) { + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-update', + 'title' => esc_html__( 'Update Available', 'chimpmatic-lite' ) . ' ' . $this->get_notification_counter( 1 ), + 'href' => $this->get_update_url(), + 'meta' => array( + 'title' => esc_attr__( 'Update strongly recommended', 'chimpmatic-lite' ), + ), + ) + ); + } + + if ( $this->is_pro_installed_not_licensed() ) { + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-activate-license', + 'title' => esc_html__( 'Activate License', 'chimpmatic-lite' ), + 'href' => $this->get_license_activation_url(), + ) + ); + } + + // Add Forms submenu with all CF7 forms. + $this->add_forms_submenu( $wp_admin_bar ); + + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-docs', + 'title' => esc_html__( 'Documentation', 'chimpmatic-lite' ), + 'href' => Cmatic_Pursuit::adminbar( 'docs', 'menu_docs' ), + 'meta' => array( + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ), + ) + ); + + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-support', + 'title' => esc_html__( 'Support', 'chimpmatic-lite' ), + 'href' => Cmatic_Pursuit::adminbar( 'support', 'menu_support' ), + 'meta' => array( + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ), + ) + ); + + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-reviews', + 'title' => esc_html__( 'Reviews', 'chimpmatic-lite' ), + 'href' => 'https://wordpress.org/support/plugin/contact-form-7-mailchimp-extension/reviews/', + 'meta' => array( + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ), + ) + ); + + if ( ! $this->is_pro_active() ) { + $upgrade_title = esc_html__( 'Upgrade to Pro', 'chimpmatic-lite' ); + + if ( $this->should_show_upgrade_badge() ) { + $upgrade_title .= ' ' . $this->get_notification_counter( 1 ); + } + + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-upgrade', + 'title' => $upgrade_title, + 'href' => Cmatic_Pursuit::adminbar( 'pricing', 'menu_upgrade' ), + 'meta' => array( + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ), + ) + ); + } + } + + private function add_forms_submenu( WP_Admin_Bar $wp_admin_bar ) { + // Check if CF7 is active. + if ( ! class_exists( 'WPCF7_ContactForm' ) ) { + return; + } + + // Get all CF7 forms. + $forms = WPCF7_ContactForm::find( array( 'posts_per_page' => -1 ) ); + + if ( empty( $forms ) ) { + return; + } + + // Add "Form Settings" section header (non-clickable label). + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-forms-header', + 'title' => esc_html__( 'Form Settings', 'chimpmatic-lite' ), + 'href' => false, + ) + ); + + // Add each form directly to main menu (flat, not nested). + foreach ( $forms as $form ) { + $form_url = admin_url( + sprintf( + 'admin.php?page=wpcf7&post=%d&action=edit&active-tab=Chimpmatic', + $form->id() + ) + ); + + // Check API connection status for this form. + $api_status = $this->get_form_api_status( $form->id() ); + + $wp_admin_bar->add_menu( + array( + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'chimpmatic-form-' . $form->id(), + 'title' => '  ' . esc_html( $form->title() ) . $api_status, + 'href' => $form_url, + 'meta' => array( + 'class' => 'cmatic-form-item', + ), + ) + ); + } + } + + private function get_form_api_status( $form_id ) { + $cf7_mch = get_option( 'cf7_mch_' . $form_id, array() ); + + // Check if API is validated and a list/audience is selected. + $is_connected = ! empty( $cf7_mch['api-validation'] ) + && 1 == $cf7_mch['api-validation'] + && ! empty( $cf7_mch['list'] ); + + if ( $is_connected ) { + return '' . esc_html__( 'API', 'chimpmatic-lite' ) . ''; + } + + return '' . esc_html__( 'API', 'chimpmatic-lite' ) . ''; + } + + private function get_notification_counter( $count ) { + if ( $count < 1 ) { + return ''; + } + + $screen_reader_text = sprintf( + /* translators: %s: number of notifications */ + _n( '%s notification', '%s notifications', $count, 'chimpmatic-lite' ), + number_format_i18n( $count ) + ); + + return sprintf( + '
%2$s
', + (int) $count, + esc_html( $screen_reader_text ) + ); + } + + private function get_settings_url() { + if ( class_exists( 'Cmatic_Plugin_Links' ) ) { + $url = Cmatic_Plugin_Links::get_settings_url(); + if ( ! empty( $url ) ) { + return $url; + } + } + + return admin_url( 'admin.php?page=wpcf7' ); + } + + public function enqueue_assets() { + if ( ! $this->can_show_menu() ) { + return; + } + + $css = $this->get_inline_css(); + wp_add_inline_style( 'admin-bar', $css ); + } + + private function get_inline_css() { + $icon_base64 = $this->get_icon_base64(); + + $css = ' + #wpadminbar .cmatic-logo.svg { + background-image: url("data:image/svg+xml;base64,' . $icon_base64 . '"); + background-position: center; + background-repeat: no-repeat; + background-size: 20px; + float: left; + height: 30px; + width: 26px; + margin-top: 2px; + } + #wpadminbar #wp-admin-bar-chimpmatic-menu .cmatic-form-item .ab-item { + background-color: rgba(255,255,255,0.04) !important; + padding-left: 20px !important; + display: flex; + justify-content: space-between; + align-items: center; + } + #wpadminbar #wp-admin-bar-chimpmatic-menu .cmatic-form-item .ab-item:hover { + background-color: rgba(255,255,255,0.1) !important; + } + #wpadminbar .cmatic-api-status { + font-size: 10px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + margin-left: 15px; + flex-shrink: 0; + } + #wpadminbar .cmatic-api-connected { + color: #00ba37; + } + #wpadminbar .cmatic-api-disconnected { + color: #787c82; + } + #wpadminbar .cmatic-issue-counter { + background-color: #d63638; + border-radius: 9px; + color: #fff; + display: inline; + padding: 1px 7px 1px 6px !important; + } + #wpadminbar .quicklinks #wp-admin-bar-chimpmatic-menu #wp-admin-bar-chimpmatic-menu-default li#wp-admin-bar-chimpmatic-upgrade { + display: flex; + } + #wpadminbar .quicklinks #wp-admin-bar-chimpmatic-menu #wp-admin-bar-chimpmatic-menu-default li#wp-admin-bar-chimpmatic-upgrade .ab-item { + align-items: center; + border-color: transparent; + border-radius: 6px; + cursor: pointer; + display: inline-flex; + justify-content: center; + margin: 8px 12px; + background-color: #00be28; + font-size: 13px; + font-weight: 500; + padding: 6px 10px; + text-align: center; + text-decoration: none; + color: #fff !important; + width: 100%; + } + #wpadminbar .quicklinks #wp-admin-bar-chimpmatic-menu #wp-admin-bar-chimpmatic-menu-default li#wp-admin-bar-chimpmatic-upgrade .ab-item:hover { + background-color: #00a522; + color: #fff !important; + } + #wpadminbar #wp-admin-bar-chimpmatic-upgrade .cmatic-issue-counter { + width: 18px; + height: 18px; + min-width: 18px; + border-radius: 50%; + padding: 0 !important; + display: inline-flex; + align-items: center; + justify-content: center; + margin-left: 6px; + font-size: 11px; + line-height: 1; + } + @media screen and (max-width: 782px) { + #wpadminbar .cmatic-logo.svg { + background-position: center 8px; + background-size: 30px; + height: 46px; + width: 52px; + } + #wpadminbar .cmatic-logo + .cmatic-issue-counter { + margin-left: -5px; + margin-right: 10px; + } + } + '; + + return $css; + } + + private function get_icon_base64() { + $svg = '' + . '' + . ''; + + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode + return base64_encode( $svg ); + } + + public function render_upgrade_click_script() { + if ( ! $this->can_show_menu() ) { + return; + } + + if ( $this->is_pro_active() || ! $this->should_show_upgrade_badge() ) { + return; + } + + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ +
+ +
+
+ = 12; + $is_valid = '1' === $apivalid; + + $btn_value = $is_valid ? 'Connected' : 'Sync Audiences'; + $btn_class = 'button'; + + $help_url = Cmatic_Pursuit::docs( 'how-to-get-your-mailchimp-api-key', 'api_panel_help' ); + + ?> +
+
+
+ + +
+ + + + + + + + + + +
+ +
+
+ +
+
+ + + + + + + + + + + +
+ + + id(); + $cf7_mch = get_option( 'cf7_mch_' . $form_id, array() ); + + if ( empty( $cf7_mch ) || empty( $cf7_mch['api-validation'] ) ) { + return $output; + } + + // Append the author credit. + return $output . self::get_author_credit(); + } + + private const DEFAULT_WELCOME = '

Hello. My name is Renzo, I WordPress and I develop this free plugin to help users like you. I drink copious amounts of coffee to keep me running longer . If you\'ve found this plugin useful, please consider making a donation.


+

Would you like to buy me a coffee? or Donate with Paypal

'; + + public static function get_welcome(): string { + $banner = get_site_option( 'mce_conten_panel_welcome', self::DEFAULT_WELCOME ); + + return empty( trim( $banner ) ) ? self::DEFAULT_WELCOME : $banner; + } + + public static function render_lateral(): void { + ?> +
+ +
+

Upgrade to PRO

+

We have the the best tool to integrate Contact Form 7 & Mailchimp.com mailing lists. We have new nifty features:

+
    +
  • Tag Existing Subscribers
  • +
  • Group Existing Subscribers
  • +
  • Email Verification
  • +
  • AWESOME Support And more!
  • +
+
+
+

40% Off!

+

Submit your name and email and we\'ll send you a coupon for 40% off your upgrade to the pro version.

+
+ +
+
'; + } + + public static function render_new_user_help(): void { + $help_url = Cmatic_Pursuit::docs( 'how-to-get-your-mailchimp-api-key', 'new_user_help' ); + ?> +

+ + + +

+ '; + $html .= 'ChimpMatic'; + $html .= ' – CF7 Mailchimp Integration'; + $html .= '

' . "\n"; + + return $html; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-data-container.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-data-container.php new file mode 100644 index 0000000..e94780f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-data-container.php @@ -0,0 +1,67 @@ +', + esc_attr( self::ELEMENT_ID ), + $attrs_html + ); + } + + public static function render_open( int $form_id, string $apivalid = '0', array $extra = array() ): void { + $attrs_html = self::build_data_attrs( $form_id, $apivalid, $extra ); + + printf( + '
', + esc_attr( self::ELEMENT_ID ), + $attrs_html + ); + } + + public static function render_close(): void { + echo '
'; + } + + private static function build_data_attrs( int $form_id, string $apivalid = '0', array $extra = array() ): string { + $data_attrs = array( + 'form-id' => $form_id, + 'api-valid' => $apivalid, + ); + + foreach ( $extra as $key => $value ) { + $key = str_replace( '_', '-', sanitize_key( $key ) ); + + if ( is_array( $value ) || is_object( $value ) ) { + $data_attrs[ $key ] = wp_json_encode( $value ); + } else { + $data_attrs[ $key ] = esc_attr( $value ); + } + } + + $attrs_html = ''; + foreach ( $data_attrs as $key => $value ) { + $attrs_html .= sprintf( ' data-%s="%s"', esc_attr( $key ), esc_attr( $value ) ); + } + + return $attrs_html; + } + + public static function get_element_id(): string { + return self::ELEMENT_ID; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-field-mapper.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-field-mapper.php new file mode 100644 index 0000000..c43da59 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-field-mapper.php @@ -0,0 +1,259 @@ + CMATIC_LITE_FIELDS; + $notice_class = $show_notice ? 'cmatic-visible' : 'cmatic-hidden'; + $audience_name = self::resolve_audience_name( $cf7_mch ); + $docs_url = Cmatic_Pursuit::url( 'https://chimpmatic.com/mailchimp-default-audience-fields-explained', 'plugin', 'fields_notice', 'docs' ); + ?> +
+ +
+

+ + , 2: total merge fields count, 3: lite fields limit */ + __( 'Your %1$s audience has %2$d merge fields. Chimpmatic Lite supports up to %3$d field mappings.', 'chimpmatic-lite' ), + '' . esc_html( $audience_name ) . '', + $total_merge, + CMATIC_LITE_FIELDS + ); + echo wp_kses( $notice_text, array( 'strong' => array() ) ); + ?> + + + + +

+
+
+ 'Field ' . $field_index, + 'type' => 'text', + 'required' => false, + 'description' => 'Map a form field to Mailchimp', + 'merge_tag' => '', + ); + } + + $tag = $merge_field['tag'] ?? ''; + $name = $merge_field['name'] ?? $tag; + $type = $merge_field['type'] ?? 'text'; + + $config = array( + 'label' => $name . ' - *|' . $tag . '|* ' . esc_html( $type ) . '', + 'type' => 'text', + 'required' => false, + 'description' => 'Map a form field to Mailchimp', + 'merge_tag' => $tag, + ); + + if ( 'EMAIL' === $tag ) { + $config['required'] = true; + $config['type'] = 'email'; + $config['description'] = 'MUST be an email tag Learn More'; + } + + return $config; + } + + private static function render_field_row( string $field_key, array $form_tags, array $cf7_mch, array $config ): void { + ?> +
+ + +
+ + + +
+ + + + + + +
+ +
+ + + + + + +
+ id(); + $cf7_mch = get_option( 'cf7_mch_' . $form_id, array() ); + $mapped = self::count_mapped_fields( $cf7_mch ); + $total = self::count_total_merge_fields( $cf7_mch ); + $classes[] = 'cmatic-mapd' . $mapped . '-' . $total; + } + + // 5. Lite version (SPARTAN_MCE_VERSION). + if ( defined( 'SPARTAN_MCE_VERSION' ) ) { + $version = str_replace( '.', '', SPARTAN_MCE_VERSION ); + $classes[] = 'cmatic-v' . $version; + } + + // 6. Pro version (CMATIC_VERSION) if active. + if ( defined( 'CMATIC_VERSION' ) ) { + $pro_version = str_replace( '.', '', CMATIC_VERSION ); + $classes[] = 'cmatic-pro-v' . $pro_version; + } + + // 7. Per-form sent count. + if ( $contact_form ) { + $form_sent = (int) ( $cf7_mch['stats_sent'] ?? 0 ); + $classes[] = 'cmatic-sent-' . $form_sent; + } + + // 8. Global total sent. + $total_sent = (int) Cmatic_Options_Repository::get_option( 'stats.sent', 0 ); + $classes[] = 'cmatic-total-' . $total_sent; + + // Append to existing classes. + if ( ! empty( $classes ) ) { + $class_attr .= ' ' . implode( ' ', $classes ); + } + + return $class_attr; + } + + private static function count_mapped_fields( array $cf7_mch ): int { + $merge_fields = isset( $cf7_mch['merge_fields'] ) && is_array( $cf7_mch['merge_fields'] ) + ? $cf7_mch['merge_fields'] + : array(); + + if ( empty( $merge_fields ) ) { + return 0; + } + + $mapped = 0; + foreach ( $merge_fields as $index => $field ) { + $field_key = 'field' . ( $index + 3 ); + if ( ! empty( $cf7_mch[ $field_key ] ) && '--' !== $cf7_mch[ $field_key ] ) { + ++$mapped; + } + } + + return $mapped; + } + + private static function count_total_merge_fields( array $cf7_mch ): int { + $merge_fields = isset( $cf7_mch['merge_fields'] ) && is_array( $cf7_mch['merge_fields'] ) + ? $cf7_mch['merge_fields'] + : array(); + + return count( $merge_fields ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-header.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-header.php new file mode 100644 index 0000000..0a2fc54 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-header.php @@ -0,0 +1,148 @@ +version = $this->resolve_version( $args ); + $this->is_pro = $this->resolve_pro_status( $args ); + $this->api_status = isset( $args['api_status'] ) && is_string( $args['api_status'] ) ? $args['api_status'] : null; + $this->review_url = isset( $args['review_url'] ) && is_string( $args['review_url'] ) ? $args['review_url'] : $this->get_default_review_url(); + + $this->review_phrases = array( + __( 'Loving Chimpmatic? Leave a review', 'chimpmatic-lite' ), + __( 'We run on coffee & 5-star reviews', 'chimpmatic-lite' ), + __( 'Make a developer smile today', 'chimpmatic-lite' ), + __( 'Got 10 seconds? Rate us!', 'chimpmatic-lite' ), + __( 'Fuel our plugin addiction', 'chimpmatic-lite' ), + __( 'Stars make us code faster', 'chimpmatic-lite' ), + __( 'Help us stay free & caffeinated', 'chimpmatic-lite' ), + __( "Love us? Don't keep it a secret", 'chimpmatic-lite' ), + __( 'Your review = our dopamine', 'chimpmatic-lite' ), + __( 'Be our hero on WordPress.org', 'chimpmatic-lite' ), + __( 'Psst... we love 5 stars', 'chimpmatic-lite' ), + __( 'Worth 5 stars? Let us know', 'chimpmatic-lite' ), + __( 'Support indie plugins', 'chimpmatic-lite' ), + __( 'Reviews keep the lights on', 'chimpmatic-lite' ), + __( 'Spread the Chimpmatic love', 'chimpmatic-lite' ), + __( 'Got love? Leave stars', 'chimpmatic-lite' ), + __( 'One click, endless gratitude', 'chimpmatic-lite' ), + __( 'Help other WP folks find us', 'chimpmatic-lite' ), + __( 'Like us? Rate us!', 'chimpmatic-lite' ), + __( 'Your stars = our motivation', 'chimpmatic-lite' ), + ); + } + + + private function resolve_version( array $args ): string { + if ( isset( $args['version'] ) && is_string( $args['version'] ) ) { + return $args['version']; + } + + if ( defined( 'CMATIC_VERSION' ) ) { + return (string) CMATIC_VERSION; + } + + if ( defined( 'SPARTAN_MCE_VERSION' ) ) { + return (string) SPARTAN_MCE_VERSION; + } + + return '0.0.0'; + } + + + private function resolve_pro_status( array $args ): bool { + if ( isset( $args['is_pro'] ) ) { + return (bool) $args['is_pro']; + } + + if ( function_exists( 'cmatic_is_blessed' ) ) { + return (bool) cmatic_is_blessed(); + } + + return false; + } + + + private function get_default_review_url(): string { + return 'https://wordpress.org/support/plugin/contact-form-7-mailchimp-extension/reviews/'; + } + + + private function get_review_phrase(): string { + $index = wp_rand( 0, count( $this->review_phrases ) - 1 ); + return $this->review_phrases[ $index ]; + } + + + public function render(): void { + $badge_class = $this->is_pro ? 'cmatic-header__badge--pro' : 'cmatic-header__badge--lite'; + $badge_text = $this->is_pro ? __( 'PRO', 'chimpmatic-lite' ) : __( 'Lite', 'chimpmatic-lite' ); + ?> +
+
+
+ + + vversion ); ?> + render_api_status(); ?> +
+ +
+
+ api_status ) { + return; + } + + $is_connected = ( 'connected' === $this->api_status ); + $dot_class = $is_connected ? 'cmatic-header__status-dot--connected' : 'cmatic-header__status-dot--disconnected'; + $status_text = $is_connected + ? __( 'API Connected', 'chimpmatic-lite' ) + : __( 'API Inactive', 'chimpmatic-lite' ); + ?> +
+ + +
+ api_status = $status; + return $this; + } + + + public static function output( array $args = array() ): void { + $header = new self( $args ); + $header->render(); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-modal.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-modal.php new file mode 100644 index 0000000..98087bd --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-modal.php @@ -0,0 +1,164 @@ +modal_id = sanitize_key( $modal_id ); + $this->admin_hooks = is_array( $admin_hooks ) ? $admin_hooks : array( $admin_hooks ); + } + + public function init() { + if ( $this->initialized ) { + return; + } + + add_action( 'admin_enqueue_scripts', array( $this, 'maybe_enqueue_assets' ) ); + add_action( $this->get_render_hook(), array( $this, 'maybe_render_modal' ), $this->get_render_priority(), $this->get_render_args() ); + + $this->initialized = true; + } + + protected function get_render_hook() { + return 'admin_footer'; + } + + protected function get_render_priority() { + return 20; + } + + protected function get_render_args() { + return 0; + } + + protected function is_valid_admin_page( $hook ) { + if ( empty( $this->admin_hooks ) ) { + return true; + } + return in_array( $hook, $this->admin_hooks, true ); + } + + public function maybe_enqueue_assets( $hook ) { + if ( ! $this->is_valid_admin_page( $hook ) ) { + return; + } + $this->enqueue_assets( $hook ); + } + + public function maybe_render_modal() { + $screen = get_current_screen(); + if ( ! $screen ) { + return; + } + + $current_hook = $screen->id; + if ( ! empty( $this->admin_hooks ) && ! in_array( $current_hook, $this->admin_hooks, true ) ) { + return; + } + + $this->render_modal(); + } + + protected function enqueue_assets( $hook ) { + } + + protected function render_modal() { + $title = $this->get_title(); + $body = $this->get_body(); + $footer = $this->get_footer(); + $extra_class = $this->get_extra_class(); + $description = $this->get_description(); + + ?> + + modal_id; + } + + protected function get_strings() { + return array( + 'closeLabel' => __( 'Close dialog', 'chimpmatic-lite' ), + ); + } + + protected function get_js_data() { + return array( + 'modalId' => $this->modal_id, + 'strings' => $this->get_strings(), + ); + } + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-notification-center.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-notification-center.php new file mode 100644 index 0000000..71d13f5 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-notification-center.php @@ -0,0 +1,290 @@ +retrieve_notifications(); + $this->add_dynamic_notifications(); + } + + private function retrieve_notifications() { + if ( $this->notifications_retrieved ) { + return; + } + + $this->notifications_retrieved = true; + $user_id = get_current_user_id(); + + if ( ! $user_id ) { + return; + } + + $stored = get_user_option( self::STORAGE_KEY, $user_id ); + + if ( ! is_array( $stored ) ) { + return; + } + + foreach ( $stored as $data ) { + $notification = Cmatic_Notification::from_array( $data ); + if ( $notification->display_for_current_user() ) { + $this->notifications[] = $notification; + } + } + } + + private function add_dynamic_notifications() { + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + + $api_key = $this->get_api_key_status(); + + if ( ! $api_key ) { + $this->add_notification( + new Cmatic_Notification( + __( 'Connect your Mailchimp API to enable email subscriptions.', 'chimpmatic-lite' ), + array( + 'id' => 'cmatic-api-not-connected', + 'type' => Cmatic_Notification::WARNING, + 'priority' => 1.0, + 'link' => $this->get_settings_url(), + 'link_text' => __( 'Connect Now', 'chimpmatic-lite' ), + ) + ) + ); + } + + if ( class_exists( 'Cmatic_Options_Repository' ) && Cmatic_Options_Repository::get_option( 'debug', false ) ) { + $this->add_notification( + new Cmatic_Notification( + __( 'Debug logging is currently enabled.', 'chimpmatic-lite' ), + array( + 'id' => 'cmatic-debug-enabled', + 'type' => Cmatic_Notification::INFO, + 'priority' => 0.3, + 'link' => $this->get_settings_url(), + 'link_text' => __( 'View Settings', 'chimpmatic-lite' ), + ) + ) + ); + } + } + + private function get_api_key_status() { + $cache_key = 'cmatic_api_connected'; + $cached = get_transient( $cache_key ); + + if ( false !== $cached ) { + return (bool) $cached; + } + + global $wpdb; + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Cached via transient. + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT option_value FROM {$wpdb->options} WHERE option_name LIKE %s LIMIT 10", + 'cf7_mch_%' + ) + ); + + $is_connected = false; + + if ( ! empty( $results ) ) { + foreach ( $results as $row ) { + $data = maybe_unserialize( $row->option_value ); + if ( is_array( $data ) && ! empty( $data['api_key'] ) ) { + $is_connected = true; + break; + } + } + } + + set_transient( $cache_key, $is_connected ? '1' : '0', HOUR_IN_SECONDS ); + + return $is_connected; + } + + private function get_settings_url() { + if ( class_exists( 'Cmatic_Plugin_Links' ) ) { + $url = Cmatic_Plugin_Links::get_settings_url(); + if ( ! empty( $url ) ) { + return $url; + } + } + + return admin_url( 'admin.php?page=wpcf7' ); + } + + public function add_notification( Cmatic_Notification $notification ) { + if ( ! $notification->display_for_current_user() ) { + return; + } + + if ( $this->is_notification_dismissed( $notification ) ) { + return; + } + + $id = $notification->get_id(); + if ( $id ) { + foreach ( $this->notifications as $existing ) { + if ( $existing->get_id() === $id ) { + return; + } + } + } + + $this->notifications[] = $notification; + $this->notifications_dirty = true; + } + + public function remove_notification( $notification_id ) { + foreach ( $this->notifications as $index => $notification ) { + if ( $notification->get_id() === $notification_id ) { + unset( $this->notifications[ $index ] ); + $this->notifications = array_values( $this->notifications ); + $this->notifications_dirty = true; + return; + } + } + } + + public function get_notification_by_id( $notification_id ) { + foreach ( $this->notifications as $notification ) { + if ( $notification->get_id() === $notification_id ) { + return $notification; + } + } + return null; + } + + public function get_notifications() { + return $this->notifications; + } + + public function get_notification_count() { + return count( $this->notifications ); + } + + public function get_sorted_notifications() { + $notifications = $this->notifications; + + usort( + $notifications, + function ( $a, $b ) { + $type_priority = array( + Cmatic_Notification::ERROR => 4, + Cmatic_Notification::WARNING => 3, + Cmatic_Notification::INFO => 2, + Cmatic_Notification::SUCCESS => 1, + ); + + $a_type = isset( $type_priority[ $a->get_type() ] ) ? $type_priority[ $a->get_type() ] : 0; + $b_type = isset( $type_priority[ $b->get_type() ] ) ? $type_priority[ $b->get_type() ] : 0; + + if ( $a_type !== $b_type ) { + return $b_type - $a_type; + } + + if ( $b->get_priority() > $a->get_priority() ) { + return 1; + } elseif ( $b->get_priority() < $a->get_priority() ) { + return -1; + } + return 0; + } + ); + + return $notifications; + } + + public function is_notification_dismissed( Cmatic_Notification $notification ) { + $dismissal_key = $notification->get_dismissal_key(); + + if ( empty( $dismissal_key ) ) { + return false; + } + + $user_id = get_current_user_id(); + $value = get_user_option( 'cmatic_dismissed_' . $dismissal_key, $user_id ); + + return ! empty( $value ); + } + + public function dismiss_notification( Cmatic_Notification $notification ) { + $dismissal_key = $notification->get_dismissal_key(); + + if ( empty( $dismissal_key ) ) { + return false; + } + + $user_id = get_current_user_id(); + $result = update_user_option( $user_id, 'cmatic_dismissed_' . $dismissal_key, time() ); + + if ( $result ) { + $this->remove_notification( $notification->get_id() ); + } + + return (bool) $result; + } + + public function save_notifications() { + if ( ! $this->notifications_dirty ) { + return; + } + + $user_id = get_current_user_id(); + + if ( ! $user_id ) { + return; + } + + $to_store = array(); + + foreach ( $this->notifications as $notification ) { + if ( $notification->is_persistent() ) { + $to_store[] = $notification->to_array(); + } + } + + if ( empty( $to_store ) ) { + delete_user_option( $user_id, self::STORAGE_KEY ); + } else { + update_user_option( $user_id, self::STORAGE_KEY, $to_store ); + } + } + + public function clear_notifications() { + $this->notifications = array(); + $this->notifications_dirty = true; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-notification.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-notification.php new file mode 100644 index 0000000..888366d --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-notification.php @@ -0,0 +1,118 @@ + self::INFO, + 'id' => '', + 'user_id' => null, + 'priority' => 0.5, + 'dismissal_key' => null, + 'capabilities' => array( 'manage_options' ), + 'link' => '', + 'link_text' => '', + ); + + public function __construct( $message, $options = array() ) { + $this->message = $message; + $this->options = wp_parse_args( $options, $this->defaults ); + + if ( null === $this->options['user_id'] ) { + $this->options['user_id'] = get_current_user_id(); + } + + $this->options['priority'] = min( 1, max( 0, $this->options['priority'] ) ); + } + + public function get_id() { + return $this->options['id']; + } + + public function get_message() { + return $this->message; + } + + public function get_type() { + return $this->options['type']; + } + + public function get_priority() { + return $this->options['priority']; + } + + public function get_user_id() { + return (int) $this->options['user_id']; + } + + public function get_dismissal_key() { + if ( empty( $this->options['dismissal_key'] ) ) { + return $this->options['id']; + } + return $this->options['dismissal_key']; + } + + public function get_link() { + return $this->options['link']; + } + + public function get_link_text() { + return $this->options['link_text']; + } + + public function is_persistent() { + return ! empty( $this->options['id'] ); + } + + public function display_for_current_user() { + if ( ! $this->is_persistent() ) { + return true; + } + + return $this->user_has_capabilities(); + } + + private function user_has_capabilities() { + $capabilities = $this->options['capabilities']; + + if ( empty( $capabilities ) ) { + return true; + } + + foreach ( $capabilities as $capability ) { + if ( ! current_user_can( $capability ) ) { + return false; + } + } + + return true; + } + + public function to_array() { + return array( + 'message' => $this->message, + 'options' => $this->options, + ); + } + + public static function from_array( $data ) { + $message = isset( $data['message'] ) ? $data['message'] : ''; + $options = isset( $data['options'] ) ? $data['options'] : array(); + return new self( $message, $options ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-panel-toggles.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-panel-toggles.php new file mode 100644 index 0000000..ff34d1a --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-panel-toggles.php @@ -0,0 +1,83 @@ + array( + 'label' => __( 'Advanced Settings', 'flavor' ), + 'aria_controls' => 'cme-container', + 'extra_class' => '', + 'priority' => 10, + ), + 'submission_logs' => array( + 'label' => __( 'Submission Logs', 'flavor' ), + 'aria_controls' => 'eventlog-sys', + 'extra_class' => '', + 'priority' => 40, + ), + 'form_preview' => array( + 'label' => __( 'Form Preview and Test', 'flavor' ), + 'aria_controls' => 'cmatic-test-container', + 'extra_class' => 'vc-test-submission', + 'priority' => 50, + ), + ); + } + + public static function cmatic_get_buttons() { + $buttons = self::cmatic_get_default_buttons(); + $buttons = apply_filters( 'cmatic_panel_toggle_buttons', $buttons ); + + // Sort by priority. + uasort( + $buttons, + function ( $a, $b ) { + $priority_a = isset( $a['priority'] ) ? $a['priority'] : 50; + $priority_b = isset( $b['priority'] ) ? $b['priority'] : 50; + return $priority_a - $priority_b; + } + ); + + return $buttons; + } + + public static function cmatic_render_button( $key, $config ) { + $classes = 'button site-health-view-passed cmatic-accordion-btn'; + if ( ! empty( $config['extra_class'] ) ) { + $classes .= ' ' . esc_attr( $config['extra_class'] ); + } + + printf( + '', + esc_attr( $classes ), + esc_attr( $config['aria_controls'] ), + esc_html( $config['label'] ) + ); + } + + public static function cmatic_render() { + $buttons = self::cmatic_get_buttons(); + + if ( empty( $buttons ) ) { + return; + } + + echo '
'; + + foreach ( $buttons as $key => $config ) { + self::cmatic_render_button( $key, $config ); + } + + echo '
'; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-sidebar-panel.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-sidebar-panel.php new file mode 100644 index 0000000..98499e8 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-sidebar-panel.php @@ -0,0 +1,104 @@ +API Connected' + : 'API Inactive'; + ?> +
+
+ +
+
+
+ +
+
+ +
+
+
+ $install_id, + 'promo' => 'pro' . $discount, + ), + Cmatic_Pursuit::promo( 'footer_banner', $discount ) + ); + ?> +
+
+

Upgrade to PRO

+

Get the best Contact Form 7 and Mailchimp integration tool available. Now with these new features:

+ +
+
+

% Off!

+

Unlock advanced tagging, subscriber groups, email verification, and priority support for your Mailchimp campaigns.

+
+ Get PRO Now + +
+
+
+ 'https://api.chimpmatic.com/promo', + 'cache_key' => 'cmatic_pricing_data', + 'cache_duration' => DAY_IN_SECONDS, + 'fallback_data' => array( + 'regular_price' => 39, + 'sale_price' => 29.25, + 'discount_percent' => 40, + 'coupon_code' => 'NOW40', + 'formatted' => '$39 → $29.25 • Save 40%', + ), + ) + ); + + return $fetcher->get_data(); + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-tags-preview.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-tags-preview.php new file mode 100644 index 0000000..ab6c221 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-tags-preview.php @@ -0,0 +1,130 @@ + 'CHK', + 'radio' => 'RAD', + 'select' => 'SEL', + 'text' => 'TXT', + 'hidden' => 'HID', + 'dynamictext' => 'DYN', + 'dynamichidden' => 'DYN', + 'tel' => 'TEL', + 'number' => 'NUM', + ); + + private static $allowed_types = array( + 'checkbox', + 'radio', + 'select', + 'text', + 'hidden', + 'dynamictext', + 'dynamichidden', + 'tel', + 'number', + ); + + public static function render( array $form_tags, array $cf7_mch, int $api_valid ): void { + if ( empty( $form_tags ) || ! is_array( $form_tags ) ) { + return; + } + + $filtered_tags = array_filter( + $form_tags, + function ( $tag ) { + $basetype = is_array( $tag ) ? ( $tag['basetype'] ?? '' ) : ( $tag->basetype ?? '' ); + return in_array( $basetype, self::$allowed_types, true ); + } + ); + + if ( empty( $filtered_tags ) ) { + return; + } + + $disclosure_class = ( 1 === $api_valid ) ? 'spt-response-out spt-valid' : 'spt-response-out chmp-inactive'; + $name_list = self::get_audience_name( $cf7_mch ); + ?> +
+
+

+ Tags for + +

+

You can add these as your contacts tags:

+
+ + +
+ PRO Feature Learn More... +
+
+ '; + $i = 1; + foreach ( $tags as $tag ) { + $tag_name = is_array( $tag ) ? ( $tag['name'] ?? null ) : ( $tag->name ?? null ); + $tag_basetype = is_array( $tag ) ? ( $tag['basetype'] ?? null ) : ( $tag->basetype ?? null ); + + if ( empty( $tag_name ) || empty( $tag_basetype ) ) { + continue; + } + + $is_checked = isset( $cf7_mch['labeltags'][ $tag_name ] ); + $type_short = self::$type_abbrev[ $tag_basetype ] ?? strtoupper( substr( $tag_basetype, 0, 3 ) ); + $selected_class = $is_checked ? ' selected' : ''; + ?> + + '; + } + + private static function get_audience_name( array $cf7_mch ): string { + $arrlist = isset( $cf7_mch['lisdata']['lists'] ) ? array_column( $cf7_mch['lisdata']['lists'], 'name', 'id' ) : array(); + $idlist = ''; + + if ( isset( $cf7_mch['list'] ) ) { + if ( is_array( $cf7_mch['list'] ) ) { + $idlist = reset( $cf7_mch['list'] ); + if ( false === $idlist ) { + $idlist = ''; + } + } else { + $idlist = $cf7_mch['list']; + } + } + + return ( ! empty( $idlist ) && isset( $arrlist[ $idlist ] ) ) ? $arrlist[ $idlist ] : ''; + } + + private function __construct() {} +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-test-submission-modal.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-test-submission-modal.php new file mode 100644 index 0000000..1ab7ee7 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/ui/class-cmatic-test-submission-modal.php @@ -0,0 +1,97 @@ +initialized ) { + return; + } + + add_action( 'wpcf7_admin_footer', array( $this, 'render_modal_with_form' ), 20, 1 ); + + $this->initialized = true; + } + + public function render_modal_with_form( $post ) { + if ( ! $post || ! method_exists( $post, 'id' ) ) { + return; + } + + $form_id = $post->id(); + if ( ! $form_id ) { + return; + } + + $this->contact_form = wpcf7_contact_form( $form_id ); + if ( ! $this->contact_form ) { + return; + } + + parent::render_modal(); + } + + protected function get_title() { + return __( 'Test Current Form Submission', 'chimpmatic-lite' ); + } + + protected function render_header_actions() { + ?> + + contact_form ) { + return '

' . esc_html__( 'No form available.', 'chimpmatic-lite' ) . '

'; + } + + ob_start(); + ?> + +
+ contact_form->form_html( array( 'html_class' => 'cmatic-test-form' ) ); + ?> +
+ __( 'Submit', 'chimpmatic-lite' ), + 'submitting' => __( 'Submitting...', 'chimpmatic-lite' ), + 'success' => __( 'Success!', 'chimpmatic-lite' ), + 'error' => __( 'Error', 'chimpmatic-lite' ), + ) + ); + } + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-buster.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-buster.php new file mode 100644 index 0000000..46e1267 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-buster.php @@ -0,0 +1,48 @@ +plugin_version = $plugin_version; + $this->is_debug = $is_debug ?? ( defined( 'WP_DEBUG' ) && WP_DEBUG ); + } + + public function get_version( string $file_path ): string { + $version_parts = array( $this->plugin_version ); + + if ( file_exists( $file_path ) ) { + $version_parts[] = (string) filemtime( $file_path ); + $version_parts[] = substr( md5_file( $file_path ), 0, 8 ); + } + + if ( $this->is_debug ) { + $version_parts[] = (string) time(); + } + + return implode( '-', $version_parts ); + } + + public static function instance(): self { + if ( null === self::$instance ) { + self::$instance = new self(); + } + + return self::$instance; + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-file-logger.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-file-logger.php new file mode 100644 index 0000000..4f45aaa --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-file-logger.php @@ -0,0 +1,97 @@ +is_write_enabled = (bool) $enabled && ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ); + $this->log_prefix = '[' . sanitize_key( $context ) . ']'; + } + + public function log( string $level, string $message, $context = null ): void { + if ( ! $this->is_write_enabled ) { + return; + } + + $level_str = strtoupper( $level ); + $log_message = "[ChimpMatic Lite] {$this->log_prefix} [{$level_str}] " . trim( $message ); + + if ( ! is_null( $context ) ) { + $context_string = $this->format_data( $context ); + $log_message .= ' | Data: ' . $context_string; + } + + error_log( $log_message ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log + } + + private function format_data( $data ) { + if ( is_string( $data ) ) { + return $data; + } + + if ( ! is_array( $data ) ) { + return wp_json_encode( $data, JSON_UNESCAPED_SLASHES ); + } + + if ( isset( $data['email_address'] ) && isset( $data['status'] ) ) { + $summary = array( + 'email' => $data['email_address'] ?? '', + 'status' => $data['status'] ?? '', + 'id' => $data['id'] ?? '', + ); + return wp_json_encode( $summary, JSON_UNESCAPED_SLASHES ); + } + + if ( isset( $data['url'] ) && isset( $data['payload'] ) ) { + $merge_fields = $data['payload']['merge_fields'] ?? array(); + if ( is_object( $merge_fields ) ) { + $merge_fields = (array) $merge_fields; + } + $summary = array( + 'url' => $data['url'], + 'email' => $data['payload']['email_address'] ?? '', + 'status' => $data['payload']['status'] ?? '', + 'fields' => is_array( $merge_fields ) ? array_keys( $merge_fields ) : array(), + ); + return wp_json_encode( $summary, JSON_UNESCAPED_SLASHES ); + } + + $json = wp_json_encode( $data, JSON_UNESCAPED_SLASHES ); + if ( strlen( $json ) <= 1000 ) { + return $json; + } + + return substr( $json, 0, 1000 ) . '... [truncated]'; + } + + private function map_numeric_level_to_string( $numeric_level ) { + switch ( (int) $numeric_level ) { + case 1: + return 'INFO'; + case 2: + return 'DEBUG'; + case 3: + return 'WARNING'; + case 4: + return 'ERROR'; + case 5: + return 'CRITICAL'; + default: + return 'UNKNOWN'; + } + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-lite-get-fields.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-lite-get-fields.php new file mode 100644 index 0000000..8b7d7b0 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-lite-get-fields.php @@ -0,0 +1,42 @@ + 'https://chimpmatic.com', + 'pricing' => 'https://chimpmatic.com/pricing', + 'support' => 'https://chimpmatic.com/contact', + 'promo' => 'https://chimpmatic.com/almost-there', + 'home' => 'https://chimpmatic.com', + 'author' => 'https://renzojohnson.com', + ); + + private function __construct() {} + + public static function url( string $base_url, string $medium, string $content = '', string $campaign = '' ): string { + if ( empty( $base_url ) ) { + return ''; + } + $params = array( + 'utm_source' => self::PLUGIN_ID, + 'utm_medium' => self::sanitize( $medium ), + 'utm_campaign' => $campaign ? self::sanitize( $campaign ) : 'plugin_' . gmdate( 'Y' ), + ); + if ( $content ) { + $params['utm_content'] = self::sanitize( $content ); + } + return add_query_arg( $params, $base_url ); + } + + public static function docs( string $slug = '', string $content = '' ): string { + $base = self::BASE_URLS['docs']; + if ( $slug ) { + $base = trailingslashit( $base ) . ltrim( $slug, '/' ); + } + return self::url( $base, 'plugin', $content, 'docs' ); + } + + public static function upgrade( string $content = '' ): string { + return self::url( self::BASE_URLS['pricing'], 'plugin', $content, 'upgrade' ); + } + + public static function support( string $content = '' ): string { + return self::url( self::BASE_URLS['support'], 'plugin', $content, 'support' ); + } + + public static function promo( string $content = '', int $discount = 40 ): string { + $params = array( + 'u_source' => self::PLUGIN_ID, + 'u_medium' => 'banner', + 'u_campaign' => 'promo_' . $discount . 'off', + ); + if ( $content ) { + $params['u_content'] = self::sanitize( $content ); + } + return add_query_arg( $params, self::BASE_URLS['promo'] ); + } + + public static function home( string $content = '' ): string { + return self::url( self::BASE_URLS['home'], 'plugin', $content, 'brand' ); + } + + public static function author( string $content = '' ): string { + return self::url( self::BASE_URLS['author'], 'plugin', $content, 'author' ); + } + + public static function adminbar( string $destination, string $content = '' ): string { + $base = self::BASE_URLS[ $destination ] ?? self::BASE_URLS['home']; + return self::url( $base, 'adminbar', $content, $destination ); + } + + private static function sanitize( string $value ): string { + return preg_replace( '/[^a-z0-9_]/', '', str_replace( array( ' ', '-' ), '_', strtolower( trim( $value ) ) ) ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-remote-fetcher.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-remote-fetcher.php new file mode 100644 index 0000000..3f5d386 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-remote-fetcher.php @@ -0,0 +1,251 @@ + '', + 'cache_key' => 'cmatic_remote_data', + 'cache_duration' => DAY_IN_SECONDS, + 'retry_interval' => 600, // 10 minutes in seconds + 'max_retries' => 3, + 'retry_count_key' => 'cmatic_retry_count', + 'cron_hook' => 'cmatic_fetch_retry', + 'timeout' => 15, + 'fallback_data' => array(), + 'parser_callback' => null, + ); + + public function __construct( $config = array() ) { + $this->config = wp_parse_args( $config, $this->defaults ); + add_action( $this->config['cron_hook'], array( $this, 'cron_retry_fetch' ) ); + } + + public function get_data() { + $cached_data = $this->get_cache(); + + if ( false !== $cached_data ) { + return $cached_data; + } + + $fresh_data = $this->fetch_fresh_data(); + + if ( false !== $fresh_data ) { + $this->set_cache( $fresh_data ); + $this->clear_retry_schedule(); + return $fresh_data; + } + + $this->schedule_retry(); + return $this->get_fallback_data(); + } + + public function get_cache() { + return get_transient( $this->config['cache_key'] ); + } + + public function set_cache( $data ) { + return set_transient( + $this->config['cache_key'], + $data, + $this->config['cache_duration'] + ); + } + + public function clear_cache() { + return delete_transient( $this->config['cache_key'] ); + } + + private function fetch_fresh_data() { + if ( empty( $this->config['url'] ) ) { + return false; + } + + $response = wp_remote_get( + $this->config['url'], + array( + 'timeout' => $this->config['timeout'], + 'user-agent' => 'WordPress/' . get_bloginfo( 'version' ) . '; ' . home_url(), + ) + ); + + if ( is_wp_error( $response ) ) { + return false; + } + + $response_code = wp_remote_retrieve_response_code( $response ); + if ( 200 !== $response_code ) { + return false; + } + + $body = wp_remote_retrieve_body( $response ); + if ( empty( $body ) ) { + return false; + } + + return $this->parse_content( $body ); + } + + /** Parse fetched content. */ + private function parse_content( $content ) { + if ( is_callable( $this->config['parser_callback'] ) ) { + return call_user_func( $this->config['parser_callback'], $content ); + } + + $json_data = $this->parse_pricing_json( $content ); + if ( false !== $json_data ) { + return $json_data; + } + + return $this->parse_pricing_html( $content ); + } + + private function parse_pricing_json( $content ) { + $json = json_decode( $content, true ); + + if ( null === $json || ! is_array( $json ) ) { + return false; + } + + if ( ! isset( $json['regular_price'] ) || ! isset( $json['discount_percent'] ) ) { + return false; + } + + $pricing_data = array( + 'regular_price' => (int) $json['regular_price'], + 'sale_price' => isset( $json['sale_price'] ) ? (float) $json['sale_price'] : null, + 'discount_percent' => (int) $json['discount_percent'], + 'coupon_code' => isset( $json['coupon_code'] ) ? sanitize_text_field( $json['coupon_code'] ) : null, + 'last_updated' => current_time( 'mysql' ), + ); + + if ( null === $pricing_data['sale_price'] ) { + $discount_amount = $pricing_data['regular_price'] * ( $pricing_data['discount_percent'] / 100 ); + $pricing_data['sale_price'] = $pricing_data['regular_price'] - $discount_amount; + } + + if ( null === $pricing_data['coupon_code'] ) { + $pricing_data['coupon_code'] = 'NOW' . $pricing_data['discount_percent']; + } + + $pricing_data['formatted'] = sprintf( + '$%d → $%s • Save %d%%', + $pricing_data['regular_price'], + number_format( $pricing_data['sale_price'], 2 ), + $pricing_data['discount_percent'] + ); + + return $pricing_data; + } + + private function parse_pricing_html( $html ) { + $pricing_data = array( + 'regular_price' => null, + 'sale_price' => null, + 'discount_percent' => null, + 'coupon_code' => null, + 'formatted' => null, + 'last_updated' => current_time( 'mysql' ), + ); + + if ( preg_match( '/Single\s+Site[^$]*\$(\d+)\/year/i', $html, $matches ) ) { + $pricing_data['regular_price'] = (int) $matches[1]; + } + + if ( preg_match( '/(\d+)%\s+Off/i', $html, $matches ) ) { + $pricing_data['discount_percent'] = (int) $matches[1]; + } + + if ( preg_match( '/coupon\s+code\s+["\']([A-Z0-9]+)["\']/i', $html, $matches ) ) { + $pricing_data['coupon_code'] = sanitize_text_field( $matches[1] ); + } + + if ( $pricing_data['regular_price'] && $pricing_data['discount_percent'] ) { + $discount_amount = $pricing_data['regular_price'] * ( $pricing_data['discount_percent'] / 100 ); + $pricing_data['sale_price'] = $pricing_data['regular_price'] - $discount_amount; + } + + if ( $pricing_data['regular_price'] && $pricing_data['sale_price'] && $pricing_data['discount_percent'] ) { + $pricing_data['formatted'] = sprintf( + '$%d → $%s • Save %d%%', + $pricing_data['regular_price'], + number_format( $pricing_data['sale_price'], 2 ), + $pricing_data['discount_percent'] + ); + } + + if ( null === $pricing_data['regular_price'] ) { + return false; + } + + return $pricing_data; + } + + private function get_fallback_data() { + if ( ! empty( $this->config['fallback_data'] ) ) { + return $this->config['fallback_data']; + } + + return array( + 'regular_price' => 39, + 'sale_price' => 29.25, + 'discount_percent' => 25, + 'coupon_code' => 'NOW25', + 'formatted' => '$39 → $29.25 • Save 25%', + 'last_updated' => null, + ); + } + + private function schedule_retry() { + $retry_count = (int) get_option( $this->config['retry_count_key'], 0 ); + + if ( $retry_count >= $this->config['max_retries'] ) { + return; + } + + update_option( $this->config['retry_count_key'], $retry_count + 1 ); + + if ( ! wp_next_scheduled( $this->config['cron_hook'] ) ) { + wp_schedule_single_event( + time() + $this->config['retry_interval'], + $this->config['cron_hook'] + ); + } + } + + public function cron_retry_fetch() { + $fresh_data = $this->fetch_fresh_data(); + + if ( false !== $fresh_data ) { + $this->set_cache( $fresh_data ); + $this->clear_retry_schedule(); + } else { + $this->schedule_retry(); + } + } + + private function clear_retry_schedule() { + $timestamp = wp_next_scheduled( $this->config['cron_hook'] ); + if ( $timestamp ) { + wp_unschedule_event( $timestamp, $this->config['cron_hook'] ); + } + + delete_option( $this->config['retry_count_key'] ); + } + + public function clear_all() { + $this->clear_cache(); + $this->clear_retry_schedule(); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-utils.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-utils.php new file mode 100644 index 0000000..b0d5e49 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/includes/utils/class-cmatic-utils.php @@ -0,0 +1,89 @@ + 'wpcf7_contact_form', + 'posts_per_page' => 1, + 'orderby' => 'ID', + 'order' => 'DESC', + 'post_status' => 'publish', + 'fields' => 'ids', + ) + ); + + return ! empty( $forms ) ? (int) $forms[0] : null; + } + + public static function get_days_since( int $timestamp ): int { + $datetime_now = new \DateTime( 'now' ); + $datetime_from = new \DateTime( '@' . $timestamp ); + + $diff = date_diff( $datetime_now, $datetime_from ); + + return (int) $diff->format( '%a' ); + } + + private function __construct() {} + + private function __clone() {} + + public function __wakeup() { + throw new \Exception( 'Cannot unserialize singleton' ); + } +} diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/languages/readme.txt b/html/wp-content/plugins/contact-form-7-mailchimp-extension/languages/readme.txt new file mode 100644 index 0000000..a07c1a0 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/languages/readme.txt @@ -0,0 +1,9 @@ +== For Translators == + +Note: this folder contains MO files and POT file only. If you are looking for PO file, you can download it from here: + +URL Coming soon... + +If you have created your own translation, or have an update of an existing one, please send it to Renzo Johnson so that I can bundle it into the next release of Contact Form 7 Campaign Monitor Ext. + +Thank you. \ No newline at end of file diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/license.txt b/html/wp-content/plugins/contact-form-7-mailchimp-extension/license.txt new file mode 100644 index 0000000..bf669df --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/license.txt @@ -0,0 +1,355 @@ +Chimpmatic Lite +Copyright (C) 2010–2025 Chimpmatic + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, see https://www.gnu.org/licenses/gpl-2.0.html + +----------------------------------------------------------------------- +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS FOR COPYING, + DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see https://www.gnu.org/licenses/gpl-2.0.html + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/readme.txt b/html/wp-content/plugins/contact-form-7-mailchimp-extension/readme.txt new file mode 100644 index 0000000..c8df8cc --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/readme.txt @@ -0,0 +1,225 @@ +=== Connect Contact Form 7 and Mailchimp === +Contributors: rnzo, chimpmatic +Donate link: https://bit.ly/2HdTzmO +Tags: contact form 7 mailchimp, cf7 mailchimp, mailchimp, mailchimp integration, contact form 7 +Requires at least: 6.4 +Tested up to: 6.9 +Stable tag: 0.9.76 +License: GPLv2 or later +License URI: https://www.gnu.org/licenses/gpl-2.0.html + +Connect Contact Form 7 to Mailchimp. Automatically sync form submissions to your Mailchimp audiences with merge field mapping, double opt-in, and opt-in checkbox support. + +== Description == + +**Chimpmatic Lite** is the easiest way to connect **Contact Form 7 to Mailchimp**. When a visitor submits your CF7 form, their information is automatically added to your Mailchimp audience using the Mailchimp API v3. + +Unlike heavyweight form builders, Chimpmatic is a specialist CF7-to-Mailchimp integration. It does one thing and does it well: syncing your Contact Form 7 submissions directly to Mailchimp. + += Why Chimpmatic? = + +* **Built specifically for Contact Form 7** - not a generic form connector +* **Lightweight** - no bloat, no extra form builders, no overhead +* **Mailchimp API v3** - uses the latest official Mailchimp API +* **50,000+ active installs** - trusted by WordPress sites worldwide + += Free Features = + +* Connect any Contact Form 7 form to a Mailchimp audience +* Map form fields to Mailchimp merge fields (FNAME, LNAME, etc.) +* Use a **different Mailchimp API key** per contact form +* Use a **different mailing list** per contact form +* **Single opt-in** or **double opt-in** support +* **Opt-in checkbox** - let visitors choose to subscribe +* Unlimited contact forms +* Works with any Contact Form 7 form layout + += Premium Features (Chimpmatic PRO) = + +Upgrade to [Chimpmatic PRO](https://chimpmatic.com/pro) for advanced Mailchimp integration: + +* **Mailchimp Tags** - automatically tag subscribers from form submissions +* **Mailchimp Groups** - assign subscribers to interest groups +* **Unlimited custom merge fields** - map any CF7 field to Mailchimp +* **GDPR consent checkbox** - built-in compliance for email marketing +* **Birthday field support** - sync date fields to Mailchimp +* **Email verification** - validate emails before subscribing +* **Unsubscribe, archive, and delete** subscriber management +* **Priority support** - direct help from the developer + +[Learn more about Chimpmatic PRO](https://chimpmatic.com/pro) + += Requirements = + +1. WordPress 6.4 or higher +2. Contact Form 7 (5.0 or higher) +3. PHP 7.4 or higher +4. A free or paid Mailchimp account + += Support = + +* [Documentation & Help Center](https://chimpmatic.com/help) +* [Getting Started Guide](https://chimpmatic.com/connect-contact-form-7-with-mailchimp) +* [Bug Reports & Feature Requests](https://chimpmatic.com/contact) + +== Installation == + +1. Install the plugin from the WordPress Plugin Directory, or upload the plugin folder to `/wp-content/plugins/`. +2. Activate the plugin through the **Plugins** menu in WordPress. +3. Edit any Contact Form 7 form - you will see a new **Mailchimp** tab. +4. Enter your Mailchimp API key, select your audience, and map your fields. + += How to Find Your Mailchimp API Key = + +1. Log in to your Mailchimp account. +2. Click your profile icon and select **Account & billing**. +3. Go to **Extras** > **API Keys**. +4. Click **Create A Key** and copy the key. +5. Paste it into the Mailchimp tab in your Contact Form 7 editor. + +For a detailed walkthrough with screenshots, see our [Mailchimp API Key Guide](https://chimpmatic.com/how-to-get-your-mailchimp-api-key). + +== Frequently Asked Questions == + += How do I connect Contact Form 7 to Mailchimp? = + +After installing Chimpmatic Lite, edit any Contact Form 7 form. Click the **Mailchimp** tab, enter your API key, select your Mailchimp audience, and map your form fields to Mailchimp merge tags. Submissions will sync automatically. + +See the full [setup guide](https://chimpmatic.com/connect-contact-form-7-with-mailchimp). + += How do I find my Mailchimp API key? = + +Log in to Mailchimp, click your profile icon, go to Account & billing > Extras > API Keys, and click Create A Key. Copy the key and paste it into the Chimpmatic settings in your CF7 form editor. + += Can I use different Mailchimp lists for different forms? = + +Yes. Each Contact Form 7 form has its own Mailchimp tab where you can set a different API key, audience, and field mapping. + += Does this support double opt-in? = + +Yes. You can choose between single opt-in (subscriber is added immediately) or double opt-in (Mailchimp sends a confirmation email first). This is configured per form. + += Can I add an opt-in checkbox? = + +Yes. Chimpmatic Lite includes an opt-in checkbox feature so visitors can choose whether to subscribe to your Mailchimp list when submitting the form. + += What is the difference between Mailchimp tags and groups? = + +Tags are labels you assign to subscribers for internal organization (e.g., "From Contact Page"). Groups are subscriber-facing categories that let people choose their interests. Both are available in [Chimpmatic PRO](https://chimpmatic.com/pricing). + += How do I add GDPR consent to Contact Form 7? = + +GDPR consent checkbox support is available in [Chimpmatic PRO](https://chimpmatic.com/pro). It adds a required opt-in checkbox that maps to Mailchimp's GDPR marketing permission fields. + += Contact Form 7 not sending to Mailchimp? = + +Common fixes: (1) Check your API key is correct and not expired. (2) Verify the email field is mapped properly. (3) Check for trailing spaces in the API key. (4) Make sure your Mailchimp audience is not archived. See our [troubleshooting guide](https://chimpmatic.com/connect-contact-form-7-with-mailchimp). + += Does this work with Mailchimp merge fields? = + +Yes. You can map any Contact Form 7 field to Mailchimp merge fields like FNAME, LNAME, ADDRESS, and more. For unlimited custom merge fields, upgrade to [Chimpmatic PRO](https://chimpmatic.com/pro). + +== Screenshots == + +1. Mailchimp tab in the Contact Form 7 editor - enter your API key and select your audience. +2. Field mapping interface - connect your CF7 form fields to Mailchimp merge fields. + +== Changelog == + +For the full changelog with details, see [Release History](https://renzojohnson.com/changelog). + += 0.9.75 = + +[Version 0.9.75 release notes](https://renzojohnson.com/changelog#0.9.75) + += 0.9.73 = + +[Version 0.9.73 release notes](https://renzojohnson.com/changelog#0.9.73) + += 0.9.22 = + +[Version 0.9.22 release notes](https://renzojohnson.com/changelog#0.9.22) + += 0.8.01 = + +[Version 0.8.01 release notes](https://renzojohnson.com/changelog#0.8.01) + += 0.7.50 = + +[Version 0.7.50 release notes](https://renzojohnson.com/changelog#0.7.50) + += 0.7.01 = + +[Version 0.7.01 release notes](https://renzojohnson.com/changelog#0.7.01) + += 0.6.10 = + +[Version 0.6.10 release notes](https://renzojohnson.com/changelog#0.6.10) + += 0.5.64 = + +[Version 0.5.64 release notes](https://renzojohnson.com/changelog#0.5.64) + += 0.5.01 = + +[Version 0.5.01 release notes](https://renzojohnson.com/changelog#0.5.01) + += 0.4.60 = + +[Version 0.4.60 release notes](https://renzojohnson.com/changelog#0.4.60) + += 0.4.43 = + +[Version 0.4.43 release notes](https://renzojohnson.com/changelog#0.4.43) + += 0.4.01 = + +[Version 0.4.01 release notes](https://renzojohnson.com/changelog#0.4.01) + += 0.3.50 = + +[Version 0.3.50 release notes](https://renzojohnson.com/changelog#0.3.50) + += 0.3.40 = + +[Version 0.3.40 release notes](https://renzojohnson.com/changelog#0.3.40) + += 0.3.20 = + +[Version 0.3.20 release notes](https://renzojohnson.com/changelog#0.3.20) + += 0.3.10 = + +[Version 0.3.10 release notes](https://renzojohnson.com/changelog#0.3.10) + += 0.3.01 = + +[Version 0.3.01 release notes](https://renzojohnson.com/changelog#0.3.01) + += 0.2.30 = + +[Version 0.2.30 release notes](https://renzojohnson.com/changelog#0.2.30) + += 0.2.20 = + +[Version 0.2.20 release notes](https://renzojohnson.com/changelog#0.2.20) + += 0.2.15 = + +[Version 0.2.15 release notes](https://renzojohnson.com/changelog#0.2.15) + += 0.2.10 = + +[Version 0.2.10 release notes](https://renzojohnson.com/changelog#0.2.10) + += 0.2.5 = + +[Version 0.2.5 release notes](https://renzojohnson.com/changelog#0.2.5) + += 0.1.5 = + +[Version 0.1.5 release notes](https://renzojohnson.com/changelog#0.1.5) + += 0.1.2 = + +[Version 0.1.2 release notes](https://renzojohnson.com/changelog#0.1.2) \ No newline at end of file diff --git a/html/wp-content/plugins/contact-form-7-mailchimp-extension/uninstall.php b/html/wp-content/plugins/contact-form-7-mailchimp-extension/uninstall.php new file mode 100644 index 0000000..04c23a9 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7-mailchimp-extension/uninstall.php @@ -0,0 +1,29 @@ +query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s", 'cf7_mch_%' ) ); diff --git a/html/wp-content/plugins/contact-form-7/admin/admin.php b/html/wp-content/plugins/contact-form-7/admin/admin.php new file mode 100644 index 0000000..74162d7 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/admin.php @@ -0,0 +1,759 @@ +service_exists() ) { + $integration = add_submenu_page( 'wpcf7', + __( 'Integration with External API', 'contact-form-7' ), + __( 'Integration', 'contact-form-7' ) + . wpcf7_admin_menu_change_notice( 'wpcf7-integration' ), + 'wpcf7_manage_integration', + 'wpcf7-integration', + 'wpcf7_admin_integration_page' + ); + + add_action( 'load-' . $integration, 'wpcf7_load_integration_page', 10, 0 ); + } +} + + +function wpcf7_admin_menu_change_notice( $menu_slug = '' ) { + $counts = apply_filters( 'wpcf7_admin_menu_change_notice', + array( + 'wpcf7' => 0, + 'wpcf7-new' => 0, + 'wpcf7-integration' => 0, + ) + ); + + if ( empty( $menu_slug ) ) { + $count = absint( array_sum( $counts ) ); + } elseif ( isset( $counts[$menu_slug] ) ) { + $count = absint( $counts[$menu_slug] ); + } else { + $count = 0; + } + + if ( $count ) { + return sprintf( + ' %2$s', + $count, + esc_html( number_format_i18n( $count ) ) + ); + } + + return ''; +} + + +add_action( + 'admin_enqueue_scripts', + 'wpcf7_admin_enqueue_scripts', + 10, 1 +); + +function wpcf7_admin_enqueue_scripts( $hook_suffix ) { + if ( false === strpos( $hook_suffix, 'wpcf7' ) ) { + return; + } + + wp_enqueue_style( 'contact-form-7-admin', + wpcf7_plugin_url( 'admin/includes/css/styles.css' ), + array(), WPCF7_VERSION, 'all' + ); + + if ( wpcf7_is_rtl() ) { + wp_enqueue_style( 'contact-form-7-admin-rtl', + wpcf7_plugin_url( 'admin/includes/css/styles-rtl.css' ), + array(), WPCF7_VERSION, 'all' + ); + } + + $assets = include wpcf7_plugin_path( 'admin/includes/js/index.asset.php' ); + + $assets = wp_parse_args( $assets, array( + 'dependencies' => array(), + 'version' => WPCF7_VERSION, + ) ); + + wp_enqueue_script( 'wpcf7-admin', + wpcf7_plugin_url( 'admin/includes/js/index.js' ), + $assets['dependencies'], + $assets['version'], + array( 'in_footer' => true ) + ); + + wp_set_script_translations( 'wpcf7-admin', 'contact-form-7' ); + + $wpcf7_obj = array( + 'apiSettings' => array( + 'root' => sanitize_url( rest_url( 'contact-form-7/v1' ) ), + 'namespace' => 'contact-form-7/v1', + ), + ); + + $post = wpcf7_get_current_contact_form(); + + if ( $post ) { + $wpcf7_obj = array_merge( $wpcf7_obj, array( + 'nonce' => array( + 'save' => wp_create_nonce( + sprintf( + 'wpcf7-save-contact-form_%s', + $post->initial() ? -1 : $post->id() + ) + ), + 'copy' => wp_create_nonce( + sprintf( + 'wpcf7-copy-contact-form_%s', + $post->initial() ? -1 : $post->id() + ) + ), + 'delete' => wp_create_nonce( + sprintf( + 'wpcf7-delete-contact-form_%s', + $post->initial() ? -1 : $post->id() + ) + ), + ), + 'configValidator' => array( + 'errors' => array(), + 'docUrl' => WPCF7_ConfigValidator::get_doc_link(), + ), + ) ); + + if ( + current_user_can( 'wpcf7_edit_contact_form', $post->id() ) and + wpcf7_validate_configuration() + ) { + $config_validator = new WPCF7_ConfigValidator( $post ); + $config_validator->restore(); + + $wpcf7_obj['configValidator'] = array_merge( + $wpcf7_obj['configValidator'], + array( + 'errors' => $config_validator->collect_error_messages( + array( 'decodes_html_entities' => true ) + ), + ) + ); + } + } + + wp_add_inline_script( 'wpcf7-admin', + sprintf( + 'var wpcf7 = %s;', + wp_json_encode( $wpcf7_obj, JSON_PRETTY_PRINT ) + ), + 'before' + ); +} + + +add_filter( + 'set_screen_option_wpcf7_contact_forms_per_page', + static function ( $result, $option, $value ) { + $wpcf7_screens = array( + 'wpcf7_contact_forms_per_page', + ); + + if ( in_array( $option, $wpcf7_screens, true ) ) { + $result = $value; + } + + return $result; + }, + 10, 3 +); + + +function wpcf7_load_contact_form_admin() { + global $plugin_page; + + $action = wpcf7_current_action(); + + do_action( 'wpcf7_admin_load', + wpcf7_superglobal_get( 'page' ), + $action + ); + + if ( 'save' === $action ) { + $id = wpcf7_superglobal_post( 'post_ID', '-1' ); + + check_admin_referer( 'wpcf7-save-contact-form_' . $id ); + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $id ) ) { + wp_die( + esc_html( __( 'You are not allowed to edit this item.', 'contact-form-7' ) ) + ); + } + + $contact_form = wpcf7_save_contact_form( + array_merge( + wp_unslash( $_REQUEST ), + array( + 'id' => $id, + 'title' => wpcf7_superglobal_post( 'post_title', null ), + 'locale' => wpcf7_superglobal_post( 'wpcf7-locale', null ), + 'form' => wpcf7_superglobal_post( 'wpcf7-form', '' ), + 'mail' => wpcf7_superglobal_post( 'wpcf7-mail', array() ), + 'mail_2' => wpcf7_superglobal_post( 'wpcf7-mail-2', array() ), + 'messages' => wpcf7_superglobal_post( 'wpcf7-messages', array() ), + 'additional_settings' => wpcf7_superglobal_post( 'wpcf7-additional-settings', '' ), + ) + ) + ); + + if ( $contact_form and wpcf7_validate_configuration() ) { + $config_validator = new WPCF7_ConfigValidator( $contact_form ); + $config_validator->validate(); + $config_validator->save(); + } + + $query = array( + 'post' => $contact_form ? $contact_form->id() : 0, + 'active-tab' => wpcf7_canonicalize_name( + wpcf7_superglobal_post( 'active-tab' ) + ), + ); + + if ( ! $contact_form ) { + $query['message'] = 'failed'; + } elseif ( -1 === (int) $id ) { + $query['message'] = 'created'; + } else { + $query['message'] = 'saved'; + } + + $redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) ); + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'copy' === $action ) { + $id = absint( $_POST['post_ID'] ?? $_REQUEST['post'] ?? '' ); + + check_admin_referer( 'wpcf7-copy-contact-form_' . $id ); + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $id ) ) { + wp_die( + esc_html( __( 'You are not allowed to edit this item.', 'contact-form-7' ) ) + ); + } + + $query = array(); + + if ( $contact_form = wpcf7_contact_form( $id ) ) { + $new_contact_form = $contact_form->copy(); + $new_contact_form->save(); + + $query['post'] = $new_contact_form->id(); + $query['message'] = 'created'; + } + + $redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) ); + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'delete' === $action ) { + $nonce_action = 'bulk-posts'; + + if ( + $post_id = wpcf7_superglobal_post( 'post_ID' ) or + ! is_array( $post_id = wpcf7_superglobal_request( 'post', array() ) ) + ) { + $nonce_action = sprintf( 'wpcf7-delete-contact-form_%s', $post_id ); + } + + check_admin_referer( $nonce_action ); + + $posts = array_filter( (array) $post_id ); + + $deleted = 0; + + foreach ( $posts as $post ) { + $post = WPCF7_ContactForm::get_instance( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( ! current_user_can( 'wpcf7_delete_contact_form', $post->id() ) ) { + wp_die( + esc_html( __( 'You are not allowed to delete this item.', 'contact-form-7' ) ) + ); + } + + if ( ! $post->delete() ) { + wp_die( + esc_html( __( 'Error in deleting.', 'contact-form-7' ) ) + ); + } + + $deleted += 1; + } + + $query = array(); + + if ( ! empty( $deleted ) ) { + $query['message'] = 'deleted'; + } + + $redirect_to = add_query_arg( $query, menu_page_url( 'wpcf7', false ) ); + + wp_safe_redirect( $redirect_to ); + exit(); + } + + $post = null; + + if ( 'wpcf7-new' === $plugin_page ) { + $post = WPCF7_ContactForm::get_template( array( + 'locale' => wpcf7_superglobal_get( 'locale', null ), + ) ); + } elseif ( $post_id = wpcf7_superglobal_get( 'post' ) ) { + $post = WPCF7_ContactForm::get_instance( $post_id ); + } + + $current_screen = get_current_screen(); + + $help_tabs = new WPCF7_Help_Tabs( $current_screen ); + + if ( $post and current_user_can( 'wpcf7_edit_contact_form', $post->id() ) ) { + $help_tabs->set_help_tabs( 'edit' ); + } else { + $help_tabs->set_help_tabs( 'list' ); + + if ( ! class_exists( 'WPCF7_Contact_Form_List_Table' ) ) { + require_once WPCF7_PLUGIN_DIR . '/admin/includes/class-contact-forms-list-table.php'; + } + + add_filter( + 'manage_' . $current_screen->id . '_columns', + array( 'WPCF7_Contact_Form_List_Table', 'define_columns' ), + 10, 0 + ); + + add_screen_option( 'per_page', array( + 'default' => 20, + 'option' => 'wpcf7_contact_forms_per_page', + ) ); + } +} + + +function wpcf7_admin_management_page() { + if ( $post = wpcf7_get_current_contact_form() ) { + $post_id = $post->initial() ? -1 : $post->id(); + + require_once WPCF7_PLUGIN_DIR . '/admin/includes/editor.php'; + require_once WPCF7_PLUGIN_DIR . '/admin/edit-contact-form.php'; + return; + } + + if ( + 'validate' === wpcf7_current_action() and + wpcf7_validate_configuration() and + current_user_can( 'wpcf7_edit_contact_forms' ) + ) { + wpcf7_admin_bulk_validate_page(); + return; + } + + $list_table = new WPCF7_Contact_Form_List_Table(); + $list_table->prepare_items(); + + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'method' => true, + ), + ) ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + 'id' => 'wpcf7-contact-form-list-table', + ) ); + + $formatter->append_start_tag( 'h1', array( + 'class' => 'wp-heading-inline', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Contact Forms', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h1' ); + + if ( current_user_can( 'wpcf7_edit_contact_forms' ) ) { + $formatter->append_preformatted( + wpcf7_link( + menu_page_url( 'wpcf7-new', false ), + __( 'Add Contact Form', 'contact-form-7' ), + array( 'class' => 'page-title-action' ) + ) + ); + } + + if ( $search_keyword = wpcf7_superglobal_request( 's' ) ) { + $formatter->append_start_tag( 'span', array( + 'class' => 'subtitle', + ) ); + + $formatter->append_preformatted( + sprintf( + /* translators: %s: Search query. */ + __( 'Search results for: %s', 'contact-form-7' ), + esc_html( $search_keyword ) + ) + ); + + $formatter->end_tag( 'span' ); + } + + $formatter->append_start_tag( 'hr', array( + 'class' => 'wp-header-end', + ) ); + + $formatter->call_user_func( static function () { + do_action( 'wpcf7_admin_warnings', + 'wpcf7', wpcf7_current_action(), null + ); + + wpcf7_welcome_panel(); + + do_action( 'wpcf7_admin_notices', + 'wpcf7', wpcf7_current_action(), null + ); + } ); + + $formatter->append_start_tag( 'form', array( + 'method' => 'get', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'name' => 'page', + 'value' => wpcf7_superglobal_request( 'page' ), + ) ); + + $formatter->call_user_func( static function () use ( $list_table ) { + $list_table->search_box( + __( 'Search Contact Forms', 'contact-form-7' ), + 'wpcf7-contact' + ); + + $list_table->display(); + } ); + + $formatter->print(); +} + + +function wpcf7_admin_add_new_page() { + $post = wpcf7_get_current_contact_form(); + + if ( ! $post ) { + $post = WPCF7_ContactForm::get_template(); + } + + $post_id = -1; + + require_once WPCF7_PLUGIN_DIR . '/admin/includes/editor.php'; + require_once WPCF7_PLUGIN_DIR . '/admin/edit-contact-form.php'; +} + + +function wpcf7_load_integration_page() { + do_action( 'wpcf7_admin_load', + wpcf7_superglobal_get( 'page' ), + wpcf7_current_action() + ); + + $integration = WPCF7_Integration::get_instance(); + + if ( + $service_name = wpcf7_superglobal_request( 'service' ) and + $integration->service_exists( $service_name ) + ) { + $service = $integration->get_service( $service_name ); + $service->load( wpcf7_current_action() ); + } + + $help_tabs = new WPCF7_Help_Tabs( get_current_screen() ); + $help_tabs->set_help_tabs( 'integration' ); +} + + +function wpcf7_admin_integration_page() { + $integration = WPCF7_Integration::get_instance(); + + $service_name = wpcf7_superglobal_request( 'service' ); + $service = null; + + if ( $service_name and $integration->service_exists( $service_name ) ) { + $service = $integration->get_service( $service_name ); + } + + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'action' => true, + 'method' => true, + ), + ) ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + 'id' => 'wpcf7-integration', + ) ); + + $formatter->append_start_tag( 'h1' ); + + $formatter->append_preformatted( + esc_html( __( 'Integration with External API', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h1' ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_preformatted( + sprintf( + /* translators: %s: URL to support page about integration with external APIs */ + __( 'You can expand the possibilities of your contact forms by integrating them with external services. For details, see Integration with external APIs.', 'contact-form-7' ), + __( 'https://contactform7.com/integration-with-external-apis/', 'contact-form-7' ) + ) + ); + + $formatter->end_tag( 'p' ); + + $formatter->call_user_func( + static function () use ( $integration, $service, $service_name ) { + do_action( 'wpcf7_admin_warnings', + 'wpcf7-integration', wpcf7_current_action(), $service + ); + + do_action( 'wpcf7_admin_notices', + 'wpcf7-integration', wpcf7_current_action(), $service + ); + + if ( $service ) { + $message = wpcf7_superglobal_request( 'message' ); + $service->admin_notice( $message ); + + $integration->list_services( array( + 'include' => $service_name, + ) ); + } else { + $integration->list_services(); + } + } + ); + + $formatter->print(); +} + + +add_action( 'wpcf7_admin_notices', 'wpcf7_admin_updated_message', 10, 3 ); + +function wpcf7_admin_updated_message( $page, $action, $object ) { + if ( ! in_array( $page, array( 'wpcf7', 'wpcf7-new' ), true ) ) { + return; + } + + $message_type = wpcf7_superglobal_request( 'message' ); + + if ( ! $message_type ) { + return; + } + + $notice_type = 'success'; + + if ( 'created' === $message_type ) { + $message = __( 'Contact form created.', 'contact-form-7' ); + } elseif ( 'saved' === $message_type ) { + $message = __( 'Contact form saved.', 'contact-form-7' ); + } elseif ( 'deleted' === $message_type ) { + $message = __( 'Contact form deleted.', 'contact-form-7' ); + } elseif ( 'failed' === $message_type ) { + $notice_type = 'error'; + $message = __( 'There was an error saving the contact form.', 'contact-form-7' ); + } elseif ( 'validated' === $message_type ) { + $bulk_validate = WPCF7::get_option( 'bulk_validate', array() ); + $count_invalid = absint( $bulk_validate['count_invalid'] ?? 0 ); + + if ( $count_invalid ) { + $notice_type = 'warning'; + + $message = sprintf( + /* translators: %s: number of contact forms */ + _n( + 'Configuration validation completed. %s invalid contact form was found.', + 'Configuration validation completed. %s invalid contact forms were found.', + $count_invalid, 'contact-form-7' + ), + number_format_i18n( $count_invalid ) + ); + } else { + $message = __( 'Configuration validation completed. No invalid contact form was found.', 'contact-form-7' ); + } + } + + if ( ! empty( $message ) ) { + wp_admin_notice( + $message, + array( 'type' => $notice_type ) + ); + } +} + + +add_filter( 'plugin_action_links', 'wpcf7_plugin_action_links', 10, 2 ); + +function wpcf7_plugin_action_links( $links, $file ) { + if ( WPCF7_PLUGIN_BASENAME !== $file ) { + return $links; + } + + if ( ! current_user_can( 'wpcf7_read_contact_forms' ) ) { + return $links; + } + + $settings_link = wpcf7_link( + menu_page_url( 'wpcf7', false ), + __( 'Settings', 'contact-form-7' ) + ); + + array_unshift( $links, $settings_link ); + + return $links; +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_old_wp_version_error', 10, 3 ); + +function wpcf7_old_wp_version_error( $page, $action, $object ) { + $wp_version = get_bloginfo( 'version' ); + + if ( version_compare( $wp_version, WPCF7_REQUIRED_WP_VERSION, '<' ) ) { + wp_admin_notice( + sprintf( + /* translators: 1: version of Contact Form 7, 2: version of WordPress, 3: URL */ + __( 'Contact Form 7 %1$s requires WordPress %2$s or higher. Please update WordPress first.', 'contact-form-7' ), + WPCF7_VERSION, + WPCF7_REQUIRED_WP_VERSION, + admin_url( 'update-core.php' ) + ), + array( 'type' => 'warning' ) + ); + } +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_not_allowed_to_edit', 10, 3 ); + +function wpcf7_not_allowed_to_edit( $page, $action, $object ) { + if ( $object instanceof WPCF7_ContactForm ) { + $contact_form = $object; + } else { + return; + } + + if ( ! current_user_can( 'wpcf7_edit_contact_form', $contact_form->id() ) ) { + wp_admin_notice( + __( 'You are not allowed to edit this contact form.', 'contact-form-7' ), + array( 'type' => 'warning' ) + ); + } +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_ctct_deprecated_warning', 10, 3 ); + +function wpcf7_ctct_deprecated_warning( $page, $action, $object ) { + $service = WPCF7_ConstantContact::get_instance(); + + if ( $service->is_active() ) { + wp_admin_notice( + __( 'Contact Form 7 has completed the removal of the Constant Contact integration. We recommend Brevo as an alternative.', 'contact-form-7' ), + array( 'type' => 'warning' ) + ); + } +} + + +add_action( 'wpcf7_admin_warnings', 'wpcf7_captcha_future_warning', 10, 3 ); + +function wpcf7_captcha_future_warning( $page, $action, $object ) { + $service = WPCF7_RECAPTCHA::get_instance(); + + if ( $service->is_active() ) { + wp_admin_notice( + __( 'Attention reCAPTCHA users: Google attempts to make all reCAPTCHA users migrate to reCAPTCHA Enterprise, meaning Google charges you for API calls exceeding the free tier. Contact Form 7 supports Cloudflare Turnstile, and we recommend it unless you have reasons to use reCAPTCHA.', 'contact-form-7' ), + array( 'type' => 'warning' ) + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7/admin/edit-contact-form.php b/html/wp-content/plugins/contact-form-7/admin/edit-contact-form.php new file mode 100644 index 0000000..e63c20b --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/edit-contact-form.php @@ -0,0 +1,484 @@ +', + wpcf7_format_atts( array( + 'type' => 'submit', + 'class' => 'button-primary', + 'name' => 'wpcf7-save', + 'value' => __( 'Save', 'contact-form-7' ), + ) ) +); + +$formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'method' => true, + 'action' => true, + 'id' => true, + 'class' => true, + 'disabled' => true, + ), + ) ), +) ); + +$formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + 'id' => 'wpcf7-contact-form-editor', +) ); + +$formatter->append_start_tag( 'h1', array( + 'class' => 'wp-heading-inline', +) ); + +$formatter->append_preformatted( + esc_html( $post->initial() + ? __( 'Add Contact Form', 'contact-form-7' ) + : __( 'Edit Contact Form', 'contact-form-7' ) + ) +); + +$formatter->end_tag( 'h1' ); + +if ( ! $post->initial() and current_user_can( 'wpcf7_edit_contact_forms' ) ) { + $formatter->append_whitespace(); + + $formatter->append_preformatted( + wpcf7_link( + menu_page_url( 'wpcf7-new', false ), + __( 'Add Contact Form', 'contact-form-7' ), + array( 'class' => 'page-title-action' ) + ) + ); +} + +$formatter->append_start_tag( 'hr', array( + 'class' => 'wp-header-end', +) ); + +$formatter->call_user_func( static function () use ( $post ) { + do_action( 'wpcf7_admin_warnings', + $post->initial() ? 'wpcf7-new' : 'wpcf7', + wpcf7_current_action(), + $post + ); + + do_action( 'wpcf7_admin_notices', + $post->initial() ? 'wpcf7-new' : 'wpcf7', + wpcf7_current_action(), + $post + ); +} ); + +if ( $post ) { + $formatter->append_start_tag( 'form', array( + 'method' => 'post', + 'action' => esc_url( add_query_arg( + array( 'post' => $post_id ), + menu_page_url( 'wpcf7', false ) + ) ), + 'id' => 'wpcf7-admin-form-element', + 'disabled' => ! current_user_can( 'wpcf7_edit_contact_form', $post_id ), + ) ); + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $formatter->call_user_func( static function () use ( $post_id ) { + wp_nonce_field( 'wpcf7-save-contact-form_' . $post_id ); + } ); + } + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'post_ID', + 'name' => 'post_ID', + 'value' => (int) $post_id, + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'wpcf7-locale', + 'name' => 'wpcf7-locale', + 'value' => $post->locale(), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'hiddenaction', + 'name' => 'action', + 'value' => 'save', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'id' => 'active-tab', + 'name' => 'active-tab', + 'value' => wpcf7_superglobal_get( 'active-tab' ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'poststuff', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'post-body', + 'class' => 'metabox-holder columns-2 wp-clearfix', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'post-body-content', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'titlediv', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'titlewrap', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'name' => 'post_title', + 'value' => $post->initial() ? '' : $post->title(), + 'id' => 'title', + 'spellcheck' => 'true', + 'autocomplete' => 'off', + 'disabled' => ! current_user_can( 'wpcf7_edit_contact_form', $post_id ), + 'placeholder' => __( 'Enter title here', 'contact-form-7' ), + 'aria-label' => __( 'Enter title here', 'contact-form-7' ), + ) ); + + $formatter->end_tag( 'div' ); // #titlewrap + + $formatter->append_start_tag( 'div', array( + 'class' => 'inside', + ) ); + + if ( ! $post->initial() ) { + if ( $shortcode = $post->shortcode() ) { + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => 'wpcf7-shortcode', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Copy this shortcode and paste it into your post, page, or text widget content:', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'span', array( + 'class' => 'shortcode wp-ui-highlight', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => 'wpcf7-shortcode', + 'readonly' => true, + 'class' => 'large-text code selectable', + 'value' => $shortcode, + ) ); + + $formatter->end_tag( 'p' ); + } + + if ( $shortcode = $post->shortcode( array( 'use_old_format' => true ) ) ) { + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => 'wpcf7-shortcode-old', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'You can also use this old-style shortcode:', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'span', array( + 'class' => 'shortcode old', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => 'wpcf7-shortcode-old', + 'readonly' => true, + 'class' => 'large-text code selectable', + 'value' => $shortcode, + ) ); + + $formatter->end_tag( 'p' ); + } + } + + $formatter->end_tag( 'div' ); // .inside + $formatter->end_tag( 'div' ); // #titlediv + $formatter->end_tag( 'div' ); // #post-body-content + + $formatter->append_start_tag( 'div', array( + 'id' => 'postbox-container-1', + 'class' => 'postbox-container', + ) ); + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $formatter->append_start_tag( 'section', array( + 'id' => 'submitdiv', + 'class' => 'postbox', + ) ); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Status', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'inside', + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'submitbox', + 'id' => 'submitpost', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'minor-publishing-actions', + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'hidden', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'class' => 'button-primary', + 'name' => 'wpcf7-save', + 'value' => __( 'Save', 'contact-form-7' ), + ) ); + + $formatter->end_tag( 'div' ); // .hidden + + if ( ! $post->initial() ) { + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'name' => 'wpcf7-copy', + 'class' => 'copy button', + 'value' => __( 'Duplicate', 'contact-form-7' ), + ) ); + } + + $formatter->end_tag( 'div' ); // #minor-publishing-actions + + $formatter->append_start_tag( 'div', array( + 'id' => 'misc-publishing-actions', + ) ); + + $formatter->call_user_func( static function () use ( $post_id ) { + do_action( 'wpcf7_admin_misc_pub_section', $post_id ); + } ); + + $formatter->end_tag( 'div' ); // #misc-publishing-actions + + $formatter->append_start_tag( 'div', array( + 'id' => 'major-publishing-actions', + ) ); + + if ( ! $post->initial() ) { + $formatter->append_start_tag( 'div', array( + 'id' => 'delete-action', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'name' => 'wpcf7-delete', + 'class' => 'delete submitdelete', + 'value' => __( 'Delete', 'contact-form-7' ), + ) ); + + $formatter->end_tag( 'div' ); // #delete-action + } + + $formatter->append_start_tag( 'div', array( + 'id' => 'publishing-action', + ) ); + + $formatter->append_preformatted( '' ); + $formatter->append_preformatted( $save_button ); + + $formatter->end_tag( 'div' ); // #publishing-action + + $formatter->append_preformatted( '
' ); + + $formatter->end_tag( 'div' ); // #major-publishing-actions + $formatter->end_tag( 'div' ); // #submitpost + $formatter->end_tag( 'div' ); // .inside + $formatter->end_tag( 'section' ); // #submitdiv + } + + $formatter->append_start_tag( 'section', array( + 'id' => 'informationdiv', + 'class' => 'postbox', + ) ); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Do you need help?', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'inside', + ) ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_preformatted( + esc_html( __( 'Here are some available options to help solve your problems.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'p' ); + + $formatter->append_start_tag( 'ol' ); + + $formatter->append_start_tag( 'li' ); + + $formatter->append_preformatted( + sprintf( + /* translators: 1: URL to FAQ, 2: URL to docs */ + 'FAQ and docs', + __( 'https://contactform7.com/faq/', 'contact-form-7' ), + __( 'https://contactform7.com/docs/', 'contact-form-7' ) + ) + ); + + $formatter->append_start_tag( 'li' ); + + $formatter->append_preformatted( + wpcf7_link( + __( 'https://wordpress.org/support/plugin/contact-form-7/', 'contact-form-7' ), + __( 'Support forums', 'contact-form-7' ) + ) + ); + + $formatter->append_start_tag( 'li' ); + + $formatter->append_preformatted( + wpcf7_link( + __( 'https://contactform7.com/custom-development/', 'contact-form-7' ), + __( 'Professional services', 'contact-form-7' ) + ) + ); + + $formatter->end_tag( 'ol' ); + $formatter->end_tag( 'div' ); // .inside + $formatter->end_tag( 'section' ); // #informationdiv + $formatter->end_tag( 'div' ); // #postbox-container-1 + + $formatter->append_start_tag( 'div', array( + 'id' => 'postbox-container-2', + 'class' => 'postbox-container', + ) ); + + $formatter->append_start_tag( 'div', array( + 'id' => 'contact-form-editor', + ) ); + + $formatter->call_user_func( static function () use ( $post, $post_id ) { + $editor = new WPCF7_Editor( $post ); + $panels = array(); + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $panels = array( + 'form-panel' => array( + 'title' => __( 'Form', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_form', + ), + 'mail-panel' => array( + 'title' => __( 'Mail', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_mail', + ), + 'messages-panel' => array( + 'title' => __( 'Messages', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_messages', + ), + ); + + $additional_settings = $post->prop( 'additional_settings' ); + + if ( ! is_scalar( $additional_settings ) ) { + $additional_settings = ''; + } + + $additional_settings = trim( $additional_settings ); + $additional_settings = explode( "\n", $additional_settings ); + $additional_settings = array_filter( $additional_settings ); + $additional_settings = count( $additional_settings ); + + $panels['additional-settings-panel'] = array( + 'title' => $additional_settings + ? sprintf( + /* translators: %d: number of additional settings */ + __( 'Additional Settings (%d)', 'contact-form-7' ), + $additional_settings + ) + : __( 'Additional Settings', 'contact-form-7' ), + 'callback' => 'wpcf7_editor_panel_additional_settings', + ); + } + + $panels = apply_filters( 'wpcf7_editor_panels', $panels ); + + foreach ( $panels as $id => $panel ) { + $editor->add_panel( $id, $panel['title'], $panel['callback'] ); + } + + $editor->display(); + } ); + + $formatter->end_tag( 'div' ); // #contact-form-editor + + if ( current_user_can( 'wpcf7_edit_contact_form', $post_id ) ) { + $formatter->append_start_tag( 'p', array( + 'class' => 'submit', + ) ); + + $formatter->append_preformatted( $save_button ); + + $formatter->end_tag( 'p' ); + } + + $formatter->end_tag( 'div' ); // #postbox-container-2 + $formatter->end_tag( 'div' ); // #post-body + + $formatter->append_preformatted( '
' ); + + $formatter->end_tag( 'div' ); // #poststuff + $formatter->end_tag( 'form' ); +} + +$formatter->end_tag( 'div' ); // .wrap + +$formatter->print(); + +$tag_generator = WPCF7_TagGenerator::get_instance(); +$tag_generator->print_panels( $post ); + +do_action( 'wpcf7_admin_footer', $post ); diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/admin-functions.php b/html/wp-content/plugins/contact-form-7/admin/includes/admin-functions.php new file mode 100644 index 0000000..11a5547 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/admin-functions.php @@ -0,0 +1,22 @@ +add( $name, $title, $callback, $options ); +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/class-contact-forms-list-table.php b/html/wp-content/plugins/contact-form-7/admin/includes/class-contact-forms-list-table.php new file mode 100644 index 0000000..6235966 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/class-contact-forms-list-table.php @@ -0,0 +1,241 @@ + '', + 'title' => __( 'Title', 'contact-form-7' ), + 'shortcode' => __( 'Shortcode', 'contact-form-7' ), + 'author' => __( 'Author', 'contact-form-7' ), + 'date' => __( 'Date', 'contact-form-7' ), + ); + + return $columns; + } + + public function __construct() { + parent::__construct( array( + 'singular' => 'post', + 'plural' => 'posts', + 'ajax' => false, + ) ); + } + + public function prepare_items() { + $current_screen = get_current_screen(); + $per_page = $this->get_items_per_page( 'wpcf7_contact_forms_per_page' ); + + $args = array( + 'posts_per_page' => $per_page, + 'orderby' => 'title', + 'order' => 'ASC', + 'offset' => ( $this->get_pagenum() - 1 ) * $per_page, + ); + + if ( $search_keyword = wpcf7_superglobal_request( 's' ) ) { + $args['s'] = $search_keyword; + } + + if ( $order_by = wpcf7_superglobal_request( 'orderby' ) ) { + $args['orderby'] = $order_by; + } + + if ( + $order = wpcf7_superglobal_request( 'order' ) and + 'desc' === strtolower( $order ) + ) { + $args['order'] = 'DESC'; + } + + $this->items = WPCF7_ContactForm::find( $args ); + + $total_items = WPCF7_ContactForm::count(); + $total_pages = ceil( $total_items / $per_page ); + + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'total_pages' => $total_pages, + 'per_page' => $per_page, + ) ); + } + + public function get_columns() { + return get_column_headers( get_current_screen() ); + } + + protected function get_sortable_columns() { + $columns = array( + 'title' => array( 'title', true ), + 'author' => array( 'author', false ), + 'date' => array( 'date', false ), + ); + + return $columns; + } + + protected function get_bulk_actions() { + $actions = array( + 'delete' => __( 'Delete', 'contact-form-7' ), + ); + + return $actions; + } + + protected function column_default( $item, $column_name ) { + return ''; + } + + public function column_cb( $item ) { + return sprintf( + '', + $this->_args['singular'], + $item->id() + ); + } + + public function column_title( $item ) { + $edit_link = add_query_arg( + array( + 'post' => absint( $item->id() ), + 'action' => 'edit', + ), + menu_page_url( 'wpcf7', false ) + ); + + $output = sprintf( + '%3$s', + esc_url( $edit_link ), + esc_attr( sprintf( + /* translators: %s: title of contact form */ + __( 'Edit “%s”', 'contact-form-7' ), + $item->title() + ) ), + esc_html( $item->title() ) + ); + + $output = sprintf( '%s', $output ); + + if ( wpcf7_validate_configuration() + and current_user_can( 'wpcf7_edit_contact_form', $item->id() ) ) { + $config_validator = new WPCF7_ConfigValidator( $item ); + $config_validator->restore(); + + if ( $count_errors = $config_validator->count_errors() ) { + $error_notice = sprintf( + /* translators: %s: number of errors detected */ + _n( + '%s configuration error detected', + '%s configuration errors detected', + $count_errors, 'contact-form-7' ), + number_format_i18n( $count_errors ) + ); + + $output .= sprintf( + '
%s
', + $error_notice + ); + } + } + + return $output; + } + + protected function handle_row_actions( $item, $column_name, $primary ) { + if ( $column_name !== $primary ) { + return ''; + } + + $edit_link = add_query_arg( + array( + 'post' => absint( $item->id() ), + 'action' => 'edit', + ), + menu_page_url( 'wpcf7', false ) + ); + + $actions = array( + 'edit' => wpcf7_link( $edit_link, __( 'Edit', 'contact-form-7' ) ), + ); + + if ( current_user_can( 'wpcf7_edit_contact_form', $item->id() ) ) { + $copy_link = add_query_arg( + array( + 'post' => absint( $item->id() ), + 'action' => 'copy', + ), + menu_page_url( 'wpcf7', false ) + ); + + $copy_link = wp_nonce_url( + $copy_link, + 'wpcf7-copy-contact-form_' . absint( $item->id() ) + ); + + $actions = array_merge( $actions, array( + 'copy' => wpcf7_link( $copy_link, __( 'Duplicate', 'contact-form-7' ) ), + ) ); + } + + return $this->row_actions( $actions ); + } + + public function column_author( $item ) { + $post = get_post( $item->id() ); + + if ( ! $post ) { + return; + } + + $author = get_userdata( $post->post_author ); + + if ( false === $author ) { + return; + } + + return esc_html( $author->display_name ); + } + + public function column_shortcode( $item ) { + $shortcodes = array( $item->shortcode() ); + + $output = ''; + + foreach ( $shortcodes as $shortcode ) { + $output .= "\n" . sprintf( + '', + wpcf7_format_atts( array( + 'type' => 'text', + 'readonly' => true, + 'value' => $shortcode, + 'class' => 'large-text code selectable', + ) ) + ); + } + + return trim( $output ); + } + + public function column_date( $item ) { + $datetime = get_post_datetime( $item->id() ); + + if ( false === $datetime ) { + return ''; + } + + $t_time = sprintf( + /* translators: 1: date, 2: time */ + __( '%1$s at %2$s', 'contact-form-7' ), + /* translators: date format, see https://www.php.net/date */ + $datetime->format( __( 'Y/m/d', 'contact-form-7' ) ), + /* translators: time format, see https://www.php.net/date */ + $datetime->format( __( 'g:i a', 'contact-form-7' ) ) + ); + + return $t_time; + } +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/config-validator.php b/html/wp-content/plugins/contact-form-7/admin/includes/config-validator.php new file mode 100644 index 0000000..e727a90 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/config-validator.php @@ -0,0 +1,180 @@ + 'validate' ), + menu_page_url( 'wpcf7', false ) + ), + __( 'Validate Contact Form 7 Configuration', 'contact-form-7' ) + ) + ), + array( 'type' => 'warning' ) + ); +} + +add_action( 'wpcf7_admin_load', 'wpcf7_load_bulk_validate_page', 10, 2 ); + +function wpcf7_load_bulk_validate_page( $page, $action ) { + if ( + 'wpcf7' !== $page or + 'validate' !== $action or + ! wpcf7_validate_configuration() or + 'POST' !== wpcf7_superglobal_server( 'REQUEST_METHOD' ) + ) { + return; + } + + check_admin_referer( 'wpcf7-bulk-validate' ); + + if ( ! current_user_can( 'wpcf7_edit_contact_forms' ) ) { + wp_die( wp_kses_data( __( 'You are not allowed to validate configuration.', 'contact-form-7' ) ) ); + } + + $contact_forms = WPCF7_ContactForm::find(); + + $result = array( + 'timestamp' => time(), + 'version' => WPCF7_VERSION, + 'count_valid' => 0, + 'count_invalid' => 0, + ); + + foreach ( $contact_forms as $contact_form ) { + $config_validator = new WPCF7_ConfigValidator( $contact_form ); + $config_validator->validate(); + $config_validator->save(); + + if ( $config_validator->is_valid() ) { + $result['count_valid'] += 1; + } else { + $result['count_invalid'] += 1; + } + } + + WPCF7::update_option( 'bulk_validate', $result ); + + $redirect_to = add_query_arg( + array( + 'message' => 'validated', + ), + menu_page_url( 'wpcf7', false ) + ); + + wp_safe_redirect( $redirect_to ); + exit(); +} + +function wpcf7_admin_bulk_validate_page() { + $contact_forms = WPCF7_ContactForm::find(); + $count = WPCF7_ContactForm::count(); + + $submit_text = sprintf( + /* translators: %s: number of contact forms */ + _n( + 'Validate %s contact form now', + 'Validate %s contact forms now', + $count, 'contact-form-7' + ), + number_format_i18n( $count ) + ); + + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'form' => array( + 'action' => true, + 'method' => true, + ), + ) ), + ) ); + + $formatter->append_start_tag( 'div', array( + 'class' => 'wrap', + ) ); + + $formatter->append_start_tag( 'h1' ); + + $formatter->append_preformatted( + esc_html( __( 'Validate Configuration', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h1' ); + + $formatter->append_start_tag( 'form', array( + 'method' => 'post', + 'action' => '', + ) ); + + $formatter->append_start_tag( 'p' ); + + $formatter->call_user_func( static function () { + wp_nonce_field( 'wpcf7-bulk-validate' ); + } ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'name' => 'action', + 'value' => 'validate', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'submit', + 'class' => 'button', + 'value' => $submit_text, + ) ); + + $formatter->end_tag( 'form' ); + + $formatter->append_preformatted( + wpcf7_link( + __( 'https://contactform7.com/configuration-validator-faq/', 'contact-form-7' ), + __( 'FAQ about Configuration Validator', 'contact-form-7' ) + ) + ); + + $formatter->print(); +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/css/styles-rtl.css b/html/wp-content/plugins/contact-form-7/admin/includes/css/styles-rtl.css new file mode 100644 index 0000000..4b5de0f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/css/styles-rtl.css @@ -0,0 +1,77 @@ +/* + * Form Tab + */ +.tag-generator-panel { + text-align: right; +} + +.tag-generator-dialog > .close-button { + right: auto; + left: 8px; +} + +form.tag-generator-panel[data-version="1"] { + .control-box > fieldset > legend { + border: 1px solid #dfdfdf; + border-right: 4px solid #00a0d2; + } + + .insert-box input.tag { + float: right; + } + + .insert-box .submitbox input[type="button"] { + float: left; + } +} + +/* + * Mail Tab + */ +.contact-form-editor-box-mail span.mailtag { + margin: 0 4px 0 0; +} + +/* + * Welcome Panel + */ +.wpcf7-welcome-panel .welcome-panel-close { + left: 10px; + right: auto; + padding: 10px 21px 10px 15px; +} + +.wpcf7-welcome-panel .welcome-panel-close::before { + right: 0; + left: auto; +} + +.wpcf7-welcome-panel .welcome-panel-content { + margin-right: 13px; +} + +.wpcf7-welcome-panel .welcome-panel-column { + float: right; + padding: 0 0 0 2%; +} + +/* + * Integration + */ +.card { + border-left: 1px solid #e5e5e5; + border-right: 4px solid #e5e5e5; +} + +.card img.icon { + float: right; + margin: 8px -8px 8px 8px; +} + +.card h2.title { + float: right; +} + +.card .infobox { + float: left; +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/css/styles.css b/html/wp-content/plugins/contact-form-7/admin/includes/css/styles.css new file mode 100644 index 0000000..0aa85ab --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/css/styles.css @@ -0,0 +1,614 @@ +#titlediv .inside p.description { + margin: 8px 2px 0; +} + +#titlediv .inside p.description label { + cursor: pointer; +} + +span.shortcode { + display: block; + margin: 2px 0; +} + +span.shortcode.old { + background: #777; + color: #fff; +} + +span.shortcode input { + font-size: 12px; + border: none; + box-shadow: none; + padding: 4px 8px; + margin: 0; +} + +#wpcf7-contact-form-list-table span.shortcode input, +#wpcf7-contact-form-editor span.shortcode input { + background: transparent; +} + +#wpcf7-contact-form-list-table span.shortcode input { + color: #444; +} + +#wpcf7-contact-form-editor span.shortcode input { + color: #fff; + width: 100%; +} + +#submitpost input.copy { + margin-bottom: 10px; +} + +#submitpost input.delete { + padding: 0; + margin: 0; + border: none; + cursor: pointer; + background: inherit; + color: #a00; +} + +#submitpost input.delete:hover { + color: #dc3232; /* Red */ +} + +#submitpost input.delete:focus { + outline: thin dotted; +} + +.postbox-container .postbox h3 { + border-bottom: 1px solid transparent; +} + +div.config-error, span.config-error, ul.config-error { + color: #444; + font-style: normal; + font-size: 13px; +} + +ul.config-error { + margin: 2px 0; +} + +ul.config-error li { + list-style: none; + padding: 2px 2px; + margin: 0; +} + +#misc-publishing-actions .config-error { + line-height: 2; +} + +[data-config-field][aria-invalid="true"] { + border-color: #dc3232; +} + +#contact-form-editor-tabs .icon-in-circle, +#contact-form-editor .config-error .icon-in-circle, +.wp-list-table .config-error .icon-in-circle, +.icon-in-circle { + display: inline-block; + vertical-align: baseline; + margin: 1px 6px 0; + padding: 0 5px; + min-width: 7px; + height: 17px; + border-radius: 11px; + background-color: #ca4a1f; + color: #fff; + font-size: 12px; + font-weight: bold; + line-height: 17px; + text-align: center; + z-index: 26; +} + +/* + * Tabs + */ +#contact-form-editor-tabs { + border-bottom: 1px solid #aaa; + padding: 9px 10px 0; + margin: 0; +} + +#contact-form-editor-tabs button { + display: inline-block; + border: 1px solid #ccc; + border-bottom: 1px solid #aaa; + padding: 6px 10px; + margin: 0 4px -1px; + color: #333; + background-color: #e4e4e4; + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +#contact-form-editor-tabs button[aria-selected="true"] { + border-top: 1px solid #aaa; + border-right: 1px solid #aaa; + border-left: 1px solid #aaa; + border-bottom: 1px solid #f5f5f5; + color: #000; + background-color: #f5f5f5; + font-weight: bold; +} + +#contact-form-editor-tabs button:hover { + color: #000; +} + +#contact-form-editor .contact-form-editor-panel > div.config-error { + margin-bottom: 1.4em; +} + +#contact-form-editor-tabs button[aria-selected="true"] .icon-in-circle { + display: none; +} + +#contact-form-editor .contact-form-editor-panel h2 { + font-size: 18px; + font-weight: 400; + line-height: 24px; + margin: 8px 0; + padding: 0; +} + +#contact-form-editor .contact-form-editor-panel { + background-color: #f5f5f5; + border: 1px solid #aaa; + border-top: none; + padding: 16px; +} + +#contact-form-editor .form-table th { + width: 100px; +} + +#contact-form-editor .contact-form-editor-panel fieldset legend { + line-height: 1.5; + margin: .6em 0 .4em; +} + +/* + * Form Tab + */ +#tag-generator-list button { + font-size: 12px; + height: 26px; + line-height: 24px; + margin: 2px; + padding: 0 8px 1px; +} + +.tag-generator-dialog { + padding: 12px; + border: 1px solid #c3c4c7; + box-shadow: 0 1px 1px rgba( 0, 0, 0, 0.04 ); + height: 720px; + width: 720px; + overflow: auto; +} + +.tag-generator-dialog::backdrop { + background: rgb( 0 0 0 / 50% ); +} + +.tag-generator-dialog > .close-button { + position: absolute; + top: 8px; + right: 8px; +} + +form.tag-generator-panel { + display: flex; + flex-direction: column; + height: 720px; + width: 720px; + max-height: 100%; + max-width: 100%; + margin-block-end: 0; +} + +form.tag-generator-panel[data-version="2"] { + &:invalid .mail-tag-tip { + display: none; + } + + .description-box { + box-sizing: border-box; + flex: none; + margin-inline: -12px; + padding-inline: 12px; + border-bottom: 1px solid #dfdfdf; + } + + .control-box { + box-sizing: border-box; + flex: auto; + display: flex; + flex-direction: column; + gap: 12px 0; + min-height: 120px; + overflow: auto; + } + + .control-box > fieldset { + margin-block: 8px; + margin-inline-start: 10em; + line-height: 2.25; + } + + .control-box > fieldset > legend { + font-weight: bolder; + margin-block: 8px; + margin-inline-start: -10em; + line-height: 1.25; + } + + .control-box input[type="text"] { + width: 20rem; + max-width: 88%; + } + + .control-box input[type="number"] { + width: 8rem; + max-width: 44%; + } + + .control-box textarea { + height: 12ex; + width: 20rem; + max-width: 88%; + } + + .control-box select { + width: 20rem; + max-width: 88%; + } + + .control-box input:invalid, + .control-box textarea:invalid { + background-color: #ffe9de; + } + + .insert-box { + box-sizing: border-box; + flex: none; + margin-block-end: -12px; + margin-inline: -12px; + padding-block: 24px 12px; + padding-inline: 12px; + background-color: #fcfcfc; + border-top: 1px solid #dfdfdf; + } + + .insert-box .flex-container { + display: flex; + } + + .insert-box .flex-container > [data-tag-part="tag"] { + flex: auto; + margin-inline-end: 8px; + } + + .insert-box .mail-tag-tip::before { + font: 1.2rem dashicons; + content: "\f348" / ''; + color: #646970; + padding-inline-end: 4px; + vertical-align: top; + } +} + +form.tag-generator-panel[data-version="1"] { + .control-box { + padding: 0; + margin: 0; + overflow: auto; + flex-grow: 1; + } + + .control-box > fieldset > legend { + border: 1px solid #dfdfdf; + border-left: 4px solid #00a0d2; + background: #f7fcfe; + padding: 4px 12px; + margin: 4px 0; + line-height: 1.4em; + width: 100%; + box-sizing: border-box; + } + + table { + width: 100%; + } + + table.form-table th { + width: 120px; + padding: 4px 10px 4px 0; + font-size: 13px; + } + + table.form-table td { + padding: 4px 10px; + font-size: 13px; + } + + .control-box input.oneline { + width: 200px; + } + + .control-box input.large-text { + width: 400px; + } + + .control-box textarea.values { + width: 200px; + height: 6em; + } + + .control-box input[type="number"], + .control-box input[type="date"] { + width: 88px; + } + + .control-box table caption { + text-align: left; + font-size: 110%; + font-weight: bold; + color: #777; + margin: 10px 0 5px; + } + + .control-box table.form-table td label { + line-height: 1.1em; + } + + .control-box table.form-table td label .description { + line-height: 1.4em; + } + + .insert-box { + margin: 0 -15px -15px; + padding: 8px 16px; + background-color: #fcfcfc; + border-top: 1px solid #dfdfdf; + overflow: auto; + } + + .insert-box input.tag { + width: 510px; + float: left; + background-color: transparent; + box-shadow: none; + } + + .insert-box .submitbox { + padding: 0; + } + + .insert-box .submitbox input[type="button"] { + float: right; + } + + .insert-box .description label { + cursor: text; + } +} + +/* + * Mail Tab + */ +.contact-form-editor-box-mail span.mailtag { + display: inline-block; + margin: 0 0 0 4px; + padding: 1px 2px; + cursor: pointer; + color: #000; +} + +.contact-form-editor-box-mail span.mailtag.used { + color: #666; +} + +.contact-form-editor-box-mail span.mailtag.unused { + font-weight: bold; +} + +/* + * Messages Tab + */ +#messages-panel p.description { + margin: 5px 0 10px; +} + +/* + * Tabs for integration modules + */ +#sendinblue-panel table tr.inactive ~ tr { + display: none; +} + +#sendinblue-panel .dashicons { + text-decoration: none; +} + +#sendinblue-panel td p { + margin-top: 12px; +} + +/* + * List Table + */ +.fixed .column-title { + width: 38%; +} + +.fixed .column-shortcode { + width: 38%; +} + +/* + * Welcome Panel + */ +.wpcf7-welcome-panel { + position: relative; + overflow: auto; + margin: 16px 0; + padding: 23px 10px 0; + border: 1px solid #c3c4c7; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); + background: #fff; + font-size: 13px; + line-height: 1.7; +} + +.wpcf7-welcome-panel h3 { + font-size: 16px; + font-weight: 600; + line-height: 2.1em; + margin: 1em 0 1.2em; +} + +.wpcf7-welcome-panel h3 .dashicons { + position: relative; + top: -2px; + display: inline-block; + width: 60px; + color: #575757; + font-size: 40px; +} + +.wpcf7-welcome-panel p { + color: #646970; +} + +.wpcf7-welcome-panel p a { + font-weight: bold; +} + +.wpcf7-welcome-panel .welcome-panel-close { + position: absolute; + z-index: 2; + top: 10px; + right: 10px; + padding: 10px 15px 10px 21px; + font-size: 13px; + line-height: 1.23076923; /* Chrome rounding, needs to be 16px equivalent */ + text-decoration: none; +} + +.wpcf7-welcome-panel .welcome-panel-close::before { + background: 0 0; + color: #787c82; + content: "\f153" / ''; + display: block; + font: normal 16px/20px dashicons; + speak: never; + height: 20px; + text-align: center; + width: 20px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + position: absolute; + top: 8px; + left: 0; + transition: all .1s ease-in-out; +} + +.wpcf7-welcome-panel .welcome-panel-content { + display: block; + margin-left: 13px; + max-width: 1500px; + min-height: auto; +} + +.wpcf7-welcome-panel .welcome-panel-column-container { + clear: both; + position: relative; +} + +.wpcf7-welcome-panel .welcome-panel-column { + display: block; + width: 48%; + min-width: 200px; + float: left; + padding: 0 2% 0 0; + margin: 0 0 1em 0; +} + +@media screen and (max-width: 870px) { + .wpcf7-welcome-panel .welcome-panel-column { + display: block; + float: none; + width: 100%; + } +} + +.wpcf7-welcome-panel .welcome-panel-column p { + margin-top: 7px; + color: #3c434a; +} + +/* + * Integration + */ +.card { + background: #fff none repeat scroll 0 0; + border: 1px solid #e5e5e5; + border-left: 4px solid #e5e5e5; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); + margin-top: 20px; + max-width: 520px; + min-width: 255px; + padding: 0.7em 2em 1em; + position: relative; +} + +.card.active { + border-color: #00a0d2; +} + +#constant_contact.card.active { + border-color: #dc3232; +} + +.card img.icon { + float: left; + margin: 8px 8px 8px -8px; +} + +.card h2.title { + float: left; + max-width: 240px; + font-size: 1.3em; + font-weight: 600; +} + +.card .infobox { + float: right; + font-size: 13px; + color: #666; + margin: 1em; + line-height: 1.5; + max-width: 240px; +} + +.card .inside .form-table th { + padding: 15px 10px 15px 0; + width: 160px; +} + +.card .inside .form-table td { + padding: 10px 10px; +} + +.card .checkboxes li { + margin: 0; +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/editor.php b/html/wp-content/plugins/contact-form-7/admin/includes/editor.php new file mode 100644 index 0000000..cb58d26 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/editor.php @@ -0,0 +1,556 @@ +contact_form = $contact_form; + } + + public function add_panel( $panel_id, $title, $callback ) { + if ( wpcf7_is_name( $panel_id ) ) { + $this->panels[$panel_id] = array( + 'title' => $title, + 'callback' => $callback, + ); + } + } + + public function display() { + if ( empty( $this->panels ) ) { + return; + } + + $active_panel_id = wpcf7_superglobal_get( 'active-tab' ); + + if ( ! array_key_exists( $active_panel_id, $this->panels ) ) { + $active_panel_id = array_key_first( $this->panels ); + } + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'nav', array( + 'id' => 'contact-form-editor-tabs', + 'role' => 'tablist', + 'aria-label' => __( 'Contact form editor tabs', 'contact-form-7' ), + 'data-active-tab' => absint( array_search( + $active_panel_id, array_keys( $this->panels ), true + ) ), + ) ); + + foreach ( $this->panels as $panel_id => $panel ) { + $active = $panel_id === $active_panel_id; + + $formatter->append_start_tag( 'button', array( + 'type' => 'button', + 'role' => 'tab', + 'aria-selected' => $active ? 'true' : 'false', + 'aria-controls' => $panel_id, + 'id' => sprintf( '%s-tab', $panel_id ), + 'tabindex' => $active ? '0' : '-1', + ) ); + + $formatter->append_preformatted( esc_html( $panel['title'] ) ); + } + + $formatter->end_tag( 'nav' ); + + foreach ( $this->panels as $panel_id => $panel ) { + $active = $panel_id === $active_panel_id; + + $formatter->append_start_tag( 'section', array( + 'role' => 'tabpanel', + 'aria-labelledby' => sprintf( '%s-tab', $panel_id ), + 'id' => $panel_id, + 'class' => 'contact-form-editor-panel', + 'tabindex' => '0', + 'hidden' => ! $active, + ) ); + + if ( is_callable( $panel['callback'] ) ) { + $formatter->call_user_func( $panel['callback'], $this->contact_form ); + } + + $formatter->end_tag( 'section' ); + } + + $formatter->print(); + } +} + +function wpcf7_editor_panel_form( $post ) { + $description = sprintf( + /* translators: %s: URL to support page about the form template */ + __( 'You can edit the form template here. For details, see Editing form template.', 'contact-form-7' ), + __( 'https://contactform7.com/editing-form-template/', 'contact-form-7' ) + ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'h2' ); + $formatter->append_preformatted( esc_html( __( 'Form', 'contact-form-7' ) ) ); + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( $description ); + $formatter->end_tag( 'legend' ); + + $formatter->call_user_func( static function () { + $tag_generator = WPCF7_TagGenerator::get_instance(); + $tag_generator->print_buttons(); + } ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => 'wpcf7-form', + 'name' => 'wpcf7-form', + 'cols' => 100, + 'rows' => 24, + 'class' => 'large-text code', + 'data-config-field' => 'form.body', + ) ); + + $formatter->append_preformatted( esc_textarea( $post->prop( 'form' ) ) ); + + $formatter->end_tag( 'textarea' ); + + $formatter->print(); +} + +function wpcf7_editor_panel_mail( $post ) { + wpcf7_editor_box_mail( $post ); + + echo '
'; + + wpcf7_editor_box_mail( $post, array( + 'id' => 'wpcf7-mail-2', + 'name' => 'mail_2', + 'title' => __( 'Mail (2)', 'contact-form-7' ), + 'use' => __( 'Use Mail (2)', 'contact-form-7' ), + ) ); +} + +function wpcf7_editor_box_mail( $post, $options = '' ) { + $options = wp_parse_args( $options, array( + 'id' => 'wpcf7-mail', + 'name' => 'mail', + 'title' => __( 'Mail', 'contact-form-7' ), + 'use' => null, + ) ); + + $id = esc_attr( $options['id'] ); + + $mail = wp_parse_args( $post->prop( $options['name'] ), array( + 'active' => false, + 'recipient' => '', + 'sender' => '', + 'subject' => '', + 'body' => '', + 'additional_headers' => '', + 'attachments' => '', + 'use_html' => false, + 'exclude_blank' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'div', array( + 'class' => 'contact-form-editor-box-mail', + 'id' => $id, + ) ); + + $formatter->append_start_tag( 'h2' ); + $formatter->append_preformatted( esc_html( $options['title'] ) ); + $formatter->end_tag( 'h2' ); + + if ( ! empty( $options['use'] ) ) { + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-active', $id ), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'id' => sprintf( '%s-active', $id ), + 'name' => sprintf( '%s[active]', $id ), + 'data-config-field' => '', + 'data-toggle' => sprintf( '%s-fieldset', $id ), + 'value' => '1', + 'checked' => $mail['active'], + ) ); + + $formatter->append_whitespace(); + $formatter->append_preformatted( esc_html( $options['use'] ) ); + $formatter->end_tag( 'label' ); + + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Mail (2) is an additional mail template often used as an autoresponder.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'p' ); + } + + $formatter->append_start_tag( 'fieldset', array( + 'id' => sprintf( '%s-fieldset', $id ), + ) ); + + $formatter->append_start_tag( 'legend' ); + + $description = sprintf( + /* translators: %s: URL to support page about the email template */ + __( 'You can edit the email template here. For details, see Setting up mail.', 'contact-form-7' ), + __( 'https://contactform7.com/setting-up-mail/', 'contact-form-7' ) + ); + + $formatter->append_preformatted( $description ); + + $formatter->append_start_tag( 'br' ); + + $formatter->append_preformatted( + esc_html( __( 'In the following fields, you can use these mail-tags:', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'br' ); + + $formatter->call_user_func( static function () use ( $post, $options ) { + $post->suggest_mail_tags( $options['name'] ); + } ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'table', array( + 'class' => 'form-table', + ) ); + + $formatter->append_start_tag( 'tbody' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-recipient', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'To', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => sprintf( '%s-recipient', $id ), + 'name' => sprintf( '%s[recipient]', $id ), + 'class' => 'large-text code', + 'size' => 70, + 'value' => $mail['recipient'], + 'data-config-field' => sprintf( '%s.recipient', $options['name'] ), + ) ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-sender', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'From', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => sprintf( '%s-sender', $id ), + 'name' => sprintf( '%s[sender]', $id ), + 'class' => 'large-text code', + 'size' => 70, + 'value' => $mail['sender'], + 'data-config-field' => sprintf( '%s.sender', $options['name'] ), + ) ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-subject', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Subject', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => sprintf( '%s-subject', $id ), + 'name' => sprintf( '%s[subject]', $id ), + 'class' => 'large-text code', + 'size' => 70, + 'value' => $mail['subject'], + 'data-config-field' => sprintf( '%s.subject', $options['name'] ), + ) ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-additional-headers', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Additional headers', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => sprintf( '%s-additional-headers', $id ), + 'name' => sprintf( '%s[additional_headers]', $id ), + 'cols' => 100, + 'rows' => 4, + 'class' => 'large-text code', + 'data-config-field' => sprintf( '%s.additional_headers', $options['name'] ), + ) ); + + $formatter->append_preformatted( + esc_textarea( $mail['additional_headers'] ) + ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-body', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Message body', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => sprintf( '%s-body', $id ), + 'name' => sprintf( '%s[body]', $id ), + 'cols' => 100, + 'rows' => 18, + 'class' => 'large-text code', + 'data-config-field' => sprintf( '%s.body', $options['name'] ), + ) ); + + $formatter->append_preformatted( + esc_textarea( $mail['body'] ) + ); + + $formatter->end_tag( 'textarea' ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-exclude-blank', $id ), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'id' => sprintf( '%s-exclude-blank', $id ), + 'name' => sprintf( '%s[exclude_blank]', $id ), + 'value' => '1', + 'checked' => $mail['exclude_blank'], + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Exclude a line from output if all of its mail-tags are blank', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'p' ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-use-html', $id ), + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'id' => sprintf( '%s-use-html', $id ), + 'name' => sprintf( '%s[use_html]', $id ), + 'value' => '1', + 'checked' => $mail['use_html'], + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Use HTML content type', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'tr' ); + + $formatter->append_start_tag( 'tr' ); + + $formatter->append_start_tag( 'th', array( + 'scope' => 'row', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => sprintf( '%s-attachments', $id ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'File attachments', 'contact-form-7' ) ) + ); + + $formatter->append_start_tag( 'td' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => sprintf( '%s-attachments', $id ), + 'name' => sprintf( '%s[attachments]', $id ), + 'cols' => 100, + 'rows' => 4, + 'class' => 'large-text code', + 'data-config-field' => sprintf( '%s.attachments', $options['name'] ), + ) ); + + $formatter->append_preformatted( + esc_textarea( $mail['attachments'] ) + ); + + $formatter->end_tag( 'textarea' ); + $formatter->end_tag( 'tr' ); + + $formatter->print(); +} + +function wpcf7_editor_panel_messages( $post ) { + $description = sprintf( + /* translators: %s: URL to support page about the messages editor */ + __( 'You can edit messages used in various situations here. For details, see Editing messages.', 'contact-form-7' ), + __( 'https://contactform7.com/editing-messages/', 'contact-form-7' ) + ); + + $messages = wpcf7_messages(); + + if ( + isset( $messages['captcha_not_match'] ) and + ! wpcf7_use_really_simple_captcha() + ) { + unset( $messages['captcha_not_match'] ); + } + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Messages', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( $description ); + $formatter->end_tag( 'legend' ); + + foreach ( $messages as $key => $arr ) { + $field_id = sprintf( 'wpcf7-message-%s', strtr( $key, '_', '-' ) ); + $field_name = sprintf( 'wpcf7-messages[%s]', $key ); + + $formatter->append_start_tag( 'p', array( + 'class' => 'description', + ) ); + + $formatter->append_start_tag( 'label', array( + 'for' => $field_id, + ) ); + + $formatter->append_preformatted( esc_html( $arr['description'] ) ); + $formatter->append_start_tag( 'br' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'id' => $field_id, + 'name' => $field_name, + 'class' => 'large-text', + 'size' => 70, + 'value' => $post->message( $key, false ), + 'data-config-field' => sprintf( 'messages.%s', $key ), + ) ); + } + + $formatter->print(); +} + +function wpcf7_editor_panel_additional_settings( $post ) { + $description = sprintf( + /* translators: %s: URL to support page about the additional settings editor */ + __( 'You can add customization code snippets here. For details, see Additional settings.', 'contact-form-7' ), + __( 'https://contactform7.com/additional-settings/', 'contact-form-7' ) + ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'h2' ); + + $formatter->append_preformatted( + esc_html( __( 'Additional Settings', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'h2' ); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( $description ); + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'textarea', array( + 'id' => 'wpcf7-additional-settings', + 'name' => 'wpcf7-additional-settings', + 'cols' => 100, + 'rows' => 24, + 'class' => 'large-text', + 'data-config-field' => 'additional_settings.body', + ) ); + + $formatter->append_preformatted( + esc_textarea( $post->prop( 'additional_settings' ) ) + ); + + $formatter->end_tag( 'textarea' ); + + $formatter->print(); +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/help-tabs.php b/html/wp-content/plugins/contact-form-7/admin/includes/help-tabs.php new file mode 100644 index 0000000..9b768b1 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/help-tabs.php @@ -0,0 +1,104 @@ +screen = $screen; + } + + public function set_help_tabs( $screen_type ) { + switch ( $screen_type ) { + case 'list': + $this->screen->add_help_tab( array( + 'id' => 'list_overview', + 'title' => __( 'Overview', 'contact-form-7' ), + 'content' => $this->content( 'list_overview' ), + ) ); + + $this->screen->add_help_tab( array( + 'id' => 'list_available_actions', + 'title' => __( 'Available Actions', 'contact-form-7' ), + 'content' => $this->content( 'list_available_actions' ), + ) ); + + $this->sidebar(); + + return; + case 'edit': + $this->screen->add_help_tab( array( + 'id' => 'edit_overview', + 'title' => __( 'Overview', 'contact-form-7' ), + 'content' => $this->content( 'edit_overview' ), + ) ); + + $this->screen->add_help_tab( array( + 'id' => 'edit_form_tags', + 'title' => __( 'Form-tags', 'contact-form-7' ), + 'content' => $this->content( 'edit_form_tags' ), + ) ); + + $this->screen->add_help_tab( array( + 'id' => 'edit_mail_tags', + 'title' => __( 'Mail-tags', 'contact-form-7' ), + 'content' => $this->content( 'edit_mail_tags' ), + ) ); + + $this->sidebar(); + + return; + case 'integration': + $this->screen->add_help_tab( array( + 'id' => 'integration_overview', + 'title' => __( 'Overview', 'contact-form-7' ), + 'content' => $this->content( 'integration_overview' ), + ) ); + + $this->sidebar(); + + return; + } + } + + private function content( $name ) { + $content = array(); + + $content['list_overview'] = '

' . __( 'On this screen, you can manage contact forms provided by Contact Form 7. You can manage an unlimited number of contact forms. Each contact form has a unique ID and Contact Form 7 shortcode ([contact-form-7 ...]). To insert a contact form into a post or a text widget, insert the shortcode into the target.', 'contact-form-7' ) . '

'; + + $content['list_available_actions'] = '

' . __( 'Hovering over a row in the contact forms list will display action links that allow you to manage your contact form. You can perform the following actions:', 'contact-form-7' ) . '

'; + $content['list_available_actions'] .= '

' . __( 'Edit - Navigates to the editing screen for that contact form. You can also reach that screen by clicking on the contact form title.', 'contact-form-7' ) . '

'; + $content['list_available_actions'] .= '

' . __( 'Duplicate - Clones that contact form. A cloned contact form inherits all content from the original, but has a different ID.', 'contact-form-7' ) . '

'; + + $content['edit_overview'] = '

' . __( 'On this screen, you can edit a contact form. A contact form is comprised of the following components:', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Title is the title of a contact form. This title is only used for labeling a contact form, and can be edited.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Form is a content of HTML form. You can use arbitrary HTML, which is allowed inside a form element. You can also use Contact Form 7’s form-tags here.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Mail manages a mail template (headers and message body) that this contact form will send when users submit it. You can use Contact Form 7’s mail-tags here.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Mail (2) is an additional mail template that works similar to Mail. Mail (2) is different in that it is sent only when Mail has been sent successfully.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'In Messages, you can edit various types of messages used for this contact form. These messages are relatively short messages, like a validation error message you see when you leave a required field blank.', 'contact-form-7' ) . '

'; + $content['edit_overview'] .= '

' . __( 'Additional Settings provides a place where you can customize the behavior of this contact form by adding code snippets.', 'contact-form-7' ) . '

'; + + $content['edit_form_tags'] = '

' . __( 'A form-tag is a short code enclosed in square brackets used in a form content. A form-tag generally represents an input field, and its components can be separated into four parts: type, name, options, and values. Contact Form 7 supports several types of form-tags including text fields, number fields, date fields, checkboxes, radio buttons, menus, file-uploading fields, CAPTCHAs, and quiz fields.', 'contact-form-7' ) . '

'; + $content['edit_form_tags'] .= '

' . __( 'While form-tags have a comparatively complex syntax, you do not need to know the syntax to add form-tags because you can use the straightforward tag generator (Generate Tag button on this screen).', 'contact-form-7' ) . '

'; + + $content['edit_mail_tags'] = '

' . __( 'A mail-tag is also a short code enclosed in square brackets that you can use in every Mail and Mail (2) field. A mail-tag represents a user input value through an input field of a corresponding form-tag.', 'contact-form-7' ) . '

'; + $content['edit_mail_tags'] .= '

' . __( 'There are also special mail-tags that have specific names, but do not have corresponding form-tags. They are used to represent meta information of form submissions like the submitter’s IP address or the URL of the page.', 'contact-form-7' ) . '

'; + + $content['integration_overview'] = '

' . __( 'On this screen, you can manage services that are available through Contact Form 7. Using API will allow you to collaborate with any services that are available.', 'contact-form-7' ) . '

'; + $content['integration_overview'] .= '

' . __( 'You may need to first sign up for an account with the service that you plan to use. When you do so, you would need to authorize Contact Form 7 to access the service with your account.', 'contact-form-7' ) . '

'; + $content['integration_overview'] .= '

' . __( 'Any information you provide will not be shared with service providers without your authorization.', 'contact-form-7' ) . '

'; + + if ( ! empty( $content[$name] ) ) { + return $content[$name]; + } + } + + public function sidebar() { + $content = '

' . __( 'For more information:', 'contact-form-7' ) . '

'; + $content .= '

' . wpcf7_link( __( 'https://contactform7.com/docs/', 'contact-form-7' ), __( 'Docs', 'contact-form-7' ) ) . '

'; + $content .= '

' . wpcf7_link( __( 'https://contactform7.com/faq/', 'contact-form-7' ), __( 'FAQ', 'contact-form-7' ) ) . '

'; + $content .= '

' . wpcf7_link( __( 'https://contactform7.com/support/', 'contact-form-7' ), __( 'Support', 'contact-form-7' ) ) . '

'; + + $this->screen->set_help_sidebar( $content ); + } +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/js/index.asset.php b/html/wp-content/plugins/contact-form-7/admin/includes/js/index.asset.php new file mode 100644 index 0000000..61de87f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/js/index.asset.php @@ -0,0 +1,9 @@ + array( + 'wp-api-fetch', + 'wp-i18n', + ), + 'version' => WPCF7_VERSION, +); diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/js/index.js b/html/wp-content/plugins/contact-form-7/admin/includes/js/index.js new file mode 100644 index 0000000..7087e3d --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/js/index.js @@ -0,0 +1 @@ +(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var r in a)e.o(a,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:a[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.wp.i18n,a=document.querySelector("#contact-form-editor"),r=window.wp.apiFetch;var c=e.n(r);const o=e=>{const t=document.createElement("span");return t.classList.add("icon-in-circle"),t.setAttribute("aria-hidden","true"),t.append(e),t},n=e=>e.replace(/[^0-9a-z]+/gi,"-"),l=e=>{const t=document.querySelector(`#${e.dataset?.toggle}`);t&&(e.checked?t.classList.remove("hidden"):t.classList.add("hidden"))},i=()=>{document.querySelectorAll("#contact-form-editor .config-error, #misc-publishing-actions .config-error").forEach((e=>{e.remove()})),document.querySelectorAll("#contact-form-editor [data-config-field]").forEach((e=>{const t=e.dataset.configField;d(t).length?(e.setAttribute("aria-invalid","true"),e.setAttribute("aria-describedby",n(`wpcf7-config-error-for-${t}`)),e.after(u(t))):e.removeAttribute("aria-invalid")})),document.querySelectorAll("#contact-form-editor-tabs [data-panel]").forEach((e=>{e.querySelectorAll(".icon-in-circle").forEach((e=>{e.remove()})),s(e.dataset.panel)&&e.querySelector("a")?.append(o("!"))}));let e=0;if(document.querySelectorAll("#contact-form-editor .contact-form-editor-panel").forEach((a=>{const r=s(a.id);if(r){e+=r;const c=document.createElement("div");c.classList.add("config-error"),c.append(o("!"),(0,t.sprintf)((0,t._n)("%d configuration error detected in this tab panel.","%d configuration errors detected in this tab panel.",r,"contact-form-7"),r)),a.prepend(c)}})),e){const a=document.createElement("div");a.classList.add("misc-pub-section","config-error");const r=document.createElement("a");r.setAttribute("href",wpcf7.configValidator.docUrl),r.append((0,t.__)("How to resolve?","contact-form-7")),a.append(o("!"),(0,t.sprintf)((0,t._n)("%d configuration error detected.","%d configuration errors detected.",e,"contact-form-7"),e),document.createElement("br"),r),document.querySelector("#misc-publishing-actions")?.append(a)}},s=e=>document.querySelectorAll(`#${e} ul.config-error li`)?.length,d=e=>{const t=[];for(const a in wpcf7.configValidator.errors)a===e&&t.push(...wpcf7.configValidator.errors[a]);return t},u=e=>{if(!e)return"";const t=document.createElement("ul");return t.setAttribute("id",n(`wpcf7-config-error-for-${e}`)),t.classList.add("config-error"),d(e).forEach((e=>{if(!e.message)return;const a=document.createElement("li");if(a.append(o("!")),e.link){const t=document.createElement("a");t.setAttribute("href",e.link),t.append(e.message),a.append(" ",t)}else a.append(" ",e.message);t.append(a)})),t},m=document.querySelector("#wpcf7-welcome-panel"),p=e=>{const t=m.querySelector("#welcomepanelnonce")?.value;if(!t)return;const a=new FormData;a.append("action","wpcf7-update-welcome-panel"),a.append("visible",e),a.append("welcomepanelnonce",t),fetch(new Request(ajaxurl,{method:"POST",body:a})),e?m.classList.remove("hidden"):m.classList.add("hidden")},f=e=>{var t;const a=e.dataset.id,r=e.querySelector('[name="name"]');let c=null!==(t=r?.value.trim())&&void 0!==t?t:"";r&&(c||(c=`${a}-${Math.floor(1e3*Math.random())}`),r.value=c),e.querySelectorAll(".tag").forEach((t=>{const a=e.querySelector('[name="tagtype"]')?.value||t.name;a&&(t.value=v(a,e))})),e.querySelectorAll("span.mail-tag").forEach((e=>{e.innerText=`[${c}]`})),e.querySelectorAll("input.mail-tag").forEach((e=>{e.value=`[${c}]`}))},v=(e,t)=>{var a,r,c;const o=null!==(a=t.querySelector(`.scope.${e}`))&&void 0!==a?a:t,n=e+(t.querySelector('[name="required"]:checked')?"*":""),l=null!==(r=t.querySelector('[name="name"]')?.value)&&void 0!==r?r:"",i=[];o.querySelectorAll(".option").forEach((e=>{"checkbox"===e.type?e.checked&&i.push(e.name):"radio"===e.type?e.checked&&!e.classList.contains("default")&&i.push(`${e.name}:${e.value}`):""!==e.value&&(e.classList.contains("filetype")?i.push(`${e.name}:${e.value.split(/[,|\s]+/).join("|")}`):e.classList.contains("color")?i.push(`${e.name}:#${e.value}`):"class"===e.name?e.value.split(" ").forEach((e=>{i.push(`class:${e}`)})):i.push(`${e.name}:${e.value}`))})),"radio"===e&&i.push("default:1");const s=null!==(c=o.querySelector('[name="values"]')?.value.split("\n").map((e=>e.trim())).filter((e=>""!==e)).map((e=>`"${e.replace(/["]/g,""")}"`)))&&void 0!==c?c:[],d=[n,l,i.join(" "),s.join(" ")].map((e=>e.trim())).filter((e=>""!==e)),u=o.querySelector('[name="content"]')?.value.trim();return u?`[${d.join(" ")}] ${u} [/${n}]`:`[${d.join(" ")}]`},g=e=>{const t=h(e);t?(e.querySelectorAll('[data-tag-part="tag"]').forEach((e=>{e.value=t})),e.querySelectorAll('[data-taggen="insert-tag"]').forEach((e=>{e.disabled=!1})),e.querySelectorAll('[data-tag-part="mail-tag"]').forEach((t=>{const a=e.querySelector('[data-tag-part="name"]');a&&(t.innerText=`[${a.value.trim()}]`)}))):(e.querySelectorAll('[data-tag-part="tag"]').forEach((e=>{e.value=""})),e.querySelectorAll('[data-taggen="insert-tag"]').forEach((e=>{e.disabled=!0})))},h=e=>{var t,a;const r=e.querySelector('[data-tag-part="basetype"]')?.value.trim();if(!r)return;if(e.querySelector(":invalid"))return;let c=r;const o=e.querySelector('[data-tag-part="type-suffix"]');o&&(["checkbox","radio"].includes(o?.type)?c+=o.checked?o.value.trim():"":c+=o.value.trim());const n=e.querySelector('[data-tag-part="name"]');let l=null!==(t=n?.value.trim())&&void 0!==t?t:"";n&&(l||(l=`${r}-${Math.floor(1e3*Math.random())}`),n.value=l);const i=[];e.querySelectorAll('[data-tag-part="option"]').forEach((e=>{const t=e.dataset.tagOption?.trim();t&&(["checkbox","radio"].includes(e?.type)&&!e.checked||t.split(" ").forEach((t=>{t.endsWith(":")?e.value?.split(" ").forEach((e=>{(e=e.trim())&&i.push(t+e)})):i.push(t)})))}));const s=null!==(a=e.querySelector('[data-tag-part="value"]')?.value.split("\n").map((e=>e.trim())).filter((e=>""!==e)).map((e=>`"${e.replace(/["]/g,""")}"`)))&&void 0!==a?a:[],d=[c,l,i.join(" "),s.join(" ")].map((e=>e.trim())).filter((e=>""!==e)),u=e.querySelector('[data-tag-part="content"]')?.value.trim();return u?`[${d.join(" ")}] ${u} [/${c}]`:`[${d.join(" ")}]`},y=e=>{const t=document.querySelector("#wpcf7-admin-form-element");if(!t)return;let a=!1;t.querySelectorAll("input, textarea, select").forEach((e=>{if(!a)switch(e.type){case"button":case"hidden":case"image":case"reset":case"search":case"submit":break;case"checkbox":case"radio":a=e.defaultChecked!==e.checked;break;case"select-multiple":case"select-one":e.querySelectorAll("option").forEach((e=>{a||e.defaultSelected===e.selected||(a=!0)}));break;default:a=e.defaultValue!==e.value}})),a&&e.preventDefault()};document.addEventListener("DOMContentLoaded",(e=>{a&&a.querySelectorAll(':scope > [role="tablist"]').forEach((e=>{const t=e.querySelectorAll(':scope > [role="tab"]');let r=parseInt(e.dataset.activeTab);e.addEventListener("keydown",(a=>{["ArrowLeft","ArrowRight"].includes(a.key)&&(t[r].setAttribute("tabindex","-1"),"ArrowLeft"===a.key&&(r-=1,r<0&&(r=t.length-1)),"ArrowRight"===a.key&&(r+=1,t.length<=r&&(r=0)),t[r].setAttribute("tabindex","0"),t[r].focus(),e.dataset.activeTab=r)})),t.forEach((t=>{t.addEventListener("click",(r=>{const c=t.getAttribute("aria-controls");if(!c)return;const o=c.split(" ").reduceRight(((e,t)=>{const r=a.querySelector(`#${t}`);return r&&(e=r),e}),null);o&&(e.querySelectorAll(':scope > [aria-selected="true"]').forEach((e=>{e.setAttribute("aria-selected","false")})),t.setAttribute("aria-selected","true"),a.querySelectorAll(':scope > [role="tabpanel"]').forEach((e=>{e.setAttribute("hidden","hidden")})),o.removeAttribute("hidden"),document.querySelectorAll('input[name="active-tab"]').forEach((e=>{e.value=o.id})))}))}))})),document.querySelectorAll("#contact-form-editor [data-config-field]").forEach((e=>{e.addEventListener("change",(e=>{const t=document.querySelector('[name="post_ID"]')?.value;t&&0{const{namespace:t}=wpcf7.apiSettings,a=`/${t}/contact-forms/${e}`,r=new FormData;document.querySelectorAll("#contact-form-editor [data-config-field]").forEach((e=>{const t=e.name?.replace(/^wpcf7-/,"").replace(/-/g,"_");if(!t)return;let a;["checkbox","radio"].includes(e.type)?e.checked&&(a=e.value):a=e.value,void 0!==a&&(t.endsWith("[]")?r.append(t,a):r.set(t,a))})),r.set("context","dry-run"),c()({path:a,method:"POST",body:r}).then((e=>{wpcf7.configValidator.errors=e.config_errors,i()}))})(t)}))})),i(),(()=>{if(!m)return;const e=document.querySelector("#wpcf7-welcome-panel-show");m.querySelectorAll(".welcome-panel-close").forEach((t=>{t.addEventListener("click",(t=>{p(0),e?.removeAttribute("checked"),t.preventDefault()}))})),e?.addEventListener("click",(t=>{p(e?.checked?1:0)}))})(),document.querySelectorAll('[data-taggen="open-dialog"]').forEach((e=>{e.addEventListener("click",(t=>{const a=document.querySelector(`#${e.dataset.target}`);if(a){const e=a.querySelector("form.tag-generator-panel");e&&("1"===e.dataset.version?(e=>{f(e),e.querySelectorAll(".control-box").forEach((t=>{t.addEventListener("change",(t=>{var a;"name"===(a=t.target).name&&(a.value=a.value.replace(/[^0-9a-zA-Z:._-]/g,"").replace(/^[^a-zA-Z]+/,"")),a.classList.contains("numeric")&&(a.value=a.value.replace(/[^0-9.-]/g,"")),a.classList.contains("idvalue")&&(a.value=a.value.replace(/[^-0-9a-zA-Z_]/g,"")),a.classList.contains("classvalue")&&(a.value=a.value.split(" ").map((e=>e.replace(/[^-0-9a-zA-Z_]/g,""))).join(" ").replace(/\s+/g," ").trim()),a.classList.contains("color")&&(a.value=a.value.replace(/[^0-9a-fA-F]/g,"")),a.classList.contains("filesize")&&(a.value=a.value.replace(/[^0-9kKmMbB]/g,"")),a.classList.contains("filetype")&&(a.value=a.value.replace(/[^0-9a-zA-Z.,|\s]/g,"")),a.classList.contains("date")&&(a.value.match(/^\d{4}-\d{2}-\d{2}$/)||(a.value="")),"values"===a.name&&(a.value=a.value.trim()),f(e)}))}))})(e):"2"===e.dataset.version&&(e=>{var t;null!==(t=e.reset())&&void 0!==t||g(e),e.querySelectorAll(".control-box").forEach((t=>{t.addEventListener("change",(t=>{g(e)})),t.addEventListener("keyup",(t=>{var a;"text"!==(null!==(a=t.target.type)&&void 0!==a?a:"")&&"textarea"!==t.target.tagName?.toLowerCase()||g(e)}))}))})(e)),a.showModal()}}))})),document.querySelectorAll("dialog.tag-generator-dialog").forEach((e=>{e.querySelectorAll('[data-taggen="close-dialog"]').forEach((t=>{t.addEventListener("click",(t=>e.close("")))})),e.querySelectorAll('[data-taggen="insert-tag"], .insert-tag').forEach((t=>{t.addEventListener("click",(t=>{const a=e.querySelector('[data-tag-part="tag"], .tag');e.close(a?.value)}))})),e.addEventListener("close",(t=>{var a;const r=document.querySelector("textarea#wpcf7-form");if(null===r)return;if(""===e.returnValue)return;const c=null!==(a=r.selectionEnd)&&void 0!==a?a:0;0===c&&(e.returnValue+="\n\n"),r.value=r.value.substring(0,c)+e.returnValue+r.value.substring(c),r.selectionStart=c,r.selectionEnd=c+e.returnValue.length,r.focus()}))})),(()=>{const e=document.querySelector("#wpcf7-admin-form-element");e&&(window.addEventListener("beforeunload",y),e.addEventListener("submit",(e=>{e.submitter?.name&&"wpcf7-copy"===e.submitter.name||window.removeEventListener("beforeunload",y)})))})();const r=document.querySelector("input#title");r&&""===r.value&&r.focus(),document.querySelector("#wpcf7-admin-form-element")?.addEventListener("submit",(e=>{const a=document.querySelector('#wpcf7-admin-form-element [name="action"]'),r=document.querySelector('#wpcf7-admin-form-element [name="_wpnonce"]');"wpcf7-save"===e.submitter?.name&&(a&&(a.value="save"),r&&(r.value=wpcf7.nonce.save),document.querySelectorAll("#wpcf7-admin-form-element #publishing-action .spinner").forEach((e=>{e.classList.add("is-active")}))),"wpcf7-copy"===e.submitter?.name&&(a&&(a.value="copy"),r&&(r.value=wpcf7.nonce.copy)),"wpcf7-delete"===e.submitter?.name&&(window.confirm((0,t.__)("You are about to delete this contact form.\n 'Cancel' to stop, 'OK' to delete.","contact-form-7"))?(a&&(a.value="delete"),r&&(r.value=wpcf7.nonce.delete)):e.preventDefault())})),document.querySelectorAll('.contact-form-editor-box-mail span.mailtag, [data-tag-part="mail-tag"]').forEach((e=>{e.addEventListener("click",(t=>{const a=document.createRange();a.selectNodeContents(e),window.getSelection().addRange(a)}))})),document.querySelectorAll("input.selectable").forEach((e=>{e.addEventListener("click",(t=>{e.focus(),e.select()}))})),document.querySelectorAll("[data-toggle]").forEach((e=>{l(e),e.addEventListener("change",(t=>{l(e)}))})),document.querySelectorAll("#wpcf7-sendinblue-enable-contact-list, #wpcf7-sendinblue-enable-transactional-email").forEach((e=>{e.addEventListener("change",(t=>{e.checked?e.closest("tr").classList.remove("inactive"):e.closest("tr").classList.add("inactive")}))}))}))})(); \ No newline at end of file diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/tag-generator.php b/html/wp-content/plugins/contact-form-7/admin/includes/tag-generator.php new file mode 100644 index 0000000..066b5c1 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/tag-generator.php @@ -0,0 +1,627 @@ + '1', + ) ); + + $this->panels[$id] = array( + 'title' => $title, + 'content' => 'tag-generator-panel-' . $id, + 'options' => $options, + 'callback' => $callback, + ); + + if ( version_compare( $options['version'], '2', '<' ) ) { + $message = sprintf( + /* translators: 1: version, 2: tag generator title */ + __( 'Use of tag generator instances older than version 2 is deprecated. Version %1$s instance (%2$s) detected.', 'contact-form-7' ), + $options['version'], + $title + ); + + wp_trigger_error( __METHOD__, $message, E_USER_DEPRECATED ); + } + + return true; + } + + + /** + * Renders form-tag generator calling buttons. + */ + public function print_buttons() { + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'span', array( + 'id' => 'tag-generator-list', + 'class' => 'hide-if-no-js', + ) ); + + foreach ( (array) $this->panels as $panel ) { + $formatter->append_start_tag( 'button', array( + 'type' => 'button', + 'data-taggen' => 'open-dialog', + 'data-target' => $panel['content'], + 'title' => sprintf( + /* translators: %s: title of form-tag */ + __( 'Form-tag Generator: %s', 'contact-form-7' ), + $panel['title'] + ), + ) ); + + $formatter->append_preformatted( esc_html( $panel['title'] ) ); + } + + $formatter->print(); + } + + + /** + * Renders form-tag generator dialog panels (hidden until called). + */ + public function print_panels( WPCF7_ContactForm $contact_form ) { + $formatter = new WPCF7_HTMLFormatter( array( + 'allowed_html' => array_merge( wpcf7_kses_allowed_html(), array( + 'dialog' => array( + 'id' => true, + 'class' => true, + ), + 'form' => array( + 'method' => true, + 'class' => true, + 'data-*' => true, + ), + ) ), + ) ); + + foreach ( (array) $this->panels as $id => $panel ) { + $callback = $panel['callback']; + + $options = array_merge( $panel['options'], array( + 'id' => $id, + 'title' => $panel['title'], + 'content' => $panel['content'], + ) ); + + if ( is_callable( $callback ) ) { + $formatter->append_start_tag( 'dialog', array( + 'id' => $options['content'], + 'class' => 'tag-generator-dialog', + ) ); + + $formatter->append_start_tag( 'button', array( + 'class' => 'close-button', + 'title' => __( 'Close this dialog box', 'contact-form-7' ), + 'data-taggen' => 'close-dialog', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Close', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'button' ); + + $formatter->append_start_tag( 'form', array( + 'method' => 'dialog', + 'class' => 'tag-generator-panel', + 'data-id' => $options['id'], + 'data-version' => $options['version'], + ) ); + + $formatter->call_user_func( $callback, $contact_form, $options ); + + $formatter->close_all_tags(); + } + } + + $formatter->print(); + } + +} + + +/** + * Class helps to implement a form-tag generator content. + */ +class WPCF7_TagGeneratorGenerator { + + private $key = ''; + + + /** + * The constructor. + */ + public function __construct( $key ) { + $this->key = $key; + } + + + /** + * Returns a unique reference ID. + */ + public function ref( $suffix = '' ) { + $ref = sprintf( '%s-%s', $this->key, $suffix ); + $ref = strtolower( $ref ); + $ref = preg_replace( '/[^0-9a-z-]/', '', $ref ); + $ref = preg_replace( '/[-]+/', '-', $ref ); + $ref = trim( $ref, '-' ); + return $ref; + } + + + /** + * Calls one of the template methods. + */ + public function print( $part, $options = '' ) { + if ( is_callable( array( $this, $part ) ) ) { + call_user_func( array( $this, $part ), $options ); + } + } + + + /** + * Template method for field type field. + */ + private function field_type( $options = '' ) { + $options = wp_parse_args( $options, array( + 'with_required' => false, + 'with_optional' => false, + 'select_options' => array(), + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend', array( + 'id' => $this->ref( 'type-legend' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Field type', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'select', array( + 'data-tag-part' => 'basetype', + 'aria-labelledby' => $this->ref( 'type-legend' ), + ) ); + + foreach ( (array) $options['select_options'] as $basetype => $title ) { + $formatter->append_start_tag( 'option', array( + 'value' => $basetype, + ) ); + + $formatter->append_preformatted( esc_html( $title ) ); + } + + $formatter->end_tag( 'select' ); + + if ( $options['with_required'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'data-tag-part' => 'type-suffix', + 'value' => '*', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'This is a required field.', 'contact-form-7' ) ) + ); + } + + if ( $options['with_optional'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'data-tag-part' => 'option', + 'data-tag-option' => 'optional', + 'checked' => true, + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'This checkbox is optional.', 'contact-form-7' ) ) + ); + } + + $formatter->print(); + } + + + /** + * Template method for field name field. + */ + private function field_name( $options = '' ) { + $options = wp_parse_args( $options, array( + 'ask_if' => '', + ) ); + +?> +
+ + + + +
+ + +
+ +
+ + +
+ +
+ + +
+ 'number', + 'title' => __( 'Length', 'contact-form-7' ), + 'min_option' => 'minlength:', + 'max_option' => 'maxlength:', + 'accept_minus' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend' ); + $formatter->append_preformatted( esc_html( $options['title'] ) ); + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'label' ); + + $formatter->append_preformatted( + esc_html( __( 'Min', 'contact-form-7' ) ) + ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'input', array( + 'type' => $options['type'], + 'data-tag-part' => 'option', + 'data-tag-option' => $options['min_option'], + 'min' => $options['accept_minus'] ? null : 0, + ) ); + + $formatter->end_tag( 'label' ); + + $formatter->append_preformatted( ' ⇔ ' ); + + $formatter->append_start_tag( 'label' ); + + $formatter->append_preformatted( + esc_html( __( 'Max', 'contact-form-7' ) ) + ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'input', array( + 'type' => $options['type'], + 'data-tag-part' => 'option', + 'data-tag-option' => $options['max_option'], + 'min' => $options['accept_minus'] ? null : 0, + ) ); + + $formatter->end_tag( 'label' ); + + $formatter->print(); + } + + + /** + * Template method for default value field. + */ + private function default_value( $options = '' ) { + $options = wp_parse_args( $options, array( + 'type' => 'text', + 'title' => __( 'Default value', 'contact-form-7' ), + 'with_placeholder' => false, + 'use_content' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend', array( + 'id' => $this->ref( 'value-legend' ), + ) ); + + $formatter->append_preformatted( esc_html( $options['title'] ) ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'input', array( + 'type' => $options['type'], + 'data-tag-part' => $options['use_content'] ? 'content' : 'value', + 'aria-labelledby' => $this->ref( 'value-legend' ), + ) ); + + if ( $options['with_placeholder'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'data-tag-part' => 'option', + 'data-tag-option' => 'placeholder', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Use this text as the placeholder.', 'contact-form-7' ) ) + ); + } + + $formatter->print(); + } + + + /** + * Template method for selectable values useful for checkboxes or a menu. + */ + private function selectable_values( $options = '' ) { + $options = wp_parse_args( $options, array( + 'first_as_label' => false, + 'use_label_element' => false, + ) ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset' ); + + $formatter->append_start_tag( 'legend', array( + 'id' => $this->ref( 'selectable-values-legend' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Selectable values', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'legend' ); + + $formatter->append_start_tag( 'span', array( + 'id' => $this->ref( 'selectable-values-description' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( 'One item per line.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'span' ); + + $formatter->append_start_tag( 'br' ); + + $formatter->append_start_tag( 'textarea', array( + 'required' => true, + 'data-tag-part' => 'value', + 'aria-labelledby' => $this->ref( 'selectable-values-legend' ), + 'aria-describedby' => $this->ref( 'selectable-values-description' ), + ) ); + + $formatter->append_preformatted( + esc_html( __( "Option 1\nOption 2\nOption 3", 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'textarea' ); + + if ( $options['first_as_label'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'checked' => 'checked' === $options['first_as_label'], + 'data-tag-part' => 'option', + 'data-tag-option' => 'first_as_label', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Use the first item as a label.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + } + + if ( $options['use_label_element'] ) { + $formatter->append_start_tag( 'br' ); + $formatter->append_start_tag( 'label' ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'checkbox', + 'checked' => 'checked' === $options['use_label_element'], + 'data-tag-part' => 'option', + 'data-tag-option' => 'use_label_element', + ) ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( + esc_html( __( 'Wrap each item with a label element.', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'label' ); + } + + $formatter->print(); + } + + + /** + * Template method for insert-box content including the result form-tag. + */ + private function insert_box_content( $options = '' ) { + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'div', array( + 'class' => 'flex-container', + ) ); + + $formatter->append_start_tag( 'input', array( + 'type' => 'text', + 'class' => 'code selectable', + 'readonly' => true, + 'data-tag-part' => 'tag', + 'aria-label' => __( 'The form-tag to be inserted into the form template', 'contact-form-7' ), + ) ); + + $formatter->append_whitespace(); + + $formatter->append_start_tag( 'button', array( + 'type' => 'button', + 'class' => 'button button-primary', + 'data-taggen' => 'insert-tag', + ) ); + + $formatter->append_preformatted( + esc_html( __( 'Insert Tag', 'contact-form-7' ) ) + ); + + $formatter->end_tag( 'button' ); + + $formatter->print(); + } + + + /** + * Template method for a tip message about mail-tag. + */ + private function mail_tag_tip( $options = '' ) { + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'p', array( + 'class' => 'mail-tag-tip', + ) ); + + $formatter->append_preformatted( sprintf( + /* translators: %s: mail-tag corresponding to the form-tag */ + esc_html( __( 'To use the user input in the email, insert the corresponding mail-tag %s into the email template.', 'contact-form-7' ) ), + '' + ) ); + + $formatter->print(); + } + +} diff --git a/html/wp-content/plugins/contact-form-7/admin/includes/welcome-panel.php b/html/wp-content/plugins/contact-form-7/admin/includes/welcome-panel.php new file mode 100644 index 0000000..ae6ffc9 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/admin/includes/welcome-panel.php @@ -0,0 +1,280 @@ +content(); + + if ( is_array( $content ) ) { + $content = implode( "\n\n", $content ); + } + + $content = wp_kses_post( $content ); + $content = wptexturize( $content ); + $content = convert_chars( $content ); + $content = wpautop( $content ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'div', array( + 'class' => 'welcome-panel-column', + ) ); + + $formatter->append_start_tag( 'h3' ); + + $formatter->append_start_tag( 'span', array( + 'class' => sprintf( 'dashicons dashicons-%s', $this->icon() ), + 'aria-hidden' => 'true', + ) ); + + $formatter->end_tag( 'span' ); + + $formatter->append_whitespace(); + + $formatter->append_preformatted( $this->title() ); + + $formatter->end_tag( 'h3' ); + + $formatter->append_preformatted( $content ); + + $formatter->print(); + } +} + + +class WPCF7_WelcomePanelColumn_AntiSpam extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'shield'; + } + + protected function title() { + return __( 'Getting spammed? You have protection.', 'contact-form-7' ); + } + + protected function content() { + return array( + __( 'Spammers target everything; your contact forms are not an exception. Before you get spammed, protect your contact forms with the powerful anti-spam features Contact Form 7 provides.', 'contact-form-7' ), + sprintf( + /* translators: 1: URL to support page about Akismet, 2: Cloudflare Turnstile, 3: Disallowed list */ + __( 'Contact Form 7 supports spam-filtering with Akismet. Cloudflare Turnstile blocks annoying spambots. Plus, using disallowed list, you can block messages containing specified keywords or those sent from specified IP addresses.', 'contact-form-7' ), + __( 'https://contactform7.com/spam-filtering-with-akismet/', 'contact-form-7' ), + __( 'https://contactform7.com/turnstile-integration/', 'contact-form-7' ), + __( 'https://contactform7.com/comment-blacklist/', 'contact-form-7' ) + ), + ); + } +} + + +class WPCF7_WelcomePanelColumn_Donation extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'megaphone'; + } + + protected function title() { + return __( 'Contact Form 7 needs your support.', 'contact-form-7' ); + } + + protected function content() { + return array( + __( 'It is hard to continue to maintain this plugin without support from users like you.', 'contact-form-7' ), + sprintf( + /* translators: %s: URL to support page about ways to contribute */ + __( 'There are several ways for you to contribute to the project: testing, coding, translating it into your local languages, helping other users, financial donations, etc, etc. We equally welcome you regardless of the way you contribute.', 'contact-form-7' ), + __( 'https://contactform7.com/contributing/', 'contact-form-7' ) + ), + ); + } +} + + +class WPCF7_WelcomePanelColumn_Flamingo extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'editor-help'; + } + + protected function title() { + return __( 'Before you cry over spilt mail…', 'contact-form-7' ); + } + + protected function content() { + return array( + __( 'Contact Form 7 does not store submitted messages anywhere. Therefore, you may lose important messages forever if your mail server has issues or you make a mistake in mail configuration.', 'contact-form-7' ), + sprintf( + /* translators: %s: URL to support page about the Flamingo plugin */ + __( 'Install a message storage plugin before this happens to you. Flamingo saves all messages through contact forms into the database. Flamingo is a free WordPress plugin created by the same author as Contact Form 7.', 'contact-form-7' ), + __( 'https://contactform7.com/save-submitted-messages-with-flamingo/', 'contact-form-7' ) + ), + ); + } +} + + +class WPCF7_WelcomePanelColumn_Integration extends WPCF7_WelcomePanelColumn { + + protected function icon() { + return 'superhero-alt'; + } + + protected function title() { + return __( 'You have strong allies to back you up.', 'contact-form-7' ); + } + + protected function content() { + return array( + sprintf( + /* translators: %s: URL to support page about the Brevo integration */ + __( 'Your contact forms will become more powerful and versatile by integrating them with external APIs. With CRM and email marketing services, you can build your own contact lists (Brevo).', 'contact-form-7' ), + __( 'https://contactform7.com/sendinblue-integration/', 'contact-form-7' ) + ), + sprintf( + /* translators: 1: URL to support page about Cloudflare Turnstile, 2: Stripe */ + __( 'With help from cloud-based machine learning, anti-spam services will protect your forms (Cloudflare Turnstile). Even payment services are natively supported (Stripe).', 'contact-form-7' ), + __( 'https://contactform7.com/turnstile-integration/', 'contact-form-7' ), + __( 'https://contactform7.com/stripe-integration/', 'contact-form-7' ) + ), + ); + } +} + + +function wpcf7_welcome_panel() { + $columns = array(); + + $flamingo_is_active = defined( 'FLAMINGO_VERSION' ); + + $sendinblue_is_active = false; + + if ( + class_exists( 'WPCF7_Sendinblue' ) and + $sendinblue = WPCF7_Sendinblue::get_instance() + ) { + $sendinblue_is_active = $sendinblue->is_active(); + } + + if ( $flamingo_is_active and $sendinblue_is_active ) { + $columns[] = new WPCF7_WelcomePanelColumn_AntiSpam(); + $columns[] = new WPCF7_WelcomePanelColumn_Donation(); + } elseif ( $flamingo_is_active ) { + $columns[] = new WPCF7_WelcomePanelColumn_Integration(); + $columns[] = new WPCF7_WelcomePanelColumn_AntiSpam(); + } elseif ( $sendinblue_is_active ) { + $columns[] = new WPCF7_WelcomePanelColumn_Flamingo(); + $columns[] = new WPCF7_WelcomePanelColumn_AntiSpam(); + } else { + $columns[] = new WPCF7_WelcomePanelColumn_Flamingo(); + $columns[] = new WPCF7_WelcomePanelColumn_Integration(); + } + + $classes = 'wpcf7-welcome-panel'; + + $vers = (array) get_user_meta( get_current_user_id(), + 'wpcf7_hide_welcome_panel_on', true + ); + + if ( wpcf7_version_grep( wpcf7_version( 'only_major=1' ), $vers ) ) { + $classes .= ' hidden'; + } + +?> +
+ + + +
+
+print_content(); + } + +?> +
+
+
+id ) { + return $screen_settings; + } + + $vers = (array) get_user_meta( get_current_user_id(), + 'wpcf7_hide_welcome_panel_on', true + ); + + $checkbox_id = 'wpcf7-welcome-panel-show'; + $checked = ! in_array( wpcf7_version( 'only_major=1' ), $vers, true ); + + $checkbox = sprintf( + '', + wpcf7_format_atts( array( + 'id' => $checkbox_id, + 'type' => 'checkbox', + 'checked' => $checked, + ) ) + ); + + $screen_settings .= sprintf( ' +
+%1$s + +
', + esc_html( __( 'Welcome panel', 'contact-form-7' ) ), + esc_attr( $checkbox_id ), + $checkbox, + esc_html( __( 'Show welcome panel', 'contact-form-7' ) ) + ); + + return $screen_settings; +} diff --git a/html/wp-content/plugins/contact-form-7/assets/icon.png b/html/wp-content/plugins/contact-form-7/assets/icon.png new file mode 100644 index 0000000..f66eefa Binary files /dev/null and b/html/wp-content/plugins/contact-form-7/assets/icon.png differ diff --git a/html/wp-content/plugins/contact-form-7/assets/icon.svg b/html/wp-content/plugins/contact-form-7/assets/icon.svg new file mode 100644 index 0000000..33df0bd --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/assets/icon.svg @@ -0,0 +1 @@ + diff --git a/html/wp-content/plugins/contact-form-7/includes/block-editor/block-editor.php b/html/wp-content/plugins/contact-form-7/includes/block-editor/block-editor.php new file mode 100644 index 0000000..05a1794 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/block-editor/block-editor.php @@ -0,0 +1,13 @@ + array( + 'react-jsx-runtime', + 'wp-api-fetch', + 'wp-block-editor', + 'wp-blocks', + 'wp-components', + 'wp-element', + 'wp-i18n', + 'wp-url', + ), + 'version' => WPCF7_VERSION, +); diff --git a/html/wp-content/plugins/contact-form-7/includes/block-editor/index.js b/html/wp-content/plugins/contact-form-7/includes/block-editor/index.js new file mode 100644 index 0000000..eb68299 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/block-editor/index.js @@ -0,0 +1 @@ +(()=>{"use strict";var t={n:e=>{var l=e&&e.__esModule?()=>e.default:()=>e;return t.d(l,{a:l}),l},d:(e,l)=>{for(var a in l)t.o(l,a)&&!t.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:l[a]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)};const e=window.wp.i18n,l=window.wp.blocks,a=window.wp.blockEditor,r=window.ReactJSXRuntime,o=(0,r.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 242.5 239.46",children:[(0,r.jsx)("defs",{children:(0,r.jsx)("clipPath",{id:"clip-path",transform:"translate(1.72)",children:(0,r.jsx)("circle",{className:"cls-1",cx:"119.73",cy:"119.73",r:"116.15",fill:"none"})})}),(0,r.jsx)("g",{id:"Layer_2","data-name":"Layer 2",children:(0,r.jsxs)("g",{id:"Layer_1","data-name":"Layer 1",children:[(0,r.jsxs)("g",{className:"cls-2",clipPath:"url(#clip-path)",children:[(0,r.jsx)("circle",{className:"cls-3",cx:"121.45",cy:"119.73",r:"116.15",fill:"#33c6f4"}),(0,r.jsx)("path",{className:"cls-4",d:"M239.32,167.79c-53.41-24-108.37-91.46-113-94.55s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11S36.94,237.79,122,237.79C208.48,237.79,239.32,167.79,239.32,167.79Z",transform:"translate(1.72)",fill:"#1b447e"}),(0,r.jsx)("path",{className:"cls-5",d:"M67.48,116.58s15.48-7,12.38,4.65-15.48,28.64-11.61,29.41S83,140.58,86.06,142.12s5.42.78,3.87,6.2-3.1,9.29,0,9.29,5.42-7,9.29-13.94,10.06-3.87,12.38-1.55,9.29,15.49,14.71,13.94,8.51-8.52,6.19-24,1.55-20.12,1.55-20.12,4.64-2.32,13.16,8.51,24,27.09,26.31,26.32-10.83-17.8-7.74-19.35,15.48,2.32,21.68,7.74c0,0,2.12,8.87,2.12.36L126.31,73.24,115.47,74l-10.06.77S80.64,111.94,67.48,116.58Z",transform:"translate(1.72)",fill:"#fff"}),(0,r.jsx)("path",{className:"cls-6",d:"M239.32,170.11c-53.41-24-108.37-93.78-113-96.87s-10.84.77-10.84.77c-3.87-6.19-10.06.77-10.06.77C76.77,123.55.14,170.11.14,170.11",transform:"translate(1.72)",fill:"none",stroke:"#221e1f",strokeMiterlimit:"10",strokeWidth:"8px"})]}),(0,r.jsx)("circle",{className:"cls-6",cx:"121.45",cy:"119.73",r:"116.15",fill:"none",stroke:"#1b447e",strokeMiterlimit:"10",strokeWidth:"8px"})]})})]}),s=window.wp.element,c=window.wp.components,n=window.wp.apiFetch;var i=t.n(n);const m=window.wp.url,h=async t=>i()({path:(0,m.addQueryArgs)("/contact-form-7/v1/contact-forms",{posts_per_page:20,orderby:"modified",order:"DESC",...t})}).then((t=>t)),d=t=>{let e="[contact-form-7]";return t.hash?e=e.replace(/\]$/,` id="${t.hash}"]`):t.id&&(e=e.replace(/\]$/,` id="${t.id}"]`)),t.title&&(e=e.replace(/\]$/,` title="${t.title}"]`)),t.htmlId&&(e=e.replace(/\]$/,` html_id="${t.htmlId}"]`)),t.htmlName&&(e=e.replace(/\]$/,` html_name="${t.htmlName}"]`)),t.htmlTitle&&(e=e.replace(/\]$/,` html_title="${t.htmlTitle}"]`)),t.htmlClass&&(e=e.replace(/\]$/,` html_class="${t.htmlClass}"]`)),"raw_form"===t.output&&(e=e.replace(/\]$/,` output="${t.output}"]`)),e},p=t=>{const e=ajaxurl.replace(/\/admin-ajax\.php$/,"/admin.php");return(0,m.addQueryArgs)(e,{page:"wpcf7",post:t.id,action:"edit"})},f={from:[],to:[{type:"block",blocks:["core/shortcode"],transform:t=>{const e=d(t);return(0,l.createBlock)("core/shortcode",{text:e})}}]};(0,l.registerBlockType)("contact-form-7/contact-form-selector",{icon:o,transforms:f,edit:function({attributes:t,setAttributes:l}){const o=t=>t.reduce(((t,e)=>t.set(e.id,e)),new Map),[n,i]=(0,s.useState)((()=>o([])));return(0,s.useEffect)((()=>{h().then((t=>{i(o(t))}))}),[]),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(a.InspectorControls,{children:[t.id&&(0,r.jsx)(c.PanelBody,{title:t.title,children:(0,r.jsx)(c.ExternalLink,{href:p(t),children:(0,e.__)("Edit this contact form","contact-form-7")})}),t.id&&(0,r.jsxs)(c.PanelBody,{title:(0,e.__)("Form attributes","contact-form-7"),initialOpen:!1,children:[(0,r.jsx)(c.TextControl,{label:(0,e.__)("ID","contact-form-7"),value:t.htmlId,onChange:t=>l({htmlId:t}),help:(0,e.__)("Used for the id attribute value of the form element.","contact-form-7")}),(0,r.jsx)(c.TextControl,{label:(0,e.__)("Name","contact-form-7"),value:t.htmlName,onChange:t=>l({htmlName:t}),help:(0,e.__)("Used for the name attribute value of the form element.","contact-form-7")}),(0,r.jsx)(c.TextControl,{label:(0,e.__)("Title","contact-form-7"),value:t.htmlTitle,onChange:t=>l({htmlTitle:t}),help:(0,e.__)("Used for the aria-label attribute value of the form element.","contact-form-7")}),(0,r.jsx)(c.TextControl,{label:(0,e.__)("Class","contact-form-7"),value:t.htmlClass,onChange:t=>l({htmlClass:t}),help:(0,e.__)("Used for the class attribute value of the form element.","contact-form-7")})]})]}),(0,r.jsx)("div",{...(0,a.useBlockProps)({className:"components-placeholder",style:{marginTop:"28px",marginBottom:"28px"}}),children:(0,r.jsx)(c.ComboboxControl,{label:(0,e.__)("Select a contact form:","contact-form-7"),options:(t=>{const e=[];for(const[l,a]of t)e.push({value:l,label:a.title});return e})(n),value:t.id,onChange:t=>l({id:parseInt(t),hash:n.get(parseInt(t))?.hash,title:n.get(parseInt(t))?.title}),onFilterValueChange:t=>{h({search:t}).then((t=>{i(o(t))}))}})})]})},save:({attributes:t})=>{const e=d(t);return(0,r.jsx)("div",{...a.useBlockProps.save(),children:e})}})})(); \ No newline at end of file diff --git a/html/wp-content/plugins/contact-form-7/includes/capabilities.php b/html/wp-content/plugins/contact-form-7/includes/capabilities.php new file mode 100644 index 0000000..09a478b --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/capabilities.php @@ -0,0 +1,26 @@ + WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_edit_contact_forms' => WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_read_contact_form' => WPCF7_ADMIN_READ_CAPABILITY, + 'wpcf7_read_contact_forms' => WPCF7_ADMIN_READ_CAPABILITY, + 'wpcf7_delete_contact_form' => WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_delete_contact_forms' => WPCF7_ADMIN_READ_WRITE_CAPABILITY, + 'wpcf7_manage_integration' => 'manage_options', + 'wpcf7_submit' => 'read', + ); + + $meta_caps = apply_filters( 'wpcf7_map_meta_cap', $meta_caps ); + + $caps = array_diff( $caps, array_keys( $meta_caps ) ); + + if ( isset( $meta_caps[$cap] ) ) { + $caps[] = $meta_caps[$cap]; + } + + return $caps; +} diff --git a/html/wp-content/plugins/contact-form-7/includes/config-validator/actions.php b/html/wp-content/plugins/contact-form-7/includes/config-validator/actions.php new file mode 100644 index 0000000..d045f75 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/config-validator/actions.php @@ -0,0 +1,27 @@ + 'unsafe_email_without_protection', + ); + + foreach ( $contact_forms as $contact_form ) { + $config_validator = new WPCF7_ConfigValidator( $contact_form, $options ); + $config_validator->restore(); + $config_validator->validate(); + $config_validator->save(); + } + } +} diff --git a/html/wp-content/plugins/contact-form-7/includes/config-validator/additional-settings.php b/html/wp-content/plugins/contact-form-7/includes/config-validator/additional-settings.php new file mode 100644 index 0000000..0d0c788 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/config-validator/additional-settings.php @@ -0,0 +1,28 @@ +supports( 'deprecated_settings' ) ) { + $deprecated_settings_used = + $this->contact_form->additional_setting( 'on_sent_ok' ) || + $this->contact_form->additional_setting( 'on_submit' ); + + if ( $deprecated_settings_used ) { + $this->add_error( $section, 'deprecated_settings', + array( + 'message' => __( 'Deprecated settings are used.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'deprecated_settings' ); + } + } + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/config-validator/form.php b/html/wp-content/plugins/contact-form-7/includes/config-validator/form.php new file mode 100644 index 0000000..a480456 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/config-validator/form.php @@ -0,0 +1,278 @@ +contact_form->prop( 'form' ); + + if ( $this->supports( 'multiple_controls_in_label' ) ) { + if ( $this->detect_multiple_controls_in_label( $section, $form ) ) { + $this->add_error( $section, 'multiple_controls_in_label', + array( + 'message' => __( 'Multiple form controls are in a single label element.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'multiple_controls_in_label' ); + } + } + + if ( $this->supports( 'unavailable_names' ) ) { + $ng_names = $this->detect_unavailable_names( $section, $form ); + + if ( $ng_names ) { + $this->add_error( $section, 'unavailable_names', + array( + 'message' => + /* translators: %names%: a list of form control names */ + __( 'Unavailable names (%names%) are used for form controls.', 'contact-form-7' ), + 'params' => array( 'names' => implode( ', ', $ng_names ) ), + ) + ); + } else { + $this->remove_error( $section, 'unavailable_names' ); + } + } + + if ( $this->supports( 'unavailable_html_elements' ) ) { + if ( $this->detect_unavailable_html_elements( $section, $form ) ) { + $this->add_error( $section, 'unavailable_html_elements', + array( + 'message' => __( 'Unavailable HTML elements are used in the form template.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'unavailable_html_elements' ); + } + } + + if ( $this->supports( 'dots_in_names' ) ) { + if ( $this->detect_dots_in_names( $section, $form ) ) { + $this->add_error( $section, 'dots_in_names', + array( + 'message' => __( 'Dots are used in form-tag names.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'dots_in_names' ); + } + } + + if ( $this->supports( 'colons_in_names' ) ) { + if ( $this->detect_colons_in_names( $section, $form ) ) { + $this->add_error( $section, 'colons_in_names', + array( + 'message' => __( 'Colons are used in form-tag names.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'colons_in_names' ); + } + } + + if ( $this->supports( 'upload_filesize_overlimit' ) ) { + if ( $this->detect_upload_filesize_overlimit( $section, $form ) ) { + $this->add_error( $section, 'upload_filesize_overlimit', + array( + 'message' => __( 'Uploadable file size exceeds PHP’s maximum acceptable size.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'upload_filesize_overlimit' ); + } + } + } + + + /** + * Detects errors of multiple form controls in a single label. + * + * @link https://contactform7.com/configuration-errors/multiple-controls-in-label/ + */ + public function detect_multiple_controls_in_label( $section, $content ) { + $pattern = '%(.+?)%s'; + + if ( preg_match_all( $pattern, $content, $matches ) ) { + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + foreach ( $matches[1] as $insidelabel ) { + $tags = $form_tags_manager->scan( $insidelabel ); + $fields_count = 0; + + foreach ( $tags as $tag ) { + $is_multiple_controls_container = wpcf7_form_tag_supports( + $tag->type, 'multiple-controls-container' + ); + + $is_zero_controls_container = wpcf7_form_tag_supports( + $tag->type, 'zero-controls-container' + ); + + if ( $is_multiple_controls_container ) { + $fields_count += count( $tag->values ); + + if ( $tag->has_option( 'free_text' ) ) { + $fields_count += 1; + } + } elseif ( $is_zero_controls_container ) { + $fields_count += 0; + } elseif ( ! empty( $tag->name ) ) { + $fields_count += 1; + } + + if ( 1 < $fields_count ) { + return true; + } + } + } + } + + return false; + } + + + /** + * Detects errors of unavailable form-tag names. + * + * @link https://contactform7.com/configuration-errors/unavailable-names/ + */ + public function detect_unavailable_names( $section, $content ) { + $public_query_vars = array( 'm', 'p', 'posts', 'w', 'cat', + 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', + 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', + 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', + 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', + 'pagename', 'page_id', 'error', 'attachment', 'attachment_id', + 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', + 'cpage', 'post_type', 'embed', + ); + + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $ng_named_tags = $form_tags_manager->filter( $content, array( + 'name' => $public_query_vars, + ) ); + + $ng_names = array(); + + foreach ( $ng_named_tags as $tag ) { + $ng_names[] = sprintf( '"%s"', $tag->name ); + } + + if ( $ng_names ) { + return array_unique( $ng_names ); + } + + return false; + } + + + /** + * Detects errors of unavailable HTML elements. + * + * @link https://contactform7.com/configuration-errors/unavailable-html-elements/ + */ + public function detect_unavailable_html_elements( $section, $content ) { + $pattern = '%(?:]|)%i'; + + if ( preg_match( $pattern, $content ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of dots in form-tag names. + * + * @link https://contactform7.com/configuration-errors/dots-in-names/ + */ + public function detect_dots_in_names( $section, $content ) { + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $tags = $form_tags_manager->filter( $content, array( + 'feature' => 'name-attr', + ) ); + + foreach ( $tags as $tag ) { + if ( str_contains( $tag->raw_name, '.' ) ) { + return true; + } + } + + return false; + } + + + /** + * Detects errors of colons in form-tag names. + * + * @link https://contactform7.com/configuration-errors/colons-in-names/ + */ + public function detect_colons_in_names( $section, $content ) { + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $tags = $form_tags_manager->filter( $content, array( + 'feature' => 'name-attr', + ) ); + + foreach ( $tags as $tag ) { + if ( str_contains( $tag->raw_name, ':' ) ) { + return true; + } + } + + return false; + } + + + /** + * Detects errors of uploadable file size overlimit. + * + * @link https://contactform7.com/configuration-errors/upload-filesize-overlimit + */ + public function detect_upload_filesize_overlimit( $section, $content ) { + $upload_max_filesize = ini_get( 'upload_max_filesize' ); + + if ( ! $upload_max_filesize ) { + return false; + } + + $upload_max_filesize = strtolower( $upload_max_filesize ); + $upload_max_filesize = trim( $upload_max_filesize ); + + if ( ! preg_match( '/^(\d+)([kmg]?)$/', $upload_max_filesize, $matches ) ) { + return false; + } + + if ( 'k' === $matches[2] ) { + $upload_max_filesize = (int) $matches[1] * KB_IN_BYTES; + } elseif ( 'm' === $matches[2] ) { + $upload_max_filesize = (int) $matches[1] * MB_IN_BYTES; + } elseif ( 'g' === $matches[2] ) { + $upload_max_filesize = (int) $matches[1] * GB_IN_BYTES; + } else { + $upload_max_filesize = (int) $matches[1]; + } + + $form_tags_manager = WPCF7_FormTagsManager::get_instance(); + + $tags = $form_tags_manager->filter( $content, array( + 'basetype' => 'file', + ) ); + + foreach ( $tags as $tag ) { + if ( $upload_max_filesize < $tag->get_limit_option() ) { + return true; + } + } + + return false; + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/config-validator/mail.php b/html/wp-content/plugins/contact-form-7/includes/config-validator/mail.php new file mode 100644 index 0000000..131810f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/config-validator/mail.php @@ -0,0 +1,583 @@ + false, + 'callback' => + array( $this, 'replace_mail_tags_with_minimum_input_callback' ), + ) ); + + $content = new WPCF7_MailTaggedText( $content, $options ); + + return $content->replace_tags(); + } + + + /** + * Callback function for WPCF7_MailTaggedText. Replaces mail-tags with + * the most conservative inputs. + */ + public function replace_mail_tags_with_minimum_input_callback( $matches ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[4] ) { + return substr( $matches[0], 1, -1 ); + } + + $tag = $matches[0]; + $tagname = $matches[2]; + $values = $matches[3]; + + $mail_tag = new WPCF7_MailTag( $tag, $tagname, $values ); + $field_name = $mail_tag->field_name(); + + $example_email = 'example@example.com'; + $example_text = 'example'; + $example_blank = ''; + + // for back-compat + $field_name = preg_replace( '/^wpcf7\./', '_', $field_name ); + + if ( '_site_admin_email' === $field_name ) { + return get_bloginfo( 'admin_email', 'raw' ); + + } elseif ( '_user_agent' === $field_name ) { + return $example_text; + + } elseif ( '_user_email' === $field_name ) { + return $this->contact_form->is_true( 'subscribers_only' ) + ? $example_email + : $example_blank; + + } elseif ( str_starts_with( $field_name, '_user_' ) ) { + return $this->contact_form->is_true( 'subscribers_only' ) + ? $example_text + : $example_blank; + + } elseif ( str_starts_with( $field_name, '_' ) ) { + return str_ends_with( $field_name, '_email' ) + ? $example_email + : $example_text; + + } + + static $opcalcset = array(); + + if ( ! isset( $opcalcset[$this->contact_form->id()] ) ) { + $opcalcset[$this->contact_form->id()] = + new WPCF7_MailTag_OutputCalculator( $this->contact_form ); + } + + $opcalc = $opcalcset[$this->contact_form->id()]; + $op = $opcalc->calc_output( $mail_tag ); + + if ( WPCF7_MailTag_OutputCalculator::email === $op ) { + return $example_email; + } elseif ( ! ( WPCF7_MailTag_OutputCalculator::blank & $op ) ) { + return $example_text; + } else { + return $example_blank; + } + } + + + /** + * Runs error detection for the mail sections. + */ + public function validate_mail( $template = 'mail' ) { + if ( + $this->contact_form->is_true( 'demo_mode' ) or + $this->contact_form->is_true( 'skip_mail' ) + ) { + return; + } + + $components = (array) $this->contact_form->prop( $template ); + + if ( ! $components ) { + return; + } + + if ( 'mail' !== $template and empty( $components['active'] ) ) { + return; + } + + $components = wp_parse_args( $components, array( + 'subject' => '', + 'sender' => '', + 'recipient' => '', + 'additional_headers' => '', + 'body' => '', + 'attachments' => '', + ) ); + + $this->validate_mail_subject( + $template, + $components['subject'] + ); + + $this->validate_mail_sender( + $template, + $components['sender'] + ); + + $this->validate_mail_recipient( + $template, + $components['recipient'] + ); + + $this->validate_mail_additional_headers( + $template, + $components['additional_headers'] + ); + + $this->validate_mail_body( + $template, + $components['body'] + ); + + $this->validate_mail_attachments( + $template, + $components['attachments'] + ); + } + + + /** + * Runs error detection for the mail subject section. + */ + public function validate_mail_subject( $template, $content ) { + $section = sprintf( '%s.subject', $template ); + + if ( $this->supports( 'maybe_empty' ) ) { + if ( $this->detect_maybe_empty( $section, $content ) ) { + $this->add_error( $section, 'maybe_empty', + array( + 'message' => __( 'There is a possible empty field.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'maybe_empty' ); + } + } + } + + + /** + * Runs error detection for the mail sender section. + */ + public function validate_mail_sender( $template, $content ) { + $section = sprintf( '%s.sender', $template ); + + if ( $this->supports( 'invalid_mailbox_syntax' ) ) { + if ( $this->detect_invalid_mailbox_syntax( $section, $content ) ) { + $this->add_error( $section, 'invalid_mailbox_syntax', + array( + 'message' => __( 'Invalid mailbox syntax is used.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'invalid_mailbox_syntax' ); + } + } + + if ( $this->supports( 'email_not_in_site_domain' ) ) { + $this->remove_error( $section, 'email_not_in_site_domain' ); + + if ( ! $this->has_error( $section, 'invalid_mailbox_syntax' ) ) { + $sender = $this->replace_mail_tags( $content ); + $sender = wpcf7_strip_newline( $sender ); + + if ( ! wpcf7_is_email_in_site_domain( $sender ) ) { + $this->add_error( $section, 'email_not_in_site_domain', + array( + 'message' => __( 'Sender email address does not belong to the site domain.', 'contact-form-7' ), + ) + ); + } + } + } + } + + + /** + * Runs error detection for the mail recipient section. + */ + public function validate_mail_recipient( $template, $content ) { + $section = sprintf( '%s.recipient', $template ); + + if ( $this->supports( 'invalid_mailbox_syntax' ) ) { + if ( $this->detect_invalid_mailbox_syntax( $section, $content ) ) { + $this->add_error( $section, 'invalid_mailbox_syntax', + array( + 'message' => __( 'Invalid mailbox syntax is used.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'invalid_mailbox_syntax' ); + } + } + + if ( $this->supports( 'unsafe_email_without_protection' ) ) { + $this->remove_error( $section, 'unsafe_email_without_protection' ); + + if ( ! $this->has_error( $section, 'invalid_mailbox_syntax' ) ) { + if ( + $this->detect_unsafe_email_without_protection( $section, $content ) + ) { + $this->add_error( $section, 'unsafe_email_without_protection', + array( + 'message' => __( 'Unsafe email config is used without sufficient protection.', 'contact-form-7' ), + ) + ); + } + } + } + } + + + /** + * Runs error detection for the mail additional headers section. + */ + public function validate_mail_additional_headers( $template, $content ) { + $section = sprintf( '%s.additional_headers', $template ); + + $invalid_mail_headers = array(); + $invalid_mailbox_fields = array(); + $unsafe_email_fields = array(); + + foreach ( explode( "\n", $content ) as $header ) { + $header = trim( $header ); + + if ( '' === $header ) { + continue; + } + + $is_valid_header = preg_match( + '/^([0-9A-Za-z-]+):(.*)$/', + $header, + $matches + ); + + if ( ! $is_valid_header ) { + $invalid_mail_headers[] = $header; + continue; + } + + $header_name = $matches[1]; + $header_value = trim( $matches[2] ); + + if ( + in_array( + strtolower( $header_name ), array( 'reply-to', 'cc', 'bcc' ), true + ) and + '' !== $header_value and + $this->detect_invalid_mailbox_syntax( $section, $header_value ) + ) { + $invalid_mailbox_fields[] = $header_name; + continue; + } + + if ( + in_array( strtolower( $header_name ), array( 'cc', 'bcc' ), true ) and + $this->detect_unsafe_email_without_protection( $section, $header_value ) + ) { + $unsafe_email_fields[] = $header_name; + } + } + + if ( $this->supports( 'invalid_mail_header' ) ) { + if ( ! empty( $invalid_mail_headers ) ) { + $this->add_error( $section, 'invalid_mail_header', + array( + 'message' => __( 'There are invalid mail header fields.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'invalid_mail_header' ); + } + } + + if ( $this->supports( 'invalid_mailbox_syntax' ) ) { + if ( ! empty( $invalid_mailbox_fields ) ) { + foreach ( $invalid_mailbox_fields as $header_name ) { + $this->add_error( $section, 'invalid_mailbox_syntax', + array( + 'message' => __( 'Invalid mailbox syntax is used in the %name% field.', 'contact-form-7' ), + 'params' => array( 'name' => $header_name ), + ) + ); + } + } else { + $this->remove_error( $section, 'invalid_mailbox_syntax' ); + } + } + + if ( $this->supports( 'unsafe_email_without_protection' ) ) { + if ( ! empty( $unsafe_email_fields ) ) { + $this->add_error( $section, 'unsafe_email_without_protection', + array( + 'message' => __( 'Unsafe email config is used without sufficient protection.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'unsafe_email_without_protection' ); + } + } + } + + + /** + * Runs error detection for the mail body section. + */ + public function validate_mail_body( $template, $content ) { + $section = sprintf( '%s.body', $template ); + + if ( $this->supports( 'maybe_empty' ) ) { + if ( $this->detect_maybe_empty( $section, $content ) ) { + $this->add_error( $section, 'maybe_empty', + array( + 'message' => __( 'There is a possible empty field.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'maybe_empty' ); + } + } + } + + + /** + * Runs error detection for the mail attachments section. + */ + public function validate_mail_attachments( $template, $content ) { + $section = sprintf( '%s.attachments', $template ); + + $total_size = 0; + $files_not_found = array(); + $files_out_of_content = array(); + + if ( '' !== $content ) { + $attachables = array(); + + $tags = $this->contact_form->scan_form_tags( + array( 'type' => array( 'file', 'file*' ) ) + ); + + foreach ( $tags as $tag ) { + $name = $tag->name; + + if ( ! str_contains( $content, "[{$name}]" ) ) { + continue; + } + + $limit = (int) $tag->get_limit_option(); + + if ( empty( $attachables[$name] ) or $attachables[$name] < $limit ) { + $attachables[$name] = $limit; + } + } + + $total_size = array_sum( $attachables ); + + foreach ( explode( "\n", $content ) as $line ) { + $line = trim( $line ); + + if ( '' === $line or str_starts_with( $line, '[' ) ) { + continue; + } + + if ( $this->detect_file_not_found( $section, $line ) ) { + $files_not_found[] = $line; + } elseif ( $this->detect_file_not_in_content_dir( $section, $line ) ) { + $files_out_of_content[] = $line; + } else { + $total_size += (int) @filesize( path_join( WP_CONTENT_DIR, $line ) ); + } + } + } + + if ( $this->supports( 'file_not_found' ) ) { + if ( ! empty( $files_not_found ) ) { + foreach ( $files_not_found as $line ) { + $this->add_error( $section, 'file_not_found', + array( + 'message' => __( 'Attachment file does not exist at %path%.', 'contact-form-7' ), + 'params' => array( 'path' => $line ), + ) + ); + } + } else { + $this->remove_error( $section, 'file_not_found' ); + } + } + + if ( $this->supports( 'file_not_in_content_dir' ) ) { + if ( ! empty( $files_out_of_content ) ) { + $this->add_error( $section, 'file_not_in_content_dir', + array( + 'message' => __( 'It is not allowed to use files outside the wp-content directory.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'file_not_in_content_dir' ); + } + } + + if ( $this->supports( 'attachments_overweight' ) ) { + $max = 25 * MB_IN_BYTES; // 25 MB + + if ( $max < $total_size ) { + $this->add_error( $section, 'attachments_overweight', + array( + 'message' => __( 'The total size of attachment files is too large.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'attachments_overweight' ); + } + } + } + + + /** + * Detects errors of invalid mailbox syntax. + * + * @link https://contactform7.com/configuration-errors/invalid-mailbox-syntax/ + */ + public function detect_invalid_mailbox_syntax( $section, $content ) { + $content = $this->replace_mail_tags( $content ); + $content = wpcf7_strip_newline( $content ); + + if ( ! wpcf7_is_mailbox_list( $content ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of empty message fields. + * + * @link https://contactform7.com/configuration-errors/maybe-empty/ + */ + public function detect_maybe_empty( $section, $content ) { + $content = $this->replace_mail_tags( $content ); + $content = wpcf7_strip_newline( $content ); + + if ( '' === $content ) { + return true; + } + + return false; + } + + + /** + * Detects errors of nonexistent attachment files. + * + * @link https://contactform7.com/configuration-errors/file-not-found/ + */ + public function detect_file_not_found( $section, $content ) { + $path = path_join( WP_CONTENT_DIR, $content ); + + if ( ! is_readable( $path ) or ! is_file( $path ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of attachment files out of the content directory. + * + * @link https://contactform7.com/configuration-errors/file-not-in-content-dir/ + */ + public function detect_file_not_in_content_dir( $section, $content ) { + $path = path_join( WP_CONTENT_DIR, $content ); + + if ( ! wpcf7_is_file_path_in_content_dir( $path ) ) { + return true; + } + + return false; + } + + + /** + * Detects errors of that unsafe email config is used without + * sufficient protection. + * + * @link https://contactform7.com/configuration-errors/unsafe-email-without-protection/ + */ + public function detect_unsafe_email_without_protection( $section, $content ) { + if ( $this->contact_form->is_true( 'subscribers_only' ) ) { + return false; + } + + static $is_captcha_active = null; + + if ( null === $is_captcha_active ) { + $is_captcha_active = call_user_func( static function () { + $recaptcha = WPCF7_RECAPTCHA::get_instance(); + $turnstile = WPCF7_Turnstile::get_instance(); + return $recaptcha->is_active() || $turnstile->is_active(); + } ); + } + + if ( $is_captcha_active ) { + return false; + } + + $example_email = 'user-specified@example.com'; + + // Replace mail-tags connected to an email type form-tag first. + $content = $this->replace_mail_tags( $content, array( + 'callback' => function ( $matches ) use ( $example_email ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[4] ) { + return substr( $matches[0], 1, -1 ); + } + + $tag = $matches[0]; + $tagname = $matches[2]; + $values = $matches[3]; + + $mail_tag = new WPCF7_MailTag( $tag, $tagname, $values ); + $field_name = $mail_tag->field_name(); + + $form_tags = $this->contact_form->scan_form_tags( + array( 'name' => $field_name ) + ); + + if ( $form_tags ) { + $form_tag = new WPCF7_FormTag( $form_tags[0] ); + + if ( 'email' === $form_tag->basetype ) { + return $example_email; + } + } + + return $tag; + }, + ) ); + + // Replace remaining mail-tags. + $content = $this->replace_mail_tags( $content ); + + $content = wpcf7_strip_newline( $content ); + + if ( str_contains( $content, $example_email ) ) { + return true; + } + + return false; + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/config-validator/messages.php b/html/wp-content/plugins/contact-form-7/includes/config-validator/messages.php new file mode 100644 index 0000000..0194d2c --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/config-validator/messages.php @@ -0,0 +1,55 @@ +contact_form->prop( 'messages' ); + + if ( ! $messages ) { + return; + } + + if ( + isset( $messages['captcha_not_match'] ) and + ! wpcf7_use_really_simple_captcha() + ) { + unset( $messages['captcha_not_match'] ); + } + + foreach ( $messages as $key => $message ) { + $section = sprintf( 'messages.%s', $key ); + + if ( $this->supports( 'html_in_message' ) ) { + if ( $this->detect_html_in_message( $section, $message ) ) { + $this->add_error( $section, 'html_in_message', + array( + 'message' => __( 'HTML tags are used in a message.', 'contact-form-7' ), + ) + ); + } else { + $this->remove_error( $section, 'html_in_message' ); + } + } + } + } + + + /** + * Detects errors of HTML uses in a message. + * + * @link https://contactform7.com/configuration-errors/html-in-message/ + */ + public function detect_html_in_message( $section, $content ) { + $stripped = wp_strip_all_tags( $content ); + + if ( $stripped !== $content ) { + return true; + } + + return false; + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/config-validator/validator.php b/html/wp-content/plugins/contact-form-7/includes/config-validator/validator.php new file mode 100644 index 0000000..cc33294 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/config-validator/validator.php @@ -0,0 +1,386 @@ + null, + 'exclude' => null, + ) ); + + $this->contact_form = $contact_form; + + if ( isset( $options['include'] ) ) { + $this->include = (array) $options['include']; + } + + if ( isset( $options['exclude'] ) ) { + $this->exclude = (array) $options['exclude']; + } + } + + + /** + * Returns the contact form object that is tied to this validator. + */ + public function contact_form() { + return $this->contact_form; + } + + + /** + * Returns true if no error has been detected. + */ + public function is_valid() { + return ! $this->count_errors(); + } + + + /** + * Returns true if the given error code is supported by this instance. + */ + public function supports( $error_code ) { + if ( isset( $this->include ) ) { + $supported_codes = array_intersect( self::error_codes, $this->include ); + } else { + $supported_codes = self::error_codes; + } + + if ( isset( $this->exclude ) ) { + $supported_codes = array_diff( $supported_codes, $this->exclude ); + } + + return in_array( $error_code, $supported_codes, true ); + } + + + /** + * Counts detected errors. + */ + public function count_errors( $options = '' ) { + $options = wp_parse_args( $options, array( + 'section' => '', + 'code' => '', + ) ); + + $count = 0; + + foreach ( $this->errors as $key => $errors ) { + if ( preg_match( '/^mail_[0-9]+\.(.*)$/', $key, $matches ) ) { + $key = sprintf( 'mail.%s', $matches[1] ); + } + + if ( + $options['section'] and + $key !== $options['section'] and + preg_replace( '/\..*$/', '', $key, 1 ) !== $options['section'] + ) { + continue; + } + + foreach ( $errors as $error ) { + if ( empty( $error ) ) { + continue; + } + + if ( $options['code'] and $error['code'] !== $options['code'] ) { + continue; + } + + $count += 1; + } + } + + return $count; + } + + + /** + * Collects messages for detected errors. + */ + public function collect_error_messages( $options = '' ) { + $options = wp_parse_args( $options, array( + 'decodes_html_entities' => false, + ) ); + + $error_messages = array(); + + foreach ( $this->errors as $section => $errors ) { + $error_messages[$section] = array(); + + foreach ( $errors as $error ) { + if ( empty( $error['args']['message'] ) ) { + $message = $this->get_default_message( $error['code'] ); + } elseif ( empty( $error['args']['params'] ) ) { + $message = $error['args']['message']; + } else { + $message = $this->build_message( + $error['args']['message'], + $error['args']['params'] + ); + } + + if ( $options['decodes_html_entities'] ) { + $message = html_entity_decode( $message, ENT_HTML5 ); + } + + $link = ''; + + if ( ! empty( $error['args']['link'] ) ) { + $link = $error['args']['link']; + } + + $error_messages[$section][] = array( + 'message' => $message, + 'link' => esc_url( $link ), + ); + } + } + + return $error_messages; + } + + + /** + * Builds an error message by replacing placeholders. + */ + public function build_message( $message, $params = '' ) { + $params = wp_parse_args( $params, array() ); + + foreach ( $params as $key => $val ) { + if ( ! preg_match( '/^[0-9A-Za-z_]+$/', $key ) ) { // invalid key + continue; + } + + $placeholder = '%' . $key . '%'; + + if ( false !== stripos( $message, $placeholder ) ) { + $message = str_ireplace( $placeholder, $val, $message ); + } + } + + return $message; + } + + + /** + * Returns a default message that is used when the message for the error + * is not specified. + */ + public function get_default_message( $code = '' ) { + return __( 'Configuration error is detected.', 'contact-form-7' ); + } + + + /** + * Returns true if the specified section has the specified error. + * + * @param string $section The section where the error detected. + * @param string $code The unique code of the error. + */ + public function has_error( $section, $code ) { + if ( empty( $this->errors[$section] ) ) { + return false; + } + + foreach ( (array) $this->errors[$section] as $error ) { + if ( isset( $error['code'] ) and $error['code'] === $code ) { + return true; + } + } + + return false; + } + + + /** + * Adds a validation error. + * + * @param string $section The section where the error detected. + * @param string $code The unique code of the error. + * @param string|array $args Optional options for the error. + */ + public function add_error( $section, $code, $args = '' ) { + $args = wp_parse_args( $args, array( + 'message' => '', + 'params' => array(), + ) ); + + $available_error_codes = (array) apply_filters( + 'wpcf7_config_validator_available_error_codes', + self::error_codes, + $this->contact_form + ); + + if ( ! in_array( $code, $available_error_codes, true ) ) { + return false; + } + + if ( ! isset( $args['link'] ) ) { + $args['link'] = self::get_doc_link( $code ); + } + + if ( ! isset( $this->errors[$section] ) ) { + $this->errors[$section] = array(); + } + + $this->errors[$section][] = array( + 'code' => $code, + 'args' => $args, + ); + + return true; + } + + + /** + * Removes an error. + * + * @param string $section The section where the error detected. + * @param string $code The unique code of the error. + */ + public function remove_error( $section, $code ) { + if ( empty( $this->errors[$section] ) ) { + return; + } + + foreach ( (array) $this->errors[$section] as $key => $error ) { + if ( isset( $error['code'] ) and $error['code'] === $code ) { + unset( $this->errors[$section][$key] ); + } + } + + if ( empty( $this->errors[$section] ) ) { + unset( $this->errors[$section] ); + } + } + + + /** + * The main validation runner. + * + * @return bool True if there is no error detected. + */ + public function validate() { + $this->validate_form(); + $this->validate_mail( 'mail' ); + $this->validate_mail( 'mail_2' ); + $this->validate_messages(); + $this->validate_additional_settings(); + + do_action( 'wpcf7_config_validator_validate', $this ); + + return $this->is_valid(); + } + + + /** + * Saves detected errors as a post meta data. + */ + public function save() { + if ( $this->contact_form->initial() ) { + return; + } + + delete_post_meta( $this->contact_form->id(), '_config_validation' ); + + if ( $this->errors ) { + update_post_meta( + $this->contact_form->id(), '_config_validation', $this->errors + ); + } + } + + + /** + * Restore errors from the database. + */ + public function restore() { + $config_errors = get_post_meta( + $this->contact_form->id(), '_config_validation', true + ); + + foreach ( (array) $config_errors as $section => $errors ) { + if ( empty( $errors ) ) { + continue; + } + + foreach ( (array) $errors as $error ) { + if ( ! empty( $error['code'] ) ) { + $code = $error['code']; + $args = isset( $error['args'] ) ? $error['args'] : ''; + $this->add_error( $section, $code, $args ); + } + } + } + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/contact-form-functions.php b/html/wp-content/plugins/contact-form-7/includes/contact-form-functions.php new file mode 100644 index 0000000..f054faa --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/contact-form-functions.php @@ -0,0 +1,476 @@ + array( + array( + 'key' => '_old_cf7_unit_id', + 'type' => 'DECIMAL', + 'value' => $old_id, + ), + ), + 'posts_per_page' => 1, + ) ); + + if ( $contact_forms ) { + return wpcf7_contact_form( $contact_forms[0] ); + } +} + + +/** + * Searches for a contact form by a hash string. + * + * @param string $hash Part of a hash string. + * @return WPCF7_ContactForm Contact form object. + */ +function wpcf7_get_contact_form_by_hash( $hash ) { + if ( ! preg_match( '/^[0-9a-f]{7,}$/', $hash ) ) { + return null; + } + + $contact_forms = WPCF7_ContactForm::find( array( + 'meta_query' => array( + array( + 'key' => '_hash', + 'compare' => 'REGEXP', + 'value' => '^' . $hash, + ), + ), + 'posts_per_page' => 1, + ) ); + + if ( $contact_forms ) { + return wpcf7_contact_form( $contact_forms[0] ); + } +} + + +/** + * Searches for a contact form by title. + * + * @param string $title Title of contact form. + * @return WPCF7_ContactForm|null Contact form object if found, null otherwise. + */ +function wpcf7_get_contact_form_by_title( $title ) { + if ( ! is_string( $title ) or '' === $title ) { + return null; + } + + $contact_forms = WPCF7_ContactForm::find( array( + 'title' => $title, + 'posts_per_page' => 1, + ) ); + + if ( $contact_forms ) { + return wpcf7_contact_form( $contact_forms[0] ); + } +} + + +/** + * Wrapper function of WPCF7_ContactForm::get_current(). + * + * @return WPCF7_ContactForm Contact form object. + */ +function wpcf7_get_current_contact_form() { + if ( $current = WPCF7_ContactForm::get_current() ) { + return $current; + } +} + + +/** + * Returns true if it is in the state that a non-Ajax submission is accepted. + */ +function wpcf7_is_posted() { + if ( ! $contact_form = wpcf7_get_current_contact_form() ) { + return false; + } + + return $contact_form->is_posted(); +} + + +/** + * Retrieves the user input value through a non-Ajax submission. + * + * @param string $name Name of form control. + * @param string $default_value Optional default value. + * @return string The user input value through the form-control. + */ +function wpcf7_get_hangover( $name, $default_value = null ) { + if ( ! wpcf7_is_posted() ) { + return $default_value; + } + + $submission = WPCF7_Submission::get_instance(); + + if ( ! $submission or $submission->is( 'mail_sent' ) ) { + return $default_value; + } + + return wpcf7_superglobal_post( $name, $default_value ); +} + + +/** + * Retrieves an HTML snippet of validation error on the given form control. + * + * @param string $name Name of form control. + * @return string Validation error message in a form of HTML snippet. + */ +function wpcf7_get_validation_error( $name ) { + if ( ! $contact_form = wpcf7_get_current_contact_form() ) { + return ''; + } + + return $contact_form->validation_error( $name ); +} + + +/** + * Returns a reference key to a validation error message. + * + * @param string $name Name of form control. + * @param string $unit_tag Optional. Unit tag of the contact form. + * @return string Reference key code. + */ +function wpcf7_get_validation_error_reference( $name, $unit_tag = '' ) { + if ( '' === $unit_tag ) { + $contact_form = wpcf7_get_current_contact_form(); + + if ( $contact_form and $contact_form->validation_error( $name ) ) { + $unit_tag = $contact_form->unit_tag(); + } else { + return null; + } + } + + return preg_replace( '/[^0-9a-z_-]+/i', '', + sprintf( + '%1$s-ve-%2$s', + $unit_tag, + $name + ) + ); +} + + +/** + * Retrieves a message for the given status. + */ +function wpcf7_get_message( $status ) { + if ( ! $contact_form = wpcf7_get_current_contact_form() ) { + return ''; + } + + return $contact_form->message( $status ); +} + + +/** + * Returns a class names list for a form-tag of the specified type. + * + * @param string $type Form-tag type. + * @param string $default_classes Optional default classes. + * @return string Whitespace-separated list of class names. + */ +function wpcf7_form_controls_class( $type, $default_classes = '' ) { + $type = trim( $type ); + + if ( is_string( $default_classes ) ) { + $default_classes = explode( ' ', $default_classes ); + } + + $classes = array( + 'wpcf7-form-control', + sprintf( 'wpcf7-%s', rtrim( $type, '*' ) ), + ); + + if ( str_ends_with( $type, '*' ) ) { + $classes[] = 'wpcf7-validates-as-required'; + } + + $classes = array_merge( $classes, $default_classes ); + $classes = array_filter( array_unique( $classes ) ); + + return implode( ' ', $classes ); +} + + +/** + * Callback function for the contact-form-7 shortcode. + */ +function wpcf7_contact_form_tag_func( $atts, $content = null, $code = '' ) { + if ( is_feed() ) { + return '[contact-form-7]'; + } + + if ( 'contact-form-7' === $code ) { + $atts = shortcode_atts( + array( + 'id' => '', + 'title' => '', + 'html_id' => '', + 'html_name' => '', + 'html_title' => '', + 'html_class' => '', + 'output' => 'form', + ), + $atts, 'wpcf7' + ); + + $id = trim( $atts['id'] ); + $title = trim( $atts['title'] ); + + $contact_form = wpcf7_get_contact_form_by_hash( $id ); + + if ( ! $contact_form ) { + $contact_form = wpcf7_contact_form( $id ); + } + + if ( ! $contact_form ) { + $contact_form = wpcf7_get_contact_form_by_title( $title ); + } + + } else { + if ( is_string( $atts ) ) { + $atts = explode( ' ', $atts, 2 ); + } + + $id = (int) array_shift( $atts ); + $contact_form = wpcf7_get_contact_form_by_old_id( $id ); + } + + if ( ! $contact_form ) { + return sprintf( + '

%1$s %2$s

', + esc_html( __( 'Error:', 'contact-form-7' ) ), + esc_html( __( "Contact form not found.", 'contact-form-7' ) ) + ); + } + + $callback = static function ( $contact_form, $atts ) { + return $contact_form->form_html( $atts ); + }; + + $output = wpcf7_switch_locale( + $contact_form->locale(), + $callback, + $contact_form, $atts + ); + + do_action( 'wpcf7_shortcode_callback', $contact_form, $atts ); + + return $output; +} + + +/** + * Saves the contact form data. + */ +function wpcf7_save_contact_form( $data = '', $context = 'save' ) { + $data = wp_parse_args( $data, array( + 'id' => -1, + 'title' => null, + 'locale' => null, + 'form' => null, + 'mail' => null, + 'mail_2' => null, + 'messages' => null, + 'additional_settings' => null, + ) ); + + $data['id'] = (int) $data['id']; + + if ( -1 === $data['id'] ) { + $contact_form = WPCF7_ContactForm::get_template(); + } else { + $contact_form = wpcf7_contact_form( $data['id'] ); + } + + if ( empty( $contact_form ) ) { + return false; + } + + if ( null !== $data['title'] ) { + $contact_form->set_title( $data['title'] ); + } + + if ( null !== $data['locale'] ) { + $contact_form->set_locale( $data['locale'] ); + } + + $properties = array(); + + if ( null !== $data['form'] ) { + $properties['form'] = wpcf7_sanitize_form( $data['form'] ); + } + + if ( null !== $data['mail'] ) { + $properties['mail'] = wpcf7_sanitize_mail( $data['mail'] ); + $properties['mail']['active'] = true; + } + + if ( null !== $data['mail_2'] ) { + $properties['mail_2'] = wpcf7_sanitize_mail( $data['mail_2'] ); + } + + if ( null !== $data['messages'] ) { + $properties['messages'] = wpcf7_sanitize_messages( $data['messages'] ); + } + + if ( null !== $data['additional_settings'] ) { + $properties['additional_settings'] = wpcf7_sanitize_additional_settings( + $data['additional_settings'] + ); + } + + $contact_form->set_properties( $properties ); + + do_action( 'wpcf7_save_contact_form', $contact_form, $data, $context ); + + if ( 'save' === $context ) { + $contact_form->save(); + } + + return $contact_form; +} + + +/** + * Sanitizes the form property data. + */ +function wpcf7_sanitize_form( $input, $default_template = '' ) { + if ( null === $input ) { + return $default_template; + } + + $output = trim( $input ); + + if ( ! current_user_can( 'unfiltered_html' ) ) { + $output = wpcf7_kses( $output, 'form' ); + } + + return $output; +} + + +/** + * Sanitizes the mail property data. + */ +function wpcf7_sanitize_mail( $input, $defaults = array() ) { + $input = wp_parse_args( $input, array( + 'active' => false, + 'subject' => '', + 'sender' => '', + 'recipient' => '', + 'body' => '', + 'additional_headers' => '', + 'attachments' => '', + 'use_html' => false, + 'exclude_blank' => false, + ) ); + + $input = wp_parse_args( $input, $defaults ); + + $output = array(); + $output['active'] = (bool) $input['active']; + $output['subject'] = trim( $input['subject'] ); + $output['sender'] = trim( $input['sender'] ); + $output['recipient'] = trim( $input['recipient'] ); + $output['body'] = trim( $input['body'] ); + + if ( ! current_user_can( 'unfiltered_html' ) ) { + $output['body'] = wpcf7_kses( $output['body'], 'mail' ); + } + + $output['additional_headers'] = ''; + + $headers = str_replace( "\r\n", "\n", $input['additional_headers'] ); + $headers = explode( "\n", $headers ); + + foreach ( $headers as $header ) { + $header = trim( $header ); + + if ( '' !== $header ) { + $output['additional_headers'] .= $header . "\n"; + } + } + + $output['additional_headers'] = trim( $output['additional_headers'] ); + $output['attachments'] = trim( $input['attachments'] ); + $output['use_html'] = (bool) $input['use_html']; + $output['exclude_blank'] = (bool) $input['exclude_blank']; + + return $output; +} + + +/** + * Sanitizes the messages property data. + */ +function wpcf7_sanitize_messages( $input, $defaults = array() ) { + $output = array(); + + foreach ( wpcf7_messages() as $key => $val ) { + if ( isset( $input[$key] ) ) { + $output[$key] = trim( $input[$key] ); + } elseif ( isset( $defaults[$key] ) ) { + $output[$key] = $defaults[$key]; + } + } + + return $output; +} + + +/** + * Sanitizes the additional settings property data. + */ +function wpcf7_sanitize_additional_settings( $input, $default_template = '' ) { + if ( null === $input ) { + return $default_template; + } + + $output = trim( $input ); + return $output; +} + + +/** + * Generates a random hash string for a contact form. + * + * @param int $post_id Post ID. + * @return string SHA-1 hash. + */ +function wpcf7_generate_contact_form_hash( $post_id ) { + return hash( 'sha256', implode( '|', array( + get_current_user_id(), + $post_id, + time(), + home_url(), + ) ) ); +} diff --git a/html/wp-content/plugins/contact-form-7/includes/contact-form-template.php b/html/wp-content/plugins/contact-form-7/includes/contact-form-template.php new file mode 100644 index 0000000..528e17f --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/contact-form-template.php @@ -0,0 +1,204 @@ + %2$s + [text* your-name autocomplete:name] + + + + + + + +[submit "%6$s"]', + __( '(optional)', 'contact-form-7' ), + __( 'Your name', 'contact-form-7' ), + __( 'Your email', 'contact-form-7' ), + __( 'Subject', 'contact-form-7' ), + __( 'Your message', 'contact-form-7' ), + __( 'Submit', 'contact-form-7' ) + ); + + return trim( $template ); + } + + public static function mail() { + $template = array( + 'subject' => sprintf( + /* translators: 1: blog name, 2: [your-subject] */ + _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ), + '[_site_title]', + '[your-subject]' + ), + 'sender' => sprintf( + '%s <%s>', + '[_site_title]', + self::from_email() + ), + 'body' => + sprintf( + /* translators: %s: [your-name] [your-email] */ + __( 'From: %s', 'contact-form-7' ), + '[your-name] [your-email]' + ) . "\n" + . sprintf( + /* translators: %s: [your-subject] */ + __( 'Subject: %s', 'contact-form-7' ), + '[your-subject]' + ) . "\n\n" + . __( 'Message Body:', 'contact-form-7' ) + . "\n" . '[your-message]' . "\n\n" + . '-- ' . "\n" + . sprintf( + /* translators: 1: blog name, 2: blog URL */ + __( 'This is a notification that a contact form was submitted on your website (%1$s %2$s).', 'contact-form-7' ), + '[_site_title]', + '[_site_url]' + ), + 'recipient' => '[_site_admin_email]', + 'additional_headers' => 'Reply-To: [your-email]', + 'attachments' => '', + 'use_html' => 0, + 'exclude_blank' => 0, + ); + + return $template; + } + + public static function mail_2() { + $template = array( + 'active' => false, + 'subject' => sprintf( + /* translators: 1: blog name, 2: [your-subject] */ + _x( '%1$s "%2$s"', 'mail subject', 'contact-form-7' ), + '[_site_title]', + '[your-subject]' + ), + 'sender' => sprintf( + '%s <%s>', + '[_site_title]', + self::from_email() + ), + 'body' => + __( 'Message Body:', 'contact-form-7' ) + . "\n" . '[your-message]' . "\n\n" + . '-- ' . "\n" + . sprintf( + /* translators: 1: blog name, 2: blog URL */ + __( 'This email is a receipt for your contact form submission on our website (%1$s %2$s) in which your email address was used. If that was not you, please ignore this message.', 'contact-form-7' ), + '[_site_title]', + '[_site_url]' + ), + 'recipient' => '[your-email]', + 'additional_headers' => sprintf( + 'Reply-To: %s', + '[_site_admin_email]' + ), + 'attachments' => '', + 'use_html' => 0, + 'exclude_blank' => 0, + ); + + return $template; + } + + public static function from_email() { + $admin_email = get_option( 'admin_email' ); + + if ( wpcf7_is_localhost() ) { + return $admin_email; + } + + $sitename = wp_parse_url( network_home_url(), PHP_URL_HOST ); + $sitename = strtolower( $sitename ); + + if ( 'www.' === substr( $sitename, 0, 4 ) ) { + $sitename = substr( $sitename, 4 ); + } + + if ( strpbrk( $admin_email, '@' ) === '@' . $sitename ) { + return $admin_email; + } + + return 'wordpress@' . $sitename; + } + + public static function messages() { + $messages = array(); + + foreach ( wpcf7_messages() as $key => $arr ) { + $messages[$key] = $arr['default']; + } + + return $messages; + } +} + +function wpcf7_messages() { + $messages = array( + 'mail_sent_ok' => array( + 'description' => __( 'Sender’s message was sent successfully', 'contact-form-7' ), + 'default' => __( 'Thank you for your message. It has been sent.', 'contact-form-7' ), + ), + + 'mail_sent_ng' => array( + 'description' => __( 'Sender’s message failed to send', 'contact-form-7' ), + 'default' => __( 'There was an error trying to send your message. Please try again later.', 'contact-form-7' ), + ), + + 'validation_error' => array( + 'description' => __( 'Validation errors occurred', 'contact-form-7' ), + 'default' => __( 'One or more fields have an error. Please check and try again.', 'contact-form-7' ), + ), + + 'spam' => array( + 'description' => __( 'Submission was referred to as spam', 'contact-form-7' ), + 'default' => __( 'There was an error trying to send your message. Please try again later.', 'contact-form-7' ), + ), + + 'accept_terms' => array( + 'description' => __( 'There are terms that the sender must accept', 'contact-form-7' ), + 'default' => __( 'You must accept the terms and conditions before sending your message.', 'contact-form-7' ), + ), + + 'invalid_required' => array( + 'description' => __( 'There is a field that the sender must fill in', 'contact-form-7' ), + 'default' => __( 'Please fill out this field.', 'contact-form-7' ), + ), + + 'invalid_too_long' => array( + 'description' => __( 'There is a field with input that is longer than the maximum allowed length', 'contact-form-7' ), + 'default' => __( 'This field has a too long input.', 'contact-form-7' ), + ), + + 'invalid_too_short' => array( + 'description' => __( 'There is a field with input that is shorter than the minimum allowed length', 'contact-form-7' ), + 'default' => __( 'This field has a too short input.', 'contact-form-7' ), + ), + ); + + return apply_filters( 'wpcf7_messages', $messages ); +} diff --git a/html/wp-content/plugins/contact-form-7/includes/contact-form.php b/html/wp-content/plugins/contact-form-7/includes/contact-form.php new file mode 100644 index 0000000..cdbb6d6 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/contact-form.php @@ -0,0 +1,1379 @@ + array( + 'name' => __( 'Contact Forms', 'contact-form-7' ), + 'singular_name' => __( 'Contact Form', 'contact-form-7' ), + ), + 'rewrite' => false, + 'query_var' => false, + 'public' => false, + 'capability_type' => 'page', + 'capabilities' => array( + 'edit_post' => 'wpcf7_edit_contact_form', + 'read_post' => 'wpcf7_read_contact_form', + 'delete_post' => 'wpcf7_delete_contact_form', + 'edit_posts' => 'wpcf7_edit_contact_forms', + 'edit_others_posts' => 'wpcf7_edit_contact_forms', + 'publish_posts' => 'wpcf7_edit_contact_forms', + 'read_private_posts' => 'wpcf7_edit_contact_forms', + ), + ) ); + } + + + /** + * Retrieves contact form data that match given conditions. + * + * @param string|array $args Optional. Arguments to be passed to WP_Query. + * @return array Array of WPCF7_ContactForm objects. + */ + public static function find( $args = '' ) { + $defaults = array( + 'post_status' => 'any', + 'posts_per_page' => -1, + 'offset' => 0, + 'orderby' => 'ID', + 'order' => 'ASC', + ); + + $args = wp_parse_args( $args, $defaults ); + + $args['post_type'] = self::post_type; + + $q = new WP_Query(); + $posts = $q->query( $args ); + + self::$found_items = $q->found_posts; + + $objs = array(); + + foreach ( $posts as $post ) { + $objs[] = new self( $post ); + } + + return $objs; + } + + + /** + * Returns a contact form data filled by default template contents. + * + * @param string|array $options Optional. Contact form options. + * @return WPCF7_ContactForm A new contact form object. + */ + public static function get_template( $options = '' ) { + $options = wp_parse_args( $options, array( + 'locale' => null, + 'title' => __( 'Untitled', 'contact-form-7' ), + ) ); + + if ( ! isset( $options['locale'] ) ) { + $options['locale'] = determine_locale(); + } + + $callback = static function ( $options ) { + $contact_form = new self(); + $contact_form->title = $options['title']; + $contact_form->locale = $options['locale']; + + $properties = $contact_form->get_properties(); + + foreach ( $properties as $key => $value ) { + $default_template = WPCF7_ContactFormTemplate::get_default( $key ); + + if ( isset( $default_template ) ) { + $properties[$key] = $default_template; + } + } + + $contact_form->properties = $properties; + + return $contact_form; + }; + + $contact_form = wpcf7_switch_locale( + $options['locale'], + $callback, + $options + ); + + self::$current = apply_filters( 'wpcf7_contact_form_default_pack', + $contact_form, $options + ); + + return self::$current; + } + + + /** + * Creates a WPCF7_ContactForm object and sets it as the current instance. + * + * @param WPCF7_ContactForm|WP_Post|int $post Object or post ID. + * @return WPCF7_ContactForm|null Contact form object. Null if unset. + */ + public static function get_instance( $post ) { + $contact_form = null; + + if ( $post instanceof self ) { + $contact_form = $post; + } elseif ( ! empty( $post ) ) { + $post = get_post( $post ); + + if ( isset( $post ) and self::post_type === get_post_type( $post ) ) { + $contact_form = new self( $post ); + } + } + + return self::$current = $contact_form; + } + + + /** + * Generates a "unit-tag" for the given contact form ID. + * + * @return string Unit-tag. + */ + private static function generate_unit_tag( $id = 0 ) { + static $global_count = 0; + + $global_count += 1; + + if ( in_the_loop() ) { + $unit_tag = sprintf( 'wpcf7-f%1$d-p%2$d-o%3$d', + absint( $id ), + get_the_ID(), + $global_count + ); + } else { + $unit_tag = sprintf( 'wpcf7-f%1$d-o%2$d', + absint( $id ), + $global_count + ); + } + + return $unit_tag; + } + + + /** + * Constructor. + */ + private function __construct( $post = null ) { + $post = get_post( $post ); + + if ( $post and self::post_type === get_post_type( $post ) ) { + $this->id = $post->ID; + $this->name = $post->post_name; + $this->title = $post->post_title; + $this->locale = get_post_meta( $post->ID, '_locale', true ); + $this->hash = get_post_meta( $post->ID, '_hash', true ); + + $this->construct_properties( $post ); + $this->upgrade(); + } else { + $this->construct_properties(); + } + + do_action( 'wpcf7_contact_form', $this ); + } + + + /** + * Magic method for property overloading. + */ + public function __get( $name ) { + /* translators: 1: property name, 2: method name */ + $message = __( '%1$s property of a WPCF7_ContactForm object is no longer accessible. Use %2$s method instead.', 'contact-form-7' ); + + if ( 'id' === $name ) { + wp_trigger_error( + '', + sprintf( $message, 'id', 'id()' ), + E_USER_DEPRECATED + ); + + return $this->id; + } elseif ( 'title' === $name ) { + wp_trigger_error( + '', + sprintf( $message, 'title', 'title()' ), + E_USER_DEPRECATED + ); + + return $this->title; + } elseif ( $prop = $this->prop( $name ) ) { + wp_trigger_error( + '', + sprintf( $message, $name, 'prop(\'' . $name . '\')' ), + E_USER_DEPRECATED + ); + + return $prop; + } + } + + + /** + * Returns true if this contact form is not yet saved to the database. + */ + public function initial() { + return empty( $this->id ); + } + + + /** + * Constructs contact form properties. This is called only once + * from the constructor. + */ + private function construct_properties( $post = null ) { + $builtin_properties = array( + 'form' => '', + 'mail' => array(), + 'mail_2' => array(), + 'messages' => array(), + 'additional_settings' => '', + ); + + $properties = apply_filters( + 'wpcf7_pre_construct_contact_form_properties', + $builtin_properties, $this + ); + + // Filtering out properties with invalid name + $properties = array_filter( + $properties, + static function ( $key ) { + $sanitized_key = sanitize_key( $key ); + return $key === $sanitized_key; + }, + ARRAY_FILTER_USE_KEY + ); + + foreach ( $properties as $name => $val ) { + $prop = $this->retrieve_property( $name ); + + if ( isset( $prop ) ) { + $properties[$name] = $prop; + } + } + + $this->properties = $properties; + + foreach ( $properties as $name => $val ) { + $properties[$name] = apply_filters( + "wpcf7_contact_form_property_{$name}", + $val, $this + ); + } + + $this->properties = $properties; + + $properties = (array) apply_filters( + 'wpcf7_contact_form_properties', + $properties, $this + ); + + $this->properties = $properties; + } + + + /** + * Retrieves contact form property of the specified name from the database. + * + * @param string $name Property name. + * @return array|string|null Property value. Null if property does not exist. + */ + private function retrieve_property( $name ) { + $property = null; + + if ( ! $this->initial() ) { + $post_id = $this->id; + + if ( metadata_exists( 'post', $post_id, '_' . $name ) ) { + $property = get_post_meta( $post_id, '_' . $name, true ); + } elseif ( metadata_exists( 'post', $post_id, $name ) ) { + $property = get_post_meta( $post_id, $name, true ); + } + } + + return $property; + } + + + /** + * Returns the value for the given property name. + * + * @param string $name Property name. + * @return array|string|null Property value. Null if property does not exist. + */ + public function prop( $name ) { + $props = $this->get_properties(); + return isset( $props[$name] ) ? $props[$name] : null; + } + + + /** + * Returns all the properties. + * + * @return array This contact form's properties. + */ + public function get_properties() { + return (array) $this->properties; + } + + + /** + * Updates properties. + * + * @param array $properties New properties. + */ + public function set_properties( $properties ) { + $defaults = $this->get_properties(); + + $properties = wp_parse_args( $properties, $defaults ); + $properties = array_intersect_key( $properties, $defaults ); + + $this->properties = $properties; + } + + + /** + * Returns ID of this contact form. + * + * @return int The ID. + */ + public function id() { + return $this->id; + } + + + /** + * Returns unit-tag for this contact form. + * + * @return string Unit-tag. + */ + public function unit_tag() { + return $this->unit_tag; + } + + + /** + * Returns name (slug) of this contact form. + * + * @return string Name. + */ + public function name() { + return $this->name; + } + + + /** + * Returns title of this contact form. + * + * @return string Title. + */ + public function title() { + return $this->title; + } + + + /** + * Set a title for this contact form. + * + * @param string $title Title. + */ + public function set_title( $title ) { + $title = wp_strip_all_tags( $title, true ); + $title = wpcf7_strip_whitespaces( $title ); + + if ( '' === $title ) { + $title = __( 'Untitled', 'contact-form-7' ); + } + + $this->title = $title; + } + + + /** + * Returns the locale code of this contact form. + * + * @return string Locale code. Empty string if no valid locale is set. + */ + public function locale() { + if ( wpcf7_is_valid_locale( $this->locale ) ) { + return $this->locale; + } else { + return ''; + } + } + + + /** + * Sets a locale for this contact form. + * + * @param string $locale Locale code. + */ + public function set_locale( $locale ) { + $locale = trim( $locale ); + + if ( wpcf7_is_valid_locale( $locale ) ) { + $this->locale = $locale; + } else { + $this->locale = 'en_US'; + } + } + + + /** + * Retrieves the random hash string tied to this contact form. + * + * @param int $length Length of hash string. + * @return string Hash string unique to this contact form. + */ + public function hash( $length = 7 ) { + return substr( $this->hash, 0, absint( $length ) ); + } + + + /** + * Returns the specified shortcode attribute value. + * + * @param string $name Shortcode attribute name. + * @return string|null Attribute value. Null if the attribute does not exist. + */ + public function shortcode_attr( $name ) { + if ( isset( $this->shortcode_atts[$name] ) ) { + return (string) $this->shortcode_atts[$name]; + } + } + + + /** + * Returns true if this contact form is identical to the submitted one. + */ + public function is_posted() { + if ( ! WPCF7_Submission::get_instance() ) { + return false; + } + + $unit_tag = wpcf7_superglobal_post( '_wpcf7_unit_tag' ); + + if ( empty( $unit_tag ) ) { + return false; + } + + return $this->unit_tag() === $unit_tag; + } + + + /** + * Generates HTML that represents a form. + * + * @param string|array $options Optional. Form options. + * @return string HTML output. + */ + public function form_html( $options = '' ) { + $options = wp_parse_args( $options, array( + 'html_id' => '', + 'html_name' => '', + 'html_title' => '', + 'html_class' => '', + 'output' => 'form', + ) ); + + $this->shortcode_atts = $options; + + if ( 'raw_form' === $options['output'] ) { + return sprintf( + '
%s
', + esc_html( $this->prop( 'form' ) ) + ); + } + + if ( + $this->is_true( 'subscribers_only' ) and + ! current_user_can( 'wpcf7_submit', $this->id() ) + ) { + $notice = sprintf( + '

%s

', + wp_kses_data( __( 'This contact form is available only for logged in users.', 'contact-form-7' ) ) + ); + + return apply_filters( 'wpcf7_subscribers_only_notice', $notice, $this ); + } + + $this->unit_tag = self::generate_unit_tag( $this->id ); + + $action_url = wpcf7_get_request_uri(); + + if ( $frag = strstr( $action_url, '#' ) ) { + $action_url = substr( $action_url, 0, -strlen( $frag ) ); + } + + $action_url .= '#' . $this->unit_tag(); + + $action_url = apply_filters( 'wpcf7_form_action_url', $action_url ); + + if ( + str_starts_with( $action_url, '//' ) or + ! str_starts_with( $action_url, '/' ) and + ! str_starts_with( $action_url, home_url() ) + ) { + return sprintf( + '

%1$s %2$s

', + esc_html( __( 'Error:', 'contact-form-7' ) ), + esc_html( __( 'Invalid action URL is detected.', 'contact-form-7' ) ) + ); + } + + $lang_tag = str_replace( '_', '-', $this->locale ); + + if ( preg_match( '/^([a-z]+-[a-z]+)-/i', $lang_tag, $matches ) ) { + $lang_tag = $matches[1]; + } + + $html = "\n" . sprintf( '
', + wpcf7_format_atts( array( + 'class' => 'wpcf7 no-js', + 'id' => $this->unit_tag(), + ( get_option( 'html_type' ) === 'text/html' ) ? 'lang' : 'xml:lang' + => $lang_tag, + 'dir' => wpcf7_is_rtl( $this->locale ) ? 'rtl' : 'ltr', + 'data-wpcf7-id' => $this->id(), + ) ) + ); + + $html .= "\n" . $this->screen_reader_response() . "\n"; + + $id_attr = apply_filters( 'wpcf7_form_id_attr', + preg_replace( '/[^A-Za-z0-9:._-]/', '', $options['html_id'] ) + ); + + $name_attr = apply_filters( 'wpcf7_form_name_attr', + preg_replace( '/[^A-Za-z0-9:._-]/', '', $options['html_name'] ) + ); + + $title_attr = apply_filters( 'wpcf7_form_title_attr', $options['html_title'] ); + + $class = 'wpcf7-form'; + + if ( $this->is_posted() ) { + $submission = WPCF7_Submission::get_instance(); + + $data_status_attr = $this->form_status_class_name( + $submission->get_status() + ); + + $class .= sprintf( ' %s', $data_status_attr ); + } else { + $data_status_attr = 'init'; + $class .= ' init'; + } + + if ( $options['html_class'] ) { + $class .= ' ' . $options['html_class']; + } + + if ( $this->in_demo_mode() ) { + $class .= ' demo'; + } + + $class = explode( ' ', $class ); + $class = array_map( 'sanitize_html_class', $class ); + $class = array_filter( $class ); + $class = array_unique( $class ); + $class = implode( ' ', $class ); + $class = apply_filters( 'wpcf7_form_class_attr', $class ); + + $enctype = wpcf7_enctype_value( apply_filters( 'wpcf7_form_enctype', '' ) ); + $autocomplete = apply_filters( 'wpcf7_form_autocomplete', '' ); + + $atts = array( + 'action' => esc_url( $action_url ), + 'method' => 'post', + 'class' => ( '' !== $class ) ? $class : null, + 'id' => ( '' !== $id_attr ) ? $id_attr : null, + 'name' => ( '' !== $name_attr ) ? $name_attr : null, + 'aria-label' => ( '' !== $title_attr ) + ? $title_attr : __( 'Contact form', 'contact-form-7' ), + 'enctype' => ( '' !== $enctype ) ? $enctype : null, + 'autocomplete' => ( '' !== $autocomplete ) ? $autocomplete : null, + 'novalidate' => true, + 'data-status' => $data_status_attr, + ); + + $atts += (array) apply_filters( 'wpcf7_form_additional_atts', array() ); + + $html .= sprintf( '
', wpcf7_format_atts( $atts ) ) . "\n"; + $html .= $this->form_hidden_fields(); + $html .= $this->form_elements(); + + if ( ! $this->responses_count ) { + $html .= $this->form_response_output(); + } + + $html .= "\n" . '
'; + $html .= "\n" . '
'; + + return $html . "\n"; + } + + + /** + * Returns the class name that matches the given form status. + */ + private function form_status_class_name( $status ) { + switch ( $status ) { + case 'init': + $class = 'init'; + break; + case 'validation_failed': + $class = 'invalid'; + break; + case 'acceptance_missing': + $class = 'unaccepted'; + break; + case 'spam': + $class = 'spam'; + break; + case 'aborted': + $class = 'aborted'; + break; + case 'mail_sent': + $class = 'sent'; + break; + case 'mail_failed': + $class = 'failed'; + break; + default: + $class = sprintf( + 'custom-%s', + preg_replace( '/[^0-9a-z]+/i', '-', $status ) + ); + } + + return $class; + } + + + /** + * Returns a set of hidden fields. + */ + private function form_hidden_fields() { + $hidden_fields = array( + '_wpcf7' => $this->id(), + '_wpcf7_version' => WPCF7_VERSION, + '_wpcf7_locale' => $this->locale(), + '_wpcf7_unit_tag' => $this->unit_tag(), + '_wpcf7_container_post' => 0, + '_wpcf7_posted_data_hash' => '', + ); + + if ( in_the_loop() ) { + $hidden_fields['_wpcf7_container_post'] = (int) get_the_ID(); + } + + if ( $this->nonce_is_active() and is_user_logged_in() ) { + $hidden_fields['_wpnonce'] = wpcf7_create_nonce(); + } + + $hidden_fields += (array) apply_filters( + 'wpcf7_form_hidden_fields', array() + ); + + $formatter = new WPCF7_HTMLFormatter(); + + $formatter->append_start_tag( 'fieldset', array( + 'class' => 'hidden-fields-container', + ) ); + + foreach ( $hidden_fields as $name => $value ) { + $formatter->append_start_tag( 'input', array( + 'type' => 'hidden', + 'name' => $name, + 'value' => $value, + ) ); + } + + return $formatter->output() . "\n"; + } + + + /** + * Returns the visible response output for a form submission. + */ + public function form_response_output() { + $status = 'init'; + $class = 'wpcf7-response-output'; + $content = ''; + + if ( $this->is_posted() ) { // Post response output for non-AJAX + $submission = WPCF7_Submission::get_instance(); + $status = $submission->get_status(); + $content = $submission->get_response(); + } + + $atts = array( + 'class' => trim( $class ), + 'aria-hidden' => 'true', + ); + + $output = sprintf( '
%2$s
', + wpcf7_format_atts( $atts ), + esc_html( $content ) + ); + + $output = apply_filters( 'wpcf7_form_response_output', + $output, $class, $content, $this, $status + ); + + $this->responses_count += 1; + + return $output; + } + + + /** + * Returns the response output that is only accessible from screen readers. + */ + public function screen_reader_response() { + $primary_response = ''; + $validation_errors = array(); + + if ( $this->is_posted() ) { // Post response output for non-AJAX + $submission = WPCF7_Submission::get_instance(); + $primary_response = $submission->get_response(); + + if ( $invalid_fields = $submission->get_invalid_fields() ) { + foreach ( (array) $invalid_fields as $name => $field ) { + $list_item = esc_html( $field['reason'] ); + + if ( $field['idref'] ) { + $list_item = sprintf( + '%2$s', + esc_attr( $field['idref'] ), + $list_item + ); + } + + $validation_error_id = wpcf7_get_validation_error_reference( + $name, + $this->unit_tag() + ); + + if ( $validation_error_id ) { + $list_item = sprintf( + '
  • %2$s
  • ', + esc_attr( $validation_error_id ), + $list_item + ); + + $validation_errors[] = $list_item; + } + } + } + } + + $primary_response = sprintf( + '

    %s

    ', + esc_html( $primary_response ) + ); + + $validation_errors = sprintf( + '
      %s
    ', + implode( "\n", $validation_errors ) + ); + + $output = sprintf( + '
    %1$s %2$s
    ', + $primary_response, + $validation_errors + ); + + return $output; + } + + + /** + * Returns a validation error for the specified input field. + * + * @param string $name Input field name. + */ + public function validation_error( $name ) { + $error = ''; + + if ( $this->is_posted() ) { + $submission = WPCF7_Submission::get_instance(); + + if ( $invalid_field = $submission->get_invalid_field( $name ) ) { + $error = trim( $invalid_field['reason'] ); + } + } + + if ( ! $error ) { + return $error; + } + + $atts = array( + 'class' => 'wpcf7-not-valid-tip', + 'aria-hidden' => 'true', + ); + + $error = sprintf( + '%2$s', + wpcf7_format_atts( $atts ), + esc_html( $error ) + ); + + return apply_filters( 'wpcf7_validation_error', $error, $name, $this ); + } + + + /** + * Replaces all form-tags in the form template with corresponding HTML. + * + * @return string Replaced form content. + */ + public function replace_all_form_tags() { + $manager = WPCF7_FormTagsManager::get_instance(); + $form = $this->prop( 'form' ); + + if ( wpcf7_autop_or_not() ) { + $form = $manager->replace_with_placeholders( $form ); + $form = wpcf7_autop( $form ); + $form = $manager->restore_from_placeholders( $form ); + } + + $form = $manager->replace_all( $form ); + $this->scanned_form_tags = $manager->get_scanned_tags(); + + return $form; + } + + + /** + * Replaces all form-tags in the form template with corresponding HTML. + * + * @deprecated 4.6 Use replace_all_form_tags() + * + * @return string Replaced form content. + */ + public function form_do_shortcode() { + wpcf7_deprecated_function( __METHOD__, '4.6', + 'WPCF7_ContactForm::replace_all_form_tags' + ); + + return $this->replace_all_form_tags(); + } + + + /** + * Scans form-tags from the form template. + * + * @param string|array|null $cond Optional. Filters. Default null. + * @return array Form-tags matching the given filter conditions. + */ + public function scan_form_tags( $cond = null ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + if ( empty( $this->scanned_form_tags ) ) { + $this->scanned_form_tags = $manager->scan( $this->prop( 'form' ) ); + } + + $tags = $this->scanned_form_tags; + + return $manager->filter( $tags, $cond ); + } + + + /** + * Scans form-tags from the form template. + * + * @deprecated 4.6 Use scan_form_tags() + * + * @param string|array|null $cond Optional. Filters. Default null. + * @return array Form-tags matching the given filter conditions. + */ + public function form_scan_shortcode( $cond = null ) { + wpcf7_deprecated_function( __METHOD__, '4.6', + 'WPCF7_ContactForm::scan_form_tags' + ); + + return $this->scan_form_tags( $cond ); + } + + + /** + * Replaces all form-tags in the form template with corresponding HTML. + * + * @return string Replaced form content. wpcf7_form_elements filters applied. + */ + public function form_elements() { + return apply_filters( 'wpcf7_form_elements', + $this->replace_all_form_tags() + ); + } + + + /** + * Collects mail-tags available for this contact form. + * + * @param string|array $options Optional. Search options. + * @return array Mail-tag names. + */ + public function collect_mail_tags( $options = '' ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + $options = wp_parse_args( $options, array( + 'include' => array(), + 'exclude' => $manager->collect_tag_types( 'not-for-mail' ), + ) ); + + $tags = $this->scan_form_tags(); + $mailtags = array(); + + foreach ( (array) $tags as $tag ) { + $type = $tag->basetype; + + if ( empty( $type ) ) { + continue; + } elseif ( ! empty( $options['include'] ) ) { + if ( ! in_array( $type, $options['include'], true ) ) { + continue; + } + } elseif ( ! empty( $options['exclude'] ) ) { + if ( in_array( $type, $options['exclude'], true ) ) { + continue; + } + } + + $mailtags[] = $tag->name; + } + + $mailtags = array_unique( $mailtags ); + $mailtags = array_filter( $mailtags ); + $mailtags = array_values( $mailtags ); + + return apply_filters( 'wpcf7_collect_mail_tags', $mailtags, $options, $this ); + } + + + /** + * Prints a mail-tag suggestion list. + * + * @param string $template_name Optional. Mail template name. Default 'mail'. + */ + public function suggest_mail_tags( $template_name = 'mail' ) { + $mail = wp_parse_args( $this->prop( $template_name ), + array( + 'active' => false, + 'recipient' => '', + 'sender' => '', + 'subject' => '', + 'body' => '', + 'additional_headers' => '', + 'attachments' => '', + 'use_html' => false, + 'exclude_blank' => false, + ) + ); + + $mail = array_filter( $mail ); + + foreach ( (array) $this->collect_mail_tags() as $mail_tag ) { + $pattern = sprintf( + '/\[(_[a-z]+_)?%s([ \t]+[^]]+)?\]/', + preg_quote( $mail_tag, '/' ) + ); + + $used = preg_grep( $pattern, $mail ); + + echo sprintf( + '[%2$s]', + 'mailtag code ' . ( $used ? 'used' : 'unused' ), + esc_html( $mail_tag ) + ); + } + } + + + /** + * Submits this contact form. + * + * @param string|array $options Optional. Submission options. Default empty. + * @return array Result of submission. + */ + public function submit( $options = '' ) { + $options = wp_parse_args( $options, array( + 'skip_mail' => ( + $this->in_demo_mode() || + $this->is_true( 'skip_mail' ) || + ! empty( $this->skip_mail ) + ), + ) ); + + if ( + $this->is_true( 'subscribers_only' ) and + ! current_user_can( 'wpcf7_submit', $this->id() ) + ) { + $result = array( + 'contact_form_id' => $this->id(), + 'status' => 'error', + 'message' => __( 'This contact form is available only for logged in users.', 'contact-form-7' ), + ); + + return $result; + } + + $submission = WPCF7_Submission::get_instance( $this, array( + 'skip_mail' => $options['skip_mail'], + ) ); + + $result = array( + 'contact_form_id' => $this->id(), + ); + + $result += $submission->get_result(); + + if ( $this->in_demo_mode() ) { + $result['demo_mode'] = true; + } + + do_action( 'wpcf7_submit', $this, $result ); + + return $result; + } + + + /** + * Returns message used for given status. + * + * @param string $status Status. + * @param bool $filter Optional. Whether filters are applied. Default true. + * @return string Message. + */ + public function message( $status, $filter = true ) { + $messages = $this->prop( 'messages' ); + $message = isset( $messages[$status] ) ? $messages[$status] : ''; + + if ( $filter ) { + $message = $this->filter_message( $message, $status ); + } + + return $message; + } + + + /** + * Filters a message. + * + * @param string $message Message to filter. + * @param string $status Optional. Status. Default empty. + * @return string Filtered message. + */ + public function filter_message( $message, $status = '' ) { + $message = wpcf7_mail_replace_tags( $message ); + $message = apply_filters( 'wpcf7_display_message', $message, $status ); + $message = wp_strip_all_tags( $message ); + + return $message; + } + + + /** + * Returns the additional setting value searched by name. + * + * @param string $name Name of setting. + * @return string Additional setting value. + */ + public function pref( $name ) { + $settings = $this->additional_setting( $name ); + + if ( $settings ) { + return $settings[0]; + } + } + + + /** + * Returns additional setting values searched by name. + * + * @param string $name Name of setting. + * @param int $max Maximum result item count. + * @return array Additional setting values. + */ + public function additional_setting( $name, $max = 1 ) { + $settings = (array) explode( "\n", $this->prop( 'additional_settings' ) ); + + $pattern = '/^([a-zA-Z0-9_]+)[\t ]*:(.*)$/'; + $count = 0; + $values = array(); + + foreach ( $settings as $setting ) { + if ( preg_match( $pattern, $setting, $matches ) ) { + if ( $matches[1] !== $name ) { + continue; + } + + if ( ! $max or $count < (int) $max ) { + $values[] = trim( $matches[2] ); + $count += 1; + } + } + } + + return $values; + } + + + /** + * Returns true if the specified setting has a truthy string value. + * + * @param string $name Name of setting. + * @return bool True if the setting value is 'on', 'true', or '1'. + */ + public function is_true( $name ) { + return in_array( + $this->pref( $name ), + array( 'on', 'true', '1' ), + true + ); + } + + + /** + * Returns true if this contact form is in the demo mode. + */ + public function in_demo_mode() { + return $this->is_true( 'demo_mode' ); + } + + + /** + * Returns true if nonce is active for this contact form. + */ + public function nonce_is_active() { + $is_active = WPCF7_VERIFY_NONCE; + + if ( $this->is_true( 'subscribers_only' ) ) { + $is_active = true; + } + + return (bool) apply_filters( 'wpcf7_verify_nonce', $is_active, $this ); + } + + + /** + * Returns true if the specified setting has a falsey string value. + * + * @param string $name Name of setting. + * @return bool True if the setting value is 'off', 'false', or '0'. + */ + public function is_false( $name ) { + return in_array( + $this->pref( $name ), + array( 'off', 'false', '0' ), + true + ); + } + + + /** + * Upgrades this contact form properties. + */ + private function upgrade() { + $mail = $this->prop( 'mail' ); + + if ( is_array( $mail ) and ! isset( $mail['recipient'] ) ) { + $mail['recipient'] = get_option( 'admin_email' ); + } + + $this->properties['mail'] = $mail; + + $messages = $this->prop( 'messages' ); + + if ( is_array( $messages ) ) { + foreach ( wpcf7_messages() as $key => $arr ) { + if ( ! isset( $messages[$key] ) ) { + $messages[$key] = $arr['default']; + } + } + } + + $this->properties['messages'] = $messages; + } + + + /** + * Stores this contact form properties to the database. + * + * @return int The post ID on success. The value 0 on failure. + */ + public function save() { + $title = wp_slash( $this->title ); + $props = wp_slash( $this->get_properties() ); + + $post_content = implode( "\n", wpcf7_array_flatten( $props ) ); + + if ( $this->initial() ) { + $post_id = wp_insert_post( array( + 'post_type' => self::post_type, + 'post_status' => 'publish', + 'post_title' => $title, + 'post_content' => trim( $post_content ), + ) ); + } else { + $post_id = wp_update_post( array( + 'ID' => (int) $this->id, + 'post_status' => 'publish', + 'post_title' => $title, + 'post_content' => trim( $post_content ), + ) ); + } + + if ( $post_id ) { + foreach ( $props as $prop => $value ) { + update_post_meta( $post_id, '_' . $prop, + wpcf7_normalize_newline_deep( $value ) + ); + } + + if ( wpcf7_is_valid_locale( $this->locale ) ) { + update_post_meta( $post_id, '_locale', $this->locale ); + } + + add_post_meta( $post_id, '_hash', + wpcf7_generate_contact_form_hash( $post_id ), + true // Unique + ); + + if ( $this->initial() ) { + $this->id = $post_id; + do_action( 'wpcf7_after_create', $this ); + } else { + do_action( 'wpcf7_after_update', $this ); + } + + do_action( 'wpcf7_after_save', $this ); + } + + return $post_id; + } + + + /** + * Makes a copy of this contact form. + * + * @return WPCF7_ContactForm New contact form object. + */ + public function copy() { + $new = new self(); + $new->title = $this->title . '_copy'; + $new->locale = $this->locale; + $new->properties = $this->properties; + + return apply_filters( 'wpcf7_copy', $new, $this ); + } + + + /** + * Deletes this contact form. + * + * @return bool True if deletion succeeded, false otherwise. + */ + public function delete() { + if ( $this->initial() ) { + return false; + } + + if ( wp_delete_post( $this->id, true ) ) { + $this->id = 0; + return true; + } + + return false; + } + + + /** + * Returns a WordPress shortcode for this contact form. + */ + public function shortcode( $options = '' ) { + $options = wp_parse_args( $options, array( + 'use_old_format' => false + ) ); + + $title = str_replace( array( '"', '[', ']' ), '', $this->title ); + + if ( $options['use_old_format'] ) { + $old_unit_id = (int) get_post_meta( $this->id, '_old_cf7_unit_id', true ); + + if ( $old_unit_id ) { + $shortcode = sprintf( + '[contact-form %1$d "%2$s"]', + $old_unit_id, + $title + ); + } else { + $shortcode = ''; + } + } else { + $shortcode = sprintf( + '[contact-form-7 id="%1$s" title="%2$s"]', + $this->hash(), + $title + ); + } + + return apply_filters( 'wpcf7_contact_form_shortcode', + $shortcode, $options, $this + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7/includes/controller.php b/html/wp-content/plugins/contact-form-7/includes/controller.php new file mode 100644 index 0000000..7d2b876 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/controller.php @@ -0,0 +1,184 @@ +submit(); + } +} + + +/** + * Registers main scripts and styles. + */ +add_action( + 'wp_enqueue_scripts', + static function () { + $assets = include wpcf7_plugin_path( 'includes/js/index.asset.php' ); + + $assets = wp_parse_args( $assets, array( + 'dependencies' => array(), + 'version' => WPCF7_VERSION, + ) ); + + wp_register_script( + 'contact-form-7', + wpcf7_plugin_url( 'includes/js/index.js' ), + array_merge( + $assets['dependencies'], + array( 'swv' ) + ), + $assets['version'], + array( 'in_footer' => true ) + ); + + wp_set_script_translations( 'contact-form-7', 'contact-form-7' ); + + wp_register_script( + 'contact-form-7-html5-fallback', + wpcf7_plugin_url( 'includes/js/html5-fallback.js' ), + array( 'jquery-ui-datepicker' ), + WPCF7_VERSION, + array( 'in_footer' => true ) + ); + + if ( wpcf7_load_js() ) { + wpcf7_enqueue_scripts(); + } + + wp_register_style( + 'contact-form-7', + wpcf7_plugin_url( 'includes/css/styles.css' ), + array(), + WPCF7_VERSION, + 'all' + ); + + wp_register_style( + 'contact-form-7-rtl', + wpcf7_plugin_url( 'includes/css/styles-rtl.css' ), + array( 'contact-form-7' ), + WPCF7_VERSION, + 'all' + ); + + wp_register_style( + 'jquery-ui-smoothness', + wpcf7_plugin_url( + 'includes/js/jquery-ui/themes/smoothness/jquery-ui.min.css' + ), + array(), + '1.12.1', + 'screen' + ); + + if ( wpcf7_load_css() ) { + wpcf7_enqueue_styles(); + } + }, + 10, 0 +); + + +/** + * Enqueues scripts. + */ +function wpcf7_enqueue_scripts() { + wp_enqueue_script( 'contact-form-7' ); + + $wpcf7_obj = array( + 'api' => array( + 'root' => sanitize_url( get_rest_url() ), + 'namespace' => 'contact-form-7/v1', + ), + ); + + if ( defined( 'WP_CACHE' ) and WP_CACHE ) { + $wpcf7_obj = array_merge( $wpcf7_obj, array( + 'cached' => 1, + ) ); + } + + wp_add_inline_script( 'contact-form-7', + sprintf( + 'var wpcf7 = %s;', + wp_json_encode( $wpcf7_obj, JSON_PRETTY_PRINT ) + ), + 'before' + ); + + do_action( 'wpcf7_enqueue_scripts' ); +} + + +/** + * Returns true if the main script is enqueued. + */ +function wpcf7_script_is() { + return wp_script_is( 'contact-form-7' ); +} + + +/** + * Enqueues styles. + */ +function wpcf7_enqueue_styles() { + wp_enqueue_style( 'contact-form-7' ); + + if ( wpcf7_is_rtl() ) { + wp_enqueue_style( 'contact-form-7-rtl' ); + } + + do_action( 'wpcf7_enqueue_styles' ); +} + + +/** + * Returns true if the main stylesheet is enqueued. + */ +function wpcf7_style_is() { + return wp_style_is( 'contact-form-7' ); +} + + +add_action( + 'wp_enqueue_scripts', + 'wpcf7_html5_fallback', + 20, 0 +); + +/** + * Enqueues scripts and styles for the HTML5 fallback. + */ +function wpcf7_html5_fallback() { + if ( ! wpcf7_support_html5_fallback() ) { + return; + } + + if ( wpcf7_script_is() ) { + wp_enqueue_script( 'contact-form-7-html5-fallback' ); + } + + if ( wpcf7_style_is() ) { + wp_enqueue_style( 'jquery-ui-smoothness' ); + } +} diff --git a/html/wp-content/plugins/contact-form-7/includes/css/styles-rtl.css b/html/wp-content/plugins/contact-form-7/includes/css/styles-rtl.css new file mode 100644 index 0000000..2ec20fd --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/css/styles-rtl.css @@ -0,0 +1,11 @@ +.wpcf7-not-valid-tip { + direction: rtl; +} + +.use-floating-validation-tip .wpcf7-not-valid-tip { + right: 1em; +} + +.wpcf7-list-item { + margin: 0 1em 0 0; +} diff --git a/html/wp-content/plugins/contact-form-7/includes/css/styles.css b/html/wp-content/plugins/contact-form-7/includes/css/styles.css new file mode 100644 index 0000000..e6517e9 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/css/styles.css @@ -0,0 +1,176 @@ +.wpcf7 .screen-reader-response { + position: absolute; + overflow: hidden; + clip: rect(1px, 1px, 1px, 1px); + clip-path: inset(50%); + height: 1px; + width: 1px; + margin: -1px; + padding: 0; + border: 0; + word-wrap: normal !important; +} + +.wpcf7 .hidden-fields-container { + display: none; +} + +.wpcf7 form .wpcf7-response-output { + margin: 2em 0.5em 1em; + padding: 0.2em 1em; + border: 2px solid #00a0d2; /* Blue */ +} + +.wpcf7 form.init .wpcf7-response-output, +.wpcf7 form.resetting .wpcf7-response-output, +.wpcf7 form.submitting .wpcf7-response-output { + display: none; +} + +.wpcf7 form.sent .wpcf7-response-output { + border-color: #46b450; /* Green */ +} + +.wpcf7 form.failed .wpcf7-response-output, +.wpcf7 form.aborted .wpcf7-response-output { + border-color: #dc3232; /* Red */ +} + +.wpcf7 form.spam .wpcf7-response-output { + border-color: #f56e28; /* Orange */ +} + +.wpcf7 form.invalid .wpcf7-response-output, +.wpcf7 form.unaccepted .wpcf7-response-output, +.wpcf7 form.payment-required .wpcf7-response-output { + border-color: #ffb900; /* Yellow */ +} + +.wpcf7-form-control-wrap { + position: relative; +} + +.wpcf7-not-valid-tip { + color: #dc3232; /* Red */ + font-size: 1em; + font-weight: normal; + display: block; +} + +.use-floating-validation-tip .wpcf7-not-valid-tip { + position: relative; + top: -2ex; + left: 1em; + z-index: 100; + border: 1px solid #dc3232; + background: #fff; + padding: .2em .8em; + width: 24em; +} + +.wpcf7-list-item { + display: inline-block; + margin: 0 0 0 1em; +} + +.wpcf7-list-item-label::before, +.wpcf7-list-item-label::after { + content: " "; +} + +.wpcf7-spinner { + visibility: hidden; + display: inline-block; + background-color: #23282d; /* Dark Gray 800 */ + opacity: 0.75; + width: 24px; + height: 24px; + border: none; + border-radius: 100%; + padding: 0; + margin: 0 24px; + position: relative; +} + +form.submitting .wpcf7-spinner { + visibility: visible; +} + +.wpcf7-spinner::before { + content: ''; + position: absolute; + background-color: #fbfbfc; /* Light Gray 100 */ + top: 4px; + left: 4px; + width: 6px; + height: 6px; + border: none; + border-radius: 100%; + transform-origin: 8px 8px; + animation-name: spin; + animation-duration: 1000ms; + animation-timing-function: linear; + animation-iteration-count: infinite; +} + +@media (prefers-reduced-motion: reduce) { + .wpcf7-spinner::before { + animation-name: blink; + animation-duration: 2000ms; + } +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +@keyframes blink { + from { + opacity: 0; + } + + 50% { + opacity: 1; + } + + to { + opacity: 0; + } +} + +.wpcf7 [inert] { + opacity: 0.5; +} + +.wpcf7 input[type="file"] { + cursor: pointer; +} + +.wpcf7 input[type="file"]:disabled { + cursor: default; +} + +.wpcf7 .wpcf7-submit:disabled { + cursor: not-allowed; +} + +.wpcf7 input[type="url"], +.wpcf7 input[type="email"], +.wpcf7 input[type="tel"] { + direction: ltr; +} + +.wpcf7-reflection > output { + display: list-item; + list-style: none; +} + +.wpcf7-reflection > output[hidden] { + display: none; +} diff --git a/html/wp-content/plugins/contact-form-7/includes/file.php b/html/wp-content/plugins/contact-form-7/includes/file.php new file mode 100644 index 0000000..2db05d1 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/file.php @@ -0,0 +1,440 @@ + false, + 'filetypes' => '', + 'limit' => MB_IN_BYTES, + ) ); + + foreach ( array( 'name', 'size', 'tmp_name', 'error' ) as $key ) { + if ( ! isset( $file[$key] ) ) { + $file[$key] = array(); + } + } + + $names = wpcf7_array_flatten( $file['name'] ); + $sizes = wpcf7_array_flatten( $file['size'] ); + $tmp_names = wpcf7_array_flatten( $file['tmp_name'] ); + $errors = wpcf7_array_flatten( $file['error'] ); + + foreach ( $errors as $error ) { + if ( ! empty( $error ) and UPLOAD_ERR_NO_FILE !== $error ) { + return new WP_Error( 'wpcf7_upload_failed_php_error', + wpcf7_get_message( 'upload_failed_php_error' ) + ); + } + } + + if ( isset( $options['schema'] ) and isset( $options['name'] ) ) { + $context = array( + 'file' => true, + 'field' => $options['name'], + ); + + foreach ( $options['schema']->validate( $context ) as $result ) { + if ( is_wp_error( $result ) ) { + return $result; + } + } + } + + // Move uploaded file to tmp dir + $uploads_dir = wpcf7_upload_tmp_dir(); + $uploads_dir = wpcf7_maybe_add_random_dir( $uploads_dir ); + + $uploaded_files = array(); + + foreach ( $names as $key => $name ) { + $tmp_name = $tmp_names[$key]; + + if ( empty( $tmp_name ) or ! is_uploaded_file( $tmp_name ) ) { + continue; + } + + $filename = $name; + $filename = wpcf7_canonicalize( $filename, array( 'strto' => 'as-is' ) ); + $filename = wpcf7_antiscript_file_name( $filename ); + + $filename = apply_filters( 'wpcf7_upload_file_name', + $filename, $name, $options + ); + + $filename = wp_unique_filename( $uploads_dir, $filename ); + $new_file = path_join( $uploads_dir, $filename ); + + // phpcs:ignore Generic.PHP.ForbiddenFunctions.Found + if ( false === @move_uploaded_file( $tmp_name, $new_file ) ) { + return new WP_Error( 'wpcf7_upload_failed', + wpcf7_get_message( 'upload_failed' ) + ); + } + + // Make sure the uploaded file is only readable for the owner process. + $filesystem->chmod( $new_file, 0400 ); + + $uploaded_files[] = $new_file; + } + + return $uploaded_files; +} + + +add_filter( + 'wpcf7_messages', + 'wpcf7_file_messages', + 10, 1 +); + +/** + * A wpcf7_messages filter callback that adds messages for + * file-uploading fields. + */ +function wpcf7_file_messages( $messages ) { + return array_merge( $messages, array( + 'upload_failed' => array( + 'description' => __( 'Uploading a file fails for any reason', 'contact-form-7' ), + 'default' => __( 'There was an unknown error uploading the file.', 'contact-form-7' ), + ), + + 'upload_file_type_invalid' => array( + 'description' => __( 'Uploaded file is not allowed for file type', 'contact-form-7' ), + 'default' => __( 'You are not allowed to upload files of this type.', 'contact-form-7' ), + ), + + 'upload_file_too_large' => array( + 'description' => __( 'Uploaded file is too large', 'contact-form-7' ), + 'default' => __( 'The uploaded file is too large.', 'contact-form-7' ), + ), + + 'upload_failed_php_error' => array( + 'description' => __( 'Uploading a file fails for PHP error', 'contact-form-7' ), + 'default' => __( 'There was an error uploading the file.', 'contact-form-7' ), + ), + ) ); +} + + +add_filter( + 'wpcf7_form_enctype', + 'wpcf7_file_form_enctype_filter', + 10, 1 +); + +/** + * A wpcf7_form_enctype filter callback that sets the enctype attribute + * to multipart/form-data if the form has file-uploading fields. + */ +function wpcf7_file_form_enctype_filter( $enctype ) { + $multipart = (bool) wpcf7_scan_form_tags( array( + 'feature' => 'file-uploading', + ) ); + + if ( $multipart ) { + $enctype = 'multipart/form-data'; + } + + return $enctype; +} + + +/** + * Converts a MIME type string to an array of corresponding file extensions. + * + * @param string $mime MIME type. + * Wildcard (*) is available for the subtype part. + * @return array Corresponding file extensions. + */ +function wpcf7_convert_mime_to_ext( $mime ) { + static $mime_types = array(); + + $mime_types = wp_get_mime_types(); + + $results = array(); + + if ( preg_match( '%^([a-z]+)/([*]|[a-z0-9.+-]+)$%i', $mime, $matches ) ) { + foreach ( $mime_types as $key => $val ) { + if ( + '*' === $matches[2] and str_starts_with( $val, $matches[1] . '/' ) or + $val === $matches[0] + ) { + $results = array_merge( $results, explode( '|', $key ) ); + } + } + } + + $results = array_unique( $results ); + $results = array_filter( $results ); + $results = array_values( $results ); + + return $results; +} + + +/** + * Returns a formatted list of acceptable filetypes. + * + * @param string|array $types Optional. Array of filetypes. + * @param string $format Optional. Pre-defined format designator. + * @return string Formatted list of acceptable filetypes. + */ +function wpcf7_acceptable_filetypes( $types = 'default', $format = 'regex' ) { + if ( 'default' === $types or empty( $types ) ) { + $types = array( + 'audio/*', + 'video/*', + 'image/*', + ); + } else { + $types = array_map( + static function ( $type ) { + if ( is_string( $type ) ) { + return preg_split( '/[\s|,]+/', strtolower( $type ) ); + } + }, + (array) $types + ); + + $types = wpcf7_array_flatten( $types ); + $types = array_filter( array_unique( $types ) ); + } + + if ( 'attr' === $format or 'attribute' === $format ) { + $types = array_map( + static function ( $type ) { + if ( false === strpos( $type, '/' ) ) { + return sprintf( '.%s', trim( $type, '.' ) ); + } elseif ( preg_match( '%^([a-z]+)/[*]$%i', $type, $matches ) ) { + if ( + in_array( $matches[1], array( 'audio', 'video', 'image' ), true ) + ) { + return $type; + } else { + return ''; + } + } elseif ( wpcf7_convert_mime_to_ext( $type ) ) { + return $type; + } + }, + $types + ); + + $types = array_filter( $types ); + + return implode( ',', $types ); + + } elseif ( 'regex' === $format ) { + $types = array_map( + static function ( $type ) { + if ( false === strpos( $type, '/' ) ) { + return preg_quote( trim( $type, '.' ) ); + } elseif ( $type = wpcf7_convert_mime_to_ext( $type ) ) { + return $type; + } + }, + $types + ); + + $types = wpcf7_array_flatten( $types ); + $types = array_filter( array_unique( $types ) ); + + return implode( '|', $types ); + } + + return ''; +} + + +add_action( + 'wpcf7_init', + 'wpcf7_init_uploads', + 10, 0 +); + +/** + * Initializes the temporary directory for uploaded files. + */ +function wpcf7_init_uploads() { + $dir = wpcf7_upload_tmp_dir(); + + if ( ! is_dir( $dir ) or ! wp_is_writable( $dir ) ) { + return; + } + + $htaccess_file = path_join( $dir, '.htaccess' ); + + if ( file_exists( $htaccess_file ) ) { + list( $first_line_comment ) = (array) file( + $htaccess_file, + FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES + ); + + if ( '# Apache 2.4+' === $first_line_comment ) { + return; + } + } + + $filesystem = WPCF7_Filesystem::get_instance(); + + $htaccess_body = ' +# Apache 2.4+ + + Require all denied + + +# Apache 2.2 + + Deny from all + +'; + + $filesystem->put_contents( $htaccess_file, ltrim( $htaccess_body ) ); +} + + +/** + * Creates a child directory with a randomly generated name. + * + * @param string $dir The parent directory path. + * @return string The child directory path if created, otherwise the parent. + */ +function wpcf7_maybe_add_random_dir( $dir ) { + do { + $dir_new = path_join( $dir, zeroise( wp_rand(), 10 ) ); + } while ( file_exists( $dir_new ) ); + + if ( wp_mkdir_p( $dir_new ) ) { + return $dir_new; + } + + return $dir; +} + + +/** + * Returns the directory path for uploaded files. + * + * @return string Directory path. + */ +function wpcf7_upload_tmp_dir() { + static $output = ''; + + if ( $output ) { + return $output; + } + + if ( defined( 'WPCF7_UPLOADS_TMP_DIR' ) ) { + $dir = path_join( WP_CONTENT_DIR, WPCF7_UPLOADS_TMP_DIR ); + wp_mkdir_p( $dir ); + + if ( wpcf7_is_file_path_in_content_dir( $dir ) ) { + return $output = $dir; + } + } + + $dir = path_join( wpcf7_upload_dir( 'dir' ), 'wpcf7_uploads' ); + wp_mkdir_p( $dir ); + + return $output = $dir; +} + + +add_action( + 'shutdown', + 'wpcf7_cleanup_upload_files', + 20, 0 +); + +/** + * Cleans up files in the temporary directory for uploaded files. + * + * @param int $seconds Files older than this are removed. Default 60. + * @param int $max Maximum number of files to be removed in a function call. + * Default 100. + */ +function wpcf7_cleanup_upload_files( $seconds = 60, $max = 100 ) { + $dir = trailingslashit( wpcf7_upload_tmp_dir() ); + + if ( + ! is_dir( $dir ) or + ! is_readable( $dir ) or + ! wp_is_writable( $dir ) + ) { + return; + } + + $seconds = absint( $seconds ); + $max = absint( $max ); + $count = 0; + + if ( $handle = opendir( $dir ) ) { + while ( false !== ( $file = readdir( $handle ) ) ) { + if ( '.' === $file or '..' === $file or '.htaccess' === $file ) { + continue; + } + + $mtime = @filemtime( path_join( $dir, $file ) ); + + if ( $mtime and time() < $mtime + $seconds ) { // less than $seconds old + continue; + } + + wpcf7_rmdir_p( path_join( $dir, $file ) ); + $count += 1; + + if ( $max <= $count ) { + break; + } + } + + closedir( $handle ); + } +} + + +add_action( + 'wpcf7_admin_warnings', + 'wpcf7_file_display_warning_message', + 10, 3 +); + +/** + * Displays warning messages about file-uploading fields. + */ +function wpcf7_file_display_warning_message( $page, $action, $object ) { + if ( $object instanceof WPCF7_ContactForm ) { + $contact_form = $object; + } else { + return; + } + + $has_tags = (bool) $contact_form->scan_form_tags( array( + 'feature' => 'file-uploading', + ) ); + + if ( ! $has_tags ) { + return; + } + + $uploads_dir = wpcf7_upload_tmp_dir(); + + if ( ! is_dir( $uploads_dir ) or ! wp_is_writable( $uploads_dir ) ) { + wp_admin_notice( + sprintf( + /* translators: %s: the path of the temporary folder */ + __( 'This contact form has file uploading fields, but the temporary folder for the files (%s) does not exist or is not writable. You can create the folder or change its permission manually.', 'contact-form-7' ), + $uploads_dir + ), + array( 'type' => 'warning' ) + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7/includes/filesystem.php b/html/wp-content/plugins/contact-form-7/includes/filesystem.php new file mode 100644 index 0000000..6f98101 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/filesystem.php @@ -0,0 +1,127 @@ +connect(); + } + + + /** + * Connects to the filesystem. + * + * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. + */ + private function connect() { + global $wp_filesystem; + + if ( $this->filesystem ) { + return false; + } + + require_once ABSPATH . 'wp-admin/includes/file.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php'; + require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php'; + + ob_start(); + $credentials = request_filesystem_credentials( '' ); + ob_end_clean(); + + if ( false === $credentials or ! WP_Filesystem( $credentials ) ) { + wp_trigger_error( + __FUNCTION__, + __( 'Could not access filesystem.', 'contact-form-7' ) + ); + } + + if ( $wp_filesystem instanceof WP_Filesystem_Base ) { + $this->filesystem = $wp_filesystem; + } else { + $this->filesystem = new WP_Filesystem_Direct( 1 ); + } + + if ( ! defined( 'FS_CHMOD_DIR' ) ) { + define( 'FS_CHMOD_DIR', fileperms( ABSPATH ) & 0777 | 0755 ); + } + + if ( ! defined( 'FS_CHMOD_FILE' ) ) { + define( 'FS_CHMOD_FILE', fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ); + } + } + + + /** + * Changes filesystem permissions. + * + * @param string $file Path to the file. + * @param int|false $mode Optional. The permissions as octal number. + * @param bool $recursive Optional. If set to true, + * changes file permissions recursively. Default false. + * @return bool True on success, false on failure. + */ + public function chmod( $file, $mode = false, $recursive = false ) { + return $this->filesystem->chmod( $file, $mode, $recursive ); + } + + + /** + * Deletes a file or directory. + * + * @param string $file Path to the file or directory. + * @param bool $recursive Optional. If set to true, deletes + * files and folders recursively. Default false. + * @param string|false $type Type of resource. + * 'f' for file, 'd' for directory. Default false. + * @return bool True on success, false on failure. + */ + public function delete( $file, $recursive = false, $type = false ) { + return $this->filesystem->delete( $file, $recursive, $type ); + } + + + /** + * Writes a string to a file. + * + * @param string $file Path to the file where to write the data. + * @param string $contents The data to write. + * @param int $mode The file permissions as octal number. + * @return bool True on success, false on failure. + */ + public function put_contents( $file, $contents, $mode = false ) { + return $this->filesystem->put_contents( $file, $contents, $mode ); + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/form-tag.php b/html/wp-content/plugins/contact-form-7/includes/form-tag.php new file mode 100644 index 0000000..c816d35 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/form-tag.php @@ -0,0 +1,618 @@ + $value ) { + if ( property_exists( __CLASS__, $key ) ) { + $this->{$key} = $value; + } + } + } + } + + + /** + * Returns true if the type has a trailing asterisk. + */ + public function is_required() { + return str_ends_with( $this->type, '*' ); + } + + + /** + * Returns true if the form-tag has a specified option. + */ + public function has_option( $option_name ) { + $pattern = sprintf( '/^%s(:.+)?$/i', preg_quote( $option_name, '/' ) ); + return (bool) preg_grep( $pattern, $this->options ); + } + + + /** + * Retrieves option values with the specified option name. + * + * @param string $option_name Option name. + * @param string $pattern Optional. A regular expression pattern or one of + * the keys of preset patterns. If specified, only options + * whose value part matches this pattern will be returned. + * @param bool $single Optional. If true, only the first matching option + * will be returned. Default false. + * @return string|array|bool The option value or an array of option values. + * False if there is no option matches the pattern. + */ + public function get_option( $option_name, $pattern = '', $single = false ) { + $preset_patterns = array( + 'date' => '[0-9]{4}-[0-9]{2}-[0-9]{2}', + 'int' => '[0-9]+', + 'signed_int' => '[-]?[0-9]+', + 'num' => '(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)', + 'signed_num' => '[-]?(?:[0-9]+|(?:[0-9]+)?[.][0-9]+)', + 'class' => '[-0-9a-zA-Z_]+', + 'id' => '[-0-9a-zA-Z_]+', + ); + + if ( isset( $preset_patterns[$pattern] ) ) { + $pattern = $preset_patterns[$pattern]; + } + + if ( '' === $pattern ) { + $pattern = '.+'; + } + + $pattern = sprintf( + '/^%s:%s$/i', + preg_quote( $option_name, '/' ), + $pattern + ); + + if ( $single ) { + $matches = $this->get_first_match_option( $pattern ); + + if ( ! $matches ) { + return false; + } + + return substr( $matches[0], strlen( $option_name ) + 1 ); + } else { + $matches_a = $this->get_all_match_options( $pattern ); + + if ( ! $matches_a ) { + return false; + } + + $results = array(); + + foreach ( $matches_a as $matches ) { + $results[] = substr( $matches[0], strlen( $option_name ) + 1 ); + } + + return $results; + } + } + + + /** + * Retrieves the id option value from the form-tag. + */ + public function get_id_option() { + static $used = array(); + + $option = $this->get_option( 'id', 'id', true ); + + if ( + ! $option or + str_starts_with( $option, 'wpcf7' ) or + in_array( $option, $used, true ) + ) { + return false; + } + + $used[] = $option; + + return $option; + } + + + /** + * Retrieves the class option value from the form-tag. + * + * @param string|array $default_classes Optional. Preset classes as an array + * or a whitespace-separated list. Default empty string. + * @return string|bool A whitespace-separated list of classes. + * False if there is no class to return. + */ + public function get_class_option( $default_classes = '' ) { + if ( is_string( $default_classes ) ) { + $default_classes = explode( ' ', $default_classes ); + } + + $options = array_merge( + (array) $default_classes, + (array) $this->get_option( 'class' ) + ); + + $options = array_map( 'sanitize_html_class', $options ); + $options = array_filter( array_unique( $options ) ); + + if ( empty( $options ) ) { + return false; + } + + return implode( ' ', $options ); + } + + + /** + * Retrieves the autocomplete option value from the form-tag. + * + * @return string|bool A whitespace-separated list of tokens. + * False if there is no token to return. + */ + public function get_autocomplete_option() { + $options = (array) $this->get_option( 'autocomplete', '[-0-9a-zA-Z|]+' ); + + $options = array_reduce( $options, static function ( $carry, $item ) { + return array_merge( $carry, + array_map( 'strtolower', explode( '|', $item ) ) + ); + }, array() ); + + $options = array_filter( $options, static function ( $item ) { + return preg_match( '/^[a-z]+(?:-[0-9a-z]+)*$/', $item ); + } ); + + $options = array_unique( $options ); + + if ( empty( $options ) ) { + return false; + } elseif ( in_array( 'off', $options, true ) ) { + return 'off'; + } elseif ( in_array( 'on', $options, true ) ) { + return 'on'; + } else { + return implode( ' ', $options ); + } + } + + + /** + * Retrieves the size option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_size_option( $default_value = false ) { + $option = $this->get_option( 'size', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( '%^([0-9]*)/[0-9]*$%' ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[1] ) and '' !== $matches[1] ) { + return $matches[1]; + } + } + + return $default_value; + } + + + /** + * Retrieves the maxlength option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_maxlength_option( $default_value = false ) { + $option = $this->get_option( 'maxlength', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( + '%^(?:[0-9]*x?[0-9]*)?/([0-9]+)$%' + ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[1] ) and '' !== $matches[1] ) { + return $matches[1]; + } + } + + return $default_value; + } + + + /** + * Retrieves the minlength option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_minlength_option( $default_value = false ) { + $option = $this->get_option( 'minlength', 'int', true ); + + if ( $option ) { + return $option; + } else { + return $default_value; + } + } + + + /** + * Retrieves the cols option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_cols_option( $default_value = false ) { + $option = $this->get_option( 'cols', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( + '%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%' + ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[1] ) and '' !== $matches[1] ) { + return $matches[1]; + } + } + + return $default_value; + } + + + /** + * Retrieves the rows option value from the form-tag. + * + * @param string $default_value Optional default value. + * @return string The option value. + */ + public function get_rows_option( $default_value = false ) { + $option = $this->get_option( 'rows', 'int', true ); + + if ( $option ) { + return $option; + } + + $matches_a = $this->get_all_match_options( + '%^([0-9]*)x([0-9]*)(?:/[0-9]+)?$%' + ); + + foreach ( $matches_a as $matches ) { + if ( isset( $matches[2] ) and '' !== $matches[2] ) { + return $matches[2]; + } + } + + return $default_value; + } + + + /** + * Retrieves a date-type option value from the form-tag. + * + * @param string $option_name A date-type option name, such as 'min' or 'max'. + * @return string|bool The option value in YYYY-MM-DD format. False if the + * option does not exist or the date value is invalid. + */ + public function get_date_option( $option_name ) { + $option_value = $this->get_option( $option_name, '', true ); + + if ( empty( $option_value ) ) { + return false; + } + + $date = apply_filters( 'wpcf7_form_tag_date_option', + null, + array( $option_name => $option_value ) + ); + + if ( $date ) { + $date_pattern = '/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/'; + + if ( + preg_match( $date_pattern, $date, $matches ) and + checkdate( $matches[2], $matches[3], $matches[1] ) + ) { + return $date; + } + } else { + $datetime_obj = date_create_immutable( + preg_replace( '/[_]+/', ' ', $option_value ), + wp_timezone() + ); + + if ( $datetime_obj ) { + return $datetime_obj->format( 'Y-m-d' ); + } + } + + return false; + } + + + /** + * Retrieves the default option value from the form-tag. + * + * @param string|array $default_value Optional default value. + * @param string|array $args Optional options for the option value retrieval. + * @return string|array The option value. If the multiple option is enabled, + * an array of option values. + */ + public function get_default_option( $default_value = '', $args = '' ) { + $args = wp_parse_args( $args, array( + 'multiple' => false, + 'shifted' => false, + ) ); + + $options = (array) $this->get_option( 'default' ); + $values = array(); + + if ( empty( $options ) ) { + return $args['multiple'] ? $values : $default_value; + } + + foreach ( $options as $opt ) { + $opt = sanitize_key( $opt ); + + if ( 'user_' === substr( $opt, 0, 5 ) and is_user_logged_in() ) { + $primary_props = array( 'user_login', 'user_email', 'user_url' ); + $opt = in_array( $opt, $primary_props, true ) ? $opt : substr( $opt, 5 ); + + $user = wp_get_current_user(); + $user_prop = $user->get( $opt ); + + if ( ! empty( $user_prop ) ) { + if ( $args['multiple'] ) { + $values[] = $user_prop; + } else { + return $user_prop; + } + } + + } elseif ( 'post_meta' === $opt and in_the_loop() ) { + if ( $args['multiple'] ) { + $values = array_merge( $values, + get_post_meta( get_the_ID(), $this->name ) + ); + } else { + $val = (string) get_post_meta( get_the_ID(), $this->name, true ); + + if ( strlen( $val ) ) { + return $val; + } + } + + } elseif ( + 'get' === $opt and + $vals = wpcf7_superglobal_get( $this->name ) + ) { + $vals = array_map( 'wpcf7_sanitize_query_var', (array) $vals ); + + if ( $args['multiple'] ) { + $values = array_merge( $values, $vals ); + } else { + $val = isset( $vals[0] ) ? (string) $vals[0] : ''; + + if ( strlen( $val ) ) { + return $val; + } + } + + } elseif ( + 'post' === $opt and + $vals = wpcf7_superglobal_post( $this->name ) + ) { + $vals = array_map( 'wpcf7_sanitize_query_var', (array) $vals ); + + if ( $args['multiple'] ) { + $values = array_merge( $values, $vals ); + } else { + $val = isset( $vals[0] ) ? (string) $vals[0] : ''; + + if ( strlen( $val ) ) { + return $val; + } + } + + } elseif ( 'shortcode_attr' === $opt ) { + if ( $contact_form = WPCF7_ContactForm::get_current() ) { + $val = $contact_form->shortcode_attr( $this->name ); + + if ( isset( $val ) and strlen( $val ) ) { + if ( $args['multiple'] ) { + $values[] = $val; + } else { + return $val; + } + } + } + + } elseif ( preg_match( '/^[0-9_]+$/', $opt ) ) { + $nums = explode( '_', $opt ); + + foreach ( $nums as $num ) { + $num = absint( $num ); + $num = $args['shifted'] ? $num : $num - 1; + + if ( isset( $this->values[$num] ) ) { + if ( $args['multiple'] ) { + $values[] = $this->values[$num]; + } else { + return $this->values[$num]; + } + } + } + } + } + + if ( $args['multiple'] ) { + $values = array_unique( $values ); + return $values; + } else { + return $default_value; + } + } + + + /** + * Retrieves the data option value from the form-tag. + * + * @param string|array $args Optional options for the option value retrieval. + * @return mixed The option value. + */ + public function get_data_option( $args = '' ) { + $options = (array) $this->get_option( 'data' ); + + return apply_filters( 'wpcf7_form_tag_data_option', null, $options, $args ); + } + + + /** + * Retrieves the limit option value from the form-tag. + * + * @param int $default_value Optional default value. Default 1048576. + * @return int The option value. + */ + public function get_limit_option( $default_value = MB_IN_BYTES ) { + $pattern = '/^limit:([1-9][0-9]*)([kKmM]?[bB])?$/'; + + $matches = $this->get_first_match_option( $pattern ); + + if ( $matches ) { + $size = (int) $matches[1]; + + if ( ! empty( $matches[2] ) ) { + $kbmb = strtolower( $matches[2] ); + + if ( 'kb' === $kbmb ) { + $size *= KB_IN_BYTES; + } elseif ( 'mb' === $kbmb ) { + $size *= MB_IN_BYTES; + } + } + + return $size; + } + + return (int) $default_value; + } + + + /** + * Retrieves the value of the first option matches the given + * regular expression pattern. + * + * @param string $pattern Regular expression pattern. + * @return array|bool Option value as an array of matched strings. + * False if there is no option matches the pattern. + */ + public function get_first_match_option( $pattern ) { + foreach ( (array) $this->options as $option ) { + if ( preg_match( $pattern, $option, $matches ) ) { + return $matches; + } + } + + return false; + } + + + /** + * Retrieves values of options that match the given + * regular expression pattern. + * + * @param string $pattern Regular expression pattern. + * @return array Array of arrays of strings that match the pattern. + */ + public function get_all_match_options( $pattern ) { + $result = array(); + + foreach ( (array) $this->options as $option ) { + if ( preg_match( $pattern, $option, $matches ) ) { + $result[] = $matches; + } + } + + return $result; + } + + + /** + * Assigns a value to the specified offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetset.php + */ + #[ReturnTypeWillChange] + public function offsetSet( $offset, $value ) { + if ( property_exists( __CLASS__, $offset ) ) { + $this->{$offset} = $value; + } + } + + + /** + * Returns the value at specified offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetget.php + */ + #[ReturnTypeWillChange] + public function offsetGet( $offset ) { + if ( property_exists( __CLASS__, $offset ) ) { + return $this->{$offset}; + } + + return null; + } + + + /** + * Returns true if the specified offset exists. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetexists.php + */ + #[ReturnTypeWillChange] + public function offsetExists( $offset ) { + return property_exists( __CLASS__, $offset ); + } + + + /** + * Unsets an offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetunset.php + */ + #[ReturnTypeWillChange] + public function offsetUnset( $offset ) { + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/form-tags-manager.php b/html/wp-content/plugins/contact-form-7/includes/form-tags-manager.php new file mode 100644 index 0000000..6088381 --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/form-tags-manager.php @@ -0,0 +1,615 @@ +add( $tag_types, $callback, $features ); +} + + +/** + * Wrapper function of WPCF7_FormTagsManager::remove(). + */ +function wpcf7_remove_form_tag( $tag_type ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + return $manager->remove( $tag_type ); +} + + +/** + * Wrapper function of WPCF7_FormTagsManager::replace_all(). + */ +function wpcf7_replace_all_form_tags( $content ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + return $manager->replace_all( $content ); +} + + +/** + * Wrapper function of WPCF7_ContactForm::scan_form_tags(). + */ +function wpcf7_scan_form_tags( $cond = null ) { + $contact_form = WPCF7_ContactForm::get_current(); + + if ( $contact_form ) { + return $contact_form->scan_form_tags( $cond ); + } + + return array(); +} + + +/** + * Wrapper function of WPCF7_FormTagsManager::tag_type_supports(). + */ +function wpcf7_form_tag_supports( $tag_type, $feature ) { + $manager = WPCF7_FormTagsManager::get_instance(); + + return $manager->tag_type_supports( $tag_type, $feature ); +} + + +/** + * The singleton instance of this class manages the collection of form-tags. + */ +class WPCF7_FormTagsManager { + + private static $instance; + + private $tag_types = array(); + private $scanned_tags = null; // Tags scanned at the last time of scan() + private $placeholders = array(); + + private function __construct() {} + + + /** + * Returns the singleton instance. + * + * @return WPCF7_FormTagsManager The singleton manager. + */ + public static function get_instance() { + if ( empty( self::$instance ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + + /** + * Returns scanned form-tags. + * + * @return array Array of WPCF7_FormTag objects. + */ + public function get_scanned_tags() { + return $this->scanned_tags; + } + + + /** + * Registers form-tag types to the manager. + * + * @param string|array $tag_types The name of the form-tag type or + * an array of the names. + * @param callable $callback The callback to generates a form control HTML + * for a form-tag in this type. + * @param string|array $features Optional. Features a form-tag + * in this type supports. + */ + public function add( $tag_types, $callback, $features = '' ) { + if ( ! is_callable( $callback ) ) { + return; + } + + if ( true === $features ) { // for back-compat + $features = array( 'name-attr' => true ); + } + + $features = wp_parse_args( $features, array() ); + + $tag_types = array_filter( array_unique( (array) $tag_types ) ); + + foreach ( $tag_types as $tag_type ) { + $tag_type = $this->sanitize_tag_type( $tag_type ); + + if ( ! $this->tag_type_exists( $tag_type ) ) { + $this->tag_types[$tag_type] = array( + 'function' => $callback, + 'features' => $features, + ); + } + } + } + + + /** + * Returns true if the given tag type exists. + */ + public function tag_type_exists( $tag_type ) { + return isset( $this->tag_types[$tag_type] ); + } + + + /** + * Returns true if the tag type supports the features. + * + * @param string $tag_type The name of the form-tag type. + * @param array|string $features The feature to check or an array of features. + * @return bool True if the form-tag type supports at least one of + * the given features, false otherwise. + */ + public function tag_type_supports( $tag_type, $features ) { + $features = array_filter( (array) $features ); + + if ( isset( $this->tag_types[$tag_type]['features'] ) ) { + return (bool) array_intersect( + array_keys( array_filter( $this->tag_types[$tag_type]['features'] ) ), + $features + ); + } + + return false; + } + + + /** + * Returns form-tag types that support the given features. + * + * @param array|string $features Optional. The feature to check or + * an array of features. Default empty array. + * @param bool $invert Optional. If this value is true, returns form-tag + * types that do not support the given features. Default false. + * @return array An array of form-tag types. If the $features param is empty, + * returns all form-tag types that have been registered. + */ + public function collect_tag_types( $features = array(), $invert = false ) { + $tag_types = array_keys( $this->tag_types ); + + if ( empty( $features ) ) { + return $tag_types; + } + + $output = array(); + + foreach ( $tag_types as $tag_type ) { + if ( + ! $invert and $this->tag_type_supports( $tag_type, $features ) or + $invert and ! $this->tag_type_supports( $tag_type, $features ) + ) { + $output[] = $tag_type; + } + } + + return $output; + } + + + /** + * Sanitizes the form-tag type name. + */ + private function sanitize_tag_type( $tag_type ) { + $tag_type = preg_replace( '/[^a-zA-Z0-9_*]+/', '_', $tag_type ); + $tag_type = rtrim( $tag_type, '_' ); + $tag_type = strtolower( $tag_type ); + return $tag_type; + } + + + /** + * Deregisters the form-tag type. + */ + public function remove( $tag_type ) { + unset( $this->tag_types[$tag_type] ); + } + + + /** + * Normalizes the text content that includes form-tags. + */ + public function normalize( $content ) { + if ( empty( $this->tag_types ) ) { + return $content; + } + + $content = preg_replace_callback( + '/' . $this->tag_regex() . '/su', + array( $this, 'normalize_callback' ), + $content + ); + + return $content; + } + + + /** + * The callback function used within normalize(). + */ + private function normalize_callback( $matches ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[6] ) { + return $matches[0]; + } + + $tag = $matches[2]; + + $attr = trim( preg_replace( '/[\r\n\t ]+/', ' ', $matches[3] ) ); + $attr = strtr( $attr, array( '<' => '<', '>' => '>' ) ); + + $content = trim( $matches[5] ); + $content = str_replace( "\n", '', $content ); + + $result = $matches[1] . '[' . $tag + . ( $attr ? ' ' . $attr : '' ) + . ( $matches[4] ? ' ' . $matches[4] : '' ) + . ']' + . ( $content ? $content . '[/' . $tag . ']' : '' ) + . $matches[6]; + + return $result; + } + + + /** + * Replace all form-tags in the given text with placeholders. + */ + public function replace_with_placeholders( $content ) { + if ( empty( $this->tag_types ) ) { + return $content; + } + + $this->placeholders = array(); + + $callback = function ( $matches ) { + // Allow [[foo]] syntax for escaping a tag. + if ( '[' === $matches[1] and ']' === $matches[6] ) { + return $matches[0]; + } + + $tag = $matches[0]; + $tag_type = $matches[2]; + + $block_or_hidden = $this->tag_type_supports( + $tag_type, + array( 'display-block', 'display-hidden' ) + ); + + if ( $block_or_hidden ) { + $placeholder_tag_name = WPCF7_HTMLFormatter::placeholder_block; + } else { + $placeholder_tag_name = WPCF7_HTMLFormatter::placeholder_inline; + } + + $placeholder = sprintf( + '<%1$s id="%2$s" />', + $placeholder_tag_name, + hash( 'sha256', $tag ) + ); + + list( $placeholder ) = + WPCF7_HTMLFormatter::normalize_start_tag( $placeholder ); + + $this->placeholders[$placeholder] = $tag; + + return $placeholder; + }; + + return preg_replace_callback( + '/' . $this->tag_regex() . '/su', + $callback, + $content + ); + } + + + /** + * Replace placeholders in the given text with original form-tags. + */ + public function restore_from_placeholders( $content ) { + return str_replace( + array_keys( $this->placeholders ), + array_values( $this->placeholders ), + $content + ); + } + + + /** + * Replaces all form-tags in the text content. + * + * @param string $content The text content including form-tags. + * @return string The result of replacements. + */ + public function replace_all( $content ) { + return $this->scan( $content, true ); + } + + + /** + * Scans form-tags in the text content. + * + * @param string $content The text content including form-tags. + * @param bool $replace Optional. Whether scanned form-tags will be + * replaced. Default false. + * @return array|string An array of scanned form-tags if $replace is false. + * Otherwise text that scanned form-tags are replaced. + */ + public function scan( $content, $replace = false ) { + $this->scanned_tags = array(); + + if ( empty( $this->tag_types ) ) { + if ( $replace ) { + return $content; + } else { + return $this->scanned_tags; + } + } + + if ( $replace ) { + $content = preg_replace_callback( + '/' . $this->tag_regex() . '/su', + array( $this, 'replace_callback' ), + $content + ); + + return $content; + } else { + preg_replace_callback( + '/' . $this->tag_regex() . '/su', + array( $this, 'scan_callback' ), + $content + ); + + return $this->scanned_tags; + } + } + + + /** + * Filters form-tags based on a condition array argument. + * + * @param array|string $input The original form-tags collection. + * If it is a string, scans form-tags from it. + * @param array $cond The conditions that filtering will be based on. + * @return array The filtered form-tags collection. + */ + public function filter( $input, $cond ) { + if ( is_array( $input ) ) { + $tags = $input; + } elseif ( is_string( $input ) ) { + $tags = $this->scan( $input ); + } else { + $tags = $this->scanned_tags; + } + + $cond = wp_parse_args( $cond, array( + 'type' => array(), + 'basetype' => array(), + 'name' => array(), + 'feature' => array(), + ) ); + + $cond = array_map( static function ( $c ) { + return array_filter( array_map( 'trim', (array) $c ) ); + }, $cond ); + + $tags = array_filter( + (array) $tags, + function ( $tag ) use ( $cond ) { + $tag = new WPCF7_FormTag( $tag ); + + if ( + $cond['type'] and + ! in_array( $tag->type, $cond['type'], true ) + ) { + return false; + } + + if ( + $cond['basetype'] and + ! in_array( $tag->basetype, $cond['basetype'], true ) + ) { + return false; + } + + if ( + $cond['name'] and + ! in_array( $tag->name, $cond['name'], true ) + ) { + return false; + } + + foreach ( $cond['feature'] as $feature ) { + if ( str_starts_with( $feature, '!' ) ) { // Negation + $feature = trim( substr( $feature, 1 ) ); + + if ( $this->tag_type_supports( $tag->type, $feature ) ) { + return false; + } + } else { + if ( ! $this->tag_type_supports( $tag->type, $feature ) ) { + return false; + } + } + } + + return true; + } + ); + + return array_values( $tags ); + } + + + /** + * Returns the regular expression for a form-tag. + */ + private function tag_regex() { + $tag_types = implode( '|', + array_map( 'preg_quote', array_keys( $this->tag_types ) ) + ); + + $whitespaces = wpcf7_get_unicode_whitespaces(); + + return '(\[?)' + . '\[(' . $tag_types . ')' + . '(?:[' . $whitespaces . ']+(.*?))?' + . '(?:[' . $whitespaces . ']+(\/))?\]' + . '(?:([^[]*?)\[\/\2\])?' + . '(\]?)'; + } + + + /** + * The callback function for the form-tag replacement. + */ + private function replace_callback( $matches ) { + return $this->scan_callback( $matches, true ); + } + + + /** + * The callback function for the form-tag scanning. + */ + private function scan_callback( $matches, $replace = false ) { + // allow [[foo]] syntax for escaping a tag + if ( '[' === $matches[1] and ']' === $matches[6] ) { + return substr( $matches[0], 1, -1 ); + } + + $tag_type = $matches[2]; + $tag_basetype = trim( $tag_type, '*' ); + $attr = $this->parse_atts( $matches[3] ); + + $scanned_tag = array( + 'type' => $tag_type, + 'basetype' => $tag_basetype, + 'raw_name' => '', + 'name' => '', + 'options' => array(), + 'raw_values' => array(), + 'values' => array(), + 'pipes' => null, + 'labels' => array(), + 'attr' => '', + 'content' => '', + ); + + if ( $this->tag_type_supports( $tag_type, 'singular' ) ) { + $tags_in_same_basetype = $this->filter( + $this->scanned_tags, + array( 'basetype' => $tag_basetype ) + ); + + if ( $tags_in_same_basetype ) { + // Another tag in the same base type already exists. Ignore this one. + return $matches[0]; + } + } + + if ( $this->tag_type_supports( $tag_type, 'name-attr' ) ) { + if ( ! is_array( $attr ) ) { + return $matches[0]; // Invalid form-tag. + } + + $scanned_tag['raw_name'] = (string) array_shift( $attr['options'] ); + + if ( ! wpcf7_is_name( $scanned_tag['raw_name'] ) ) { + return $matches[0]; // Invalid name is used. Ignore this tag. + } + + $scanned_tag['name'] = strtr( $scanned_tag['raw_name'], '.', '_' ); + } + + if ( is_array( $attr ) ) { + $scanned_tag['options'] = (array) $attr['options']; + $scanned_tag['raw_values'] = (array) $attr['values']; + + if ( WPCF7_USE_PIPE ) { + $pipes = new WPCF7_Pipes( $scanned_tag['raw_values'] ); + $scanned_tag['values'] = $pipes->collect_befores(); + $scanned_tag['pipes'] = $pipes; + } else { + $scanned_tag['values'] = $scanned_tag['raw_values']; + } + + $scanned_tag['labels'] = $scanned_tag['values']; + + } else { + $scanned_tag['attr'] = $attr; + } + + $scanned_tag['values'] = array_map( 'trim', $scanned_tag['values'] ); + $scanned_tag['labels'] = array_map( 'trim', $scanned_tag['labels'] ); + + $content = trim( $matches[5] ); + $content = preg_replace( "/$/m", '', $content ); + $scanned_tag['content'] = $content; + + $scanned_tag = apply_filters( 'wpcf7_form_tag', $scanned_tag, $replace ); + + $scanned_tag = new WPCF7_FormTag( $scanned_tag ); + + $this->scanned_tags[] = $scanned_tag; + + if ( $replace ) { + $callback = $this->tag_types[$tag_type]['function']; + return $matches[1] . call_user_func( $callback, $scanned_tag ) . $matches[6]; + } else { + return $matches[0]; + } + } + + + /** + * Parses the attributes of a form-tag to extract the name, + * options, and values. + * + * @param string $text Attributes of a form-tag. + * @return array|string An associative array of the options and values + * if the input is in the correct syntax, + * otherwise the input text itself. + */ + private function parse_atts( $text ) { + $atts = array( + 'options' => array(), + 'values' => array(), + ); + + $whitespaces = wpcf7_get_unicode_whitespaces(); + + $text = preg_replace( '/[\x{00a0}\x{200b}]+/u', ' ', $text ); + $text = wpcf7_strip_whitespaces( $text ); + + $pattern = '%^([-+*=0-9a-zA-Z:.!?#$&@_/|\%' . $whitespaces . ']*?)' + . '((?:' + . '[' . $whitespaces . ']*"[^"]*"' + . '|' + . '[' . $whitespaces . ']*\'[^\']*\'' + . ')*)$%u'; + + if ( preg_match( $pattern, $text, $matches ) ) { + if ( ! empty( $matches[1] ) ) { + $atts['options'] = preg_split( + sprintf( '/[%s]+/u', $whitespaces ), + wpcf7_strip_whitespaces( $matches[1] ) + ); + } + + if ( ! empty( $matches[2] ) ) { + preg_match_all( '/"[^"]*"|\'[^\']*\'/', $matches[2], $matched_values ); + $atts['values'] = wpcf7_strip_quote_deep( $matched_values[0] ); + } + } else { + $atts = $text; + } + + return $atts; + } + +} diff --git a/html/wp-content/plugins/contact-form-7/includes/formatting.php b/html/wp-content/plugins/contact-form-7/includes/formatting.php new file mode 100644 index 0000000..37210db --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/formatting.php @@ -0,0 +1,653 @@ +/is', + static function ( $matches ) use ( &$placeholders ) { + $placeholder = sprintf( + '<%1$s id="%2$s" />', + WPCF7_HTMLFormatter::placeholder_inline, + hash( 'sha256', $matches[0] ) + ); + + list( $placeholder ) = + WPCF7_HTMLFormatter::normalize_start_tag( $placeholder ); + + $placeholders[$placeholder] = $matches[0]; + + return $placeholder; + }, + $input + ); + + $formatter = new WPCF7_HTMLFormatter( array( + 'auto_br' => $br, + 'allowed_html' => null, + ) ); + + $chunks = $formatter->separate_into_chunks( $input ); + + $output = $formatter->format( $chunks ); + + // Restore from placeholders. + $output = str_replace( + array_keys( $placeholders ), + array_values( $placeholders ), + $output + ); + + return $output; +} + + +/** + * Newline preservation help function for wpcf7_autop(). + * + * @deprecated 5.7 Unnecessary to use any more. + * + * @param array $matches preg_replace_callback() matches array. + * @return string Text including newline placeholders. + */ +function wpcf7_autop_preserve_newline_callback( $matches ) { + return str_replace( "\n", '', $matches[0] ); +} + + +/** + * Sanitizes the query variables. + * + * @param string $text Query variable. + * @return string Text sanitized. + */ +function wpcf7_sanitize_query_var( $text ) { + $text = wp_unslash( $text ); + $text = wp_check_invalid_utf8( $text ); + + if ( false !== strpos( $text, '<' ) ) { + $text = wp_pre_kses_less_than( $text ); + $text = wp_strip_all_tags( $text ); + } + + $text = preg_replace( '/%[a-f0-9]{2}/i', '', $text ); + $text = preg_replace( '/ +/', ' ', $text ); + $text = trim( $text, ' ' ); + + return $text; +} + + +/** + * Strips quote characters surrounding the input. + * + * @param string $text Input text. + * @return string Processed output. + */ +function wpcf7_strip_quote( $text ) { + $text = wpcf7_strip_whitespaces( $text ); + + if ( preg_match( '/^"(.*)"$/s', $text, $matches ) ) { + $text = $matches[1]; + } elseif ( preg_match( "/^'(.*)'$/s", $text, $matches ) ) { + $text = $matches[1]; + } + + return $text; +} + + +/** + * Navigates through an array, object, or scalar, and + * strips quote characters surrounding the each value. + * + * @param mixed $input The array or string to be processed. + * @return mixed Processed value. + */ +function wpcf7_strip_quote_deep( $input ) { + if ( is_string( $input ) ) { + return wpcf7_strip_quote( $input ); + } + + if ( is_array( $input ) ) { + $result = array(); + + foreach ( $input as $key => $text ) { + $result[$key] = wpcf7_strip_quote_deep( $text ); + } + + return $result; + } +} + + +/** + * Normalizes newline characters. + * + * @param string $text Input text. + * @param string $to Optional. The newline character that is used in the output. + * @return string Normalized text. + */ +function wpcf7_normalize_newline( $text, $to = "\n" ) { + if ( ! is_string( $text ) ) { + return $text; + } + + $nls = array( "\r\n", "\r", "\n" ); + + if ( ! in_array( $to, $nls, true ) ) { + return $text; + } + + return str_replace( $nls, $to, $text ); +} + + +/** + * Navigates through an array, object, or scalar, and + * normalizes newline characters in the each value. + * + * @param mixed $input The array or string to be processed. + * @param string $to Optional. The newline character that is used in the output. + * @return mixed Processed value. + */ +function wpcf7_normalize_newline_deep( $input, $to = "\n" ) { + if ( is_array( $input ) ) { + $result = array(); + + foreach ( $input as $key => $text ) { + $result[$key] = wpcf7_normalize_newline_deep( $text, $to ); + } + + return $result; + } + + return wpcf7_normalize_newline( $input, $to ); +} + + +/** + * Strips newline characters. + * + * @param string $text Input text. + * @return string Processed one-line text. + */ +function wpcf7_strip_newline( $text ) { + $text = (string) $text; + $text = str_replace( array( "\r", "\n" ), '', $text ); + return wpcf7_strip_whitespaces( $text ); +} + + +/** + * Canonicalizes text. + * + * @param string $text Input text. + * @param string|array|object $options Options. + * @return string Canonicalized text. + */ +function wpcf7_canonicalize( $text, $options = '' ) { + // for back-compat + if ( + is_string( $options ) and + '' !== $options and + ! str_contains( $options, '=' ) + ) { + $options = array( + 'strto' => $options, + ); + } + + $options = wp_parse_args( $options, array( + 'strto' => 'lower', + 'strip_separators' => false, + ) ); + + static $charset = null; + + if ( ! isset( $charset ) ) { + $charset = get_option( 'blog_charset' ); + + $is_utf8 = in_array( + $charset, + array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ), + true + ); + + if ( $is_utf8 ) { + $charset = 'UTF-8'; + } + } + + $text = html_entity_decode( $text, ENT_QUOTES | ENT_HTML5, $charset ); + + if ( function_exists( 'mb_convert_kana' ) ) { + $text = mb_convert_kana( $text, 'asKV', $charset ); + } + + if ( $options['strip_separators'] ) { + $text = preg_replace( '/[\r\n\t ]+/', '', $text ); + } else { + $text = preg_replace( '/[\r\n\t ]+/', ' ', $text ); + } + + if ( 'lower' === $options['strto'] ) { + if ( function_exists( 'mb_strtolower' ) ) { + $text = mb_strtolower( $text, $charset ); + } else { + $text = strtolower( $text ); + } + } elseif ( 'upper' === $options['strto'] ) { + if ( function_exists( 'mb_strtoupper' ) ) { + $text = mb_strtoupper( $text, $charset ); + } else { + $text = strtoupper( $text ); + } + } + + return wpcf7_strip_whitespaces( $text ); +} + + +/** + * Returns a canonical keyword usable for a name or an ID purposes. + */ +function wpcf7_canonicalize_name( $text ) { + return preg_replace( '/[^0-9a-z]+/i', '-', $text ); +} + + +/** + * Sanitizes Contact Form 7's form unit-tag. + * + * @param string $tag Unit-tag. + * @return string Sanitized unit-tag. + */ +function wpcf7_sanitize_unit_tag( $tag ) { + $tag = preg_replace( '/[^A-Za-z0-9_-]/', '', (string) $tag ); + return $tag; +} + + +/** + * Converts a file name to one that is not executable as a script. + * + * @param string $filename File name. + * @return string Converted file name. + */ +function wpcf7_antiscript_file_name( $filename ) { + $filename = wp_basename( $filename ); + + // Apply part of protection logic from sanitize_file_name(). + $filename = str_replace( + array( + '?', '[', ']', '/', '\\', '=', '<', '>', ':', ';', ',', "'", '"', + '&', '$', '#', '*', '(', ')', '|', '~', '`', '!', '{', '}', + '%', '+', '’', '«', '»', 'â€', '“', chr( 0 ) + ), + '', + $filename + ); + + $filename = preg_replace( '/[\r\n\t -]+/', '-', $filename ); + $filename = preg_replace( '/[\pC\pZ]+/iu', '', $filename ); + + $parts = explode( '.', $filename ); + + if ( count( $parts ) < 2 ) { + return $filename; + } + + $script_pattern = '/^(php|phtml|pl|py|rb|cgi|asp|aspx)\d?$/i'; + + $filename = array_shift( $parts ); + $extension = array_pop( $parts ); + + foreach ( $parts as $part ) { + if ( preg_match( $script_pattern, $part ) ) { + $filename .= '.' . $part . '_'; + } else { + $filename .= '.' . $part; + } + } + + if ( preg_match( $script_pattern, $extension ) ) { + $filename .= '.' . $extension . '_.txt'; + } else { + $filename .= '.' . $extension; + } + + return $filename; +} + + +/** + * Masks a password with asterisks (*). + * + * @param int $right Length of right-hand unmasked text. Default 0. + * @param int $left Length of left-hand unmasked text. Default 0. + * @return string Text of masked password. + */ +function wpcf7_mask_password( $text, $right = 0, $left = 0 ) { + $length = strlen( $text ); + + $right = absint( $right ); + $left = absint( $left ); + + if ( $length < $right + $left ) { + $right = $left = 0; + } + + if ( $length <= 48 ) { + $masked = str_repeat( '*', $length - ( $right + $left ) ); + } elseif ( $right + $left < 48 ) { + $masked = str_repeat( '*', 48 - ( $right + $left ) ); + } else { + $masked = '****'; + } + + $left_unmasked = $left ? substr( $text, 0, $left ) : ''; + $right_unmasked = $right ? substr( $text, -1 * $right ) : ''; + + $text = $left_unmasked . $masked . $right_unmasked; + + return $text; +} + + +/** + * Returns an array of allowed HTML tags and attributes for a given context. + * + * @param string $context Context used to decide allowed tags and attributes. + * @return array Array of allowed HTML tags and their allowed attributes. + */ +function wpcf7_kses_allowed_html( $context = 'form' ) { + static $allowed_tags = array(); + + if ( isset( $allowed_tags[$context] ) ) { + return apply_filters( + 'wpcf7_kses_allowed_html', + $allowed_tags[$context], + $context + ); + } + + $allowed_tags[$context] = wp_kses_allowed_html( 'post' ); + + if ( 'form' === $context ) { + $additional_tags_for_form = array( + 'button' => array( + 'disabled' => true, + 'name' => true, + 'type' => true, + 'value' => true, + ), + 'datalist' => array(), + 'fieldset' => array( + 'disabled' => true, + 'name' => true, + ), + 'input' => array( + 'accept' => true, + 'alt' => true, + 'autocomplete' => true, + 'capture' => true, + 'checked' => true, + 'disabled' => true, + 'list' => true, + 'max' => true, + 'maxlength' => true, + 'min' => true, + 'minlength' => true, + 'multiple' => true, + 'name' => true, + 'pattern' => true, + 'placeholder' => true, + 'readonly' => true, + 'required' => true, + 'size' => true, + 'step' => true, + 'type' => true, + 'value' => true, + ), + 'label' => array( + 'for' => true, + ), + 'legend' => array(), + 'meter' => array( + 'value' => true, + 'min' => true, + 'max' => true, + 'low' => true, + 'high' => true, + 'optimum' => true, + ), + 'optgroup' => array( + 'disabled' => true, + 'label' => true, + ), + 'option' => array( + 'disabled' => true, + 'label' => true, + 'selected' => true, + 'value' => true, + ), + 'output' => array( + 'for' => true, + 'name' => true, + ), + 'progress' => array( + 'max' => true, + 'value' => true, + ), + 'select' => array( + 'autocomplete' => true, + 'disabled' => true, + 'multiple' => true, + 'name' => true, + 'required' => true, + 'size' => true, + ), + 'textarea' => array( + 'autocomplete' => true, + 'cols' => true, + 'disabled' => true, + 'maxlength' => true, + 'minlength' => true, + 'name' => true, + 'placeholder' => true, + 'readonly' => true, + 'required' => true, + 'rows' => true, + 'wrap' => true, + ), + ); + + $allowed_tags[$context] = array_merge( + $allowed_tags[$context], + $additional_tags_for_form + ); + + $allowed_tags[$context] = array_map( + static function ( $elm ) { + $global_attributes = array( + 'aria-atomic' => true, + 'aria-checked' => true, + 'aria-controls' => true, + 'aria-current' => true, + 'aria-describedby' => true, + 'aria-details' => true, + 'aria-disabled' => true, + 'aria-expanded' => true, + 'aria-hidden' => true, + 'aria-invalid' => true, + 'aria-label' => true, + 'aria-labelledby' => true, + 'aria-live' => true, + 'aria-relevant' => true, + 'aria-required' => true, + 'aria-selected' => true, + 'class' => true, + 'data-*' => true, + 'dir' => true, + 'hidden' => true, + 'id' => true, + 'inputmode' => true, + 'lang' => true, + 'role' => true, + 'spellcheck' => true, + 'style' => true, + 'tabindex' => true, + 'title' => true, + 'xml:lang' => true, + ); + + return array_merge( $global_attributes, (array) $elm ); + }, + $allowed_tags[$context] + ); + } + + return apply_filters( + 'wpcf7_kses_allowed_html', + $allowed_tags[$context], + $context + ); +} + + +/** + * Sanitizes content for allowed HTML tags for the specified context. + * + * @param string $input Content to filter. + * @param string $context Context used to decide allowed tags and attributes. + * @return string Filtered text with allowed HTML tags and attributes intact. + */ +function wpcf7_kses( $input, $context = 'form' ) { + $output = wp_kses( + $input, + wpcf7_kses_allowed_html( $context ) + ); + + return $output; +} + + +/** + * Returns a formatted string of HTML attributes. + * + * @param array $atts Associative array of attribute name and value pairs. + * @return string Formatted HTML attributes. + */ +function wpcf7_format_atts( $atts ) { + $atts_filtered = array(); + + foreach ( $atts as $name => $value ) { + $name = strtolower( trim( $name ) ); + + if ( ! preg_match( '/^[a-z_:][a-z_:.0-9-]*$/', $name ) ) { + continue; + } + + static $boolean_attributes = array( + 'checked', + 'disabled', + 'inert', + 'multiple', + 'readonly', + 'required', + 'selected', + ); + + if ( in_array( $name, $boolean_attributes, true ) and '' === $value ) { + $value = false; + } + + if ( is_numeric( $value ) ) { + $value = (string) $value; + } + + if ( null === $value or false === $value ) { + unset( $atts_filtered[$name] ); + } elseif ( true === $value ) { + $atts_filtered[$name] = $name; // boolean attribute + } elseif ( is_string( $value ) ) { + $atts_filtered[$name] = trim( $value ); + } + } + + $output = ''; + + foreach ( $atts_filtered as $name => $value ) { + $output .= sprintf( ' %1$s="%2$s"', $name, esc_attr( $value ) ); + } + + return trim( $output ); +} + + +/** + * Returns the regular expression pattern that represents + * whitespace characters Unicode defines. + * + * @link https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt + * + * @return string Regular expression pattern. + */ +function wpcf7_get_unicode_whitespaces() { + return '\x09-\x0D\x20\x85\xA0\x{1680}\x{2000}-\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}'; +} + + +/** + * Strips surrounding whitespaces. + * + * @link https://contactform7.com/2024/07/13/consistent-handling-policy-of-surrounding-whitespaces/ + * + * @param string|array $input Input text. + * @param string $side The side from which whitespaces are stripped. + * 'start', 'end', or 'both' (default). + * @return string|array Output text. + */ +function wpcf7_strip_whitespaces( $input, $side = 'both' ) { + if ( is_array( $input ) ) { + return array_map( + static function ( $i ) use ( $side ) { + return wpcf7_strip_whitespaces( $i, $side ); + }, + $input + ); + } + + // https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html + $whitespaces = wpcf7_get_unicode_whitespaces() . '\x{FEFF}'; + + if ( 'end' !== $side ) { + // Strip leading whitespaces + $input = preg_replace( + sprintf( '/^[%s]+/u', $whitespaces ), + '', + $input + ); + } + + if ( 'start' !== $side ) { + // Strip trailing whitespaces + $input = preg_replace( + sprintf( '/[%s]+$/u', $whitespaces ), + '', + $input + ); + } + + return $input; +} diff --git a/html/wp-content/plugins/contact-form-7/includes/functions.php b/html/wp-content/plugins/contact-form-7/includes/functions.php new file mode 100644 index 0000000..2ce51cf --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/functions.php @@ -0,0 +1,749 @@ + $uploads['basedir'], + 'url' => $uploads['baseurl'], + ) ); + + if ( 'dir' === $type ) { + return $uploads['dir']; + } if ( 'url' === $type ) { + return $uploads['url']; + } + + return $uploads; +} + + +/** + * Verifies that a correct security nonce was used with time limit. + * + * @param string $nonce Nonce value that was used for verification. + * @param string $action Optional. Context to what is taking place. + * Default 'wp_rest'. + * @return int|bool 1 if the nonce is generated between 0-12 hours ago, + * 2 if the nonce is generated between 12-24 hours ago. + * False if the nonce is invalid. + */ +function wpcf7_verify_nonce( $nonce, $action = 'wp_rest' ) { + return wp_verify_nonce( $nonce, $action ); +} + + +/** + * Creates a cryptographic token tied to a specific action, user, user session, + * and window of time. + * + * @param string $action Optional. Context to what is taking place. + * Default 'wp_rest'. + * @return string The token. + */ +function wpcf7_create_nonce( $action = 'wp_rest' ) { + return wp_create_nonce( $action ); +} + + +/** + * Converts multi-dimensional array to a flat array. + * + * @param mixed $input Array or item of array. + * @return array Flatten array. + */ +function wpcf7_array_flatten( $input ) { + if ( ! is_array( $input ) ) { + return array( $input ); + } + + $output = array(); + + foreach ( $input as $value ) { + $output = array_merge( $output, wpcf7_array_flatten( $value ) ); + } + + return $output; +} + + +/** + * Excludes unset or blank text values from the given array. + * + * @param array $input The array. + * @return array Array without blank text values. + */ +function wpcf7_exclude_blank( $input ) { + $output = array_filter( $input, + static function ( $i ) { + return isset( $i ) && '' !== $i; + } + ); + + return array_values( $output ); +} + + +/** + * Creates a comma-separated list from a multi-dimensional array. + * + * @param mixed $input Array or item of array. + * @param string|array $options Optional. Output options. + * @return string Comma-separated list. + */ +function wpcf7_flat_join( $input, $options = '' ) { + $options = wp_parse_args( $options, array( + 'separator' => ', ', + ) ); + + $input = wpcf7_array_flatten( $input ); + $output = array(); + + foreach ( $input as $value ) { + if ( is_scalar( $value ) ) { + $output[] = trim( (string) $value ); + } + } + + return implode( $options['separator'], $output ); +} + + +/** + * Returns true if HTML5 is supported. + */ +function wpcf7_support_html5() { + return (bool) wpcf7_apply_filters_deprecated( + 'wpcf7_support_html5', + array( true ), + '5.6', + '' + ); +} + + +/** + * Returns true if HTML5 fallback is active. + */ +function wpcf7_support_html5_fallback() { + return (bool) apply_filters( 'wpcf7_support_html5_fallback', false ); +} + + +/** + * Returns true if the Really Simple CAPTCHA plugin is used for contact forms. + */ +function wpcf7_use_really_simple_captcha() { + return apply_filters( 'wpcf7_use_really_simple_captcha', + WPCF7_USE_REALLY_SIMPLE_CAPTCHA + ); +} + + +/** + * Returns true if config validation is active. + */ +function wpcf7_validate_configuration() { + return apply_filters( 'wpcf7_validate_configuration', + WPCF7_VALIDATE_CONFIGURATION + ); +} + + +/** + * Returns true if wpcf7_autop() is applied. + */ +function wpcf7_autop_or_not( $options = '' ) { + $options = wp_parse_args( $options, array( + 'for' => 'form', + ) ); + + return (bool) apply_filters( 'wpcf7_autop_or_not', WPCF7_AUTOP, $options ); +} + + +/** + * Returns true if JavaScript for this plugin is loaded. + */ +function wpcf7_load_js() { + return apply_filters( 'wpcf7_load_js', WPCF7_LOAD_JS ); +} + + +/** + * Returns true if CSS for this plugin is loaded. + */ +function wpcf7_load_css() { + return apply_filters( 'wpcf7_load_css', WPCF7_LOAD_CSS ); +} + + +/** + * Builds an HTML anchor element. + * + * @param string $url Link URL. + * @param string $anchor_text Anchor label text. + * @param string|array $atts Optional. HTML attributes. + * @return string Formatted anchor element. + */ +function wpcf7_link( $url, $anchor_text, $atts = '' ) { + $atts = wp_parse_args( $atts, array( + 'id' => null, + 'class' => null, + ) ); + + $atts = array_merge( $atts, array( + 'href' => esc_url( $url ), + ) ); + + return sprintf( + '%2$s', + wpcf7_format_atts( $atts ), + esc_html( $anchor_text ) + ); +} + + +/** + * Returns the current request URL. + */ +function wpcf7_get_request_uri() { + static $request_uri = ''; + + if ( empty( $request_uri ) ) { + $request_uri = add_query_arg( array() ); + $request_uri = '/' . ltrim( $request_uri, '/' ); + } + + return sanitize_url( $request_uri ); +} + + +/** + * Registers post types used for this plugin. + */ +function wpcf7_register_post_types() { + if ( class_exists( 'WPCF7_ContactForm' ) ) { + WPCF7_ContactForm::register_post_type(); + return true; + } else { + return false; + } +} + + +/** + * Returns the version string of this plugin. + * + * @param string|array $options Optional. Output options. + * @return string Version string. + */ +function wpcf7_version( $options = '' ) { + $options = wp_parse_args( $options, array( + 'limit' => -1, + 'only_major' => false, + ) ); + + if ( $options['only_major'] ) { + $options['limit'] = 2; + } + + $options['limit'] = (int) $options['limit']; + + $ver = WPCF7_VERSION; + $ver = strtr( $ver, '_-+', '...' ); + $ver = preg_replace( '/[^0-9.]+/', '.$0.', $ver ); + $ver = preg_replace( '/[.]+/', '.', $ver ); + $ver = trim( $ver, '.' ); + $ver = explode( '.', $ver ); + + if ( -1 < $options['limit'] ) { + $ver = array_slice( $ver, 0, $options['limit'] ); + } + + $ver = implode( '.', $ver ); + + return $ver; +} + + +/** + * Returns array entries that match the given version. + * + * @param string $version The version to search for. + * @param array $input Search target array. + * @return array|bool Array of matched entries. False on failure. + */ +function wpcf7_version_grep( $version, array $input ) { + $pattern = '/^' . preg_quote( (string) $version, '/' ) . '(?:\.|$)/'; + + return preg_grep( $pattern, $input ); +} + + +/** + * Returns an enctype attribute value. + * + * @param string $enctype Enctype value. + * @return string Enctype value. Empty if not a valid enctype. + */ +function wpcf7_enctype_value( $enctype ) { + $enctype = trim( $enctype ); + + if ( empty( $enctype ) ) { + return ''; + } + + $valid_enctypes = array( + 'application/x-www-form-urlencoded', + 'multipart/form-data', + 'text/plain', + ); + + if ( in_array( $enctype, $valid_enctypes, true ) ) { + return $enctype; + } + + $pattern = '%^enctype="(' . implode( '|', $valid_enctypes ) . ')"$%'; + + if ( preg_match( $pattern, $enctype, $matches ) ) { + return $matches[1]; // for back-compat + } + + return ''; +} + + +/** + * Removes directory recursively. + * + * @param string $dir Directory path. + * @return bool True on success, false on failure. + */ +function wpcf7_rmdir_p( $dir ) { + $filesystem = WPCF7_Filesystem::get_instance(); + + return $filesystem->delete( $dir, true ); +} + + +/** + * Builds a URL-encoded query string. + * + * @link https://developer.wordpress.org/reference/functions/_http_build_query/ + * + * @param array $data URL query parameters. + * @param string $key Optional. If specified, used to prefix key name. + * @return string Query string. + */ +function wpcf7_build_query( $data, $key = '' ) { + $sep = '&'; + $ret = array(); + + foreach ( (array) $data as $k => $v ) { + $k = urlencode( $k ); + + if ( ! empty( $key ) ) { + $k = $key . '%5B' . $k . '%5D'; + } + + if ( null === $v ) { + continue; + } elseif ( false === $v ) { + $v = '0'; + } + + if ( is_array( $v ) or is_object( $v ) ) { + array_push( $ret, wpcf7_build_query( $v, $k ) ); + } else { + array_push( $ret, $k . '=' . urlencode( $v ) ); + } + } + + return implode( $sep, $ret ); +} + + +/** + * Returns the number of code units in a string. + * + * @link http://www.w3.org/TR/html5/infrastructure.html#code-unit-length + * + * @param string $text Input string. + * @return int|false The number of code units, or false if + * mb_convert_encoding is not available. + */ +function wpcf7_count_code_units( $text ) { + static $use_mb = null; + + if ( is_null( $use_mb ) ) { + $use_mb = function_exists( 'mb_convert_encoding' ); + } + + if ( ! $use_mb ) { + return false; + } + + $text = (string) $text; + + if ( '' === $text ) { + return 0; + } + + $text = str_replace( "\r\n", "\n", $text ); + + $text = mb_convert_encoding( + $text, + 'UTF-16', + mb_detect_encoding( $text, mb_detect_order(), true ) ?: 'UTF-8' + ); + + return intdiv( mb_strlen( $text, '8bit' ), 2 ); +} + + +/** + * Returns true if WordPress is running on the localhost. + */ +function wpcf7_is_localhost() { + $sitename = wp_parse_url( network_home_url(), PHP_URL_HOST ); + + return in_array( + strtolower( $sitename ), + array( 'localhost', '127.0.0.1' ), + true + ); +} + + +/** + * Marks a function as deprecated and informs when it has been used. + * + * @param string $function_name The function that was called. + * @param string $version The version of Contact Form 7 that deprecated + * the function. + * @param string $replacement The function that should have been called. + */ +function wpcf7_deprecated_function( $function_name, $version, $replacement ) { + + if ( ! WP_DEBUG ) { + return; + } + + if ( function_exists( '__' ) ) { + /* translators: 1: PHP function name, 2: version number, 3: alternative function name */ + $message = __( 'Function %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' ); + } else { + $message = 'Function %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.'; + } + + $message = sprintf( $message, $function_name, $version, $replacement ); + + wp_trigger_error( '', $message, E_USER_DEPRECATED ); +} + + +/** + * Fires functions attached to a deprecated filter hook. + * + * @param string $hook_name The name of the filter hook. + * @param array $args Array of additional function arguments to be + * passed to apply_filters(). + * @param string $version The version of Contact Form 7 that deprecated + * the hook. + * @param string $replacement The hook that should have been used. + */ +function wpcf7_apply_filters_deprecated( $hook_name, $args, $version, $replacement = '' ) { + if ( ! has_filter( $hook_name ) ) { + return $args[0]; + } + + if ( WP_DEBUG and apply_filters( 'deprecated_hook_trigger_error', true ) ) { + if ( $replacement ) { + wp_trigger_error( + '', + sprintf( + /* translators: 1: WordPress hook name, 2: version number, 3: alternative hook name */ + __( 'Hook %1$s is deprecated since Contact Form 7 version %2$s! Use %3$s instead.', 'contact-form-7' ), + $hook_name, + $version, + $replacement + ), + E_USER_DEPRECATED + ); + } else { + wp_trigger_error( + '', + sprintf( + /* translators: 1: WordPress hook name, 2: version number */ + __( 'Hook %1$s is deprecated since Contact Form 7 version %2$s with no alternative available.', 'contact-form-7' ), + $hook_name, + $version + ), + E_USER_DEPRECATED + ); + } + } + + return apply_filters_ref_array( $hook_name, $args ); +} + + +/** + * Marks something as being incorrectly called. + * + * @param string $function_name The function that was called. + * @param string $message A message explaining what has been done incorrectly. + * @param string $version The version of Contact Form 7 where the message + * was added. + */ +function wpcf7_doing_it_wrong( $function_name, $message, $version ) { + + if ( ! WP_DEBUG ) { + return; + } + + if ( function_exists( '__' ) ) { + if ( $version ) { + $version = sprintf( + /* translators: %s: Contact Form 7 version number. */ + __( '(This message was added in Contact Form 7 version %s.)', 'contact-form-7' ), + $version + ); + } + + wp_trigger_error( + '', + sprintf( + /* translators: Developer debugging message. 1: PHP function name, 2: Explanatory message, 3: Contact Form 7 version number. */ + __( 'Function %1$s was called incorrectly. %2$s %3$s', 'contact-form-7' ), + $function_name, + $message, + $version + ), + E_USER_NOTICE + ); + } else { + if ( $version ) { + $version = sprintf( + '(This message was added in Contact Form 7 version %s.)', + $version + ); + } + + wp_trigger_error( + '', + sprintf( + 'Function %1$s was called incorrectly. %2$s %3$s', + $function_name, + $message, + $version + ), + E_USER_NOTICE + ); + } +} + + +/** + * Triggers an error about a remote HTTP request and response. + * + * @param string $url The resource URL. + * @param array $request Request arguments. + * @param array|WP_Error $response The response or WP_Error on failure. + */ +function wpcf7_log_remote_request( $url, $request, $response ) { + + if ( ! WP_DEBUG ) { + return; + } + + $log = sprintf( + /* translators: 1: response code, 2: message, 3: body, 4: URL */ + __( 'HTTP Response: %1$s %2$s %3$s from %4$s', 'contact-form-7' ), + (int) wp_remote_retrieve_response_code( $response ), + wp_remote_retrieve_response_message( $response ), + wp_remote_retrieve_body( $response ), + $url + ); + + $log = apply_filters( 'wpcf7_log_remote_request', + $log, $url, $request, $response + ); + + if ( $log ) { + wp_trigger_error( '', $log, E_USER_NOTICE ); + } +} + + +/** + * Anonymizes an IP address by masking local part. + * + * @param string $ip_addr The original IP address. + * @return string|bool Anonymized IP address, or false on failure. + */ +function wpcf7_anonymize_ip_addr( $ip_addr ) { + if ( + ! function_exists( 'inet_ntop' ) or + ! function_exists( 'inet_pton' ) + ) { + return $ip_addr; + } + + $packed = inet_pton( $ip_addr ); + + if ( false === $packed ) { + return $ip_addr; + } + + if ( 4 === strlen( $packed ) ) { // IPv4 + $mask = '255.255.255.0'; + } elseif ( 16 === strlen( $packed ) ) { // IPv6 + $mask = 'ffff:ffff:ffff:0000:0000:0000:0000:0000'; + } else { + return $ip_addr; + } + + return inet_ntop( $packed & inet_pton( $mask ) ); +} + + +/** + * Retrieves a sanitized value from the $_GET superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_get( $key, $default = '' ) { + return wpcf7_superglobal( 'get', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the $_POST superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_post( $key, $default = '' ) { + return wpcf7_superglobal( 'post', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the $_REQUEST superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_request( $key, $default = '' ) { + return wpcf7_superglobal( 'request', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the $_SERVER superglobal. + * + * @param string $key Array key. + * @param mixed $default The default value returned when + * the specified superglobal is not set. + * @return mixed Sanitized value. + */ +function wpcf7_superglobal_server( $key, $default = '' ) { + return wpcf7_superglobal( 'server', $key ) ?? $default; +} + + +/** + * Retrieves a sanitized value from the specified superglobal. + * + * @param string $superglobal A superglobal type. + * @param string $key Array key. + * @return string|array|null Sanitized value. + */ +function wpcf7_superglobal( $superglobal, $key ) { + $superglobals = array( + 'get' => $_GET, + 'post' => $_POST, + 'request' => $_REQUEST, + 'server' => $_SERVER, + ); + + if ( isset( $superglobals[$superglobal][$key] ) ) { + return map_deep( + $superglobals[$superglobal][$key], + static function ( $val ) { + $val = wp_unslash( $val ); + $val = wp_check_invalid_utf8( $val ); + $val = wp_kses_no_null( $val ); + $val = wpcf7_strip_whitespaces( $val ); + return $val; + } + ); + } +} diff --git a/html/wp-content/plugins/contact-form-7/includes/html-formatter.php b/html/wp-content/plugins/contact-form-7/includes/html-formatter.php new file mode 100644 index 0000000..5f08d8d --- /dev/null +++ b/html/wp-content/plugins/contact-form-7/includes/html-formatter.php @@ -0,0 +1,868 @@ +options = wp_parse_args( $options, array( + 'auto_br' => true, + 'auto_indent' => true, + 'allowed_html' => wpcf7_kses_allowed_html(), + ) ); + } + + + /** + * Separates the given text into chunks of HTML. Each chunk must be an + * associative array that includes 'position', 'type', and 'content' keys. + * + * @param string $input Text to be separated into chunks. + * @return iterable Iterable of chunks. + */ + public function separate_into_chunks( $input ) { + $input_bytelength = strlen( $input ); + $position = 0; + + while ( $position < $input_bytelength ) { + $next_tag = preg_match( + '/(?:|<(?:\/?)[a-z].*?>)/is', + $input, + $matches, + PREG_OFFSET_CAPTURE, + $position + ); + + if ( ! $next_tag ) { + yield array( + 'position' => $position, + 'type' => self::text, + 'content' => substr( $input, $position ), + ); + + break; + } + + $next_tag = $matches[0][0]; + $next_tag_position = $matches[0][1]; + + if ( $position < $next_tag_position ) { + yield array( + 'position' => $position, + 'type' => self::text, + 'content' => substr( + $input, + $position, + $next_tag_position - $position + ), + ); + } + + if ( ' $next_tag_position, + 'type' => $next_tag_type, + 'content' => substr( + $input, + $next_tag_position, + strlen( $next_tag ) + ), + ); + + $position = $next_tag_position + strlen( $next_tag ); + } + } + + + /** + * Normalizes content in each chunk. This may change the type and position + * of the chunk. + * + * @param iterable $chunks The original chunks. + * @return iterable Normalized chunks. + */ + public function pre_format( $chunks ) { + $position = 0; + + foreach ( $chunks as $chunk ) { + $chunk['position'] = $position; + + // Standardize newline characters to "\n". + $chunk['content'] = str_replace( + array( "\r\n", "\r" ), "\n", $chunk['content'] + ); + + if ( self::start_tag === $chunk['type'] ) { + list( $chunk['content'] ) = + self::normalize_start_tag( $chunk['content'] ); + + // Replace
    by a line break. + if ( + $this->options['auto_br'] and + preg_match( '/^$/i', $chunk['content'] ) + ) { + $chunk['type'] = self::text; + $chunk['content'] = "\n"; + } + } + + yield $chunk; + $position = self::calc_next_position( $chunk ); + } + } + + + /** + * Concatenates neighboring text chunks to create a single chunk. + * + * @param iterable $chunks The original chunks. + * @return iterable Processed chunks. + */ + public function concatenate_texts( $chunks ) { + $position = 0; + $text_left = null; + + foreach ( $chunks as $chunk ) { + $chunk['position'] = $position; + + if ( self::text === $chunk['type'] ) { + if ( isset( $text_left ) ) { + $text_left['content'] .= $chunk['content']; + } else { + $text_left = $chunk; + } + + continue; + } + + if ( isset( $text_left ) ) { + yield $text_left; + $chunk['position'] = self::calc_next_position( $text_left ); + $text_left = null; + } + + yield $chunk; + $position = self::calc_next_position( $chunk ); + } + + if ( isset( $text_left ) ) { + yield $text_left; + } + } + + + /** + * Outputs formatted HTML based on the given chunks. + * + * @param iterable $chunks The original chunks. + * @return string Formatted HTML. + */ + public function format( $chunks ) { + $chunks = $this->pre_format( $chunks ); + $chunks = $this->concatenate_texts( $chunks ); + + $this->output = ''; + $this->stacked_elements = array(); + + foreach ( $chunks as $chunk ) { + + if ( self::text === $chunk['type'] ) { + $this->append_text( $chunk['content'] ); + } + + if ( self::start_tag === $chunk['type'] ) { + $this->start_tag( $chunk['content'] ); + } + + if ( self::end_tag === $chunk['type'] ) { + $this->end_tag( $chunk['content'] ); + } + + if ( self::comment === $chunk['type'] ) { + $this->append_comment( $chunk['content'] ); + } + } + + return $this->output(); + } + + + /** + * Appends preformatted text to the output property. + */ + public function append_preformatted( $content ) { + $this->output .= $content; + } + + + /** + * Appends whitespace to the output property. + */ + public function append_whitespace() { + $this->append_preformatted( ' ' ); + } + + + /** + * Appends a text node content to the output property. + * + * @param string $content Text node content. + */ + public function append_text( $content ) { + if ( $this->is_inside( array( 'pre', 'template' ) ) ) { + $this->append_preformatted( $content ); + return; + } + + if ( + empty( $this->stacked_elements ) or + $this->has_parent( 'p' ) or + $this->has_parent( self::p_parent_elements ) + ) { + // Close

    if the content starts with multiple line breaks. + if ( preg_match( '/^\s*\n\s*\n\s*/', $content ) ) { + $this->end_tag( 'p' ); + } + + // Split up the contents into paragraphs, separated by double line breaks. + $paragraphs = preg_split( '/\s*\n\s*\n\s*/', $content ); + + $paragraphs = array_filter( $paragraphs, static function ( $paragraph ) { + return '' !== wpcf7_strip_whitespaces( $paragraph ); + } ); + + $paragraphs = array_values( $paragraphs ); + + if ( $paragraphs ) { + if ( $this->is_inside( 'p' ) ) { + $paragraph = array_shift( $paragraphs ); + + $paragraph = self::normalize_paragraph( + $paragraph, + $this->options['auto_br'] + ); + + $this->append_preformatted( $paragraph ); + } + + foreach ( $paragraphs as $paragraph ) { + $this->start_tag( 'p' ); + + $paragraph = wpcf7_strip_whitespaces( $paragraph, 'start' ); + + $paragraph = self::normalize_paragraph( + $paragraph, + $this->options['auto_br'] + ); + + $this->append_preformatted( $paragraph ); + } + } + + // Close

    if the content ends with multiple line breaks. + if ( preg_match( '/\s*\n\s*\n\s*$/', $content ) ) { + $this->end_tag( 'p' ); + } + + // Cases where the content is a single line break. + if ( preg_match( '/^\s*\n\s*$/', $content ) ) { + $auto_br = $this->options['auto_br'] && $this->is_inside( 'p' ); + + $content = self::normalize_paragraph( $content, $auto_br ); + + $this->append_preformatted( $content ); + } + } else { + $auto_br = $this->options['auto_br'] && + $this->has_parent( self::br_parent_elements ); + + $content = self::normalize_paragraph( $content, $auto_br ); + + $this->append_preformatted( $content ); + } + } + + + /** + * Appends a start tag to the output property. + * + * @param string $tag A start tag. + */ + public function start_tag( $tag ) { + list( $tag, $tag_name ) = self::normalize_start_tag( $tag ); + + if ( + in_array( $tag_name, self::p_child_elements, true ) and + ! $this->is_inside( 'p' ) and + ! $this->is_inside( self::p_child_elements ) and + ! $this->has_parent( self::p_nonparent_elements ) + ) { + // Open

    if it does not exist. + $this->start_tag( 'p' ); + } + + $this->append_start_tag( $tag_name, array(), $tag ); + } + + + /** + * Appends a start tag to the output property. + * + * @param string $tag_name Tag name. + * @param array $atts Associative array of attribute name and value pairs. + * @param string $tag A start tag. + */ + public function append_start_tag( $tag_name, $atts = array(), $tag = '' ) { + if ( ! self::validate_tag_name( $tag_name ) ) { + wp_trigger_error( + __METHOD__, + sprintf( + /* translators: %s: Invalid HTML tag name */ + __( 'Invalid tag name (%s) is specified.', 'contact-form-7' ), + $tag_name + ), + E_USER_WARNING + ); + + return false; + } + + if ( WP_DEBUG and ! empty( $this->options['allowed_html'] ) ) { + $html_disallowance = array(); + + if ( ! isset( $this->options['allowed_html'][$tag_name] ) ) { + $html_disallowance = array( + 'element' => $tag_name, + ); + } else { + $atts_allowed = $this->options['allowed_html'][$tag_name]; + + $atts_disallowed = array_diff_ukey( $atts, $atts_allowed, + static function ( $key_1, $key_2 ) use ( $atts_allowed ) { + if ( + str_starts_with( $key_1, 'data-' ) and + ! empty( $atts_allowed['data-*'] ) and + preg_match( '/^data-[a-z0-9_-]+$/', $key_1 ) + ) { + return 0; + } else { + return $key_1 === $key_2 ? 0 : 1; + } + } + ); + + if ( ! empty( $atts_disallowed ) ) { + $html_disallowance = array( + 'element' => $tag_name, + 'attributes' => array_keys( $atts_disallowed ), + ); + } + } + + if ( $html_disallowance ) { + $notice = sprintf( + /* translators: %s: JSON-formatted array of disallowed HTML */ + __( 'HTML Disallowance: %s', 'contact-form-7' ), + wp_json_encode( $html_disallowance, JSON_PRETTY_PRINT ) + ); + + wp_trigger_error( __METHOD__, $notice, E_USER_NOTICE ); + } + } + + if ( + 'p' === $tag_name or + in_array( $tag_name, self::p_parent_elements, true ) or + in_array( $tag_name, self::p_nonparent_elements, true ) + ) { + // Close

    if it exists. + $this->end_tag( 'p' ); + } + + if ( 'dd' === $tag_name or 'dt' === $tag_name ) { + // Close

    and
    if closing tag is omitted. + $this->end_tag( 'dd' ); + $this->end_tag( 'dt' ); + } + + if ( 'li' === $tag_name ) { + // Close
  • if closing tag is omitted. + $this->end_tag( 'li' ); + } + + if ( 'optgroup' === $tag_name ) { + // Close if closing tag is omitted. + $this->end_tag( 'option' ); + $this->end_tag( 'optgroup' ); + } + + if ( 'option' === $tag_name ) { + // Close
  • "},l=function(){};l.prototype={asyncSupport:!0,actualizeOptions:function(){return a.attr(this.$element,this.options.namespace,this.domOptions),this.parent&&this.parent.actualizeOptions&&this.parent.actualizeOptions(),this},_resetOptions:function(e){this.domOptions=a.objectCreate(this.parent.options),this.options=a.objectCreate(this.domOptions);for(var t in e)e.hasOwnProperty(t)&&(this.options[t]=e[t]);this.actualizeOptions()},_listeners:null,on:function(e,t){this._listeners=this._listeners||{};var i=this._listeners[e]=this._listeners[e]||[];return i.push(t),this},subscribe:function(t,i){e.listenTo(this,t.toLowerCase(),i)},off:function(e,t){var i=this._listeners&&this._listeners[e];if(i)if(t)for(var n=i.length;n--;)i[n]===t&&i.splice(n,1);else delete this._listeners[e];return this},unsubscribe:function(t,i){e.unsubscribeTo(this,t.toLowerCase())},trigger:function(e,t,i){t=t||this;var n,r=this._listeners&&this._listeners[e];if(r)for(var s=r.length;s--;)if(n=r[s].call(t,t,i),n===!1)return n;return this.parent?this.parent.trigger(e,t,i):!0},reset:function(){if("ParsleyForm"!==this.__class__)return this._resetUI(),this._trigger("reset");for(var e=0;e3&&(i=[].slice.call(arguments,1,-1)),this.fn.call(this,t,i);if(e.isArray(t)){if(!this.validateMultiple)throw"Validator `"+this.name+"` does not handle multiple values";return this.validateMultiple.apply(this,arguments)}if(this.validateNumber)return isNaN(t)?!1:(arguments[0]=parseFloat(arguments[0]),this.validateNumber.apply(this,arguments));if(this.validateString)return this.validateString.apply(this,arguments);throw"Validator `"+this.name+"` only handles multiple values"},parseRequirements:function(t,i){if("string"!=typeof t)return e.isArray(t)?t:[t];var n=this.requirementType;if(e.isArray(n)){for(var r=d(t,n.length),s=0;s0},validateString:function(e){return/\S/.test(e)},priority:512},type:{validateString:function(e,t){var i=arguments.length<=2||void 0===arguments[2]?{}:arguments[2],n=i.step,r=void 0===n?"1":n,s=i.base,a=void 0===s?0:s,o=m[t];if(!o)throw new Error("validator type `"+t+"` is not supported");if(!o.test(e))return!1;if("number"===t&&!/^any$/i.test(r||"")){var l=Number(e),u=Math.max(g(r),g(a));if(g(l)>u)return!1;var d=function(e){return Math.round(e*Math.pow(10,u))};if((d(l)-d(a))%d(r)!=0)return!1}return!0},requirementType:{"":"string",step:"string",base:"number"},priority:256},pattern:{validateString:function(e,t){return t.test(e)},requirementType:"regexp",priority:64},minlength:{validateString:function(e,t){return e.length>=t},requirementType:"integer",priority:30},maxlength:{validateString:function(e,t){return e.length<=t},requirementType:"integer",priority:30},length:{validateString:function(e,t,i){return e.length>=t&&e.length<=i},requirementType:["integer","integer"],priority:30},mincheck:{validateMultiple:function(e,t){return e.length>=t},requirementType:"integer",priority:30},maxcheck:{validateMultiple:function(e,t){return e.length<=t},requirementType:"integer",priority:30},check:{validateMultiple:function(e,t,i){return e.length>=t&&e.length<=i},requirementType:["integer","integer"],priority:30},min:{validateNumber:function(e,t){return e>=t},requirementType:"number",priority:30},max:{validateNumber:function(e,t){return t>=e},requirementType:"number",priority:30},range:{validateNumber:function(e,t,i){return e>=t&&i>=e},requirementType:["number","number"],priority:30},equalto:{validateString:function(t,i){var n=e(i);return n.length?t===n.val():t===i},priority:256}}};var y={},v=function T(e,t,i){for(var n=[],r=[],s=0;s0&&"undefined"==typeof t.options.noFocus&&(this._focusedField=t.$element,"first"===this.options.focus))break}return null===this._focusedField?null:this._focusedField.focus()},_destroyUI:function(){this.$element.off(".Parsley")}},y.Field={_reflowUI:function(){if(this._buildUI(),this._ui){var e=v(this.validationResult,this._ui.lastValidationResult);this._ui.lastValidationResult=this.validationResult,this._manageStatusClass(),this._manageErrorsMessages(e),this._actualizeTriggers(),!e.kept.length&&!e.added.length||this._failedOnce||(this._failedOnce=!0,this._actualizeTriggers())}},getErrorsMessages:function(){if(!0===this.validationResult)return[];for(var e=[],t=0;t0?this._errorClass():this._resetClass()},_manageErrorsMessages:function(t){if("undefined"==typeof this.options.errorsMessagesDisabled){if("undefined"!=typeof this.options.errorMessage)return t.added.length||t.kept.length?(this._insertErrorWrapper(),0===this._ui.$errorsWrapper.find(".parsley-custom-error-message").length&&this._ui.$errorsWrapper.append(e(this.options.errorTemplate).addClass("parsley-custom-error-message")),this._ui.$errorsWrapper.addClass("filled").find(".parsley-custom-error-message").html(this.options.errorMessage)):this._ui.$errorsWrapper.removeClass("filled").find(".parsley-custom-error-message").remove();for(var i=0;i').appendTo(this.$element)),i.attr({name:t.attr("name"),value:t.attr("value")})}this.$element.trigger(e.extend(e.Event("submit"),{parsley:!0}))}},validate:function(t){if(arguments.length>=1&&!e.isPlainObject(t)){a.warnOnce("Calling validate on a parsley form without passing arguments as an object is deprecated.");var i=_slice.call(arguments),n=i[0],r=i[1],s=i[2];t={group:n,force:r,event:s}}return w[this.whenValidate(t).state()]},whenValidate:function(){var t=this,i=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=i.group,r=i.force,s=i.event;this.submitEvent=s,s&&(this.submitEvent=e.extend({},s,{preventDefault:function(){a.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`"),t.validationResult=!1}})),this.validationResult=!0,this._trigger("validate"),this._refreshFields();var o=this._withoutReactualizingFormOptions(function(){return e.map(t.fields,function(e){return e.whenValidate({force:r,group:n})})}),l=function(){var i=e.Deferred();return!1===t.validationResult&&i.reject(),i.resolve().promise()};return e.when.apply(e,_toConsumableArray(o)).done(function(){t._trigger("success")}).fail(function(){t.validationResult=!1,t.focus(),t._trigger("error")}).always(function(){t._trigger("validated")}).pipe(l,l)},isValid:function(t){if(arguments.length>=1&&!e.isPlainObject(t)){a.warnOnce("Calling isValid on a parsley form without passing arguments as an object is deprecated.");var i=_slice.call(arguments),n=i[0],r=i[1];t={group:n,force:r}}return w[this.whenValid(t).state()]},whenValid:function(){var t=this,i=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=i.group,r=i.force;this._refreshFields();var s=this._withoutReactualizingFormOptions(function(){return e.map(t.fields,function(e){return e.whenValid({group:n,force:r})})});return e.when.apply(e,_toConsumableArray(s))},_refreshFields:function(){return this.actualizeOptions()._bindFields()},_bindFields:function(){var t=this,i=this.fields;return this.fields=[],this.fieldsMappedById={},this._withoutReactualizingFormOptions(function(){t.$element.find(t.options.inputs).not(t.options.excluded).each(function(e,i){var n=new window.Parsley.Factory(i,{},t);"ParsleyField"!==n.__class__&&"ParsleyFieldMultiple"!==n.__class__||!0===n.options.excluded||"undefined"==typeof t.fieldsMappedById[n.__class__+"-"+n.__id__]&&(t.fieldsMappedById[n.__class__+"-"+n.__id__]=n,t.fields.push(n))}),e(i).not(t.fields).each(function(e,t){t._trigger("reset")})}),this},_withoutReactualizingFormOptions:function(e){var t=this.actualizeOptions;this.actualizeOptions=function(){return this};var i=e();return this.actualizeOptions=t,i},_trigger:function(e){return this.trigger("form:"+e)}};var b=function(t,i,n,r,s){if(!/ParsleyField/.test(t.__class__))throw new Error("ParsleyField or ParsleyFieldMultiple instance expected");var a=window.Parsley._validatorRegistry.validators[i],o=new f(a);e.extend(this,{validator:o,name:i,requirements:n,priority:r||t.options[i+"Priority"]||o.priority,isDomConstraint:!0===s}),this._parseRequirements(t.options)},F=function(e){var t=e[0].toUpperCase();return t+e.slice(1)};b.prototype={validate:function(e,t){var i=this.requirementList.slice(0);return i.unshift(e),i.push(t),this.validator.validate.apply(this.validator,i)},_parseRequirements:function(e){var t=this;this.requirementList=this.validator.parseRequirements(this.requirements,function(i){return e[t.name+F(i)]})}};var C=function(t,i,n,r){this.__class__="ParsleyField",this.__id__=a.generateID(),this.$element=e(t),"undefined"!=typeof r&&(this.parent=r),this.options=n,this.domOptions=i,this.constraints=[],this.constraintsByName={},this.validationResult=[],this._bindConstraints()},$={pending:null,resolved:!0,rejected:!1};C.prototype={validate:function(t){arguments.length>=1&&!e.isPlainObject(t)&&(a.warnOnce("Calling validate on a parsley field without passing arguments as an object is deprecated."),t={options:t});var i=this.whenValidate(t);if(!i)return!0;switch(i.state()){case"pending":return null;case"resolved":return!0;case"rejected":return this.validationResult}},whenValidate:function(){var e=this,t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],i=t.force,n=t.group;return this.refreshConstraints(),!n||this._isInGroup(n)?(this.value=this.getValue(),this._trigger("validate"),this.whenValid({force:i,value:this.value,_refreshed:!0}).always(function(){e._reflowUI()}).done(function(){e._trigger("success")}).fail(function(){e._trigger("error")}).always(function(){e._trigger("validated")})):void 0},hasConstraints:function(){return 0!==this.constraints.length},needsValidation:function(e){return"undefined"==typeof e&&(e=this.getValue()),e.length||this._isRequired()||"undefined"!=typeof this.options.validateIfEmpty?!0:!1},_isInGroup:function(t){return e.isArray(this.options.group)?-1!==e.inArray(t,this.options.group):this.options.group===t},isValid:function(t){if(arguments.length>=1&&!e.isPlainObject(t)){a.warnOnce("Calling isValid on a parsley field without passing arguments as an object is deprecated.");var i=_slice.call(arguments),n=i[0],r=i[1];t={force:n,value:r}}var s=this.whenValid(t);return s?$[s.state()]:!0},whenValid:function(){var t=this,i=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=i.force,r=void 0===n?!1:n,s=i.value,a=i.group,o=i._refreshed;if(o||this.refreshConstraints(),!a||this._isInGroup(a)){if(this.validationResult=!0,!this.hasConstraints())return e.when();if(("undefined"==typeof s||null===s)&&(s=this.getValue()),!this.needsValidation(s)&&!0!==r)return e.when();var l=this._getGroupedConstraints(),u=[];return e.each(l,function(i,n){var r=e.when.apply(e,_toConsumableArray(e.map(n,function(e){return t._validateConstraint(s,e)})));return u.push(r),"rejected"===r.state()?!1:void 0}),e.when.apply(e,u)}},_validateConstraint:function(t,i){var n=this,r=i.validate(t,this);return!1===r&&(r=e.Deferred().reject()),e.when(r).fail(function(e){!0===n.validationResult&&(n.validationResult=[]),n.validationResult.push({assert:i,errorMessage:"string"==typeof e&&e})})},getValue:function(){var e;return e="function"==typeof this.options.value?this.options.value(this):"undefined"!=typeof this.options.value?this.options.value:this.$element.val(),"undefined"==typeof e||null===e?"":this._handleWhitespace(e)},refreshConstraints:function(){return this.actualizeOptions()._bindConstraints()},addConstraint:function(e,t,i,n){if(window.Parsley._validatorRegistry.validators[e]){var r=new b(this,e,t,i,n);"undefined"!==this.constraintsByName[r.name]&&this.removeConstraint(r.name),this.constraints.push(r),this.constraintsByName[r.name]=r}return this},removeConstraint:function(e){for(var t=0;t1){var i=[];return this.each(function(){i.push(e(this).parsley(t))}),i}return e(this).length?new E(this,t):void a.warn("You must bind Parsley on an existing element.")},"undefined"==typeof window.ParsleyExtend&&(window.ParsleyExtend={}),M.options=e.extend(a.objectCreate(o),window.ParsleyConfig),window.ParsleyConfig=M.options,window.Parsley=window.psly=M,window.ParsleyUtils=a;var O=window.Parsley._validatorRegistry=new c(window.ParsleyConfig.validators,window.ParsleyConfig.i18n);window.ParsleyValidator={},e.each("setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator".split(" "),function(t,i){window.Parsley[i]=e.proxy(O,i),window.ParsleyValidator[i]=function(){var e;return a.warnOnce("Accessing the method '"+i+"' through ParsleyValidator is deprecated. Simply call 'window.Parsley."+i+"(...)'"),(e=window.Parsley)[i].apply(e,arguments)}}),window.Parsley.UI=y,window.ParsleyUI={removeError:function(e,t,i){var n=!0!==i;return a.warnOnce("Accessing ParsleyUI is deprecated. Call 'removeError' on the instance directly. Please comment in issue 1073 as to your need to call this method."),e.removeError(t,{updateClass:n})},getErrorsMessages:function(e){return a.warnOnce("Accessing ParsleyUI is deprecated. Call 'getErrorsMessages' on the instance directly."),e.getErrorsMessages()}},e.each("addError updateError".split(" "),function(e,t){window.ParsleyUI[t]=function(e,i,n,r,s){var o=!0!==s;return a.warnOnce("Accessing ParsleyUI is deprecated. Call '"+t+"' on the instance directly. Please comment in issue 1073 as to your need to call this method."),e[t](i,{message:n,assert:r,updateClass:o})}}),/firefox/i.test(navigator.userAgent)&&e(document).on("change","select",function(t){e(t.target).trigger("input")}),!1!==window.ParsleyConfig.autoBind&&e(function(){e("[data-parsley-validate]").length&&e("[data-parsley-validate]").parsley()});var A=e({}),R=function(){a.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley")},D="parsley:";e.listen=function(e,n){var r;if(R(),"object"==typeof arguments[1]&&"function"==typeof arguments[2]&&(r=arguments[1],n=arguments[2]),"function"!=typeof n)throw new Error("Wrong parameters");window.Parsley.on(i(e),t(n,r))},e.listenTo=function(e,n,r){if(R(),!(e instanceof x||e instanceof _))throw new Error("Must give Parsley instance");if("string"!=typeof n||"function"!=typeof r)throw new Error("Wrong parameters");e.on(i(n),t(r))},e.unsubscribe=function(e,t){if(R(),"string"!=typeof e||"function"!=typeof t)throw new Error("Wrong arguments");window.Parsley.off(i(e),t.parsleyAdaptedCallback)},e.unsubscribeTo=function(e,t){if(R(),!(e instanceof x||e instanceof _))throw new Error("Must give Parsley instance");e.off(i(t))},e.unsubscribeAll=function(t){R(),window.Parsley.off(i(t)),e("form,input,textarea,select").each(function(){var n=e(this).data("Parsley");n&&n.off(i(t))})},e.emit=function(e,t){var n;R();var r=t instanceof x||t instanceof _,s=Array.prototype.slice.call(arguments,r?2:1);s.unshift(i(e)),r||(t=window.Parsley),(n=t).trigger.apply(n,_toConsumableArray(s))};e.extend(!0,M,{asyncValidators:{"default":{fn:function(e){return e.status>=200&&e.status<300},url:!1},reverse:{fn:function(e){return e.status<200||e.status>=300},url:!1}},addAsyncValidator:function(e,t,i,n){return M.asyncValidators[e]={fn:t,url:i||!1,options:n||{}},this}}),M.addValidator("remote",{requirementType:{"":"string",validator:"string",reverse:"boolean",options:"object"},validateString:function(t,i,n,r){var s,a,o={},l=n.validator||(!0===n.reverse?"reverse":"default");if("undefined"==typeof M.asyncValidators[l])throw new Error("Calling an undefined async validator: `"+l+"`");i=M.asyncValidators[l].url||i,i.indexOf("{value}")>-1?i=i.replace("{value}",encodeURIComponent(t)):o[r.$element.attr("name")||r.$element.attr("id")]=t;var u=e.extend(!0,n.options||{},M.asyncValidators[l].options);s=e.extend(!0,{},{url:i,data:o,type:"GET"},u),r.trigger("field:ajaxoptions",r,s),a=e.param(s),"undefined"==typeof M._remoteCache&&(M._remoteCache={});var d=M._remoteCache[a]=M._remoteCache[a]||e.ajax(s),h=function(){var t=M.asyncValidators[l].fn.call(r,d,i,n);return t||(t=e.Deferred().reject()),e.when(t)};return d.then(h,h)},priority:-1}),M.on("form:submit",function(){M._remoteCache={}}),window.ParsleyExtend.addAsyncValidator=function(){return ParsleyUtils.warnOnce("Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`"),M.addAsyncValidator.apply(M,arguments)},M.addMessages("en",{defaultMessage:"This value seems to be invalid.",type:{email:"This value should be a valid email.",url:"This value should be a valid url.",number:"This value should be a valid number.",integer:"This value should be a valid integer.",digits:"This value should be digits.",alphanum:"This value should be alphanumeric."},notblank:"This value should not be blank.",required:"This value is required.",pattern:"This value seems to be invalid.",min:"This value should be greater than or equal to %s.",max:"This value should be lower than or equal to %s.",range:"This value should be between %s and %s.",minlength:"This value is too short. It should have %s characters or more.",maxlength:"This value is too long. It should have %s characters or fewer.",length:"This value length is invalid. It should be between %s and %s characters long.",mincheck:"You must select at least %s choices.",maxcheck:"You must select %s choices or fewer.",check:"You must select between %s and %s choices.",equalto:"This value should be the same."}),M.setLocale("en");var q=M;return q}); +//# sourceMappingURL=parsley.min.js.map \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/assets/js/parsley.min.js.map b/html/wp-content/plugins/duplicator/assets/js/parsley.min.js.map new file mode 100644 index 0000000..28ff9cb --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/js/parsley.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["parsley.min.js","/source/parsley.js","/source/src/parsley/pubsub.js","/source/src/parsley/utils.js","/source/src/parsley/defaults.js","/source/src/parsley/abstract.js","/source/src/parsley/validator.js","/source/src/parsley/validator_registry.js","/source/src/parsley/ui.js","/source/src/parsley/form.js","/source/src/parsley/factory/constraint.js","/source/src/parsley/field.js","/source/src/parsley/multiple.js","/source/src/parsley/factory.js","/source/src/parsley/main.js","/source/src/parsley/remote.js","/source/src/i18n/en.js","/source/src/parsley.js"],"names":["_toConsumableArray","arr","Array","isArray","i","arr2","length","from","_slice","prototype","slice","global","factory","exports","module","require","define","amd","parsley","jQuery","this","$","adapt","fn","context","parsleyAdaptedCallback","args","call","arguments","unshift","apply","o","eventName","name","lastIndexOf","eventPrefix","substr","globalID","pastWarnings","ParsleyUtils__ParsleyUtils","attr","$element","namespace","obj","attribute","attributes","regex","RegExp","hasOwnProperty","specified","test","camelize","deserializeValue","value","checkAttr","_checkAttr","is","setAttr","setAttribute","dasherize","String","generateID","num","isNaN","Number","parseJSON","e","str","replace","match","chr","toUpperCase","toLowerCase","warn","_window$console","window","console","warnOnce","msg","_resetWarnings","trimString","string","namespaceEvents","events","split","map","evt","join","objectCreate","Object","create","Error","TypeError","result","ParsleyUtils__default","ParsleyDefaults","inputs","excluded","priorityEnabled","multiple","group","uiEnabled","validationThreshold","focus","trigger","triggerAfterFailure","errorClass","successClass","classHandler","ParsleyField","errorsContainer","errorsWrapper","errorTemplate","ParsleyAbstract","asyncSupport","actualizeOptions","options","domOptions","parent","_resetOptions","initOptions","_listeners","on","queue","push","subscribe","listenTo","off","splice","unsubscribe","unsubscribeTo","target","extraArg","reset","__class__","_resetUI","_trigger","fields","destroy","_destroyUI","removeData","asyncIsValid","force","whenValid","_findRelated","find","requirementConverters","_string","integer","parseInt","number","parseFloat","reference","boolean","object","regexp","_regexp","flags","convertArrayRequirement","m","values","convertRequirement","requirementType","converter","convertExtraOptionRequirement","requirementSpec","extraOptionReader","main","extra","key","ParsleyValidator","spec","extend","validate","requirementFirstArg","validateMultiple","validateNumber","validateString","parseRequirements","requirements","type","isPlainObject","priority","ParsleyValidatorRegistry","validators","catalog","locale","init","typeRegexes","email","digits","alphanum","url","range","decimalPlaces","Math","max","addValidator","Parsley","setLocale","addCatalog","messages","set","addMessage","message","addMessages","nameMessageObject","arg1","arg2","_setValidator","updateValidator","removeValidator","validator","getErrorMessage","constraint","typeMessages","formatMessage","defaultMessage","en","parameters","notblank","required","_ref","undefined","_ref$step","step","_ref$base","base","nb","decimals","toInt","f","round","pow","pattern","minlength","requirement","maxlength","min","mincheck","maxcheck","check","equalto","refOrValue","$reference","val","ParsleyUI","diffResults","newResult","oldResult","deep","added","kept","found","j","assert","removed","Form","_actualizeTriggers","_this","onSubmitValidate","onSubmitButton","_focusedField","validationResult","field","noFocus","Field","_reflowUI","_buildUI","_ui","diff","lastValidationResult","_manageStatusClass","_manageErrorsMessages","_failedOnce","getErrorsMessages","errorMessage","_getErrorMessage","addError","_ref2","_ref2$updateClass","updateClass","_addError","_errorClass","updateError","_ref3","_ref3$updateClass","_updateError","removeError","_ref4","_ref4$updateClass","_removeError","hasConstraints","needsValidation","_successClass","_resetClass","errorsMessagesDisabled","_insertErrorWrapper","$errorsWrapper","append","addClass","html","removeClass","remove","_ref5","_ref6","customConstraintErrorMessage","__id__","$errorClassHandler","_manageClassHandler","errorsWrapperId","validationInformationVisible","$handler","$errorsContainer","$from","after","_this2","$toBind","event","_eventValidate","getValue","children","ParsleyForm","element","ParsleyForm__statusMapping","pending","resolved","rejected","_this3","$submitSource","_$submitSource","first","prop","promise","whenValidate","state","stopImmediatePropagation","preventDefault","done","_submit","$synthetic","appendTo","Event","_arguments","_this4","_ref7","submitEvent","_refreshFields","promises","_withoutReactualizingFormOptions","promiseBasedOnValidationResult","r","Deferred","reject","resolve","when","fail","always","pipe","isValid","_arguments2","_this5","_ref8","_bindFields","_this6","oldFields","fieldsMappedById","not","each","_","fieldInstance","Factory","oldActualizeOptions","ConstraintFactory","parsleyField","isDomConstraint","validatorSpec","_validatorRegistry","_parseRequirements","capitalize","cap","instance","requirementList","_this7","parsleyFormInstance","constraints","constraintsByName","_bindConstraints","parsley_field__statusMapping","_this8","_ref9","refreshConstraints","_isInGroup","_refreshed","_isRequired","validateIfEmpty","inArray","_arguments3","_this9","_ref10","_ref10$force","groupedConstraints","_getGroupedConstraints","_validateConstraint","_this10","_handleWhitespace","addConstraint","removeConstraint","updateConstraint","_bindHtml5Constraints","hasClass","trimValue","whitespace","index","p","sort","a","b","parsley_field","ParsleyMultiple","addElement","$elements","fieldConstraints","has","data","filter","_init","ParsleyFactory","savedparsleyFormInstance","__version__","bind","isMultiple","handleMultiple","parsleyMultipleInstance","_this11","input","$previouslyRelated","get","doNotStore","parsleyInstance","ParsleyExtend","vernums","jquery","forEach","document","version","psly","instances","ParsleyConfig","ParsleyUtils","registry","i18n","method","proxy","_window$Parsley","UI","doNotUpdateClass","navigator","userAgent","autoBind","deprecated","listen","callback","unsubscribeAll","emit","_instance","instanceGiven","asyncValidators","default","xhr","status","reverse","addAsyncValidator","ajaxOptions","csr","indexOf","encodeURIComponent","remoteOptions","param","_remoteCache","ajax","handleXhr","then"],"mappings":";;;;;;;;AAcA,QAASA,oBAAmBC,GAAO,GAAIC,MAAMC,QAAQF,GAAM,CAAE,IAAK,GAAIG,GAAI,EAAGC,EAAOH,MAAMD,EAAIK,QAASF,EAAIH,EAAIK,OAAQF,IAAKC,EAAKD,GAAKH,EAAIG,EAAI,OAAOC,GAAe,MAAOH,OAAMK,KAAKN,GCFtL,GAAAO,QAAAN,MAAAO,UAAAC,OAZA,SAAWC,EAAQC,GACE,gBAAZC,UAA0C,mBAAXC,QAAyBA,OAAOD,QAAUD,EAAQG,QAAQ,WAC9E,kBAAXC,SAAyBA,OAAOC,IAAMD,QAAQ,UAAWJ,GAChED,EAAOO,QAAUN,EAAQD,EAAOQ,SAChCC,KAAM,SAAUC,GAAK,YCOvB,SAASC,GAAMC,EAAIC,GASjB,MAPKD,GAAGE,yBACNF,EAAGE,uBAAyB,WAC1B,GAAIC,GAAOxB,MAAMO,UAAUC,MAAMiB,KAAKC,UAAW,EACjDF,GAAKG,QAAQT,MACbG,EAAGO,MAAMN,GAAWO,EAAGL,KAGpBH,EAAGE,uBAKZ,QAASO,GAAUC,GACjB,MAAyC,KAArCA,EAAKC,YAAYC,EAAa,GACzBF,EAAKG,OAAOD,EAAY7B,QAC1B2B,EC1BT,GAAII,GAAW,EACXC,KAHJC,GAQEC,KAAM,SAAUC,EAAUC,EAAWC,GACnC,GAAIvC,GACAwC,EACAC,EACAC,EAAQ,GAAIC,QAAO,IAAML,EAAW,IAExC,IAAI,mBAAuBC,GACzBA,SAGA,KAAKvC,IAAKuC,GACJA,EAAIK,eAAe5C,UACduC,GAAIvC,EAIjB,IAAI,mBAAuBqC,IAAY,mBAAuBA,GAAS,GACrE,MAAOE,EAGT,KADAE,EAAaJ,EAAS,GAAGI,WACpBzC,EAAIyC,EAAWvC,OAAQF,KAC1BwC,EAAYC,EAAWzC,GAEnBwC,GAAaA,EAAUK,WAAaH,EAAMI,KAAKN,EAAUX,QAC3DU,EAAIvB,KAAK+B,SAASP,EAAUX,KAAKvB,MAAMgC,EAAUpC,UAAYc,KAAKgC,iBAAiBR,EAAUS,OAIjG,OAAOV,IAGTW,UAAW,SAAUb,EAAUC,EAAWa,GACxC,MAAOd,GAASe,GAAG,IAAMd,EAAYa,EAAY,MAGnDE,QAAS,SAAUhB,EAAUC,EAAWF,EAAMa,GAC5CZ,EAAS,GAAGiB,aAAatC,KAAKuC,UAAUjB,EAAYF,GAAOoB,OAAOP,KAGpEQ,WAAY,WACV,MAAO,GAAKxB,KAKde,iBAAkB,SAAUC,GAC1B,GAAIS,EAEJ,KACE,MAAOT,GACI,QAATA,IACU,SAATA,GAAmB,EACX,QAATA,EAAkB,KACjBU,MAAMD,EAAME,OAAOX,IACpB,UAAUH,KAAKG,GAAShC,EAAE4C,UAAUZ,GACpCA,EAF8BS,GAG5BT,EACJ,MAAOa,GAAK,MAAOb,KAIvBF,SAAU,SAAUgB,GAClB,MAAOA,GAAIC,QAAQ,UAAW,SAAUC,EAAOC,GAC7C,MAAOA,GAAMA,EAAIC,cAAgB,MAKrCZ,UAAW,SAAUQ,GACnB,MAAOA,GAAIC,QAAQ,MAAO,KACvBA,QAAQ,wBAAyB,SACjCA,QAAQ,oBAAqB,SAC7BA,QAAQ,KAAM,KACdI,eAGLC,KAAM,WHOF,GAAIC,EGNFC,QAAOC,SAAW,kBAAsBD,QAAOC,QAAQH,OACzDC,EAAAC,OAAOC,SAAQH,KAAA3C,MAAA4C,EAAQ9C,YAG3BiD,SAAU,SAASC,GACZxC,EAAawC,KAChBxC,EAAawC,IAAO,EACpB1D,KAAKqD,KAAA3C,MAALV,KAAaQ,aAIjBmD,eAAgB,WACdzC,MAGF0C,WAAY,SAASC,GACnB,MAAOA,GAAOb,QAAQ,aAAc,KAGtCc,gBAAiB,SAASC,EAAQzC,GAEhC,MADAyC,GAAS/D,KAAK4D,WAAWG,GAAU,IAAIC,MAAM,OACxCD,EAAO,GAEL9D,EAAEgE,IAAIF,EAAQ,SAAAG,GAAS,MAAUA,GAAA,IAAO5C,IAAgB6C,KAAK,KAD3D,IAKXC,aAAcC,OAAOC,QAAU,WAC7B,GAAID,GAAS,YACb,OAAO,UAAUhF,GACf,GAAImB,UAAUtB,OAAS,EACrB,KAAMqF,OAAM,gCAEd,IAAwB,gBAAblF,GACT,KAAMmF,WAAU,6BAElBH,GAAOhF,UAAYA,CACnB,IAAIoF,GAAS,GAAIJ,EAEjB,OADAA,GAAOhF,UAAY,KACZoF,OA5HbC,EAAAvD,ECKIwD,GAIFrD,UAAW,gBAGXsD,OAAQ,0BAGRC,SAAU,gFAGVC,iBAAiB,EAKjBC,SAAU,KAGVC,MAAO,KAIPC,WAAW,EAGXC,oBAAqB,EAGrBC,MAAO,QAGPC,SAAS,EAGTC,oBAAqB,QAGrBC,WAAY,gBAGZC,aAAc,kBAIdC,aAAc,SAAUC,KAIxBC,gBAAiB,SAAUD,KAG3BE,cAAe,wCAGfC,cAAe,aC3DbC,EAAkB,YAEtBA,GAAgBxG,WACdyG,cAAc,EAEdC,iBAAkB,WAIhB,MAZJrB,GASiBtD,KAAKpB,KAAKqB,SAAUrB,KAAKgG,QAAQ1E,UAAWtB,KAAKiG,YAC1DjG,KAAKkG,QAAUlG,KAAKkG,OAAOH,kBAC7B/F,KAAKkG,OAAOH,mBACP/F,MAGTmG,cAAe,SAAUC,GACvBpG,KAAKiG,WAhBTvB,EAgBmCN,aAAapE,KAAKkG,OAAOF,SACxDhG,KAAKgG,QAjBTtB,EAiBgCN,aAAapE,KAAKiG,WAE9C,KAAK,GAAIjH,KAAKoH,GACRA,EAAYxE,eAAe5C,KAC7BgB,KAAKgG,QAAQhH,GAAKoH,EAAYpH,GAElCgB,MAAK+F,oBAGPM,WAAY,KAMZC,GAAI,SAAUzF,EAAMV,GAClBH,KAAKqG,WAAarG,KAAKqG,cACvB,IAAIE,GAAQvG,KAAKqG,WAAWxF,GAAQb,KAAKqG,WAAWxF,MAGpD,OAFA0F,GAAMC,KAAKrG,GAEJH,MAITyG,UAAW,SAAS5F,EAAMV,GACxBF,EAAEyG,SAAS1G,KAAMa,EAAKuC,cAAejD,IAIvCwG,IAAK,SAAU9F,EAAMV,GACnB,GAAIoG,GAAQvG,KAAKqG,YAAcrG,KAAKqG,WAAWxF,EAC/C,IAAI0F,EACF,GAAKpG,EAGH,IAAK,GAAInB,GAAIuH,EAAMrH,OAAQF,KACrBuH,EAAMvH,KAAOmB,GACfoG,EAAMK,OAAO5H,EAAG,cAJbgB,MAAKqG,WAAWxF,EAO3B,OAAOb,OAIT6G,YAAa,SAAShG,EAAMV,GAC1BF,EAAE6G,cAAc9G,KAAMa,EAAKuC,gBAM7BgC,QAAS,SAAUvE,EAAMkG,EAAQC,GAC/BD,EAASA,GAAU/G,IACnB,IACIyE,GADA8B,EAAQvG,KAAKqG,YAAcrG,KAAKqG,WAAWxF,EAG/C,IAAI0F,EACF,IAAK,GAAIvH,GAAIuH,EAAMrH,OAAQF,KAEzB,GADAyF,EAAS8B,EAAMvH,GAAGuB,KAAKwG,EAAQA,EAAQC,GACnCvC,KAAW,EAAO,MAAOA,EAGjC,OAAIzE,MAAKkG,OACAlG,KAAKkG,OAAOd,QAAQvE,EAAMkG,EAAQC,IAEpC,GAITC,MAAO,WAEL,GAAI,gBAAkBjH,KAAKkH,UAEzB,MADAlH,MAAKmH,WACEnH,KAAKoH,SAAS,QAIvB,KAAK,GAAIpI,GAAI,EAAGA,EAAIgB,KAAKqH,OAAOnI,OAAQF,IACtCgB,KAAKqH,OAAOrI,GAAGiI,OAEjBjH,MAAKoH,SAAS,UAIhBE,QAAS,WAGP,GADAtH,KAAKuH,aACD,gBAAkBvH,KAAKkH,UAKzB,MAJAlH,MAAKqB,SAASmG,WAAW,WACzBxH,KAAKqB,SAASmG,WAAW,4BACzBxH,MAAKoH,SAAS,UAMhB,KAAK,GAAIpI,GAAI,EAAGA,EAAIgB,KAAKqH,OAAOnI,OAAQF,IACtCgB,KAAKqH,OAAOrI,GAAGsI,SAEjBtH,MAAKqB,SAASmG,WAAW,WACzBxH,KAAKoH,SAAS,YAGhBK,aAAc,SAAUzC,EAAO0C,GAE7B,MA1HJhD,GAyHiBjB,SAAS,4DACfzD,KAAK2H,WAAW3C,MAAAA,EAAO0C,MAAAA,KAGhCE,aAAc,WACZ,MAAO5H,MAAKgG,QAAQjB,SAClB/E,KAAKkG,OAAO7E,SAASwG,KAAA,IAAS7H,KAAKgG,QAAQ1E,UAAA,aAAsBtB,KAAKgG,QAAQjB,SAAA,MAC9E/E,KAAKqB,UC7HX,IAAIyG,IACFjE,OAAQ,SAASkE,GACf,MAAOA,IAETC,QAAS,SAASnE,GAChB,GAAIlB,MAAMkB,GACR,KAAM,mCAAqCA,EAAS,GACtD,OAAOoE,UAASpE,EAAQ,KAE1BqE,OAAQ,SAASrE,GACf,GAAIlB,MAAMkB,GACR,KAAM,iCAAmCA,EAAS,GACpD,OAAOsE,YAAWtE,IAEpBuE,UAAW,SAASvE,GAClB,GAAIY,GAASxE,EAAE4D,EACf,IAAsB,IAAlBY,EAAOvF,OACT,KAAM,uBAAyB2E,EAAS,GAC1C,OAAOY,IAET4D,UAAS,SAASxE,GAChB,MAAkB,UAAXA,GAETyE,OAAQ,SAASzE,GACf,MA3BJa,GA2BwB1C,iBAAiB6B,IAEvC0E,OAAQ,SAASC,GACf,GAAIC,GAAQ,EAcZ,OAXI,sBAAsB3G,KAAK0G,IAG7BC,EAAQD,EAAOxF,QAAQ,iBAAkB,MAGzCwF,EAASA,EAAOxF,QAAQ,GAAIrB,QAAO,WAAa8G,EAAQ,KAAM,OAG9DD,EAAS,IAAMA,EAAS,IAEnB,GAAI7G,QAAO6G,EAAQC,KAI1BC,EAA0B,SAAS7E,EAAQ3E,GAC7C,GAAIyJ,GAAI9E,EAAOZ,MAAM,mBACrB,KAAK0F,EACH,KAAM,iCAAmC9E,EAAS,GACpD,IAAI+E,GAASD,EAAE,GAAG3E,MAAM,KAAKC,IApD/BS,EAoDgDd,WAC9C,IAAIgF,EAAO1J,SAAWA,EACpB,KAAM,mBAAqB0J,EAAO1J,OAAS,gBAAkBA,EAAS,aACxE,OAAO0J,IAGLC,EAAqB,SAASC,EAAiBjF,GACjD,GAAIkF,GAAYjB,EAAsBgB,GAAmB,SACzD,KAAKC,EACH,KAAM,uCAAyCD,EAAkB,GACnE,OAAOC,GAAUlF,IAGfmF,EAAgC,SAASC,EAAiBpF,EAAQqF,GACpE,GAAIC,GAAO,KACPC,IACJ,KAAK,GAAIC,KAAOJ,GACd,GAAII,EAAK,CACP,GAAIpH,GAAQiH,EAAkBG,EAC1B,iBAAoBpH,KACtBA,EAAQ4G,EAAmBI,EAAgBI,GAAMpH,IACnDmH,EAAMC,GAAOpH,MAEbkH,GAAON,EAAmBI,EAAgBI,GAAMxF,EAGpD,QAAQsF,EAAMC,IAKZE,EAAmB,SAASC,GAC9BtJ,EAAEuJ,QAAO,EAAMxJ,KAAMuJ,GAGvBD,GAAiBjK,WAEfoK,SAAU,SAASxH,EAAOyH,GACxB,GAAI1J,KAAKG,GAIP,MAFIK,WAAUtB,OAAS,IACrBwK,KAAyBpK,MAAMiB,KAAKC,UAAW,EAAG,KAC7CR,KAAKG,GAAGI,KAAKP,KAAMiC,EAAOyH,EAGnC,IAAIzJ,EAAElB,QAAQkD,GAAQ,CACpB,IAAKjC,KAAK2J,iBACR,KAAM,cAAgB3J,KAAKa,KAAO,mCACpC,OAAOb,MAAK2J,iBAAAjJ,MAALV,KAAyBQ,WAEhC,GAAIR,KAAK4J,eACP,MAAIjH,OAAMV,IACD,GACTzB,UAAU,GAAK2H,WAAW3H,UAAU,IAC7BR,KAAK4J,eAAAlJ,MAALV,KAAuBQ,WAEhC,IAAIR,KAAK6J,eACP,MAAO7J,MAAK6J,eAAAnJ,MAALV,KAAuBQ,UAEhC,MAAM,cAAgBR,KAAKa,KAAO,kCAMtCiJ,kBAAmB,SAASC,EAAcb,GACxC,GAAI,gBAAoBa,GAGtB,MAAO9J,GAAElB,QAAQgL,GAAgBA,GAAgBA,EAEnD,IAAIC,GAAOhK,KAAK8I,eAChB,IAAI7I,EAAElB,QAAQiL,GAAO,CAEnB,IAAK,GADDpB,GAASF,EAAwBqB,EAAcC,EAAK9K,QAC/CF,EAAI,EAAGA,EAAI4J,EAAO1J,OAAQF,IACjC4J,EAAO5J,GAAK6J,EAAmBmB,EAAKhL,GAAI4J,EAAO5J,GACjD,OAAO4J,GACF,MAAI3I,GAAEgK,cAAcD,GAClBhB,EAA8BgB,EAAMD,EAAcb,IAEjDL,EAAmBmB,EAAMD,KAIrCjB,gBAAiB,SAEjBoB,SAAU,ECrIZ,IAAIC,GAA2B,SAAUC,EAAYC,GACnDrK,KAAKkH,UAAY,2BAGjBlH,KAAKsK,OAAS,KAEdtK,KAAKuK,KAAKH,MAAkBC,QAG1BG,GACFC,MAAO,04BAGPvC,OAAQ,+BAERF,QAAS,UAET0C,OAAQ,QAERC,SAAU,SAEVC,IAAK,GAAIjJ,QACL,qWA+BK,KAGX6I,GAAYK,MAAQL,EAAYtC,MAGhC,IAAI4C,GAAgB,SAAApI,GAClB,GAAIO,IAAS,GAAKP,GAAKO,MAAM,mCAC7B,OAAKA,GACE8H,KAAKC,IACP,GAEC/H,EAAM,GAAKA,EAAM,GAAG/D,OAAS,IAE7B+D,EAAM,IAAMA,EAAM,GAAK,IANR,EASvBkH,GAAyB9K,WACvBkL,KAAM,SAAUH,EAAYC,GAC1BrK,KAAKqK,QAAUA,EAEfrK,KAAKoK,WAAanK,EAAEuJ,UAAWxJ,KAAKoK,WAEpC,KAAK,GAAIvJ,KAAQuJ,GACfpK,KAAKiL,aAAapK,EAAMuJ,EAAWvJ,GAAMV,GAAIiK,EAAWvJ,GAAMqJ,SAEhE3G,QAAO2H,QAAQ9F,QAAQ,2BAIzB+F,UAAW,SAAUb,GACnB,GAAI,mBAAuBtK,MAAKqK,QAAQC,GACtC,KAAM,IAAI/F,OAAM+F,EAAS,mCAI3B,OAFAtK,MAAKsK,OAASA,EAEPtK,MAIToL,WAAY,SAAUd,EAAQe,EAAUC,GAItC,MAHI,gBAAoBD,KACtBrL,KAAKqK,QAAQC,GAAUe,IAErB,IAASC,EACJtL,KAAKmL,UAAUb,GAEjBtK,MAITuL,WAAY,SAAUjB,EAAQzJ,EAAM2K,GAMlC,MALI,mBAAuBxL,MAAKqK,QAAQC,KACtCtK,KAAKqK,QAAQC,OAEftK,KAAKqK,QAAQC,GAAQzJ,GAAQ2K,EAEtBxL,MAITyL,YAAa,SAAUnB,EAAQoB,GAC7B,IAAK,GAAI7K,KAAQ6K,GACf1L,KAAKuL,WAAWjB,EAAQzJ,EAAM6K,EAAkB7K,GAElD,OAAOb,OAiBTiL,aAAc,SAAUpK,EAAM8K,EAAMC,GAClC,GAAI5L,KAAKoK,WAAWvJ,GA7IxB6D,EA8ImBrB,KAAK,cAAgBxC,EAAO,6BACtC,IAAI8D,EAAgB/C,eAAef,GAEtC,WAjJN6D,GAgJmBrB,KAAK,IAAMxC,EAAO,+DAGjC,OAAOb,MAAK6L,cAAAnL,MAALV,KAAsBQ,YAG/BsL,gBAAiB,SAAUjL,EAAM8K,EAAMC,GACrC,MAAK5L,MAAKoK,WAAWvJ,GAIdb,KAAK6L,cAAc7L,KAAMQ,YA3JpCkE,EAwJmBrB,KAAK,cAAgBxC,EAAO,6BAClCb,KAAKiL,aAAAvK,MAALV,KAAqBQ,aAKhCuL,gBAAiB,SAAUlL,GAMzB,MALKb,MAAKoK,WAAWvJ,IA/JzB6D,EAgKmBrB,KAAK,cAAgBxC,EAAO,2BAEpCb,MAAKoK,WAAWvJ,GAEhBb,MAGT6L,cAAe,SAAUhL,EAAMmL,EAAW9B,GACpC,gBAAoB8B,KAEtBA,GACE7L,GAAI6L,EACJ9B,SAAUA,IAGT8B,EAAUvC,WACbuC,EAAY,GAAI1C,GAAiB0C,IAEnChM,KAAKoK,WAAWvJ,GAAQmL,CAExB,KAAK,GAAI1B,KAAU0B,GAAUX,aAC3BrL,KAAKuL,WAAWjB,EAAQzJ,EAAMmL,EAAUX,SAASf,GAEnD,OAAOtK,OAGTiM,gBAAiB,SAAUC,GACzB,GAAIV,EAGJ,IAAI,SAAWU,EAAWrL,KAAM,CAC9B,GAAIsL,GAAenM,KAAKqK,QAAQrK,KAAKsK,QAAQ4B,EAAWrL,SACxD2K,GAAUW,EAAaD,EAAWnC,kBAElCyB,GAAUxL,KAAKoM,cAAcpM,KAAKqK,QAAQrK,KAAKsK,QAAQ4B,EAAWrL,MAAOqL,EAAWnC,aAEtF,OAAOyB,IAAWxL,KAAKqK,QAAQrK,KAAKsK,QAAQ+B,gBAAkBrM,KAAKqK,QAAQiC,GAAGD,gBAIhFD,cAAe,SAAUvI,EAAQ0I,GAC/B,GAAI,gBAAoBA,GAAY,CAClC,IAAK,GAAIvN,KAAKuN,GACZ1I,EAAS7D,KAAKoM,cAAcvI,EAAQ0I,EAAWvN,GAEjD,OAAO6E,GAGT,MAAO,gBAAoBA,GAASA,EAAOb,QAAQ,MAAOuJ,GAAc,IAU1EnC,YACEoC,UACE3C,eAAgB,SAAS5H,GACvB,MAAO,KAAKH,KAAKG,IAEnBiI,SAAU,GAEZuC,UACE9C,iBAAkB,SAASf,GACzB,MAAOA,GAAO1J,OAAS,GAEzB2K,eAAgB,SAAS5H,GACvB,MAAO,KAAKH,KAAKG,IAEnBiI,SAAU,KAEZF,MACEH,eAAgB,SAAS5H,EAAO+H,GPmb5B,GAAI0C,GAAOlM,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MOnbaA,UAAA,GPqbvDoM,EAAYF,EOrbmBG,KAAAA,EAAAF,SAAAC,EAAO,IAAAA,EPubtCE,EAAYJ,EOvb+BK,KAAAA,EAAAJ,SAAAG,EAAO,EAAAA,EACpDpL,EAAQ8I,EAAYR,EACxB,KAAKtI,EACH,KAAM,IAAI6C,OAAM,mBAAqByF,EAAO,qBAE9C,KAAKtI,EAAMI,KAAKG,GACd,OAAO,CACT,IAAI,WAAa+H,IACV,SAASlI,KAAK+K,GAAQ,IAAK,CAC9B,GAAIG,GAAKpK,OAAOX,GACZgL,EAAWlC,KAAKC,IAAIF,EAAc+B,GAAO/B,EAAciC,GAC3D,IAAIjC,EAAckC,GAAMC,EACtB,OAAO,CAET,IAAIC,GAAQ,SAAAC,GAAO,MAAOpC,MAAKqC,MAAMD,EAAIpC,KAAKsC,IAAI,GAAIJ,IACtD,KAAKC,EAAMF,GAAME,EAAMH,IAASG,EAAML,IAAS,EAC7C,OAAO,EAGb,OAAO,GAET/D,iBACE,GAAI,SACJ+D,KAAM,SACNE,KAAM,UAER7C,SAAU,KAEZoD,SACEzD,eAAgB,SAAS5H,EAAOsG,GAC9B,MAAOA,GAAOzG,KAAKG,IAErB6G,gBAAiB,SACjBoB,SAAU,IAEZqD,WACE1D,eAAgB,SAAU5H,EAAOuL,GAC/B,MAAOvL,GAAM/C,QAAUsO,GAEzB1E,gBAAiB,UACjBoB,SAAU,IAEZuD,WACE5D,eAAgB,SAAU5H,EAAOuL,GAC/B,MAAOvL,GAAM/C,QAAUsO,GAEzB1E,gBAAiB,UACjBoB,SAAU,IAEZhL,QACE2K,eAAgB,SAAU5H,EAAOyL,EAAK1C,GACpC,MAAO/I,GAAM/C,QAAUwO,GAAOzL,EAAM/C,QAAU8L,GAEhDlC,iBAAkB,UAAW,WAC7BoB,SAAU,IAEZyD,UACEhE,iBAAkB,SAAUf,EAAQ4E,GAClC,MAAO5E,GAAO1J,QAAUsO,GAE1B1E,gBAAiB,UACjBoB,SAAU,IAEZ0D,UACEjE,iBAAkB,SAAUf,EAAQ4E,GAClC,MAAO5E,GAAO1J,QAAUsO,GAE1B1E,gBAAiB,UACjBoB,SAAU,IAEZ2D,OACElE,iBAAkB,SAAUf,EAAQ8E,EAAK1C,GACvC,MAAOpC,GAAO1J,QAAUwO,GAAO9E,EAAO1J,QAAU8L,GAElDlC,iBAAkB,UAAW,WAC7BoB,SAAU,IAEZwD,KACE9D,eAAgB,SAAU3H,EAAOuL,GAC/B,MAAOvL,IAASuL,GAElB1E,gBAAiB,SACjBoB,SAAU,IAEZc,KACEpB,eAAgB,SAAU3H,EAAOuL,GAC/B,MAAgBA,IAATvL,GAET6G,gBAAiB,SACjBoB,SAAU,IAEZW,OACEjB,eAAgB,SAAU3H,EAAOyL,EAAK1C,GACpC,MAAO/I,IAASyL,GAAgB1C,GAAT/I,GAEzB6G,iBAAkB,SAAU,UAC5BoB,SAAU,IAEZ4D,SACEjE,eAAgB,SAAU5H,EAAO8L,GAC/B,GAAIC,GAAa/N,EAAE8N,EACnB,OAAIC,GAAW9O,OACN+C,IAAU+L,EAAWC,MAErBhM,IAAU8L,GAErB7D,SAAU,MClVhB,IAAIgE,MAEAC,EAAc,QAAdA,GAAwBC,EAAWC,EAAWC,GAIhD,IAAK,GAHDC,MACAC,KAEKxP,EAAI,EAAGA,EAAIoP,EAAUlP,OAAQF,IAAK,CAGzC,IAAK,GAFDyP,IAAQ,EAEHC,EAAI,EAAGA,EAAIL,EAAUnP,OAAQwP,IACpC,GAAIN,EAAUpP,GAAG2P,OAAO9N,OAASwN,EAAUK,GAAGC,OAAO9N,KAAM,CACzD4N,GAAQ,CACR,OAGAA,EACFD,EAAKhI,KAAK4H,EAAUpP,IAEpBuP,EAAM/H,KAAK4H,EAAUpP,IAGzB,OACEwP,KAAMA,EACND,MAAOA,EACPK,QAAUN,KAAOH,EAAYE,EAAWD,GAAW,GAAMG,OAI7DL,GAAUW,MAERC,mBAAoB,WR0wBhB,GAAIC,GAAQ/O,IQzwBdA,MAAKqB,SAASiF,GAAG,iBAAkB,SAAApC,GAAS6K,EAAKC,iBAAiB9K,KAClElE,KAAKqB,SAASiF,GAAG,gBAAiB,8CAA+C,SAAApC,GAAS6K,EAAKE,eAAe/K,MAG1G,IAAUlE,KAAKgG,QAAQf,WAG3BjF,KAAKqB,SAASD,KAAK,aAAc,KAGnC+D,MAAO,WAGL,GAFAnF,KAAKkP,cAAgB,MAEjB,IAASlP,KAAKmP,kBAAoB,SAAWnP,KAAKgG,QAAQb,MAC5D,MAAO,KAET,KAAK,GAAInG,GAAI,EAAGA,EAAIgB,KAAKqH,OAAOnI,OAAQF,IAAK,CAC3C,GAAIoQ,GAAQpP,KAAKqH,OAAOrI,EACxB,KAAI,IAASoQ,EAAMD,kBAAoBC,EAAMD,iBAAiBjQ,OAAS,GAAK,mBAAuBkQ,GAAMpJ,QAAQqJ,UAC/GrP,KAAKkP,cAAgBE,EAAM/N,SACvB,UAAYrB,KAAKgG,QAAQb,OAC3B,MAIN,MAAI,QAASnF,KAAKkP,cACT,KAEFlP,KAAKkP,cAAc/J,SAG5BoC,WAAY,WAEVvH,KAAKqB,SAASsF,IAAI,cAKtBuH,EAAUoB,OAERC,UAAW,WAIT,GAHAvP,KAAKwP,WAGAxP,KAAKyP,IAAV,CAIA,GAAIC,GAAOvB,EAAYnO,KAAKmP,iBAAkBnP,KAAKyP,IAAIE,qBAGvD3P,MAAKyP,IAAIE,qBAAuB3P,KAAKmP,iBAGrCnP,KAAK4P,qBAGL5P,KAAK6P,sBAAsBH,GAG3B1P,KAAK8O,sBAGAY,EAAKlB,KAAKtP,SAAUwQ,EAAKnB,MAAMrP,QAAYc,KAAK8P,cACnD9P,KAAK8P,aAAc,EACnB9P,KAAK8O,wBAKTiB,kBAAmB,WAEjB,IAAI,IAAS/P,KAAKmP,iBAChB,QAIF,KAAK,GAFD9D,MAEKrM,EAAI,EAAGA,EAAIgB,KAAKmP,iBAAiBjQ,OAAQF,IAChDqM,EAAS7E,KAAKxG,KAAKmP,iBAAiBnQ,GAAGgR,cACtChQ,KAAKiQ,iBAAiBjQ,KAAKmP,iBAAiBnQ,GAAG2P,QAElD,OAAOtD,IAIT6E,SAAU,SAAUrP,GRwwBhB,GAAIsP,GAAQ3P,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MQxwBeA,UAAA,GAAvCgL,EAAA2E,EAAA3E,QAASmD,EAAAwB,EAAAxB,OR4wB5ByB,EAAoBD,EQ5wBgBE,YAAAA,EAAA1D,SAAAyD,GAAc,EAAAA,CACxDpQ,MAAKwP,WACLxP,KAAKsQ,UAAUzP,GAAO2K,QAAAA,EAASmD,OAAAA,IAE3B0B,GACFrQ,KAAKuQ,eAITC,YAAa,SAAU3P,GR8wBnB,GAAI4P,GAAQjQ,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MQ9wBkBA,UAAA,GAAvCgL,EAAAiF,EAAAjF,QAASmD,EAAA8B,EAAA9B,ORkxB/B+B,EAAoBD,EQlxBmBJ,YAAAA,EAAA1D,SAAA+D,GAAc,EAAAA,CAC3D1Q,MAAKwP,WACLxP,KAAK2Q,aAAa9P,GAAO2K,QAAAA,EAASmD,OAAAA,IAE9B0B,GACFrQ,KAAKuQ,eAITK,YAAa,SAAU/P,GRoxBnB,GAAIgQ,GAAQrQ,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MQpxBCA,UAAA,GRsxB5CsQ,EAAoBD,EQtxBER,YAAAA,EAAA1D,SAAAmE,GAAc,EAAAA,CAC1C9Q,MAAKwP,WACLxP,KAAK+Q,aAAalQ,GAIdwP,GACFrQ,KAAK4P,sBAGTA,mBAAoB,WACd5P,KAAKgR,kBAAoBhR,KAAKiR,oBAAqB,IAASjR,KAAKmP,iBACnEnP,KAAKkR,gBACElR,KAAKmP,iBAAiBjQ,OAAS,EACtCc,KAAKuQ,cAELvQ,KAAKmR,eAGTtB,sBAAuB,SAAUH,GAC/B,GAAI,mBAAuB1P,MAAKgG,QAAQoL,uBAAxC,CAIA,GAAI,mBAAuBpR,MAAKgG,QAAQgK,aACtC,MAAKN,GAAKnB,MAAMrP,QAAUwQ,EAAKlB,KAAKtP,QAClCc,KAAKqR,sBAED,IAAMrR,KAAKyP,IAAI6B,eAAezJ,KAAK,iCAAiC3I,QACtEc,KAAKyP,IAAI6B,eACNC,OACCtR,EAAED,KAAKgG,QAAQJ,eACd4L,SAAS,iCAGTxR,KAAKyP,IAAI6B,eACbE,SAAS,UACT3J,KAAK,iCACL4J,KAAKzR,KAAKgG,QAAQgK,eAGhBhQ,KAAKyP,IAAI6B,eACbI,YAAY,UACZ7J,KAAK,iCACL8J,QAIL,KAAK,GAAI3S,GAAI,EAAGA,EAAI0Q,EAAKd,QAAQ1P,OAAQF,IACvCgB,KAAK+Q,aAAarB,EAAKd,QAAQ5P,GAAG2P,OAAO9N,KAE3C,KAAK7B,EAAI,EAAGA,EAAI0Q,EAAKnB,MAAMrP,OAAQF,IACjCgB,KAAKsQ,UAAUZ,EAAKnB,MAAMvP,GAAG2P,OAAO9N,MAAO2K,QAASkE,EAAKnB,MAAMvP,GAAGgR,aAAcrB,OAAQe,EAAKnB,MAAMvP,GAAG2P,QAExG,KAAK3P,EAAI,EAAGA,EAAI0Q,EAAKlB,KAAKtP,OAAQF,IAChCgB,KAAK2Q,aAAajB,EAAKlB,KAAKxP,GAAG2P,OAAO9N,MAAO2K,QAASkE,EAAKlB,KAAKxP,GAAGgR,aAAcrB,OAAQe,EAAKlB,KAAKxP,GAAG2P,WAI1G2B,UAAW,SAAUzP,EAAM+Q,GRmwBvB,GQnwBwBpG,GAADoG,EAACpG,QAASmD,EAAViD,EAAUjD,MACnC3O,MAAKqR,sBACLrR,KAAKyP,IAAI6B,eACNE,SAAS,UACTD,OACCtR,EAAED,KAAKgG,QAAQJ,eACd4L,SAAS,WAAa3Q,GACtB4Q,KAAKjG,GAAWxL,KAAKiQ,iBAAiBtB,MAI7CgC,aAAc,SAAU9P,EAAMgR,GRgwB1B,GQhwB2BrG,GAADqG,EAACrG,QAASmD,EAAVkD,EAAUlD,MACtC3O,MAAKyP,IAAI6B,eACNE,SAAS,UACT3J,KAAK,YAAchH,GACnB4Q,KAAKjG,GAAWxL,KAAKiQ,iBAAiBtB,KAG3CoC,aAAc,SAAUlQ,GACtBb,KAAKyP,IAAI6B,eACNI,YAAY,UACZ7J,KAAK,YAAchH,GACnB8Q,UAGL1B,iBAAkB,SAAU/D,GAC1B,GAAI4F,GAA+B5F,EAAWrL,KAAO,SAErD,OAAI,mBAAuBb,MAAKgG,QAAQ8L,GAC/BvO,OAAO2H,QAAQkB,cAAcpM,KAAKgG,QAAQ8L,GAA+B5F,EAAWnC,cAEtFxG,OAAO2H,QAAQe,gBAAgBC,IAGxCsD,SAAU,WAER,IAAIxP,KAAKyP,MAAO,IAAUzP,KAAKgG,QAAQf,UAAvC,CAGA,GAAIwK,KAGJzP,MAAKqB,SAASD,KAAKpB,KAAKgG,QAAQ1E,UAAY,KAAMtB,KAAK+R,QAIvDtC,EAAIuC,mBAAqBhS,KAAKiS,sBAG9BxC,EAAIyC,gBAAkB,eAAiBlS,KAAKgG,QAAQjB,SAAW,YAAc/E,KAAKgG,QAAQjB,SAAW/E,KAAK+R,QAC1GtC,EAAI6B,eAAiBrR,EAAED,KAAKgG,QAAQL,eAAevE,KAAK,KAAMqO,EAAIyC,iBAGlEzC,EAAIE,wBACJF,EAAI0C,8BAA+B,EAGnCnS,KAAKyP,IAAMA,IAIbwC,oBAAqB,WAEnB,GAAI,gBAAoBjS,MAAKgG,QAAQR,cAAgBvF,EAAED,KAAKgG,QAAQR,cAActG,OAChF,MAAOe,GAAED,KAAKgG,QAAQR,aAGxB,IAAI4M,GAAWpS,KAAKgG,QAAQR,aAAajF,KAAKP,KAAMA,KAGpD,OAAI,mBAAuBoS,IAAYA,EAASlT,OACvCkT,GAGJpS,KAAKgG,QAAQjB,UAAY/E,KAAKqB,SAASe,GAAG,UACtCpC,KAAKqB,SAGPrB,KAAKqB,SAAS6E,UAGvBmL,oBAAqB,WACnB,GAAIgB,EAGJ,IAAI,IAAMrS,KAAKyP,IAAI6B,eAAepL,SAAShH,OACzC,MAAOc,MAAKyP,IAAI6B,eAAepL,QAEjC,IAAI,gBAAoBlG,MAAKgG,QAAQN,gBAAiB,CACpD,GAAIzF,EAAED,KAAKgG,QAAQN,iBAAiBxG,OAClC,MAAOe,GAAED,KAAKgG,QAAQN,iBAAiB6L,OAAOvR,KAAKyP,IAAI6B,eA9R/D5M,GAgSqBrB,KAAK,yBAA2BrD,KAAKgG,QAAQN,gBAAkB,+BACrE,kBAAsB1F,MAAKgG,QAAQN,kBAC5C2M,EAAmBrS,KAAKgG,QAAQN,gBAAgBnF,KAAKP,KAAMA,MAE7D,IAAI,mBAAuBqS,IAAoBA,EAAiBnT,OAC9D,MAAOmT,GAAiBd,OAAOvR,KAAKyP,IAAI6B,eAE1C,IAAIgB,GAAQtS,KAAKqB,QAGjB,OAFIrB,MAAKgG,QAAQjB,WACfuN,EAAQA,EAAMpM,UACToM,EAAMC,MAAMvS,KAAKyP,IAAI6B,iBAG9BxC,mBAAoB,WRivBhB,GAAI0D,GAASxS,KQhvBXyS,EAAUzS,KAAK4H,cAGnB6K,GAAQ9L,IAAI,YACR3G,KAAK8P,YACP2C,EAAQnM,GAnTd5B,EAmT8BZ,gBAAgB9D,KAAKgG,QAAQX,oBAAqB,WAAY,WACpFmN,EAAK/I,aAGPgJ,EAAQnM,GAvTd5B,EAuT8BZ,gBAAgB9D,KAAKgG,QAAQZ,QAAS,WAAY,SAAAsN,GACxEF,EAAKG,eAAeD,MAK1BC,eAAgB,SAAUD,KAIpB,YAAY5Q,KAAK4Q,EAAM1I,OACnBhK,KAAKyP,KAAOzP,KAAKyP,IAAI0C,gCAAiCnS,KAAK4S,WAAW1T,QAAUc,KAAKgG,QAAQd,uBAGrGlF,KAAKyJ,YAGPtC,SAAU,WAERnH,KAAK8P,aAAc,EACnB9P,KAAK8O,qBAGD,mBAAuB9O,MAAKyP,MAIhCzP,KAAKyP,IAAI6B,eACNI,YAAY,UACZmB,WACAlB,SAGH3R,KAAKmR,cAGLnR,KAAKyP,IAAIE,wBACT3P,KAAKyP,IAAI0C,8BAA+B,IAG1C5K,WAAY,WACVvH,KAAKmH,WAED,mBAAuBnH,MAAKyP,KAC9BzP,KAAKyP,IAAI6B,eAAeK,eAEnB3R,MAAKyP,KAGdyB,cAAe,WACblR,KAAKyP,IAAI0C,8BAA+B,EACxCnS,KAAKyP,IAAIuC,mBAAmBN,YAAY1R,KAAKgG,QAAQV,YAAYkM,SAASxR,KAAKgG,QAAQT,eAEzFgL,YAAa,WACXvQ,KAAKyP,IAAI0C,8BAA+B,EACxCnS,KAAKyP,IAAIuC,mBAAmBN,YAAY1R,KAAKgG,QAAQT,cAAciM,SAASxR,KAAKgG,QAAQV,aAE3F6L,YAAa,WACXnR,KAAKyP,IAAIuC,mBAAmBN,YAAY1R,KAAKgG,QAAQT,cAAcmM,YAAY1R,KAAKgG,QAAQV,aC7WhG,IAAIwN,GAAc,SAAUC,EAAS9M,EAAYD,GAC/ChG,KAAKkH,UAAY,cACjBlH,KAAK+R,OANPrN,EAM6BjC,aAE3BzC,KAAKqB,SAAWpB,EAAE8S,GAClB/S,KAAKiG,WAAaA,EAClBjG,KAAKgG,QAAUA,EACfhG,KAAKkG,OAAS3C,OAAO2H,QAErBlL,KAAKqH,UACLrH,KAAKmP,iBAAmB,MAd1B6D,GAiBqBC,QAAS,KAAMC,UAAU,EAAMC,UAAU,EAE9DL,GAAYzT,WACV2P,iBAAkB,SAAU0D,GT2lCxB,GAAIU,GAASpT,ISzlCf,KAAI,IAAS0S,EAAM5S,QAAnB,CAIA,GAAIuT,GAAgBrT,KAAKsT,gBAAkBtT,KAAKqB,SAASwG,KAAK,+CAA+C0L,OAG7G,IAFAvT,KAAKsT,eAAiB,KACtBtT,KAAKqB,SAASwG,KAAK,oCAAoC2L,KAAK,YAAY,IACpEH,EAAcjR,GAAG,oBAArB,CAGA,GAAIqR,GAAUzT,KAAK0T,cAAchB,MAAAA,GAE7B,cAAee,EAAQE,UAAW,IAAU3T,KAAKoH,SAAS,YAK5DsL,EAAMkB,2BACNlB,EAAMmB,iBACF,YAAcJ,EAAQE,SACxBF,EAAQK,KAAK,WAAQV,EAAKW,QAAQV,SAIxCpE,eAAgB,SAASyD,GACvB1S,KAAKsT,eAAiBrT,EAAEyS,EAAM3L,SAKhCgN,QAAS,SAAUV,GACjB,IAAI,IAAUrT,KAAKoH,SAAS,UAA5B,CAGA,GAAIiM,EAAe,CACjB,GAAIW,GAAahU,KAAKqB,SAASwG,KAAK,oCAAoC2L,KAAK,YAAY,EACrF,KAAMQ,EAAW9U,SACnB8U,EAAa/T,EAAE,iEAAiEgU,SAASjU,KAAKqB,WAChG2S,EAAW5S,MACTP,KAAMwS,EAAcjS,KAAK,QACzBa,MAAOoR,EAAcjS,KAAK,WAI9BpB,KAAKqB,SAAS+D,QAAQnF,EAAEuJ,OAAOvJ,EAAEiU,MAAM,WAAYpU,SAAS,OAQ9D2J,SAAU,SAAUzD,GAClB,GAAIxF,UAAUtB,QAAU,IAAMe,EAAEgK,cAAcjE,GAAU,CA3E5DtB,EA4EmBjB,SAAS,2FT2lCpB,IAAI0Q,GAAa/U,OAAOmB,KS1lCEC,WAAvBwE,EAAAmP,EAAA,GAAOzM,EAAAyM,EAAA,GAAOzB,EAAAyB,EAAA,EACnBnO,IAAWhB,MAAAA,EAAO0C,MAAAA,EAAOgL,MAAAA,GAE3B,MAhFJM,GAgF0BhT,KAAK0T,aAAa1N,GAAS2N,UAGnDD,aAAc,WTgmCV,GAAIU,GAASpU,KAETqU,EAAQ7T,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MSlmCHA,UAAA,GAAvBwE,EAAAqP,EAAArP,MAAO0C,EAAA2M,EAAA3M,MAAOgL,EAAA2B,EAAA3B,KACrC1S,MAAKsU,YAAc5B,EACfA,IACF1S,KAAKsU,YAAcrU,EAAEuJ,UAAWkJ,GAAQmB,eAAgB,WAtF9DnP,EAuFqBjB,SAAS,0GACtB2Q,EAAKjF,kBAAmB,MAG5BnP,KAAKmP,kBAAmB,EAGxBnP,KAAKoH,SAAS,YAGdpH,KAAKuU,gBAEL,IAAIC,GAAWxU,KAAKyU,iCAAiC,WACnD,MAAOxU,GAAEgE,IAAImQ,EAAK/M,OAAQ,SAAA+H,GACxB,MAAOA,GAAMsE,cAAchM,MAAAA,EAAO1C,MAAAA,QAIlC0P,EAAiC,WACnC,GAAIC,GAAI1U,EAAE2U,UAGV,QAFI,IAAUR,EAAKjF,kBACjBwF,EAAEE,SACGF,EAAEG,UAAUrB,UAGrB,OAAOxT,GAAE8U,KAAArU,MAAFT,EAAArB,mBAAU4V,IACdV,KAAO,WAAQM,EAAKhN,SAAS,aAC7B4N,KAAO,WACNZ,EAAKjF,kBAAmB,EACxBiF,EAAKjP,QACLiP,EAAKhN,SAAS,WAEf6N,OAAO,WAAQb,EAAKhN,SAAS,eAC7B8N,KAAOR,EAAgCA,IAO5CS,QAAS,SAAUnP,GACjB,GAAIxF,UAAUtB,QAAU,IAAMe,EAAEgK,cAAcjE,GAAU,CAhI5DtB,EAiImBjB,SAAS,0FTwmCpB,IAAI2R,GAAchW,OAAOmB,KSvmCNC,WAAhBwE,EAAAoQ,EAAA,GAAO1N,EAAA0N,EAAA,EACZpP,IAAWhB,MAAAA,EAAO0C,MAAAA,GAEpB,MArIJsL,GAqI0BhT,KAAK2H,UAAU3B,GAAS2N,UAMhDhM,UAAW,WT4mCP,GAAI0N,GAASrV,KAETsV,EAAQ9U,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MS9mCbA,UAAA,GAAhBwE,EAAAsQ,EAAAtQ,MAAO0C,EAAA4N,EAAA5N,KAC3B1H,MAAKuU,gBAEL,IAAIC,GAAWxU,KAAKyU,iCAAiC,WACnD,MAAOxU,GAAEgE,IAAIoR,EAAKhO,OAAQ,SAAA+H,GACxB,MAAOA,GAAMzH,WAAW3C,MAAAA,EAAO0C,MAAAA,OAGnC,OAAOzH,GAAE8U,KAAArU,MAAFT,EAAArB,mBAAU4V,KAGnBD,eAAgB,WACd,MAAOvU,MAAK+F,mBAAmBwP,eAGjCA,YAAa,WTmnCT,GAAIC,GAASxV,KSlnCXyV,EAAYzV,KAAKqH,MAwBrB,OAtBArH,MAAKqH,UACLrH,KAAK0V,oBAEL1V,KAAKyU,iCAAiC,WACpCe,EAAKnU,SACJwG,KAAK2N,EAAKxP,QAAQpB,QAClB+Q,IAAIH,EAAKxP,QAAQnB,UACjB+Q,KAAK,SAACC,EAAG9C,GACR,GAAI+C,GAAgB,GAAIvS,QAAO2H,QAAQ6K,QAAQhD,KAASyC,EAGnD,kBAAmBM,EAAc5O,WAAa,yBAA2B4O,EAAc5O,YAAe,IAAS4O,EAAc9P,QAAQnB,UACpI,mBAAuB2Q,GAAKE,iBAAiBI,EAAc5O,UAAY,IAAM4O,EAAc/D,UAC7FyD,EAAKE,iBAAiBI,EAAc5O,UAAY,IAAM4O,EAAc/D,QAAU+D,EAC9EN,EAAKnO,OAAOb,KAAKsP,MAIvB7V,EAAEwV,GAAWE,IAAIH,EAAKnO,QAAQuO,KAAK,SAACC,EAAGzG,GACrCA,EAAMhI,SAAS,aAGZpH,MAUTyU,iCAAkC,SAAUtU,GAC1C,GAAI6V,GAAsBhW,KAAK+F,gBAC/B/F,MAAK+F,iBAAmB,WAAc,MAAO/F,MAC7C,IAAIyE,GAAStE,GAEb,OADAH,MAAK+F,iBAAmBiQ,EACjBvR,GAMT2C,SAAU,SAAUxG,GAClB,MAAOZ,MAAKoF,QAAQ,QAAUxE,ICpMlC,IAAIqV,GAAoB,SAAUC,EAAcrV,EAAMkJ,EAAcG,EAAUiM,GAC5E,IAAK,eAAerU,KAAKoU,EAAahP,WACpC,KAAM,IAAI3C,OAAM,yDAElB,IAAI6R,GAAgB7S,OAAO2H,QAAQmL,mBAAmBjM,WAAWvJ,GAC7DmL,EAAY,GAAI1C,GAAiB8M,EAErCnW,GAAEuJ,OAAOxJ,MACPgM,UAAWA,EACXnL,KAAMA,EACNkJ,aAAcA,EACdG,SAAUA,GAAYgM,EAAalQ,QAAQnF,EAAO,aAAemL,EAAU9B,SAC3EiM,iBAAiB,IAASA,IAE5BnW,KAAKsW,mBAAmBJ,EAAalQ,UAGnCuQ,EAAa,SAASxT,GACxB,GAAIyT,GAAMzT,EAAI,GAAGI,aACjB,OAAOqT,GAAMzT,EAAIzD,MAAM,GAGzB2W,GAAkB5W,WAChBoK,SAAU,SAASxH,EAAOwU,GACxB,GAAInW,GAAON,KAAK0W,gBAAgBpX,MAAM,EAGtC,OAFAgB,GAAKG,QAAQwB,GACb3B,EAAKkG,KAAKiQ,GACHzW,KAAKgM,UAAUvC,SAAS/I,MAAMV,KAAKgM,UAAW1L,IAGvDgW,mBAAoB,SAAStQ,GV2zCzB,GAAI2Q,GAAS3W,IU1zCfA,MAAK0W,gBAAkB1W,KAAKgM,UAAUlC,kBAAkB9J,KAAK+J,aAAc,SAAAV,GACzE,MAAOrD,GAAQ2Q,EAAK9V,KAAO0V,EAAWlN,OChC5C,IAAI5D,GAAe,SAAU2J,EAAOnJ,EAAYD,EAAS4Q,GACvD5W,KAAKkH,UAAY,eACjBlH,KAAK+R,OAPPrN,EAO6BjC,aAE3BzC,KAAKqB,SAAWpB,EAAEmP,GAGd,mBAAuBwH,KACzB5W,KAAKkG,OAAS0Q,GAGhB5W,KAAKgG,QAAUA,EACfhG,KAAKiG,WAAaA,EAGlBjG,KAAK6W,eACL7W,KAAK8W,qBACL9W,KAAKmP,oBAGLnP,KAAK+W,oBAzBPC,GA4BqB/D,QAAS,KAAMC,UAAU,EAAMC,UAAU,EAE9D1N,GAAapG,WAKXoK,SAAU,SAAUzD,GACdxF,UAAUtB,QAAU,IAAMe,EAAEgK,cAAcjE,KApClDtB,EAqCmBjB,SAAS,6FACtBuC,GAAWA,QAAAA,GAEb,IAAIyN,GAAUzT,KAAK0T,aAAa1N,EAChC,KAAKyN,EACH,OAAO,CACT,QAAQA,EAAQE,SACd,IAAK,UAAW,MAAO,KACvB,KAAK,WAAY,OAAO,CACxB,KAAK,WAAY,MAAO3T,MAAKmP,mBAOjCuE,aAAc,WXq2CV,GAAIuD,GAASjX,KAETkX,EAAQ1W,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MWv2CTA,UAAA,GAAjBkH,EAAAwP,EAAAxP,MAAO1C,EAAAkS,EAAAlS,KAG9B,OADAhF,MAAKmX,sBACDnS,GAAUhF,KAAKoX,WAAWpS,IAG9BhF,KAAKiC,MAAQjC,KAAK4S,WAGlB5S,KAAKoH,SAAS,YAEPpH,KAAK2H,WAAWD,MAAAA,EAAOzF,MAAOjC,KAAKiC,MAAOoV,YAAY,IAC1DpC,OAAO,WAAQgC,EAAK1H,cACpBuE,KAAK,WAAUmD,EAAK7P,SAAS,aAC7B4N,KAAK,WAAUiC,EAAK7P,SAAS,WAC7B6N,OAAO,WAAQgC,EAAK7P,SAAS,gBAZhC,QAeF4J,eAAgB,WACd,MAAO,KAAMhR,KAAK6W,YAAY3X,QAIhC+R,gBAAiB,SAAUhP,GAMzB,MALI,mBAAuBA,KACzBA,EAAQjC,KAAK4S,YAIV3Q,EAAM/C,QAAWc,KAAKsX,eAAiB,mBAAuBtX,MAAKgG,QAAQuR,iBAGzE,GAFE,GAKXH,WAAY,SAAUpS,GACpB,MAAI/E,GAAElB,QAAQiB,KAAKgG,QAAQhB,OAClB,KAAO/E,EAAEuX,QAAQxS,EAAOhF,KAAKgG,QAAQhB,OACvChF,KAAKgG,QAAQhB,QAAUA,GAOhCmQ,QAAS,SAAUnP,GACjB,GAAIxF,UAAUtB,QAAU,IAAMe,EAAEgK,cAAcjE,GAAU,CAnG5DtB,EAoGmBjB,SAAS,2FX62CpB,IAAIgU,GAAcrY,OAAOmB,KW52CNC,WAAhBkH,EAAA+P,EAAA,GAAOxV,EAAAwV,EAAA,EACZzR,IAAW0B,MAAAA,EAAOzF,MAAAA,GAEpB,GAAIwR,GAAUzT,KAAK2H,UAAU3B,EAC7B,OAAKyN,GAzGTuD,EA2GyBvD,EAAQE,UADpB,GASXhM,UAAW,WXi3CP,GAAI+P,GAAS1X,KAET2X,EAASnX,UAAUtB,QAAU,GAAsByN,SAAjBnM,UAAU,MWn3CaA,UAAA,GXq3CzDoX,EAAeD,EWr3CDjQ,MAAAA,EAAAiF,SAAAiL,GAAQ,EAAAA,EAAO3V,EAAA0V,EAAA1V,MAAO+C,EAAA2S,EAAA3S,MAAOqS,EAAAM,EAAAN,UAKjD,IAHKA,GACHrX,KAAKmX,sBAEHnS,GAAUhF,KAAKoX,WAAWpS,GAA9B,CAMA,GAHAhF,KAAKmP,kBAAmB,GAGnBnP,KAAKgR,iBACR,MAAO/Q,GAAE8U,MAMX,KAHI,mBAAuB9S,IAAS,OAASA,KAC3CA,EAAQjC,KAAK4S,aAEV5S,KAAKiR,gBAAgBhP,KAAU,IAASyF,EAC3C,MAAOzH,GAAE8U,MAEX,IAAI8C,GAAqB7X,KAAK8X,yBAC1BtD,IAWJ,OAVAvU,GAAE2V,KAAKiC,EAAoB,SAAChC,EAAGgB,GAG7B,GAAIpD,GAAUxT,EAAE8U,KAAArU,MAAFT,EAAArB,mBACTqB,EAAEgE,IAAI4S,EAAa,SAAA3K,GXq3CpB,MWr3CkCwL,GAAKK,oBAAoB9V,EAAOiK,MAGtE,OADAsI,GAAShO,KAAKiN,GACU,aAApBA,EAAQE,SACH,EADT,SAGK1T,EAAE8U,KAAKrU,MAAMT,EAAGuU,KAIzBuD,oBAAqB,SAAS9V,EAAOiK,GXq3CjC,GAAI8L,GAAUhY,KWp3CZyE,EAASyH,EAAWzC,SAASxH,EAAOjC,KAKxC,QAHI,IAAUyE,IACZA,EAASxE,EAAE2U,WAAWC,UAEjB5U,EAAE8U,KAAKtQ,GAAQuQ,KAAK,SAAAhF,IACrB,IAASgI,EAAK7I,mBAChB6I,EAAK7I,qBACP6I,EAAK7I,iBAAiB3I,MACpBmI,OAAQzC,EACR8D,aAAc,gBAAoBA,IAAgBA,OAMxD4C,SAAU,WACR,GAAI3Q,EAWJ,OAPEA,GADE,kBAAsBjC,MAAKgG,QAAQ/D,MAC7BjC,KAAKgG,QAAQ/D,MAAMjC,MACpB,mBAAuBA,MAAKgG,QAAQ/D,MACnCjC,KAAKgG,QAAQ/D,MAEbjC,KAAKqB,SAAS4M,MAGpB,mBAAuBhM,IAAS,OAASA,EACpC,GAEFjC,KAAKiY,kBAAkBhW,IAKhCkV,mBAAoB,WAClB,MAAOnX,MAAK+F,mBAAmBgR,oBAWjCmB,cAAe,SAAUrX,EAAMkJ,EAAcG,EAAUiM,GAErD,GAAI5S,OAAO2H,QAAQmL,mBAAmBjM,WAAWvJ,GAAO,CACtD,GAAIqL,GAAa,GAAI+J,GAAkBjW,KAAMa,EAAMkJ,EAAcG,EAAUiM,EAGvE,eAAgBnW,KAAK8W,kBAAkB5K,EAAWrL,OACpDb,KAAKmY,iBAAiBjM,EAAWrL,MAEnCb,KAAK6W,YAAYrQ,KAAK0F,GACtBlM,KAAK8W,kBAAkB5K,EAAWrL,MAAQqL,EAG5C,MAAOlM,OAITmY,iBAAkB,SAAUtX,GAC1B,IAAK,GAAI7B,GAAI,EAAGA,EAAIgB,KAAK6W,YAAY3X,OAAQF,IAC3C,GAAI6B,IAASb,KAAK6W,YAAY7X,GAAG6B,KAAM,CACrCb,KAAK6W,YAAYjQ,OAAO5H,EAAG,EAC3B,OAGJ,aADOgB,MAAK8W,kBAAkBjW,GACvBb,MAIToY,iBAAkB,SAAUvX,EAAM0L,EAAYrC,GAC5C,MAAOlK,MAAKmY,iBAAiBtX,GAC1BqX,cAAcrX,EAAM0L,EAAYrC,IAOrC6M,iBAAkB,WAKhB,IAAK,GAJDF,MACAC,KAGK9X,EAAI,EAAGA,EAAIgB,KAAK6W,YAAY3X,OAAQF,KACvC,IAAUgB,KAAK6W,YAAY7X,GAAGmX,kBAChCU,EAAYrQ,KAAKxG,KAAK6W,YAAY7X,IAClC8X,EAAkB9W,KAAK6W,YAAY7X,GAAG6B,MAAQb,KAAK6W,YAAY7X,GAGnEgB,MAAK6W,YAAcA,EACnB7W,KAAK8W,kBAAoBA,CAGzB,KAAK,GAAIjW,KAAQb,MAAKgG,QACpBhG,KAAKkY,cAAcrX,EAAMb,KAAKgG,QAAQnF,GAAO8L,QAAW,EAG1D,OAAO3M,MAAKqY,yBAKdA,sBAAuB,YAEjBrY,KAAKqB,SAASiX,SAAS,aAAetY,KAAKqB,SAASD,KAAK,cAC3DpB,KAAKkY,cAAc,YAAY,EAAMvL,QAAW,GAG9C,gBAAoB3M,MAAKqB,SAASD,KAAK,YACzCpB,KAAKkY,cAAc,UAAWlY,KAAKqB,SAASD,KAAK,WAAYuL,QAAW,GAGtE,mBAAuB3M,MAAKqB,SAASD,KAAK,QAAU,mBAAuBpB,MAAKqB,SAASD,KAAK,OAChGpB,KAAKkY,cAAc,SAAUlY,KAAKqB,SAASD,KAAK,OAAQpB,KAAKqB,SAASD,KAAK,QAASuL,QAAW,GAGxF,mBAAuB3M,MAAKqB,SAASD,KAAK,OACjDpB,KAAKkY,cAAc,MAAOlY,KAAKqB,SAASD,KAAK,OAAQuL,QAAW,GAGzD,mBAAuB3M,MAAKqB,SAASD,KAAK,QACjDpB,KAAKkY,cAAc,MAAOlY,KAAKqB,SAASD,KAAK,OAAQuL,QAAW,GAI9D,mBAAuB3M,MAAKqB,SAASD,KAAK,cAAgB,mBAAuBpB,MAAKqB,SAASD,KAAK,aACtGpB,KAAKkY,cAAc,UAAWlY,KAAKqB,SAASD,KAAK,aAAcpB,KAAKqB,SAASD,KAAK,cAAeuL,QAAW,GAGrG,mBAAuB3M,MAAKqB,SAASD,KAAK,aACjDpB,KAAKkY,cAAc,YAAalY,KAAKqB,SAASD,KAAK,aAAcuL,QAAW,GAGrE,mBAAuB3M,MAAKqB,SAASD,KAAK,cACjDpB,KAAKkY,cAAc,YAAalY,KAAKqB,SAASD,KAAK,aAAcuL,QAAW,EAI9E,IAAI3C,GAAOhK,KAAKqB,SAASD,KAAK,OAE9B,OAAI,mBAAuB4I,GAClBhK,KAGL,WAAagK,EACRhK,KAAKkY,cAAc,QAAS,UACjCrL,KAAM7M,KAAKqB,SAASD,KAAK,QACzB2L,KAAM/M,KAAKqB,SAASD,KAAK,QAAUpB,KAAKqB,SAASD,KAAK,WACpDuL,QAAW,GAEN,uBAAuB7K,KAAKkI,GAC9BhK,KAAKkY,cAAc,OAAQlO,EAAM2C,QAAW,GAE9C3M,MAKTsX,YAAa,WACX,MAAI,mBAAuBtX,MAAK8W,kBAAkBrK,UACzC,GAEF,IAAUzM,KAAK8W,kBAAkBrK,SAAS1C,cAKnD3C,SAAU,SAAUxG,GAClB,MAAOZ,MAAKoF,QAAQ,SAAWxE,IAOjCqX,kBAAmB,SAAUhW,GAU3B,OATI,IAASjC,KAAKgG,QAAQuS,WAhV9B7T,EAiVmBjB,SAAS,2FAEpB,WAAazD,KAAKgG,QAAQwS,aAC5BvW,EAAQA,EAAMe,QAAQ,UAAW,OAE/B,SAAYhD,KAAKgG,QAAQwS,YAAgB,WAAaxY,KAAKgG,QAAQwS,aAAgB,IAASxY,KAAKgG,QAAQuS,aAC3GtW,EAvVNyC,EAuV2Bd,WAAW3B,IAE3BA,GAMT6V,uBAAwB,WACtB,IAAI,IAAU9X,KAAKgG,QAAQlB,gBACzB,OAAQ9E,KAAK6W,YAMf,KAAK,GAJDgB,MACAY,KAGKzZ,EAAI,EAAGA,EAAIgB,KAAK6W,YAAY3X,OAAQF,IAAK,CAChD,GAAI0Z,GAAI1Y,KAAK6W,YAAY7X,GAAGkL,QACvBuO,GAAMC,IACTb,EAAmBrR,KAAKiS,EAAMC,OAChCD,EAAMC,GAAGlS,KAAKxG,KAAK6W,YAAY7X,IAKjC,MAFA6Y,GAAmBc,KAAK,SAAUC,EAAGC,GAAK,MAAOA,GAAE,GAAG3O,SAAW0O,EAAE,GAAG1O,WAE/D2N,GAhXX,IAAAiB,GAAArT,ECEIsT,EAAkB,WACpB/Y,KAAKkH,UAAY,uBAGnB6R,GAAgB1Z,WAEd2Z,WAAY,SAAU3X,GAGpB,MAFArB,MAAKiZ,UAAUzS,KAAKnF,GAEbrB,MAITmX,mBAAoB,WAClB,GAAI+B,EAKJ,IAHAlZ,KAAK6W,eAGD7W,KAAKqB,SAASe,GAAG,UAGnB,MAFApC,MAAK+F,mBAAmBgR,mBAEjB/W,IAIT,KAAK,GAAIhB,GAAI,EAAGA,EAAIgB,KAAKiZ,UAAU/Z,OAAQF,IAGzC,GAAKiB,EAAE,QAAQkZ,IAAInZ,KAAKiZ,UAAUja,IAAIE,OAAtC,CAKAga,EAAmBlZ,KAAKiZ,UAAUja,GAAGoa,KAAK,wBAAwBjC,qBAAqBN,WAEvF,KAAK,GAAInI,GAAI,EAAGA,EAAIwK,EAAiBha,OAAQwP,IAC3C1O,KAAKkY,cAAcgB,EAAiBxK,GAAG7N,KAAMqY,EAAiBxK,GAAG3E,aAAcmP,EAAiBxK,GAAGxE,SAAUgP,EAAiBxK,GAAGyH,qBAPjInW,MAAKiZ,UAAUrS,OAAO5H,EAAG,EAU7B,OAAOgB,OAIT4S,SAAU,WAER,GAAI,kBAAsB5S,MAAKgG,QAAQ/D,MACrCA,MAAQjC,KAAKgG,QAAQ/D,MAAMjC,UACxB,IAAI,mBAAuBA,MAAKgG,QAAQ/D,MAC3C,MAAOjC,MAAKgG,QAAQ/D,KAGtB,IAAIjC,KAAKqB,SAASe,GAAG,qBACnB,MAAOpC,MAAK4H,eAAeyR,OAAO,YAAYpL,OAAS,EAGzD,IAAIjO,KAAKqB,SAASe,GAAG,wBAAyB,CAC5C,GAAIwG,KAMJ,OAJA5I,MAAK4H,eAAeyR,OAAO,YAAYzD,KAAK,WAC1ChN,EAAOpC,KAAKvG,EAAED,MAAMiO,SAGfrF,EAIT,MAAI5I,MAAKqB,SAASe,GAAG,WAAa,OAASpC,KAAKqB,SAAS4M,SAIlDjO,KAAKqB,SAAS4M,OAGvBqL,MAAO,WAGL,MAFAtZ,MAAKiZ,WAAajZ,KAAKqB,UAEhBrB,MCxEX,IAAIuZ,GAAiB,SAAUxG,EAAS/M,EAAS4Q,GAC/C5W,KAAKqB,SAAWpB,EAAE8S,EAGlB,IAAIyG,GAA2BxZ,KAAKqB,SAAS+X,KAAK,UAClD,IAAII,EAQF,MALI,mBAAuB5C,IAAuB4C,EAAyBtT,SAAW3C,OAAO2H,UAC3FsO,EAAyBtT,OAAS0Q,EAClC4C,EAAyBrT,cAAcqT,EAAyBxT,UAG3DwT,CAIT,KAAKxZ,KAAKqB,SAASnC,OACjB,KAAM,IAAIqF,OAAM,gDAElB,IAAI,mBAAuBqS,IAAuB,gBAAkBA,EAAoB1P,UACtF,KAAM,IAAI3C,OAAM,iDAGlB,OADAvE,MAAKkG,OAAS0Q,GAAuBrT,OAAO2H,QACrClL,KAAKuK,KAAKvE,GAGnBuT,GAAela,WACbkL,KAAM,SAAUvE,GASd,MARAhG,MAAKkH,UAAY,UACjBlH,KAAKyZ,YAAc,QACnBzZ,KAAK+R,OAtCTrN,EAsC+BjC,aAG3BzC,KAAKmG,cAAcH,GAGfhG,KAAKqB,SAASe,GAAG,SA5CzBsC,EA4CkDxC,UAAUlC,KAAKqB,SAAUrB,KAAKgG,QAAQ1E,UAAW,cAAgBtB,KAAKqB,SAASe,GAAGpC,KAAKgG,QAAQpB,QACpI5E,KAAK0Z,KAAK,eAGZ1Z,KAAK2Z,aAAe3Z,KAAK4Z,iBAAmB5Z,KAAK0Z,KAAK,iBAG/DC,WAAY,WACV,MAAO3Z,MAAMqB,SAASe,GAAG,4CAAgDpC,KAAKqB,SAASe,GAAG,WAAa,mBAAuBpC,MAAKqB,SAASD,KAAK,aAKnJwY,eAAgB,WbmxDZ,GalxDE/Y,GAEAgZ,EbgxDEC,EAAU9Z,IarwDhB,IARIA,KAAKgG,QAAQjB,WAER,mBAAuB/E,MAAKqB,SAASD,KAAK,SAAWpB,KAAKqB,SAASD,KAAK,QAAQlC,OACvFc,KAAKgG,QAAQjB,SAAWlE,EAAOb,KAAKqB,SAASD,KAAK,QAC3C,mBAAuBpB,MAAKqB,SAASD,KAAK,OAASpB,KAAKqB,SAASD,KAAK,MAAMlC,SACnFc,KAAKgG,QAAQjB,SAAW/E,KAAKqB,SAASD,KAAK,QAGzCpB,KAAKqB,SAASe,GAAG,WAAa,mBAAuBpC,MAAKqB,SAASD,KAAK,YAE1E,MADApB,MAAKgG,QAAQjB,SAAW/E,KAAKgG,QAAQjB,UAAY/E,KAAK+R,OAC/C/R,KAAK0Z,KAAK,uBAGZ,KAAK1Z,KAAKgG,QAAQjB,SAEvB,MA9ENL,GA6EmBrB,KAAK,wHAAyHrD,KAAKqB,UACzIrB,IAITA,MAAKgG,QAAQjB,SAAW/E,KAAKgG,QAAQjB,SAAS/B,QAAQ,yBAA0B;AAG5E,mBAAuBnC,IACzBZ,EAAE,eAAiBY,EAAO,MAAM+U,KAAK,SAAC5W,EAAG+a,GACnC9Z,EAAE8Z,GAAO3X,GAAG,4CACdnC,EAAE8Z,GAAO3Y,KAAK0Y,EAAK9T,QAAQ1E,UAAY,WAAYwY,EAAK9T,QAAQjB,WAMtE,KAAK,GADDiV,GAAqBha,KAAK4H,eACrB5I,EAAI,EAAGA,EAAIgb,EAAmB9a,OAAQF,IAE7C,GADA6a,EAA0B5Z,EAAE+Z,EAAmBC,IAAIjb,IAAIoa,KAAK,WACxD,mBAAuBS,GAAyB,CAE7C7Z,KAAKqB,SAAS+X,KAAK,yBACtBS,EAAwBb,WAAWhZ,KAAKqB,SAG1C,OAQJ,MAFArB,MAAK0Z,KAAK,gBAAgB,GAEnBG,GAA2B7Z,KAAK0Z,KAAK,yBAI9CA,KAAM,SAAU1P,EAAMkQ,GACpB,GAAIC,EAEJ,QAAQnQ,GACN,IAAK,cACHmQ,EAAkBla,EAAEuJ,OAClB,GAAIsJ,GAAY9S,KAAKqB,SAAUrB,KAAKiG,WAAYjG,KAAKgG,SACrDzC,OAAO6W,eACP7E,aACF,MACF,KAAK,eACH4E,EAAkBla,EAAEuJ,OAClB,GA9HVsP,GA8H2B9Y,KAAKqB,SAAUrB,KAAKiG,WAAYjG,KAAKgG,QAAShG,KAAKkG,QACpE3C,OAAO6W,cAET,MACF,KAAK,uBACHD,EAAkBla,EAAEuJ,OAClB,GApIVsP,GAoI2B9Y,KAAKqB,SAAUrB,KAAKiG,WAAYjG,KAAKgG,QAAShG,KAAKkG,QACpE,GAAI6S,GACJxV,OAAO6W,eACPd,OACF,MACF,SACE,KAAM,IAAI/U,OAAMyF,EAAO,mCAM3B,MAHIhK,MAAKgG,QAAQjB,UA7IrBL,EA8ImBrC,QAAQrC,KAAKqB,SAAUrB,KAAKgG,QAAQ1E,UAAW,WAAYtB,KAAKgG,QAAQjB,UAEnF,mBAAuBmV,IACzBla,KAAKqB,SAAS+X,KAAK,uBAAwBe,GAEpCA,IAITna,KAAKqB,SAAS+X,KAAK,UAAWe,GAG9BA,EAAgBrL,qBAChBqL,EAAgB/S,SAAS,QAElB+S,IClJX,IAAIE,GAAUpa,EAAEE,GAAGma,OAAOtW,MAAM,IAChC,IAAIiE,SAASoS,EAAQ,KAAO,GAAKpS,SAASoS,EAAQ,IAAM,EACtD,KAAM,6EAEHA,GAAQE,SAfb7V,EAgBerB,KAAK,4FAGpB,IAAI6H,GAAUjL,EAAEuJ,OAAO,GAAI3D,IACvBxE,SAAUpB,EAAEua,UACZzU,iBAAkB,KAClBI,cAAe,KACf4P,QAASwD,EACTkB,QAAS,SAKbxa,GAAEuJ,OA7BFsP,EA6BsBzZ,UAAW6O,EAAUoB,MAAOzJ,EAAgBxG,WAClEY,EAAEuJ,OAAOsJ,EAAYzT,UAAW6O,EAAUW,KAAMhJ,EAAgBxG,WAEhEY,EAAEuJ,OAAO+P,EAAela,UAAWwG,EAAgBxG,WAInDY,EAAEE,GAAGL,QAAUG,EAAEE,GAAGua,KAAO,SAAU1U,GACnC,GAAIhG,KAAKd,OAAS,EAAG,CACnB,GAAIyb,KAMJ,OAJA3a,MAAK4V,KAAK,WACR+E,EAAUnU,KAAKvG,EAAED,MAAMF,QAAQkG,MAG1B2U,EAIT,MAAK1a,GAAED,MAAMd,OAMN,GAAIqa,GAAevZ,KAAMgG,OAtDlCtB,GAiDiBrB,KAAK,kDAUlB,mBAAuBE,QAAO6W,gBAChC7W,OAAO6W,kBAITlP,EAAQlF,QAAU/F,EAAEuJ,OAhEpB9E,EAgEwCN,aAAaO,GAAkBpB,OAAOqX,eAC9ErX,OAAOqX,cAAgB1P,EAAQlF,QAG/BzC,OAAO2H,QAAU3H,OAAOmX,KAAOxP,EAC/B3H,OAAOsX,aArEPnW,CAwEA,IAAIoW,GAAWvX,OAAO2H,QAAQmL,mBAAqB,GAAIlM,GAAyB5G,OAAOqX,cAAcxQ,WAAY7G,OAAOqX,cAAcG,KACtIxX,QAAO+F,oBACPrJ,EAAE2V,KAAK,yHAAyH5R,MAAM,KAAM,SAAUhF,EAAGgc,GACvJzX,OAAO2H,QAAQ8P,GAAU/a,EAAEgb,MAAMH,EAAUE,GAC3CzX,OAAO+F,iBAAiB0R,GAAU,Wd05D9B,GAAIE,Ecx5DN,OA9EJxW,GA6EiBjB,SAAA,yBAAkCuX,EAAA,yEAA+EA,EAAA,WACvHE,EAAA3X,OAAO2H,SAAQ8P,GAAAta,MAAAwa,EAAW1a,cAMrC+C,OAAO2H,QAAQiQ,GAAKjN,EACpB3K,OAAO2K,WACL0C,YAAa,SAAU6F,EAAU5V,EAAMua,GACrC,GAAI/K,IAAc,IAAS+K,CAE3B,OAzFJ1W,GAwFiBjB,SAAA,qJACNgT,EAAS7F,YAAY/P,GAAOwP,YAAAA,KAErCN,kBAAmB,SAAU0G,GAE3B,MA7FJ/R,GA4FiBjB,SAAA,yFACNgT,EAAS1G,sBAGpB9P,EAAE2V,KAAK,uBAAuB5R,MAAM,KAAM,SAAUhF,EAAGgc,GACrDzX,OAAO2K,UAAU8M,GAAU,SAAUvE,EAAU5V,EAAM2K,EAASmD,EAAQyM,GACpE,GAAI/K,IAAc,IAAS+K,CAE3B,OApGJ1W,GAmGiBjB,SAAA,4CAAqDuX,EAAA,iGAC3DvE,EAASuE,GAAQna,GAAO2K,QAAAA,EAASmD,OAAAA,EAAQ0B,YAAAA,OAMhD,WAAWvO,KAAKuZ,UAAUC,YAC5Brb,EAAEua,UAAUlU,GAAG,SAAU,SAAU,SAAApC,GACjCjE,EAAEiE,EAAI6C,QAAQ3B,QAAQ,YAMtB,IAAU7B,OAAOqX,cAAcW,UACjCtb,EAAE,WAEIA,EAAE,2BAA2Bf,QAC/Be,EAAE,2BAA2BH,WZjHnC,IAAIa,GAAIV,MACJub,EAAa,WANjB9W,EAOejB,SAAS,iHAgBpB1C,EAAc,UASlBd,GAAEwb,OAAS,SAAU5a,EAAM6a,GACzB,GAAItb,EAOJ,IANAob,IACI,gBAAoBhb,WAAU,IAAM,kBAAsBA,WAAU,KACtEJ,EAAUI,UAAU,GACpBkb,EAAWlb,UAAU,IAGnB,kBAAsBkb,GACxB,KAAM,IAAInX,OAAM,mBAElBhB,QAAO2H,QAAQ5E,GAAG1F,EAAUC,GAAOX,EAAMwb,EAAUtb,KAGrDH,EAAEyG,SAAW,SAAU+P,EAAU5V,EAAMV,GAErC,GADAqb,MACM/E,YAhDRqC,IAgD+CrC,YAAoB3D,IAC/D,KAAM,IAAIvO,OAAM,6BAElB,IAAI,gBAAoB1D,IAAQ,kBAAsBV,GACpD,KAAM,IAAIoE,OAAM,mBAElBkS,GAASnQ,GAAG1F,EAAUC,GAAOX,EAAMC,KAGrCF,EAAE4G,YAAc,SAAUhG,EAAMV,GAE9B,GADAqb,IACI,gBAAoB3a,IAAQ,kBAAsBV,GACpD,KAAM,IAAIoE,OAAM,kBAClBhB,QAAO2H,QAAQvE,IAAI/F,EAAUC,GAAOV,EAAGE,yBAGzCJ,EAAE6G,cAAgB,SAAU2P,EAAU5V,GAEpC,GADA2a,MACM/E,YAlERqC,IAkE+CrC,YAAoB3D,IAC/D,KAAM,IAAIvO,OAAM,6BAClBkS,GAAS9P,IAAI/F,EAAUC,KAGzBZ,EAAE0b,eAAiB,SAAU9a,GAC3B2a,IACAjY,OAAO2H,QAAQvE,IAAI/F,EAAUC,IAC7BZ,EAAE,8BAA8B2V,KAAK,WACnC,GAAIa,GAAWxW,EAAED,MAAMoZ,KAAK,UACxB3C,IACFA,EAAS9P,IAAI/F,EAAUC,OAM7BZ,EAAE2b,KAAO,SAAU/a,EAAM4V,GF0gErB,GAAIoF,EEzgENL,IACA,IAAIM,GAAiBrF,YArFvBqC,IAqF6DrC,YAAoB3D,GAC3ExS,EAAOxB,MAAMO,UAAUC,MAAMiB,KAAKC,UAAWsb,EAAgB,EAAI,EACrExb,GAAKG,QAAQG,EAAUC,IAClBib,IACHrF,EAAWlT,OAAO2H,UAEpB2Q,EAAApF,GAASrR,QAAA1E,MAAAmb,EAAAjd,mBAAW0B,IavFtBL,GAAEuJ,QAAO,EAAM0B,GACb6Q,iBACEC,WACE7b,GAAI,SAAU8b,GAKZ,MAAOA,GAAIC,QAAU,KAAOD,EAAIC,OAAS,KAE3CtR,KAAK,GAEPuR,SACEhc,GAAI,SAAU8b,GAEZ,MAAOA,GAAIC,OAAS,KAAOD,EAAIC,QAAU,KAE3CtR,KAAK,IAITwR,kBAAmB,SAAUvb,EAAMV,EAAIyK,EAAK5E,GAO1C,MANAkF,GAAQ6Q,gBAAgBlb,IACtBV,GAAIA,EACJyK,IAAKA,IAAO,EACZ5E,QAASA,OAGJhG,QAKXkL,EAAQD,aAAa,UACnBnC,iBACE,GAAI,SACJkD,UAAa,SACbmQ,QAAW,UACXnW,QAAW,UAGb6D,eAAgB,SAAU5H,EAAO2I,EAAK5E,EAASyQ,GAC7C,GACI4F,GACAC,EAFAlD,KAGApN,EAAYhG,EAAQgG,aAAc,IAAShG,EAAQmW,QAAU,UAAY,UAE7E,IAAI,mBAAuBjR,GAAQ6Q,gBAAgB/P,GACjD,KAAM,IAAIzH,OAAM,0CAA4CyH,EAAY,IAE1EpB,GAAMM,EAAQ6Q,gBAAgB/P,GAAWpB,KAAOA,EAG5CA,EAAI2R,QAAQ,WAAa,GAC3B3R,EAAMA,EAAI5H,QAAQ,UAAWwZ,mBAAmBva,IAEhDmX,EAAK3C,EAASpV,SAASD,KAAK,SAAWqV,EAASpV,SAASD,KAAK,OAASa,CAIzE,IAAIwa,GAAgBxc,EAAEuJ,QAAO,EAAMxD,EAAQA,YAAgBkF,EAAQ6Q,gBAAgB/P,GAAWhG,QAG9FqW,GAAcpc,EAAEuJ,QAAO,MACrBoB,IAAKA,EACLwO,KAAMA,EACNpP,KAAM,OACLyS,GAGHhG,EAASrR,QAAQ,oBAAqBqR,EAAU4F,GAEhDC,EAAMrc,EAAEyc,MAAML,GAGV,mBAAuBnR,GAAQyR,eACjCzR,EAAQyR,gBAGV,IAAIV,GAAM/Q,EAAQyR,aAAaL,GAAOpR,EAAQyR,aAAaL,IAAQrc,EAAE2c,KAAKP,GAEtEQ,EAAY,WACd,GAAIpY,GAASyG,EAAQ6Q,gBAAgB/P,GAAW7L,GAAGI,KAAKkW,EAAUwF,EAAKrR,EAAK5E,EAG5E,OAFKvB,KACHA,EAASxE,EAAE2U,WAAWC,UACjB5U,EAAE8U,KAAKtQ,GAGhB,OAAOwX,GAAIa,KAAKD,EAAWA,IAG7B3S,SAAU,KAGZgB,EAAQ5E,GAAG,cAAe,WACxB4E,EAAQyR,kBAGVpZ,OAAO6W,cAAcgC,kBAAoB,WAEvC,MADAvB,cAAapX,SAAS,4HACfyH,EAAQkR,kBAAA1b,MAARwK,EAA6B1K,YCpGtC0K,EAAQO,YAAY,MAClBY,eAAgB,kCAChBrC,MACES,MAAc,sCACdG,IAAc,oCACd1C,OAAc,uCACdF,QAAc,wCACd0C,OAAc,+BACdC,SAAc,sCAEhB6B,SAAgB,kCAChBC,SAAgB,0BAChBa,QAAgB,kCAChBI,IAAgB,oDAChB1C,IAAgB,kDAChBH,MAAgB,0CAChB0C,UAAgB,iEAChBE,UAAgB,iEAChBvO,OAAgB,gFAChByO,SAAgB,uCAChBC,SAAgB,uCAChBC,MAAgB,6CAChBC,QAAgB,mCAGlB5C,EAAQC,UAAU,KC7BlB,IAAArL,GAAAoL,ChBuzEE,OAAOpL","file":"parsley.min.js","sourcesContent":[null,"(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :\n typeof define === 'function' && define.amd ? define(['jquery'], factory) :\n global.parsley = factory(global.$)\n}(this, function ($) { 'use strict';\n\n var globalID = 1;\n var pastWarnings = {};\n\n var ParsleyUtils__ParsleyUtils = {\n // Parsley DOM-API\n // returns object from dom attributes and values\n attr: function ($element, namespace, obj) {\n var i;\n var attribute;\n var attributes;\n var regex = new RegExp('^' + namespace, 'i');\n\n if ('undefined' === typeof obj)\n obj = {};\n else {\n // Clear all own properties. This won't affect prototype's values\n for (i in obj) {\n if (obj.hasOwnProperty(i))\n delete obj[i];\n }\n }\n\n if ('undefined' === typeof $element || 'undefined' === typeof $element[0])\n return obj;\n\n attributes = $element[0].attributes;\n for (i = attributes.length; i--; ) {\n attribute = attributes[i];\n\n if (attribute && attribute.specified && regex.test(attribute.name)) {\n obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);\n }\n }\n\n return obj;\n },\n\n checkAttr: function ($element, namespace, checkAttr) {\n return $element.is('[' + namespace + checkAttr + ']');\n },\n\n setAttr: function ($element, namespace, attr, value) {\n $element[0].setAttribute(this.dasherize(namespace + attr), String(value));\n },\n\n generateID: function () {\n return '' + globalID++;\n },\n\n /** Third party functions **/\n // Zepto deserialize function\n deserializeValue: function (value) {\n var num;\n\n try {\n return value ?\n value == \"true\" ||\n (value == \"false\" ? false :\n value == \"null\" ? null :\n !isNaN(num = Number(value)) ? num :\n /^[\\[\\{]/.test(value) ? $.parseJSON(value) :\n value)\n : value;\n } catch (e) { return value; }\n },\n\n // Zepto camelize function\n camelize: function (str) {\n return str.replace(/-+(.)?/g, function (match, chr) {\n return chr ? chr.toUpperCase() : '';\n });\n },\n\n // Zepto dasherize function\n dasherize: function (str) {\n return str.replace(/::/g, '/')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n .replace(/([a-z\\d])([A-Z])/g, '$1_$2')\n .replace(/_/g, '-')\n .toLowerCase();\n },\n\n warn: function () {\n if (window.console && 'function' === typeof window.console.warn)\n window.console.warn(...arguments);\n },\n\n warnOnce: function(msg) {\n if (!pastWarnings[msg]) {\n pastWarnings[msg] = true;\n this.warn(...arguments);\n }\n },\n\n _resetWarnings: function () {\n pastWarnings = {};\n },\n\n trimString: function(string) {\n return string.replace(/^\\s+|\\s+$/g, '');\n },\n\n namespaceEvents: function(events, namespace) {\n events = this.trimString(events || '').split(/\\s+/);\n if (!events[0])\n return '';\n return $.map(events, evt => { return `${evt}.${namespace}`; }).join(' ');\n },\n\n // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill\n objectCreate: Object.create || (function () {\n var Object = function () {};\n return function (prototype) {\n if (arguments.length > 1) {\n throw Error('Second argument not supported');\n }\n if (typeof prototype != 'object') {\n throw TypeError('Argument must be an object');\n }\n Object.prototype = prototype;\n var result = new Object();\n Object.prototype = null;\n return result;\n };\n })()\n };\n\n var ParsleyUtils__default = ParsleyUtils__ParsleyUtils;\n\n // All these options could be overriden and specified directly in DOM using\n // `data-parsley-` default DOM-API\n // eg: `inputs` can be set in DOM using `data-parsley-inputs=\"input, textarea\"`\n // eg: `data-parsley-stop-on-first-failing-constraint=\"false\"`\n\n var ParsleyDefaults = {\n // ### General\n\n // Default data-namespace for DOM API\n namespace: 'data-parsley-',\n\n // Supported inputs by default\n inputs: 'input, textarea, select',\n\n // Excluded inputs by default\n excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',\n\n // Stop validating field on highest priority failing constraint\n priorityEnabled: true,\n\n // ### Field only\n\n // identifier used to group together inputs (e.g. radio buttons...)\n multiple: null,\n\n // identifier (or array of identifiers) used to validate only a select group of inputs\n group: null,\n\n // ### UI\n // Enable\\Disable error messages\n uiEnabled: true,\n\n // Key events threshold before validation\n validationThreshold: 3,\n\n // Focused field on form validation error. 'first'|'last'|'none'\n focus: 'first',\n\n // event(s) that will trigger validation before first failure. eg: `input`...\n trigger: false,\n\n // event(s) that will trigger validation after first failure.\n triggerAfterFailure: 'input',\n\n // Class that would be added on every failing validation Parsley field\n errorClass: 'parsley-error',\n\n // Same for success validation\n successClass: 'parsley-success',\n\n // Return the `$element` that will receive these above success or error classes\n // Could also be (and given directly from DOM) a valid selector like `'#div'`\n classHandler: function (ParsleyField) {},\n\n // Return the `$element` where errors will be appended\n // Could also be (and given directly from DOM) a valid selector like `'#div'`\n errorsContainer: function (ParsleyField) {},\n\n // ul elem that would receive errors' list\n errorsWrapper: '
      ',\n\n // li elem that would receive error message\n errorTemplate: '
    • '\n };\n\n var ParsleyAbstract = function () {};\n\n ParsleyAbstract.prototype = {\n asyncSupport: true, // Deprecated\n\n actualizeOptions: function () {\n ParsleyUtils__default.attr(this.$element, this.options.namespace, this.domOptions);\n if (this.parent && this.parent.actualizeOptions)\n this.parent.actualizeOptions();\n return this;\n },\n\n _resetOptions: function (initOptions) {\n this.domOptions = ParsleyUtils__default.objectCreate(this.parent.options);\n this.options = ParsleyUtils__default.objectCreate(this.domOptions);\n // Shallow copy of ownProperties of initOptions:\n for (var i in initOptions) {\n if (initOptions.hasOwnProperty(i))\n this.options[i] = initOptions[i];\n }\n this.actualizeOptions();\n },\n\n _listeners: null,\n\n // Register a callback for the given event name\n // Callback is called with context as the first argument and the `this`\n // The context is the current parsley instance, or window.Parsley if global\n // A return value of `false` will interrupt the calls\n on: function (name, fn) {\n this._listeners = this._listeners || {};\n var queue = this._listeners[name] = this._listeners[name] || [];\n queue.push(fn);\n\n return this;\n },\n\n // Deprecated. Use `on` instead\n subscribe: function(name, fn) {\n $.listenTo(this, name.toLowerCase(), fn);\n },\n\n // Unregister a callback (or all if none is given) for the given event name\n off: function (name, fn) {\n var queue = this._listeners && this._listeners[name];\n if (queue) {\n if (!fn) {\n delete this._listeners[name];\n } else {\n for (var i = queue.length; i--; )\n if (queue[i] === fn)\n queue.splice(i, 1);\n }\n }\n return this;\n },\n\n // Deprecated. Use `off`\n unsubscribe: function(name, fn) {\n $.unsubscribeTo(this, name.toLowerCase());\n },\n\n // Trigger an event of the given name\n // A return value of `false` interrupts the callback chain\n // Returns false if execution was interrupted\n trigger: function (name, target, extraArg) {\n target = target || this;\n var queue = this._listeners && this._listeners[name];\n var result;\n var parentResult;\n if (queue) {\n for (var i = queue.length; i--; ) {\n result = queue[i].call(target, target, extraArg);\n if (result === false) return result;\n }\n }\n if (this.parent) {\n return this.parent.trigger(name, target, extraArg);\n }\n return true;\n },\n\n // Reset UI\n reset: function () {\n // Field case: just emit a reset event for UI\n if ('ParsleyForm' !== this.__class__) {\n this._resetUI();\n return this._trigger('reset');\n }\n\n // Form case: emit a reset event for each field\n for (var i = 0; i < this.fields.length; i++)\n this.fields[i].reset();\n\n this._trigger('reset');\n },\n\n // Destroy Parsley instance (+ UI)\n destroy: function () {\n // Field case: emit destroy event to clean UI and then destroy stored instance\n this._destroyUI();\n if ('ParsleyForm' !== this.__class__) {\n this.$element.removeData('Parsley');\n this.$element.removeData('ParsleyFieldMultiple');\n this._trigger('destroy');\n\n return;\n }\n\n // Form case: destroy all its fields and then destroy stored instance\n for (var i = 0; i < this.fields.length; i++)\n this.fields[i].destroy();\n\n this.$element.removeData('Parsley');\n this._trigger('destroy');\n },\n\n asyncIsValid: function (group, force) {\n ParsleyUtils__default.warnOnce(\"asyncIsValid is deprecated; please use whenValid instead\");\n return this.whenValid({group, force});\n },\n\n _findRelated: function () {\n return this.options.multiple ?\n this.parent.$element.find(`[${this.options.namespace}multiple=\"${this.options.multiple}\"]`)\n : this.$element;\n }\n };\n\n var requirementConverters = {\n string: function(string) {\n return string;\n },\n integer: function(string) {\n if (isNaN(string))\n throw 'Requirement is not an integer: \"' + string + '\"';\n return parseInt(string, 10);\n },\n number: function(string) {\n if (isNaN(string))\n throw 'Requirement is not a number: \"' + string + '\"';\n return parseFloat(string);\n },\n reference: function(string) { // Unused for now\n var result = $(string);\n if (result.length === 0)\n throw 'No such reference: \"' + string + '\"';\n return result;\n },\n boolean: function(string) {\n return string !== 'false';\n },\n object: function(string) {\n return ParsleyUtils__default.deserializeValue(string);\n },\n regexp: function(regexp) {\n var flags = '';\n\n // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern\n if (/^\\/.*\\/(?:[gimy]*)$/.test(regexp)) {\n // Replace the regexp literal string with the first match group: ([gimy]*)\n // If no flag is present, this will be a blank string\n flags = regexp.replace(/.*\\/([gimy]*)$/, '$1');\n // Again, replace the regexp literal string with the first match group:\n // everything excluding the opening and closing slashes and the flags\n regexp = regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');\n } else {\n // Anchor regexp:\n regexp = '^' + regexp + '$';\n }\n return new RegExp(regexp, flags);\n }\n };\n\n var convertArrayRequirement = function(string, length) {\n var m = string.match(/^\\s*\\[(.*)\\]\\s*$/);\n if (!m)\n throw 'Requirement is not an array: \"' + string + '\"';\n var values = m[1].split(',').map(ParsleyUtils__default.trimString);\n if (values.length !== length)\n throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';\n return values;\n };\n\n var convertRequirement = function(requirementType, string) {\n var converter = requirementConverters[requirementType || 'string'];\n if (!converter)\n throw 'Unknown requirement specification: \"' + requirementType + '\"';\n return converter(string);\n };\n\n var convertExtraOptionRequirement = function(requirementSpec, string, extraOptionReader) {\n var main = null;\n var extra = {};\n for (var key in requirementSpec) {\n if (key) {\n var value = extraOptionReader(key);\n if ('string' === typeof value)\n value = convertRequirement(requirementSpec[key], value);\n extra[key] = value;\n } else {\n main = convertRequirement(requirementSpec[key], string);\n }\n }\n return [main, extra];\n };\n\n // A Validator needs to implement the methods `validate` and `parseRequirements`\n\n var ParsleyValidator = function(spec) {\n $.extend(true, this, spec);\n };\n\n ParsleyValidator.prototype = {\n // Returns `true` iff the given `value` is valid according the given requirements.\n validate: function(value, requirementFirstArg) {\n if (this.fn) { // Legacy style validator\n\n if (arguments.length > 3) // If more args then value, requirement, instance...\n requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest\n return this.fn.call(this, value, requirementFirstArg);\n }\n\n if ($.isArray(value)) {\n if (!this.validateMultiple)\n throw 'Validator `' + this.name + '` does not handle multiple values';\n return this.validateMultiple(...arguments);\n } else {\n if (this.validateNumber) {\n if (isNaN(value))\n return false;\n arguments[0] = parseFloat(arguments[0]);\n return this.validateNumber(...arguments);\n }\n if (this.validateString) {\n return this.validateString(...arguments);\n }\n throw 'Validator `' + this.name + '` only handles multiple values';\n }\n },\n\n // Parses `requirements` into an array of arguments,\n // according to `this.requirementType`\n parseRequirements: function(requirements, extraOptionReader) {\n if ('string' !== typeof requirements) {\n // Assume requirement already parsed\n // but make sure we return an array\n return $.isArray(requirements) ? requirements : [requirements];\n }\n var type = this.requirementType;\n if ($.isArray(type)) {\n var values = convertArrayRequirement(requirements, type.length);\n for (var i = 0; i < values.length; i++)\n values[i] = convertRequirement(type[i], values[i]);\n return values;\n } else if ($.isPlainObject(type)) {\n return convertExtraOptionRequirement(type, requirements, extraOptionReader);\n } else {\n return [convertRequirement(type, requirements)];\n }\n },\n // Defaults:\n requirementType: 'string',\n\n priority: 2\n\n };\n\n var ParsleyValidatorRegistry = function (validators, catalog) {\n this.__class__ = 'ParsleyValidatorRegistry';\n\n // Default Parsley locale is en\n this.locale = 'en';\n\n this.init(validators || {}, catalog || {});\n };\n\n var typeRegexes = {\n email: /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i,\n\n // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers\n number: /^-?(\\d*\\.)?\\d+(e[-+]?\\d+)?$/i,\n\n integer: /^-?\\d+$/,\n\n digits: /^\\d+$/,\n\n alphanum: /^\\w+$/i,\n\n url: new RegExp(\n \"^\" +\n // protocol identifier\n \"(?:(?:https?|ftp)://)?\" + // ** mod: make scheme optional\n // user:pass authentication\n \"(?:\\\\S+(?::\\\\S*)?@)?\" +\n \"(?:\" +\n // IP address exclusion\n // private & local networks\n // \"(?!(?:10|127)(?:\\\\.\\\\d{1,3}){3})\" + // ** mod: allow local networks\n // \"(?!(?:169\\\\.254|192\\\\.168)(?:\\\\.\\\\d{1,3}){2})\" + // ** mod: allow local networks\n // \"(?!172\\\\.(?:1[6-9]|2\\\\d|3[0-1])(?:\\\\.\\\\d{1,3}){2})\" + // ** mod: allow local networks\n // IP address dotted notation octets\n // excludes loopback network 0.0.0.0\n // excludes reserved space >= 224.0.0.0\n // excludes network & broacast addresses\n // (first & last IP address of each class)\n \"(?:[1-9]\\\\d?|1\\\\d\\\\d|2[01]\\\\d|22[0-3])\" +\n \"(?:\\\\.(?:1?\\\\d{1,2}|2[0-4]\\\\d|25[0-5])){2}\" +\n \"(?:\\\\.(?:[1-9]\\\\d?|1\\\\d\\\\d|2[0-4]\\\\d|25[0-4]))\" +\n \"|\" +\n // host name\n \"(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)\" +\n // domain name\n \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*\" +\n // TLD identifier\n \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,}))\" +\n \")\" +\n // port number\n \"(?::\\\\d{2,5})?\" +\n // resource path\n \"(?:/\\\\S*)?\" +\n \"$\", 'i'\n )\n };\n typeRegexes.range = typeRegexes.number;\n\n // See http://stackoverflow.com/a/10454560/8279\n var decimalPlaces = num => {\n var match = ('' + num).match(/(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/);\n if (!match) { return 0; }\n return Math.max(\n 0,\n // Number of digits right of decimal point.\n (match[1] ? match[1].length : 0) -\n // Adjust for scientific notation.\n (match[2] ? +match[2] : 0));\n };\n\n ParsleyValidatorRegistry.prototype = {\n init: function (validators, catalog) {\n this.catalog = catalog;\n // Copy prototype's validators:\n this.validators = $.extend({}, this.validators);\n\n for (var name in validators)\n this.addValidator(name, validators[name].fn, validators[name].priority);\n\n window.Parsley.trigger('parsley:validator:init');\n },\n\n // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n\n setLocale: function (locale) {\n if ('undefined' === typeof this.catalog[locale])\n throw new Error(locale + ' is not available in the catalog');\n\n this.locale = locale;\n\n return this;\n },\n\n // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`\n addCatalog: function (locale, messages, set) {\n if ('object' === typeof messages)\n this.catalog[locale] = messages;\n\n if (true === set)\n return this.setLocale(locale);\n\n return this;\n },\n\n // Add a specific message for a given constraint in a given locale\n addMessage: function (locale, name, message) {\n if ('undefined' === typeof this.catalog[locale])\n this.catalog[locale] = {};\n\n this.catalog[locale][name] = message;\n\n return this;\n },\n\n // Add messages for a given locale\n addMessages: function (locale, nameMessageObject) {\n for (var name in nameMessageObject)\n this.addMessage(locale, name, nameMessageObject[name]);\n\n return this;\n },\n\n // Add a new validator\n //\n // addValidator('custom', {\n // requirementType: ['integer', 'integer'],\n // validateString: function(value, from, to) {},\n // priority: 22,\n // messages: {\n // en: \"Hey, that's no good\",\n // fr: \"Aye aye, pas bon du tout\",\n // }\n // })\n //\n // Old API was addValidator(name, function, priority)\n //\n addValidator: function (name, arg1, arg2) {\n if (this.validators[name])\n ParsleyUtils__default.warn('Validator \"' + name + '\" is already defined.');\n else if (ParsleyDefaults.hasOwnProperty(name)) {\n ParsleyUtils__default.warn('\"' + name + '\" is a restricted keyword and is not a valid validator name.');\n return;\n }\n return this._setValidator(...arguments);\n },\n\n updateValidator: function (name, arg1, arg2) {\n if (!this.validators[name]) {\n ParsleyUtils__default.warn('Validator \"' + name + '\" is not already defined.');\n return this.addValidator(...arguments);\n }\n return this._setValidator(this, arguments);\n },\n\n removeValidator: function (name) {\n if (!this.validators[name])\n ParsleyUtils__default.warn('Validator \"' + name + '\" is not defined.');\n\n delete this.validators[name];\n\n return this;\n },\n\n _setValidator: function (name, validator, priority) {\n if ('object' !== typeof validator) {\n // Old style validator, with `fn` and `priority`\n validator = {\n fn: validator,\n priority: priority\n };\n }\n if (!validator.validate) {\n validator = new ParsleyValidator(validator);\n }\n this.validators[name] = validator;\n\n for (var locale in validator.messages || {})\n this.addMessage(locale, name, validator.messages[locale]);\n\n return this;\n },\n\n getErrorMessage: function (constraint) {\n var message;\n\n // Type constraints are a bit different, we have to match their requirements too to find right error message\n if ('type' === constraint.name) {\n var typeMessages = this.catalog[this.locale][constraint.name] || {};\n message = typeMessages[constraint.requirements];\n } else\n message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);\n\n return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;\n },\n\n // Kind of light `sprintf()` implementation\n formatMessage: function (string, parameters) {\n if ('object' === typeof parameters) {\n for (var i in parameters)\n string = this.formatMessage(string, parameters[i]);\n\n return string;\n }\n\n return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';\n },\n\n // Here is the Parsley default validators list.\n // A validator is an object with the following key values:\n // - priority: an integer\n // - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these\n // - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise\n // Alternatively, a validator can be a function that returns such an object\n //\n validators: {\n notblank: {\n validateString: function(value) {\n return /\\S/.test(value);\n },\n priority: 2\n },\n required: {\n validateMultiple: function(values) {\n return values.length > 0;\n },\n validateString: function(value) {\n return /\\S/.test(value);\n },\n priority: 512\n },\n type: {\n validateString: function(value, type, {step = '1', base = 0} = {}) {\n var regex = typeRegexes[type];\n if (!regex) {\n throw new Error('validator type `' + type + '` is not supported');\n }\n if (!regex.test(value))\n return false;\n if ('number' === type) {\n if (!/^any$/i.test(step || '')) {\n var nb = Number(value);\n var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));\n if (decimalPlaces(nb) > decimals) // Value can't have too many decimals\n return false;\n // Be careful of rounding errors by using integers.\n var toInt = f => { return Math.round(f * Math.pow(10, decimals)); };\n if ((toInt(nb) - toInt(base)) % toInt(step) != 0)\n return false;\n }\n }\n return true;\n },\n requirementType: {\n '': 'string',\n step: 'string',\n base: 'number'\n },\n priority: 256\n },\n pattern: {\n validateString: function(value, regexp) {\n return regexp.test(value);\n },\n requirementType: 'regexp',\n priority: 64\n },\n minlength: {\n validateString: function (value, requirement) {\n return value.length >= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n maxlength: {\n validateString: function (value, requirement) {\n return value.length <= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n length: {\n validateString: function (value, min, max) {\n return value.length >= min && value.length <= max;\n },\n requirementType: ['integer', 'integer'],\n priority: 30\n },\n mincheck: {\n validateMultiple: function (values, requirement) {\n return values.length >= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n maxcheck: {\n validateMultiple: function (values, requirement) {\n return values.length <= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n check: {\n validateMultiple: function (values, min, max) {\n return values.length >= min && values.length <= max;\n },\n requirementType: ['integer', 'integer'],\n priority: 30\n },\n min: {\n validateNumber: function (value, requirement) {\n return value >= requirement;\n },\n requirementType: 'number',\n priority: 30\n },\n max: {\n validateNumber: function (value, requirement) {\n return value <= requirement;\n },\n requirementType: 'number',\n priority: 30\n },\n range: {\n validateNumber: function (value, min, max) {\n return value >= min && value <= max;\n },\n requirementType: ['number', 'number'],\n priority: 30\n },\n equalto: {\n validateString: function (value, refOrValue) {\n var $reference = $(refOrValue);\n if ($reference.length)\n return value === $reference.val();\n else\n return value === refOrValue;\n },\n priority: 256\n }\n }\n };\n\n var ParsleyUI = {};\n\n var diffResults = function (newResult, oldResult, deep) {\n var added = [];\n var kept = [];\n\n for (var i = 0; i < newResult.length; i++) {\n var found = false;\n\n for (var j = 0; j < oldResult.length; j++)\n if (newResult[i].assert.name === oldResult[j].assert.name) {\n found = true;\n break;\n }\n\n if (found)\n kept.push(newResult[i]);\n else\n added.push(newResult[i]);\n }\n\n return {\n kept: kept,\n added: added,\n removed: !deep ? diffResults(oldResult, newResult, true).added : []\n };\n };\n\n ParsleyUI.Form = {\n\n _actualizeTriggers: function () {\n this.$element.on('submit.Parsley', evt => { this.onSubmitValidate(evt); });\n this.$element.on('click.Parsley', 'input[type=\"submit\"], button[type=\"submit\"]', evt => { this.onSubmitButton(evt); });\n\n // UI could be disabled\n if (false === this.options.uiEnabled)\n return;\n\n this.$element.attr('novalidate', '');\n },\n\n focus: function () {\n this._focusedField = null;\n\n if (true === this.validationResult || 'none' === this.options.focus)\n return null;\n\n for (var i = 0; i < this.fields.length; i++) {\n var field = this.fields[i];\n if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {\n this._focusedField = field.$element;\n if ('first' === this.options.focus)\n break;\n }\n }\n\n if (null === this._focusedField)\n return null;\n\n return this._focusedField.focus();\n },\n\n _destroyUI: function () {\n // Reset all event listeners\n this.$element.off('.Parsley');\n }\n\n };\n\n ParsleyUI.Field = {\n\n _reflowUI: function () {\n this._buildUI();\n\n // If this field doesn't have an active UI don't bother doing something\n if (!this._ui)\n return;\n\n // Diff between two validation results\n var diff = diffResults(this.validationResult, this._ui.lastValidationResult);\n\n // Then store current validation result for next reflow\n this._ui.lastValidationResult = this.validationResult;\n\n // Handle valid / invalid / none field class\n this._manageStatusClass();\n\n // Add, remove, updated errors messages\n this._manageErrorsMessages(diff);\n\n // Triggers impl\n this._actualizeTriggers();\n\n // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user\n if ((diff.kept.length || diff.added.length) && !this._failedOnce) {\n this._failedOnce = true;\n this._actualizeTriggers();\n }\n },\n\n // Returns an array of field's error message(s)\n getErrorsMessages: function () {\n // No error message, field is valid\n if (true === this.validationResult)\n return [];\n\n var messages = [];\n\n for (var i = 0; i < this.validationResult.length; i++)\n messages.push(this.validationResult[i].errorMessage ||\n this._getErrorMessage(this.validationResult[i].assert));\n\n return messages;\n },\n\n // It's a goal of Parsley that this method is no longer required [#1073]\n addError: function (name, {message, assert, updateClass = true} = {}) {\n this._buildUI();\n this._addError(name, {message, assert});\n\n if (updateClass)\n this._errorClass();\n },\n\n // It's a goal of Parsley that this method is no longer required [#1073]\n updateError: function (name, {message, assert, updateClass = true} = {}) {\n this._buildUI();\n this._updateError(name, {message, assert});\n\n if (updateClass)\n this._errorClass();\n },\n\n // It's a goal of Parsley that this method is no longer required [#1073]\n removeError: function (name, {updateClass = true} = {}) {\n this._buildUI();\n this._removeError(name);\n\n // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult\n // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.\n if (updateClass)\n this._manageStatusClass();\n },\n\n _manageStatusClass: function () {\n if (this.hasConstraints() && this.needsValidation() && true === this.validationResult)\n this._successClass();\n else if (this.validationResult.length > 0)\n this._errorClass();\n else\n this._resetClass();\n },\n\n _manageErrorsMessages: function (diff) {\n if ('undefined' !== typeof this.options.errorsMessagesDisabled)\n return;\n\n // Case where we have errorMessage option that configure an unique field error message, regardless failing validators\n if ('undefined' !== typeof this.options.errorMessage) {\n if ((diff.added.length || diff.kept.length)) {\n this._insertErrorWrapper();\n\n if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length)\n this._ui.$errorsWrapper\n .append(\n $(this.options.errorTemplate)\n .addClass('parsley-custom-error-message')\n );\n\n return this._ui.$errorsWrapper\n .addClass('filled')\n .find('.parsley-custom-error-message')\n .html(this.options.errorMessage);\n }\n\n return this._ui.$errorsWrapper\n .removeClass('filled')\n .find('.parsley-custom-error-message')\n .remove();\n }\n\n // Show, hide, update failing constraints messages\n for (var i = 0; i < diff.removed.length; i++)\n this._removeError(diff.removed[i].assert.name);\n\n for (i = 0; i < diff.added.length; i++)\n this._addError(diff.added[i].assert.name, {message: diff.added[i].errorMessage, assert: diff.added[i].assert});\n\n for (i = 0; i < diff.kept.length; i++)\n this._updateError(diff.kept[i].assert.name, {message: diff.kept[i].errorMessage, assert: diff.kept[i].assert});\n },\n\n\n _addError: function (name, {message, assert}) {\n this._insertErrorWrapper();\n this._ui.$errorsWrapper\n .addClass('filled')\n .append(\n $(this.options.errorTemplate)\n .addClass('parsley-' + name)\n .html(message || this._getErrorMessage(assert))\n );\n },\n\n _updateError: function (name, {message, assert}) {\n this._ui.$errorsWrapper\n .addClass('filled')\n .find('.parsley-' + name)\n .html(message || this._getErrorMessage(assert));\n },\n\n _removeError: function (name) {\n this._ui.$errorsWrapper\n .removeClass('filled')\n .find('.parsley-' + name)\n .remove();\n },\n\n _getErrorMessage: function (constraint) {\n var customConstraintErrorMessage = constraint.name + 'Message';\n\n if ('undefined' !== typeof this.options[customConstraintErrorMessage])\n return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);\n\n return window.Parsley.getErrorMessage(constraint);\n },\n\n _buildUI: function () {\n // UI could be already built or disabled\n if (this._ui || false === this.options.uiEnabled)\n return;\n\n var _ui = {};\n\n // Give field its Parsley id in DOM\n this.$element.attr(this.options.namespace + 'id', this.__id__);\n\n /** Generate important UI elements and store them in this **/\n // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes\n _ui.$errorClassHandler = this._manageClassHandler();\n\n // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer\n _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);\n _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);\n\n // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly\n _ui.lastValidationResult = [];\n _ui.validationInformationVisible = false;\n\n // Store it in this for later\n this._ui = _ui;\n },\n\n // Determine which element will have `parsley-error` and `parsley-success` classes\n _manageClassHandler: function () {\n // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`\n if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length)\n return $(this.options.classHandler);\n\n // Class handled could also be determined by function given in Parsley options\n var $handler = this.options.classHandler.call(this, this);\n\n // If this function returned a valid existing DOM element, go for it\n if ('undefined' !== typeof $handler && $handler.length)\n return $handler;\n\n // Otherwise, if simple element (input, texatrea, select...) it will perfectly host the classes\n if (!this.options.multiple || this.$element.is('select'))\n return this.$element;\n\n // But if multiple element (radio, checkbox), that would be their parent\n return this.$element.parent();\n },\n\n _insertErrorWrapper: function () {\n var $errorsContainer;\n\n // Nothing to do if already inserted\n if (0 !== this._ui.$errorsWrapper.parent().length)\n return this._ui.$errorsWrapper.parent();\n\n if ('string' === typeof this.options.errorsContainer) {\n if ($(this.options.errorsContainer).length)\n return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);\n else\n ParsleyUtils__default.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');\n } else if ('function' === typeof this.options.errorsContainer)\n $errorsContainer = this.options.errorsContainer.call(this, this);\n\n if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)\n return $errorsContainer.append(this._ui.$errorsWrapper);\n\n var $from = this.$element;\n if (this.options.multiple)\n $from = $from.parent();\n return $from.after(this._ui.$errorsWrapper);\n },\n\n _actualizeTriggers: function () {\n var $toBind = this._findRelated();\n\n // Remove Parsley events already bound on this field\n $toBind.off('.Parsley');\n if (this._failedOnce)\n $toBind.on(ParsleyUtils__default.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), () => {\n this.validate();\n });\n else {\n $toBind.on(ParsleyUtils__default.namespaceEvents(this.options.trigger, 'Parsley'), event => {\n this._eventValidate(event);\n });\n }\n },\n\n _eventValidate: function (event) {\n // For keyup, keypress, keydown, input... events that could be a little bit obstrusive\n // do not validate if val length < min threshold on first validation. Once field have been validated once and info\n // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.\n if (/key|input/.test(event.type))\n if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold)\n return;\n\n this.validate();\n },\n\n _resetUI: function () {\n // Reset all event listeners\n this._failedOnce = false;\n this._actualizeTriggers();\n\n // Nothing to do if UI never initialized for this field\n if ('undefined' === typeof this._ui)\n return;\n\n // Reset all errors' li\n this._ui.$errorsWrapper\n .removeClass('filled')\n .children()\n .remove();\n\n // Reset validation class\n this._resetClass();\n\n // Reset validation flags and last validation result\n this._ui.lastValidationResult = [];\n this._ui.validationInformationVisible = false;\n },\n\n _destroyUI: function () {\n this._resetUI();\n\n if ('undefined' !== typeof this._ui)\n this._ui.$errorsWrapper.remove();\n\n delete this._ui;\n },\n\n _successClass: function () {\n this._ui.validationInformationVisible = true;\n this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);\n },\n _errorClass: function () {\n this._ui.validationInformationVisible = true;\n this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);\n },\n _resetClass: function () {\n this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);\n }\n };\n\n var ParsleyForm = function (element, domOptions, options) {\n this.__class__ = 'ParsleyForm';\n this.__id__ = ParsleyUtils__default.generateID();\n\n this.$element = $(element);\n this.domOptions = domOptions;\n this.options = options;\n this.parent = window.Parsley;\n\n this.fields = [];\n this.validationResult = null;\n };\n\n var ParsleyForm__statusMapping = {pending: null, resolved: true, rejected: false};\n\n ParsleyForm.prototype = {\n onSubmitValidate: function (event) {\n // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior\n if (true === event.parsley)\n return;\n\n // If we didn't come here through a submit button, use the first one in the form\n var $submitSource = this._$submitSource || this.$element.find('input[type=\"submit\"], button[type=\"submit\"]').first();\n this._$submitSource = null;\n this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);\n if ($submitSource.is('[formnovalidate]'))\n return;\n\n var promise = this.whenValidate({event});\n\n if ('resolved' === promise.state() && false !== this._trigger('submit')) {\n // All good, let event go through. We make this distinction because browsers\n // differ in their handling of `submit` being called from inside a submit event [#1047]\n } else {\n // Rejected or pending: cancel this submit\n event.stopImmediatePropagation();\n event.preventDefault();\n if ('pending' === promise.state())\n promise.done(() => { this._submit($submitSource); });\n }\n },\n\n onSubmitButton: function(event) {\n this._$submitSource = $(event.target);\n },\n // internal\n // _submit submits the form, this time without going through the validations.\n // Care must be taken to \"fake\" the actual submit button being clicked.\n _submit: function ($submitSource) {\n if (false === this._trigger('submit'))\n return;\n // Add submit button's data\n if ($submitSource) {\n var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);\n if (0 === $synthetic.length)\n $synthetic = $('').appendTo(this.$element);\n $synthetic.attr({\n name: $submitSource.attr('name'),\n value: $submitSource.attr('value')\n });\n }\n\n this.$element.trigger($.extend($.Event('submit'), {parsley: true}));\n },\n\n // Performs validation on fields while triggering events.\n // @returns `true` if all validations succeeds, `false`\n // if a failure is immediately detected, or `null`\n // if dependant on a promise.\n // Consider using `whenValidate` instead.\n validate: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils__default.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');\n var [group, force, event] = arguments;\n options = {group, force, event};\n }\n return ParsleyForm__statusMapping[ this.whenValidate(options).state() ];\n },\n\n whenValidate: function ({group, force, event} = {}) {\n this.submitEvent = event;\n if (event) {\n this.submitEvent = $.extend({}, event, {preventDefault: () => {\n ParsleyUtils__default.warnOnce(\"Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`\");\n this.validationResult = false;\n }});\n }\n this.validationResult = true;\n\n // fire validate event to eventually modify things before very validation\n this._trigger('validate');\n\n // Refresh form DOM options and form's fields that could have changed\n this._refreshFields();\n\n var promises = this._withoutReactualizingFormOptions(() => {\n return $.map(this.fields, field => {\n return field.whenValidate({force, group});\n });\n });\n\n var promiseBasedOnValidationResult = () => {\n var r = $.Deferred();\n if (false === this.validationResult)\n r.reject();\n return r.resolve().promise();\n };\n\n return $.when(...promises)\n .done( () => { this._trigger('success'); })\n .fail( () => {\n this.validationResult = false;\n this.focus();\n this._trigger('error');\n })\n .always(() => { this._trigger('validated'); })\n .pipe( promiseBasedOnValidationResult, promiseBasedOnValidationResult);\n },\n\n // Iterate over refreshed fields, and stop on first failure.\n // Returns `true` if all fields are valid, `false` if a failure is detected\n // or `null` if the result depends on an unresolved promise.\n // Prefer using `whenValid` instead.\n isValid: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils__default.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');\n var [group, force] = arguments;\n options = {group, force};\n }\n return ParsleyForm__statusMapping[ this.whenValid(options).state() ];\n },\n\n // Iterate over refreshed fields and validate them.\n // Returns a promise.\n // A validation that immediately fails will interrupt the validations.\n whenValid: function ({group, force} = {}) {\n this._refreshFields();\n\n var promises = this._withoutReactualizingFormOptions(() => {\n return $.map(this.fields, field => {\n return field.whenValid({group, force});\n });\n });\n return $.when(...promises);\n },\n\n _refreshFields: function () {\n return this.actualizeOptions()._bindFields();\n },\n\n _bindFields: function () {\n var oldFields = this.fields;\n\n this.fields = [];\n this.fieldsMappedById = {};\n\n this._withoutReactualizingFormOptions(() => {\n this.$element\n .find(this.options.inputs)\n .not(this.options.excluded)\n .each((_, element) => {\n var fieldInstance = new window.Parsley.Factory(element, {}, this);\n\n // Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children\n if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && (true !== fieldInstance.options.excluded))\n if ('undefined' === typeof this.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {\n this.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;\n this.fields.push(fieldInstance);\n }\n });\n\n $(oldFields).not(this.fields).each((_, field) => {\n field._trigger('reset');\n });\n });\n return this;\n },\n\n // Internal only.\n // Looping on a form's fields to do validation or similar\n // will trigger reactualizing options on all of them, which\n // in turn will reactualize the form's options.\n // To avoid calling actualizeOptions so many times on the form\n // for nothing, _withoutReactualizingFormOptions temporarily disables\n // the method actualizeOptions on this form while `fn` is called.\n _withoutReactualizingFormOptions: function (fn) {\n var oldActualizeOptions = this.actualizeOptions;\n this.actualizeOptions = function () { return this; };\n var result = fn();\n this.actualizeOptions = oldActualizeOptions;\n return result;\n },\n\n // Internal only.\n // Shortcut to trigger an event\n // Returns true iff event is not interrupted and default not prevented.\n _trigger: function (eventName) {\n return this.trigger('form:' + eventName);\n }\n\n };\n\n var ConstraintFactory = function (parsleyField, name, requirements, priority, isDomConstraint) {\n if (!/ParsleyField/.test(parsleyField.__class__))\n throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');\n\n var validatorSpec = window.Parsley._validatorRegistry.validators[name];\n var validator = new ParsleyValidator(validatorSpec);\n\n $.extend(this, {\n validator: validator,\n name: name,\n requirements: requirements,\n priority: priority || parsleyField.options[name + 'Priority'] || validator.priority,\n isDomConstraint: true === isDomConstraint\n });\n this._parseRequirements(parsleyField.options);\n };\n\n var capitalize = function(str) {\n var cap = str[0].toUpperCase();\n return cap + str.slice(1);\n };\n\n ConstraintFactory.prototype = {\n validate: function(value, instance) {\n var args = this.requirementList.slice(0); // Make copy\n args.unshift(value);\n args.push(instance);\n return this.validator.validate.apply(this.validator, args);\n },\n\n _parseRequirements: function(options) {\n this.requirementList = this.validator.parseRequirements(this.requirements, key => {\n return options[this.name + capitalize(key)];\n });\n }\n };\n\n var ParsleyField = function (field, domOptions, options, parsleyFormInstance) {\n this.__class__ = 'ParsleyField';\n this.__id__ = ParsleyUtils__default.generateID();\n\n this.$element = $(field);\n\n // Set parent if we have one\n if ('undefined' !== typeof parsleyFormInstance) {\n this.parent = parsleyFormInstance;\n }\n\n this.options = options;\n this.domOptions = domOptions;\n\n // Initialize some properties\n this.constraints = [];\n this.constraintsByName = {};\n this.validationResult = [];\n\n // Bind constraints\n this._bindConstraints();\n };\n\n var parsley_field__statusMapping = {pending: null, resolved: true, rejected: false};\n\n ParsleyField.prototype = {\n // # Public API\n // Validate field and trigger some events for mainly `ParsleyUI`\n // @returns `true`, an array of the validators that failed, or\n // `null` if validation is not finished. Prefer using whenValidate\n validate: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils__default.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');\n options = {options};\n }\n var promise = this.whenValidate(options);\n if (!promise) // If excluded with `group` option\n return true;\n switch (promise.state()) {\n case 'pending': return null;\n case 'resolved': return true;\n case 'rejected': return this.validationResult;\n }\n },\n\n // Validate field and trigger some events for mainly `ParsleyUI`\n // @returns a promise that succeeds only when all validations do\n // or `undefined` if field is not in the given `group`.\n whenValidate: function ({force, group} = {}) {\n // do not validate a field if not the same as given validation group\n this.refreshConstraints();\n if (group && !this._isInGroup(group))\n return;\n\n this.value = this.getValue();\n\n // Field Validate event. `this.value` could be altered for custom needs\n this._trigger('validate');\n\n return this.whenValid({force, value: this.value, _refreshed: true})\n .always(() => { this._reflowUI(); })\n .done(() => { this._trigger('success'); })\n .fail(() => { this._trigger('error'); })\n .always(() => { this._trigger('validated'); });\n },\n\n hasConstraints: function () {\n return 0 !== this.constraints.length;\n },\n\n // An empty optional field does not need validation\n needsValidation: function (value) {\n if ('undefined' === typeof value)\n value = this.getValue();\n\n // If a field is empty and not required, it is valid\n // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators\n if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty)\n return false;\n\n return true;\n },\n\n _isInGroup: function (group) {\n if ($.isArray(this.options.group))\n return -1 !== $.inArray(group, this.options.group);\n return this.options.group === group;\n },\n\n // Just validate field. Do not trigger any event.\n // Returns `true` iff all constraints pass, `false` if there are failures,\n // or `null` if the result can not be determined yet (depends on a promise)\n // See also `whenValid`.\n isValid: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils__default.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');\n var [force, value] = arguments;\n options = {force, value};\n }\n var promise = this.whenValid(options);\n if (!promise) // Excluded via `group`\n return true;\n return parsley_field__statusMapping[promise.state()];\n },\n\n // Just validate field. Do not trigger any event.\n // @returns a promise that succeeds only when all validations do\n // or `undefined` if the field is not in the given `group`.\n // The argument `force` will force validation of empty fields.\n // If a `value` is given, it will be validated instead of the value of the input.\n whenValid: function ({force = false, value, group, _refreshed} = {}) {\n // Recompute options and rebind constraints to have latest changes\n if (!_refreshed)\n this.refreshConstraints();\n // do not validate a field if not the same as given validation group\n if (group && !this._isInGroup(group))\n return;\n\n this.validationResult = true;\n\n // A field without constraint is valid\n if (!this.hasConstraints())\n return $.when();\n\n // Value could be passed as argument, needed to add more power to 'parsley:field:validate'\n if ('undefined' === typeof value || null === value)\n value = this.getValue();\n\n if (!this.needsValidation(value) && true !== force)\n return $.when();\n\n var groupedConstraints = this._getGroupedConstraints();\n var promises = [];\n $.each(groupedConstraints, (_, constraints) => {\n // Process one group of constraints at a time, we validate the constraints\n // and combine the promises together.\n var promise = $.when(\n ...$.map(constraints, constraint => this._validateConstraint(value, constraint))\n );\n promises.push(promise);\n if (promise.state() === 'rejected')\n return false; // Interrupt processing if a group has already failed\n });\n return $.when.apply($, promises);\n },\n\n // @returns a promise\n _validateConstraint: function(value, constraint) {\n var result = constraint.validate(value, this);\n // Map false to a failed promise\n if (false === result)\n result = $.Deferred().reject();\n // Make sure we return a promise and that we record failures\n return $.when(result).fail(errorMessage => {\n if (true === this.validationResult)\n this.validationResult = [];\n this.validationResult.push({\n assert: constraint,\n errorMessage: 'string' === typeof errorMessage && errorMessage\n });\n });\n },\n\n // @returns Parsley field computed value that could be overrided or configured in DOM\n getValue: function () {\n var value;\n\n // Value could be overriden in DOM or with explicit options\n if ('function' === typeof this.options.value)\n value = this.options.value(this);\n else if ('undefined' !== typeof this.options.value)\n value = this.options.value;\n else\n value = this.$element.val();\n\n // Handle wrong DOM or configurations\n if ('undefined' === typeof value || null === value)\n return '';\n\n return this._handleWhitespace(value);\n },\n\n // Actualize options that could have change since previous validation\n // Re-bind accordingly constraints (could be some new, removed or updated)\n refreshConstraints: function () {\n return this.actualizeOptions()._bindConstraints();\n },\n\n /**\n * Add a new constraint to a field\n *\n * @param {String} name\n * @param {Mixed} requirements optional\n * @param {Number} priority optional\n * @param {Boolean} isDomConstraint optional\n */\n addConstraint: function (name, requirements, priority, isDomConstraint) {\n\n if (window.Parsley._validatorRegistry.validators[name]) {\n var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);\n\n // if constraint already exist, delete it and push new version\n if ('undefined' !== this.constraintsByName[constraint.name])\n this.removeConstraint(constraint.name);\n\n this.constraints.push(constraint);\n this.constraintsByName[constraint.name] = constraint;\n }\n\n return this;\n },\n\n // Remove a constraint\n removeConstraint: function (name) {\n for (var i = 0; i < this.constraints.length; i++)\n if (name === this.constraints[i].name) {\n this.constraints.splice(i, 1);\n break;\n }\n delete this.constraintsByName[name];\n return this;\n },\n\n // Update a constraint (Remove + re-add)\n updateConstraint: function (name, parameters, priority) {\n return this.removeConstraint(name)\n .addConstraint(name, parameters, priority);\n },\n\n // # Internals\n\n // Internal only.\n // Bind constraints from config + options + DOM\n _bindConstraints: function () {\n var constraints = [];\n var constraintsByName = {};\n\n // clean all existing DOM constraints to only keep javascript user constraints\n for (var i = 0; i < this.constraints.length; i++)\n if (false === this.constraints[i].isDomConstraint) {\n constraints.push(this.constraints[i]);\n constraintsByName[this.constraints[i].name] = this.constraints[i];\n }\n\n this.constraints = constraints;\n this.constraintsByName = constraintsByName;\n\n // then re-add Parsley DOM-API constraints\n for (var name in this.options)\n this.addConstraint(name, this.options[name], undefined, true);\n\n // finally, bind special HTML5 constraints\n return this._bindHtml5Constraints();\n },\n\n // Internal only.\n // Bind specific HTML5 constraints to be HTML5 compliant\n _bindHtml5Constraints: function () {\n // html5 required\n if (this.$element.hasClass('required') || this.$element.attr('required'))\n this.addConstraint('required', true, undefined, true);\n\n // html5 pattern\n if ('string' === typeof this.$element.attr('pattern'))\n this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);\n\n // range\n if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max'))\n this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);\n\n // HTML5 min\n else if ('undefined' !== typeof this.$element.attr('min'))\n this.addConstraint('min', this.$element.attr('min'), undefined, true);\n\n // HTML5 max\n else if ('undefined' !== typeof this.$element.attr('max'))\n this.addConstraint('max', this.$element.attr('max'), undefined, true);\n\n\n // length\n if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength'))\n this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);\n\n // HTML5 minlength\n else if ('undefined' !== typeof this.$element.attr('minlength'))\n this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);\n\n // HTML5 maxlength\n else if ('undefined' !== typeof this.$element.attr('maxlength'))\n this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);\n\n\n // html5 types\n var type = this.$element.attr('type');\n\n if ('undefined' === typeof type)\n return this;\n\n // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise\n if ('number' === type) {\n return this.addConstraint('type', ['number', {\n step: this.$element.attr('step'),\n base: this.$element.attr('min') || this.$element.attr('value')\n }], undefined, true);\n // Regular other HTML5 supported types\n } else if (/^(email|url|range)$/i.test(type)) {\n return this.addConstraint('type', type, undefined, true);\n }\n return this;\n },\n\n // Internal only.\n // Field is required if have required constraint without `false` value\n _isRequired: function () {\n if ('undefined' === typeof this.constraintsByName.required)\n return false;\n\n return false !== this.constraintsByName.required.requirements;\n },\n\n // Internal only.\n // Shortcut to trigger an event\n _trigger: function (eventName) {\n return this.trigger('field:' + eventName);\n },\n\n // Internal only\n // Handles whitespace in a value\n // Use `data-parsley-whitespace=\"squish\"` to auto squish input value\n // Use `data-parsley-whitespace=\"trim\"` to auto trim input value\n _handleWhitespace: function (value) {\n if (true === this.options.trimValue)\n ParsleyUtils__default.warnOnce('data-parsley-trim-value=\"true\" is deprecated, please use data-parsley-whitespace=\"trim\"');\n\n if ('squish' === this.options.whitespace)\n value = value.replace(/\\s{2,}/g, ' ');\n\n if (('trim' === this.options.whitespace) || ('squish' === this.options.whitespace) || (true === this.options.trimValue))\n value = ParsleyUtils__default.trimString(value);\n\n return value;\n },\n\n // Internal only.\n // Returns the constraints, grouped by descending priority.\n // The result is thus an array of arrays of constraints.\n _getGroupedConstraints: function () {\n if (false === this.options.priorityEnabled)\n return [this.constraints];\n\n var groupedConstraints = [];\n var index = {};\n\n // Create array unique of priorities\n for (var i = 0; i < this.constraints.length; i++) {\n var p = this.constraints[i].priority;\n if (!index[p])\n groupedConstraints.push(index[p] = []);\n index[p].push(this.constraints[i]);\n }\n // Sort them by priority DESC\n groupedConstraints.sort(function (a, b) { return b[0].priority - a[0].priority; });\n\n return groupedConstraints;\n }\n\n };\n\n var parsley_field = ParsleyField;\n\n var ParsleyMultiple = function () {\n this.__class__ = 'ParsleyFieldMultiple';\n };\n\n ParsleyMultiple.prototype = {\n // Add new `$element` sibling for multiple field\n addElement: function ($element) {\n this.$elements.push($element);\n\n return this;\n },\n\n // See `ParsleyField.refreshConstraints()`\n refreshConstraints: function () {\n var fieldConstraints;\n\n this.constraints = [];\n\n // Select multiple special treatment\n if (this.$element.is('select')) {\n this.actualizeOptions()._bindConstraints();\n\n return this;\n }\n\n // Gather all constraints for each input in the multiple group\n for (var i = 0; i < this.$elements.length; i++) {\n\n // Check if element have not been dynamically removed since last binding\n if (!$('html').has(this.$elements[i]).length) {\n this.$elements.splice(i, 1);\n continue;\n }\n\n fieldConstraints = this.$elements[i].data('ParsleyFieldMultiple').refreshConstraints().constraints;\n\n for (var j = 0; j < fieldConstraints.length; j++)\n this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);\n }\n\n return this;\n },\n\n // See `ParsleyField.getValue()`\n getValue: function () {\n // Value could be overriden in DOM\n if ('function' === typeof this.options.value)\n value = this.options.value(this);\n else if ('undefined' !== typeof this.options.value)\n return this.options.value;\n\n // Radio input case\n if (this.$element.is('input[type=radio]'))\n return this._findRelated().filter(':checked').val() || '';\n\n // checkbox input case\n if (this.$element.is('input[type=checkbox]')) {\n var values = [];\n\n this._findRelated().filter(':checked').each(function () {\n values.push($(this).val());\n });\n\n return values;\n }\n\n // Select multiple case\n if (this.$element.is('select') && null === this.$element.val())\n return [];\n\n // Default case that should never happen\n return this.$element.val();\n },\n\n _init: function () {\n this.$elements = [this.$element];\n\n return this;\n }\n };\n\n var ParsleyFactory = function (element, options, parsleyFormInstance) {\n this.$element = $(element);\n\n // If the element has already been bound, returns its saved Parsley instance\n var savedparsleyFormInstance = this.$element.data('Parsley');\n if (savedparsleyFormInstance) {\n\n // If the saved instance has been bound without a ParsleyForm parent and there is one given in this call, add it\n if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {\n savedparsleyFormInstance.parent = parsleyFormInstance;\n savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);\n }\n\n return savedparsleyFormInstance;\n }\n\n // Parsley must be instantiated with a DOM element or jQuery $element\n if (!this.$element.length)\n throw new Error('You must bind Parsley on an existing element.');\n\n if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__)\n throw new Error('Parent instance must be a ParsleyForm instance');\n\n this.parent = parsleyFormInstance || window.Parsley;\n return this.init(options);\n };\n\n ParsleyFactory.prototype = {\n init: function (options) {\n this.__class__ = 'Parsley';\n this.__version__ = '2.3.5';\n this.__id__ = ParsleyUtils__default.generateID();\n\n // Pre-compute options\n this._resetOptions(options);\n\n // A ParsleyForm instance is obviously a `
      ` element but also every node that is not an input and has the `data-parsley-validate` attribute\n if (this.$element.is('form') || (ParsleyUtils__default.checkAttr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))\n return this.bind('parsleyForm');\n\n // Every other element is bound as a `ParsleyField` or `ParsleyFieldMultiple`\n return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');\n },\n\n isMultiple: function () {\n return (this.$element.is('input[type=radio], input[type=checkbox]')) || (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple'));\n },\n\n // Multiples fields are a real nightmare :(\n // Maybe some refactoring would be appreciated here...\n handleMultiple: function () {\n var name;\n var multiple;\n var parsleyMultipleInstance;\n\n // Handle multiple name\n if (this.options.multiple)\n ; // We already have our 'multiple' identifier\n else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length)\n this.options.multiple = name = this.$element.attr('name');\n else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length)\n this.options.multiple = this.$element.attr('id');\n\n // Special select multiple input\n if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {\n this.options.multiple = this.options.multiple || this.__id__;\n return this.bind('parsleyFieldMultiple');\n\n // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it\n } else if (!this.options.multiple) {\n ParsleyUtils__default.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);\n return this;\n }\n\n // Remove special chars\n this.options.multiple = this.options.multiple.replace(/(:|\\.|\\[|\\]|\\{|\\}|\\$)/g, '');\n\n // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name\n if ('undefined' !== typeof name) {\n $('input[name=\"' + name + '\"]').each((i, input) => {\n if ($(input).is('input[type=radio], input[type=checkbox]'))\n $(input).attr(this.options.namespace + 'multiple', this.options.multiple);\n });\n }\n\n // Check here if we don't already have a related multiple instance saved\n var $previouslyRelated = this._findRelated();\n for (var i = 0; i < $previouslyRelated.length; i++) {\n parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');\n if ('undefined' !== typeof parsleyMultipleInstance) {\n\n if (!this.$element.data('ParsleyFieldMultiple')) {\n parsleyMultipleInstance.addElement(this.$element);\n }\n\n break;\n }\n }\n\n // Create a secret ParsleyField instance for every multiple field. It will be stored in `data('ParsleyFieldMultiple')`\n // And will be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance\n this.bind('parsleyField', true);\n\n return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');\n },\n\n // Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`\n bind: function (type, doNotStore) {\n var parsleyInstance;\n\n switch (type) {\n case 'parsleyForm':\n parsleyInstance = $.extend(\n new ParsleyForm(this.$element, this.domOptions, this.options),\n window.ParsleyExtend\n )._bindFields();\n break;\n case 'parsleyField':\n parsleyInstance = $.extend(\n new parsley_field(this.$element, this.domOptions, this.options, this.parent),\n window.ParsleyExtend\n );\n break;\n case 'parsleyFieldMultiple':\n parsleyInstance = $.extend(\n new parsley_field(this.$element, this.domOptions, this.options, this.parent),\n new ParsleyMultiple(),\n window.ParsleyExtend\n )._init();\n break;\n default:\n throw new Error(type + 'is not a supported Parsley type');\n }\n\n if (this.options.multiple)\n ParsleyUtils__default.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);\n\n if ('undefined' !== typeof doNotStore) {\n this.$element.data('ParsleyFieldMultiple', parsleyInstance);\n\n return parsleyInstance;\n }\n\n // Store the freshly bound instance in a DOM element for later access using jQuery `data()`\n this.$element.data('Parsley', parsleyInstance);\n\n // Tell the world we have a new ParsleyForm or ParsleyField instance!\n parsleyInstance._actualizeTriggers();\n parsleyInstance._trigger('init');\n\n return parsleyInstance;\n }\n };\n\n var vernums = $.fn.jquery.split('.');\n if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {\n throw \"The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.\";\n }\n if (!vernums.forEach) {\n ParsleyUtils__default.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');\n }\n // Inherit `on`, `off` & `trigger` to Parsley:\n var Parsley = $.extend(new ParsleyAbstract(), {\n $element: $(document),\n actualizeOptions: null,\n _resetOptions: null,\n Factory: ParsleyFactory,\n version: '2.3.5'\n });\n\n // Supplement ParsleyField and Form with ParsleyAbstract\n // This way, the constructors will have access to those methods\n $.extend(parsley_field.prototype, ParsleyUI.Field, ParsleyAbstract.prototype);\n $.extend(ParsleyForm.prototype, ParsleyUI.Form, ParsleyAbstract.prototype);\n // Inherit actualizeOptions and _resetOptions:\n $.extend(ParsleyFactory.prototype, ParsleyAbstract.prototype);\n\n // ### jQuery API\n // `$('.elem').parsley(options)` or `$('.elem').psly(options)`\n $.fn.parsley = $.fn.psly = function (options) {\n if (this.length > 1) {\n var instances = [];\n\n this.each(function () {\n instances.push($(this).parsley(options));\n });\n\n return instances;\n }\n\n // Return undefined if applied to non existing DOM element\n if (!$(this).length) {\n ParsleyUtils__default.warn('You must bind Parsley on an existing element.');\n\n return;\n }\n\n return new ParsleyFactory(this, options);\n };\n\n // ### ParsleyField and ParsleyForm extension\n // Ensure the extension is now defined if it wasn't previously\n if ('undefined' === typeof window.ParsleyExtend)\n window.ParsleyExtend = {};\n\n // ### Parsley config\n // Inherit from ParsleyDefault, and copy over any existing values\n Parsley.options = $.extend(ParsleyUtils__default.objectCreate(ParsleyDefaults), window.ParsleyConfig);\n window.ParsleyConfig = Parsley.options; // Old way of accessing global options\n\n // ### Globals\n window.Parsley = window.psly = Parsley;\n window.ParsleyUtils = ParsleyUtils__default;\n\n // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley\n var registry = window.Parsley._validatorRegistry = new ParsleyValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);\n window.ParsleyValidator = {};\n $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {\n window.Parsley[method] = $.proxy(registry, method);\n window.ParsleyValidator[method] = function () {\n ParsleyUtils__default.warnOnce(`Accessing the method '${method}' through ParsleyValidator is deprecated. Simply call 'window.Parsley.${method}(...)'`);\n return window.Parsley[method](...arguments);\n };\n });\n\n // ### ParsleyUI\n // Deprecated global object\n window.Parsley.UI = ParsleyUI;\n window.ParsleyUI = {\n removeError: function (instance, name, doNotUpdateClass) {\n var updateClass = true !== doNotUpdateClass;\n ParsleyUtils__default.warnOnce(`Accessing ParsleyUI is deprecated. Call 'removeError' on the instance directly. Please comment in issue 1073 as to your need to call this method.`);\n return instance.removeError(name, {updateClass});\n },\n getErrorsMessages: function (instance) {\n ParsleyUtils__default.warnOnce(`Accessing ParsleyUI is deprecated. Call 'getErrorsMessages' on the instance directly.`);\n return instance.getErrorsMessages();\n }\n };\n $.each('addError updateError'.split(' '), function (i, method) {\n window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {\n var updateClass = true !== doNotUpdateClass;\n ParsleyUtils__default.warnOnce(`Accessing ParsleyUI is deprecated. Call '${method}' on the instance directly. Please comment in issue 1073 as to your need to call this method.`);\n return instance[method](name, {message, assert, updateClass});\n };\n });\n\n // Alleviate glaring Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=1250521\n // See also https://github.com/guillaumepotier/Parsley.js/issues/1068\n if (/firefox/i.test(navigator.userAgent)) {\n $(document).on('change', 'select', evt => {\n $(evt.target).trigger('input');\n });\n }\n\n // ### PARSLEY auto-binding\n // Prevent it by setting `ParsleyConfig.autoBind` to `false`\n if (false !== window.ParsleyConfig.autoBind) {\n $(function () {\n // Works only on `data-parsley-validate`.\n if ($('[data-parsley-validate]').length)\n $('[data-parsley-validate]').parsley();\n });\n }\n\n var o = $({});\n var deprecated = function () {\n ParsleyUtils__default.warnOnce(\"Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley\");\n };\n\n // Returns an event handler that calls `fn` with the arguments it expects\n function adapt(fn, context) {\n // Store to allow unbinding\n if (!fn.parsleyAdaptedCallback) {\n fn.parsleyAdaptedCallback = function () {\n var args = Array.prototype.slice.call(arguments, 0);\n args.unshift(this);\n fn.apply(context || o, args);\n };\n }\n return fn.parsleyAdaptedCallback;\n }\n\n var eventPrefix = 'parsley:';\n // Converts 'parsley:form:validate' into 'form:validate'\n function eventName(name) {\n if (name.lastIndexOf(eventPrefix, 0) === 0)\n return name.substr(eventPrefix.length);\n return name;\n }\n\n // $.listen is deprecated. Use Parsley.on instead.\n $.listen = function (name, callback) {\n var context;\n deprecated();\n if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {\n context = arguments[1];\n callback = arguments[2];\n }\n\n if ('function' !== typeof callback)\n throw new Error('Wrong parameters');\n\n window.Parsley.on(eventName(name), adapt(callback, context));\n };\n\n $.listenTo = function (instance, name, fn) {\n deprecated();\n if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm))\n throw new Error('Must give Parsley instance');\n\n if ('string' !== typeof name || 'function' !== typeof fn)\n throw new Error('Wrong parameters');\n\n instance.on(eventName(name), adapt(fn));\n };\n\n $.unsubscribe = function (name, fn) {\n deprecated();\n if ('string' !== typeof name || 'function' !== typeof fn)\n throw new Error('Wrong arguments');\n window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);\n };\n\n $.unsubscribeTo = function (instance, name) {\n deprecated();\n if (!(instance instanceof parsley_field) && !(instance instanceof ParsleyForm))\n throw new Error('Must give Parsley instance');\n instance.off(eventName(name));\n };\n\n $.unsubscribeAll = function (name) {\n deprecated();\n window.Parsley.off(eventName(name));\n $('form,input,textarea,select').each(function () {\n var instance = $(this).data('Parsley');\n if (instance) {\n instance.off(eventName(name));\n }\n });\n };\n\n // $.emit is deprecated. Use jQuery events instead.\n $.emit = function (name, instance) {\n deprecated();\n var instanceGiven = (instance instanceof parsley_field) || (instance instanceof ParsleyForm);\n var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);\n args.unshift(eventName(name));\n if (!instanceGiven) {\n instance = window.Parsley;\n }\n instance.trigger(...args);\n };\n\n var pubsub = {};\n\n $.extend(true, Parsley, {\n asyncValidators: {\n 'default': {\n fn: function (xhr) {\n // By default, only status 2xx are deemed successful.\n // Note: we use status instead of state() because responses with status 200\n // but invalid messages (e.g. an empty body for content type set to JSON) will\n // result in state() === 'rejected'.\n return xhr.status >= 200 && xhr.status < 300;\n },\n url: false\n },\n reverse: {\n fn: function (xhr) {\n // If reverse option is set, a failing ajax request is considered successful\n return xhr.status < 200 || xhr.status >= 300;\n },\n url: false\n }\n },\n\n addAsyncValidator: function (name, fn, url, options) {\n Parsley.asyncValidators[name] = {\n fn: fn,\n url: url || false,\n options: options || {}\n };\n\n return this;\n }\n\n });\n\n Parsley.addValidator('remote', {\n requirementType: {\n '': 'string',\n 'validator': 'string',\n 'reverse': 'boolean',\n 'options': 'object'\n },\n\n validateString: function (value, url, options, instance) {\n var data = {};\n var ajaxOptions;\n var csr;\n var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');\n\n if ('undefined' === typeof Parsley.asyncValidators[validator])\n throw new Error('Calling an undefined async validator: `' + validator + '`');\n\n url = Parsley.asyncValidators[validator].url || url;\n\n // Fill current value\n if (url.indexOf('{value}') > -1) {\n url = url.replace('{value}', encodeURIComponent(value));\n } else {\n data[instance.$element.attr('name') || instance.$element.attr('id')] = value;\n }\n\n // Merge options passed in from the function with the ones in the attribute\n var remoteOptions = $.extend(true, options.options || {} , Parsley.asyncValidators[validator].options);\n\n // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`\n ajaxOptions = $.extend(true, {}, {\n url: url,\n data: data,\n type: 'GET'\n }, remoteOptions);\n\n // Generate store key based on ajax options\n instance.trigger('field:ajaxoptions', instance, ajaxOptions);\n\n csr = $.param(ajaxOptions);\n\n // Initialise querry cache\n if ('undefined' === typeof Parsley._remoteCache)\n Parsley._remoteCache = {};\n\n // Try to retrieve stored xhr\n var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);\n\n var handleXhr = function () {\n var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);\n if (!result) // Map falsy results to rejected promise\n result = $.Deferred().reject();\n return $.when(result);\n };\n\n return xhr.then(handleXhr, handleXhr);\n },\n\n priority: -1\n });\n\n Parsley.on('form:submit', function () {\n Parsley._remoteCache = {};\n });\n\n window.ParsleyExtend.addAsyncValidator = function () {\n ParsleyUtils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');\n return Parsley.addAsyncValidator(...arguments);\n };\n\n // This is included with the Parsley library itself,\n // thus there is no use in adding it to your project.\n Parsley.addMessages('en', {\n defaultMessage: \"This value seems to be invalid.\",\n type: {\n email: \"This value should be a valid email.\",\n url: \"This value should be a valid url.\",\n number: \"This value should be a valid number.\",\n integer: \"This value should be a valid integer.\",\n digits: \"This value should be digits.\",\n alphanum: \"This value should be alphanumeric.\"\n },\n notblank: \"This value should not be blank.\",\n required: \"This value is required.\",\n pattern: \"This value seems to be invalid.\",\n min: \"This value should be greater than or equal to %s.\",\n max: \"This value should be lower than or equal to %s.\",\n range: \"This value should be between %s and %s.\",\n minlength: \"This value is too short. It should have %s characters or more.\",\n maxlength: \"This value is too long. It should have %s characters or fewer.\",\n length: \"This value length is invalid. It should be between %s and %s characters long.\",\n mincheck: \"You must select at least %s choices.\",\n maxcheck: \"You must select %s choices or fewer.\",\n check: \"You must select between %s and %s choices.\",\n equalto: \"This value should be the same.\"\n });\n\n Parsley.setLocale('en');\n\n var parsley = Parsley;\n\n return parsley;\n\n}));\n","import $ from 'jquery';\nimport ParsleyField from './field';\nimport ParsleyForm from './form';\nimport ParsleyUtils from './utils';\n\nvar o = $({});\nvar deprecated = function () {\n ParsleyUtils.warnOnce(\"Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley\");\n};\n\n// Returns an event handler that calls `fn` with the arguments it expects\nfunction adapt(fn, context) {\n // Store to allow unbinding\n if (!fn.parsleyAdaptedCallback) {\n fn.parsleyAdaptedCallback = function () {\n var args = Array.prototype.slice.call(arguments, 0);\n args.unshift(this);\n fn.apply(context || o, args);\n };\n }\n return fn.parsleyAdaptedCallback;\n}\n\nvar eventPrefix = 'parsley:';\n// Converts 'parsley:form:validate' into 'form:validate'\nfunction eventName(name) {\n if (name.lastIndexOf(eventPrefix, 0) === 0)\n return name.substr(eventPrefix.length);\n return name;\n}\n\n// $.listen is deprecated. Use Parsley.on instead.\n$.listen = function (name, callback) {\n var context;\n deprecated();\n if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {\n context = arguments[1];\n callback = arguments[2];\n }\n\n if ('function' !== typeof callback)\n throw new Error('Wrong parameters');\n\n window.Parsley.on(eventName(name), adapt(callback, context));\n};\n\n$.listenTo = function (instance, name, fn) {\n deprecated();\n if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))\n throw new Error('Must give Parsley instance');\n\n if ('string' !== typeof name || 'function' !== typeof fn)\n throw new Error('Wrong parameters');\n\n instance.on(eventName(name), adapt(fn));\n};\n\n$.unsubscribe = function (name, fn) {\n deprecated();\n if ('string' !== typeof name || 'function' !== typeof fn)\n throw new Error('Wrong arguments');\n window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);\n};\n\n$.unsubscribeTo = function (instance, name) {\n deprecated();\n if (!(instance instanceof ParsleyField) && !(instance instanceof ParsleyForm))\n throw new Error('Must give Parsley instance');\n instance.off(eventName(name));\n};\n\n$.unsubscribeAll = function (name) {\n deprecated();\n window.Parsley.off(eventName(name));\n $('form,input,textarea,select').each(function () {\n var instance = $(this).data('Parsley');\n if (instance) {\n instance.off(eventName(name));\n }\n });\n};\n\n// $.emit is deprecated. Use jQuery events instead.\n$.emit = function (name, instance) {\n deprecated();\n var instanceGiven = (instance instanceof ParsleyField) || (instance instanceof ParsleyForm);\n var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);\n args.unshift(eventName(name));\n if (!instanceGiven) {\n instance = window.Parsley;\n }\n instance.trigger(...args);\n};\n\nexport default {};\n","import $ from 'jquery';\n\nvar globalID = 1;\nvar pastWarnings = {};\n\nvar ParsleyUtils = {\n // Parsley DOM-API\n // returns object from dom attributes and values\n attr: function ($element, namespace, obj) {\n var i;\n var attribute;\n var attributes;\n var regex = new RegExp('^' + namespace, 'i');\n\n if ('undefined' === typeof obj)\n obj = {};\n else {\n // Clear all own properties. This won't affect prototype's values\n for (i in obj) {\n if (obj.hasOwnProperty(i))\n delete obj[i];\n }\n }\n\n if ('undefined' === typeof $element || 'undefined' === typeof $element[0])\n return obj;\n\n attributes = $element[0].attributes;\n for (i = attributes.length; i--; ) {\n attribute = attributes[i];\n\n if (attribute && attribute.specified && regex.test(attribute.name)) {\n obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);\n }\n }\n\n return obj;\n },\n\n checkAttr: function ($element, namespace, checkAttr) {\n return $element.is('[' + namespace + checkAttr + ']');\n },\n\n setAttr: function ($element, namespace, attr, value) {\n $element[0].setAttribute(this.dasherize(namespace + attr), String(value));\n },\n\n generateID: function () {\n return '' + globalID++;\n },\n\n /** Third party functions **/\n // Zepto deserialize function\n deserializeValue: function (value) {\n var num;\n\n try {\n return value ?\n value == \"true\" ||\n (value == \"false\" ? false :\n value == \"null\" ? null :\n !isNaN(num = Number(value)) ? num :\n /^[\\[\\{]/.test(value) ? $.parseJSON(value) :\n value)\n : value;\n } catch (e) { return value; }\n },\n\n // Zepto camelize function\n camelize: function (str) {\n return str.replace(/-+(.)?/g, function (match, chr) {\n return chr ? chr.toUpperCase() : '';\n });\n },\n\n // Zepto dasherize function\n dasherize: function (str) {\n return str.replace(/::/g, '/')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n .replace(/([a-z\\d])([A-Z])/g, '$1_$2')\n .replace(/_/g, '-')\n .toLowerCase();\n },\n\n warn: function () {\n if (window.console && 'function' === typeof window.console.warn)\n window.console.warn(...arguments);\n },\n\n warnOnce: function(msg) {\n if (!pastWarnings[msg]) {\n pastWarnings[msg] = true;\n this.warn(...arguments);\n }\n },\n\n _resetWarnings: function () {\n pastWarnings = {};\n },\n\n trimString: function(string) {\n return string.replace(/^\\s+|\\s+$/g, '');\n },\n\n namespaceEvents: function(events, namespace) {\n events = this.trimString(events || '').split(/\\s+/);\n if (!events[0])\n return '';\n return $.map(events, evt => { return `${evt}.${namespace}`; }).join(' ');\n },\n\n // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill\n objectCreate: Object.create || (function () {\n var Object = function () {};\n return function (prototype) {\n if (arguments.length > 1) {\n throw Error('Second argument not supported');\n }\n if (typeof prototype != 'object') {\n throw TypeError('Argument must be an object');\n }\n Object.prototype = prototype;\n var result = new Object();\n Object.prototype = null;\n return result;\n };\n })()\n};\n\nexport default ParsleyUtils;\n","// All these options could be overriden and specified directly in DOM using\n// `data-parsley-` default DOM-API\n// eg: `inputs` can be set in DOM using `data-parsley-inputs=\"input, textarea\"`\n// eg: `data-parsley-stop-on-first-failing-constraint=\"false\"`\n\nvar ParsleyDefaults = {\n // ### General\n\n // Default data-namespace for DOM API\n namespace: 'data-parsley-',\n\n // Supported inputs by default\n inputs: 'input, textarea, select',\n\n // Excluded inputs by default\n excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',\n\n // Stop validating field on highest priority failing constraint\n priorityEnabled: true,\n\n // ### Field only\n\n // identifier used to group together inputs (e.g. radio buttons...)\n multiple: null,\n\n // identifier (or array of identifiers) used to validate only a select group of inputs\n group: null,\n\n // ### UI\n // Enable\\Disable error messages\n uiEnabled: true,\n\n // Key events threshold before validation\n validationThreshold: 3,\n\n // Focused field on form validation error. 'first'|'last'|'none'\n focus: 'first',\n\n // event(s) that will trigger validation before first failure. eg: `input`...\n trigger: false,\n\n // event(s) that will trigger validation after first failure.\n triggerAfterFailure: 'input',\n\n // Class that would be added on every failing validation Parsley field\n errorClass: 'parsley-error',\n\n // Same for success validation\n successClass: 'parsley-success',\n\n // Return the `$element` that will receive these above success or error classes\n // Could also be (and given directly from DOM) a valid selector like `'#div'`\n classHandler: function (ParsleyField) {},\n\n // Return the `$element` where errors will be appended\n // Could also be (and given directly from DOM) a valid selector like `'#div'`\n errorsContainer: function (ParsleyField) {},\n\n // ul elem that would receive errors' list\n errorsWrapper: '
        ',\n\n // li elem that would receive error message\n errorTemplate: '
      • '\n};\n\nexport default ParsleyDefaults;\n","import $ from 'jquery';\nimport ParsleyUtils from './utils';\n\nvar ParsleyAbstract = function () {};\n\nParsleyAbstract.prototype = {\n asyncSupport: true, // Deprecated\n\n actualizeOptions: function () {\n ParsleyUtils.attr(this.$element, this.options.namespace, this.domOptions);\n if (this.parent && this.parent.actualizeOptions)\n this.parent.actualizeOptions();\n return this;\n },\n\n _resetOptions: function (initOptions) {\n this.domOptions = ParsleyUtils.objectCreate(this.parent.options);\n this.options = ParsleyUtils.objectCreate(this.domOptions);\n // Shallow copy of ownProperties of initOptions:\n for (var i in initOptions) {\n if (initOptions.hasOwnProperty(i))\n this.options[i] = initOptions[i];\n }\n this.actualizeOptions();\n },\n\n _listeners: null,\n\n // Register a callback for the given event name\n // Callback is called with context as the first argument and the `this`\n // The context is the current parsley instance, or window.Parsley if global\n // A return value of `false` will interrupt the calls\n on: function (name, fn) {\n this._listeners = this._listeners || {};\n var queue = this._listeners[name] = this._listeners[name] || [];\n queue.push(fn);\n\n return this;\n },\n\n // Deprecated. Use `on` instead\n subscribe: function(name, fn) {\n $.listenTo(this, name.toLowerCase(), fn);\n },\n\n // Unregister a callback (or all if none is given) for the given event name\n off: function (name, fn) {\n var queue = this._listeners && this._listeners[name];\n if (queue) {\n if (!fn) {\n delete this._listeners[name];\n } else {\n for (var i = queue.length; i--; )\n if (queue[i] === fn)\n queue.splice(i, 1);\n }\n }\n return this;\n },\n\n // Deprecated. Use `off`\n unsubscribe: function(name, fn) {\n $.unsubscribeTo(this, name.toLowerCase());\n },\n\n // Trigger an event of the given name\n // A return value of `false` interrupts the callback chain\n // Returns false if execution was interrupted\n trigger: function (name, target, extraArg) {\n target = target || this;\n var queue = this._listeners && this._listeners[name];\n var result;\n var parentResult;\n if (queue) {\n for (var i = queue.length; i--; ) {\n result = queue[i].call(target, target, extraArg);\n if (result === false) return result;\n }\n }\n if (this.parent) {\n return this.parent.trigger(name, target, extraArg);\n }\n return true;\n },\n\n // Reset UI\n reset: function () {\n // Field case: just emit a reset event for UI\n if ('ParsleyForm' !== this.__class__) {\n this._resetUI();\n return this._trigger('reset');\n }\n\n // Form case: emit a reset event for each field\n for (var i = 0; i < this.fields.length; i++)\n this.fields[i].reset();\n\n this._trigger('reset');\n },\n\n // Destroy Parsley instance (+ UI)\n destroy: function () {\n // Field case: emit destroy event to clean UI and then destroy stored instance\n this._destroyUI();\n if ('ParsleyForm' !== this.__class__) {\n this.$element.removeData('Parsley');\n this.$element.removeData('ParsleyFieldMultiple');\n this._trigger('destroy');\n\n return;\n }\n\n // Form case: destroy all its fields and then destroy stored instance\n for (var i = 0; i < this.fields.length; i++)\n this.fields[i].destroy();\n\n this.$element.removeData('Parsley');\n this._trigger('destroy');\n },\n\n asyncIsValid: function (group, force) {\n ParsleyUtils.warnOnce(\"asyncIsValid is deprecated; please use whenValid instead\");\n return this.whenValid({group, force});\n },\n\n _findRelated: function () {\n return this.options.multiple ?\n this.parent.$element.find(`[${this.options.namespace}multiple=\"${this.options.multiple}\"]`)\n : this.$element;\n }\n};\n\nexport default ParsleyAbstract;\n","import $ from 'jquery';\nimport ParsleyUtils from './utils';\n\nvar requirementConverters = {\n string: function(string) {\n return string;\n },\n integer: function(string) {\n if (isNaN(string))\n throw 'Requirement is not an integer: \"' + string + '\"';\n return parseInt(string, 10);\n },\n number: function(string) {\n if (isNaN(string))\n throw 'Requirement is not a number: \"' + string + '\"';\n return parseFloat(string);\n },\n reference: function(string) { // Unused for now\n var result = $(string);\n if (result.length === 0)\n throw 'No such reference: \"' + string + '\"';\n return result;\n },\n boolean: function(string) {\n return string !== 'false';\n },\n object: function(string) {\n return ParsleyUtils.deserializeValue(string);\n },\n regexp: function(regexp) {\n var flags = '';\n\n // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern\n if (/^\\/.*\\/(?:[gimy]*)$/.test(regexp)) {\n // Replace the regexp literal string with the first match group: ([gimy]*)\n // If no flag is present, this will be a blank string\n flags = regexp.replace(/.*\\/([gimy]*)$/, '$1');\n // Again, replace the regexp literal string with the first match group:\n // everything excluding the opening and closing slashes and the flags\n regexp = regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');\n } else {\n // Anchor regexp:\n regexp = '^' + regexp + '$';\n }\n return new RegExp(regexp, flags);\n }\n};\n\nvar convertArrayRequirement = function(string, length) {\n var m = string.match(/^\\s*\\[(.*)\\]\\s*$/);\n if (!m)\n throw 'Requirement is not an array: \"' + string + '\"';\n var values = m[1].split(',').map(ParsleyUtils.trimString);\n if (values.length !== length)\n throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';\n return values;\n};\n\nvar convertRequirement = function(requirementType, string) {\n var converter = requirementConverters[requirementType || 'string'];\n if (!converter)\n throw 'Unknown requirement specification: \"' + requirementType + '\"';\n return converter(string);\n};\n\nvar convertExtraOptionRequirement = function(requirementSpec, string, extraOptionReader) {\n var main = null;\n var extra = {};\n for (var key in requirementSpec) {\n if (key) {\n var value = extraOptionReader(key);\n if ('string' === typeof value)\n value = convertRequirement(requirementSpec[key], value);\n extra[key] = value;\n } else {\n main = convertRequirement(requirementSpec[key], string);\n }\n }\n return [main, extra];\n};\n\n// A Validator needs to implement the methods `validate` and `parseRequirements`\n\nvar ParsleyValidator = function(spec) {\n $.extend(true, this, spec);\n};\n\nParsleyValidator.prototype = {\n // Returns `true` iff the given `value` is valid according the given requirements.\n validate: function(value, requirementFirstArg) {\n if (this.fn) { // Legacy style validator\n\n if (arguments.length > 3) // If more args then value, requirement, instance...\n requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest\n return this.fn.call(this, value, requirementFirstArg);\n }\n\n if ($.isArray(value)) {\n if (!this.validateMultiple)\n throw 'Validator `' + this.name + '` does not handle multiple values';\n return this.validateMultiple(...arguments);\n } else {\n if (this.validateNumber) {\n if (isNaN(value))\n return false;\n arguments[0] = parseFloat(arguments[0]);\n return this.validateNumber(...arguments);\n }\n if (this.validateString) {\n return this.validateString(...arguments);\n }\n throw 'Validator `' + this.name + '` only handles multiple values';\n }\n },\n\n // Parses `requirements` into an array of arguments,\n // according to `this.requirementType`\n parseRequirements: function(requirements, extraOptionReader) {\n if ('string' !== typeof requirements) {\n // Assume requirement already parsed\n // but make sure we return an array\n return $.isArray(requirements) ? requirements : [requirements];\n }\n var type = this.requirementType;\n if ($.isArray(type)) {\n var values = convertArrayRequirement(requirements, type.length);\n for (var i = 0; i < values.length; i++)\n values[i] = convertRequirement(type[i], values[i]);\n return values;\n } else if ($.isPlainObject(type)) {\n return convertExtraOptionRequirement(type, requirements, extraOptionReader);\n } else {\n return [convertRequirement(type, requirements)];\n }\n },\n // Defaults:\n requirementType: 'string',\n\n priority: 2\n\n};\n\nexport default ParsleyValidator;\n","import $ from 'jquery';\nimport ParsleyUtils from './utils';\nimport ParsleyDefaults from './defaults';\nimport ParsleyValidator from './validator';\n\nvar ParsleyValidatorRegistry = function (validators, catalog) {\n this.__class__ = 'ParsleyValidatorRegistry';\n\n // Default Parsley locale is en\n this.locale = 'en';\n\n this.init(validators || {}, catalog || {});\n};\n\nvar typeRegexes = {\n email: /^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))$/i,\n\n // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers\n number: /^-?(\\d*\\.)?\\d+(e[-+]?\\d+)?$/i,\n\n integer: /^-?\\d+$/,\n\n digits: /^\\d+$/,\n\n alphanum: /^\\w+$/i,\n\n url: new RegExp(\n \"^\" +\n // protocol identifier\n \"(?:(?:https?|ftp)://)?\" + // ** mod: make scheme optional\n // user:pass authentication\n \"(?:\\\\S+(?::\\\\S*)?@)?\" +\n \"(?:\" +\n // IP address exclusion\n // private & local networks\n // \"(?!(?:10|127)(?:\\\\.\\\\d{1,3}){3})\" + // ** mod: allow local networks\n // \"(?!(?:169\\\\.254|192\\\\.168)(?:\\\\.\\\\d{1,3}){2})\" + // ** mod: allow local networks\n // \"(?!172\\\\.(?:1[6-9]|2\\\\d|3[0-1])(?:\\\\.\\\\d{1,3}){2})\" + // ** mod: allow local networks\n // IP address dotted notation octets\n // excludes loopback network 0.0.0.0\n // excludes reserved space >= 224.0.0.0\n // excludes network & broacast addresses\n // (first & last IP address of each class)\n \"(?:[1-9]\\\\d?|1\\\\d\\\\d|2[01]\\\\d|22[0-3])\" +\n \"(?:\\\\.(?:1?\\\\d{1,2}|2[0-4]\\\\d|25[0-5])){2}\" +\n \"(?:\\\\.(?:[1-9]\\\\d?|1\\\\d\\\\d|2[0-4]\\\\d|25[0-4]))\" +\n \"|\" +\n // host name\n \"(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)\" +\n // domain name\n \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*\" +\n // TLD identifier\n \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,}))\" +\n \")\" +\n // port number\n \"(?::\\\\d{2,5})?\" +\n // resource path\n \"(?:/\\\\S*)?\" +\n \"$\", 'i'\n )\n};\ntypeRegexes.range = typeRegexes.number;\n\n// See http://stackoverflow.com/a/10454560/8279\nvar decimalPlaces = num => {\n var match = ('' + num).match(/(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/);\n if (!match) { return 0; }\n return Math.max(\n 0,\n // Number of digits right of decimal point.\n (match[1] ? match[1].length : 0) -\n // Adjust for scientific notation.\n (match[2] ? +match[2] : 0));\n};\n\nParsleyValidatorRegistry.prototype = {\n init: function (validators, catalog) {\n this.catalog = catalog;\n // Copy prototype's validators:\n this.validators = $.extend({}, this.validators);\n\n for (var name in validators)\n this.addValidator(name, validators[name].fn, validators[name].priority);\n\n window.Parsley.trigger('parsley:validator:init');\n },\n\n // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n\n setLocale: function (locale) {\n if ('undefined' === typeof this.catalog[locale])\n throw new Error(locale + ' is not available in the catalog');\n\n this.locale = locale;\n\n return this;\n },\n\n // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`\n addCatalog: function (locale, messages, set) {\n if ('object' === typeof messages)\n this.catalog[locale] = messages;\n\n if (true === set)\n return this.setLocale(locale);\n\n return this;\n },\n\n // Add a specific message for a given constraint in a given locale\n addMessage: function (locale, name, message) {\n if ('undefined' === typeof this.catalog[locale])\n this.catalog[locale] = {};\n\n this.catalog[locale][name] = message;\n\n return this;\n },\n\n // Add messages for a given locale\n addMessages: function (locale, nameMessageObject) {\n for (var name in nameMessageObject)\n this.addMessage(locale, name, nameMessageObject[name]);\n\n return this;\n },\n\n // Add a new validator\n //\n // addValidator('custom', {\n // requirementType: ['integer', 'integer'],\n // validateString: function(value, from, to) {},\n // priority: 22,\n // messages: {\n // en: \"Hey, that's no good\",\n // fr: \"Aye aye, pas bon du tout\",\n // }\n // })\n //\n // Old API was addValidator(name, function, priority)\n //\n addValidator: function (name, arg1, arg2) {\n if (this.validators[name])\n ParsleyUtils.warn('Validator \"' + name + '\" is already defined.');\n else if (ParsleyDefaults.hasOwnProperty(name)) {\n ParsleyUtils.warn('\"' + name + '\" is a restricted keyword and is not a valid validator name.');\n return;\n }\n return this._setValidator(...arguments);\n },\n\n updateValidator: function (name, arg1, arg2) {\n if (!this.validators[name]) {\n ParsleyUtils.warn('Validator \"' + name + '\" is not already defined.');\n return this.addValidator(...arguments);\n }\n return this._setValidator(this, arguments);\n },\n\n removeValidator: function (name) {\n if (!this.validators[name])\n ParsleyUtils.warn('Validator \"' + name + '\" is not defined.');\n\n delete this.validators[name];\n\n return this;\n },\n\n _setValidator: function (name, validator, priority) {\n if ('object' !== typeof validator) {\n // Old style validator, with `fn` and `priority`\n validator = {\n fn: validator,\n priority: priority\n };\n }\n if (!validator.validate) {\n validator = new ParsleyValidator(validator);\n }\n this.validators[name] = validator;\n\n for (var locale in validator.messages || {})\n this.addMessage(locale, name, validator.messages[locale]);\n\n return this;\n },\n\n getErrorMessage: function (constraint) {\n var message;\n\n // Type constraints are a bit different, we have to match their requirements too to find right error message\n if ('type' === constraint.name) {\n var typeMessages = this.catalog[this.locale][constraint.name] || {};\n message = typeMessages[constraint.requirements];\n } else\n message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);\n\n return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;\n },\n\n // Kind of light `sprintf()` implementation\n formatMessage: function (string, parameters) {\n if ('object' === typeof parameters) {\n for (var i in parameters)\n string = this.formatMessage(string, parameters[i]);\n\n return string;\n }\n\n return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';\n },\n\n // Here is the Parsley default validators list.\n // A validator is an object with the following key values:\n // - priority: an integer\n // - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these\n // - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise\n // Alternatively, a validator can be a function that returns such an object\n //\n validators: {\n notblank: {\n validateString: function(value) {\n return /\\S/.test(value);\n },\n priority: 2\n },\n required: {\n validateMultiple: function(values) {\n return values.length > 0;\n },\n validateString: function(value) {\n return /\\S/.test(value);\n },\n priority: 512\n },\n type: {\n validateString: function(value, type, {step = '1', base = 0} = {}) {\n var regex = typeRegexes[type];\n if (!regex) {\n throw new Error('validator type `' + type + '` is not supported');\n }\n if (!regex.test(value))\n return false;\n if ('number' === type) {\n if (!/^any$/i.test(step || '')) {\n var nb = Number(value);\n var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));\n if (decimalPlaces(nb) > decimals) // Value can't have too many decimals\n return false;\n // Be careful of rounding errors by using integers.\n var toInt = f => { return Math.round(f * Math.pow(10, decimals)); };\n if ((toInt(nb) - toInt(base)) % toInt(step) != 0)\n return false;\n }\n }\n return true;\n },\n requirementType: {\n '': 'string',\n step: 'string',\n base: 'number'\n },\n priority: 256\n },\n pattern: {\n validateString: function(value, regexp) {\n return regexp.test(value);\n },\n requirementType: 'regexp',\n priority: 64\n },\n minlength: {\n validateString: function (value, requirement) {\n return value.length >= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n maxlength: {\n validateString: function (value, requirement) {\n return value.length <= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n length: {\n validateString: function (value, min, max) {\n return value.length >= min && value.length <= max;\n },\n requirementType: ['integer', 'integer'],\n priority: 30\n },\n mincheck: {\n validateMultiple: function (values, requirement) {\n return values.length >= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n maxcheck: {\n validateMultiple: function (values, requirement) {\n return values.length <= requirement;\n },\n requirementType: 'integer',\n priority: 30\n },\n check: {\n validateMultiple: function (values, min, max) {\n return values.length >= min && values.length <= max;\n },\n requirementType: ['integer', 'integer'],\n priority: 30\n },\n min: {\n validateNumber: function (value, requirement) {\n return value >= requirement;\n },\n requirementType: 'number',\n priority: 30\n },\n max: {\n validateNumber: function (value, requirement) {\n return value <= requirement;\n },\n requirementType: 'number',\n priority: 30\n },\n range: {\n validateNumber: function (value, min, max) {\n return value >= min && value <= max;\n },\n requirementType: ['number', 'number'],\n priority: 30\n },\n equalto: {\n validateString: function (value, refOrValue) {\n var $reference = $(refOrValue);\n if ($reference.length)\n return value === $reference.val();\n else\n return value === refOrValue;\n },\n priority: 256\n }\n }\n};\n\nexport default ParsleyValidatorRegistry;\n","import $ from 'jquery';\nimport ParsleyUtils from './utils';\n\nvar ParsleyUI = {};\n\nvar diffResults = function (newResult, oldResult, deep) {\n var added = [];\n var kept = [];\n\n for (var i = 0; i < newResult.length; i++) {\n var found = false;\n\n for (var j = 0; j < oldResult.length; j++)\n if (newResult[i].assert.name === oldResult[j].assert.name) {\n found = true;\n break;\n }\n\n if (found)\n kept.push(newResult[i]);\n else\n added.push(newResult[i]);\n }\n\n return {\n kept: kept,\n added: added,\n removed: !deep ? diffResults(oldResult, newResult, true).added : []\n };\n};\n\nParsleyUI.Form = {\n\n _actualizeTriggers: function () {\n this.$element.on('submit.Parsley', evt => { this.onSubmitValidate(evt); });\n this.$element.on('click.Parsley', 'input[type=\"submit\"], button[type=\"submit\"]', evt => { this.onSubmitButton(evt); });\n\n // UI could be disabled\n if (false === this.options.uiEnabled)\n return;\n\n this.$element.attr('novalidate', '');\n },\n\n focus: function () {\n this._focusedField = null;\n\n if (true === this.validationResult || 'none' === this.options.focus)\n return null;\n\n for (var i = 0; i < this.fields.length; i++) {\n var field = this.fields[i];\n if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {\n this._focusedField = field.$element;\n if ('first' === this.options.focus)\n break;\n }\n }\n\n if (null === this._focusedField)\n return null;\n\n return this._focusedField.focus();\n },\n\n _destroyUI: function () {\n // Reset all event listeners\n this.$element.off('.Parsley');\n }\n\n};\n\nParsleyUI.Field = {\n\n _reflowUI: function () {\n this._buildUI();\n\n // If this field doesn't have an active UI don't bother doing something\n if (!this._ui)\n return;\n\n // Diff between two validation results\n var diff = diffResults(this.validationResult, this._ui.lastValidationResult);\n\n // Then store current validation result for next reflow\n this._ui.lastValidationResult = this.validationResult;\n\n // Handle valid / invalid / none field class\n this._manageStatusClass();\n\n // Add, remove, updated errors messages\n this._manageErrorsMessages(diff);\n\n // Triggers impl\n this._actualizeTriggers();\n\n // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user\n if ((diff.kept.length || diff.added.length) && !this._failedOnce) {\n this._failedOnce = true;\n this._actualizeTriggers();\n }\n },\n\n // Returns an array of field's error message(s)\n getErrorsMessages: function () {\n // No error message, field is valid\n if (true === this.validationResult)\n return [];\n\n var messages = [];\n\n for (var i = 0; i < this.validationResult.length; i++)\n messages.push(this.validationResult[i].errorMessage ||\n this._getErrorMessage(this.validationResult[i].assert));\n\n return messages;\n },\n\n // It's a goal of Parsley that this method is no longer required [#1073]\n addError: function (name, {message, assert, updateClass = true} = {}) {\n this._buildUI();\n this._addError(name, {message, assert});\n\n if (updateClass)\n this._errorClass();\n },\n\n // It's a goal of Parsley that this method is no longer required [#1073]\n updateError: function (name, {message, assert, updateClass = true} = {}) {\n this._buildUI();\n this._updateError(name, {message, assert});\n\n if (updateClass)\n this._errorClass();\n },\n\n // It's a goal of Parsley that this method is no longer required [#1073]\n removeError: function (name, {updateClass = true} = {}) {\n this._buildUI();\n this._removeError(name);\n\n // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult\n // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.\n if (updateClass)\n this._manageStatusClass();\n },\n\n _manageStatusClass: function () {\n if (this.hasConstraints() && this.needsValidation() && true === this.validationResult)\n this._successClass();\n else if (this.validationResult.length > 0)\n this._errorClass();\n else\n this._resetClass();\n },\n\n _manageErrorsMessages: function (diff) {\n if ('undefined' !== typeof this.options.errorsMessagesDisabled)\n return;\n\n // Case where we have errorMessage option that configure an unique field error message, regardless failing validators\n if ('undefined' !== typeof this.options.errorMessage) {\n if ((diff.added.length || diff.kept.length)) {\n this._insertErrorWrapper();\n\n if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length)\n this._ui.$errorsWrapper\n .append(\n $(this.options.errorTemplate)\n .addClass('parsley-custom-error-message')\n );\n\n return this._ui.$errorsWrapper\n .addClass('filled')\n .find('.parsley-custom-error-message')\n .html(this.options.errorMessage);\n }\n\n return this._ui.$errorsWrapper\n .removeClass('filled')\n .find('.parsley-custom-error-message')\n .remove();\n }\n\n // Show, hide, update failing constraints messages\n for (var i = 0; i < diff.removed.length; i++)\n this._removeError(diff.removed[i].assert.name);\n\n for (i = 0; i < diff.added.length; i++)\n this._addError(diff.added[i].assert.name, {message: diff.added[i].errorMessage, assert: diff.added[i].assert});\n\n for (i = 0; i < diff.kept.length; i++)\n this._updateError(diff.kept[i].assert.name, {message: diff.kept[i].errorMessage, assert: diff.kept[i].assert});\n },\n\n\n _addError: function (name, {message, assert}) {\n this._insertErrorWrapper();\n this._ui.$errorsWrapper\n .addClass('filled')\n .append(\n $(this.options.errorTemplate)\n .addClass('parsley-' + name)\n .html(message || this._getErrorMessage(assert))\n );\n },\n\n _updateError: function (name, {message, assert}) {\n this._ui.$errorsWrapper\n .addClass('filled')\n .find('.parsley-' + name)\n .html(message || this._getErrorMessage(assert));\n },\n\n _removeError: function (name) {\n this._ui.$errorsWrapper\n .removeClass('filled')\n .find('.parsley-' + name)\n .remove();\n },\n\n _getErrorMessage: function (constraint) {\n var customConstraintErrorMessage = constraint.name + 'Message';\n\n if ('undefined' !== typeof this.options[customConstraintErrorMessage])\n return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);\n\n return window.Parsley.getErrorMessage(constraint);\n },\n\n _buildUI: function () {\n // UI could be already built or disabled\n if (this._ui || false === this.options.uiEnabled)\n return;\n\n var _ui = {};\n\n // Give field its Parsley id in DOM\n this.$element.attr(this.options.namespace + 'id', this.__id__);\n\n /** Generate important UI elements and store them in this **/\n // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes\n _ui.$errorClassHandler = this._manageClassHandler();\n\n // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer\n _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);\n _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);\n\n // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly\n _ui.lastValidationResult = [];\n _ui.validationInformationVisible = false;\n\n // Store it in this for later\n this._ui = _ui;\n },\n\n // Determine which element will have `parsley-error` and `parsley-success` classes\n _manageClassHandler: function () {\n // An element selector could be passed through DOM with `data-parsley-class-handler=#foo`\n if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length)\n return $(this.options.classHandler);\n\n // Class handled could also be determined by function given in Parsley options\n var $handler = this.options.classHandler.call(this, this);\n\n // If this function returned a valid existing DOM element, go for it\n if ('undefined' !== typeof $handler && $handler.length)\n return $handler;\n\n // Otherwise, if simple element (input, texatrea, select...) it will perfectly host the classes\n if (!this.options.multiple || this.$element.is('select'))\n return this.$element;\n\n // But if multiple element (radio, checkbox), that would be their parent\n return this.$element.parent();\n },\n\n _insertErrorWrapper: function () {\n var $errorsContainer;\n\n // Nothing to do if already inserted\n if (0 !== this._ui.$errorsWrapper.parent().length)\n return this._ui.$errorsWrapper.parent();\n\n if ('string' === typeof this.options.errorsContainer) {\n if ($(this.options.errorsContainer).length)\n return $(this.options.errorsContainer).append(this._ui.$errorsWrapper);\n else\n ParsleyUtils.warn('The errors container `' + this.options.errorsContainer + '` does not exist in DOM');\n } else if ('function' === typeof this.options.errorsContainer)\n $errorsContainer = this.options.errorsContainer.call(this, this);\n\n if ('undefined' !== typeof $errorsContainer && $errorsContainer.length)\n return $errorsContainer.append(this._ui.$errorsWrapper);\n\n var $from = this.$element;\n if (this.options.multiple)\n $from = $from.parent();\n return $from.after(this._ui.$errorsWrapper);\n },\n\n _actualizeTriggers: function () {\n var $toBind = this._findRelated();\n\n // Remove Parsley events already bound on this field\n $toBind.off('.Parsley');\n if (this._failedOnce)\n $toBind.on(ParsleyUtils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), () => {\n this.validate();\n });\n else {\n $toBind.on(ParsleyUtils.namespaceEvents(this.options.trigger, 'Parsley'), event => {\n this._eventValidate(event);\n });\n }\n },\n\n _eventValidate: function (event) {\n // For keyup, keypress, keydown, input... events that could be a little bit obstrusive\n // do not validate if val length < min threshold on first validation. Once field have been validated once and info\n // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.\n if (/key|input/.test(event.type))\n if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold)\n return;\n\n this.validate();\n },\n\n _resetUI: function () {\n // Reset all event listeners\n this._failedOnce = false;\n this._actualizeTriggers();\n\n // Nothing to do if UI never initialized for this field\n if ('undefined' === typeof this._ui)\n return;\n\n // Reset all errors' li\n this._ui.$errorsWrapper\n .removeClass('filled')\n .children()\n .remove();\n\n // Reset validation class\n this._resetClass();\n\n // Reset validation flags and last validation result\n this._ui.lastValidationResult = [];\n this._ui.validationInformationVisible = false;\n },\n\n _destroyUI: function () {\n this._resetUI();\n\n if ('undefined' !== typeof this._ui)\n this._ui.$errorsWrapper.remove();\n\n delete this._ui;\n },\n\n _successClass: function () {\n this._ui.validationInformationVisible = true;\n this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);\n },\n _errorClass: function () {\n this._ui.validationInformationVisible = true;\n this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);\n },\n _resetClass: function () {\n this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);\n }\n};\n\nexport default ParsleyUI;\n","import $ from 'jquery';\nimport ParsleyAbstract from './abstract';\nimport ParsleyUtils from './utils';\n\nvar ParsleyForm = function (element, domOptions, options) {\n this.__class__ = 'ParsleyForm';\n this.__id__ = ParsleyUtils.generateID();\n\n this.$element = $(element);\n this.domOptions = domOptions;\n this.options = options;\n this.parent = window.Parsley;\n\n this.fields = [];\n this.validationResult = null;\n};\n\nvar statusMapping = {pending: null, resolved: true, rejected: false};\n\nParsleyForm.prototype = {\n onSubmitValidate: function (event) {\n // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior\n if (true === event.parsley)\n return;\n\n // If we didn't come here through a submit button, use the first one in the form\n var $submitSource = this._$submitSource || this.$element.find('input[type=\"submit\"], button[type=\"submit\"]').first();\n this._$submitSource = null;\n this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);\n if ($submitSource.is('[formnovalidate]'))\n return;\n\n var promise = this.whenValidate({event});\n\n if ('resolved' === promise.state() && false !== this._trigger('submit')) {\n // All good, let event go through. We make this distinction because browsers\n // differ in their handling of `submit` being called from inside a submit event [#1047]\n } else {\n // Rejected or pending: cancel this submit\n event.stopImmediatePropagation();\n event.preventDefault();\n if ('pending' === promise.state())\n promise.done(() => { this._submit($submitSource); });\n }\n },\n\n onSubmitButton: function(event) {\n this._$submitSource = $(event.target);\n },\n // internal\n // _submit submits the form, this time without going through the validations.\n // Care must be taken to \"fake\" the actual submit button being clicked.\n _submit: function ($submitSource) {\n if (false === this._trigger('submit'))\n return;\n // Add submit button's data\n if ($submitSource) {\n var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);\n if (0 === $synthetic.length)\n $synthetic = $('').appendTo(this.$element);\n $synthetic.attr({\n name: $submitSource.attr('name'),\n value: $submitSource.attr('value')\n });\n }\n\n this.$element.trigger($.extend($.Event('submit'), {parsley: true}));\n },\n\n // Performs validation on fields while triggering events.\n // @returns `true` if all validations succeeds, `false`\n // if a failure is immediately detected, or `null`\n // if dependant on a promise.\n // Consider using `whenValidate` instead.\n validate: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');\n var [group, force, event] = arguments;\n options = {group, force, event};\n }\n return statusMapping[ this.whenValidate(options).state() ];\n },\n\n whenValidate: function ({group, force, event} = {}) {\n this.submitEvent = event;\n if (event) {\n this.submitEvent = $.extend({}, event, {preventDefault: () => {\n ParsleyUtils.warnOnce(\"Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`\");\n this.validationResult = false;\n }});\n }\n this.validationResult = true;\n\n // fire validate event to eventually modify things before very validation\n this._trigger('validate');\n\n // Refresh form DOM options and form's fields that could have changed\n this._refreshFields();\n\n var promises = this._withoutReactualizingFormOptions(() => {\n return $.map(this.fields, field => {\n return field.whenValidate({force, group});\n });\n });\n\n var promiseBasedOnValidationResult = () => {\n var r = $.Deferred();\n if (false === this.validationResult)\n r.reject();\n return r.resolve().promise();\n };\n\n return $.when(...promises)\n .done( () => { this._trigger('success'); })\n .fail( () => {\n this.validationResult = false;\n this.focus();\n this._trigger('error');\n })\n .always(() => { this._trigger('validated'); })\n .pipe( promiseBasedOnValidationResult, promiseBasedOnValidationResult);\n },\n\n // Iterate over refreshed fields, and stop on first failure.\n // Returns `true` if all fields are valid, `false` if a failure is detected\n // or `null` if the result depends on an unresolved promise.\n // Prefer using `whenValid` instead.\n isValid: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');\n var [group, force] = arguments;\n options = {group, force};\n }\n return statusMapping[ this.whenValid(options).state() ];\n },\n\n // Iterate over refreshed fields and validate them.\n // Returns a promise.\n // A validation that immediately fails will interrupt the validations.\n whenValid: function ({group, force} = {}) {\n this._refreshFields();\n\n var promises = this._withoutReactualizingFormOptions(() => {\n return $.map(this.fields, field => {\n return field.whenValid({group, force});\n });\n });\n return $.when(...promises);\n },\n\n _refreshFields: function () {\n return this.actualizeOptions()._bindFields();\n },\n\n _bindFields: function () {\n var oldFields = this.fields;\n\n this.fields = [];\n this.fieldsMappedById = {};\n\n this._withoutReactualizingFormOptions(() => {\n this.$element\n .find(this.options.inputs)\n .not(this.options.excluded)\n .each((_, element) => {\n var fieldInstance = new window.Parsley.Factory(element, {}, this);\n\n // Only add valid and not excluded `ParsleyField` and `ParsleyFieldMultiple` children\n if (('ParsleyField' === fieldInstance.__class__ || 'ParsleyFieldMultiple' === fieldInstance.__class__) && (true !== fieldInstance.options.excluded))\n if ('undefined' === typeof this.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__]) {\n this.fieldsMappedById[fieldInstance.__class__ + '-' + fieldInstance.__id__] = fieldInstance;\n this.fields.push(fieldInstance);\n }\n });\n\n $(oldFields).not(this.fields).each((_, field) => {\n field._trigger('reset');\n });\n });\n return this;\n },\n\n // Internal only.\n // Looping on a form's fields to do validation or similar\n // will trigger reactualizing options on all of them, which\n // in turn will reactualize the form's options.\n // To avoid calling actualizeOptions so many times on the form\n // for nothing, _withoutReactualizingFormOptions temporarily disables\n // the method actualizeOptions on this form while `fn` is called.\n _withoutReactualizingFormOptions: function (fn) {\n var oldActualizeOptions = this.actualizeOptions;\n this.actualizeOptions = function () { return this; };\n var result = fn();\n this.actualizeOptions = oldActualizeOptions;\n return result;\n },\n\n // Internal only.\n // Shortcut to trigger an event\n // Returns true iff event is not interrupted and default not prevented.\n _trigger: function (eventName) {\n return this.trigger('form:' + eventName);\n }\n\n};\n\nexport default ParsleyForm;\n","import $ from 'jquery';\nimport ParsleyUtils from '../utils';\nimport ParsleyValidator from '../validator';\n\n\nvar ConstraintFactory = function (parsleyField, name, requirements, priority, isDomConstraint) {\n if (!/ParsleyField/.test(parsleyField.__class__))\n throw new Error('ParsleyField or ParsleyFieldMultiple instance expected');\n\n var validatorSpec = window.Parsley._validatorRegistry.validators[name];\n var validator = new ParsleyValidator(validatorSpec);\n\n $.extend(this, {\n validator: validator,\n name: name,\n requirements: requirements,\n priority: priority || parsleyField.options[name + 'Priority'] || validator.priority,\n isDomConstraint: true === isDomConstraint\n });\n this._parseRequirements(parsleyField.options);\n};\n\nvar capitalize = function(str) {\n var cap = str[0].toUpperCase();\n return cap + str.slice(1);\n};\n\nConstraintFactory.prototype = {\n validate: function(value, instance) {\n var args = this.requirementList.slice(0); // Make copy\n args.unshift(value);\n args.push(instance);\n return this.validator.validate.apply(this.validator, args);\n },\n\n _parseRequirements: function(options) {\n this.requirementList = this.validator.parseRequirements(this.requirements, key => {\n return options[this.name + capitalize(key)];\n });\n }\n};\n\nexport default ConstraintFactory;\n\n","import $ from 'jquery';\nimport ConstraintFactory from './factory/constraint';\nimport ParsleyUI from './ui';\nimport ParsleyUtils from './utils';\n\nvar ParsleyField = function (field, domOptions, options, parsleyFormInstance) {\n this.__class__ = 'ParsleyField';\n this.__id__ = ParsleyUtils.generateID();\n\n this.$element = $(field);\n\n // Set parent if we have one\n if ('undefined' !== typeof parsleyFormInstance) {\n this.parent = parsleyFormInstance;\n }\n\n this.options = options;\n this.domOptions = domOptions;\n\n // Initialize some properties\n this.constraints = [];\n this.constraintsByName = {};\n this.validationResult = [];\n\n // Bind constraints\n this._bindConstraints();\n};\n\nvar statusMapping = {pending: null, resolved: true, rejected: false};\n\nParsleyField.prototype = {\n // # Public API\n // Validate field and trigger some events for mainly `ParsleyUI`\n // @returns `true`, an array of the validators that failed, or\n // `null` if validation is not finished. Prefer using whenValidate\n validate: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');\n options = {options};\n }\n var promise = this.whenValidate(options);\n if (!promise) // If excluded with `group` option\n return true;\n switch (promise.state()) {\n case 'pending': return null;\n case 'resolved': return true;\n case 'rejected': return this.validationResult;\n }\n },\n\n // Validate field and trigger some events for mainly `ParsleyUI`\n // @returns a promise that succeeds only when all validations do\n // or `undefined` if field is not in the given `group`.\n whenValidate: function ({force, group} = {}) {\n // do not validate a field if not the same as given validation group\n this.refreshConstraints();\n if (group && !this._isInGroup(group))\n return;\n\n this.value = this.getValue();\n\n // Field Validate event. `this.value` could be altered for custom needs\n this._trigger('validate');\n\n return this.whenValid({force, value: this.value, _refreshed: true})\n .always(() => { this._reflowUI(); })\n .done(() => { this._trigger('success'); })\n .fail(() => { this._trigger('error'); })\n .always(() => { this._trigger('validated'); });\n },\n\n hasConstraints: function () {\n return 0 !== this.constraints.length;\n },\n\n // An empty optional field does not need validation\n needsValidation: function (value) {\n if ('undefined' === typeof value)\n value = this.getValue();\n\n // If a field is empty and not required, it is valid\n // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators\n if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty)\n return false;\n\n return true;\n },\n\n _isInGroup: function (group) {\n if ($.isArray(this.options.group))\n return -1 !== $.inArray(group, this.options.group);\n return this.options.group === group;\n },\n\n // Just validate field. Do not trigger any event.\n // Returns `true` iff all constraints pass, `false` if there are failures,\n // or `null` if the result can not be determined yet (depends on a promise)\n // See also `whenValid`.\n isValid: function (options) {\n if (arguments.length >= 1 && !$.isPlainObject(options)) {\n ParsleyUtils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');\n var [force, value] = arguments;\n options = {force, value};\n }\n var promise = this.whenValid(options);\n if (!promise) // Excluded via `group`\n return true;\n return statusMapping[promise.state()];\n },\n\n // Just validate field. Do not trigger any event.\n // @returns a promise that succeeds only when all validations do\n // or `undefined` if the field is not in the given `group`.\n // The argument `force` will force validation of empty fields.\n // If a `value` is given, it will be validated instead of the value of the input.\n whenValid: function ({force = false, value, group, _refreshed} = {}) {\n // Recompute options and rebind constraints to have latest changes\n if (!_refreshed)\n this.refreshConstraints();\n // do not validate a field if not the same as given validation group\n if (group && !this._isInGroup(group))\n return;\n\n this.validationResult = true;\n\n // A field without constraint is valid\n if (!this.hasConstraints())\n return $.when();\n\n // Value could be passed as argument, needed to add more power to 'parsley:field:validate'\n if ('undefined' === typeof value || null === value)\n value = this.getValue();\n\n if (!this.needsValidation(value) && true !== force)\n return $.when();\n\n var groupedConstraints = this._getGroupedConstraints();\n var promises = [];\n $.each(groupedConstraints, (_, constraints) => {\n // Process one group of constraints at a time, we validate the constraints\n // and combine the promises together.\n var promise = $.when(\n ...$.map(constraints, constraint => this._validateConstraint(value, constraint))\n );\n promises.push(promise);\n if (promise.state() === 'rejected')\n return false; // Interrupt processing if a group has already failed\n });\n return $.when.apply($, promises);\n },\n\n // @returns a promise\n _validateConstraint: function(value, constraint) {\n var result = constraint.validate(value, this);\n // Map false to a failed promise\n if (false === result)\n result = $.Deferred().reject();\n // Make sure we return a promise and that we record failures\n return $.when(result).fail(errorMessage => {\n if (true === this.validationResult)\n this.validationResult = [];\n this.validationResult.push({\n assert: constraint,\n errorMessage: 'string' === typeof errorMessage && errorMessage\n });\n });\n },\n\n // @returns Parsley field computed value that could be overrided or configured in DOM\n getValue: function () {\n var value;\n\n // Value could be overriden in DOM or with explicit options\n if ('function' === typeof this.options.value)\n value = this.options.value(this);\n else if ('undefined' !== typeof this.options.value)\n value = this.options.value;\n else\n value = this.$element.val();\n\n // Handle wrong DOM or configurations\n if ('undefined' === typeof value || null === value)\n return '';\n\n return this._handleWhitespace(value);\n },\n\n // Actualize options that could have change since previous validation\n // Re-bind accordingly constraints (could be some new, removed or updated)\n refreshConstraints: function () {\n return this.actualizeOptions()._bindConstraints();\n },\n\n /**\n * Add a new constraint to a field\n *\n * @param {String} name\n * @param {Mixed} requirements optional\n * @param {Number} priority optional\n * @param {Boolean} isDomConstraint optional\n */\n addConstraint: function (name, requirements, priority, isDomConstraint) {\n\n if (window.Parsley._validatorRegistry.validators[name]) {\n var constraint = new ConstraintFactory(this, name, requirements, priority, isDomConstraint);\n\n // if constraint already exist, delete it and push new version\n if ('undefined' !== this.constraintsByName[constraint.name])\n this.removeConstraint(constraint.name);\n\n this.constraints.push(constraint);\n this.constraintsByName[constraint.name] = constraint;\n }\n\n return this;\n },\n\n // Remove a constraint\n removeConstraint: function (name) {\n for (var i = 0; i < this.constraints.length; i++)\n if (name === this.constraints[i].name) {\n this.constraints.splice(i, 1);\n break;\n }\n delete this.constraintsByName[name];\n return this;\n },\n\n // Update a constraint (Remove + re-add)\n updateConstraint: function (name, parameters, priority) {\n return this.removeConstraint(name)\n .addConstraint(name, parameters, priority);\n },\n\n // # Internals\n\n // Internal only.\n // Bind constraints from config + options + DOM\n _bindConstraints: function () {\n var constraints = [];\n var constraintsByName = {};\n\n // clean all existing DOM constraints to only keep javascript user constraints\n for (var i = 0; i < this.constraints.length; i++)\n if (false === this.constraints[i].isDomConstraint) {\n constraints.push(this.constraints[i]);\n constraintsByName[this.constraints[i].name] = this.constraints[i];\n }\n\n this.constraints = constraints;\n this.constraintsByName = constraintsByName;\n\n // then re-add Parsley DOM-API constraints\n for (var name in this.options)\n this.addConstraint(name, this.options[name], undefined, true);\n\n // finally, bind special HTML5 constraints\n return this._bindHtml5Constraints();\n },\n\n // Internal only.\n // Bind specific HTML5 constraints to be HTML5 compliant\n _bindHtml5Constraints: function () {\n // html5 required\n if (this.$element.hasClass('required') || this.$element.attr('required'))\n this.addConstraint('required', true, undefined, true);\n\n // html5 pattern\n if ('string' === typeof this.$element.attr('pattern'))\n this.addConstraint('pattern', this.$element.attr('pattern'), undefined, true);\n\n // range\n if ('undefined' !== typeof this.$element.attr('min') && 'undefined' !== typeof this.$element.attr('max'))\n this.addConstraint('range', [this.$element.attr('min'), this.$element.attr('max')], undefined, true);\n\n // HTML5 min\n else if ('undefined' !== typeof this.$element.attr('min'))\n this.addConstraint('min', this.$element.attr('min'), undefined, true);\n\n // HTML5 max\n else if ('undefined' !== typeof this.$element.attr('max'))\n this.addConstraint('max', this.$element.attr('max'), undefined, true);\n\n\n // length\n if ('undefined' !== typeof this.$element.attr('minlength') && 'undefined' !== typeof this.$element.attr('maxlength'))\n this.addConstraint('length', [this.$element.attr('minlength'), this.$element.attr('maxlength')], undefined, true);\n\n // HTML5 minlength\n else if ('undefined' !== typeof this.$element.attr('minlength'))\n this.addConstraint('minlength', this.$element.attr('minlength'), undefined, true);\n\n // HTML5 maxlength\n else if ('undefined' !== typeof this.$element.attr('maxlength'))\n this.addConstraint('maxlength', this.$element.attr('maxlength'), undefined, true);\n\n\n // html5 types\n var type = this.$element.attr('type');\n\n if ('undefined' === typeof type)\n return this;\n\n // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise\n if ('number' === type) {\n return this.addConstraint('type', ['number', {\n step: this.$element.attr('step'),\n base: this.$element.attr('min') || this.$element.attr('value')\n }], undefined, true);\n // Regular other HTML5 supported types\n } else if (/^(email|url|range)$/i.test(type)) {\n return this.addConstraint('type', type, undefined, true);\n }\n return this;\n },\n\n // Internal only.\n // Field is required if have required constraint without `false` value\n _isRequired: function () {\n if ('undefined' === typeof this.constraintsByName.required)\n return false;\n\n return false !== this.constraintsByName.required.requirements;\n },\n\n // Internal only.\n // Shortcut to trigger an event\n _trigger: function (eventName) {\n return this.trigger('field:' + eventName);\n },\n\n // Internal only\n // Handles whitespace in a value\n // Use `data-parsley-whitespace=\"squish\"` to auto squish input value\n // Use `data-parsley-whitespace=\"trim\"` to auto trim input value\n _handleWhitespace: function (value) {\n if (true === this.options.trimValue)\n ParsleyUtils.warnOnce('data-parsley-trim-value=\"true\" is deprecated, please use data-parsley-whitespace=\"trim\"');\n\n if ('squish' === this.options.whitespace)\n value = value.replace(/\\s{2,}/g, ' ');\n\n if (('trim' === this.options.whitespace) || ('squish' === this.options.whitespace) || (true === this.options.trimValue))\n value = ParsleyUtils.trimString(value);\n\n return value;\n },\n\n // Internal only.\n // Returns the constraints, grouped by descending priority.\n // The result is thus an array of arrays of constraints.\n _getGroupedConstraints: function () {\n if (false === this.options.priorityEnabled)\n return [this.constraints];\n\n var groupedConstraints = [];\n var index = {};\n\n // Create array unique of priorities\n for (var i = 0; i < this.constraints.length; i++) {\n var p = this.constraints[i].priority;\n if (!index[p])\n groupedConstraints.push(index[p] = []);\n index[p].push(this.constraints[i]);\n }\n // Sort them by priority DESC\n groupedConstraints.sort(function (a, b) { return b[0].priority - a[0].priority; });\n\n return groupedConstraints;\n }\n\n};\n\nexport default ParsleyField;\n","import $ from 'jquery';\n\nvar ParsleyMultiple = function () {\n this.__class__ = 'ParsleyFieldMultiple';\n};\n\nParsleyMultiple.prototype = {\n // Add new `$element` sibling for multiple field\n addElement: function ($element) {\n this.$elements.push($element);\n\n return this;\n },\n\n // See `ParsleyField.refreshConstraints()`\n refreshConstraints: function () {\n var fieldConstraints;\n\n this.constraints = [];\n\n // Select multiple special treatment\n if (this.$element.is('select')) {\n this.actualizeOptions()._bindConstraints();\n\n return this;\n }\n\n // Gather all constraints for each input in the multiple group\n for (var i = 0; i < this.$elements.length; i++) {\n\n // Check if element have not been dynamically removed since last binding\n if (!$('html').has(this.$elements[i]).length) {\n this.$elements.splice(i, 1);\n continue;\n }\n\n fieldConstraints = this.$elements[i].data('ParsleyFieldMultiple').refreshConstraints().constraints;\n\n for (var j = 0; j < fieldConstraints.length; j++)\n this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);\n }\n\n return this;\n },\n\n // See `ParsleyField.getValue()`\n getValue: function () {\n // Value could be overriden in DOM\n if ('function' === typeof this.options.value)\n value = this.options.value(this);\n else if ('undefined' !== typeof this.options.value)\n return this.options.value;\n\n // Radio input case\n if (this.$element.is('input[type=radio]'))\n return this._findRelated().filter(':checked').val() || '';\n\n // checkbox input case\n if (this.$element.is('input[type=checkbox]')) {\n var values = [];\n\n this._findRelated().filter(':checked').each(function () {\n values.push($(this).val());\n });\n\n return values;\n }\n\n // Select multiple case\n if (this.$element.is('select') && null === this.$element.val())\n return [];\n\n // Default case that should never happen\n return this.$element.val();\n },\n\n _init: function () {\n this.$elements = [this.$element];\n\n return this;\n }\n};\n\nexport default ParsleyMultiple;\n","import $ from 'jquery';\nimport ParsleyUtils from './utils';\nimport ParsleyAbstract from './abstract';\nimport ParsleyForm from './form';\nimport ParsleyField from './field';\nimport ParsleyMultiple from './multiple';\n\nvar ParsleyFactory = function (element, options, parsleyFormInstance) {\n this.$element = $(element);\n\n // If the element has already been bound, returns its saved Parsley instance\n var savedparsleyFormInstance = this.$element.data('Parsley');\n if (savedparsleyFormInstance) {\n\n // If the saved instance has been bound without a ParsleyForm parent and there is one given in this call, add it\n if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {\n savedparsleyFormInstance.parent = parsleyFormInstance;\n savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);\n }\n\n return savedparsleyFormInstance;\n }\n\n // Parsley must be instantiated with a DOM element or jQuery $element\n if (!this.$element.length)\n throw new Error('You must bind Parsley on an existing element.');\n\n if ('undefined' !== typeof parsleyFormInstance && 'ParsleyForm' !== parsleyFormInstance.__class__)\n throw new Error('Parent instance must be a ParsleyForm instance');\n\n this.parent = parsleyFormInstance || window.Parsley;\n return this.init(options);\n};\n\nParsleyFactory.prototype = {\n init: function (options) {\n this.__class__ = 'Parsley';\n this.__version__ = '@@version';\n this.__id__ = ParsleyUtils.generateID();\n\n // Pre-compute options\n this._resetOptions(options);\n\n // A ParsleyForm instance is obviously a `` element but also every node that is not an input and has the `data-parsley-validate` attribute\n if (this.$element.is('form') || (ParsleyUtils.checkAttr(this.$element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)))\n return this.bind('parsleyForm');\n\n // Every other element is bound as a `ParsleyField` or `ParsleyFieldMultiple`\n return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');\n },\n\n isMultiple: function () {\n return (this.$element.is('input[type=radio], input[type=checkbox]')) || (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple'));\n },\n\n // Multiples fields are a real nightmare :(\n // Maybe some refactoring would be appreciated here...\n handleMultiple: function () {\n var name;\n var multiple;\n var parsleyMultipleInstance;\n\n // Handle multiple name\n if (this.options.multiple)\n ; // We already have our 'multiple' identifier\n else if ('undefined' !== typeof this.$element.attr('name') && this.$element.attr('name').length)\n this.options.multiple = name = this.$element.attr('name');\n else if ('undefined' !== typeof this.$element.attr('id') && this.$element.attr('id').length)\n this.options.multiple = this.$element.attr('id');\n\n // Special select multiple input\n if (this.$element.is('select') && 'undefined' !== typeof this.$element.attr('multiple')) {\n this.options.multiple = this.options.multiple || this.__id__;\n return this.bind('parsleyFieldMultiple');\n\n // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it\n } else if (!this.options.multiple) {\n ParsleyUtils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);\n return this;\n }\n\n // Remove special chars\n this.options.multiple = this.options.multiple.replace(/(:|\\.|\\[|\\]|\\{|\\}|\\$)/g, '');\n\n // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name\n if ('undefined' !== typeof name) {\n $('input[name=\"' + name + '\"]').each((i, input) => {\n if ($(input).is('input[type=radio], input[type=checkbox]'))\n $(input).attr(this.options.namespace + 'multiple', this.options.multiple);\n });\n }\n\n // Check here if we don't already have a related multiple instance saved\n var $previouslyRelated = this._findRelated();\n for (var i = 0; i < $previouslyRelated.length; i++) {\n parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');\n if ('undefined' !== typeof parsleyMultipleInstance) {\n\n if (!this.$element.data('ParsleyFieldMultiple')) {\n parsleyMultipleInstance.addElement(this.$element);\n }\n\n break;\n }\n }\n\n // Create a secret ParsleyField instance for every multiple field. It will be stored in `data('ParsleyFieldMultiple')`\n // And will be useful later to access classic `ParsleyField` stuff while being in a `ParsleyFieldMultiple` instance\n this.bind('parsleyField', true);\n\n return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');\n },\n\n // Return proper `ParsleyForm`, `ParsleyField` or `ParsleyFieldMultiple`\n bind: function (type, doNotStore) {\n var parsleyInstance;\n\n switch (type) {\n case 'parsleyForm':\n parsleyInstance = $.extend(\n new ParsleyForm(this.$element, this.domOptions, this.options),\n window.ParsleyExtend\n )._bindFields();\n break;\n case 'parsleyField':\n parsleyInstance = $.extend(\n new ParsleyField(this.$element, this.domOptions, this.options, this.parent),\n window.ParsleyExtend\n );\n break;\n case 'parsleyFieldMultiple':\n parsleyInstance = $.extend(\n new ParsleyField(this.$element, this.domOptions, this.options, this.parent),\n new ParsleyMultiple(),\n window.ParsleyExtend\n )._init();\n break;\n default:\n throw new Error(type + 'is not a supported Parsley type');\n }\n\n if (this.options.multiple)\n ParsleyUtils.setAttr(this.$element, this.options.namespace, 'multiple', this.options.multiple);\n\n if ('undefined' !== typeof doNotStore) {\n this.$element.data('ParsleyFieldMultiple', parsleyInstance);\n\n return parsleyInstance;\n }\n\n // Store the freshly bound instance in a DOM element for later access using jQuery `data()`\n this.$element.data('Parsley', parsleyInstance);\n\n // Tell the world we have a new ParsleyForm or ParsleyField instance!\n parsleyInstance._actualizeTriggers();\n parsleyInstance._trigger('init');\n\n return parsleyInstance;\n }\n};\n\nexport default ParsleyFactory;\n","import $ from 'jquery';\nimport ParsleyUtils from './utils';\nimport ParsleyDefaults from './defaults';\nimport ParsleyAbstract from './abstract';\nimport ParsleyValidatorRegistry from './validator_registry';\nimport ParsleyUI from './ui';\nimport ParsleyForm from './form';\nimport ParsleyField from './field';\nimport ParsleyMultiple from './multiple';\nimport ParsleyFactory from './factory';\n\nvar vernums = $.fn.jquery.split('.');\nif (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {\n throw \"The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.\";\n}\nif (!vernums.forEach) {\n ParsleyUtils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');\n}\n// Inherit `on`, `off` & `trigger` to Parsley:\nvar Parsley = $.extend(new ParsleyAbstract(), {\n $element: $(document),\n actualizeOptions: null,\n _resetOptions: null,\n Factory: ParsleyFactory,\n version: '@@version'\n });\n\n// Supplement ParsleyField and Form with ParsleyAbstract\n// This way, the constructors will have access to those methods\n$.extend(ParsleyField.prototype, ParsleyUI.Field, ParsleyAbstract.prototype);\n$.extend(ParsleyForm.prototype, ParsleyUI.Form, ParsleyAbstract.prototype);\n// Inherit actualizeOptions and _resetOptions:\n$.extend(ParsleyFactory.prototype, ParsleyAbstract.prototype);\n\n// ### jQuery API\n// `$('.elem').parsley(options)` or `$('.elem').psly(options)`\n$.fn.parsley = $.fn.psly = function (options) {\n if (this.length > 1) {\n var instances = [];\n\n this.each(function () {\n instances.push($(this).parsley(options));\n });\n\n return instances;\n }\n\n // Return undefined if applied to non existing DOM element\n if (!$(this).length) {\n ParsleyUtils.warn('You must bind Parsley on an existing element.');\n\n return;\n }\n\n return new ParsleyFactory(this, options);\n};\n\n// ### ParsleyField and ParsleyForm extension\n// Ensure the extension is now defined if it wasn't previously\nif ('undefined' === typeof window.ParsleyExtend)\n window.ParsleyExtend = {};\n\n// ### Parsley config\n// Inherit from ParsleyDefault, and copy over any existing values\nParsley.options = $.extend(ParsleyUtils.objectCreate(ParsleyDefaults), window.ParsleyConfig);\nwindow.ParsleyConfig = Parsley.options; // Old way of accessing global options\n\n// ### Globals\nwindow.Parsley = window.psly = Parsley;\nwindow.ParsleyUtils = ParsleyUtils;\n\n// ### Define methods that forward to the registry, and deprecate all access except through window.Parsley\nvar registry = window.Parsley._validatorRegistry = new ParsleyValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);\nwindow.ParsleyValidator = {};\n$.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator'.split(' '), function (i, method) {\n window.Parsley[method] = $.proxy(registry, method);\n window.ParsleyValidator[method] = function () {\n ParsleyUtils.warnOnce(`Accessing the method '${method}' through ParsleyValidator is deprecated. Simply call 'window.Parsley.${method}(...)'`);\n return window.Parsley[method](...arguments);\n };\n});\n\n// ### ParsleyUI\n// Deprecated global object\nwindow.Parsley.UI = ParsleyUI;\nwindow.ParsleyUI = {\n removeError: function (instance, name, doNotUpdateClass) {\n var updateClass = true !== doNotUpdateClass;\n ParsleyUtils.warnOnce(`Accessing ParsleyUI is deprecated. Call 'removeError' on the instance directly. Please comment in issue 1073 as to your need to call this method.`);\n return instance.removeError(name, {updateClass});\n },\n getErrorsMessages: function (instance) {\n ParsleyUtils.warnOnce(`Accessing ParsleyUI is deprecated. Call 'getErrorsMessages' on the instance directly.`);\n return instance.getErrorsMessages();\n }\n};\n$.each('addError updateError'.split(' '), function (i, method) {\n window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {\n var updateClass = true !== doNotUpdateClass;\n ParsleyUtils.warnOnce(`Accessing ParsleyUI is deprecated. Call '${method}' on the instance directly. Please comment in issue 1073 as to your need to call this method.`);\n return instance[method](name, {message, assert, updateClass});\n };\n});\n\n// Alleviate glaring Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=1250521\n// See also https://github.com/guillaumepotier/Parsley.js/issues/1068\nif (/firefox/i.test(navigator.userAgent)) {\n $(document).on('change', 'select', evt => {\n $(evt.target).trigger('input');\n });\n}\n\n// ### PARSLEY auto-binding\n// Prevent it by setting `ParsleyConfig.autoBind` to `false`\nif (false !== window.ParsleyConfig.autoBind) {\n $(function () {\n // Works only on `data-parsley-validate`.\n if ($('[data-parsley-validate]').length)\n $('[data-parsley-validate]').parsley();\n });\n}\n\nexport default Parsley;\n","import $ from 'jquery';\n\nimport Parsley from './main';\n\n$.extend(true, Parsley, {\n asyncValidators: {\n 'default': {\n fn: function (xhr) {\n // By default, only status 2xx are deemed successful.\n // Note: we use status instead of state() because responses with status 200\n // but invalid messages (e.g. an empty body for content type set to JSON) will\n // result in state() === 'rejected'.\n return xhr.status >= 200 && xhr.status < 300;\n },\n url: false\n },\n reverse: {\n fn: function (xhr) {\n // If reverse option is set, a failing ajax request is considered successful\n return xhr.status < 200 || xhr.status >= 300;\n },\n url: false\n }\n },\n\n addAsyncValidator: function (name, fn, url, options) {\n Parsley.asyncValidators[name] = {\n fn: fn,\n url: url || false,\n options: options || {}\n };\n\n return this;\n }\n\n});\n\nParsley.addValidator('remote', {\n requirementType: {\n '': 'string',\n 'validator': 'string',\n 'reverse': 'boolean',\n 'options': 'object'\n },\n\n validateString: function (value, url, options, instance) {\n var data = {};\n var ajaxOptions;\n var csr;\n var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');\n\n if ('undefined' === typeof Parsley.asyncValidators[validator])\n throw new Error('Calling an undefined async validator: `' + validator + '`');\n\n url = Parsley.asyncValidators[validator].url || url;\n\n // Fill current value\n if (url.indexOf('{value}') > -1) {\n url = url.replace('{value}', encodeURIComponent(value));\n } else {\n data[instance.$element.attr('name') || instance.$element.attr('id')] = value;\n }\n\n // Merge options passed in from the function with the ones in the attribute\n var remoteOptions = $.extend(true, options.options || {} , Parsley.asyncValidators[validator].options);\n\n // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`\n ajaxOptions = $.extend(true, {}, {\n url: url,\n data: data,\n type: 'GET'\n }, remoteOptions);\n\n // Generate store key based on ajax options\n instance.trigger('field:ajaxoptions', instance, ajaxOptions);\n\n csr = $.param(ajaxOptions);\n\n // Initialise querry cache\n if ('undefined' === typeof Parsley._remoteCache)\n Parsley._remoteCache = {};\n\n // Try to retrieve stored xhr\n var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);\n\n var handleXhr = function () {\n var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);\n if (!result) // Map falsy results to rejected promise\n result = $.Deferred().reject();\n return $.when(result);\n };\n\n return xhr.then(handleXhr, handleXhr);\n },\n\n priority: -1\n});\n\nParsley.on('form:submit', function () {\n Parsley._remoteCache = {};\n});\n\nwindow.ParsleyExtend.addAsyncValidator = function () {\n ParsleyUtils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');\n return Parsley.addAsyncValidator(...arguments);\n};\n","// This is included with the Parsley library itself,\n// thus there is no use in adding it to your project.\nimport Parsley from '../parsley/main';\n\nParsley.addMessages('en', {\n defaultMessage: \"This value seems to be invalid.\",\n type: {\n email: \"This value should be a valid email.\",\n url: \"This value should be a valid url.\",\n number: \"This value should be a valid number.\",\n integer: \"This value should be a valid integer.\",\n digits: \"This value should be digits.\",\n alphanum: \"This value should be alphanumeric.\"\n },\n notblank: \"This value should not be blank.\",\n required: \"This value is required.\",\n pattern: \"This value seems to be invalid.\",\n min: \"This value should be greater than or equal to %s.\",\n max: \"This value should be lower than or equal to %s.\",\n range: \"This value should be between %s and %s.\",\n minlength: \"This value is too short. It should have %s characters or more.\",\n maxlength: \"This value is too long. It should have %s characters or fewer.\",\n length: \"This value length is invalid. It should be between %s and %s characters long.\",\n mincheck: \"You must select at least %s choices.\",\n maxcheck: \"You must select %s choices or fewer.\",\n check: \"You must select between %s and %s choices.\",\n equalto: \"This value should be the same.\"\n});\n\nParsley.setLocale('en');\n","import $ from 'jquery';\nimport Parsley from './parsley/main';\nimport './parsley/pubsub';\nimport './parsley/remote';\nimport './i18n/en';\n\nexport default Parsley;\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/assets/js/popper/popper.js b/html/wp-content/plugins/duplicator/assets/js/popper/popper.js new file mode 100644 index 0000000..a551fef --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/js/popper/popper.js @@ -0,0 +1,1961 @@ +/*! + * @popperjs/core v2.6.0 - MIT License + */ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = global || self, factory(global.Popper = {})); +}(this, (function (exports) { + 'use strict'; + + function getBoundingClientRect(element) + { + var rect = element.getBoundingClientRect(); + return { + width: rect.width, + height: rect.height, + top: rect.top, + right: rect.right, + bottom: rect.bottom, + left: rect.left, + x: rect.left, + y: rect.top + }; + } + + /*:: import type { Window } from '../types'; */ + + /*:: declare function getWindow(node: Node | Window): Window; */ + function getWindow(node) + { + if (node.toString() !== '[object Window]') { + var ownerDocument = node.ownerDocument; + return ownerDocument ? ownerDocument.defaultView || window : window; + } + + return node; + } + + function getWindowScroll(node) + { + var win = getWindow(node); + var scrollLeft = win.pageXOffset; + var scrollTop = win.pageYOffset; + return { + scrollLeft: scrollLeft, + scrollTop: scrollTop + }; + } + + /*:: declare function isElement(node: mixed): boolean %checks(node instanceof + Element); */ + + function isElement(node) + { + var OwnElement = getWindow(node).Element; + return node instanceof OwnElement || node instanceof Element; + } + /*:: declare function isHTMLElement(node: mixed): boolean %checks(node instanceof + HTMLElement); */ + + + function isHTMLElement(node) + { + var OwnElement = getWindow(node).HTMLElement; + return node instanceof OwnElement || node instanceof HTMLElement; + } + /*:: declare function isShadowRoot(node: mixed): boolean %checks(node instanceof + ShadowRoot); */ + + + function isShadowRoot(node) + { + var OwnElement = getWindow(node).ShadowRoot; + return node instanceof OwnElement || node instanceof ShadowRoot; + } + + function getHTMLElementScroll(element) + { + return { + scrollLeft: element.scrollLeft, + scrollTop: element.scrollTop + }; + } + + function getNodeScroll(node) + { + if (node === getWindow(node) || !isHTMLElement(node)) { + return getWindowScroll(node); + } else { + return getHTMLElementScroll(node); + } + } + + function getNodeName(element) + { + return element ? (element.nodeName || '').toLowerCase() : null; + } + + function getDocumentElement(element) + { + // $FlowFixMe[incompatible-return]: assume body is always available + return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing] + element.document) || window.document).documentElement; + } + + function getWindowScrollBarX(element) + { + // If has a CSS width greater than the viewport, then this will be + // incorrect for RTL. + // Popper 1 is broken in this case and never had a bug report so let's assume + // it's not an issue. I don't think anyone ever specifies width on + // anyway. + // Browsers where the left scrollbar doesn't cause an issue report `0` for + // this (e.g. Edge 2019, IE11, Safari) + return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; + } + + function getComputedStyle(element) + { + return getWindow(element).getComputedStyle(element); + } + + function isScrollParent(element) + { + // Firefox wants us to check `-x` and `-y` variations as well + var _getComputedStyle = getComputedStyle(element), + overflow = _getComputedStyle.overflow, + overflowX = _getComputedStyle.overflowX, + overflowY = _getComputedStyle.overflowY; + + return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); + } + + // Composite means it takes into account transforms as well as layout. + + function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) + { + if (isFixed === void 0) { + isFixed = false; + } + + var documentElement = getDocumentElement(offsetParent); + var rect = getBoundingClientRect(elementOrVirtualElement); + var isOffsetParentAnElement = isHTMLElement(offsetParent); + var scroll = { + scrollLeft: 0, + scrollTop: 0 + }; + var offsets = { + x: 0, + y: 0 + }; + + if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { + if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 + isScrollParent(documentElement)) { + scroll = getNodeScroll(offsetParent); + } + + if (isHTMLElement(offsetParent)) { + offsets = getBoundingClientRect(offsetParent); + offsets.x += offsetParent.clientLeft; + offsets.y += offsetParent.clientTop; + } else if (documentElement) { + offsets.x = getWindowScrollBarX(documentElement); + } + } + + return { + x: rect.left + scroll.scrollLeft - offsets.x, + y: rect.top + scroll.scrollTop - offsets.y, + width: rect.width, + height: rect.height + }; + } + + // Returns the layout rect of an element relative to its offsetParent. Layout + // means it doesn't take into account transforms. + function getLayoutRect(element) + { + return { + x: element.offsetLeft, + y: element.offsetTop, + width: element.offsetWidth, + height: element.offsetHeight + }; + } + + function getParentNode(element) + { + if (getNodeName(element) === 'html') { + return element; + } + + return ( // this is a quicker (but less type safe) way to save quite some bytes from the bundle + // $FlowFixMe[incompatible-return] + // $FlowFixMe[prop-missing] + element.assignedSlot || // step into the shadow DOM of the parent of a slotted node + element.parentNode || // DOM Element detected + // $FlowFixMe[incompatible-return]: need a better way to handle this... + element.host || // ShadowRoot detected + // $FlowFixMe[incompatible-call]: HTMLElement is a Node + getDocumentElement(element) // fallback + + ); + } + + function getScrollParent(node) + { + if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { + // $FlowFixMe[incompatible-return]: assume body is always available + return node.ownerDocument.body; + } + + if (isHTMLElement(node) && isScrollParent(node)) { + return node; + } + + return getScrollParent(getParentNode(node)); + } + + /* + given a DOM element, return the list of all scroll parents, up the list of ancesors + until we get to the top window object. This list is what we attach scroll listeners + to, because if any of these parent elements scroll, we'll need to re-calculate the + reference element's position. + */ + + function listScrollParents(element, list) + { + if (list === void 0) { + list = []; + } + + var scrollParent = getScrollParent(element); + var isBody = getNodeName(scrollParent) === 'body'; + var win = getWindow(scrollParent); + var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; + var updatedList = list.concat(target); + return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here + updatedList.concat(listScrollParents(getParentNode(target))); + } + + function isTableElement(element) + { + return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0; + } + + function getTrueOffsetParent(element) + { + if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 + getComputedStyle(element).position === 'fixed') { + return null; + } + + var offsetParent = element.offsetParent; + + if (offsetParent) { + var html = getDocumentElement(offsetParent); + + if (getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static' && getComputedStyle(html).position !== 'static') { + return html; + } + } + + return offsetParent; + } // `.offsetParent` reports `null` for fixed elements, while absolute elements + // return the containing block + + + function getContainingBlock(element) + { + var currentNode = getParentNode(element); + + while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { + var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that + // create a containing block. + + if (css.transform !== 'none' || css.perspective !== 'none' || css.willChange && css.willChange !== 'auto') { + return currentNode; + } else { + currentNode = currentNode.parentNode; + } + } + + return null; + } // Gets the closest ancestor positioned element. Handles some edge cases, + // such as table ancestors and cross browser bugs. + + + function getOffsetParent(element) + { + var window = getWindow(element); + var offsetParent = getTrueOffsetParent(element); + + while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') { + offsetParent = getTrueOffsetParent(offsetParent); + } + + if (offsetParent && getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static') { + return window; + } + + return offsetParent || getContainingBlock(element) || window; + } + + var top = 'top'; + var bottom = 'bottom'; + var right = 'right'; + var left = 'left'; + var auto = 'auto'; + var basePlacements = [top, bottom, right, left]; + var start = 'start'; + var end = 'end'; + var clippingParents = 'clippingParents'; + var viewport = 'viewport'; + var popper = 'popper'; + var reference = 'reference'; + var variationPlacements = /*#__PURE__*/ basePlacements.reduce(function (acc, placement) { + return acc.concat([placement + "-" + start, placement + "-" + end]); + }, []); + var placements = /*#__PURE__*/ [].concat(basePlacements, [auto]).reduce(function (acc, placement) { + return acc.concat([placement, placement + "-" + start, placement + "-" + end]); + }, []); // modifiers that need to read the DOM + + var beforeRead = 'beforeRead'; + var read = 'read'; + var afterRead = 'afterRead'; // pure-logic modifiers + + var beforeMain = 'beforeMain'; + var main = 'main'; + var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) + + var beforeWrite = 'beforeWrite'; + var write = 'write'; + var afterWrite = 'afterWrite'; + var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; + + function order(modifiers) + { + var map = new Map(); + var visited = new Set(); + var result = []; + modifiers.forEach(function (modifier) { + map.set(modifier.name, modifier); + }); // On visiting object, check for its dependencies and visit them recursively + + function sort(modifier) + { + visited.add(modifier.name); + var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); + requires.forEach(function (dep) { + if (!visited.has(dep)) { + var depModifier = map.get(dep); + + if (depModifier) { + sort(depModifier); + } + } + }); + result.push(modifier); + } + + modifiers.forEach(function (modifier) { + if (!visited.has(modifier.name)) { + // check for visited object + sort(modifier); + } + }); + return result; + } + + function orderModifiers(modifiers) + { + // order based on dependencies + var orderedModifiers = order(modifiers); // order based on phase + + return modifierPhases.reduce(function (acc, phase) { + return acc.concat(orderedModifiers.filter(function (modifier) { + return modifier.phase === phase; + })); + }, []); + } + + function debounce(fn) + { + var pending; + return function () { + if (!pending) { + pending = new Promise(function (resolve) { + Promise.resolve().then(function () { + pending = undefined; + resolve(fn()); + }); + }); + } + + return pending; + }; + } + + function format(str) + { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + return [].concat(args).reduce(function (p, c) { + return p.replace(/%s/, c); + }, str); + } + + var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s'; + var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available'; + var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options']; + + function validateModifiers(modifiers) + { + modifiers.forEach(function (modifier) { + Object.keys(modifier).forEach(function (key) { + switch (key) { + case 'name': + if (typeof modifier.name !== 'string') { + console.error(format(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\"")); + } + + break; + + case 'enabled': + if (typeof modifier.enabled !== 'boolean') { + console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\"")); + } + + case 'phase': + if (modifierPhases.indexOf(modifier.phase) < 0) { + console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(', '), "\"" + String(modifier.phase) + "\"")); + } + + break; + + case 'fn': + if (typeof modifier.fn !== 'function') { + console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\"")); + } + + break; + + case 'effect': + if (typeof modifier.effect !== 'function') { + console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\"")); + } + + break; + + case 'requires': + if (!Array.isArray(modifier.requires)) { + console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\"")); + } + + break; + + case 'requiresIfExists': + if (!Array.isArray(modifier.requiresIfExists)) { + console.error(format(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\"")); + } + + break; + + case 'options': + case 'data': + break; + + default: + console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) { + return "\"" + s + "\""; + }).join(', ') + "; but \"" + key + "\" was provided."); + } + + modifier.requires && modifier.requires.forEach(function (requirement) { + if (modifiers.find(function (mod) { + return mod.name === requirement; + }) == null) { + console.error(format(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement)); + } + }); + }); + }); + } + + function uniqueBy(arr, fn) + { + var identifiers = new Set(); + return arr.filter(function (item) { + var identifier = fn(item); + + if (!identifiers.has(identifier)) { + identifiers.add(identifier); + return true; + } + }); + } + + function getBasePlacement(placement) + { + return placement.split('-')[0]; + } + + function mergeByName(modifiers) + { + var merged = modifiers.reduce(function (merged, current) { + var existing = merged[current.name]; + merged[current.name] = existing ? Object.assign(Object.assign(Object.assign({}, existing), current), {}, { + options: Object.assign(Object.assign({}, existing.options), current.options), + data: Object.assign(Object.assign({}, existing.data), current.data) + }) : current; + return merged; + }, {}); // IE11 does not support Object.values + + return Object.keys(merged).map(function (key) { + return merged[key]; + }); + } + + function getViewportRect(element) + { + var win = getWindow(element); + var html = getDocumentElement(element); + var visualViewport = win.visualViewport; + var width = html.clientWidth; + var height = html.clientHeight; + var x = 0; + var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper + // can be obscured underneath it. + // Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even + // if it isn't open, so if this isn't available, the popper will be detected + // to overflow the bottom of the screen too early. + + if (visualViewport) { + width = visualViewport.width; + height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently) + // In Chrome, it returns a value very close to 0 (+/-) but contains rounding + // errors due to floating point numbers, so we need to check precision. + // Safari returns a number <= 0, usually < -1 when pinch-zoomed + // Feature detection fails in mobile emulation mode in Chrome. + // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) < + // 0.001 + // Fallback here: "Not Safari" userAgent + + if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + x = visualViewport.offsetLeft; + y = visualViewport.offsetTop; + } + } + + return { + width: width, + height: height, + x: x + getWindowScrollBarX(element), + y: y + }; + } + + // of the `` and `` rect bounds if horizontally scrollable + + function getDocumentRect(element) + { + var html = getDocumentElement(element); + var winScroll = getWindowScroll(element); + var body = element.ownerDocument.body; + var width = Math.max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); + var height = Math.max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); + var x = -winScroll.scrollLeft + getWindowScrollBarX(element); + var y = -winScroll.scrollTop; + + if (getComputedStyle(body || html).direction === 'rtl') { + x += Math.max(html.clientWidth, body ? body.clientWidth : 0) - width; + } + + return { + width: width, + height: height, + x: x, + y: y + }; + } + + function contains(parent, child) + { + var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method + // then fallback to custom implementation with Shadow DOM support + if (parent.contains(child)) { + return true; + } else if (rootNode && isShadowRoot(rootNode)) { + var next = child; + + do { + if (next && parent.isSameNode(next)) { + return true; + } // $FlowFixMe[prop-missing]: need a better way to handle this... + + + next = next.parentNode || next.host; + } while (next); + } // Give up, the result is false + + + return false; + } + + function rectToClientRect(rect) + { + return Object.assign(Object.assign({}, rect), {}, { + left: rect.x, + top: rect.y, + right: rect.x + rect.width, + bottom: rect.y + rect.height + }); + } + + function getInnerBoundingClientRect(element) + { + var rect = getBoundingClientRect(element); + rect.top = rect.top + element.clientTop; + rect.left = rect.left + element.clientLeft; + rect.bottom = rect.top + element.clientHeight; + rect.right = rect.left + element.clientWidth; + rect.width = element.clientWidth; + rect.height = element.clientHeight; + rect.x = rect.left; + rect.y = rect.top; + return rect; + } + + function getClientRectFromMixedType(element, clippingParent) + { + return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isHTMLElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element))); + } // A "clipping parent" is an overflowable container with the characteristic of + // clipping (or hiding) overflowing elements with a position different from + // `initial` + + + function getClippingParents(element) + { + var clippingParents = listScrollParents(getParentNode(element)); + var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0; + var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; + + if (!isElement(clipperElement)) { + return []; + } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414 + + + return clippingParents.filter(function (clippingParent) { + return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body'; + }); + } // Gets the maximum area that the element is visible in due to any number of + // clipping parents + + + function getClippingRect(element, boundary, rootBoundary) + { + var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); + var clippingParents = [].concat(mainClippingParents, [rootBoundary]); + var firstClippingParent = clippingParents[0]; + var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { + var rect = getClientRectFromMixedType(element, clippingParent); + accRect.top = Math.max(rect.top, accRect.top); + accRect.right = Math.min(rect.right, accRect.right); + accRect.bottom = Math.min(rect.bottom, accRect.bottom); + accRect.left = Math.max(rect.left, accRect.left); + return accRect; + }, getClientRectFromMixedType(element, firstClippingParent)); + clippingRect.width = clippingRect.right - clippingRect.left; + clippingRect.height = clippingRect.bottom - clippingRect.top; + clippingRect.x = clippingRect.left; + clippingRect.y = clippingRect.top; + return clippingRect; + } + + function getVariation(placement) + { + return placement.split('-')[1]; + } + + function getMainAxisFromPlacement(placement) + { + return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; + } + + function computeOffsets(_ref) + { + var reference = _ref.reference, + element = _ref.element, + placement = _ref.placement; + var basePlacement = placement ? getBasePlacement(placement) : null; + var variation = placement ? getVariation(placement) : null; + var commonX = reference.x + reference.width / 2 - element.width / 2; + var commonY = reference.y + reference.height / 2 - element.height / 2; + var offsets; + + switch (basePlacement) { + case top: + offsets = { + x: commonX, + y: reference.y - element.height + }; + break; + + case bottom: + offsets = { + x: commonX, + y: reference.y + reference.height + }; + break; + + case right: + offsets = { + x: reference.x + reference.width, + y: commonY + }; + break; + + case left: + offsets = { + x: reference.x - element.width, + y: commonY + }; + break; + + default: + offsets = { + x: reference.x, + y: reference.y + }; + } + + var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; + + if (mainAxis != null) { + var len = mainAxis === 'y' ? 'height' : 'width'; + + switch (variation) { + case start: + offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); + break; + + case end: + offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); + break; + } + } + + return offsets; + } + + function getFreshSideObject() + { + return { + top: 0, + right: 0, + bottom: 0, + left: 0 + }; + } + + function mergePaddingObject(paddingObject) + { + return Object.assign(Object.assign({}, getFreshSideObject()), paddingObject); + } + + function expandToHashMap(value, keys) + { + return keys.reduce(function (hashMap, key) { + hashMap[key] = value; + return hashMap; + }, {}); + } + + function detectOverflow(state, options) + { + if (options === void 0) { + options = {}; + } + + var _options = options, + _options$placement = _options.placement, + placement = _options$placement === void 0 ? state.placement : _options$placement, + _options$boundary = _options.boundary, + boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, + _options$rootBoundary = _options.rootBoundary, + rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, + _options$elementConte = _options.elementContext, + elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, + _options$altBoundary = _options.altBoundary, + altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, + _options$padding = _options.padding, + padding = _options$padding === void 0 ? 0 : _options$padding; + var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); + var altContext = elementContext === popper ? reference : popper; + var referenceElement = state.elements.reference; + var popperRect = state.rects.popper; + var element = state.elements[altBoundary ? altContext : elementContext]; + var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary); + var referenceClientRect = getBoundingClientRect(referenceElement); + var popperOffsets = computeOffsets({ + reference: referenceClientRect, + element: popperRect, + strategy: 'absolute', + placement: placement + }); + var popperClientRect = rectToClientRect(Object.assign(Object.assign({}, popperRect), popperOffsets)); + var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect + // 0 or negative = within the clipping rect + + var overflowOffsets = { + top: clippingClientRect.top - elementClientRect.top + paddingObject.top, + bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, + left: clippingClientRect.left - elementClientRect.left + paddingObject.left, + right: elementClientRect.right - clippingClientRect.right + paddingObject.right + }; + var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element + + if (elementContext === popper && offsetData) { + var offset = offsetData[placement]; + Object.keys(overflowOffsets).forEach(function (key) { + var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; + var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x'; + overflowOffsets[key] += offset[axis] * multiply; + }); + } + + return overflowOffsets; + } + + var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.'; + var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.'; + var DEFAULT_OPTIONS = { + placement: 'bottom', + modifiers: [], + strategy: 'absolute' + }; + + function areValidElements() + { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return !args.some(function (element) { + return !(element && typeof element.getBoundingClientRect === 'function'); + }); + } + + function popperGenerator(generatorOptions) + { + if (generatorOptions === void 0) { + generatorOptions = {}; + } + + var _generatorOptions = generatorOptions, + _generatorOptions$def = _generatorOptions.defaultModifiers, + defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, + _generatorOptions$def2 = _generatorOptions.defaultOptions, + defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; + return function createPopper(reference, popper, options) + { + if (options === void 0) { + options = defaultOptions; + } + + var state = { + placement: 'bottom', + orderedModifiers: [], + options: Object.assign(Object.assign({}, DEFAULT_OPTIONS), defaultOptions), + modifiersData: {}, + elements: { + reference: reference, + popper: popper + }, + attributes: {}, + styles: {} + }; + var effectCleanupFns = []; + var isDestroyed = false; + var instance = { + state: state, + setOptions: function setOptions(options) + { + cleanupModifierEffects(); + state.options = Object.assign(Object.assign(Object.assign({}, defaultOptions), state.options), options); + state.scrollParents = { + reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], + popper: listScrollParents(popper) + }; // Orders the modifiers based on their dependencies and `phase` + // properties + + var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers + + state.orderedModifiers = orderedModifiers.filter(function (m) { + return m.enabled; + }); // Validate the provided modifiers so that the consumer will get warned + // if one of the modifiers is invalid for any reason + + { + var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) { + var name = _ref.name; + return name; + }); + validateModifiers(modifiers); + + if (getBasePlacement(state.options.placement) === auto) { + var flipModifier = state.orderedModifiers.find(function (_ref2) { + var name = _ref2.name; + return name === 'flip'; + }); + + if (!flipModifier) { + console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' ')); + } + } + + var _getComputedStyle = getComputedStyle(popper), + marginTop = _getComputedStyle.marginTop, + marginRight = _getComputedStyle.marginRight, + marginBottom = _getComputedStyle.marginBottom, + marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can + // cause bugs with positioning, so we'll warn the consumer + + + if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) { + return parseFloat(margin); + })) { + console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' ')); + } + } + + runModifierEffects(); + return instance.update(); + }, + // Sync update – it will always be executed, even if not necessary. This + // is useful for low frequency updates where sync behavior simplifies the + // logic. + // For high frequency updates (e.g. `resize` and `scroll` events), always + // prefer the async Popper#update method + forceUpdate: function forceUpdate() + { + if (isDestroyed) { + return; + } + + var _state$elements = state.elements, + reference = _state$elements.reference, + popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements + // anymore + + if (!areValidElements(reference, popper)) { + { + console.error(INVALID_ELEMENT_ERROR); + } + + return; + } // Store the reference and popper rects to be read by modifiers + + + state.rects = { + reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), + popper: getLayoutRect(popper) + }; // Modifiers have the ability to reset the current update cycle. The + // most common use case for this is the `flip` modifier changing the + // placement, which then needs to re-run all the modifiers, because the + // logic was previously ran for the previous placement and is therefore + // stale/incorrect + + state.reset = false; + state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier + // is filled with the initial data specified by the modifier. This means + // it doesn't persist and is fresh on each update. + // To ensure persistent data, use `${name}#persistent` + + state.orderedModifiers.forEach(function (modifier) { + return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); + }); + var __debug_loops__ = 0; + + for (var index = 0; index < state.orderedModifiers.length; index++) { + { + __debug_loops__ += 1; + + if (__debug_loops__ > 100) { + console.error(INFINITE_LOOP_ERROR); + break; + } + } + + if (state.reset === true) { + state.reset = false; + index = -1; + continue; + } + + var _state$orderedModifie = state.orderedModifiers[index], + fn = _state$orderedModifie.fn, + _state$orderedModifie2 = _state$orderedModifie.options, + _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, + name = _state$orderedModifie.name; + + if (typeof fn === 'function') { + state = fn({ + state: state, + options: _options, + name: name, + instance: instance + }) || state; + } + } + }, + // Async and optimistically optimized update – it will not be executed if + // not necessary (debounced to run at most once-per-tick) + update: debounce(function () { + return new Promise(function (resolve) { + instance.forceUpdate(); + resolve(state); + }); + }), + destroy: function destroy() + { + cleanupModifierEffects(); + isDestroyed = true; + } + }; + + if (!areValidElements(reference, popper)) { + { + console.error(INVALID_ELEMENT_ERROR); + } + + return instance; + } + + instance.setOptions(options).then(function (state) { + if (!isDestroyed && options.onFirstUpdate) { + options.onFirstUpdate(state); + } + }); // Modifiers have the ability to execute arbitrary code before the first + // update cycle runs. They will be executed in the same order as the update + // cycle. This is useful when a modifier adds some persistent data that + // other modifiers need to use, but the modifier is run after the dependent + // one. + + function runModifierEffects() + { + state.orderedModifiers.forEach(function (_ref3) { + var name = _ref3.name, + _ref3$options = _ref3.options, + options = _ref3$options === void 0 ? {} : _ref3$options, + effect = _ref3.effect; + + if (typeof effect === 'function') { + var cleanupFn = effect({ + state: state, + name: name, + instance: instance, + options: options + }); + + var noopFn = function noopFn() + {}; + + effectCleanupFns.push(cleanupFn || noopFn); + } + }); + } + + function cleanupModifierEffects() + { + effectCleanupFns.forEach(function (fn) { + return fn(); + }); + effectCleanupFns = []; + } + + return instance; + }; + } + + var passive = { + passive: true + }; + + function effect(_ref) + { + var state = _ref.state, + instance = _ref.instance, + options = _ref.options; + var _options$scroll = options.scroll, + scroll = _options$scroll === void 0 ? true : _options$scroll, + _options$resize = options.resize, + resize = _options$resize === void 0 ? true : _options$resize; + var window = getWindow(state.elements.popper); + var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); + + if (scroll) { + scrollParents.forEach(function (scrollParent) { + scrollParent.addEventListener('scroll', instance.update, passive); + }); + } + + if (resize) { + window.addEventListener('resize', instance.update, passive); + } + + return function () { + if (scroll) { + scrollParents.forEach(function (scrollParent) { + scrollParent.removeEventListener('scroll', instance.update, passive); + }); + } + + if (resize) { + window.removeEventListener('resize', instance.update, passive); + } + }; + } // eslint-disable-next-line import/no-unused-modules + + + var eventListeners = { + name: 'eventListeners', + enabled: true, + phase: 'write', + fn: function fn() + {}, + effect: effect, + data: {} + }; + + function popperOffsets(_ref) + { + var state = _ref.state, + name = _ref.name; + // Offsets are the actual position the popper needs to have to be + // properly positioned near its reference element + // This is the most basic placement, and will be adjusted by + // the modifiers in the next step + state.modifiersData[name] = computeOffsets({ + reference: state.rects.reference, + element: state.rects.popper, + strategy: 'absolute', + placement: state.placement + }); + } // eslint-disable-next-line import/no-unused-modules + + + var popperOffsets$1 = { + name: 'popperOffsets', + enabled: true, + phase: 'read', + fn: popperOffsets, + data: {} + }; + + var unsetSides = { + top: 'auto', + right: 'auto', + bottom: 'auto', + left: 'auto' + }; // Round the offsets to the nearest suitable subpixel based on the DPR. + // Zooming can change the DPR, but it seems to report a value that will + // cleanly divide the values into the appropriate subpixels. + + function roundOffsetsByDPR(_ref) + { + var x = _ref.x, + y = _ref.y; + var win = window; + var dpr = win.devicePixelRatio || 1; + return { + x: Math.round(x * dpr) / dpr || 0, + y: Math.round(y * dpr) / dpr || 0 + }; + } + + function mapToStyles(_ref2) + { + var _Object$assign2; + + var popper = _ref2.popper, + popperRect = _ref2.popperRect, + placement = _ref2.placement, + offsets = _ref2.offsets, + position = _ref2.position, + gpuAcceleration = _ref2.gpuAcceleration, + adaptive = _ref2.adaptive, + roundOffsets = _ref2.roundOffsets; + + var _ref3 = roundOffsets ? roundOffsetsByDPR(offsets) : offsets, + _ref3$x = _ref3.x, + x = _ref3$x === void 0 ? 0 : _ref3$x, + _ref3$y = _ref3.y, + y = _ref3$y === void 0 ? 0 : _ref3$y; + + var hasX = offsets.hasOwnProperty('x'); + var hasY = offsets.hasOwnProperty('y'); + var sideX = left; + var sideY = top; + var win = window; + + if (adaptive) { + var offsetParent = getOffsetParent(popper); + + if (offsetParent === getWindow(popper)) { + offsetParent = getDocumentElement(popper); + } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it + + /*:: offsetParent = (offsetParent: Element); */ + + + if (placement === top) { + sideY = bottom; + y -= offsetParent.clientHeight - popperRect.height; + y *= gpuAcceleration ? 1 : -1; + } + + if (placement === left) { + sideX = right; + x -= offsetParent.clientWidth - popperRect.width; + x *= gpuAcceleration ? 1 : -1; + } + } + + var commonStyles = Object.assign({ + position: position + }, adaptive && unsetSides); + + if (gpuAcceleration) { + var _Object$assign; + + return Object.assign(Object.assign({}, commonStyles), {}, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) < 2 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); + } + + return Object.assign(Object.assign({}, commonStyles), {}, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); + } + + function computeStyles(_ref4) + { + var state = _ref4.state, + options = _ref4.options; + var _options$gpuAccelerat = options.gpuAcceleration, + gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, + _options$adaptive = options.adaptive, + adaptive = _options$adaptive === void 0 ? true : _options$adaptive, + _options$roundOffsets = options.roundOffsets, + roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; + + { + var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || ''; + + if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) { + return transitionProperty.indexOf(property) >= 0; + })) { + console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' ')); + } + } + + var commonStyles = { + placement: getBasePlacement(state.placement), + popper: state.elements.popper, + popperRect: state.rects.popper, + gpuAcceleration: gpuAcceleration + }; + + if (state.modifiersData.popperOffsets != null) { + state.styles.popper = Object.assign(Object.assign({}, state.styles.popper), mapToStyles(Object.assign(Object.assign({}, commonStyles), {}, { + offsets: state.modifiersData.popperOffsets, + position: state.options.strategy, + adaptive: adaptive, + roundOffsets: roundOffsets + }))); + } + + if (state.modifiersData.arrow != null) { + state.styles.arrow = Object.assign(Object.assign({}, state.styles.arrow), mapToStyles(Object.assign(Object.assign({}, commonStyles), {}, { + offsets: state.modifiersData.arrow, + position: 'absolute', + adaptive: false, + roundOffsets: roundOffsets + }))); + } + + state.attributes.popper = Object.assign(Object.assign({}, state.attributes.popper), {}, { + 'data-popper-placement': state.placement + }); + } // eslint-disable-next-line import/no-unused-modules + + + var computeStyles$1 = { + name: 'computeStyles', + enabled: true, + phase: 'beforeWrite', + fn: computeStyles, + data: {} + }; + + // and applies them to the HTMLElements such as popper and arrow + + function applyStyles(_ref) + { + var state = _ref.state; + Object.keys(state.elements).forEach(function (name) { + var style = state.styles[name] || {}; + var attributes = state.attributes[name] || {}; + var element = state.elements[name]; // arrow is optional + virtual elements + + if (!isHTMLElement(element) || !getNodeName(element)) { + return; + } // Flow doesn't support to extend this property, but it's the most + // effective way to apply styles to an HTMLElement + // $FlowFixMe[cannot-write] + + + Object.assign(element.style, style); + Object.keys(attributes).forEach(function (name) { + var value = attributes[name]; + + if (value === false) { + element.removeAttribute(name); + } else { + element.setAttribute(name, value === true ? '' : value); + } + }); + }); + } + + function effect$1(_ref2) + { + var state = _ref2.state; + var initialStyles = { + popper: { + position: state.options.strategy, + left: '0', + top: '0', + margin: '0' + }, + arrow: { + position: 'absolute' + }, + reference: {} + }; + Object.assign(state.elements.popper.style, initialStyles.popper); + + if (state.elements.arrow) { + Object.assign(state.elements.arrow.style, initialStyles.arrow); + } + + return function () { + Object.keys(state.elements).forEach(function (name) { + var element = state.elements[name]; + var attributes = state.attributes[name] || {}; + var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them + + var style = styleProperties.reduce(function (style, property) { + style[property] = ''; + return style; + }, {}); // arrow is optional + virtual elements + + if (!isHTMLElement(element) || !getNodeName(element)) { + return; + } + + Object.assign(element.style, style); + Object.keys(attributes).forEach(function (attribute) { + element.removeAttribute(attribute); + }); + }); + }; + } // eslint-disable-next-line import/no-unused-modules + + + var applyStyles$1 = { + name: 'applyStyles', + enabled: true, + phase: 'write', + fn: applyStyles, + effect: effect$1, + requires: ['computeStyles'] + }; + + function distanceAndSkiddingToXY(placement, rects, offset) + { + var basePlacement = getBasePlacement(placement); + var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; + + var _ref = typeof offset === 'function' ? offset(Object.assign(Object.assign({}, rects), {}, { + placement: placement + })) : offset, + skidding = _ref[0], + distance = _ref[1]; + + skidding = skidding || 0; + distance = (distance || 0) * invertDistance; + return [left, right].indexOf(basePlacement) >= 0 ? { + x: distance, + y: skidding + } : { + x: skidding, + y: distance + }; + } + + function offset(_ref2) + { + var state = _ref2.state, + options = _ref2.options, + name = _ref2.name; + var _options$offset = options.offset, + offset = _options$offset === void 0 ? [0, 0] : _options$offset; + var data = placements.reduce(function (acc, placement) { + acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); + return acc; + }, {}); + var _data$state$placement = data[state.placement], + x = _data$state$placement.x, + y = _data$state$placement.y; + + if (state.modifiersData.popperOffsets != null) { + state.modifiersData.popperOffsets.x += x; + state.modifiersData.popperOffsets.y += y; + } + + state.modifiersData[name] = data; + } // eslint-disable-next-line import/no-unused-modules + + + var offset$1 = { + name: 'offset', + enabled: true, + phase: 'main', + requires: ['popperOffsets'], + fn: offset + }; + + var hash = { + left: 'right', + right: 'left', + bottom: 'top', + top: 'bottom' + }; + + function getOppositePlacement(placement) + { + return placement.replace(/left|right|bottom|top/g, function (matched) { + return hash[matched]; + }); + } + + var hash$1 = { + start: 'end', + end: 'start' + }; + + function getOppositeVariationPlacement(placement) + { + return placement.replace(/start|end/g, function (matched) { + return hash$1[matched]; + }); + } + + /*:: type OverflowsMap = { [ComputedPlacement]: number }; */ + + /*;; type OverflowsMap = { [key in ComputedPlacement]: number }; */ + function computeAutoPlacement(state, options) + { + if (options === void 0) { + options = {}; + } + + var _options = options, + placement = _options.placement, + boundary = _options.boundary, + rootBoundary = _options.rootBoundary, + padding = _options.padding, + flipVariations = _options.flipVariations, + _options$allowedAutoP = _options.allowedAutoPlacements, + allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; + var variation = getVariation(placement); + var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) { + return getVariation(placement) === variation; + }) : basePlacements; + var allowedPlacements = placements$1.filter(function (placement) { + return allowedAutoPlacements.indexOf(placement) >= 0; + }); + + if (allowedPlacements.length === 0) { + allowedPlacements = placements$1; + + { + console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(' ')); + } + } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... + + + var overflows = allowedPlacements.reduce(function (acc, placement) { + acc[placement] = detectOverflow(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding + })[getBasePlacement(placement)]; + return acc; + }, {}); + return Object.keys(overflows).sort(function (a, b) { + return overflows[a] - overflows[b]; + }); + } + + function getExpandedFallbackPlacements(placement) + { + if (getBasePlacement(placement) === auto) { + return []; + } + + var oppositePlacement = getOppositePlacement(placement); + return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; + } + + function flip(_ref) + { + var state = _ref.state, + options = _ref.options, + name = _ref.name; + + if (state.modifiersData[name]._skip) { + return; + } + + var _options$mainAxis = options.mainAxis, + checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, + _options$altAxis = options.altAxis, + checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, + specifiedFallbackPlacements = options.fallbackPlacements, + padding = options.padding, + boundary = options.boundary, + rootBoundary = options.rootBoundary, + altBoundary = options.altBoundary, + _options$flipVariatio = options.flipVariations, + flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, + allowedAutoPlacements = options.allowedAutoPlacements; + var preferredPlacement = state.options.placement; + var basePlacement = getBasePlacement(preferredPlacement); + var isBasePlacement = basePlacement === preferredPlacement; + var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); + var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { + return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding, + flipVariations: flipVariations, + allowedAutoPlacements: allowedAutoPlacements + }) : placement); + }, []); + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var checksMap = new Map(); + var makeFallbackChecks = true; + var firstFittingPlacement = placements[0]; + + for (var i = 0; i < placements.length; i++) { + var placement = placements[i]; + + var _basePlacement = getBasePlacement(placement); + + var isStartVariation = getVariation(placement) === start; + var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; + var len = isVertical ? 'width' : 'height'; + var overflow = detectOverflow(state, { + placement: placement, + boundary: boundary, + rootBoundary: rootBoundary, + altBoundary: altBoundary, + padding: padding + }); + var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; + + if (referenceRect[len] > popperRect[len]) { + mainVariationSide = getOppositePlacement(mainVariationSide); + } + + var altVariationSide = getOppositePlacement(mainVariationSide); + var checks = []; + + if (checkMainAxis) { + checks.push(overflow[_basePlacement] <= 0); + } + + if (checkAltAxis) { + checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); + } + + if (checks.every(function (check) { + return check; + })) { + firstFittingPlacement = placement; + makeFallbackChecks = false; + break; + } + + checksMap.set(placement, checks); + } + + if (makeFallbackChecks) { + // `2` may be desired in some cases – research later + var numberOfChecks = flipVariations ? 3 : 1; + + var _loop = function _loop(_i) + { + var fittingPlacement = placements.find(function (placement) { + var checks = checksMap.get(placement); + + if (checks) { + return checks.slice(0, _i).every(function (check) { + return check; + }); + } + }); + + if (fittingPlacement) { + firstFittingPlacement = fittingPlacement; + return "break"; + } + }; + + for (var _i = numberOfChecks; _i > 0; _i--) { + var _ret = _loop(_i); + + if (_ret === "break") { + break; + } + } + } + + if (state.placement !== firstFittingPlacement) { + state.modifiersData[name]._skip = true; + state.placement = firstFittingPlacement; + state.reset = true; + } + } // eslint-disable-next-line import/no-unused-modules + + + var flip$1 = { + name: 'flip', + enabled: true, + phase: 'main', + fn: flip, + requiresIfExists: ['offset'], + data: { + _skip: false + } + }; + + function getAltAxis(axis) + { + return axis === 'x' ? 'y' : 'x'; + } + + function within(min, value, max) + { + return Math.max(min, Math.min(value, max)); + } + + function preventOverflow(_ref) + { + var state = _ref.state, + options = _ref.options, + name = _ref.name; + var _options$mainAxis = options.mainAxis, + checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, + _options$altAxis = options.altAxis, + checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, + boundary = options.boundary, + rootBoundary = options.rootBoundary, + altBoundary = options.altBoundary, + padding = options.padding, + _options$tether = options.tether, + tether = _options$tether === void 0 ? true : _options$tether, + _options$tetherOffset = options.tetherOffset, + tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; + var overflow = detectOverflow(state, { + boundary: boundary, + rootBoundary: rootBoundary, + padding: padding, + altBoundary: altBoundary + }); + var basePlacement = getBasePlacement(state.placement); + var variation = getVariation(state.placement); + var isBasePlacement = !variation; + var mainAxis = getMainAxisFromPlacement(basePlacement); + var altAxis = getAltAxis(mainAxis); + var popperOffsets = state.modifiersData.popperOffsets; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign(Object.assign({}, state.rects), {}, { + placement: state.placement + })) : tetherOffset; + var data = { + x: 0, + y: 0 + }; + + if (!popperOffsets) { + return; + } + + if (checkMainAxis) { + var mainSide = mainAxis === 'y' ? top : left; + var altSide = mainAxis === 'y' ? bottom : right; + var len = mainAxis === 'y' ? 'height' : 'width'; + var offset = popperOffsets[mainAxis]; + var min = popperOffsets[mainAxis] + overflow[mainSide]; + var max = popperOffsets[mainAxis] - overflow[altSide]; + var additive = tether ? -popperRect[len] / 2 : 0; + var minLen = variation === start ? referenceRect[len] : popperRect[len]; + var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go + // outside the reference bounds + + var arrowElement = state.elements.arrow; + var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { + width: 0, + height: 0 + }; + var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject(); + var arrowPaddingMin = arrowPaddingObject[mainSide]; + var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want + // to include its full size in the calculation. If the reference is small + // and near the edge of a boundary, the popper can overflow even if the + // reference is not overflowing as well (e.g. virtual elements with no + // width or height) + + var arrowLen = within(0, referenceRect[len], arrowRect[len]); + var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue; + var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue; + var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); + var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; + var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0; + var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset; + var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue; + var preventedOffset = within(tether ? Math.min(min, tetherMin) : min, offset, tether ? Math.max(max, tetherMax) : max); + popperOffsets[mainAxis] = preventedOffset; + data[mainAxis] = preventedOffset - offset; + } + + if (checkAltAxis) { + var _mainSide = mainAxis === 'x' ? top : left; + + var _altSide = mainAxis === 'x' ? bottom : right; + + var _offset = popperOffsets[altAxis]; + + var _min = _offset + overflow[_mainSide]; + + var _max = _offset - overflow[_altSide]; + + var _preventedOffset = within(_min, _offset, _max); + + popperOffsets[altAxis] = _preventedOffset; + data[altAxis] = _preventedOffset - _offset; + } + + state.modifiersData[name] = data; + } // eslint-disable-next-line import/no-unused-modules + + + var preventOverflow$1 = { + name: 'preventOverflow', + enabled: true, + phase: 'main', + fn: preventOverflow, + requiresIfExists: ['offset'] + }; + + function arrow(_ref) + { + var _state$modifiersData$; + + var state = _ref.state, + name = _ref.name; + var arrowElement = state.elements.arrow; + var popperOffsets = state.modifiersData.popperOffsets; + var basePlacement = getBasePlacement(state.placement); + var axis = getMainAxisFromPlacement(basePlacement); + var isVertical = [left, right].indexOf(basePlacement) >= 0; + var len = isVertical ? 'height' : 'width'; + + if (!arrowElement || !popperOffsets) { + return; + } + + var paddingObject = state.modifiersData[name + "#persistent"].padding; + var arrowRect = getLayoutRect(arrowElement); + var minProp = axis === 'y' ? top : left; + var maxProp = axis === 'y' ? bottom : right; + var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; + var startDiff = popperOffsets[axis] - state.rects.reference[axis]; + var arrowOffsetParent = getOffsetParent(arrowElement); + var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; + var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is + // outside of the popper bounds + + var min = paddingObject[minProp]; + var max = clientSize - arrowRect[len] - paddingObject[maxProp]; + var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; + var offset = within(min, center, max); // Prevents breaking syntax highlighting... + + var axisProp = axis; + state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); + } + + function effect$2(_ref2) + { + var state = _ref2.state, + options = _ref2.options, + name = _ref2.name; + var _options$element = options.element, + arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element, + _options$padding = options.padding, + padding = _options$padding === void 0 ? 0 : _options$padding; + + if (arrowElement == null) { + return; + } // CSS selector + + + if (typeof arrowElement === 'string') { + arrowElement = state.elements.popper.querySelector(arrowElement); + + if (!arrowElement) { + return; + } + } + + { + if (!isHTMLElement(arrowElement)) { + console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' ')); + } + } + + if (!contains(state.elements.popper, arrowElement)) { + { + console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' ')); + } + + return; + } + + state.elements.arrow = arrowElement; + state.modifiersData[name + "#persistent"] = { + padding: mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)) + }; + } // eslint-disable-next-line import/no-unused-modules + + + var arrow$1 = { + name: 'arrow', + enabled: true, + phase: 'main', + fn: arrow, + effect: effect$2, + requires: ['popperOffsets'], + requiresIfExists: ['preventOverflow'] + }; + + function getSideOffsets(overflow, rect, preventedOffsets) + { + if (preventedOffsets === void 0) { + preventedOffsets = { + x: 0, + y: 0 + }; + } + + return { + top: overflow.top - rect.height - preventedOffsets.y, + right: overflow.right - rect.width + preventedOffsets.x, + bottom: overflow.bottom - rect.height + preventedOffsets.y, + left: overflow.left - rect.width - preventedOffsets.x + }; + } + + function isAnySideFullyClipped(overflow) + { + return [top, right, bottom, left].some(function (side) { + return overflow[side] >= 0; + }); + } + + function hide(_ref) + { + var state = _ref.state, + name = _ref.name; + var referenceRect = state.rects.reference; + var popperRect = state.rects.popper; + var preventedOffsets = state.modifiersData.preventOverflow; + var referenceOverflow = detectOverflow(state, { + elementContext: 'reference' + }); + var popperAltOverflow = detectOverflow(state, { + altBoundary: true + }); + var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); + var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); + var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); + var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); + state.modifiersData[name] = { + referenceClippingOffsets: referenceClippingOffsets, + popperEscapeOffsets: popperEscapeOffsets, + isReferenceHidden: isReferenceHidden, + hasPopperEscaped: hasPopperEscaped + }; + state.attributes.popper = Object.assign(Object.assign({}, state.attributes.popper), {}, { + 'data-popper-reference-hidden': isReferenceHidden, + 'data-popper-escaped': hasPopperEscaped + }); + } // eslint-disable-next-line import/no-unused-modules + + + var hide$1 = { + name: 'hide', + enabled: true, + phase: 'main', + requiresIfExists: ['preventOverflow'], + fn: hide + }; + + var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1]; + var createPopper = /*#__PURE__*/ popperGenerator({ + defaultModifiers: defaultModifiers + }); // eslint-disable-next-line import/no-unused-modules + + var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1]; + var createPopper$1 = /*#__PURE__*/ popperGenerator({ + defaultModifiers: defaultModifiers$1 + }); // eslint-disable-next-line import/no-unused-modules + + exports.applyStyles = applyStyles$1; + exports.arrow = arrow$1; + exports.computeStyles = computeStyles$1; + exports.createPopper = createPopper$1; + exports.createPopperLite = createPopper; + exports.defaultModifiers = defaultModifiers$1; + exports.detectOverflow = detectOverflow; + exports.eventListeners = eventListeners; + exports.flip = flip$1; + exports.hide = hide$1; + exports.offset = offset$1; + exports.popperGenerator = popperGenerator; + exports.popperOffsets = popperOffsets$1; + exports.preventOverflow = preventOverflow$1; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/assets/js/popper/popper.min.js b/html/wp-content/plugins/duplicator/assets/js/popper/popper.min.js new file mode 100644 index 0000000..91669bd --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/js/popper/popper.min.js @@ -0,0 +1,5 @@ +/*! + * @popperjs/core v2.6.0 - MIT License + */ + +"use strict";!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).Popper={})}(this,(function(e){function t(e){return{width:(e=e.getBoundingClientRect()).width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function n(e){return"[object Window]"!==e.toString()?(e=e.ownerDocument)&&e.defaultView||window:e}function r(e){return{scrollLeft:(e=n(e)).pageXOffset,scrollTop:e.pageYOffset}}function o(e){return e instanceof n(e).Element||e instanceof Element}function i(e){return e instanceof n(e).HTMLElement||e instanceof HTMLElement}function a(e){return e?(e.nodeName||"").toLowerCase():null}function s(e){return((o(e)?e.ownerDocument:e.document)||window.document).documentElement}function f(e){return t(s(e)).left+r(e).scrollLeft}function c(e){return n(e).getComputedStyle(e)}function p(e){return e=c(e),/auto|scroll|overlay|hidden/.test(e.overflow+e.overflowY+e.overflowX)}function l(e,o,c){void 0===c&&(c=!1);var l=s(o);e=t(e);var u=i(o),d={scrollLeft:0,scrollTop:0},m={x:0,y:0};return(u||!u&&!c)&&(("body"!==a(o)||p(l))&&(d=o!==n(o)&&i(o)?{scrollLeft:o.scrollLeft,scrollTop:o.scrollTop}:r(o)),i(o)?((m=t(o)).x+=o.clientLeft,m.y+=o.clientTop):l&&(m.x=f(l))),{x:e.left+d.scrollLeft-m.x,y:e.top+d.scrollTop-m.y,width:e.width,height:e.height}}function u(e){return{x:e.offsetLeft,y:e.offsetTop,width:e.offsetWidth,height:e.offsetHeight}}function d(e){return"html"===a(e)?e:e.assignedSlot||e.parentNode||e.host||s(e)}function m(e,t){void 0===t&&(t=[]);var r=function e(t){return 0<=["html","body","#document"].indexOf(a(t))?t.ownerDocument.body:i(t)&&p(t)?t:e(d(t))}(e);e="body"===a(r);var o=n(r);return r=e?[o].concat(o.visualViewport||[],p(r)?r:[]):r,t=t.concat(r),e?t:t.concat(m(d(r)))}function h(e){if(!i(e)||"fixed"===c(e).position)return null;if(e=e.offsetParent){var t=s(e);if("body"===a(e)&&"static"===c(e).position&&"static"!==c(t).position)return t}return e}function g(e){for(var t=n(e),r=h(e);r&&0<=["table","td","th"].indexOf(a(r))&&"static"===c(r).position;)r=h(r);if(r&&"body"===a(r)&&"static"===c(r).position)return t;if(!r)e:{for(e=d(e);i(e)&&0>["html","body"].indexOf(a(e));){if("none"!==(r=c(e)).transform||"none"!==r.perspective||r.willChange&&"auto"!==r.willChange){r=e;break e}e=e.parentNode}r=null}return r||t}function v(e){var t=new Map,n=new Set,r=[];return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||function e(o){n.add(o.name),[].concat(o.requires||[],o.requiresIfExists||[]).forEach((function(r){n.has(r)||(r=t.get(r))&&e(r)})),r.push(o)}(e)})),r}function b(e){var t;return function(){return t||(t=new Promise((function(n){Promise.resolve().then((function(){t=void 0,n(e())}))}))),t}}function y(e){return e.split("-")[0]}function O(e,t){var r,o=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if((r=o)&&(r=o instanceof(r=n(o).ShadowRoot)||o instanceof ShadowRoot),r)do{if(t&&e.isSameNode(t))return!0;t=t.parentNode||t.host}while(t);return!1}function w(e){return Object.assign(Object.assign({},e),{},{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function x(e,o){if("viewport"===o){o=n(e);var a=s(e);o=o.visualViewport;var p=a.clientWidth;a=a.clientHeight;var l=0,u=0;o&&(p=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(l=o.offsetLeft,u=o.offsetTop)),e=w(e={width:p,height:a,x:l+f(e),y:u})}else i(o)?((e=t(o)).top+=o.clientTop,e.left+=o.clientLeft,e.bottom=e.top+o.clientHeight,e.right=e.left+o.clientWidth,e.width=o.clientWidth,e.height=o.clientHeight,e.x=e.left,e.y=e.top):(u=s(e),e=s(u),l=r(u),o=u.ownerDocument.body,p=Math.max(e.scrollWidth,e.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),a=Math.max(e.scrollHeight,e.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),u=-l.scrollLeft+f(u),l=-l.scrollTop,"rtl"===c(o||e).direction&&(u+=Math.max(e.clientWidth,o?o.clientWidth:0)-p),e=w({width:p,height:a,x:u,y:l}));return e}function j(e,t,n){return t="clippingParents"===t?function(e){var t=m(d(e)),n=0<=["absolute","fixed"].indexOf(c(e).position)&&i(e)?g(e):e;return o(n)?t.filter((function(e){return o(e)&&O(e,n)&&"body"!==a(e)})):[]}(e):[].concat(t),(n=(n=[].concat(t,[n])).reduce((function(t,n){return n=x(e,n),t.top=Math.max(n.top,t.top),t.right=Math.min(n.right,t.right),t.bottom=Math.min(n.bottom,t.bottom),t.left=Math.max(n.left,t.left),t}),x(e,n[0]))).width=n.right-n.left,n.height=n.bottom-n.top,n.x=n.left,n.y=n.top,n}function M(e){return 0<=["top","bottom"].indexOf(e)?"x":"y"}function E(e){var t=e.reference,n=e.element,r=(e=e.placement)?y(e):null;e=e?e.split("-")[1]:null;var o=t.x+t.width/2-n.width/2,i=t.y+t.height/2-n.height/2;switch(r){case"top":o={x:o,y:t.y-n.height};break;case"bottom":o={x:o,y:t.y+t.height};break;case"right":o={x:t.x+t.width,y:i};break;case"left":o={x:t.x-n.width,y:i};break;default:o={x:t.x,y:t.y}}if(null!=(r=r?M(r):null))switch(i="y"===r?"height":"width",e){case"start":o[r]-=t[i]/2-n[i]/2;break;case"end":o[r]+=t[i]/2-n[i]/2}return o}function D(e){return Object.assign(Object.assign({},{top:0,right:0,bottom:0,left:0}),e)}function P(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function L(e,n){void 0===n&&(n={});var r=n;n=void 0===(n=r.placement)?e.placement:n;var i=r.boundary,a=void 0===i?"clippingParents":i,f=void 0===(i=r.rootBoundary)?"viewport":i;i=void 0===(i=r.elementContext)?"popper":i;var c=r.altBoundary,p=void 0!==c&&c;r=D("number"!=typeof(r=void 0===(r=r.padding)?0:r)?r:P(r,T));var l=e.elements.reference;c=e.rects.popper,a=j(o(p=e.elements[p?"popper"===i?"reference":"popper":i])?p:p.contextElement||s(e.elements.popper),a,f),p=E({reference:f=t(l),element:c,strategy:"absolute",placement:n}),c=w(Object.assign(Object.assign({},c),p)),f="popper"===i?c:f;var u={top:a.top-f.top+r.top,bottom:f.bottom-a.bottom+r.bottom,left:a.left-f.left+r.left,right:f.right-a.right+r.right};if(e=e.modifiersData.offset,"popper"===i&&e){var d=e[n];Object.keys(u).forEach((function(e){var t=0<=["right","bottom"].indexOf(e)?1:-1,n=0<=["top","bottom"].indexOf(e)?"y":"x";u[e]+=d[n]*t}))}return u}function k(){for(var e=arguments.length,t=Array(e),n=0;n(v.devicePixelRatio||1)?"translate("+e+"px, "+l+"px)":"translate3d("+e+"px, "+l+"px, 0)",d)):Object.assign(Object.assign({},r),{},((t={})[h]=a?l+"px":"",t[m]=u?e+"px":"",t.transform="",t))}function A(e){return e.replace(/left|right|bottom|top/g,(function(e){return G[e]}))}function H(e){return e.replace(/start|end/g,(function(e){return J[e]}))}function R(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function S(e){return["top","right","bottom","left"].some((function(t){return 0<=e[t]}))}var T=["top","bottom","right","left"],q=T.reduce((function(e,t){return e.concat([t+"-start",t+"-end"])}),[]),C=[].concat(T,["auto"]).reduce((function(e,t){return e.concat([t,t+"-start",t+"-end"])}),[]),N="beforeRead read afterRead beforeMain main afterMain beforeWrite write afterWrite".split(" "),V={placement:"bottom",modifiers:[],strategy:"absolute"},I={passive:!0},_={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,r=e.instance,o=(e=e.options).scroll,i=void 0===o||o,a=void 0===(e=e.resize)||e,s=n(t.elements.popper),f=[].concat(t.scrollParents.reference,t.scrollParents.popper);return i&&f.forEach((function(e){e.addEventListener("scroll",r.update,I)})),a&&s.addEventListener("resize",r.update,I),function(){i&&f.forEach((function(e){e.removeEventListener("scroll",r.update,I)})),a&&s.removeEventListener("resize",r.update,I)}},data:{}},U={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state;t.modifiersData[e.name]=E({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},z={top:"auto",right:"auto",bottom:"auto",left:"auto"},F={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options;e=void 0===(e=n.gpuAcceleration)||e;var r=n.adaptive;r=void 0===r||r,n=void 0===(n=n.roundOffsets)||n,e={placement:y(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:e},null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign(Object.assign({},t.styles.popper),W(Object.assign(Object.assign({},e),{},{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:r,roundOffsets:n})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign(Object.assign({},t.styles.arrow),W(Object.assign(Object.assign({},e),{},{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:n})))),t.attributes.popper=Object.assign(Object.assign({},t.attributes.popper),{},{"data-popper-placement":t.placement})},data:{}},X={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},r=t.attributes[e]||{},o=t.elements[e];i(o)&&a(o)&&(Object.assign(o.style,n),Object.keys(r).forEach((function(e){var t=r[e];!1===t?o.removeAttribute(e):o.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var r=t.elements[e],o=t.attributes[e]||{};e=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{}),i(r)&&a(r)&&(Object.assign(r.style,e),Object.keys(o).forEach((function(e){r.removeAttribute(e)})))}))}},requires:["computeStyles"]},Y={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.name,r=void 0===(e=e.options.offset)?[0,0]:e,o=(e=C.reduce((function(e,n){var o=t.rects,i=y(n),a=0<=["left","top"].indexOf(i)?-1:1,s="function"==typeof r?r(Object.assign(Object.assign({},o),{},{placement:n})):r;return o=(o=s[0])||0,s=((s=s[1])||0)*a,i=0<=["left","right"].indexOf(i)?{x:s,y:o}:{x:o,y:s},e[n]=i,e}),{}))[t.placement],i=o.x;o=o.y,null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=i,t.modifiersData.popperOffsets.y+=o),t.modifiersData[n]=e}},G={left:"right",right:"left",bottom:"top",top:"bottom"},J={start:"end",end:"start"},K={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options;if(e=e.name,!t.modifiersData[e]._skip){var r=n.mainAxis;r=void 0===r||r;var o=n.altAxis;o=void 0===o||o;var i=n.fallbackPlacements,a=n.padding,s=n.boundary,f=n.rootBoundary,c=n.altBoundary,p=n.flipVariations,l=void 0===p||p,u=n.allowedAutoPlacements;p=y(n=t.options.placement),i=i||(p!==n&&l?function(e){if("auto"===y(e))return[];var t=A(e);return[H(e),t,H(t)]}(n):[A(n)]);var d=[n].concat(i).reduce((function(e,n){return e.concat("auto"===y(n)?function(e,t){void 0===t&&(t={});var n=t.boundary,r=t.rootBoundary,o=t.padding,i=t.flipVariations,a=t.allowedAutoPlacements,s=void 0===a?C:a,f=t.placement.split("-")[1];0===(i=(t=f?i?q:q.filter((function(e){return e.split("-")[1]===f})):T).filter((function(e){return 0<=s.indexOf(e)}))).length&&(i=t);var c=i.reduce((function(t,i){return t[i]=L(e,{placement:i,boundary:n,rootBoundary:r,padding:o})[y(i)],t}),{});return Object.keys(c).sort((function(e,t){return c[e]-c[t]}))}(t,{placement:n,boundary:s,rootBoundary:f,padding:a,flipVariations:l,allowedAutoPlacements:u}):n)}),[]);n=t.rects.reference,i=t.rects.popper;var m=new Map;p=!0;for(var h=d[0],g=0;gi[x]&&(O=A(O)),x=A(O),w=[],r&&w.push(0>=j[b]),o&&w.push(0>=j[O],0>=j[x]),w.every((function(e){return e}))){h=v,p=!1;break}m.set(v,w)}if(p)for(r=function(e){var t=d.find((function(t){if(t=m.get(t))return t.slice(0,e).every((function(e){return e}))}));if(t)return h=t,"break"},o=l?3:1;0.tippy-arrow::before { + bottom: -9px; +} + +.tippy-box[data-placement^='bottom']>.tippy-arrow::before { + top: -9px; +} + +.tippy-box[data-theme~='duplicator'], +.tippy-box[data-theme~='duplicator-filled'] { + border-color: #13659C; +} + +.tippy-box[data-theme~='duplicator'] h3, +.tippy-box[data-theme~='duplicato-filled'] h3 { + background-color: #13659C; + color: white; +} + +.tippy-box[data-theme~='duplicator-filled'] .tippy-content { + background-color: #13659C; + color: white; +} + +.tippy-box[data-theme~='duplicator'][data-placement^='top']>.tippy-arrow::before, +.tippy-box[data-theme~='duplicator-filled'][data-placement^='top']>.tippy-arrow::before { + border-top-color: #13659C; +} + +.tippy-box[data-theme~='duplicator'][data-placement^='bottom']>.tippy-arrow::before, +.tippy-box[data-theme~='duplicator-filled'][data-placement^='bottom']>.tippy-arrow::before { + border-bottom-color: #13659C; +} + +.tippy-box[data-theme~='duplicator'][data-placement^='left']>.tippy-arrow::before, +.tippy-box[data-theme~='duplicator-filled'][data-placement^='left']>.tippy-arrow::before { + border-left-color: #13659C; +} + +.tippy-box[data-theme~='duplicator'][data-placement^='right']>.tippy-arrow::before, +.tippy-box[data-theme~='duplicator-filled'][data-placement^='right']>.tippy-arrow::before { + border-right-color: #13659C; +} \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/assets/js/tippy/index.php b/html/wp-content/plugins/duplicator/assets/js/tippy/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/js/tippy/index.php @@ -0,0 +1,3 @@ +.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:\"\";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}"; + + function injectCSS(css) + { + var style = document.createElement('style'); + style.textContent = css; + style.setAttribute('data-tippy-stylesheet', ''); + var head = document.head; + var firstStyleOrLinkTag = document.querySelector('head>style,head>link'); + + if (firstStyleOrLinkTag) { + head.insertBefore(style, firstStyleOrLinkTag); + } else { + head.appendChild(style); + } + } + + var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'; + var ua = isBrowser ? navigator.userAgent : ''; + var isIE = /MSIE |Trident\//.test(ua); + + var ROUND_ARROW = ''; + var BOX_CLASS = "tippy-box"; + var CONTENT_CLASS = "tippy-content"; + var BACKDROP_CLASS = "tippy-backdrop"; + var ARROW_CLASS = "tippy-arrow"; + var SVG_ARROW_CLASS = "tippy-svg-arrow"; + var TOUCH_OPTIONS = { + passive: true, + capture: true + }; + + function hasOwnProperty(obj, key) + { + return {}.hasOwnProperty.call(obj, key); + } + function getValueAtIndexOrReturn(value, index, defaultValue) + { + if (Array.isArray(value)) { + var v = value[index]; + return v == null ? Array.isArray(defaultValue) ? defaultValue[index] : defaultValue : v; + } + + return value; + } + function isType(value, type) + { + var str = {}.toString.call(value); + return str.indexOf('[object') === 0 && str.indexOf(type + "]") > -1; + } + function invokeWithArgsOrReturn(value, args) + { + return typeof value === 'function' ? value.apply(void 0, args) : value; + } + function debounce(fn, ms) + { + // Avoid wrapping in `setTimeout` if ms is 0 anyway + if (ms === 0) { + return fn; + } + + var timeout; + return function (arg) { + clearTimeout(timeout); + timeout = setTimeout(function () { + fn(arg); + }, ms); + }; + } + function removeProperties(obj, keys) + { + var clone = Object.assign({}, obj); + keys.forEach(function (key) { + delete clone[key]; + }); + return clone; + } + function splitBySpaces(value) + { + return value.split(/\s+/).filter(Boolean); + } + function normalizeToArray(value) + { + return [].concat(value); + } + function pushIfUnique(arr, value) + { + if (arr.indexOf(value) === -1) { + arr.push(value); + } + } + function unique(arr) + { + return arr.filter(function (item, index) { + return arr.indexOf(item) === index; + }); + } + function getBasePlacement(placement) + { + return placement.split('-')[0]; + } + function arrayFrom(value) + { + return [].slice.call(value); + } + function removeUndefinedProps(obj) + { + return Object.keys(obj).reduce(function (acc, key) { + if (obj[key] !== undefined) { + acc[key] = obj[key]; + } + + return acc; + }, {}); + } + + function div() + { + return document.createElement('div'); + } + function isElement(value) + { + return ['Element', 'Fragment'].some(function (type) { + return isType(value, type); + }); + } + function isNodeList(value) + { + return isType(value, 'NodeList'); + } + function isMouseEvent(value) + { + return isType(value, 'MouseEvent'); + } + function isReferenceElement(value) + { + return !!(value && value._tippy && value._tippy.reference === value); + } + function getArrayOfElements(value) + { + if (isElement(value)) { + return [value]; + } + + if (isNodeList(value)) { + return arrayFrom(value); + } + + if (Array.isArray(value)) { + return value; + } + + return arrayFrom(document.querySelectorAll(value)); + } + function setTransitionDuration(els, value) + { + els.forEach(function (el) { + if (el) { + el.style.transitionDuration = value + "ms"; + } + }); + } + function setVisibilityState(els, state) + { + els.forEach(function (el) { + if (el) { + el.setAttribute('data-state', state); + } + }); + } + function getOwnerDocument(elementOrElements) + { + var _normalizeToArray = normalizeToArray(elementOrElements), + element = _normalizeToArray[0]; + + return element ? element.ownerDocument || document : document; + } + function isCursorOutsideInteractiveBorder(popperTreeData, event) + { + var clientX = event.clientX, + clientY = event.clientY; + return popperTreeData.every(function (_ref) { + var popperRect = _ref.popperRect, + popperState = _ref.popperState, + props = _ref.props; + var interactiveBorder = props.interactiveBorder; + var basePlacement = getBasePlacement(popperState.placement); + var offsetData = popperState.modifiersData.offset; + + if (!offsetData) { + return true; + } + + var topDistance = basePlacement === 'bottom' ? offsetData.top.y : 0; + var bottomDistance = basePlacement === 'top' ? offsetData.bottom.y : 0; + var leftDistance = basePlacement === 'right' ? offsetData.left.x : 0; + var rightDistance = basePlacement === 'left' ? offsetData.right.x : 0; + var exceedsTop = popperRect.top - clientY + topDistance > interactiveBorder; + var exceedsBottom = clientY - popperRect.bottom - bottomDistance > interactiveBorder; + var exceedsLeft = popperRect.left - clientX + leftDistance > interactiveBorder; + var exceedsRight = clientX - popperRect.right - rightDistance > interactiveBorder; + return exceedsTop || exceedsBottom || exceedsLeft || exceedsRight; + }); + } + function updateTransitionEndListener(box, action, listener) + { + var method = action + "EventListener"; // some browsers apparently support `transition` (unprefixed) but only fire + // `webkitTransitionEnd`... + + ['transitionend', 'webkitTransitionEnd'].forEach(function (event) { + box[method](event, listener); + }); + } + + var currentInput = { + isTouch: false + }; + var lastMouseMoveTime = 0; + /** + * When a `touchstart` event is fired, it's assumed the user is using touch + * input. We'll bind a `mousemove` event listener to listen for mouse input in + * the future. This way, the `isTouch` property is fully dynamic and will handle + * hybrid devices that use a mix of touch + mouse input. + */ + + function onDocumentTouchStart() + { + if (currentInput.isTouch) { + return; + } + + currentInput.isTouch = true; + + if (window.performance) { + document.addEventListener('mousemove', onDocumentMouseMove); + } + } + /** + * When two `mousemove` event are fired consecutively within 20ms, it's assumed + * the user is using mouse input again. `mousemove` can fire on touch devices as + * well, but very rarely that quickly. + */ + + function onDocumentMouseMove() + { + var now = performance.now(); + + if (now - lastMouseMoveTime < 20) { + currentInput.isTouch = false; + document.removeEventListener('mousemove', onDocumentMouseMove); + } + + lastMouseMoveTime = now; + } + /** + * When an element is in focus and has a tippy, leaving the tab/window and + * returning causes it to show again. For mouse users this is unexpected, but + * for keyboard use it makes sense. + * TODO: find a better technique to solve this problem + */ + + function onWindowBlur() + { + var activeElement = document.activeElement; + + if (isReferenceElement(activeElement)) { + var instance = activeElement._tippy; + + if (activeElement.blur && !instance.state.isVisible) { + activeElement.blur(); + } + } + } + function bindGlobalEventListeners() + { + document.addEventListener('touchstart', onDocumentTouchStart, TOUCH_OPTIONS); + window.addEventListener('blur', onWindowBlur); + } + + function createMemoryLeakWarning(method) + { + var txt = method === 'destroy' ? 'n already-' : ' '; + return [method + "() was called on a" + txt + "destroyed instance. This is a no-op but", 'indicates a potential memory leak.'].join(' '); + } + function clean(value) + { + var spacesAndTabs = /[ \t]{2,}/g; + var lineStartWithSpaces = /^[ \t]*/gm; + return value.replace(spacesAndTabs, ' ').replace(lineStartWithSpaces, '').trim(); + } + + function getDevMessage(message) + { + return clean("\n %ctippy.js\n\n %c" + clean(message) + "\n\n %c\uD83D\uDC77\u200D This is a development-only message. It will be removed in production.\n "); + } + + function getFormattedMessage(message) + { + return [getDevMessage(message), // title + 'color: #00C584; font-size: 1.3em; font-weight: bold;', // message + 'line-height: 1.5', // footer + 'color: #a6a095;']; + } // Assume warnings and errors never have the same message + + var visitedMessages; + + { + resetVisitedMessages(); + } + + function resetVisitedMessages() + { + visitedMessages = new Set(); + } + function warnWhen(condition, message) + { + if (condition && !visitedMessages.has(message)) { + var _console; + + visitedMessages.add(message); + + (_console = console).warn.apply(_console, getFormattedMessage(message)); + } + } + function errorWhen(condition, message) + { + if (condition && !visitedMessages.has(message)) { + var _console2; + + visitedMessages.add(message); + + (_console2 = console).error.apply(_console2, getFormattedMessage(message)); + } + } + function validateTargets(targets) + { + var didPassFalsyValue = !targets; + var didPassPlainObject = Object.prototype.toString.call(targets) === '[object Object]' && !targets.addEventListener; + errorWhen(didPassFalsyValue, ['tippy() was passed', '`' + String(targets) + '`', 'as its targets (first) argument. Valid types are: String, Element,', 'Element[], or NodeList.'].join(' ')); + errorWhen(didPassPlainObject, ['tippy() was passed a plain object which is not supported as an argument', 'for virtual positioning. Use props.getReferenceClientRect instead.'].join(' ')); + } + + var pluginProps = { + animateFill: false, + followCursor: false, + inlinePositioning: false, + sticky: false + }; + var renderProps = { + allowHTML: false, + animation: 'fade', + arrow: true, + content: '', + inertia: false, + maxWidth: 350, + role: 'tooltip', + theme: '', + zIndex: 9999 + }; + var defaultProps = Object.assign({ + appendTo: function appendTo() + { + return document.body; + }, + aria: { + content: 'auto', + expanded: 'auto' + }, + delay: 0, + duration: [300, 250], + getReferenceClientRect: null, + hideOnClick: true, + ignoreAttributes: false, + interactive: false, + interactiveBorder: 2, + interactiveDebounce: 0, + moveTransition: '', + offset: [0, 10], + onAfterUpdate: function onAfterUpdate() + {}, + onBeforeUpdate: function onBeforeUpdate() + {}, + onCreate: function onCreate() + {}, + onDestroy: function onDestroy() + {}, + onHidden: function onHidden() + {}, + onHide: function onHide() + {}, + onMount: function onMount() + {}, + onShow: function onShow() + {}, + onShown: function onShown() + {}, + onTrigger: function onTrigger() + {}, + onUntrigger: function onUntrigger() + {}, + onClickOutside: function onClickOutside() + {}, + placement: 'top', + plugins: [], + popperOptions: {}, + render: null, + showOnCreate: false, + touch: true, + trigger: 'mouseenter focus', + triggerTarget: null + }, pluginProps, {}, renderProps); + var defaultKeys = Object.keys(defaultProps); + var setDefaultProps = function setDefaultProps(partialProps) + { + /* istanbul ignore else */ + { + validateProps(partialProps, []); + } + + var keys = Object.keys(partialProps); + keys.forEach(function (key) { + defaultProps[key] = partialProps[key]; + }); + }; + function getExtendedPassedProps(passedProps) + { + var plugins = passedProps.plugins || []; + var pluginProps = plugins.reduce(function (acc, plugin) { + var name = plugin.name, + defaultValue = plugin.defaultValue; + + if (name) { + acc[name] = passedProps[name] !== undefined ? passedProps[name] : defaultValue; + } + + return acc; + }, {}); + return Object.assign({}, passedProps, {}, pluginProps); + } + function getDataAttributeProps(reference, plugins) + { + var propKeys = plugins ? Object.keys(getExtendedPassedProps(Object.assign({}, defaultProps, { + plugins: plugins + }))) : defaultKeys; + var props = propKeys.reduce(function (acc, key) { + var valueAsString = (reference.getAttribute("data-tippy-" + key) || '').trim(); + + if (!valueAsString) { + return acc; + } + + if (key === 'content') { + acc[key] = valueAsString; + } else { + try { + acc[key] = JSON.parse(valueAsString); + } catch (e) { + acc[key] = valueAsString; + } + } + + return acc; + }, {}); + return props; + } + function evaluateProps(reference, props) + { + var out = Object.assign({}, props, { + content: invokeWithArgsOrReturn(props.content, [reference]) + }, props.ignoreAttributes ? {} : getDataAttributeProps(reference, props.plugins)); + out.aria = Object.assign({}, defaultProps.aria, {}, out.aria); + out.aria = { + expanded: out.aria.expanded === 'auto' ? props.interactive : out.aria.expanded, + content: out.aria.content === 'auto' ? props.interactive ? null : 'describedby' : out.aria.content + }; + return out; + } + function validateProps(partialProps, plugins) + { + if (partialProps === void 0) { + partialProps = {}; + } + + if (plugins === void 0) { + plugins = []; + } + + var keys = Object.keys(partialProps); + keys.forEach(function (prop) { + var nonPluginProps = removeProperties(defaultProps, Object.keys(pluginProps)); + var didPassUnknownProp = !hasOwnProperty(nonPluginProps, prop); // Check if the prop exists in `plugins` + + if (didPassUnknownProp) { + didPassUnknownProp = plugins.filter(function (plugin) { + return plugin.name === prop; + }).length === 0; + } + + warnWhen(didPassUnknownProp, ["`" + prop + "`", "is not a valid prop. You may have spelled it incorrectly, or if it's", 'a plugin, forgot to pass it in an array as props.plugins.', '\n\n', 'All props: https://atomiks.github.io/tippyjs/v6/all-props/\n', 'Plugins: https://atomiks.github.io/tippyjs/v6/plugins/'].join(' ')); + }); + } + + var innerHTML = function innerHTML() + { + return 'innerHTML'; + }; + + function dangerouslySetInnerHTML(element, html) + { + element[innerHTML()] = html; + } + + function createArrowElement(value) + { + var arrow = div(); + + if (value === true) { + arrow.className = ARROW_CLASS; + } else { + arrow.className = SVG_ARROW_CLASS; + + if (isElement(value)) { + arrow.appendChild(value); + } else { + dangerouslySetInnerHTML(arrow, value); + } + } + + return arrow; + } + + function setContent(content, props) + { + if (isElement(props.content)) { + dangerouslySetInnerHTML(content, ''); + content.appendChild(props.content); + } else if (typeof props.content !== 'function') { + if (props.allowHTML) { + dangerouslySetInnerHTML(content, props.content); + } else { + content.textContent = props.content; + } + } + } + function getChildren(popper) + { + var box = popper.firstElementChild; + var boxChildren = arrayFrom(box.children); + return { + box: box, + content: boxChildren.find(function (node) { + return node.classList.contains(CONTENT_CLASS); + }), + arrow: boxChildren.find(function (node) { + return node.classList.contains(ARROW_CLASS) || node.classList.contains(SVG_ARROW_CLASS); + }), + backdrop: boxChildren.find(function (node) { + return node.classList.contains(BACKDROP_CLASS); + }) + }; + } + function render(instance) + { + var popper = div(); + var box = div(); + box.className = BOX_CLASS; + box.setAttribute('data-state', 'hidden'); + box.setAttribute('tabindex', '-1'); + var content = div(); + content.className = CONTENT_CLASS; + content.setAttribute('data-state', 'hidden'); + setContent(content, instance.props); + popper.appendChild(box); + box.appendChild(content); + onUpdate(instance.props, instance.props); + + function onUpdate(prevProps, nextProps) + { + var _getChildren = getChildren(popper), + box = _getChildren.box, + content = _getChildren.content, + arrow = _getChildren.arrow; + + if (nextProps.theme) { + box.setAttribute('data-theme', nextProps.theme); + } else { + box.removeAttribute('data-theme'); + } + + if (typeof nextProps.animation === 'string') { + box.setAttribute('data-animation', nextProps.animation); + } else { + box.removeAttribute('data-animation'); + } + + if (nextProps.inertia) { + box.setAttribute('data-inertia', ''); + } else { + box.removeAttribute('data-inertia'); + } + + box.style.maxWidth = typeof nextProps.maxWidth === 'number' ? nextProps.maxWidth + "px" : nextProps.maxWidth; + + if (nextProps.role) { + box.setAttribute('role', nextProps.role); + } else { + box.removeAttribute('role'); + } + + if (prevProps.content !== nextProps.content || prevProps.allowHTML !== nextProps.allowHTML) { + setContent(content, instance.props); + } + + if (nextProps.arrow) { + if (!arrow) { + box.appendChild(createArrowElement(nextProps.arrow)); + } else if (prevProps.arrow !== nextProps.arrow) { + box.removeChild(arrow); + box.appendChild(createArrowElement(nextProps.arrow)); + } + } else if (arrow) { + box.removeChild(arrow); + } + } + + return { + popper: popper, + onUpdate: onUpdate + }; + } // Runtime check to identify if the render function is the default one; this + // way we can apply default CSS transitions logic and it can be tree-shaken away + + render.$$tippy = true; + + var idCounter = 1; + var mouseMoveListeners = []; // Used by `hideAll()` + + var mountedInstances = []; + function createTippy(reference, passedProps) + { + var props = evaluateProps(reference, Object.assign({}, defaultProps, {}, getExtendedPassedProps(removeUndefinedProps(passedProps)))); // =========================================================================== + // 🔒 Private members + // =========================================================================== + + var showTimeout; + var hideTimeout; + var scheduleHideAnimationFrame; + var isVisibleFromClick = false; + var didHideDueToDocumentMouseDown = false; + var didTouchMove = false; + var ignoreOnFirstUpdate = false; + var lastTriggerEvent; + var currentTransitionEndListener; + var onFirstUpdate; + var listeners = []; + var debouncedOnMouseMove = debounce(onMouseMove, props.interactiveDebounce); + var currentTarget; // =========================================================================== + // 🔑 Public members + // =========================================================================== + + var id = idCounter++; + var popperInstance = null; + var plugins = unique(props.plugins); + var state = { + // Is the instance currently enabled? + isEnabled: true, + // Is the tippy currently showing and not transitioning out? + isVisible: false, + // Has the instance been destroyed? + isDestroyed: false, + // Is the tippy currently mounted to the DOM? + isMounted: false, + // Has the tippy finished transitioning in? + isShown: false + }; + var instance = { + // properties + id: id, + reference: reference, + popper: div(), + popperInstance: popperInstance, + props: props, + state: state, + plugins: plugins, + // methods + clearDelayTimeouts: clearDelayTimeouts, + setProps: setProps, + setContent: setContent, + show: show, + hide: hide, + hideWithInteractivity: hideWithInteractivity, + enable: enable, + disable: disable, + unmount: unmount, + destroy: destroy + }; // TODO: Investigate why this early return causes a TDZ error in the tests — + // it doesn't seem to happen in the browser + + /* istanbul ignore if */ + + if (!props.render) { + { + errorWhen(true, 'render() function has not been supplied.'); + } + + return instance; + } // =========================================================================== + // Initial mutations + // =========================================================================== + + + var _props$render = props.render(instance), + popper = _props$render.popper, + onUpdate = _props$render.onUpdate; + + popper.setAttribute('data-tippy-root', ''); + popper.id = "tippy-" + instance.id; + instance.popper = popper; + reference._tippy = instance; + popper._tippy = instance; + var pluginsHooks = plugins.map(function (plugin) { + return plugin.fn(instance); + }); + var hasAriaExpanded = reference.hasAttribute('aria-expanded'); + addListeners(); + handleAriaExpandedAttribute(); + handleStyles(); + invokeHook('onCreate', [instance]); + + if (props.showOnCreate) { + scheduleShow(); + } // Prevent a tippy with a delay from hiding if the cursor left then returned + // before it started hiding + + + popper.addEventListener('mouseenter', function () { + if (instance.props.interactive && instance.state.isVisible) { + instance.clearDelayTimeouts(); + } + }); + popper.addEventListener('mouseleave', function (event) { + if (instance.props.interactive && instance.props.trigger.indexOf('mouseenter') >= 0) { + getDocument().addEventListener('mousemove', debouncedOnMouseMove); + debouncedOnMouseMove(event); + } + }); + return instance; // =========================================================================== + // 🔒 Private methods + // =========================================================================== + + function getNormalizedTouchSettings() + { + var touch = instance.props.touch; + return Array.isArray(touch) ? touch : [touch, 0]; + } + + function getIsCustomTouchBehavior() + { + return getNormalizedTouchSettings()[0] === 'hold'; + } + + function getIsDefaultRenderFn() + { + var _instance$props$rende; + + // @ts-ignore + return !!((_instance$props$rende = instance.props.render) == null ? void 0 : _instance$props$rende.$$tippy); + } + + function getCurrentTarget() + { + return currentTarget || reference; + } + + function getDocument() + { + var parent = getCurrentTarget().parentNode; + return parent ? getOwnerDocument(parent) : document; + } + + function getDefaultTemplateChildren() + { + return getChildren(popper); + } + + function getDelay(isShow) + { + // For touch or keyboard input, force `0` delay for UX reasons + // Also if the instance is mounted but not visible (transitioning out), + // ignore delay + if (instance.state.isMounted && !instance.state.isVisible || currentInput.isTouch || lastTriggerEvent && lastTriggerEvent.type === 'focus') { + return 0; + } + + return getValueAtIndexOrReturn(instance.props.delay, isShow ? 0 : 1, defaultProps.delay); + } + + function handleStyles() + { + popper.style.pointerEvents = instance.props.interactive && instance.state.isVisible ? '' : 'none'; + popper.style.zIndex = "" + instance.props.zIndex; + } + + function invokeHook(hook, args, shouldInvokePropsHook) + { + if (shouldInvokePropsHook === void 0) { + shouldInvokePropsHook = true; + } + + pluginsHooks.forEach(function (pluginHooks) { + if (pluginHooks[hook]) { + pluginHooks[hook].apply(void 0, args); + } + }); + + if (shouldInvokePropsHook) { + var _instance$props; + + (_instance$props = instance.props)[hook].apply(_instance$props, args); + } + } + + function handleAriaContentAttribute() + { + var aria = instance.props.aria; + + if (!aria.content) { + return; + } + + var attr = "aria-" + aria.content; + var id = popper.id; + var nodes = normalizeToArray(instance.props.triggerTarget || reference); + nodes.forEach(function (node) { + var currentValue = node.getAttribute(attr); + + if (instance.state.isVisible) { + node.setAttribute(attr, currentValue ? currentValue + " " + id : id); + } else { + var nextValue = currentValue && currentValue.replace(id, '').trim(); + + if (nextValue) { + node.setAttribute(attr, nextValue); + } else { + node.removeAttribute(attr); + } + } + }); + } + + function handleAriaExpandedAttribute() + { + if (hasAriaExpanded || !instance.props.aria.expanded) { + return; + } + + var nodes = normalizeToArray(instance.props.triggerTarget || reference); + nodes.forEach(function (node) { + if (instance.props.interactive) { + node.setAttribute('aria-expanded', instance.state.isVisible && node === getCurrentTarget() ? 'true' : 'false'); + } else { + node.removeAttribute('aria-expanded'); + } + }); + } + + function cleanupInteractiveMouseListeners() + { + getDocument().removeEventListener('mousemove', debouncedOnMouseMove); + mouseMoveListeners = mouseMoveListeners.filter(function (listener) { + return listener !== debouncedOnMouseMove; + }); + } + + function onDocumentPress(event) + { + // Moved finger to scroll instead of an intentional tap outside + if (currentInput.isTouch) { + if (didTouchMove || event.type === 'mousedown') { + return; + } + } // Clicked on interactive popper + + + if (instance.props.interactive && popper.contains(event.target)) { + return; + } // Clicked on the event listeners target + + + if (getCurrentTarget().contains(event.target)) { + if (currentInput.isTouch) { + return; + } + + if (instance.state.isVisible && instance.props.trigger.indexOf('click') >= 0) { + return; + } + } else { + invokeHook('onClickOutside', [instance, event]); + } + + if (instance.props.hideOnClick === true) { + instance.clearDelayTimeouts(); + instance.hide(); // `mousedown` event is fired right before `focus` if pressing the + // currentTarget. This lets a tippy with `focus` trigger know that it + // should not show + + didHideDueToDocumentMouseDown = true; + setTimeout(function () { + didHideDueToDocumentMouseDown = false; + }); // The listener gets added in `scheduleShow()`, but this may be hiding it + // before it shows, and hide()'s early bail-out behavior can prevent it + // from being cleaned up + + if (!instance.state.isMounted) { + removeDocumentPress(); + } + } + } + + function onTouchMove() + { + didTouchMove = true; + } + + function onTouchStart() + { + didTouchMove = false; + } + + function addDocumentPress() + { + var doc = getDocument(); + doc.addEventListener('mousedown', onDocumentPress, true); + doc.addEventListener('touchend', onDocumentPress, TOUCH_OPTIONS); + doc.addEventListener('touchstart', onTouchStart, TOUCH_OPTIONS); + doc.addEventListener('touchmove', onTouchMove, TOUCH_OPTIONS); + } + + function removeDocumentPress() + { + var doc = getDocument(); + doc.removeEventListener('mousedown', onDocumentPress, true); + doc.removeEventListener('touchend', onDocumentPress, TOUCH_OPTIONS); + doc.removeEventListener('touchstart', onTouchStart, TOUCH_OPTIONS); + doc.removeEventListener('touchmove', onTouchMove, TOUCH_OPTIONS); + } + + function onTransitionedOut(duration, callback) + { + onTransitionEnd(duration, function () { + if (!instance.state.isVisible && popper.parentNode && popper.parentNode.contains(popper)) { + callback(); + } + }); + } + + function onTransitionedIn(duration, callback) + { + onTransitionEnd(duration, callback); + } + + function onTransitionEnd(duration, callback) + { + var box = getDefaultTemplateChildren().box; + + function listener(event) + { + if (event.target === box) { + updateTransitionEndListener(box, 'remove', listener); + callback(); + } + } // Make callback synchronous if duration is 0 + // `transitionend` won't fire otherwise + + + if (duration === 0) { + return callback(); + } + + updateTransitionEndListener(box, 'remove', currentTransitionEndListener); + updateTransitionEndListener(box, 'add', listener); + currentTransitionEndListener = listener; + } + + function on(eventType, handler, options) + { + if (options === void 0) { + options = false; + } + + var nodes = normalizeToArray(instance.props.triggerTarget || reference); + nodes.forEach(function (node) { + node.addEventListener(eventType, handler, options); + listeners.push({ + node: node, + eventType: eventType, + handler: handler, + options: options + }); + }); + } + + function addListeners() + { + if (getIsCustomTouchBehavior()) { + on('touchstart', onTrigger, { + passive: true + }); + on('touchend', onMouseLeave, { + passive: true + }); + } + + splitBySpaces(instance.props.trigger).forEach(function (eventType) { + if (eventType === 'manual') { + return; + } + + on(eventType, onTrigger); + + switch (eventType) { + case 'mouseenter': + on('mouseleave', onMouseLeave); + break; + + case 'focus': + on(isIE ? 'focusout' : 'blur', onBlurOrFocusOut); + break; + + case 'focusin': + on('focusout', onBlurOrFocusOut); + break; + } + }); + } + + function removeListeners() + { + listeners.forEach(function (_ref) { + var node = _ref.node, + eventType = _ref.eventType, + handler = _ref.handler, + options = _ref.options; + node.removeEventListener(eventType, handler, options); + }); + listeners = []; + } + + function onTrigger(event) + { + var _lastTriggerEvent; + + var shouldScheduleClickHide = false; + + if (!instance.state.isEnabled || isEventListenerStopped(event) || didHideDueToDocumentMouseDown) { + return; + } + + var wasFocused = ((_lastTriggerEvent = lastTriggerEvent) == null ? void 0 : _lastTriggerEvent.type) === 'focus'; + lastTriggerEvent = event; + currentTarget = event.currentTarget; + handleAriaExpandedAttribute(); + + if (!instance.state.isVisible && isMouseEvent(event)) { + // If scrolling, `mouseenter` events can be fired if the cursor lands + // over a new target, but `mousemove` events don't get fired. This + // causes interactive tooltips to get stuck open until the cursor is + // moved + mouseMoveListeners.forEach(function (listener) { + return listener(event); + }); + } // Toggle show/hide when clicking click-triggered tooltips + + + if (event.type === 'click' && (instance.props.trigger.indexOf('mouseenter') < 0 || isVisibleFromClick) && instance.props.hideOnClick !== false && instance.state.isVisible) { + shouldScheduleClickHide = true; + } else { + scheduleShow(event); + } + + if (event.type === 'click') { + isVisibleFromClick = !shouldScheduleClickHide; + } + + if (shouldScheduleClickHide && !wasFocused) { + scheduleHide(event); + } + } + + function onMouseMove(event) + { + var target = event.target; + var isCursorOverReferenceOrPopper = getCurrentTarget().contains(target) || popper.contains(target); + + if (event.type === 'mousemove' && isCursorOverReferenceOrPopper) { + return; + } + + var popperTreeData = getNestedPopperTree().concat(popper).map(function (popper) { + var _instance$popperInsta; + + var instance = popper._tippy; + var state = (_instance$popperInsta = instance.popperInstance) == null ? void 0 : _instance$popperInsta.state; + + if (state) { + return { + popperRect: popper.getBoundingClientRect(), + popperState: state, + props: props + }; + } + + return null; + }).filter(Boolean); + + if (isCursorOutsideInteractiveBorder(popperTreeData, event)) { + cleanupInteractiveMouseListeners(); + scheduleHide(event); + } + } + + function onMouseLeave(event) + { + var shouldBail = isEventListenerStopped(event) || instance.props.trigger.indexOf('click') >= 0 && isVisibleFromClick; + + if (shouldBail) { + return; + } + + if (instance.props.interactive) { + instance.hideWithInteractivity(event); + return; + } + + scheduleHide(event); + } + + function onBlurOrFocusOut(event) + { + if (instance.props.trigger.indexOf('focusin') < 0 && event.target !== getCurrentTarget()) { + return; + } // If focus was moved to within the popper + + + if (instance.props.interactive && event.relatedTarget && popper.contains(event.relatedTarget)) { + return; + } + + scheduleHide(event); + } + + function isEventListenerStopped(event) + { + return currentInput.isTouch ? getIsCustomTouchBehavior() !== event.type.indexOf('touch') >= 0 : false; + } + + function createPopperInstance() + { + destroyPopperInstance(); + var _instance$props2 = instance.props, + popperOptions = _instance$props2.popperOptions, + placement = _instance$props2.placement, + offset = _instance$props2.offset, + getReferenceClientRect = _instance$props2.getReferenceClientRect, + moveTransition = _instance$props2.moveTransition; + var arrow = getIsDefaultRenderFn() ? getChildren(popper).arrow : null; + var computedReference = getReferenceClientRect ? { + getBoundingClientRect: getReferenceClientRect, + contextElement: getReferenceClientRect.contextElement || getCurrentTarget() + } : reference; + var tippyModifier = { + name: '$$tippy', + enabled: true, + phase: 'beforeWrite', + requires: ['computeStyles'], + fn: function fn(_ref2) + { + var state = _ref2.state; + + if (getIsDefaultRenderFn()) { + var _getDefaultTemplateCh = getDefaultTemplateChildren(), + box = _getDefaultTemplateCh.box; + + ['placement', 'reference-hidden', 'escaped'].forEach(function (attr) { + if (attr === 'placement') { + box.setAttribute('data-placement', state.placement); + } else { + if (state.attributes.popper["data-popper-" + attr]) { + box.setAttribute("data-" + attr, ''); + } else { + box.removeAttribute("data-" + attr); + } + } + }); + state.attributes.popper = {}; + } + } + }; + var modifiers = [{ + name: 'offset', + options: { + offset: offset + } + }, { + name: 'preventOverflow', + options: { + padding: { + top: 2, + bottom: 2, + left: 5, + right: 5 + } + } + }, { + name: 'flip', + options: { + padding: 5 + } + }, { + name: 'computeStyles', + options: { + adaptive: !moveTransition + } + }, tippyModifier]; + + if (getIsDefaultRenderFn() && arrow) { + modifiers.push({ + name: 'arrow', + options: { + element: arrow, + padding: 3 + } + }); + } + + modifiers.push.apply(modifiers, (popperOptions == null ? void 0 : popperOptions.modifiers) || []); + instance.popperInstance = core.createPopper(computedReference, popper, Object.assign({}, popperOptions, { + placement: placement, + onFirstUpdate: onFirstUpdate, + modifiers: modifiers + })); + } + + function destroyPopperInstance() + { + if (instance.popperInstance) { + instance.popperInstance.destroy(); + instance.popperInstance = null; + } + } + + function mount() + { + var appendTo = instance.props.appendTo; + var parentNode; // By default, we'll append the popper to the triggerTargets's parentNode so + // it's directly after the reference element so the elements inside the + // tippy can be tabbed to + // If there are clipping issues, the user can specify a different appendTo + // and ensure focus management is handled correctly manually + + var node = getCurrentTarget(); + + if (instance.props.interactive && appendTo === defaultProps.appendTo || appendTo === 'parent') { + parentNode = node.parentNode; + } else { + parentNode = invokeWithArgsOrReturn(appendTo, [node]); + } // The popper element needs to exist on the DOM before its position can be + // updated as Popper needs to read its dimensions + + + if (!parentNode.contains(popper)) { + parentNode.appendChild(popper); + } + + createPopperInstance(); + /* istanbul ignore else */ + + { + // Accessibility check + warnWhen(instance.props.interactive && appendTo === defaultProps.appendTo && node.nextElementSibling !== popper, ['Interactive tippy element may not be accessible via keyboard', 'navigation because it is not directly after the reference element', 'in the DOM source order.', '\n\n', 'Using a wrapper
        or tag around the reference element', 'solves this by creating a new parentNode context.', '\n\n', 'Specifying `appendTo: document.body` silences this warning, but it', 'assumes you are using a focus management solution to handle', 'keyboard navigation.', '\n\n', 'See: https://atomiks.github.io/tippyjs/v6/accessibility/#interactivity'].join(' ')); + } + } + + function getNestedPopperTree() + { + return arrayFrom(popper.querySelectorAll('[data-tippy-root]')); + } + + function scheduleShow(event) + { + instance.clearDelayTimeouts(); + + if (event) { + invokeHook('onTrigger', [instance, event]); + } + + addDocumentPress(); + var delay = getDelay(true); + + var _getNormalizedTouchSe = getNormalizedTouchSettings(), + touchValue = _getNormalizedTouchSe[0], + touchDelay = _getNormalizedTouchSe[1]; + + if (currentInput.isTouch && touchValue === 'hold' && touchDelay) { + delay = touchDelay; + } + + if (delay) { + showTimeout = setTimeout(function () { + instance.show(); + }, delay); + } else { + instance.show(); + } + } + + function scheduleHide(event) + { + instance.clearDelayTimeouts(); + invokeHook('onUntrigger', [instance, event]); + + if (!instance.state.isVisible) { + removeDocumentPress(); + return; + } // For interactive tippies, scheduleHide is added to a document.body handler + // from onMouseLeave so must intercept scheduled hides from mousemove/leave + // events when trigger contains mouseenter and click, and the tip is + // currently shown as a result of a click. + + + if (instance.props.trigger.indexOf('mouseenter') >= 0 && instance.props.trigger.indexOf('click') >= 0 && ['mouseleave', 'mousemove'].indexOf(event.type) >= 0 && isVisibleFromClick) { + return; + } + + var delay = getDelay(false); + + if (delay) { + hideTimeout = setTimeout(function () { + if (instance.state.isVisible) { + instance.hide(); + } + }, delay); + } else { + // Fixes a `transitionend` problem when it fires 1 frame too + // late sometimes, we don't want hide() to be called. + scheduleHideAnimationFrame = requestAnimationFrame(function () { + instance.hide(); + }); + } + } // =========================================================================== + // 🔑 Public methods + // =========================================================================== + + + function enable() + { + instance.state.isEnabled = true; + } + + function disable() + { + // Disabling the instance should also hide it + // https://github.com/atomiks/tippy.js-react/issues/106 + instance.hide(); + instance.state.isEnabled = false; + } + + function clearDelayTimeouts() + { + clearTimeout(showTimeout); + clearTimeout(hideTimeout); + cancelAnimationFrame(scheduleHideAnimationFrame); + } + + function setProps(partialProps) + { + /* istanbul ignore else */ + { + warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('setProps')); + } + + if (instance.state.isDestroyed) { + return; + } + + invokeHook('onBeforeUpdate', [instance, partialProps]); + removeListeners(); + var prevProps = instance.props; + var nextProps = evaluateProps(reference, Object.assign({}, instance.props, {}, partialProps, { + ignoreAttributes: true + })); + instance.props = nextProps; + addListeners(); + + if (prevProps.interactiveDebounce !== nextProps.interactiveDebounce) { + cleanupInteractiveMouseListeners(); + debouncedOnMouseMove = debounce(onMouseMove, nextProps.interactiveDebounce); + } // Ensure stale aria-expanded attributes are removed + + + if (prevProps.triggerTarget && !nextProps.triggerTarget) { + normalizeToArray(prevProps.triggerTarget).forEach(function (node) { + node.removeAttribute('aria-expanded'); + }); + } else if (nextProps.triggerTarget) { + reference.removeAttribute('aria-expanded'); + } + + handleAriaExpandedAttribute(); + handleStyles(); + + if (onUpdate) { + onUpdate(prevProps, nextProps); + } + + if (instance.popperInstance) { + createPopperInstance(); // Fixes an issue with nested tippies if they are all getting re-rendered, + // and the nested ones get re-rendered first. + // https://github.com/atomiks/tippyjs-react/issues/177 + // TODO: find a cleaner / more efficient solution(!) + + getNestedPopperTree().forEach(function (nestedPopper) { + // React (and other UI libs likely) requires a rAF wrapper as it flushes + // its work in one + requestAnimationFrame(nestedPopper._tippy.popperInstance.forceUpdate); + }); + } + + invokeHook('onAfterUpdate', [instance, partialProps]); + } + + function setContent(content) + { + instance.setProps({ + content: content + }); + } + + function show() + { + /* istanbul ignore else */ + { + warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('show')); + } // Early bail-out + + + var isAlreadyVisible = instance.state.isVisible; + var isDestroyed = instance.state.isDestroyed; + var isDisabled = !instance.state.isEnabled; + var isTouchAndTouchDisabled = currentInput.isTouch && !instance.props.touch; + var duration = getValueAtIndexOrReturn(instance.props.duration, 0, defaultProps.duration); + + if (isAlreadyVisible || isDestroyed || isDisabled || isTouchAndTouchDisabled) { + return; + } // Normalize `disabled` behavior across browsers. + // Firefox allows events on disabled elements, but Chrome doesn't. + // Using a wrapper element (i.e. ) is recommended. + + + if (getCurrentTarget().hasAttribute('disabled')) { + return; + } + + invokeHook('onShow', [instance], false); + + if (instance.props.onShow(instance) === false) { + return; + } + + instance.state.isVisible = true; + + if (getIsDefaultRenderFn()) { + popper.style.visibility = 'visible'; + } + + handleStyles(); + addDocumentPress(); + + if (!instance.state.isMounted) { + popper.style.transition = 'none'; + } // If flipping to the opposite side after hiding at least once, the + // animation will use the wrong placement without resetting the duration + + + if (getIsDefaultRenderFn()) { + var _getDefaultTemplateCh2 = getDefaultTemplateChildren(), + box = _getDefaultTemplateCh2.box, + content = _getDefaultTemplateCh2.content; + + setTransitionDuration([box, content], 0); + } + + onFirstUpdate = function onFirstUpdate() + { + if (!instance.state.isVisible || ignoreOnFirstUpdate) { + return; + } + + ignoreOnFirstUpdate = true; // reflow + + void popper.offsetHeight; + popper.style.transition = instance.props.moveTransition; + + if (getIsDefaultRenderFn() && instance.props.animation) { + var _getDefaultTemplateCh3 = getDefaultTemplateChildren(), + _box = _getDefaultTemplateCh3.box, + _content = _getDefaultTemplateCh3.content; + + setTransitionDuration([_box, _content], duration); + setVisibilityState([_box, _content], 'visible'); + } + + handleAriaContentAttribute(); + handleAriaExpandedAttribute(); + pushIfUnique(mountedInstances, instance); + instance.state.isMounted = true; + invokeHook('onMount', [instance]); + + if (instance.props.animation && getIsDefaultRenderFn()) { + onTransitionedIn(duration, function () { + instance.state.isShown = true; + invokeHook('onShown', [instance]); + }); + } + }; + + mount(); + } + + function hide() + { + /* istanbul ignore else */ + { + warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('hide')); + } // Early bail-out + + + var isAlreadyHidden = !instance.state.isVisible; + var isDestroyed = instance.state.isDestroyed; + var isDisabled = !instance.state.isEnabled; + var duration = getValueAtIndexOrReturn(instance.props.duration, 1, defaultProps.duration); + + if (isAlreadyHidden || isDestroyed || isDisabled) { + return; + } + + invokeHook('onHide', [instance], false); + + if (instance.props.onHide(instance) === false) { + return; + } + + instance.state.isVisible = false; + instance.state.isShown = false; + ignoreOnFirstUpdate = false; + isVisibleFromClick = false; + + if (getIsDefaultRenderFn()) { + popper.style.visibility = 'hidden'; + } + + cleanupInteractiveMouseListeners(); + removeDocumentPress(); + handleStyles(); + + if (getIsDefaultRenderFn()) { + var _getDefaultTemplateCh4 = getDefaultTemplateChildren(), + box = _getDefaultTemplateCh4.box, + content = _getDefaultTemplateCh4.content; + + if (instance.props.animation) { + setTransitionDuration([box, content], duration); + setVisibilityState([box, content], 'hidden'); + } + } + + handleAriaContentAttribute(); + handleAriaExpandedAttribute(); + + if (instance.props.animation) { + if (getIsDefaultRenderFn()) { + onTransitionedOut(duration, instance.unmount); + } + } else { + instance.unmount(); + } + } + + function hideWithInteractivity(event) + { + /* istanbul ignore else */ + { + warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('hideWithInteractivity')); + } + + getDocument().addEventListener('mousemove', debouncedOnMouseMove); + pushIfUnique(mouseMoveListeners, debouncedOnMouseMove); + debouncedOnMouseMove(event); + } + + function unmount() + { + /* istanbul ignore else */ + { + warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('unmount')); + } + + if (instance.state.isVisible) { + instance.hide(); + } + + if (!instance.state.isMounted) { + return; + } + + destroyPopperInstance(); // If a popper is not interactive, it will be appended outside the popper + // tree by default. This seems mainly for interactive tippies, but we should + // find a workaround if possible + + getNestedPopperTree().forEach(function (nestedPopper) { + nestedPopper._tippy.unmount(); + }); + + if (popper.parentNode) { + popper.parentNode.removeChild(popper); + } + + mountedInstances = mountedInstances.filter(function (i) { + return i !== instance; + }); + instance.state.isMounted = false; + invokeHook('onHidden', [instance]); + } + + function destroy() + { + /* istanbul ignore else */ + { + warnWhen(instance.state.isDestroyed, createMemoryLeakWarning('destroy')); + } + + if (instance.state.isDestroyed) { + return; + } + + instance.clearDelayTimeouts(); + instance.unmount(); + removeListeners(); + delete reference._tippy; + instance.state.isDestroyed = true; + invokeHook('onDestroy', [instance]); + } + } + + function tippy(targets, optionalProps) + { + if (optionalProps === void 0) { + optionalProps = {}; + } + + var plugins = defaultProps.plugins.concat(optionalProps.plugins || []); + /* istanbul ignore else */ + + { + validateTargets(targets); + validateProps(optionalProps, plugins); + } + + bindGlobalEventListeners(); + var passedProps = Object.assign({}, optionalProps, { + plugins: plugins + }); + var elements = getArrayOfElements(targets); + /* istanbul ignore else */ + + { + var isSingleContentElement = isElement(passedProps.content); + var isMoreThanOneReferenceElement = elements.length > 1; + warnWhen(isSingleContentElement && isMoreThanOneReferenceElement, ['tippy() was passed an Element as the `content` prop, but more than', 'one tippy instance was created by this invocation. This means the', 'content element will only be appended to the last tippy instance.', '\n\n', 'Instead, pass the .innerHTML of the element, or use a function that', 'returns a cloned version of the element instead.', '\n\n', '1) content: element.innerHTML\n', '2) content: () => element.cloneNode(true)'].join(' ')); + } + + var instances = elements.reduce(function (acc, reference) { + var instance = reference && createTippy(reference, passedProps); + + if (instance) { + acc.push(instance); + } + + return acc; + }, []); + return isElement(targets) ? instances[0] : instances; + } + + tippy.defaultProps = defaultProps; + tippy.setDefaultProps = setDefaultProps; + tippy.currentInput = currentInput; + var hideAll = function hideAll(_temp) + { + var _ref = _temp === void 0 ? {} : _temp, + excludedReferenceOrInstance = _ref.exclude, + duration = _ref.duration; + + mountedInstances.forEach(function (instance) { + var isExcluded = false; + + if (excludedReferenceOrInstance) { + isExcluded = isReferenceElement(excludedReferenceOrInstance) ? instance.reference === excludedReferenceOrInstance : instance.popper === excludedReferenceOrInstance.popper; + } + + if (!isExcluded) { + var originalDuration = instance.props.duration; + instance.setProps({ + duration: duration + }); + instance.hide(); + + if (!instance.state.isDestroyed) { + instance.setProps({ + duration: originalDuration + }); + } + } + }); + }; + + var createSingleton = function createSingleton(tippyInstances, optionalProps) + { + if (optionalProps === void 0) { + optionalProps = {}; + } + + /* istanbul ignore else */ + { + errorWhen(!Array.isArray(tippyInstances), ['The first argument passed to createSingleton() must be an array of', 'tippy instances. The passed value was', String(tippyInstances)].join(' ')); + } + + var individualInstances = tippyInstances; + var references = []; + var currentTarget; + var overrides = optionalProps.overrides; + var interceptSetPropsCleanups = []; + + function setReferences() + { + references = individualInstances.map(function (instance) { + return instance.reference; + }); + } + + function enableInstances(isEnabled) + { + individualInstances.forEach(function (instance) { + if (isEnabled) { + instance.enable(); + } else { + instance.disable(); + } + }); + } + + function interceptSetProps(singleton) + { + return individualInstances.map(function (instance) { + var originalSetProps = instance.setProps; + + instance.setProps = function (props) { + originalSetProps(props); + + if (instance.reference === currentTarget) { + singleton.setProps(props); + } + }; + + return function () { + instance.setProps = originalSetProps; + }; + }); + } + + enableInstances(false); + setReferences(); + var plugin = { + fn: function fn() + { + return { + onDestroy: function onDestroy() + { + enableInstances(true); + }, + onTrigger: function onTrigger(instance, event) + { + var target = event.currentTarget; + var index = references.indexOf(target); // bail-out + + if (target === currentTarget) { + return; + } + + currentTarget = target; + var overrideProps = (overrides || []).concat('content').reduce(function (acc, prop) { + acc[prop] = individualInstances[index].props[prop]; + return acc; + }, {}); + instance.setProps(Object.assign({}, overrideProps, { + getReferenceClientRect: typeof overrideProps.getReferenceClientRect === 'function' ? overrideProps.getReferenceClientRect : function () { + return target.getBoundingClientRect(); + } + })); + } + }; + } + }; + var singleton = tippy(div(), Object.assign({}, removeProperties(optionalProps, ['overrides']), { + plugins: [plugin].concat(optionalProps.plugins || []), + triggerTarget: references + })); + var originalSetProps = singleton.setProps; + + singleton.setProps = function (props) { + overrides = props.overrides || overrides; + originalSetProps(props); + }; + + singleton.setInstances = function (nextInstances) { + enableInstances(true); + interceptSetPropsCleanups.forEach(function (fn) { + return fn(); + }); + individualInstances = nextInstances; + enableInstances(false); + setReferences(); + interceptSetProps(singleton); + singleton.setProps({ + triggerTarget: references + }); + }; + + interceptSetPropsCleanups = interceptSetProps(singleton); + return singleton; + }; + + var BUBBLING_EVENTS_MAP = { + mouseover: 'mouseenter', + focusin: 'focus', + click: 'click' + }; + /** + * Creates a delegate instance that controls the creation of tippy instances + * for child elements (`target` CSS selector). + */ + + function delegate(targets, props) + { + /* istanbul ignore else */ + { + errorWhen(!(props && props.target), ['You must specity a `target` prop indicating a CSS selector string matching', 'the target elements that should receive a tippy.'].join(' ')); + } + + var listeners = []; + var childTippyInstances = []; + var disabled = false; + var target = props.target; + var nativeProps = removeProperties(props, ['target']); + var parentProps = Object.assign({}, nativeProps, { + trigger: 'manual', + touch: false + }); + var childProps = Object.assign({}, nativeProps, { + showOnCreate: true + }); + var returnValue = tippy(targets, parentProps); + var normalizedReturnValue = normalizeToArray(returnValue); + + function onTrigger(event) + { + if (!event.target || disabled) { + return; + } + + var targetNode = event.target.closest(target); + + if (!targetNode) { + return; + } // Get relevant trigger with fallbacks: + // 1. Check `data-tippy-trigger` attribute on target node + // 2. Fallback to `trigger` passed to `delegate()` + // 3. Fallback to `defaultProps.trigger` + + + var trigger = targetNode.getAttribute('data-tippy-trigger') || props.trigger || defaultProps.trigger; // @ts-ignore + + if (targetNode._tippy) { + return; + } + + if (event.type === 'touchstart' && typeof childProps.touch === 'boolean') { + return; + } + + if (event.type !== 'touchstart' && trigger.indexOf(BUBBLING_EVENTS_MAP[event.type]) < 0) { + return; + } + + var instance = tippy(targetNode, childProps); + + if (instance) { + childTippyInstances = childTippyInstances.concat(instance); + } + } + + function on(node, eventType, handler, options) + { + if (options === void 0) { + options = false; + } + + node.addEventListener(eventType, handler, options); + listeners.push({ + node: node, + eventType: eventType, + handler: handler, + options: options + }); + } + + function addEventListeners(instance) + { + var reference = instance.reference; + on(reference, 'touchstart', onTrigger); + on(reference, 'mouseover', onTrigger); + on(reference, 'focusin', onTrigger); + on(reference, 'click', onTrigger); + } + + function removeEventListeners() + { + listeners.forEach(function (_ref) { + var node = _ref.node, + eventType = _ref.eventType, + handler = _ref.handler, + options = _ref.options; + node.removeEventListener(eventType, handler, options); + }); + listeners = []; + } + + function applyMutations(instance) + { + var originalDestroy = instance.destroy; + var originalEnable = instance.enable; + var originalDisable = instance.disable; + + instance.destroy = function (shouldDestroyChildInstances) { + if (shouldDestroyChildInstances === void 0) { + shouldDestroyChildInstances = true; + } + + if (shouldDestroyChildInstances) { + childTippyInstances.forEach(function (instance) { + instance.destroy(); + }); + } + + childTippyInstances = []; + removeEventListeners(); + originalDestroy(); + }; + + instance.enable = function () { + originalEnable(); + childTippyInstances.forEach(function (instance) { + return instance.enable(); + }); + disabled = false; + }; + + instance.disable = function () { + originalDisable(); + childTippyInstances.forEach(function (instance) { + return instance.disable(); + }); + disabled = true; + }; + + addEventListeners(instance); + } + + normalizedReturnValue.forEach(applyMutations); + return returnValue; + } + + var animateFill = { + name: 'animateFill', + defaultValue: false, + fn: function fn(instance) + { + var _instance$props$rende; + + // @ts-ignore + if (!((_instance$props$rende = instance.props.render) == null ? void 0 : _instance$props$rende.$$tippy)) { + { + errorWhen(instance.props.animateFill, 'The `animateFill` plugin requires the default render function.'); + } + + return {}; + } + + var _getChildren = getChildren(instance.popper), + box = _getChildren.box, + content = _getChildren.content; + + var backdrop = instance.props.animateFill ? createBackdropElement() : null; + return { + onCreate: function onCreate() + { + if (backdrop) { + box.insertBefore(backdrop, box.firstElementChild); + box.setAttribute('data-animatefill', ''); + box.style.overflow = 'hidden'; + instance.setProps({ + arrow: false, + animation: 'shift-away' + }); + } + }, + onMount: function onMount() + { + if (backdrop) { + var transitionDuration = box.style.transitionDuration; + var duration = Number(transitionDuration.replace('ms', '')); // The content should fade in after the backdrop has mostly filled the + // tooltip element. `clip-path` is the other alternative but is not + // well-supported and is buggy on some devices. + + content.style.transitionDelay = Math.round(duration / 10) + "ms"; + backdrop.style.transitionDuration = transitionDuration; + setVisibilityState([backdrop], 'visible'); + } + }, + onShow: function onShow() + { + if (backdrop) { + backdrop.style.transitionDuration = '0ms'; + } + }, + onHide: function onHide() + { + if (backdrop) { + setVisibilityState([backdrop], 'hidden'); + } + } + }; + } + }; + + function createBackdropElement() + { + var backdrop = div(); + backdrop.className = BACKDROP_CLASS; + setVisibilityState([backdrop], 'hidden'); + return backdrop; + } + + var mouseCoords = { + clientX: 0, + clientY: 0 + }; + var activeInstances = []; + + function storeMouseCoords(_ref) + { + var clientX = _ref.clientX, + clientY = _ref.clientY; + mouseCoords = { + clientX: clientX, + clientY: clientY + }; + } + + function addMouseCoordsListener(doc) + { + doc.addEventListener('mousemove', storeMouseCoords); + } + + function removeMouseCoordsListener(doc) + { + doc.removeEventListener('mousemove', storeMouseCoords); + } + + var followCursor = { + name: 'followCursor', + defaultValue: false, + fn: function fn(instance) + { + var reference = instance.reference; + var doc = getOwnerDocument(instance.props.triggerTarget || reference); + var isInternalUpdate = false; + var wasFocusEvent = false; + var isUnmounted = true; + var prevProps = instance.props; + + function getIsInitialBehavior() + { + return instance.props.followCursor === 'initial' && instance.state.isVisible; + } + + function addListener() + { + doc.addEventListener('mousemove', onMouseMove); + } + + function removeListener() + { + doc.removeEventListener('mousemove', onMouseMove); + } + + function unsetGetReferenceClientRect() + { + isInternalUpdate = true; + instance.setProps({ + getReferenceClientRect: null + }); + isInternalUpdate = false; + } + + function onMouseMove(event) + { + // If the instance is interactive, avoid updating the position unless it's + // over the reference element + var isCursorOverReference = event.target ? reference.contains(event.target) : true; + var followCursor = instance.props.followCursor; + var clientX = event.clientX, + clientY = event.clientY; + var rect = reference.getBoundingClientRect(); + var relativeX = clientX - rect.left; + var relativeY = clientY - rect.top; + + if (isCursorOverReference || !instance.props.interactive) { + instance.setProps({ + getReferenceClientRect: function getReferenceClientRect() + { + var rect = reference.getBoundingClientRect(); + var x = clientX; + var y = clientY; + + if (followCursor === 'initial') { + x = rect.left + relativeX; + y = rect.top + relativeY; + } + + var top = followCursor === 'horizontal' ? rect.top : y; + var right = followCursor === 'vertical' ? rect.right : x; + var bottom = followCursor === 'horizontal' ? rect.bottom : y; + var left = followCursor === 'vertical' ? rect.left : x; + return { + width: right - left, + height: bottom - top, + top: top, + right: right, + bottom: bottom, + left: left + }; + } + }); + } + } + + function create() + { + if (instance.props.followCursor) { + activeInstances.push({ + instance: instance, + doc: doc + }); + addMouseCoordsListener(doc); + } + } + + function destroy() + { + activeInstances = activeInstances.filter(function (data) { + return data.instance !== instance; + }); + + if (activeInstances.filter(function (data) { + return data.doc === doc; + }).length === 0) { + removeMouseCoordsListener(doc); + } + } + + return { + onCreate: create, + onDestroy: destroy, + onBeforeUpdate: function onBeforeUpdate() + { + prevProps = instance.props; + }, + onAfterUpdate: function onAfterUpdate(_, _ref2) + { + var followCursor = _ref2.followCursor; + + if (isInternalUpdate) { + return; + } + + if (followCursor !== undefined && prevProps.followCursor !== followCursor) { + destroy(); + + if (followCursor) { + create(); + + if (instance.state.isMounted && !wasFocusEvent && !getIsInitialBehavior()) { + addListener(); + } + } else { + removeListener(); + unsetGetReferenceClientRect(); + } + } + }, + onMount: function onMount() + { + if (instance.props.followCursor && !wasFocusEvent) { + if (isUnmounted) { + onMouseMove(mouseCoords); + isUnmounted = false; + } + + if (!getIsInitialBehavior()) { + addListener(); + } + } + }, + onTrigger: function onTrigger(_, event) + { + if (isMouseEvent(event)) { + mouseCoords = { + clientX: event.clientX, + clientY: event.clientY + }; + } + + wasFocusEvent = event.type === 'focus'; + }, + onHidden: function onHidden() + { + if (instance.props.followCursor) { + unsetGetReferenceClientRect(); + removeListener(); + isUnmounted = true; + } + } + }; + } + }; + + function getProps(props, modifier) + { + var _props$popperOptions; + + return { + popperOptions: Object.assign({}, props.popperOptions, { + modifiers: [].concat((((_props$popperOptions = props.popperOptions) == null ? void 0 : _props$popperOptions.modifiers) || []).filter(function (_ref) { + var name = _ref.name; + return name !== modifier.name; + }), [modifier]) + }) + }; + } + + var inlinePositioning = { + name: 'inlinePositioning', + defaultValue: false, + fn: function fn(instance) + { + var reference = instance.reference; + + function isEnabled() + { + return !!instance.props.inlinePositioning; + } + + var placement; + var cursorRectIndex = -1; + var isInternalUpdate = false; + var modifier = { + name: 'tippyInlinePositioning', + enabled: true, + phase: 'afterWrite', + fn: function fn(_ref2) + { + var state = _ref2.state; + + if (isEnabled()) { + if (placement !== state.placement) { + instance.setProps({ + getReferenceClientRect: function getReferenceClientRect() + { + return _getReferenceClientRect(state.placement); + } + }); + } + + placement = state.placement; + } + } + }; + + function _getReferenceClientRect(placement) + { + return getInlineBoundingClientRect(getBasePlacement(placement), reference.getBoundingClientRect(), arrayFrom(reference.getClientRects()), cursorRectIndex); + } + + function setInternalProps(partialProps) + { + isInternalUpdate = true; + instance.setProps(partialProps); + isInternalUpdate = false; + } + + function addModifier() + { + if (!isInternalUpdate) { + setInternalProps(getProps(instance.props, modifier)); + } + } + + return { + onCreate: addModifier, + onAfterUpdate: addModifier, + onTrigger: function onTrigger(_, event) + { + if (isMouseEvent(event)) { + var rects = arrayFrom(instance.reference.getClientRects()); + var cursorRect = rects.find(function (rect) { + return rect.left - 2 <= event.clientX && rect.right + 2 >= event.clientX && rect.top - 2 <= event.clientY && rect.bottom + 2 >= event.clientY; + }); + cursorRectIndex = rects.indexOf(cursorRect); + } + }, + onUntrigger: function onUntrigger() + { + cursorRectIndex = -1; + } + }; + } + }; + function getInlineBoundingClientRect(currentBasePlacement, boundingRect, clientRects, cursorRectIndex) + { + // Not an inline element, or placement is not yet known + if (clientRects.length < 2 || currentBasePlacement === null) { + return boundingRect; + } // There are two rects and they are disjoined + + + if (clientRects.length === 2 && cursorRectIndex >= 0 && clientRects[0].left > clientRects[1].right) { + return clientRects[cursorRectIndex] || boundingRect; + } + + switch (currentBasePlacement) { + case 'top': + case 'bottom': + { + var firstRect = clientRects[0]; + var lastRect = clientRects[clientRects.length - 1]; + var isTop = currentBasePlacement === 'top'; + var top = firstRect.top; + var bottom = lastRect.bottom; + var left = isTop ? firstRect.left : lastRect.left; + var right = isTop ? firstRect.right : lastRect.right; + var width = right - left; + var height = bottom - top; + return { + top: top, + bottom: bottom, + left: left, + right: right, + width: width, + height: height + }; + } + + case 'left': + case 'right': + { + var minLeft = Math.min.apply(Math, clientRects.map(function (rects) { + return rects.left; + })); + var maxRight = Math.max.apply(Math, clientRects.map(function (rects) { + return rects.right; + })); + var measureRects = clientRects.filter(function (rect) { + return currentBasePlacement === 'left' ? rect.left === minLeft : rect.right === maxRight; + }); + var _top = measureRects[0].top; + var _bottom = measureRects[measureRects.length - 1].bottom; + var _left = minLeft; + var _right = maxRight; + + var _width = _right - _left; + + var _height = _bottom - _top; + + return { + top: _top, + bottom: _bottom, + left: _left, + right: _right, + width: _width, + height: _height + }; + } + + default: + { + return boundingRect; + } + } + } + + var sticky = { + name: 'sticky', + defaultValue: false, + fn: function fn(instance) + { + var reference = instance.reference, + popper = instance.popper; + + function getReference() + { + return instance.popperInstance ? instance.popperInstance.state.elements.reference : reference; + } + + function shouldCheck(value) + { + return instance.props.sticky === true || instance.props.sticky === value; + } + + var prevRefRect = null; + var prevPopRect = null; + + function updatePosition() + { + var currentRefRect = shouldCheck('reference') ? getReference().getBoundingClientRect() : null; + var currentPopRect = shouldCheck('popper') ? popper.getBoundingClientRect() : null; + + if (currentRefRect && areRectsDifferent(prevRefRect, currentRefRect) || currentPopRect && areRectsDifferent(prevPopRect, currentPopRect)) { + if (instance.popperInstance) { + instance.popperInstance.update(); + } + } + + prevRefRect = currentRefRect; + prevPopRect = currentPopRect; + + if (instance.state.isMounted) { + requestAnimationFrame(updatePosition); + } + } + + return { + onMount: function onMount() + { + if (instance.props.sticky) { + updatePosition(); + } + } + }; + } + }; + + function areRectsDifferent(rectA, rectB) + { + if (rectA && rectB) { + return rectA.top !== rectB.top || rectA.right !== rectB.right || rectA.bottom !== rectB.bottom || rectA.left !== rectB.left; + } + + return true; + } + + if (isBrowser) { + injectCSS(css); + } + + tippy.setDefaultProps({ + plugins: [animateFill, followCursor, inlinePositioning, sticky], + render: render + }); + tippy.createSingleton = createSingleton; + tippy.delegate = delegate; + tippy.hideAll = hideAll; + tippy.roundArrow = ROUND_ARROW; + + return tippy; + +}))); diff --git a/html/wp-content/plugins/duplicator/assets/js/tippy/tippy-bundle.umd.min.js b/html/wp-content/plugins/duplicator/assets/js/tippy/tippy-bundle.umd.min.js new file mode 100644 index 0000000..09bc11d --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/js/tippy/tippy-bundle.umd.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t=t||self).tippy=e(t.Popper)}(this,(function(t){"use strict";var e="undefined"!=typeof window&&"undefined"!=typeof document,n=e?navigator.userAgent:"",r=/MSIE |Trident\//.test(n),i={passive:!0,capture:!0};function o(t,e,n){if(Array.isArray(t)){var r=t[e];return null==r?Array.isArray(n)?n[e]:n:r}return t}function a(t,e){var n={}.toString.call(t);return 0===n.indexOf("[object")&&n.indexOf(e+"]")>-1}function s(t,e){return"function"==typeof t?t.apply(void 0,e):t}function u(t,e){return 0===e?t:function(r){clearTimeout(n),n=setTimeout((function(){t(r)}),e)};var n}function c(t,e){var n=Object.assign({},t);return e.forEach((function(t){delete n[t]})),n}function p(t){return[].concat(t)}function f(t,e){-1===t.indexOf(e)&&t.push(e)}function l(t){return t.split("-")[0]}function d(t){return[].slice.call(t)}function v(){return document.createElement("div")}function m(t){return["Element","Fragment"].some((function(e){return a(t,e)}))}function g(t){return a(t,"MouseEvent")}function h(t){return!(!t||!t._tippy||t._tippy.reference!==t)}function b(t){return m(t)?[t]:function(t){return a(t,"NodeList")}(t)?d(t):Array.isArray(t)?t:d(document.querySelectorAll(t))}function y(t,e){t.forEach((function(t){t&&(t.style.transitionDuration=e+"ms")}))}function x(t,e){t.forEach((function(t){t&&t.setAttribute("data-state",e)}))}function w(t){var e=p(t)[0];return e&&e.ownerDocument||document}function E(t,e,n){var r=e+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(e){t[r](e,n)}))}var T={isTouch:!1},C=0;function A(){T.isTouch||(T.isTouch=!0,window.performance&&document.addEventListener("mousemove",O))}function O(){var t=performance.now();t-C<20&&(T.isTouch=!1,document.removeEventListener("mousemove",O)),C=t}function L(){var t=document.activeElement;if(h(t)){var e=t._tippy;t.blur&&!e.state.isVisible&&t.blur()}}var D=Object.assign({appendTo:function(){return document.body},aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(D);function R(t){var e=(t.plugins||[]).reduce((function(e,n){var r=n.name,i=n.defaultValue;return r&&(e[r]=void 0!==t[r]?t[r]:i),e}),{});return Object.assign({},t,{},e)}function M(t,e){var n=Object.assign({},e,{content:s(e.content,[t])},e.ignoreAttributes?{}:function(t,e){return(e?Object.keys(R(Object.assign({},D,{plugins:e}))):k).reduce((function(e,n){var r=(t.getAttribute("data-tippy-"+n)||"").trim();if(!r)return e;if("content"===n)e[n]=r;else try{e[n]=JSON.parse(r)}catch(t){e[n]=r}return e}),{})}(t,e.plugins));return n.aria=Object.assign({},D.aria,{},n.aria),n.aria={expanded:"auto"===n.aria.expanded?e.interactive:n.aria.expanded,content:"auto"===n.aria.content?e.interactive?null:"describedby":n.aria.content},n}function P(t,e){t.innerHTML=e}function V(t){var e=v();return!0===t?e.className="tippy-arrow":(e.className="tippy-svg-arrow",m(t)?e.appendChild(t):P(e,t)),e}function j(t,e){m(e.content)?(P(t,""),t.appendChild(e.content)):"function"!=typeof e.content&&(e.allowHTML?P(t,e.content):t.textContent=e.content)}function I(t){var e=t.firstElementChild,n=d(e.children);return{box:e,content:n.find((function(t){return t.classList.contains("tippy-content")})),arrow:n.find((function(t){return t.classList.contains("tippy-arrow")||t.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(t){return t.classList.contains("tippy-backdrop")}))}}function S(t){var e=v(),n=v();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=v();function i(n,r){var i=I(e),o=i.box,a=i.content,s=i.arrow;r.theme?o.setAttribute("data-theme",r.theme):o.removeAttribute("data-theme"),"string"==typeof r.animation?o.setAttribute("data-animation",r.animation):o.removeAttribute("data-animation"),r.inertia?o.setAttribute("data-inertia",""):o.removeAttribute("data-inertia"),o.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?o.setAttribute("role",r.role):o.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||j(a,t.props),r.arrow?s?n.arrow!==r.arrow&&(o.removeChild(s),o.appendChild(V(r.arrow))):o.appendChild(V(r.arrow)):s&&o.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),j(r,t.props),e.appendChild(n),n.appendChild(r),i(t.props,t.props),{popper:e,onUpdate:i}}S.$$tippy=!0;var B=1,H=[],N=[];function U(e,n){var a,c,m,h,b,C,A,O,L,k=M(e,Object.assign({},D,{},R((a=n,Object.keys(a).reduce((function(t,e){return void 0!==a[e]&&(t[e]=a[e]),t}),{}))))),P=!1,V=!1,j=!1,S=!1,U=[],_=u(bt,k.interactiveDebounce),z=B++,F=(L=k.plugins).filter((function(t,e){return L.indexOf(t)===e})),W={id:z,reference:e,popper:v(),popperInstance:null,props:k,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:F,clearDelayTimeouts:function(){clearTimeout(c),clearTimeout(m),cancelAnimationFrame(h)},setProps:function(t){if(W.state.isDestroyed)return;it("onBeforeUpdate",[W,t]),gt();var n=W.props,r=M(e,Object.assign({},W.props,{},t,{ignoreAttributes:!0}));W.props=r,mt(),n.interactiveDebounce!==r.interactiveDebounce&&(st(),_=u(bt,r.interactiveDebounce));n.triggerTarget&&!r.triggerTarget?p(n.triggerTarget).forEach((function(t){t.removeAttribute("aria-expanded")})):r.triggerTarget&&e.removeAttribute("aria-expanded");at(),rt(),q&&q(n,r);W.popperInstance&&(Et(),Ct().forEach((function(t){requestAnimationFrame(t._tippy.popperInstance.forceUpdate)})));it("onAfterUpdate",[W,t])},setContent:function(t){W.setProps({content:t})},show:function(){var t=W.state.isVisible,e=W.state.isDestroyed,n=!W.state.isEnabled,r=T.isTouch&&!W.props.touch,i=o(W.props.duration,0,D.duration);if(t||e||n||r)return;if(Z().hasAttribute("disabled"))return;if(it("onShow",[W],!1),!1===W.props.onShow(W))return;W.state.isVisible=!0,Q()&&(Y.style.visibility="visible");rt(),ft(),W.state.isMounted||(Y.style.transition="none");if(Q()){var a=et(),u=a.box,c=a.content;y([u,c],0)}A=function(){if(W.state.isVisible&&!S){if(S=!0,Y.offsetHeight,Y.style.transition=W.props.moveTransition,Q()&&W.props.animation){var t=et(),e=t.box,n=t.content;y([e,n],i),x([e,n],"visible")}ot(),at(),f(N,W),W.state.isMounted=!0,it("onMount",[W]),W.props.animation&&Q()&&function(t,e){dt(t,e)}(i,(function(){W.state.isShown=!0,it("onShown",[W])}))}},function(){var t,e=W.props.appendTo,n=Z();t=W.props.interactive&&e===D.appendTo||"parent"===e?n.parentNode:s(e,[n]);t.contains(Y)||t.appendChild(Y);Et()}()},hide:function(){var t=!W.state.isVisible,e=W.state.isDestroyed,n=!W.state.isEnabled,r=o(W.props.duration,1,D.duration);if(t||e||n)return;if(it("onHide",[W],!1),!1===W.props.onHide(W))return;W.state.isVisible=!1,W.state.isShown=!1,S=!1,P=!1,Q()&&(Y.style.visibility="hidden");if(st(),lt(),rt(),Q()){var i=et(),a=i.box,s=i.content;W.props.animation&&(y([a,s],r),x([a,s],"hidden"))}ot(),at(),W.props.animation?Q()&&function(t,e){dt(t,(function(){!W.state.isVisible&&Y.parentNode&&Y.parentNode.contains(Y)&&e()}))}(r,W.unmount):W.unmount()},hideWithInteractivity:function(t){tt().addEventListener("mousemove",_),f(H,_),_(t)},enable:function(){W.state.isEnabled=!0},disable:function(){W.hide(),W.state.isEnabled=!1},unmount:function(){W.state.isVisible&&W.hide();if(!W.state.isMounted)return;Tt(),Ct().forEach((function(t){t._tippy.unmount()})),Y.parentNode&&Y.parentNode.removeChild(Y);N=N.filter((function(t){return t!==W})),W.state.isMounted=!1,it("onHidden",[W])},destroy:function(){if(W.state.isDestroyed)return;W.clearDelayTimeouts(),W.unmount(),gt(),delete e._tippy,W.state.isDestroyed=!0,it("onDestroy",[W])}};if(!k.render)return W;var X=k.render(W),Y=X.popper,q=X.onUpdate;Y.setAttribute("data-tippy-root",""),Y.id="tippy-"+W.id,W.popper=Y,e._tippy=W,Y._tippy=W;var $=F.map((function(t){return t.fn(W)})),J=e.hasAttribute("aria-expanded");return mt(),at(),rt(),it("onCreate",[W]),k.showOnCreate&&At(),Y.addEventListener("mouseenter",(function(){W.props.interactive&&W.state.isVisible&&W.clearDelayTimeouts()})),Y.addEventListener("mouseleave",(function(t){W.props.interactive&&W.props.trigger.indexOf("mouseenter")>=0&&(tt().addEventListener("mousemove",_),_(t))})),W;function G(){var t=W.props.touch;return Array.isArray(t)?t:[t,0]}function K(){return"hold"===G()[0]}function Q(){var t;return!!(null==(t=W.props.render)?void 0:t.$$tippy)}function Z(){return O||e}function tt(){var t=Z().parentNode;return t?w(t):document}function et(){return I(Y)}function nt(t){return W.state.isMounted&&!W.state.isVisible||T.isTouch||b&&"focus"===b.type?0:o(W.props.delay,t?0:1,D.delay)}function rt(){Y.style.pointerEvents=W.props.interactive&&W.state.isVisible?"":"none",Y.style.zIndex=""+W.props.zIndex}function it(t,e,n){var r;(void 0===n&&(n=!0),$.forEach((function(n){n[t]&&n[t].apply(void 0,e)})),n)&&(r=W.props)[t].apply(r,e)}function ot(){var t=W.props.aria;if(t.content){var n="aria-"+t.content,r=Y.id;p(W.props.triggerTarget||e).forEach((function(t){var e=t.getAttribute(n);if(W.state.isVisible)t.setAttribute(n,e?e+" "+r:r);else{var i=e&&e.replace(r,"").trim();i?t.setAttribute(n,i):t.removeAttribute(n)}}))}}function at(){!J&&W.props.aria.expanded&&p(W.props.triggerTarget||e).forEach((function(t){W.props.interactive?t.setAttribute("aria-expanded",W.state.isVisible&&t===Z()?"true":"false"):t.removeAttribute("aria-expanded")}))}function st(){tt().removeEventListener("mousemove",_),H=H.filter((function(t){return t!==_}))}function ut(t){if(!(T.isTouch&&(j||"mousedown"===t.type)||W.props.interactive&&Y.contains(t.target))){if(Z().contains(t.target)){if(T.isTouch)return;if(W.state.isVisible&&W.props.trigger.indexOf("click")>=0)return}else it("onClickOutside",[W,t]);!0===W.props.hideOnClick&&(W.clearDelayTimeouts(),W.hide(),V=!0,setTimeout((function(){V=!1})),W.state.isMounted||lt())}}function ct(){j=!0}function pt(){j=!1}function ft(){var t=tt();t.addEventListener("mousedown",ut,!0),t.addEventListener("touchend",ut,i),t.addEventListener("touchstart",pt,i),t.addEventListener("touchmove",ct,i)}function lt(){var t=tt();t.removeEventListener("mousedown",ut,!0),t.removeEventListener("touchend",ut,i),t.removeEventListener("touchstart",pt,i),t.removeEventListener("touchmove",ct,i)}function dt(t,e){var n=et().box;function r(t){t.target===n&&(E(n,"remove",r),e())}if(0===t)return e();E(n,"remove",C),E(n,"add",r),C=r}function vt(t,n,r){void 0===r&&(r=!1),p(W.props.triggerTarget||e).forEach((function(e){e.addEventListener(t,n,r),U.push({node:e,eventType:t,handler:n,options:r})}))}function mt(){var t;K()&&(vt("touchstart",ht,{passive:!0}),vt("touchend",yt,{passive:!0})),(t=W.props.trigger,t.split(/\s+/).filter(Boolean)).forEach((function(t){if("manual"!==t)switch(vt(t,ht),t){case"mouseenter":vt("mouseleave",yt);break;case"focus":vt(r?"focusout":"blur",xt);break;case"focusin":vt("focusout",xt)}}))}function gt(){U.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,i=t.options;e.removeEventListener(n,r,i)})),U=[]}function ht(t){var e,n=!1;if(W.state.isEnabled&&!wt(t)&&!V){var r="focus"===(null==(e=b)?void 0:e.type);b=t,O=t.currentTarget,at(),!W.state.isVisible&&g(t)&&H.forEach((function(e){return e(t)})),"click"===t.type&&(W.props.trigger.indexOf("mouseenter")<0||P)&&!1!==W.props.hideOnClick&&W.state.isVisible?n=!0:At(t),"click"===t.type&&(P=!n),n&&!r&&Ot(t)}}function bt(t){var e=t.target,n=Z().contains(e)||Y.contains(e);"mousemove"===t.type&&n||function(t,e){var n=e.clientX,r=e.clientY;return t.every((function(t){var e=t.popperRect,i=t.popperState,o=t.props.interactiveBorder,a=l(i.placement),s=i.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,p="right"===a?s.left.x:0,f="left"===a?s.right.x:0,d=e.top-r+u>o,v=r-e.bottom-c>o,m=e.left-n+p>o,g=n-e.right-f>o;return d||v||m||g}))}(Ct().concat(Y).map((function(t){var e,n=null==(e=t._tippy.popperInstance)?void 0:e.state;return n?{popperRect:t.getBoundingClientRect(),popperState:n,props:k}:null})).filter(Boolean),t)&&(st(),Ot(t))}function yt(t){wt(t)||W.props.trigger.indexOf("click")>=0&&P||(W.props.interactive?W.hideWithInteractivity(t):Ot(t))}function xt(t){W.props.trigger.indexOf("focusin")<0&&t.target!==Z()||W.props.interactive&&t.relatedTarget&&Y.contains(t.relatedTarget)||Ot(t)}function wt(t){return!!T.isTouch&&K()!==t.type.indexOf("touch")>=0}function Et(){Tt();var n=W.props,r=n.popperOptions,i=n.placement,o=n.offset,a=n.getReferenceClientRect,s=n.moveTransition,u=Q()?I(Y).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||Z()}:e,p=[{name:"offset",options:{offset:o}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(t){var e=t.state;if(Q()){var n=et().box;["placement","reference-hidden","escaped"].forEach((function(t){"placement"===t?n.setAttribute("data-placement",e.placement):e.attributes.popper["data-popper-"+t]?n.setAttribute("data-"+t,""):n.removeAttribute("data-"+t)})),e.attributes.popper={}}}}];Q()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==r?void 0:r.modifiers)||[]),W.popperInstance=t.createPopper(c,Y,Object.assign({},r,{placement:i,onFirstUpdate:A,modifiers:p}))}function Tt(){W.popperInstance&&(W.popperInstance.destroy(),W.popperInstance=null)}function Ct(){return d(Y.querySelectorAll("[data-tippy-root]"))}function At(t){W.clearDelayTimeouts(),t&&it("onTrigger",[W,t]),ft();var e=nt(!0),n=G(),r=n[0],i=n[1];T.isTouch&&"hold"===r&&i&&(e=i),e?c=setTimeout((function(){W.show()}),e):W.show()}function Ot(t){if(W.clearDelayTimeouts(),it("onUntrigger",[W,t]),W.state.isVisible){if(!(W.props.trigger.indexOf("mouseenter")>=0&&W.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(t.type)>=0&&P)){var e=nt(!1);e?m=setTimeout((function(){W.state.isVisible&&W.hide()}),e):h=requestAnimationFrame((function(){W.hide()}))}}else lt()}}function _(t,e){void 0===e&&(e={});var n=D.plugins.concat(e.plugins||[]);document.addEventListener("touchstart",A,i),window.addEventListener("blur",L);var r=Object.assign({},e,{plugins:n}),o=b(t).reduce((function(t,e){var n=e&&U(e,r);return n&&t.push(n),t}),[]);return m(t)?o[0]:o}_.defaultProps=D,_.setDefaultProps=function(t){Object.keys(t).forEach((function(e){D[e]=t[e]}))},_.currentInput=T;var z={mouseover:"mouseenter",focusin:"focus",click:"click"};var F={name:"animateFill",defaultValue:!1,fn:function(t){var e;if(!(null==(e=t.props.render)?void 0:e.$$tippy))return{};var n=I(t.popper),r=n.box,i=n.content,o=t.props.animateFill?function(){var t=v();return t.className="tippy-backdrop",x([t],"hidden"),t}():null;return{onCreate:function(){o&&(r.insertBefore(o,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",t.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(o){var t=r.style.transitionDuration,e=Number(t.replace("ms",""));i.style.transitionDelay=Math.round(e/10)+"ms",o.style.transitionDuration=t,x([o],"visible")}},onShow:function(){o&&(o.style.transitionDuration="0ms")},onHide:function(){o&&x([o],"hidden")}}}};var W={clientX:0,clientY:0},X=[];function Y(t){var e=t.clientX,n=t.clientY;W={clientX:e,clientY:n}}var q={name:"followCursor",defaultValue:!1,fn:function(t){var e=t.reference,n=w(t.props.triggerTarget||e),r=!1,i=!1,o=!0,a=t.props;function s(){return"initial"===t.props.followCursor&&t.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,t.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||e.contains(n.target),i=t.props.followCursor,o=n.clientX,a=n.clientY,s=e.getBoundingClientRect(),u=o-s.left,c=a-s.top;!r&&t.props.interactive||t.setProps({getReferenceClientRect:function(){var t=e.getBoundingClientRect(),n=o,r=a;"initial"===i&&(n=t.left+u,r=t.top+c);var s="horizontal"===i?t.top:r,p="vertical"===i?t.right:n,f="horizontal"===i?t.bottom:r,l="vertical"===i?t.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){t.props.followCursor&&(X.push({instance:t,doc:n}),function(t){t.addEventListener("mousemove",Y)}(n))}function d(){0===(X=X.filter((function(e){return e.instance!==t}))).filter((function(t){return t.doc===n})).length&&function(t){t.removeEventListener("mousemove",Y)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=t.props},onAfterUpdate:function(e,n){var o=n.followCursor;r||void 0!==o&&a.followCursor!==o&&(d(),o?(l(),!t.state.isMounted||i||s()||u()):(c(),p()))},onMount:function(){t.props.followCursor&&!i&&(o&&(f(W),o=!1),s()||u())},onTrigger:function(t,e){g(e)&&(W={clientX:e.clientX,clientY:e.clientY}),i="focus"===e.type},onHidden:function(){t.props.followCursor&&(p(),c(),o=!0)}}}};var $={name:"inlinePositioning",defaultValue:!1,fn:function(t){var e,n=t.reference;var r=-1,i=!1,o={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(i){var o=i.state;t.props.inlinePositioning&&(e!==o.placement&&t.setProps({getReferenceClientRect:function(){return function(t){return function(t,e,n,r){if(n.length<2||null===t)return e;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||e;switch(t){case"top":case"bottom":var i=n[0],o=n[n.length-1],a="top"===t,s=i.top,u=o.bottom,c=a?i.left:o.left,p=a?i.right:o.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(t){return t.left}))),l=Math.max.apply(Math,n.map((function(t){return t.right}))),d=n.filter((function(e){return"left"===t?e.left===f:e.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return e}}(l(t),n.getBoundingClientRect(),d(n.getClientRects()),r)}(o.placement)}}),e=o.placement)}};function a(){var e;i||(e=function(t,e){var n;return{popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat(((null==(n=t.popperOptions)?void 0:n.modifiers)||[]).filter((function(t){return t.name!==e.name})),[e])})}}(t.props,o),i=!0,t.setProps(e),i=!1)}return{onCreate:a,onAfterUpdate:a,onTrigger:function(e,n){if(g(n)){var i=d(t.reference.getClientRects()),o=i.find((function(t){return t.left-2<=n.clientX&&t.right+2>=n.clientX&&t.top-2<=n.clientY&&t.bottom+2>=n.clientY}));r=i.indexOf(o)}},onUntrigger:function(){r=-1}}}};var J={name:"sticky",defaultValue:!1,fn:function(t){var e=t.reference,n=t.popper;function r(e){return!0===t.props.sticky||t.props.sticky===e}var i=null,o=null;function a(){var s=r("reference")?(t.popperInstance?t.popperInstance.state.elements.reference:e).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&G(i,s)||u&&G(o,u))&&t.popperInstance&&t.popperInstance.update(),i=s,o=u,t.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){t.props.sticky&&a()}}}};function G(t,e){return!t||!e||(t.top!==e.top||t.right!==e.right||t.bottom!==e.bottom||t.left!==e.left)}return e&&function(t){var e=document.createElement("style");e.textContent=t,e.setAttribute("data-tippy-stylesheet","");var n=document.head,r=document.querySelector("head>style,head>link");r?n.insertBefore(e,r):n.appendChild(e)}('.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}'),_.setDefaultProps({plugins:[F,q,$,J],render:S}),_.createSingleton=function(t,e){void 0===e&&(e={});var n,r=t,i=[],o=e.overrides,a=[];function s(){i=r.map((function(t){return t.reference}))}function u(t){r.forEach((function(e){t?e.enable():e.disable()}))}function p(t){return r.map((function(e){var r=e.setProps;return e.setProps=function(i){r(i),e.reference===n&&t.setProps(i)},function(){e.setProps=r}}))}u(!1),s();var f={fn:function(){return{onDestroy:function(){u(!0)},onTrigger:function(t,e){var a=e.currentTarget,s=i.indexOf(a);if(a!==n){n=a;var u=(o||[]).concat("content").reduce((function(t,e){return t[e]=r[s].props[e],t}),{});t.setProps(Object.assign({},u,{getReferenceClientRect:"function"==typeof u.getReferenceClientRect?u.getReferenceClientRect:function(){return a.getBoundingClientRect()}}))}}}}},l=_(v(),Object.assign({},c(e,["overrides"]),{plugins:[f].concat(e.plugins||[]),triggerTarget:i})),d=l.setProps;return l.setProps=function(t){o=t.overrides||o,d(t)},l.setInstances=function(t){u(!0),a.forEach((function(t){return t()})),r=t,u(!1),s(),p(l),l.setProps({triggerTarget:i})},a=p(l),l},_.delegate=function(t,e){var n=[],r=[],i=!1,o=e.target,a=c(e,["target"]),s=Object.assign({},a,{trigger:"manual",touch:!1}),u=Object.assign({},a,{showOnCreate:!0}),f=_(t,s);function l(t){if(t.target&&!i){var n=t.target.closest(o);if(n){var a=n.getAttribute("data-tippy-trigger")||e.trigger||D.trigger;if(!n._tippy&&!("touchstart"===t.type&&"boolean"==typeof u.touch||"touchstart"!==t.type&&a.indexOf(z[t.type])<0)){var s=_(n,u);s&&(r=r.concat(s))}}}}function d(t,e,r,i){void 0===i&&(i=!1),t.addEventListener(e,r,i),n.push({node:t,eventType:e,handler:r,options:i})}return p(f).forEach((function(t){var e=t.destroy,o=t.enable,a=t.disable;t.destroy=function(t){void 0===t&&(t=!0),t&&r.forEach((function(t){t.destroy()})),r=[],n.forEach((function(t){var e=t.node,n=t.eventType,r=t.handler,i=t.options;e.removeEventListener(n,r,i)})),n=[],e()},t.enable=function(){o(),r.forEach((function(t){return t.enable()})),i=!1},t.disable=function(){a(),r.forEach((function(t){return t.disable()})),i=!0},function(t){var e=t.reference;d(e,"touchstart",l),d(e,"mouseover",l),d(e,"focusin",l),d(e,"click",l)}(t)})),f},_.hideAll=function(t){var e=void 0===t?{}:t,n=e.exclude,r=e.duration;N.forEach((function(t){var e=!1;if(n&&(e=h(n)?t.reference===n:t.popper===n.popper),!e){var i=t.props.duration;t.setProps({duration:r}),t.hide(),t.state.isDestroyed||t.setProps({duration:i})}}))},_.roundArrow='',_})); \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/assets/js/tippy/tippy.css b/html/wp-content/plugins/duplicator/assets/js/tippy/tippy.css new file mode 100644 index 0000000..d1cd2e1 --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/js/tippy/tippy.css @@ -0,0 +1 @@ +.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/assets/lib/lity/lity.min.css b/html/wp-content/plugins/duplicator/assets/lib/lity/lity.min.css new file mode 100644 index 0000000..02cb092 --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/lib/lity/lity.min.css @@ -0,0 +1,3 @@ +/*! Lity - v3.0.0-dev - 2018-07-09 +* http://sorgalla.com/lity/ +* Copyright (c) 2015-2018 Jan Sorgalla; Licensed MIT */.lity-active,.lity-active body{overflow:hidden}.lity{z-index:9990;position:fixed;top:0;right:0;bottom:0;left:0;white-space:nowrap;background:#0b0b0b;background:rgba(0,0,0,.9);outline:none!important;opacity:0;transition:opacity .3s ease}.lity.lity-opened{opacity:1}.lity.lity-closed{opacity:0}.lity *{box-sizing:border-box}.lity-wrap{z-index:9990;position:fixed;top:0;right:0;bottom:0;left:0;text-align:center;outline:none!important}.lity-wrap:before{content:"";display:inline-block;height:100%;vertical-align:middle;margin-right:-.25em}.lity-loader{z-index:9991;color:#fff;position:absolute;top:50%;margin-top:-.8em;width:100%;text-align:center;font-size:14px;font-family:Arial,Helvetica,sans-serif;opacity:0;transition:opacity .3s ease}.lity-loading .lity-loader{opacity:1}.lity-container{z-index:9992;position:relative;text-align:left;vertical-align:middle;display:inline-block;white-space:normal;max-width:100%;max-height:100%;outline:none!important}.lity-content{z-index:9993;width:100%;transform:scale(1);transition:transform .3s ease}.lity-closed .lity-content,.lity-loading .lity-content{transform:scale(.8)}.lity-content:after{content:"";position:absolute;left:0;top:0;bottom:0;display:block;right:0;width:auto;height:auto;z-index:-1;box-shadow:0 0 8px rgba(0,0,0,.6)}.lity-close,.lity-close:active,.lity-close:focus,.lity-close:hover,.lity-close:visited{z-index:9994;width:35px;height:35px;position:fixed;right:0;top:0;-webkit-appearance:none;cursor:pointer;text-decoration:none;text-align:center;padding:0;color:#fff;font-style:normal;font-size:35px;font-family:Arial,Baskerville,monospace;line-height:35px;text-shadow:0 1px 2px rgba(0,0,0,.6);border:0;background:none;box-shadow:none}.lity-close::-moz-focus-inner{border:0;padding:0}.lity-close:active{top:1px}.lity-image img{max-width:100%;display:block;line-height:0;border:0}.lity-iframe .lity-container{width:100%;max-width:964px}.lity-iframe-container{width:100%;height:0;padding-top:56.25%;overflow:auto;pointer-events:auto;transform:translateZ(0);-webkit-overflow-scrolling:touch}.lity-iframe-container iframe{position:absolute;display:block;top:0;left:0;width:100%;height:100%;box-shadow:0 0 8px rgba(0,0,0,.6);background:#000}.lity-hide{display:none} \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/assets/lib/lity/lity.min.js b/html/wp-content/plugins/duplicator/assets/lib/lity/lity.min.js new file mode 100644 index 0000000..2d9e23c --- /dev/null +++ b/html/wp-content/plugins/duplicator/assets/lib/lity/lity.min.js @@ -0,0 +1,5 @@ +/*! Lity - v3.0.0-dev - 2019-08-07 +* http://sorgalla.com/lity/ +* Copyright (c) 2015-2019 Jan Sorgalla; Licensed MIT */ + +!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return b(a,c)}):"object"==typeof module&&"object"==typeof module.exports?module.exports=b(a,require("jquery")):a.lity=b(a,a.jQuery||a.Zepto)}("undefined"!=typeof window?window:this,function(a,b){"use strict";function c(a){var b=y();return G&&a.length?(a.one(G,b.resolve),setTimeout(b.resolve,500)):b.resolve(),b.promise()}function d(a,c,d){if(1===arguments.length)return b.extend({},a);if("string"==typeof c){if(void 0===d)return void 0===a[c]?null:a[c];a[c]=d}else b.extend(a,c);return this}function e(a){var b=a.indexOf("?");b>-1&&(a=a.substr(b+1));for(var c,d=decodeURI(a.split("#")[0]).split("&"),e={},f=0,g=d.length;f-1){var d=a.split("?");a=d.shift(),c=b.extend({},e(d[0]),c)}return a+"?"+b.param(c)}function g(a,b){var c=a.indexOf("#");return-1===c?b:(c>0&&(a=a.substr(c)),b+a)}function h(a,b,c,d){return b&&b.element().addClass("lity-iframe"),c&&(a=f(a,c)),d&&(a=g(d,a)),'
        '; + return DUPX_U_Html::getLigthBox($linkLabelHtml, $titleContent, $lightBoxContent, $echo, $afterContent); + } + + protected static function lightBoxCss() + { + ?> + + + + + + $atValue) { + $attrsHtml[] = $atName . '="' . DUPX_U::esc_attr($atValue) . '"'; + } + ?> + + /> + + + + + + + + > + > + + + + + 'help', + DUPX_Security::CTRL_TOKEN => DUPX_CSRF::generate('help'), + 'basic' => '', + 'open_section' => $helpOpenSection + )); + } + + public static function helpLink($section, $linkLabel = 'Help', $echo = true) + { + ob_start(); + $help_url = self::getHelpLink($section); + DUPX_U_Html::getLightBoxIframe($linkLabel, 'HELP', $help_url); + if ($echo) { + ob_end_flush(); + } else { + return ob_get_clean(); + } + } + + public static function helpLockLink() + { + if (DUPX_ArchiveConfig::getInstance()->secure_on) { + self::helpLink('secure', ''); + } else { + self::helpLink('secure', ''); + } + } + + public static function helpIconLink($section) + { + self::helpLink($section, ''); + } + + /** + * Get badge class attr val from status + * + * @param string $status + * + * @return string html class attribute + */ + public static function getBadgeClassFromCheckStatus($status) + { + switch ($status) { + case 'Pass': + return 'status-badge.pass'; + case 'Fail': + return 'status-badge.fail'; + case 'Warn': + return 'status-badge.warn'; + default: + Log::error(sprintf("The arcCheck var has the illegal value %s in switch case", Log::v2str($status))); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/.htaccess b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/.htaccess new file mode 100644 index 0000000..a58990b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/.htaccess @@ -0,0 +1,9 @@ + + Order Deny,Allow + Deny from all + + + + Order Allow,Deny + Allow from all + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.ajax.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.ajax.php new file mode 100644 index 0000000..99e0346 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.ajax.php @@ -0,0 +1,313 @@ + true, + 'message' => '', + "errorContent" => array( + 'pre' => '', + 'html' => '' + ), + 'trace' => '', + 'actionData' => null + ); + + Log::setThrowExceptionOnError(true); + + try { + DUPX_Template::getInstance()->setTemplate(PrmMng::getInstance()->getValue(PrmMng::PARAM_TEMPLATE)); + $jsonResult['actionData'] = self::actions($action); + } catch (Exception $e) { + Log::logException($e); + + if (SnapString::isHTML($e->getMessage())) { + $message = $e->getMessage(); + } else { + $message = DUPX_U::esc_html($e->getMessage()); + } + + $jsonResult = array( + 'success' => false, + 'message' => $message, + "errorContent" => array( + 'pre' => Log::getLogException($e), + 'html' => '' + ) + ); + } + + $invalidOutput = SnapUtil::obCleanAll(); + ob_end_clean(); + if (strlen($invalidOutput) > 0) { + Log::info('INVALID AJAX OUTPUT:' . "\n" . $invalidOutput . "\n---------------------------------"); + } + + if ($jsonResult['success']) { + Log::info('AJAX ACTION [' . $action . '] SUCCESS'); + } else { + Log::info('AJAX ACTION [' . $action . '] FAIL, MESSAGE: ' . $jsonResult['message']); + } + + Log::info('-------------------------' . "\n"); + + if (!headers_sent()) { + header('Content-Type: application/json'); + } + echo SnapJson::jsonEncode($jsonResult); + Log::close(); + // if is ajax always die; + die(); + } + + /** + * ajax actions + * + * @param string $action + * + * @return mixed + */ + protected static function actions($action) + { + $actionData = null; + + self::debugAjaxCallSleep(); + + switch ($action) { + case self::ACTION_PWD_CHECK: + $actionData = DUPX_Security::getInstance()->securityCheck(); + break; + case self::ACTION_EMAIL_SUBSCRIPTION: + $actionData = DUPX_Ctrl_Params::setParamEmail(); + break; + case self::ACTION_PROCEED_CONFIRM_DIALOG: + $vData = DUPX_Validation_database_service::getInstance(); + if (!$vData->getDbConnection()) { + throw new Exception('Connection DB data isn\'t valid'); + } + $actionData = dupxTplRender( + 'pages-parts/step1/proceed-confirm-dialog', + array( + 'tableCount' => $vData->getDBActionAffectedTablesCount() + ), + false + ); + break; + case self::ACTION_VALIDATE: + DUP_Extraction::resetData(); + $actionData = DUPX_Validation_manager::getInstance()->getValidateData(); + if ($actionData['mainLevel'] <= DUPX_Validation_abstract_item::LV_FAIL) { + sleep(self::PREVENT_BRUTE_FORCE_ATTACK_SLEEP); + } else { + DUPX_Ctrl_Params::setParamsAfterValidation(); + } + $actionData['nextStepMessagesHtml'] = DUPX_NOTICE_MANAGER::getInstance()->nextStepMessages(true, false); + + break; + case self::ACTION_SET_PARAMS_S1: + $valid = DUPX_Ctrl_Params::setParamsStep1(); + DUPX_NOTICE_MANAGER::getInstance()->nextStepLog(false); + $nexStepNotices = DUPX_NOTICE_MANAGER::getInstance()->nextStepMessages(true, false); + $actionData = array( + 'isValid' => $valid, + 'nextStepMessagesHtml' => $nexStepNotices + ); + break; + case self::ACTION_SET_PARAMS_S2: + $valid = DUPX_Ctrl_Params::setParamsStep2(); + DUPX_NOTICE_MANAGER::getInstance()->nextStepLog(false); + $nexStepNotices = DUPX_NOTICE_MANAGER::getInstance()->nextStepMessages(true, false); + $actionData = array( + 'isValid' => $valid, + 'nextStepMessagesHtml' => $nexStepNotices + ); + break; + case self::ACTION_SET_PARAMS_S3: + $valid = DUPX_Ctrl_Params::setParamsStep3(); + DUPX_NOTICE_MANAGER::getInstance()->nextStepLog(false); + $nexStepNotices = DUPX_NOTICE_MANAGER::getInstance()->nextStepMessages(true, false); + $actionData = array( + 'isValid' => $valid, + 'nextStepMessagesHtml' => $nexStepNotices + ); + break; + case self::ACTION_EXTRACTION: + $extractor = DUP_Extraction::getInstance(); + DUPX_U::maintenanceMode(true); + $extractor->runExtraction(); + $actionData = $extractor->finishExtraction(); + break; + case self::ACTION_DBINSTALL: + $dbInstall = DUPX_DBInstall::getInstance(); + $actionData = $dbInstall->deploy(); + DUPX_Plugins_Manager::getInstance()->preViewChecks(); + break; + case self::ACTION_WEBSITE_UPDATE: + $actionData = DUPX_S3_Funcs::getInstance()->updateWebsite(); + break; + case self::ACTION_FINAL_TESTS_PREPARE: + $actionData = TestsExecuter::preTestPrepare(); + break; + case self::ACTION_FINAL_TESTS_AFTER: + $actionData = TestsExecuter::afterTestClean(); + break; + case self::ACTION_SET_AUTO_CLEAN_FILES: + if (DUPX_Ctrl_Params::setParamAutoClean()) { + $valid = DUPX_S3_Funcs::getInstance()->duplicatorMigrationInfoSet(); + } else { + $valid = false; + } + DUPX_NOTICE_MANAGER::getInstance()->nextStepLog(false); + $nexStepNotices = DUPX_NOTICE_MANAGER::getInstance()->nextStepMessages(true, false); + $actionData = array( + 'isValid' => $valid, + 'nextStepMessagesHtml' => $nexStepNotices + ); + break; + default: + throw new Exception('Invalid ajax action'); + } + return $actionData; + } + + /** + * Check if current call is ajax + * + * @param string $action if is ajax $action is set with action string + * + * @return bool true if is ajax + */ + public static function isAjax(&$action = null) + { + static $isAjaxAction = null; + if (is_null($isAjaxAction)) { + $isAjaxAction = array( + 'isAjax' => false, + 'action' => false + ); + + $argsInput = SnapUtil::filterInputRequestArray(array( + PrmMng::PARAM_CTRL_ACTION => array( + 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, + 'flags' => FILTER_REQUIRE_SCALAR | FILTER_FLAG_STRIP_HIGH, + 'options' => array('default' => '') + ), + self::ACTION_NAME => array( + 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, + 'flags' => FILTER_REQUIRE_SCALAR | FILTER_FLAG_STRIP_HIGH, + 'options' => array('default' => false) + ) + )); + + if ($argsInput[PrmMng::PARAM_CTRL_ACTION] !== 'ajax' || $argsInput[self::ACTION_NAME] === false) { + $isAjaxAction['isAjax'] = false; + } else { + if (($isAjaxAction['isAjax'] = in_array($argsInput[self::ACTION_NAME], self::ajaxActions()))) { + $isAjaxAction['action'] = $argsInput[self::ACTION_NAME]; + } + } + } + + if ($isAjaxAction['isAjax']) { + $action = $isAjaxAction['action']; + } + return $isAjaxAction['isAjax']; + } + + public static function getTokenKeyByAction($action) + { + return self::ACTION_NAME . $action; + } + + public static function getTokenFromInput() + { + return SnapUtil::filterInputDefaultSanitizeString(INPUT_POST, self::TOKEN_NAME, false); + } + + public static function generateToken($action) + { + return DUPX_CSRF::generate(self::getTokenKeyByAction($action)); + } + + protected static function debugAjaxCallSleep() + { + if (self::DEBUG_AJAX_CALL_SLEEP > 0) { + sleep(self::DEBUG_AJAX_CALL_SLEEP); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.dbinstall.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.dbinstall.php new file mode 100644 index 0000000..63613be --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.dbinstall.php @@ -0,0 +1,1345 @@ +initData(); + } + + /** + * inizialize extraction data + */ + protected function initData() + { + // if data file exists load saved data + if (file_exists(self::dbinstallDataFilePath())) { + Log::info('LOAD DBINSTALL DATA FROM JSON', Log::LV_DETAILED); + if ($this->loadData() == false) { + throw new Exception('Can\'t load dbinstall data'); + } + } else { + Log::info('INIT DB INSTALL DATA', Log::LV_DETAILED); + $this->constructData(); + $this->initLogDbInstall(); + $this->saveData(); + } + } + + protected function constructData() + { + $paramsManager = PrmMng::getInstance(); + $this->start_microtime = DUPX_U::getMicrotime(); + $this->sql_file_path = DUPX_Package::getSqlFilePath(); + $this->dbFileSize = DUPX_Package::getSqlFileSize(); + $this->profile_start = DUPX_U::getMicrotime(); + + $this->post = array( + 'view_mode' => $paramsManager->getValue(PrmMng::PARAM_DB_VIEW_MODE), + 'dbname' => $paramsManager->getValue(PrmMng::PARAM_DB_NAME), + 'dbuser' => $paramsManager->getValue(PrmMng::PARAM_DB_USER), + 'dbpass' => $paramsManager->getValue(PrmMng::PARAM_DB_PASS), + 'dbport' => parse_url($paramsManager->getValue(PrmMng::PARAM_DB_HOST), PHP_URL_PORT), + 'dbmysqlmode' => $paramsManager->getValue(PrmMng::PARAM_DB_MYSQL_MODE), + 'dbmysqlmode_opts' => $paramsManager->getValue(PrmMng::PARAM_DB_MYSQL_MODE_OPTS), + 'pos' => 0, + 'pass' => false, + 'first_chunk' => true, + 'dbchunk_retry' => 0, + 'continue_chunking' => $paramsManager->getValue(PrmMng::PARAM_DB_CHUNK), + 'progress' => 0, + 'delimiter' => ';', + 'is_error' => 0, + 'error_msg' => '' + ); + + $this->dbaction = $paramsManager->getValue(PrmMng::PARAM_DB_ACTION); + $this->dbcharset = $paramsManager->getValue(PrmMng::PARAM_DB_CHARSET); + $this->dbcollate = $paramsManager->getValue(PrmMng::PARAM_DB_COLLATE); + $this->dbsplit_creates = $paramsManager->getValue(PrmMng::PARAM_DB_SPLIT_CREATES); + + $this->dbUserMode = new DbUserMode(); + } + + protected function initLogDbInstall() + { + $paramsManager = PrmMng::getInstance(); + $labelPadSize = 20; + Log::info("\n\n\n********************************************************************************"); + Log::info('* DUPLICATOR LITE: INSTALL-LOG'); + Log::info('* STEP-2 START @ ' . @date('h:i:s')); + Log::info('* NOTICE: Do NOT post to public sites or forums!!'); + Log::info("********************************************************************************"); + Log::info("USER INPUTS"); + Log::info(str_pad('DB ENGINE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_ENGINE))); + Log::info(str_pad('VIEW MODE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_VIEW_MODE))); + Log::info(str_pad('DB ACTION', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_ACTION))); + Log::info(str_pad('DB HOST', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str('**OBSCURED**')); + Log::info(str_pad('DB NAME', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str('**OBSCURED**')); + Log::info(str_pad('DB PASS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str('**OBSCURED**')); + Log::info(str_pad('DB PORT', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str('**OBSCURED**')); + Log::info(str_pad('USER MODE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_USERS_MODE))); + Log::info(str_pad('TABLE PREFIX', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_TABLE_PREFIX))); + Log::info(str_pad('MYSQL MODE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_MYSQL_MODE))); + Log::info(str_pad('MYSQL MODE OPTS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_MYSQL_MODE_OPTS))); + Log::info(str_pad('CHARSET', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_CHARSET))); + Log::info(str_pad('COLLATE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_COLLATE))); + Log::info(str_pad('CUNKING', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_CHUNK))); + Log::info(str_pad('VIEW CREATION', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_VIEW_CREATION))); + Log::info(str_pad('STORED PROCEDURE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_PROC_CREATION))); + Log::info(str_pad('FUNCTIONS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_FUNC_CREATION))); + Log::info(str_pad('REMOVE DEFINER', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_REMOVE_DEFINER))); + Log::info(str_pad('SPLIT CREATES', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_DB_SPLIT_CREATES))); + + $tables = DUPX_DB_Tables::getInstance()->getTables(); + Log::info("--------------------------------------"); + Log::info('TABLES'); + Log::info("--------------------------------------"); + foreach ($tables as $tablesObj) { + Log::info('TABLE ' . str_pad(Log::v2str($tablesObj->getOriginalName()), 50, '_', STR_PAD_RIGHT) + . '[ROWS:' . str_pad($tablesObj->getRows(), 8, " ", STR_PAD_LEFT) . ']' + . ' [' . ($tablesObj->extract() ? 'EXTRACT' : 'NO EXTR') . '|' . ($tablesObj->replaceEngine() ? 'REPLACE' : 'NO REPL') . '] ' + . '[INST NAME: ' . $tablesObj->getNewName() . ']'); + } + Log::info("********************************************************************************\n"); + Log::flush(); + } + + public function deploy() + { + $paramsManager = PrmMng::getInstance(); + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + Log::setThrowExceptionOnError(true); + if ($this->firstOrNotChunking()) { + if ($this->post['dbchunk_retry'] > 0) { + Log::info("## >> Last DB Chunk installation was failed, so retrying from start point. Retrying count: " . $this->post['dbchunk_retry']); + } + + $this->prepareDB(); + + //Fatal Memory errors from file_get_contents is not catchable. + //Try to warn ahead of time with a check on buffer in memory difference + $current_php_mem = DUPX_U::returnBytes($GLOBALS['PHP_MEMORY_LIMIT']); + $current_php_mem = is_numeric($current_php_mem) ? $current_php_mem : null; + + if ($current_php_mem != null && $this->dbFileSize > $current_php_mem) { + $readable_size = DUPX_U::readableByteSize($this->dbFileSize); + $msg = "\nWARNING: The database script is '{$readable_size}' in size. The PHP memory allocation is set\n"; + $msg .= "at '{$GLOBALS['PHP_MEMORY_LIMIT']}'. There is a high possibility that the installer script will fail with\n"; + $msg .= "a memory allocation error when trying to load the database.sql file. It is\n"; + $msg .= "recommended to increase the 'memory_limit' setting in the php.ini config file.\n"; + $msg .= "see: " . DUPX_Constants::FAQ_URL . "how-to-manage-server-resources-cpu-memory-disk/ \n"; + Log::info($msg); + unset($msg); + } + + Log::info("--------------------------------------"); + Log::info("DATABASE RESULTS"); + Log::info("--------------------------------------"); + } + + switch ($paramsManager->getValue(PrmMng::PARAM_DB_ACTION)) { + case self::DBACTION_MANUAL: + Log::info("\n** SQL EXECUTION IS IN MANUAL MODE **"); + Log::info("- No SQL script has been executed -"); + $this->post['pass'] = 1; + $this->post['continue_chunking'] = false; + break; + case DUPX_DBInstall::DBACTION_ONLY_CONNECT: + case DUPX_DBInstall::DBACTION_CREATE: + case DUPX_DBInstall::DBACTION_EMPTY: + case DUPX_DBInstall::DBACTION_REMOVE_ONLY_TABLES: + case DUPX_DBInstall::DBACTION_RENAME: + if ($this->firstOrNotChunking()) { + $this->beforeInstallDatabaseActions(); + } + $this->insertDatabase(); + if (!$this->post['continue_chunking']) { + $this->afterInstallDatabaseActions(); + } + break; + default: + throw new Exception('Invalid db action'); + } + $this->post['first_chunk'] = false; + + $this->saveData(); + $nManager->saveNotices(); + + return $this->getResultData(); + } + + /** + * + * @throws Exception + */ + protected function insertDatabase() + { + $paramsManager = PrmMng::getInstance(); + $validation = false; + if ($paramsManager->getValue(PrmMng::PARAM_DB_CHUNK)) { + if ($this->post['continue_chunking'] == true) { + if ($this->deployDatabaseChunkMode() == false) { + throw new Exception('Error on db extraction'); + } + } elseif ($this->post['pass'] == 1) { + $validation = true; + } else { + throw new Exception('Error on db extraction'); + } + } else { + $this->deployDatabaseSingleMode(); + $validation = true; + } + + if ($validation) { + $rowCountMisMatchTables = $this->getRowCountMisMatchTables(); + $this->post['pass'] = 1; + if (!empty($rowCountMisMatchTables)) { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $errMsg = 'Database Table row count verification was failed for table(s): ' + . implode(', ', $rowCountMisMatchTables) . '.'; + Log::info($errMsg); + $nManager->addBothNextAndFinalReportNotice( + array( + 'shortMsg' => 'Database Table row count was validation failed', + 'level' => DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => $errMsg, + 'sections' => 'database' + ) + ); + } + } + } + + /** + * Actione executed before db install + * + * @return void + */ + protected function beforeInstallDatabaseActions() + { + $this->queryFixes = new QueryFixes(); + $this->queryFixes->logRules(); + DbUserMode::moveTargetUserTablesOnCurrentPrefix(); + $this->dbUserMode->removeAllUserMetaKeysOfCurrentPrefix(); + $this->dbUserMode->initTargetSiteUsersData(); + $this->saveData(); + } + + protected function afterInstallDatabaseActions() + { + $this->dbUserMode->generateImportReport(); + $profileEnd = DUPX_U::getMicrotime(); + $this->writeLog(); + + //FINAL RESULTS + $ajax1_sum = DUPX_U::elapsedTime($profileEnd, $this->start_microtime); + Log::info("\nINSERT DATA RUNTIME: " . DUPX_U::elapsedTime($profileEnd, $this->profile_start)); + Log::info('STEP-2 COMPLETE @ ' . @date('h:i:s') . " - RUNTIME: {$ajax1_sum}"); + self::resetData(); + } + + /** + * + * @return string + */ + protected static function dbinstallDataFilePath() + { + static $path = null; + if (is_null($path)) { + $path = DUPX_INIT . '/dup-installer-dbinstall__' . DUPX_Package::getPackageHash() . '.json'; + } + return $path; + } + + /** + * + * @staticvar string $path + * @return string + */ + protected static function seekTellFilePath() + { + static $path = null; + if (is_null($path)) { + $path = DUPX_INIT . "/dup-database-seek-tell-log__" . DUPX_ArchiveConfig::getInstance()->package_hash . ".txt"; + } + return $path; + } + + /** + * + * @return boolean + */ + protected function saveData() + { + if (($json = SnapJson::jsonEncodePPrint($this)) === false) { + Log::info('Can\'t encode json data'); + return false; + } + + if (file_put_contents(self::dbinstallDataFilePath(), $json) === false) { + throw new Exception('Can\'t save dbinstall data file'); + } + + return true; + } + + /** + * It can clean up the object and is supposed to return an array with the + * names of all variables of that object that should be serialized. + * + * @return string[] + */ + public function __sleep() + { + $props = array_keys(get_object_vars($this)); + return array_diff($props, array('dbh')); + } + + /** + * + * @return boolean + */ + protected function loadData() + { + if (!file_exists(self::dbinstallDataFilePath())) { + return false; + } + + if (($json = file_get_contents(self::dbinstallDataFilePath())) === false) { + throw new Exception('Can\'t load dbinstall data file'); + } + + JsonSerialize::unserializeToObj($json, $this); + + return true; + } + + /** + * + * @return boolean + */ + public static function resetData() + { + $result = true; + if (file_exists(self::dbinstallDataFilePath())) { + if (unlink(self::dbinstallDataFilePath()) === false) { + throw new Exception('Can\'t delete dbinstall data file'); + } + } + if (file_exists(self::seekTellFilePath())) { + if (unlink(self::seekTellFilePath()) === false) { + throw new Exception('Can\'t delete dbinstall chunk seek data file'); + } + } + return $result; + } + + /** + * execute a connection if db isn't connected + * + * @return resource + */ + protected function dbConnect($reconnect = false) + { + if ($reconnect) { + $this->dbClose(); + } + + $paramsManager = PrmMng::getInstance(); + + if (is_null($this->dbh)) { + switch ($this->dbaction) { + case self::DBACTION_EMPTY: + case self::DBACTION_REMOVE_ONLY_TABLES: + case self::DBACTION_RENAME: + case self::DBACTION_ONLY_CONNECT: + //ESTABLISH CONNECTION + if (($this->dbh = DUPX_DB_Functions::getInstance()->dbConnection()) == false) { + $this->dbh = null; + Log::error(ERR_DBCONNECT . mysqli_connect_error()); + } + + // EXEC ALWAYS A DB SELECT is required when chunking is activated + if (DUPX_DB::selectDB($this->dbh, $paramsManager->getValue(PrmMng::PARAM_DB_NAME)) == false) { + Log::error(sprintf(ERR_DBCREATE, $paramsManager->getValue(PrmMng::PARAM_DB_NAME))); + } + break; + case self::DBACTION_CREATE: + //ESTABLISH CONNECTION WITHOUT DATABASE NAME + $connParams = array( + 'dbhost' => $paramsManager->getValue(PrmMng::PARAM_DB_HOST), + 'dbname' => null, + 'dbuser' => $paramsManager->getValue(PrmMng::PARAM_DB_USER), + 'dbpass' => $paramsManager->getValue(PrmMng::PARAM_DB_PASS) + ); + + if (($this->dbh = DUPX_DB_Functions::getInstance()->dbConnection($connParams)) == false) { + $this->dbh = null; + Log::error(ERR_DBCONNECT . mysqli_connect_error()); + } + + // don't check for success because in the create new database option the database may not exist. + DUPX_DB::selectDB($this->dbh, $paramsManager->getValue(PrmMng::PARAM_DB_NAME)); + break; + case self::DBACTION_MANUAL: + Log::info('DB ACTION MANUAL'); + break; + default: + Log::error('Invalid dbaction: ' . Log::v2str($this->dbaction)); + break; + } + + try { + DUPX_DB::mysqli_query($this->dbh, "SET wait_timeout = " . mysqli_real_escape_string($this->dbh, $GLOBALS['DB_MAX_TIME'])); + DUPX_DB::mysqli_query($this->dbh, "SET GLOBAL max_allowed_packet = " . mysqli_real_escape_string($this->dbh, $GLOBALS['DB_MAX_PACKETS']), Log::LV_DEBUG); + DUPX_DB::mysqli_query($this->dbh, "SET max_allowed_packet = " . mysqli_real_escape_string($this->dbh, $GLOBALS['DB_MAX_PACKETS']), Log::LV_DEBUG); + + $this->dbvar_maxtime = DUPX_DB::getVariable($this->dbh, 'wait_timeout', 300); + $this->dbvar_maxpacks = DUPX_DB::getVariable($this->dbh, 'max_allowed_packet', MB_IN_BYTES); + $this->dbvar_sqlmode = DUPX_DB::getVariable($this->dbh, 'sql_mode', 'NOT_SET'); + } catch (Exception $e) { + Log::logException($e, Log::LV_DEFAULT, 'EXCEPTION ON DB SET VARS [CONTINUE]'); + } + } + return $this->dbh; + } + + protected function dbClose() + { + if (!is_null($this->dbh)) { + mysqli_close($this->dbh); + $this->dbh = null; + } + } + + protected function pingAndReconnect() + { + if (!$this->dbh instanceof mysqli) { + $this->dbConnect(true); + return; + } + + try { + $result = $this->dbh->query('/* ping */ DO 1'); + + if ($result instanceof mysqli_result) { + $result->free(); + } + } catch (Throwable $e) { + Log::info('DB PING FAILED: ' . $e->getMessage()); + Log::info('Attempting to reconnect'); + $this->dbConnect(true); + } + } + + protected function prepareDB() + { + if ($this->dbaction === self::DBACTION_MANUAL) { + return; + } + + $this->dbConnect(); + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + + DUPX_DB::setCharset($this->dbh, $this->dbcharset, $this->dbcollate); + $this->setSQLSessionMode(); + + //Set defaults incase the variable could not be read + $this->drop_tbl_log = 0; + $this->rename_tbl_log = 0; + $sql_file_size1 = DUPX_U::readableByteSize(DUPX_Package::getSqlFileSize()); + + Log::info("--------------------------------------"); + Log::info('DATABASE-ENVIRONMENT'); + Log::info("--------------------------------------"); + Log::info( + "MYSQL VERSION:\tThis Server: " . + DUPX_DB::getVersion($this->dbh) . + " -- Build Server: {$archiveConfig->version_db}" + ); + Log::info("FILE SIZE:\t" . basename(DUPX_Package::getSqlFilePath()) . " ({$sql_file_size1})"); + Log::info("TIMEOUT:\t{$this->dbvar_maxtime}"); + Log::info("MAXPACK:\t{$this->dbvar_maxpacks}"); + Log::info("SQLMODE-GLOBAL:\t{$this->dbvar_sqlmode}"); + Log::info("SQLMODE-SESSION:" . ($this->getSQLSessionMode())); + + switch ($this->dbaction) { + case self::DBACTION_CREATE: + $this->dbActionCreate(); + break; + case self::DBACTION_EMPTY: + $this->dbActionEmpty(); + break; + case self::DBACTION_REMOVE_ONLY_TABLES: + $this->dbActionRemoveOnlyTables(); + break; + case self::DBACTION_RENAME: + $this->dbActionRename(); + break; + case self::DBACTION_MANUAL: + case self::DBACTION_ONLY_CONNECT: + break; + default: + Log::error('DB ACTION INVALID'); + break; + } + } + + protected function dbActionCreate() + { + if ($this->post['view_mode'] == 'basic') { + DUPX_DB::mysqli_query($this->dbh, "CREATE DATABASE IF NOT EXISTS `" . mysqli_real_escape_string($this->dbh, $this->post['dbname']) . "`"); + } + + if (mysqli_select_db($this->dbh, mysqli_real_escape_string($this->dbh, $this->post['dbname'])) == false) { + Log::error(sprintf(ERR_DBCONNECT_CREATE, $this->post['dbname'])); + } + } + + protected function dbActionEmpty() + { + $excludeDropTable = DUPX_DB_Functions::getExcludedTables(); + + //Drop all tables, views and procs + $this->dropTables($excludeDropTable); + DbCleanup::dropViews(); + DbCleanup::dropProcs(); + DbCleanup::dropFuncs(); + } + + protected function dbActionRemoveOnlyTables() + { + $excludeDropTable = DUPX_DB_Functions::getExcludedTables(); + + $this->dropTables($excludeDropTable, DUPX_DB_Tables::getInstance()->getNewTablesNames()); + + DbCleanup::dropProcs(); + DbCleanup::dropFuncs(); + DbCleanup::dropViews(); + } + + protected function dbActionRename() + { + Log::info('TABLE RENAME TO BACKUP'); + + $copyTables = array(); + if (ParamDescUsers::getUsersMode() !== ParamDescUsers::USER_MODE_OVERWRITE) { + $paramsManager = PrmMng::getInstance(); + $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + $copyTables = array( + DUPX_DB_Functions::getUserTableName($overwriteData['table_prefix']), + DUPX_DB_Functions::getUserMetaTableName($overwriteData['table_prefix']) + ); + } + + DUPX_DB_Functions::getInstance()->pregReplaceTableName('/^(.+)$/', $GLOBALS['DB_RENAME_PREFIX'] . '$1', array( + 'prefixFilter' => DUPX_Constants::BACKUP_RENAME_PREFIX, + 'regexTablesDropFkeys' => '^' . SnapDB::quoteRegex($GLOBALS['DB_RENAME_PREFIX']) . '.+', + 'copyTables' => $copyTables, + 'exclude' => array( + DUPX_DB_Functions::getUserTableName(self::TEMP_DB_PREFIX), + DUPX_DB_Functions::getUserMetaTableName(self::TEMP_DB_PREFIX) + ) + )); + } + + /** + * Return true if is delimiter query line and set new delimiter + * + * @param string $line query line + * + * @return boolean|string false if isn't delimiter or delimiter string + */ + protected static function isDelimiterLine($line) + { + $delimiterMatch = null; + + if (preg_match('/^\s*DELIMITER\s+([^\s]+)\s*$/i', $line, $delimiterMatch) === 1) { + $delimiter = $delimiterMatch[1]; + Log::info("SET DELIMITER " . $delimiter . " AND SKIP QUERY"); + return $delimiter; + } else { + return false; + } + } + + protected function deployDatabaseChunkMode() + { + Log::info("--------------------------------------"); + Log::info("** DATABASE CHUNK install start"); + Log::info("--------------------------------------"); + $this->dbConnect(); + + if (isset($this->post['dbchunk_retry']) && $this->post['dbchunk_retry'] > 0) { + Log::info("DATABASE CHUNK RETRY COUNT: " . Log::v2str($this->post['dbchunk_retry'])); + } + + $delimiter = $this->post['delimiter']; + + $handle = fopen($this->sql_file_path, 'rb'); + if ($handle === false) { + return false; + } + + Log::info("DATABASE CHUNK SEEK POSITION: " . Log::v2str($this->post['pos'])); + + if (-1 !== fseek($handle, $this->post['pos'])) { + DUPX_DB::setCharset($this->dbh, $this->dbcharset, $this->dbcollate); + + $this->setSQLSessionMode(); + + $this->thread_start_time = DUPX_U::getMicrotime(); + + Log::info('DATABASE CHUNK START POS:' . Log::v2str($this->post['pos']), Log::LV_DETAILED); + $this->pingAndReconnect(); + + if (@mysqli_autocommit($this->dbh, false)) { + Log::info('Auto Commit set to false successfully'); + } else { + Log::info('Failed to set Auto Commit to false'); + } + + Log::info("DATABASE CHUNK: Iterating query loop", Log::LV_DEBUG); + + if (!$this->post['first_chunk'] && !empty($this->setQueries)) { + Log::info("SET QUERIES FROM FIRST CHUNK", Log::LV_DETAILED); + foreach ($this->setQueries as $setQuery) { + Log::info("\tSET QUERY " . Log::v2str($setQuery), Log::LV_DEBUG); + $this->writeQueryInDB($setQuery); + } + } + + $query = ''; + $skipChunkTimeoutCheck = $this->dbsplit_creates && $this->post['first_chunk']; + + while (($line = fgets($handle)) !== false) { + if (($res = self::isDelimiterLine($line)) !== false) { + $query = ''; + $delimiter = $this->post['delimiter'] = $res; + continue; + } + + if ($this->post['first_chunk']) { + //Matches ordinary set queries e.g "SET @saved_cs_client = @@character_set_client;" + //and version dependent set queries e.g. "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;" + if (preg_match('/^[\s\t]*(?:\/\*!\d+)?[\s\t]*SET[\s\t]*@.+;/', $line)) { + $setQuery = trim($line); + if (!in_array($setQuery, $this->setQueries)) { + Log::info("FIRST CHUNK SET QUERY " . Log::v2str($setQuery), Log::LV_DEBUG); + $this->setQueries[] = $setQuery; + } + } + + if ($line === self::TABLE_CREATION_END_MARKER) { + Log::info("DATABASE CHUNK: CREATION TABLE MARKER FOUND"); + $skipChunkTimeoutCheck = false; + continue; + } + } + + $query .= $line; + if (preg_match('/' . preg_quote($delimiter, '/') . '\s*$/S', $line)) { + // Temp: Uncomment this to randomly kill the php db process to simulate real world hosts and verify system recovers properly + /* + $rand_no = rand(0, 500); + if (0 == $this->post['dbchunk_retry'] && 1 == $rand_no) { + Log::info("intentionally killing db chunk installation process"); + error_log('intentionally killing db chunk installation process'); + exit(1); + } + */ + + $this->writeQueryInDB($query); + $query = ''; + + $elapsed_time = (microtime(true) - $this->thread_start_time); + if (Log::isLevel(Log::LV_DEBUG)) { + Log::info("DATABASE CHUNK: Elapsed time: " . Log::v2str($elapsed_time), Log::LV_HARD_DEBUG); + if ($elapsed_time > DUPX_Constants::CHUNK_DBINSTALL_TIMEOUT_TIME) { + Log::info("DATABASE CHUNK: Breaking query loop.", Log::LV_DEBUG); + } else { + Log::info("DATABASE CHUNK: Not Breaking query loop", Log::LV_HARD_DEBUG); + } + } + + //Only stop first chunk if all CREATE queries have been run + if (!$skipChunkTimeoutCheck && $elapsed_time > DUPX_Constants::CHUNK_DBINSTALL_TIMEOUT_TIME) { + break; + } + } + } + + if (@mysqli_autocommit($this->dbh, true)) { + Log::info('Auto Commit set to true successfully'); + } else { + Log::info('Failed to set Auto Commit to true'); + } + + $query_offset = ftell($handle); + + $seek_tell_log_line = ( + file_exists(self::seekTellFilePath()) && + filesize(self::seekTellFilePath()) > 0 + ) ? ',' : ''; + + $seek_tell_log_line .= $this->post['pos'] . '-' . $query_offset; + file_put_contents(self::seekTellFilePath(), $seek_tell_log_line, FILE_APPEND); + + $this->post['progress'] = ceil($query_offset / $this->dbFileSize * 100); + $this->post['pos'] = $query_offset; + + if (feof($handle)) { + if ($this->seekIntegrityCheck()) { + Log::info('DATABASE CHUNK: DB install chunk process integrity check has been just passed successfully.', Log::LV_DETAILED); + $this->post['pass'] = 1; + $this->post['continue_chunking'] = false; + } else { + Log::info('DB install chunk process integrity check has been just failed.'); + $this->post['pass'] = 0; + $this->post['is_error'] = 1; + $this->post['error_msg'] = 'DB install chunk process integrity check has been just failed.'; + } + } else { + $this->post['pass'] = 0; + $this->post['continue_chunking'] = true; + } + } + Log::info("DATABASE CHUNK: End Query offset " . Log::v2str($query_offset), Log::LV_DETAILED); + + if ($this->post['pass']) { + Log::info('DATABASE CHUNK: This is last chunk', Log::LV_DETAILED); + } + + fclose($handle); + + Log::info("--------------------------------------"); + Log::info("** DATABASE CHUNK install end"); + Log::info("--------------------------------------"); + + ob_flush(); + flush(); + return true; + } + + protected function seekIntegrityCheck() + { + // ensure integrity + $seek_tell_log = file_get_contents(self::seekTellFilePath()); + $seek_tell_log_explodes = explode(',', $seek_tell_log); + $last_start = 0; + $last_end = 0; + foreach ($seek_tell_log_explodes as $seek_tell_log_explode) { + $temp_arr = explode('-', $seek_tell_log_explode); + if (is_array($temp_arr) && 2 == count($temp_arr)) { + $start = $temp_arr[0]; + $end = $temp_arr[1]; + if ($start != $last_end) { + return false; + } + if ($last_start > $end) { + return false; + } + + $last_start = $start; + $last_end = $end; + } else { + return false; + } + } + + if ($last_end != DUPX_Package::getSqlFileSize()) { + return false; + } + return true; + } + + /** + * Check if query should be skipped + * + * @param string $query query to check + * + * @return bool return true if query should be skipped + */ + protected static function skipQuery($query) + { + static $skipRegex = null; + + if (is_null($skipRegex)) { + $skipRegex = array(); + $skipTables = DUPX_DB_Tables::getInstance()->getTablesToSkip(); + $skipCreate = DUPX_DB_Tables::getInstance()->getTablesCreateSkip(); + + if (count($skipTables) > 0) { + $skipTables = array_map(function ($table) { + return preg_quote($table, '/'); + }, $skipTables); + + for ($i = 0; $i < ceil(count($skipTables) / self::TABLES_REGEX_CHUNK_SIZE); $i++) { + $subArray = array_slice($skipTables, $i * self::TABLES_REGEX_CHUNK_SIZE, self::TABLES_REGEX_CHUNK_SIZE); + + if (count($subArray) == 0) { + break; + } + + if (DUPX_ArchiveConfig::getInstance()->dbInfo->buildMode === self::BUILD_MODE_MYSQLDUMP) { + $skipRegex[] = '/^\s*(?:\/\*!\d+\s)?\s*(?:CREATE|INSERT|ALTER|LOCK)\s.*(?:TABLE|INTO).*[`\s](?-i)(' . + implode('|', $subArray) . ')(?i)[`\s]/im'; + } else { + $skipRegex[] = '/^\s*(?:CREATE|INSERT)\s.*(?:TABLE|INTO).*[`\s](?-i)(' . implode('|', $subArray) . ')(?i)[`\s]/im'; + } + } + } + + if (count($skipCreate) > 0) { + $skipCreate = array_map(function ($table) { + return preg_quote($table, '/'); + }, $skipCreate); + + for ($i = 0; $i < ceil(count($skipCreate) / self::TABLES_REGEX_CHUNK_SIZE); $i++) { + $subArray = array_slice($skipCreate, $i * self::TABLES_REGEX_CHUNK_SIZE, self::TABLES_REGEX_CHUNK_SIZE); + + if (count($subArray) == 0) { + break; + } + + $skipRegex[] = '/^\s*CREATE\s.*TABLE.*[`\s](?-i)(' . implode('|', $subArray) . ')(?i)[`\s]/im'; + } + } + + switch (count($skipRegex)) { + case 0: + $skipRegex = false; + Log::info('NO TABLE TO SKIP'); + break; + case 1: + $skipRegex = $skipRegex[0]; + // no break + default: + Log::info( + 'TABLES TO SKIP FOUND ' . Log::v2str( + array( + 'Extraction' => $skipTables, + 'Create only' => $skipCreate) + ) . "\n" + ); + Log::info('SKIP TABLE EXTRACTION REGEX ' . Log::v2str($skipRegex), Log::LV_DETAILED); + break; + } + } + + if (strlen($query) == 0) { + return true; + } elseif ($skipRegex === false) { + return false; + } elseif (is_array($skipRegex)) { + foreach ($skipRegex as $regex) { + if (preg_match($regex, $query) === 1) { + return true; + } + } + return false; + } else { + return (preg_match($skipRegex, $query) === 1); + } + } + + protected function getRowCountMisMatchTables() + { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + + $this->dbConnect(); + + if (is_null($this->dbh)) { + $errorMsg = "**ERROR** database DBH is null"; + $this->dbquery_errs++; + $nManager->addBothNextAndFinalReportNotice(array( + 'shortMsg' => $errorMsg, + 'level' => DUPX_NOTICE_ITEM::CRITICAL, + 'sections' => 'database' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'query-dbh-null'); + Log::info($errorMsg); + $nManager->saveNotices(); + return false; + } + + $tablesList = $archiveConfig->dbInfo->tablesList; + $tablePrefix = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_TABLE_PREFIX); + $skipTables = array( + $tablePrefix . "duplicator_packages", + DUPX_DB_Functions::getOptionsTableName(), + DUPX_DB_Functions::getPackagesTableName() + ); + $misMatchTables = array(); + foreach ($tablesList as $table => $tableInfo) { + if ($tableInfo->insertedRows === false) { + // if it is false it means that no precise count is available to perform the validity test. + continue; + } + $table = $archiveConfig->getTableWithNewPrefix($table); + if (in_array($table, $skipTables)) { + continue; + } + $sql = "SELECT count(*) as cnt FROM `" . mysqli_real_escape_string($this->dbh, $table) . "`"; + $result = DUPX_DB::mysqli_query($this->dbh, $sql); + if (false !== $result) { + $row = mysqli_fetch_assoc($result); + if ($tableInfo->insertedRows != ($row['cnt'])) { + $errMsg = 'DATABASE: table ' . Log::v2str($table) . ' row count mismatch; expected ' . Log::v2str($tableInfo->insertedRows) . ' in database' . Log::v2str($row['cnt']); + Log::info($errMsg); + $nManager->addBothNextAndFinalReportNotice(array( + 'shortMsg' => 'Database Table row count validation was failed', + 'level' => DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => $errMsg . "\n", + 'sections' => 'database' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'row-count-mismatch'); + $misMatchTables[] = $table; + } + } + } + return $misMatchTables; + } + + protected function deployDatabaseSingleMode() + { + Log::info("--------------------------------------"); + Log::info("** DATABASE SNGLE MODE install start"); + Log::info("--------------------------------------"); + $this->dbConnect(); + + $handle = fopen($this->sql_file_path, 'rb'); + if ($handle === false) { + return false; + } + + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + if (is_null($this->dbh)) { + $errorMsg = "**ERROR** database DBH is null"; + $this->dbquery_errs++; + $nManager->addNextStepNoticeMessage($errorMsg, DUPX_NOTICE_ITEM::CRITICAL, DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'query-dbh-null'); + $nManager->addFinalReportNotice(array( + 'shortMsg' => $errorMsg, + 'level' => DUPX_NOTICE_ITEM::CRITICAL, + 'sections' => 'database' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'query-dbh-null'); + Log::info($errorMsg); + $nManager->saveNotices(); + return; + } + + $query = ''; + $delimiter = ';'; + + while (($line = fgets($handle)) !== false) { + if (($res = self::isDelimiterLine($line)) !== false) { + $query = ''; + $delimiter = $this->post['delimiter'] = $res; + continue; + } + + $query .= $line; + + if (preg_match('/' . preg_quote($delimiter, '/') . '\s*$/S', $line)) { + $this->writeQueryInDB($query); + $query = ''; + } + } + + $nManager->saveNotices(); + } + + /** + * @param string $query + * + * @return boolean // false on failure + */ + protected function writeQueryInDB($query) + { + $query = trim($query); + if ($this->skipQuery($query)) { + return true; + } + + $return = false; + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + $query = $this->queryFixes->applyFixes($query); + $query = $this->dbUserMode->applyUsersFixes($query); + + if (strlen($query) == 0) { + return true; + } + + if (($queryLen = strlen($query)) > $this->dbvar_maxpacks) { + $errorMsg = "FAILED QUERY LIMIT [QLEN:" . $queryLen . "|MAX:{$this->dbvar_maxpacks}]\n\t[SQL=" . substr($query, 0, self::QUERY_ERROR_LOG_LEN) . "...]\n\n"; + $this->dbquery_errs++; + $nManager->addBothNextAndFinalReportNotice(array( + 'shortMsg' => 'Query size limit error (max limit ' . $this->dbvar_maxpacks . ')', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $errorMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE, + 'sections' => 'database', + 'faqLink' => array( + 'url' => InstallerLinkManager::getDocUrl( + 'how-to-fix-database-errors-or-general-warnings-on-the-install-report', + 'install', + 'DB error notice' + ), + 'label' => 'FAQ Link' + ) + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'query-size-limit-msg'); + Log::info($errorMsg); + $return = false; + } + + @mysqli_autocommit($this->dbh, false); + //Check to make sure the connection is alive + if (($query_res = DUPX_DB::mysqli_query($this->dbh, $query)) === false) { + $err = mysqli_error($this->dbh); + $errMsg = "DATABASE ERROR: '{$err}'\n\t[SQL=" . substr($query, 0, self::QUERY_ERROR_LOG_LEN) . "...]\n\n"; + $url = InstallerLinkManager::getDocUrl('how-to-fix-database-write-issues', 'install', 'DB error notice'); + + if (DUPX_U::contains($err, 'Unknown collation')) { + $nManager->addNextStepNotice(array( + 'shortMsg' => 'DATABASE ERROR: ' . $err, + 'level' => DUPX_NOTICE_ITEM::HARD_WARNING, + 'longMsg' => 'Unknown collation
        RECOMMENDATION: Try resolutions found at ' . $url, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'faqLink' => array( + 'url' => $url, + 'label' => 'FAQ Link' + ) + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'query-collation-write-msg'); + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'DATABASE ERROR: ' . $err, + 'level' => DUPX_NOTICE_ITEM::HARD_WARNING, + 'longMsg' => 'Unknown collation
        RECOMMENDATION: Try resolutions found at ' . $url . '
        ' . $errMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database', + 'faqLink' => array( + 'url' => $url, + 'label' => 'FAQ Link' + ) + )); + Log::info('RECOMMENDATION: Try resolutions found at ' . $url); + } elseif (!$this->skipErrorNotice($err, $query)) { + $nManager->addNextStepNotice(array( + 'shortMsg' => 'DATABASE ERROR: database error write', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $errMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'query-write-msg'); + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'DATABASE ERROR: ' . $err, + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $errMsg, + 'sections' => 'database' + )); + } + + $this->pingAndReconnect(); + $this->dbquery_errs++; + + //Buffer data to browser to keep connection open + $return = false; + } else { + if (!is_bool($query_res)) { + @mysqli_free_result($query_res); + } + $this->dbquery_rows++; + $return = true; + } + + @mysqli_commit($this->dbh); + @mysqli_autocommit($this->dbh, true); + return $return; + } + + private function getSQLSessionMode() + { + $this->dbConnect(); + $result = DUPX_DB::mysqli_query($this->dbh, "SELECT @@SESSION.sql_mode;"); + $row = mysqli_fetch_row($result); + $result->close(); + return is_array($row) ? $row[0] : ''; + } + + /** + * SQL MODE OVERVIEW: + * sql_mode can cause db create issues on some systems because the mode affects how data is inserted. + * Right now defaulting to NO_AUTO_VALUE_ON_ZERO (https://dev.mysql.com/doc/refman/5.5/en/sql-mode.html#sqlmode_no_auto_value_on_zero) + * has been the saftest option because the act of seting the sql_mode will nullify the MySQL Engine defaults which can be very problematic + * if the default is something such as STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_DATE. So the default behavior will be to always + * use NO_AUTO_VALUE_ON_ZERO. If the user insits on using the true system defaults they can use the Custom option. Note these values can + * be overriden by values set in the database.sql script such as: + * !40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' + * + * @throws Exception + */ + private function setSQLSessionMode() + { + $this->dbConnect(); + switch ($this->post['dbmysqlmode']) { + case 'DEFAULT': + $query = "SET SESSION sql_mode = 'NO_AUTO_VALUE_ON_ZERO'"; + break; + case 'DISABLE': + $query = "SET SESSION sql_mode = ''"; + break; + case 'CUSTOM': + $query = "SET SESSION sql_mode = '" . mysqli_real_escape_string($this->dbh, $this->post['dbmysqlmode_opts']) . "'"; + break; + default: + throw new Exception('Unknown dbmysqlmode option ' . $this->post['dbmysqlmode']); + } + + if (!$result = DUPX_DB::mysqli_query($this->dbh, $query)) { + $sql_error = mysqli_error($this->dbh); + $long = "WARNING: A custom sql_mode setting issue has been detected:\n{$sql_error}.
        "; + $long .= "The installation continue with the default MySQL Mode of the database.

        "; + $long .= "For more details visit: sql-mode documentation"; + DUPX_NOTICE_MANAGER::getInstance()->addBothNextAndFinalReportNotice(array( + 'shortMsg' => 'SET SQL MODE ERROR', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $long, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'drop-mysql-mode-set'); + } + } + + /** + * + * @param array $exclude tables to exclude + * @param bool|array $tables // if true drop all tables or table in list + * + * @return void + */ + private function dropTables($exclude = array(), $tables = true) + { + $logMsg = 'DROP' . ($tables === true ? ' ALL TABLES' : ' TABLES ' . Log::v2str($tables)); + if (count($exclude) > 0) { + $logMsg .= ' EXCEPT ' . Log::v2str($exclude); + } + Log::info($logMsg); + + $found_tables = array(); + + $sql = "SHOW FULL TABLES WHERE Table_Type != 'VIEW'"; + if (($result = DUPX_DB::mysqli_query($this->dbh, $sql)) === false) { + Log::error('QUERY ' . Log::v2str($sql) . 'ERROR: ' . mysqli_error($this->dbh)); + } + while ($row = mysqli_fetch_row($result)) { + if (in_array($row[0], $exclude)) { + continue; + } + + if (is_bool($tables) && $tables == false) { + continue; + } + + if (is_array($tables) && !in_array($row[0], $tables)) { + continue; + } + + $found_tables[] = $row[0]; + } + + if (!count($found_tables)) { + return; + } + + DUPX_DB::mysqli_query($this->dbh, "SET FOREIGN_KEY_CHECKS = 0;"); + foreach ($found_tables as $table_name) { + //Log::info('DROP TABLE ' . $table_name, Log::LV_DEBUG); + Log::info('DROP TABLE ' . $table_name); + $sql = "DROP TABLE `" . mysqli_real_escape_string($this->dbh, $this->post['dbname']) . "`.`" . mysqli_real_escape_string($this->dbh, $table_name) . "`"; + if (!$result = DUPX_DB::mysqli_query($this->dbh, $sql)) { + Log::error(sprintf(ERR_DROP_TABLE_TRYCLEAN, $table_name, $this->post['dbname'], mysqli_error($this->dbh))); + } + } + DUPX_DB::mysqli_query($this->dbh, "SET FOREIGN_KEY_CHECKS = 1;"); + + $this->drop_tbl_log = count($found_tables); + } + + protected function writeLog() + { + $this->dbConnect(); + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $paramsManager = PrmMng::getInstance(); + + Log::info("ERRORS FOUND:\t{$this->dbquery_errs}"); + Log::info("DROPPED TABLES:\t{$this->drop_tbl_log}"); + Log::info("RENAMED TABLES:\t{$this->rename_tbl_log}"); + Log::info("QUERIES RAN:\t{$this->dbquery_rows}\n"); + + $this->dbtable_rows = 1; + $this->dbtable_count = 0; + + Log::info("TABLES ROWS IN DATABASE AFTER EXTRACTION\n"); + if (($result = DUPX_DB::mysqli_query($this->dbh, "SHOW TABLES")) != false) { + while ($row = mysqli_fetch_array($result, MYSQLI_NUM)) { + $table_rows = DUPX_DB::countTableRows($this->dbh, $row[0]); + $this->dbtable_rows += $table_rows; + Log::info('TABLE ' . str_pad(Log::v2str($row[0]), 50, '_', STR_PAD_RIGHT) . '[ROWS:' . str_pad($table_rows, 6, " ", STR_PAD_LEFT) . ']'); + $this->dbtable_count++; + } + @mysqli_free_result($result); + } + + if ($this->dbtable_count == 0) { + $tablePrefix = $paramsManager->getValue(PrmMng::PARAM_DB_TABLE_PREFIX); + $longMsg = "You may have to manually run the installer-data.sql to validate data input. " . + "Also check to make sure your installer file is correct and the table prefix '" . $tablePrefix . " is correct for this particular version of WordPress."; + $nManager->addBothNextAndFinalReportNotice(array( + 'shortMsg' => 'No table in database', + 'level' => DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => $longMsg, + 'sections' => 'database' + )); + Log::info("NOTICE: " . $longMsg . "\n"); + } + + $finalReport = $paramsManager->getValue(PrmMng::PARAM_FINAL_REPORT_DATA); + $finalReport['extraction']['table_count'] = $this->dbtable_count; + $finalReport['extraction']['table_rows'] = $this->dbtable_rows; + $finalReport['extraction']['query_errs'] = $this->dbquery_errs; + $paramsManager->setValue(PrmMng::PARAM_FINAL_REPORT_DATA, $finalReport); + + $paramsManager->save(); + $nManager->saveNotices(); + } + + public function getResultData() + { + $result = array(); + $result['pass'] = $this->post['pass']; + $result['continue_chunking'] = $this->post['continue_chunking']; + if ($result['continue_chunking'] == 0 && $result['pass']) { + $result['perc'] = '100%'; + $result['queryOffset'] = 'Bytes processed ' . number_format($this->dbFileSize) . ' of ' . number_format($this->dbFileSize); + } else { + $result['perc'] = round(($this->post['pos'] * 100 / $this->dbFileSize), 2) . '%'; + $result['queryOffset'] = 'Bytes processed ' . number_format($this->post['pos']) . ' of ' . number_format($this->dbFileSize); + } + $result['is_error'] = $this->post['is_error']; + $result['error_msg'] = $this->post['error_msg']; + $result['table_count'] = $this->dbtable_count; + $result['table_rows'] = $this->dbtable_rows; + $result['query_errs'] = $this->dbquery_errs; + + return $result; + } + + /** + * @param $err string Error message + * @param $query string the SQL query + * + * @return bool if true will skip front-end notice of error message + */ + private function skipErrorNotice($err, $query) + { + return false; + } + + protected function firstOrNotChunking() + { + return $this->post['first_chunk'] || !PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_CHUNK); + } + + public function __destruct() + { + $this->dbClose(); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.extraction.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.extraction.php new file mode 100644 index 0000000..8f76c3b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.extraction.php @@ -0,0 +1,1196 @@ +initData(); + } + + /** + * Inizialize extraction data + * + * @return void + */ + public function initData() + { + // if data file exists load saved data + if (file_exists(self::extractionDataFilePath())) { + Log::info('LOAD EXTRACTION DATA FROM JSON', Log::LV_DETAILED); + if ($this->loadData() == false) { + throw new Exception('Can\'t load extraction data'); + } + } else { + Log::info('INIT EXTRACTION DATA', Log::LV_DETAILED); + $this->constructData(); + $this->saveData(); + $this->logStart(); + } + + if (strlen($relativeAbsPth = DUPX_ArchiveConfig::getInstance()->getRelativePathsInArchive('abs')) > 0) { + Log::info('SET RELATIVE ABSPATH: ' . Log::v2str($relativeAbsPth)); + SnapWP::setWpCoreRelativeAbsPath(DUPX_ArchiveConfig::getInstance()->getRelativePathsInArchive('abs')); + } + + $this->chunkStart = DUPX_U::getMicrotime(); + } + + /** + * Construct persistent data + * + * @return void + */ + private function constructData() + { + $paramsManager = PrmMng::getInstance(); + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + + $this->extractonStart = DUPX_U::getMicrotime(); + $this->zip_filetime = $paramsManager->getValue(PrmMng::PARAM_FILE_TIME); + $this->archive_action = $paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ACTION); + $this->archive_engine = $paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ENGINE); + $this->root_path = SnapIO::trailingslashit($paramsManager->getValue(PrmMng::PARAM_PATH_NEW)); + $this->archive_path = DUPX_Security::getInstance()->getArchivePath(); + $this->dawn_status = null; + $this->archive_items_count = $archiveConfig->totalArchiveItemsCount(); + $this->ajax1_error_level = error_reporting(); + error_reporting(E_ERROR); + $this->max_size_extract_at_a_time = DUPX_U::get_default_chunk_size_in_byte(MB_IN_BYTES * 2); + + if (self::ENGINE_DUP == $this->archive_engine || $this->archive_engine == self::ENGINE_MANUAL) { + $this->sub_folder_archive = ''; + } elseif (($this->sub_folder_archive = DUPX_U::findDupInstallerFolder(DUPX_Security::getInstance()->getArchivePath())) === false) { + Log::info("findDupInstallerFolder error; set no subfolder"); + // if not found set not subfolder + $this->sub_folder_archive = ''; + } + + $this->filters = FilterMng::getExtractFilters($this->sub_folder_archive); + $this->removeFilters = FilterMng::getRemoveFilters($this->filters); + } + + /** + * + * @return string + */ + private static function extractionDataFilePath() + { + static $path = null; + if (is_null($path)) { + $path = DUPX_INIT . '/dup-installer-extraction__' . DUPX_Package::getPackageHash() . '.json'; + } + return $path; + } + + /** + * + * @return boolean + */ + public function saveData() + { + if (($json = SnapJson::jsonEncodePPrint($this)) === false) { + Log::info('Can\'t encode json data'); + return false; + } + + if (@file_put_contents(self::extractionDataFilePath(), $json) === false) { + Log::info('Can\'t save extraction data file'); + return false; + } + + return true; + } + + /** + * + * @return boolean + */ + private function loadData() + { + if (!file_exists(self::extractionDataFilePath())) { + return false; + } + + if (($json = @file_get_contents(self::extractionDataFilePath())) === false) { + throw new Exception('Can\'t load extraction data file'); + } + + JsonSerialize::unserializeToObj($json, $this); + return true; + } + + /** + * reset extraction data + * + * @return boolean + */ + public static function resetData() + { + $result = true; + if (file_exists(self::extractionDataFilePath())) { + if (@unlink(self::extractionDataFilePath()) === false) { + throw new Exception('Can\'t delete extraction data file'); + } + } + return $result; + } + + /** + * Preliminary actions before the extraction. + * + * @return void + */ + protected function beforeExtraction() + { + if (!$this->isFirst()) { + return; + } + + Log::info('BEFORE EXTRACION ACTIONS'); + + if (DUPX_ArchiveConfig::getInstance()->exportOnlyDB) { + Log::info('EXPORT DB ONLY CHECKS'); + $this->exportOnlyDB(); + } + + DUPX_ServerConfig::reset($this->root_path); + + $remover = new RemoveFiles($this->removeFilters); + $remover->remove(); + + //throw new Exception('FORCE FAIL'); + + DUPX_U::maintenanceMode(true); + + $this->createFoldersAndPermissionPrepare(); + + if (!empty($this->sub_folder_archive)) { + Log::info("ARCHIVE dup-installer SUBFOLDER:" . Log::v2str($this->sub_folder_archive)); + } else { + Log::info("ARCHIVE dup-installer SUBFOLDER:" . Log::v2str($this->sub_folder_archive), Log::LV_DETAILED); + } + } + + /** + * Shows next step and final report notice files are found WP core folders + * + * @return void + */ + protected function configFilesCheckNotice() + { + //Test if config files are present in main folders + $folderList = array( + PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW) . "/wp-admin", + PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW) . "/wp-includes", + PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_CONTENT_NEW) + ); + + $configFiles = array( + 'php.ini', + '.user.ini', + '.htaccess' + ); + + $foundConfigFiles = array(); + + foreach ($folderList as $dir) { + foreach ($configFiles as $file) { + if (file_exists($dir . '/' . $file)) { + $foundConfigFiles[] = DUPX_U::esc_html('- ' . $dir . '/' . $file); + Log::info("WARNING: Found " . $file . " config file in " . $dir, Log::LV_DETAILED); + } + } + } + + if (!empty($foundConfigFiles)) { + $noticeManager = DUPX_NOTICE_MANAGER::getInstance(); + $msg = "Config files in WordPress main folders may cause problems with accessing the site after the installation." . + " The following config files were found:

        " . implode("
        ", $foundConfigFiles) . + "

        Please consider removing those files in case you have problems with your site after the installation."; + + $noticeManager->addBothNextAndFinalReportNotice(array( + 'shortMsg' => 'One or multiple config files were found in main WordPress folders', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'longMsg' => $msg, + 'sections' => 'general' + )); + $noticeManager->saveNotices(); + } + } + + /** + * Execute extraction + * + * @throws Exception + * + * @return void + */ + public function runExtraction() + { + $this->beforeExtraction(); + + switch ($this->archive_engine) { + case self::ENGINE_ZIP_CHUNK: + $this->runZipArchive(true); + break; + case self::ENGINE_ZIP: + $this->runZipArchive(false); + break; + case self::ENGINE_MANUAL: + break; + case self::ENGINE_ZIP_SHELL: + $this->runShellExec(); + break; + case self::ENGINE_DUP: + $this->runDupExtraction(); + break; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + } + + /** + * + * @return boolean + * + * @throws Exception + */ + protected function createFoldersAndPermissionPrepare() + { + Log::info("\n*** CREATE FOLDER AND PERMISSION PREPARE"); + + switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE)) { + case self::ENGINE_ZIP_CHUNK: + case self::ENGINE_ZIP: + case self::ENGINE_DUP: + $filters = $this->filters; + DUPX_Package::foreachDirCallback(function ($info) use ($filters) { + if ($filters->isFiltered($info->p)) { + return true; + } + + $destPath = DUPX_ArchiveConfig::getInstance()->destFileFromArchiveName($info->p); + + if (file_exists($destPath)) { + Log::info("PATH " . Log::v2str($destPath) . ' ALEADY EXISTS', Log::LV_DEBUG); + } else { + Log::info("PATH " . Log::v2str($destPath) . ' NOT EXISTS, CREATE IT', Log::LV_DEBUG); + if (SnapIO::mkdirP($destPath) === false) { + Log::info("ARCHIVE EXTRACION: can't create folder " . Log::v2str($destPath)); + } + } + + if (!SnapIO::dirAddFullPermsAndCheckResult($destPath)) { + Log::info("ARCHIVE EXTRACION: can't set writable " . Log::v2str($destPath)); + } + }); + break; + case self::ENGINE_ZIP_SHELL: + self::setPermsViaShell('u+rwx', 'u+rw'); + break; + case self::ENGINE_MANUAL: + break; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + + Log::info("FOLDER PREPARE DONE"); + return true; + } + + /** + * + * @return boolean + * @throws Exception + */ + public static function setFolderPermissionAfterExtraction() + { + $paramManager = PrmMng::getInstance(); + if (!$paramManager->getValue(PrmMng::PARAM_SET_DIR_PERMS)) { + Log::info('\n SKIP FOLDER PERMISSION AFTER EXTRACTION'); + return; + } + + Log::info("\n*** SET FOLDER PERMISSION AFTER EXTRACTION"); + + switch ($paramManager->getValue(PrmMng::PARAM_ARCHIVE_ENGINE)) { + case self::ENGINE_ZIP_CHUNK: + case self::ENGINE_ZIP: + case self::ENGINE_DUP: + DUPX_Package::foreachDirCallback(function ($info) { + $destPath = DUPX_ArchiveConfig::getInstance()->destFileFromArchiveName($info->p); + DUP_Extraction::setPermsFromParams($destPath); + }); + break; + case self::ENGINE_ZIP_SHELL: + $dirPerms = ( + $paramManager->getValue(PrmMng::PARAM_SET_DIR_PERMS) ? + $paramManager->getValue(PrmMng::PARAM_DIR_PERMS_VALUE) : + false); + $filePerms = ( + $paramManager->getValue(PrmMng::PARAM_SET_FILE_PERMS) ? + $paramManager->getValue(PrmMng::PARAM_FILE_PERMS_VALUE) : + false); + self::setPermsViaShell($dirPerms, $filePerms, true); + break; + case self::ENGINE_MANUAL: + break; + default: + throw new Exception('No valid engine '); + } + + Log::info("SET FOLDER PERMISSION DONE"); + return true; + } + + /** + * Extract package with duparchive + * + * @return void + */ + protected function runDupExtraction() + { + $paramsManager = PrmMng::getInstance(); + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + SnapLog::init(Log::getLogFilePath()); + SnapLog::$logHandle = Log::getFileHandle(); + + $params = array( + 'action' => $this->isFirst() ? 'start_expand' : 'expand', + 'archive_filepath' => DUPX_Security::getInstance()->getArchivePath(), + 'restore_directory' => $paramsManager->getValue(PrmMng::PARAM_PATH_NEW), + 'worker_time' => DUPX_Constants::CHUNK_EXTRACTION_TIMEOUT_TIME_ZIP, + 'filtered_directories' => $this->filters->getDirs(), + 'filtered_files' => $this->filters->getFiles(), + 'excludedDirWithoutChilds' => $this->filters->getDirsWithoutChilds(), + 'includeFiles' => array(), // ignore filtered + 'file_renames' => array(), + 'file_mode_override' => ( + $paramsManager->getValue(PrmMng::PARAM_SET_FILE_PERMS) ? + $paramsManager->getValue(PrmMng::PARAM_FILE_PERMS_VALUE) : + -1), + 'includedFiles' => array(), + 'dir_mode_override' => 'u+rwx', + 'keep_file_time' => ($paramsManager->getValue(PrmMng::PARAM_FILE_TIME) == 'original') ? true : false + ); + + $params['filtered_files'][] = DupArchive::INDEX_FILE_NAME; + if (!file_exists(DUPX_Package::getSqlFilePath())) { + Log::info('SQL FILE NOT FOUND SO ADD TO EXTRACTION'); + $params['includedFiles'][] = DUPX_Package::getSqlFilePathInArchive(); + $params['fileRenames'][DUPX_Package::getSqlFilePathInArchive()] = DUPX_Package::getSqlFilePath(); + } + + $offset = $this->isFirst() ? 0 : $this->dawn_status->archive_offset; + Log::info("ARCHIVE OFFSET " . $offset); + + $daws = new Daws(); + $daws->setFailureCallBack(function ($failure) { + DUP_Extraction::reportExtractionNotices($failure->subject, $failure->description); + }); + $dupResult = $daws->processRequest($params); + $this->dawn_status = $dupResult->status; + $nManager->saveNotices(); + } + + /** + * extract package with ziparchive + * + * @param bool $chunk false no chunk system + * + * @return void + * + * @throws Exception + */ + protected function runZipArchive($chunk = true) + { + if (!class_exists('ZipArchive')) { + Log::info("ERROR: Stopping install process. " . + "Trying to extract without ZipArchive module installed. " . + "Please use the 'Manual Archive Extraction' mode to extract zip file."); + Log::error(ERR_ZIPARCHIVE); + } + + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + $dupInstallerZipPath = ltrim($this->sub_folder_archive . '/' . self::DUP_FOLDER_NAME, '/'); + + $zip = new ZipArchive(); + $time_over = false; + + Log::info("ARCHIVE OFFSET " . Log::v2str($this->archive_offset)); + Log::info('DUP INSTALLER ARCHIVE PATH:"' . $dupInstallerZipPath . '"', Log::LV_DETAILED); + + if ($zip->open($this->archive_path) !== true) { + $faqURL = InstallerLinkManager::getDocUrl('how-to-fix-installer-archive-extraction-issues', 'install'); + $zip_err_msg = ERR_ZIPOPEN; + $zip_err_msg .= '

        To resolve error see ' . + DUPX_Constants::FAQ_URL . "how-to-fix-installer-archive-extraction-issues/"; + Log::info($zip_err_msg); + throw new Exception("Couldn't open zip archive."); + } + + $this->num_files = $zip->numFiles; + $num_files_minus_1 = $this->num_files - 1; + + $extracted_size = 0; + + LogHandler::setMode(LogHandler::MODE_VAR, false, false); + + // Main chunk + do { + $extract_filename = null; + + $no_of_files_in_micro_chunk = 0; + $size_in_micro_chunk = 0; + do { + //rsr uncomment if debugging Log::info("c ao " . $this->archive_offset); + $stat_data = $zip->statIndex($this->archive_offset); + $filename = $stat_data['name']; + + if ($this->filters->isFiltered($filename)) { + if (Log::isLevel(Log::LV_DETAILED)) { + // optimization + Log::info("FILE EXTRACTION SKIP: " . Log::v2str($filename), Log::LV_DETAILED); + } + } else { + $extract_filename = $filename; + $size_in_micro_chunk += $stat_data['size']; + $no_of_files_in_micro_chunk++; + } + + $this->archive_offset++; + } while ( + $this->archive_offset < $num_files_minus_1 && + $no_of_files_in_micro_chunk < 1 && + $size_in_micro_chunk < $this->max_size_extract_at_a_time + ); + + if (!empty($extract_filename)) { + // skip dup-installer folder. Alrady extracted in bootstrap + if ( + (strpos($extract_filename, $dupInstallerZipPath) === 0) || + (strlen($this->sub_folder_archive) > 0 && strpos($extract_filename, $this->sub_folder_archive) !== 0) + ) { + Log::info("SKIPPING NOT IN ZIPATH:\"" . Log::v2str($extract_filename) . "\"", Log::LV_DETAILED); + } else { + $destFilePath = $archiveConfig->destFileFromArchiveName($extract_filename); + $this->extractFile($zip, $extract_filename, $destFilePath); + } + } + + $extracted_size += $size_in_micro_chunk; + if ($this->archive_offset == $this->num_files - 1) { + if (!empty($this->sub_folder_archive)) { + DUPX_U::moveUpfromSubFolder($this->root_path . $this->sub_folder_archive, true); + } + + Log::info("FILE EXTRACTION: done processing last file in list of {$this->num_files}"); + $this->chunkedExtractionCompleted = true; + break; + } + + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_ZIP_THROTTLING)) { + for ($i = 0; $i < self::ZIP_THROTTLING_ITERATIONS; $i++) { + usleep(self::ZIP_THROTTLING_SLEEP_TIME); + } + } + + if (($time_over = $chunk && (DUPX_U::getMicrotime() - $this->chunkStart) > DUPX_Constants::CHUNK_EXTRACTION_TIMEOUT_TIME_ZIP)) { + Log::info("TIME IS OVER - CHUNK", 2); + } + } while ($this->archive_offset < $num_files_minus_1 && !$time_over); + + // set handler as default + LogHandler::setMode(); + $zip->close(); + + $chunk_time = DUPX_U::getMicrotime() - $this->chunkStart; + + $chunk_extract_rate = $extracted_size / $chunk_time; + $this->zip_arc_chunks_extract_rates[] = $chunk_extract_rate; + $zip_arc_chunks_extract_rates = $this->zip_arc_chunks_extract_rates; + $average_extract_rate = array_sum($zip_arc_chunks_extract_rates) / count($zip_arc_chunks_extract_rates); + + $expected_extract_time = $average_extract_rate > 0 ? DUPX_Conf_Utils::archiveSize() / $average_extract_rate : 0; + + /* + Log::info("Expected total archive extract time: {$expected_extract_time}"); + Log::info("Total extraction elapsed time until now: {$expected_extract_time}"); + */ + + $elapsed_time = DUPX_U::getMicrotime() - $this->extractonStart; + $max_no_of_notices = count($GLOBALS['ZIP_ARC_CHUNK_EXTRACT_NOTICES']) - 1; + + $zip_arc_chunk_extract_disp_notice_after = $GLOBALS['ZIP_ARC_CHUNK_EXTRACT_DISP_NOTICE_AFTER']; + $zip_arc_chunk_extract_disp_notice_min_expected_extract_time = $GLOBALS['ZIP_ARC_CHUNK_EXTRACT_DISP_NOTICE_MIN_EXPECTED_EXTRACT_TIME']; + $zip_arc_chunk_extract_disp_next_notice_interval = $GLOBALS['ZIP_ARC_CHUNK_EXTRACT_DISP_NEXT_NOTICE_INTERVAL']; + + if ($this->zip_arc_chunk_notice_no < 0) { // -1 + if ( + ( + $elapsed_time > $zip_arc_chunk_extract_disp_notice_after && + $expected_extract_time > $zip_arc_chunk_extract_disp_notice_min_expected_extract_time + ) || + $elapsed_time > $zip_arc_chunk_extract_disp_notice_min_expected_extract_time + ) { + $this->zip_arc_chunk_notice_no++; + $this->zip_arc_chunk_notice_change_last_time = DUPX_U::getMicrotime(); + } + } elseif ($this->zip_arc_chunk_notice_no > 0 && $this->zip_arc_chunk_notice_no < $max_no_of_notices) { + $interval_after_last_notice = DUPX_U::getMicrotime() - $this->zip_arc_chunk_notice_change_last_time; + Log::info("Interval after last notice: {$interval_after_last_notice}"); + if ($interval_after_last_notice > $zip_arc_chunk_extract_disp_next_notice_interval) { + $this->zip_arc_chunk_notice_no++; + $this->zip_arc_chunk_notice_change_last_time = DUPX_U::getMicrotime(); + } + } + + $nManager->saveNotices(); + + //rsr todo uncomment when debugging Log::info("Zip archive chunk notice no.: {$this->zip_arc_chunk_notice_no}"); + } + + /** + * Set files permission + * + * @param string $path Path + * @param boolean $setDir Folders permissions + * @param boolean $setFile Files permissions + * + * @return boolean // false if fail, if file don't exists retur true + */ + public static function setPermsFromParams($path, $setDir = true, $setFile = true) + { + static $permsSettings = null; + + if (is_null($permsSettings)) { + $paramsManager = PrmMng::getInstance(); + + $permsSettings = array( + 'fileSet' => $paramsManager->getValue(PrmMng::PARAM_SET_FILE_PERMS), + 'fileVal' => $paramsManager->getValue(PrmMng::PARAM_FILE_PERMS_VALUE), + 'dirSet' => $paramsManager->getValue(PrmMng::PARAM_SET_DIR_PERMS), + 'dirVal' => $paramsManager->getValue(PrmMng::PARAM_DIR_PERMS_VALUE) + ); + } + + if (!file_exists($path)) { + return true; + } + + if (is_file($path) || is_link($path)) { + if ($setFile && $permsSettings['fileSet']) { + if (!SnapIO::chmod($path, $permsSettings['fileVal'])) { + Log::info('CHMOD FAIL: ' . $path . ' PERMS: ' . SnapIO::permsToString($permsSettings['fileVal'])); + return false; + } + } + } else { + if ($setDir && $permsSettings['dirSet']) { + if (!SnapIO::chmod($path, $permsSettings['dirVal'])) { + Log::info('CHMOD FAIL: ' . $path . ' PERMS: ' . SnapIO::permsToString($permsSettings['dirVal'])); + return false; + } + } + } + + return true; + } + + /** + * Extract file from zip archive + * + * @param ZipArchive $zipObj Zip archive object + * @param string $zipFilename File name + * @param string $newFilePath Path to extract + * + * @return void + */ + protected function extractFile(ZipArchive $zipObj, $zipFilename, $newFilePath) + { + try { + //rsr uncomment if debugging Log::info("Attempting to extract {$zipFilename}. Time:". time()); + $error = false; + + // IF EXIST SET READ WRITE PERMISSION + if (is_file($newFilePath) || is_link($newFilePath)) { + SnapIO::chmod($newFilePath, 'u+rw'); + } elseif (is_dir($newFilePath)) { + SnapIO::chmod($newFilePath, 'u+rwx'); + } + + if ($this->root_path . ltrim($zipFilename, '\\/') === $newFilePath) { + if (Log::isLevel(Log::LV_DEBUG)) { + Log::info('EXTRACT FILE [' . $zipFilename . '] TO [' . $newFilePath . ']', Log::LV_DEBUG); + } + if (!$zipObj->extractTo($this->root_path, $zipFilename)) { + $error = true; + } + } else { + if (Log::isLevel(Log::LV_DEBUG)) { + Log::info('CUSTOM EXTRACT FILE [' . $zipFilename . '] TO [' . $newFilePath . ']', Log::LV_DEBUG); + } + if (substr($zipFilename, -1) === '/') { + SnapIO::mkdirP(dirname($newFilePath)); + } else { + if (($destStream = fopen($newFilePath, 'w')) === false) { + if (!file_exists(dirname($newFilePath))) { + SnapIO::mkdirP(dirname($newFilePath)); + if (($destStream = fopen($newFilePath, 'w')) === false) { + $error = true; + } + } else { + $error = true; + } + } + + if ($error || ($sourceStream = $zipObj->getStream($zipFilename)) === false) { + $error = true; + } else { + while (!feof($sourceStream)) { + fwrite($destStream, fread($sourceStream, 1048576)); // 1M + } + + fclose($sourceStream); + fclose($destStream); + } + } + } + + if ($error) { + self::reportExtractionNotices($zipFilename, LogHandler::getVarLogClean()); + } else { + if (Log::isLevel(Log::LV_HARD_DEBUG)) { + Log::info("FILE EXTRACTION DONE: " . Log::v2str($zipFilename), Log::LV_HARD_DEBUG); + } + // SET ONLY FILES + self::setPermsFromParams($newFilePath, false); + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_FILE_TIME) == 'current') { + touch($newFilePath, time()); + } + } + } catch (Exception $ex) { + self::reportExtractionNotices($zipFilename, $ex->getMessage()); + } + } + + /** + * + * @param string $fileName package relative path + * @param string $errorMessage error message + * + * @return void + */ + protected static function reportExtractionNotices($fileName, $errorMessage) + { + if (DUPX_Custom_Host_Manager::getInstance()->skipWarningExtractionForManaged($fileName)) { + // @todo skip warning for managed hostiong (it's a temp solution) + return; + } + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + if (SnapWP::isWpCore($fileName, SnapWP::PATH_RELATIVE)) { + Log::info("FILE CORE EXTRACTION ERROR: {$fileName} | MSG:" . $errorMessage); + $shortMsg = 'Can\'t extract wp core files'; + $finalShortMsg = 'Wp core files not extracted'; + $errLevel = DUPX_NOTICE_ITEM::CRITICAL; + $idManager = 'wp-extract-error-file-core'; + } else { + Log::info("FILE EXTRACTION ERROR: {$fileName} | MSG:" . $errorMessage); + $shortMsg = 'Can\'t extract files'; + $finalShortMsg = 'Files not extracted'; + $errLevel = DUPX_NOTICE_ITEM::SOFT_WARNING; + $idManager = 'wp-extract-error-file-no-core'; + } + + $longMsg = 'FILE: ' . htmlspecialchars($fileName) . '
        Message: ' . htmlspecialchars($errorMessage) . '

        '; + + $nManager->addNextStepNotice(array( + 'shortMsg' => $shortMsg, + 'longMsg' => $longMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'level' => $errLevel + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager); + $nManager->addFinalReportNotice(array( + 'shortMsg' => $finalShortMsg, + 'longMsg' => $longMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'level' => $errLevel, + 'sections' => array('files'), + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $idManager); + } + + /** + * Export db only + * + * @return void + */ + protected function exportOnlyDB() + { + if ($this->archive_engine == self::ENGINE_MANUAL || $this->archive_engine == self::ENGINE_DUP) { + $sql_file_path = DUPX_Package::getSqlFilePath(); + if (!file_exists(DUPX_Package::getWpconfigArkPath()) && !file_exists($sql_file_path)) { + Log::error(ERR_ZIPMANUAL); + } + } else { + if (!is_readable("{$this->archive_path}")) { + Log::error("archive file path:
        " . ERR_ZIPNOTFOUND); + } + } + } + + /** + * Write extraction log header + * + * @return void + */ + protected function logStart() + { + $paramsManager = PrmMng::getInstance(); + + Log::info("********************************************************************************"); + Log::info('* DUPLICATOR LITE: Install-Log'); + Log::info('* STEP-1 START @ ' . @date('h:i:s')); + Log::info('* NOTICE: Do NOT post to public sites or forums!!'); + Log::info("********************************************************************************"); + + $labelPadSize = 20; + Log::info("USER INPUTS"); + Log::info(str_pad('INSTALL TYPE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . DUPX_InstallerState::installTypeToString()); + Log::info(str_pad('BLOG NAME', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_BLOGNAME))); + + Log::info(str_pad('HOME URL NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_URL_NEW))); + Log::info(str_pad('SITE URL NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_SITE_URL))); + Log::info(str_pad('CONTENT URL NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_URL_CONTENT_NEW))); + Log::info(str_pad('UPLOAD URL NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_URL_UPLOADS_NEW))); + Log::info(str_pad('PLUGINS URL NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_URL_PLUGINS_NEW))); + Log::info( + str_pad('MUPLUGINS URL NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_URL_MUPLUGINS_NEW)) + ); + + Log::info(str_pad('HOME PATH NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_PATH_NEW))); + Log::info(str_pad('SITE PATH NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW))); + Log::info(str_pad('CONTENT PATH NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW))); + Log::info(str_pad('UPLOAD PATH NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_NEW))); + Log::info(str_pad('PLUGINS PATH NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW))); + Log::info( + str_pad('MUPLUGINS PATH NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW)) + ); + + Log::info(str_pad('ARCHIVE ACTION', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ACTION))); + Log::info( + str_pad( + 'SKIP WP FILES', + $labelPadSize, + '_', + STR_PAD_RIGHT + ) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) + ); + Log::info(str_pad('ARCHIVE ENGINE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ENGINE))); + Log::info(str_pad('SET DIR PERMS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_SET_DIR_PERMS))); + Log::info( + str_pad( + 'DIR PERMS VALUE', + $labelPadSize, + '_', + STR_PAD_RIGHT + ) . ': ' . SnapIO::permsToString($paramsManager->getValue(PrmMng::PARAM_DIR_PERMS_VALUE)) + ); + Log::info(str_pad('SET FILE PERMS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_SET_FILE_PERMS))); + Log::info( + str_pad( + 'FILE PERMS VALUE', + $labelPadSize, + '_', + STR_PAD_RIGHT + ) . ': ' . SnapIO::permsToString($paramsManager->getValue(PrmMng::PARAM_FILE_PERMS_VALUE)) + ); + Log::info(str_pad('SAFE MODE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_SAFE_MODE))); + Log::info(str_pad('LOGGING', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_LOGGING))); + Log::info(str_pad('ZIP THROTTLING', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_ZIP_THROTTLING))); + Log::info(str_pad('WP CONFIG', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_WP_CONFIG))); + Log::info(str_pad('HTACCESS CONFIG', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_HTACCESS_CONFIG))); + Log::info(str_pad('OTHER CONFIG', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_OTHER_CONFIG))); + Log::info(str_pad('FILE TIME', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_FILE_TIME))); + Log::info("********************************************************************************\n"); + Log::info('REMOVE FILTERS'); + Log::incIndent(); + foreach ($this->removeFilters->getDirs() as $path) { + Log::info('DIR : ' . Log::v2str($path)); + } + foreach ($this->removeFilters->getFiles() as $path) { + Log::info('FILE: ' . Log::v2str($path)); + } + foreach ($this->removeFilters->getDirsWithoutChilds() as $path) { + Log::info('DIRS WITHOUT CHILDS: ' . Log::v2str($path)); + } + Log::resetIndent(); + Log::info('EXTRACTION FILTERS'); + Log::incIndent(); + foreach ($this->filters->getDirs() as $path) { + Log::info('DIR : ' . Log::v2str($path)); + } + foreach ($this->filters->getFiles() as $path) { + Log::info('FILE: ' . Log::v2str($path)); + } + foreach ($this->filters->getDirsWithoutChilds() as $path) { + Log::info('DIR WITHOUT CHILDS: ' . Log::v2str($path)); + } + Log::resetIndent(); + Log::info("--------------------------------------\n"); + + switch ($this->archive_engine) { + case self::ENGINE_ZIP_CHUNK: + Log::info("\nEXTRACTION: ZIP CHUNKING >>> START"); + break; + case self::ENGINE_ZIP: + Log::info("\nEXTRACTION: ZIP STANDARD >>> START"); + break; + case self::ENGINE_MANUAL: + Log::info("\nEXTRACTION: MANUAL MODE >>> START"); + break; + case self::ENGINE_ZIP_SHELL: + Log::info("\nEXTRACTION: ZIP SHELL >>> START"); + break; + case self::ENGINE_DUP: + Log::info("\nEXTRACTION: DUP ARCHIVE >>> START"); + break; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + } + + /** + * Write log extraction end + * + * @return void + */ + protected function logComplete() + { + + switch ($this->archive_engine) { + case self::ENGINE_ZIP_CHUNK: + Log::info("\nEXTRACTION: ZIP CHUNKING >>> DONE"); + break; + case self::ENGINE_ZIP: + Log::info("\nEXTRACTION: ZIP STANDARD >>> DONE"); + break; + case self::ENGINE_MANUAL: + Log::info("\nEXTRACTION: MANUAL MODE >>> DONE"); + break; + case self::ENGINE_ZIP_SHELL: + Log::info("\nEXTRACTION: ZIP SHELL >>> DONE"); + break; + case self::ENGINE_DUP: + $criticalPresent = false; + if (count($this->dawn_status->failures) > 0) { + $log = ''; + foreach ($this->dawn_status->failures as $failure) { + if ($failure->isCritical) { + $log .= 'DUP EXTRACTION CRITICAL ERROR ' . $failure->description; + $criticalPresent = true; + } + } + if (!empty($log)) { + Log::info($log); + } + } + if ($criticalPresent) { + throw new Exception('Critical Errors present so stopping install.'); + } + + Log::info("\n\nEXTRACTION: DUP ARCHIVE >>> DONE"); + break; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + } + + /** + * Extract zip archive via shell + * + * @return void + */ + protected function runShellExec() + { + $command = escapeshellcmd(DUPX_Server::get_unzip_filepath()) . + " -o -qq " . escapeshellarg($this->archive_path) . " -d " . + escapeshellarg($this->root_path) . " 2>&1"; + if ($this->zip_filetime == 'original') { + Log::info("\nShell Exec Current does not support orginal file timestamp please use ZipArchive"); + } + + Log::info('SHELL COMMAND: ' . Log::v2str($command)); + $stderr = shell_exec($command); + if ($stderr != '') { + $faqUrl = InstallerLinkManager::getDocUrl('how-to-fix-installer-archive-extraction-issues', 'install', 'shell exec error'); + $zip_err_msg = ERR_SHELLEXEC_ZIPOPEN . ": $stderr"; + $zip_err_msg .= '

        To resolve error see ' + . DUPX_Constants::FAQ_URL . "how-to-fix-installer-archive-extraction-issues"; + Log::error($zip_err_msg); + } + } + + /** + * Set file permission via shell + * + * @param boolean|string $dirPerm folders permissions + * @param boolean|string $filePerm files permsission + * @param boolean $excludeDupInit if true dont set permsission on dup folder + * + * @return void + */ + protected static function setPermsViaShell($dirPerm = false, $filePerm = false, $excludeDupInit = false) + { + $rootPath = PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW); + $exludeDupFolder = ($excludeDupInit ? "! -path " . escapeshellarg(DUPX_INIT . '*') . " " : ''); + + if ($filePerm !== false) { + $command = "find " . escapeshellarg($rootPath) . " -type d " . $exludeDupFolder . "-exec chmod " . SnapIO::permsToString($dirPerm) . " {} \;"; + Log::info('SHELL COMMAND: ' . Log::v2str($command)); + shell_exec($command); + } + + if ($dirPerm !== false) { + $command = "find " . escapeshellarg($rootPath) . " -type f " . $exludeDupFolder . "-exec chmod " . SnapIO::permsToString($filePerm) . " {} \;"; + Log::info('SHELL COMMAND: ' . Log::v2str($command)); + shell_exec($command); + } + } + + /** + * + * @return string + */ + public static function getInitialFileProcessedString() + { + return 'Files processed: 0 of ' . number_format(DUPX_ArchiveConfig::getInstance()->totalArchiveItemsCount()); + } + + /** + * Get extraction result + * + * @param boolean $complete true if extraction is complate false if chunk is complete + * + * @return array + */ + protected function getResultExtraction($complete = false) + { + $result = array( + 'pass' => 0, + 'processedFiles' => '', + 'perc' => '' + ); + + if ($complete) { + $result['pass'] = 1; + $result['perc'] = '100%'; + switch ($this->archive_engine) { + case self::ENGINE_ZIP_CHUNK: + case self::ENGINE_ZIP: + case self::ENGINE_ZIP_SHELL: + case self::ENGINE_DUP: + $result['processedFiles'] = 'Files processed: ' . number_format($this->archive_items_count) . + ' of ' . number_format($this->archive_items_count); + break; + case self::ENGINE_MANUAL: + break; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + + $deltaTime = DUPX_U::elapsedTime(DUPX_U::getMicrotime(), $this->extractonStart); + Log::info("\nEXTRACTION COMPLETE @ " . @date('h:i:s') . " - RUNTIME: {$deltaTime} - " . $result['processedFiles']); + } else { + $result['pass'] = -1; + switch ($this->archive_engine) { + case self::ENGINE_ZIP_CHUNK: + case self::ENGINE_ZIP: + case self::ENGINE_ZIP_SHELL: + $result['processedFiles'] = 'Files processed: ' . number_format(min($this->archive_offset, $this->archive_items_count)) . + ' of ' . number_format($this->archive_items_count); + $result['perc'] = min(100, round(($this->archive_offset * 100 / $this->archive_items_count), 2)) . '%'; + break; + case self::ENGINE_DUP: + $result['processedFiles'] = 'Files processed: ' . number_format(min($this->dawn_status->file_index, $this->archive_items_count)) . + ' of ' . number_format($this->archive_items_count); + $result['perc'] = min(100, round(($this->dawn_status->file_index * 100 / $this->archive_items_count), 2)) . '%'; + break; + case self::ENGINE_MANUAL: + break; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + + $deltaTime = DUPX_U::elapsedTime(DUPX_U::getMicrotime(), $this->chunkStart); + Log::info("CHUNK COMPLETE - RUNTIME: {$deltaTime} - " . $result['processedFiles']); + } + return $result; + } + + /** + * End extraction + * + * @return array + */ + protected function finishFullExtraction() + { + $this->configFilesCheckNotice(); + $this->logComplete(); + return $this->getResultExtraction(true); + } + + /** + * End chunked extraction + * + * @return array + */ + protected function finishChunkExtraction() + { + $this->saveData(); + return $this->getResultExtraction(false); + } + + /** + * Finish extraction process + * + * @return array + */ + public function finishExtraction() + { + $complete = false; + + switch ($this->archive_engine) { + case self::ENGINE_ZIP_CHUNK: + $complete = $this->chunkedExtractionCompleted; + break; + case self::ENGINE_DUP: + $complete = $this->dawn_status->is_done; + break; + case self::ENGINE_ZIP: + case self::ENGINE_MANUAL: + case self::ENGINE_ZIP_SHELL: + $complete = true; + break; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + + if ($complete) { + return $this->finishFullExtraction(); + } else { + return $this->finishChunkExtraction(); + } + } + + /** + * + * @return bool + */ + protected function isFirst() + { + switch ($this->archive_engine) { + case self::ENGINE_ZIP_CHUNK: + return $this->archive_offset == 0 && $this->archive_engine == self::ENGINE_ZIP_CHUNK; + case self::ENGINE_DUP: + return is_null($this->dawn_status); + case self::ENGINE_ZIP: + case self::ENGINE_MANUAL: + case self::ENGINE_ZIP_SHELL: + return true; + default: + throw new Exception('No valid engine ' . $this->archive_engine); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.params.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.params.php new file mode 100644 index 0000000..8a5f5ef --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.params.php @@ -0,0 +1,442 @@ +setValueFromInput(PrmMng::PARAM_CTRL_ACTION, ParamForm::INPUT_REQUEST); + $paramsManager->setValueFromInput(PrmMng::PARAM_STEP_ACTION, ParamForm::INPUT_REQUEST); + return true; + } + + /** + * + * @return boolean + */ + public static function setParamsStep0() + { + Log::info('CTRL PARAMS S0', Log::LV_DETAILED); + Log::info('REQUEST: ' . Log::v2str($_REQUEST), Log::LV_HARD_DEBUG); + $paramsManager = PrmMng::getInstance(); + + DUPX_ArchiveConfig::getInstance()->setNewPathsAndUrlParamsByMainNew(); + DUPX_Custom_Host_Manager::getInstance()->setManagedHostParams(); + + $paramsManager->save(); + return self::$paramsValidated; + } + + /** + * Set param email + * + * @return bool + */ + public static function setParamEmail() + { + Log::info('CTRL PARAM EMAIL', Log::LV_DETAILED); + + PrmMng::getInstance()->setValueFromInput(PrmMng::PARAM_SUBSCRIBE_EMAIL, ParamForm::INPUT_REQUEST); + $resposne = DUPX_HTTP::post(DUPX_Constants::URL_SUBSCRIBE, array( + 'email' => PrmMng::getInstance()->getValue(PrmMng::PARAM_SUBSCRIBE_EMAIL) + )); + + Log::infoObject('response', $resposne); + + PrmMng::getInstance()->save(); + return true; + } + + /** + * + * @return boolean + */ + public static function setParamsStep1() + { + Log::info('CTRL PARAMS S1', Log::LV_DETAILED); + Log::info('REQUEST: ' . Log::v2str($_REQUEST), Log::LV_HARD_DEBUG); + $archive_config = DUPX_ArchiveConfig::getInstance(); + $paramsManager = PrmMng::getInstance(); + $paramsManager->setValueFromInput(PrmMng::PARAM_LOGGING, ParamForm::INPUT_POST); + Log::setLogLevel(); + + $readParamsList = array( + PrmMng::PARAM_INST_TYPE, + PrmMng::PARAM_PATH_NEW, + PrmMng::PARAM_URL_NEW, + PrmMng::PARAM_PATH_WP_CORE_NEW, + PrmMng::PARAM_SITE_URL, + PrmMng::PARAM_PATH_CONTENT_NEW, + PrmMng::PARAM_URL_CONTENT_NEW, + PrmMng::PARAM_PATH_UPLOADS_NEW, + PrmMng::PARAM_URL_UPLOADS_NEW, + PrmMng::PARAM_PATH_PLUGINS_NEW, + PrmMng::PARAM_URL_PLUGINS_NEW, + PrmMng::PARAM_PATH_MUPLUGINS_NEW, + PrmMng::PARAM_URL_MUPLUGINS_NEW, + PrmMng::PARAM_ARCHIVE_ACTION, + PrmMng::PARAM_ARCHIVE_ENGINE, + PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES, + PrmMng::PARAM_DB_ENGINE, + PrmMng::PARAM_REPLACE_ENGINE, + PrmMng::PARAM_USERS_MODE, + PrmMng::PARAM_SET_FILE_PERMS, + PrmMng::PARAM_SET_DIR_PERMS, + PrmMng::PARAM_FILE_PERMS_VALUE, + PrmMng::PARAM_DIR_PERMS_VALUE, + PrmMng::PARAM_SAFE_MODE, + PrmMng::PARAM_WP_CONFIG, + PrmMng::PARAM_HTACCESS_CONFIG, + PrmMng::PARAM_OTHER_CONFIG, + PrmMng::PARAM_FILE_TIME, + PrmMng::PARAM_REMOVE_RENDUNDANT, + PrmMng::PARAM_BLOGNAME, + PrmMng::PARAM_ACCEPT_TERM_COND, + PrmMng::PARAM_ZIP_THROTTLING + ); + + foreach ($readParamsList as $cParam) { + if ($paramsManager->setValueFromInput($cParam, ParamForm::INPUT_POST, false, true) === false) { + self::$paramsValidated = false; + } + } + + $paramsManager->setValue(PrmMng::PARAM_REPLACE_ENGINE, ParamDescEngines::getReplaceEngineModeFromParams()); + $paramsManager->setValue(PrmMng::PARAM_DB_CHUNK, ParamDescEngines::getDbChunkFromParams()); + + self::setParamsDatabase(); + + if (self::$paramsValidated) { + self::resetUrlAndPathsFromOverwriteData(); + + Log::info('UPDATE PARAMS FROM SUBSITE ID', Log::LV_DEBUG); + Log::info('NETWORK INSTALL: false', Log::LV_DEBUG); + + // UPDATE ACTIVE PARAMS BY SUBSITE ID + $activePlugins = DUPX_Plugins_Manager::getInstance()->getDefaultActivePluginsList(); + $paramsManager->setValue(PrmMng::PARAM_PLUGINS, $activePlugins); + + // IF SAFE MODE DISABLE ALL PLUGINS + if ($paramsManager->getValue(PrmMng::PARAM_SAFE_MODE) > 0) { + $forceDisable = DUPX_Plugins_Manager::getInstance()->getAllPluginsSlugs(); + + // EXCLUDE DUPLICATOR PRO + if (($key = array_search(DUPX_Plugins_Manager::SLUG_DUPLICATOR_PRO, $forceDisable)) !== false) { + unset($forceDisable[$key]); + } + + $paramsManager->setValue(PrmMng::PARAM_FORCE_DIABLE_PLUGINS, $forceDisable); + } + } + + // reload state after new path and new url + DUPX_InstallerState::getInstance()->checkState(false, false); + $paramsManager->save(); + return self::$paramsValidated; + } + + /** + * + * @return boolean + */ + public static function setParamsAfterValidation() + { + Log::info("\nCTRL PARAMS AFTER VALIDATION"); + $paramsManager = PrmMng::getInstance(); + + $paramsManager->setValue(PrmMng::PARAM_WP_ADDON_SITES_PATHS, DUPX_Validation_test_addon_sites::getAddonsListsFolders()); + ParamDescDatabase::updateCharsetAndCollateByDatabaseSettings(); + + $configsChecks = DUPX_Validation_test_iswritable_configs::configsWritableChecks(); + + if ($configsChecks['wpconfig'] === false) { + Log::info("WP-CONFIG ISN\'T READABLE SO SET noting ON " . PrmMng::PARAM_WP_CONFIG . ' PARAM'); + $paramsManager->setValue(PrmMng::PARAM_WP_CONFIG, 'nothing'); + $paramsManager->setFormStatus(PrmMng::PARAM_WP_CONFIG, ParamForm::STATUS_INFO_ONLY); + + Log::info('SET AND DISABLE ALL DB PARAMS'); + $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + $paramsManager->setValue(PrmMng::PARAM_DB_HOST, $overwriteData['dbhost']); + $paramsManager->setFormStatus(PrmMng::PARAM_DB_HOST, ParamForm::STATUS_INFO_ONLY); + $paramsManager->setValue(PrmMng::PARAM_DB_NAME, $overwriteData['dbname']); + $paramsManager->setFormStatus(PrmMng::PARAM_DB_NAME, ParamForm::STATUS_INFO_ONLY); + $paramsManager->setValue(PrmMng::PARAM_DB_USER, $overwriteData['dbuser']); + $paramsManager->setFormStatus(PrmMng::PARAM_DB_USER, ParamForm::STATUS_INFO_ONLY); + $paramsManager->setValue(PrmMng::PARAM_DB_PASS, $overwriteData['dbpass']); + $paramsManager->setFormStatus(PrmMng::PARAM_DB_PASS, ParamForm::STATUS_INFO_ONLY); + $paramsManager->setValue(PrmMng::PARAM_DB_TABLE_PREFIX, $overwriteData['table_prefix']); + $paramsManager->setFormStatus(PrmMng::PARAM_DB_TABLE_PREFIX, ParamForm::STATUS_INFO_ONLY); + } + + if ($configsChecks['htaccess'] === false) { + Log::info("HTACCESS ISN\'T READABLE SO SET noting ON " . PrmMng::PARAM_HTACCESS_CONFIG . ' PARAM'); + $paramsManager->setValue(PrmMng::PARAM_HTACCESS_CONFIG, 'nothing'); + $paramsManager->setFormStatus(PrmMng::PARAM_HTACCESS_CONFIG, ParamForm::STATUS_INFO_ONLY); + } + + if ($configsChecks['other'] === false) { + Log::info("OTHER CONFIGS ISN\'T READABLE SO SET noting ON " . PrmMng::PARAM_OTHER_CONFIG . ' PARAM'); + $paramsManager->setValue(PrmMng::PARAM_OTHER_CONFIG, 'nothing'); + $paramsManager->setFormStatus(PrmMng::PARAM_OTHER_CONFIG, ParamForm::STATUS_INFO_ONLY); + } + + $paramsManager->save(); + + return self::$paramsValidated; + } + + /** + * + * @return bool + */ + protected static function setParamsDatabase() + { + $paramsManager = PrmMng::getInstance(); + + $paramsManager->setValueFromInput(PrmMng::PARAM_DB_VIEW_MODE, ParamForm::INPUT_POST); + + switch ($paramsManager->getValue(PrmMng::PARAM_DB_VIEW_MODE)) { + case 'basic': + case 'cpnl': + $readParamsList = array( + PrmMng::PARAM_DB_ACTION, + PrmMng::PARAM_DB_HOST, + PrmMng::PARAM_DB_NAME, + PrmMng::PARAM_DB_USER, + PrmMng::PARAM_DB_PASS + ); + foreach ($readParamsList as $cParam) { + if ($paramsManager->setValueFromInput($cParam, ParamForm::INPUT_POST, false, true) === false) { + self::$paramsValidated = false; + } + } + break; + } + + $readParamsList = array( + PrmMng::PARAM_DB_TABLE_PREFIX, + PrmMng::PARAM_DB_VIEW_CREATION, + PrmMng::PARAM_DB_PROC_CREATION, + PrmMng::PARAM_DB_FUNC_CREATION, + PrmMng::PARAM_DB_REMOVE_DEFINER, + PrmMng::PARAM_DB_SPLIT_CREATES, + PrmMng::PARAM_DB_MYSQL_MODE, + PrmMng::PARAM_DB_MYSQL_MODE_OPTS + ); + + foreach ($readParamsList as $cParam) { + if ($paramsManager->setValueFromInput($cParam, ParamForm::INPUT_POST, false, true) === false) { + self::$paramsValidated = false; + } + } + + if ( + DUPX_Validation_database_service::getInstance()->caseSensitiveTablesValue() !== 0 + && ($redundantTables = DUPX_ArchiveConfig::getInstance()->getRedundantDuplicateTableNames()) !== array() + ) { + $defaultTables = DUPX_DB_Tables::getInstance()->getFilteredParamValue($redundantTables); + } else { + $defaultTables = DUPX_DB_Tables::getInstance()->getDefaultParamValue(); + } + + if ($paramsManager->setValue(PrmMng::PARAM_DB_TABLES, $defaultTables) === false) { + self::$paramsValidated = false; + } + + return self::$paramsValidated; + } + + /** + * resets the original values in case of D&G import + * + * @return void + */ + protected static function resetUrlAndPathsFromOverwriteData() + { + if (!DUPX_InstallerState::isImportFromBackendMode()) { + return; + } + + $paramsManager = PrmMng::getInstance(); + $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + + if (!isset($overwriteData['urls']['home']) || !isset($overwriteData['paths']['home'])) { + return; + } + + $paramsManager->setValue(PrmMng::PARAM_URL_NEW, $overwriteData['urls']['home']); + $paramsManager->setValue(PrmMng::PARAM_PATH_NEW, $overwriteData['paths']['home']); + + $paramsManager->setValue(PrmMng::PARAM_SITE_URL, $overwriteData['urls']['abs']); + $paramsManager->setValue(PrmMng::PARAM_PATH_WP_CORE_NEW, $overwriteData['paths']['abs']); + + $paramsManager->setValue(PrmMng::PARAM_URL_UPLOADS_NEW, $overwriteData['urls']['uploads']); + $paramsManager->setValue(PrmMng::PARAM_PATH_UPLOADS_NEW, $overwriteData['paths']['uploads']); + } + + /** + * + * @return boolean + */ + public static function setParamsStep2() + { + Log::info('CTRL PARAMS S2', Log::LV_DETAILED); + Log::info('REQUEST: ' . Log::v2str($_REQUEST), Log::LV_HARD_DEBUG); + $paramsManager = PrmMng::getInstance(); + + $readParamsList = array( + PrmMng::PARAM_DB_CHARSET, + PrmMng::PARAM_DB_COLLATE, + PrmMng::PARAM_DB_TABLES + ); + + foreach ($readParamsList as $cParam) { + if ($paramsManager->setValueFromInput($cParam, ParamForm::INPUT_POST, false, true) === false) { + self::$paramsValidated = false; + } + } + + $paramsManager->save(); + return self::$paramsValidated; + } + + /** + * + * @return boolean + */ + public static function setParamsStep3() + { + Log::info('CTRL PARAMS S3', Log::LV_DETAILED); + Log::info('REQUEST: ' . Log::v2str($_REQUEST), Log::LV_HARD_DEBUG); + + $paramsManager = PrmMng::getInstance(); + + $readParamsList = array( + PrmMng::PARAM_EMAIL_REPLACE, + PrmMng::PARAM_FULL_SEARCH, + PrmMng::PARAM_SKIP_PATH_REPLACE, + PrmMng::PARAM_POSTGUID, + PrmMng::PARAM_MAX_SERIALIZE_CHECK, + PrmMng::PARAM_PLUGINS, + PrmMng::PARAM_WP_CONF_DISALLOW_FILE_EDIT, + PrmMng::PARAM_WP_CONF_DISALLOW_FILE_MODS, + PrmMng::PARAM_WP_CONF_AUTOSAVE_INTERVAL, + PrmMng::PARAM_WP_CONF_WP_POST_REVISIONS, + PrmMng::PARAM_WP_CONF_FORCE_SSL_ADMIN, + PrmMng::PARAM_WP_CONF_IMAGE_EDIT_OVERWRITE, + PrmMng::PARAM_GEN_WP_AUTH_KEY, + PrmMng::PARAM_WP_CONF_AUTOMATIC_UPDATER_DISABLED, + PrmMng::PARAM_WP_CONF_WP_AUTO_UPDATE_CORE, + PrmMng::PARAM_WP_CONF_WP_CACHE, + PrmMng::PARAM_WP_CONF_WPCACHEHOME, + PrmMng::PARAM_WP_CONF_WP_DEBUG, + PrmMng::PARAM_WP_CONF_WP_DEBUG_LOG, + PrmMng::PARAM_WP_CONF_WP_DISABLE_FATAL_ERROR_HANDLER, + PrmMng::PARAM_WP_CONF_WP_DEBUG_DISPLAY, + PrmMng::PARAM_WP_CONF_SCRIPT_DEBUG, + PrmMng::PARAM_WP_CONF_CONCATENATE_SCRIPTS, + PrmMng::PARAM_WP_CONF_SAVEQUERIES, + PrmMng::PARAM_WP_CONF_ALTERNATE_WP_CRON, + PrmMng::PARAM_WP_CONF_DISABLE_WP_CRON, + PrmMng::PARAM_WP_CONF_WP_CRON_LOCK_TIMEOUT, + PrmMng::PARAM_WP_CONF_EMPTY_TRASH_DAYS, + PrmMng::PARAM_WP_CONF_COOKIE_DOMAIN, + PrmMng::PARAM_WP_CONF_WP_MEMORY_LIMIT, + PrmMng::PARAM_WP_CONF_WP_MAX_MEMORY_LIMIT, + PrmMng::PARAM_WP_CONF_WP_TEMP_DIR, + PrmMng::PARAM_WP_CONF_MYSQL_CLIENT_FLAGS, + PrmMng::PARAM_USERS_PWD_RESET, + PrmMng::PARAM_WP_ADMIN_CREATE_NEW + ); + + foreach ($readParamsList as $cParam) { + if ($paramsManager->setValueFromInput($cParam, ParamForm::INPUT_POST, false, true) === false) { + self::$paramsValidated = false; + } + } + + if ($paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_CREATE_NEW)) { + $readParamsList = array( + PrmMng::PARAM_WP_ADMIN_NAME, + PrmMng::PARAM_WP_ADMIN_PASSWORD, + PrmMng::PARAM_WP_ADMIN_MAIL, + PrmMng::PARAM_WP_ADMIN_NICKNAME, + PrmMng::PARAM_WP_ADMIN_FIRST_NAME, + PrmMng::PARAM_WP_ADMIN_LAST_NAME + ); + + foreach ($readParamsList as $cParam) { + if ($paramsManager->setValueFromInput($cParam, ParamForm::INPUT_POST, false, true) === false) { + self::$paramsValidated = false; + } + } + + if (DUPX_DB_Functions::getInstance()->checkIfUserNameExists($paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_NAME))) { + self::$paramsValidated = false; + DUPX_NOTICE_MANAGER::getInstance()->addNextStepNotice(array( + 'shortMsg' => 'The user ' . $paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_NAME) . ' can\'t be created, already exists', + 'level' => DUPX_NOTICE_ITEM::CRITICAL, + 'longMsg' => 'Please insert another new user login name', + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML + )); + } + } + + $paramsManager->save(); + return self::$paramsValidated; + } + + /** + * + * @return boolean + */ + public static function setParamAutoClean() + { + $paramsManager = PrmMng::getInstance(); + if ($paramsManager->setValueFromInput(PrmMng::PARAM_AUTO_CLEAN_INSTALLER_FILES, ParamForm::INPUT_POST, false, true) === false) { + self::$paramsValidated = false; + } + $paramsManager->save(); + return self::$paramsValidated; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s0.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s0.php new file mode 100644 index 0000000..eb2f6b8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s0.php @@ -0,0 +1,95 @@ +getArchivePath(); + $paramsManager = PrmMng::getInstance(); + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + $labelPadSize = 20; + + Log::info("INSTALLER INFO\n"); + Log::info(str_pad('TEMPLATE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_TEMPLATE))); + Log::info(str_pad('SECURE MODE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str(DUPX_Security::getInstance()->getSecurityType())); + Log::info(str_pad('URL PLUGINS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('pluginsUrl')); + Log::info(str_pad('VALIDATE ON START', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_VALIDATION_ACTION_ON_START))); + Log::info(str_pad('PATH_NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_PATH_NEW))); + Log::info(str_pad('URL_NEW', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_URL_NEW))); + Log::info("********************************************************************************"); + + if (DUPX_InstallerState::isImportFromBackendMode()) { + $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + Log::info("IMPORTER INFO\n"); + Log::info(str_pad('WP VERSION ', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . (isset($overwriteData['wpVersion']) ? $overwriteData['wpVersion'] : 'unknown')); + Log::info(str_pad('DUP VERSION ', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . (isset($overwriteData['dupVersion']) ? $overwriteData['dupVersion'] : 'unknown')); + Log::info(str_pad('LICENSE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . 'Free version'); + Log::info("********************************************************************************"); + } + + $log = ''; + $log .= "ARCHIVE INFO\n\n"; + $log .= str_pad('ARCHIVE NAME', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($archive_path) . "\n"; + $log .= str_pad('ARCHIVE SIZE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . DUPX_U::readableByteSize(DUPX_Conf_Utils::archiveSize()) . "\n"; + $log .= str_pad('CREATED', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->created . "\n"; + $log .= str_pad('WP VERSION', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->version_wp . "\n"; + $log .= str_pad('DUP VERSION', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->version_dup . "\n"; + $log .= str_pad('LICENSE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . 'Free version' . "\n"; + $log .= str_pad('DB VERSION', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->version_db . "\n"; + $log .= str_pad('DB FILE SIZE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . DUPX_U::readableByteSize($archiveConfig->dbInfo->tablesSizeOnDisk) . "\n"; + $log .= str_pad('DB TABLES', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->dbInfo->tablesFinalCount . "\n"; + $log .= str_pad('DB ROWS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->dbInfo->tablesRowCount . "\n"; + $log .= str_pad('URL HOME', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('homeUrl') . "\n"; + $log .= str_pad('URL CORE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('siteUrl') . "\n"; + $log .= str_pad('URL CONTENT', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('contentUrl') . "\n"; + $log .= str_pad('URL UPLOAD', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('uploadBaseUrl') . "\n"; + $log .= str_pad('URL PLUGINS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('pluginsUrl') . "\n"; + $log .= str_pad('URL MU PLUGINS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('mupluginsUrl') . "\n"; + $log .= str_pad('URL THEMES', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->getRealValue('themesUrl') . "\n"; + + + $paths = (array) $archiveConfig->getRealValue('archivePaths'); + foreach ($paths as $key => $value) { + $log .= str_pad('PATH ' . strtoupper($key), $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $value . "\n"; + } + + if (count($archiveConfig->subsites) > 0) { + $log .= "\nSUBSITES\n"; + foreach ($archiveConfig->subsites as $subsite) { + $log .= 'SUBSITE [ID:' . str_pad($subsite->id, 4, ' ', STR_PAD_LEFT) . '] ' . Log::v2str($subsite->domain . $subsite->path) . "\n"; + } + } + + $plugins = (array) $archiveConfig->wpInfo->plugins; + $log .= "\nPLUGINS\n"; + foreach ($plugins as $plugin) { + $log .= 'PLUGIN [SLUG:' . str_pad($plugin->slug, 50, ' ', STR_PAD_RIGHT) . ']'; + + if (is_array($plugin->active)) { + $log .= '[ON:' . str_pad(implode(',', $plugin->active), 5, ' ', STR_PAD_RIGHT) . ']'; + } else { + $log .= '[ON:' . str_pad(Log::v2str($plugin->active), 5, ' ', STR_PAD_RIGHT) . ']'; + } + + $log .= ' ' . $plugin->name . "\n"; + } + Log::info($log, Log::LV_DEFAULT); + Log::info("********************************************************************************"); + Log::flush(); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s3.funcs.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s3.funcs.php new file mode 100644 index 0000000..0cad9a0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s3.funcs.php @@ -0,0 +1,1405 @@ +initData(); + $this->timeStart = DUPX_U::getMicrotime(); + } + + public function updateWebsite() + { + Log::setThrowExceptionOnError(true); + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + switch ($this->getEngineMode()) { + case DUPX_S3_Funcs::MODE_CHUNK: + /* START CHUNK MANAGER */ + $maxIteration = 0; // max iteration before stop. If 0 have no limit + // auto set prevent timeout + $inimaxExecutionTime = ini_get('max_execution_time'); + $maxExecutionTime = (int) (empty($inimaxExecutionTime) ? DUPX_Constants::CHUNK_MAX_TIMEOUT_TIME : $inimaxExecutionTime); + $timeOut = max(5, $maxExecutionTime - 2) * 1000; // timeout in milliseconds before stop exectution + $throttling = 2; // sleep in milliseconds every iteration + $GLOBALS['DATABASE_PAGE_SIZE'] = 1000; // database pagination size for engine update queries + + /* TEST INIT SINGLE FUNC + $maxIteration = 1; // max iteration before stop. If 0 have no limit + $timeOut = 0; // timeout in milliseconds before stop exectution + $throttling = 0; // sleep in milliseconds every iteration + $GLOBALS['DATABASE_PAGE_SIZE'] = 1000000; // database pagination size for engine update queries + */ + + $chunkmManager = new DUPX_chunkS3Manager($maxIteration, $timeOut, $throttling); + if ($chunkmManager->start() === false) { + /* Stop executions */ + $this->chunkStop($chunkmManager->getProgressPerc(), $chunkmManager->getLastPosition()); + } else { + /* step 3 completed */ + $this->complete(); + } + break; + case DUPX_S3_Funcs::MODE_SKIP: + $this->initLog(); + DbCleanup::cleanupOptions(); + DbCleanup::cleanupExtra(); + DbCleanup::cleanupPackages(); + $this->removeMaintenanceMode(); + $this->configFilesUpdate(); + $this->forceLogoutOfAllUsers(); + $this->duplicatorMigrationInfoSet(); + $this->checkForIndexHtml(); + $this->noticeTest(); + $this->cleanupTmpFiles(); + $this->setFilePermsission(); + $this->finalReportNotices(); + $this->complete(); + break; + case DUPX_S3_Funcs::MODE_NORMAL: + default: + $chunkmManager = new DUPX_chunkS3Manager(); + if ($chunkmManager->start() === false) { + throw new Exception('No chunk in normal mode'); + } + $this->complete(); + } + + $nManager->saveNotices(); + return $this->getJsonReport(); + } + + /** + * + * @return self + */ + public static function getInstance() + { + if (is_null(self::$instance)) { + self::$instance = new self(); + } + return self::$instance; + } + + /** + * inizialize 3sFunc data + */ + public function initData() + { + // if data file exists load saved data + if (file_exists(self::getS3dataFilePath())) { + Log::info('LOAD S3 DATA FROM JSON', Log::LV_DETAILED); + if ($this->loadData() == false) { + throw new Exception('Can\'t load s3 data'); + } + } else { + Log::info('INIT S3 DATA', Log::LV_DETAILED); + // else init data from $_POST + $this->setReplaceList(); + $this->initReport(); + } + } + + /** + * + * @return string + */ + private static function getS3dataFilePath() + { + static $path = null; + if (is_null($path)) { + $path = DUPX_INIT . '/dup-installer-s3data__' . DUPX_Package::getPackageHash() . '.json'; + } + return $path; + } + + /** + * + * @return boolean + */ + public function saveData() + { + $data = array( + 'report' => $this->report, + 'cTableParams' => $this->cTableParams, + 'replaceData' => DUPX_S_R_MANAGER::getInstance()->getArrayData() + ); + + if (($json = SnapJson::jsonEncodePPrint($data)) === false) { + Log::info('Can\'t encode json data'); + return false; + } + + if (@file_put_contents(self::getS3dataFilePath(), $json) === false) { + Log::info('Can\'t save s3 data file'); + return false; + } + + return true; + } + + /** + * + * @return boolean + */ + private function loadData() + { + if (!file_exists(self::getS3dataFilePath())) { + return false; + } + + if (($json = @file_get_contents(self::getS3dataFilePath())) === false) { + Log::info('Can\'t load s3 data file'); + return false; + } + + $data = json_decode($json, true); + + if (!is_array($data)) { + Log::info('Can\'t decode json data'); + return false; + } + + if (array_key_exists('cTableParams', $data)) { + $this->cTableParams = $data['cTableParams']; + } else { + Log::info('S3 data not well formed: cTableParams not found.'); + return false; + } + + if (array_key_exists('replaceData', $data)) { + DUPX_S_R_MANAGER::getInstance()->setFromArrayData($data['replaceData']); + } else { + Log::info('S3 data not well formed: replace not found.'); + return false; + } + + if (array_key_exists('report', $data)) { + $this->report = $data['report']; + } else { + Log::info('S3 data not well formed: report not found.'); + return false; + } + + return true; + } + + /** + * + * @return boolean + */ + public static function resetData() + { + $result = true; + if (file_exists(self::getS3dataFilePath())) { + if (@unlink(self::getS3dataFilePath()) === false) { + Log::info('Can\'t delete s3 data file'); + $result = false; + } + } + + if (file_exists($GLOBALS["CHUNK_DATA_FILE_PATH"])) { + if (@unlink($GLOBALS["CHUNK_DATA_FILE_PATH"]) === false) { + Log::info('Can\'t delete s3 chunk file'); + $result = false; + } + } + return $result; + } + + private function initReport() + { + $this->report = array( + 'pass' => 0, + 'chunk' => 0, + 'chunkPos' => array(), + 'progress_perc' => 0, + 'scan_tables' => 0, + 'scan_rows' => 0, + 'scan_cells' => 0, + 'updt_tables' => 0, + 'updt_rows' => 0, + 'updt_cells' => 0, + 'errsql' => array(), + 'errser' => array(), + 'errkey' => array(), + 'errsql_sum' => 0, + 'errser_sum' => 0, + 'errkey_sum' => 0, + 'profile_start' => '', + 'profile_end' => '', + 'time' => '', + 'err_all' => 0, + 'warn_all' => 0, + 'warnlist' => array() + ); + } + + public function getJsonReport() + { + $this->report['warn_all'] = empty($this->report['warnlist']) ? 0 : count($this->report['warnlist']); + + return array( + 'step3' => $this->report + ); + } + + private static function logSectionHeader($title, $func, $line) + { + $log = "\n" . '====================================' . "\n" . + $title; + + if (Log::isLevel(Log::LV_DETAILED)) { + $log .= ' [FUNC: ' . $func . ' L:' . $line . ']'; + } + $log .= "\n" . + '===================================='; + Log::info($log); + } + + /** + * open db connection if is closed + * + * @return database connection handle + */ + private function dbConnection() + { + if (is_null($this->dbh)) { + $this->dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + } + return $this->dbh; + } + + /** + * @return database|mysqli connection handle + */ + public function getDbConnection() + { + return $this->dbConnection(); + } + + /** + * close db connection if is open + */ + public function closeDbConnection() + { + DUPX_DB_Functions::getInstance()->closeDbConnection(); + $this->dbh = null; + } + + public function initLog() + { + $paramsManager = PrmMng::getInstance(); + $labelPadSize = 22; + + // make sure dbConnection is initialized + $this->dbConnection(); + + $charsetServer = @mysqli_character_set_name($this->dbh); + $charsetClient = @mysqli_character_set_name($this->dbh); + + //LOGGING + $date = @date('h:i:s'); + $log = "\n\n" . + "********************************************************************************\n" . + "DUPLICATOR LITE: INSTALL-LOG\n" . + "STEP-3 START @ " . $date . "\n" . + "NOTICE: Do NOT post to public sites or forums\n" . + "********************************************************************************\n" . + "CHARSET SERVER:\t" . Log::v2str($charsetServer) . "\n" . + "CHARSET CLIENT:\t" . Log::v2str($charsetClient) . "\n" . + "********************************************************************************\n" . + "OPTIONS:\n"; + + $log .= str_pad('SKIP PATH REPLACE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($paramsManager->getValue(PrmMng::PARAM_SKIP_PATH_REPLACE)) . "\n"; + + $wpConfigsKeys = array( + PrmMng::PARAM_WP_CONF_DISALLOW_FILE_EDIT, + PrmMng::PARAM_WP_CONF_DISALLOW_FILE_MODS, + PrmMng::PARAM_WP_CONF_AUTOSAVE_INTERVAL, + PrmMng::PARAM_WP_CONF_WP_POST_REVISIONS, + PrmMng::PARAM_WP_CONF_FORCE_SSL_ADMIN, + PrmMng::PARAM_WP_CONF_WP_AUTO_UPDATE_CORE, + PrmMng::PARAM_WP_CONF_WP_CACHE, + PrmMng::PARAM_WP_CONF_WPCACHEHOME, + PrmMng::PARAM_WP_CONF_WP_DEBUG, + PrmMng::PARAM_WP_CONF_WP_DEBUG_LOG, + PrmMng::PARAM_WP_CONF_WP_DEBUG_DISPLAY, + PrmMng::PARAM_WP_CONF_WP_DISABLE_FATAL_ERROR_HANDLER, + PrmMng::PARAM_WP_CONF_SCRIPT_DEBUG, + PrmMng::PARAM_WP_CONF_CONCATENATE_SCRIPTS, + PrmMng::PARAM_WP_CONF_SAVEQUERIES, + PrmMng::PARAM_WP_CONF_ALTERNATE_WP_CRON, + PrmMng::PARAM_WP_CONF_DISABLE_WP_CRON, + PrmMng::PARAM_WP_CONF_WP_CRON_LOCK_TIMEOUT, + PrmMng::PARAM_WP_CONF_COOKIE_DOMAIN, + PrmMng::PARAM_WP_CONF_WP_MEMORY_LIMIT, + PrmMng::PARAM_WP_CONF_WP_MAX_MEMORY_LIMIT, + PrmMng::PARAM_WP_CONF_WP_TEMP_DIR + ); + foreach ($wpConfigsKeys as $key) { + $label = $paramsManager->getLabel($key); + $value = SnapString::implodeKeyVals(', ', $paramsManager->getValue($key), '[%s = %s]'); + $log .= str_pad($label, $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $value . "\n"; + } + $log .= "********************************************************************************\n"; + + Log::info($log); + + $log .= "--------------------------------------\n"; + $log .= "KEEP PLUGINS ACTIVE\n"; + $log .= "--------------------------------------\n"; + $plugins = $paramsManager->getValue(PrmMng::PARAM_PLUGINS); + $log .= (count($plugins) > 0 ? Log::v2str($plugins) : 'No plugins selected for activation'); + Log::info($log, Log::LV_DETAILED); + Log::flush(); + } + + public function initChunkLog($maxIteration, $timeOut, $throttling, $rowsPerPage) + { + $log = "********************************************************************************\n" . + "CHUNK PARAMS:\n"; + $log .= str_pad('maxIteration', 22, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($maxIteration) . "\n"; + $log .= str_pad('timeOut', 22, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($timeOut) . "\n"; + $log .= str_pad('throttling', 22, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($throttling) . "\n"; + $log .= str_pad('rowsPerPage', 22, '_', STR_PAD_RIGHT) . ': ' . Log::v2str($rowsPerPage) . "\n"; + $log .= "********************************************************************************\n"; + Log::info($log); + } + + /** + * set replace list + * + * Auto inizialize function + */ + public function setReplaceList() + { + if ($this->getEngineMode() === self::MODE_SKIP) { + return; + } + + self::logSectionHeader('SET SEARCH AND REPLACE LIST INSTALL TYPE ' . DUPX_InstallerState::installTypeToString(), __FUNCTION__, __LINE__); + + $dbReplace = new DbReplace(); + $dbReplace->setSearchReplace(); + } + + /** + * + * @return int MODE_NORAML|MODE_CHUNK|MODE_SKIP + */ + public function getEngineMode() + { + return PrmMng::getInstance()->getValue(PrmMng::PARAM_REPLACE_ENGINE); + } + + /** + * + * @return bool + */ + public function isChunk() + { + return PrmMng::getInstance()->getValue(PrmMng::PARAM_REPLACE_ENGINE) === self::MODE_CHUNK; + } + + public function runSearchAndReplace() + { + self::logSectionHeader('RUN SEARCH AND REPLACE', __FUNCTION__, __LINE__); + + $tables = DUPX_DB_Tables::getInstance()->getReplaceTablesNames(); + + DUPX_UpdateEngine::load($tables); + DUPX_UpdateEngine::logStats(); + DUPX_UpdateEngine::logErrors(); + } + + public function removeMaintenanceMode() + { + self::logSectionHeader('REMOVE MAINTENANCE MODE', __FUNCTION__, __LINE__); + DUPX_U::maintenanceMode(false); + } + + protected function resetUsersPasswords() + { + self::logSectionHeader('RESET USERS PASSWORD', __FUNCTION__, __LINE__); + + $usersLoginsName = DUPX_ArchiveConfig::getInstance()->getUsersLists(); + foreach (PrmMng::getInstance()->getValue(PrmMng::PARAM_USERS_PWD_RESET) as $userId => $newPassword) { + if (strlen($newPassword) > 0) { + Log::info('RESET USER ID ' . $userId . ' NAME ' . $usersLoginsName[$userId] . ' PASSWORD'); + DUPX_DB_Functions::getInstance()->userPwdReset($userId, $newPassword); + } + } + } + + public function forceLogoutOfAllUsers() + { + Log::info('RESET ALL USERS SESSION TOKENS'); + $escapedTablePrefix = mysqli_real_escape_string($this->dbh, PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_TABLE_PREFIX)); + + try { + DUPX_DB::chunksDelete($this->dbh, $escapedTablePrefix . 'usermeta', "meta_key='session_tokens'"); + } catch (Exception $e) { + Log::info('RESET USER SESSION TOKENS EXCEPTION: ' . $e->getMessage()); + } + } + + public function createNewAdminUser() + { + $this->resetUsersPasswords(); + + if (!PrmMng::getInstance()->getValue(PrmMng::PARAM_WP_ADMIN_CREATE_NEW)) { + return; + } + + self::logSectionHeader('CREATE NEW ADMIN USER', __FUNCTION__, __LINE__); + // make sure dbConnection is initialized + $this->dbConnection(); + + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $escapedTablePrefix = mysqli_real_escape_string($this->dbh, PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_TABLE_PREFIX)); + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + $paramsManager = PrmMng::getInstance(); + + $wpUserName = $paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_NAME); + $wpUserNameEscaped = mysqli_real_escape_string($this->dbh, $wpUserName); + + $newuser_check = DUPX_DB::mysqli_query( + $this->dbh, + "SELECT COUNT(*) AS count FROM `" . $escapedTablePrefix . "users` WHERE user_login = '{$wpUserNameEscaped}' " + ); + $newuser_row = mysqli_fetch_row($newuser_check); + $newuser_count = is_null($newuser_row) ? 0 : $newuser_row[0]; + + if ($newuser_count == 0) { + $newuser_datetime = @date("Y-m-d H:i:s"); + $newuser_datetime = mysqli_real_escape_string($this->dbh, $newuser_datetime); + $newuser_security = mysqli_real_escape_string($this->dbh, DUPX_WPConfig::ADMIN_SERIALIZED_SECURITY_STRING); + + $post_wp_password = $paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_PASSWORD); + $post_wp_mail = $paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_MAIL); + $post_wp_nickname = $paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_NICKNAME); + if (empty($post_wp_nickname)) { + $post_wp_nickname = $wpUserName; + } + $post_wp_first_name = $paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_FIRST_NAME); + $post_wp_last_name = $paramsManager->getValue(PrmMng::PARAM_WP_ADMIN_LAST_NAME); + + $wp_password = mysqli_real_escape_string($this->dbh, $post_wp_password); + $wp_mail = mysqli_real_escape_string($this->dbh, $post_wp_mail); + $wp_nickname = mysqli_real_escape_string($this->dbh, $post_wp_nickname); + $wp_first_name = mysqli_real_escape_string($this->dbh, $post_wp_first_name); + $wp_last_name = mysqli_real_escape_string($this->dbh, $post_wp_last_name); + + $usermeta_table = $escapedTablePrefix . 'usermeta'; + + $newuser1 = DUPX_DB::mysqli_query( + $this->dbh, + "INSERT INTO `" . $escapedTablePrefix . "users` + (`user_login`, `user_pass`, `user_nicename`, `user_email`, `user_registered`, `user_activation_key`, `user_status`, `display_name`) + VALUES ('{$wpUserNameEscaped}', MD5('{$wp_password}'), '{$wpUserNameEscaped}', '{$wp_mail}', '{$newuser_datetime}', '', '0', '{$wpUserNameEscaped}')" + ); + + $newuser1_insert_id = intval(mysqli_insert_id($this->dbh)); + + $newuser2 = DUPX_DB::mysqli_query( + $this->dbh, + "INSERT INTO `" . $usermeta_table . "` + (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser1_insert_id}', '" . $escapedTablePrefix . "capabilities', '{$newuser_security}')" + ); + + $newuser3 = DUPX_DB::mysqli_query( + $this->dbh, + "INSERT INTO `" . $usermeta_table . "` + (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser1_insert_id}', '" . $escapedTablePrefix . "user_level', '10')" + ); + + //Misc Meta-Data Settings: + DUPX_DB::mysqli_query($this->dbh, "INSERT INTO `" . $usermeta_table . "` (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser1_insert_id}', 'rich_editing', 'true')"); + DUPX_DB::mysqli_query($this->dbh, "INSERT INTO `" . $usermeta_table . "` (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser1_insert_id}', 'admin_color', 'fresh')"); + DUPX_DB::mysqli_query($this->dbh, "INSERT INTO `" . $usermeta_table . "` (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser1_insert_id}', 'nickname', '{$wp_nickname}')"); + DUPX_DB::mysqli_query($this->dbh, "INSERT INTO `" . $usermeta_table . "` (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser1_insert_id}', 'first_name', '{$wp_first_name}')"); + DUPX_DB::mysqli_query($this->dbh, "INSERT INTO `" . $usermeta_table . "` (`user_id`, `meta_key`, `meta_value`) VALUES ('{$newuser1_insert_id}', 'last_name', '{$wp_last_name}')"); + + Log::info("\nNEW WP-ADMIN USER:"); + if ($newuser1 && $newuser2 && $newuser3) { + Log::info("- New username '{$wpUserName}' was created successfully allong with MU usermeta."); + } elseif ($newuser1) { + Log::info("- New username '{$wpUserName}' was created successfully."); + } else { + $newuser_warnmsg = "- Failed to create the user '{$wpUserName}' \n "; + $this->report['warnlist'][] = $newuser_warnmsg; + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'New admin user create error', + 'level' => DUPX_NOTICE_ITEM::HARD_WARNING, + 'longMsg' => $newuser_warnmsg, + 'sections' => 'general' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_UPDATE, 'new-user-create-error'); + + Log::info($newuser_warnmsg); + } + } else { + $newuser_warnmsg = "\nNEW WP-ADMIN USER:\n - Username '{$wpUserName}' already exists in the database. Unable to create new account.\n"; + $this->report['warnlist'][] = $newuser_warnmsg; + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'New admin user create error', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $newuser_warnmsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE, + 'sections' => 'general' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_UPDATE, 'new-user-create-error'); + + Log::info($newuser_warnmsg); + } + } + + /** + * update all config files + */ + public function configFilesUpdate() + { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + // SET FILES + DUPX_ServerConfig::setFiles(PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW)); + $wpConfigFile = DUPX_WPConfig::getWpConfigPath(); + + // UPDATE FILES + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_WP_CONFIG) == 'nothing') { + Log::info('SKIP WP CONFIG UPDATE'); + } elseif (file_exists(($wpConfigFile))) { + if (SnapIO::chmod($wpConfigFile, 'u+rw') === false) { + $err_log = "\nWARNING: Unable to update file permissions and write to wp-config.php. "; + $err_log .= "Check that the wp-config.php is in the archive.zip and check with your host or administrator to enable PHP to write to the wp-config.php file. "; + $err_log .= "If performing a 'Manual Extraction' please be sure to select the 'Manual Archive Extraction' option on step 1 under options."; + Log::error("{$err_log}"); + } + $configTransformer = new WPConfigTransformer($wpConfigFile); + $this->wpConfigUpdate($configTransformer); + DUP_Extraction::setPermsFromParams($wpConfigFile); + } else { + $msg = "WP-CONFIG NOTICE: wp-config.php not found.

        "; + $msg .= "No action on the wp-config was possible.
        "; + $msg .= "Be sure to insert a properly modified wp-config for correct wordpress operation."; + + $nManager->addBothNextAndFinalReportNotice(array( + 'shortMsg' => 'wp-config.php file not found', + 'level' => DUPX_NOTICE_ITEM::CRITICAL, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'longMsg' => $msg, + 'sections' => 'general' + )); + } + + $this->htaccessUpdate(); + $this->indexPhpUpdate(); + DUPX_NOTICE_MANAGER::getInstance()->saveNotices(); + } + + /** + * update index.php file with right wp-blog-header include related to installation ABSPATH + * + * @return boolean + */ + protected function indexPhpUpdate() + { + $paramsManager = PrmMng::getInstance(); + + if ( + DUPX_InstallerState::isRestoreBackup() + ) { + return; + } + + self::logSectionHeader('INDEX.PHP UPDATE', __FUNCTION__, __LINE__); + + $pathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_NEW); + $indexPath = $pathNew . '/index.php'; + + if (!is_writable($indexPath)) { + Log::info('index.php isn\'t writable'); + return false; + } + + if (($relativeAbsPath = SnapIO::getRelativePath($paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW), $pathNew)) === false) { + $blogHeaderValue = "'" . $paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW) . "/wp-blog-header.php'"; + } else { + $relativeAbsPath = strlen($relativeAbsPath) ? '/' . $relativeAbsPath : ''; + $blogHeaderValue = "__DIR__ . '" . $relativeAbsPath . "/wp-blog-header.php'"; + } + + if (($indexContent = file_get_contents($indexPath)) === false) { + Log::info('Can\'t read index.php content'); + return false; + } + $indexContent = preg_replace('/(require\s*\(.*wp-blog-header.php[\'"]\s*\))/m', 'require(' . $blogHeaderValue . ')', $indexContent); + + if (file_put_contents($indexPath, $indexContent) === false) { + Log::info('Can\'t update index.php content'); + return false; + } + + Log::info('INDEX.PHP updated with new blog header ' . Log::v2str($blogHeaderValue) . "\n"); + return true; + } + + /** + * + * @param WPConfigTransformer $confTransformer + * + * @return void + */ + protected function wpConfigUpdate(WPConfigTransformer $confTransformer) + { + self::logSectionHeader('CONFIGURATION FILE UPDATES', __FUNCTION__, __LINE__); + Log::incIndent(); + + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $paramsManager = PrmMng::getInstance(); + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + + try { + $this->configurationMultisiteUpdate($confTransformer); + $this->configurationUrlsAndPaths($confTransformer); + + $dbhost = DUPX_U::getEscapedGenericString($paramsManager->getValue(PrmMng::PARAM_DB_HOST)); + $dbname = DUPX_U::getEscapedGenericString($paramsManager->getValue(PrmMng::PARAM_DB_NAME)); + $dbuser = DUPX_U::getEscapedGenericString($paramsManager->getValue(PrmMng::PARAM_DB_USER)); + $dbpass = DUPX_U::getEscapedGenericString($paramsManager->getValue(PrmMng::PARAM_DB_PASS)); + $dbcharset = $paramsManager->getValue(PrmMng::PARAM_DB_CHARSET); + $dbcollate = $paramsManager->getValue(PrmMng::PARAM_DB_COLLATE); + + $confTransformer->update('constant', 'DB_NAME', $dbname, array('raw' => true)); + Log::info('UPDATE DB_NAME ' . Log::v2str($dbname)); + + $confTransformer->update('constant', 'DB_USER', $dbuser, array('raw' => true)); + Log::info('UPDATE DB_USER ' . Log::v2str('** OBSCURED **')); + + $confTransformer->update('constant', 'DB_PASSWORD', $dbpass, array('raw' => true)); + Log::info('UPDATE DB_PASSWORD ' . Log::v2str('** OBSCURED **')); + + $confTransformer->update('constant', 'DB_HOST', $dbhost, array('raw' => true)); + Log::info('UPDATE DB_HOST ' . Log::v2str($dbhost)); + + $confTransformer->update('constant', 'DB_CHARSET', $dbcharset); + Log::info('UPDATE DB_CHARSET ' . Log::v2str($dbcharset)); + + $confTransformer->update('constant', 'DB_COLLATE', $dbcollate); + Log::info('UPDATE DB_COLLATE ' . Log::v2str($dbcollate)); + + if (DUPX_InstallerState::isRestoreBackup()) { + Log::info("\nRESTORE BACKUP MODE: SKIP OTHER WP-CONFIGS UPDATE ***"); + Log::resetIndent(); + return; + } + + $auth_keys = array( + 'AUTH_KEY', + 'SECURE_AUTH_KEY', + 'LOGGED_IN_KEY', + 'NONCE_KEY', + 'AUTH_SALT', + 'SECURE_AUTH_SALT', + 'LOGGED_IN_SALT', + 'NONCE_SALT', + ); + + foreach ($auth_keys as $const_key) { + $confTransformer->update('constant', $const_key, $archiveConfig->getDefineValue($const_key)); + } + + $confTransformer->update('variable', 'table_prefix', $paramsManager->getValue(PrmMng::PARAM_DB_TABLE_PREFIX)); + + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'DISALLOW_FILE_EDIT', PrmMng::PARAM_WP_CONF_DISALLOW_FILE_EDIT); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'DISALLOW_FILE_MODS', PrmMng::PARAM_WP_CONF_DISALLOW_FILE_MODS); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'FORCE_SSL_ADMIN', PrmMng::PARAM_WP_CONF_FORCE_SSL_ADMIN); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'IMAGE_EDIT_OVERWRITE', PrmMng::PARAM_WP_CONF_IMAGE_EDIT_OVERWRITE); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_CACHE', PrmMng::PARAM_WP_CONF_WP_CACHE); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WPCACHEHOME', PrmMng::PARAM_WP_CONF_WPCACHEHOME); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'COOKIE_DOMAIN', PrmMng::PARAM_WP_CONF_COOKIE_DOMAIN); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'AUTOSAVE_INTERVAL', PrmMng::PARAM_WP_CONF_AUTOSAVE_INTERVAL); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_POST_REVISIONS', PrmMng::PARAM_WP_CONF_WP_POST_REVISIONS); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_DEBUG', PrmMng::PARAM_WP_CONF_WP_DEBUG); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_DEBUG_LOG', PrmMng::PARAM_WP_CONF_WP_DEBUG_LOG); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_DISABLE_FATAL_ERROR_HANDLER', PrmMng::PARAM_WP_CONF_WP_DISABLE_FATAL_ERROR_HANDLER); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_DEBUG_DISPLAY', PrmMng::PARAM_WP_CONF_WP_DEBUG_DISPLAY); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'SCRIPT_DEBUG', PrmMng::PARAM_WP_CONF_SCRIPT_DEBUG); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'CONCATENATE_SCRIPTS', PrmMng::PARAM_WP_CONF_CONCATENATE_SCRIPTS); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'SAVEQUERIES', PrmMng::PARAM_WP_CONF_SAVEQUERIES); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'ALTERNATE_WP_CRON', PrmMng::PARAM_WP_CONF_ALTERNATE_WP_CRON); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'DISABLE_WP_CRON', PrmMng::PARAM_WP_CONF_DISABLE_WP_CRON); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_CRON_LOCK_TIMEOUT', PrmMng::PARAM_WP_CONF_WP_CRON_LOCK_TIMEOUT); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'EMPTY_TRASH_DAYS', PrmMng::PARAM_WP_CONF_EMPTY_TRASH_DAYS); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_MEMORY_LIMIT', PrmMng::PARAM_WP_CONF_WP_MEMORY_LIMIT); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_MAX_MEMORY_LIMIT', PrmMng::PARAM_WP_CONF_WP_MAX_MEMORY_LIMIT); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'WP_TEMP_DIR', PrmMng::PARAM_WP_CONF_WP_TEMP_DIR); + DUPX_ArchiveConfig::updateWpConfigByParam($confTransformer, 'AUTOMATIC_UPDATER_DISABLED', PrmMng::PARAM_WP_CONF_AUTOMATIC_UPDATER_DISABLED); + + $wpConfigValue = $paramsManager->getValue(PrmMng::PARAM_WP_CONF_WP_AUTO_UPDATE_CORE); + switch ($wpConfigValue['value']) { + case 'false': + $wpConfigValue['value'] = false; + break; + case 'true': + $wpConfigValue['value'] = true; + break; + case 'minor': + default: + $wpConfigValue['value'] = 'minor'; + break; + } + DUPX_ArchiveConfig::updateWpConfigByValue($confTransformer, 'WP_AUTO_UPDATE_CORE', $wpConfigValue); + + $wpConfigValue = $paramsManager->getValue(PrmMng::PARAM_WP_CONF_MYSQL_CLIENT_FLAGS); + $constantValue = implode(' | ', SnapDB::getMysqlConnectFlagsList(true, $wpConfigValue['value'])); + DUPX_ArchiveConfig::updateWpConfigByValue($confTransformer, 'MYSQL_CLIENT_FLAGS', $wpConfigValue, $constantValue); + + Log::info("\n*** UPDATED WP CONFIG FILE ***"); + } catch (Exception $e) { + $shortMsg = 'wp-config.php transformer:' . $e->getMessage(); + $longMsg = << +The installation is finished but check the wp-config.php file and manually update the incorrect values. +LONGMSG; + /* $nManager->addNextStepNotice(array( + 'shortMsg' => $shortMsg, + 'level' => DUPX_NOTICE_ITEM::CRITICAL, + + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE , 'wp-config-transformer-exception'); */ + $nManager->addFinalReportNotice(array( + 'shortMsg' => $shortMsg, + 'level' => DUPX_NOTICE_ITEM::CRITICAL, + 'longMsg' => $longMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'general' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'wp-config-transformer-exception'); + + Log::info("WP-CONFIG TRANSFORMER EXCEPTION\n" . $e->getTraceAsString()); + } + Log::resetIndent(); + } + + /** + * + * @param WPConfigTransformer $confTransformer + */ + protected function configurationMultisiteUpdate(WPConfigTransformer $confTransformer) + { + $muDefines = array( + 'WP_ALLOW_MULTISITE', + 'ALLOW_MULTISITE', + 'MULTISITE', + 'DOMAIN_CURRENT_SITE', + 'PATH_CURRENT_SITE', + 'SITE_ID_CURRENT_SITE', + 'BLOG_ID_CURRENT_SITE', + 'NOBLOGREDIRECT', + 'SUBDOMAIN_INSTALL', + 'VHOST', + 'SUNRISE', + 'COOKIEPATH', + 'SITECOOKIEPATH', + 'ADMIN_COOKIE_PATH', + 'PLUGINS_COOKIE_PATH' + ); + + // Clean all mu site define + foreach ($muDefines as $key) { + if ($confTransformer->exists('constant', $key)) { + $confTransformer->remove('constant', $key); + Log::info('TRANSFORMER[no wpmu]: ' . $key . ' constant removed from WP config file'); + } + } + } + + /** + * + * @param WPConfigTransformer $confTransformer + */ + protected function configurationUrlsAndPaths(WPConfigTransformer $confTransformer) + { + $paramsManager = PrmMng::getInstance(); + + $urlNew = $paramsManager->getValue(PrmMng::PARAM_URL_NEW); + $pathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_NEW); + + $mu_newDomain = parse_url($urlNew); + $mu_newDomainHost = $mu_newDomain['host']; + $mu_newUrlPath = parse_url($urlNew, PHP_URL_PATH); + + if (empty($mu_newUrlPath) || ($mu_newUrlPath == '/')) { + $mu_newUrlPath = '/'; + } else { + $mu_newUrlPath = rtrim($mu_newUrlPath, '/') . '/'; + } + + if ($confTransformer->exists('constant', 'ABSPATH')) { + if (($relativeAbsPath = SnapIO::getRelativePath($paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW), $pathNew)) === false) { + $absPathValue = "'" . $paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW) . "'"; + } else { + $absPathValue = "__DIR__ . '/" . $relativeAbsPath . "'"; + } + $confTransformer->update('constant', 'ABSPATH', $absPathValue, array('raw' => true)); + Log::info('UPDATE ABSPATH ' . Log::v2str($absPathValue)); + } + + if ($confTransformer->exists('constant', 'WP_HOME')) { + $confTransformer->update('constant', 'WP_HOME', $urlNew, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WP_HOME ' . Log::v2str($urlNew)); + } + + $newSiteUrl = $paramsManager->getValue(PrmMng::PARAM_SITE_URL); + if ($confTransformer->exists('constant', 'WP_SITEURL') || $urlNew != $newSiteUrl) { + $confTransformer->update('constant', 'WP_SITEURL', $newSiteUrl, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WP_SITEURL ' . Log::v2str($newSiteUrl)); + } + + if ($confTransformer->exists('constant', 'DOMAIN_CURRENT_SITE')) { + $confTransformer->update('constant', 'DOMAIN_CURRENT_SITE', $mu_newDomainHost, array('normalize' => true, 'add' => true)); + Log::info('UPDATE DOMAIN_CURRENT_SITE ' . Log::v2str($mu_newDomainHost)); + } + if ($confTransformer->exists('constant', 'PATH_CURRENT_SITE')) { + $confTransformer->update('constant', 'PATH_CURRENT_SITE', $mu_newUrlPath, array('normalize' => true, 'add' => true)); + Log::info('UPDATE PATH_CURRENT_SITE ' . Log::v2str($mu_newUrlPath)); + } + + $pathContent = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW); + if ($confTransformer->exists('constant', 'WP_CONTENT_DIR') || $pathNew . '/wp-content' != $pathContent) { + $confTransformer->update('constant', 'WP_CONTENT_DIR', $pathContent, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WP_CONTENT_DIR ' . Log::v2str($pathContent)); + } + + $urlContent = $paramsManager->getValue(PrmMng::PARAM_URL_CONTENT_NEW); + if ($confTransformer->exists('constant', 'WP_CONTENT_URL') || $urlNew . '/wp-content' != $urlContent) { + $confTransformer->update('constant', 'WP_CONTENT_URL', $urlContent, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WP_CONTENT_URL ' . Log::v2str($urlContent)); + } + + $pathPlugins = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW); + if ($confTransformer->exists('constant', 'WP_PLUGIN_DIR') || $pathNew . '/wp-content/plugins' != $pathPlugins) { + $confTransformer->update('constant', 'WP_PLUGIN_DIR', $pathPlugins, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WP_PLUGIN_DIR ' . Log::v2str($pathPlugins)); + } + + $urlPlugins = $paramsManager->getValue(PrmMng::PARAM_URL_PLUGINS_NEW); + if ($confTransformer->exists('constant', 'WP_PLUGIN_URL') || $urlNew . '/wp-content/plugins' != $urlPlugins) { + $confTransformer->update('constant', 'WP_PLUGIN_URL', $urlPlugins, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WP_PLUGIN_URL ' . Log::v2str($urlPlugins)); + } + + $pathMuPlugins = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW); + if ($confTransformer->exists('constant', 'WPMU_PLUGIN_DIR') || $pathNew . '/wp-content/mu-plugins' != $pathMuPlugins) { + $confTransformer->update('constant', 'WPMU_PLUGIN_DIR', $pathMuPlugins, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WPMU_PLUGIN_DIR ' . Log::v2str($pathMuPlugins)); + } + + $urlMuPlugins = $paramsManager->getValue(PrmMng::PARAM_URL_MUPLUGINS_NEW); + if ($confTransformer->exists('constant', 'WPMU_PLUGIN_URL') || $urlNew . '/wp-content/mu-plugins' != $urlMuPlugins) { + $confTransformer->update('constant', 'WPMU_PLUGIN_URL', $urlMuPlugins, array('normalize' => true, 'add' => true)); + Log::info('UPDATE WPMU_PLUGIN_URL ' . Log::v2str($urlMuPlugins)); + } + } + + protected function htaccessUpdate() + { + self::logSectionHeader('HTACCESS UPDATE', __FUNCTION__, __LINE__); + // make sure dbConnection is initialized + $this->dbConnection(); + + DUPX_ServerConfig::setup($this->dbh, PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW)); + } + + protected function updateBlogName() + { + $paramsManager = PrmMng::getInstance(); + + $escapedOptionTable = mysqli_real_escape_string($this->dbh, DUPX_DB_Functions::getOptionsTableName()); + $escapedBlogName = htmlspecialchars($paramsManager->getValue(PrmMng::PARAM_BLOGNAME), ENT_QUOTES); + $escapedBlogName = mysqli_real_escape_string($this->dbh, $escapedBlogName); + + Log::info('UPATE BLOG NAME ' . Log::v2str($escapedBlogName), Log::LV_DETAILED); + DUPX_DB::mysqli_query( + $this->dbh, + "UPDATE `" . $escapedOptionTable . + "` SET option_value = '" . mysqli_real_escape_string($this->dbh, $escapedBlogName) . + "' WHERE option_name = 'blogname' " + ); + } + + /** + * Update options URLs + * + * @param string $table + * @param string $urlNew + * @param string $siteUrl + * + * @return void + */ + protected function updateOptionsUrls($table, $urlNew, $siteUrl) + { + $paramsManager = PrmMng::getInstance(); + $escapedOptionTable = mysqli_real_escape_string($this->dbh, $table); + + Log::info('UPATE URL NEW ' . Log::v2str($urlNew), Log::LV_DETAILED); + DUPX_DB::mysqli_query( + $this->dbh, + "UPDATE `" . $escapedOptionTable . "` " . + "SET option_value = '" . mysqli_real_escape_string($this->dbh, $urlNew) . "' WHERE option_name = 'home' " + ); + Log::info('UPATE SITE URL ' . Log::v2str($siteUrl), Log::LV_DETAILED); + DUPX_DB::mysqli_query( + $this->dbh, + "UPDATE `" . $escapedOptionTable . "` " . + "SET option_value = '" . mysqli_real_escape_string($this->dbh, $siteUrl) . "' WHERE option_name = 'siteurl' " + ); + + $safeModeVal = mysqli_real_escape_string($this->dbh, $paramsManager->getValue(PrmMng::PARAM_SAFE_MODE)); + DUPX_DB::mysqli_query($this->dbh, "INSERT INTO `" . $escapedOptionTable . "` (option_value, option_name) " + . "VALUES('" . $safeModeVal . "','duplicator_pro_exe_safe_mode')" + . "ON DUPLICATE KEY UPDATE option_value = '" . $safeModeVal . "'"); + } + + /** + * Update post GUID + * + * @param string $table + * @param string $urlNew + * + * @return void + */ + protected function updatePostsGuid($table, $urlNew) + { + $paramsManager = PrmMng::getInstance(); + + //Reset the postguid data + if (!$paramsManager->getValue(PrmMng::PARAM_POSTGUID)) { + return; + } + $escapedPostsTable = mysqli_real_escape_string($this->dbh, $table); + + Log::info('UPATE postguid'); + DUPX_DB::mysqli_query( + $this->dbh, + "UPDATE `" . $escapedPostsTable . "` SET guid = REPLACE(guid, '" . mysqli_real_escape_string($this->dbh, $urlNew) . "', '" . mysqli_real_escape_string( + $this->dbh, + $paramsManager->getValue(PrmMng::PARAM_URL_OLD) + ) . "')" + ); + $update_guid = @mysqli_affected_rows($this->dbh) or 0; + Log::info("Reverted '{$update_guid}' post guid columns back to '" . $paramsManager->getValue(PrmMng::PARAM_URL_OLD) . "'"); + } + + public function generalUpdate() + { + self::logSectionHeader('GENERAL UPDATES', __FUNCTION__, __LINE__); + // make sure dbConnection is initialized + $this->dbConnection(); + + $this->updateBlogName(); + + $paramsManager = PrmMng::getInstance(); + $urlNew = $paramsManager->getValue(PrmMng::PARAM_URL_NEW); + $siteUrl = $paramsManager->getValue(PrmMng::PARAM_SITE_URL); + + $this->updateOptionsUrls( + DUPX_DB_Functions::getOptionsTableName(), + $urlNew, + $siteUrl + ); + $this->updatePostsGuid( + DUPX_DB_Functions::getPostsTableName(), + $urlNew + ); + + $this->managePlugins(); + } + + /** + * + * @return boolean + */ + public function duplicatorMigrationInfoSet() + { + Log::info('MIGRATION INFO SET'); + // make sure dbConnection is initialized + $this->dbConnection(); + + // on main options tables in all installation + $optionTable = mysqli_real_escape_string($this->dbh, DUPX_DB_Functions::getOptionsTableName()); + $migrationData = DUPX_InstallerState::getMigrationData(); + + $query = "REPLACE INTO `" . $optionTable . "` (`option_id`, `option_name`, `option_value`, `autoload`) VALUES " . + "(NULL, '" . self::FIRST_LOGIN_OPTION . "', '1', 'no'), " . + "(NULL, '" . self::MIGRATION_DATA_OPTION . "', '" . mysqli_real_escape_string($this->dbh, SnapJson::jsonEncodePPrint($migrationData)) . "', 'no');"; + + if (DUPX_DB::mysqli_query($this->dbh, $query) === false) { + $errMsg = "DATABASE ERROR \"" . mysqli_error($this->dbh) . "\"
        [sql=" . substr($query, 0, DUPX_DBInstall::QUERY_ERROR_LOG_LEN) . "...]"; + DUPX_NOTICE_MANAGER::getInstance()->addBothNextAndFinalReportNotice(array( + 'shortMsg' => 'UPDATE MIRATION INFO ISSUE', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $errMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database' + )); + + return false; + } else { + return true; + } + } + + public function generalCleanup() + { + self::logSectionHeader('GENERAL CLEANUP', __FUNCTION__, __LINE__); + // make sure dbConnection is initialized + $this->dbConnection(); + $paramsManager = PrmMng::getInstance(); + + if (!DUPX_UpdateEngine::updateTablePrefixKeys()) { + // @todo display erorr on notice manager + } + } + + /** + * activate and deactivate plugins + * + * @return void + */ + protected function managePlugins() + { + self::logSectionHeader("MANAGE PLUGINS", __FUNCTION__, __LINE__); + $paramsManager = PrmMng::getInstance(); + + try { + $pluginsManager = DUPX_Plugins_Manager::getInstance(); + $pluginsManager->setActions($paramsManager->getValue(PrmMng::PARAM_PLUGINS)); + $pluginsManager->executeActions($this->dbConnection()); + } catch (Exception $e) { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'Plugins settings error ' . $e->getMessage(), + 'level' => DUPX_NOTICE_ITEM::CRITICAL, + 'longMsg' => $e->getTraceAsString(), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE, + 'sections' => 'general' + )); + + Log::info("PLUGIN MANAGER EXCEPTIOMN\n" . $e->getTraceAsString()); + } + } + + /** + * checks for index.html in root, and if found, issues a soft warning + * + * @return void + */ + public function checkForIndexHtml() + { + self::logSectionHeader('CHECK FOR INDEX.HTML', __FUNCTION__, __LINE__); + + //scan for index.html + if (file_exists(PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW) . '/index.html')) { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $nManager->addFinalReportNotice( + array( + 'shortMsg' => 'An index.html was found.', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => 'An index.html was found in the existing site. You may need to manually remove it for the new site to work.', + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT, + 'sections' => 'general' + ) + ); + + Log::info("AN INDEX.HTML WAS FOUND IN THE ROOT OF THE INSTALLATION."); + } else { + Log::info("NO INDEX.HTML WAS FOUND"); + } + } + + public function noticeTest() + { + self::logSectionHeader('NOTICES TEST', __FUNCTION__, __LINE__); + // make sure dbConnection is initialized + $this->dbConnection(); + $optonsTable = mysqli_real_escape_string($this->dbh, DUPX_DB_Functions::getOptionsTableName()); + + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + //Database + $result = DUPX_DB::mysqli_query( + $this->dbh, + "SELECT option_value FROM `" . $optonsTable . "` WHERE option_name IN ('upload_url_path','uploadPath')" + ); + if ($result) { + while ($row = mysqli_fetch_row($result)) { + if (strlen($row[0])) { + $msg = "MEDIA SETTINGS NOTICE: The table '" . $optonsTable . "' has at least one the following values ['upload_url_path','uploadPath'] \n"; + $msg .= "set please validate settings. These settings can be changed in the wp-admin by going to /wp-admin/options.php'"; + + $this->report['warnlist'][] = $msg; + Log::info($msg); + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'Media settings notice', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $msg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE, + 'sections' => 'general' + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_UPDATE, 'media-settings-notice'); + + break; + } + } + } + + if (empty($this->report['warnlist'])) { + Log::info("No General Notices Found\n"); + } + } + + public function cleanupTmpFiles() + { + self::logSectionHeader('CLEANUP TMP FILES', __FUNCTION__, __LINE__); + + //Cleanup any tmp files a developer may have forgotten about + //Lets be proactive for the developer just in case + $pathNew = PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW); + $wpconfig_path_bak = $pathNew . "/wp-config.bak"; + $wpconfig_path_old = $pathNew . "/wp-config.old"; + $wpconfig_path_org = $pathNew . "/wp-config.org"; + $wpconfig_path_orig = $pathNew . "/wp-config.orig"; + $wpconfig_safe_check = array($wpconfig_path_bak, $wpconfig_path_old, $wpconfig_path_org, $wpconfig_path_orig); + foreach ($wpconfig_safe_check as $file) { + if (file_exists($file)) { + $tmp_newfile = $file . uniqid('_'); + if (rename($file, $tmp_newfile) === false) { + Log::info("WARNING: Unable to rename '{$file}' to '{$tmp_newfile}'"); + } + } + } + } + + public function setFilePermsission() + { + self::logSectionHeader('SET PARAMS PERMISSION', __FUNCTION__, __LINE__); + DUP_Extraction::setFolderPermissionAfterExtraction(); + } + + public function finalReportNotices() + { + self::logSectionHeader('FINAL REPORT NOTICES', __FUNCTION__, __LINE__); + + $this->wpConfigFinalReport(); + $this->htaccessFinalReport(); + } + + private function htaccessFinalReport() + { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + $origHtaccessPath = DUPX_Orig_File_Manager::getInstance()->getEntryStoredPath(DUPX_ServerConfig::CONFIG_ORIG_FILE_HTACCESS_ID); + if ($origHtaccessPath === false || ($orig = file_get_contents($origHtaccessPath)) === false) { + $orig = 'Original .htaccess file doesn\'t exist'; + } + + $targetHtaccessPath = DUPX_ServerConfig::getHtaccessTargetPath(); + if (!file_exists($targetHtaccessPath) || ($new = file_get_contents($targetHtaccessPath)) === false) { + $new = 'New .htaccess file doesn\'t exist'; + } + + $lightBoxContent = '
        ' . + '
        Original .htaccess
        ' . htmlspecialchars($orig) . '
        ' . + '
        New .htaccess
        ' . htmlspecialchars($new) . '
        ' . + '
        '; + $longMsg = DUPX_U_Html::getLigthBox('.htaccess changes', 'HTACCESS COMPARE', $lightBoxContent, false); + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'htaccess changes', + 'level' => DUPX_NOTICE_ITEM::INFO, + 'longMsg' => $longMsg, + 'sections' => 'changes', + 'open' => true, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'htaccess-changes'); + } + + private function wpConfigFinalReport() + { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $wpConfigPath = DUPX_Orig_File_Manager::getInstance()->getEntryStoredPath(DUPX_ServerConfig::CONFIG_ORIG_FILE_WPCONFIG_ID); + + if ($wpConfigPath === false || ($orig = file_get_contents($wpConfigPath)) === false) { + $orig = 'Can\'t read origin wp-config.php file'; + } else { + $orig = $this->obscureWpConfig($orig); + } + + $wpConfigFile = DUPX_WPConfig::getWpConfigPath(); + if (!is_readable($wpConfigFile)) { + $new = 'Can read wp-config.php file'; + } elseif (($new = file_get_contents($wpConfigFile)) === false) { + $new = 'Can read wp-config.php file'; + } else { + $new = $this->obscureWpConfig($new); + } + + $lightBoxContent = '
        ' . + '
        Original wp-config.php
        ' . htmlspecialchars($orig) . '
        ' . + '
        New wp-config.php
        ' . htmlspecialchars($new) . '
        ' . + '
        '; + $longMsg = DUPX_U_Html::getLigthBox('wp-config.php changes', 'WP-CONFIG.PHP COMPARE', $lightBoxContent, false); + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'wp-config.php changes', + 'level' => DUPX_NOTICE_ITEM::INFO, + 'longMsg' => $longMsg, + 'sections' => 'changes', + 'open' => true, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE, 'wp-config-changes'); + } + + private function obscureWpConfig($src) + { + $transformer = new WPConfigTransformerSrc($src); + $obsKeys = array( + 'DB_NAME', + 'DB_USER', + 'DB_HOST', + 'DB_PASSWORD', + 'AUTH_KEY', + 'SECURE_AUTH_KEY', + 'LOGGED_IN_KEY', + 'NONCE_KEY', + 'AUTH_SALT', + 'SECURE_AUTH_SALT', + 'LOGGED_IN_SALT', + 'NONCE_SALT' + ); + + foreach ($obsKeys as $key) { + if ($transformer->exists('constant', $key)) { + $transformer->update('constant', $key, '**OBSCURED**'); + } + } + + return $transformer->getSrc(); + } + + public function chunkStop($progressPerc, $position) + { + $this->closeDbConnection(); + + $ajax3_sum = DUPX_U::elapsedTime(DUPX_U::getMicrotime(), $this->timeStart); + Log::info("\nSTEP-3 CHUNK STOP @ " . @date('h:i:s') . " - RUNTIME: {$ajax3_sum} \n\n"); + + $this->report['chunk'] = 1; + $this->report['chunkPos'] = $position; + $this->report['pass'] = 0; + $this->report['progress_perc'] = $progressPerc; + } + + public function complete() + { + $this->closeDbConnection(); + + $paramsManager = PrmMng::getInstance(); + + $ajax3_sum = DUPX_U::elapsedTime(DUPX_U::getMicrotime(), $this->timeStart); + Log::info("\nSTEP-3 COMPLETE @ " . @date('h:i:s') . " - RUNTIME: {$ajax3_sum} \n\n"); + + $finalReport = $paramsManager->getValue(PrmMng::PARAM_FINAL_REPORT_DATA); + + $finalReport['replace']['scan_tables'] = $this->report['scan_tables']; + $finalReport['replace']['scan_rows'] = $this->report['scan_rows']; + $finalReport['replace']['scan_cells'] = $this->report['scan_cells']; + $finalReport['replace']['updt_tables'] = $this->report['updt_tables']; + $finalReport['replace']['updt_rows'] = $this->report['updt_rows']; + $finalReport['replace']['updt_cells'] = $this->report['updt_cells']; + $finalReport['replace']['errsql'] = $this->report['errsql']; + $finalReport['replace']['errser'] = $this->report['errser']; + $finalReport['replace']['errkey'] = $this->report['errkey']; + $finalReport['replace']['errsql_sum'] = $this->report['errsql_sum']; + $finalReport['replace']['errser_sum'] = $this->report['errser_sum']; + $finalReport['replace']['errkey_sum'] = $this->report['errkey_sum']; + $finalReport['replace']['err_all'] = $this->report['err_all']; + $finalReport['replace']['warn_all'] = $this->report['warn_all']; + $finalReport['replace']['warnlist'] = $this->report['warnlist']; + + $paramsManager->setValue(PrmMng::PARAM_FINAL_REPORT_DATA, $finalReport); + $paramsManager->save(); + + $this->report['pass'] = 1; + $this->report['chunk'] = 0; + $this->report['chunkPos'] = null; + $this->report['progress_perc'] = 100; + // error_reporting($ajax3_error_level); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s4.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s4.php new file mode 100644 index 0000000..41ae52d --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/classes/class.ctrl.s4.php @@ -0,0 +1,140 @@ +sortFinalReport(); + } + + public static function getNoticesCount() + { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + return array( + 'general' => $nManager->countFinalReportNotices('general', DUPX_NOTICE_ITEM::NOTICE, '>='), + 'files' => $nManager->countFinalReportNotices('files', DUPX_NOTICE_ITEM::NOTICE, '>='), + 'database' => $nManager->countFinalReportNotices('database', DUPX_NOTICE_ITEM::NOTICE, '>'), + 'search_replace' => $nManager->countFinalReportNotices('search_replace', DUPX_NOTICE_ITEM::NOTICE, '>='), + 'plugins' => $nManager->countFinalReportNotices('plugins', DUPX_NOTICE_ITEM::NOTICE, '>=') + ); + } + + protected static function finalReportDatabase() + { + $paramsManager = PrmMng::getInstance(); + $finalReportData = $paramsManager->getValue(PrmMng::PARAM_FINAL_REPORT_DATA); + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $logLink = DUPX_View_Funcs::installerLogLink(false); + $faqUrl = InstallerLinkManager::getDocUrl('how-to-fix-database-write-issues', 'final-report', 'How to Fix Database Write Issues'); + + if ($finalReportData['extraction']['query_errs'] > 0) { + $longMsg = <<
        + +COMMON FIXES: + +LONGMSG; + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'DB EXTRACTION - INSTALL NOTICES (' . $finalReportData['extraction']['query_errs'] . ')', + 'level' => DUPX_NOTICE_ITEM::HARD_WARNING, + 'longMsg' => $longMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => array('database'), + 'priority' => 5, + 'open' => true + )); + } + + if ($finalReportData['replace']['errsql_sum'] > 0) { + $longMsg = <<addFinalReportNotice(array( + 'shortMsg' => 'STEP 3 - UPDATE NOTICES (' . $finalReportData['replace']['errsql_sum'] . ')', + 'level' => DUPX_NOTICE_ITEM::HARD_WARNING, + 'longMsg' => $longMsg, + 'sections' => array('database'), + 'priority' => 5, + 'open' => true + )); + } + + if ($finalReportData['replace']['errkey_sum'] > 0) { + $longMsg = <<
        + + Advanced Searching:
        + Use the following query to locate the table that was not updated:
        + SELECT @row := @row + 1 as row, t.* FROM some_table t, (SELECT @row := 0) r +
        +LONGMSG; + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'TABLE KEY NOTICES (' . $finalReportData['replace']['errkey_sum'] . ')', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $longMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => array('database'), + 'priority' => 5, + 'open' => true + )); + } + } + + protected static function finalReportSearchReplace() + { + $paramsManager = PrmMng::getInstance(); + $finalReportData = $paramsManager->getValue(PrmMng::PARAM_FINAL_REPORT_DATA); + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + if ($finalReportData['replace']['errser_sum'] > 0) { + $longMsg = <<addFinalReportNotice(array( + 'shortMsg' => 'SERIALIZATION NOTICES (' . $finalReportData['replace']['errser_sum'] . ')', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => $longMsg, + 'sections' => array('search_replace'), + 'priority' => 5, + 'open' => true + )); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/ctrl.base.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/ctrl.base.php new file mode 100644 index 0000000..e08abb0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/ctrl.base.php @@ -0,0 +1,237 @@ +report = new DUPX_CTRL_Report(); + $this->payload = null; + $this->startProcessTime(); + } + + public function startProcessTime() + { + $this->timeStart = $this->microtimeFloat(); + } + + public function getProcessTime() + { + $this->timeEnd = $this->microtimeFloat(); + $this->report->runTime = $this->timeEnd - $this->timeStart; + return $this->report->runTime; + } + + private function microtimeFloat() + { + list($usec, $sec) = explode(" ", microtime()); + return ((float) $usec + (float) $sec); + } +} + +class DUPX_CTRL +{ + const ACTION_STEP_INIZIALIZED = 'initialized'; + const ACTION_STEP_ON_VALIDATE = 'on-validate'; + const ACTION_STEP_SET_TEMPLATE = 'settpm'; +/** + * + * @var self + */ + protected static $instance = null; +/** + * + * @var bool|string + */ + protected $pageView = false; +/** + * + * @var array + */ + protected $extraParamsPage = array(); +/** + * + * @return self + */ + public static function getInstance() + { + if (is_null(self::$instance)) { + self::$instance = new self(); + } + return self::$instance; + } + + private function __construct() + { + } + + public function mainController() + { + $paramsManager = PrmMng::getInstance(); + $ctrlAction = $paramsManager->getValue(PrmMng::PARAM_CTRL_ACTION); + $stepAction = $paramsManager->getValue(PrmMng::PARAM_STEP_ACTION); + Log::info("\n" . '---------------', Log::LV_DETAILED); + Log::info('CONTROLLER ACTION: ' . Log::v2str($ctrlAction), Log::LV_DETAILED); + if (!empty($stepAction)) { + Log::info('STEP ACTION: ' . Log::v2str($stepAction)); + } + Log::info('---------------' . "\n", Log::LV_DETAILED); + DUPX_Template::getInstance()->setTemplate(PrmMng::getInstance()->getValue(PrmMng::PARAM_TEMPLATE)); + if (Bootstrap::isInit()) { + if (!DUPX_Ctrl_Params::setParamsStep0()) { + Log::info('PARAMS AREN\'T VALID', Log::LV_DETAILED); + Log::error('PARAMS AREN\'T VALID'); + } + DUPX_Ctrl_S0::stepHeaderLog(); + } + + if ( + $ctrlAction !== 'help' && + DUPX_Security::getInstance()->getSecurityType() != DUPX_Security::SECURITY_NONE + ) { + Log::info('SECURE CHECK -> GO TO SECURE PAGE'); + $this->pageView = 'secure'; + return; + } + + switch ($ctrlAction) { + case "ctrl-step1": + if ($stepAction === DUPX_CTRL::ACTION_STEP_SET_TEMPLATE) { + $paramsManager->setValueFromInput(PrmMng::PARAM_TEMPLATE); + Log::info('NEW TEMPLATE:' . $paramsManager->getValue(PrmMng::PARAM_TEMPLATE)); + $paramsManager->save(); + DUPX_Template::getInstance()->setTemplate($paramsManager->getValue(PrmMng::PARAM_TEMPLATE)); + } + $this->pageView = 'step1'; + break; + case "ctrl-step2": + $this->pageView = 'step2'; + break; + case "ctrl-step3": + $this->pageView = 'step3'; + break; + case "ctrl-step4": + DUPX_Ctrl_S4::updateFinalReport(); + $this->pageView = 'step4'; + break; + case "help": + $this->pageView = 'help'; + break; + default: + Log::error('No valid action request ' . $ctrlAction); + } + } + + public function setExceptionPage(Exception $e) + { + Log::info("--------------------------------------"); + Log::info('EXCEPTION: ' . $e->getMessage()); + Log::info('TRACE:'); + Log::info($e->getTraceAsString()); + Log::info("--------------------------------------"); + $this->extraParamsPage['exception'] = $e; + $this->pageView = 'exception'; + } + + public function renderPage() + { + Log::logTime('RENDER PAGE ' . Log::v2str($this->pageView), Log::LV_DETAILED); + $echo = false; + $paramsManager = PrmMng::getInstance(); + $this->extraParamsPage['bodyClasses'] = 'template_' . $paramsManager->getValue(PrmMng::PARAM_TEMPLATE); + if ($paramsManager->getValue(PrmMng::PARAM_DEBUG_PARAMS)) { + $this->extraParamsPage['bodyClasses'] .= ' debug-params'; + } + + switch ($this->pageView) { + case 'secure': + $result = dupxTplRender('page-secure', $this->extraParamsPage, $echo); + break; + case 'step1': + $result = dupxTplRender('page-step1', $this->extraParamsPage, $echo); + break; + case 'step2': + $result = dupxTplRender('page-step2', $this->extraParamsPage, $echo); + break; + case 'step3': + $result = dupxTplRender('page-step3', $this->extraParamsPage, $echo); + break; + case 'step4': + $result = dupxTplRender('page-step4', $this->extraParamsPage, $echo); + DUPX_NOTICE_MANAGER::getInstance()->finalReportLog( + array('general', 'files', 'database', 'search_replace', 'plugins') + ); + break; + case 'exception': + $result = dupxTplRender('page-exception', $this->extraParamsPage, $echo); + break; + case 'help': + $result = dupxTplRender('page-help', $this->extraParamsPage, $echo); + break; + case false: + // no page + break; + default: + Log::error('No valid render page ' . Log::v2str($this->pageView)); + } + Log::logTime('END RENDER PAGE'); + return self::renderPostProcessings($result); + } + + public static function renderPostProcessings($string) + { + return str_replace(array( + DUPX_Package::getArchiveFileHash(), + DUPX_Package::getPackageHash()), '[HASH]', $string); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/index.php b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/ctrls/index.php @@ -0,0 +1,3 @@ + + + + + + #ffc40d + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_android-chrome-192x192.png b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_android-chrome-192x192.png new file mode 100644 index 0000000..5a53ec6 Binary files /dev/null and b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_android-chrome-192x192.png differ diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_android-chrome-256x256.png b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_android-chrome-256x256.png new file mode 100644 index 0000000..890596d Binary files /dev/null and b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_android-chrome-256x256.png differ diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_apple-touch-icon.png b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_apple-touch-icon.png new file mode 100644 index 0000000..1d67506 Binary files /dev/null and b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_apple-touch-icon.png differ diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon-16x16.png b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon-16x16.png new file mode 100644 index 0000000..4595182 Binary files /dev/null and b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon-16x16.png differ diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon-32x32.png b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon-32x32.png new file mode 100644 index 0000000..f5d420f Binary files /dev/null and b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon-32x32.png differ diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon.ico b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon.ico new file mode 100644 index 0000000..4575c3c Binary files /dev/null and b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_favicon.ico differ diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_mstile-150x150.png b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_mstile-150x150.png new file mode 100644 index 0000000..f12abe1 Binary files /dev/null and b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_mstile-150x150.png differ diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_safari-pinned-tab.svg b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_safari-pinned-tab.svg new file mode 100644 index 0000000..c896755 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/pro01_safari-pinned-tab.svg @@ -0,0 +1,40 @@ + + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/site.webmanifest b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/site.webmanifest new file mode 100644 index 0000000..b73d6e2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/favicon/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/dup-installer/favicon/pro01_android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/dup-installer/favicon/pro01_android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/index.php b/html/wp-content/plugins/duplicator/installer/dup-installer/index.php new file mode 100644 index 0000000..674e237 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/index.php @@ -0,0 +1,4 @@ + $ex->getMessage(), + 'trace' => $ex->getTraceAsString() + )); + die(); +} + +ob_start(); +try { + $controller = DUPX_CTRL::getInstance(); + $exceptionError = false; + // Log::error thotw an exception + Log::setThrowExceptionOnError(true); + Log::logTime('CONTROLLER START', Log::LV_DETAILED); + + $controller->mainController(); +} catch (Exception $e) { + SnapUtil::obCleanAll(false); + $controller->setExceptionPage($e); +} + +/** + * clean output + */ +$unespectOutput = trim(ob_get_clean()); +ob_end_clean(); +if (!empty($unespectOutput)) { + Log::info('ERROR: Unespect output ' . Log::v2str($unespectOutput)); + $exceptionError = new Exception('Unespected output ' . Log::v2str($unespectOutput)); + $controller->setExceptionPage($exceptionError); +} + +ob_start(); +try { + echo $controller->renderPage(); +} catch (Exception $e) { + SnapUtil::obCleanAll(false); + ob_end_clean(); + $controller->setExceptionPage($e); + echo $controller->renderPage(); +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/.htaccess b/html/wp-content/plugins/duplicator/installer/dup-installer/src/.htaccess new file mode 100644 index 0000000..a58990b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/.htaccess @@ -0,0 +1,9 @@ + + Order Deny,Allow + Deny from all + + + + Order Allow,Deny + Allow from all + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Addons/InstAbstractAddonCore.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Addons/InstAbstractAddonCore.php new file mode 100644 index 0000000..bb05b39 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Addons/InstAbstractAddonCore.php @@ -0,0 +1,254 @@ +addonData = self::getInitAddonData($reflect->getShortName()); + } + + /** + * Function called on addon init only if is avaiable + * + * @return void + */ + abstract public function init(); + + /** + * Get main addon file path + * + * @return string + */ + public static function getAddonFile() + { + // To prevent the warning about static abstract functions that appears in PHP 5.4/5.6 I use this trick. + throw new \Exception('this function have to overwritte on child class'); + } + + /** + * Get main addon folder + * + * @return string + */ + public static function getAddonPath() + { + // To prevent the warning about static abstract functions that appears in PHP 5.4/5.6 I use this trick. + throw new \Exception('this function have to overwritte on child class'); + } + + /** + * Get slug of current addon + * + * @return string + */ + public function getSlug() + { + return $this->addonData['slug']; + } + + /** + * True if current addon is avaiable + * + * @return boolean + */ + public function canEnable() + { + if (version_compare(PHP_VERSION, $this->addonData['requiresPHP'], '<')) { + return false; + } + + if (version_compare(DUPX_VERSION, $this->addonData['requiresDuplcator'], '<')) { + return false; + } + + return true; + } + + /** + * True if addon has dependencies + * + * @return boolean + */ + public function hasDependencies() + { + $avaliableAddons = InstAddonsManager::getInstance()->getAvaiableAddons(); + return !array_diff($this->addonData['requiresAddons'], $avaliableAddons); + } + + /** + * Get addon data from header addon file + * + * @param string $class addon class + * + * @return array + */ + protected static function getInitAddonData($class) + { + $data = self::getFileFata(static::getAddonFile(), self::getDefaltHeaders()); + $getDefaultVal = self::getDefaultHeadersValues(); + + foreach ($data as $key => $val) { + if (strlen($val) === 0) { + $data[$key] = $getDefaultVal[$key]; + } + } + + if (!is_array($data['requiresAddons'])) { + $data['requiresAddons'] = explode(',', $data['requiresAddons']); + } + $data['requiresAddons'] = array_map('trim', $data['requiresAddons']); + + $data['slug'] = $class; + if (strlen($data['name']) === 0) { + $data['name'] = $data['slug']; + } + return $data; + } + + /** + * Retur default addon date headers + * + * @return array + */ + protected static function getDefaultHeadersValues() + { + static $defaultHeaders = null; + if (is_null($defaultHeaders)) { + $defaultHeaders = array( + 'name' => '', + 'addonURI' => '', + 'version' => '0', + 'description' => '', + 'author' => '', + 'authorURI' => '', + 'requiresWP' => '5.3', + 'requiresPHP' => '7.4', + 'requiresDuplcator' => '4.5.20', + 'requiresAddons' => array() + ); + } + return $defaultHeaders; + } + + /** + * Return headers list keys + * + * @return array + */ + protected static function getDefaltHeaders() + { + return array( + 'name' => 'Name', + 'addonURI' => 'Addon URI', + 'version' => 'Version', + 'description' => 'Description', + 'author' => 'Author', + 'authorURI' => 'Author URI', + 'requiresWP' => 'Requires WordPress min version', + 'requiresPHP' => 'Requires PHP', + 'requiresDuplcator' => 'Requires Duplicator min version', + 'requiresAddons' => 'Requires addons' + ); + } + + /** + * Retrieve metadata from a file. + * + * Searches for metadata in the first 8 KB of a file, such as a plugin or theme. + * Each piece of metadata must be on its own line. Fields can not span multiple + * lines, the value will get cut at the end of the first line. + * + * If the file data is not within that first 8 KB, then the author should correct + * their plugin file and move the data headers to the top. + * + * from wordpress get_file_data function + * + * @param string $file Absolute path to the file. + * @param array $defaultHeaders List of headers, in the format `array( 'HeaderKey' => 'Header Name' )`. + * + * @return array Array of file headers in `HeaderKey => Header Value` format. + */ + protected static function getFileFata($file, $defaultHeaders) + { + // We don't need to write to the file, so just open for reading. + $fp = fopen($file, 'r'); + + // Pull only the first 8 KB of the file in. + $file_data = fread($fp, 8 * KB_IN_BYTES); + + // PHP will close file handle, but we are good citizens. + fclose($fp); + + // Make sure we catch CR-only line endings. + $file_data = str_replace("\r", "\n", $file_data); + $all_headers = $defaultHeaders; + + foreach ($all_headers as $field => $regex) { + if (preg_match('/^[ \t\/*#@]*' . preg_quote($regex, '/') . ':(.*)$/mi', $file_data, $match) && $match[1]) { + $all_headers[$field] = self::cleanupHeaderComment($match[1]); + } else { + $all_headers[$field] = ''; + } + } + + return $all_headers; + } + + /** + * Strip close comment and close php tags from file headers used by WP. + * + * From wordpress _cleanup_header_comment + * + * @param string $str Header comment to clean up. + * + * @return string + */ + protected static function cleanupHeaderComment($str) + { + return trim(preg_replace('/\s*(?:\*\/|\?>).*/', '', $str)); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Addons/InstAddonsManager.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Addons/InstAddonsManager.php new file mode 100644 index 0000000..8ae8f1b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Addons/InstAddonsManager.php @@ -0,0 +1,178 @@ +addons = self::getAddonListFromFolder(); + } + + /** + * inizialize all abaiblae addons + * + * @return void + */ + public function inizializeAddons() + { + foreach ($this->addons as $addon) { + if ($addon->canEnable() && $addon->hasDependencies()) { + $this->enabledAddons[] = $addon->getSlug(); + $addon->init(); + Log::info('ADDON ' . $addon->getAddonFile() . ' ENABLED', Log::LV_DETAILED); + } else { + Log::info('CAN\'T ENABLE ADDON ' . $addon->getSlug()); + } + } + HooksMng::getInstance()->doAction('duplicator_addons_loaded'); + } + + /** + * + * @return InstAbstractAddonCore[] + */ + public function getAvaiableAddons() + { + $result = array(); + foreach ($this->addons as $addon) { + $result[] = $addon->getSlug(); + } + + return $result; + } + + /** + * + * @return InstAbstractAddonCore[] + */ + public function getEnabledAddons() + { + return $this->enabledAddons; + } + + /** + * return addons folder + * + * @return string + */ + public static function getAddonsPath() + { + return DUPX_INIT . '/addons'; + } + + /** + * + * @return InstAbstractAddonCore[] + */ + private static function getAddonListFromFolder() + { + $addonList = array(); + + $checkDir = SnapIO::trailingslashit(self::getAddonsPath()); + + if (!is_dir($checkDir)) { + return array(); + } + + if (($dh = opendir($checkDir)) == false) { + return array(); + } + + while (($elem = readdir($dh)) !== false) { + if ($elem === '.' || $elem === '..') { + continue; + } + + $fullPath = $checkDir . $elem; + $addonMainFile = false; + + if (!is_dir($fullPath)) { + continue; + } + + if (($addonDh = opendir($fullPath)) == false) { + continue; + } + + while (($addonElem = readdir($addonDh)) !== false) { + if ($addonElem === '.' || $addonElem === '..') { + continue; + } + $info = pathinfo($fullPath . '/' . $addonElem); + + if (strcasecmp($elem, $info['filename']) === 0) { + $addonMainFile = $checkDir . $elem . '/' . $addonElem; + $addonMainClass = 'Duplicator\\Installer\\Addons\\' . $info['filename'] . '\\' . $info['filename']; + break; + } + } + + if (empty($addonMainFile)) { + continue; + } + + try { + if (!is_subclass_of($addonMainClass, 'Duplicator\\Installer\\Core\\Addons\\InstAbstractAddonCore')) { + continue; + } + } catch (\Exception $e) { + Log::info('Addon file ' . $addonMainFile . ' exists but not countain addon main core class, Exception: ' . $e->getMessage()); + continue; + } catch (\Error $e) { + Log::info('Addon file ' . $addonMainFile . ' exists but generate an error, Exception: ' . $e->getMessage()); + continue; + } + + $addonObj = $addonMainClass::getInstance(); + $addonList[$addonObj->getSlug()] = $addonObj; + } + closedir($dh); + + return $addonList; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Bootstrap.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Bootstrap.php new file mode 100644 index 0000000..0be9ae5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Bootstrap.php @@ -0,0 +1,538 @@ +inizializeAddons(); + // init templates + self::templatesInit(); + // SECURITY CHECK + \DUPX_Security::getInstance()->check(); + // init error handler after constant + LogHandler::initErrorHandler(); + + // init params + PrmMng::getInstance()->initParams(); + + // read params from request and init global value + self::initInstallerFiles(); + + // check custom hosts + \DUPX_Custom_Host_Manager::getInstance()->init(); + + $pathInfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; + Log::info("\n\n" + . "==============================================\n" + . "= BOOT INIT OK [" . $pathInfo . "]\n" + . "==============================================\n", Log::LV_DETAILED); + + if (Log::isLevel(Log::LV_DEBUG)) { + Log::info('-------------------'); + Log::info('PARAMS'); + Log::info(PrmMng::getInstance()->getParamsToText()); + Log::info('-------------------'); + } + + \DUPX_DB_Tables::getInstance(); + } + + /** + * Init ini_set and default constants + * + * @return void + */ + public static function phpIni() + { + /* Absolute path to the Installer directory. - necessary for php protection */ + if (!defined('KB_IN_BYTES')) { + define('KB_IN_BYTES', 1024); + } + if (!defined('MB_IN_BYTES')) { + define('MB_IN_BYTES', 1024 * KB_IN_BYTES); + } + if (!defined('GB_IN_BYTES')) { + define('GB_IN_BYTES', 1024 * MB_IN_BYTES); + } + if (!defined('DUPLICATOR_PHP_MAX_MEMORY')) { + define('DUPLICATOR_PHP_MAX_MEMORY', 4096 * MB_IN_BYTES); + } + + date_default_timezone_set('UTC'); // Some machines don’t have this set so just do it here. + @ignore_user_abort(true); + + @set_time_limit(3600); + + $defaultCharset = ini_get("default_charset"); + if (empty($defaultCharset) && SnapUtil::isIniValChangeable('default_charset')) { + @ini_set("default_charset", 'utf-8'); + } + if (SnapUtil::isIniValChangeable('memory_limit')) { + @ini_set('memory_limit', DUPLICATOR_PHP_MAX_MEMORY); + } + if (SnapUtil::isIniValChangeable('max_input_time')) { + @ini_set('max_input_time', '-1'); + } + if (SnapUtil::isIniValChangeable('pcre.backtrack_limit')) { + @ini_set('pcre.backtrack_limit', PHP_INT_MAX); + } + + //PHP INI SETUP: all time in seconds + if (!isset($GLOBALS['DUPX_ENFORCE_PHP_INI']) || !$GLOBALS['DUPX_ENFORCE_PHP_INI']) { + if (SnapUtil::isIniValChangeable('mysql.connect_timeout')) { + @ini_set('mysql.connect_timeout', '5000'); + } + if (SnapUtil::isIniValChangeable('max_execution_time')) { + @ini_set("max_execution_time", '5000'); + } + if (SnapUtil::isIniValChangeable('max_input_time')) { + @ini_set("max_input_time", '5000'); + } + if (SnapUtil::isIniValChangeable('default_socket_timeout')) { + @ini_set('default_socket_timeout', '5000'); + } + @set_time_limit(0); + } + } + + /** + * Include default utils files and constants + * + * @return void + */ + public static function includes() + { + require_once(DUPX_INIT . '/vendor/requests/library/Requests.php'); + \Requests::register_autoloader(); + + require_once(DUPX_INIT . '/classes/config/class.conf.wp.php'); + require_once(DUPX_INIT . '/classes/utilities/class.u.php'); + require_once(DUPX_INIT . '/classes/utilities/class.u.notices.manager.php'); + require_once(DUPX_INIT . '/classes/utilities/template/class.u.template.manager.php'); + require_once(DUPX_INIT . '/classes/utilities/class.u.orig.files.manager.php'); + require_once(DUPX_INIT . '/classes/validation/class.validation.manager.php'); + require_once(DUPX_INIT . '/classes/config/class.security.php'); + require_once(DUPX_INIT . '/classes/plugins/class.plugins.manager.php'); + require_once(DUPX_INIT . '/classes/class.password.php'); + require_once(DUPX_INIT . '/classes/database/class.db.php'); + require_once(DUPX_INIT . '/classes/database/class.db.functions.php'); + require_once(DUPX_INIT . '/classes/database/class.db.tables.php'); + require_once(DUPX_INIT . '/classes/database/class.db.table.item.php'); + require_once(DUPX_INIT . '/classes/class.http.php'); + require_once(DUPX_INIT . '/classes/class.crypt.php'); + require_once(DUPX_INIT . '/classes/class.csrf.php'); + require_once(DUPX_INIT . '/classes/class.package.php'); + require_once(DUPX_INIT . '/classes/class.server.php'); + require_once(DUPX_INIT . '/classes/rest/class.rest.php'); + require_once(DUPX_INIT . '/classes/rest/class.rest.auth.php'); + require_once(DUPX_INIT . '/classes/config/class.archive.config.php'); + require_once(DUPX_INIT . '/classes/config/class.constants.php'); + require_once(DUPX_INIT . '/classes/config/class.conf.utils.php'); + require_once(DUPX_INIT . '/classes/class.installer.state.php'); + require_once(DUPX_INIT . '/ctrls/classes/class.ctrl.ajax.php'); + require_once(DUPX_INIT . '/ctrls/classes/class.ctrl.params.php'); + require_once(DUPX_INIT . '/ctrls/ctrl.base.php'); + require_once(DUPX_INIT . '/ctrls/classes/class.ctrl.extraction.php'); + require_once(DUPX_INIT . '/ctrls/classes/class.ctrl.dbinstall.php'); + require_once(DUPX_INIT . '/ctrls/classes/class.ctrl.s3.funcs.php'); + require_once(DUPX_INIT . '/classes/view-helpers/class.u.html.php'); + require_once(DUPX_INIT . '/classes/view-helpers/class.view.php'); + require_once(DUPX_INIT . '/classes/host/class.custom.host.manager.php'); + require_once(DUPX_INIT . '/classes/config/class.conf.srv.php'); + require_once(DUPX_INIT . '/classes/class.engine.php'); + } + + /** + * This function moves the error_log.php into the dup-installer directory. + * It is called before including any other file so it uses only native PHP functions. + * + * !!! Don't use any Duplicator function within this function. !!! + * + * @param bool $reset if true reset log file + * + * @return boolean + */ + public static function initPhpErrorLog($reset = false) + { + if (!function_exists('ini_set')) { + return false; + } + + $logFile = DUPX_INIT . '/php_error__' . self::getPackageHash() . '.log'; + + if (file_exists($logFile)) { + if (!is_writable($logFile)) { + return false; + } elseif ($reset && function_exists('unlink')) { + @unlink($logFile); + } + } + + if (function_exists('error_reporting')) { + error_reporting(E_ALL); + } + + @ini_set("log_errors", 1); + if (@ini_set("error_log", $logFile) === false) { + return false; + } + + if (!file_exists($logFile)) { + SnapUtil::errorLog("PHP ERROR LOG INIT"); + } + + return true; + } + + /** + * It is called before including any other file so it uses only native PHP functions. + * + * !!! Don't use any Duplicator function within this function. !!! + * + * @return bool|string package hash or false if fail + */ + public static function getPackageHash() + { + static $packageHash = null; + if (is_null($packageHash)) { + $searchStr = DUPX_INIT . '/' . self::ARCHIVE_PREFIX . '*' . self::ARCHIVE_EXTENSION; + $config_files = glob($searchStr); + if (empty($config_files)) { + $packageHash = false; + } else { + $config_file_absolute_path = array_pop($config_files); + $config_file_name = basename($config_file_absolute_path, self::ARCHIVE_EXTENSION); + $packageHash = substr($config_file_name, strlen(self::ARCHIVE_PREFIX)); + } + } + return $packageHash; + } + + /** + * This function init all params before read from request + * + * @return void + */ + protected static function initParamsBase() + { + // GET PARAMS FROM REQUEST + \DUPX_Ctrl_Params::setParamsBase(); + + // set log level from params + Log::setLogLevel(); + Log::setPostProcessCallback(array('DUPX_CTRL', 'renderPostProcessings')); + Log::setAfterFatalErrorCallback(function () { + if (\DUPX_InstallerState::getInstance()->getMode() === \DUPX_InstallerState::MODE_OVR_INSTALL) { + \DUPX_U::maintenanceMode(false); + } + }); + + $paramsManager = PrmMng::getInstance(); + $GLOBALS['DUPX_DEBUG'] = $paramsManager->getValue(PrmMng::PARAM_DEBUG); + } + + /** + * Makes sure no caching mechanism is used during install + * + * @return void + */ + protected static function setHTTPHeaders() + { + header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + } + + /** + * Init log header + * + * @return void + */ + protected static function initLogs() + { + if (!chdir(DUPX_INIT)) { + // RSR TODO: Can't change directories + throw new \Exception("Can't change to directory " . DUPX_INIT); + } + + //Restart log if user starts from step 0 + if (self::isInit()) { + self::initPhpErrorLog(true); + Log::clearLog(); + Log::info("********************************************************************************"); + Log::info('* DUPLICATOR LITE: Install-Log'); + Log::info('* STEP-0 START @ ' . @date('h:i:s')); + Log::info('* NOTICE: Do NOT post to public sites or forums!!'); + Log::info("********************************************************************************"); + } + } + + /** + * Init all installer files + * + * @return void + */ + protected static function initInstallerFiles() + { + if (!chdir(DUPX_INIT)) { + // RSR TODO: Can't change directories + throw new \Exception("Can't change to directory " . DUPX_INIT); + } + + //Restart log if user starts from step 0 + if (self::isInit()) { + self::logHeader(); + \DUPX_NOTICE_MANAGER::getInstance()->resetNotices(); + + // LOAD PARAMS AFTER LOG RESET + $paramManager = PrmMng::getInstance(); + $paramManager->load(true); + \DUPX_Orig_File_Manager::getInstance()->init(false); + try { + \DUPX_Orig_File_Manager::getInstance()->restoreAll(array( + \DUPX_ServerConfig::CONFIG_ORIG_FILE_USERINI_ID, + \DUPX_ServerConfig::CONFIG_ORIG_FILE_PHPINI_ID, + \DUPX_ServerConfig::CONFIG_ORIG_FILE_WEBCONFIG_ID, + \DUPX_ServerConfig::CONFIG_ORIG_FILE_HTACCESS_ID, + \DUPX_ServerConfig::CONFIG_ORIG_FILE_WPCONFIG_ID + )); + } catch (\Exception $e) { + Log::logException($e, 'CANT RESTORE CONFIG FILES FORM PREVISION INSTALLATION'); + \DUPX_NOTICE_MANAGER::getInstance()->addNextStepNotice(array( + 'shortMsg' => 'The installer cannot restore files from a previous installation. ', + 'longMsg' => 'This problem does not affect the current installation so you can continue.
        ' + . 'This can happen if the root folder does not have write permissions.', + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'level' => \DUPX_NOTICE_ITEM::NOTICE + )); + } + + self::initParamsBase(); + + \DUP_Extraction::resetData(); + \DUPX_DBInstall::resetData(); + \DUPX_S3_Funcs::resetData(); + + // update state only if isn't set by param overwrite + \DUPX_InstallerState::getInstance()->checkState(true, false); + // On init remove maintenance mode + \DUPX_U::maintenanceMode(false); + } else { + // INIT PARAMS + $paramManager = PrmMng::getInstance(); + $paramManager->load(); + \DUPX_Orig_File_Manager::getInstance()->init(false); + + self::initParamsBase(); + } + + $paramManager->save(); + } + + /** + * Write log header + * + * @return void + */ + protected static function logHeader() + { + $archiveConfig = \DUPX_ArchiveConfig::getInstance(); + $colSize = 60; + $labelPadSize = 20; + $os = defined('PHP_OS') ? PHP_OS : 'unknown'; + + $log = ''; + $log .= str_pad( + str_pad('PACKAGE INFO', $labelPadSize, '_', STR_PAD_RIGHT) . ' ' . 'ORIGINAL SERVER', + $colSize, + ' ', + STR_PAD_RIGHT + ) . '|' . 'CURRENT SERVER' . "\n"; + $log .= str_pad( + str_pad('OS', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->version_os, + $colSize, + ' ', + STR_PAD_RIGHT + ) . '|' . $os . "\n"; + $log .= str_pad( + str_pad('PHP VERSION', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $archiveConfig->version_php, + $colSize, + ' ', + STR_PAD_RIGHT + ) . '|' . phpversion() . "\n"; + $log .= "********************************************************************************"; + Log::info($log, Log::LV_DEFAULT); + + Log::info("CURRENT SERVER INFO"); + Log::info(str_pad('PHP', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . phpversion() . ' | SAPI: ' . php_sapi_name()); + Log::info(str_pad('PHP MEMORY', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $GLOBALS['PHP_MEMORY_LIMIT'] . ' | SUHOSIN: ' . $GLOBALS['PHP_SUHOSIN_ON']); + Log::info(str_pad('ARCHITECTURE', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . SnapUtil::getArchitectureString()); + Log::info(str_pad('SERVER', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . $_SERVER['SERVER_SOFTWARE']); + Log::info(str_pad('DOC ROOT', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str(DUPX_ROOT)); + Log::info(str_pad('REQUEST URL', $labelPadSize, '_', STR_PAD_RIGHT) . ': ' . Log::v2str(DUPX_ROOT_URL)); + Log::info("********************************************************************************"); + } + + /** + * return true if is the first installer call from installer.php + * + * @return bool + */ + public static function isInit() + { + // don't use param manager because isn't initialized + $isFirstStep = isset($_REQUEST[PrmMng::PARAM_CTRL_ACTION]) && $_REQUEST[PrmMng::PARAM_CTRL_ACTION] === "ctrl-step1"; + $isInitialized = isset($_REQUEST[PrmMng::PARAM_STEP_ACTION]) && !empty($_REQUEST[PrmMng::PARAM_STEP_ACTION]); + return $isFirstStep && !$isInitialized; + } + + /** + * This function disables the shutdown function defined in the boot class + * + * @return void + */ + public static function disableBootShutdownFunction() + { + self::$shutdownFunctionEnaled = false; + } + + /** + * This function sets the shutdown function before the installer is initialized. + * Prevents blank pages. + * + * After the plugin is initialized it will be set as a shudwon ​​function LogHandler::shutdown + * + * !!! Don't use any Duplicator function within this function. !!! + * + * @return void + */ + public static function bootShutdown() + { + if (!self::$shutdownFunctionEnaled) { + return; + } + + if (($error = error_get_last())) { + ?> +

        BOOT SHUTDOWN FATAL ERROR

        +
        + =')) { + return true; + } + $match = null; + if (preg_match("#^\d+(\.\d+)*#", PHP_VERSION, $match)) { + $phpVersion = $match[0]; + } else { + $phpVersion = PHP_VERSION; + } + // no html + echo 'This server is running PHP: ' . $phpVersion . '. A minimum of PHP ' . self::MINIMUM_PHP_VERSION . ' is required to run the installer.' + . ' Contact your hosting provider or server administrator and let them know you would like to upgrade your PHP version.'; + die(); + } + + /** + * Init templates + * + * @return void + */ + protected static function templatesInit() + { + $tpl = \DUPX_Template::getInstance(); + + $tpl->addTemplate(\DUPX_Template::TEMPLATE_BASE, DUPX_INIT . '/templates/base', \DUPX_Template::TEMPLATE_ADVANCED); + $tpl->addTemplate(\DUPX_Template::TEMPLATE_IMPORT_ADVANCED, DUPX_INIT . '/templates/import-advanced', \DUPX_Template::TEMPLATE_ADVANCED); + $tpl->addTemplate(\DUPX_Template::TEMPLATE_IMPORT_BASE, DUPX_INIT . '/templates/import-base', \DUPX_Template::TEMPLATE_IMPORT_ADVANCED); + + $tpl->setTemplate(\DUPX_Template::TEMPLATE_ADVANCED); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbCleanup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbCleanup.php new file mode 100644 index 0000000..3c5096f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbCleanup.php @@ -0,0 +1,334 @@ +getValue(PrmMng::PARAM_DB_VIEW_CREATION)) { + self::dropViews(); + Log::info("\t- VIEWS DROPPED"); + } else { + Log::info("\t- SKIP DROP VIEWS"); + } + + if (!$paramsManager->getValue(PrmMng::PARAM_DB_PROC_CREATION)) { + self::dropProcs(); + Log::info("\t- PROCS DROPPED"); + } else { + Log::info("\t- SKIP DROP PROCS"); + } + + if (!$paramsManager->getValue(PrmMng::PARAM_DB_FUNC_CREATION)) { + self::dropFuncs(); + Log::info("\t- FUNCS DROPPED"); + } else { + Log::info("\t- SKIP DROP FUNCS"); + } + } + + /** + * Cleanup packages + * + * @return void + */ + public static function cleanupPackages() + { + if (DUPX_InstallerState::isRestoreBackup()) { + Log::info("REMOVE CURRENT PACKAGE IN BACKUP"); + self::deletePackageInBackup(); + } else { + Log::info("EMPTY PACKAGES TABLE"); + self::emptyDuplicatorPackages(); + } + } + + /** + * Cleanup options tables (remove transientes ..) + * + * @return int return number of items deleted + */ + public static function cleanupOptions() + { + if (DUPX_InstallerState::isRestoreBackup()) { + return; + } + + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + $optionsTableList = array(); + $deleteOptionConds = array(); + + $optionsTableList[] = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getOptionsTableName()); + $deleteOptionConds[] = '`option_name` = "duplicator_plugin_data_stats"'; + $deleteOptionConds[] = '`option_name` LIKE "\_transient%"'; + $deleteOptionConds[] = '`option_name` LIKE "\_site\_transient%"'; + + $opts_delete = array(); + foreach ($archiveConfig->opts_delete as $value) { + $opts_delete[] = '"' . mysqli_real_escape_string($dbh, $value) . '"'; + } + if (count($opts_delete) > 0) { + $deleteOptionConds[] = '`option_name` IN (' . implode(',', $opts_delete) . ')'; + } + + $count = 0; + foreach ($optionsTableList as $optionsTable) { + $log = "CLEAN OPTIONS [" . $optionsTable . "]"; + foreach ($deleteOptionConds as $cond) { + $log .= "\n\t" . $cond; + } + Log::info($log); + $count += DUPX_DB::chunksDelete($dbh, $optionsTable, implode(' OR ', $deleteOptionConds)); + Log::info(sprintf('DATABASE OPTIONS DELETED [ROWS:%6d]', $count)); + } + return $count; + } + + /** + * Delete current package in backup + * + * @return void + */ + protected static function deletePackageInBackup() + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $packageId = DUPX_ArchiveConfig::getInstance()->packInfo->packageId; + Log::info("CLEANUP CURRENT PACKAGE STATUS ID " . $packageId); + + $packagesTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getPackagesTableName()); + $optionsTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getOptionsTableName()); + DUPX_DB::mysqli_query($dbh, 'DELETE FROM `' . $packagesTable . '` WHERE `id` = ' . $packageId); + DUPX_DB::mysqli_query($dbh, "DELETE FROM `" . $optionsTable . "` WHERE `option_name` = 'duplicator_package_active'"); + } + + /** + * Empty duplicator packages table + * + * @return int return number of packages deleted + */ + protected static function emptyDuplicatorPackages() + { + Log::info("CLEAN PACKAGES"); + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $packagesTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getPackagesTableName()); + $count = DUPX_DB::chunksDelete($dbh, $packagesTable, '1 = 1'); + Log::info('DATABASE PACKAGE DELETED [ROWS:' . str_pad($count, 6, " ", STR_PAD_LEFT) . ']'); + return$count; + } + + + /** + * Drop db procedures + * + * @return void + */ + public static function dropProcs() + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $dbName = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME); + + $sql = "SHOW PROCEDURE STATUS WHERE db='{$dbName}'"; + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + if (!($result = DUPX_DB::mysqli_query($dbh, $sql))) { + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'PROCEDURE CLEAN ERROR: ' . mysqli_error($dbh), + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to get list of PROCEDURES from database "%s".', $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database', + )); + + Log::info("PROCEDURE CLEAN ERROR: Could not get list of PROCEDURES to drop them."); + return; + } + + if ($result->num_rows === 0) { + return; + } + + while ($row = mysqli_fetch_row($result)) { + $proc_name = $row[1]; + $sql = "DROP PROCEDURE IF EXISTS `" . mysqli_real_escape_string($dbh, $dbName) . "`.`" . mysqli_real_escape_string($dbh, $proc_name) . "`"; + if (!DUPX_DB::mysqli_query($dbh, $sql)) { + $err = mysqli_error($dbh); + $nManager->addNextStepNotice(array( + 'shortMsg' => 'PROCEDURE CLEAN ERROR', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to remove PROCEDURE "%s" from database "%s".
        ', $proc_name, $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'drop-proc-fail-msg'); + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'PROCEDURE CLEAN ERROR: ' . $err, + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to remove PROCEDURE "%s" from database "%s".', $proc_name, $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database', + )); + + Log::info("PROCEDURE CLEAN ERROR: '{$err}'\n\t[SQL=" . substr($sql, 0, DUPX_DBInstall::QUERY_ERROR_LOG_LEN) . "...]\n\n"); + } + } + + $nManager->addNextStepNotice(array( + 'shortMsg' => 'PROCEDURE CLEAN ERROR', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf(ERR_DROP_PROCEDURE_TRYCLEAN, mysqli_error($dbh)), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, 'drop-proc-fail-msg'); + } + + /** + * Drop db functions + * + * @return void + */ + public static function dropFuncs() + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $dbName = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME); + + $sql = "SHOW FUNCTION STATUS WHERE db='{$dbName}'"; + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + if (!($result = DUPX_DB::mysqli_query($dbh, $sql))) { + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'FUNCTION CLEAN ERROR: ' . mysqli_error($dbh), + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to get list of FUNCTIONS from database "%s".', $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database', + )); + + Log::info("FUNCTION CLEAN ERROR: Could not get list of FUNCTIONS to drop them."); + return; + } + + if ($result->num_rows === 0) { + return; + } + + while ($row = mysqli_fetch_row($result)) { + $func_name = $row[1]; + $sql = "DROP FUNCTION IF EXISTS `" . mysqli_real_escape_string($dbh, $dbName) . "`.`" . mysqli_real_escape_string($dbh, $func_name) . "`"; + if (!DUPX_DB::mysqli_query($dbh, $sql)) { + $err = mysqli_error($dbh); + $nManager->addNextStepNotice(array( + 'shortMsg' => 'FUNCTION CLEAN ERROR', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to remove FUNCTION "%s" from database "%s".
        ', $func_name, $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'drop-func-fail-msg'); + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'FUNCTION CLEAN ERROR: ' . $err, + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to remove FUNCTION "%s" from database "%s".', $func_name, $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database', + )); + + Log::info("FUNCTION CLEAN ERROR: '{$err}'\n\t[SQL=" . substr($sql, 0, DUPX_DBInstall::QUERY_ERROR_LOG_LEN) . "...]\n\n"); + } + } + + $nManager->addNextStepNotice(array( + 'shortMsg' => 'FUNCTION CLEAN ERROR', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf(ERR_DROP_FUNCTION_TRYCLEAN, mysqli_error($dbh)), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, 'drop-func-fail-msg'); + } + + /** + * Drop db views + * + * @return void + */ + public static function dropViews() + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $dbName = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME); + + $sql = "SHOW FULL TABLES WHERE Table_Type = 'VIEW'"; + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + if (!($result = DUPX_DB::mysqli_query($dbh, $sql))) { + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'VIEW CLEAN ERROR: ' . mysqli_error($dbh), + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to get list of VIEWS from database "%s"', $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database', + )); + + Log::info("VIEW CLEAN ERROR: Could not get list of VIEWS to drop them."); + return; + } + + if ($result->num_rows === 0) { + return; + } + + while ($row = mysqli_fetch_row($result)) { + $view_name = $row[0]; + $sql = "DROP VIEW `" . mysqli_real_escape_string($dbh, $dbName) . "`.`" . mysqli_real_escape_string($dbh, $view_name) . "`"; + if (!DUPX_DB::mysqli_query($dbh, $sql)) { + $err = mysqli_error($dbh); + + $nManager->addNextStepNotice(array( + 'shortMsg' => 'VIEW CLEAN ERROR', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to remove VIEW "%s" from database "%s".
        ', $view_name, $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'drop-view-fail-msg'); + + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'VIEW CLEAN ERROR: ' . $err, + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf('Unable to remove VIEW "%s" from database "%s"', $view_name, $dbName), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'database', + )); + + Log::info("VIEW CLEAN ERROR: '{$err}'\n\t[SQL=" . substr($sql, 0, DUPX_DBInstall::QUERY_ERROR_LOG_LEN) . "...]\n\n"); + } + } + + $nManager->addNextStepNotice(array( + 'shortMsg' => 'VIEW CLEAN ERROR', + 'level' => DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => sprintf(ERR_DROP_VIEW_TRYCLEAN, mysqli_error($dbh)), + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + ), DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, 'drop-view-fail-msg'); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbReplace.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbReplace.php new file mode 100644 index 0000000..723d278 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbReplace.php @@ -0,0 +1,250 @@ +mainUrlOld = $prmMng->getValue(PrmMng::PARAM_URL_OLD); + $this->mainUrlNew = $prmMng->getValue(PrmMng::PARAM_URL_NEW); + } + + /** + * Set search and replace strings + * + * @return bool + */ + public function setSearchReplace() + { + switch (DUPX_InstallerState::getInstType()) { + case DUPX_InstallerState::INSTALL_SINGLE_SITE: + $this->setGlobalSearchAndReplaceList(); + break; + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBDOMAIN: + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBFOLDER: + throw new Exception('mode not avaiable'); + case DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE: + throw new Exception('Replace engine isn\'t avaiable for restore backup mode'); + case DUPX_InstallerState::INSTALL_NOT_SET: + default: + throw new Exception('Invalid installer mode'); + } + + return true; + } + + /** + * Set global search replace + * + * @return void + */ + private function setGlobalSearchAndReplaceList() + { + $srManager = DUPX_S_R_MANAGER::getInstance(); + $paramsManager = PrmMng::getInstance(); + + // DIRS PATHS + $this->addReplaceEnginePaths($srManager); + + Log::info('GLOBAL SEARCH REPLACE ', Log::LV_DETAILED); + + if ( + !DUPX_InstallerState::isInstallerCreatedInThisLocation() + ) { + $uploadUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_UPLOADS_OLD); + $uploadUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_UPLOADS_NEW); + + if (self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $uploadUrlOld, $uploadUrlNew)) { + $srManager->addItem($uploadUrlOld, $uploadUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + + $siteUrlOld = $paramsManager->getValue(PrmMng::PARAM_SITE_URL_OLD); + $siteUrlNew = $paramsManager->getValue(PrmMng::PARAM_SITE_URL); + if (self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $siteUrlOld, $siteUrlNew)) { + $srManager->addItem($siteUrlOld, $siteUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); + } + + $srManager->addItem($this->mainUrlOld, $this->mainUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); + } + + $pluginsUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_PLUGINS_OLD); + $pluginsUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_PLUGINS_NEW); + if ( + $this->forceReplaceSiteSubfolders || + self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $pluginsUrlOld, $pluginsUrlNew) + ) { + $srManager->addItem($pluginsUrlOld, $pluginsUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + + $mupluginsUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_MUPLUGINS_OLD); + $mupluginsUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_MUPLUGINS_NEW); + if ( + $this->forceReplaceSiteSubfolders || + self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $mupluginsUrlOld, $mupluginsUrlNew) + ) { + $srManager->addItem($mupluginsUrlOld, $mupluginsUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + + $contentUrlOld = $paramsManager->getValue(PrmMng::PARAM_URL_CONTENT_OLD); + $contentUrlNew = $paramsManager->getValue(PrmMng::PARAM_URL_CONTENT_NEW); + if ( + $this->forceReplaceSiteSubfolders || + self::checkRelativeAndAbsoluteDiff($this->mainUrlOld, $this->mainUrlNew, $contentUrlOld, $contentUrlNew) + ) { + $srManager->addItem($contentUrlOld, $contentUrlNew, DUPX_S_R_ITEM::TYPE_URL_NORMALIZE_DOMAIN, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P2); + } + + // Replace email address (xyz@oldomain.com to xyz@newdomain.com). + if ($paramsManager->getValue(PrmMng::PARAM_EMAIL_REPLACE)) { + $at_old_domain = '@' . DUPX_U::getDomain($this->mainUrlOld); + $at_new_domain = '@' . DUPX_U::getDomain($this->mainUrlNew); + $srManager->addItem($at_old_domain, $at_new_domain, DUPX_S_R_ITEM::TYPE_STRING, DUPX_UpdateEngine::SR_PRORITY_LOW); + } + } + + /** + * add paths to replace on sear/replace engine + * + * @return void + */ + private function addReplaceEnginePaths() + { + $srManager = DUPX_S_R_MANAGER::getInstance(); + $paramsManager = PrmMng::getInstance(); + if ($paramsManager->getValue(PrmMng::PARAM_SKIP_PATH_REPLACE)) { + return; + } + + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + $originalPaths = $archiveConfig->getRealValue('originalPaths'); + $mainPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_OLD); + $mainPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_NEW); + + if ( + !DUPX_InstallerState::isInstallerCreatedInThisLocation() + ) { + $uploadPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_OLD); + $uploadPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_NEW); + if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $uploadPathOld, $uploadPathNew)) { + $srManager->addItem($uploadPathOld, $uploadPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + if ( + $originalPaths->uploads != $uploadPathOld && + self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->uploads, $uploadPathNew) + ) { + $srManager->addItem($originalPaths->uploads, $uploadPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + + $corePathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_OLD); + $corePathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW); + if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $corePathOld, $corePathNew)) { + $srManager->addItem($corePathOld, $corePathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); + } + if ( + $originalPaths->abs != $corePathOld && + self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->abs, $corePathNew) + ) { + $srManager->addItem($originalPaths->abs, $corePathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); + } + + $srManager->addItem($mainPathOld, $mainPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); + if ($originalPaths->home != $mainPathOld) { + $srManager->addItem($originalPaths->home, $mainPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P3); + } + } + + $pluginsPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_OLD); + $pluginsPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW); + if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $pluginsPathOld, $pluginsPathNew)) { + $srManager->addItem($pluginsPathOld, $pluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + if ( + $originalPaths->plugins != $pluginsPathOld && + self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->plugins, $pluginsPathNew) + ) { + $srManager->addItem($originalPaths->plugins, $pluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + + $mupluginsPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_OLD); + $mupluginsPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW); + if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $mupluginsPathOld, $mupluginsPathNew)) { + $srManager->addItem($mupluginsPathOld, $mupluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + if ( + $originalPaths->muplugins != $mupluginsPathOld && + self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->muplugins, $mupluginsPathNew) + ) { + $srManager->addItem($originalPaths->muplugins, $mupluginsPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P1); + } + + $contentPathOld = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_OLD); + $contentPathNew = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW); + if (self::checkRelativeAndAbsoluteDiff($mainPathOld, $mainPathNew, $contentPathOld, $contentPathNew)) { + $srManager->addItem($contentPathOld, $contentPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P2); + } + if ( + $originalPaths->wpcontent != $contentPathOld && + self::checkRelativeAndAbsoluteDiff($originalPaths->home, $mainPathNew, $originalPaths->wpcontent, $contentPathNew) + ) { + $srManager->addItem($originalPaths->wpcontent, $contentPathNew, DUPX_S_R_ITEM::TYPE_PATH, DUPX_UpdateEngine::SR_PRORITY_GENERIC_SUBST_P2); + } + } + + /** + * Check if sub path if different + * + * @param string $mainOld main old path + * @param string $mainNew main new path + * @param string $old old sub path + * @param string $new new sub path + * + * @return bool + */ + private static function checkRelativeAndAbsoluteDiff($mainOld, $mainNew, $old, $new) + { + $mainOld = SnapIO::safePath($mainOld); + $mainNew = SnapIO::safePath($mainNew); + $old = SnapIO::safePath($old); + $new = SnapIO::safePath($new); + + $log = "CHECK REL AND ABS DIF\n" . + "\tMAIN OLD: " . Log::v2str($mainOld) . "\n" . + "\tMAIN NEW: " . Log::v2str($mainNew) . "\n" . + "\tOLD: " . Log::v2str($old) . "\n" . + "\tNEW: " . Log::v2str($new); + Log::info($log, Log::LV_DEBUG); + + $isRelativePathDifferent = substr($old, strlen($mainOld)) !== substr($new, strlen($mainNew)); + + if (strpos($old, $mainOld) !== 0 || strpos($new, $mainNew) !== 0 || $isRelativePathDifferent) { + Log::info("\t*** RESULT: TRUE", Log::LV_DEBUG); + return true; + } else { + Log::info("\t*** RESULT: FALSE", Log::LV_DEBUG); + return false; + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbUserMode.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbUserMode.php new file mode 100644 index 0000000..a9034d5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/DbUserMode.php @@ -0,0 +1,618 @@ +userMode = ParamDescUsers::getUsersMode(); + $this->prefixMetaRegexCheck = '/^' . preg_quote(DUPX_ArchiveConfig::getInstance()->wp_tableprefix, '/') . '(?:(\d+)_)?(.*)$/'; + + switch (DUPX_InstallerState::getInstType()) { + case DUPX_InstallerState::INSTALL_SINGLE_SITE: + $this->addPrefixMetaMapping( + 0, + $prmMng->getValue(PrmMng::PARAM_DB_TABLE_PREFIX) + ); + break; + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBDOMAIN: + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBFOLDER: + throw new Exception('Invalid mode'); + case DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE: + break; + case DUPX_InstallerState::INSTALL_NOT_SET: + throw new Exception('Cannot change setup with current installation type [' . DUPX_InstallerState::getInstType() . ']'); + default: + throw new Exception('Unknown mode'); + } + } + + /** + * Add meta prefix meta mapping + * + * @param int $subsiteId subsite id + * @param string $prefix replace value + * + * @return void + */ + protected function addPrefixMetaMapping($subsiteId, $prefix) + { + Log::info('ADD PREFIX META MAP ID ' . $subsiteId . ' ' . $prefix); + $key = ($subsiteId == 1 ? 0 : $subsiteId); + $this->prefixMetaMapping[$key] = $prefix; + } + + /** + * This function renames the user tables of the target site, also updates the user meta keys + * + * @return void + */ + public static function moveTargetUserTablesOnCurrentPrefix() + { + $paramsManager = PrmMng::getInstance(); + if (ParamDescUsers::getUsersMode() === ParamDescUsers::USER_MODE_OVERWRITE) { + return; + } + + Log::info("\nKEEP TARGET SITE USERS TABLES - USER MODE " . ParamDescUsers::getUsersMode()); + + $dbFunc = DUPX_DB_Functions::getInstance(); + $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + + if ($overwriteData['table_prefix'] == $paramsManager->getValue(PrmMng::PARAM_DB_TABLE_PREFIX)) { + Log::info('TABLE NAMES ARE THE SAME, SO SKIP USERS TABLES RENAME'); + return; + } + + $targetUserTable = DUPX_DB_Functions::getUserTableName($overwriteData['table_prefix']); + $targetUserMetaTable = DUPX_DB_Functions::getUserMetaTableName($overwriteData['table_prefix']); + $currentUserTableName = DUPX_DB_Functions::getUserTableName(); + $currentUserMetaTableName = DUPX_DB_Functions::getUserMetaTableName(); + + $dbFunc->renameTable($targetUserTable, $currentUserTableName, true); + $dbFunc->renameTable($targetUserMetaTable, $currentUserMetaTableName, true); + + // Update table prefix on meta key + DUPX_UpdateEngine::updateTablePrefix( + $dbFunc->dbConnection(), + $currentUserMetaTableName, + 'meta_key', + $overwriteData['table_prefix'], + $paramsManager->getValue(PrmMng::PARAM_DB_TABLE_PREFIX) + ); + Log::info("USER TABLES RENAMED"); + } + + /** + * This function removes all meta keys of the current prefix in the usermeta table. + * This is needed to replace them with the meta keys that will be imported + * + * @return void + */ + public function removeAllUserMetaKeysOfCurrentPrefix() + { + $paramsManager = PrmMng::getInstance(); + if ( + ParamDescUsers::getUsersMode() !== ParamDescUsers::USER_MODE_IMPORT_USERS + ) { + return; + } + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + + $loggedInUserId = (int) $overwriteData['loggedUser']['id']; + + foreach ($this->prefixMetaMapping as $overwriteId => $prefix) { + $where = 'user_id != ' . $loggedInUserId; + $escPergPrefix = mysqli_real_escape_string($dbh, SnapDB::quoteRegex($prefix)); + + if ($prefix == $overwriteData['table_prefix']) { + Log::info("\nREMOVE EXISTING USER META KEY WITH PREFIX " . $prefix . ' EXCEPT ' . $prefix . '[0-9]+_'); + // SELECT * FROM `prefix_usermeta` WHERE user_id != 2 AND meta_key REGEXP "^prefix_" AND meta_key NOT REGEXP "^prefix_[0-9]+_" + $where .= ' AND meta_key REGEXP "^' . $escPergPrefix . '" AND meta_key NOT REGEXP "^' . $escPergPrefix . '[0-9]+_"'; + } else { + Log::info("\nREMOVE EXISTING USER META KEY WITH PREFIX " . $prefix); + // SELECT * FROM `prefix_usermeta` WHERE user_id != 2 AND meta_key REGEXP "^prefix_2_" + $where .= ' AND meta_key REGEXP "^' . $escPergPrefix . '"'; + } + + DUPX_DB::chunksDelete($dbh, DUPX_DB_Functions::getUserMetaTableName(), $where); + } + } + + /** + * Filter props on json encode + * + * @return strng[] + */ + public function __sleep() + { + $props = array_keys(get_object_vars($this)); + return array_diff($props, array('targetUsersByMail', 'targetUsersByLogin')); + } + + /** + * Called after json decode + * + * @return void + */ + public function __wakeup() + { + foreach ($this->targetUsersById as $user) { + $this->targetUsersByMail[$user->getMail()] = $user; + $this->targetUsersByLogin[$user->getLogin()] = $user; + } + } + + /** + * Return the list of columns that contain user id to remap in an array( table => numberColumn) + * + * @return int[] + */ + protected static function getTableColIdsToRemap() + { + static $remapTables = null; + if (is_null($remapTables)) { + $remapTables = array(); + + foreach (DUPX_DB_Tables::getInstance()->getTablesByNameWithoutPrefix('posts') as $table) { + $remapTables[$table] = 1; + } + + Log::info('REMAP USERS TABLES/COLUMN ' . Log::v2str($remapTables)); + } + return $remapTables; + } + + /** + * Load from users table the user list + * + * @return void + */ + public function initTargetSiteUsersData() + { + if ($this->userMode !== ParamDescUsers::USER_MODE_IMPORT_USERS) { + return; + } + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + Log::info('INIT IMPORT TARGET USER TABLE DATA'); + + $dbName = mysqli_real_escape_string($dbh, PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_NAME)); + $userTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserTableName()); + + // count num cols of user table, can be different from source to target + $query = 'SELECT count(*) AS num_cols FROM information_schema.columns WHERE table_schema = "' . $dbName . '" AND table_name = "' . $userTable . '"'; + if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { + $err = mysqli_error($dbh); + throw new Exception('Query error: ' . $err); + } + $row = $queryRes->fetch_array(); + $this->userTableNumCols = (int) $row[0]; + Log::info('USER TABLE COLUMNS COUNT ' . $this->userTableNumCols, Log::LV_DETAILED); + + $query = 'SELECT `ID`,`user_login`,`user_email` FROM `' . $userTable . '`'; + if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { + $err = mysqli_error($dbh); + throw new Exception('Query error: ' . $err); + } + + $this->usersAutoIncrement = -1; + while ($row = $queryRes->fetch_assoc()) { + $rowId = (int) $row['ID']; + $user = new ImportUser($rowId, $row['user_login'], $row['user_email']); + + $this->targetUsersById[$user->getId()] = $user; + $this->targetUsersByMail[$user->getMail()] = $user; + $this->targetUsersByLogin[$user->getLogin()] = $user; + + if ($rowId > $this->usersAutoIncrement) { + $this->usersAutoIncrement = $rowId; + } + } + $this->usersAutoIncrement++; + $queryRes->free_result(); + Log::info('EXISTING USERS COUNT ' . count($this->targetUsersById), Log::LV_DETAILED); + Log::info('USERS TABLE AUTOINCREMENT VALUE ' . $this->usersAutoIncrement, Log::LV_DETAILED); + + $this->initTargetSiteUserMetaData(); + } + + /** + * For each existing meta key, a list of IDs is associated with each user who has that key or true if all users have the key + * + * @return void + */ + protected function initTargetSiteUserMetaData() + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + Log::info('INIT IMPORT TARGET USERMETA TABLE DATA'); + + $userTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserTableName()); + $userMetaTable = mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserMetaTableName()); + + $query = 'SELECT max(umeta_id) AS maxId FROM `' . $userMetaTable . '`'; + if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { + $err = mysqli_error($dbh); + throw new Exception('Query error: ' . $err); + } + $row = $queryRes->fetch_assoc(); + $this->usersMetaAutoIncrement = ((int) $row['maxId']) + 1; + $queryRes->free_result(); + Log::info('USERMETA TABLE AUTOINCREMENT VALUE ' . $this->usersAutoIncrement, Log::LV_DETAILED); + + $query = 'SELECT COUNT(*) FROM `' . $userTable . '`'; + if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { + $err = mysqli_error($dbh); + throw new Exception('Query error: ' . $err); + } + $row = $queryRes->fetch_array(); + $maxNumIds = $row[0]; + + $query = 'SELECT `meta_key`, IF(COUNT(`user_id`) >= ' . $maxNumIds . ', "ALL", GROUP_CONCAT(`user_id` ORDER BY `user_id` ASC)) AS IDS ' . + 'FROM `' . $userMetaTable . '`' . + 'WHERE `user_id` IN (SELECT `ID` FROM `' . $userTable . '`) GROUP BY meta_key'; + if (($queryRes = DUPX_DB::mysqli_query($dbh, $query)) === false) { + $err = mysqli_error($dbh); + throw new Exception('Query error: ' . $err); + } + + while ($row = $queryRes->fetch_assoc()) { + $this->existingsMetaIsd[$row['meta_key']] = ( + ($row['IDS'] === 'ALL') ? + true : + array_map('intval', explode(',', $row['IDS'])) + ); + } + Log::info('NUM META KEYS READ ' . count($this->existingsMetaIsd), Log::LV_DETAILED); + $queryRes->free_result(); + } + + /** + * Apply inser query user fixes + * + * @param string $query query string + * + * @return string if the string is empty no query must be executed + */ + public function applyUsersFixes(&$query) + { + if ($this->userMode == ParamDescUsers::USER_MODE_OVERWRITE) { + return $query; + } + + $matches = array(); + if (preg_match('/^\s*(?:\/\*.*\*\/|#.*\n|--.*\n)?\s*INSERT\s+INTO\s+`?([^\s`]*?)`?\s+VALUES/s', $query, $matches) !== 1) { + return $query; + } + + $tableName = SnapDB::parsedQueryValueToString($matches[1]); + + if ($this->userMode == ParamDescUsers::USER_MODE_IMPORT_USERS) { + if ($tableName == DUPX_DB_Functions::getUserTableName()) { + return $this->getUserTableQueryFix(SnapDB::getValuesFromQueryInsert($query)); + } elseif ($tableName == DUPX_DB_Functions::getUserMetaTableName()) { + return $this->getUserMetaTableQueryFix(SnapDB::getValuesFromQueryInsert($query)); + } + } + + $tablesColRemap = self::getTableColIdsToRemap(); + if (in_array($tableName, array_keys($tablesColRemap))) { + return $this->getTableUserRemapQueryFix( + $tableName, + $tablesColRemap[$tableName], + SnapDB::getValuesFromQueryInsert($query) + ); + } + return $query; + } + + /** + * Generate import final report + * + * @return void + */ + public function generateImportReport() + { + if ($this->userMode !== ParamDescUsers::USER_MODE_IMPORT_USERS) { + return; + } + + $numAdded = 0; + $numChanged = 0; + + if (($fp = fopen(DUPX_INIT . '/' . self::getCsvReportName(), 'w')) === false) { + Log::info('Can\'t open report file ' . DUPX_INIT . '/' . self::getCsvReportName()); + } else { + fputcsv($fp, ImportUser::getArrayReportTitles()); + } + + foreach ($this->targetUsersById as $user) { + if ($user->isAdded()) { + $numAdded++; + } elseif ($user->isChanged()) { + $numChanged++; + } else { + continue; + } + if ($fp != false) { + fputcsv($fp, $user->getArrayReport()); + } + } + + if ($fp != false) { + fclose($fp); + $csvUrl = DUPX_INIT_URL . '/' . self::getCsvReportName(); + } else { + $csvUrl = false; + } + + $longMsg = dupxTplRender( + 'parts/reports/import_report', + array( + 'numAdded' => $numAdded, + 'numChanged' => $numChanged, + 'csvUrl' => $csvUrl + ), + false + ); + + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $nManager->addFinalReportNotice( + array( + 'shortMsg' => 'User import report', + 'level' => DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => $longMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'sections' => 'general' + ) + ); + $nManager->saveNotices(); + } + + /** + * Return csv report file name + * + * @return string + */ + protected static function getCsvReportName() + { + return 'dup-installer-import-report__' . DUPX_Security::getInstance()->getSecondaryPackageHash() . '.csv'; + } + + /** + * Apply query fix for user table + * + * @param array $queryValues two dimensional array where each item is a row containing the list of values + * + * @return string + */ + protected function getUserTableQueryFix($queryValues) + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $resultValues = array(); + $numColsQueryVals = isset($queryValues[0]) ? count($queryValues[0]) : 0; + $colsDeltaDiff = $this->userTableNumCols - $numColsQueryVals; + + foreach ($queryValues as $rowVals) { + $rowId = SnapDB::parsedQueryValueToInt($rowVals[0]); + $rowLogin = SnapDB::parsedQueryValueToString($rowVals[1]); + $rowMail = SnapDB::parsedQueryValueToString($rowVals[4]); + + if (isset($this->targetUsersByMail[$rowMail])) { + $targetUser = $this->targetUsersByMail[$rowMail]; + $targetId = $targetUser->getId(); + $targetLogin = $targetUser->getLogin(); + + if ($rowId != $targetId) { + $targetUser->setOldId($rowId); + $this->mappingIds[$rowId] = $targetId; + } + + if ($rowLogin != $targetLogin) { + $targetUser->setOldLogin($rowLogin); + } + } else { + $rowVals[0] = $targetId = $this->usersAutoIncrement; + $this->usersAutoIncrement++; + + if ($rowId != $targetId) { + $this->mappingIds[$rowId] = $targetId; + } + + $newLogin = $rowLogin; + $postfixIndex = 0; + while (isset($this->targetUsersByLogin[$newLogin])) { + $postfixIndex++; + $newLogin = $rowLogin . $postfixIndex; + } + if ($rowLogin != $newLogin) { + $rowVals[1] = '"' . mysqli_real_escape_string($dbh, $newLogin) . '"'; + + $niceName = SnapDB::parsedQueryValueToString($rowVals[3]); + $rowVals[3] = '"' . mysqli_real_escape_string($dbh, $niceName) . $postfixIndex . '"'; + + $displayName = SnapDB::parsedQueryValueToString($rowVals[9]); + if ($rowLogin == $displayName) { + $rowVals[9] = '"' . mysqli_real_escape_string($dbh, $newLogin) . '"'; + } + } + + $user = new ImportUser($targetId, $newLogin, $rowMail, $rowId, $rowLogin, true); + $this->targetUsersById[$user->getId()] = $user; + $this->targetUsersByMail[$user->getMail()] = $user; + $this->targetUsersByLogin[$user->getLogin()] = $user; + $this->addedUsers[$user->getOldId()] = true; + + if ($colsDeltaDiff == 0) { + $resultValues[] = $rowVals; + } elseif ($colsDeltaDiff < 0) { + $resultValues[] = array_slice($rowVals, 0, $this->userTableNumCols); + } else { + for ($i = 0; $i < $colsDeltaDiff; $i++) { + $rowVals[] = '"0"'; + } + $resultValues[] = $rowVals; + } + } + } + + if (empty($resultValues)) { + return ''; + } + + return 'INSERT INTO `' . mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserTableName()) . '` ' . + 'VALUES ' . SnapDB::getQueryInsertValuesFromArray($resultValues) . ';'; + } + + /** + * Apply query fix for usermeta table + * + * @param array $queryValues two dimensional array where each item is a row containing the list of values + * + * @return string + */ + protected function getUserMetaTableQueryFix($queryValues) + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + $resultValues = array(); + + // reset value + $user = new ImportUser(-1, '', ''); + + $prefixMatches = null; + foreach ($queryValues as $rowVals) { + try { + $rowUserId = SnapDB::parsedQueryValueToInt($rowVals[1]); + $rowMetakey = SnapDB::parsedQueryValueToString($rowVals[2]); + + if ($user->getId() != $rowUserId) { + $userId = isset($this->mappingIds[$rowUserId]) ? $this->mappingIds[$rowUserId] : $rowUserId; + if (isset($this->targetUsersById[$userId])) { + $user = $this->targetUsersById[$userId]; + } else { + // This happens if there is a meta key that has a user id that does not belong to any user, it is an anomalous thing so it is skipped. + continue; + } + } + + if (preg_match($this->prefixMetaRegexCheck, $rowMetakey, $prefixMatches) === 1) { + $currentId = (int)$prefixMatches[1]; + if (!isset($this->prefixMetaMapping[$currentId])) { + // if the attribute is not of the selected sub-site then it is not inserted in the import + continue; + } + + $rowMetakey = $this->prefixMetaMapping[$currentId] . $prefixMatches[2]; + $rowVals[2] = '"' . mysqli_real_escape_string($dbh, $rowMetakey) . '"'; + } + + if ( + $user->isAdded() || + !isset($this->existingsMetaIsd[$rowMetakey]) || + ( + $this->existingsMetaIsd[$rowMetakey] !== true && + SnapUtil::binarySearch($this->existingsMetaIsd[$rowMetakey], $user->getId()) == false + ) + ) { + $rowVals[0] = $this->usersMetaAutoIncrement; + $this->usersMetaAutoIncrement++; + $rowVals[1] = $user->getId(); + + if ($rowMetakey == 'nickname') { + // update nickname + $rowMetaValue = SnapDB::parsedQueryValueToString($rowVals[3]); + if ($rowMetaValue == $user->getOldLogin()) { + $rowVals[3] = '"' . mysqli_real_escape_string($dbh, $user->getLogin()) . '"'; + } + } + + $resultValues[] = $rowVals; + } + } catch (Exception $e) { + Log::logException($e, 'Error on parse user meta row'); + } catch (Error $e) { + Log::logException($e, 'Error on parse user meta row'); + } + } + + if (empty($resultValues)) { + return ''; + } + + return 'INSERT INTO `' . mysqli_real_escape_string($dbh, DUPX_DB_Functions::getUserMetaTableName()) . + '` VALUES ' . SnapDB::getQueryInsertValuesFromArray($resultValues) . ';'; + } + + /** + * Apply query fix for table/colum user id + * + * @param string $tableName table name + * @param string $colNum column index, 0 is first + * @param array $queryValues two dimensional array where each item is a row containing the list of values + * + * @return void + */ + protected function getTableUserRemapQueryFix($tableName, $colNum, $queryValues) + { + $dbh = DUPX_DB_Functions::getInstance()->dbConnection(); + + for ($i = 0; $i < count($queryValues); $i++) { + $rowUserId = SnapDB::parsedQueryValueToInt($queryValues[$i][$colNum]); + if (isset($this->mappingIds[$rowUserId])) { + $queryValues[$i][$colNum] = $this->mappingIds[$rowUserId]; + } + } + + return 'INSERT INTO `' . mysqli_real_escape_string($dbh, $tableName) . + '` VALUES ' . SnapDB::getQueryInsertValuesFromArray($queryValues) . ';'; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/QueryFixes.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/QueryFixes.php new file mode 100644 index 0000000..00a84e2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Database/QueryFixes.php @@ -0,0 +1,302 @@ + array(), + 'replace' => array() + ); + /** @var array */ + protected $tablesPrefixRules = array(); + /** @var string */ + protected $generatorLog = ''; + + /** + * Class constructor + */ + public function __construct() + { + $this->rulesProcAndViews(); + $this->rulesMySQLEngine(); + $this->legacyCharsetAndCollation(); + $this->rulesTableNames(); + } + + /** + * Filter props on json encode + * + * @return string[] + */ + public function __sleep() + { + $props = array_keys(get_object_vars($this)); + return array_diff($props, array('generatorLog')); + } + + /** + * Write rules in log + * + * @return void + */ + public function logRules() + { + if (strlen($this->generatorLog) == 0) { + Log::info('NO GENERAL QUERY FIXES'); + } else { + Log::info('QUERY FIXES'); + Log::info($this->generatorLog); + } + + if (count($this->globalRules['search']) > 0) { + Log::info('QUERY FIXES GLOBAL RULES'); + Log::incIndent(); + foreach ($this->globalRules['search'] as $index => $search) { + Log::info('SEARCH => ' . $search); + Log::info('REPLACE => ' . $this->globalRules['replace'][$index] . "\n"); + } + Log::resetIndent(); + } + + if (count($this->tablesPrefixRules) > 0) { + Log::info('QUERY FIXES TABLES RULES'); + Log::incIndent(); + foreach ($this->tablesPrefixRules as $indexRulesSet => $ruleSet) { + Log::info('RULESET ' . ($indexRulesSet + 1)); + Log::incIndent(); + foreach ($ruleSet['search'] as $index => $search) { + Log::info('SEARCH => ' . $search); + Log::info('REPLACE => ' . $ruleSet['replace'][$index] . "\n"); + } + Log::decIndent(); + } + Log::resetIndent(); + } + } + + /** + * @param string $query query to fix + * + * @return string The query with appropriate substitutions done + */ + public function applyFixes($query) + { + $query = preg_replace($this->globalRules['search'], $this->globalRules['replace'], $query); + + foreach ($this->tablesPrefixRules as $ruleSet) { + $query = preg_replace($ruleSet['search'], $ruleSet['replace'], $query); + } + return $query; + } + + /** + * Set search and replace rules + * + * @return void + */ + protected function rulesProcAndViews() + { + if (DUPX_InstallerState::isRestoreBackup()) { + return; + } + + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_REMOVE_DEFINER)) { + $this->globalRules['search'][] = self::USER_DEFINER_REMOVE_PATTERN; + $this->globalRules['replace'][] = self::USER_DEFINER_REMOVE_REPLACE; + } else { + $this->globalRules['search'][] = self::USER_DEFINER_REPLACE_PATTERN; + + $dbHost = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_HOST); + $dbUser = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_USER); + + $definerHost = (($dbHost == "localhost" || $dbHost == "127.0.0.1") ? $dbHost : '%'); + $this->globalRules['replace'][] = '$1' . addcslashes("`" . $dbUser . "`@`" . $definerHost . "`", '\\$') . '$3'; + } + + $this->globalRules['search'][] = self::SQL_SECURITY_INVOKER_PATTERN; + $this->globalRules['replace'][] = self::SQL_SECURITY_INVOKER_REPLACE; + + $this->generatorLog .= "GLOBAL RULES ADDED: PROC AND VIEWS\n"; + } + + /** + * Check invalid SQL engines + * + * @return void + */ + protected function rulesMySQLEngine() + { + $invalidEngines = array_map(function ($engine) { + return preg_quote($engine, '/'); + }, DUPX_ArchiveConfig::getInstance()->invalidEngines()); + + if (empty($invalidEngines)) { + return; + } + $this->globalRules['search'][] = '/^(\s*(?:\/\*!\d+\s)?\s*CREATE.+ENGINE=)(' . implode('|', $invalidEngines) . ')(.*)$/ms'; + $this->globalRules['replace'][] = '$1' . DUPX_DB_Functions::getInstance()->getDefaultEngine() . '$3'; + + $this->generatorLog .= "GLOBAL RULES ADDED: MYSQL ENGINES\n"; + } + + /** + * Set legacy charset adn collation rules + * + * regex managed examples + * - `meta_value` longtext CHARACTER SET utf16 COLLATE utf16_slovak_ci DEFAULT NULL, + * - `comment_author` tinytext COLLATE utf8mb4_unicode_ci NOT NULL, + * - ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci_test; + * - ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4; + * + * accept ['"`]charset['"`] + * + * @return void + */ + public function legacyCharsetAndCollation() + { + $invalidCharsets = DUPX_ArchiveConfig::getInstance()->invalidCharsets(); + $invalidCollations = DUPX_ArchiveConfig::getInstance()->invalidCollations(); + $defCharsetRegex = addcslashes(DUPX_DB_Functions::getInstance()->getRealCharsetByParam(), '\\$'); + $defCollateRegex = addcslashes(DUPX_DB_Functions::getInstance()->getRealCollateByParam(), '\\$'); + + if (count($invalidCharsets) > 0) { + $invalidChrRegex = '(?:' . implode('|', array_map(function ($val) { + return preg_quote($val, '/'); + }, $invalidCharsets)) . ')'; + + $this->globalRules['search'][] = '/(^.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)(' . + $invalidChrRegex . ')([`\'"]?\s.*COLLATE\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?.*$)/m'; + $this->globalRules['replace'][] = '$1' . $defCharsetRegex . '$3' . $defCollateRegex . '$5'; + $this->globalRules['search'][] = '/(^.*COLLATE\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?\s.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)(' . + $invalidChrRegex . ')([`\'"]?[\s;,].*$)/m'; + $this->globalRules['replace'][] = '$1' . $defCollateRegex . '$3' . $defCharsetRegex . '$5'; + $this->globalRules['search'][] = '/(^.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)(' . $invalidChrRegex . ')([`\'"]?[\s;,].*$)/m'; + $this->globalRules['replace'][] = '$1' . $defCharsetRegex . '$3'; + + $this->generatorLog .= "GLOBAL RULES ADDED: INVALID CHARSETS\n"; + } + + if (count($invalidCollations) > 0) { + $invalidColRegex = '(?:' . implode('|', array_map(function ($val) { + return preg_quote($val, '/'); + }, $invalidCollations)) . ')'; + + $this->globalRules['search'][] = '/(^.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?\s.*COLLATE\s*[\s=]\s*[`\'"]?)(' . + $invalidColRegex . ')([`\'"]?[\s;,].*$)/m'; + $this->globalRules['replace'][] = '$1' . $defCharsetRegex . '$3' . $defCollateRegex . '$5'; + $this->globalRules['search'][] = '/(^.*COLLATE\s*[\s=]\s*[`\'"]?)(' . + $invalidColRegex . ')([`\'"]?\s.*(?:CHARSET|CHARACTER SET)\s*[\s=]\s*[`\'"]?)([^`\'"\s;,]+)([`\'"]?.*$)/m'; + $this->globalRules['replace'][] = '$1' . $defCollateRegex . '$3' . $defCharsetRegex . '$5'; + $this->globalRules['search'][] = '/(^.*COLLATE\s*[\s=]\s*[`\'"]?)(' . $invalidColRegex . ')([`\'"]?[\s;,].*$)/m'; + $this->globalRules['replace'][] = '$1' . $defCollateRegex . '$3'; + + $this->generatorLog .= "GLOBAL RULES ADDED: INVALID COLLATIONS\n"; + } + } + + /** + * Set search and replace table prefix rules + * + * @return void + */ + protected function rulesTableNames() + { + $mapping = DUPX_DB_Tables::getInstance()->getRenameTablesMapping(); + + $oldPrefixes = array_keys($mapping); + $newPrefixes = array(); + foreach ($mapping as $oldPrefix => $newMapping) { + $newPrefixes = array_merge($newPrefixes, array_keys($newMapping)); + } + $newPrefixes = array_unique($newPrefixes); + + // Prevent double transformation with temp prefix + $doublePrefixes = array_intersect($oldPrefixes, $newPrefixes); + if (count($doublePrefixes) > 0) { + $this->generatorLog .= 'DOUBLE PREFIXES ' . Log::v2str($doublePrefixes); + } + + foreach ($mapping as $oldPrefix => $newMapping) { + $rulesSet = array( + 'search' => array(), + 'replace' => array() + ); + + $quoteOldPrefix = preg_quote($oldPrefix, '/'); + + foreach ($newMapping as $newPrefix => $commons) { + $this->generatorLog .= "TABLES RULES ADDED: CHANGE TABLES PREFIX " . $oldPrefix . " TO " . $newPrefix ; + if (in_array($newPrefix, $doublePrefixes)) { + $this->generatorLog .= " [USE TMP PREFIX]\n"; + $newPrefix = $newPrefix . self::TEMP_POSTFIX; + } else { + $this->generatorLog .= "\n"; + } + $this->generatorLog .= "\tFOR TABLES " . implode(',', $commons) . "\n"; + + $quoteNewPrefix = addcslashes($newPrefix, '\\$'); + $quoteCommons = array_map( + function ($val) { + return preg_quote($val, '/'); + }, + $commons + ); + + for ($i = 0; $i < ceil(count($quoteCommons) / DUPX_DBInstall::TABLES_REGEX_CHUNK_SIZE); $i++) { + $subArray = array_slice($quoteCommons, $i * DUPX_DBInstall::TABLES_REGEX_CHUNK_SIZE, DUPX_DBInstall::TABLES_REGEX_CHUNK_SIZE); + + if (count($subArray) == 0) { + break; + } + + $rulesSet['search'][] = '/' . $quoteOldPrefix . '(' . implode('|', $subArray) . ')/m'; + $rulesSet['replace'][] = $quoteNewPrefix . '$1'; + } + + $rulesSet['search'][] = '/(CONSTRAINT[\s\t]+[`\'"]?.+)(?-i)' . $quoteOldPrefix . '(?i)(.+[`\'"]?[\s\t]+FOREIGN[\s\t]+KEY)/mi'; + $rulesSet['replace'][] = '$1' . $quoteNewPrefix . '$2'; + } + + if (count($rulesSet['search']) > 0) { + $this->tablesPrefixRules[] = $rulesSet; + } + } + + if (count($doublePrefixes)) { + // REMOVE TEMP PREFIXES + $rulesSet = array( + 'search' => array(), + 'replace' => array() + ); + + foreach ($doublePrefixes as $prefix) { + $quoteTempPrefix = preg_quote($prefix . self::TEMP_POSTFIX, '/'); + $quotePrefix = addcslashes($prefix, '\\$'); + + $rulesSet['search'][] = '/' . $quoteTempPrefix . '/m'; + $rulesSet['replace'][] = $quotePrefix . '$1'; + } + + $this->tablesPrefixRules[] = $rulesSet; + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/Daws.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/Daws.php new file mode 100644 index 0000000..f92b397 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/Daws.php @@ -0,0 +1,196 @@ +lockFile = DUPX_INIT . '/dup-installer-dawslock__' . DUPX_Package::getPackageHash() . '.bin'; + $this->cancelFile = DUPX_INIT . '/dup-installer-dawscancel__' . DUPX_Package::getPackageHash() . '.bin'; + } + + /** + * Failure callback + * + * @param callable $callback callback + * + * @return void + */ + public function setFailureCallBack($callback) + { + if (is_callable($callback)) { + $this->failureCallback = $callback; + } + } + + /** + * Extract dup archvie + * + * @param array $params dup archvie params + * + * @return stdClass + */ + public function processRequest($params) + { + $retVal = new stdClass(); + + $retVal->pass = false; + + $action = $params['action']; + + $initializeState = false; + + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + if (!DupArchiveFileProcessor::setNewFilePathCallback(array($archiveConfig, 'destFileFromArchiveName'))) { + Log::info('ERROR: CAN\'T SET THE PATH SE CALLBACK FUNCTION'); + } else { + Log::info('PATH SE CALLBACK FUNCTION OK ', Log::LV_DEBUG); + } + + $throttleDelayInMs = SnapUtil::getArrayValue($params, 'throttle_delay', false, 0); + + if ($action == 'start_expand') { + Log::info('DAWN START EXPAND'); + + $initializeState = true; + + DawsExpandState::purgeStatefile(); + SnapIO::rm($this->cancelFile); + $archiveFilepath = SnapUtil::getArrayValue($params, 'archive_filepath'); + $restoreDirectory = SnapUtil::getArrayValue($params, 'restore_directory'); + $workerTime = SnapUtil::getArrayValue($params, 'worker_time', false, self::DEFAULT_WORKER_TIME); + $filteredDirectories = SnapUtil::getArrayValue($params, 'filtered_directories', false, array()); + $excludedDirWithoutChilds = SnapUtil::getArrayValue($params, 'excludedDirWithoutChilds', false, array()); + $filteredFiles = SnapUtil::getArrayValue($params, 'filtered_files', false, array()); + $fileRenames = SnapUtil::getArrayValue($params, 'fileRenames', false, array()); + $fileModeOverride = SnapUtil::getArrayValue($params, 'file_mode_override', false, 0644); + $includedFiles = SnapUtil::getArrayValue($params, 'includedFiles', false, array()); + $directoryModeOverride = SnapUtil::getArrayValue($params, 'dir_mode_override', false, 0755); + $keepFileTime = SnapUtil::getArrayValue($params, 'keep_file_time', false, false); + + $action = 'expand'; + } else { + Log::info('DAWN CONTINUE EXPAND'); + } + + if ($action == 'expand') { + $expandState = DawsExpandState::getInstance($initializeState); + + $this->lock_handle = SnapIO::fopen($this->lockFile, 'c+'); + SnapIO::flock($this->lock_handle, LOCK_EX); + + if ($initializeState || $expandState->working) { + if ($initializeState) { + $expandState->archivePath = $archiveFilepath; + $expandState->working = true; + $expandState->timeSliceInSecs = $workerTime; + $expandState->basePath = $restoreDirectory; + $expandState->filteredDirectories = $filteredDirectories; + $expandState->excludedDirWithoutChilds = $excludedDirWithoutChilds; + $expandState->includedFiles = $includedFiles; + $expandState->filteredFiles = $filteredFiles; + $expandState->fileRenames = $fileRenames; + $expandState->fileModeOverride = $fileModeOverride; + $expandState->directoryModeOverride = $directoryModeOverride; + $expandState->keepFileTime = $keepFileTime; + + $expandState->save(); + } + $expandState->throttleDelayInUs = 1000 * $throttleDelayInMs; + DupArchiveEngine::expandArchive($expandState); + } + + if (!$expandState->working) { + $deltaTime = time() - $expandState->startTimestamp; + Log::info("DAWN EXPAND DONE, SECONDS: " . $deltaTime, Log::LV_DETAILED); + + if (count($expandState->failures) > 0) { + Log::info('DAWN EXPAND ERRORS DETECTED'); + + foreach ($expandState->failures as $failure) { + Log::info("{$failure->subject}:{$failure->description}"); + if (is_callable($this->failureCallback)) { + call_user_func($this->failureCallback, $failure); + } + } + } + } else { + Log::info("DAWN EXPAND CONTINUE", Log::LV_DETAILED); + } + + + SnapIO::flock($this->lock_handle, LOCK_UN); + + $retVal->pass = true; + $retVal->status = $this->getStatus($expandState); + } elseif ($action == 'get_status') { + /* @var $expandState DawsExpandState */ + $expandState = DawsExpandState::getInstance($initializeState); + + $retVal->pass = true; + $retVal->status = $this->getStatus($expandState); + } elseif ($action == 'cancel') { + if (!SnapIO::touch($this->cancelFile)) { + throw new Exception("Couldn't update time on " . $this->cancelFile); + } + $retVal->pass = true; + } else { + throw new Exception('Unknown command.'); + } + session_write_close(); + + return $retVal; + } + + /** + * Get dup archive status + * + * @param DupArchiveStateBase $state dup archive state + * + * @return stdClass + */ + private function getStatus(DawsExpandState $state) + { + $ret_val = new stdClass(); + $ret_val->archive_offset = $state->archiveOffset; + $ret_val->archive_size = @filesize($state->archivePath); + $ret_val->failures = $state->failures; + $ret_val->file_index = $state->fileWriteCount; + $ret_val->is_done = !$state->working; + $ret_val->timestamp = time(); + + return $ret_val; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/DawsExpandState.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/DawsExpandState.php new file mode 100644 index 0000000..6ca6a4f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/DawsExpandState.php @@ -0,0 +1,161 @@ +initMembers(); + } + + /** + * Remove state file + * + * @return bool + */ + public static function purgeStatefile() + { + $stateFilepath = __DIR__ . '/' . self::STATE_FILE; + if (!file_exists($stateFilepath)) { + return true; + } + return SnapIO::rm($stateFilepath, false); + } + + /** + * + * @param boolean $reset reset state + * + * @return self + */ + public static function getInstance($reset = false) + { + if ((self::$instance == null) && (!$reset)) { + $stateFilepath = __DIR__ . '/' . self::STATE_FILE; + + self::$instance = new self(); + + if (file_exists($stateFilepath)) { + $stateHandle = SnapIO::fopen($stateFilepath, 'rb'); + + // RSR we shouldn't need read locks and it seems to screw up on some boxes anyway.. SnapIO::flock($stateHandle, LOCK_EX); + $stateString = fread($stateHandle, filesize($stateFilepath)); + $data = json_decode($stateString, false); + self::$instance->setFromData($data); + self::$instance->fileRenames = (array) (self::$instance->fileRenames); + + // SnapIO::flock($stateHandle, LOCK_UN); + SnapIO::fclose($stateHandle); + } else { + $reset = true; + } + } + + if ($reset) { + self::$instance = new self(); + self::$instance->reset(); + } + + return self::$instance; + } + + /** + * Init state from data + * + * @param stdClass $data data + * + * @return void + */ + private function setFromData($data) + { + foreach ($data as $key => $val) { + if (!property_exists($this, $key)) { + continue; + } + $this->{$key} = $val; + } + } + + /** + * Reset state + * + * @return void + */ + public function reset() + { + $stateFilepath = __DIR__ . '/' . self::STATE_FILE; + $stateHandle = SnapIO::fopen($stateFilepath, 'w'); + SnapIO::flock($stateHandle, LOCK_EX); + + $this->initMembers(); + SnapIO::fwrite($stateHandle, json_encode($this)); + SnapIO::flock($stateHandle, LOCK_UN); + SnapIO::fclose($stateHandle); + } + + /** + * Save state + * + * @return void + */ + public function save() + { + $stateFilepath = __DIR__ . '/' . self::STATE_FILE; + $stateHandle = SnapIO::fopen($stateFilepath, 'w'); + SnapIO::flock($stateHandle, LOCK_EX); + + DupArchiveUtil::tlog("saving state"); + SnapIO::fwrite($stateHandle, json_encode($this)); + SnapIO::flock($stateHandle, LOCK_UN); + SnapIO::fclose($stateHandle); + } + + /** + * Init props + * + * @return void + */ + private function initMembers() + { + $this->currentFileHeader = null; + $this->archiveOffset = 0; + $this->archiveHeader = 0; + $this->archivePath = null; + $this->basePath = null; + $this->currentFileOffset = 0; + $this->failures = array(); + $this->isCompressed = false; + $this->startTimestamp = time(); + $this->timeSliceInSecs = -1; + $this->working = false; + $this->validateOnly = false; + $this->filteredDirectories = array(); + $this->filteredFiles = array(); + $this->fileRenames = array(); + $this->directoryModeOverride = -1; + $this->fileModeOverride = -1; + $this->lastHeaderOffset = -1; + $this->throttleDelayInUs = 0; + $this->timerEnabled = true; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/DawsLogger.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/DawsLogger.php new file mode 100644 index 0000000..cd9683e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/DupArchive/DawsLogger.php @@ -0,0 +1,63 @@ +addFile($archiveConfig->installer_backup_name); + $result->addDir(ltrim($subFolderArchive . '/' . DUP_Extraction::DUP_FOLDER_NAME, '/')); + + if (self::filterWpCoreFiles()) { + $relAbsPath = $archiveConfig->getRelativePathsInArchive('abs'); + $relAbsPath .= (strlen($relAbsPath) > 0 ? '/' : ''); + $rootWpCoreItems = SnapWP::getWpCoreFilesListInFolder(); + foreach ($rootWpCoreItems['dirs'] as $name) { + $result->addDir($relAbsPath . $name); + } + + foreach ($rootWpCoreItems['files'] as $name) { + $result->addFile($relAbsPath . $name); + } + } + + if (self::filterAllExceptPlugingThemesMedia()) { + Log::info('FILTER ALL EXCEPT MEDIA'); + $filterFilesChildOfFolders[] = $archiveConfig->getRelativePathsInArchive('home'); + $filterFilesChildOfFolders[] = $archiveConfig->getRelativePathsInArchive('wpcontent'); + + $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('uploads'); + $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('wpcontent') . '/blogs.dir'; + $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('plugins'); + $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('muplugins'); + $acceptFolderOfFilterChilds[] = $archiveConfig->getRelativePathsInArchive('themes'); + } + + if (self::filterExistsPlugins()) { + $newPluginDir = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW); + if (is_dir($newPluginDir)) { + $relPlugPath = $archiveConfig->getRelativePathsInArchive('plugins'); + $relPlugPath .= (strlen($relPlugPath) > 0 ? '/' : ''); + + SnapIO::regexGlobCallback($newPluginDir, function ($item) use ($relPlugPath, &$result) { + if (is_dir($item)) { + $result->addDir($relPlugPath . pathinfo($item, PATHINFO_BASENAME)); + } else { + $result->addFile($relPlugPath . pathinfo($item, PATHINFO_BASENAME)); + } + }, array()); + } + + $newMuPluginDir = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW); + if (is_dir($newMuPluginDir)) { + $relMuPlugPath = $archiveConfig->getRelativePathsInArchive('muplugins'); + $relMuPlugPath .= (strlen($relMuPlugPath) > 0 ? '/' : ''); + + SnapIO::regexGlobCallback($newMuPluginDir, function ($item) use ($relMuPlugPath, &$result) { + if (is_dir($item)) { + $result->addDir($relMuPlugPath . pathinfo($item, PATHINFO_BASENAME)); + } else { + $result->addFile($relMuPlugPath . pathinfo($item, PATHINFO_BASENAME)); + } + }, array()); + } + + $newWpContentDir = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW) . '/'; + if (is_dir($newWpContentDir)) { + $relContentPath = $archiveConfig->getRelativePathsInArchive('wpcontent'); + $relContentPath .= (strlen($relContentPath) > 0 ? '/' : ''); + foreach (SnapWP::getDropinsPluginsNames() as $dropinsPlugin) { + if (file_exists($newWpContentDir . $dropinsPlugin)) { + $result->addFile($relContentPath . $dropinsPlugin); + } + } + } + } + + if (self::filterExistsThemes()) { + $newThemesDir = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW) . '/themes'; + if (is_dir($newThemesDir)) { + $relThemesPath = $archiveConfig->getRelativePathsInArchive('themes'); + $relThemesPath .= (strlen($relContentPath) > 0 ? '/' : ''); + + SnapIO::regexGlobCallback($newThemesDir, function ($item) use ($relThemesPath, &$result) { + if (is_dir($item)) { + $result->addDir($relThemesPath . pathinfo($item, PATHINFO_BASENAME)); + } else { + $result->addFile($relThemesPath . pathinfo($item, PATHINFO_BASENAME)); + } + }, array()); + } + } + + self::filterAllChildsOfPathExcept($result, $filterFilesChildOfFolders, $acceptFolderOfFilterChilds); + $result->optmizeFilters(); + + return $result; + } + + /** + * Create filters for remove files + * + * @param Filters|null $baseFilters base extraction filters + * + * @return Filters + */ + public static function getRemoveFilters(Filters $baseFilters = null) + { + $archiveConfig = DUPX_ArchiveConfig::getInstance(); + $security = DUPX_Security::getInstance(); + + $result = new Filters(); + if (!is_null($baseFilters)) { + // convert all relative path from archive to absolute destination path + foreach ($baseFilters->getDirs() as $dir) { + $result->addDir($archiveConfig->destFileFromArchiveName($dir)); + } + foreach ($baseFilters->getDirsWithoutChilds() as $dir) { + $result->addDir($archiveConfig->destFileFromArchiveName($dir), true); + } + foreach ($baseFilters->getFiles() as $file) { + $result->addFile($archiveConfig->destFileFromArchiveName($file)); + } + } + + $result->addFile($security->getArchivePath()); + $result->addFile($security->getBootFilePath()); + $result->addFile($security->getBootLogFile()); + + $result->addDir(DUPX_INIT); + foreach (DUPX_Server::getWpAddonsSiteLists() as $addonPath) { + $result->addDir($addonPath); + } + + $result->optmizeFilters(); + + return $result; + } + + /** + * This function update filters from $filterFilesChildOfFolders and $acceptFolders values + * + * @param Filters $filters Filters + * @param string[] $filterFilesChildOfFolders Filter contents of these paths + * @param string[] $acceptFolders Folders not to filtered + * + * @return void + */ + private static function filterAllChildsOfPathExcept(Filters $filters, $filterFilesChildOfFolders, $acceptFolders = array()) + { + //No sense adding filters if not folders specified + if (!is_array($filterFilesChildOfFolders) || count($filterFilesChildOfFolders) == 0) { + return; + } + + $acceptFolders = array_unique($acceptFolders); + $filterFilesChildOfFolders = array_unique($filterFilesChildOfFolders); + + Log::info('ACCEPT FOLDERS ' . Log::v2str($acceptFolders), Log::LV_DETAILED); + Log::info('CHILDS FOLDERS ' . Log::v2str($filterFilesChildOfFolders), Log::LV_DETAILED); + + DUPX_Package::foreachDirCallback(function ($info) use ($acceptFolders, $filterFilesChildOfFolders, &$filters) { + if (in_array($info->p, $filterFilesChildOfFolders)) { + return; + } + + foreach ($acceptFolders as $acceptFolder) { + if (SnapIO::isChildPath($info->p, $acceptFolder, true)) { + return; + } + } + + $parentFolder = SnapIO::getRelativeDirname($info->p); + + if (in_array($parentFolder, $filterFilesChildOfFolders)) { + $filters->addDir($info->p); + } + }); + + DUPX_Package::foreachFileCallback(function ($info) use ($filterFilesChildOfFolders, &$filters) { + $parentFolder = SnapIO::getRelativeDirname($info->p); + if (in_array($parentFolder, $filterFilesChildOfFolders)) { + $filters->addFile($info->p); + } + }); + + Log::info('FILTERS RESULT ' . Log::v2str($filters), log::LV_DETAILED); + } + + /** + * + * @return boolean + * @throws Exception + */ + public static function filterWpCoreFiles() + { + switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { + case DUP_Extraction::FILTER_NONE: + return false; + case DUP_Extraction::FILTER_SKIP_WP_CORE: + case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: + case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: + return true; + default: + throw new Exception('Unknown filter type'); + } + } + + /** + * + * @return boolean + * @throws Exception + */ + protected static function filterExistsPlugins() + { + switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { + case DUP_Extraction::FILTER_NONE: + case DUP_Extraction::FILTER_SKIP_WP_CORE: + return false; + case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: + case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: + return true; + default: + throw new Exception('Unknown filter type'); + } + } + + /** + * + * @return boolean + * @throws Exception + */ + protected static function filterExistsThemes() + { + switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { + case DUP_Extraction::FILTER_NONE: + case DUP_Extraction::FILTER_SKIP_WP_CORE: + return false; + case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: + case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: + return true; + default: + throw new Exception('Unknown filter type'); + } + } + + /** + * + * @return boolean + * @throws Exception + */ + protected static function filterAllExceptPlugingThemesMedia() + { + switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES)) { + case DUP_Extraction::FILTER_NONE: + case DUP_Extraction::FILTER_SKIP_WP_CORE: + case DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES: + return false; + case DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES: + return true; + default: + throw new Exception('Unknown filter type'); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Files/Filters.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Files/Filters.php new file mode 100644 index 0000000..096e7b9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Files/Filters.php @@ -0,0 +1,166 @@ +files = (array) $files; + $this->dirs = (array) $dirs; + $this->dirsWithoutChilds = (array) $dirsWithoutChilds; + } + + /** + * Check if passe path is filterd + * + * @param string $path path to check + * + * @return bool + */ + public function isFiltered($path) + { + if (in_array($path, $this->dirsWithoutChilds)) { + return true; + } + + foreach ($this->dirs as $dirFilter) { + if (SnapIO::isChildPath($path, $dirFilter)) { + return true; + } + } + + return in_array($path, $this->files); + } + + /** + * Add dir filter + * + * @param string $dir dir path + * @param bool $withoutChild if true add dir filter without childs + * + * @return void + */ + public function addDir($dir, $withoutChild = false) + { + if ($withoutChild) { + $this->dirsWithoutChilds[] = (string) $dir; + } else { + $this->dirs[] = (string) $dir; + } + } + + /** + * Add file fo filters + * + * @param string $file file path + * + * @return void + */ + public function addFile($file) + { + $this->files[] = (string) $file; + } + + /** + * Optimize and sort filters + * + * @return bool + */ + public function optmizeFilters() + { + $this->files = array_values(array_unique($this->files)); + $this->dirsWithoutChilds = array_values(array_unique($this->dirsWithoutChilds)); + $this->dirs = array_values(array_unique($this->dirs)); + + $optimizedDirs = array(); + $optimizedFiles = array(); + + for ($i = 0; $i < count($this->dirs); $i++) { + $exclude = false; + for ($j = 0; $j < count($this->dirs); $j++) { + if ($i === $j) { + continue; + } + if (SnapIO::isChildPath($this->dirs[$i], $this->dirs[$j])) { + $exclude = true; + break; + } + } + if (!$exclude) { + $optimizedDirs[] = $this->dirs[$i]; + } + } + + $optimizedDirs = SnapIO::sortBySubfoldersCount($optimizedDirs); + + foreach ($this->files as $file) { + $exclude = false; + foreach ($optimizedDirs as $cDir) { + if (SnapIO::isChildPath($file, $cDir)) { + $exclude = true; + break; + } + } + + if (!$exclude) { + $optimizedFiles[] = $file; + } + } + + $this->files = $optimizedFiles; + $this->dirs = $optimizedDirs; + + return true; + } + + /** + * Get the value of files + * + * @return string[] + */ + public function getFiles() + { + return $this->files; + } + + /** + * Get the value of dirs + * + * @return string[] + */ + public function getDirs() + { + return $this->dirs; + } + + /** + * Get the value of dirsWithoutChilds + * + * @return string[] + */ + public function getDirsWithoutChilds() + { + return $this->dirsWithoutChilds; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Files/RemoveFiles.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Files/RemoveFiles.php new file mode 100644 index 0000000..1b2e2a2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Deploy/Files/RemoveFiles.php @@ -0,0 +1,256 @@ +removeFilters = $filters; + } + + /** + * Remove file if action is enableds + * + * @return void + */ + public function remove() + { + $paramsManager = PrmMng::getInstance(); + + switch ($paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ACTION)) { + case DUP_Extraction::ACTION_REMOVE_ALL_FILES: + $this->removeAllFiles(); + break; + case DUP_Extraction::ACTION_REMOVE_WP_FILES: + $this->removeWpFiles(); + break; + case DUP_Extraction::ACTION_REMOVE_UPLOADS: + $this->removeUploads(); + break; + case DUP_Extraction::ACTION_DO_NOTHING: + break; + default: + throw new Exception('Invalid engine action ' . $paramsManager->getValue(PrmMng::PARAM_ARCHIVE_ACTION)); + } + } + + /** + * This function remove files before extraction + * + * @param string[] $folders Folders lists + * + * @return void + */ + protected function removeFiles($folders = array()) + { + Log::info('REMOVE FILES'); + + $excludeFiles = array_map(function ($value) { + return '/^' . preg_quote($value, '/') . '$/'; + }, $this->removeFilters->getFiles()); + + $excludeFolders = array_map(function ($value) { + return '/^' . preg_quote($value, '/') . '(?:\/.*)?$/'; + }, $this->removeFilters->getDirs()); + $excludeFolders[] = '/.+\/backups-dup-(lite|pro)$/'; + + $excludeDirsWithoutChilds = $this->removeFilters->getDirsWithoutChilds(); + + foreach ($folders as $folder) { + Log::info('REMOVE FOLDER ' . Log::v2str($folder)); + SnapIO::regexGlobCallback($folder, function ($path) use ($excludeDirsWithoutChilds) { + foreach ($excludeDirsWithoutChilds as $excludePath) { + if (SnapIO::isChildPath($excludePath, $path)) { + return; + } + } + + $result = (is_dir($path) ? rmdir($path) : unlink($path)); + if ($result == false) { + $lastError = error_get_last(); + $message = (isset($lastError['message']) ? $lastError['message'] : 'Couldn\'t remove file'); + RemoveFiles::reportRemoveNotices($path, $message); + } + }, array( + 'regexFile' => $excludeFiles, + 'regexFolder' => $excludeFolders, + 'checkFullPath' => true, + 'recursive' => true, + 'invert' => true, + 'childFirst' => true + )); + } + } + + /** + * Remove worpdress core files + * + * @return void + */ + protected function removeWpFiles() + { + try { + Log::info('REMOVE WP FILES'); + Log::resetTime(Log::LV_DEFAULT, false); + + $paramsManager = PrmMng::getInstance(); + $absDir = SnapIO::safePathTrailingslashit($paramsManager->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW)); + if (!is_dir($absDir) || !is_readable($absDir)) { + return false; + } + + $removeFolders = array(); + + if (!FilterMng::filterWpCoreFiles() && ($dh = opendir($absDir))) { + while (($elem = readdir($dh)) !== false) { + if ($elem === '.' || $elem === '..') { + continue; + } + + if (SnapWP::isWpCore($elem, SnapWP::PATH_RELATIVE)) { + $fullPath = $absDir . $elem; + if (is_dir($fullPath)) { + $removeFolders[] = $fullPath; + } else { + if (is_writable($fullPath)) { + unlink($fullPath); + } + } + } + } + closedir($dh); + } + + $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_CONTENT_NEW); + $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_NEW); + $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_PLUGINS_NEW); + $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_MUPLUGINS_NEW); + + $this->removeFiles(array_unique($removeFolders)); + Log::logTime('FOLDERS REMOVED', Log::LV_DEFAULT, false); + } catch (Exception $e) { + Log::logException($e); + } catch (Error $e) { + Log::logException($e); + } + } + + /** + * Remove ony uploads files + * + * @return void + */ + protected function removeUploads() + { + try { + Log::info('REMOVE UPLOADS FILES'); + Log::resetTime(Log::LV_DEFAULT, false); + + $paramsManager = PrmMng::getInstance(); + + $removeFolders = array(); + $removeFolders[] = $paramsManager->getValue(PrmMng::PARAM_PATH_UPLOADS_NEW); + + $this->removeFiles(array_unique($removeFolders)); + Log::logTime('FOLDERS REMOVED', Log::LV_DEFAULT, false); + } catch (Exception $e) { + Log::logException($e); + } catch (Error $e) { + Log::logException($e); + } + } + + /** + * Remove all files before extraction + * + * @return void + */ + protected function removeAllFiles() + { + try { + Log::info('REMOVE ALL FILES'); + Log::resetTime(Log::LV_DEFAULT, false); + $pathsMapping = DUPX_ArchiveConfig::getInstance()->getPathsMapping(); + $folders = is_string($pathsMapping) ? array($pathsMapping) : array_values($pathsMapping); + + $this->removeFiles($folders); + Log::logTime('FOLDERS REMOVED', Log::LV_DEFAULT, false); + } catch (Exception $e) { + Log::logException($e); + } catch (Error $e) { + Log::logException($e); + } + } + + + /** + * + * @param string $fileName package relative path + * @param string $errorMessage error message + * + * @return void + */ + public static function reportRemoveNotices($fileName, $errorMessage) + { + if (DUPX_Custom_Host_Manager::getInstance()->skipWarningExtractionForManaged($fileName)) { + // @todo skip warning for managed hostiong (it's a temp solution) + return; + } + + Log::info('Remove ' . $fileName . ' error message: ' . $errorMessage); + if (is_dir($fileName)) { + // Skip warning message for folders + return; + } + + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + + if (SnapWP::isWpCore($fileName, SnapWP::PATH_RELATIVE)) { + Log::info("FILE CORE REMOVE ERROR: {$fileName} | MSG:" . $errorMessage); + $shortMsg = 'Can\'t remove wp core files'; + $errLevel = DUPX_NOTICE_ITEM::CRITICAL; + $idManager = 'wp-remove-error-file-core'; + } else { + Log::info("FILE REMOVE ERROR: {$fileName} | MSG:" . $errorMessage); + $shortMsg = 'Can\'t remove files'; + $errLevel = DUPX_NOTICE_ITEM::HARD_WARNING; + $idManager = 'wp-remove-error-file-no-core'; + } + + $longMsg = 'FILE: ' . htmlspecialchars($fileName) . '
        Message: ' . htmlspecialchars($errorMessage) . '

        '; + + $nManager->addBothNextAndFinalReportNotice( + array( + 'shortMsg' => $shortMsg, + 'longMsg' => $longMsg, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_HTML, + 'level' => $errLevel, + 'sections' => array('files') + ), + DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, + $idManager + ); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Hooks/Hook.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Hooks/Hook.php new file mode 100644 index 0000000..9b98d4a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Hooks/Hook.php @@ -0,0 +1,593 @@ +callbacks[$priority]); + + $this->callbacks[$priority][$idx] = array( + 'function' => $function_to_add, + 'accepted_args' => $accepted_args, + ); + + // If we're adding a new priority to the list, put them back in sorted order. + if (!$priority_existed && count($this->callbacks) > 1) { + ksort($this->callbacks, SORT_NUMERIC); + } + + if ($this->nestingLevel > 0) { + $this->resortActiveIterations($priority, $priority_existed); + } + } + + /** + * Handles resetting callback priority keys mid-iteration. + * + * @param false|int $new_priority Optional. The priority of the new filter being added. Default false, + * for no priority being added. + * @param bool $priority_existed Optional. Flag for whether the priority already existed before the new + * filter was added. Default false. + * + * @return void + */ + private function resortActiveIterations($new_priority = false, $priority_existed = false) + { + $new_priorities = array_keys($this->callbacks); + + // If there are no remaining hooks, clear out all running iterations. + if (!$new_priorities) { + foreach ($this->iterations as $index => $iteration) { + $this->iterations[$index] = $new_priorities; + } + return; + } + + $min = min($new_priorities); + foreach ($this->iterations as $index => &$iteration) { + $current = current($iteration); + // If we're already at the end of this iteration, just leave the array pointer where it is. + if (false === $current) { + continue; + } + + $iteration = $new_priorities; + + if ($current < $min) { + array_unshift($iteration, $current); + continue; + } + + while (current($iteration) < $current) { + if (false === next($iteration)) { + break; + } + } + + // If we have a new priority that didn't exist, but ::applyFilters() or ::doAction() thinks it's the current priority... + if ($new_priority === $this->currentPriority[$index] && !$priority_existed) { + /* + * ...and the new priority is the same as what $this->iterations thinks is the previous + * priority, we need to move back to it. + */ + + if (false === current($iteration)) { + // If we've already moved off the end of the array, go back to the last element. + $prev = end($iteration); + } else { + // Otherwise, just go back to the previous element. + $prev = prev($iteration); + } + if (false === $prev) { + // Start of the array. Reset, and go about our day. + reset($iteration); + } elseif ($new_priority !== $prev) { + // Previous wasn't the same. Move forward again. + next($iteration); + } + } + } + unset($iteration); + } + + /** + * Unhooks a function or method from a specific filter action. + * + * @param string $tag The filter hook to which the function to be removed is hooked. + * @param callable $function_to_remove The callback to be removed from running when the filter is applied. + * @param int $priority The exact priority used when adding the original filter callback. + * + * @return bool Whether the callback existed before it was removed. + */ + public function removeFilter($tag, $function_to_remove, $priority) + { + $function_key = self::wpFilterBuildUniqueId($tag, $function_to_remove, $priority); + + $exists = isset($this->callbacks[$priority][$function_key]); + if ($exists) { + unset($this->callbacks[$priority][$function_key]); + if (!$this->callbacks[$priority]) { + unset($this->callbacks[$priority]); + if ($this->nestingLevel > 0) { + $this->resortActiveIterations(); + } + } + } + return $exists; + } + + /** + * Checks if a specific action has been registered for this hook. + * + * When using the `$function_to_check` argument, this function may return a non-boolean value + * that evaluates to false (e.g. 0), so use the `===` operator for testing the return value. + * + * @param string $tag Optional. The name of the filter hook. Default empty. + * @param callable|false $function_to_check Optional. The callback to check for. Default false. + * + * @return bool|int If `$function_to_check` is omitted, returns boolean for whether the hook has + * anything registered. When checking a specific function, the priority of that + * hook is returned, or false if the function is not attached. + */ + public function hasFilter($tag = '', $function_to_check = false) + { + if (false === $function_to_check) { + return $this->hasFilters(); + } + + $function_key = self::wpFilterBuildUniqueId($tag, $function_to_check, false); + if (!$function_key) { + return false; + } + + foreach ($this->callbacks as $priority => $callbacks) { + if (isset($callbacks[$function_key])) { + return $priority; + } + } + + return false; + } + + /** + * Checks if any callbacks have been registered for this hook. + * + * @return bool True if callbacks have been registered for the current hook, otherwise false. + */ + public function hasFilters() + { + foreach ($this->callbacks as $callbacks) { + if ($callbacks) { + return true; + } + } + return false; + } + + /** + * Removes all callbacks from the current filter. + * + * @param int|false $priority Optional. The priority number to remove. Default false. + * + * @return void + */ + public function removeAllFilters($priority = false) + { + if (!$this->callbacks) { + return; + } + + if (false === $priority) { + $this->callbacks = array(); + } elseif (isset($this->callbacks[$priority])) { + unset($this->callbacks[$priority]); + } + + if ($this->nestingLevel > 0) { + $this->resortActiveIterations(); + } + } + + /** + * Calls the callback functions that have been added to a filter hook. + * + * @param mixed $value The value to filter. + * @param array $args Additional parameters to pass to the callback functions. + * This array is expected to include $value at index 0. + * + * @return mixed The filtered value after all hooked functions are applied to it. + */ + public function applyFilters($value, $args) + { + if (!$this->callbacks) { + return $value; + } + + $nestingLevel = $this->nestingLevel++; + + $this->iterations[$nestingLevel] = array_keys($this->callbacks); + $num_args = count($args); + + do { + $this->currentPriority[$nestingLevel] = current($this->iterations[$nestingLevel]); + $priority = $this->currentPriority[$nestingLevel]; + + foreach ($this->callbacks[$priority] as $the_) { + if (!$this->doingAction) { + $args[0] = $value; + } + + // Avoid the array_slice() if possible. + if (0 == $the_['accepted_args']) { + $value = call_user_func($the_['function']); + } elseif ($the_['accepted_args'] >= $num_args) { + $value = call_user_func_array($the_['function'], $args); + } else { + $value = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args'])); + } + } + } while (false !== next($this->iterations[$nestingLevel])); + + unset($this->iterations[$nestingLevel]); + unset($this->currentPriority[$nestingLevel]); + + $this->nestingLevel--; + + return $value; + } + + /** + * Calls the callback functions that have been added to an action hook. + * + * @param array $args Parameters to pass to the callback functions. + * + * @return void + */ + public function doAction($args) + { + $this->doingAction = true; + $this->applyFilters('', $args); + + // If there are recursive calls to the current action, we haven't finished it until we get to the last one. + if (!$this->nestingLevel) { + $this->doingAction = false; + } + } + + /** + * Processes the functions hooked into the 'all' hook. + * + * @param array $args Arguments to pass to the hook callbacks. Passed by reference. + * + * @return void + */ + public function doAllHook(&$args) + { + $nestingLevel = $this->nestingLevel++; + $this->iterations[$nestingLevel] = array_keys($this->callbacks); + + do { + $priority = current($this->iterations[$nestingLevel]); + foreach ($this->callbacks[$priority] as $the_) { + call_user_func_array($the_['function'], $args); + } + } while (false !== next($this->iterations[$nestingLevel])); + + unset($this->iterations[$nestingLevel]); + $this->nestingLevel--; + } + + /** + * Return the current priority level of the currently running iteration of the hook. + * + * @return int|false If the hook is running, return the current priority level. If it isn't running, return false. + */ + public function currentPriority() + { + if (false === current($this->iterations)) { + return false; + } + + return current(current($this->iterations)); + } + + /** + * Normalizes filters set up before WordPress has initialized to Hook objects. + * + * The `$filters` parameter should be an array keyed by hook name, with values + * containing either: + * + * - A `Hook` instance + * - An array of callbacks keyed by their priorities + * + * Examples: + * + * $filters = array( + * 'wp_fatal_error_handler_enabled' => array( + * 10 => array( + * array( + * 'accepted_args' => 0, + * 'function' => function() { + * return false; + * }, + * ), + * ), + * ), + * ); + * + * @param array $filters Filters to normalize. See documentation above for details. + * + * @return WP_Hook[] Array of normalized filters. + */ + public static function buildPreinitializedHooks($filters) + { + /** @var WP_Hook[] $normalized */ + $normalized = array(); + + foreach ($filters as $tag => $callback_groups) { + if (is_object($callback_groups) && $callback_groups instanceof self) { + $normalized[$tag] = $callback_groups; + continue; + } + $hook = new self(); + + // Loop through callback groups. + foreach ($callback_groups as $priority => $callbacks) { + // Loop through callbacks. + foreach ($callbacks as $cb) { + $hook->addFilter($tag, $cb['function'], $priority, $cb['accepted_args']); + } + } + $normalized[$tag] = $hook; + } + return $normalized; + } + + /** + * Determines whether an offset value exists. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetexists.php + * + * @param mixed $offset An offset to check for. + * + * @return bool True if the offset exists, false otherwise. + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + return isset($this->callbacks[$offset]); + } + + /** + * Retrieves a value at a specified offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetget.php + * + * @param mixed $offset The offset to retrieve. + * + * @return mixed If set, the value at the specified offset, null otherwise. + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return isset($this->callbacks[$offset]) ? $this->callbacks[$offset] : null; + } + + /** + * Sets a value at a specified offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetset.php + * + * @param mixed $offset The offset to assign the value to. + * @param mixed $value The value to set. + * + * @return void + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if (is_null($offset)) { + $this->callbacks[] = $value; + } else { + $this->callbacks[$offset] = $value; + } + } + + /** + * Unsets a specified offset. + * + * @link https://www.php.net/manual/en/arrayaccess.offsetunset.php + * + * @param mixed $offset The offset to unset. + * + * @return void + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + unset($this->callbacks[$offset]); + } + + /** + * Returns the current element. + * + * @link https://www.php.net/manual/en/iterator.current.php + * + * @return array Of callbacks at current priority. + */ + #[\ReturnTypeWillChange] + public function current() + { + return current($this->callbacks); + } + + /** + * Moves forward to the next element. + * + * @link https://www.php.net/manual/en/iterator.next.php + * + * @return array Of callbacks at next priority. + */ + #[\ReturnTypeWillChange] + public function next() + { + return next($this->callbacks); + } + + /** + * Returns the key of the current element. + * + * @link https://www.php.net/manual/en/iterator.key.php + * + * @return mixed Returns current priority on success, or NULL on failure + */ + #[\ReturnTypeWillChange] + public function key() + { + return key($this->callbacks); + } + + /** + * Checks if current position is valid. + * + * @link https://www.php.net/manual/en/iterator.valid.php + * + * @return bool Whether the current position is valid. + */ + #[\ReturnTypeWillChange] + public function valid() + { + return key($this->callbacks) !== null; + } + + /** + * Rewinds the Iterator to the first element. + * + * @link https://www.php.net/manual/en/iterator.rewind.php + * + * @return void + */ + #[\ReturnTypeWillChange] + public function rewind() + { + reset($this->callbacks); + } + + /** + * Build Unique ID for storage and retrieval. + * + * The old way to serialize the callback caused issues and this function is the + * solution. It works by checking for objects and creating a new property in + * the class to keep track of the object and new objects of the same class that + * need to be added. + * + * It also allows for the removal of actions and filters for objects after they + * change class properties. It is possible to include the property $wp_filter_id + * in your class and set it to "null" or a number to bypass the workaround. + * However this will prevent you from adding new classes and any new classes + * will overwrite the previous hook by the same class. + * + * Functions and static method callbacks are just returned as strings and + * shouldn't have any speed penalty. + * + * @link https://core.trac.wordpress.org/ticket/3875 + * + * @since 2.2.3 + * @since 5.3.0 Removed workarounds for spl_object_hash(). + * `$tag` and `$priority` are no longer used, + * and the function always returns a string. + * @access private + * + * @param string $tag Unused. The name of the filter to build ID for. + * @param callable $function The function to generate ID for. + * @param int $priority Unused. The order in which the functions + * associated with a particular action are executed. + * + * @return string Unique function ID for usage as array key. + */ + protected static function wpFilterBuildUniqueId($tag, $function, $priority) + { + if (is_string($function)) { + return $function; + } + + if (is_object($function)) { + // Closures are currently implemented as objects. + $function = array($function, ''); + } else { + $function = (array) $function; + } + + if (is_object($function[0])) { + // Object class calling. + return spl_object_hash($function[0]) . $function[1]; + } elseif (is_string($function[0])) { + // Static calling. + return $function[0] . '::' . $function[1]; + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Hooks/HooksMng.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Hooks/HooksMng.php new file mode 100644 index 0000000..6ad7c69 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Hooks/HooksMng.php @@ -0,0 +1,451 @@ +filters[$tag])) { + $this->filters[$tag] = new Hook(); + } + $this->filters[$tag]->addFilter($tag, $function_to_add, $priority, $accepted_args); + return true; + } + + /** + * Checks if any filter has been registered for a hook. + * + * When using the `$function_to_check` argument, this function may return a non-boolean value + * that evaluates to false (e.g. 0), so use the `===` operator for testing the return value. + * + * @param string $tag The name of the filter hook. + * @param callable|false $function_to_check Optional. The callback to check for. Default false. + * + * @return bool|int If `$function_to_check` is omitted, returns boolean for whether the hook has + * anything registered. When checking a specific function, the priority of that + * hook is returned, or false if the function is not attached. + */ + public function hasFilter($tag, $function_to_check = false) + { + if (!isset($this->filters[$tag])) { + return false; + } + + return $this->filters[$tag]->hasFilter($tag, $function_to_check); + } + + /** + * Calls the callback functions that have been added to a filter hook. + * + * The callback functions attached to the filter hook are invoked by calling + * this function. This function can be used to create a new filter hook by + * simply calling this function with the name of the new hook specified using + * the `$tag` parameter. + * + * The function also allows for multiple additional arguments to be passed to hooks. + * + * Example usage: + * + * // The filter callback function. + * function example_callback( $string, $arg1, $arg2 ) { + * // (maybe) modify $string. + * return $string; + * } + * add_filter( 'example_filter', 'example_callback', 10, 3 ); + * + * /* + * * Apply the filters by calling the 'example_callback()' function + * * that's hooked onto `example_filter` above. + * * + * * - 'example_filter' is the filter hook. + * * - 'filter me' is the value being filtered. + * * - $arg1 and $arg2 are the additional arguments passed to the callback. + * $value = applyFilters( 'example_filter', 'filter me', $arg1, $arg2 ); + * + * @param string $tag The name of the filter hook. + * @param mixed $value The value to filter. + * ... $args Additional parameters to pass to the callback functions. + * + * @return mixed The filtered value after all hooked functions are applied to it. + */ + public function applyFilters($tag, $value) + { + $args = func_get_args(); + + // Do 'all' actions first. + if (isset($this->filters['all'])) { + $this->currentFilter[] = $tag; + $this->callAllHook($args); + } + + if (!isset($this->filters[$tag])) { + if (isset($this->filters['all'])) { + array_pop($this->currentFilter); + } + return $value; + } + + if (!isset($this->filters['all'])) { + $this->currentFilter[] = $tag; + } + + // Don't pass the tag name to Hook. + array_shift($args); + + $filtered = $this->filters[$tag]->applyFilters($value, $args); + + array_pop($this->currentFilter); + + return $filtered; + } + + /** + * Removes a function from a specified filter hook. + * + * This function removes a function attached to a specified filter hook. This + * method can be used to remove default functions attached to a specific filter + * hook and possibly replace them with a substitute. + * + * To remove a hook, the $function_to_remove and $priority arguments must match + * when the hook was added. This goes for both filters and actions. No warning + * will be given on removal failure. + * + * @param string $tag The filter hook to which the function to be removed is hooked. + * @param callable $function_to_remove The name of the function which should be removed. + * @param int $priority Optional. The priority of the function. Default 10. + * + * @return bool Whether the function existed before it was removed. + */ + public function removeFilter($tag, $function_to_remove, $priority = 10) + { + $r = false; + if (isset($this->filters[$tag])) { + $r = $this->filters[$tag]->removeFilter($tag, $function_to_remove, $priority); + if (!$this->filters[$tag]->callbacks) { + unset($this->filters[$tag]); + } + } + + return $r; + } + + /** + * Remove all of the hooks from a filter. + * + * @param string $tag The filter to remove hooks from. + * @param int|false $priority Optional. The priority number to remove. Default false. + * + * @return true True when finished. + */ + public function removeAllFilters($tag, $priority = false) + { + if (isset($this->filters[$tag])) { + $this->filters[$tag]->removeAllFilters($priority); + if (!$this->filters[$tag]->hasFilters()) { + unset($this->filters[$tag]); + } + } + + return true; + } + + /** + * Hooks a function on to a specific action. + * + * Actions are the hooks that the WordPress core launches at specific points + * during execution, or when specific events occur. Plugins can specify that + * one or more of its PHP functions are executed at these points, using the + * Action API. + * + * @param string $tag The name of the action to which the $function_to_add is hooked. + * @param callable $function_to_add The name of the function you wish to be called. + * @param int $priority Optional. Used to specify the order in which the functions + * associated with a particular action are executed. Default 10. + * Lower numbers correspond with earlier execution, + * and functions with the same priority are executed + * in the order in which they were added to the action. + * @param int $accepted_args Optional. The number of arguments the function accepts. Default 1. + * + * @return true Will always return true. + */ + public function addAction($tag, $function_to_add, $priority = 10, $accepted_args = 1) + { + return $this->addFilter($tag, $function_to_add, $priority, $accepted_args); + } + + /** + * Execute functions hooked on a specific action hook. + * + * This function invokes all functions attached to action hook `$tag`. It is + * possible to create new action hooks by simply calling this function, + * specifying the name of the new hook using the `$tag` parameter. + * + * You can pass extra arguments to the hooks, much like you can with `applyFilters()`. + * + * Example usage: + * + * // The action callback function. + * function example_callback( $arg1, $arg2 ) { + * // (maybe) do something with the args. + * } + * add_action( 'example_action', 'example_callback', 10, 2 ); + * + * /* + * * Trigger the actions by calling the 'example_callback()' function + * * that's hooked onto `example_action` above. + * * + * * - 'example_action' is the action hook. + * * - $arg1 and $arg2 are the additional arguments passed to the callback. + * $value = do_action( 'example_action', $arg1, $arg2 ); + * + * @global Hook[] $this->filters Stores all of the filters and actions. + * @global string[] $this->currentFilter Stores the list of current filters with the current one last. + * + * @param string $tag The name of the action to be executed. + * ...$arg Optional. Additional arguments which are passed on to the + * functions hooked to the action. Default empty. + * + * @return void + */ + public function doAction($tag) + { + $arg = $all_args = func_get_args(); + array_shift($arg); // remove tag action + + // Do 'all' actions first. + if (isset($this->filters['all'])) { + $this->currentFilter[] = $tag; + $this->callAllHook($all_args); + } + + if (!isset($this->filters[$tag])) { + if (isset($this->filters['all'])) { + array_pop($this->currentFilter); + } + return; + } + + if (!isset($this->filters['all'])) { + $this->currentFilter[] = $tag; + } + + if (empty($arg)) { + $arg[] = ''; + } elseif (is_array($arg[0]) && 1 === count($arg[0]) && isset($arg[0][0]) && is_object($arg[0][0])) { + // Backward compatibility for PHP4-style passing of `array( &$this )` as action `$arg`. + $arg[0] = $arg[0][0]; + } + + $this->filters[$tag]->doAction($arg); + + array_pop($this->currentFilter); + } + + /** + * Checks if any action has been registered for a hook. + * + * When using the `$function_to_check` argument, this function may return a non-boolean value + * that evaluates to false (e.g. 0), so use the `===` operator for testing the return value. + * + * @see hasFilter() has_action() is an alias of hasFilter(). + * + * @param string $tag The name of the action hook. + * @param callable|false $function_to_check Optional. The callback to check for. Default false. + * + * @return bool|int If `$function_to_check` is omitted, returns boolean for whether the hook has + * anything registered. When checking a specific function, the priority of that + * hook is returned, or false if the function is not attached. + */ + public function hasAction($tag, $function_to_check = false) + { + return $this->hasFilter($tag, $function_to_check); + } + + /** + * Removes a function from a specified action hook. + * + * This function removes a function attached to a specified action hook. This + * method can be used to remove default functions attached to a specific filter + * hook and possibly replace them with a substitute. + * + * @param string $tag The action hook to which the function to be removed is hooked. + * @param callable $function_to_remove The name of the function which should be removed. + * @param int $priority Optional. The priority of the function. Default 10. + * + * @return bool Whether the function is removed. + */ + public function removeAction($tag, $function_to_remove, $priority = 10) + { + return $this->removeFilter($tag, $function_to_remove, $priority); + } + + /** + * Remove all of the hooks from an action. + * + * @param string $tag The action to remove hooks from. + * @param int|false $priority The priority number to remove them from. Default false. + * + * @return true True when finished. + */ + public function removeAllActions($tag, $priority = false) + { + return $this->removeAllFilters($tag, $priority); + } + + /** + * Retrieve the name of the current filter or action. + * + * @global string[] $wp_current_filter Stores the list of current filters with the current one last + * + * @return string Hook name of the current filter or action. + */ + public function currentFilter() + { + return end($this->currentFilter); + } + + /** + * Retrieve the name of the current action. + * + * @return string Hook name of the current action. + */ + public function currentAction() + { + return $this->currentFilter(); + } + + /** + * Call the 'all' hook, which will process the functions hooked into it. + * + * The 'all' hook passes all of the arguments or parameters that were used for + * the hook, which this function was called for. + * + * This function is used internally for apply_filters(), do_action(), and + * do_action_ref_array() and is not meant to be used from outside those + * functions. This function does not check for the existence of the all hook, so + * it will fail unless the all hook exists prior to this function call. + * + * @global Hook[] $this->filters Stores all of the filters and actions. + * + * @param array $args The collected parameters from the hook that was called. + * + * @return void + */ + private function callAllHook($args) + { + $this->filters['all']->doAllHook($args); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/DescriptorInterface.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/DescriptorInterface.php new file mode 100644 index 0000000..ac03f70 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/DescriptorInterface.php @@ -0,0 +1,36 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamOption; +use Duplicator\Installer\Utils\Log\Log; +use DUPX_InstallerState; +use DUPX_Template; +use DUPX_TemplateItem; +use Exception; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescConfigs implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_INST_TYPE] = new ParamForm( + PrmMng::PARAM_INST_TYPE, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_RADIO, + array( + 'default' => DUPX_InstallerState::INSTALL_NOT_SET, + 'acceptValues' => array(__CLASS__, 'getInstallTypesAcceptValues') + ), + array( + 'status' => ParamForm::STATUS_ENABLED, + 'label' => 'Install Type:', + 'wrapperClasses' => array('group-block', 'revalidate-on-change'), + 'options' => self::getInstallTypeOptions(), + // Temporarly diabled for inital release 1.5 + // 'proFlagTitle' => 'Upgrade Features', + // 'proFlag' => 'Improve the install experiance with support for these popular install modes:' + // . '
          ' . + // '
        • Full Multisite Support
        • ' . + // '
        • Install from Remote Server
        • ' . + // '
        • Restore from Recovery Point
        • ' . + // '
        ' + ) + ); + + $params[PrmMng::PARAM_WP_CONFIG] = new ParamForm( + PrmMng::PARAM_WP_CONFIG, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => 'modify', + 'acceptValues' => array( + 'modify', + 'nothing', + 'new' + ) + ), + array( + 'label' => 'WordPress:', + 'wrapperClasses' => 'medium', + 'status' => function (ParamItem $paramObj) { + if ( + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'options' => array( + new ParamOption('nothing', 'Do nothing'), + new ParamOption('modify', 'Modify original'), + new ParamOption('new', 'Create new from wp-config sample') + ), + 'subNote' => 'wp-config.php' + ) + ); + + $params[PrmMng::PARAM_HTACCESS_CONFIG] = new ParamForm( + PrmMng::PARAM_HTACCESS_CONFIG, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => 'new', + 'acceptValues' => array( + 'new', + 'original', + 'nothing' + ) + ), + array( + 'label' => 'Apache:', + 'wrapperClasses' => 'medium', + 'status' => function (ParamItem $paramObj) { + if ( + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'options' => array( + new ParamOption('nothing', 'Do nothing'), + new ParamOption('original', 'Retain original from Archive.zip/daf'), + new ParamOption('new', 'Create new (recommended)') + ), + 'subNote' => '.htaccess' + ) + ); + + $params[PrmMng::PARAM_OTHER_CONFIG] = new ParamForm( + PrmMng::PARAM_OTHER_CONFIG, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => 'new', + 'acceptValues' => array( + 'new', + 'original', + 'nothing' + ) + ), + array( + 'label' => 'General:', + 'wrapperClasses' => 'medium', + 'status' => function (ParamItem $paramObj) { + if ( + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'options' => array( + new ParamOption('nothing', 'Do nothing'), + new ParamOption('original', 'Retain original from Archive.zip/daf'), + new ParamOption('new', 'Reset') + ), + 'subNote' => 'includes: php.ini, .user.ini, web.config' + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + $installType = $params[PrmMng::PARAM_INST_TYPE]->getValue(); + if ($installType == DUPX_InstallerState::INSTALL_NOT_SET) { + $acceptValues = $params[PrmMng::PARAM_INST_TYPE]->getAcceptValues(); + $params[PrmMng::PARAM_INST_TYPE]->setValue(self::getInstTypeByPriority($acceptValues)); + } + + $installType = $params[PrmMng::PARAM_INST_TYPE]->getValue(); + if (DUPX_InstallerState::isRestoreBackup($installType)) { + if (\DUPX_Custom_Host_Manager::getInstance()->isManaged()) { + $params[PrmMng::PARAM_WP_CONFIG]->setValue('nothing'); + $params[PrmMng::PARAM_HTACCESS_CONFIG]->setValue('nothing'); + $params[PrmMng::PARAM_OTHER_CONFIG]->setValue('nothing'); + } else { + $params[PrmMng::PARAM_WP_CONFIG]->setValue('modify'); + $params[PrmMng::PARAM_HTACCESS_CONFIG]->setValue('original'); + $params[PrmMng::PARAM_OTHER_CONFIG]->setValue('original'); + } + } + } + + /** + * Return default install type from install types enabled + * + * @param int[] $acceptValues install types enabled + * + * @return int + */ + protected static function getInstTypeByPriority($acceptValues) + { + $defaultPriority = array( + DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE, + DUPX_InstallerState::INSTALL_SINGLE_SITE + ); + + foreach ($defaultPriority as $current) { + if (in_array($current, $acceptValues)) { + return $current; + } + } + + throw new Exception('No default value found on proprity list'); + } + + /** + * + * @return ParamOption[] + */ + protected static function getInstallTypeOptions() + { + $result = array(); + + $option = new ParamOption( + DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE, + 'Restore single site', + array(__CLASS__, 'typeOptionsVisibility') + ); + $result[] = $option; + + $option = new ParamOption( + DUPX_InstallerState::INSTALL_SINGLE_SITE, + 'Full install single site', + array(__CLASS__, 'typeOptionsVisibility') + ); + $result[] = $option; + + $option = new ParamOption( + DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBDOMAIN, + 'Import single site into multisite network', + array(__CLASS__, 'typeOptionsVisibility') + ); + $result[] = $option; + + $option = new ParamOption( + DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBFOLDER, + 'Import single site into multisite network', + array(__CLASS__, 'typeOptionsVisibility') + ); + $result[] = $option; + + return $result; + } + + /** + * Return option type status + * + * @param ParamOption $option install type option + * + * @return string option status + */ + public static function typeOptionsVisibility(ParamOption $option) + { + $archiveConfig = \DUPX_ArchiveConfig::getInstance(); + $overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + $isOwrMode = PrmMng::getInstance()->getValue(PrmMng::PARAM_INSTALLER_MODE) === DUPX_InstallerState::MODE_OVR_INSTALL; + + switch ($option->value) { + case DUPX_InstallerState::INSTALL_SINGLE_SITE: + if ($archiveConfig->mu_mode != 0) { + return ParamOption::OPT_HIDDEN; + } + break; + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBDOMAIN: + if (!$isOwrMode || !$overwriteData['isMultisite'] || !$overwriteData['subdomain']) { + return ParamOption::OPT_HIDDEN; + } + break; + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBFOLDER: + if (!$isOwrMode || !$overwriteData['isMultisite'] || $overwriteData['subdomain']) { + return ParamOption::OPT_HIDDEN; + } + break; + case DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE: + if ($archiveConfig->mu_mode != 0 || !DUPX_InstallerState::isInstallerCreatedInThisLocation()) { + return ParamOption::OPT_HIDDEN; + } + break; + case DUPX_InstallerState::INSTALL_NOT_SET: + default: + throw new Exception('Install type not valid ' . $option->value); + } + + $acceptValues = self::getInstallTypesAcceptValues(); + return in_array($option->value, $acceptValues) ? ParamOption::OPT_ENABLED : ParamOption::OPT_DISABLED; + } + + /** + * + * @return int[] + */ + public static function getInstallTypesAcceptValues() + { + $acceptValues = array(); + $isSameLocation = DUPX_InstallerState::isInstallerCreatedInThisLocation(); + + $acceptValues[] = DUPX_InstallerState::INSTALL_SINGLE_SITE; + if ($isSameLocation) { + $acceptValues[] = DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE; + } + + return $acceptValues; + } + + /** + * Return install type option note + * + * @param ParamOption $option install type option + * + * @return string + */ + public static function getInstallTypesNotes(ParamOption $option) + { + switch ($option->value) { + case DUPX_InstallerState::INSTALL_SINGLE_SITE: + return ''; + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBDOMAIN: + case DUPX_InstallerState::INSTALL_SINGLE_SITE_ON_SUBFOLDER: + return ''; + case DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE: + case DUPX_InstallerState::INSTALL_NOT_SET: + default: + throw new Exception('Install type not valid ' . $option->value); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescController.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescController.php new file mode 100644 index 0000000..5f91203 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescController.php @@ -0,0 +1,184 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescController implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_FINAL_REPORT_DATA] = new ParamItem( + PrmMng::PARAM_FINAL_REPORT_DATA, + ParamItem::TYPE_ARRAY_MIXED, + array( + 'default' => array( + 'extraction' => array( + 'table_count' => 0, + 'table_rows' => 0, + 'query_errs' => 0, + ), + 'replace' => array( + 'scan_tables' => 0, + 'scan_rows' => 0, + 'scan_cells' => 0, + 'updt_tables' => 0, + 'updt_rows' => 0, + 'updt_cells' => 0, + 'errsql' => 0, + 'errser' => 0, + 'errkey' => 0, + 'errsql_sum' => 0, + 'errser_sum' => 0, + 'errkey_sum' => 0, + 'err_all' => 0, + 'warn_all' => 0, + 'warnlist' => array() + ) + ) + ) + ); + + $params[PrmMng::PARAM_INSTALLER_MODE] = new ParamItem( + PrmMng::PARAM_INSTALLER_MODE, + ParamItem::TYPE_INT, + array( + 'default' => \DUPX_InstallerState::MODE_UNKNOWN, + 'acceptValues' => array( + \DUPX_InstallerState::MODE_UNKNOWN, + \DUPX_InstallerState::MODE_STD_INSTALL, + \DUPX_InstallerState::MODE_OVR_INSTALL + ) + ) + ); + + $params[PrmMng::PARAM_OVERWRITE_SITE_DATA] = new ParamItem( + PrmMng::PARAM_OVERWRITE_SITE_DATA, + ParamItem::TYPE_ARRAY_MIXED, + array( + 'default' => DUPX_InstallerState::overwriteDataDefault() + ) + ); + + + $params[PrmMng::PARAM_DEBUG] = new ParamItem( + PrmMng::PARAM_DEBUG, + ParamItem::TYPE_BOOL, + array( + 'persistence' => true, + 'default' => false + ) + ); + + $params[PrmMng::PARAM_DEBUG_PARAMS] = new ParamItem( + PrmMng::PARAM_DEBUG_PARAMS, + ParamItem::TYPE_BOOL, + array( + 'persistence' => true, + 'default' => false + ) + ); + + $params[PrmMng::PARAM_CTRL_ACTION] = new ParamItem( + PrmMng::PARAM_CTRL_ACTION, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_HIDDEN, + array( + 'persistence' => false, + 'default' => '', + 'acceptValues' => array( + '', + 'ajax', + 'secure', + 'ctrl-step1', + 'ctrl-step2', + 'ctrl-step3', + 'ctrl-step4', + 'help' + )) + ); + + $params[PrmMng::PARAM_STEP_ACTION] = new ParamItem( + PrmMng::PARAM_STEP_ACTION, + ParamForm::TYPE_STRING, + array( + 'persistence' => false, + 'default' => '', + 'acceptValues' => array( + '', + \DUPX_CTRL::ACTION_STEP_INIZIALIZED, + \DUPX_CTRL::ACTION_STEP_ON_VALIDATE, + \DUPX_CTRL::ACTION_STEP_SET_TEMPLATE + )) + ); + + $params[\DUPX_Security::CTRL_TOKEN] = new ParamItem( + \DUPX_Security::CTRL_TOKEN, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_HIDDEN, + array( + 'persistence' => false, + 'default' => null, + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline') + ) + ); + + $params[PrmMng::PARAM_ROUTER_ACTION] = new ParamItem( + PrmMng::PARAM_ROUTER_ACTION, + ParamItem::TYPE_STRING, + array( + 'persistence' => false, + 'default' => 'router', + 'acceptValues' => array( + 'router' + )) + ); + + $params[PrmMng::PARAM_TEMPLATE] = new ParamItem( + PrmMng::PARAM_TEMPLATE, + ParamForm::TYPE_STRING, + array( + 'default' => \DUPX_Template::TEMPLATE_BASE, + 'acceptValues' => array( + \DUPX_Template::TEMPLATE_BASE, + \DUPX_Template::TEMPLATE_ADVANCED, + \DUPX_Template::TEMPLATE_IMPORT_BASE, + \DUPX_Template::TEMPLATE_IMPORT_ADVANCED + )) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescDatabase.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescDatabase.php new file mode 100644 index 0000000..6a2afeb --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescDatabase.php @@ -0,0 +1,506 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Descriptors\ParamsDescriptors; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamOption; +use Duplicator\Installer\Core\Params\Items\ParamFormTables; +use Duplicator\Installer\Core\Params\Items\ParamFormPass; +use Duplicator\Installer\Utils\Log\Log; +use Duplicator\Libs\Snap\SnapJson; +use Duplicator\Libs\Snap\SnapUtil; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescDatabase implements DescriptorInterface +{ + const INVALID_EMPTY = 'can\'t be empty'; + const EMPTY_COLLATION_LABEL = ' --- DEFAULT --- '; + const DEFAULT_CHARSET_POSTFIX = ' (Default)'; + const DEFAULT_COLLATE_POSTFIX = ' (Default)'; + const SPLIT_CREATE_MAX_VALUE_TO_DEFAULT = 200; + + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $archiveConfig = \DUPX_ArchiveConfig::getInstance(); + + $params[PrmMng::PARAM_DB_DISPLAY_OVERWIRE_WARNING] = new ParamItem( + PrmMng::PARAM_DB_DISPLAY_OVERWIRE_WARNING, + ParamItem::TYPE_BOOL, + array( + 'default' => true + ) + ); + + $params[PrmMng::PARAM_DB_VIEW_MODE] = new ParamForm( + PrmMng::PARAM_DB_VIEW_MODE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_BGROUP, + array( + 'default' => 'basic', + 'acceptValues' => array( + 'basic', + 'cpnl' + ) + ), + array( + 'label' => 'Database view mode', + 'renderLabel' => false, + 'options' => array( + new ParamOption('basic', 'Default'), + new ParamOption('cpnl', 'cPanel') + ), + 'wrapperClasses' => array('revalidate-on-change', 'align-right'), + 'inputContainerClasses' => array('small') + ) + ); + + $params[PrmMng::PARAM_DB_HOST] = new ParamForm( + PrmMng::PARAM_DB_HOST, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'persistence' => true, + 'default' => 'localhost', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline'), + 'validateCallback' => array(__CLASS__, 'validateNoEmptyIfBasic'), + 'invalidMessage' => self::INVALID_EMPTY + ), + array( + 'label' => 'Host:', + 'wrapperClasses' => array('revalidate-on-change'), + 'attr' => array( + 'required' => 'required', + 'placeholder' => 'localhost' + ) + ) + ); + + $params[PrmMng::PARAM_DB_NAME] = new ParamForm( + PrmMng::PARAM_DB_NAME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'persistence' => true, + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline'), + 'validateCallback' => array(__CLASS__, 'validateNoEmptyIfBasic'), + 'invalidMessage' => self::INVALID_EMPTY + ), + array( + 'label' => 'Database:', + 'wrapperClasses' => array('revalidate-on-change'), + 'attr' => array( + 'required' => 'required', + 'placeholder' => 'new or existing database name' + ), + 'subNote' => dupxTplRender('parts/params/db-name-notes', array(), false) + ) + ); + + $params[PrmMng::PARAM_DB_USER] = new ParamForm( + PrmMng::PARAM_DB_USER, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'persistence' => true, + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline'), + 'validateCallback' => array(__CLASS__, 'validateNoEmptyIfBasic'), + 'invalidMessage' => self::INVALID_EMPTY + ), + array( + 'label' => 'User:', + 'wrapperClasses' => array('revalidate-on-change'), + 'attr' => array( + 'placeholder' => 'valid database username', + // Can be written field wise + // Ref. https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion + 'autocomplete' => "off" + ) + ) + ); + + $params[PrmMng::PARAM_DB_PASS] = new ParamFormPass( + PrmMng::PARAM_DB_PASS, + ParamFormPass::TYPE_STRING, + ParamFormPass::FORM_TYPE_PWD_TOGGLE, + array( + 'persistence' => true, + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline') + ), + array( + 'label' => 'Password:', + 'wrapperClasses' => array('revalidate-on-change'), + 'attr' => array( + 'placeholder' => 'valid database user password', + // Can be written field wise + // Ref. https://devBasicBasiceloper.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion + 'autocomplete' => "off" + ) + ) + ); + + $params[PrmMng::PARAM_DB_FLAG] = new ParamItem( + PrmMng::PARAM_DB_FLAG, + ParamForm::TYPE_INT, + array( + 'default' => \DUPX_DB::DB_CONNECTION_FLAG_NOT_SET, + 'acceptValues' => function (ParamItem $param) { + $result = array( + \DUPX_DB::MYSQLI_CLIENT_NO_FLAGS, + MYSQLI_CLIENT_SSL, + ); + if (defined("MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT")) { + // phpcs:ignore PHPCompatibility.Constants.NewConstants.mysqli_client_ssl_dont_verify_server_certFound + $result[] = MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT; + } + return $result; + } + ) + ); + + $params[PrmMng::PARAM_DB_CHARSET] = new ParamForm( + PrmMng::PARAM_DB_CHARSET, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => $archiveConfig->getWpConfigDefineValue('DB_CHARSET', ''), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateRegex' => ParamForm::VALIDATE_REGEX_AZ_NUMBER_SEP_EMPTY + ), + array( + 'label' => 'Charset:', + 'status' => function (ParamForm $param) { + if (DUPX_InstallerState::isRestoreBackup()) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'options' => array(__CLASS__, 'getCharsetSelectOptions') + ) + ); + + $params[PrmMng::PARAM_DB_COLLATE] = new ParamForm( + PrmMng::PARAM_DB_COLLATE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => $archiveConfig->getWpConfigDefineValue('DB_COLLATE', ''), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateRegex' => ParamForm::VALIDATE_REGEX_AZ_NUMBER_SEP_EMPTY + ), + array( + 'label' => 'Collation:', + 'status' => function () { + if (DUPX_InstallerState::isRestoreBackup()) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'options' => array(__CLASS__, 'getCollationSelectOptions') + ) + ); + + $params[PrmMng::PARAM_DB_TABLE_PREFIX] = new ParamForm( + PrmMng::PARAM_DB_TABLE_PREFIX, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => \DUPX_ArchiveConfig::getInstance()->wp_tableprefix, + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateRegex' => ParamForm::VALIDATE_REGEX_AZ_NUMBER_SEP + ), + array( + 'status' => function () { + return ParamForm::STATUS_DISABLED; + }, + 'label' => 'Table Prefix:', + 'proFlagTitle' => 'Upgrade Features', + 'proFlag' => '

        Enhance the install experiance by changing the table prefix to a new name during installation.

        ' + ) + ); + + $params[PrmMng::PARAM_DB_VIEW_CREATION] = new ParamForm( + PrmMng::PARAM_DB_VIEW_CREATION, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => true + ), + array( + 'label' => 'Objects:', + 'checkboxLabel' => 'Enable View Creation' + ) + ); + + $params[PrmMng::PARAM_DB_PROC_CREATION] = new ParamForm( + PrmMng::PARAM_DB_PROC_CREATION, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => true + ), + array( + 'label' => ' ', + 'checkboxLabel' => 'Enable Stored Procedure Creation' + ) + ); + + $params[PrmMng::PARAM_DB_FUNC_CREATION] = new ParamForm( + PrmMng::PARAM_DB_FUNC_CREATION, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => true + ), + array( + 'label' => ' ', + 'checkboxLabel' => 'Enable Function Creation' + ) + ); + + $params[PrmMng::PARAM_DB_REMOVE_DEFINER] = new ParamForm( + PrmMng::PARAM_DB_REMOVE_DEFINER, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => ' ', + 'checkboxLabel' => 'Remove security DEFINER declarations' + ) + ); + + $numTables = count((array) \DUPX_ArchiveConfig::getInstance()->dbInfo->tablesList); + $params[PrmMng::PARAM_DB_SPLIT_CREATES] = new ParamForm( + PrmMng::PARAM_DB_SPLIT_CREATES, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => ($numTables > self::SPLIT_CREATE_MAX_VALUE_TO_DEFAULT ? false : true) + ), + array( + 'label' => 'Create:', + 'checkboxLabel' => 'Run all CREATE SQL statements at once' + ) + ); + + $newObj = new ParamForm( + PrmMng::PARAM_DB_MYSQL_MODE_OPTS, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '', + 'validateRegex' => '/^[A-Za-z0-9_\-,]*$/', // db options with , and can be empty + 'sanitizeCallback' => function ($value) { + $value = SnapUtil::sanitizeNSCharsNewlineTrim($value); + return str_replace(' ', '', $value); + }, + ), + array( + 'label' => ' ', // for aligment at PARAM_DB_MYSQL_MODE + 'wrapperClasses' => 'no-display', + 'subNote' => 'Separate additional ' . \DUPX_View_Funcs::helpLink('step2', 'sql modes', false) . ' with commas & no spaces.
        ' + . 'Example: NO_ENGINE_SUBSTITUTION,NO_ZERO_IN_DATE,....' + ) + ); + $params[PrmMng::PARAM_DB_MYSQL_MODE_OPTS] = $newObj; + $modeOptsWrapper = $newObj->getFormWrapperId(); + + $params[PrmMng::PARAM_DB_MYSQL_MODE] = new ParamForm( + PrmMng::PARAM_DB_MYSQL_MODE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_RADIO, + array( + 'default' => 'DEFAULT', + 'acceptValues' => array( + 'DEFAULT', + 'DISABLE', + 'CUSTOM' + ) + ), + array( + 'label' => 'Mode:', + 'options' => array( + new ParamOption('DEFAULT', 'Default', ParamOption::OPT_ENABLED, array( + 'onchange' => "if ($(this).is(':checked')) { " + . "jQuery('#" . $modeOptsWrapper . "').addClass('no-display');" + . "}" + )), + new ParamOption('DISABLE', 'Disable', ParamOption::OPT_ENABLED, array( + 'onchange' => "if ($(this).is(':checked')) { " + . "jQuery('#" . $modeOptsWrapper . "').addClass('no-display');" + . "}" + )), + new ParamOption('CUSTOM', 'Custom', ParamOption::OPT_ENABLED, array( + 'onchange' => "if ($(this).is(':checked')) { " + . "jQuery('#" . $modeOptsWrapper . "').removeClass('no-display');" + . "}")), + )) + ); + + $params[PrmMng::PARAM_DB_TABLES] = new ParamFormTables( + PrmMng::PARAM_DB_TABLES, + ParamFormTables::TYPE_ARRAY_TABLES, + ParamFormTables::FORM_TYPE_TABLES_SELECT, + array(// ITEM ATTRIBUTES + 'default' => array() + ), + array(// FORM ATTRIBUTES + 'label' => 'Tables', + 'renderLabel' => false, + 'status' => function (ParamForm $paramObj) { + if (DUPX_InstallerState::isRestoreBackup()) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + } + ) + ); + } + + /** + * Validate function for database params + * + * @param mixed $value input value + * @param ParamItem $paramObj current param object + * + * @return boolean + */ + public static function validateNoEmptyIfBasic($value, ParamItem $paramObj) + { + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_VIEW_MODE) !== 'basic') { + return true; + } + + return ParamsDescriptors::validateNotEmpty($value, $paramObj); + } + + /** + * Get charset options list + * + * @return ParamOption[] + */ + public static function getCharsetSelectOptions() + { + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_VALIDATION_LEVEL) < \DUPX_Validation_manager::MIN_LEVEL_VALID) { + return array(); + } + + $data = \DUPX_DB_Functions::getInstance()->getCharsetAndCollationData(); + $charsetDef = \DUPX_DB_Functions::getInstance()->getDefaultCharset(); + + $options = array(); + + foreach ($data as $charset => $charsetInfo) { + $label = $charset . ($charset == $charsetDef ? self::DEFAULT_CHARSET_POSTFIX : ''); + $options[] = new ParamOption($charset, $label, ParamOption::OPT_ENABLED, array( + 'data-collations' => json_encode($charsetInfo['collations']), + 'data-collation-default' => $charsetInfo['defCollation'] + )); + } + + return $options; + } + + /** + * Get collation options list + * + * @return ParamOption[] + */ + public static function getCollationSelectOptions() + { + $options = array( + new ParamOption('', self::EMPTY_COLLATION_LABEL) + ); + + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_VALIDATION_LEVEL) < \DUPX_Validation_manager::MIN_LEVEL_VALID) { + return $options; + } + + $data = \DUPX_DB_Functions::getInstance()->getCharsetAndCollationData(); + $currentCharset = PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_CHARSET); + + if (!isset($data[$currentCharset])) { + return $options; + } + + $defaultCollation = \DUPX_DB_Functions::getInstance()->getDefaultCollateOfCharset($currentCharset); + // if charset exists update default + $options = array( + new ParamOption('', self::EMPTY_COLLATION_LABEL . ' [' . $defaultCollation . ']') + ); + + foreach ($data[$currentCharset]['collations'] as $collation) { + $label = $collation . ($collation == $data[$currentCharset]['defCollation'] ? self::DEFAULT_COLLATE_POSTFIX : ''); + $options[] = new ParamOption($collation, $label); + } + + return $options; + } + + /** + * Update Charset and collate param by database settings + * + * @return void + */ + public static function updateCharsetAndCollateByDatabaseSettings() + { + $paramsManager = PrmMng::getInstance(); + $data = \DUPX_DB_Functions::getInstance()->getCharsetAndCollationData(); + $charsetDef = \DUPX_DB_Functions::getInstance()->getDefaultCharset(); + + $currentCharset = $paramsManager->getValue(PrmMng::PARAM_DB_CHARSET); + $currentCollate = $paramsManager->getValue(PrmMng::PARAM_DB_COLLATE); + + if (!array_key_exists($currentCharset, $data)) { + $paramsManager->setValue(PrmMng::PARAM_DB_CHARSET, $charsetDef); + $paramsManager->setValue(PrmMng::PARAM_DB_COLLATE, ''); + Log::info('DEFAULT DB_CHARSET [' . $currentCharset . '] isn\'t valid, update DB_CHARSET to ' . $charsetDef . ' and DB_COLLATE set empty'); + } elseif (strlen($currentCollate) > 0 && !in_array($currentCollate, $data[$currentCharset]['collations'])) { + $paramsManager->setValue(PrmMng::PARAM_DB_COLLATE, ''); + Log::info('DEFAULT DB_COLLATE [' . $currentCollate . '] isn\'t valid, DB_COLLATE set empty'); + } + $paramsManager->save(); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + $params[PrmMng::PARAM_DB_TABLES]->setValue(\DUPX_DB_Tables::getInstance()->getDefaultParamValue()); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescEngines.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescEngines.php new file mode 100644 index 0000000..e4d85f8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescEngines.php @@ -0,0 +1,446 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use DUP_Extraction; +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamOption; +use DUPX_InstallerState; +use DUPX_ArchiveConfig; +use Duplicator\Installer\Utils\InstallerLinkManager; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescEngines implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $archiveConfig = \DUPX_ArchiveConfig::getInstance(); + + $params[PrmMng::PARAM_ARCHIVE_ACTION] = new ParamForm( + PrmMng::PARAM_ARCHIVE_ACTION, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => DUP_Extraction::ACTION_DO_NOTHING, + 'acceptValues' => array( + DUP_Extraction::ACTION_DO_NOTHING, + DUP_Extraction::ACTION_REMOVE_WP_FILES, + DUP_Extraction::ACTION_REMOVE_ALL_FILES + ) + ), + array( + 'label' => 'Archive Action:', + 'status' => function ($paramObj) { + if (DUPX_InstallerState::isRestoreBackup()) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'options' => array( + new ParamOption(DUP_Extraction::ACTION_DO_NOTHING, 'Extract files over current files'), + new ParamOption(DUP_Extraction::ACTION_REMOVE_WP_FILES, 'Remove WordPress core and content and extract (Pro)', ParamOption::OPT_DISABLED), + new ParamOption(DUP_Extraction::ACTION_REMOVE_ALL_FILES, 'Remove all files except addon sites and extract (Pro)', ParamOption::OPT_DISABLED), + new ParamOption(DUP_Extraction::ACTION_REMOVE_UPLOADS, 'Empty only uploads folder (Pro)', ParamOption::OPT_DISABLED) + ), + 'wrapperClasses' => array('revalidate-on-change'), + 'subNote' => function ($param) { + return dupxTplRender('parts/params/archive-action-notes', array( + 'currentAction' => $param->getValue() + ), false); + }, + // Temporarly diabled for inital release 1.5 + // 'proFlagTitle' => 'Upgrade Features', + // 'proFlag' => 'Enhance the install experience with custom extraction modes. + // When performing an overwrite install process users can ' + // . 'automate and customize that files they need to be installed.' + ) + ); + + $params[PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES] = new ParamForm( + PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => DUP_Extraction::FILTER_NONE, + 'acceptValues' => array(DUP_Extraction::FILTER_NONE) + ), + array( + 'label' => 'Skip Files:', + 'status' => ParamForm::STATUS_ENABLED, + 'options' => array( + new ParamOption(DUP_Extraction::FILTER_NONE, 'Extract all files'), + new ParamOption(DUP_Extraction::FILTER_SKIP_WP_CORE, 'Skip extraction of WordPress core files (Pro)', ParamOption::OPT_DISABLED), + new ParamOption( + DUP_Extraction::FILTER_SKIP_CORE_PLUG_THEMES, + 'Skip extraction of WordPress core files and plugins/themes existing on host (Pro)', + ParamOption::OPT_DISABLED + ), + new ParamOption( + DUP_Extraction::FILTER_ONLY_MEDIA_PLUG_THEMES, + 'Extract only media files and new plugins/themes (Pro)', + ParamOption::OPT_DISABLED + ) + ), + 'wrapperClasses' => array('revalidate-on-change'), + 'subNote' => dupxTplRender('parts/params/extract-skip-notes', array( + 'currentSkipMode' => DUP_Extraction::FILTER_NONE + ), false), + // Temporarly diabled for inital release 1.5 + // 'proFlagTitle' => 'Upgrade Features', + // 'proFlag' => 'Exclude plugins and themes from extraction so as not to overwrite existing ones' . + // '
          ' . + // '
        • Skip extraction of WP core files
        • ' . + // '
        • Skip extraction of WP core files & plugins/themes existing on the host
        • ' . + // '
        • Extract only media files & new plugins/themes
        • ' . + // '
        ' + ) + ); + + $engineOptions = self::getArchiveEngineOptions(); + + $params[PrmMng::PARAM_ARCHIVE_ENGINE] = new ParamForm( + PrmMng::PARAM_ARCHIVE_ENGINE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => $engineOptions['default'], + 'acceptValues' => $engineOptions['acceptValues'], + 'sanitizeCallback' => function ($value) { + if ( + PrmMng::getInstance()->getValue( + PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES + ) !== DUP_Extraction::FILTER_NONE && $value === DUP_Extraction::ENGINE_ZIP_SHELL + ) { + return DUP_Extraction::ENGINE_ZIP_CHUNK; + } + return $value; + } + ), + array( + 'label' => 'Extraction Mode:', + 'options' => $engineOptions['options'], + 'size' => 0, + 'subNote' => $engineOptions['subNote'], + 'attr' => array( + 'onchange' => 'DUPX.onSafeModeSwitch();' + ) + ) + ); + + $params[PrmMng::PARAM_ZIP_THROTTLING] = new ParamForm( + PrmMng::PARAM_ZIP_THROTTLING, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => 'Server Throttling:', + 'checkboxLabel' => 'Enable archive extraction throttling', + 'status' => function () { + if ( + PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE) === DUP_Extraction::ENGINE_ZIP + || PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE) === DUP_Extraction::ENGINE_ZIP_CHUNK + ) { + return ParamForm::STATUS_ENABLED; + } else { + return ParamForm::STATUS_DISABLED; + } + }, + 'subNote' => '* This option is only available with Zip Formats' + ) + ); + + $params[PrmMng::PARAM_DB_ACTION] = new ParamForm( + PrmMng::PARAM_DB_ACTION, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => 'empty', + 'acceptValues' => array( + \DUPX_DBInstall::DBACTION_CREATE, + \DUPX_DBInstall::DBACTION_EMPTY, + \DUPX_DBInstall::DBACTION_REMOVE_ONLY_TABLES, + \DUPX_DBInstall::DBACTION_RENAME, + \DUPX_DBInstall::DBACTION_MANUAL, + \DUPX_DBInstall::DBACTION_ONLY_CONNECT + ) + ), + array( + 'label' => 'Action:', + 'status' => function ($paramObj) { + if ( + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'wrapperClasses' => array('revalidate-on-change'), + 'options' => array( + new ParamOption(\DUPX_DBInstall::DBACTION_EMPTY, 'Empty Database'), + new ParamOption(\DUPX_DBInstall::DBACTION_RENAME, 'Backup Existing Tables'), + new ParamOption(\DUPX_DBInstall::DBACTION_ONLY_CONNECT, 'Do Nothing (Advanced)', ParamOption::OPT_HIDDEN), + new ParamOption(\DUPX_DBInstall::DBACTION_MANUAL, 'Skip Database Extraction'), + new ParamOption(\DUPX_DBInstall::DBACTION_CREATE, 'Create New Database'), + new ParamOption(\DUPX_DBInstall::DBACTION_REMOVE_ONLY_TABLES, 'Overwrite Existing Tables (Pro)', ParamOption::OPT_DISABLED), + ), + // Temporarly diabled for inital release 1.5 + // 'proFlagTitle' => 'Upgrade Features', + // 'proFlag' => + // 'Duplicator Pro offers these additional actions on the database for greater flexibility.' + // . '
          ' . + // '
        • Create New Database
        • ' . + // '
        • Overwrite Existing Tables
        • ' . + // '
        ' . + // 'Users can create a new database on supported servers or act only on installation-specific tables without touching ' + // . 'others tables. This process is useful if you want to install multiple instances of worpdress in the same database.' + ) + ); + + $params[PrmMng::PARAM_DB_ENGINE] = new ParamForm( + PrmMng::PARAM_DB_ENGINE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => \DUPX_DBInstall::ENGINE_CHUNK, + 'acceptValues' => array( + \DUPX_DBInstall::ENGINE_CHUNK, + \DUPX_DBInstall::ENGINE_NORMAL + )), + array( + 'label' => 'Processing:', + 'size' => 0, + 'options' => array( + new ParamOption(\DUPX_DBInstall::ENGINE_CHUNK, 'Chunking mode'), + new ParamOption(\DUPX_DBInstall::ENGINE_NORMAL, 'Single step') + )) + ); + + $params[PrmMng::PARAM_DB_CHUNK] = new ParamItem( + PrmMng::PARAM_DB_CHUNK, + ParamForm::TYPE_BOOL, + array( + 'default' => ($params[PrmMng::PARAM_DB_ENGINE]->getValue() === \DUPX_DBInstall::ENGINE_CHUNK) + ) + ); + + $params[PrmMng::PARAM_REPLACE_ENGINE] = new ParamItem( + PrmMng::PARAM_REPLACE_ENGINE, + ParamForm::TYPE_INT, + array( + 'default' => \DUPX_S3_Funcs::MODE_CHUNK, + 'acceptValues' => array( + \DUPX_S3_Funcs::MODE_NORMAL, + \DUPX_S3_Funcs::MODE_CHUNK, + \DUPX_S3_Funcs::MODE_SKIP, + )) + ); + + $oldHomePath = DUPX_ArchiveConfig::getInstance()->getRealValue('archivePaths')->home; + $params[PrmMng::PARAM_SKIP_PATH_REPLACE] = new ParamForm( + PrmMng::PARAM_SKIP_PATH_REPLACE, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => in_array($oldHomePath, array('', '/html')) + ), + array( + 'label' => 'Skip Path Replace:', + 'checkboxLabel' => 'Skips the replacement of the source path', + 'status' => function (ParamForm $paramObj) { + $sourcePath = PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_OLD); + if (strlen($sourcePath) == 0) { + return ParamForm::STATUS_DISABLED; + } else { + return ParamForm::STATUS_ENABLED; + } + } + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + if ( + $params[PrmMng::PARAM_ARCHIVE_ACTION]->getStatus() !== ParamItem::STATUS_OVERWRITE && + DUPX_InstallerState::isRestoreBackup($params[PrmMng::PARAM_INST_TYPE]->getValue()) + ) { + $params[PrmMng::PARAM_ARCHIVE_ACTION]->setValue(DUP_Extraction::ACTION_REMOVE_WP_FILES); + } + + if (DUPX_InstallerState::isRestoreBackup($params[PrmMng::PARAM_INST_TYPE]->getValue())) { + $default = \DUPX_S3_Funcs::MODE_SKIP; + } elseif ($params[PrmMng::PARAM_DB_ENGINE]->getValue() === \DUPX_DBInstall::ENGINE_CHUNK) { + $default = \DUPX_S3_Funcs::MODE_CHUNK; + } else { + $default = \DUPX_S3_Funcs::MODE_NORMAL; + } + $params[PrmMng::PARAM_REPLACE_ENGINE]->setValue($default); + + if ( + ($params[PrmMng::PARAM_ARCHIVE_ENGINE]->getValue() === DUP_Extraction::ENGINE_ZIP + || $params[PrmMng::PARAM_ARCHIVE_ENGINE]->getValue() === DUP_Extraction::ENGINE_ZIP_CHUNK) + && \DUPX_Custom_Host_Manager::getInstance()->isHosting(\DUPX_Custom_Host_Manager::HOST_SITEGROUND) + ) { + $params[PrmMng::PARAM_ZIP_THROTTLING]->setValue(true); + } + } + + /** + * Get db chunk engine value + * + * @return boolean + */ + public static function getDbChunkFromParams() + { + return PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_ENGINE) === \DUPX_DBInstall::ENGINE_CHUNK; + } + + /** + * Get replace engine mode + * + * @return integer + */ + public static function getReplaceEngineModeFromParams() + { + $paramsManager = PrmMng::getInstance(); + if (DUPX_InstallerState::isRestoreBackup()) { + return \DUPX_S3_Funcs::MODE_SKIP; + } elseif ($paramsManager->getValue(PrmMng::PARAM_DB_ENGINE) === \DUPX_DBInstall::ENGINE_CHUNK) { + return \DUPX_S3_Funcs::MODE_CHUNK; + } else { + return \DUPX_S3_Funcs::MODE_NORMAL; + } + } + + + /** + * Get archive engine options + * + * @return array + */ + private static function getArchiveEngineOptions() + { + $archiveConfig = \DUPX_ArchiveConfig::getInstance(); + + $acceptValues = array(); + $subNote = null; + if (($manualEnable = \DUPX_Conf_Utils::isManualExtractFilePresent()) === true) { + $acceptValues[] = DUP_Extraction::ENGINE_MANUAL; + } else { + $faqUrl = InstallerLinkManager::getDocUrl('how-to-handle-various-install-scenarios', 'install', 'archive engine subnote'); + $subNote = <<[more info] +SUBNOTEHTML; + } + if (($zipEnable = ($archiveConfig->isZipArchive() && \DUPX_Conf_Utils::archiveExists() && \DUPX_Conf_Utils::classZipArchiveEnable())) === true) { + $acceptValues[] = DUP_Extraction::ENGINE_ZIP; + $acceptValues[] = DUP_Extraction::ENGINE_ZIP_CHUNK; + } + if (($shellZipEnable = ($archiveConfig->isZipArchive() && \DUPX_Conf_Utils::archiveExists() && \DUPX_Conf_Utils::shellExecUnzipEnable())) === true) { + $acceptValues[] = DUP_Extraction::ENGINE_ZIP_SHELL; + } + if (($dupEnable = (!$archiveConfig->isZipArchive() && \DUPX_Conf_Utils::archiveExists())) === true) { + $acceptValues[] = DUP_Extraction::ENGINE_DUP; + } + + $options = array(); + $options[] = new ParamOption( + DUP_Extraction::ENGINE_MANUAL, + 'Manual Archive Extraction', + $manualEnable ? ParamOption::OPT_ENABLED : ParamOption::OPT_DISABLED + ); + + if ($archiveConfig->isZipArchive()) { + //ZIP-ARCHIVE + $options[] = new ParamOption( + DUP_Extraction::ENGINE_ZIP, + 'PHP ZipArchive', + $zipEnable ? ParamOption::OPT_ENABLED : ParamOption::OPT_DISABLED + ); + + $options[] = new ParamOption( + DUP_Extraction::ENGINE_ZIP_CHUNK, + 'PHP ZipArchive Chunking', + $zipEnable ? ParamOption::OPT_ENABLED : ParamOption::OPT_DISABLED + ); + + $options[] = new ParamOption( + DUP_Extraction::ENGINE_ZIP_SHELL, + 'Shell Exec Unzip', + function () { + $archiveConfig = \DUPX_ArchiveConfig::getInstance(); + $pathsMapping = $archiveConfig->getPathsMapping(); + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES) !== DUP_Extraction::FILTER_NONE) { + return ParamOption::OPT_DISABLED; + } + if (is_array($pathsMapping) && count($pathsMapping) > 1) { + return ParamOption::OPT_DISABLED; + } + if ($archiveConfig->isZipArchive() && \DUPX_Conf_Utils::archiveExists() && \DUPX_Conf_Utils::shellExecUnzipEnable()) { + return ParamOption::OPT_ENABLED; + } + return ParamOption::OPT_DISABLED; + } + ); + } else { + // DUPARCHIVE + $options[] = new ParamOption( + DUP_Extraction::ENGINE_DUP, + 'DupArchive', + $dupEnable ? ParamOption::OPT_ENABLED : ParamOption::OPT_DISABLED + ); + } + + if ($manualEnable) { + $default = DUP_Extraction::ENGINE_MANUAL; + } elseif ($zipEnable) { + $default = DUP_Extraction::ENGINE_ZIP_CHUNK; + } elseif ($shellZipEnable) { + $default = DUP_Extraction::ENGINE_ZIP_SHELL; + } elseif ($dupEnable) { + $default = DUP_Extraction::ENGINE_DUP; + } else { + $default = null; + } + + return array( + 'options' => $options, + 'acceptValues' => $acceptValues, + 'default' => $default, + 'subNote' => $subNote + ); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescGeneric.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescGeneric.php new file mode 100644 index 0000000..468229e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescGeneric.php @@ -0,0 +1,299 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamOption; +use Duplicator\Installer\Core\Params\Items\ParamFormPass; +use Duplicator\Installer\Utils\Log\Log; +use Duplicator\Libs\Snap\SnapOS; +use DUPX_ArchiveConfig; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescGeneric implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $newObj = new ParamForm( + PrmMng::PARAM_FILE_PERMS_VALUE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '644', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateRegex' => '/^[ugorwx,\s\+\-0-7]+$/' // octal + ugo rwx, + ), + array( + 'label' => 'File permissions', + 'renderLabel' => false, + 'status' => SnapOS::isWindows() ? ParamForm::STATUS_SKIP : ParamForm::STATUS_ENABLED, + 'wrapperClasses' => array('display-inline-block') + ) + ); + + $params[PrmMng::PARAM_FILE_PERMS_VALUE] = $newObj; + $permItemId = $newObj->getFormItemId(); + $params[PrmMng::PARAM_SET_FILE_PERMS] = new ParamForm( + PrmMng::PARAM_SET_FILE_PERMS, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_SWITCH, + array( + 'default' => !SnapOS::isWindows() + ), + array( + 'status' => SnapOS::isWindows() ? ParamForm::STATUS_SKIP : ParamForm::STATUS_ENABLED, + 'label' => 'File permissions:', + 'checkboxLabel' => 'All files', + 'wrapperClasses' => array('display-inline-block'), + 'attr' => array( + 'onclick' => "jQuery('#" . $permItemId . "').prop('disabled', !jQuery(this).is(':checked'));" + ) + ) + ); + + $newObj = new ParamForm( + PrmMng::PARAM_DIR_PERMS_VALUE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '755', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateRegex' => '/^[ugorwx,\s\+\-0-7]+$/' // octal + ugo rwx + ), + array( + 'label' => 'Folder permissions', + 'renderLabel' => false, + 'status' => SnapOS::isWindows() ? ParamForm::STATUS_SKIP : ParamForm::STATUS_ENABLED, + 'wrapperClasses' => array('display-inline-block') + ) + ); + + $params[PrmMng::PARAM_DIR_PERMS_VALUE] = $newObj; + $permItemId = $newObj->getFormItemId(); + $params[PrmMng::PARAM_SET_DIR_PERMS] = new ParamForm( + PrmMng::PARAM_SET_DIR_PERMS, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_SWITCH, + array( + 'default' => !SnapOS::isWindows() + ), + array( + 'status' => SnapOS::isWindows() ? ParamForm::STATUS_SKIP : ParamForm::STATUS_ENABLED, + 'label' => 'Dir permissions:', + 'checkboxLabel' => 'All Directories', + 'wrapperClasses' => array('display-inline-block'), + 'attr' => array( + 'onclick' => "jQuery('#" . $permItemId . "').prop('disabled', !jQuery(this).is(':checked'));" + ) + ) + ); + + $params[PrmMng::PARAM_SAFE_MODE] = new ParamForm( + PrmMng::PARAM_SAFE_MODE, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => 0, + 'acceptValues' => array(0, 1, 2) + ), + array( + 'label' => 'Safe Mode:', + 'status' => function (ParamItem $paramObj) { + if (DUPX_InstallerState::isRestoreBackup()) { + return ParamForm::STATUS_DISABLED; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'options' => array( + new ParamOption(0, 'Disabled'), + new ParamOption(1, 'Enabled') + ), + 'attr' => array( + 'onchange' => 'DUPX.onSafeModeSwitch();' + ) + ) + ); + + $params[PrmMng::PARAM_FILE_TIME] = new ParamForm( + PrmMng::PARAM_FILE_TIME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_RADIO, + array( + 'default' => 'current', + 'acceptValues' => array( + 'current', + 'original' + ) + ), + array( + 'label' => 'File Times:', + 'status' => ParamForm::STATUS_ENABLED, + 'options' => array( + new ParamOption('current', 'Current', ParamOption::OPT_ENABLED, array('title' => 'Set the files current date time to now')), + new ParamOption('original', 'Original', ParamOption::OPT_ENABLED, array('title' => 'Keep the files date time the same')) + ), + 'subNote' => 'This option is not supported for extraction mode Shell Exec Unzip' + ) + ); + + $params[PrmMng::PARAM_LOGGING] = new ParamForm( + PrmMng::PARAM_LOGGING, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_RADIO, + array( + 'default' => Log::LV_DEFAULT, + 'acceptValues' => array( + Log::LV_DEFAULT, + Log::LV_DETAILED, + Log::LV_DEBUG, + Log::LV_HARD_DEBUG, + ) + ), + array( + 'label' => 'Logging:', + 'options' => array( + new ParamOption(Log::LV_DEFAULT, 'Light'), + new ParamOption(Log::LV_DETAILED, 'Detailed'), + new ParamOption(Log::LV_DEBUG, 'Debug'), + // enabled only with overwrite params + new ParamOption(Log::LV_HARD_DEBUG, 'Hard debug', ParamOption::OPT_HIDDEN) + ) + ) + ); + + $params[PrmMng::PARAM_REMOVE_RENDUNDANT] = new ParamForm( + PrmMng::PARAM_REMOVE_RENDUNDANT, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => 'Cleanup:', + 'checkboxLabel' => 'Remove disabled plugins/themes (Pro)', + 'status' => ParamForm::STATUS_DISABLED, + 'proFlagTitle' => 'Upgrade Features', + 'proFlag' => '

        Improve the install cleanup and automation of additional tasks with these cleanup options that are available ' + . 'in Duplicator Pro.

        ' + ) + ); + + $params[PrmMng::PARAM_REMOVE_USERS_WITHOUT_PERMISSIONS] = new ParamForm( + PrmMng::PARAM_REMOVE_USERS_WITHOUT_PERMISSIONS, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => ' ', + 'checkboxLabel' => 'Remove users without permissions (Pro)', + 'status' => ParamForm::STATUS_DISABLED + ) + ); + + $params[PrmMng::PARAM_RECOVERY_LINK] = new ParamItem( + PrmMng::PARAM_RECOVERY_LINK, + ParamFormPass::TYPE_STRING, + array( + 'default' => '' + ) + ); + + $params[PrmMng::PARAM_FROM_SITE_IMPORT_INFO] = new ParamItem( + PrmMng::PARAM_FROM_SITE_IMPORT_INFO, + ParamFormPass::TYPE_ARRAY_MIXED, + array( + 'default' => array() + ) + ); + + $params[PrmMng::PARAM_AUTO_CLEAN_INSTALLER_FILES] = new ParamForm( + PrmMng::PARAM_AUTO_CLEAN_INSTALLER_FILES, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => true + ), + array( + 'label' => 'CLean installation files', + 'renderLabel' => false, + 'checkboxLabel' => 'Auto delete installer files after login to secure site (recommended!)' + ) + ); + + $params[PrmMng::PARAM_SUBSCRIBE_EMAIL] = new ParamForm( + PrmMng::PARAM_SUBSCRIBE_EMAIL, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'validateCallback' => function ($value, ParamItem $paramObj) { + if (strlen($value) < 4) { + $paramObj->setInvalidMessage('Email name must have 4 or more characters'); + return false; + } + + if (filter_var($value, FILTER_VALIDATE_EMAIL) == false) { + $paramObj->setInvalidMessage('Email "' . $value . '" isn\'t valid'); + return false; + } + + return true; + } + ), + array(// FORM ATTRIBUTES + 'label' => 'Subscribe to our newsletter:', + 'renderLabel' => false, + 'wrapperClasses' => array('subscribe-form'), + 'attr' => array( + 'placeholder' => 'Email Address' + ), + 'subNote' => 'Get tips and product updates straight to your inbox.', + 'status' => function ($paramObj) { + if ($paramObj->getValue() !== '') { + return ParamForm::STATUS_SKIP; + } + + return ParamForm::STATUS_ENABLED; + }, + 'postfix' => array('type' => 'button', 'label' => 'Subscribe', 'btnAction' => 'DUPX.submitEmail(this);') + + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescNewAdmin.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescNewAdmin.php new file mode 100644 index 0000000..2c4d544 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescNewAdmin.php @@ -0,0 +1,233 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamFormPass; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescNewAdmin implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_WP_ADMIN_CREATE_NEW] = new ParamForm( + PrmMng::PARAM_WP_ADMIN_CREATE_NEW, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_SWITCH, + array( + 'default' => false + ), + array( + 'label' => 'Create New User:', + 'status' => function ($paramObj) { + if (ParamDescUsers::getUsersMode() != ParamDescUsers::USER_MODE_OVERWRITE) { + return ParamForm::STATUS_DISABLED; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'checkboxLabel' => '' + ) + ); + + $params[PrmMng::PARAM_WP_ADMIN_NAME] = new ParamForm( + PrmMng::PARAM_WP_ADMIN_NAME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateCallback' => function ($value, ParamItem $paramObj) { + if (!PrmMng::getInstance()->getValue(PrmMng::PARAM_WP_ADMIN_CREATE_NEW)) { + return true; + } + + if (strlen($value) < 4) { + $paramObj->setInvalidMessage('Must have 4 or more characters'); + return false; + } + + return true; + } + ), + array( + 'status' => array(__CLASS__, 'getStatuOfNewAdminParams'), + 'label' => 'Username:', + 'classes' => 'new-admin-field', + 'attr' => array( + 'title' => '4 characters minimum', + 'placeholder' => "(4 or more characters)" + ) + ) + ); + + $params[PrmMng::PARAM_WP_ADMIN_PASSWORD] = new ParamFormPass( + PrmMng::PARAM_WP_ADMIN_PASSWORD, + ParamFormPass::TYPE_STRING, + ParamFormPass::FORM_TYPE_PWD_TOGGLE, + array( + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateCallback' => function ($value, ParamItem $paramObj) { + if (!PrmMng::getInstance()->getValue(PrmMng::PARAM_WP_ADMIN_CREATE_NEW)) { + return true; + } + + if (strlen($value) < \DUPX_Constants::MIN_NEW_PASSWORD_LEN) { + $paramObj->setInvalidMessage('Must have ' . \DUPX_Constants::MIN_NEW_PASSWORD_LEN . ' or more characters'); + return false; + } + + return true; + } + ), + array( + 'status' => array(__CLASS__, 'getStatuOfNewAdminParams'), + 'label' => 'Password:', + 'classes' => array('strength-pwd-check', 'new-admin-field'), + 'attr' => array( + 'placeholder' => '(' . \DUPX_Constants::MIN_NEW_PASSWORD_LEN . ' or more characters)', + 'title' => \DUPX_Constants::MIN_NEW_PASSWORD_LEN . ' characters minimum' + ) + ) + ); + + $params[PrmMng::PARAM_WP_ADMIN_MAIL] = new ParamForm( + PrmMng::PARAM_WP_ADMIN_MAIL, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateCallback' => function ($value, ParamItem $paramObj) { + if (!PrmMng::getInstance()->getValue(PrmMng::PARAM_WP_ADMIN_CREATE_NEW)) { + return true; + } + + if (strlen($value) < 4) { + $paramObj->setInvalidMessage('Email name must have 4 or more characters'); + return false; + } + + if (filter_var($value, FILTER_VALIDATE_EMAIL) == false) { + $paramObj->setInvalidMessage('Email "' . $value . '" isn\'t valid'); + return false; + } + + return true; + } + ), + array( + 'status' => array(__CLASS__, 'getStatuOfNewAdminParams'), + 'label' => 'Email:', + 'classes' => 'new-admin-field', + 'attr' => array( + 'title' => '4 characters minimum', + 'placeholder' => "(4 or more characters)" + ) + ) + ); + + $params[PrmMng::PARAM_WP_ADMIN_NICKNAME] = new ParamForm( + PrmMng::PARAM_WP_ADMIN_NICKNAME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim') + ), + array( + 'status' => array(__CLASS__, 'getStatuOfNewAdminParams'), + 'label' => 'Nickname:', + 'classes' => 'new-admin-field', + 'attr' => array( + 'title' => 'if username is empty', + 'placeholder' => "(if username is empty)" + ) + ) + ); + + $params[PrmMng::PARAM_WP_ADMIN_FIRST_NAME] = new ParamForm( + PrmMng::PARAM_WP_ADMIN_FIRST_NAME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim') + ), + array( + 'status' => array(__CLASS__, 'getStatuOfNewAdminParams'), + 'label' => 'First Name:', + 'classes' => 'new-admin-field', + 'attr' => array( + 'title' => 'optional', + 'placeholder' => "(optional)" + ) + ) + ); + + $params[PrmMng::PARAM_WP_ADMIN_LAST_NAME] = new ParamForm( + PrmMng::PARAM_WP_ADMIN_LAST_NAME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim') + ), + array( + 'status' => array(__CLASS__, 'getStatuOfNewAdminParams'), + 'label' => 'Last Name:', + 'classes' => 'new-admin-field', + 'attr' => array( + 'title' => 'optional', + 'placeholder' => "(optional)" + ) + ) + ); + } + + /** + * + * @return string + */ + public static function getStatuOfNewAdminParams() + { + if (PrmMng::getInstance()->getValue(PrmMng::PARAM_WP_ADMIN_CREATE_NEW)) { + return ParamForm::STATUS_ENABLED; + } else { + return ParamForm::STATUS_DISABLED; + } + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescPlugins.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescPlugins.php new file mode 100644 index 0000000..a77fd02 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescPlugins.php @@ -0,0 +1,88 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamFormPlugins; +use Duplicator\Libs\Snap\SnapUtil; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescPlugins implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_PLUGINS] = new ParamFormPlugins( + PrmMng::PARAM_PLUGINS, + ParamFormPlugins::TYPE_ARRAY_STRING, + ParamFormPlugins::FORM_TYPE_PLUGINS_SELECT, + array( + 'default' => array(), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline') + ), + array( + 'label' => 'Plugins', + 'renderLabel' => false, + 'status' => function ($paramObj) { + if ( + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_DISABLED; + } else { + return ParamForm::STATUS_ENABLED; + } + } + ) + ); + + $params[PrmMng::PARAM_IGNORE_PLUGINS] = new ParamItem( + PrmMng::PARAM_IGNORE_PLUGINS, + ParamItem::TYPE_ARRAY_STRING, + array( + 'default' => array(), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline'), + ) + ); + + $params[PrmMng::PARAM_FORCE_DIABLE_PLUGINS] = new ParamItem( + PrmMng::PARAM_FORCE_DIABLE_PLUGINS, + ParamItem::TYPE_ARRAY_STRING, + array( + 'default' => array(), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline'), + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescReplace.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescReplace.php new file mode 100644 index 0000000..3984da2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescReplace.php @@ -0,0 +1,128 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Libs\Snap\SnapUtil; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescReplace implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_BLOGNAME] = new ParamForm( + PrmMng::PARAM_BLOGNAME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'default' => '', + 'sanitizeCallback' => function ($value) { + $value = SnapUtil::sanitizeNSCharsNewline($value); + return htmlspecialchars_decode((empty($value) ? 'No Blog Title Set' : $value), ENT_QUOTES); + } + ), + array( + 'label' => 'Site Title:', + 'status' => function ($paramObj) { + if (DUPX_InstallerState::isRestoreBackup()) { + return ParamForm::STATUS_DISABLED; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'wrapperClasses' => array('revalidate-on-change'), + ) + ); + + $params[PrmMng::PARAM_EMAIL_REPLACE] = new ParamForm( + PrmMng::PARAM_EMAIL_REPLACE, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => 'Email Domains:', + 'checkboxLabel' => 'Update' + ) + ); + + $params[PrmMng::PARAM_FULL_SEARCH] = new ParamForm( + PrmMng::PARAM_FULL_SEARCH, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => 'Database Search:', + 'checkboxLabel' => 'Full Search Mode' + ) + ); + + $params[PrmMng::PARAM_POSTGUID] = new ParamForm( + PrmMng::PARAM_POSTGUID, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => 'Post GUID:', + 'checkboxLabel' => 'Keep Unchanged' + ) + ); + + $params[PrmMng::PARAM_MAX_SERIALIZE_CHECK] = new ParamForm( + PrmMng::PARAM_MAX_SERIALIZE_CHECK, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_NUMBER, + array( + 'default' => \DUPX_Constants::DEFAULT_MAX_STRLEN_SERIALIZED_CHECK_IN_M + ), + array( + 'min' => 0, + 'max' => 99, + 'step' => 1, + 'wrapperClasses' => array('small'), + 'label' => 'Serialized Max Size:', + 'postfix' => array('type' => 'label', 'label' => 'MB'), + 'subNote' => 'If the serialized object stored in the database exceeds this size, it will not be parsed for replacement.' + . '
        Too large a size in low memory installations can generate a fatal error.' + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescSecurity.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescSecurity.php new file mode 100644 index 0000000..6e516e2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescSecurity.php @@ -0,0 +1,110 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamFormPass; +use DUPX_ArchiveConfig; +use DUPX_InstallerState; +use DUPX_Security; +use DUPX_View_Funcs; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescSecurity implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_SECURE_PASS] = new ParamFormPass( + PrmMng::PARAM_SECURE_PASS, + ParamFormPass::TYPE_STRING, + ParamFormPass::FORM_TYPE_PWD_TOGGLE, + array( + 'persistence' => false, + 'default' => null, + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewline') + ), + array( + 'label' => 'Password:', + 'status' => function (ParamForm $param) { + if (DUPX_Security::getInstance()->getSecurityType() == DUPX_Security::SECURITY_PASSWORD) { + return ParamForm::STATUS_ENABLED; + } else { + return ParamForm::STATUS_DISABLED; + } + }, + 'wrapperClasses' => 'margin-bottom-1', + 'attr' => array( + 'placeholder' => (DUPX_ArchiveConfig::getInstance()->secure_on ? '' : 'Password not enabled') + ) + ) + ); + + $params[PrmMng::PARAM_SECURE_ARCHIVE_HASH] = new ParamForm( + PrmMng::PARAM_SECURE_ARCHIVE_HASH, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( + 'persistence' => false, + 'default' => null, + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim') + ), + array( + 'label' => 'Archive File Name:', + 'status' => function (ParamForm $param) { + if (!DUPX_InstallerState::isOverwrite()) { + return ParamForm::STATUS_SKIP; + } elseif (DUPX_Security::getInstance()->getSecurityType() == DUPX_Security::SECURITY_ARCHIVE) { + return ParamForm::STATUS_ENABLED; + } else { + return ParamForm::STATUS_DISABLED; + } + }, + 'wrapperClasses' => 'margin-bottom-4', + 'attr' => array( + 'placeholder' => 'example: [full-unique-name]_archive.zip' + ), + 'subNote' => DUPX_View_Funcs::helpLink('secure', 'How to get archive file name?', false) + ) + ); + + $params[PrmMng::PARAM_SECURE_OK] = new ParamItem( + PrmMng::PARAM_SECURE_OK, + ParamForm::TYPE_BOOL, + array( + 'default' => false + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescUrlsPaths.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescUrlsPaths.php new file mode 100644 index 0000000..24ac458 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescUrlsPaths.php @@ -0,0 +1,498 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Libs\Snap\SnapIO; +use Duplicator\Libs\Snap\SnapJson; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescUrlsPaths implements DescriptorInterface +{ + const INVALID_PATH_EMPTY = 'can\'t be empty'; + const INVALID_URL_EMPTY = 'can\'t be empty'; + + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $archive_config = \DUPX_ArchiveConfig::getInstance(); + $paths = $archive_config->getRealValue('archivePaths'); + + $oldMainPath = $paths->home; + $newMainPath = DUPX_ROOT; + + $oldHomeUrl = rtrim($archive_config->getRealValue('homeUrl'), '/'); + $newHomeUrl = rtrim(DUPX_ROOT_URL, '/'); + + $oldSiteUrl = rtrim($archive_config->getRealValue('siteUrl'), '/'); + $oldContentUrl = rtrim($archive_config->getRealValue('contentUrl'), '/'); + $oldUploadUrl = rtrim($archive_config->getRealValue('uploadBaseUrl'), '/'); + $oldPluginsUrl = rtrim($archive_config->getRealValue('pluginsUrl'), '/'); + $oldMuPluginsUrl = rtrim($archive_config->getRealValue('mupluginsUrl'), '/'); + + $oldWpAbsPath = $paths->abs; + $oldContentPath = $paths->wpcontent; + $oldUploadsBasePath = $paths->uploads; + $oldPluginsPath = $paths->plugins; + $oldMuPluginsPath = $paths->muplugins; + + $defValEdit = "This default value is automatically generated.\n" + . "Change it only if you're sure you know what you're doing!"; + + $params[PrmMng::PARAM_URL_OLD] = new ParamItem( + PrmMng::PARAM_URL_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldHomeUrl + ) + ); + + $params[PrmMng::PARAM_WP_ADDON_SITES_PATHS] = new ParamItem( + PrmMng::PARAM_WP_ADDON_SITES_PATHS, + ParamForm::TYPE_ARRAY_STRING, + array( + 'default' => array() + ) + ); + + $newObj = new ParamForm( + PrmMng::PARAM_URL_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => $newHomeUrl, + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizeUrl'), + 'validateCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'validateUrlWithScheme') + ), + array(// FORM ATTRIBUTES + 'label' => 'New Site URL:', + 'status' => function (ParamForm $param) { + if ( + PrmMng::getInstance()->getValue(PrmMng::PARAM_TEMPLATE) !== \DUPX_Template::TEMPLATE_ADVANCED || + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'wrapperClasses' => array('revalidate-on-change', 'cant-be-empty'), + 'subNote' => function (ParamForm $param) { + $archive_config = \DUPX_ArchiveConfig::getInstance(); + $oldHomeUrl = rtrim($archive_config->getRealValue('homeUrl'), '/'); + return 'Old value: ' . \DUPX_U::esc_html($oldHomeUrl) . ''; + }, + 'postfix' => array('type' => 'button', 'label' => 'get', 'btnAction' => 'DUPX.getNewUrlByDomObj(this);') + ) + ); + $params[PrmMng::PARAM_URL_NEW] = $newObj; + $urlNewInputId = $newObj->getFormItemId(); + + $params[PrmMng::PARAM_PATH_OLD] = new ParamItem( + PrmMng::PARAM_PATH_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldMainPath + ) + ); + + $newObj = new ParamForm( + PrmMng::PARAM_PATH_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => $newMainPath, + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizePath'), + 'validateCallback' => function ($value, ParamItem $paramObj) { + if (strlen($value) == 0) { + $paramObj->setInvalidMessage('The new path can\'t be empty.'); + return false; + } + + // if home path is root path is necessary do a trailingslashit + $realPath = SnapIO::safePathTrailingslashit($value); + if (!is_dir($realPath)) { + $paramObj->setInvalidMessage( + 'The new path must be an existing folder on the server.
        ' . + 'It is not possible to continue the installation without first creating the folder
        ' . + '' . $value . '' + ); + return false; + } + + // don't check the return of chmod, if fail the installer must continue + SnapIO::chmod($realPath, 'u+rwx'); + return true; + } + ), + array(// FORM ATTRIBUTES + 'label' => 'New Path:', + 'status' => function (ParamForm $param) { + if ( + PrmMng::getInstance()->getValue(PrmMng::PARAM_TEMPLATE) !== \DUPX_Template::TEMPLATE_ADVANCED || + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_INFO_ONLY; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldMainPath) . '', + 'wrapperClasses' => array('revalidate-on-change', 'cant-be-empty') + ) + ); + + $params[PrmMng::PARAM_PATH_NEW] = $newObj; + $pathNewInputId = $newObj->getFormItemId(); + + $params[PrmMng::PARAM_SITE_URL_OLD] = new ParamItem( + PrmMng::PARAM_SITE_URL_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldSiteUrl + ) + ); + + $wrapClasses = array('revalidate-on-change', 'cant-be-empty', 'auto-updatable', 'autoupdate-enabled'); + $postfixElement = array( + 'type' => 'button', + 'label' => 'Auto', + 'btnAction' => 'DUPX.autoUpdateToggle(this, ' . SnapJson::jsonEncode($defValEdit) . ');' + ); + + $params[PrmMng::PARAM_SITE_URL] = new ParamForm( + PrmMng::PARAM_SITE_URL, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizeUrl'), + 'validateCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'validateUrlWithScheme') + ), + array(// FORM ATTRIBUTES + 'label' => 'WP core URL:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldSiteUrl) . '', + ) + ); + + $params[PrmMng::PARAM_PATH_CONTENT_OLD] = new ParamItem( + PrmMng::PARAM_PATH_CONTENT_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldContentPath + ) + ); + + $params[PrmMng::PARAM_PATH_CONTENT_NEW] = new ParamForm( + PrmMng::PARAM_PATH_CONTENT_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizePath') + ), + array(// FORM ATTRIBUTES + 'label' => 'WP-content path:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldContentPath) . '' + ) + ); + + $params[PrmMng::PARAM_PATH_WP_CORE_OLD] = new ParamItem( + PrmMng::PARAM_PATH_WP_CORE_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldWpAbsPath + ) + ); + + $params[PrmMng::PARAM_PATH_WP_CORE_NEW] = new ParamForm( + PrmMng::PARAM_PATH_WP_CORE_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizePath'), + ), + array(// FORM ATTRIBUTES + 'label' => 'WP core path:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldWpAbsPath) . '' + ) + ); + + $params[PrmMng::PARAM_PATH_UPLOADS_OLD] = new ParamItem( + PrmMng::PARAM_PATH_UPLOADS_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldUploadsBasePath + ) + ); + + $params[PrmMng::PARAM_PATH_UPLOADS_NEW] = new ParamForm( + PrmMng::PARAM_PATH_UPLOADS_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizePath') + ), + array(// FORM ATTRIBUTES + 'label' => 'Uploads path:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldUploadsBasePath) . '' + ) + ); + + $params[PrmMng::PARAM_URL_CONTENT_OLD] = new ParamItem( + PrmMng::PARAM_URL_CONTENT_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldContentUrl + ) + ); + + $params[PrmMng::PARAM_URL_CONTENT_NEW] = new ParamForm( + PrmMng::PARAM_URL_CONTENT_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizeUrl'), + 'validateCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'validateUrlWithScheme') + ), + array(// FORM ATTRIBUTES + 'label' => 'WP-content URL:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldContentUrl) . '' + ) + ); + + $params[PrmMng::PARAM_URL_UPLOADS_OLD] = new ParamItem( + PrmMng::PARAM_URL_UPLOADS_OLD, + ParamForm::TYPE_STRING, + array(// ITEM ATTRIBUTES + 'default' => $oldUploadUrl + ) + ); + + $params[PrmMng::PARAM_URL_UPLOADS_NEW] = new ParamForm( + PrmMng::PARAM_URL_UPLOADS_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizeUrl'), + 'validateCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'validateUrlWithScheme') + ), + array(// FORM ATTRIBUTES + 'label' => 'Uploads URL:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldUploadUrl) . '' + ) + ); + + $params[PrmMng::PARAM_URL_PLUGINS_OLD] = new ParamItem( + PrmMng::PARAM_URL_PLUGINS_OLD, + ParamForm::TYPE_STRING, + array(// ITEM ATTRIBUTES + 'default' => $oldPluginsUrl + ) + ); + + $params[PrmMng::PARAM_URL_PLUGINS_NEW] = new ParamForm( + PrmMng::PARAM_URL_PLUGINS_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizeUrl'), + 'validateCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'validateUrlWithScheme') + ), + array(// FORM ATTRIBUTES + 'label' => 'Plugins URL:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldPluginsUrl) . '' + ) + ); + + $params[PrmMng::PARAM_PATH_PLUGINS_OLD] = new ParamItem( + PrmMng::PARAM_PATH_PLUGINS_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldPluginsPath + ) + ); + + $params[PrmMng::PARAM_PATH_PLUGINS_NEW] = new ParamForm( + PrmMng::PARAM_PATH_PLUGINS_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizePath') + ), + array(// FORM ATTRIBUTES + 'label' => 'Plugins path:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldPluginsPath) . '' + ) + ); + + $params[PrmMng::PARAM_URL_MUPLUGINS_OLD] = new ParamItem( + PrmMng::PARAM_URL_MUPLUGINS_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldMuPluginsUrl + ) + ); + + $params[PrmMng::PARAM_URL_MUPLUGINS_NEW] = new ParamForm( + PrmMng::PARAM_URL_MUPLUGINS_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizeUrl'), + 'validateCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'validateUrlWithScheme') + ), + array(// FORM ATTRIBUTES + 'label' => 'MU-plugins URL:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'subNote' => 'Old value: ' . \DUPX_U::esc_html($oldMuPluginsUrl) . '' + ) + ); + + $params[PrmMng::PARAM_PATH_MUPLUGINS_OLD] = new ParamItem( + PrmMng::PARAM_PATH_MUPLUGINS_OLD, + ParamForm::TYPE_STRING, + array( + 'default' => $oldMuPluginsPath + ) + ); + + $params[PrmMng::PARAM_PATH_MUPLUGINS_NEW] = new ParamForm( + PrmMng::PARAM_PATH_MUPLUGINS_NEW, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array(// ITEM ATTRIBUTES + 'default' => '', + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizePath') + ), + array(// FORM ATTRIBUTES + 'label' => 'MU-plugins path:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'postfix' => $postfixElement + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + PrmMng::getInstance(); + + $archive_config = \DUPX_ArchiveConfig::getInstance(); + $paths = $archive_config->getRealValue('archivePaths'); + + $oldMainPath = $paths->home; + $newMainPath = $params[PrmMng::PARAM_PATH_NEW]->getValue(); + + $oldHomeUrl = rtrim($archive_config->getRealValue('homeUrl'), '/'); + $newHomeUrl = $params[PrmMng::PARAM_URL_NEW]->getValue(); + + $oldSiteUrl = rtrim($archive_config->getRealValue('siteUrl'), '/'); + $oldContentUrl = rtrim($archive_config->getRealValue('contentUrl'), '/'); + $oldUploadUrl = rtrim($archive_config->getRealValue('uploadBaseUrl'), '/'); + $oldPluginsUrl = rtrim($archive_config->getRealValue('pluginsUrl'), '/'); + $oldMuPluginsUrl = rtrim($archive_config->getRealValue('mupluginsUrl'), '/'); + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_PATH_WP_CORE_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubString($oldMainPath, $newMainPath, $paths->abs); + $params[PrmMng::PARAM_PATH_WP_CORE_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_PATH_CONTENT_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubString($oldMainPath, $newMainPath, $paths->wpcontent); + $params[PrmMng::PARAM_PATH_CONTENT_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_PATH_UPLOADS_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubString($oldMainPath, $newMainPath, $paths->uploads); + $params[PrmMng::PARAM_PATH_UPLOADS_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_PATH_PLUGINS_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubString($oldMainPath, $newMainPath, $paths->plugins); + $params[PrmMng::PARAM_PATH_PLUGINS_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_PATH_MUPLUGINS_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubString($oldMainPath, $newMainPath, $paths->muplugins); + $params[PrmMng::PARAM_PATH_MUPLUGINS_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_SITE_URL]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubUrl($oldHomeUrl, $newHomeUrl, $oldSiteUrl); + $params[PrmMng::PARAM_SITE_URL]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_URL_CONTENT_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubUrl($oldHomeUrl, $newHomeUrl, $oldContentUrl); + $params[PrmMng::PARAM_URL_CONTENT_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_URL_UPLOADS_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubUrl($oldHomeUrl, $newHomeUrl, $oldUploadUrl); + $params[PrmMng::PARAM_URL_UPLOADS_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_URL_PLUGINS_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubUrl($oldHomeUrl, $newHomeUrl, $oldPluginsUrl); + $params[PrmMng::PARAM_URL_PLUGINS_NEW]->setValue($newVal); + } + + // if empty value isn't overwritten + if (strlen($params[PrmMng::PARAM_URL_MUPLUGINS_NEW]->getValue()) == 0) { + $newVal = \DUPX_ArchiveConfig::getNewSubUrl($oldHomeUrl, $newHomeUrl, $oldMuPluginsUrl); + $params[PrmMng::PARAM_URL_MUPLUGINS_NEW]->setValue($newVal); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescUsers.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescUsers.php new file mode 100644 index 0000000..cac25e9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescUsers.php @@ -0,0 +1,166 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamOption; +use Duplicator\Installer\Core\Params\Items\ParamFormUsersReset; +use DUPX_DBInstall; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescUsers implements DescriptorInterface +{ + const USER_MODE_OVERWRITE = 'overwrite'; + const USER_MODE_IMPORT_USERS = 'import_users'; + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_USERS_MODE] = new ParamForm( + PrmMng::PARAM_USERS_MODE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_RADIO, + array( + 'default' => self::USER_MODE_OVERWRITE, + 'sanitizeCallback' => function ($value) { + if ( + DUPX_InstallerState::getInstance()->getMode() !== DUPX_InstallerState::MODE_OVR_INSTALL || + DUPX_InstallerState::isRestoreBackup() + ) { + // if is restore backup user mode must be overwrite + return ParamDescUsers::USER_MODE_OVERWRITE; + } + + $overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + if ($overwriteData['isMultisite']) { + return ParamDescUsers::USER_MODE_OVERWRITE; + } + + // disable keep users for some db actions + switch (PrmMng::getInstance()->getValue(PrmMng::PARAM_DB_ACTION)) { + case DUPX_DBInstall::DBACTION_CREATE: + case DUPX_DBInstall::DBACTION_MANUAL: + case DUPX_DBInstall::DBACTION_ONLY_CONNECT: + return ParamDescUsers::USER_MODE_OVERWRITE; + case DUPX_DBInstall::DBACTION_EMPTY: + case DUPX_DBInstall::DBACTION_REMOVE_ONLY_TABLES: + case DUPX_DBInstall::DBACTION_RENAME: + return $value; + } + }, + 'acceptValues' => array( + self::USER_MODE_OVERWRITE, + self::USER_MODE_IMPORT_USERS + ) + ), + array( + 'status' => function () { + /* Hide user mode instandalone migration for now */ + return ParamForm::STATUS_SKIP; + if (DUPX_InstallerState::getInstance()->getMode() !== DUPX_InstallerState::MODE_OVR_INSTALL) { + return ParamForm::STATUS_DISABLED; + } + + $overwriteData = PrmMng::getInstance()->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + + if ( + $overwriteData['isMultisite'] || + DUPX_InstallerState::isRestoreBackup() + ) { + return ParamForm::STATUS_DISABLED; + } + return ParamForm::STATUS_ENABLED; + }, + 'label' => 'Users:', + 'options' => function ($item) { + $result = array(); + $result[] = new ParamOption(ParamDescUsers::USER_MODE_OVERWRITE, 'Overwrite'); + $result[] = new ParamOption(ParamDescUsers::USER_MODE_IMPORT_USERS, 'Merge'); + return $result; + }, + 'inlineHelp' => dupxTplRender('parts/params/inline_helps/user_mode', array(), false), + 'wrapperClasses' => array('revalidate-on-change') + ) + ); + + $params[PrmMng::PARAM_USERS_PWD_RESET] = new ParamFormUsersReset( + PrmMng::PARAM_USERS_PWD_RESET, + ParamFormUsersReset::TYPE_ARRAY_STRING, + ParamFormUsersReset::FORM_TYPE_USERS_PWD_RESET, + array( // ITEM ATTRIBUTES + 'default' => array_map(function ($value) { + return ''; + }, \DUPX_ArchiveConfig::getInstance()->getUsersLists()), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateCallback' => function ($value) { + return strlen($value) == 0 || strlen($value) >= \DUPX_Constants::MIN_NEW_PASSWORD_LEN; + }, + 'validateCallback' => function ($value, ParamItem $paramObj) { + if (strlen($value) > 0 && strlen($value) < \DUPX_Constants::MIN_NEW_PASSWORD_LEN) { + $paramObj->setInvalidMessage('New password must have ' . \DUPX_Constants::MIN_NEW_PASSWORD_LEN . ' or more characters'); + return false; + } + + return true; + } + ), + array( // FORM ATTRIBUTES + 'status' => function ($paramObj) { + if (ParamDescUsers::getUsersMode() != ParamDescUsers::USER_MODE_OVERWRITE) { + return ParamForm::STATUS_DISABLED; + } else { + return ParamForm::STATUS_ENABLED; + } + }, + 'label' => 'Existing user reset password:', + 'classes' => 'strength-pwd-check', + 'attr' => array( + 'title' => \DUPX_Constants::MIN_NEW_PASSWORD_LEN . ' characters minimum', + 'placeholder' => "Reset user password" + ) + ) + ); + } + + /** + * Return import users mode + * + * @return string + */ + public static function getUsersMode() + { + $paramsManager = PrmMng::getInstance(); + return $paramsManager->getValue(PrmMng::PARAM_USERS_MODE); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescValidation.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescValidation.php new file mode 100644 index 0000000..d98f7a6 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescValidation.php @@ -0,0 +1,102 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescValidation implements DescriptorInterface +{ + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $params[PrmMng::PARAM_VALIDATION_LEVEL] = new ParamItem( + PrmMng::PARAM_VALIDATION_LEVEL, + ParamItem::TYPE_INT, + array( + 'default' => \DUPX_Validation_abstract_item::LV_FAIL, + 'acceptValues' => array( + \DUPX_Validation_abstract_item::LV_FAIL, + \DUPX_Validation_abstract_item::LV_HARD_WARNING, + \DUPX_Validation_abstract_item::LV_SOFT_WARNING, + \DUPX_Validation_abstract_item::LV_GOOD, + \DUPX_Validation_abstract_item::LV_PASS + ) + ) + ); + + $params[PrmMng::PARAM_VALIDATION_ACTION_ON_START] = new ParamItem( + PrmMng::PARAM_VALIDATION_ACTION_ON_START, + ParamForm::TYPE_STRING, + array( + 'default' => \DUPX_Validation_manager::ACTION_ON_START_NORMAL, + 'acceptValues' => array( + \DUPX_Validation_manager::ACTION_ON_START_NORMAL, + \DUPX_Validation_manager::ACTION_ON_START_AUTO + ) + ) + ); + + $params[PrmMng::PARAM_VALIDATION_SHOW_ALL] = new ParamForm( + PrmMng::PARAM_VALIDATION_SHOW_ALL, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_SWITCH, + array( + 'default' => false + ), + array( + 'label' => 'Show all', + 'wrapperClasses' => 'align-right' + ) + ); + + $params[PrmMng::PARAM_ACCEPT_TERM_COND] = new ParamForm( + PrmMng::PARAM_ACCEPT_TERM_COND, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => 'Accept term and conditions', + 'renderLabel' => false, + 'checkboxLabel' => 'I have read and accept all terms & notices*', + 'subNote' => '
        * required to continue
        ', + 'attr' => array( + 'onclick' => 'DUPX.acceptWarning();' + ) + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescWpConfig.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescWpConfig.php new file mode 100644 index 0000000..64d5685 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamDescWpConfig.php @@ -0,0 +1,749 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Params\PrmMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Core\Params\Items\ParamForm; +use Duplicator\Installer\Core\Params\Items\ParamOption; +use Duplicator\Installer\Core\Params\Items\ParamFormWpConfig; +use Duplicator\Libs\Snap\SnapUtil; +use Duplicator\Libs\Snap\SnapIO; +use Duplicator\Libs\Snap\SnapDB; +use DUPX_ArchiveConfig; +use DUPX_InstallerState; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamDescWpConfig implements DescriptorInterface +{ + const NOTICE_ID_WP_CONF_PARAM_PATHS_EMPTY = 'wp_conf_param_paths_empty_to_validate'; + const NOTICE_ID_WP_CONF_FORCE_SSL_ADMIN = 'wp_conf_disabled_force_ssl_admin'; + const NOTICE_ID_WP_CONF_PARAM_DOMAINS_MODIFIED = 'wp_conf_param_domains_empty_to_validate'; + + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function init(&$params) + { + $archiveConfig = \DUPX_ArchiveConfig::getInstance(); + + $params[PrmMng::PARAM_GEN_WP_AUTH_KEY] = new ParamForm( + PrmMng::PARAM_GEN_WP_AUTH_KEY, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => false + ), + array( + 'label' => 'Auth Keys:', + 'checkboxLabel' => 'Generate New Unique Authentication Keys and Salts', + 'status' => ParamForm::STATUS_INFO_ONLY + ) + ); + + $params[PrmMng::PARAM_WP_CONF_DISALLOW_FILE_EDIT] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_DISALLOW_FILE_EDIT, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue( + 'DISALLOW_FILE_EDIT' + ) + ), + array( + 'label' => 'DISALLOW_FILE_EDIT:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Disable the Plugin/Theme Editor' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_DISALLOW_FILE_MODS] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_DISALLOW_FILE_MODS, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue( + 'DISALLOW_FILE_MODS', + array( + 'value' => false, + 'inWpConfig' => false + ) + ) + ), + array( + 'label' => 'DISALLOW_FILE_MODS:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'This will block users being able to use the plugin and theme installation/update ' . + 'functionality from the WordPress admin area' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_AUTOSAVE_INTERVAL] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_AUTOSAVE_INTERVAL, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_NUMBER, + array( // ITEM ATTRIBUTES + 'default' => $archiveConfig->getDefineArrayValue( + 'AUTOSAVE_INTERVAL', + array( + 'value' => 60, + 'inWpConfig' => false + ) + ) + ), + array( // FORM ATTRIBUTES + 'label' => 'AUTOSAVE_INTERVAL:', + 'status' => ParamForm::STATUS_INFO_ONLY, + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_POST_REVISIONS] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_POST_REVISIONS, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_NUMBER, + array( // ITEM ATTRIBUTES + 'default' => $archiveConfig->getDefineArrayValue( + 'WP_POST_REVISIONS', + array( + 'value' => true, + 'inWpConfig' => false + ) + ), + ), + array( // FORM ATTRIBUTES + 'label' => 'WP_POST_REVISIONS:', + 'status' => ParamForm::STATUS_INFO_ONLY, + ) + ); + + $params[PrmMng::PARAM_WP_CONF_FORCE_SSL_ADMIN] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_FORCE_SSL_ADMIN, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => self::getDefaultForceSSLAdminConfig(), + ), + array( + 'label' => 'FORCE_SSL_ADMIN:', + 'checkboxLabel' => 'Enforce Admin SSL' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_AUTOMATIC_UPDATER_DISABLED] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_AUTOMATIC_UPDATER_DISABLED, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue( + 'AUTOMATIC_UPDATER_DISABLED', + array( + 'value' => false, + 'inWpConfig' => false + ) + ) + ), + array( + 'label' => 'AUTOMATIC_UPDATER_DISABLED:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Disable automatic updater' + ) + ); + + $autoUpdateValue = $archiveConfig->getWpConfigDefineValue('WP_AUTO_UPDATE_CORE'); + if (is_bool($autoUpdateValue)) { + $autoUpdateValue = ($autoUpdateValue ? 'true' : 'false'); + } + $params[PrmMng::PARAM_WP_CONF_WP_AUTO_UPDATE_CORE] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_AUTO_UPDATE_CORE, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_SELECT, + array( + 'default' => array( + 'value' => $autoUpdateValue, + 'inWpConfig' => $archiveConfig->inWpConfigDefine('WP_AUTO_UPDATE_CORE') + ), + 'acceptValues' => array('', 'false', 'true', 'minor') + ), + array( + 'label' => 'WP_AUTO_UPDATE_CORE:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'options' => array( + new ParamOption('minor', 'Enable only core minor updates - Default'), + new ParamOption('false', 'Disable all core updates'), + new ParamOption('true', 'Enable all core updates') + ) + ) + ); + + $params[PrmMng::PARAM_WP_CONF_IMAGE_EDIT_OVERWRITE] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_IMAGE_EDIT_OVERWRITE, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue( + 'IMAGE_EDIT_OVERWRITE', + array( + 'value' => true, + 'inWpConfig' => false + ) + ) + ), + array( + 'label' => 'IMAGE_EDIT_OVERWRITE:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Create only one set of image edits' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_CACHE] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_CACHE, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('WP_CACHE') + ), + array( + 'label' => 'WP_CACHE:', + 'checkboxLabel' => 'Keep Enabled' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WPCACHEHOME] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WPCACHEHOME, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( // ITEM ATTRIBUTES + 'default' => $archiveConfig->getDefineArrayValue("WPCACHEHOME"), + 'sanitizeCallback' => function ($value) { + $result = SnapUtil::sanitizeNSCharsNewlineTrim($value); + // WPCACHEHOME want final slash + return SnapIO::safePathTrailingslashit($result); + } + ), + array( // FORM ATTRIBUTES + 'label' => 'WPCACHEHOME:', + 'subNote' => 'This define is not part of the WordPress core but is a define used by WP Super Cache.' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_TEMP_DIR] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_TEMP_DIR, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( // ITEM ATTRIBUTES + 'default' => $archiveConfig->getDefineArrayValue("WP_TEMP_DIR"), + 'sanitizeCallback' => array('Duplicator\\Installer\\Core\\Params\\Descriptors\\ParamsDescriptors', 'sanitizePath') + ), + array( // FORM ATTRIBUTES + 'label' => 'WP_TEMP_DIR:', + //'wrapperClasses' => array('small'), + //'subNote' => 'Wordpress admin maximum memory limit (default:256M)' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_DEBUG] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_DEBUG, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('WP_DEBUG') + ), + array( + 'label' => 'WP_DEBUG:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Display errors and warnings' + ) + ); + + $debugLogValue = $archiveConfig->getWpConfigDefineValue('WP_DEBUG_LOG'); + if (is_string($debugLogValue)) { + $debugLogValue = empty($debugLogValue) ? false : true; + } + $params[PrmMng::PARAM_WP_CONF_WP_DEBUG_LOG] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_DEBUG_LOG, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => array( + 'value' => $debugLogValue, + 'inWpConfig' => $archiveConfig->inWpConfigDefine('WP_DEBUG_LOG') + ) + ), + array( + 'label' => 'WP_DEBUG_LOG:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Log errors and warnings', + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_DISABLE_FATAL_ERROR_HANDLER] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_DISABLE_FATAL_ERROR_HANDLER, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('WP_DISABLE_FATAL_ERROR_HANDLER') + ), + array( + 'label' => 'WP_DISABLE_FATAL_ERROR_HANDLER:', + 'checkboxLabel' => 'Disable fatal error handler', + 'status' => ParamForm::STATUS_INFO_ONLY + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_DEBUG_DISPLAY] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_DEBUG_DISPLAY, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('WP_DEBUG_DISPLAY') + ), + array( + 'label' => 'WP_DEBUG_DISPLAY:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Display errors and warnings' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_SCRIPT_DEBUG] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_SCRIPT_DEBUG, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('SCRIPT_DEBUG') + ), + array( + 'label' => 'SCRIPT_DEBUG:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'JavaScript or CSS errors' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_CONCATENATE_SCRIPTS] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_CONCATENATE_SCRIPTS, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('CONCATENATE_SCRIPTS', array( + 'value' => false, + 'inWpConfig' => false + )) + ), + array( + 'label' => 'CONCATENATE_SCRIPTS:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Concatenate all JavaScript files into one URL' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_SAVEQUERIES] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_SAVEQUERIES, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('SAVEQUERIES') + ), + array( + 'label' => 'SAVEQUERIES:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Save database queries in an array ($wpdb->queries)' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_ALTERNATE_WP_CRON] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_ALTERNATE_WP_CRON, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('ALTERNATE_WP_CRON', array( + 'value' => false, + 'inWpConfig' => false + )) + ), + array( + 'label' => 'ALTERNATE_WP_CRON:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Use an alternative Cron with WP' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_DISABLE_WP_CRON] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_DISABLE_WP_CRON, + ParamForm::TYPE_BOOL, + ParamForm::FORM_TYPE_CHECKBOX, + array( + 'default' => $archiveConfig->getDefineArrayValue('DISABLE_WP_CRON', array( + 'value' => false, + 'inWpConfig' => false + )) + ), + array( + 'label' => 'DISABLE_WP_CRON:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'checkboxLabel' => 'Disable cron entirely' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_CRON_LOCK_TIMEOUT] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_CRON_LOCK_TIMEOUT, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_NUMBER, + array( + 'default' => $archiveConfig->getDefineArrayValue('WP_CRON_LOCK_TIMEOUT', array( + 'value' => 60, + 'inWpConfig' => false + )), + 'min_range' => 1 + ), + array( + 'label' => 'WP_CRON_LOCK_TIMEOUT:', + 'status' => ParamForm::STATUS_INFO_ONLY + ) + ); + + $params[PrmMng::PARAM_WP_CONF_EMPTY_TRASH_DAYS] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_EMPTY_TRASH_DAYS, + ParamForm::TYPE_INT, + ParamForm::FORM_TYPE_NUMBER, + array( + 'default' => $archiveConfig->getDefineArrayValue('EMPTY_TRASH_DAYS', array( + 'value' => 30, + 'inWpConfig' => false + )), + 'min_range' => 0 + ), + array( + 'label' => 'EMPTY_TRASH_DAYS:', + 'status' => ParamForm::STATUS_INFO_ONLY + ) + ); + + $params[PrmMng::PARAM_WP_CONF_COOKIE_DOMAIN] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_COOKIE_DOMAIN, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( // ITEM ATTRIBUTES + 'default' => $archiveConfig->getDefineArrayValue("COOKIE_DOMAIN"), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim') + ), + array( // FORM ATTRIBUTES + 'label' => 'COOKIE_DOMAIN:', + 'subNote' => 'Set ' . + 'different domain for cookies.subdomain.example.com' + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_MEMORY_LIMIT] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_MEMORY_LIMIT, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( // ITEM ATTRIBUTES + 'default' => $archiveConfig->getDefineArrayValue('WP_MEMORY_LIMIT'), + 'sanitizeCallback' => array('Duplicator\\Libs\\Snap\\SnapUtil', 'sanitizeNSCharsNewlineTrim'), + 'validateRegex' => ParamItem::VALIDATE_REGEX_AZ_NUMBER + ), + array( // FORM ATTRIBUTES + 'label' => 'WP_MEMORY_LIMIT:', + 'status' => ParamForm::STATUS_INFO_ONLY + ) + ); + + $params[PrmMng::PARAM_WP_CONF_WP_MAX_MEMORY_LIMIT] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_WP_MAX_MEMORY_LIMIT, + ParamForm::TYPE_STRING, + ParamForm::FORM_TYPE_TEXT, + array( // ITEM ATTRIBUTES + 'default' => $archiveConfig->getDefineArrayValue('WP_MAX_MEMORY_LIMIT') + ), + array( // FORM ATTRIBUTES + 'label' => 'WP_MAX_MEMORY_LIMIT:', + 'status' => ParamForm::STATUS_INFO_ONLY + ) + ); + + $params[PrmMng::PARAM_WP_CONF_MYSQL_CLIENT_FLAGS] = new ParamFormWpConfig( + PrmMng::PARAM_WP_CONF_MYSQL_CLIENT_FLAGS, + ParamForm::TYPE_ARRAY_INT, + ParamForm::FORM_TYPE_SELECT, + array( // ITEM ATTRIBUTES + 'default' => self::getMysqlClientFlagsDefaultVals(), + ), + array( // FORM ATTRIBUTES + 'label' => 'MYSQL_CLIENT_FLAGS:', + 'status' => ParamForm::STATUS_INFO_ONLY, + 'options' => self::getMysqlClientFlagsOptions(), + 'multiple' => true + ) + ); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + //UPDATE PATHS AUTOMATICALLY + self::setDefaultWpConfigPathValue($params, PrmMng::PARAM_WP_CONF_WP_TEMP_DIR, 'WP_TEMP_DIR'); + self::setDefaultWpConfigPathValue($params, PrmMng::PARAM_WP_CONF_WPCACHEHOME, 'WPCACHEHOME'); + self::wpConfigPathsNotices(); + + //UPDATE DOMAINS AUTOMATICALLY + self::setDefaultWpConfigDomainValue($params, PrmMng::PARAM_WP_CONF_COOKIE_DOMAIN, "COOKIE_DOMAIN"); + self::wpConfigDomainNotices(); + } + + /** + * Returns wp counfi default value + * + * @return array + */ + protected static function getMysqlClientFlagsDefaultVals() + { + $result = DUPX_ArchiveConfig::getInstance()->getDefineArrayValue( + 'MYSQL_CLIENT_FLAGS', + array( + 'value' => array(), + 'inWpConfig' => false + ) + ); + + $result['value'] = array_intersect($result['value'], SnapDB::getMysqlConnectFlagsList(false)); + return $result; + } + + /** + * Returns the list of options of the mysql real connect flags + * + * @return int[] + */ + protected static function getMysqlClientFlagsOptions() + { + $result = array(); + foreach (SnapDB::getMysqlConnectFlagsList() as $flag) { + $result[] = new ParamOption(constant($flag), $flag); + } + return $result; + } + + /** + * Tries to replace the old path with the new path for the given wp config define. + * If that's not possible returns a notice to the user. + * + * @param ParamItem[] $params params list + * @param string $paramKey param key + * @param string $wpConfigKey wp config key + * + * @return void + */ + protected static function setDefaultWpConfigPathValue(&$params, $paramKey, $wpConfigKey) + { + if (!self::wpConfigNeedsUpdate($params, $paramKey, $wpConfigKey)) { + return; + } + + $oldMainPath = $params[PrmMng::PARAM_PATH_OLD]->getValue(); + $newMainPath = $params[PrmMng::PARAM_PATH_NEW]->getValue(); + $wpConfigVal = \DUPX_ArchiveConfig::getInstance()->getDefineArrayValue($wpConfigKey); + + // TRY TO CHANGE THE VALUE OR RESET + if (($wpConfigVal['value'] = \DUPX_ArchiveConfig::getNewSubString($oldMainPath, $newMainPath, $wpConfigVal['value'])) === false) { + $wpConfigVal['inWpConfig'] = false; + $wpConfigVal['value'] = ''; + + \DUPX_NOTICE_MANAGER::getInstance()->addNextStepNotice(array( + 'shortMsg' => 'WP CONFIG custom paths disabled.', + 'level' => \DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => "The " . $params[$paramKey]->getLabel() . " path could not be set programmatically and has been disabled
        \n", + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), \DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, self::NOTICE_ID_WP_CONF_PARAM_PATHS_EMPTY); + } + + $params[$paramKey]->setValue($wpConfigVal); + } + + /** + * Tries to replace the old domain with the new domain for the given wp config define. + * If that's not possible returns a notice to the user. + * + * @param ParamItem[] $params params list + * @param string $paramKey param key + * @param string $wpConfigKey wp config key + * + * @return void + */ + protected static function setDefaultWpConfigDomainValue(&$params, $paramKey, $wpConfigKey) + { + if (!self::wpConfigNeedsUpdate($params, $paramKey, $wpConfigKey)) { + return; + } + + $wpConfigVal = \DUPX_ArchiveConfig::getInstance()->getDefineArrayValue($wpConfigKey); + $parsedUrlNew = parse_url(PrmMng::getInstance()->getValue(PrmMng::PARAM_URL_NEW)); + $parsedUrlOld = parse_url(PrmMng::getInstance()->getValue(PrmMng::PARAM_URL_OLD)); + + if ($wpConfigVal['value'] == $parsedUrlOld['host']) { + $wpConfigVal['value'] = $parsedUrlNew['host']; + } else { + $wpConfigVal['inWpConfig'] = false; + $wpConfigVal['value'] = ''; + + \DUPX_NOTICE_MANAGER::getInstance()->addNextStepNotice(array( + 'shortMsg' => 'WP CONFIG domains disabled.', + 'level' => \DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => "The " . $params[$paramKey]->getLabel() . " domain could not be set programmatically and has been disabled
        \n", + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), \DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, self::NOTICE_ID_WP_CONF_PARAM_DOMAINS_MODIFIED); + } + + $params[$paramKey]->setValue($wpConfigVal); + } + + /** + * Return true if wp config key need update + * + * @param ParamItem[] $params params list + * @param string $paramKey param key + * @param string $wpConfigKey wp config key + * + * @return bool + */ + protected static function wpConfigNeedsUpdate(&$params, $paramKey, $wpConfigKey) + { + if ( + DUPX_InstallerState::isRestoreBackup($params[PrmMng::PARAM_INST_TYPE]->getValue()) + ) { + return false; + } + + // SKIP IF PARAM IS OVERWRITTEN + if ($params[$paramKey]->getStatus() === ParamItem::STATUS_OVERWRITE) { + return false; + } + + // SKIP IF EMPTY + $wpConfigVal = \DUPX_ArchiveConfig::getInstance()->getDefineArrayValue($wpConfigKey); + if (strlen($wpConfigVal['value']) === 0) { + return false; + } + + // EMPTY IF DISABLED + if ($wpConfigVal['inWpConfig'] == false) { + $wpConfigVal['value'] = ''; + $params[$paramKey]->setValue($wpConfigVal); + return false; + } + + return true; + } + + /** + * Set wp config paths notices + * + * @return void + */ + protected static function wpConfigPathsNotices() + { + $noticeManager = \DUPX_NOTICE_MANAGER::getInstance(); + + /* PREPEND IF EXISTS */ + $noticeManager->addNextStepNotice(array( + 'shortMsg' => '', + 'level' => \DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => "It was found that the following config paths were outside of the source site's home path (" . + \DUPX_ArchiveConfig::getInstance()->getRealValue("originalPaths")->home . "):

        \n", + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), \DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, self::NOTICE_ID_WP_CONF_PARAM_PATHS_EMPTY); + + /* APPEND IF EXISTS */ + $msg = '
        Keeping config paths that are outside of the home path may cause malfunctions, so these settings have been disabled by default,'; + $msg .= ' but you can set them manually if necessary by switching the install mode '; + $msg .= 'to "Advanced" and at Step 3 navigating to "Options" > "WP-Config File"'; + + $noticeManager->addNextStepNotice(array( + 'shortMsg' => '', + 'level' => \DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => $msg, + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), \DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND_IF_EXISTS, self::NOTICE_ID_WP_CONF_PARAM_PATHS_EMPTY); + + $noticeManager->saveNotices(); + } + + /** + * Set wp config domain notices + * + * @return void + */ + protected static function wpConfigDomainNotices() + { + $noticeManager = \DUPX_NOTICE_MANAGER::getInstance(); + + /* PREPEND IF EXISTS */ + $noticeManager->addNextStepNotice(array( + 'shortMsg' => '', + 'level' => \DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => "The following config domains were disabled:

        \n", + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), \DUPX_NOTICE_MANAGER::ADD_UNIQUE_PREPEND_IF_EXISTS, self::NOTICE_ID_WP_CONF_PARAM_DOMAINS_MODIFIED); + + /* APPEND IF EXISTS */ + $msg = '
        The plugin was unable to automatically replace the domain, so the setting has been disabled by default.'; + $msg .= ' Please review them by switching the install mode to "Advanced" and at Step 3 navigating to "Options" > "WP-Config File"'; + + $noticeManager->addNextStepNotice(array( + 'shortMsg' => '', + 'level' => \DUPX_NOTICE_ITEM::NOTICE, + 'longMsg' => $msg, + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), \DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND_IF_EXISTS, self::NOTICE_ID_WP_CONF_PARAM_DOMAINS_MODIFIED); + + $noticeManager->saveNotices(); + } + + /** + * Returns default config value for FORCE_SSL_ADMIN depending on current site's settings + * + * @return array + * @throws \Exception + */ + protected static function getDefaultForceSSLAdminConfig() + { + $forceAdminSSLConfig = \DUPX_ArchiveConfig::getInstance()->getDefineArrayValue('FORCE_SSL_ADMIN'); + if (!\DUPX_U::is_ssl() && $forceAdminSSLConfig['inWpConfig'] === true) { + $noticeMng = \DUPX_NOTICE_MANAGER::getInstance(); + $noticeMng->addFinalReportNotice( + array( + 'shortMsg' => "FORCE_SSL_ADMIN was enabled on none SSL", + 'level' => \DUPX_NOTICE_ITEM::SOFT_WARNING, + 'longMsg' => 'It was found that FORCE_SSL_ADMIN is enabled and you are installing on a site without SSL, ' . + 'so that config has been disabled.', + 'sections' => 'general' + ), + \DUPX_NOTICE_MANAGER::ADD_UNIQUE, + self::NOTICE_ID_WP_CONF_FORCE_SSL_ADMIN + ); + $noticeMng->saveNotices(); + $forceAdminSSLConfig['value'] = false; + } + return $forceAdminSSLConfig; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamsDescriptors.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamsDescriptors.php new file mode 100644 index 0000000..d65b096 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Descriptors/ParamsDescriptors.php @@ -0,0 +1,183 @@ + + * @copyright 2011-2021 Snapcreek LLC + * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3 + */ + +namespace Duplicator\Installer\Core\Params\Descriptors; + +use Duplicator\Installer\Core\Hooks\HooksMng; +use Duplicator\Installer\Core\Params\Items\ParamItem; +use Duplicator\Installer\Utils\Log\Log; +use Duplicator\Libs\Snap\SnapUtil; +use Duplicator\Libs\Snap\SnapIO; + +/** + * class where all parameters are initialized. Used by the param manager + */ +final class ParamsDescriptors +{ + /** + * Params init + * + * @return void + */ + public static function init() + { + HooksMng::getInstance()->addAction('after_params_overwrite', array(__CLASS__, 'updateParamsAfterOverwrite')); + } + + /** + * Init params + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function initParams(&$params) + { + ParamDescUrlsPaths::init($params); + ParamDescController::init($params); + ParamDescSecurity::init($params); + ParamDescGeneric::init($params); + ParamDescConfigs::init($params); + ParamDescEngines::init($params); + ParamDescValidation::init($params); + ParamDescDatabase::init($params); + ParamDescReplace::init($params); + ParamDescPlugins::init($params); + ParamDescUsers::init($params); + ParamDescNewAdmin::init($params); + ParamDescWpConfig::init($params); + } + + /** + * Update params after overwrite logic + * + * @param ParamItem[]|ParamForm[] $params params list + * + * @return void + */ + public static function updateParamsAfterOverwrite($params) + { + Log::info('UPDATE PARAMS AFTER OVERWRITE', Log::LV_DETAILED); + ParamDescUrlsPaths::updateParamsAfterOverwrite($params); + ParamDescController::updateParamsAfterOverwrite($params); + ParamDescSecurity::updateParamsAfterOverwrite($params); + ParamDescGeneric::updateParamsAfterOverwrite($params); + ParamDescConfigs::updateParamsAfterOverwrite($params); + ParamDescEngines::updateParamsAfterOverwrite($params); + ParamDescValidation::updateParamsAfterOverwrite($params); + ParamDescDatabase::updateParamsAfterOverwrite($params); + ParamDescReplace::updateParamsAfterOverwrite($params); + ParamDescPlugins::updateParamsAfterOverwrite($params); + ParamDescUsers::updateParamsAfterOverwrite($params); + ParamDescNewAdmin::updateParamsAfterOverwrite($params); + ParamDescWpConfig::updateParamsAfterOverwrite($params); + } + + /** + * Validate function, return true if value isn't empty + * + * @param mixed $value input value + * @param ParamItem $paramObj current param object + * + * @return boolean + */ + public static function validateNotEmpty($value, ParamItem $paramObj) + { + if (is_string($value)) { + $result = strlen($value) > 0; + } else { + $result = !empty($value); + } + + if ($result == false) { + $paramObj->setInvalidMessage('Can\'t be empty'); + } + + return true; + } + + /** + * Sanitize path + * + * @param string $value input value + * + * @return string + */ + public static function sanitizePath($value) + { + $result = SnapUtil::sanitizeNSCharsNewlineTrim($value); + return SnapIO::safePathUntrailingslashit($result); + } + + /** + * The path can't be empty + * + * @param string $value input value + * @param ParamItem $paramObj current param object + * + * @return bool + */ + public static function validatePath($value, ParamItem $paramObj) + { + if (strlen($value) > 1) { + return true; + } else { + $paramObj->setInvalidMessage('Path can\'t empty'); + return false; + } + } + + /** + * Sanitize URL + * + * @param string $value input value + * + * @return string + */ + public static function sanitizeUrl($value) + { + $result = SnapUtil::sanitizeNSCharsNewlineTrim($value); + if (empty($value)) { + return ''; + } + // if scheme not set add http by default + if (!preg_match('/^[a-zA-Z]+\:\/\//', $result)) { + $result = 'http://' . ltrim($result, '/'); + } + return rtrim($result, '/\\'); + } + + /** + * The URL can't be empty + * + * @param string $value input value + * @param ParamItem $paramObj current param object + * + * @return bool + */ + public static function validateUrlWithScheme($value, ParamItem $paramObj) + { + if (strlen($value) == 0) { + $paramObj->setInvalidMessage('URL can\'t be empty'); + return false; + } + if (($parsed = parse_url($value)) === false) { + $paramObj->setInvalidMessage('URL isn\'t valid'); + return false; + } + if (!isset($parsed['host']) || empty($parsed['host'])) { + $paramObj->setInvalidMessage('URL must be a valid host'); + return false; + } + return true; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamForm.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamForm.php new file mode 100644 index 0000000..d13773e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamForm.php @@ -0,0 +1,1312 @@ +formAttr = array_merge($defaultAttr, (array) $formAttr); + + if (isset($formAttr['classes'])) { + $this->formAttr['classes'] = array_merge($defaultAttr['classes'], (array) $formAttr['classes']); + } + + if (isset($formAttr['labelClasses'])) { + $this->formAttr['labelClasses'] = array_merge($defaultAttr['labelClasses'], (array) $formAttr['labelClasses']); + } + + if (isset($formAttr['wrapperClasses'])) { + $this->formAttr['wrapperClasses'] = array_merge($defaultAttr['wrapperClasses'], (array) $formAttr['wrapperClasses']); + } + + if (isset($formAttr['inputContainerClasses'])) { + $this->formAttr['inputContainerClasses'] = array_merge($defaultAttr['inputContainerClasses'], (array) $formAttr['inputContainerClasses']); + } + + if (strlen($this->formAttr['label']) == 0) { + throw new Exception('Param ' . $name . ' must have label (user renderLabel to hide it)'); + } + + if ($this->formAttr['renderLabel']) { + $this->formAttr['wrapperClasses'][] = 'has-main-label'; + } + + $this->formType = $formType; + + if (empty($this->formAttr['id'])) { + $this->formAttr['id'] = 'param_item_' . $name; + } + + if (empty($this->formAttr['wrapperId'])) { + $this->formAttr['wrapperId'] = 'wrapper_item_' . $name; + } + + //Log::infoObject('PARAM INIZIALIZED ['.$this->name.']', $this, Log::LV_DEFAULT); + } + + /** + * Return param label + * + * @return string + */ + public function getLabel() + { + if (!empty($this->formAttr['label'])) { + return $this->formAttr['label']; + } else { + return parent::getLabel(); + } + } + + /** + * get the input id (input, select ... ) + * normally it depends on the name of the object but can be perosnalizzato through formAttrs + * + * @return string + */ + public function getFormItemId() + { + return $this->formAttr['id']; + } + + /** + * return the input wrapper id if isn't empty or false + * normally it depends on the name of the object but can be perosnalizzato through formAttrs + * + * @return string + */ + /** + * return the input wrapper id if isn't empty or false + * normally it depends on the name of the object but can be perosnalizzato through formAttrs + * + * @return string + */ + public function getFormWrapperId() + { + return empty($this->formAttr['wrapperId']) ? false : $this->formAttr['wrapperId']; + } + + /** + * return current form status + * + * @return string // STATUS_ENABLED | STATUS_READONLY ... + */ + public function getFormStatus() + { + if (is_callable($this->formAttr['status'])) { + return call_user_func($this->formAttr['status'], $this); + } else { + return $this->formAttr['status']; + } + } + + /** + * Add html class at param wrapper container + * + * @param string $class class string + * + * @return void + */ + public function addWrapperClass($class) + { + if (!in_array($class, $this->formAttr['wrapperClasses'])) { + $this->formAttr['wrapperClasses'][] = $class; + } + } + + /** + * Remove html class at param wrapper container + * + * @param string $class class string + * + * @return void + */ + public function removeWrapperClass($class) + { + if (in_array($class, $this->formAttr['wrapperClasses'])) { + unset($this->formAttr['wrapperClasses'][$class]); + } + } + + /** + * This function can be extended in child classes + * + * @return string + */ + protected function getAttrName() + { + return $this->name; + } + + /** + * this function renturn a hidden name for support checkbox input + * + * @return string + */ + protected function getAttrHiddenName() + { + return $this->getAttrName() . '_is_input'; + } + + /** + * this function can be extended in child classes + * + * @return mixed + */ + protected function getInputValue() + { + return $this->value; + } + + /** + * Return a copy of this object with a new name ad overwrite attr + * + * @param string $newName new param name + * @param array $attr param attributes + * @param array $formAttr form attributes + * + * @return self + */ + public function getCopyWithNewName($newName, $attr = array(), $formAttr = array()) + { + $copy = parent::getCopyWithNewName($newName, $attr); + + $reflect = new \ReflectionObject($copy); + + $formAttrProp = $reflect->getProperty('formAttr'); + $formAttrProp->setAccessible(true); + + $newAttr = $formAttrProp->getValue($copy); + $newAttr['id'] = 'param_item_' . $newName; + $newAttr['wrapperId'] = 'wrapper_item_' . $newName; + $newAttr = array_merge($newAttr, $formAttr); + + if (isset($newAttr['options']) && is_array($newAttr['options'])) { + $options = $newAttr['options']; + $newAttr['options'] = array(); + foreach ($options as $key => $option) { + if (is_object($option)) { + $newAttr['options'][$key] = clone $option; + } else { + $newAttr['options'][$key] = $option; + } + } + } + + $formAttrProp->setValue($copy, $newAttr); + + return $copy; + } + + /** + * + * @return bool + */ + public function isEnabled() + { + return $this->getFormStatus() == self::STATUS_ENABLED; + } + + /** + * + * @return bool + */ + public function isSkip() + { + return $this->getFormStatus() == self::STATUS_SKIP; + } + + /** + * + * @return bool + */ + public function isDisabled() + { + return $this->getFormStatus() == self::STATUS_DISABLED; + } + + /** + * + * @return bool + */ + public function isReadonly() + { + return $this->getFormStatus() == self::STATUS_READONLY; + } + + /** + * Return true if the passed value is in current value if type is array or equal if is scalar + * + * @param mixed $value value to check + * @param mixed $inputValue current selected value/s + * + * @return bool + */ + protected static function isValueInValue($value, $inputValue) + { + if (is_null($inputValue) || is_scalar($inputValue)) { + return $value == $inputValue; + } else { + return in_array($value, $inputValue); + } + } + + /** + * Display the html input of current item + * + * @return void + */ + protected function htmlItem() + { + switch ($this->formType) { + case self::FORM_TYPE_HIDDEN: + $this->hiddenHtml(); + break; + case self::FORM_TYPE_TEXT: + $this->inputHtml('text'); + break; + case self::FORM_TYPE_NUMBER: + $this->inputHtml('number'); + break; + case self::FORM_TYPE_SELECT: + $this->selectHtml(); + break; + case self::FORM_TYPE_CHECKBOX: + $this->checkBoxHtml(false); + break; + case self::FORM_TYPE_SWITCH: + $this->checkBoxHtml(true); + break; + case self::FORM_TYPE_M_CHECKBOX: + $this->mCheckBoxHtml(); + break; + case self::FORM_TYPE_RADIO: + $this->radioHtml(); + break; + case self::FORM_TYPE_BGROUP: + $this->bgroupHtml(); + break; + default: + throw new \Exception('ITEM ERROR ' . $this->name . ' Invalid form type ' . $this->formType); + } + } + + /** + * Return form attribute + * + * @param string $key form attribute key + * + * @return mixed + */ + public function getFormAttr($key) + { + return $this->formAttr[$key]; + } + + /** + * Set form attribute + * + * @param string $key form attribute key + * @param mixed $value value + * + * @return void + */ + public function setFormAttr($key, $value) + { + $this->formAttr[$key] = $value; + } + + /** + * Get param options + * + * @return ParamOption[] + */ + protected function getOptions() + { + if (!isset($this->formAttr['options'])) { + return array(); + } elseif (is_callable($this->formAttr['options'])) { + return call_user_func($this->formAttr['options'], $this); + } else { + return $this->formAttr['options']; + } + } + + /** + * Update option status + * + * @param int $index option index + * @param string $status option status + * + * @return void + */ + public function setOptionStatus($index, $status) + { + if (is_array($this->formAttr['options']) && isset($this->formAttr['options'][$index])) { + $this->formAttr['options'][$index]->setStatus($status); + } + } + + /** + * Html of current item if the status if info only + * + * @return void + */ + protected function infoOnlyHtml() + { + $attrs = array( + 'id' => $this->formAttr['id'] + ); + $classes = array_merge(array('input-info-only'), $this->formAttr['classes']); + $attrs['class'] = implode(' ', $classes); + ?> + > + valueToInfo()); ?> + + formType) { + case self::FORM_TYPE_SELECT: + case self::FORM_TYPE_M_CHECKBOX: + $optionsLabels = array(); + foreach ($this->getOptions() as $option) { + if (self::isValueInValue($option->value, $this->getInputValue())) { + $optionsLabels[] = $option->label; + } + } + return implode(', ', $optionsLabels); + case self::FORM_TYPE_CHECKBOX: + $result = ''; + if (self::isValueInValue($this->formAttr['checkedValue'], $this->getInputValue())) { + $result = '[enabled]'; + } else { + $result = '[disabled]'; + } + return $result . ' ' . $this->formAttr['checkboxLabel']; + case self::FORM_TYPE_RADIO: + case self::FORM_TYPE_BGROUP: + $optionsLabels = array(); + foreach ($this->getOptions() as $option) { + if (self::isValueInValue($option->value, $this->getInputValue())) { + return $option->label; + } + } + return '[disabled]'; + case self::FORM_TYPE_HIDDEN: + case self::FORM_TYPE_TEXT: + case self::FORM_TYPE_NUMBER: + default: + if (is_null($this->getInputValue()) || is_scalar($this->getInputValue())) { + return \DUPX_U::esc_html($this->getInputValue()); + } else { + return \DUPX_U::esc_html(implode(',', $this->getInputValue())); + } + } + } + + /** + * Get html form option of current item + * + * @param bool $echo if true echo html + * + * @return string + */ + public function getHtml($echo = true) + { + if ($this->isSkip() === true) { + return ''; + } + ob_start(); + + try { + $this->htmlItemBefore(); + if ($this->getFormStatus() == self::STATUS_INFO_ONLY) { + $this->infoOnlyHtml(); + } else { + $this->htmlItem(); + } + $this->htmlItemAfter(); + } catch (\Exception $e) { + ob_end_flush(); + throw $e; + } + + + if ($echo) { + ob_end_flush(); + return ''; + } else { + return ob_get_clean(); + } + } + + /** + * Input item before (wrapper input and label) + * + * @return void + */ + protected function htmlItemBefore() + { + if (!empty($this->formAttr['wrapperTag'])) { + $wrapperAttrs = array(); + if (!empty($this->formAttr['wrapperId'])) { + $wrapperAttrs['id'] = $this->formAttr['wrapperId']; + } + + $tmpWrapperClasses = $this->formAttr['wrapperClasses']; + if ($this->isDisabled()) { + $tmpWrapperClasses[] = 'param-wrapper-disabled'; + } + + if ($this->isReadonly()) { + $tmpWrapperClasses[] = 'param-wrapper-readonly'; + } + + if ($this->isEnabled()) { + $tmpWrapperClasses[] = 'param-wrapper-enabled'; + } + + if (!empty($tmpWrapperClasses)) { + $wrapperAttrs['class'] = implode(' ', $tmpWrapperClasses); + } + + foreach ($this->formAttr['wrapperAttr'] as $attrName => $attrVal) { + $wrapperAttrs[$attrName] = $attrVal; + } + + echo '<' . $this->formAttr['wrapperTag'] . ' ' . \DUPX_U_Html::arrayAttrToHtml($wrapperAttrs) . ' >'; + + if (!empty($this->formAttr['wrapperContainerTag'])) { + echo '<' . $this->formAttr['wrapperContainerTag'] . ' class="container" >'; + } + } + + $this->getLabelHtml(); + $this->htmlInputContBefore(); + if (!empty($this->formAttr['inputContainerTag'])) { + echo ''; + } + } + + /** + * function called between label and input container + * used on extended classes + * + * @return void + */ + protected function htmlInputContBefore() + { + } + + /** + * function calle after input container + * used on extended classes + * + * @return void + */ + protected function htmlInputContAfter() + { + } + + /** + * input item after (close wrapper) + * + * @return void + */ + protected function htmlItemAfter() + { + if (!empty($this->formAttr['inputContainerTag'])) { + echo ''; + } + + $this->htmlInputContAfter(); + if (!empty($this->formAttr['wrapperTag'])) { + if (!empty($this->formAttr['wrapperContainerTag'])) { + echo 'formAttr['wrapperContainerTag'] . '>'; + } + echo $this->getSubNote(); + echo 'formAttr['wrapperTag'] . '>'; + } else { + echo $this->getSubNote(); + } + } + + /** + * + * @return string + */ + protected function getSubNote() + { + + if (is_callable($this->formAttr['subNote'])) { + $subNote = call_user_func($this->formAttr['subNote'], $this); + } else { + $subNote = $this->formAttr['subNote']; + } + + return empty($subNote) ? '' : '
        ' . $subNote . '
        '; + } + + /** + * Return postfix element data + * + * @param array $data postix element data + * + * @return array + */ + protected function prefixPostfixElem($data) + { + $default = array( + 'type' => 'none', + 'label' => null, + 'id' => null, + 'btnAction' => null, + 'attrs' => array() + ); + + if (is_callable($data)) { + $element = call_user_func($data, $this); + } else { + $element = $data; + } + + if (is_array($element)) { + return array_merge($default, $element); + } else { + return $default; + } + } + + /** + * Return prefix element data + * + * @return array + */ + protected function getPrefix() + { + return $this->prefixPostfixElem($this->formAttr['prefix']); + } + + /** + * Return postifx element data + * + * @return array + */ + protected function getPostfix() + { + return $this->prefixPostfixElem($this->formAttr['postfix']); + } + + /** + * html if type is hidden + * + * @return void + */ + protected function hiddenHtml() + { + $attrs = array( + 'id' => $this->formAttr['id'], + 'name' => $this->getAttrName(), + 'value' => $this->getInputValue() + ); + + if ($this->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + if (!empty($this->formAttr['classes'])) { + $attrs['class'] = implode(' ', $this->formAttr['classes']); + } + + $attrs = array_merge($attrs, $this->formAttr['attr']); + ?> + > + $type, + 'id' => $this->formAttr['id'], + 'name' => $this->getAttrName(), + 'value' => $this->getInputValue() + ); + + if ($this->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + if (!is_null($this->formAttr['maxLength'])) { + $attrs['maxLength'] = $this->formAttr['maxLength']; + } + + if (!is_null($this->formAttr['size'])) { + $attrs['size'] = $this->formAttr['size']; + } + + if (isset($this->formAttr['min']) && !is_null($this->formAttr['min'])) { + $attrs['min'] = $this->formAttr['min']; + } + + if (isset($this->formAttr['max']) && !is_null($this->formAttr['max'])) { + $attrs['max'] = $this->formAttr['max']; + } + + if (isset($this->formAttr['step']) && !is_null($this->formAttr['step'])) { + $attrs['step'] = $this->formAttr['step']; + } + + if (!empty($this->formAttr['classes'])) { + $attrs['class'] = implode(' ', $this->formAttr['classes']); + } + + $prefixHtml = self::getPrefixPostfixHtml($this->getPrefix(), 'prefix'); + $postfixHtml = self::getPrefixPostfixHtml($this->getPostfix(), 'postfix'); + $isPrePostFix = (strlen($prefixHtml) > 0 || strlen($postfixHtml) > 0); + + $attrs = array_merge($attrs, $this->formAttr['attr']); + if ($isPrePostFix) { + ?> + + + > + + + $class); + switch ($element['type']) { + case 'button': + $tag = 'button'; + $attrs['type'] = 'button'; + if (!empty($element['btnAction'])) { + $attrs['onclick'] = $element['btnAction']; + } + break; + case 'label': + default: + $tag = 'span'; + break; + } + if (!empty($element['id'])) { + $attrs['id'] = $element['id']; + } + $attrs = array_merge($attrs, $element['attrs']); + return '<' . $tag . ' ' . \DUPX_U_Html::arrayAttrToHtml($attrs) . '>' . $element['label'] . ''; + } + + /** + * HTML if type is select + * + * @return void + */ + protected function selectHtml() + { + $attrs = array( + 'id' => $this->formAttr['id'], + 'name' => $this->getAttrName() . ($this->formAttr['multiple'] ? '[]' : ''), + ); + + if (!empty($this->formAttr['classes'])) { + $attrs['class'] = implode(' ', $this->formAttr['classes']); + } + + if ($this->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + if ($this->formAttr['multiple']) { + $attrs['multiple'] = ''; + } + + $attrs['size'] = $this->formAttr['size'] == 0 ? count($this->getOptions()) : $this->formAttr['size']; + + $attrs = array_merge($attrs, $this->formAttr['attr']); + ?> + + isHidden()) { + continue; + } + + if ($lastOptGroup !== $option->getOptGroup()) { + if (strlen($lastOptGroup) > 0) { + ?>getOptGroup()) > 0) { + ?>getOptGroup(); + } + + $optAttr = array( + 'value' => $option->value + ); + + if ($option->isDisabled()) { + $optAttr['disabled'] = 'disabled'; + } elseif ( + self::isValueInValue($option->value, $inputValue) || + $autoSelectFirst + ) { + // can't be selected if is disabled + $optAttr['selected'] = 'selected'; + } + + $optAttr = array_merge($optAttr, (array) $option->attrs); + ?> + + 0) { + ?> $this->formAttr['id'], + 'name' => $this->getAttrName(), + 'value' => $this->formAttr['checkedValue'] + ); + + if (!empty($this->formAttr['classes'])) { + $attrs['class'] = implode(' ', $this->formAttr['classes']); + } + + if ($this->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + if (self::isValueInValue($this->formAttr['checkedValue'], $this->getInputValue())) { + $attrs['checked'] = 'checked'; + } + + $attrs = array_merge($attrs, $this->formAttr['attr']); + + $hiddenAttrs = array( + 'name' => $this->getAttrHiddenName(), + 'value' => true + ); + + if ($switch) { + \DUPX_U_Html::checkboxSwitch($attrs); + } else { + ?> + > + + formAttr['checkboxLabel']; ?> + > + formAttr['attr']); + */ + foreach ($this->getOptions() as $index => $option) { + $attrs = array( + 'id' => $this->formAttr['id'] . '_' . $index, + 'name' => $this->getAttrName() . '[]', + 'value' => $option->value + ); + + if (!empty($this->formAttr['classes'])) { + $attrs['class'] = implode(' ', $this->formAttr['classes']); + } + + if (self::isValueInValue($option->value, $this->getInputValue())) { + $attrs['checked'] = 'checked'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + if ($this->isDisabled() || $option->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + $attrs = array_merge($attrs, $option->attrs); + if (!empty($attrs['title'])) { + $labelTtile = ' title="' . \DUPX_U::esc_attr($attrs['title']) . '"'; + unset($attrs['title']); + } else { + $labelTtile = ''; + } + ?> + + formAttr['attr']); + */ + foreach ($this->getOptions() as $index => $option) { + if ($option->isHidden()) { + continue; + } + + $attrs = array( + 'id' => $this->formAttr['id'] . '_' . $index, + 'name' => $this->getAttrName(), + 'value' => $option->value + ); + + $optionGroupClasses = 'option-group'; + + if (!empty($this->formAttr['classes'])) { + $attrs['class'] = implode(' ', $this->formAttr['classes']); + } + + if (self::isValueInValue($option->value, $this->getInputValue())) { + $attrs['checked'] = 'checked'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + if ($this->isDisabled() || $option->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + if ($option->isDisabled()) { + $optionGroupClasses .= ' option-disabled'; + } + + $attrs = array_merge($attrs, $option->attrs); + if (!empty($attrs['title'])) { + $labelTtile = ' title="' . \DUPX_U::esc_attr($attrs['title']) . '"'; + unset($attrs['title']); + } else { + $labelTtile = ''; + } + ?> + + formAttr['attr']); + */ + $this->hiddenHtml(); + foreach ($this->getOptions() as $index => $option) { + if ($option->isHidden()) { + continue; + } + + $attrs = array( + 'id' => $this->formAttr['id'] . '_' . $index, + 'value' => $option->value, + 'class' => $this->formAttr['id'] . '_button ' . implode(' ', $this->formAttr['classes']) + ); + + if (self::isValueInValue($option->value, $this->getInputValue())) { + $attrs['class'] .= ' active'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + if ($this->isDisabled() || $option->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + $attrs = array_merge($attrs, $option->attrs); + if (!empty($attrs['title'])) { + $labelTtile = ' title="' . \DUPX_U::esc_attr($attrs['title']) . '"'; + unset($attrs['title']); + } else { + $labelTtile = ''; + } + ?> + + formAttr['renderLabel'] == false) { + return ''; + } + + $attrs = array(); + if (!empty($this->formAttr['labelClasses'])) { + $attrs['class'] = implode(' ', $this->formAttr['labelClasses']); + } + ob_start(); + ?> + > + formAttr['label']) == 0 ? ' ' : \DUPX_U::esc_html($this->formAttr['label'])); + if (strlen($this->formAttr['inlineHelp']) > 0) { + $helpTitle = (strlen($this->formAttr['inlineHelpTitle']) ? $this->formAttr['inlineHelpTitle'] : rtrim($this->formAttr['label'], ':')); + ?> + + formAttr['proFlag']) > 0) { + $flagTitle = (strlen($this->formAttr['proFlagTitle']) ? $this->formAttr['proFlagTitle'] : rtrim($this->formAttr['label'], ':')); + ?>* + + + formAttr['status'] = $data['formStatus']; + } + return $result; + } + + /** + * return array dato to store in json array data + * + * @return array + */ + public function toArrayData() + { + $result = parent::toArrayData(); + if (!is_callable($this->formAttr['status'])) { + $result['formStatus'] = $this->getFormStatus(); + } + return $result; + } + + /** + * update the value from input if exists ot set the default + * sanitation and validation are performed + * skip set value if current status is disabled, info only or skip + * + * @param string $method query string method (POST, GET) + * + * @return boolean false if value isn't validated + */ + public function setValueFromInput($method = self::INPUT_POST) + { + // if input is disabled don't reads from input. + if ( + $this->getFormStatus() == self::STATUS_INFO_ONLY || + $this->getFormStatus() == self::STATUS_SKIP + ) { + return true; + } + + // prevent overwrite by default if item is disable and isn't enable in client by js + $superObject = self::getSuperObjectByMethod($method); + if ($this->getFormStatus() == self::STATUS_DISABLED && !$this->isValueInInput($superObject)) { + return true; + } + + // prevent overwrite by default if checkbox isn't in form + if (($this->formType === self::FORM_TYPE_CHECKBOX || $this->formType === self::FORM_TYPE_SWITCH) && !isset($superObject[$this->getAttrName()])) { + if (!isset($superObject[$this->getAttrHiddenName()]) || !$superObject[$this->getAttrHiddenName()]) { + return true; + } + } elseif (!isset($superObject[$this->name])) { + return true; + } + + return parent::setValueFromInput($method); + } + + /** + * this function return the default formAttr for each type. + * in the constructor an array merge is made between the result of this function and the parameters passed. + * In this way the values ​​in $ this -> ['attr'] are always consistent. + * + * @param string $formType form type + * + * @return array + */ + protected static function getDefaultAttrForFormType($formType) + { + $attrs = array( + 'label' => null, // input main label, + 'renderLabel' => true, // if false don\'t render label + 'labelClasses' => array('label', 'main-label'), // label classes (the label html is label + 'id' => null, // input id , if null the default is 'param_item_'.$name + 'classes' => array('input-item'), // input classes + 'status' => self::STATUS_ENABLED, // form status + 'title' => null, // input title + 'attr' => array(), // custom input attributes key="VALUE" + 'inlineHelpTitle' => '', + 'inlineHelp' => '', + 'proFlagTitle' => '', + 'proFlag' => '', + 'subNote' => null, // sub note container (html string), + 'wrapperTag' => 'div', // if null the input haven't the wrapper tag. + // input tag wrapper, wrapper html is + // ~ + 'wrapperId' => null, // input wrapper id, if null the default is 'wrapper_item_'.$name + 'wrapperClasses' => array(// wrapper classes, param-wrapper generic class plus 'param-form-type-'.$formType type class + 'param-wrapper', + 'param-form-type-' . $formType), + 'wrapperAttr' => array(), // custom wrapper attributes key="VALUE" + 'wrapperContainerTag' => 'label', + 'inputContainerTag' => 'span', + 'inputContainerClasses' => array('input-container'), + ); + + switch ($formType) { + case self::FORM_TYPE_HIDDEN: + $attrs['wrapperTag'] = null; // disable wrapper for hidden inputs + $attrs['wrapperContainerTag'] = null; + $attrs['inputContainerTag'] = null; + break; + case self::FORM_TYPE_NUMBER: + $attrs['min'] = null; // attr min + $attrs['max'] = null; // attr max + $attrs['step'] = null; // attr step + // continue form type text + case self::FORM_TYPE_TEXT: + $attrs['maxLength'] = null; // if null have no limit + $attrs['size'] = null; + $attrs['prefix'] = array( + 'type' => 'none', // none | button | label + 'label' => null, + 'id' => null, + 'btnAction' => null, + 'attrs' => array() + ); + $attrs['postfix'] = array( + 'type' => 'none', // none | button | label + 'label' => null, + 'id' => null, + 'btnAction' => null, + 'attrs' => array() + ); + break; + case self::FORM_TYPE_SELECT: + $attrs['classes'][] = 'js-select'; + $attrs['multiple'] = false; + $attrs['options'] = array(); // ParamOption[] | callback + $attrs['size'] = 1; // select size if 0 get num options + break; + case self::FORM_TYPE_CHECKBOX: + case self::FORM_TYPE_SWITCH: + $attrs['checkboxLabel'] = null; + $attrs['checkedValue'] = true; + break; + case self::FORM_TYPE_M_CHECKBOX: + $attrs['options'] = array(); // ParamOption[] | callback + $attrs['wrapperContainerTag'] = 'div'; + break; + case self::FORM_TYPE_RADIO: + $attrs['options'] = array(); // ParamOption[] | callback + $attrs['wrapperContainerTag'] = 'div'; + break; + case self::FORM_TYPE_BGROUP: + $attrs['options'] = array(); // ParamOption[] | callback + $attrs['wrapperContainerTag'] = 'span'; + $attrs['inputContainerClasses'] = array('input-container', 'btn-group'); + break; + default: + // accepts unknown values ​​because this class can be extended + } + + return $attrs; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormPass.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormPass.php new file mode 100644 index 0000000..662fd97 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormPass.php @@ -0,0 +1,94 @@ +formType == self::FORM_TYPE_PWD_TOGGLE) { + $this->pwdToggleHtml(); + } else { + parent::htmlItem(); + } + } + + /** + * return the text of current object for info only status + * + * @return string + */ + protected function valueToInfo() + { + return '**********'; + } + + /** + * Render PWD toggle element + * + * @return void + */ + protected function pwdToggleHtml() + { + $attrs = array( + 'value' => $this->getInputValue(), + ); + + if ($this->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + if (!is_null($this->formAttr['maxLength'])) { + $attrs['maxLength'] = $this->formAttr['maxLength']; + } + + if (!is_null($this->formAttr['size'])) { + $attrs['size'] = $this->formAttr['size']; + } + + $attrs = array_merge($attrs, $this->formAttr['attr']); + + \DUPX_U_Html::inputPasswordToggle($this->getAttrName(), $this->formAttr['id'], $this->formAttr['classes'], $attrs, true); + } + + /** + * Get default form attributes + * + * @param string $formType form type + * + * @return array + */ + protected static function getDefaultAttrForFormType($formType) + { + $attrs = parent::getDefaultAttrForFormType($formType); + if ($formType == self::FORM_TYPE_PWD_TOGGLE) { + $attrs['maxLength'] = null; // if null have no limit + $attrs['size'] = null; + } + return $attrs; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormPlugins.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormPlugins.php new file mode 100644 index 0000000..eb8f88f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormPlugins.php @@ -0,0 +1,318 @@ +formType == self::FORM_TYPE_PLUGINS_SELECT) { + $this->pluginSelectHtml(); + } else { + parent::htmlItem(); + } + } + + /** + * Render plugin selector HTML + * + * @return void + */ + protected function pluginSelectHtml() + { + $pluginsManager = \DUPX_Plugins_Manager::getInstance(); + $plugns_list = $pluginsManager->getPlugins(); + + $attrs = array( + 'id' => $this->formAttr['id'], + 'name' => $this->getAttrName() . '[]', + 'multiple' => '' + ); + $this->formAttr['classes'][] = 'no-display'; + + if (!empty($this->formAttr['classes'])) { + $attrs['class'] = implode(' ', array_unique($this->formAttr['classes'])); + } + + if ($this->isDisabled()) { + $attrs['disabled'] = 'disabled'; + } + + if ($this->isReadonly()) { + $attrs['readonly'] = 'readonly'; + } + + $attrs = array_merge($attrs, $this->formAttr['attr']); + ?> + + getSubNote(); + $this->pluginsSelector(); + } + + /** + * Render plugin selector + * + * @return void + */ + protected function pluginsSelector() + { + $pluginsManager = \DUPX_Plugins_Manager::getInstance(); + $plugns_list = $pluginsManager->getPlugins(); + $paramsManager = PrmMng::getInstance(); + $safe_mode = $paramsManager->getValue(PrmMng::PARAM_SAFE_MODE); + ?> +
        + isDisabled()) { ?> + 0) { + echo + '
        ' + . ' Safe Mode Enabled: Only Duplicator will be enabled during install.' + . '
        '; + } + ?> +
        + +
        +
          +
        • + + All () + +
        • + getStatusCounts() as $status => $count) { + if ($count) { + ?> +
        • + + () + +
        • + +
        + + + + + + + + + + + + isIgnore() || $pluginObj->isForceDisabled()) { + continue; + } + $this->pluginHtmlItem($pluginObj); + } + ?> + +
        NameDetailsOriginal
        Status
        + pluginTableSelectorJs(); + } + + /** + * Render plugin item + * + * @param \DUPX_Plugin_item $pluginObj plugin object + * @param int $subsiteId selected subsite id + * + * @return void + */ + protected function pluginHtmlItem($pluginObj, $subsiteId = -1) + { + $itemClasses = array( + 'table-item', + ); + $orgiStats = $pluginObj->getOrgiStatus($subsiteId); + $itemClasses[] = 'orig-' . $orgiStats; + $itemClasses[] = self::isValueInValue($pluginObj->slug, $this->getInputValue()) ? 'active' : 'inactive'; + + //$authorURI = $pluginObj->authorURI; + if (empty($pluginObj->authorURI)) { + $author = \DUPX_U::esc_html($pluginObj->author); + } else { + $author = '' . \DUPX_U::esc_html($pluginObj->author) . ''; + } + ?> + + + isReadonly() ? 'readonly' : ''; ?> isDisabled() ? 'disabled' : ''; ?>> + + name); ?> + + Version: version); ?>
        + URL: + pluginURI); ?> +
        + Author:
        + + getStatusLabel($orgiStats)); ?> + + + + formType == self::FORM_TYPE_TABLES_SELECT) { + $this->tablesSelectHtml(); + } else { + parent::htmlItem(); + } + } + + /** + * Render tables selector HTML + * + * @return void + */ + protected function tablesSelectHtml() + { + $tables = \DUPX_DB_Tables::getInstance(); + $value = $this->getInputValue(); + ?> + + + + + + + + + + + + + + + + + $tableVals) { + $this->tableHtmlItem($tableVals, $tables->getTableObjByName($name), $index); + $index++; + } + ?> + + + + + + + + + +
        + Toggle All + + + + + + + + + + +
        Original NameNew NameImportUpdate
        Original NameNew NameImportUpdate
        + getFormItemId() . self::TABLE_ITEM_POSTFIX + ); + $hiddenNameAttrs = array( + 'id' => $this->getFormItemId() . self::TABLE_NAME_POSTFIX_TNAME . '_' . $index, + 'type' => 'hidden', + 'name' => $this->getName() . '[]', + 'class' => $this->getFormItemId() . self::TABLE_NAME_POSTFIX_TNAME, + 'value' => $tableOjb->getOriginalName() + ); + $extractCheckboxAttrs = array( + 'id' => $this->getFormItemId() . self::TABLE_NAME_POSTFIX_EXTRACT . '_' . $index, + 'name' => $this->getName() . self::TABLE_NAME_POSTFIX_EXTRACT . '[]', + 'class' => $this->getFormItemId() . self::TABLE_NAME_POSTFIX_EXTRACT, + 'value' => 1 + ); + $replaceCheckboxAttrs = array( + 'id' => $this->getFormItemId() . self::TABLE_NAME_POSTFIX_REPLACE . '_' . $index, + 'name' => $this->getName() . self::TABLE_NAME_POSTFIX_REPLACE . '[]', + 'class' => $this->getFormItemId() . self::TABLE_NAME_POSTFIX_REPLACE, + 'value' => 1 + ); + + if ($tableOjb->canBeExctracted()) { + if ($vals['extract']) { + $extractCheckboxAttrs['checked'] = ''; + } + + if ($vals['replace']) { + $replaceCheckboxAttrs['checked'] = ''; + } + } else { + $itemClasses[] = 'no-display'; + $extractCheckboxAttrs['disabled'] = ''; + $replaceCheckboxAttrs['disabled'] = ''; + } + + if ($this->isDisabled() || $this->isReadonly()) { + $extractCheckboxAttrs['disabled'] = ''; + $replaceCheckboxAttrs['disabled'] = ''; + + $skipSendValue = true; + } else { + $skipSendValue = false; + } + ?> + + + getOriginalName()); ?>
        + Rows: getRows(); ?> Size: getSize(true); ?> + + + getNewName()); ?>
        +   + + + + > + 'Extract in database' + ) + ); + ?> + + + 'Apply replace engine at URLs and paths in database' + ) + ); + ?> + + + getTablesNames(); + $validateTables = array_keys($validateValue); + + // all tables in list have to exist in avaiable tables + foreach ($validateValue as $table => $tableValues) { + if (!in_array($table, $avaiableTables)) { + Log::info('INVALID ' . $table . ' ISN\'T IN AVAIBLE LIST: ' . Log::v2str($avaiableTables)); + return false; + } + } + + // all tables abaliable have to exists in list + foreach ($avaiableTables as $avaibleTable) { + if (!in_array($avaibleTable, $validateTables)) { + Log::info('AVAIABLE ' . $avaibleTable . ' ISN\'T IN PARAM LIST TABLE'); + return false; + } + } + + return true; + } + + /** + * Appli filter to value input + * + * @param array $superObject query string values + * + * @return array + */ + public function getValueFilter($superObject) + { + $result = array(); + + if (($tables = json_decode($superObject[$this->getName()])) == false) { + throw new \Exception('Invalid json string'); + } + + foreach ($tables as $table) { + $table = (array) $table; + if ($table['extract'] == false) { + // replace can't be true if extract if false + $table['replace'] = false; + } + $result[$table['name']] = $table; + } + + return $result; + } + + /** + * Return sanitized value + * + * @param mixed $value value input + * + * @return array + */ + public function getSanitizeValue($value) + { + $newValues = (array) $value; + $sanitizeValues = array(); + + foreach ($newValues as $key => $newValue) { + $sanitizedKey = SnapUtil::sanitizeNSCharsNewlineTrim($key); + $newValue = (array) $newValue; + + $sanitizedNewValue = self::getParamItemValueFromData(); + $sanitizedNewValue['name'] = isset($newValue['name']) ? SnapUtil::sanitizeNSCharsNewlineTrim($newValue['name']) : ''; + $sanitizedNewValue['extract'] = isset($newValue['extract']) ? filter_var($newValue['extract'], FILTER_VALIDATE_BOOLEAN) : false; + $sanitizedNewValue['replace'] = isset($newValue['replace']) ? filter_var($newValue['replace'], FILTER_VALIDATE_BOOLEAN) : false; + + $sanitizeValues[$sanitizedKey] = $sanitizedNewValue; + } + return $sanitizeValues; + } + + /** + * Get default type attributes + * + * @param string $type param type + * + * @return array + */ + protected static function getDefaultAttrForType($type) + { + $attrs = parent::getDefaultAttrForType($type); + if ($type == self::TYPE_ARRAY_TABLES) { + $attrs['default'] = array(); + } + + return $attrs; + } + + /** + * Get default form attributes + * + * @param string $formType form type + * + * @return array + */ + protected static function getDefaultAttrForFormType($formType) + { + $attrs = parent::getDefaultAttrForFormType($formType); + if ($formType == self::FORM_TYPE_TABLES_SELECT) { + $attrs['wrapperContainerTag'] = 'div'; + $attrs['inputContainerTag'] = 'div'; + } + return $attrs; + } + + /** + * Return param item from data + * + * @param string $name table name + * @param bool $extract extract + * @param bool $replace replace + * + * @return array + */ + public static function getParamItemValueFromData($name = '', $extract = false, $replace = false) + { + return array( + 'name' => $name, + 'extract' => $extract, + 'replace' => $replace + ); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormUsersReset.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormUsersReset.php new file mode 100644 index 0000000..45c53cf --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormUsersReset.php @@ -0,0 +1,105 @@ +formType == self::FORM_TYPE_USERS_PWD_RESET) { + $result = ''; + $users = \DUPX_ArchiveConfig::getInstance()->getUsersLists(); + + $mainInputId = $this->formAttr['id']; + foreach ($users as $userId => $login) { + $this->currentUserId = $userId; + $this->formAttr['id'] = $mainInputId . '_' . $this->currentUserId; + $this->formAttr['label'] = $login; + $result .= parent::getHtml($echo); + } + $this->currentUserId = -1; + $this->formAttr['id'] = $mainInputId; + return $result; + } else { + return parent::getHtml($echo); + } + } + + /** + * Display the html input of current item + * + * @return void + */ + protected function htmlItem() + { + if ($this->formType == self::FORM_TYPE_USERS_PWD_RESET) { + $this->pwdToggleHtml(); + } else { + parent::htmlItem(); + } + } + + /** + * Return attribute name + * + * @return string + */ + protected function getAttrName() + { + return $this->name . '[' . $this->currentUserId . ']'; + } + + /** + * Return input value + * + * @return mixed + */ + protected function getInputValue() + { + return isset($this->value[$this->currentUserId]) ? $this->value[$this->currentUserId] : ''; + } + + /** + * Get default form attributes + * + * @param string $formType form type + * + * @return array + */ + protected static function getDefaultAttrForFormType($formType) + { + $attrs = parent::getDefaultAttrForFormType($formType); + if ($formType == self::FORM_TYPE_USERS_PWD_RESET) { + $attrs['maxLength'] = null; // if null have no limit + $attrs['size'] = null; + } + return $attrs; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormWpConfig.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormWpConfig.php new file mode 100644 index 0000000..8a89cea --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamFormWpConfig.php @@ -0,0 +1,221 @@ +attr['defaultFromInput'] = $this->attr['default']; + $this->attr['defaultFromInput']['inWpConfig'] = false; + + if ($type === self::TYPE_BOOL) { + $this->attr['defaultFromInput']['value'] = false; + } + } + + /** + * this function is calle before sanitization. + * Is use in extendend classs and transform value before the sanitization and validation process + * + * @param array $superObject query string super object + * + * @return mixed + */ + protected function getValueFilter($superObject) + { + $result = array( + 'value' => parent::getValueFilter($superObject), + 'inWpConfig' => filter_var($superObject[$this->name . self::IN_WP_CONF_POSTFIX], FILTER_VALIDATE_BOOLEAN) + ); + + if (!parent::isValueInInput($superObject)) { + $result['value'] = $this->attr['defaultFromInput']['value']; + } + + return $result; + } + + /** + * Return sanitized value + * + * @param mixed $value input value + * + * @return mixed + */ + public function getSanitizeValue($value) + { + $result = (array) $value; + $result['value'] = parent::getSanitizeValue($result['value']); + return $result; + } + + /** + * Get value info from value + * + * @return string + */ + protected function valueToInfo() + { + if ($this->value['inWpConfig']) { + return 'Set in wp config with value ' . parent::valueToInfo(); + } else { + return 'Not set in wp config'; + } + } + + /** + * Return input value + * + * @return mixed + */ + protected function getInputValue() + { + return $this->value['value']; + } + + /** + * Return true if value is in input method + * + * @param array $superObject query string super object + * + * @return bool + */ + protected function isValueInInput($superObject) + { + return parent::isValueInInput($superObject) || isset($superObject[$this->name . self::IN_WP_CONF_POSTFIX]); + } + + /** + * Check if input value is valid + * + * @param mixed $value input value + * @param mixed $validateValue variable passed by reference. Updated to validated value in the case, the value is a valid value. + * + * @return bool true if is a valid value for this object + */ + public function isValid($value, &$validateValue = null) + { + if (!is_array($value) || !isset($value['value']) || !isset($value['inWpConfig'])) { + Log::info('WP CONFIG INVALID ARRAY VAL:' . Log::v2str($value)); + return false; + } + + // IF isn't in wp config the value isn't validate + if ($value['inWpConfig'] === false) { + $validateValue = $value; + return true; + } else { + $confValidValue = $value['value']; + if (parent::isValid($value['value'], $confValidValue) === false) { + Log::info('WP CONFIG INVALID VALUE:' . Log::v2str($confValidValue)); + return false; + } else { + $validateValue = $value; + $validateValue['value'] = $confValidValue; + return true; + } + } + } + + /** + * Render HTML input before content + * + * @return void + */ + protected function htmlInputContBefore() + { + if ($this->getFormStatus() == self::STATUS_INFO_ONLY) { + return; + } + + if (!$this->value['inWpConfig']) { + $this->formAttr['inputContainerClasses'][] = 'no-display'; + if ($this->formAttr['status'] == self::STATUS_ENABLED) { + $this->formAttr['status'] = self::STATUS_DISABLED; + } + } + + $inputAttrs = array( + 'name' => $this->name . self::IN_WP_CONF_POSTFIX, + 'value' => 1 + ); + if ($this->value['inWpConfig']) { + $inputAttrs['checked'] = 'checked'; + } + echo ''; + \DUPX_U_Html::checkboxSwitch( + $inputAttrs, + array( + 'title' => 'Add in wp config' + ) + ); + echo ''; + } + + /** + * This function return the default attr for each type. + * in the constructor an array merge is made between the result of this function and the parameters passed. + * In this way the values ​​in $ this -> ['attr'] are always consistent. + * + * @param string $type param value type + * + * @return array + */ + protected static function getDefaultAttrForType($type) + { + $attrs = parent::getDefaultAttrForType($type); + $valFromInput = $attrs['defaultFromInput']; + + $attrs['defaultFromInput'] = array( + 'value' => $valFromInput, + 'inWpConfig' => false + ); + return $attrs; + } + + /** + * this function return the default formAttr for each type. + * in the constructor an array merge is made between the result of this function and the parameters passed. + * In this way the values ​​in $ this -> ['attr'] are always consistent. + * + * @param string $formType form type + * + * @return array + */ + protected static function getDefaultAttrForFormType($formType) + { + $attrs = parent::getDefaultAttrForFormType($formType); + + $attrs['wrapperClasses'][] = 'wp-config-item'; + $attrs['wrapperContainerTag'] = 'div'; + return $attrs; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamItem.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamItem.php new file mode 100644 index 0000000..1d12685 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamItem.php @@ -0,0 +1,656 @@ +\0]+$/'; + const VALIDATE_REGEX_FILE_PATH = '/^([a-zA-Z]:[\\\\\/]|\/|\\\\\\\\|\/\/)[^<>\0]+$/'; + + protected $name = null; + protected $type = null; + protected $attr = array(); + protected $value = null; + protected $status = self::STATUS_INIT; + + /** + * Class constructor + * + * @param string $name param identifier + * @param string $type TYPE_STRING | TYPE_ARRAY_STRING | ... + * @param array $attr list of attributes + */ + public function __construct($name, $type, $attr = null) + { + if (empty($name) || strlen($name) < 4) { + throw new \Exception('the name can\'t be empty or len can\'t be minor of 4'); + } + $this->type = $type; + $this->attr = array_merge(static::getDefaultAttrForType($type), (array) $attr); + if ($type == self::TYPE_ARRAY_STRING || $type == self::TYPE_ARRAY_INT || $type == self::TYPE_ARRAY_MIXED) { + $this->attr['default'] = (array) $this->attr['default']; + } + $this->name = $name; + $this->value = $this->getSanitizeValue($this->attr['default']); + + if (is_null($this->attr['defaultFromInput'])) { + $this->attr['defaultFromInput'] = $this->attr['default']; + } else { + if ($type == self::TYPE_ARRAY_STRING || $type == self::TYPE_ARRAY_INT || $type == self::TYPE_ARRAY_MIXED) { + $this->attr['defaultFromInput'] = (array) $this->attr['defaultFromInput']; + } + } + } + + /** + * this funtion return the discursive label + * + * @return string + */ + public function getLabel() + { + return $this->name; + } + + /** + * get current item identifier + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * get current item value + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * + * @return string // STATUS_INIT | STATUS_OVERWRITE | STATUS_UPD_FROM_INPUT + */ + public function getStatus() + { + return $this->status; + } + + /** + * Set item status with overwrite value + * + * @return void + */ + public function setOveriteStatus() + { + $this->status = self::STATUS_OVERWRITE; + } + + /** + * if it is true, this object is defined as persistent and will be saved in the parameter persistence file otherwise the param manager + * will not save this value and at each call of the script the parameter will assume the default value. + * + * @return bool + */ + public function isPersistent() + { + return $this->attr['persistence']; + } + + /** + * return the invalid param message or empty string + * + * @return string + */ + public function getInvalidMessage() + { + if (is_callable($this->attr['invalidMessage'])) { + return call_user_func($this->attr['invalidMessage'], $this); + } else { + return (string) $this->attr['invalidMessage']; + } + } + + /** + * Set the invalid param message + * + * @param $message invalid message + * + * @return string + */ + public function setInvalidMessage($message) + { + $this->attr['invalidMessage'] = (string) $message; + } + + /** + * Update item attribute + * + * @param string $key attribute key + * @param mixed $value value + * + * @return void + */ + public function setAttr($key, $value) + { + $this->attr[$key] = $value; + } + + /** + * Set param value + * + * @param mixed $value value to set + * + * @return boolean false if value isn't validated + */ + public function setValue($value) + { + $validateValue = null; + if (!$this->isValid($value, $validateValue)) { + return false; + } + + $this->value = $validateValue; + return true; + } + + /** + * Get super object from method + * + * @param string $method query string method + * + * @return array return the reference + */ + protected static function getSuperObjectByMethod($method) + { + $superObject = array(); + switch ($method) { + case self::INPUT_GET: + $superObject = &$_GET; + break; + case self::INPUT_POST: + $superObject = &$_POST; + break; + case self::INPUT_REQUEST: + $superObject = &$_REQUEST; + break; + case self::INPUT_COOKIE: + $superObject = &$_COOKIE; + break; + case self::INPUT_SERVER: + $superObject = &$_SERVER; + break; + case self::INPUT_ENV: + $superObject = &$_ENV; + break; + default: + throw new \Exception('INVALID SUPER OBJECT METHOD ' . Log::v2str($method)); + } + return $superObject; + } + + /** + * Return true if value is in input method + * + * @param array $superObject query string super object + * + * @return bool + */ + protected function isValueInInput($superObject) + { + return isset($superObject[$this->name]); + } + + /** + * update the value from input if exists ot set the default + * sanitation and validation are performed + * + * @param string $method query string method + * + * @return boolean false if value isn't validated + */ + public function setValueFromInput($method = self::INPUT_POST) + { + $superObject = self::getSuperObjectByMethod($method); + + Log::info( + 'SET VALUE FROM INPUT KEY [' . $this->name . '] VALUE[' . + Log::v2str(isset($superObject[$this->name]) ? $superObject[$this->name] : '') . + ']', + Log::LV_DEBUG + ); + + if (!$this->isValueInInput($superObject)) { + $inputValue = $this->attr['defaultFromInput']; + } else { + // get value from input + $inputValue = $this->getValueFilter($superObject); + // sanitize value + $inputValue = $this->getSanitizeValue($inputValue); + } + + if (($result = $this->setValue($inputValue)) === false) { + $msg = 'PARAM [' . $this->name . '] ERROR: Invalid value ' . Log::v2str($inputValue); + Log::info($msg); + return false; + } else { + $this->status = self::STATUS_UPD_FROM_INPUT; + } + + return $result; + } + + /** + * Check if input value is valid + * + * @param mixed $value input value + * @param mixed $validateValue variable passed by reference. Updated to validated value in the case, the value is a valid value. + * + * @return bool true if is a valid value for this object + */ + public function isValid($value, &$validateValue = null) + { + switch ($this->type) { + case self::TYPE_STRING: + case self::TYPE_BOOL: + case self::TYPE_INT: + return $this->isValidScalar($value, $validateValue); + case self::TYPE_ARRAY_STRING: + case self::TYPE_ARRAY_INT: + case self::TYPE_ARRAY_MIXED: + return $this->isValidArray($value, $validateValue); + default: + throw new \Exception('ITEM ERROR invalid type ' . $this->type); + } + } + + /** + * Validate function for scalar value + * + * @param mixed $value input value + * @param mixed $validateValue variable passed by reference. Updated to validated value in the case, the value is a valid value. + * + * @return boolean false if value isn't a valid value + */ + protected function isValidScalar($value, &$validateValue = null) + { + if (!is_null($value) && !is_scalar($value)) { + return false; + } + + $result = true; + switch ($this->type) { + case self::TYPE_STRING: + case self::TYPE_ARRAY_STRING: + $validateValue = (string) $value; + if (strlen($validateValue) < $this->attr['min_len']) { + $this->setInvalidMessage('Must have ' . $this->attr['min_len'] . ' or more characters'); + $result = false; + } + + if ($this->attr['max_len'] > 0 && strlen($validateValue) > $this->attr['max_len']) { + $this->setInvalidMessage('Must have max ' . $this->attr['mimax_lenn_len'] . ' characters'); + $result = false; + } + + if (!empty($this->attr['validateRegex']) && preg_match($this->attr['validateRegex'], $validateValue) !== 1) { + $this->setInvalidMessage('String isn\'t valid'); + $result = false; + } + break; + case self::TYPE_INT: + case self::TYPE_ARRAY_INT: + $validateValue = filter_var($value, FILTER_VALIDATE_INT, array( + 'options' => array( + 'default' => false, // value to return if the filter fails + 'min_range' => $this->attr['min_range'], + 'max_range' => $this->attr['max_range'], + ) + )); + + if ($validateValue === false) { + $this->setInvalidMessage('Isn\'t a valid number'); + $result = false; + } + break; + case self::TYPE_BOOL: + $validateValue = is_bool($value) ? $value : filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); + if (($result = !is_null($validateValue)) === false) { + $this->setInvalidMessage('Isn\'t a valid value'); + } + break; + default: + throw new \Exception('ITEM ERROR ' . $this->name . ' Invalid type ' . $this->type); + } + + if ($result == true) { + $acceptValues = $this->getAcceptValues(); + if (empty($acceptValues)) { + $result = $this->callValidateCallback($validateValue); + } else { + if (in_array($validateValue, $acceptValues)) { + $result = true; + } else { + $this->setInvalidMessage('Isn\'t a accepted value'); + $result = false; + } + } + } + + if ($result === false) { + $validateValue = null; + } + + return $result; + } + + /** + * Validate function for array value + * + * @param mixed $value input value + * @param mixed $validateValue variable passed by reference. Updated to validated value in the case, the value is a valid value. + * + * @return boolean false if value isn't a valid value + */ + protected function isValidArray($value, &$validateValue = null) + { + $newValues = (array) $value; + $validateValue = array(); + $validValue = null; + + if ($this->type == self::TYPE_ARRAY_MIXED) { + $validateValue = $newValues; + return $this->callValidateCallback($newValues); + } else { + foreach ($newValues as $key => $newValue) { + if (!$this->isValidScalar($newValue, $validValue)) { + return false; + } + $validateValue[$key] = $validValue; + } + } + return true; + } + + /** + * Call attribute validate callback + * + * @param mixed $value input value + * + * @return mixed + */ + protected function callValidateCallback($value) + { + if (is_callable($this->attr['validateCallback'])) { + return call_user_func($this->attr['validateCallback'], $value, $this); + } elseif (!is_null($this->attr['validateCallback'])) { + throw new \Exception('PARAM ' . $this->name . ' validateCallback isn\'t null and isn\'t callable'); + } else { + return true; + } + } + + /** + * this function is calle before sanitization. + * Is use in extendend classs and transform value before the sanitization and validation process + * + * @param array $superObject query string super object + * + * @return mixed + */ + protected function getValueFilter($superObject) + { + if (isset($superObject[$this->name])) { + return $superObject[$this->name]; + } else { + return null; + } + } + + /** + * Return sanitized value + * + * @param mixed $value input value + * + * @return mixed + */ + public function getSanitizeValue($value) + { + switch ($this->type) { + case self::TYPE_STRING: + case self::TYPE_BOOL: + case self::TYPE_INT: + return $this->getSanitizeValueScalar($value); + case self::TYPE_ARRAY_STRING: + case self::TYPE_ARRAY_INT: + return $this->getSanitizeValueArray($value); + case self::TYPE_ARRAY_MIXED: + // global sanitize for mixed + return $this->getSanitizeValueScalar($value); + default: + throw new \Exception('ITEM ERROR invalid type ' . $this->type); + } + } + + /** + * If sanitizeCallback is apply sanitizeCallback at current value else return value. + * + * @param mixed $value input value + * + * @return mixed + */ + protected function getSanitizeValueScalar($value) + { + if (is_callable($this->attr['sanitizeCallback'])) { + return call_user_func($this->attr['sanitizeCallback'], $value); + } elseif (!is_null($this->attr['sanitizeCallback'])) { + throw new \Exception('PARAM ' . $this->name . ' sanitizeCallback isn\'t null and isn\'t callable'); + } else { + return $value; + } + } + + /** + * If sanitizeCallback is apply sanitizeCallback at each value of array. + * + * @param mixed $value input value + * + * @return array + */ + protected function getSanitizeValueArray($value) + { + $newValues = (array) $value; + $sanitizeValues = array(); + + foreach ($newValues as $key => $newValue) { + $sanitizeValues[$key] = $this->getSanitizeValueScalar($newValue); + } + + return $sanitizeValues; + } + + /** + * get accept values + * + * @return array + */ + public function getAcceptValues() + { + if (is_callable($this->attr['acceptValues'])) { + return call_user_func($this->attr['acceptValues'], $this); + } else { + return $this->attr['acceptValues']; + } + } + + /** + * Set value from array. This function is used to set data from json array + * + * @param array $data param data + * + * @return boolean + */ + public function fromArrayData($data) + { + $data = (array) $data; + if (isset($data['status'])) { + $this->status = $data['status']; + } + + // only if value is different from current value + if (isset($data['value']) && $data['value'] !== $this->value) { + $sanitizedVal = $this->getSanitizeValue($data['value']); + return $this->setValue($sanitizedVal); + } else { + return true; + } + } + + /** + * return array dato to store in json array data + * + * @return array + */ + public function toArrayData() + { + return array( + 'value' => $this->value, + 'status' => $this->status + ); + } + + /** + * Return a copy of this object with a new name ad overwrite attr + * + * @param string $newName new name + * @param array $attr overwrite attributes + * + * @return self + */ + public function getCopyWithNewName($newName, $attr = array()) + { + $copy = clone $this; + $reflect = new \ReflectionObject($copy); + + $nameProp = $reflect->getProperty('name'); + $nameProp->setAccessible(true); + $nameProp->setValue($copy, $newName); + + $attrProp = $reflect->getProperty('attr'); + $attrProp->setAccessible(true); + $newAttr = array_merge($attrProp->getValue($copy), $attr); + $attrProp->setValue($copy, $newAttr); + + $valueProp = $reflect->getProperty('value'); + $valueProp->setAccessible(true); + $valueProp->setValue($copy, $newAttr['default']); + + return $copy; + } + + /** + * This function return the default attr for each type. + * in the constructor an array merge is made between the result of this function and the parameters passed. + * In this way the values ​​in $ this -> ['attr'] are always consistent. + * + * @param string $type param value type + * + * @return array + */ + protected static function getDefaultAttrForType($type) + { + $attrs = array( + 'default' => null, // the default value on init + 'defaultFromInput' => null, // if value isn't set in query form when setValueFromInput is called set this valus. + // (normally defaultFromInput is equal to default) + 'acceptValues' => array(), // if not empty accept only values in list | callback + 'sanitizeCallback' => null, // function (ParamItem $obj, $inputValue) + 'validateCallback' => null, // function (ParamItem $obj, $validateValue, $originalValue) + 'persistence' => true, // if false don't store value in persistence file + 'invalidMessage' => '' //this message is added at next step validation error message if not empty + ); + + switch ($type) { + case self::TYPE_STRING: // value type is a string + $attrs['min_len'] = 0; // min string len. used in validation + $attrs['max_len'] = 0; // max string len. used in validation + $attrs['default'] = ''; // set default at empty string + $attrs['validateRegex'] = null; // if isn;t null this regex is called to pass for validation. + //Can be combined with validateCallback. If both are active, the validation must pass both. + break; + case self::TYPE_ARRAY_STRING: // value type is array of string + $attrs['min_len'] = 0; // min string len. used in validation + $attrs['max_len'] = 0; // max string len. used in validation + $attrs['default'] = array(); // set default at empty array + $attrs['validateRegex'] = null; // if isn;t null this regex is called to pass for validation. + // Can be combined with validateCallback. If both are active, the validation must pass both. + break; + case self::TYPE_INT: // value type is a int + $attrs['min_range'] = PHP_INT_MAX * -1; + $attrs['max_range'] = PHP_INT_MAX; + $attrs['default'] = 0; // set default at 0 + break; + case self::TYPE_ARRAY_INT: // value type is an array of int + $attrs['min_range'] = PHP_INT_MAX * -1; + $attrs['max_range'] = PHP_INT_MAX; + $attrs['default'] = array(); // set default at empty array + break; + case self::TYPE_BOOL: + $attrs['default'] = false; // set default fals + $attrs['defaultFromInput'] = false; // if value isn't set in input the default must be false for bool values + break; + case self::TYPE_ARRAY_MIXED: + break; + default: + // accepts unknown values ​​because this class can be extended + } + return $attrs; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamOption.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamOption.php new file mode 100644 index 0000000..5da17dc --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/Items/ParamOption.php @@ -0,0 +1,149 @@ +value = $value; + $this->label = $label; + $this->optStatus = $optStatus; + $this->attrs = (array) $attrs; + } + + /** + * get current statis. + * + * @return string + */ + public function getStatus() + { + if (is_callable($this->optStatus)) { + return call_user_func($this->optStatus, $this); + } else { + return $this->optStatus; + } + } + + /** + * Set options status + * + * @param string|callable $optStatus option status. can be a fixed status or a callback + * + * @return void + */ + public function setStatus($optStatus) + { + $this->optStatus = $optStatus; + } + + /** + * Set option note + * + * @param string|callable $note option note + * + * @return void + */ + public function setNote($note) + { + $this->note = is_callable($note) ? $note : ((string) $note); + } + + /** + * + * @return string + */ + public function getNote() + { + $note = ''; + if (is_callable($this->note)) { + $note = call_user_func($this->note, $this); + } else { + $note = $this->note; + } + + return (empty($note) ? '' : '
        ' . $note . '
        '); + } + + /** + * Set option group, used on select + * + * @param string $label optiongroup label is empty reset option + * + * @return void + */ + public function setOptGroup($label) + { + $this->groupLabel = (string) $label; + } + + /** + * Return option group label, empty if not set + * + * @return string + */ + public function getOptGroup() + { + return $this->groupLabel; + } + + /** + * + * @return bool + */ + public function isEnable() + { + return $this->getStatus() == self::OPT_ENABLED; + } + + /** + * + * @return bool + */ + public function isDisabled() + { + return $this->getStatus() == self::OPT_DISABLED; + } + + /** + * + * @return bool + */ + public function isHidden() + { + return $this->getStatus() == self::OPT_HIDDEN; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/PrmMng.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/PrmMng.php new file mode 100644 index 0000000..12b76cc --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Core/Params/PrmMng.php @@ -0,0 +1,863 @@ +params); + $this->params = HooksMng::getInstance()->applyFilters('installer_get_init_params', $this->params); + + $this->paramsHtmlInfo[] = '***** INIT PARAMS WITH STD VALUlES'; + + return true; + } + + /** + * get value of param key. + * thorw execption if key don't exists + * + * @param string $key param key + * + * @return mixed + * + * @throws \Exception + */ + public function getValue($key) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + return $this->params[$key]->getValue(); + } + + /** + * Get param status + * + * @param string $key param key + * + * @return string // STATUS_INIT | STATUS_OVERWRITE | STATUS_UPD_FROM_INPUT + * + * @throws \Exception + */ + public function getInitStatus($key) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'does not exists'); + } + return $this->params[$key]->getStatus(); + } + + /** + * get the label of param key. + * thorw execption if key don't exists + * + * @param string $key param key + * + * @return string + * + * @throws \Exception + */ + public function getLabel($key) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + return rtrim($this->params[$key]->getLabel(), ": \n\t"); + } + + /** + * Set param value + * + * @param string $key param key + * @param mixed $value value + * + * @return boolean // return false if params isn't valid + * + * @throws \Exception // if key don't exists + */ + public function setValue($key, $value) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + return $this->params[$key]->setValue($value); + } + + /** + * this cungion set value get from input method. + * + * @param string $key param key + * @param string $method input method (GET, POST ... ) + * @param boolean $thowException if true throw exception if value isn't valid. + * @param boolean $nextStepErrorMessage if true and param isn't valid add next step message + * + * @return boolean + */ + public function setValueFromInput($key, $method = ParamForm::INPUT_POST, $thowException = true, $nextStepErrorMessage = false) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (($result = $this->params[$key]->setValueFromInput($method)) === false) { + $this->paramsHtmlInfo[] = 'INVALID VALUE INPUT ' . $key . ''; + + if ($nextStepErrorMessage) { + $this->addParamValidationFaliedNotice($key); + } + if ($thowException) { + $errorMessage = 'Parameter "' . $this->getLabel($key) . '" have invalid value'; + throw new \Exception('PARAM ERROR: ' . $errorMessage); + } + } else { + $this->paramsHtmlInfo[] = 'SET FROM INPUT ' . $key . ' VALUE: ' . Log::v2str($this->params[$key]->getValue()); + } + return $result; + } + + /** + * Add next step validation failed notice + * + * @param string $key param key + * + * @return void + */ + public function addParamValidationFaliedNotice($key) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + $longMessage = '' . $this->getLabel($key) . ' ' . $this->params[$key]->getInvalidMessage() . "
        \n"; + \DUPX_NOTICE_MANAGER::getInstance()->addNextStepNotice(array( + 'shortMsg' => 'Parameter validation failed', + 'level' => \DUPX_NOTICE_ITEM::CRITICAL, + 'longMsg' => $longMessage, + 'longMsgMode' => \DUPX_NOTICE_ITEM::MSG_MODE_HTML + ), \DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, 'params_validation_fail'); + } + + /** + * Return the form param wrapper id + * + * @param string $key param key + * + * @return boolean|string return false if the item key isn't a instance of ParamForm + */ + public function getFormWrapperId($key) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (method_exists($this->params[$key], 'getFormWrapperId')) { + return $this->params[$key]->getFormWrapperId(); + } else { + return false; + } + } + + /** + * Return form item id + * + * @param string $key param key + * + * @return boolean|string return false if the item key isn't a instance of ParamForm + */ + public function getFormItemId($key) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (method_exists($this->params[$key], 'getFormItemId')) { + return $this->params[$key]->getFormItemId(); + } else { + return false; + } + } + + /** + * Get param form status + * + * @param string $key param key + * + * @return boolean|string return false if the item key isn't a instance of ParamForm + */ + public function getFormStatus($key) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (method_exists($this->params[$key], 'getFormStatus')) { + return $this->params[$key]->getFormStatus(); + } else { + return false; + } + } + + /** + * Set form param status + * + * @param string $key param key + * @param string|callable $status STATUS_ENABLED , STATUS_READONLY or callable function + * + * @return boolean|string return false if the item key isn't a instance of ParamForm + */ + public function setFormStatus($key, $status) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (method_exists($this->params[$key], 'setFormAttr')) { + return $this->params[$key]->setFormAttr('status', $status); + } else { + return false; + } + } + + /** + * Set form wrapper class + * + * @param string $key param key + * @param string $class wrapper class + * + * @return boolean|string return false if the item key isn't a instance of ParamForm + */ + public function addFormWrapperClass($key, $class) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (method_exists($this->params[$key], 'addWrapperClass')) { + return $this->params[$key]->addWrapperClass($class); + } else { + return false; + } + } + + /** + * Remove form wrapper class + * + * @param string $key param key + * @param string $class wrapper class + * + * @return boolean|string return false if the item key isn't a instance of ParamForm + */ + public function removeFormWrapperClass($key, $class) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (method_exists($this->params[$key], 'removeWrapperClass')) { + return $this->params[$key]->removeWrapperClass($class); + } else { + return false; + } + } + + /** + * This tunction add o remove note on the param form + * + * @param string $key param key + * @param string $htmlString true if is html + * + * @return boolean + */ + public function setFormNote($key, $htmlString) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (method_exists($this->params[$key], 'setFormAttr')) { + $this->params[$key]->setFormAttr('subNote', $htmlString); + return true; + } else { + return false; + } + } + + /** + * return true if the input exists in html form + * false if isn't ParamForm object or status is STATUS_INFO_ONLY or STATUS_SKIP + * + * @param string $key param key + * + * @return boolean + */ + public function isHtmlInput($key) + { + $status = $this->getFormStatus($key); + switch ($status) { + case ParamForm::STATUS_ENABLED: + case ParamForm::STATUS_READONLY: + case ParamForm::STATUS_DISABLED: + return true; + case ParamForm::STATUS_INFO_ONLY: + case ParamForm::STATUS_SKIP: + default: + return false; + } + } + + /** + * get the input form html + * + * @param string $key the param identifier + * @param mixed $overwriteValue if not null set overwriteValue begore get html + * (IMPORTANT: the stored param value don't change. To change it use setValue.) + * @param bool $echo true echo else return string + * + * @return bool|string return false if the item kay isn't a instance of ParamForm + */ + public function getHtmlFormParam($key, $overwriteValue = null, $echo = true) + { + if (!isset($this->params[$key])) { + throw new \Exception('Param key ' . Log::v2str($key) . 'don\' exists'); + } + + if (!($this->params[$key] instanceof ParamForm)) { + return false; + } + + if (is_null($overwriteValue)) { + return $this->params[$key]->getHtml($echo); + } else { + $tmpParam = clone $this->params[$key]; + if ($tmpParam->setValue($overwriteValue) === false) { + throw new \Exception('Can\'t set overwriteValue ' . Log::v2str($overwriteValue) . ' in param:' . $tmpParam->getName()); + } + + return $tmpParam->getHtml($echo); + } + } + + /** + * Load params from persistance files + * + * @param boolean $reset if true reset params + * + * @return boolean + */ + public function load($reset = false) + { + if ($reset) { + $this->resetParams(); + $this->initParamsOverwrite(); + return true; + } else { + if (!file_exists(self::getPersistanceFilePath())) { + return false; + } + $this->paramsHtmlInfo[] = '***** LOAD PARAMS FROM PERSISTENCE FILE'; + + if (($json = file_get_contents(self::getPersistanceFilePath())) === false) { + throw new \Exception('Can\'t read param persistence file ' . Log::v2str(self::getPersistanceFilePath())); + } + + $arrayData = json_decode($json, true); + if ($this->setParamsValues($arrayData) === false) { + throw new \Exception('Can\'t set params from persistence file ' . Log::v2str(self::getPersistanceFilePath())); + } + return true; + } + } + + /** + * Remove persistance file and all params and reinit all + * + * @return boolean + */ + protected function resetParams() + { + $this->paramsHtmlInfo[] = '***** RESET PARAMS'; + SnapIO::rm(self::getPersistanceFilePath()); + $this->params = array(); + self::$initialized = false; + return $this->initParams(); + } + + /** + * Ovrewrite params from sources + * + * @return boolean + */ + public function initParamsOverwrite() + { + Log::info('OVERWRITE PARAMS'); + $this->paramsHtmlInfo[] = '***** LOAD OVERWRITE INFO'; + /** + * @todo temp disabled require major study + * if (isset($_ENV[self::ENV_PARAMS_KEY])) { + * $this->paramsHtmlInfo[] = 'LOAD FROM ENV VARS'; + $arrayData = json_decode($_ENV[self::ENV_PARAMS_KEY]); + $this->setParamsValues($arrayData, true); + } */ + // LOAD PARAMS FROM PACKAGE OVERWRITE + $arrayData = (array) \DUPX_ArchiveConfig::getInstance()->overwriteInstallerParams; + if (!empty($arrayData)) { + $this->paramsHtmlInfo[] = '***** LOAD FROM PACKAGE OVERWRITE'; + Log::info(' *** FROM PACKAGE'); + if ($this->setParamsValues($arrayData, true, Log::LV_DEFAULT) === false) { + throw new \Exception('Can\'t set params from package overwrite '); + } + } + + // LOAD PARAMS FROM LOCAL OVERWRITE + $localOverwritePath = DUPX_ROOT . '/' . self::LOCAL_OVERWRITE_PARAMS . self::LOCAL_OVERWRITE_PARAMS_EXTENSION; + if (is_readable($localOverwritePath)) { + // json file is set in $localOverwritePath php file + $json = null; + include($localOverwritePath); + if (empty($json)) { + Log::info('LOCAL OVERWRITE PARAMS FILE ISN\'T WELL FORMED'); + } else { + $arrayData = json_decode($json, true); + if (!empty($arrayData)) { + $this->paramsHtmlInfo[] = '***** LOAD FROM LOCAL OVERWRITE'; + Log::info(' *** FROM LOCAL FILE'); + if ($this->setParamsValues($arrayData, true, Log::LV_DEFAULT) === false) { + throw new \Exception('Can\'t set params from local overwrite '); + } + } + } + } + + // LOAD PARAMS FROM LOCAL OVERWRITE PACKAGE_HASH + $localOverwritePath = DUPX_ROOT . '/' . self::LOCAL_OVERWRITE_PARAMS . '_' . Bootstrap::getPackageHash() . '.json'; + if (is_readable($localOverwritePath)) { + if (($json = file_get_contents($localOverwritePath)) === false) { + Log::info('CAN\'T READ LOCAL OVERWRITE PARAM HASH FILE'); + } else { + $arrayData = json_decode($json, true); + if (!empty($arrayData)) { + $this->paramsHtmlInfo[] = '***** LOAD FROM LOCAL OVERWRITE HASH'; + Log::info(' *** FROM LOCAL FILE'); + if ($this->setParamsValues($arrayData, true, Log::LV_DEFAULT) === false) { + throw new \Exception('Can\'t set params from local overwrite '); + } + } + } + } + + HooksMng::getInstance()->doAction('after_params_overwrite', $this->params); + + Log::info("********************************************************************************"); + return true; + } + + /** + * Update params values from arrayData + * + * @param array $arrayData params data + * @param boolean $overwrite if true overwrite status + * @param integer $logginLevelSet log level + * + * @return bool returns false if a parameter has not been set + */ + protected function setParamsValues($arrayData, $overwrite = false, $logginLevelSet = Log::LV_DEBUG) + { + + if (!is_array($arrayData)) { + throw new \Exception('Invalid data params '); + } + $result = true; + + foreach ($arrayData as $key => $arrayValues) { + if (isset($this->params[$key])) { + $arrayValues = (array) $arrayValues; + $arrayValValToStr = array_map(array('Duplicator\\Installer\\Utils\\Log\\Log', 'v2str'), $arrayValues); + + $this->paramsHtmlInfo[] = 'SET PARAM ' . $key . ' ARRAY DATA: ' . + SnapString::implodeKeyVals(', ', $arrayValValToStr, '[%s = %s]'); + if ($this->params[$key]->fromArrayData($arrayValues) === false) { + Log::info('PARAM ISSUE SET KEY[' . $key . '] VALUE: ' . SnapString::implodeKeyVals(', ', $arrayValValToStr, '[%s = %s]')); + Log::info(Log::traceToString(debug_backtrace())); + // $result = false; + } else { + $log = 'PARAM SET KEY[' . $key . ']'; + $log .= (Log::isLevel(Log::LV_DEBUG) ? (' VALUE: ' . SnapString::implodeKeyVals(', ', $arrayValValToStr, '[%s = %s]')) : ''); + Log::info($log, $logginLevelSet); + if ($overwrite) { + $this->params[$key]->setOveriteStatus(); + } + } + } + } + return $result; + } + + /** + * update persistance file + * + * @return bool\int // This function returns the number of bytes that were written to the file, or FALSE on failure. + */ + public function save() + { + Log::info("SAVE PARAMS\n" . Log::traceToString(debug_backtrace()), Log::LV_DEBUG); + + $arrayData = array(); + foreach ($this->params as $param) { + if ($param->isPersistent()) { + $arrayData[$param->getName()] = $param->toArrayData(); + } + } + $json = SnapJson::jsonEncodePPrint($arrayData); + if (($result = file_put_contents(self::getPersistanceFilePath(), $json, LOCK_EX)) === false) { + Log::info('PRAMS: can\'t save persistence file'); + } + return $result; + } + + /** + * + * @staticvar string $path + * @return string + */ + protected static function getPersistanceFilePath() + { + static $path = null; + + if (is_null($path)) { + $path = DUPX_INIT . '/' . 'dup-params__' . \DUPX_Package::getPackageHash() . '.json'; + } + + return $path; + } + + /** + * html params info for debug params + * + * @return void + */ + public function getParamsHtmlInfo() + { + if (!$this->getValue(self::PARAM_DEBUG_PARAMS)) { + return; + } + ?> +
        +

        CURRENT VALUES

        +
          + params as $param) { ?> +
        • + PARAM getName(); ?> VALUE: getValue())); ?> +
        • + +
        +

        LOAD SEQUENCE

        +
          + paramsHtmlInfo as $info) { ?> +
        • + +
        • + +
        +

        ARCHIVE PARAM DATA

        +
        +
        + params as $param) { + if (method_exists($param, 'getFormStatus')) { + $line = 'PARAM FORM ' . $param->getName() . ' VALUE: ' . Log::v2str($param->getValue()) . ' STATUS: ' . $param->getFormStatus(); + } else { + $line = 'PARAM ITEM ' . $param->getName() . ' VALUE: ' . Log::v2str($param->getValue()); + } + + $result[] = $line; + } + + return implode("\n", $result); + } + + /** + * Prevent clone object + * + * @return void + */ + private function __clone() + { + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Models/ImportUser.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Models/ImportUser.php new file mode 100644 index 0000000..0f8e851 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Models/ImportUser.php @@ -0,0 +1,183 @@ +id = (int) $id; + $this->login = $login; + $this->mail = $mail; + $this->oldId = (int) $oldId; + $this->oldLogin = $oldLogin; + $this->isAdded = $isAdded; + + if ($this->id == $this->oldId) { + $this->oldId = 0; + } + if ($this->login == $this->oldLogin) { + $this->oldLogin = ''; + } + } + + /** + * Return CSV report columns title + * + * @return string[] + */ + public static function getArrayReportTitles() + { + return array( + 'e-mail', + 'original login', + 'new login', + 'original id', + 'new id' + ); + } + + /** + * Return array for CSV report + * + * @return array + */ + public function getArrayReport() + { + $result = array($this->mail); + if (strlen($this->oldLogin) == 0) { + $result[] = $this->login; + $result[] = ''; + } else { + $result[] = $this->oldLogin; + $result[] = $this->login; + } + + if ($this->oldId == 0) { + $result[] = $this->id; + $result[] = ''; + } else { + $result[] = $this->oldId; + $result[] = $this->id; + } + + return $result; + } + + /** + * Get the value of id + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Get the value of login + * + * @return string + */ + public function getLogin() + { + return $this->login; + } + + /** + * Get the value of mail + * + * @return string + */ + public function getMail() + { + return $this->mail; + } + + /** + * Get the value of oldId + * + * @return int + */ + public function getOldId() + { + return ($this->oldId == 0 ? $this->id : $this->oldId); + } + + /** + * Set the value of oldId + * + * @param int $oldId old mapped id + * + * @return void + */ + public function setOldId($oldId) + { + $this->oldId = (int) ($this->id == $oldId ? 0 : $oldId); + } + + /** + * Get the value of oldLogin + * + * @return string + */ + public function getOldLogin() + { + return (strlen($this->oldLogin) == 0 ? $this->login : $this->oldLogin); + } + + /** + * Set the value of oldLogin + * + * @param string $oldLogin old login + * + * @return void + */ + public function setOldLogin($oldLogin) + { + $this->oldLogin = ($this->login == $oldLogin ? '' : $oldLogin); + } + + /** + * True if current user have changed values (login or id) + * + * @return boolean + */ + public function isChanged() + { + return ($this->oldId > 0 || strlen($this->oldLogin) > 0); + } + + /** + * True if current user is added + * + * @return bool + */ + public function isAdded() + { + return $this->isAdded; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Models/ScanInfo.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Models/ScanInfo.php new file mode 100644 index 0000000..2c26239 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Models/ScanInfo.php @@ -0,0 +1,75 @@ +data = json_decode($contents, true)) === null) { + throw new Exception("Can\'t decode archive json"); + } + } + + /** + * Get uncompressed size, -1 unknown + * + * @return int + */ + public function getUSize() + { + return isset($this->data['ARC']['Usize']) ? $this->data['ARC']['Usize'] : -1; + } + + /** + * Return true if package has filtered core folders + * + * @return bool + */ + public function hasFilteredCoreFolders() + { + return $this->data['ARC']['Status']['HasFilteredCoreFolders']; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Autoloader.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Autoloader.php new file mode 100644 index 0000000..58e21e8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Autoloader.php @@ -0,0 +1,126 @@ + $mappedPath) { + if (strpos($className, $namespace) !== 0) { + continue; + } + + $filepath = $mappedPath . str_replace('\\', '/', substr($className, strlen($namespace))) . '.php'; + if (file_exists($filepath)) { + include_once($filepath); + return true; + } + } + } else { + if (file_exists($filepath)) { + include_once($filepath); + return true; + } + } + + return false; + } + + /** + * + * @param string $class class name + * + * @return boolean|string + */ + protected static function getAddonFile($class) + { + $matches = null; + if (preg_match('/^\\\\?Duplicator\\\\Installer\\\\Addons\\\\(.+?)\\\\(.+)$/', $class, $matches) !== 1) { + return false; + } + + $addonName = $matches[1]; + $subClass = $matches[2]; + $basePath = DUPX_INIT . '/addons/' . strtolower($addonName) . '/'; + + if (self::endsWith($class, $addonName) === false) { + $basePath .= 'src/'; + } + + return $basePath . str_replace('\\', '/', $subClass) . '.php'; + } + + /** + * + * @staticvar [string] $mapping + * @return [string] + */ + protected static function getNamespacesMapping() + { + // the order is important, it is necessary to insert the longest namespaces first + return array( + self::ROOT_ADDON_INSTALLER_NAMESPACE => DUPX_INIT . '/addons/', + self::ROOT_INSTALLER_NAMESPACE => DUPX_INIT . '/src/', + self::ROOT_LIBS_NAMESPACE => DUPX_INIT . '/libs/' + ); + } + + /** + * Returns true if the $haystack string end with the $needle, only for internal use + * + * @param string $haystack The full string to search in + * @param string $needle The string to for + * + * @return bool Returns true if the $haystack string starts with the $needle + */ + protected static function endsWith($haystack, $needle) + { + $length = strlen($needle); + if ($length == 0) { + return true; + } + + return (substr($haystack, -$length) === $needle); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/InstallerLinkManager.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/InstallerLinkManager.php new file mode 100644 index 0000000..12aefb5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/InstallerLinkManager.php @@ -0,0 +1,119 @@ + 'WordPress', + 'utm_campaign' => 'liteplugin' + ); + + if ($medium !== '') { + $utmData['utm_medium'] = $medium; + } + + if ($content !== '') { + $utmData['utm_content'] = $content; + } + + if (is_array($paths)) { + $paths = implode('/', $paths); + } + $paths = trim($paths, '/') . '/'; + + return self::DUPLICATOR_URL . $paths . '?' . http_build_query($utmData); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/InstallerUpsell.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/InstallerUpsell.php new file mode 100644 index 0000000..18d4ea5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/InstallerUpsell.php @@ -0,0 +1,98 @@ + + + getValue(PrmMng::PARAM_LOGGING); + } + + /** + * Used to write debug info to the text log file + * + * @param string $msg Any text data + * @param int $logging Log level + * @param bool $flush if true flush file log + * + * @return void + */ + public static function info($msg, $logging = self::LV_DEFAULT, $flush = false) + { + if ($logging > self::$logLevel) { + return; + } + + $preLog = ''; + if (self::$indentation) { + $preLog .= str_repeat("\t", self::$indentation); + } + if (self::$logLevel >= self::LV_DETAILED) { + $preLog .= sprintf('[DELTA:%10.5f] ', microtime(true) - self::$microtimeStart); + } + if (is_callable(self::$postprocessCallback)) { + $msg = call_user_func(self::$postprocessCallback, $msg); + } + + @fwrite(self::getFileHandle(), $preLog . $msg . "\n", self::MAX_LENGTH_FWRITE); + + if ($flush) { + self::flush(); + } + } + + /** + * + * @return bool

        Returns true on success or false on failure.

        + */ + public static function clearLog() + { + self::close(); + if (file_exists(self::getLogFilePath())) { + return unlink(self::getLogFilePath()); + } else { + return true; + } + } + + /** + * + * @return string + */ + protected static function getLogFileName() + { + return 'dup-installer-log__' . \DUPX_Security::getInstance()->getSecondaryPackageHash() . '.txt'; + } + + /** + * + * @return string + */ + public static function getLogFilePath() + { + return DUPX_INIT . '/' . self::getLogFileName(); + } + + /** + * + * @return string + */ + public static function getLogFileUrl() + { + return DUPX_INIT_URL . '/' . self::getLogFileName() . '?now=' . $GLOBALS['NOW_TIME']; + } + + /** + * Get trace string + * + * @param array $callers result of debug_backtrace + * @param int $fromLevel level to start + * + * @return string + */ + public static function traceToString($callers, $fromLevel = 0) + { + $result = ''; + for ($i = $fromLevel; $i < count($callers); $i++) { + $trace = $callers[$i]; + if (!empty($trace['class'])) { + $result .= str_pad('TRACE[' . $i . '] CLASS___: ' . $trace['class'] . $trace['type'] . $trace['function'], 45, ' '); + } else { + $result .= str_pad('TRACE[' . $i . '] FUNCTION: ' . $trace['function'], 45, ' '); + } + if (isset($trace['file'])) { + $result .= ' FILE: ' . $trace['file'] . '[' . $trace['line'] . ']'; + } else { + $result .= ' NO FILE'; + } + $result .= "\n"; + } + return $result; + } + + /** + * Set post process callback + * + * @param callable $callback callback function + * + * @return void + */ + public static function setPostProcessCallback($callback) + { + self::$postprocessCallback = is_callable($callback) ? $callback : null; + } + + /** + * Set after fatal error callback + * + * @param callable $callback callback function + * + * @return void + */ + public static function setAfterFatalErrorCallback($callback) + { + self::$afterFatalErrorCallback = is_callable($callback) ? $callback : null; + } + + /** + * Reset time counter + * + * @param int $logging log level + * @param boolean $fileInfo Log file info (file, line) + * + * @return void + */ + public static function resetTime($logging = self::LV_DEFAULT, $fileInfo = true) + { + self::$microtimeStart = microtime(true); + if ($logging > self::$logLevel) { + return; + } + $callers = debug_backtrace(); + $file = $callers[0]['file']; + $line = $callers[0]['line']; + Log::info('LOG-TIME' . ($fileInfo ? '[' . $file . ':' . $line . ']' : '') . ' RESET TIME', $logging); + } + + /** + * Log time delta from last resetTime call + * + * @param string $msg message + * @param int $logging log level + * @param bool $fileInfo if strue write file info (file, line) + * + * @return void + */ + public static function logTime($msg = '', $logging = self::LV_DEFAULT, $fileInfo = true) + { + if ($logging > self::$logLevel) { + return; + } + $callers = debug_backtrace(); + $file = $callers[0]['file']; + $line = $callers[0]['line']; + + if ($fileInfo) { + Log::info( + sprintf('LOG-TIME[%s:%s][DELTA:%10.5f] ', $file, $line, microtime(true) - self::$microtimeStart) . (empty($msg) ? '' : ' MESSAGE:' . $msg), + $logging + ); + } else { + Log::info(sprintf('LOG-TIME[DELTA:%10.5f] ', microtime(true) - self::$microtimeStart) . (empty($msg) ? '' : ' MESSAGE:' . $msg), $logging); + } + } + + /** + * Increment indentation + * + * @return void + */ + public static function incIndent() + { + self::$indentation++; + } + + /** + * Decrease indentation + * + * @return void + */ + public static function decIndent() + { + if (self::$indentation > 0) { + self::$indentation--; + } + } + + /** + * Reset indentation + * + * @return void + */ + public static function resetIndent() + { + self::$indentation = 0; + } + + /** + * Return true if log level is >= of loggin level + * + * @param int $logging log level + * + * @return boolean + */ + public static function isLevel($logging) + { + return $logging <= self::$logLevel; + } + + /** + * Log passed object + * + * @param string $msg log message + * @param mixed $object object to log + * @param int $logging log level + * + * @return void + */ + public static function infoObject($msg, &$object, $logging = self::LV_DEFAULT) + { + $msg = $msg . "\n" . print_r($object, true); + self::info($msg, $logging); + } + + /** + * Flush log file + * + * @return void + */ + public static function flush() + { + if (is_resource(self::$logHandle)) { + fflush(self::$logHandle); + } + } + + /** + * Close log file + * + * @return void + */ + public static function close() + { + if (is_null(self::$logHandle)) { + return true; + } + + if (is_resource(self::$logHandle)) { + fclose(self::$logHandle); + } + self::$logHandle = null; + return true; + } + + /** + * Get log file stream + * + * @return resource + */ + public static function getFileHandle() + { + if (is_resource(self::$logHandle)) { + return self::$logHandle; + } + + if (!is_writable(dirname(self::getLogFilePath()))) { + throw new \Exception('Can\'t write in dup-installer folder, please check the dup-installer permission folder'); + } + + if (file_exists(self::getLogFilePath())) { + SnapIO::chmod(self::getLogFilePath(), 'u+rw'); + } + + if ((self::$logHandle = fopen(self::getLogFilePath(), "a+")) === false) { + self::$logHandle = null; + throw new \Exception('Can\'t open the log file, please check the dup-installer permission folder'); + } + + SnapIO::chmod(self::getLogFilePath(), 'u+rw'); + + return self::$logHandle; + } + + /** + * Log error and die or thore exception if self::$thowExceptionOnError is true + * + * @param string $errorMessage error message + * + * @return void + */ + public static function error($errorMessage) + { + $breaks = array("
        ", "
        ", "
        "); + $spaces = array(" "); + $log_msg = str_ireplace($breaks, "\r\n", $errorMessage); + $log_msg = str_ireplace($spaces, " ", $log_msg); + $log_msg = strip_tags($log_msg); + + self::info("\nINSTALLER ERROR:\n{$log_msg}\n"); + + if (is_callable(self::$afterFatalErrorCallback)) { + call_user_func(self::$afterFatalErrorCallback); + } + + if (self::$thowExceptionOnError) { + throw new \Exception($errorMessage); + } else { + self::close(); + die("

        INSTALL ERROR!
        {$errorMessage}
        "); + } + } + + /** + * Get log exception string + * + * @param Exception $e exception object + * @param string $title log message + * + * @return string + */ + public static function getLogException($e, $title = 'EXCEPTION ERROR: ') + { + return $title . ' ' . $e->getMessage() . "\n" . + "\tFILE:" . $e->getFile() . '[' . $e->getLIne() . "]\n" . + "\tTRACE:\n" . $e->getTraceAsString(); + } + + /** + * Log exception + * + * @param Exception $e exception object + * @param int $logging log level + * @param string $title log message + * + * @return void + */ + public static function logException($e, $logging = self::LV_DEFAULT, $title = 'EXCEPTION ERROR: ') + { + if ($logging <= self::$logLevel) { + Log::info("\n" . self::getLogException($e, $title) . "\n"); + } + } + + /** + * If set true error function thorw exception instead die + * + * @param boolean $set enable/disable thorw exception + * + * @return void + */ + public static function setThrowExceptionOnError($set) + { + self::$thowExceptionOnError = (bool) $set; + } + + /** + * Get string from generic value + * + * @param mixed $var value + * @param bool $checkCallable if true check if var is callable and display it + * + * @return string + */ + public static function v2str($var, $checkCallable = false) + { + if ($checkCallable && is_callable($var)) { + return '(callable) ' . print_r($var, true); + } + switch (gettype($var)) { + case "boolean": + return $var ? 'true' : 'false'; + case "integer": + case "double": + return (string) $var; + case "string": + return '"' . $var . '"'; + case "array": + case "object": + return print_r($var, true); + case "resource": + case "resource (closed)": + case "NULL": + case "unknown type": + default: + return gettype($var); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Log/LogHandler.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Log/LogHandler.php new file mode 100644 index 0000000..c4b454c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Log/LogHandler.php @@ -0,0 +1,258 @@ + 'timeout' + ); + + /** + * + * @var int + */ + private static $handlerMode = self::MODE_LOG; + + /** + * + * @var bool // print code reference and errno at end of php error line [CODE:10|FILE:test.php|LINE:100] + */ + private static $codeReference = true; + + /** + * + * @var bool // print prefix in php error line [PHP ERR][WARN] MSG: ..... + */ + private static $errPrefix = true; + + /** + * + * @var string // php errors in MODE_VAR + */ + private static $varModeLog = ''; + + /** + * Error handler + * + * @param integer $errno Error level + * @param string $errstr Error message + * @param string $errfile Error file + * @param integer $errline Error line + * + * @return void + */ + public static function error($errno, $errstr, $errfile, $errline) + { + switch (self::$handlerMode) { + case self::MODE_OFF: + if ($errno == E_ERROR) { + $log_message = self::getMessage($errno, $errstr, $errfile, $errline); + Log::error($log_message); + } + break; + case self::MODE_VAR: + self::$varModeLog .= self::getMessage($errno, $errstr, $errfile, $errline) . "\n"; + break; + case self::MODE_LOG: + default: + switch ($errno) { + case E_ERROR: + $log_message = self::getMessage($errno, $errstr, $errfile, $errline); + Log::error($log_message); + break; + case E_NOTICE: + case E_WARNING: + default: + $log_message = self::getMessage($errno, $errstr, $errfile, $errline); + Log::info($log_message); + break; + } + } + } + + /** + * Get error message from erro data + * + * @param int $errno error code + * @param string $errstr error message + * @param string $errfile file + * @param int $errline line + * + * @return string + */ + private static function getMessage($errno, $errstr, $errfile, $errline) + { + $result = ''; + + if (self::$errPrefix) { + $result = '[PHP ERR]' . '[' . self::errnoToString($errno) . '] MSG:'; + } + + $result .= $errstr; + + if (self::$codeReference) { + $result .= ' [CODE:' . $errno . '|FILE:' . $errfile . '|LINE:' . $errline . ']'; + if (Log::isLevel(Log::LV_DEBUG)) { + Log::info(Log::traceToString(debug_backtrace(), 1)); + } + } + + return $result; + } + + /** + * Errno code to string + * + * @param int $errno error code + * + * @return string + */ + public static function errnoToString($errno) + { + switch ($errno) { + case E_PARSE: + return 'E_PARSE'; + case E_ERROR: + return 'E_ERROR'; + case E_CORE_ERROR: + return 'E_CORE_ERROR'; + case E_COMPILE_ERROR: + return 'E_COMPILE_ERROR'; + case E_USER_ERROR: + return 'E_USER_ERROR'; + case E_WARNING: + return 'E_WARNING'; + case E_USER_WARNING: + return 'E_USER_WARNING'; + case E_COMPILE_WARNING: + return 'E_COMPILE_WARNING'; + case E_NOTICE: + return 'E_NOTICE'; + case E_USER_NOTICE: + return 'E_USER_NOTICE'; + case self::ERRNO_EXCEPTION: + return 'EXCEPTION'; + default: + break; + } + if (defined('E_RECOVERABLE_ERROR') && $errno === E_RECOVERABLE_ERROR) { + return 'E_RECOVERABLE_ERROR'; + } + if (defined('E_DEPRECATED') && $errno === E_DEPRECATED) { + return 'E_DEPRECATED'; + } + if (defined('E_USER_DEPRECATED') && $errno === E_USER_DEPRECATED) { + return 'E_USER_DEPRECATED'; + } + return 'E_UNKNOWN CODE: ' . $errno; + } + + /** + * if setMode is called without params set as default + * + * @param int $mode log mode + * @param bool $errPrefix print prefix in php error line [PHP ERR][WARN] MSG: ..... + * @param bool $codeReference print code reference and errno at end of php error line [CODE:10|FILE:test.php|LINE:100] + * + * @return void + */ + public static function setMode($mode = self::MODE_LOG, $errPrefix = true, $codeReference = true) + { + switch ($mode) { + case self::MODE_OFF: + case self::MODE_VAR: + self::$handlerMode = $mode; + break; + case self::MODE_LOG: + default: + self::$handlerMode = self::MODE_LOG; + } + + self::$varModeLog = ''; + self::$errPrefix = $errPrefix; + self::$codeReference = $codeReference; + } + + /** + * + * @return string // return var log string in MODE_VAR + */ + public static function getVarLog() + { + return self::$varModeLog; + } + + /** + * + * @return string // return var log string in MODE_VAR and clean var + */ + public static function getVarLogClean() + { + $result = self::$varModeLog; + self::$varModeLog = ''; + return $result; + } + + /** + * Set shutdown print string + * + * @param string $status status type + * @param string $str string to print if is shouddown status + * + * @return void + */ + public static function setShutdownReturn($status, $str) + { + self::$shutdownReturns[$status] = $str; + } + + /** + * Shutdown handler + * + * @return void + */ + public static function shutdown() + { + if (($error = error_get_last())) { + if (preg_match('/^Maximum execution time (?:.+) exceeded$/i', $error['message'])) { + echo self::$shutdownReturns[self::SHUTDOWN_TIMEOUT]; + } + self::error($error['type'], $error['message'], $error['file'], $error['line']); + } + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/MessageCustomizer.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/MessageCustomizer.php new file mode 100644 index 0000000..f1d8739 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/MessageCustomizer.php @@ -0,0 +1,201 @@ +conditionSatisfied($longMessage)) { + $shortMessage = $item->apply($shortMessage, self::CONTEXT_SHORT_MESSAGE); + $longMessage = $item->apply($longMessage, self::CONTEXT_LONG_MESSAGE); + $noticeId = $item->apply($noticeId, self::CONTEXT_NOTICE_ID); + return true; + } + } + + return false; + } + + /** + * Get customization to apply at error messages + * + * @return MessageCustomizerItem[] customizations list + * @throws \Exception + */ + protected static function getCustomizationItems() + { + $items = array(); + $items[] = new MessageCustomizerItem( + function ($string) { + if (MessageCustomizer::getArchiveConfigData() == false) { + return false; + } + return preg_match("/undefined.*create_function/", $string) && + version_compare(phpversion(), "8") >= 0 && + version_compare(MessageCustomizer::getArchiveConfigData()->version_php, "8") < 0; + }, + function ($string, $context) { + if (MessageCustomizer::getArchiveConfigData() == false) { + return $string; + } + $phpVersionNew = MessageCustomizer::getTwoLevelVersion(phpversion()); + $phpVersionOld = MessageCustomizer::getTwoLevelVersion(MessageCustomizer::getArchiveConfigData()->version_php); + $longMsgPrefix = "There is code in this site that is not compatible with PHP " . $phpVersionNew . ". " . + "To make the install work you will either have to\ninstall on PHP " . + $phpVersionOld . " or "; + + switch ($context) { + case MessageCustomizer::CONTEXT_SHORT_MESSAGE: + return "Source site or plugins are incompatible with PHP " . $phpVersionNew; + case MessageCustomizer::CONTEXT_LONG_MESSAGE: + if (($plugin = MessageCustomizer::getProblematicPluginFromError($string)) !== false) { + return $longMsgPrefix . "disable the plugin '{$plugin->name}' (slug: $plugin->slug) using a " . + "file manager of your choice.\nSee full error message below: \n\n" . $string; + } elseif (($theme = MessageCustomizer::getProblematicThemeFromError($string)) !== false) { + return $longMsgPrefix . "disable the theme '{$theme->themeName}' (slug: $theme->slug) using a " . + "file manager of your choice.\nSee full error message below: \n\n" . $string; + } else { + return $longMsgPrefix . "manually modify the affected files mentioned in the error trace below: \n\n" . + $string; + } + case MessageCustomizer::CONTEXT_NOTICE_ID: + return $string . '_php8'; + } + } + ); + + return $items; + } + + /** + * Return the plugin that is causing the error message if present + * + * @param string $longMessage the long error message containing the error trace + * + * @return false|object object containing plugin info or false on failure + */ + protected static function getProblematicPluginFromError($longMessage) + { + if (($archiveConfig = self::getArchiveConfigData()) === false) { + return false; + } + $oldMain = $archiveConfig->wpInfo->targetRoot; + $oldMuPlugins = $archiveConfig->wpInfo->configs->realValues->originalPaths->muplugins; + $oldPlugins = $archiveConfig->wpInfo->configs->realValues->originalPaths->plugins; + $relativeMuPlugins = str_replace($oldMain, "", $oldMuPlugins); + $relativePlugins = str_replace($oldMain, "", $oldPlugins); + $regex = "/(?:" . preg_quote($relativePlugins, "/") . "\/|" . preg_quote($relativeMuPlugins, "/") . "\/)(.*?)(\/|\.php).*$/m"; + if (!preg_match($regex, $longMessage, $matches)) { + return false; + } + + //matches the first part of the slug related to the plugin directory + $slug = $matches[1]; + foreach ($archiveConfig->wpInfo->plugins as $plugin) { + if (strpos($plugin->slug, $slug) === 0) { + return $plugin; + } + } + + return false; + } + + /** + * Returns the theme that is causing the error message if present + * + * @param string $longMessage the long error message containing the error trace + * + * @return false|object object containing theme info or false + */ + protected static function getProblematicThemeFromError($longMessage) + { + $archiveConfig = self::getArchiveConfigData(); + $oldMain = $archiveConfig->wpInfo->targetRoot; + $oldThemes = $archiveConfig->wpInfo->configs->realValues->originalPaths->themes; + $relativeThemes = str_replace($oldMain, "", $oldThemes); + + file_put_contents( + DUPX_INIT . "/my_log.txt", + "OLD THEMES: {$oldThemes} \n" . + "Relative themes: {$relativeThemes} \n" . + "regex: " . "/(" . preg_quote($relativeThemes, "/") . "\/)(.*?)(\/|\.php).*$/m" + ); + + if (!preg_match("/(?:" . preg_quote($relativeThemes, "/") . "\/)(.*?)(?:\/|\.php).*$/m", $longMessage, $matches)) { + return false; + } + + $slug = $matches[1]; + foreach ($archiveConfig->wpInfo->themes as $theme) { + if ($theme->slug == $slug) { + return $theme; + } + } + + return false; + } + + /** + * Get package config data + * + * @return false|object package config data or false on failure + */ + protected static function getArchiveConfigData() + { + static $archiveConfig = null; + if (is_null($archiveConfig)) { + if ( + ($path = glob(DUPX_INIT . "/dup-archive__*.txt")) === false || + count($path) !== 1 + ) { + return $archiveConfig = false; + } + + if (($json = file_get_contents($path[0])) === false) { + return $archiveConfig = false; + } + + $archiveConfig = json_decode($json); + if (!is_object($archiveConfig)) { + $archiveConfig = false; + } + } + return $archiveConfig; + } + + /** + * @param string $version a version number + * + * @return string returns only the first 2 levels of the version numbers + */ + private static function getTwoLevelVersion($version) + { + $arr = explode(".", $version); + return $arr[0] . "." . $arr[1]; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/MessageCustomizerItem.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/MessageCustomizerItem.php new file mode 100644 index 0000000..9640aad --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/MessageCustomizerItem.php @@ -0,0 +1,47 @@ +checkCallback = $checkCallback; + + if (!is_callable($applyCallback)) { + throw new \Exception("customization callback must be callable"); + } + $this->applyCallback = $applyCallback; + } + + /** + * @param mixed $input necessary input to check condition + * + * @return bool + */ + public function conditionSatisfied($input) + { + return (is_bool($this->checkCallback) && $this->checkCallback) || call_user_func($this->checkCallback, $input); + } + + /** + * @param string $string string to be customized + * @param mixed $context context about what to apply + * + * @return false|mixed + */ + public function apply($string, $context) + { + return call_user_func($this->applyCallback, $string, $context); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/TestInterface.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/TestInterface.php new file mode 100644 index 0000000..61e91ee --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/TestInterface.php @@ -0,0 +1,16 @@ + self::getErrorCategoryFromErrno($errno), + 'errno' => $errno, + 'errno_str' => self::errnoToString($errno), + 'errstr' => $errstr, + 'errfile' => $errfile, + 'errline' => $errline, + 'trace' => array_map(array(__CLASS__, 'normalizeTraceElement'), $trace) + ); + + self::$errors[] = $newError; + + if (function_exists('error_clear_last')) { + error_clear_last(); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.error_clear_lastFound + } + } + + /** + * @param array $error the error array + * + * @return string human-readable error message with trace + */ + public static function errorToString($error) + { + $result = $error['errno_str'] . ' ' . $error['errstr'] . "\n"; + $result .= "\t" . 'FILE: ' . $error['errfile'] . '[' . $error['errline'] . ']' . "\n"; + $result .= "\t--- TRACE ---\n"; + foreach ($error['trace'] as $trace) { + $result .= "\t"; + if (!empty($trace['class'])) { + $result .= str_pad('CLASS___: ' . $trace['class'] . $trace['type'] . $trace['function'], 40, ' '); + } else { + $result .= str_pad('FUNCTION: ' . $trace['function'], 40, ' '); + } + $result .= 'FILE: ' . $trace['file'] . '[' . $trace['line'] . ']' . "\n"; + } + + return $result; + } + + /** + * Error handler + * + * @param integer $errno Error level + * @param string $errstr Error message + * @param string $errfile Error file + * @param integer $errline Error line + * + * @return void + */ + public static function error($errno, $errstr, $errfile, $errline) + { + $trace = debug_backtrace(); + array_shift($trace); + self::adderror($errno, $errstr, $errfile, $errline, $trace); + } + + /** + * Exception handler + * + * @param Exception|Error $e // Throwable in php 7 + * + * @return void + */ + public static function exception($e) + { + self::adderror(self::ERRNO_EXCEPTION, $e->getMessage(), $e->getFile(), $e->getLine(), $e->getTrace()); + } + + /** + * Shutdown handler + * + * @return void + */ + public static function shutdown() + { + self::obCleanAll(); + + if (($error = error_get_last())) { + self::error($error['type'], $error['message'], $error['file'], $error['line']); + } + ob_end_clean(); + + if (is_callable(self::$shutdownCallback)) { + call_user_func(self::$shutdownCallback, self::$errors); + } else { + echo json_encode(self::$errors); + } + + // prevent other shutdown functions + exit(); + } + + /** + * Close all buffers and return content + * + * @param bool $getContent If true it returns buffer content, otherwise it is discarded + * + * @return string + */ + protected static function obCleanAll($getContent = true) + { + $result = ''; + for ($i = 0; $i < ob_get_level(); $i++) { + if ($getContent) { + $result .= ob_get_contents(); + } + ob_clean(); + } + return $result; + } + + /** + * @param array $elem normalize error element + * + * @return array + */ + public static function normalizeTraceElement($elem) + { + if (!is_array($elem)) { + $elem = array(); + } + + unset($elem['args']); + unset($elem['object']); + + return array_merge(array( + 'file' => '', + 'line' => -1, + 'function' => '', + 'class' => '', + 'type' => ''), $elem); + } + + /** + * + * @param int $errno error number + * + * @return string + */ + public static function getErrorCategoryFromErrno($errno) + { + switch ($errno) { + case E_PARSE: + case E_ERROR: + case E_CORE_ERROR: + case E_COMPILE_ERROR: + case E_USER_ERROR: + case self::ERRNO_EXCEPTION: + return self::ERR_TYPE_ERROR; + case E_WARNING: + case E_USER_WARNING: + case E_COMPILE_WARNING: + return self::ERR_TYPE_WARNING; + case E_NOTICE: + case E_USER_NOTICE: + return self::ERR_TYPE_NOTICE; + default: + break; + } + if (defined('E_RECOVERABLE_ERROR') && $errno === E_RECOVERABLE_ERROR) { + return self::ERR_TYPE_WARNING; + } + if (defined('E_DEPRECATED') && $errno === E_DEPRECATED) { + return self::ERR_TYPE_DEPRECATED; + } + if (defined('E_USER_DEPRECATED') && $errno === E_USER_DEPRECATED) { + return self::ERR_TYPE_DEPRECATED; + } + return self::ERR_TYPE_WARNING; + } + + /** + * + * @param int $errno error number + * + * @return string + */ + public static function errnoToString($errno) + { + switch ($errno) { + case E_PARSE: + return 'E_PARSE'; + case E_ERROR: + return 'E_ERROR'; + case E_CORE_ERROR: + return 'E_CORE_ERROR'; + case E_COMPILE_ERROR: + return 'E_COMPILE_ERROR'; + case E_USER_ERROR: + return 'E_USER_ERROR'; + case E_WARNING: + return 'E_WARNING'; + case E_USER_WARNING: + return 'E_USER_WARNING'; + case E_COMPILE_WARNING: + return 'E_COMPILE_WARNING'; + case E_NOTICE: + return 'E_NOTICE'; + case E_USER_NOTICE: + return 'E_USER_NOTICE'; + case self::ERRNO_EXCEPTION: + return 'EXCEPTION'; + default: + break; + } + if (defined('E_RECOVERABLE_ERROR') && $errno === E_RECOVERABLE_ERROR) { + return 'E_RECOVERABLE_ERROR'; + } + if (defined('E_DEPRECATED') && $errno === E_DEPRECATED) { + return 'E_DEPRECATED'; + } + if (defined('E_USER_DEPRECATED') && $errno === E_USER_DEPRECATED) { + return 'E_USER_DEPRECATED'; + } + return 'E_UNKNOWN CODE: ' . $errno; + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/WP/TestsExecuter.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/WP/TestsExecuter.php new file mode 100644 index 0000000..0f0d12e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/WP/TestsExecuter.php @@ -0,0 +1,149 @@ +addFinalReportNotice(array( + 'shortMsg' => 'Can\'t create final text script file', + 'longMsg' => 'Can\'t create file ' . $scriptFilePath, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT, + 'level' => DUPX_NOTICE_ITEM::HARD_WARNING, + 'sections' => array('general'), + )); + + return false; + } + + return true; + } + + /** + * @return bool true on success + * @throws \Exception + */ + public static function afterTestClean() + { + $nManager = DUPX_NOTICE_MANAGER::getInstance(); + $scriptFilePath = self::getScriptTestPath(); + Log::info('DELETE FILE AFTER TEST: ' . $scriptFilePath, Log::LV_DETAILED); + if (file_exists($scriptFilePath)) { + if (unlink($scriptFilePath) == false) { + $nManager->addFinalReportNotice(array( + 'shortMsg' => 'Can\'t deleta final text script file', + 'longMsg' => 'Can\'t delete file ' . $scriptFilePath . '. Remove it manually', + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_DEFAULT, + 'level' => DUPX_NOTICE_ITEM::HARD_WARNING, + 'sections' => array('general'), + )); + } + } + + return true; + } + + /** + * @return string url of WP front-end + * @throws \Exception + */ + public static function getFrontendUrl() + { + $indexPath = PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_NEW) . '/index.php'; + $data = array( + self::SCRIPT_NAME_HTTP_PARAM => $indexPath + ); + + return self::getScriptTestUrl() . '?' . http_build_query($data); + } + + /** + * @return string url of WP back-end + * @throws \Exception + */ + public static function getBackendUrl() + { + $indexPath = PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_WP_CORE_NEW) . '/wp-login.php'; + $data = array( + self::SCRIPT_NAME_HTTP_PARAM => $indexPath + ); + + return self::getScriptTestUrl() . '?' . http_build_query($data); + } + + /** + * @return string test script name + */ + protected static function getScriptTestName() + { + return 'wp_test_script_' . DUPX_Security::getInstance()->getSecondaryPackageHash() . '.php'; + } + + /** + * @return string test script path + * @throws \Exception + */ + public static function getScriptTestPath() + { + // use wp-content path and not root path + return PrmMng::getInstance()->getValue(PrmMng::PARAM_PATH_CONTENT_NEW) . '/' . self::getScriptTestName(); + } + + /** + * @return string test script url + * @throws \Exception + */ + public static function getScriptTestUrl() + { + // use wp-content path and not root path + return PrmMng::getInstance()->getValue(PrmMng::PARAM_URL_CONTENT_NEW) . '/' . self::getScriptTestName(); + } + + /** + * @return string contents to be added to the test script file + */ + public static function getExecFileContent() + { + $result = file_get_contents(__DIR__ . '/tests_template.php'); + $result = preg_replace('/^.*\[REMOVE LINE BY SCRIPT].*\n/m', '', $result); // remove first line with die + return str_replace( + array( + '$_$_NOTICES_FILE_PATH_$_$', + '$_$_DUPX_INIT_$_$' + ), + array( + $GLOBALS["NOTICES_FILE_PATH"], + DUPX_INIT + ), + $result + ); + } +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/WP/tests_template.php b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/WP/tests_template.php new file mode 100644 index 0000000..88d69ba --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/src/Utils/Tests/WP/tests_template.php @@ -0,0 +1,121 @@ + $shortMessage, + 'level' => $errorLevel, + 'longMsgMode' => DUPX_NOTICE_ITEM::MSG_MODE_PRE, + 'longMsg' => $longMessage, + 'sections' => 'general' + ); + if ($errorLevel == DUPX_NOTICE_ITEM::FATAL) { + $nManager->addBothNextAndFinalReportNotice($data, DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $noticeId); + } else { + $nManager->addFinalReportNotice($data, DUPX_NOTICE_MANAGER::ADD_UNIQUE_APPEND, $noticeId); + } + } + + if ($nManager->saveNotices()) { + echo json_encode(true); + } else { + echo json_encode(false); + } +}); + +$_SERVER['REQUEST_URI'] = '/'; +if (file_exists($GLOBALS["TEST_SCRIPT"])) { + require_once($GLOBALS["TEST_SCRIPT"]); +} else { + throw new Exception('test script file ' . $GLOBALS["TEST_SCRIPT"] . ' doesn\'t exist'); +} diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/.htaccess b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/.htaccess new file mode 100644 index 0000000..a58990b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/.htaccess @@ -0,0 +1,9 @@ + + Order Deny,Allow + Deny from all + + + + Order Allow,Deny + Allow from all + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/actions/switch-template.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/actions/switch-template.php new file mode 100644 index 0000000..1b6c8da --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/actions/switch-template.php @@ -0,0 +1,25 @@ + +
        + + + + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/continue-block.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/continue-block.php new file mode 100644 index 0000000..3f178ed --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/continue-block.php @@ -0,0 +1,31 @@ + +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/options.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/options.php new file mode 100644 index 0000000..6381767 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step1/options.php @@ -0,0 +1,8 @@ + 'Step 1 of 2: Deployment ' . + '
        This step will extract the archive file, install & update the database.
        ', + 'showInstallerMode' => true, + 'showSwitchView' => true, + 'showInstallerLog' => false +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step4/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step4/step-title.php new file mode 100644 index 0000000..90bd42f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/pages-parts/step4/step-title.php @@ -0,0 +1,12 @@ + 'Step 2 of 2: Test Site' +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/scripts/step1-deploy.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/scripts/step1-deploy.php new file mode 100644 index 0000000..36c030b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/base/scripts/step1-deploy.php @@ -0,0 +1,22 @@ + 'ctrl-step4', + DUPX_Security::CTRL_TOKEN => DUPX_CSRF::generate('ctrl-step4') +); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-boot-error.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-boot-error.php new file mode 100644 index 0000000..b5fb656 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-boot-error.php @@ -0,0 +1,23 @@ + + + + + +
        +

        DUPLICATOR: ISSUE

        + Problem on duplicator init.
        + Message: +
        +
        + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-exception.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-exception.php new file mode 100644 index 0000000..92b611c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-exception.php @@ -0,0 +1,32 @@ + 'exception', + 'bodyId' => 'page-exception', + 'bodyClasses' => $bodyClasses +)); +?> +
        + 'Exception error' + )); + ?> +
        + $exception + )); + ?> +
        +
        + + 'help', + 'bodyId' => 'page-help', + 'bodyClasses' => $bodyClasses +)); +?> +
        +
        + +
        +
        + 'secure', + 'bodyId' => 'page-secure', + 'bodyClasses' => $bodyClasses, + 'skipTopMessages' => true +)); +?> +
        + 'Installer Security' + )); + ?> +
        + +
        +
        + + + + + +
        +

        DUPLICATOR: SECURITY CHECK

        + An invalid request was made.
        + Message:
        +
        + In order to protect this request from unauthorized access please restart this install process.
        + Reopen your browser and browse to the http(s)://yoursite.com/[hash]_installer.php file again. +
        + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-step1.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-step1.php new file mode 100644 index 0000000..85d0346 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/page-step1.php @@ -0,0 +1,30 @@ + 'step1', + 'bodyId' => 'page-step1', + 'bodyClasses' => $bodyClasses +)); +?> +
        + +
        + +
        + DUPX_Validation_manager::validateOnLoad() + )); + ?> +
        + 'step2', + 'bodyId' => 'page-step2', + 'bodyClasses' => $bodyClasses +)); +?> +
        + +
        + +
        + +
        + 'step3', + 'bodyId' => 'page-step3', + 'bodyClasses' => $bodyClasses +)); +?> +
        + +
        + +
        + +
        + 'step4', + 'bodyId' => 'page-step4', + 'bodyClasses' => $bodyClasses +)); +?> +
        + +
        + +
        + +
        + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/boot-error/header.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/boot-error/header.php new file mode 100644 index 0000000..6cec1a3 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/boot-error/header.php @@ -0,0 +1,23 @@ + + + + + Duplicator - issue + + + + + + + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/exception/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/exception/main.php new file mode 100644 index 0000000..b7c3617 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/exception/main.php @@ -0,0 +1,44 @@ +getValue(PrmMng::PARAM_RECOVERY_LINK); +if (SnapString::isHTML($exception->getMessage())) { + $message = $exception->getMessage(); +} else { + $message = '' . DUPX_U::esc_html($exception->getMessage()) . ''; +} +?> +
        + INSTALL ERROR! +

        + Message:
        + Please see the file for more details. +

        +
        + Trace: +
        getTraceAsString();
        +    ?>
        +
        + + +

        + + Restore Recovery Point + +

        + + +
        + + See online help for more details at duplicator.com +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/css-scripts.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/css-scripts.php new file mode 100644 index 0000000..b95f23c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/css-scripts.php @@ -0,0 +1,47 @@ +version_dup; + +$cssList = array( + 'assets/normalize.css', + 'assets/font-awesome/css/all.min.css', + 'assets/fonts/dots/dots-font.css', + 'assets/js/password-strength/password.css', + 'assets/js/tippy/dup-pro-tippy.css', + 'vendor/select2/css/select2.css' +); + +$jsList = array( + 'assets/inc.libs.js', + 'assets/js/popper/popper.min.js', + 'assets/js/tippy/tippy-bundle.umd.min.js', + 'assets/js/duplicator-tooltip.js', + 'vendor/select2/js/select2.js' +); + +/* CSS */ +foreach ($cssList as $css) { + ?> + + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/css-template-custom.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/css-template-custom.php new file mode 100644 index 0000000..6381767 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/css-template-custom.php @@ -0,0 +1,8 @@ + +
        +
        + +
        +
        + +
        + getHtmlModeHeader(); ?> +
        + +
        + +
        + +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/meta.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/meta.php new file mode 100644 index 0000000..bb28e8c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/meta.php @@ -0,0 +1,22 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/server-details.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/server-details.php new file mode 100644 index 0000000..6dc167c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/head/server-details.php @@ -0,0 +1,50 @@ + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/addtional-help.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/addtional-help.php new file mode 100644 index 0000000..b6579e7 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/addtional-help.php @@ -0,0 +1,13 @@ + +
        + For additional help please visit + + Duplicator Migration and Backup Online Help + +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/main.php new file mode 100644 index 0000000..527dd1b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/main.php @@ -0,0 +1,59 @@ + + +
        +

        + For complete help visit
        + + Duplicator Migration and Backup Online Help +
        + The Pro tag indicates the feature is only available in Duplicator Pro +
        + + $open_section, + ); + dupxTplRender('pages-parts/help/steps/security', $step_pass_data); + dupxTplRender('pages-parts/help/steps/step-1', $step_pass_data); + dupxTplRender('pages-parts/help/steps/step-2', $step_pass_data); + dupxTplRender('pages-parts/help/steps/step-3', $step_pass_data); + dupxTplRender('pages-parts/help/steps/step-4', $step_pass_data); + dupxTplRender('pages-parts/help/addtional-help'); + ?> +
        + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/security.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/security.php new file mode 100644 index 0000000..970ca80 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/security.php @@ -0,0 +1,132 @@ + + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-1.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-1.php new file mode 100644 index 0000000..dbc59d5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-1.php @@ -0,0 +1,24 @@ + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-2.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-2.php new file mode 100644 index 0000000..eea7df5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-2.php @@ -0,0 +1,87 @@ + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-3.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-3.php new file mode 100644 index 0000000..f69653d --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-3.php @@ -0,0 +1,238 @@ + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-4.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-4.php new file mode 100644 index 0000000..0eec491 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step-4.php @@ -0,0 +1,42 @@ + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/advanced-step1-options.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/advanced-step1-options.php new file mode 100644 index 0000000..6da1b97 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/advanced-step1-options.php @@ -0,0 +1,432 @@ + +

        + Options + Advanced mode +

        +The advanced options are only shown when the installer mode is set to "Advanced." This section allows users to change or set advanced options, +configure additional database settings and set other configuration options in the wp-config.php file. +

        + + +

        + + Advanced Tab +

        +These are the advanced options for advanced users. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        OptionDetails
        + Processing +
        Extraction
        Mode
        + Manual Archive Extraction
        + Set the Extraction value to "Manual Archive Extraction" when the archive file has already been manually extracted on the server. This can be + done through your host's control panel such as cPanel or by your host directly. This setting can be helpful if you have a large archive file + or are having issues with the installer extracting the file due to timeout issues. +

        + + PHP ZipArchive
        + This extraction method will use the PHP ZipArchive code to extract the + archive zip file. +

        + + PHP ZipArchive Chunking
        + This extraction method will use the PHP ZipArchive code with multiple + execution threads to extract the archive zip file. +

        + + Shell-Exec Unzip
        + This extraction method will use the PHP shell_exec + to call the system unzip command on the server. This is the default mode that is used if it's available on the server. +

        + + DupArchive
        + This extraction method will use the DupArchive extractor code to extract the daf-based archive file. +
        Server
        Throttling
        + If the current host is a budget host that monitors CPU usage, then users might want to consider checking this box to help slow down the + process and not kick off any high-usage monitors. +
        +
        + Extraction Flow +
        Archive Action + Extract files over current files
        + The existing site files will be overwritten with the contents of the archive.zip/daf. +

        + + Pro + Remove WordPress core and content and extract
        + The existing WordPress core files and WordPress content directory will be removed, and then the archive will be extracted. +

        + + Pro + Remove all files except add-on sites and extract
        + All files except an add-on site will be removed, and then the archive will be extracted. An add-on site is a site/domain that is stored in a + directory off of your main site that has been "added on" to your main hosting account. For instance, when you purchased a hosting account it + could be for a.com. Then after that, you decided to add b.com and c.com to the same hosting account. The structure of this setup is often the + following although it can vary some: + +
          +
        • /public_html - contains files for a.com
        • +
        • /public_html/b.com - contains files for b.com
        • +
        • /public_html/c.com - contains files for c.com
        • +
        + + The directories /public_html/b.com and c.com contain the files for the add-on sites b.com and c.com (so the option above means that b.com and c.com + would be preserved and not deleted when you installed to a.com) +
        Skip Files + Extract all files
        + Extract all files from the package archive. This option is selected by default. +

        + + Pro + Skip extraction of WordPress core files
        + Extract all files except WordPress core files. Choose this option to extract only the wp-content folder and other non-core WordPress + files and directories. +

        + + Pro + Skip extraction of WordPress core files and plugins/themes existing on host
        + Extract all files except WordPress core files and existing plugins/themes on the current host. +

        + + Pro + Extract only media files and new plugins and themes
        + Extract all media files, new plugins, and new themes. The installer will not extract plugins and themes that already exist on the destination site. +
        File Times + When the archive is extracted it should show the current date-time or keep the original time it had when it was built. + This setting will be applied to all files and directories. + Note: Setting the Original time is currently only supported when using the ZipArchive Format. +
        File
        Permissions
        + Switch on and set permissions in either octal or symbolic values to assign permissions to files. This option is not available on Windows machines. +
        Directory
        Permissions
        + Switch on and set permissions in either octal or symbolic values to assign permissions to directories. This option is not available on + Windows machines. +
        + Configuration Files +
        + WordPress
        + wp-config +
        + Do nothing
        + This option simply does nothing. The wp-config file does not get backed up, renamed, or created. This advanced option assumes you already + know how it should behave in the new environment. This option is for advanced technical persons. +

        + + Modify original
        + This is the default recommended option which will modify the original wp-config file. +

        + + Create new from wp-config sample
        + This option creates a new wp-config file by modifying the wp-config-sample.php file. + The new wp-config.php file will behave as if it was created in a fresh, default WordPress installation. +

        +
        + Apache
        + .htaccess +
        + Do nothing
        + This option simply does nothing. The .htaccess is not backed up, renamed, or created. This advanced option assumes you already have your + .htaccess file set up and know how it should behave in the new environment. When the package is built it will always create an .htaccess file + at this location: + + /dup-installer/original_files_[HASH]/.htaccess + + Since the file is already in the archive file it will show up when the archive is extracted. +

        + + Retain original from Archive.zip/daf
        + This option simply copies the /dup-installer/original_files_[HASH]/.htaccess file to the .htaccess file. Please note this option will cause issues + with the install process if the .htaccess is not properly set up to handle the new server environment. This is an advanced option and should + only be used if you know how to properly configure your .htaccess configuration. +

        + + Create New
        + This is the default recommended option which will create a new .htaccess file. The new .htaccess file is streamlined to help + guarantee no conflicts are created during install. +

        + + + Notes: Inside the archive.zip or archive.daf will be a copy of the original .htaccess (Apache) file that was set up with your + packaged site. The .htaccess file is copied to /dup-installer/original_files_[HASH]/source_site_htaccess. When using either "Create New" + or "Retain original from Archive.zip/daf" an existing .htaccess file will be backed up to a + /wp-content/backups-dup-lite/installer/original_files_[HASH]/source_site_htaccess. + This change will not made until the final step is completed, to avoid any issues the .htaccess might cause during the install + +
        + General
        + php.ini, .user.ini,
        web.config
        +
        + OVERVIEW
        + When the archive is built it will always create an original backup of the php.ini, .user.ini, and web.config files ("Config Files") if they exist. + The backups will be in the following location within the archive file without an extension. + + Original File Backups
        + archive.zip|daf/dup-installer/original_files_[HASH]/[location]_phpini
        + archive.zip|daf/dup-installer/original_files_[HASH]/[location]_userini
        + archive.zip|daf/dup-installer/original_files_[HASH]/[location]_webconfig +
        + If there are "Config Files" on the new server, backups may also optionally be created. Backup [location] is defined by the following: +
          +
        • source_site Backup of original file when the archive was created on the source host
        • +
        • installer_host Backup of original file before the installer starts on active host
        • +

        + + + ACTIONS
        + Do nothing
        + This option performs no actions and assumes you already have your configuration files set up properly; either on the server or in the archive. + If the same "Config Files" exist in both the deploy directory and the archive, then the archive files will overwrite any configuration files + that exist at the same location in the archive. +


        + + Retain original from Archive.zip/daf +
          +
        1. + Moves any existing "Config Files" on the new host to the following location: + + /dup-installer/original_files_[HASH]/installer_host_[CONFIG-TYPE]
          + An existing "Config File" resides on the server before the archive is extracted or step 1 is ran. +
          +
        2. +
        3. + The installer last step copies all "Config Files" from the archive backups to the correct location on the new host. + They are copied from this location:
          + + /dup-installer/original_files_[HASH]/source_site_[CONFIG-TYPE] + +
        4. +

        + + Reset +
          +
        1. + Moves any existing "Config Files" on the new host to the following location: + + /dup-installer/original_files_[HASH]/installer_host_[CONFIG-TYPE]
          + An existing "Config File" resides on the server before the archive is extracted or step 1 is ran. +
          +
        2. +
        3. + If any "Config Files" already exist in the archive they will be deployed "as is" to the location that matches the + archive file structure. +
        4. +
        +
        + General +
        Logging + The level of detail that will be sent to the log file (installer-log.txt). The recommended setting for most installs should be "Light." + Note if you use Debug the amount of data written can be very large. Debug is only recommended for support. +
        Cleanup + Pro + Remove disabled plugins/themes
        + Remove all inactive plugins and themes when installing site. Inactive users will also be removed during subsite to standalone migrations. +

        + + Pro + Remove users without permissions
        + Removes users that currently do not have any permissions associated with their accounts. +
        Safe Mode + Safe mode is designed to configure the site with specific options at install time to help overcome issues that may happen during the install + where the site is having issues. These options should only be used if you run into issues after you have tried to run an install. +

        + + Disabled
        + This is the default. This option will not apply any additional settings at install time. +

        + + Enabled
        + When enabled the safe mode option will disable all the plugins at install time. + Note: When this option is set you will need to manually re-enable the plugins that need to be enabled after the install from the + WordPress admin plugins page. +
        +

        + + + +

        + + Database Tab +

        +These are the advanced options for database configuration. + + + + + + + + + + + + + + + + + + + + + + + + + +
        OptionDetails
        Table Prefix + Pro + This option allows changing the table prefix to other than the package creation site's table prefix. The table prefix is the value placed in the + front of your database tables. It is possible to have multiple installations in one database if you give each WordPress site a unique prefix. +
        Mode + Modes affect the SQL syntax MySQL supports (and others such as MariaDB) . This setting performs various data validation checks. This makes + it easier to use MySQL in different environments and to use MySQL together with other database servers. It is very useful when running into + conversion issues. The following options are supported: +
          +
        • Default: This is the recommended setting to use. It will use the current Database mode setting.
        • +
        • Disable: This will prevent the database engine from running in any mode.
        • +
        • Custom: This option will allow you to enter a custom set of mode commands. See the documentation link below for options.
        • +
        + + For a full overview please see the MySQL mode and + MariaDB mode specific to your version. To add a custom setting enable the + Custom radio button and enter in the mode(s) that needs to be applied. +
        Processing + Chunking mode
        + Split the work of inserting data across several requests. If your host throttles requests or you're on a shared server that is being heavily + utilized by other sites then you should choose this option. This is the default option. +

        + + Single step
        + Perform data insertion in a single request. This is typically a bit faster than chunking, however it is more susceptible to problems when the + database is large or the host is constrained. +
        Create + Run all CREATE SQL statements at once. This option should be checked when source database tables have foreign key relationships. + When choosing this option there might be a chance of a timeout error. Uncheck this option to split CREATE queries in chunks. + This option is checked by default. +
        Objects + Allow or Ignore objects for "Views," "Stored Procedures," "Functions" and "DEFINER" statements. Typically the defaults + for these settings should be used. In the event you see an error such as "'Access denied; you need (at least one of) + the SUPER privilege(s) for this operation" then changing the value for each operation should be considered. +
        +

        + + +

        + + URLs & Paths Tab + Pro +

        +In the tab "URLs & Paths," you can read the current path of all the various path configurations for the WordPress site. These are advanced options +that should only be edited if you know the correct path. These options are editable in the Pro version. +
          +
        • + WordPress core path +
        • +
        • + WordPress core URL +
        • +
        • + WP-content path +
        • +
        • + WP-content URL +
        • +
        • + Uploads path +
        • +
        • + Uploads URL +
        • +
        • + Plugins path +
        • +
        • + Plugins URL +
        • +
        • + MU-plugins path +
        • +
        • + MU-plugins URL +
        • +
        + +These paths and URLs are set automatically by the package installer. You can set these paths and URLs manually. If you are changing it, +please make sure you are putting the right path or URL. +


        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/basic-step1-setup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/basic-step1-setup.php new file mode 100644 index 0000000..ad47e61 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/basic-step1-setup.php @@ -0,0 +1,355 @@ + + +If no passwords were set on the installer or archive file then users will initially see step one of the installer. The installer has two operating views +that can be toggled via the Basic and Advanced buttons in the right-hand corner of the application. These installer views can only be chosen on step 1. +An overview of each view is explained below. +

        + + Views: +
          +
        • + Basic: + This is a simple two-step mode with all options set to the defaults. This is the default mode. The Basic view is the easiest and fastest and + covers most setup types. This is the recommended view for most installs. +
        • +
        • + Advanced: + This four-step mode allows for higher levels of customization with various detail settings. The Advanced view allows users to implement and apply + additional settings/features to the install process.
          + This is the only mode that Duplicator supported before version 1.5 +
        • +
        + + +

        Overview

        +The overview section allows users to identify the status, mode and select from the install type based on the user's install status. Additionally there are +other details about the archive file. Below is an overview of the various status, mode and install types.
        + + + Note: Duplicator Lite supports only single WordPress sites, while + " target="_blank"> + Duplicator Pro + supports single and multisite websites. + +

        + +

        + + Installation Tab +

        +This section will give an overview of the various install modes, methods and types that are currently being used. +

        + + Status: +
          +
        • + Install - Single Site
          + This will perform the installation of a single WordPress site based on the associated method. +
        • +
        • + Pro + Install - Multisite-Subdomain:
          + This is a full Multisite installation subdomain (i.e. subdomain.mysite.com) install. All sites in the network will be extracted and installed. +
        • +
        • + Pro + Install - Multisite-Subfolder:
          + This is a full Multisite installation via sub-folders install. All sites in the network will be extracted and installed. +
        • +
        • + Pro + Install - Standalone Site:
          + This installation converts the selected subsite into a standalone website. +
        • +
        • + Pro + Install - Archive Single Site into Subdomain/Subfolder Multisite:
          + This installation will insert the package site into the current multisite subdomain/subfolder setup. +
        • +
        • + Pro + Install - Selected Subsite in Subdomain/Subfolder Multisite:
          + This installation will insert the selected subsite of the package into the current subdomain/subfolder multisite installation. +
        • +
        • + Pro + Recovery - [Site Type]:
          + This status is enabled when the installer detects recovery mode installer was launched. This process will overwrite this site from the recovery + point made on a specific date. The site type will represent the type of site being recovered. +
        • +
        • + Pro + Restore Site Backup:
          + This method is enabled when the installer detects an archive is imported that matches the current setup. The restore backup status restores the + original site by not performing any processing on the database or tables to ensure an exact copy of the original site exists. Restore has the + following status types: Restore: Single Site Backup, Restore - Multisite-Subdomain Backup, Restore - Multisite-Subfolder Backup +
        • +
        + + + Mode: +
          +
        • + Standard Install +
            +
          • Includes both files and tables in the archive file.
          • +
          • The files and tables are determined by filters enabled during the archive build process.
          • +
          • Method is enabled when there is no existing WordPress site present in the current install directory.
          • +
          +
        • +
        • + Standard Install - Database Only +
            +
          • Includes only database tables in the archive file.
          • +
          • The tables are determined by filters enabled during the archive build process.
          • +
          • + Method is enabled when the archive only contains the database and there is no existing WordPress site present in the + current install directory. +
          • +
          +
        • +
        • + Overwrite Install
          +
            +
          • Includes both files and tables in the archive file.
          • +
          • The files and tables are determined by filters enabled during the archive build process.
          • +
          • Method is enabled when the installer detects an existing WordPress site is present.
          • +
          +
        • +
        • + Overwrite Install - Database Only
          +
            +
          • Includes only database tables in the archive file.
          • +
          • The tables are determined by filters enabled during the archive build process.
          • +
          • Method is enabled when the installer detects an existing WordPress site is present.
          • +
          +
        • +
        • + Pro + Custom Install
          +
            +
          • When the mode is custom this indicates the install is specifically driven by the status type.
          • +
          • See the status type of the install for all exact install details.
          • +
          +
        • +
        + + Install Type: +
          +
        • Full/Restore: This is the default install type.
        • +
        • Pro Convert: This is a Multisite feature used to convert a network subsite to a standalone site.
        • +
        • Pro Import: This is a Multisite feature used to import a subsite into a Multisite network.
        • +
        +* The Restore, Convert and Import types are only visible when the installer detects that it can perform the action. +

        + +

        + + Archive Tab +

        +The archive tab shows various details about the archive file and site details related to the site that was archived. With Duplicator the following +install modes are currently supported: +
          +
        • + Classic Install: + With this mode users can install to an empty directory like a new WordPress install does. +
        • +
        • + + Overwrite Install: + + This mode allows users to quickly overwrite an existing WordPress site in a few clicks. +
        • +
        • + Pro + Import Install: + Drag and drop or use a URL for super-fast installs. This Pro-only feature will import both Pro and Lite archives. +
            +
          • Import File: Drag and drop an existing Duplicator Lite or Pro archive and quickly replace the existing WordPress site
          • +
          • Import Link: Provide a link to an existing Duplicator Lite or Pro archive and quickly replace the existing WordPress site.
          • +
          +
        • +
        +


        + + +

        Setup

        +

        + + Database Tab +

        +The database connection inputs allow you to connect to an existing database or create a new database along with the other actions below. There are currently +two options you can use to perform the database setup: +
          +
        1. + Default: This option requires knowledge about the existing server, and requires the database be created ahead of time on most hosts. +
        2. +
        3. + Pro + cPanel: + The cPanel option is for hosts that support cPanel software. This option will automatically show you the existing + databases and users in your cPanel server and allow you to create new databases directly from the installer. +
        4. +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        OptionDetails
        + Default +
        Action + Empty Database
        + DELETE all tables in the database you are connecting to. Please make sure you have backups of all your data before using this part of the + installer, as this option WILL remove all data. +

        + + Backup Existing Tables
        + Create a backup of all existing tables by performing a RENAME of all tables in the database with a prefix of + "". This makes room for the new tables to be created. +

        + + Skip Database Extraction
        + This option requires that you manually run your own SQL import to an existing database before running the installer. + When this action is selected the + dup-database__[hash].sql file found inside the dup-installer folder of the archive.zip file will NOT be processed. The database you're connecting to + should already be a valid WordPress installed database. This option is viable when you need to perform custom SQL work or advanced installs. +

        + + Create New Database
        + Will attempt to create a new database if it does not exist. This option will not work on most hosting providers (due to host restrictions) but + will work on most local systems. If the database does not exist then you will need to log in to your host's database management system and create + the database. If your host supports cPanel then you can use this option to create a new database after logging in via your cPanel account. +

        + + Pro + Overwrite Existing Tables
        + Overwrite only the tables that are extracted. This option is useful if you want to install WordPress in a database containing other WordPress + installations or applications. Note: When performing an install alongside another installation be sure to change the prefix since only those + tables with the same prefix will be overwritten while tables of a different prefix will be retained. +

        +
        HostThe name of the host server that the database resides on. + Most times this will be "localhost," however each hosting provider will have its own naming + convention so please check with your server administrator or host to determine the proper host name. + To add a port number, just append it to the host i.e. "localhost:3306."
        Database + The name of the database to which this installation will connect and install the new tables and data into. + Some hosts will require a prefix while others do not. + Be sure to know exactly how your host requires the database name to be entered. +
        User + The name of MySQL/MariaDB database server user. + This is a special account that has privileges to access a database and can read from or write to that database. + This is not the WordPress administrator account. +
        PasswordThe password of the MySQL/MariaDB database server user.
        + cPanel Pro +
        HostPro + This should be the primary domain account URL that is associated with your host. Most hosts will require you to register a primary domain name. + This should be the URL that you place in the host field. For example if your primary domain name is "mysite.com" then you would enter in + "https://mysite.com:2083." The port 2083 is the common port number that cPanel works on. If you do not know your primary domain name please + contact your hosting provider or server administrator. +
        Username + Pro + The cPanel username used to login to your cPanel account. This is not the same thing as your WordPress administrator account. + If you're unsure of this name please contact your hosting provider or server administrator. +
        Password + Pro + The password of the cPanel user. +
        Troubleshoot + Pro + Common cPanel Connection Issues:
        + - Your host does not use cPanel software.
        + - Your host has disabled cPanel API access.
        + - Your host has configured cPanel to work differently (please contact your host).
        + + - View a list of valid cPanel Supported Hosts. +
        +

        + + +

        + + Settings Tab +

        +The settings options allow users to change the "Site Title," "Site URL" and "Site Path". By default and in most cases the "Site URL" and "Site Path" +should not need to be changed. In Basic mode these values are read-only. In order to edit them switch to the "Advanced" mode found in the upper right +corner of the installer wizard. + + + + + + + + + + + + + + + + + +
        OptionDetails
        Site Title + The name of the WordPress website. On most websites this value will be the name used to bookmark the site or the name of the browser tab + used to view the page. +
        Site URL + The New Site URL input field is auto-filled with the installation site URL. By default you have no need to change it. For details see WordPress + Site URL & + Alternate Directory. + This value should only be changed if you know what you want the value to be. The old URL value is listed as a read-only and will show the URL + of the site when the package was created. These values should not be changed, unless you know the underlying reasons. +
        Site Path + This is the physical server path where your WordPress site resides. For hosted server check with your hosting provider for the correct + path location. These values should not be changed, unless you know the underlying reasons. +
        +


        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/validation-step1.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/validation-step1.php new file mode 100644 index 0000000..a13981e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/step1-parts/validation-step1.php @@ -0,0 +1,27 @@ + + + + +

        Validation

        +The system validation checks help to make sure the system is ready for install. During installation the website will be in maintenance mode and not +accessible to users. The series of checks will alert if there are any items that need attention. An overview of the different status codes can all +be found online in the FAQ titled + + How to fix installer validation checks? + +

        + +The validation process requires a connection to the database before starting. Enter in all the Database Connection fields and click the "Validate" button +to start the validation process. If the database connection is not successful, details about how to solve the issue will be provided. If the database +connection is successful then additional system checks will be performed to help users identify any potential issues that might arise during the install +process. + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/troubleshoot.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/troubleshoot.php new file mode 100644 index 0000000..148f74a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/help/steps/troubleshoot.php @@ -0,0 +1,76 @@ + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/page-footer.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/page-footer.php new file mode 100644 index 0000000..063b39c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/page-footer.php @@ -0,0 +1,24 @@ + InstallerUpsell::getProFeatureList() +)); +?> +
        +getParamsHtmlInfo(); +?> + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/page-header.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/page-header.php new file mode 100644 index 0000000..cacea4f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/page-header.php @@ -0,0 +1,37 @@ + + + + + Duplicator + + + + $bodyId, + 'bodyClasses' => $bodyClasses + )); + ?> +
        + $paramView + )); + if (!isset($skipTopMessages) || $skipTopMessages !== true) { + dupxTplRender('parts/top-messages.php'); + } diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/secure/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/secure/main.php new file mode 100644 index 0000000..f9abff4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/secure/main.php @@ -0,0 +1,81 @@ +getSecurityType()) { + case DUPX_Security::SECURITY_PASSWORD: + $errorMsg = 'Invalid Password! Please try again...'; + break; + case DUPX_Security::SECURITY_ARCHIVE: + $errorMsg = 'Invalid Archive name! Please try again...'; + break; + case DUPX_Security::SECURITY_NONE: + default: + $errorMsg = ''; + break; +} +?> + +
        +

        + +

        +
        + +
        +
        + + Why do I see this screen? + +
        +
        + This screen will show under the following conditions: +

        + + Password: + If the installer was password protected when created then the password input below should be enabled.
        + If the input is disabled then no password was set during the build process. +

        + + Secure-File: + If the archive file is on a public server under these conditions: +
          +
        • Running a basic installer name (installer.php) with no installer password.
        • +
        • Running with the "Overwrite Install" method active and no installer password.
        • +
        + Validate the 'Archive File Name' input with the secure-file name it was created with ([name]_[hash]_[time]_archive.zip).
        + If the archive file name input is disabled or hidden then it can be ignored. +
        +
        + +
        + getHtmlFormParam(PrmMng::PARAM_SECURE_PASS); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_SECURE_ARCHIVE_HASH); + ?> +
        + + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions-part.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions-part.php new file mode 100644 index 0000000..fdc9ba3 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions-part.php @@ -0,0 +1,12 @@ + +
        +
        + + This installation will not be able to proceed until the archive and validation sections both pass. + Please adjust your servers settings click validate buttom or contact your server administrator, + hosting provider or visit the resources below for additional help. + + +
        +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/hwarn-accept.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/hwarn-accept.php new file mode 100644 index 0000000..aca5293 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/hwarn-accept.php @@ -0,0 +1,15 @@ + +
        +

        + It is not recommended but possible to continue with the installation before
        + the problems indicated in the validation have been solved. +

        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/next.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/next.php new file mode 100644 index 0000000..462c50c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/next.php @@ -0,0 +1,31 @@ + +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/switch-template.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/switch-template.php new file mode 100644 index 0000000..6e983ed --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/switch-template.php @@ -0,0 +1,25 @@ + +
        + + + + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/validate.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/validate.php new file mode 100644 index 0000000..111c899 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/actions/validate.php @@ -0,0 +1,20 @@ + +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/base-setup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/base-setup.php new file mode 100644 index 0000000..8b3fadc --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/base-setup.php @@ -0,0 +1,61 @@ +getValue(PrmMng::PARAM_DB_VIEW_MODE) === 'cpnl') { + $cpnlDisplay = ''; + $basicDisplay = 'no-display'; +} +?> +
        + Setup +
        +
        +
        +
        + +
        + getHtmlFormParam(PrmMng::PARAM_DB_VIEW_MODE); + } + ?> +
        + +
        + + +
        + +
        + + +
        +
        + +
        +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/continue-block.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/continue-block.php new file mode 100644 index 0000000..3f178ed --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/continue-block.php @@ -0,0 +1,31 @@ + +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/basic-db-connection.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/basic-db-connection.php new file mode 100644 index 0000000..b4911eb --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/basic-db-connection.php @@ -0,0 +1,56 @@ +getMode() === DUPX_InstallerState::MODE_OVR_INSTALL && $paramsManager->getValue(PrmMng::PARAM_DB_DISPLAY_OVERWIRE_WARNING)) { + $displayOverwrite = true; +} else { + $displayOverwrite = false; +} +?> +
        +
        + Database Connection +
        + +
        + Ready to connect to existing sites database?
        +
        + The existing site's database settings are ready to be applied below. + If you want to connect to this database and replace all its data then + click the 'Apply button' to set the placeholder values. + To use different database settings click the 'Reset button' to clear and set new values. +

        + + + + Warning: Please note that reusing an existing site's database will overwrite all of its data. If you're not 100% sure about + using these database settings, then create a new database and use the new credentials instead. + +
        + +
        + + +
        +
        + getHtmlFormParam(PrmMng::PARAM_DB_ACTION); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_HOST); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_NAME); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_USER); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_PASS); + ?> +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/cpanel-panel.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/cpanel-panel.php new file mode 100644 index 0000000..d8a8699 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/cpanel-panel.php @@ -0,0 +1,64 @@ + +
        cPanel Connection
        + +
        +

        + cPanel Connectivity +

        + + + + + +
        + This server does not appear to support cPanel!
        + Consider upgrading to a host that does.
        + cPanel support is available only in Duplicator Pro with participating hosts. +
        + + + Duplicator Pro cPanel connectivity allows the following + without leaving this installer: + +
          +
        • Directly login to cPanel
        • +
        • Instantly create new databases & users
        • +
        • Preview and select existing databases & users
        • +
        + + + Note: Hosts that support cPanel provide remote access to server resources, allowing operations such as direct database and user creation. + Duplicator Pro + supports cPanel API access, which can help improve and speed up your workflow. + +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/db-options.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/db-options.php new file mode 100644 index 0000000..cdb024f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/database-tabs/db-options.php @@ -0,0 +1,39 @@ + +
        Extraction Settings
        +
        + +
        +isManaged()) { + $paramsManager->setFormNote(PrmMng::PARAM_DB_TABLE_PREFIX, 'The table prefix must be set according to the managed hosting where you install the site.'); +} +$paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_TABLE_PREFIX); +?> +
        + getHtmlFormParam(PrmMng::PARAM_DB_MYSQL_MODE); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_MYSQL_MODE_OPTS); + ?> +
        +getHtmlFormParam(PrmMng::PARAM_DB_ENGINE); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_SPLIT_CREATES); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_VIEW_CREATION); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_PROC_CREATION); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_FUNC_CREATION); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_REMOVE_DEFINER); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/archive.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/archive.php new file mode 100644 index 0000000..68c3804 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/archive.php @@ -0,0 +1,58 @@ + +
        + + + + + + + + + + + + + + + + +
        Archive File
        Created:created; ?>
        Size:
        Archive:package_name; ?>
        + + + + + + + + + + + + + + + + + + + exportOnlyDB) : ?> + + + + + +
        Site Details
        Site:blogname); ?>
        URL:getRealValue('siteUrl'), '/')); ?>
        Notes:package_notes) ? "{$archiveConfig->package_notes}" : " - no notes - "; ?>
        Mode:Archive only database was enabled during package package creation.
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/general.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/general.php new file mode 100644 index 0000000..a0bc752 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/general.php @@ -0,0 +1,21 @@ + +
        + +
        + getHtmlFormParam(PrmMng::PARAM_INST_TYPE); + ?> +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overview-description.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overview-description.php new file mode 100644 index 0000000..e2ebf6d --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overview-description.php @@ -0,0 +1,31 @@ +getMode() === DUPX_InstallerState::MODE_OVR_INSTALL); +?> +
        + isManaged()) !== false) { + $hostObj = $hostManager->getHosting($identifier); + ?> +
        +

        + getLabel(); ?> managed hosting detected +

        +

        + The installation is occurring on a WordPress managed host. + Managed hosts are more restrictive than standard shared hosts so some installer settings cannot be changed. + These settings include new path, new URL, database connection data, and wp-config settings. +

        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overviews/restore-backup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overviews/restore-backup.php new file mode 100644 index 0000000..cb1409c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overviews/restore-backup.php @@ -0,0 +1,59 @@ +getMode() === DUPX_InstallerState::MODE_OVR_INSTALL); +$display = DUPX_InstallerState::getInstance()->isInstType( + array( + DUPX_InstallerState::INSTALL_RBACKUP_SINGLE_SITE + ) +); +?> +
        +
        +
        + '); ?> +
        + + + + + + + + + + + + + +
        Views: + Try + Basic + new or + Advanced views + +
        Status:Restore Single Site Backup
        Mode: +  ' : ''; + echo DUPX_InstallerState::getInstance()->getHtmlModeHeader(); + if ($overwriteMode) { + echo '
        + This will clear all site data and the current archive will be installed. This process cannot be undone! +
        '; + } + ?> +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overviews/type-single-site.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overviews/type-single-site.php new file mode 100644 index 0000000..5aa24b9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info-tabs/overviews/type-single-site.php @@ -0,0 +1,54 @@ +getMode() === DUPX_InstallerState::MODE_OVR_INSTALL); +$display = DUPX_InstallerState::getInstance()->isInstType(DUPX_InstallerState::INSTALL_SINGLE_SITE); +?> +
        +
        +
        + '); ?> +
        + + + + + + + + + + + + + +
        View: + Try + Basic + new or + Advanced views +
        Status:Standard Single Site Setup
        Mode: +  ' : ''; + echo DUPX_InstallerState::getInstance()->getHtmlModeHeader(); + if ($overwriteMode) { + echo '
        + This will clear all site data and the current archive will be installed. This process cannot be undone! +
        '; + } + ?> +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info.php new file mode 100644 index 0000000..41f7064 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/info.php @@ -0,0 +1,28 @@ + + +
        +
        + + +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/main.php new file mode 100644 index 0000000..e6a49a4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/main.php @@ -0,0 +1,20 @@ + +
        +
        + +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/advanced.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/advanced.php new file mode 100644 index 0000000..ad9980d --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/advanced.php @@ -0,0 +1,63 @@ + +
        + +
        + +
        Processing
        +getHtmlFormParam(PrmMng::PARAM_ARCHIVE_ENGINE); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_ZIP_THROTTLING); +?> + +
        Extraction Flow
        +getHtmlFormParam(PrmMng::PARAM_ARCHIVE_ACTION); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_FILE_TIME); +if (!SnapOS::isWindows()) { + ?> +
        + getHtmlFormParam(PrmMng::PARAM_SET_FILE_PERMS); ?> +   + getHtmlFormParam(PrmMng::PARAM_FILE_PERMS_VALUE); ?> +
        +
        + getHtmlFormParam(PrmMng::PARAM_SET_DIR_PERMS); ?> +   + getHtmlFormParam(PrmMng::PARAM_DIR_PERMS_VALUE); ?> +
        + + +
        Configuration Files
        +getHtmlFormParam(PrmMng::PARAM_WP_CONFIG); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_HTACCESS_CONFIG); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_OTHER_CONFIG); +?> + +
        General
        +getHtmlFormParam(PrmMng::PARAM_USERS_MODE); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_LOGGING); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_REMOVE_RENDUNDANT); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_REMOVE_USERS_WITHOUT_PERMISSIONS); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_SAFE_MODE); + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/engine-settings.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/engine-settings.php new file mode 100644 index 0000000..74da480 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/engine-settings.php @@ -0,0 +1,19 @@ + +
        Engine Settings
        +getHtmlFormParam(PrmMng::PARAM_ARCHIVE_ENGINE); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_ARCHIVE_ENGINE_SKIP_WP_FILES); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_ENGINE); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_ZIP_THROTTLING); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/other-urls-path.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/other-urls-path.php new file mode 100644 index 0000000..882f156 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/other-urls-path.php @@ -0,0 +1,41 @@ + +
        + Secondary URLs and paths + ">* + +
        + +
        + *All of these options are configurable with Duplicator Pro. + getHtmlFormParam(PrmMng::PARAM_PATH_WP_CORE_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_SITE_URL); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_PATH_CONTENT_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_URL_CONTENT_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_PATH_UPLOADS_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_URL_UPLOADS_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_PATH_PLUGINS_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_URL_PLUGINS_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_PATH_MUPLUGINS_NEW); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_URL_MUPLUGINS_NEW); + ?> +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/settings.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/settings.php new file mode 100644 index 0000000..24c399d --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options-tabs/settings.php @@ -0,0 +1,20 @@ + +
        General
        +getHtmlFormParam(PrmMng::PARAM_BLOGNAME); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_URL_NEW); +$paramsManager->getHtmlFormParam(PrmMng::PARAM_PATH_NEW); + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options.php new file mode 100644 index 0000000..66d6f0b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/options.php @@ -0,0 +1,34 @@ + +
        + Options +
        +
        +
        + +
        + +
        +
        + +
        +
        + +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/proceed-confirm-dialog.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/proceed-confirm-dialog.php new file mode 100644 index 0000000..d52433d --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/proceed-confirm-dialog.php @@ -0,0 +1,85 @@ +getValue(PrmMng::PARAM_RECOVERY_LINK); +$txtTable = $tableCount . ' table' . ($tableCount == 1 ? '' : 's'); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/step-title.php new file mode 100644 index 0000000..8af6687 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/step-title.php @@ -0,0 +1,15 @@ + 'Step 1 of 4: Deployment
        This step will extract the archive file contents.
        ', + 'showInstallerMode' => true, + 'showSwitchView' => true, + 'showInstallerLog' => false +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/terms-and-conditions.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/terms-and-conditions.php new file mode 100644 index 0000000..d82f1de --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step1/terms-and-conditions.php @@ -0,0 +1,97 @@ + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/main.php new file mode 100644 index 0000000..7ae5c6b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/main.php @@ -0,0 +1,49 @@ + + +
        +
        + +
        +
        + +
        + +
        +
        + +
        +
        +
        +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/options-tabs/general.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/options-tabs/general.php new file mode 100644 index 0000000..ef5c1e4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/options-tabs/general.php @@ -0,0 +1,31 @@ + +
        + +
        +
        + +
        + Charset & Collation +
        + getHtmlFormParam(PrmMng::PARAM_DB_CHARSET); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_DB_COLLATE); + } + ?> +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/options-tabs/tables.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/options-tabs/tables.php new file mode 100644 index 0000000..abee724 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/options-tabs/tables.php @@ -0,0 +1,32 @@ + +
        + +
        +
        + +
        + Import and Update +
        + + To exclude a table from install click the "Import" checkbox. To prevent a table from being updated with the new site data click the "Update" checkbox. +
        + getHtmlFormParam(PrmMng::PARAM_DB_TABLES); + }?> +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/step-title.php new file mode 100644 index 0000000..b42a099 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step2/step-title.php @@ -0,0 +1,12 @@ + 'Step 2 of 4: Install Database
        This step will install the database from the archive.
        ' +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/main.php new file mode 100644 index 0000000..6841b45 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/main.php @@ -0,0 +1,28 @@ + + + +
        +
        + +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/plugins.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/plugins.php new file mode 100644 index 0000000..23e316a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/plugins.php @@ -0,0 +1,23 @@ + +
        + +
        +
        Activate Plugins Settings
        +getHtmlFormParam(PrmMng::PARAM_PLUGINS); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/search-rules.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/search-rules.php new file mode 100644 index 0000000..51e33ba --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/search-rules.php @@ -0,0 +1,54 @@ + +
        Search & replace settings
        + +
        + +
        + +
        + Custom Search and Replace + ">* + +
        +

        + Add additional search and replace URLs to replace additional data.
        + This option is available in Duplicator Pro. +

        + +
        Database Scan Options
        +
        + getHtmlFormParam(PrmMng::PARAM_SKIP_PATH_REPLACE); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_EMAIL_REPLACE); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_FULL_SEARCH); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_POSTGUID); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_MAX_SERIALIZE_CHECK); + ?> +
        + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/users.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/users.php new file mode 100644 index 0000000..f764b38 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options-tabs/users.php @@ -0,0 +1,26 @@ + +
        + +
        + +
        User settings
        + +
        + +
        +
        + WP-Config File Setup + " + aria-expanded="false">* + +
        +
        + + + + See the WordPress documentation + for more information and specifications. All items are fully editable in Duplicator Pro. + + +
        CONTENT Posts/Pages
        + getHtmlFormParam(PrmMng::PARAM_WP_CONF_DISALLOW_FILE_EDIT); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_DISALLOW_FILE_MODS); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_AUTOSAVE_INTERVAL); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_POST_REVISIONS); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_EMPTY_TRASH_DAYS); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_IMAGE_EDIT_OVERWRITE); + ?> +
        SECURITY
        + getHtmlFormParam(PrmMng::PARAM_WP_CONF_FORCE_SSL_ADMIN); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_AUTOMATIC_UPDATER_DISABLED); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_AUTO_UPDATE_CORE); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_GEN_WP_AUTH_KEY); + ?> +
        CRON
        + getHtmlFormParam(PrmMng::PARAM_WP_CONF_ALTERNATE_WP_CRON); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_DISABLE_WP_CRON); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_CRON_LOCK_TIMEOUT); + ?> +
        DEBUG
        + getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_DEBUG); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_DEBUG_LOG); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_DEBUG_DISPLAY); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_SCRIPT_DEBUG); + ?> +
        SYSTEM
        + getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_CACHE); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WPCACHEHOME); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_MEMORY_LIMIT); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_MAX_MEMORY_LIMIT); + ?> +
        GENERAL
        + getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_DISABLE_FATAL_ERROR_HANDLER); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_MYSQL_CLIENT_FLAGS); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_CONCATENATE_SCRIPTS); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_SAVEQUERIES); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_COOKIE_DOMAIN); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_CONF_WP_TEMP_DIR); + } + ?> +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options.php new file mode 100644 index 0000000..6bb3bc6 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/options.php @@ -0,0 +1,58 @@ +getValue(PrmMng::PARAM_WP_CONFIG); +$skipWpConfig = ($wpConfig == 'nothing' || $wpConfig == 'original'); +?> + +
        + Options +
        + +
        +
        + + + +
        + +
        + + +
        + +
        + + +
        + +
        + + +
        + +
        + +
        +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/step-title.php new file mode 100644 index 0000000..bb7f062 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/step-title.php @@ -0,0 +1,13 @@ + 'Step 3 of 4: ' . + 'Update Data
        This step will update the database and config files to match your new sites values.
        ' +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/usersParts/newAdminUser.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/usersParts/newAdminUser.php new file mode 100644 index 0000000..5f4b436 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/usersParts/newAdminUser.php @@ -0,0 +1,32 @@ + +
        New Admin Account
        +

        + + This feature is optional. If the username already exists the account will NOT be created or updated. + +

        +
        + getHtmlFormParam(PrmMng::PARAM_WP_ADMIN_CREATE_NEW); ?> +
        + getHtmlFormParam(PrmMng::PARAM_WP_ADMIN_NAME); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_ADMIN_PASSWORD); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_ADMIN_MAIL); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_ADMIN_NICKNAME); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_ADMIN_FIRST_NAME); + $paramsManager->getHtmlFormParam(PrmMng::PARAM_WP_ADMIN_LAST_NAME); + ?> +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/usersParts/usersPwdReset.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/usersParts/usersPwdReset.php new file mode 100644 index 0000000..2821258 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step3/usersParts/usersPwdReset.php @@ -0,0 +1,19 @@ + +
        Admin Password Reset
        +
        + getHtmlFormParam(PrmMng::PARAM_USERS_PWD_RESET); + ?> +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/actions/admin-login-button.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/actions/admin-login-button.php new file mode 100644 index 0000000..76e29aa --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/actions/admin-login-button.php @@ -0,0 +1,35 @@ +getValue(PrmMng::PARAM_SAFE_MODE); +?> +
        + +
        + Click the Admin Login button to login and finalize this install.
        + getHtmlFormParam(PrmMng::PARAM_AUTO_CLEAN_INSTALLER_FILES); ?> +
        +
        + + +
        + SAFE MODE: + Safe mode has deactivated all plugins. Please be sure to enable your plugins after logging in. + + If you notice that problems arise when activating + the plugins then active them one-by-one to isolate the plugin that could be causing the issue. + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/final-review-actions.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/final-review-actions.php new file mode 100644 index 0000000..5d2eae1 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/final-review-actions.php @@ -0,0 +1,40 @@ + + +
        + Review +
        +
          +
        • + Review this site's front-end + +
        • +
        • + getFinalReporNoticeById('wp-config-changes'); + $htaccessNorice = $nManager->getFinalReporNoticeById('htaccess-changes'); + ?> + Review the longMsg; ?> and longMsg; ?> +
        • +
        • + For additional help visit the online FAQs +
        • +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/full-report.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/full-report.php new file mode 100644 index 0000000..c225de2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/full-report.php @@ -0,0 +1,56 @@ +getValue(PrmMng::PARAM_FINAL_REPORT_DATA); +?> +
        +
        + displayFinalRepostSectionHtml('general', 'General Notices Report'); + $nManager->displayFinalRepostSectionHtml('files', 'Files Notices Report'); + $nManager->displayFinalRepostSectionHtml('database', 'Database Notices Report'); + $nManager->displayFinalRepostSectionHtml('search_replace', 'Search and Replace Notices Report'); + $nManager->displayFinalRepostSectionHtml('plugins', 'Plugins Actions Report'); + ?> +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Database Report
        TablesRowsCells
        Createdn/a
        Scanned
        Updated
        +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/important-final-notice.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/important-final-notice.php new file mode 100644 index 0000000..225a17b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/important-final-notice.php @@ -0,0 +1,15 @@ + +
        + FINAL STEPS: + Login into the WordPress Admin to remove all and finalize the install process. + This install is NOT complete until all installer files have been completely removed. Leaving installer files on this server can + lead to security issues. +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/installer-result-summary.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/installer-result-summary.php new file mode 100644 index 0000000..0ecbb73 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/installer-result-summary.php @@ -0,0 +1,45 @@ + + +
        + Install Result +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        General Notices()getSectionErrLevelHtml('general'); ?>
        Files Status() getSectionErrLevelHtml('files'); ?>
        Database Status()getSectionErrLevelHtml('database'); ?>
        Search and Replace Status() getSectionErrLevelHtml('search_replace'); ?>
        Plugins Status() getSectionErrLevelHtml('plugins'); ?>
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/main.php new file mode 100644 index 0000000..d0955cc --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/pages-parts/step4/main.php @@ -0,0 +1,14 @@ + 'Step 4 of 4: Test Site' +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/ajax-error.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/ajax-error.php new file mode 100644 index 0000000..32850c9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/ajax-error.php @@ -0,0 +1,48 @@ +getValue(PrmMng::PARAM_RECOVERY_LINK); +?> +
        +

        + ERROR:

        + Please try again an issue has occurred. +

        +
        Please see the file for more details.
        +
        +
        +
        
        +
        +

        + Additional Resources:
        + » + '> + Help Resources +
        + » + '> + Technical FAQ + +

        +

        + + + + Restore Recovery Point + + +

        +

        + + See online help for more details at duplicator.com +

        +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/education/did-you-know-blurb.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/education/did-you-know-blurb.php new file mode 100644 index 0000000..3ae732c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/education/did-you-know-blurb.php @@ -0,0 +1,27 @@ + +
        + Did you know Duplicator Pro has: ? + + Upgrade To Pro + + getHtmlFormParam(PrmMng::PARAM_SUBSCRIBE_EMAIL); ?> +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/education/footer-cta.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/education/footer-cta.php new file mode 100644 index 0000000..188b790 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/education/footer-cta.php @@ -0,0 +1,58 @@ + +
        +
        Get Duplicator Pro and Unlock all the Powerful Features
        +

        + Thanks for being a loyal Duplicator Lite user. Upgrade to Duplicator Pro to unlock all the awesome features and + experience why Duplicator is consistently rated the best WordPress migration plugin. +

        +

        + ', 5) + ); + ?> +

        +
        Pro Features:
        +
          + +
        • + + + +
        • + +
        +

        + + Get Duplicator Pro Today and Unlock all the Powerful Features » + +

        +

        + Bonus: Duplicator Lite users get % off regular price, + automatically applied at checkout. +

        +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/archive-action-notes.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/archive-action-notes.php new file mode 100644 index 0000000..cf40fec --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/archive-action-notes.php @@ -0,0 +1,43 @@ + +
        + Note: Files are extracted over existing files. + After install, the destination folder will contain a combination of the old site files and the files extracted from the archive. + This option is the most conservative option for those who want to make sure they do not want to lose data. +
        +
        + Note: Before extracting the package files, all files and folders in the installation folder will be removed + except for folders that contain WordPress installations or Duplicator backup folders
        + This option is recommended for those who want to delete all files related to old installations or external applications. +
        +
        + Note: Before extracting the package files, all current media files will be removed (wp-content/uploads)
        + This option is for those who want to avoid having old site media mixed with new but have other files/folders + in the home path that they don't want to delete. +
        +
        + Note: Before extracting the package files, all current WordPress core and content files and folders will be removed (wp-include, wp-content ... )
        + This option is for those who want to avoid having old site media mixed with new but have other files/folders + in the home path that they don't want to delete. +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/db-name-notes.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/db-name-notes.php new file mode 100644 index 0000000..669e0e8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/db-name-notes.php @@ -0,0 +1,21 @@ + + + Warning: The selected 'Action' above will remove all data from this database! + + + Notice: The selected 'Action' will rename all existing tables from the database name above with a prefix + The prefix is only applied to existing tables and not the new tables that will be installed. + + + Notice: The 'Skip Database Extraction' action will prevent the SQL script (dup-database__[HASH].sql) in the archive from being executed. + The database above should already be pre-populated with the data for the site. The updates routines for updating the site URL and paths will be the + only SQL database commands applied to the database. + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/extract-skip-notes.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/extract-skip-notes.php new file mode 100644 index 0000000..72efd27 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/extract-skip-notes.php @@ -0,0 +1,36 @@ + +
        + All Files in the archive are going to be extracted. +
        +
        + When this option is chosen the wordpress core files, if any, are not modified. They are not deleted and/or extracted. +
        +
        + When this option is chosen the wordpress core files, if any, are not modified. They are not deleted and/or extracted.
        + Also, if a plugin (theme) exists on BOTH the host and and the archive, the contents of the host plugin (theme) are going to be kept. +
        +
        + When this option is chosen only the "uploads" folder and plugins (themes) that don't exist on the host are going to be extracted. +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/inline_helps/subsite_user_mode.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/inline_helps/subsite_user_mode.php new file mode 100644 index 0000000..db1ccde --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/inline_helps/subsite_user_mode.php @@ -0,0 +1,17 @@ + +

        + Import: Adds all users from the source site to the target site. Does not remove or alter existing target users. +

        +

        + Ignore: Don't import users from the source site. + All content on the source site will be assigned to the content author selected user. +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/inline_helps/user_mode.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/inline_helps/user_mode.php new file mode 100644 index 0000000..e785dc0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/params/inline_helps/user_mode.php @@ -0,0 +1,21 @@ + +

        + Overwrite: Overwrites users is the classic mode, users from the source site will be installed and those from the target site will be discarded. +

        +

        + Keep: Keeps all users of the target site by discarding users of the source site. + All content on the source site will be assigned to the content author selected user. +

        +

        + Merge: Merges users from the target site with users from the source site. + The target site users will be unchanged and the source site users will be added by remapping ids and logins if duplicated. +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/progress-bar.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/progress-bar.php new file mode 100644 index 0000000..8426e95 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/progress-bar.php @@ -0,0 +1,24 @@ +
        +
        +
        +
        +
        +
        +

        Please Wait...



        +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/reports/import_report.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/reports/import_report.php new file mode 100644 index 0000000..5831007 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/reports/import_report.php @@ -0,0 +1,33 @@ + +

        + users have been added
        + users were already present and therefore have been modified +

        + +

        + No users have been imported and/or modified, all users from the source site are in the target site. +

        + + A CSV report has been generated with the list of all the users added/modified and the mapping of the modifications
        + + Download import CSV report +
        + Note: This report does not contain users who were already at the target site. + +

        + Csv report rile can't be generated +

        + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/restore-backup-mode-notice.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/restore-backup-mode-notice.php new file mode 100644 index 0000000..549815c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/restore-backup-mode-notice.php @@ -0,0 +1,13 @@ + +

        + Restore backup mode is enabled so most options are disabled.
        + If you want to activate these options to change the migration website you need to restart the installer and deactivate the Restore backup mode option +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/top-header-help.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/top-header-help.php new file mode 100644 index 0000000..9f76b1c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/top-header-help.php @@ -0,0 +1,21 @@ + + + + + +
        +
        + Duplicator help +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/top-header.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/top-header.php new file mode 100644 index 0000000..b844108 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/top-header.php @@ -0,0 +1,43 @@ + + + + + + +
        +
        + + applyFilters('dupx_main_header', 'Duplicator'); ?> +
        +
        + version:version_dup; ?> + +
        + +  | '; + DUPX_View_Funcs::helpLink($paramView, 'Help'); + ?> + +   + +
        +
        + +
        + nextStepLog(); +// display and remove next step notices + DUPX_NOTICE_MANAGER::getInstance()->displayStepMessages(); + ?> +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-affected-tables.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-affected-tables.php new file mode 100644 index 0000000..a5b3ff5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-affected-tables.php @@ -0,0 +1,47 @@ + +
        STATUS
        + + + +

        + Adding a new subsite into WordPress does not require removing or renaming any tables. +

        + +

        + The chosen Database Action does not affect any tables in the selected database. +

        + + +

        + The chosen Database Action will result in the modification of + table(s). +

        + +
        DETAILS
        +

        + +
        +
          + +
        • + +
        +
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-case-sensitive-duplicates.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-case-sensitive-duplicates.php new file mode 100644 index 0000000..4497cf2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-case-sensitive-duplicates.php @@ -0,0 +1,49 @@ + $duplicateTableNames + * @var string[] $reduntantTableNames + */ + +?> +
        STATUS
        +

        + The following tables have the same name but different casing. Underlined tables are going to be excluded from the database extraction. +

        +
          + $tableNames) { ?> +
        • + $name) { + if (in_array($name, $reduntantTableNames)) { ?> + + +
        • + +
        + +
        DETAILS
        +

        + The database setting lower_case_table_names is set to [] which doesn't allow case sensitive table names. + This will cause issues trying to create tables with the same case insensitive table name. To change the filtered tables switch to "Advanced" and + mode and choose the tables to extract in Step 2. +

        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-case-sensitive-tables.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-case-sensitive-tables.php new file mode 100644 index 0000000..69b1625 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-case-sensitive-tables.php @@ -0,0 +1,65 @@ + +
        STATUS
        +

        + + No table casing issues detected. This servers variable setting for lower_case_table_names is [] + + An upper case table name was found in the database SQL script and the server variable lower_case_table_names is set to + []. + When both of these conditions are met it can lead to issues with creating tables with upper case characters.
        + Options:
        + - On this server have the host company set the lower_case_table_names value to 1 or 2 in the my.cnf file.
        + - On the build server set the lower_case_table_names value to 2 restart server and build package.
        + - Optionally continue the install with data creation issues on upper case tables names.
        + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks if any tables have upper case characters as part of the name. + On some systems creating tables with upper case can cause issues if the server + setting for + lower_case_table_names + is set to zero and upper case + table names exist. +

        + +
        TROUBLESHOOT
        + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-cleanup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-cleanup.php new file mode 100644 index 0000000..9c2bd8e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-cleanup.php @@ -0,0 +1,76 @@ + +
        STATUS
        +

        + + Successfully removed database [] + + The database [] was successfully created. + However removing the database was not successful with the following response:
        + To continue refresh the page, change the setup action and continue with the install + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks if the database can be removed by the database user . + The test will attempt drop the database name provided as part of the overall test. +

        + +
        TROUBLESHOOT
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-connection.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-connection.php new file mode 100644 index 0000000..8d98872 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-connection.php @@ -0,0 +1,95 @@ + +
        STATUS
        +

        + + The user [] successfully connected to the database server on host + []. + + Unable to connect the user [] to the host + [].
        + + The server error response was: ' + + Please contact your hosting provider or server administrator. + + +

        + +
        DETAILS
        +

        + This test checks that the database user is allowed to connect to the database server. + It validates on the user name, password and host values. + The check does not take into account the database name or the user permissions. A database user must first exist and have access to the host + database server before any additional checks can be made. +

        + + + + + + + + + + + + + + +
        Host:
        User:
        Password:

        + +
        TROUBLESHOOT
        + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-create.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-create.php new file mode 100644 index 0000000..a3745eb --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-create.php @@ -0,0 +1,82 @@ + +
        STATUS
        +

        + + Successfully created database [] + + DATABASE CREATION FAILURE: A database named [] already exists.

        + Please continue with the following options:
        + - Choose a different database name or remove this one.
        + - Change the action drop-down to an option like "Connect and Remove All Data".
        + + Error creating database []. + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks if the database can be created by the database user . + The test will attempt to create and drop the database name provided as part of the overall test. +

        + +
        TROUBLESHOOT
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-gtid-mode.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-gtid-mode.php new file mode 100644 index 0000000..62bb1b9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-gtid-mode.php @@ -0,0 +1,48 @@ + +
        STATUS
        +

        + + The installer have not detected GTID mode. + + Your database server have GTID mode is on, It might make a trouble in Database installation.
        + Details: You might face the error something like Statement violates GTID consistency. + You should ask hosting provider to make off GTID off. + You can make off GTID mode as decribed in the + + https://dev.mysql.com/doc/refman/5.7/en/replication-mode-change-online-disable-gtids.html + + + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks to make sure the database server should not have GTID mode enabled. +

        +
        TROUBLESHOOT
        + + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-host-name.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-host-name.php new file mode 100644 index 0000000..b13299c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-host-name.php @@ -0,0 +1,29 @@ + +

        + Database host: + + [] is valid. + + [] is not a valid. Try using [] instead. + + +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-manual-tables-count.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-manual-tables-count.php new file mode 100644 index 0000000..0988f17 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-manual-tables-count.php @@ -0,0 +1,42 @@ + +
        STATUS
        +

        + + This test passes. A WordPress database looks to be setup. + + The database [] has tables. This does not look to be a valid WordPress database. + The base WordPress install has 12 tables. Please validate that this database is indeed pre-populated with a valid WordPress database. + The "Skip Database Extraction" mode requires that you have a valid WordPress database already installed. + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks if the database looks to represents a base WordPress install. Since this option is advanced it is left upto the user to + have the correct database tables installed. +

        + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-multiple-wp-installs.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-multiple-wp-installs.php new file mode 100644 index 0000000..36a6a46 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-multiple-wp-installs.php @@ -0,0 +1,45 @@ + +
        STATUS
        + + +

        + The selected database action does not affect other WordPress installations. +

        + +

        + The selected database action affects WordPress installations. +

        + + +
        DETAILS
        +

        + This test makes sure that the selected database action affects at most one WordPress installation. Please make sure that the + chosen database action will not cause unwanted consequences for tables of other sites residing on the same database. In case + you want to avoid removing the tables of the second WordPress installation we recommend switching the Database action to + "Overwrite Existing Tables". +

        + 0) : ?> +

        WordPress tables with the following table prefixes will be affected by the chosen database action:

        +
          + +
        • + +
        + + + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-prefix-too-long.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-prefix-too-long.php new file mode 100644 index 0000000..12def11 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-prefix-too-long.php @@ -0,0 +1,54 @@ + +
        STATUS
        +

        + + There are no table names whose length exceeds limit of 64 characters after adding prefix. + + Some table names exceed limit of 64 characters after adding prefix. + +

        + +

        + Error detail: +

        + + + +
        DETAILS
        +

        + This test checks if there are any table names that would be too long after adding prefix to them. + MySQL accepts length of table names with maximum of 64 characters + (see length limits). + With a too long prefix, tables can exceed this limit. +

        + + + List of database tables that are too long after adding prefix
        +
        +
          + +
        • + +
        +
        + + +
        TROUBLESHOOT
        +
          +
        • Choose a shorter prefix in Options ⯠Database Settings ⯠Table Prefix.
        • +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-show-variables.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-show-variables.php new file mode 100644 index 0000000..68e2e4b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-show-variables.php @@ -0,0 +1,38 @@ + +
        STATUS
        + +

        + Successfully read database variables. +

        + +

        + Error reading database variables. +

        + +
        DETAILS
        +

        + Query executed: SHOW VARIABLES like 'version'

        + The "SHOW VARIABLES" query statement is required to obtain + necessary information about the database and safely execute the installation process. There is not a single setting that will make this query work + for all hosting providers. Please contact your hosting provider or server admin with + this link and ask for them to provide support for the + "SHOW VARIABLES" when called from PHP.

        + + Additional FAQ resources for this issue can be found here:
        + + DigitalOcean -- digitalocean.com + +

        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-charset.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-charset.php new file mode 100644 index 0000000..90e1daa --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-charset.php @@ -0,0 +1,138 @@ + DUPX_Validation_abstract_item::LV_SOFT_WARNING ? 'green' : 'red'; + +$dupDatabase = basename(DUPX_Package::getSqlFilePath()); +$dupDatabaseDupFolder = basename(DUPX_INIT) . '/' . $dupDatabase; +$invalidCheckboxTitle = ''; +$subTitle = ''; + +?> +
        STATUS
        +

        + + It is impossible to verify the list of charsets in the database. + + isn't supported on current database. + will be replaced with default values.
        + + Character set and Collate test passed! This database supports the required table character sets and collations. + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks to make sure this database can support the character set and collations found in the + script. +

        + + + + + + + + + + + + + + + + + + + + + + +
        + Character set list +
        + + + + +
        + Collations list +
        + + +
        + +

        + The database where the package was created has a that is not supported on this server. + This issue happens when a site is moved from an newer version of MySQL to a older version of MySQL. + The recommended fix is to update MySQL on this server to support the character set that is failing below. + If this is not an option for your host, then you can continue the installation. Invalid values will be replaced with the default values. + For more details about this issue and other details regarding this issue see the FAQ link below. +

        + +

        + Default charset and setting in current installation
        + DB_CHARSET =
        + DB_COLLATE = +

        + +

        TROUBLESHOOT
        + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-default-charset.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-default-charset.php new file mode 100644 index 0000000..7795760 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-default-charset.php @@ -0,0 +1,55 @@ + +
        STATUS
        +

        + + It is not possible to read the list of available charsets in the database.
        + Message: + + This server's database does not support the source site's character set [], + so the installer is going to use default character []. + + This server's database does not support the source site's collate [], + so the installer is going to use default collate of current charset []. + + The current server supports the source site's charset [] + and Collate [] + (set in the wp-config file).
        + +

        + +
        DETAILS
        +

        + Settings used in the current installation
        + DB_CHARSET =
        + DB_COLLATE = +

        +

        + DB_CHARSET and DB_COLLATE are set in wp-config.php + (see: Editing wp-config.php ).
        + When the charset or collate of the source site is not supported in the database of the target site, the default is automatically set. +

        + +
        TROUBLESHOOT
        +
          +
        • In case the default charset/collates are not the desired ones you can change the setting in the advanced installation mode.
        • +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-engine.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-engine.php new file mode 100644 index 0000000..ee21924 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-supported-engine.php @@ -0,0 +1,79 @@ + DUPX_Validation_abstract_item::LV_SOFT_WARNING ? 'green' : 'red'; + +$dupDatabase = basename(DUPX_Package::getSqlFilePath()); +$dupDatabaseDupFolder = basename(DUPX_INIT) . '/' . $dupDatabase; +$invalidCheckboxTitle = ''; +$subTitle = ''; + +?> +
        STATUS
        +

        + + The Duplicator Installer is currently unable to verify the list of engines in the database. + + Some of the MySQL engines used in the source site are not supported on the current database. + + Database engine for MySQL compatibility passed! This database supports the required MySQL engine types. + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks to make sure this database can support the MySQL engines found in the + script. +

        + + +

        + The following MySQL Engine(s) were found to not be supported by the current database: +

        +
          + +
        • + +
        + and are going to be replaced by the default MySQL Engine []. + + +
        TROUBLESHOOT
        +
          +
        • + In case some of the MySQL engines of the source site are not supported and replacing them with the default engine + is not desired, please try getting in touch with your hosting provider and asking them to enable the engine. +
        • +
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-triggers.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-triggers.php new file mode 100644 index 0000000..ad4a009 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-triggers.php @@ -0,0 +1,46 @@ + +
        STATUS
        +

        + + The source database did not contain any triggers. + + The source database contained TRIGGERS which will have to be manually imported. + +

        + +
        DETAILS
        +

        + TRIGGERS are not being imported along side the rest of the database, because their presence might cause unintended + behavior. You can copy the CREATE queries by clicking the button below and manually add triggers via PHPMyAdmin, if necessary. +

        + +
        + + +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-cleanup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-cleanup.php new file mode 100644 index 0000000..f746595 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-cleanup.php @@ -0,0 +1,50 @@ + +
        STATUS
        +

        + + Successfully removed database user [] with cPanel API. + + The database user [] was successfully created. + However removing the user was not successful via the cPanel API with the following response:
        + To continue refresh the page, uncheck the 'Create New Database User' checkbox and select the user from the drop-down. + +

        + +

        + Error detail: +

        + + +
        DETAILS
        +

        + This test checks that the cPanl API is allowed to remove database user crated before. +

        + + + + + + +
        User:

        + +
        TROUBLESHOOT
        +
          +
        • Contact your host to make sure they support the cPanel API.
        • +
        • Check with your host to make sure the user name provided meets the cPanel requirements.
        • +
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-perms.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-perms.php new file mode 100644 index 0000000..e37e26a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-perms.php @@ -0,0 +1,147 @@ + +
        STATUS
        +

        + + The user [] has the correct privileges on the database []. + + The user [] is missing privileges on the database [] + + The user [] is missing privileges on the database []
        + You can continue with the installation but some features may not be restored correctly. + +

        + +

        + Error detail:
        + +
        + +

        + + +
        DETAILS
        +

        + This test checks the privileges of the current database user. In order to successfully use Duplicator all of the privileges should pass. + In the event the checks below fail, contact your hosting provider to make sure the database user has the correct permissions listed below. +

        + + + Note: In some cases "Create Views, Procedures, Functions and Triggers" will not pass, but continuing with the install will still work. + It is however recommended that a green pass on all permissions is set when possible. Please work with your hosting provider to get all + values to pass. + +


        + +
        TABLE PRIVILEGES ON []
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Create
        Select
        Insert
        Update
        Delete
        Drop
        Create Views
        Procedures (Create & Alter)
        Functions (Create & Alter)
        Trigger

        + +
        TROUBLESHOOT
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-resources.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-resources.php new file mode 100644 index 0000000..c6bf044 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-user-resources.php @@ -0,0 +1,48 @@ + +
        STATUS
        + +

        + No restrictions on the current DB user's resources were detected. +

        + +

        + Restrictions on the current DB user's resources were detected. +

        + + +
        DETAILS
        +

        + Some server's put in place restrictions on the resources available to a user, which may cause errors during + the installation process since a significant number of connections are made and queries are run. +

        + + 0) : ?> +
        USER RESOURCES
        +
          + $limit) : ?> +
        • + : 0 ? $limit : 'unlimited'; ?> +
        • + +
        + +
        TROUBLESHOOT
        +

        + We suggest asking your hosting provider to undo the restrictions in case they are present or if you have root access to the mysql server + you can use the methods described in the official documentation + to remove the restrictions. +

        + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-version-swarn.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-version-swarn.php new file mode 100644 index 0000000..1623030 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-version-swarn.php @@ -0,0 +1,64 @@ + +
        STATUS
        +

        + + + The current database engine is [] while the host database engine was + []. + + + + The current database version is [] which is below the source database version of + []. + + + In some cases this might cause problems with the migration. +

        + +
        DETAILS
        +

        + + Some versions of different database engines are not compatible with each other, which might cause problems with the database import. + We suggest continuing the install as usual. + In case there are problems with the database install please consult the links in the + troubleshoot section to find out which features are not compatible. + + The source site used a newer version of , + which may result in problems during the installation if there were changes + made which are not backward-compatible. We suggest continuing with the install as usual. + In case of problems with the database try contacting your hosting provider and asking for a database version upgrade. + +

        + +
        TROUBLESHOOT
        + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-version.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-version.php new file mode 100644 index 0000000..06ab35f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-version.php @@ -0,0 +1,52 @@ + +
        STATUS
        +

        + + + This test passes with a current database version of [] + + + + The current database version is [] which is below the required version of 5.0.0. + Please work with your server admin or hosting provider to update the database server. + + +

        + +
        DETAILS
        +

        + The minimum supported database server is MySQL Server 5.0 or the + MariaDB equivalent. + Versions prior to MySQL 5.0 are over 10 years old and will not be compatible with Duplicator. + If your host is using a legacy version, please ask them + to upgrade the MySQL database engine to a more recent version. +

        + +
        TROUBLESHOOT
        + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-visibility.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-visibility.php new file mode 100644 index 0000000..c550f27 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/database-tests/db-visibility.php @@ -0,0 +1,96 @@ + +
        STATUS
        +

        + + The database user [] has visible access to see the database named + [] + + The user [] is unable to see the database named + [].
        + Be sure the database name already exists. + If you want to create a new database choose the action 'Create New Database'.
        + +

        + +

        + Error detail: +

        + + + +
        DETAILS
        +

        + This test checks if the database user is allowed to connect or view the database. + This test will not be ran if the 'Create New Database' action is selected. +

        + + + Databases visible to user []
        +
          + +
        • + +
        • + +
        • + No databases are viewable +
        • + +
        + + +
        TROUBLESHOOT
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/addon-sites.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/addon-sites.php new file mode 100644 index 0000000..fee5dc1 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/addon-sites.php @@ -0,0 +1,58 @@ + DUPX_Validation_abstract_item::LV_SOFT_WARNING ? 'green' : 'red' ); +?> +
        STATUS
        +

        + + No addon site detected. + + Detected addon sites, see the details section for the list of sites.
        + DUPX_Validation_abstract_item::LV_SOFT_WARNING) { ?> + Normal installation generally does not interfere with these sites. + + These sites are not deleted even if you have selected an action that removes the files before extracting them. + If there are other folders outside the home path that are necessary for the addon site to work, it will be removed + so pay attention in the event there are addon custom installations. + +

        + +
        DETAILS
        +

        + An addon site is a WordPress installation in a subfolder of the current home path. +

        + 0) { ?> +

        + Addons Site Paths +

        +
          + +
        • + +
        • + +
        + +
        TROUBLESHOOT
        +
          +
        • + The installer doesn't modify addon sites so their presence doesn't cause problems + but if you want to be sure you don't lose data it might be useful to make a backup of the addon site. +
        • +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/archive-check.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/archive-check.php new file mode 100644 index 0000000..4761fbc --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/archive-check.php @@ -0,0 +1,43 @@ + + Archive file successfully detected. + + + The archive file named above must be the exact name of the archive file placed in the root path (character for character). + But you can proceed with choosing Manual Archive Extraction. + + + + The archive file named above must be the exact name of the archive file placed in the root path (character for character). + When downloading the package files make sure both files are from the same package line.

        + + If the contents of the archive were manually transferred to this location without the archive file then simply create a temp file named with + the exact name shown above and place the file in the same directory as the installer.php file. The temp file will not need to contain any data. + Afterward, refresh this page and continue with the install process. +
        + + Invalid test result value DUPX_Validation_abstract_item::LV_SOFT_WARNING ? 'green' : 'red' ); +?> +
        STATUS
        +

        + DUPX_Validation_abstract_item::LV_SOFT_WARNING) { ?> + All configuration files are editable. + + One or more configuration files cannot be edited, the list is in the details section + +

        + +
        DETAILS
        +

        + This test verifies that the configuration files are editable. + Otherwise it is possible to continue with the installation but some settings will be disabled and + it will not be possible to modify the configuration file without write permissions. +

        + + + + + + + + + + + + + + + +
        + wp-config.php + + + +
        + .htaccess + + + +
        + Other configs
        + [ web.config, php.ini, .user.ini ] +
        + + +
        + +
        TROUBLESHOOT
        +
          +
        • If possible, via FTP or file manager, manually change the permissions of the conditioner files.
        • +
        • In case the home path does not have write or run permissions, add them manually.
        • +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/dbonly-iswordpress.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/dbonly-iswordpress.php new file mode 100644 index 0000000..38126f2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/dbonly-iswordpress.php @@ -0,0 +1,30 @@ +Deployment Path: getValue(PrmMng::PARAM_PATH_NEW)); ?> +

        + +The installer has detected that a WordPress site does not exist at the deployment path above. +This installer is currently in 'Database Only' mode because that is how the archive was created. +If core WordPress site files do not exist at the path above then they will need to be placed there in order for a WordPress site +to properly work. To continue choose one of these options: + +
          +
        1. Place this installer and archive at a path where core WordPress files already exist to hide this message.
        2. +
        3. Create a new package that includes both the database and the core WordPress files.
        4. +
        5. Ignore this message and install only the database (for advanced users only).
        6. +
        + + + Note: This test simply looks for the directories and a wp-config.php file. + If they are not found in the deployment path above then this notice is shown. + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/diskspace.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/diskspace.php new file mode 100644 index 0000000..c620b35 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/diskspace.php @@ -0,0 +1,34 @@ + +
        STATUS
        +

        + + You have sufficient disk space on your machine to extract the archive. + + You don’t have sufficient disk space on your machine to extract the archive. + +

        + +
        DETAILS
        +

        + Duplicator needs at least enough disk space to be able to host the package file and the extracted files.
        + The available free disk space is , the required disk space should at least be . +

        + +
        TROUBLESHOOT
        +
          +
        • Ask your host to increase your disk space.
        • +
        • Back-up and remove all unnecessary files you have in the install directory to free up space.
        • +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/importable-package.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/importable-package.php new file mode 100644 index 0000000..05dc9b5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/importable-package.php @@ -0,0 +1,41 @@ + DUPX_Validation_abstract_item::LV_SOFT_WARNING ? 'green' : 'red' ); +?> +
        STATUS
        +

        + DUPX_Validation_abstract_item::LV_SOFT_WARNING) { ?> + The package has all the elements to be imported. + + The package can't be imported. + +

        + + 0) { ?> +
        DETAILS
        +

        + +

        + + +
        TROUBLESHOOT
        +
          +
        • + A package with filtered elements cannot be imported to avoid a malfunction of the current site.
          + Create a new package in the site you want to import deactivating the filters on tables and/or files. +
        • +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/importer-version.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/importer-version.php new file mode 100644 index 0000000..57ab75e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/importer-version.php @@ -0,0 +1,43 @@ + DUPX_Validation_abstract_item::LV_SOFT_WARNING ? 'green' : 'red' ); +?> +
        STATUS
        +

        + DUPX_Validation_abstract_item::LV_SOFT_WARNING) { ?> + The version of Duplicator importer is compatible with the current package. + + Version of Duplicator importer is old compared to version of current package. + +

        + +
        DETAILS
        +

        + Importer version:
        + Package version: +

        + +
        TROUBLESHOOT
        +
          +
        • + The version of Duplicator in the importer site must be equal to or greater than the version with which the package was created.
          + Please update Duplicator to the latest version and restart the installation. +
        • +
        • + In case it is not possible to update the plugin, it is possible to perform a classic installation by starting the installer directly +
        • +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/managed-supported.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/managed-supported.php new file mode 100644 index 0000000..69efd92 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/managed-supported.php @@ -0,0 +1,22 @@ +

        + Managed hosting detected.
        + This managed hosting is supported. +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/managed-tprefix.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/managed-tprefix.php new file mode 100644 index 0000000..e27f285 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/managed-tprefix.php @@ -0,0 +1,26 @@ + +

        + + The prefix of the existing WordPress configuration table is equal of the prefix of the table of the source site where the package was created. + + The prefix of the existing WordPress configuration table does not match the prefix of the table of the source site where the package was created, + so the prefix will be changed to the managed hosting prefix. + +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/manual-extraction.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/manual-extraction.php new file mode 100644 index 0000000..bf82802 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/manual-extraction.php @@ -0,0 +1,35 @@ +

        + Deployment Path: getValue(PrmMng::PARAM_PATH_NEW)); ?> +

        +The installer has detected that the archive file has been extracted to the deployment path above. + +

        + The installer has detected that the archive file has been extracted to the deployment path above. The installer is going + to skip the extraction process by default. If you want to re-extract the archive file, switch to "Advanced" mode, and + under "Options" > "Extraction Mode" choose the preferred extraction mode. +

        + + + Note: This test looks for a file named dup-manual-extract__[HASH] in the directory. + If the file exists then this notice is shown. + The dup-manual-extract__[HASH] file is created with every archive and removed once the install is complete. For more details on this process see the + + manual extraction FAQ + . + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/memory-limit.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/memory-limit.php new file mode 100644 index 0000000..f3fadec --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/memory-limit.php @@ -0,0 +1,56 @@ + +

        +

        STATUS
        +

        + + + The memory_limit has a value of [] which is higher or equal to the suggested minimum of + []. + + + + The memory_limit has a value of [] + which is lower than the suggested minimum of []. + + +

        + +
        DETAILS
        +

        + +

        +The 'memory_limit' configuration in php.ini sets how much memory a script can use during its runtime. +When this value is lower than the suggested minimum of + the installer might run into issues. + +
        TROUBLESHOOT
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/mysql-connect.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/mysql-connect.php new file mode 100644 index 0000000..2940289 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/mysql-connect.php @@ -0,0 +1,13 @@ +

        + Support for the PHP mysqli extension is required. + Please contact your hosting provider or server administrator to enable the mysqli extension. The detection for this call uses + the function_exists('mysqli_connect') call. +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/open-basedir.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/open-basedir.php new file mode 100644 index 0000000..669f6ea --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/open-basedir.php @@ -0,0 +1,44 @@ + +

        + Open BaseDir: + DisabledEnabledEnabled +

        + + + The open_basedir configuration is disabled. + + All required archive paths were found in the open_basedir path list. + + If open_basedir is enabled and you're + having issues getting your site to install properly please work with your host and follow these steps to prevent issues: +
          +
        1. Disable the open_basedir setting in the php.ini file
        2. +
        3. If the host will not disable, then add the paths below to the open_basedir setting in the php.ini
          + + ""
          + +
        4. +
        5. Save the settings and restart the web server
        6. +
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/overwrite-install.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/overwrite-install.php new file mode 100644 index 0000000..92a0594 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/overwrite-install.php @@ -0,0 +1,35 @@ +Deployment Path: getValue(PrmMng::PARAM_PATH_NEW)); ?> +

        + +Duplicator is in "Overwrite Install" mode because it has detected an existing WordPress site at the deployment path above. This mode allows for the installer +to be dropped directly into an existing WordPress site and overwrite its contents. Any content inside of the archive file +will overwrite the contents from the deployment path. To continue choose one of these options: + +
          +
        1. Ignore this notice and continue with the install if you want to overwrite this sites files.
        2. +
        3. Move this installer and archive to another empty directory path to keep this sites files.
        4. +
        + + + Notice: Existing content such as plugin/themes/images will still show-up after the install is complete if they did not already exist in + the archive file. For example if you have an SEO plugin in the current site but that same SEO plugin does not exist in the archive file + then that plugin will display as a disabled plugin after the install is completed. The same concept with themes and images applies. This will + not impact the sites operation, and the behavior is expected. + +

        + + Recommendation: It is recommended you only overwrite WordPress sites that have a minimal setup (plugins/themes). Typically a fresh install or a + cPanel 'one click' install is the best baseline to work from when using this mode but is not required. + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/package-age.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/package-age.php new file mode 100644 index 0000000..52cd40e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/package-age.php @@ -0,0 +1,17 @@ +

        + This package is day(s) old. + Packages older than days might be considered stale. It is recommended to build a new + package unless your aware of the content and its data. This is message is simply a recommendation. +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/package-size.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/package-size.php new file mode 100644 index 0000000..f953550 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/package-size.php @@ -0,0 +1,28 @@ + +

        + This package is . + You might run into issues installing packages bigger than MB with Duplicator Lite. + Duplicator Pro has support for larger sites. Confirmed migration of sites up to 100GB! +

        +

        + + Upgrade Now + +

        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/php-extensions.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/php-extensions.php new file mode 100644 index 0000000..3ffb5bb --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/php-extensions.php @@ -0,0 +1,51 @@ + +
        DETAILS
        +

        + PHP extensions are compiled libraries which enable specific functions to be used in your PHP code. + This test checks if some of the most widely used extensions are + installed on your server. Extensions with an asterisk (*) are required for the installer to work. +

        + +
          + $extensionTest) : ?> +
        • + + + + * + : + + + Enabled + + Disabled + +
        • + +
        + +
        TROUBLESHOOT
        +

        + In case this test failed you have to install the required extension on your server or ask your hosting provider to + install it for you. +

        + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/php-version.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/php-version.php new file mode 100644 index 0000000..7c67963 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/php-version.php @@ -0,0 +1,46 @@ + +
        STATUS
        +

        + You are migrating site from PHP to PHP +

        + +
        DETAILS
        +

        + If the PHP version of your website is different than the PHP version of your package it may cause problems with the + functioning of your website. +

        + +

        + In case you are migrating your website from an older version of PHP to + PHP 8.x there is a relatively high probability + that some plugins or themes will not be compatible and may cause the overall website to not work. +

        + +
        TROUBLESHOOT
        +
          +
        • + We suggest proceeding in the "Advanced" mode and at Step 3 of the installation process under the "Plugins" tab + uncheck all plugins. In this way all plugins will be deactivated after the migration and you can then activate them + one-by-one to make sure everything works properly and be able to isolate offending plugins. +
        • +
        • + In case you are still experiencing issues after applying the fix above, the most likely cause of that is that + the active theme is not compatible with the new version of PHP. In this case too, it is suggested to + deactivate the theme to debug the issue. +
        • +
        + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/recovery.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/recovery.php new file mode 100644 index 0000000..3a24b77 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/recovery.php @@ -0,0 +1,60 @@ + + Recovery URL: is valid. + + The Recovery Point is set but was created hours ago. +

        + In case of an error and subsequent restore all changes created after the restore point will be lost. +

        + + The Recovery Point is not set! + +

        You can continue but in the event you run into an install issue/error you will not be able to restore the current site. In some cases + this might be desirable. For example: +

        +
          +
        • This is a completely blank WordPress site and getting it back is simple.
        • +
        • Losing access to this site is no big deal and you know how to restore things on your own.
        • +
        + + +
        DETAILS
        +

        + Package age: hours +

        +

        + You can + + go back + + go back + + and set a new Recovery Point. +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/replace-paths.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/replace-paths.php new file mode 100644 index 0000000..c552226 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/replace-paths.php @@ -0,0 +1,33 @@ + +

        + The installer will not perform replacements on database PATHs but only on URLs. +

        + +
        DETAILS
        + + +

        + +

        + + +

        + Usually the database does not contain significant references to paths, so you can continue with the installation, + but some plugins may write absolute paths in the database and there may be some malfunctions. +

        + +
        TROUBLESHOOT
        +

        + If you experience any issues after the install you will have to manually replace paths in the database using phpMyAdmin or similar tools. +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/rest-api.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/rest-api.php new file mode 100644 index 0000000..5fa84fe --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/rest-api.php @@ -0,0 +1,64 @@ + +
        STATUS
        + +

        + Successfully did a test REST API call to the WordPress backend. +

        + +

        + REST API call failed with the following message: +

        + + + +
        DETAILS
        +

        + This test makes sure the + WordPress REST API works properly, which is necessary to create new subsites. + +

        + +
        TROUBLESHOOT
        +

        + Some of the possible reasons why the WordPress REST API test might fail are the following: +

        + +
          +
        • + The rest API is disabled on WordPress. + To test whether the REST API works properly please visit the + following address + + and make sure you get a valid JSON output. + In case you don't get a JSON output, please make sure that you have permalinks enabled. Under "Settings" > "Permalinks" the + setting should not be set to "Plain". +
        • +
        • + SSL certificates are expired or invalid. + If this is the case please get in touch with your hosting provider to get everything working and up-to-date. +
        • +
        • + Basic Auth Authentication is enabled. If you have basic auth enabled, please go to + Duplicator ⯠Settings ⯠Packages ⯠Advanced Settings and + set the "Basic Auth" option to enabled and enter the username and password. After saving the settings restart the import process. +
        • +
        • + For more information on the topic please check out the + + REST API FAQ + . +
        • +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/siteground.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/siteground.php new file mode 100644 index 0000000..4428057 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/siteground.php @@ -0,0 +1,34 @@ + +
        STATUS
        +

        + You are installing on a SiteGround server. +

        + +
        DETAILS
        +

        + To overcome errors while extracting ZipArchive on SiteGround Server throttling has been automatically enabled. +

        + +
        TROUBLESHOOT
        +
          +
        • + In case you still get errors during the extraction please try switching the "Extraction Mode" to + "Shell Exec Zip" in Advanced mode under the "Options" section. +
        • +
        • + If the above doesn't work either, please consider creating a new package on the source using the DAF archive format. +
        • +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/timeout.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/timeout.php new file mode 100644 index 0000000..66f8a00 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/timeout.php @@ -0,0 +1,44 @@ +

        + Archive Size: (detection limit is set at )
        + PHP max_execution_time: (zero means not limit)
        + PHP set_time_limit: SuccessFailed +

        +

        + The PHP max_execution_time + setting is used to determine how long a PHP process is allowed to run. + If the setting is too small and the archive file size is too large then PHP may not have enough + time to finish running before the process is killed causing a timeout. +

        +

        + Duplicator attempts to turn off the timeout by using the + set_time_limit setting. + If this notice shows as a warning then it is still safe to continue with the install. + However, if a timeout occurs then you will need to consider working with the max_execution_time setting or extracting the + archive file using the 'Manual Archive Extraction' method.   + + [Additional FAQ Help] + +

        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/tokenizer.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/tokenizer.php new file mode 100644 index 0000000..9aa4202 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/tokenizer.php @@ -0,0 +1,46 @@ + +
        STATUS
        + +

        + The function [token_get_all] exists on your server and can be used. +

        + +

        + The function [token_get_all] is disabled or not present on your server. +

        + + +
        DETAILS
        + +

        + The function [token_get_all] + is part of the tokenizer module + and is required for parsing the contents of the wp-config.php file. + To avoid problems during the installation the handling of the wp-config.php file has been disabled (the setting 'WordPress wp-config.php' + under Advanced Mode > Options > Advanced > Configuration files has been set to 'Do nothing'.) +

        + +
        TROUBLESHOOT
        + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/wordfence/wordfence-detected.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/wordfence/wordfence-detected.php new file mode 100644 index 0000000..9195150 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/wordfence/wordfence-detected.php @@ -0,0 +1,29 @@ + +
        STATUS
        +

        A Wordfence firewall instance was detected at .

        + +
        DETAILS
        +

        + The Wordfence Web Application Firewall is a PHP based, application level firewall that filters out malicious + requests to your site. Sometimes Wordfence returns false positives on requests done during the installation process, + because of which it might fail. +

        + +
        TROUBLESHOOT
        +

        + We recommend turning off the Wordfence firewall of the WordPress instance located at "" + during the installation process and reactivate it after the migration is completed. To deactivate the firewall follow these steps: +

        +
          +
        1. Go to WordPress Admin Dashboard ⯠Wordfence ⯠Firewall and click on the "Manage WAF".
        2. +
        3. Choose Web Application Firewall Status to the "Disabled" option.
        4. +
        5. Click on the "SAVE CHANGES" button and save the changed settings.
        6. +
        7. Wait for the changes to take place
        8. +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/wordfence/wordfence-not-detected.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/wordfence/wordfence-not-detected.php new file mode 100644 index 0000000..ae77dba --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/wordfence/wordfence-not-detected.php @@ -0,0 +1,11 @@ + +
        STATUS
        +

        Having Wordfence in a parent site can interfere with the install, however no such condition was detected.

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/writeable-checks.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/writeable-checks.php new file mode 100644 index 0000000..584e00a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/tests/writeable-checks.php @@ -0,0 +1,138 @@ + +
        STATUS
        + +

        + Some folders do not have write permission, see details for more information. +

        + +

        + Write permissions granted for WordPress core directories. +

        + + +
        DETAILS
        + + + + + + + + + + + + + + + + + + + + + + +
        + Deployment Path: + + getValue(PrmMng::PARAM_PATH_NEW)); ?> +
        + Check folders permission: + + All existing folders have write permissionsSome folders do not have write permissions +
        + PHP files extraction on : + + + Pass + + + +
        + Suhosin Extension: + + DisabledEnabled +
        + PHP Safe Mode: + + DisabledEnabled +
        + + 0) { ?> +

        + Overwrite fails for these folders (change permissions or remove then restart): +

        +
        +
        +
        + + +
        TROUBLESHOOT
        + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validate-area.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validate-area.php new file mode 100644 index 0000000..aacfe3a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validate-area.php @@ -0,0 +1,25 @@ + + +
        +
        + +
        +
        + The system validation checks help to make sure the system is ready for install.
        + During installation the website will be in maintenance mode and not accessible to users. +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validate-noresult.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validate-noresult.php new file mode 100644 index 0000000..7b9a311 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validate-noresult.php @@ -0,0 +1,14 @@ + +
        + + Pending setup validation!
        + Click the validate button to continue... +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-category.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-category.php new file mode 100644 index 0000000..e12ed1f --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-category.php @@ -0,0 +1,31 @@ +getTestsCategory($category); +?> +
        +
        +
        + + +
        +
        +
        + $test)); + } + ?> +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-result.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-result.php new file mode 100644 index 0000000..1d4b62d --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-result.php @@ -0,0 +1,30 @@ + +
        + getHtmlFormParam(PrmMng::PARAM_VALIDATION_SHOW_ALL); ?> +
        + 'General', + 'category' => DUPX_Validation_manager::CAT_GENERAL)); +dupxTplRender('parts/validation/validation-category', array( + 'title' => 'File System', + 'category' => DUPX_Validation_manager::CAT_FILESYSTEM)); +dupxTplRender('parts/validation/validation-category', array( + 'title' => 'PHP config', + 'category' => DUPX_Validation_manager::CAT_PHP)); +dupxTplRender('parts/validation/validation-category', array( + 'title' => 'Database', + 'category' => DUPX_Validation_manager::CAT_DATABASE)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-test.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-test.php new file mode 100644 index 0000000..a7e9089 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/parts/validation/validation-test.php @@ -0,0 +1,31 @@ +display()) { + return; +} + +$validationLevel = PrmMng::getInstance()->getValue(PrmMng::PARAM_VALIDATION_LEVEL); +$open = ($test->test() <= DUPX_Validation_abstract_item::LV_HARD_WARNING && $test->test() <= $validationLevel); +$icon = $open ? 'fa-caret-down' : 'fa-caret-right'; +?> +
        +
        + getTitle()); ?> + +
        +
        + getContent(); ?> +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/dupx-functions.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/dupx-functions.php new file mode 100644 index 0000000..cac0ead --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/dupx-functions.php @@ -0,0 +1,23 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/confirm-dialog.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/confirm-dialog.php new file mode 100644 index 0000000..ac7a39b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/confirm-dialog.php @@ -0,0 +1,74 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-charset.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-charset.php new file mode 100644 index 0000000..7f7786c --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-charset.php @@ -0,0 +1,43 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-install.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-install.php new file mode 100644 index 0000000..b4f43de --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-install.php @@ -0,0 +1,120 @@ + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-test.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-test.php new file mode 100644 index 0000000..4c84f5a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/db-test.php @@ -0,0 +1,109 @@ +getMode() === DUPX_InstallerState::MODE_OVR_INSTALL) { + $overwriteData = $paramsManager->getValue(PrmMng::PARAM_OVERWRITE_SITE_DATA); + $ovr_dbhost = $overwriteData['dbhost']; + $ovr_dbname = $overwriteData['dbname']; + $ovr_dbuser = $overwriteData['dbuser']; + $ovr_dbpass = $overwriteData['dbpass']; +} else { + $ovr_dbhost = ''; + $ovr_dbname = ''; + $ovr_dbuser = ''; + $ovr_dbpass = ''; +} +?> + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/extraction-module.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/extraction-module.php new file mode 100644 index 0000000..b2c27cb --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/extraction-module.php @@ -0,0 +1,169 @@ + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/final-tests.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/final-tests.php new file mode 100644 index 0000000..72f6e0a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/final-tests.php @@ -0,0 +1,116 @@ + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/new-admin-user.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/new-admin-user.php new file mode 100644 index 0000000..7003c07 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/new-admin-user.php @@ -0,0 +1,30 @@ + + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/package-deploy.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/package-deploy.php new file mode 100644 index 0000000..296e075 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/package-deploy.php @@ -0,0 +1,36 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/page-components.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/page-components.php new file mode 100644 index 0000000..91749b8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/page-components.php @@ -0,0 +1,44 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/params-module.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/params-module.php new file mode 100644 index 0000000..431b5c5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/params-module.php @@ -0,0 +1,331 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/progress-bar.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/progress-bar.php new file mode 100644 index 0000000..7363310 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/progress-bar.php @@ -0,0 +1,119 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/site-replace-and-update.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/site-replace-and-update.php new file mode 100644 index 0000000..5ede059 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/site-replace-and-update.php @@ -0,0 +1,97 @@ + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/system-validation-module.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/system-validation-module.php new file mode 100644 index 0000000..fc1edea --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/system-validation-module.php @@ -0,0 +1,60 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/top-page-messages.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/top-page-messages.php new file mode 100644 index 0000000..5aa2778 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/modules/top-page-messages.php @@ -0,0 +1,24 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/secure-init.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/secure-init.php new file mode 100644 index 0000000..4e4f712 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/secure-init.php @@ -0,0 +1,55 @@ + 'ctrl-step1', + DUPX_Security::CTRL_TOKEN => DUPX_CSRF::generate('ctrl-step1'), + PrmMng::PARAM_STEP_ACTION => DUPX_CTRL::ACTION_STEP_INIZIALIZED +); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step1-deploy.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step1-deploy.php new file mode 100644 index 0000000..500fb86 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step1-deploy.php @@ -0,0 +1,22 @@ + 'ctrl-step2', + DUPX_Security::CTRL_TOKEN => DUPX_CSRF::generate('ctrl-step2') +); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step1-init.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step1-init.php new file mode 100644 index 0000000..7897112 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step1-init.php @@ -0,0 +1,339 @@ + + + 'ctrl-step3', + DUPX_Security::CTRL_TOKEN => DUPX_CSRF::generate('ctrl-step3') +); +?> diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step3-init.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step3-init.php new file mode 100644 index 0000000..b89dc08 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step3-init.php @@ -0,0 +1,114 @@ + 'ctrl-step4', + DUPX_Security::CTRL_TOKEN => DUPX_CSRF::generate('ctrl-step4') +); + +dupxTplRender('scripts/modules/new-admin-user'); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step4-init.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step4-init.php new file mode 100644 index 0000000..ed48668 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/default/scripts/step4-init.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/body/body-tag.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/body/body-tag.php new file mode 100644 index 0000000..321c33e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/body/body-tag.php @@ -0,0 +1,11 @@ + + diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/head/css-template-custom.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/head/css-template-custom.php new file mode 100644 index 0000000..36ebec6 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/head/css-template-custom.php @@ -0,0 +1,158 @@ +getValue(PrmMng::PARAM_FROM_SITE_IMPORT_INFO); + +if (isset($importSiteInfo['color-scheme'])) { + $colorScheme = $importSiteInfo['color-scheme']; +} else { + $colorScheme = array(); + $colorScheme['colors'] = array('#222', '#333', '#0073aa', '#00a0d2'); +} +$colorPrimaryButton = isset($importSiteInfo['color-primary-button']) ? $importSiteInfo['color-primary-button'] : $colorScheme->colors[2]; +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/actions/next.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/actions/next.php new file mode 100644 index 0000000..a15c9de --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/actions/next.php @@ -0,0 +1,35 @@ +getValue(PrmMng::PARAM_FROM_SITE_IMPORT_INFO); +$importPage = isset($importSiteInfo['import_page']) ? $importSiteInfo['import_page'] : false; + +?> +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/actions/switch-template.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/actions/switch-template.php new file mode 100644 index 0000000..44a8b68 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/actions/switch-template.php @@ -0,0 +1,25 @@ + +
        + + + + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/info-tabs/restore-backup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/info-tabs/restore-backup.php new file mode 100644 index 0000000..69856c8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/info-tabs/restore-backup.php @@ -0,0 +1,19 @@ + +
        +

        + Site Overwrite Notice +

        +

        + This process will overwrite the entire site you're currently logged into. + All plugins, themes, content and data will be replaced with the content found in the archive file. + The database credentials of the imported site will be used for the database overwrite by default. +

        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/step-title.php new file mode 100644 index 0000000..85b399a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step1/step-title.php @@ -0,0 +1,15 @@ + 'Step 1 of 4: Extract Uploaded Package
        This step will extract package.
        ', + 'showInstallerMode' => false, + 'showSwitchView' => true, + 'showInstallerLog' => true +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step2/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step2/step-title.php new file mode 100644 index 0000000..68acc0e --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step2/step-title.php @@ -0,0 +1,16 @@ + 'Step 2 of 4: ' . + 'Install Database
        This step will install the database from the archive.
        ', + 'showInstallerMode' => false, + 'showSwitchView' => false, + 'showInstallerLog' => true +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step3/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step3/step-title.php new file mode 100644 index 0000000..9fe9756 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step3/step-title.php @@ -0,0 +1,16 @@ + 'Step 3 of 4: ' . + 'Update Data
        This step will update the database and config files to match your new sites values.
        ', + 'showInstallerMode' => false, + 'showSwitchView' => false, + 'showInstallerLog' => true +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step4/actions/recovery-point-button.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step4/actions/recovery-point-button.php new file mode 100644 index 0000000..1e765bb --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step4/actions/recovery-point-button.php @@ -0,0 +1,35 @@ +getValue(PrmMng::PARAM_RECOVERY_LINK); + +if (empty($recoveryLink)) { + return; +} +?> +
        +
        +
        Restore Options
        +
        + +
        + The new import has finished. + Optionally this site can be restored to its previous recovery point by running the recovery wizard. + If no recovery is needed then this option can be ignored. +
        +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step4/main.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step4/main.php new file mode 100644 index 0000000..0c78b4b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/pages-parts/step4/main.php @@ -0,0 +1,15 @@ + 'Step 4 of 4: Import Finished', + 'showInstallerMode' => false, + 'showSwitchView' => false, + 'showInstallerLog' => true +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/parts/top-header.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/parts/top-header.php new file mode 100644 index 0000000..6381767 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-advanced/parts/top-header.php @@ -0,0 +1,8 @@ + +
        STATUS
        +

        A Wordfence firewall instance was detected at .

        + +
        DETAILS
        +

        + The Wordfence Web Application Firewall is a PHP based, application level firewall that filters out malicious + requests to your site. Sometimes Wordfence returns false positives on requests done during the import, because of which + the import might fail. +

        + +
        TROUBLESHOOT
        +

        + If you have Wordfence installed on the current WordPress instance (or the current WordPress instance is located in a + subdirectory of another WordPress instance which has Wordfence installed) we recommend turning it off during the import + and reactivating it after the import is completed. To deactivate the firewall follow these steps: +

        +
          +
        1. Go to WordPress Admin Dashboard ⯠Wordfence ⯠Firewall and click on the "Manage WAF".
        2. +
        3. Choose Web Application Firewall Status to the "Disabled" option.
        4. +
        5. Click on the "SAVE CHANGES" button and save the changed settings.
        6. +
        7. Wait for the changes to take place
        8. +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/actions/switch-template.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/actions/switch-template.php new file mode 100644 index 0000000..8a5ae08 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/actions/switch-template.php @@ -0,0 +1,30 @@ + +
        + + + + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/base-setup.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/base-setup.php new file mode 100644 index 0000000..f7ed732 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/base-setup.php @@ -0,0 +1,15 @@ + +
        + Setup +
        +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/options.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/options.php new file mode 100644 index 0000000..6381767 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step1/options.php @@ -0,0 +1,8 @@ + 'Step 1 of 2: ' . + 'Deploy Uploaded Package
        This step will extract the archive file, install & update the database.
        ', + 'showInstallerMode' => false, + 'showSwitchView' => true, + 'showInstallerLog' => true +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step4/step-title.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step4/step-title.php new file mode 100644 index 0000000..852e84a --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/pages-parts/step4/step-title.php @@ -0,0 +1,15 @@ + 'Step 2 of 2: Import Finished', + 'showInstallerMode' => false, + 'showSwitchView' => false, + 'showInstallerLog' => true +)); diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/parts/top-header.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/parts/top-header.php new file mode 100644 index 0000000..6381767 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/parts/top-header.php @@ -0,0 +1,8 @@ + +
        STATUS
        +

        A Wordfence firewall instance was detected at .

        + +
        DETAILS
        +

        + The Wordfence Web Application Firewall is a PHP based, application level firewall that filters out malicious + requests to your site. Sometimes Wordfence returns false positives on requests done during the import, because of which + the import might fail. +

        + +
        TROUBLESHOOT
        +

        + If you have Wordfence installed on the current WordPress instance (or the current WordPress instance is located in a + subdirectory of another WordPress instance which has Wordfence installed) we recommend turning it off during the import + and reactivating it after the import is completed. To deactivate the firewall follow these steps: +

        +
          +
        1. Go to WordPress Admin Dashboard ⯠Wordfence ⯠Firewall and click on the "Manage WAF".
        2. +
        3. Choose Web Application Firewall Status to the "Disabled" option.
        4. +
        5. Click on the "SAVE CHANGES" button and save the changed settings.
        6. +
        7. Wait for the changes to take place
        8. +
        diff --git a/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/scripts/step1-deploy.php b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/scripts/step1-deploy.php new file mode 100644 index 0000000..36c030b --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/dup-installer/templates/import-base/scripts/step1-deploy.php @@ -0,0 +1,22 @@ + 'ctrl-step4', + DUPX_Security::CTRL_TOKEN => DUPX_CSRF::generate('ctrl-step4') +); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/installer/index.php b/html/wp-content/plugins/duplicator/installer/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/installer/index.php @@ -0,0 +1,3 @@ +setHTTPHeaders(); + $this->targetRoot = self::setSafePath(__DIR__); + // clean log file + $this->log('', true); + + $archive_filepath = $this->getArchiveFilePath(); + $this->origDupInstFolder = self::INSTALLER_DIR_NAME; + $this->targetDupInstFolder = filter_input(INPUT_GET, 'dup_folder', FILTER_SANITIZE_SPECIAL_CHARS, array( + "options" => array( + "default" => self::INSTALLER_DIR_NAME, + ), + 'flags' => FILTER_FLAG_STRIP_HIGH)); + + $this->isCustomDupFolder = $this->origDupInstFolder !== $this->targetDupInstFolder; + $this->targetDupInst = $this->targetRoot . '/' . $this->targetDupInstFolder; + $this->manualExtractFileName = 'dup-manual-extract__' . self::PACKAGE_HASH; + + if ($this->isCustomDupFolder) { + $this->extractionTmpFolder = $this->getTempDir($this->targetRoot); + } else { + $this->extractionTmpFolder = $this->targetRoot; + } + + DUPX_CSRF::init($this->targetDupInst, self::PACKAGE_HASH); + + //ARCHIVE_SIZE will be blank with a root filter so we can estimate + //the default size of the package around 17.5MB (18088000) + $archiveActualSize = @file_exists($archive_filepath) ? @filesize($archive_filepath) : false; + $archiveActualSize = ($archiveActualSize !== false) ? $archiveActualSize : 0; + $this->hasZipArchive = class_exists('ZipArchive'); + $this->hasShellExecUnzip = $this->getUnzipFilePath() != null ? true : false; + $this->archiveExpectedSize = strlen(self::ARCHIVE_SIZE) ? self::ARCHIVE_SIZE : 0; + $this->archiveActualSize = $archiveActualSize; + + if ($this->archiveExpectedSize > 0) { + $this->archiveRatio = (((1.0) * $this->archiveActualSize) / $this->archiveExpectedSize) * 100; + } else { + $this->archiveRatio = 100; + } + } + + /** + * + * @return self + */ + public static function getInstance() + { + if (is_null(self::$instance)) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Makes sure no caching mechanism is used during install + * + * @return void + */ + private function setHTTPHeaders() + { + header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + } + + /** + * Return temp dir + * + * @param string $path path string + * + * @return boolean|string + */ + private function getTempDir($path) + { + $tempfile = tempnam($path, 'dup-installer_tmp_'); + if (file_exists($tempfile)) { + unlink($tempfile); + mkdir($tempfile); + if (is_dir($tempfile)) { + return $tempfile; + } + } + return false; + } + + /** + * Check php version + * + * @return void + */ + public static function phpVersionCheck() + { + if (version_compare(PHP_VERSION, self::MINIMUM_PHP_VERSION, '>=')) { + return true; + } + + $match = null; + if (preg_match("#^\d+(\.\d+)*#", PHP_VERSION, $match)) { + $phpVersion = $match[0]; + } else { + $phpVersion = PHP_VERSION; + } + ?> + + + + + Duplicator - issue + + +
        +

        DUPLICATOR ISSUE: PHP REQUIRED

        +

        + This server is running PHP: . A minimum of PHP + is required.

        + Contact your hosting provider or server administrator and let them know you would like to upgrade your PHP version. +

        +
        + + + log('==DUPLICATOR INSTALLER BOOTSTRAP v' . self::VERSION . '=='); + $this->log('----------------------------------------------------'); + $this->log('Installer bootstrap start'); + + $archive_filepath = $this->getArchiveFilePath(); + $archive_filename = self::ARCHIVE_FILENAME; + + $error = null; + + $is_installer_file_valid = true; + if (preg_match('/_([a-z0-9]{7})[a-z0-9]+_[0-9]{6}([0-9]{8})_archive.(?:zip|daf)$/', $archive_filename, $matches)) { + $expected_package_hash = $matches[1] . '-' . $matches[2]; + if (self::PACKAGE_HASH != $expected_package_hash) { + $is_installer_file_valid = false; + $this->log("[ERROR] Installer and archive mismatch detected."); + } + } else { + $this->log("[ERROR] Invalid archive file name."); + $is_installer_file_valid = false; + } + + if (false === $is_installer_file_valid) { + $error = "Installer and archive mismatch detected. + Ensure uncorrupted installer and matching archive are present."; + return $error; + } + + $extract_installer = true; + $extract_success = false; + $archiveExpectedEasy = $this->readableByteSize($this->archiveExpectedSize); + $archiveActualEasy = $this->readableByteSize($this->archiveActualSize); + + //$archive_extension = strtolower(pathinfo($archive_filepath)['extension']); + $archive_extension = strtolower(pathinfo($archive_filepath, PATHINFO_EXTENSION)); + $installer_dir_found = ( + file_exists($this->targetDupInst) && + file_exists($this->targetDupInst . "/main.installer.php") && + file_exists($this->targetDupInst . "/dup-archive__" . self::PACKAGE_HASH . ".txt") + ); + + $manual_extract_found = ( + $installer_dir_found && + file_exists($this->targetDupInst . "/" . $this->manualExtractFileName) + ); + + $isZip = ($archive_extension == 'zip'); + + //MANUAL EXTRACTION NOT FOUND + if (!$manual_extract_found) { + //MISSING ARCHIVE FILE + if (!file_exists($archive_filepath)) { + $this->log("[ERROR] Archive file not found!"); + $archive_candidates = ($isZip) ? $this->getFilesWithExtension('zip') : $this->getFilesWithExtension('daf'); + $candidate_count = count($archive_candidates); + $candidate_html = "- No {$archive_extension} files found -"; + + if ($candidate_count >= 1) { + $candidate_html = "
          "; + foreach ($archive_candidates as $archive_candidate) { + $candidate_html .= '
        1. ' . $this->compareStrings($archive_filename, $archive_candidate) . '
        2. '; + } + $candidate_html .= "
        "; + } + + $error = "" + . "Archive not found! The required archive file must be present in the 'Extraction Path' below. " + . "When the archive file name was created it was named with a secure file name. This file name must be " + . "the exact same name as when it was created character for character. Each archive file has a unique installer associated " + . "with it and must be used together. See the list below for more options:
        " + . ""; + + return $error; + } + + $archive_size = self::ARCHIVE_SIZE; + + // Sometimes the self::ARCHIVE_SIZE is ''. + if (!empty($archive_size) && !self::checkInputValidInt(self::ARCHIVE_SIZE)) { + $no_of_bits = PHP_INT_SIZE * 8; + $error = 'Current is a ' . $no_of_bits . '-bit SO. This archive is too large for ' . $no_of_bits . '-bit PHP.' . '
        '; + $this->log('[ERROR] ' . $error); + $error .= 'Possibibles solutions:
        '; + $error .= '- Use the file filters to get your package lower to support this server or try the package on a Linux server.' . '
        '; + $error .= '- Perform a ' . + 'Manual Extract Install' . '
        '; + + switch ($no_of_bits == 32) { + case 32: + $error .= '- Ask your host to upgrade the server to 64-bit PHP or install on another system has 64-bit PHP' . '
        '; + break; + case 64: + $error .= '- Ask your host to upgrade the server to 128-bit PHP or install on another system has 128-bit PHP' . '
        '; + break; + } + + if (self::isWindows()) { + $error .= '- ' . + 'Windows DupArchive extractor to extract all files from the archive.' . '
        '; + } + + return $error; + } + + //SIZE CHECK ERROR + if (($this->archiveRatio < 90) && ($this->archiveActualSize > 0) && ($this->archiveExpectedSize > 0)) { + $this->log( + "ERROR: The expected archive size should be around [{$archiveExpectedEasy}]. " . + "The actual size is currently [{$archiveActualEasy}]." + ); + $this->log("ERROR: The archive file may not have fully been downloaded to the server"); + $percent = round($this->archiveRatio); + + $autochecked = isset($_POST['auto-fresh']) ? "checked='true'" : ''; + $error = "Archive file size warning.
        The expected archive size is [{$archiveExpectedEasy}]. " + . "Currently the archive size is [{$archiveActualEasy}].
        " + . "The archive file may have not fully been uploaded to the server." + . "
          " + . "
        • Download the whole archive from the source website (open WordPress Admin > Duplicator > Packages) " + . "and validate that the file size is close to the expected size.
        • " + . "
        • Make sure to upload the whole archive file to the destination server.
        • " + . "
        • If the archive file is still uploading then please refresh this page to get an update on the currently uploaded file size.
        • " + . "
        "; + return $error; + } + } + + if ($installer_dir_found) { + // INSTALL DIRECTORY: Check if its setup correctly AND we are not in overwrite mode + if (($extract_installer = filter_input(INPUT_GET, 'force-extract-installer', FILTER_VALIDATE_BOOLEAN))) { + $this->log("Manual extract found with force extract installer get parametr"); + } else { + $this->log("Manual extract found so not going to extract " . $this->targetDupInstFolder . " dir"); + } + } else { + $extract_installer = true; + } + + // if ($extract_installer && file_exists($this->targetDupInst)) { + if (file_exists($this->targetDupInst)) { + $this->log("EXTRACT " . $this->targetDupInstFolder . " dir"); + $hash_pattern = '[a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'; + $file_patterns_with_hash_file = array( + // file pattern => hash file + 'dup-archive__' . $hash_pattern . '.txt' => 'dup-archive__' . self::PACKAGE_HASH . '.txt', + 'dup-database__' . $hash_pattern . '.sql' => 'dup-database__' . self::PACKAGE_HASH . '.sql', + 'dup-installer-data__' . $hash_pattern . '.sql' => 'dup-installer-data__' . self::PACKAGE_HASH . '.sql', + 'dup-installer-log__' . $hash_pattern . '.txt' => 'dup-installer-log__' . self::PACKAGE_HASH . '.txt', + 'dup-scan__' . $hash_pattern . '.json' => 'dup-scan__' . self::PACKAGE_HASH . '.json', + 'dup-scanned-dirs__' . $hash_pattern . '.txt' => 'dup-scanned-dirs__' . self::PACKAGE_HASH . '.txt', + 'dup-scanned-files__' . $hash_pattern . '.txt' => 'dup-scanned-files__' . self::PACKAGE_HASH . '.txt', + ); + foreach ($file_patterns_with_hash_file as $file_pattern => $hash_file) { + $globs = glob($this->targetDupInst . '/' . $file_pattern); + if (!empty($globs)) { + foreach ($globs as $glob) { + $file = basename($glob); + if ($file != $hash_file) { + if (unlink($glob)) { + $this->log('Successfully deleted the file ' . $glob); + } else { + $error .= '[ERROR] Error deleting the file ' . $glob . ' Please manually delete it and try again.'; + $this->log($error); + } + } + } + } + } + } + + //ATTEMPT EXTRACTION: + //ZipArchive and Shell Exec + if ($extract_installer) { + $this->log("Ready to extract the installer"); + + $this->log("Checking permission of destination folder"); + $destination = $this->targetRoot; + if (!is_writable($destination)) { + $this->log("destination folder for extraction is not writable"); + if (self::chmod($destination, 'u+rwx')) { + $this->log("Permission of destination folder changed to u+rwx"); + } else { + $this->log("[ERROR] Permission of destination folder failed to change to u+rwx"); + } + } + + if (!is_writable($destination)) { + $this->log("WARNING: The {$destination} directory is not writable."); + $error = "NOTICE: The {$destination} directory is not writable on this server please talk to your host or server admin about making "; + $error .= "" . + "writable {$destination} directory on this server.
        "; + return $error; + } + + if ($isZip) { + $zip_mode = $this->getZipMode(); + + if (($zip_mode == self::ZIP_MODE_AUTO) || ($zip_mode == self::ZIP_MODE_ARCHIVE) && class_exists('ZipArchive')) { + if ($this->hasZipArchive) { + $this->log("ZipArchive exists so using that"); + $extract_success = $this->extractInstallerZipArchive($archive_filepath, $this->origDupInstFolder, $this->extractionTmpFolder); + + if ($extract_success) { + $this->log('Successfully extracted with ZipArchive'); + } else { + if (0 == $this->installer_files_found) { + $error = "[ERROR] This archive is not properly formatted and does not contain a " . $this->origDupInstFolder . + " directory. Please make sure you are attempting to install " . + "the original archive and not one that has been reconstructed."; + $this->log($error); + return $error; + } else { + $error = '[ERROR] Error extracting with ZipArchive. '; + $this->log($error); + } + } + } else { + $this->log("WARNING: ZipArchive is not enabled."); + $error = "NOTICE: ZipArchive is not enabled on this server please talk to your host or server admin about enabling "; + $error .= "" . + "ZipArchive on this server.
        "; + } + } + + if (!$extract_success) { + if (($zip_mode == self::ZIP_MODE_AUTO) || ($zip_mode == self::ZIP_MODE_SHELL)) { + $unzip_filepath = $this->getUnzipFilePath(); + if ($unzip_filepath != null) { + $extract_success = $this->extractInstallerShellexec($archive_filepath, $this->origDupInstFolder, $this->extractionTmpFolder); + $this->log("Resetting perms of items in folder {$this->targetDupInstFolder}"); + self::setPermsToDefaultR($this->targetDupInstFolder); + if ($extract_success) { + $this->log('Successfully extracted with Shell Exec'); + $error = null; + } else { + $error .= '[ERROR] Error extracting with Shell Exec. ' . + 'Please manually extract archive then choose Advanced > Manual Extract in installer.'; + $this->log($error); + } + } else { + $this->log('WARNING: Shell Exec Zip is not available'); + $error .= "NOTICE: Shell Exec is not enabled on this server please talk to your host or server admin about enabling "; + $error .= "Shell Exec " . + "on this server or manually extract archive then choose Advanced > Manual Extract in installer."; + } + } + } + + // If both ZipArchive and ShellZip are not available, Error message should be combined for both + if (!$extract_success && $zip_mode == self::ZIP_MODE_AUTO) { + $unzip_filepath = $this->getUnzipFilePath(); + if (!class_exists('ZipArchive') && empty($unzip_filepath)) { + $this->log("WARNING: ZipArchive and Shell Exec are not enabled on this server."); + $error = "NOTICE: ZipArchive and Shell Exec are not enabled on this server please " . + "talk to your host or server admin about enabling "; + $error .= "ZipArchive " . + "or Shell Exec " . + "on this server or manually extract archive then choose Advanced > Manual Extract in installer."; + } + } + } else { + try { + DupArchiveExpandBasicEngine::setCallbacks( + array($this, 'log'), + array($this, 'chmod'), + array($this, 'mkdir') + ); + $offset = DupArchiveExpandBasicEngine::getExtraOffset($archive_filepath); + $this->log('Expand directory from offset ' . $offset); + DupArchiveExpandBasicEngine::expandDirectory( + $archive_filepath, + $this->origDupInstFolder, + $this->extractionTmpFolder, + false, + $offset + ); + //In case of DupArchive just remove the manual extract check file + @unlink($this->extractionTmpFolder . "/" . $this->origDupInstFolder . "/" . $this->manualExtractFileName); + } catch (Exception $ex) { + $this->log("[ERROR] Error expanding installer subdirectory:" . $ex->getMessage()); + throw $ex; + } + } + + if ($this->isCustomDupFolder) { + $this->log("Move dup-installer folder to custom folder:" . $this->targetDupInst); + if (file_exists($this->targetDupInst)) { + $this->log('Custom folder already exists so delete it'); + if (self::rrmdir($this->targetDupInst) == false) { + throw new Exception('Can\'t remove custom target folder'); + } + } + if (rename($this->extractionTmpFolder . '/' . $this->origDupInstFolder, $this->targetDupInst) === false) { + throw new Exception('Can\'t rename the tmp dup-installer folder'); + } + } + + $htaccessToRemove = $this->targetDupInst.'/.htaccess'; + if (is_file($htaccessToRemove) && is_writable($htaccessToRemove)) { + $this->log("Remove Htaccess in dup-installer folder"); + @unlink($htaccessToRemove); + } + + $is_apache = (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false || strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false); + $is_nginx = (strpos($_SERVER['SERVER_SOFTWARE'], 'nginx') !== false); + + $sapi_type = php_sapi_name(); + $php_ini_data = array( + 'max_execution_time' => 3600, + 'max_input_time' => -1, + 'ignore_user_abort' => 'On', + 'post_max_size' => '4096M', + 'upload_max_filesize' => '4096M', + 'memory_limit' => DUPLICATOR_PHP_MAX_MEMORY, + 'default_socket_timeout' => 3600, + 'pcre.backtrack_limit' => 99999999999, + ); + $sapi_type_first_three_chars = substr($sapi_type, 0, 3); + if ('fpm' === $sapi_type_first_three_chars) { + $this->log("SAPI: FPM"); + if ($is_apache) { + $this->log('Server: Apache'); + } elseif ($is_nginx) { + $this->log('Server: Nginx'); + } + + if (($is_apache && function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) || $is_nginx) { + $htaccess_data = array(); + foreach ($php_ini_data as $php_ini_key => $php_ini_val) { + if ($is_apache) { + $htaccess_data[] = 'SetEnv PHP_VALUE "' . $php_ini_key . ' = ' . $php_ini_val . '"'; + } elseif ($is_nginx) { + if ('On' == $php_ini_val || 'Off' == $php_ini_val) { + $htaccess_data[] = 'php_flag ' . $php_ini_key . ' ' . $php_ini_val; + } else { + $htaccess_data[] = 'php_value ' . $php_ini_key . ' ' . $php_ini_val; + } + } + } + + $htaccess_text = implode("\n", $htaccess_data); + $htaccess_file_path = $this->targetDupInst . '/.htaccess'; + $this->log("creating {$htaccess_file_path} with the content:"); + $this->log($htaccess_text); + @file_put_contents($htaccess_file_path, $htaccess_text); + } + } elseif ('cgi' === $sapi_type_first_three_chars || 'litespeed' === $sapi_type) { + if ('cgi' === $sapi_type_first_three_chars) { + $this->log("SAPI: CGI"); + } else { + $this->log("SAPI: litespeed"); + } + if (version_compare(phpversion(), 5.5) >= 0 && (!$is_apache || 'litespeed' === $sapi_type)) { + $ini_data = array(); + foreach ($php_ini_data as $php_ini_key => $php_ini_val) { + $ini_data[] = $php_ini_key . ' = ' . $php_ini_val; + } + $ini_text = implode("\n", $ini_data); + $ini_file_path = $this->targetDupInst . '/.user.ini'; + $this->log("creating {$ini_file_path} with the content:"); + $this->log($ini_text); + @file_put_contents($ini_file_path, $ini_text); + } else { + $this->log("No need to create " . $this->targetDupInstFolder . "/.htaccess or " . $this->targetDupInstFolder . "/.user.ini"); + } + } elseif ("apache2handler" === $sapi_type) { + $this->log("No need to create " . $this->targetDupInstFolder . "/.htaccess or " . $this->targetDupInstFolder . "/.user.ini"); + $this->log("SAPI: apache2handler"); + } + else { + $this->log("No need to create " . $this->targetDupInstFolder . "/.htaccess or " . $this->targetDupInstFolder . "/.user.ini"); + $this->log("ERROR: SAPI: Unrecognized"); + } + } else { + $this->log("NOTICE: Didn't need to extract the installer."); + } + + if (empty($error)) { + if ($this->isCustomDupFolder && file_exists($this->extractionTmpFolder)) { + rmdir($this->extractionTmpFolder); + } + + $config_files = glob($this->targetDupInst . '/dup-archive__*.txt'); + $config_file_absolute_path = array_pop($config_files); + if (!file_exists($config_file_absolute_path)) { + $error = 'Archive config file not found in ' . $this->targetDupInstFolder . ' folder.

        '; + return $error; + } + } + + $uri_start = self::getCurrentUrl(false, false, 1); + if ($error === null) { + if (!file_exists($this->targetDupInst)) { + $error = 'Can\'t extract installer directory. ' . + 'See this FAQ item' . + ' for details on how to resolve.'; + } + + if ($error == null) { + $bootloader_name = basename(__FILE__); + $this->mainInstallerURL = $uri_start . '/' . $this->targetDupInstFolder . '/main.installer.php'; + + $this->archive = $archive_filepath; + $this->bootloader = $bootloader_name; + + $this->fixInstallerPerms($this->mainInstallerURL); + // $this->mainInstallerURL = $this->mainInstallerURL . "?archive=$encoded_archive_path&bootloader=$bootloader_name&ctrl_action=ctrl-step1"; + /* + if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) { + $this->mainInstallerURL .= '?'.$_SERVER['QUERY_STRING']; + }*/ + + $this->log("DONE: No detected errors so redirecting to the main installer. Main Installer URI = {$this->mainInstallerURL}"); + } + } + + return $error; + } + + /** + * Get current url + * + * @param bool $queryString If true the query string will also be returned. + * @param bool $requestUri if true check request uri + * @param int $getParentDirLevel if 0 get current script name or parent folder, if 1 parent folder if 2 parent of parent folder ... + * + * @return void + */ + public static function getCurrentUrl($queryString = true, $requestUri = false, $getParentDirLevel = 0) + { + // *** HOST + if (isset($_SERVER['HTTP_X_ORIGINAL_HOST'])) { + $host = $_SERVER['HTTP_X_ORIGINAL_HOST']; + } else { + $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']; //WAS SERVER_NAME and caused problems on some boxes + } + + // *** PROTOCOL + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $_SERVER ['HTTPS'] = 'on'; + } + if (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'https') { + $_SERVER ['HTTPS'] = 'on'; + } + if (isset($_SERVER['HTTP_CF_VISITOR'])) { + $visitor = json_decode($_SERVER['HTTP_CF_VISITOR']); + if ($visitor->scheme == 'https') { + $_SERVER ['HTTPS'] = 'on'; + } + } + $protocol = 'http' . ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on') ? 's' : ''); + + if ($requestUri) { + $serverUrlSelf = preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI']); + } else { + // *** SCRIPT NAME + $serverUrlSelf = $_SERVER['SCRIPT_NAME']; + for ($i = 0; $i < $getParentDirLevel; $i++) { + $serverUrlSelf = preg_match('/^[\\\\\/]?$/', dirname($serverUrlSelf)) ? '' : dirname($serverUrlSelf); + } + } + + // *** QUERY STRING + $query = ($queryString && isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 ) ? '?' . $_SERVER['QUERY_STRING'] : ''; + + return $protocol . '://' . $host . $serverUrlSelf . $query; + } + + /** + * Attempts to set the 'dup-installer' directory permissions + * + * @return null + */ + private function fixInstallerPerms() + { + $file_perms = 'u+rw'; + $dir_perms = 'u+rwx'; + + $installer_dir_path = $this->targetDupInstFolder; + + $this->setPerms($installer_dir_path, $dir_perms, false); + $this->setPerms($installer_dir_path, $file_perms, true); + } + + /** + * Set the permissions of a given directory and optionally all files + * + * @param string $directory The full path to the directory where perms will be set + * @param string $perms The given permission sets to use such as '0755' or 'u+rw' + * @param string $do_files Also set the permissions of all the files in the directory + * + * @return null + */ + private function setPerms($directory, $perms, $do_files) + { + if (!$do_files) { + // If setting a directory hiearchy be sure to include the base directory + $this->setPermsOnItem($directory, $perms); + } + + $item_names = array_diff(scandir($directory), array('.', '..')); + + foreach ($item_names as $item_name) { + $path = "$directory/$item_name"; + if (($do_files && is_file($path)) || (!$do_files && !is_file($path))) { + $this->setPermsOnItem($path, $perms); + } + } + } + + /** + * Set the permissions of a single directory or file + * + * @param string $path The full path to the directory or file where perms will be set + * @param string $perms The given permission sets to use such as '0755' or 'u+rw' + * + * @return bool Returns true if the permission was properly set + */ + private function setPermsOnItem($path, $perms) + { + if (($result = self::chmod($path, $perms)) === false) { + $this->log("ERROR: Couldn't set permissions of $path
        "); + } else { + $this->log("Set permissions of $path
        "); + } + return $result; + } + + /** + * Compare two strings and return html text which represts diff + * + * @param string $oldString old string + * @param string $newString new string + * + * @return string Returns html text + */ + private function compareStrings($oldString, $newString) + { + $ret = ''; + for ($i = 0; isset($oldString[$i]) || isset($newString[$i]); $i++) { + if (!isset($oldString[$i])) { + $ret .= '' . $newString[$i] . ''; + continue; + } + for ($char = 0; isset($oldString[$i][$char]) || isset($newString[$i][$char]); $char++) { + if (!isset($oldString[$i][$char])) { + $ret .= '' . substr($newString[$i], $char) . ''; + break; + } elseif (!isset($newString[$i][$char])) { + break; + } + + if (ord($oldString[$i][$char]) != ord($newString[$i][$char])) { + $ret .= '' . $newString[$i][$char] . ''; + } else { + $ret .= $newString[$i][$char]; + } + } + } + return $ret; + } + + /** + * Logs a string to the dup-installer-bootlog__[HASH].txt file + * + * @param string $s The string to log to the log file + * @param bool $deleteOld if true delete old file + * + * @return boog|int This function returns the number of bytes that were written to the file, or FALSE on failure. + */ + public function log($s, $deleteOld = false) + { + static $logfile = null; + if (is_null($logfile)) { + $logfile = $this->getBootLogFilePath(); + } + if ($deleteOld && file_exists($logfile)) { + @unlink($logfile); + } + $timestamp = date('M j H:i:s'); + return @file_put_contents($logfile, '[' . $timestamp . '] ' . self::postprocessLog($s) . "\n", FILE_APPEND); + } + + /** + * get boot log file name the dup-installer-bootlog__[HASH].txt file + * + * @return string + */ + public function getBootLogFilePath() + { + return $this->targetRoot . '/dup-installer-bootlog__' . self::SECONDARY_PACKAGE_HASH . '.txt'; + } + + /** + * Post process log and remove hash string + * + * @param string $str string + * + * @return string + */ + protected static function postprocessLog($str) + { + return str_replace(array( + self::getArchiveFileHash(), + self::PACKAGE_HASH, + self::SECONDARY_PACKAGE_HASH + ), '[HASH]', $str); + } + + /** + * Return archive file hash + * + * @return string + */ + public static function getArchiveFileHash() + { + static $fileHash = null; + if (is_null($fileHash)) { + $fileHash = preg_replace('/^.+_([a-z0-9]+)_[0-9]{14}_archive\.(?:daf|zip)$/', '$1', self::ARCHIVE_FILENAME); + } + return $fileHash; + } + + /** + * Extraxt installer + * + * @param string $archive_filepath The path to the archive file. + * @param string $origDupInstFolder relative folder in archive + * @param string $destination destination folder + * @param bool $checkSubFolder check if is in subfolder + * + * @return bool Returns true if the data was properly extracted + */ + private function extractInstallerZipArchive($archive_filepath, $origDupInstFolder, $destination, $checkSubFolder = false) + { + $success = true; + $zipArchive = new ZipArchive(); + $subFolderArchiveList = array(); + + if (($zipOpenRes = $zipArchive->open($archive_filepath)) === true) { + $this->log("Successfully opened archive file."); + $folder_prefix = $origDupInstFolder . '/'; + $this->log("Extracting all files from archive within " . $origDupInstFolder); + + $installer_files_found = 0; + + for ($i = 0; $i < $zipArchive->numFiles; $i++) { + $stat = $zipArchive->statIndex($i); + if ($checkSubFolder == false) { + $filenameCheck = $stat['name']; + $filename = $stat['name']; + $tmpSubFolder = null; + } else { + $safePath = rtrim(self::setSafePath($stat['name']), '/'); + $tmpArray = explode('/', $safePath); + + if (count($tmpArray) < 2) { + continue; + } + + $tmpSubFolder = $tmpArray[0]; + array_shift($tmpArray); + $filenameCheck = implode('/', $tmpArray); + $filename = $stat['name']; + } + + + if ($this->startsWith($filenameCheck, $folder_prefix)) { + $installer_files_found++; + + if (!empty($tmpSubFolder) && !in_array($tmpSubFolder, $subFolderArchiveList)) { + $subFolderArchiveList[] = $tmpSubFolder; + } + + if (basename($filename) === $this->manualExtractFileName) { + $this->log("Skipping manual extract file: {$filename}"); + continue; + } + + if ($zipArchive->extractTo($destination, $filename) === true) { + $this->log("Success: {$filename} >>> {$destination}"); + } else { + $this->log("[ERROR] Error extracting {$filename} from archive archive file"); + $success = false; + break; + } + } + } + + if ($checkSubFolder && count($subFolderArchiveList) !== 1) { + $this->log("Error: Multiple dup subfolder archive"); + $success = false; + } else { + if ($checkSubFolder) { + $this->moveUpfromSubFolder($destination . '/' . $subFolderArchiveList[0], true); + } + + $lib_directory = $destination . '/' . $origDupInstFolder . '/lib'; + $snaplib_directory = $lib_directory . '/snaplib'; + + // If snaplib files aren't present attempt to extract and copy those + if (!file_exists($snaplib_directory)) { + $folder_prefix = 'snaplib/'; + $destination = $lib_directory; + + for ($i = 0; $i < $zipArchive->numFiles; $i++) { + $stat = $zipArchive->statIndex($i); + $filename = $stat['name']; + + if ($this->startsWith($filename, $folder_prefix)) { + $installer_files_found++; + + if ($zipArchive->extractTo($destination, $filename) === true) { + $this->log("Success: {$filename} >>> {$destination}"); + } else { + $this->log("[ERROR] Error extracting {$filename} from archive archive file"); + $success = false; + break; + } + } + } + } + } + + if ($zipArchive->close() === true) { + $this->log("Successfully closed archive file"); + } else { + $this->log("[ERROR] Problem closing archive file"); + $success = false; + } + + if ($success != false && $installer_files_found < 10) { + if ($checkSubFolder) { + $this->log("[ERROR] Couldn't find the installer directory in the archive!"); + $success = false; + } else { + $this->log("[ERROR] Couldn't find the installer directory in archive root! Check subfolder"); + $this->extractInstallerZipArchive($archive_filepath, $origDupInstFolder, $destination, true); + } + } + } else { + $this->log("[ERROR] Couldn't open archive archive file with ZipArchive CODE[" . $zipOpenRes . "]"); + $success = false; + } + + return $success; + } + + /** + * return true if current SO is windows + * + * @staticvar bool $isWindows + * @return bool + */ + public static function isWindows() + { + static $isWindows = null; + if (is_null($isWindows)) { + $isWindows = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); + } + return $isWindows; + } + + /** + * return current SO path path len + * @staticvar int $maxPath + * @return int + */ + public static function maxPathLen() + { + static $maxPath = null; + if (is_null($maxPath)) { + if (defined('PHP_MAXPATHLEN')) { + $maxPath = PHP_MAXPATHLEN; + } else { + // for PHP < 5.3.0 + $maxPath = self::isWindows() ? 260 : 4096; + } + } + return $maxPath; + } + + /** + * @param string $directory Path for folder to set perms + * + * @return void + */ + public static function setPermsToDefaultR($directory) + { + $dir = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS); + $iterator = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST); + // Default permissions + $defaultFilePermission = 0666 & ~umask(); + $defaultDirPermission = 0777 & ~umask(); + + foreach ($iterator as $item) { + if ($item->isFile()) { + self::chmod($item->getPathname(), $defaultFilePermission); + } + + if ($item->isDir()) { + self::chmod($item->getPathname(), $defaultDirPermission); + } + } + } + + /** + * this function make a chmod only if the are different from perms input and if chmod function is enabled + * + * this function handles the variable MODE in a way similar to the chmod of lunux + * So the MODE variable can be + * 1) an octal number (0755) + * 2) a string that defines an octal number ("644") + * 3) a string with the following format [ugoa]*([-+=]([rwx]*)+ + * + * examples + * u+rw add read and write at the user + * u+rw,uo-wx add read and write ad the user and remove wx at groupd and other + * a=rw is equal at 666 + * u=rwx,go-rwx is equal at 700 + * + * @param string $file file path + * @param int|string $mode mode + * + * @return boolean + */ + public static function chmod($file, $mode) + { + if (!file_exists($file)) { + return false; + } + + $octalMode = 0; + + if (is_int($mode)) { + $octalMode = $mode; + } elseif (is_string($mode)) { + $mode = trim($mode); + if (preg_match('/([0-7]{1,3})/', $mode)) { + $octalMode = intval(('0' . $mode), 8); + } elseif (preg_match_all('/(a|[ugo]{1,3})([-=+])([rwx]{1,3})/', $mode, $gMatch, PREG_SET_ORDER)) { + if (!function_exists('fileperms')) { + return false; + } + + // start by file permission + $octalMode = (fileperms($file) & 0777); + + foreach ($gMatch as $matches) { + // [ugo] or a = ugo + $group = $matches[1]; + if ($group === 'a') { + $group = 'ugo'; + } + // can be + - = + $action = $matches[2]; + // [rwx] + $gPerms = $matches[3]; + + // reset octal group perms + $octalGroupMode = 0; + + // Init sub perms + $subPerm = 0; + $subPerm += strpos($gPerms, 'x') !== false ? 1 : 0; // mask 001 + $subPerm += strpos($gPerms, 'w') !== false ? 2 : 0; // mask 010 + $subPerm += strpos($gPerms, 'r') !== false ? 4 : 0; // mask 100 + + $ugoLen = strlen($group); + + if ($action === '=') { + // generate octal group permsissions and ugo mask invert + $ugoMaskInvert = 0777; + for ($i = 0; $i < $ugoLen; $i++) { + switch ($group[$i]) { + case 'u': + $octalGroupMode = $octalGroupMode | $subPerm << 6; // mask xxx000000 + $ugoMaskInvert = $ugoMaskInvert & 077; + break; + case 'g': + $octalGroupMode = $octalGroupMode | $subPerm << 3; // mask 000xxx000 + $ugoMaskInvert = $ugoMaskInvert & 0707; + break; + case 'o': + $octalGroupMode = $octalGroupMode | $subPerm; // mask 000000xxx + $ugoMaskInvert = $ugoMaskInvert & 0770; + break; + } + } + // apply = action + $octalMode = $octalMode & ($ugoMaskInvert | $octalGroupMode); + } else { + // generate octal group permsissions + for ($i = 0; $i < $ugoLen; $i++) { + switch ($group[$i]) { + case 'u': + $octalGroupMode = $octalGroupMode | $subPerm << 6; // mask xxx000000 + break; + case 'g': + $octalGroupMode = $octalGroupMode | $subPerm << 3; // mask 000xxx000 + break; + case 'o': + $octalGroupMode = $octalGroupMode | $subPerm; // mask 000000xxx + break; + } + } + // apply + or - action + switch ($action) { + case '+': + $octalMode = $octalMode | $octalGroupMode; + break; + case '-': + $octalMode = $octalMode & ~$octalGroupMode; + break; + } + } + } + } + } + + // if input permissions are equal at file permissions return true without performing chmod + if (function_exists('fileperms') && $octalMode === (fileperms($file) & 0777)) { + return true; + } + + if (!function_exists('chmod')) { + return false; + } + + return @chmod($file, $octalMode); + } + + /** + * Check if input is valid int + * + * @param mixed $input input string or number + * + * @return bool + */ + public static function checkInputValidInt($input) + { + return (filter_var($input, FILTER_VALIDATE_INT) === 0 || filter_var($input, FILTER_VALIDATE_INT)); + } + + /** + * this function creates a folder if it does not exist and performs a chmod. + * it is different from the normal mkdir function to which an umask is applied to the input permissions. + * + * this function handles the variable MODE in a way similar to the chmod of lunux + * So the MODE variable can be + * 1) an octal number (0755) + * 2) a string that defines an octal number ("644") + * 3) a string with the following format [ugoa]*([-+=]([rwx]*)+ + * + * @param string $path folder path + * @param int|string $mode mode permissions + * @param bool $recursive Allows the creation of nested directories specified in the pathname. Default to false. + * @param resource $context not used for windows bug + * + * @return boolean bool TRUE on success or FALSE on failure. + * + * @todo check recursive true and multiple chmod + */ + public static function mkdir($path, $mode = 0777, $recursive = false, $context = null) + { + if (strlen($path) > self::maxPathLen()) { + throw new Exception('Skipping a file that exceeds allowed max path length [' . self::maxPathLen() . ']. File: ' . $filepath); + } + + if (!file_exists($path)) { + if (!function_exists('mkdir')) { + return false; + } + if (!@mkdir($path, 0777, $recursive)) { + return false; + } + } + + return self::chmod($path, $mode); + } + + /** + * move all folder content up to parent + * + * @param string $subFolderName full path + * @param boolean $deleteSubFolder if true delete subFolder after moved all + * + * @return boolean + */ + private function moveUpfromSubFolder($subFolderName, $deleteSubFolder = false) + { + if (!is_dir($subFolderName)) { + return false; + } + + $parentFolder = dirname($subFolderName); + if (!is_writable($parentFolder)) { + return false; + } + + $success = true; + if (($subList = glob(rtrim($subFolderName, '/') . '/*', GLOB_NOSORT)) === false) { + $this->log("[ERROR] Problem glob folder " . $subFolderName); + return false; + } else { + foreach ($subList as $cName) { + $destination = $parentFolder . '/' . basename($cName); + if (file_exists($destination)) { + $success = self::rrmdir($destination); + } + + if ($success) { + $success = rename($cName, $destination); + } else { + break; + } + } + + if ($success && $deleteSubFolder) { + $success = self::rrmdir($subFolderName, true); + } + } + + if (!$success) { + $this->log("[ERROR] Problem om moveUpfromSubFolder subFolder:" . $subFolderName); + } + + return $success; + } + + /** + * Extracts only the 'dup-installer' files using Shell-Exec Unzip + * + * @param string $archive_filepath The path to the archive file. + * @param string $origDupInstFolder dup-installer folder + * @param string $destination destination folder + * + * @return bool + */ + private function extractInstallerShellexec($archive_filepath, $origDupInstFolder, $destination) + { + $success = false; + $this->log("Attempting to use Shell Exec"); + $unzip_filepath = $this->getUnzipFilePath(); + + if ($unzip_filepath != null) { + $unzip_command = "$unzip_filepath -q $archive_filepath " . + $origDupInstFolder . '/* -d ' . $destination . ' -x ' . + $origDupInstFolder . '/' . $this->manualExtractFileName . ' 2>&1'; + $this->log("Executing $unzip_command"); + $stderr = shell_exec($unzip_command); + + $lib_directory = $destination . '/' . $origDupInstFolder . '/lib'; + $snaplib_directory = $lib_directory . '/snaplib'; + + // If snaplib files aren't present attempt to extract and copy those + if (!file_exists($snaplib_directory)) { + $local_lib_directory = $destination . '/snaplib'; + $unzip_command = "$unzip_filepath -q $archive_filepath snaplib/* -d '.$destination.' 2>&1"; + + $this->log("Executing unzip command"); + $stderr .= shell_exec($unzip_command); + self::mkdir($lib_directory, 'u+rwx'); + rename($local_lib_directory, $snaplib_directory); + } + + if ($stderr == '') { + $this->log("Shell exec unzip succeeded"); + $success = true; + } else { + $this->log("[ERROR] Shell exec unzip failed. Output={$stderr}"); + } + } + + return $success; + } + + /** + * Attempts to get the archive file path + * + * @return string The full path to the archive file + */ + private function getArchiveFilePath() + { + if (($archive_filepath = filter_input(INPUT_GET, 'archive', FILTER_SANITIZE_SPECIAL_CHARS)) != false) { + if (is_dir($archive_filepath) && file_exists($archive_filepath . '/' . self::ARCHIVE_FILENAME)) { + $archive_filepath = $archive_filepath . '/' . self::ARCHIVE_FILENAME; + } else { + $archive_filepath = $archive_filepath; + } + } else { + $archive_filepath = $this->targetRoot . '/' . self::ARCHIVE_FILENAME; + } + + if (($realPath = realpath($archive_filepath)) !== false) { + return $realPath; + } else { + return $archive_filepath; + } + } + + /** + * Gets the enum type that should be used + * + * @return int Returns the current zip mode enum + */ + private function getZipMode() + { + $zip_mode = self::ZIP_MODE_AUTO; + + if (isset($_GET['zipmode'])) { + $zipmode_string = $_GET['zipmode']; + $this->log("Unzip mode specified in querystring: $zipmode_string"); + + switch ($zipmode_string) { + case 'autounzip': + $zip_mode = self::ZIP_MODE_AUTO; + break; + case 'ziparchive': + $zip_mode = self::ZIP_MODE_ARCHIVE; + break; + case 'shellexec': + $zip_mode = self::ZIP_MODE_SHELL; + break; + } + } + + return $zip_mode; + } + + /** + * Checks to see if a string starts with specific characters + * + * @param string $haystack haystack + * @param string $needle needle + * + * @return bool + */ + private function startsWith($haystack, $needle) + { + return $needle === "" || strrpos($haystack, $needle, - strlen($haystack)) !== false; + } + + /** + * Checks to see if the server supports issuing commands to shell_exex + * + * @return bool Returns true shell_exec can be ran on this server + */ + public function hasShellExec() + { + $cmds = array('shell_exec', 'escapeshellarg', 'escapeshellcmd', 'extension_loaded'); + + //Function disabled at server level + if (array_intersect($cmds, array_map('trim', explode(',', @ini_get('disable_functions'))))) { + return false; + } + + //Suhosin: http://www.hardened-php.net/suhosin/ + //Will cause PHP to silently fail + if (extension_loaded('suhosin')) { + $suhosin_ini = @ini_get("suhosin.executor.func.blacklist"); + if (array_intersect($cmds, array_map('trim', explode(',', $suhosin_ini)))) { + return false; + } + } + + if (! function_exists('shell_exec')) { + return false; + } + + // Can we issue a simple echo command? + if (!@shell_exec('echo duplicator')) { + return false; + } + + return true; + } + + /** + * Gets the possible system commands for unzip on Linux + * + * @return string Returns unzip file path that can execute the unzip command + */ + public function getUnzipFilePath() + { + $filepath = null; + + if ($this->hasShellExec()) { + if (shell_exec('hash unzip 2>&1') == null) { + $filepath = 'unzip'; + } else { + $possible_paths = array( + '/usr/bin/unzip', + '/opt/local/bin/unzip', + '/bin/unzip', + '/usr/local/bin/unzip', + '/usr/sfw/bin/unzip', + '/usr/xdg4/bin/unzip', + '/opt/bin/unzip', + // RSR TODO put back in when we support shellexec on windows, + ); + + foreach ($possible_paths as $path) { + if (file_exists($path)) { + $filepath = $path; + break; + } + } + } + } + + return $filepath; + } + + /** + * Display human readable byte sizes such as 150MB + * + * @param int $size The size in bytes + * + * @return string A readable byte size format such as 100MB + */ + public function readableByteSize($size) + { + try { + $units = array('B', 'KB', 'MB', 'GB', 'TB'); + for ($i = 0; $size >= 1024 && $i < 4; $i++) { + $size /= 1024; + } + return round($size, 2) . $units[$i]; + } catch (Exception $e) { + return "n/a"; + } + } + + /** + * Returns an array of zip files found in the current executing directory + * + * @param string $extension extenstion file + * + * @return array of zip files + */ + public function getFilesWithExtension($extension) + { + $files = array(); + foreach (glob("*.{$extension}") as $name) { + if (file_exists($name)) { + $files[] = $name; + } + } + if (count($files) > 0) { + return $files; + } + //FALL BACK: Windows XP has bug with glob, + //add secondary check for PHP lameness + if (($dh = opendir($this->targetRoot))) { + while (false !== ($name = readdir($dh))) { + $ext = substr($name, strrpos($name, '.') + 1); + if (in_array($ext, array($extension))) { + $files[] = $name; + } + } + closedir($dh); + } + + return $files; + } + + /** + * Safely remove a directory and recursively files and directory upto multiple sublevels + * + * @param string $path The full path to the directory to remove + * + * @return bool Returns true if all content was removed + */ + public static function rrmdir($path) + { + if (is_dir($path)) { + if (($dh = opendir($path)) === false) { + return false; + } + while (($object = readdir($dh)) !== false) { + if ($object == "." || $object == "..") { + continue; + } + if (!self::rrmdir($path . "/" . $object)) { + closedir($dh); + return false; + } + } + closedir($dh); + return @rmdir($path); + } else { + if (is_writable($path)) { + return @unlink($path); + } else { + return false; + } + } + } + + /** + * Makes path safe for any OS for PHP + * + * Paths should ALWAYS READ be "/" + * uni: /home/path/file.txt + * win: D:/home/path/file.txt + * + * @param string $path TThe path to make safe + * + * @return string The original $path with a with all slashes facing '/'. + */ + public static function setSafePath($path) + { + return str_replace("\\", "/", $path); + } + } + + class LogHandler + { + + /** @var bool */ + private static $initialized = false; + + /** + * This function only initializes the error handler the first time it is called + * + * @return void + */ + public static function init_error_handler() + { + if (!self::$initialized) { + @set_error_handler(array(__CLASS__, 'error')); + @register_shutdown_function(array(__CLASS__, 'shutdown')); + self::$initialized = true; + } + } + + /** + * Error handler + * + * @param integer $errno Error level + * @param string $errstr Error message + * @param string $errfile Error file + * @param integer $errline Error line + * @return void + */ + public static function error($errno, $errstr, $errfile, $errline) + { + switch ($errno) { + case E_ERROR: + $log_message = self::getMessage($errno, $errstr, $errfile, $errline); + if (DUPX_Bootstrap::getInstance()->log($log_message) === false) { + $log_message = "Can\'t wrinte logfile\n\n" . $log_message; + } + die('
        ' . htmlspecialchars($log_message) . '
        '); + break; + case E_NOTICE: + case E_WARNING: + default: + $log_message = self::getMessage($errno, $errstr, $errfile, $errline); + DUPX_Bootstrap::getInstance()->log($log_message); + break; + } + } + + /** + * Get message from error + * + * @param int $errno errno + * @param string $errstr message + * @param string $errfile file + * @param int $errline line + * + * @return string + */ + private static function getMessage($errno, $errstr, $errfile, $errline) + { + $result = '[PHP ERR]'; + switch ($errno) { + case E_ERROR: + $result .= '[FATAL]'; + break; + case E_WARNING: + $result .= '[WARN]'; + break; + case E_NOTICE: + $result .= '[NOTICE]'; + break; + default: + $result .= '[ISSUE]'; + break; + } + $result .= ' MSG:'; + $result .= $errstr; + $result .= ' [CODE:' . $errno . '|FILE:' . $errfile . '|LINE:' . $errline . ']'; + return $result; + } + + /** + * Shutdown handler + * + * @return void + */ + public static function shutdown() + { + if (($error = error_get_last())) { + LogHandler::error($error['type'], $error['message'], $error['file'], $error['line']); + } + } + } + + class DUPX_CSRF + { + + private static $packagHash = null; + private static $mainFolder = null; + + /** + * Session var name prefix + * @var string + */ + public static $prefix = '_DUPX_CSRF'; + + /** + * Stores all CSRF values: Key as CSRF name and Val as CRF value + * @var array + */ + private static $CSRFVars = null; + + /** + * Init CSRF + * + * @param string $mainFolderm main folder + * @param string $packageHash hash + * + * @return void + */ + public static function init($mainFolderm, $packageHash) + { + self::$mainFolder = $mainFolderm; + self::$packagHash = $packageHash; + self::$CSRFVars = null; + } + + /** + * Set new CSRF + * + * @param string $key CSRF Key + * @param string $val CSRF Val + * + * @return Void + */ + public static function setKeyVal($key, $val) + { + $CSRFVars = self::getCSRFVars(); + $CSRFVars[$key] = $val; + self::saveCSRFVars($CSRFVars); + self::$CSRFVars = null; + } + + /** + * Get CSRF value by passing CSRF key + * + * @param string $key CSRF key + * + * @return string|boolean If CSRF value set for give n Key, It returns CRF value otherise returns false + */ + public static function getVal($key) + { + $CSRFVars = self::getCSRFVars(); + if (isset($CSRFVars[$key])) { + return $CSRFVars[$key]; + } else { + return false; + } + } + + /** + * Generate DUPX_CSRF value for form + * + * @param string $form Form name as session key + * + * @return string token + */ + public static function generate($form = null) + { + $keyName = self::getKeyName($form); + + $existingToken = self::getVal($keyName); + if (false !== $existingToken) { + $token = $existingToken; + } else { + $token = DUPX_CSRF::token() . DUPX_CSRF::fingerprint(); + } + + self::setKeyVal($keyName, $token); + return $token; + } + + /** + * Check DUPX_CSRF value of form + * + * @param string $token Token + * @param string $form Form name as session key + * + * @return boolean + */ + public static function check($token, $form = null) + { + if (empty($form)) { + return false; + } + + $keyName = self::getKeyName($form); + $CSRFVars = self::getCSRFVars(); + if (isset($CSRFVars[$keyName]) && $CSRFVars[$keyName] == $token) { // token OK + return true; + } + return false; + } + + /** Generate token + * + * @return string + */ + protected static function token() + { + $microtime = (int) (microtime(true) * 10000); + mt_srand($microtime); + $charid = strtoupper(md5(uniqid(rand(), true))); + return substr($charid, 0, 8) . substr($charid, 8, 4) . substr($charid, 12, 4) . substr($charid, 16, 4) . substr($charid, 20, 12); + } + + /** Returns "digital fingerprint" of user + * + * @return string - MD5 hashed data + */ + protected static function fingerprint() + { + return strtoupper(md5(implode('|', array($_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'])))); + } + + /** + * Generate CSRF Key name + * + * @param string $form the form name for which CSRF key need to generate + * @return string CSRF key + */ + private static function getKeyName($form) + { + return DUPX_CSRF::$prefix . '_' . $form; + } + + /** + * Get Package hash + * + * @return string Package hash + */ + private static function getPackageHash() + { + if (is_null(self::$packagHash)) { + throw new Exception('Not init CSFR CLASS'); + } + return self::$packagHash; + } + + /** + * Get file path where CSRF tokens are stored in JSON encoded format + * + * @return string file path where CSRF token stored + */ + private static function getFilePath() + { + if (is_null(self::$mainFolder)) { + throw new Exception('Not init CSFR CLASS'); + } + $dupInstallerfolderPath = self::$mainFolder; + $packageHash = self::getPackageHash(); + $fileName = 'dup-installer-csrf__' . $packageHash . '.txt'; + $filePath = $dupInstallerfolderPath . '/' . $fileName; + return $filePath; + } + + /** + * Get all CSRF vars in array format + * + * @return array Key as CSRF name and value as CSRF value + */ + private static function getCSRFVars() + { + if (is_null(self::$CSRFVars)) { + $filePath = self::getFilePath(); + if (file_exists($filePath)) { + $contents = file_get_contents($filePath); + if (empty($contents)) { + self::$CSRFVars = array(); + } else { + $CSRFobjs = json_decode($contents); + foreach ($CSRFobjs as $key => $value) { + self::$CSRFVars[$key] = $value; + } + } + } else { + self::$CSRFVars = array(); + } + } + return self::$CSRFVars; + } + + /** + * Stores all CSRF vars + * + * @param array $CSRFVars holds all CSRF key val + * @return void + */ + private static function saveCSRFVars($CSRFVars) + { + $contents = json_encode($CSRFVars); + $filePath = self::getFilePath(); + file_put_contents($filePath, $contents); + } + } + /* * * CLASS DEFINITION END ** */ + $auto_refresh = isset($_POST['auto-fresh']) ? true : false; + DUPX_Bootstrap::phpVersionCheck(); + + try { + $boot = DUPX_Bootstrap::getInstance(); + $boot_error = $boot->run(); + } catch (Exception $e) { + $boot_error = $e->getMessage(); + } + + if ($boot_error == null) { + $secure_csrf_token = DUPX_CSRF::generate('secure'); + $ctrl_csrf_token = DUPX_CSRF::generate('ctrl-step1'); + DUPX_CSRF::setKeyVal('installerOrigCall', DUPX_Bootstrap::getCurrentUrl()); + DUPX_CSRF::setKeyVal('installerOrigPath', __FILE__); + DUPX_CSRF::setKeyVal('archive', $boot->archive); + DUPX_CSRF::setKeyVal('bootloader', $boot->bootloader); + DUPX_CSRF::setKeyVal('booturl', '//' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); + DUPX_CSRF::setKeyVal('bootLogFile', $boot->getBootLogFilePath()); + DUPX_CSRF::setKeyVal('package_hash', DUPX_Bootstrap::PACKAGE_HASH); + DUPX_CSRF::setKeyVal('secondaryHash', DUPX_Bootstrap::SECONDARY_PACKAGE_HASH); + } + ?> + + + + + + Duplicator Installer + + + +
        + Initializing Installer. Please wait... +
        + mainInstallerURL}' />\n"; + $data = array( + 'ctrl_action' => 'ctrl-step1', + 'ctrl_csrf_token' => $ctrl_csrf_token, + 'step_action' => 'init' + ); + foreach ($data as $name => $value) { + if ('csrf_token' != $name) { + $_SESSION[$name] = $value; + } + $html .= "\n"; + } + $html .= "\n"; + $html .= ""; + echo $html; + ?> + + + + + + + +
        + + + + + +
          Duplicator - Bootloader + + version:
        + » + + dup-installer-bootlog__[HASH].txt + +
        + +
        +
        +

        Setup Notice

        +
        + An error has occurred. In order to load the full installer please resolve the issue below. +
        +
        + +
        +

        + +

        Server Settings

        + + + + + + + + + + + + + + + + + + + + + + + + + +
        ZipArchive:hasZipArchive ? 'Enabled' : 'Disabled'; ?>
        Shell Unzip:hasShellExecUnzip ? 'Enabled' : 'Disabled'; ?>
        Extraction Path:targetRoot; ?>
        Installer Path:targetDupInstFolder; ?>
        Archive Size: + Expected Size: readableByteSize($boot->archiveExpectedSize); ?>   + Actual Size: readableByteSize($boot->archiveActualSize); ?> +
        Boot Log + + dup-installer-bootlog__[HASH].txt + +
        +

        + +
        + Note: For archive.zip files either ZipArchive or Shell Exec will need to be enabled for the installer to run automatically + otherwise a manual extraction will need to be performed. In order to run the installer manually follow the instructions to + manually extract before + running the installer. +
        +

        + +
        +
        + +
        + + + + + + + + \n" +"Language-Team: Duplicator \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"POT-Creation-Date: 2025-10-13T20:06:57+00:00\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"X-Generator: WP-CLI 2.12.0\n" +"X-Domain: duplicator\n" + +#. Plugin Name of the plugin +#. Author of the plugin +#: duplicator.php +#: src/Views/DashboardWidget.php:46 +#: template/mail/email_summary.php:28 +msgid "Duplicator" +msgstr "" + +#. Plugin URI of the plugin +#. Author URI of the plugin +#: duplicator.php +msgid "https://duplicator.com/" +msgstr "" + +#. Description of the plugin +#: duplicator.php +msgid "Migrate and backup a copy of your WordPress files and database. Duplicate and move a site from one location to another quickly." +msgstr "" + +#: assets/js/duplicator/dup.util.php:21 +msgid "wait ..." +msgstr "" + +#: assets/js/duplicator/dup.util.php:83 +msgid "RESPONSE SUCCESS" +msgstr "" + +#: assets/js/duplicator/dup.util.php:97 +#: template/admin_pages/settings/general/general.php:199 +#: template/admin_pages/settings/general/general.php:244 +msgid "RESPONSE ERROR!" +msgstr "" + +#: assets/js/duplicator/dup.util.php:106 +msgid "AJAX ERROR! " +msgstr "" + +#: assets/js/duplicator/dup.util.php:106 +msgid "Ajax request error" +msgstr "" + +#: assets/js/javascript.php:272 +msgid "Copied: " +msgstr "" + +#: assets/js/javascript.php:274 +msgid "unable to copy" +msgstr "" + +#: assets/js/javascript.php:278 +#: assets/js/javascript.php:282 +msgid "Copy to Clipboard!" +msgstr "" + +#: classes/class.logging.php:161 +msgid "No Log" +msgstr "" + +#: classes/class.server.php:327 +msgid "(directory)" +msgstr "" + +#: classes/class.server.php:390 +#: views/packages/details/detail.php:92 +#: views/settings/controller.php:30 +msgid "General" +msgstr "" + +#: classes/class.server.php:396 +#: views/packages/details/detail.php:138 +#: views/packages/main/s2.scan2.php:116 +msgid "WordPress" +msgstr "" + +#: classes/class.server.php:402 +#: views/packages/details/detail.php:142 +msgid "PHP" +msgstr "" + +#: classes/class.server.php:408 +msgid "MySQL" +msgstr "" + +#: classes/class.server.php:414 +msgid "Paths Info" +msgstr "" + +#: classes/class.server.php:422 +msgid "URL " +msgstr "" + +#: classes/class.server.php:429 +msgid "URLs Info" +msgstr "" + +#: classes/class.server.php:439 +msgid "Free Space" +msgstr "" + +#: classes/class.server.php:442 +msgid "%1$s%% -- %2$s from %3$s" +msgstr "" + +#: classes/class.server.php:447 +msgid "" +"Note: This value is the physical servers hard-drive allocation.\n" +" On shared hosts check your control panel for the \"TRUE\" disk space quota value." +msgstr "" + +#: classes/class.server.php:456 +msgid "Server Disk" +msgstr "" + +#: classes/class.server.php:470 +msgid "Can't detect" +msgstr "" + +#: classes/class.server.php:479 +#: classes/class.server.php:534 +msgid "Duplicator Version" +msgstr "" + +#: classes/class.server.php:484 +msgid "Operating System" +msgstr "" + +#: classes/class.server.php:489 +msgid "Timezone" +msgstr "" + +#: classes/class.server.php:491 +#: classes/utilities/class.u.php:70 +msgid "Unknown" +msgstr "" + +#: classes/class.server.php:493 +msgctxt "%1$s and %2$s are the opening and closing anchor tags" +msgid "This is a %1$sWordPress Setting%2$s" +msgstr "" + +#: classes/class.server.php:504 +msgid "Server Time" +msgstr "" + +#: classes/class.server.php:509 +#: views/packages/main/s2.scan2.php:51 +msgid "Web Server" +msgstr "" + +#: classes/class.server.php:514 +msgid "Loaded PHP INI" +msgstr "" + +#: classes/class.server.php:519 +msgid "Server IP" +msgstr "" + +#: classes/class.server.php:524 +msgid "Client IP" +msgstr "" + +#: classes/class.server.php:529 +#: views/packages/details/detail.php:514 +#: views/packages/main/s1.setup2.php:460 +msgid "Host" +msgstr "" + +#: classes/class.server.php:552 +#: views/packages/main/s2.scan2.php:122 +msgid "WordPress Version" +msgstr "" + +#: classes/class.server.php:557 +msgid "Language" +msgstr "" + +#: classes/class.server.php:562 +#: classes/class.server.php:674 +#: views/packages/main/s1.setup2.php:512 +msgid "Charset" +msgstr "" + +#: classes/class.server.php:567 +#: classes/class.server.php:598 +msgid "Memory Limit" +msgstr "" + +#: classes/class.server.php:583 +#: views/packages/main/s1.setup1.php:112 +#: views/packages/main/s2.scan2.php:56 +msgid "PHP Version" +msgstr "" + +#: classes/class.server.php:588 +msgid "PHP SAPI" +msgstr "" + +#: classes/class.server.php:593 +#: views/packages/details/detail.php:165 +#: views/packages/details/detail.php:522 +#: views/packages/main/s1.setup2.php:499 +msgid "User" +msgstr "" + +#: classes/class.server.php:604 +msgid "Memory In Use" +msgstr "" + +#: classes/class.server.php:609 +msgid "Max Execution Time" +msgstr "" + +#: classes/class.server.php:614 +msgctxt "%1$s = \"is dynamic\" or \"value is fixed\" based on settings" +msgid "(default) - %1$s" +msgstr "" + +#: classes/class.server.php:615 +msgid "is dynamic" +msgstr "" + +#: classes/class.server.php:615 +msgid "value is fixed" +msgstr "" + +#: classes/class.server.php:618 +msgid "" +"If the value shows dynamic then this means its possible for PHP to run longer than the default. \n" +" If the value is fixed then PHP will not be allowed to run longer than the default." +msgstr "" + +#: classes/class.server.php:625 +msgid "open_basedir" +msgstr "" + +#: classes/class.server.php:628 +#: views/packages/details/detail.php:380 +#: views/packages/details/detail.php:444 +msgid "Off" +msgstr "" + +#: classes/class.server.php:631 +msgid "Shell (exec)" +msgstr "" + +#: classes/class.server.php:634 +#: classes/class.server.php:639 +msgid "Is Supported" +msgstr "" + +#: classes/class.server.php:634 +#: classes/class.server.php:639 +msgid "Not Supported" +msgstr "" + +#: classes/class.server.php:637 +msgid "Shell Exec Zip" +msgstr "" + +#: classes/class.server.php:642 +msgid "Suhosin Extension" +msgstr "" + +#: classes/class.server.php:645 +#: template/admin_pages/settings/misc/misc.php:168 +#: template/parts/DashboardWidget/sections-section.php:51 +#: views/packages/main/s2.scan3.php:46 +#: views/packages/main/s2.scan3.php:416 +#: views/packages/main/s2.scan3.php:757 +msgid "Enabled" +msgstr "" + +#: classes/class.server.php:645 +#: views/packages/main/s2.scan3.php:757 +msgid "Disabled" +msgstr "" + +#: classes/class.server.php:648 +msgid "Architecture" +msgstr "" + +#: classes/class.server.php:653 +msgid "Error Log File" +msgstr "" + +#: classes/class.server.php:669 +#: template/admin_pages/settings/misc/misc.php:92 +#: views/packages/details/detail.php:130 +msgid "Version" +msgstr "" + +#: classes/class.server.php:679 +msgid "Wait Timeout" +msgstr "" + +#: classes/class.server.php:685 +msgid "Max Allowed Packets" +msgstr "" + +#: classes/class.server.php:691 +msgid "mysqldump Path" +msgstr "" + +#: classes/class.server.php:694 +msgid "Path Not Found" +msgstr "" + +#: classes/class.server.php:708 +msgid "Target root path" +msgstr "" + +#: classes/class.server.php:716 +msgid "Original " +msgstr "" + +#: classes/class.server.php:724 +msgid "Archive " +msgstr "" + +#: classes/package/class.pack.database.php:602 +msgid "Shell mysql dump error. Change SQL Mode to the \"PHP Code\" in the Duplicator > Settings > Backups." +msgstr "" + +#: classes/package/class.pack.database.php:757 +msgid "Please contact your DataBase administrator to fix the error." +msgstr "" + +#: classes/package/class.pack.installer.php:140 +msgid "Error reading DupArchive expander" +msgstr "" + +#: classes/package/class.pack.installer.php:153 +msgid "Error writing installer contents" +msgstr "" + +#: classes/package/class.pack.installer.php:761 +msgid "Zip archive %1s not present." +msgstr "" + +#: classes/package/class.pack.installer.php:834 +#: classes/package/class.pack.php:1015 +msgid "ERROR: Cannot open created archive. Error code = %1$s" +msgstr "" + +#: classes/package/class.pack.installer.php:838 +#: classes/package/class.pack.php:1020 +msgid "ERROR: Archive is not valid zip archive." +msgstr "" + +#: classes/package/class.pack.installer.php:841 +#: classes/package/class.pack.php:1024 +msgid "ERROR: Archive doesn't pass consistency check." +msgstr "" + +#: classes/package/class.pack.installer.php:844 +#: classes/package/class.pack.php:1029 +msgid "ERROR: Archive checksum is bad." +msgstr "" + +#: classes/package/class.pack.installer.php:860 +msgid "ARCHIVE CONSISTENCY TEST: FAIL" +msgstr "" + +#: classes/package/class.pack.installer.php:863 +msgid "ARCHIVE CONSISTENCY TEST: PASS" +msgstr "" + +#: classes/package/class.pack.php:355 +msgid "Backup name can't be empty" +msgstr "" + +#: classes/package/class.pack.php:364 +msgid "Directories: %1$s isn't a valid path" +msgstr "" + +#: classes/package/class.pack.php:373 +msgid "File extension: %1$s isn't a valid extension" +msgstr "" + +#: classes/package/class.pack.php:382 +msgid "Files: %1$s isn't a valid file name" +msgstr "" + +#: classes/package/class.pack.php:391 +msgid "MySQL Server Host: %1$s isn't a valid host" +msgstr "" + +#: classes/package/class.pack.php:401 +msgid "MySQL Server Port: %1$s isn't a valid port" +msgstr "" + +#: classes/package/class.pack.php:945 +msgid "Can't find Scanfile %s. Please ensure there no non-English characters in the Backup or schedule name." +msgstr "" + +#: classes/package/class.pack.php:966 +msgid "EXPECTED FILE/DIRECTORY COUNT: %1$s" +msgstr "" + +#: classes/package/class.pack.php:967 +msgid "ACTUAL FILE/DIRECTORY COUNT: %1$s" +msgstr "" + +#: classes/package/class.pack.php:1039 +msgid "ARCHIVE CONSISTENCY TEST: Pass" +msgstr "" + +#: classes/package/duparchive/class.pack.archive.duparchive.php:35 +msgid "Backup build appears stuck so marking Backup as failed. Is the Max Worker Time set too high?." +msgstr "" + +#: classes/package/duparchive/class.pack.archive.duparchive.php:36 +msgid "Build Failure" +msgstr "" + +#: classes/package/duparchive/class.pack.archive.duparchive.php:61 +msgid "Click on \"Resolve This\" button to fix the JSON settings." +msgstr "" + +#: classes/package/duparchive/class.pack.archive.duparchive.php:71 +msgid "ERROR: Can't find Scanfile %s. Please ensure there no non-English characters in the Backup or schedule name." +msgstr "" + +#: classes/package/duparchive/class.pack.archive.duparchive.php:157 +msgid "Problem adding items to archive." +msgstr "" + +#: classes/package/duparchive/class.pack.archive.duparchive.php:158 +msgid "Problems adding items to archive." +msgstr "" + +#: classes/package/duparchive/class.pack.archive.duparchive.php:232 +msgid "Critical failure present in validation" +msgstr "" + +#: classes/ui/class.ui.dialog.php:86 +msgid "Processing please wait..." +msgstr "" + +#: classes/ui/class.ui.dialog.php:89 +msgid "OK" +msgstr "" + +#: classes/ui/class.ui.dialog.php:90 +#: deactivation.php:156 +msgid "Cancel" +msgstr "" + +#: classes/utilities/class.u.php:64 +msgid "32-bit" +msgstr "" + +#: classes/utilities/class.u.php:67 +msgid "64-bit" +msgstr "" + +#: classes/utilities/class.u.php:310 +msgctxt "sec. stands for seconds" +msgid "%.2f sec." +msgstr "" + +#: classes/utilities/class.u.php:513 +msgid "You do not have sufficient permissions to access this page." +msgstr "" + +#: ctrls/class.web.services.php:94 +#: ctrls/class.web.services.php:98 +#: ctrls/class.web.services.php:102 +msgid "Invalid request." +msgstr "" + +#: ctrls/class.web.services.php:116 +msgid "INVALID REQUEST: File not found, please check the backup folder for file." +msgstr "" + +#: ctrls/class.web.services.php:161 +#: deactivation.php:410 +#: src/Views/AdminNotices.php:139 +msgid "Security issue" +msgstr "" + +#: ctrls/class.web.services.php:168 +msgid "Invalid Request" +msgstr "" + +#: ctrls/class.web.services.php:177 +msgid "Notice with that ID doesn't exist." +msgstr "" + +#: ctrls/ctrl.package.php:192 +msgid "Error building DupArchive Backup" +msgstr "" + +#: ctrls/ctrl.package.php:285 +msgid "An unauthorized security request was made to this page. Please try again!" +msgstr "" + +#: ctrls/ctrl.package.php:304 +msgid "Active Backup object error" +msgstr "" + +#: ctrls/ctrl.tools.php:114 +#: ctrls/ctrl.ui.php:91 +#: deactivation.php:415 +msgid "Invalid Request." +msgstr "" + +#: deactivation.php:67 +msgid "Need help? We are ready to answer your questions." +msgstr "" + +#: deactivation.php:68 +msgid "Contact Support" +msgstr "" + +#: deactivation.php:72 +msgid "It's not working on my server." +msgstr "" + +#: deactivation.php:74 +msgid "Kindly share what didn't work so we can fix it in future updates..." +msgstr "" + +#: deactivation.php:79 +msgid "It's too confusing to understand." +msgstr "" + +#: deactivation.php:81 +msgid "Please tell us what is not clear so that we can improve it." +msgstr "" + +#: deactivation.php:86 +msgid "I found a different plugin that I like better." +msgstr "" + +#: deactivation.php:88 +msgid "What's the plugin name?" +msgstr "" + +#: deactivation.php:92 +msgid "It does not do what I need." +msgstr "" + +#: deactivation.php:94 +msgid "What does it need to do?" +msgstr "" + +#: deactivation.php:98 +msgid "It's a temporary deactivation, I use the plugin all the time." +msgstr "" + +#: deactivation.php:105 +msgid "I'm switching over to the %s" +msgstr "" + +#: deactivation.php:106 +msgid "Pro version" +msgstr "" + +#: deactivation.php:148 +msgid "Quick Feedback" +msgstr "" + +#: deactivation.php:150 +msgid "If you have a moment, please let us know why you are deactivating" +msgstr "" + +#: deactivation.php:158 +#: deactivation.php:381 +msgid "Skip & Deactivate" +msgstr "" + +#: deactivation.php:160 +msgid "Send & Deactivate" +msgstr "" + +#: deactivation.php:164 +msgid "Your response is sent anonymously." +msgstr "" + +#: deactivation.php:259 +#: deactivation.php:261 +msgid "Processing" +msgstr "" + +#: deactivation.php:314 +msgid "Please tell us the reason so we can improve it." +msgstr "" + +#: src/Ajax/ServicesEducation.php:417 +msgid "Upgrade installation failed: %s. Please try again or install manually." +msgstr "" + +#: src/Controllers/AboutUsController.php:54 +msgid "Loading..." +msgstr "" + +#: src/Controllers/AboutUsController.php:55 +msgid "Failure" +msgstr "" + +#: src/Controllers/AboutUsController.php:56 +#: src/Utils/ExtraPlugins/ExtraItem.php:293 +msgid "Active" +msgstr "" + +#: src/Controllers/AboutUsController.php:57 +#: template/admin_pages/about_us/about_us/extra_plugin_item.php:17 +msgid "Activated" +msgstr "" + +#: src/Controllers/AboutUsController.php:129 +msgid "Backup Files & Database" +msgstr "" + +#: src/Controllers/AboutUsController.php:133 +#: src/Utils/Upsell.php:26 +#: src/Utils/Upsell.php:52 +#: template/admin_pages/welcome/features.php:71 +msgid "File & Database Table Filters" +msgstr "" + +#: src/Controllers/AboutUsController.php:137 +msgid "Migration Wizard" +msgstr "" + +#: src/Controllers/AboutUsController.php:141 +msgid "Overwrite Live Site" +msgstr "" + +#: src/Controllers/AboutUsController.php:145 +#: src/Utils/Upsell.php:32 +#: src/Utils/Upsell.php:55 +msgid "Drag & Drop Installs" +msgstr "" + +#: src/Controllers/AboutUsController.php:147 +msgid "Classic WordPress-less Installs Only" +msgstr "" + +#: src/Controllers/AboutUsController.php:148 +msgid "Drag and Drop migrations and site restores! Simply drag the bundled site archive to the site you wish to overwrite." +msgstr "" + +#: src/Controllers/AboutUsController.php:154 +#: src/Utils/Upsell.php:22 +#: src/Utils/Upsell.php:48 +#: template/admin_pages/welcome/features.php:28 +msgid "Scheduled Backups" +msgstr "" + +#: src/Controllers/AboutUsController.php:156 +msgid "Ensure that your important data is regularly and consistently backed up, allowing for quick and efficient recovery in case of data loss." +msgstr "" + +#: src/Controllers/AboutUsController.php:162 +#: src/Utils/Upsell.php:23 +#: src/Utils/Upsell.php:49 +#: template/admin_pages/welcome/features.php:45 +msgid "Recovery Points" +msgstr "" + +#: src/Controllers/AboutUsController.php:164 +msgid "Recovery Points provide protection against mistakes and bad updates by letting you quickly rollback your system to a known, good state." +msgstr "" + +#: src/Controllers/AboutUsController.php:170 +#: src/Utils/Upsell.php:53 +msgid "Cloud Storage" +msgstr "" + +#: src/Controllers/AboutUsController.php:172 +msgid "Back up to Dropbox, FTP, Google Drive, OneDrive, Amazon S3 or any S3-compatible storage service for safe storage." +msgstr "" + +#: src/Controllers/AboutUsController.php:178 +#: src/Utils/Upsell.php:33 +#: src/Utils/Upsell.php:59 +msgid "Larger Site Support" +msgstr "" + +#: src/Controllers/AboutUsController.php:180 +msgid "We've developed a new way to package backups especially tailored for larger site. No server timeouts or other restrictions!" +msgstr "" + +#: src/Controllers/AboutUsController.php:186 +msgid "Server-to-Server Import" +msgstr "" + +#: src/Controllers/AboutUsController.php:188 +msgid "Direct Server Transfers allow you to build an archive, then directly transfer it from the source server to the destination server for a lightning fast migration!" +msgstr "" + +#: src/Controllers/AboutUsController.php:195 +msgid "Multisite support" +msgstr "" + +#: src/Controllers/AboutUsController.php:197 +msgid "Supports multisite network backup & migration. Subsite As Standalone Install, Standalone Import Into Multisite and Import Subsite Into Multisite" +msgstr "" + +#: src/Controllers/AboutUsController.php:204 +#: src/Utils/Upsell.php:60 +msgid "Installer Branding" +msgstr "" + +#: src/Controllers/AboutUsController.php:206 +msgid "Create your own custom-configured WordPress site and \"Brand\" the installer file with your look and feel." +msgstr "" + +#: src/Controllers/AboutUsController.php:209 +msgid "Archive Encryption" +msgstr "" + +#: src/Controllers/AboutUsController.php:211 +msgid "Protect and secure the archive file with industry-standard AES-256 encryption!" +msgstr "" + +#: src/Controllers/AboutUsController.php:214 +#: src/Utils/Upsell.php:36 +#: src/Utils/Upsell.php:66 +#: template/mocks/settings/access/capabilities.php:123 +msgid "Advanced Backup Permissions" +msgstr "" + +#: src/Controllers/AboutUsController.php:216 +msgid "Enjoy granular access control to ensure only authorized users can perform these critical functions." +msgstr "" + +#: src/Controllers/AboutUsController.php:222 +msgid "Enhanced Features" +msgstr "" + +#: src/Controllers/AboutUsController.php:224 +msgid "Enhanced features include: Managed Hosting Support, Shared Database Support, Streamlined Installer, Email Alerts and more..." +msgstr "" + +#: src/Controllers/AboutUsController.php:230 +msgid "Advanced Features" +msgstr "" + +#: src/Controllers/AboutUsController.php:232 +msgid "Advanced features included: Hourly Schedules, Custom Search & Replace, Migrate Duplicator Settings, Regenerate Salts and Developer Hooks" +msgstr "" + +#: src/Controllers/AboutUsController.php:238 +msgid "Customer Support" +msgstr "" + +#: src/Controllers/AboutUsController.php:240 +msgid "Limited Support" +msgstr "" + +#: src/Controllers/AboutUsController.php:241 +msgid "Priority Support" +msgstr "" + +#: src/Controllers/StorageController.php:34 +msgid "Advanced Storage" +msgstr "" + +#: src/Controllers/StorageController.php:56 +#: src/Controllers/StorageController.php:57 +msgid "Amazon S3" +msgstr "" + +#: src/Controllers/StorageController.php:61 +#: src/Controllers/StorageController.php:62 +msgid "Google Drive" +msgstr "" + +#: src/Controllers/StorageController.php:66 +#: src/Controllers/StorageController.php:67 +msgid "OneDrive" +msgstr "" + +#: src/Controllers/StorageController.php:71 +#: src/Controllers/StorageController.php:72 +msgid "DropBox" +msgstr "" + +#: src/Controllers/StorageController.php:76 +#: src/Controllers/StorageController.php:77 +msgid "FTP/SFTP" +msgstr "" + +#: src/Controllers/StorageController.php:81 +#: src/Controllers/StorageController.php:82 +msgid "Google Cloud Storage" +msgstr "" + +#: src/Controllers/StorageController.php:86 +#: src/Controllers/StorageController.php:87 +msgid "Back Blaze" +msgstr "" + +#: src/Controllers/StorageController.php:91 +#: src/Controllers/StorageController.php:92 +msgid "Cloudflare R2" +msgstr "" + +#: src/Controllers/StorageController.php:96 +#: src/Controllers/StorageController.php:97 +msgid "DigitalOcean Spaces" +msgstr "" + +#: src/Controllers/StorageController.php:101 +#: src/Controllers/StorageController.php:102 +msgid "Vultr Object Storage" +msgstr "" + +#: src/Controllers/StorageController.php:106 +#: src/Controllers/StorageController.php:107 +msgid "Dream Objects" +msgstr "" + +#: src/Controllers/StorageController.php:111 +#: src/Controllers/StorageController.php:112 +msgid "Wasabi" +msgstr "" + +#: src/Controllers/StorageController.php:116 +msgid "S3-Compatible Provider" +msgstr "" + +#: src/Controllers/StorageController.php:117 +msgid "S3-Compatible (Generic) Cloudian, Cloudn, Connectria, Constant, Exoscal, Eucalyptus, Nifty, Nimbula, Minio, etc..." +msgstr "" + +#: src/Controllers/WelcomeController.php:65 +#: src/Controllers/WelcomeController.php:66 +msgid "Welcome to Duplicator" +msgstr "" + +#: src/Core/Bootstrap.php:269 +#: src/Core/Bootstrap.php:544 +msgid "Upgrade to Pro" +msgstr "" + +#: src/Core/Bootstrap.php:270 +msgid "NEW!" +msgstr "" + +#: src/Core/Bootstrap.php:274 +#: src/Core/Bootstrap.php:275 +#: template/mail/email_summary.php:130 +#: views/packages/details/controller.php:76 +#: views/packages/main/s3.build.php:124 +#: views/settings/controller.php:36 +msgid "Backups" +msgstr "" + +#: src/Core/Bootstrap.php:284 +#: src/Core/Bootstrap.php:285 +msgid "Import Backups" +msgstr "" + +#: src/Core/Bootstrap.php:295 +#: src/Core/Bootstrap.php:296 +msgid "Schedule Backups" +msgstr "" + +#: src/Core/Bootstrap.php:306 +#: src/Core/Bootstrap.php:307 +#: template/mocks/storage/storage.php:59 +#: views/packages/details/detail.php:278 +#: views/packages/main/s1.setup2.php:104 +#: views/settings/controller.php:42 +msgid "Storage" +msgstr "" + +#: src/Core/Bootstrap.php:315 +#: src/Core/Bootstrap.php:316 +msgid "Tools" +msgstr "" + +#: src/Core/Bootstrap.php:329 +#: src/Core/Bootstrap.php:330 +#: template/admin_pages/settings/general/general.php:91 +#: template/mocks/storage/storage.php:87 +#: views/settings/controller.php:23 +msgid "Settings" +msgstr "" + +#: src/Core/Bootstrap.php:339 +msgid "About Duplicator" +msgstr "" + +#: src/Core/Bootstrap.php:340 +#: template/admin_pages/about_us/tabs.php:17 +msgid "About Us" +msgstr "" + +#: src/Core/Bootstrap.php:383 +#: template/parts/Education/subscribe-form.php:26 +msgid "Subscribe" +msgstr "" + +#: src/Core/Bootstrap.php:384 +msgid "Subscribed ✓" +msgstr "" + +#: src/Core/Bootstrap.php:385 +msgid "Subscribing..." +msgstr "" + +#: src/Core/Bootstrap.php:386 +msgid "Failed ✗" +msgstr "" + +#: src/Core/Bootstrap.php:387 +msgid "Email subscription failed with message: " +msgstr "" + +#: src/Core/Bootstrap.php:398 +msgid "Failed to connect to Duplicator Pro." +msgstr "" + +#: src/Core/Bootstrap.php:399 +msgid "Message: " +msgstr "" + +#: src/Core/Bootstrap.php:400 +msgid "Please try again or contact support if the issue persists." +msgstr "" + +#: src/Core/Bootstrap.php:409 +msgid "Failed to load help content!" +msgstr "" + +#: src/Core/Bootstrap.php:418 +msgid "Copy to clipboard" +msgstr "" + +#: src/Core/Bootstrap.php:419 +msgid "copied to clipboard" +msgstr "" + +#: src/Core/Bootstrap.php:420 +msgid "Unable to copy" +msgstr "" + +#: src/Core/Bootstrap.php:564 +msgid "Manage Backups" +msgstr "" + +#: src/Core/Bootstrap.php:565 +msgid "Manage" +msgstr "" + +#: src/Core/MigrationMng.php:242 +msgid "NOTICE: Safe mode (Basic) was enabled during install, be sure to re-enable all your plugins." +msgstr "" + +#: src/Core/MigrationMng.php:245 +msgid "NOTICE: Safe mode (Advanced) was enabled during install, be sure to re-enable all your plugins." +msgstr "" + +#: src/Core/MigrationMng.php:323 +msgid "Installer file %s removed for security reasons" +msgstr "" + +#: src/Core/MigrationMng.php:328 +msgid "Can't remove installer file %s, please remove it for security reasons" +msgstr "" + +#: src/Core/MigrationMng.php:339 +msgid "Installer file %s renamed with HASH" +msgstr "" + +#: src/Core/MigrationMng.php:345 +msgid "Can't rename installer file %s with HASH, please remove it for security reasons" +msgstr "" + +#: src/Core/MigrationMng.php:378 +msgid "Original files folder moved in installer backup directory" +msgstr "" + +#: src/Core/MigrationMng.php:383 +msgid "Can't move %s to %s" +msgstr "" + +#: src/Core/MigrationMng.php:400 +msgid "Installer log" +msgstr "" + +#: src/Core/MigrationMng.php:401 +msgid "Installer boot log" +msgstr "" + +#: src/Core/MigrationMng.php:402 +msgid "Original files folder" +msgstr "" + +#: src/Core/Notifications/Review.php:95 +msgid "Are you enjoying %s?" +msgstr "" + +#: src/Core/Notifications/Review.php:98 +#: template/admin_pages/settings/general/general.php:175 +msgid "Yes" +msgstr "" + +#: src/Core/Notifications/Review.php:102 +msgid "Not really" +msgstr "" + +#: src/Core/Notifications/Review.php:109 +msgid "That’s awesome! Could you please do me a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?" +msgstr "" + +#: src/Core/Notifications/Review.php:114 +msgid "~ John Turner
        President of Duplicator" +msgstr "" + +#: src/Core/Notifications/Review.php:118 +msgid "Ok, you deserve it" +msgstr "" + +#: src/Core/Notifications/Review.php:122 +msgid "Nope, maybe later" +msgstr "" + +#: src/Core/Notifications/Review.php:126 +msgid "I already did" +msgstr "" + +#: src/Core/Notifications/Review.php:133 +msgid "We're sorry to hear you aren't enjoying Duplicator. We would love a chance to improve. Could you take a minute and let us know what we can do better?" +msgstr "" + +#: src/Core/Notifications/Review.php:141 +msgid "Give Feedback" +msgstr "" + +#: src/Core/Notifications/Review.php:145 +msgid "No thanks" +msgstr "" + +#. translators: $1$s - WPForms plugin name; $2$s - WP.org review link; $3$s - WP.org review link. +#: src/Core/Notifications/Review.php:220 +msgid "Please rate Duplicator ★★★★★ on WordPress.org to help us spread the word. Thank you from the Duplicator team!" +msgstr "" + +#: src/Libs/OneClickUpgrade/UpgraderSkin.php:100 +msgid "There was an error installing the upgrade. Please try again." +msgstr "" + +#: src/Lite/Requirements.php:50 +msgctxt "%1$s and %2$s are tags" +msgid "" +"Can't enable Duplicator LITE if the PRO version is enabled. Please deactivate Duplicator PRO, \n" +" then reactivate LITE version from the %1$splugins page%2$s." +msgstr "" + +#: src/Lite/Requirements.php:139 +msgid "Duplicator Notice:" +msgstr "" + +#: src/Lite/Requirements.php:140 +msgid "The \"Duplicator Lite\" and \"Duplicator Pro\" plugins cannot both be active at the same time. " +msgstr "" + +#: src/Lite/Requirements.php:143 +msgid "To use \"Duplicator LITE\" please deactivate \"Duplicator PRO\" from the " +msgstr "" + +#: src/Lite/Requirements.php:145 +msgid "plugins page" +msgstr "" + +#: src/Utils/CachesPurge/CacheItem.php:61 +msgid "All caches on %s have been purged." +msgstr "" + +#: src/Utils/CachesPurge/CacheItem.php:100 +#: src/Utils/CachesPurge/CacheItem.php:104 +msgid "Error on caches purge of %s." +msgstr "" + +#: src/Utils/CronUtils.php:32 +msgid "Once a Day" +msgstr "" + +#: src/Utils/CronUtils.php:37 +msgid "Once a Week" +msgstr "" + +#: src/Utils/CronUtils.php:42 +msgid "Once a Month" +msgstr "" + +#: src/Utils/DuplicatorPhpVersionCheck.php:63 +msgid "DUPLICATOR: Action Required - PHP Version Update Needed, Your site is running PHP version %s." +msgstr "" + +#: src/Utils/DuplicatorPhpVersionCheck.php:77 +msgid "Starting from Duplicator %1$s, Duplicator will require PHP %2$s or higher to receive new updates." +msgstr "" + +#: src/Utils/DuplicatorPhpVersionCheck.php:90 +msgid "" +"While your current version of Duplicator will continue to work, \n" +" you'll need to upgrade your PHP version to receive future features, improvements, and security updates." +msgstr "" + +#: src/Utils/DuplicatorPhpVersionCheck.php:97 +msgid "Please contact your hosting provider to upgrade your PHP version." +msgstr "" + +#: src/Utils/DuplicatorPhpVersionCheck.php:105 +msgid "Learn more about this change and how to upgrade" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:103 +msgid "Successful" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:108 +msgid "Failed" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:123 +msgid "Never" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:124 +msgid "Daily" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:125 +msgid "Weekly" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:126 +msgid "Monthly" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:140 +msgid "day" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:142 +msgid "month" +msgstr "" + +#: src/Utils/Email/EmailSummary.php:145 +msgid "week" +msgstr "" + +#: src/Utils/Email/EmailSummaryBootstrap.php:71 +msgctxt "%s is the site domain" +msgid "Your Weekly Duplicator Summary for %s" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraItem.php:295 +msgid "Inactive" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraItem.php:297 +msgid "Not Installed" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:93 +msgid "Plugin slug is empty" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:98 +msgid "Plugin not found" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:123 +msgid "OptinMonster" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:126 +msgid "Instantly get more subscribers, leads, and sales with the #1 conversion optimization toolkit. Create high converting popups, announcement bars, spin a wheel, and more with smart targeting and personalization." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:135 +#: src/Views/DashboardWidget.php:214 +msgid "MonsterInsights" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:138 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:150 +msgid "The leading WordPress analytics plugin that shows you how people find and use your website, so you can make data driven decisions to grow your business. Properly set up Google Analytics without writing code." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:147 +msgid "MonsterInsights Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:160 +msgid "WPForms" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:163 +msgid "The best drag & drop WordPress form builder. Easily create beautiful contact forms, surveys, payment forms, and more with our 100+ form templates. Trusted by over 4 million websites as the best forms plugin." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:172 +msgid "WPForms Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:175 +msgid "The easiest drag & drop WordPress form builder plugin to create beautiful contact forms, subscription forms, payment forms, and more in minutes. No coding skills required." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:185 +#: src/Views/DashboardWidget.php:238 +msgid "WP Mail SMTP" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:188 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:200 +msgid "Improve your WordPress email deliverability and make sure that your website emails reach user's inbox with the #1 SMTP plugin for WordPress. Over 3 million websites use it to fix WordPress email issues." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:197 +msgid "WP Mail SMTP Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:210 +#: src/Views/DashboardWidget.php:222 +msgid "AIOSEO" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:213 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:225 +msgid "The original WordPress SEO plugin and toolkit that improves your website's search rankings. Comes with all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:222 +msgid "AIOSEO Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:235 +#: src/Views/DashboardWidget.php:230 +msgid "SeedProd" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:238 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:247 +msgid "The best WordPress coming soon page plugin to create a beautiful coming soon page, maintenance mode page, or landing page. No coding skills required." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:244 +msgid "SeedProd Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:254 +msgid "RafflePress" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:257 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:269 +msgid "Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and social media followers with the most powerful giveaways & contests plugin for WordPress." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:266 +msgid "RafflePress Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:279 +msgid "PushEngage" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:282 +msgid "Connect with your visitors after they leave your website with the leading web push notification software. Over 10,000+ businesses worldwide use PushEngage to send 9 billion notifications each month." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:294 +msgid "Smash Balloon Instagram Feeds" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:297 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:309 +msgid "Easily display Instagram content on your WordPress site without writing any code. Comes with multiple templates, ability to show content from multiple accounts, hashtags, and more. Trusted by 1 million websites." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:306 +msgid "Smash Balloon Instagram Feeds Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:319 +msgid "Smash Balloon Facebook Feeds" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:322 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:334 +msgid "Easily display Facebook content on your WordPress site without writing any code. Comes with multiple templates, ability to embed albums, group content, reviews, live videos, comments, and reactions." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:331 +msgid "Smash Balloon Facebook Feeds Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:344 +msgid "Smash Balloon Twitter Feeds" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:347 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:359 +msgid "Easily display Twitter content in WordPress without writing any code. Comes with multiple layouts, ability to combine multiple Twitter feeds, Twitter card support, tweet moderation, and more." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:356 +msgid "Smash Balloon Twitter Feeds Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:369 +msgid "Smash Balloon YouTube Feeds" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:372 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:384 +msgid "Easily display YouTube videos on your WordPress site without writing any code. Comes with multiple layouts, ability to embed live streams, video filtering, ability to combine multiple channel videos, and more." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:381 +msgid "Smash Balloon YouTube Feeds Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:394 +msgid "TrustPulse" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:397 +msgid "Boost your sales and conversions by up to 15% with real-time social proof notifications. TrustPulse helps you show live user activity and purchases to help convince other users to purchase." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:410 +msgid "SearchWP" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:413 +msgid "The most advanced WordPress search plugin. Customize your WordPress search algorithm, reorder search results, track search metrics, and everything you need to leverage search to grow your business." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:424 +msgid "AffiliateWP" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:427 +msgid "The #1 affiliate management plugin for WordPress. Easily create an affiliate program for your eCommerce store or membership site within minutes and start growing your sales with the power of referral marketing." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:439 +msgid "WP Simple Pay" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:442 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:454 +msgid "The #1 Stripe payments plugin for WordPress. Start accepting one-time and recurring payments on your WordPress site without setting up a shopping cart. No code required." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:451 +msgid "WP Simple Pay Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:464 +msgid "Easy Digital Downloads" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:467 +msgid "The best WordPress eCommerce plugin for selling digital downloads. Start selling eBooks, software, music, digital art, and more within minutes. Accept payments, manage subscriptions, advanced access control, and more." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:476 +msgid "Sugar Calendar" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:479 +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:488 +msgid "A simple & powerful event calendar plugin for WordPress that comes with all the event management features including payments, scheduling, timezones, ticketing, recurring events, and more." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:485 +msgid "Sugar Calendar Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:496 +msgid "WPCode" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:499 +msgid "Future proof your WordPress customizations with the most popular code snippet management plugin for WordPress. Trusted by over 1,500,000+ websites for easily adding code to WordPress right from the admin area." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:508 +msgid "Search & Replace Everything" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:511 +msgid "Efficiently manage your website’s content directly from the WordPress admin with Search & Replace Everything by WPCode. This tool is essential for site migrations, content updates, or any situation where batch text and image replacements are needed." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:520 +msgid "Uncanny Automator" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:523 +msgid "Uncanny Automator is the easiest and most powerful way to automate your WordPress site with no code. Build automations in minutes that connect your WordPress plugins, sites and apps together using billions of recipe combinations." +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:532 +msgid "Database Reset Pro" +msgstr "" + +#: src/Utils/ExtraPlugins/ExtraPluginsMng.php:535 +msgid "" +"Database Reset Pro is the safest and simplest way to reset your WordPress database to its default state. \n" +" Unlike reinstalling WordPress, this database reset plugin preserves your files, uploads, \n" +" and admin credentials while giving you a fresh start in seconds." +msgstr "" + +#: src/Utils/Support/SupportToolkit.php:60 +msgid "Failed to create zip file" +msgstr "" + +#: src/Utils/Upsell.php:24 +#: src/Utils/Upsell.php:50 +#: template/admin_pages/welcome/features.php:54 +msgid "Secure File Encryption" +msgstr "" + +#: src/Utils/Upsell.php:25 +#: src/Utils/Upsell.php:51 +#: template/admin_pages/welcome/features.php:62 +msgid "Server to Server Import" +msgstr "" + +#: src/Utils/Upsell.php:27 +msgid "Cloud Storage - Google Drive" +msgstr "" + +#: src/Utils/Upsell.php:28 +msgid "Cloud Storage - Amazon S3" +msgstr "" + +#: src/Utils/Upsell.php:29 +msgid "Cloud Storage - DropBox" +msgstr "" + +#: src/Utils/Upsell.php:30 +msgid "Cloud Storage - OneDrive" +msgstr "" + +#: src/Utils/Upsell.php:31 +msgid "Cloud Storage - FTP/SFTP" +msgstr "" + +#: src/Utils/Upsell.php:34 +msgid "Multisite Network Support" +msgstr "" + +#: src/Utils/Upsell.php:35 +#: src/Utils/Upsell.php:64 +msgid "Email Alerts" +msgstr "" + +#: src/Utils/Upsell.php:54 +msgid "Smart Migration Wizard" +msgstr "" + +#: src/Utils/Upsell.php:56 +msgid "Streamlined Installer" +msgstr "" + +#: src/Utils/Upsell.php:57 +msgid "Developer Hooks" +msgstr "" + +#: src/Utils/Upsell.php:58 +msgid "Managed Hosting Support" +msgstr "" + +#: src/Utils/Upsell.php:61 +msgid "Migrate Duplicator Settings" +msgstr "" + +#: src/Utils/Upsell.php:62 +msgid "Regenerate SALTS" +msgstr "" + +#: src/Utils/Upsell.php:63 +msgid "Multisite Network" +msgstr "" + +#: src/Utils/Upsell.php:65 +msgid "Custom Search & Replace" +msgstr "" + +#: src/Utils/ZipArchiveExtended.php:357 +msgid "ZipArchive PHP module is not installed/enabled. The current Backup cannot be opened." +msgstr "" + +#: src/Views/AdminNotices.php:198 +msgid "Safe Mode:" +msgstr "" + +#: src/Views/AdminNotices.php:199 +msgid "During the install safe mode was enabled deactivating all plugins.
        Please be sure to " +msgstr "" + +#: src/Views/AdminNotices.php:200 +msgid "re-activate the plugins" +msgstr "" + +#: src/Views/AdminNotices.php:206 +#: views/parts/migration-message.php:17 +msgid "This site has been successfully migrated!" +msgstr "" + +#: src/Views/AdminNotices.php:207 +msgid "Final step(s):" +msgstr "" + +#: src/Views/AdminNotices.php:208 +msgid "This message will be removed after all installer files are removed. Installer files must be removed to maintain a secure site. Click the link above or button below to remove all installer files and complete the migration." +msgstr "" + +#: src/Views/AdminNotices.php:215 +#: views/parts/migration-message.php:52 +msgid "Remove Installation Files Now!" +msgstr "" + +#: src/Views/AdminNotices.php:219 +msgid "Optionally, Review Duplicator at WordPress.org..." +msgstr "" + +#: src/Views/AdminNotices.php:225 +#: src/Views/AdminNotices.php:317 +#: views/parts/migration-almost-complete.php:17 +msgid "Migration Almost Complete!" +msgstr "" + +#: src/Views/AdminNotices.php:226 +msgid "Reserved Duplicator installation files have been detected in the root directory. Please delete these installation files to avoid security issues.
        Go to: Duplicator > Tools > General > Information > Utils and click the \"Remove Installation Files\" button" +msgstr "" + +#: src/Views/AdminNotices.php:244 +#: views/parts/migration-almost-complete.php:33 +msgid "Take me there now!" +msgstr "" + +#: src/Views/AdminNotices.php:260 +msgid "Redirecting Please Wait..." +msgstr "" + +#: src/Views/AdminNotices.php:263 +#: views/settings/storage.php:17 +msgid "Invalid token permissions to perform this request." +msgstr "" + +#: src/Views/AdminNotices.php:307 +msgid "Activate %s" +msgstr "" + +#: src/Views/AdminNotices.php:317 +msgid "Warning!" +msgstr "" + +#: src/Views/AdminNotices.php:318 +msgid "Plugin(s) listed here have been deactivated during installation to help prevent issues. Please activate them to finish this migration: " +msgstr "" + +#: src/Views/AdminNotices.php:340 +msgid "Upgrade failed. Please check if you have the necessary permissions to activate plugins." +msgstr "" + +#: src/Views/AdminNotices.php:406 +msgid "Congrats!" +msgstr "" + +#: src/Views/AdminNotices.php:410 +msgid "" +"You created over %d backups with Duplicator. Great job! If you can spare a minute,\n" +" please help us by leaving a five star review on WordPress.org." +msgstr "" + +#: src/Views/AdminNotices.php:423 +msgid "Sure! I'd love to help" +msgstr "" + +#: src/Views/AdminNotices.php:426 +msgid "Hide Notification" +msgstr "" + +#: src/Views/AdminNotices.php:448 +msgid "" +"Duplicator
        Your logged-in user role does not have export\n" +" capability so you don't have access to Duplicator functionality." +msgstr "" + +#: src/Views/AdminNotices.php:455 +msgctxt "%1$s and %2$s are
        tags" +msgid "RECOMMENDATION: Add export capability to your role. See FAQ: %1$sWhy is the Duplicator/Packages menu missing from my admin menu?%2$s" +msgstr "" + +#: src/Views/DashboardWidget.php:166 +msgid "A Backup is currently running." +msgstr "" + +#: src/Views/DashboardWidget.php:183 +msgid "No Backups have been created yet." +msgstr "" + +#: src/Views/DashboardWidget.php:195 +msgctxt "%s represents the time diff, eg. 2 days" +msgid "%s ago" +msgstr "" + +#: src/Views/EducationElements.php:108 +msgid "Scheduled Backups - Ensure that important data is regularly and consistently backed up, allowing for quick and efficient recovery in case of data loss." +msgstr "" + +#: src/Views/EducationElements.php:110 +msgid "Cloud Backups - Back up to Dropbox, FTP, Google Drive, OneDrive, or Amazon S3 and more for safe storage." +msgstr "" + +#: src/Views/EducationElements.php:111 +msgid "Recovery Points - Recovery Points provides protection against mistakes and bad updates by letting you quickly rollback your system to a known, good state." +msgstr "" + +#: src/Views/EducationElements.php:113 +msgid "Secure File Encryption - Protect and secure the archive file with industry-standard AES-256 encryption" +msgstr "" + +#: src/Views/EducationElements.php:114 +msgid "Server to Server Import - Direct Backup import from source server or cloud storage using URL. No need to download the Backup to your desktop machine first." +msgstr "" + +#: src/Views/EducationElements.php:116 +msgid "File & Database Table Filters - Use file and database filters to pick and choose exactly what you want to backup or transfer. No bloat!" +msgstr "" + +#: src/Views/EducationElements.php:118 +msgid "Large Site Support - Duplicator Pro has developed a new way to package backups especially tailored for larger site. No server timeouts or other restrictions." +msgstr "" + +#: src/Views/EducationElements.php:120 +msgid "Multisite Support - Duplicator Pro supports multisite network backup & migration. You can even install a subsite as a standalone site." +msgstr "" + +#: template/admin_pages/about_us/about_us/extra_plugin_item.php:22 +msgid "Activate" +msgstr "" + +#: template/admin_pages/about_us/about_us/extra_plugin_item.php:28 +msgid "Install Plugin" +msgstr "" + +#: template/admin_pages/about_us/about_us/extra_plugin_item.php:46 +msgid "Status:" +msgstr "" + +#: template/admin_pages/about_us/about_us/info.php:4 +msgid "Hello and welcome to Duplicator, the most reliable WordPress backup and migration plugin. At Duplicator, we build software that helps protect your website with our reliable secure backups and migrate your website without any manual effort." +msgstr "" + +#: template/admin_pages/about_us/about_us/info.php:9 +msgid "Over the years, we found that most WordPress backup and migration plugins were unreliable, buggy, slow, and very hard to use. So we started with a simple goal: build a WordPress backup and migration plugin that’s both easy and powerful." +msgstr "" + +#: template/admin_pages/about_us/about_us/info.php:14 +msgid "Our goal is to take the pain out of creating backups, migrations, and make it easy." +msgstr "" + +#. translators: %1$s - WPBeginner URL; %2$s - OptinMonster URL; %3$s - MonsterInsights URL. +#: template/admin_pages/about_us/about_us/info.php:21 +msgid "Duplicator is brought to you by the same team that’s behind the largest WordPress resource site, WPBeginner, the most popular lead-generation software, OptinMonster, the best WordPress analytics plugin, MonsterInsights, and more!" +msgstr "" + +#: template/admin_pages/about_us/about_us/info.php:43 +msgid "Yup, we know a thing or two about building awesome products that customers love." +msgstr "" + +#: template/admin_pages/about_us/about_us/info.php:49 +msgid "The Awesome Motive Team photo" +msgstr "" + +#: template/admin_pages/about_us/about_us/info.php:51 +msgid "The Awesome Motive Team" +msgstr "" + +#: template/admin_pages/about_us/getting_started/first_package.php:25 +msgid "Creating Your First Backup" +msgstr "" + +#: template/admin_pages/about_us/getting_started/first_package.php:28 +msgid "Want to get started creating your first Backup with Duplicator? By following the step by step instructions in this walkthrough, you can easily create a backup or migration." +msgstr "" + +#: template/admin_pages/about_us/getting_started/first_package.php:32 +msgid "To begin, you’ll need to be logged into the WordPress admin area. Once there, click on Duplicator in the admin sidebar to go the Backups page." +msgstr "" + +#: template/admin_pages/about_us/getting_started/first_package.php:36 +msgid "In the Backups page, the Backups list will be empty because there are no Backups yet. To create a new Backup, click on the Create New button, and this will launch the Backup Creation Wizard." +msgstr "" + +#: template/admin_pages/about_us/getting_started/first_package.php:47 +msgid "Quick Start Guide" +msgstr "" + +#: template/admin_pages/about_us/getting_started/first_package.php:56 +msgid "How to Create a Backup" +msgstr "" + +#: template/admin_pages/about_us/getting_started/first_package.php:65 +msgid "How to Migrate to a New Site" +msgstr "" + +#: template/admin_pages/about_us/getting_started/get_pro.php:26 +#: template/parts/Education/callout-cta.php:23 +msgid "Get Duplicator Pro and Unlock all the Powerful Features" +msgstr "" + +#: template/admin_pages/about_us/getting_started/get_pro.php:32 +msgid "Thanks for being a loyal Duplicator Lite user. Upgrade to Duplicator Pro to unlock all the awesome features and experience
        why Duplicator is consistently rated the best WordPress migration plugin." +msgstr "" + +#. translators: %s - stars. +#: template/admin_pages/about_us/getting_started/get_pro.php:49 +msgid "We know that you will truly love Duplicator. It has over 4000+ five star ratings (%s) and is active on over 1 million websites." +msgstr "" + +#: template/admin_pages/about_us/getting_started/get_pro.php:94 +#: template/admin_pages/about_us/lite_vs_pro/main.php:104 +msgid "Get Duplicator Pro Today and Unlock all the Powerful Features" +msgstr "" + +#: template/admin_pages/about_us/getting_started/get_pro.php:102 +#: template/admin_pages/about_us/lite_vs_pro/main.php:112 +msgid "Bonus: Duplicator Lite users get %1$d%% off regular price, automatically applied at checkout." +msgstr "" + +#: template/admin_pages/about_us/lite_vs_pro/main.php:27 +msgid "Lite vs Pro" +msgstr "" + +#: template/admin_pages/about_us/lite_vs_pro/main.php:39 +msgid "Get the most out of Duplicator by upgrading to Pro and unlocking all of the powerful features." +msgstr "" + +#: template/admin_pages/about_us/lite_vs_pro/main.php:48 +msgid "Feature" +msgstr "" + +#: template/admin_pages/about_us/lite_vs_pro/main.php:53 +msgid "Lite" +msgstr "" + +#: template/admin_pages/about_us/lite_vs_pro/main.php:58 +msgid "Pro" +msgstr "" + +#: template/admin_pages/about_us/lite_vs_pro/main.php:77 +#: template/admin_pages/about_us/lite_vs_pro/main.php:87 +msgid "Included" +msgstr "" + +#: template/admin_pages/about_us/lite_vs_pro/main.php:78 +msgid "Not Available" +msgstr "" + +#: template/admin_pages/about_us/tabs.php:21 +msgid "Getting Started" +msgstr "" + +#: template/admin_pages/about_us/tabs.php:25 +msgid "Lite vs Pro" +msgstr "" + +#: template/admin_pages/settings/general/email_summary.php:20 +msgid "Email Summary" +msgstr "" + +#: template/admin_pages/settings/general/email_summary.php:24 +msgid "Frequency" +msgstr "" + +#: template/admin_pages/settings/general/email_summary.php:37 +msgctxt "%1s and %2s are the opening and close tags to the summary preview link" +msgid "You can view the email summary example %1shere%2s." +msgstr "" + +#: template/admin_pages/settings/general/email_summary.php:45 +#: template/mail/email_summary.php:178 +msgctxt "%1s and %2s are opening and closing link tags to the documentation." +msgid "Learn %1show to disable%2s." +msgstr "" + +#: template/admin_pages/settings/general/general.php:26 +msgid "General Settings Saved" +msgstr "" + +#: template/admin_pages/settings/general/general.php:87 +msgid "Advanced" +msgstr "" + +#: template/admin_pages/settings/general/general.php:94 +msgid "Reset Backups" +msgstr "" + +#: template/admin_pages/settings/general/general.php:98 +msgid "This process will reset all Backups by deleting those without a completed status, reset the active Backup id and perform a cleanup of the build tmp file." +msgstr "" + +#: template/admin_pages/settings/general/general.php:102 +msgid "Reset Settings" +msgstr "" + +#: template/admin_pages/settings/general/general.php:104 +msgid "This action should only be used if the Backups screen is having issues or a build is stuck." +msgstr "" + +#: template/admin_pages/settings/general/general.php:110 +msgid "Backup scan" +msgstr "" + +#: template/admin_pages/settings/general/general.php:113 +#: template/admin_pages/welcome/intro.php:48 +msgid "Skip" +msgstr "" + +#: template/admin_pages/settings/general/general.php:116 +msgid "If enabled all files check on scan will be skipped before Backup creation. In some cases, this option can be beneficial if the scan process is having issues running or returning errors." +msgstr "" + +#: template/admin_pages/settings/general/general.php:123 +msgid "Foreign JavaScript" +msgstr "" + +#: template/admin_pages/settings/general/general.php:126 +#: template/admin_pages/settings/general/general.php:140 +msgid "Disable" +msgstr "" + +#: template/admin_pages/settings/general/general.php:129 +msgid "Check this option if other plugins/themes JavaScript files are conflicting with Duplicator." +msgstr "" + +#: template/admin_pages/settings/general/general.php:131 +#: template/admin_pages/settings/general/general.php:145 +msgid "Do not modify this setting unless you know the expected result or have talked to support." +msgstr "" + +#: template/admin_pages/settings/general/general.php:137 +msgid "Foreign CSS" +msgstr "" + +#: template/admin_pages/settings/general/general.php:143 +msgid "Check this option if other plugins/themes CSS files are conflicting with Duplicator." +msgstr "" + +#: template/admin_pages/settings/general/general.php:159 +msgid "Save General Settings" +msgstr "" + +#: template/admin_pages/settings/general/general.php:170 +msgid "Reset Backups ?" +msgstr "" + +#: template/admin_pages/settings/general/general.php:171 +msgid "This will clear and reset all of the current temporary Backups. Would you like to continue?" +msgstr "" + +#: template/admin_pages/settings/general/general.php:172 +msgid "Resetting settings, Please Wait..." +msgstr "" + +#: template/admin_pages/settings/general/general.php:176 +msgid "No" +msgstr "" + +#: template/admin_pages/settings/general/general.php:182 +msgid "AJAX Call Error!" +msgstr "" + +#: template/admin_pages/settings/general/general.php:184 +msgctxt "1 and 2 are opening and closing tags" +msgid "AJAX error encountered when resetting Backups. Please see %1$sthis FAQ entry%2$s for possible resolutions." +msgstr "" + +#: template/admin_pages/settings/general/general.php:234 +msgid "Backups successfully reset" +msgstr "" + +#: template/admin_pages/settings/general/license.php:16 +msgid "License" +msgstr "" + +#: template/admin_pages/settings/general/license.php:20 +msgid "License Key" +msgstr "" + +#: template/admin_pages/settings/general/license.php:23 +msgid "You're using Duplicator Lite - no license needed. Enjoy!" +msgstr "" + +#: template/admin_pages/settings/general/license.php:27 +msgid "" +"To unlock more features consider upgrading to PRO." +msgstr "" + +#: template/admin_pages/settings/general/license.php:45 +msgid "As a valued Duplicator Lite user you receive %1$d%% off, automatically applied at checkout!" +msgstr "" + +#: template/admin_pages/settings/general/license.php:55 +msgid "Already purchased? Connect to unlock Duplicator PRO!" +msgstr "" + +#: template/admin_pages/settings/general/license.php:58 +msgid "Connect to Duplicator Pro" +msgstr "" + +#: template/admin_pages/settings/general/license.php:62 +msgid "This opens connect.duplicator.com where you'll securely connect to Duplicator Pro." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:19 +msgid "All information sent to the server is anonymous." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:20 +msgid "No information about storage or Backup's content are sent." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:26 +msgid "" +"Usage tracking for Duplicator helps us better understand our users and their website needs by looking \n" +" at a range of server and website environments." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:33 +msgid "This allows us to continuously improve our product as well as our Q&A / testing process." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:35 +msgid "Below is the list of information that Duplicator collects as part of the usage tracking:" +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:40 +msgid "PHP Version: so we know which PHP versions we have to test against (no one likes whitescreens or log files full of errors)." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:48 +msgid "WordPress Version: so we know which WordPress versions to support and test against." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:56 +msgid "MySQL Version: so we know which versions of MySQL to support and test against for our custom tables." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:64 +msgid "" +"Duplicator Version: so we know which versions of Duplicator are potentially responsible for issues when we get bug reports, \n" +" allowing us to identify issues and release solutions much faster." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:73 +msgid "Plugins and Themes infos: so we can figure out which ones can generate compatibility errors with Duplicator." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:81 +msgid "" +"Site info: General information about the site such as database, file size, number of users, and sites in case it is a multisite. \n" +" This is useful for us to understand the critical issues of Backup creation." +msgstr "" + +#: template/admin_pages/settings/general/usage_tracking_tooltip.php:90 +msgid "Backups infos: Information about the Backups created and the type of components included." +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:24 +msgid "Misc Settings Saved" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:88 +msgid "Plugin" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:100 +msgid "Uninstall" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:104 +msgid "Delete Plugin Settings" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:108 +msgid "Delete Entire Storage Directory" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:113 +msgid "Usage statistics" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:117 +msgid "Usage statistics are hardcoded disallowed." +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:127 +msgid "Enable usage tracking" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:130 +msgid "Usage Tracking" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:139 +msgid "Hide Announcements" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:148 +msgid "Check this option to hide plugin announcements and update details." +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:154 +msgid "Debug" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:158 +msgid "Debugging" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:161 +msgid "Enable debug options throughout user interface" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:165 +msgid "Trace Log" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:171 +msgid "Turns on detailed operation logging. Logging will occur in both PHP error and local trace logs." +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:173 +msgid "WARNING: Only turn on this setting when asked to by support as tracing will impact performance." +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:181 +msgid "Download Trace Log" +msgstr "" + +#: template/admin_pages/settings/misc/misc.php:194 +msgid "Save Misc Settings" +msgstr "" + +#: template/admin_pages/welcome/features.php:21 +msgid "Duplicator Features" +msgstr "" + +#: template/admin_pages/welcome/features.php:22 +msgid "Duplicator is both easy to use and extremely powerful. We have tons of helpful features that allow us to give you everything you need from a backup & migration plugin." +msgstr "" + +#: template/admin_pages/welcome/features.php:30 +msgid "Ensure that important data is regularly and consistently backed up, allowing for quick and efficient recovery in case of data loss." +msgstr "" + +#: template/admin_pages/welcome/features.php:37 +msgid "Cloud Backups" +msgstr "" + +#: template/admin_pages/welcome/features.php:39 +msgid "Back up to Dropbox, FTP, Google Drive, OneDrive, or Amazon S3 and more for safe storage." +msgstr "" + +#: template/admin_pages/welcome/features.php:47 +#: template/mocks/recovery/content-popup.php:14 +msgid "Recovery Points provides protection against mistakes and bad updates by letting you quickly rollback your system to a known, good state." +msgstr "" + +#: template/admin_pages/welcome/features.php:56 +#: views/packages/main/s1.setup2.php:354 +msgid "Protect and secure the Backup file with industry-standard AES-256 encryption." +msgstr "" + +#: template/admin_pages/welcome/features.php:64 +msgid "Direct Backup import from source server or cloud storage using URL. No need to download the Backup to your desktop machine first." +msgstr "" + +#: template/admin_pages/welcome/features.php:73 +msgid "Use file and database filters to pick and choose exactly what you want to backup or transfer. No bloat!" +msgstr "" + +#: template/admin_pages/welcome/features.php:80 +msgid "Large Site Support" +msgstr "" + +#: template/admin_pages/welcome/features.php:82 +msgid "Duplicator Pro has developed a new way to package backups especially tailored for larger site. No server timeouts or other restrictions." +msgstr "" + +#: template/admin_pages/welcome/features.php:89 +msgid "Multisite Support" +msgstr "" + +#: template/admin_pages/welcome/features.php:91 +msgid "Duplicator Pro supports multisite network backup & migration. You can even install a subsite as a standalone site." +msgstr "" + +#: template/admin_pages/welcome/features.php:101 +msgid "See All Features" +msgstr "" + +#: template/admin_pages/welcome/footer.php:25 +msgid "Create Your First Backup" +msgstr "" + +#: template/admin_pages/welcome/footer.php:34 +#: template/parts/help/main.php:242 +msgid "Upgrade to Duplicator Pro" +msgstr "" + +#: template/admin_pages/welcome/intro.php:23 +msgid "Willie the Duplicator mascot" +msgstr "" + +#: template/admin_pages/welcome/intro.php:26 +msgid "Never miss an important update" +msgstr "" + +#: template/admin_pages/welcome/intro.php:30 +msgid "Opt in to get email notifications for security & feature updates, educational content, and occasional offers, and to share some basic WordPress environment info. This will help us make the plugin more compatible with your site and better at doing what you need it to." +msgstr "" + +#: template/admin_pages/welcome/intro.php:40 +msgid "Allow & Continue" +msgstr "" + +#: template/admin_pages/welcome/intro.php:55 +msgid "This will allow Duplicator to" +msgstr "" + +#: template/admin_pages/welcome/intro.php:63 +msgid "View Basic Profile Info" +msgstr "" + +#: template/admin_pages/welcome/intro.php:66 +msgid "Basic Profile Info" +msgstr "" + +#: template/admin_pages/welcome/intro.php:68 +msgid "Never miss important updates, get security warnings before they become public knowledge, and receive notifications about special offers and awesome new features." +msgstr "" + +#: template/admin_pages/welcome/intro.php:77 +msgid "Your WordPress user's: first & last name, and email address" +msgstr "" + +#: template/admin_pages/welcome/intro.php:88 +msgid "View Basic Website Info" +msgstr "" + +#: template/admin_pages/welcome/intro.php:91 +msgid "Basic Website Info" +msgstr "" + +#: template/admin_pages/welcome/intro.php:93 +msgid "To provide additional functionality that's relevant to your website, avoid WordPress or PHP version incompatibilities that can break your website, and recognize which languages & regions the plugin should be translated and tailored to." +msgstr "" + +#: template/admin_pages/welcome/intro.php:103 +msgid "Homepage URL & title, WP & PHP versions, and site language" +msgstr "" + +#: template/admin_pages/welcome/intro.php:113 +msgid "View Basic Plugin Info" +msgstr "" + +#: template/admin_pages/welcome/intro.php:115 +msgid "Current plugin & SDK versions, and if active or uninstalled" +msgstr "" + +#: template/admin_pages/welcome/intro.php:126 +msgid "View Plugins & Themes List" +msgstr "" + +#: template/admin_pages/welcome/intro.php:129 +msgid "Plugins & Themes List" +msgstr "" + +#: template/admin_pages/welcome/intro.php:131 +msgid "To ensure compatibility and avoid conflicts with your installed plugins and themes." +msgstr "" + +#: template/admin_pages/welcome/intro.php:139 +msgid "Names, slugs, versions, and if active or not" +msgstr "" + +#: template/admin_pages/welcome/testimonials.php:20 +msgid "Testimonials" +msgstr "" + +#: template/admin_pages/welcome/testimonials.php:27 +msgid "It walked me step-by-step through the process of migrating a WordPress website. If you want to save a ton of time with WP migration, I very much recommend this plugin!" +msgstr "" + +#: template/admin_pages/welcome/testimonials.php:44 +msgid "Duplicator Pro is the best WordPress migration & backup plugin I have ever used. I will be recommending this plugin to everyone I can." +msgstr "" + +#: template/admin_pages/welcome/upgrade-cta.php:21 +msgid "Upgrade to PRO" +msgstr "" + +#: template/admin_pages/welcome/upgrade-cta.php:36 +#: template/mocks/storage/popup.php:37 +#: template/mocks/storage/storage.php:68 +msgid "Upgrade Now" +msgstr "" + +#: template/mail/email_summary.php:72 +msgid "Hi there!" +msgstr "" + +#: template/mail/email_summary.php:76 +msgctxt "%s is the frequency of email summaries." +msgid "Here's a quick overview of your backups in the past %s." +msgstr "" + +#: template/mail/email_summary.php:87 +msgid "Did you know?" +msgstr "" + +#: template/mail/email_summary.php:92 +msgid "With Duplicator Pro you can create fully automatic backups! Schedule your preferred intervals for backups - daily, weekly, or monthly and never worry about data loss again!" +msgstr "" + +#: template/mail/email_summary.php:98 +msgid "With Duplicator Pro you can store backups in Google Drive, Amazon S3, OneDrive, Dropbox, or any SFTP/FTP server for added protection." +msgstr "" + +#: template/mail/email_summary.php:109 +msgctxt "%s and %s are opening and closing link tags to the pricing page." +msgid "To unlock scheduled backups, remote storages and many other features, %supgrade to PRO%s!" +msgstr "" + +#: template/mail/email_summary.php:122 +msgid "Below are the total numbers of successful and failed backups." +msgstr "" + +#: template/mail/email_summary.php:127 +msgid "State" +msgstr "" + +#: template/mail/email_summary.php:152 +msgid "No backups were created in the past week." +msgstr "" + +#: template/mail/email_summary.php:164 +msgctxt "%s is an tag with a link to the current website." +msgid "This email was auto-generated and sent from %s." +msgstr "" + +#: template/mocks/db_reset/db_reset.php:17 +msgid "Clean & Reset WordPress Database" +msgstr "" + +#: template/mocks/import/content-popup.php:18 +msgid "In addition to the classic installer method on an empty site, Duplicator Pro now supports Drag and Drop migrations and site restores! Simply drag the bundled site Backup to the site you wish to overwrite." +msgstr "" + +#: template/mocks/import/import.php:17 +#: views/packages/main/packages.php:126 +msgid "Import" +msgstr "" + +#: template/mocks/import/import.php:26 +msgctxt "%1$s and %2$s are opening and closing span tags" +msgid "Step %1$s1%2$s of 2: Upload Backup" +msgstr "" + +#: template/mocks/import/import.php:211 +msgid "Overwrite a WordPress site with Drag and Drop Import!" +msgstr "" + +#: template/mocks/import/import.php:212 +msgid "Drag and Drop Import is not available in Duplicator Lite!" +msgstr "" + +#: template/mocks/recovery/recovery.php:16 +#: template/parts/DashboardWidget/sections-section.php:98 +msgid "Recovery Point" +msgstr "" + +#: template/mocks/recovery/recovery.php:20 +msgid "Quickly restore this site to a specific point in time." +msgstr "" + +#: template/mocks/recovery/recovery.php:21 +msgid "Need more help?" +msgstr "" + +#: template/mocks/recovery/recovery.php:117 +msgid "Rollback your sites with Recovery Points!" +msgstr "" + +#: template/mocks/recovery/recovery.php:118 +msgid "Recovery Points are not supported in Duplicator Lite!" +msgstr "" + +#: template/mocks/schedule/content-popup.php:14 +msgid "Scheduled Backups provide peace of mind and ensure that critical data can be quickly and easily restored in the event of a disaster or loss. Duplicator Pro supports Hourly, Daily, Weekly and Monthly scheduled backups." +msgstr "" + +#: template/mocks/schedule/content-popup.php:23 +msgid "Supported Cloud Storage: Google Drive, Dropbox, Microsoft One Drive, Amazon S3 (or any compatible S3 service), and FTP/SFTP Storage." +msgstr "" + +#: template/mocks/schedule/schedules.php:16 +msgid "Schedules" +msgstr "" + +#: template/mocks/schedule/schedules.php:279 +msgid "Automate your workflow with scheduled backups!" +msgstr "" + +#: template/mocks/schedule/schedules.php:280 +msgid "Duplicator Lite does not support scheduled backups!" +msgstr "" + +#: template/mocks/settings/access/capabilities.php:15 +msgid "Roles and Permissions" +msgstr "" + +#: template/mocks/settings/access/capabilities.php:19 +msgid "Select the user roles and/or users that are allowed to manage different aspects of Duplicator." +msgstr "" + +#: template/mocks/settings/access/capabilities.php:20 +msgid "By default, all permissions are provided only to administrator users." +msgstr "" + +#: template/mocks/settings/access/capabilities.php:21 +msgid "Some capabilities depend on others so If you select for example storage capability automatically the Backup read and Backup edit capabilities are assigned" +msgstr "" + +#: template/mocks/settings/access/capabilities.php:23 +msgid "It is not possible to self remove the manage settings capabilities." +msgstr "" + +#: template/mocks/settings/access/capabilities.php:28 +msgid "Backup Read " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:32 +#: template/mocks/settings/access/capabilities.php:42 +#: template/mocks/settings/access/capabilities.php:52 +#: template/mocks/settings/access/capabilities.php:62 +#: template/mocks/settings/access/capabilities.php:72 +#: template/mocks/settings/access/capabilities.php:82 +#: template/mocks/settings/access/capabilities.php:92 +#: template/mocks/settings/access/capabilities.php:102 +#: template/mocks/settings/access/capabilities.php:112 +msgid "Administrator" +msgstr "" + +#: template/mocks/settings/access/capabilities.php:38 +msgid " - Backup Edit " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:48 +msgid " - - Manage Schedules " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:58 +msgid " - - Manage Storages " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:68 +msgid " - Restore Backup " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:78 +msgid " - - Backup Import " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:88 +msgid " - Backup Export " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:98 +msgid " - Manage Settings " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:108 +msgid " - - Manage License Settings " +msgstr "" + +#: template/mocks/settings/access/capabilities.php:124 +msgid "Advanced Backup Permissions are not available in Duplicator Lite!" +msgstr "" + +#: template/mocks/settings/access/content-popup.php:15 +msgid "Elevate your backup capabilities with advanced permissions, allowing for precise control over the creation, exportation, restoration, and management of control settings. Enjoy granular access control to ensure only authorized users can perform these critical functions." +msgstr "" + +#: template/mocks/storage/popup.php:17 +msgid "Store to Multiple Endpoints with Duplicator Pro" +msgstr "" + +#: template/mocks/storage/popup.php:30 +msgid "Set up one-time storage locations and automatically push the Backup to your destination." +msgstr "" + +#: template/mocks/storage/storage.php:61 +msgid "Remote Cloud Backups is a PRO feature" +msgstr "" + +#: template/mocks/storage/storage.php:62 +msgid "Back up to Dropbox, FTP, Google Drive, OneDrive, Amazon S3 or Amazon S3 compatible for safe off-site storage." +msgstr "" + +#: template/mocks/storage/storage.php:79 +#: views/packages/main/packages.php:93 +msgid "Bulk Actions" +msgstr "" + +#: template/mocks/storage/storage.php:81 +#: views/packages/main/packages.php:96 +msgid "Delete" +msgstr "" + +#: template/mocks/storage/storage.php:84 +#: views/packages/main/packages.php:101 +msgid "Apply" +msgstr "" + +#: template/mocks/storage/storage.php:93 +msgid "Add New" +msgstr "" + +#: template/mocks/storage/storage.php:108 +#: views/packages/details/detail.php:98 +#: views/packages/details/detail.php:286 +#: views/packages/details/detail.php:422 +#: views/packages/main/packages.php:194 +#: views/packages/main/s1.setup2.php:84 +#: views/packages/main/s1.setup2.php:121 +#: views/packages/main/s2.scan3.php:729 +msgid "Name" +msgstr "" + +#: template/mocks/storage/storage.php:109 +#: views/packages/details/detail.php:287 +#: views/packages/details/detail.php:426 +#: views/packages/main/s1.setup2.php:122 +msgid "Type" +msgstr "" + +#: template/mocks/storage/storage.php:119 +#: views/packages/details/detail.php:294 +#: views/packages/main/s1.setup2.php:132 +msgid "Default" +msgstr "" + +#: template/mocks/storage/storage.php:122 +#: views/packages/details/detail.php:307 +#: views/packages/main/s1.setup2.php:145 +msgid "Local" +msgstr "" + +#: template/mocks/storage/storage.php:146 +msgid "Total: %s" +msgstr "" + +#: template/mocks/templates/content-popup.php:14 +msgid "If you install the same theme, plugins or content on all your WordPress sites then Duplicator can save you a lot of time." +msgstr "" + +#: template/mocks/templates/content-popup.php:22 +msgid "Instead of manually configuring the same themes and plugins over and over, just configure one site and bundle it into a Duplicator Backup. Install the Backup to create a pre-configured site on as many locations as you want!" +msgstr "" + +#: template/mocks/templates/templates.php:194 +msgid "Easily customize your backups with templates!" +msgstr "" + +#: template/mocks/templates/templates.php:195 +msgid "Templates are not available in Duplicator Lite!" +msgstr "" + +#: template/mocks/transfer/content-popup.php:14 +msgid "With manual transfers you can upload your backup to remote storages even after you have created them." +msgstr "" + +#: template/mocks/transfer/transfer.php:230 +msgid "Manually transfer backups to remote storages!" +msgstr "" + +#: template/mocks/transfer/transfer.php:231 +msgid "Remote storages are not available in Duplicator Lite!" +msgstr "" + +#: template/parts/cross_promotion/item.php:23 +#: template/parts/DashboardWidget/recommended-section.php:42 +msgid "Install" +msgstr "" + +#: template/parts/cross_promotion/list.php:25 +msgid "Enjoying Duplicator? Check out a couple of our other free plugins..." +msgstr "" + +#: template/parts/DashboardWidget/package-create-section.php:22 +msgid "Backup creation" +msgstr "" + +#: template/parts/DashboardWidget/package-create-section.php:23 +msgid "This will create a new Backup. If a Backup is currently running then this button will be disabled." +msgstr "" + +#: template/parts/DashboardWidget/package-create-section.php:31 +msgid "Last backup:" +msgstr "" + +#: template/parts/DashboardWidget/package-create-section.php:46 +#: views/packages/main/packages.php:142 +#: views/packages/main/s3.build.php:138 +msgid "Create New" +msgstr "" + +#: template/parts/DashboardWidget/recently-packages.php:28 +msgid "Recently Backups" +msgstr "" + +#: template/parts/DashboardWidget/recently-packages.php:47 +msgid "Backups: %1$d, Failures: %2$d" +msgstr "" + +#: template/parts/DashboardWidget/recommended-section.php:36 +msgid "Recommended Plugin:" +msgstr "" + +#: template/parts/DashboardWidget/recommended-section.php:45 +msgid "Learn More" +msgstr "" + +#: template/parts/DashboardWidget/recommended-section.php:50 +msgid "Dismiss recommended plugin" +msgstr "" + +#: template/parts/DashboardWidget/sections-section.php:40 +msgid "%s Schedule" +msgid_plural "%s Schedules" +msgstr[0] "" +msgstr[1] "" + +#: template/parts/DashboardWidget/sections-section.php:56 +#: views/packages/main/s1.setup2.php:563 +msgid "Next" +msgstr "" + +#: template/parts/DashboardWidget/sections-section.php:65 +msgid "%s Storage" +msgid_plural "%s Storages" +msgstr[0] "" +msgstr[1] "" + +#: template/parts/DashboardWidget/sections-section.php:82 +msgid "%s Template" +msgid_plural "%s Templates" +msgstr[0] "" +msgstr[1] "" + +#: template/parts/DashboardWidget/sections-section.php:103 +msgid "Not set" +msgstr "" + +#: template/parts/Education/callout-cta.php:22 +#: template/parts/Notifications/main.php:24 +msgid "Dismiss this message" +msgstr "" + +#: template/parts/Education/callout-cta.php:25 +msgid "Thanks for being a loyal Duplicator Lite user. Upgrade to Duplicator Pro to unlock all the awesome features and experience why Duplicator is consistently rated the best WordPress migration plugin." +msgstr "" + +#. translators: %s - star icons. +#: template/parts/Education/callout-cta.php:35 +msgid "We know that you will truly love Duplicator. It has over 4000+ five star ratings (%s) and is active on over 1 million websites." +msgstr "" + +#: template/parts/Education/callout-cta.php:51 +msgid "Pro Features:" +msgstr "" + +#: template/parts/Education/callout-cta.php:67 +msgid "Get Duplicator Pro Today and Unlock all the Powerful Features »" +msgstr "" + +#: template/parts/Education/callout-cta.php:73 +msgid "Bonus: Duplicator Lite users get %1$d%% off regular price,automatically applied at checkout." +msgstr "" + +#: template/parts/Education/did-you-know-blurb.php:22 +msgid "Did you know Duplicator Pro has: %s?" +msgstr "" + +#: template/parts/Education/did-you-know-blurb.php:24 +#: views/packages/main/s1.setup2.php:359 +msgid "Upgrade To Pro" +msgstr "" + +#: template/parts/Education/packages-bottom-bar.php:27 +msgid "Upgrade to Pro to Unlock..." +msgstr "" + +#: template/parts/Education/packages-bottom-bar.php:36 +msgid "Upgrade Now & Save!" +msgstr "" + +#: template/parts/Education/static-popup.php:31 +msgid "Upgrade to Duplicator Pro Now" +msgstr "" + +#: template/parts/Education/subscribe-form.php:24 +msgid "Email Address" +msgstr "" + +#: template/parts/Education/subscribe-form.php:29 +msgid "Get tips and product updates straight to your inbox." +msgstr "" + +#: template/parts/filters/package_components.php:26 +msgid "Backup components allow you to include/exclude differents part of your WordPress installation in the Backup.

        Database: Include the database in the Backup.
        Plugins: Include the plugins in the Backup. With the 'active only' option enabled, only active plugins will be included in the Backup.
        Themes: Include the themes in the Backup. With the 'active only' option enabled, only active themes will be included in the Backup.
        Media: Include the 'uploads' folder.
        Other: Include non-WordPress files and folders in the root directory.
        " +msgstr "" + +#: template/parts/filters/package_components.php:35 +msgid "File filters allow you to exclude files and folders from the Backup. To enable path and extension filters check the checkbox. Enter the full path of the files and folders you want to exclude from the Backup as a semicolon (;) seperated list." +msgstr "" + +#: template/parts/filters/package_components.php:37 +msgid "File extension filters allow you to exclude files with certain file extensions from the Backup e.g. zip;rar;pdf etc. Enter the file extensions you want to exclude from the Backup as a semicolon (;) seperated list." +msgstr "" + +#: template/parts/filters/package_components.php:45 +msgid "Components" +msgstr "" + +#: template/parts/filters/package_components.php:47 +msgid "Backup Components (Pro feature)" +msgstr "" + +#: template/parts/filters/package_components.php:82 +#: views/packages/details/detail.php:518 +#: views/packages/main/s1.setup2.php:214 +#: views/packages/main/s1.setup2.php:486 +#: views/packages/main/s2.scan3.php:410 +#: views/packages/main/s2.scan3.php:735 +#: views/settings/packages.php:92 +msgid "Database" +msgstr "" + +#: template/parts/filters/package_components.php:89 +msgid "Plugins" +msgstr "" + +#: template/parts/filters/package_components.php:95 +msgid "Only Active Plugins" +msgstr "" + +#: template/parts/filters/package_components.php:102 +msgid "Themes" +msgstr "" + +#: template/parts/filters/package_components.php:108 +msgid "Only Active Themes" +msgstr "" + +#: template/parts/filters/package_components.php:115 +msgid "Media" +msgstr "" + +#: template/parts/filters/package_components.php:122 +msgid "Other" +msgstr "" + +#: template/parts/filters/package_components.php:130 +#: views/packages/details/detail.php:378 +#: views/packages/details/detail.php:443 +#: views/packages/main/s1.setup2.php:226 +msgid "Filters" +msgstr "" + +#: template/parts/filters/package_components.php:132 +msgid "Enable" +msgstr "" + +#: template/parts/filters/package_components.php:134 +msgid "Path Filters" +msgstr "" + +#: template/parts/filters/package_components.php:140 +msgid "root path" +msgstr "" + +#: template/parts/filters/package_components.php:145 +msgid "cache" +msgstr "" + +#: template/parts/filters/package_components.php:147 +#: template/parts/filters/package_components.php:166 +msgid "clear" +msgstr "" + +#: template/parts/filters/package_components.php:157 +#: template/parts/filters/package_components.php:159 +msgid "File Extensions" +msgstr "" + +#: template/parts/filters/package_components.php:164 +msgid "media" +msgstr "" + +#: template/parts/filters/package_components.php:165 +#: views/packages/details/detail.php:193 +#: views/packages/details/detail.php:207 +#: views/packages/details/detail.php:354 +#: views/packages/main/packages.php:203 +#: views/packages/main/packages.php:295 +#: views/packages/main/s1.setup2.php:187 +#: views/packages/main/s2.scan3.php:29 +#: views/packages/main/s2.scan3.php:728 +#: views/settings/packages.php:251 +msgid "Backup" +msgstr "" + +#: template/parts/filters/package_components.php:174 +msgid "Overview:
        This advanced option excludes all files from the Backup. Only the database and a copy of the installer.php will be included in the archive.zip file. The option can be used for backing up and moving only the database." +msgstr "" + +#: template/parts/filters/package_components.php:187 +msgid " Notice:
        Installing only the database over an existing site may have unintended consequences. Be sure to know the state of your system before installing the database without the associated files. " +msgstr "" + +#: template/parts/filters/package_components.php:200 +msgid "For example, if you have WordPress 5.6 on this site and you copy this site's database to a host that has WordPress 5.8 files then the source code of the files will not be in sync with the database causing possible errors. This can also be true of plugins and themes. When moving only the database be sure to know the database will be compatible with ALL source code files. Please use this advanced feature with caution!" +msgstr "" + +#: template/parts/filters/package_components.php:212 +msgid "Install Time:
        When installing a database only Backup please visit the " +msgstr "" + +#: template/parts/filters/package_components.php:223 +msgid "database only quick start" +msgstr "" + +#: template/parts/filters/package_components.php:232 +msgctxt "%1$s and %2$s represents the opening and closing HTML tags for an anchor or link." +msgid "The Media Only and Custom options are not included in Duplicator Lite. To enable advanced options please %1$supgrade to Pro%2$s." +msgstr "" + +#: template/parts/help/main.php:205 +msgid "Search" +msgstr "" + +#: template/parts/help/main.php:207 +msgid "No results found" +msgstr "" + +#: template/parts/help/main.php:211 +msgid "Related Articles" +msgstr "" + +#: template/parts/help/main.php:221 +msgid "View Documentation" +msgstr "" + +#: template/parts/help/main.php:223 +msgid "Browse documentation, reference material, and tutorials for Duplicator." +msgstr "" + +#: template/parts/help/main.php:230 +msgid "View All Documentation" +msgstr "" + +#: template/parts/help/main.php:235 +msgid "Get Support" +msgstr "" + +#: template/parts/help/main.php:236 +msgid "Upgrade to Duplicator Pro to access our world class customer support." +msgstr "" + +#. translators: %s - duplicator.com Upgrade page URL. +#: template/parts/notice-bar.php:44 +msgid "You're using Duplicator Lite. To unlock more features consider upgrading to Pro" +msgstr "" + +#: template/parts/notice-bar.php:65 +msgid "Dismiss this message." +msgstr "" + +#: template/parts/Notifications/main.php:20 +msgid "Notifications" +msgstr "" + +#: template/parts/Notifications/main.php:29 +msgid "Previous message" +msgstr "" + +#: template/parts/Notifications/main.php:33 +msgid "Next message" +msgstr "" + +#: template/parts/Notifications/single-message.php:21 +msgid "Watch video" +msgstr "" + +#: template/parts/plugin-footer.php:28 +msgid "Support" +msgstr "" + +#: template/parts/plugin-footer.php:32 +msgid "Docs" +msgstr "" + +#: template/parts/plugin-footer.php:36 +msgid "Migration Services" +msgstr "" + +#: template/parts/plugin-footer.php:40 +msgid "Free Plugins" +msgstr "" + +#: template/parts/plugin-footer.php:48 +msgid "Made with ♥ by the Duplicator Team" +msgstr "" + +#: views/packages/details/controller.php:29 +msgctxt "%1$s represents the Backup name" +msgid "Backup Details » %1$s" +msgstr "" + +#: views/packages/details/controller.php:43 +msgctxt "%1 and %2 are replaced with and respectively" +msgid "This Backup contains an error. Please review the %1$sBackup log%2$s for details." +msgstr "" + +#: views/packages/details/controller.php:53 +msgctxt "%1, %3 and %2, %4 are replaced with and respectively" +msgid "For help visit the %1$sFAQ%2$s and %3$sresources page%4$s." +msgstr "" + +#: views/packages/details/controller.php:70 +msgid "Details" +msgstr "" + +#: views/packages/details/controller.php:73 +msgid "Transfer" +msgstr "" + +#: views/packages/details/detail.php:80 +msgid "Invalid Backup ID request. Please try again!" +msgstr "" + +#: views/packages/details/detail.php:84 +msgid "[open all]" +msgstr "" + +#: views/packages/details/detail.php:85 +msgid "[close all]" +msgstr "" + +#: views/packages/details/detail.php:106 +msgid "ID" +msgstr "" + +#: views/packages/details/detail.php:110 +msgid "Hash" +msgstr "" + +#: views/packages/details/detail.php:114 +msgid "Full Name" +msgstr "" + +#: views/packages/details/detail.php:122 +#: views/packages/main/s1.setup2.php:93 +#: views/packages/main/s2.scan3.php:730 +msgid "Notes" +msgstr "" + +#: views/packages/details/detail.php:123 +msgid "- no notes -" +msgstr "" + +#: views/packages/details/detail.php:126 +#: views/packages/main/packages.php:192 +msgid "Created" +msgstr "" + +#: views/packages/details/detail.php:139 +#: views/packages/details/detail.php:143 +#: views/packages/details/detail.php:148 +#: views/packages/details/detail.php:149 +#: views/packages/details/detail.php:166 +msgid "- unknown -" +msgstr "" + +#: views/packages/details/detail.php:146 +msgid "Mysql" +msgstr "" + +#: views/packages/details/detail.php:157 +msgid "Runtime" +msgstr "" + +#: views/packages/details/detail.php:158 +msgid "error running" +msgstr "" + +#: views/packages/details/detail.php:161 +msgid "Status" +msgstr "" + +#: views/packages/details/detail.php:162 +msgid "completed" +msgstr "" + +#: views/packages/details/detail.php:162 +msgid "in-complete" +msgstr "" + +#: views/packages/details/detail.php:169 +#: views/packages/details/detail.php:401 +#: views/packages/main/s1.setup2.php:213 +#: views/packages/main/s2.scan3.php:36 +#: views/packages/main/s2.scan3.php:786 +#: views/packages/main/s2.scan3.php:838 +msgid "Files" +msgstr "" + +#: views/packages/details/detail.php:175 +msgid "Download hashed installer ([name]_[hash]_[time]_installer.php)" +msgstr "" + +#: views/packages/details/detail.php:178 +msgid "Download basic installer (installer.php)" +msgstr "" + +#: views/packages/details/detail.php:184 +msgid "Click buttons or links to download." +msgstr "" + +#: views/packages/details/detail.php:190 +#: views/packages/details/detail.php:223 +#: views/packages/details/detail.php:466 +#: views/packages/main/packages.php:289 +#: views/packages/main/s1.setup2.php:371 +#: views/packages/main/s3.build.php:183 +#: views/settings/packages.php:327 +msgid "Installer" +msgstr "" + +#: views/packages/details/detail.php:196 +msgid "Share File Links" +msgstr "" + +#: views/packages/details/detail.php:200 +msgid "Log" +msgstr "" + +#: views/packages/details/detail.php:215 +msgid "Build Log" +msgstr "" + +#: views/packages/details/detail.php:228 +msgid "The installer is also available inside the Backup file." +msgstr "" + +#: views/packages/details/detail.php:242 +msgid "Download Links" +msgstr "" + +#: views/packages/details/detail.php:245 +msgid "The following links contain sensitive data. Share with caution!" +msgstr "" + +#: views/packages/details/detail.php:250 +msgid "Select All" +msgstr "" + +#: views/packages/details/detail.php:256 +msgctxt "%1$s and %2$s are opening and closing tags" +msgid "A copy of the database.sql and installer.php files can both be found inside of the archive.zip/daf file. Download and extract the Backup file to get a copy of the installer which will be named 'installer-backup.php'. For details on how to extract a archive.daf file please see: %1$sHow to work with DAF files and the DupArchive extraction tool?%2$s" +msgstr "" + +#: views/packages/details/detail.php:288 +msgid "Locations" +msgstr "" + +#: views/packages/details/detail.php:298 +#: views/packages/main/s1.setup2.php:136 +msgid "(Legacy Path)" +msgstr "" + +#: views/packages/details/detail.php:300 +#: views/packages/main/s1.setup2.php:138 +msgid "(Contents Path)" +msgstr "" + +#: views/packages/details/detail.php:322 +#: views/packages/main/s1.setup2.php:154 +msgid "Back up this site to %1$s, %2$s, %3$s, %4$s, %5$s and other locations with " +msgstr "" + +#: views/packages/details/detail.php:333 +#: views/packages/main/packages.php:172 +#: views/packages/main/s1.setup2.php:163 +#: views/packages/main/s2.scan3.php:602 +#: views/packages/main/s2.scan3.php:697 +#: views/packages/main/s3.build.php:231 +msgid "Duplicator Pro" +msgstr "" + +#: views/packages/details/detail.php:336 +#: views/packages/main/s1.setup2.php:166 +msgid "Additional Storage:" +msgstr "" + +#: views/packages/details/detail.php:337 +#: views/packages/main/s1.setup2.php:167 +msgid "Duplicator Pro allows you to create a Backup and store it at a custom location on this server or to a remote cloud location such as Google Drive, Amazon, Dropbox and many more." +msgstr "" + +#: views/packages/details/detail.php:362 +msgid "FILES" +msgstr "" + +#: views/packages/details/detail.php:366 +msgid "Build Mode" +msgstr "" + +#: views/packages/details/detail.php:373 +msgid "Database Mode" +msgstr "" + +#: views/packages/details/detail.php:374 +msgid "Backup Database Only Enabled" +msgstr "" + +#: views/packages/details/detail.php:380 +#: views/packages/details/detail.php:444 +msgid "On" +msgstr "" + +#: views/packages/details/detail.php:382 +#: views/packages/main/s2.scan3.php:764 +#: views/packages/main/s2.scan3.php:829 +msgid "Directories" +msgstr "" + +#: views/packages/details/detail.php:386 +#: views/packages/details/detail.php:396 +#: views/packages/details/detail.php:405 +#: views/packages/details/detail.php:453 +msgid "- no filters -" +msgstr "" + +#: views/packages/details/detail.php:392 +#: views/packages/main/s2.scan3.php:775 +msgid "Extensions" +msgstr "" + +#: views/packages/details/detail.php:418 +msgid "DATABASE" +msgstr "" + +#: views/packages/details/detail.php:430 +#: views/packages/main/s1.setup2.php:302 +#: views/settings/packages.php:96 +msgid "SQL Mode" +msgstr "" + +#: views/packages/details/detail.php:436 +#: views/packages/main/s2.scan3.php:746 +msgid "MySQL Compatibility Mode Enabled" +msgstr "" + +#: views/packages/details/detail.php:437 +#: views/packages/main/s1.setup2.php:314 +#: views/packages/main/s2.scan2.php:64 +#: views/packages/main/s2.scan2.php:75 +#: views/packages/main/s2.scan2.php:81 +#: views/packages/main/s2.scan3.php:747 +msgid "details" +msgstr "" + +#: views/packages/details/detail.php:449 +#: views/packages/main/s2.scan3.php:439 +msgid "Tables" +msgstr "" + +#: views/packages/details/detail.php:474 +#: views/packages/main/s1.setup1.php:65 +#: views/packages/main/s1.setup2.php:401 +#: views/packages/main/s2.scan1.php:194 +#: views/packages/main/s2.scan2.php:10 +#: views/packages/main/s3.build.php:111 +msgid "Setup" +msgstr "" + +#: views/packages/details/detail.php:479 +#: views/packages/main/s1.setup2.php:415 +msgid "Security" +msgstr "" + +#: views/packages/details/detail.php:484 +msgid "Password Protection Enabled" +msgstr "" + +#: views/packages/details/detail.php:486 +msgid "Password Protection Disabled" +msgstr "" + +#: views/packages/details/detail.php:497 +#: views/packages/main/s1.setup2.php:431 +msgid "Show/Hide Password" +msgstr "" + +#: views/packages/details/detail.php:510 +#: views/packages/main/s1.setup2.php:457 +msgid " MySQL Server" +msgstr "" + +#: views/packages/details/detail.php:515 +#: views/packages/details/detail.php:519 +#: views/packages/details/detail.php:523 +msgid "- not set -" +msgstr "" + +#: views/packages/details/detail.php:531 +msgid "View Backup Object" +msgstr "" + +#: views/packages/details/detail.php:548 +msgid "Backup File Links" +msgstr "" + +#: views/packages/details/detail.php:553 +msgid "BACKUP" +msgstr "" + +#: views/packages/details/detail.php:554 +msgid "LOG" +msgstr "" + +#: views/packages/main/controller.php:9 +msgid "An invalid request was made to this page." +msgstr "" + +#: views/packages/main/controller.php:10 +msgid "Please retry by going to the" +msgstr "" + +#: views/packages/main/controller.php:11 +msgid "Backups Screen" +msgstr "" + +#: views/packages/main/controller.php:59 +msgid "Backups » All" +msgstr "" + +#: views/packages/main/controller.php:63 +#: views/packages/main/controller.php:67 +#: views/packages/main/controller.php:71 +msgid "Backups » New" +msgstr "" + +#: views/packages/main/packages.php:24 +msgid "When clicking the Installer download button, the 'Save as' dialog is currently defaulting the name to 'installer.php'. To improve the security and get more information, go to: Settings > Backups Tab > Installer > Name option or click on the gear icon at the top of this page." +msgstr "" + +#: views/packages/main/packages.php:27 +msgid "When clicking the Installer download button, the 'Save as' dialog is defaulting the name to '[name]_[hash]_[time]_installer.php'. This is the secure and recommended option. For more information, go to: Settings > Backups Tab > Installer > Name or click on the gear icon at the top of this page.

        To quickly copy the hashed installer name, to your clipboard use the copy icon link or click the installer name and manually copy the selected text." +msgstr "" + +#: views/packages/main/packages.php:95 +msgid "Delete selected backup(s)" +msgstr "" + +#: views/packages/main/packages.php:105 +msgid "Get Help" +msgstr "" + +#: views/packages/main/packages.php:111 +msgid "Backup Settings" +msgstr "" + +#: views/packages/main/packages.php:118 +msgid "Templates" +msgstr "" + +#: views/packages/main/packages.php:130 +msgid "Recovery" +msgstr "" + +#: views/packages/main/packages.php:158 +#: views/packages/main/packages.php:211 +msgid "No Backups Found" +msgstr "" + +#: views/packages/main/packages.php:159 +#: views/packages/main/packages.php:212 +msgid "Click 'Create New' to Backup Site" +msgstr "" + +#: views/packages/main/packages.php:161 +#: views/packages/main/packages.php:214 +msgid "New to Duplicator?" +msgstr "" + +#: views/packages/main/packages.php:163 +#: views/packages/main/packages.php:216 +msgid "Visit the 'Quick Start' guide!" +msgstr "" + +#: views/packages/main/packages.php:169 +msgid "Duplicator Lite does not officially support WordPress multisite." +msgstr "" + +#: views/packages/main/packages.php:171 +#: views/packages/main/s3.build.php:230 +msgid "We strongly recommend upgrading to " +msgstr "" + +#: views/packages/main/packages.php:190 +msgid "Select all Backups" +msgstr "" + +#: views/packages/main/packages.php:193 +#: views/packages/main/s2.scan3.php:97 +#: views/packages/main/s2.scan3.php:438 +msgid "Size" +msgstr "" + +#: views/packages/main/packages.php:196 +msgid "Installer Name" +msgstr "" + +#: views/packages/main/packages.php:198 +#: views/packages/main/s3.build.php:217 +msgid "Installer Name:" +msgstr "" + +#: views/packages/main/packages.php:250 +msgid "Backup created as zip file" +msgstr "" + +#: views/packages/main/packages.php:251 +msgid "Backup created as daf file" +msgstr "" + +#: views/packages/main/packages.php:256 +#: views/packages/main/s1.setup2.php:201 +#: views/packages/main/s2.scan3.php:43 +#: views/packages/main/s2.scan3.php:64 +msgid "Database Only" +msgstr "" + +#: views/packages/main/packages.php:258 +#: views/packages/main/s3.build.php:153 +msgid "Building Backup" +msgstr "" + +#: views/packages/main/packages.php:260 +msgid "Backup Build Running" +msgstr "" + +#: views/packages/main/packages.php:261 +msgid "To stop or reset this Backup build goto Settings > Advanced > Reset Backups" +msgstr "" + +#: views/packages/main/packages.php:278 +msgid "Click to configure installer name." +msgstr "" + +#: views/packages/main/packages.php:297 +msgid "Backup Details" +msgstr "" + +#: views/packages/main/packages.php:314 +msgid "Error Processing" +msgstr "" + +#: views/packages/main/packages.php:330 +msgid "Trace Logging Enabled. Please disable when trace capture is complete." +msgstr "" + +#: views/packages/main/packages.php:335 +msgid "Current Server Time" +msgstr "" + +#: views/packages/main/packages.php:338 +#: views/packages/main/s3.build.php:475 +msgid "Time" +msgstr "" + +#: views/packages/main/packages.php:353 +msgid "Items" +msgstr "" + +#: views/packages/main/packages.php:364 +msgid "Bulk Action Required" +msgstr "" + +#: views/packages/main/packages.php:366 +msgid "No selections made! Please select an action from the \"Bulk Actions\" drop down menu." +msgstr "" + +#: views/packages/main/packages.php:370 +msgid "Selection Required" +msgstr "" + +#: views/packages/main/packages.php:372 +msgid "No selections made! Please select at least one Backup to delete." +msgstr "" + +#: views/packages/main/packages.php:376 +msgid "Delete Backups?" +msgstr "" + +#: views/packages/main/packages.php:377 +msgid "Are you sure you want to delete the selected Backup(s)?" +msgstr "" + +#: views/packages/main/packages.php:378 +msgid "Removing Backups, Please Wait..." +msgstr "" + +#: views/packages/main/packages.php:385 +msgid "Duplicator Help" +msgstr "" + +#: views/packages/main/packages.php:390 +msgid "Alert!" +msgstr "" + +#: views/packages/main/packages.php:391 +msgid "A Backup is being processed. Retry later." +msgstr "" + +#: views/packages/main/packages.php:398 +msgid "Common Questions:" +msgstr "" + +#: views/packages/main/packages.php:401 +msgid "How do I create a Backup" +msgstr "" + +#: views/packages/main/packages.php:405 +msgid "How do I install a Backup?" +msgstr "" + +#: views/packages/main/packages.php:409 +msgid "Frequently Asked Questions!" +msgstr "" + +#: views/packages/main/packages.php:413 +msgid "Other Resources:" +msgstr "" + +#: views/packages/main/packages.php:415 +msgid "Need help with the plugin?" +msgstr "" + +#: views/packages/main/packages.php:419 +#: views/packages/main/s3.build.php:291 +msgid "Help review the plugin!" +msgstr "" + +#: views/packages/main/s1.setup1.php:15 +msgid "Backup settings have been reset." +msgstr "" + +#: views/packages/main/s1.setup1.php:66 +#: views/packages/main/s2.scan1.php:195 +#: views/packages/main/s3.build.php:112 +msgid "Scan" +msgstr "" + +#: views/packages/main/s1.setup1.php:67 +#: views/packages/main/s2.scan1.php:196 +#: views/packages/main/s2.scan1.php:280 +#: views/packages/main/s3.build.php:113 +msgid "Build" +msgstr "" + +#: views/packages/main/s1.setup1.php:72 +msgid "Step 1: Choose the WordPress contents to backup." +msgstr "" + +#: views/packages/main/s1.setup1.php:91 +msgid "Requirements:" +msgstr "" + +#: views/packages/main/s1.setup1.php:100 +msgid "System requirements must pass for the Duplicator to work properly. Click each link for details." +msgstr "" + +#: views/packages/main/s1.setup1.php:106 +msgid "PHP Support" +msgstr "" + +#: views/packages/main/s1.setup1.php:114 +msgid "PHP versions 5.2.9+ or higher is required." +msgstr "" + +#: views/packages/main/s1.setup1.php:118 +msgid "Zip Archive Enabled" +msgstr "" + +#: views/packages/main/s1.setup1.php:122 +msgctxt "1 and 2 are
        tags" +msgid "ZipArchive extension is required or %1$sSwitch to DupArchive%2$s to by-pass this requirement." +msgstr "" + +#: views/packages/main/s1.setup1.php:135 +msgid "Safe Mode Off" +msgstr "" + +#: views/packages/main/s1.setup1.php:137 +msgid "Safe Mode should be set to Off in you php.ini file and is deprecated as of PHP 5.3.0." +msgstr "" + +#: views/packages/main/s1.setup1.php:140 +#: views/packages/main/s1.setup1.php:145 +#: views/packages/main/s1.setup1.php:150 +msgid "Function" +msgstr "" + +#: views/packages/main/s1.setup1.php:156 +msgid "For any issues in this section please contact your hosting provider or server administrator. For additional information see our online documentation." +msgstr "" + +#: views/packages/main/s1.setup1.php:164 +msgid "Required Paths" +msgstr "" + +#: views/packages/main/s1.setup1.php:186 +msgid "If the root WordPress path is not writable by PHP on some systems this can cause issues." +msgstr "" + +#: views/packages/main/s1.setup1.php:189 +msgid "If Duplicator does not have enough permissions then you will need to manually create the paths above.   " +msgstr "" + +#: views/packages/main/s1.setup1.php:198 +msgid "Server Support" +msgstr "" + +#: views/packages/main/s1.setup1.php:204 +msgid "MySQL Version" +msgstr "" + +#: views/packages/main/s1.setup1.php:208 +msgid "MySQLi Support" +msgstr "" + +#: views/packages/main/s1.setup1.php:214 +msgid "MySQL version 5.0+ or better is required and the PHP MySQLi extension (note the trailing 'i') is also required. Contact your server administrator and request that mysqli extension and MySQL Server 5.0+ be installed." +msgstr "" + +#: views/packages/main/s1.setup1.php:219 +msgid "more info" +msgstr "" + +#: views/packages/main/s1.setup1.php:230 +msgid "The function mysqli_real_escape_string is not working properly. Please consult host support and ask them to switch to a different PHP version or configuration." +msgstr "" + +#: views/packages/main/s1.setup1.php:239 +msgid "Reserved Files" +msgstr "" + +#: views/packages/main/s1.setup1.php:244 +msgid "None of the reserved files where found from a previous install. This means you are clear to create a new Backup." +msgstr "" + +#: views/packages/main/s1.setup1.php:252 +msgid "WordPress Root Path:" +msgstr "" + +#: views/packages/main/s1.setup1.php:257 +msgid "Remove Files Now" +msgstr "" + +#: views/packages/main/s1.setup2.php:87 +msgid "Add Notes" +msgstr "" + +#: views/packages/main/s1.setup2.php:90 +msgid "Toggle a default name" +msgstr "" + +#: views/packages/main/s1.setup2.php:110 +msgid "This is the storage location on this server where the Backup and installer files will be saved." +msgstr "" + +#: views/packages/main/s1.setup2.php:113 +msgid "[Storage Options]" +msgstr "" + +#: views/packages/main/s1.setup2.php:123 +msgid "Location" +msgstr "" + +#: views/packages/main/s1.setup2.php:192 +msgid "File filter enabled" +msgstr "" + +#: views/packages/main/s1.setup2.php:196 +msgid "Database filter enabled" +msgstr "" + +#: views/packages/main/s1.setup2.php:200 +msgid "Backup Only the Database" +msgstr "" + +#: views/packages/main/s1.setup2.php:215 +msgid "File Backup Encryption" +msgstr "" + +#: views/packages/main/s1.setup2.php:233 +msgid "Enable Table Filters" +msgstr "" + +#: views/packages/main/s1.setup2.php:235 +msgid "Enable Table Filters:" +msgstr "" + +#: views/packages/main/s1.setup2.php:236 +msgid "Checked tables will not be added to the database script. Excluding certain tables can possibly cause your site or plugins to not work correctly after install!" +msgstr "" + +#: views/packages/main/s1.setup2.php:243 +msgid "Include All" +msgstr "" + +#: views/packages/main/s1.setup2.php:244 +msgid "Exclude All" +msgstr "" + +#: views/packages/main/s1.setup2.php:289 +msgid "Checked tables will be excluded from the database script. " +msgstr "" + +#: views/packages/main/s1.setup2.php:290 +msgid "Excluding certain tables can cause your site or plugins to not work correctly after install!
        " +msgstr "" + +#: views/packages/main/s1.setup2.php:291 +msgid " Use caution when excluding tables! It is highly recommended to not exclude WordPress core tables*, unless you know the impact." +msgstr "" + +#: views/packages/main/s1.setup2.php:297 +msgid "Configuration" +msgstr "" + +#: views/packages/main/s1.setup2.php:306 +msgid "Compatibility Mode" +msgstr "" + +#: views/packages/main/s1.setup2.php:308 +msgid "Compatibility Mode:" +msgstr "" + +#: views/packages/main/s1.setup2.php:309 +msgid "This is an advanced database backwards compatibility feature that should ONLY be used if having problems installing Backups. If the database server version is lower than the version where the Backup was built then these options may help generate a script that is more compliant with the older database server. It is recommended to try each option separately starting with mysql40." +msgstr "" + +#: views/packages/main/s1.setup2.php:329 +msgid "mysql40" +msgstr "" + +#: views/packages/main/s1.setup2.php:333 +msgid "no_table_options" +msgstr "" + +#: views/packages/main/s1.setup2.php:337 +msgid "no_key_options" +msgstr "" + +#: views/packages/main/s1.setup2.php:341 +msgid "no_field_options" +msgstr "" + +#: views/packages/main/s1.setup2.php:346 +msgid "This option is only available with mysqldump mode." +msgstr "" + +#: views/packages/main/s1.setup2.php:374 +msgid "Installer password protection is on" +msgstr "" + +#: views/packages/main/s1.setup2.php:377 +msgid "Installer password protection is off" +msgstr "" + +#: views/packages/main/s1.setup2.php:388 +msgid "The installer file is used to redeploy/install the Backup contents." +msgstr "" + +#: views/packages/main/s1.setup2.php:390 +msgid "All values in this section are" +msgstr "" + +#: views/packages/main/s1.setup2.php:390 +msgid "optional" +msgstr "" + +#: views/packages/main/s1.setup2.php:392 +msgid "Setup/Prefills" +msgstr "" + +#: views/packages/main/s1.setup2.php:393 +msgid "All values in this section are OPTIONAL! If you know ahead of time the database input fields the installer will use, then you can optionally enter them here and they will be prefilled at install time. Otherwise you can just enter them in at install time and ignore all these options in the Installer section." +msgstr "" + +#: views/packages/main/s1.setup2.php:404 +#: views/packages/main/s1.setup2.php:409 +msgid "Branding" +msgstr "" + +#: views/packages/main/s1.setup2.php:407 +msgid "Available with Duplicator Pro!" +msgstr "" + +#: views/packages/main/s1.setup2.php:410 +msgid "Branding is a way to customize the installer look and feel. With branding you can create multiple brands of installers." +msgstr "" + +#: views/packages/main/s1.setup2.php:422 +msgid "Enable Password Protection" +msgstr "" + +#: views/packages/main/s1.setup2.php:424 +msgid "Security:" +msgstr "" + +#: views/packages/main/s1.setup2.php:425 +msgid "Enabling this option will allow for basic password protection on the installer. Before running the installer the password below must be entered before proceeding with an install. This password is a general deterrent and should not be substituted for properly keeping your files secure. Be sure to remove all installer files when the install process is completed." +msgstr "" + +#: views/packages/main/s1.setup2.php:440 +msgid "Prefills" +msgstr "" + +#: views/packages/main/s1.setup2.php:448 +#: views/settings/packages.php:339 +msgid "Basic" +msgstr "" + +#: views/packages/main/s1.setup2.php:449 +msgid "cPanel" +msgstr "" + +#: views/packages/main/s1.setup2.php:468 +msgid "example: localhost (value is optional)" +msgstr "" + +#: views/packages/main/s1.setup2.php:473 +msgid "Host Port" +msgstr "" + +#: views/packages/main/s1.setup2.php:481 +msgid "example: 3306 (value is optional)" +msgstr "" + +#: views/packages/main/s1.setup2.php:494 +msgid "example: DatabaseName (value is optional)" +msgstr "" + +#: views/packages/main/s1.setup2.php:507 +msgid "example: DatabaseUserName (value is optional)" +msgstr "" + +#: views/packages/main/s1.setup2.php:520 +msgid "example: utf8 (value is optional)" +msgstr "" + +#: views/packages/main/s1.setup2.php:525 +msgid "Collation" +msgstr "" + +#: views/packages/main/s1.setup2.php:533 +msgid "example: utf8_general_ci (value is optional)" +msgstr "" + +#: views/packages/main/s1.setup2.php:545 +msgid "Create the database and database user at install time without leaving the installer!" +msgstr "" + +#: views/packages/main/s1.setup2.php:546 +msgid "This feature is only availble in " +msgstr "" + +#: views/packages/main/s1.setup2.php:548 +msgid "Duplicator Pro!" +msgstr "" + +#: views/packages/main/s1.setup2.php:550 +msgid "This feature works only with hosts that support cPanel." +msgstr "" + +#: views/packages/main/s1.setup2.php:562 +msgid "Reset" +msgstr "" + +#: views/packages/main/s1.setup2.php:572 +msgid "Reset Backup Settings?" +msgstr "" + +#: views/packages/main/s1.setup2.php:573 +msgid "This will clear and reset all of the current Backup settings. Would you like to continue?" +msgstr "" + +#: views/packages/main/s2.scan1.php:167 +msgid "Input fields not valid" +msgstr "" + +#: views/packages/main/s2.scan1.php:168 +#: views/packages/main/s2.scan1.php:229 +msgid "Please try again!" +msgstr "" + +#: views/packages/main/s2.scan1.php:170 +#: views/packages/main/s2.scan1.php:234 +#: views/packages/main/s3.build.php:519 +msgid "Error Message:" +msgstr "" + +#: views/packages/main/s2.scan1.php:180 +#: views/packages/main/s2.scan1.php:278 +msgid "Back" +msgstr "" + +#: views/packages/main/s2.scan1.php:200 +msgid "Step 2: Scan site for configuration & system notices." +msgstr "" + +#: views/packages/main/s2.scan1.php:216 +msgid "Scanning Site" +msgstr "" + +#: views/packages/main/s2.scan1.php:218 +#: views/packages/main/s3.build.php:155 +msgid "Please Wait..." +msgstr "" + +#: views/packages/main/s2.scan1.php:219 +msgid "Keep this window open during the scan process." +msgstr "" + +#: views/packages/main/s2.scan1.php:220 +msgid "This can take several minutes." +msgstr "" + +#: views/packages/main/s2.scan1.php:228 +msgid "Scan Error" +msgstr "" + +#: views/packages/main/s2.scan1.php:231 +#: views/packages/main/s3.build.php:502 +msgid "Server Status:" +msgstr "" + +#: views/packages/main/s2.scan1.php:243 +msgid "Scan Complete" +msgstr "" + +#: views/packages/main/s2.scan1.php:245 +msgid "Scan Time:" +msgstr "" + +#: views/packages/main/s2.scan1.php:261 +msgid "Scan checks are not required to pass, however they could cause issues on some systems." +msgstr "" + +#: views/packages/main/s2.scan1.php:263 +msgid "Please review the details for each section by clicking on the detail title." +msgstr "" + +#: views/packages/main/s2.scan1.php:269 +msgid "Do you want to continue?" +msgstr "" + +#: views/packages/main/s2.scan1.php:271 +msgid "At least one or more checkboxes were checked in \"Quick Filters\"." +msgstr "" + +#: views/packages/main/s2.scan1.php:272 +msgid "To apply a \"Quick Filter\" click the \"Add Filters & Rescan\" button" +msgstr "" + +#: views/packages/main/s2.scan1.php:274 +msgid "Yes. Continue without applying any file filters." +msgstr "" + +#: views/packages/main/s2.scan1.php:279 +msgid "Rescan" +msgstr "" + +#: views/packages/main/s2.scan1.php:423 +msgid "Unable to perform a full scan, please try the following actions:" +msgstr "" + +#: views/packages/main/s2.scan1.php:424 +msgid "1. Go back and create a root path directory filter to validate the site is scan-able." +msgstr "" + +#: views/packages/main/s2.scan1.php:425 +msgid "2. Continue to add/remove filters to isolate which path is causing issues." +msgstr "" + +#: views/packages/main/s2.scan1.php:426 +msgid "3. This message will go away once the correct filters are applied." +msgstr "" + +#: views/packages/main/s2.scan1.php:428 +msgid "Common Issues:" +msgstr "" + +#: views/packages/main/s2.scan1.php:429 +msgid "- On some budget hosts scanning over 30k files can lead to timeout/gateway issues. Consider scanning only your main WordPress site and avoid trying to backup other external directories." +msgstr "" + +#: views/packages/main/s2.scan1.php:434 +msgid "- Symbolic link recursion can cause timeouts. Ask your server admin if any are present in the scan path. If they are add the full path as a filter and try running the scan again." +msgstr "" + +#: views/packages/main/s2.scan1.php:452 +#: views/packages/main/s2.scan3.php:65 +#: views/packages/main/s2.scan3.php:77 +#: views/packages/main/s2.scan3.php:621 +#: views/packages/main/s3.build.php:386 +msgid "Notice" +msgstr "" + +#: views/packages/main/s2.scan1.php:454 +#: views/packages/main/s2.scan3.php:619 +msgid "Good" +msgstr "" + +#: views/packages/main/s2.scan1.php:455 +msgid "Fail" +msgstr "" + +#: views/packages/main/s2.scan2.php:12 +msgid "Show Diagnostics" +msgstr "" + +#: views/packages/main/s2.scan2.php:13 +msgid "Check Site Health" +msgstr "" + +#: views/packages/main/s2.scan2.php:44 +msgid "System" +msgstr "" + +#: views/packages/main/s2.scan2.php:52 +msgid "Supported web servers: " +msgstr "" + +#: views/packages/main/s2.scan2.php:57 +msgid "The minimum PHP version supported by Duplicator is 5.2.9. It is highly recommended to use PHP 5.3+ for improved stability. For international language support please use PHP 7.0+." +msgstr "" + +#: views/packages/main/s2.scan2.php:62 +msgid "PHP Open Base Dir" +msgstr "" + +#: views/packages/main/s2.scan2.php:63 +msgid "Issues might occur when [open_basedir] is enabled. Work with your server admin to disable this value in the php.ini file if you’re having issues building a Backup." +msgstr "" + +#: views/packages/main/s2.scan2.php:68 +#: views/packages/main/s3.build.php:482 +msgid "PHP Max Execution Time" +msgstr "" + +#: views/packages/main/s2.scan2.php:69 +msgid "Timeouts may occur for larger Backups when [max_execution_time] time in the php.ini is too low. A value of 0 (recommended) indicates that PHP has no time limits. An attempt is made to override this value if the server allows it." +msgstr "" + +#: views/packages/main/s2.scan2.php:72 +msgid "Note: Timeouts can also be set at the web server layer, so if the PHP max timeout passes and you still see a build timeout messages, then your web server could be killing the process. If you are on a budget host and limited on processing time, consider using the database or file filters to shrink the size of your overall Backup. However use caution as excluding the wrong resources can cause your install to not work properly." +msgstr "" + +#: views/packages/main/s2.scan2.php:79 +msgid "Get faster builds with Duplicator Pro with access to shell_exec zip." +msgstr "" + +#: views/packages/main/s2.scan2.php:86 +msgid "Managed Host" +msgstr "" + +#: views/packages/main/s2.scan2.php:87 +msgid "A managed host is a WordPress host that tightly controls the server environment so that the software running on it can be closely ‘managed’ by the hosting company. Managed hosts typically have constraints imposed to facilitate this management, including the locking down of certain files and directories as well as non-standard configurations." +msgstr "" + +#: views/packages/main/s2.scan2.php:90 +msgid "Duplicator Lite allows users to build a Backup on managed hosts, however, the installer may not properly install Backups created on managed hosts due to the non-standard configurations of managed hosts. It is also possible the Backup engine of Duplicator Lite won’t be able to capture all of the necessary data of a site running on a managed host." +msgstr "" + +#: views/packages/main/s2.scan2.php:95 +msgctxt "1 and 2 are
        tags" +msgid "" +"It's possible one could get the Backup to install but it may require custom manual effort. \n" +" To get support and the advanced installer processing required for managed host support we encourage users to %1$supgrade to Duplicator Pro%2$s.\n" +" Pro has more sophisticated Backup and installer logic and accounts for odd configurations associated with managed hosts." +msgstr "" + +#: views/packages/main/s2.scan2.php:123 +msgid "It is recommended to have a version of WordPress that is greater than %1$s. Older version of WordPress can lead to migration issues and are a security risk. If possible please update your WordPress site to the latest version." +msgstr "" + +#: views/packages/main/s2.scan2.php:127 +msgid "Core Files" +msgstr "" + +#: views/packages/main/s2.scan2.php:133 +msgid "The core WordPress paths below will NOT be included in the Backup. These paths are required for WordPress to function!" +msgstr "" + +#: views/packages/main/s2.scan2.php:144 +msgid "The core WordPress file below will NOT be included in the Backup. This file is required for WordPress to function!" +msgstr "" + +#: views/packages/main/s2.scan2.php:156 +msgid "" +"Note: Please change the %1$s filters if you wish to include the WordPress core files \n" +" otherwise the data will have to be manually copied to the new location for the site to function properly." +msgstr "" + +#: views/packages/main/s2.scan2.php:168 +msgid "If the scanner is unable to locate the wp-config.php file in the root directory, then you will need to manually copy it to its new location. This check will also look for core WordPress paths that should be included in the Backup for WordPress to work correctly." +msgstr "" + +#: views/packages/main/s2.scan2.php:187 +msgid "Multisite: Unsupported" +msgstr "" + +#: views/packages/main/s2.scan2.php:188 +msgid "Duplicator does not support WordPress multisite migrations. We strongly recommend using Duplicator Pro which currently supports full multisite migrations and various other subsite scenarios." +msgstr "" + +#: views/packages/main/s2.scan2.php:192 +msgid "While it is not recommended you can still continue with the build of this Backup. At install time additional manual custom configurations will need to be made to finalize this multisite migration. Please note that any support requests for mulitsite with Duplicator Lite will not be supported." +msgstr "" + +#: views/packages/main/s2.scan2.php:194 +#: views/packages/main/s2.scan2.php:199 +msgid "upgrade to pro" +msgstr "" + +#: views/packages/main/s2.scan2.php:196 +msgid "Multisite: N/A" +msgstr "" + +#: views/packages/main/s2.scan2.php:197 +msgid "This is not a multisite install so duplication will proceed without issue. Duplicator does not officially support multisite. However, Duplicator Pro supports duplication of a full multisite network and also has the ability to install a multisite subsite as a standalone site." +msgstr "" + +#: views/packages/main/s2.scan2.php:209 +msgid "Migration Status" +msgstr "" + +#: views/packages/main/s2.scan2.php:217 +msgid "The Backup created here can be migrated to a new server." +msgstr "" + +#: views/packages/main/s2.scan2.php:221 +msgid "" +"The Backup created here cannot be migrated to a new server.\n" +" The Backup created here can be restored on the same server." +msgstr "" + +#: views/packages/main/s2.scan3.php:11 +msgid "Root Path" +msgstr "" + +#: views/packages/main/s2.scan3.php:31 +msgid "Show Scan Details" +msgstr "" + +#: views/packages/main/s2.scan3.php:52 +msgid "Backup Size" +msgstr "" + +#: views/packages/main/s2.scan3.php:53 +msgid "This size includes only files BEFORE compression is applied. It does not include the size of the database script or any applied filters. Once complete the Backup size will be smaller than this number." +msgstr "" + +#: views/packages/main/s2.scan3.php:56 +#: views/packages/main/s2.scan3.php:426 +#: views/packages/main/s2.scan3.php:549 +msgid "uncompressed" +msgstr "" + +#: views/packages/main/s2.scan3.php:68 +msgid "Only the database and a copy of the installer will be included in the Backup file. This notice simply indicates that the Backup will not be capable of restoring a full WordPress site, but only the database. If this is the desired intention then this notice can be ignored." +msgstr "" + +#: views/packages/main/s2.scan3.php:76 +msgid "Skip Backup scan enabled" +msgstr "" + +#: views/packages/main/s2.scan3.php:80 +msgid "All file checks are skipped. This could cause problems during extraction if problematic files are included." +msgstr "" + +#: views/packages/main/s2.scan3.php:82 +msgid " Disable the advanced option to re-enable file controls." +msgstr "" + +#: views/packages/main/s2.scan3.php:93 +msgid "Size Checks" +msgstr "" + +#: views/packages/main/s2.scan3.php:98 +msgid "File Count" +msgstr "" + +#: views/packages/main/s2.scan3.php:99 +msgid "Directory Count" +msgstr "" + +#: views/packages/main/s2.scan3.php:101 +msgid "Compressing larger sites on some budget hosts may cause timeouts. " +msgstr "" + +#: views/packages/main/s2.scan3.php:102 +msgid "more details..." +msgstr "" + +#: views/packages/main/s2.scan3.php:107 +msgctxt "%s size in bytes" +msgid "This notice is triggered at [%s] and can be ignored on most hosts. If during the build process you see a \"Host Build Interrupt\" message then this host has strict processing limits. Below are some options you can take to overcome constraints set up on this host." +msgstr "" + +#: views/packages/main/s2.scan3.php:118 +msgid "Timeout Options" +msgstr "" + +#: views/packages/main/s2.scan3.php:121 +msgid "Apply the \"Quick Filters\" below or click the back button to apply on previous page." +msgstr "" + +#: views/packages/main/s2.scan3.php:125 +msgctxt "%1$s and %2$s are tags" +msgid "See the FAQ link to adjust this hosts timeout limits: %1$sWhat can I try for Timeout Issues?%2$s" +msgstr "" + +#: views/packages/main/s2.scan3.php:138 +msgctxt "%1$s and %2$s are tags" +msgid "Consider trying multi-threaded support in %1$sDuplicator Pro%2$s." +msgstr "" + +#: views/packages/main/s2.scan3.php:151 +msgid "Files over %1$s are listed below. Larger files such as movies or zipped content can cause timeout issues on some budget hosts. If you are having issues creating a Backup try excluding the directory paths below or go back to Step 1 and add them." +msgstr "" + +#: views/packages/main/s2.scan3.php:159 +#: views/packages/main/s2.scan3.php:251 +#: views/packages/main/s2.scan3.php:300 +msgid "Quick Filters" +msgstr "" + +#: views/packages/main/s2.scan3.php:160 +msgid "Large Files" +msgstr "" + +#: views/packages/main/s2.scan3.php:163 +#: views/packages/main/s2.scan3.php:303 +msgid "Hide All" +msgstr "" + +#: views/packages/main/s2.scan3.php:164 +#: views/packages/main/s2.scan3.php:304 +msgid "Show All" +msgstr "" + +#: views/packages/main/s2.scan3.php:174 +#: views/packages/main/s2.scan3.php:319 +msgid "Core WordPress directories should not be filtered. Use caution when excluding files." +msgstr "" + +#: views/packages/main/s2.scan3.php:194 +msgid "No large files found during this scan." +msgstr "" + +#: views/packages/main/s2.scan3.php:197 +msgid "No large files found during this scan. If you're having issues building a Backup click the back button and try adding a file filter to non-essential files paths like wp-content/uploads. These excluded files can then be manually moved to the new location after you have ran the migration installer." +msgstr "" + +#: views/packages/main/s2.scan3.php:210 +#: views/packages/main/s2.scan3.php:345 +msgid "*Checking a directory will exclude all items recursively from that path down. Please use caution when filtering directories." +msgstr "" + +#: views/packages/main/s2.scan3.php:213 +#: views/packages/main/s2.scan3.php:274 +#: views/packages/main/s2.scan3.php:348 +msgid "Add Filters & Rescan" +msgstr "" + +#: views/packages/main/s2.scan3.php:215 +#: views/packages/main/s2.scan3.php:350 +msgid "Copy Paths to Clipboard" +msgstr "" + +#: views/packages/main/s2.scan3.php:231 +msgid "Addon Sites" +msgstr "" + +#: views/packages/main/s2.scan3.php:238 +msgid "" +"An \"Addon Site\" is a separate WordPress site(s) residing in subdirectories within this site. If you confirm these to be separate sites, \n" +" then it is recommended that you exclude them by checking the corresponding boxes below and clicking the 'Add Filters & Rescan' button. To backup the other sites \n" +" install the plugin on the sites needing to be backed-up." +msgstr "" + +#: views/packages/main/s2.scan3.php:265 +msgid "No add on sites found." +msgstr "" + +#: views/packages/main/s2.scan3.php:271 +msgid "*Checking a directory will exclude all items in that path recursively." +msgstr "" + +#: views/packages/main/s2.scan3.php:287 +#: views/packages/main/s2.scan3.php:301 +msgid "Name Checks" +msgstr "" + +#: views/packages/main/s2.scan3.php:292 +msgid "Unicode and special characters such as \"*?><:/\\|\", can be problematic on some hosts." +msgstr "" + +#: views/packages/main/s2.scan3.php:293 +msgid " Only consider using this filter if the Backup build is failing. Select files that are not important to your site or you can migrate manually." +msgstr "" + +#: views/packages/main/s2.scan3.php:294 +msgid "If this environment/system and the system where it will be installed are set up to support Unicode and long paths then these filters can be ignored. If you run into issues with creating or installing a Backup, then is recommended to filter these paths." +msgstr "" + +#: views/packages/main/s2.scan3.php:339 +msgid "No file/directory name warnings found." +msgstr "" + +#: views/packages/main/s2.scan3.php:362 +msgid "Read Checks" +msgstr "" + +#: views/packages/main/s2.scan3.php:367 +msgid "PHP is unable to read the following items and they will NOT be included in the Backup. Please work with your host to adjust the permissions or resolve the symbolic-link(s) shown in the lists below. If these items are not needed then this notice can be ignored." +msgstr "" + +#: views/packages/main/s2.scan3.php:373 +msgid "Unreadable Items:" +msgstr "" + +#: views/packages/main/s2.scan3.php:380 +msgid "No unreadable items found." +msgstr "" + +#: views/packages/main/s2.scan3.php:384 +msgid "Recursive Links:" +msgstr "" + +#: views/packages/main/s2.scan3.php:391 +msgid "No recursive sym-links found." +msgstr "" + +#: views/packages/main/s2.scan3.php:422 +msgid "Database Size:" +msgstr "" + +#: views/packages/main/s2.scan3.php:423 +msgid "The database size represents only the included tables. The process for gathering the size uses the query SHOW TABLE STATUS. The overall size of the database file can impact the final size of the Backup." +msgstr "" + +#: views/packages/main/s2.scan3.php:433 +#: views/packages/main/s3.build.php:333 +msgid "Overview" +msgstr "" + +#: views/packages/main/s2.scan3.php:437 +msgid "TOTAL SIZE" +msgstr "" + +#: views/packages/main/s2.scan3.php:440 +msgid "Records" +msgstr "" + +#: views/packages/main/s2.scan3.php:443 +msgid "Total size and row counts are approximate values. The thresholds that trigger notices are %1$s records total for the entire database. Larger databases take more time to process. On some budget hosts that have cpu/memory/timeout limits this may cause issues." +msgstr "" + +#: views/packages/main/s2.scan3.php:448 +msgid "TABLE DETAILS:" +msgstr "" + +#: views/packages/main/s2.scan3.php:450 +msgid "The notices for tables are %1$s records or names with upper-case characters. Individual tables will not trigger a notice message, but can help narrow down issues if they occur later on." +msgstr "" + +#: views/packages/main/s2.scan3.php:457 +#: views/packages/main/s2.scan3.php:570 +#: views/packages/main/s2.scan3.php:658 +msgid "RECOMMENDATIONS:" +msgstr "" + +#: views/packages/main/s2.scan3.php:460 +msgid "repair and optimization" +msgstr "" + +#: views/packages/main/s2.scan3.php:461 +msgid "1. Run a %1$s on the table to improve the overall size and performance." +msgstr "" + +#: views/packages/main/s2.scan3.php:463 +msgid "2. Remove post revisions and stale data from tables. Tables such as logs, statistical or other non-critical data should be cleared." +msgstr "" + +#: views/packages/main/s2.scan3.php:465 +msgid "Enable mysqldump" +msgstr "" + +#: views/packages/main/s2.scan3.php:466 +msgid "3. %1$s if this host supports the option." +msgstr "" + +#: views/packages/main/s2.scan3.php:468 +msgid "lower_case_table_names" +msgstr "" + +#: views/packages/main/s2.scan3.php:469 +msgid "4. For table name case sensitivity issues either rename the table with lower case characters or be prepared to work with the %1$s system variable setting." +msgstr "" + +#: views/packages/main/s2.scan3.php:480 +msgid "Triggers" +msgstr "" + +#: views/packages/main/s2.scan3.php:489 +msgid "triggers" +msgstr "" + +#: views/packages/main/s2.scan3.php:490 +msgid "This database makes use of %1$s which can manually be imported at install time. Instructions and SQL statement queries will be provided at install time for users to execute. No actions need to be performed at this time, this message is simply a notice." +msgstr "" + +#: views/packages/main/s2.scan3.php:509 +msgid "Object Access" +msgstr "" + +#: views/packages/main/s2.scan3.php:517 +msgid "The database user for this WordPress site has sufficient permissions to write stored procedures and functions to the sql file of the archive. [The command SHOW CREATE FUNCTION will work.]" +msgstr "" + +#: views/packages/main/s2.scan3.php:521 +msgid "The database user for this WordPress site does NOT sufficient permissions to write stored procedures or functions to the sql file of the archive. Stored procedures will not be added to the sql file." +msgstr "" + +#: views/packages/main/s2.scan3.php:541 +msgid "Total Size" +msgstr "" + +#: views/packages/main/s2.scan3.php:546 +msgid "Total Size:" +msgstr "" + +#: views/packages/main/s2.scan3.php:547 +msgid "The total size of the site (files plus database)." +msgstr "" + +#: views/packages/main/s2.scan3.php:557 +msgid "The build can't continue because the total size of files and the database exceeds the %s limit that can be processed when creating a DupArchive Backup. " +msgstr "" + +#: views/packages/main/s2.scan3.php:559 +msgid "Click for recommendations." +msgstr "" + +#: views/packages/main/s2.scan3.php:564 +#: views/settings/packages.php:255 +msgid "Backup Engine" +msgstr "" + +#: views/packages/main/s2.scan3.php:565 +msgid "The %s is set to create Backups in the 'DupArchive' format. This custom format is used to overcome budget host constraints. With DupArchive, Duplicator is restricted to processing sites up to %s. To process larger sites, consider these recommendations. " +msgstr "" + +#: views/packages/main/s2.scan3.php:578 +msgid "Step 1" +msgstr "" + +#: views/packages/main/s2.scan3.php:579 +msgid "- Add data filters to get the Backup size under %s: " +msgstr "" + +#: views/packages/main/s2.scan3.php:581 +msgid "- In the 'Size Checks' section above consider adding filters (if notice is shown)." +msgstr "" + +#: views/packages/main/s2.scan3.php:583 +msgid "- In %s consider adding file/directory or database table filters." +msgstr "" + +#: views/packages/main/s2.scan3.php:588 +msgctxt "%1$s and %2$s represent opening and closing anchor tags" +msgid "- Perform a two part install as %1$sdescribed in the documentation%2$s." +msgstr "" + +#: views/packages/main/s2.scan3.php:598 +msgid "ZipArchive Engine" +msgstr "" + +#: views/packages/main/s2.scan3.php:599 +msgid "- Switch to the %s which requires a capable hosting provider (VPS recommended)." +msgstr "" + +#: views/packages/main/s2.scan3.php:603 +msgid "- Consider upgrading to %s for unlimited large site support." +msgstr "" + +#: views/packages/main/s2.scan3.php:615 +msgid "Mysqldump memory check" +msgstr "" + +#: views/packages/main/s2.scan3.php:628 +msgid "The database size is within the allowed mysqldump size limit." +msgstr "" + +#: views/packages/main/s2.scan3.php:632 +msgctxt "1$s and 2$s represent opening and closing anchor tags" +msgid "If you encounter any issues with mysqldump please change the setting SQL Mode to PHP Code. You can do that by opening %1$sDuplicator Pro > Settings > Backups.%2$s" +msgstr "" + +#: views/packages/main/s2.scan3.php:646 +msgid "The database size exceeds the allowed mysqldump size limit." +msgstr "" + +#: views/packages/main/s2.scan3.php:649 +msgid "The database size is larger than the PHP memory_limit value. This can lead into issues when building a Backup, during which the system can run out of memory. To fix this issue please consider doing one of the below mentioned recommendations." +msgstr "" + +#: views/packages/main/s2.scan3.php:664 +msgctxt "%1$s and %2$s represent opening and closing anchor tags" +msgid "Please change the setting SQL Mode to PHP Code. You can do that by opening %1$sDuplicator Pro > Settings > Backups.%2$s" +msgstr "" + +#: views/packages/main/s2.scan3.php:678 +msgctxt "%1$s represents the memory limit value (e.g. 256MB)" +msgid "If you want to build the Backup with mysqldump, increase the PHP memory_limit value in your php.ini file to at least %1$s." +msgstr "" + +#: views/packages/main/s2.scan3.php:696 +msgid "Migrate large, multi-gig sites with" +msgstr "" + +#: views/packages/main/s2.scan3.php:711 +msgid "Scan Details" +msgstr "" + +#: views/packages/main/s2.scan3.php:718 +msgid "Copy Quick Filter Paths" +msgstr "" + +#: views/packages/main/s2.scan3.php:731 +msgid "Archive Engine" +msgstr "" + +#: views/packages/main/s2.scan3.php:737 +msgid "Name:" +msgstr "" + +#: views/packages/main/s2.scan3.php:738 +msgid "Host:" +msgstr "" + +#: views/packages/main/s2.scan3.php:740 +msgid "Build Mode:" +msgstr "" + +#: views/packages/main/s2.scan3.php:756 +msgid "File Filters" +msgstr "" + +#: views/packages/main/s2.scan3.php:771 +msgid "No custom directory filters set." +msgstr "" + +#: views/packages/main/s2.scan3.php:781 +msgid "No file extension filters have been set." +msgstr "" + +#: views/packages/main/s2.scan3.php:793 +msgid "No custom file filters set." +msgstr "" + +#: views/packages/main/s2.scan3.php:797 +msgid "Auto Directory Filters" +msgstr "" + +#: views/packages/main/s2.scan3.php:803 +msgid "Auto File Filters" +msgstr "" + +#: views/packages/main/s2.scan3.php:816 +msgid "Path filters will be skipped during the archive process when enabled." +msgstr "" + +#: views/packages/main/s2.scan3.php:818 +msgid "[view json result report]" +msgstr "" + +#: views/packages/main/s2.scan3.php:821 +msgid "Auto filters are applied to prevent archiving other backup sets." +msgstr "" + +#: views/packages/main/s2.scan3.php:832 +#: views/packages/main/s2.scan3.php:841 +msgid "Click to Copy" +msgstr "" + +#: views/packages/main/s2.scan3.php:846 +msgid "Copy the paths above and apply them as needed on Step 1 > Archive > Files section." +msgstr "" + +#: views/packages/main/s2.scan3.php:863 +msgid "Directory applied filter set." +msgstr "" + +#: views/packages/main/s2.scan3.php:890 +msgid "No directories have been selected!" +msgstr "" + +#: views/packages/main/s2.scan3.php:894 +msgid "No files have been selected!" +msgstr "" + +#: views/packages/main/s2.scan3.php:932 +msgid "Copied to Clipboard!" +msgstr "" + +#: views/packages/main/s2.scan3.php:934 +msgid "Manual copy of selected text required on this browser." +msgstr "" + +#: views/packages/main/s2.scan3.php:941 +msgid "Initializing Please Wait..." +msgstr "" + +#: views/packages/main/s2.scan3.php:984 +#: views/packages/main/s2.scan3.php:991 +msgid "Error applying filters. Please go back to Step 1 to add filter manually!" +msgstr "" + +#: views/packages/main/s2.scan3.php:1103 +msgid "Unable to report on any tables" +msgstr "" + +#: views/packages/main/s2.scan3.php:1112 +msgid "Uppercase:" +msgstr "" + +#: views/packages/main/s2.scan3.php:1116 +msgid "Rows:" +msgstr "" + +#: views/packages/main/s2.scan3.php:1120 +msgid "Size:" +msgstr "" + +#: views/packages/main/s2.scan3.php:1129 +msgid "Unable to report on database stats" +msgstr "" + +#: views/packages/main/s3.build.php:21 +msgid "When clicking the Installer download button, the 'Save as' dialog will default the name to 'installer.php'. To improve the security and get more information, goto: Settings ⯠Backups Tab ⯠Installer Name option." +msgstr "" + +#: views/packages/main/s3.build.php:24 +msgid "When clicking the Installer download button, the 'Save as' dialog will save the name as '[name]_[hash]_[time]_installer.php'. This is the secure and recommended option. For more information goto: Settings ⯠Backups Tab ⯠Installer Name Option. To quickly copy the hashed installer name, to your clipboard use the copy icon link." +msgstr "" + +#: views/packages/main/s3.build.php:117 +msgid "Step 3: Build and download the Backup files." +msgstr "" + +#: views/packages/main/s3.build.php:156 +msgid "Keep this window open and do not close during the build process." +msgstr "" + +#: views/packages/main/s3.build.php:157 +msgid "This may take several minutes to complete." +msgstr "" + +#: views/packages/main/s3.build.php:163 +msgid "Build Status" +msgstr "" + +#: views/packages/main/s3.build.php:170 +msgid "Backup Build Completed" +msgstr "" + +#: views/packages/main/s3.build.php:174 +msgid "Build Time" +msgstr "" + +#: views/packages/main/s3.build.php:180 +msgid "Download Backup Files" +msgstr "" + +#: views/packages/main/s3.build.php:182 +msgid "Click to download installer file" +msgstr "" + +#: views/packages/main/s3.build.php:185 +msgid "Click to download Backup file" +msgstr "" + +#: views/packages/main/s3.build.php:186 +msgid "Archive" +msgstr "" + +#: views/packages/main/s3.build.php:190 +msgid "Click to download both files" +msgstr "" + +#: views/packages/main/s3.build.php:192 +msgid "Download Both Files" +msgstr "" + +#: views/packages/main/s3.build.php:196 +msgid "Download Both Files:" +msgstr "" + +#: views/packages/main/s3.build.php:197 +msgid "Clicking this button will open the installer and Backup download prompts one after the other with one click verses downloading each file separately with two clicks. On some browsers you may have to disable pop-up warnings on this domain for this to work correctly." +msgstr "" + +#: views/packages/main/s3.build.php:207 +msgid "[Copy Installer Name to Clipboard]" +msgstr "" + +#: views/packages/main/s3.build.php:212 +msgid "[Show Installer Name]" +msgstr "" + +#: views/packages/main/s3.build.php:228 +msgid "Notice:Duplicator Lite does not officially support WordPress multisite." +msgstr "" + +#: views/packages/main/s3.build.php:238 +msgid "How to install this Backup?" +msgstr "" + +#: views/packages/main/s3.build.php:247 +msgid "Install to Empty Directory " +msgstr "" + +#: views/packages/main/s3.build.php:256 +msgid "Install to an empty directory like a new WordPress install does." +msgstr "" + +#: views/packages/main/s3.build.php:263 +msgid "Overwrite Site" +msgstr "" + +#: views/packages/main/s3.build.php:270 +msgid "Quickly overwrite an existing WordPress site in a few clicks." +msgstr "" + +#: views/packages/main/s3.build.php:277 +msgid "Import Backup and Overwrite Site" +msgstr "" + +#: views/packages/main/s3.build.php:283 +msgid "Drag and drop or use a URL for super-fast installs (requires Pro*)" +msgstr "" + +#: views/packages/main/s3.build.php:300 +msgid "Host Build Interrupt" +msgstr "" + +#: views/packages/main/s3.build.php:301 +msgid "This server cannot complete the build due to host setup constraints, see the error message for more details." +msgstr "" + +#: views/packages/main/s3.build.php:302 +msgid "If the error details are not specific consider the options below by clicking each section." +msgstr "" + +#: views/packages/main/s3.build.php:309 +msgid "Option 1: DupArchive" +msgstr "" + +#: views/packages/main/s3.build.php:314 +msgid "Enable the DupArchive format which is specific to Duplicator and designed to perform better on constrained budget hosts." +msgstr "" + +#: views/packages/main/s3.build.php:320 +msgctxt "1: opening link tag, 2: closing link tag ()" +msgid "" +"Note: DupArchive on Duplicator only supports sites up to 500MB. If your site is over 500MB then use a file filter on \n" +" step 1 to get the size below 500MB or try the other options mentioned below. Alternatively, you may want to consider \n" +" %1$sDuplicator Pro%2$s, which is capable of migrating sites much larger than 500MB." +msgstr "" + +#: views/packages/main/s3.build.php:334 +#: views/packages/main/s3.build.php:415 +msgid "Please follow these steps:" +msgstr "" + +#: views/packages/main/s3.build.php:336 +msgid "On the scanner step check to make sure your Backup is under 500MB. If not see additional options below." +msgstr "" + +#: views/packages/main/s3.build.php:338 +msgid "Go to Duplicator > Settings > Backups Tab > Backup Engine >" +msgstr "" + +#: views/packages/main/s3.build.php:339 +msgid "Enable DupArchive" +msgstr "" + +#: views/packages/main/s3.build.php:341 +msgid "Build a new Backup using the new engine format." +msgstr "" + +#: views/packages/main/s3.build.php:347 +msgctxt "1: opening link tag, 2: closing link tag ()" +msgid "" +"Note: The DupArchive engine will generate an archive.daf file. This file is very similar to a .zip except that it can \n" +" only be extracted by the installer.php file or the %1$scommandline extraction tool%2$s." +msgstr "" + +#: views/packages/main/s3.build.php:367 +msgid "Option 2: File Filters" +msgstr "" + +#: views/packages/main/s3.build.php:372 +msgid "The first pass for reading files on some budget hosts maybe slow and have conflicts with strict timeout settings setup by the hosting provider. In these cases, it is recommended to retry the build by adding file filters to larger files/directories." +msgstr "" + +#: views/packages/main/s3.build.php:377 +msgid "For example, you could filter out the \"/wp-content/uploads/\" folder to create the Backup then move the files from that directory over manually. If this work-flow is not desired or does not work please check-out the other options below." +msgstr "" + +#: views/packages/main/s3.build.php:382 +msgid "Retry Build With Filters" +msgstr "" + +#: views/packages/main/s3.build.php:390 +msgid "Build Folder:" +msgstr "" + +#: views/packages/main/s3.build.php:392 +msgid "On some servers the build will continue to run in the background. To validate if a build is still running; open the 'tmp' folder above and see if the Backup file is growing in size or check the main Backups screen to see if the Backup completed. If it is not then your server has strict timeout constraints." +msgstr "" + +#: views/packages/main/s3.build.php:405 +msgid "Option 3: Two-Part Install" +msgstr "" + +#: views/packages/main/s3.build.php:410 +msgid "A two-part install minimizes server load and can avoid I/O and CPU issues encountered on some budget hosts. With this procedure you simply build a 'database-only' Backup, manually move the website files, and then run the installer to complete the process." +msgstr "" + +#: views/packages/main/s3.build.php:414 +msgid " Overview" +msgstr "" + +#: views/packages/main/s3.build.php:417 +msgid "Click the button below to go back to Step 1." +msgstr "" + +#: views/packages/main/s3.build.php:418 +msgid "On Step 1 the \"Backup Only the Database\" checkbox will be auto checked." +msgstr "" + +#: views/packages/main/s3.build.php:422 +msgctxt "1: opening link, 2: closing link" +msgid "Complete the Backup build and follow the %1$sQuick Start Two-Part Install Instructions%2$s" +msgstr "" + +#: views/packages/main/s3.build.php:436 +msgid "Yes. I have read the above overview and would like to continue!" +msgstr "" + +#: views/packages/main/s3.build.php:438 +msgid "Start Two-Part Install Process" +msgstr "" + +#: views/packages/main/s3.build.php:448 +msgid "Option 4: Configure Server" +msgstr "" + +#: views/packages/main/s3.build.php:452 +msgid "OPTION 4:" +msgstr "" + +#: views/packages/main/s3.build.php:453 +msgid "This option is available on some hosts that allow for users to adjust server configurations. With this option you will be directed to an FAQ page that will show various recommendations you can take to improve/unlock constraints set up on this server." +msgstr "" + +#: views/packages/main/s3.build.php:462 +msgid "Diagnose Server Setup" +msgstr "" + +#: views/packages/main/s3.build.php:466 +msgid "RUNTIME DETAILS" +msgstr "" + +#: views/packages/main/s3.build.php:469 +msgid "Allowed Runtime:" +msgstr "" + +#: views/packages/main/s3.build.php:473 +msgid "PHP Max Execution" +msgstr "" + +#: views/packages/main/s3.build.php:483 +msgid "This value is represented in seconds. A value of 0 means no timeout limit is set for PHP." +msgstr "" + +#: views/packages/main/s3.build.php:487 +#: views/settings/packages.php:209 +msgid "Mode" +msgstr "" + +#: views/packages/main/s3.build.php:493 +msgid "PHP Max Execution Mode" +msgstr "" + +#: views/packages/main/s3.build.php:495 +msgid "If the value is [dynamic] then its possible for PHP to run longer than the default. If the value is [fixed] then PHP will not be allowed to run longer than the default.

        If this value is larger than the [Allowed Runtime] above then the web server has been enabled with a timeout cap and is overriding the PHP max time setting." +msgstr "" + +#: views/packages/main/s3.build.php:503 +msgid "unavailable" +msgstr "" + +#: views/packages/main/s3.build.php:515 +msgid "System Details" +msgstr "" + +#: views/packages/main/s3.build.php:522 +msgid "Error status unavailable." +msgstr "" + +#: views/packages/main/s3.build.php:530 +msgid "See Backup Log For Complete Details" +msgstr "" + +#: views/parts/migration-almost-complete.php:15 +msgid "Restore Backup Almost Complete!" +msgstr "" + +#: views/parts/migration-almost-complete.php:23 +msgid "Reserved Duplicator installation files have been detected in the root directory. Please delete these installation files to avoid security issues." +msgstr "" + +#: views/parts/migration-almost-complete.php:31 +msgid "Go to: Duplicator > Tools > General > Information > Utils and click the \"Remove Installation Files\" button" +msgstr "" + +#: views/parts/migration-almost-complete.php:43 +#: views/parts/migration-message.php:72 +msgid "If an archive.zip/daf file was intentially added to the root directory to perform an overwrite install of this site then you can ignore this message." +msgstr "" + +#: views/parts/migration-clean-installation-files.php:13 +msgid "Installation cleanup ran!" +msgstr "" + +#: views/parts/migration-clean-installation-files.php:21 +msgid "No Duplicator files were found on this WordPress Site." +msgstr "" + +#: views/parts/migration-clean-installation-files.php:27 +msgid "Removed" +msgstr "" + +#: views/parts/migration-clean-installation-files.php:31 +msgid "Found" +msgstr "" + +#: views/parts/migration-clean-installation-files.php:47 +msgid "Some of the installer files did not get removed, " +msgstr "" + +#: views/parts/migration-clean-installation-files.php:49 +msgid "please retry the installer cleanup process" +msgstr "" + +#: views/parts/migration-clean-installation-files.php:51 +msgid " If this process continues please see the previous FAQ link." +msgstr "" + +#: views/parts/migration-clean-installation-files.php:60 +msgid "Security Notes" +msgstr "" + +#: views/parts/migration-clean-installation-files.php:62 +msgid " If the installer files do not successfully get removed with this action, then they WILL need to be removed manually through your hosts control panel or FTP. Please remove all installer files to avoid any security issues on this site." +msgstr "" + +#: views/parts/migration-clean-installation-files.php:71 +msgctxt "%1$s and %2$s are tags" +msgid "For more details please visit the FAQ link %1$sWhich files need to be removed after an install?%2$s" +msgstr "" + +#: views/parts/migration-clean-installation-files.php:82 +msgid "Help Support Duplicator" +msgstr "" + +#: views/parts/migration-clean-installation-files.php:84 +msgid "The Duplicator team has worked many years to make moving a WordPress site a much easier process. " +msgstr "" + +#: views/parts/migration-clean-installation-files.php:87 +msgctxt "%1$s and %2$s are tags" +msgid "Show your support with a %1$s5 star review%2$s! We would be thrilled if you could!" +msgstr "" + +#: views/parts/migration-message.php:15 +msgid "This site has been successfully restored!" +msgstr "" + +#: views/parts/migration-message.php:22 +msgid "The following installation files are stored in the folder %s" +msgstr "" + +#: views/parts/migration-message.php:38 +msgid "Security actions:" +msgstr "" + +#: views/parts/migration-message.php:50 +msgid "Final step:" +msgstr "" + +#: views/parts/migration-message.php:63 +msgid "Note: This message will be removed after all installer files are removed. Installer files must be removed to maintain a secure site. Click the link above to remove all installer files and complete the migration." +msgstr "" + +#: views/settings/about-info.php:49 +msgid "" +"Duplicator can streamline your workflow and quickly clone/migrate a WordPress site. The plugin helps admins, designers and \n" +" developers speed up the migration process of moving a WordPress site. Please help us continue development by giving the plugin a \n" +" 5 star and consider purchasing our Pro product." +msgstr "" + +#: views/settings/about-info.php:63 +msgid "Rate Duplicator" +msgstr "" + +#: views/settings/about-info.php:75 +msgid "Support Duplicator
        with a 5 star review!" +msgstr "" + +#: views/settings/about-info.php:91 +msgid "Spread the Word" +msgstr "" + +#: views/settings/about-info.php:99 +msgid "Facebook" +msgstr "" + +#: views/settings/about-info.php:102 +msgid "Twitter" +msgstr "" + +#: views/settings/about-info.php:105 +msgid "LinkedIn" +msgstr "" + +#: views/settings/controller.php:48 +msgid "Access" +msgstr "" + +#: views/settings/controller.php:55 +msgid "Misc" +msgstr "" + +#: views/settings/packages.php:14 +msgid "Backup Settings Saved" +msgstr "" + +#: views/settings/packages.php:100 +msgid "Mysqldump" +msgstr "" + +#: views/settings/packages.php:110 +msgid "PHP Code" +msgstr "" + +#: views/settings/packages.php:120 +msgid "This server does not support the PHP shell_exec or exec function which is required for mysqldump to run. " +msgstr "" + +#: views/settings/packages.php:121 +msgid "Please contact the host or server administrator to enable this feature." +msgstr "" + +#: views/settings/packages.php:126 +msgid "Host Recommendation:" +msgstr "" + +#: views/settings/packages.php:127 +msgid "Duplicator recommends going with the high performance pro plan or better from our recommended list" +msgstr "" + +#: views/settings/packages.php:131 +msgctxt "%1s and %2s represents the opening and closing HTML tags for an anchor or link" +msgid "Please visit our recommended %1$shost list%2$s for reliable access to mysqldump." +msgstr "" + +#: views/settings/packages.php:151 +msgid "Successfully Found:" +msgstr "" + +#: views/settings/packages.php:158 +msgid "Mysqldump was not found at its default location or the location provided. Please enter a custom path to a valid location where mysqldump can run. If the problem persist contact your host or server administrator. " +msgstr "" + +#: views/settings/packages.php:162 +msgctxt "%1s and %2s represents the opening and closing HTML tags for an anchor or link" +msgid "See the %1$shost list%2$s for reliable access to mysqldump." +msgstr "" + +#: views/settings/packages.php:176 +msgid "Custom Path" +msgstr "" + +#: views/settings/packages.php:178 +msgid "mysqldump path:" +msgstr "" + +#: views/settings/packages.php:180 +msgid "Add a custom path if the path to mysqldump is not properly detected. For all paths use a forward slash as the path seperator. On Linux systems use mysqldump for Windows systems use mysqldump.exe. If the path tried does not work please contact your hosting provider for details on the correct path." +msgstr "" + +#: views/settings/packages.php:189 +msgid "/usr/bin/mypath/mysqldump" +msgstr "" + +#: views/settings/packages.php:194 +msgid " The custom path provided is not recognized as a valid mysqldump file:
        " +msgstr "" + +#: views/settings/packages.php:212 +msgid "Single-Threaded" +msgstr "" + +#: views/settings/packages.php:215 +msgid "Multi-Threaded (Pro)" +msgstr "" + +#: views/settings/packages.php:219 +msgid "PHP Code Mode:" +msgstr "" + +#: views/settings/packages.php:221 +msgid "Single-Threaded mode attempts to create the entire database script in one request. Multi-Threaded mode allows the database script to be chunked over multiple requests. Multi-Threaded mode is typically slower but much more reliable especially for larger databases." +msgstr "" + +#: views/settings/packages.php:223 +msgid "

        Multi-Threaded mode is only available in Duplicator Pro." +msgstr "" + +#: views/settings/packages.php:226 +msgid "Query Limit Size" +msgstr "" + +#: views/settings/packages.php:236 +msgid "PHP Query Limit Size" +msgstr "" + +#: views/settings/packages.php:237 +msgid "A higher limit size will speed up the database build time, however it will use more memory. If your host has memory caps start off low." +msgstr "" + +#: views/settings/packages.php:260 +msgid "ZipArchive" +msgstr "" + +#: views/settings/packages.php:266 +msgid "DupArchive" +msgstr "" + +#: views/settings/packages.php:274 +msgid "Creates a Backup format (archive.zip)." +msgstr "" + +#: views/settings/packages.php:277 +msgid "This option uses the internal PHP ZipArchive classes to create a zip file." +msgstr "" + +#: views/settings/packages.php:279 +msgid "Duplicator Lite has no fixed size constraints for zip formats. The only constraints are timeouts on the server." +msgstr "" + +#: views/settings/packages.php:289 +msgid "Creates a custom Backup format (archive.daf)." +msgstr "" + +#: views/settings/packages.php:292 +msgid "This option is recommended for large sites or sites on constrained servers." +msgstr "" + +#: views/settings/packages.php:293 +msgid "Duplicator Lite has a fixed constraint of 500MB for daf formats." +msgstr "" + +#: views/settings/packages.php:296 +msgctxt "%1$s and %2$s represents the opening and closing HTML tags for an anchor or link" +msgid "Consider upgrading to %1$sDuplicator Pro%2$s for unlimited large site support with DupArchive." +msgstr "" + +#: views/settings/packages.php:311 +msgid "Network Keep Alive" +msgstr "" + +#: views/settings/packages.php:314 +msgid "Attempt Network Keep Alive" +msgstr "" + +#: views/settings/packages.php:315 +msgid "enable only for large archives" +msgstr "" + +#: views/settings/packages.php:318 +msgid "This will attempt to keep a network connection established for large archives." +msgstr "" + +#: views/settings/packages.php:320 +msgid " Valid only when Backup Engine for ZipArchive is enabled." +msgstr "" + +#: views/settings/packages.php:331 +msgid "File Name" +msgstr "" + +#: views/settings/packages.php:333 +msgid "Default 'Save as' name:" +msgstr "" + +#: views/settings/packages.php:348 +msgid "Secure" +msgstr "" + +#: views/settings/packages.php:350 +msgctxt "Leave _installer.php part as is translate only [name], [hash] and [time]" +msgid "[name]_[hash]_[time]_installer.php" +msgstr "" + +#: views/settings/packages.php:356 +msgid "recommended" +msgstr "" + +#: views/settings/packages.php:359 +msgid "To understand the importance and usage of the installer name, please" +msgstr "" + +#: views/settings/packages.php:360 +msgid "read this section" +msgstr "" + +#: views/settings/packages.php:364 +msgid "Using a 'Secure' file helps prevent unauthorized access to the installer file." +msgstr "" + +#: views/settings/packages.php:365 +msgid "Example" +msgstr "" + +#: views/settings/packages.php:369 +msgid "This setting specifies the name of the installer used at download-time. Independent of the value of this setting, you can change the name of the installer in the \"Save as\" file dialog at download-time. If you choose to use a custom name, use a file name that is known only to you. Installer filenames must end in \"php\". Changes to the Backup file should not be made." +msgstr "" + +#: views/settings/packages.php:380 +msgid "Do not to leave any installer files on the destination server, after installing the migrated/restored site. Logon as a WordPress administrator and follow the prompts to remove the installer files or remove them manually." +msgstr "" + +#: views/settings/packages.php:388 +msgid "Tip: Each row on the Backups screen includes a copy button to copy the installer name to the clipboard. Paste the installer name from the clipboard into the URL being used to install the destination site. This feature is handy when using the secure installer name." +msgstr "" + +#: views/settings/packages.php:399 +msgid "Visuals" +msgstr "" + +#: views/settings/packages.php:403 +msgid "Created Format" +msgstr "" + +#: views/settings/packages.php:407 +msgid "By Year" +msgstr "" + +#: views/settings/packages.php:414 +msgid "By Month" +msgstr "" + +#: views/settings/packages.php:421 +msgid "By Day" +msgstr "" + +#: views/settings/packages.php:429 +msgid "The UTC date format shown in the 'Created' column on the Backups screen." +msgstr "" + +#: views/settings/packages.php:430 +msgid "To use WordPress timezone formats consider an upgrade to Duplicator Pro." +msgstr "" + +#: views/settings/packages.php:439 +msgid "Save Backup Settings" +msgstr "" + +#: views/settings/storage.php:10 +msgid "Storage Settings Saved" +msgstr "" + +#: views/settings/storage.php:49 +msgid "Storage Location" +msgstr "" + +#: views/settings/storage.php:55 +msgid "Backup files are stored in the wp-content directory for better security and compatibility." +msgstr "" + +#: views/settings/storage.php:58 +msgid "More Advanced Storage Options..." +msgstr "" + +#: views/settings/storage.php:63 +msgid "Apache .htaccess" +msgstr "" + +#: views/settings/storage.php:66 +msgid "Disable .htaccess file in storage directory" +msgstr "" + +#: views/settings/storage.php:69 +msgid "When checked this setting will prevent Duplicator from laying down an .htaccess file in the storage location above." +msgstr "" + +#: views/settings/storage.php:70 +msgid "Only disable this option if issues occur when downloading either the installer/archive files." +msgstr "" + +#: views/settings/storage.php:78 +msgid "Save Storage Settings" +msgstr "" diff --git a/html/wp-content/plugins/duplicator/languages/index.php b/html/wp-content/plugins/duplicator/languages/index.php new file mode 100644 index 0000000..e0ee508 --- /dev/null +++ b/html/wp-content/plugins/duplicator/languages/index.php @@ -0,0 +1,3 @@ + + * @package Encoding + * @version 2.0 + * @link https://github.com/neitanod/forceutf8 + * @example https://github.com/neitanod/forceutf8 + * @license Revised BSD + */ + +//namespace ForceUTF8; +if (!class_exists('DUP_Encoding')) { + class DUP_Encoding + { + const ICONV_TRANSLIT = "TRANSLIT"; + const ICONV_IGNORE = "IGNORE"; + const WITHOUT_ICONV = ""; + protected static $win1252ToUtf8 = array( + 128 => "\xe2\x82\xac", + + 130 => "\xe2\x80\x9a", + 131 => "\xc6\x92", + 132 => "\xe2\x80\x9e", + 133 => "\xe2\x80\xa6", + 134 => "\xe2\x80\xa0", + 135 => "\xe2\x80\xa1", + 136 => "\xcb\x86", + 137 => "\xe2\x80\xb0", + 138 => "\xc5\xa0", + 139 => "\xe2\x80\xb9", + 140 => "\xc5\x92", + 142 => "\xc5\xbd", + 145 => "\xe2\x80\x98", + 146 => "\xe2\x80\x99", + 147 => "\xe2\x80\x9c", + 148 => "\xe2\x80\x9d", + 149 => "\xe2\x80\xa2", + 150 => "\xe2\x80\x93", + 151 => "\xe2\x80\x94", + 152 => "\xcb\x9c", + 153 => "\xe2\x84\xa2", + 154 => "\xc5\xa1", + 155 => "\xe2\x80\xba", + 156 => "\xc5\x93", + + 158 => "\xc5\xbe", + 159 => "\xc5\xb8" + ); + protected static $brokenUtf8ToUtf8 = array( + "\xc2\x80" => "\xe2\x82\xac", + + "\xc2\x82" => "\xe2\x80\x9a", + "\xc2\x83" => "\xc6\x92", + "\xc2\x84" => "\xe2\x80\x9e", + "\xc2\x85" => "\xe2\x80\xa6", + "\xc2\x86" => "\xe2\x80\xa0", + "\xc2\x87" => "\xe2\x80\xa1", + "\xc2\x88" => "\xcb\x86", + "\xc2\x89" => "\xe2\x80\xb0", + "\xc2\x8a" => "\xc5\xa0", + "\xc2\x8b" => "\xe2\x80\xb9", + "\xc2\x8c" => "\xc5\x92", + + "\xc2\x8e" => "\xc5\xbd", + + + "\xc2\x91" => "\xe2\x80\x98", + "\xc2\x92" => "\xe2\x80\x99", + "\xc2\x93" => "\xe2\x80\x9c", + "\xc2\x94" => "\xe2\x80\x9d", + "\xc2\x95" => "\xe2\x80\xa2", + "\xc2\x96" => "\xe2\x80\x93", + "\xc2\x97" => "\xe2\x80\x94", + "\xc2\x98" => "\xcb\x9c", + "\xc2\x99" => "\xe2\x84\xa2", + "\xc2\x9a" => "\xc5\xa1", + "\xc2\x9b" => "\xe2\x80\xba", + "\xc2\x9c" => "\xc5\x93", + + "\xc2\x9e" => "\xc5\xbe", + "\xc2\x9f" => "\xc5\xb8" + ); + protected static $utf8ToWin1252 = array( + "\xe2\x82\xac" => "\x80", + + "\xe2\x80\x9a" => "\x82", + "\xc6\x92" => "\x83", + "\xe2\x80\x9e" => "\x84", + "\xe2\x80\xa6" => "\x85", + "\xe2\x80\xa0" => "\x86", + "\xe2\x80\xa1" => "\x87", + "\xcb\x86" => "\x88", + "\xe2\x80\xb0" => "\x89", + "\xc5\xa0" => "\x8a", + "\xe2\x80\xb9" => "\x8b", + "\xc5\x92" => "\x8c", + + "\xc5\xbd" => "\x8e", + + + "\xe2\x80\x98" => "\x91", + "\xe2\x80\x99" => "\x92", + "\xe2\x80\x9c" => "\x93", + "\xe2\x80\x9d" => "\x94", + "\xe2\x80\xa2" => "\x95", + "\xe2\x80\x93" => "\x96", + "\xe2\x80\x94" => "\x97", + "\xcb\x9c" => "\x98", + "\xe2\x84\xa2" => "\x99", + "\xc5\xa1" => "\x9a", + "\xe2\x80\xba" => "\x9b", + "\xc5\x93" => "\x9c", + + "\xc5\xbe" => "\x9e", + "\xc5\xb8" => "\x9f" + ); + + public static function toUTF8($text) + { + /** + * Function \ForceUTF8\Encoding::toUTF8 + * + * This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8. + * + * It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1. + * + * It may fail to convert characters to UTF-8 if they fall into one of these scenarios: + * + * 1) when any of these characters: ÀÃÂÃÄÅÆÇÈÉÊËÌÃÃŽÃÃÑÒÓÔÕÖרÙÚÛÜÃÞß + * are followed by any of these: ("group B") + * ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶•¸¹º»¼½¾¿ + * For example: %ABREPRESENT%C9%BB. «REPRESENTÉ» + * The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB) + * is also a valid unicode character, and will be left unchanged. + * + * 2) when any of these: àáâãäåæçèéêëìíîï are followed by TWO chars from group B, + * 3) when any of these: ðñòó are followed by THREE chars from group B. + * + * @name toUTF8 + * @param string $text Any string. + * @return string The same string, UTF8 encoded + * + */ + + if (is_array($text)) { + foreach ($text as $k => $v) { + $text[$k] = self::toUTF8($v); + } + return $text; + } + + if (!is_string($text)) { + return $text; + } + + $max = self::strlen($text); + $buf = ""; + for ($i = 0; $i < $max; $i++) { + $c1 = $text[$i]; + if ($c1 >= "\xc0") { + //Should be converted to UTF8, if it's not UTF8 already + $c2 = $i + 1 >= $max ? "\x00" : $text[$i + 1]; + $c3 = $i + 2 >= $max ? "\x00" : $text[$i + 2]; + $c4 = $i + 3 >= $max ? "\x00" : $text[$i + 3]; + if ($c1 >= "\xc0" & $c1 <= "\xdf") { + //looks like 2 bytes UTF8 + if ($c2 >= "\x80" && $c2 <= "\xbf") { + //yeah, almost sure it's UTF8 already + $buf .= $c1 . $c2; + $i++; + } else { + //not valid UTF8. Convert it. + $cc1 = (chr(ord($c1) / 64) | "\xc0"); + $cc2 = ($c1 & "\x3f") | "\x80"; + $buf .= $cc1 . $cc2; + } + } elseif ($c1 >= "\xe0" & $c1 <= "\xef") { + //looks like 3 bytes UTF8 + if ($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf") { + //yeah, almost sure it's UTF8 already + $buf .= $c1 . $c2 . $c3; + $i = $i + 2; + } else { + //not valid UTF8. Convert it. + $cc1 = (chr(ord($c1) / 64) | "\xc0"); + $cc2 = ($c1 & "\x3f") | "\x80"; + $buf .= $cc1 . $cc2; + } + } elseif ($c1 >= "\xf0" & $c1 <= "\xf7") { + //looks like 4 bytes UTF8 + if ($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf") { + //yeah, almost sure it's UTF8 already + $buf .= $c1 . $c2 . $c3 . $c4; + $i = $i + 3; + } else { + //not valid UTF8. Convert it. + $cc1 = (chr(ord($c1) / 64) | "\xc0"); + $cc2 = ($c1 & "\x3f") | "\x80"; + $buf .= $cc1 . $cc2; + } + } else { + //doesn't look like UTF8, but should be converted + $cc1 = (chr(ord($c1) / 64) | "\xc0"); + $cc2 = (($c1 & "\x3f") | "\x80"); + $buf .= $cc1 . $cc2; + } + } elseif (($c1 & "\xc0") == "\x80") { + // needs conversion + if (isset(self::$win1252ToUtf8[ord($c1)])) { +//found in Windows-1252 special cases + $buf .= self::$win1252ToUtf8[ord($c1)]; + } else { + $cc1 = (chr(ord($c1) / 64) | "\xc0"); + $cc2 = (($c1 & "\x3f") | "\x80"); + $buf .= $cc1 . $cc2; + } + } else { + // it doesn't need conversion + $buf .= $c1; + } + } + return $buf; + } + + public static function toWin1252($text, $option = self::WITHOUT_ICONV) + { + if (is_array($text)) { + foreach ($text as $k => $v) { + $text[$k] = self::toWin1252($v, $option); + } + return $text; + } elseif (is_string($text)) { + return self::utf8_decode($text, $option); + } else { + return $text; + } + } + + public static function toISO8859($text) + { + return self::toWin1252($text); + } + + public static function toLatin1($text) + { + return self::toWin1252($text); + } + + public static function fixUTF8($text, $option = self::WITHOUT_ICONV) + { + if (is_array($text)) { + foreach ($text as $k => $v) { + $text[$k] = self::fixUTF8($v, $option); + } + return $text; + } + + $last = ""; + while ($last <> $text) { + $last = $text; + $text = self::toUTF8(self::utf8_decode($text, $option)); + } + $text = self::toUTF8(self::utf8_decode($text, $option)); + return $text; + } + + public static function UTF8FixWin1252Chars($text) + { + // If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1 + // (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it. + // See: http://en.wikipedia.org/wiki/Windows-1252 + + return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text); + } + + public static function removeBOM($str = "") + { + if (substr($str, 0, 3) == pack("CCC", 0xef, 0xbb, 0xbf)) { + $str = substr($str, 3); + } + return $str; + } + + protected static function strlen($text) + { + if ((version_compare(PHP_VERSION, '7.2.0') >= 0)) { + return (function_exists('mb_strlen')) + ? mb_strlen($text, '8bit') + : strlen($text); + } else { + return (function_exists('mb_strlen') && ((int) ini_get('mbstring.func_overload')) & 2) + ? mb_strlen($text, '8bit') + : strlen($text); + } + } + + public static function normalizeEncoding($encodingLabel) + { + $encoding = strtoupper($encodingLabel); + $encoding = preg_replace('/[^a-zA-Z0-9\s]/', '', $encoding); + $equivalences = array( + 'ISO88591' => 'ISO-8859-1', + 'ISO8859' => 'ISO-8859-1', + 'ISO' => 'ISO-8859-1', + 'LATIN1' => 'ISO-8859-1', + 'LATIN' => 'ISO-8859-1', + 'UTF8' => 'UTF-8', + 'UTF' => 'UTF-8', + 'WIN1252' => 'ISO-8859-1', + 'WINDOWS1252' => 'ISO-8859-1' + ); + if (empty($equivalences[$encoding])) { + return 'UTF-8'; + } + + return $equivalences[$encoding]; + } + + public static function encode($encodingLabel, $text) + { + $encodingLabel = self::normalizeEncoding($encodingLabel); + if ($encodingLabel == 'ISO-8859-1') { + return self::toLatin1($text); + } + return self::toUTF8($text); + } + + protected static function utf8_decode($text, $option) + { + if ($option == self::WITHOUT_ICONV || !function_exists('iconv')) { + $o = utf8_decode(str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text))); + } else { + $o = iconv("UTF-8", "Windows-1252" . ($option == self::ICONV_TRANSLIT ? '//TRANSLIT' : ($option == self::ICONV_IGNORE ? '//IGNORE' : '')), $text); + } + return $o; + } + } + +} diff --git a/html/wp-content/plugins/duplicator/lib/forceutf8/README.md b/html/wp-content/plugins/duplicator/lib/forceutf8/README.md new file mode 100644 index 0000000..d2131c3 --- /dev/null +++ b/html/wp-content/plugins/duplicator/lib/forceutf8/README.md @@ -0,0 +1,61 @@ +forceutf8 +========= + +PHP Class Encoding featuring popular \ForceUTF8\Encoding::toUTF8() function --formerly known as forceUTF8()-- that fixes mixed encoded strings. + +Description +=========== + +If you apply the PHP function utf8_encode() to an already-UTF8 string it will return a garbled UTF8 string. + +This class addresses this issue and provides a handy static function called \ForceUTF8\Encoding::toUTF8(). + +You don't need to know what the encoding of your strings is. It can be Latin1 (iso 8859-1), Windows-1252 or UTF8, or the string can have a mix of them. \ForceUTF8\Encoding::toUTF8() will convert everything to UTF8. + +Sometimes you have to deal with services that are unreliable in terms of encoding, possibly mixing UTF8 and Latin1 in the same string. + +Update: + +I've included another function, \ForceUTF8\Encoding::fixUTF8(), which will fix the double (or multiple) encoded UTF8 string that looks garbled. + +Usage: +====== + + use \ForceUTF8\Encoding; + + $utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string); + + $latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string); + +also: + + $utf8_string = Encoding::fixUTF8($garbled_utf8_string); + +Examples: + + use \ForceUTF8\Encoding; + + echo Encoding::fixUTF8("Fédération Camerounaise de Football\n"); + echo Encoding::fixUTF8("Fédération Camerounaise de Football\n"); + echo Encoding::fixUTF8("Fédération Camerounaise de Football\n"); + echo Encoding::fixUTF8("Fédération Camerounaise de Football\n"); + +will output: + + Fédération Camerounaise de Football + Fédération Camerounaise de Football + Fédération Camerounaise de Football + Fédération Camerounaise de Football + +Install via composer: +===================== +Edit your composer.json file to include the following: + +```json +{ + "require": { + "neitanod/forceutf8": "dev-master" + } +} +``` + diff --git a/html/wp-content/plugins/duplicator/lib/forceutf8/index.php b/html/wp-content/plugins/duplicator/lib/forceutf8/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/lib/forceutf8/index.php @@ -0,0 +1,3 @@ + Duplicator Pro
        +> This plugin is the Lite version of Duplicator Pro, which comes with scheduled backups, cloud storage integrations, multisite support, and more. [Get Duplicator Pro for the complete migration and backup solution](https://duplicator.com/?utm_source=wprepo&utm_medium=link&utm_campaign=duplicator_lite&utm_content=get_duplicator_pro). + +https://www.youtube.com/watch?v=MSa83NkLDmU + + += Easy Site Migration, Backup, and Cloning = + +Duplicator streamlines site migrations by packaging your website files and database into a single file, known as a "backup". Download and re-install your "backup" on any new WordPress location or server without dealing with complicated setups. Launch at your new destination without installing WordPress. Duplicator is the **only** migration and backup plugin that works on an empty site. + + +See why experts love Duplicator: + +> "Duplicator provides an easy to use tool to make backups of your site, or to transfer it to another location." +> Richard McAdams - Expert Web Developer + + += Secure WordPress Backups = + +Duplicator offers cloud [WordPress backups](https://duplicator.com/secure-wordpress-backups/?utm_source=wprepo&utm_medium=link&utm_content=secure_wordpress_backups&utm_campaign=duplicator_lite) with military-grade encryption. Automatically backup your entire WordPress site to secure cloud storage. + += Recovery Points (1-click Restore) = + +Duplicator makes [1-click restores](https://duplicator.com/disaster-recovery-1-click-restore/?utm_source=wprepo&utm_medium=link&utm_content=1_click_restores&utm_campaign=duplicator_lite) for WordPress backups easy and stress-free. Quickly restore your entire website in minutes just like a time machine. + += Fast WordPress Migrations = + +Duplicator makes [WordPress website migrations](https://duplicator.com/wordpress-migration/?utm_source=wprepo&utm_medium=link&utm_content=wordpress_migrations&utm_campaign=duplicator_lite) fast and stress-free. Quickly move to a new host, domain, or server. No downtime, no data loss, and no coding required. + += WordPress Multisite Backups = + +Duplicator offers automatic [WordPress Multisite backups](https://duplicator.com/wordpress-multisite-backups/?utm_source=wprepo&utm_medium=link&utm_content=wordpress_multisite_backups&utm_campaign=duplicator_lite) with easy 1-click restore. Safely backup your entire Multisite network to secure cloud storage. + += WooCommerce Backups = + +Duplicator offers reliable [WooCommerce backups](https://duplicator.com/woocommerce-backups/?utm_source=wprepo&utm_medium=link&utm_content=woocommerce_backups&utm_campaign=duplicator_lite) with military-grade encryption. Easily and automatically back up your entire online store to secure cloud storage. + += Pre-configured WordPress Installs = + +Never start from scratch with Duplicator’s smart [pre-configured WordPress installs](https://duplicator.com/pre-configured-wordpress-installations/?utm_source=wprepo&utm_medium=link&utm_content=pre_configured_installs&utm_campaign=duplicator_lite). Save time and hassle duplicating ready-made sites with 1-click. + += WordPress Recovery Points with Quick Rollbacks = + +Duplicator offers hourly recovery points and [1-click rollbacks for WordPress sites](https://duplicator.com/wordpress-recovery-points-rollback/?utm_source=wprepo&utm_medium=link&utm_content=wordpress_recovery_points&utm_campaign=duplicator_lite). Quickly and automatically recover from failed WordPress updates or disasters. + += Partial WordPress Backup Plugin = + +Duplicator makes [partial backups for WordPress](https://duplicator.com/partial-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=partial_backups&utm_campaign=duplicator_lite) quick and easy. Save storage and restore sites faster with database-only, media-only, or completely custom backups. + + += Server to Server WordPress Migration Import Tool = + +Duplicator makes [server-to-server WordPress migrations](https://duplicator.com/server-to-server-wordpress-migration/?utm_source=wprepo&utm_medium=link&utm_content=server_to_server_migrations&utm_campaign=duplicator_lite) fast and hassle-free. Quickly import your website to a new server in minutes. No downtime, no data loss. + + += Smart WordPress Migration Wizard = + +Duplicator’s smart [WordPress migration wizard](https://duplicator.com/wordpress-migration-wizard/?utm_source=wprepo&utm_medium=link&utm_content=wordpress_migration_wizard&utm_campaign=duplicator_lite) makes transferring your website to a new host or server effortless. No downtime, no data loss, and no code required. + + += Drag & Drop Import WordPress Website Tool = + +Migrating WordPress sites has never been easier with Duplicator’s [drag & drop import tools](https://duplicator.com/drag-drop-import-wordpress-tool/?utm_source=wprepo&utm_medium=link&utm_content=wordpress_migration_wizard&utm_campaign=duplicator_lite). Quickly transfer your site to a new host or server in minutes, no code required. + + += Clone WordPress Website Plugin = + +Duplicator [clones your entire WordPress website](https://duplicator.com/clone-wordpress-plugin/?utm_source=wprepo&utm_medium=link&utm_content=clone_wordpress_website&utm_campaign=duplicator_lite) with 1-click, no code needed. Perfect for staging sites, sandbox, or site migration. + + += Duplicator Pro Features = +Duplicator Pro takes Duplicator to the next level with features you'll love, such as: + +* Drag and Drop installs - just drag the backup file to the destination site! +* Scheduled backups +* Cloud Storage to Dropbox Backups, Google Drive Backups, Microsoft OneDrive Backups, Amazon S3 Backups and FTP/SFTP Backups +* Custom Backups and Cloning: want just plugins, or just themes, just the database? No problem! +* A special 2-step streamlined installer mode for mega-fast installs +* Recovery Points added for very fast emergency site restores +* Support for managed and shared hosts such as WordPress.com, WPEngine, GoDaddy Managed, and more +* Multi-threaded to support larger websites & databases +* Migrate an entire multisite WordPress network or a sub site as a standalone site +* Database and user creation *in the installer* with cPanel API +* Connect to cPanel directly from the installer +* Custom plugin hooks for developers +* Advanced permissions +* Email notifications +* Professional support +* ... and much more! + += Supported Backup Cloud Storage Integrations = +We support any Amazon S3 compatible storage providers plus these first-party integrations. + +* [Localhost Backups](https://duplicator.com/secure-wordpress-backups/?utm_source=wprepo&utm_medium=link&utm_content=localhost_backups&utm_campaign=duplicator_lite) +* [FTP/ SFTP Backups](https://duplicator.com/ftp-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=ftp_sftp_backups&utm_campaign=duplicator_lite) +* [Dropbox Backups](https://duplicator.com/dropbox-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=dropbox_backups&utm_campaign=duplicator_lite) +* [Google Drive Backups](https://duplicator.com/google-drive-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=google_drive_backups&utm_campaign=duplicator_lite) +* [Microsoft OneDrive Backups](https://duplicator.com/microsoft-one-drive-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=microsoft_one_drive_backups&utm_campaign=duplicator_lite) +* [Amazon S3 Backups](https://duplicator.com/amazon-s3-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=amazon_s3_backups&utm_campaign=duplicator_lite) +* [Cloudflare R2 Backups](https://duplicator.com/cloudflare-r2-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=cloudflare_r2_backups&utm_campaign=duplicator_lite) +* [Wasabi Backups](https://duplicator.com/wasabi-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=wasabi_backups&utm_campaign=duplicator_lite) +* [Dream Objects Backups](https://duplicator.com/dream-objects-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=dream_objects_backups&utm_campaign=duplicator_lite) +* [Vultr Backups](https://duplicator.com/vultr-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=vultr_backups&utm_campaign=duplicator_lite) +* [Digital Ocean Spaces Backups](https://duplicator.com/wordpress-backups-for-digitalocean-spaces/?utm_source=wprepo&utm_medium=link&utm_content=digital_ocean_spaces_backups&utm_campaign=duplicator_lite) +* [Google Cloud Storage Backups](https://duplicator.com/google-cloud-storage-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=google_cloud_storage_backups&utm_campaign=duplicator_lite) +* [Backblaze B2 Storage Backups](https://duplicator.com/backblaze-b2-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=backblaze_b2_storage_backups&utm_campaign=duplicator_lite) +* [Linode Object Storage Backups](https://duplicator.com/linode-object-storage-wordpress-backup-plugin/?utm_source=wprepo&utm_medium=link&utm_content=linode_object_storage_backups&utm_campaign=duplicator_lite) + + +You can easily see why Duplicator is the best WordPress backup and migration plugin on the market! Want to unlock these features? [Upgrade to our Pro version](https://duplicator.com/?utm_source=wprepo&utm_medium=link&utm_content=upgrade_to_pro&utm_campaign=duplicator_lite) + += Branding Guidelines = + +Duplicator® is a registered trademark of Snap Creek LLC. When writing about the backup & migration plugin by Duplicator, please make sure to uppercase the initial first letter. + +* Duplicator (correct) +* duplicator (incorrect) + + +== Screenshots == + +1. Main Interface for all Backups +2. Create Backup Step 1 +3. Create Backup Step 2 +4. Build Process +5. Installer Screen + +== Frequently Asked Questions == + += Who Should Use Duplicator? = + +Duplicator is perfect for business owners, bloggers, designers, developers, photographers, and basically everyone else. If you want to create a WordPress Backup or Migration, then you need to use Duplicator. + += What's required to use Duplicator? = + +Duplicator is a WordPress Plugin. In order to use Duplicator, you must have a self-hosted WordPress site. That's all. + += Do I need coding skills to use Duplicator? = + +Absolutely not. You can create backups and migrations without any coding knowledge. Duplicator is the most beginner-friendly backup solution in the market. + += Will Duplicator slow down my website? = + +Absolutely not. Duplicator is carefully built with performance in mind. We have developed everything with best practices and modern standards to ensure things run smooth and fast. + += Can I backup WooCommerce sites? = + +Yes. Duplicator makes [backing up WooCommerce sites](https://duplicator.com/woocommerce-backups/?utm_source=wprepo&utm_medium=link&utm_content=faq_woocommerce_backups&utm_campaign=duplicator_lite) easy and stress-free. + + += Is this plugin compatible with WordPress multisite (MU)? = +Yes, however you will need [Duplicator Pro](https://duplicator.com/wordpress-multisite-backups/?utm_source=wprepo&utm_medium=link&utm_content=faq_dpro_multisiteinfo&utm_campaign=duplicator_lite) for full multisite network migrations &backups and the ability to install a multisite subsite as a standalone site. + += Where can I get more help and support for this plugin? = +Purchase a Pro License for quick support [Duplicator Pro](https://duplicator.com/pricing/?utm_source=wprepo&utm_medium=link&utm_content=faq_support&utm_campaign=duplicator_lite) + += Does Duplicator have a knowledge base or FAQ? = +Yes. Please see [all documents](https://duplicator.com/knowledge-base/?utm_source=wprepo&utm_medium=link&utm_content=faq_docs&utm_campaign=duplicator_lite) at duplicator.com + += Installation Instructions = +1. Upload `duplicator` folder to the `/wp-content/plugins/` directory +2. Activate the plugin through the 'Plugins' menu in WordPress +3. Click on the Duplicator link from the main menu +4. Check out the help by clicking the help icon and create your first backup. + +The Duplicator requires php 5.3 or higher. + +== Changelog == + +Please see the following url: +[https://duplicator.com/knowledge-base/changelog/](https://duplicator.com/knowledge-base/changelog/?lite&utm_source=wprepo&utm_medium=link&utm_content=changelog_support&utm_campaign=duplicator_lite) + + + +== Upgrade Notice == \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/src/Ajax/AbstractAjaxService.php b/html/wp-content/plugins/duplicator/src/Ajax/AbstractAjaxService.php new file mode 100644 index 0000000..4f7054d --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Ajax/AbstractAjaxService.php @@ -0,0 +1,31 @@ + null, + 'output' => '', + 'message' => '' + ); + + ob_start(); + try { + DUP_Handler::init_error_handler(); + $nonce = SnapUtil::sanitizeNSCharsNewline($nonce); + if (is_null($nonceaction) || !wp_verify_nonce($nonce, $nonceaction)) { + DUP_Log::trace('Security issue'); + throw new Exception('Security issue'); + } + if (!is_null($capability)) { + DUP_Util::hasCapability($capability, DUP_Util::SECURE_ISSUE_THROW); + } + + // execute ajax function + $result['funcData'] = call_user_func($callback); + } catch (Exception $e) { + $error = true; + $result['message'] = $e->getMessage(); + } + + $result['output'] = ob_get_clean(); + if ($errorUnespectedOutput && !empty($result['output'])) { + $error = true; + } + + if ($error) { + wp_send_json_error($result); + } else { + wp_send_json_success($result); + } + } + + /** + * This function wrap a callback and start a chunked file download. + * The callback must return a file path. + * + * @param callable():false|array{path:string,name:string} $callback Callback function that return a file path for download or false on error + * @param string $nonceaction if action is null don't verify nonce + * @param string $nonce nonce string + * @param bool $errorUnespectedOutput if true thorw exception with unespected optput + * + * @return never + */ + public static function fileDownload( + $callback, + $nonceaction = null, + $nonce = null, + $errorUnespectedOutput = true + ) { + ob_start(); + try { + DUP_Handler::init_error_handler(); + $nonce = SnapUtil::sanitizeNSCharsNewline($nonce); + if (!is_null($nonceaction) && !wp_verify_nonce($nonce, $nonceaction)) { + DUP_Log::trace('Security issue'); + throw new Exception('Security issue'); + } + + // execute ajax function + if (($fileInfo = call_user_func($callback)) === false) { + throw new Exception('Error generating file'); + } + + if (!@file_exists($fileInfo['path'])) { + throw new Exception('File ' . $fileInfo['path'] . ' not found'); + } + + $result['output'] = ob_get_clean(); + if ($errorUnespectedOutput && !empty($result['output'])) { + throw new Exception('Unespected output'); + } + + SnapIO::serveFileForDownload($fileInfo['path'], $fileInfo['name'], DUPLICATOR_BUFFER_READ_WRITE_SIZE); + } catch (Exception $e) { + DUP_Log::trace($e->getMessage()); + SnapIO::serverError500(); + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Ajax/ServicesDashboard.php b/html/wp-content/plugins/duplicator/src/Ajax/ServicesDashboard.php new file mode 100644 index 0000000..7bf9411 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Ajax/ServicesDashboard.php @@ -0,0 +1,80 @@ +addAjaxCall('wp_ajax_duplicator_dashboad_widget_info', 'dashboardWidgetInfo'); + $this->addAjaxCall('wp_ajax_duplicator_dismiss_recommended_plugin', 'dismissRecommendedPlugin'); + } + + /** + * Set recovery callback + * + * @return array + */ + public static function dashboardWidgetInfoCallback() + { + $result = array( + 'isRunning' => DUP_Package::isPackageRunning(), + 'lastBackupInfo' => DashboardWidget::getLastBackupString() + ); + return $result; + } + + /** + * Set recovery action + * + * @return void + */ + public function dashboardWidgetInfo() + { + AjaxWrapper::json( + array(__CLASS__, 'dashboardWidgetInfoCallback'), + 'duplicator_dashboad_widget_info', + $_POST['nonce'], + 'export' + ); + } + + /** + * Set dismiss recommended callback + * + * @return bool + */ + public static function dismissRecommendedPluginCallback() + { + return (update_user_meta(get_current_user_id(), DashboardWidget::RECOMMENDED_PLUGIN_DISMISSED_OPT_KEY, true) !== false); + } + + /** + * Set recovery action + * + * @return void + */ + public function dismissRecommendedPlugin() + { + AjaxWrapper::json( + array(__CLASS__, 'dismissRecommendedPluginCallback'), + 'duplicator_dashboad_widget_dismiss_recommended', + $_POST['nonce'], + 'export' + ); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Ajax/ServicesEducation.php b/html/wp-content/plugins/duplicator/src/Ajax/ServicesEducation.php new file mode 100644 index 0000000..6d2a7fe --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Ajax/ServicesEducation.php @@ -0,0 +1,430 @@ +addAjaxCall('wp_ajax_duplicator_settings_callout_cta_dismiss', 'dismissCalloutCTA'); + $this->addAjaxCall('wp_ajax_duplicator_packages_bottom_bar_dismiss', 'dismissBottomBar'); + $this->addAjaxCall('wp_ajax_duplicator_email_subscribe', 'setEmailSubscribed'); + $this->addAjaxCall('wp_ajax_duplicator_generate_connect_oth', 'generateConnectOTH'); + $this->addAjaxCall('wp_ajax_nopriv_duplicator_lite_run_one_click_upgrade', 'oneClickUpgrade'); + $this->addAjaxCall('wp_ajax_duplicator_lite_run_one_click_upgrade', 'oneClickUpgrade'); + $this->addAjaxCall('wp_ajax_duplicator_enable_usage_stats', 'enableUsageStats'); + } + + /** + * Set email subscribed + * + * @return bool + */ + public static function setEmailSubscribedCallback() + { + if (EducationElements::userIsSubscribed()) { + return true; + } + + $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL, FILTER_NULL_ON_FAILURE); + if (is_null($email)) { + throw new \Exception('Invalid email'); + } + + $response = wp_remote_post(self::REMOTE_SUBSCRIBE_URL, array( + 'method' => 'POST', + 'timeout' => 45, + 'body' => array('email' => $email) + )); + + if (is_wp_error($response) || 200 !== wp_remote_retrieve_response_code($response)) { + $error_msg = $response->get_error_code() . ': ' . $response->get_error_message(); + SnapUtil::errorLog($error_msg); + throw new \Exception($error_msg); + } + + return (update_user_meta(get_current_user_id(), EducationElements::DUP_EMAIL_SUBSCRIBED_OPT_KEY, true) !== false); + } + + /** + * Set recovery action + * + * @return void + */ + public function setEmailSubscribed() + { + AjaxWrapper::json( + array(__CLASS__, 'setEmailSubscribedCallback'), + 'duplicator_email_subscribe', + $_POST['nonce'], + 'export' + ); + } + + /** + * Set dismiss callout CTA callback + * + * @return bool + */ + public static function dismissCalloutCTACallback() + { + return (update_user_meta(get_current_user_id(), EducationElements::DUP_SETTINGS_FOOTER_CALLOUT_DISMISSED, true) !== false); + } + + /** + * Dismiss callout CTA + * + * @return void + */ + public function dismissCalloutCTA() + { + AjaxWrapper::json( + array(__CLASS__, 'dismissCalloutCTACallback'), + 'duplicator_settings_callout_cta_dismiss', + $_POST['nonce'], + 'export' + ); + } + + /** + * Dismiss bottom bar callback + * + * @return bool + */ + public static function dismissBottomBarCallback() + { + return (update_user_meta(get_current_user_id(), EducationElements::DUP_PACKAGES_BOTTOM_BAR_DISMISSED, true) !== false); + } + + /** + * Dismiss bottom bar + * + * @return void + */ + public function dismissBottomBar() + { + AjaxWrapper::json( + array(__CLASS__, 'dismissBottomBarCallback'), + 'duplicator_packages_bottom_bar_dismiss', + $_POST['nonce'], + 'export' + ); + } + + + /** + * Generate OTH for connect flow + * + * @return void + */ + public function generateConnectOTH() + { + AjaxWrapper::json( + array(__CLASS__, 'generateConnectOTHCallback'), + 'duplicator_generate_connect_oth', + SnapUtil::sanitizeTextInput(INPUT_POST, 'nonce'), + 'export' + ); + } + + /** + * Generate OTH for connect flow callback + * + * @return array + * @throws Exception + */ + public static function generateConnectOTHCallback() + { + $oth = wp_generate_password(30, false, false); + $hashed_oth = self::hashOth($oth); + + // Save HASHED OTH with TTL for security + $oth_data = array( + 'token' => $hashed_oth, // Store hashed OTH for decryption + 'created_at' => time(), + 'expires_at' => time() + (10 * MINUTE_IN_SECONDS) // 10 minute expiration + ); + + delete_option(self::OPTION_KEY_ONE_CLICK_UPGRADE_OTH); + $ok = update_option(self::OPTION_KEY_ONE_CLICK_UPGRADE_OTH, $oth_data); + + if (!$ok) { + throw new Exception("Problem saving security token."); + } + + return array( + 'success' => true, + 'oth' => $hashed_oth, + 'php_version' => phpversion(), + 'wp_version' => get_bloginfo('version'), + 'redirect_url' => admin_url('admin-ajax.php?action=duplicator_lite_run_one_click_upgrade') + ); + } + + + /** + * Returh hashed OTH + * + * @param string $oth OTH + * + * @return string Hashed OTH + */ + protected static function hashOth($oth) + { + return hash_hmac('sha512', $oth, wp_salt()); + } + + /** + * Decrypt data using OTH-based key. + * + * @param string $encryptedData Base64 encoded encrypted data + * @param string $oth The OTH token + * + * @return string|false Decrypted data or false on failure + */ + protected static function decryptData($encryptedData, $oth) + { + try { + $encryption_key = substr(hash('sha256', $oth), 0, 32); // 32-byte key from OTH + $iv = substr($oth, 0, 16); // 16-byte IV from OTH + + $encrypted = base64_decode($encryptedData); + return openssl_decrypt($encrypted, 'AES-256-CBC', $encryption_key, 0, $iv); + } catch (Exception $e) { + DUP_Log::trace("ERROR: Decryption failed: " . $e->getMessage()); + return false; + } + } + + /** + * Decrypt and parse encrypted package from service. + * + * @param string $encryptedPackage Base64 encoded encrypted package + * @param string $oth The OTH token + * + * @return array|false Parsed package data or false on failure + */ + protected static function decryptPackage($encryptedPackage, $oth) + { + $decrypted = self::decryptData($encryptedPackage, $oth); + + if ($decrypted === false) { + return false; + } + + $package = json_decode($decrypted, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + DUP_Log::trace("ERROR: Invalid JSON in decrypted package"); + return false; + } + + return $package; + } + + + /** + * Enable usage stats + * + * @return void + */ + public function enableUsageStats() + { + AjaxWrapper::json( + array(__CLASS__, 'enableUsageStatsCallback'), + 'duplicator_enable_usage_stats', + SnapUtil::sanitizeTextInput(INPUT_POST, 'nonce'), + 'manage_options' + ); + } + + /** + * Enable usage stats callback + * + * @return void + */ + public static function enableUsageStatsCallback() + { + $result = true; + if (DUP_Settings::Get('usage_tracking') !== true) { + DUP_Settings::setUsageTracking(true); + $result = DUP_Settings::Save(); + } + + return $result && self::setEmailSubscribedCallback(); + } + + + /** + * Accepts encrypted package from remote endpoint, after validating the OTH. + * + * @return void + */ + public function oneClickUpgrade() + { + try { + // Get encrypted package from service + $encryptedPackage = sanitize_text_field($_REQUEST["package"] ?? ''); + + if (empty($encryptedPackage)) { + DUP_Log::trace("ERROR: No encrypted package received from service."); + throw new Exception("No encrypted package received from service"); + } + + // Get OTH data for validation + $oth_data = get_option(self::OPTION_KEY_ONE_CLICK_UPGRADE_OTH); + + if (empty($oth_data) || !is_array($oth_data)) { + DUP_Log::trace("ERROR: Invalid OTH data structure."); + throw new Exception("Invalid security token"); + } + + // Check TTL expiration + if (time() > $oth_data['expires_at']) { + DUP_Log::trace("ERROR: OTH token expired."); + delete_option(self::OPTION_KEY_ONE_CLICK_UPGRADE_OTH); + throw new Exception("Security token expired"); + } + + // Decrypt package using OTH + $package = self::decryptPackage($encryptedPackage, $oth_data['token']); + + if ($package === false) { + DUP_Log::trace("ERROR: Failed to decrypt package from service."); + throw new Exception("Invalid encrypted data"); + } + + // Extract data from decrypted package + $download_url = $package['download_url'] ?? ''; + $auth_token = $package['auth_token'] ?? ''; + + if (empty($download_url)) { + DUP_Log::trace("ERROR: No download URL in decrypted package."); + throw new Exception("No download URL provided"); + } + + // Delete OTH so it cannot be replayed (single-use) + delete_option(self::OPTION_KEY_ONE_CLICK_UPGRADE_OTH); + + // Save authentication token for Pro to use + if (!empty($auth_token)) { + delete_option(self::AUTH_TOKEN_KEY_OPTION_AUTO_ACTIVE); + update_option(self::AUTH_TOKEN_KEY_OPTION_AUTO_ACTIVE, $auth_token); + DUP_Log::trace("Authentication token saved for Pro activation."); + } + + // Validate download URL format + if (!filter_var($download_url, FILTER_VALIDATE_URL)) { + DUP_Log::trace("ERROR: Invalid download URL format: " . $download_url); + throw new Exception("Invalid download URL format"); + } + + // Install Pro if not already installed + if (!is_dir(WP_PLUGIN_DIR . "/duplicator-pro")) { + DUP_Log::trace("Installing Pro using service-provided URL: " . $download_url); + + // Request filesystem credentials + $url = esc_url_raw(add_query_arg(array('page' => 'duplicator-settings'), admin_url('admin.php'))); + $creds = request_filesystem_credentials($url, '', false, false, null); + + if (false === $creds || ! \WP_Filesystem($creds)) { + wp_send_json_error(array('message' => 'File system permissions error. Please check permissions and try again.')); + } + + // Install the plugin + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + remove_action('upgrader_process_complete', array('Language_Pack_Upgrader', 'async_upgrade'), 20); + + $installer = new Plugin_Upgrader(new UpgraderSkin()); + $result = $installer->install($download_url); + + if (is_wp_error($result)) { + DUP_Log::trace("ERROR: Plugin installation failed: " . $result->get_error_message()); + throw new Exception('Plugin installation failed: ' . $result->get_error_message()); + } + + wp_cache_flush(); + $plugin_basename = $installer->plugin_info(); + + if ($plugin_basename) { + $upgradeDir = dirname($plugin_basename); + if ($upgradeDir != "duplicator-pro" && !rename(WP_PLUGIN_DIR . "/" . $upgradeDir, WP_PLUGIN_DIR . "/duplicator-pro")) { + throw new Exception('Failed renaming plugin directory'); + } + } else { + throw new Exception('Installation of upgrade version failed'); + } + } + + $newFolder = WP_PLUGIN_DIR . "/duplicator-pro"; + if (!is_dir($newFolder)) { + DUP_Log::trace("ERROR: Duplicator Pro folder not found after installation"); + throw new Exception('Pro plugin installation failed - folder not created'); + } + + // Deactivate Lite FIRST (critical for avoiding conflicts) + deactivate_plugins(DUPLICATOR_PLUGIN_PATH . "/duplicator.php"); + + // Create activation URL for Pro + $plugin = "duplicator-pro/duplicator-pro.php"; + $pluginsAdminUrl = is_multisite() ? network_admin_url('plugins.php') : admin_url('plugins.php'); + $activateProUrl = esc_url_raw( + add_query_arg( + array( + 'action' => 'activate', + 'plugin' => $plugin, + '_wpnonce' => wp_create_nonce("activate-plugin_$plugin") + ), + $pluginsAdminUrl + ) + ); + + // Redirect to WordPress activation URL + DUP_Log::trace("Pro installation successful. Redirecting to activation URL: " . $activateProUrl); + wp_safe_redirect($activateProUrl); + exit; + } catch (Exception $e) { + DUP_Log::trace("ERROR in oneClickUpgrade: " . $e->getMessage()); + + // Add error notice and redirect to settings page + Notice::error( + sprintf(__('Upgrade installation failed: %s. Please try again or install manually.', 'duplicator'), $e->getMessage()), + 'one_click_upgrade_failed' + ); + + $settingsUrl = ControllersManager::getMenuLink( + ControllersManager::SETTINGS_SUBMENU_SLUG, + 'general' + ); + + wp_safe_redirect($settingsUrl); + exit; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Ajax/ServicesExtraPlugins.php b/html/wp-content/plugins/duplicator/src/Ajax/ServicesExtraPlugins.php new file mode 100644 index 0000000..9108743 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Ajax/ServicesExtraPlugins.php @@ -0,0 +1,56 @@ +addAjaxCall('wp_ajax_duplicator_install_extra_plugin', 'extraPluginInstall'); + } + + /** + * Install and activate or just activate plugin + * + * @return string + */ + public static function extraPluginInstallCallback() + { + $slug = filter_input(INPUT_POST, 'plugin', FILTER_SANITIZE_STRING); + $message = ''; + + if (!ExtraPluginsMng::getInstance()->install($slug, $message)) { + throw new \Exception($message); + } + + return $message; + } + + /** + * Addon plugin install action callback + * + * @return void + */ + public function extraPluginInstall() + { + AjaxWrapper::json( + array(__CLASS__, 'extraPluginInstallCallback'), + 'duplicator_install_extra_plugin', + $_POST['nonce'], + 'install_plugins' + ); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Ajax/ServicesNotifications.php b/html/wp-content/plugins/duplicator/src/Ajax/ServicesNotifications.php new file mode 100644 index 0000000..8216cbb --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Ajax/ServicesNotifications.php @@ -0,0 +1,69 @@ +addAjaxCall('wp_ajax_duplicator_notification_dismiss', 'setDissmisedNotifications'); + } + + /** + * Dismiss notification + * + * @return bool + */ + public static function dismissNotifications() + { + $id = sanitize_key($_POST['id']); + $type = is_numeric($id) ? 'feed' : 'events'; + $option = Notifications::getOption(); + + $option['dismissed'][] = $id; + $option['dismissed'] = array_unique($option['dismissed']); + + // Remove notification. + if (!is_array($option[$type]) || empty($option[$type])) { + throw new \Exception('Notification type not set.'); + } + + foreach ($option[$type] as $key => $notification) { + if ((string)$notification['id'] === (string)$id) { + unset($option[$type][$key]); + + break; + } + } + + return update_option(Notifications::DUPLICATOR_NOTIFICATIONS_OPT_KEY, $option); + } + + /** + * Set dismiss notification action + * + * @return void + */ + public function setDissmisedNotifications() + { + AjaxWrapper::json( + array(__CLASS__, 'dismissNotifications'), + Notifications::DUPLICATOR_NOTIFICATION_NONCE_KEY, + $_POST['nonce'], + 'manage_options' + ); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Ajax/ServicesTools.php b/html/wp-content/plugins/duplicator/src/Ajax/ServicesTools.php new file mode 100644 index 0000000..44fefd5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Ajax/ServicesTools.php @@ -0,0 +1,61 @@ +addAjaxCall('wp_ajax_duplicator_download_support_toolkit', 'downloadSupportToolkit'); + } + + /** + * Function to download diagnostic data + * + * @return never + */ + public function downloadSupportToolkit() + { + AjaxWrapper::fileDownload( + [ + __CLASS__, + 'downloadSupportToolkitCallback', + ], + 'duplicator_download_support_toolkit', + SnapUtil::sanitizeTextInput(SnapUtil::INPUT_REQUEST, 'nonce') + ); + } + + /** + * Function to create diagnostic data + * + * @return false|array{path:string,name:string} + */ + public static function downloadSupportToolkitCallback() + { + $domain = SnapURL::wwwRemove(SnapURL::parseUrl(network_home_url(), PHP_URL_HOST)); + $result = [ + 'path' => SupportToolkit::getToolkit(), + 'name' => SupportToolkit::SUPPORT_TOOLKIT_PREFIX . + substr(sanitize_file_name($domain), 0, 12) . '_' . + date('YmdHis') . '.zip', + ]; + + return $result; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Controllers/AboutUsController.php b/html/wp-content/plugins/duplicator/src/Controllers/AboutUsController.php new file mode 100644 index 0000000..e4b3e08 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Controllers/AboutUsController.php @@ -0,0 +1,247 @@ + esc_html__('Loading...', 'duplicator'), + 'failure' => esc_html__('Failure', 'duplicator'), + 'active' => esc_html__('Active', 'duplicator'), + 'activated' => esc_html__('Activated', 'duplicator'), + ) + ); + wp_localize_script( + 'duplicator-extra-plugins', + 'duplicator_extra_plugins', + array( + 'ajax_url' => admin_url('admin-ajax.php'), + 'extra_plugin_install_nonce' => wp_create_nonce('duplicator_install_extra_plugin'), + ) + ); + } + + /** + * Enqueue styles + * + * @return void + */ + public static function enqueueStyles() + { + wp_enqueue_style( + 'duplicator-about', + DUPLICATOR_PLUGIN_URL . "assets/css/about.css", + array(), + DUPLICATOR_VERSION + ); + } + + /** + * Render welcome screen + * + * @return void + */ + public static function render() + { + $levels = ControllersManager::getMenuLevels(); + TplMng::getInstance()->render( + 'admin_pages/about_us/tabs', + array( + 'active_tab' => is_null($levels[ControllersManager::QUERY_STRING_MENU_KEY_L2]) ? + self::ABOUT_US_TAB : $levels[ControllersManager::QUERY_STRING_MENU_KEY_L2] + ), + true + ); + + switch ($levels[ControllersManager::QUERY_STRING_MENU_KEY_L2]) { + case self::GETTING_STARTED: + TplMng::getInstance()->render('admin_pages/about_us/getting_started/main', array(), true); + break; + case self::LITE_VS_PRO: + TplMng::getInstance()->render('admin_pages/about_us/lite_vs_pro/main', array(), true); + break; + case self::ABOUT_US_TAB: + default: + TplMng::getInstance()->render('admin_pages/about_us/about_us/main', array(), true); + break; + } + } + + /** + * Returns the lite vs pro features as an array + * + * @return array + */ + public static function getLiteVsProFeatures() + { + if (!empty(self::$liteVsProfeatures)) { + return self::$liteVsProfeatures; + } + + self::$liteVsProfeatures = array( + array( + 'title' => __('Backup Files & Database', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_FULL, + ), + array( + 'title' => __('File & Database Table Filters', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_FULL, + ), + array( + 'title' => __('Migration Wizard', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_FULL, + ), + array( + 'title' => __('Overwrite Live Site', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_FULL, + ), + array( + 'title' => __('Drag & Drop Installs', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_PARTIAL, + 'lite_text' => __('Classic WordPress-less Installs Only', 'duplicator'), + 'pro_text' => __( + 'Drag and Drop migrations and site restores! Simply drag the bundled site archive to the site you wish to overwrite.', + 'duplicator' + ) + ), + array( + 'title' => __('Scheduled Backups', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Ensure that your important data is regularly and consistently backed up, allowing for quick and efficient recovery in case of data loss.', + 'duplicator' + ) + ), + array( + 'title' => __('Recovery Points', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Recovery Points provide protection against mistakes and bad updates by letting you quickly rollback your system to a known, good state.', + 'duplicator' + ) + ), + array( + 'title' => __('Cloud Storage', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Back up to Dropbox, FTP, Google Drive, OneDrive, Amazon S3 or any S3-compatible storage service for safe storage.', + 'duplicator' + ) + ), + array( + 'title' => __('Larger Site Support', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'We\'ve developed a new way to package backups especially tailored for larger site. No server timeouts or other restrictions!', + 'duplicator' + ) + ), + array( + 'title' => __('Server-to-Server Import', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Direct Server Transfers allow you to build an archive, then directly transfer it from the source ' . + 'server to the destination server for a lightning fast migration!', + 'duplicator' + ) + ), + array( + 'title' => __('Multisite support', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Supports multisite network backup & migration. Subsite As Standalone Install, Standalone ' . + 'Import Into Multisite and Import Subsite Into Multisite', + 'duplicator' + ) + ), + array( + 'title' => __('Installer Branding', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __('Create your own custom-configured WordPress site and "Brand" the installer file with your look and feel.', 'duplicator') + ), + array( + 'title' => __('Archive Encryption', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __('Protect and secure the archive file with industry-standard AES-256 encryption!', 'duplicator') + ), + array( + 'title' => __('Advanced Backup Permissions', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Enjoy granular access control to ensure only authorized users can perform these critical functions.', + 'duplicator' + ) + ), + array( + 'title' => __('Enhanced Features', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Enhanced features include: Managed Hosting Support, Shared Database Support, Streamlined Installer, Email Alerts and more...', + 'duplicator' + ) + ), + array( + 'title' => __('Advanced Features', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'pro_text' => __( + 'Advanced features included: Hourly Schedules, Custom Search & Replace, Migrate Duplicator Settings, Regenerate Salts and Developer Hooks', + 'duplicator' + ) + ), + array( + 'title' => __('Customer Support', 'duplicator'), + 'lite_enabled' => self::LITE_ENABLED_NONE, + 'lite_text' => __('Limited Support', 'duplicator'), + 'pro_text' => __('Priority Support', 'duplicator') + ) + ); + + return self::$liteVsProfeatures; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Controllers/EmailSummaryPreviewPageController.php b/html/wp-content/plugins/duplicator/src/Controllers/EmailSummaryPreviewPageController.php new file mode 100644 index 0000000..c7e924e --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Controllers/EmailSummaryPreviewPageController.php @@ -0,0 +1,37 @@ +render('mail/email_summary', array( + 'packages' => EmailSummary::getInstance()->getPackagesInfo() + )); + die; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Controllers/HelpPageController.php b/html/wp-content/plugins/duplicator/src/Controllers/HelpPageController.php new file mode 100644 index 0000000..3efff70 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Controllers/HelpPageController.php @@ -0,0 +1,50 @@ +render( + "parts/help/main", + [ + 'tag' => $tag, + ] + ); + die; + } + + /** + * Returns link to the help page + * + * @return string + */ + public static function getHelpLink() + { + return ControllersManager::getMenuLink(self::HELP_SLUG); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Controllers/StorageController.php b/html/wp-content/plugins/duplicator/src/Controllers/StorageController.php new file mode 100644 index 0000000..00b6bbc --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Controllers/StorageController.php @@ -0,0 +1,125 @@ +render('mocks/storage/storage', array( + 'storages' => self::getStoragesData() + ), true); + } + + /** + * Fet storage alert dialog box + * + * @param string $utm_medium UTM medium for the upsell link + * + * @return DUP_UI_Dialog + */ + public static function getDialogBox($utm_medium) + { + require_once(DUPLICATOR_PLUGIN_PATH . '/classes/ui/class.ui.dialog.php'); + + $storageAlert = new DUP_UI_Dialog(); + $storageAlert->title = __('Advanced Storage', 'duplicator'); + $storageAlert->height = 600; + $storageAlert->width = 550; + $storageAlert->okText = ''; + $storageAlert->message = TplMng::getInstance()->render('mocks/storage/popup', array( + 'storages' => self::getStoragesData(), + 'utm_medium' => $utm_medium, + ), false); + $storageAlert->initAlert(); + + return $storageAlert; + } + + /** + * Returns the storage data for the view + * + * @return array[] + */ + private static function getStoragesData() + { + return array( + array( + 'title' => __('Amazon S3', 'duplicator'), + 'label' => __('Amazon S3', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/aws.svg', + ), + array( + 'title' => __('Google Drive', 'duplicator'), + 'label' => __('Google Drive', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/google-drive.svg', + ), + array( + 'title' => __('OneDrive', 'duplicator'), + 'label' => __('OneDrive', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/onedrive.svg', + ), + array( + 'title' => __('DropBox', 'duplicator'), + 'label' => __('DropBox', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/dropbox.svg', + ), + array( + 'title' => __('FTP/SFTP', 'duplicator'), + 'label' => __('FTP/SFTP', 'duplicator'), + 'fa-class' => 'fas fa-network-wired', + ), + array( + 'title' => __('Google Cloud Storage', 'duplicator'), + 'label' => __('Google Cloud Storage', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/google-cloud.svg', + ), + array( + 'title' => __('Back Blaze', 'duplicator'), + 'label' => __('Back Blaze', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/backblaze.svg', + ), + array( + 'title' => __('Cloudflare R2', 'duplicator'), + 'label' => __('Cloudflare R2', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/cloudflare.svg', + ), + array( + 'title' => __('DigitalOcean Spaces', 'duplicator'), + 'label' => __('DigitalOcean Spaces', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/digital-ocean.svg', + ), + array( + 'title' => __('Vultr Object Storage', 'duplicator'), + 'label' => __('Vultr Object Storage', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/vultr.svg', + ), + array( + 'title' => __('Dream Objects', 'duplicator'), + 'label' => __('Dream Objects', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/dreamhost.svg', + ), + array( + 'title' => __('Wasabi', 'duplicator'), + 'label' => __('Wasabi', 'duplicator'), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/wasabi.svg', + ), + array( + 'title' => __('S3-Compatible Provider', 'duplicator'), + 'label' => __( + 'S3-Compatible (Generic) Cloudian, Cloudn, Connectria, Constant, Exoscal, Eucalyptus, Nifty, Nimbula, Minio, etc...', + 'duplicator' + ), + 'iconUrl' => DUPLICATOR_PLUGIN_URL . 'assets/img/aws.svg', + ), + ); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Controllers/WelcomeController.php b/html/wp-content/plugins/duplicator/src/Controllers/WelcomeController.php new file mode 100644 index 0000000..8d7f218 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Controllers/WelcomeController.php @@ -0,0 +1,163 @@ + admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce("duplicator_enable_usage_stats"), + 'email' => wp_get_current_user()->user_email, + 'redirect_url' => ControllersManager::getMenuLink(ControllersManager::PACKAGES_SUBMENU_SLUG) + ) + ); + wp_enqueue_style('dup-font-awesome'); + wp_enqueue_script('dup-jquery-qtip'); + wp_enqueue_style('dup-plugin-style'); + wp_enqueue_style('dup-jquery-qtip'); + } + + /** + * Render welcome screen + * + * @return void + */ + public static function render() + { + TplMng::getInstance()->render('admin_pages/welcome/welcome', array(), true); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Bootstrap.php b/html/wp-content/plugins/duplicator/src/Core/Bootstrap.php new file mode 100644 index 0000000..5f0d52c --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Bootstrap.php @@ -0,0 +1,619 @@ +init(); + DUP_Settings::init(); + DUP_Log::Init(); + DUP_Util::init(); + DUP_DB::init(); + MigrationMng::init(); + Notice::init(); + NoticeBar::init(); + Review::init(); + AdminNotices::init(); + DUP_Web_Services::init(); + WelcomeController::init(); + DashboardWidget::init(); + EducationElements::init(); + Notifications::init(); + EmailSummaryPreviewPageController::init(); + HelpPageController::init(); + CrossPromotion::init(); + $dashboardService = new ServicesDashboard(); + $dashboardService->init(); + $extraPlugin = new ServicesExtraPlugins(); + $extraPlugin->init(); + $educationService = new ServicesEducation(); + $educationService->init(); + $toolsServices = new ServicesTools(); + $toolsServices->init(); + } + } + + /** + * Return admin body classes + * + * @param string $classes classes + * + * @return string + */ + public static function addBodyClass($classes) + { + if (ControllersManager::isDuplicatorPage()) { + $classes .= ' duplicator-pages'; + } + return $classes; + } + + /** + * Hooked into `plugins_loaded`. Routines used to update the plugin + * + * @return null + */ + public static function update() + { + if (DUPLICATOR_VERSION != get_option(DUP_LITE_Plugin_Upgrade::DUP_VERSION_OPT_KEY)) { + DUP_LITE_Plugin_Upgrade::onActivationAction(); + // $snapShotDirPerm = substr(sprintf("%o", fileperms(DUP_Settings::getSsdirPath())),-4); + } + load_plugin_textdomain('duplicator'); + } + + /** + * Load text domain for translation + * + * @return void + */ + public static function loadTextdomain() + { + load_plugin_textdomain('duplicator', false, false); + } + + /** + * User role editor integration + * + * @return void + */ + public static function wpfrontIntegrate() + { + if (DUP_Settings::Get('wpfront_integrate')) { + do_action('wpfront_user_role_editor_duplicator_init', array('export', 'manage_options', 'read')); + } + } + + /** + * Hooked into `admin_init`. Init routines for all admin pages + * + * @return void + */ + public static function adminInit() + { + add_action('in_admin_header', array('Duplicator\\Views\\ViewHelper', 'adminLogoHeader'), 100); + + /* CSS */ + wp_register_style('dup-jquery-ui', DUPLICATOR_PLUGIN_URL . 'assets/css/jquery-ui.css', null, "1.14.1"); + wp_register_style('dup-font-awesome', DUPLICATOR_PLUGIN_URL . 'assets/css/font-awesome/css/all.min.css', [], '6.4.2'); + wp_register_style('dup-plugin-global-style', DUPLICATOR_PLUGIN_URL . 'assets/css/global_admin_style.css', null, DUPLICATOR_VERSION); + wp_register_style('dup-plugin-style', DUPLICATOR_PLUGIN_URL . 'assets/css/style.css', array('dup-plugin-global-style'), DUPLICATOR_VERSION); + + wp_register_style('dup-jquery-qtip', DUPLICATOR_PLUGIN_URL . 'assets/js/jquery.qtip/jquery.qtip.min.css', null, '2.2.1'); + wp_register_style('dup-parsley-style', DUPLICATOR_PLUGIN_URL . 'assets/css/parsley.css', null, '2.3.5'); + /* JS */ + wp_register_script('dup-handlebars', DUPLICATOR_PLUGIN_URL . 'assets/js/handlebars.min.js', array('jquery'), '4.0.10'); + wp_register_script('dup-parsley', DUPLICATOR_PLUGIN_URL . 'assets/js/parsley.min.js', array('jquery'), '1.1.18'); + wp_register_script('dup-jquery-qtip', DUPLICATOR_PLUGIN_URL . 'assets/js/jquery.qtip/jquery.qtip.min.js', array('jquery'), '2.2.1'); + + add_action('admin_head', [DUP_UI_Screen::class, 'getCustomCss']); + // Clean tmp folder + DUP_Package::not_active_files_tmp_cleanup(); + + $unhook_third_party_js = DUP_Settings::Get('unhook_third_party_js'); + $unhook_third_party_css = DUP_Settings::Get('unhook_third_party_css'); + if ($unhook_third_party_js || $unhook_third_party_css) { + add_action('admin_enqueue_scripts', array(__CLASS__, 'unhookThirdPartyAssets'), 99999, 1); + } + } + + /** + * Hooked into `admin_menu`. Loads all of the wp left nav admin menus for Duplicator + * + * @return void + */ + public static function menuInit() + { + $menuLabel = apply_filters('duplicator_menu_label_duplicator', 'Duplicator'); + //SVG Icon: See https://websemantics.uk/tools/image-to-data-uri-converter/ + $hook_prefix = add_menu_page('Duplicator Plugin', $menuLabel, 'export', 'duplicator', null, DUP_Constants::ICON_SVG); + add_action('admin_print_scripts-' . $hook_prefix, array(__CLASS__, 'scripts')); + add_action('admin_print_styles-' . $hook_prefix, array(__CLASS__, 'styles')); + + //Submenus are displayed in the same order they have in the array + $subMenuItems = self::getSubmenuItems(); + foreach ($subMenuItems as $k => $subMenuItem) { + $pageTitle = apply_filters('duplicator_page_title_' . $subMenuItem['menu_slug'], $subMenuItem['page_title']); + $menuLabel = apply_filters('duplicator_menu_label_' . $subMenuItem['menu_slug'], $subMenuItem['menu_title']); + + $subMenuItems[$k]['hook_prefix'] = add_submenu_page( + $subMenuItem['parent_slug'], + $pageTitle, + $menuLabel, + $subMenuItem['capability'], + $subMenuItem['menu_slug'], + $subMenuItem['callback'], + $k + ); + add_action('admin_print_scripts-' . $subMenuItems[$k]['hook_prefix'], array(__CLASS__, 'scripts')); + + if (isset($subMenuItem['enqueue_style_callback'])) { + add_action('admin_print_styles-' . $subMenuItems[$k]['hook_prefix'], $subMenuItem['enqueue_style_callback']); + } + add_action('admin_print_styles-' . $subMenuItems[$k]['hook_prefix'], array(__CLASS__, 'styles')); + } + } + + /** + * Submenu datas + * + * @return array[] + */ + protected static function getSubmenuItems() + { + $proTitle = '' . __('Upgrade to Pro', 'duplicator') . ''; + $dupMenuNew = ' ' . __('NEW!', 'duplicator') . ''; + return array( + array( + 'parent_slug' => 'duplicator', + 'page_title' => __('Backups', 'duplicator'), + 'menu_title' => __('Backups', 'duplicator'), + 'capability' => 'export', + 'menu_slug' => ControllersManager::MAIN_MENU_SLUG, + 'callback' => function () { + include(DUPLICATOR_PLUGIN_PATH . 'views/packages/controller.php'); + } + ), + array( + 'parent_slug' => 'duplicator', + 'page_title' => __('Import Backups', 'duplicator'), + 'menu_title' => __('Import Backups', 'duplicator'), + 'capability' => 'export', + 'menu_slug' => ControllersManager::IMPORT_SUBMENU_SLUG, + 'callback' => function () { + TplMng::getInstance()->render('mocks/import/import'); + }, + 'enqueue_style_callback' => array(__CLASS__, 'mocksStyles') + ), + array( + 'parent_slug' => 'duplicator', + 'page_title' => __('Schedule Backups', 'duplicator'), + 'menu_title' => __('Schedule Backups', 'duplicator') . $dupMenuNew, + 'capability' => 'export', + 'menu_slug' => ControllersManager::SCHEDULES_SUBMENU_SLUG, + 'callback' => function () { + TplMng::getInstance()->render('mocks/schedule/schedules'); + }, + 'enqueue_style_callback' => array(__CLASS__, 'mocksStyles') + ), + array( + 'parent_slug' => 'duplicator', + 'page_title' => __('Storage', 'duplicator'), + 'menu_title' => '' . __('Storage', 'duplicator') . '', + 'capability' => 'export', + 'menu_slug' => ControllersManager::STORAGE_SUBMENU_SLUG, + 'callback' => array('Duplicator\\Controllers\\StorageController', 'render'), + 'enqueue_style_callback' => array(__CLASS__, 'mocksStyles') + ), + array( + 'parent_slug' => 'duplicator', + 'page_title' => __('Tools', 'duplicator'), + 'menu_title' => __('Tools', 'duplicator'), + 'capability' => 'manage_options', + 'menu_slug' => ControllersManager::TOOLS_SUBMENU_SLUG, + 'callback' => function () { + include(DUPLICATOR_PLUGIN_PATH . 'views/tools/controller.php'); + }, + 'enqueue_style_callback' => function () { + AboutUsController::enqueues(); + self::mocksStyles(); + } + ), + array( + 'parent_slug' => 'duplicator', + 'page_title' => __('Settings', 'duplicator'), + 'menu_title' => __('Settings', 'duplicator'), + 'capability' => 'manage_options', + 'menu_slug' => ControllersManager::SETTINGS_SUBMENU_SLUG, + 'callback' => function () { + include(DUPLICATOR_PLUGIN_PATH . 'views/settings/controller.php'); + } + ), + array( + 'parent_slug' => 'duplicator', + 'page_title' => __('About Duplicator', 'duplicator'), + 'menu_title' => __('About Us', 'duplicator'), + 'capability' => 'manage_options', + 'menu_slug' => ControllersManager::ABOUT_US_SUBMENU_SLUG, + 'callback' => array('Duplicator\\Controllers\\AboutUsController', 'render'), + 'enqueue_style_callback' => array('Duplicator\\Controllers\\AboutUsController', 'enqueues') + ), + array( + 'parent_slug' => 'duplicator', + 'page_title' => $proTitle, + 'menu_title' => $proTitle, + 'capability' => 'manage_options', + 'menu_slug' => LinkManager::getCampaignUrl('admin-menu', 'Upgrade to Pro'), + 'callback' => null, + ) + ); + } + + /** + * Hooked into `admin_enqueue_scripts`. Init routines for all admin pages + * + * @access global + * @return null + */ + public static function adminEqueueScripts() + { + wp_enqueue_script('dup-global-script', DUPLICATOR_PLUGIN_URL . 'assets/js/global-admin-script.js', array('jquery'), DUPLICATOR_VERSION, true); + wp_localize_script( + 'dup-global-script', + 'dup_global_script_data', + array( + 'nonce_admin_notice_to_dismiss' => wp_create_nonce('duplicator_admin_notice_to_dismiss'), + 'nonce_settings_callout_to_dismiss' => wp_create_nonce('duplicator_settings_callout_cta_dismiss'), + 'nonce_packages_bottom_bar_dismiss' => wp_create_nonce('duplicator_packages_bottom_bar_dismiss'), + 'nonce_email_subscribe' => wp_create_nonce('duplicator_email_subscribe'), + 'nonce_dashboard_widged_info' => wp_create_nonce("duplicator_dashboad_widget_info"), + 'nonce_dashboard_widged_dismiss_recommended' => wp_create_nonce("duplicator_dashboad_widget_dismiss_recommended"), + 'ajaxurl' => admin_url('admin-ajax.php') + ) + ); + wp_localize_script( + 'dup-global-script', + 'l10nDupGlobalScript', + array( + 'subscribe' => esc_html__('Subscribe', 'duplicator'), + 'subscribed' => esc_html__('Subscribed ✓', 'duplicator'), + 'subscribing' => esc_html__('Subscribing...', 'duplicator'), + 'fail' => esc_html__('Failed ✗', 'duplicator'), + 'emailFail' => esc_html__('Email subscription failed with message: ', 'duplicator'), + ) + ); + + wp_enqueue_script('dup-one-click-upgrade-script', DUPLICATOR_PLUGIN_URL . 'assets/js/one-click-upgrade.js', array('jquery'), DUPLICATOR_VERSION, true); + wp_localize_script( + 'dup-one-click-upgrade-script', + 'dup_one_click_upgrade_script_data', + array( + 'nonce_generate_connect_oth' => wp_create_nonce('duplicator_generate_connect_oth'), + 'ajaxurl' => admin_url('admin-ajax.php'), + 'fail_notice_title' => __('Failed to connect to Duplicator Pro.', 'duplicator'), + 'fail_notice_message_label' => __('Message: ', 'duplicator'), + 'fail_notice_suggestion' => __('Please try again or contact support if the issue persists.', 'duplicator'), + ) + ); + + wp_enqueue_script('dup-dynamic-help', DUPLICATOR_PLUGIN_URL . 'assets/js/dynamic-help.js', array('jquery'), DUPLICATOR_VERSION, true); + wp_localize_script( + 'dup-dynamic-help', + 'l10nDupDynamicHelp', + array( + 'failMsg' => esc_html__('Failed to load help content!', 'duplicator') + ) + ); + + wp_enqueue_script('dup-duplicator-tooltip', DUPLICATOR_PLUGIN_URL . 'assets/js/duplicator-tooltip.js', array('jquery'), DUPLICATOR_VERSION, true); + wp_localize_script( + 'dup-duplicator-tooltip', + 'l10nDupTooltip', + array( + 'copy' => esc_html__('Copy to clipboard', 'duplicator'), + 'copied' => esc_html__('copied to clipboard', 'duplicator'), + 'copyUnable' => esc_html__('Unable to copy', 'duplicator') + ) + ); + + wp_enqueue_style('dup-plugin-global-style'); + } + + /** + * Add the PRO badge to left sidebar menu item. + * + * @return void + */ + public static function adjustProMenuItemClass() + { + //Add to footer so it's applied on hovered item too + ?> + + + render('parts/plugin-footer'); + } + + /** + * Loads all required javascript libs/source for DupPro + * + * @return void + */ + public static function scripts() + { + wp_enqueue_script('jquery'); + wp_enqueue_script('jquery-ui-core'); + wp_enqueue_script('jquery-ui-progressbar'); + wp_enqueue_script('dup-parsley'); + wp_enqueue_script('dup-jquery-qtip'); + } + + /** + * Loads all CSS style libs/source for DupPro + * + * @return void + */ + public static function styles() + { + wp_enqueue_style('dup-jquery-ui'); + wp_enqueue_style('dup-font-awesome'); + wp_enqueue_style('dup-plugin-style'); + wp_enqueue_style('dup-jquery-qtip'); + } + + /** + * Enqueue mock related styles + * + * @return void + */ + public static function mocksStyles() + { + wp_enqueue_style( + 'dup-mocks-styles', + DUPLICATOR_PLUGIN_URL . 'assets/css/mocks.css', + array(), + DUPLICATOR_VERSION + ); + } + + /** + * Adds the manage link in the plugins list + * + * @param string[] $links links + * @param string $file file + * + * @return string The manage link in the plugins list + */ + public static function manageLink($links, $file) + { + static $this_plugin; + if (!$this_plugin) { + $this_plugin = plugin_basename(DUPLICATOR_LITE_FILE); + } + + if ($file == $this_plugin) { + /* + $settings_link = '
        ' . esc_html__("Manage", 'duplicator') . ''; + array_unshift($links, $settings_link); + */ + $upgrade_link = '' . + '' . + esc_html__("Upgrade to Pro", 'duplicator') . + ''; + array_unshift($links, $upgrade_link); + } + return $links; + } + + /** + * Adds links to the plugins manager page + * + * @param string[] $links links + * @param string $file file + * + * @return string The meta help link data for the plugins manager + */ + public static function metaLinks($links, $file) + { + $plugin = plugin_basename(DUPLICATOR_LITE_FILE); + // create link + if ($file == $plugin) { + $links[] = '' . + esc_html__('Manage', 'duplicator') . + ''; + return $links; + } + return $links; + } + + /** + * Remove all external styles and scripts coming from other plugins + * which may cause compatibility issue, especially with React + * + * @param string $hook hook + * + * @return void + */ + public static function unhookThirdPartyAssets($hook) + { + /* + $hook values in duplicator admin pages: + toplevel_page_duplicator + duplicator_page_duplicator-tools + duplicator_page_duplicator-settings + duplicator_page_duplicator-gopro + */ + if (strpos($hook, 'duplicator') !== false && strpos($hook, 'duplicator-pro') === false) { + $unhook_third_party_js = DUP_Settings::Get('unhook_third_party_js'); + $unhook_third_party_css = DUP_Settings::Get('unhook_third_party_css'); + $assets = array(); + if ($unhook_third_party_css) { + $assets['styles'] = wp_styles(); + } + if ($unhook_third_party_js) { + $assets['scripts'] = wp_scripts(); + } + foreach ($assets as $type => $asset) { + foreach ($asset->registered as $handle => $dep) { + $src = $dep->src; + // test if the src is coming from /wp-admin/ or /wp-includes/ or /wp-fsqm-pro/. + if ( + is_string($src) && // For some built-ins, $src is true|false + strpos($src, 'wp-admin') === false && + strpos($src, 'wp-include') === false && + // things below are specific to your plugin, so change them + strpos($src, 'duplicator') === false && + strpos($src, 'woocommerce') === false && + strpos($src, 'jetpack') === false && + strpos($src, 'debug-bar') === false + ) { + 'scripts' === $type ? wp_dequeue_script($handle) : wp_dequeue_style($handle); + } + } + } + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Controllers/ControllersManager.php b/html/wp-content/plugins/duplicator/src/Core/Controllers/ControllersManager.php new file mode 100644 index 0000000..7d4301d --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Controllers/ControllersManager.php @@ -0,0 +1,227 @@ + 'new1', + '_wpnonce' => wp_create_nonce('new1-package') + ) + ); + } + + /** + * Return package detail link + * + * @param int $packageId package id + * + * @return string + */ + public static function getPackageDetailUrl($packageId) + { + return self::getMenuLink( + self::PACKAGES_SUBMENU_SLUG, + 'detail', + null, + array( + 'action' => 'detail', + 'id' => $packageId + ) + ); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/MigrationMng.php b/html/wp-content/plugins/duplicator/src/Core/MigrationMng.php new file mode 100644 index 0000000..28a190a --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/MigrationMng.php @@ -0,0 +1,547 @@ + array(), + 'stored' => array(), + 'instFile' => array() + ); + + /** + * Init + * + * @return void + */ + public static function init() + { + add_action('admin_init', array(__CLASS__, 'adminInit')); + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, function ($migrationData) { + DUP_Util::initSnapshotDirectory(); + }); + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, array(__CLASS__, 'removeFirstLoginOption')); + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, array(__CLASS__, 'renameInstallersPhpFiles')); + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, array(__CLASS__, 'storeMigrationFiles')); + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, array(__CLASS__, 'setDupSettingsAfterInstall')); + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, array(__CLASS__, 'usageStatistics')); + // save cleanup report after actions + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, array(__CLASS__, 'saveCleanupReport'), 100); + + // LAST BEACAUSE MAKE A WP_REDIRECT + add_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, array(__CLASS__, 'autoCleanFileAfterInstall'), 99999); + } + + /** + * Admin Init function + * + * @return void + */ + public static function adminInit() + { + if (self::isFirstLoginAfterInstall()) { + add_action('current_screen', array(__CLASS__, 'wpAdminHook'), 99999); + update_option(AdminNotices::OPTION_KEY_MIGRATION_SUCCESS_NOTICE, true); + do_action(self::HOOK_FIRST_LOGIN_AFTER_INSTALL, self::getMigrationData()); + } + } + + /** + * Admin Hook function + * + * @return void + */ + public static function wpAdminHook() + { + if (!DUP_CTRL_Tools::isToolPage()) { + wp_redirect(DUP_CTRL_Tools::getDiagnosticURL(false)); + exit; + } + } + + /** + * + * @return boolean + */ + public static function isFirstLoginAfterInstall() + { + if (is_user_logged_in() && get_option(self::FIRST_LOGIN_OPTION, false)) { + if (is_multisite()) { + if (is_super_admin()) { + return true; + } + } else { + if (current_user_can('manage_options')) { + return true; + } + } + } + + return false; + } + + /** + * Purge all caches + * + * @return string[] // messages + */ + public static function purgeCaches() + { + if ( + self::getMigrationData('restoreBackupMode') || + in_array(self::getMigrationData('installType'), array(4,5,6,7)) //update with define when installerstat will be in namespace + ) { + return array(); + } + + return CachesPurge::purgeAll(); + } + + /** + * Clean after install + * + * @param array $migrationData migration data + * + * @return void + */ + public static function usageStatistics($migrationData) + { + $migrationData = (object) $migrationData; + PluginData::getInstance()->updateFromMigrateData($migrationData); + CommStats::installerSend(); + } + + /** + * + * @param array $migrationData Migration data + * + * @return void + */ + public static function autoCleanFileAfterInstall($migrationData) + { + if ($migrationData == false || $migrationData['cleanInstallerFiles'] == false) { + return; + } + + wp_redirect(DUP_CTRL_Tools::getCleanFilesAcrtionUrl(false)); + exit; + } + + /** + * + * @param array $migrationData Migration data + * + * @return void + */ + public static function setDupSettingsAfterInstall($migrationData) + { + flush_rewrite_rules(true); + } + + /** + * return cleanup report + * + * @return array + */ + public static function getCleanupReport() + { + $option = get_option(self::CLEAN_INSTALL_REPORT_OPTION); + if (is_array($option)) { + self::$migrationCleanupReport = array_merge(self::$migrationCleanupReport, $option); + } + + return self::$migrationCleanupReport; + } + + /** + * save clean up report in wordpress options + * + * @return boolean + */ + public static function saveCleanupReport() + { + return add_option(self::CLEAN_INSTALL_REPORT_OPTION, self::$migrationCleanupReport, '', 'no'); + } + + /** + * + * @param array $migrationData Migration data + * + * @return void + */ + public static function removeFirstLoginOption($migrationData) + { + delete_option(self::FIRST_LOGIN_OPTION); + } + + /** + * + * @staticvar array $migrationData + * + * @param string|null $key Key to get from migration data + * + * @return mixed + */ + public static function getMigrationData($key = null) + { + static $migrationData = null; + if (is_null($migrationData)) { + $migrationData = get_option(self::MIGRATION_DATA_OPTION, false); + if (is_string($migrationData)) { + $migrationData = json_decode($migrationData, true); + } + } + + if (is_null($key)) { + return $migrationData; + } elseif (isset($migrationData[$key])) { + return $migrationData[$key]; + } else { + return false; + } + } + + /** + * + * @return string + */ + public static function getSaveModeWarning() + { + switch (self::getMigrationData('safeMode')) { + case 1: + //safe_mode basic + return __('NOTICE: Safe mode (Basic) was enabled during install, be sure to re-enable all your plugins.', 'duplicator'); + case 2: + //safe_mode advance + return __('NOTICE: Safe mode (Advanced) was enabled during install, be sure to re-enable all your plugins.', 'duplicator'); + case 0: + default: + return ''; + } + } + + /** + * Check the root path and in case there are installer files without hashes rename them. + * + * @param integer $fileTimeDelay If the file is younger than $fileTimeDelay seconds then it is not renamed. + * + * @return void + */ + public static function renameInstallersPhpFiles($fileTimeDelay = 0) + { + $fileTimeDelay = is_numeric($fileTimeDelay) ? (int) $fileTimeDelay : 0; + + $pathsTocheck = array( + SnapIO::safePathTrailingslashit(ABSPATH), + SnapIO::safePathTrailingslashit(SnapWP::getHomePath()), + SnapIO::safePathTrailingslashit(WP_CONTENT_DIR) + ); + + $migrationData = self::getMigrationData(); + if (isset($migrationData['installerPath'])) { + $pathsTocheck[] = SnapIO::safePathTrailingslashit(dirname($migrationData['installerPath'])); + } + if (isset($migrationData['dupInstallerPath'])) { + $pathsTocheck[] = SnapIO::safePathTrailingslashit(dirname($migrationData['dupInstallerPath'])); + } + $pathsTocheck = array_unique($pathsTocheck); + + $filesToCheck = array(); + foreach ($pathsTocheck as $cFolder) { + if ( + !is_dir($cFolder) || + !is_writable($cFolder) // rename permissions + ) { + continue; + } + $cFile = $cFolder . 'installer.php'; + if ( + !is_file($cFile) || + !SnapIO::chmod($cFile, 'u+rw') || + !is_readable($cFile) + ) { + continue; + } + $filesToCheck[] = $cFile; + } + + $installerTplCheck = '/const\s+ARCHIVE_FILENAME\s*=\s*[\'"](.+?)[\'"]\s*;.*const\s+PACKAGE_HASH\s*=\s*[\'"](.+?)[\'"]\s*;/s'; + + foreach ($filesToCheck as $file) { + $fileName = basename($file); + + if ($fileTimeDelay > 0 && (time() - filemtime($file)) < $fileTimeDelay) { + continue; + } + + if (($content = @file_get_contents($file, false, null)) === false) { + continue; + } + $matches = null; + if (preg_match($installerTplCheck, $content, $matches) !== 1) { + continue; + } + + $archiveName = $matches[1]; + $hash = $matches[2]; + $matches = null; + + + if (preg_match(DUPLICATOR_ARCHIVE_REGEX_PATTERN, $archiveName, $matches) !== 1) { + if (SnapIO::unlink($file)) { + self::$migrationCleanupReport['instFile'][] = "
        " + . " " + . sprintf(__('Installer file %s removed for security reasons', 'duplicator'), esc_html($fileName)) + . "
        "; + } else { + self::$migrationCleanupReport['instFile'][] = "
        " + . ' ' + . sprintf(__('Can\'t remove installer file %s, please remove it for security reasons', 'duplicator'), esc_html($fileName)) + . '
        '; + } + continue; + } + + $archiveHash = $matches[1]; + if (strpos($file, $archiveHash) === false) { + if (SnapIO::rename($file, dirname($file) . '/' . $archiveHash . '_installer.php', true)) { + self::$migrationCleanupReport['instFile'][] = "
        " + . " " + . sprintf(__('Installer file %s renamed with HASH', 'duplicator'), esc_html($fileName)) + . "
        "; + } else { + self::$migrationCleanupReport['instFile'][] = "
        " + . ' ' + . sprintf( + __('Can\'t rename installer file %s with HASH, please remove it for security reasons', 'duplicator'), + esc_html($fileName) + ) + . '
        '; + } + } + } + } + + /** + * + * @param array $migrationData Migration data + * + * @return void + */ + public static function storeMigrationFiles($migrationData) + { + $ssdInstallerPath = DUP_Settings::getSsdirInstallerPath(); + wp_mkdir_p($ssdInstallerPath); + SnapIO::emptyDir($ssdInstallerPath); + SnapIO::createSilenceIndex($ssdInstallerPath); + + $filesToMove = array( + $migrationData['installerLog'], + $migrationData['installerBootLog'], + $migrationData['origFileFolderPath'] + ); + + foreach ($filesToMove as $path) { + if (file_exists($path)) { + if (SnapIO::rcopy($path, $ssdInstallerPath . '/' . basename($path), true)) { + self::$migrationCleanupReport['stored'] = "
        " + . " " + . __('Original files folder moved in installer backup directory', 'duplicator') . " - " . esc_html($path) . + "
        "; + } else { + self::$migrationCleanupReport['stored'] = "
        " + . ' ' + . sprintf(__('Can\'t move %s to %s', 'duplicator'), esc_html($path), $ssdInstallerPath) + . '
        '; + } + } + } + } + + /** + * + * @return array + */ + public static function getStoredMigrationLists() + { + if (($migrationData = self::getMigrationData()) == false) { + $filesToCheck = array(); + } else { + $filesToCheck = array( + $migrationData['installerLog'] => __('Installer log', 'duplicator'), + $migrationData['installerBootLog'] => __('Installer boot log', 'duplicator'), + $migrationData['origFileFolderPath'] => __('Original files folder', 'duplicator') + ); + } + + $result = array(); + + foreach ($filesToCheck as $path => $label) { + $storedPath = DUP_Settings::getSsdirInstallerPath() . '/' . basename($path); + if (!file_exists($storedPath)) { + continue; + } + $result[$storedPath] = $label; + } + + return $result; + } + + /** + * + * @return bool + */ + public static function haveFileToClean() + { + return count(self::checkInstallerFilesList()) > 0; + } + + /** + * Gets a list of all the installer files and directory by name and full path + * + * @remarks + * FILES: installer.php, installer-backup.php, dup-installer-bootlog__[HASH].txt + * DIRS: dup-installer + * Last set is for lazy developer cleanup files that a developer may have + * accidentally left around lets be proactive for the user just in case. + * + * @return [string] // [file_name] + */ + public static function getGenericInstallerFiles() + { + return array( + 'installer.php', + '[HASH]installer-backup.php', + 'dup-installer', + 'dup-installer[HASH]', + 'dup-installer-bootlog__[HASH].txt', + '[HASH]_archive.zip|daf' + ); + } + + /** + * + * @return string[] + * @throws Exception + */ + public static function checkInstallerFilesList() + { + $migrationData = self::getMigrationData(); + + $foldersToChkeck = array( + SnapIO::safePathTrailingslashit(ABSPATH), + SnapWP::getHomePath(), + ); + + $result = array(); + + if (!empty($migrationData)) { + if ( + file_exists($migrationData['archivePath']) && + !DUP_Archive::isBackupPathChild($migrationData['archivePath']) + ) { + $result[] = $migrationData['archivePath']; + } + if ( + self::isInstallerFile($migrationData['installerPath']) && + !DUP_Archive::isBackupPathChild($migrationData['archivePath']) + ) { + $result[] = $migrationData['installerPath']; + } + if (file_exists($migrationData['installerBootLog'])) { + $result[] = $migrationData['installerBootLog']; + } + if (file_exists($migrationData['dupInstallerPath'])) { + $result[] = $migrationData['dupInstallerPath']; + } + } + + foreach ($foldersToChkeck as $folder) { + $result = array_merge($result, SnapIO::regexGlob($folder, array( + 'regexFile' => array( + DUPLICATOR_ARCHIVE_REGEX_PATTERN, + DUPLICATOR_INSTALLER_REGEX_PATTERN, + DUPLICATOR_DUP_INSTALLER_BOOTLOG_REGEX_PATTERN, + DUPLICATOR_DUP_INSTALLER_OWRPARAM_REGEX_PATTERN + ), + 'regexFolder' => array( + DUPLICATOR_DUP_INSTALLER_FOLDER_REGEX_PATTERN + ) + ))); + } + + $result = array_map(array('Duplicator\\Libs\\Snap\\SnapIO', 'safePathUntrailingslashit'), $result); + return array_unique($result); + } + + /** + * @param $path string Path to check + * + * @return bool true if the file at current path is the installer file + */ + public static function isInstallerFile($path) + { + if (!is_file($path) || !is_array($last5Lines = SnapIO::getLastLinesOfFile($path, 5)) || empty($last5Lines)) { + return false; + } + + return strpos(implode("", $last5Lines), "DUPLICATOR_INSTALLER_EOF") !== false; + } + + /** + * Clear all the installer files and directory + * + * @return array + */ + public static function cleanMigrationFiles() + { + $cleanList = self::checkInstallerFilesList(); + + $result = array(); + + foreach ($cleanList as $path) { + try { + $success = (SnapIO::rrmdir($path) !== false); + } catch (Exception $ex) { + $success = false; + } catch (Error $ex) { + $success = false; + } + + $result[$path] = $success; + } + + delete_option(self::CLEAN_INSTALL_REPORT_OPTION); + + return $result; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Notifications/Notice.php b/html/wp-content/plugins/duplicator/src/Core/Notifications/Notice.php new file mode 100644 index 0000000..d8b54b9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Notifications/Notice.php @@ -0,0 +1,388 @@ + admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('duplicator-admin-notice'), + ) + ); + } + + /** + * Display the notices. + * + * @return void + */ + public static function display() + { + + $dismissed_notices = get_user_meta(get_current_user_id(), self::DISMISSED_NOTICES_OPTKEY, true); + $dismissed_notices = is_array($dismissed_notices) ? $dismissed_notices : array(); + $dismissed_notices = array_merge($dismissed_notices, (array)get_option(self::DISMISSED_NOTICES_OPTKEY, array())); + + foreach (self::$notices as $slug => $notice) { + if (isset($dismissed_notices[$slug])) { + unset(self::$notices[$slug]); + } + } + + $output = implode('', self::$notices); + + echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + // Enqueue script only when it's needed. + if (strpos($output, 'is-dismissible') !== false) { + self::enqueues(); + } + } + + /** + * Add notice to the registry. + * + * @param string $message Message to display. + * @param string $slug Unique slug identifying the notice + * @param string $type Type of the notice. Can be [ '' (default) | 'info' | 'error' | 'success' | 'warning' ]. + * @param array $args The array of additional arguments. Please see the $defaults array below. + * + * @return void + */ + public static function add($message, $slug, $type = '', $args = array()) + { + $defaults = array( + 'dismiss' => self::DISMISS_NONE, // Dismissible level: one of the self::DISMISS_* const. By default notice is not dismissible. + 'autop' => true, // `false` if not needed to pass message through wpautop(). + 'class' => '' // Additional CSS class. + ); + + $args = wp_parse_args($args, $defaults); + $dismiss = (int)$args['dismiss']; + $classes = array(); + + if (!empty($type)) { + $classes[] = 'notice-' . esc_attr(sanitize_key($type)); + } + + if (!empty($args['class'])) { + $classes[] = esc_attr(sanitize_key($args['class'])); + } + + if ($dismiss > self::DISMISS_NONE) { + $classes[] = 'is-dismissible'; + } + + $id = $dismiss === self::DISMISS_GLOBAL ? self::DEFAULT_PREFIX . self::GLOBAL_PREFIX . $slug : self::DEFAULT_PREFIX . $slug; + $message = $args['autop'] ? wpautop($message) : $message; + $notice = sprintf( + '
        %s
        ', + esc_attr(implode(' ', $classes)), + esc_attr($id), + $message + ); + + self::$notices[$slug] = $notice; + } + + /** + * Add multistep notice. + * + * @param array $steps Array of info for each step. + * @param string $slug Unique slug identifying the notice + * @param string $type Type of the notice. Can be [ '' (default) | 'info' | 'error' | 'success' | 'warning' ]. + * @param array $args Array of additional arguments. Details in the self::add() method. + * + * @return void + */ + public static function addMultistep($steps, $slug, $type = '', $args = array()) + { + $content = '
        '; + foreach ($steps as $i => $step) { + $hide = $i === 0 ? '' : ' style="display: none;"'; + $content .= '
        '; + + $content .= $step['message']; + $content .= "

        "; + foreach ($step["links"] as $link) { + $url = isset($link['url']) ? $link['url'] : "#"; + $target = isset($link['url']) ? 'target="_blank"' : ''; + $switch = isset($link['switch']) ? ' data-step="' . $link['switch'] . '"' : ''; + $dismiss = isset($link['dismiss']) && $link['dismiss'] ? ' class="dup-notice-dismiss"' : ''; + + $content .= '' . $link['text'] . '
        '; + } + $content .= "

        "; + $content .= "
        "; + } + $content .= "
        "; + + self::add($content, $slug, $type, $args); + } + + /** + * Add info notice. + * + * @param string $message Message to display. + * @param string $slug Unique slug identifying the notice + * @param array $args Array of additional arguments. Details in the self::add() method. + * + * @return void + */ + public static function info($message, $slug, $args = array()) + { + + self::add($message, $slug, self::NOTICE_TYPE_INFO, $args); + } + + /** + * Add error notice. + * + * @param string $message Message to display. + * @param string $slug Unique slug identifying the notice + * @param array $args Array of additional arguments. Details in the self::add() method. + * + * @return void + */ + public static function error($message, $slug, $args = array()) + { + + self::add($message, $slug, self::NOTICE_TYPE_ERROR, $args); + } + + /** + * Add success notice. + * + * @param string $message Message to display. + * @param string $slug Unique slug identifying the notice + * @param array $args Array of additional arguments. Details in the self::add() method. + * + * @return void + */ + public static function success($message, $slug, $args = array()) + { + + self::add($message, $slug, self::NOTICE_TYPE_SUCCESS, $args); + } + + /** + * Add warning notice. + * + * @param string $message Message to display. + * @param string $slug Unique slug identifying the notice + * @param array $args Array of additional arguments. Details in the self::add() method. + * + * @return void + */ + public static function warning($message, $slug, $args = array()) + { + + self::add($message, $slug, self::NOTICE_TYPE_WARNING, $args); + } + + /** + * AJAX routine that updates dismissed notices meta data. + * + * @return void + */ + public static function dismissAjax() + { + + // Run a security check. + check_ajax_referer('duplicator-admin-notice', 'nonce'); + + // Sanitize POST data. + $post = array_map('sanitize_key', wp_unslash($_POST)); + + // Update notices meta data. + if (strpos($post['id'], self::GLOBAL_PREFIX) !== false) { + // Check for permissions. + if (!current_user_can('manage_options')) { + wp_send_json_error(); + } + + $notices = self::dismissGlobal($post['id']); + $level = self::DISMISS_GLOBAL; + } else { + $notices = self::dismissUser($post['id']); + $level = self::DISMISS_USER; + } + + /** + * Allows developers to apply additional logic to the dismissing notice process. + * Executes after updating option or user meta (according to the notice level). + * + * @param string $notice_id Notice ID (slug). + * @param integer $level Notice level. + * @param array $notices Dismissed notices. + */ + do_action('duplicator_admin_notice_dismiss_ajax', $post['id'], $level, $notices); + + wp_send_json_success( + array( + 'id' => $post['id'], + 'time' => time(), + 'level' => $level, + 'notices' => $notices + ) + ); + } + + /** + * AJAX sub-routine that updates dismissed notices option. + * + * @param string $id Notice Id. + * + * @return array Notices. + */ + private static function dismissGlobal($id) + { + + $id = str_replace(self::GLOBAL_PREFIX, '', $id); + $notices = get_option(self::DISMISSED_NOTICES_OPTKEY, array()); + $notices[$id] = array( + 'time' => time() + ); + + update_option(self::DISMISSED_NOTICES_OPTKEY, $notices, true); + + return $notices; + } + + /** + * AJAX sub-routine that updates dismissed notices user meta. + * + * @param string $id Notice Id. + * + * @return array Notices. + */ + private static function dismissUser($id) + { + + $user_id = get_current_user_id(); + $notices = get_user_meta($user_id, self::DISMISSED_NOTICES_OPTKEY, true); + $notices = !is_array($notices) ? array() : $notices; + $notices[$id] = array( + 'time' => time() + ); + + update_user_meta($user_id, self::DISMISSED_NOTICES_OPTKEY, $notices); + + return $notices; + } + + /** + * Delete related option + * + * @return void + */ + public static function deleteOption() + { + delete_option(self::DISMISSED_NOTICES_OPTKEY); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Notifications/NoticeBar.php b/html/wp-content/plugins/duplicator/src/Core/Notifications/NoticeBar.php new file mode 100644 index 0000000..6445a5e --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Notifications/NoticeBar.php @@ -0,0 +1,81 @@ + $value) { + if (strlen((string) $value) == 0) { + continue; + } + $utm_content .= ucfirst($key) . ' ' . $value . ' '; + } + $utm_content = trim($utm_content); + + TplMng::getInstance()->render('/parts/notice-bar', array( + 'utm_content' => $utm_content + )); + } + + /** + * Dismiss notice bar ajax action + * + * @return void + */ + public static function dismissNoticeBar() + { + // Run a security check. + check_ajax_referer('duplicator-notice-bar-dismiss', 'nonce'); + update_user_meta(get_current_user_id(), self::NOTICE_BAR_DISMISSED_OPT_KEY, true); + } + + /** + * Delete related option + * + * @return bool true on success, false on failure + */ + public static function deleteOption() + { + return SnapWP::deleteUserMetaKey(self::NOTICE_BAR_DISMISSED_OPT_KEY); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Notifications/Notifications.php b/html/wp-content/plugins/duplicator/src/Core/Notifications/Notifications.php new file mode 100644 index 0000000..61b352e --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Notifications/Notifications.php @@ -0,0 +1,613 @@ +' . self::getCount() . ''; + }); + + self::update(); + + add_action(self::DUPLICATOR_BEFORE_PACKAGES_HOOK, array(__CLASS__, 'output')); + + $notificationsService = new ServicesNotifications(); + $notificationsService->init(); + } + + /** + * Check if user has access and is enabled. + * + * @return bool + */ + public static function hasAccess() + { + return current_user_can('manage_options'); + } + + /** + * Get option value. + * + * @param bool $cache Reference property cache if available. + * + * @return array + */ + public static function getOption($cache = true) + { + if (self::$option && $cache) { + return self::$option; + } + + $option = get_option(self::DUPLICATOR_NOTIFICATIONS_OPT_KEY, array()); + + self::$option = array( + 'update' => !empty($option['update']) ? (int)$option['update'] : 0, + 'feed' => !empty($option['feed']) ? (array)$option['feed'] : array(), + 'events' => !empty($option['events']) ? (array)$option['events'] : array(), + 'dismissed' => !empty($option['dismissed']) ? (array)$option['dismissed'] : array() + ); + + return self::$option; + } + + /** + * Fetch notifications from feed. + * + * @return array + */ + public static function fetchFeed() + { + $response = wp_remote_get( + self::SOURCE_URL, + array( + 'timeout' => 10, + 'user-agent' => self::getUserAgent(), + ) + ); + + if (is_wp_error($response)) { + return array(); + } + + $body = wp_remote_retrieve_body($response); + + if (empty($body)) { + return array(); + } + + return self::verify(json_decode($body, true)); + } + + /** + * Verify notification data before it is saved. + * + * @param array $notifications Array of notifications items to verify. + * + * @return array + */ + public static function verify($notifications) + { + $data = array(); + if (!is_array($notifications) || empty($notifications)) { + return $data; + } + + foreach ($notifications as $notification) { + // Ignore if one of the conditional checks is true: + // + // 1. notification message is empty. + // 2. license type does not match. + // 3. notification is expired. + // 4. notification has already been dismissed. + // 5. notification existed before installing Duplicator. + // (Prevents bombarding the user with notifications after activation). + if ( + empty($notification['content']) || + !self::isLicenseTypeMatch($notification) || + self::isExpired($notification) || + self::isDismissed($notification) || + self::isExisted($notification) + ) { + continue; + } + + $data[] = $notification; + } + + return $data; + } + + /** + * Verify saved notification data for active notifications. + * + * @param array $notifications Array of notifications items to verify. + * + * @return array + */ + public static function verifyActive($notifications) + { + if (!is_array($notifications) || empty($notifications)) { + return array(); + } + + $current_timestamp = time(); + + // Remove notifications that are not active. + foreach ($notifications as $key => $notification) { + if ( + (!empty($notification['start']) && $current_timestamp < strtotime($notification['start'])) || + (!empty($notification['end']) && $current_timestamp > strtotime($notification['end'])) + ) { + unset($notifications[$key]); + } + } + + return $notifications; + } + + /** + * Get notification data. + * + * @return array + */ + public static function get() + { + if (!self::hasAccess()) { + return array(); + } + + $option = self::getOption(); + + $feed = !empty($option['feed']) ? self::verifyActive($option['feed']) : array(); + $events = !empty($option['events']) ? self::verifyActive($option['events']) : array(); + + return array_merge($feed, $events); + } + + /** + * Get notification count. + * + * @return int + */ + public static function getCount() + { + return count(self::get()); + } + + /** + * Add a new Event Driven notification. + * + * @param array $notification Notification data. + * + * @return void + */ + public static function add($notification) + { + if (!self::isValid($notification)) { + return; + } + + $option = self::getOption(); + + // Notification ID already exists. + if (!empty($option['events'][$notification['id']])) { + return; + } + + $notification = self::verify(array($notification)); + update_option( + self::DUPLICATOR_NOTIFICATIONS_OPT_KEY, + array( + 'update' => $option['update'], + 'feed' => $option['feed'], + 'events' => array_merge($notification, $option['events']), + 'dismissed' => $option['dismissed'], + ) + ); + } + + /** + * Determine if notification data is valid. + * + * @param array $notification Notification data. + * + * @return bool + */ + public static function isValid($notification) + { + if (empty($notification['id'])) { + return false; + } + + return count(self::verify(array($notification))) > 0; + } + + /** + * Determine if notification has already been dismissed. + * + * @param array $notification Notification data. + * + * @return bool + */ + private static function isDismissed($notification) + { + $option = self::getOption(); + + return !empty($option['dismissed']) && in_array($notification['id'], $option['dismissed']); + } + + /** + * Determine if license type is match. + * + * @param array $notification Notification data. + * + * @return bool + */ + private static function isLicenseTypeMatch($notification) + { + // A specific license type is not required. + $notification['type'] = (array)$notification['type']; + if (empty($notification['type'])) { + return false; + } + + if (in_array('any', $notification['type'])) { + return true; + } + + return in_array(self::getLicenseType(), (array)$notification['type'], true); + } + + /** + * Determine if notification is expired. + * + * @param array $notification Notification data. + * + * @return bool + */ + private static function isExpired($notification) + { + return !empty($notification['end']) && time() > strtotime($notification['end']); + } + + /** + * Determine if notification existed before installing Duplicator. + * + * @param array $notification Notification data. + * + * @return bool + */ + private static function isExisted($notification) + { + $installInfo = DUP_LITE_Plugin_Upgrade::getInstallInfo(); + return (!empty($notification['start']) && $installInfo['time'] > strtotime($notification['start'])); + } + + /** + * Update notification data from feed. + * + * @return void + */ + public static function update() + { + $option = self::getOption(); + + //Only update twice daily + if ($option['update'] !== 0 && time() < $option['update'] + DAY_IN_SECONDS / 2) { + return; + } + + $data = array( + 'update' => time(), + 'feed' => self::fetchFeed(), + 'events' => $option['events'], + 'dismissed' => $option['dismissed'], + ); + + /** + * Allow changing notification data before it will be updated in database. + * + * @param array $data New notification data. + */ + $data = (array)apply_filters('duplicator_admin_notifications_update_data', $data); + + update_option(self::DUPLICATOR_NOTIFICATIONS_OPT_KEY, $data); + } + + /** + * Remove notification data from database before a plugin is deactivated. + * + * @param string $plugin Path to the plugin file relative to the plugins directory. + * + * @return void + */ + public static function delete($plugin) + { + $duplicator_plugins = array( + 'duplicator-lite/duplicator.php', + 'duplicator/duplicator.php', + ); + + if (!in_array($plugin, $duplicator_plugins, true)) { + return; + } + + delete_option(self::DUPLICATOR_NOTIFICATIONS_OPT_KEY); + } + + /** + * Enqueue assets on Form Overview admin page. + * + * @return void + */ + public static function enqueues() + { + if (!self::getCount()) { + return; + } + + wp_enqueue_style( + 'dup-admin-notifications', + DUPLICATOR_PLUGIN_URL . "assets/css/admin-notifications.css", + array('dup-lity'), + DUPLICATOR_VERSION + ); + + wp_enqueue_script( + 'dup-admin-notifications', + DUPLICATOR_PLUGIN_URL . "assets/js/notifications/admin-notifications.js", + array('jquery', 'dup-lity'), + DUPLICATOR_VERSION, + true + ); + + wp_localize_script( + 'dup-admin-notifications', + 'dup_admin_notifications', + array( + 'ajax_url' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce(self::DUPLICATOR_NOTIFICATION_NONCE_KEY), + ) + ); + + // Lity. + wp_enqueue_style( + 'dup-lity', + DUPLICATOR_PLUGIN_URL . 'assets/lib/lity/lity.min.css', + array(), + DUPLICATOR_VERSION + ); + + wp_enqueue_script( + 'dup-lity', + DUPLICATOR_PLUGIN_URL . 'assets/lib/lity/lity.min.js', + array('jquery'), + DUPLICATOR_VERSION, + true + ); + } + + /** + * Output notifications on Form Overview admin area. + * + * @return void + */ + public static function output() + { + $notificationsData = self::get(); + + if (empty($notificationsData)) { + return; + } + + + $content_allowed_tags = array( + 'br' => array(), + 'em' => array(), + 'strong' => array(), + 'span' => array( + 'style' => array() + ), + 'p' => array( + 'id' => array(), + 'class' => array() + ), + 'a' => array( + 'href' => array(), + 'target' => array(), + 'rel' => array() + ) + ); + + $notifications = array(); + foreach ($notificationsData as $notificationData) { + // Prepare required arguments. + $notificationData = wp_parse_args( + $notificationData, + array( + 'id' => 0, + 'title' => '', + 'content' => '', + 'video' => '' + ) + ); + + $title = self::getComponentData($notificationData['title']); + $content = self::getComponentData($notificationData['content']); + + if (!$title && !$content) { + continue; + } + + $notifications[] = array( + 'id' => $notificationData['id'], + 'title' => $title, + 'btns' => self::getButtonsData($notificationData), + 'content' => wp_kses(wpautop($content), $content_allowed_tags), + 'video_url' => wp_http_validate_url(self::getComponentData($notificationData['video'])), + ); + } + + self::enqueues(); + TplMng::getInstance()->render( + 'parts/Notifications/main', + array( + 'notifications' => $notifications + ) + ); + } + + /** + * Retrieve notification's buttons. + * + * @param array $notification Notification data. + * + * @return array + */ + private static function getButtonsData($notification) + { + if (empty($notification['btn']) || !is_array($notification['btn'])) { + return array(); + } + + $buttons = array(); + if (!empty($notification['btn']['main_text']) && !empty($notification['btn']['main_url'])) { + $buttons[] = array( + 'type' => 'primary', + 'text' => $notification['btn']['main_text'], + 'url' => self::prepareBtnUrl($notification['btn']['main_url']), + 'target' => '_blank' + ); + } + + if (!empty($notification['btn']['alt_text']) && !empty($notification['btn']['alt_url'])) { + $buttons[] = array( + 'type' => 'secondary', + 'text' => $notification['btn']['alt_text'], + 'url' => self::prepareBtnUrl($notification['btn']['alt_url']), + 'target' => '_blank' + ); + } + + return $buttons; + } + + /** + * Retrieve notification's component data by a license type. + * + * @param mixed $data Component data. + * + * @return false|mixed + */ + private static function getComponentData($data) + { + if (empty($data['license'])) { + return $data; + } + + $license_type = self::getLicenseType(); + return !empty($data['license'][$license_type]) ? $data['license'][$license_type] : false; + } + + /** + * Retrieve the current installation license type (always lowercase). + * + * @return string + */ + private static function getLicenseType() + { + return 'lite'; + } + + /** + * Prepare button URL. + * + * @param string $btnUrl Button url. + * + * @return string + */ + private static function prepareBtnUrl($btnUrl) + { + if (empty($btnUrl)) { + return ''; + } + + $replace_tags = array( + '{admin_url}' => admin_url() + ); + + return wp_http_validate_url(str_replace(array_keys($replace_tags), array_values($replace_tags), $btnUrl)); + } + + /** + * User agent that will be used for the request + * + * @return string + */ + private static function getUserAgent() + { + return 'WordPress/' . get_bloginfo('version') . '; ' . get_bloginfo('url') . '; Duplicator/Lite-' . DUPLICATOR_VERSION; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Notifications/Review.php b/html/wp-content/plugins/duplicator/src/Core/Notifications/Review.php new file mode 100644 index 0000000..030938c --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Notifications/Review.php @@ -0,0 +1,240 @@ + '=' , 'status' => \DUP_PackageStatus::COMPLETE ) + )); + + // Display if plugin has been installed for at least 3 days and has a package installed + if ((($installInfo['time'] + (DAY_IN_SECONDS * 3)) < time() && $numberOfPackages > 0)) { + $display = true; + } + + //Display if it's been 3 days after a successful migration + $migrationTime = MigrationMng::getMigrationData('time'); + if (!$display && $migrationTime !== false && (($migrationTime + (DAY_IN_SECONDS * 3)) < time())) { + $display = true; + } + + if (!$display) { + return; + } + + Notice::addMultistep( + array( + array( + "message" => "

        " . sprintf(__('Are you enjoying %s?', 'duplicator'), 'Duplicator') . "

        ", + "links" => array( + array( + "text" => __('Yes', 'duplicator'), + "switch" => 1 + ), + array( + "text" => __('Not really', 'duplicator'), + "switch" => 2 + ) + ) + ), + array( + "message" => "

        " . + __( + 'That’s awesome! Could you please do me a BIG favor and give it a 5-star rating on ' . + 'WordPress to help us spread the word and boost our motivation?', + 'duplicator' + ) . "

        " . + "

        " . wp_kses(__('~ John Turner
        President of Duplicator', 'duplicator'), array('br' => array())) . "

        ", + "links" => array( + array( + "url" => self::getReviewUrl(), + "text" => __('Ok, you deserve it', 'duplicator'), + "dismiss" => true + ), + array( + "text" => __('Nope, maybe later', 'duplicator'), + "dismiss" => true + ), + array( + "text" => __('I already did', 'duplicator'), + "dismiss" => true + ) + ) + ), + array( + "message" => "

        " . + __( + 'We\'re sorry to hear you aren\'t enjoying Duplicator. We would love a chance to improve. ' . + 'Could you take a minute and let us know what we can do better?', + 'duplicator' + ) . "

        ", + "links" => array( + array( + "url" => self::getFeedbackUrl(), + "text" => __('Give Feedback', 'duplicator'), + "dismiss" => true + ), + array( + "text" => __('No thanks', 'duplicator'), + "dismiss" => true + ) + ) + ) + ), + self::REVIEW_REQUEST_NOTICE_SLUG, + Notice::NOTICE_TYPE_INFO, + array( + 'dismiss' => Notice::DISMISS_GLOBAL, + 'autop' => false, + 'class' => 'dup-review-notice', + ) + ); + } + + /** + * @return string The review url on wordpress.org + */ + public static function getReviewUrl() + { + return "https://wordpress.org/support/plugin/duplicator/reviews/#new-post"; + } + + /** + * @return string The snapcreek feedback url + */ + public static function getFeedbackUrl() + { + return DUPLICATOR_BLOG_URL . "contact/"; + } + + /** + * Updates admin footer text by adding Duplicator version + * + * @param string $defaultText Default WP footer text + * + * @return string Modified version text + */ + public static function adminFooterVersion($defaultText) + { + if (!ControllersManager::isDuplicatorPage()) { + return $defaultText; + } + + $defaultText = sprintf( + '%1$s | Duplicator %2$s', + $defaultText, + esc_html(DUPLICATOR_VERSION) + ); + + return $defaultText; + } + + /** + * When user is on a Duplicator related admin page, display footer text + * that graciously asks them to rate us. + * + * @param string $text Footer text. + * + * @return string + */ + public static function adminFooter($text) + { + //Show only on duplicator pages + if ( + ! is_admin() || + empty($_REQUEST['page']) || + strpos($_REQUEST['page'], 'duplicator') === false + ) { + return false; + } + + $text = sprintf( + wp_kses( /* translators: $1$s - WPForms plugin name; $2$s - WP.org review link; $3$s - WP.org review link. */ + __( + 'Please rate Duplicator ' . + '★★★★★' . + ' on WordPress.org to help us spread the word. Thank you from the Duplicator team!', + 'duplicator' + ), + array( + 'a' => array( + 'href' => array(), + 'target' => array(), + 'rel' => array(), + ), + 'strong' => array() + ) + ), + self::getReviewUrl() + ); + + return $text; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Unistall.php b/html/wp-content/plugins/duplicator/src/Core/Unistall.php new file mode 100644 index 0000000..522aea4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Unistall.php @@ -0,0 +1,42 @@ +')) { + return; + } + + if (($data = get_option(EmailSummary::INFO_OPT_OLD_KEY)) !== false) { + update_option(EmailSummary::INFO_OPT_KEY, $data); + delete_option(EmailSummary::INFO_OPT_OLD_KEY); + } + } + + /** + * Update storage position option + * + * @param false|string $currentVersion current Duplicator version, false if is first installation + * + * @return void + */ + private static function updateStoragePostition($currentVersion): void + { + //PRE 1.3.35 + //Do not update to new wp-content storage till after + if ($currentVersion !== false && version_compare($currentVersion, self::FIRST_VERSION_NEW_STORAGE_POSITION, '<')) { + DUP_Settings::Set('storage_position', DUP_Settings::STORAGE_POSITION_LEGACY); + } + } + + /** + * Migrate storage folders from legacy to new location + * + * @param false|string $currentVersion current Duplicator version, false if first install + * + * @return void + */ + private static function migrateStorageFolders($currentVersion): void + { + // Skip on fresh installs or if already past migration version + if ($currentVersion === false || version_compare($currentVersion, self::FIRST_VERSION_FOLDER_MIGRATION, '>=')) { + return; + } + + // If storage position is already set to new, do not migrate + if (DUP_Settings::Get('storage_position') === DUP_Settings::STORAGE_POSITION_WP_CONTENT) { + return; + } + + // Force using wp-content storage position + DUP_Settings::setStoragePosition(DUP_Settings::STORAGE_POSITION_WP_CONTENT); + DUP_Settings::Save(); + } + + /** + * Migrate existing log files from root directory to logs subfolder + * + * @param false|string $currentVersion current Duplicator version, false if is first installation + * + * @return void + */ + private static function migrateLogsToSubfolder($currentVersion): void + { + if ($currentVersion === false || version_compare($currentVersion, self::FIRST_VERSION_WITH_LOGS_SUBFOLDER, '>=')) { + return; + } + + try { + DUP_Log::Trace("MIGRATION: Moving log files to logs subfolder"); + + // Ensure logs directory exists + if (!file_exists(DUP_Settings::getSsdirLogsPath())) { + SnapIO::dirWriteCheckOrMkdir(DUP_Settings::getSsdirLogsPath(), 'u+rwx'); + } + + // Use SnapIO::regexGlob for more robust file discovery + $logFiles = SnapIO::regexGlob(DUP_Settings::getSsdirPath(), [ + 'regexFile' => [ + '/.*\.log$/', + '/.*\.log1$/', + ], + 'regexFolder' => false, + 'recursive' => false, + ]); + + $migratedCount = 0; + foreach ($logFiles as $oldPath) { + $filename = basename($oldPath); + $newPath = DUP_Settings::getSsdirLogsPath() . '/' . $filename; + + if (SnapIO::rename($oldPath, $newPath)) { + $migratedCount++; + } + } + + DUP_Log::Trace("MIGRATION: Moved {$migratedCount} log files to logs subfolder - old location is now clean"); + } catch (Exception $e) { + DUP_Log::Trace("MIGRATION: Error moving log files: " . $e->getMessage()); + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Core/Views/TplMng.php b/html/wp-content/plugins/duplicator/src/Core/Views/TplMng.php new file mode 100644 index 0000000..08720c8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Core/Views/TplMng.php @@ -0,0 +1,244 @@ +mainFolder = DUPLICATOR_PLUGIN_PATH . '/template/'; + } + + /** + * If strip spaces is true in render method spaced between tag are removed + * + * @param bool $strip if true strip spaces + * + * @return void + */ + public static function setStripSpaces($strip) + { + self::$stripSpaces = (bool) $strip; + } + + /** + * Set template global value in template data + * + * @param string $key global value key + * @param mixed $val value + * + * @return void + */ + public function setGlobalValue($key, $val) + { + $this->globalData[$key] = $val; + } + + /** + * Remove global value if exist + * + * @param string $key gloval value key + * + * @return void + */ + public function unsetGlobalValue($key) + { + if (isset($this->globalData[$key])) { + unset($this->globalData[$key]); + } + } + + /** + * Return true if global values exists + * + * @param string $key gloval value key + * + * @return bool + */ + public function hasGlobalValue($key) + { + return isset($this->globalData[$key]); + } + + /** + * Multiple global data set + * + * @param array $data data tu set in global data + * + * @return void + */ + public function updateGlobalData(array $data = array()) + { + $this->globalData = array_merge($this->globalData, (array) $data); + } + + /** + * Return global data + * + * @return array + */ + public function getGlobalData() + { + return $this->globalData; + } + + /** + * Render template + * + * @param string $slugTpl template file is a relative path from root template folder + * @param array $args array key / val where key is the var name in template + * @param bool $echo if false return template in string + * + * @return string + */ + public function render($slugTpl, $args = array(), $echo = true) + { + ob_start(); + if (($renderFile = $this->getFileTemplate($slugTpl)) !== false) { + $tplData = apply_filters(self::getDataHook($slugTpl), array_merge($this->globalData, $args)); + $tplMng = $this; + require($renderFile); + } else { + echo '

        FILE TPL NOT FOUND: ' . $slugTpl . '

        '; + } + $renderResult = apply_filters(self::getRenderHook($slugTpl), ob_get_clean()); + + if (self::$stripSpaces) { + $renderResult = preg_replace('~>[\n\s]+<~', '><', $renderResult); + } + if ($echo) { + echo $renderResult; + return ''; + } else { + return $renderResult; + } + } + + /** + * Render template in json string + * + * @param string $slugTpl template file is a relative path from root template folder + * @param array $args array key / val where key is the var name in template + * @param bool $echo if false return template in string + * + * @return string + */ + public function renderJson($slugTpl, $args = array(), $echo = true) + { + $renderResult = SnapJson::jsonEncode($this->render($slugTpl, $args, false)); + if ($echo) { + echo $renderResult; + return ''; + } else { + return $renderResult; + } + } + + /** + * Render template apply esc attr + * + * @param string $slugTpl template file is a relative path from root template folder + * @param array $args array key / val where key is the var name in template + * @param bool $echo if false return template in string + * + * @return string + */ + public function renderEscAttr($slugTpl, $args = array(), $echo = true) + { + $renderResult = esc_attr($this->render($slugTpl, $args, false)); + if ($echo) { + echo $renderResult; + return ''; + } else { + return $renderResult; + } + } + + /** + * Get hook unique from template slug + * + * @param string $slugTpl template slug + * + * @return string + */ + public static function tplFileToHookSlug($slugTpl) + { + return str_replace(array('\\', '/', '.'), '_', $slugTpl); + } + + /** + * Return data hook from template slug + * + * @param string $slugTpl template slug + * + * @return string + */ + public static function getDataHook($slugTpl) + { + return 'duplicator_template_data_' . self::tplFileToHookSlug($slugTpl); + } + + /** + * Return render hook from template slug + * + * @param string $slugTpl template slug + * + * @return string + */ + public static function getRenderHook($slugTpl) + { + return 'duplicator_template_render_' . self::tplFileToHookSlug($slugTpl); + } + + /** + * Acctept html of php extensions. if the file have unknown extension automatic add the php extension + * + * @param string $slugTpl template slug + * + * @return boolean|string return false if don\'t find the template file + */ + protected function getFileTemplate($slugTpl) + { + $fullPath = $this->mainFolder . $slugTpl . '.php'; + + if (file_exists($fullPath)) { + return $fullPath; + } else { + return false; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Certificates/cacert.pem b/html/wp-content/plugins/duplicator/src/Libs/Certificates/cacert.pem new file mode 100644 index 0000000..0bf312f --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Certificates/cacert.pem @@ -0,0 +1,3232 @@ +## +## Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Tue Oct 26 03:12:05 2021 GMT +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## +## Conversion done with mk-ca-bundle.pl version 1.28. +## SHA256: bb36818a81feaa4cca61101e6d6276cd09e972efcb08112dfed846918ca41d7f +## + + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ +KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy +T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT +J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e +nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx +ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6 +XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk +lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB +lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy +lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt +66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn +wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh +D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy +BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie +J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud +DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU +a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv +Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3 +UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm +VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK ++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW +IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1 +WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X +f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II +4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8 +VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT +EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx +OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg +DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij +KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K +DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv +BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp +p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8 +nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX +MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM +Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz +uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT +BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj +YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB +BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD +VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4 +ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE +AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV +qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s +hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z +POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2 +Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp +8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC +bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu +g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p +vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr +qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw +EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN +MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp +c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq +t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C +jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg +vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF +ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR +AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend +jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO +peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR +7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi +GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64 +OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm +5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr +44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf +Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m +Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp +mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk +vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf +KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br +NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj +viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT +BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X +DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3 +aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644 +N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm ++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH +6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu +MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h +qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5 +FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs +ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc +celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X +CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB +tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P +4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F +kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L +3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx +/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa +DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP +e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu +WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ +DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub +DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +======================================== +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG +EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz +MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu +QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ +03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK +ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU ++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC +PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT +OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK +F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK +0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+ +0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB +leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID +AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+ +SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG +NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l +Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga +kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q +hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs +g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5 +aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5 +nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC +ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo +Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z +WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2011 +======================================================= +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT +O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y +aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT +AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo +IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI +1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa +71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u +8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH +3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 +MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu +b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt +XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD +/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N +7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe +Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE +LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD +ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA +BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv +KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z +p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC +AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ +4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y +eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw +MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G +PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw +OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm +2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV +dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph +X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +D-TRUST Root Class 3 CA 2 EV 2009 +================================= +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK +DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw +OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS +egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh +zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T +7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 +sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 +11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv +cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v +ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El +MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp +b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh +c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ +PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX +ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA +NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv +w9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +CA Disig Root R2 +================ +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw +EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp +ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx +EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp +c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC +w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia +xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 +A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S +GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV +g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa +5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE +koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A +Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i +Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u +Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV +sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je +dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 +1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx +mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 +utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 +sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg +UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV +7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +ACCVRAIZ1 +========= +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB +SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 +MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH +UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM +jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 +RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD +aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ +0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG +WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 +8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR +5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J +9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK +Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw +Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu +Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM +Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA +QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh +AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA +YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj +AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA +IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk +aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 +dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 +MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI +hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E +R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN +YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 +nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ +TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 +sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg +Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd +3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p +EfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +TWCA Global Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT +CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD +QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK +EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C +nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV +r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR +Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV +tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W +KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 +sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p +yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn +kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI +zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g +cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M +8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg +/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg +lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP +A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m +i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 +EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 +zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= +-----END CERTIFICATE----- + +TeliaSonera Root CA v1 +====================== +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE +CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 +MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW +VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ +6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA +3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k +B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn +Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH +oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 +F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ +oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 +gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc +TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB +AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW +DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm +zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW +pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV +G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc +c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT +JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 +qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 +Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems +WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +E-Tugra Certification Authority +=============================== +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w +DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls +ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw +NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx +QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl +cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD +DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd +hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K +CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g +ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ +BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0 +E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz +rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq +jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5 +dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK +kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO +XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807 +VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo +a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc +dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV +KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT +Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0 +8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G +C7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 2 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx +MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ +SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F +vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 +2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV +WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy +YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 +r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf +vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR +3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== +-----END CERTIFICATE----- + +Atos TrustedRoot 2011 +===================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU +cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 +MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG +A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV +hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr +54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ +DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 +HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR +z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R +l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ +bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h +k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh +TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 +61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G +3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +QuoVadis Root CA 1 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE +PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm +PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 +Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN +ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l +g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV +7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX +9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f +iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg +t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI +hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 +GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct +Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP ++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh +3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa +wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 +O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 +FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV +hMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +QuoVadis Root CA 2 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh +ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY +NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t +oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o +MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l +V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo +L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ +sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD +6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh +lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI +hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K +pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 +x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz +dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X +U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw +mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD +zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN +JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr +O3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +QuoVadis Root CA 3 G3 +===================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG +A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv +b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN +MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg +RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 +IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL +Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe +6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 +I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U +VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 +5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi +Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM +dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt +rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI +hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS +t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ +TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du +DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib +Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD +hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX +0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW +dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 +PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +DigiCert Assured ID Root G2 +=========================== +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw +MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH +35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq +bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw +VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP +YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn +lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO +w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv +0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz +d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW +hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M +jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +DigiCert Assured ID Root G3 +=========================== +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD +VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb +RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs +KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF +UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy +YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy +1vUhZscv6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +DigiCert Global Root G2 +======================= +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx +MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ +kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO +3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV +BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM +UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB +o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu +5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr +F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U +WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH +QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ +iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +DigiCert Global Root G3 +======================= +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD +VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw +MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k +aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C +AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O +YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp +Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y +3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 +VOKa5Vt8sycX +-----END CERTIFICATE----- + +DigiCert Trusted Root G4 +======================== +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw +HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 +MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp +pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o +k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa +vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 +MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm +mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 +f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH +dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 +oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY +ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr +yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy +7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah +ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN +5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb +/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa +5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK +G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP +82Z+ +-----END CERTIFICATE----- + +COMODO RSA Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- + +USERTrust RSA Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE +BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK +ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz +0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j +Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn +RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O ++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq +/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE +Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM +lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8 +yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+ +eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW +FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ +7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ +Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM +8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi +FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi +yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c +J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw +sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx +Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +USERTrust ECC Certification Authority +===================================== +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC +VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 +0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez +nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV +HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB +HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu +9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R4 +=========================== +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl +OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV +MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF +JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q= +-----END CERTIFICATE----- + +GlobalSign ECC Root CA - R5 +=========================== +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb +R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD +EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 +SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS +h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx +uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 +yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +Staat der Nederlanden EV Root CA +================================ +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M +MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl +cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk +SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW +O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r +0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8 +Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV +XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr +08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV +0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd +74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx +fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa +ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu +c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq +5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN +b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN +f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi +5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4 +WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK +DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy +eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg== +-----END CERTIFICATE----- + +IdenTrust Commercial Root CA 1 +============================== +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS +b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES +MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB +IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld +hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ +mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi +1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C +XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl +3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy +NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV +WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg +xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix +uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI +hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg +ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt +ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV +YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX +feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro +kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe +2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz +Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R +cGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +IdenTrust Public Sector Root CA 1 +================================= +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG +EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv +ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV +UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS +b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy +P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 +Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI +rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf +qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS +mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn +ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh +LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v +iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL +4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B +Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw +DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A +mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt +GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt +m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx +NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 +Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI +ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC +ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ +3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy +bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug +b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw +HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT +DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx +OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP +/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz +HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU +s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y +TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx +AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 +0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z +iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi +nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ +vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO +e4pIb4tF9g== +-----END CERTIFICATE----- + +Entrust Root Certification Authority - EC1 +========================================== +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx +FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn +YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw +FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs +LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg +dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt +IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy +AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef +9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h +vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 +kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +CFCA EV ROOT +============ +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE +CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB +IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw +MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD +DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV +BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD +7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN +uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW +ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 +xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f +py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K +gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol +hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ +tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf +BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q +ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua +4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG +E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX +BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn +aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy +PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX +kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C +ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GB CA +=============================== +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG +EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw +MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds +b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX +scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP +rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk +9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o +Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg +GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI +hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD +dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 +VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui +HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +SZAFIR ROOT CA2 +=============== +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG +A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV +BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ +BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD +VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q +qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK +DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE +2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ +ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi +ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P +AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC +AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 +O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 +oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul +4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 ++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +Certum Trusted Network CA 2 +=========================== +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE +BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 +bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y +ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ +TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB +IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 +7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o +CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b +Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p +uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 +GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ +9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB +Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye +hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM +BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI +hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW +Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA +L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo +clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM +pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb +w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo +J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm +ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX +is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 +zAYspsbiDrW5viSP +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2015 +======================================================= +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT +BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 +aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx +MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg +QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV +BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw +MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv +bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh +iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ +6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd +FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr +i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F +GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 +fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu +iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI +hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ +D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM +d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y +d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn +82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb +davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F +Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt +J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa +JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q +p/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions ECC RootCA 2015 +=========================================================== +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 +aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw +MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj +IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD +VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 +Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP +dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK +Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O +BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA +GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn +dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +ISRG Root X1 +============ +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE +BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD +EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG +EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT +DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r +Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 +3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K +b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN +Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ +4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf +1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu +hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH +usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r +OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY +9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV +0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt +hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw +TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx +e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA +JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD +YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n +JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ +m+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM +================ +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT +AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw +MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD +TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf +qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr +btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL +j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou +08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw +WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT +tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ +47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC +ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa +i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o +dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s +D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ +j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT +Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW ++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 +Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d +8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm +5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG +rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +Amazon Root CA 1 +================ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 +MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH +FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ +gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t +dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce +VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 +DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM +CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy +8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa +2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 +xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +Amazon Root CA 2 +================ +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD +VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 +MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv +bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 +kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp +N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 +AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd +fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx +kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS +btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 +Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN +c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ +3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw +DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA +A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE +YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW +xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ +gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW +aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV +Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 +KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi +JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= +-----END CERTIFICATE----- + +Amazon Root CA 3 +================ +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB +f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr +Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 +rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc +eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +Amazon Root CA 4 +================ +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG +EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy +NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ +MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN +/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri +83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA +MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 +AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT +D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr +IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g +TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp +ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD +VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt +c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth +bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 +IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 +6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc +wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 +3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 +WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU +ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc +lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R +e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j +q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +GDCA TrustAUTH R5 ROOT +====================== +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw +BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD +DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow +YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs +AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p +OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr +pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ +9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ +xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM +R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ +D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4 +oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx +9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9 +H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35 +6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd ++PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ +HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD +F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ +8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv +/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT +aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +TrustCor RootCert CA-1 +====================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYDVQQGEwJQQTEP +MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig +U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkx +MjMxMTcyMzE2WjCBpDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFu +YW1hIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUGA1UECwwe +VHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZUcnVzdENvciBSb290Q2Vy +dCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv463leLCJhJrMxnHQFgKq1mq +jQCj/IDHUHuO1CAmujIS2CNUSSUQIpidRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4 +pQa81QBeCQryJ3pS/C3Vseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0 +JEsq1pme9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CVEY4h +gLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorWhnAbJN7+KIor0Gqw +/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/DeOxCbeKyKsZn3MzUOcwHwYDVR0j +BBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwDQYJKoZIhvcNAQELBQADggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5 +mDo4Nvu7Zp5I/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZyonnMlo2HD6C +qFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djtsL1Ac59v2Z3kf9YKVmgenFK+P +3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdNzl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- + +TrustCor RootCert CA-2 +====================== +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNVBAYTAlBBMQ8w +DQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQwIgYDVQQKDBtUcnVzdENvciBT +eXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0 +eTEfMB0GA1UEAwwWVHJ1c3RDb3IgUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEy +MzExNzI2MzlaMIGkMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5h +bWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29yIFJvb3RDZXJ0 +IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnIG7CKqJiJJWQdsg4foDSq8Gb +ZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9Nk +RvRUqdw6VC0xK5mC8tkq1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1 +oYxOdqHp2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nKDOOb +XUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hapeaz6LMvYHL1cEksr1 +/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF3wP+TfSvPd9cW436cOGlfifHhi5q +jxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQP +eSghYA2FFn3XVDjxklb9tTNMg9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+Ctg +rKAmrhQhJ8Z3mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAdBgNVHQ4EFgQU +2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6UnrybPZx9mCAZ5YwwYrIwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/h +Osh80QA9z+LqBrWyOrsGS2h60COXdKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnp +kpfbsEZC89NiqpX+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv +2wnL/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RXCI/hOWB3 +S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYaZH9bDTMJBzN7Bj8RpFxw +PIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dv +DDqPys/cA8GiCcjl/YBeyGBCARsaU1q7N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYU +RpFHmygk71dSTlxCnKr3Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANE +xdqtvArBAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp5KeX +RKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu1uwJ +-----END CERTIFICATE----- + +TrustCor ECA-1 +============== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYDVQQGEwJQQTEP +MA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3Ig +U3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkxFzAVBgNVBAMMDlRydXN0Q29yIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3Mjgw +N1owgZwxCzAJBgNVBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5 +MSQwIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRydXN0Q29y +IENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3IgRUNBLTEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb3w9U73NjKYKtR8aja+3+XzP4Q1HpGjOR +MRegdMTUpwHmspI+ap3tDvl0mEDTPwOABoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23 +xFUfJ3zSCNV2HykVh0A53ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmc +p0yJF4OuowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/wZ0+ +fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZFZtS6mFjBAgMBAAGj +YzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAfBgNVHSMEGDAWgBREnkj1zG1I1KBL +f/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF +AAOCAQEABT41XBVwm8nHc2FvcivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u +/ukZMjgDfxT2AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50soIipX1TH0Xs +J5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BIWJZpTdwHjFGTot+fDz2LYLSC +jaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1WitJ/X5g== +-----END CERTIFICATE----- + +SSL.com Root Certification Authority RSA +======================================== +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM +BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x +MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw +MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx +EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM +LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C +Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8 +P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge +oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp +k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z +fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ +gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2 +UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8 +1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s +bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr +dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf +ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl +u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq +erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj +MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ +vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI +Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y +wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI +WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +SSL.com Root Certification Authority ECC +======================================== +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV +BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv +BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy +MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO +BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+ +8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR +hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT +jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW +e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z +5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +SSL.com EV Root Certification Authority RSA R2 +============================================== +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w +DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u +MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI +DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD +VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh +hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w +cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO +Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+ +B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh +CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim +9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto +RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm +JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48 ++qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp +qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1 +++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx +Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G +guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz +OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7 +CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq +lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR +rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1 +hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX +9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +SSL.com EV Root Certification Authority ECC +=========================================== +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV +BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy +BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw +MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx +EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM +LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy +3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O +BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe +5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ +N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm +m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +GlobalSign Root CA - R6 +======================= +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX +R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds +b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i +YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs +U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss +grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE +3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF +vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM +PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+ +azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O +WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy +CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP +0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN +b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE +AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV +HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0 +lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY +BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym +Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr +3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1 +0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T +uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK +oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t +JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GC CA +=============================== +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD +SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo +MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa +Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL +ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr +VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab +NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E +AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk +AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +GTS Root R1 +=========== +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG +EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv +b3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG +A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx +9vaMf/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7r +aKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnW +r4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqM +LnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly +4cpk9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr +06zqkUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om +3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNu +JLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEM +BQADggIBADiWCu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 +d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6ZXPYfcX3v73sv +fuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZRgyFmxhE+885H7pwoHyXa/6xm +ld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9b +gsiG1eGZbYwE8na6SfZu6W0eX6DvJ4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq +4BjFbkerQUIpm/ZgDdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWEr +tXvM+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyyF62ARPBo +pY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9SQ98POyDGCBDTtWTurQ0 +sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdwsE3PYJ/HQcu51OyLemGhmW/HGY0dVHLql +CFF1pkgl +-----END CERTIFICATE----- + +GTS Root R2 +=========== +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQG +EwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJv +b3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAG +A1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTuk +k3LvCvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo +7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWI +m8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5Gm +dFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbu +ak7MkogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscsz +cTJGr61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73Vululycsl +aVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy +5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEM +BQADggIBALZp8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT +vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiTz9D2PGcDFWEJ ++YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiApJiS4wGWAqoC7o87xdFtCjMw +c3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvbpxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3Da +WsYDQvTtN6LwG1BUSw7YhN4ZKJmBR64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5r +n/WkhLx3+WuXrD5RRaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56Gtmwfu +Nmsk0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC5AwiWVIQ +7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiFizoHCBy69Y9Vmhh1fuXs +gWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLnyOd/xCxgXS/Dr55FBcOEArf9LAhST4Ld +o/DUhgkC +-----END CERTIFICATE----- + +GTS Root R3 +=========== +-----BEGIN CERTIFICATE----- +MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV +UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg +UjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE +ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUU +Rout736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24Cej +QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP +0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFukfCPAlaUs3L6JbyO5o91lAFJekazInXJ0 +glMLfalAvWhgxeG4VDvBNhcl2MG9AjEAnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOa +KaqW04MjyaR7YbPMAuhd +-----END CERTIFICATE----- + +GTS Root R4 +=========== +-----BEGIN CERTIFICATE----- +MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJV +UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg +UjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE +ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa +6zzuhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqj +QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV +2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0CMRw3J5QdCHojXohw0+WbhXRIjVhLfoI +N+4Zba3bssx9BzT1YBkstTTZbyACMANxsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11x +zPKwTdb+mciUqXWi4w== +-----END CERTIFICATE----- + +UCA Global G2 Root +================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG +EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x +NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU +cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT +oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV +8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS +h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o +LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/ +R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe +KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa +4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc +OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97 +8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo +5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A +Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9 +yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX +c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo +jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk +bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x +ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn +RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A== +-----END CERTIFICATE----- + +UCA Extended Validation Root +============================ +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG +EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u +IFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G +A1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs +iWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF +Rv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu +eUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR +59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH +0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR +el7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv +B0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth +WG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS +NwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS +3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL +BQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM +aVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4 +dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb ++7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW +F3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi +GpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc +GMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi +djzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr +dhh2n1ax +-----END CERTIFICATE----- + +Certigna Root CA +================ +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE +BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ +MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda +MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz +MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX +stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz +KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8 +JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16 +XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq +4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej +wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ +lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI +jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/ +/TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy +dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h +LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl +cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt +OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP +TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq +7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3 +4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd +8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS +6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY +tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS +aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde +E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +emSign Root CA - G1 +=================== +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET +MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl +ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx +ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk +aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN +LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1 +cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW +DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ +6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH +hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2 +vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q +NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q ++Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih +U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +emSign ECC Root CA - G3 +======================= +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG +A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg +MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4 +MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11 +ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc +58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr +MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC +AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D +CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7 +jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +emSign Root CA - C1 +=================== +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx +EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp +Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD +ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up +ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/ +Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX +OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V +I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms +lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+ +XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp +/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1 +NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9 +wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ +BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +emSign ECC Root CA - C3 +======================= +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG +A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF +Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE +BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD +ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd +6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9 +SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA +B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA +MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU +ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +Hongkong Post Root CA 3 +======================= +-----BEGIN CERTIFICATE----- +MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQELBQAwbzELMAkG +A1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJSG9uZyBLb25nMRYwFAYDVQQK +Ew1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2 +MDMwMjI5NDZaFw00MjA2MDMwMjI5NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtv +bmcxEjAQBgNVBAcTCUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMX +SG9uZ2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz +iNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFOdem1p+/l6TWZ5Mwc50tf +jTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mIVoBc+L0sPOFMV4i707mV78vH9toxdCim +5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOe +sL4jpNrcyCse2m5FHomY2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj +0mRiikKYvLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+TtbNe/ +JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZbx39ri1UbSsUgYT2u +y1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+l2oBlKN8W4UdKjk60FSh0Tlxnf0h ++bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YKTE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsG +xVd7GYYKecsAyVKvQv83j+GjHno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwID +AQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e +i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEwDQYJKoZIhvcN +AQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG7BJ8dNVI0lkUmcDrudHr9Egw +W62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCkMpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWld +y8joRTnU+kLBEUx3XZL7av9YROXrgZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov ++BS5gLNdTaqX4fnkGMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDc +eqFS3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJmOzj/2ZQw +9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+l6mc1X5VTMbeRRAc6uk7 +nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6cJfTzPV4e0hz5sy229zdcxsshTrD3mUcY +hcErulWuBurQB7Lcq9CClnXO0lD+mefPL5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB +60PZ2Pierc+xYw5F9KBaLJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fq +dBb9HxEGmpv0 +-----END CERTIFICATE----- + +Entrust Root Certification Authority - G4 +========================================= +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAwgb4xCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3Qu +bmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1 +dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eSAtIEc0MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYT +AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3D +umSXbcr3DbVZwbPLqGgZ2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV +3imz/f3ET+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j5pds +8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAMC1rlLAHGVK/XqsEQ +e9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73TDtTUXm6Hnmo9RR3RXRv06QqsYJn7 +ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNXwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5X +xNMhIWNlUpEbsZmOeX7m640A2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV +7rtNOzK+mndmnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwlN4y6mACXi0mW +Hv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNjc0kCAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9n +MA0GCSqGSIb3DQEBCwUAA4ICAQAS5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4Q +jbRaZIxowLByQzTSGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht +7LGrhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/B7NTeLUK +YvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uIAeV8KEsD+UmDfLJ/fOPt +jqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbwH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+ +m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKW +RGhXxNUzzxkvFMSUHHuk2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjA +JOgc47OlIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk5F6G ++TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuYn/PIjhs4ViFqUZPT +kcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +Microsoft ECC Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND +IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4 +MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6 +thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB +eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM ++Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf +Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR +eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +Microsoft RSA Root Certificate Authority 2017 +============================================= +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg +UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw +NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u +MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml +7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e +S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7 +1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+ +dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F +yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS +MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr +lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ +0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ +ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og +6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80 +dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk ++ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex +/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy +AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW +ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE +7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT +c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D +5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +e-Szigno Root CA 2017 +===================== +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw +DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt +MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa +Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE +CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp +Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx +s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G +A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv +vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA +tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO +svxyqltZ+efcMQ== +-----END CERTIFICATE----- + +certSIGN Root CA G2 +=================== +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw +EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy +MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH +TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05 +N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk +abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg +wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp +dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh +ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732 +jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf +95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc +z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL +iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud +DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB +ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB +/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5 +8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5 +BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW +atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU +Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M +NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N +0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +Trustwave Global Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV +UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 +ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0xNzA4MjMxOTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJV +UzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2 +ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALldUShLPDeS0YLOvR29 +zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0XznswuvCAAJWX/NKSqIk4cXGIDtiLK0thAf +LdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4Bq +stTnoApTAbqOl5F2brz81Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9o +WN0EACyW80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotPJqX+ +OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1lRtzuzWniTY+HKE40 +Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfwhI0Vcnyh78zyiGG69Gm7DIwLdVcE +uE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm ++9jaJXLE9gCxInm943xZYkqcBW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqj +ifLJS3tBEW1ntwiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1UdDwEB/wQEAwIB +BjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W0OhUKDtkLSGm+J1WE2pIPU/H +PinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfeuyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0H +ZJDmHvUqoai7PF35owgLEQzxPy0QlG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla +4gt5kNdXElE1GYhBaCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5R +vbbEsLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPTMaCm/zjd +zyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qequ5AvzSxnI9O4fKSTx+O +856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxhVicGaeVyQYHTtgGJoC86cnn+OjC/QezH +Yj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu +3R3y4G5OBVixwJAWKqQ9EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP +29FpHOTKyeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +Trustwave Global ECC P256 Certification Authority +================================================= +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy +dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1 +NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH77bOYj +43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoNFWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqm +P62jQzBBMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt +0UrrdaVKEJmzsaGLSvcwCgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjz +RM4q3wghDDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +Trustwave Global ECC P384 Certification Authority +================================================= +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYDVQQGEwJVUzER +MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy +dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4 +NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGvaDXU1CDFH +Ba5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJj9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr +/TklZvFe/oyujUF5nQlgziip04pt89ZF1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV +HQ8BAf8EBQMDBwYAMB0GA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNn +ADBkAjA3AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsCMGcl +CrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVuSw== +-----END CERTIFICATE----- + +NAVER Global Root Certification Authority +========================================= +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG +A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD +DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4 +NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT +UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb +UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW ++j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7 +XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2 +aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4 +Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z +VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B +A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai +cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy +YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV +HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK +21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB +jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx +hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg +E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH +D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ +A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY +qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG +I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg +kpzNNIaRkPpkUZ3+/uul9XXeifdy +-----END CERTIFICATE----- + +AC RAIZ FNMT-RCM SERVIDORES SEGUROS +=================================== +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF +UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy +NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4 +MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt +UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB +QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA +BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2 +LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG +SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD +zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c= +-----END CERTIFICATE----- + +GlobalSign Root R46 +=================== +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv +b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX +BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es +CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/ +r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje +2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt +bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj +K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4 +12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on +ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls +eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9 +vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM +BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy +gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92 +CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm +OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq +JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye +qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz +nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7 +DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3 +QEUxeCp6 +-----END CERTIFICATE----- + +GlobalSign Root E46 +=================== +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT +AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg +RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV +BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB +jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj +QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL +gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk +vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ +CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +GLOBALTRUST 2020 +================ +-----BEGIN CERTIFICATE----- +MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx +IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT +VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh +BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy +MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi +D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO +VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM +CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm +fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA +A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR +JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG +DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU +clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ +mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud +IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA +VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw +4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9 +iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS +8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2 +HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS +vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918 +oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF +YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl +gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== +-----END CERTIFICATE----- + +ANF Secure Server Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNVBAUTCUc2MzI4 +NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lv +bjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNVBAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3Qg +Q0EwHhcNMTkwOTA0MTAwMDM4WhcNMzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEw +MQswCQYDVQQGEwJFUzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQw +EgYDVQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9vdCBDQTCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCjcqQZAZ2cC4Ffc0m6p6zz +BE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9qyGFOtibBTI3/TO80sh9l2Ll49a2pcbnv +T1gdpd50IJeh7WhM3pIXS7yr/2WanvtH2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcv +B2VSAKduyK9o7PQUlrZXH1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXse +zx76W0OLzc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyRp1RM +VwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQzW7i1o0TJrH93PB0j +7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/SiOL9V8BY9KHcyi1Swr1+KuCLH5z +JTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJnLNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe +8TZBAQIvfXOn3kLMTOmJDVb3n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVO +Hj1tyRRM4y5Bu8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj +o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAOBgNVHQ8BAf8E +BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEATh65isagmD9uw2nAalxJ +UqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzx +j6ptBZNscsdW699QIyjlRRA96Gejrw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDt +dD+4E5UGUcjohybKpFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM +5gf0vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjqOknkJjCb +5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ/zo1PqVUSlJZS2Db7v54 +EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ92zg/LFis6ELhDtjTO0wugumDLmsx2d1H +hk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI+PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGy +g77FGr8H6lnco4g175x2MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3 +r5+qPeoott7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= +-----END CERTIFICATE----- + +Certum EC-384 CA +================ +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQswCQYDVQQGEwJQ +TDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2 +MDcyNDU0WhcNNDMwMzI2MDcyNDU0WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERh +dGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +GTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATEKI6rGFtq +vm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7TmFy8as10CW4kjPMIRBSqn +iBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68KjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFI0GZnQkdjrzife81r1HfS+8EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNo +ADBlAjADVS2m5hjEfO/JUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0 +QoSZ/6vnnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +Certum Trusted Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6MQswCQYDVQQG +EwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0g +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0Ew +HhcNMTgwMzE2MTIxMDEzWhcNNDMwMzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMY +QXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZn0EGze2jusDbCSzBfN8p +fktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/qp1x4EaTByIVcJdPTsuclzxFUl6s1wB52 +HO8AU5853BSlLCIls3Jy/I2z5T4IHhQqNwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2 +fJmItdUDmj0VDT06qKhF8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGt +g/BKEiJ3HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGamqi4 +NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi7VdNIuJGmj8PkTQk +fVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSFytKAQd8FqKPVhJBPC/PgP5sZ0jeJ +P/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0PqafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSY +njYJdmZm/Bo/6khUHL4wvYBQv3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHK +HRzQ+8S1h9E6Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 +vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQADggIBAEii1QAL +LtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4WxmB82M+w85bj/UvXgF2Ez8s +ALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvozMrnadyHncI013nR03e4qllY/p0m+jiGPp2K +h2RX5Rc64vmNueMzeMGQ2Ljdt4NR5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8 +CYyqOhNf6DR5UMEQGfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA +4kZf5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq0Uc9Nneo +WWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7DP78v3DSk+yshzWePS/Tj +6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTMqJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmT +OPQD8rv7gmsHINFSH5pkAnuYZttcTVoP0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZck +bxJF0WddCajJFdr60qZfE2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb +-----END CERTIFICATE----- + +TunTrust Root CA +================ +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG +A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj +dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw +NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD +ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz +2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b +bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7 +NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd +gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW +VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f +Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ +juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas +DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS +VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI +04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl +0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd +Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY +YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp +adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x +xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP +jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM +MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z +ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r +AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +HARICA TLS RSA Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG +EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u +cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz +OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl +bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB +IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN +JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu +a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y +Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K +5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv +dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR +0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH +GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm +haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ +CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU +EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq +QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD +QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR +j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5 +vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0 +qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6 +Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/ +PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn +kf3/W9b3raYvAwtt41dU63ZTGI0RmLo= +-----END CERTIFICATE----- + +HARICA TLS ECC Root CA 2021 +=========================== +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH +UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD +QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX +DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj +IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv +b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l +AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b +ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW +0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi +rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw +CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchive.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchive.php new file mode 100644 index 0000000..69bc8b2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchive.php @@ -0,0 +1,286 @@ +': + $retVal = self::HEADER_TYPE_DIR; + break; + case '': + $retVal = self::HEADER_TYPE_FILE; + break; + case '': + $retVal = self::HEADER_TYPE_GLOB; + break; + default: + throw new Exception("Invalid header marker {$marker}. Location:" . ftell($archiveHandle)); + } + } + + return $retVal; + } + + /** + * Get archive index data + * + * @param string $archivePath archive path + * + * @return bool|array return index data, false if don't exists + */ + public static function getIndexData($archivePath) + { + try { + $indexContent = self::getSrcFile($archivePath, self::INDEX_FILE_NAME, 0, 3000, false); + if ($indexContent === false) { + return false; + } + $indexData = json_decode(rtrim($indexContent, "\0"), true); + + if (!is_array($indexData)) { + return false; + } + } catch (Exception $e) { + return false; + } catch (Error $e) { + return false; + } + + return $indexData; + } + + /** + * Get extra files offset if set or 0 + * + * @param string $archivePath archive path + * + * @return int + */ + public static function getExtraOffset($archivePath) + { + if (($indexData = self::getIndexData($archivePath)) === false) { + return 0; + } + return (isset($indexData[self::EXTRA_FILES_POS_KEY]) ? $indexData[self::EXTRA_FILES_POS_KEY] : 0); + } + + /** + * Add file in archive from src + * + * @param string $archivePath archive path + * @param string $relativePath relative path + * @param int $offset start search location + * @param int $sizeToSearch max size where search + * + * @return bool|int false if file not found of path position + */ + public static function seachPathInArchive($archivePath, $relativePath, $offset = 0, $sizeToSearch = 0) + { + if (($archiveHandle = fopen($archivePath, 'rb')) === false) { + throw new Exception("Can’t open archive at $archivePath!"); + } + $result = self::searchPath($archivePath, $relativePath, $offset, $sizeToSearch); + @fclose($archiveHandle); + return $result; + } + + /** + * Search path, if found set and return position + * + * @param resource $archiveHandle dup archive resource + * @param string $relativePath relative path to extract + * @param int $offset start search location + * @param int $sizeToSearch max size where search + * + * @return bool|int false if file not found of path position + */ + public static function searchPath($archiveHandle, $relativePath, $offset = 0, $sizeToSearch = 0) + { + if (!is_resource($archiveHandle)) { + throw new Exception('Archive handle must be a resource'); + } + + if (fseek($archiveHandle, $offset, SEEK_SET) < 0) { + return false; + } + + if ($offset == 0) { + DupArchiveReaderHeader::readFromArchive($archiveHandle); + } + + $result = false; + $position = ftell($archiveHandle); + $continue = true; + + do { + switch (($type = self::getNextHeaderType($archiveHandle))) { + case self::HEADER_TYPE_FILE: + $currentFileHeader = DupArchiveReaderFileHeader::readFromArchive($archiveHandle, true, true); + if ($currentFileHeader->relativePath == $relativePath) { + $continue = false; + $result = $position; + } + break; + case self::HEADER_TYPE_DIR: + $directoryHeader = DupArchiveReaderDirectoryHeader::readFromArchive($archiveHandle, true); + if ($directoryHeader->relativePath == $relativePath) { + $continue = false; + $result = $position; + } + break; + case self::HEADER_TYPE_NONE: + $continue = false; + break; + default: + throw new Exception('Invali header type "' . $type . '"'); + } + $position = ftell($archiveHandle); + if ($sizeToSearch > 0 && ($position - $offset) >= $sizeToSearch) { + break; + } + } while ($continue); + + if ($result !== false) { + if (fseek($archiveHandle, $result, SEEK_SET) < 0) { + return false; + } + } + return $result; + } + + /** + * Get file content + * + * @param string $archivePath archvie path + * @param string $relativePath relative path to extract + * @param int $offset start search location + * @param int $sizeToSearch max size where search + * @param bool $isCompressed true if is compressed + * + * @return bool|string false if file not found + */ + public static function getSrcFile($archivePath, $relativePath, $offset = 0, $sizeToSearch = 0, $isCompressed = null) + { + if (($archiveHandle = fopen($archivePath, 'rb')) === false) { + throw new Exception("Can’t open archive at $archivePath!"); + } + $archiveHeader = DupArchiveReaderHeader::readFromArchive($archiveHandle); + if (is_null($isCompressed)) { + $isCompressed = $archiveHeader->isCompressed; + } + + if (self::searchPath($archiveHandle, $relativePath, $offset, $sizeToSearch) === false) { + return false; + } + + if (self::getNextHeaderType($archiveHandle) != self::HEADER_TYPE_FILE) { + return false; + } + + $header = DupArchiveReaderFileHeader::readFromArchive($archiveHandle, false, true); + $result = self::getSrcFromHeader($archiveHandle, $header, $isCompressed); + @fclose($archiveHandle); + return $result; + } + + /** + * Get src file form header + * + * @param resource $archiveHandle archive handle + * @param DupArchiveReaderFileHeader $fileHeader file header + * @param bool $isCompressed true if is compressed + * + * @return string + */ + protected static function getSrcFromHeader($archiveHandle, DupArchiveReaderFileHeader $fileHeader, $isCompressed) + { + if ($fileHeader->fileSize == 0) { + return ''; + } + $dataSize = 0; + $result = ''; + + do { + $globHeader = DupArchiveReaderGlobHeader::readFromArchive($archiveHandle); + $result .= DupArchiveReaderGlobHeader::readContent($archiveHandle, $globHeader, $isCompressed); + $dataSize += $globHeader->originalSize; + } while ($dataSize < $fileHeader->fileSize); + + return $result; + } + + /** + * Skip file in archive + * + * @param resource $archiveHandle dup archive resource + * @param DupArchiveFileHeader $fileHeader file header + * + * @return void + */ + protected static function skipFileInArchive($archiveHandle, DupArchiveReaderFileHeader $fileHeader) + { + if ($fileHeader->fileSize == 0) { + return; + } + $dataSize = 0; + + do { + $globHeader = DupArchiveReaderGlobHeader::readFromArchive($archiveHandle, true); + $dataSize += $globHeader->originalSize; + } while ($dataSize < $fileHeader->fileSize); + } + + /** + * Assumes we are on one header and just need to get to the next + * + * @param resource $archiveHandle dup archive resource + * + * @return void + */ + protected static function skipToNextHeader($archiveHandle) + { + $headerType = self::getNextHeaderType($archiveHandle); + switch ($headerType) { + case self::HEADER_TYPE_FILE: + $fileHeader = DupArchiveReaderFileHeader::readFromArchive($archiveHandle, false, true); + self::skipFileInArchive($archiveHandle, $fileHeader); + break; + case self::HEADER_TYPE_DIR: + DupArchiveReaderDirectoryHeader::readFromArchive($archiveHandle, true); + break; + case self::HEADER_TYPE_NONE: + false; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveEngine.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveEngine.php new file mode 100644 index 0000000..6545013 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveEngine.php @@ -0,0 +1,827 @@ +basepathLength); + $result = ltrim($result, '/'); + if ($createState->newBasePath !== null) { + $result = $createState->newBasePath . $result; + } + } else { + $safePath = SnapIO::safePathUntrailingslashit($path); + $result = ltrim( + $createState->newBasePath . preg_replace('/^' . preg_quote(self::$targetRootPath, '/') . '(.*)/m', '$1', $safePath), + '/' + ); + } + return $result; + } + + /** + * Get archvie info from path + * + * @param string $filepath archvie path + * + * @return DupArchiveInfo + */ + public static function getArchiveInfo($filepath) + { + $archiveInfo = new DupArchiveInfo(); + + DupArchiveUtil::log("archive size=" . filesize($filepath)); + $archiveHandle = SnapIO::fopen($filepath, 'rb'); + $archiveInfo->archiveHeader = DupArchiveHeader::readFromArchive($archiveHandle); + $moreToRead = true; + + while ($moreToRead) { + $headerType = self::getNextHeaderType($archiveHandle); + + // DupArchiveUtil::log("next header type=$headerType: " . ftell($archiveHandle)); + + switch ($headerType) { + case self::HEADER_TYPE_FILE: + $fileHeader = DupArchiveFileHeader::readFromArchive($archiveHandle, true, true); + $archiveInfo->fileHeaders[] = $fileHeader; + DupArchiveUtil::log("file" . $fileHeader->relativePath); + break; + + case self::HEADER_TYPE_DIR: + $directoryHeader = DupArchiveDirectoryHeader::readFromArchive($archiveHandle, true); + + $archiveInfo->directoryHeaders[] = $directoryHeader; + break; + + case self::HEADER_TYPE_NONE: + $moreToRead = false; + } + } + return $archiveInfo; + } + + /** + * Add folder to archive + * + * can't span requests since create state can't store list of files + * + * @param string $archiveFilepath archive file + * @param string $directory folder to add + * @param string $basepath base path to consider (?) + * @param boolean $includeFiles if true include files + * @param string $newBasepath new base path + * @param int $globSize global size + * + * @return stdClass + */ + public static function addDirectoryToArchiveST( + $archiveFilepath, + $directory, + $basepath, + $includeFiles = false, + $newBasepath = null, + $globSize = DupArchiveCreateState::DEFAULT_GLOB_SIZE + ) { + if ($includeFiles) { + $scan = DupArchiveScanUtil::createScanObject($directory); + } else { + $scan = new stdClass(); + $scan->Files = array(); + $scan->Dirs = array(); + } + + $createState = new DupArchiveSimpleCreateState(); + + $createState->archiveOffset = filesize($archiveFilepath); + $createState->archivePath = $archiveFilepath; + $createState->basePath = $basepath; + $createState->basepathLength = strlen($basepath); + $createState->timerEnabled = false; + $createState->globSize = $globSize; + $createState->newBasePath = $newBasepath; + + self::addItemsToArchive($createState, $scan); + + $retVal = new stdClass(); + $retVal->numDirsAdded = $createState->currentDirectoryIndex; + $retVal->numFilesAdded = $createState->currentFileIndex; + + if ($createState->skippedFileCount > 0) { + throw new Exception("One or more files were were not able to be added when adding {$directory} to {$archiveFilepath}"); + } elseif ($createState->skippedDirectoryCount > 0) { + throw new Exception("One or more directories were not able to be added when adding {$directory} to {$archiveFilepath}"); + } + + return $retVal; + } + + /** + * Add relative file to archive + * + * @param string $archiveFilepath archive file + * @param string $filepath file to add + * @param string $relativePath relative path in archive + * @param int $globSize global size + * + * @return void + */ + public static function addRelativeFileToArchiveST( + $archiveFilepath, + $filepath, + $relativePath, + $globSize = DupArchiveCreateState::DEFAULT_GLOB_SIZE + ) { + $createState = new DupArchiveSimpleCreateState(); + + $createState->archiveOffset = filesize($archiveFilepath); + $createState->archivePath = $archiveFilepath; + $createState->basePath = null; + $createState->basepathLength = 0; + $createState->timerEnabled = false; + $createState->globSize = $globSize; + + $scan = new stdClass(); + + $scan->Files = array(); + $scan->Dirs = array(); + + $scan->Files[] = $filepath; + + if ($relativePath != null) { + $scan->FileAliases = array(); + $scan->FileAliases[$filepath] = $relativePath; + } + + self::addItemsToArchive($createState, $scan); + } + + /** + * Add file in archive from src + * + * @param string|resource $archive Archive path or archive handle + * @param string $src source string + * @param string $relativeFilePath relative path + * @param int $forceSize if 0 size is auto of content is filled of \0 char to size + * + * @return bool + */ + public static function addFileFromSrc( + $archive, + $src, + $relativeFilePath, + $forceSize = 0 + ) { + if (is_resource($archive)) { + $archiveHandle = $archive; + SnapIO::fseek($archiveHandle, 0, SEEK_SET); + } else { + if (($archiveHandle = SnapIO::fopen($archive, 'r+b')) == false) { + throw new Exception('Can\'t open archive'); + } + } + + $createState = new DupArchiveSimpleCreateState(); + $createState->archiveOffset = SnapIO::ftell($archiveHandle); + $createState->basePath = dirname($relativeFilePath); + $createState->basepathLength = strlen($createState->basePath); + $createState->timerEnabled = false; + + if ($forceSize == 0) { + $archiveHeader = DupArchiveHeader::readFromArchive($archiveHandle); + $createState->isCompressed = $archiveHeader->isCompressed; + } else { + // ff force size is enables the src isn't compress + $createState->isCompressed = false; + } + + SnapIO::fseek($archiveHandle, 0, SEEK_END); + + $result = DupArchiveFileProcessor::writeFileSrcToArchive($createState, $archiveHandle, $src, $relativeFilePath, $forceSize); + + if (!is_resource($archive)) { + SnapIO::fclose($archiveHandle); + } + return $result; + } + + /** + * Add file in archive from src + * + * @param string $archiveFilepath archive path + * @param string $src source string + * @param string $relativeFilePath relative path + * @param int $offset start search location + * @param int $sizeToSearch max size where search + * + * @return bool + */ + public static function replaceFileContent( + $archiveFilepath, + $src, + $relativeFilePath, + $offset = 0, + $sizeToSearch = 0 + ) { + if (($archiveHandle = SnapIO::fopen($archiveFilepath, 'r+b')) == false) { + throw new Exception('Can\'t open archive'); + } + + if (($filePos = self::searchPath($archiveHandle, $relativeFilePath, $offset, $sizeToSearch)) == false) { + return false; + } + $fileHeader = DupArchiveReaderFileHeader::readFromArchive($archiveHandle); + $globHeader = DupArchiveReaderGlobHeader::readFromArchive($archiveHandle); + SnapIO::fseek($archiveHandle, $filePos); + + $createState = new DupArchiveSimpleCreateState(); + $createState->archivePath = $archiveFilepath; + $createState->archiveOffset = $filePos; + $createState->basePath = dirname($relativeFilePath); + $createState->basepathLength = strlen($createState->basePath); + $createState->timerEnabled = false; + $createState->isCompressed = false; // replaced content can't be compressed + + $forceSize = $globHeader->storedSize; + + $result = DupArchiveFileProcessor::writeFileSrcToArchive($createState, $archiveHandle, $src, $relativeFilePath, $forceSize); + SnapIO::fclose($archiveHandle); + + return $result; + } + + + /** + * Add file in archive using base dir + * + * @param string $archiveFilepath archive file + * @param string $basePath base path + * @param string $filepath file to add + * @param int $globSize global size + * + * @return void + */ + public static function addFileToArchiveUsingBaseDirST( + $archiveFilepath, + $basePath, + $filepath, + $globSize = DupArchiveCreateState::DEFAULT_GLOB_SIZE + ) { + $createState = new DupArchiveSimpleCreateState(); + + $createState->archiveOffset = filesize($archiveFilepath); + $createState->archivePath = $archiveFilepath; + $createState->basePath = $basePath; + $createState->basepathLength = strlen($basePath); + $createState->timerEnabled = false; + $createState->globSize = $globSize; + + $scan = new stdClass(); + + $scan->Files = array(); + $scan->Dirs = array(); + + $scan->Files[] = $filepath; + + self::addItemsToArchive($createState, $scan); + } + + /** + * Create archive + * + * @param string $archivePath archive file path + * @param bool $isCompressed is compressed + * + * @return void + */ + public static function createArchive($archivePath, $isCompressed) + { + if (($archiveHandle = SnapIO::fopen($archivePath, 'w+b')) === false) { + throw new Exception('Can\t create dup archvie file ' . $archivePath); + } + + $archiveHeader = DupArchiveHeader::create($isCompressed); + $archiveHeader->writeToArchive($archiveHandle); + + //reserver space for index + $src = json_encode(array('test')); + $src .= str_repeat("\0", self::INDEX_FILE_SIZE - strlen($src)); + self::addFileFromSrc($archiveHandle, $src, self::INDEX_FILE_NAME, self::INDEX_FILE_SIZE); + + // Intentionally do not write build state since if something goes wrong we went it to start over on the archive + SnapIO::fclose($archiveHandle); + } + + /** + * Add items to archive + * + * @param DupArchiveCreateState $createState create state info + * @param stdClass $scanFSInfo scan if + * + * @return void + */ + public static function addItemsToArchive(DupArchiveCreateState $createState, stdClass $scanFSInfo) + { + if ($createState->globSize == -1) { + $createState->globSize = DupArchiveCreateState::DEFAULT_GLOB_SIZE; + } + + DupArchiveUtil::tlogObject("addItemsToArchive start", $createState); + + $directoryCount = count($scanFSInfo->Dirs); + $fileCount = count($scanFSInfo->Files); + $createState->startTimer(); + $archiveHandle = SnapIO::fopen($createState->archivePath, 'r+b'); + + DupArchiveUtil::tlog("Archive size=", filesize($createState->archivePath)); + DupArchiveUtil::tlog("Archive location is now " . SnapIO::ftell($archiveHandle)); + + $archiveHeader = DupArchiveHeader::readFromArchive($archiveHandle); + + $createState->isCompressed = $archiveHeader->isCompressed; + + if ($createState->archiveOffset == filesize($createState->archivePath)) { + DupArchiveUtil::tlog( + "Seeking to end of archive location because of offset {$createState->archiveOffset} " . + "for file size " . filesize($createState->archivePath) + ); + SnapIO::fseek($archiveHandle, 0, SEEK_END); + } else { + DupArchiveUtil::tlog("Seeking archive offset {$createState->archiveOffset} for file size " . filesize($createState->archivePath)); + SnapIO::fseek($archiveHandle, $createState->archiveOffset); + } + + while (($createState->currentDirectoryIndex < $directoryCount) && (!$createState->timedOut())) { + if ($createState->throttleDelayInUs !== 0) { + usleep($createState->throttleDelayInUs); + } + + $directory = $scanFSInfo->Dirs[$createState->currentDirectoryIndex]; + + try { + $relativeDirectoryPath = ''; + + if (isset($scanFSInfo->DirectoryAliases) && array_key_exists($directory, $scanFSInfo->DirectoryAliases)) { + $relativeDirectoryPath = $scanFSInfo->DirectoryAliases[$directory]; + } else { + $relativeDirectoryPath = self::getLocalPath($directory, $createState); + } + + if ($relativeDirectoryPath !== '') { + DupArchiveDirectoryProcessor::writeDirectoryToArchive($createState, $archiveHandle, $directory, $relativeDirectoryPath); + } else { + $createState->skippedDirectoryCount++; + $createState->currentDirectoryIndex++; + } + } catch (Exception $ex) { + DupArchiveUtil::log("Failed to add {$directory} to archive. Error: " . $ex->getMessage(), true); + + $createState->addFailure(DupArchiveProcessingFailure::TYPE_DIRECTORY, $directory, $ex->getMessage(), false); + $createState->currentDirectoryIndex++; + $createState->skippedDirectoryCount++; + $createState->save(); + } + } + + $createState->archiveOffset = SnapIO::ftell($archiveHandle); + + $workTimestamp = time(); + while (($createState->currentFileIndex < $fileCount) && (!$createState->timedOut())) { + $filepath = $scanFSInfo->Files[$createState->currentFileIndex]; + + try { + $relativeFilePath = ''; + + if (isset($scanFSInfo->FileAliases) && array_key_exists($filepath, $scanFSInfo->FileAliases)) { + $relativeFilePath = $scanFSInfo->FileAliases[$filepath]; + } else { + $relativeFilePath = self::getLocalPath($filepath, $createState); + } + + // Uncomment when testing error handling +// if((strpos($relativeFilePath, 'dup-installer') !== false) || (strpos($relativeFilePath, 'lib') !== false)) { +// Dup_Log::Trace("Was going to do intentional error to {$relativeFilePath} but skipping"); +// } else { +// throw new Exception("#### intentional file error when writing " . $relativeFilePath); +// } +// } + + DupArchiveFileProcessor::writeFilePortionToArchive($createState, $archiveHandle, $filepath, $relativeFilePath); + + if (($createState->isRobust) && (time() - $workTimestamp >= 1)) { + DupArchiveUtil::log("Robust mode create state save"); + + // When in robustness mode save the state every second + $workTimestamp = time(); + $createState->working = ($createState->currentDirectoryIndex < $directoryCount) || ($createState->currentFileIndex < $fileCount); + $createState->save(); + } + } catch (Snap32BitSizeLimitException $ex) { + throw $ex; + } catch (Exception $ex) { + DupArchiveUtil::log("Failed to add {$filepath} to archive. Error: " . $ex->getMessage() . $ex->getTraceAsString(), true); + $createState->currentFileIndex++; + $createState->skippedFileCount++; + $createState->addFailure(DupArchiveProcessingFailure::TYPE_FILE, $filepath, $ex->getMessage(), ($ex->getCode() === self::EXCEPTION_FATAL)); + $createState->save(); + } + } + + $createState->working = ($createState->currentDirectoryIndex < $directoryCount) || ($createState->currentFileIndex < $fileCount); + $createState->save(); + + SnapIO::fclose($archiveHandle); + + if (!$createState->working) { + DupArchiveUtil::log("compress done"); + } else { + DupArchiveUtil::tlog("compress not done so continuing later"); + } + } + + /** + * Expand archive + * + * @param DupArchiveExpandState $expandState expand state + * + * @return void + */ + public static function expandArchive(DupArchiveExpandState $expandState) + { + $expandState->startTimer(); + $archiveHandle = SnapIO::fopen($expandState->archivePath, 'rb'); + + SnapIO::fseek($archiveHandle, $expandState->archiveOffset); + + if ($expandState->archiveOffset == 0) { + $expandState->archiveHeader = DupArchiveHeader::readFromArchive($archiveHandle); + $expandState->isCompressed = $expandState->archiveHeader->isCompressed; + $expandState->archiveOffset = SnapIO::ftell($archiveHandle); + + $expandState->save(); + } else { + DupArchiveUtil::log("#### seeking archive offset {$expandState->archiveOffset}"); + } + + DupArchiveUtil::log('DUP EXPAND OFFSET ' . $expandState->archiveOffset); + + if ((!$expandState->validateOnly) || ($expandState->validationType == DupArchiveExpandState::VALIDATION_FULL)) { + $moreItems = self::expandItems($expandState, $archiveHandle); + } else { + $moreItems = self::standardValidateItems($expandState, $archiveHandle); + } + + $expandState->working = $moreItems; + $expandState->save(); + + SnapIO::fclose($archiveHandle, false); + + if (!$expandState->working) { + DupArchiveUtil::log("DUP EXPAND DONE"); + + if (($expandState->expectedFileCount != -1) && ($expandState->expectedFileCount != $expandState->fileWriteCount)) { + $expandState->addFailure( + DupArchiveProcessingFailure::TYPE_FILE, + 'Archive', + "Number of files expected ({$expandState->expectedFileCount}) doesn't equal number written ({$expandState->fileWriteCount})." + ); + } + + if (($expandState->expectedDirectoryCount != -1) && ($expandState->expectedDirectoryCount != $expandState->directoryWriteCount)) { + $expandState->addFailure( + DupArchiveProcessingFailure::TYPE_DIRECTORY, + 'Archive', + "Number of directories expected ({$expandState->expectedDirectoryCount}) " . + "doesn't equal number written ({$expandState->directoryWriteCount})." + ); + } + } else { + DupArchiveUtil::tlogObject("expand not done so continuing later", $expandState); + } + } + + /** + * Single-threaded file expansion + * + * @param string $archiveFilePath archive path + * @param string $relativeFilePaths relative file path in archive + * @param string $destPath destination path + * + * @return void + */ + public static function expandFiles($archiveFilePath, $relativeFilePaths, $destPath) + { + // Not setting timeout timestamp so it will never timeout + DupArchiveUtil::tlog("opening archive {$archiveFilePath}"); + + $archiveHandle = SnapIO::fopen($archiveFilePath, 'r'); + + /* @var $expandState DupArchiveSimpleExpandState */ + $expandState = new DupArchiveSimpleExpandState(); + + $expandState->archiveHeader = DupArchiveHeader::readFromArchive($archiveHandle); + $expandState->isCompressed = $expandState->archiveHeader->isCompressed; + $expandState->archiveOffset = SnapIO::ftell($archiveHandle); + $expandState->includedFiles = $relativeFilePaths; + $expandState->filteredDirectories = array('*'); + $expandState->filteredFiles = array('*'); + // $expandState->basePath = $destPath . '/tempExtract'; // RSR remove once extract works + $expandState->basePath = $destPath; // RSR remove once extract works + // TODO: Filter out all directories/files except those in the list + self::expandItems($expandState, $archiveHandle); + } + + /** + * Expand dup archive items + * + * @param DupArchiveExpandState $expandState dup archive expand state + * @param resource $archiveHandle dup archvie resource + * + * @return bool true if more to read + */ + private static function expandItems(DupArchiveExpandState $expandState, $archiveHandle) + { + $moreToRead = true; + $workTimestamp = time(); + + while ($moreToRead && (!$expandState->timedOut())) { + if ($expandState->throttleDelayInUs !== 0) { + usleep($expandState->throttleDelayInUs); + } + + if ($expandState->currentFileHeader != null) { + DupArchiveUtil::tlog("Writing file {$expandState->currentFileHeader->relativePath}"); + + if (self::filePassesFilters($expandState)) { + try { + $fileCompleted = DupArchiveFileProcessor::writeToFile($expandState, $archiveHandle); + } catch (Exception $ex) { + DupArchiveUtil::log("Failed to write to {$expandState->currentFileHeader->relativePath}. Error: " . $ex->getMessage(), true); + + // Reset things - skip over this file within the archive. + SnapIO::fseek($archiveHandle, $expandState->lastHeaderOffset); + self::skipToNextHeader($archiveHandle, $expandState->currentFileHeader); + + $expandState->archiveOffset = ftell($archiveHandle); + $expandState->addFailure( + DupArchiveProcessingFailure::TYPE_FILE, + $expandState->currentFileHeader->relativePath, + $ex->getMessage(), + false + ); + $expandState->resetForFile(); + $expandState->lastHeaderOffset = -1; + $expandState->save(); + } + } else { + self::skipFileInArchive($archiveHandle, $expandState->currentFileHeader); + $expandState->resetForFile(); + } + } else { + // Header is null so read in the next one + $expandState->lastHeaderOffset = @ftell($archiveHandle); + $headerType = self::getNextHeaderType($archiveHandle); + + DupArchiveUtil::tlog('header type ' . $headerType); + switch ($headerType) { + case self::HEADER_TYPE_FILE: + DupArchiveUtil::tlog('File header'); + $expandState->currentFileHeader = DupArchiveFileHeader::readFromArchive($archiveHandle, false, true); + $expandState->archiveOffset = @ftell($archiveHandle); + DupArchiveUtil::tlog('Just read file header from archive'); + break; + case self::HEADER_TYPE_DIR: + DupArchiveUtil::tlog('Directory Header'); + $directoryHeader = DupArchiveDirectoryHeader::readFromArchive($archiveHandle, true); + + if (self::passesDirectoryExclusion($expandState, $directoryHeader->relativePath)) { + $createdDirectory = true; + + if (!$expandState->validateOnly) { + $createdDirectory = DupArchiveFileProcessor::createDirectory($expandState, $directoryHeader); + } + + if ($createdDirectory) { + $expandState->directoryWriteCount++; + } + } + $expandState->archiveOffset = ftell($archiveHandle); + DupArchiveUtil::tlog('Just read directory header ' . $directoryHeader->relativePath . ' from archive'); + break; + case self::HEADER_TYPE_NONE: + $moreToRead = false; + } + } + + if (($expandState->isRobust) && (time() - $workTimestamp >= 1)) { + DupArchiveUtil::log("Robust mode extract state save for standard validate"); + + // When in robustness mode save the state every second + $workTimestamp = time(); + $expandState->save(); + } + } + + $expandState->save(); + + return $moreToRead; + } + + /** + * check exclude dir + * + * @param DupArchiveExpandState $expandState dup archive expand state + * @param string $candidate check exclude dir + * + * @return bool + */ + private static function passesDirectoryExclusion(DupArchiveExpandState $expandState, $candidate) + { + foreach ($expandState->filteredDirectories as $directoryFilter) { + if ($directoryFilter === '*') { + return false; + } + + if (SnapIO::getRelativePath($candidate, $directoryFilter) !== false) { + return false; + } + } + + if (in_array($candidate, $expandState->excludedDirWithoutChilds)) { + return false; + } + + return true; + } + + /** + * Check flils filters + * + * @param DupArchiveExpandState $expandState dup archive expand state + * + * @return boolean + */ + private static function filePassesFilters(DupArchiveExpandState $expandState) + { + $candidate = $expandState->currentFileHeader->relativePath; + + // Included files trumps all exclusion filters + foreach ($expandState->includedFiles as $includedFile) { + if ($includedFile === $candidate) { + return true; + } + } + + if (self::passesDirectoryExclusion($expandState, $candidate)) { + foreach ($expandState->filteredFiles as $fileFilter) { + if ($fileFilter === '*' || $fileFilter === $candidate) { + return false; + } + } + } else { + return false; + } + + return true; + } + + /** + * Validate items + * + * @param DupArchiveExpandState $expandState dup archive expan state + * @param resource $archiveHandle dup archive resource + * + * @return bool true if more to read + */ + private static function standardValidateItems(DupArchiveExpandState $expandState, $archiveHandle) + { + $moreToRead = true; + + $to = $expandState->timedOut(); + $workTimestamp = time(); + + while ($moreToRead && (!$to)) { + if ($expandState->throttleDelayInUs !== 0) { + usleep($expandState->throttleDelayInUs); + } + + if ($expandState->currentFileHeader != null) { + try { + $fileCompleted = DupArchiveFileProcessor::standardValidateFileEntry($expandState, $archiveHandle); + + if ($fileCompleted) { + $expandState->resetForFile(); + } + + // Expand state taken care of within the write to file to ensure consistency + } catch (Exception $ex) { + DupArchiveUtil::log("Failed validate file in archive. Error: " . $ex->getMessage(), true); + DupArchiveUtil::logObject("expand state", $expandState, true); + // $expandState->currentFileIndex++; + // RSR TODO: Need way to skip past that file + + $expandState->addFailure(DupArchiveProcessingFailure::TYPE_FILE, $expandState->currentFileHeader->relativePath, $ex->getMessage()); + $expandState->save(); + + $moreToRead = false; + } + } else { + $headerType = self::getNextHeaderType($archiveHandle); + + switch ($headerType) { + case self::HEADER_TYPE_FILE: + $expandState->currentFileHeader = DupArchiveFileHeader::readFromArchive($archiveHandle, false, true); + $expandState->archiveOffset = ftell($archiveHandle); + break; + case self::HEADER_TYPE_DIR: + $directoryHeader = DupArchiveDirectoryHeader::readFromArchive($archiveHandle, true); + $expandState->directoryWriteCount++; + $expandState->archiveOffset = ftell($archiveHandle); + break; + case self::HEADER_TYPE_NONE: + $moreToRead = false; + } + } + + if (($expandState->isRobust) && (time() - $workTimestamp >= 1)) { + DupArchiveUtil::log("Robust mdoe extract state save for standard validate"); + + // When in robustness mode save the state every second + $workTimestamp = time(); + $expandState->save(); + } + $to = $expandState->timedOut(); + } + + $expandState->save(); + + return $moreToRead; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveExpandBasicEngine.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveExpandBasicEngine.php new file mode 100644 index 0000000..e8e0f3f --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveExpandBasicEngine.php @@ -0,0 +1,272 @@ +destDirectory = $destDirectory; + $writeInfo->isCompressed = $archiveHeader->isCompressed; + + if ($offset > 0) { + fseek($archiveHandle, $offset); + } + + $moreToRead = true; + + while ($moreToRead) { + if ($writeInfo->currentFileHeader != null) { + try { + if (self::passesInclusionFilter($inclusionFilter, $writeInfo->currentFileHeader->relativePath)) { + self::writeToFile($archiveHandle, $writeInfo); + $writeInfo->fileWriteCount++; + } elseif ($writeInfo->currentFileHeader->fileSize > 0) { + self::skipFileInArchive($archiveHandle, $writeInfo->currentFileHeader); + } + $writeInfo->currentFileHeader = null; + // Expand state taken care of within the write to file to ensure consistency + } catch (Exception $ex) { + if (!$ignoreErrors) { + throw $ex; + } + } + } else { + $headerType = self::getNextHeaderType($archiveHandle); + + switch ($headerType) { + case self::HEADER_TYPE_FILE: + $writeInfo->currentFileHeader = DupArchiveReaderFileHeader::readFromArchive($archiveHandle, false, true); + break; + case self::HEADER_TYPE_DIR: + $directoryHeader = DupArchiveReaderDirectoryHeader::readFromArchive($archiveHandle, true); + // self::log("considering $inclusionFilter and {$directoryHeader->relativePath}"); + if (self::passesInclusionFilter($inclusionFilter, $directoryHeader->relativePath)) { + // self::log("passed"); + $directory = "{$writeInfo->destDirectory}/{$directoryHeader->relativePath}"; + + // $mode = $directoryHeader->permissions; + // rodo handle this more elegantly @mkdir($directory, $directoryHeader->permissions, true); + if (is_callable(self::$mkdirCallback)) { + call_user_func(self::$mkdirCallback, $directory, 'u+rwx', true); + } else { + mkdir($directory, 0755, true); + } + $writeInfo->directoryWriteCount++; + } else { + // self::log("didnt pass"); + } + break; + case self::HEADER_TYPE_NONE: + $moreToRead = false; + } + } + } + + fclose($archiveHandle); + } + + /** + * Write to file + * + * @param resource $archiveHandle archive file handle + * @param DupArchiveExpanderInfo $writeInfo write info + * + * @return void + */ + private static function writeToFile($archiveHandle, DupArchiveExpanderInfo $writeInfo) + { + $destFilePath = $writeInfo->getCurrentDestFilePath(); + + if ($writeInfo->currentFileHeader->fileSize > 0) { + $parentDir = dirname($destFilePath); + if (!file_exists($parentDir)) { + if (is_callable(self::$mkdirCallback)) { + $res = call_user_func(self::$mkdirCallback, $parentDir, 'u+rwx', true); + } else { + $res = mkdir($parentDir, 0755, true); + } + if (!$res) { + throw new Exception("Couldn't create {$parentDir}"); + } + } + + $destFileHandle = fopen($destFilePath, 'wb+'); + if ($destFileHandle === false) { + throw new Exception("Couldn't open {$destFilePath} for writing."); + } + + do { + self::appendGlobToFile($archiveHandle, $destFileHandle, $writeInfo); + + $currentFileOffset = ftell($destFileHandle); + + $moreGlobstoProcess = $currentFileOffset < $writeInfo->currentFileHeader->fileSize; + } while ($moreGlobstoProcess); + + fclose($destFileHandle); + + if (is_callable(self::$chmodCallback)) { + call_user_func(self::$chmodCallback, $destFilePath, 'u+rw'); + } else { + chmod($destFilePath, 0644); + } + + self::validateExpandedFile($writeInfo); + } else { + if (touch($destFilePath) === false) { + throw new Exception("Couldn't create $destFilePath"); + } + + if (is_callable(self::$chmodCallback)) { + call_user_func(self::$chmodCallback, $destFilePath, 'u+rw'); + } else { + chmod($destFilePath, 0644); + } + } + } + + /** + * Validate file + * + * @param DupArchiveExpanderInfo $writeInfo write info + * + * @return void + */ + private static function validateExpandedFile(DupArchiveExpanderInfo $writeInfo) + { + if ($writeInfo->currentFileHeader->hash !== '00000000000000000000000000000000') { + $hash = hash_file('crc32b', $writeInfo->getCurrentDestFilePath()); + + if ($hash !== $writeInfo->currentFileHeader->hash) { + throw new Exception("MD5 validation fails for {$writeInfo->getCurrentDestFilePath()}"); + } + } + } + + /** + * Undocumented function + * Assumption is that archive handle points to a glob header on this call + * + * @param resource $archiveHandle archive handle + * @param resource $destFileHandle dest file handle + * @param DupArchiveExpanderInfo $writeInfo write info + * + * @return void + */ + private static function appendGlobToFile($archiveHandle, $destFileHandle, DupArchiveExpanderInfo $writeInfo) + { + $globHeader = DupArchiveReaderGlobHeader::readFromArchive($archiveHandle, false); + $globContents = fread($archiveHandle, $globHeader->storedSize); + + if ($globContents === false) { + throw new Exception("Error reading glob from " . $writeInfo->getCurrentDestFilePath()); + } + + if ($writeInfo->isCompressed) { + $globContents = gzinflate($globContents); + } + + if (fwrite($destFileHandle, $globContents) !== strlen($globContents)) { + throw new Exception("Unable to write all bytes of data glob to storage."); + } + } + + /** + * Check filter + * + * @param string $filter filter + * @param string $candidate candidate + * + * @return bool + */ + private static function passesInclusionFilter($filter, $candidate) + { + return (substr($candidate, 0, strlen($filter)) == $filter); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveLoggerBase.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveLoggerBase.php new file mode 100644 index 0000000..a3f83b9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/DupArchiveLoggerBase.php @@ -0,0 +1,23 @@ +relativePathLength == 0) { + // Don't allow a base path to be written to the archive + return; + } + + $headerString = '' . + $this->mtime . '

        ' . + $this->permissions . '

        ' . + $this->relativePathLength . '' . + $this->relativePath . '
        '; + + //SnapIO::fwrite($archiveHandle, $headerString); + $bytes_written = @fwrite($archiveHandle, $headerString); + + if ($bytes_written === false) { + throw new Exception('Error writing to file.'); + } else { + return $bytes_written; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveFileHeader.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveFileHeader.php new file mode 100644 index 0000000..8049bb6 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveFileHeader.php @@ -0,0 +1,119 @@ +fileSize = SnapIO::filesize($filepath); + $instance->permissions = substr(sprintf('%o', fileperms($filepath)), -4); + $instance->mtime = SnapIO::filemtime($filepath); + + if ($instance->fileSize > self::MAX_SIZE_FOR_HASHING) { + $instance->hash = "00000000000000000000000000000000"; + } else { + $instance->hash = hash_file('crc32b', $filepath); + } + + $instance->relativePath = $relativeFilePath; + $instance->relativePathLength = strlen($instance->relativePath); + + return $instance; + } + + /** + * create header from src + * + * @param string $src source string + * @param string $relativeFilePath relative path in archvie + * @param int $forceSize if 0 size is auto of content is filled of \0 char to size + * + * @return static + */ + public static function createFromSrc($src, $relativeFilePath, $forceSize = 0) + { + $instance = new static(); + + $instance->fileSize = strlen($src); + $instance->permissions = '0644'; + $instance->mtime = time(); + + $srcLen = strlen($src); + + if ($forceSize > 0 && $srcLen < $forceSize) { + $charsToAdd = $forceSize - $srcLen; + $src .= str_repeat("\0", $charsToAdd); + } + + if ($instance->fileSize > self::MAX_SIZE_FOR_HASHING) { + $instance->hash = "00000000000000000000000000000000"; + } else { + $instance->hash = hash('crc32b', $src); + } + + $instance->relativePath = $relativeFilePath; + $instance->relativePathLength = strlen($instance->relativePath); + + return $instance; + } + + /** + * Write header in archive + * + * @param resource $archiveHandle archive resource + * + * @return int bytes written + */ + public function writeToArchive($archiveHandle) + { + $headerString = '' . + $this->fileSize . '' . + $this->mtime . '

        ' . + $this->permissions . '

        ' . + $this->hash . '' . + $this->relativePathLength . '' . + $this->relativePath . '
        '; + + //SnapIO::fwrite($archiveHandle, $headerString); + $bytes_written = @fwrite($archiveHandle, $headerString); + + if ($bytes_written === false) { + throw new Exception('Error writing to file.'); + } else { + return $bytes_written; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveGlobHeader.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveGlobHeader.php new file mode 100644 index 0000000..c6412ef --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveGlobHeader.php @@ -0,0 +1,48 @@ +xxxx
        + + $headerString = '' . $this->originalSize . '' . $this->storedSize . '' . $this->hash . ''; + + //SnapIO::fwrite($archiveHandle, $headerString); + $bytes_written = @fwrite($archiveHandle, $headerString); + + if ($bytes_written === false) { + throw new Exception('Error writing to file.'); + } else { + return $bytes_written; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveHeader.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveHeader.php new file mode 100644 index 0000000..f0fe155 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveHeader.php @@ -0,0 +1,53 @@ +version = DupArchiveEngine::DUPARCHIVE_VERSION; + $instance->isCompressed = $isCompressed; + return $instance; + } + + /** + * Write header to archive + * + * @param resource $archiveHandle archive resource + * + * @return void + */ + public function writeToArchive($archiveHandle) + { + SnapIO::fwrite($archiveHandle, '' . $this->version . '' . ($this->isCompressed ? 'true' : 'false') . ''); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveHeaderU.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveHeaderU.php new file mode 100644 index 0000000..a6cc2f3 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveHeaderU.php @@ -0,0 +1,44 @@ +'; + $expectedEnd = ''; + + $startingElement = fread($archiveHandle, strlen($expectedStart)); + + if ($startingElement !== $expectedStart) { + throw new Exception("Invalid starting element. Was expecting {$expectedStart} but got {$startingElement}"); + } + + $headerString = stream_get_line($archiveHandle, self::MAX_FILED_LEN, $expectedEnd); + + if ($headerString === false) { + throw new Exception('Error reading line.'); + } + + return $headerString; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderDirectoryHeader.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderDirectoryHeader.php new file mode 100644 index 0000000..14baec4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderDirectoryHeader.php @@ -0,0 +1,79 @@ + + $startElement = fread($archiveHandle, 3); + + if ($startElement === false) { + if (feof($archiveHandle)) { + return false; + } else { + throw new Exception('Error reading directory header'); + } + } + + if ($startElement != '') { + throw new Exception("Invalid directory header marker found [{$startElement}] : location " . ftell($archiveHandle)); + } + } + + $instance->mtime = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'MT'); + $instance->permissions = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'P'); + $instance->relativePathLength = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'RPL'); + + // Skip the + fread($archiveHandle, 4); + + $instance->relativePath = fread($archiveHandle, $instance->relativePathLength); + + // Skip the + // fread($archiveHandle, 5); + + // Skip the + // fread($archiveHandle, 4); + + // Skip the and the + fread($archiveHandle, 9); + + return $instance; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderFileHeader.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderFileHeader.php new file mode 100644 index 0000000..7922c15 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderFileHeader.php @@ -0,0 +1,100 @@ + 20000 files -> 1.2MB larger + * xxxxxx + * # F#x#x#x#x#x#x! + * + * @param resource $archiveHandle archive resource + * @param boolean $skipContents if true skip contents + * @param boolean $skipMarker if true skip marker + * + * @return static + */ + public static function readFromArchive($archiveHandle, $skipContents = false, $skipMarker = false) + { + // RSR TODO Read header from archive handle and populate members + // TODO: return null if end of archive or throw exception if can read something but its not a file header + + $instance = new static(); + + if (!$skipMarker) { + $marker = @fread($archiveHandle, 3); + + if ($marker === false) { + if (feof($archiveHandle)) { + return false; + } else { + throw new Exception('Error reading file header'); + } + } + + if ($marker != '') { + throw new Exception("Invalid file header marker found [{$marker}] : location " . ftell($archiveHandle)); + } + } + + $instance->fileSize = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'FS'); + $instance->mtime = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'MT'); + $instance->permissions = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'P'); + $instance->hash = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'HA'); + $instance->relativePathLength = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'RPL'); + + // Skip + fread($archiveHandle, 4); + $instance->relativePath = fread($archiveHandle, $instance->relativePathLength); + + // Skip + // fread($archiveHandle, 5); + + // Skip the + // fread($archiveHandle, 4); + + // Skip the and the
        + fread($archiveHandle, 9); + + if ($skipContents && ($instance->fileSize > 0)) { + $dataSize = 0; + $moreGlobs = true; + while ($moreGlobs) { + $globHeader = DupArchiveReaderGlobHeader::readFromArchive($archiveHandle, true); + $dataSize += $globHeader->originalSize; + $moreGlobs = ($dataSize < $instance->fileSize); + } + } + + return $instance; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderGlobHeader.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderGlobHeader.php new file mode 100644 index 0000000..99ed298 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderGlobHeader.php @@ -0,0 +1,88 @@ +') { + throw new Exception("Invalid glob header marker found {$startElement}. location:" . ftell($archiveHandle)); + } + + $instance->originalSize = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'OS'); + $instance->storedSize = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'SS'); + $instance->hash = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'HA'); + + // Skip the + fread($archiveHandle, 4); + + if ($skipGlob) { + if (fseek($archiveHandle, $instance->storedSize, SEEK_CUR) === -1) { + throw new Exception("Can't fseek when skipping glob at location:" . ftell($archiveHandle)); + } + } + + return $instance; + } + + /** + * Get glob content from header + * + * @param resource $archiveHandle archive hadler + * @param self $header chunk glob header + * @param bool $isCompressed true if is compressed + * + * @return string + */ + public static function readContent($archiveHandle, self $header, $isCompressed) + { + if ($header->storedSize == 0) { + return 0; + } + + if (($globContents = fread($archiveHandle, $header->storedSize)) === false) { + throw new Exception("Error reading glob content"); + } + + return ($isCompressed ? gzinflate($globContents) : $globContents); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderHeader.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderHeader.php new file mode 100644 index 0000000..d3aafa3 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Headers/DupArchiveReaderHeader.php @@ -0,0 +1,55 @@ +') { + throw new Exception("Invalid archive header marker found {$startElement}"); + } + + $instance->version = DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'V'); + $instance->isCompressed = filter_var(DupArchiveHeaderU::readStandardHeaderField($archiveHandle, 'C'), FILTER_VALIDATE_BOOLEAN); + + // Skip the + fgets($archiveHandle, 5); + return $instance; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Info/DupArchiveExpanderInfo.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Info/DupArchiveExpanderInfo.php new file mode 100644 index 0000000..23913bf --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Info/DupArchiveExpanderInfo.php @@ -0,0 +1,28 @@ +destDirectory != null) { + return "{$this->destDirectory}/{$this->currentFileHeader->relativePath}"; + } else { + return null; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Info/DupArchiveInfo.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Info/DupArchiveInfo.php new file mode 100644 index 0000000..6706e49 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Info/DupArchiveInfo.php @@ -0,0 +1,25 @@ +fileHeaders = array(); + $this->directoryHeaders = array(); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveDirectoryProcessor.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveDirectoryProcessor.php new file mode 100644 index 0000000..aa21d0f --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveDirectoryProcessor.php @@ -0,0 +1,45 @@ +permissions = substr(sprintf('%o', fileperms($sourceDirectoryPath)), -4); + $directoryHeader->mtime = SnapIO::filemtime($sourceDirectoryPath); + $directoryHeader->relativePath = $relativeDirectoryPath; + $directoryHeader->relativePathLength = strlen($directoryHeader->relativePath); + + $directoryHeader->writeToArchive($archiveHandle); + + // Just increment this here - the actual state save is on the outside after timeout or completion of all directories + $createState->currentDirectoryIndex++; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveFileProcessor.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveFileProcessor.php new file mode 100644 index 0000000..a7179ba --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveFileProcessor.php @@ -0,0 +1,548 @@ +archiveOffset = SnapIO::ftell($archiveHandle); + $createState->currentFileIndex++; + $createState->currentFileOffset = 0; + $createState->skippedFileCount++; + $createState->addFailure(DupArchiveProcessingFailure::TYPE_FILE, $sourceFilepath, "Couldn't open $sourceFilepath", false); + return; + } + + if ($createState->currentFileOffset > 0) { + SnapIO::fseek($sourceHandle, $createState->currentFileOffset); + } else { + $fileHeader = DupArchiveFileHeader::createFromFile($sourceFilepath, $relativeFilePath); + $fileHeader->writeToArchive($archiveHandle); + } + + $sourceFileSize = filesize($sourceFilepath); + + $moreFileDataToProcess = true; + + while ((!$createState->timedOut()) && $moreFileDataToProcess) { + if ($createState->throttleDelayInUs !== 0) { + usleep($createState->throttleDelayInUs); + } + + $moreFileDataToProcess = self::appendGlobToArchive($createState, $archiveHandle, $sourceHandle, $sourceFilepath, $sourceFileSize); + $createState->archiveOffset = SnapIO::ftell($archiveHandle); + + if ($moreFileDataToProcess) { + $createState->currentFileOffset += $createState->globSize; + } else { + $createState->currentFileIndex++; + $createState->currentFileOffset = 0; + } + + // Only writing state after full group of files have been written - less reliable but more efficient + // $createState->save(); + } + + SnapIO::fclose($sourceHandle); + } + + /** + * Write file to archive from source + * + * @param DupArchiveCreateState $createState dup archive create state + * @param resource $archiveHandle archive resource + * @param string $src source string + * @param string $relativeFilePath relative file path + * @param int $forceSize if 0 size is auto of content is filled of \0 char to size + * + * @return void + */ + public static function writeFileSrcToArchive( + DupArchiveCreateState $createState, + $archiveHandle, + $src, + $relativeFilePath, + $forceSize = 0 + ) { + DupArchiveUtil::tlog("writeFileSrcToArchive"); + + $fileHeader = DupArchiveFileHeader::createFromSrc($src, $relativeFilePath, $forceSize); + $fileHeader->writeToArchive($archiveHandle); + + self::appendFileSrcToArchive($createState, $archiveHandle, $src, $forceSize); + $createState->currentFileIndex++; + $createState->currentFileOffset = 0; + $createState->archiveOffset = SnapIO::ftell($archiveHandle); + } + + /** + * Expand du archive + * + * Assumption is that this is called at the beginning of a glob header since file header already writtern + * + * @param DupArchiveExpandState $expandState expand state + * @param resource $archiveHandle archive resource + * + * @return bool true on success + */ + public static function writeToFile(DupArchiveExpandState $expandState, $archiveHandle) + { + if (isset($expandState->fileRenames[$expandState->currentFileHeader->relativePath])) { + $destFilepath = $expandState->fileRenames[$expandState->currentFileHeader->relativePath]; + } else { + $destFilepath = self::getNewFilePath($expandState->basePath, $expandState->currentFileHeader->relativePath); + } + $parentDir = dirname($destFilepath); + + $moreGlobstoProcess = true; + + SnapIO::dirWriteCheckOrMkdir($parentDir, 'u+rwx', true); + + if ($expandState->currentFileHeader->fileSize > 0) { + if ($expandState->currentFileOffset > 0) { + $destFileHandle = SnapIO::fopen($destFilepath, 'r+b'); + SnapIO::fseek($destFileHandle, $expandState->currentFileOffset); + } else { + $destFileHandle = SnapIO::fopen($destFilepath, 'w+b'); + } + + while (!$expandState->timedOut()) { + $moreGlobstoProcess = $expandState->currentFileOffset < $expandState->currentFileHeader->fileSize; + + if ($moreGlobstoProcess) { + if ($expandState->throttleDelayInUs !== 0) { + usleep($expandState->throttleDelayInUs); + } + + self::appendGlobToFile($expandState, $archiveHandle, $destFileHandle, $destFilepath); + + $expandState->currentFileOffset = ftell($destFileHandle); + $expandState->archiveOffset = SnapIO::ftell($archiveHandle); + + $moreGlobstoProcess = $expandState->currentFileOffset < $expandState->currentFileHeader->fileSize; + + if (!$moreGlobstoProcess) { + break; + } + } else { + // rsr todo record fclose error + @fclose($destFileHandle); + $destFileHandle = null; + + if ($expandState->validationType == DupArchiveExpandState::VALIDATION_FULL) { + self::validateExpandedFile($expandState); + } + break; + } + } + + DupArchiveUtil::tlog('Out of glob loop'); + + if ($destFileHandle != null) { + // rsr todo record file close error + @fclose($destFileHandle); + $destFileHandle = null; + } + + if (!$moreGlobstoProcess && $expandState->validateOnly && ($expandState->validationType == DupArchiveExpandState::VALIDATION_FULL)) { + if (!is_writable($destFilepath)) { + SnapIO::chmod($destFilepath, 'u+rw'); + } + if (@unlink($destFilepath) === false) { + // $expandState->addFailure(DupArchiveFailureTypes::File, $destFilepath, "Couldn't delete {$destFilepath} during validation", false); + // TODO: Have to know how to handle this - want to report it but don’t want to mess up validation - + // some non critical errors could be important to validation + } + } + } else { + // 0 length file so just touch it + $moreGlobstoProcess = false; + + if (file_exists($destFilepath)) { + @unlink($destFilepath); + } + + if (touch($destFilepath) === false) { + throw new Exception("Couldn't create {$destFilepath}"); + } + } + + if (!$moreGlobstoProcess) { + self::setFileMode($expandState, $destFilepath); + self::setFileTimes($expandState, $destFilepath); + DupArchiveUtil::tlog('No more globs to process'); + + $expandState->fileWriteCount++; + $expandState->resetForFile(); + } + + return !$moreGlobstoProcess; + } + + /** + * Create directory + * + * @param DupArchiveExpandState $expandState expand state + * @param DupArchiveDirectoryHeader $directoryHeader directory header + * + * @return boolean + */ + public static function createDirectory(DupArchiveExpandState $expandState, DupArchiveDirectoryHeader $directoryHeader) + { + /* @var $expandState DupArchiveExpandState */ + $destDirPath = self::getNewFilePath($expandState->basePath, $directoryHeader->relativePath); + + $mode = $directoryHeader->permissions; + + if ($expandState->directoryModeOverride != -1) { + $mode = $expandState->directoryModeOverride; + } + + if (!SnapIO::dirWriteCheckOrMkdir($destDirPath, $mode, true)) { + $error_message = "Unable to create directory $destDirPath"; + $expandState->addFailure(DupArchiveProcessingFailure::TYPE_DIRECTORY, $directoryHeader->relativePath, $error_message, false); + DupArchiveUtil::tlog($error_message); + return false; + } else { + return true; + } + } + + /** + * Set file mode if is enabled + * + * @param DupArchiveExpandState $expandState dup expand state + * @param string $filePath file path + * + * @return bool + */ + public static function setFileMode(DupArchiveExpandState $expandState, $filePath) + { + if ($expandState->fileModeOverride === -1) { + return; + } + return SnapIO::chmod($filePath, $expandState->fileModeOverride); + } + + /** + * Set original file times if enabled + * + * @param DupArchiveExpandState $expandState dup expand state + * @param string $filePath File path + * + * @return bool true if success, false otherwise + */ + protected static function setFileTimes(DupArchiveExpandState $expandState, $filePath) + { + if (!$expandState->keepFileTime) { + return true; + } + if (!file_exists($filePath)) { + return false; + } + return touch($filePath, $expandState->currentFileHeader->mtime); + } + + /** + * Validate file entry + * + * @param DupArchiveExpandState $expandState dup expand state + * @param resource $archiveHandle dup archive resource + * + * @return bool + */ + public static function standardValidateFileEntry(DupArchiveExpandState $expandState, $archiveHandle) + { + $moreGlobstoProcess = $expandState->currentFileOffset < $expandState->currentFileHeader->fileSize; + + if (!$moreGlobstoProcess) { + // Not a 'real' write but indicates that we actually did fully process a file in the archive + $expandState->fileWriteCount++; + } else { + while ((!$expandState->timedOut()) && $moreGlobstoProcess) { + // Read in the glob header but leave the pointer at the payload + $globHeader = DupArchiveGlobHeader::readFromArchive($archiveHandle, false); + $globContents = fread($archiveHandle, $globHeader->storedSize); + + if ($globContents === false) { + throw new Exception("Error reading glob from archive"); + } + + $hash = hash('crc32b', $globContents); + + if ($hash != $globHeader->hash) { + $expandState->addFailure( + DupArchiveProcessingFailure::TYPE_FILE, + $expandState->currentFileHeader->relativePath, + 'Hash mismatch on DupArchive file entry', + true + ); + DupArchiveUtil::tlog("Glob hash mismatch during standard check of {$expandState->currentFileHeader->relativePath}"); + } else { + // DupArchiveUtil::tlog("Glob MD5 passes"); + } + + $expandState->currentFileOffset += $globHeader->originalSize; + $expandState->archiveOffset = SnapIO::ftell($archiveHandle); + $moreGlobstoProcess = $expandState->currentFileOffset < $expandState->currentFileHeader->fileSize; + + if (!$moreGlobstoProcess) { + $expandState->fileWriteCount++; + $expandState->resetForFile(); + } + } + } + + return !$moreGlobstoProcess; + } + + /** + * Validate file + * + * @param DupArchiveExpandState $expandState dup expand state + * + * @return void + */ + private static function validateExpandedFile(DupArchiveExpandState $expandState) + { + /* @var $expandState DupArchiveExpandState */ + $destFilepath = self::getNewFilePath($expandState->basePath, $expandState->currentFileHeader->relativePath); + + if ($expandState->currentFileHeader->hash !== '00000000000000000000000000000000') { + $hash = hash_file('crc32b', $destFilepath); + + if ($hash !== $expandState->currentFileHeader->hash) { + $expandState->addFailure(DupArchiveProcessingFailure::TYPE_FILE, $destFilepath, "MD5 mismatch for {$destFilepath}", false); + } else { + DupArchiveUtil::tlog('MD5 Match for ' . $destFilepath); + } + } else { + DupArchiveUtil::tlog('MD5 non match is 0\'s'); + } + } + + /** + * Append file to archive + * + * @param DupArchiveCreateState $createState create state + * @param resource $archiveHandle archive resource + * @param resource $sourceFilehandle file resource + * @param string $sourceFilepath file path + * @param int $fileSize file size + * + * @return bool true if more file remaning + */ + private static function appendGlobToArchive( + DupArchiveCreateState $createState, + $archiveHandle, + $sourceFilehandle, + $sourceFilepath, + $fileSize + ) { + DupArchiveUtil::tlog("Appending file glob to archive for file {$sourceFilepath} at file offset {$createState->currentFileOffset}"); + + if ($fileSize == 0) { + return false; + } + + $fileSize -= $createState->currentFileOffset; + $globContents = @fread($sourceFilehandle, $createState->globSize); + + if ($globContents === false) { + throw new Exception("Error reading $sourceFilepath"); + } + + $originalSize = strlen($globContents); + + if ($createState->isCompressed) { + $globContents = gzdeflate($globContents, 2); // 2 chosen as best compromise between speed and size + $storeSize = strlen($globContents); + } else { + $storeSize = $originalSize; + } + + $globHeader = new DupArchiveGlobHeader(); + $globHeader->originalSize = $originalSize; + $globHeader->storedSize = $storeSize; + $globHeader->hash = hash('crc32b', $globContents); + $globHeader->writeToArchive($archiveHandle); + + if (@fwrite($archiveHandle, $globContents) === false) { + // Considered fatal since we should always be able to write to the archive - + // plus the header has already been written (could back this out later though) + throw new Exception( + "Error writing $sourceFilepath to archive. Ensure site still hasn't run out of space.", + DupArchiveEngine::EXCEPTION_FATAL + ); + } + + $fileSizeRemaining = $fileSize - $createState->globSize; + $moreFileRemaining = $fileSizeRemaining > 0; + + return $moreFileRemaining; + } + + /** + * Append file in dup archvie from source string + * + * @param DupArchiveCreateState $createState create state + * @param resource $archiveHandle archive handle + * @param string $src source to add + * @param int $forceSize if 0 size is auto of content is filled of \0 char to size + * + * @return bool + */ + private static function appendFileSrcToArchive( + DupArchiveCreateState $createState, + $archiveHandle, + $src, + $forceSize = 0 + ) { + DupArchiveUtil::tlog("Appending file glob to archive from src"); + + if (($originalSize = strlen($src)) == 0 && $forceSize == 0) { + return false; + } + + if ($forceSize == 0 && $createState->isCompressed) { + $src = gzdeflate($src, 2); // 2 chosen as best compromise between speed and size + $storeSize = strlen($src); + } else { + $storeSize = $originalSize; + } + + if ($forceSize > 0 && $storeSize < $forceSize) { + $charsToAdd = $forceSize - $storeSize; + $src .= str_repeat("\0", $charsToAdd); + $storeSize = $forceSize; + } + + $globHeader = new DupArchiveGlobHeader(); + $globHeader->originalSize = $originalSize; + $globHeader->storedSize = $storeSize; + $globHeader->hash = hash('crc32b', $src); + $globHeader->writeToArchive($archiveHandle); + + + if (SnapIO::fwriteChunked($archiveHandle, $src) === false) { + // Considered fatal since we should always be able to write to the archive - + // plus the header has already been written (could back this out later though) + throw new Exception( + "Error writing SRC to archive. Ensure site still hasn't run out of space.", + DupArchiveEngine::EXCEPTION_FATAL + ); + } + + return true; + } + + /** + * Extract file from dup archive + * Assumption is that archive handle points to a glob header on this call + * + * @param DupArchiveExpandState $expandState dup archive expand state + * @param resource $archiveHandle archvie resource + * @param resource $destFileHandle file resource + * @param string $destFilePath file path + * + * @return void + */ + private static function appendGlobToFile( + DupArchiveExpandState $expandState, + $archiveHandle, + $destFileHandle, + $destFilePath + ) { + DupArchiveUtil::tlog('Appending file glob to file ' . $destFilePath . ' at file offset ' . $expandState->currentFileOffset); + + // Read in the glob header but leave the pointer at the payload + $globHeader = DupArchiveGlobHeader::readFromArchive($archiveHandle, false); + if (($globContents = DupArchiveGlobHeader::readContent($archiveHandle, $globHeader, $expandState->archiveHeader->isCompressed)) === false) { + throw new Exception("Error reading glob from $destFilePath"); + } + + if (@fwrite($destFileHandle, $globContents) === false) { + throw new Exception("Error writing glob to $destFilePath"); + } else { + DupArchiveUtil::tlog('Successfully wrote glob'); + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveProcessingFailure.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveProcessingFailure.php new file mode 100644 index 0000000..7f124f8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Processors/DupArchiveProcessingFailure.php @@ -0,0 +1,24 @@ + fullNewPath */ + public $fileRenames = array(); + public $directoryModeOverride = -1; + public $fileModeOverride = -1; + public $lastHeaderOffset = -1; + /** @var bool */ + public $keepFileTime = false; + + /** + * Reset state for file + * + * @return void + */ + public function resetForFile() + { + $this->currentFileHeader = null; + $this->currentFileOffset = 0; + } + + /** + * save expand state + * + * @return void + */ + abstract public function save(); +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/States/DupArchiveSimpleCreateState.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/States/DupArchiveSimpleCreateState.php new file mode 100644 index 0000000..1f88611 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/States/DupArchiveSimpleCreateState.php @@ -0,0 +1,34 @@ +currentDirectoryIndex = 0; + $this->currentFileIndex = 0; + $this->currentFileOffset = 0; + } + + /** + * Save state + * + * @return void + */ + public function save() + { + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/States/DupArchiveSimpleExpandState.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/States/DupArchiveSimpleExpandState.php new file mode 100644 index 0000000..657af8a --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/States/DupArchiveSimpleExpandState.php @@ -0,0 +1,31 @@ +failures) > 0) { + foreach ($this->failures as $failure) { + if ($failure->isCritical) { + return true; + } + } + } + + return false; + } + + /** + * Che failure summary + * + * @param boolean $includeCritical include critical failures + * @param boolean $includeWarnings include warnings failures + * + * @return string + */ + public function getFailureSummary($includeCritical = true, $includeWarnings = false) + { + if (count($this->failures) > 0) { + $message = ''; + + foreach ($this->failures as $failure) { + if ($includeCritical || !$failure->isCritical) { + $message .= "\n" . $this->getFailureString($failure); + } + } + + return $message; + } else { + if ($includeCritical) { + if ($includeWarnings) { + return 'No errors or warnings.'; + } else { + return 'No errors.'; + } + } else { + return 'No warnings.'; + } + } + } + + /** + * Return failure string from item + * + * @param DupArchiveProcessingFailure $failure failure item + * + * @return string + */ + public function getFailureString(DupArchiveProcessingFailure $failure) + { + $s = ''; + + if ($failure->isCritical) { + $s = 'CRITICAL: '; + } + + return "{$s}{$failure->subject} : {$failure->description}"; + } + + /** + * Add failure item + * + * @param int $type failure type enum + * @param string $subject failure subject + * @param string $description failure description + * @param boolean $isCritical true if is critical + * + * @return DupArchiveProcessingFailure + */ + public function addFailure($type, $subject, $description, $isCritical = true) + { + $this->failureCount++; + if ($this->failureCount > self::MAX_FAILURE) { + return false; + } + + $failure = new DupArchiveProcessingFailure(); + + $failure->type = $type; + $failure->subject = $subject; + $failure->description = $description; + $failure->isCritical = $isCritical; + + $this->failures[] = $failure; + + return $failure; + } + + /** + * Set start time + * + * @return void + */ + public function startTimer() + { + if ($this->timerEnabled) { + $this->timeoutTimestamp = time() + $this->timeSliceInSecs; + } + } + + /** + * Check if is timeout + * + * @return bool + */ + public function timedOut() + { + if ($this->timerEnabled) { + if ($this->timeoutTimestamp != -1) { + return time() >= $this->timeoutTimestamp; + } else { + return false; + } + } else { + return false; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Utils/DupArchiveScanUtil.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Utils/DupArchiveScanUtil.php new file mode 100644 index 0000000..2a1a23c --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Utils/DupArchiveScanUtil.php @@ -0,0 +1,96 @@ +Dirs = DupArchiveUtil::expandDirectories($sourceDirectory, true); + $scan->Files = DupArchiveUtil::expandFiles($sourceDirectory, true); + + return $scan; + } + + /** + * Scan folder and add result to scan file + * + * @param string $scanFilepath scan file + * @param string $sourceDirectory folder to scan + * + * @return void + */ + public static function createScan($scanFilepath, $sourceDirectory) + { + DupArchiveUtil::tlog("Creating scan"); + + $scan = self::createScanObject($sourceDirectory); + $scan_handle = fopen($scanFilepath, 'w'); + + if ($scan_handle === false) { + echo "Couldn't create scan file"; + die(); + } + + $jsn = SnapJson::jsonEncode($scan); + + fwrite($scan_handle, $jsn); + return $scan; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Utils/DupArchiveUtil.php b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Utils/DupArchiveUtil.php new file mode 100644 index 0000000..32153ee --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/DupArchive/Utils/DupArchiveUtil.php @@ -0,0 +1,165 @@ +log($s, $flush, $callingFunctionName); + } else { + // throw new Exception('Logging object not initialized'); + } + } + + /** + * Write trace log + * + * @param string $s log string + * @param boolean $flush if true flosh name + * @param string $callingFunctionName function has called log + * + * @return void + */ + public static function tlog($s, $flush = false, $callingFunctionName = null) + { + if (self::$TRACE_ON) { + if ($callingFunctionName === null) { + $callingFunctionName = SnapUtil::getCallingFunctionName(); + } + + self::log("####{$s}", $flush, $callingFunctionName); + } + } + + /** + * Write object in trace log + * + * @param string $s log string + * @param mixed $o value to write in log + * @param boolean $flush if true flosh name + * @param string $callingFunctionName function has called log + * + * @return void + */ + public static function tlogObject($s, $o, $flush = false, $callingFunctionName = null) + { + if (is_object($o)) { + $o = get_object_vars($o); + } + + $ostring = print_r($o, true); + + if ($callingFunctionName === null) { + $callingFunctionName = SnapUtil::getCallingFunctionName(); + } + + self::tlog($s, $flush, $callingFunctionName); + self::tlog($ostring, $flush, $callingFunctionName); + } + + /** + * Write object in log + * + * @param string $s log string + * @param mixed $o value to write in log + * @param boolean $flush if true flosh name + * @param string $callingFunctionName function has called log + * + * @return void + */ + public static function logObject($s, $o, $flush = false, $callingFunctionName = null) + { + $ostring = print_r($o, true); + + if ($callingFunctionName === null) { + $callingFunctionName = SnapUtil::getCallingFunctionName(); + } + + self::log($s, $flush, $callingFunctionName); + self::log($ostring, $flush, $callingFunctionName); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/OneClickUpgrade/UpgraderSkin.php b/html/wp-content/plugins/duplicator/src/Libs/OneClickUpgrade/UpgraderSkin.php new file mode 100644 index 0000000..90cf5d4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/OneClickUpgrade/UpgraderSkin.php @@ -0,0 +1,118 @@ +upgrader =& $upgrader; + } + } + + /** + * Set the upgrader result and store it as a property in the parent class. + * + * @since 1.5.13 + * + * @param object $result The result of the install process. + * + * @return void + */ + public function set_result($result) + { + $this->result = $result; + } + + /** + * Empty out the header of its HTML content and only check to see if it has + * been performed or not. + * + * @since 1.5.13 + * + * @return void + */ + public function header() + { + } + + /** + * Empty out the footer of its HTML contents. + * + * @since 1.5.13 + * + * @return void + */ + public function footer() + { + } + + /** + * Instead of outputting HTML for errors, send proper WordPress AJAX error response. + * + * @since 1.5.13 + * + * @param array $errors Array of errors with the install process. + * + * @return void + */ + public function error($errors) + { + if (!empty($errors)) { + wp_send_json_error(array('message' => esc_html__('There was an error installing the upgrade. Please try again.', 'duplicator'))); + } + } + + /** + * Empty out the feedback method to prevent outputting HTML strings as the install + * is progressing. + * + * @since 1.5.13 + * + * @param string $string The feedback string. + * @param mixed ...$args Additional arguments. + * + * @return void + */ + public function feedback($string, ...$args) + { + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/FunctionalityCheck.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/FunctionalityCheck.php new file mode 100644 index 0000000..f535714 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/FunctionalityCheck.php @@ -0,0 +1,161 @@ +type = $type; + break; + default: + throw new Exception('Invalid item type'); + } + + if (strlen($key) == 0) { + throw new Exception('Key can\'t be empty'); + } + $this->required = $required; + $this->itemKey = (string) $key; + $this->link = (string) $link; + $this->troubleshoot = (string) $troubleshoot; + } + + /** + * Get the value of type + * + * @return int + */ + public function getType() + { + return $this->type; + } + + /** + * Get the value of itemKey + * + * @return string + */ + public function getItemKey() + { + return $this->itemKey; + } + + /** + * true if is required + * + * @return bool + */ + public function isRequired() + { + return $this->required; + } + + /** + * Check if item exists + * + * @return bool + */ + public function check() + { + $result = false; + + switch ($this->type) { + case self::TYPE_FUNCTION: + $result = function_exists($this->itemKey); + break; + case self::TYPE_CLASS: + $result = SnapUtil::classExists($this->itemKey); + break; + default: + throw new Exception('Invalid item type'); + } + + if ($result == false && is_callable($this->failCallback)) { + call_user_func($this->failCallback, $this); + } + return $result; + } + + /** + * Set the value of failCallback + * + * @param callable $failCallback fail callback function + * + * @return void + */ + public function setFailCallback($failCallback) + { + $this->failCallback = $failCallback; + } + + /** + * Check all Functionalities in list + * + * @param self[] $funcs Functionalities list + * @param bool $requiredOnly if true skip functs not required + * @param self[] $notPassList list of items that not have pass the test + * + * @return bool + */ + public static function checkList($funcs, $requiredOnly = false, &$notPassList = array()) + { + if (!is_array($funcs)) { + throw new Exception('funcs must be an array'); + } + + $notPassList = array(); + + foreach ($funcs as $func) { + if ($requiredOnly && !$func->isRequired()) { + continue; + } + + if ($func->check() === false) { + $notPassList[] = $func; + } + } + + return (count($notPassList) === 0); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/JsonSerializable.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/JsonSerializable.php new file mode 100644 index 0000000..238466f --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/JsonSerializable.php @@ -0,0 +1,30 @@ + $reflect->name); + } + + if (method_exists($obj, '__sleep')) { + $includeProps = $obj->__sleep(); + if (!is_array($includeProps)) { + throw new Exception('__sleep method must return an array'); + } + } else { + $includeProps = true; + } + + // Get all props of current class but not props private of parent class and static props + foreach ($reflect->getProperties() as $prop) { + if ($prop->isStatic()) { + continue; + } + $propName = $prop->getName(); + if ($includeProps !== true && !in_array($propName, $includeProps)) { + continue; + } + $prop->setAccessible(true); + $propValue = $prop->getValue($obj); + $result[$propName] = self::valueToJsonData($propValue, $flags, $objParents); + } + + return $result; + } + + /** + * Recursive parse values, all objects are transformed to array + * + * @param mixed $value valute to parse + * @param int $flags flags bitmask + * @param string[] $objParents objs parents unique hash ids + * + * @return mixed + */ + final public static function valueToJsonData($value, $flags = 0, $objParents = array()) + { + switch (gettype($value)) { + case "boolean": + case "integer": + case "double": + case "string": + case "NULL": + return $value; + case "array": + $result = array(); + foreach ($value as $key => $arrayVal) { + $result[$key] = self::valueToJsonData($arrayVal, $flags, $objParents); + } + return $result; + case "object": + $objHash = spl_object_hash($value); + if (in_array($objHash, $objParents)) { + // prevent infinite recursion loop + return null; + } + $objParents[] = $objHash; + return self::objectToJsonData($value, $flags, $objParents); + case "resource": + case "resource (closed)": + case "unknown type": + default: + return null; + } + } + + /** + * Return value from json decoded data + * + * @param mixed $value json decoded data + * + * @return mixed + */ + final protected static function jsonDataToValue($value) + { + switch (gettype($value)) { + case 'array': + if (($newClassName = self::getClassFromArray($value)) === false) { + $result = array(); + foreach ($value as $key => $arrayVal) { + $result[$key] = self::jsonDataToValue($arrayVal); + } + } else { + $result = self::fillObjFromValue($value, self::getObjFromClass($newClassName)); + } + return $result; + case 'boolean': + case 'integer': + case 'double': + case 'string': + case "NULL": + return $value; + default: + return null; + } + } + + /** + * Get object from class name, if class don't exists return StdClass. + * With PHP 5.4.0 the object is intialized without call the constructor. + * + * @param string $class class name + * + * @return object + */ + final protected static function getObjFromClass($class) + { + if (class_exists($class)) { + if (version_compare(PHP_VERSION, '5.4.0') >= 0) { + $classReflect = new ReflectionClass($class); + return $classReflect->newInstanceWithoutConstructor(); + } else { + return new $class(); + } + } else { + return new \StdClass(); + } + } + + /** + * Fill passed object from array values + * + * @param array $value value from json data + * @param object $obj object to fill with json data + * + * @return object + */ + final protected static function fillObjFromValue($value, $obj) + { + if ($obj instanceof \stdClass) { + foreach ($value as $arrayProp => $arrayValue) { + if ($arrayProp == self::CLASS_KEY_FOR_JSON_SERIALIZE) { + continue; + } + $obj->{$arrayProp} = self::jsonDataToValue($arrayValue); + } + } else { + $reflect = new ReflectionObject($obj); + foreach ($reflect->getProperties() as $prop) { + $prop->setAccessible(true); + $propName = $prop->getName(); + if (!isset($value[$propName]) || $prop->isStatic()) { + continue; + } + $prop->setValue($obj, self::jsonDataToValue($value[$propName])); + } + + if (method_exists($obj, '__wakeup')) { + $obj->__wakeup(); + } + } + return $obj; + } + + /** + * Return class name from array values + * + * @param array $array array data + * + * @return bool|string false if prop not found + */ + final protected static function getClassFromArray($array) + { + return (isset($array[self::CLASS_KEY_FOR_JSON_SERIALIZE]) ? $array[self::CLASS_KEY_FOR_JSON_SERIALIZE] : false); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/JsonSerialize/JsonSerialize.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/JsonSerialize/JsonSerialize.php new file mode 100644 index 0000000..1bc9ccb --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/JsonSerialize/JsonSerialize.php @@ -0,0 +1,83 @@ +=') ? json_decode($json, true, $depth, $flags) : json_decode($json, true, $depth) + ); + return self::jsonDataToValue($publicArray); + } + + /** + * Unserialize json on passed object + * + * @param string $json json string + * @param object|string $obj object to fill or class name + * @param integer $depth json_decode depth + * @param integer $flags json_decode flags + * + * @link https://www.php.net/manual/en/function.json-decode.php + * + * @return object + */ + public static function unserializeToObj($json, $obj, $depth = 512, $flags = 0) + { + if (is_object($obj)) { + } elseif (is_string($obj) && class_exists($obj)) { + $obj = self::getObjFromClass($obj); + } else { + throw new Exception('invalid obj param'); + } + // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.json_decode_optionsFound + $value = (version_compare(PHP_VERSION, '5.4', '>=') ? json_decode($json, true, $depth, $flags) : json_decode($json, true, $depth) + ); + if (!is_array($value)) { + throw new Exception('json value isn\'t an array VALUE: ' . SnapLog::v2str($value)); + } + return self::fillObjFromValue($value, $obj); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/Snap32BitSizeLimitException.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/Snap32BitSizeLimitException.php new file mode 100644 index 0000000..673f4dd --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/Snap32BitSizeLimitException.php @@ -0,0 +1,13 @@ + */ + private static $cache = array(); + + /** + * Return array if primary key is composite key + * + * @param mysqli|resource $dbh database connection + * @param string $tableName table name + * @param null|callable $logCallback log callback + * + * @return false|string|string[] return unique index column ky or false if don't exists + */ + public static function getUniqueIndexColumn($dbh, $tableName, $logCallback = null) + { + $cacheKey = self::CACHE_PREFIX_PRIMARY_KEY_COLUMN . $tableName; + + if (!isset(self::$cache[$cacheKey])) { + $query = 'SHOW COLUMNS FROM `' . self::realEscapeString($dbh, $tableName) . '` WHERE `Key` IN ("PRI","UNI")'; + if (($result = self::query($dbh, $query)) === false) { + if (is_callable($logCallback)) { + call_user_func($logCallback, $dbh, $result, $query); + } + throw new \Exception('SHOW KEYS QUERY ERROR: ' . self::error($dbh)); + } + + if (is_callable($logCallback)) { + call_user_func($logCallback, $dbh, $result, $query); + } + + if (self::numRows($result) == 0) { + self::$cache[$cacheKey] = false; + } else { + $primary = false; + $excludePrimary = false; + $unique = false; + + while ($row = self::fetchAssoc($result)) { + switch ($row['Key']) { + case 'PRI': + if ($primary === false) { + $primary = $row['Field']; + } else { + if (is_scalar($primary)) { + $primary = array($primary); + } + $primary[] = $row['Field']; + } + + if (preg_match('/^(?:var)?binary/i', $row['Type'])) { + // exclude binary or varbynary columns + $excludePrimary = true; + } + break; + case 'UNI': + if (!preg_match('/^(?:var)?binary/i', $row['Type'])) { + // exclude binary or varbynary columns + $unique = $row['Field']; + } + break; + default: + break; + } + } + if ($primary !== false && $excludePrimary === false) { + self::$cache[$cacheKey] = $primary; + } elseif ($unique !== false) { + self::$cache[$cacheKey] = $unique; + } else { + self::$cache[$cacheKey] = false; + } + } + self::freeResult($result); + } + + return self::$cache[$cacheKey]; + } + + /** + * Escape the regex for mysql queries, the mysqli_real_escape must be applied anyway to the generated string + * + * @param string $regex Regex + * + * @return string Escaped regex + */ + public static function quoteRegex($regex) + { + // preg_quote takes a string and escapes special characters with a backslash. + // It is meant for PHP regexes, not MySQL regexes, and it does not escape &, + // which is needed for MySQL. So we only need to modify it like so: + // https://stackoverflow.com/questions/3782379/whats-the-best-way-to-escape-user-input-for-regular-expressions-in-mysql + return preg_replace('/&/', '\\&', preg_quote($regex, null /* no delimiter */)); + } + + /** + * Returns the offset from the current row + * + * @param mixed[] $row current database row + * @param int|string|string[] $indexColumns columns of the row that generated the index offset + * @param mixed $lastOffset last offset + * + * @return mixed + */ + public static function getOffsetFromRowAssoc($row, $indexColumns, $lastOffset) + { + if (is_array($indexColumns)) { + $result = array(); + foreach ($indexColumns as $col) { + $result[$col] = isset($row[$col]) ? $row[$col] : 0; + } + return $result; + } elseif (strlen($indexColumns) > 0) { + return isset($row[$indexColumns]) ? $row[$indexColumns] : 0; + } else { + if (is_scalar($lastOffset)) { + return $lastOffset + 1; + } else { + return $lastOffset; + } + } + } + + /** + * This function performs a select by structuring the primary key as offset if the table has a primary key. + * For optimization issues, no checks are performed on the input query and it is assumed that the select has at least a where value. + * If there are no conditions, you still have to perform an always true condition, for example + * SELECT * FROM `copy1_postmeta` WHERE 1 + * + * @param mysqli|resource $dbh database connection + * @param string $query query string + * @param string $table table name + * @param int $offset row offset + * @param int $limit limit of query, 0 no limit + * @param mixed $lastRowOffset last offset to use on next function call + * @param null|callable $logCallback log callback + * + * @return mysqli_result + */ + public static function selectUsingPrimaryKeyAsOffset($dbh, $query, $table, $offset, $limit, &$lastRowOffset = null, $logCallback = null) + { + $where = ''; + $orderby = ''; + $offsetStr = ''; + $limitStr = $limit > 0 ? ' LIMIT ' . $limit : ''; + + if (($primaryColumn = self::getUniqueIndexColumn($dbh, $table, $logCallback)) == false) { + $offsetStr = ' OFFSET ' . (is_scalar($offset) ? $offset : 0); + } else { + if (is_array($primaryColumn)) { + // COMPOSITE KEY + $orderByCols = array(); + foreach ($primaryColumn as $colIndex => $col) { + $orderByCols[] = '`' . $col . '` ASC'; + } + $orderby = ' ORDER BY ' . implode(',', $orderByCols); + } else { + $orderby = ' ORDER BY `' . $primaryColumn . '` ASC'; + } + $where = self::getOffsetKeyCondition($dbh, $primaryColumn, $offset); + } + $query .= $where . $orderby . $limitStr . $offsetStr; + + if (($result = self::query($dbh, $query)) === false) { + if (is_callable($logCallback)) { + call_user_func($logCallback, $dbh, $result, $query); + } + throw new \Exception('SELECT ERROR: ' . self::error($dbh) . ' QUERY: ' . $query); + } + + if (is_callable($logCallback)) { + call_user_func($logCallback, $dbh, $result, $query); + } + + if (self::dbConnTypeByResult($result) === self::CONN_MYSQLI) { + if ($primaryColumn == false) { + $lastRowOffset = $offset + $result->num_rows; + } else { + if ($result->num_rows == 0) { + $lastRowOffset = $offset; + } else { + $result->data_seek(($result->num_rows - 1)); + $row = $result->fetch_assoc(); + if (is_array($primaryColumn)) { + $lastRowOffset = array(); + foreach ($primaryColumn as $col) { + $lastRowOffset[$col] = $row[$col]; + } + } else { + $lastRowOffset = $row[$primaryColumn]; + } + $result->data_seek(0); + } + } + } else { + if ($primaryColumn == false) { + $lastRowOffset = $offset + mysql_num_rows($result); // @phpstan-ignore-line + } else { + if (mysql_num_rows($result) == 0) { // @phpstan-ignore-line + $lastRowOffset = $offset; + } else { + mysql_data_seek($result, (mysql_num_rows($result) - 1)); // @phpstan-ignore-line + $row = mysql_fetch_assoc($result); // @phpstan-ignore-line + if (is_array($primaryColumn)) { + $lastRowOffset = array(); + foreach ($primaryColumn as $col) { + $lastRowOffset[$col] = $row[$col]; + } + } else { + $lastRowOffset = $row[$primaryColumn]; + } + mysql_data_seek($result, 0); // @phpstan-ignore-line + } + } + } + + return $result; + } + + /** + * Depending on the structure type of the primary key returns the condition to position at the right offset + * + * @param mysqli|resource $dbh database connection + * @param string|string[] $primaryColumn primaricolumng index + * @param mixed $offset offset + * + * @return string + */ + protected static function getOffsetKeyCondition($dbh, $primaryColumn, $offset) + { + $condition = ''; + + if ($offset === 0) { + return ''; + } + + // COUPOUND KEY + if (is_array($primaryColumn)) { + $isFirstCond = true; + + foreach ($primaryColumn as $colIndex => $col) { + if (is_array($offset) && isset($offset[$col])) { + if ($isFirstCond) { + $isFirstCond = false; + } else { + $condition .= ' OR '; + } + $condition .= ' ('; + for ($prevColIndex = 0; $prevColIndex < $colIndex; $prevColIndex++) { + $condition .= + ' `' . $primaryColumn[$prevColIndex] . '` = "' . + self::realEscapeString($dbh, $offset[$primaryColumn[$prevColIndex]]) . '" AND '; + } + $condition .= ' `' . $col . '` > "' . self::realEscapeString($dbh, $offset[$col]) . '")'; + } + } + } else { + $condition = '`' . $primaryColumn . '` > "' . self::realEscapeString($dbh, (is_scalar($offset) ? $offset : 0)) . '"'; + } + + return (strlen($condition) ? ' AND (' . $condition . ')' : ''); + } + + /** + * get current database engine (mysql, maria, percona) + * + * @param mysqli|resource $dbh database connection + * + * @return string + */ + public static function getDBEngine($dbh) + { + if (($result = self::query($dbh, "SHOW VARIABLES LIKE 'version%'")) === false) { + // on query error assume is mysql. + return self::DB_ENGINE_MYSQL; + } + + $rows = array(); + while ($row = self::fetchRow($result)) { + $rows[] = $row; + } + self::freeResult($result); + + $version = isset($rows[0][1]) ? $rows[0][1] : false; + $versionComment = isset($rows[1][1]) ? $rows[1][1] : false; + + //Default is mysql + if ($version === false && $versionComment === false) { + return self::DB_ENGINE_MYSQL; + } + + if (stripos($version, 'maria') !== false || stripos($versionComment, 'maria') !== false) { + return self::DB_ENGINE_MARIA; + } + + if (stripos($version, 'percona') !== false || stripos($versionComment, 'percona') !== false) { + return self::DB_ENGINE_PERCONA; + } + + return self::DB_ENGINE_MYSQL; + } + + /** + * Escape string + * + * @param resource|mysqli $dbh database connection + * @param string $string string to escape + * + * @return string Returns an escaped string. + */ + public static function realEscapeString($dbh, $string) + { + if (self::dbConnType($dbh) === self::CONN_MYSQLI) { + return mysqli_real_escape_string($dbh, $string); + } else { + return mysql_real_escape_string($string, $dbh); // @phpstan-ignore-line + } + } + + /** + * + * @param resource|mysqli $dbh database connection + * @param string $query query string + * + * @return mixed

        Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or + * EXPLAIN queries mysqli_query() will return a mysqli_result object. + * For other successful queries mysqli_query() will return TRUE.

        + */ + public static function query($dbh, $query) + { + try { + if (self::dbConnType($dbh) === self::CONN_MYSQLI) { + return mysqli_query($dbh, $query); + } else { + return mysql_query($query, $dbh); // @phpstan-ignore-line + } + } catch (Exception $e) { + return false; + } + } + + /** + * + * @param resource|mysqli_result $result query result + * + * @return int + */ + public static function numRows($result) + { + if (self::dbConnTypeByResult($result) === self::CONN_MYSQLI) { + return $result->num_rows; + } else { + return mysql_num_rows($result); // @phpstan-ignore-line + } + } + + /** + * + * @param resource|mysqli_result $result query result + * + * @return string[]|null|false Returns an array of strings that corresponds to the fetched row. NULL if there are no more rows in result set + */ + public static function fetchRow($result) + { + if (self::dbConnTypeByResult($result) === self::CONN_MYSQLI) { + return mysqli_fetch_row($result); + } elseif (is_resource($result)) { + return mysql_fetch_row($result); // @phpstan-ignore-line + } else { + return false; + } + } + + /** + * + * @param resource|mysqli_result $result query result + * + * @return string[]|null|false Returns an associative array of values representing the fetched row in the result set, + * where each key in the array represents the name of one of the result set's + * columns or null if there are no more rows in result set. + */ + public static function fetchAssoc($result) + { + if (self::dbConnTypeByResult($result) === self::CONN_MYSQLI) { + return mysqli_fetch_assoc($result); + } elseif (is_resource($result)) { + return mysql_fetch_assoc($result); // @phpstan-ignore-line + } else { + return false; + } + } + + /** + * + * @param resource|mysqli_result $result query result + * + * @return boolean + */ + public static function freeResult($result) + { + if (self::dbConnTypeByResult($result) === self::CONN_MYSQLI) { + $result->free(); + return true; + } elseif (is_resource($result)) { + return mysql_free_result($result); // @phpstan-ignore-line + } else { + $result = null; + return true; + } + } + + /** + * + * @param resource|mysqli $dbh database connection + * + * @return string + */ + public static function error($dbh) + { + if (self::dbConnType($dbh) === self::CONN_MYSQLI) { + if ($dbh instanceof mysqli) { + return mysqli_error($dbh); + } else { + return 'Unable to retrieve the error message from MySQL'; + } + } else { + if (is_resource($dbh)) { + return mysql_error($dbh); // @phpstan-ignore-line + } else { + return 'Unable to retrieve the error message from MySQL'; + } + } + } + + /** + * + * @param resource|mysqli $dbh database connection + * + * @return string // self::CONN_MYSQLI|self::CONN_MYSQL + */ + public static function dbConnType($dbh) + { + return (is_object($dbh) && get_class($dbh) == 'mysqli') ? self::CONN_MYSQLI : self::CONN_MYSQL; + } + + /** + * + * @param resource|mysqli_result $result query resyult + * + * @return string Enum self::CONN_MYSQLI|self::CONN_MYSQL + */ + public static function dbConnTypeByResult($result) + { + return (is_object($result) && get_class($result) == 'mysqli_result') ? self::CONN_MYSQLI : self::CONN_MYSQL; + } + + /** + * This function takes in input the values of a multiple inster with this format + * (v1, v2, v3 ...),(v1, v2, v3, ...),... + * and returns a two dimensional array where each item is a row containing the list of values + * [ + * [v1, v2, v3 ...], + * [v1, v2, v3 ...], + * ... + * ] + * The return values are not processed but are taken exactly as they are in the dump file. + * So if they are escaped it remains unchanged + * + * @param string $query query values + * + * @return array> + */ + public static function getValuesFromQueryInsert($query) + { + $result = array(); + $isItemOpen = false; + $isStringOpen = false; + $char = ''; + $pChar = ''; + + $currentItem = array(); + $currentValue = ''; + + for ($i = 0; $i < strlen($query); $i++) { + $pChar = $char; + $char = $query[$i]; + + switch ($char) { + case '(': + if ($isItemOpen == false && !$isStringOpen) { + $isItemOpen = true; + continue 2; + } + break; + case ')': + if ($isItemOpen && !$isStringOpen) { + $isItemOpen = false; + $currentItem[] = trim($currentValue); + $currentValue = ''; + $result[] = $currentItem; + $currentItem = array(); + continue 2; + } + break; + case '\'': + case '"': + if ($isStringOpen === false && $pChar !== '\\') { + $isStringOpen = $char; + } elseif ($isStringOpen === $char && $pChar !== '\\') { + $isStringOpen = false; + } + break; + case ',': + if ($isItemOpen == false) { + continue 2; + } elseif ($isStringOpen === false) { + $currentItem[] = trim($currentValue); + $currentValue = ''; + continue 2; + } + break; + default: + break; + } + + if ($isItemOpen == false) { + continue; + } + + $currentValue .= $char; + } + return $result; + } + + /** + * This is the inverse of getValuesFromQueryInsert, from an array of values it returns the valody of an insert query + * + * @param mixed[] $values rows values + * + * @return string + */ + public static function getQueryInsertValuesFromArray(array $values) + { + + return implode( + ',', + array_map( + function ($rowVals) { + return '(' . implode(',', $rowVals) . ')'; + }, + $values + ) + ); + } + + /** + * Returns the content of a value resulting from getValuesFromQueryInsert in string + * Then remove the outer quotes and escape + * "value\"test" become value"test + * + * @param string $value value + * + * @return string + */ + public static function parsedQueryValueToString($value) + { + $result = preg_replace('/^[\'"]?(.*?)[\'"]?$/s', '$1', $value); + return stripslashes($result); + } + + /** + * Returns the content of a value resulting from getValuesFromQueryInsert in int + * Then remove the outer quotes and escape + * "100" become (int)100 + * + * @param string $value value + * + * @return int + */ + public static function parsedQueryValueToInt($value) + { + return (int) preg_replace('/^[\'"]?(.*?)[\'"]?$/s', '$1', $value); + } + + /** + * Return the list of mysqlrealconnect existing flags values from mask + * + * @see https://www.php.net/manual/en/mysqli.real-connect.php + * + * @param bool $returnStr if true return define string else values + * @param null|int[] $filter if not null only the values that exist and are contained in the array are returned + * + * @return int[]|string[] + */ + public static function getMysqlConnectFlagsList($returnStr = true, $filter = null) + { + static $flagsList = null; + + if (is_null($flagsList)) { + $flagsList = array(); + + if (defined('MYSQLI_CLIENT_COMPRESS')) { + $flagsList[MYSQLI_CLIENT_COMPRESS] = 'MYSQLI_CLIENT_COMPRESS'; + } + if (defined('MYSQLI_CLIENT_FOUND_ROWS')) { + $flagsList[MYSQLI_CLIENT_FOUND_ROWS] = 'MYSQLI_CLIENT_FOUND_ROWS'; + } + if (defined('MYSQLI_CLIENT_IGNORE_SPACE')) { + $flagsList[MYSQLI_CLIENT_IGNORE_SPACE] = 'MYSQLI_CLIENT_IGNORE_SPACE'; + } + if (defined('MYSQLI_CLIENT_INTERACTIVE')) { + $flagsList[MYSQLI_CLIENT_INTERACTIVE] = 'MYSQLI_CLIENT_INTERACTIVE'; + } + if (defined('MYSQLI_CLIENT_SSL')) { + $flagsList[MYSQLI_CLIENT_SSL] = 'MYSQLI_CLIENT_SSL'; + } + if (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT')) { + // phpcs:ignore PHPCompatibility.Constants.NewConstants.mysqli_client_ssl_dont_verify_server_certFound + $flagsList[MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT] = 'MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT'; + } + } + + if (is_null($filter)) { + $result = $flagsList; + } else { + $result = array(); + foreach ($flagsList as $flagVal => $flag) { + if (!in_array($flagVal, $filter)) { + continue; + } + $result[$flagVal] = $flag; + } + } + + if ($returnStr) { + return array_values($result); + } else { + return array_keys($result); + } + } + + /** + * Return the list of mysqlrealconnect flags values from mask + * + * @see https://www.php.net/manual/en/mysqli.real-connect.php + * + * @param int $value mask value + * + * @return int[] + */ + public static function getMysqlConnectFlagsFromMaskVal($value) + { + /* + MYSQLI_CLIENT_COMPRESS 32 + MYSQLI_CLIENT_FOUND_ROWS 2 + MYSQLI_CLIENT_IGNORE_SPACE 256 + MYSQLI_CLIENT_INTERACTIVE 1024 + MYSQLI_CLIENT_SSL 2048 + MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT 64 + */ + + $result = array(); + + foreach (self::getMysqlConnectFlagsList(false) as $flagVal) { + if (($value & $flagVal) > 0) { + $result[] = $flagVal; + } + } + + return $result; + } + + /** + * Returns a list of redundant case insensitive duplicate tables + * + * @param string $prefix The WP table prefix + * @param string[] $duplicates List of case insensitive duplicate table names + * + * @return string[] + */ + public static function getRedundantDuplicateTables($prefix, $duplicates) + { + //core tables are not redundant, check with priority + foreach (SnapWP::getSiteCoreTables() as $coreTable) { + if (($k = array_search($prefix . $coreTable, $duplicates)) !== false) { + unset($duplicates[$k]); + return array_values($duplicates); + } + } + + foreach ($duplicates as $i => $tableName) { + if (stripos($tableName, $prefix) === 0) { + //table has prefix, the case sensitive match is not redundant + if (strpos($tableName, $prefix) === 0) { + unset($duplicates[$i]); + break; + } + + //no case sensitive match is present, first table is not redundant + if ($i === (count($duplicates) - 1)) { + unset($duplicates[0]); + break; + } + } else { + //no prefix present, first table not redundant + unset($duplicates[$i]); + break; + } + } + + return array_values($duplicates); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapIO.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapIO.php new file mode 100644 index 0000000..27f60f7 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapIO.php @@ -0,0 +1,1785 @@ + $args array key/val where key is the var name in include + * @param bool $required if true is required + * + * @return string + * + * @throws Exception // thorw exception if is $required and file can't be read + */ + public static function getInclude($path, $args = array(), $required = true) + { + if (!is_readable($path)) { + if ($required) { + throw new Exception('Can\'t read required file ' . $path); + } else { + return ''; + } + } + + foreach ($args as $var => $value) { + ${$var} = $value; + } + + ob_start(); + if ($required) { + require($path); + } else { + include($path); + } + return ob_get_clean(); + } + + /** + * Copy file + * + * @param string $source source path + * @param string $dest detination path + * @param boolean $overwriteIfExists if true and file exists the file is overwritten + * + * @return boolean Returns true on success or false on failure. + */ + public static function copy($source, $dest, $overwriteIfExists = true) + { + if (file_exists($dest)) { + if ($overwriteIfExists) { + self::rm($dest); + } else { + return false; + } + } + return copy($source, $dest); + } + + /** + * Copy part of file, if offset is 0 anf to file exists is truncated + * + * @param string|resource $from file name or resource + * @param string|resource $to file name or resource + * @param int<0, max> $offset copy offset + * @param int<-1, max> $length copy if -1 copy ot the end of file + * + * @return bool true on success or false on fail. + */ + public static function copyFilePart($from, $to, $offset = 0, $length = -1) + { + $closeFrom = false; + $closeTo = false; + $fromStream = null; + $toStream = null; + if (is_resource($from)) { + $fromStream = $from; + } else { + if (!is_file((string) $from)) { + return false; + } + if (($fromStream = self::fopen($from, 'r')) === false) { + return false; + } + $closeFrom = true; + } + if (is_resource($to)) { + $toStream = $to; + } else { + $mode = ($offset == 0 ? 'w+' : 'c+'); + if (($toStream = SnapIO::fopen($to, $mode)) === false) { + return false; + } + $closeTo = true; + } + if ($offset === 0) { + if (ftruncate($toStream, 0) === false) { + return false; + } + } + if (fseek($toStream, $offset) === -1) { + return false; + } + if ($closeFrom && is_resource($fromStream)) { + fclose($fromStream); + } + if ($closeTo && is_resource($toStream)) { + fclose($toStream); + } + return (stream_copy_to_stream($fromStream, $toStream, ($length < 0 ? null : $length), $offset) !== false); + } + + /** + * Copy recursive folder content + * + * @param string $source source path + * @param string $dest detination path + * + * @return boolean Returns true on success or false on failure. + */ + public static function rcopy($source, $dest) + { + if (!is_readable($source)) { + return false; + } + + if (is_dir($source)) { + if (!file_exists($dest)) { + if (!self::mkdir($dest)) { + return false; + } + } + + if (($handle = opendir($source)) == false) { + return false; + } + + while ($file = readdir($handle)) { + if ($file == "." || $file == "..") { + continue; + } + + if (!self::rcopy($source . '/' . $file, $dest . '/' . $file)) { + closedir($handle); + return false; + } + } + closedir($handle); + return true; + } else { + return copy($source, $dest); + } + } + + /** + * Untrailingslashit path + * + * @param string $path file path + * + * @return string + */ + public static function untrailingslashit($path) + { + return rtrim($path, '/\\'); + } + + /** + * Trailingslashit path + * + * @param string $path file path + * + * @return string + */ + public static function trailingslashit($path) + { + return self::untrailingslashit($path) . '/'; + } + + /** + * Normalize path + * + * @param string $path file path + * @param boolean $real if true apply realpath function + * + * @return string + */ + public static function safePath($path, $real = false) + { + if ($real) { + if (($res = realpath($path)) === false) { + $res = $path; + } + } else { + $res = $path; + } + return self::normalizePath($res); + } + + /** + * Untrailingslashit and normalize path + * + * @param string $path file path + * @param boolean $real if true apply realpath function + * + * @return string + */ + public static function safePathUntrailingslashit($path, $real = false) + { + if ($real) { + if (($res = realpath($path)) === false) { + $res = $path; + } + } else { + $res = $path; + } + return rtrim(self::normalizePath($res), '/'); + } + + /** + * Trailingslashit and normalize path + * + * @param string $path file path + * @param boolean $real if true apply realpath function + * + * @return string + */ + public static function safePathTrailingslashit($path, $real = false) + { + return self::safePathUntrailingslashit($path, $real) . '/'; + } + + /** + * Remove file path + * + * @param string $file path + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public static function unlink($file) + { + try { + if (!file_exists($file)) { + return true; + } + if (!function_exists('unlink') || is_dir($file)) { + return false; + } + self::chmod($file, 'u+rw'); + return @unlink($file); + } catch (Exception $e) { + return false; + } catch (Error $e) { + return false; + } + } + + /** + * Rename file from old name to new name + * + * @param string $oldname path + * @param string $newname path + * @param bool $removeIfExists if true remove exists file + * + * @return bool Returns TRUE on success or FALSE on failure. + */ + public static function rename($oldname, $newname, $removeIfExists = false) + { + try { + if (!file_exists($oldname) || !function_exists('rename')) { + return false; + } + + if ($removeIfExists && file_exists($newname)) { + if (!self::rrmdir($newname)) { + return false; + } + } + return @rename($oldname, $newname); + } catch (Exception $e) { + return false; + } catch (Error $e) { + return false; + } + } + + /** + * Open file + * + * @param string $filepath File path + * @param string $mode The mode parameter specifies the type of access you require to the stream. + * @param boolean $throwOnError thorw exception on error + * + * @return boolean|resource Returns a file pointer resource on success, or false on failure + */ + public static function fopen($filepath, $mode, $throwOnError = true) + { + if (strlen($filepath) > PHP_MAXPATHLEN) { + throw new Exception('Skipping a file that exceeds allowed max path length [' . PHP_MAXPATHLEN . ']. File: ' . $filepath); + } + + if (SnapString::startsWith($mode, 'w') || SnapString::startsWith($mode, 'c') || file_exists($filepath)) { + $file_handle = @fopen($filepath, $mode); + } else { + if ($throwOnError) { + throw new Exception("$filepath doesn't exist"); + } else { + return false; + } + } + + if (!is_resource($file_handle)) { + if ($throwOnError) { + throw new Exception("Error opening $filepath"); + } else { + return false; + } + } else { + return $file_handle; + } + } + + /** + * Touch file + * + * @param string $filepath File path + * @param int $time The touch time. If time is not supplied, the current system time is used. + * + * @return bool Returns true on success or false on failure. + */ + public static function touch($filepath, $time = null) + { + if (!function_exists('touch')) { + return false; + } + + if ($time === null) { + $time = time(); + } + return @touch($filepath, $time); + } + + /** + * Remove folder + * + * @param string $dirname dir path + * @param boolean $mustExist if true and folder don't esist thorw error + * + * @return void + */ + public static function rmdir($dirname, $mustExist = false) + { + if (file_exists($dirname)) { + self::chmod($dirname, 'u+rwx'); + if (self::rrmdir($dirname) === false) { + throw new Exception("Couldn't remove {$dirname}"); + } + } elseif ($mustExist) { + throw new Exception("{$dirname} doesn't exist"); + } + } + + /** + * Remove file + * + * @param string $filepath file path + * @param boolean $mustExist if true and folder don't esist thorw error + * + * @return void + */ + public static function rm($filepath, $mustExist = false) + { + if (file_exists($filepath)) { + self::chmod($filepath, 'u+rw'); + if (@unlink($filepath) === false) { + throw new Exception("Couldn't remove {$filepath}"); + } + } elseif ($mustExist) { + throw new Exception("{$filepath} doesn't exist"); + } + } + + /** + * string string in file + * + * @param resource $handle file handle + * @param string $string fwrite string + * + * @return int bytes written + */ + public static function fwrite($handle, $string) + { + $bytes_written = @fwrite($handle, $string); + + if ($bytes_written != strlen($string)) { + throw new Exception('Error writing all bytes to file.'); + } else { + return $bytes_written; + } + } + + /** + * Wrinte file in chunk mode. For big data. + * + * @param resource $handle file handle + * @param string $content fwrite string + * + * @return int bytes written + * + * @throws Exception + */ + public static function fwriteChunked($handle, $content) + { + if (strlen($content) == 0) { + return 0; + } + + $pieces = str_split($content, self::FWRITE_CHUNK_SIZE); + $written = 0; + + foreach ($pieces as $piece) { + if (($fwResult = @fwrite($handle, $piece, self::FWRITE_CHUNK_SIZE)) === false) { + throw new Exception('Error writing to file.'); + } + $written += $fwResult; + } + + if ($written != strlen($content)) { + throw new Exception('Error writing all bytes to file.'); + } + + return $written; + } + + /** + * Append file $from to file $to, if $to file don't exits create it. + * In case of error throw exceptions. + * + * @param string $from file path + * @param string $to file path + * + * @return int writte bytes + */ + public static function appendFileToFile($from, $to) + { + try { + $written = 0; + $fromHd = false; + $toHd = false; + + if (!file_exists($from) || !is_readable($from)) { + throw new Exception('File: ' . $from . ' don\'t exists os isn\'t readable'); + } + + if (file_exists($to) && !is_writable($to)) { + throw new Exception('File: ' . $to . ' isn\'t writeable'); + } + + if (($fromHd = @fopen($from, "rb")) === false) { + throw new Exception('Could not open file: ' . $from); + } + + if (($toHd = @fopen($to, "ab")) === false) { + throw new Exception('Could not open file: ' . $to); + } + + if (($fromStat = fstat($fromHd)) == false) { + throw new Exception('Can\t stat file: ' . $from); + } + + while ($buffer = fread($fromHd, self::FWRITE_CHUNK_SIZE)) { + if (($fwResult = @fwrite($toHd, $buffer)) === false) { + throw new Exception('Error writing to file ' . $to); + } + $written += $fwResult; + } + + if ($written != $fromStat['size']) { + throw new Exception('Error on file append, written bytes ' . $written . ' expected ' . $fromStat['size']); + } + } catch (Exception $e) { + if ($fromHd !== false) { + fclose($fromHd); + } + if ($toHd !== false) { + fclose($toHd); + } + throw $e; + } + + fclose($fromHd); + fclose($toHd); + + return $written; + } + + /** + * File get + * + * @param resource $handle file handle + * @param int $length max num bytes + * + * @return string + */ + public static function fgets($handle, $length) + { + $line = fgets($handle, $length); + + if ($line === false) { + throw new Exception('Error reading line.'); + } + + return $line; + } + + /** + * File close + * + * @param resource $handle file handle + * @param boolean $exception_on_fail if true thorw exception on fail + * + * @return void + */ + public static function fclose($handle, $exception_on_fail = true) + { + if ((@fclose($handle) === false) && $exception_on_fail) { + throw new Exception("Error closing file"); + } + } + + /** + * Exec a flock, thow exception on failure + * + * @param resource $handle file handle + * @param int $operation flock openration + * + * @return void + */ + public static function flock($handle, $operation) + { + if (@flock($handle, $operation) === false) { + throw new Exception("Error locking file"); + } + } + + /** + * Returns the current position of the file read/write pointer + * throw exception on failure + * + * @param resource $file_handle file handle + * + * @return int + */ + public static function ftell($file_handle) + { + $position = @ftell($file_handle); + + if ($position === false) { + throw new Exception("Couldn't retrieve file offset."); + } else { + return $position; + } + } + + /** + * Safely remove a directory and recursively files and directory upto multiple sublevels + * + * @param string $path The full path to the directory to remove + * + * @return bool Returns true if all content was removed + */ + public static function rrmdir($path) + { + if (is_dir($path)) { + if (($dh = opendir($path)) === false) { + return false; + } + while (($object = readdir($dh)) !== false) { + if ($object == "." || $object == "..") { + continue; + } + if (!self::rrmdir($path . "/" . $object)) { + closedir($dh); + return false; + } + } + closedir($dh); + return @rmdir($path); + } else { + if (is_writable($path)) { + return @unlink($path); + } else { + return false; + } + } + } + + /** + * Return files size, throw eception on failure + * + * @param string $filename file path + * + * @return int + */ + public static function filesize($filename) + { + $file_size = @filesize($filename); + + if ($file_size === false) { + throw new Exception("Error retrieving file size of $filename"); + } + + return $file_size; + } + + /** + * Fseek on file, throw exception on failure + * + * @param resource $handle file handle + * @param int $offset The offset. + * @param int $whence whence values are: SEEK_SET + * - Set position equal to offset bytes. SEEK_CUR + * - Set position to current location plus offset. SEEK_END + * - Set position to end-of-file plus offset. + * + * @return void + */ + public static function fseek($handle, $offset, $whence = SEEK_SET) + { + $ret_val = @fseek($handle, $offset, $whence); + + if ($ret_val !== 0) { + $filepath = stream_get_meta_data($handle); + $filepath = $filepath["uri"]; + $filesize = self::filesize($filepath); + + if ( + abs($offset) > self::FILE_SIZE_LIMIT_32BIT || + $filesize > self::FILE_SIZE_LIMIT_32BIT || + ($offset <= 0 && ($whence == SEEK_SET || $whence == SEEK_END)) + ) { + //This check is not strict, but in most cases 32 Bit PHP will be the issue + throw new Snap32BitSizeLimitException("Trying to seek on a file beyond the capability of 32 bit PHP. offset=$offset filesize=$filesize"); + } else { + throw new Exception("Error seeking to file offset $offset. Retval = $ret_val"); + } + } + } + + /** + * Gets file modification time + * + * @param string $filename file path + * + * @return int|false the time the file was last modified, or false on failure. + * The time is returned as a Unix timestamp, which is suitable for the date function + */ + public static function filemtime($filename) + { + $mtime = filemtime($filename); + + if ($mtime === false) { + throw new Exception("Cannot retrieve last modified time of $filename"); + } + + return $mtime; + } + + /** + * File put content, thorw exception on failure + * + * @param string $filename file path + * @param mixed $data The data to write. Can be either a string, an array or a stream resource. + + * @return bool + */ + public static function filePutContents($filename, $data) + { + if (($dirFile = realpath(dirname($filename))) === false) { + throw new Exception('FILE ERROR: put_content for file ' . $filename . ' failed [realpath fail]'); + } + if (!is_dir($dirFile)) { + throw new Exception('FILE ERROR: put_content for file ' . $filename . ' failed [dir ' . $dirFile . ' doesn\'t exist]'); + } + if (!is_writable($dirFile)) { + throw new Exception('FILE ERROR: put_content for file ' . $filename . ' failed [dir ' . $dirFile . ' exists but isn\'t writable]'); + } + $realFileName = $dirFile . basename($filename); + if (file_exists($realFileName) && !is_writable($realFileName)) { + throw new Exception('FILE ERROR: put_content for file ' . $filename . ' failed [file exist ' . $realFileName . ' but isn\'t writable'); + } + if (file_put_contents($filename, $data) === false) { + throw new Exception('FILE ERROR: put_content for file ' . $filename . ' failed [Couldn\'t write data to ' . $realFileName . ']'); + } + return true; + } + + /** + * this function make a chmod only if the are different from perms input and if chmod function is enabled + * + * this function handles the variable MODE in a way similar to the chmod of lunux + * So the MODE variable can be + * 1) an octal number (0755) + * 2) a string that defines an octal number ("644") + * 3) a string with the following format [ugoa]*([-+=]([rwx]*)+ + * + * examples + * u+rw add read and write at the user + * u+rw,uo-wx add read and write ad the user and remove wx at groupd and other + * a=rw is equal at 666 + * u=rwx,go-rwx is equal at 700 + * + * @param string $file file path + * @param int|string $mode permission mode + * + * @return boolean + */ + public static function chmod($file, $mode) + { + if (!file_exists($file)) { + return false; + } + + $octalMode = 0; + + if (is_int($mode)) { + $octalMode = $mode; + } elseif (is_numeric($mode)) { + $octalMode = intval((($mode[0] === '0' ? '' : '0') . $mode), 8); + } elseif (is_string($mode) && preg_match_all('/(a|[ugo]{1,3})([-=+])([rwx]{1,3})/', $mode, $gMatch, PREG_SET_ORDER)) { + if (!function_exists('fileperms')) { + return false; + } + + // start by file permission + $octalMode = (fileperms($file) & 0777); + + foreach ($gMatch as $matches) { + // [ugo] or a = ugo + $group = $matches[1]; + if ($group === 'a') { + $group = 'ugo'; + } + // can be + - = + $action = $matches[2]; + // [rwx] + $gPerms = $matches[3]; + + // reset octal group perms + $octalGroupMode = 0; + + // Init sub perms + $subPerm = 0; + $subPerm += strpos($gPerms, 'x') !== false ? 1 : 0; // mask 001 + $subPerm += strpos($gPerms, 'w') !== false ? 2 : 0; // mask 010 + $subPerm += strpos($gPerms, 'r') !== false ? 4 : 0; // mask 100 + + $ugoLen = strlen($group); + + if ($action === '=') { + // generate octal group permsissions and ugo mask invert + $ugoMaskInvert = 0777; + for ($i = 0; $i < $ugoLen; $i++) { + switch ($group[$i]) { + case 'u': + $octalGroupMode = $octalGroupMode | $subPerm << 6; // mask xxx000000 + $ugoMaskInvert = $ugoMaskInvert & 077; + break; + case 'g': + $octalGroupMode = $octalGroupMode | $subPerm << 3; // mask 000xxx000 + $ugoMaskInvert = $ugoMaskInvert & 0707; + break; + case 'o': + $octalGroupMode = $octalGroupMode | $subPerm; // mask 000000xxx + $ugoMaskInvert = $ugoMaskInvert & 0770; + break; + } + } + // apply = action + $octalMode = $octalMode & ($ugoMaskInvert | $octalGroupMode); + } else { + // generate octal group permsissions + for ($i = 0; $i < $ugoLen; $i++) { + switch ($group[$i]) { + case 'u': + $octalGroupMode = $octalGroupMode | $subPerm << 6; // mask xxx000000 + break; + case 'g': + $octalGroupMode = $octalGroupMode | $subPerm << 3; // mask 000xxx000 + break; + case 'o': + $octalGroupMode = $octalGroupMode | $subPerm; // mask 000000xxx + break; + } + } + // apply + or - action + switch ($action) { + case '+': + $octalMode = $octalMode | $octalGroupMode; + break; + case '-': + $octalMode = $octalMode & ~$octalGroupMode; + break; + } + } + } + } else { + return true; + } + + // if input permissions are equal at file permissions return true without performing chmod + if (function_exists('fileperms') && $octalMode === (fileperms($file) & 0777)) { + return true; + } + + if (!function_exists('chmod')) { + return false; + } + + return @chmod($file, $octalMode); + } + + /** + * Return file perms in string + * + * @param int|string $perms permssions + * + * @return string|false false if fail + */ + public static function permsToString($perms) + { + if (is_int($perms)) { + return decoct($perms); + } elseif (is_numeric($perms)) { + return ($perms[0] === '0' ? '' : '0') . $perms; + } elseif (is_string($perms)) { + return $perms; + } else { + return false; + } + } + + /** + * this function creates a folder if it does not exist and performs a chmod. + * it is different from the normal mkdir function to which an umask is applied to the input permissions. + * + * this function handles the variable MODE in a way similar to the chmod of lunux + * So the MODE variable can be + * 1) an octal number (0755) + * 2) a string that defines an octal number ("644") + * 3) a string with the following format [ugoa]*([-+=]([rwx]*)+ + * + * @param string $path folder path + * @param int|string $mode mode permissions + * @param bool $recursive Allows the creation of nested directories specified in the pathname. Default to false. + * @param resource $context not used for windows bug + * + * @return boolean bool TRUE on success or FALSE on failure. + * + * @todo check recursive true and multiple chmod + */ + public static function mkdir($path, $mode = 0777, $recursive = false, $context = null) + { + if (strlen($path) > PHP_MAXPATHLEN) { + throw new Exception('Skipping a file that exceeds allowed max path length [' . PHP_MAXPATHLEN . ']. File: ' . $path); + } + + if (!file_exists($path)) { + if (!function_exists('mkdir')) { + return false; + } + if (!@mkdir($path, 0777, $recursive)) { + return false; + } + } + + return self::chmod($path, $mode); + } + + /** + * this function call snap mkdir if te folder don't exists od don't have write or exec permissions + * + * this function handles the variable MODE in a way similar to the chmod of lunux + * The mode variable can be set to have more flexibility but not giving the user write and read and exec permissions doesn't make much sense + * + * @param string $path folder path + * @param int|string $mode mode permissions + * @param bool $recursive Allows the creation of nested directories specified in the pathname. Default to false. + * @param resource $context not used for windows bug + * + * @return boolean bool TRUE on success or FALSE on failure. + */ + public static function dirWriteCheckOrMkdir($path, $mode = 'u+rwx', $recursive = false, $context = null) + { + if (!file_exists($path)) { + return self::mkdir($path, $mode, $recursive, $context); + } elseif (!is_writable($path) || (function_exists('is_executable') && !is_executable($path))) { + return self::chmod($path, $mode); + } else { + return true; + } + } + + /** + * Create an empty index.php file in dir. + * + * @param string $dir Dir where create index.php + * + * @return bool true on success, false on failure + */ + public static function createSilenceIndex($dir) + { + if (!is_dir($dir)) { + return false; + } + + $path = self::trailingslashit($dir) . 'index.php'; + if (!file_exists($path)) { + $fileContent = << $lenB) { + return ($childsFirst ? -1 : 1); + } else { + return ($childsFirst ? 1 : -1); + } + }); + return $paths; + } + + /** + * from wp_normalize_path + * + * @param string $path Path to normalize. + * + * @return string Normalized path. + */ + public static function normalizePath($path) + { + $wrapper = ''; + if (self::isStream($path)) { + list( $wrapper, $path ) = explode('://', $path, 2); + $wrapper .= '://'; + } + + // Standardise all paths to use / + $path = str_replace('\\', '/', $path); + + // Replace multiple slashes down to a singular, allowing for network shares having two slashes. + $path = preg_replace('|(?<=.)/+|', '/', $path); + if (strpos($path, '//') === 0) { + $path = substr($path, 1); + } + + // Windows paths should uppercase the drive letter + if (':' === substr($path, 1, 1)) { + $path = ucfirst($path); + } + + return $wrapper . $path; + } + + /** + * Get common parent path from given paths + * + * @param string[] $paths list of paths + * + * @return string common parent path + */ + public static function getCommonPath($paths = array()) + { + if (empty($paths)) { + return ''; + } if (!is_array($paths)) { + $paths = array($paths); + } else { + $paths = array_values($paths); + } + + $pathAssoc = array(); + $numPaths = count($paths); + $minPathCouts = PHP_INT_MAX; + + for ($i = 0; $i < $numPaths; $i++) { + $pathAssoc[$i] = explode('/', self::safePathUntrailingslashit($paths[$i])); + $pathCount = count($pathAssoc[$i]); + if ($minPathCouts > $pathCount) { + $minPathCouts = $pathCount; + } + } + + for ($partIndex = 0; $partIndex < $minPathCouts; $partIndex++) { + $currentPart = $pathAssoc[0][$partIndex]; + for ($currentPath = 1; $currentPath < $numPaths; $currentPath++) { + if ($pathAssoc[$currentPath][$partIndex] != $currentPart) { + break 2; + } + } + } + + $resultParts = array_slice($pathAssoc[0], 0, $partIndex); + + return implode('/', $resultParts); + } + + /** + * remove root path transforming the current path into a relative path + * + * ex. /aaa/bbb become aaa/bbb + * ex. C:\aaa\bbb become aaa\bbb + * + * @param string $path file path + * + * @return string + */ + public static function removeRootPath($path) + { + return preg_replace('/^(?:[A-Za-z]:)?[\/](.*)/', '$1', $path); + } + + /** + * Returns the last N lines of a file. Simular to tail command + * + * @param string $filepath The full path to the file to be tailed + * @param int $lines The number of lines to return with each tail call + * + * @return false|string The last N parts of the file, flse on failure + */ + public static function tailFile($filepath, $lines = 2) + { + // Open file + $f = @fopen($filepath, "rb"); + if ($f === false) { + return false; + } + + // Sets buffer size + $buffer = 256; + + // Jump to last character + fseek($f, -1, SEEK_END); + + // Read it and adjust line number if necessary + // (Otherwise the result would be wrong if file doesn't end with a blank line) + if (fread($f, 1) != "\n") { + $lines -= 1; + } + + // Start reading + $output = ''; + $chunk = ''; + + // While we would like more + while (ftell($f) > 0 && $lines >= 0) { + // Figure out how far back we should jump + $seek = min(ftell($f), $buffer); + // Do the jump (backwards, relative to where we are) + fseek($f, -$seek, SEEK_CUR); + // Read a chunk and prepend it to our output + $output = ($chunk = fread($f, $seek)) . $output; + // Jump back to where we started reading + fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR); + // Decrease our line counter + $lines -= substr_count($chunk, "\n"); + } + + // While we have too many lines + // (Because of buffer size we might have read too many) + while ($lines++ < 0) { + // Find first newline and remove all text before that + $output = substr($output, strpos($output, "\n") + 1); + } + fclose($f); + return trim($output); + } + + /** + * @param string $filepath path to file to be downloaded + * @param string $downloadName name to be downloaded as + * @param int $bufferSize file chunks to be served + * @param bool $limitRate if set to true the download rate will be limited to $bufferSize/seconds + * + * @return void + */ + public static function serveFileForDownload($filepath, $downloadName, $bufferSize = 0, $limitRate = false) + { + // Process download + if (!file_exists($filepath)) { + throw new Exception("File does not exist!"); + } + + if (!is_file($filepath)) { + throw new Exception("'$filepath' is not a file!"); + } + + // Clean output buffers + SnapUtil::obCleanAll(false); + + header('Content-Description: File Transfer'); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="' . $downloadName . '"'); + header('Expires: 0'); + header('Cache-Control: must-revalidate'); + header('Pragma: public'); + header('Content-Length: ' . filesize($filepath)); + flush(); // Flush system output buffer + + if ($bufferSize <= 0) { + readfile($filepath); + exit; + } + + $fp = @fopen($filepath, 'r'); + if (!is_resource($fp)) { + throw new Exception('Fail to open the file ' . $filepath); + } + + while (!feof($fp) && ($data = fread($fp, $bufferSize)) !== false) { + echo $data; + + if ($limitRate) { + sleep(1); + } + } + @fclose($fp); + exit; + } + + /** + * Serve error 500 and exit + * + * @return never + */ + public static function serverError500() + { + header('HTTP/1.1 500 Internal Server Error'); + exit; + } + + /** + * Return lasts fine of file + * + * @param string $path Path to the file + * @param int $n Number of lines to get + * @param int $charLimit Number of chars to include in each line + * + * @return bool|string[] Last $n lines of file + */ + public static function getLastLinesOfFile($path, $n, $charLimit = null) + { + if (!is_readable($path)) { + return false; + } + + if (($handle = self::fopen($path, 'r', false)) === false) { + return false; + } + + $result = array(); + $pos = -1; + $currentLine = ''; + $counter = 0; + + while ($counter < $n && -1 !== fseek($handle, $pos, SEEK_END)) { + $char = fgetc($handle); + if (PHP_EOL == $char) { + $trimmedValue = trim($currentLine); + if (is_null($charLimit)) { + $currentLine = substr($currentLine, 0); + } else { + $currentLine = substr($currentLine, 0, (int) $charLimit); + if (strlen($currentLine) == $charLimit) { + $currentLine .= '...'; + } + } + + if (!empty($trimmedValue)) { + $result[] = $currentLine; + $counter++; + } + $currentLine = ''; + } else { + $currentLine = $char . $currentLine; + } + $pos--; + } + self::fclose($handle, false); + + return array_reverse($result); + } + + /** + * Thif function scan a folder filter by regex + * + * Options + * regexFile: [bool|string|array] if is bool alrays or never match, if is string o array of string check if rexeses match file name + * regexFolder: [bool|string|array] if is bool alrays or never match, if is string o array of string check if rexeses match file name + * checkFullPath: bool if false only current file/folder name is passed at regex if true is passed the full path + * recursive: bool if false check only passed folder or all sub folder recursively + * invert: bool if false pass invert the result + * childFirst: bool if false is parsed parent folters first or child folders first + * + * @param string $dir dir to scan + * @param array $options array{ + * regexFile?: bool|string, + * regexFolder?: bool|string, + * checkFullPath?: bool, + * recursive?: bool, + * invert?: bool, + * childFirst?: bool + * } + * + * @return string[] paths lists + */ + public static function regexGlob($dir, $options) + { + $result = array(); + + self::regexGlobCallback($dir, function ($path) use (&$result) { + $result[] = $path; + }, $options); + + return $result; + } + + /** + * Execute the callback function foreach right element, private function for optimization + * + * Options + * regexFile: [bool|string|array] if is bool alrays or never match, if is string o array of string check if rexeses match file name + * regexFolder: [bool|string|array] if is bool alrays or never match, if is string o array of string check if rexeses match file name + * checkFullPath: bool if false only current file/folder name is passed at regex if true is passed the full path + * recursive: bool if false check only passed folder or all sub folder recursively + * invert: bool if false pass invert the result + * childFirst: bool if false is parsed parent folters first or child folders first + * symlinks: string[] list a symblink parsed + * + * @param string $dir dir to scan + * @param callable $callback callback function + * @param array $options array{ + * regexFile?: bool|string, + * regexFolder?: bool|string, + * checkFullPath?: bool, + * recursive?: bool, + * invert?: bool, + * childFirst?: bool, + * symlinks?: string[] + * } + * + * @return boolean Returns true on success or false on failure. + */ + protected static function regexGlobCallbackPrivate($dir, $callback, &$options) + { + if (($dh = opendir($dir)) == false) { + return false; + } + + while (($elem = readdir($dh)) !== false) { + if ($elem === '.' || $elem === '..') { + continue; + } + + $fullPath = $dir . $elem; + $isDir = is_dir($fullPath); + if (($regex = $isDir ? $options['regexFolder'] : $options['regexFile']) === false) { + continue; + } + + if ($isDir && is_link($fullPath)) { + $realPath = self::safePathUntrailingslashit($fullPath, true); + if (in_array($realPath, $options['symlinks'])) { + continue; + } + $options['symlinks'][] = $realPath; + } + + if (is_bool($regex)) { + $match = $regex; + } else { + $match = false; + $pathCheck = $options['checkFullPath'] ? $fullPath : $elem; + + foreach ($regex as $currentRegex) { + if (preg_match($currentRegex, $pathCheck) === 1) { + $match = true; + break; + } + } + + if ($options['invert']) { + $match = !$match; + } + } + + if ($match) { + if ($isDir && $options['execChildFirst']) { + self::regexGlobCallbackPrivate($fullPath . '/', $callback, $options); + } + + call_user_func($callback, $fullPath); + + if ($isDir && $options['execChildAfter']) { + self::regexGlobCallbackPrivate($fullPath . '/', $callback, $options); + } + } + } + closedir($dh); + + return true; + } + + /** + * Execute the callback function foreach right element (folder or files) + * + * Options + * regexFile: [bool|string|array] if is bool alrays or never match, if is string o array of string check if rexeses match file name + * regexFolder: [bool|string|array] if is bool alrays or never match, if is string o array of string check if rexeses match file name + * checkFullPath: bool if false only current file/folder name is passed at regex if true is passed the full path + * recursive: bool if false check only passed folder or all sub folder recursively + * invert: bool if false pass invert the result + * childFirst: bool if false is parsed parent folters first or child folders first + * + * @param string $dir dir to scan + * @param callable $callback callback function + * @param array $options array{ + * regexFile?: bool|string, + * regexFolder?: bool|string, + * checkFullPath?: bool, + * recursive?: bool, + * invert?: bool, + * childFirst?: bool + * } + * + * @return boolean Returns true on success or false on failure. + */ + public static function regexGlobCallback($dir, $callback, $options = array()) + { + $dir = self::safePathTrailingslashit($dir); + + if (!is_dir($dir) || !is_readable($dir)) { + return false; + } + + if (!is_callable($callback)) { + return false; + } + + $options = array_merge(array( + 'regexFile' => true, + 'regexFolder' => true, + 'checkFullPath' => false, + 'recursive' => false, + 'invert' => false, + 'childFirst' => false, + 'symlinks' => array() + ), (array) $options); + + if (is_bool($options['regexFile'])) { + $options['regexFile'] = ($options['regexFile'] xor $options['invert']); + } elseif (is_scalar($options['regexFile'])) { + $options['regexFile'] = array($options['regexFile']); + } + + if (is_bool($options['regexFolder'])) { + $options['regexFolder'] = ($options['regexFolder'] xor $options['invert']); + } elseif (is_scalar($options['regexFolder'])) { + $options['regexFolder'] = array($options['regexFolder']); + } + + // optimizization + $options['execChildFirst'] = ($options['recursive'] && $options['childFirst'] === true); + $options['execChildAfter'] = ($options['recursive'] && $options['childFirst'] === false); + + return self::regexGlobCallbackPrivate($dir, $callback, $options); + } + + /** + * Empty passed dir + * + * @param string $dir folder to empty + * @param string[] $filter childs name to skip + * + * @return boolean Returns true on success or false on failure. + */ + public static function emptyDir($dir, $filter = array()) + { + $dir = self::safePathTrailingslashit($dir); + if (!is_dir($dir) || !is_readable($dir)) { + return false; + } + + if (($dh = opendir($dir)) == false) { + return false; + } + + $listToDelete = array(); + + while (($elem = readdir($dh)) !== false) { + if ($elem === '.' || $elem === '..') { + continue; + } + + if (in_array($elem, $filter)) { + continue; + } + + $fullPath = $dir . $elem; + if (self::chmod($fullPath, 'ugo+rwx')) { + $listToDelete[] = $fullPath; + } + } + closedir($dh); + + foreach ($listToDelete as $path) { + self::rrmdir($path); + } + return true; + } + + /** + * Returns a path to the base root folder of path taking into account the + * open_basedir setting. + * + * @param string $path file path + * + * @return bool|string Base root path of $path if it's accessible, otherwise false; + */ + public static function getMaxAllowedRootOfPath($path) + { + $path = self::safePathUntrailingslashit($path, true); + + if (!self::isOpenBaseDirEnabled()) { + $parts = explode("/", $path); + return $parts[0] . "/"; + } else { + return self::getOpenBaseDirRootOfPath($path); + } + } + + /** + * Check if php.ini open_basedir is enabled + * + * @return bool true if open_basedir is set + */ + public static function isOpenBaseDirEnabled() + { + $iniVar = ini_get("open_basedir"); + return (strlen($iniVar) > 0); + } + + /** + * Get open_basedir list paths + * + * @return string[] Paths contained in the open_basedir setting. Empty array if the setting is not enabled. + */ + public static function getOpenBaseDirPaths() + { + if (!($openBase = ini_get("open_basedir"))) { + return array(); + } + return explode(PATH_SEPARATOR, $openBase); + } + + /** + * Get open base dir root path of path + * + * @param string $path file path + * + * @return bool|string Path to the base dir of $path if it exists, otherwise false + */ + public static function getOpenBaseDirRootOfPath($path) + { + foreach (self::getOpenBaseDirPaths() as $allowedPath) { + $allowedPath = $allowedPath !== "/" ? self::safePathUntrailingslashit($allowedPath) : "/"; + if (strpos($path, $allowedPath) === 0) { + return $allowedPath; + } + } + + return false; + } + + /** + * this function is similar at dirname but if empty path return empty value not . + * and is SO indipendent so work on not normalized path + * + * @param string $path file path + * + * @return string + */ + public static function getRelativeDirname($path) + { + if (preg_match('/^(.*)[\/]+/', $path, $matches) !== 1) { + return ''; + } + + return $matches[1]; + } + + /** + * Set full user permissions on folder (rwx) + * + * @param string $path dir path + * + * @return boolean // return false if folder don't have read write permission on folder + */ + public static function dirAddFullPermsAndCheckResult($path) + { + if (!SnapIO::chmod($path, 'u+rwx')) { + return false; + } + + if (!is_readable($path) || !is_writable($path)) { + return false; + } + + if (function_exists('is_executable') && !is_executable($path) && !SnapOS::isWindows()) { + return false; + } + + return true; + } + + /** + * set full user permissions on file (rwx) + * + * @param string $path file path + * + * @return boolean // return false if folder don't have read write permission on folder + */ + public static function fileAddFullPermsAndCheckResult($path) + { + if (!SnapIO::chmod($path, 'u+rw')) { + return false; + } + + if (!is_readable($path) || !is_writable($path)) { + return false; + } + + return true; + } + + /** + * Returns the total size of a filesystem or disk partition in bytes + * + * @param string $directory path + * + * @return int rturn number of bytes or -1 on failure + */ + public static function diskTotalSpace($directory) + { + if (!function_exists('disk_total_space')) { + return -1; + } + + if (($space = disk_total_space($directory)) === false) { + return -1; + } + + return (int) round($space); + } + + /** + * Returns available space in directory in bytes + * + * @param string $directory path + * + * @return int rturn number of bytes or -1 on failure + */ + public static function diskFreeSpace($directory) + { + if (!function_exists('disk_free_space')) { + return -1; + } + + if (($space = disk_free_space($directory)) === false) { + return -1; + } + + return (int) round($space); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapJson.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapJson.php new file mode 100644 index 0000000..95b21c0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapJson.php @@ -0,0 +1,302 @@ +=')) { + $args = array($data, $options, $depth); + } elseif (version_compare(PHP_VERSION, '5.3', '>=')) { + $args = array($data, $options); + } else { + $args = array($data); + } + + $preparedData = self::jsonPrepareData($data); + // Prepare the data for JSON serialization. + $args[0] = $preparedData; + + $json = @call_user_func_array('json_encode', $args); + + // If json_encode() was successful, no need to do more sanity checking. + // ... unless we're in an old version of PHP, and json_encode() returned + // a string containing 'null'. Then we need to do more sanity checking. + if (false !== $json && ( version_compare(PHP_VERSION, '5.5', '>=') || false === strpos($json, 'null') )) { + return $json; + } + + try { + $args[0] = self::jsonSanityCheck($preparedData, $depth); + } catch (\Exception $e) { + return false; + } + + return call_user_func_array('json_encode', $args); + } + + /** + * wp_json_encode with pretty print if define exists + * + * @param mixed $data Variable (usually an array or object) to encode as JSON. + * @param int $options Optional. Options to be passed to json_encode(). Default 0. + * @param int $depth Optional. Maximum depth to walk through $data. Must be + * greater than 0. Default 512. + * + * @return string|false The JSON encoded string, or false if it cannot be encoded. + */ + public static function jsonEncodePPrint($data, $options = 0, $depth = 512) + { + if (defined('JSON_PRETTY_PRINT')) { + // phpcs:ignore PHPCompatibility.Constants.NewConstants.json_pretty_printFound + return self::jsonEncode($data, JSON_PRETTY_PRINT | $options, $depth); + } else { + return self::jsonEncode($data, $options, $depth); + } + } + + /** + * Prepares response data to be serialized to JSON. + * + * This supports the JsonSerializable interface for PHP 5.2-5.3 as well. + * + * @param mixed $data Native representation. + * + * @return bool|int|float|null|string|mixed[] Data ready for `json_encode()`. + */ + private static function jsonPrepareData($data) + { + if ( + !defined('WP_JSON_SERIALIZE_COMPATIBLE') || + WP_JSON_SERIALIZE_COMPATIBLE === false + ) { + return $data; + } + + switch (gettype($data)) { + case 'boolean': + case 'integer': + case 'double': + case 'string': + case 'NULL': + // These values can be passed through. + return $data; + + case 'array': + // Arrays must be mapped in case they also return objects. + return array_map(array(__CLASS__, 'jsonPrepareData'), $data); + + case 'object': + // If this is an incomplete object (__PHP_Incomplete_Class), bail. + if (!is_object($data)) { + return null; + } + + if ($data instanceof \JsonSerializable) { + $data = $data->jsonSerialize(); + } else { + $data = get_object_vars($data); + } + + // Now, pass the array (or whatever was returned from jsonSerialize through). + return self::jsonPrepareData($data); + + default: + return null; + } + } + + /** + * Perform sanity checks on data that shall be encoded to JSON. + * + * @ignore + * @since 4.1.0 + * @access private + * + * @see wp_json_encode() + * + * @param mixed $data Variable (usually an array or object) to encode as JSON. + * @param int $depth Maximum depth to walk through $data. Must be greater than 0. + * + * @return mixed The sanitized data that shall be encoded to JSON. + */ + private static function jsonSanityCheck($data, $depth) + { + if ($depth < 0) { + throw new \Exception('Reached depth limit'); + } + + if ($data instanceof \JsonSerializable) { + $data = $data->jsonSerialize(); + } + + if (is_array($data)) { + $output = array(); + foreach ($data as $id => $el) { + // Don't forget to sanitize the ID! + if (is_string($id)) { + $clean_id = self::jsonConvertString($id); + } else { + $clean_id = $id; + } + + // Check the element type, so that we're only recursing if we really have to. + if (is_array($el) || is_object($el)) { + $output[$clean_id] = self::jsonSanityCheck($el, $depth - 1); + } elseif (is_string($el)) { + $output[$clean_id] = self::jsonConvertString($el); + } else { + $output[$clean_id] = $el; + } + } + } elseif (is_object($data)) { + $output = new \stdClass(); + foreach ($data as $id => $el) { + if (is_string($id)) { + $clean_id = self::jsonConvertString($id); + } else { + $clean_id = $id; + } + + if (is_array($el) || is_object($el)) { + $output->$clean_id = self::jsonSanityCheck($el, $depth - 1); + } elseif (is_string($el)) { + $output->$clean_id = self::jsonConvertString($el); + } else { + $output->$clean_id = $el; + } + } + } elseif (is_string($data)) { + return self::jsonConvertString($data); + } else { + return $data; + } + + return $output; + } + + /** + * Return json string + * + * @param string $string data + * + * @return string + */ + private static function jsonConvertString($string) + { + static $use_mb = null; + if (is_null($use_mb)) { + $use_mb = function_exists('mb_convert_encoding'); + } + + if ($use_mb) { + $encoding = mb_detect_encoding($string, mb_detect_order(), true); + if ($encoding) { + return mb_convert_encoding($string, 'UTF-8', $encoding); + } else { + return mb_convert_encoding($string, 'UTF-8', 'UTF-8'); + } + } else { + return self::checkInvalidUTF8($string, true); + } + } + + /** + * Checks for invalid UTF8 in a string. + * + * @param string $string The text which is to be checked. + * @param bool $strip Optional. Whether to attempt to strip out invalid UTF8. Default is false. + * + * @return string The checked text. + */ + public static function checkInvalidUTF8($string, $strip = false) + { + $string = (string) $string; + + if (0 === strlen($string)) { + return ''; + } + + // Check for support for utf8 in the installed PCRE library once and store the result in a static + static $utf8_pcre = null; + if (!isset($utf8_pcre)) { + $utf8_pcre = @preg_match('/^./u', 'a'); + } + // We can't demand utf8 in the PCRE installation, so just return the string in those cases + if (!$utf8_pcre) { + return $string; + } + + // preg_match fails when it encounters invalid UTF8 in $string + if (1 === @preg_match('/^./us', $string)) { + return $string; + } + + // Attempt to strip the bad chars if requested (not recommended) + if ($strip && function_exists('iconv')) { + return iconv('utf-8', 'utf-8', $string); + } + + return ''; + } + + /** + * todo remove esc_attr wp function + * + * @param mixed $val object to be encoded + * + * @return string escaped json string + */ + public static function jsonEncodeEscAttr($val) + { + return esc_attr(json_encode($val)); + } + + /** + * this function return a json encoded string without quotes at the beginning and the end + * + * @param string $string json string + * + * @return string + */ + public static function getJsonWithoutQuotes($string) + { + if (!is_string($string)) { + throw new \Exception('the function getJsonStringWithoutQuotes take only strings'); + } + + return substr(self::jsonEncode($string), 1, -1); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapLog.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapLog.php new file mode 100644 index 0000000..d64ffcb --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapLog.php @@ -0,0 +1,223 @@ +"; + $lfp = self::$logFilepath; + // echo "logging $s to {$lfp}
        "; + if (self::$logFilepath === null) { + throw new Exception('Logging not initialized'); + } + + if (isset($_SERVER['REQUEST_TIME_FLOAT'])) { + $timepart = $_SERVER['REQUEST_TIME_FLOAT']; + } else { + $timepart = $_SERVER['REQUEST_TIME']; + } + + $thread_id = sprintf("%08x", abs(crc32($_SERVER['REMOTE_ADDR'] . $timepart . $_SERVER['REMOTE_PORT']))); + + $s = $thread_id . ' ' . date('h:i:s') . ":$s"; + + if (self::$logHandle === null) { + self::$logHandle = fopen(self::$logFilepath, 'a'); + } + + fwrite(self::$logHandle, "$s\n"); + + if ($flush) { + fflush(self::$logHandle); + + fclose(self::$logHandle); + + self::$logHandle = fopen(self::$logFilepath, 'a'); + } + } + + /** + * Get formatted string fo value + * + * @param mixed $var value to convert to string + * @param bool $checkCallable if true check if var is callable and display it + * + * @return string + */ + public static function v2str($var, $checkCallable = false) + { + if ($checkCallable && is_callable($var)) { + return '(callable) ' . print_r($var, true); + } + switch (gettype($var)) { + case "boolean": + return $var ? 'true' : 'false'; + case "integer": + case "double": + return (string) $var; + case "string": + return '"' . $var . '"'; + case "array": + case "object": + return print_r($var, true); + case "resource": + case "resource (closed)": + case "NULL": + case "unknown type": + default: + return gettype($var); + } + } + + /** + * Get backtrace of calling line + * + * @param string $message message + * + * @return string + */ + public static function getCurrentbacktrace($message = 'getCurrentLineTrace') + { + $callers = debug_backtrace(); + array_shift($callers); + $file = $callers[0]['file']; + $line = $callers[0]['line']; + $result = 'BACKTRACE: ' . $message . "\n"; + $result .= "\t[" . $file . ':' . $line . "]\n"; + $result .= self::traceToString($callers, 1, true); + return $result; + } + + /** + * Get trace string + * + * @param mixed[] $callers result of debug_backtrace + * @param int $fromLevel level to start + * @param bool $tab if true apply tab foreach line + * + * @return string + */ + public static function traceToString($callers, $fromLevel = 0, $tab = false) + { + $result = ''; + for ($i = $fromLevel; $i < count($callers); $i++) { + $result .= ($tab ? "\t" : ''); + $trace = $callers[$i]; + if (!empty($trace['class'])) { + $result .= str_pad('TRACE[' . $i . '] CLASS___: ' . $trace['class'] . $trace['type'] . $trace['function'], 45, ' '); + } else { + $result .= str_pad('TRACE[' . $i . '] FUNCTION: ' . $trace['function'], 45, ' '); + } + if (isset($trace['file'])) { + $result .= ' FILE: ' . $trace['file'] . '[' . $trace['line'] . ']'; + } else { + $result .= ' NO FILE'; + } + $result .= "\n"; + } + return $result; + } + + /** + * Get exception message file line trace + * + * @param Exception|Error $e exception object + * @param bool $displayMessage if true diplay exception message + * + * @return string + */ + public static function getTextException($e, $displayMessage = true) + { + $result = ($displayMessage ? $e->getMessage() . "\n" : ''); + return $result . "FILE:" . $e->getFile() . '[' . $e->getLIne() . "]\n" . + "TRACE:\n" . $e->getTraceAsString(); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapOS.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapOS.php new file mode 100644 index 0000000..6d5752a --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapOS.php @@ -0,0 +1,43 @@ + */ + protected $origFolderEntries = array(); + /** @var string */ + protected $rootPath = null; + + /** + * Class constructor + * + * @param string $root wordpress root path + * @param string $origFolderParentPath orig files folder path + * @param string $hash package hash + */ + public function __construct($root, $origFolderParentPath, $hash) + { + $this->rootPath = SnapIO::safePathUntrailingslashit($root, true); + $this->origFilesFolder = SnapIO::safePathTrailingslashit($origFolderParentPath, true) . self::ORIG_FOLDER_PREFIX . $hash; + $this->persistanceFile = $this->origFilesFolder . '/' . self::PERSISTANCE_FILE_NAME; + + if (file_exists($this->persistanceFile)) { + $this->load(); + } + } + + /** + * Create a main folder if don't exist and load the entries + * + * @param boolean $reset if strue reset orig file folder + * + * @return void + */ + public function init($reset = false) + { + $this->createMainFolder($reset); + $this->load(); + } + + /** + * Create orig file folder + * + * @param boolean $reset if true delete current folder + * + * @return boolean return true if succeded + * + * @throws \Exception + */ + protected function createMainFolder($reset = false) + { + if ($reset) { + $this->deleteMainFolder(); + } + + if (!file_exists($this->origFilesFolder)) { + if (!SnapIO::mkdir($this->origFilesFolder, 'u+rwx')) { + throw new \Exception('Can\'t create the original files folder ' . SnapLog::v2str($this->origFilesFolder)); + } + } + + $htaccessFile = $this->origFilesFolder . '/.htaccess'; + if (!file_exists($htaccessFile)) { + $content = <<persistanceFile)) { + $this->save(); + } + + return true; + } + + /** + * @return string Main folder path + * @throws \Exception + */ + public function getMainFolder() + { + if (!file_exists($this->origFilesFolder)) { + throw new \Exception('Can\'t get the original files folder ' . SnapLog::v2str($this->origFilesFolder)); + } + + return $this->origFilesFolder; + } + + /** + * delete origianl files folder + * + * @return boolean + * @throws \Exception + */ + public function deleteMainFolder() + { + if (file_exists($this->origFilesFolder) && !SnapIO::rrmdir($this->origFilesFolder)) { + throw new \Exception('Can\'t delete the original files folder ' . SnapLog::v2str($this->origFilesFolder)); + } + $this->origFolderEntries = array(); + + return true; + } + + /** + * add a entry on original folder. + * + * @param string $identifier entry identifier + * @param string $path entry path. can be a file or a folder + * @param string $mode MODE_MOVE move the item in original folder + * MODE_COPY copy the item in original folder + * @param bool|string $rename if rename is a string the item is renamed in original folder. + * + * @return boolean true if succeded + */ + public function addEntry($identifier, $path, $mode = self::MODE_MOVE, $rename = false) + { + if (!file_exists($path)) { + return false; + } + + $baseName = empty($rename) ? basename($path) : $rename; + + if (($relativePath = SnapIO::getRelativePath($path, $this->rootPath)) === false) { + $isRelative = false; + } else { + $isRelative = true; + } + $parentFolder = $isRelative ? dirname($relativePath) : SnapIO::removeRootPath(dirname($path)); + if (empty($parentFolder) || $parentFolder === '.') { + $parentFolder = ''; + } else { + $parentFolder .= '/'; + } + $targetFolder = $this->origFilesFolder . '/' . $parentFolder; + if (!file_exists($targetFolder)) { + SnapIO::mkdirP($targetFolder); + } + $dest = $targetFolder . $baseName; + + switch ($mode) { + case self::MODE_MOVE: + // Don't use rename beacause new files must have the current script owner + if (!SnapIO::rcopy($path, $dest)) { + throw new \Exception('Can\'t copy the original file ' . SnapLog::v2str($path)); + } + if (!SnapIO::rrmdir($path)) { + throw new \Exception('Can\'t remove the original file ' . SnapLog::v2str($path)); + } + break; + case self::MODE_COPY: + if (!SnapIO::rcopy($path, $dest)) { + throw new \Exception('Can\'t copy the original file ' . SnapLog::v2str($path)); + } + break; + default: + throw new \Exception('invalid mode addEntry'); + } + + $this->origFolderEntries[$identifier] = array( + 'baseName' => $baseName, + 'source' => $isRelative ? $relativePath : $path, + 'stored' => $parentFolder . $baseName, + 'mode' => $mode, + 'isRelative' => $isRelative + ); + + $this->save(); + return true; + } + + /** + * Get entry info from identifier + * + * @param string $identifier orig file identifier + * + * @return false|array{baseName:string, source:string, stored: string, mode:string, isRelative: bool} false if entry don't exists + */ + public function getEntry($identifier) + { + if (isset($this->origFolderEntries[$identifier])) { + return $this->origFolderEntries[$identifier]; + } else { + return false; + } + } + + /** + * Get entry stored path in original folder + * + * @param string $identifier orig file identifier + * + * @return boolean|string false if entry don't exists + */ + public function getEntryStoredPath($identifier) + { + if (isset($this->origFolderEntries[$identifier])) { + return $this->origFilesFolder . '/' . $this->origFolderEntries[$identifier]['stored']; + } else { + return false; + } + } + + /** + * Return true if identifier org file is relative path + * + * @param string $identifier orig file identifier + * + * @return boolean + */ + public function isRelative($identifier) + { + if (isset($this->origFolderEntries[$identifier])) { + return $this->origFolderEntries[$identifier]['isRelative']; + } else { + return false; + } + } + + /** + * Get entry target restore path + * + * @param string $identifier orig file identifier + * @param null|string $defaultIfIsAbsolute if isn't null return the value if path is absolute + * + * @return false|string false if entry don't exists + */ + public function getEntryTargetPath($identifier, $defaultIfIsAbsolute = null) + { + if (isset($this->origFolderEntries[$identifier])) { + if ($this->origFolderEntries[$identifier]['isRelative']) { + return $this->rootPath . '/' . $this->origFolderEntries[$identifier]['source']; + } else { + if (is_null($defaultIfIsAbsolute)) { + return $this->origFolderEntries[$identifier]['source']; + } else { + return $defaultIfIsAbsolute; + } + } + } else { + return false; + } + } + + /** + * this function restore current entry in original position. + * If mode is copy it simply delete the entry else move the entry in original position + * + * @param string $identifier identified of current entrye + * @param boolean $save update saved entries + * @param null|string $defaultIfIsAbsolute if isn't null return the value if path is absolute + * + * @return boolean true if succeded + */ + public function restoreEntry($identifier, $save = true, $defaultIfIsAbsolute = null) + { + if (!isset($this->origFolderEntries[$identifier])) { + return false; + } + + $stored = $this->getEntryStoredPath($identifier); + if (($original = $this->getEntryTargetPath($identifier, $defaultIfIsAbsolute)) === false) { + return false; + } + + switch ($this->origFolderEntries[$identifier]['mode']) { + case self::MODE_MOVE: + if (!SnapIO::rename($stored, $original)) { + throw new \Exception('Can\'t move the original file ' . SnapLog::v2str($stored)); + } + break; + case self::MODE_COPY: + if (!SnapIO::rrmdir($stored)) { + throw new \Exception('Can\'t delete entry ' . SnapLog::v2str($stored)); + } + break; + default: + throw new \Exception('invalid mode addEntry'); + } + + unset($this->origFolderEntries[$identifier]); + if ($save) { + $this->save(); + } + return true; + } + + /** + * Put all entries on original position and empty original folder + * + * @param string[] $exclude identifiers list t exclude + * + * @return boolean + */ + public function restoreAll($exclude = array()) + { + foreach (array_keys($this->origFolderEntries) as $ident) { + if (in_array($ident, $exclude)) { + continue; + } + $this->restoreEntry($ident, false); + } + $this->save(); + return true; + } + + /** + * Save notices from json file + * + * @return bool + */ + public function save() + { + if (!file_put_contents($this->persistanceFile, SnapJson::jsonEncodePPrint($this->origFolderEntries))) { + throw new \Exception('Can\'t write persistence file'); + } + return true; + } + + /** + * Load notice from json file + * + * @return bool + */ + private function load() + { + if (file_exists($this->persistanceFile)) { + $json = file_get_contents($this->persistanceFile); + $this->origFolderEntries = json_decode($json, true); + } else { + $this->origFolderEntries = array(); + } + return true; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapString.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapString.php new file mode 100644 index 0000000..533ab1a --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapString.php @@ -0,0 +1,186 @@ + $maxWidth) { + $s = substr($s, 0, $maxWidth - 3) . '...'; + } + + return $s; + } + + /** + * Returns true if the $haystack string starts with the $needle + * + * @param string $haystack The full string to search in + * @param string $needle The string to for + * + * @return bool Returns true if the $haystack string starts with the $needle + */ + public static function startsWith($haystack, $needle) + { + return (strpos($haystack, $needle) === 0); + } + + /** + * Returns true if the $haystack string end with the $needle + * + * @param string $haystack The full string to search in + * @param string $needle The string to for + * + * @return bool Returns true if the $haystack string starts with the $needle + */ + public static function endsWith($haystack, $needle) + { + $length = strlen($needle); + if ($length == 0) { + return true; + } + return (substr($haystack, -$length) === $needle); + } + + /** + * Returns true if the $needle is found in the $haystack + * + * @param string $haystack The full string to search in + * @param string $needle The string to for + * + * @return bool + */ + public static function contains($haystack, $needle) + { + $pos = strpos($haystack, $needle); + return ($pos !== false); + } + + /** + * Implode array key values to a string + * + * @param string $glue separator + * @param mixed[] $pieces array fo implode + * @param string $format format + * + * @return string + */ + public static function implodeKeyVals($glue, $pieces, $format = '%s="%s"') + { + $strList = array(); + foreach ($pieces as $key => $value) { + if (is_scalar($value)) { + $strList[] = sprintf($format, $key, $value); + } else { + $strList[] = sprintf($format, $key, print_r($value, true)); + } + } + return implode($glue, $strList); + } + + /** + * Replace last occurrence + * + * @param string $search The value being searched for + * @param string $replace The replacement value that replaces found search values + * @param string $str The string or array being searched and replaced on, otherwise known as the haystack + * @param boolean $caseSensitive Whether the replacement should be case sensitive or not + * + * @return string + */ + public static function strLastReplace($search, $replace, $str, $caseSensitive = true) + { + $pos = $caseSensitive ? strrpos($str, $search) : strripos($str, $search); + if (false !== $pos) { + $str = substr_replace($str, $replace, $pos, strlen($search)); + } + return $str; + } + + /** + * Check if passed string have html tags + * + * @param string $string input string + * + * @return boolean + */ + public static function isHTML($string) + { + return ($string != strip_tags($string)); + } + + /** + * Safe way to get number of characters + * + * @param ?string $string input string + * + * @return int + */ + public static function stringLength($string) + { + if (!isset($string) || $string == "") { // null == "" is also true + return 0; + } + return strlen($string); + } + + /** + * Returns case insensitive duplicates + * + * @param string[] $strings The array of strings to check for duplicates + * + * @return array + */ + public static function getCaseInsesitiveDuplicates($strings) + { + $duplicates = array(); + for ($i = 0; $i < count($strings) - 1; $i++) { + $key = strtolower($strings[$i]); + + //already found all instances so don't check again + if (isset($duplicates[$key])) { + continue; + } + + for ($j = $i + 1; $j < count($strings); $j++) { + if ($strings[$i] !== $strings[$j] && $key === strtolower($strings[$j])) { + $duplicates[$key][] = $strings[$j]; + } + } + + //duplicates were found, add the comparing string to list + if (isset($duplicates[$key])) { + $duplicates[$key][] = $strings[$i]; + } + } + + return $duplicates; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapURL.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapURL.php new file mode 100644 index 0000000..c766299 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapURL.php @@ -0,0 +1,237 @@ + */ + protected static $DEF_ARRAY_PARSE_URL = array( + 'scheme' => false, + 'host' => false, + 'port' => false, + 'user' => false, + 'pass' => false, + 'path' => '', + 'query' => false, + 'fragment' => false + ); + + /** + * Append a new query value to the end of a URL + * + * @param string $url The URL to append the new value to + * @param string $key The new key name + * @param ?scalar $value The new key name value + * + * @return string Returns the new URL with with the query string name and value + */ + public static function appendQueryValue($url, $key, $value) + { + $separator = (parse_url($url, PHP_URL_QUERY) == null) ? '?' : '&'; + $modified_url = $url . "$separator$key=" . $value; + + return $modified_url; + } + + /** + * Add www. in url if don't have + * + * @param string $url input URL + * + * @return string + */ + public static function wwwAdd($url) + { + return preg_replace('/^((?:\w+\:)?\/\/)?(?!www\.)(.+)/', '$1www.$2', $url); + } + + /** + * Remove www. in url if don't have + * + * @param string $url input URL + * + * @return string + */ + public static function wwwRemove($url) + { + return preg_replace('/^((?:\w+\:)?\/\/)?www\.(.+)/', '$1$2', $url); + } + + /** + * Fetches current URL via PHP + * + * @param bool $queryString If true the query string will also be returned. + * @param boolean $requestUri If true check REQUEST_URI else SCRIPT_NAME + * @param int $getParentDirLevel If 0 get current script name or parent folder, if 1 parent folder if 2 parent of parent folder ... + * + * @return string The current page url + */ + public static function getCurrentUrl($queryString = true, $requestUri = false, $getParentDirLevel = 0) + { + // *** HOST + if (isset($_SERVER['HTTP_X_ORIGINAL_HOST'])) { + $host = $_SERVER['HTTP_X_ORIGINAL_HOST']; + } else { + $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']; //WAS SERVER_NAME and caused problems on some boxes + } + + // *** PROTOCOL + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + $_SERVER ['HTTPS'] = 'on'; + } + if (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'https') { + $_SERVER ['HTTPS'] = 'on'; + } + if (isset($_SERVER['HTTP_CF_VISITOR'])) { + $visitor = json_decode($_SERVER['HTTP_CF_VISITOR']); + if (is_object($visitor) && property_exists($visitor, 'scheme') && $visitor->scheme == 'https') { + $_SERVER ['HTTPS'] = 'on'; + } + } + $protocol = 'http' . ((isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on') ? 's' : ''); + + if ($requestUri) { + $serverUrlSelf = preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI']); + } else { + // *** SCRIPT NAME + $serverUrlSelf = $_SERVER['SCRIPT_NAME']; + for ($i = 0; $i < $getParentDirLevel; $i++) { + $serverUrlSelf = preg_match('/^[\\\\\/]?$/', dirname($serverUrlSelf)) ? '' : dirname($serverUrlSelf); + } + } + + // *** QUERY STRING + $query = ($queryString && isset($_SERVER['QUERY_STRING']) && strlen($_SERVER['QUERY_STRING']) > 0 ) ? '?' . $_SERVER['QUERY_STRING'] : ''; + + return $protocol . '://' . $host . $serverUrlSelf . $query; + } + + /** + * Get current query string data array + * + * @return string[] + */ + public static function getCurrentQueryURLdata() + { + $result = array(); + if (!isset($_SERVER['QUERY_STRING']) || strlen($_SERVER['QUERY_STRING']) == 0) { + return $result; + } + + parse_str($_SERVER['QUERY_STRING'], $result); + + return $result; + } + + /** + * this function is a native PHP parse_url wrapper + * this function returns an associative array with all the keys present and the values = false if they do not exist. + * + * @param string $url

        The URL to parse. Invalid characters are replaced by _.

        + * @param int $component if != 1 return specific URL component + * + * @return mixed[]|string|int|null|false

        On seriously malformed URLs, parse_url() may return FALSE.

        + *

        If the component parameter is omitted, an associative array is returned. + * At least one element will be present within the array. Potential keys within this array are:

        + *
          + *
        • scheme - e.g. http
        • + *
        • host
        • + *
        • port
        • + *
        • user
        • + *
        • pass
        • + *
        • path
        • + *
        • query - after the question mark ?
        • + *
        • fragment - after the hashmark #
        • + *
        + *

        If the component parameter is specified, + * parse_url() returns a string (or an integer, + * in the case of PHP_URL_PORT) instead of an array. + * If the requested component doesn't exist within the given URL, NULL will be returned.

        + */ + public static function parseUrl($url, $component = -1) + { + if (preg_match('/^([a-zA-Z0-9]+\:)?\/\//', $url) !== 1) { + // fix invalid URL for only host string ex. 'myhost.com' + $url = '//' . $url; + } + + $result = parse_url($url, $component); + if (is_array($result)) { + $result = array_merge(self::$DEF_ARRAY_PARSE_URL, $result); + } + + return $result; + } + + /** + * Remove scheme from URL + * + * @param string $url source url + * @param bool $removeWww if true remove www + * + * @return string + */ + public static function removeScheme($url, $removeWww = false) + { + $parts = self::parseUrl($url); + unset($parts['scheme']); + $result = self::buildUrl($parts); + if ($removeWww) { + $result = self::wwwRemove($result); + } + return ltrim($result, '/'); + } + + /** + * this function build a url from array result of parse url. + * if work with both parse_url native function result and snap parseUrl result + * + * @param array $parts url parts from parseUrl + * + * @return bool|string return false if param isn't array + */ + public static function buildUrl($parts) + { + if (!is_array($parts)) { + return false; + } + + $result = ''; + $result .= (isset($parts['scheme']) && $parts['scheme'] !== false) ? $parts['scheme'] . ':' : ''; + $result .= ( + (isset($parts['user']) && $parts['user'] !== false) || + (isset($parts['host']) && $parts['host'] !== false)) ? '//' : ''; + + $result .= (isset($parts['user']) && $parts['user'] !== false) ? $parts['user'] : ''; + $result .= (isset($parts['pass']) && $parts['pass'] !== false) ? ':' . $parts['pass'] : ''; + $result .= (isset($parts['user']) && $parts['user'] !== false) ? '@' : ''; + + $result .= (isset($parts['host']) && $parts['host'] !== false) ? $parts['host'] : ''; + $result .= (isset($parts['port']) && $parts['port'] !== false) ? ':' . $parts['port'] : ''; + + $result .= (isset($parts['path']) && $parts['path'] !== false) ? $parts['path'] : ''; + $result .= (isset($parts['query']) && $parts['query'] !== false) ? '?' . $parts['query'] : ''; + $result .= (isset($parts['fragment']) && $parts['fragment'] !== false) ? '#' . $parts['fragment'] : ''; + + return $result; + } + + /** + * Encode alla chars + * + * @param string $url input URL + * + * @return string + */ + public static function urlEncodeAll($url) + { + $hex = unpack('H*', urldecode($url)); + return preg_replace('~..~', '%$0', strtoupper($hex[1])); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapUtil.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapUtil.php new file mode 100644 index 0000000..fd8f986 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapUtil.php @@ -0,0 +1,1003 @@ + 0) { + $percent = $startingPercent + (($endingPercent - $startingPercent) * ($currentTaskCount / (float) $totalTaskCount)); + } else { + $percent = $startingPercent; + } + + return min(max($startingPercent, $percent), $endingPercent); + } + + /** + * Compare two versions like version_compare but the ability to enter the number of levels to compare. + * For example, if the level is 2 between 4.1.1 and 4.1.2.1, 4.1 is compared with 4.1 and so they are equal. + * + * @param string $version1 version one + * @param string $version2 version two + * @param string $operator operetor type + * @param int $vLevel version level 0 is all levels + * + * @return int|bool + */ + public static function versionCompare($version1, $version2, $operator = null, $vLevel = 0) + { + if ($vLevel > 0) { + $tV1 = array_slice(preg_split("/[.-]/", $version1), 0, $vLevel); + $version1 = implode('.', $tV1); + $tV2 = array_slice(preg_split("/[.-]/", $version2), 0, $vLevel); + $version2 = implode('.', $tV2); + } + return version_compare($version1, $version2, $operator); + } + + /** + * Return version with level + * + * @param string $version version + * @param int $vLevel version level 0 is all levels + * + * @return string + */ + public static function getVersion($version, $vLevel = 0) + { + if ($vLevel > 0) { + $tV1 = array_slice(preg_split("/[.-]/", $version), 0, $vLevel); + $version = implode('.', $tV1); + } + return $version; + } + + /** + * Return true if is PHP7+ + * + * @return bool + */ + public static function isPHP7Plus() + { + static $isPHP7Plus = null; + if (is_null($isPHP7Plus)) { + $isPHP7Plus = version_compare(PHP_VERSION, '7.0.0', '>='); + } + return $isPHP7Plus; + } + + /** + * Groups an array into arrays by a given key, or set of keys, shared between all array members. + * + * Based on {@author Jake Zatecky}'s {@link https://github.com/jakezatecky/array_group_by array_group_by()} function. + * This variant allows $key to be closures. + * + * @param mixed[] $array The array to have grouping performed on. + * @param mixed $key The key to group or split by. Can be a _string_, an _integer_, a _float_, or a _callable_. + * - If the key is a callback, it must return a valid key from the array. - If the key is + * _NULL_, the iterated element is skipped. - string|int callback ( mixed $item ) + * + * @return mixed[]|null Returns a multidimensional array or `null` if `$key` is invalid. + */ + public static function arrayGroupBy(array $array, $key) + { + if (!is_string($key) && !is_int($key) && !is_float($key) && !is_callable($key)) { + trigger_error('array_group_by(): The key should be a string, an integer, or a callback', E_USER_ERROR); + } + $func = (!is_string($key) && is_callable($key) ? $key : null); + $_key = $key; + // Load the new array, splitting by the target key + $grouped = array(); + foreach ($array as $value) { + $key = null; + if (is_callable($func)) { + $key = call_user_func($func, $value); + } elseif (is_object($value) && isset($value->{$_key})) { + $key = $value->{$_key}; + } elseif (isset($value[$_key])) { + $key = $value[$_key]; + } + if ($key === null) { + continue; + } + $grouped[$key][] = $value; + } + // Recursively build a nested grouping if more parameters are supplied + // Each grouped array value is grouped according to the next sequential key + if (func_num_args() > 2) { + $args = func_get_args(); + foreach ($grouped as $key => $value) { + $params = array_merge(array($value), array_slice($args, 2, func_num_args())); + $grouped[$key] = call_user_func_array(array(__CLASS__, 'arrayGroupBy'), $params); + } + } + return $grouped; + } + + /** + * Converts human readable types (10GB) to bytes + * + * @param string $from A human readable byte size such as 100MB + * + * @return int<-1, max> Returns and integer of the byte size, -1 if isn't well formatted + */ + public static function convertToBytes($from) + { + if (is_numeric($from)) { + return (int) $from; + } + + $number = (int) substr($from, 0, -2); + switch (strtoupper(substr($from, -2))) { + case "KB": + return $number * 1024; + case "MB": + return $number * pow(1024, 2); + case "GB": + return $number * pow(1024, 3); + case "TB": + return $number * pow(1024, 4); + case "PB": + return $number * pow(1024, 5); + } + + $number = (int) substr($from, 0, -1); + switch (strtoupper(substr($from, -1))) { + case "K": + return $number * 1024; + case "M": + return $number * pow(1024, 2); + case "G": + return $number * pow(1024, 3); + case "T": + return $number * pow(1024, 4); + case "P": + return $number * pow(1024, 5); + } + + return -1; + } + + /** + * Sanitize input for XSS code + * + * @param string $input The value to sanitize + * + * @return string Returns the input value cleaned up. + */ + public static function sanitize($input) + { + return htmlspecialchars(self::sanitizeNSChars($input)); + } + + /** + * Remove all non stamp chars from string + * + * @param string $string input string + * + * @return string + */ + public static function sanitizeNSChars($string) + { + return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', (string) $string); + } + + /** + * remove all non stamp chars from string and newline + * trim string + * + * @param string $string input string + * + * @return string + */ + public static function sanitizeNSCharsNewline($string) + { + return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\r\n]/u', '', (string) $string); + } + + /** + * Remove all non stamp chars, newline, spaces and tabulation from string + * + * @param string $string input string + * + * @return string + */ + public static function sanitizeNSCharsNewlineTabs($string) + { + return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\r\n\s]/u', '', (string) $string); + } + + /** + * remove all non stamp chars from string and newline + * trim string + * + * @param string $string input string + * + * @return string + */ + public static function sanitizeNSCharsNewlineTrim($string) + { + return trim(self::sanitizeNSCharsNewline($string)); + } + + /** + * Default filter sanitize input text, apply sanitizeNSCharsNewlineTrim function. + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV. + * @param string $var_name Name of a variable to get. + * @param string $default default value if dont exists + * + * @return string + */ + public static function sanitizeTextInput($type, $var_name, $default = '') + { + $filter = FILTER_UNSAFE_RAW; + $options = array( + 'options' => array( 'default' => null), + ); + if ($type == self::INPUT_REQUEST) { + $result = self::filterInputRequest($var_name, $filter, $options); + } else { + $result = filter_input($type, $var_name, $filter, $options); + } + if (is_null($result)) { + return $default; + } + return self::sanitizeNSCharsNewlineTrim($result); + } + + + + /** + * Determines whether a PHP ini value is changeable at runtime. + * + * @since 4.6.0 + * + * @staticvar array $ini_all + * + * @link https://secure.php.net/manual/en/function.ini-get-all.php + * + * @param string $setting The name of the ini setting to check. + * + * @return bool True if the value is changeable at runtime. False otherwise. + */ + public static function isIniValChangeable($setting) + { + // if ini_set is disabled can change the values + if (!function_exists('ini_set')) { + return false; + } + + static $ini_all; + + if (!isset($ini_all)) { + $ini_all = false; + // Sometimes `ini_get_all()` is disabled via the `disable_functions` option for "security purposes". + if (function_exists('ini_get_all')) { + $ini_all = ini_get_all(); + } + } + + // Bit operator to workaround https://bugs.php.net/bug.php?id=44936 which changes access level to 63 in PHP 5.2.6 - 5.2.17. + if (isset($ini_all[$setting]['access']) && ( INI_ALL === ( $ini_all[$setting]['access'] & 7 ) || INI_USER === ( $ini_all[$setting]['access'] & 7 ) )) { + return true; + } + + // If we were unable to retrieve the details, fail gracefully to assume it's changeable. + if (!is_array($ini_all)) { + return true; + } + + return false; + } + + /** + * get php.ini value + * + * @param string $key php ini value + * @param mixed $default default valu if init_get is disabled or key don't exists + * @param string $returnType the return type, accept only scalar values (bool, int, float, string) + * + * @return mixed + */ + public static function phpIniGet($key, $default, $returnType = 'string') + { + if (!function_exists('ini_get')) { + return $default; + } + + if (($result = ini_get($key)) === false) { + return $default; + } + + switch ($returnType) { + case "bool": + return filter_var($result, FILTER_VALIDATE_BOOLEAN); + case "int": + return (int) $result; + case "float": + return (float) $result; + case "string": + return (string) $result; + default: + throw new Exception('Invalid return type ' . $returnType); + } + } + + /** + * The val value returns if it is between min and max otherwise it returns min or max + * + * @param int|float $val input value + * @param int|float $min min value + * @param int|float $max max value + * + * @return int + */ + public static function getIntBetween($val, $min, $max) + { + return min((int) $max, max((int) $min, (int) $val)); + } + + /** + * Gets a specific external variable by name and optionally filters it by request + * + * @param string $variable_name

        Name of a variable to get.

        + * @param int $filter

        The ID of the filter to apply. The Types of filters manual page lists the available filters.

        + *

        If omitted, FILTER_DEFAULT will be used, which is equivalent to + * FILTER_UNSAFE_RAW. This will result in no filtering taking place by + * default.

        + * @param mixed[]|int $options

        Associative array of options or bitwise disjunction of flags. + * If filter accepts options, flags can be provided in "flags" field of array.

        + * + * @return mixed Value of the requested variable on success + * + * @link http://php.net/manual/en/function.filter-input.php + * @see filter_var(), filter_input_array(), filter_var_array() + */ + public static function filterInputRequest($variable_name, $filter = FILTER_DEFAULT, $options = 0) + { + if (isset($_GET[$variable_name]) && !isset($_POST[$variable_name])) { + return filter_input(INPUT_GET, $variable_name, $filter, $options); + } + + return filter_input(INPUT_POST, $variable_name, $filter, $options); + } + + /** + * Return input from type + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV, self::INPUT_REQUEST + * + * @return mixed[] + */ + public static function getInputFromType($type) + { + switch ($type) { + case INPUT_GET: + return $_GET; + case INPUT_POST: + return $_POST; + case INPUT_COOKIE: + return $_COOKIE; + case INPUT_SERVER: + return $_SERVER; + case INPUT_ENV: + return $_ENV; + case self::INPUT_REQUEST: + return array_merge($_GET, $_POST); + default: + throw new Exception('Invalid type ' . $type); + } + } + + /** + * Default filter sanitize string, apply sanitizeNSChars function. + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV. + * @param string $var_name Name of a variable to get. + * @param mixed $default default value if dont exists + * + * @return string + */ + public static function filterInputDefaultSanitizeString($type, $var_name, $default = '') + { + $filter = FILTER_UNSAFE_RAW; + $options = array( + 'options' => array( 'default' => null) + ); + if ($type == self::INPUT_REQUEST) { + $result = self::filterInputRequest($var_name, $filter, $options); + } else { + $result = filter_input($type, $var_name, $filter, $options); + } + if (is_null($result)) { + return $default; + } + return self::sanitizeNSChars($result); + } + + /** + * All characters that are not explicitly accepted are removed. + * By default, only alphanumeric characters are accepted. + * + * @param mixed $input input value + * @param string $extraAcceptChars extra accepted chars + * + * @return string|string[] + */ + public static function sanitizeStrict($input, $extraAcceptChars = '') + { + $regex = '/[^a-zA-Z0-9' . preg_quote($extraAcceptChars, '/') . ' ]/m'; + if (is_scalar($input) || is_null($input)) { + $input = (string) $input; + } elseif (is_array($input)) { + } elseif (is_object($input)) { + $input = (array) $input; + } else { + $input = ''; + } + + if (is_array($input)) { + foreach ($input as $key => $val) { + $input[$key] = self::sanitizeStrict($val, $extraAcceptChars); + } + return $input; + } + + $result = preg_replace($regex, '', $input); + return (is_null($result) ? '' : $result); + } + + /** + * Sanitize value to int + * + * @param mixed $input Input value + * @param int $default Default value if input isnt valid + * + * @return int + */ + public static function sanitizeInt($input, $default = 0) + { + if (!is_scalar($input)) { + return $default; + } elseif (is_bool($input)) { + return (int) $input; + } else { + return filter_var($input, FILTER_VALIDATE_INT, array('options' => array( 'default' => $default))); + } + } + + /** + * Sanitize value to bool + * + * @param mixed $input Input value + * + * @return bool + */ + public static function sanitizeBool($input) + { + if (!is_scalar($input)) { + return false; + } elseif (is_bool($input)) { + return $input; + } else { + return filter_var($input, FILTER_VALIDATE_BOOLEAN); + } + } + + /** + * Sanitize value from input $_GET, $_POST, $_REQUEST ... + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV or SnapUtil::INPUT_REQUEST + * @param string $varName Name of a variable to get. + * @param mixed $default default value if var $varName don't exists + * @param string $extraAcceptChars extra accepted chars + * + * @return string|string[]|mixed return default value if varName isn't defined + */ + public static function sanitizeStrictInput($type, $varName, $default = false, $extraAcceptChars = '') + { + if (($value = self::getValueByType($type, $varName)) === null) { + return $default; + } + + return self::sanitizeStrict($value, $extraAcceptChars); + } + + /** + * Sanitize value from input $_GET, $_POST, $_REQUEST ... + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV or SnapUtil::INPUT_REQUEST + * @param string $varName Name of a variable to get. + * @param int $default default value if var $varName don't exists + * + * @return int return default value if varName isn't defined + */ + public static function sanitizeIntInput($type, $varName, $default = 0) + { + if (($value = self::getValueByType($type, $varName)) === null) { + return $default; + } + + return self::sanitizeInt($value); + } + + /** + * Sanitize value from input $_GET, $_POST, $_REQUEST ... + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV or SnapUtil::INPUT_REQUEST + * @param string $varName Name of a variable to get. + * @param null|bool $default default value if var $varName don't exists + * + * @return bool return default value if varName isn't defined + */ + public static function sanitizeBoolInput($type, $varName, $default = false) + { + if (($value = self::getValueByType($type, $varName)) === null) { + return $default; + } + + return self::sanitizeBool($value); + } + + /** + * Sanitize value from input $_GET, $_POST, $_REQUEST ... + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV or SnapUtil::INPUT_REQUEST + * @param string $varName Name of a variable to get. + * @param mixed $default default value if var $varName don't exists + * + * @return string|string[]|mixed return default value if varName isn't defined + */ + public static function sanitizeInput($type, $varName, $default = false) + { + if (($value = self::getValueByType($type, $varName)) === null) { + return $default; + } + return self::sanitize($value); + } + + /** + * Return value input by type null if don't exists + * + * @param int $type One of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV or SnapUtil::INPUT_REQUEST + * @param string $varName Name of a variable to get. + * + * @return string|string[]|null + */ + protected static function getValueByType($type, $varName) + { + $doNothingCallback = function ($v) { + return $v; + }; + + if ($type === self::INPUT_REQUEST) { + $type = ((isset($_GET[$varName]) && !isset($_POST[$varName])) ? INPUT_GET : INPUT_POST); + } + $value = filter_input($type, $varName, FILTER_CALLBACK, array('options' => $doNothingCallback)); + + /** @var string|string[]|null $value */ + return $value; + } + + /** + * Gets external variables and optionally filters them + *

        This function is useful for retrieving many values without repetitively calling filter_input().

        + * + * @param mixed[]|int $definition

        An array defining the arguments. + * A valid key is a string containing a variable name and a valid value is either a filter type, + * or an array optionally specifying the filter, flags and options. + * If the value is an array, valid keys are filter which specifies the filter type, + * flags which specifies any flags that apply to the filter, and options + * which specifies any options that apply to the filter. See the example below for a better understanding.

        + *

        This parameter can be also an integer holding a filter constant. + * Then all values in the input array are filtered by this filter.

        + * @param bool $add_empty

        Add missing keys as NULL to the return value.

        + * + * @return mixed An array containing the values of the requested variables on success. + * + * @link http://php.net/manual/en/function.filter-input-array.php + * @see filter_input(), filter_var_array() + */ + public static function filterInputRequestArray($definition = FILTER_DEFAULT, $add_empty = true) + { + if (!is_array($definition) || count($definition) === 0) { + return array(); + } + $getKeys = array_keys($_GET); + $postKeys = array_keys($_POST); + $keys = array_keys($definition); + + if (count(array_intersect($keys, $getKeys)) && !count(array_intersect($keys, $postKeys))) { + $type = INPUT_GET; + } else { + $type = INPUT_POST; + } + + // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctionParameters.filter_input_array_add_emptyFound + $result = filter_input_array($type, $definition, $add_empty); + + if (!is_array($result)) { + $result = array(); + foreach ($keys as $key) { + $result[$key] = null; + } + } + return $result; + } + + /** + * Close all buffers and return content + * + * @param bool $getContent If true it returns buffer content, otherwise it is discarded + * + * @return string + */ + public static function obCleanAll($getContent = true) + { + $result = ''; + for ($i = 0; $i < ob_get_level(); $i++) { + if ($getContent) { + $result .= ob_get_contents(); + } + ob_clean(); + } + return $result; + } + + /** + * Array map recursively + * + * @param callable $callback callback function + * @param mixed[] $array array input + * + * @return mixed[] + */ + public static function arrayMapRecursive($callback, $array) + { + if (!is_array($array)) { + throw new Exception('$array must be an array'); + } + if (!is_callable($callback)) { + throw new Exception('$callback must be callable'); + } + $func = function ($item) use (&$func, &$callback) { + return is_array($item) ? array_map($func, $item) : call_user_func($callback, $item); + }; + return array_map($func, $array); + } + + /** + * Implemented array_key_first + * + * @link https://www.php.net/manual/en/function.array-key-first.php + * + * @param mixed[] $arr array input + * + * @return int|string|null + */ + public static function arrayKeyFirst($arr) + { + if (!function_exists('array_key_first')) { + foreach ($arr as $key => $unused) { + return $key; + } + return null; + } else { + // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.array_key_firstFound + return array_key_first($arr); + } + } + + /** + * Get number of bit supported by PHP + * + * @return string + */ + public static function getArchitectureString() + { + return (PHP_INT_SIZE * 8) . '-bit'; + } + + /** + * In array check by callback + * + * @param mixed[] $haystack array input + * @param callable $callback callback function + * + * @return null|bool + */ + public static function inArrayExtended($haystack, $callback) + { + if (!is_callable($callback)) { + return null; + } + + foreach ($haystack as $value) { + if (call_user_func($callback, $value)) { + return true; + } + } + + return false; + } + + /** + * This is a binary recursion, so it only works on an ordered array of integers. + * (If it is not ordered, it does not work) + * + * The advantage of using this search instead of normal array search is that the complexity goes from O(n) to O(log n). + * + * @param int[] $array array values + * @param int $x element to search + * + * @return bool + */ + public static function binarySearch($array, $x) + { + if (count($array) === 0) { + return false; + } + $low = 0; + $high = count($array) - 1; + + while ($low <= $high) { + $mid = floor(($low + $high) / 2); + + if ($array[$mid] == $x) { + return true; + } + if ($x < $array[$mid]) { + $high = $mid - 1; + } else { + $low = $mid + 1; + } + } + return false; + } + + /** + * Generates a random password drawn from the defined set of characters. + * Copy of the wp_generate_password() function from wp-includes/pluggable.php with minor tweaks + * + * @param int $length Optional. The length of password to generate. Default 12. + * @param bool $special_chars Optional. Whether to include standard special characters. + * Default true. + * @param bool $extra_special_chars Optional. Whether to include other special characters. + * Used when generating secret keys and salts. Default false. + * + * @return string The random password. + */ + public static function generatePassword($length = 12, $special_chars = true, $extra_special_chars = false) + { + $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + if ($special_chars) { + $chars .= '!@#$%^&*()'; + } + if ($extra_special_chars) { + $chars .= '-_ []{}<>~`+=,.;:/?|'; + } + + $password = ''; + for ($i = 0; $i < $length; $i++) { + $password .= substr($chars, self::rand(0, strlen($chars) - 1), 1); + } + + return $password; + } + + /** + * Generates a random number + * Copy of the wp_rand() function from wp-includes/pluggable.php with minor tweaks + * + * @param int $min Lower limit for the generated number + * @param int $max Upper limit for the generated number + * + * @return int A random number between min and max + */ + public static function rand($min = 0, $max = 0) + { + global $rnd_value; + // Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers + // larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats. + $max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // @phpstan-ignore-line + // 4294967295 = 0xffffffff + // We only handle Ints, floats are truncated to their integer value. + $min = (int) $min; + $max = (int) $max; + // Use PHP's CSPRNG, or a compatible method + static $use_random_int_functionality = null; + if (is_null($use_random_int_functionality)) { + $use_random_int_functionality = function_exists('random_int'); + } + if ($use_random_int_functionality) { + try { + $_max = ( 0 != $max ) ? $max : $max_random_number; + // rand() can accept arguments in either order, PHP cannot. + $_max = max($min, $_max); + $_min = min($min, $_max); + // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.random_intFound + $val = random_int($_min, $_max); + if (false !== $val) { + return abs(intval($val)); + } else { // @phpstan-ignore-line + $use_random_int_functionality = false; + } + } catch (Error $e) { + $use_random_int_functionality = false; + } catch (Exception $e) { + $use_random_int_functionality = false; + } + } + + // Reset $rnd_value after 14 uses + // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value + if (strlen($rnd_value) < 8) { + static $seed = ''; + $rnd_value = md5(uniqid(microtime() . mt_rand(), true) . $seed); + $rnd_value .= sha1($rnd_value); + $rnd_value .= sha1($rnd_value . $seed); + $seed = md5($seed . $rnd_value); + } + + // Take the first 8 digits for our value + $value = substr($rnd_value, 0, 8); + // Strip the first eight, leaving the remainder for the next call to rand(). + $rnd_value = substr($rnd_value, 8); + $value = abs(hexdec($value)); + // Reduce the value to be within the min - max range + if ($max != 0) { + $value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 ); + } + + return abs(intval($value)); + } + + /** + * Returns true if the class exists, false otherwise + * + * @param string $className Name of the class to check if it exists + * @param boolean $autoload Parameter that will be passed to class_exists as second + * + * @return boolean + */ + public static function classExists($className, $autoload = true) + { + if (!class_exists($className, $autoload)) { + return false; + } + if (function_exists("ini_get")) { + $disabled = explode(',', ini_get('disable_classes')); + return in_array($className, $disabled) ? false : true; + } + // We can only suppose that it exists, can't be 100% sure, but it's the best guess + return true; + } + + /** + * Function phpinfo wrapper + * + * @see https://www.php.net/manual/en/function.phpinfo.php + * + * @param int $flags see phpinfo function flags + * + * @return bool Returns true on success or false on failure. + */ + public static function phpinfo($flags = INFO_ALL) + { + if (!function_exists('phpinfo')) { + return false; + } + return phpinfo($flags); + } + + /** + * Wrapper for set_time_limit to see if it is enabled. + * + * @since 1.6.4 + * + * @param int $limit Time limit. + * + * @return void + */ + public static function duplicatorSetTimeLimit($limit = 0) + { + + if ( + function_exists('set_time_limit') && + false === strpos(ini_get('disable_functions'), 'set_time_limit') && + ! ini_get('safe_mode') + ) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved + @set_time_limit( $limit ); // @codingStandardsIgnoreLine + } + } + + /** + * Wrapper for error_log to call only if it is enabled. + * + * @param string $message The error message that should be logged. + * @param int $message_type The type of error. It can be 0, 1, 2, 3 or 4. + * @param string|null $destination The destination of the error message. It can be a file, email, or a syslog. + * @param string|null $additional_headers Additional headers to be sent with the email. + * + * @return bool Returns true on success or false on failure. + */ + public static function errorLog($message, $message_type = 0, $destination = null, $additional_headers = null) + { + if (function_exists('error_log')) { + return error_log($message, $message_type, $destination, $additional_headers); + } + return false; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapWP.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapWP.php new file mode 100644 index 0000000..d12127c --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/SnapWP.php @@ -0,0 +1,1052 @@ + initialized inside wordpress_core_files.php */ + private static $corePathList = null; + + /** + * return safe ABSPATH without last / + * perform safe function only one time + * + * @return string + */ + public static function getSafeAbsPath() + { + static $safeAbsPath = null; + + if (is_null($safeAbsPath)) { + if (defined('ABSPATH')) { + $safeAbsPath = SnapIO::safePathUntrailingslashit(ABSPATH); + } else { + $safeAbsPath = ''; + } + } + + return $safeAbsPath; + } + + + /** + * Return wp-config path or false if not found + * + * @return bool|string + */ + public static function getWPConfigPath() + { + static $configPath = null; + if (is_null($configPath)) { + $absPath = SnapIO::safePathTrailingslashit(ABSPATH, true); + $absParent = dirname($absPath) . '/'; + + if (file_exists($absPath . 'wp-config.php')) { + $configPath = $absPath . 'wp-config.php'; + } elseif (@file_exists($absParent . 'wp-config.php') && !@file_exists($absParent . 'wp-settings.php')) { + $configPath = $absParent . 'wp-config.php'; + } else { + $configPath = false; + } + } + return $configPath; + } + + + /** + * Get wordpress table info by table name + * + * @param string $table table name + * @param string $prefix wordpress prefix + * + * @return array{isCore: bool, havePrefix: bool, subsiteId: int, isMultisiteCore: bool} + */ + public static function getTableInfoByName($table, $prefix) + { + $result = array( + 'isCore' => false, + 'havePrefix' => false, + 'subsiteId' => -1, + 'isMultisiteCore' => false + ); + + if (preg_match('/^' . preg_quote($prefix, '/') . '(?:(\d+)_)?(.+)/', $table, $matches) !== 1) { + return $result; + } + + $result['havePrefix'] = true; + $nameWithoutPrefix = $matches[2]; + $result['isMultisiteCore'] = in_array($nameWithoutPrefix, self::getMultisiteTables()); + $result['isCore'] = $result['isMultisiteCore'] || in_array($nameWithoutPrefix, self::getSiteCoreTables()); + + if (is_numeric($matches[1])) { + $result['subsiteId'] = (int) $matches[1]; + } elseif (!$result['isMultisiteCore']) { + $result['subsiteId'] = 1; + } + return $result; + } + + /** + * Get the list of wp prefixes from given tables list + * + * @param string[] $tables List of table names to check for unique WP prefixes + * + * @return string[] + */ + public static function getUniqueWPTablePrefixes($tables) + { + $userPrefix = array(); + $userMetaPrefix = array(); + + foreach ($tables as $table) { + if (preg_match("/^(.*)users$/m", $table, $matches)) { + $userPrefix[] = $matches[1]; + } elseif (preg_match("/^(.*)usermeta$/m", $table, $matches)) { + $userMetaPrefix[] = $matches[1]; + } + } + + return array_intersect($userPrefix, $userMetaPrefix); + } + + /** + * Modifies the database based on specified SQL statements. + * + * Useful for creating new tables and updating existing tables to a new structure. + * + * From Wordpress dbDelta + * + * @global \wpdb $wpdb WordPress database abstraction object. + * + * @param string[]|string $queries Optional. The query to run. Can be multiple queries + * in an array, or a string of queries separated by + * semicolons. Default empty string. + * @param bool $execute Optional. Whether or not to execute the query right away. + * Default true. + * + * @return string[] Strings containing the results of the various update queries. + */ + public static function dbDelta($queries = '', $execute = true) + { + $mysqliDriver = new \mysqli_driver(); + + $defReporting = $mysqliDriver->report_mode; + mysqli_report(MYSQLI_REPORT_OFF); + + $result = dbDelta($queries, $execute); + mysqli_report($defReporting); + + return $result; + } + + /** + * Schedules cron event if it's not already scheduled. + * + * @param int $timestamp Timestamp of the first next run time + * @param string $cronIntervalName Name of cron interval to be used + * @param string $hook Hook that we want to assign to the given cron interval + * + * @return void + */ + public static function scheduleEvent($timestamp, $cronIntervalName, $hook) + { + if (!wp_next_scheduled($hook)) { + // Assign the hook to the schedule + wp_schedule_event($timestamp, $cronIntervalName, $hook); + } + } + + /** + * Unschedules cron event if it's scheduled. + * + * @param string $hook Name of the hook that we want to unschedule + * + * @return void + */ + public static function unscheduleEvent($hook) + { + if (wp_next_scheduled($hook)) { + // Unschedule the hook + $timestamp = wp_next_scheduled($hook); + wp_unschedule_event($timestamp, $hook); + } + } + + /** + * Get Auto_increment value of wp_blogs table in multisite. + * That is id of the first next subsite that will be imported. + * + * @return int // returns Auto_increment value of wp_blogs table in multisite, + * // returns -1 if Auto_increment value can not be obtained for any reason + */ + public static function getNextSubsiteIdAI() + { + $nextSubsiteIdAI = -1; + if (!is_multisite()) { + return $nextSubsiteIdAI; + } + /** @var \wpdb $wpdb */ + global $wpdb; + + $sql = $wpdb->prepare("SHOW TABLE STATUS LIKE %s", $wpdb->prefix . "blogs"); + $result = $wpdb->get_results($sql, ARRAY_A); + if (count($result) < 1) { + return $nextSubsiteIdAI; + } + $row = $result[0]; + if (array_key_exists("Auto_increment", $row)) { + $nextSubsiteIdAI = intval($row["Auto_increment"]); + } + return $nextSubsiteIdAI; + } + + /** + * From a tables list filters all tables without WP prefix + * + * @param string[] $tables tables list + * + * @return string[] + */ + public static function getTablesWithPrefix($tables) + { + /** @var \wpdb $wpdb */ + global $wpdb; + + $tables = (array) $tables; + + $result = array(); + + foreach ($tables as $table) { + if (strpos($table, $wpdb->prefix) === 0) { + $result[] = $table; + } + } + return $result; + } + + /** + * Check if passed folder is home folder + * + * @param string $folder folder path + * + * @return boolean return true if folder is wordpress home folder + */ + public static function isWpHomeFolder($folder) + { + $indexPhp = SnapIO::trailingslashit($folder) . 'index.php'; + if (!file_exists($indexPhp)) { + return false; + } + + if (($indexContent = file_get_contents($indexPhp)) === false) { + return false; + } + + return (preg_match('/^.*\srequire.*?[\'"].*wp-blog-header\.php[\'"].*?;.*$/s', $indexContent) === 1); + } + + /** + * This function is the equivalent of the get_home_path function but with various fixes + * + * @return string + */ + public static function getHomePath() + { + static $home_path = null; + + if (is_null($home_path)) { + // outside wordpress this function makes no sense + if (!defined('ABSPATH')) { + $home_path = ''; + return $home_path; + } + + if (isset($_SERVER['SCRIPT_FILENAME']) && is_readable($_SERVER['SCRIPT_FILENAME'])) { + $scriptFilename = $_SERVER['SCRIPT_FILENAME']; + } else { + $files = get_included_files(); + $scriptFilename = array_shift($files); + } + + $realScriptDirname = SnapIO::safePathTrailingslashit(dirname($scriptFilename), true); + $realAbsPath = SnapIO::safePathTrailingslashit(ABSPATH, true); + + if (strpos($realScriptDirname, $realAbsPath) === 0) { + // normalize URLs without www + $home = SnapURL::wwwRemove(set_url_scheme(get_option('home'), 'http')); + $siteurl = SnapURL::wwwRemove(set_url_scheme(get_option('siteurl'), 'http')); + + if (!empty($home) && 0 !== strcasecmp($home, $siteurl)) { + if (stripos($siteurl, $home) === 0) { + $wp_path_rel_to_home = str_ireplace($home, '', $siteurl); /* $siteurl - $home */ + $pos = strripos( + str_replace('\\', '/', $scriptFilename), + SnapIO::trailingslashit($wp_path_rel_to_home) + ); + $home_path = substr($scriptFilename, 0, $pos); + $home_path = SnapIO::trailingslashit($home_path); + } else { + $home_path = ABSPATH; + } + } else { + $home_path = ABSPATH; + } + } else { + // On frontend the home path is the folder of index.php + $home_path = SnapIO::trailingslashit(dirname($scriptFilename)); + } + + // make sure the folder exists or consider ABSPATH + if (!file_exists($home_path)) { + $home_path = ABSPATH; + } + + $home_path = str_replace('\\', '/', $home_path); + } + return $home_path; + } + + /** + * Return admin url, if is multisite return network_admin_url + * + * @param string $path Optional. Path relative to the admin URL. Default 'admin'. + * @param string $scheme The scheme to use. Default is 'admin', which obeys force_ssl_admin() and is_ssl(). + * 'http' or 'https' can be passed to force those schemes. + * + * @return string Admin URL link with optional path appended. + */ + public static function getAdminUrl($path, $scheme = 'admin') + { + if (is_multisite()) { + return network_admin_url($path, $scheme); + } else { + return admin_url($path, $scheme); + } + } + + + /** + * Ser relative abs path + * + * @param string $string abs path + * + * @return void + */ + public static function setWpCoreRelativeAbsPath($string = '') + { + self::$wpCoreRelativePath = (string) $string; + } + + /** + * check if path is in wordpress core list + * PATH_FULL and PATH_RELATIVE is better optimized and perform less operations + * + * @param string $path file path + * @param int $fullPath if PATH_AUTO check if is a full path or relative path + * if PATH_FULL remove ABSPATH len without check + * if PATH_RELATIVE consider path a relative path + * @param bool $isSafe if false call rtrim(SnapIO::safePath( PATH ), '/') + * if true consider path a safe path without check + * + * @return boolean + */ + public static function isWpCore($path, $fullPath = self::PATH_AUTO, $isSafe = false) + { + if ($isSafe == false) { + $path = rtrim(SnapIO::safePath($path), '/'); + } + + switch ($fullPath) { + case self::PATH_FULL: + $absPath = self::getSafeAbsPath(); + if (strlen($path) < strlen($absPath)) { + return false; + } + $relPath = ltrim(substr($path, strlen($absPath)), '/'); + break; + case self::PATH_RELATIVE: + if (($relPath = SnapIO::getRelativePath($path, self::$wpCoreRelativePath)) === false) { + return false; + } + break; + case self::PATH_AUTO: + default: + $absPath = self::getSafeAbsPath(); + if (strpos($path, $absPath) === 0) { + $relPath = ltrim(substr($path, strlen($absPath)), '/'); + } else { + $relPath = ltrim($path, '/'); + } + } + + // if rel path is empty is consider root path so is a core folder. + if (strlen($relPath) === 0) { + return true; + } + + $pExploded = explode('/', $relPath); + $corePaths = self::getCorePathsList(); + + foreach ($pExploded as $current) { + if (!isset($corePaths[$current])) { + return false; + } + + if (is_scalar($corePaths[$current])) { + // is file so don't have childs + $corePaths = array(); + } else { + $corePaths = $corePaths[$current]; + } + } + return true; + } + + /** + * + * @param string $relPath If empty is consider abs root path + * + * @return array{dirs: string[], files: string[]} + */ + public static function getWpCoreFilesListInFolder($relPath = '') + { + $corePaths = self::getCorePathsList(); + if (strlen($relPath) > 0) { + $pExploded = explode('/', $relPath); + foreach ($pExploded as $current) { + if (!isset($corePaths[$current])) { + $corePaths = array(); + break; + } + + if (is_scalar($corePaths[$current])) { + // is file so don't have childs + $corePaths = array(); + } else { + $corePaths = $corePaths[$current]; + } + } + } + + $result = array( + 'dirs' => array(), + 'files' => array() + ); + + foreach ($corePaths as $name => $content) { + if (is_array($content)) { + $result['dirs'][] = $name; + } else { + $result['files'][] = $name; + } + } + + return $result; + } + + /** + * Get core path list from relative abs path + * [ + * 'folder' => [ + * 's-folder1' => [ + * file1 => [], + * file2 => [], + * ], + * 's-folder2' => [], + * file1 => [] + * ] + * ] + * + * @return array + */ + public static function getCorePathsList() + { + if (is_null(self::$corePathList)) { + require_once(__DIR__ . '/wordpress_core_files.php'); + } + return self::$corePathList; + } + + /** + * Get List of core folders inside the wp-content folder + * + * @return string[] + */ + public static function getWPContentCoreDirs() + { + return array( + 'languages', + 'cache' + ); + } + + /** + * Returns the main site ID for the network. + * + * Copied from the source of the get_main_site_id() except first line in https://developer.wordpress.org/reference/functions/get_main_site_id/ + * get_main_site_id() is introduced in WP 4.9.0. It is for backward compatibility + * + * @param int|null $network_id network id + * + * @return int The ID of the main site. + */ + public static function getMainSiteId($network_id = null) + { + get_main_site_id($network_id); + } + + /** + * Return object list of sites + * + * @param string|array $args list of filters, see wordpress get_sites function + * + * @return false|WP_Site[]|int[] site list or ids or false if isn't multisite + */ + public static function getSites($args = array()) + { + if (!function_exists('is_multisite') || !is_multisite()) { + return false; + } + + if (!isset($args['number'])) { + $args['number'] = self::DEFAULT_MAX_GET_SITES_NUMBER; + } + + if (function_exists('get_sites')) { + return get_sites($args); + } else { + $result = array(); + $blogs = wp_get_sites($args); + $returnIds = (isset($args['fields']) && $args['fields'] === 'ids'); + foreach ($blogs as $blog) { + if (is_array($blog)) { + $blog = (object) $blog; + } + $result[] = ($returnIds ? $blog->blog_id : $blog); + } + return $result; + } + } + + /** + * Return list of subiste ids + * + * @return int[] + */ + public static function getSitesIds() + { + if (!is_multisite()) { + return array(1); + } + + return SnapWP::getSites(array('fields' => 'ids')); + } + + /** + * return the list of possible dropins plugins + * + * @return string[] + */ + public static function getDropinsPluginsNames() + { + return array( + 'advanced-cache.php', // WP_CACHE + 'db.php', // auto on load + 'db-error.php', // auto on error + 'install.php', // auto on installation + 'maintenance.php', // auto on maintenance + 'object-cache.php', // auto on load + 'php-error.php', // auto on error + 'fatal-error-handler.php', // auto on error + 'sunrise.php', + 'blog-deleted.php', + 'blog-inactive.php', + 'blog-suspended.php' + ); + } + + /** + * Return site and subsite tables names without prefix + * + * @return string[] + */ + public static function getSiteCoreTables() + { + return array( + 'commentmeta', + 'comments', + 'links', + 'options', + 'postmeta', + 'posts', + 'term_relationships', + 'term_taxonomy', + 'terms', + 'termmeta' + ); + } + + /** + * Return multisite general tables without prefix + * + * @return string[] + */ + public static function getMultisiteTables() + { + return array( + 'blogmeta', + 'blogs', + 'blog_versions', + 'registration_log', + 'signups', + 'site', + 'sitemeta' + ); + } + + /** + * Returns gmt_offset * 3600 + * + * @return int timezone offset in seconds + */ + public static function getGMTOffset() + { + return get_option('gmt_offset') ? ((float) get_option('gmt_offset')) * 3600 : 0; + } + + /** + * Returns wp option "timezone_string" + * + * @return string // timezone_string, will be empty if manual offset is chosen + */ + public static function getTimeZoneString() + { + static $timezoneString = null; + if (is_null($timezoneString)) { + $timezoneString = get_option('timezone_string'); + } + return $timezoneString; + } + + /** + * Returns 1 if DST is active on given timestamp, 0 if it's not active. + * Currently active timezone is taken into account. + * + * @param int $timestamp In seconds + * + * @return int 1 if DST is active, 0 otherwise + */ + public static function getDST($timestamp) + { + $timezoneString = self::getTimeZoneString(); + if (!$timezoneString) { + // There is no DST if manual offset is chosen in WP settings timezone + return 0; + } + $date = new \DateTime(); + $date->setTimestamp($timestamp); + $date->setTimezone(new \DateTimeZone($timezoneString)); + return (int) $date->format('I'); + } + + /** + * Converts timestamp to date string with given format, according to + * currently selected timezone in Wordpress settings + * + * @param string $format Format for date + * @param int $timestamp In seconds + * + * @return string Date converted to string in currently selected timezone + */ + public static function getDateInWPTimezone($format, $timestamp) + { + $timezoneString = self::getTimeZoneString(); + if ($timezoneString) { + // Particular timezone is selected, not manual offset. This means that DST could be in place, + // and we can't use current gmt_offset. We have to use the timezone! + $date = new \DateTime(); + $date->setTimestamp($timestamp); + $date->setTimezone(new \DateTimeZone($timezoneString)); + return $date->format($format); + } + // Manual offset is selected. In this case there is no DST so we can + // create the date string using current gmt_offset. + $local_time = $timestamp + SnapWP::getGMTOffset(); + return (string) date($format, $local_time); + } + + /** + * + * @param int $blogId if multisite and blogId > 0 return the user of blog + * + * @return array + */ + public static function getAdminUserLists($blogId = 0) + { + $args = array( + 'fields' => array('ID', 'user_login') + ); + + if (is_multisite()) { + $args['blog_id'] = $blogId; + if ($blogId == 0) { + $args['login__in'] = get_site_option('site_admins'); + } + } else { + $args['role'] = 'administrator'; + } + + return get_users($args); + } + + /** + * Get users count + * + * @return int + */ + public static function getUsersCount() + { + global $wpdb; + $table = esc_sql($wpdb->users); + return (int) $wpdb->get_var("SELECT COUNT(ID) FROM {$table}"); + } + + /** + * Return post types count + * + * @return array + */ + public static function getPostTypesCount() + { + $postTypes = get_post_types(); + $postTypeCount = array(); + + foreach ($postTypes as $postName) { + $postObj = get_post_type_object($postName); + if (!$postObj->public) { + continue; + } + + /** @var int[] */ + $postCountForTypes = (array) wp_count_posts($postName); + $postCount = 0; + foreach ($postCountForTypes as $num) { + $postCount += $num; + } + $postTypeCount[$postObj->label] = $postCount; + } + + return $postTypeCount; + } + + /** + * Get plugins array info with multisite, must-use and drop-ins + * + * @param string $key User meta key + * + * @return bool true on success, false on failure + */ + public static function deleteUserMetaKey($key) + { + /** @var wpdb $wpdb */ + global $wpdb; + + if ( + $wpdb->delete( + $wpdb->usermeta, + array('meta_key' => $key), + array('%s') + ) === false + ) { + return false; + } + + return true; + } + + /** + * return plugin formatted data from plugin info + * + * @param WP_Theme $theme instance of WP Core class WP_Theme. theme info from get_themes function + * + * @return array + */ + protected static function getThemeArrayData(WP_Theme $theme) + { + $slug = $theme->get_stylesheet(); + $parent = $theme->parent(); + return array( + 'slug' => $slug, + 'themeName' => $theme->get('Name'), + 'version' => $theme->get('Version'), + 'themeURI' => $theme->get('ThemeURI'), + 'parentTheme' => (false === $parent) ? false : $parent->get_stylesheet(), + 'template' => $theme->get_template(), + 'stylesheet' => $theme->get_stylesheet(), + 'description' => $theme->get('Description'), + 'author' => $theme->get('Author'), + "authorURI" => $theme->get('AuthorURI'), + 'tags' => $theme->get('Tags'), + 'isAllowed' => $theme->is_allowed(), + 'isActive' => (is_multisite() ? array() : false), + 'defaultTheme' => (defined('WP_DEFAULT_THEME') && WP_DEFAULT_THEME == $slug), + ); + } + + /** + * get themes array info with active template, stylesheet + * + * @return array + */ + public static function getThemesInfo() + { + if (!function_exists('wp_get_themes')) { + require_once ABSPATH . 'wp-admin/includes/theme.php'; + } + + $result = array(); + + foreach (wp_get_themes() as $slug => $theme) { + $result[$slug] = self::getThemeArrayData($theme); + } + + if (is_multisite()) { + foreach (SnapWP::getSitesIds() as $siteId) { + switch_to_blog($siteId); + $stylesheet = get_stylesheet(); + if (isset($result[$stylesheet])) { + $result[$stylesheet]['isActive'][] = $siteId; + } + + //Also set parent theme to active if it exists + $template = get_template(); + if ($template !== $stylesheet && isset($result[$template])) { + $result[$template]['isActive'][] = $siteId; + } + + restore_current_blog(); + } + } else { + $stylesheet = get_stylesheet(); + if (isset($result[$stylesheet])) { + $result[$stylesheet]['isActive'] = true; + } + + //Also set parent theme to active if it exists + $template = get_template(); + if ($template !== $stylesheet && isset($result[$template])) { + $result[$template]['isActive'] = true; + } + } + + return $result; + } + + /** + * Get plugins array info with multisite, must-use and drop-ins + * + * @param int $filter ENUM: PLUGIN_INFO_ALL, PLUGIN_INFO_ACTIVE, PLUGIN_INFO_INACTIVE + * + * @return array + */ + public static function getPluginsInfo($filter = self::PLUGIN_INFO_ALL) + { + if (!defined('ABSPATH')) { + throw new Exception('This function can be used only on wp'); + } + + if (!function_exists('get_plugins')) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + // parse all plugins + $result = array(); + foreach (get_plugins() as $path => $plugin) { + $result[$path] = self::getPluginArrayData($path, $plugin); + $result[$path]['networkActive'] = is_plugin_active_for_network($path); + if (!is_multisite()) { + $result[$path]['active'] = is_plugin_active($path); + } else { + // if is _multisite the active value is an array with the blog ids list where the plugin is active + $result[$path]['active'] = array(); + } + } + + // If is _multisite the active value is an array with the blog ids list where the plugin is active + if (is_multisite()) { + foreach (SnapWP::getSitesIds() as $siteId) { + switch_to_blog($siteId); + foreach ($result as $path => $plugin) { + if (!$result[$path]['networkActive'] && is_plugin_active($path)) { + $result[$path]['active'][] = $siteId; + } + } + restore_current_blog(); + } + } + + // parse all must use plugins + foreach (get_mu_plugins() as $path => $plugin) { + $result[$path] = self::getPluginArrayData($path, $plugin); + $result[$path]['mustUse'] = true; + } + + // parse all dropins plugins + foreach (get_dropins() as $path => $plugin) { + $result[$path] = self::getPluginArrayData($path, $plugin); + $result[$path]['dropIns'] = true; + } + + switch ($filter) { + case self::PLUGIN_INFO_ACTIVE: + return array_filter( + $result, + function ($info) { + return SnapWP::isPluginActiveByInfo($info); + } + ); + case self::PLUGIN_INFO_INACTIVE: + return array_filter( + $result, + function ($info) { + return !SnapWP::isPluginActiveByInfo($info); + } + ); + case self::PLUGIN_INFO_ALL: + default: + return $result; + } + } + + /** + * Determine if a plugin is active by info + * + * @param array{active: bool|bool[], networkActive: bool, dropIns: bool, mustUse: bool} $info Plugin info + * + * @return bool + */ + protected static function isPluginActiveByInfo($info) + { + return ( + $info['active'] === true || + $info['networkActive'] || + ( + is_array($info['active']) && + !empty($info['active']) + ) || + $info['dropIns'] || + $info['mustUse'] + ); + } + + /** + * Check if a plugin is installed + * + * @param string $pluginSlug plugin slug + * + * @return bool + */ + public static function isPluginInstalled($pluginSlug) + { + if (!defined('ABSPATH')) { + throw new Exception('This function can be used only on wp'); + } + + if (!function_exists('get_plugins')) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $plugins = array_keys(get_plugins()); + return in_array($pluginSlug, $plugins); + } + + /** + * return plugin formatted data from plugin info + * plugin info = Array ( + * [Name] => Hello Dolly + * [PluginURI] => http://wordpress.org/extend/plugins/hello-dolly/ + * [Version] => 1.6 + * [Description] => This is not just ... + * [Author] => Matt Mullenweg + * [AuthorURI] => http://ma.tt/ + * [TextDomain] => + * [DomainPath] => + * [Network] => + * [Title] => Hello Dolly + * [AuthorName] => Matt Mullenweg + * ) + * + * @param string $slug plugin slug + * @param array $plugin pluhin info from get_plugins function + * + * @return array + */ + protected static function getPluginArrayData($slug, $plugin) + { + return array( + 'slug' => $slug, + 'name' => $plugin['Name'], + 'version' => $plugin['Version'], + 'pluginURI' => $plugin['PluginURI'], + 'author' => $plugin['Author'], + 'authorURI' => $plugin['AuthorURI'], + 'description' => $plugin['Description'], + 'title' => $plugin['Title'], + 'networkActive' => false, + 'active' => false, + 'mustUse' => false, + 'dropIns' => false + ); + } + + /** + * Retrieves the global WP_Roles instance and instantiates it if necessary. + * Added for compatibility with WP < 4.3 + * + * @return WP_Roles WP_Roles global instance if not already instantiated. + */ + public static function wpRoles() + { + if (function_exists('wp_roles')) { + return wp_roles(); + } + global $wp_roles; + if (! isset($wp_roles)) { + $wp_roles = new WP_Roles(); + } + return $wp_roles; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/Snap/index.php b/html/wp-content/plugins/duplicator/src/Libs/Snap/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/Snap/index.php @@ -0,0 +1,3 @@ +>>>>> THIS FILE IS GENERATED WITH A SCRIPT, DON'T EDIT IT DIRECTLY <<<<< + * >>>>>> USE THE GENERATOR SCRIPT <<<<< + * + * >>>>>> THIS FILE IS GENERATED WITH A SCRIPT, DON'T EDIT IT DIRECTLY <<<<< + * >>>>>> USE THE GENERATOR SCRIPT <<<<< + * + * >>>>>> THIS FILE IS GENERATED WITH A SCRIPT, DON'T EDIT IT DIRECTLY <<<<< + * >>>>>> USE THE GENERATOR SCRIPT <<<<< + */ + +defined('ABSPATH') || defined('DUPXABSPATH') || exit; + +/* + * >>>>>> THIS FILE IS GENERATED WITH A SCRIPT, DON'T EDIT IT DIRECTLY <<<<< + * >>>>>> USE THE GENERATOR SCRIPT <<<<< + * + * >>>>>> THIS FILE IS GENERATED WITH A SCRIPT, DON'T EDIT IT DIRECTLY <<<<< + * >>>>>> USE THE GENERATOR SCRIPT <<<<< + * + * >>>>>> THIS FILE IS GENERATED WITH A SCRIPT, DON'T EDIT IT DIRECTLY <<<<< + * >>>>>> USE THE GENERATOR SCRIPT <<<<< + */ + +// @phpstan-ignore-next-line +self::$corePathList = array( + 'wp-login.php' => "f", + 'wp-cron.php' => "f", + 'wp-mail.php' => "f", + 'wp-blog-header.php' => "f", + 'license.txt' => "f", + 'wp-activate.php' => "f", + 'wp-settings.php' => "f", + 'wp-config-sample.php' => "f", + 'readme.html' => "f", + 'wp-comments-post.php' => "f", + 'wp-signup.php' => "f", + 'wp-load.php' => "f", + 'index.php' => "f", + 'xmlrpc.php' => "f", + 'wp-trackback.php' => "f", + 'wp-links-opml.php' => "f", + 'wp-admin' => array( + 'import.php' => "f", + 'admin.php' => "f", + 'site-editor.php' => "f", + 'ms-options.php' => "f", + 'update.php' => "f", + 'custom-background.php' => "f", + 'privacy-policy-guide.php' => "f", + 'user-new.php' => "f", + 'privacy.php' => "f", + 'link-manager.php' => "f", + 'upgrade.php' => "f", + 'tools.php' => "f", + 'post-new.php' => "f", + 'update-core.php' => "f", + 'options-head.php' => "f", + 'js' => array( + 'tags-suggest.min.js' => "f", + 'auth-app.js' => "f", + 'media-gallery.min.js' => "f", + 'press-this.js' => "f", + 'image-edit.js' => "f", + 'editor.min.js' => "f", + 'inline-edit-post.js' => "f", + 'custom-background.min.js' => "f", + 'user-profile.min.js' => "f", + 'dashboard.js' => "f", + 'theme.js' => "f", + 'media-gallery.js' => "f", + 'site-health.min.js' => "f", + 'set-post-thumbnail.min.js' => "f", + 'application-passwords.min.js' => "f", + 'customize-nav-menus.js' => "f", + 'common.js' => "f", + 'media-upload.min.js' => "f", + 'password-strength-meter.min.js' => "f", + 'wp-fullscreen-stub.js' => "f", + 'link.js' => "f", + 'updates.js' => "f", + 'customize-widgets.min.js' => "f", + 'revisions.min.js' => "f", + 'color-picker.min.js' => "f", + 'inline-edit-tax.min.js' => "f", + 'bookmarklet.min.js' => "f", + 'widgets' => array( + 'media-audio-widget.min.js' => "f", + 'custom-html-widgets.min.js' => "f", + 'text-widgets.min.js' => "f", + 'media-video-widget.min.js' => "f", + 'media-widgets.js' => "f", + 'media-video-widget.js' => "f", + 'custom-html-widgets.js' => "f", + 'media-widgets.min.js' => "f", + 'media-image-widget.min.js' => "f", + 'text-widgets.js' => "f", + 'media-gallery-widget.js' => "f", + 'media-image-widget.js' => "f", + 'media-gallery-widget.min.js' => "f", + 'media-audio-widget.js' => "f", + ), + 'customize-widgets.js' => "f", + 'language-chooser.min.js' => "f", + 'updates.min.js' => "f", + 'iris.min.js' => "f", + 'color-picker.js' => "f", + 'editor.js' => "f", + 'wp-fullscreen.js' => "f", + 'media.min.js' => "f", + 'wp-fullscreen.min.js' => "f", + 'post.min.js' => "f", + 'nav-menu.js' => "f", + 'svg-painter.min.js' => "f", + 'theme-plugin-editor.min.js' => "f", + 'user-suggest.min.js' => "f", + 'tags-box.js' => "f", + 'media.js' => "f", + 'media-upload.js' => "f", + 'site-icon.min.js' => "f", + 'inline-edit-tax.js' => "f", + 'custom-header.js' => "f", + 'editor-expand.min.js' => "f", + 'widgets.js' => "f", + 'edit-comments.js' => "f", + 'gallery.js' => "f", + 'accordion.js' => "f", + 'tags-suggest.js' => "f", + 'svg-painter.js' => "f", + 'password-toggle.js' => "f", + 'postbox.min.js' => "f", + 'tags.js' => "f", + 'widgets.min.js' => "f", + 'post.js' => "f", + 'xfn.min.js' => "f", + 'nav-menu.min.js' => "f", + 'tags-box.min.js' => "f", + 'comment.min.js' => "f", + 'language-chooser.js' => "f", + 'custom-background.js' => "f", + 'customize-nav-menus.min.js' => "f", + 'farbtastic.js' => "f", + 'plugin-install.min.js' => "f", + 'tags.min.js' => "f", + 'privacy-tools.js' => "f", + 'word-count.js' => "f", + 'inline-edit-post.min.js' => "f", + 'auth-app.min.js' => "f", + 'edit-comments.min.js' => "f", + 'code-editor.min.js' => "f", + 'user-suggest.js' => "f", + 'theme-plugin-editor.js' => "f", + 'site-icon.js' => "f", + 'common.min.js' => "f", + 'user-profile.js' => "f", + 'wp-fullscreen-stub.min.js' => "f", + 'postbox.js' => "f", + 'password-toggle.min.js' => "f", + 'press-this.min.js' => "f", + 'xfn.js' => "f", + 'link.min.js' => "f", + 'code-editor.js' => "f", + 'comment.js' => "f", + 'customize-controls.min.js' => "f", + 'plugin-install.js' => "f", + 'privacy-tools.min.js' => "f", + 'application-passwords.js' => "f", + 'site-health.js' => "f", + 'set-post-thumbnail.js' => "f", + 'dashboard.min.js' => "f", + 'bookmarklet.js' => "f", + 'gallery.min.js' => "f", + 'revisions.js' => "f", + 'theme.min.js' => "f", + 'word-count.min.js' => "f", + 'accordion.min.js' => "f", + 'customize-controls.js' => "f", + 'password-strength-meter.js' => "f", + 'editor-expand.js' => "f", + 'image-edit.min.js' => "f", + ), + 'link.php' => "f", + 'ms-sites.php' => "f", + 'upgrade-functions.php' => "f", + 'plugin-install.php' => "f", + 'widgets-form-blocks.php' => "f", + 'media-new.php' => "f", + 'options-permalink.php' => "f", + 'load-scripts.php' => "f", + 'theme-install.php' => "f", + 'plugin-editor.php' => "f", + 'post.php' => "f", + 'term.php' => "f", + 'my-sites.php' => "f", + 'customize.php' => "f", + 'edit-form-blocks.php' => "f", + 'upload.php' => "f", + 'images' => array( + 'freedom-2.svg' => "f", + 'browser-rtl.png' => "f", + 'about-texture.png' => "f", + 'spinner.gif' => "f", + 'media-button.png' => "f", + 'browser.png' => "f", + 'align-none-2x.png' => "f", + 'contribute-code.svg' => "f", + 'dashboard-background.svg' => "f", + 'menu.png' => "f", + 'align-left-2x.png' => "f", + 'align-right-2x.png' => "f", + 'generic.png' => "f", + 'imgedit-icons.png' => "f", + 'icons32.png' => "f", + 'sort.gif' => "f", + 'media-button-video.gif' => "f", + 'align-center-2x.png' => "f", + 'list.png' => "f", + 'about-color-palette.svg' => "f", + 'media-button-image.gif' => "f", + 'post-formats.png' => "f", + 'menu-2x.png' => "f", + 'arrows-2x.png' => "f", + 'contribute-main.svg' => "f", + 'resize-2x.gif' => "f", + 'about-header-contribute.svg' => "f", + 'wordpress-logo.svg' => "f", + 'marker.png' => "f", + 'media-button-2x.png' => "f", + 'list-2x.png' => "f", + 'no.png' => "f", + 'about-header-background.svg' => "f", + 'se.png' => "f", + 'icons32-2x.png' => "f", + 'icons32-vs.png' => "f", + 'post-formats32-vs.png' => "f", + 'wheel.png' => "f", + 'align-none.png' => "f", + 'freedom-3.svg' => "f", + 'mask.png' => "f", + 'resize.gif' => "f", + 'post-formats-vs.png' => "f", + 'wordpress-logo-white.svg' => "f", + 'menu-vs.png' => "f", + 'wpspin_light-2x.gif' => "f", + 'icons32-vs-2x.png' => "f", + 'stars.png' => "f", + 'sort-2x.gif' => "f", + 'about-badge.svg' => "f", + 'wpspin_light.gif' => "f", + 'about-header-privacy.svg' => "f", + 'spinner-2x.gif' => "f", + 'w-logo-blue.png' => "f", + 'arrows.png' => "f", + 'xit-2x.gif' => "f", + 'privacy.svg' => "f", + 'bubble_bg-2x.gif' => "f", + 'resize-rtl-2x.gif' => "f", + 'align-center.png' => "f", + 'contribute-no-code.svg' => "f", + 'post-formats32.png' => "f", + 'media-button-music.gif' => "f", + 'wordpress-logo.png' => "f", + 'about-color-palette-vert.svg' => "f", + 'stars-2x.png' => "f", + 'about-release-badge.svg' => "f", + 'resize-rtl.gif' => "f", + 'loading.gif' => "f", + 'about-header-brushes.svg' => "f", + 'bubble_bg.gif' => "f", + 'comment-grey-bubble.png' => "f", + 'freedom-4.svg' => "f", + 'align-right.png' => "f", + 'about-header-freedoms.svg' => "f", + 'align-left.png' => "f", + 'media-button-other.gif' => "f", + 'imgedit-icons-2x.png' => "f", + 'privacy.png' => "f", + 'comment-grey-bubble-2x.png' => "f", + 'freedoms.png' => "f", + 'date-button.gif' => "f", + 'freedom-1.svg' => "f", + 'xit.gif' => "f", + 'date-button-2x.gif' => "f", + 'about-header-about.svg' => "f", + 'w-logo-white.png' => "f", + 'about-header-credits.svg' => "f", + 'yes.png' => "f", + 'menu-vs-2x.png' => "f", + ), + 'css' => array( + 'nav-menus.css' => "f", + 'press-this-editor-rtl.css' => "f", + 'about-rtl.css' => "f", + 'widgets.min.css' => "f", + 'code-editor.css' => "f", + 'farbtastic.min.css' => "f", + 'ie.css' => "f", + 'login.min.css' => "f", + 'forms-rtl.min.css' => "f", + 'login.css' => "f", + 'press-this-editor-rtl.min.css' => "f", + 'widgets-rtl.min.css' => "f", + 'customize-nav-menus.min.css' => "f", + 'site-health-rtl.css' => "f", + 'nav-menus-rtl.css' => "f", + 'customize-nav-menus.css' => "f", + 'press-this-editor.css' => "f", + 'customize-widgets-rtl.min.css' => "f", + 'edit.min.css' => "f", + 'list-tables-rtl.min.css' => "f", + 'site-health.css' => "f", + 'site-icon-rtl.css' => "f", + 'press-this.css' => "f", + 'media-rtl.css' => "f", + 'about.css' => "f", + 'themes-rtl.min.css' => "f", + 'site-icon-rtl.min.css' => "f", + 'install.css' => "f", + 'site-health.min.css' => "f", + 'media.min.css' => "f", + 'edit-rtl.min.css' => "f", + 'site-icon.css' => "f", + 'list-tables.css' => "f", + 'farbtastic.css' => "f", + 'admin-menu-rtl.min.css' => "f", + 'nav-menus.min.css' => "f", + 'ie-rtl.min.css' => "f", + 'media.css' => "f", + 'install-rtl.css' => "f", + 'ie-rtl.css' => "f", + 'l10n-rtl.css' => "f", + 'common-rtl.min.css' => "f", + 'revisions.min.css' => "f", + 'color-picker-rtl.css' => "f", + 'list-tables-rtl.css' => "f", + 'revisions.css' => "f", + 'customize-controls-rtl.min.css' => "f", + 'admin-menu.css' => "f", + 'press-this.min.css' => "f", + 'press-this-rtl.css' => "f", + 'site-health-rtl.min.css' => "f", + 'media-rtl.min.css' => "f", + 'login-rtl.min.css' => "f", + 'customize-nav-menus-rtl.css' => "f", + 'about.min.css' => "f", + 'color-picker-rtl.min.css' => "f", + 'admin-menu.min.css' => "f", + 'themes.css' => "f", + 'color-picker.css' => "f", + 'admin-menu-rtl.css' => "f", + 'install-rtl.min.css' => "f", + 'site-icon.min.css' => "f", + 'color-picker.min.css' => "f", + 'wp-admin.min.css' => "f", + 'dashboard-rtl.min.css' => "f", + 'customize-widgets.min.css' => "f", + 'press-this-editor.min.css' => "f", + 'customize-controls-rtl.css' => "f", + 'deprecated-media.css' => "f", + 'forms.css' => "f", + 'widgets.css' => "f", + 'about-rtl.min.css' => "f", + 'nav-menus-rtl.min.css' => "f", + 'common.css' => "f", + 'wp-admin-rtl.min.css' => "f", + 'l10n.min.css' => "f", + 'ie.min.css' => "f", + 'l10n.css' => "f", + 'farbtastic-rtl.min.css' => "f", + 'code-editor-rtl.css' => "f", + 'install.min.css' => "f", + 'customize-controls.min.css' => "f", + 'list-tables.min.css' => "f", + 'code-editor-rtl.min.css' => "f", + 'themes.min.css' => "f", + 'press-this-rtl.min.css' => "f", + 'customize-nav-menus-rtl.min.css' => "f", + 'colors' => array( + '_variables.scss' => "f", + '_admin.scss' => "f", + 'light' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + 'ocean' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + 'ectoplasm' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + 'coffee' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + 'sunrise' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + '_mixins.scss' => "f", + 'blue' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + 'midnight' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + 'modern' => array( + 'colors.css' => "f", + 'colors.min.css' => "f", + 'colors.scss' => "f", + 'colors-rtl.css' => "f", + 'colors-rtl.min.css' => "f", + ), + ), + 'revisions-rtl.min.css' => "f", + 'dashboard.min.css' => "f", + 'deprecated-media.min.css' => "f", + 'revisions-rtl.css' => "f", + 'dashboard-rtl.css' => "f", + 'customize-controls.css' => "f", + 'login-rtl.css' => "f", + 'farbtastic-rtl.css' => "f", + 'l10n-rtl.min.css' => "f", + 'customize-widgets.css' => "f", + 'themes-rtl.css' => "f", + 'customize-widgets-rtl.css' => "f", + 'common.min.css' => "f", + 'forms.min.css' => "f", + 'deprecated-media-rtl.css' => "f", + 'edit-rtl.css' => "f", + 'wp-admin-rtl.css' => "f", + 'wp-admin.css' => "f", + 'common-rtl.css' => "f", + 'widgets-rtl.css' => "f", + 'code-editor.min.css' => "f", + 'forms-rtl.css' => "f", + 'edit.css' => "f", + 'deprecated-media-rtl.min.css' => "f", + 'dashboard.css' => "f", + ), + 'erase-personal-data.php' => "f", + 'media.php' => "f", + 'nav-menus.php' => "f", + 'credits.php' => "f", + 'admin-ajax.php' => "f", + 'install.php' => "f", + 'ms-delete-site.php' => "f", + 'revision.php' => "f", + 'users.php' => "f", + 'plugins.php' => "f", + 'install-helper.php' => "f", + 'widgets.php' => "f", + 'setup-config.php' => "f", + 'menu.php' => "f", + 'link-add.php' => "f", + 'edit-tags.php' => "f", + 'edit-link-form.php' => "f", + 'edit-form-advanced.php' => "f", + 'admin-header.php' => "f", + 'maint' => array('repair.php' => "f"), + 'options-reading.php' => "f", + 'export.php' => "f", + 'ms-admin.php' => "f", + 'options-privacy.php' => "f", + 'edit-tag-form.php' => "f", + 'ms-themes.php' => "f", + 'load-styles.php' => "f", + 'edit.php' => "f", + 'site-health.php' => "f", + 'edit-comments.php' => "f", + 'moderation.php' => "f", + 'index.php' => "f", + 'async-upload.php' => "f", + 'site-health-info.php' => "f", + 'comment.php' => "f", + 'widgets-form.php' => "f", + 'contribute.php' => "f", + 'press-this.php' => "f", + 'options-writing.php' => "f", + 'options-general.php' => "f", + 'admin-functions.php' => "f", + 'network.php' => "f", + 'admin-post.php' => "f", + 'profile.php' => "f", + 'export-personal-data.php' => "f", + 'user-edit.php' => "f", + 'media-upload.php' => "f", + 'ms-users.php' => "f", + 'ms-upgrade-network.php' => "f", + 'options-media.php' => "f", + 'freedoms.php' => "f", + 'authorize-application.php' => "f", + 'theme-editor.php' => "f", + 'options-discussion.php' => "f", + 'edit-form-comment.php' => "f", + 'about.php' => "f", + 'options.php' => "f", + 'link-parse-opml.php' => "f", + 'admin-footer.php' => "f", + 'network' => array( + 'settings.php' => "f", + 'admin.php' => "f", + 'update.php' => "f", + 'site-settings.php' => "f", + 'user-new.php' => "f", + 'privacy.php' => "f", + 'site-info.php' => "f", + 'upgrade.php' => "f", + 'update-core.php' => "f", + 'plugin-install.php' => "f", + 'theme-install.php' => "f", + 'plugin-editor.php' => "f", + 'site-new.php' => "f", + 'credits.php' => "f", + 'site-users.php' => "f", + 'users.php' => "f", + 'plugins.php' => "f", + 'menu.php' => "f", + 'edit.php' => "f", + 'index.php' => "f", + 'contribute.php' => "f", + 'sites.php' => "f", + 'site-themes.php' => "f", + 'profile.php' => "f", + 'user-edit.php' => "f", + 'freedoms.php' => "f", + 'setup.php' => "f", + 'theme-editor.php' => "f", + 'about.php' => "f", + 'themes.php' => "f", + ), + 'custom-header.php' => "f", + 'user' => array( + 'admin.php' => "f", + 'privacy.php' => "f", + 'credits.php' => "f", + 'menu.php' => "f", + 'index.php' => "f", + 'contribute.php' => "f", + 'profile.php' => "f", + 'user-edit.php' => "f", + 'freedoms.php' => "f", + 'about.php' => "f", + ), + 'themes.php' => "f", + 'ms-edit.php' => "f", + 'includes' => array( + 'import.php' => "f", + 'admin-filters.php' => "f", + 'image-edit.php' => "f", + 'class-wp-ms-themes-list-table.php' => "f", + 'class-wp-plugins-list-table.php' => "f", + 'user.php' => "f", + 'admin.php' => "f", + 'theme.php' => "f", + 'class-wp-filesystem-direct.php' => "f", + 'class-wp-privacy-data-export-requests-list-table.php' => "f", + 'update.php' => "f", + 'class-wp-upgrader-skin.php' => "f", + 'class-wp-filesystem-base.php' => "f", + 'class-wp-theme-install-list-table.php' => "f", + 'class-wp-ms-users-list-table.php' => "f", + 'class-wp-ajax-upgrader-skin.php' => "f", + 'file.php' => "f", + 'class-wp-site-health.php' => "f", + 'bookmark.php' => "f", + 'class-wp-list-table.php' => "f", + 'ms-admin-filters.php' => "f", + 'upgrade.php' => "f", + 'class-wp-community-events.php' => "f", + 'class-wp-themes-list-table.php' => "f", + 'class-wp-post-comments-list-table.php' => "f", + 'class-wp-terms-list-table.php' => "f", + 'class-custom-background.php' => "f", + 'ajax-actions.php' => "f", + 'class-custom-image-header.php' => "f", + 'update-core.php' => "f", + 'class-bulk-theme-upgrader-skin.php' => "f", + 'class-pclzip.php' => "f", + 'class-wp-links-list-table.php' => "f", + 'class-ftp.php' => "f", + 'plugin-install.php' => "f", + 'class-wp-application-passwords-list-table.php' => "f", + 'class-walker-nav-menu-edit.php' => "f", + 'class-plugin-installer-skin.php' => "f", + 'screen.php' => "f", + 'class-wp-upgrader.php' => "f", + 'misc.php' => "f", + 'noop.php' => "f", + 'image.php' => "f", + 'theme-install.php' => "f", + 'post.php' => "f", + 'class-wp-list-table-compat.php' => "f", + 'class-wp-posts-list-table.php' => "f", + 'class-language-pack-upgrader-skin.php' => "f", + 'meta-boxes.php' => "f", + 'media.php' => "f", + 'credits.php' => "f", + 'class-wp-filesystem-ftpext.php' => "f", + 'revision.php' => "f", + 'class-wp-upgrader-skins.php' => "f", + 'taxonomy.php' => "f", + 'dashboard.php' => "f", + 'class-wp-privacy-data-removal-requests-list-table.php' => "f", + 'class-wp-debug-data.php' => "f", + 'class-wp-press-this.php' => "f", + 'class-ftp-sockets.php' => "f", + 'widgets.php' => "f", + 'menu.php' => "f", + 'class-wp-privacy-requests-table.php' => "f", + 'list-table.php' => "f", + 'class-walker-category-checklist.php' => "f", + 'class-theme-upgrader-skin.php' => "f", + 'class-file-upload-upgrader.php' => "f", + 'export.php' => "f", + 'class-wp-screen.php' => "f", + 'class-automatic-upgrader-skin.php' => "f", + 'class-wp-ms-sites-list-table.php' => "f", + 'class-theme-upgrader.php' => "f", + 'class-core-upgrader.php' => "f", + 'plugin.php' => "f", + 'class-wp-automatic-updater.php' => "f", + 'comment.php' => "f", + 'class-wp-comments-list-table.php' => "f", + 'schema.php' => "f", + 'class-wp-plugin-install-list-table.php' => "f", + 'nav-menu.php' => "f", + 'network.php' => "f", + 'class-wp-privacy-policy-content.php' => "f", + 'edit-tag-messages.php' => "f", + 'class-wp-filesystem-ssh2.php' => "f", + 'class-walker-nav-menu-checklist.php' => "f", + 'class-wp-internal-pointers.php' => "f", + 'class-wp-users-list-table.php' => "f", + 'class-bulk-plugin-upgrader-skin.php' => "f", + 'class-ftp-pure.php' => "f", + 'ms-deprecated.php' => "f", + 'ms.php' => "f", + 'class-theme-installer-skin.php' => "f", + 'translation-install.php' => "f", + 'continents-cities.php' => "f", + 'class-wp-site-icon.php' => "f", + 'class-wp-importer.php' => "f", + 'class-bulk-upgrader-skin.php' => "f", + 'class-language-pack-upgrader.php' => "f", + 'class-plugin-upgrader-skin.php' => "f", + 'deprecated.php' => "f", + 'class-wp-media-list-table.php' => "f", + 'options.php' => "f", + 'class-plugin-upgrader.php' => "f", + 'class-wp-filesystem-ftpsockets.php' => "f", + 'class-wp-site-health-auto-updates.php' => "f", + 'privacy-tools.php' => "f", + 'template.php' => "f", + ), + 'menu-header.php' => "f", + ), + 'wp-includes' => array( + 'class-wp-customize-section.php' => "f", + 'Requests' => array( + 'Session.php' => "f", + 'SSL.php' => "f", + 'Exception' => array( + 'HTTP' => array( + '417.php' => "f", + '502.php' => "f", + '306.php' => "f", + 'Unknown.php' => "f", + '418.php' => "f", + '408.php' => "f", + '504.php' => "f", + '431.php' => "f", + '406.php' => "f", + '404.php' => "f", + '409.php' => "f", + '411.php' => "f", + '401.php' => "f", + '400.php' => "f", + '405.php' => "f", + '500.php' => "f", + '429.php' => "f", + '402.php' => "f", + '505.php' => "f", + '413.php' => "f", + '305.php' => "f", + '412.php' => "f", + '304.php' => "f", + '428.php' => "f", + '416.php' => "f", + '414.php' => "f", + '407.php' => "f", + '501.php' => "f", + '410.php' => "f", + '415.php' => "f", + '503.php' => "f", + '403.php' => "f", + '511.php' => "f", + ), + 'Transport.php' => "f", + 'HTTP.php' => "f", + 'Transport' => array('cURL.php' => "f"), + ), + 'Hooker.php' => "f", + 'src' => array( + 'Session.php' => "f", + 'Exception' => array( + 'Http.php' => "f", + 'ArgumentCount.php' => "f", + 'Transport.php' => "f", + 'Http' => array( + 'Status503.php' => "f", + 'Status406.php' => "f", + 'Status405.php' => "f", + 'Status404.php' => "f", + 'StatusUnknown.php' => "f", + 'Status501.php' => "f", + 'Status414.php' => "f", + 'Status429.php' => "f", + 'Status431.php' => "f", + 'Status409.php' => "f", + 'Status416.php' => "f", + 'Status403.php' => "f", + 'Status407.php' => "f", + 'Status428.php' => "f", + 'Status413.php' => "f", + 'Status411.php' => "f", + 'Status306.php' => "f", + 'Status415.php' => "f", + 'Status417.php' => "f", + 'Status412.php' => "f", + 'Status418.php' => "f", + 'Status408.php' => "f", + 'Status410.php' => "f", + 'Status401.php' => "f", + 'Status305.php' => "f", + 'Status504.php' => "f", + 'Status502.php' => "f", + 'Status500.php' => "f", + 'Status400.php' => "f", + 'Status505.php' => "f", + 'Status402.php' => "f", + 'Status304.php' => "f", + 'Status511.php' => "f", + ), + 'Transport' => array('Curl.php' => "f"), + 'InvalidArgument.php' => "f", + ), + 'Auth.php' => "f", + 'Cookie' => array('Jar.php' => "f"), + 'Transport.php' => "f", + 'Auth' => array('Basic.php' => "f"), + 'Ipv6.php' => "f", + 'Response' => array('Headers.php' => "f"), + 'Cookie.php' => "f", + 'HookManager.php' => "f", + 'Proxy.php' => "f", + 'Response.php' => "f", + 'Hooks.php' => "f", + 'IdnaEncoder.php' => "f", + 'Iri.php' => "f", + 'Capability.php' => "f", + 'Requests.php' => "f", + 'Ssl.php' => "f", + 'Proxy' => array('Http.php' => "f"), + 'Autoload.php' => "f", + 'Exception.php' => "f", + 'Utility' => array( + 'InputValidator.php' => "f", + 'FilteredIterator.php' => "f", + 'CaseInsensitiveDictionary.php' => "f", + ), + 'Port.php' => "f", + 'Transport' => array( + 'Fsockopen.php' => "f", + 'Curl.php' => "f", + ), + ), + 'IDNAEncoder.php' => "f", + 'Auth.php' => "f", + 'Cookie' => array('Jar.php' => "f"), + 'Transport.php' => "f", + 'Auth' => array('Basic.php' => "f"), + 'Response' => array('Headers.php' => "f"), + 'Cookie.php' => "f", + 'Proxy.php' => "f", + 'IPv6.php' => "f", + 'Response.php' => "f", + 'Hooks.php' => "f", + 'library' => array('Requests.php' => "f"), + 'Proxy' => array('HTTP.php' => "f"), + 'IRI.php' => "f", + 'Exception.php' => "f", + 'Utility' => array( + 'FilteredIterator.php' => "f", + 'CaseInsensitiveDictionary.php' => "f", + ), + 'Transport' => array( + 'fsockopen.php' => "f", + 'cURL.php' => "f", + ), + ), + 'class-wp-oembed-controller.php' => "f", + 'category-template.php' => "f", + 'canonical.php' => "f", + 'class-wp-http-requests-hooks.php' => "f", + 'cache.php' => "f", + 'SimplePie' => array( + 'Cache' => array( + 'Redis.php' => "f", + 'Base.php' => "f", + 'Memcached.php' => "f", + 'Memcache.php' => "f", + 'DB.php' => "f", + 'File.php' => "f", + 'MySQL.php' => "f", + ), + 'autoloader.php' => "f", + 'Content' => array( + 'Type' => array('Sniffer.php' => "f"), + ), + 'Sanitize.php' => "f", + 'Restriction.php' => "f", + 'Parser.php' => "f", + 'Cache.php' => "f", + 'Item.php' => "f", + 'HTTP' => array('Parser.php' => "f"), + 'src' => array( + 'RegistryAware.php' => "f", + 'Cache' => array( + 'BaseDataCache.php' => "f", + 'Redis.php' => "f", + 'DataCache.php' => "f", + 'CallableNameFilter.php' => "f", + 'Base.php' => "f", + 'Memcached.php' => "f", + 'Memcache.php' => "f", + 'NameFilter.php' => "f", + 'DB.php' => "f", + 'File.php' => "f", + 'MySQL.php' => "f", + 'Psr16.php' => "f", + ), + 'Gzdecode.php' => "f", + 'Content' => array( + 'Type' => array('Sniffer.php' => "f"), + ), + 'Sanitize.php' => "f", + 'Restriction.php' => "f", + 'Parser.php' => "f", + 'Cache.php' => "f", + 'Item.php' => "f", + 'HTTP' => array('Parser.php' => "f"), + 'Misc.php' => "f", + 'Decode' => array( + 'HTML' => array('Entities.php' => "f"), + ), + 'Enclosure.php' => "f", + 'XML' => array( + 'Declaration' => array('Parser.php' => "f"), + ), + 'Caption.php' => "f", + 'Category.php' => "f", + 'Author.php' => "f", + 'File.php' => "f", + 'Net' => array('IPv6.php' => "f"), + 'Parse' => array('Date.php' => "f"), + 'IRI.php' => "f", + 'SimplePie.php' => "f", + 'Exception.php' => "f", + 'Source.php' => "f", + 'Rating.php' => "f", + 'Registry.php' => "f", + 'Credit.php' => "f", + 'Locator.php' => "f", + 'Copyright.php' => "f", + 'Core.php' => "f", + ), + 'Misc.php' => "f", + 'Decode' => array( + 'HTML' => array('Entities.php' => "f"), + ), + 'gzdecode.php' => "f", + 'Enclosure.php' => "f", + 'XML' => array( + 'Declaration' => array('Parser.php' => "f"), + ), + 'Caption.php' => "f", + 'Category.php' => "f", + 'Author.php' => "f", + 'File.php' => "f", + 'Net' => array('IPv6.php' => "f"), + 'Parse' => array('Date.php' => "f"), + 'library' => array( + 'SimplePie' => array( + 'Cache' => array( + 'Redis.php' => "f", + 'Base.php' => "f", + 'Memcached.php' => "f", + 'Memcache.php' => "f", + 'DB.php' => "f", + 'File.php' => "f", + 'MySQL.php' => "f", + ), + 'Content' => array( + 'Type' => array('Sniffer.php' => "f"), + ), + 'Sanitize.php' => "f", + 'Restriction.php' => "f", + 'Parser.php' => "f", + 'Cache.php' => "f", + 'Item.php' => "f", + 'HTTP' => array('Parser.php' => "f"), + 'Misc.php' => "f", + 'Decode' => array( + 'HTML' => array('Entities.php' => "f"), + ), + 'gzdecode.php' => "f", + 'Enclosure.php' => "f", + 'XML' => array( + 'Declaration' => array('Parser.php' => "f"), + ), + 'Caption.php' => "f", + 'Category.php' => "f", + 'Author.php' => "f", + 'File.php' => "f", + 'Net' => array('IPv6.php' => "f"), + 'Parse' => array('Date.php' => "f"), + 'IRI.php' => "f", + 'Exception.php' => "f", + 'Source.php' => "f", + 'Rating.php' => "f", + 'Registry.php' => "f", + 'Credit.php' => "f", + 'Locator.php' => "f", + 'Copyright.php' => "f", + 'Core.php' => "f", + ), + 'SimplePie.php' => "f", + ), + 'IRI.php' => "f", + 'Exception.php' => "f", + 'Source.php' => "f", + 'Rating.php' => "f", + 'Registry.php' => "f", + 'Credit.php' => "f", + 'Locator.php' => "f", + 'Copyright.php' => "f", + 'Core.php' => "f", + ), + 'embed-template.php' => "f", + 'class-wp-hook.php' => "f", + 'feed.php' => "f", + 'class-wp-walker.php' => "f", + 'registration-functions.php' => "f", + 'user.php' => "f", + 'class-snoopy.php' => "f", + 'class-simplepie.php' => "f", + 'block-i18n.json' => "f", + 'ID3' => array( + 'license.commercial.txt' => "f", + 'module.audio.ogg.php' => "f", + 'module.tag.id3v1.php' => "f", + 'license.txt' => "f", + 'module.tag.apetag.php' => "f", + 'getid3.php' => "f", + 'readme.txt' => "f", + 'module.audio.flac.php' => "f", + 'module.audio.ac3.php' => "f", + 'getid3.lib.php' => "f", + 'module.audio-video.asf.php' => "f", + 'module.tag.id3v2.php' => "f", + 'module.tag.lyrics3.php' => "f", + 'module.audio.dts.php' => "f", + 'module.audio-video.quicktime.php' => "f", + 'module.audio-video.riff.php' => "f", + 'module.audio-video.flv.php' => "f", + 'module.audio-video.matroska.php' => "f", + 'module.audio.mp3.php' => "f", + ), + 'theme.php' => "f", + 'Text' => array( + 'Diff.php' => "f", + 'Diff' => array( + 'Engine' => array( + 'shell.php' => "f", + 'string.php' => "f", + 'xdiff.php' => "f", + 'native.php' => "f", + ), + 'Renderer' => array('inline.php' => "f"), + 'Renderer.php' => "f", + ), + 'Exception.php' => "f", + ), + 'update.php' => "f", + 'ms-default-constants.php' => "f", + 'ms-load.php' => "f", + 'class-wp-http-requests-response.php' => "f", + 'block-template-utils.php' => "f", + 'class-wp-term-query.php' => "f", + 'class-wp-list-util.php' => "f", + 'blocks.php' => "f", + 'class-wp-block-supports.php' => "f", + 'class-wp-block.php' => "f", + 'class-wp-user-meta-session-tokens.php' => "f", + 'block-template.php' => "f", + 'script-loader.php' => "f", + 'block-bindings' => array( + 'pattern-overrides.php' => "f", + 'post-meta.php' => "f", + ), + 'PHPMailer' => array( + 'SMTP.php' => "f", + 'Exception.php' => "f", + 'PHPMailer.php' => "f", + ), + 'class-wp-customize-manager.php' => "f", + 'vars.php' => "f", + 'bookmark.php' => "f", + 'class-wp-theme-json-schema.php' => "f", + 'class-wp-role.php' => "f", + 'default-constants.php' => "f", + 'html-api' => array( + 'html5-named-character-references.php' => "f", + 'class-wp-html-attribute-token.php' => "f", + 'class-wp-html-stack-event.php' => "f", + 'class-wp-html-active-formatting-elements.php' => "f", + 'class-wp-html-text-replacement.php' => "f", + 'class-wp-html-processor-state.php' => "f", + 'class-wp-html-doctype-info.php' => "f", + 'class-wp-html-token.php' => "f", + 'class-wp-html-processor.php' => "f", + 'class-wp-html-span.php' => "f", + 'class-wp-html-decoder.php' => "f", + 'class-wp-html-unsupported-exception.php' => "f", + 'class-wp-html-tag-processor.php' => "f", + 'class-wp-html-open-elements.php' => "f", + ), + 'sodium_compat' => array( + 'autoload.php' => "f", + 'src' => array( + 'PHP52' => array('SplFixedArray.php' => "f"), + 'Crypto.php' => "f", + 'Compat.php' => "f", + 'Core32' => array( + 'Poly1305.php' => "f", + 'Salsa20.php' => "f", + 'XChaCha20.php' => "f", + 'BLAKE2b.php' => "f", + 'X25519.php' => "f", + 'SecretStream' => array('State.php' => "f"), + 'Curve25519' => array( + 'Fe.php' => "f", + 'H.php' => "f", + 'README.md' => "f", + 'Ge' => array( + 'P3.php' => "f", + 'Cached.php' => "f", + 'P1p1.php' => "f", + 'Precomp.php' => "f", + 'P2.php' => "f", + ), + ), + 'Int64.php' => "f", + 'SipHash.php' => "f", + 'Curve25519.php' => "f", + 'XSalsa20.php' => "f", + 'HSalsa20.php' => "f", + 'ChaCha20.php' => "f", + 'Ed25519.php' => "f", + 'HChaCha20.php' => "f", + 'Int32.php' => "f", + 'Poly1305' => array('State.php' => "f"), + 'Util.php' => "f", + 'ChaCha20' => array( + 'IetfCtx.php' => "f", + 'Ctx.php' => "f", + ), + ), + 'SodiumException.php' => "f", + 'Crypto32.php' => "f", + 'Core' => array( + 'Poly1305.php' => "f", + 'Base64' => array( + 'Common.php' => "f", + 'UrlSafe.php' => "f", + 'Original.php' => "f", + ), + 'Salsa20.php' => "f", + 'Ristretto255.php' => "f", + 'XChaCha20.php' => "f", + 'BLAKE2b.php' => "f", + 'X25519.php' => "f", + 'AEGIS128L.php' => "f", + 'SecretStream' => array('State.php' => "f"), + 'AES' => array( + 'KeySchedule.php' => "f", + 'Block.php' => "f", + 'Expanded.php' => "f", + ), + 'Curve25519' => array( + 'Fe.php' => "f", + 'H.php' => "f", + 'README.md' => "f", + 'Ge' => array( + 'P3.php' => "f", + 'Cached.php' => "f", + 'P1p1.php' => "f", + 'Precomp.php' => "f", + 'P2.php' => "f", + ), + ), + 'SipHash.php' => "f", + 'Curve25519.php' => "f", + 'AES.php' => "f", + 'XSalsa20.php' => "f", + 'HSalsa20.php' => "f", + 'ChaCha20.php' => "f", + 'Ed25519.php' => "f", + 'HChaCha20.php' => "f", + 'AEGIS' => array( + 'State128L.php' => "f", + 'State256.php' => "f", + ), + 'AEGIS256.php' => "f", + 'Poly1305' => array('State.php' => "f"), + 'Util.php' => "f", + 'ChaCha20' => array( + 'IetfCtx.php' => "f", + 'Ctx.php' => "f", + ), + ), + 'File.php' => "f", + ), + 'namespaced' => array( + 'Crypto.php' => "f", + 'Compat.php' => "f", + 'Core' => array( + 'Poly1305.php' => "f", + 'Salsa20.php' => "f", + 'XChaCha20.php' => "f", + 'BLAKE2b.php' => "f", + 'X25519.php' => "f", + 'Curve25519' => array( + 'Fe.php' => "f", + 'H.php' => "f", + 'Ge' => array( + 'P3.php' => "f", + 'Cached.php' => "f", + 'P1p1.php' => "f", + 'Precomp.php' => "f", + 'P2.php' => "f", + ), + ), + 'SipHash.php' => "f", + 'Curve25519.php' => "f", + 'HSalsa20.php' => "f", + 'ChaCha20.php' => "f", + 'Ed25519.php' => "f", + 'HChaCha20.php' => "f", + 'Poly1305' => array('State.php' => "f"), + 'Xsalsa20.php' => "f", + 'Util.php' => "f", + 'ChaCha20' => array( + 'IetfCtx.php' => "f", + 'Ctx.php' => "f", + ), + ), + 'File.php' => "f", + ), + 'composer.json' => "f", + 'autoload-php7.php' => "f", + 'LICENSE' => "f", + 'lib' => array( + 'php84compat.php' => "f", + 'sodium_compat.php' => "f", + 'php72compat_const.php' => "f", + 'constants.php' => "f", + 'namespaced.php' => "f", + 'ristretto255.php' => "f", + 'stream-xchacha20.php' => "f", + 'php72compat.php' => "f", + 'php84compat_const.php' => "f", + ), + ), + 'fonts' => array( + 'class-wp-font-utils.php' => "f", + 'dashicons.woff2' => "f", + 'dashicons.woff' => "f", + 'class-wp-font-collection.php' => "f", + 'dashicons.svg' => "f", + 'class-wp-font-face-resolver.php' => "f", + 'class-wp-font-library.php' => "f", + 'dashicons.eot' => "f", + 'class-wp-font-face.php' => "f", + 'dashicons.ttf' => "f", + ), + 'embed.php' => "f", + 'load.php' => "f", + 'class-wp-comment-query.php' => "f", + 'cache-compat.php' => "f", + 'ms-site.php' => "f", + 'class-oembed.php' => "f", + 'class-wp-block-list.php' => "f", + 'js' => array( + 'customize-preview-nav-menus.min.js' => "f", + 'jquery' => array( + 'jquery.table-hotkeys.min.js' => "f", + 'jquery.ui.touch-punch.js' => "f", + 'jquery.js' => "f", + 'jquery.schedule.js' => "f", + 'jquery-migrate.js' => "f", + 'jquery.masonry.min.js' => "f", + 'suggest.js' => "f", + 'suggest.min.js' => "f", + 'ui' => array( + 'jquery.ui.effect-slide.min.js' => "f", + 'tooltip.min.js' => "f", + 'effect-bounce.min.js' => "f", + 'jquery.ui.effect-transfer.min.js' => "f", + 'effect-slide.min.js' => "f", + 'jquery.ui.slider.min.js' => "f", + 'resizable.min.js' => "f", + 'selectmenu.min.js' => "f", + 'effect-fold.js' => "f", + 'jquery.ui.datepicker.min.js' => "f", + 'menu.min.js' => "f", + 'jquery.ui.effect.min.js' => "f", + 'checkboxradio.min.js' => "f", + 'effect-explode.js' => "f", + 'jquery.ui.effect-shake.min.js' => "f", + 'dialog.min.js' => "f", + 'effect.js' => "f", + 'effect-explode.min.js' => "f", + 'effect-shake.min.js' => "f", + 'sortable.min.js' => "f", + 'draggable.min.js' => "f", + 'tabs.js' => "f", + 'jquery.ui.accordion.min.js' => "f", + 'mouse.js' => "f", + 'effect-fade.js' => "f", + 'effect-blind.js' => "f", + 'selectmenu.js' => "f", + 'datepicker.min.js' => "f", + 'jquery.ui.effect-bounce.min.js' => "f", + 'button.min.js' => "f", + 'slider.js' => "f", + 'jquery.ui.position.min.js' => "f", + 'effect-transfer.js' => "f", + 'jquery.ui.autocomplete.min.js' => "f", + 'jquery.ui.effect-clip.min.js' => "f", + 'jquery.ui.button.min.js' => "f", + 'resizable.js' => "f", + 'effect-puff.min.js' => "f", + 'effect-puff.js' => "f", + 'effect-scale.js' => "f", + 'effect-size.min.js' => "f", + 'progressbar.js' => "f", + 'jquery.ui.spinner.min.js' => "f", + 'dialog.js' => "f", + 'effect-drop.js' => "f", + 'effect-clip.js' => "f", + 'jquery.ui.effect-blind.min.js' => "f", + 'controlgroup.js' => "f", + 'tooltip.js' => "f", + 'jquery.ui.core.min.js' => "f", + 'jquery.ui.progressbar.min.js' => "f", + 'progressbar.min.js' => "f", + 'jquery.ui.draggable.min.js' => "f", + 'effect.min.js' => "f", + 'effect-highlight.js' => "f", + 'droppable.js' => "f", + 'jquery.ui.tabs.min.js' => "f", + 'effect-fade.min.js' => "f", + 'effect-pulsate.js' => "f", + 'core.js' => "f", + 'effect-highlight.min.js' => "f", + 'jquery.ui.widget.min.js' => "f", + 'effect-slide.js' => "f", + 'effect-transfer.min.js' => "f", + 'effect-fold.min.js' => "f", + 'jquery.ui.effect-fade.min.js' => "f", + 'mouse.min.js' => "f", + 'spinner.js' => "f", + 'sortable.js' => "f", + 'spinner.min.js' => "f", + 'autocomplete.min.js' => "f", + 'jquery.ui.effect-pulsate.min.js' => "f", + 'tabs.min.js' => "f", + 'effect-pulsate.min.js' => "f", + 'selectable.js' => "f", + 'effect-shake.js' => "f", + 'jquery.ui.resizable.min.js' => "f", + 'accordion.js' => "f", + 'effect-size.js' => "f", + 'menu.js' => "f", + 'jquery.ui.droppable.min.js' => "f", + 'jquery.ui.mouse.min.js' => "f", + 'core.min.js' => "f", + 'effect-blind.min.js' => "f", + 'jquery.ui.effect-fold.min.js' => "f", + 'jquery.ui.effect-drop.min.js' => "f", + 'effect-drop.min.js' => "f", + 'droppable.min.js' => "f", + 'jquery.ui.effect-highlight.min.js' => "f", + 'jquery.ui.effect-explode.min.js' => "f", + 'effect-scale.min.js' => "f", + 'effect-clip.min.js' => "f", + 'slider.min.js' => "f", + 'autocomplete.js' => "f", + 'jquery.ui.dialog.min.js' => "f", + 'widget.min.js' => "f", + 'controlgroup.min.js' => "f", + 'jquery.ui.tooltip.min.js' => "f", + 'position.min.js' => "f", + 'button.js' => "f", + 'checkboxradio.js' => "f", + 'datepicker.js' => "f", + 'jquery.ui.menu.min.js' => "f", + 'jquery.ui.sortable.min.js' => "f", + 'selectable.min.js' => "f", + 'jquery.ui.selectable.min.js' => "f", + 'draggable.js' => "f", + 'accordion.min.js' => "f", + 'jquery.ui.effect-scale.min.js' => "f", + 'effect-bounce.js' => "f", + ), + 'jquery.min.js' => "f", + 'jquery.hotkeys.min.js' => "f", + 'jquery.form.min.js' => "f", + 'jquery.serialize-object.js' => "f", + 'jquery.query.js' => "f", + 'jquery.color.min.js' => "f", + 'jquery.table-hotkeys.js' => "f", + 'jquery.hotkeys.js' => "f", + 'jquery.form.js' => "f", + 'jquery-migrate.min.js' => "f", + ), + 'admin-bar.js' => "f", + 'backbone.js' => "f", + 'media-views.min.js' => "f", + 'customize-preview.min.js' => "f", + 'customize-models.js' => "f", + 'wp-emoji-release.min.js' => "f", + 'wp-emoji-loader.min.js' => "f", + 'zxcvbn.min.js' => "f", + 'customize-base.js' => "f", + 'customize-models.min.js' => "f", + 'wp-embed-template.js' => "f", + 'twemoji.js' => "f", + 'clipboard.min.js' => "f", + 'zxcvbn-async.min.js' => "f", + 'shortcode.js' => "f", + 'customize-preview-nav-menus.js' => "f", + 'customize-selective-refresh.min.js' => "f", + 'customize-views.js' => "f", + 'wpdialog.min.js' => "f", + 'mce-view.js' => "f", + 'wp-lists.min.js' => "f", + 'tinymce' => array( + 'utils' => array( + 'validate.js' => "f", + 'mctabs.js' => "f", + 'editable_selects.js' => "f", + 'form_utils.js' => "f", + ), + 'wp-mce-help.php' => "f", + 'wp-tinymce.js' => "f", + 'license.txt' => "f", + 'langs' => array('wp-langs-en.js' => "f"), + 'tinymce.min.js' => "f", + 'plugins' => array( + 'wpembed' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wplink' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wpview' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wpfullscreen' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'tabfocus' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wpeditimage' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'link' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wptextpattern' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wordpress' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'media' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + 'moxieplayer.swf' => "f", + ), + 'wpdialogs' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wpautoresize' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wpgallery' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'lists' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'wpemoji' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'charmap' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'colorpicker' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'fullscreen' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'directionality' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'paste' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'hr' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'compat3x' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + 'css' => array('dialog.css' => "f"), + ), + 'image' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + 'textcolor' => array( + 'plugin.js' => "f", + 'plugin.min.js' => "f", + ), + ), + 'wp-tinymce.js.gz' => "f", + 'tiny_mce_popup.js' => "f", + 'wp-tinymce.php' => "f", + 'skins' => array( + 'lightgray' => array( + 'fonts' => array( + 'tinymce.woff' => "f", + 'tinymce.json' => "f", + 'tinymce-small.eot' => "f", + 'tinymce.ttf' => "f", + 'tinymce-small.svg' => "f", + 'tinymce-small.json' => "f", + 'tinymce-small.woff' => "f", + 'tinymce.svg' => "f", + 'readme.md' => "f", + 'tinymce.eot' => "f", + 'tinymce-small.ttf' => "f", + ), + 'skin.ie7.min.css' => "f", + 'skin.min.css' => "f", + 'content.inline.min.css' => "f", + 'content.min.css' => "f", + 'img' => array( + 'trans.gif' => "f", + 'loader.gif' => "f", + 'object.gif' => "f", + 'anchor.gif' => "f", + ), + ), + 'wordpress' => array( + 'wp-content.css' => "f", + 'images' => array( + 'dashicon-no.png' => "f", + 'pagebreak.png' => "f", + 'script.svg' => "f", + 'playlist-video.png' => "f", + 'pagebreak-2x.png' => "f", + 'gallery-2x.png' => "f", + 'dashicon-edit.png' => "f", + 'video.png' => "f", + 'more.png' => "f", + 'embedded.png' => "f", + 'more-2x.png' => "f", + 'dashicon-no-alt.png' => "f", + 'gallery.png' => "f", + 'audio.png' => "f", + 'playlist-audio.png' => "f", + 'style.svg' => "f", + ), + ), + ), + 'themes' => array( + 'inlite' => array( + 'theme.js' => "f", + 'theme.min.js' => "f", + ), + 'modern' => array( + 'theme.js' => "f", + 'theme.min.js' => "f", + ), + ), + ), + 'wp-emoji.js' => "f", + 'wpdialog.js' => "f", + 'underscore.min.js' => "f", + 'media-grid.js' => "f", + 'json2.js' => "f", + 'wp-sanitize.js' => "f", + 'wp-list-revisions.min.js' => "f", + 'twemoji.min.js' => "f", + 'codemirror' => array( + 'esprima.js' => "f", + 'htmlhint-kses.js' => "f", + 'codemirror.min.css' => "f", + 'csslint.js' => "f", + 'htmlhint.js' => "f", + 'fakejshint.js' => "f", + 'codemirror.min.js' => "f", + 'jshint.js' => "f", + 'jsonlint.js' => "f", + ), + 'customize-preview.js' => "f", + 'wplink.js' => "f", + 'heartbeat.js' => "f", + 'swfupload' => array( + 'swfupload.swf' => "f", + 'handlers.js' => "f", + 'license.txt' => "f", + 'plugins' => array( + 'swfupload.queue.js' => "f", + 'swfupload.speed.js' => "f", + 'swfupload.swfobject.js' => "f", + 'swfupload.cookies.js' => "f", + ), + 'handlers.min.js' => "f", + 'swfupload.js' => "f", + ), + 'wp-auth-check.min.js' => "f", + 'colorpicker.js' => "f", + 'comment-reply.min.js' => "f", + 'wp-backbone.js' => "f", + 'plupload' => array( + 'handlers.js' => "f", + 'plupload.full.min.js' => "f", + 'license.txt' => "f", + 'wp-plupload.js' => "f", + 'plupload.min.js' => "f", + 'plupload.js' => "f", + 'moxie.js' => "f", + 'moxie.min.js' => "f", + 'handlers.min.js' => "f", + 'wp-plupload.min.js' => "f", + 'plupload.silverlight.xap' => "f", + 'plupload.flash.swf' => "f", + ), + 'wp-a11y.js' => "f", + 'json2.min.js' => "f", + 'api-request.js' => "f", + 'customize-loader.js' => "f", + 'wp-backbone.min.js' => "f", + 'wp-custom-header.min.js' => "f", + 'hoverIntent.js' => "f", + 'utils.js' => "f", + 'mce-view.min.js' => "f", + 'tw-sack.js' => "f", + 'wp-custom-header.js' => "f", + 'imgareaselect' => array( + 'border-anim-v.gif' => "f", + 'border-anim-h.gif' => "f", + 'jquery.imgareaselect.min.js' => "f", + 'jquery.imgareaselect.js' => "f", + 'imgareaselect.css' => "f", + ), + 'wp-embed-template.min.js' => "f", + 'heartbeat.min.js' => "f", + 'imagesloaded.min.js' => "f", + 'customize-views.min.js' => "f", + 'wp-a11y.min.js' => "f", + 'wp-sanitize.min.js' => "f", + 'crop' => array( + 'marqueeHoriz.gif' => "f", + 'marqueeVert.gif' => "f", + 'cropper.css' => "f", + 'cropper.js' => "f", + ), + 'customize-selective-refresh.js' => "f", + 'media-models.js' => "f", + 'wp-ajax-response.js' => "f", + 'wp-emoji.min.js' => "f", + 'wp-list-revisions.js' => "f", + 'media-audiovideo.min.js' => "f", + 'autosave.js' => "f", + 'wp-pointer.min.js' => "f", + 'clipboard.js' => "f", + 'utils.min.js' => "f", + 'underscore.js' => "f", + 'customize-loader.min.js' => "f", + 'wp-ajax-response.min.js' => "f", + 'backbone.min.js' => "f", + 'shortcode.min.js' => "f", + 'customize-base.min.js' => "f", + 'autosave.min.js' => "f", + 'wp-auth-check.js' => "f", + 'zxcvbn-async.js' => "f", + 'wp-pointer.js' => "f", + 'wp-util.js' => "f", + 'tw-sack.min.js' => "f", + 'media-models.min.js' => "f", + 'thickbox' => array( + 'loadingAnimation.gif' => "f", + 'macFFBgHack.png' => "f", + 'thickbox.css' => "f", + 'thickbox.js' => "f", + ), + 'media-grid.min.js' => "f", + 'wplink.min.js' => "f", + 'wp-util.min.js' => "f", + 'mediaelement' => array( + 'skipback.png' => "f", + 'mediaelement.min.js' => "f", + 'wp-mediaelement.min.css' => "f", + 'controls.png' => "f", + 'wp-mediaelement.min.js' => "f", + 'wp-playlist.js' => "f", + 'mejs-controls.png' => "f", + 'bigplay.svg' => "f", + 'mediaelement-and-player.js' => "f", + 'froogaloop.min.js' => "f", + 'mediaelementplayer.min.css' => "f", + 'jumpforward.png' => "f", + 'mediaelement-and-player.min.js' => "f", + 'background.png' => "f", + 'mediaelement-migrate.js' => "f", + 'mediaelementplayer-legacy.min.css' => "f", + 'mediaelement-migrate.min.js' => "f", + 'renderers' => array( + 'vimeo.js' => "f", + 'vimeo.min.js' => "f", + ), + 'controls.svg' => "f", + 'wp-mediaelement.css' => "f", + 'loading.gif' => "f", + 'mediaelement.js' => "f", + 'wp-mediaelement.js' => "f", + 'mejs-controls.svg' => "f", + 'mediaelementplayer-legacy.css' => "f", + 'bigplay.png' => "f", + 'mediaelementplayer.css' => "f", + 'wp-playlist.min.js' => "f", + ), + 'customize-preview-widgets.js' => "f", + 'quicktags.js' => "f", + 'hoverintent-js.min.js' => "f", + 'wp-emoji-loader.js' => "f", + 'dist' => array( + 'i18n.js' => "f", + 'list-reusable-blocks.min.js' => "f", + 'private-apis.min.js' => "f", + 'html-entities.min.js' => "f", + 'deprecated.js' => "f", + 'interactivity-router.asset.php' => "f", + 'edit-post.min.js' => "f", + 'core-data.min.js' => "f", + 'patterns.js' => "f", + 'editor.min.js' => "f", + 'autop.min.js' => "f", + 'escape-html.min.js' => "f", + 'private-apis.js' => "f", + 'annotations.min.js' => "f", + 'list-reusable-blocks.js' => "f", + 'shortcode.js' => "f", + 'keycodes.js' => "f", + 'reusable-blocks.min.js' => "f", + 'element.min.js' => "f", + 'format-library.js' => "f", + 'style-engine.min.js' => "f", + 'preferences.js' => "f", + 'nux.min.js' => "f", + 'block-editor.js' => "f", + 'data-controls.js' => "f", + 'customize-widgets.min.js' => "f", + 'warning.js' => "f", + 'annotations.js' => "f", + 'components.js' => "f", + 'compose.min.js' => "f", + 'priority-queue.min.js' => "f", + 'rich-text.min.js' => "f", + 'components.min.js' => "f", + 'block-directory.js' => "f", + 'customize-widgets.js' => "f", + 'undo-manager.js' => "f", + 'blob.min.js' => "f", + 'compose.js' => "f", + 'preferences.min.js' => "f", + 'editor.js' => "f", + 'core-commands.js' => "f", + 'a11y.min.js' => "f", + 'style-engine.js' => "f", + 'commands.js' => "f", + 'fields.min.js' => "f", + 'escape-html.js' => "f", + 'warning.min.js' => "f", + 'core-data.js' => "f", + 'redux-routine.min.js' => "f", + 'format-library.min.js' => "f", + 'plugins.js' => "f", + 'blob.js' => "f", + 'edit-widgets.min.js' => "f", + 'server-side-render.min.js' => "f", + 'primitives.js' => "f", + 'commands.min.js' => "f", + 'notices.min.js' => "f", + 'autop.js' => "f", + 'dom-ready.js' => "f", + 'url.js' => "f", + 'interactivity-router.min.asset.php' => "f", + 'date.js' => "f", + 'viewport.js' => "f", + 'html-entities.js' => "f", + 'undo-manager.min.js' => "f", + 'a11y.js' => "f", + 'dom.js' => "f", + 'keycodes.min.js' => "f", + 'redux-routine.js' => "f", + 'wordcount.js' => "f", + 'core-commands.min.js' => "f", + 'hooks.min.js' => "f", + 'api-fetch.js' => "f", + 'date.min.js' => "f", + 'widgets.js' => "f", + 'deprecated.min.js' => "f", + 'media-utils.min.js' => "f", + 'nux.js' => "f", + 'block-library.js' => "f", + 'server-side-render.js' => "f", + 'router.min.js' => "f", + 'widgets.min.js' => "f", + 'dom.min.js' => "f", + 'priority-queue.js' => "f", + 'media-utils.js' => "f", + 'edit-widgets.js' => "f", + 'shortcode.min.js' => "f", + 'script-modules' => array( + 'a11y' => array( + 'index.js' => "f", + 'index.min.js' => "f", + ), + 'interactivity-router' => array( + 'index.js' => "f", + 'index.min.js' => "f", + ), + 'block-library' => array( + 'form' => array( + 'view.min.js' => "f", + 'view.js' => "f", + ), + 'search' => array( + 'view.min.js' => "f", + 'view.js' => "f", + ), + 'navigation' => array( + 'view.min.js' => "f", + 'view.js' => "f", + ), + 'query' => array( + 'view.min.js' => "f", + 'view.js' => "f", + ), + 'file' => array( + 'view.min.js' => "f", + 'view.js' => "f", + ), + 'image' => array( + 'view.min.js' => "f", + 'view.js' => "f", + ), + ), + 'interactivity' => array( + 'debug.js' => "f", + 'index.js' => "f", + 'index.min.js' => "f", + 'debug.min.js' => "f", + ), + ), + 'plugins.min.js' => "f", + 'preferences-persistence.min.js' => "f", + 'primitives.min.js' => "f", + 'reusable-blocks.js' => "f", + 'block-serialization-default-parser.js' => "f", + 'keyboard-shortcuts.js' => "f", + 'interactivity.js' => "f", + 'data-controls.min.js' => "f", + 'data.js' => "f", + 'edit-post.js' => "f", + 'rich-text.js' => "f", + 'dom-ready.min.js' => "f", + 'i18n.min.js' => "f", + 'data.min.js' => "f", + 'is-shallow-equal.min.js' => "f", + 'element.js' => "f", + 'router.js' => "f", + 'edit-site.js' => "f", + 'token-list.min.js' => "f", + 'block-editor.min.js' => "f", + 'vendor' => array( + 'lodash.js' => "f", + 'wp-polyfill-fetch.js' => "f", + 'wp-polyfill-node-contains.js' => "f", + 'wp-polyfill-element-closest.min.js' => "f", + 'wp-polyfill.min.js' => "f", + 'wp-polyfill-object-fit.min.js' => "f", + 'wp-polyfill-importmap.min.js' => "f", + 'wp-polyfill-formdata.js' => "f", + 'wp-polyfill-formdata.min.js' => "f", + 'wp-polyfill-node-contains.min.js' => "f", + 'wp-polyfill.js' => "f", + 'lodash.min.js' => "f", + 'moment.js' => "f", + 'wp-polyfill-importmap.js' => "f", + 'react-dom.min.js.LICENSE.txt' => "f", + 'wp-polyfill-object-fit.js' => "f", + 'react.js' => "f", + 'wp-polyfill-inert.min.js' => "f", + 'wp-polyfill-fetch.min.js' => "f", + 'regenerator-runtime.min.js' => "f", + 'regenerator-runtime.js' => "f", + 'wp-polyfill-element-closest.js' => "f", + 'wp-polyfill-inert.js' => "f", + 'moment.min.js' => "f", + 'react-jsx-runtime.min.js' => "f", + 'react.min.js' => "f", + 'wp-polyfill-url.min.js' => "f", + 'react-jsx-runtime.js' => "f", + 'react.min.js.LICENSE.txt' => "f", + 'wp-polyfill-dom-rect.min.js' => "f", + 'react-jsx-runtime.min.js.LICENSE.txt' => "f", + 'react-dom.js' => "f", + 'wp-polyfill-url.js' => "f", + 'react-dom.min.js' => "f", + 'wp-polyfill-dom-rect.js' => "f", + ), + 'is-shallow-equal.js' => "f", + 'block-library.min.js' => "f", + 'blocks.js' => "f", + 'interactivity-router.js' => "f", + 'interactivity-router.min.js' => "f", + 'interactivity.min.js' => "f", + 'development' => array( + 'react-refresh-runtime.min.js' => "f", + 'react-refresh-entry.js' => "f", + 'react-refresh-runtime.js' => "f", + 'react-refresh-entry.min.js' => "f", + ), + 'edit-site.min.js' => "f", + 'hooks.js' => "f", + 'wordcount.min.js' => "f", + 'token-list.js' => "f", + 'block-serialization-default-parser.min.js' => "f", + 'keyboard-shortcuts.min.js' => "f", + 'notices.js' => "f", + 'url.min.js' => "f", + 'preferences-persistence.js' => "f", + 'viewport.min.js' => "f", + 'api-fetch.min.js' => "f", + 'blocks.min.js' => "f", + 'block-directory.min.js' => "f", + 'fields.js' => "f", + 'patterns.min.js' => "f", + ), + 'swfobject.js' => "f", + 'jcrop' => array( + 'Jcrop.gif' => "f", + 'jquery.Jcrop.min.js' => "f", + 'jquery.Jcrop.min.css' => "f", + ), + 'media-views.js' => "f", + 'wp-embed.min.js' => "f", + 'customize-preview-widgets.min.js' => "f", + 'wp-embed.js' => "f", + 'wp-api.min.js' => "f", + 'hoverIntent.min.js' => "f", + 'colorpicker.min.js' => "f", + 'api-request.min.js' => "f", + 'wp-api.js' => "f", + 'masonry.min.js' => "f", + 'quicktags.min.js' => "f", + 'wp-lists.js' => "f", + 'media-editor.min.js' => "f", + 'media-audiovideo.js' => "f", + 'media-editor.js' => "f", + 'admin-bar.min.js' => "f", + 'comment-reply.js' => "f", + ), + 'customize' => array( + 'class-wp-customize-code-editor-control.php' => "f", + 'class-wp-customize-background-position-control.php' => "f", + 'class-wp-customize-upload-control.php' => "f", + 'class-wp-customize-header-image-setting.php' => "f", + 'class-wp-customize-nav-menu-auto-add-control.php' => "f", + 'class-wp-customize-filter-setting.php' => "f", + 'class-wp-customize-date-time-control.php' => "f", + 'class-wp-widget-form-customize-control.php' => "f", + 'class-wp-customize-themes-panel.php' => "f", + 'class-wp-customize-theme-control.php' => "f", + 'class-wp-customize-partial.php' => "f", + 'class-wp-customize-nav-menus-panel.php' => "f", + 'class-wp-customize-nav-menu-section.php' => "f", + 'class-wp-customize-custom-css-setting.php' => "f", + 'class-wp-customize-new-menu-section.php' => "f", + 'class-wp-customize-new-menu-control.php' => "f", + 'class-wp-customize-site-icon-control.php' => "f", + 'class-wp-customize-nav-menu-name-control.php' => "f", + 'class-wp-customize-background-image-setting.php' => "f", + 'class-wp-customize-nav-menu-control.php' => "f", + 'class-wp-customize-nav-menu-setting.php' => "f", + 'class-wp-customize-sidebar-section.php' => "f", + 'class-wp-customize-background-image-control.php' => "f", + 'class-wp-sidebar-block-editor-control.php' => "f", + 'class-wp-customize-header-image-control.php' => "f", + 'class-wp-customize-nav-menu-item-setting.php' => "f", + 'class-wp-customize-media-control.php' => "f", + 'class-wp-customize-nav-menu-item-control.php' => "f", + 'class-wp-customize-nav-menu-location-control.php' => "f", + 'class-wp-customize-nav-menu-locations-control.php' => "f", + 'class-wp-customize-themes-section.php' => "f", + 'class-wp-widget-area-customize-control.php' => "f", + 'class-wp-customize-color-control.php' => "f", + 'class-wp-customize-image-control.php' => "f", + 'class-wp-customize-cropped-image-control.php' => "f", + 'class-wp-customize-selective-refresh.php' => "f", + ), + 'class-wp-tax-query.php' => "f", + 'class-wp-navigation-fallback.php' => "f", + 'class-wp-xmlrpc-server.php' => "f", + 'class-walker-comment.php' => "f", + 'media-template.php' => "f", + 'functions.php' => "f", + 'class-wp-exception.php' => "f", + 'feed-rss.php' => "f", + 'post-thumbnail-template.php' => "f", + 'class-wp-metadata-lazyloader.php' => "f", + 'class-wp-object-cache.php' => "f", + 'class-wp-site.php' => "f", + 'class-wp-block-bindings-registry.php' => "f", + 'navigation-fallback.php' => "f", + 'class-wp-post-type.php' => "f", + 'ms-network.php' => "f", + 'class-wp-block-template.php' => "f", + 'class-wp-date-query.php' => "f", + 'class-wp-query.php' => "f", + 'class-wp-theme-json-resolver.php' => "f", + 'class-wp-network-query.php' => "f", + 'class-wp-customize-nav-menus.php' => "f", + 'class-walker-page-dropdown.php' => "f", + 'class-wp-block-type-registry.php' => "f", + 'general-template.php' => "f", + 'class-wp-recovery-mode.php' => "f", + 'php-compat' => array('readonly.php' => "f"), + 'widgets' => array( + 'class-wp-widget-recent-posts.php' => "f", + 'class-wp-widget-pages.php' => "f", + 'class-wp-widget-media-video.php' => "f", + 'class-wp-widget-text.php' => "f", + 'class-wp-widget-media-image.php' => "f", + 'class-wp-widget-meta.php' => "f", + 'class-wp-widget-media-gallery.php' => "f", + 'class-wp-widget-rss.php' => "f", + 'class-wp-widget-tag-cloud.php' => "f", + 'class-wp-nav-menu-widget.php' => "f", + 'class-wp-widget-categories.php' => "f", + 'class-wp-widget-block.php' => "f", + 'class-wp-widget-calendar.php' => "f", + 'class-wp-widget-media.php' => "f", + 'class-wp-widget-search.php' => "f", + 'class-wp-widget-archives.php' => "f", + 'class-wp-widget-recent-comments.php' => "f", + 'class-wp-widget-links.php' => "f", + 'class-wp-widget-custom-html.php' => "f", + 'class-wp-widget-media-audio.php' => "f", + ), + 'class-wp-text-diff-renderer-inline.php' => "f", + 'cron.php' => "f", + 'class-walker-category-dropdown.php' => "f", + 'post.php' => "f", + 'IXR' => array( + 'class-IXR-client.php' => "f", + 'class-IXR-introspectionserver.php' => "f", + 'class-IXR-base64.php' => "f", + 'class-IXR-date.php' => "f", + 'class-IXR-server.php' => "f", + 'class-IXR-request.php' => "f", + 'class-IXR-value.php' => "f", + 'class-IXR-message.php' => "f", + 'class-IXR-error.php' => "f", + 'class-IXR-clientmulticall.php' => "f", + ), + 'theme-previews.php' => "f", + 'class-walker-category.php' => "f", + 'class-wp-application-passwords.php' => "f", + 'category.php' => "f", + 'comment-template.php' => "f", + 'template-loader.php' => "f", + 'class-wp-classic-to-block-menu-converter.php' => "f", + 'functions.wp-scripts.php' => "f", + 'style-engine.php' => "f", + 'class.wp-scripts.php' => "f", + 'query.php' => "f", + 'class-wp-theme-json.php' => "f", + 'class-wp-duotone.php' => "f", + 'images' => array( + 'icon-pointer-flag.png' => "f", + 'admin-bar-sprite.png' => "f", + 'spinner.gif' => "f", + 'uploader-icons-2x.png' => "f", + 'toggle-arrow-2x.png' => "f", + 'rss.png' => "f", + 'arrow-pointer-blue-2x.png' => "f", + 'icon-pointer-flag-2x.png' => "f", + 'toggle-arrow.png' => "f", + 'wlw' => array( + 'wp-comments.png' => "f", + 'wp-watermark.png' => "f", + 'wp-icon.png' => "f", + ), + 'media' => array( + 'interactive.png' => "f", + 'video.svg' => "f", + 'document.png' => "f", + 'text.png' => "f", + 'code.svg' => "f", + 'default.png' => "f", + 'spreadsheet.png' => "f", + 'video.png' => "f", + 'interactive.svg' => "f", + 'spreadsheet.svg' => "f", + 'audio.svg' => "f", + 'document.svg' => "f", + 'default.svg' => "f", + 'audio.png' => "f", + 'text.svg' => "f", + 'archive.png' => "f", + 'code.png' => "f", + 'archive.svg' => "f", + ), + 'wpicons.png' => "f", + 'rss-2x.png' => "f", + 'arrow-pointer-blue.png' => "f", + 'uploader-icons.png' => "f", + 'w-logo-blue-white-bg.png' => "f", + 'wpicons-2x.png' => "f", + 'crystal' => array( + 'interactive.png' => "f", + 'license.txt' => "f", + 'document.png' => "f", + 'text.png' => "f", + 'default.png' => "f", + 'spreadsheet.png' => "f", + 'video.png' => "f", + 'audio.png' => "f", + 'archive.png' => "f", + 'code.png' => "f", + ), + 'spinner-2x.gif' => "f", + 'admin-bar-sprite-2x.png' => "f", + 'w-logo-blue.png' => "f", + 'xit-2x.gif' => "f", + 'wpspin.gif' => "f", + 'blank.gif' => "f", + 'smilies' => array( + 'icon_surprised.gif' => "f", + 'frownie.png' => "f", + 'icon_cool.gif' => "f", + 'icon_exclaim.gif' => "f", + 'icon_razz.gif' => "f", + 'icon_question.gif' => "f", + 'icon_lol.gif' => "f", + 'simple-smile.png' => "f", + 'icon_neutral.gif' => "f", + 'icon_mad.gif' => "f", + 'icon_evil.gif' => "f", + 'icon_wink.gif' => "f", + 'icon_eek.gif' => "f", + 'icon_smile.gif' => "f", + 'icon_mrgreen.gif' => "f", + 'icon_arrow.gif' => "f", + 'icon_biggrin.gif' => "f", + 'icon_confused.gif' => "f", + 'mrgreen.png' => "f", + 'rolleyes.png' => "f", + 'icon_cry.gif' => "f", + 'icon_twisted.gif' => "f", + 'icon_rolleyes.gif' => "f", + 'icon_idea.gif' => "f", + 'icon_redface.gif' => "f", + 'icon_sad.gif' => "f", + ), + 'xit.gif' => "f", + 'down_arrow.gif' => "f", + 'wpspin-2x.gif' => "f", + 'down_arrow-2x.gif' => "f", + ), + 'css' => array( + 'buttons-rtl.min.css' => "f", + 'editor.css' => "f", + 'wp-empty-template-alert.min.css' => "f", + 'wp-embed-template.css' => "f", + 'dashicons.min.css' => "f", + 'buttons-rtl.css' => "f", + 'jquery-ui-dialog-rtl.min.css' => "f", + 'customize-preview-rtl.min.css' => "f", + 'customize-preview-rtl.css' => "f", + 'media-views-rtl.css' => "f", + 'wp-auth-check.min.css' => "f", + 'wp-pointer-rtl.min.css' => "f", + 'wp-embed-template-ie.min.css' => "f", + 'dashicons.css' => "f", + 'admin-bar.min.css' => "f", + 'wp-pointer.min.css' => "f", + 'admin-bar-rtl.css' => "f", + 'wp-auth-check-rtl.css' => "f", + 'jquery-ui-dialog-rtl.css' => "f", + 'wp-empty-template-alert.css' => "f", + 'classic-themes.css' => "f", + 'buttons.min.css' => "f", + 'admin-bar-rtl.min.css' => "f", + 'admin-bar.css' => "f", + 'wp-auth-check.css' => "f", + 'editor.min.css' => "f", + 'classic-themes.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'wp-embed-template.min.css' => "f", + 'media-views.min.css' => "f", + 'media-views.css' => "f", + 'buttons.css' => "f", + 'editor-rtl.css' => "f", + 'jquery-ui-dialog.css' => "f", + 'media-views-rtl.min.css' => "f", + 'dist' => array( + 'edit-widgets' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'block-directory' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'list-reusable-blocks' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'edit-site' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'posts-rtl.min.css' => "f", + 'posts.css' => "f", + 'posts.min.css' => "f", + 'style.min.css' => "f", + 'posts-rtl.css' => "f", + 'style.css' => "f", + ), + 'edit-post' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'classic.css' => "f", + 'classic-rtl.css' => "f", + 'classic.min.css' => "f", + 'style.min.css' => "f", + 'classic-rtl.min.css' => "f", + 'style.css' => "f", + ), + 'commands' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'widgets' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'block-library' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'elements-rtl.css' => "f", + 'style-rtl.css' => "f", + 'reset.css' => "f", + 'reset-rtl.min.css' => "f", + 'theme-rtl.min.css' => "f", + 'classic.css' => "f", + 'theme.css' => "f", + 'elements.min.css' => "f", + 'reset.min.css' => "f", + 'common-rtl.min.css' => "f", + 'editor-elements.css' => "f", + 'classic-rtl.css' => "f", + 'classic.min.css' => "f", + 'editor-elements-rtl.css' => "f", + 'editor-elements.min.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'reset-rtl.css' => "f", + 'editor.min.css' => "f", + 'common.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'elements.css' => "f", + 'editor-rtl.css' => "f", + 'classic-rtl.min.css' => "f", + 'style.css' => "f", + 'common.min.css' => "f", + 'elements-rtl.min.css' => "f", + 'editor-elements-rtl.min.css' => "f", + 'common-rtl.css' => "f", + ), + 'reusable-blocks' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'customize-widgets' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'block-editor' => array( + 'style-rtl.min.css' => "f", + 'default-editor-styles.css' => "f", + 'content-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'content-rtl.css' => "f", + 'default-editor-styles.min.css' => "f", + 'default-editor-styles-rtl.css' => "f", + 'style.min.css' => "f", + 'default-editor-styles-rtl.min.css' => "f", + 'content.css' => "f", + 'style.css' => "f", + 'content.min.css' => "f", + ), + 'format-library' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'nux' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'components' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'preferences' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'editor' => array( + 'style-rtl.min.css' => "f", + 'editor-styles-rtl.min.css' => "f", + 'editor-styles.css' => "f", + 'style-rtl.css' => "f", + 'editor-styles.min.css' => "f", + 'style.min.css' => "f", + 'editor-styles-rtl.css' => "f", + 'style.css' => "f", + ), + 'patterns' => array( + 'style-rtl.min.css' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + ), + 'wp-embed-template-ie.css' => "f", + 'wp-pointer-rtl.css' => "f", + 'customize-preview.css' => "f", + 'customize-preview.min.css' => "f", + 'wp-auth-check-rtl.min.css' => "f", + 'jquery-ui-dialog.min.css' => "f", + 'wp-pointer.css' => "f", + ), + 'block-bindings.php' => "f", + 'wp-db.php' => "f", + 'rest-api' => array( + 'class-wp-rest-request.php' => "f", + 'search' => array( + 'class-wp-rest-term-search-handler.php' => "f", + 'class-wp-rest-post-format-search-handler.php' => "f", + 'class-wp-rest-search-handler.php' => "f", + 'class-wp-rest-post-search-handler.php' => "f", + ), + 'fields' => array( + 'class-wp-rest-term-meta-fields.php' => "f", + 'class-wp-rest-user-meta-fields.php' => "f", + 'class-wp-rest-comment-meta-fields.php' => "f", + 'class-wp-rest-post-meta-fields.php' => "f", + 'class-wp-rest-meta-fields.php' => "f", + ), + 'endpoints' => array( + 'class-wp-rest-font-faces-controller.php' => "f", + 'class-wp-rest-block-patterns-controller.php' => "f", + 'class-wp-rest-terms-controller.php' => "f", + 'class-wp-rest-menu-locations-controller.php' => "f", + 'class-wp-rest-block-types-controller.php' => "f", + 'class-wp-rest-menus-controller.php' => "f", + 'class-wp-rest-attachments-controller.php' => "f", + 'class-wp-rest-template-revisions-controller.php' => "f", + 'class-wp-rest-autosaves-controller.php' => "f", + 'class-wp-rest-widget-types-controller.php' => "f", + 'class-wp-rest-post-statuses-controller.php' => "f", + 'class-wp-rest-posts-controller.php' => "f", + 'class-wp-rest-blocks-controller.php' => "f", + 'class-wp-rest-menu-items-controller.php' => "f", + 'class-wp-rest-global-styles-controller.php' => "f", + 'class-wp-rest-edit-site-export-controller.php' => "f", + 'class-wp-rest-search-controller.php' => "f", + 'class-wp-rest-sidebars-controller.php' => "f", + 'class-wp-rest-font-families-controller.php' => "f", + 'class-wp-rest-site-health-controller.php' => "f", + 'class-wp-rest-font-collections-controller.php' => "f", + 'class-wp-rest-taxonomies-controller.php' => "f", + 'class-wp-rest-themes-controller.php' => "f", + 'class-wp-rest-navigation-fallback-controller.php' => "f", + 'class-wp-rest-block-directory-controller.php' => "f", + 'class-wp-rest-comments-controller.php' => "f", + 'class-wp-rest-widgets-controller.php' => "f", + 'class-wp-rest-templates-controller.php' => "f", + 'class-wp-rest-global-styles-revisions-controller.php' => "f", + 'class-wp-rest-controller.php' => "f", + 'class-wp-rest-plugins-controller.php' => "f", + 'class-wp-rest-block-renderer-controller.php' => "f", + 'class-wp-rest-url-details-controller.php' => "f", + 'class-wp-rest-settings-controller.php' => "f", + 'class-wp-rest-revisions-controller.php' => "f", + 'class-wp-rest-users-controller.php' => "f", + 'class-wp-rest-block-pattern-categories-controller.php' => "f", + 'class-wp-rest-pattern-directory-controller.php' => "f", + 'class-wp-rest-application-passwords-controller.php' => "f", + 'class-wp-rest-post-types-controller.php' => "f", + 'class-wp-rest-template-autosaves-controller.php' => "f", + ), + 'class-wp-rest-server.php' => "f", + 'class-wp-rest-response.php' => "f", + ), + 'media.php' => "f", + 'functions.wp-styles.php' => "f", + 'class-wp-textdomain-registry.php' => "f", + 'atomlib.php' => "f", + 'spl-autoload-compat.php' => "f", + 'formatting.php' => "f", + 'class-wp-site-query.php' => "f", + 'revision.php' => "f", + 'class-json.php' => "f", + 'class-wp-image-editor.php' => "f", + 'https-detection.php' => "f", + 'class-wp-customize-setting.php' => "f", + 'class-wp-phpmailer.php' => "f", + 'class-avif-info.php' => "f", + 'sitemaps' => array( + 'class-wp-sitemaps-provider.php' => "f", + 'class-wp-sitemaps-renderer.php' => "f", + 'class-wp-sitemaps-stylesheet.php' => "f", + 'class-wp-sitemaps-index.php' => "f", + 'class-wp-sitemaps.php' => "f", + 'class-wp-sitemaps-registry.php' => "f", + 'providers' => array( + 'class-wp-sitemaps-posts.php' => "f", + 'class-wp-sitemaps-taxonomies.php' => "f", + 'class-wp-sitemaps-users.php' => "f", + ), + ), + 'class-wp-plugin-dependencies.php' => "f", + 'https-migration.php' => "f", + 'ms-settings.php' => "f", + 'class-wp-theme-json-data.php' => "f", + 'class-wp-scripts.php' => "f", + 'class-walker-nav-menu.php' => "f", + 'class-wp-script-modules.php' => "f", + 'rss.php' => "f", + 'taxonomy.php' => "f", + 'rss-functions.php' => "f", + 'class-wp-block-metadata-registry.php' => "f", + 'rest-api.php' => "f", + 'session.php' => "f", + 'class-wp-block-styles-registry.php' => "f", + 'nav-menu-template.php' => "f", + 'admin-bar.php' => "f", + 'class-wp-block-pattern-categories-registry.php' => "f", + 'class.wp-styles.php' => "f", + 'class-wp-block-type.php' => "f", + 'feed-atom.php' => "f", + 'class-wp-post.php' => "f", + 'date.php' => "f", + 'pomo' => array( + 'translations.php' => "f", + 'mo.php' => "f", + 'entry.php' => "f", + 'po.php' => "f", + 'plural-forms.php' => "f", + 'streams.php' => "f", + ), + 'class-wp-block-editor-context.php' => "f", + 'widgets.php' => "f", + 'wlwmanifest.xml' => "f", + 'class-wp-block-bindings-source.php' => "f", + 'class-wp-session-tokens.php' => "f", + 'class-wp-taxonomy.php' => "f", + 'class-wp-simplepie-file.php' => "f", + 'class-wp-block-templates-registry.php' => "f", + 'block-patterns' => array( + 'query-grid-posts.php' => "f", + 'social-links-shared-background-color.php' => "f", + 'query-offset-posts.php' => "f", + 'heading-paragraph.php' => "f", + 'query-large-title-posts.php' => "f", + 'text-three-columns-buttons.php' => "f", + 'query-small-posts.php' => "f", + 'query-standard-posts.php' => "f", + 'two-buttons.php' => "f", + 'text-two-columns.php' => "f", + 'text-two-columns-with-images.php' => "f", + 'two-images.php' => "f", + 'quote.php' => "f", + 'three-buttons.php' => "f", + 'large-header.php' => "f", + 'query-medium-posts.php' => "f", + 'large-header-button.php' => "f", + ), + 'class-wp-rewrite.php' => "f", + 'class-wp-recovery-mode-email-service.php' => "f", + 'class-wp-meta-query.php' => "f", + 'class-wp-term.php' => "f", + 'bookmark-template.php' => "f", + 'default-widgets.php' => "f", + 'class-phpmailer.php' => "f", + 'class-wp-matchesmapregex.php' => "f", + 'class-wp-styles.php' => "f", + 'class-wp-image-editor-imagick.php' => "f", + 'class-wp-feed-cache-transient.php' => "f", + 'class-wp-feed-cache.php' => "f", + 'class-wp-widget.php' => "f", + 'class-wp-roles.php' => "f", + 'global-styles-and-settings.php' => "f", + 'meta.php' => "f", + 'class-pop3.php' => "f", + 'ms-default-filters.php' => "f", + 'class-wp-comment.php' => "f", + 'class-wp-customize-widgets.php' => "f", + 'ms-functions.php' => "f", + 'class-wp-error.php' => "f", + 'l10n.php' => "f", + 'theme-i18n.json' => "f", + 'class-wp-paused-extensions-storage.php' => "f", + 'class-walker-page.php' => "f", + 'class-wp-image-editor-gd.php' => "f", + 'registration.php' => "f", + 'pluggable-deprecated.php' => "f", + 'class-wp-editor.php' => "f", + 'author-template.php' => "f", + 'class-wp-http-response.php' => "f", + 'class-wp-simplepie-sanitize-kses.php' => "f", + 'feed-rss2.php' => "f", + 'script-modules.php' => "f", + 'assets' => array( + 'script-loader-react-refresh-runtime.min.php' => "f", + 'script-modules-packages.php' => "f", + 'script-modules-packages.min.php' => "f", + 'script-loader-packages.php' => "f", + 'script-loader-packages.min.php' => "f", + 'script-loader-react-refresh-entry.php' => "f", + 'script-loader-react-refresh-entry.min.php' => "f", + 'script-loader-react-refresh-runtime.php' => "f", + ), + 'locale.php' => "f", + 'plugin.php' => "f", + 'class-wp-admin-bar.php' => "f", + 'comment.php' => "f", + 'class-wp-speculation-rules.php' => "f", + 'style-engine' => array( + 'class-wp-style-engine-css-declarations.php' => "f", + 'class-wp-style-engine-css-rule.php' => "f", + 'class-wp-style-engine-css-rules-store.php' => "f", + 'class-wp-style-engine-processor.php' => "f", + 'class-wp-style-engine.php' => "f", + ), + 'capabilities.php' => "f", + 'class-smtp.php' => "f", + 'class-feed.php' => "f", + 'class-wp-widget-factory.php' => "f", + 'class-wp-http-curl.php' => "f", + 'class-wp-ajax-response.php' => "f", + 'ms-files.php' => "f", + 'class-wp-network.php' => "f", + 'class-wp.php' => "f", + 'error-protection.php' => "f", + 'class-wp-block-parser-frame.php' => "f", + 'option.php' => "f", + 'class-wp-embed.php' => "f", + 'nav-menu.php' => "f", + 'blocks' => array( + 'query-no-results.php' => "f", + 'missing' => array('block.json' => "f"), + 'post-navigation-link' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'post-comments.php' => "f", + 'query-pagination-previous' => array('block.json' => "f"), + 'post-date.php' => "f", + 'post-comments-form' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'cover.php' => "f", + 'verse' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'social-link.php' => "f", + 'query-total' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'read-more.php' => "f", + 'block.php' => "f", + 'file.php' => "f", + 'comments-pagination.php' => "f", + 'legacy-widget.php' => "f", + 'blocks-json.php' => "f", + 'comment-date' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'post-terms.php' => "f", + 'code' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'media-text' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'more' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'shortcode.php' => "f", + 'query-title' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'post-content.php' => "f", + 'post-terms' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'gallery' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'loginout.php' => "f", + 'group' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'search' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'view.asset.php' => "f", + 'view.min.js' => "f", + 'view.min.asset.php' => "f", + 'theme.css' => "f", + 'view.js' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'table' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'home-link.php' => "f", + 'video' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'template-part.php' => "f", + 'avatar.php' => "f", + 'post-featured-image.php' => "f", + 'comments-pagination-numbers' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'comments-query-loop' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'post-title.php' => "f", + 'comment-content.php' => "f", + 'post-excerpt.php' => "f", + 'require-dynamic-blocks.php' => "f", + 'nextpage' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'navigation-link' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'latest-posts.php' => "f", + 'page-list' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'tag-cloud.php' => "f", + 'post-content' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'comment-author-name' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'query-no-results' => array('block.json' => "f"), + 'image.php' => "f", + 'navigation-submenu' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'pullquote' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'navigation.php' => "f", + 'comments-pagination-next' => array('block.json' => "f"), + 'comment-template.php' => "f", + 'pattern.php' => "f", + 'comment-edit-link.php' => "f", + 'require-static-blocks.php' => "f", + 'post-date' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'query.php' => "f", + 'columns' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'html' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'buttons' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'site-title' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'latest-posts' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'navigation-submenu.php' => "f", + 'query-pagination-numbers.php' => "f", + 'navigation' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'view.asset.php' => "f", + 'view.min.js' => "f", + 'view.min.asset.php' => "f", + 'view-modal.asset.php' => "f", + 'view-modal.js' => "f", + 'view.js' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + 'view-modal.min.asset.php' => "f", + 'view-modal.min.js' => "f", + ), + 'button' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'comments' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'post-navigation-link.php' => "f", + 'pattern' => array('block.json' => "f"), + 'post-author' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'spacer' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'search.php' => "f", + 'column' => array('block.json' => "f"), + 'loginout' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'block' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'rss.php' => "f", + 'embed' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'query-pagination-previous.php' => "f", + 'post-author.php' => "f", + 'archives.php' => "f", + 'categories' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'preformatted' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'post-comments-form.php' => "f", + 'footnotes.php' => "f", + 'audio' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'page-list-item' => array('block.json' => "f"), + 'post-comments' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'social-link' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'comments-pagination-previous.php' => "f", + 'query-title.php' => "f", + 'latest-comments' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'comment-reply-link' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'latest-comments.php' => "f", + 'rss' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'site-tagline.php' => "f", + 'cover' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'comments-pagination' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'tag-cloud' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'media-text.php' => "f", + 'site-title.php' => "f", + 'heading' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'comment-reply-link.php' => "f", + 'comment-template' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'query-pagination' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'comment-content' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'comment-edit-link' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'term-description' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'site-logo' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'query' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'view.asset.php' => "f", + 'view.min.js' => "f", + 'view.min.asset.php' => "f", + 'view.js' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'comment-date.php' => "f", + 'comments-title.php' => "f", + 'classic' => array('block.json' => "f"), + 'index.php' => "f", + 'post-excerpt' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'shortcode' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'post-author-biography' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'post-template' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'query-total.php' => "f", + 'navigation-link.php' => "f", + 'subhead' => array('block.json' => "f"), + 'read-more' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'comments-pagination-previous' => array('block.json' => "f"), + 'site-logo.php' => "f", + 'query-pagination-numbers' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'gallery.php' => "f", + 'button.php' => "f", + 'list-item' => array('block.json' => "f"), + 'query-pagination-next.php' => "f", + 'comments-pagination-next.php' => "f", + 'categories.php' => "f", + 'term-description.php' => "f", + 'social-links' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'details' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'widget-group' => array('block.json' => "f"), + 'text-columns' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'home-link' => array('block.json' => "f"), + 'query-pagination.php' => "f", + 'page-list.php' => "f", + 'footnotes' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'post-author-name' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'post-author-name.php' => "f", + 'legacy-widget' => array('block.json' => "f"), + 'comments-title' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'freeform' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'separator' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'calendar.php' => "f", + 'page-list-item.php' => "f", + 'paragraph' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'site-tagline' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'file' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'view.asset.php' => "f", + 'view.min.js' => "f", + 'view.min.asset.php' => "f", + 'view.js' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'query-pagination-next' => array('block.json' => "f"), + 'post-featured-image' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'quote' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'theme.min.css' => "f", + 'style.css' => "f", + ), + 'comments.php' => "f", + 'avatar' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'list' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'image' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'theme-rtl.min.css' => "f", + 'view.asset.php' => "f", + 'view.min.js' => "f", + 'view.min.asset.php' => "f", + 'theme.css' => "f", + 'view.js' => "f", + 'theme-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'comments-pagination-numbers.php' => "f", + 'calendar' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'comment-author-name.php' => "f", + 'heading.php' => "f", + 'post-author-biography.php' => "f", + 'post-title' => array( + 'style-rtl.min.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'style.css' => "f", + ), + 'template-part' => array( + 'editor.css' => "f", + 'block.json' => "f", + 'theme-rtl.min.css' => "f", + 'theme.css' => "f", + 'theme-rtl.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'theme.min.css' => "f", + 'editor-rtl.css' => "f", + ), + 'archives' => array( + 'style-rtl.min.css' => "f", + 'editor.css' => "f", + 'block.json' => "f", + 'style-rtl.css' => "f", + 'style.min.css' => "f", + 'editor.min.css' => "f", + 'editor-rtl.min.css' => "f", + 'editor-rtl.css' => "f", + 'style.css' => "f", + ), + 'widget-group.php' => "f", + 'post-template.php' => "f", + 'list.php' => "f", + ), + 'ms-blogs.php' => "f", + 'block-supports' => array( + 'settings.php' => "f", + 'dimensions.php' => "f", + 'layout.php' => "f", + 'colors.php' => "f", + 'generated-classname.php' => "f", + 'duotone.php' => "f", + 'custom-classname.php' => "f", + 'border.php' => "f", + 'utils.php' => "f", + 'elements.php' => "f", + 'typography.php' => "f", + 'spacing.php' => "f", + 'background.php' => "f", + 'aria-label.php' => "f", + 'block-style-variations.php' => "f", + 'position.php' => "f", + 'align.php' => "f", + 'shadow.php' => "f", + ), + 'class-wp-http.php' => "f", + 'class-wp-recovery-mode-key-service.php' => "f", + 'class-wpdb.php' => "f", + 'sitemaps.php' => "f", + 'class-wp-locale-switcher.php' => "f", + 'template-canvas.php' => "f", + 'class-wp-user.php' => "f", + 'class-wp-http-ixr-client.php' => "f", + 'compat.php' => "f", + 'certificates' => array('ca-bundle.crt' => "f"), + 'class-http.php' => "f", + 'class-wp-http-encoding.php' => "f", + 'class-wp-theme.php' => "f", + 'fonts.php' => "f", + 'theme-templates.php' => "f", + 'feed-rss2-comments.php' => "f", + 'link-template.php' => "f", + 'speculative-loading.php' => "f", + 'class-wp-fatal-error-handler.php' => "f", + 'class-wp-block-parser-block.php' => "f", + 'class-wp-token-map.php' => "f", + 'robots-template.php' => "f", + 'ms-deprecated.php' => "f", + 'kses.php' => "f", + 'theme.json' => "f", + 'block-patterns.php' => "f", + 'feed-atom-comments.php' => "f", + 'version.php' => "f", + 'theme-compat' => array( + 'embed.php' => "f", + 'embed-404.php' => "f", + 'footer-embed.php' => "f", + 'footer.php' => "f", + 'sidebar.php' => "f", + 'embed-content.php' => "f", + 'header.php' => "f", + 'header-embed.php' => "f", + 'comments-popup.php' => "f", + 'comments.php' => "f", + ), + 'class-wp-dependencies.php' => "f", + 'class-wp-recovery-mode-link-service.php' => "f", + 'class-phpass.php' => "f", + 'class-wp-recovery-mode-cookie-service.php' => "f", + 'class-wp-dependency.php' => "f", + 'class-wp-http-proxy.php' => "f", + 'post-formats.php' => "f", + 'class-wp-text-diff-renderer-table.php' => "f", + 'wp-diff.php' => "f", + 'class-requests.php' => "f", + 'feed-rdf.php' => "f", + 'class-wp-user-request.php' => "f", + 'default-filters.php' => "f", + 'deprecated.php' => "f", + 'class-wp-block-patterns-registry.php' => "f", + 'class-wp-http-streams.php' => "f", + 'class-IXR.php' => "f", + 'class-wp-oembed.php' => "f", + 'block-editor.php' => "f", + 'class-wp-customize-control.php' => "f", + 'class-wp-customize-panel.php' => "f", + 'pluggable.php' => "f", + 'interactivity-api' => array( + 'class-wp-interactivity-api-directives-processor.php' => "f", + 'class-wp-interactivity-api.php' => "f", + 'interactivity-api.php' => "f", + ), + 'class-wp-url-pattern-prefixer.php' => "f", + 'random_compat' => array( + 'random_bytes_libsodium.php' => "f", + 'random_bytes_com_dotnet.php' => "f", + 'random_bytes_libsodium_legacy.php' => "f", + 'random_int.php' => "f", + 'random_bytes_openssl.php' => "f", + 'random.php' => "f", + 'error_polyfill.php' => "f", + 'random_bytes_mcrypt.php' => "f", + 'byte_safe_strings.php' => "f", + 'cast_to_int.php' => "f", + 'random_bytes_dev_urandom.php' => "f", + ), + 'class-wp-block-parser.php' => "f", + 'class-wp-locale.php' => "f", + 'shortcodes.php' => "f", + 'class.wp-dependencies.php' => "f", + 'post-template.php' => "f", + 'template.php' => "f", + 'l10n' => array( + 'class-wp-translations.php' => "f", + 'class-wp-translation-controller.php' => "f", + 'class-wp-translation-file-php.php' => "f", + 'class-wp-translation-file-mo.php' => "f", + 'class-wp-translation-file.php' => "f", + ), + 'http.php' => "f", + 'rewrite.php' => "f", + 'class-wp-http-cookie.php' => "f", + 'class-wp-user-query.php' => "f", + ), +); diff --git a/html/wp-content/plugins/duplicator/src/Libs/WpConfig/WPConfigTransformer.php b/html/wp-content/plugins/duplicator/src/Libs/WpConfig/WPConfigTransformer.php new file mode 100644 index 0000000..d4fea09 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/WpConfig/WPConfigTransformer.php @@ -0,0 +1,496 @@ +wp_config_path = $wp_config_path; + } + + /** + * Checks if a config exists in the wp-config.php file. + * + * @throws Exception If the wp-config.php file is empty. + * @throws Exception If the requested config type is invalid. + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * + * @return bool + */ + public function exists($type, $name) + { + $wp_config_src = file_get_contents($this->wp_config_path); + + if (! trim($wp_config_src)) { + throw new Exception('wp-config.php file is empty.'); + } + + // SnapCreek custom change + // Normalize the newline to prevent an issue coming from OSX + $wp_config_src = str_replace(array("\r\n", "\r"), "\n", $wp_config_src); + + $this->wp_config_src = $wp_config_src; + $this->wp_configs = $this->parseWpConfig($this->wp_config_src); + + if (! isset($this->wp_configs[ $type ])) { + throw new Exception("Config type '{$type}' does not exist."); + } + + return isset($this->wp_configs[ $type ][ $name ]); + } + + /** + * Get the value of a config in the wp-config.php file. + * + * @throws Exception If the wp-config.php file is empty. + * @throws Exception If the requested config type is invalid. + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * @param bool $get_real_value if true return real value + * + * @return array + */ + public function getValue($type, $name, $get_real_value = true) + { + $wp_config_src = file_get_contents($this->wp_config_path); + if (! trim($wp_config_src)) { + throw new Exception('wp-config.php file is empty.'); + } + + // SnapCreek custom change + // Normalize the newline to prevent an issue coming from OSX + $wp_config_src = str_replace(array("\r\n", "\r"), "\n", $wp_config_src); + + $this->wp_config_src = $wp_config_src; + $this->wp_configs = $this->parseWpConfig($this->wp_config_src); + + if (! isset($this->wp_configs[ $type ])) { + throw new Exception("Config type '{$type}' does not exist."); + } + + // Duplicator Extra + $val = $this->wp_configs[ $type ][ $name ]['value']; + if ($get_real_value) { + return self::getRealValFromVal($val); + } else { + return $val; + } + + return $val; + } + + /** + * Get typed val from string val + * + * @param string $val string value + * + * @return mixed + */ + public static function getRealValFromVal($val) + { + if ($val[0] === '\'') { + // string with ' + $result = substr($val, 1, strlen($val) - 2); + return str_replace(array('\\\'', '\\\\'), array('\'', '\\'), $result); + } elseif ($val[0] === '"') { + // string with " + return json_decode(str_replace('\\$', '$', $val)); + } elseif (strcasecmp($val, 'true') === 0) { + return true; + } elseif (strcasecmp($val, 'false') === 0) { + return false; + } elseif (strcasecmp($val, 'null') === 0) { + return null; + } elseif (preg_match('/^[-+]?[0-9]+$/', $val)) { + return (int) $val; + } elseif (preg_match('/^[-+]?[0-9]+\.[0-9]+$/', $val)) { + return (float) $val; + } else { + return $val; + } + } + + /** + * Adds a config to the wp-config.php file. + * + * @throws Exception If the config value provided is not a string. + * @throws Exception If the config placement anchor could not be located. + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * @param string $value Config value. + * @param array $options (optional) Array of special behavior options. + * + * @return bool + */ + public function add($type, $name, $value, array $options = array()) + { + if (! is_string($value)) { + throw new Exception('Config value must be a string.'); + } + + if ($this->exists($type, $name)) { + return false; + } + + $defaults = array( + 'raw' => false, // Display value in raw format without quotes. + 'anchor' => "/* That's all, stop editing!", // Config placement anchor string. + 'separator' => PHP_EOL, // Separator between config definition and anchor string. + 'placement' => 'before', // Config placement direction (insert before or after). + ); + + list( $raw, $anchor, $separator, $placement ) = array_values(array_merge($defaults, $options)); + + $raw = (bool) $raw; + $anchor = (string) $anchor; + $separator = (string) $separator; + $placement = (string) $placement; + + // Custom code by the SnapCreek Team + if (false === strpos($this->wp_config_src, $anchor)) { + $other_anchor_points = array( + '/** Absolute path to the WordPress directory', + // ABSPATH defined check with single quote + "if ( !defined('ABSPATH') )", + "if ( ! defined( 'ABSPATH' ) )", + "if (!defined('ABSPATH') )", + "if(!defined('ABSPATH') )", + "if(!defined('ABSPATH'))", + "if ( ! defined( 'ABSPATH' ))", + "if ( ! defined( 'ABSPATH') )", + "if ( ! defined('ABSPATH' ) )", + "if (! defined( 'ABSPATH' ))", + "if (! defined( 'ABSPATH') )", + "if (! defined('ABSPATH' ) )", + "if ( !defined( 'ABSPATH' ))", + "if ( !defined( 'ABSPATH') )", + "if ( !defined('ABSPATH' ) )", + "if( !defined( 'ABSPATH' ))", + "if( !defined( 'ABSPATH') )", + "if( !defined('ABSPATH' ) )", + // ABSPATH defined check with double quote + 'if ( !defined("ABSPATH") )', + 'if ( ! defined( "ABSPATH" ) )', + 'if (!defined("ABSPATH") )', + 'if(!defined("ABSPATH") )', + 'if(!defined("ABSPATH"))', + 'if ( ! defined( "ABSPATH" ))', + 'if ( ! defined( "ABSPATH") )', + 'if ( ! defined("ABSPATH" ) )', + 'if (! defined( "ABSPATH" ))', + 'if (! defined( "ABSPATH") )', + 'if (! defined("ABSPATH" ) )', + 'if ( !defined( "ABSPATH" ))', + 'if ( !defined( "ABSPATH") )', + 'if ( !defined("ABSPATH" ) )', + 'if( !defined( "ABSPATH" ))', + 'if( !defined( "ABSPATH") )', + 'if( !defined("ABSPATH" ) )', + + '/** Sets up WordPress vars and included files', + 'require_once(ABSPATH', + 'require_once ABSPATH', + 'require_once( ABSPATH', + 'require_once', + "define( 'DB_NAME'", + 'define( "DB_NAME"', + "define('DB_NAME'", + 'define("DB_NAME"', + 'require', + 'include_once', + ); + foreach ($other_anchor_points as $anchor_point) { + $anchor_point = (string) $anchor_point; + if (false !== strpos($this->wp_config_src, $anchor_point)) { + $anchor = $anchor_point; + break; + } + } + } + + if (false === strpos($this->wp_config_src, $anchor)) { + throw new Exception('Unable to locate placement anchor.'); + } + + $new_src = $this->normalize($type, $name, $this->formatValue($value, $raw)); + $new_src = ( 'after' === $placement ) ? $anchor . $separator . $new_src : $new_src . $separator . $anchor; + $contents = str_replace($anchor, $new_src, $this->wp_config_src); + + return $this->save($contents); + } + + /** + * Updates an existing config in the wp-config.php file. + * + * @throws Exception If the config value provided is not a string. + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * @param string $value Config value. + * @param array $options (optional) Array of special behavior options. + * + * @return bool + */ + public function update($type, $name, $value, array $options = array()) + { + if (! is_string($value)) { + throw new Exception('Config value must be a string.'); + } + + $defaults = array( + 'add' => true, // Add the config if missing. + 'raw' => false, // Display value in raw format without quotes. + 'normalize' => false, // Normalize config output using WP Coding Standards. + ); + + list( $add, $raw, $normalize ) = array_values(array_merge($defaults, $options)); + + $add = (bool) $add; + $raw = (bool) $raw; + $normalize = (bool) $normalize; + + if (! $this->exists($type, $name)) { + return ( $add ) ? $this->add($type, $name, $value, $options) : false; + } + + $old_src = $this->wp_configs[ $type ][ $name ]['src']; + $old_value = $this->wp_configs[ $type ][ $name ]['value']; + $new_value = $this->formatValue($value, $raw); + + if ($normalize) { + $new_src = $this->normalize($type, $name, $new_value); + } else { + $new_parts = $this->wp_configs[ $type ][ $name ]['parts']; + $new_parts[1] = str_replace($old_value, $new_value, $new_parts[1]); // Only edit the value part. + $new_src = implode('', $new_parts); + } + + $contents = preg_replace( + sprintf('/(?<=^|;|<\?php\s|<\?\s)(\s*?)%s/m', preg_quote(trim($old_src), '/')), + '$1' . self::REPLACE_TEMP_STIRNG, + $this->wp_config_src + ); + $contents = str_replace(self::REPLACE_TEMP_STIRNG, trim($new_src), $contents); + return $this->save($contents); + } + + /** + * Removes a config from the wp-config.php file. + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * + * @return bool + */ + public function remove($type, $name) + { + if (! $this->exists($type, $name)) { + return false; + } + + $pattern = sprintf('/(?<=^|;|<\?php\s|<\?\s)%s\s*(\S|$)/m', preg_quote($this->wp_configs[ $type ][ $name ]['src'], '/')); + $contents = preg_replace($pattern, '$1', $this->wp_config_src); + + return $this->save($contents); + } + + /** + * Applies formatting to a config value. + * + * @throws Exception When a raw value is requested for an empty string. + * + * @param string $value Config value. + * @param bool $raw Display value in raw format without quotes. + * + * @return mixed + */ + protected function formatValue($value, $raw) + { + if ($raw && '' === trim($value)) { + throw new Exception('Raw value for empty string not supported.'); + } + + return ( $raw ) ? $value : var_export($value, true); + } + + /** + * Normalizes the source output for a name/value pair. + * + * @throws Exception If the requested config type does not support normalization. + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * @param mixed $value Config value. + * + * @return string + */ + protected function normalize($type, $name, $value) + { + if ('constant' === $type) { + $placeholder = "define( '%s', %s );"; + } elseif ('variable' === $type) { + $placeholder = '$%s = %s;'; + } else { + throw new Exception("Unable to normalize config type '{$type}'."); + } + + return sprintf($placeholder, $name, $value); + } + + /** + * Parses the source of a wp-config.php file. + * + * @param string $src Config file source. + * + * @return array + */ + protected function parseWpConfig($src) + { + $configs = array(); + $configs['constant'] = array(); + $configs['variable'] = array(); + + if (function_exists('token_get_all')) { + // Strip comments. + foreach (token_get_all($src) as $token) { + if (in_array($token[0], array( T_COMMENT, T_DOC_COMMENT ), true)) { + $src = str_replace($token[1], '', $src); + } + } + } + + preg_match_all( + '/(?<=^|;|<\?php\s|<\?\s)' . + '(\h*define\s*\(\s*[\'"](\w*?)[\'"]\s*)(,\s*(\'\'|""|\'.*?[^\\\\]\'|".*?[^\\\\]"|.*?)\s*)' . + '((?:,\s*(?:true|false)\s*)?\)\s*;)/ims', + $src, + $constants + ); + preg_match_all('/(?<=^|;|<\?php\s|<\?\s)(\h*\$(\w+)\s*=)(\s*(\'\'|""|\'.*?[^\\\\]\'|".*?[^\\\\]"|.*?)\s*;)/ims', $src, $variables); + + if ( + !empty($constants[0]) && + !empty($constants[1]) && + !empty($constants[2]) && + !empty($constants[3]) && + !empty($constants[4]) && + !empty($constants[5]) + ) { + foreach ($constants[2] as $index => $name) { + $configs['constant'][ $name ] = array( + 'src' => $constants[0][ $index ], + 'value' => $constants[4][ $index ], + 'parts' => array( + $constants[1][ $index ], + $constants[3][ $index ], + $constants[5][ $index ], + ), + ); + } + } + + if (! empty($variables[0]) && ! empty($variables[1]) && ! empty($variables[2]) && ! empty($variables[3]) && ! empty($variables[4])) { + // Remove duplicate(s), last definition wins. + $variables[2] = array_reverse(array_unique(array_reverse($variables[2], true)), true); + foreach ($variables[2] as $index => $name) { + $configs['variable'][ $name ] = array( + 'src' => $variables[0][ $index ], + 'value' => $variables[4][ $index ], + 'parts' => array( + $variables[1][ $index ], + $variables[3][ $index ], + ), + ); + } + } + + return $configs; + } + + /** + * Saves new contents to the wp-config.php file. + * + * @throws Exception If the config file content provided is empty. + * @throws Exception If there is a failure when saving the wp-config.php file. + * + * @param string $contents New config contents. + * + * @return bool + */ + protected function save($contents) + { + if (!trim($contents)) { + throw new Exception('Cannot save the wp-config.php file with empty contents.'); + } + + if ($contents === $this->wp_config_src) { + return false; + } + + $result = file_put_contents($this->wp_config_path, $contents, LOCK_EX); + + if (false === $result) { + throw new Exception('Failed to update the wp-config.php file.'); + } + + return true; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Libs/WpConfig/WPConfigTransformerSrc.php b/html/wp-content/plugins/duplicator/src/Libs/WpConfig/WPConfigTransformerSrc.php new file mode 100644 index 0000000..52b99d9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Libs/WpConfig/WPConfigTransformerSrc.php @@ -0,0 +1,99 @@ +wp_config_src = str_replace(array("\n\r", "\r"), array("\n", "\n"), $wp_config_src); + } + + /** + * Get content string + * + * @return string + */ + public function getSrc() + { + return $this->wp_config_src; + } + + /** + * Checks if a config exists in the wp-config.php src + * + * @throws Exception If the wp-config.php file is empty. + * @throws Exception If the requested config type is invalid. + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * + * @return bool + */ + public function exists($type, $name) + { + $this->wp_configs = $this->parseWpConfig($this->wp_config_src); + + if (!isset($this->wp_configs[$type])) { + throw new Exception("Config type '{$type}' does not exist."); + } + + return isset($this->wp_configs[$type][$name]); + } + + /** + * Get the value of a config in the wp-config.php src + * + * @param string $type Config type (constant or variable). + * @param string $name Config name. + * @param bool $get_real_value if true return typed value + * + * @return array + */ + public function getValue($type, $name, $get_real_value = true) + { + $this->wp_configs = $this->parseWpConfig($this->wp_config_src); + + if (!isset($this->wp_configs[$type])) { + throw new Exception("Config type '{$type}' does not exist."); + } + + // Duplicator Extra + $val = $this->wp_configs[$type][$name]['value']; + if ($get_real_value) { + return self::getRealValFromVal($val); + } else { + return $val; + } + } + + /** + * Update wp_config_src + * + * @param string $contents config content + * + * @return boolean + */ + protected function save($contents) + { + $this->wp_config_src = $contents; + return true; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Lite/Requirements.php b/html/wp-content/plugins/duplicator/src/Lite/Requirements.php new file mode 100644 index 0000000..49437bc --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Lite/Requirements.php @@ -0,0 +1,151 @@ + tags', + 'duplicator' + ), + '', + '' + ); + $result = false; + } + + if ($result === false) { + register_activation_hook($pluginFile, array(__CLASS__, 'deactivateOnActivation')); + } + + return $result; + } + + /** + * + * @param string $plugin plugin slug + * + * @return boolean return true if plugin key is active and plugin file exists + */ + protected static function isPluginActive($plugin) + { + $isActive = false; + if (in_array($plugin, (array) get_option('active_plugins', array()))) { + $isActive = true; + } + + if (is_multisite()) { + $plugins = get_site_option('active_sitewide_plugins'); + if (isset($plugins[$plugin])) { + $isActive = true; + } + } + + return ($isActive && file_exists(WP_PLUGIN_DIR . '/' . $plugin)); + } + + /** + * display admin notice only if user can manage plugins. + * + * @return void + */ + public static function addProEnableNotice() + { + if (current_user_can('activate_plugins')) { + add_action('admin_notices', array(__CLASS__, 'proEnabledNotice')); + } + } + + /** + * display admin notice + * + * @return void + */ + public static function addMultisiteNotice() + { + if (current_user_can('activate_plugins')) { + add_action('admin_notices', array(__CLASS__, 'multisiteNotice')); + } + } + + /** + * deactivate current plugin on activation + * + * @return void + */ + public static function deactivateOnActivation() + { + deactivate_plugins(plugin_basename(self::$pluginFile)); + wp_die(self::$deactivationMessage); + } + + /** + * Display admin notice if duplicator pro is enabled + * + * @return void + */ + public static function proEnabledNotice() + { + $pluginUrl = (is_multisite() ? network_admin_url('plugins.php') : admin_url('plugins.php')); + ?> +
        +

        + + + +

        +

        + + + . + +

        +
        + $mappedPath) { + if (strpos($className, $namespace) !== 0) { + continue; + } + + $filepath = $mappedPath . str_replace('\\', '/', substr($className, strlen($namespace))) . '.php'; + if (file_exists($filepath)) { + include_once($filepath); + return true; + } + } + } + + return false; + } + + /** + * Load external libs + * + * @param string $className class name + * + * @return bool return true if class is loaded + */ + protected static function externalLibs($className) + { + switch (strtolower(ltrim($className, '\\'))) { + default: + return false; + } + } + + /** + * mappgin of some legacy classes + * + * @return array + */ + protected static function customLegacyMapping() + { + return array(); + } + + /** + * Return namespace mapping + * + * @return string[] + */ + protected static function getNamespacesMapping() + { + // the order is important, it is necessary to insert the longest namespaces first + return array( + self::ROOT_INSTALLER_NAMESPACE => DUPLICATOR_LITE_PATH . '/installer/dup-installer/src/', + self::ROOT_NAMESPACE => DUPLICATOR_LITE_PATH . '/src/' + ); + } + + /** + * Returns true if the $haystack string end with the $needle, only for internal use + * + * @param string $haystack The full string to search in + * @param string $needle The string to for + * + * @return bool Returns true if the $haystack string starts with the $needle + */ + protected static function endsWith($haystack, $needle) + { + $length = strlen($needle); + if ($length == 0) { + return true; + } + + return (substr($haystack, -$length) === $needle); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/CachesPurge/CacheItem.php b/html/wp-content/plugins/duplicator/src/Utils/CachesPurge/CacheItem.php new file mode 100644 index 0000000..c7edb4d --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/CachesPurge/CacheItem.php @@ -0,0 +1,108 @@ +name = $name; + if (!is_bool($checkCallback) && !is_callable($checkCallback)) { + throw new Exception('checkCallback must be boolean or callable'); + } + $this->checkCallback = $checkCallback; + + /* purge callback may not exist if the referenced plugin is not initialized. + * That's why the check is performed only if you actually purge the plugin + */ + $this->purgeCallback = $purgeCallback; + $this->purgedMessage = sprintf(__('All caches on %s have been purged.', 'duplicator'), $this->name); + } + + /** + * overwrite default purged message + * + * @param string $message message if item have benn purged + * + * @return void + */ + public function setPurgedMessage($message) + { + $this->purgedMessage = $message; + } + + /** + * purge caches item + * + * @param string $message message if item have benn purged + * + * @return bool + */ + public function purge(&$message) + { + try { + if ( + (is_bool($this->checkCallback) && $this->checkCallback) || + call_user_func($this->checkCallback) == true + ) { + DUP_Log::trace('Purge ' . $this->name); + if (!is_callable($this->purgeCallback)) { + throw new Exception('purgeCallback must be callable'); + } + call_user_func($this->purgeCallback); + $message = $this->purgedMessage; + } + return true; + } catch (Exception $e) { + DUP_Log::trace('Error purge ' . $this->name . ' message:' . $e->getMessage()); + $message = sprintf(__('Error on caches purge of %s.', 'duplicator'), $this->name); + return false; + } catch (Error $e) { + DUP_Log::trace('Error purge ' . $this->name . ' message:' . $e->getMessage()); + $message = sprintf(__('Error on caches purge of %s.', 'duplicator'), $this->name); + return false; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/CachesPurge/CachesPurge.php b/html/wp-content/plugins/duplicator/src/Utils/CachesPurge/CachesPurge.php new file mode 100644 index 0000000..75c3cb9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/CachesPurge/CachesPurge.php @@ -0,0 +1,291 @@ +purge($message); + if (strlen($message) > 0 && $result) { + $globalMessages[] = $message; + } + } + + return $globalMessages; + } + + /** + * get list to cache items to purge + * + * @return CacheItem[] + */ + protected static function getPurgePlugins() + { + $items = array(); + $items[] = new CacheItem( + 'Elementor', + function () { + return class_exists("\\Elementor\\Plugin"); + }, + function () { + \Elementor\Plugin::$instance->files_manager->clear_cache(); + } + ); + $items[] = new CacheItem( + 'W3 Total Cache', + function () { + return function_exists('w3tc_pgcache_flush'); + }, + 'w3tc_pgcache_flush' + ); + $items[] = new CacheItem( + 'WP Super Cache', + function () { + return function_exists('wp_cache_clear_cache'); + }, + 'wp_cache_clear_cache' + ); + $items[] = new CacheItem( + 'WP Rocket', + function () { + return function_exists('rocket_clean_domain'); + }, + 'rocket_clean_domain' + ); + $items[] = new CacheItem( + 'Fast velocity minify', + function () { + return function_exists('fvm_purge_static_files'); + }, + 'fvm_purge_static_files' + ); + $items[] = new CacheItem( + 'Cachify', + function () { + return function_exists('cachify_flush_cache'); + }, + 'cachify_flush_cache' + ); + $items[] = new CacheItem( + 'Comet Cache', + function () { + return class_exists('\\comet_cache'); + }, + array('\\comet_cache', 'clear') + ); + $items[] = new CacheItem( + 'Zen Cache', + function () { + return class_exists('\\zencache'); + }, + array('\\zencache', 'clear') + ); + $items[] = new CacheItem( + 'LiteSpeed Cache', + function () { + return has_action('litespeed_purge_all'); + }, + function () { + return do_action('litespeed_purge_all'); + } + ); + $items[] = new CacheItem( + 'WP Cloudflare Super Page Cache', + function () { + return class_exists('\\SW_CLOUDFLARE_PAGECACHE'); + }, + function () { + return do_action("swcfpc_purge_everything"); + } + ); + $items[] = new CacheItem( + 'Hyper Cache', + function () { + return class_exists('\\HyperCache'); + }, + function () { + return do_action('autoptimize_action_cachepurged'); + } + ); + $items[] = new CacheItem( + 'Cache Enabler', + function () { + return has_action('ce_clear_cache'); + }, + function () { + return do_action('ce_clear_cache'); + } + ); + $items[] = new CacheItem( + 'WP Fastest Cache', + function () { + return function_exists('wpfc_clear_all_cache'); + }, + function () { + wpfc_clear_all_cache(true); + } + ); + $items[] = new CacheItem( + 'Breeze', + function () { + return class_exists("\\Breeze_PurgeCache"); + }, + array('\\Breeze_PurgeCache', 'breeze_cache_flush') + ); + $items[] = new CacheItem( + 'Swift Performance', + function () { + return class_exists("\\Swift_Performance_Cache"); + }, + array('\\Swift_Performance_Cache', 'clear_all_cache') + ); + $items[] = new CacheItem( + 'Hummingbird', + function () { + return has_action('wphb_clear_page_cache'); + }, + function () { + return do_action('wphb_clear_page_cache'); + } + ); + $items[] = new CacheItem( + 'WP-Optimize', + function () { + return has_action('wpo_cache_flush'); + }, + function () { + return do_action('wpo_cache_flush'); + } + ); + $items[] = new CacheItem( + 'Wordpress default', + function () { + return function_exists('wp_cache_flush'); + }, + 'wp_cache_flush' + ); + $items[] = new CacheItem( + 'Wordpress permalinks', + function () { + return function_exists('flush_rewrite_rules'); + }, + 'flush_rewrite_rules' + ); + return $items; + } + + /** + * get list to cache items to purge + * + * @return CacheItem[] + */ + protected static function getPurgeHosts() + { + $items = array(); + $items[] = new CacheItem( + 'Godaddy Managed WordPress Hosting', + function () { + return class_exists('\\WPaaS\\Plugin') && method_exists('\\WPass\\Plugin', 'vip'); + }, + function () { + $method = 'BAN'; + $url = home_url(); + $host = wpraiser_get_domain(); + $url = set_url_scheme(str_replace($host, \WPaas\Plugin::vip(), $url), 'http'); + update_option('gd_system_last_cache_flush', time(), 'no'); # purge apc + wp_remote_request( + esc_url_raw($url), + array( + 'method' => $method, + 'blocking' => false, + 'headers' => + array( + 'Host' => $host + ) + ) + ); + } + ); + $items[] = new CacheItem( + 'SG Optimizer (Siteground)', + function () { + return function_exists('sg_cachepress_purge_everything'); + }, + 'sg_cachepress_purge_everything' + ); + $items[] = new CacheItem( + 'WP Engine', + function () { + return (class_exists("\\WpeCommon") && + (method_exists('\\WpeCommon', 'purge_memcached') || + method_exists('\\WpeCommon', 'purge_varnish_cache'))); + }, + function () { + if (method_exists('\\WpeCommon', 'purge_memcached')) { + \WpeCommon::purge_memcached(); + } + if (method_exists('\\WpeCommon', 'purge_varnish_cache')) { + \WpeCommon::purge_varnish_cache(); + } + } + ); + $items[] = new CacheItem( + 'Kinsta', + function () { + global $kinsta_cache; + return ( + (isset($kinsta_cache) && + class_exists('\\Kinsta\\CDN_Enabler')) && + !empty($kinsta_cache->kinsta_cache_purge)); + }, + function () { + global $kinsta_cache; + $kinsta_cache->kinsta_cache_purge->purge_complete_caches(); + } + ); + $items[] = new CacheItem( + 'Pagely', + function () { + return class_exists('\\PagelyCachePurge'); + }, + function () { + $purge_pagely = new \PagelyCachePurge(); + $purge_pagely->purgeAll(); + } + ); + $items[] = new CacheItem( + 'Pressidum', + function () { + return defined('WP_NINUKIS_WP_NAME') && class_exists('\\Ninukis_Plugin'); + }, + function () { + $purge_pressidum = \Ninukis_Plugin::get_instance(); + $purge_pressidum->purgeAllCaches(); + } + ); + + $items[] = new CacheItem( + 'Pantheon Advanced Page Cache plugin', + function () { + return function_exists('pantheon_wp_clear_edge_all'); + }, + 'pantheon_wp_clear_edge_all' + ); + return $items; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/CronUtils.php b/html/wp-content/plugins/duplicator/src/Utils/CronUtils.php new file mode 100644 index 0000000..e5fc354 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/CronUtils.php @@ -0,0 +1,47 @@ +> $schedules schedules + * + * @return array> + */ + public static function defaultCronIntervals($schedules) + { + $schedules[self::INTERVAL_DAILTY] = array( + 'interval' => DAY_IN_SECONDS, + 'display' => __('Once a Day', 'duplicator'), + ); + + $schedules[self::INTERVAL_WEEKLY] = array( + 'interval' => WEEK_IN_SECONDS, + 'display' => __('Once a Week', 'duplicator'), + ); + + $schedules[self::INTERVAL_MONTHLY] = array( + 'interval' => MONTH_IN_SECONDS, + 'display' => __('Once a Month', 'duplicator'), + ); + + return $schedules; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/DuplicatorPhpVersionCheck.php b/html/wp-content/plugins/duplicator/src/Utils/DuplicatorPhpVersionCheck.php new file mode 100644 index 0000000..ad27ec6 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/DuplicatorPhpVersionCheck.php @@ -0,0 +1,112 @@ + +
        +

        + PHP Version Update Needed, Your site is running PHP version %s.', + 'duplicator' + ), + esc_html($phpVersion) + ), + [ + 'b' => [], + ] + ); + ?>

        + Duplicator %1$s, Duplicator will require PHP %2$s or higher to receive new updates.', + 'duplicator' + ), + '1.5.12', + esc_html(self::$minVer) + ), + [ + 'b' => [], + ] + ); + ?>
        +
        + +

        +

        + + + +

        +
        + > List of styles in class => styles format*/ + public static $styles = array( + 'body' => array( + "border-collapse" => "collapse", + "border-spacing" => "0", + "vertical-align" => "top", + "mso-table-lspace" => "0pt", + "mso-table-rspace" => "0pt", + "-ms-text-size-adjust" => "100%", + "-webkit-text-size-adjust" => "100%", + "height" => "100% !important", + "width" => "100% !important", + "min-width" => "100%", + "-moz-box-sizing" => "border-box", + "-webkit-box-sizing" => "border-box", + "box-sizing" => "border-box", + "-webkit-font-smoothing" => "antialiased !important", + "-moz-osx-font-smoothing" => "grayscale !important", + "background-color" => "#e9eaec", + "color" => "#444444", + "font-family" => "'Helvetica Neue', Helvetica, Arial, sans-serif", + "font-weight" => "normal", + "padding" => "0", + "margin" => "0", + "text-align" => "left", + "font-size" => "14px", + "mso-line-height-rule" => "exactly", + "line-height" => "140%", + ), + 'table' => array( + "border-collapse" => "collapse", + "border-spacing" => "0", + "vertical-align" => "top", + "mso-table-lspace" => "0pt", + "mso-table-rspace" => "0pt", + "-ms-text-size-adjust" => "100%", + "-webkit-text-size-adjust" => "100%", + "margin" => "0 auto 0 auto", + "padding" => "0", + "text-align" => "inherit", + ), + 'main-tbl' => array( + "width" => "600px", + ), + 'stats-tbl' => array( + "-ms-text-size-adjust" => "100%", + "-webkit-text-size-adjust" => "100%", + "width" => "100%", + "margin" => "15px 0 38px 0", + ), + 'tr' => array( + "padding" => "0", + "vertical-align" => "top", + "text-align" => "left", + ), + 'td' => array( + "word-wrap" => "break-word", + "-webkit-hyphens" => "auto", + "-moz-hyphens" => "auto", + "hyphens" => "auto", + "border-collapse" => "collapse !important", + "vertical-align" => "top", + "mso-table-lspace" => "0pt", + "mso-table-rspace" => "0pt", + "-ms-text-size-adjust" => "100%", + "-webkit-text-size-adjust" => "100%", + "color" => "#444444", + "font-family" => "'Helvetica Neue', Helvetica, Arial, sans-serif", + "font-weight" => "normal", + "padding" => "0", + "margin" => "0", + "font-size" => "14px", + "mso-line-height-rule" => "exactly", + "line-height" => "140%", + ), + 'stats-count-cell' => array( + 'width' => '1px', + 'text-align' => 'center', + ), + 'unsubscribe' => array( + "padding" => "30px", + "color" => "#72777c", + "font-size" => "12px", + "text-align" => "center", + ), + 'th' => array( + "font-family" => "'Helvetica Neue', Helvetica, Arial, sans-serif", + "margin" => "0", + "text-align" => "left", + "font-size" => "14px", + "mso-line-height-rule" => "exactly", + "line-height" => "140%", + "font-weight" => "700", + "color" => "#777777", + "background" => "#f1f1f1", + "border" => "1px solid #f1f1f1", + "padding" => "17px 20px 17px 20px", + ), + 'stats-cell' => array( + "font-size" => "16px", + "border-top" => "none", + "border-right" => "none", + "border-bottom" => "1px solid #f1f1f1", + "border-left" => "none", + "color" => "#444444", + "padding" => "17px 20px 17px 20px", + ), + 'img' => array( + "outline" => "none", + "text-decoration" => "none", + "width" => "auto", + "clear" => "both", + "-ms-interpolation-mode" => "bicubic", + "display" => "inline-block !important", + "max-width" => "45%", + ), + 'h6' => array( + "padding" => "0", + "text-align" => "left", + "word-wrap" => "normal", + "font-family" => "'Helvetica Neue', Helvetica, Arial, sans-serif", + "font-weight" => "bold", + "mso-line-height-rule" => "exactly", + "line-height" => "130%", + "font-size" => "18px", + "color" => "#444444", + "margin" => "0 0 3px 0", + ), + 'p' => array( + "-ms-text-size-adjust" => "100%", + "-webkit-text-size-adjust" => "100%", + "font-family" => "'Helvetica Neue', Helvetica, Arial, sans-serif", + "font-weight" => "normal", + "padding" => "0", + "text-align" => "left", + "mso-line-height-rule" => "exactly", + "line-height" => "140%", + "overflow-wrap" => "break-word", + "word-wrap" => "break-word", + "-ms-word-break" => "break-all", + "word-break" => "break-word", + "-ms-hyphens" => "auto", + "-moz-hyphens" => "auto", + "-webkit-hyphens" => "auto", + "hyphens" => "auto", + "color" => "#777777", + "font-size" => "14px", + "margin" => "25px 0 25px 0", + ), + 'a' => array( + "-ms-text-size-adjust" => "100%", + "-webkit-text-size-adjust" => "100%", + "font-family" => "'Helvetica Neue', Helvetica, Arial, sans-serif", + "font-weight" => "normal", + "padding" => "0", + "margin" => "0", + "Margin" => "0", + "text-align" => "left", + "mso-line-height-rule" => "exactly", + "line-height" => "140%", + ), + 'footer-link' => array( + "color" => "#72777c", + "text-decoration" => "underline", + ), + 'inline-link' => array( + "color" => "inherit", + "text-decoration" => "underline", + ), + 'stats-title' => array( + "margin" => "0 0 15px 0", + ), + 'subtitle' => array( + "font-size" => "16px", + "margin" => "0 0 15px 0", + ), + 'txt-orange' => array( + "color" => "#e27730", + ), + 'txt-center' => array( + 'text-align' => 'center', + ), + 'logo' => array( + "padding" => "30px 0px", + ), + 'content' => array( + "background-color" => "#ffffff", + "padding" => "60px 75px 45px 75px", + "border-top" => "3px solid #e27730", + "border-right" => "1px solid #dddddd", + "border-bottom" => "1px solid #dddddd", + "border-left" => "1px solid #dddddd", + ), + 'strong' => array( + "font-weight" => "bold", + ), + ); + + /** + * Get Inline CSS of selector or empty if selector not found + * + * @param string $selectors Space separated selectors + * + * @return string + */ + public static function getStyle($selectors) + { + if ($selectors === '') { + return ''; + } + + $selArr = explode(' ', $selectors); + $uniqueStyles = array(); + foreach ($selArr as $i => $selector) { + if (!isset(self::$styles[$selector])) { + continue; + } + + //overwrite repeating styles + foreach (self::$styles[$selector] as $key => $value) { + $uniqueStyles[$key] = $value; + } + } + + $style = ''; + foreach ($uniqueStyles as $key => $value) { + $style .= $key . ': ' . $value . ';'; + } + + return $style; + } + + /** + * Print Inline CSS of selector or empty if selector not found + * + * @param string $selectors Space separated selectors + * + * @return void + */ + public static function printStyle($selectors) + { + echo 'class="' . esc_attr($selectors) . '" style="' . self::getStyle($selectors) . '"'; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/Email/EmailSummary.php b/html/wp-content/plugins/duplicator/src/Utils/Email/EmailSummary.php new file mode 100644 index 0000000..68ae52f --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/Email/EmailSummary.php @@ -0,0 +1,171 @@ +manualPackageIds[] = $package->ID; + } elseif ($status === DUP_PackageStatus::ERROR) { + $this->failedPackageIds[] = $package->ID; + } + + $this->save(); + } + + /** + * Returns info about created packages + * + * @return array> + */ + public function getPackagesInfo() + { + $packagesInfo = array(); + $packagesInfo['manual'] = array( + 'name' => __('Successful', 'duplicator'), + 'count' => count($this->manualPackageIds), + ); + + $packagesInfo['failed'] = array( + 'name' => __('Failed', 'duplicator'), + 'count' => count($this->failedPackageIds), + ); + + return $packagesInfo; + } + + /** + * Get all frequency options + * + * @return array + */ + public static function getAllFrequencyOptions() + { + return array( + self::SEND_FREQ_NEVER => esc_html__('Never', 'duplicator'), + self::SEND_FREQ_DAILY => esc_html__('Daily', 'duplicator'), + self::SEND_FREQ_WEEKLY => esc_html__('Weekly', 'duplicator'), + self::SEND_FREQ_MONTHLY => esc_html__('Monthly', 'duplicator'), + ); + } + + /** + * Get the frequency text displayed in the email + * + * @return string + */ + public static function getFrequencyText() + { + $frequency = DUP_Settings::Get('email_summary_frequency'); + switch ($frequency) { + case self::SEND_FREQ_DAILY: + return esc_html__('day', 'duplicator'); + case self::SEND_FREQ_MONTHLY: + return esc_html__('month', 'duplicator'); + case self::SEND_FREQ_WEEKLY: + default: + return esc_html__('week', 'duplicator'); + } + } + + /** + * Reset plugin data + * + * @return bool True if data has been reset, false otherwise + */ + public function resetData() + { + $this->manualPackageIds = array(); + $this->failedPackageIds = array(); + + return $this->save(); + } + + /** + * Save plugin data + * + * @return bool True if data has been saved, false otherwise + */ + private function save() + { + return update_option(self::INFO_OPT_KEY, JsonSerialize::serialize($this)); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/Email/EmailSummaryBootstrap.php b/html/wp-content/plugins/duplicator/src/Utils/Email/EmailSummaryBootstrap.php new file mode 100644 index 0000000..7c94868 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/Email/EmailSummaryBootstrap.php @@ -0,0 +1,249 @@ +addPackage($package, $status); + } + + /** + * Send email summary + * + * @return bool True if email was sent + */ + public static function send() + { + $frequency = DUP_Settings::Get('email_summary_frequency'); + if (($recipient = get_option('admin_email')) === false || $frequency === EmailSummary::SEND_FREQ_NEVER) { + return false; + } + + $parsedHomeUrl = wp_parse_url(home_url()); + $siteDomain = $parsedHomeUrl['host']; + + if (is_multisite() && isset($parsedHomeUrl['path'])) { + $siteDomain .= $parsedHomeUrl['path']; + } + + $subject = sprintf( + esc_html_x( + 'Your Weekly Duplicator Summary for %s', + '%s is the site domain', + 'duplicator' + ), + $siteDomain + ); + + $content = TplMng::getInstance()->render('mail/email_summary', array( + 'packages' => EmailSummary::getInstance()->getPackagesInfo(), + ), false); + + add_filter('wp_mail_content_type', array(__CLASS__, 'getMailContentType')); + if (!wp_mail($recipient, $subject, $content)) { + DUP_Log::Trace("FAILED TO SEND EMAIL SUMMARY."); + DUP_Log::Trace("Recipients: " . $recipient); + return false; + } elseif (!EmailSummary::getInstance()->resetData()) { + DUP_Log::Trace("FAILED TO RESET EMAIL SUMMARY DATA."); + return false; + } + + return true; + } + + /** + * Get mail content type + * + * @return string + */ + public static function getMailContentType() + { + return 'text/html'; + } + + /** + * Activation action + * + * @return void + */ + public static function activationAction() + { + $frequency = DUP_Settings::Get('email_summary_frequency'); + if ($frequency === EmailSummary::SEND_FREQ_NEVER) { + return; + } + + if (self::updateCron($frequency) == false) { + DUP_Log::Trace("FAILED TO INIT EMAIL SUMMARY CRON. Frequency: {$frequency}"); + } + } + + /** + * Deactivation action + * + * @return void + */ + public static function deactivationAction() + { + if (self::updateCron(EmailSummary::SEND_FREQ_NEVER) == false) { + DUP_Log::Trace("FAILED TO REMOVE EMAIL SUMMARY CRON."); + } + } + + /** + * Update next send time on frequency setting change + * + * @param string $oldFrequency The old frequency + * @param string $newFrequency The new frequency + * + * @return bool True if the cron was updated or false on error + */ + public static function updateFrequency($oldFrequency, $newFrequency) + { + if ($oldFrequency === $newFrequency) { + return true; + } + + return self::updateCron($newFrequency); + } + + /** + * Updates the WP Cron job base on frequency or settings + * + * @param string $frequency The frequency + * + * @return bool True if the cron was updated or false on error + */ + private static function updateCron($frequency = '') + { + if (strlen($frequency) === 0) { + $frequency = DUP_Settings::Get('email_summary_frequency'); + } + + if ($frequency === EmailSummary::SEND_FREQ_NEVER) { + if (wp_next_scheduled(self::CRON_HOOK)) { + //have to check return like this because + //wp_clear_scheduled_hook returns void in WP < 5.1 + return !self::isFalseOrWpError(wp_clear_scheduled_hook(self::CRON_HOOK)); + } else { + return true; + } + } else { + if ( + wp_next_scheduled(self::CRON_HOOK) + && self::isFalseOrWpError(wp_clear_scheduled_hook(self::CRON_HOOK)) + ) { + return false; + } + + return !self::isFalseOrWpError(wp_schedule_event( + self::getFirstRunTime($frequency), + self::getCronSchedule($frequency), + self::CRON_HOOK + )); + } + } + + /** + * Set next send time based on frequency + * + * @param string $frequency Frequency + * + * @return int + */ + private static function getFirstRunTime($frequency) + { + switch ($frequency) { + case EmailSummary::SEND_FREQ_DAILY: + $firstRunTime = strtotime('tomorrow 14:00'); + break; + case EmailSummary::SEND_FREQ_WEEKLY: + $firstRunTime = strtotime('next monday 14:00'); + break; + case EmailSummary::SEND_FREQ_MONTHLY: + $firstRunTime = strtotime('first day of next month 14:00'); + break; + case EmailSummary::SEND_FREQ_NEVER: + return 0; + default: + throw new \Exception("Unknown frequency: " . $frequency); + } + + return $firstRunTime - SnapWP::getGMTOffset(); + } + + /** + * Get the cron schedule + * + * @param string $frequency The frequency + * + * @return string + */ + private static function getCronSchedule($frequency) + { + switch ($frequency) { + case EmailSummary::SEND_FREQ_DAILY: + return CronUtils::INTERVAL_DAILTY; + case EmailSummary::SEND_FREQ_WEEKLY: + return CronUtils::INTERVAL_WEEKLY; + case EmailSummary::SEND_FREQ_MONTHLY: + return CronUtils::INTERVAL_MONTHLY; + default: + throw new Exception("Unknown frequency: " . $frequency); + } + } + + /** + * Returns true if is false or wp_error + * + * @param mixed $value The value + * + * @return bool + */ + private static function isFalseOrWpError($value) + { + return $value === false || is_wp_error($value); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/ExpireOptions.php b/html/wp-content/plugins/duplicator/src/Utils/ExpireOptions.php new file mode 100644 index 0000000..186b34c --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/ExpireOptions.php @@ -0,0 +1,164 @@ + */ + private static $cacheOptions = array(); + + + /** + * Sets/updates the value of a expire option. + * + * You do not need to serialize values. If the value needs to be serialized, + * then it will be serialized before it is set. + * + * @param string $key Expire option key. + * @param mixed $value Option value. + * @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration). + * + * @return bool True if the value was set, false otherwise. + */ + public static function set($key, $value, $expiration = 0) + { + $time = ($expiration > 0 ? time() + $expiration : 0); + + self::$cacheOptions[$key] = array( + 'expire' => $time, + 'value' => $value, + ); + + return update_option(self::OPTION_PREFIX . $key, JsonSerialize::serialize(self::$cacheOptions[$key]), true); + } + + /** + * Retrieves the value of a expire option. + * + * If the option does not exist, does not have a value, or has expired, + * then the return value will be false. + * + * @param string $key Expire option key. + * @param mixed $default Return this value if option don\'t exists os is expired + * + * @return mixed Value of transient. + */ + public static function get($key, $default = false) + { + if (!isset(self::$cacheOptions[$key])) { + if (($option = get_option(self::OPTION_PREFIX . $key)) == false) { + self::$cacheOptions[$key] = self::unexistsKeyValue(); + } else { + self::$cacheOptions[$key] = JsonSerialize::unserialize($option); + } + } + + if (self::$cacheOptions[$key]['expire'] < 0) { + // don't exists the wp-option + return $default; + } + + if (self::$cacheOptions[$key]['expire'] > 0 && self::$cacheOptions[$key]['expire'] < time()) { + // if 0 don't expire so check only if time is > 0 + self::delete($key); + return $default; + } + + return self::$cacheOptions[$key]['value']; + } + + /** + * This function returns the value of the option or false if it has expired. In case the option has expired then it is updated. + * It does the same thing as a get and a set but with one less query. + * + * @param string $key Expire option key. + * @param mixed $value Option value. + * @param int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration). + * + * @return mixed Value of transient. + */ + public static function getUpdate($key, $value, $expiration = 0) + { + if (!isset(self::$cacheOptions[$key])) { + if (($option = get_option(self::OPTION_PREFIX . $key)) == false) { + self::$cacheOptions[$key] = self::unexistsKeyValue(); + } else { + self::$cacheOptions[$key] = JsonSerialize::unserialize($option); + } + } + + if (self::$cacheOptions[$key]['expire'] < time()) { + self::set($key, $value, $expiration); + return false; + } + + return self::$cacheOptions[$key]['value']; + } + + /** + * Deletes a option + * + * @param string $key Expire option key. Expected to not be SQL-escaped. + * + * @return bool True if the option was deleted, false otherwise. + */ + public static function delete($key) + { + if (delete_option(self::OPTION_PREFIX . $key)) { + self::$cacheOptions[$key] = self::unexistsKeyValue(); + return true; + } else { + return false; + } + } + + /** + * Delete all options + * + * @return bool + */ + public static function deleteAll() + { + /** @var \wpdb $wpdb */ + global $wpdb; + + $optionsTableName = esc_sql($wpdb->base_prefix . "options"); + $query = $wpdb->prepare( + "SELECT `option_name` FROM `{$optionsTableName}` WHERE `option_name` REGEXP %s", + SnapDB::quoteRegex(self::OPTION_PREFIX) + ); + $dupOptionNames = $wpdb->get_col($query); + + foreach ($dupOptionNames as $dupOptionName) { + delete_option($dupOptionName); + } + self::$cacheOptions = array(); + + return true; + } + + /** + * Return value for unexists key option + * + * @return array{expire: int, value: false} + */ + private static function unexistsKeyValue() + { + return array( + 'expire' => -1, + 'value' => false, + ); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/CrossPromotion.php b/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/CrossPromotion.php new file mode 100644 index 0000000..a37e628 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/CrossPromotion.php @@ -0,0 +1,125 @@ + time()) { + return; + } + + if (!ControllersManager::isCurrentPage(ControllersManager::MAIN_MENU_SLUG)) { + return; + } + + $plugins = self::getExtraPlugins(); + if (count($plugins) === 0) { + return; + } + + AboutUsController::enqueueScripts(); + + Notice::add( + TplMng::getInstance()->render( + 'parts/cross_promotion/list', + [ + 'plugins' => $plugins, + 'limit' => self::PLUGINS_LIMIT, + ], + false + ), + self::NOTICE_SLUG, + '', + [ + 'autop' => false, + 'dismiss' => Notice::DISMISS_USER, + ] + ); + } + + /** + * Get the extra plugins to be promoted + * + * @return ExtraItem[] + */ + public static function getExtraPlugins() + { + $slugs = self::getSlugs(); + $plugins = []; + $extraPluginsMng = ExtraPluginsMng::getInstance(); + + foreach ($slugs as $slug) { + if (count($plugins) >= self::PLUGINS_LIMIT) { + break; + } + + if (($plugin = $extraPluginsMng->getBySlug($slug)) === false) { + continue; + } + + if ($plugin->isInstalled() || !$plugin->checkRequirments()) { + continue; + } + + $plugins[] = $plugin; + } + + foreach ($extraPluginsMng->getAll() as $plugin) { + if (count($plugins) >= self::PLUGINS_LIMIT) { + break; + } + + if (in_array($plugin->getSlug(), $slugs)) { + continue; + } + + if ($plugin->isInstalled() || !$plugin->checkRequirments()) { + continue; + } + + $plugins[] = $plugin; + } + + return $plugins; + } + + /** + * Get the slugs of the extra plugins to be promoted with priority + * + * @return string[] + */ + protected static function getSlugs() + { + return [ + 'search-replace-wpcode/wsrw.php', + 'wp-mail-smtp/wp_mail_smtp.php', + 'insert-headers-and-footers/ihaf.php', + 'all-in-one-seo-pack/all_in_one_seo_pack.php', + 'wpforms-lite/wpforms.php', + 'uncanny-automator/uncanny-automator.php', + ]; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/ExtraItem.php b/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/ExtraItem.php new file mode 100644 index 0000000..c06eee9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/ExtraItem.php @@ -0,0 +1,364 @@ + false, + 'added' => false, + 'author' => false, + 'author_block_count' => false, + 'author_block_rating' => false, + 'author_profile' => false, + 'banners' => false, + 'compatibility' => false, + 'contributors' => false, + 'description' => false, + 'donate_link' => false, + 'download_link' => false, + 'downloaded' => false, + 'group' => false, + 'homepage' => false, + 'icons' => false, + 'last_updated' => false, + 'name' => false, + 'num_ratings' => false, + 'rating' => false, + 'ratings' => false, + 'requires' => true, + 'requires_php' => true, + 'reviews' => false, + 'screenshots' => false, + 'sections' => false, + 'short_description' => false, + 'slug' => false, + 'support_threads' => false, + 'support_threads_resolved' => false, + 'tags' => false, + 'tested' => false, + 'version' => false, + 'versions' => false, + ]; + + /** + * plugin name + * + * @var string + */ + public $name = ''; + + /** + * plugin slug + * + * @var string + */ + protected $slug = ''; + + /** + * url to plugin icon + * + * @var string + */ + public $icon = ''; + + /** + * plugin description + * + * @var string + */ + public $desc = ''; + + /** + * plugin url either to zip file or pro version + * + * @var string + */ + public $url = ''; + + /** + * plugin url on wordpress.org if available + * + * @var bool|string + */ + public $wpOrgURL = ''; + + /** + * PRO version of plugin if available + * + * @var ExtraItem|null + */ + protected $pro = null; + + /** + * Class constructor + * + * @param string $name plugin name + * @param string $slug plugin slug + * @param string $icon url to plugin icon + * @param string $desc plugin description + * @param string $url plugin url + * @param string|bool $wpOrgURL plugin url on wordpress.org + */ + public function __construct($name, $slug, $icon, $desc, $url, $wpOrgURL = false) + { + $this->name = $name; + $this->slug = $slug; + $this->icon = $icon; + $this->desc = $desc; + $this->url = $url; + $this->wpOrgURL = $wpOrgURL; + } + + /** + * Returns plugin slug + * + * @return string + */ + public function getSlug() + { + return $this->slug; + } + + /** + * Is plugin active + * + * @return bool + */ + public function isActive() + { + return $this->isInstalled() && is_plugin_active($this->slug); + } + + /** + * Is plugin installed + * + * @return bool + */ + public function isInstalled() + { + static $installedSlugs = null; + if ($installedSlugs === null) { + if (!function_exists('get_plugins')) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + $installedSlugs = array_keys(get_plugins()); + } + return in_array($this->slug, $installedSlugs); + } + + /** + * Checks of the WP and PHP version requirments pass + * + * @return bool True if checks pass, false otherwise + */ + public function checkRequirments() + { + global $wp_version; + + if (($reqs = $this->getRequirments()) === false) { + return false; + } + + return version_compare($wp_version, $reqs['wp_version'], '>=') && + version_compare(PHP_VERSION, $reqs['php_version'], '>='); + } + + /** + * Gets the requirments either from the cache (wp_options) or from the remote + * API and updates the cache. + * + * @return array{last_updated:int,wp_version:string,php_version:string}|false The data or false of failure + */ + private function getRequirments() + { + if (($data = ExpireOptions::get($this->getApiSlug())) === false) { + if (($data = $this->getRemoteRequirments()) !== false) { + ExpireOptions::set($this->getApiSlug(), $data, 2 * WEEK_IN_SECONDS); + } else { + return false; + } + } + + return $data; + } + + /** + * Returns the slug that should be used with the API calls + * + * @return string + */ + private function getApiSlug() + { + return dirname($this->getSlug()); + } + + /** + * Retrieves the PHP and WP version requirments of a plugin from the WP API. + * + * @return array{wp_version:string,php_version:string}|false The data or false on failure + */ + private function getRemoteRequirments() + { + if (!function_exists('plugins_api')) { + require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; + } + + $response = plugins_api('plugin_information', [ + 'slug' => $this->getApiSlug(), + 'fields' => self::PLUGIN_API_FIELDS + ]); + + if (is_wp_error($response)) { + return false; + } + + return [ + 'wp_version' => $response->requires, + 'php_version' => $response->requires_php + ]; + } + + /** + * Returns pro version of plugin if available + * + * @return ExtraItem|null + */ + public function getPro() + { + return $this->pro; + } + + /** + * Set pro plugin + * + * @param string $name plugin name + * @param string $slug plugin slug + * @param string $icon url to plugin icon + * @param string $desc plugin description + * @param string $url plugin url + * @param string|bool $wpOrgURL plugin url on wordpress.org + * + * @return void + */ + public function setPro($name, $slug, $icon, $desc, $url, $wpOrgURL = false) + { + $this->pro = new self($name, $slug, $icon, $desc, $url, $wpOrgURL); + } + + /** + * Whether to skip lite version of plugin because it is installed and pro version is available + * + * @return bool + */ + public function skipLite() + { + return $this->pro !== null && $this->isActive(); + } + + /** + * Enum of status constants (STATUS_ACTIVE, STATUS_INSTALLED, STATUS_UNINSALED) + * + * @return int return status constant + */ + public function getStatus() + { + if ($this->isActive()) { + return self::STATUS_ACTIVE; + } elseif ($this->isInstalled()) { + return self::STATUS_INSTALLED; + } else { + return self::STATUS_NOT_INSTALLED; + } + } + + /** + * Status text + * + * @return string + */ + public function getStatusText() + { + switch ($this->getStatus()) { + case self::STATUS_ACTIVE: + return __('Active', 'duplicator'); + case self::STATUS_INSTALLED: + return __('Inactive', 'duplicator'); + case self::STATUS_NOT_INSTALLED: + return __('Not Installed', 'duplicator'); + } + } + + /** + * Enum of URL constants (URL_TYPE_GENERIC, URL_TYPE_ZIP) + * + * @return int + */ + public function getURLType() + { + if (SnapString::endsWith($this->url, '.zip')) { + return self::URL_TYPE_ZIP; + } else { + return self::URL_TYPE_GENERIC; + } + } + + /** + * Install this plugin + * + * @return bool true on success + */ + public function install() + { + if ($this->isInstalled()) { + return true; + } + + if (!SnapString::endsWith($this->url, '.zip')) { + throw new \Exception('Invalid plugin url for installation'); + } + + if (!current_user_can('install_plugins')) { + throw new \Exception('User does not have permission to install plugins'); + } + + if (!class_exists('Plugin_Upgrader')) { + require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; + } + wp_cache_flush(); + + $upgrader = new \Plugin_Upgrader(new \Automatic_Upgrader_Skin()); + if (!$upgrader->install($this->url)) { + throw new \Exception('Failed to install plugin'); + } + + return true; + } + + /** + * Activate this plugin + * + * @return bool true on success + */ + public function activate() + { + if ($this->isActive()) { + return true; + } + + if (!is_null(activate_plugin($this->slug))) { + throw new \Exception('Failed to activate plugin'); + } + + return true; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/ExtraPluginsMng.php b/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/ExtraPluginsMng.php new file mode 100644 index 0000000..0d5e6fc --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/ExtraPlugins/ExtraPluginsMng.php @@ -0,0 +1,549 @@ + key slug item */ + protected $plugins = array(); + + /** + * + * @return self + */ + public static function getInstance() + { + if (is_null(self::$instance)) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Singleton constructor + */ + protected function __construct() + { + $this->plugins = self::getInitList(); + } + + /** + * Execute callback for each plugin + * + * @param callable $callback callback function + * + * @return void + */ + public function foreachCallback($callback) + { + if (!is_callable($callback)) { + return; + } + + foreach ($this->plugins as $plugin) { + call_user_func($callback, $plugin); + } + } + + /** + * Get all plugins + * + * @return ExtraItem[] All plugin items + */ + public function getAll() + { + return $this->plugins; + } + + /** + * Returns plugin by slug + * + * @param string $slug plugin slug + * + * @return false|ExtraItem plugin item or false if not found + */ + public function getBySlug($slug) + { + if (strlen($slug) === 0) { + return false; + } + + if (!isset($this->plugins[$slug])) { + return false; + } + + return (isset($this->plugins[$slug]) ? $this->plugins[$slug] : false); + } + + /** + * Install plugin slug + * + * @param string $slug plugin slug + * @param string $message message + * + * @return bool true if plugin installed and activated or false on failure + */ + public function install($slug, &$message = '') + { + if (strlen($slug) === 0) { + $message = __('Plugin slug is empty', 'duplicator'); + return false; + } + + if (($plugin = $this->getBySlug($slug)) == false) { + $message = __('Plugin not found', 'duplicator'); + return false; + } + + $result = true; + ob_start(); + if ($plugin->install() == false) { + $result = false; + } elseif ($plugin->activate() == false) { + $result = false; + } + $message = ob_get_clean(); + return $result; + } + + /** + * Init addon plugins + * + * @return void + */ + private static function getInitList() + { + $result = array(); + + $item = new ExtraItem( + __('OptinMonster', 'duplicator'), + 'optinmonster/optin-monster-wp-api.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-om.png', + __('Instantly get more subscribers, leads, and sales with the #1 conversion optimization toolkit. Create ' . + 'high converting popups, announcement bars, spin a wheel, and more with smart targeting and personalization.', 'duplicator'), + 'https://downloads.wordpress.org/plugin/optinmonster.zip', + 'https://wordpress.org/plugins/optinmonster/' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('MonsterInsights', 'duplicator'), + 'google-analytics-for-wordpress/googleanalytics.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-mi.png', + __( + 'The leading WordPress analytics plugin that shows you how people find and use your website, so you can ' . + 'make data driven decisions to grow your business. Properly set up Google Analytics without writing code.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/google-analytics-for-wordpress.zip', + 'https://wordpress.org/plugins/google-analytics-for-wordpress/' + ); + $item->setPro( + __('MonsterInsights Pro', 'duplicator'), + 'google-analytics-premium/googleanalytics-premium.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-mi.png', + __( + 'The leading WordPress analytics plugin that shows you how people find and use your website, so you ' . + 'can make data driven decisions to grow your business. Properly set up Google Analytics without writing code.', + 'duplicator' + ), + 'https://www.monsterinsights.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('WPForms', 'duplicator'), + 'wpforms-lite/wpforms.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-wpforms.png', + __( + 'The best drag & drop WordPress form builder. Easily create beautiful contact forms, surveys, payment ' . + 'forms, and more with our 100+ form templates. Trusted by over 4 million websites as the best forms plugin.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/wpforms-lite.zip', + 'https://wordpress.org/plugins/wpforms-lite/' + ); + $item->setPro( + __('WPForms Pro', 'duplicator'), + 'wpforms/wpforms.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-wpforms.png', + __( + 'The easiest drag & drop WordPress form builder plugin to create beautiful contact forms, subscription ' . + 'forms, payment forms, and more in minutes. No coding skills required.', + 'duplicator' + ), + 'https://wpforms.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('WP Mail SMTP', 'duplicator'), + 'wp-mail-smtp/wp_mail_smtp.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-smtp.png', + __( + 'Improve your WordPress email deliverability and make sure that your website emails reach user\'s inbox ' . + 'with the #1 SMTP plugin for WordPress. Over 3 million websites use it to fix WordPress email issues.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/wp-mail-smtp.zip', + 'https://wordpress.org/plugins/wp-mail-smtp/' + ); + $item->setPro( + __('WP Mail SMTP Pro', 'duplicator'), + 'wp-mail-smtp-pro/wp_mail_smtp.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-smtp.png', + __( + 'Improve your WordPress email deliverability and make sure that your website emails reach user\'s inbox ' . + 'with the #1 SMTP plugin for WordPress. Over 3 million websites use it to fix WordPress email issues.', + 'duplicator' + ), + 'https://wpmailsmtp.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('AIOSEO', 'duplicator'), + 'all-in-one-seo-pack/all_in_one_seo_pack.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-aioseo.png', + __( + 'The original WordPress SEO plugin and toolkit that improves your website\'s search rankings. Comes with ' . + 'all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/all-in-one-seo-pack.zip', + 'https://wordpress.org/plugins/all-in-one-seo-pack/' + ); + $item->setPro( + __('AIOSEO Pro', 'duplicator'), + 'all-in-one-seo-pack-pro/all_in_one_seo_pack.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-aioseo.png', + __( + 'The original WordPress SEO plugin and toolkit that improves your website\'s search rankings. Comes ' . + 'with all the SEO features like Local SEO, WooCommerce SEO, sitemaps, SEO optimizer, schema, and more.', + 'duplicator' + ), + 'https://aioseo.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('SeedProd', 'duplicator'), + 'coming-soon/coming-soon.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-seedprod.png', + __('The best WordPress coming soon page plugin to create a beautiful coming soon page, maintenance mode page, ' . + 'or landing page. No coding skills required.', 'duplicator'), + 'https://downloads.wordpress.org/plugin/coming-soon.zip', + 'https://wordpress.org/plugins/coming-soon/' + ); + $item->setPro( + __('SeedProd Pro', 'duplicator'), + 'seedprod-coming-soon-pro-5/seedprod-coming-soon-pro-5.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-seedprod.png', + __('The best WordPress coming soon page plugin to create a beautiful coming soon page, maintenance mode ' . + 'page, or landing page. No coding skills required.', 'duplicator'), + 'https://www.seedprod.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('RafflePress', 'duplicator'), + 'rafflepress/rafflepress.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-rp.png', + __( + 'Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and social ' . + 'media followers with the most powerful giveaways & contests plugin for WordPress.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/rafflepress.zip', + 'https://wordpress.org/plugins/rafflepress/' + ); + $item->setPro( + __('RafflePress Pro', 'duplicator'), + 'rafflepress-pro/rafflepress-pro.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-rp.png', + __( + 'Turn your website visitors into brand ambassadors! Easily grow your email list, website traffic, and ' . + 'social media followers with the most powerful giveaways & contests plugin for WordPress.', + 'duplicator' + ), + 'https://rafflepress.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('PushEngage', 'duplicator'), + 'pushengage/main.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-pushengage.png', + __( + 'Connect with your visitors after they leave your website with the leading web push notification software. ' . + 'Over 10,000+ businesses worldwide use PushEngage to send 9 billion notifications each month.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/pushengage.zip', + 'https://wordpress.org/plugins/pushengage/' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Smash Balloon Instagram Feeds', 'duplicator'), + 'instagram-feed/instagram-feed.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-instagram.png', + __( + 'Easily display Instagram content on your WordPress site without writing any code. Comes with multiple templates, ' . + 'ability to show content from multiple accounts, hashtags, and more. Trusted by 1 million websites.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/instagram-feed.zip', + 'https://wordpress.org/plugins/instagram-feed/' + ); + $item->setPro( + __('Smash Balloon Instagram Feeds Pro', 'duplicator'), + 'instagram-feed-pro/instagram-feed.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-instagram.png', + __( + 'Easily display Instagram content on your WordPress site without writing any code. Comes with multiple ' . + 'templates, ability to show content from multiple accounts, hashtags, and more. Trusted by 1 million websites.', + 'duplicator' + ), + 'https://smashballoon.com/instagram-feed/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Smash Balloon Facebook Feeds', 'duplicator'), + 'custom-facebook-feed/custom-facebook-feed.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-fb.png', + __( + 'Easily display Facebook content on your WordPress site without writing any code. Comes with multiple templates, ' . + 'ability to embed albums, group content, reviews, live videos, comments, and reactions.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/custom-facebook-feed.zip', + 'https://wordpress.org/plugins/custom-facebook-feed/' + ); + $item->setPro( + __('Smash Balloon Facebook Feeds Pro', 'duplicator'), + 'custom-facebook-feed-pro/custom-facebook-feed.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-fb.png', + __( + 'Easily display Facebook content on your WordPress site without writing any code. Comes with multiple templates, ' . + 'ability to embed albums, group content, reviews, live videos, comments, and reactions.', + 'duplicator' + ), + 'https://smashballoon.com/custom-facebook-feed/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Smash Balloon Twitter Feeds', 'duplicator'), + 'custom-twitter-feeds/custom-twitter-feed.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-twitter.png', + __( + 'Easily display Twitter content in WordPress without writing any code. Comes with multiple layouts, ability ' . + 'to combine multiple Twitter feeds, Twitter card support, tweet moderation, and more.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/custom-twitter-feeds.zip', + 'https://wordpress.org/plugins/custom-twitter-feeds/' + ); + $item->setPro( + __('Smash Balloon Twitter Feeds Pro', 'duplicator'), + 'custom-twitter-feeds-pro/custom-twitter-feeds.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-twitter.png', + __( + 'Easily display Twitter content in WordPress without writing any code. Comes with multiple layouts, ' . + 'ability to combine multiple Twitter feeds, Twitter card support, tweet moderation, and more.', + 'duplicator' + ), + 'https://smashballoon.com/custom-twitter-feeds/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Smash Balloon YouTube Feeds', 'duplicator'), + 'feeds-for-youtube/youtube-feed.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-youtube.png', + __( + 'Easily display YouTube videos on your WordPress site without writing any code. Comes with multiple layouts, ' . + 'ability to embed live streams, video filtering, ability to combine multiple channel videos, and more.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/feeds-for-youtube.zip', + 'https://wordpress.org/plugins/feeds-for-youtube/' + ); + $item->setPro( + __('Smash Balloon YouTube Feeds Pro', 'duplicator'), + 'youtube-feed-pro/youtube-feed.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sb-youtube.png', + __( + 'Easily display YouTube videos on your WordPress site without writing any code. Comes with multiple ' . + 'layouts, ability to embed live streams, video filtering, ability to combine multiple channel videos, and more.', + 'duplicator' + ), + 'https://smashballoon.com/youtube-feed/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('TrustPulse', 'duplicator'), + 'trustpulse-api/trustpulse.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-trustpulse.png', + __( + 'Boost your sales and conversions by up to 15% with real-time social proof notifications. TrustPulse helps ' . + 'you show live user activity and purchases to help convince other users to purchase.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/trustpulse-api.zip', + 'https://wordpress.org/plugins/trustpulse-api/' + ); + + $result[$item->getSlug()] = $item; + + + $item = new ExtraItem( + __('SearchWP', 'duplicator'), + 'searchwp/index.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-searchwp.png', + __( + 'The most advanced WordPress search plugin. Customize your WordPress search algorithm, reorder search results, ' . + 'track search metrics, and everything you need to leverage search to grow your business.', + 'duplicator' + ), + 'https://searchwp.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('AffiliateWP', 'duplicator'), + 'affiliate-wp/affiliate-wp.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-affwp.png', + __( + 'The #1 affiliate management plugin for WordPress. Easily create an affiliate program for your eCommerce ' . + 'store or membership site within minutes and start growing your sales with the power of referral marketing.', + 'duplicator' + ), + 'https://affiliatewp.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator', + false + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('WP Simple Pay', 'duplicator'), + 'stripe/stripe-checkout.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-wp-simple-pay.png', + __( + 'The #1 Stripe payments plugin for WordPress. Start accepting one-time and recurring payments on your ' . + 'WordPress site without setting up a shopping cart. No code required.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/stripe.zip', + 'https://wordpress.org/plugins/stripe/' + ); + $item->setPro( + __('WP Simple Pay Pro', 'duplicator'), + 'wp-simple-pay-pro-3/simple-pay.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-wp-simple-pay.png', + __( + 'The #1 Stripe payments plugin for WordPress. Start accepting one-time and recurring payments on your ' . + 'WordPress site without setting up a shopping cart. No code required.', + 'duplicator' + ), + 'https://wpsimplepay.com/lite-upgrade/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Easy Digital Downloads', 'duplicator'), + 'easy-digital-downloads/easy-digital-downloads.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-edd.png', + __('The best WordPress eCommerce plugin for selling digital downloads. Start selling eBooks, software, music, ' . + 'digital art, and more within minutes. Accept payments, manage subscriptions, advanced access control, and more.', 'duplicator'), + 'https://downloads.wordpress.org/plugin/easy-digital-downloads.zip', + 'https://wordpress.org/plugins/easy-digital-downloads/' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Sugar Calendar', 'duplicator'), + 'sugar-calendar-lite/sugar-calendar-lite.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sugarcalendar.png', + __('A simple & powerful event calendar plugin for WordPress that comes with all the event management features ' . + 'including payments, scheduling, timezones, ticketing, recurring events, and more.', 'duplicator'), + 'https://downloads.wordpress.org/plugin/sugar-calendar-lite.zip', + 'https://wordpress.org/plugins/sugar-calendar-lite/' + ); + $item->setPro( + __('Sugar Calendar Pro', 'duplicator'), + 'sugar-calendar/sugar-calendar.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-sugarcalendar.png', + __('A simple & powerful event calendar plugin for WordPress that comes with all the event management features ' . + 'including payments, scheduling, timezones, ticketing, recurring events, and more.', 'duplicator'), + 'https://sugarcalendar.com/?utm_source=duplicatorplugin&utm_medium=link&utm_campaign=About%20Duplicator' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('WPCode', 'duplicator'), + 'insert-headers-and-footers/ihaf.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-wpcode.png', + __('Future proof your WordPress customizations with the most popular code snippet management plugin for WordPress. ' . + 'Trusted by over 1,500,000+ websites for easily adding code to WordPress right from the admin area.', 'duplicator'), + 'https://downloads.wordpress.org/plugin/insert-headers-and-footers.zip', + 'https://wordpress.org/plugins/insert-headers-and-footers/' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Search & Replace Everything', 'duplicator'), + 'search-replace-wpcode/wsrw.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-search-and-replace.png', + __('Efficiently manage your website’s content directly from the WordPress admin with Search & Replace Everything by WPCode. ' . + 'This tool is essential for site migrations, content updates, or any situation where batch text and image replacements are needed.', 'duplicator'), + 'https://downloads.wordpress.org/plugin/search-replace-wpcode.zip', + 'https://wordpress.org/plugins/search-replace-wpcode/' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Uncanny Automator', 'duplicator'), + 'uncanny-automator/uncanny-automator.php', + DUPLICATOR_PLUGIN_URL . 'assets/img/about/plugin-uncanny-automator.png', + __('Uncanny Automator is the easiest and most powerful way to automate your WordPress site with no code. ' . + 'Build automations in minutes that connect your WordPress plugins, sites and apps together using billions of recipe combinations.', 'duplicator'), + 'https://downloads.wordpress.org/plugin/uncanny-automator.zip', + 'https://wordpress.org/plugins/uncanny-automator/' + ); + + $result[$item->getSlug()] = $item; + + $item = new ExtraItem( + __('Database Reset Pro', 'duplicator'), + 'db-reset-pro/db-reset-pro.php', + DUPLICATOR_PLUGIN_URL . 'assets/css/images/db-reset-icon.png', + __( + 'Database Reset Pro is the safest and simplest way to reset your WordPress database to its default state. + Unlike reinstalling WordPress, this database reset plugin preserves your files, uploads, + and admin credentials while giving you a fresh start in seconds.', + 'duplicator' + ), + 'https://downloads.wordpress.org/plugin/db-reset-pro.zip', + 'https://wordpress.org/plugins/db-reset-pro/' + ); + + $result[$item->getSlug()] = $item; + + return $result; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/Help/Article.php b/html/wp-content/plugins/duplicator/src/Utils/Help/Article.php new file mode 100644 index 0000000..64833b8 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/Help/Article.php @@ -0,0 +1,89 @@ +id = $id; + $this->title = $title; + $this->link = $link; + $this->categories = $categories; + $this->tags = $tags; + } + + /** + * Get the Title + * + * @return string + */ + public function getTitle() + { + return $this->title; + } + + /** + * Get the Link + * + * @return string + */ + public function getLink() + { + return $this->link; + } + + /** + * Get the Categories + * + * @return int[] + */ + public function getCategories() + { + return $this->categories; + } + + /** + * Get the Tags + * + * @return string[] + */ + public function getTags() + { + return $this->tags; + } + + /** + * Get the ID + * + * @return int + */ + public function getId() + { + return $this->id; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/Help/Category.php b/html/wp-content/plugins/duplicator/src/Utils/Help/Category.php new file mode 100644 index 0000000..e6b8d69 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/Help/Category.php @@ -0,0 +1,114 @@ +id = $id; + $this->name = $name; + $this->articleCount = $articleCount; + } + + /** + * Get the ID + * + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Get the Name + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Get the Article Count + * + * @return int + */ + public function getArticleCount() + { + return $this->articleCount; + } + + /** + * Get the Children + * + * @return Category[] + */ + public function getChildren() + { + return $this->children; + } + + /** + * Add a child + * + * @param Category $child The child + * + * @return void + */ + public function addChild(Category $child) + { + if (isset($this->children[$child->getId()])) { + return; + } + + $this->children[$child->getId()] = $child; + } + + /** + * Get the Parent + * + * @return Category|null + */ + public function getParent() + { + return $this->parent; + } + + /** + * Set the Parent + * + * @param Category $parent The parent + * + * @return void + */ + public function setParent(Category $parent) + { + $this->parent = $parent; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/Help/Help.php b/html/wp-content/plugins/duplicator/src/Utils/Help/Help.php new file mode 100644 index 0000000..921eded --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/Help/Help.php @@ -0,0 +1,413 @@ + The tags ID => slug */ + private $tags = []; + + /** @var self The instance */ + private static $instance = null; + + /** + * Init + * + * @return void + */ + private function __construct() + { + // Update data from API if cache is expired or does not exist + if ( + !ExpireOptions::getUpdate(self::DOCS_EXPIRE_OPT_KEY, true, WEEK_IN_SECONDS) || + !$this->loadData() + ) { + $this->updateData(); + } + } + + /** + * Get the instance + * + * @return self The instance + */ + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Get the help page URL with tag + * + * @return string The URL with tag + */ + public static function getHelpPageUrl() + { + return HelpPageController::getHelpLink() . '&tag=' . self::getCurrentPageTag(); + } + + /** + * Get articles by category + * + * @param int $categoryId The category ID + * + * @return Article[] The articles + */ + public function getArticlesByCategory($categoryId) + { + return array_filter($this->articles, function (Article $article) use ($categoryId) { + return in_array($categoryId, $article->getCategories()); + }); + } + + /** + * Get articles by tag + * + * @param string $tag The tag + * + * @return Article[] The articles + */ + public function getArticlesByTag($tag) + { + if ($tag === '') { + return []; + } + + return array_filter($this->articles, function (Article $article) use ($tag) { + return in_array($tag, $article->getTags()); + }); + } + + /** + * Get top level categories. + * E.g. categories without parents & with children or articles + * + * @return Category[] The categories + */ + public function getTopLevelCategories() + { + return array_filter($this->categories, function (Category $category) { + return $category->getParent() === null && (count($category->getChildren()) > 0 || $category->getArticleCount() > 0); + }); + } + + /** + * Load data from API + * + * @return array{articles: mixed[], categories: mixed[], tags: mixed[]}|array The data + */ + private function getDataFromApi() + { + $categories = $this->fetchDataFromEndpoint( + self::CATEGORY_ENDPOINT, + self::MAX_CATEGORY, + [ + 'id', + 'name', + 'count', + 'parent', + ] + ); + + $articles = $this->fetchDataFromEndpoint( + self::ARTICLE_ENDPOINT, + self::MAX_ARTICLES, + [ + 'id', + 'title', + 'link', + 'ht-kb-category', + 'ht-kb-tag', + ] + ); + + $tags = $this->fetchDataFromEndpoint( + self::TAGS_ENDPOINT, + self::MAX_TAGS, + [ + 'id', + 'slug', + ] + ); + + if ($categories === [] || $articles === [] || $tags === []) { + DUP_Log::Trace('Failed to load from API. No data.'); + return []; + } + + return [ + 'articles' => $articles, + 'categories' => $categories, + 'tags' => $tags, + ]; + } + + /** + * Load from API + * + * @param string $endpoint The endpoint + * @param int $limit Maximum number of items to load + * @param string[] $fields The fields to load + * + * @return array The data + */ + private function fetchDataFromEndpoint($endpoint, $limit, $fields = []) + { + $result = []; + $endpointUrl = $endpoint . '?per_page=' . self::PER_PAGE; + if (count($fields) > 0) { + $endpointUrl .= '&_fields[]=' . implode('&_fields[]=', $fields); + } + + $maxPages = ceil($limit / self::PER_PAGE); + for ($i = 1; $i <= $maxPages; $i++) { + $endpointUrl .= '&page=' . $i; + $response = wp_remote_get( + $endpointUrl, + ['timeout' => 15] + ); + if (is_wp_error($response)) { + DUP_Log::Trace("Failed to load from API: {$endpointUrl}"); + DUP_Log::Trace($response->get_error_message()); + return []; + } + + $code = wp_remote_retrieve_response_code($response); + if ($code !== 200) { + DUP_Log::Trace("Failed to load from API: {$endpointUrl}, code: {$code}"); + return []; + } + + $body = wp_remote_retrieve_body($response); + if (($data = json_decode($body, true)) === null) { + DUP_Log::Trace("Failed to decode response: {$body}"); + return []; + } + + $result = array_merge($result, $data); + $totalPages = wp_remote_retrieve_header($response, 'x-wp-totalpages'); + if ($totalPages === '' || $i >= (int) $totalPages) { + break; + } + } + + $result = array_combine(array_column($result, 'id'), $result); + return $result; + } + + /** + * Get the current page tag + * + * @return string The tag + */ + private static function getCurrentPageTag() + { + if (!isset($_GET['page'])) { + return ''; + } + + $page = $_GET['page']; + $tab = isset($_GET['tab']) ? $_GET['tab'] : ''; + $innerPage = isset($_GET['inner_page']) ? $_GET['inner_page'] : ''; + + switch ($page) { + case ControllersManager::PACKAGES_SUBMENU_SLUG: + if ($innerPage === 'new1') { + return 'backup_step_1'; + } elseif ($tab === 'new2') { + return 'backup_step_2'; + } elseif ($tab === 'new3') { + return 'backup_step_3'; + } + + return 'backups'; + case ControllersManager::IMPORT_SUBMENU_SLUG: + return 'import'; + case ControllersManager::SCHEDULES_SUBMENU_SLUG: + return 'schedules'; + case ControllersManager::STORAGE_SUBMENU_SLUG: + return 'storages'; + case ControllersManager::TOOLS_SUBMENU_SLUG: + if ($tab === 'templates') { + return 'templates'; + } elseif ($tab === 'recovery') { + return 'recovery'; + } + + return 'tools'; + case ControllersManager::SETTINGS_SUBMENU_SLUG: + return 'settings'; + default: + DUP_Log::Trace("No tag for page."); + } + + return ''; + } + + /** + * Get the cache path + * + * @return string The cache path + */ + private static function getCacheFilePath() + { + $installInfo = DUP_LITE_Plugin_Upgrade::getInstallInfo(); + return DUP_Settings::getSsdirPath() . '/cache_' . md5($installInfo['time']) . '/duplicator_help_cache.json'; + } + + /** + * Set from cache data + * + * @param array{articles: mixed[], categories: mixed[], tags: mixed[]} $data The data + * + * @return bool True if set + */ + private function setFromArray($data) + { + if (!isset($data['articles']) || !isset($data['categories']) || !isset($data['tags'])) { + DUP_Log::Trace("Invalid data."); + return false; + } + + foreach ($data['tags'] as $tag) { + $this->tags[$tag['id']] = $tag['slug']; + } + + foreach ($data['categories'] as $category) { + $this->categories[$category['id']] = new Category( + $category['id'], + $category['name'], + $category['count'] + ); + } + + foreach ($this->categories as $category) { + if ( + ($parentId = $data['categories'][$category->getId()]['parent']) === 0 || + !isset($this->categories[$parentId]) + ) { + continue; + } + + $this->categories[$parentId]->addChild($category); + $category->setParent($this->categories[$parentId]); + } + + foreach ($data['articles'] as $article) { + $this->articles[$article['id']] = new Article( + $article['id'], + $article['title']['rendered'], + $article['link'], + $article['ht-kb-category'], + array_map(function ($tagId) { + return $this->tags[$tagId]; + }, $article['ht-kb-tag']) + ); + } + + return true; + } + + /** + * Get data from cache + * + * @return bool True if loaded + */ + private function loadData() + { + if (!file_exists(self::getCacheFilePath())) { + DUP_Log::Trace("Cache file does not exist: " . self::getCacheFilePath()); + return false; + } + + if (($contents = file_get_contents(self::getCacheFilePath())) === false) { + DUP_Log::Trace("Failed to read cache file: " . self::getCacheFilePath()); + return false; + } + + if (($data = json_decode($contents, true)) === null) { + DUP_Log::Trace("Failed to decode cache file: " . self::getCacheFilePath()); + return false; + } + + return $this->setFromArray($data); + } + + /** + * Save to cache + * + * @return bool True if saved + */ + public function updateData() + { + if (($data = $this->getDataFromApi()) === []) { + DUP_Log::Trace("Failed to load data from API."); + return false; + } + + $cachePath = self::getCacheFilePath(); + $cacheDir = dirname($cachePath); + if (!file_exists($cacheDir) && !SnapIO::mkdir($cacheDir, 0755, true)) { + DUP_Log::Trace("Failed to create cache directory: {$cacheDir}"); + return false; + } + + if (($encoded = SnapJson::jsonEncode($data)) === false) { + DUP_Log::Trace("Failed to encode cache data."); + return false; + } + + if (file_put_contents(self::getCacheFilePath(), $encoded) === false) { + DUP_Log::Trace("Failed to write cache file: {$cachePath}"); + return false; + } + + return $this->setFromArray($data); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/LinkManager.php b/html/wp-content/plugins/duplicator/src/Utils/LinkManager.php new file mode 100644 index 0000000..924338b --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/LinkManager.php @@ -0,0 +1,27 @@ + 'duplicator_download_support_toolkit', + 'nonce' => wp_create_nonce('duplicator_download_support_toolkit'), + ]); + } + + /** + * Generates a support toolkit zip file + * + * @return string The path to the generated zip file + */ + public static function getToolkit() + { + $tempZipFilePath = DUP_Settings::getSsdirTmpPath() . '/' . + self::SUPPORT_TOOLKIT_PREFIX . date('YmdHis') . '_' . + SnapUtil::generatePassword(16, false, false) . '.zip'; + $zip = new ZipArchiveExtended($tempZipFilePath); + + if ($zip->open() === false) { + throw new Exception(__('Failed to create zip file', 'duplicator')); + } + + // Trace log + if (DUP_Settings::Get('trace_log_enabled')) { + $zip->addFile(DUP_Log::getTraceFilepath()); + } + + // Debug log (if it exists) + if (WP_DEBUG_LOG !== false) { + if (is_bool(WP_DEBUG_LOG) && WP_DEBUG_LOG === true) { + $zip->addFile( + trailingslashit(wp_normalize_path(realpath(WP_CONTENT_DIR))) . 'debug.log', + '', + 10 * MB_IN_BYTES + ); + } elseif (is_string(WP_DEBUG_LOG) && strlen(WP_DEBUG_LOG) > 0) { + //The path can be relative too so resolve via safepath + $zip->addFile( + SnapIO::safePath(WP_DEBUG_LOG, true), + '', + 10 * MB_IN_BYTES + ); + } + } + + //phpinfo (as html) + $zip->addFileFromString('phpinfo.html', self::getPhpInfo()); + + //custom server settings info (as html) + $zip->addFileFromString('serverinfo.txt', self::getPlainServerSettings()); + + //Last 10 backup build logs + DUP_Package::by_status_callback( + function (DUP_Package $package) use ($zip) { + $file_path = DUP_Settings::getSsdirLogsPath() . "/" . $package->getLogFilename(); + $zip->addFile($file_path); + }, + [], + self::SUPPORT_TOOLKIT_BACKUP_NUMBER, + 0, + '`id` DESC' + ); + + return $tempZipFilePath; + } + + /** + * Returns the contents of the "Server Settings" section in "Tools" > "General" in plain text format + * + * @return string + */ + private static function getPlainServerSettings() + { + $result = ''; + + foreach (DUP_Server::getServerSettingsData() as $section) { + $result .= $section['title'] . "\n"; + $result .= str_repeat('=', 50) . "\n"; + foreach ($section['settings'] as $data) { + $result .= str_pad($data['logLabel'], 20, ' ', STR_PAD_RIGHT) . ' ' . $data['value'] . "\n"; + } + $result .= "\n\n"; + } + + return $result; + } + + /** + * Returns the output of phpinfo as a string + * + * @return string + */ + private static function getPhpInfo() + { + ob_start(); + SnapUtil::phpinfo(); + $phpInfo = ob_get_clean(); + + return $phpInfo === false ? '' : $phpInfo; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/Upsell.php b/html/wp-content/plugins/duplicator/src/Utils/Upsell.php new file mode 100644 index 0000000..ee01cf4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/Upsell.php @@ -0,0 +1,69 @@ +getDataToSend(); + + if (self::request(self::END_POINT_PLUGIN_STATS, $data)) { + PluginData::getInstance()->updateLastSendTime(); + return true; + } else { + return false; + } + } + + /** + * Disabled usage tracking + * + * @return bool true if data was sent successfully, false otherwise + */ + public static function disableUsageTracking() + { + if (DUPLICATOR_USTATS_DISALLOW) { // @phpstan-ignore-line + // Don't use StatsBootstrap::isTrackingAllowed beacause on disalbe usage tracking i necessary disable the tracking on server + return false; + } + + // Remove usage tracking data on server + $data = PluginData::getInstance()->getDisableDataToSend(); + return self::request(self::END_POINT_DISABLE, $data, 'Disable usage tracking error'); + } + + /** + * Sent installer statistics + * + * @return bool true if data was sent successfully, false otherwise + */ + public static function installerSend() + { + if (!StatsBootstrap::isTrackingAllowed()) { + return false; + } + + $data = InstallerData::getInstance()->getDataToSend(); + return self::request(self::END_POINT_INSTALLER, $data, 'Installer usage tracking error'); + } + + /** + * Request to usage tracking server + * + * @param string $endPoint end point + * @param array $data data to send + * @param string $traceMessagePerefix trace message prefix + * + * @return bool true if data was sent successfully, false otherwise + */ + protected static function request($endPoint, $data, $traceMessagePerefix = 'Error sending usage tracking') + { + try { + global $wp_version; + + $agent_string = "WordPress/" . $wp_version; + $postParams = array( + 'method' => 'POST', + 'timeout' => 10, + 'redirection' => 5, + 'sslverify' => false, + 'httpversion' => '1.1', + //'blocking' => false, + 'user-agent' => $agent_string, + 'body' => $data, + ); + + $url = self::getRemoteHost() . $endPoint . '/'; + $response = wp_remote_post($url, $postParams); + + if (is_wp_error($response)) { + /** @var WP_Error $response */ + DUP_Log::trace('URL Request: ' . $url); + DUP_Log::trace($traceMessagePerefix . ' code: ' . $response->get_error_code()); + DUP_Log::trace('Error message: ' . $response->get_error_message()); + return false; + } elseif ($response['response']['code'] < 200 || $response['response']['code'] >= 300) { + DUP_Log::trace('URL Request: ' . $url); + DUP_Log::trace($traceMessagePerefix . ' code: ' . $response['response']['code']); + DUP_Log::trace('Error message: ' . $response['response']['message']); + DUP_Log::traceObject('Data', $data); + return false; + } else { + DUP_Log::trace('Usage tracking updated successfully'); + return true; + } + } catch (Exception $e) { + DUP_Log::trace($traceMessagePerefix . ' trace msg: ' . $e->getMessage() . "\n" . SnapLog::getTextException($e, false)); + return false; + } catch (Error $e) { + DUP_Log::trace($traceMessagePerefix . ' trace msg: ' . $e->getMessage() . "\n" . SnapLog::getTextException($e, false)); + return false; + } + } + + /** + * Get remote host + * + * @return string + */ + public static function getRemoteHost() + { + if (DUPLICATOR_CUSTOM_STATS_REMOTE_HOST != '') { // @phpstan-ignore-line + return DUPLICATOR_CUSTOM_STATS_REMOTE_HOST; + } else { + return self::DEFAULT_REMOTE_HOST; + } + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/InstallerData.php b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/InstallerData.php new file mode 100644 index 0000000..808d640 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/InstallerData.php @@ -0,0 +1,88 @@ + + */ + public function getDataToSend() + { + /** @var wpdb $wpdb */ + global $wpdb; + + $data = (object) MigrationMng::getMigrationData(); + + $result = array( + 'api_version' => CommStats::API_VERSION, + 'plugin' => $data->plugin, + 'plugin_version' => $data->installerVersion, + 'install_type' => StatsUtil::getInstallType($data->installType), + 'logic_modes' => StatsUtil::getLogicModes($data->logicModes), + 'template' => StatsUtil::getTemplate($data->template), + 'wp_version' => get_bloginfo('version'), + 'db_engine' => SnapDB::getDBEngine($wpdb->dbh), // @phpstan-ignore-line + 'db_version' => DUP_DB::getVersion(), + // SOURCE SITE INFO + 'source_phpv' => SnapUtil::getVersion($data->phpVersion, 3), + // TARGET SITE INFO + 'target_phpv' => SnapUtil::getVersion(phpversion(), 3), + // PACKAGE INFO + 'license_type' => StatsUtil::getLicenseType($data->licenseType), + 'archive_type' => $data->archiveType, + 'site_size_mb' => round(((int) $data->siteSize) / 1024 / 1024, 2), + 'site_num_files' => $data->siteNumFiles, + 'site_db_size_mb' => round(((int) $data->siteDbSize) / 1024 / 1024, 2), + 'site_db_num_tbl' => $data->siteDBNumTables, + 'components' => StatsUtil::getStatsComponents($data->components), + ); + + $rules = array( + 'api_version' => 'string|max:7', // 1.0 + 'plugin_version' => 'string|max:25', + 'wp_version' => 'string|max:25', + 'db_engine' => 'string|max:25', + 'db_version' => 'string|max:25', + // SOURCE SERVER INFO + 'source_phpv' => 'string|max:25', + // TARGET SERVER INFO + 'target_phpv' => 'string|max:25', + ); + return StatsUtil::sanitizeFields($result, $rules); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/PluginData.php b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/PluginData.php new file mode 100644 index 0000000..b0ad328 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/PluginData.php @@ -0,0 +1,434 @@ +getProperties(); + foreach ($props as $prop) { + if (isset($data[$prop->getName()])) { + $prop->setAccessible(true); + $prop->setValue($this, $data[$prop->getName()]); + } + } + } else { + $this->identifier = self::generateIdentifier(); + $this->save(); + } + } + + /** + * Get instance + * + * @return self + */ + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Save plugin data + * + * @return bool True if data has been saved, false otherwise + */ + public function save() + { + $values = get_object_vars($this); + return update_option(self::PLUGIN_DATA_OPTION_KEY, SnapJson::jsonEncodePPrint($values)); + } + + /** + * Get identifier + * + * @return string + */ + public function getIdentifier() + { + return $this->identifier; + } + + /** + * Update from migrate data + * + * @param StdClass $data Migration data + * + * @return bool + */ + public function updateFromMigrateData(stdClass $data) + { + $save = false; + if ( + isset($data->ustatIdentifier) && + strlen($data->ustatIdentifier) > 0 && + $data->ustatIdentifier !== $this->identifier + ) { + $this->identifier = $data->ustatIdentifier; + $save = true; + } + + return ($save ? $this->save() : true); + } + + /** + * Return usage tracking data + * + * @return array + */ + public function getDataToSend() + { + $result = $this->getBasicInfos(); + $result = array_merge($result, $this->getPluginInfos()); + $result = array_merge($result, $this->getSiteInfos()); + $result = array_merge($result, $this->getManualPackageInfos()); + $result = array_merge($result, $this->getSettingsInfos()); + + $rules = array( + 'api_version' => 'string|max:7', // 1.0 + 'identifier' => 'string|max:44', + // BASIC INFO + 'plugin_version' => 'string|max:25', + 'php_version' => 'string|max:25', + 'wp_version' => 'string|max:25', + // PLUGIN INFO + 'pinstall_version' => '?string|max:25', + // SITE INFO + 'servertype' => 'string|max:25', + 'db_engine' => 'string|max:25', + 'db_version' => 'string|max:25', + 'timezoneoffset' => 'string|max:10', + 'locale' => 'string|max:10', + 'themename' => 'string|max:255', + 'themeversion' => 'string|max:25', + ); + + return StatsUtil::sanitizeFields($result, $rules); + } + + /** + * Get disable tracking data + * + * @return array + */ + public function getDisableDataToSend() + { + $result = $this->getBasicInfos(); + + $rules = array( + 'api_version' => 'string|max:7', // 1.0 + 'identifier' => 'string|max:44', + // BASIC INFO + 'plugin_version' => 'string|max:25', + 'php_version' => 'string|max:25', + 'wp_version' => 'string|max:25', + ); + + return StatsUtil::sanitizeFields($result, $rules); + } + + /** + * Set status + * + * @param string $status Status: active, inactive or uninstalled + * + * @return void + */ + public function setStatus($status) + { + if ($this->pluginStatus === $status) { + return; + } + + switch ($status) { + case self::PLUGIN_STATUS_ACTIVE: + case self::PLUGIN_STATUS_INACTIVE: + $this->pluginStatus = $status; + $this->save(); + break; + } + } + + /** + * Get status + * + * @return string Enum: self::PLUGIN_STATUS_ACTIVE, self::PLUGIN_STATUS_INACTIVE or self::PLUGIN_STATUS_UNINSTALLED + */ + public function getStatus() + { + return $this->pluginStatus; + } + + /** + * Add paackage build count and date for manual and schedule build + * + * @param DUP_Package $package Package + * + * @return void + */ + public function addPackageBuild(DUP_Package $package) + { + if ($package->Status == DUP_PackageStatus::COMPLETE) { + $this->buildCount++; + $this->buildLastDate = time(); + } else { + $this->buildFailedCount++; + $this->buildFailedLastDate = time(); + } + + $this->save(); + } + + /** + * Set site size + * + * @param int $size Site size in bytes + * @param int $numFiles Number of files + * @param int $dbSize Database size in bytes + * @param int $numTables Number of tables + * + * @return void + */ + public function setSiteSize($size, $numFiles, $dbSize, $numTables) + { + $this->siteSizeMB = round(((int) $size) / 1024 / 1024, 2); + $this->siteNumFiles = (int) $numFiles; + $this->siteDbSizeMB = round(((int) $dbSize) / 1024 / 1024, 2); + $this->siteDbNumTables = (int) $numTables; + $this->save(); + } + + /** + * Update last send time + * + * @return void + */ + public function updateLastSendTime() + { + $this->lastSendTime = time(); + $this->save(); + } + + /** + * Get last send time + * + * @return int + */ + public function getLastSendTime() + { + return $this->lastSendTime; + } + + /** + * Get basic infos + * + * @return array + */ + protected function getBasicInfos() + { + return array( + 'api_version' => CommStats::API_VERSION, + 'identifier' => $this->identifier, + 'plugin' => $this->plugin, + 'plugin_status' => $this->pluginStatus, + 'plugin_version' => DUPLICATOR_VERSION, + 'php_version' => SnapUtil::getVersion(phpversion(), 3), + 'wp_version' => get_bloginfo('version'), + ); + } + + /** + * Return plugin infos + * + * @return array + */ + protected function getPluginInfos() + { + if (($installInfo = DUP_LITE_Plugin_Upgrade::getInstallInfo()) === false) { + $installInfo = array( + 'version' => null, + 'time' => null, + ); + } + + return array( + 'pinstall_date' => ($installInfo['time'] == null ? null : date('Y-m-d H:i:s', $installInfo['time'])), + 'pinstall_version' => ($installInfo['version'] == null ? null : $installInfo['version']), + 'license_type' => StatsUtil::getLicenseType(), + 'license_status' => StatsUtil::getLicenseStatus(), + ); + } + + /** + * Return site infos + * + * @return array + */ + protected function getSiteInfos() + { + /** @var wpdb $wpdb */ + global $wpdb; + + $theme_data = wp_get_theme(); + + return array( + 'servertype' => StatsUtil::getServerType(), + 'db_engine' => SnapDB::getDBEngine($wpdb->dbh), // @phpstan-ignore-line + 'db_version' => DUP_DB::getVersion(), + 'is_multisite' => is_multisite(), + 'sites_count' => count(SnapWP::getSitesIds()), + 'user_count' => SnapWp::getUsersCount(), + 'timezoneoffset' => get_option('gmt_offset'), /** @todo evaluate use wp or server timezone offset */ + 'locale' => get_locale(), + 'am_family' => StatsUtil::getAmFamily(), + 'themename' => $theme_data->get('Name'), + 'themeversion' => $theme_data->get('Version'), + 'site_size_mb' => ($this->siteSizeMB == 0 ? null : $this->siteSizeMB), + 'site_num_files' => ($this->siteNumFiles == 0 ? null : $this->siteNumFiles), + 'site_db_size_mb' => ($this->siteDbSizeMB == 0 ? null : $this->siteDbSizeMB), + 'site_db_num_tbl' => ($this->siteDbNumTables == 0 ? null : $this->siteDbNumTables), + ); + } + + /** + * Return manal package infos + * + * @return array + */ + protected function getManualPackageInfos() + { + return array( + 'packages_build_count' => $this->buildCount, + 'packages_build_last_date' => ($this->buildLastDate == 0 ? null : date('Y-m-d H:i:s', $this->buildLastDate)), + 'packages_build_failed_count' => $this->buildFailedCount, + 'packages_build_failed_last_date' => ($this->buildFailedLastDate == 0 ? null : date('Y-m-d H:i:s', $this->buildFailedLastDate)), + 'packages_count' => DUP_Package::getNumCompletePackages(), + ); + } + + /** + * Return granular permissions infos + * + * @return array + */ + protected function getSettingsInfos() + { + return array( + 'settings_archive_build_mode' => StatsUtil::getArchiveBuildMode(), + 'settings_db_build_mode' => StatsUtil::getDbBuildMode(), + 'settings_usage_enabled' => StatsBootstrap::isTrackingAllowed(), + ); + } + + /** + * Return unique identifier + * + * @return string + */ + protected static function generateIdentifier() + { + $maxRand = strlen(self::IDENTIFIER_CHARS) - 1; + + $result = ''; + for ($i = 0; $i < 44; $i++) { + $result .= substr(self::IDENTIFIER_CHARS, wp_rand(0, $maxRand), 1); + } + + return $result; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/StatsBootstrap.php b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/StatsBootstrap.php new file mode 100644 index 0000000..c3dced0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/StatsBootstrap.php @@ -0,0 +1,136 @@ +getStatus() !== PluginData::PLUGIN_STATUS_ACTIVE) { + PluginData::getInstance()->setStatus(PluginData::PLUGIN_STATUS_ACTIVE); + CommStats::pluginSend(); + } + } + + /** + * Deactivation action + * + * @return void + */ + public static function deactivationAction() + { + // Unschedule custom cron event for cleanup if it's scheduled + if (wp_next_scheduled(self::USAGE_TRACKING_CRON_HOOK)) { + $timestamp = wp_next_scheduled(self::USAGE_TRACKING_CRON_HOOK); + wp_unschedule_event($timestamp, self::USAGE_TRACKING_CRON_HOOK); + } + + PluginData::getInstance()->setStatus(PluginData::PLUGIN_STATUS_INACTIVE); + CommStats::pluginSend(); + } + + /** + * Add package build, + * don't use PluginData::getInstance()->addPackageBuild() directly in hook to avoid useless init + * + * @param DUP_Package $package Package + * @param int $status Status DUP_PRO_PackageStatus Enum + * + * @return void + */ + public static function addPackageBuild(DUP_Package $package, $status) + { + if ($status >= DUP_PackageStatus::CREATED && $status < DUP_PackageStatus::COMPLETE) { + return; + } + PluginData::getInstance()->addPackageBuild($package); + } + + /** + * Add site size statistics + * + * @param DUP_Package $package Package + * @param array $report Scan report + * + * @return void + */ + public static function addSiteSizes(DUP_Package $package, $report) + { + if ($package->Archive->ExportOnlyDB) { + return; + } + + PluginData::getInstance()->setSiteSize( + $report['ARC']['USize'], + $report['ARC']['UFullCount'], + $report['DB']['RawSize'], + $report['DB']['TableCount'] + ); + } + + /** + * Is tracking allowed + * + * @return bool + */ + public static function isTrackingAllowed() + { + if (DUPLICATOR_USTATS_DISALLOW) { // @phpstan-ignore-line + return false; + } + + return DUP_Settings::Get('usage_tracking', false); + } + + /** + * Send plugin statistics + * + * @return void + */ + public static function sendPluginStatCron() + { + if (!self::isTrackingAllowed()) { + return; + } + + DUP_Log::trace("CRON: Sending plugin statistics"); + CommStats::pluginSend(); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/StatsUtil.php b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/StatsUtil.php new file mode 100644 index 0000000..ff81ec4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/UsageStatistics/StatsUtil.php @@ -0,0 +1,261 @@ + $data Data + * @param array $rules Rules + * + * @return array + */ + public static function sanitizeFields($data, $rules) + { + foreach ($data as $key => $val) { + if (!isset($rules[$key])) { + continue; + } + + $matches = null; + if (preg_match('/(\??)(int|float|bool|string)(?:\|max:(\d+))?/', $rules[$key], $matches) !== 1) { + throw new Exception("Invalid sanitize rule: {$rules[$key]}"); + } + + $nullable = $matches[1] === '?'; + $type = $matches[2]; + $max = isset($matches[3]) ? (int) $matches[3] : PHP_INT_MAX; + + if ($nullable && $val === null) { + continue; + } + + switch ($type) { + case 'int': + $data[$key] = (int) $val; + break; + case 'float': + $data[$key] = (float) $val; + break; + case 'bool': + $data[$key] = (bool) $val; + break; + case 'string': + $data[$key] = substr((string) $val, 0, $max); + break; + default: + throw new Exception("Unknown sanitize rule: {$rules[$key]}"); + } + } + + return $data; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Utils/ZipArchiveExtended.php b/html/wp-content/plugins/duplicator/src/Utils/ZipArchiveExtended.php new file mode 100644 index 0000000..74abfa9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Utils/ZipArchiveExtended.php @@ -0,0 +1,383 @@ +archivePath = $path; + $this->zipArchive = new ZipArchive(); + $this->setCompressed(true); + } + + /** + * Class destructor + */ + public function __destruct() + { + $this->close(); + } + + /** + * Check if class ZipArchvie is available + * + * @return bool + */ + public static function isPhpZipAvailable() + { + return SnapUtil::classExists(ZipArchive::class); + } + + /** + * Add full dir in archive + * + * @param string $dirPath dir path + * @param string $archivePath local archive path + * + * @return bool TRUE on success or FALSE on failure. + */ + public function addDir($dirPath, $archivePath) + { + if (!is_dir($dirPath) || !is_readable($dirPath)) { + return false; + } + + $dirPath = SnapIO::safePathTrailingslashit($dirPath); + $archivePath = SnapIO::safePathTrailingslashit($archivePath); + $thisObj = $this; + + return SnapIO::regexGlobCallback( + $dirPath, + function ($path) use ($dirPath, $archivePath, $thisObj) { + $newPath = $archivePath . SnapIO::getRelativePath($path, $dirPath); + + if (is_dir($path)) { + $thisObj->addEmptyDir($newPath); + } else { + $thisObj->addFile($path, $newPath); + } + }, + array('recursive' => true) + ); + } + + /** + * Add empty dir on zip archive + * + * @param string $path archive dir to add + * + * @return bool TRUE on success or FALSE on failure. + */ + public function addEmptyDir($path) + { + return $this->zipArchive->addEmptyDir($path); + } + + /** + * Add file on zip archive + * + * @param string $filepath file path + * @param string $archivePath archive path, if empty use file name + * @param int $maxSize max size of file, if the size is grater than this value the file will be truncated, 0 for no limit + * + * @return bool TRUE on success or FALSE on failure. + */ + public function addFile($filepath, $archivePath = '', $maxSize = 0) + { + if (!is_file($filepath) || !is_readable($filepath)) { + return false; + } + if (strlen($archivePath) === 0) { + $archivePath = basename($filepath); + } + if ($maxSize > 0 && filesize($filepath) > $maxSize) { + if (($content = file_get_contents($filepath, false, null, 0, $maxSize)) === false) { + return false; + } + $result = $this->zipArchive->addFromString($archivePath, $content); + } else { + $result = $this->zipArchive->addFile($filepath, $archivePath); + } + if ($result && $this->encrypt) { + $this->zipArchive->setEncryptionName($archivePath, ZipArchive::EM_AES_256); + } + if ($result && !$this->compressed) { + $this->zipArchive->setCompressionName($archivePath, ZipArchive::CM_STORE); + } + return $result; + } + + /** + * Creates a temporary file with the given content. The file will be deleted after the zip is created + * + * @param string $archivePath Filename in archive + * @param string $content Content of the file + * @param int $maxSize max size of file, if the size is grater than this value the file will be truncated, 0 for no limit + * + * @return bool returns true if the file was created successfully + */ + public function addFileFromString($archivePath, $content, $maxSize = 0) + { + if ($maxSize > 0 && strlen($content) > $maxSize) { + $content = substr($content, 0, $maxSize); + } + $result = $this->zipArchive->addFromString($archivePath, $content); + if ($result && $this->encrypt) { + $this->zipArchive->setEncryptionName($archivePath, ZipArchive::EM_AES_256); + } + if ($result && !$this->compressed) { + $this->zipArchive->setCompressionName($archivePath, ZipArchive::CM_STORE); + } + return $result; + } + + /** + * Open Zip archive, create it if don't exists + * + * @return bool|int Returns TRUE on success or the error code. See zip archive + */ + public function open() + { + if ($this->isOpened) { + return true; + } + + if (($result = $this->zipArchive->open($this->archivePath, ZipArchive::CREATE)) === true) { + $this->isOpened = true; + if ($this->encrypt) { + $this->zipArchive->setPassword($this->password); + } else { + $this->zipArchive->setPassword(''); + } + } + return $result; + } + + /** + * Close zip archive + * + * @return bool True on success or false on failure. + */ + public function close() + { + if (!$this->isOpened) { + return true; + } + + $result = false; + + if (($result = $this->zipArchive->close()) === true) { + $this->isOpened = false; + } + + return $result; + } + + /** + * Get num files in zip archive + * + * @return int + */ + public function getNumFiles() + { + $this->open(); + return $this->zipArchive->numFiles; + } + + /** + * Get the value of compressed\ + * + * @return bool + */ + public function isCompressed() + { + return $this->compressed; + } + + /** + * Se compression if is available + * + * @param bool $compressed if true compress zip archive + * + * @return bool return compressd value + */ + public function setCompressed($compressed) + { + if (!method_exists($this->zipArchive, 'setCompressionName')) { + // If don't exists setCompressionName the archive can't create uncrompressed + $this->compressed = true; + } else { + $this->compressed = $compressed; + } + return $this->compressed; + } + + /** + * Get the value of encrypt + * + * @return bool + */ + public function isEncrypted() + { + return $this->encrypt; + } + + /** + * Return true if ZipArchive encryption is available + * + * @return bool + */ + public static function isEncryptionAvaliable() + { + static $isEncryptAvailable = null; + if ($isEncryptAvailable === null) { + if (!self::isPhpZipAvailable()) { + $isEncryptAvailable = false; + return false; + } + + $zipArchive = new ZipArchive(); + if (!method_exists($zipArchive, 'setEncryptionName')) { + $isEncryptAvailable = false; + return false; + } + + if (version_compare(self::getLibzipVersion(), '1.2.0', '<')) { + $isEncryptAvailable = false; + return false; + } + + $isEncryptAvailable = true; + } + + return $isEncryptAvailable; + } + + /** + * Get libzip version + * + * @return string + */ + public static function getLibzipVersion() + { + static $zlibVersion = null; + + if (is_null($zlibVersion)) { + ob_start(); + SnapUtil::phpinfo(INFO_MODULES); + $info = (string) ob_get_clean(); + + if (preg_match('/\s*(libzip.*\sver.+?)\s*<\/td>\s*\s*(.+?)\s*<\/td>/i', $info, $matches) !== 1) { + $zlibVersion = "0"; + } else { + $zlibVersion = $matches[2]; + } + } + + return $zlibVersion; + } + + /** + * Set encryption + * + * @param bool $encrypt true if archvie must be encrypted + * @param string $password password + + * @return bool + */ + public function setEncrypt($encrypt, $password = '') + { + $this->encrypt = (self::isEncryptionAvaliable() ? $encrypt : false); + + if ($this->encrypt) { + $this->password = $password; + } else { + $this->password = ''; + } + + if ($this->isOpened) { + if ($this->encrypt) { + $this->zipArchive->setPassword($this->password); + } else { + $this->zipArchive->setPassword(''); + } + } + + return $this->encrypt; + } + + /** + * Files regex search and return zip file stat + * + * @param string $path Archive path + * @param string $regex Regex to search + * @param string $password Password if archive is encrypted or empty string + * + * @return false|array{name:string,index:int,crc:int,size:int,mtime:int,comp_size:int,comp_method:int} + */ + public static function searchRegex($path, $regex, $password = '') + { + if (!self::isPhpZipAvailable()) { + throw new Exception(__('ZipArchive PHP module is not installed/enabled. The current Backup cannot be opened.', 'duplicator')); + } + + $zip = new ZipArchive(); + if ($zip->open($path) !== true) { + throw new Exception('Cannot open the ZipArchive file. Please see the online FAQ\'s for additional help.' . $path); + } + + if (strlen($password)) { + $zip->setPassword($password); + } + + $result = false; + for ($i = 0; $i < $zip->numFiles; $i++) { + /** @var array{name:string,index:int,crc:int,size:int,mtime:int,comp_size:int,comp_method:int} */ + $stat = $zip->statIndex($i); + $name = basename($stat['name']); + if (preg_match($regex, $name) === 1) { + $result = $stat; + break; + } + } + + $zip->close(); + return $result; + } +} diff --git a/html/wp-content/plugins/duplicator/src/Views/AdminNotices.php b/html/wp-content/plugins/duplicator/src/Views/AdminNotices.php new file mode 100644 index 0000000..a23814d --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Views/AdminNotices.php @@ -0,0 +1,548 @@ +roles) && !current_user_can('export'); + } + + if ($noCapabilitiesNotice) { + $notices[] = array(__CLASS__, 'showNoExportCapabilityNotice'); + } + + if (is_multisite()) { + $displayNotices = is_super_admin() && current_user_can('export'); + } else { + $displayNotices = current_user_can('export'); + } + + if ($displayNotices) { + $notices[] = array(__CLASS__, 'clearInstallerFilesAction'); // BEFORE MIGRATION SUCCESS NOTICE + $notices[] = array(__CLASS__, 'migrationSuccessNotice'); + $notices[] = array(__CLASS__, 'installAutoDeactivatePlugins'); + $notices[] = array(__CLASS__, 'failedOneClickUpgradeNotice'); + } + + $action = is_multisite() ? 'network_admin_notices' : 'admin_notices'; + foreach ($notices as $notice) { + add_action($action, $notice); + } + } + + /** + * Remove all notices coming from other plugins + * + * @param string $hook Hook string + * + * @return void + */ + public static function unhookThirdPartyNotices($hook) + { + if (!ControllersManager::isDuplicatorPage()) { + return; + } + + global $wp_filter; + $filterHooks = array('user_admin_notices', 'admin_notices', 'all_admin_notices', 'network_admin_notices'); + foreach ($filterHooks as $filterHook) { + if (empty($wp_filter[$filterHook]->callbacks) || !is_array($wp_filter[$filterHook]->callbacks)) { + continue; + } + + foreach ($wp_filter[$filterHook]->callbacks as $priority => $hooks) { + foreach ($hooks as $name => $arr) { + if (is_object($arr['function']) && $arr['function'] instanceof Closure) { + unset($wp_filter[$filterHook]->callbacks[$priority][$name]); + continue; + } + if ( + !empty($arr['function'][0]) && + is_object($arr['function'][0]) && + strpos(get_class($arr['function'][0]), Autoloader::ROOT_NAMESPACE) === 0 + ) { + continue; + } + if (!empty($name) && strpos($name, Autoloader::ROOT_NAMESPACE) !== 0) { + unset($wp_filter[$filterHook]->callbacks[$priority][$name]); + } + } + } + } + } + + /** + * Clear installer file action + * + * @return void + */ + public static function clearInstallerFilesAction() + { + + if (!\DUP_CTRL_Tools::isDiagnosticPage() || get_option(self::OPTION_KEY_MIGRATION_SUCCESS_NOTICE) == true) { + return; + } + + + if (sanitize_text_field(SnapUtil::filterInputRequest('action')) === 'installer') { + if (! wp_verify_nonce($_REQUEST['_wpnonce'], 'duplicator_cleanup_page')) { + echo '

        ' . __('Security issue', 'duplicator') . '

        '; + exit; // Get out of here bad nounce! + } + + ?> +
        + +
        + id == 'duplicator_page_duplicator-tools' && isset($_GET['action']) && $_GET['action'] == 'installer'); + if (DUP_Server::hasInstallerFiles() && !$is_installer_cleanup_req) { + MigrationMng::renameInstallersPhpFiles(); + + $on_active_tab = isset($_GET['section']) ? $_GET['section'] : ''; + echo '

        '; + + //Safe Mode Notice + $safe_html = ''; + if (get_option("duplicator_exe_safe_mode", 0) > 0) { + $safe_msg1 = __('Safe Mode:', 'duplicator'); + $safe_msg2 = __('During the install safe mode was enabled deactivating all plugins.
        Please be sure to ', 'duplicator'); + $safe_msg3 = __('re-activate the plugins', 'duplicator'); + $safe_html = "

        {$safe_msg1}
        {$safe_msg2} {$safe_msg3}!

        "; + } + + //On Tools > Cleanup Page + if ($screen->id == 'duplicator_page_duplicator-tools' && ($on_active_tab == "info" || $on_active_tab == '')) { + $title = __('This site has been successfully migrated!', 'duplicator'); + $msg1 = __('Final step(s):', 'duplicator'); + $msg2 = __('This message will be removed after all installer files are removed. Installer files must be removed to maintain a secure site. ' + . 'Click the link above or button below to remove all installer files and complete the migration.', 'duplicator'); + + echo " " . esc_html($title) . + "
        {$safe_html} " . esc_html($msg1) . "
        "; + printf( + "1. %s
        ", + esc_html__('Remove Installation Files Now!', 'duplicator') + ); + printf( + "2. %s
        ", + esc_html__('Optionally, Review Duplicator at WordPress.org...', 'duplicator') + ); + echo "
        " . esc_html($msg2) . "
        "; + + //All other Pages + } else { + $title = __('Migration Almost Complete!', 'duplicator'); + $msg = __( + 'Reserved Duplicator installation files have been detected in the root directory. Please delete these installation files to ' + . 'avoid security issues.
        Go to: Duplicator > Tools > General > Information > Utils and click the "Remove Installation Files" button', + 'duplicator' + ); + + $nonce = wp_create_nonce('duplicator_cleanup_page'); + $url = ControllersManager::getMenuLink( + ControllersManager::TOOLS_SUBMENU_SLUG, + 'diagnostics', + null, + array( + 'section' => 'info', + '_wpnonce' => $nonce, + ), + true + ); + echo "{$title}
        {$safe_html} {$msg}"; + @printf("
        %s", __('Take me there now!', 'duplicator')); + } + echo "

        "; + } + } + + /** + * Shows a message for redirecting a page + * + * @param string $location The location to redirect to + * + * @return never + */ + public static function redirect($location) + { + echo '
        '; + esc_html__('Redirecting Please Wait...', 'duplicator'); + echo '
        '; + echo ""; + die(esc_html__('Invalid token permissions to perform this request.', 'duplicator')); + } + + /** + * Shows install deactivated function + * + * @return void + */ + public static function installAutoDeactivatePlugins() + { + $reactivatePluginsAfterInstallation = get_option(self::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL, false); + + $pluginsToActive = get_option(self::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL, false); + if (!is_array($pluginsToActive) || empty($pluginsToActive)) { + return false; + } + + $shouldBeActivated = array(); + $allPlugins = get_plugins(); + foreach ($pluginsToActive as $index => $pluginSlug) { + if (!isset($allPlugins[$pluginSlug])) { + unset($pluginsToActive[$index]); + continue; + } + + $isActive = is_plugin_active($pluginSlug); + + if (!$isActive && isset($allPlugins[$pluginSlug])) { + $shouldBeActivated[$pluginSlug] = $allPlugins[$pluginSlug]['Name']; + } else { + unset($pluginsToActive[$index]); + } + } + + if (empty($shouldBeActivated)) { + delete_option(self::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL); + return; + } else { + update_option(self::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL, $pluginsToActive); + } + + $activatePluginsAnchors = array(); + foreach ($shouldBeActivated as $slug => $title) { + $activateURL = wp_nonce_url(admin_url('plugins.php?action=activate&plugin=' . $slug), 'activate-plugin_' . $slug); + $anchorTitle = sprintf(esc_html__('Activate %s', 'duplicator'), $title); + $activatePluginsAnchors[] = '' . + $title . ''; + } + ?> +
        +

        + " . esc_html__("Warning!", "duplicator") . " " . esc_html__("Migration Almost Complete!", "duplicator") . "
        "; + echo esc_html__( + "Plugin(s) listed here have been deactivated during installation to help prevent issues. Please activate them to finish this migration: ", + "duplicator" + ) . "
        "; + echo implode(' ,', $activatePluginsAnchors); + ?> +

        +
        + id, $duplicator_pages) || (isset($notices[$notice_id]) && 'true' === $notices[$notice_id])) { + return; + } + + global $wpdb; + // not using DUP_Util::getTablePrefix() in place of $tablePrefix because AdminNotices included initially (Duplicator\Lite\Requirement + // is depended on the AdminNotices) + $tablePrefix = (is_multisite() && is_plugin_active_for_network('duplicator/duplicator.php')) ? + $wpdb->base_prefix : + $wpdb->prefix; + $tableName = esc_sql($tablePrefix . 'duplicator_packages'); + $packagesCount = $wpdb->get_var("SELECT count(id) FROM `{$tableName}` WHERE status=100"); + + if ($packagesCount < DUPLICATOR_FEEDBACK_NOTICE_SHOW_AFTER_NO_PACKAGE) { + return; + } + + $notices[$notice_id] = 'false'; + update_user_meta(get_current_user_id(), DUPLICATOR_ADMIN_NOTICES_USER_META_KEY, $notices); + $dismiss_url = wp_nonce_url( + add_query_arg(array( + 'action' => 'duplicator_set_admin_notice_viewed', + 'notice_id' => esc_attr($notice_id), + ), admin_url('admin-post.php')), + 'duplicator_set_admin_notice_viewed', + 'nonce' + ); + ?> +
        +
        +
        + " + style="text-align:top; margin:0; height:60px; width:60px;" alt="Duplicator"> +
        +
        +

        + + + + +

        +

        + + + + + + +

        +
        +
        +
        + roles) && !current_user_can('export')) { + $faqUrl = esc_url(LinkManager::getDocUrl( + 'how-to-resolve-duplicator-plugin-user-interface-ui-issues', + 'admin_notice', + 'duplicator menu missing' + )); + $errorMessage = __( + 'Duplicator
        Your logged-in user role does not have export + capability so you don\'t have access to Duplicator functionality.', + 'duplicator' + ) . + "
        " . + sprintf( + _x( + 'RECOMMENDATION: Add export capability to your role. See FAQ: ' . + '%1$sWhy is the Duplicator/Packages menu missing from my admin menu?%2$s', + '%1$s and %2$s are tags', + 'duplicator' + ), + '', + '' + ); + self::displayGeneralAdminNotice($errorMessage, self::GEN_ERROR_NOTICE, true); + } + } + + /** + * Display multisite notice + * + * @return void + */ + public static function multisiteNotice() + { + if ( + !ControllersManager::isDuplicatorPage() || + ControllersManager::isCurrentPage(ControllersManager::ABOUT_US_SUBMENU_SLUG) || + ControllersManager::isCurrentPage(ControllersManager::SETTINGS_SUBMENU_SLUG, 'general') + ) { + return; + } + + $message = TplMng::getInstance()->render('parts/notices/drm_multisite_msg', array(), false); + self::displayGeneralAdminNotice($message, self::GEN_ERROR_NOTICE, false, ['duplicator-multisite-notice']); + } + + /** + * display genral admin notice by printing it + * + * @param string $htmlMsg html code to be printed + * @param integer $noticeType constant value of SELF::GEN_ + * @param boolean $isDismissible whether the notice is dismissable or not. Default is true + * @param array|string $extraClasses add more classes to the notice div + * + * @return void + */ + public static function displayGeneralAdminNotice($htmlMsg, $noticeType, $isDismissible = true, $extraClasses = array()) + { + if (empty($extraClasses)) { + $classes = array(); + } elseif (is_array($extraClasses)) { + $classes = $extraClasses; + } else { + $classes = array($extraClasses); + } + + $classes[] = 'notice'; + + switch ($noticeType) { + case self::GEN_INFO_NOTICE: + $classes[] = 'notice-info'; + break; + case self::GEN_SUCCESS_NOTICE: + $classes[] = 'notice-success'; + break; + case self::GEN_WARNING_NOTICE: + $classes[] = 'notice-warning'; + break; + case self::GEN_ERROR_NOTICE: + $classes[] = 'notice-error'; + break; + default: + throw new Exception('Invalid Admin notice type!'); + } + + if ($isDismissible) { + $classes[] = 'is-dismissible'; + } + + $classesStr = implode(' ', $classes); + ?> +
        +

        + + + + +

        +
        + setStripSpaces(true); + ?> +
        + +
        + +
        + +
        + render( + 'parts/DashboardWidget/package-create-section', + array ( + 'lastBackupString' => self::getLastBackupString() + ) + ); + } + + /** + * Render the last packages + * + * @return void + */ + protected static function renderRecentlyPackages() + { + /** @var DUP_Package[] */ + $packages = DUP_Package::get_packages_by_status( + array( + array( + 'op' => '>=', + 'status' => DUP_PackageStatus::COMPLETE + ) + ), + self::LAST_PACKAGES_LIMIT, + 0, + 'created DESC' + ); + + $totalsIds = DUP_Package::get_ids_by_status( + array( + array( + 'op' => '>=', + 'status' => DUP_PackageStatus::COMPLETE + ) + ) + ); + + $failuresIds = DUP_Package::get_ids_by_status( + array( + array( + 'op' => '<', + 'status' => 0 + ) + ) + ); + + TplMng::getInstance()->render( + 'parts/DashboardWidget/recently-packages', + array( + 'packages' => $packages, + 'totalPackages' => count($totalsIds), + 'totalFailures' => count($failuresIds) + ) + ); + } + + /** + * Render Duplicate sections + * + * @return void + */ + protected static function renderSections() + { + TplMng::getInstance()->render( + 'parts/DashboardWidget/sections-section', + array( + 'numSchedules' => 0, + 'numSchedulesEnabled' => 0, + 'numTemplates' => 1, + 'numStorages' => 1, + 'nextScheduleString' => '', + 'recoverDateString' => '' + ) + ); + } + + /** + * Get the last backup string + * + * @return string HTML string + */ + public static function getLastBackupString() + { + if (DUP_Package::isPackageRunning()) { + return ' ' . esc_html__('A Backup is currently running.', 'duplicator') . ''; + } + + /** @var DUP_Package[] */ + $lastPackage = DUP_Package::get_packages_by_status( + array( + array( + 'op' => '>=', + 'status' => DUP_PackageStatus::COMPLETE + ) + ), + 1, + 0, + 'created DESC' + ); + + if (empty($lastPackage)) { + return '' . esc_html__('No Backups have been created yet.', 'duplicator') . ''; + } + + $createdTime = date_i18n(get_option('date_format'), strtotime($lastPackage[0]->Created)); + + if ($lastPackage[0]->getPackageLife() > self::LAST_PACKAGE_TIME_WARNING) { + $timeDiffClass = 'maroon'; + } else { + $timeDiffClass = 'green'; + } + + $timeDiff = sprintf( + _x('%s ago', '%s represents the time diff, eg. 2 days', 'duplicator'), + $lastPackage[0]->getPackageLife('human') + ); + + return '' . $createdTime . ' ' . + " (" . '' . + $timeDiff . + '' . ")"; + } + + /** + * Return randomly chosen one of recommended plugins. + * + * @return false|array{name: string,slug: string,more: string,pro: array{file: string}} + */ + protected static function getRecommendedPluginData() + { + $plugins = array( + 'google-analytics-for-wordpress/googleanalytics.php' => array( + 'name' => __('MonsterInsights', 'duplicator'), + 'slug' => 'google-analytics-for-wordpress', + 'more' => 'https://www.monsterinsights.com/', + 'pro' => array( + 'file' => 'google-analytics-premium/googleanalytics-premium.php', + ), + ), + 'all-in-one-seo-pack/all_in_one_seo_pack.php' => array( + 'name' => __('AIOSEO', 'duplicator'), + 'slug' => 'all-in-one-seo-pack', + 'more' => 'https://aioseo.com/', + 'pro' => array( + 'file' => 'all-in-one-seo-pack-pro/all_in_one_seo_pack.php', + ), + ), + 'coming-soon/coming-soon.php' => array( + 'name' => __('SeedProd', 'duplicator'), + 'slug' => 'coming-soon', + 'more' => 'https://www.seedprod.com/', + 'pro' => array( + 'file' => 'seedprod-coming-soon-pro-5/seedprod-coming-soon-pro-5.php', + ), + ), + 'wp-mail-smtp/wp_mail_smtp.php' => array( + 'name' => __('WP Mail SMTP', 'duplicator'), + 'slug' => 'wp-mail-smtp', + 'more' => 'https://wpmailsmtp.com/', + 'pro' => array( + 'file' => 'wp-mail-smtp-pro/wp_mail_smtp.php', + ), + ), + ); + + $installed = get_plugins(); + + foreach ($plugins as $id => $plugin) { + if (isset($installed[$id])) { + unset($plugins[$id]); + } + + if (isset($installed[$plugin['pro']['file']])) { + unset($plugins[$id]); + } + } + return ($plugins ? $plugins[ array_rand($plugins) ] : false); + } + + /** + * Recommended plugin block HTML. + * + * @return void + */ + public static function renderRecommendedPluginSection() + { + if (get_user_meta(get_current_user_id(), self::RECOMMENDED_PLUGIN_DISMISSED_OPT_KEY, true) != false) { + return; + } + + $plugin = self::getRecommendedPluginData(); + + if (empty($plugin)) { + return; + } + + $installUrl = wp_nonce_url( + self_admin_url('update.php?action=install-plugin&plugin=' . rawurlencode($plugin['slug'])), + 'install-plugin_' . $plugin['slug'] + ); + + TplMng::getInstance()->render( + 'parts/DashboardWidget/recommended-section', + array( + 'plugin' => $plugin, + 'installUrl' => $installUrl, + ) + ); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Views/EducationElements.php b/html/wp-content/plugins/duplicator/src/Views/EducationElements.php new file mode 100644 index 0000000..6adaf90 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Views/EducationElements.php @@ -0,0 +1,134 @@ +render('parts/Education/callout-cta'); + } + + /** + * Display did you know + * + * @return void + */ + public static function didYouKnow() + { + $features = Upsell::getProFeatureList(); + TplMng::getInstance()->render('parts/Education/did-you-know-blurb', array( + 'feature' => $features[array_rand($features)] + )); + } + + /** + * Display email form + * + * @return void + */ + public static function emailForm() + { + if (self::userIsSubscribed()) { + return; + } + + TplMng::getInstance()->render('parts/Education/subscribe-form'); + } + + /** + * Display did you know + * + * @return void + */ + public static function bottomBar() + { + if (get_user_meta(get_current_user_id(), self::DUP_PACKAGES_BOTTOM_BAR_DISMISSED, false) == true) { + return; + } + + $numberOfPackages = \DUP_Package::count_by_status(array( + array('op' => '=' , 'status' => \DUP_PackageStatus::COMPLETE ) + )); + + if ($numberOfPackages < 1) { + return; + } + + $features = self::getBottomBarFeatures(); + TplMng::getInstance()->render('parts/Education/packages-bottom-bar', array( + 'feature' => $features[array_rand($features)] + )); + } + + /** + * Get packages bottom bar feature list + * + * @return string[] + */ + private static function getBottomBarFeatures() + { + return array( + __('Scheduled Backups - Ensure that important data is regularly and consistently backed up, allowing for quick ' . + 'and efficient recovery in case of data loss.', 'duplicator'), + __('Cloud Backups - Back up to Dropbox, FTP, Google Drive, OneDrive, or Amazon S3 and more for safe storage.', 'duplicator'), + __('Recovery Points - Recovery Points provides protection against mistakes and bad updates by letting you ' . + 'quickly rollback your system to a known, good state.', 'duplicator'), + __('Secure File Encryption - Protect and secure the archive file with industry-standard AES-256 encryption', 'duplicator'), + __('Server to Server Import - Direct Backup import from source server or cloud storage using URL. No need ' . + 'to download the Backup to your desktop machine first.', 'duplicator'), + __('File & Database Table Filters - Use file and database filters to pick and choose exactly what you want to ' . + 'backup or transfer. No bloat!', 'duplicator'), + __('Large Site Support - Duplicator Pro has developed a new way to package backups especially tailored for ' . + 'larger site. No server timeouts or other restrictions.', 'duplicator'), + __('Multisite Support - Duplicator Pro supports multisite network backup & migration. You can even install ' . + 'a subsite as a standalone site.', 'duplicator'), + ); + } + + /** + * True if user is subscribed + * + * @return bool + */ + public static function userIsSubscribed() + { + return get_user_meta(get_current_user_id(), self::DUP_EMAIL_SUBSCRIBED_OPT_KEY, false); + } +} diff --git a/html/wp-content/plugins/duplicator/src/Views/ViewHelper.php b/html/wp-content/plugins/duplicator/src/Views/ViewHelper.php new file mode 100644 index 0000000..7f31e76 --- /dev/null +++ b/html/wp-content/plugins/duplicator/src/Views/ViewHelper.php @@ -0,0 +1,26 @@ +render('parts/admin-logo-header'); + } +} diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/extra_plugin_item.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/extra_plugin_item.php new file mode 100644 index 0000000..df98537 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/extra_plugin_item.php @@ -0,0 +1,69 @@ + $tplData + * @var ExtraItem $plugin + */ + +$plugin = $tplData['plugin']; + +switch ($plugin->getStatus()) { + case ExtraItem::STATUS_ACTIVE: + $buttonLabel = __('Activated', 'duplicator'); + $buttonClass = 'disabled'; + $statusClass = 'status-active'; + break; + case ExtraItem::STATUS_INSTALLED: + $buttonLabel = __('Activate', 'duplicator'); + $buttonClass = 'button-secondary'; + $statusClass = 'status-installed'; + break; + case ExtraItem::STATUS_NOT_INSTALLED: + default: + $buttonLabel = __('Install Plugin', 'duplicator'); + $buttonClass = 'button-primary'; + $statusClass = 'status-missing'; + break; +} + +?> +
        +
        +
        + <?php echo $plugin->name; ?> logo +
        + name; ?> +
        +

        desc; ?>

        +
        +
        +
        + + + getStatusText(); ?> + + +
        +
        + getURLType() === ExtraItem::URL_TYPE_GENERIC) { ?> + + + + + + +
        +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/extra_plugins.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/extra_plugins.php new file mode 100644 index 0000000..499a3ba --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/extra_plugins.php @@ -0,0 +1,32 @@ + $tplData + */ + +defined('ABSPATH') || die(); + +if (!current_user_can('install_plugins')) { + return; +} +?> +
        +
        +
        + foreachCallback(function (ExtraItem $plugin) use ($tplMng) { + $tplMng->render( + 'admin_pages/about_us/about_us/extra_plugin_item', + array('plugin' => $plugin->skipLite() ? $plugin->getPro() : $plugin) + ); + }); + ?> +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/info.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/info.php new file mode 100644 index 0000000..151b85a --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/info.php @@ -0,0 +1,55 @@ +
        +
        +

        + +

        +

        + +

        +

        + +

        +

        + WPBeginner, the most popular ' . + 'lead-generation software, OptinMonster, ' . + 'the best WordPress analytics plugin, MonsterInsights, and more!', + 'duplicator' + ), + array( + 'a' => array( + 'href' => array(), + 'rel' => array(), + 'target' => array(), + ), + ) + ), + 'https://www.wpbeginner.com/?utm_source=duplicatorplugin&utm_medium=pluginaboutpage&utm_campaign=aboutduplicator', + 'https://optinmonster.com/?utm_source=duplicatorplugin&utm_medium=pluginaboutpage&utm_campaign=aboutduplicator', + 'https://www.monsterinsights.com/?utm_source=duplicatorplugin&utm_medium=pluginaboutpage&utm_campaign=aboutduplicator' + ); + ?> +

        +

        + +

        +
        + +
        +
        + <?php esc_attr_e('The Awesome Motive Team photo', 'duplicator'); ?> +
        +
        +
        +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/main.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/main.php new file mode 100644 index 0000000..571b5aa --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/about_us/main.php @@ -0,0 +1,25 @@ + $tplData + */ +?> + +
        +render('admin_pages/about_us/about_us/info'); +$tplMng->render('admin_pages/about_us/about_us/extra_plugins'); +?> +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/first_package.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/first_package.php new file mode 100644 index 0000000..44ef6ab --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/first_package.php @@ -0,0 +1,72 @@ + $tplData + */ +?> +
        + +
        + +

        + +

        + +

        +

        + +

        +

        + +

        + + + +
        + +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/get_pro.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/get_pro.php new file mode 100644 index 0000000..a9e4635 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/get_pro.php @@ -0,0 +1,113 @@ + $tplData + */ +?> +
        + +
        +

        + +

        + +

        + Upgrade to Duplicator Pro to unlock ' . + 'all the awesome features and experience
        why Duplicator is consistently rated the best WordPress migration plugin.', + 'duplicator' + ), + array( + 'br' => array(), + 'strong' => array(), + ) + ); + ?> +

        + +

        + 4000+ five star ratings ' . + '(%s) and is active on over 1 million websites.', + 'duplicator' + ), + array( + 'strong' => array(), + ) + ), + '' . + '' . + '' . + '' . + '' + ); + ?> +

        +
        + +
        +
        +
          + +
        • + + + +
        • + +
        +
        + +
        + +

        + ', + esc_url(LinkManager::getCampaignUrl('duplicator-about_getting-started', 'Get Duplicator Pro Today')) + ); + + _e('Get Duplicator Pro Today and Unlock all the Powerful Features', 'duplicator'); + ?> + +

        + +

        + %1$d%% off regular price, ' . + 'automatically applied at checkout.', + 'duplicator' + ), + DUP_Constants::UPSELL_DEFAULT_DISCOUNT + ); + ?> +

        +
        + +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/main.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/main.php new file mode 100644 index 0000000..3c8b6b5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/getting_started/main.php @@ -0,0 +1,30 @@ + $tplData + */ + +?> + +
        +render('admin_pages/about_us/getting_started/first_package'); + +TplMng::getInstance()->render('admin_pages/about_us/getting_started/get_pro'); +?> +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/lite_vs_pro/main.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/lite_vs_pro/main.php new file mode 100644 index 0000000..72a1738 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/lite_vs_pro/main.php @@ -0,0 +1,123 @@ + $tplData + */ +?> +
        +
        +

        + Lite vs Pro', + 'duplicator' + ), + [ + 'strong' => [], + ] + ); + ?> +

        + +

        + +

        +
        + +
        + +
        +
        +

        + +

        +
        +
        +

        + +

        +
        +
        +

        + +

        +
        +
        +
        + + + + + + + + + +
        +

        +
        +

        + + + +

        +
        +

        + + + +

        +
        +
        +
        +
        +
        +

        + ', + esc_url(LinkManager::getCampaignUrl('about_duplicator_lite_vs_pro', 'Get Duplicator Pro Today')) + ); + _e('Get Duplicator Pro Today and Unlock all the Powerful Features', 'duplicator') + ?> + +

        + +

        + %1$d%% off regular price, ' . + 'automatically applied at checkout.', + 'duplicator' + ), + DUP_Constants::UPSELL_DEFAULT_DISCOUNT + ); + ?> +

        +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/about_us/tabs.php b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/tabs.php new file mode 100644 index 0000000..b32b173 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/about_us/tabs.php @@ -0,0 +1,27 @@ + $tplData + */ +?> + + diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/packages/setup/archive-filter-files-tab.php b/html/wp-content/plugins/duplicator/template/admin_pages/packages/setup/archive-filter-files-tab.php new file mode 100644 index 0000000..0b87db9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/packages/setup/archive-filter-files-tab.php @@ -0,0 +1,23 @@ + $tplData + */ +?> +
        + render('parts/filters/package_components', array( + 'package' => $tplData['package'], + )); ?> +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/email_summary.php b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/email_summary.php new file mode 100644 index 0000000..6631a30 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/email_summary.php @@ -0,0 +1,57 @@ + $tplData + */ + +use Duplicator\Utils\LinkManager; +use Duplicator\Utils\Email\EmailSummary; + +defined('ABSPATH') || exit; + +$frequency = DUP_Settings::Get('email_summary_frequency'); +?> + +

        +
        + + + + + +
        + +

        + tags to the summary preview link', + 'duplicator' + ), + '', + '' + ) . ' ' . sprintf( + esc_html_x( + 'Learn %1show to disable%2s.', + '%1s and %2s are opening and closing link tags to the documentation.', + 'duplicator' + ), + '', + '' + ); + ?> +

        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/general.php b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/general.php new file mode 100644 index 0000000..d609b15 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/general.php @@ -0,0 +1,263 @@ + $tplData + */ + +use Duplicator\Core\Controllers\ControllersManager; +use Duplicator\Utils\LinkManager; +use Duplicator\Libs\Snap\SnapUtil; +use Duplicator\Core\Views\TplMng; + +global $wp_version; +global $wpdb; + +$action_updated = null; +$action_response = __("General Settings Saved", 'duplicator'); + +//SAVE RESULTS +if (isset($_POST['action']) && $_POST['action'] == 'save') { + //Nonce Check + if (!isset($_POST['dup_settings_save_nonce_field']) || !wp_verify_nonce($_POST['dup_settings_save_nonce_field'], 'dup_settings_save')) { + die('Invalid token permissions to perform this request.'); + } + + DUP_Settings::Set('wpfront_integrate', isset($_POST['wpfront_integrate']) ? "1" : "0"); + + $skip_archive_scan = filter_input(INPUT_POST, 'skip_archive_scan', FILTER_VALIDATE_BOOLEAN); + DUP_Settings::Set('skip_archive_scan', $skip_archive_scan); + + $unhook_third_party_js = filter_input(INPUT_POST, 'unhook_third_party_js', FILTER_VALIDATE_BOOLEAN); + DUP_Settings::Set('unhook_third_party_js', $unhook_third_party_js); + + $unhook_third_party_css = filter_input(INPUT_POST, 'unhook_third_party_css', FILTER_VALIDATE_BOOLEAN); + DUP_Settings::Set('unhook_third_party_css', $unhook_third_party_css); + + $email_summary_frequency = SnapUtil::sanitizeStrictInput(INPUT_POST, 'email_summary_frequency'); + DUP_Settings::setEmailSummaryFrequency($email_summary_frequency); + + + + DUP_Settings::Save(); + $action_updated = true; + DUP_Util::initSnapshotDirectory(); +} + +$wpfront_integrate = DUP_Settings::Get('wpfront_integrate'); +$wpfront_ready = apply_filters('wpfront_user_role_editor_duplicator_integration_ready', false); +$skip_archive_scan = DUP_Settings::Get('skip_archive_scan'); +$unhook_third_party_js = DUP_Settings::Get('unhook_third_party_js'); +$unhook_third_party_css = DUP_Settings::Get('unhook_third_party_css'); +$actionUrl = ControllersManager::getMenuLink(ControllersManager::SETTINGS_SUBMENU_SLUG, 'general'); +?> + + + +
        + + + + + + +

        + + + render('admin_pages/settings/general/license'); ?> + + render('admin_pages/settings/general/email_summary'); ?> + + +

        +
        + + + + + + + + + + + + + + + + + +
        + +

        + + " + data-tooltip=""> + +

        +
        + value="1" /> +
        +

        + +

        +
        + value="1"/> +
        +

        + '; + esc_html_e("Do not modify this setting unless you know the expected result or have talked to support.", 'duplicator'); + ?> +

        +
        + value="1"/> +
        +

        + '; + esc_html_e("Do not modify this setting unless you know the expected result or have talked to support.", 'duplicator'); + ?> +

        +
        + +

        +
        + " + style="display: inline-block;" + /> +

        + +
        + + +title = __('Reset Backups ?', 'duplicator'); +$reset_confirm->message = __('This will clear and reset all of the current temporary Backups. Would you like to continue?', 'duplicator'); +$reset_confirm->progressText = __('Resetting settings, Please Wait...', 'duplicator'); +$reset_confirm->jscallback = 'Duplicator.Pack.ResetAll()'; +$reset_confirm->progressOn = false; +$reset_confirm->okText = __('Yes', 'duplicator'); +$reset_confirm->cancelText = __('No', 'duplicator'); +$reset_confirm->closeOnConfirm = true; +$reset_confirm->initConfirm(); + +$faqUrl = esc_url(LinkManager::getDocUrl('how-to-resolve-duplicator-plugin-user-interface-ui-issues', 'settings-admin_notice')); +$msg_ajax_error = new DUP_UI_Messages( + __('AJAX Call Error!', 'duplicator') . '
        ' . + sprintf( + _x( + 'AJAX error encountered when resetting Backups. Please see %1$sthis FAQ entry%2$s for possible resolutions.', + '1 and 2 are opening and closing tags', + 'duplicator' + ), + '', + '' + ), + DUP_UI_Messages::ERROR +); + +$msg_ajax_error->hide_on_init = true; +$msg_ajax_error->is_dismissible = true; +$msg_ajax_error->initMessage(); + +$msg_response_error = new DUP_UI_Messages(__('RESPONSE ERROR!', 'duplicator'), DUP_UI_Messages::ERROR); +$msg_response_error->hide_on_init = true; +$msg_response_error->is_dismissible = true; +$msg_response_error->initMessage(); + +$msg_response_success = new DUP_UI_Messages('', DUP_UI_Messages::NOTICE); +$msg_response_success->hide_on_init = true; +$msg_response_success->is_dismissible = true; +$msg_response_success->initMessage(); +?> + diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/license.php b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/license.php new file mode 100644 index 0000000..ae95d13 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/license.php @@ -0,0 +1,67 @@ + + +

        +
        + + + + + +
        +
        +

        🙂

        +

        + upgrading to PRO.', 'duplicator'), + array( + 'a' => array( + 'href' => array(), + 'class' => array(), + 'target' => array(), + 'rel' => array(), + ), + 'strong' => array(), + ) + ), + esc_url(LinkManager::getCampaignUrl('license-tab', 'upgrading to PRO')) + ); ?> +

        +

        + %1$d%% off, automatically applied at checkout!', + 'duplicator' + ), + DUP_Constants::UPSELL_DEFAULT_DISCOUNT + ); + ?> +

        +
        +

        + Duplicator PRO!', 'duplicator'); ?>

        +

        + +

        +

        + +

        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/usage_tracking_tooltip.php b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/usage_tracking_tooltip.php new file mode 100644 index 0000000..6c27ead --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/settings/general/usage_tracking_tooltip.php @@ -0,0 +1,96 @@ + $tplData + */ +?> +
        + +
        + +
        +
        +
        +
        + + + + + +
        +
          +
        • + PHP Version: so we know which PHP versions we have to test against (no one likes whitescreens or log files full of errors).', + 'duplicator' + ); + ?> +
        • +
        • + WordPress Version: so we know which WordPress versions to support and test against.', + 'duplicator' + ); + ?> +
        • +
        • + MySQL Version: so we know which versions of MySQL to support and test against for our custom tables.', + 'duplicator' + ); + ?> +
        • +
        • + Duplicator Version: so we know which versions of Duplicator are potentially responsible for issues when we get bug reports, + allowing us to identify issues and release solutions much faster.', + 'duplicator' + ); + ?> +
        • +
        • + Plugins and Themes infos: so we can figure out which ones can generate compatibility errors with Duplicator.', + 'duplicator' + ); + ?> +
        • +
        • + Site info: General information about the site such as database, file size, number of users, and sites in case it is a multisite. + This is useful for us to understand the critical issues of Backup creation.', + 'duplicator' + ); + ?> +
        • +
        • + Backups infos: Information about the Backups created and the type of components included.', + 'duplicator' + ); + ?> +
        • +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/settings/misc/misc.php b/html/wp-content/plugins/duplicator/template/admin_pages/settings/misc/misc.php new file mode 100644 index 0000000..1561511 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/settings/misc/misc.php @@ -0,0 +1,211 @@ + $tplData + */ + +use Duplicator\Core\Controllers\ControllersManager; +use Duplicator\Libs\Snap\SnapUtil; + +global $wp_version; +global $wpdb; + +$action_updated = null; +$action_response = __("Misc Settings Saved", 'duplicator'); + +//SAVE RESULTS +if (isset($_POST['action']) && $_POST['action'] == 'save') { + //Nonce Check + if (!isset($_POST['dup_settings_save_nonce_field']) || !wp_verify_nonce($_POST['dup_settings_save_nonce_field'], 'dup_settings_save')) { + die('Invalid token permissions to perform this request.'); + } + + DUP_Settings::Set('uninstall_settings', isset($_POST['uninstall_settings']) ? "1" : "0"); + DUP_Settings::Set('uninstall_files', isset($_POST['uninstall_files']) ? "1" : "0"); + DUP_Settings::Set('package_debug', isset($_POST['package_debug']) ? "1" : "0"); + + $usage_tracking = filter_input(INPUT_POST, 'usage_tracking', FILTER_VALIDATE_BOOLEAN); + DUP_Settings::setUsageTracking($usage_tracking); + + $amNotices = !SnapUtil::sanitizeBoolInput(INPUT_POST, 'dup_am_notices'); + DUP_Settings::Set('amNotices', $amNotices); + + if (isset($_REQUEST['trace_log_enabled'])) { + dup_log::trace("#### trace log enabled"); + // Trace on + + if (DUP_Settings::Get('trace_log_enabled') == 0) { + DUP_Log::DeleteTraceLog(); + } + + DUP_Settings::Set('trace_log_enabled', 1); + } else { + dup_log::trace("#### trace log disabled"); + + // Trace off + DUP_Settings::Set('trace_log_enabled', 0); + } + + DUP_Settings::Save(); + $action_updated = true; + DUP_Util::initSnapshotDirectory(); +} + +$trace_log_enabled = DUP_Settings::Get('trace_log_enabled'); +$uninstall_settings = DUP_Settings::Get('uninstall_settings'); +$uninstall_files = DUP_Settings::Get('uninstall_files'); +$package_debug = DUP_Settings::Get('package_debug'); +$actionUrl = ControllersManager::getMenuLink(ControllersManager::SETTINGS_SUBMENU_SLUG, 'misc'); +?> + + + +
        + + + + + + +

        + + +

        +
        + + + + + + + + + + + + + + + + + +
        + +
        +

        + /> + +

        +

        + /> +
        +

        +
        + + + + + + + > + + " + data-tooltip="render('admin_pages/settings/general/usage_tracking_tooltip', array(), false)); ?>" + data-tooltip-width="600" + > + + +
        + + /> + +
        + +

        +
        + + + + + + + + + +
        + /> + +
        + /> +
        +

        + '); + esc_html_e('WARNING: Only turn on this setting when asked to by support as tracing will impact performance.', 'duplicator'); + ?> +


        + +

        + +

        +
        + " + style="display: inline-block;" + /> +

        + +
        + + diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/welcome/features.php b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/features.php new file mode 100644 index 0000000..013eaa2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/features.php @@ -0,0 +1,105 @@ + $tplData + */ +?> + +
        +
        +

        +
        + +
        +
        + +
        +

        + +

        +
        + +
        + +
        +

        + +

        +
        + +
        + +
        +

        + +

        +
        + +
        + +
        +

        + +

        +
        + +
        + +
        +

        + +

        +
        + +
        + +
        +

        + +

        +
        + +
        + +
        +

        + +

        +
        + +
        + +
        +

        + +

        +
        +
        + +
        + + + +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/welcome/footer.php b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/footer.php new file mode 100644 index 0000000..4e467b7 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/footer.php @@ -0,0 +1,41 @@ + $tplData + */ +?> + + diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/welcome/intro.php b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/intro.php new file mode 100644 index 0000000..27a3374 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/intro.php @@ -0,0 +1,148 @@ + $tplData +*/ +?> +
        +
        + <?php esc_attr_e('Willie the Duplicator mascot', 'duplicator'); ?> +
        +
        +

        +
        +
        +
        + +
        +
        +
        + +
        +
        + + + +
        +
        +
        +
        +
        + + +
        + +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/welcome/testimonials.php b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/testimonials.php new file mode 100644 index 0000000..c4cd0b5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/testimonials.php @@ -0,0 +1,56 @@ + $tplData + */ +?> +
        +
        +

        + +
        + +

        + WP migration, I very much recommend this plugin!', + 'duplicator' + ), + array('b' => array()) + ); + ?> +

        +

        Karina Caidez, Website Designer

        +
        + +
        + +

        + WordPress migration & backup plugin I have ever used. I will be ' . + 'recommending this plugin to everyone I can.', + 'duplicator' + ), + array('b' => array()) + ); + ?> +

        +

        Blake Stiller, Website Development Instructor

        +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/welcome/upgrade-cta.php b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/upgrade-cta.php new file mode 100644 index 0000000..b4a72c2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/upgrade-cta.php @@ -0,0 +1,40 @@ + $tplData + */ +?> +
        +
        +
        +

        +
          + +
        • + +
        • + +
        +
        + +
        + + + +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/admin_pages/welcome/welcome.php b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/welcome.php new file mode 100644 index 0000000..41ebdb7 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/admin_pages/welcome/welcome.php @@ -0,0 +1,48 @@ + $tplData + */ +?> + +
        +
        + render( + 'admin_pages/welcome/intro', + array( + 'packageNonceUrl' => $packageNonceUrl + ) + ); + + TplMng::getInstance()->render('admin_pages/welcome/features'); + + TplMng::getInstance()->render('admin_pages/welcome/upgrade-cta'); + + TplMng::getInstance()->render('admin_pages/welcome/testimonials'); + + TplMng::getInstance()->render( + 'admin_pages/welcome/footer', + array( + 'packageNonceUrl' => $packageNonceUrl + ) + ); + ?> +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/mail/email_summary.php b/html/wp-content/plugins/duplicator/template/mail/email_summary.php new file mode 100644 index 0000000..d1e823b --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mail/email_summary.php @@ -0,0 +1,195 @@ + $tplData + */ + +?> + + + + + + <?php _e('Duplicator', 'duplicator'); ?> + + + > + > + > + + +
        > + > + > + + + > + + + + + +
        > + logo + > +
        > + > + > + + +
        > +
        >
        +

        > + +

        +

        > + + + +
        + +

        +

        > + ', + '' + ); + ?> +

        + 0) : ?> +

        > + +

        + > + > + + + + $packageInfo) : ?> + > + + + + +
        > + + > + +
        > + + > + + > + + + + + +
        + +

        > + +

        + +
        +
        > + tag with a link to the current website.', + 'duplicator' + ), + '' + . wp_specialchars_decode(get_bloginfo('name')) . '' + ); + ?> + + ', + '' + ); + ?> +
        +
        + + + diff --git a/html/wp-content/plugins/duplicator/template/mocks/db_reset/db_reset.php b/html/wp-content/plugins/duplicator/template/mocks/db_reset/db_reset.php new file mode 100644 index 0000000..1d4fdf3 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/db_reset/db_reset.php @@ -0,0 +1,47 @@ + $tplData + */ +?> +
        +

        + +

        +
        + getBySlug('db-reset-pro/db-reset-pro.php'); + + $tplMng->render( + 'admin_pages/about_us/about_us/extra_plugin_item', + array('plugin' => $plugin->skipLite() ? $plugin->getPro() : $plugin) + ); + ?> +
        +

        + The Simplest Database Reset Solution +

        +
        +
        + Database Reset Pro Screenshot +
        +
          +
        • One-Click Operation – No complex settings or configurations
        • +
        • Clear Visual Interface – Know exactly what will happen before you click
        • +
        • Instant Reset – Complete database reset in seconds, not minutes
        • +
        • No Learning Curve – If you can click a button, you can use this plugin
        • +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/mocks/import/content-popup.php b/html/wp-content/plugins/duplicator/template/mocks/import/content-popup.php new file mode 100644 index 0000000..ac243fe --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/import/content-popup.php @@ -0,0 +1,35 @@ + $tplData + */ +?> +

        + classic installer method ' . + 'on an empty site, Duplicator Pro now supports Drag and Drop migrations and site restores! Simply drag ' . + 'the bundled site Backup to the site you wish to overwrite.', + 'duplicator' + ), + array( + 'a' => array( + 'href' => array(), + 'rel' => array(), + 'target' => array(), + ) + ) + ), + LinkManager::getPostUrl('how-to-move-a-wordpress-website-to-a-new-host', 'import_popup', 'classic installer method') + ); + ?> +

        diff --git a/html/wp-content/plugins/duplicator/template/mocks/import/import.php b/html/wp-content/plugins/duplicator/template/mocks/import/import.php new file mode 100644 index 0000000..5322927 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/import/import.php @@ -0,0 +1,217 @@ + $tplData + */ +?> +
        +

        + +

        +
        +
        +
        +

        + + ', + '' + ); + ?> +

        +
        +
        + + +
        + + +
        +
        +render( + 'parts/Education/static-popup', + array( + 'title' => __('Overwrite a WordPress site with Drag and Drop Import!', 'duplicator'), + 'warning-text' => __('Drag and Drop Import is not available in Duplicator Lite!', 'duplicator'), + 'content-tpl' => 'mocks/import/content-popup', + 'upsell-url' => LinkManager::getCampaignUrl('blurred-mocks', 'Import') + ), + true +); ?> diff --git a/html/wp-content/plugins/duplicator/template/mocks/recovery/content-popup.php b/html/wp-content/plugins/duplicator/template/mocks/recovery/content-popup.php new file mode 100644 index 0000000..76f5b52 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/recovery/content-popup.php @@ -0,0 +1,19 @@ + $tplData + */ +?> +

        + +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/mocks/recovery/recovery.php b/html/wp-content/plugins/duplicator/template/mocks/recovery/recovery.php new file mode 100644 index 0000000..142026f --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/recovery/recovery.php @@ -0,0 +1,123 @@ + $tplData + */ +?> + + +render( + 'parts/Education/static-popup', + array( + 'title' => __('Rollback your sites with Recovery Points!', 'duplicator'), + 'warning-text' => __('Recovery Points are not supported in Duplicator Lite!', 'duplicator'), + 'content-tpl' => 'mocks/recovery/content-popup', + 'upsell-url' => LinkManager::getCampaignUrl('blurred-mocks', 'Recovery') + ), + true +); ?> diff --git a/html/wp-content/plugins/duplicator/template/mocks/schedule/content-popup.php b/html/wp-content/plugins/duplicator/template/mocks/schedule/content-popup.php new file mode 100644 index 0000000..fd14c53 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/schedule/content-popup.php @@ -0,0 +1,28 @@ + $tplData + */ +?> +

        + +

        +

        + +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/mocks/schedule/schedules.php b/html/wp-content/plugins/duplicator/template/mocks/schedule/schedules.php new file mode 100644 index 0000000..5e6c9f9 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/schedule/schedules.php @@ -0,0 +1,285 @@ + $tplData + */ +?> +
        +

        +
        + + + + + + + + +
        + + + + + + +
        + Add New +
        +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NameStorageRuns NextLast RanActiveRecovery
        + + + Daily Schedule - Default Local + DefaultJanuary 1, 2023 0:00 - Daily + December 31, 2022 0:00 + Yes + Available +
        + + + Weekly Schedule - DropBox + DropBoxJanuary 8, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Monthly Schedule - GDrive + Google DriveFebruary 1, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Monthly Schedule - All Storages + Local, Google Drive, FTP, SFTP,
        S3, OneDrive, DropBox
        February 1, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Daily Schedule - Default Local + DefaultJanuary 1, 2023 0:00 - Daily + December 31, 2022 0:00 + Yes + Available +
        + + + Weekly Schedule - DropBox + DropBoxJanuary 8, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Monthly Schedule - GDrive + Google DriveFebruary 1, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Monthly Schedule - All Storages + Local, Google Drive, FTP, SFTP,
        S3, OneDrive, DropBox
        February 1, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Daily Schedule - Default Local + DefaultJanuary 1, 2023 0:00 - Daily + December 31, 2022 0:00 + Yes + Available +
        + + + Weekly Schedule - DropBox + DropBoxJanuary 8, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Monthly Schedule - GDrive + Google DriveFebruary 1, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + + + Monthly Schedule - All Storages + Local, Google Drive, FTP, SFTP,
        S3, OneDrive, DropBox
        February 1, 2023 0:00 - Weekly + January 1, 2023 0:00 + Yes + Available +
        + Total: 12 | Active: 12 | Time: 00:00:01
        +
        +
        +
        +render( + 'parts/Education/static-popup', + array( + 'title' => __('Automate your workflow with scheduled backups!', 'duplicator'), + 'warning-text' => __('Duplicator Lite does not support scheduled backups!', 'duplicator'), + 'content-tpl' => 'mocks/schedule/content-popup', + 'upsell-url' => LinkManager::getCampaignUrl('blurred-mocks', 'Schedules') + ) +); +?> diff --git a/html/wp-content/plugins/duplicator/template/mocks/settings/access/capabilities.php b/html/wp-content/plugins/duplicator/template/mocks/settings/access/capabilities.php new file mode 100644 index 0000000..b0e826f --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/settings/access/capabilities.php @@ -0,0 +1,129 @@ + $tplData + */ +?> +

        +
        +
        +

        +
        +
        +
        + +

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        +
        +render( + 'parts/Education/static-popup', + array( + 'title' => __('Advanced Backup Permissions', 'duplicator'), + 'warning-text' => __('Advanced Backup Permissions are not available in Duplicator Lite!', 'duplicator'), + 'content-tpl' => 'mocks/settings/access/content-popup', + 'upsell-url' => LinkManager::getCampaignUrl('blurred-mocks', 'Settings Access Tab') + ), + true +); ?> diff --git a/html/wp-content/plugins/duplicator/template/mocks/settings/access/content-popup.php b/html/wp-content/plugins/duplicator/template/mocks/settings/access/content-popup.php new file mode 100644 index 0000000..d487981 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/settings/access/content-popup.php @@ -0,0 +1,23 @@ + $tplData + */ +?> +

        + +

        diff --git a/html/wp-content/plugins/duplicator/template/mocks/storage/popup.php b/html/wp-content/plugins/duplicator/template/mocks/storage/popup.php new file mode 100644 index 0000000..383afa3 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/storage/popup.php @@ -0,0 +1,41 @@ + $tplData + */ +?> + +
        + " /> + +
          + +
        • + + + +   + +
        • + +
        + +
        +
        +

        + + + +

        +
        + diff --git a/html/wp-content/plugins/duplicator/template/mocks/storage/storage.php b/html/wp-content/plugins/duplicator/template/mocks/storage/storage.php new file mode 100644 index 0000000..1965c50 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/storage/storage.php @@ -0,0 +1,172 @@ + $tplData + */ +?> + +

        +
        +

        +

        +

        + + + +

        +
        + + + + + + + + +
        + + + + + + + +
        + +
        +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + + +   +
        + + + + + + + + <?php echo $storage['label']; ?> + + +
        +
        +
        + + diff --git a/html/wp-content/plugins/duplicator/template/mocks/templates/content-popup.php b/html/wp-content/plugins/duplicator/template/mocks/templates/content-popup.php new file mode 100644 index 0000000..e0057f1 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/templates/content-popup.php @@ -0,0 +1,28 @@ + $tplData + */ +?> +

        + +

        +

        + +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/mocks/templates/templates.php b/html/wp-content/plugins/duplicator/template/mocks/templates/templates.php new file mode 100644 index 0000000..e40cc6f --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/templates/templates.php @@ -0,0 +1,200 @@ + $tplData + */ +?> +
        + + + + + + + + +
        + + + +
        + Add New +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        NameRecovery
        + + + Default + + + Available + +  
        + + + Full site backup + + + Available + +  
        + + + Database only backup + + + Disabled + +  
        + + + Uploads folder filtered + + + Available + +  
        + + + Non-WP tables filtered + + + Disabled + +  
        + + + Full site backup + + + Available + +  
        + + + Database only backup + + + Disabled + +  
        + + + Uploads folder filtered + + + Available + +  
        + + + Non-WP tables filtered + + + Disabled + +  
        + Total: 2 +
        +
        +render( + 'parts/Education/static-popup', + array( + 'title' => __('Easily customize your backups with templates!', 'duplicator'), + 'warning-text' => __('Templates are not available in Duplicator Lite!', 'duplicator'), + 'content-tpl' => 'mocks/templates/content-popup', + 'upsell-url' => LinkManager::getCampaignUrl('blurred-mocks', 'Templates') + ), + true +); ?> diff --git a/html/wp-content/plugins/duplicator/template/mocks/transfer/content-popup.php b/html/wp-content/plugins/duplicator/template/mocks/transfer/content-popup.php new file mode 100644 index 0000000..1e22416 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/transfer/content-popup.php @@ -0,0 +1,19 @@ + $tplData + */ +?> +

        + +

        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/mocks/transfer/transfer.php b/html/wp-content/plugins/duplicator/template/mocks/transfer/transfer.php new file mode 100644 index 0000000..6efe45a --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/mocks/transfer/transfer.php @@ -0,0 +1,236 @@ + $tplData + */ +?> + +
        + +
        +

        + Manual Transfer +

        +
        +
        + +
        +
        +

        Step 1: Choose Location

        + + + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        TypeNameLocation
        + + + + + + +  DropBox + + https://dropbox.com/home
        + + + + + + +  Google Drive + + google://Duplicator Backups/duplicator.com
        + + + + + + +  OneDrive + + Not Authenticated
        + + + + + + +  FTP + + ftp://duplicator.com:21/duplicator.com
        + + + + + + +  SFTP + + duplicator.com:22
        + + [Create New Storage] + +
        + +
        + + +
        +

        + Step 2: Transfer Files + +

        + + + +
        + +
        +
        + + +
        +
        + + Transfer Log +
        +
        + + + + + + + + + + + + + + + + + + + + + + +
        StartedStoppedStatusTypeDescription
        Sun, 01 Jan 00:00:00Sun, 01 Jan 00:01:00SucceededDropboxTransferred Backup to Dropbox folder duplicator.com
        Log Items: 1
        +
        +
        +
        +render( + 'parts/Education/static-popup', + array( + 'title' => __('Manually transfer backups to remote storages!', 'duplicator'), + 'warning-text' => __('Remote storages are not available in Duplicator Lite!', 'duplicator'), + 'content-tpl' => 'mocks/transfer/content-popup', + 'upsell-url' => LinkManager::getCampaignUrl('blurred-mocks', 'Details Transfer') + ), + true +); ?> diff --git a/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/package-create-section.php b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/package-create-section.php new file mode 100644 index 0000000..9275ab5 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/package-create-section.php @@ -0,0 +1,49 @@ + $tplData + */ + +$tooltipTitle = esc_attr__('Backup creation', 'duplicator'); +$tooltipContent = esc_attr__( + 'This will create a new Backup. If a Backup is currently running then this button will be disabled.', + 'duplicator' +); + +?> +
        + + + + + + + + + + + +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/recently-packages.php b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/recently-packages.php new file mode 100644 index 0000000..b2a75dd --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/recently-packages.php @@ -0,0 +1,49 @@ + $tplData + * @var DUP_Package[] $packages + */ +$packages = $tplData['packages']; + +?> +
        +

        + +

        + 0) { ?> +
          + Created); + $createdDate = date_i18n(get_option('date_format'), $createdTime); + $createdHours = date_i18n(get_option('time_format'), $createdTime); + + ?> +
        • + + Name); ?> + - +
        • + +
        + +

        + +

        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/recommended-section.php b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/recommended-section.php new file mode 100644 index 0000000..941e2e0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/recommended-section.php @@ -0,0 +1,55 @@ + $tplData + * @var array{name: string,slug: string,more: string,pro: array{file: string}} $plugin + */ +$plugin = $tplData['plugin']; + +/** @var string */ +$installUrl = $tplData['installUrl']; +$moreUrl = $plugin['more'] . '?' . http_build_query(array( + 'utm_medium' => 'link', + 'utm_source' => 'duplicatorplugin', + 'utm_campaign' => 'duplicatordashboardwidget' +)); + +?> + diff --git a/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/sections-section.php b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/sections-section.php new file mode 100644 index 0000000..b45370e --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/DashboardWidget/sections-section.php @@ -0,0 +1,107 @@ + $tplData + */ + +$templatesURL = ControllersManager::getMenuLink( + ControllersManager::TOOLS_SUBMENU_SLUG, + 'templates' +); +$recoveryURl = ControllersManager::getMenuLink( + ControllersManager::TOOLS_SUBMENU_SLUG, + 'recovery' +); + +?> +
        +
          +
        • + + + : + + + + + - : + + +
        • +
        • + +
        • +
        • + +
        • +
        • + + + + +
        • +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/Education/callout-cta.php b/html/wp-content/plugins/duplicator/template/parts/Education/callout-cta.php new file mode 100644 index 0000000..8202470 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/Education/callout-cta.php @@ -0,0 +1,82 @@ + $tplData + */ +?> +
        + +
        +

        + +

        +

        + array( + 'class' => array(), + 'aria-hidden' => array(), + ), + ) + ), + str_repeat('', 5) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + ); + ?> +

        +
        +
          + +
        • + + + +
        • + +
        +

        + + + +

        +

        + Bonus: Duplicator Lite users get %1$d%% off regular price,' . + 'automatically applied at checkout.', + 'duplicator' + ), + DUP_Constants::UPSELL_DEFAULT_DISCOUNT + ); + ?> +

        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/Education/did-you-know-blurb.php b/html/wp-content/plugins/duplicator/template/parts/Education/did-you-know-blurb.php new file mode 100644 index 0000000..f27c1cb --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/Education/did-you-know-blurb.php @@ -0,0 +1,26 @@ + $tplData + */ +?> +
        + + + + + +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/Education/packages-bottom-bar.php b/html/wp-content/plugins/duplicator/template/parts/Education/packages-bottom-bar.php new file mode 100644 index 0000000..49b2127 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/Education/packages-bottom-bar.php @@ -0,0 +1,46 @@ + $tplData + */ +?> + + +
        +
        + +
        +
        +

        +

        + +

        +
        +
        + + + +
        +
        + +
        +
        + + diff --git a/html/wp-content/plugins/duplicator/template/parts/Education/static-popup.php b/html/wp-content/plugins/duplicator/template/parts/Education/static-popup.php new file mode 100644 index 0000000..4cbd602 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/Education/static-popup.php @@ -0,0 +1,34 @@ + $tplData + */ +?> +
        +
        + +
        +
        +

        + +

        + render($tplData['content-tpl']); ?> +
        +
        + + + +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/Education/subscribe-form.php b/html/wp-content/plugins/duplicator/template/parts/Education/subscribe-form.php new file mode 100644 index 0000000..d2481d4 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/Education/subscribe-form.php @@ -0,0 +1,31 @@ + $tplData + */ +?> +
        +
        + +
        +
        + +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/Notifications/main.php b/html/wp-content/plugins/duplicator/template/parts/Notifications/main.php new file mode 100644 index 0000000..453b1c6 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/Notifications/main.php @@ -0,0 +1,45 @@ + $tplData + */ + +defined('ABSPATH') || exit; + +?> +
        +
        +
        + + +
        +
        +
        + +
        + + + 1) : ?> + + + +
        + render('parts/Notifications/single-message', $notification); + } ?> +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/Notifications/single-message.php b/html/wp-content/plugins/duplicator/template/parts/Notifications/single-message.php new file mode 100644 index 0000000..4ed8465 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/Notifications/single-message.php @@ -0,0 +1,36 @@ + $tplData + */ + +defined('ABSPATH') || exit; +?> +
        +

        + + + > + + + +

        +
        + +
        + + > + + + +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/admin-logo-header.php b/html/wp-content/plugins/duplicator/template/parts/admin-logo-header.php new file mode 100644 index 0000000..222d213 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/admin-logo-header.php @@ -0,0 +1,38 @@ + $tplData + */ +$helpPageUrl = SnapJson::jsonEncode(Help::getHelpPageUrl()); +require_once(DUPLICATOR_PLUGIN_PATH . '/assets/js/javascript.php'); +?> + +
        +
        + Duplicator Logo + +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/cross_promotion/item.php b/html/wp-content/plugins/duplicator/template/parts/cross_promotion/item.php new file mode 100644 index 0000000..59b8108 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/cross_promotion/item.php @@ -0,0 +1,26 @@ + $tplData + * @var ExtraItem $plugin + */ + +$plugin = $tplData['plugin']; +?> +
        + <?php echo esc_attr($plugin->name); ?> logo +
        +
        + name); ?> +
        +

        desc); ?>

        + +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/cross_promotion/list.php b/html/wp-content/plugins/duplicator/template/parts/cross_promotion/list.php new file mode 100644 index 0000000..194176d --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/cross_promotion/list.php @@ -0,0 +1,41 @@ + $tplData + */ + +defined('ABSPATH') || die(); + +if (!current_user_can('install_plugins')) { + return; +} + +/** @var ExtraItem[] $plugins */ +$plugins = $tplData['plugins']; +/** @var int $limit */ +$limit = $tplData['limit']; +?> +
        +

        + +

        +
        + $plugin) { + if ($i > $limit - 1) { + break; + } + + $tplMng->render( + 'parts/cross_promotion/item', + array('plugin' => $plugin) + ); + } + ?> +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/filters/package_components.php b/html/wp-content/plugins/duplicator/template/parts/filters/package_components.php new file mode 100644 index 0000000..59953b0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/filters/package_components.php @@ -0,0 +1,344 @@ + $tplData + */ + +$archiveFilterPaths = trim($tplData['package']->Archive->FilterDirs . ";" . $tplData['package']->Archive->FilterFiles, ";"); +$archiveFilterPaths = str_replace(';', ";\n", $archiveFilterPaths); +$archiveFilterExtensions = $tplData['package']->Archive->FilterExts; +$packageComponentsTooltip = __( + "Backup components allow you to include/exclude differents part of your WordPress installation in the Backup.

        " . + "Database: Include the database in the Backup.
        " . + "Plugins: Include the plugins in the Backup. With the 'active only' option enabled, only active plugins will be included in the Backup.
        " . + "Themes: Include the themes in the Backup. With the 'active only' option enabled, only active themes will be included in the Backup.
        " . + "Media: Include the 'uploads' folder.
        " . + "Other: Include non-WordPress files and folders in the root directory.
        ", + 'duplicator' +); +$pathFiltersTooltip = __("File filters allow you to exclude files and folders from the Backup. To enable path and extension filters check the " . + "checkbox. Enter the full path of the files and folders you want to exclude from the Backup as a semicolon (;) seperated list.", "duplicator"); +$extensionFilterTooltip = __("File extension filters allow you to exclude files with certain file extensions from the Backup e.g. zip;rar;pdf etc. " . + "Enter the file extensions you want to exclude from the Backup as a semicolon (;) seperated list.", "duplicator"); +?> + +
        +
        +
        + + + + +
        +
        +
        + Archive->ExportOnlyDB); ?> + > + + Archive->ExportOnlyDB); ?> + data-parsley-multiple="auto-select-components" + > + + + +
        +
        +
          +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        +
        +
        +
        +
        + () + + + +
        + +
        + + + + + +
        + +
        +
        + Overview:
        This advanced option excludes all files from the Backup. Only the database and a copy of the installer.php " + . "will be included in the archive.zip file. The option can be used for backing up and moving only the database.", + 'duplicator' + ), + array( + 'b' => array(), + 'br' => array(), + ) + ); + echo '

        '; + + echo wp_kses( + __( + " Notice:
        " + . "Installing only the database over an existing site may have unintended consequences. " + . "Be sure to know the state of your system before installing the database without the associated files. ", + 'duplicator' + ), + array( + 'b' => array(), + 'i' => array('class'), + 'br' => array() + ) + ); + + esc_html_e( + "For example, if you have WordPress 5.6 on this site and you copy this site's database to a host that has WordPress 5.8 files " + . "then the source code of the files will not be in sync with the database causing possible errors. " + . "This can also be true of plugins and themes. " + . "When moving only the database be sure to know the database will be compatible with " + . "ALL source code files. Please use this advanced feature with caution!", + 'duplicator' + ); + + echo '

        '; + + echo wp_kses( + __("Install Time:
        When installing a database only Backup please visit the ", 'duplicator'), + array( + 'b' => array(), + 'br' => array(), + ) + ); + ?> + + + +
        +
        +
        +
        + + Media Only and Custom options are not included in Duplicator Lite. ' . + 'To enable advanced options please %1$supgrade to Pro%2$s.', + '%1$s and %2$s represents the opening and closing HTML tags for an anchor or link.', + 'duplicator' + ), + '', + '' + ); + ?> + +
        + diff --git a/html/wp-content/plugins/duplicator/template/parts/help/article-list.php b/html/wp-content/plugins/duplicator/template/parts/help/article-list.php new file mode 100644 index 0000000..76d6f97 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/help/article-list.php @@ -0,0 +1,33 @@ + $tplData + */ + +/** @var Article[] $articles p*/ +$articles = $tplData['articles']; +$listClass = isset($tplData['list_class']) ? 'class="' . $tplData['list_class'] . '"' : ''; +?> + 0) : ?> + + diff --git a/html/wp-content/plugins/duplicator/template/parts/help/category-list.php b/html/wp-content/plugins/duplicator/template/parts/help/category-list.php new file mode 100644 index 0000000..348f474 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/help/category-list.php @@ -0,0 +1,61 @@ + $tplData + */ + +/** @var Category[] $categories */ +$categories = $tplData['categories']; +if (empty($categories)) : ?> +

        + ', + '' + ); + ?> +

        + +
          + +
        • +
          + + getName()); ?> + +
          + getChildren()) > 0) { ?> + render('parts/help/category-list', ['categories' => $category->getChildren()]); + } ?> + getArticleCount() > 0) : ?> + render( + 'parts/help/article-list', + [ + 'articles' => Help::getInstance()->getArticlesByCategory($category->getId()), + 'list_class' => 'duplicator-help-article-list', + ] + ); ?> + +
        • + + +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/help/main.php b/html/wp-content/plugins/duplicator/template/parts/help/main.php new file mode 100644 index 0000000..0527ca0 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/help/main.php @@ -0,0 +1,247 @@ + $tplData + */ +?> + +
        +
        + +
        +
        + +
        + getArticlesByTag($tplData['tag'])) > 0) : ?> +

        + render('parts/help/article-list', ['articles' => Help::getInstance()->getArticlesByTag($tplData['tag'])]); ?> + +
        +
        + render('parts/help/category-list', ['categories' => Help::getInstance()->getTopLevelCategories()]); ?> +
        + +
        +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/notice-bar.php b/html/wp-content/plugins/duplicator/template/parts/notice-bar.php new file mode 100644 index 0000000..4edddce --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/notice-bar.php @@ -0,0 +1,67 @@ + $tplData + */ +?> + +
        + + You\'re using Duplicator Lite. To unlock more features consider ' . + 'upgrading to Pro', + 'duplicator' + ), + array( + 'a' => array( + 'href' => array(), + 'rel' => array(), + 'target' => array(), + ), + 'strong' => array(), + ) + ), + esc_url(LinkManager::getCampaignUrl('lite-upgrade-bar', $tplData['utm_content'])) + ); + ?> + → + + +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/notices/drm_multisite_msg.php b/html/wp-content/plugins/duplicator/template/parts/notices/drm_multisite_msg.php new file mode 100644 index 0000000..0c4d465 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/notices/drm_multisite_msg.php @@ -0,0 +1,37 @@ + $tplData + */ + + +$upgradeUrl = LinkManager::getCampaignUrl('lite-multisite-notice', 'Upgrade now!') +?> + +
        +

        + +

        +

        + +

        + +
        diff --git a/html/wp-content/plugins/duplicator/template/parts/plugin-footer.php b/html/wp-content/plugins/duplicator/template/parts/plugin-footer.php new file mode 100644 index 0000000..a80a221 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/plugin-footer.php @@ -0,0 +1,82 @@ + $tplData + */ + +$facebookIcon = ''; // phpcs:disable Generic.Files.LineLength.TooLong +$xIcon = ''; // phpcs:disable Generic.Files.LineLength.TooLong +$youtubeIcon = ''; // phpcs:disable Generic.Files.LineLength.TooLong +$links = [ + [ + 'url' => 'https://wordpress.org/support/plugin/duplicator/', + 'text' => __('Support', 'duplicator'), + ], + [ + 'url' => LinkManager::getDocUrl('', 'plugin-lite-footer'), + 'text' => __('Docs', 'duplicator') + ], + [ + 'url' => 'https://duplicator.com/migration-services/', + 'text' => __('Migration Services', 'duplicator') + ], + [ + 'url' => ControllersManager::getMenuLink(ControllersManager::ABOUT_US_SUBMENU_SLUG, AboutUsController::ABOUT_US_TAB), + 'text' => __('Free Plugins', 'duplicator'), + ], +]; +$count = count($links); + +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/template/parts/tools/server_settings_table.php b/html/wp-content/plugins/duplicator/template/parts/tools/server_settings_table.php new file mode 100644 index 0000000..f08a837 --- /dev/null +++ b/html/wp-content/plugins/duplicator/template/parts/tools/server_settings_table.php @@ -0,0 +1,82 @@ + $tplData + */ +$serverSettings = $tplData['serverSettings']; +?> + + + + + + + + + + + + +
        + + + + + + + + + + + + + [ + 'href' => [], + 'target' => [], + ], + ] + ); ?> + + + + +

        + + + [ + 'href' => [], + 'target' => [], + ], + ] + ); ?> + + +

        + + + + + +
        diff --git a/html/wp-content/plugins/duplicator/uninstall.php b/html/wp-content/plugins/duplicator/uninstall.php new file mode 100644 index 0000000..98e829a --- /dev/null +++ b/html/wp-content/plugins/duplicator/uninstall.php @@ -0,0 +1,167 @@ +base_prefix . self::PACKAGES_TABLE_NAME); + $wpdb->query("DROP TABLE IF EXISTS {$tableName}"); + + $fsystem = new WP_Filesystem_Direct(true); + $fsystem->rmdir(self::getSsdirPathWpCont(), true); + $fsystem->rmdir(self::getSsdirPathLegacy(), true); + } + + /** + * Remove plugins settings + * + * @return void + */ + private static function removeSettings() + { + if (get_option(self::UNINSTALL_SETTINGS_OPTION_KEY) != true) { + return; + } + + self::deleteUserMetaKeys(); + self::deleteOptions(); + self::deleteTransients(); + } + + /** + * Delete all users meta key + * + * @return void + */ + private static function deleteUserMetaKeys() + { + /** @var wpdb */ + global $wpdb; + + $wpdb->query("DELETE FROM `{$wpdb->usermeta}` WHERE meta_key REGEXP '^duplicator_(?!pro_)'"); + } + + /** + * Delete all options + * + * @return void + */ + private static function deleteOptions() + { + /** @var wpdb */ + global $wpdb; + + $optionsTableName = esc_sql($wpdb->base_prefix . "options"); + $dupOptionNames = $wpdb->get_col( + "SELECT `option_name` FROM `{$optionsTableName}` WHERE `option_name` REGEXP '^duplicator_(?!pro_)'" + ); + + foreach ($dupOptionNames as $dupOptionName) { + delete_option($dupOptionName); + } + } + + /** + * Delete all transients + * + * @return void + */ + private static function deleteTransients() + { + global $wpdb; + + $optionsTableName = esc_sql($wpdb->base_prefix . "options"); + $dupOptionTransientNames = $wpdb->get_col( + "SELECT `option_name` FROM `{$optionsTableName}` WHERE `option_name` REGEXP '^_transient_duplicator_(?!pro_)'" + ); + + foreach ($dupOptionTransientNames as $dupOptionTransientName) { + delete_transient(str_replace("_transient_", "", $dupOptionTransientName)); + } + } +} + +DuplicatorLiteUninstall::uninstall(); diff --git a/html/wp-content/plugins/duplicator/views/inc.header.php b/html/wp-content/plugins/duplicator/views/inc.header.php new file mode 100644 index 0000000..6578ffe --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/inc.header.php @@ -0,0 +1,13 @@ +" . esc_html($title) . ""; +} diff --git a/html/wp-content/plugins/duplicator/views/index.php b/html/wp-content/plugins/duplicator/views/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/index.php @@ -0,0 +1,3 @@ + + + +
        + +
        diff --git a/html/wp-content/plugins/duplicator/views/packages/details/controller.php b/html/wp-content/plugins/duplicator/views/packages/details/controller.php new file mode 100644 index 0000000..41b9fa2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/details/controller.php @@ -0,0 +1,89 @@ +Status < 100); +?> + + + +
        + Name) + ) + ); + ?> + + +
        +

        + and respectively', + 'duplicator' + ), + '', + '' + ); + ?> + and respectively', + 'duplicator' + ), + '', + '', + '', + '' + ); + ?> +

        +
        + + + + + + render('mocks/transfer/transfer', array(), true); + break; + } + ?> +
        diff --git a/html/wp-content/plugins/duplicator/views/packages/details/detail.php b/html/wp-content/plugins/duplicator/views/packages/details/detail.php new file mode 100644 index 0000000..eb3de28 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/details/detail.php @@ -0,0 +1,612 @@ +getPackageFileDownloadInfo(DUP_PackageFileType::Archive); +$logDownloadInfo = $package->getPackageFileDownloadInfo(DUP_PackageFileType::Log); +$installerDownloadInfo = $package->getInstallerDownloadInfo(); +$archiveDownloadInfoJson = SnapJson::jsonEncodeEscAttr($archiveDownloadInfo); +$logDownloadInfoJson = SnapJson::jsonEncodeEscAttr($logDownloadInfo); +$installerDownloadInfoJson = SnapJson::jsonEncodeEscAttr($installerDownloadInfo); +$showLinksDialogJson = SnapJson::jsonEncodeEscAttr(array( + "archive" => $archiveDownloadInfo["url"], + "log" => $logDownloadInfo["url"], +)); + +$debug_on = DUP_Settings::Get('package_debug'); +$mysqldump_on = DUP_Settings::Get('package_mysqldump') && DUP_DB::getMySqlDumpPath(); +$mysqlcompat_on = isset($Package->Database->Compatible) && strlen($Package->Database->Compatible); +$mysqlcompat_on = ($mysqldump_on && $mysqlcompat_on) ? true : false; +$dbbuild_mode = $package->Database->info->buildMode; +$archive_build_mode = ($package->Archive->Format === 'ZIP') ? 'ZipArchive (zip)' : 'DupArchive (daf)'; +$dup_install_secure_on = isset($package->Installer->OptsSecureOn) ? $package->Installer->OptsSecureOn : 0; +$dup_install_secure_pass = isset($package->Installer->OptsSecurePass) ? DUP_Util::installerUnscramble($package->Installer->OptsSecurePass) : ''; +$installerNameMode = DUP_Settings::Get('installer_name_mode'); +$storage_position = DUP_Settings::Get('storage_position'); + +$currentStoreURLPath = DUP_Settings::getSsdirUrl(); +$installerSecureName = $package->getInstDownloadName(true); +$installerDirectLink = "{$currentStoreURLPath}/" . pathinfo($installerSecureName, PATHINFO_FILENAME) . DUP_Installer::INSTALLER_SERVER_EXTENSION; +?> + + + + +

        + + +
        +   + +
        + + +
        +
        + +
        +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + Name); ?> + +
        + + + + + + + + + + + + + +
        ID); ?>
        Hash); ?>
        NameHash); ?>
        +
        +
        Notes) ? $package->Notes : esc_html__('- no notes -', 'duplicator') ?>
        Created) ?>
        + + Version); ?> + +
        + + + + + + + + + + + + + +
        VersionWP) ? esc_html($package->VersionWP) : esc_html__('- unknown -', 'duplicator') ?>
        VersionPHP) ? esc_html($package->VersionPHP) : esc_html__('- unknown -', 'duplicator') ?>
        + VersionDB) ? esc_html($package->VersionDB) : esc_html__('- unknown -', 'duplicator') ?> | + Database->Comments) ? esc_html($package->Database->Comments) : esc_html__('- unknown -', 'duplicator') ?> +
        +
        +
        Runtime) ? esc_html($package->Runtime) : esc_html__("error running", 'duplicator'); ?>
        Status >= 100) ? esc_html__('completed', 'duplicator') : esc_html__('in-complete', 'duplicator') ?>
        WPUser) ? esc_html($package->WPUser) : esc_html__('- unknown -', 'duplicator') ?>
        +
        + + '; + } else { + $installBtnTooltip = __('Download basic installer (installer.php)', 'duplicator'); + $installBtnIcon = ''; + } + ?> +
        + + +

        +
        + + + + + + +
        + + + + + + + + + + + + + + + + + +
        + " class="link-style"> + Archive->File); ?> + +
        + " target="file_results" class="link-style"> + + +
        + +
        + +
        +
        +
        + + + + + + +
        +
        + + +
        +
        +
        + + + + + + + + + + + + + + + + + + + +
        + + + + + + + + + '; + echo DUP_Settings:: getSsdirUrl(); + ?> +
        +
        + +  ' . 'Amazon', + ' ' . 'Dropbox', + ' ' . 'Google Drive', + ' ' . 'OneDrive', + ' ' . 'FTP/SFTP' + ); ?> + + + + " + data-tooltip=""> + + +
        +
        + +
        +
        + + +
        +
        + +
        +
        +
        + + +
        + + +
        + + + + + + + + Archive->ExportOnlyDB) : ?> + + + + + + + + + + +
        + Archive->FilterOn == 1 ? esc_html__('On', 'duplicator') : esc_html__('Off', 'duplicator'); ?> +
        +
        + Archive->FilterDirs) + ? str_replace(';', ";\n", $package->Archive->FilterDirs) + : esc_html__('- no filters -', 'duplicator'); + ?> + +
        + +
        +
        + Archive->FilterExts) && strlen($package->Archive->FilterExts) + ? esc_html($package->Archive->FilterExts) + : esc_html__('- no filters -', 'duplicator'); + ?> +
        + +
        +
        + Archive->FilterFiles) + ? str_replace(';', ";\n", $package->Archive->FilterFiles) + : esc_html__('- no filters -', 'duplicator'); + ?> + +
        +
        +

        + + +
        + + +
        + + + + + + + + + + + + + + + + + + + + + +
        Database->info->name); ?>
        Database->Type); ?>
        + + +
        + + + [] + + +
        Database->FilterOn == 1 ? esc_html__('On', 'duplicator') : esc_html__('Off', 'duplicator'); ?>
          +
        + Database->FilterTables) && strlen($package->Database->FilterTables) + ? str_replace(',', "
        \n", $package->Database->FilterTables) + : esc_html__('- no filters -', 'duplicator'); + ?> +
        +
        +
        + + + +
        +
        + +
        +
        +
        + + + + + + + + + + + + + + + +
        +
        +
        + + + +
        +
        + + +
        +
        +

        + + + + + + + + + + + + + + + + + +
        +
        +
        Installer->OptsDBHost) ? esc_html($package->Installer->OptsDBHost) : esc_html__('- not set -', 'duplicator') ?>
        Installer->OptsDBName) ? esc_html($package->Installer->OptsDBName) : esc_html__('- not set -', 'duplicator') ?>
        Installer->OptsDBUser) ? esc_html($package->Installer->OptsDBUser) : esc_html__('- not set -', 'duplicator') ?>
        +
        +
        + + +
        + []
        + +
        + + + + diff --git a/html/wp-content/plugins/duplicator/views/packages/details/index.php b/html/wp-content/plugins/duplicator/views/packages/details/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/details/index.php @@ -0,0 +1,3 @@ +%s %s.", $txt_invalid_msg1, $txt_invalid_msg2, $txt_invalid_lnk)); + } + break; + case 'new2': + if (!wp_verify_nonce($_GET['_wpnonce'], 'new2-package')) { + die(printf("%s
        %s %s.", $txt_invalid_msg1, $txt_invalid_msg2, $txt_invalid_lnk)); + } + break; + case 'new3': + if (!wp_verify_nonce($_GET['_wpnonce'], 'new3-package')) { + die(printf("%s
        %s %s.", $txt_invalid_msg1, $txt_invalid_msg2, $txt_invalid_lnk)); + } + break; +} +?> + + + + diff --git a/html/wp-content/plugins/duplicator/views/packages/main/index.php b/html/wp-content/plugins/duplicator/views/packages/main/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/main/index.php @@ -0,0 +1,3 @@ + '>=', 'status' => DUP_PackageStatus::COMPLETE))); // total packages completed +$active_package_present = DUP_Package::isPackageRunning(); +$is_mu = is_multisite(); + +$package_running = false; +global $packageTablerowCount; +$packageTablerowCount = 0; + +if (DUP_Settings::Get('installer_name_mode') == DUP_Settings::INSTALLER_NAME_MODE_SIMPLE) { + $packageExeNameModeMsg = __("When clicking the Installer download button, the 'Save as' dialog is currently defaulting the name to 'installer.php'. " + . "To improve the security and get more information, go to: Settings > Backups Tab > Installer > Name option or click on the gear icon at the top of this page.", 'duplicator'); +} else { + $packageExeNameModeMsg = __("When clicking the Installer download button, the 'Save as' dialog is defaulting the name to '[name]_[hash]_[time]_installer.php'. " + . "This is the secure and recommended option. For more information, go to: Settings > Backups Tab > Installer > Name or click on the gear icon at the top of this page.

        " + . "To quickly copy the hashed installer name, to your clipboard use the copy icon link or click the installer name and manually copy the selected text.", 'duplicator'); +} +?> + + + +
        + + + + + + + +
        + + " + onclick="Duplicator.Pack.ConfirmDelete()" + > + + " onclick="Duplicator.Pack.showHelp()"> + + + " + > + + + " + > + + + + " + > + + + "> + + + + + + + +
        + + + + + + + + + + + +
         
        +
        + +
        +
        +
        > +
        + + + +
        + '; + echo ' '; + esc_html_e('Duplicator Lite does not officially support WordPress multisite.', 'duplicator'); + echo "
        "; + esc_html_e('We strongly recommend upgrading to ', 'duplicator'); + echo " [" . esc_html__('Duplicator Pro', 'duplicator') . "]."; + echo '
        '; + } + ?> +
         
        + +
         
        + + + + + + + + + + + + + + + + + isRunning(); + $pack_name = $Package->Name; + $pack_archive_size = $Package->getArchiveSize(); + $pack_perc = $Package->Status; + $pack_dbonly = $Package->Archive->ExportOnlyDB; + $pack_build_mode = ($Package->Archive->Format === 'ZIP') ? true : false; + + //Links + $uniqueid = $Package->NameHash; + $packagepath = DUP_Settings::getSsdirUrl() . '/' . $Package->Archive->File; + + $css_alt = ($packageTablerowCount % 2 != 0) ? '' : 'alternate'; + + if ($Package->Status >= 100 || $is_running_package) : + ?> + + + + + + + + + ID}"; + ?> + + + + + + + + + + + + + + + + +
        + " style="margin-left:12px" onclick="Duplicator.Pack.SetDeleteAll()" /> + + + " + data-tooltip="" > + + + +
        +
        + +
        +
        +
        +
        + + + +
        +
         
        +
        +
        + Created, DUP_Settings::get_create_date_format()); + echo ' ' . ($pack_build_mode ? + "zip" : + "daf"); + ?> + + DB" : esc_html($pack_name); ?>
        + + % +   " + data-tooltip=" Advanced > Reset Backups', 'duplicator'); ?>"> + +
        + getInstDownloadName(); + ?> + "> + + + + + + + + +
        Created, DUP_Settings::get_create_date_format()); ?>  + + +
        + + + +
        + +
        + +
        + + +
        + + +title = __('Bulk Action Required', 'duplicator'); +$alert1->message = ' '; +$alert1->message .= __('No selections made! Please select an action from the "Bulk Actions" drop down menu.', 'duplicator'); +$alert1->initAlert(); + +$alert2 = new DUP_UI_Dialog(); +$alert2->title = __('Selection Required', 'duplicator', 'duplicator'); +$alert2->message = ' '; +$alert2->message .= __('No selections made! Please select at least one Backup to delete.', 'duplicator'); +$alert2->initAlert(); + +$confirm1 = new DUP_UI_Dialog(); +$confirm1->title = __('Delete Backups?', 'duplicator'); +$confirm1->message = __('Are you sure you want to delete the selected Backup(s)?', 'duplicator'); +$confirm1->progressText = __('Removing Backups, Please Wait...', 'duplicator'); +$confirm1->jscallback = 'Duplicator.Pack.Delete()'; +$confirm1->initConfirm(); + +$alert3 = new DUP_UI_Dialog(); +$alert3->height = 400; +$alert3->width = 450; +$alert3->title = __('Duplicator Help', 'duplicator'); +$alert3->message = "
        "; +$alert3->initAlert(); + +$alertPackRunning = new DUP_UI_Dialog(); +$alertPackRunning->title = __('Alert!', 'duplicator'); +$alertPackRunning->message = __('A Backup is being processed. Retry later.', 'duplicator'); +$alertPackRunning->initAlert(); +?> + + + + + diff --git a/html/wp-content/plugins/duplicator/views/packages/main/s1.setup1.php b/html/wp-content/plugins/duplicator/views/packages/main/s1.setup1.php new file mode 100644 index 0000000..ce149e2 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/main/s1.setup1.php @@ -0,0 +1,319 @@ +setResponseType('PHP'); +$data = $ctrl_ui->GetViewStateList(); + +$ui_css_storage = (isset($data->payload['dup-pack-storage-panel']) && !$data->payload['dup-pack-storage-panel']) ? 'display:none' : 'display:block'; +$ui_css_archive = (isset($data->payload['dup-pack-archive-panel']) && $data->payload['dup-pack-archive-panel']) ? 'display:block' : 'display:none'; +$ui_css_installer = (isset($data->payload['dup-pack-installer-panel']) && $data->payload['dup-pack-installer-panel']) ? 'display:block' : 'display:none'; +$dup_intaller_files = implode(", ", array_keys(DUP_Server::getInstallerFiles())); +$dbbuild_mode = (DUP_Settings::Get('package_mysqldump') && DUP_DB::getMySqlDumpPath()) ? 'mysqldump' : 'PHP'; +$archive_build_mode = DUP_Settings::Get('archive_build_mode') == DUP_Archive_Build_Mode::ZipArchive ? 'zip' : 'daf'; + +//="No Selection", 1="Try Again", 2="Two-Part Install" +$retry_state = isset($_GET['retry']) ? $_GET['retry'] : 0; +?> + + + + + + + + + + +
        +
        +
        + + + +
        +
        +
        + + +
        +
         
        +
        + + +

        + + + + + +
        +
        + Pass
        ' : '
        Fail
        '; + ?> +
        +
        + +
        + +
        + +
        + + +
        +
        + +
        +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + tags', + 'duplicator' + ), + '', + '' + ); + ?> +
        file_get_contents
        file_put_contents
        mb_strlen
        + + + +
        +
        + + +
        +
        + +
        + +
        +
        +
        + %s   [%s]
        ", $dup_tests['IO']['SSDIR'], DUP_Settings::getSsdirPath()); + printf("%s   [%s]
        ", $dup_tests['IO']['SSTMP'], DUP_Settings::getSsdirTmpPath()); + printf("%s   [%s]
        ", $dup_tests['IO']['WPROOT'], $abs_path); + ?> +
        + '; + } + esc_html_e("If Duplicator does not have enough permissions then you will need to manually create the paths above.   ", 'duplicator'); + ?> +
        +
        +
        + + +
        +
        + +
        +
        +
        + + + + + + + + + +
        + + [" . esc_html__('more info', 'duplicator') . "]"; + ?> + +
        + + + + + +
        mysqli_real_escape_string
        + + + +
        +
        + + +
        +
        +
        +
        +
        + + + +
        + +
        + +
        ' style='font-size:10px; margin-top:5px;' /> +
        + +
        +
        + +
        +

        + + + + +
        + +
        + + +
        + +
        + + diff --git a/html/wp-content/plugins/duplicator/views/packages/main/s1.setup2.php b/html/wp-content/plugins/duplicator/views/packages/main/s1.setup2.php new file mode 100644 index 0000000..c9e2cf7 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/main/s1.setup2.php @@ -0,0 +1,680 @@ + + + $retry_state]); +$action_nonce_url = wp_nonce_url($action_url, 'new2-package'); +$storage_position = DUP_Settings::Get('storage_position'); +?> +
        + + + +
        + + +
        +
        +
        +
        + +
        +
        +
        + + +
        +
        + + +
        +
        +
        +
        + + + +
        + +
        +
        + + + + + + + + + + + + + + + + + + + + + +
        + + + + + + + + + +
        +
        + +  ' . 'Amazon', + ' ' . 'Dropbox', + ' ' . 'Google Drive', + ' ' . 'OneDrive', + ' ' . 'FTP/SFTP' + ); + ?> + + + + " + data-tooltip=""> + + +
        +
        +
        +

        + + + +
        +
        +
        + + {$archive_build_mode}"; + ?>     +
        +
        + + + + + + + + + + +   + +
        +
        +
        +
        + + + +
        +
          +
        • +
        • +
        • +
        + + + render('admin_pages/packages/setup/archive-filter-files-tab', array ( + 'package' => $Package + )); ?> + + +
        +
        + +
        + + + + + + +
        Database->FilterOn) ? "checked='checked'" : ""; ?> /> + + " + data-tooltip=""> + +
        +
        +
        +   + +
        +
        + get_results("SHOW FULL TABLES FROM `" . esc_sql(DB_NAME) . "` WHERE Table_Type = 'BASE TABLE' ", ARRAY_N); + $num_rows = count($tables); + $next_row = round($num_rows / 4, 0); + $counter = 0; + $tableList = explode(',', $Package->Database->FilterTables); + + echo '
        '; + foreach ($tables as $table) { + if (DUP_Util::isTableExists($table[0])) { + if (DUP_Util::isWPCoreTable($table[0])) { + $core_css = 'core-table'; + $core_note = '*'; + } else { + $core_css = 'non-core-table'; + $core_note = ''; + } + + if (in_array($table[0], $tableList)) { + $checked = 'checked="checked"'; + $css = 'text-decoration:line-through'; + } else { + $checked = ''; + $css = ''; + } + echo "
        "; + $counter++; + if ($next_row <= $counter) { + echo '
        '; + $counter = 0; + } + } + } + echo '
        '; + ?> +
        +
        + +
        + excluded from the database script. ", 'duplicator'); + _e("Excluding certain tables can cause your site or plugins to not work correctly after install!
        ", 'duplicator'); + _e(" Use caution when excluding tables! It is highly recommended to not exclude WordPress core tables*, unless you know the impact.", 'duplicator'); + ?> +
        +
        + +
        + +
        + +
        + + :  + + +
        + :  + " + data-tooltip=""> +   + + [] + + + + Database->Compatible); + $is_mysql40 = in_array('mysql40', $modes); + $is_no_table = in_array('no_table_options', $modes); + $is_no_key = in_array('no_key_options', $modes); + $is_no_field = in_array('no_field_options', $modes); + ?> + + + + + + + +
        + > + + + > + + + > + + + > + +
        + + + +
        +
        + + +
        +

        + +

        + + + +
        +
        +
        +

        + + +
        +
        +
        +   +
        +
        + + + + + + +
        +
        +
        + +
        + +
        + + +
        + + " + data-tooltip=""> + +
        + + + + + + + + + + + + + +
        + + + :" + data-tooltip=""> +

        +
        + Installer->OptsSecureOn) ? $Package->Installer->OptsSecureOn : 0; + $dup_install_secure_pass = isset($Package->Installer->OptsSecurePass) ? DUP_Util::installerUnscramble($Package->Installer->OptsSecurePass) : ''; + ?> + /> + + " + data-tooltip=""> + +
        + + +
        +
        +
        + + + + + +
        + + +
        +
          +
        • +
        • +
        + + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +
        + +
        + +
        + +
        + +
        + +

        +
        + + +
        +
        + " style="width:16px; height:12px" /> +
        + + + +
        + +
        +
        + +
        + + +
        +

        + + + + +
        + + +title = __('Reset Backup Settings?', 'duplicator'); + $confirm1->message = __('This will clear and reset all of the current Backup settings. Would you like to continue?', 'duplicator'); + $confirm1->jscallback = 'Duplicator.Pack.ResetSettings()'; + $confirm1->initConfirm(); + + $default_name1 = DUP_Package::getDefaultName(); + $default_name2 = DUP_Package::getDefaultName(false); +?> + diff --git a/html/wp-content/plugins/duplicator/views/packages/main/s2.scan1.php b/html/wp-content/plugins/duplicator/views/packages/main/s2.scan1.php new file mode 100644 index 0000000..6d46c24 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/main/s2.scan1.php @@ -0,0 +1,467 @@ +window.location.href = '{$reredirect_nonce_url}'"); +} + +$Package = new DUP_Package(); +$Package->saveActive($_POST); + +DUP_Settings::Set('active_package_id', -1); +DUP_Settings::Save(); + +$Package = DUP_Package::getActive(); + +$mysqldump_on = DUP_Settings::Get('package_mysqldump') && DUP_DB::getMySqlDumpPath(); +$mysqlcompat_on = isset($Package->Database->Compatible) && strlen($Package->Database->Compatible); +$mysqlcompat_on = ($mysqldump_on && $mysqlcompat_on) ? true : false; +$dbbuild_mode = ($mysqldump_on) ? 'mysqldump' : 'PHP'; +$zip_check = DUP_Util::getZipPath(); + +$action_url = ControllersManager::getMenuLink( + ControllersManager::PACKAGES_SUBMENU_SLUG, + 'new3' +); +$action_nonce_url = wp_nonce_url($action_url, 'new3-package'); +?> + + + +validateInputs(); +if (!$validator->isSuccess()) { + ?> +
        + +
        +
        +
        +
        + +
        +
          + getErrorsFormat("
        • %s
        • "); + ?> +
        +
        +
        +
        + " onclick="window.location.assign('?page=duplicator&tab=new1&_wpnonce=')" class="button button-large" /> +
        + + + + + + + + +
        +
        +
        + + + +
        +
        + + +
        +
        +
         
        +
        + +
        + + + +
        + +
        +
        +
        +

        +
        +
        +
        + +
        + + + + + + + + +
        + + diff --git a/html/wp-content/plugins/duplicator/views/packages/main/s2.scan2.php b/html/wp-content/plugins/duplicator/views/packages/main/s2.scan2.php new file mode 100644 index 0000000..e90d583 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/main/s2.scan2.php @@ -0,0 +1,258 @@ + + +
        + +
        +   + +
        +
        + + +
        + + Archive->FilterDirs); + $filterFiles = explode(';', $Package->Archive->FilterFiles); + + if (!$Package->Archive->ExportOnlyDB && $Package->Archive->FilterOn) { + $core_dir_included = array_intersect($filterDirs, DUP_Util::getWPCoreDirs()); + if (count($core_dir_included)) { + $core_dir_notice = true; + } + + $core_files_included = array_intersect($filterFiles, DUP_Util::getWPCoreFiles()); + if (count($core_files_included)) { + $core_file_notice = true; + } + } + ?> +
        +
        +
        +
        +
        +  ' . esc_html__('Web Server', 'duplicator') . ":  '" . esc_attr($_SERVER['SERVER_SOFTWARE']) . "'
        "; + _e("Supported web servers: ", 'duplicator'); + echo "" . esc_html($web_servers) . ""; + + //PHP VERSION + echo '
         ' . esc_html__('PHP Version', 'duplicator') . "
        "; + _e('The minimum PHP version supported by Duplicator is 5.2.9. It is highly recommended to use PHP 5.3+ for improved stability. For international language support please use PHP 7.0+.', 'duplicator'); + + //OPEN_BASEDIR + $test = ini_get("open_basedir"); + $test = ($test) ? 'ON' : 'OFF'; + echo '
         ' . esc_html__('PHP Open Base Dir', 'duplicator') . ":  '{$test}'
        "; + _e('Issues might occur when [open_basedir] is enabled. Work with your server admin to disable this value in the php.ini file if you’re having issues building a Backup.', 'duplicator'); + echo " [" . esc_html__('details', 'duplicator') . "]
        "; + + //MAX_EXECUTION_TIME + $test = (@set_time_limit(0)) ? 0 : ini_get("max_execution_time"); + echo '
         ' . esc_html__('PHP Max Execution Time', 'duplicator') . ":  '{$test}'
        "; + _e('Timeouts may occur for larger Backups when [max_execution_time] time in the php.ini is too low. A value of 0 (recommended) indicates that PHP has no time limits. ' + . 'An attempt is made to override this value if the server allows it.', 'duplicator'); + echo '

        '; + _e('Note: Timeouts can also be set at the web server layer, so if the PHP max timeout passes and you still see a build timeout messages, then your web server could be killing ' + . 'the process. If you are on a budget host and limited on processing time, consider using the database or file filters to shrink the size of your overall Backup. ' + . 'However use caution as excluding the wrong resources can cause your install to not work properly.', 'duplicator'); + echo " [" . esc_html__('details', 'duplicator') . "]"; + if ($zip_check != null) { + echo '

        '; + echo ''; + _e('Get faster builds with Duplicator Pro with access to shell_exec zip.', 'duplicator'); + echo ''; + echo " [" . esc_html__('details', 'duplicator') . "]"; + } + + //MANAGED HOST + $test = DUP_Custom_Host_Manager::getInstance()->isManaged() ? "true" : "false"; + echo '
         ' . esc_html__('Managed Host', 'duplicator') . ":  '{$test}'
        "; + _e('A managed host is a WordPress host that tightly controls the server environment so that the software running on it can be closely ‘managed’ by the hosting company. ' + . 'Managed hosts typically have constraints imposed to facilitate this management, including the locking down of certain files and directories as well as non-standard configurations.', 'duplicator'); + echo '

        '; + _e('Duplicator Lite allows users to build a Backup on managed hosts, however, the installer may not properly install Backups created on managed hosts due to the non-standard configurations of managed hosts. ' + . 'It is also possible the Backup engine of Duplicator Lite won’t be able to capture all of the necessary data of a site running on a managed host.', 'duplicator'); + echo '

        '; + _e('Due to these constraints Lite does not officially support the migration of managed hosts. '); + printf( + esc_html_x( + 'It\'s possible one could get the Backup to install but it may require custom manual effort. + To get support and the advanced installer processing required for managed host support we encourage users to %1$supgrade to Duplicator Pro%2$s. + Pro has more sophisticated Backup and installer logic and accounts for odd configurations associated with managed hosts.', + '1 and 2 are tags', + 'duplicator' + ), + '', + '' + ); + echo '

        '; + + ?> +
        +
        + + +
        + +
        +
        +
        +
        +
        +  ' . esc_html__('WordPress Version', 'duplicator') . ":  '{$wp_version}'
        "; + printf(__('It is recommended to have a version of WordPress that is greater than %1$s. Older version of WordPress can lead to migration issues and are a security risk. ' + . 'If possible please update your WordPress site to the latest version.', 'duplicator'), DUPLICATOR_SCAN_MIN_WP); + + //CORE FILES + echo '
         ' . esc_html__('Core Files', 'duplicator') . "
        "; + + + $filter_text = ""; + if ($core_dir_notice) { + echo ''; + esc_html_e("The core WordPress paths below will NOT be included in the Backup. These paths are required for WordPress to function!", 'duplicator'); + echo "
        "; + foreach ($core_dir_included as $core_dir) { + echo '     ' . $core_dir . '
        '; + } + echo '

        '; + $filter_text = __("directories"); + } + + if ($core_file_notice) { + echo ''; + esc_html_e("The core WordPress file below will NOT be included in the Backup. This file is required for WordPress to function!", 'duplicator'); + echo "
        "; + foreach ($core_files_included as $core_file) { + echo '     ' . $core_file . '
        '; + } + echo '

        '; + $filter_text .= (strlen($filter_text) > 0) ? __(" and file") : __("files"); + } + + if (strlen($filter_text) > 0) { + echo ''; + printf( + esc_html__( + 'Note: Please change the %1$s filters if you wish to include the WordPress core files + otherwise the data will have to be manually copied to the new location for the site to function properly.', + 'duplicator' + ), + esc_html($filter_text) + ); + echo ''; + } + + + if (!$core_dir_notice && !$core_file_notice) : + esc_html_e("If the scanner is unable to locate the wp-config.php file in the root directory, then you will need to manually copy it to its new location. " + . "This check will also look for core WordPress paths that should be included in the Backup for WordPress to work correctly.", 'duplicator'); + endif; + + + + //CACHE DIR + /* + $cache_path = DUP_Util::safePath(WP_CONTENT_DIR) . '/cache'; + $cache_size = DUP_Util::byteSize(DUP_Util::getDirectorySize($cache_path)); + echo '
         ' . esc_html__('Cache Path', 'duplicator') . ":  '".esc_html($cache_path)."' (".esc_html($cache_size).")
        "; + _e("Cached data will lead to issues at install time and increases your Backup size. Empty your cache directory before building the Backup by using " + . "your cache plugins clear cache feature. Use caution if manually removing files the cache folder. The cache " + . "size minimum threshold that triggers this warning is currently set at ", 'duplicator'); + echo esc_html(DUP_Util::byteSize(DUPLICATOR_SCAN_CACHESIZE)) . '.'; + */ + + //MU SITE + if (is_multisite()) { + echo '
         ' . esc_html__('Multisite: Unsupported', 'duplicator') . "
        "; + esc_html_e('Duplicator does not support WordPress multisite migrations. We strongly recommend using Duplicator Pro which currently supports full multisite migrations and various other ' + . 'subsite scenarios.', 'duplicator'); + echo '

        '; + + esc_html_e('While it is not recommended you can still continue with the build of this Backup. At install time additional manual custom configurations will ' + . 'need to be made to finalize this multisite migration. Please note that any support requests for mulitsite with Duplicator Lite will not be supported.', 'duplicator'); + echo " [" . esc_html__('upgrade to pro', 'duplicator') . "]"; + } else { + echo '
         ' . esc_html__('Multisite: N/A', 'duplicator') . "
        "; + esc_html_e('This is not a multisite install so duplication will proceed without issue. Duplicator does not officially support multisite. However, Duplicator Pro supports ' + . 'duplication of a full multisite network and also has the ability to install a multisite subsite as a standalone site.', 'duplicator'); + echo " [" . esc_html__('upgrade to pro', 'duplicator') . "]"; + } + ?> +
        +
        + + +
        +
        +
        +
        +
        +
        + +
        +
        +
        + + diff --git a/html/wp-content/plugins/duplicator/views/packages/main/s2.scan3.php b/html/wp-content/plugins/duplicator/views/packages/main/s2.scan3.php new file mode 100644 index 0000000..a1898cf --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/main/s2.scan3.php @@ -0,0 +1,1181 @@ + 50 ? substr($root, 0, 50) . '...' : $root; + echo "
        {$sroot}
        "; +} + +$archive_type_label = DUP_Settings::Get('archive_build_mode') == DUP_Archive_Build_Mode::ZipArchive ? "ZipArchive" : "DupArchive"; +$archive_type_extension = DUP_Settings::Get('archive_build_mode') == DUP_Archive_Build_Mode::ZipArchive ? "zip" : "daf"; +$duparchive_max_limit = DUP_Util::readableByteSize(DUPLICATOR_MAX_DUPARCHIVE_SIZE); +$skip_archive_scan = DUP_Settings::Get('skip_archive_scan'); +$dbbuild_mode = DUP_DB::getBuildMode(); + +global $wpdb; +?> + + +
        +   + +
        +
        + +
        + + + +
        +
        + Archive->ExportOnlyDB) { + echo ' '; + esc_html_e('Database Only', 'duplicator'); + } elseif ($Package->Archive->FilterOn) { + echo ' '; + esc_html_e('Enabled', 'duplicator'); + } + ?> +
        +
        + + +
        +
        +
        + +Archive->ExportOnlyDB) { ?> +
        +
        +
        +
        +
        +
        + +
        +
        + +
        +
        +
        +
        +
        +
        + +

        + +
        +
        + + + +
        +
        +
        +
        +
        +
        + :   |   + :   |   + :
        + some budget hosts may cause timeouts. ', 'duplicator'); + echo "  [" . esc_html__('more details...', 'duplicator') . "]"; + ?> +
        + ' . DUP_Util::byteSize(DUPLICATOR_SCAN_SIZE_DEFAULT) . '' + ); + ?> +

        + ": +
        +
          +
        • +
        • + tags', + 'duplicator' + ), + '', + '' + ); + ?> +
        • +
        • + tags', + 'duplicator' + ), + '', + '' + ); + ?> +
        • +
        +
        + + +
        +
        +
        + + +
        +
        +
        +
        +
        +
        +
        + +
        + +
        +
        +
        + + + +
        +
        +
        +
        +
        +
        + <:/\|", can be problematic on some hosts.', 'duplicator'); + esc_html_e(' Only consider using this filter if the Backup build is failing. Select files that are not important to your site or you can migrate manually.', 'duplicator'); + $txt = __('If this environment/system and the system where it will be installed are set up to support Unicode and long paths then these filters can be ignored. ' + . 'If you run into issues with creating or installing a Backup, then is recommended to filter these paths.', 'duplicator'); + ?> + +
        +
        +
        + +
        +
        +
        +
        +
        +
        + + +
        +
        +
        + + + + + + +
        +
        + + +
        +
        + Database->FilterOn) { + echo ' '; + esc_html_e('Enabled', 'duplicator'); + } + ?> +
        +
        + " + data-tooltip=""> + +
        + +
        +
        + +
        +
        +
        +
        +
        +
        + ' . esc_html__('TOTAL SIZE', 'duplicator') . '   ⇛   '; ?> + :   |   + :   |   + :
        +
        '; + + //TABLE DETAILS + echo '' . __('TABLE DETAILS:', 'duplicator') . '
        '; + $dup_scan_tbl_trigger_size = DUP_Util::byteSize(DUPLICATOR_SCAN_DB_TBL_SIZE) . ', ' . number_format(DUPLICATOR_SCAN_DB_TBL_ROWS); + printf(esc_html__('The notices for tables are %1$s records or names with upper-case characters. Individual tables will not trigger ' + . 'a notice message, but can help narrow down issues if they occur later on.', 'duplicator'), $dup_scan_tbl_trigger_size); + + echo '
        '; + + //RECOMMENDATIONS + echo '

        '; + echo '' . esc_html__('RECOMMENDATIONS:', 'duplicator') . '
        '; + + echo '
        '; + $lnk = '' . esc_html__('repair and optimization', 'duplicator') . ''; + printf(__('1. Run a %1$s on the table to improve the overall size and performance.', 'duplicator'), $lnk); + echo '

        '; + _e('2. Remove post revisions and stale data from tables. Tables such as logs, statistical or other non-critical data should be cleared.', 'duplicator'); + echo '

        '; + $lnk = '' . esc_html__('Enable mysqldump', 'duplicator') . ''; + printf(__('3. %1$s if this host supports the option.', 'duplicator'), $lnk); + echo '

        '; + $lnk = '' . esc_html__('lower_case_table_names', 'duplicator') . ''; + printf(__('4. For table name case sensitivity issues either rename the table with lower case characters or be prepared to work with the %1$s system variable setting.', 'duplicator'), $lnk); + echo '
        '; + + ?> +
        +
        + get_col("SHOW TRIGGERS", 1); + if (count($triggers)) { ?> +
        +
        +
        +
        +
        +
        + +
        +
        +
        + + prepare("SHOW PROCEDURE STATUS WHERE `Db` = %s", $wpdb->dbname); + $procedures = $wpdb->get_col($procQuery, 1); + $funcQuery = $wpdb->prepare("SHOW FUNCTION STATUS WHERE `Db` = %s", $wpdb->dbname); + $functions = $wpdb->get_col($funcQuery, 1); + if (count($procedures) || count($functions)) { ?> +
        +
        +
        +
        +
        +
        + +
        +
        +
        + + + + + + + +
        + + + +  '; + esc_html_e('Migrate large, multi-gig sites with', 'duplicator'); + echo ' ' . esc_html__('Duplicator Pro', 'duplicator') . '!'; + echo '
        '; + ?> +
        +

        + + + +height = 600; + $alert1->width = 600; + $alert1->title = __('Scan Details', 'duplicator'); + $alert1->message = "
        "; + $alert1->initAlert(); + + $alert2 = new DUP_UI_Dialog(); + $alert2->height = 450; + $alert2->width = 650; + $alert2->title = __('Copy Quick Filter Paths', 'duplicator'); + $alert2->message = "
        "; + $alert2->initAlert(); +?> + + + + + + + + + diff --git a/html/wp-content/plugins/duplicator/views/packages/main/s3.build.php b/html/wp-content/plugins/duplicator/views/packages/main/s3.build.php new file mode 100644 index 0000000..8266267 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/packages/main/s3.build.php @@ -0,0 +1,875 @@ + + + + + + + + + + +
        +
        +
        + + + +
        +
        + + +
        +
        +
        + + + + + + + + + +
        +
        + + +
        + + + +
        + +
        +
        0%
        +
        +

        +
        +
        +
        + +
        + + + +
        + + diff --git a/html/wp-content/plugins/duplicator/views/parts/migration-almost-complete.php b/html/wp-content/plugins/duplicator/views/parts/migration-almost-complete.php new file mode 100644 index 0000000..b8df785 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/parts/migration-almost-complete.php @@ -0,0 +1,53 @@ + +
        +

        + +

        +

        + +
        + Tools > General > Information > Utils and click the "Remove Installation Files" button', 'duplicator'); ?>
        + + + +

        + 0) { ?> +
        + +
        + +

        + + +

        + + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/duplicator/views/parts/migration-clean-installation-files.php b/html/wp-content/plugins/duplicator/views/parts/migration-clean-installation-files.php new file mode 100644 index 0000000..1c57b9b --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/parts/migration-clean-installation-files.php @@ -0,0 +1,98 @@ + +
        +

        + +

        + +

        + +

        $success) { + if ($success) { + ?>
        + - +
        + - +
        + +
        + +

        + + + +
        + +

        + +
        +

        + : +
        + tags', + 'duplicator' + ), + '', + '' + ); + ?> +

        +

        + : + '; + printf( + esc_html_x( + 'Show your support with a %1$s5 star review%2$s! We would be thrilled if you could!', + '%1$s and %2$s are tags', + 'duplicator' + ), + '', + '' + ); + ?> +

        +
        +
        diff --git a/html/wp-content/plugins/duplicator/views/parts/migration-message.php b/html/wp-content/plugins/duplicator/views/parts/migration-message.php new file mode 100644 index 0000000..a49249e --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/parts/migration-message.php @@ -0,0 +1,85 @@ + +
        +
        + +
        +

        + %s', 'duplicator'), DUP_Settings::getSsdirPath()); ?> +

        +
          + $label) { ?> +
        • + - +
        • + +
        + + 0) { ?> +

        + +

        +
          + +
        • + +
        • + +
        + +

        +
        + + + +

        + 0) { ?> +
        + +
        + + +

        +
        + + +
        +

        + +
        diff --git a/html/wp-content/plugins/duplicator/views/settings/about-info.php b/html/wp-content/plugins/duplicator/views/settings/about-info.php new file mode 100644 index 0000000..a4c6e7c --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/settings/about-info.php @@ -0,0 +1,129 @@ + + + + +
        +
        + + + + + +
        + " style='margin-top:-60px; height:176px; width:176px' /> + + +

        + + + + + +
        + + + + +
        + +
        +
        +
        + +
        +
        +

        +
        + +
        +




        + diff --git a/html/wp-content/plugins/duplicator/views/settings/controller.php b/html/wp-content/plugins/duplicator/views/settings/controller.php new file mode 100644 index 0000000..d2155ec --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/settings/controller.php @@ -0,0 +1,81 @@ + + +
        + + + + + render("admin_pages/settings/general/general"); + break; + case 'package': + include(DUPLICATOR_PLUGIN_PATH . "views/settings/packages.php"); + break; + case 'storage': + include(DUPLICATOR_PLUGIN_PATH . "views/settings/storage.php"); + break; + case 'access': + Bootstrap::mocksStyles(); + TplMng::getInstance()->render("mocks/settings/access/capabilities"); + break; + + case 'misc': + TplMng::getInstance()->render("admin_pages/settings/misc/misc"); + break; + } + do_action('duplicator_settings_page_footer'); + ?> +
        diff --git a/html/wp-content/plugins/duplicator/views/settings/index.php b/html/wp-content/plugins/duplicator/views/settings/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/settings/index.php @@ -0,0 +1,3 @@ + + + + +
        + + + + + +

        + + + +

        +
        + + + + + +
        +
        + /> + +
        + +
        + + + + + /> + + +
        + +

        + + + + + + +
        + + +

        +
        + + + + + + + + + +
        +
        + /> + +
        + +
        + /> +     +
        + +
        + + + + + + +
        + /> + + () +

        + +

        +

        + +

        +
        + + + + + +
        +
        + +
        + +

        + + . +

        +
        +

        +
        + : my-name_64fc6df76c17f2023225_20220815053010_installer.php +

        +

        + +

        +

        + +

        +

        + + + + +

        +
        +
        + +

        +
        + + + + + +
        + +

        +
        + +

        +

        + + +

        +
        + " style="display: inline-block;" /> +

        +
        + + diff --git a/html/wp-content/plugins/duplicator/views/settings/storage.php b/html/wp-content/plugins/duplicator/views/settings/storage.php new file mode 100644 index 0000000..1fa819a --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/settings/storage.php @@ -0,0 +1,94 @@ + + + +
        +
        + + + + + +

        + + + + + + + + + + + +
        +

        + +

        +

        + +
        +   + [] +

        +
        + /> + +

        + +

        +
        +

        +
        + " style="display: inline-block;" /> +

        +
        +
        +
        + + + diff --git a/html/wp-content/plugins/duplicator/views/tools/controller.php b/html/wp-content/plugins/duplicator/views/tools/controller.php new file mode 100644 index 0000000..926edcd --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/controller.php @@ -0,0 +1,46 @@ + + +
        + + + + + render('mocks/templates/templates', array(), true); + break; + case 'recovery': + TplMng::getInstance()->render('mocks/recovery/recovery', array(), true); + break; + case 'db-reset': + TplMng::getInstance()->render('mocks/db_reset/db_reset', array(), true); + break; + } + ?> +
        diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.data.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.data.php new file mode 100644 index 0000000..a37ae09 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.data.php @@ -0,0 +1,115 @@ + + + +
        +
        + + +
        +
        +
        + + + + + + + + + + + + + +
        + + + + []
        + +
        +
        "; + + $installer_files = array_keys($installer_files); + array_push($installer_files, '[HASH]_archive.zip/daf'); + echo '' . implode('
        ', $installer_files) . '
        '; + echo "

        "; + ?> +
        +
        + + [].
        + + + + + + +
        +
        +
        +
        + + +title = __('Clear Build Cache?', 'duplicator'); + $confirmClearBuildCache->message = __('This process will remove all build cache files. Be sure no backups are currently building or else they will be cancelled.', 'duplicator'); + $confirmClearBuildCache->jscallback = 'Duplicator.Tools.ClearBuildCache()'; + $confirmClearBuildCache->initConfirm(); +?> + + diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.phpinfo.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.phpinfo.php new file mode 100644 index 0000000..76dafe7 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.phpinfo.php @@ -0,0 +1,38 @@ +phpinfo function is not supported on this server, ' + . 'for more details contact your hosting provider.'; +} else { + $serverinfo = preg_replace('%^.*(.*).*$%ms', '$1', $serverinfo); + $serverinfo = preg_replace('%^.*(.*).*$%ms', '$1', $serverinfo); +} +?> + + +
        +
        + + +
        +
        +
        +
        + +
        diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.settings.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.settings.php new file mode 100644 index 0000000..f775718 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.settings.php @@ -0,0 +1,25 @@ + + + +
        +
        + + +
        +
        +
        + render( + 'parts/tools/server_settings_table', + [ + 'serverSettings' => DUP_Server::getServerSettingsData(), + ] + ); ?> +
        +
        +
        diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.validator.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.validator.php new file mode 100644 index 0000000..b0b2ebe --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/inc.validator.php @@ -0,0 +1,164 @@ + + + + + +title = __('Run Validator', 'duplicator'); + $confirm1->message = __('This will run the scan validation check. This may take several minutes. Do you want to Continue?', 'duplicator'); + $confirm1->progressOn = false; + $confirm1->jscallback = 'Duplicator.Tools.runScanValidator()'; + $confirm1->initConfirm(); +?> + + +
        +
        + + +
        +
        +
        + +

        + + + + + +
        + +
        +
        +
        + + + diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/information.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/information.php new file mode 100644 index 0000000..ed19943 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/information.php @@ -0,0 +1,68 @@ + +
        +

        +
        + 'info'] +); +?> + +
        + +
        diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/logging.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/logging.php new file mode 100644 index 0000000..84fe73f --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/logging.php @@ -0,0 +1,240 @@ + 0) { + unset($logname); + } + unset($validFiles); +} + +if (!isset($logname) || !$logname) { + $logname = (count($logs) > 0) ? basename($logs[0]) : ""; +} + +$logurl = DUP_Settings::getSsdirLogsUrl() . '/' . $logname; +$logfound = (strlen($logname) > 0) ? true : false; +?> + + + + + +
        + + + + +
        +

        .

        + .

        + :
        + - .
        + - .
        + - .
        +
        + + + + + + +
        +
        +   |   + " + data-tooltip=""> + + tags', + 'duplicator' + ), + '', + '' + ); + ?> + +
        +
         
        +
        +
        
        +            
        +

        +
        + " />   + + +
        + +
        + + +
        + +
        + " . esc_html($time) . "-" . esc_html($name) . "" + : "" . esc_html($time) . "-" . esc_html($name) . ""; + if ($count > 20) { + break; + } + } + ?> +
        +
        + +
        diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/main.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/main.php new file mode 100644 index 0000000..5ca95f1 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/main.php @@ -0,0 +1,80 @@ + + + + +setResponseType('PHP'); +$data = $ctrl_ui->GetViewStateList(); + +$ui_css_srv_panel = (isset($data->payload['dup-settings-diag-srv-panel']) && $data->payload['dup-settings-diag-srv-panel']) ? 'display:block' : 'display:none'; +$ui_css_opts_panel = (isset($data->payload['dup-settings-diag-opts-panel']) && $data->payload['dup-settings-diag-opts-panel']) ? 'display:block' : 'display:none'; + +$section = isset($_GET['section']) ? $_GET['section'] : 'info'; +$txt_diagnostic = __('Information', 'duplicator'); +$txt_log = __('Logs', 'duplicator'); +$txt_support = __('Support', 'duplicator'); +; +$tools_url = 'admin.php?page=duplicator-tools&tab=diagnostics'; + +switch ($section) { + case 'info': + echo "
        " . + esc_html($txt_diagnostic) . + "  |  " . + esc_html($txt_log) . "  |  " . + esc_html($txt_support) . "
        "; + include(__DIR__ . '/information.php'); + break; + + case 'log': + echo ""; + include(__DIR__ . '/logging.php'); + break; + + case 'support': + echo "
        " . + esc_html($txt_diagnostic) . "  |  " . + esc_html($txt_log) . "  |  " . + esc_html($txt_support) . "
        "; + include(__DIR__ . '/support.php'); + break; +} +?> diff --git a/html/wp-content/plugins/duplicator/views/tools/diagnostics/support.php b/html/wp-content/plugins/duplicator/views/tools/diagnostics/support.php new file mode 100644 index 0000000..42f2bb6 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/diagnostics/support.php @@ -0,0 +1,120 @@ + + + + +
        + +
        + + + + + +
        + +
        +

        + + +
        +
        + +
        +
        +
        + +
        + +
        +
        + + +
        +
        + +
        +
        +
        + +
        + + + ', + '' + ); + ?> + +
        +
        +
        +
        + diff --git a/html/wp-content/plugins/duplicator/views/tools/index.php b/html/wp-content/plugins/duplicator/views/tools/index.php new file mode 100644 index 0000000..c919965 --- /dev/null +++ b/html/wp-content/plugins/duplicator/views/tools/index.php @@ -0,0 +1,3 @@ + array(), + 'version' => FLAMINGO_VERSION, + ) ); + + wp_enqueue_script( 'flamingo-admin', + flamingo_plugin_url( 'admin/includes/js/index.js' ), + $assets['dependencies'], + $assets['version'], + array( 'in_footer' => true ) + ); + + wp_set_script_translations( 'flamingo-admin', 'flamingo' ); + + $current_screen = get_current_screen(); + + wp_add_inline_script( 'flamingo-admin', + sprintf( + 'var flamingo = %s;', + wp_json_encode( array( + 'screenId' => $current_screen->id, + ), JSON_PRETTY_PRINT ) + ), + 'before' + ); +} + +/* Updated Message */ + +add_action( 'flamingo_admin_updated_message', + 'flamingo_admin_updated_message', + 10, 0 +); + +function flamingo_admin_updated_message() { + if ( empty( $_REQUEST['message'] ) ) { + return; + } + + if ( 'contactupdated' === $_REQUEST['message'] ) { + $message = __( 'Contact updated.', 'flamingo' ); + } elseif ( 'contactdeleted' === $_REQUEST['message'] ) { + $message = __( 'Contact deleted.', 'flamingo' ); + } elseif ( 'inboundupdated' === $_REQUEST['message'] ) { + $message = __( 'Messages updated.', 'flamingo' ); + } elseif ( 'inboundtrashed' === $_REQUEST['message'] ) { + $message = __( 'Messages trashed.', 'flamingo' ); + } elseif ( 'inbounduntrashed' === $_REQUEST['message'] ) { + $message = __( 'Messages restored.', 'flamingo' ); + } elseif ( 'inbounddeleted' === $_REQUEST['message'] ) { + $message = __( 'Messages deleted.', 'flamingo' ); + } elseif ( 'inboundspammed' === $_REQUEST['message'] ) { + $message = __( 'Messages got marked as spam.', 'flamingo' ); + } elseif ( 'inboundunspammed' === $_REQUEST['message'] ) { + $message = __( 'Messages got marked as not spam.', 'flamingo' ); + } + + if ( ! empty( $message ) ) { + wp_admin_notice( $message, array( + 'type' => 'success', + 'dismissible' => true, + ) ); + } +} + +/* Contact */ + +function flamingo_load_contact_admin() { + $action = flamingo_current_action(); + + $redirect_to = menu_page_url( 'flamingo', false ); + + if ( 'save' === $action and ! empty( $_REQUEST['post'] ) ) { + $post = new Flamingo_Contact( $_REQUEST['post'] ); + + if ( ! empty( $post ) ) { + if ( ! current_user_can( 'flamingo_edit_contact', $post->id() ) ) { + wp_die( + wp_kses_data( __( 'You are not allowed to edit this item.', 'flamingo' ) ) + ); + } + + check_admin_referer( 'flamingo-update-contact_' . $post->id() ); + + $post->props = (array) $_POST['contact']; + + $post->name = trim( $_POST['contact']['name'] ); + + $post->tags = ( + ! empty( $_POST['tax_input'][Flamingo_Contact::contact_tag_taxonomy] ) + ? explode( + ',', $_POST['tax_input'][Flamingo_Contact::contact_tag_taxonomy] + ) + : array() + ); + + $post->save(); + + $redirect_to = add_query_arg( + array( + 'action' => 'edit', + 'post' => $post->id(), + 'message' => 'contactupdated', + ), $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'delete' === $action and ! empty( $_REQUEST['post'] ) ) { + if ( ! is_array( $_REQUEST['post'] ) ) { + check_admin_referer( 'flamingo-delete-contact_' . $_REQUEST['post'] ); + } else { + check_admin_referer( 'bulk-posts' ); + } + + $deleted = 0; + + foreach ( (array) $_REQUEST['post'] as $post ) { + $post = new Flamingo_Contact( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( ! current_user_can( 'flamingo_delete_contact', $post->id() ) ) { + wp_die( + wp_kses_data( __( 'You are not allowed to delete this item.', 'flamingo' ) ) + ); + } + + if ( ! $post->delete() ) { + wp_die( + wp_kses_data( __( 'Error in deleting.', 'flamingo' ) ) + ); + } + + $deleted += 1; + } + + if ( ! empty( $deleted ) ) { + $redirect_to = add_query_arg( + array( 'message' => 'contactdeleted' ), $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( ! empty( $_GET['export'] ) ) { + check_admin_referer( 'bulk-posts' ); + + $csv_class = apply_filters( 'flamingo_contact_csv_class', + 'Flamingo_Contact_CSV' + ); + + if ( is_subclass_of( $csv_class, 'Flamingo_CSV' ) ) { + $csv_obj = new $csv_class; + $csv_obj->send_http_headers(); + $csv_obj->print_data(); + } + + exit(); + } + + if ( 'edit' === $action ) { + $post_id = (int) ( $_REQUEST['post'] ?? '0' ); + + if ( ! $post_id ) { + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( + ! current_user_can( 'flamingo_edit_contact', $post_id ) or + Flamingo_Contact::post_type !== get_post_type( $post_id ) + ) { + wp_die( + wp_kses_data( __( 'You are not allowed to edit this item.', 'flamingo' ) ) + ); + } + + add_meta_box( 'submitdiv', __( 'Save', 'flamingo' ), + 'flamingo_contact_submit_meta_box', null, 'side', 'core' + ); + + add_meta_box( 'contacttagsdiv', __( 'Tags', 'flamingo' ), + 'flamingo_contact_tags_meta_box', null, 'side', 'core' + ); + + add_meta_box( 'contactnamediv', __( 'Name', 'flamingo' ), + 'flamingo_contact_name_meta_box', null, 'normal', 'core' + ); + + } else { + if ( ! class_exists( 'Flamingo_Contacts_List_Table' ) ) { + require_once FLAMINGO_PLUGIN_DIR + . '/admin/includes/class-contacts-list-table.php'; + } + + $current_screen = get_current_screen(); + + add_filter( 'manage_' . $current_screen->id . '_columns', + array( 'Flamingo_Contacts_List_Table', 'define_columns' ), + 10, 0 + ); + + add_screen_option( 'per_page', array( + 'default' => 20, + 'option' => 'flamingo_contacts_per_page', + ) ); + } +} + +function flamingo_contact_admin_page() { + if ( 'edit' === flamingo_current_action() ) { + flamingo_contact_edit_page(); + return; + } + + $list_table = new Flamingo_Contacts_List_Table(); + $list_table->prepare_items(); + +?> +
        + +

        + +%s', + wp_kses_data( sprintf( + /* translators: %s: Search query. */ + __( 'Search results for: %s', 'flamingo' ), + esc_html( $_REQUEST['s'] ) + ) ) + ); + } +?> + +
        + + + +
        + + search_box( __( 'Search contacts', 'flamingo' ), 'flamingo-contact' ); ?> + display(); ?> +
        + +
        + $_GET['post_status'], + ), + $redirect_to + ); + } + + if ( 'save' === $action and ! empty( $_REQUEST['post'] ) ) { + $post = new Flamingo_Inbound_Message( $_REQUEST['post'] ); + + if ( ! empty( $post ) ) { + if ( ! current_user_can( 'flamingo_edit_inbound_message', $post->id() ) ) { + wp_die( + wp_kses_data( __( 'You are not allowed to edit this item.', 'flamingo' ) ) + ); + } + + check_admin_referer( 'flamingo-update-inbound_' . $post->id() ); + + $status = $_POST['inbound']['status'] ?? ''; + + if ( ! $post->spam and 'spam' === $status ) { + $post->spam(); + } elseif ( $post->spam and 'ham' === $status ) { + $post->unspam(); + } + + $redirect_to = add_query_arg( + array( + 'action' => 'edit', + 'post' => $post->id(), + 'message' => 'inboundupdated', + ), $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'trash' === $action and ! empty( $_REQUEST['post'] ) ) { + if ( ! is_array( $_REQUEST['post'] ) ) { + check_admin_referer( + 'flamingo-trash-inbound-message_' . $_REQUEST['post'] + ); + } else { + check_admin_referer( 'bulk-posts' ); + } + + $trashed = 0; + + foreach ( (array) $_REQUEST['post'] as $post ) { + $post = new Flamingo_Inbound_Message( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( ! current_user_can( + 'flamingo_delete_inbound_message', $post->id() ) ) { + wp_die( + wp_kses_data( __( 'You are not allowed to move this item to the Trash.', 'flamingo' ) ) + ); + } + + if ( ! $post->trash() ) { + wp_die( + wp_kses_data( __( 'Error in moving to Trash.', 'flamingo' ) ) + ); + } + + $trashed += 1; + } + + if ( ! empty( $trashed ) ) { + $redirect_to = add_query_arg( + array( + 'message' => 'inboundtrashed', + ), + $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'untrash' === $action and ! empty( $_REQUEST['post'] ) ) { + if ( ! is_array( $_REQUEST['post'] ) ) { + check_admin_referer( + 'flamingo-untrash-inbound-message_' . $_REQUEST['post'] + ); + } else { + check_admin_referer( 'bulk-posts' ); + } + + $untrashed = 0; + + foreach ( (array) $_REQUEST['post'] as $post ) { + $post = new Flamingo_Inbound_Message( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( + ! current_user_can( 'flamingo_delete_inbound_message', $post->id() ) + ) { + wp_die( + wp_kses_data( __( 'You are not allowed to restore this item from the Trash.', 'flamingo' ) ) + ); + } + + if ( ! $post->untrash() ) { + wp_die( + wp_kses_data( __( 'Error in restoring from Trash.', 'flamingo' ) ) + ); + } + + $untrashed += 1; + } + + if ( ! empty( $untrashed ) ) { + $redirect_to = add_query_arg( + array( + 'message' => 'inbounduntrashed', + ), $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'delete_all' === $action ) { + check_admin_referer( 'bulk-posts' ); + + $_REQUEST['post'] = flamingo_get_all_ids_in_trash( + Flamingo_Inbound_Message::post_type + ); + + $action = 'delete'; + } + + if ( 'delete' === $action and ! empty( $_REQUEST['post'] ) ) { + if ( ! is_array( $_REQUEST['post'] ) ) { + check_admin_referer( + 'flamingo-delete-inbound-message_' . $_REQUEST['post'] + ); + } else { + check_admin_referer( 'bulk-posts' ); + } + + $deleted = 0; + + foreach ( (array) $_REQUEST['post'] as $post ) { + $post = new Flamingo_Inbound_Message( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( + ! current_user_can( 'flamingo_delete_inbound_message', $post->id() ) + ) { + wp_die( + wp_kses_data( __( 'You are not allowed to delete this item.', 'flamingo' ) ) + ); + } + + if ( ! $post->delete() ) { + wp_die( + wp_kses_data( __( 'Error in deleting.', 'flamingo' ) ) + ); + } + + $deleted += 1; + } + + if ( ! empty( $deleted ) ) { + $redirect_to = add_query_arg( + array( + 'message' => 'inbounddeleted', + ), + $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'spam' === $action and ! empty( $_REQUEST['post'] ) ) { + if ( ! is_array( $_REQUEST['post'] ) ) { + check_admin_referer( + 'flamingo-spam-inbound-message_' . $_REQUEST['post'] + ); + } else { + check_admin_referer( 'bulk-posts' ); + } + + $submitted = 0; + + foreach ( (array) $_REQUEST['post'] as $post ) { + $post = new Flamingo_Inbound_Message( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( + ! current_user_can( 'flamingo_spam_inbound_message', $post->id() ) + ) { + wp_die( + wp_kses_data( __( 'You are not allowed to spam this item.', 'flamingo' ) ) + ); + } + + if ( $post->spam() ) { + $submitted += 1; + } + } + + if ( ! empty( $submitted ) ) { + $redirect_to = add_query_arg( + array( + 'message' => 'inboundspammed', + ), + $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( 'unspam' === $action and ! empty( $_REQUEST['post'] ) ) { + if ( ! is_array( $_REQUEST['post'] ) ) { + check_admin_referer( + 'flamingo-unspam-inbound-message_' . $_REQUEST['post'] + ); + } else { + check_admin_referer( 'bulk-posts' ); + } + + $submitted = 0; + + foreach ( (array) $_REQUEST['post'] as $post ) { + $post = new Flamingo_Inbound_Message( $post ); + + if ( empty( $post ) ) { + continue; + } + + if ( + ! current_user_can( 'flamingo_unspam_inbound_message', $post->id() ) + ) { + wp_die( + wp_kses_data( __( 'You are not allowed to unspam this item.', 'flamingo' ) ) + ); + } + + if ( $post->unspam() ) { + $submitted += 1; + } + } + + if ( ! empty( $submitted ) ) { + $redirect_to = add_query_arg( + array( + 'message' => 'inboundunspammed', + ), + $redirect_to + ); + } + + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( ! empty( $_GET['export'] ) ) { + check_admin_referer( 'bulk-posts' ); + + $csv_class = apply_filters( 'flamingo_inbound_csv_class', + 'Flamingo_Inbound_CSV' + ); + + if ( is_subclass_of( $csv_class, 'Flamingo_CSV' ) ) { + $csv_obj = new $csv_class; + $csv_obj->send_http_headers(); + $csv_obj->print_data(); + } + + exit(); + } + + if ( 'edit' === $action ) { + $post_id = (int) ( $_REQUEST['post'] ?? '0' ); + + if ( ! $post_id ) { + wp_safe_redirect( $redirect_to ); + exit(); + } + + if ( + ! current_user_can( 'flamingo_edit_inbound_message', $post_id ) or + Flamingo_Inbound_Message::post_type !== get_post_type( $post_id ) + ) { + wp_die( + wp_kses_data( __( 'You are not allowed to edit this item.', 'flamingo' ) ) + ); + } + + $post = new Flamingo_Inbound_Message( $post_id ); + + add_meta_box( 'submitdiv', __( 'Status', 'flamingo' ), + 'flamingo_inbound_submit_meta_box', null, 'side', 'core' + ); + + if ( ! empty( $post->fields ) ) { + add_meta_box( 'inboundfieldsdiv', __( 'Fields', 'flamingo' ), + 'flamingo_inbound_fields_meta_box', null, 'normal', 'core' + ); + } + + if ( ! empty( $post->consent ) ) { + add_meta_box( 'inboundconsentdiv', __( 'Consent', 'flamingo' ), + 'flamingo_inbound_consent_meta_box', null, 'normal', 'core' + ); + } + + if ( ! empty( $post->recaptcha ) ) { + add_meta_box( 'inboundrecaptchadiv', __( 'reCAPTCHA', 'flamingo' ), + 'flamingo_inbound_recaptcha_meta_box', null, 'normal', 'core' + ); + } + + if ( ! empty( $post->meta ) ) { + add_meta_box( 'inboundmetadiv', __( 'Meta', 'flamingo' ), + 'flamingo_inbound_meta_meta_box', null, 'normal', 'core' + ); + } + + } else { + if ( ! class_exists( 'Flamingo_Inbound_Messages_List_Table' ) ) { + require_once FLAMINGO_PLUGIN_DIR . '/admin/includes/class-inbound-messages-list-table.php'; + } + + $current_screen = get_current_screen(); + + add_filter( 'manage_' . $current_screen->id . '_columns', + array( 'Flamingo_Inbound_Messages_List_Table', 'define_columns' ), + 10, 0 + ); + + add_screen_option( 'per_page', array( + 'default' => 20, + 'option' => 'flamingo_inbound_messages_per_page', + ) ); + } +} + +function flamingo_inbound_admin_page() { + if ( 'edit' === flamingo_current_action() ) { + flamingo_inbound_edit_page(); + return; + } + + $list_table = new Flamingo_Inbound_Messages_List_Table(); + $list_table->prepare_items(); + +?> +
        + +

        + +%s', + wp_kses_data( sprintf( + /* translators: %s: Search query. */ + __( 'Search results for: %s', 'flamingo' ), + esc_html( $_REQUEST['s'] ) + ) ) + ); + } +?> + +
        + + + +views(); ?> + +
        + + + search_box( __( 'Search messages', 'flamingo' ), 'flamingo-inbound' ); ?> + display(); ?> +
        + +
        +id() ) ) { + $nonce_action = 'flamingo-update-contact_' . $post->id(); +} else { + $nonce_action = 'flamingo-add-contact'; +} + +?> +
        + +

        + + + +
        + + +
        +
        + +
        +
        +
        + id() ) ) : ?> + + + + + +
        +
        +
        + +
        + +
        + +
        + +
        + +
        +
        + +
        + +id() ) : ?> + + + + + +
        + +
        diff --git a/html/wp-content/plugins/flamingo/admin/edit-inbound-form.php b/html/wp-content/plugins/flamingo/admin/edit-inbound-form.php new file mode 100644 index 0000000..7da45cc --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/edit-inbound-form.php @@ -0,0 +1,82 @@ +id() ) ) { + $nonce_action = 'flamingo-update-inbound_' . $post->id(); +} else { + $nonce_action = 'flamingo-add-inbound'; +} + +?> +
        + +

        + + + +
        + + +
        +
        + +
        + + + + + + + + + + + + + + +
        :subject ); ?>
        :from_email ) ) { ?>from ); ?>from ); } ?>
        +
        + +
        + +
        + +
        + +
        + +
        +
        + +
        + +id() ) : ?> + + + + + +
        + +
        diff --git a/html/wp-content/plugins/flamingo/admin/includes/admin-functions.php b/html/wp-content/plugins/flamingo/admin/includes/admin-functions.php new file mode 100644 index 0000000..c126a3a --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/admin-functions.php @@ -0,0 +1,27 @@ +get_col( $wpdb->prepare( + "SELECT ID FROM %i WHERE post_status = 'trash' AND post_type = %s", + $wpdb->posts, + $post_type + ) ); +} diff --git a/html/wp-content/plugins/flamingo/admin/includes/class-contacts-list-table.php b/html/wp-content/plugins/flamingo/admin/includes/class-contacts-list-table.php new file mode 100644 index 0000000..271a67a --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/class-contacts-list-table.php @@ -0,0 +1,356 @@ + '', + 'email' => __( 'Email', 'flamingo' ), + 'full_name' => __( 'Name', 'flamingo' ), + 'tags' => __( 'Tags', 'flamingo' ), + 'history' => __( 'History', 'flamingo' ), + 'last_contacted' => __( 'Last contact', 'flamingo' ), + ); + + $columns = apply_filters( + 'manage_flamingo_contact_posts_columns', $columns + ); + + return $columns; + } + + public function __construct() { + parent::__construct( array( + 'singular' => 'post', + 'plural' => 'posts', + 'ajax' => false, + ) ); + } + + public function prepare_items() { + $per_page = $this->get_items_per_page( + 'flamingo_contacts_per_page' + ); + + $args = array( + 'posts_per_page' => $per_page, + 'offset' => ( $this->get_pagenum() - 1 ) * $per_page, + 'orderby' => 'meta_value', + 'order' => 'DESC', + 'meta_key' => '_last_contacted', + ); + + if ( ! empty( $_REQUEST['s'] ) ) { + $args['s'] = $_REQUEST['s']; + } + + if ( ! empty( $_REQUEST['orderby'] ) ) { + if ( 'email' === $_REQUEST['orderby'] ) { + $args['meta_key'] = '_email'; + } elseif ( 'name' === $_REQUEST['orderby'] ) { + $args['meta_key'] = '_name'; + } + } + + if ( + ! empty( $_REQUEST['order'] ) and + 'asc' === strtolower( $_REQUEST['order'] ) + ) { + $args['order'] = 'ASC'; + } + + if ( ! empty( $_REQUEST['contact_tag_id'] ) ) { + $args['contact_tag_id'] = explode( ',', $_REQUEST['contact_tag_id'] ); + } + + $this->items = Flamingo_Contact::find( $args ); + + $total_items = Flamingo_Contact::count(); + $total_pages = ceil( $total_items / $per_page ); + + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'total_pages' => $total_pages, + 'per_page' => $per_page, + ) ); + } + + public function get_columns() { + return get_column_headers( get_current_screen() ); + } + + protected function get_sortable_columns() { + $columns = array( + 'email' => array( 'email', false ), + 'full_name' => array( 'name', false ), + 'last_contacted' => array( 'last_contacted', true ), + ); + + return $columns; + } + + protected function get_bulk_actions() { + $actions = array( + 'delete' => __( 'Delete', 'flamingo' ), + ); + + return $actions; + } + + protected function extra_tablenav( $which ) { + $tag = 0; + + if ( ! empty( $_REQUEST['contact_tag_id'] ) ) { + $tag_id = explode( ',', $_REQUEST['contact_tag_id'] ); + + $term = get_term( $tag_id[0], Flamingo_Contact::contact_tag_taxonomy ); + + if ( ! empty( $term ) and ! is_wp_error( $term ) ) { + $tag = $term->term_id; + } + } + +?> +
        + Flamingo_Contact::contact_tag_taxonomy, + 'name' => 'contact_tag_id', + 'show_option_all' => __( 'View all tags', 'flamingo' ), + 'hide_empty' => 1, + 'hide_if_empty' => 1, + 'orderby' => 'name', + 'selected' => $tag, + ) ); + + if ( array_filter( $filters ) ) { + submit_button( __( 'Filter', 'flamingo' ), + 'secondary', false, false, array( 'id' => 'post-query-submit' ) + ); + } + + submit_button( __( 'Export', 'flamingo' ), 'secondary', 'export', false ); + } +?> +
        +id() + ); + } + + protected function column_cb( $item ) { + return sprintf( + '', + $this->_args['singular'], + $item->id() + ); + } + + protected function column_email( $item ) { + $edit_link = add_query_arg( array( + 'post' => $item->id(), + 'action' => 'edit', + ), menu_page_url( 'flamingo', false ) ); + + if ( current_user_can( 'flamingo_edit_contact', $item->id() ) ) { + return sprintf( + '%3$s', + esc_url( $edit_link ), + esc_attr( sprintf( + /* translators: %s: Item title. */ + __( '“%s” (Edit)', 'flamingo' ), + $item->email + ) ), + esc_html( $item->email ) + ); + } else { + return sprintf( + '%1$s', + esc_html( $item->email ) + ); + } + } + + protected function handle_row_actions( $item, $column_name, $primary ) { + if ( $column_name !== $primary ) { + return ''; + } + + $actions = array(); + + $link = add_query_arg( array( + 'post' => $item->id(), + 'action' => 'edit', + ), menu_page_url( 'flamingo', false ) ); + + if ( current_user_can( 'flamingo_edit_contact', $item->id() ) ) { + $actions['edit'] = sprintf( + '%2$s', + esc_url( $link ), + esc_html( __( 'Edit', 'flamingo' ) ) + ); + } + + return $this->row_actions( $actions ); + } + + protected function column_full_name( $item ) { + return esc_html( $item->name ); + } + + protected function column_tags( $item ) { + if ( empty( $item->tags ) ) { + return esc_html( __( 'No tags', 'flamingo' ) ); + } + + $output = ''; + + foreach ( (array) $item->tags as $tag ) { + $term = get_term_by( 'name', $tag, + Flamingo_Contact::contact_tag_taxonomy + ); + + if ( empty( $term ) or is_wp_error( $term ) ) { + continue; + } + + if ( $output ) { + $output .= ', '; + } + + $link = add_query_arg( array( + 'contact_tag_id' => $term->term_id, + ), menu_page_url( 'flamingo', false ) ); + + $output .= sprintf( '%3$s', + esc_url( $link ), + esc_attr( $term->name ), + esc_html( $term->name ) + ); + } + + return $output; + } + + protected function column_history( $item ) { + $history = array(); + + // User + if ( $user = get_user_by( 'email', $item->email ) ) { + $link = sprintf( 'user-edit.php?user_id=%d', $user->ID ); + + $history[] = sprintf( + '%1$s', + esc_html( __( 'User', 'flamingo' ) ), + admin_url( $link ) + ); + } + + // Comment + $comment_count = (int) get_comments( array( + 'count' => true, + 'author_email' => $item->email, + 'status' => 'approve', + 'type' => 'comment', + ) ); + + if ( 0 < $comment_count ) { + $link = sprintf( 'edit-comments.php?s=%s', urlencode( $item->email ) ); + + $history[] = sprintf( + '%1$s', + esc_html( sprintf( + /* translators: %d: Number of comments. */ + __( 'Comment (%d)', 'flamingo' ), + $comment_count + ) ), + admin_url( $link ) + ); + } + + // Contact channels + $terms = get_terms( array( + 'taxonomy' => Flamingo_Inbound_Message::channel_taxonomy, + ) ); + + if ( ! empty( $terms ) and ! is_wp_error( $terms ) ) { + foreach ( (array) $terms as $term ) { + Flamingo_Inbound_Message::find( array( + 'channel' => $term->slug, + 's' => $item->email, + ) ); + + $count = (int) Flamingo_Inbound_Message::count(); + + if ( ! $count ) { + continue; + } + + $link = add_query_arg( array( + 'channel' => $term->slug, + 's' => $item->email, + ), menu_page_url( 'flamingo_inbound', false ) ); + + $history[] = sprintf( + '%1$s', + esc_html( sprintf( + /* translators: 1: contact channel name, 2: contact count */ + _x( '%1$s (%2$d)', 'contact history', 'flamingo' ), + $term->name, + $count + ) ), + esc_url( $link ) + ); + } + } + + $output = ''; + + foreach ( $history as $item ) { + $output .= sprintf( '
      • %s
      • ', $item ); + } + + return sprintf( '
          %s
        ', $output ); + } + + protected function column_last_contacted( $item ) { + if ( + empty( $item->last_contacted ) or + '0000-00-00 00:00:00' === $item->last_contacted + ) { + return ''; + } + + $datetime = date_create_immutable_from_format( + 'Y-m-d H:i:s', + $item->last_contacted, + wp_timezone() + ); + + if ( false === $datetime ) { + return ''; + } + + $t_time = sprintf( + /* translators: 1: date, 2: time */ + __( '%1$s at %2$s', 'flamingo' ), + /* translators: date format, see https://www.php.net/date */ + $datetime->format( __( 'Y/m/d', 'flamingo' ) ), + /* translators: time format, see https://www.php.net/date */ + $datetime->format( __( 'g:i a', 'flamingo' ) ) + ); + + return $t_time; + } +} diff --git a/html/wp-content/plugins/flamingo/admin/includes/class-inbound-messages-list-table.php b/html/wp-content/plugins/flamingo/admin/includes/class-inbound-messages-list-table.php new file mode 100644 index 0000000..162dda3 --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/class-inbound-messages-list-table.php @@ -0,0 +1,455 @@ + '', + 'subject' => __( 'Subject', 'flamingo' ), + 'from' => __( 'From', 'flamingo' ), + 'channel' => __( 'Channel', 'flamingo' ), + 'date' => __( 'Date', 'flamingo' ), + ); + + $columns = apply_filters( + 'manage_flamingo_inbound_posts_columns', $columns + ); + + return $columns; + } + + public function __construct() { + parent::__construct( array( + 'singular' => 'post', + 'plural' => 'posts', + 'ajax' => false, + ) ); + } + + public function prepare_items() { + $per_page = $this->get_items_per_page( + 'flamingo_inbound_messages_per_page' + ); + + $args = array( + 'posts_per_page' => $per_page, + 'offset' => ( $this->get_pagenum() - 1 ) * $per_page, + 'orderby' => 'date', + 'order' => 'DESC', + ); + + if ( ! empty( $_REQUEST['s'] ) ) { + $args['s'] = $_REQUEST['s']; + } + + if ( ! empty( $_REQUEST['orderby'] ) ) { + if ( 'subject' === $_REQUEST['orderby'] ) { + $args['meta_key'] = '_subject'; + $args['orderby'] = 'meta_value'; + } elseif ( 'from' === $_REQUEST['orderby'] ) { + $args['meta_key'] = '_from'; + $args['orderby'] = 'meta_value'; + } + } + + if ( + ! empty( $_REQUEST['order'] ) and + 'asc' === strtolower( $_REQUEST['order'] ) + ) { + $args['order'] = 'ASC'; + } + + if ( ! empty( $_REQUEST['m'] ) ) { + $args['m'] = $_REQUEST['m']; + } + + if ( ! empty( $_REQUEST['channel_id'] ) ) { + $args['channel_id'] = $_REQUEST['channel_id']; + } + + if ( ! empty( $_REQUEST['channel'] ) ) { + $args['channel'] = $_REQUEST['channel']; + } + + if ( ! empty( $_REQUEST['post_status'] ) ) { + if ( 'trash' === $_REQUEST['post_status'] ) { + $args['post_status'] = 'trash'; + $this->is_trash = true; + } elseif ( 'spam' === $_REQUEST['post_status'] ) { + $args['post_status'] = Flamingo_Inbound_Message::spam_status; + $this->is_spam = true; + } + } + + $this->items = Flamingo_Inbound_Message::find( $args ); + + $total_items = Flamingo_Inbound_Message::count(); + $total_pages = ceil( $total_items / $per_page ); + + $this->set_pagination_args( array( + 'total_items' => $total_items, + 'total_pages' => $total_pages, + 'per_page' => $per_page, + ) ); + } + + protected function get_views() { + $base_url = menu_page_url( 'flamingo_inbound', false ); + $link_data = array(); + + // Inbox + Flamingo_Inbound_Message::find( array( + 'post_status' => 'any', + ) ); + + $posts_in_inbox = Flamingo_Inbound_Message::count(); + + $inbox = sprintf( + /* translators: %s: Number of items. */ + _nx( + 'Inbox (%s)', + 'Inbox (%s)', + $posts_in_inbox, 'posts', 'flamingo' + ), + number_format_i18n( $posts_in_inbox ) + ); + + $link_data['inbox'] = array( + 'url' => $base_url, + 'label' => $inbox, + 'current' => ! $this->is_trash && ! $this->is_spam, + ); + + // Spam + Flamingo_Inbound_Message::find( array( + 'post_status' => Flamingo_Inbound_Message::spam_status, + ) ); + + $posts_in_spam = Flamingo_Inbound_Message::count(); + + $spam = sprintf( + /* translators: %s: Number of items. */ + _nx( + 'Spam (%s)', + 'Spam (%s)', + $posts_in_spam, 'posts', 'flamingo' + ), + number_format_i18n( $posts_in_spam ) + ); + + $link_data['spam'] = array( + 'url' => add_query_arg( 'post_status', 'spam', $base_url ), + 'label' => $spam, + 'current' => $this->is_spam, + ); + + // Trash + Flamingo_Inbound_Message::find( array( + 'post_status' => 'trash', + ) ); + + $posts_in_trash = Flamingo_Inbound_Message::count(); + + if ( $posts_in_trash ) { + $trash = sprintf( + /* translators: %s: Number of items. */ + _nx( + 'Trash (%s)', + 'Trash (%s)', + $posts_in_trash, 'posts', 'flamingo' + ), + number_format_i18n( $posts_in_trash ) + ); + + $link_data['trash'] = array( + 'url' => add_query_arg( 'post_status', 'trash', $base_url ), + 'label' => $trash, + 'current' => $this->is_trash, + ); + } + + return $this->get_views_links( $link_data ); + } + + public function get_columns() { + return get_column_headers( get_current_screen() ); + } + + protected function get_sortable_columns() { + $columns = array( + 'subject' => array( 'subject', false ), + 'from' => array( 'from', false ), + 'date' => array( 'date', true ), + ); + + return $columns; + } + + protected function get_bulk_actions() { + $actions = array(); + + if ( $this->is_trash ) { + $actions['untrash'] = __( 'Restore', 'flamingo' ); + } + + if ( $this->is_trash or ! EMPTY_TRASH_DAYS ) { + $actions['delete'] = __( 'Delete permanently', 'flamingo' ); + } else { + $actions['trash'] = __( 'Move to trash', 'flamingo' ); + } + + if ( $this->is_spam ) { + $actions['unspam'] = __( 'Not spam', 'flamingo' ); + } else { + $actions['spam'] = __( 'Mark as spam', 'flamingo' ); + } + + return $actions; + } + + protected function extra_tablenav( $which ) { + $channel = 0; + + if ( ! empty( $_REQUEST['channel_id'] ) ) { + $term = get_term( $_REQUEST['channel_id'], + Flamingo_Inbound_Message::channel_taxonomy + ); + + if ( ! empty( $term ) and ! is_wp_error( $term ) ) { + $channel = $term->term_id; + } + + } elseif ( ! empty( $_REQUEST['channel'] ) ) { + $term = get_term_by( 'slug', $_REQUEST['channel'], + Flamingo_Inbound_Message::channel_taxonomy + ); + + if ( ! empty( $term ) and ! is_wp_error( $term ) ) { + $channel = $term->term_id; + } + } + +?> +
        +months_dropdown( Flamingo_Inbound_Message::post_type ); + + wp_dropdown_categories( array( + 'taxonomy' => Flamingo_Inbound_Message::channel_taxonomy, + 'name' => 'channel_id', + 'show_option_all' => __( 'View all channels', 'flamingo' ), + 'show_count' => 0, + 'hide_empty' => 1, + 'hide_if_empty' => 1, + 'orderby' => 'name', + 'hierarchical' => 1, + 'selected' => $channel, + ) ); + + submit_button( __( 'Filter', 'flamingo' ), + 'secondary', false, false, array( 'id' => 'post-query-submit' ) + ); + + if ( ! $this->is_spam and ! $this->is_trash ) { + submit_button( __( 'Export', 'flamingo' ), + 'secondary', 'export', false + ); + } + } + + if ( + $this->is_trash and + current_user_can( 'flamingo_delete_inbound_messages' ) + ) { + submit_button( __( 'Empty trash', 'flamingo' ), + 'button-secondary apply', 'delete_all', false + ); + } +?> +
        +id() + ); + } + + protected function column_cb( $item ) { + return sprintf( + '', + $this->_args['singular'], + $item->id() + ); + } + + protected function column_subject( $item ) { + if ( $this->is_trash ) { + return sprintf( '%s', esc_html( $item->subject ) ); + } + + if ( current_user_can( 'flamingo_edit_inbound_message', $item->id() ) ) { + $edit_link = add_query_arg( array( + 'post' => $item->id(), + 'action' => 'edit', + ), menu_page_url( 'flamingo_inbound', false ) ); + + return sprintf( + '%3$s', + esc_url( $edit_link ), + esc_attr( sprintf( + /* translators: %s: Item title. */ + __( '“%s” (Edit)', 'flamingo' ), + $item->subject + ) ), + esc_html( $item->subject ) + ); + } + + return sprintf( '%1$s', + esc_html( $item->subject ) + ); + } + + protected function handle_row_actions( $item, $column_name, $primary ) { + if ( $column_name !== $primary ) { + return ''; + } + + $actions = array(); + + if ( current_user_can( 'flamingo_edit_inbound_message', $item->id() ) ) { + $link = add_query_arg( array( + 'post' => $item->id(), + 'action' => 'edit', + ), menu_page_url( 'flamingo_inbound', false ) ); + + $actions['edit'] = sprintf( '%2$s', + esc_url( $link ), + esc_html( __( 'View', 'flamingo' ) ) + ); + } + + if ( + $item->spam and + current_user_can( 'flamingo_unspam_inbound_message', $item->id() ) + ) { + $link = add_query_arg( array( + 'post' => $item->id(), + 'action' => 'unspam', + ), menu_page_url( 'flamingo_inbound', false ) ); + + $link = wp_nonce_url( $link, + 'flamingo-unspam-inbound-message_' . $item->id() + ); + + $actions['unspam'] = sprintf( '%2$s', + esc_url( $link ), + esc_html( __( 'Not spam', 'flamingo' ) ) + ); + } + + if ( + ! $item->spam and + current_user_can( 'flamingo_spam_inbound_message', $item->id() ) + ) { + $link = add_query_arg( array( + 'post' => $item->id(), + 'action' => 'spam', + ), menu_page_url( 'flamingo_inbound', false ) ); + + $link = wp_nonce_url( $link, + 'flamingo-spam-inbound-message_' . $item->id() + ); + + $actions['spam'] = sprintf( '%2$s', + esc_url( $link ), + esc_html( __( 'Spam', 'flamingo' ) ) + ); + } + + return $this->row_actions( $actions ); + } + + protected function column_from( $item ) { + return esc_html( $item->from ); + } + + protected function column_channel( $item ) { + if ( empty( $item->channel ) ) { + return ''; + } + + $term = get_term_by( 'slug', $item->channel, + Flamingo_Inbound_Message::channel_taxonomy + ); + + if ( empty( $term ) or is_wp_error( $term ) ) { + return $item->channel; + } + + $output = ''; + + $ancestors = (array) get_ancestors( $term->term_id, + Flamingo_Inbound_Message::channel_taxonomy + ); + + while ( $parent = array_pop( $ancestors ) ) { + $parent = get_term( $parent, Flamingo_Inbound_Message::channel_taxonomy ); + + if ( empty( $parent ) or is_wp_error( $parent ) ) { + continue; + } + + $link = add_query_arg( array( + 'channel' => $parent->slug, + ), menu_page_url( 'flamingo_inbound', false ) ); + + $output .= sprintf( '%3$s / ', + esc_url( $link ), + esc_attr( $parent->name ), + esc_html( $parent->name ) + ); + } + + $link = add_query_arg( array( + 'channel' => $term->slug, + ), menu_page_url( 'flamingo_inbound', false ) ); + + $output .= sprintf( '%3$s', + esc_url( $link ), + esc_attr( $term->name ), + esc_html( $term->name ) + ); + + return $output; + } + + protected function column_date( $item ) { + $datetime = get_post_datetime( $item->id() ); + + if ( false === $datetime ) { + return ''; + } + + $t_time = sprintf( + /* translators: 1: date, 2: time */ + __( '%1$s at %2$s', 'flamingo' ), + /* translators: date format, see https://www.php.net/date */ + $datetime->format( __( 'Y/m/d', 'flamingo' ) ), + /* translators: time format, see https://www.php.net/date */ + $datetime->format( __( 'g:i a', 'flamingo' ) ) + ); + + return $t_time; + } +} diff --git a/html/wp-content/plugins/flamingo/admin/includes/css/style-rtl.css b/html/wp-content/plugins/flamingo/admin/includes/css/style-rtl.css new file mode 100644 index 0000000..0d0030e --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/css/style-rtl.css @@ -0,0 +1,20 @@ +table.message-main-fields th, table.message-main-fields td { + text-align: right; +} + +table.message-fields td { + padding: 4px 7px 2px 14px; +} + +table.message-fields td.field-value li { + margin-right: 1em; +} + +.tablenav .actions input.button { + margin: 0 0 0 8px; +} + +#misc-publishing-actions .spam-log .dashicons-before::before { + margin: 0 -1px 0 0; + padding: 0 0 0 3px; +} diff --git a/html/wp-content/plugins/flamingo/admin/includes/css/style.css b/html/wp-content/plugins/flamingo/admin/includes/css/style.css new file mode 100644 index 0000000..4f50e59 --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/css/style.css @@ -0,0 +1,62 @@ +ul.contact-history { + margin: 0; +} + +#poststuff #submitdiv .inside { + margin: 0; + padding: 0; +} + +#poststuff table.form-table tr.contact-prop th { + width: 25%; +} + +table.message-main-fields th, table.message-main-fields td { + font-size: 15px; + text-align: left; + padding: 8px 4px; +} + +table.message-main-fields th { + width: 20%; + color: #555; +} + +table.message-fields td { + padding: 4px 14px 2px 7px; +} + +table.message-fields td.field-title { + font-weight: bold; + width: 24%; +} + +table.message-fields td.field-value p { + overflow-wrap: anywhere; +} + +table.message-fields td.field-value ul { + margin: 0; +} + +table.message-fields td.field-value li { + list-style: disc; + margin-left: 1em; +} + +.tagsdiv { + margin-top: inherit; +} + +.tablenav .actions input.button { + margin: 0 8px 0 0; +} + +#misc-publishing-actions .dashicons-before::before { + position: relative; + top: -1px; + margin-left: -1px; + padding-right: 3px; + vertical-align: top; + color: #82878c; +} diff --git a/html/wp-content/plugins/flamingo/admin/includes/js/index.asset.php b/html/wp-content/plugins/flamingo/admin/includes/js/index.asset.php new file mode 100644 index 0000000..cc1a2b6 --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/js/index.asset.php @@ -0,0 +1,8 @@ + array( + 'wp-i18n', + ), + 'version' => FLAMINGO_VERSION, +); diff --git a/html/wp-content/plugins/flamingo/admin/includes/js/index.js b/html/wp-content/plugins/flamingo/admin/includes/js/index.js new file mode 100644 index 0000000..9b8f52b --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/js/index.js @@ -0,0 +1 @@ +(()=>{"use strict";const e=window.wp.i18n;document.addEventListener("DOMContentLoaded",t=>{document.querySelectorAll(".submitdelete").forEach(t=>{t.addEventListener("click",t=>{if(window.confirm((0,e.__)("You are about to delete this item.\n 'Cancel' to stop, 'OK' to delete.","flamingo")))return!0;t.preventDefault()})}),postboxes.add_postbox_toggles(flamingo.screenId)})})(); \ No newline at end of file diff --git a/html/wp-content/plugins/flamingo/admin/includes/meta-boxes.php b/html/wp-content/plugins/flamingo/admin/includes/meta-boxes.php new file mode 100644 index 0000000..28f2132 --- /dev/null +++ b/html/wp-content/plugins/flamingo/admin/includes/meta-boxes.php @@ -0,0 +1,330 @@ + + +id(), $taxonomy->name ); + $tag_names = $tag_ids = array(); + + if ( ! empty( $tags ) and ! is_wp_error( $tags ) ) { + foreach( $tags as $tag ) { + $tag_names[] = $tag->name; + $tag_ids[] = $tag->term_id; + } + } + + $tag_names = implode( ', ', $tag_names ); + + $most_used_tags = get_terms( array( + 'taxonomy' => Flamingo_Contact::contact_tag_taxonomy, + 'orderby' => 'count', + 'order' => 'DESC', + 'number' => 10, + 'exclude' => $tag_ids, + 'fields' => 'names', + ) ); + + if ( is_wp_error( $most_used_tags ) ) { + $most_used_tags = array(); + } + +?> +
        + + +

        + + +

        +
        + +' . esc_html( $tag ) . ' '; +} ?> +

        + + +
        + +
        +
        +
        +
        + +
        + +
        + +
        + +id() ); + + $submitted_on = sprintf( + /* translators: Publish box date string. 1: Date, 2: Time. */ + __( '%1$s at %2$s', 'flamingo' ), + wp_date( + /* translators: Publish box date format, see https://www.php.net/date */ + _x( 'M j, Y', 'publish box date format', 'flamingo' ), + $submitted_timestamp + ), + wp_date( + /* translators: Publish box time format, see https://www.php.net/date */ + _x( 'H:i', 'publish box time format', 'flamingo' ), + $submitted_timestamp + ) + ); + + echo wp_kses_data( sprintf( + /* translators: %s: Message submission date. */ + __( 'Submitted on: %s', 'flamingo' ), + $submitted_on + ) ); +?> + +
        +submission_status ) ) { + echo '
        ', "\n"; + + echo sprintf( + ' %2$s', + in_array( $post->submission_status, array( 'mail_failed', 'spam' ) ) + ? 'dashicons-no' : 'dashicons-yes', + wp_kses_data( sprintf( + /* translators: %s: Result of the submission. */ + __( 'Submission result: %s', 'flamingo' ), + $post->submission_status + ) ) + ); + + echo '
        ', "\n"; + } + + foreach ( (array) $post->spam_log as $log ) { + echo '
        '; + + echo sprintf( + ' %2$s', + esc_attr( $log['agent'] ?? '' ), + wp_kses_data( sprintf( + /* translators: %s: reason why this message is regarded as spam */ + __( 'Spam log: %s', 'flamingo' ), + $log['reason'] ?? '' + ) ) + ); + + echo '
        '; + } +?> +
        + +
        +
        + +
        +
        +id() ) ) { + if ( ! EMPTY_TRASH_DAYS ) { + $delete_text = __( 'Delete permanently', 'flamingo' ); + } else { + $delete_text = __( 'Move to trash', 'flamingo' ); + } + + $delete_link = add_query_arg( + array( + 'post' => $post->id(), + 'action' => 'trash', + ), + menu_page_url( 'flamingo_inbound', false ) + ); + + $delete_link = wp_nonce_url( + $delete_link, + 'flamingo-trash-inbound-message_' . $post->id() + ); + + echo sprintf( '%2$s', + esc_url( $delete_link ), + esc_html( $delete_text ) + ); + } +?> +
        + +
        + +
        + +
        +
        +
        + + + + + + + + + + + + + + + + + + + + +
        + + + + +fields as $key => $value ) : ?> + + + + + + + +
        +consent; + + if ( empty( $consent ) ) { + return; + } + +?> + + + + $value ) : ?> + + + + + + + +
        + + + + +recaptcha as $key => $value ) : ?> + + + + + + + +
        + + + + +meta as $key => $value ) : ?> + + + + + + + +
        + array( + 'eraser_friendly_name' => __( 'Flamingo Address Book', 'flamingo' ), + 'callback' => 'flamingo_privacy_contact_eraser', + ), + 'flamingo-inbound' => array( + 'eraser_friendly_name' => __( 'Flamingo Inbound Messages', 'flamingo' ), + 'callback' => 'flamingo_privacy_inbound_eraser', + ), + ) ); +} + + +/** + * Callback for the contact data. + */ +function flamingo_privacy_contact_eraser( $email_address, $page = 1 ) { + $number = 100; + + $posts = Flamingo_Contact::find( array( + 'meta_key' => '_email', + 'meta_value' => $email_address, + 'posts_per_page' => $number, + 'paged' => (int) $page, + ) ); + + $items_removed = false; + $items_retained = false; + $messages = array(); + + foreach ( (array) $posts as $post ) { + if ( ! current_user_can( 'flamingo_delete_contact', $post->id() ) ) { + $items_retained = true; + + $messages = array( + __( 'Flamingo Address Book: You are not allowed to delete contact data.', 'flamingo' ), + ); + + continue; + } + + if ( $post->delete() ) { + $items_removed = true; + } else { + $items_retained = true; + } + } + + $done = Flamingo_Contact::count() < $number; + + return array( + 'items_removed' => $items_removed, + 'items_retained' => $items_retained, + 'messages' => array_map( 'esc_html', (array) $messages ), + 'done' => $done, + ); +} + + +/** + * Callback for the inbound messages data. + */ +function flamingo_privacy_inbound_eraser( $email_address, $page = 1 ) { + $number = 100; + + $posts = Flamingo_Inbound_Message::find( array( + 'meta_key' => '_from_email', + 'meta_value' => $email_address, + 'posts_per_page' => $number, + 'paged' => (int) $page, + ) ); + + $items_removed = false; + $items_retained = false; + $messages = array(); + + foreach ( (array) $posts as $post ) { + if ( ! current_user_can( 'flamingo_delete_inbound_message', $post->id() ) ) { + $items_retained = true; + + $messages = array( + __( 'Flamingo Inbound Messages: You are not allowed to delete inbound messages.', 'flamingo' ), + ); + + continue; + } + + if ( $post->delete() ) { + $items_removed = true; + } else { + $items_retained = true; + } + } + + $done = Flamingo_Inbound_Message::count() < $number; + + return array( + 'items_removed' => $items_removed, + 'items_retained' => $items_retained, + 'messages' => array_map( 'esc_html', (array) $messages ), + 'done' => $done, + ); +} diff --git a/html/wp-content/plugins/flamingo/flamingo.php b/html/wp-content/plugins/flamingo/flamingo.php new file mode 100644 index 0000000..e9d444f --- /dev/null +++ b/html/wp-content/plugins/flamingo/flamingo.php @@ -0,0 +1,83 @@ + $data ) { + $query_string .= + $key . '=' . urlencode( wp_unslash( (string) $data ) ) . '&'; + } + + $response = Akismet::http_post( $query_string, 'submit-' . $spam_or_ham ); + + return (bool) $response[1]; +} + +function flamingo_akismet_is_active() { + if ( is_callable( array( 'Akismet', 'get_api_key' ) ) ) { + return (bool) Akismet::get_api_key(); + } + + return false; +} diff --git a/html/wp-content/plugins/flamingo/includes/capabilities.php b/html/wp-content/plugins/flamingo/includes/capabilities.php new file mode 100644 index 0000000..7441818 --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/capabilities.php @@ -0,0 +1,27 @@ + 'edit_users', + 'flamingo_edit_contacts' => 'edit_users', + 'flamingo_delete_contact' => 'edit_users', + 'flamingo_edit_inbound_message' => 'edit_users', + 'flamingo_edit_inbound_messages' => 'edit_users', + 'flamingo_delete_inbound_message' => 'edit_users', + 'flamingo_delete_inbound_messages' => 'edit_users', + 'flamingo_spam_inbound_message' => 'edit_users', + 'flamingo_unspam_inbound_message' => 'edit_users', + ); + + $meta_caps = apply_filters( 'flamingo_map_meta_cap', $meta_caps ); + + $caps = array_diff( $caps, array_keys( $meta_caps ) ); + + if ( isset( $meta_caps[$cap] ) ) { + $caps[] = $meta_caps[$cap]; + } + + return $caps; +} diff --git a/html/wp-content/plugins/flamingo/includes/class-contact.php b/html/wp-content/plugins/flamingo/includes/class-contact.php new file mode 100644 index 0000000..ac9e4a0 --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/class-contact.php @@ -0,0 +1,228 @@ + array( + 'name' => __( 'Flamingo Contacts', 'flamingo' ), + 'singular_name' => __( 'Flamingo Contact', 'flamingo' ), + ), + 'rewrite' => false, + 'query_var' => false, + ) ); + + register_taxonomy( self::contact_tag_taxonomy, self::post_type, array( + 'labels' => array( + 'name' => __( 'Flamingo Contact Tags', 'flamingo' ), + 'singular_name' => __( 'Flamingo Contact Tag', 'flamingo' ), + ), + 'public' => false, + 'rewrite' => false, + 'query_var' => false, + ) ); + } + + public static function find( $args = '' ) { + $defaults = array( + 'posts_per_page' => 10, + 'offset' => 0, + 'orderby' => 'ID', + 'order' => 'ASC', + 'meta_key' => '', + 'meta_value' => '', + 'post_status' => 'any', + 'tax_query' => array(), + 'contact_tag_id' => '', + ); + + $args = wp_parse_args( $args, $defaults ); + + $args['post_type'] = self::post_type; + + if ( ! empty( $args['contact_tag_id'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => self::contact_tag_taxonomy, + 'terms' => $args['contact_tag_id'], + 'field' => 'term_id', + ); + } + + $q = new WP_Query(); + $posts = $q->query( $args ); + + self::$found_items = $q->found_posts; + + $objs = array(); + + foreach ( (array) $posts as $post ) { + $objs[] = new self( $post ); + } + + return $objs; + } + + public static function count( $args = '' ) { + if ( $args ) { + $args = wp_parse_args( $args, array( + 'offset' => 0, + 'post_status' => 'publish', + ) ); + + self::find( $args ); + } + + return absint( self::$found_items ); + } + + public static function search_by_email( $email ) { + $objs = self::find( array( + 'posts_per_page' => 1, + 'orderby' => 'ID', + 'meta_key' => '_email', + 'meta_value' => $email, + ) ); + + if ( empty( $objs ) ) { + return null; + } + + return $objs[0]; + } + + public static function add( $args = '' ) { + $args = wp_parse_args( $args, array( + 'email' => '', + 'name' => '', + 'props' => array(), + 'last_contacted' => '0000-00-00 00:00:00', + ) ); + + $args = apply_filters( 'flamingo_add_contact', $args ); + + if ( empty( $args['email'] ) or ! is_email( $args['email'] ) ) { + return; + } + + $obj = self::search_by_email( $args['email'] ); + + if ( ! $obj ) { + $obj = new self(); + + $obj->email = $args['email']; + $obj->name = $args['name']; + $obj->props = (array) $args['props']; + } + + if ( '0000-00-00 00:00:00' !== $args['last_contacted'] ) { + $obj->last_contacted = $args['last_contacted']; + } elseif ( $datetime = date_create_immutable( 'now', wp_timezone() ) ) { + $obj->last_contacted = $datetime->format( 'Y-m-d H:i:s' ); + } + + $obj->save(); + + return $obj; + } + + public function __construct( $post = null ) { + if ( ! empty( $post ) and $post = get_post( $post ) ) { + $this->id = $post->ID; + $this->email = get_post_meta( $post->ID, '_email', true ); + $this->name = get_post_meta( $post->ID, '_name', true ); + $this->props = get_post_meta( $post->ID, '_props', true ); + $this->last_contacted = + get_post_meta( $post->ID, '_last_contacted', true ); + + $terms = wp_get_object_terms( $this->id, self::contact_tag_taxonomy ); + + if ( ! empty( $terms ) and ! is_wp_error( $terms ) ) { + foreach ( $terms as $term ) { + $this->tags[] = $term->name; + } + } + } + } + + public function __get( $name ) { + if ( 'id' === $name ) { + return $this->id; + } + } + + public function id() { + return $this->id; + } + + public function save() { + $post_title = $this->email; + $post_name = strtr( $this->email, '@', '-' ); + + $fields = flamingo_array_flatten( $this->props ); + $fields = array_merge( $fields, array( $this->email, $this->name ) ); + $fields = array_filter( array_map( 'trim', $fields ) ); + $fields = array_unique( $fields ); + + $post_content = implode( "\n", $fields ); + + $postarr = array( + 'ID' => absint( $this->id ), + 'post_type' => self::post_type, + 'post_status' => 'publish', + 'post_title' => $post_title, + 'post_name' => $post_name, + 'post_content' => $post_content, + ); + + $post_id = wp_insert_post( $postarr ); + + if ( $post_id ) { + $this->id = $post_id; + update_post_meta( $post_id, '_email', $this->email ); + update_post_meta( $post_id, '_name', $this->name ); + update_post_meta( $post_id, '_props', $this->props ); + update_post_meta( $post_id, '_last_contacted', $this->last_contacted ); + + wp_set_object_terms( $this->id, $this->tags, self::contact_tag_taxonomy ); + } + + return $post_id; + } + + public function get_prop( $name ) { + if ( 'name' == $name ) { + return $this->name; + } + + if ( isset( $this->props[$name] ) ) { + return $this->props[$name]; + } + + return ''; + } + + public function delete() { + if ( empty( $this->id ) ) { + return; + } + + if ( $post = wp_delete_post( $this->id, true ) ) { + $this->id = 0; + } + + return (bool) $post; + } + +} diff --git a/html/wp-content/plugins/flamingo/includes/class-inbound-message.php b/html/wp-content/plugins/flamingo/includes/class-inbound-message.php new file mode 100644 index 0000000..2ecd7e5 --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/class-inbound-message.php @@ -0,0 +1,452 @@ + array( + 'name' => __( 'Flamingo Inbound Messages', 'flamingo' ), + 'singular_name' => __( 'Flamingo Inbound Message', 'flamingo' ), + ), + 'rewrite' => false, + 'query_var' => false, + ) ); + + register_post_status( self::spam_status, array( + 'label' => __( 'Spam', 'flamingo' ), + 'public' => false, + 'exclude_from_search' => true, + 'show_in_admin_all_list' => false, + 'show_in_admin_status_list' => true, + ) ); + + register_taxonomy( self::channel_taxonomy, self::post_type, array( + 'labels' => array( + 'name' => __( 'Flamingo Inbound Message Channels', 'flamingo' ), + 'singular_name' => __( 'Flamingo Inbound Message Channel', 'flamingo' ), + ), + 'public' => false, + 'hierarchical' => true, + 'rewrite' => false, + 'query_var' => false, + ) ); + } + + public static function find( $args = '' ) { + $defaults = array( + 'posts_per_page' => 10, + 'offset' => 0, + 'orderby' => 'ID', + 'order' => 'ASC', + 'meta_key' => '', + 'meta_value' => '', + 'post_status' => 'any', + 'tax_query' => array(), + 'channel' => '', + 'channel_id' => 0, + 'hash' => '', + ); + + $args = wp_parse_args( $args, $defaults ); + + $args['post_type'] = self::post_type; + + if ( ! empty( $args['channel_id'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => self::channel_taxonomy, + 'terms' => absint( $args['channel_id'] ), + 'field' => 'term_id', + ); + } + + if ( ! empty( $args['channel'] ) ) { + $args['tax_query'][] = array( + 'taxonomy' => self::channel_taxonomy, + 'terms' => $args['channel'], + 'field' => 'slug', + ); + } + + if ( ! empty( $args['hash'] ) ) { + $args['meta_query'][] = array( + 'key' => '_hash', + 'value' => $args['hash'], + ); + } + + $q = new WP_Query(); + $posts = $q->query( $args ); + + self::$found_items = $q->found_posts; + + $objs = array(); + + foreach ( (array) $posts as $post ) { + $objs[] = new self( $post ); + } + + return $objs; + } + + public static function count( $args = '' ) { + if ( $args ) { + $args = wp_parse_args( $args, array( + 'offset' => 0, + 'channel' => '', + 'channel_id' => 0, + 'post_status' => 'publish', + ) ); + + self::find( $args ); + } + + return absint( self::$found_items ); + } + + public static function add( $args = '' ) { + $args = wp_parse_args( $args, array( + 'channel' => '', + 'status' => '', + 'subject' => '', + 'from' => '', + 'from_name' => '', + 'from_email' => '', + 'fields' => array(), + 'meta' => array(), + 'akismet' => array(), + 'recaptcha' => array(), + 'spam' => false, + 'spam_log' => array(), + 'consent' => array(), + 'timestamp' => null, + 'posted_data_hash' => null, + ) ); + + $args = apply_filters( 'flamingo_add_inbound', $args ); + + $obj = new self(); + + $obj->channel = $args['channel']; + $obj->submission_status = $args['status']; + $obj->subject = $args['subject']; + $obj->from = $args['from']; + $obj->from_name = $args['from_name']; + $obj->from_email = $args['from_email']; + $obj->fields = $args['fields']; + $obj->meta = $args['meta']; + $obj->akismet = $args['akismet']; + $obj->recaptcha = $args['recaptcha']; + $obj->spam = $args['spam']; + $obj->spam_log = $args['spam_log']; + $obj->consent = $args['consent']; + + if ( $args['timestamp'] ) { + $obj->timestamp = $args['timestamp']; + } + + if ( $args['posted_data_hash'] ) { + $obj->hash = $args['posted_data_hash']; + } + + $obj->save(); + + return $obj; + } + + public function __construct( $post = null ) { + if ( ! empty( $post ) and $post = get_post( $post ) ) { + $this->id = $post->ID; + $this->subject = get_post_meta( $post->ID, '_subject', true ); + $this->from = get_post_meta( $post->ID, '_from', true ); + $this->from_name = get_post_meta( $post->ID, '_from_name', true ); + $this->from_email = get_post_meta( $post->ID, '_from_email', true ); + $this->fields = get_post_meta( $post->ID, '_fields', true ); + + if ( ! empty( $this->fields ) ) { + foreach ( (array) $this->fields as $key => $value ) { + $meta_key = sanitize_key( '_field_' . $key ); + + if ( metadata_exists( 'post', $post->ID, $meta_key ) ) { + $value = get_post_meta( $post->ID, $meta_key, true ); + $this->fields[$key] = $value; + } + } + } + + $this->submission_status = get_post_meta( $post->ID, + '_submission_status', true + ); + + $this->meta = get_post_meta( $post->ID, '_meta', true ); + $this->akismet = get_post_meta( $post->ID, '_akismet', true ); + $this->recaptcha = get_post_meta( $post->ID, '_recaptcha', true ); + $this->spam_log = get_post_meta( $post->ID, '_spam_log', true ); + $this->consent = get_post_meta( $post->ID, '_consent', true ); + + $terms = wp_get_object_terms( $this->id, self::channel_taxonomy ); + + if ( ! empty( $terms ) and ! is_wp_error( $terms ) ) { + $this->channel = $terms[0]->slug; + } + + if ( self::spam_status == get_post_status( $post ) ) { + $this->spam = true; + } else { + $this->spam = isset( $this->akismet['spam'] ) && $this->akismet['spam']; + } + + $this->hash = get_post_meta( $post->ID, '_hash', true ); + } + } + + public function __get( $name ) { + if ( 'id' === $name ) { + return $this->id; + } + } + + public function id() { + return $this->id; + } + + public function save() { + if ( ! empty( $this->subject ) ) { + $post_title = $this->subject; + } else { + $post_title = __( '(No Title)', 'flamingo' ); + } + + $post_content = array_merge( + (array) $this->fields, + (array) $this->consent, + (array) $this->meta + ); + + $post_content = flamingo_array_flatten( $post_content ); + $post_content = array_filter( array_map( 'trim', $post_content ) ); + $post_content = implode( "\n", $post_content ); + + $post_status = $this->spam ? self::spam_status : 'publish'; + + $postarr = array( + 'ID' => absint( $this->id ), + 'post_type' => self::post_type, + 'post_status' => $post_status, + 'post_title' => $post_title, + 'post_content' => $post_content, + 'post_date' => $this->get_post_date(), + ); + + if ( + $this->timestamp and + $datetime = date_create( '@' . $this->timestamp ) + ) { + $datetime->setTimezone( wp_timezone() ); + $postarr['post_date'] = $datetime->format( 'Y-m-d H:i:s' ); + } + + $post_id = wp_insert_post( $postarr ); + + if ( $post_id ) { + $this->id = $post_id; + + switch ( $post_status ) { + case self::spam_status: + update_post_meta( $post_id, '_spam_meta_time', time() ); + break; + case 'trash': + // Do nothing. + break; + default: + delete_post_meta( $post_id, '_spam_meta_time' ); + } + + update_post_meta( $post_id, '_submission_status', + $this->submission_status + ); + + update_post_meta( $post_id, '_subject', $this->subject ); + update_post_meta( $post_id, '_from', $this->from ); + update_post_meta( $post_id, '_from_name', $this->from_name ); + update_post_meta( $post_id, '_from_email', $this->from_email ); + + foreach ( $this->fields as $key => $value ) { + $meta_key = sanitize_key( '_field_' . $key ); + update_post_meta( $post_id, $meta_key, $value ); + $this->fields[$key] = null; + } + + update_post_meta( $post_id, '_fields', $this->fields ); + update_post_meta( $post_id, '_meta', $this->meta ); + update_post_meta( $post_id, '_akismet', $this->akismet ); + update_post_meta( $post_id, '_recaptcha', $this->recaptcha ); + update_post_meta( $post_id, '_spam_log', $this->spam_log ); + update_post_meta( $post_id, '_consent', $this->consent ); + update_post_meta( $post_id, '_hash', $this->hash ); + + if ( term_exists( $this->channel, self::channel_taxonomy ) ) { + wp_set_object_terms( + $this->id, + $this->channel, + self::channel_taxonomy + ); + } + } + + return $post_id; + } + + private function get_post_date() { + if ( empty( $this->id ) ) { + return false; + } + + $post = get_post( $this->id ); + + if ( ! $post ) { + return false; + } + + return $post->post_date; + } + + public function trash() { + if ( empty( $this->id ) ) { + return; + } + + if ( ! EMPTY_TRASH_DAYS ) { + return $this->delete(); + } + + $post = wp_trash_post( $this->id ); + + return (bool) $post; + } + + public function untrash() { + if ( empty( $this->id ) ) { + return; + } + + $post = wp_untrash_post( $this->id ); + + return (bool) $post; + } + + public function delete() { + if ( empty( $this->id ) ) { + return; + } + + if ( $post = wp_delete_post( $this->id, true ) ) { + $this->id = 0; + } + + return (bool) $post; + } + + public function spam() { + if ( $this->spam ) { + return; + } + + $this->akismet_submit_spam(); + $this->spam = true; + + $user_name = get_user_option( 'user_login' ); + + if ( false === $user_name ) { + $user_name = __( 'Unknown', 'flamingo' ); + } + + if ( empty( $this->spam_log ) ) { + $this->spam_log = array(); + } + + $this->spam_log[] = array( + 'agent' => 'flamingo', + 'reason' => sprintf( + /* translators: %s: WordPress user name */ + __( '%s has marked this message as spam.', 'flamingo' ), + $user_name + ), + ); + + return $this->save(); + } + + public function akismet_submit_spam() { + if ( empty( $this->id ) or empty( $this->akismet ) ) { + return; + } + + if ( isset( $this->akismet['spam'] ) and $this->akismet['spam'] ) { + return; + } + + if ( empty( $this->akismet['comment'] ) ) { + return; + } + + if ( flamingo_akismet_submit_spam( $this->akismet['comment'] ) ) { + $this->akismet['spam'] = true; + update_post_meta( $this->id, '_akismet', $this->akismet ); + return true; + } + } + + public function unspam() { + if ( ! $this->spam ) { + return; + } + + $this->akismet_submit_ham(); + $this->spam = false; + + return $this->save(); + } + + public function akismet_submit_ham() { + if ( empty( $this->id ) or empty( $this->akismet ) ) { + return; + } + + if ( isset( $this->akismet['spam'] ) and ! $this->akismet['spam'] ) { + return; + } + + if ( empty( $this->akismet['comment'] ) ) { + return; + } + + if ( flamingo_akismet_submit_ham( $this->akismet['comment'] ) ) { + $this->akismet['spam'] = false; + update_post_meta( $this->id, '_akismet', $this->akismet ); + return true; + } + } +} diff --git a/html/wp-content/plugins/flamingo/includes/comment.php b/html/wp-content/plugins/flamingo/includes/comment.php new file mode 100644 index 0000000..933a2b5 --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/comment.php @@ -0,0 +1,79 @@ +comment_approved ) { + return; + } + + Flamingo_Contact::add( array( + 'email' => $comment->comment_author_email, + 'name' => $comment->comment_author, + 'channel' => 'comment', + ) ); +} + + +add_action( 'transition_comment_status', + 'flamingo_transition_comment_status', + 10, 3 +); + +/** + * Creates a Flamingo_Contact record when the comment status changes. + */ +function flamingo_transition_comment_status( $new_status, $old_status, $comment ) { + if ( 'approved' !== $new_status ) { + return; + } + + $email = $comment->comment_author_email; + $name = $comment->comment_author; + + Flamingo_Contact::add( array( + 'email' => $email, + 'name' => $name, + 'channel' => 'comment', + ) ); +} + + +add_action( 'activate_' . FLAMINGO_PLUGIN_BASENAME, + 'flamingo_collect_contacts_from_comments', + 10, 0 +); + +/** + * Creates Flamingo_Contact records for existing comments. + */ +function flamingo_collect_contacts_from_comments() { + $comments = get_comments( array( + 'status' => 'approve', + 'type' => 'comment', + 'number' => 20, + ) ); + + foreach ( $comments as $comment ) { + $email = $comment->comment_author_email; + $name = $comment->comment_author; + + if ( empty( $email ) ) { + continue; + } + + Flamingo_Contact::add( array( + 'email' => $email, + 'name' => $name, + 'channel' => 'comment', + ) ); + } +} diff --git a/html/wp-content/plugins/flamingo/includes/cron.php b/html/wp-content/plugins/flamingo/includes/cron.php new file mode 100644 index 0000000..4a70157 --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/cron.php @@ -0,0 +1,46 @@ +get_file_name(); + $charset = get_option( 'blog_charset' ); + + header( "Content-Description: File Transfer" ); + header( "Content-Disposition: attachment; filename=$filename" ); + header( "Content-Type: text/csv; charset=$charset" ); + } + + public function print_data() { + echo ''; + } + +} + + +class Flamingo_Contact_CSV extends Flamingo_CSV { + + public function get_file_name() { + return sprintf( + '%1$s-flamingo-contact-%2$s.csv', + sanitize_key( get_bloginfo( 'name' ) ), + wp_date( 'Y-m-d' ) + ); + } + + public function print_data() { + $labels = array( + __( 'Email', 'flamingo' ), + __( 'Full name', 'flamingo' ), + __( 'First name', 'flamingo' ), + __( 'Last name', 'flamingo' ), + ); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo flamingo_csv_row( $labels ); + + $args = array( + 'posts_per_page' => -1, + 'orderby' => 'meta_value', + 'order' => 'ASC', + 'meta_key' => '_email', + ); + + if ( ! empty( $_GET['s'] ) ) { + $args['s'] = $_GET['s']; + } + + if ( ! empty( $_GET['orderby'] ) ) { + if ( 'email' === $_GET['orderby'] ) { + $args['meta_key'] = '_email'; + } elseif ( 'name' === $_GET['orderby'] ) { + $args['meta_key'] = '_name'; + } + } + + if ( + ! empty( $_GET['order'] ) and + 'asc' === strtolower( $_GET['order'] ) + ) { + $args['order'] = 'ASC'; + } + + if ( ! empty( $_GET['contact_tag_id'] ) ) { + $args['contact_tag_id'] = explode( ',', $_GET['contact_tag_id'] ); + } + + $items = Flamingo_Contact::find( $args ); + + foreach ( $items as $item ) { + echo "\r\n"; + + $row = array( + $item->email, + $item->get_prop( 'name' ), + $item->get_prop( 'first_name' ), + $item->get_prop( 'last_name' ), + ); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo flamingo_csv_row( $row ); + } + } + +} + + +class Flamingo_Inbound_CSV extends Flamingo_CSV { + + public function get_file_name() { + return sprintf( + '%1$s-flamingo-inbound-%2$s.csv', + sanitize_key( get_bloginfo( 'name' ) ), + wp_date( 'Y-m-d' ) + ); + } + + public function print_data() { + $args = array( + 'posts_per_page' => -1, + 'orderby' => 'date', + 'order' => 'DESC', + ); + + if ( ! empty( $_REQUEST['s'] ) ) { + $args['s'] = $_REQUEST['s']; + } + + if ( ! empty( $_REQUEST['orderby'] ) ) { + if ( 'subject' === $_REQUEST['orderby'] ) { + $args['meta_key'] = '_subject'; + $args['orderby'] = 'meta_value'; + } elseif ( 'from' === $_REQUEST['orderby'] ) { + $args['meta_key'] = '_from'; + $args['orderby'] = 'meta_value'; + } + } + + if ( + ! empty( $_REQUEST['order'] ) and + 'asc' === strtolower( $_REQUEST['order'] ) + ) { + $args['order'] = 'ASC'; + } + + if ( ! empty( $_REQUEST['m'] ) ) { + $args['m'] = $_REQUEST['m']; + } + + if ( ! empty( $_REQUEST['channel_id'] ) ) { + $args['channel_id'] = $_REQUEST['channel_id']; + } + + if ( ! empty( $_REQUEST['channel'] ) ) { + $args['channel'] = $_REQUEST['channel']; + } + + $items = Flamingo_Inbound_Message::find( $args ); + + if ( empty( $items ) ) { + return; + } + + $labels = array_keys( $items[0]->fields ); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo flamingo_csv_row( + array_merge( $labels, array( __( 'Date', 'flamingo' ) ) ) + ); + + foreach ( $items as $item ) { + echo "\r\n"; + + $row = array(); + + foreach ( $labels as $label ) { + $col = isset( $item->fields[$label] ) ? $item->fields[$label] : ''; + + if ( is_array( $col ) ) { + $col = flamingo_array_flatten( $col ); + $col = array_filter( array_map( 'trim', $col ) ); + $col = implode( ', ', $col ); + } + + $row[] = $col; + } + + $row[] = get_post_time( 'c', false, $item->id() ); // Date + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo flamingo_csv_row( $row ); + } + } + +} + + +/** + * Retrieves text that represents a CSV row. + */ +function flamingo_csv_row( $inputs = array() ) { + $row = array(); + + foreach ( $inputs as $input ) { + $row[] = apply_filters( 'flamingo_csv_quotation', $input ); + } + + $separator = apply_filters( 'flamingo_csv_value_separator', ',' ); + + return implode( $separator, $row ); +} + + +add_filter( 'flamingo_csv_quotation', 'flamingo_csv_quote', 10, 1 ); + +/** + * Retrieves text that represents a CSV cell with quotation. + */ +function flamingo_csv_quote( $input ) { + $prefix = apply_filters( 'flamingo_csv_field_prefix', '', $input ); + $input = trim( sprintf( '%1$s %2$s', $prefix, $input ) ); + + return sprintf( '"%s"', str_replace( '"', '""', $input ) ); +} + + +add_filter( 'flamingo_csv_field_prefix', + 'flamingo_csv_field_prefix_text', + 10, 2 +); + +/** + * Adds a security alert at the head of a cell. + * + * @see https://contactform7.com/2020/01/15/heads-up-about-spreadsheet-vulnerabilities/ + */ +function flamingo_csv_field_prefix_text( $prefix, $input ) { + $formula_triggers = array( '=', '+', '-', '@' ); + + if ( in_array( substr( $input, 0, 1 ), $formula_triggers, true ) ) { + /* translators: %s: URL */ + $prefix = __( '(Security Alert: Suspicious content is detected. See %s for details.)', 'flamingo' ); + + if ( in_array( substr( $prefix, 0, 1 ), $formula_triggers, true ) ) { + $prefix = '\'' . $prefix; + } + + $prefix = sprintf( + $prefix, + esc_url( __( 'https://contactform7.com/heads-up-about-spreadsheet-vulnerabilities', 'flamingo' ) ) + ); + } + + return $prefix; +} diff --git a/html/wp-content/plugins/flamingo/includes/formatting.php b/html/wp-content/plugins/flamingo/includes/formatting.php new file mode 100644 index 0000000..b28ea46 --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/formatting.php @@ -0,0 +1,17 @@ +%s', flamingo_htmlize( $v ) ); + } + + $result = sprintf( '
          %s
        ', $result ); + } else { + $result = wpautop( esc_html( (string) $val ) ); + } + + return apply_filters( 'flamingo_htmlize', $result, $val ); +} diff --git a/html/wp-content/plugins/flamingo/includes/functions.php b/html/wp-content/plugins/flamingo/includes/functions.php new file mode 100644 index 0000000..e39c72f --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/functions.php @@ -0,0 +1,60 @@ + 20, + 'meta_key' => '_spam_meta_time', + 'meta_value' => time() - ( DAY_IN_SECONDS * FLAMINGO_MOVE_TRASH_DAYS ), + 'meta_compare' => '<', + 'orderby' => 'meta_value_num', + 'order' => 'ASC', + 'post_status' => Flamingo_Inbound_Message::spam_status, + ) ); + + foreach ( $posts_to_move as $post ) { + $post->trash(); + } +} diff --git a/html/wp-content/plugins/flamingo/includes/user.php b/html/wp-content/plugins/flamingo/includes/user.php new file mode 100644 index 0000000..aa78d2c --- /dev/null +++ b/html/wp-content/plugins/flamingo/includes/user.php @@ -0,0 +1,68 @@ +user_email; + $name = $user->display_name; + + $props = array( + 'first_name' => $user->first_name, + 'last_name' => $user->last_name, + ); + + if ( ! empty( $email ) ) { + Flamingo_Contact::add( array( + 'email' => $email, + 'name' => $name, + 'props' => $props, + 'channel' => 'user', + ) ); + } +} + + +add_action( 'activate_' . FLAMINGO_PLUGIN_BASENAME, + 'flamingo_collect_contacts_from_users', + 10, 0 +); + +/** + * Creates Flamingo_Contact records for existing users. + */ +function flamingo_collect_contacts_from_users() { + $users = get_users( array( + 'number' => 20, + ) ); + + foreach ( $users as $user ) { + $email = $user->user_email; + $name = $user->display_name; + + if ( empty( $email ) ) { + continue; + } + + $props = array( + 'first_name' => empty( $user->first_name ) ? '' : $user->first_name, + 'last_name' => empty( $user->last_name ) ? '' : $user->last_name, + ); + + Flamingo_Contact::add( array( + 'email' => $email, + 'name' => $name, + 'props' => $props, + 'channel' => 'user', + ) ); + } +} diff --git a/html/wp-content/plugins/flamingo/languages/readme.txt b/html/wp-content/plugins/flamingo/languages/readme.txt new file mode 100644 index 0000000..eb2dfb2 --- /dev/null +++ b/html/wp-content/plugins/flamingo/languages/readme.txt @@ -0,0 +1,4 @@ +Translations have moved to +https://translate.wordpress.org/projects/wp-plugins/flamingo + +Thank you for your contribution. diff --git a/html/wp-content/plugins/flamingo/license.txt b/html/wp-content/plugins/flamingo/license.txt new file mode 100644 index 0000000..e420c03 --- /dev/null +++ b/html/wp-content/plugins/flamingo/license.txt @@ -0,0 +1,360 @@ +Flamingo WordPress Plugin + +Copyright (C) 2012-2025 Takayuki Miyoshi 2025 Rock Lobster Inc. +Flamingo is distributed under the terms of the GNU GPL + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/html/wp-content/plugins/flamingo/readme.txt b/html/wp-content/plugins/flamingo/readme.txt new file mode 100644 index 0000000..d061234 --- /dev/null +++ b/html/wp-content/plugins/flamingo/readme.txt @@ -0,0 +1,53 @@ +=== Flamingo === +Contributors: rocklobsterinc, takayukister, megumithemes, itpixelz +Tags: bird, contact, mail, crm +Requires at least: 6.7 +Tested up to: 6.9 +Stable tag: 2.6.1 +Requires PHP: 7.4 +License: GPLv2 or later +License URI: https://www.gnu.org/licenses/gpl-2.0.html +Donate link: https://contactform7.com/donate/ + +A trustworthy message storage plugin for Contact Form 7. + +== Description == + +Flamingo is a message storage plugin originally created for [Contact Form 7](https://wordpress.org/plugins/contact-form-7/), which doesn't store submitted messages. + +After activation of the plugin, you'll find **Flamingo** on the WordPress admin screen menu. All messages through contact forms are listed there and are searchable. With Flamingo, you no longer need to worry about losing important messages due to mail server issues or misconfiguration in mail setup. + +For more detailed information, please refer to the [Contact Form 7 documentation page](https://contactform7.com/save-submitted-messages-with-flamingo/). + += Privacy Notices = + +This plugin stores submission data collected through contact forms, which may include the submitters' personal information, in the database on the server that hosts the website. + +== Installation == + +1. Upload the entire `flamingo` folder to the `/wp-content/plugins/` directory. +1. Activate the plugin through the 'Plugins' menu in WordPress. + +== Frequently Asked Questions == + +== Screenshots == + +== Changelog == + += 2.6.1 = + +* Updates Node modules. +* Confirmed WordPress 6.9 compatibility. + += 2.6 = + +* Bumps up the minimum required WordPress version to 6.7. +* Fixes errors reported by PCP. +* Performs a tune-up for the cron job scheduling. + += 2.5 = + +* Bumps up the minimum required WordPress version to 6.4. +* Uses `wp_json_encode()` instead of `json_encode()`. +* Uses `get_views_links()`. +* Uses null coalescing operators. diff --git a/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorindexnow.php b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorindexnow.php new file mode 100644 index 0000000..9fb050d --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorindexnow.php @@ -0,0 +1,103 @@ +siteUrl = get_home_url(); + $this->version = $this->getVersion(); + $apiKey = $this->getApiKey(); + + return $this->sendToIndex($this->siteUrl, $indexUrl, $apiKey, false); + } + + public function getApiKey() { + $meta_key = $this->prefix . "admin_api_key"; + $apiKey = is_multisite() ? get_site_option($meta_key) : get_option($meta_key); + if ($apiKey) return base64_decode($apiKey); + + return false; + } + + private function sendToIndex($site_url, $url, $api_key, $is_manual_submission){ + + $data = json_encode( + array( + 'host' => $this->remove_scheme( $site_url ), + 'key' => $api_key, + 'keyLocation' => trailingslashit( $site_url ) . $api_key . '.txt', + 'urlList' => array( $url ), + ) + ); + + $response = wp_remote_post( + 'https://api.indexnow.org/indexnow/', + array( + 'body' => $data, + 'headers' => array( + 'Content-Type' => 'application/json', + 'X-Source-Info' => 'https://wordpress.com/' . $this->version . '/' . $is_manual_submission + ), + ) + ); + + if (is_wp_error( $response )) { + if ( true === WP_DEBUG && true === WP_DEBUG_LOG) { + error_log(__METHOD__ . " error:WP_Error: ".$response->get_error_message()) ; + } + return "error:WP_Error"; + } + if ( isset( $response['errors'] ) ) { + return 'error:RequestFailed'; + } + try { + if (in_array($response['response']['code'], [200, 202])) { + return 'success'; + } else { + if ( 400 === $response['response']['code'] ) { + return 'error:InvalidRequest'; + } else + if ( 403 === $response['response']['code'] ) { + return 'error:InvalidApiKey'; + } else + if ( 422 === $response['response']['code'] ) { + return 'error:InvalidUrl'; + }else + if ( 429 === $response['response']['code'] ) { + return 'error:UnknownError'; + }else { + return 'error: ' . $response['response']['message']; + if ( true === WP_DEBUG && true === WP_DEBUG_LOG) { + error_log(__METHOD__ . " body : ". json_decode($response['body'])->message) ; + } + } + } + } catch ( \Throwable $th ) { + return 'error:RequestFailed'; + } + + } + + private function remove_scheme( $url ) { + if ( 'http://' === substr( $url, 0, 7 ) ) { + return substr( $url, 7 ); + } + if ( 'https://' === substr( $url, 0, 8 ) ) { + return substr( $url, 8 ); + } + return $url; + } + + private function getVersion(){ + if ( isset( $GLOBALS['sm_version']) ) { + $this->version = $GLOBALS['sm_version']; + } else { + $this->version = '1.0.1'; + } + } + +} \ No newline at end of file diff --git a/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorloader.php b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorloader.php new file mode 100644 index 0000000..35035b0 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorloader.php @@ -0,0 +1,1321 @@ + 'index.php?xml_sitemap=params=$matches[2]', + '.*-misc\.xml\.gz$' => 'index.php?xml_sitemap=params=$matches[2];zip=true', + '.*-misc\.html$' => 'index.php?xml_sitemap=params=$matches[2];html=true', + '.*-misc\.html\.gz$' => 'index.php?xml_sitemap=params=$matches[2];html=true;zip=true', + '.*-sitemap(?:\d{1,4}(?!-misc)|-misc)?\.xml$' => 'index.php?xml_sitemap=params=$matches[2]', + '.*-sitemap(?:\d{1,4}(?!-misc)|-misc)?\.xml\.gz$' => 'index.php?xml_sitemap=params=$matches[2];zip=true', + '.*-sitemap(?:\d{1,4}(?!-misc)|-misc)?\.html$' => 'index.php?xml_sitemap=params=$matches[2];html=true', + '.*-sitemap(?:\d{1,4}(?!-misc)|-misc)?\.html\.gz$' => 'index.php?xml_sitemap=params=$matches[2];html=true;zip=true', + $sm_sitemap_name . '(?:\d{1,4}(?!-misc)|-misc)?\.xml$' => 'index.php?xml_sitemap=params=$matches[2]', + $sm_sitemap_name . '(?:\d{1,4}(?!-misc)|-misc)?\.xml\.gz$' => 'index.php?xml_sitemap=params=$matches[2];zip=true', + $sm_sitemap_name . '(?:\d{1,4}(?!-misc)|-misc)?\.html$' => 'index.php?xml_sitemap=params=$matches[2];html=true', + $sm_sitemap_name . '(?:\d{1,4}(?!-misc)|-misc)?\.html.gz$' => 'index.php?xml_sitemap=params=$matches[2];html=true;zip=true', + ); + return array_merge( $sm_rules, $wp_rules ); + } + + /** + * Returns the rules required for Nginx permalinks + * + * @return string[] + */ + public static function get_ngin_x_rules() { + return array( + 'rewrite ^/.*-misc?\.xml$ "/index.php?xml_sitemap=params=$2" last;', + 'rewrite ^/.*-misc?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;', + 'rewrite ^/.*-misc?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;', + 'rewrite ^/.*-misc?\.html\.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;', + + 'rewrite ^/.*-sitemap.*(?:\d\{1,4\}(?!-misc)|-misc)?\.xml$ "/index.php?xml_sitemap=params=$2" last;', + 'rewrite ^/.*-sitemap.*(?:\d\{1,4\}(?!-misc)|-misc)?\.xml\.gz$ "/index.php?xml_sitemap=params=$2;zip=true" last;', + 'rewrite ^/.*-sitemap.*(?:\d\{1,4\}(?!-misc)|-misc)?\.html$ "/index.php?xml_sitemap=params=$2;html=true" last;', + 'rewrite ^/.*-sitemap.*(?:\d\{1,4\}(?!-misc)|-misc)?\.html\.gz$ "/index.php?xml_sitemap=params=$2;html=true;zip=true" last;', + ); + + } + + /** + * Adds the filters for wp rewrite rule adding + * + * @since 4.0 + * @uses add_filter() + */ + public static function setup_rewrite_hooks() { + add_filter( 'rewrite_rules_array', array( __CLASS__, 'add_rewrite_rules' ), 1, 1 ); + } + + /** + * Deregisters the plugin specific rewrite rules + * + * Combined: sitemap(-+([a-zA-Z0-9_-]+))?\.(xml|html)(.gz)?$ + * + * @since 4.0 + * @param array $wp_rules Array of existing rewrite rules . + * @return Array An array containing the new rewrite rules + */ + public static function remove_rewrite_rules( $wp_rules ) { + $sm_rules = array( + '.*\.xml$' => 'index.php?xml_sitemap=params=$matches[2]', + '.*\.xml\.gz$' => 'index.php?xml_sitemap=params=$matches[2];zip=true', + '.*\.html$' => 'index.php?xml_sitemap=params=$matches[2];html=true', + '.*\.html\.gz$' => 'index.php?xml_sitemap=params=$matches[2];html=true;zip=true', + ); + foreach ( $wp_rules as $key => $value ) { + if ( array_key_exists( $key, $sm_rules ) ) { + unset( $wp_rules[ $key ] ); + } + } + return $wp_rules; + } + + /** + * Remove rewrite hooks method + */ + public static function remove_rewrite_hooks() { + add_filter( 'rewrite_rules_array', array( __CLASS__, 'remove_rewrite_rules' ), 1, 1 ); + } + + /** + * Flushes the rewrite rules + * + * @since 4.0 + * @global $wp_rewrite WP_Rewrite + * @uses WP_Rewrite::flush_rules() + */ + public static function activate_rewrite() { + // @var $wp_rewrite WP_Rewrite . + global $wp_rewrite; + $wp_rewrite->flush_rules( false ); + update_option( 'sm_rewrite_done', self::$svn_version ); + } + + /** + * Handled the plugin activation on installation + * + * @uses GoogleSitemapGeneratorLoader::activate_rewrite + * @since 4.0 + */ + public static function activate_plugin() { + self::setup_rewrite_hooks(); + self::activate_rewrite(); + + self::activation_indexnow_setup(); //activtion indexNow + + if ( self::load_plugin() ) { + $gsg = GoogleSitemapGenerator::get_instance(); + if ( $gsg->old_file_exists() ) { + $gsg->delete_old_files(); + } + } + + } + + /** + * Handled the plugin deactivation + * + * @uses GoogleSitemapGeneratorLoader::activate_rewrite + * @since 4.0 + */ + public static function deactivate_plugin() { + global $wp_rewrite; + delete_option( 'sm_rewrite_done' ); + wp_clear_scheduled_hook( 'sm_ping_daily' ); + self::remove_rewrite_hooks(); + $wp_rewrite->flush_rules( false ); + self::deactivation_indexnow(); // deactivation indexNow plugin + } + + + /** + * Handles the plugin output on template redirection if the xml_sitemap query var is present. + * + * @since 4.0 + */ + public static function do_template_redirect() { + // @var $wp_query WP_Query . + global $wp_query; + if ( ! empty( $wp_query->query_vars['xml_sitemap'] ) ) { + $wp_query->is_404 = false; + $wp_query->is_feed = true; + self::call_show_sitemap( $wp_query->query_vars['xml_sitemap'] ); + } + } + + /** + * Registers the plugin in the admin menu system + * + * @uses add_options_page() + */ + public static function register_admin_page() { + add_options_page( __( 'XML-Sitemap Generator', 'google-sitemap-generator' ), __( 'XML-Sitemap', 'google-sitemap-generator' ), 'administrator', self::get_base_name(), array( __CLASS__, 'call_html_show_options_page' ) ); + } + + /** + * Add a widget to the dashboard. + * + * @param string $a . + */ + public static function wp_dashboard_setup( $a ) { + self::load_plugin(); + $sg = GoogleSitemapGenerator::get_instance(); + + if ( $sg->show_survey() ) { + add_action( 'admin_notices', array( __CLASS__, 'wp_dashboard_admin_notices' ) ); + } + } + /** + * Wp dashboard admin notices method + */ + public static function wp_dashboard_admin_notices() { + $sg = GoogleSitemapGenerator::get_instance(); + $sg->html_survey(); + } + /** + * Hide banner info. + */ + public function hide_banner() { + update_option( 'sm_show_beta_banner', 'false' ); + add_option( 'sm_beta_banner_discarded_on', gmdate( 'Y/m/d' ) ); + update_option( 'sm_beta_banner_discarded_count', (int) 2 ); + } + /** + * Beta notice. + */ + public static function beta_notice() { + + $current_page = self::get_current_page_url(); + $arr = self::get_tags_array(); + + $default_value = 'show_banner'; + $value = get_option( 'sm_show_beta_banner', $default_value ); + $now = time(); + $banner_discarded = strtotime( get_option( 'sm_beta_banner_discarded_on' ) ); + $image_url = trailingslashit( plugins_url( '', __FILE__ ) ) . 'img/close.png'; + + $page_to_show_notice = array( 'settings_page_google-sitemap-generator/sitemap', 'dashboard', 'plugins' ); + $current_screen = get_current_screen()->base; + $banner_discarded_count = get_option( 'sm_beta_banner_discarded_count' ); + if ( gettype( $banner_discarded ) === 'boolean' ) { + $banner_discarded = time(); + } + $datediff = $now - $banner_discarded; + $datediff = round( $datediff / ( 60 * 60 * 24 ) ); + if ( ( in_array( $current_screen, $page_to_show_notice, true ) ) && ( $value === $default_value || 'true' === $value ) && ( 'true' !== get_option( 'sm_beta_notice_dismissed_from_wp_admin' ) || 'google-sitemap-generator/sitemap.php' === $current_page ) || ( 'google-sitemap-generator/sitemap.php' === $current_page && $datediff >= SM_BANNER_HIDE_DURATION_IN_DAYS && $banner_discarded_count < 2 ) ) { + ?> + +
        + array(), + 'p' => array(), + 'div' => array( + 'style' => array( + 'display' => 'flex', + 'justify-content' => 'space-between', + ), + 'class' => array(), + 'id' => array(), + ), + 'img' => array( + 'src' => array(), + 'id' => array(), + 'class' => array(), + 'height' => array(), + 'width' => array(), + ), + 'a' => array( + 'href' => array(), + 'target' => array(), + 'class' => array(), + 'name' => array(), + 'id' => array(), + ), + 'h4' => array( + 'style' => array( + 'width' => array(), + 'display' => array(), + ), + 'id' => array(), + ), + 'h3' => array( + 'style' => array( + 'width' => array(), + 'display' => array(), + ), + 'id' => array(), + ), + 'button' => array( + 'onClick' => array(), + 'type' => array(), + 'onclick' => array(), + 'class' => array(), + 'id' => array(), + ), + 'strong' => array(), + 'input' => array( + 'type' => array(), + 'class' => array(), + 'id' => array(), + 'name' => array(), + 'value' => array(), + 'formaction' => array(), + 'style' => array( + 'position' => array(), + 'padding' => array(), + 'background' => array(), + 'right' => array(), + 'color' => array(), + 'border-color' => array(), + 'cursor' => array(), + ), + ), + 'form' => array( + 'id' => array(), + 'method' => array(), + 'action' => array(), + 'style' => array( + 'margin-top' => array(), + 'margin-left' => array(), + 'display' => array(), + ), + ), + ); + $consent_url = wp_nonce_url( home_url( '/wp-content/plugins/google-sitemap-generator/upgrade-plugin.php?action=yes' ), 'user_consent_yesno_nonce' ); + $decline_consent_url = ( empty( $_SERVER['HTTPS'] ) ? 'http' : 'https' ) . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; + + $qs = 'settings_page_google-sitemap-generator/sitemap' === $current_screen ? '&action=no' : '?action=no'; + /* translators: %s: search term */ + echo wp_kses( + __('

        Do you want the best SEO indexation technology for your website? Join the Google XML Sitemaps Beta Program now!

        + +
        + Yes, I am in + X +
        + ', + 'google-sitemap-generator' + ), + $arr + ); + ?> +
        + + + + ', + 'google-sitemap-generator'), + $arr + ); + } + /* translators: %s: search term */ + ?> + + + ', + 'google-sitemap-generator' + ), + $arr + ); + } + /* translators: %s: search term */ + $default_value = 'default'; + $auto_update_plugins = get_option( 'auto_update_plugins', $default_value ); + $hide_auto_update_banner = get_option( 'sm_hide_auto_update_banner' ); + if ( ! is_array( $auto_update_plugins ) ) { + $auto_update_plugins = array(); + } + if ( (! in_array( 'google-sitemap-generator/sitemap.php', $auto_update_plugins, true ) && ('google-sitemap-generator/sitemap.php' === $current_page || $_SERVER['REQUEST_URI'] === '/wp-admin/index.php' || $_SERVER['REQUEST_URI'] === '/wp-admin/') && 'yes' !== $hide_auto_update_banner) ) { + ?> + +
        + Auto-updates aren not enabled for Sitemap Generator. Would you like to enable auto-updates to always have the best indexation features? + +
        + ' . wp_nonce_field("enable_updates_nonce", "enable_updates_nonce_token") . + '
        + ', + 'google-sitemap-generator' + ), + $arr + ); + /* translators: %s: search term */ + ?> +
        + ' . __( 'Settings', 'google-sitemap-generator' ) . ''; + $links[] = '' . __( 'FAQ', 'google-sitemap-generator' ) . ''; + $links[] = '' . __( 'Support', 'google-sitemap-generator' ) . ''; + } + return $links; + } + + /** + * SchedulePingOnStatus Change + * + * @param string $new_status string The new post status . + * @param string $old_status string The old post status . + * @param object $post WP_Post The post object . + */ + public static function schedule_ping_on_status_change( $new_status, $old_status, $post ) { + if ( 'publish' === $new_status ) { + set_transient( 'sm_ping_post_id', $post->ID, 120 ); + wp_schedule_single_event( time() + 5, 'sm_ping' ); + } + } + + /** + * Invokes the HtmlShowOptionsPage method of the generator + * + * @uses GoogleSitemapGeneratorLoader::load_plugin() + * @uses GoogleSitemapGenerator::HtmlShowOptionsPage() + */ + public static function call_html_show_options_page() { + if ( self::load_plugin() ) { + GoogleSitemapGenerator::get_instance()->html_show_options_page(); + } + } + + /** + * Invokes the ShowPingResult method of the generator + * + * @uses GoogleSitemapGeneratorLoader::load_plugin() + * @uses GoogleSitemapGenerator::ShowPingResult() + */ + public static function call_show_ping_result() { + if ( self::load_plugin() ) { + GoogleSitemapGenerator::get_instance()->show_ping_result(); + } + } + + /** + * Invokes the SendPing method of the generator + * + * @uses GoogleSitemapGeneratorLoader::load_plugin() + * @uses GoogleSitemapGenerator::SendPing() + */ + public static function call_send_ping() { + if ( self::load_plugin() ) { + GoogleSitemapGenerator::get_instance()->send_ping(); + } + } + + /** + * Invokes the SendPingDaily method of the generator + * + * @uses GoogleSitemapGeneratorLoader::load_plugin() + * @uses GoogleSitemapGenerator::SendPingDaily() + */ + public static function call_send_ping_daily() { + if ( self::load_plugin() ) { + GoogleSitemapGenerator::get_instance()->send_ping_daily(); + } + } + + /** + * Invokes the ShowSitemap method of the generator + * + * @param string $options . + * @uses GoogleSitemapGeneratorLoader::load_plugin() + * @uses GoogleSitemapGenerator::ShowSitemap() + */ + public static function call_show_sitemap( $options ) { + $newFormat = self::change_url_to_required(); + if($newFormat) $options = $newFormat; + + if ( self::load_plugin() ) { + GoogleSitemapGenerator::get_instance()->show_sitemap( $options ); + } + } + + /* Get url and to transform required format */ + public static function change_url_to_required(){ + global $wp; + $current_url = parse_url(home_url(add_query_arg(array(), $wp->request))); + if( isset($current_url['path']) && strlen($current_url['path']) > 1){ + $currentUrl = substr($current_url['path'], 1); + $arrayType = explode('.', $currentUrl); + if (isset($arrayType) && is_array($arrayType) && count($arrayType) > 1) { + if (isset($arrayType[1]) && is_string($arrayType[1])) { + if (in_array($arrayType[1], array('xml', 'html'))){ + if(isset(get_option('sm_options')['sm_b_sitemap_name']) && $arrayType[0] === get_option('sm_options')['sm_b_sitemap_name']){ + $postType[0] = $arrayType[0] . '.' . $arrayType[1]; + }else if( strpos($arrayType[0], '-misc') !== false ) { + $postType[0] = 'sitemap'; + $postType[1] = $arrayType[1]; + } + else $postType = explode('-sitemap', $currentUrl); + + if (strpos($postType[0], '/') !== false){ + $newType = explode('/', $postType[0]); + $postType[0] = end($newType); + } + + if (strpos($postType[0], 'authors') !== false && strpos($postType[0], '-') !== false) { + $array = explode('-', $postType[0]); + $postType[0] = end($array); + } + + if(count($postType) > 1 ){ + preg_match('/\d+/', $postType[1], $matches); + if(empty($matches)) $matches[0] = 1; + if($postType[0] === 'sitemap') return 'params=misc'; + else if($postType[0] === 'post_tag' || $postType[0] === 'category' || taxonomy_exists($postType[0])) return 'params=tax-' . $postType[0] . '-' . $matches[0]; + else if($postType[0] === 'productcat') return 'params=productcat-' . $matches[0]; + else if($postType[0] === 'authors' || $postType[0] === 'archives') return 'params=' . $postType[0]; + else if($postType[0] === 'productcat') return 'params=productcat-' . $matches[0]; + else if($postType[0] === 'producttags') return 'params=producttags-' . $matches[0]; + else return 'params=pt-' . $postType[0] . '-p' . $matches[0] . '-2023-11'; + } + } + } + } + } + return false; + } + + /** + * Invokes the DoRobots method of the generator + * + * @uses GoogleSitemapGeneratorLoader::load_plugin() + * @uses GoogleSitemapGenerator::DoRobots() + */ + public static function call_do_robots() { + if ( self::load_plugin() ) { + GoogleSitemapGenerator::get_instance()->do_robots(); + } + } + + /** + * Displays the help links in the upper Help Section of WordPress + */ + public static function call_html_show_help_list() { + + $screen = get_current_screen(); + $id = get_plugin_page_hookname( self::get_base_name(), 'options-general.php' ); + + } + + + /** + * Loads the actual generator class and tries to raise the memory and time limits if not already done by WP + * + * @uses GoogleSitemapGenerator::enable() + * @return boolean true if run successfully + */ + public static function load_plugin() { + + $disable_functions = ini_get( 'disable_functions' ); + + if ( ! class_exists( 'GoogleSitemapGenerator' ) ) { + + $mem = abs( intval( ini_get( 'memory_limit' ) ) ); + if ( $mem && $mem < 128 ) { + wp_raise_memory_limit( '128M' ); + } + + $time = abs( intval( ini_get( 'max_execution_time' ) ) ); + if ( 0 !== $time && 120 > $time ) { + if ( strpos( $disable_functions, 'set_time_limit' ) === false ) { + set_time_limit( 120 ); + } + } + + $path = trailingslashit( dirname( __FILE__ ) ); + + if ( ! file_exists( $path . 'sitemap-core.php' ) ) { + return false; + } + require_once $path . 'sitemap-core.php'; + } + + GoogleSitemapGenerator::enable(); + return true; + } + + /** + * Returns the plugin basename of the plugin (using __FILE__) + * + * @return string The plugin basename, 'sitemap' for example + */ + public static function get_base_name() { + return plugin_basename( sm_get_init_file() ); + } + + /** + * Returns the name of this loader script, using sm_GetInitFile + * + * @return string The sm_GetInitFile value + */ + public static function get_plugin_file() { + return sm_get_init_file(); + } + + /** + * Returns the plugin version + * + * Uses the WP API to get the meta data from the top of this file (comment) + * + * @return string The version like 3.1.1 + */ + public static function get_version() { + if ( ! isset( $GLOBALS['sm_version'] ) ) { + if ( ! function_exists( 'get_plugin_data' ) ) { + if ( file_exists( ABSPATH . 'wp-admin/includes/plugin.php' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } else { + return '0.ERROR'; + } + } + $data = get_plugin_data( self::get_plugin_file(), false, false ); + $GLOBALS['sm_version'] = $data['Version']; + } + return $GLOBALS['sm_version']; + } + + /** + * Get SVN function . + */ + public static function get_svn_version() { + return self::$svn_version; + } + + public static function get_current_page_url(){ + $window_url = home_url() . $_SERVER[ 'REQUEST_URI' ]; + $parts = wp_parse_url( $window_url ); + $current_page = ''; + $current_url = $_SERVER['REQUEST_URI']; + if ( isset( $parts['query'] ) ) { + parse_str( $parts['query'], $query ); + if ( isset( $query['page'] ) ) { + $current_page = $query['page']; + } + } + return $current_page; + } + + public static function get_tags_array(){ + return array( + 'br' => array(), + 'p' => array(), + 'h3' => array(), + 'div' => array( + 'style' => array( + 'display' => 'flex', + 'justify-content' => 'space-between', + ), + 'class' => array(), + 'id' => array(), + ), + 'a' => array( + 'href' => array(), + 'name' => array(), + 'class' => array(), + 'name' => array(), + 'id' => array(), + ), + 'h4' => array( + 'style' => array( + 'width' => array(), + 'display' => array(), + ), + 'id' => array(), + 'class' => array(), + ), + 'h3' => array( + 'style' => array( + 'width' => array(), + 'display' => array(), + ), + 'id' => array(), + ), + 'img' => array( + 'src' => array(), + 'class' => array(), + 'id' => array(), + 'height' => array(), + 'width' => array(), + ), + 'button' => array( + 'onClick' => array(), + 'type' => array(), + 'onclick' => array(), + 'class' => array(), + 'id' => array(), + ), + 'strong' => array(), + 'input' => array( + 'type' => array(), + 'class' => array(), + 'id' => array(), + 'name' => array(), + 'value' => array(), + 'style' => array( + 'position' => array(), + 'padding' => array(), + 'background' => array(), + 'right' => array(), + 'color' => array(), + 'border-color' => array(), + 'cursor' => array(), + ), + ), + 'form' => array( + 'id' => array(), + 'method' => array(), + 'action' => array(), + 'style' => array( + 'margin-top' => array(), + 'margin-left' => array(), + 'display' => array(), + ), + ), + ); + } + + public static function create_notice_conflict_plugin(){ + + $window_url = home_url() . $_SERVER[ 'REQUEST_URI' ]; + $parts = wp_parse_url( $window_url ); + $current_page = ''; + $current_url = $_SERVER['REQUEST_URI']; + if ( isset( $parts['query'] ) ) { + parse_str( $parts['query'], $query ); + if ( isset( $query['page'] ) ) { + $current_page = $query['page']; + } + } + + $default_value = 'default'; + + $yoast_options = get_option( 'wpseo', $default_value ); + $yoast_sm_enabled = 0; + if ( $yoast_options !== $default_value && isset( $yoast_options['enable_xml_sitemap'] ) ) { + $yoast_sm_enabled = $yoast_options['enable_xml_sitemap'] ? $yoast_options['enable_xml_sitemap'] : 0; + } + + $aio_seo_options = get_option( 'aioseo_options', $default_value ); + $aio_seo_sm_enabled = 0; + + if ( $aio_seo_options !== $default_value ) { + $aio_seo_options = json_decode( $aio_seo_options ); + $aio_seo_sm_enabled = $aio_seo_options->sitemap->general->enable; + } + + $jetpack_options = get_option( 'jetpack_active_modules', $default_value ); + $jetpack_sm_enabled = 0; + if(is_array($jetpack_options)) { + if (in_array('sitemaps', $jetpack_options)) { + $jetpack_sm_enabled = 1; + } + } + + if(isset(get_option('sm_options')['sm_wp_sitemap_status']) ) $wordpress_options = get_option('sm_options')['sm_wp_sitemap_status']; + else $wordpress_options = true; + $wordpress_sm_enabled = 0; + if($wordpress_options) { + $wordpress_sm_enabled = 1; + } + + $sitemap_plugins = array(); + $plugins = get_plugins(); + foreach ( $plugins as $key => $value ) { + $plug = array(); + if ( strpos( $key, 'google-sitemap-generator' ) !== false ) { + continue; + } + if ( ( strpos( $key, 'sitemap' ) !== false || strpos( $key, 'seo' ) !== false || $jetpack_sm_enabled || $wordpress_sm_enabled) && is_plugin_active( ( $key ) ) ) { + array_push( $plug, $key ); + foreach ( $value as $k => $v ) { + if ( 'Name' === $k ) { + array_push( $plug, $v ); + } + } + array_push( $sitemap_plugins, $plug ); + } + } + + $conflict_plugins = explode( ',', SM_CONFLICT_PLUGIN_LIST ); + + $plugin_title = array(); + $plugin_name = array(); + + for ( $i = 0; $i < count( $sitemap_plugins ); $i++ ) { + if ( in_array( $sitemap_plugins[ $i ][1], $conflict_plugins ) ) { + array_push( $plugin_name, $sitemap_plugins[ $i ][1] ); + array_push( $plugin_title, $sitemap_plugins[ $i ][0] ); + } + } + + if(('google-sitemap-generator/sitemap.php' === $current_page || $_SERVER['REQUEST_URI'] === '/wp-admin/index.php' || $_SERVER['REQUEST_URI'] === '/wp-admin/' ) && count( $sitemap_plugins ) > 0 && ( 0 !== $yoast_sm_enabled || 0 !== $aio_seo_sm_enabled || 0 !== $jetpack_sm_enabled || 0 !== $jetpack_sm_enabled) && count($plugin_name) > 0){ + $plug_name = []; + $plug_title = []; + + if($yoast_options = get_option('wpseo')){ + $yoast_options = get_option('wpseo'); + if (in_array('wordpress-seo/wp-seo.php', $plugin_title) && isset($yoast_options['enable_xml_sitemap'])) { + $sitemap_enabled = $yoast_options['enable_xml_sitemap']; + if ($sitemap_enabled) { + $plug_name[] = 'Yoast SEO'; + $plug_title[] = 'wordpress-seo/wp-seo.php'; + } + } + } + + $aioseo_option_key = 'aioseo_options'; + if($aioseo_options = get_option($aioseo_option_key)){ + $aioseo_options = json_decode($aioseo_options, true); + if(in_array('all-in-one-seo-pack/all_in_one_seo_pack.php', $plugin_title) && $aioseo_options['sitemap']['general']['enable']){ + $plug_name[] = 'All in One SEO'; + $plug_title[] = 'all-in-one-seo-pack/all_in_one_seo_pack.php'; + } + } + + if($jetpack_sm_enabled){ + $plug_name[] = 'Jetpack Sitemap'; + $plug_title[] = 'jetpack/jetpack.php'; + } + + if($wordpress_sm_enabled){ + $plug_name[] = 'Wordpress Sitemap'; + $plug_title[] = 'wordpress-sitemap'; + } + + if(count($plug_name) > 0){ + ?> + +
        + + One or more plugins conflict with proper indexation of your website. Use the deactivate button below to disable the extra sitemaps: + ', + 'google-sitemap-generator' + ), + self::get_tags_array() + ); + echo wp_kses_post('
          '); + foreach ($plug_name as $name) { + echo wp_kses_post( + '
        • ' . esc_html($name) . '
        • ' + ); + } + echo wp_kses_post('
        '); + echo wp_kses( + __( + '
        +
        + + '. wp_nonce_field("disable_plugin_sitemap_nonce", "disable_plugin_sitemap_nonce_token") . ' + +
        +
        +
        +
        ', + 'google-sitemap-generator' + ), + self::get_tags_array() + ); + ?> +
        + + build_posts( $gsg, $params ); + break; + case 'archives': + $this->build_archives( $gsg ); + break; + case 'authors': + $this->build_authors( $gsg ); + break; + case 'tax': + $this->build_taxonomies( $gsg, $params ); + break; + case 'producttags': + $this->build_product_tags( $gsg, $params ); + break; + case 'productcat': + $this->build_product_categories( $gsg, $params ); + break; + case 'externals': + $this->build_externals( $gsg ); + break; + case 'misc': + default: + $this->build_misc( $gsg ); + break; + } + } + + /** + * Generates the content for the post sitemap + * + * @param GoogleSitemapGenerator $gsg instance of sitemap generator. + * @param string $params string. + */ + public function build_posts( $gsg, $params ) { + + $pts = strrpos( $params, '-' ); + + if ( ! $pts ) { + return; + } + + $pts = strrpos( $params, '-', $pts - strlen( $params ) - 1 ); + + $param_length = count( explode( '-', $params ) ); + $post_type = ''; + $post_type = substr( $params, 0, $pts ); + $type = explode( '-', $post_type ); + if ( $param_length > 4 ) { + $new = array_slice( $type,0,count($type) -1 ); + $post_type = implode( "-", $new ); + } else { + $post_type = $type[0]; + } + $limit = $type[count($type)-1]; + $limits = substr( $limit, 1 ); + $links_per_page = $gsg->get_entries_per_page(); + if ( gettype( $links_per_page ) !== 'integer' ) { + $links_per_page = (int) 1000; + } + $limit = ( (int) $limits ) * $links_per_page; + if ( ! $post_type || ! in_array( $post_type, $gsg->get_active_post_types(), true ) ) { + return; + } + + $params = substr( $params, $pts + 1 ); + + /** + * Global variable for database. + * + * @var $wpdb wpdb + */ + global $wpdb; + + if ( preg_match( '/^([0-9]{4})\-([0-9]{2})$/', $params, $matches ) ) { + $year = $matches[1]; + $month = $matches[2]; + + // Excluded posts by ID. + $excluded_post_ids = $gsg->get_excluded_post_ids( $gsg ); + $not_allowed_slugs = $gsg->robots_disallowed(); + $excluded_post_ids = array_unique( array_merge( $excluded_post_ids, $not_allowed_slugs ), SORT_REGULAR ); + $gsg->set_option( 'b_exclude', $excluded_post_ids ); + $gsg->save_options(); + $ex_post_s_q_l = ''; + if ( count( $excluded_post_ids ) > 0 ) { + $ex_post_s_q_l = 'AND p.ID NOT IN (' . implode( ',', $excluded_post_ids ) . ')'; + } + + // Excluded categories by taxonomy ID. + $excluded_category_i_d_s = $gsg->get_excluded_category_i_ds( $gsg ); + $ex_cat_s_q_l = ''; + if ( count( $excluded_category_i_d_s ) > 0 ) { + $ex_cat_s_q_l = "AND ( p.ID NOT IN ( SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN ( SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE term_id IN ( " . implode( ',', $excluded_category_i_d_s ) . '))))'; + } + // Statement to query the actual posts for this post type. + $qs = " + SELECT + p.ID, + p.post_author, + p.post_status, + p.post_name, + p.post_parent, + p.post_type, + p.post_date, + p.post_date_gmt, + p.post_modified, + p.post_modified_gmt, + p.comment_count + FROM + {$wpdb->posts} p + WHERE + p.post_password = '' + AND p.post_type = '%s' + AND p.post_status = 'publish' + {$ex_post_s_q_l} + {$ex_cat_s_q_l} + ORDER BY + p.post_date_gmt ASC + LIMIT + %d, %d + "; + // Query for counting all relevant posts for this post type. + $qsc = " + SELECT + COUNT(*) + FROM + {$wpdb->posts} p + WHERE + p.post_password = '' + AND p.post_type = '%s' + AND p.post_status = 'publish' + {$ex_post_s_q_l} + {$ex_cat_s_q_l} + "; + + // Calculate the offset based on the limit and links_per_page + $offset = max( 0, ( $limit - $links_per_page ) ); + + // phpcs:disable + $q = $wpdb->prepare( $qs, $post_type, $offset, $links_per_page ); + + // phpcs:enable + $posts = $wpdb->get_results( $q ); // phpcs:ignore + $post_count = count( $posts ); + if ( ( $post_count ) > 0 ) { + /** + * Description for priority provider + * + * @var $priority_provider GoogleSitemapGeneratorPrioProviderBase + */ + $priority_provider = null; + + if ( $gsg->get_option( 'b_prio_provider' ) !== '' ) { + + // Number of comments for all posts. + $cache_key = __CLASS__ . '::commentCount'; + $comment_count = wp_cache_get( $cache_key, 'sitemap' ); + if ( false === $comment_count ) { + $comment_count = $wpdb->get_var( "SELECT COUNT(*) as `comment_count` FROM {$wpdb->comments} WHERE `comment_approved`='1'" ); // db call ok. + wp_cache_set( $cache_key, $comment_count, 'sitemap', 20 ); + } + + // Number of all posts matching our criteria. + $cache_key = __CLASS__ . "::totalPostCount::$post_type"; + $total_post_count = wp_cache_get( $cache_key, 'sitemap' ); + if ( false === $total_post_count ) { + // phpcs:disable + $total_post_count = $wpdb->get_var( + $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} p WHERE p.post_password = '' AND p.post_type = '%s' AND p.post_status = 'publish' " . $ex_post_s_q_l . " " . $ex_cat_s_q_l . " ", $post_type ) // phpcs:ignore + ); // db call ok. + // phpcs:enable + wp_cache_add( $cache_key, $total_post_count, 'sitemap', 20 ); + } + + // Initialize a new priority provider. + $provider_class = $gsg->get_option( 'b_prio_provider' ); + $priority_provider = new $provider_class( $comment_count, $total_post_count ); + } + + // Default priorities. + $default_priority_for_posts = $gsg->get_option( 'pr_posts' ); + $default_priority_for_pages = $gsg->get_option( 'pr_pages' ); + + // Minimum priority. + $minimum_priority = $gsg->get_option( 'pr_posts_min' ); + + // Change frequencies. + $change_frequency_for_posts = $gsg->get_option( 'cf_posts' ); + $change_frequency_for_pages = $gsg->get_option( 'cf_pages' ); + + // Page as home handling. + $home_pid = 0; + $home = get_home_url(); + if ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) ) { + $page_on_front = get_option( 'page_on_front' ); + $p = get_post( $page_on_front ); + if ( $p ) { + $home_pid = $p->ID; + } + } + + $siteLanguages = []; + $defaultLanguageCode = ''; + + if (function_exists('icl_get_languages')) { + if (function_exists('icl_get_default_language')) $defaultLanguageCode = icl_get_default_language(); + $languages = icl_get_languages('skip_missing=0'); + if($languages){ + foreach ($languages as $language) { + if($defaultLanguageCode !== $language['language_code']) $siteLanguages[] = $language['language_code']; + } + } + } else if (function_exists('pll_the_languages')) { + if (function_exists('pll_default_language')) $defaultLanguageCode = pll_default_language(); + $languages = pll_the_languages(array('raw' => 1)); + if ($languages) { + foreach ($languages as $language) { + if($defaultLanguageCode !== $language['slug']) $siteLanguages[] = $language['slug']; + } + } + } + + foreach ( $posts as $post ) { + + $permalink = get_permalink( $post ); + + $permalink = apply_filters( 'sm_xml_sitemap_post_url', $permalink, $post ); + + if(count($siteLanguages) > 0){ + + $structurekArr = explode('/', get_option('permalink_structure')); + $postLinkArr = explode('/', $permalink); + + $index = null; + if(is_array($structurekArr) && is_array($postLinkArr)){ + foreach ($siteLanguages as $lang){ + if (in_array($lang, $postLinkArr)) { + $index = array_search($lang, $postLinkArr); + } + } + } + + if ($index !== null) { + if ($postLinkArr[$index] !== $defaultLanguageCode) { + $custom_post_type_name = get_post_type($post); + if (!in_array($custom_post_type_name, $postLinkArr)) { + $key = array_search('%postname%', $structurekArr); + if ($structurekArr[$key] === '%postname%') { + $postLinkArr[$index + $key] = $post->post_name; + } + } + $permalink = implode('/', $postLinkArr); + } + } + } + + // Exclude the home page and placeholder items by some plugins. Also include only internal links. + if ( + ( ! empty( $permalink ) ) + && $permalink !== $home + && $post->ID !== $home_pid + && strpos( $permalink, $home ) !== false + ) { + + // Default Priority if auto calc is disabled. + $priority = ( 'page' === $post_type ? $default_priority_for_pages : $default_priority_for_posts ); + + // If priority calc. is enabled, calculate (but only for posts, not pages)! + if ( null !== $priority_provider && 'post' === $post_type ) { + $priority = $priority_provider->get_post_priority( $post->ID, $post->comment_count, $post ); + } + + // Ensure the minimum priority. + if ( 'post' === $post_type && $minimum_priority > 0 && $priority < $minimum_priority ) { + $priority = $minimum_priority; + } + + // Add the URL to the sitemap. + $gsg->add_url( + $permalink, + $gsg->get_timestamp_from_my_sql( $post->post_modified_gmt && '0000-00-00 00:00:00' !== $post->post_modified_gmt ? $post->post_modified_gmt : $post->post_date_gmt ), + ( 'page' === $post_type ? $change_frequency_for_pages : $change_frequency_for_posts ), + $priority, + $post->ID + ); + } + + // Why not use clean_post_cache? Because some plugin will go crazy then (lots of database queries). + // The post cache was not populated in a clean way, so we also won't delete it using the API. + // wp_cache_delete( $post->ID, 'posts' );. + unset( $post ); + } + unset( $posts_custom ); + } + } + } + + + /** + * Generates the content for the archives sitemap + * + * @param GoogleSitemapGenerator $gsg object of google sitemap. + */ + public function build_archives( $gsg ) { + /** + * Super global variable for database. + * + * @var $wpdb wpdb + */ + global $wpdb; + + $now = current_time( 'mysql', true ); + + $archives = $wpdb->get_results( + // phpcs:disable + $wpdb->prepare( + "SELECT DISTINCT + YEAR(post_date_gmt) AS `year`, + MONTH(post_date_gmt) AS `month`, + MAX(post_date_gmt) AS last_mod, + count(ID) AS posts + FROM + $wpdb->posts + WHERE + post_date_gmt < '%s' + AND post_status = 'publish' + AND post_type = 'post' + GROUP BY + YEAR(post_date_gmt), + MONTH(post_date_gmt) + ORDER BY + post_date_gmt DESC", + $now + ) + // phpcs:enable + ); // db call ok; no-cache ok. + + if ( $archives ) { + foreach ( $archives as $archive ) { + + $url = get_month_link( $archive->year, $archive->month ); + + // Archive is the current one. + if ( gmdate( 'n' ) === $archive->month && gmdate( 'Y' ) === $archive->year ) { + $change_freq = $gsg->get_option( 'cf_arch_curr' ); + } else { // Archive is older. + $change_freq = $gsg->get_option( 'cf_arch_old' ); + } + + $gsg->add_url( $url, $gsg->get_timestamp_from_my_sql( $archive->last_mod ), $change_freq, $gsg->get_option( 'pr_arch' ) ); + } + } + + $post_type_customs = get_post_types( array( 'public' => 1 ) ); + $post_type_customs = array_diff( $post_type_customs, array( 'page', 'attachment', 'product', 'post' ) ); + foreach ( $post_type_customs as $post_type_custom ) { + $latest = new WP_Query( + array( + 'post_type' => $post_type_custom, + 'post_status' => 'publish', + 'posts_per_page' => 1, + 'orderby' => 'modified', + 'order' => 'DESC', + ) + ); + + if ( $latest->have_posts() ) { + $modified_date = $latest->posts[0]->post_modified; + if ( gmdate( 'n', strtotime( $modified_date ) ) === gmdate( 'n' ) && gmdate( 'Y', strtotime( $modified_date ) ) === gmdate( 'Y' ) ) { + $change_freq = $gsg->get_option( 'cf_arch_curr' ); + } else { // Archive is older. + $change_freq = $gsg->get_option( 'cf_arch_old' ); + } + $gsg->add_url( get_post_type_archive_link( $post_type_custom ), $gsg->get_timestamp_from_my_sql( $modified_date ), $change_freq, $gsg->get_option( 'pr_arch' ), 0, array(), array(), '' ); + } + } + } + + /** + * Generates the misc sitemap + * + * @param GoogleSitemapGenerator $gsg instence of sitemap generator class. + */ + public function build_misc( $gsg ) { + $lm = get_lastpostmodified( 'gmt' ); + + if ( $gsg->get_option( 'in_home' ) ) { + $home = get_bloginfo( 'url' ); + + // Add the home page (WITH a slash!). + if ( $gsg->get_option( 'in_home' ) ) { + if ( 'page' === get_option( 'show_on_front' ) && get_option( 'page_on_front' ) ) { + $page_on_front = get_option( 'page_on_front' ); + $p = get_post( $page_on_front ); + if ( $p ) { + $gsg->add_url( + trailingslashit( $home ), + $gsg->get_timestamp_from_my_sql( ( $p->post_modified_gmt && '0000-00-00 00:00:00' !== $p->post_modified_gmt ? $p->post_modified_gmt : $p->post_date_gmt ) ), + $gsg->get_option( 'cf_home' ), + $gsg->get_option( 'pr_home' ) + ); + } + } else { + $gsg->add_url( + trailingslashit( $home ), + ( $lm ? $gsg->get_timestamp_from_my_sql( $lm ) : time() ), + $gsg->get_option( 'cf_home' ), + $gsg->get_option( 'pr_home' ) + ); + } + } + } + + if ( $gsg->is_xsl_enabled() && true === $gsg->get_option( 'b_html' ) ) { + if(is_multisite()) { + if(isset(get_blog_option( get_current_blog_id(), 'sm_options' )['sm_b_sitemap_name'])) { + $sm_sitemap_name = get_blog_option( get_current_blog_id(), 'sm_options' )['sm_b_sitemap_name']; + } + } else if(isset(get_option('sm_options')['sm_b_sitemap_name'])) $sm_sitemap_name = get_option('sm_options')['sm_b_sitemap_name']; + if(!isset($sm_sitemap_name)) $sm_sitemap_name = 'sitemap'; + $gsg->add_url( + str_replace('.html', $sm_sitemap_name . '.html', $gsg->get_xml_url( 'main', '', array( 'html' => true ) ) ), + ( $lm ? $gsg->get_timestamp_from_my_sql( $lm ) : time() ) + ); + } + + do_action( 'sm_buildmap' ); + } + + /** + * Generates the author sitemap + * + * @param GoogleSitemapGenerator $gsg instence of sitemap generator class. + */ + public function build_authors( $gsg ) { + /** + * Use the wpdb global variable + * + * @var $wpdb wpdb + * */ + global $wpdb; + + // Unfortunately there is no API function to get all authors, so we have to do it the dirty way... + // We retrieve only users with published and not password protected enabled post types. + + $enabled_post_types = null; + $enabled_post_types = $gsg->get_active_post_types(); + + // Ensure we count at least the posts... + $enabled_post_types_count = count( $enabled_post_types ); + if ( 0 === $enabled_post_types_count ) { + $enabled_post_types[] = 'post'; + } + $sql = "SELECT DISTINCT + u.ID, + u.user_nicename, + MAX(p.post_modified_gmt) AS last_post + FROM + {$wpdb->users} u, + {$wpdb->posts} p + WHERE + p.post_author = u.ID + AND p.post_status = 'publish' + AND p.post_type IN(" . implode( ', ', array_fill( 0, count( $enabled_post_types ), '%s' ) ) . ") + AND p.post_password = '' + GROUP BY + u.ID, + u.user_nicename"; + $query = call_user_func_array( array( $wpdb, 'prepare' ), array_merge( array( $sql ), $enabled_post_types ) ); + $authors = $wpdb->get_results( $query ); // phpcs:ignore + + if ( $authors && is_array( $authors ) ) { + $authors = $this->exclude_authors( $authors ); + + if ( ! empty( $authors ) ) { + foreach ( $authors as $author ) { + $url = get_author_posts_url( $author->ID, $author->user_nicename ); + $gsg->add_url( + $url, + $gsg->get_timestamp_from_my_sql( $author->last_post ), + $gsg->get_option( 'cf_auth' ), + $gsg->get_option( 'pr_auth' ) + ); + } + } + } + } + + /** + * Wrap legacy filter to deduplicate calls. + * + * @param array $users Array of user objects to filter. + * + * @return array + */ + protected function exclude_authors( $authors ) { + + /** + * Filter the authors, included in XML sitemap. + * + * @param array $authors Array of user objects to filter. + */ + return apply_filters( 'sm_sitemap_exclude_author', $authors ); + } + + /** + * Filters the terms query to only include published posts + * + * @param string[] $selects Array of string. + * @return string[] + */ + public function filter_terms_query( $selects ) { + /** + * Global variable in functional scope for database + * + * @var wpdb $wpdb Global variable for wpdb + */ + global $wpdb; + $selects[] = " + ( /* ADDED BY XML SITEMAPS */ + SELECT + UNIX_TIMESTAMP(MAX(p.post_date_gmt)) as _mod_date + FROM + {$wpdb->posts} p, + {$wpdb->term_relationships} r + WHERE + p.ID = r.object_id + AND p.post_status = 'publish' + AND p.post_password = '' + AND r.term_taxonomy_id = tt.term_taxonomy_id + ) as _mod_date + /* END ADDED BY XML SITEMAPS */ + "; + + return $selects; + } + + /** + * Generates the taxonomies sitemap + * + * @param GoogleSitemapGenerator $gsg Instance of sitemap generator. + * @param string $taxonomy The Taxonomy. + */ + public function build_taxonomies( $gsg, $taxonomy ) { + + $offset = $taxonomy; + $links_per_page = $gsg->get_entries_per_page(); + if ( gettype( $links_per_page ) !== 'integer' ) { + $links_per_page = (int)1000; + } + if ( strpos( $taxonomy, '-' ) !== false ) { + $offset = substr( $taxonomy, strrpos( $taxonomy, '-' ) + 1 ); + $taxonomy = str_replace( '-' . $offset, '', $taxonomy ); + } else { + $offset = 1; + } + $temp_offset = $offset; + $offset = intval( $offset ); + if ( 0 === $offset ) { + $taxonomy = $taxonomy . '-' . $temp_offset; + $links_per_page = $this->linkPerPage; + } else { + $offset = ( --$offset ) * $links_per_page; + } + $enabled_taxonomies = $this->get_enabled_taxonomies( $gsg ); + if ( in_array( $taxonomy, $enabled_taxonomies, true ) ) { + + $excludes = array(); + + $excl_cats = $gsg->get_option( 'b_exclude_cats' ); // Excluded cats. + if ( $excl_cats ) { + $excludes = $excl_cats; + } + add_filter( 'get_terms_fields', array( $this, 'filter_terms_query' ), 20, 2 ); + /* + $terms = get_terms( + $taxonomy, + array( + 'number' => $links_per_page, + 'offset' => $offset, + 'hide_empty' => true, + 'hierarchical' => false, + 'exclude' => $excludes, + ) + ); + */ + $queryArr = [ + 'taxonomy' => $taxonomy, + 'number' => $links_per_page, + 'offset' => $offset, + 'exclude' => $excludes, + ]; + $queryArr['hide_empty'] = apply_filters( 'sm_sitemap_taxonomy_hide_empty', true ); + if (preg_match('/(post_tag|category)/', $taxonomy)) { + $queryArr['hierarchical'] = false; + } + $terms = array_values( + array_unique( + array_filter( + $this->get_terms($queryArr), + function ($term) use ($taxonomy) { + return $term->taxonomy === $taxonomy; + } + ), + SORT_REGULAR + ) + ); + + remove_filter( 'get_terms_fields', array( $this, 'filter_terms_query' ), 20, 2 ); + + //$terms = array_values(array_unique($terms, SORT_REGULAR)); + + /** + * Filter: 'sm_exclude_from_sitemap_by_term_ids' - Allow excluding terms by ID. + * + * @param array $terms_to_exclude The terms to exclude. + */ + $terms_to_exclude = apply_filters( 'sm_exclude_from_sitemap_by_term_ids', [] ); + + $step = 1; + $size_of_terms = count( $terms ); + for ( $tax_count = 0; $tax_count < $size_of_terms; $tax_count++ ) { + $term = $terms[ $tax_count ]; + + if ( in_array( $term->term_id, $terms_to_exclude ) ) { + $step++; + continue; + } + + switch ( $term->taxonomy ) { + case 'category': + $gsg->add_url( get_term_link( $term, $step ), $this->getTaxonomyUpdatedDate($term->term_id) ?: 0, $gsg->get_option( 'cf_cats' ), $gsg->get_option( 'pr_cats' ) ); + break; + case 'product_cat': + $gsg->add_url( get_term_link( $term, $step ), $term->_mod_date, $gsg->get_option( 'cf_product_cat' ), $gsg->get_option( 'pr_product_cat' ) ); + break; + case 'post_tag': + $gsg->add_url( get_term_link( $term, $step ), $this->getTaxonomyUpdatedDate($term->term_id) ?: 0, $gsg->get_option( 'cf_tags' ), $gsg->get_option( 'pr_tags' ) ); + break; + default: + $gsg->add_url( get_term_link( $term, $step ), $this->getTaxonomyUpdatedDate($term->term_id) ?: 0, $gsg->get_option( 'cf_' . $term->taxonomy ), $gsg->get_option( 'pr_' . $term->taxonomy ) ); + break; + } + $step++; + } + } + } + + /* + get last updated date of taxonomy post + returns timestamp (int) + */ + private function getTaxonomyUpdatedDate($term_id){ + global $wpdb; + + $query = $wpdb->prepare(" + SELECT p.* + FROM {$wpdb->posts} p + INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id + INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id + WHERE tt.term_id = %d + ORDER BY p.post_date DESC + LIMIT 1 + ", $term_id); + + $post = $wpdb->get_row($query); + + if ($post) { + return strtotime($post->post_date); + } + } + + /** + * Returns the enabled taxonomies. Only taxonomies with posts are returned. + * + * @param GoogleSitemapGenerator $gsg Google sitemap generator's instance. + * @return array + */ + public function get_enabled_taxonomies( GoogleSitemapGenerator $gsg ) { + $enabled_taxonomies = $gsg->get_option( 'in_tax' ); + if ( $gsg->get_option( 'in_tags' ) ) { + $enabled_taxonomies[] = 'post_tag'; + } + if ( $gsg->get_option( 'in_cats' ) ) { + $enabled_taxonomies[] = 'category'; + } + return $enabled_taxonomies; + } + + /** + * Returns the enabled Product tags. Only Product Tags with posts are returned. + * + * @param GoogleSitemapGenerator $gsg Instance of sitemap generator. + * @param int $offset Offset. + * @return void + */ + public function build_product_tags( GoogleSitemapGenerator $gsg, $offset ) { + $links_per_page = $gsg->get_entries_per_page(); + if ( gettype( $links_per_page ) !== 'integer' ) { + $links_per_page = (int) 1000; + } + $offset = (intval(--$offset)) * $links_per_page; + + add_filter( 'get_terms_fields', array( $this, 'filter_terms_query' ), 20, 2 ); + $terms = get_terms( + 'product_tag', + array( + 'number' => $links_per_page, + 'offset' => $offset, + ) + ); + remove_filter( 'get_terms_fields', array( $this, 'filter_terms_query' ), 20, 2 ); + $term_array = array(); + + if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) { + foreach ( $terms as $term ) { + $term_array[] = $term->name; + $url = get_term_link( $term ); + //$gsg->add_url( $url, $term->_mod_date, $gsg->get_option( 'cf_tags' ), $gsg->get_option( 'pr_tags' ), $term->ID, array(), array(), '' ); + $gsg->add_url( $url, $this->getProductUpdatedDate($term->term_id, 'product_tag'), $gsg->get_option( 'cf_tags' ), $gsg->get_option( 'pr_tags' ), $term->ID, array(), array(), '' ); + } + } + } + + /** + * Returns the enabled Product Categories. Only Product Categories with posts are returned. + * + * @param GoogleSitemapGenerator $gsg Instance of sitemap generator. + * @param int $offset Offset. + * @return void + */ + public function build_product_categories( GoogleSitemapGenerator $gsg, $offset ) { + $links_per_page = $gsg->get_entries_per_page(); + if ( gettype( $links_per_page ) !== 'integer' ) { + //$links_per_page = (int) 1000; + $links_per_page = (int)$links_per_page; + } + $offset = (intval(--$offset)) * $links_per_page; + $excludes = array(); + $excl_cats = $gsg->get_option( 'b_exclude_cats' ); // Excluded cats. + if ( $excl_cats ) { + $excludes = $excl_cats; + } + add_filter( 'get_terms_fields', array( $this, 'filter_terms_query' ), 20, 2 ); + $category = get_terms( + 'product_cat', + array( + 'number' => $links_per_page, + 'offset' => $offset, + 'exclude' => $excludes, + ) + ); + remove_filter( 'get_terms_fields', array( $this, 'filter_terms_query' ), 20, 2 ); + $cat_array = array(); + if ( ! empty( $category ) && ! is_wp_error( $category ) ) { + $step = 1; + foreach ( $category as $cat ) { + $cat_array[] = $cat->name; + if ( $cat && wp_count_terms( $cat->name, array( 'hide_empty' => true ) ) > 0 ) { + $step++; + $url = get_term_link( $cat ); + $gsg->add_url( $url, $this->getProductUpdatedDate($cat->term_id, 'product_cat'), $gsg->get_option( 'cf_product_cat' ), $gsg->get_option( 'pr_product_cat' ), $cat->ID, array(), array(), '' ); + } + } + } + } + + /* Get last product updated date by tag ID */ + private function getProductUpdatedDate($term_id, $taxonomy){ + $args = array( + 'post_type' => 'product', + 'posts_per_page' => 1, + 'tax_query' => array( + array( + 'taxonomy' => $taxonomy, + 'field' => 'id', + 'terms' => $term_id, + ), + ), + 'orderby' => 'modified', + 'order' => 'DESC', + ); + + $products = new WC_Product_Query($args); + $product_results = $products->get_products(); + + if ($product_results) { + $product = array_shift($product_results); + $updated_date = strtotime($product->get_date_modified()->date('Y-m-d H:i:s')); + + return $updated_date; + } + return false; + } + + /** + * Generates the external sitemap + * + * @param GoogleSitemapGenerator $gsg Instance of sitemap generator. + */ + public function build_externals( $gsg ) { + $pages = $gsg->get_pages(); + if ( $pages && is_array( $pages ) && count( $pages ) > 0 ) { + foreach ( $pages as $page ) { + // Disabled phpcs for backward compatibility . + // phpcs:disable + $url = ! empty( $page->get_url() ) ? $page->get_url() : $page->url; + $change_freq = ! empty( $page->get_change_freq() ) ? $page->get_change_freq() : $page->change_freq; + $priority = ! empty( $page->get_priority() ) ? $page->get_priority() : $page->priority; + $last_mod = ! empty( $page->get_last_mod() ) ? $page->get_last_mod() : $page->last_mod; + // phpcs:enable + /** + * Description for $page variable. + * + * @var $page GoogleSitemapGeneratorPage + */ + $gsg->add_url( $url, $last_mod, $change_freq, $priority ); + } + } + } + + /** + * Generates the sitemap index + * + * @param GoogleSitemapGenerator $gsg Instance of sitemap generator. + */ + public function index( $gsg ) { + /** + * Global variable for database. + * + * @var $wpdb wpdb + */ + global $wpdb; + $blog_update = strtotime( get_lastpostmodified( 'gmt' ) ); + $links_per_page = $gsg->get_entries_per_page(); + if ( 0 === $links_per_page || is_nan( $links_per_page ) ) { + $links_per_page = $this->linkPerPage; + $gsg->set_option( 'links_page', $this->linkPerPage ); + } + else if ($links_per_page > $this->maxLinksPerPage) $links_per_page = $this->maxLinksPerPage; + $gsg->add_sitemap( 'misc', null, $blog_update ); + + /** + * Filter: 'sm_sitemap_exclude_taxonomy' - Allow extending and modifying the taxonomies to exclude. + * + * @param array $taxonomies_to_exclude The taxonomies to exclude. + */ + $taxonomies_to_exclude = []; + $default_taxonomies_to_exclude = [ 'product_tag', 'product_cat' ]; + $taxonomies_to_exclude = apply_filters( 'sm_sitemap_exclude_taxonomy', $taxonomies_to_exclude ); + if ( ! is_array( $taxonomies_to_exclude ) || empty( $taxonomies_to_exclude ) ) { + $taxonomies_to_exclude = $default_taxonomies_to_exclude; + } else { + $taxonomies_to_exclude = array_merge( $taxonomies_to_exclude, $default_taxonomies_to_exclude ); + } + $enabled_taxonomies = $this->get_enabled_taxonomies( $gsg ); + $excl_cats = $gsg->get_option( 'b_exclude_cats' ); + $excludes = $excl_cats ? $excl_cats : array(); + $terms_by_taxonomy = array(); + + foreach ( $enabled_taxonomies as $taxonomy ) { + if ( ! in_array( $taxonomy, $taxonomies_to_exclude, true ) ) { + $terms_args = [ + 'taxonomy' => $taxonomy, + 'exclude' => $excludes + ]; + $terms_args['hide_empty'] = apply_filters( 'sm_sitemap_taxonomy_hide_empty', true ); + $terms = $this->get_terms( $terms_args ); + $terms_by_taxonomy[ $taxonomy ] = $terms; + } + } + + foreach ( $terms_by_taxonomy as $taxonomy => $terms ) { + $step = 1; + $i = 0; + foreach ( $terms as $term ) { + if ( 0 === ( $i % $links_per_page ) && '' !== $term->taxonomy && taxonomy_exists( $term->taxonomy ) ) { + $gsg->add_sitemap( $term->taxonomy,'-sitemap' . ($step === 1? '' : $step), $blog_update ); + $step++; + } + $i++; + } + } + + // If Product Tags is enabled from sitemap settings. + if ( true === $gsg->get_option( 'product_tags' ) ) { + $product_tags = get_terms( 'product_tag' ); + if ( ! empty( $product_tags ) && ! is_wp_error( $product_tags ) ) { + $step = 1; + $product_tags_size_of = count( $product_tags ); + + for ( $product_count = 0; $product_count < $product_tags_size_of; $product_count++ ) { + if ( 0 === ( $product_count % $links_per_page ) ) { + //$gsg->add_sitemap( 'producttags', $step, $blog_update ); + $gsg->add_sitemap( 'producttags', '-sitemap' . ($step === 1? '' : $step), $blog_update ); + $step = ++$step; + } + } + } + } + + // If Product category is enabled from sitemap settings. + if ( true === $gsg->get_option( 'in_product_cat' ) ) { + $excludes = array(); + $excl_cats = $gsg->get_option( 'b_exclude_cats' ); // Excluded cats. + + if ( $excl_cats ) { + $excludes = $excl_cats; + } + + $product_cat = get_terms( 'product_cat', array( 'exclude' => $excludes ) ); + + if ( ! empty( $product_cat ) && ! is_wp_error( $product_cat ) ) { + $step = 1; + $product_cat_count = count( $product_cat ); + for ( $product_count = 0; $product_count < $product_cat_count; $product_count++ ) { + if ( 0 === ( $product_count % $links_per_page ) ) { + //$gsg->add_sitemap( 'productcat', $step, $blog_update ); + $gsg->add_sitemap( 'productcat', '-sitemap' . ($step === 1? '' : $step), $blog_update ); + $step = ++$step; + } + } + } + } + + $pages = (array)$gsg->get_pages(); + if ( count( $pages ) > 0 ) { + foreach ( $pages as $page ) { + $url = ! empty( $page->get_url() ) ? $page->get_url() : ( property_exists( $page, '_url' ) ? $page->_url : '' ); + if ( $page instanceof GoogleSitemapGeneratorPage && $url ) { + $gsg->add_sitemap( 'externals-sitemap', null, $blog_update ); + break; + } + } + } + + $enabled_post_types = $gsg->get_active_post_types(); + + //checking for products enabled + if($gsg->get_option( 'in_product_assortment' ) !== null && $gsg->get_option( 'in_product_assortment' ) !== true){ + $enabled_post_types = array_filter($enabled_post_types, function($value) { + return $value !== 'product'; + }); + } + + $has_enabled_post_types_posts = false; + $has_posts = false; + + if ( count( $enabled_post_types ) > 0 ) { + + $excluded_post_ids = $gsg->get_excluded_post_ids( $gsg ); + $not_allowed_slugs = $gsg->robots_disallowed(); + $excluded_post_ids = array_unique( array_merge( $excluded_post_ids, $not_allowed_slugs ), SORT_REGULAR ); + $gsg->set_option( 'b_exclude', $excluded_post_ids ); + $gsg->save_options(); + $ex_post_s_q_l = ''; + $excluded_post_ids_count = count( $excluded_post_ids ); + if ( $excluded_post_ids_count > 0 ) { + $ex_post_s_q_l = 'AND p.ID NOT IN (' . implode( ',', $excluded_post_ids ) . ')'; + } + $excluded_category_i_d_s = $gsg->get_excluded_category_i_ds( $gsg ); + $ex_cat_s_q_l = ''; + $excluded_category_i_d_s_count = count( $excluded_category_i_d_s ); + if ( $excluded_category_i_d_s_count > 0 ) { + $ex_cat_s_q_l = "AND ( p.ID NOT IN ( SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN (" . implode( ',', $excluded_category_i_d_s ) . ')))'; + } + foreach ( $enabled_post_types as $post_type_custom ) { + // phpcs:disable + $prp = $wpdb->prepare( + "SELECT + COUNT(p.ID) AS `numposts`, + MAX(p.post_modified_gmt) as `last_mod` + FROM + {$wpdb->posts} p + WHERE + p.post_password = '' + AND p.post_type = '%s' + AND p.post_status = 'publish' + " . $ex_post_s_q_l . "" + . $ex_cat_s_q_l . " + ORDER BY + p.post_date_gmt DESC", + $post_type_custom + ); + $posts = $wpdb->get_results($prp); + + if ( $posts ) { + if ( 'post' === $post_type_custom ) { + $has_posts = true; + } + $has_enabled_post_types_posts = true; + + foreach ( $posts as $post ) { + $step = 1; + for ( $i = 0; $i < $post->numposts; $i++ ) { + if ( 0 === ( $i % $links_per_page ) ) { + //$gsg->add_sitemap( 'pt', $post_type_custom . '-p' . $step . '-' . sprintf( '%04d-%02d', $post->year, $post->month ), $gsg->get_timestamp_from_my_sql( $post->last_mod ), 'p' . $step ); + $gsg->add_sitemap( 'pt', $post_type_custom . '-sitemap' . ($step === 1? '' : $step) , $gsg->get_timestamp_from_my_sql( $post->last_mod ) ); + $step = ++$step; + } + } + // $gsg->add_sitemap( 'pt', $post_type_custom . '-' . sprintf( '%04d-%02d', $post->year, $post->month ), $gsg->get_timestamp_from_my_sql( $post->last_mod ) ); + } + } + // phpcs:enable + } + } + + // Only include authors if there is a public post with a enabled post type. + if ( $gsg->get_option( 'in_auth' ) && $has_enabled_post_types_posts ) { + $gsg->add_sitemap( 'authors-sitemap', null, $blog_update ); + } + + // Only include archived if there are posts with postType post. + if ( $gsg->get_option( 'in_arch' ) && $has_posts ) { + $gsg->add_sitemap( 'archives-sitemap', null, $blog_update ); + } + + /** + * Filter: 'sm_sitemap_index' - Allow extending and modifying the xml links to include. + * + * @param array $sitemap_custom_items The custom xml link to include. + */ + $sitemap_custom_items = []; + $sitemap_custom_items = apply_filters( 'sm_sitemap_index', $sitemap_custom_items ); + if ( ! is_array( $sitemap_custom_items ) ) { + $sitemap_custom_items = []; + } + if ( ! empty( $sitemap_custom_items ) ) { + foreach ( $sitemap_custom_items as $sitemap_custom_item ) { + $title = ( isset( $sitemap_custom_item['title'] ) ) ? $sitemap_custom_item['title'] : ''; + $modified = ( isset( $sitemap_custom_item['modified'] ) ) ? strtotime( $sitemap_custom_item['modified'] ) : ''; + if ( $title != '' && $modified != '' ) { + $gsg->add_sitemap( $title, null, $modified ); + } + } + } + } + + /** + * Return the URL to the sitemap related to a specific post + * + * @param array $urls Post sitemap urls. + * @param GoogleSitemapGenerator $gsg Instance of google sitemap generator. + * @param int $post_id The post ID. + * + * @return string[] + */ + public function get_sitemap_url_for_post( array $urls, $gsg, $post_id ) { + $post = get_post( $post_id ); + if ( $post ) { + $last_modified = $gsg->get_timestamp_from_my_sql( $post->post_modified_gmt ); + + $url = $gsg->get_xml_url( 'pt', $post->post_type . '-' . gmdate( 'Y-m', $last_modified ) ); + $urls[] = $url; + } + + return $urls; + } + + public function get_terms( $args = [] ) { + global $wpdb; + + $taxonomy = ( isset( $args['taxonomy'] ) && null !== $args['taxonomy'] ) ? $args['taxonomy'] : false; + + $sql = 'SELECT DISTINCT *'; + $sql .= ' FROM '.$wpdb->prefix.'terms as t'; + $sql .= ' INNER JOIN '.$wpdb->prefix.'term_taxonomy as tt'; + $sql .= ' WHERE `tt`.taxonomy = \'' . $taxonomy . '\''; + $sql .= ' AND `tt`.term_id = `t`.term_id'; + + if ( ! empty( $args ) ) { + if ( isset( $args['hide_empty'] ) && $args['hide_empty'] === true ) { + $sql .= ' AND `tt`.count != 0'; + } + if ( isset( $args['hierarchical'] ) && $args['hierarchical'] === true ) { + $sql .= ' AND `tt`.parent != 0'; + } + if ( isset( $args['exclude'] ) && is_array( $args['exclude'] ) && ! empty( $args['exclude'] ) ) { + foreach ( $args['exclude'] as $term_id ) { + $sql .= ' AND `tt`.term_id != ' . $term_id; + } + } + $sql .= ' ORDER BY t.name ASC'; + if ( isset( $args['number'] ) && $args['number'] != '' ) { + $sql .= ' LIMIT ' . $args['number']; + } + if ( isset( $args['offset'] ) && $args['offset'] != '' ) { + $sql .= ' OFFSET ' . $args['offset']; + } + } + + $result = $wpdb->get_results($sql); + + return $result; + } +} + +if ( defined( 'WPINC' ) ) { + new GoogleSitemapGeneratorStandardBuilder(); +} diff --git a/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorstatus.php b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorstatus.php new file mode 100644 index 0000000..3f05bf9 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorstatus.php @@ -0,0 +1,214 @@ +start_time = microtime( true ); + + $this->auto_save = $auto_save; + + if ( $auto_save ) { + + $exists = get_option( 'sm_status' ); + + if ( false === $exists ) { + add_option( 'sm_status', '', '', 'no' ); + } + $this->save(); + } + } + + /** + * Saves the status back to the database + */ + public function save() { + update_option( 'sm_status', $this ); + } + + /** + * Returns the last saved status object or null + * + * @return GoogleSitemapGeneratorStatus + */ + public static function load() { + $status = get_option( 'sm_status' ); + if ( is_a( $status, 'GoogleSitemapGeneratorStatus' ) ) { + return $status; + } else { + return null; + } + } + + /** + * Ends the ping process + */ + public function end() { + $this->end_time = microtime( true ); + if ( $this->auto_save ) { + $this->save(); + } + } + + /** + * Returns the duration of the ping process + * + * @return int + */ + public function get_duration() { + return round( $this->end_time - $this->start_time, 2 ); + } + + /** + * Returns the time when the pings were started + * + * @return int + */ + public function get_start_time() { + return round( $this->start_time, 2 ); + } + + /** + * Start ping . + * + * @param string $service string The internal name of the ping service . + * @param string $url string The URL to ping . + * @param string $name string The display name of the service . + * @return void + */ + public function start_ping( $service, $url, $name = null ) { + $this->ping_results[ $service ] = array( + 'start_time' => microtime( true ), + 'end_time' => 0, + 'success' => false, + 'url' => $url, + 'name' => $name ? $name : $service, + ); + + if ( $this->auto_save ) { + $this->save(); + } + } + + /** + * End ping . + * + * @param string $service string The internal name of the ping service . + * @param string $success boolean If the ping was successful . + * @return void + */ + public function end_ping( $service, $success ) { + $this->ping_results[ $service ]['end_time'] = microtime( true ); + $this->ping_results[ $service ]['success'] = $success; + + if ( $this->auto_save ) { + $this->save(); + } + } + + /** + * Returns the duration of the last ping of a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return float + */ + public function get_ping_duration( $service ) { + $res = $this->ping_results[ $service ]; + return round( $res['end_time'] - $res['start_time'], 2 ); + } + + /** + * Returns the last result for a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return array + */ + public function get_ping_result( $service ) { + return $this->ping_results[ $service ]['success']; + } + + /** + * Returns the URL for a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return array + */ + public function get_ping_url( $service ) { + return $this->ping_results[ $service ]['url']; + } + + /** + * Returns the name for a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return array + */ + public function get_service_name( $service ) { + return $this->ping_results[ $service ]['name']; + } + + /** + * Returns if a service was used in the last ping + * + * @param string $service string The internal name of the ping service . + * @return bool + */ + public function used_ping_service( $service ) { + return array_key_exists( $service, $this->ping_results ); + } + + /** + * Returns the services which were used in the last ping + * + * @return array + */ + public function get_used_ping_services() { + return array_keys( $this->ping_results ); + } +} diff --git a/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorui.php b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorui.php new file mode 100644 index 0000000..4345ca0 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorui.php @@ -0,0 +1,2027 @@ +sg = $sitemap_builder; + $this->index_now = $index_now; + } + /** + * Constructor function. + * + * @param string $id s . + * @param string $title . + */ + private function html_print_box_header( $id, $title ) { + ?> +
        +

        +
        + +
        +
        + sg->get_freq_names() as $k => $v ) { + echo "'; + } + } + + /** + * Echos option fields for an select field containing the valid priorities (0- 1.0) + * + * @since 4.0 + * @param string $current_val string The value which should be selected. + * @return void + */ + public static function html_get_priority_values( $current_val ) { + $current_val = (float) $current_val; + for ( $i = 0.0; $i <= 1.0; $i += 0.1 ) { + $v = number_format( $i, 1, '.', '' ); + echo "'; + } + } + + /** + * Returns the checked attribute if the given values match + * + * @since 4.0 + * @param string $val string The current value. + * @param string $equals string The value to match. + * @return string The checked attribute if the given values match, an empty string if not + */ + public static function html_get_checked( $val, $equals ) { + $is_equals = $val === $equals; + if ( $is_equals ) { + return self::html_get_attribute( 'checked' ); + } else { + return ''; + } + } + + /** + * Returns the selected attribute if the given values match + * + * @since 4.0 + * @param string $val string The current value. + * @param string $equals string The value to match. + * @return string The selected attribute if the given values match, an empty string if not + */ + public static function html_get_selected( $val, $equals ) { + if ( is_numeric( $val ) && is_numeric( $equals ) ) { + $is_equals = ( round( $val * 10 ) === round( $equals * 10 ) ); + } else { + $is_equals = $val === $equals; + } + if ( $is_equals ) { + return self::html_get_attribute( 'selected' ); + } else { + return ''; + } + } + /** + * Active Sitemap listing . + */ + public function active_plugins() { + $plugins = get_plugins(); + foreach ( $plugins as $key => $val ) { + if ( 'WooCommerce' === $val['Name'] && is_plugin_active( $key ) ) { + $this->has_woo_commerce = true; + } + } + } + /** + * Returns an formatted attribute. If the value is NULL, the name will be used. + * + * @since 4.0 + * @param string $attr string The attribute name. + * @param string $value string The attribute value. + * @return string The formatted attribute + */ + public static function html_get_attribute( $attr, $value = null ) { + if ( null === $value ) { + $value = $attr; + } + return ' ' . $attr . '=' . esc_attr( $value ) . ' '; + } + + /** + * Returns an array with GoogleSitemapGeneratorPage objects which is generated from POST values + * + * @since 4.0 + * @see GoogleSitemapGeneratorPage + * @return array An array with GoogleSitemapGeneratorPage objects + */ + public function html_apply_pages() { + //phpcs:disable + // $pages_ur = ( ( ! isset( $_POST['sm_pages_ur'] ) ) ) && ( ! isset( $_POST['sm_pages_ur'] ) || ! is_array( $_POST['sm_pages_ur'] ) ? array() : esc_url_raw( wp_unslash( $_POST['sm_pages_ur'] ) ) ); + // Array with all priorities. + $pages_ur = array(); + $pages_pr = array(); + $pages_cf = array(); + $pages_lm = array(); + $pages_ur = ( ! isset( $_POST['sm_pages_ur'] ) || ! is_array( $_POST['sm_pages_ur'] ) ) ? array() : array_map( 'sanitize_text_field', wp_unslash( $_POST['sm_pages_ur'] ) ); + // if ( isset( $_POST['sm_pages_pr'] ) && wp_verify_nonce( array_map( 'sanitize_text_field', ( wp_unslash( $_POST['sm_pages_pr'] ) ) ) ) ) { + $pages_pr = ( ! isset( $_POST['sm_pages_pr'] ) || ! is_array( $_POST['sm_pages_pr'] ) ? array() : array_map( 'sanitize_text_field', wp_unslash( $_POST['sm_pages_pr'] ) ) ); + // } + // if ( isset( $_POST['sm_pages_cf'] ) && wp_verify_nonce( array_map( 'sanitize_text_field', ( wp_unslash( $_POST['sm_pages_cf'] ) ) ) ) ) { + $pages_cf = ( ! isset( $_POST['sm_pages_cf'] ) || ! is_array( $_POST['sm_pages_cf'] ) ? array() : array_map( 'sanitize_text_field', wp_unslash( $_POST['sm_pages_cf'] ) ) ); + // } + // if ( isset( $_POST['sm_pages_lm'] ) && wp_verify_nonce( array_map( 'sanitize_text_field', ( wp_unslash( $_POST['sm_pages_lm'] ) ) ) ) ) { + $pages_lm = ( ! isset( $_POST['sm_pages_lm'] ) || ! is_array( $_POST['sm_pages_lm'] ) ? array() : array_map( 'sanitize_text_field', wp_unslash( $_POST['sm_pages_lm'] ) ) ); + // } + // Array where the new pages are stored. + $pages = array(); + // Loop through all defined pages and set their properties into an object. + if ( isset( $_POST['sm_pages_mark'] ) && is_array( $_POST['sm_pages_mark'] ) ) { + $len = count( $_POST['sm_pages_mark'] ); + // phpcs:enable + for ( $i = 0; $i < $len; $i++ ) { + // Create new object. + $p = new GoogleSitemapGeneratorPage(); + if ( substr( $pages_ur[ $i ], 0, 4 ) === 'www.' ) { + $pages_ur[ $i ] = 'http://' . $pages_ur[ $i ]; + } + $p->set_url( $pages_ur[ $i ] ); + $p->set_priority( $pages_pr[ $i ] ); + $p->set_change_freq( $pages_cf[ $i ] ); + // Try to parse last modified, if -1 (note ===) automatic will be used (0). + $lm = ( ! empty( $pages_lm[ $i ] ) ? strtotime( $pages_lm[ $i ], time() ) : -1 ); + if ( -1 === $lm ) { + $p->set_last_mod( 0 ); + } else { + $p->set_last_mod( $lm ); + } + // Add it to the array. + array_push( $pages, $p ); + } + } + return $pages; + } + + public function get_max_input_vars() { + $form_inputs = 40; + $max_input_vars = ini_get('max_input_vars'); + + return $max_input_vars - $form_inputs - (count($this->sg->get_pages())*5); + } + + /** + * Escape. + * + * @param string $v String. + */ + public static function escape( $v ) { + // prevent html tags in strings where they are not required. + return strtr( $v, '<>', '..' ); + } + /** + * Array_map_r. + * + * @param array $func . + * @param array $arr . + */ + public static function array_map_r( $func, $arr ) { + $new_arr = array(); + foreach ( $arr as $key => $value ) { + $new_arr[ $key ] = ( is_array( $value ) ? self::array_map_r( $func, $value ) : ( is_array( $func ) ? call_user_func_array( $func, $value ) : $func( $value ) ) ); + } + foreach ( $new_arr as $k => $v ) { + echo esc_html( ' [ ' . $k . ' ] => ' . $v ); + echo '
        '; + } + } + + /** + * Displays the option page + * + * @since 3.0 + * @access public + * @author Arne Brachhold + */ + public function html_show_options_page() { + $this->active_plugins(); + global $wp_version; + $snl = false; // SNL. + + $this->sg->initate(); + + $message = ''; + + if ( ! empty( $_REQUEST['sm_rebuild'] ) ) { + // Pressed Button: Rebuild Sitemap. + check_admin_referer( 'sitemap' ); + + if ( isset( $_GET['sm_do_debug'] ) && 'true' === $_GET['sm_do_debug'] ) { + + // Check again, just for the case that something went wrong before. + if ( ! current_user_can( 'administrator' ) || ! is_super_admin() ) { + echo '

        Please log in as admin

        '; + return; + } + + echo "
        "; + echo '

        ' . esc_html( __( 'XML Sitemap Generator for Google', 'google-sitemap-generator' ) ) . ' ' . esc_html( $this->sg->get_version() ) . '

        '; + echo '

        This is the debug mode of the XML Sitemap Generator. It will show all PHP notices and warnings as well as the internal logs, messages and configuration.

        '; + echo "

        DO NOT POST THIS INFORMATION ON PUBLIC PAGES LIKE SUPPORT FORUMS AS IT MAY CONTAIN PASSWORDS OR SECRET SERVER INFORMATION!

        "; + echo '

        WordPress and PHP Information

        '; + echo '

        WordPress ' . esc_html( $GLOBALS['wp_version'] ) . ' with DB ' . esc_html( $GLOBALS['wp_db_version'] ) . ' on PHP ' . esc_html( phpversion() ) . '

        '; + echo '

        Plugin version: ' . esc_html( $this->sg->get_version() ) . ' (' . esc_html( $this->sg->get_svn_version() ) . ')'; + echo '

        Environment

        '; + echo '
        ';
        +				$sc = $_SERVER;
        +				$this->sg->get_svn_version();
        +				unset( $sc['HTTP_COOKIE'] );
        +				foreach ( $sc as $key => $value ) {
        +					echo esc_html( ' [ ' . $key . ' ]   =>   ' . $value );
        +					echo '
        '; + } + echo '
        '; + echo '

        WordPress Config

        '; + echo '
        ';
        +				$opts = array();
        +				if ( function_exists( 'wp_load_alloptions' ) ) {
        +					$opts = wp_load_alloptions();
        +				} else {
        +					// @var $wpdb wpdb .
        +					global $wpdb;
        +					$os = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" ); // db call ok; no-cache ok.
        +					foreach ( (array) $os as $o ) {
        +						$opts[ $o->option_name ] = $o->option_value;
        +					}
        +				}
        +
        +				$popts = array();
        +				foreach ( $opts as $k => $v ) {
        +					// Try to filter out passwords etc...
        +					if ( preg_match( '/pass|login|pw|secret|user|usr|key|auth|token/si', $k ) ) {
        +						continue;
        +					}
        +					$popts[ $k ] = htmlspecialchars( $v );
        +				}
        +				foreach ( $popts as $key => $value ) {
        +					echo esc_html( ' [ ' . $key . ' ]   =>   ' . $value );
        +					echo '
        '; + } + echo '
        '; + echo '

        Sitemap Config

        '; + echo '
        ';
        +				self::array_map_r( 'strip_tags', $this->sg->get_options() );
        +				echo '
        '; + echo '

        Sitemap Content and Errors, Warnings, Notices

        '; + echo '
        '; + + $sitemaps = $this->sg->simulate_index(); + + foreach ( $sitemaps as $sitemap ) { + + // @var $s GoogleSitemapGeneratorSitemapEntry . + $s = $sitemap['data']; + echo '

        Sitemap: get_url() ) . '\'>' . esc_html( $sitemap['type'] ) . '/' . ( esc_html( $sitemap['params'] ) ? esc_html( $sitemap['params'] ) : '(No parameters)' ) . ' by ' . esc_html( $sitemap['caller']['class'] ) . '

        '; + + $res = $this->sg->simulate_sitemap( $sitemap['type'], $sitemap['params'] ); + + echo "
          "; + foreach ( $res as $s ) { + // @var $d GoogleSitemapGeneratorSitemapEntry . + $d = $s['data']; + echo '
        • ' . esc_html( $d->get_url() ) . '
        • '; + } + echo '
        '; + } + + $status = GoogleSitemapGeneratorStatus::load(); + echo '
        '; + echo '

        MySQL Queries

        '; + if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) { + echo '
        ';
        +					// phpcs:disable.
        +					var_dump( $GLOBALS['wpdb']->queries );
        +					// phpcs:enable
        +					echo '
        '; + + $total = 0; + foreach ( $GLOBALS['wpdb']->queries as $q ) { + $total += $q[1]; + } + echo '

        Total Query Time

        '; + echo '
        ' . count( $GLOBALS['wpdb']->queries ) . ' queries in ' . esc_html( round( $total, 2 ) ) . ' seconds.
        '; + } else { + echo '

        Please edit wp-db.inc.php in wp-includes and set SAVEQUERIES to true if you want to see the queries.

        '; + } + echo '

        Build Process Results

        '; + echo '
        ';
        +				echo '
        '; + echo "

        Done. Rebuild or Return

        "; + echo "

        DO NOT POST THIS INFORMATION ON PUBLIC PAGES LIKE SUPPORT FORUMS AS IT MAY CONTAIN PASSWORDS OR SECRET SERVER INFORMATION!

        "; + echo '
        '; + return; + } else { + + $redir_url = $this->sg->get_back_link() . '&sm_fromrb=true'; + + // Redirect so the sm_rebuild GET parameter no longer exists. + header( 'location: ' . $redir_url ); + // If there was already any other output, the header redirect will fail. + echo ""; + echo ""; + exit; + } + } elseif ( ! empty( $_POST['sm_update'] ) ) { // Pressed Button: Update Config. + check_admin_referer( 'sitemap' ); + + if ( isset( $_POST['sm_b_style'] ) && $_POST['sm_b_style'] === $this->sg->get_default_style() ) { + $_POST['sm_b_style_default'] = true; + $_POST['sm_b_style'] = ''; + } + + $old_name = ''; + foreach ( $this->sg->get_options() as $k => $v ) { + // Skip some options if the user is not super admin... + if ( ! is_super_admin() && in_array( $k, array( 'sm_b_time', 'sm_b_memory', 'sm_b_style', 'sm_b_style_default' ), true ) ) { + continue; + } + + // Check vor values and convert them into their types, based on the category they are in. + if ( ! isset( $_POST[ $k ] ) ) { + $_POST[ $k ] = ''; + } // Empty string will get false on 2bool and 0 on 2float + // Options of the category 'Basic Settings' are boolean, except the filename and the autoprio provider. + if ( substr( $k, 0, 5 ) === 'sm_b_' ) { + if ( 'sm_b_prio_provider' === $k || 'sm_b_style' === $k || 'sm_b_memory' === $k || 'sm_b_baseurl' === $k || 'sm_b_sitemap_name' === $k || 'sm_b_old_sm_name' === $k ) { + if ( 'sm_b_filename_manual' === $k && strpos( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ), '\\' ) !== false ) { + $_POST[ $k ] = stripslashes( self::escape( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ) ); + } elseif ( 'sm_b_baseurl' === $k ) { + $_POST[ $k ] = esc_url_raw( trim( self::escape( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ) ) ); + if ( ! empty( $_POST[ $k ] ) ) { + $_POST[ $k ] = untrailingslashit( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ); + } + } elseif ( 'sm_b_style' === $k ) { + $_POST[ $k ] = esc_url_raw( trim( self::escape( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ) ) ); + if ( ! empty( $_POST[ $k ] ) ) { + $_POST[ $k ] = untrailingslashit( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ); + } + } elseif ( 'sm_b_sitemap_name' === $k ) { + $old_name = $v; + if ( '' === $_POST[ $k ] ) { + $_POST[ $k ] = 'sitemap'; + } else { + $_POST[ $k ] = trim( self::escape( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ) ); + if ( $this->sg->old_file_exists() ) { + $this->sg->delete_old_files(); + } + } + } elseif ( 'sm_b_old_sm_name' === $k ) { + $_POST[ $k ] = $old_name; + } + $this->sg->set_option( $k, (string) sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ); + } elseif ( 'sm_b_time' === $k ) { + if ( '' === $_POST[ $k ] ) { + $_POST[ $k ] = -1; + } + $this->sg->set_option( $k, intval( $_POST[ $k ] ) ); + } elseif ( 'sm_i_install_date' === $k ) { + if ( $this->sg->get_option( 'i_install_date' ) <= 0 ) { + $this->sg->set_option( $k, time() ); + } + } elseif ( 'sm_b_exclude' === $k ) { + $id_ss = array(); + $id_s = explode( ',', sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ); + $len = count( $id_s ); + for ( $x = 0; $x < $len; $x++ ) { + $id = intval( trim( $id_s[ $x ] ) ); + if ( $id > 0 ) { + $id_ss[] = $id; + } + } + $this->sg->set_option( $k, $id_ss ); + } elseif ( 'sm_b_exclude_cats' === $k ) { + $ex_cats = array(); + if ( isset( $_POST['post_category'] ) ) { + foreach ( (array) array_map( 'sanitize_text_field', ( wp_unslash( $_POST['post_category'] ) ) ) as $vv ) { + if ( ! empty( $vv ) && is_numeric( $vv ) ) { + $ex_cats[] = intval( $vv ); + } + } + } + if ( isset( $_POST['tax_input'] ) && isset( $_POST['tax_input']['product_cat'] ) ) { + $prod_cat = array_map( 'sanitize_text_field', ( wp_unslash( $_POST['tax_input']['product_cat'] ) ) ); + foreach ( (array) $prod_cat as $vv ) { + if ( ! empty( $vv ) && is_numeric( $vv ) ) { + $ex_cats[] = intval( $vv ); + } + } + } + $taxonomies = $this->sg->get_custom_taxonomies(); + foreach ( $taxonomies as $key => $taxonomy ) { + if ( isset( $_POST['tax_input'] ) && isset( $_POST['tax_input'][ $taxonomy ] ) ) { + $custom_cat = array_map( 'sanitize_text_field', ( wp_unslash( $_POST['tax_input'][ $taxonomy ] ) ) ); + foreach ( (array) $custom_cat as $vv ) { + if ( ! empty( $vv ) && is_numeric( $vv ) ) { + $ex_cats[] = intval( $vv ); + } + } + } + } + $this->sg->set_option( $k, $ex_cats ); + } else { + $this->sg->set_option( $k, (bool) $_POST[ $k ] ); + } + // Options of the category 'Includes' are boolean. + } elseif ( 'sm_i_tid' === $k ) { + // $_POST[ $k ] = trim( self::escape( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ) ); + $this->sg->set_option( $k, trim( self::escape( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ) ) ); + } elseif ( 'sm_user_consent' === $k ) { + + $allow_cookies = (bool) sanitize_text_field( wp_unslash( $_POST[ $k ] ) ); + if ( $allow_cookies ) { + update_option( 'sm_user_consent', 'yes' ); + } else { + update_option( 'sm_user_consent', 'no' ); + } + } elseif ( substr( $k, 0, 6 ) === 'sm_in_' ) { + if ( 'sm_in_tax' === $k ) { + + $enabled_taxonomies = array(); + $sm_in_tax = isset( $_POST[ $k ] ) ? (array) array_map( 'sanitize_text_field', ( wp_unslash( is_array( $_POST[ $k ] ) ? $_POST[ $k ] : array() ) ) ) : array(); + foreach ( array_keys( (array) $sm_in_tax ) as $tax_name ) { + if ( empty( $tax_name ) || ! taxonomy_exists( $tax_name ) ) { + continue; + } + + $enabled_taxonomies[] = self::escape( $tax_name ); + } + + $this->sg->set_option( $k, $enabled_taxonomies ); + } elseif ( 'sm_in_customtypes' === $k ) { + + $enabled_post_types = array(); + $sm_in_customtype = isset( $_POST[ $k ] ) ? (array) array_map( 'sanitize_text_field', wp_unslash( is_array( $_POST[ $k ] ) ? $_POST[ $k ] : array() ) ) : array(); + foreach ( array_keys( (array) $sm_in_customtype ) as $post_type_name ) { + if ( empty( $post_type_name ) || ! post_type_exists( $post_type_name ) ) { + continue; + } + + $enabled_post_types[] = self::escape( $post_type_name ); + } + + $this->sg->set_option( $k, $enabled_post_types ); + } else { + $this->sg->set_option( $k, (bool) $_POST[ $k ] ); + } + // Options of the category 'Change frequencies' are string. + } elseif ( substr( $k, 0, 6 ) === 'sm_cf_' ) { + $this->sg->set_option( $k, (string) self::escape( sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ) ); + // Options of the category 'Priorities' are float. + } elseif ( substr( $k, 0, 6 ) === 'sm_pr_' ) { + $this->sg->set_option( $k, (float) sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ); + } elseif ( 'sm_links_page' === $k ) { + $links_per_page = sanitize_text_field( wp_unslash( $_POST[ $k ] ) ); + $links_per_page = (int) $links_per_page; + if ( 0 >= $links_per_page || is_nan( $links_per_page ) ) { + $links_per_page = 1000; + } + $this->sg->set_option( $k, (int) $links_per_page ); + } elseif ( substr( $k, 0, 3 ) === 'sm_' ) { + $this->sg->set_option( $k, (bool) sanitize_text_field( wp_unslash( $_POST[ $k ] ) ) ); + } + } + GoogleSitemapGeneratorLoader::setup_rewrite_hooks(); + GoogleSitemapGeneratorLoader::activate_rewrite(); + + // Apply page changes from POST. + if ( is_super_admin() ) { + $this->sg->set_pages( $this->html_apply_pages() ); + } + + if(!$this->sg->get_option('sm_b_activate_indexnow')) $this->sg->set_option('sm_b_activate_indexnow', true); + + if ( $this->sg->save_options() ) { + $message .= __( 'Configuration updated', 'google-sitemap-generator' ) . '
        '; + } else { + $message .= __( 'Error while saving options', 'google-sitemap-generator' ) . '
        '; + } + + if ( is_super_admin() ) { + if ( $this->sg->save_pages() ) { + $message .= __( 'Pages saved', 'google-sitemap-generator' ) . '
        '; + } else { + $message .= __( 'Error while saving pages', 'google-sitemap-generator' ) . '
        '; + } + } + } elseif ( ! empty( $_POST['sm_reset_config'] ) ) { // Pressed Button: Reset Config. + + $options = get_option('sm_options', array()); + + check_admin_referer( 'sitemap' ); + delete_option( 'sm_show_beta_banner' ); + delete_option( 'sm_beta_banner_discarded_on' ); + delete_option( 'sm_beta_banner_discarded_count' ); + delete_option( 'sm_beta_notice_dismissed_from_wp_admin' ); + delete_option( 'sm_user_consent' ); + delete_option( 'sm_hide_auto_update_banner' ); + delete_option( 'sm_disabe_other_plugin' ); + + if(isset($options['sm_wp_sitemap_status'])) $wp_sitemap_status = $options['sm_wp_sitemap_status']; + + $this->sg->init_options(); + $this->sg->save_options(); + + $options_new = get_option('sm_options', array()); + if (isset($wp_sitemap_status) && $wp_sitemap_status === false) { + $options_new['sm_wp_sitemap_status'] = false; + } else if(isset($wp_sitemap_status) && $wp_sitemap_status === true) { + $options_new['sm_wp_sitemap_status'] = true; + } + + update_option('sm_options', $options_new); + + $message .= __( 'The default configuration was restored.', 'google-sitemap-generator' ); + } elseif ( ! empty( $_GET['sm_delete_old'] ) ) { // Delete old sitemap files. + check_admin_referer( 'sitemap' ); + + // Check again, just for the case that something went wrong before. + if ( ! current_user_can( 'administrator' ) ) { + echo '

        Please log in as admin

        '; + return; + } + if ( ! $this->sg->delete_old_files() ) { + $message = __( 'The old files could NOT be deleted. Please use an FTP program and delete them by yourself.', 'google-sitemap-generator' ); + } else { + $message = __( 'The old files were successfully deleted.', 'google-sitemap-generator' ); + } + } elseif ( ! empty( $_GET['sm_ping_all'] ) ) { + check_admin_referer( 'sitemap' ); + + // Check again, just for the case that something went wrong before. + if ( ! current_user_can( 'administrator' ) ) { + echo '

        Please log in as admin

        '; + return; + } + + ?> + + + + + + + + ' . esc_html( __( 'Notify Search Engines about all sitemaps', 'google-sitemap-generator' ) ) . ''; + echo '

        ' . esc_html( __( 'The plugin is notifying the selected search engines about your main sitemap and all sub-sitemaps. This might take a minute or two.', 'google-sitemap-generator' ) ) . '

        '; + flush(); + $results = $this->sg->send_ping_all(); + + echo '
          '; + + foreach ( $results as $result ) { + + $sitemap_url = $result['sitemap']; + // @var $status GoogleSitemapGeneratorStatus . + $status = $result['status']; + + echo esc_html( '
        • ' . $sitemap_url . '
            ' ); + $services = $status->get_used_ping_services(); + foreach ( $services as $service_id ) { + echo '
          • '; + echo esc_html( $status->get_service_name( $service_id ) . ': ' . ( $status->get_ping_result( $service_id ) === true ? 'OK' : 'ERROR' ) ); + echo '
          • '; + } + echo '
        • '; + } + echo '
        '; + echo '

        ' . esc_html( __( 'All done!', 'google-sitemap-generator' ) ) . '

        '; + ?> + + + Please log in as admin

        '; + return; + } + + $this->sg->send_ping(); + $message = __( 'Ping was executed, please see below for the result.', 'google-sitemap-generator' ); + } elseif ( ! empty( $_GET['sm_ping_all_subsitemaps'] ) ) { + check_admin_referer( 'sitemap' ); + + // Check again, just for the case that something went wrong before. + if ( ! current_user_can( 'administrator' ) ) { + echo '

        Please log in as admin

        '; + return; + } + + $this->sg->send_ping_all(); + $message = __( 'Ping was executed, please see below for the result.', 'google-sitemap-generator' ); + } elseif ( get_option( 'sm_beta_opt_in' ) ) { + delete_option( 'sm_beta_opt_in' ); + $message = __( 'Thanks for for supporting the project. We will reach out by email shortly.', 'google-sitemap-generator' ); + } + + // Print out the message to the user, if any. + if ( '' !== $message ) { + ?> +
        +

        + array(), + 'p' => array(), + 'strong' => array(), + ); + echo wp_kses( $message, $arr ); + ?> +

        +
        + sg->set_option( 'i_hide_donated', true ); + $this->sg->save_options(); + } + if ( isset( $_GET['sm_donated'] ) ) { + $this->sg->set_option( 'i_donated', true ); + $this->sg->save_options(); + } + if ( isset( $_GET['sm_hide_note'] ) ) { + $this->sg->set_option( 'i_hide_note', true ); + $this->sg->save_options(); + } + if ( isset( $_GET['sm_hide_survey'] ) ) { + $this->sg->set_option( 'i_hide_survey', true ); + $this->sg->save_options(); + } + if ( isset( $_GET['sm_hidedonors'] ) ) { + $this->sg->set_option( 'i_hide_donors', true ); + $this->sg->save_options(); + } + if ( isset( $_GET['sm_hide_works'] ) ) { + $this->sg->set_option( 'i_hide_works', true ); + $this->sg->save_options(); + } + if ( isset( $_GET['sm_disable_supportfeed'] ) ) { + $this->sg->set_option( 'i_supportfeed', 'true' === $_GET['sm_disable_supportfeed'] ? false : true ); + $this->sg->save_options(); + } + + if ( isset( $_GET['sm_donated'] ) || ( $this->sg->get_option( 'i_donated' ) === true && $this->sg->get_option( 'i_hide_donated' ) !== true ) ) { + ?> + + sg->get_option( 'i_donated' ) !== true && $this->sg->get_option( 'i_install_date' ) > 0 && $this->sg->get_option( 'i_hide_note' ) !== true && time() > ( $this->sg->get_option( 'i_install_date' ) + ( 60 * 60 * 24 * 30 ) ) ) { + ?> + +

        +
        + + sg->get_option( 'i_install_date' ) > 0 && $this->sg->get_option( 'i_hide_works' ) !== true && time() > ( $this->sg->get_option( 'i_install_date' ) + ( 60 * 60 * 24 * 15 ) ) ) { + ?> +
        + + +

        + array(), + 'p' => array(), + 'a' => array( + 'href' => array(), + ), + 'strong' => array(), + ); + /* translators: %s: search term */ + echo wp_kses( str_replace( array( '%1$s', '%2$s' ), $this->sg->get_redirect_link( 'redir/sitemap-works-note' ), __( 'Thanks for using this plugin! You\'ve installed this plugin some time ago. If it works and your are satisfied, why not rate it. and recommend it to others? :-)', 'google-sitemap-generator' ) ), $arr ); + ?> + ' style='float:right; display:block; border:none;'> + +

        +
        +
        +
        + get_max_input_vars() <= 0) { + ?> +
        +

        +
        + sg->show_survey() ) { + $this->sg->html_survey(); + } + } + + ?> + + +
        + user_email; + ?> + + + +
        +

        + sg->get_version() ); + ?> +

        + +
        +

        + array(), + 'p' => array(), + 'a' => array( + 'href' => array(), + ), + 'strong' => array(), + ); + /* translators: %s: search term */ + echo wp_kses( str_replace( '%s', 'options-reading.php#blog_public', __( 'Your Reading Settings signal to search engines not to index your website. While your sitemap will still be generated, the "Search engine visibility" setting should de-selected for optimal indexation.', 'google-sitemap-generator' ) ), $arr ); + ?> +

        +
        + + + +
        +
        +
        + +
        + + + + + html_print_box_header( 'sm_pnres', __( 'About this Plugin:', 'google-sitemap-generator' ), true ); ?> + '> + '> + '> + '> + '> + '> + + '> + html_print_box_footer( true ); ?> + + html_print_box_header( 'sm_smres', __( 'Sitemap Resources:', 'google-sitemap-generator' ), true ); ?> + '> + '> + '> + '> +
        + '> + '> + '> + html_print_box_footer( true ); ?> + + +
        +
        + + +
        + +
        + +
        + + + + get_start_time() && $this->sg->get_option('b_indexnow') ) { + $opt = get_option( 'gmt_offset' ); + $st = intval($status->get_start_time() + ( $opt * 3600 )); + /* translators: %s: search term */ + $head = str_replace( '%date%', date_i18n( get_option( 'date_format' ), $st ) . ' ' . date_i18n( get_option( 'time_format' ), $st ), esc_html__( 'Result of the last ping, started on %date%.', 'google-sitemap-generator' ) ); + } + else esc_html__( '“Search engines have not been notified yet. Publish or update a post to update your sitemap modification dates and notify IndexNow-compatible search engines.â€', 'google-sitemap-generator' ); + + $this->html_print_box_header( 'sm_rebuild', $head ); + ?> + + +
        + + sg->get_option( 'i_supportfeed' ) ) { + + echo 'sg->get_back_link() ) . '&sm_disable_supportfeed=true' ) . '\'>' . esc_html__( 'Disable', 'google-sitemap-generator' ) . ''; + + $support_feed = $this->sg->get_support_feed(); + + if ( ! is_wp_error( $support_feed ) && $support_feed ) { + $support_items = $support_feed->get_items( 0, $support_feed->get_item_quantity( 3 ) ); + + if ( count( $support_items ) > 0 ) { + echo '
          '; + foreach ( $support_items as $item ) { + $url = esc_url( $item->get_permalink() ); + $title = esc_html( $item->get_title() ); + $title = html_entity_decode( $title ); + $title = strip_tags( $title ); + echo '
        • ' . esc_html( $title ) . '
        • '; + } + echo '
        '; + } + } else { + echo '
        • ' . esc_html__( 'No support topics available or an error occurred while fetching them.', 'google-sitemap-generator' ) . '
        '; + } + } else { + echo ''; + } + ?> +
        + + +
        +
          + sg->old_file_exists() ) { + /* translators: %s: search term */ + echo '
        • ' . esc_html( str_replace( '%s', ( $this->sg->get_back_link() ) . '&sm_delete_old=true', 'google-sitemap-generator' ) ), esc_html__( 'There is still a sitemap.xml or sitemap.xml.gz file in your site directory. Please delete them as no static files are used anymore or try to delete them automatically.', 'google-sitemap-generator' ) . '
        • '; + } + $arr = array( + 'br' => array(), + 'p' => array(), + 'a' => array( + 'href' => array(), + ), + 'strong' => array(), + ); + /* translators: %s: search term */ + echo '
        • ' . wp_kses( str_replace( array( '%1$s', '%2$s' ), isset($custom_sitemap_name['sm_b_sitemap_name'])?home_url() .'/'. $custom_sitemap_name['sm_b_sitemap_name'] . '.xml':$this->sg->get_base_sitemap_url(), __( 'The URL to your sitemap index file is: %2$s.', 'google-sitemap-generator' ) ), $arr ) . '
        • '; + if ( !$this->sg->get_option('b_indexnow') ) { + //echo '
        • ' . esc_html__( 'Search engines haven\'t been notified yet. Write a post to let them know about your sitemap.', 'google-sitemap-generator' ) . '
        • '; + } else { + + $services = (null !== $status) ? $status->get_used_ping_services() : array(); + + foreach ( $services as $service ) { + $name = $status->get_service_name( $service ); + + if ( $status->get_ping_result( $service ) ) { + $arr = array( + 'b' => array(), + 'a' => array( + 'href' => array(), + ), + ); + /* translators: %s: search term */ + + echo '
        • ' . wp_kses( sprintf( __( '%s was successfully notified about changes.', 'google-sitemap-generator' ), $name ), $arr ) . '
        • '; + $dur = $status->get_ping_duration( $service ); + if ( $dur > 4 ) { + echo '
        • ' . wp_kses( str_replace( array( '%time%', '%name%' ), array( $dur, $name ), __( 'It took %time% seconds to notify %name%, maybe you want to disable this feature to reduce the building time.', 'google-sitemap-generator' ) ), $arr ) . '
        • '; + } + } else { + /* translators: %s: search term */ + //echo '
        • ' . wp_kses( str_replace( array( '%s', '%name%' ), array( wp_nonce_url( $this->sg->get_back_link() . '&sm_ping_service=' . $service . '&noheader=true', 'sitemap' ), $name ), __( 'There was a problem while notifying %name%. View result', 'google-sitemap-generator' ) ), $arr ) . '
        • '; + } + } + } + + ?> + sg->get_option('b_indexnow')) : ?> +
        • + Notify Search Engines about '>your sitemap or '>your main sitemap and all sub-sitemaps now. +
        • + + array(), + 'p' => array(), + 'a' => array( + 'href' => array(), + ), + 'strong' => array(), + ); + /* translators: %s: search term */ + echo '
        • ' . wp_kses( str_replace( '%d', wp_nonce_url( $this->sg->get_back_link() . '&sm_rebuild=true&sm_do_debug=true', 'sitemap' ), __( 'If you encounter any problems with your sitemap you can use the debug function to get more information.', 'google-sitemap-generator' ) ), $arr ) . '
        • '; + } + ?> +
        +
          +
        • + array(), + 'p' => array(), + 'a' => array( + 'href' => array(), + ), + 'strong' => array(), + ); + /* translators: %s: search term */ + echo wp_kses( sprintf( __( 'If you like the plugin, please rate it 5 stars! :)', 'google-sitemap-generator' ), $this->sg->get_redirect_link( 'redir/sitemap-works-note' ), $this->sg->get_redirect_link( 'redirsitemap-paypal' ) ), $arr ); + ?> +
        • +
        +
        + html_print_box_footer(); ?> + + sg->is_nginx() && $this->sg->is_using_permalinks() ) : ?> + html_print_box_header( 'ngin_x', __( 'Webserver Configuration', 'google-sitemap-generator' ) ); ?> + +

        + + '; // phpcs:ignore + } + ?> + +

        + html_print_box_footer(); ?> + + + + + html_print_box_header( 'sm_basic_options', __( 'Basic Options', 'google-sitemap-generator' ) ); ?> + + ' target='_blank'> +
          + +
        • +
          + + array(), + 'p' => array(), + 'a' => array( + 'href' => array(), + ), + 'strong' => array(), + ); + if ($this->sg->get_option('b_indexnow') && + $api_key = $this->index_now->getApiKey()) { + esc_html_e(sprintf(__('Microsoft Bing API Key: %s', 'google-sitemap-generator'), $api_key)); + echo '
          '; + } + /* translators: %s: search term */ + echo wp_kses( str_replace( '%s', $this->sg->get_redirect_link( 'redir/sitemap-gwb/' ), __( 'No registration required, however, you can join the Microsoft Bing Webmaster Tools for more crawling details.', 'google-sitemap-generator' ) ), $arr ); + ?> +
          +
        • +
        • + + +
          + +
        • +
        + + + + ' target='_blank'> +
          +
        • + ( ) +
        • +
        • + () +
        • +
        • +
          + +
        • +
        • + sg->get_default_style() && $this->sg->get_option( 'b_style_default' ) === true ); ?> + + () + sg->get_default_style() ) : + ?> + +
        • +
        • +
          + ' target='_blank'> +
        • +
        • +
          + ' target='_blank'> +
        • +
        • + +
        • +
        + + + html_print_box_footer(); ?> + + + html_print_box_header( 'sm_pages', __( 'Additional Pages', 'google-sitemap-generator' ) ); ?> + + array(), + 'p' => array(), + 'a' => array(), + 'strong' => array(), + ); + echo wp_kses( 'Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Site/WordPress.
        For example, if your domain is www.foo.com and your site is located on www.foo.com/site you might want to include your homepage at www.foo.com', $arr ); + echo '
        • '; + echo '' . esc_html__( 'Note', 'google-sitemap-generator' ) . ': '; + esc_html_e( 'If your site is in a subdirectory and you want to add pages which are NOT in the site directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!', 'google-sitemap-generator' ); + echo '
        • '; + echo '' . esc_html__( 'URL to the page', 'google-sitemap-generator' ) . ': '; + esc_html_e( 'Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home ', 'google-sitemap-generator' ); + echo '
        • '; + echo '' . esc_html__( 'Priority', 'google-sitemap-generator' ) . ': '; + esc_html_e( 'Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint.', 'google-sitemap-generator' ); + echo '
        • '; + echo '' . esc_html__( 'Last Changed', 'google-sitemap-generator' ) . ': '; + esc_html_e( 'Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional).', 'google-sitemap-generator' ); + + echo '
        '; + ?> + + sg->get_plugin_url() . 'img/sitemap.js' ), '', '1.0.0', false ); + ?> + + + + + + + + + + + + + +
        + + html_print_box_footer(); ?> + + + + + html_print_box_header( 'sm_postprio', __( 'Post Priority', 'google-sitemap-generator' ) ); ?> + +

        +
          + sg->get_prio_providers(); + array_unshift( $provs, '' ); + $len = count( $provs ); + for ( $i = 0; $i < $len; $i++ ) { + if ( 0 === $i ) { + echo '
        • html_get_checked( $this->sg->get_option( 'b_prio_provider' ), $provs[ $i ] ) ) . ' />
          ' . esc_html__( 'All posts will have the same priority which is defined in "Priorities"', 'google-sitemap-generator' ) . '

        • '; + } else { + echo '
        • html_get_checked( $this->sg->get_option( 'b_prio_provider' ), $provs[ $i ] ) ) . ' />
          ' . esc_html__( call_user_func( array( $provs[ $i ], 'get_description' ) ), 'google-sitemap-generator' ) . '

        • '; + } + } + ?> +
        + html_print_box_footer(); ?> + + + html_print_box_header( 'sm_includes', __( 'Sitemap Content', 'google-sitemap-generator' ) ); ?> + : +
          +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • + sg->is_taxonomy_supported() ) : ?> +
        • + +
        • + +
        + + sg->is_taxonomy_supported() ) { + $taxonomies = $this->sg->get_custom_taxonomies(); + + $enabled_taxonomies = $this->sg->get_option( 'in_tax' ); + + if ( count( $taxonomies ) > 0 ) { + ?> + + + : +
          + name, $enabled_taxonomies, true ); + ?> +
        • + +
        • + +
        + sg->is_custom_post_types_supported() ) { + $custom_post_types = $this->sg->get_custom_post_types(); + $enabled_post_types = $this->sg->get_option( 'in_customtypes' ); + + if ( count( $custom_post_types ) > 0 ) { + ?> + + : +
          + name, $enabled_post_types, true ); + } + + ?> +
        • + +
        • + +
        + + + : +
          +
        • +
          + + array(), + ); + echo wp_kses( __( 'This is highly recommended and helps the search engines to know when your content has changed. This option affects all sitemap entries.', 'google-sitemap-generator' ), $arr ); + ?> + +
        • +
        +
          +
        • + +
        • +
        + + html_print_box_footer(); ?> + + + html_print_box_header( 'sm_excludes', __( 'Excluded Items', 'google-sitemap-generator' ) ); ?> + + : + +
        +
          + sg->get_option( 'b_exclude_cats' ), false ); ?> +
        +
          + has_woo_commerce ) { + $defaults = array( + 'descendants_and_self' => 0, + 'selected_cats' => $this->sg->get_option( 'b_exclude_cats' ), + 'popular_cats' => false, + 'walker' => null, + 'taxonomy' => 'product_cat', + 'checked_ontop' => true, + 'echo' => true, + ); + } else { + $defaults = array( + 'selected_cats' => $this->sg->get_option( 'b_exclude_cats' ), + 'echo' => true, + ); + } + + wp_terms_checklist( 0, $defaults ); + ?> +
        + sg->get_custom_taxonomies(); + foreach ( $taxonomies as $key => $taxonomy ) { + ?> +
          + has_woo_commerce ) { + $defaults = array( + 'descendants_and_self' => 0, + 'selected_cats' => $this->sg->get_option( 'b_exclude_cats' ), + 'popular_cats' => false, + 'walker' => null, + 'taxonomy' => $taxonomy, + 'checked_ontop' => true, + 'echo' => true, + ); + } else { + $defaults = array( + 'selected_cats' => $this->sg->get_option( 'b_exclude_cats' ), + 'echo' => true, + ); + } + wp_terms_checklist( 0, $defaults ); + ?> +
        + +
        + : +
        +
        + : +
        + + html_print_box_footer(); ?> + + + html_print_box_header( 'sm_change_frequencies', __( 'Change Frequencies', 'google-sitemap-generator' ) ); ?> + +

        + : + +

        +
          +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • +
        • + +
        • + sg->is_taxonomy_supported() ) { + $in_tax = $this->sg->get_option( 'in_tax' ); + if( ! empty( $in_tax ) ) { + foreach( $in_tax as $tax_name ) { + $taxonomy = get_taxonomy( $tax_name ); + $field_name = "cf_" . $tax_name; + ?> +
        • + +
        • + +
        • + +
        • +
        • + +
        • + sg->is_taxonomy_supported() ) : ?> +
        • + +
        • + +
        • + +
        • +
        + + html_print_box_footer(); ?> + + + html_print_box_header( 'sm_priorities', __( 'Priorities', 'google-sitemap-generator' ) ); ?> +
          +
        • + +
        • +
        • + + +
        • +
        • + + +
        • +
        • + + +
        • +
        • + +
        • +
        • + +
        • + sg->is_taxonomy_supported() ) { + $in_tax = $this->sg->get_option( 'in_tax' ); + if( ! empty( $in_tax ) ) { + foreach( $in_tax as $tax_name ) { + $taxonomy = get_taxonomy( $tax_name ); + $field_name = "pr_" . $tax_name; + ?> +
        • + +
        • + +
        • + +
        • + sg->is_taxonomy_supported() ) : ?> +
        • + +
        • + +
        • + + +
        • +
        + + html_print_box_footer(); ?> + +
        + +
        + +
        + +
        +

        + + ' /> + ' /> +

        +
        + + +
        +
        +
        + +
        + array( + 'cc' => 'USD', + 'lc' => 'US', + ), + 'en-GB' => array( + 'cc' => 'GBP', + 'lc' => 'GB', + ), + 'de' => array( + 'cc' => 'EUR', + 'lc' => 'DE', + ), + ); + $my_lc = $lc['en']; + $wpl = get_bloginfo( 'language' ); + if ( ! empty( $wpl ) ) { + if ( array_key_exists( $wpl, $lc ) ) { + $my_lc = $lc[ $wpl ]; + } else { + $wpl = substr( $wpl, 0, 2 ); + if ( array_key_exists( $wpl, $lc ) ) { + $my_lc = $lc[ $wpl ]; + } + } + } + ?> + + ' /> + + + ' /> + ' /> + + ' /> + + + ' /> +
        +
        + XML-Sitemap and customize settings like priorities and change frequencies. +4. The plugin will automatically update your sitemap of you publish a post, so theres nothing more to do :) + + +Additional contributors: +============================================================================== +Inspiration Michael Nguyen http://www.socialpatterns.com/ +SQL Improvements Rodney Shupe http://www.shupe.ca/ +Japanse Lang. File Hirosama http://hiromasa.zone.ne.jp/ +Spanish lang. File Omi http://equipajedemano.info/ +Italian lang. File Stefano Aglietti http://wordpress-it.it/ +Trad.Chinese File Kirin Lin http://kirin-lin.idv.tw/ +Simpl.Chinese File june6 http://www.june6.cn/ +Swedish Lang. File Tobias Bergius http://tobiasbergius.se/ +Czech Lang. File Peter Kahoun http://kahi.cz +Finnish Lang. File Olli Jarva http://kuvat.blog.olli.jarva.fi/ +Belorussian Lang. File Marcis Gasuns +Bulgarian Lang. File Alexander Dichev http://dichev.com + +Thanks to all contributors and bug reporters! There were much more people involved +in testing this plugin and reporting bugs, either by email or in the WordPress forums. + +Unfortunately I can't maintain a whole list here, but thanks again to everybody not listed here! + + +Release History: +============================================================================== +2005-06-05 1.0 First release +2005-06-05 1.1 Added archive support +2005-06-05 1.2 Added category support +2005-06-05 2.0a Beta: Real Plugin! Static file generation, Admin UI +2005-06-05 2.0 Various fixes, more help, more comments, configurable filename +2005-06-07 2.01 Fixed 2 Bugs: 147 is now _e(strval($i)); instead of _e($i); 344 uses a full < ?php instead of < ? + Thanks to Christian Aust for reporting this :) +2005-06-07 2.1 Correct usage of last modification date for cats and archives (thx to Rodney Shupe (http://www.shupe.ca/)) + Added support for .gz generation + Fixed bug which ignored different post/page priorities + Should support now different wordpress/admin directories +2005-06-07 2.11 Fixed bug with hardcoded table table names instead of the $wpd vars +2005-06-07 2.12 Changed SQL Statement of the categories to get it work on MySQL 3 +2005-06-08 2.2 Added language file support: + - Japanese Language Files and code modifications by hiromasa (http://hiromasa.zone.ne.jp/) + - German Language File by Arne Brachhold (http://www.arnebrachhold.de) +2005-06-14 2.5 Added support for external pages + Added support for Google Ping + Added the minimum Post Priority option + Added Spanish Language File by César Gómez Martín (http://www.cesargomez.org/) + Added Italian Language File by Stefano Aglietti (http://wordpress-it.it/) + Added Traditional Chine Language File by Kirin Lin (http://kirin-lin.idv.tw/) +2005-07-03 2.6 Added support to store the files at a custom location + Changed the home URL to have a slash at the end + Required admin-functions.php so the script will work with external calls, wp-mail for example + Added support for other plugins to add content to the sitemap via add_filter() +2005-07-20 2.7 Fixed wrong date format in additional pages + Added Simplified Chinese Language Files by june6 (http://www.june6.cn/) + Added Swedish Language File by Tobias Bergius (http://tobiasbergius.se/) +2006-01-07 3.0b Added different priority calculation modes and introduced an API to create custom ones + Added support to use the Popularity Contest plugin by Alex King to calculate post priority + Added Button to restore default configuration + Added several links to homepage and support + Added option to exclude password protected posts + Added function to start sitemap creation via GET and a secret key + Posts and pages marked for publish with a date in the future won't be included + Improved compatiblity with other plugins + Improved speed and optimized settings handling + Improved user-interface + Recoded plugin architecture which is now fully OOP +2006-01-07 3.0b1 Changed the way for hook support to be PHP5 and PHP4 compatible + Readded support for tools like w.Bloggar + Fixed "doubled-content" bug with WP2 + Added xmlns to enable validation +2006-03-01 3.0b3 More performance + More caching + Better support for Popularity Contest and WP 2.x +2006-11-16 3.0b4 Fixed bug with option SELECTS + Decreased memory usage which should solve timeout and memory problems + Updated namespace to support YAHOO and MSN +2007-01-19 3.0b5 Javascripted page editor + WP 2 Design + YAHOO notification + New status report, removed ugly logfiles + Better Popularity Contest Support + Fixed double backslashes on windows systems + Added option to specify time limit and memory limit + Added option to define a XSLT stylesheet and added a default one + Fixed bug with sub-pages. Thanks to: + - Mike Baptiste (http://baptiste.us), + - Peter Claus Lamprecht (http://fastagent.de) + - Glenn Nicholas (http://publicityship.com.au) + Improved file handling, thanks to VJTD3 (http://www.VJTD3.com) + WP 2.1 improvements +2007-01-23 3.0b6 Use memory_get_peak_usage instead of memory_get_usage if available + Removed the usage of REQUEST_URI since it not correct in all environments + Fixed that sitemap.xml.gz was not compressed + Added compat function "stripos" for PHP4 (Thanks to Joseph Abboud!) + Streamlined some code +2007-05-17 3.0b7 Added option to include the author pages like /author/john + Small enhancements, removed stripos dependency and the added compat function + Added check to not build the sitemap if importing posts + Fixed missing domain parameter for translator name + Fixed WP 2.1 / Pre 2.1 post / pages database changes + Fixed wrong XSLT location (Thanks froosh) + Added Ask.com notification + Removed unused javascript +2007-07-22 3.0b8 Changed category SQL to prevent unused cats from beeing included + Plugin will be loaded on "init" instead of direclty after the file has been loaded. + Added support for robots.txt modification + Switched YAHOO ping API from YAHOO Web Services to the "normal" ping service which doesn't require an app id + Search engines will only be pinged if the sitemap file has changed +2007-09-02 3.0b9 Added tag support for WordPress 2.3 + Now using post_date_gmt instead of post_date everywhere + Fixed archive bug with static pages (Thanks to Peter Claus Lamprecht) + Fixed some missing translation domains, thanks to Kirin Lin! + Added Czech translation files for 2.7.1, thanks to Peter Kahoun (http://kahi.cz) +2007-09-04 3.0b10 Added category support for WordPress 2.3 + Fixed bug with empty URLs in sitemap + Repaired GET building + Added more info on debug mode +2007-09-23 3.0b11 Changed mysql queries to unbuffered queries + Uses MUCH less memory + Fixed really stupid bug with search engine pings + Option to set how many posts will be included +2007-09-24 3.0 Yeah, 3.0 Final after one and a half year ;) + Removed useless functions +2007-11-03 3.0.1 Using the Snoopy HTTP client for ping requests instead of wp_remote_fopen + Fixed undefined translation strings + Added "safemode" for SQL which doesn't use unbuffered results (old style) + Added option to run the building process in background using wp-cron + Removed unnecessary function_exists, Thanks to user00265 + Added links to test the ping if it failed. +2007-11-25 3.0.2 Fixed bug which caused that some settings were not saved correctly + Added option to exclude pages or post by ID + Restored YAHOO ping service with API key since the other one is to unreliable. (see 3.0b8) +2007-11-28 3.0.2.1 Fixed wrong XML Schema Location (Thanks to Emanuele Tessore) + Added Russian Language files by Sergey http://ryvkin.ru +2007-12-30 3.0.3 Added Live Search Ping + Removed some hooks which rebuilt the sitemap with every comment +2008-03-30 3.0.3.1 Added compatibility CSS for WP 2.5 +2008-04-28 3.0.3.2 Improved WP 2.5 handling +2008-04-29 3.0.3.3 Fixed author pages + Enhanced background building and increased delay to 15 seconds + Background building is enabled by default +2008-04-28 3.1b1 Reorganized files in builder, loader and UI + Added 2 step loader so only code that's needed will be loaded + Improved WP 2.5 handling + Secured all admin actions with nonces +2008-05-18 3.1b2 Fixed critical bug with the build in background option + Added notification if a build is scheduled +2008-05-19 3.1b3 Cleaned up plugin directory and moved asset files to subfolders + Fixed background building bug in WP 2.1 + Removed auto-update plugin link for WP < 2.5 +2008-05-22 3.1 Marked as 3.1 stable, updated documentation +2008-05-27 3.1.0.1 Extracted UI JS to external file + Enabled the option to include following pages of multi-page posts + Script tries to raise memory and time limit if active +2008-12-21 3.1.1 Fixed redirect issue if wp-admin is rewritten via mod_rewrite, thanks to macjoost + Fixed wrong path to assets, thanks PozHonks + Fixed wrong plugin URL if wp-content was renamed / redirected, thanks to wnorris + Updated WP User Interface for 2.7 + Various other small things +2008-12-26 3.1.2 Changed the way the stylesheet is saved (default / custom stylesheet) + Sitemap is now build when page is published + Removed support for static robots.txt files, this is now handled via WordPress + Added compat. exceptions for WP 2.0 and WP 2.1 +2009-06-07 3.1.3 Changed MSN Live Search to Bing + Exclude categories also now exludes the category itself and not only the posts + Pings now use the new WordPress HTTP API instead of Snoopy + Fixed bug that in localized WP installations priorities could not be saved. + The sitemap cron job is now cleared after a manual rebuild or after changing the config + Adjusted style of admin area for WP 2.8 and refreshed icons + Disabled the "Exclude categories" feature for WP 2.5.1, since it doesn't have the required functions yet +2009-06-22 3.1.4 Fixed bug which broke all pings in WP < 2.7 + Added more output in debug mode if pings fail + Moved global post definitions for other plugins + Added small icon for ozh admin menu + Added more help links in UI +2009-08-24 3.1.5 Added option to completely disable the last modification time + Fixed bug regarding the use of the HTTPS url for the XSL stylesheet if the sitemap was build via the admin panel + Improved handling of homepage if a single page was set for it + Fixed mktime warning which appeared sometimes + Fixed bug which caused inf. reloads after rebuilding the sitemap via the admin panel + Improved handling of missing sitemaps files if WP was moved to another location +2009-08-31 3.1.6 Fixed PHP error "Only variables can be passed by reference" + Fixed wrong URLS of multi-page posts (Thanks artstorm!) +2009-10-21 3.1.7 Added support for custom taxonomies (Thanks to Lee!) +2009-11-07 3.1.8 Improved custom taxonomy handling and fixed wrong last modification date + Changed readme and backlinks + Fixed fatal error in WP < 2.3 + Fixed Update Notice in WP 2.8+ + Added warning if blog privacy is activated + Fixed custom URLs priorities were shown as 0 instead of 1 +2009-11-13 3.1.9 Fixed MySQL Error if author pages were included +2009-11-23 3.2 Added function to show the actual results of a ping instead of only linking to the url + Added new hook (sm_rebuild) for third party plugins to start building the sitemap + Fixed bug which showed the wrong URL for the latest Google ping result + Added some missing phpdoc documentation + Removed hardcoded php name for sitemap file for admin urls + Uses KSES for showing ping test results + Ping test fixed for WP < 2.3 +2009-12-16 3.2.1 Notes and update messages could interfere with the redirect after manual build + Help Links in the WP context help were not shown anymore since last update + IE 7 sometimes displayed a cached admin page + Removed invalid link to config page from the plugin description (This resulted in a "Not enough permission error") + Improved performance of getting the current plugin version with caching + Updated Spanish language files +2009-12-19 3.2.2 Fixed PHP4 problems +2010-04-02 3.2.3 Fixed that all pages were not included in the sitemap if the "Uncategorized" category was excluded +2010-05-29 3.2.4 Fixed more deprecated function calls + Added (GMT) to sitemap xslt template to avoid confusion with time zone + Added warning and don't activate plugin if multisite mode is enabled (this mode is NOT tested yet) + Changed get_bloginfo('siteurl') to get_bloginfo('url') to avoid deprecation warning + Changed has_cap(10) to has_cap('level_10') to avoid deprecation warning + Fixed wrong SQL statement for author pages (Ticket #1108), thanks to twoenough +2010-07-11 3.2.5 Backported Bing ping success fix from beta + Added friendly hint to try out the new beta +2010-09-19 3.2.6 Removed YAHOO ping since YAHOO uses bing now + Removed deprecated function call +2012-04-24 3.2.7 Fixed custom post types, thanks to clearsite of the wordpress.org forum! + Fixed broken admin layout on WP 3.4 +2012-08-08 3.2.8 Fixed wrong custom taxonomy URLs, thanks to ramon fincken of the wordpress.org forum! + Removed ASK ping since they shut down their service. + Exclude post_format taxonomy from custom taxonomy list +2013-01-11 3.2.9 Fixed security issue with change frequencies and filename of sitemap file. Exploit was only possible for admin accounts. +2013-09-28 3.3 Fixed problem with file permission checking + Filter out hashs (#) in URLs +2013-11-24 3.4 Fixed deprecation warnings in PHP 5.4, thanks to Dion Hulse! +2014-03-29 4.0 No static files anymore, sitemap is created on the fly + Sitemap is split-up into sub-sitemaps by month, allowing up to 50.000 posts per month + Support for custom post types and custom taxonomis! + 100% Multisite compatible, including by-blog and network activation. + Added support for mu-plugins forced-activation (see sitemap-wpmu.php for details) + Reduced server resource usage due to less content per request. + New API allows other plugins to add their own, separate sitemaps. + Raised min requirements to PHP 5.1 and WordPress 3.3 + Note: This version will try to rename your old sitemap files to *-old.xml. If that doesn’t work, please delete them manually since no static files are needed anymore! + Using only wpdb instead of unbuffered queries anymore + Ping to search engines are done on WP ping + Using PHP5 syntax instead of old PHP4 OOP style + Added pre-loader which checks the requirements + Avoid the main query of WordPress (based on plugin by Michael Adams) + Avoid additional queries in post sitemaps + Added custom post types + Fixed include of static front page in pages index + Do not list "#" permalinks from placeholder plugins + Removed YAHOO pings since YAHOO doesn't have its own ping service anymore. + Sitemap doesn't state it is a feed anymore + Removed Ask.com ping since they shut down their service (who uses Ask anyway?) +2014-03-31 4.0.1 Fixed bug with custom post types including a "-" + Changed rewrite-setup to happen on init and flushing on wp_loaded to better work with other plugins +2014-04-01 4.0.2 Fixed warning if an gzip handler is already active +2014-04-13 4.0.3 Fixed compression if an gzlib handler was already active + Help regarding permalinks for Nginx users + Fix with gzip compression in case there was other output before already + Return 404 for HTML sitemaps if the option has been disabled +2014-04-19 4.0.4 Removed deprecated get_page call + Changed last modification time of sub-sitemaps to the last modification date of the posts instead of the publish date + Removed information window if the statistic option has not been activated + Added link regarding new sitemap format + Updated Portuguese translation, thanks to Pedro Martinho + Updated German translation +2014-05-18 4.0.5 Fixed issue with empty post sitemaps (related to GMT/local time offset) + Fixed some timing issues in archives + Improved check for possible problems before gzipping + Fixed empty Archives and Authors in case there were no posts + Changed content type to text/xml to improve compatibility with caching plugins + Changed query parameters to is_feed=true to improve compatibility with caching plugins + Switched from using WP_Query to load posts to a custom SQL statement to avoid problems with other plugin filters + Fixed bug which caused the Priority Provider to disappear in recent PHP versions + Cleaned up code and renamed variables to be more readable + Added caching of some SQL statements + Added support feed for more help topics + Added support for changing the base of the sitemap url to another URL (for WP installations in sub-folders) + Changed text in XSL template to be more clear about sitemap-index and sub-sitemaps + Added link to new help page + Plugin will also ping with the corresponding sub-sitemap in case a post was modified + Added function to manually start ping for main-sitemap or all sub-sitemaps + Better checking for empty externals + Updated Japanese Translation, thanks to Daisuke Takahashi +2014-06-03 4.0.6 Added option to disable automatic gzipping + Fixed bug with duplicated external sitemap entries + Updated language file template + Don't gzip if behind Varnish + Improved compatibility with caches + Ping on post edit +2014-06-23 4.0.7 Better compatibility with managed GoDaddy hosting (clear alloptions cache when generating the sitemap) + Improved checking if the sitemap should be gzipped or not (depending on ob levels) + Removed WordPress version from the sitemap + Corrected link to WordPress privacy settings + Changed hook which is being used for sitemap pings +2014-09-02 4.0.7.1Added icon for the new WP Add-Plugin page + Changed "Tested up to" to 4.0 +2014-11-15 4.0.8 Fixed bug with excluded categories, thanks to Claus Schöffel! +2017-03-22 4.0.9 Fixed security issue with donation submission. +2018-12-18 4.1.0 Fixed security issues related to forms and external URLs +2022-04-07 4.1.1 Fixed security issues and added support for WooCommerce based sitemap +2022-04-07 4.1.2 Fixed security issues and features like support for WooCommerce based sitemap +2022-05-31 4.1.3 Added backward compatibility settings, Changed Google Tracking ID field to optional, Fixed PHP warnings +2022-06-06 4.1.4 Fixed the issue of PHP warnings, Fixed links per page issue, Improved WordPress 6.0 compatibility +2022-06-14 4.1.5 Fixed code regressions moving from git to svn +2022-11-23 4.1.6 Made the Google TID field non mandatory in order to ping Google +2022-11-24 4.1.7 Fixed custom taxonomy unit generation issue + + + +Todo: +============================================================================== +- Your wishes :) + + +License: +============================================================================== +Copyright 2005 - 2018 ARNE BRACHHOLD (email : himself - arnebrachhold - de) + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Please see license.txt for the full license. + + +Developer Documentation +============================================================================== + +Adding other pages to the sitemap via other plugins + +This plugin uses the action system of WordPress to allow other plugins +to add urls to the sitemap. Simply add your function with add_action to +the list and the plugin will execute yours every time the sitemap is build. +Use the static method "get_instance" to get the generator and add_url method +to add your content. + +Sample: + +function your_pages() { + $generatorObject = &GoogleSitemapGenerator::get_instance(); + if($generatorObject!=null) $generatorObject->add_url("http://blog.uri/tags/hello/",time(),"daily",0.5); +} +add_action("sm_buildmap", "your_pages"); + +Parameters: +- The URL to the page +- The last modified data, as a UNIX timestamp (optional) +- The Change Frequency (daily, hourly, weekly and so on) (optional) +- The priority 0.0 to 1.0 (optional) + + +Rebuilding the sitemap on request + +If you want to rebuild the sitemap because dynamic content from your plugin has changed, +please use the "sm_rebuild" hook which is available since 3.1.9. +All other methods, like calling the Build method directly are highly unrecommended and might +not work anymore with the next version of the plugin. Using this hook, the sitemap plugin will +take care of everything like loading the required classes and so on. + +Sample: + +do_action("sm_rebuild"); + +The sitemap might not be rebuild immediately, since newer versions use a background WP-Cron +job by default to prevent that the user has to wait and avoid multiple rebuilds within a very short time. +In case the sitemap plugin is not installed, nothing will happen and no errors will be thrown. + +=============================================== + +Adding additional PriorityProviders + +This plugin uses several classes to calculate the post priority. +You can register your own provider and choose it at the options screen. + +Your class has to extend the GoogleSitemapGeneratorPrioProviderBase class +which has a default constructor and a method called GetPostPriority +which you can override. + +Look at the GoogleSitemapGeneratorPrioByPopularityContestProvider class +for an example. + +To register your provider to the sitemap generator, use the following filter: + +add_filter("sm_add_prio_provider","AddMyProvider"); + +Your function could look like this: + +function AddMyProvider($providers) { + array_push($providers,"MyProviderClass"); + return $providers; +} + +Note that you have to return the modified list! \ No newline at end of file diff --git a/html/wp-content/plugins/google-sitemap-generator/google-sitemap-generator-prio-provider-base.php b/html/wp-content/plugins/google-sitemap-generator/google-sitemap-generator-prio-provider-base.php new file mode 100644 index 0000000..42a95a1 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/google-sitemap-generator-prio-provider-base.php @@ -0,0 +1,54 @@ +1) { + firstRow.parentNode.removeChild(firstRow); + } + } + var cnt = table.getElementsByTagName('TR').length; + if(cnt%2) tr.className="alternate"; + + table.appendChild(tr); +} + +function sm_loadPages() { + for(var i=0; i, 2005. +# $Id: sitemap.pot 2327 2005-06-19 03:09:59 RedAltExport $ +msgid "" +msgstr "" +"Project-Id-Version: Sitemap v2.7.1 for WP\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-06-07 01:15+0100\n" +"PO-Revision-Date: 2009-07-15 03:12+0200\n" +"Last-Translator: Hazem Khaled \n" +"Language-Team: Sewar \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Arabic\n" +"X-Poedit-Country: ARABIAN WORLD\n" +"X-Poedit-SourceCharset: utf-8\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:642 +msgid "Comment Count" +msgstr "عدد التعليقات" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:654 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "أستخدم عدد التعليقات لحساب الأولوية" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:714 +msgid "Comment Average" +msgstr "متوسط التعليقات" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:726 +msgid "Uses the average comment count to calculate the priority" +msgstr "أستخدم متوسط التعليقات لحساب الأولوية" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:789 +msgid "Popularity Contest" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:801 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1187 +msgid "Always" +msgstr "دائماً" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1188 +msgid "Hourly" +msgstr "كل ساعة" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1189 +msgid "Daily" +msgstr "يومياً" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1190 +msgid "Weekly" +msgstr "اسبوعياً" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1191 +msgid "Monthly" +msgstr "شهرياً" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1192 +msgid "Yearly" +msgstr "سنوياً" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1193 +msgid "Never" +msgstr "أبداً" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Hide this notice" +msgstr "Ø£Ø®ÙØ§Ø¡ هذا التبليغ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "شكراً ﻷستخدامك هذه Ø§Ù„Ø£Ø¶Ø§ÙØ©! لقد قمت بتركيب Ø§Ù„Ø¥Ø¶Ø§ÙØ© من اكثر من شهر. إذا كنت راضي عن النتائج, يمكنك التبرع بدولار واحد على الأقل؟ المتبرعين ساعدوني بدعم وتطوير هذه Ø§Ù„Ø£Ø¶Ø§ÙØ© المجانية! أكيد, لا يوجد مشكلة!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +msgid "No thanks, please don't bug me anymore!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:119 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:121 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:146 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:453 +msgid "XML Sitemap Generator for WordPress" +msgstr "صانع خريطة الموقع" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:298 +msgid "Configuration updated" +msgstr "تم تحديث الإعدادات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:299 +msgid "Error while saving options" +msgstr "حدث خطأ عند Ø­ÙØ¸ إعدادات Ø§Ù„ØµÙØ­Ø§Øª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:301 +msgid "Pages saved" +msgstr "تم Ø­ÙØ¸ إعدادات Ø§Ù„ØµÙØ­Ø§Øª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:302 +msgid "Error while saving pages" +msgstr "حدث خطأ عند Ø­ÙØ¸ إعدادات Ø§Ù„ØµÙØ­Ø§Øª" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:309 +msgid "The default configuration was restored." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:466 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "هناك إصدارة جديدة %1$s متاحة. تحميل الأصدارة %3$s من هنا." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:468 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "هناك إصدارة جديدة %1$s متاحة. تحميل الأصدارة %3$s من هنا. التحديث التلقائي غير متاح ÙÙŠ هذه المدونة." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:470 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "هناك إصدارة جديدة %1$s متاحة. تحميل الأصدارة %3$s من هنا او حدث تلقائياً." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:493 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:510 +msgid "open" +msgstr "ÙØªØ­" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:494 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:511 +msgid "close" +msgstr "أغلاق" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:495 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:512 +msgid "click-down and drag to move this box" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:496 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:513 +msgid "click to %toggle% this box" +msgstr "أضغط لكي %toggle% هذا المربع" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:497 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:514 +msgid "use the arrow keys to move this box" +msgstr "أستخدم السهم لتحريك المربعات" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:498 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:515 +msgid ", or press the enter key to %toggle% it" +msgstr ", او أضغط على الزر لـ%toggle%" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +msgid "About this Plugin:" +msgstr "عن هذه Ø§Ù„Ø£Ø¶Ø§ÙØ©" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:534 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:141 +msgid "Plugin Homepage" +msgstr "Ø§Ù„ØµÙØ­Ø© الرئيسية" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:535 +msgid "Suggest a Feature" +msgstr "رشح خاصية جديدة" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:536 +msgid "Notify List" +msgstr "قائمة التبليغ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:537 +msgid "Support Forum" +msgstr "منتدى الدعم" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:538 +msgid "Report a Bug" +msgstr "أبلغ عن خطأ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:540 +msgid "Donate with PayPal" +msgstr "تبرع بالباي بال" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:541 +msgid "My Amazon Wish List" +msgstr "قائمة رغباتي بأمازون" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:542 +msgid "translator_name" +msgstr "إعادة الترجمة : حازم خالد" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:542 +msgid "translator_url" +msgstr "http://HazemKhaled.com" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:545 +msgid "Sitemap Resources:" +msgstr "موارد خريطة الموقع:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:546 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:552 +msgid "Webmaster Tools" +msgstr "ادوات مدير الموقع" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:547 +msgid "Webmaster Blog" +msgstr "مدونة مدير الموقع" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:549 +msgid "Site Explorer" +msgstr "Ù…ØªØµÙØ­ الموقع" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:550 +msgid "Search Blog" +msgstr "بحث المدونة" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:553 +msgid "Webmaster Center Blog" +msgstr "مدونة مركز مدير الموقع" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:555 +msgid "Sitemaps Protocol" +msgstr "بروتوكول خريطة الموقع" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:556 +msgid "Official Sitemaps FAQ" +msgstr "الأسئلة الشائعة الرسمية عن خريطة المواقع" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:557 +msgid "My Sitemaps FAQ" +msgstr "الأسئلة الشائعة عن خريطة الموقع" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:560 +msgid "Recent Donations:" +msgstr "أخر تبرع" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:564 +msgid "List of the donors" +msgstr "قائمة المتبرعين" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:566 +msgid "Hide this list" +msgstr "Ø§Ø®ÙØ§Ø¡ هذه القائمة" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:569 +msgid "Thanks for your support!" +msgstr "شكراً لدعمك" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:587 +msgid "Status" +msgstr "الحالة" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:595 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:601 +msgid "Your sitemap was last built on %date%." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:603 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreأعر٠المزيد" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:610 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:612 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreأعر٠المزيد" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:618 +msgid "Google was successfully notified about changes." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:621 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:624 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:630 +msgid "YAHOO was successfully notified about changes." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:633 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:636 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:642 +msgid "Bing was successfully notified about changes." +msgstr "" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:645 +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:648 +#, php-format +msgid "There was a problem while notifying Bing. View result" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:654 +msgid "Ask.com was successfully notified about changes." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:657 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:660 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:668 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "تم الأنشاء ÙÙŠ حوالي %time% ثانية وأستخدام %memory% MB من الذاكرة." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:670 +msgid "The building process took about %time% seconds to complete." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:674 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:682 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:685 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:687 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:691 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:695 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:698 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "إذا تغير شيء على الخادم الخاص بك أو مدونتك, Ùيجب عليك إعادة غنشاء الخريطة يدوياً" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:700 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "إذا واجهتك أي مشاكل ÙÙŠ عملية انشاء الخريطة Ùيمكنك أستخدام debug function للحصول على المزيد من المعلومات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:707 +msgid "Basic Options" +msgstr "إعدادات أساسية" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:709 +msgid "Sitemap files:" +msgstr "Ù…Ù„ÙØ§Øª الخريطة" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:709 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Learn more" +msgstr "أعر٠المزيد" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:714 +msgid "Write a normal XML file (your filename)" +msgstr "كتابة مل٠XML عادي (مل٠خريطة الموقع)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:720 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "كتابة مل٠XML مضغوط (مل٠خريطة الموقع + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +msgid "Building mode:" +msgstr "نظام البناء:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:729 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "اعادة إنشاء الخريطة إذا قمت بتغيير محتوى المدونة" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:736 +msgid "Enable manual sitemap building via GET Request" +msgstr "إتاحة أنشاء الخريطة يدوياً عن طريق طلب GET" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:740 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +msgid "Update notification:" +msgstr "تحديث التبليغات:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:748 +msgid "Notify Google about updates of your Blog" +msgstr "تبليغ جوجل عن تحديثات موقعك" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:749 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "لا يحتاج للتسجيل, ولكن يمكنك التسجيل ÙÙŠ Google Webmaster Tools لمتابعة أحصائيات Ø£Ø±Ø´ÙØ© موقعك." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:753 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "أبلاغ BING (رسمياً MSN Live Search) عن التحديثات بمدونتك" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:754 +#, php-format +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "لا يحتاج للتسجيل, ولكن يمكنك التسجيل ÙÙŠ Bing Webmaster Tools لمتابعة أحصائيات Ø£Ø±Ø´ÙØ© موقعك." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:758 +msgid "Notify Ask.com about updates of your Blog" +msgstr "أبلاغ Ask.com عن تحديثات مدونتك" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:759 +msgid "No registration required." +msgstr "لا يحتاج للتسجيل" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:763 +msgid "Notify YAHOO about updates of your Blog" +msgstr "تبليغ YAHOO بتحديثات مدونتك" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:764 +msgid "Your Application ID:" +msgstr "رقم الطلب الخاص بك :" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:765 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:770 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Ø¥Ø¶Ø§ÙØ© خريطة الموقع لمل٠robots.txt" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:774 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "مل٠robots.txt Ø§Ù„Ø£ÙØªØ±Ø§Ø¶ÙŠ Ø§Ù„Ø°ÙŠ تم إنشائه بواسطة WordPress قيد الأستخدام. مل٠robots.txt Ø§Ù„ÙØ¹Ù„ÙŠ يجب أن لا يكون موجود بمجلد المدونة!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Advanced options:" +msgstr "خيارات متقدمة" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Limit the number of posts in the sitemap:" +msgstr "تحديد عدد التدوينات ÙÙŠ الخريطة :" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Newer posts will be included first" +msgstr "التدوينة الجديدة ستدرج الأولى" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "Try to increase the memory limit to:" +msgstr "حاول تزيد حد الذاكرة إلى:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "e.g. \"4M\", \"16M\"" +msgstr "مثال : \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "Try to increase the execution time limit to:" +msgstr "حاول زيادة مدة التنÙيذ :" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "بالثواني, مثال: \"60\" أو \"0\" للغير نهائي" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:790 +msgid "Include a XSLT stylesheet:" +msgstr "أستخدام مل٠تنسيقي XSLT:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Full or relative URL to your .xsl file" +msgstr "الرابط كاملاً ملÙÙ… ال .xsl" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Use default" +msgstr "أستخدام Ø§Ù„Ø£ÙØªØ±Ø§Ø¶ÙŠ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:797 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "ØªÙØ¹ÙŠÙ„ وضع MySQL القياسي. أستخدها Ùقط ÙÙŠ حالة حدوث اخطاء MySQL. (يحتاج إلى المزيد من الذاكرة!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:798 +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "يجب تحديث وردبريس للأصدارة 2.2 Ù„ØªÙØ¹ÙŠÙ„ وصل أسرع لل MySQL" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:805 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "بناء خريطة الموقع ÙÙŠ كل مرة ÙÙŠ الخلÙية (لكل لا يأخر عملية Ø­ÙØ¸ التدوينات)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:806 +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "يجب تحديث المدونة لإصدارة 2.1 على الأقل Ù„ØªÙØ¹ÙŠÙ„ العمل ÙÙŠ الخلÙية" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:813 +msgid "Additional pages" +msgstr "ØµÙØ­Ø§Øª إضاÙية" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:816 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "هنا يمكنك تضمين Ø§Ù„Ù…Ù„ÙØ§Øª Ùˆ الروابط التي يجب أن يتم تضمينها ÙÙŠ خريطة الموقع، لكنها لا تتبع ووردبريس .
        على سبيل المثال، إذا كان نطاق موقعك www.foo.com Ùˆ مدونتك موجودة ÙÙŠ www.foo.com/blog أنت قد تريد تضمين Ø§Ù„ØµÙØ­Ø© الرئيسية لموقعك ÙÙŠ www.foo.com." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:818 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:997 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1020 +msgid "Note" +msgstr "تنبيه" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:819 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "إذا كانت مدونتك ÙÙŠ مجلد ÙØ±Ø¹ÙŠ Ùˆ أردت Ø¥Ø¶Ø§ÙØ© ØµÙØ­Ø§Øª خارج مجلد مدونتك، يجب عليك وضع مل٠خريطة موقعك ÙÙŠ المجلد الرئيسي لموقعك (انظر ÙØ³Ù… "مكان مل٠خريطة موقعك" ÙÙŠ هذه Ø§Ù„ØµÙØ­Ø©)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:821 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:860 +msgid "URL to the page" +msgstr "رابط Ø§Ù„ØµÙØ­Ø©" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "ضع رابط Ø§Ù„ØµÙØ­Ø© ØŒ مثلاً : http://www.foo.com/index.html أو www.foo.com/home ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:824 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:861 +msgid "Priority" +msgstr "Ø§Ù„Ø£ÙØ¶Ù„ية" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:825 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "إختر Ø£ÙØ¶Ù„ية Ø§Ù„ØµÙØ­Ø© نسبة إلى Ø§Ù„ØµÙØ­Ø§Øª الأخرى ØŒ على سبيل المثال ØŒ ØµÙØ­ØªÙƒ الرئيسية لربّما يكون لها Ø£ÙØ¶Ù„ية أعلى من سيرتك الذاتية ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:827 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "Last Changed" +msgstr "آخر تعديل" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:828 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "ضع تاريخ آخر تعديل كـ YYYY-MM-DD (مثلاً : 2005-12-31) (اختياري) ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:862 +msgid "Change Frequency" +msgstr "ÙØªØ±Ø© التحديث" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:864 +msgid "#" +msgstr "#" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:869 +msgid "No pages defined." +msgstr "لا يوجد ØµÙØ­Ø§Øª Ù…Ø¶Ø§ÙØ© ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:874 +msgid "Add new page" +msgstr "Ø£Ø¶Ù ØµÙØ­Ø© جديدة" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:879 +msgid "Post Priority" +msgstr "Ø§Ù„Ø£ÙØ¶Ù„ية" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:881 +msgid "Please select how the priority of each post should be calculated:" +msgstr "الرجاء اختيار مدى أولوية كل تدوينة :" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:883 +msgid "Do not use automatic priority calculation" +msgstr "لا تستخدم حساب الأولوية تلقائيا" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:883 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "كل المواضيع تحمل Ù†ÙØ³ الأولوية التي تم تحديدها ÙÙŠ "الأولويات"" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:894 +msgid "Location of your sitemap file" +msgstr "مكان مل٠خريطة موقعك" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:897 +msgid "Automatic detection" +msgstr "الكش٠الآلي" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:901 +msgid "Filename of the sitemap file" +msgstr "اسم مل٠خريطة الموقع:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:904 +msgid "Detected Path" +msgstr "مسار الملÙ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:904 +msgid "Detected URL" +msgstr "رابط الملÙ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:909 +msgid "Custom location" +msgstr "مسار مخصص" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:913 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "المسار الكامل لمل٠خريطة الموقع." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:915 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:924 +msgid "Example" +msgstr "مثال" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:922 +msgid "Complete URL to the sitemap file, including name." +msgstr "الرابط الكامل لمل٠خريطة الموقع." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:935 +msgid "Sitemap Content" +msgstr "محتوى خريطة الموقع" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:941 +msgid "Include homepage" +msgstr "تضمين Ø§Ù„ØµÙØ­Ø© الرئيسية" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:947 +msgid "Include posts" +msgstr "تضمين التدوينات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:953 +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "إدراج Ø§Ù„ØµÙØ­Ø§Øª التابعة للمواضيع متعددة Ø§Ù„ØµÙØ­Ø§Øª (يزيد ÙÙŠ مدة إنشاء الخيرطة وكمية الذاكرة المستخدمة)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:959 +msgid "Include static pages" +msgstr "تضمين Ø§Ù„ØµÙØ­Ø§Øª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:965 +msgid "Include categories" +msgstr "تضمين Ø§Ù„ØªØµÙ†ÙŠÙØ§Øª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:971 +msgid "Include archives" +msgstr "تضمين الأرشيÙ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:978 +msgid "Include tag pages" +msgstr "تضمين ØµÙØ­Ø§Øª التاجات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:985 +msgid "Include author pages" +msgstr "تضمين ØµÙØ­Ø§Øª الكتاب" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:993 +msgid "Excluded items" +msgstr "استبعاد عناصر" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:995 +msgid "Excluded categories" +msgstr "استبعاد Ø§Ù„ØªØµÙ†ÙŠÙØ§Øª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:997 +msgid "Using this feature will increase build time and memory usage!" +msgstr "باستخدام هذه الميزة سو٠تزيد من وقت الأنشاء واستخدام ذاكرة اكبر!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1004 +#, php-format +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "هذه الخاصية تحتاج لنسخة وردبريس 2.5.1, أنت تستخدم %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1007 +msgid "Exclude posts" +msgstr "استبعاد التدوينات" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +msgid "Exclude the following posts or pages:" +msgstr "أستبعاد التدوينات او المواضيع الأتية:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +msgid "List of IDs, separated by comma" +msgstr "ضع الأرقام IDs, ÙˆØ£ÙØµÙ„ بينهم بكومة انجليزية" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1011 +msgid "Child posts won't be excluded automatically!" +msgstr "المواضيع التابعة لن تستبعد تلقائيا!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1017 +msgid "Change frequencies" +msgstr "ÙØªØ±Ø© التحديث" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1021 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "رجاء لاحظ بأنّ قيمة هذه الخاصية هي تلميح معتبر Ùˆ ليس إجبارياً . بالرغم من أنّ محركات البحث تقرأ هذه الخاصية عندما تبحث ØŒ هي قد ØªÙØ­Øµ Ø§Ù„ØµÙØ­Ø§Øª التي أشّرت \"كل ساعة\" أقل كثيرا من ذلك ØŒ وهي قد ØªÙØ­Øµ Ø§Ù„ØµÙØ­Ø§Øª التي أشّرت \"سنوياً\" أكثر من ذلك . هي أيضا من المحتمل ØªÙØ­Øµ Ø§Ù„ØµÙØ­Ø§Øª التي أشّرت \"أبداً\" بشكل دوري لكي هم يمكن أن يعالجوا التغييرات الغير المتوقّعة ÙÙŠ تلك Ø§Ù„ØµÙØ­Ø§Øª ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1084 +msgid "Homepage" +msgstr "Ø§Ù„ØµÙØ­Ø© الرئيسية" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1033 +msgid "Posts" +msgstr "التدوينات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1039 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1102 +msgid "Static pages" +msgstr "Ø§Ù„ØµÙØ­Ø§Øª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1045 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1108 +msgid "Categories" +msgstr "Ø§Ù„ØªØµÙ†ÙŠÙØ§Øª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1051 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "أرشي٠الشهر الحالي (ÙŠÙØ¶Ù„ أن يكون مثل Ø§Ù„ØµÙØ­Ø© الرئيسية)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1057 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "الأرشي٠السابق (يتغير عندما تحرر تدوينة قديمة Ùقط)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1121 +msgid "Tag pages" +msgstr "ØµÙØ­Ø§Øª التاجات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1128 +msgid "Author pages" +msgstr "ØµÙØ­Ø§Øª المؤلÙين" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1079 +msgid "Priorities" +msgstr "Ø§Ù„Ø£ÙØ¶Ù„يات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1090 +msgid "Posts (If auto calculation is disabled)" +msgstr "التدوينات (إذا كان الحساب الآلي غير Ù…ÙØ¹Ù„)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1096 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Ø£ÙØ¶Ù„ية التدوينة الدنيا (حتى إذا كان الحساب الآلي Ù…ÙØ¹Ù„)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1114 +msgid "Archives" +msgstr "الأرشيÙ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1139 +msgid "Update options" +msgstr "تحديث الإعدادات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1140 +msgid "Reset options" +msgstr "تصÙير الإعدادات" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:84 +msgid "XML-Sitemap Generator" +msgstr "صانع خريطة الموقع" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:84 +msgid "XML-Sitemap" +msgstr "خريطة الموقع" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:142 +msgid "Sitemap FAQ" +msgstr "الأسئلة الشائعة عن خريطة الموقع" + +#~ msgid "Manual location" +#~ msgstr "تحديد الرابط يدوياً" +#~ msgid "OR" +#~ msgstr "أو" +#~ msgid "Error" +#~ msgstr "حصل خطأ" +#~ msgid "" +#~ "A new page was added. Click on "Save page changes" to save your " +#~ "changes." +#~ msgstr "" +#~ "تم Ø¥Ø¶Ø§ÙØ© ØµÙØ­Ø© جديدة ØŒ إضغط على زر "Ø­ÙØ¸ تغييرات Ø§Ù„ØµÙØ­Ø§Øª" Ù„Ø­ÙØ¸ " +#~ "تغييراتك ." +#~ msgid "" +#~ "The page was deleted. Click on "Save page changes" to save your " +#~ "changes." +#~ msgstr "تم Ø­Ø°Ù Ø§Ù„ØµÙØ­Ø© ." +#~ msgid "You changes have been cleared." +#~ msgstr "تم إلغاء تغييراتك ." +#~ msgid "Manual rebuild" +#~ msgstr "إنشاء خريطة الموقع يدوياً" +#~ msgid "" +#~ "If you want to build the sitemap without editing a post, click on here!" +#~ msgstr "" +#~ "إذا كنت تريد إنشاء خريطة الموقع بدون تعديل تدوينة ØŒ إضغط على الزر التالي :" +#~ msgid "Rebuild Sitemap" +#~ msgstr "إعادة إنشاء خريطة الموقع" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-bg_BG.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-bg_BG.mo new file mode 100644 index 0000000..7fefcb8 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-bg_BG.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-bg_BG.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-bg_BG.po new file mode 100644 index 0000000..dea81e3 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-bg_BG.po @@ -0,0 +1,827 @@ +msgid "" +msgstr "" +"Project-Id-Version: sitemap 3.1.1\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2009-03-02 13:53+0200\n" +"Last-Translator: Alexander Dichev \n" +"Language-Team: Alexander Dichev \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Bulgarian\n" +"X-Poedit-Country: BULGARIA\n" +"X-Poedit-SourceCharset: utf-8\n" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:642 +msgid "Comment Count" +msgstr "Брой Коментари" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:654 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Използва Ð±Ñ€Ð¾Ñ Ð½Ð° коментарите при калкулиране на приоритета на поÑта" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:714 +msgid "Comment Average" +msgstr "Коментари Средно" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:726 +msgid "Uses the average comment count to calculate the priority" +msgstr "Използва ÑÑ€ÐµÐ´Ð½Ð¸Ñ Ð±Ñ€Ð¾Ð¹ на коментарите при калкулиране на приоритета" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:789 +msgid "Popularity Contest" +msgstr "Popularity Contest" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:801 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Използва активиран Popularity Contest Plugin от Alex King. Виж ÐаÑтройки и Ðай-популÑрните поÑтове." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1118 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1209 +msgid "Always" +msgstr "Винаги" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1119 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1210 +msgid "Hourly" +msgstr "ЕжечаÑно" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1120 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1211 +msgid "Daily" +msgstr "Ежедневно" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1212 +msgid "Weekly" +msgstr "ЕжеÑедмично" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1122 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1213 +msgid "Monthly" +msgstr "ЕжемеÑечно" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1123 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1214 +msgid "Yearly" +msgstr "Ежегодно" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1215 +msgid "Never" +msgstr "Ðикога" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Ð‘Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ñ Ð’Ð¸ много за дарението. Вие ми помагате да продължа развитието и поддръжката на този плъгин и на други безплатни Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ Ñофтуер." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Hide this notice" +msgstr "Скриване на Ñъобщението" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Ð‘Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ñ Ð’Ð¸, че използвате този плъгин! Вие Ñте инÑталирали и използвате този плъгин повече от меÑец. Ðко работи добре и Ñте доволни от резултата, не Ñи ли заÑлужава поне един долар? ДарениÑта ми помагат да продължа развитието и поддръжката на този безплатен Ñофтуер! Разбира Ñе, нÑма проблеми! " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +msgid "No thanks, please don't bug me anymore!" +msgstr "Ðе благодарÑ, молÑ, не ме безпокойте повече!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:119 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "Вашата карта на Ñайта Ñе обновÑва в момента. Ð’ завиÑимоÑÑ‚ от големината на блога, това би коÑтвало извеÑтно време." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:121 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "Вашата карта на Ñайта ще бъде обновена Ñлед %s Ñекунди. Ð’ завиÑимоÑÑ‚ от големината на блога, това би коÑтвало извеÑтно време." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:146 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:441 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Sitemap Генератор за WordPress" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:278 +msgid "Configuration updated" +msgstr "КонфигурациÑта е обновена" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:279 +msgid "Error while saving options" +msgstr "Грешка при запазване на наÑтройките" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:281 +msgid "Pages saved" +msgstr "Страниците Ñа запаметени" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:282 +msgid "Error while saving pages" +msgstr "Грешка при запаметÑване на Ñтраниците" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:286 +#, php-format +msgid "Robots.txt file saved" +msgstr "Файла Robots.txt е запазен" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:288 +msgid "Error while saving Robots.txt file" +msgstr "Грешка при запазването на файла robots.txt" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:297 +msgid "The default configuration was restored." +msgstr "Стандартните наÑтройки Ñа възÑтановени" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:454 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "Има нова верÑÐ¸Ñ Ð½Ð° %1$s. Изтеглете верÑÐ¸Ñ %3$s тук." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:456 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "Има нова верÑÐ¸Ñ Ð½Ð° %1$s. Изтегли верÑÐ¸Ñ %3$s тук невъзможно е автоматично обновÑване за това разширение." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:458 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "Има нова верÑÐ¸Ñ Ð½Ð° %1$s. Изтегли верÑÐ¸Ñ %3$s тук илиr обнови автоматично." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:481 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:498 +msgid "open" +msgstr "отвори" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:482 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:499 +msgid "close" +msgstr "затвори" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:483 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:500 +msgid "click-down and drag to move this box" +msgstr "кликнете Ñ Ð¼Ð¸ÑˆÐºÐ°Ñ‚Ð° върху кутиÑта и провлачете за да Ñ Ð¿Ñ€ÐµÐ¼ÐµÑтите" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:484 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:501 +msgid "click to %toggle% this box" +msgstr "кликнете за да %toggle% кутиÑта" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:485 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:502 +msgid "use the arrow keys to move this box" +msgstr "използвайте бутоните ÑÑŠÑ Ñтрелките за премеÑтване на кутиÑта" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:486 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:503 +msgid ", or press the enter key to %toggle% it" +msgstr ", или натиÑнете бутона Enter за да го %toggle%" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:521 +msgid "About this Plugin:" +msgstr "За плъгина:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:522 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:138 +msgid "Plugin Homepage" +msgstr "Страница на плъгина" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:523 +msgid "Suggest a Feature" +msgstr "Предложи Ðова ВъзможноÑÑ‚" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:524 +msgid "Notify List" +msgstr "E-Mail абонамент за обновÑваниÑта" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:525 +msgid "Support Forum" +msgstr "Форуми за помощ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:526 +msgid "Report a Bug" +msgstr "Докладвай за Бъг" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:528 +msgid "Donate with PayPal" +msgstr "Дарение Ñ PayPal" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:529 +msgid "My Amazon Wish List" +msgstr "МоÑÑ‚ ÑпиÑък Ñ Ð¶ÐµÐ»Ð°Ð½Ð¸Ñ Ð¾Ñ‚ Amazon" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:530 +msgid "translator_name" +msgstr "Alexander Dichev" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:530 +msgid "translator_url" +msgstr "http://dichev.com/" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +msgid "Sitemap Resources:" +msgstr "Sitemap РеÑурÑи:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:534 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:540 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:535 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:537 +msgid "Site Explorer" +msgstr "Site Explorer" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:538 +msgid "Search Blog" +msgstr "Search Blog" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:541 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:543 +msgid "Sitemaps Protocol" +msgstr "Sitemaps Протокол" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:544 +msgid "Official Sitemaps FAQ" +msgstr "Официални ЧеÑто Задавани ВъпроÑи" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:545 +msgid "My Sitemaps FAQ" +msgstr "Моите ЧеÑто Задавани ВъпроÑи" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:548 +msgid "Recent Donations:" +msgstr "ПоÑледни ДарениÑ;" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:552 +msgid "List of the donors" +msgstr "СпиÑък на дарителите" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:554 +msgid "Hide this list" +msgstr "Скрийте този ÑпиÑък" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:557 +msgid "Thanks for your support!" +msgstr "Ð‘Ð»Ð°Ð³Ð¾Ð´Ð°Ñ€Ñ Ð·Ð° помощта!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:575 +msgid "Status" +msgstr "СтатуÑ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:583 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Ð’Ñе още не е Ñъздаден sitemap-файл. От тази връзка генерирайте карта на Ñайта за първи път." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:589 +msgid "Your sitemap was last built on %date%." +msgstr "ВашиÑÑ‚ sitemap-файл беше Ñъздаден уÑпешно на %date%." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:591 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreПовече информациÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:598 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "ВашиÑÑ‚ архивиран sitemap-файл беше Ñъздаден уÑпешно на %date%." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:600 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreПовече информациÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:606 +msgid "Google was successfully notified about changes." +msgstr "Google беше уведомен уÑпешно за промените в блога." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:609 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Отне %time% Ñекунди за уведомÑването на Google ако желаете да намалите времето за генериране можете да деактивирате тази функциÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:612 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Имаше проблем Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ñването на Google. Виж резултата" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:618 +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOO беше уведомен уÑпешно за промените в блога." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:621 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Отне %time% Ñекунди за уведомÑването на YAHOO ако желаете да намалите времето за генериране можете да деактивирате тази функциÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:624 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Имаше проблем Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ñването на YAHOO. Виж резултата" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:630 +msgid "MSN was successfully notified about changes." +msgstr "MSN беше уведомен уÑпешно за промените в блога." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:633 +msgid "It took %time% seconds to notify MSN.com, maybe you want to disable this feature to reduce the building time." +msgstr "Отне %time% Ñекунди за уведомÑването на MSN.com, ако желаете да намалите времето за генериране можете да деактивирате тази функциÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:636 +#, php-format +msgid "There was a problem while notifying MSN.com. View result" +msgstr "Имаше проблем Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ñването на MSN.com. Виж резултата" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:642 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com беше уведомен уÑпешно за промените в блога." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:645 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Отне %time% Ñекунди за уведомÑването на Ask.com ако желаете да намалите времето за генериране можете да деактивирате тази функциÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:648 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Имаше проблем Ñ ÑƒÐ²ÐµÐ´Ð¾Ð¼Ñването на Ask.com. Виж резултата" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:656 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Генерирането на sitemap-а отне %time% Ñекунди и беше използвана %memory% MB памет." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:658 +msgid "The building process took about %time% seconds to complete." +msgstr "ПроцеÑÑŠÑ‚ на генериране отне %time% Ñекунди." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:662 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Съдържанието на картата на Ñайта Ви не е променено от поÑÐ»ÐµÐ´Ð½Ð¸Ñ Ð¿ÑŠÑ‚, затова файлове не бÑха Ñъздадени и не бÑха ping-нати търÑачки." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:670 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "Възможно е процеÑÑŠÑ‚ по изграждане вÑе още да не е приключил. Презареди Ñтраницата Ñлед нÑколко Ñекунди и провери за промÑна." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:673 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "ПоÑледниÑÑ‚ опит на генериране на карта на Ñайта приключи неуÑпешно! Можете да опитате да увеличите макÑимума използвана памет и лимита за време на изпълнение на PHP-Ñкриптове на Ð’Ð°ÑˆÐ¸Ñ ÑƒÐµÐ±-Ñървър. Повече информациÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:675 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "ПоÑледното региÑтрирано количеÑтво използвана от Ñкрипта памет е %memused%MB, лимита за използвана памет от PHP-Ñкриптове, зададен в конфигурациÑта на Ð’Ð°ÑˆÐ¸Ñ ÑƒÐµÐ±-Ñървър е %memlimit%MB." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:679 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "ПоÑледното региÑтрирано време за изпълнение на Ñкрипта беше %timeused% Ñекунди, лимита за продължителноÑÑ‚ на изпълнение на PHP-Ñкриптове зададен в конфигурациÑта на Ð’Ð°ÑˆÐ¸Ñ ÑƒÐµÐ±-Ñървър е %timelimit% Ñекунди." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:683 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Изпълнението на този Ñкрипт ÑÐ¿Ñ€Ñ Ð¾ÐºÐ¾Ð»Ð¾ поÑÑ‚ номер %lastpost% (+/- 100)." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:686 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Ðко Ñте направили нÑкакви промени по Ñървъра или блога е необходимо да Регенерирате Sitemap-а ръчно." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:688 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Ðко изпитвате проблеми при Ñъздаването на файла можете да активирате Дебъг ФункциÑта за да получите повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° грешките." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:695 +msgid "Basic Options" +msgstr "ОÑновни ÐаÑтройки" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:697 +msgid "Sitemap files:" +msgstr "Sitemap файлове:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:697 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:712 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:732 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:765 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:782 +msgid "Learn more" +msgstr "Повече информациÑ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:702 +msgid "Write a normal XML file (your filename)" +msgstr "Генерирай нормален XML файл (име на файла)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:708 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Генерирай архивирана верÑÐ¸Ñ (име_на_файла + .gz)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:712 +msgid "Building mode:" +msgstr "Метод на генериране:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:717 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Регенерирай sitemap-а при промÑна в Ñъдържанието на блога" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +msgid "Enable manual sitemap building via GET Request" +msgstr "Ðктивиране на ръчно генериране на sitemap-файла чрез изпращане на GET заÑвка" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:728 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Това прави възможно регенериране на sitemap-а ако външен инÑтрумент е внеÑъл промени в базата данни на WordPress без да изпозва WordPress API. Ðктивирайте процеÑа от тази връзка: %1. МолÑ, проверете log-файла по-горе за да разжерете дали sitemap-а е генериран уÑпешно." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:732 +msgid "Update notification:" +msgstr "УведомÑване при обновÑване:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:736 +msgid "Notify Google about updates of your Blog" +msgstr "УведомÑване на Google при обновÑване на блога Ви" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:737 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Ðе е необходима региÑтрациÑ, но трÑбва да Ñе включите в Google Webmaster Tools за да проверите ÑтатиÑтиката от поÑещениÑта на търÑачката на Ñайта ви." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:741 +msgid "Notify MSN Live Search about updates of your Blog" +msgstr "УведомÑване на MSN Live Search при обновÑване на блога Ви" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:742 +#, php-format +msgid "No registration required, but you can join the MSN Live Webmaster Tools to check crawling statistics." +msgstr "Ðе е необходима региÑтрациÑ, но трÑбва да Ñе включите в MSN Live Webmaster Tools за да проверите ÑтатиÑтиката от поÑещениÑта на търÑачката на Ñайта ви." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:746 +msgid "Notify Ask.com about updates of your Blog" +msgstr "УведомÑване на Ask.com за обновÑÐ²Ð°Ð½Ð¸Ñ Ð½Ð° блога Ви" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:747 +msgid "No registration required." +msgstr "Ðе е необходима региÑтрациÑ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:751 +msgid "Notify YAHOO about updates of your Blog" +msgstr "УведомÑване на YAHOO за обновÑÐ²Ð°Ð½Ð¸Ñ Ð½Ð° блога Ви" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:752 +msgid "Your Application ID:" +msgstr "Вашето Application ID:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:753 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "ÐÑмате ли ключ? ЗаÑвете Ñи от тук! %s2" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:760 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "ОбновÑване или Ñъздаване на факл %s в главната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ð° блога, коÑто Ñе намира меÑтоположението на картата на Ñайта." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:763 +msgid "File permissions: " +msgstr "Права върху файла:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:768 +msgid "OK, robots.txt is writable." +msgstr "OK, robots.txt е разрешен за промÑна." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:770 +msgid "Error, robots.txt is not writable." +msgstr "Грешка, robots.txt е заключен за промÑна." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:774 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, robots.txt не ÑъщеÑтвува, но директориÑта е разрешена за пиÑане." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:776 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Грешка, robots.txt не ÑъщеÑтвува и директориÑта не е разрешена за пиÑане" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:782 +msgid "Advanced options:" +msgstr "Допълнителни наÑтройки:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:785 +msgid "Limit the number of posts in the sitemap:" +msgstr "Ограничи Ð±Ñ€Ð¾Ñ Ð½Ð° поÑтовете в sitemap-а:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:785 +msgid "Newer posts will be included first" +msgstr "Ðовите поÑтове ще бъдат включени първо" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:788 +msgid "Try to increase the memory limit to:" +msgstr "При възможноÑÑ‚ увеличи лимита на паметта на:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:788 +msgid "e.g. \"4M\", \"16M\"" +msgstr "например \"4M\", \"16M\"" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Try to increase the execution time limit to:" +msgstr "При възможноÑÑ‚ увеличи времето за изпълнение на:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "Ñекунди, например \"60\" или \"0\" без ограничение" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:795 +msgid "Include a XSLT stylesheet:" +msgstr "Добави XSLT Stylesheet:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:796 +msgid "Full or relative URL to your .xsl file" +msgstr "ÐбÑолютен или отноÑителен URL до Ð’Ð°ÑˆÐ¸Ñ .xsl файл" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:796 +msgid "Use default" +msgstr "Използвай Стандартните" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:801 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Ðктивиране на MySQL Standard метод. Използва Ñе Ñамо при получаване на MySQL грешки. (Използва доÑта повече памет!)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:807 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Генерирай картата на Ñайта на заден план (ÐÑма да е необходимо да Ñе чака при запазване на поÑÑ‚)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:814 +msgid "Additional pages" +msgstr "Допълнителни Ñтраници" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:817 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Тук можете да определите файлове или URL-и, които да бъдат добавени в картата на Ñайта, въпреки, че не Ñа чаÑÑ‚ от блога/WordPress.
        Ðапример, ако домейнът Ви е www.foo.com и блогът Ви Ñе намира на www.foo.com/blog, може да добавите заглавната Ñтраница на Ñайта Ñи http://www.foo.com" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:819 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:998 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1021 +msgid "Note" +msgstr "Забележка" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:820 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Ðко блогът Ви Ñе намира в Ð¿Ð¾Ð´Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð¸ Вие желаете да включите Ñтраници, които ÐЕ Ñа в директориÑта на блога, вие ТРЯБВРда локализирате Ð’Ð°ÑˆÐ¸Ñ sitemap-файл в главната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ (Виж ÑекциÑта "МеÑтонахождение на sitemap-файла")!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:861 +msgid "URL to the page" +msgstr "URL на Ñтраницата" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:823 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Въведете URL на Ñтраницата. Примери: http://www.foo.com/index.html или www.foo.com/home " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:825 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:862 +msgid "Priority" +msgstr "Приоритет" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:826 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Изберете приоритета на Ñтраницата в завиÑимоÑÑ‚ от другите Ñтраници. Ðапример, Вашата заглавна Ñтраница може да има по-виÑок приоритет от Ñтраницата Ви за контакт." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:828 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:864 +msgid "Last Changed" +msgstr "ПоÑледна ПромÑна" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:829 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Въведете датата на поÑледното обновÑване във вида (например 2005-12-31) (незадължително)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "Change Frequency" +msgstr "ЧеÑтота на ОбновÑване" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:865 +msgid "#" +msgstr "#" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:870 +msgid "No pages defined." +msgstr "ÐÑма дефинирани Ñтраници." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:875 +msgid "Add new page" +msgstr "ДобавÑне на нова Ñтраница" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:880 +msgid "Post Priority" +msgstr "Приоритет на ПоÑта" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:882 +msgid "Please select how the priority of each post should be calculated:" +msgstr "МолÑ, изберете начин на калкулиране на приоритета на поÑтовете" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:884 +msgid "Do not use automatic priority calculation" +msgstr "Ðе използвай авто-калкулиране на приоритета" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:884 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Ð’Ñички поÑтове ще имат еднакъв приоритет, който е дефиниран в "Приоритети"" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:895 +msgid "Location of your sitemap file" +msgstr "Път до sitemap-файла" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:898 +msgid "Automatic detection" +msgstr "Ðвтоматично разпознаване" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:902 +msgid "Filename of the sitemap file" +msgstr "Име на sitemap-файла" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:905 +msgid "Detected Path" +msgstr "Ðамерен път" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:905 +msgid "Detected URL" +msgstr "Ðамерен URL" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:910 +msgid "Custom location" +msgstr "Друго меÑтонахождение" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:914 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "ÐбÑолютен и отноÑителен път до sitemap-файла, включително името." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:925 +msgid "Example" +msgstr "Пример" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:923 +msgid "Complete URL to the sitemap file, including name." +msgstr "ÐбÑолютен URL до sitemap-файла, включително името." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:936 +msgid "Sitemap Content" +msgstr "Съдържание на картата на Ñайта" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:942 +msgid "Include homepage" +msgstr "Включи заглавната Ñтраница" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:948 +msgid "Include posts" +msgstr "Включи поÑтове" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:911 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:954 +msgid "Include following pages of multi-page posts (<!--nextpage-->)" +msgstr "Включи Ñледните Ñтраници от многоÑтранични Ñтатии (<!--nextpage-->)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:960 +msgid "Include static pages" +msgstr "Включи Ñтатични Ñтраници" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:966 +msgid "Include categories" +msgstr "Включи категории" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:972 +msgid "Include archives" +msgstr "Включи архиви" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:979 +msgid "Include tag pages" +msgstr "Включи Ñтраници Ñ Ñ‚Ð°Ð³Ð¾Ð²Ðµ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:986 +msgid "Include author pages" +msgstr "Включи авторÑки Ñтраници" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:994 +msgid "Excluded items" +msgstr "Изключени" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:996 +msgid "Excluded categories" +msgstr "Изключени категории" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:998 +msgid "Using this feature will increase build time and memory usage!" +msgstr "Използването на това ще увеличи времето за Ñъздаване и употребата на памет!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1005 +#, php-format +msgid "This feature requires at least WordPress 2.5, you are using %s" +msgstr "Това изиÑква най-малко WordPress 2.5, Вие използвате %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1008 +msgid "Exclude posts" +msgstr "Изключени поÑтове" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +msgid "Exclude the following posts or pages:" +msgstr "Ðе включвай Ñледните поÑтове и/или Ñтраници:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +msgid "List of IDs, separated by comma" +msgstr "СпиÑък на ID-тата, разделени ÑÑŠÑ Ð·Ð°Ð¿ÐµÑ‚Ð°Ñ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1012 +msgid "Child posts will not automatically be excluded!" +msgstr "ПодÑтраниците ще бъдат автоматично изключени!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1018 +msgid "Change frequencies" +msgstr "ЧеÑтота на обновÑване" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1022 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "МолÑ, обърнете внимание, че ÑтойноÑтта на този таг е Ñамо подÑказка, а не команда. Дори търÑачките да Ñе влиÑÑÑ‚ от тази Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¸ вземане на решениÑта Ñи, те може да поÑещават Ñтраници, маркирани Ñ \"hourly\" по-Ñ€Ñдко от това на вÑеки Ñ‡Ð°Ñ Ð¸ Ñтраници маркирани Ñ \"yearly\" по-чеÑто от един път в годината. Приема Ñе, че търÑачките периодично поÑещават Ñтраници, маркирани Ñ \"never\" за да могат да отбележат евентуални неочаквани промени в Ñъдържанието им." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1028 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1086 +msgid "Homepage" +msgstr "Заглавна Ñтраница" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1034 +msgid "Posts" +msgstr "ПоÑтове" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1040 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1104 +msgid "Static pages" +msgstr "Статични Ñтраници" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1046 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1110 +msgid "Categories" +msgstr "Категории" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1052 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "ÐаÑтоÑщ архив за меÑеца (ТрÑбва да е ÑÑŠÑ‰Ð¸Ñ ÐºÐ°Ñ‚Ð¾ на заглавната Ñтраница)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1058 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Стари архиви (ПромÑна Ñамо при Ñ€ÐµÐ´Ð°ÐºÑ†Ð¸Ñ Ð½Ð° Ñтар поÑÑ‚)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1065 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1123 +msgid "Tag pages" +msgstr "Страници на тагове" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1072 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1130 +msgid "Author pages" +msgstr "ÐвторÑки Ñтраници" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1080 +msgid "Priorities" +msgstr "Приоритети" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1092 +msgid "Posts (If auto calculation is disabled)" +msgstr "ПоÑтове (Ðко авто-калкулиране е неактивно)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1098 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Минимален приоритет на поÑтовете (Важи и при активирано авто-калкулиране)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1116 +msgid "Archives" +msgstr "Ðрхив" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1141 +msgid "Update options" +msgstr "ОбновÑване на наÑтройките" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1142 +msgid "Reset options" +msgstr "Връщане на вградените наÑтройки" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:81 +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Генератор" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:81 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:139 +msgid "Sitemap FAQ" +msgstr "ЧеÑто Задавани ВъпроÑи" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-by_BY.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-by_BY.mo new file mode 100644 index 0000000..7a399ab Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-by_BY.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-by_BY.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-by_BY.po new file mode 100644 index 0000000..f0ddc05 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-by_BY.po @@ -0,0 +1,685 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 24948 2007-11-18 16:37:44Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2009-06-07 02:23+0100\n" +"Last-Translator: Arne Brachhold\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" +"X-Poedit-KeywordsList: _e;__\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: C:\\Inetpub\\wwwroot\\wp\\wp-content\\plugins\\sitemap_beta\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +msgid "Comment Count" +msgstr "КолькаÑць каментароў" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "ВыкарыÑтае колькаÑць каментароў да артыкула Ð´Ð»Ñ Ð²Ñ‹Ð»Ñ–Ñ‡ÑÐ½Ð½Ñ Ð¿Ñ€Ñ‹ÑрытÑту" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +msgid "Comment Average" +msgstr "СÑÑ€ÑднÑÑ ÐºÐ¾Ð»ÑŒÐºÐ°Ñць каментароў" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +msgid "Uses the average comment count to calculate the priority" +msgstr "ВыкарыÑтае ÑÑÑ€ÑднÑÑ ÐºÐ¾Ð»ÑŒÐºÐ°Ñць каментароў Ð´Ð»Ñ Ð²Ñ‹Ð»Ñ–Ñ‡ÑÐ½Ð½Ñ Ð¿Ñ€Ñ‹ÑрытÑту" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +msgid "Popularity Contest" +msgstr "ПапулÑрнаÑць дыÑкуÑÑ–Ñ–" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "ВыкарыÑтайце актываваны Убудова папулÑрнаÑці дыÑкуÑій ад Alex King. Гл. Ðалады Ñ– Ð¡Ð°Ð¼Ñ‹Ñ Ð¿Ð°Ð¿ÑƒÐ»ÑÑ€Ð½Ñ‹Ñ Ð·Ð°Ð¿Ñ–ÑÑ‹" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap Generator" +msgstr "Генератар XML-карты Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap" +msgstr "XML-карта Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Премного дзÑкую за ахвÑраванні. Ð’Ñ‹ дапамагаеце мне Ñž продалжении падтрымкі Ñ– раÑпрацоўкі гÑтай убудовы Ñ– іншага вольнага ПÐ!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Hide this notice" +msgstr "Схаваць гÑтую заўвагу" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "ДзÑкую Ð’Ð°Ñ Ð·Ð° выкарыÑтанне гÑтай убудовы! Ð’Ñ‹ ÑžÑталÑвалі Ñго звыш меÑÑца назад. Калі ён працуе Ñ– Ð’Ñ‹ Ð·Ð´Ð°Ð²Ð¾Ð»ÐµÐ½Ñ‹Ñ Ñго вынікамі, вышліце мне хоць бы $1? ÐхвÑраванні дапамогуць мне Ñž падтрымцы Ñ– раÑпрацоўцы гÑтага бÑÑплатнага ПÐ! Ð’Ñдома, без праблем!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +msgid "No thanks, please don't bug me anymore!" +msgstr "Ðе, дзÑкуй. Прашу мÑне больш не турбаваць!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +msgid "XML Sitemap Generator for WordPress" +msgstr "Генератар XML-карты Ñайта Ð´Ð»Ñ WordPress" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +msgid "Configuration updated" +msgstr "ÐšÐ°Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ‹Ñ Ð°Ð±Ð½Ð¾ÑžÐ»ÐµÐ½Ð°Ñ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +msgid "Error while saving options" +msgstr "Памылка пры захаванні параметраў" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +msgid "Pages saved" +msgstr "Старонкі захаваныÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +msgid "Error while saving pages" +msgstr "Памылка пры захаванні Ñтаронак" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2748 +#, php-format +msgid "Robots.txt file saved" +msgstr "Файл Robots.txt захаваны" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2750 +msgid "Error while saving Robots.txt file" +msgstr "Памылка пры захаванні файла Robots.txt" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +msgid "The default configuration was restored." +msgstr "ÐšÐ°Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ‹Ñ Ð¿Ð° змаўчанні адноўленаÑ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +msgid "open" +msgstr "адкрыць" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +msgid "close" +msgstr "зачыніць" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +msgid "click-down and drag to move this box" +msgstr "ÐаціÑніце кнопку мышы Ñ– цÑгнеце Ð´Ð»Ñ Ð¿ÐµÑ€Ð°Ð¼ÑшчÑÐ½Ð½Ñ Ð³Ñтага блока" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +msgid "click to %toggle% this box" +msgstr "ÐаціÑніце Ð´Ð»Ñ %toggle% на гÑты блок" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +msgid "use the arrow keys to move this box" +msgstr "выкарыÑтайце ÑтрÑлкі Ð´Ð»Ñ Ð¿ÐµÑ€Ð°Ð¼ÑшчÑÐ½Ð½Ñ Ð³Ñтага блока" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +msgid ", or press the enter key to %toggle% it" +msgstr ", або націÑніце копку ўвод (enter) Ð´Ð»Ñ %toggle% Ñго" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +msgid "About this Plugin:" +msgstr "Ðб гÑта ўбудове:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +msgid "Plugin Homepage" +msgstr "ХатнÑÑ Ñтаронка ўбудовы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +msgid "Notify List" +msgstr "Ð¡Ð¿Ñ–Ñ Ð½Ð°Ð¿Ð°Ð¼Ñ–Ð½ÐºÑƒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +msgid "Support Forum" +msgstr "Форум Ñ‚Ñхнічнай падтрымкі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +msgid "Donate with PayPal" +msgstr "ÐхвÑраваць праз PayPal" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +msgid "My Amazon Wish List" +msgstr "Мой ÑÐ¿Ñ–Ñ Ð¿Ð°Ð¶Ð°Ð´Ð°Ð½Ð½ÑÑž на Amazon" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_name" +msgstr "Перавёў СÑргей Рывкин" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_url" +msgstr "http://ryvkin.ru" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +msgid "Sitemap Resources:" +msgstr "РÑÑурÑÑ‹ карыт Ñайта:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +msgid "Webmaster Tools" +msgstr "Прылады вÑб-майÑтра" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +msgid "Webmaster Blog" +msgstr "Дзённік вÑб-майÑтра" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +msgid "Site Explorer" +msgstr "ПраглÑд Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +msgid "Search Blog" +msgstr "Шукаць у дзённіку" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +msgid "Sitemaps Protocol" +msgstr "Пратакол выкарыÑÑ‚Ð°Ð½Ð½Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +msgid "Official Sitemaps FAQ" +msgstr "Ðфіцыйны ЧÐВО па картах Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +msgid "My Sitemaps FAQ" +msgstr "Мой ЧÐВО па картах Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +msgid "Recent Donations:" +msgstr "ÐÐ¿Ð¾ÑˆÐ½Ñ–Ñ Ð°Ñ…Ð²Ñраванні:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +msgid "List of the donors" +msgstr "Ð¡Ð¿Ñ–Ñ ÑпонÑараў" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +msgid "Hide this list" +msgstr "Схаваць гÑты ÑпіÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +msgid "Thanks for your support!" +msgstr "ДзÑкуй за Вашу падтрымку!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +msgid "Status" +msgstr "Статут" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Карта Ñайта ÑÑˆÑ‡Ñ Ð½Ðµ пабудаванаÑ. ÐаціÑніце тут Ð´Ð»Ñ ÑтварÑÐ½Ð½Ñ Ñе ўпершыню." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +msgid "Your sitemap was last built on %date%." +msgstr "Ваша карта Ñайта апошні раз была пабудаванаÑ: %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreПачытаць ÑшчÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "Ваша карта Ñайта (ÑціÑнутаÑ) апошні раз была пабудаванаÑ: %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreПачытаць ÑшчÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +msgid "Google was successfully notified about changes." +msgstr "Google быў паÑпÑхова паінфармаваны аб зменах." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "%time% Ñекунд занÑло інфармаванне Google; магчыма, Ð’Ð°Ñ Ð²Ð°Ñ€Ñ‚Ð° адключыць гÑтую функцыю, каб знізіць Ñ‡Ð°Ñ Ð¿Ð°Ð±ÑƒÐ´Ð¾Ð²Ñ‹ карты." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Пры інфармаванні Google адбылаÑÑ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ°. ПаглÑдзець вынік" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOO быў паÑпÑхова паінфармаваны аб зменах." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "%time% Ñекунд занÑло інфармаванне YAHOO; магчыма, Ð’Ð°Ñ Ð²Ð°Ñ€Ñ‚Ð° адключыць гÑтую функцыю, каб знізіць Ñ‡Ð°Ñ Ð¿Ð°Ð±ÑƒÐ´Ð¾Ð²Ñ‹ карты." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Пры інфармаванні YAHOO адбылаÑÑ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ°. ПаглÑдзець вынік" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com быў паÑпÑхова паінфармаваны аб зменах." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "%time% Ñекунд занÑло інфармаванне Ask.com; магчыма, Ð’Ð°Ñ Ð²Ð°Ñ€Ñ‚Ð° адключыць гÑтую функцыю, каб знізіць Ñ‡Ð°Ñ Ð¿Ð°Ð±ÑƒÐ´Ð¾Ð²Ñ‹ карты." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Пры інфармаванні Ask.com адбылаÑÑ Ð¿Ð°Ð¼Ñ‹Ð»ÐºÐ°. ПаглÑдзець вынік" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "ПрацÑÑ Ð¿Ð°Ð±ÑƒÐ´Ð¾Ð²Ñ‹ занÑÑž прыкладна %time% Ñекунд Ñ– выкарыÑтаў %memory% MB памÑці." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +msgid "The building process took about %time% seconds to complete." +msgstr "ПрацÑÑ Ð¿Ð°Ð±ÑƒÐ´Ð¾Ð²Ñ‹ занÑÑž прыкладна %time% Ñекунд." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Утрыманне Вашай карты Ñайта не змÑнÑлаÑÑ Ð·Ð° апошні чаÑ, таму файлы не запіÑваліÑÑ Ñ– Ð¿Ð¾ÑˆÑƒÐºÐ°Ð²Ñ‹Ñ ÑÑ–ÑÑ‚Ñмы не інфармаваліÑÑ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "Ðпошні запуÑк не быў завершаны! Магчыма, Ð’Ñ‹ перавыÑілі ліміты памÑці або чаÑу выкананнÑ. Пачытаць ÑшчÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "Ðпошні раз Ñкрыпт выкарыÑтаў %memused%MB памÑці, ліміт памÑці Вашага Ñервера Ñкладае %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "Ðпошні раз Ñкрыпт працаваў %timeused% Ñекунд, абмежаванне чаÑу на Вашым Ñерверы Ñкладае %timelimit% Ñекунд." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Скрыпт ÑпыніўÑÑ ÐºÐ°Ð»Ñ Ð°Ñ€Ñ‚Ñ‹ÐºÑƒÐ»Ð° нумар %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Калі Ð’Ñ‹ нешта памÑнÑлі на Вашым Ñервре або Ñž дзённіку, Вам неабходна зноўку пабудаваць карту Ñайта уручную." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Калі Ð’Ñ‹ ÑапхнуліÑÑ Ð· ÑкіÑ-небудзь праблемамі Ñž працÑÑе пабудовы, Ð’Ñ‹ можаце ÑкарыÑтацца функцыÑй адладкі Ð´Ð»Ñ Ð°Ñ‚Ñ€Ñ‹Ð¼Ð°Ð½Ð½Ñ Ð´Ð°Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð°Ð¹ інфармацыі." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +msgid "Basic Options" +msgstr "Ð‘Ð°Ð·Ð°Ð²Ñ‹Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +msgid "Sitemap files:" +msgstr "Файлы карты Ñайта:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Learn more" +msgstr "Пачытаць ÑшчÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3049 +msgid "Write a normal XML file (your filename)" +msgstr "ЗапіÑаць звычайны XML файл (Ваша Ñ–Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3055 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "ЗапіÑаць запакаваны XML файл (Ваша Ñ–Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +msgid "Building mode:" +msgstr "РÑжым пабудовы карты:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Пабудуйце зноўку карту Ñайта, калі Ð’Ñ‹ змÑнілі ўтрыманне Вашага дзённіка" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +msgid "Enable manual sitemap building via GET Request" +msgstr "Дазволіць ручную пабудову карты Ñайта з дапамогай запыту GET" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "ГÑта дазволіць Вам абнавіць карту Ñайта, калі знешнÑÑ Ð¿Ñ€Ñ‹Ð»Ð°Ð´Ð° будзе піÑаць у базу WordPress? не выкарыÑтаючы WordPress API. ВыкарыÑтайце наÑтупны URL Ð´Ð»Ñ Ð²Ñ‹ÐºÐ°Ð½Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ñ†ÑÑу: %1 ПаглÑдзіце пратакол (гл. вышÑй) Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²ÐµÑ€ÐºÑ–, ці Ð¿Ð°Ð±ÑƒÐ´Ð°Ð²Ð°Ð½Ð°Ñ ÐºÐ°Ñ€Ñ‚Ð° Ñайта." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +msgid "Update notification:" +msgstr "Ðбнавіць апавÑшчÑнне:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +msgid "Notify Google about updates of your Blog" +msgstr "ÐпавÑÑціць Google аб зменах у Вашым дзённіку" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "РÑгіÑÑ‚Ñ€Ð°Ñ†Ñ‹Ñ Ð½Ðµ патрабуецца, але Ð’Ñ‹ можаце далучыцца да Прыладам вÑб-майÑтра Google Ð´Ð»Ñ Ð¿Ñ€Ð°Ð³Ð»Ñду ÑтатыÑтыкі пошукавых робатаў." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +msgid "Notify Ask.com about updates of your Blog" +msgstr "ÐпавÑÑціць Asc.com аб зменах у Вашым дзённіку" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +msgid "No registration required." +msgstr "РÑгіÑÑ‚Ñ€Ð°Ñ†Ñ‹Ñ Ð½Ðµ патрабуецца." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +msgid "Notify YAHOO about updates of your Blog" +msgstr "ÐпавÑÑціць YAHOO аб зменах у Вашым дзённіку" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +msgid "Your Application ID:" +msgstr "Ваш ідÑнтыфікатар Ð¿Ñ€Ñ‹ÐºÐ»Ð°Ð´Ð°Ð½Ð½Ñ (Application ID):" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "У Ð’Ð°Ñ Ð½Ñма такога ключа?? Запытаеце тут! %s2" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3099 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "ЗмÑніць або Ñтварыць файл %s у дзённіку, Ñкі ўтрымоўвае інфармацыю аб размÑшчÑнні карты Ñайта." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3102 +msgid "File permissions: " +msgstr "Дазволы на доÑтуп да файлаў: " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3107 +msgid "OK, robots.txt is writable." +msgstr "OK, robots.txt адчынены на запіÑ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3109 +msgid "Error, robots.txt is not writable." +msgstr "Памылка, robots.txt не адчынены на запіÑ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3113 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, robots.txt не Ñ–Ñнуе, але каталог адчынены на запіÑ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3115 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Памылка, robots.txt не Ñ–Ñнуе, Ñ– каталог не адчынены на запіÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Advanced options:" +msgstr "ÐŸÐ°ÑˆÑ‹Ñ€Ð°Ð½Ñ‹Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Limit the number of posts in the sitemap:" +msgstr "Ðбмежаваць колькаÑць артыкулаў у карце Ñайта:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Newer posts will be included first" +msgstr "ÐÐ°Ð²ÐµÐ¹ÑˆÑ‹Ñ Ð°Ñ€Ñ‚Ñ‹ÐºÑƒÐ»Ñ‹ будуць ÑƒÐºÐ»ÑŽÑ‡Ð°Ð½Ñ‹Ñ Ð¿ÐµÑ€ÑˆÑ‹Ð¼Ñ–" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "Try to increase the memory limit to:" +msgstr "ПаÑпрабаваць павÑлічыць ліміт памÑці да:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "e.g. \"4M\", \"16M\"" +msgstr "напрыклад, \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "Try to increase the execution time limit to:" +msgstr "ПаÑпрабаваць павÑлічыць абмежаванне чаÑу Ð²Ñ‹ÐºÐ°Ð½Ð°Ð½Ð½Ñ Ð´Ð°:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "у Ñекундах, напрыклад, \"60\" або \"0\" Ð´Ð»Ñ Ð½ÐµÐ°Ð±Ð¼ÐµÐ¶Ð°Ð²Ð°Ð½Ð°Ð³Ð° чаÑу" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Include a XSLT stylesheet:" +msgstr "Уключыць табліцу ÑтылÑÑž XSLT:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Use Default" +msgstr "ВыкарыÑтаць значÑнне па змаўчанні" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Full or relative URL to your .xsl file" +msgstr "Поўны або адноÑны URL да Вашага файла .xsl" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Дазволіць Ñтандартны Ñ€Ñжым MySQL. ВыкарыÑтаць толькі Ñž выпадку памылак MySQL. (Патрабуе нашмат больш памÑці!)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Будаваць карту Ñайта Ñž фонавым працÑÑе (Вам не трÑба чакаць захаванні артыкула)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "Exclude the following posts or pages:" +msgstr "Выключыць наÑÑ‚ÑƒÐ¿Ð½Ñ‹Ñ Ð°Ñ€Ñ‚Ñ‹ÐºÑƒÐ»Ñ‹ або Ñтаронкі:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "List of IDs, separated by comma" +msgstr "Ð¡Ð¿Ñ–Ñ Ñ–Ð´Ñнтыфікатараў (ID), падзеленых коÑкамі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +msgid "Additional pages" +msgstr "Ð”Ð°Ð´Ð°Ñ‚ÐºÐ¾Ð²Ñ‹Ñ Ñтаронкі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Тут Ð’Ñ‹ можаце паказаць файлы або URL, ÑÐºÑ–Ñ Ð¿Ð°Ð²Ñ–Ð½Ð½Ñ‹ быць ÑƒÐºÐ»ÑŽÑ‡Ð°Ð½Ñ‹Ñ Ñž карту Ñайта, але не Ð¿Ñ€Ñ‹Ð½Ð°Ð»ÐµÐ¶Ð½Ñ‹Ñ Ð’Ð°ÑˆÐ°Ð¼Ñƒ дзённіку/WordPress.
        Ðапрыклад,калі Ваш дамен www.foo.com, а Ваш дзённік размешчаны Ñž www.foo.com/blog, Вам можа ÑпатрÑбіцца дадаць хатнюю Ñтаронку з www.foo.com" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +msgid "Note" +msgstr "Заўвага" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Калі Ваш дзённік размешчаны Ñž падкаталогу, Ñ– Ð’Ñ‹ жадаеце дадаць Ñтаронкі, ÑÐºÑ–Ñ Ð·Ð½Ð°Ñ…Ð¾Ð´Ð·Ñцца ВЫШЭЙ у Ñтруктуры каталогаў, Вам ÐЕÐБХОДÐРзмÑÑціць карту Ñайта Ñž каранёвы каталог (Гл. Ñекцыю "РазмÑшчÑнне файла з картай Ñайта" на гÑтай Ñтаронцы)!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +msgid "URL to the page" +msgstr "URL Ñтаронкі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "УвÑдзіце URL гÑтай Ñтаронкі. Прыклады: http://www.foo.com/index.html або www.foo.com/home " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +msgid "Priority" +msgstr "ПрыÑрытÑÑ‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Вылучыце прыÑрытÑÑ‚ гÑтай Ñтаронкі адноÑна іншых Ñтаронак. Ðапрыклад, Ваша Ð³Ð°Ð»Ð¾ÑžÐ½Ð°Ñ Ñтаронка можа мець больш выÑокі прыÑрытÑÑ‚, чым Ñтаронка з інфармацыÑй аб Ñайце." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +msgid "Last Changed" +msgstr "Ðпошні раз змÑнÑлаÑÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "УвÑдзіце дату апошнÑй змены Ñž фармаце YYYY-MM-DD (2005-12-31, напрыклад) (не абавÑзкова)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +msgid "Change Frequency" +msgstr "ЧаÑтата змен" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +msgid "#" +msgstr "â„–" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +msgid "No pages defined." +msgstr "ÐÑма Ñтаронак." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +msgid "Add new page" +msgstr "Дадаць новую Ñтаронку" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +msgid "Post Priority" +msgstr "ПрыÑрытÑÑ‚ артыкула" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Вылучыце, Ñк будзе вылічацца прыÑрытÑÑ‚ кожнага артыкула:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "Do not use automatic priority calculation" +msgstr "Ðе выкарыÑтаць аўтаматычнае вылічÑнне прыÑрытÑту" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "УÑе артыкулы будуць мець аднолькавы прыÑрытÑÑ‚, Ñкі вызначаны Ñž "ПрыÑрытÑтах"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3348 +msgid "Location of your sitemap file" +msgstr "РазмÑшчÑнне Вашага файла з картай Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3353 +msgid "Automatic detection" +msgstr "Ðўтаматычнае азначÑнне" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3357 +msgid "Filename of the sitemap file" +msgstr "Ð†Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° з картай Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +msgid "Detected Path" +msgstr "Ð’Ñ‹Ñўлены шлÑÑ…" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +msgid "Detected URL" +msgstr "Ð’Ñ‹Ñўлены URL" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3365 +msgid "Custom location" +msgstr "КарыÑтацкае размÑшчÑнне" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3369 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "ÐбÑалютны або адноÑны шлÑÑ… да файла з картай Ñайта, уключаючы Ñ–Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3371 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3380 +msgid "Example" +msgstr "Прыклад" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3378 +msgid "Complete URL to the sitemap file, including name." +msgstr "Запоўніце URL да файла з картай Ñайта, уключаючы Ñ–Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +msgid "Sitemap Content" +msgstr "Утрыманне карты Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +msgid "Include homepage" +msgstr "Уключыць хатнюю Ñтаронку" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +msgid "Include posts" +msgstr "Уключыць артыкулы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +msgid "Include static pages" +msgstr "Уключыць ÑÑ‚Ð°Ñ‚Ñ‹Ñ‡Ð½Ñ‹Ñ Ñтаронкі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +msgid "Include categories" +msgstr "Уключыць катÑгорыі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +msgid "Include archives" +msgstr "Уключыць архівы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +msgid "Include tag pages" +msgstr "Уключыць Ñтаронкі пазанак" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +msgid "Include author pages" +msgstr "Уключыць Ñтаронкі аўтараў" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +msgid "Change frequencies" +msgstr "ЗмÑніць чаÑтоты" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Звернеце ўвагу, што значÑнне гÑтай пазнакі лічыцца Ñ€ÑкамендацыÑй Ñ– не з'ÑўлÑецца камандай. Ðават калі Ð¿Ð¾ÑˆÑƒÐºÐ°Ð²Ñ‹Ñ Ñ€Ð¾Ð±Ð°Ñ‚Ñ‹ бÑруць гÑтую інфармацыю да ўвагі Ð´Ð»Ñ Ð¿Ñ€Ñ‹Ð½ÑÑ†Ñ†Ñ Ñ€Ð°ÑˆÑннÑÑž, Ñны могуць аглÑдаць Ñтаронкі, Ð¿Ð°Ð·Ð½Ð°Ñ‡Ð°Ð½Ñ‹Ñ \"раз у гадзіну\" радзей, чым запытана, Ñ– Ñны могуць аглÑдаць Ñтаронкі, Ð¿Ð°Ð·Ð½Ð°Ñ‡Ð°Ð½Ñ‹Ñ Ñк \"раз у год\" гушчару, чым запытана. ТакÑама бывае, што Ð¿Ð¾ÑˆÑƒÐºÐ°Ð²Ñ‹Ñ Ñ€Ð¾Ð±Ð°Ñ‚Ñ‹ аглÑдаюць Ñтаронкі, Ð¿Ð°Ð·Ð½Ð°Ñ‡Ð°Ð½Ñ‹Ñ Ñк \"ніколі\", адзначаючы не Ð¿Ñ€Ð°Ð´ÑƒÐ³Ð»ÐµÐ´Ð¶Ð°Ð½Ñ‹Ñ Ð·Ð¼ÐµÐ½Ñ‹ на гÑтых Ñтаронках." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +msgid "Homepage" +msgstr "Ð“Ð°Ð»Ð¾ÑžÐ½Ð°Ñ Ñтаронка" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +msgid "Posts" +msgstr "Ðртыкулы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +msgid "Static pages" +msgstr "Ð¡Ñ‚Ð°Ñ‚Ñ‹Ñ‡Ð½Ñ‹Ñ Ñтаронкі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +msgid "Categories" +msgstr "КатÑгорыі" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "БÑгучы архіў за гÑты меÑÑц (Павінен быць тым жа, што Ñ– Ð“Ð°Ð»Ð¾ÑžÐ½Ð°Ñ Ñтаронка)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Ð¡Ñ‚Ð°Ñ€Ñ‹Ñ Ð°Ñ€Ñ…Ñ–Ð²Ñ‹ (ЗмÑнÑюцца толькі Ñž выпадку, калі Ð’Ñ‹ Ñ€Ñдагуеце ÑÑ‚Ð°Ñ€Ñ‹Ñ Ð°Ñ€Ñ‚Ñ‹ÐºÑƒÐ»Ñ‹)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +msgid "Tag pages" +msgstr "Старонкі пазанак" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +msgid "Author pages" +msgstr "Старонкі аўтараў" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +msgid "Priorities" +msgstr "ПрыÑрытÑты" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +msgid "Posts (If auto calculation is disabled)" +msgstr "Ðртыкулы (Калі аўтаматычнае вылічÑнне забароненае)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Мінімальны прыÑрытÑÑ‚ артыкула (Ðават калі аўтаматычнае вылічÑнне дазволена)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +msgid "Archives" +msgstr "Ðрхівы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +msgid "Update options" +msgstr "Ðбнавіць параметры" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +msgid "Reset options" +msgstr "Ð’Ñрнуць Ð·Ñ‹Ñ…Ð¾Ð´Ð½Ñ‹Ñ Ð·Ð½Ð°Ñ‡Ñнні" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-cs_CZ.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-cs_CZ.mo new file mode 100644 index 0000000..a53aaea Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-cs_CZ.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-cs_CZ.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-cs_CZ.po new file mode 100644 index 0000000..5636729 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-cs_CZ.po @@ -0,0 +1,604 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 2502 2005-07-03 20:50:38Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2007-11-21 20:50+0100\n" +"Last-Translator: Peter Kahoun \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +msgid "Comment Count" +msgstr "PoÄet komentářů" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "K vypoÄítání priority se využívá poÄet komentářů" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +msgid "Comment Average" +msgstr "PrůmÄ›rný poÄet komentářů" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +msgid "Uses the average comment count to calculate the priority" +msgstr "K vypoÄítání priority se využívá průmÄ›rného poÄtu komentářů" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +msgid "Popularity Contest" +msgstr "Soutěž popularity" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Využívá se pluginu Soutěž popularity (Popularity contest) od Alexe Kinga. Viz Nastavení a NejpopulárnÄ›jší příspÄ›vky" + +msgid "XML-Sitemap Generator" +msgstr "Generátor XML-Sitemapy" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "DÄ›kuji vám mockrát za vaÅ¡e příspÄ›vky. Pomáháte tím pokraÄovat v podpoÅ™e a vývoji tohoto pluginu a dalšího nekomerÄního softwaru!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Hide this notice" +msgstr "Skrýt toto oznámení" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Díky za používání tohoto pluginu! Už je to více než mÄ›síc, co jste ho naistalovali. Pokud funguje k vaší spokojenosti, není hoden alespoň toho jednoho dolaru? Peněžní příspÄ›vky mi pomáhají pokraÄovat v podpoÅ™e a vývoji tohoto nekomerÄního softwaru! OvÅ¡em, žádný problém!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +msgid "No thanks, please don't bug me anymore!" +msgstr "Ne, díky, už mÄ› prosím neotravuj!" + +msgid "XML Sitemap Generator for WordPress" +msgstr "Generátor XML Sitemap" + +msgid "Configuration updated" +msgstr "Nastavení aktualizováno" + +msgid "Error while saving options" +msgstr "PÅ™i ukládání nastavení nastala chyba" + +msgid "Pages saved" +msgstr "Stránka uložena" + +msgid "Error while saving pages" +msgstr "PÅ™i ukládání stránek nastala chyba" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2748 +#, php-format +msgid "Robots.txt file saved" +msgstr "Soubor robots.txt uložen" + +msgid "Error while saving Robots.txt file" +msgstr "PÅ™i ukládání souboru robots.txt nastala chyba" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +msgid "The default configuration was restored." +msgstr "Výchozí nastavení bylo obnoveno." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +msgid "open" +msgstr "otevřít" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +msgid "close" +msgstr "zavřít" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +msgid "click-down and drag to move this box" +msgstr "Podržte tlaÄítko myÅ¡i a táhnÄ›te tento box dolů" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +msgid "click to %toggle% this box" +msgstr "kliknÄ›te k pÅ™epnutí viditelnosti tohoto boxu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +msgid "use the arrow keys to move this box" +msgstr "k pÅ™esunutí tohoto boxu použijte Å¡ipky na klávesnici" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +msgid ", or press the enter key to %toggle% it" +msgstr ", anebo stisknÄ›te Enter k pÅ™epnutí viditelnosti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +msgid "About this Plugin:" +msgstr "O tomto pluginu:" + +msgid "Plugin Homepage" +msgstr "Domovská stránka pluginu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +msgid "Notify List" +msgstr "Oznamovatel novinek" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +msgid "Support Forum" +msgstr "Podpora (fórum)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +msgid "Donate with PayPal" +msgstr "PÅ™ispÄ›jte pÅ™es PayPal" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +msgid "My Amazon Wish List" +msgstr "Můj WishList na Amazonu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_name" +msgstr "Peter \"Kahi\" Kahoun" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_url" +msgstr "http://kahi.cz/wordpress" + +msgid "Sitemap Resources:" +msgstr "Zdroje:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +msgid "Site Explorer" +msgstr "Site Explorer" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +msgid "Search Blog" +msgstr "Search Blog" + +msgid "Sitemaps Protocol" +msgstr "Sitemaps protokol" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +msgid "Official Sitemaps FAQ" +msgstr "Oficiální Sitemaps FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +msgid "My Sitemaps FAQ" +msgstr "Mé Sitemaps FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +msgid "Recent Donations:" +msgstr "Poslední příspÄ›vky:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +msgid "List of the donors" +msgstr "Seznam dárců" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +msgid "Hide this list" +msgstr "Skrýt seznam" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +msgid "Thanks for your support!" +msgstr "Díky za vaÅ¡i podporu!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +msgid "Status" +msgstr "Stav" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Sitemapa jeÅ¡tÄ› nebyla vytvoÅ™ena. KliknÄ›te sem pro první vytvoÅ™ení." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +msgid "Your sitemap was last built on %date%." +msgstr "VaÅ¡e sitemapa byla naposledy aktualizována %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreDozvÄ›dÄ›t se víc" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "VaÅ¡e zazipovaná sitemapa byla naposledy aktualizována %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreDozvÄ›dÄ›t se víc" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +msgid "Google was successfully notified about changes." +msgstr "Google byl úspěšnÄ› upozornÄ›n na zmÄ›ny." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Oznámení Googlu zabralo %time% sekund, možná budete chtít deaktivovat tuto funkci pro snížení potÅ™ebného Äasu k vytváření sitemapy." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Vyskytl se problém pÅ™i oznamování zmÄ›n Googlu. Prohlédnout výsledek" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +msgid "YAHOO was successfully notified about changes." +msgstr "Yahoo byl úspěšnÄ› upozornÄ›n na zmÄ›ny." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Oznámení Yahoo zabralo %time% sekund, možná budete chtít deaktivovat tuto funkci pro snížení potÅ™ebného Äasu k vytváření sitemapy." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Vyskytl se problém pÅ™i oznamování zmÄ›n Yahoo. Prohlédnout výsledek" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com byl úspěšnÄ› upozornÄ›n na zmÄ›ny." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Oznámení Ask.com zabralo %time% sekund, možná budete chtít deaktivovat tuto funkci pro snížení potÅ™ebného Äasu k vytváření sitemapy." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Vyskytl se problém pÅ™i oznamování zmÄ›n Ask.com. Prohlédnout výsledek" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Proces vytváření zabral kolem %time% seconds a spotÅ™eboval %memory% MB pamÄ›ti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +msgid "The building process took about %time% seconds to complete." +msgstr "Proces vytváření zabral kolem %time% sekund." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Obsah vaší sitemapy se nezmÄ›nil od posledního vytváření, takže soubory nebyly aktualizovány a vyhledávaÄe nebyly upozorňovány na zmÄ›ny." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "Poslední bÄ›h neprobÄ›hl do konce! Možná byste mohli navýšit limit pamÄ›ti Äi maximálního Äasu pro PHP skripty. DozvÄ›dÄ›t se víc" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "Poslední známé využití pamÄ›ti bylo %memused%MB, limit vaÅ¡eho serveru je %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "Poslední známý Äas trvání skriptu byl %timeused% sekund, limit vaÅ¡eho serveru je %timelimit% sekund." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Skript byl zastaven kolem příspÄ›vku Äíslo %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Pokud bylo nÄ›co na vaÅ¡em serveru nebo blogu zmÄ›nÄ›no, mÄ›li byste aktualizovat sitemapu ruÄnÄ›." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Pokud zaregistrujete jakékoli problémy pÅ™i procesu aktualizace sitemapy, k získání více informací můžete použít ladící funkci." + +msgid "Basic Options" +msgstr "Základní možnosti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +msgid "Sitemap files:" +msgstr "Soubory sitemapy:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Learn more" +msgstr "DozvÄ›dÄ›t se víc" + +msgid "Write a normal XML file (your filename)" +msgstr "Ukládat normální XML soubor (jméno vaÅ¡eho souboru)" + +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Ukládat komprimovaný (gzip) soubor (jméno vaÅ¡eho souboru + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +msgid "Building mode:" +msgstr "Mód aktualizace:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Aktualizovat sitemapu pÅ™i každé zmÄ›nÄ› v obsahu vaÅ¡eho blogu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +msgid "Enable manual sitemap building via GET Request" +msgstr "Povolit ruÄní aktualizaci sitemapy pomocí GET dotazu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Toto umožní aktualizovat vaÅ¡i sitemapu, pokud do databáze Wordpressu zapíše data nÄ›jaký externí nástroj bez využití WordPress API. Použijte tuto URL ke spuÅ¡tÄ›ní procesu: %1. Prosím zkontrolujte log-soubor výše, jestli byla sitemapa aktualizována úspěšnÄ›." + +msgid "Update notification:" +msgstr "Oznámení o aktualizaci:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +msgid "Notify Google about updates of your Blog" +msgstr "Oznamovat Googlu zmÄ›ny na vaÅ¡em blogu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Registrace není vyžadována, ale může se pÅ™ipojit k Google Webmaster Tools kvůli kontrole statistik návÅ¡tÄ›v vyhledávaÄe." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Oznamovat Ask.com zmÄ›ny na vaÅ¡em blogu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +msgid "No registration required." +msgstr "Registrace není vyžadována." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Oznamovat Yahoo zmÄ›ny na vaÅ¡em blogu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3094 +#, php-format +msgid "No registration required, but you can sign up for the YAHOO Site Explorer to view the crawling progress." +msgstr "Registrace není vyžadována, ale můžete se pÅ™ihlásit do YAHOO Site Explorer kvůli prohlížení postupu návÅ¡tÄ›v vyhledávaÄe." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3099 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "Upravit nebo vytvoÅ™it %s soubor v koÅ™eni blogu, který obsahuje adresu sitemapy." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3102 +msgid "File permissions: " +msgstr "OprávnÄ›ní k souboru:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3107 +msgid "OK, robots.txt is writable." +msgstr "V pořádku, je možné zapisovat do robots.txt." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3109 +msgid "Error, robots.txt is not writable." +msgstr "Chyba, není možné zapisovat do robots.txt." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3113 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "V pořádku, robots.txt neexistuje, ale zápis do adresáře je povolen." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3115 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Chyba, robots.txt neexistuje a zápis do adresáře není povolen." + +msgid "Advanced options:" +msgstr "PokroÄilé možnosti:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Limit the number of posts in the sitemap:" +msgstr "Omezit poÄet příspÄ›vků v sitemapÄ›:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Newer posts will be included first" +msgstr "NovÄ›jší příspÄ›vky budou zahrnuty nejdříve" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "Try to increase the memory limit to:" +msgstr "Zkuste navýšit limit pamÄ›ti na:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "e.g. \"4M\", \"16M\"" +msgstr "napÅ™: \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "Try to increase the execution time limit to:" +msgstr "Zkuste navýšit maximální Äas provádÄ›ní skriptu na:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "v sekundách, napÅ™. \"60\" anebo \"0\" pro nekoneÄno" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Include a XSLT stylesheet:" +msgstr "PÅ™ipojit XSLT stylopis:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Use Default" +msgstr "Použít výchozí" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Full or relative URL to your .xsl file" +msgstr "Adresa k vaÅ¡emu .xsl souboru" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Povolit standardní mód MySQL. Toto používejte jedinÄ› když se zobrazují MySQL chyby - vyžaduje to mnohem víc pamÄ›ti!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Vytvářet sitemapu v pozadí (Tzn. nebudete muset Äekat pÅ™i ukládání příspÄ›vku)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "Exclude the following posts or pages:" +msgstr "VyÅ™adit tyto příspÄ›vky Äi stránky:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "List of IDs, separated by comma" +msgstr "Seznam ID oddÄ›lených Äárkou" + +msgid "Additional pages" +msgstr "Stránky navíc" + +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Zde můžete nastavit URL adresy, které mají být zahrnuty do sitemapy, ale nenáleží k blogu/WordPressu.
        Například, pokud vaÅ¡e doména je www.nÄ›co.cz a váš blog se nachází na www.nÄ›co.cz/blog, možná byste chtÄ›li zahrnout i www.nÄ›co.cz" + +msgid "Note" +msgstr "Poznámka" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Je-li váš blog v podsložce a chcete-li pÅ™idat stránky, které NEJSOU v adresáři blogu (anebo v podadresářích), MUSÃTE umístit vaÅ¡i sitemapu do koÅ™enové složky (Viz sekce "UmístÄ›ní vaší sitemapy" na této stránce)!" + +msgid "URL to the page" +msgstr "URL stránky" + +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Vložte URL (adresu) stránky. Příklady: http://www.nÄ›co.cz/index.html nebo www.nÄ›co.cz/home " + +msgid "Priority" +msgstr "Priorita" + +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Vyberte prioritu stránky relativnÄ› k ostatním stránkám. Například, vaÅ¡e titulní stránka by mÄ›la mít vyšší prioritu než stránka O mnÄ›." + +msgid "Last Changed" +msgstr "Naposledy zmÄ›nÄ›no" + +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Vložte datum poslední zmÄ›ny ve formátu RRRR-MM-DD (například 2007-08-12) (nepovinné)." + +msgid "Change Frequency" +msgstr "Nastavit frekvenci" + +msgid "#" +msgstr "#" + +msgid "No pages defined." +msgstr "Nejsou definovány žádné stránky." + +msgid "Add new page" +msgstr "PÅ™idat novou stránku" + +msgid "Post Priority" +msgstr "Priorita příspÄ›vků" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Vyberte prosím způsob, kterým má být priorita každého z příspÄ›vků vypoÄítávána." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "Do not use automatic priority calculation" +msgstr "Nepoužívat automatický výpoÄet priority" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "VÅ¡echny příspÄ›vky budou mít stejnou prioritu, která je definována v "Prioritách"" + +msgid "Location of your sitemap file" +msgstr "UmístÄ›ní vaší sitemapy" + +msgid "Automatic detection" +msgstr "Automatická detekce" + +msgid "Filename of the sitemap file" +msgstr "Jméno souboru sitemapy" + +msgid "Detected Path" +msgstr "ZjiÅ¡tÄ›ná cesta" + +msgid "Detected URL" +msgstr "ZjiÅ¡tÄ›ná URL" + +msgid "Custom location" +msgstr "Vlastní umístÄ›ní" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Absolutní nebo relativní cesta k sitemapÄ›, vÄetnÄ› jména souboru." + +msgid "Example" +msgstr "Příklad" + +msgid "Complete URL to the sitemap file, including name." +msgstr "Celá URL k sitemapÄ›, vÄetnÄ› jména." + +msgid "Sitemap Content" +msgstr "Obsah sitemapy" + +msgid "Include homepage" +msgstr "Zahrnout titulní stránku" + +msgid "Include posts" +msgstr "Zahrnout příspÄ›vky" + +msgid "Include static pages" +msgstr "Zahrnout statické stránky" + +msgid "Include categories" +msgstr "Zahrnout rubriky" + +msgid "Include archives" +msgstr "Zahrnout archivy" + +msgid "Include tag pages" +msgstr "Zahrnout stránky Å¡títků" + +msgid "Include author pages" +msgstr "Zahrnout stránky autorů" + +msgid "Change frequencies" +msgstr "Nastavení frekvence" + +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Berte prosím na vÄ›domí, že hodnota tohoto Å¡títku je jen zvažována \"jako náznak\", není to příkaz. PÅ™estože vyhledávací roboti berou pÅ™i rozhodování tuto hodnotu na vÄ›domí, pÅ™esto mohou navÅ¡tÄ›vovat stránky oznaÄené jako \"každou hodinu\" ménÄ› Äasto, a také mohou stránky oznaÄené jako \"roÄnÄ›\" navÅ¡tÄ›vovat ÄastÄ›ji. Rovněž je pravdÄ›podobné, že roboti budou naÅ¡tÄ›vovat i stránky oznaÄené jako \"nikdy\" aby se mohli vypořádat s neÄekanými zmÄ›nami na tÄ›chto stránkách." + +msgid "Homepage" +msgstr "Titulní stránka" + +msgid "Posts" +msgstr "PříspÄ›vky" + +msgid "Static pages" +msgstr "Statické stránky" + +msgid "Categories" +msgstr "Rubriky" + +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Stávající archiv tohoto mÄ›síce (MÄ›l by být stejný jako vaÅ¡e titulní stránka)" + +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Starší archivy (MÄ›ní se jen když upravíte starý příspÄ›vek)" + +msgid "Tag pages" +msgstr "Stránky Å¡títků" + +msgid "Author pages" +msgstr "Stránky autorů" + +msgid "Priorities" +msgstr "Priority" + +msgid "Posts (If auto calculation is disabled)" +msgstr "PříspÄ›vky (Když je automatický výpoÄet vypnutý)" + +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Minimální priorita příspÄ›vku (I když je povolený automatický výpoÄet)" + +msgid "Archives" +msgstr "Archivy" + +msgid "Update options" +msgstr "Aktualizovat možnosti" + +msgid "Reset options" +msgstr "Vynulovat možnosti" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-da_DK.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-da_DK.mo new file mode 100644 index 0000000..855c975 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-da_DK.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-da_DK.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-da_DK.po new file mode 100644 index 0000000..7afe243 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-da_DK.po @@ -0,0 +1,594 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 2502 2005-07-03 20:50:38Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2007-11-25 01:16+0100\n" +"Last-Translator: Arne Brachhold \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" + +msgid "Comment Count" +msgstr "Antal kommentar" + +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Brug antallet af kommentarer til indlægget til at udregne prioriteten" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +msgid "Comment Average" +msgstr "Kommentar gennemsnit" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +msgid "Uses the average comment count to calculate the priority" +msgstr "Bruger det gennemsnitlige antal kommentarer til at udregne prioriteten" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +msgid "Popularity Contest" +msgstr "Popularitets konkurrence" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Bruger det aktiveret Popularity Contest Plugin fra Alex King. Se indstillinger og Mest populære indlæg" + +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Mange tak for din donation. Du hjælper mig med at fortsætte support og udvikling af dette plugin og andet gratis software!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Hide this notice" +msgstr "Skjul denne meddelelse" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2606 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Tak fordi du bruger dette plugin! Du installerede dette plugin over en mÃ¥nede siden. Hvis det virker og du er tilfreds, er det sÃ¥ ikke bare en enkel dollar værd? Donationer hjælper mig med at fortsætte support og udvikling af dette gratis stykke software! Selvfølgelig, ingen problem!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2606 +msgid "No thanks, please don't bug me anymore!" +msgstr "Nej tak, lad venligst være med at forstyrre mig igen!" + +msgid "XML Sitemap Generator for WordPress" +msgstr "XML-Sitemap Generator til Wordpress" + +msgid "Configuration updated" +msgstr "Indstillingerne blev opdateret" + +msgid "Error while saving options" +msgstr "Der forekom en fejl da indstilingerne skulle gemmes" + +msgid "Pages saved" +msgstr "Sider gemt" + +msgid "Error while saving pages" +msgstr "Der opstod en fejl da siderne skulle gemmes" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2748 +#, php-format +msgid "Robots.txt file saved" +msgstr "Robots.txt er gemt" + +msgid "Error while saving Robots.txt file" +msgstr "Der forekom en fejl da Robots.txt filen skulle gemmes" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +msgid "The default configuration was restored." +msgstr "Standard indstillingerne er gendannet." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +msgid "open" +msgstr "Ã…ben" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +msgid "close" +msgstr "Luk" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +msgid "click-down and drag to move this box" +msgstr "tryk og træk for at flytte denne boks" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +msgid "click to %toggle% this box" +msgstr "klik for at %toggle% denne boks" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +msgid "use the arrow keys to move this box" +msgstr "brug piltasterne for at flytte denne boks" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +msgid ", or press the enter key to %toggle% it" +msgstr ", eller tryk pÃ¥ enter tasten for at %toggle% den" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +msgid "About this Plugin:" +msgstr "Om dette plugin:" + +msgid "Plugin Homepage" +msgstr "Plugin hjemmeside" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +msgid "Notify List" +msgstr "Informer liste" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +msgid "Support Forum" +msgstr "Support forum" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +msgid "Donate with PayPal" +msgstr "Donere via PayPal" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +msgid "My Amazon Wish List" +msgstr "Min Amazon ønskeliste" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_name" +msgstr "translator_name" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_url" +msgstr "translator_url" + +msgid "Sitemap Resources:" +msgstr "Sitemap ressourcer:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +msgid "Site Explorer" +msgstr "Site Explorer" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +msgid "Search Blog" +msgstr "Search Blog" + +msgid "Sitemaps Protocol" +msgstr "Sitemap protocol" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +msgid "Official Sitemaps FAQ" +msgstr "Officiel Sitemap FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +msgid "My Sitemaps FAQ" +msgstr "Dette Sitemaps FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +msgid "Recent Donations:" +msgstr "Seneste donationer:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +msgid "List of the donors" +msgstr "Liste over donationsgivere" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +msgid "Hide this list" +msgstr "Skjul denne liste" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +msgid "Thanks for your support!" +msgstr "Tak for din support!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +msgid "Status" +msgstr "Status" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Dette Sitemap er ikke bygget endnu. Klik her for at bygge det for første gang." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +msgid "Your sitemap was last built on %date%." +msgstr "Dit sitemap blev sidst bygget den %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreLær mere" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "Dit sitemap (gzipped) blev bygget sidst den %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreLær mere" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +msgid "Google was successfully notified about changes." +msgstr "Google blev informeret korrekt omkring ændringerne." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Det tog %time% sekunder at informerer google, mÃ¥ske skulle du deaktivere denn funktion for at reducerer bygge tiden." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2970 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Der opstod et problem under kommunikationen med Google. Se resultat" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +msgid "YAHOO was successfully notified about changes." +msgstr "Yahoo blev informeret korrekt omkring ændringerne." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Det tog %time% sekunder at informerer Yahoo, mÃ¥ske skulle du deaktivere denn funktion for at reducerer bygge tiden." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2982 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Der opstod et problem under kommunikationen med YAHOO. Se resultat" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com blev informeret korrekt omkring ændringerne." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Det tog %time% sekunder at informerer Ask.com, mÃ¥ske skulle du deaktivere denn funktion for at reducerer bygge tiden." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2994 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Der opstod et problem under kommunikationen med Ask.com. Se resultat" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Bygge processen tog omkring %time% sekunder for at fuldføre og bruge %memory% MB hukommelse." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +msgid "The building process took about %time% seconds to complete." +msgstr "Bygge processen tog omkring %time% sekunder for at fuldføre." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Indholdet af dit sitemap har ikke ændret sig siden sidst. Derfor blev der ikke ikke skrevet til nogle filer og ikke kommunikeret med nogle søgemaskiner." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "Sidste forsøg blev ikke færdigt! MÃ¥ske skal du hæve hukommelses begrænsningen for PHP scripts. Lær mere" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "Det sidst kendte forbrug af hukommelse af dette script var %memused%MB, begrænsningen pÃ¥ din server er %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "Den sidste kendte eksekverings tid for dette script var %timeused% sekunder, begrænsningen pÃ¥ din server er %timelimit% sekunder." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Scriptet stoppede omkring indlæg nummer %lastpost% (+/-100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Hvis du ændre noget pÃ¥ din server eller blog, burde du opdatere dit sitemap manuelt." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Hvis du støder pÃ¥ problemer under bygge processen, kan du bruge debug funktionen for at fÃ¥ flere informationer." + +msgid "Basic Options" +msgstr "Basis indstillinger" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +msgid "Sitemap files:" +msgstr "Sitemap filer:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Learn more" +msgstr "Lær mere" + +msgid "Write a normal XML file (your filename)" +msgstr "Lav en normal XML fil (Dit filnavn)" + +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Lav en gzipped fil (Dit filnavn + .gz" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +msgid "Building mode:" +msgstr "Bygge metode:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Opdater dit sitemap hvis der sker ændringer i indholdet pÃ¥ din blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +msgid "Enable manual sitemap building via GET Request" +msgstr "Aktiverer manuel bygning af sitemap via GET Request" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Dette vil tillade dig at opdatere dit sitemap hvis et eksternt værktøj skrev til Wordpress databasen uden at bruge Wordpress API'et. Brug følgende URL til at starte processen: %1 Tjek venligst logfilen ovenover, for at se om dit sitemap blev bygget korrekt." + +msgid "Update notification:" +msgstr "Opdaterings meddelelser:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +msgid "Notify Google about updates of your Blog" +msgstr "Informer Google om opdateringer pÃ¥ din blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Registrering er ikke pÃ¥krævet, men du kan tilmelde dig Google Webmaster Tools for at tjekke \"crawling\" statistikker." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Informer Ask.com om opdateringer pÃ¥ din blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +msgid "No registration required." +msgstr "Registrering ikke pÃ¥krævet." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Informer Yahoo om opdateringer pÃ¥ din blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3094 +#, php-format +msgid "No registration required, but you can sign up for the YAHOO Site Explorer to view the crawling progress." +msgstr "Registrering er ikke pÃ¥krævet, men du kan tilmelde dig YAHOO Site Explorer for at tjekke \"crawling\" statistikker." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3099 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "Ændre eller opret %s i blog \"root\", som indeholder sitemap placeringen." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3102 +msgid "File permissions: " +msgstr "Fil rettigheder: " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3107 +msgid "OK, robots.txt is writable." +msgstr "OK, robots.txt er skrivbar." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3109 +msgid "Error, robots.txt is not writable." +msgstr "Fejl, robots.txt er ikke skrivbar." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3113 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, robots.txt eksisterer ikke, men mappen er skrivbar." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3115 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Fejl, robots.txt eksisterer ikke og mappen er ikke skrivbar." + +msgid "Advanced options:" +msgstr "Avanceret indstillinger" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Limit the number of posts in the sitemap:" +msgstr "Begræns antallet af indlæg i dit sitemap:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Newer posts will be included first" +msgstr "Nyeste indlæg vil blive inkluderet først" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "Try to increase the memory limit to:" +msgstr "Prøv at forøg hukommelses begrænsningen til:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "e.g. \"4M\", \"16M\"" +msgstr "f.eks. \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "Try to increase the execution time limit to:" +msgstr "Prøv at forøg eksekverings tids begrænsningen til:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "i sekunder, f.eks. \"60\" eller \"0\" for ubegrænset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Include a XSLT stylesheet:" +msgstr "Inkluderer et XSLT stylesheet:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Use Default" +msgstr "Brug standard" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Full or relative URL to your .xsl file" +msgstr "Fuld eller relativ URL til din .xsl fil" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Aktiver MySQL standard mode. Brug kun dette hvis du fÃ¥r MySQL fejl. (Bruger meget mere hukommelse!)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Byg dit sitemap i en baggrundsprocess (Du behøver ikke at vente nÃ¥r du gemmer et indlæg)" + +msgid "Additional pages" +msgstr "Ekstra sider" + +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Her kan du specificere filer og URLs, der skal inkluderes i dit sitemap, som ikke tilhører din side.
        F.eks. hvis dit domæne er www.minside.dk og din side er placeret i en under mappe (www.minside.dk/blog), så vil du måske inkludere www.minside.dk" + +msgid "Note" +msgstr "Note" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Hvis din blog er i en undermappe og du vil tilføje sider, som IKKE er i blog mappen eller en mappe under, SKAL du placerer din sitemap fil i "root mappen" (Se "Stien til din sitemap fil" sektionen på denne side)." + +msgid "URL to the page" +msgstr "URL til siden" + +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Indtast URL'en til siden. F.eks.: http://www.minside.dk/index.html ellerhttp://www.minside.dk/forside" + +msgid "Priority" +msgstr "Prioritet" + +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Vælg sidens prioritet i forhold til de andre sider." + +msgid "Last Changed" +msgstr "Ændret sidst" + +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Indtast datoen for den sidste ændret, som YYYY-MM-DD (F.eks. 2005-12-31) (Valgfri)" + +msgid "Change Frequency" +msgstr "Skift frekvens" + +msgid "#" +msgstr "#" + +msgid "No pages defined." +msgstr "Ingen sider defineret" + +msgid "Add new page" +msgstr "Tilføj ny side" + +msgid "Post Priority" +msgstr "Indlægs prioritet" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Vælg venligst hvordan prioriteten af hver enkelt indlæg skal udregnes:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "Do not use automatic priority calculation" +msgstr "Brug ikke automatisk prioritets udregning" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Alle indlæg vil have den samme prioritet som er defineret under "Prioritet"" + +msgid "Location of your sitemap file" +msgstr "Stien til din sitemap fil" + +msgid "Automatic detection" +msgstr "Find Automatisk " + +msgid "Filename of the sitemap file" +msgstr "Sitemap filnavn" + +msgid "Detected Path" +msgstr "Fundet sti" + +msgid "Detected URL" +msgstr "Fundet URL" + +msgid "Custom location" +msgstr "Brugerdefineret sti" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Absolut eller relativ sti til sitemap filen, inklusiv filnavn." + +msgid "Example" +msgstr "Eksempel" + +msgid "Complete URL to the sitemap file, including name." +msgstr "Fuldstændig URL til sitemap filen, inklusiv filnavn" + +msgid "Sitemap Content" +msgstr "Sitemap indhold" + +msgid "Include homepage" +msgstr "Inkluder hjemmeside" + +msgid "Include posts" +msgstr "Inkluder indlæg" + +msgid "Include static pages" +msgstr "Inkluder statiske sider" + +msgid "Include categories" +msgstr "Inkluder kategorier" + +msgid "Include archives" +msgstr "Inkluder arkiver" + +msgid "Include tag pages" +msgstr "Inkluder tag sider" + +msgid "Include author pages" +msgstr "Inkluder forfatter sider" + +msgid "Change frequencies" +msgstr "Ændre frekvenser" + +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Bemærk venligst at værdien af dette \"tag\" anses for at være et hint og ikke en kommando. Selvom søgemaskine crawlers tager denne information i betrægtning, kan de crawle sider markeret \"pr. time\" færre gange og sider markeret \"årlig\" oftere. Det er også sandsynligt at crawlere periodisk vil crawle sider makeret \"aldrig\", så de kan håndtere uforventet ændringer på disse sider." + +msgid "Homepage" +msgstr "Hjemmeside" + +msgid "Posts" +msgstr "Indlæg" + +msgid "Static pages" +msgstr "Statiske sider" + +msgid "Categories" +msgstr "Kategorier" + +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Arkivet for denne måned (Burde være den som på din hjemmeside)" + +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Ældre arkiver (Ændre sig kun hvis du redigere et gammelt indlæg" + +msgid "Tag pages" +msgstr "Tag sider" + +msgid "Author pages" +msgstr "Forfatter sider" + +msgid "Priorities" +msgstr "Prioriteter" + +msgid "Posts (If auto calculation is disabled)" +msgstr "Indlæg (Hvis auto-udregn er deaktiveret)" + +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Minimum indlægs prioritet (Selvom auto-udregn er aktiveret)" + +msgid "Archives" +msgstr "Arkiver" + +msgid "Update options" +msgstr "Opdater indstillinger" + +msgid "Reset options" +msgstr "Nulstil indstillinger" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-de_DE.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-de_DE.mo new file mode 100644 index 0000000..a79167f Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-de_DE.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-de_DE.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-de_DE.po new file mode 100644 index 0000000..a8c7d13 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-de_DE.po @@ -0,0 +1,1179 @@ +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-05-21 19:54+0100\n" +"PO-Revision-Date: 2014-05-21 19:55+0100\n" +"Last-Translator: Arne Brachhold \n" +"Language-Team: \n" +"Language: de_DE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.6.4\n" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:547 +msgid "Comment Count" +msgstr "Anzahl der Kommentare" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:557 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "" +"Verwendet die Anzahl der Kommentare um die Priorität der Beiträge zu " +"berechnen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:608 +msgid "Comment Average" +msgstr "Durchschnittliche Anzahl der Kommentare" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:618 +msgid "Uses the average comment count to calculate the priority" +msgstr "" +"Verwendet die durchschnittliche Anzahl der Kommentare um die Priorität der " +"Beiträge zu berechnen." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1118 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:778 +msgid "Always" +msgstr "Immer" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1119 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:779 +msgid "Hourly" +msgstr "Stündlich" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1120 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:780 +msgid "Daily" +msgstr "Täglich" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1121 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:781 +msgid "Weekly" +msgstr "Wöchentlich" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1122 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:782 +msgid "Monthly" +msgstr "Monatlich" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1123 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:783 +msgid "Yearly" +msgstr "Jährlich" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1124 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:784 +msgid "Never" +msgstr "Nie" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:233 +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:233 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:260 +msgid "Settings" +msgstr "Einstellungen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:261 +msgid "FAQ" +msgstr "FAQ" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:262 +msgid "Support" +msgstr "Support" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:263 +msgid "Donate" +msgstr "Spenden" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:181 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:663 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Sitemap Generator für WordPress" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:368 +msgid "Configuration updated" +msgstr "Die Konfiguration wurde gespeichert." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:369 +msgid "Error while saving options" +msgstr "Beim Speichern der Seiten ist ein Fehler aufgetreten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:372 +msgid "Pages saved" +msgstr "Ihre Seiten wurden gespeichert." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:373 +msgid "Error while saving pages" +msgstr "Beim Speichern der Seiten ist ein Fehler aufgetreten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:381 +msgid "The default configuration was restored." +msgstr "Die Standard Konfiguration wurde wieder hergestellt." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:391 +msgid "" +"The old files could NOT be deleted. Please use an FTP program and delete " +"them by yourself." +msgstr "" +"Die alten Sitemap-Dateien konnten NICHT gelöscht werden. Bitte verwenden Sie " +"ein FTP-Programm um diese zu löschen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:393 +msgid "The old files were successfully deleted." +msgstr "Die alten Dateien wurden erfolgreich gelöscht." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:430 +msgid "Notify Search Engines about all sitemaps" +msgstr "Suchmaschienen über alle Sitemaps benachrichtigen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:431 +msgid "" +"The plugin is notifying the selected search engines about your main sitemap " +"and all sub-sitemaps. This might take a minute or two." +msgstr "" +"Das plugin benachrichtigt die ausgewählten Suchmaschienen über die Haupt-" +"Sitemap und alle Unter-Sitemaps. Dies kann kurz dauern." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:453 +msgid "All done!" +msgstr "Fertig!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:470 +msgid "Ping was executed, please see below for the result." +msgstr "Ping wurde ausgeführt, das Ergebnis wird unten angezeigt." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:513 +msgid "" +"Thank you very much for your donation. You help me to continue support and " +"development of this plugin and other free software!" +msgstr "" +"Vielen Dank für Deine Spende! Du hilfst mir damit diese kostenlose Software " +"zu unterstützen und weiterzuentwickeln!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:513 +msgid "Hide this notice" +msgstr "Diesen Hinweis verstecken" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:519 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin over a month ago. " +"If it works and you are satisfied with the results, isn't it worth at least " +"a few dollar? Donations help me to continue support and " +"development of this free software! Sure, no problem!" +msgstr "" +"Danke dass Du dieses Plugin benutzt! Du hast dieses Plugin vor mehr als " +"einem Monat installiert. Wenn es funktioniert und zu mit dem Ergebnis " +"zufrieden bist, ist es nicht mindestens ein paar Euro Wert? Spenden helfen mir diese kostenlose Software zu unterstützen " +"und weiterzuentwickeln! Klar, kein Problem! " + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:519 +msgid "Sure, but I already did!" +msgstr "Klar, hab ich schon gemacht!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:519 +msgid "No thanks, please don't bug me anymore!" +msgstr "Nein danke, bitte nicht mehr nerven! " + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:526 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin some time ago. If " +"it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "" +"Danke dass Du dieses Plugin benutzt! Du hast dieses Plugin vor mehr als " +"einem Monat installiert. Wenn es funktioniert und zu mit dem Ergebnis " +"zufrieden bist, würde ich mich freuen wenn Du es bewerten " +"und weiterempfehlen würdest." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:526 +msgid "Don't show this anymore" +msgstr "Diesen Hinweis nicht mehr zeigen" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:679 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here." +msgstr "" +"Es gibt eine Version von %1$s. Version %3$s hier " +"downloaden." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:681 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here automatic upgrade unavailable for this plugin." +msgstr "" +"Es gibt eine Version von %1$s. Version %3$s hier " +"downloaden Automatisches Upgraden ist für dieses Plugin nicht " +"möglich." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:683 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here or upgrade automatically." +msgstr "" +"Es gibt eine Version von %1$s. Version %3$s hier " +"downloaden oder automatisch upgraden." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:691 +#, php-format +msgid "" +"Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "" +"Dein Blog blockiert zur Zeit Suchmaschienen! Unter den Eistellungen zur Privatsphäre lässt sich dies ändern." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:706 +msgid "About this Plugin:" +msgstr "Über dieses Plugin:" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:707 +msgid "Plugin Homepage" +msgstr "Plugin Startseite" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:708 +msgid "Suggest a Feature" +msgstr "Funktion vorschlagen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:709 +msgid "Help / FAQ" +msgstr "Hilfe / FAQ" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:710 +msgid "Notify List" +msgstr "E-Mail bei Update" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:711 +msgid "Support Forum" +msgstr "Hilfe Forum" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:712 +msgid "Report a Bug" +msgstr "Fehler berichten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:714 +msgid "Donate with PayPal" +msgstr "Mit PayPal spenden" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:715 +msgid "My Amazon Wish List" +msgstr "Amazon Wunschliste" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:716 +msgid "translator_name" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:716 +msgid "translator_url" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:719 +msgid "Sitemap Resources:" +msgstr "Sitemap Informationen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:720 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:725 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:721 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:723 +msgid "Search Blog" +msgstr "Search Blog" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:726 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:728 +msgid "Sitemaps Protocol" +msgstr "Sitemaps Protokoll" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:729 +msgid "Official Sitemaps FAQ" +msgstr "Offizielle Sitemaps FAQ" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:730 +msgid "My Sitemaps FAQ" +msgstr "Meine Sitemaps FAQ" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:733 +msgid "Recent Donations:" +msgstr "Aktuelle Spenden:" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:736 +msgid "List of the donors" +msgstr "Liste der Spender" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:738 +msgid "Hide this list" +msgstr "Liste ausblenden" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:741 +msgid "Thanks for your support!" +msgstr "Danke für Deine Unterstützung!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:761 +msgid "Search engines haven't been notified yet" +msgstr "Die Suchmaschinen wurden bisher noch nicht benachrichtigt." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:765 +msgid "Result of the last ping, started on %date%." +msgstr "Ergebnisse des letzten Pins, gestartet am %date%." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:772 +msgid "Recent Support Topics / News" +msgstr "Aktuelle Support-Themen / News" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:776 +msgid "Disable" +msgstr "Deaktivieren" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:794 +msgid "No support topics available or an error occurred while fetching them." +msgstr "" +"Es gibt zur Zeit keine Support-Themen oder es trat ein Fehler beim Abruf auf." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:797 +msgid "" +"Support Topics have been disabled. Enable them to see useful information " +"regarding this plugin. No Ads or Spam!" +msgstr "" +"Support-Themen wurden deaktiviert. Bitte aktivieren um nützliche " +"Informationen zu diesem Plugin zu sehen. Keine Werbung oder Spam!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:797 +msgid "Enable" +msgstr "Aktivieren" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:808 +#, php-format +msgid "" +"There is still a sitemap.xml or sitemap.xml.gz file in your blog directory. " +"Please delete them as no static files are used anymore or try " +"to delete them automatically." +msgstr "" +"Im Blog-Verzeichnis gibt es immer noch eine sitemap.xml oder sitemap.xml.gz " +"Datei. Bitte löschen Sie diese, da sie nicht mehr benötigt werden oder versuchen Sie diese automatisch zu löschen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:811 +#, php-format +msgid "The URL to your sitemap index file is: %s." +msgstr "Die URL zu Ihrer Sitemap Index-Datei lautet: %s." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:814 +msgid "" +"Search engines haven't been notified yet. Write a post to let them know " +"about your sitemap." +msgstr "" +"Die Suchmaschinen wurden bisher noch nicht benachrichtigt. Schreiben Sie " +"einen Beitrag um diese über Ihre Sitemap zu informieren." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:823 +#, php-format +msgid "%s was successfully notified about changes." +msgstr "" +"%s wurde erfolgreich über die Änderungen benachrichtigt." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:826 +msgid "" +"It took %time% seconds to notify %name%, maybe you want to disable this " +"feature to reduce the building time." +msgstr "" +"Es hat %time% Sekunden gedauert %name% zu benachrichtigen. Vielleicht " +"möchtest Du dieses Feature deaktivieren um die Dauer der Sitemap-Generierung " +"zu verkürzen?" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:829 +msgid "" +"There was a problem while notifying %name%. View result" +msgstr "" +"Leider gab es beim Versuch %name% zu benachrichtigen ein Problem. Ergebnis anzeigen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:841 +#, php-format +msgid "" +"If you encounter any problems with your sitemap you can use the debug function to get more information." +msgstr "" +"Falls es beim Generieren der Sitemap Probleme gibt, kannst Du die Debug Funktion verwenden um mehr über die auftretenden Fehler zu " +"erfahren." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:845 +#, php-format +msgid "" +"If you like the plugin, please rate it 5 " +"stars or donate via PayPal! I'm supporting this " +"plugin since over 9 years! Thanks a lot! :)" +msgstr "" +"Wenn Ihnen dieses Plugin gefällt,, bewerten Sie es bitte mit 5 Sternen oder spenden Sie via " +"PayPal! Ich unterstütze dieses Plugin seit über 9 Jahren! Vielen Dank :)" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:853 +msgid "Webserver Configuration" +msgstr "Webserver Konfiguration" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:854 +msgid "" +"Since you are using Nginx as your web-server, please configure the following " +"rewrite rules in case you get 404 Not Found errors for your sitemap:" +msgstr "" +"Da ein NginX Web-Server verwendet wird, müssen eventuell die folgenden " +"Rewrite-Rules konfiguriert werden falls die Sitemap nicht gefunden werden " +"kann:" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:870 +msgid "Basic Options" +msgstr "Allgemeine Einstellungen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:872 +msgid "Update notification:" +msgstr "Benachrichtigung über Änderungen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:872 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:895 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:917 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:929 +msgid "Learn more" +msgstr "Mehr Infos" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:876 +msgid "Notify Google about updates of your Blog" +msgstr "Google über Änderungen benachrichtigen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:877 +#, php-format +msgid "" +"No registration required, but you can join the Google " +"Webmaster Tools to check crawling statistics." +msgstr "" +"Keine Registrierung erforderlich, aber Du kannst Dich bei den Google Webmaster Tools anmelden, um Indexierungs-Statistiken zu " +"Deiner Website zu sehen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:881 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "Bing (vormals MSN Live Search) über Änderungen benachrichtigen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:882 +#, php-format +msgid "" +"No registration required, but you can join the Bing Webmaster " +"Tools to check crawling statistics." +msgstr "" +"Keine Registrierung erforderlich, aber Du kannst Dich bei den Bing Webmaster Tools anmelden, um Indexierungs-Statistiken zu Deiner " +"Website zu sehen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:887 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Die Sitemap zur virtuellen robots hinzufügen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:891 +msgid "" +"The virtual robots.txt generated by WordPress is used. A real robots.txt " +"file must NOT exist in the blog directory!" +msgstr "" +"Es wird die von WordPress generierte virtuelle robots.txt verwendet. Es darf " +"keine robots.txt Datei im Blog Verzeichnis liegen!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:895 +msgid "Advanced options:" +msgstr "Erweiterte Einstellungen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:898 +msgid "Try to increase the memory limit to:" +msgstr "Versuchen, das Speicherlimit zu erhöhen auf: " + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:898 +msgid "e.g. \"4M\", \"16M\"" +msgstr "z.B. \"4M\", \"16M\"" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:901 +msgid "Try to increase the execution time limit to:" +msgstr "Versuchen, das Zeit Limit zu erhöhen auf: " + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:901 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "in Sekunden, z.B. \"60\" oder \"0\" für unendlich" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:906 +msgid "" +"Try to automatically compress the sitemap if the requesting client supports " +"it." +msgstr "" +"Die Sitemap automatisch komprimieren, sofern der Client dies unterstützt." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:908 +msgid "" +"Disable this option if you get garbled content or encoding errors in your " +"sitemap." +msgstr "" +"Deaktivieren Sie diese Option falls Ihre Sitemap kaputt aussieht oder Sie " +"Content-Encoding Fehler erhalten." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:912 +msgid "Include a XSLT stylesheet:" +msgstr "Ein XSLT-Stylesheet einbinden:" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:913 +msgid "Full or relative URL to your .xsl file" +msgstr "Kompletter oder relativer Pfad zur .xsl Datei" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:913 +msgid "Use default" +msgstr "Standard verwenden" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:916 +msgid "Override the base URL of the sitemap:" +msgstr "Die Basis-URL zur Sitemap überschreiben:" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:917 +msgid "" +"Use this if your blog is in a sub-directory, but you want the sitemap be " +"located in the root. Requires .htaccess modification." +msgstr "" +"Benutzen Sie diese Funktion falls Ihr Blog in einem Unterordner installiert " +"ist, Sie die Sitemap aber im Root Ihrer Domain speichern möchten. Benötigt " +"eine Änderung der .htaccess Datei." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:922 +msgid "Include sitemap in HTML format" +msgstr "Einbindung der Sitemap im HTML-Format" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:922 +msgid "(The required PHP XSL Module is not installed)" +msgstr "(Das benötigte PHP XSL Modul ist nicht installiert)" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:928 +msgid "Allow anonymous statistics (no personal information)" +msgstr "" +"Erlaube anonyme Statistiken (es werden keine persönlichen Information " +"gesendet)." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:937 +msgid "Additional pages" +msgstr "Zusätzliche Seiten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:940 +msgid "" +"Here you can specify files or URLs which should be included in the sitemap, " +"but do not belong to your Blog/WordPress.
        For example, if your domain " +"is www.foo.com and your blog is located on www.foo.com/blog you might want " +"to include your homepage at www.foo.com" +msgstr "" +"Hier können Sie zusätzliche Seiten in Form von URLs angeben, welche mit in " +"Ihre Sitemap aufgenommen werden sollen, aber nicht von WordPress erzeugt " +"werden. Falls Sie z.B. Ihre Homepage auf www.beispiel.com haben, Ihr Blog " +"aber unter www.beispiel.com/blog zu erreichen ist, tragen Sie Ihre Homepage " +"als http://www.beispiel.com hier ein." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:942 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1156 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1165 +msgid "Note" +msgstr "Hinweis" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:943 +msgid "" +"If your blog is in a subdirectory and you want to add pages which are NOT in " +"the blog directory or beneath, you MUST place your sitemap file in the root " +"directory (Look at the "Location of your sitemap file" section on " +"this page)!" +msgstr "" +"Falls Dein Blog in einem Unterverzeichnis liegt und Du Seiten hinzufügen " +"möchtest die nicht in deinem Blogverzeichnis oder einem tieferen Verzeichnis " +"liegen, musst Du seine Seite ins Stammverzeichnis legen. (Schau Dir den " +"Punkt "Pfad zur Sitemap Datei" weiter unten an)!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:945 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:984 +msgid "URL to the page" +msgstr "URL zur Seite" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:946 +msgid "" +"Enter the URL to the page. Examples: http://www.foo.com/index.html or www." +"foo.com/home " +msgstr "" +"Geben Sie hier die URL Ihrer Seite an. Beispiele: www.foo.com oder http://" +"www.nic.de/index.html" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:948 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:985 +msgid "Priority" +msgstr "Priorität" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:949 +msgid "" +"Choose the priority of the page relative to the other pages. For example, " +"your homepage might have a higher priority than your imprint." +msgstr "" +"Wählen Sie hier die Priorität der Seite relativ zu den anderen Seiten. Ihre " +"Homepage könnte z.B. eine höhere Priorität besitzen als das Impressum. " + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:951 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:987 +msgid "Last Changed" +msgstr "Letzte Änderung" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:952 +msgid "" +"Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) " +"(optional)." +msgstr "" +"Tragen Sie hier das Datum der letzten Änderung im Format JJJJ-MM-TT (z.B. " +"2005-12-31). Dieses Feld ist optional und muss nicht ausgefüllt werden." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:986 +msgid "Change Frequency" +msgstr "Änderungshäufigkeit" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:988 +msgid "#" +msgstr "#" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:993 +msgid "No pages defined." +msgstr "Bisher keine Seiten eingetragen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:998 +msgid "Add new page" +msgstr "Neue Seite hinzufügen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1004 +msgid "Post Priority" +msgstr "Priorität der Beiträge" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1006 +msgid "Please select how the priority of each post should be calculated:" +msgstr "" +"Bitte wähle wie die Priorität der einzelnen Beiträge berechnet werden soll." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1008 +msgid "Do not use automatic priority calculation" +msgstr "Keine automatische Prioritätsberechung verwenden" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1008 +msgid "" +"All posts will have the same priority which is defined in "" +"Priorities"" +msgstr "" +"Alle Beiträge haben dieselbe Priorität welche unter "Prioritäten" " +"eingestellt ist." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1019 +msgid "Sitemap Content" +msgstr "Inhalt der Sitemap" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1020 +msgid "WordPress standard content" +msgstr "Standard WordPress Inhalte" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1025 +msgid "Include homepage" +msgstr "Startseite" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1031 +msgid "Include posts" +msgstr "Beiträge" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1037 +msgid "Include static pages" +msgstr "Statische Seiten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1043 +msgid "Include categories" +msgstr "Kategorien" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1049 +msgid "Include archives" +msgstr "Archive" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1055 +msgid "Include author pages" +msgstr "Autoren Seiten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1062 +msgid "Include tag pages" +msgstr "Tag Seiten " + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1076 +msgid "Custom taxonomies" +msgstr "Eigene Taxonomies" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1087 +#, php-format +msgid "Include taxonomy pages for %s" +msgstr "Taxonomy Seiten für %s einbinden" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1105 +msgid "Custom post types" +msgstr "Eigene Post-Types" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1116 +#, php-format +msgid "Include custom post type %s" +msgstr "Eigene Post-Types Seiten für %s einbinden" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1128 +msgid "Further options" +msgstr "Weitere Optionen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1133 +msgid "Include the last modification time." +msgstr "Letztes Änderungsdatum mit einbeziehen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1135 +msgid "" +"This is highly recommended and helps the search engines to know when your " +"content has changed. This option affects all sitemap entries." +msgstr "" +"Dies ist äußerst empfohel und hilft den Suchmaschienen zu wissen wann Ihr " +"Inhalt geändert wurde. Diese Einstellungen betrifft alle Einträge der " +"Sitemap." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1142 +msgid "Excluded items" +msgstr "Seiten ausschließen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1144 +msgid "Excluded categories" +msgstr "Kategorien ausschließen" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1152 +msgid "Exclude posts" +msgstr "Beiträge ausschließen" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1154 +msgid "Exclude the following posts or pages:" +msgstr "Folgende Beiträge oder Seiten ausschließen:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1154 +msgid "List of IDs, separated by comma" +msgstr "Liste der IDs, getrennt mit Komma" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1156 +msgid "Child posts won't be excluded automatically!" +msgstr "Unterseiten werden nicht automatisch ausgeschlossen!" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1162 +msgid "Change frequencies" +msgstr "Änderungsfrequenz" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1166 +msgid "" +"Please note that the value of this tag is considered a hint and not a " +"command. Even though search engine crawlers consider this information when " +"making decisions, they may crawl pages marked \"hourly\" less frequently " +"than that, and they may crawl pages marked \"yearly\" more frequently than " +"that. It is also likely that crawlers will periodically crawl pages marked " +"\"never\" so that they can handle unexpected changes to those pages." +msgstr "" +"Bitte beachten Sie dass diese Einstellung nur als Tipp und nicht als " +"Kommando gesehen wird. Suchmaschinen könnten diesen Tipp beachten, müssen " +"sich aber nicht daran halten. Sie können Seiten die als stündlich markiert " +"wurden weniger häufig besuchen und Seiten die als niemals markiert wurden " +"trotzdem überprüfen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1172 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1229 +msgid "Homepage" +msgstr "Startseite" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1178 +msgid "Posts" +msgstr "Beiträge" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1184 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1247 +msgid "Static pages" +msgstr "Statische Seiten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1190 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1253 +msgid "Categories" +msgstr "Kategorien" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1196 +msgid "" +"The current archive of this month (Should be the same like your homepage)" +msgstr "" +"Das Archive des aktuellen Monats (Sollte den gleichen Wert haben wie Ihre " +"Startseite)" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1202 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Archive der vergangenen Monate" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1209 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1266 +msgid "Tag pages" +msgstr "Tag Seiten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1216 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1273 +msgid "Author pages" +msgstr "Autoren Seiten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1224 +msgid "Priorities" +msgstr "Prioritäten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1235 +msgid "Posts (If auto calculation is disabled)" +msgstr "Beiträge (wenn automatische Berechnung deaktiviert wurde)" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1241 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "" +"Minimale Priorität für Beiträge (auch wenn automatische Berechnung aktiviert " +"wurde)" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1259 +msgid "Archives" +msgstr "Archive" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1284 +msgid "Update options" +msgstr "Änderungen speichern" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1285 +msgid "Reset options" +msgstr "Einstellungen zurücksetzten" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:85 +msgid "Your WordPress version is too old for XML Sitemaps." +msgstr "Ihre WordPress-Version ist zu alt für XML-Sitemaps." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:85 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least " +"WordPress %4$s. You are using Wordpress %2$s, which is out-dated and " +"insecure. Please upgrade or go to active plugins and " +"deactivate the Google XML Sitemaps plugin to hide this message. You can " +"download an older version of this plugin from the plugin " +"website." +msgstr "" +"Leider benötigt die aktuelle Version des XML-Sitemaps Plugins mindestens " +"WordPress %4$s. Sie verwenden Wordpress %2$s, was veraltet und eventuell " +"unsicher ist. Bitte aktualisieren Sie WordPress oder gehen Sie zu den aktiven Plugins und deaktivieren Sie das Google XML " +"Sitemaps Plugin um diesen Hinweis zu verbergen. Sie können auch eine ältere " +"Version dieses Plugins auf der plugin website " +"herunterladen." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:95 +msgid "Your PHP version is too old for XML Sitemaps." +msgstr "Ihre PHP-Version ist zu alt für XML-Sitemaps." + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:95 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least PHP " +"%4$s. You are using PHP %2$s, which is out-dated and insecure. Please ask " +"your web host to update your PHP installation or go to active plugins and deactivate the Google XML Sitemaps plugin to hide " +"this message. You can download an older version of this plugin from the plugin website." +msgstr "" +"Leider benötigt die aktuelle Version des XML-Sitemaps Plugins mindestens PHP " +"%4$s. Sie verwenden PHP %2$s, was veraltet und eventuell unsicher ist. Bitte " +"aktualisieren Sie PHP oder gehen Sie zu den aktiven " +"Plugins und deaktivieren Sie das Google XML Sitemaps Plugin um diesen " +"Hinweis zu verbergen. Sie können auch eine ältere Version dieses Plugins auf " +"der plugin website herunterladen." + +#~ msgid "Using this feature will increase build time and memory usage!" +#~ msgstr "" +#~ "Die Verwendung dieser Funktion wird die Erstelldauer sowie den " +#~ "Speicherverbrauch erhöhen!" + +#~ msgid "Popularity Contest" +#~ msgstr "Popularity Contest" + +#~ msgid "" +#~ "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +#~ msgstr "" +#~ "Verwendet das aktivierte Popularity Contest Plugin von " +#~ "Alex King. Siehe Einstellungen und " +#~ "wichtigste Beiträge" + +#~ msgid "Notify Ask.com about updates of your Blog" +#~ msgstr "Ask.com über Änderungen benachrichtigen" + +#~ msgid "No registration required." +#~ msgstr "Keine Registrierung erforderlich" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#~ msgid "" +#~ "Your sitemap is being refreshed at the moment. Depending on your blog " +#~ "size this might take some time!" +#~ msgstr "" +#~ "Die Sietemap wird im Moment neu erzeugt. Abhängig von der Anzahl Ihrer " +#~ "Beiträge kann dies einige Sekunden dauern. " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#~ msgid "" +#~ "Your sitemap will be refreshed in %s seconds. Depending on your blog size " +#~ "this might take some time!" +#~ msgstr "" +#~ "Die Sietemap wird in %s Sekunden neu erzeugt. Abhängig von der Anzahl " +#~ "Ihrer Beiträge kann dies einige Sekunden dauern." + +#~ msgid "open" +#~ msgstr "öffnen" + +#~ msgid "close" +#~ msgstr "schließen" + +#~ msgid "click-down and drag to move this box" +#~ msgstr "Klicken und ziehen um diese Box zu verschieben" + +#~ msgid "click to %toggle% this box" +#~ msgstr "Klicken um diese box zu %toggle%" + +#~ msgid "use the arrow keys to move this box" +#~ msgstr "Benutze die Pfeiltaste um diese box zu verschieben" + +#~ msgid ", or press the enter key to %toggle% it" +#~ msgstr ", oder drück Enter um sie zu %toggle%" + +#~ msgid "Site Explorer" +#~ msgstr "Site Explorer" + +#~ msgid "The sitemap wasn't generated yet." +#~ msgstr "Die Sitemap wurde bisher noch nicht erzeugt." + +#~ msgid "" +#~ "The sitemap wasn't built yet. Click here to build it " +#~ "the first time." +#~ msgstr "" +#~ "Die Sitemap wurde noch nicht erstellt. Klick hier um " +#~ "sie das erste mal zu erstellen." + +#~ msgid "Your sitemap was last built on %date%." +#~ msgstr "" +#~ "Deine Sitemap wurde zuletzt am %date% " +#~ "erstellt." + +#~ msgid "" +#~ "The last build succeeded, but the file was deleted later or can't be " +#~ "accessed anymore. Did you move your blog to another server or domain?" +#~ msgstr "" +#~ "Die letzte Sitemap wurde erzeugt, jedoch kann sie nicht mehr gelesen " +#~ "werden oder wurde gelöscht. Haben Sie das Blog auf einen anderen Server " +#~ "verschoben?" + +#, fuzzy +#~ msgid "" +#~ "There was a problem writing your sitemap file. Make sure the file exists " +#~ "and is writable. Learn more" +#~ msgstr "" +#~ "Leider gab es ein Problem beim Schreiben der Sitemap. Bitte vergewisser " +#~ "dich dass die Datei exisitert und beschreibbar ist. Mehr infoszipped) was last built on %date%." +#~ msgstr "" +#~ "Deine Sitemap (gezippt) wurde zuletzt am %date% erstellt." + +#~ msgid "" +#~ "The last zipped build succeeded, but the file was deleted later or can't " +#~ "be accessed anymore. Did you move your blog to another server or domain?" +#~ msgstr "" +#~ "Die letzte gezippte Sitemap wurde erzeugt, jedoch kann sie nicht mehr " +#~ "gelesen werden oder wurde gelöscht. Haben Sie das Blog auf einen anderen " +#~ "Server verschoben?" + +#, fuzzy +#~ msgid "" +#~ "There was a problem writing your zipped sitemap file. Make sure the file " +#~ "exists and is writable. Learn more" +#~ msgstr "" +#~ "Leider gab es ein Problem beim Schreiben der gezippten Sitemap. Bitte " +#~ "vergewisser dich dass die Datei exisitert und beschreibbar ist. Mehr infossuccessfully notified about changes." +#~ msgstr "" +#~ "Google wurde erfolgreich über die Änderungen benachrichtigt." + +#~ msgid "" +#~ "It took %time% seconds to notify Google, maybe you want to disable this " +#~ "feature to reduce the building time." +#~ msgstr "" +#~ "Es hat %time% Sekunden gedauert Google zu benachrichtigen. Vielleicht " +#~ "möchtest Du dieses Feature deaktivieren um die Dauer der Sitemap-" +#~ "Generierung zu verkürzen?" + +#~ msgid "" +#~ "There was a problem while notifying Google. View result" +#~ msgstr "" +#~ "Leider gab es beim Versuch Google zu benachrichtigen ein Problem. Ergebnis anzeigen" + +#~ msgid "YAHOO was successfully notified about changes." +#~ msgstr "" +#~ "YAHOO wurde erfolgreich über die Änderungen benachrichtigt." + +#~ msgid "" +#~ "It took %time% seconds to notify YAHOO, maybe you want to disable this " +#~ "feature to reduce the building time." +#~ msgstr "" +#~ "Es hat %time% Sekunden gedauert YAHOO zu benachrichtigen. Vielleicht " +#~ "möchtest Du dieses Feature deaktivieren um die Dauer der Sitemap-" +#~ "Generierung zu verkürzen?" + +#~ msgid "" +#~ "There was a problem while notifying YAHOO. View result" +#~ msgstr "" +#~ "Leider gab es beim Versuch YAHOO zu benachrichtigen ein Problem. Ergebnis anzeigen" + +#~ msgid "Ask.com was successfully notified about changes." +#~ msgstr "" +#~ "Ask.com wurde erfolgreich über die Änderungen benachrichtigt." + +#~ msgid "" +#~ "It took %time% seconds to notify Ask.com, maybe you want to disable this " +#~ "feature to reduce the building time." +#~ msgstr "" +#~ "Es hat %time% Sekunden gedauert Ask.com zu benachrichtigen. Vielleicht " +#~ "möchtest Du dieses Feature deaktivieren um die Dauer der Sitemap-" +#~ "Generierung zu verkürzen?" + +#~ msgid "" +#~ "There was a problem while notifying Ask.com. View result" +#~ msgstr "" +#~ "Leider gab es beim Versuch Ask.com zu benachrichtigen ein Problem. Ergebnis anzeigen" + +#~ msgid "" +#~ "The building process took about %time% seconds to complete and " +#~ "used %memory% MB of memory." +#~ msgstr "" +#~ "Die Sitemap-Generierung dauerte %time% sekunden und verwendete " +#~ "%memory% MB Speicher." + +#~ msgid "The building process took about %time% seconds to complete." +#~ msgstr "Die Sitemap-Generierung dauerte %time% sekunden." + +#~ msgid "" +#~ "The content of your sitemap didn't change since the last " +#~ "time so the files were not written and no search engine was pinged." +#~ msgstr "" +#~ "Die Inhalte der Sitemap haben sich nicht geändert seit " +#~ "dem letzten mal, daher wurden keine Dateien geschrieben oder " +#~ "Suchmaschinen informiert." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#~ msgid "" +#~ "The building process might still be active! Reload the page in a few " +#~ "seconds and check if something has changed." +#~ msgstr "" +#~ "Das Erstellen der Sitemap dauert eventuell noch. Laden Sie diese Seite in " +#~ "ein paar Sekunden neu und prüfen Sie ob sich der Status geändert hat." + +#~ msgid "" +#~ "The last run didn't finish! Maybe you can raise the memory or time limit " +#~ "for PHP scripts. Learn more" +#~ msgstr "" +#~ "Die letzte Generierung der Sitemap wurde nicht abgeschlossen. Eventuell " +#~ "hilft es das Speicherlimit für PHP Skripte zu erhöhen. Mehr Infos" + +#~ msgid "" +#~ "The last known memory usage of the script was %memused%MB, the limit of " +#~ "your server is %memlimit%." +#~ msgstr "" +#~ "Der zuletzt bekannte Speicherverauch lag bei %memused%MB, das Limit für " +#~ "PHP Skripte ist %memlimit%." + +#~ msgid "" +#~ "The last known execution time of the script was %timeused% seconds, the " +#~ "limit of your server is %timelimit% seconds." +#~ msgstr "" +#~ "Die zuletzt bekannte Ausührungszeit lag bei %timeused% Sekunden, das " +#~ "Limit für PHP Skripe ist %timelimit% Sekunden." + +#~ msgid "The script stopped around post number %lastpost% (+/- 100)" +#~ msgstr "Das Script hat bei dem %lastpost% Beitrag abgebrochen. (+/- 100)" + +#~ msgid "" +#~ "If you changed something on your server or blog, you should rebuild the sitemap manually." +#~ msgstr "" +#~ "Falls Du etwas am Server oder am Blog geändert hast, solltest Du die " +#~ "Sitemap von Hand neu erstellen." + +#~ msgid "Sitemap files:" +#~ msgstr "Sitemap Dateien:" + +#~ msgid "Write a normal XML file (your filename)" +#~ msgstr "Sitemap als XML Datei erzeugen" + +#~ msgid "Write a gzipped file (your filename + .gz)" +#~ msgstr "Gezippte Sitemap erzeugen (Dateiname + .gz)" + +#~ msgid "Building mode:" +#~ msgstr "Erstellungsmodus:" + +#~ msgid "Rebuild sitemap if you change the content of your blog" +#~ msgstr "Sitemap neu generieren wenn Du den Inhalt Deines Blogs änderst" + +#~ msgid "Enable manual sitemap building via GET Request" +#~ msgstr "Manuelles Generieren der Sitemap über GET Anfrage erlauben" + +#, fuzzy +#~ msgid "" +#~ "This will allow you to refresh your sitemap if an external tool wrote " +#~ "into the WordPress database without using the WordPress API. Use the " +#~ "following URL to start the process: %1 Please check " +#~ "the result box above to see if sitemap was successfully built." +#~ msgstr "" +#~ "Dies erlaubt Dir die Sitemao zu aktualisieren falls ein externes Programm " +#~ "in die WordPress Datenbank geschrieben hat ohne die API zu verwenden. " +#~ "Verwende folgende URL um die Generierung zu starten: %1 Bitte überpüf die Logdatei um zu sehen ob die Generirung erfolgreich " +#~ "war." + +#~ msgid "Notify YAHOO about updates of your Blog" +#~ msgstr "YAHOO über Änderungen benachrichtigen" diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-es_ES.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-es_ES.mo new file mode 100644 index 0000000..cbeb47c Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-es_ES.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-es_ES.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-es_ES.po new file mode 100644 index 0000000..c556850 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-es_ES.po @@ -0,0 +1,1030 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap-es_ES.po 183255 2009-12-15 22:14:37Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: Google Sitemap Generator 3.2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-11-20 22:53+0100\n" +"PO-Revision-Date: 2009-11-23 10:01+0100\n" +"Last-Translator: Omi \n" +"Language-Team: Omi | http://equipajedemano.info/ \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Poedit-Language: Spanish\n" +"X-Poedit-Country: Spain\n" +"X-Poedit-SourceCharset: utf-8\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:525 +msgid "Comment Count" +msgstr "Contador de comentarios" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:537 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Utiliza la cantidad de comentarios en un artículo para calcular su prioridad" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:597 +msgid "Comment Average" +msgstr "Promedio de comentarios" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:609 +msgid "Uses the average comment count to calculate the priority" +msgstr "Utiliza el promedio de comentarios para calcular la prioridad" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:672 +msgid "Popularity Contest" +msgstr "Concurso de popularidad" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:684 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Utilizará el plugin Popularity Contest de Alex King. Revise Configuraciones y Artículos más populares" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1084 +msgid "Always" +msgstr "Siempre" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1085 +msgid "Hourly" +msgstr "Cada hora" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1086 +msgid "Daily" +msgstr "Diariamente" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1087 +msgid "Weekly" +msgstr "Semanalmente" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1088 +msgid "Monthly" +msgstr "Mensualmente" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1089 +msgid "Yearly" +msgstr "Anualmente" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1090 +msgid "Never" +msgstr "Nunca" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:107 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Muchas gracias por su donación. ¡Su ayuda me permite seguir ofreciendo soporte y desarrollo para este plugin y para otros programas gratuitos!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:107 +msgid "Hide this notice" +msgstr "Ocultar esta notificación" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:113 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and you are satisfied with the results, isn't it worth at least a few dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "¡Gracias por utilizar este plugin! Ha pasado más de un mes desde que lo instaló. Si funciona bien y está contento con los resultados, ¿no merece la pena donar aunque sea un euro? Las donaciones me ayudan a seguir ofreciendo soporte y desarrollo para este software gratuito Claro, ¡sin problemas!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:113 +msgid "Sure, but I already did!" +msgstr "Claro, ¡pero ya lo hice!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:113 +msgid "No thanks, please don't bug me anymore!" +msgstr "No gracias. ¡No me moleste más por favor!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:120 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin some time ago. If it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "¡Gracias por utilizar este plugin! Ya ha pasado algún tiempo desde que lo instaló. Si todo funciona correctamente y está satisfecho con su rendimiento, ¿qué tal si vota por el y se lo recomienda a otros? :-)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:120 +msgid "Don't show this anymore" +msgstr "No mostrar esto más" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:132 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "Su sitemap está siendo actualizado en este momento. Dependiendo del tamaño de su blog esto podría llevar algún tiempo." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:134 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "Su sitemap se actualizará en %s segundos. Dependiendo del tamaño de su blog esto podría llevar algún tiempo." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:163 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:480 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Sitemap Generator para WordPress" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:323 +msgid "Configuration updated" +msgstr "Configuración actualizada" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:324 +msgid "Error while saving options" +msgstr "Error mientras se guardaban las opciones" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:326 +msgid "Pages saved" +msgstr "Páginas guardadas" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:327 +msgid "Error while saving pages" +msgstr "Error mientras se guardaban las páginas" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:334 +msgid "The default configuration was restored." +msgstr "Se restauró la configuración por defecto." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:496 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "Hay una nueva versión disponible de %1$s. Descargue la versión %3$s desde aquí." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:498 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "Hay una nueva versión disponible de %1$s. Descargue la versión %3$s desde aquí la actualización automática no está disponible para este plugin." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:500 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "Hay una nueva versión disponbile de %1$s. Descargue la versión %3$s desde aquí o actualice automáticamente." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:508 +#, php-format +msgid "Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "¡Su blog está actualmente bloqueando a los motores de búsqueda! Revise la configuración de privacidad para cambiar esto." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:529 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:546 +msgid "open" +msgstr "abrir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:530 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:547 +msgid "close" +msgstr "cerrar" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:531 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:548 +msgid "click-down and drag to move this box" +msgstr "pinche y arrastre para mover este cuadro" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:532 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:549 +msgid "click to %toggle% this box" +msgstr "pinche para %toggle% este cuadro" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:550 +msgid "use the arrow keys to move this box" +msgstr "utilice las teclas de dirección para mover este cuadro" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:534 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:551 +msgid ", or press the enter key to %toggle% it" +msgstr ", o pulse la tecla Enter para %toggle%lo" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:580 +msgid "About this Plugin:" +msgstr "Acerca de este plugin:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:581 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:181 +msgid "Plugin Homepage" +msgstr "Web principal del plugin" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:582 +msgid "Suggest a Feature" +msgstr "Solicitar nuevas características" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:583 +msgid "Notify List" +msgstr "Lista de notificaciones" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:584 +msgid "Support Forum" +msgstr "Foro de soporte" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:585 +msgid "Report a Bug" +msgstr "Comunicar un fallo" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:587 +msgid "Donate with PayPal" +msgstr "Donar usando PayPal" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:588 +msgid "My Amazon Wish List" +msgstr "Mi lista de deseos en Amazon" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:589 +msgid "translator_name" +msgstr "Traducido por: Omi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:589 +msgid "translator_url" +msgstr "http://equipajedemano.info" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:593 +msgid "Sitemap Resources:" +msgstr "Recursos sobre sitemap:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:594 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:600 +msgid "Webmaster Tools" +msgstr "Herramientas para Webmasters" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:595 +msgid "Webmaster Blog" +msgstr "El blog del Webmaster" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:597 +msgid "Site Explorer" +msgstr "Explorador de sitios" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:598 +msgid "Search Blog" +msgstr "Blog del buscador" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:601 +msgid "Webmaster Center Blog" +msgstr "El blog del Webmaster" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:603 +msgid "Sitemaps Protocol" +msgstr "Protocolo sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:604 +msgid "Official Sitemaps FAQ" +msgstr "FAQ oficial de Sitemaps" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:605 +msgid "My Sitemaps FAQ" +msgstr "Mi FAQ de Sitemaps" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:608 +msgid "Recent Donations:" +msgstr "Donaciones recientes:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:611 +msgid "List of the donors" +msgstr "Listado de donantes" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:613 +msgid "Hide this list" +msgstr "Ocultar esta lista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:616 +msgid "Thanks for your support!" +msgstr "¡Gracias por su colaboración!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:638 +msgid "The sitemap wasn't generated yet." +msgstr "El sitemap todavía no se ha generado." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:641 +msgid "Result of the last build process, started on %date%." +msgstr "Resultados del último proceso de creación (fecha y hora de inicio: %date%)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:650 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "El sitemap todavía no se ha creado. Pinche aquí para crearlo por primera vez" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:656 +msgid "Your sitemap was last built on %date%." +msgstr "Su sitemap se creó por última vez el %date%." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:657 +msgid "The last build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "La última creación se realizó con éxito, pero el archivo ha sido posteriormente borrado o bien no puede accederse a el. ¿Ha movido su blog a otro servidor o dominio?" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:659 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "Hubo un problema creando su archivo sitemap. Asegúrese de que el fichero existe y de que dispone de permisos de escritura. Más información" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:666 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "Su sitemap (comprimido) se creó por última vez el %date%." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:667 +msgid "The last zipped build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "La última creación comprimida se realizó con éxito, pero el archivo ha sido posteriormente borrado o bien no puede accederse a el. ¿Ha movido su blog a otro servidor o dominio?" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:669 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "Hubo un problema creando su archivo sitemap comprimido. Asegúrese de que el fichero existe y de que dispone de permisos de escritura. Más información" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:675 +msgid "Google was successfully notified about changes." +msgstr "Google ha sido correctamente notificado sobre los cambios." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:678 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Llevó %time% segundos notificar a Google. Quizás quiera desactivar esta característica para reducir el tiempo de creación." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:681 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Hubo un problema notificando a Google. Ver resultado" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:687 +msgid "YAHOO was successfully notified about changes." +msgstr "Yahoo ha sido correctamente notificado sobre los cambios." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:690 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Llevó %time% segundos notificar a Yahoo. Quizás quiera desactivar esta característica para reducir el tiempo de creación." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:693 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Hubo un problema notificando a Yahoo. Ver resultado" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:699 +msgid "Bing was successfully notified about changes." +msgstr "Bing ha sido correctamente notificado sobre los cambios." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:702 +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "Llevó %time% segundos notificar a Bing. Quizás quiera desactivar esta característica para reducir el tiempo de creación." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:705 +#, php-format +msgid "There was a problem while notifying Bing. View result" +msgstr "Hubo un problema notificando a Bing. Ver resultado" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:711 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com ha sido correctamente notificado sobre los cambios." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:714 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Llevó %time% segundos notificar a Ask.com. Quizás quiera desactivar esta característica para reducir el tiempo de creación." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:717 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Hubo un problema notificando a Ask.com. Ver resultado" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:725 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "El proceso de creación tardó aproximadamente %time% segundos en completarse y utilizó %memory% MB de memoria." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:727 +msgid "The building process took about %time% seconds to complete." +msgstr "El proceso de creación tardó aproximadamente %time% segundos en completarse." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:731 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "El contenido de su archivo sitemap no ha cambiado desde la última vez, por lo que no se han creado nuevos ficheros ni se ha notificado a los buscadores." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:739 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "¡El proceso de construcción todavía podría estar activo! Recargue la página dentro de unos segundos y compruebe si algo ha cambiado." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:742 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "¡La última ejecución no logró terminar! Quizás pueda elevar la memoria o el límite de tiempo para los scripts de PHP. Más información" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "El último uso de memoria por el script fue de %memused%MB; el límite de su servidor es de %memlimit%MB." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:748 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "El último tiempo de ejecución por el script fue de %timeused% segundos; el límite de su servidor está en %timelimit% segundos." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:752 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "El scripts se detuvo sobre el artículo número %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:755 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Si ha cambiado algo en su servidor o blog debería crear el sitemap manualmente." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:757 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Si encuentra algún problema durante el proceso de creación, puede utilizar la función de depuración para obtener más información." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:764 +msgid "Basic Options" +msgstr "Opciones básicas" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:766 +msgid "Sitemap files:" +msgstr "Archivos sitemap:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:766 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:781 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:801 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:834 +msgid "Learn more" +msgstr "Más información" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:771 +msgid "Write a normal XML file (your filename)" +msgstr "Escribir un fichero XML normal (nombre_fichero)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Escribir un fichero comprimido con gzip (nombre_fichero+.gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:781 +msgid "Building mode:" +msgstr "Modo de creación:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Volver a crear el sitemap si ha cambiado el contenido de su blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:793 +msgid "Enable manual sitemap building via GET Request" +msgstr "Permitir la creación manual del sitemap mediante peticiones GET" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:797 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the result box above to see if sitemap was successfully built." +msgstr "Esto le permitirá actualizar su sitemap si utiliza una herramienta externa, que no usa la API de WordPress, para escribir en la base de datos. Utilice la siguiente URL para iniciar el proceso: %1 Por favor, compruebe el resultado en el cuadro de texto superior para observar si el sitemap se ha creado correctamente." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:801 +msgid "Update notification:" +msgstr "Notificación de actualización" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:805 +msgid "Notify Google about updates of your Blog" +msgstr "Notificar a Google sobre cambios en su blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:806 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "No es necesario registrarse, pero puede unirse a las herramientas de Google para webmasters para revisar sus estadísticas." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:810 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "Notificar a Bing (anteriormente MSN Live Search) sobre cambios en su blog" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:811 +#, php-format +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "No es necesario registrarse, pero puede unirse a las herramientas de Bing para webmasters para revisar sus estadísticas." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:815 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Notificar a Ask.com sobre cambios en su blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:816 +msgid "No registration required." +msgstr "No es necesario registrarse." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:820 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Notificar a Yahoo sobre cambios en su blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:821 +msgid "Your Application ID:" +msgstr "Su Id de aplicación:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "¿No tiene esa identificación? Puede solicitar una aquí! %s2" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:827 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Añadir la URL del sitemap al archivo robots.txt virtual" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:831 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "Se utiliza el archivo robots.txt virtual generado por WordPress. ¡NO debe existir un fichero real robots.txt dentro del directorio del blog!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:834 +msgid "Advanced options:" +msgstr "Opciones avanzadas:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:837 +msgid "Limit the number of posts in the sitemap:" +msgstr "Limitar el número de artículos en el sitemap:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:837 +msgid "Newer posts will be included first" +msgstr "Los artículos más recientes se incluiran primero" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:840 +msgid "Try to increase the memory limit to:" +msgstr "Tratar de incrementar el límite de memoria a:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:840 +msgid "e.g. \"4M\", \"16M\"" +msgstr "ej.: \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:843 +msgid "Try to increase the execution time limit to:" +msgstr "Tratar de incrementar el límite de tiempo de ejecución a:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:843 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "en segundos, ej.: \"60\" o \"0\" para ilimitado" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:847 +msgid "Include a XSLT stylesheet:" +msgstr "Incluir una hoja de estilos XSLT" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:848 +msgid "Full or relative URL to your .xsl file" +msgstr "URL completa o relativa hacia su fichero .xsl" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:848 +msgid "Use default" +msgstr "Utilizar el predeterminado" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:854 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Activar el modo estándar de MySQL. Sólo deberá utilizarlo si está padeciendo errores de MySQL (¡necesita mucha memoria!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:855 +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "Actualice, como mínimo, a WordPress 2.2 para activar el acceso rápido a MySQL" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:862 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Crear el sitemap en segundo plano (así no tendrá que esperar cuando grabe un artículo)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "Actualice, como mínimo, a WordPress 2.1 para activar la creación en segundo plano" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:870 +msgid "Additional pages" +msgstr "Páginas adicionales" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:873 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Aquí puede especificar los ficheros o URLs que deben incluirse en el sitemap, pero que no pertenecen a su blog/WordPress.
        Por ejemplo: si su dominio es www.foo.com y su blog está en www.foo.com/blog, quizás quiera incluir su página de inicio de www.foo.com" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:875 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1097 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1106 +msgid "Note" +msgstr "Nota" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:876 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "¡Si su blog está en un subdirectorio y quiere añadir páginas que NO están en el directorio de su blog o por debajo del mismo, DEBE colocar su fichero sitemap en el directorio raíz (Mire la sección \"Localización de su fichero sitemap\" en esta página)!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:878 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:917 +msgid "URL to the page" +msgstr "URL de la página" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:879 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "URL de la página. Ejemplos: http://www.foo.com/index.html o www.foo.com/home" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:881 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:918 +msgid "Priority" +msgstr "Prioridad" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:882 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Escoja la prioridad relativa de la página comparándola con la de las otras páginas. Por ejemplo, su página de inicio debe tener una mayor prioridad que sus datos personales." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:920 +msgid "Last Changed" +msgstr "Últimos cambios" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:885 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Introduzca la fecha del último cambio como AAAA-MM-DD (por ejemplo: 2005-12-31) (opcional)." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:919 +msgid "Change Frequency" +msgstr "Frecuencia de cambios" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:921 +msgid "#" +msgstr "#" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:926 +msgid "No pages defined." +msgstr "Ninguna página definida" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:931 +msgid "Add new page" +msgstr "Añadir una nueva página" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:936 +msgid "Post Priority" +msgstr "Prioridad del artículo" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:938 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Por favor, seleccione como se calculará la prioridad de cada artículo:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:940 +msgid "Do not use automatic priority calculation" +msgstr "No utilizar el cálculo de prioridad automático" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:940 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Todos los artículos tendrán la misma prioridad según se haya definido en "prioridades"" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:951 +msgid "Location of your sitemap file" +msgstr "Localización de su fichero sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:954 +msgid "Automatic detection" +msgstr "Detección automática" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:958 +msgid "Filename of the sitemap file" +msgstr "Nombre de fichero para el archivo sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:961 +msgid "Detected Path" +msgstr "Ruta detectada" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:961 +msgid "Detected URL" +msgstr "URL detectada" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:966 +msgid "Custom location" +msgstr "Localización automática" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:970 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Ruta absoluta o relativa al fichero sitemap, incluyendo el nombre." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:972 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:981 +msgid "Example" +msgstr "Ejemplo" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:979 +msgid "Complete URL to the sitemap file, including name." +msgstr "URL completa del fichero sitemap, incluyendo el nombre." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:992 +msgid "Sitemap Content" +msgstr "Contenido del sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:998 +msgid "Include homepage" +msgstr "Incluir página principal" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1004 +msgid "Include posts" +msgstr "Incluir artículos" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "Incluir las páginas subsiguientes de los artículos multipágina (¡aumenta el tiempo de creación y el uso de memoria!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1016 +msgid "Include static pages" +msgstr "Incluir páginas estáticas" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1022 +msgid "Include categories" +msgstr "Incluir categorías" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1028 +msgid "Include archives" +msgstr "Incluir archivos" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1035 +msgid "Include tag pages" +msgstr "Incluir páginas de etiquetas" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1051 +#, php-format +msgid "Include taxonomy pages for %s" +msgstr "Incluir páginas de taxonomía para %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1061 +msgid "Include author pages" +msgstr "Incluir páginas de autor" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1065 +msgid "Further options" +msgstr "Más opciones" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1070 +msgid "Include the last modification time." +msgstr "Incluir la fecha de última modificación" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1072 +msgid "This is highly recommended and helps the search engines to know when your content has changed. This option affects all sitemap entries." +msgstr "Altamente recomendado, ya que ayuda a los buscadores a saber cuando ha cambiado el contenido. Esta opción afecta a todas las entradas del sitemap." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1079 +msgid "Excluded items" +msgstr "Elementos excluidos" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1081 +msgid "Excluded categories" +msgstr "Categorías excluidas" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1083 +msgid "Using this feature will increase build time and memory usage!" +msgstr "¡Utilizar esta función incrementará el tiempo de creación y el uso de memoria!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1090 +#, php-format +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "Esta característica requiere de, al menos, WordPress 2.5.1. y Vd. está utilizando la versión %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1093 +msgid "Exclude posts" +msgstr "Artículos excluidos" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1095 +msgid "Exclude the following posts or pages:" +msgstr "Excluir los siguientes artículos o páginas:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1095 +msgid "List of IDs, separated by comma" +msgstr "Indique los ID, separados por coma" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1097 +msgid "Child posts won't be excluded automatically!" +msgstr "¡Los artículos anidados no se excluirán automáticamente!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1103 +msgid "Change frequencies" +msgstr "Frecuencias de cambio" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1107 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Por favor, tenga en cuenta que el valor de esta etiqueta es considerado como un consejo, no como una orden. Incluso aunque los rastreadores tengan en cuenta esto a la hora de decidir, puede que rastreen páginas marcadas como \"cada hora\" con menos frecuencia que la indicada, y puede que rastreen páginas marcadas como \"anualmente\" con más frecuencia que esta. También podría ocurrir que los rastreadores revisen periódicamente páginas marcadas como \"nunca\" por si ha habido cambios inesperados en dichas páginas." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1113 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1170 +msgid "Homepage" +msgstr "Página principal" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1119 +msgid "Posts" +msgstr "Artículos" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1125 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1188 +msgid "Static pages" +msgstr "Páginas estáticas" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1131 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1194 +msgid "Categories" +msgstr "Categorías" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1137 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "El archivo de este mes (Debe ser igual al de su página principal)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1143 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Archivos obsoletos (Sólo cambia si edita un artículo antiguo)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1150 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1207 +msgid "Tag pages" +msgstr "Páginas de etiquetas" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1157 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1214 +msgid "Author pages" +msgstr "Páginas de autor" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1165 +msgid "Priorities" +msgstr "Prioridades" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1176 +msgid "Posts (If auto calculation is disabled)" +msgstr "Artículos (Si el cálculo automático está deshabilitado)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1182 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Prioridad mínima para artículos (Incluso aunque el cálculo automático esté activo)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1200 +msgid "Archives" +msgstr "Archivos" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1225 +msgid "Update options" +msgstr "Grabar cambios" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1226 +msgid "Reset options" +msgstr "Reestablecer configuración" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:95 +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:95 +msgid "XML-Sitemap" +msgstr "Sitemap XML" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:109 +msgid "Settings" +msgstr "Configuraciones" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:110 +msgid "FAQ" +msgstr "FAQ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:111 +msgid "Support" +msgstr "Soporte" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:112 +msgid "Donate" +msgstr "Dona" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:182 +msgid "Sitemap FAQ" +msgstr "FAQ sitemap" + +#~ msgid "Manual location" +#~ msgstr "Localización manual" +#~ msgid "OR" +#~ msgstr "O" +#~ msgid "Error" +#~ msgstr "Error" +#~ msgid "" +#~ "A new page was added. Click on "Save page changes" to save your " +#~ "changes." +#~ msgstr "" +#~ "Una nueva página fue añadida. Haga click en \"Guardar cambios\" para " +#~ "guardar sus cambios." +#~ msgid "" +#~ "The page was deleted. Click on "Save page changes" to save your " +#~ "changes." +#~ msgstr "" +#~ "La página fue borrada. Haga click en \"Guardar cambios\" para guardar sus " +#~ "cambios." +#~ msgid "You changes have been cleared." +#~ msgstr "Sus cambios se han deshecho." +#~ msgid "Manual rebuild" +#~ msgstr "Reconstrucción manual" +#~ msgid "" +#~ "If you want to build the sitemap without editing a post, click on here!" +#~ msgstr "" +#~ "Si quieres construir el sitemap sin editar ningún artículo, ¡pulse aquí!" +#~ msgid "Rebuild Sitemap" +#~ msgstr "Reconstruir Sitemap" +#~ msgid "Save page changes" +#~ msgstr "Guardar los cambios de la página" +#~ msgid "Undo all page changes" +#~ msgstr "Deshacer todos los cambios de la página" +#~ msgid "Delete marked page" +#~ msgstr "Borrar página marcada" +#~ msgid "" +#~ "Enable automatic priority calculation for posts based on comment count" +#~ msgstr "" +#~ "Activar cálculo automático de prioridades para artículos basándose en el " +#~ "número de comentarios" +#~ msgid "Write debug comments" +#~ msgstr "Escribir comentarios de depuración" +#~ msgid "Auto-Ping Google Sitemaps" +#~ msgstr "Ping automático a Google Sitemaps" +#~ msgid "This option will automatically tell Google about changes." +#~ msgstr "" +#~ "Esta opción indicará automáticamente a Google que ha habido cambios." +#~ msgid "Includings" +#~ msgstr "Inclusiones" +#~ msgid "Informations and support" +#~ msgstr "Información y soporte" +#~ msgid "" +#~ "Check %s for updates and comment there if you have any problems / " +#~ "questions / suggestions." +#~ msgstr "" +#~ "Compruebe %s para actualizaciones, comentarios, problemas, cuestiones y " +#~ "sugerencias." +#~ msgid "URL:" +#~ msgstr "URL:" +#~ msgid "Path:" +#~ msgstr "Ruta:" +#~ msgid "Could not write into %s" +#~ msgstr "No puedo escribir en %s" +#~ msgid "Successfully built sitemap file:" +#~ msgstr "Fichero sitemap correctamente construido:" +#~ msgid "Successfully built gzipped sitemap file:" +#~ msgstr "Fichero sitemap comprimido correctamente construido:" +#~ msgid "Could not ping to Google at %s" +#~ msgstr "No pude hacer ping a Google en %s" +#~ msgid "Successfully pinged Google at %s" +#~ msgstr "Ping a Google realizado correctamente en %s" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fi_FI.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fi_FI.mo new file mode 100644 index 0000000..955b677 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fi_FI.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fi_FI.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fi_FI.po new file mode 100644 index 0000000..97932ad --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fi_FI.po @@ -0,0 +1,1005 @@ +msgid "" +msgstr "" +"Project-Id-Version: Sitemaps for WordPress\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-12-23 10:32+0800\n" +"PO-Revision-Date: \n" +"Last-Translator: Olli Jarva \n" +"Language-Team: Olli Jarva \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Finnish\n" +"X-Poedit-Country: FINLAND\n" +"X-Poedit-SourceCharset: utf-8\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:642 +msgid "Comment Count" +msgstr "Kommenttien lukumäärä" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:654 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Käytetään kommenttien määrää prioriteetin laskemiseen" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:714 +msgid "Comment Average" +msgstr "Kommenttien keskiarvo" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:726 +msgid "Uses the average comment count to calculate the priority" +msgstr "Käytetään keskimääräistä kommenttien määrää prioriteetin laskemiseen" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:789 +msgid "Popularity Contest" +msgstr "Suosituimmuuskilpailu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:801 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Käyttää aktivoitua Popularity Contest Plugin-lisäosaa, jonka on tehnyt Alex King. Katso asetukset ja suosituimmat merkinnät" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1118 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1209 +msgid "Always" +msgstr "Aina" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1119 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1210 +msgid "Hourly" +msgstr "Tunnittain" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1120 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1211 +msgid "Daily" +msgstr "Päivittäin" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1212 +msgid "Weekly" +msgstr "Viikottain" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1122 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1213 +msgid "Monthly" +msgstr "Kuukausittain" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1123 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1214 +msgid "Yearly" +msgstr "Vuosittain" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1215 +msgid "Never" +msgstr "Ei ikinä" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Kiitos lahjoituksesta! Autat tämän lisäosan ja muiden vapaiden ohjelmien tukemisessa ja kehittämisessä!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Hide this notice" +msgstr "Piilota tämä huomautus" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Kiitos lisäosan käyttämisestä! Olet asentanut lisäosan yli kuukausi sitten. Jos se toimii ja olet tyytyväinen tuloksiin, eikö se ole edes yhden dollarin arvoinen? Lahjoitukset auttavat tämän vapaan ohjelman kehittämisessä! Toki, ei ongelmaa!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +msgid "No thanks, please don't bug me anymore!" +msgstr "Ei kiitos, älä häiritse minua enää!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:119 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "Sivustokarttaa päivitetään. Blogin koosta riippuen päivittäminen voi kestää jonkin aikaa." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:121 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "Sivustokartta päivitetään %s sekunnin kuluttua. Blogin koosta riippuen päivittäminen voi kestää jonkin aikaa." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:146 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:441 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML-sivustokarttojen luontityökalu WordPressiin" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:278 +msgid "Configuration updated" +msgstr "Asetukset päivitetty" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:279 +msgid "Error while saving options" +msgstr "Virhe asetusten tallentamisessa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:281 +msgid "Pages saved" +msgstr "Sivut tallennettu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:282 +msgid "Error while saving pages" +msgstr "Virhe sivujen tallentamisessa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2748 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:286 +#, php-format +msgid "Robots.txt file saved" +msgstr "Robots.txt tallennettu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2750 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:288 +msgid "Error while saving Robots.txt file" +msgstr "Virhe robots.txt:n tallentamisessa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:297 +msgid "The default configuration was restored." +msgstr "Oletusasetukset on palautettu." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:454 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "Uusi versio (%1$s) on saatavilla. Lataa versio %3$s." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:456 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "Uusi versio (%1$s) on saatavilla. Lataa versio %3$s. Automaattinen päivitys ei ole käytössä tälle lisäosalle." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:458 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "Uusi versio (%1$s) on saatavilla. Lataa versio %3$s tai päivitä automaattisesti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:481 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:498 +msgid "open" +msgstr "avaa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:482 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:499 +msgid "close" +msgstr "sulje" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:483 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:500 +msgid "click-down and drag to move this box" +msgstr "liikuta tätä laatikkoa vetämällä ja pudottamalla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:484 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:501 +msgid "click to %toggle% this box" +msgstr "klikkaa %toggle% laatikko" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:485 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:502 +msgid "use the arrow keys to move this box" +msgstr "käytä nuolinäppäimiä liikkumiseen" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:486 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:503 +msgid ", or press the enter key to %toggle% it" +msgstr "tai paina enter-näppäintä vaihtaaksesi (%toggle%)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:521 +msgid "About this Plugin:" +msgstr "Tietoja lisäosasta:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:522 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:138 +msgid "Plugin Homepage" +msgstr "Lisäosan kotisivu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:523 +msgid "Suggest a Feature" +msgstr "Ehdota ominaisuutta" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:524 +msgid "Notify List" +msgstr "Tiedotuslista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:525 +msgid "Support Forum" +msgstr "Tukifoorumit" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:526 +msgid "Report a Bug" +msgstr "Raportoi virhe" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:528 +msgid "Donate with PayPal" +msgstr "Lahjoita PayPalilla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:529 +msgid "My Amazon Wish List" +msgstr "Amazonin toivelista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:530 +msgid "translator_name" +msgstr "translator_name" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:530 +msgid "translator_url" +msgstr "translator_url" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +msgid "Sitemap Resources:" +msgstr "Sivustokarttaresurssit:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:534 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:540 +msgid "Webmaster Tools" +msgstr "Ylläpitäjän työkalut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:535 +msgid "Webmaster Blog" +msgstr "Ylläpitäjän blogi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:537 +msgid "Site Explorer" +msgstr "Sivustoselain" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:538 +msgid "Search Blog" +msgstr "Hakukoneblogi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:541 +msgid "Webmaster Center Blog" +msgstr "Ylläpitäjäkeskuksen blogi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:543 +msgid "Sitemaps Protocol" +msgstr "Sivustokartta-protokolla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:544 +msgid "Official Sitemaps FAQ" +msgstr "Virallinen sivustokartta-FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:545 +msgid "My Sitemaps FAQ" +msgstr "Sivustokartta-FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:548 +msgid "Recent Donations:" +msgstr "Äskettäin lahjoittaneet:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:552 +msgid "List of the donors" +msgstr "Lahjoittajalista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:554 +msgid "Hide this list" +msgstr "Piilota tämä lista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:557 +msgid "Thanks for your support!" +msgstr "Kiitos tuestasi!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:575 +msgid "Status" +msgstr "Tila" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:583 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Sivustokarttaa ei ole luotu. Luo sivustokartta ensimmäisen kerran." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:589 +msgid "Your sitemap was last built on %date%." +msgstr "Sivustokartta on päivitetty edellisen kerran %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:591 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreLue lisää" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:598 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "Sivustokartta (pakattu) on päivitetty edellisen kerran %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:600 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreLue lisääsuccessfully notified
        about changes." +msgstr "Googlea tiedotettiin onnistuneesti päivityksistä." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:609 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Kesti %time% sekuntia huomauttaa Googlea päivityksistä. Saatat haluta poistaa käytöstä tämän ominaisuuden nopeuttaaksesi sivustokartan luomista." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:612 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Virhe Googlen huomauttamisessa. Katso tulokset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:618 +msgid "YAHOO was successfully notified about changes." +msgstr "Yahoota tiedotettiin onnistuneesti päivityksistä." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:621 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Kesti %time% sekuntia huomauttaa Yahoota päivityksistä. Saatat haluta poistaa käytöstä tämän ominaisuuden nopeuttaaksesi sivustokartan luomista." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:624 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Virhe Yahoon huomauttamisessa. Katso tulokset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3097 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:630 +msgid "MSN was successfully notified about changes." +msgstr "MSN:ää tiedotettiin onnistuneesti päivityksistä." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3100 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:633 +msgid "It took %time% seconds to notify MSN.com, maybe you want to disable this feature to reduce the building time." +msgstr "Kesti %time% sekuntia huomauttaa MSN.comia päivityksistä. Saatat haluta poistaa käytöstä tämän ominaisuuden nopeuttaaksesi sivustokartan luomista." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3103 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:636 +#, php-format +msgid "There was a problem while notifying MSN.com. View result" +msgstr "Virhe MSN.comin huomauttamisessa. Katso tulokset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:642 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.comia tiedotettiin onnistuneesti päivityksistä." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:645 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Kesti %time% sekuntia huomauttaa Ask.comia päivityksistä. Saatat haluta poistaa käytöstä tämän ominaisuuden nopeuttaaksesi sivustokartan luomista." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:648 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Virhe Ask.comin huomauttamisessa. Katso tulokset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:656 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Luominen kesti noin %time% sekuntia ja käytti %memory% MB muistia." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:658 +msgid "The building process took about %time% seconds to complete." +msgstr "Luominen kesti noin %time% sekuntia." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:662 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Sivustokartan sisältö ei vaihtunut edellisestä päivityksestä, joten tiedostoja ei kirjoitettu ja hakukoneita ei huomautettu päivityksistä." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:670 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "Luomisprosessi saattaa olla yhä aktiivinen! Lataa sivu uudelleen muutaman sekunnin kuluttua." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:673 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "Edellinen päivitys ei valmistunut! Muisti- tai aikarajoitusten kasvattaminen saattaa auttaa. Lue lisää" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:675 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "Edellinen tunnettu muistin käyttö oli %memused%MB, palvelimen rajoitus on %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:679 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "Edellinen tunnettu ajoaika oli %timeused% sekuntia, palvelimen rajoitus on %timelimit% sekuntia." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:683 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Ohjelma lopetti merkinnässä numero %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:686 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Jos jotain on muuttunut palvelimella tai blogissa, saatat haluta luoda sivustokartan uudelleen manuaalisesti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:688 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Jos sivustokartan luomisprosessissa oli ongelmia, voit käyttää virheenetsintätilaa lisätietojen saamiseksi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:695 +msgid "Basic Options" +msgstr "Perusasetukset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:697 +msgid "Sitemap files:" +msgstr "Sivustokarttatiedostot:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:697 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:712 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:732 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:765 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:782 +msgid "Learn more" +msgstr "Lue lisää" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3049 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:702 +msgid "Write a normal XML file (your filename)" +msgstr "Luo normaali XML-tiedosto (tiedostonimi)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3055 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:708 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Luo pakattu (gzip) tiedosto (tiedostonimi + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:712 +msgid "Building mode:" +msgstr "Luomisasetukset:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:717 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Luo sivustokartta uudelleen, jos blogin sisältöä on muutettu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +msgid "Enable manual sitemap building via GET Request" +msgstr "Salli manuaalinen sivustokartan luominen GET-pyynnöllä" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:728 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Tämä sallii sivustokartan päivittämisen, jos työkalu kirjoittaa WordPressin tietokantaan käyttämättä WordPressin API:a. Käytä seuraavaa osoitetta päivittämiseen: %1 . Tarkista lokitiedostosta, päivitettiinkö sivustokartta onnistuneesti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:732 +msgid "Update notification:" +msgstr "Päivityshuomautukset:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:736 +msgid "Notify Google about updates of your Blog" +msgstr "Ilmoita Googlelle päivityksistä blogissa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:737 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Rekisteröintiä ei vaadita, mutta Googlen verkkoylläpitäjän työkalut kertovat tietoja sivuston indeksoinnista." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3209 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:741 +msgid "Notify MSN Live Search about updates of your Blog" +msgstr "Ilmoita MSN Live Searchille päivityksistä blogissa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3210 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:742 +#, php-format +msgid "No registration required, but you can join the MSN Live Webmaster Tools to check crawling statistics." +msgstr "Rekisteröintiä ei vaadita, mutta MSN Liven verkkoylläpitäjän työkalut kertovat tietoja sivuston indeksoinnista." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:746 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Ilmoita Ask.comille päivityksistä blogissa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:747 +msgid "No registration required." +msgstr "Rekisteröintiä ei vaadita" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:751 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Ilmoita Yahoolle päivityksistä blogissa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:752 +msgid "Your Application ID:" +msgstr "ID:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:753 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "Ei avainta? Hae omasi täältä! %s2" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3099 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:760 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "Muokkaa tai luo tiedosto %s blogin juurihakemistoon" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3102 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:763 +msgid "File permissions: " +msgstr "Tiedoston oikeudet:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3107 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:768 +msgid "OK, robots.txt is writable." +msgstr "OK, robots.txt:hen on kirjoitusoikeudet." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3109 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:770 +msgid "Error, robots.txt is not writable." +msgstr "Virhe: robots.txt-tiedostoon ei voi kirjoittaa." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3113 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:774 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "Ok, robots.txt:tä ei ole ja kansioon voi kirjoittaa." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3115 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:776 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Virhe: robots.txt:tä ei ole ja kansioon ei voi kirjoittaa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:782 +msgid "Advanced options:" +msgstr "Lisäasetukset:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:785 +msgid "Limit the number of posts in the sitemap:" +msgstr "Rajoita sivustokartan merkintöjen lukumäärää:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:785 +msgid "Newer posts will be included first" +msgstr "Uusimmat merkinnät listataan ensimmäisinä" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:788 +msgid "Try to increase the memory limit to:" +msgstr "Yritä lisätä muistirajoitusta:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:788 +msgid "e.g. \"4M\", \"16M\"" +msgstr "esim. \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Try to increase the execution time limit to:" +msgstr "Yritä lisätä ajoajan rajoitusta:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "sekunneissa, esim. \"60\" tai \"0\" rajoittamattomaan" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:795 +msgid "Include a XSLT stylesheet:" +msgstr "Ota mukaan XSLT-tyylitiedosto:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:796 +msgid "Full or relative URL to your .xsl file" +msgstr "Kokonainen tai suhteellinen .xsl-tiedoston URL" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:796 +msgid "Use default" +msgstr "Käytä oletuksia" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:801 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Ota käyttöön MySQL:n standarditila. Käytä tätä vain jos saat MySQL-virheitä (tarvitsee huomattavasti enemmän muistia)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:807 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Luo sivustokartta taustaprosessissa (Ei viiveitä merkintöjä luodessa)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:814 +msgid "Additional pages" +msgstr "Lisäsivut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:817 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Voit määrittää tiedostot tai osoitteet jotka lisätään sivustokarttaan, mutta jotka eivät ole WordPressissä.
        Esimerkiksi jos domain on www.example.com ja blogi on osoitteessa www.example.com/blog, saatat haluta lisätä etusivun www.example.com sivustokarttaan" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:819 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:998 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1021 +msgid "Note" +msgstr "Huom" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:820 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Jos blogi on alihakemistossa ja haluat lisätä sivuja jotka EIVÄT ole blogin hakemistossa tai alikansioissa, sivustokartta TÄYTYY laittaa juurihakemistoon. Katso "Sivustokartan sijainti"-osiota tällä sivulla." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:861 +msgid "URL to the page" +msgstr "Sivun URL" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:823 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Kirjoita sivun osoite. Esimerkiksi http://example.com/index.html tai www.example.com/home" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:825 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:862 +msgid "Priority" +msgstr "Prioriteetti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:826 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Valitse prioriteetti suhteessa muihin sivuihin. Esimerkiksi etusivu voi olla korkeammalla prioriteetilla kuin vanhat arkistosivut." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:828 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:864 +msgid "Last Changed" +msgstr "Viimeinen muutos" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:829 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Kirjoita edellisen muutoksen päiväys muodossa YYYY-MM-DD (esim. 2009-05-13) (ei pakollinen)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "Change Frequency" +msgstr "Muutostiheys" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:865 +msgid "#" +msgstr "#" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:870 +msgid "No pages defined." +msgstr "Ei sivuja määritetty." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:875 +msgid "Add new page" +msgstr "Lisää uusi sivu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:880 +msgid "Post Priority" +msgstr "Merkinnän prioriteetti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:882 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Valitse, miten merkintöjen prioriteetti lasketaan:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:884 +msgid "Do not use automatic priority calculation" +msgstr "Älä käytä automaattista prioriteetin laskemista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:884 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Kaikilla merkinnöillä on prioriteetit-kohdassa määritetty prioriteetti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3348 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:895 +msgid "Location of your sitemap file" +msgstr "Sivustokartan sijainti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3353 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:898 +msgid "Automatic detection" +msgstr "Automaattinen tunnistus" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3357 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:902 +msgid "Filename of the sitemap file" +msgstr "Sivustokartan tiedostonimi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:905 +msgid "Detected Path" +msgstr "Tunnistettu polku" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:905 +msgid "Detected URL" +msgstr "Tunnistettu URL" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3365 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:910 +msgid "Custom location" +msgstr "Muokattu sijainti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3369 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:914 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Absoluuttinen tai suhteellinen sivustokartan osoite, myös tiedostonimi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3371 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3380 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:925 +msgid "Example" +msgstr "Esimerkki" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:923 +msgid "Complete URL to the sitemap file, including name." +msgstr "Koko URL sivustokarttatiedostoon, myös nimi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:936 +msgid "Sitemap Content" +msgstr "Sivustokartan sisältö" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:942 +msgid "Include homepage" +msgstr "Ota mukaan etusivu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:948 +msgid "Include posts" +msgstr "Ota mukaan merkinnät" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:911 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:954 +msgid "Include following pages of multi-page posts (<!--nextpage-->)" +msgstr "Ota mukaan kaikki sivut monisivuisista merkinnöistä (<!--nextpage-->)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:960 +msgid "Include static pages" +msgstr "Ota mukaan staattiset sivut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:966 +msgid "Include categories" +msgstr "Ota mukaan luokat" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:972 +msgid "Include archives" +msgstr "Ota mukaan arkistosivut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:979 +msgid "Include tag pages" +msgstr "Ota mukaan avainsanasivut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:986 +msgid "Include author pages" +msgstr "Ota mukaan tekijäsivut" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:994 +msgid "Excluded items" +msgstr "Jätä huomiotta" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:996 +msgid "Excluded categories" +msgstr "Jätä huomiotta luokkia" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:998 +msgid "Using this feature will increase build time and memory usage!" +msgstr "Tämän ominaisuuden käyttö lisää luomisaikaa ja muistinkäyttöä!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1005 +#, php-format +msgid "This feature requires at least WordPress 2.5, you are using %s" +msgstr "Ominaisuus vaatii vähintään WordPress 2.5:n, sinulla on %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1008 +msgid "Exclude posts" +msgstr "Jätä huomiotta merkintöjä" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +msgid "Exclude the following posts or pages:" +msgstr "Jätä huomiotta seuraavat merkinnät tai sivut:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +msgid "List of IDs, separated by comma" +msgstr "Lista ID:istä, pilkulla eroteltuna" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1012 +msgid "Child posts will not automatically be excluded!" +msgstr "Alimerkintöjä ei jätetä automaattisesti huomiotta!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1018 +msgid "Change frequencies" +msgstr "Päivitystiheydet" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1022 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Huomioi että tämä avainsana on vihje, ei komento. Vaikka osa hakukoneista ottaa avainsanan huomioon päätöksiä tehdessä, tunneittain päivittyviksi merkittyjä sivuja saatetaan hakea harvemmin. Vastaavasti vuosittain päivittyviä sivuja haetaan mahdollisesti useammin. Lisäksi osa hakukoneista hakee säännöllisesti sivuja, joiden päivittymistiheydeksi on merkitty \"ei koskaan\", jotta odottamattomat muutokset päivittyvät." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1028 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1086 +msgid "Homepage" +msgstr "Etusivu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1034 +msgid "Posts" +msgstr "Merkinnät" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1040 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1104 +msgid "Static pages" +msgstr "Staattiset sivut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1046 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1110 +msgid "Categories" +msgstr "Kategoriat" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1052 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Tämän kuun arkistosivu (yleensä blogin etusivu)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1058 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Vanhat arkistosivut (vaihtuvat vain kun muokkaat vanhaa merkintää)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1065 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1123 +msgid "Tag pages" +msgstr "Avainsanasivut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1072 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1130 +msgid "Author pages" +msgstr "Tekijän sivut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1080 +msgid "Priorities" +msgstr "Prioriteetit" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1092 +msgid "Posts (If auto calculation is disabled)" +msgstr "Merkinnät (jos automaattinen laskenta on poistettu käytöstä)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1098 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Merkintöjen minimiprioriteetti (vaikka automaattinen laskenta olisi käytössä)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1116 +msgid "Archives" +msgstr "Arkistot" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1141 +msgid "Update options" +msgstr "Päivitä asetukset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1142 +msgid "Reset options" +msgstr "Nollaa asetukset" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:81 +msgid "XML-Sitemap Generator" +msgstr "XML-sivustokartan luontityökalu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:81 +msgid "XML-Sitemap" +msgstr "XML-Sivustokartta" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:139 +msgid "Sitemap FAQ" +msgstr "Sivustokartta-FAQ" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fr_FR.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fr_FR.mo new file mode 100644 index 0000000..cfd231d Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fr_FR.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fr_FR.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fr_FR.po new file mode 100644 index 0000000..c7e7167 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-fr_FR.po @@ -0,0 +1,1230 @@ +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 2502 2005-07-03 20:50:38Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap 3.1.2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-05-05 20:24+0100\n" +"PO-Revision-Date: 2014-04-10 10:46+0100\n" +"Last-Translator: kalyx \n" +"Language-Team: Serge Rauber \n" +"Language: fr_FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-KeywordsList: __;_e\n" +"X-Poedit-Basepath: .\n" +"X-Generator: Poedit 1.5.4\n" +"X-Poedit-SearchPath-0: .\n" +"X-Poedit-SearchPath-1: ..\n" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:527 +msgid "Comment Count" +msgstr "Nombre de commentaires" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:537 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Utilise le nombre de commentaires pour calculer la priorité" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:590 +msgid "Comment Average" +msgstr "Moyenne des commentaires" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:600 +msgid "Uses the average comment count to calculate the priority" +msgstr "Utilise la moyenne des commentaires pour calculer la priorité" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:661 +msgid "Popularity Contest" +msgstr "Popularity Contest" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:671 +msgid "" +"Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "" +"Utiliser le plugin Popularity Contest d'Alex King. Voir Réglages et Articles les plus populaires" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:840 +msgid "Always" +msgstr "Toujours" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:841 +msgid "Hourly" +msgstr "Une fois par heure" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:842 +msgid "Daily" +msgstr "Une fois par jour" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:843 +msgid "Weekly" +msgstr "une fois par semaine" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:844 +msgid "Monthly" +msgstr "une fois par mois" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:845 +msgid "Yearly" +msgstr "une fois par an" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-core.php:846 +msgid "Never" +msgstr "Jamais" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:212 +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:212 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:239 +msgid "Settings" +msgstr "Réglages" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:240 +msgid "FAQ" +msgstr "FAQ" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:241 +msgid "Support" +msgstr "Aide" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:242 +msgid "Donate" +msgstr "Donation" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:328 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:630 +msgid "Plugin Homepage" +msgstr "Page du plugin" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-loader.php:329 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:652 +msgid "My Sitemaps FAQ" +msgstr "Ma FAQ" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:198 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:585 +msgid "XML Sitemap Generator for WordPress" +msgstr "Générateur de sitemap xml pour WordPress" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:374 +msgid "Configuration updated" +msgstr "Configuration mise à jour" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:375 +msgid "Error while saving options" +msgstr "Erreur lors de la sauvegarde des options" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:378 +msgid "Pages saved" +msgstr "Pages enregistrées" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:379 +msgid "Error while saving pages" +msgstr "Erreur durant l'enregistrement des pages" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:387 +msgid "The default configuration was restored." +msgstr "Configuration par défaut restaurée." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:397 +msgid "" +"The old files could NOT be deleted. Please use an FTP program and delete " +"them by yourself." +msgstr "" +"Les anciens fichiers n'ont pu être effacés. Veuillez utiliser un logiciel " +"FTP et les supprimer vous même." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:399 +msgid "The old files were successfully deleted." +msgstr "LEs anciens fichiers ont bien été effacés." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:439 +msgid "" +"Thank you very much for your donation. You help me to continue support and " +"development of this plugin and other free software!" +msgstr "" +"Merci beaucoup pour votre don, ça m'aide à continuer de développer ce plugin " +"et d'autres softwares!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:439 +msgid "Hide this notice" +msgstr "Masquer" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:445 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin over a month ago. " +"If it works and you are satisfied with the results, isn't it worth at least " +"a few dollar? Donations help me to continue support and " +"development of this free software! Sure, no problem!" +msgstr "" +"Merci d'utiliser ce plugin! Vous l'avez installé il y a un mois. S'il " +"fonctionne bien et que vous en êtes satisfait, est-ce trop de donner un " +"petit dollar?Les dons me permettent de continuer à " +"développer ce plugin libre et gratuit ! Je t'aide, pas " +"de problème!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:445 +msgid "Sure, but I already did!" +msgstr "Oui, mais je l'ai déjà fait!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:445 +msgid "No thanks, please don't bug me anymore!" +msgstr "Non merci, ne plus me le rappeler!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:452 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin some time ago. If " +"it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "" +"Merci d'utiliser ce plugin! Vous l'avez installé il y a quelques temps. S'il " +"fonctionne bien et que vous en êtes satisfait, pourquoi pas voter pour lui et le recommander aux autres? :-)" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:452 +msgid "Don't show this anymore" +msgstr "Ne plus jamais afficher" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:601 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here." +msgstr "" +"Une nouvelle version de %1$s est disponible. Télécharger la " +"version %3$s ici." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:603 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here automatic upgrade unavailable for this plugin." +msgstr "" +"Une nouvelle version de %1$s est disponible. Télécharger la " +"version %3$s ici.mise à jour automatique non disponible pour ce " +"plugin" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:605 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here or upgrade automatically." +msgstr "" +"Une nouvelle version de %1$s est disponible. Télécharger la " +"version %3$s ici ou Mettre à jour automatiquement." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:613 +#, php-format +msgid "" +"Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "" +"Votre site bloque actuellement les moteurs de recherche! Allez sur Réglages -> Lecture pour changer." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:629 +msgid "About this Plugin:" +msgstr "A propos" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:631 +msgid "Suggest a Feature" +msgstr "Suggestion" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:632 +msgid "Notify List" +msgstr "S'abonner" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:633 +msgid "Support Forum" +msgstr "Forum" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:634 +msgid "Report a Bug" +msgstr "Signaler un bug" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:636 +msgid "Donate with PayPal" +msgstr "Don PayPal" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:637 +msgid "My Amazon Wish List" +msgstr "Ma liste Amazon" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:638 +msgid "translator_name" +msgstr "Traduit par Serge" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:638 +msgid "translator_url" +msgstr "http://wp.kalyxstudio.com" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:641 +msgid "Sitemap Resources:" +msgstr "Ressources" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:642 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:647 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:643 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:645 +msgid "Search Blog" +msgstr "Search Blog" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:648 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:650 +msgid "Sitemaps Protocol" +msgstr "Sitemaps Protocol" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:651 +msgid "Official Sitemaps FAQ" +msgstr "Official Sitemaps FAQ" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:655 +msgid "Recent Donations:" +msgstr "Dons récents:" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:658 +msgid "List of the donors" +msgstr "Liste des donateurs" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:660 +msgid "Hide this list" +msgstr "Masquer" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:663 +msgid "Thanks for your support!" +msgstr "Merci de votre aide!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:683 +msgid "Search engines haven't been notified yet" +msgstr "Les moteurs de recherche n'ont pas encore été notifiés." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:687 +msgid "Result of the last ping, started on %date%." +msgstr "Résultat du dernier ping, démarré le %date%." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:702 +#, php-format +msgid "" +"There is still a sitemap.xml or sitemap.xml.gz file in your blog directory. " +"Please delete them as no static files are used anymore or try " +"to delete them automatically." +msgstr "" +"Il y a encore un fichier sitemap.xml ou sitemap.xml.gz dans le répertoire de " +"votre site. Veuillez les supprimer car ces fichiers ne sont plus utilisés ou " +"essayez de les supprimer automatiquement." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:705 +#, php-format +msgid "The URL to your sitemap index file is: %s." +msgstr "L'URL de l'index de votre sitemap est : %s." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:708 +msgid "" +"Search engines haven't been notified yet. Write a post to let them know " +"about your sitemap." +msgstr "" +"Les moteurs de recherche n'ont pas encore été notifiés. Publiez un article " +"pour les notifier de votre sitemap." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:717 +#, php-format +msgid "%s was successfully notified about changes." +msgstr "%s a été informé des changements." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:720 +msgid "" +"It took %time% seconds to notify %name%, maybe you want to disable this " +"feature to reduce the building time." +msgstr "" +"Il a fallu %time% secondes pour informer %name%, vous pouvez désactivez " +"cette fonction pour réduire la durée du processus." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:723 +msgid "" +"There was a problem while notifying %name%. View result" +msgstr "" +"Problème de notification avec %name%.Voir le résultat" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:727 +#, php-format +msgid "" +"If you encounter any problems with your sitemap you can use the debug function to get more information." +msgstr "" +"Si vous rencontrez un problème avec votre sitemap, vous pouvez utiliser la " +"fonction de débogage pour avoir plus d'infos." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:735 +msgid "Basic Options" +msgstr "Options de base" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:737 +msgid "Update notification:" +msgstr "Notifications:" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:737 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:765 +msgid "Learn more" +msgstr "En savoir plus" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:741 +msgid "Notify Google about updates of your Blog" +msgstr "Informer Google des mises à jour du blog" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:742 +#, php-format +msgid "" +"No registration required, but you can join the Google " +"Webmaster Tools to check crawling statistics." +msgstr "" +"Pas d'inscription nécessaire, mais vous pouvez vous inscrire sur Google Webmaster Tools pour connaître les statistiques de passage de " +"google" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:746 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "Informer Bing (MSN Live Search) des mises à jour du blog" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:747 +#, php-format +msgid "" +"No registration required, but you can join the Bing Webmaster " +"Tools to check crawling statistics." +msgstr "" +"Pas d'inscription nécessaire, mais vous pouvez vous inscrire sur bing Webmaster Tools pour connaître les statistiques de passage de " +"Bing" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:751 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Informer Ask.com des mises à jour du blog" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:752 +msgid "No registration required." +msgstr "Inscription non requise." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:757 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Ajouter l'URL du sitemap au fichier virtuel robots.txt" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:761 +msgid "" +"The virtual robots.txt generated by WordPress is used. A real robots.txt " +"file must NOT exist in the blog directory!" +msgstr "" +"Le fichier virtuel robots.txt de WordPress est utilisé. Il NE DOIT PAS y " +"avoir de vrai fichier robots.txt dans le répertoire du blog!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:765 +msgid "Advanced options:" +msgstr "Options avancées:" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:768 +msgid "Try to increase the memory limit to:" +msgstr "Essayer d'augmenter la quantité de mémoire alouée:" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:768 +msgid "e.g. \"4M\", \"16M\"" +msgstr "ex: \"4M\", \"16M\"" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:771 +msgid "Try to increase the execution time limit to:" +msgstr "Essayer d'augmenter la durée limite d'éxécution du script : " + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:771 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "en secondes, ex: \"60\" ou \"0\" pour illimité" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:775 +msgid "Include a XSLT stylesheet:" +msgstr "Feuille de style XSLT:" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:776 +msgid "Full or relative URL to your .xsl file" +msgstr "Adresse complète ou relative du fichier .xsl" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:776 +msgid "Use default" +msgstr "par défaut" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:781 +msgid "Include sitemap in HTML format" +msgstr "INclure un sitemap au format HTML" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:790 +msgid "Additional pages" +msgstr "Pages supplémentaires" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:793 +msgid "" +"Here you can specify files or URLs which should be included in the sitemap, " +"but do not belong to your Blog/WordPress.
        For example, if your domain " +"is www.foo.com and your blog is located on www.foo.com/blog you might want " +"to include your homepage at www.foo.com" +msgstr "" +"Vous pouvez préciser ici des adresses à inclure dans le sitemap, qui " +"n'appartiennent pas à votre Blog/WordPress.
        Par exemple, si votre " +"domaine est www.truc.com et que votre blog est situé sur www.truc.com/blog, " +"vous pouvez choisir d'inclure la page d'accueil www.truc.com" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:795 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:998 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1018 +msgid "Note" +msgstr "Remarque" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:796 +msgid "" +"If your blog is in a subdirectory and you want to add pages which are NOT in " +"the blog directory or beneath, you MUST place your sitemap file in the root " +"directory (Look at the "Location of your sitemap file" section on " +"this page)!" +msgstr "" +"Si votre weblog est dans un sous-repertoire et que vous voulez ajouter des " +"pages qui ne sont PAS situées dans le répertoire du blog ou un répertoire en " +"dessous, vous DEVEZ placer votre fichier sitemap dans le répertoire racine " +"(voir la section "Emplacement de votre fichier sitemap" de cette " +"page)!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:798 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:836 +msgid "URL to the page" +msgstr "URL de la page" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:799 +msgid "" +"Enter the URL to the page. Examples: http://www.foo.com/index.html or www." +"foo.com/home " +msgstr "" +"Indiquez l'URL de la page. Examples: http://www.foo.com/index.html ou www." +"foo.com/home " + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:801 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:837 +msgid "Priority" +msgstr "Priorité" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:802 +msgid "" +"Choose the priority of the page relative to the other pages. For example, " +"your homepage might have a higher priority than your imprint." +msgstr "" +"Définissez la priorité de la page par rapport aux autres pages. Par exemple, " +"votre page d'accueil peut avoir une priorité supérieure à celle des autres " +"pages." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:804 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:839 +msgid "Last Changed" +msgstr "Dernière modification" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:805 +msgid "" +"Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) " +"(optional)." +msgstr "" +"Entrez la date de dernière modification au format AAAA-MM-JJ (2005-12-31 par " +"exemple) (facultatif)." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:838 +msgid "Change Frequency" +msgstr "Modifier la fréquence" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:840 +msgid "#" +msgstr "#" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:845 +msgid "No pages defined." +msgstr "Aucune page définie." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:850 +msgid "Add new page" +msgstr "Ajouter une nouvelle page" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:856 +msgid "Post Priority" +msgstr "Priorité de l'article" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:858 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Choisissez comment la priorité de l'article est calculée:" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:860 +msgid "Do not use automatic priority calculation" +msgstr "ne pas faire de calcul automatique" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:860 +msgid "" +"All posts will have the same priority which is defined in "" +"Priorities"" +msgstr "Tous les articles auront la même priorité" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:871 +msgid "Sitemap Content" +msgstr "Contenu du sitemap" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:872 +msgid "WordPress standard content" +msgstr "Contenu standard de WordPress" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:877 +msgid "Include homepage" +msgstr "Inclure la page d'accueil" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:883 +msgid "Include posts" +msgstr "Inclure les articles" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:889 +msgid "Include static pages" +msgstr "Inclure les pages statiques" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:895 +msgid "Include categories" +msgstr "Inclure les catégories" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:901 +msgid "Include archives" +msgstr "Inclure les archives" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:907 +msgid "Include author pages" +msgstr "Inclure les pages Auteur" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:914 +msgid "Include tag pages" +msgstr "Inclure les pages tags" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:928 +msgid "Custom taxonomies" +msgstr "Taxonomies" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:939 +#, php-format +msgid "Include taxonomy pages for %s" +msgstr "Inclure les pages %s" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:957 +msgid "Custom post types" +msgstr "Autres types d'article" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:968 +#, php-format +msgid "Include custom post type %s" +msgstr "Inclure les articles de type %s" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:980 +msgid "Further options" +msgstr "Options supplémentaires" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:985 +msgid "Include the last modification time." +msgstr "Inclure la date de dernière modification" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:987 +msgid "" +"This is highly recommended and helps the search engines to know when your " +"content has changed. This option affects all sitemap entries." +msgstr "" +"Ceci est fortement recommandé et aide les moteurs de recherche à savoir " +"lorsque vote contenu à changer. Cette option affecte toutes les donnéesdu sitemap." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:994 +msgid "Excluded items" +msgstr "Données à exclure" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:996 +msgid "Excluded categories" +msgstr "Catégories exclues" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:998 +msgid "Using this feature will increase build time and memory usage!" +msgstr "" +"L'utilisation de cette fonction augmente la durée et la mémoire utilisée!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1005 +msgid "Exclude posts" +msgstr "EXclure des articles" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1007 +msgid "Exclude the following posts or pages:" +msgstr "Exclure les articles ou pages suivants:" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1007 +msgid "List of IDs, separated by comma" +msgstr "liste d'ID, séparés par une virgule" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +msgid "Child posts won't be excluded automatically!" +msgstr "Les sous-pages ne seront pas automatiquement exclus!" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1015 +msgid "Change frequencies" +msgstr "Modifier les fréquences" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1019 +msgid "" +"Please note that the value of this tag is considered a hint and not a " +"command. Even though search engine crawlers consider this information when " +"making decisions, they may crawl pages marked \"hourly\" less frequently " +"than that, and they may crawl pages marked \"yearly\" more frequently than " +"that. It is also likely that crawlers will periodically crawl pages marked " +"\"never\" so that they can handle unexpected changes to those pages." +msgstr "" +"Veuillez noter que la valeur de ce champ est considérée comme un indice et " +"non une commande. Même si les robots de moteurs de recherche prennent en " +"compte cette information, il peuvent parcourir les pages marquées "" +"toutes les heures" moins fréquemment que cela, et peuvent parcourir les " +"pages marquées "une fois par an" plus fréquemment que cela. Il est " +"aussi probable que les robots parcourent de façon périodique les pages " +"marquées "jamais" afin de prendre en compte les modifications " +"inattendues de ces pages." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1025 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1082 +msgid "Homepage" +msgstr "Page d'accueil" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1031 +msgid "Posts" +msgstr "Articles" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1037 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1100 +msgid "Static pages" +msgstr "Pages statiques" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1043 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1106 +msgid "Categories" +msgstr "Catégories" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1049 +msgid "" +"The current archive of this month (Should be the same like your homepage)" +msgstr "" +"L'archive du mois en cours (devrait correspondre à votre page d'accueil)" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1055 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "" +"Archives antérieures (ne change que lorsque vous modifier un ancien article)" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1062 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1119 +msgid "Tag pages" +msgstr "Pages Tag" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1069 +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1126 +msgid "Author pages" +msgstr "Pages Auteur" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1077 +msgid "Priorities" +msgstr "Priorités" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1088 +msgid "Posts (If auto calculation is disabled)" +msgstr "Articles (si le calcul automatique est désactivé)" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1094 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "" +"Priorité minimum des articles (Même si le calcul automatique est activé)" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1112 +msgid "Archives" +msgstr "Archives" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1137 +msgid "Update options" +msgstr "Enregistrer les changements" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap-ui.php:1138 +msgid "Reset options" +msgstr "Réinitialiser les options" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap.php:82 +msgid "Your WordPress version is too old for XML Sitemaps." +msgstr "Votre version de WordPress est trop ancienne pour XML Sitemaps" + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap.php:82 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least " +"WordPress %4$s. You are using Wordpress %2$s, which is out-dated and " +"insecure. Please upgrade or go to active plugins and " +"deactivate the Google XML Sitemaps plugin to hide this message. You can " +"download an older version of this plugin from the plugin " +"website." +msgstr "" +"Cette version de Google XML Sitemaps nécessite au moins WordPress %4$s. Vous " +"utilisez Wordpress %2$s, qui est ancien et vulnérable. Mettez à jour ou " +"allez sur Extensions installées et désactiver cette " +"ectension. Vous pouvez télécharger l'ancienne version de cette extension sur " +"mon site." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap.php:92 +msgid "Your PHP version is too old for XML Sitemaps." +msgstr "Votre version de PHP est trop ancienne pour XML Sitemaps." + +#: C:\Inetpub\wwwroot\wp_plugins\sitemap_beta/sitemap.php:92 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least PHP " +"%4$s. You are using PHP %2$s, which is out-dated and insecure. Please ask " +"your web host to update your PHP installation or go to active plugins and deactivate the Google XML Sitemaps plugin to hide " +"this message. You can download an older version of this plugin from the plugin website." +msgstr "" +"Cette version de Google XML Sitemaps nécessite au moins PHP %4$s. Vous " +"utilisez PHP %2$s, qui est ancien et vulnérable. Demandez à votre hébergeur " +"de mettre à jour PHP sur votre serveur ou allez sur Extensions installées et désactiver cette ectension. Vous pouvez " +"télécharger l'ancienne version de cette extension sur mon " +"site." + +#~ msgid "" +#~ "Your sitemap is being refreshed at the moment. Depending on your blog " +#~ "size this might take some time!" +#~ msgstr "" +#~ "Mise à jour du sitemap en cours. En fonction de la taille de votre blog, " +#~ "ça peut prendre un certain temps!" + +#~ msgid "" +#~ "Your sitemap will be refreshed in %s seconds. Depending on your blog size " +#~ "this might take some time!" +#~ msgstr "" +#~ "La mise à jour du sitemap devrait prendre %s secondes. En fonction de la " +#~ "taille de votre blog, ça peut prendre un certain temps!" + +#~ msgid "open" +#~ msgstr "ouvrir" + +#~ msgid "close" +#~ msgstr "fermer" + +#~ msgid "click-down and drag to move this box" +#~ msgstr "Faites un glisser/déposer pour déplacer cette boite." + +#~ msgid "click to %toggle% this box" +#~ msgstr "Cliquez pour %inverser% cette case" + +#~ msgid "use the arrow keys to move this box" +#~ msgstr "Utilisez les touches fléchées pour déplacer cette boite" + +#~ msgid ", or press the enter key to %toggle% it" +#~ msgstr ", ou appuyez sur la touche Entrée pour l'%inverser%." + +#~ msgid "Site Explorer" +#~ msgstr "Site Explorer" + +#~ msgid "Status" +#~ msgstr "Statuts" + +#~ msgid "" +#~ "The sitemap wasn't built yet. Click here to build it " +#~ "the first time." +#~ msgstr "Cliquez ici pour générer votre premier sitemap." + +#~ msgid "Your sitemap was last built on %date%." +#~ msgstr "Dernier sitemap généré le %date%." + +#~ msgid "" +#~ "There was a problem writing your sitemap file. Make sure the file exists " +#~ "and is writable. Learn moreen savoir " +#~ "pluszipped) was last built on %date%." +#~ msgstr "" +#~ "Dernier sitemap (zip) généré le %date%." + +#~ msgid "" +#~ "There was a problem writing your zipped sitemap file. Make sure the file " +#~ "exists and is writable. Learn moreen savoir " +#~ "plussuccessfully notified about changes." +#~ msgstr "Google a été informé des changements." + +#~ msgid "" +#~ "It took %time% seconds to notify Google, maybe you want to disable this " +#~ "feature to reduce the building time." +#~ msgstr "" +#~ "Il a fallu %time% secondes pour informer Google, vous pouvez désactivez " +#~ "cette fonction pour réduire la durée du processus." + +#~ msgid "" +#~ "There was a problem while notifying Google. View result" +#~ msgstr "Problème pour informer Google.Voir le résultat" + +#~ msgid "YAHOO was successfully notified about changes." +#~ msgstr "Yahoo a été informé des changements." + +#~ msgid "" +#~ "It took %time% seconds to notify YAHOO, maybe you want to disable this " +#~ "feature to reduce the building time." +#~ msgstr "" +#~ "Il a fallu %time% secondes pour informer Yahoo, vous pouvez désactivez " +#~ "cette fonction pour réduire la durée du processus." + +#~ msgid "" +#~ "There was a problem while notifying YAHOO. View result" +#~ msgstr "Problème pour informer Yahoo.Voir le résultat" + +#~ msgid "Ask.com was successfully notified about changes." +#~ msgstr "Ask.com a été informé des changements." + +#~ msgid "" +#~ "It took %time% seconds to notify Ask.com, maybe you want to disable this " +#~ "feature to reduce the building time." +#~ msgstr "" +#~ "Il a fallu %time% secondes pour informer Ask.com, vous pouvez désactivez " +#~ "cette fonction pour réduire la durée du processus." + +#~ msgid "" +#~ "There was a problem while notifying Ask.com. View result" +#~ msgstr "Problème pour informer Ask.com.Voir le résultat" + +#~ msgid "" +#~ "The building process took about %time% seconds to complete and " +#~ "used %memory% MB of memory." +#~ msgstr "" +#~ "Le processus a mis environ %time% secondes et utilisé %memory% MB " +#~ "de mémoire." + +#~ msgid "The building process took about %time% seconds to complete." +#~ msgstr "Le processus a mis environ %time% secondes." + +#~ msgid "" +#~ "The content of your sitemap didn't change since the last " +#~ "time so the files were not written and no search engine was pinged." +#~ msgstr "" +#~ "Le contenu de votre sitemap n'a pas changé depuis la " +#~ "dernière fois. Les fichiers n'ont pas été modifié, et les moteurs de " +#~ "recherche n'ont pas été informé." + +#~ msgid "" +#~ "The building process might still be active! Reload the page in a few " +#~ "seconds and check if something has changed." +#~ msgstr "" +#~ "Le processus est encore en cours! Rechargez la page dans quelques " +#~ "secondes et vérifiez si quelque chose a changé." + +#~ msgid "" +#~ "The last run didn't finish! Maybe you can raise the memory or time limit " +#~ "for PHP scripts. Learn more" +#~ msgstr "" +#~ "Le dernier processus a échoué! Essayez d'augmenter le mémoire alouée ou " +#~ "la durée limite des scripts PHP En savoir plus" + +#~ msgid "" +#~ "The last known memory usage of the script was %memused%MB, the limit of " +#~ "your server is %memlimit%." +#~ msgstr "" +#~ "Mémoire utilisée la dernière fois : %memused%MB (limite du serveur : " +#~ "%memlimit%)" + +#~ msgid "" +#~ "The last known execution time of the script was %timeused% seconds, the " +#~ "limit of your server is %timelimit% seconds." +#~ msgstr "" +#~ "Temps d'éxécution la dernière fois : %timeused% secondes (limite du " +#~ "serveur : %timelimit%)" + +#~ msgid "The script stopped around post number %lastpost% (+/- 100)" +#~ msgstr "Le script s'est arrêté vers l'article numéro %lastpost% (+/- 100)" + +#~ msgid "" +#~ "If you changed something on your server or blog, you should rebuild the sitemap manually." +#~ msgstr "" +#~ "Si vous changez quelquechose sur votre serveur ou sur votre blog, vous " +#~ "devez reconstruire le sitemap manuellement." + +#~ msgid "Sitemap files:" +#~ msgstr "Type de fichiers:" + +#~ msgid "Write a normal XML file (your filename)" +#~ msgstr "Ecrire un fichier XML normal (nom de fichier)" + +#~ msgid "Write a gzipped file (your filename + .gz)" +#~ msgstr "Ecrire un fichier gzippé (votre nom de fichier + .gz)" + +#~ msgid "Building mode:" +#~ msgstr "Mode de construction:" + +#~ msgid "Rebuild sitemap if you change the content of your blog" +#~ msgstr "Générer le sitemap lorsque le contenu du blog change" + +#~ msgid "Enable manual sitemap building via GET Request" +#~ msgstr "Activer la génération manuel du sitemap par requête GET" + +#~ msgid "" +#~ "This will allow you to refresh your sitemap if an external tool wrote " +#~ "into the WordPress database without using the WordPress API. Use the " +#~ "following URL to start the process: %1 Please check " +#~ "the logfile above to see if sitemap was successfully built." +#~ msgstr "" +#~ "Ceci vous permet de mettre à jour votre sitemap si vous utilisez un outil " +#~ "externe de publication. Utilisez l'adresse suivante pour lancer le " +#~ "processus %1. Vérifiez dans le fichier log que le " +#~ "processus a bien fonctionné." + +#~ msgid "Notify YAHOO about updates of your Blog" +#~ msgstr "Informer Yahoo des mises à jour du blog" + +#~ msgid "Your Application ID:" +#~ msgstr "Yahoo ID:" + +#~ msgid "Don't you have such a key? Request one here! %s2" +#~ msgstr "" +#~ "Vous n'avez pas de clé Yahoo ?Demandez en une ici! %s2" + +#~ msgid "Limit the number of posts in the sitemap:" +#~ msgstr "Limiter le nombre d'articles dans le sitemap:" + +#~ msgid "Newer posts will be included first" +#~ msgstr "Les nouveaux articles seront ajoutés au début" + +#~ msgid "" +#~ "Enable MySQL standard mode. Use this only if you're getting MySQL errors. " +#~ "(Needs much more memory!)" +#~ msgstr "" +#~ "Active le mode MySQL standard. A n'utiliser que si vous avez des erreurs " +#~ "MySQL. (utilise plus de mémoire!)" + +#~ msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +#~ msgstr "" +#~ "Passez au moins à la version 2.2 de WordPress pour activer l'accès MySQL " +#~ "rapide" + +#~ msgid "" +#~ "Build the sitemap in a background process (You don't have to wait when " +#~ "you save a post)" +#~ msgstr "" +#~ "Générer le sitemap en arrière-plan (pas d'attente lors de la sauvegarde " +#~ "d'un article)" + +#~ msgid "Upgrade WordPress at least to 2.1 to enable background building" +#~ msgstr "Passez au moins à la version 2.1 pour utiliser la tâche de fond." + +#~ msgid "Location of your sitemap file" +#~ msgstr "Emplacement de votre fichier sitemap" + +#~ msgid "Automatic detection" +#~ msgstr "Détection automatique" + +#~ msgid "Filename of the sitemap file" +#~ msgstr "Nom du fichier sitemap" + +#~ msgid "Detected Path" +#~ msgstr "Répertoire détecté" + +#~ msgid "Detected URL" +#~ msgstr "URL détecté" + +#~ msgid "Absolute or relative path to the sitemap file, including name." +#~ msgstr "Chemin absolu ou relatif vers le fichier sitemap, nom inclus." + +#~ msgid "Example" +#~ msgstr "Exemple" + +#~ msgid "Complete URL to the sitemap file, including name." +#~ msgstr "URL complet du fichier sitemap, nom inclus." + +#~ msgid "" +#~ "Include following pages of multi-page posts (Increases build time and " +#~ "memory usage!)" +#~ msgstr "" +#~ "Inclure les pages suivantes d'article multi-page (augmente la durée du " +#~ "processus et l'usage de la mémoire)" + +#~ msgid "This feature requires at least WordPress 2.5.1, you are using %s" +#~ msgstr "Cette fonction requiert au moins WordPress 2.5.1, vous utilisez %s" + +#~ msgid "" +#~ "It took %time% seconds to notify MSN.com, maybe you want to disable this " +#~ "feature to reduce the building time." +#~ msgstr "" +#~ "Il a fallu %time% secondes pour informer MSN, vous pouvez désactivez " +#~ "cette fonction pour réduire la durée du processus." + +#~ msgid "" +#~ "There was a problem while notifying MSN.com. View result" +#~ msgstr "Problème pour informer MSN.Voir le résultat" + +#~ msgid "" +#~ "No registration required, but you can join the MSN Live " +#~ "Webmaster Tools to check crawling statistics." +#~ msgstr "" +#~ "Pas d'inscription nécessaire, mais vous pouvez vous inscrire sur MSN Live Webmaster Tools pour connaître les statistiques de " +#~ "passage de google" + +#~ msgid "Sitemap FAQ" +#~ msgstr "Ma FAQ" + +#~ msgid "Robots.txt file saved" +#~ msgstr "Robots.txt sauvegardé" + +#~ msgid "Error while saving Robots.txt file" +#~ msgstr "Erreur lors de l'enregistrement du fichier robots.txt" + +#~ msgid "" +#~ "Modify or create %s file in blog root which contains the sitemap location." +#~ msgstr "" +#~ "Modifier ou créer le fichier %s à la racine du blog qui contient " +#~ "l'adresse du sitemap" + +#~ msgid "File permissions: " +#~ msgstr "Permission :" + +#~ msgid "OK, robots.txt is writable." +#~ msgstr "OK, robots.txt est en écriture" + +#~ msgid "Error, robots.txt is not writable." +#~ msgstr "Erreur, robots.txt n'est pas en écriture" + +#~ msgid "OK, robots.txt doesn't exist but the directory is writable." +#~ msgstr "OK, robots.txt n'existe pas mais peut être créé" + +#~ msgid "Error, robots.txt doesn't exist and the directory is not writable" +#~ msgstr "Erreur, robots.txt n'existe pas et ne peut être créé." + +#~ msgid "Manual location" +#~ msgstr "Emplacement manuel" + +#~ msgid "OR" +#~ msgstr "OU" + +#~ msgid "Error" +#~ msgstr "Erreur" + +#~ msgid "" +#~ "A new page was added. Click on "Save page changes" to save your " +#~ "changes." +#~ msgstr "" +#~ "Une nouvelle page a été ajoutée. Cliquez sur "Enregistrer les " +#~ "modifications" pour enregistrer vos modifications" + +#~ msgid "" +#~ "The page was deleted. Click on "Save page changes" to save your " +#~ "changes." +#~ msgstr "" +#~ "La page a été effacée. Cliquez sur "Entregistrer les " +#~ "modifications" pour enregistrer vos modifications." + +#~ msgid "You changes have been cleared." +#~ msgstr "Vos modifications ont été remises à zero." + +#~ msgid "Manual rebuild" +#~ msgstr "Reconstruction manuelle" + +#~ msgid "" +#~ "If you want to build the sitemap without editing a post, click on here!" +#~ msgstr "" +#~ "Si vous voulez construire le fichier sitemap sans modifier un article, " +#~ "cliquez ici!" + +#~ msgid "Rebuild Sitemap" +#~ msgstr "Reconstruire le fichier Sitemap" + +#~ msgid "Save page changes" +#~ msgstr "Enregistrer les modifications de page" + +#~ msgid "Undo all page changes" +#~ msgstr "Annuler toutes les modifications de page" + +#~ msgid "Delete marked page" +#~ msgstr "Effacer la page marquée" + +#~ msgid "" +#~ "Enable automatic priority calculation for posts based on comment count" +#~ msgstr "" +#~ "Autoriser le calcul de priorité automatique pour les articles en fonction " +#~ "du nombre de commentaires" + +#~ msgid "Write debug comments" +#~ msgstr "Ecrire des commentaires de debug" + +#~ msgid "Auto-Ping Google Sitemaps" +#~ msgstr "Effectuer un ping automatique de Google Sitemaps" + +#~ msgid "This option will automatically tell Google about changes." +#~ msgstr "" +#~ "Cette option préviendra automatiquement Google lors de modifications." + +#~ msgid "Includings" +#~ msgstr "Inclusions" + +#~ msgid "Informations and support" +#~ msgstr "Informations et support" + +#~ msgid "" +#~ "Check %s for updates and comment there if you have any problems / " +#~ "questions / suggestions." +#~ msgstr "" +#~ "Allez sur %s pour les mises à jour et pour poster un commentaire en cas " +#~ "de probleme / question / suggestion." + +#~ msgid "URL:" +#~ msgstr "URL:" + +#~ msgid "Path:" +#~ msgstr "Chemin:" + +#~ msgid "Could not write into %s" +#~ msgstr "Impossible d'écrire dans %s" + +#~ msgid "Successfully built sitemap file:" +#~ msgstr "Sitemap généré avec succès:" + +#~ msgid "Successfully built gzipped sitemap file:" +#~ msgstr "Sitemap gzippé généré avec succès:" + +#~ msgid "Could not ping to Google at %s" +#~ msgstr "Ping de Google impossible à %s" + +#~ msgid "Successfully pinged Google at %s" +#~ msgstr "Ping de Google réussi à %s" diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hi_IN.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hi_IN.mo new file mode 100644 index 0000000..97c7241 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hi_IN.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hi_IN.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hi_IN.po new file mode 100644 index 0000000..b76e666 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hi_IN.po @@ -0,0 +1,1030 @@ +msgid "" +msgstr "" +"Project-Id-Version: google-sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-11-20 22:53+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Ashish \n" +"Language-Team: Outshine Solutions \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Hindi\n" +"X-Poedit-Country: INDIA\n" +"X-Poedit-SourceCharset: utf-8\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:525 +msgid "Comment Count" +msgstr "टिपà¥à¤ªà¤£à¥€ गिनती" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:537 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "पद की टिपà¥à¤ªà¤£à¤¿à¤¯à¥‹à¤‚ की संखà¥à¤¯à¤¾ का उपयोग करते हà¥à¤ पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता की गणना करो " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:597 +msgid "Comment Average" +msgstr "टिपà¥à¤ªà¤£à¥€ औसत" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:609 +msgid "Uses the average comment count to calculate the priority" +msgstr "औसत टिपà¥à¤ªà¤£à¥€ गिनती का उपयोग पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता की गणना के लिठकरो. " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:672 +msgid "Popularity Contest" +msgstr "लोकपà¥à¤°à¤¿à¤¯à¤¤à¤¾ पà¥à¤°à¤¤à¤¿à¤¯à¥‹à¤—िता" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:684 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "सकà¥à¤°à¤¿à¤¯ का उपयोग करता है लोकपà¥à¤°à¤¿à¤¯à¤¤à¤¾ पà¥à¤°à¤¤à¤¿à¤¯à¥‹à¤—िता पà¥à¤²à¤—इन से à¤à¤²à¥‡à¤•à¥à¤¸ राजा . देखे सेटिंगà¥à¤¸ और सरà¥à¤µà¤¾à¤§à¤¿à¤• लोकपà¥à¤°à¤¿à¤¯ डाक" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1118 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1084 +msgid "Always" +msgstr "हमेशा" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1119 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1085 +msgid "Hourly" +msgstr "पà¥à¤°à¤¤à¤¿ घंटा" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1120 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1086 +msgid "Daily" +msgstr "दैनिक" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1087 +msgid "Weekly" +msgstr "सापà¥à¤¤à¤¾à¤¹à¤¿à¤•" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1122 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1088 +msgid "Monthly" +msgstr "मासिक" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1123 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1089 +msgid "Yearly" +msgstr "वारà¥à¤·à¤¿à¤•" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1090 +msgid "Never" +msgstr "कभी नहीं" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:107 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "आपको अपने दान के लिठबहà¥à¤¤ बहà¥à¤¤ धनà¥à¤¯à¤µà¤¾à¤¦. तà¥à¤® मेरी समरà¥à¤¥à¤¨ और इस पà¥à¤²à¤—इन और अनà¥à¤¯ मà¥à¤•à¥à¤¤ सॉफà¥à¤Ÿà¤µà¥‡à¤¯à¤° के विकास को जारी रखने के लिठमदद करो !" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:107 +msgid "Hide this notice" +msgstr "नोटिस छà¥à¤ªà¤¾à¤à¤" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:113 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and you are satisfied with the results, isn't it worth at least a few dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "इस पà¥à¤²à¤—इन का उपयोग करने के लिठधनà¥à¤¯à¤µà¤¾à¤¦! तà¥à¤® à¤à¤• महीने पहले इस पà¥à¤²à¤—इन को सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ चà¥à¤•े हो. अगर यह काम करता है और तà¥à¤® परिणाम से संतà¥à¤·à¥à¤Ÿ हो, दान समरà¥à¤¥à¤¨ और इस का विकास जारी रखने के लिठमेरी मदद करो free सॉफà¥à¤Ÿà¤µà¥‡à¤¯à¤°! बेशक, कोई समसà¥à¤¯à¤¾ नहीं है! " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:113 +msgid "Sure, but I already did!" +msgstr "यकीन है, लेकिन मैं इसे पहले ही कर चूका हà¥!." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:113 +msgid "No thanks, please don't bug me anymore!" +msgstr "नहीं, धनà¥à¤¯à¤µà¤¾à¤¦,, कृपया मà¥à¤à¥‡ अब और परेशान नहीं करो!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:120 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin some time ago. If it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "इस पà¥à¤²à¤—इन का उपयोग करने के लिठधनà¥à¤¯à¤µà¤¾à¤¦! आप इस पà¥à¤²à¤—इन को कà¥à¤› समय पहले सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ कर चà¥à¤•े हो.अगर यह काम करता है और आपके संतà¥à¤·à¥à¤Ÿ करता है, कà¥à¤¯à¥‹à¤‚ नहीं यह दर और यह अनà¥à¤¶à¤‚सा to others? :-)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:120 +msgid "Don't show this anymore" +msgstr "अब यह मत दिखाओ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:132 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "आपका साइटमैप पल में ताजा किया जा रहा है. निरभर है अपने बà¥à¤²à¥‰à¤— के आकार पर यह कà¥à¤› समय ले सकता है!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:134 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "साइटमैप ताजा हो जाà¤à¤—ा %s सेकंड में, यह कà¥à¤› समय ले सकता है! निरभर है आपके बà¥à¤²à¥‰à¤— के आकार पर !" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:163 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:480 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML साइटमैप WordPress के लिठजेनरेटर है " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:323 +msgid "Configuration updated" +msgstr "विनà¥à¤¯à¤¾à¤¸ नवनिरà¥à¤®à¤¿à¤¤ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:324 +msgid "Error while saving options" +msgstr "विकलà¥à¤ª बचाते समय तà¥à¤°à¥à¤Ÿà¤¿ आई " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:326 +msgid "Pages saved" +msgstr "पृषà¥à¤ à¥‹à¤‚ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:327 +msgid "Error while saving pages" +msgstr "पनà¥à¤¨à¥‡ बचाते समय तà¥à¤°à¥à¤Ÿà¤¿ आई " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:334 +msgid "The default configuration was restored." +msgstr "डिफ़ॉलà¥à¤Ÿ कॉनà¥à¤«à¤¼à¤¿à¤—रेशन बहाल कर दी गई." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:496 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "वहाठà¤à¤• नया संसà¥à¤•रण %1$s उपलबà¥à¤§ है. डाउनलोड संसà¥à¤•रण %3$s here." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:498 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "वहाठà¤à¤• नया संसà¥à¤•रण %1$s उपलबà¥à¤§ है. डाउनलोड संसà¥à¤•रण %3$s hereसà¥à¤µà¤¤: उनà¥à¤¨à¤¯à¤¨ इस पà¥à¤²à¤—इन के लिठअनà¥à¤ªà¤²à¤¬à¥à¤§ ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:500 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "वहाठà¤à¤• नया संसà¥à¤•रण %1$s उपलबà¥à¤§ है. डाउनलोड संसà¥à¤•रण %3$s here या सà¥à¤µà¤¤à¤ƒ उनà¥à¤¨à¤¤." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:508 +#, php-format +msgid "Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "वरà¥à¤¤à¤®à¤¾à¤¨ में आपके बà¥à¤²à¥‰à¤— खोज इंजन बाधा डाल रही है! गोपनीयता सेटिंगà¥à¤¸ इसे बदलते हैं." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:529 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:546 +msgid "open" +msgstr "खà¥à¤²à¤¾ होना" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:530 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:547 +msgid "close" +msgstr "खà¥à¤²à¤¾ होना" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:531 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:548 +msgid "click-down and drag to move this box" +msgstr "नीचे कà¥à¤²à¤¿à¤• करें और इस को बॉकà¥à¤¸ डà¥à¤°à¥ˆà¤— करे. " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:532 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:549 +msgid "click to %toggle% this box" +msgstr "कà¥à¤²à¤¿à¤• करे %toggle%इस बॉकà¥à¤¸ पर " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:550 +msgid "use the arrow keys to move this box" +msgstr "तीर कà¥à¤‚जी का उपयोग इस बॉकà¥à¤¸ पर करे. " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:534 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:551 +msgid ", or press the enter key to %toggle% it" +msgstr ", या इंटर के दबाये %टॉगल % करने में " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:580 +msgid "About this Plugin:" +msgstr "इस पà¥à¤²à¤—इन के बारे में:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:581 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:181 +msgid "Plugin Homepage" +msgstr "पà¥à¤²à¤—इन मà¥à¤–पृषà¥à¤ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:582 +msgid "Suggest a Feature" +msgstr "à¤à¤• फीचर का सà¥à¤à¤¾à¤µ है" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:583 +msgid "Notify List" +msgstr "सूचित सूची" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:584 +msgid "Support Forum" +msgstr "समरà¥à¤¥à¤¨ फोरम" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:585 +msgid "Report a Bug" +msgstr "à¤à¤• बग रिपोरà¥à¤Ÿ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:587 +msgid "Donate with PayPal" +msgstr "पेपैल के साथ दान" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:588 +msgid "My Amazon Wish List" +msgstr "मेरे अमेज़न इचà¥à¤›à¤¾ सूची" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:589 +msgid "translator_name" +msgstr "Outshine Solutions" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:589 +msgid "translator_url" +msgstr "http://outshinesolutions.com" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:593 +msgid "Sitemap Resources:" +msgstr "साइटमैप संसाधन:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:594 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:600 +msgid "Webmaster Tools" +msgstr "वेबमासà¥à¤Ÿà¤° उपकरण" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:595 +msgid "Webmaster Blog" +msgstr "वेबमासà¥à¤Ÿà¤° बà¥à¤²à¥‰à¤—" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:597 +msgid "Site Explorer" +msgstr "साइट à¤à¤•à¥à¤¸à¤ªà¥à¤²à¥‹à¤°à¤°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:598 +msgid "Search Blog" +msgstr "खोज बà¥à¤²à¥‰à¤—" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:601 +msgid "Webmaster Center Blog" +msgstr "वेबमासà¥à¤Ÿà¤° केंदà¥à¤° बà¥à¤²à¥‰à¤—" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:603 +msgid "Sitemaps Protocol" +msgstr "साइटमैप पà¥à¤°à¥‹à¤Ÿà¥‹à¤•ॉल" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:604 +msgid "Official Sitemaps FAQ" +msgstr "सरकारी साइटमैप फैकà¥à¤¸" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:605 +msgid "My Sitemaps FAQ" +msgstr "मेरा साइटमैप फैकà¥à¤¸ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:608 +msgid "Recent Donations:" +msgstr "हाल ही में दान" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:611 +msgid "List of the donors" +msgstr "दानदाताओं की सूची" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:613 +msgid "Hide this list" +msgstr "सूची छिपाà¤à¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:616 +msgid "Thanks for your support!" +msgstr "आपके समरà¥à¤¥à¤¨ के लिठधनà¥à¤¯à¤µà¤¾à¤¦!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:638 +msgid "The sitemap wasn't generated yet." +msgstr "साइटमैप अभी तक सृजित नहीं किया गया." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:641 +msgid "Result of the last build process, started on %date%." +msgstr "पिछले निरà¥à¤®à¤¾à¤£ पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ के परिणाम, शà¥à¤°à¥‚ में % तिथि%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:650 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "साइटमैप अभी तक नहीं बनाई गई थी. यहां कà¥à¤²à¤¿à¤• करें पहली बार निरà¥à¤®à¤¾à¤£ करने में " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:656 +msgid "Your sitemap was last built on %date%." +msgstr "आपका साइटमैप पिछले पर बनाया गया था %तिथि ." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:657 +msgid "The last build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "पिछले सफल बनाने, लेकिन बाद में नषà¥à¤Ÿ कर दिया फ़ाइल या अब तक पहà¥à¤à¤šà¤¾ नहीं जा सकता था. कà¥à¤¯à¤¾ तà¥à¤® à¤à¤• सरà¥à¤µà¤° या डोमेन को अपने बà¥à¤²à¥‰à¤— में ला सकते हो?" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:659 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "वहाठà¤à¤• अपने साइटमैप फ़ाइल लेखन समसà¥à¤¯à¤¾ थी. सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करें कि फ़ाइल मौजूद है और लिखने योगà¥à¤¯ है.अधिक जानें" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:666 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "आपका साइटमैप(zipped) पिछले पर बनाया गया था %तिथि%." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:667 +msgid "The last zipped build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "पिछले ज़िपित सफल बनी, लेकिन बाद में फ़ाइल नषà¥à¤Ÿ कर दिया या अब तक पहà¥à¤à¤šà¤¾ नहीं जा सकता था." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:669 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "वहाठà¤à¤• ज़िपित साइटमैप फ़ाइल लेखन में समसà¥à¤¯à¤¾ थी. सà¥à¤¨à¤¿à¤¶à¥à¤šà¤¿à¤¤ करें कि फ़ाइल मौजूद है और लिखने योगà¥à¤¯ है. अधिक जानें" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:675 +msgid "Google was successfully notified about changes." +msgstr "गूगल थी सफलतापूरà¥à¤µà¤• अधिसूचित परिवरà¥à¤¤à¤¨ के बारे में." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:678 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "इसे लेकर % समय% सेकंड के लिठGoogle को सूचित करे,शायद आप इस सà¥à¤µà¤¿à¤§à¤¾ को अकà¥à¤·à¤® करने का निरà¥à¤®à¤¾à¤£ समय को कम के लिठकरे." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:681 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "वहाठथोड़ी देर के लिठगूगल सूचित समसà¥à¤¯à¤¾ थी. देखें परिणाम" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:687 +msgid "YAHOO was successfully notified about changes." +msgstr "याहू परिवरà¥à¤¤à¤¨ के बारे में सफलतापूरà¥à¤µà¤• अधिसूचित था" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:690 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "यह याहू %समय% सेकंड में सूचित करे,शायद आप इस सà¥à¤µà¤¿à¤§à¤¾ को अकà¥à¤·à¤® करने का निरà¥à¤®à¤¾à¤£ समय को कम करने के लिठकरे." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:693 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "यहाठयाहू को सूचित करने में समसà¥à¤¯à¤¾ थी, देखें परिणाम " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:699 +msgid "Bing was successfully notified about changes." +msgstr "बिंग सफलतापूरà¥à¤µà¤• / b> परिवरà¥à¤¤à¤¨ के बारे में <अधिसूचित था." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:702 +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "यह बिंग को %समय% सेकंड में सूचित करे,शायद आप इस सà¥à¤µà¤¿à¤§à¤¾ को अकà¥à¤·à¤® करने का निरà¥à¤®à¤¾à¤£ समय को कम करने के लिठकरे." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:705 +#, php-format +msgid "There was a problem while notifying Bing. View result" +msgstr "यहाठबिंग को सूचित करने में समसà¥à¤¯à¤¾ थी, देखें परिणाम " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:711 +msgid "Ask.com was successfully notified about changes." +msgstr "अशà¥à¤•.कॉम सफलतापूरà¥à¤µà¤• / b> परिवरà¥à¤¤à¤¨ के बारे में <अधिसूचित था." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:714 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "यह अशà¥à¤•.कॉम को %समय% सेकंड में सूचित करे,शायद आप इस सà¥à¤µà¤¿à¤§à¤¾ को अकà¥à¤·à¤® करने का निरà¥à¤®à¤¾à¤£ समय को कम करने के लिठकरे." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:717 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "यहाठअशà¥à¤•.कॉम को सूचित करने में समसà¥à¤¯à¤¾ थी, देखें परिणाम " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:725 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "निरà¥à¤®à¤¾à¤£ की पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ % समय% सेकंड लेगी पूरी तरह पूरा करने में और इसà¥à¤¤à¥‡à¤®à¤¾à¤²% सà¥à¤®à¥ƒà¤¤à¤¿ % MB सà¥à¤®à¥ƒà¤¤à¤¿ करेगी. " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:727 +msgid "The building process took about %time% seconds to complete." +msgstr "निरà¥à¤®à¤¾à¤£ की पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ % समय% सेकंड लेगी पूरी तरह पूरा करने में" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:731 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "आपके साइटमैप की सामगà¥à¤°à¥€ नहीं बदल पिछली बार के बाद से तो फाइल लिखा नहीं खोज इंजन pinged नहीं था और थे." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:739 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "निरà¥à¤®à¤¾à¤£ की पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ अब भी सकà¥à¤°à¤¿à¤¯ हो सकती है! कà¥à¤› ही सेकंड में पृषà¥à¤  पà¥à¤¨à¤ƒ लोड करे और जांच करे अगर कà¥à¤› बदल गया है." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:742 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "पिछले भाग समापà¥à¤¤ नहीं किया! यद तà¥à¤®à¥à¤¹à¥‡à¤‚ याद हो या समय PHP लिपियों के लिठसीमा बढ़ा सकते हैं अधिक जानें" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ थी की अंतिम जà¥à¤žà¤¾à¤¤ मेमोरी उपयोग %memused%MB,पने सरà¥à¤µà¤° की सीमा% memlimit% है." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:748 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ की अंतिम जà¥à¤žà¤¾à¤¤ निषà¥à¤ªà¤¾à¤¦à¤¨ समय %timeused% seconds, अपने सरà¥à¤µà¤° की सीमा% timelimit% सेकंड है." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:752 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ के बाद आसपास की संखà¥à¤¯à¤¾ रोका %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:755 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "यदि सरà¥à¤µà¤° या बà¥à¤²à¥‰à¤— पर कà¥à¤› बदल गया है ,आपका <साइटमैप पà¥à¤¨à¤°à¥à¤¨à¤¿à¤°à¥à¤®à¤¾à¤£ / a> मैनà¥à¤¯à¥à¤…ल रूप से होना चाहिà¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:757 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "यदि आप किसी भी समसà¥à¤¯à¤¾à¤“ं का सामना पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ बनाने के साथ सकते हैं आप उपयोग कर सकते हैं समारोह डिबग के बारे में अधिक जानकारी पाने के लिà¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:764 +msgid "Basic Options" +msgstr "मूलभूत विकलà¥à¤ª" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:766 +msgid "Sitemap files:" +msgstr "साइटमैप फ़ाइलें हैं:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:766 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:781 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:801 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:834 +msgid "Learn more" +msgstr "अधिक जानें" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3049 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:771 +msgid "Write a normal XML file (your filename)" +msgstr "à¤à¤• सामानà¥à¤¯ XML फ़ाइल लिखना (आपकी फ़ाइल नाम)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3055 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "लिखें gzipped फ़ाइल (फ़ाइल नाम आपके + gz.)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:781 +msgid "Building mode:" +msgstr "निरà¥à¤®à¤¾à¤£ मोड:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "पà¥à¤¨à¤°à¥à¤¨à¤¿à¤°à¥à¤®à¤¾à¤£ साइटमैप यदि आप अपने बà¥à¤²à¥‰à¤— की सामगà¥à¤°à¥€ को बदलते है " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:793 +msgid "Enable manual sitemap building via GET Request" +msgstr "सकà¥à¤·à¤® मैनà¥à¤…ल के जरिठसाइटमैप निरà¥à¤®à¤¾à¤£ अनà¥à¤°à¥‹à¤§ पà¥à¤°à¤¾à¤ªà¥à¤¤" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:797 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the result box above to see if sitemap was successfully built." +msgstr "यह आप अपने साइटमैप ताज़ा करने की अनà¥à¤®à¤¤à¤¿ देगा अगर à¤à¤• बाहà¥à¤¯ उपकरण WordPress API का उपयोग किठबिना WordPress डेटाबेस में लिखा था. निमà¥à¤¨à¤²à¤¿à¤–ित यूआरà¤à¤² का पà¥à¤°à¤¯à¥‹à¤— करें पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ शà¥à¤°à¥‚ करने के %1 लिà¤: कृपया ऊपर परिणाम बॉकà¥à¤¸ को चेक करें यदि साइटमैप सफलतापूरà¥à¤µà¤• बनाया गया था देखने" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:801 +msgid "Update notification:" +msgstr "अदà¥à¤¯à¤¤à¤¨ सूचना:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:805 +msgid "Notify Google about updates of your Blog" +msgstr "सूचित करे आपके बà¥à¤²à¥‰à¤— के अदà¥à¤¯à¤¤à¤¨ के बारे में गूगल" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:806 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "कोई पंजीकरण की आवशà¥à¤¯à¤•ता नहीं है, लेकिन आप शामिल हो सकते हैं गूगल वेबमासà¥à¤Ÿà¤° उपकरण आà¤à¤•ड़ों को खंगालने की जाà¤à¤š करें." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:810 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "बिंग सूचित करे आपके बà¥à¤²à¥‰à¤— के अदà¥à¤¯à¤¤à¤¨ के बारे में (पूरà¥à¤µ MSN लाइव खोज)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:811 +#, php-format +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "कोई पंजीकरण की आवशà¥à¤¯à¤•ता नहीं है, लेकिन आप शामिल हो सकते हैं गूगल वेबमासà¥à¤Ÿà¤° उपकरण आà¤à¤•ड़ों को खंगालने की जाà¤à¤š करें." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:815 +msgid "Notify Ask.com about updates of your Blog" +msgstr "अशà¥à¤•.कॉम को सूचित करे आपके बà¥à¤²à¥‰à¤— के अदà¥à¤¯à¤¤à¤¨ के बारे में " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:816 +msgid "No registration required." +msgstr "कोई पंजीकरण की आवशà¥à¤¯à¤•ता नहीं है," + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:820 +msgid "Notify YAHOO about updates of your Blog" +msgstr "याहू को सूचित करे आपके बà¥à¤²à¥‰à¤— के अदà¥à¤¯à¤¤à¤¨ के बारे में " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:821 +msgid "Your Application ID:" +msgstr "आपका आवेदन आईडी:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "कà¥à¤¯à¤¾ नहीं है?यहाठà¤à¤• अनà¥à¤°à¥‹à¤§ करे! %s2" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:827 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "जोड़ें आभासी robots.txt फ़ाइल के लिठURL साइटमैप." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:831 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "आभासी WordPress दà¥à¤µà¤¾à¤°à¤¾ उतà¥à¤ªà¤¨à¥à¤¨ robots.txt पà¥à¤°à¤¯à¥‹à¤— किया जाता है. à¤à¤• असली robots.txt फ़ाइल बà¥à¤²à¥‰à¤— निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा में मौजूद नहीं होगा!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:834 +msgid "Advanced options:" +msgstr "उनà¥à¤¨à¤¤ विकलà¥à¤ª हैं:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:837 +msgid "Limit the number of posts in the sitemap:" +msgstr "साइटमैप में पदों की संखà¥à¤¯à¤¾ सीमा:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:837 +msgid "Newer posts will be included first" +msgstr "नठपदों को पहले शामिल किया जाà¤à¤—ा" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:840 +msgid "Try to increase the memory limit to:" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ सीमा बढ़ाने की कोशिश करें:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:840 +msgid "e.g. \"4M\", \"16M\"" +msgstr "e.g. \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:843 +msgid "Try to increase the execution time limit to:" +msgstr "सà¥à¤®à¥ƒà¤¤à¤¿ सीमा बढ़ाने की कोशिश करें:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:843 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "सेकंड में, e.g. \"60\" or \"0\" के लिठअसीमित" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:847 +msgid "Include a XSLT stylesheet:" +msgstr "à¤à¤• XSLT stylesheet शामिल करें:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:848 +msgid "Full or relative URL to your .xsl file" +msgstr "पूरà¥à¤£ या अपने रिशà¥à¤¤à¥‡à¤¦à¤¾à¤°. Xsl फ़ाइल के लिठURL" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:848 +msgid "Use default" +msgstr " डिफ़ॉलà¥à¤Ÿ का पà¥à¤°à¤¯à¥‹à¤— करें" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:854 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "सकà¥à¤·à¤® MySQL मानक मोड. यह सिरà¥à¤« अगर हो रही है MySQL तà¥à¤°à¥à¤Ÿà¤¿à¤¯à¥‹à¤‚ का पà¥à¤°à¤¯à¥‹à¤— करें. (आवशà¥à¤¯à¤•ताओं अधिक सà¥à¤®à¥ƒà¤¤à¤¿!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:855 +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "अदà¥à¤¯à¤¤à¤¨ में कम से कम 2.2 के लिठWordPress तेजी से सकà¥à¤·à¤® करने के लिठMySQL का उपयोग" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:862 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "निरà¥à¤®à¤¾à¤£ की पà¥à¤°à¤•à¥à¤°à¤¿à¤¯à¤¾ में à¤à¤• पृषà¥à¤ à¤­à¥‚मि साइटमैप (आप के लिठइंतजार करना तà¥à¤® à¤à¤• के बाद जब बचाने के लिठनहीं है)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "अदà¥à¤¯à¤¤à¤¨ में कम से कम 2.1 के लिठWordPress पृषà¥à¤ à¤­à¥‚मि निरà¥à¤®à¤¾à¤£ सकà¥à¤·à¤® करने के लिà¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:870 +msgid "Additional pages" +msgstr "अतिरिकà¥à¤¤ पृषà¥à¤ à¥‹à¤‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:873 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "यहाठआप फ़ाइलों या यूआरà¤à¤² जो साइटमैप में शामिल किया जाना चाहिठनिरà¥à¤¦à¤¿à¤·à¥à¤Ÿ कर सकते हैं, लेकिन आपके बà¥à¤²à¥‰à¤— /WordPress का नहीं.
        उदाहरण के लिà¤,यदि आपके डोमेन www.foo.com और अपने बà¥à¤²à¥‰à¤— पर सà¥à¤¥à¤¿à¤¤ www.foo.com / बà¥à¤²à¥‰à¤— आप www.foo.com पर अपने मà¥à¤–पृषà¥à¤  शामिल करना चाहते हो " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:875 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1097 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1106 +msgid "Note" +msgstr "नोट" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:876 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "यदि आपका बà¥à¤²à¥‰à¤— à¤à¤• subdirectory में है और आप पृषà¥à¤ à¥‹à¤‚ जो बà¥à¤²à¥‰à¤— निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा या नीचे में नहीं जोड़ना चाहते हैं, तà¥à¤® जरूरी रूट निरà¥à¤¦à¥‡à¤¶à¤¿à¤•ा में आपके साइटमैप फ़ाइल सà¥à¤¥à¤¾à¤¨ (आपके साइटमैप फ़ाइल \"सà¥à¤¥à¤¾à¤¨ पर देखो इस पृषà¥à¤  पर\" अनà¥à¤­à¤¾à¤—)!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:878 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:917 +msgid "URL to the page" +msgstr "पृषà¥à¤  के यूआरà¤à¤²" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:879 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "पृषà¥à¤  के URL दरà¥à¤œ करें. उदाहरण: http://www.foo.com/index.html or www.foo.com/home " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:881 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:918 +msgid "Priority" +msgstr "पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:882 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "षà¥à¤  की पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता के अनà¥à¤¯ पनà¥à¤¨à¥‹à¤‚ के सापेकà¥à¤· चà¥à¤¨à¥‡à¤‚. उदाहरण के लिà¤, अपने होमपेज पर अपनी छाप से à¤à¤• उचà¥à¤š पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता होगी." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:920 +msgid "Last Changed" +msgstr "पिछले परिवरà¥à¤¤à¤¿à¤¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:885 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "पिछले परिवरà¥à¤¤à¤¨ के रूप में की तारीख दरà¥à¤œ करें YYYY-MM-DD (उदाहरण के लिठ2005/12/31)(वैकलà¥à¤ªà¤¿à¤•)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:919 +msgid "Change Frequency" +msgstr "बदलें आवृतà¥à¤¤à¤¿" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:921 +msgid "#" +msgstr "#" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:926 +msgid "No pages defined." +msgstr "कोई परिभाषित पृषà¥à¤ à¥‹à¤‚ नहीं." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:931 +msgid "Add new page" +msgstr "नया पृषà¥à¤  जोड़ें" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:936 +msgid "Post Priority" +msgstr "पोसà¥à¤Ÿ पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:938 +msgid "Please select how the priority of each post should be calculated:" +msgstr "कृपया चयन करे कैसे पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• पोसà¥à¤Ÿ की पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता की गणना की जानी चाहिà¤:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:940 +msgid "Do not use automatic priority calculation" +msgstr "सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता गणना का पà¥à¤°à¤¯à¥‹à¤— न करें" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:940 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "सभी पदों को ही पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता होगी जो परिभाषित है में " पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ताओं "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3348 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:951 +msgid "Location of your sitemap file" +msgstr "आपके साइटमैप के सà¥à¤¥à¤¾à¤¨ फाइल" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3353 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:954 +msgid "Automatic detection" +msgstr "सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ पहचान" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3357 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:958 +msgid "Filename of the sitemap file" +msgstr "साइटमैप फ़ाइल का फ़ाइल नाम" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:961 +msgid "Detected Path" +msgstr "पता पथ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:961 +msgid "Detected URL" +msgstr "पता पथ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3365 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:966 +msgid "Custom location" +msgstr "पसंदीदा सà¥à¤¥à¤¾à¤¨" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3369 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:970 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "निरपेकà¥à¤· या रिशà¥à¤¤à¥‡à¤¦à¤¾à¤° साइटमैप फ़ाइल के पथ, नाम भी शामिल है." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3371 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3380 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:972 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:981 +msgid "Example" +msgstr "उदाहरण" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:979 +msgid "Complete URL to the sitemap file, including name." +msgstr "पूरा साइटमैप फ़ाइल यूआरà¤à¤², नाम भी शामिल है." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:992 +msgid "Sitemap Content" +msgstr "साइटमैप सामगà¥à¤°à¥€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:998 +msgid "Include homepage" +msgstr "शामिल मà¥à¤–पृषà¥à¤ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1004 +msgid "Include posts" +msgstr "शामिल पदों" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "शामिल बहॠके अगले पृषà¥à¤  का पद (वृदà¥à¤§à¤¿ समय और सà¥à¤®à¥ƒà¤¤à¤¿ के उपयोग का निरà¥à¤®à¤¾à¤£!)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1016 +msgid "Include static pages" +msgstr "शामिल सà¥à¤¥à¥ˆà¤¤à¤¿à¤• पृषà¥à¤ à¥‹à¤‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1022 +msgid "Include categories" +msgstr "शामिल शà¥à¤°à¥‡à¤£à¤¿à¤¯à¤¾à¤‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1028 +msgid "Include archives" +msgstr "शामिल अभिलेखागार" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1035 +msgid "Include tag pages" +msgstr "शामिल टैग पृषà¥à¤ " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1051 +#, php-format +msgid "Include taxonomy pages for %s" +msgstr "शामिल पृषà¥à¤ à¥‹à¤‚ के वरà¥à¤—ीकरण के लिठ%s" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1061 +msgid "Include author pages" +msgstr "शामिल लेखक पृषà¥à¤ " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1065 +msgid "Further options" +msgstr "इसके अलावा विकलà¥à¤ª" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1070 +msgid "Include the last modification time." +msgstr "अंतिम संशोधन का समय शामिल करें." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1072 +msgid "This is highly recommended and helps the search engines to know when your content has changed. This option affects all sitemap entries." +msgstr "यह अतà¥à¤¯à¤§à¤¿à¤• की सिफारिश की है और खोज इंजन में मदद करता है पता है जब आपके सामगà¥à¤°à¥€ बदल गया है. इस विकलà¥à¤ª को पà¥à¤°à¤­à¤¾à¤µà¤¿à¤¤ करता है सभी साइटमैप दरà¥à¤œ की हैं." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1079 +msgid "Excluded items" +msgstr "अपवरà¥à¤œà¤¿à¤¤ आइटम" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1081 +msgid "Excluded categories" +msgstr "अपवरà¥à¤œà¤¿à¤¤ शà¥à¤°à¥‡à¤£à¤¿à¤¯à¤¾à¤‚" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1083 +msgid "Using this feature will increase build time and memory usage!" +msgstr "इस सà¥à¤µà¤¿à¤§à¤¾ का उपयोग समय और मेमोरी उपयोग के निरà¥à¤®à¤¾à¤£ में वृदà¥à¤§à¤¿ होगी!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1090 +#, php-format +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "इस सà¥à¤µà¤¿à¤§à¤¾ की आवशà¥à¤¯à¤•ता कम से कम 2.5.1 WordPress,तà¥à¤® पà¥à¤°à¤¯à¥‹à¤— कर रहे हैं %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1093 +msgid "Exclude posts" +msgstr "बाहर निकालने के पदों" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1095 +msgid "Exclude the following posts or pages:" +msgstr "निमà¥à¤¨à¤²à¤¿à¤–ित पदों या पेज बाहर निकालें:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1095 +msgid "List of IDs, separated by comma" +msgstr "आईडी की सूची, अलà¥à¤ªà¤µà¤¿à¤°à¤¾à¤® के दà¥à¤µà¤¾à¤°à¤¾ अलग" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1097 +msgid "Child posts won't be excluded automatically!" +msgstr "बचà¥à¤šà¥‡ के पदों को सà¥à¤µà¤šà¤¾à¤²à¤¿à¤¤ रूप से बाहर नहीं जाà¤à¤—ा!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1103 +msgid "Change frequencies" +msgstr "बदलें आवृतà¥à¤¤à¤¿à¤¯à¥‹à¤‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1107 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "कृपया धà¥à¤¯à¤¾à¤¨ दें कि इस टैग का मूलà¥à¤¯ à¤à¤• और संकेत à¤à¤• आदेश माना जाता है.हालांकि खोज इंजन crawlers जब इस निरà¥à¤£à¤¯ की जानकारी विचार,वे चिहà¥à¤¨à¤¿à¤¤ पृषà¥à¤ à¥‹à¤‚ कà¥à¤°à¥‰à¤² कर सकते हैं \"पà¥à¤°à¤¤à¤¿ घंटा \" है कि कम से अकà¥à¤¸à¤°, और वे पृषà¥à¤  कà¥à¤°à¥‰à¤² के रूप में चिहà¥à¤¨à¤¿à¤¤ कर सकते हैं \"वारà¥à¤·à¤¿à¤• \" अधिक से अधिक है कि अकà¥à¤¸à¤°.यह भी संभावना है कि crawlers समय समय पर पृषà¥à¤ à¥‹à¤‚ कà¥à¤°à¥‰à¤² जाà¤à¤—ा चिहà¥à¤¨à¤¿à¤¤ \"कभी \" ताकि वे उन पृषà¥à¤ à¥‹à¤‚ को अपà¥à¤°à¤¤à¥à¤¯à¤¾à¤¶à¤¿à¤¤ परिवरà¥à¤¤à¤¨ संभाल सकता हूà¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1113 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1170 +msgid "Homepage" +msgstr "मà¥à¤–पृषà¥à¤ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1119 +msgid "Posts" +msgstr "डाक" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1125 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1188 +msgid "Static pages" +msgstr "सà¥à¤¥à¥ˆà¤¤à¤¿à¤• पृषà¥à¤ à¥‹à¤‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1131 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1194 +msgid "Categories" +msgstr "शà¥à¤°à¥‡à¤£à¤¿à¤¯à¤¾à¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1137 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "इस महीने की मौजूदा संगà¥à¤°à¤¹ (करना चाहिठअपने होमपेज की तरह ही)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1143 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "पà¥à¤°à¤¾à¤¨à¥‡ अभिलेखागार (परिवरà¥à¤¤à¤¨ केवल अगर तà¥à¤® à¤à¤• पà¥à¤°à¤¾à¤¨à¥€ पोसà¥à¤Ÿ संपादित करें)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1150 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1207 +msgid "Tag pages" +msgstr "टैग पृषà¥à¤ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1157 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1214 +msgid "Author pages" +msgstr "लेखक पृषà¥à¤ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1165 +msgid "Priorities" +msgstr "पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ताà¤à¤‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1176 +msgid "Posts (If auto calculation is disabled)" +msgstr "पदों (यदि सà¥à¤µà¤¤: गणना अकà¥à¤·à¤® है)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1182 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "नà¥à¤¯à¥‚नतम पोसà¥à¤Ÿ पà¥à¤°à¤¾à¤¥à¤®à¤¿à¤•ता (अगर ऑटो गणना सकà¥à¤·à¤® है)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1200 +msgid "Archives" +msgstr "अभिलेखागार" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1225 +msgid "Update options" +msgstr "अदà¥à¤¯à¤¤à¤¨ विकलà¥à¤ª" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1226 +msgid "Reset options" +msgstr "रीसेट विकलà¥à¤ª" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:95 +msgid "XML-Sitemap Generator" +msgstr "XML-साइटमैप जनरेटर" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:95 +msgid "XML-Sitemap" +msgstr "XML - साइटमैप" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:109 +msgid "Settings" +msgstr "सेटिंगà¥à¤¸" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:110 +msgid "FAQ" +msgstr "फैकà¥à¤¸ " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:111 +msgid "Support" +msgstr "सहायता" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:112 +msgid "Donate" +msgstr "दान" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:182 +msgid "Sitemap FAQ" +msgstr "साइटमैप फैकà¥à¤¸" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hu_HU.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hu_HU.mo new file mode 100644 index 0000000..ccbf36a Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hu_HU.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hu_HU.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hu_HU.po new file mode 100644 index 0000000..6d4744e --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-hu_HU.po @@ -0,0 +1,596 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 2502 2005-07-03 20:50:38Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2007-11-05 23:44+0100\n" +"Last-Translator: Cenzi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +msgid "Comment Count" +msgstr "Kommentek számolása" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Kommentek számának felhasználása a fontosság kiszámításához" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +msgid "Comment Average" +msgstr "Kommentek" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +msgid "Uses the average comment count to calculate the priority" +msgstr "Kommentek számolása, hogy a fontosságot megállapíthassa" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +msgid "Popularity Contest" +msgstr "Gyakori tartalom" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" + +msgid "XML-Sitemap Generator" +msgstr "Oldaltérkép generátor" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap" +msgstr "XML-Oldaltérkép" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Köszönjük a támogatást. Segíthez a plugin fejlesztésében, hogy mindez ingyenes maradhasson!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Hide this notice" +msgstr "Tanács elrejtése" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Köszönjük, hogy ezt a plugint használja! Kb. egy hónapja telepítette a plugint. Ha jól működik, és elégedett az eredményekkel, akkor nem adományozna a fejlesztéshez egy keveset? Adományok segíthetnek a fejleszésekben, hogy ez a plugin ingyenes maradhasson! Persze, nem probléma!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +msgid "No thanks, please don't bug me anymore!" +msgstr "Köszönöm, nem. Ne jelenjen meg többet." + +msgid "XML Sitemap Generator for WordPress" +msgstr "Oldaltérkép generátor WordPresshez" + +msgid "Configuration updated" +msgstr "Beállítások frissítve!" + +msgid "Error while saving options" +msgstr "Hiba az oldalak mentésekor" + +msgid "Pages saved" +msgstr "Oldalak mentve" + +msgid "Error while saving pages" +msgstr "Hiba az oldalak mentésekor" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2748 +#, php-format +msgid "Robots.txt file saved" +msgstr "Robots.txt fájl elmentve" + +msgid "Error while saving Robots.txt file" +msgstr "Hiba aa Robots.txt fájl mentésekor" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +msgid "The default configuration was restored." +msgstr "Alap beállítás visszaállítva." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +msgid "open" +msgstr "megnyit" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +msgid "close" +msgstr "bezár" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +msgid "click-down and drag to move this box" +msgstr "kattintson rá, és ragadja meg ezt a dobozt" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +msgid "click to %toggle% this box" +msgstr "kattintson, hogy %toggle% ezt a dobozt" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +msgid "use the arrow keys to move this box" +msgstr "használja a mozgatáshoz a jobbra, balra, fel és le billentyűket" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +msgid ", or press the enter key to %toggle% it" +msgstr ", vagy nyomja meg az enter gombot az %toggle% -hez." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +msgid "About this Plugin:" +msgstr "Pluginról:" + +msgid "Plugin Homepage" +msgstr "Plugin fÅ‘oldal" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +msgid "Notify List" +msgstr "Értesítések" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +msgid "Support Forum" +msgstr "Fórum" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +msgid "Donate with PayPal" +msgstr "Adományozás (PayPal)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +msgid "My Amazon Wish List" +msgstr "My Amazon kívánságlista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_name" +msgstr "Cenzi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_url" +msgstr "http://blog.cenzi.hu" + +msgid "Sitemap Resources:" +msgstr "Oldaltérkép eredmények:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +msgid "Site Explorer" +msgstr "Oldal böngészése" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +msgid "Search Blog" +msgstr "KeresÅ‘ blog" + +msgid "Sitemaps Protocol" +msgstr "Oldaltérkép protokol" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +msgid "Official Sitemaps FAQ" +msgstr "Hivatalos oldaltérképek GYIK" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +msgid "My Sitemaps FAQ" +msgstr "Oldaltérképek GYIK" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +msgid "Recent Donations:" +msgstr "Adományok:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +msgid "List of the donors" +msgstr "Adományozók listája" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +msgid "Hide this list" +msgstr "Lista elrejtése" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +msgid "Thanks for your support!" +msgstr "Köszönjük a támogatást!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +msgid "Status" +msgstr "Ãllapot" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Az oldaltérkép még nem készült el. Kattints ide az elkészítéséhez." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +msgid "Your sitemap was last built on %date%." +msgstr "Az oldaltérkép legutóbbi felépítése: %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreTovábbzipped) was last built on %date%." +msgstr "Az oldaltérképed (tömörésének) ideje: %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreTovábbsuccessfully notified
        about changes." +msgstr "Google sikeresen értesítve lett a változásokról." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "%time% másodpercbe telt a Google értesítése, de kikapcsolható ez a funkció." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Probléma merült fel a Google értesítésénél. Eredmény megtekintése" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOO sikeresen értesítve lett a változásokról." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "%time% másodpercbe telt a YAHOO értesítése, de kikapcsolható ez a funkció." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Probléma merült fel a YAHOO értesítésénél. Eredmény megtekintése" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com sikeresen értesítve lett a változásokról." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "%time% másodpercbe telt a Ask.com értesítése, de kikapcsolható ez a funkció." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Probléma merült fel a Ask.com értesítésénél. Eredmény megtekintése" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Felépítési folyamat kb. %time% másodperc ami %memory% MB memóriát használ fel." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +msgid "The building process took about %time% seconds to complete." +msgstr "Felépítési folyamat kb. %time% másodperc." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Az oldaltérkép tartalma nem változott, ezért nem lesznek a keresők megpingelve." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "Nem sikerült! Talán kevés a memória. Tovább" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "Az utolsó memóriahasználat %memused%MB volt, a memórialimit: %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "Az utolsó script használat %timeused% másodperc, a szervered limite: %timelimit% másodperc." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "A script megállt megközelítőleg a következő bejegyzési számnál: %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Ha valamilyen változás történik a blogodon vagy szervereden, akkor ajánlatos az oldaltérkép újraépítése kézzel." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Ha felmerül valamilyen probléma a felépítési folyamat során, akkor futtasd le a debug funkciót a további információért." + +msgid "Basic Options" +msgstr "Alap beállítások" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +msgid "Sitemap files:" +msgstr "Oldaltérkép fájlok:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Learn more" +msgstr "Tovább" + +msgid "Write a normal XML file (your filename)" +msgstr "Normál XML fájl írása (fájlnév)" + +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Gzippelt fájl írása (fájlév + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +msgid "Building mode:" +msgstr "Felépítési mód:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Oldaltérkép újraépítése, ha a blogod tartalma megváltozott" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +msgid "Enable manual sitemap building via GET Request" +msgstr "Kézi oldaltérkép engedélyezése a GET Request segítségével" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Ez engedélyezni fogja az oldaltérkép frissülését a WordPress adatbázisban. Használd a következő címet a folyamat elindításához: %1 Ellenőrizd a naplózó fájlt, hogy a folyamat befejeződött-e." + +msgid "Update notification:" +msgstr "Frissítési értesítések" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +msgid "Notify Google about updates of your Blog" +msgstr "Google értesítése a blogod frissülésekor" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Nincs szükség a regisztráláshoz, de csatlakozhatsz a Google Webmaster Tools programhoz, hogy ellenőrizhesd a robotok statisztikáját." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Ask.com értesítése a blogod frissítésekor" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +msgid "No registration required." +msgstr "Nincs szükség a regisztrációhoz." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +msgid "Notify YAHOO about updates of your Blog" +msgstr "YAHOO értesítése a blogod frissítésekor" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3094 +#, php-format +msgid "No registration required, but you can sign up for the YAHOO Site Explorer to view the crawling progress." +msgstr "Nincs szükség a regisztráláshoz, de csatlakozhatsz a YAHOO Site Explorer programhoz, hogy ellenőrizhesd a robotok statisztikáját." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3099 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "%s fájl elkészítése vagy módosítása." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3102 +msgid "File permissions: " +msgstr "Fájl engedélyek:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3107 +msgid "OK, robots.txt is writable." +msgstr "OK, robots.txt írható." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3109 +msgid "Error, robots.txt is not writable." +msgstr "Hiba, robots.txt nem írható." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3113 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, robots.txt nem létezik, de a könyvtár írható." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3115 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Hiba, robots.txt nem létezik és a könyvtár nem írható." + +msgid "Advanced options:" +msgstr "Haladó beállítások:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Limit the number of posts in the sitemap:" +msgstr "Bejegyzések számának limitálása az oldaltérképben:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Newer posts will be included first" +msgstr "Újabb bejegyzések előre kerülnek" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "Try to increase the memory limit to:" +msgstr "Próbáld meg a memória limit emelését:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "e.g. \"4M\", \"16M\"" +msgstr "pl. \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "Try to increase the execution time limit to:" +msgstr "Próbáld meg a végrehajtási idő emelését:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "másodpercekben pl. \"60\" vagy \"0\" a korlátlanért" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Include a XSLT stylesheet:" +msgstr "XSLT stíluslap mellékelése:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Use Default" +msgstr "Alapbeállítás használata" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Full or relative URL to your .xsl file" +msgstr "Teljes vagy relatív URL elérése a .xsl fájlhoz" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Alap MySQL mód engedélyezése. Ezt csak akkor használd, ha MySQL hibákat tapasztalsz. (Sokkal több memóriára lesz szükség!)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Háttérfolyamatként építse fel az oldaltérképet (Nem kell várni, amíg a bejegyzést elmented)" + +msgid "Additional pages" +msgstr "Oldalak" + +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Be tudod állítani azokat a fájlokat, amelyek nem tartoznak a blogodhoz.
        Például, ha a domainod www.akarmi.hu és a blogod a www.akarmi.hu/blog címen van, beleteheted a www.akarmi.hu címet is az oldaltérképbe." + +msgid "Note" +msgstr "Megjegyzés" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Ha a blogod egy alkönyvtárban van és olyan oldalakat szeretnél felvenni, amelyek nincsennek a blog könyvtárában, akkor a gyökér könyvtárban kell elhelyeznek az oldaltérképet." + +msgid "URL to the page" +msgstr "Oldal URL-je" + +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Ãrd be az oldal URL-jét. Például: http://www.akarmi.hu/index.html vagy www.akarmi.hu/home" + +msgid "Priority" +msgstr "Fontosság" + +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Válaszd ki az oldalak fontosságát. Például, a kezdÅ‘lapod lehet, hogy fontosabb, mint az aloldalak." + +msgid "Last Changed" +msgstr "Utolsó módosítás" + +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Ãrd be az utolsó módosítást YYYY-MM-DD (példaként: 2007-08-12) (ajánlott)." + +msgid "Change Frequency" +msgstr "Változások gyakorisága" + +msgid "#" +msgstr "#" + +msgid "No pages defined." +msgstr "Nincs oldal beállítva." + +msgid "Add new page" +msgstr "Új oldal felvétele" + +msgid "Post Priority" +msgstr "Bejegyzés fontossága" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Válaszd ki, hogyan működjön a fontosság kalkulálása" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "Do not use automatic priority calculation" +msgstr "Ne használja az automatikus fontosság kalkulálását" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Minden bejegyzés azonos fontosságú ami a "Fontosságok" alatt lett beállítva" + +msgid "Location of your sitemap file" +msgstr "Oldaltérkép fájl elérése" + +msgid "Automatic detection" +msgstr "Automatikus megállapítás" + +msgid "Filename of the sitemap file" +msgstr "Oldaltérkép fájl neve" + +msgid "Detected Path" +msgstr "Elérés" + +msgid "Detected URL" +msgstr "URL megállapítása" + +msgid "Custom location" +msgstr "Egyéni elérés" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Abszolút vagy relatív elérése az oldaltérkép fájlnak (fájl-névvel együtt)." + +msgid "Example" +msgstr "Példa" + +msgid "Complete URL to the sitemap file, including name." +msgstr "Teljes URL-je az oldaltérkép fájlnak (fájl-névvel együtt)." + +msgid "Sitemap Content" +msgstr "Oldaltérkép tartalma" + +msgid "Include homepage" +msgstr "FÅ‘oldal mellékelése" + +msgid "Include posts" +msgstr "Bejegyzések mellékelése" + +msgid "Include static pages" +msgstr "Statikus oldalak mellékelése" + +msgid "Include categories" +msgstr "Kategóriák mellékelése" + +msgid "Include archives" +msgstr "Arhívumok mellékelése" + +msgid "Include tag pages" +msgstr "Címkék oldalak melléklése" + +msgid "Include author pages" +msgstr "SzerzÅ‘ oldalak melléklése" + +msgid "Change frequencies" +msgstr "Változások gyakorisága" + +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." + +msgid "Homepage" +msgstr "FÅ‘oldal" + +msgid "Posts" +msgstr "Bejegyzések" + +msgid "Static pages" +msgstr "Statikus oldal" + +msgid "Categories" +msgstr "Kategóriák" + +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Jelenlegi hónap arhívuma (Megegyezik az oldaladéval)" + +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Régi archívumok (Ha egy régi bejegyzést módosítottál)" + +msgid "Tag pages" +msgstr "Címkék oldalak" + +msgid "Author pages" +msgstr "SzerzÅ‘ oldalak" + +msgid "Priorities" +msgstr "Fontosságok" + +msgid "Posts (If auto calculation is disabled)" +msgstr "Bejegyzések (Ha az automatikus kalkulálás ki van kapcsolva)" + +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Minimum bejegyzések fontossága (Ha az automatikus kalkulálás engedélyezve van)" + +msgid "Archives" +msgstr "Archívumok" + +msgid "Update options" +msgstr "Beállítások frissítése" + +msgid "Reset options" +msgstr "Beállítások visszaállítása" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-it_IT.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-it_IT.mo new file mode 100644 index 0000000..ee8edc7 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-it_IT.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-it_IT.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-it_IT.po new file mode 100644 index 0000000..03aca4c --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-it_IT.po @@ -0,0 +1,938 @@ +msgid "" +msgstr "" +"Project-Id-Version: Google Sitemap Generator in italiano\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-08-24 00:20+0100\n" +"PO-Revision-Date: 2009-08-24 19:14+0100\n" +"Last-Translator: Gianni Diurno (aka gidibao) \n" +"Language-Team: Gianni Diurno | http://gidibao.net/ \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Italian\n" +"X-Poedit-Country: ITALY\n" +"X-Poedit-SourceCharset: utf-8\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:642 +msgid "Comment Count" +msgstr "Numero dei commenti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:654 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Utilizza per calcolare la priorità il numero dei commenti all'articolo" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:714 +msgid "Comment Average" +msgstr "Media dei commenti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:726 +msgid "Uses the average comment count to calculate the priority" +msgstr "Utilizza per calcolare la priorità la media dei commenti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:789 +msgid "Popularity Contest" +msgstr "Popularity Contest" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:801 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Utilizza il plugin attivato a nomePopularity Contest di Alex King. Vai sotto Impostazioni quindi Most Popular Posts" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1191 +msgid "Always" +msgstr "sempre" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1192 +msgid "Hourly" +msgstr "ogni ora" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1193 +msgid "Daily" +msgstr "ogni giorno" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1194 +msgid "Weekly" +msgstr "settimanalmente" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1195 +msgid "Monthly" +msgstr "mensilmente" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1196 +msgid "Yearly" +msgstr "annualmente" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1197 +msgid "Never" +msgstr "mai" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:97 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Grazie per la tua donazione. Mi hai aiutato nel proseguire lo sviluppo ed il supporto per questo plugin e per dell'altro software gratuito!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:97 +msgid "Hide this notice" +msgstr "Nascondi questo annuncio" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:103 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Grazie per l'utilizzo di questo plugin! Tu hai installato questo plugin più di un mese fa. Qualora funzionasse correttamente e tu fossi soddisfatto per i risultati, perché non donarmi un dollaro? Le donazioni mi aiuteranno nel proseguire lo sviluppo ed il supporto per questo plugin gratuito! Ecco la mia offerta!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:103 +msgid "No thanks, please don't bug me anymore!" +msgstr "No grazie. Non scocciarmi più!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:114 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "La tua sitemap sta per essere rigenerata. In relazione alla dimensione del tuo blog potrebbe occorrere un po' di tempo!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:116 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "La tua sitemap verrà rigenerata in %s secondi. In relazione alla dimensione del tuo blog potrebbe occorrere un po' di tempo!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:145 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:448 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Sitemap Generator per WordPress" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:293 +msgid "Configuration updated" +msgstr "Configurazione aggiornata" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:294 +msgid "Error while saving options" +msgstr "Errore durante il savataggio delle opzioni" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:296 +msgid "Pages saved" +msgstr "Pagine salvate" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:297 +msgid "Error while saving pages" +msgstr "Errore durante il salvataggio delle pagine" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:304 +msgid "The default configuration was restored." +msgstr "La configurazione predefinita é stata ripristinata." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:461 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "E' disponibile una nuova versione di %1$s. Scarica qui la versione %3$s." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:463 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "E' disponibile una nuova versione di %1$s. Scarica qui la versione %3$s l'aggiornamento automatico non é disponibile per questo plugin." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:465 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "E' disponibile una nuova versione di %1$s. Scarica qui la versione %3$s oppure aggiorna in automatico." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:488 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:505 +msgid "open" +msgstr "apri" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:489 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:506 +msgid "close" +msgstr "chiudi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:490 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:507 +msgid "click-down and drag to move this box" +msgstr "clicca verso il basso e trascina per spostare questo riquadro" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:491 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:508 +msgid "click to %toggle% this box" +msgstr "clicca per %toggle% questo riquadro" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:492 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:509 +msgid "use the arrow keys to move this box" +msgstr "udsa il tasto freccia per spostare questo riquadro" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:493 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:510 +msgid ", or press the enter key to %toggle% it" +msgstr ", oppure premi il tasto Invio per %toggle%" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:528 +msgid "About this Plugin:" +msgstr "Info plugin:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:529 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:153 +msgid "Plugin Homepage" +msgstr "Plugin Homepage" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:530 +msgid "Suggest a Feature" +msgstr "Suggerimenti" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:531 +msgid "Notify List" +msgstr "Lista notifiche" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:532 +msgid "Support Forum" +msgstr "Forum di supporto" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +msgid "Report a Bug" +msgstr "Segnala un errore" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:535 +msgid "Donate with PayPal" +msgstr "Dona con PayPal" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:536 +msgid "My Amazon Wish List" +msgstr "La mia Amazon Wish List" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:537 +msgid "translator_name" +msgstr "Gianni Diurno" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:537 +msgid "translator_url" +msgstr "http://gidibao.net/" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:540 +msgid "Sitemap Resources:" +msgstr "Risorse Sitemap:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:541 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:547 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:542 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:544 +msgid "Site Explorer" +msgstr "Site Explorer" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:545 +msgid "Search Blog" +msgstr "Search Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:548 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:550 +msgid "Sitemaps Protocol" +msgstr "Protocollo Sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:551 +msgid "Official Sitemaps FAQ" +msgstr "FAQ ufficiale Sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:552 +msgid "My Sitemaps FAQ" +msgstr "La mia Sitemaps FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:555 +msgid "Recent Donations:" +msgstr "Contributi recenti:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:559 +msgid "List of the donors" +msgstr "Lista dei donatori" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:561 +msgid "Hide this list" +msgstr "Nascondi questa lista" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:564 +msgid "Thanks for your support!" +msgstr "Grazie per il tuo supporto!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:584 +msgid "The sitemap wasn't generated yet." +msgstr "La sitemap non é stata ancora generata." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:587 +msgid "Result of the last build process, started on %date%." +msgstr "Risultato dell'ultimo processo di generazione, avviato il %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:596 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "La sitemap non é stata ancora generatat. Clicca qui per costruirla la prima volta." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:602 +msgid "Your sitemap was last built on %date%." +msgstr "La tua sitemap é stata generata il %date%." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:603 +msgid "The last build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "La generazione é avvenuta con successo ma pare che il file é stato cancellato oppure non sia più accessibile. Hai forse spostato il tuo blog su di un altro server oppure hai cambiato il dominio?" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:605 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "Si é verificato un problema durante la scrittura del file sitemap. Assicurati che il file esista e sia scrivibile. Info" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:612 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "La tua sitemap (archivio .zip) é stata generata il %date%." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:613 +msgid "The last zipped build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "La creazione del file .zip é avvenuta con successo ma pare che il file é stato cancellato oppure non sia più accessibile. Hai forse spostato il tuo blog su di un altro server oppure hai cambiato il dominio?" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:615 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "Si é verificato un problema durante la scrittura del file .zip della sitemap. Assicurati che il file esista e sia scrivibile . Info" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:621 +msgid "Google was successfully notified about changes." +msgstr "Google ha ricevuto con successo la notifica dei cambiamenti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:624 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Sono stati necessari %time% secondi per la notifica a Google, meglio disattivare questa funzione in modo tale da poter ridurre i tempi di generazione." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:627 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Si é verificato un errore durante la notifica a Google. Vedi risultato" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:633 +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOO ha ricevuto con successo la notifica dei cambiamenti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:636 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Sono stati necessari %time% secondi per la notifica a YAHOO, meglio disattivare questa funzione in modo tale da poter ridurre i tempi di generazione." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:639 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Si é verificato un errore durante la notifica a YAHOO. Vedi risultato" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3097 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:645 +msgid "Bing was successfully notified about changes." +msgstr "Bing ha ricevuto con successo la notifica dei cambiamenti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:648 +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "Sono stati necessari %time% secondi per la notifica a Bing, meglio disattivare questa funzione in modo tale da poter ridurre i tempi di generazione." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:651 +#, php-format +msgid "There was a problem while notifying Bing. View result" +msgstr "Si é verificato un errore durante la notifica a Bing. Vedi risultato" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:657 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com ha ricevuto con successo la notifica dei cambiamenti." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:660 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Sono stati necessari %time% secondi per la notifica a Ask.com, meglio disattivare questa funzione in modo tale da poter ridurre i tempi di generazione." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:663 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Si é verificato un errore durante la notifica a Ask.com. Vedi risultato" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:671 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Sono stati necessari circa %time% secondi per completare il processo di costruzione e sono stati utilizzati %memory% MB di memoria." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:673 +msgid "The building process took about %time% seconds to complete." +msgstr "Sono stati necessari circa %time% secondi per completare il processo." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:677 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Il contenuto della tua sitemap non cambierà sino all'ultimo momento in modo tale che i file non scritti e nessun motore di ricerca ricevano il ping." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:685 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "La procedura di costruzione é ancora in atto! Ricarica tra alcuni secondi la pagina e verifica quindi se qualcosa fosse cambiato." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:688 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "L'ultima operazione non é ancora conclusa! Forse é necessario che tu aumenti la memoria oppure il limite di tempo per gli scripts PHP. Info" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:690 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "L'ultimo utilizzo di memoria conosciuto per lo script é %memused%MB, il limite del tuo server é %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:694 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "L'ultimo tempo di esecuzione dello script é stato di %timeused% secondi, il limite del tuo server é di %timelimit% secondi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:698 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Lo script si é fermato intorno al post numero %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:701 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Qualora avessi modificato qualcosa nel tuo blog o server dovrai rigenerare la sitemap manualmente." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:703 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Nel caso in cui rilevassi un qualche problema durante il processo di generazione, utilizza la funzione debug per ottenere maggiori informazioni." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:710 +msgid "Basic Options" +msgstr "Opzioni di Base" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:712 +msgid "Sitemap files:" +msgstr "File Sitemap:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:712 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:727 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:747 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Learn more" +msgstr "altre info" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:717 +msgid "Write a normal XML file (your filename)" +msgstr "Scrivi un normale file XML (nome del file)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:723 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Scrivi un file gzip (il nome del file + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:727 +msgid "Building mode:" +msgstr "Modalità generazione:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:732 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Rigenera la sitemap quando cambi il contenuto del tuo blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:739 +msgid "Enable manual sitemap building via GET Request" +msgstr "Abilita la generazione manuale della sitemap via GET Request" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:743 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the result box above to see if sitemap was successfully built." +msgstr "Questa operazione ti permetterà di rigenerare la sitemap qualora uno strumento esterno abbia operato una scrittura nel database di WordPress senza l'utilizzo della WordPress API. Utilizza l'URL a seguire per avviare il processo: %1 Verifica nel registro qui sopra se la generazione della sitemap é avvenuta con successo." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:747 +msgid "Update notification:" +msgstr "Notifica aggiornamenti:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:751 +msgid "Notify Google about updates of your Blog" +msgstr "Segnala a Google gli aggiornamenti del tuo blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:752 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Non é richiesta alcuna registrazione, vedi Google Webmaster Tools per le relative informazioni." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3209 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:756 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "Segnala a Bing (ex MSN Live Search) gli aggiornamenti del tuo blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:757 +#, php-format +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "Non é richiesta alcuna registrazione, vai alla pagina Bing Webmaster Tools per verificare le statistiche." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:761 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Segnala ad Ask.com gli aggiornamenti del tuo blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:762 +msgid "No registration required." +msgstr "Nessuna registrazione necessaria." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:766 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Segnala a YAHOO gli aggiornamenti del tuo blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:767 +msgid "Your Application ID:" +msgstr "La tua ID applicazione:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:768 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "Non hai una chiave? Richiedine qui una! %s2" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:773 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Aggiungi l'URL della sitemap al file virtuale robot.txt " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "Verrà utilizzato il robots.txt virtuale generato da WordPress. Un file robots.txt reale NON deve esistere nella cartella del blog!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Advanced options:" +msgstr "Opzioni avanzate:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "Limit the number of posts in the sitemap:" +msgstr "Numero limite di articoli presenti nella sitemap:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "Newer posts will be included first" +msgstr "gli articoli più recenti verranno inclusi per primi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "Try to increase the memory limit to:" +msgstr "Prova ad aumentare il limite di memoria a:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "e.g. \"4M\", \"16M\"" +msgstr "es. \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:789 +msgid "Try to increase the execution time limit to:" +msgstr "Prova ad aumentare il limite del tempo di esecuzione a:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:789 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "in secondi, es. \"60\" o \"0\" per nessun limite" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:793 +msgid "Include a XSLT stylesheet:" +msgstr "Includi un foglio di stile XSLT: " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:794 +msgid "Full or relative URL to your .xsl file" +msgstr "URL al tuo file .xsl " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:794 +msgid "Use default" +msgstr "Utilizza predefinito" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:800 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Abilita la modalità MySQL standard. Solo in caso di errori MySQL. (ampio utilizzo della memoria!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:801 +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "Aggiorna almeno a WordPress 2.2 per attivare un accesso MySQL più veloce" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:808 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Costruisci la sitemap con una procedura in background (nessuna attesa durante il salvataggio di un articolo)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:809 +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "Aggiorna almeno a WordPress 2.1 per attivare la generazione in background" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:816 +msgid "Additional pages" +msgstr "Pagine aggiuntive" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:819 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Qui è possibile specificare file o URL che dovranno venir incluse nella sitemap ma che non appartengono al vostro Blog/WordPress.
        Ad esempio, se il vostro dominio è www.foo.com ed il vostro blog è posizionato in www.foo.com/blog potreste voler includere la vostra homepage in www.foo.com" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:821 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1024 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1033 +msgid "Note" +msgstr "Nota" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Se il tuo blog fosse allocato in una sottodirectory e desiderassi aggiungere delle pagine che NON si trovano nella directory del blog o sotto di essa, DOVRAI posizionare il tuo file di sitemap nella directory radice (vedi la sezione "Posizione del file di sitemap" su questa pagina)!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:824 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "URL to the page" +msgstr "URL della pagina" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:825 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "inserire la URL della pagina. Ad esempio: http://www.foo.com/index.html oppure www.foo.com/home " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:827 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:864 +msgid "Priority" +msgstr "Priorità" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:828 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "scegli la priorità di questa pagina in relazione alle altre. Ad esempio, la tua homepage dovrebbe avere una priorità maggiore rispetto alle altre pagine." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:830 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:866 +msgid "Last Changed" +msgstr "Ultima modifica" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:831 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Inserisci la data dell'ultima modifica nel formato YYYY-MM-DD (ad esempio 2005-12-31) (opzionale)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:865 +msgid "Change Frequency" +msgstr "Cambia frequenza" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:867 +msgid "#" +msgstr "#" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:872 +msgid "No pages defined." +msgstr "Nessuna pagina definita" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:877 +msgid "Add new page" +msgstr "Aggiungi nuova pagina" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:882 +msgid "Post Priority" +msgstr "Priorità articolo" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:884 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Seleziona come deve essere calcolata la priorità per ogni articolo:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:886 +msgid "Do not use automatic priority calculation" +msgstr "Non utilizzare il calcolo automatico della priorità" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:886 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Tutti gli articoli hanno la stessa priorità definita in "Prioritià"" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:897 +msgid "Location of your sitemap file" +msgstr "Posizione del file di sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:900 +msgid "Automatic detection" +msgstr "Rilevazione automatica" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:904 +msgid "Filename of the sitemap file" +msgstr "Nome del file di sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:907 +msgid "Detected Path" +msgstr "Percorso determinato" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:907 +msgid "Detected URL" +msgstr "URL determinata" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:912 +msgid "Custom location" +msgstr "Località personalizzata" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:916 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Percorso" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:927 +msgid "Example" +msgstr "Esempio" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:925 +msgid "Complete URL to the sitemap file, including name." +msgstr "URL completa al file di sitemap, compreso il nome del file" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:938 +msgid "Sitemap Content" +msgstr "Contenuto sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:944 +msgid "Include homepage" +msgstr "Includi homepage" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:950 +msgid "Include posts" +msgstr "Includi articoli" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:911 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:956 +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "Includi le seguenti pagine di articoli pagina-multipla (incrementa il tempo di generazione e l'utilizzo di memoria!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:962 +msgid "Include static pages" +msgstr "Includi pagine statiche" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:968 +msgid "Include categories" +msgstr "Includi categorie" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:974 +msgid "Include archives" +msgstr "Includi gli archivi" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:981 +msgid "Include tag pages" +msgstr "Includi pagine tag" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:988 +msgid "Include author pages" +msgstr "Includi pagine autore" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:992 +msgid "Further options" +msgstr "Opzioni aggiuntive" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:997 +msgid "Include the last modification time." +msgstr "Includi ora dell'ultima modifica." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:999 +msgid "This is highly recommended and helps the search engines to know when your content has changed. This option affects all sitemap entries." +msgstr "Questa operazione é altamente raccomandata poiché aiuta i motori di ricerca a conoscere quando sono stati modificati i contenuti. Questa opzione avrà influenza su tutti i contenuti della sitemap." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1006 +msgid "Excluded items" +msgstr "Escludi elementi" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1008 +msgid "Excluded categories" +msgstr "Categorie escluse" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1010 +msgid "Using this feature will increase build time and memory usage!" +msgstr "l'utilizzo di questa funzione aumenterà il tempo di generazione e l'utilizzo di memoria!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1017 +#, php-format +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "Questa funzione richiede come minimo WordPress 2.5.1, tu stai usando %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1020 +msgid "Exclude posts" +msgstr "Escludi articoli" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1022 +msgid "Exclude the following posts or pages:" +msgstr "Escludi i seguenti articoli o pagine:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1022 +msgid "List of IDs, separated by comma" +msgstr "separa tra loro con una virgola i vari ID" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1024 +msgid "Child posts won't be excluded automatically!" +msgstr "gli articoli child non saranno automaticamente esclusi!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1030 +msgid "Change frequencies" +msgstr "Modifica frequenze" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1034 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Si noti che il valore di questo tag è da considerarsi un suggerimento e non un comando. Anch se i motori di ricerca prendono in considerazione questa informazione quando decidono cosa indicizzare, potrebbero comunque indicizzare le pagine marcate \"ogni ora\" meno frequentemente così come potrebbero analizzare le pagine marcate come \"annualmente\" più frequentemente. È anche probabile che i moori analizzino periodicamente anche le pagine marcate con \"mai\" per gestire eventuali modifiche inaspettate in queste pagine." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1040 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1097 +msgid "Homepage" +msgstr "Homepage" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1046 +msgid "Posts" +msgstr "Articoli" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1052 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1115 +msgid "Static pages" +msgstr "Pagine statiche" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1058 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1121 +msgid "Categories" +msgstr "Categorie" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1064 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Archivo del mese corrente (dovrebbe avere lo stesso valore della homepage)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1070 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Archivi precedenti (cambia solo se modificato un vecchio articolo)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1077 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1134 +msgid "Tag pages" +msgstr "Pagine tag" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1141 +msgid "Author pages" +msgstr "Pagine autore" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1092 +msgid "Priorities" +msgstr "Priorità" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1103 +msgid "Posts (If auto calculation is disabled)" +msgstr "Articoli (se disabilitato il calcolo automatico)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1109 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Priorità minima degli articoli (anche se fosse stato abilitato il calcolo automatico)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1127 +msgid "Archives" +msgstr "Archivi" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1152 +msgid "Update options" +msgstr "Aggiorna le opzioni" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1153 +msgid "Reset options" +msgstr "Ripristina le opzioni" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:87 +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:87 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:101 +msgid "Settings" +msgstr "Impostazioni" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:102 +msgid "FAQ" +msgstr "FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:103 +msgid "Support" +msgstr "Supporto" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:104 +msgid "Donate" +msgstr "Donazione" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:154 +msgid "Sitemap FAQ" +msgstr "Sitemap FAQ" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja.mo new file mode 100644 index 0000000..f886dfa Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja.po new file mode 100644 index 0000000..7ffe134 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja.po @@ -0,0 +1,604 @@ +# Translation of Google XML Sitemaps in Japanese +# This file is distributed under the same license as the Google XML Sitemaps package. +msgid "" +msgstr "" +"PO-Revision-Date: 2014-04-06 01:07:14+0000\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: GlotPress/0.1\n" +"Project-Id-Version: Google XML Sitemaps\n" + +#: sitemap-ui.php:782 +msgid "Allow anonymous statistics (no personal information)" +msgstr "匿åã®çµ±è¨ˆã‚’許å¯ã™ã‚‹ï¼ˆå€‹äººæƒ…å ±ã¯å«ã¾ã‚Œã¾ã›ã‚“)" + +#: sitemap-ui.php:776 +msgid "(The required PHP XSL Module is not installed)" +msgstr "(å¿…è¦ãªPHPã®XSLモジュールãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“)" + +#: sitemap-core.php:536 +msgid "Comment Count" +msgstr "コメント数" + +#: sitemap-core.php:546 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "コメント数ã‹ã‚‰æŠ•稿ã®å„ªå…ˆé †ä½ã‚’計算ã™ã‚‹" + +#: sitemap-core.php:599 +msgid "Comment Average" +msgstr "å¹³å‡ã‚³ãƒ¡ãƒ³ãƒˆæ•°" + +#: sitemap-core.php:609 +msgid "Uses the average comment count to calculate the priority" +msgstr "å¹³å‡ã‚³ãƒ¡ãƒ³ãƒˆæ•°ã‚’使ã£ã¦å„ªå…ˆé †ä½ã‚’計算ã™ã‚‹" + +#: sitemap-core.php:770 +msgid "Always" +msgstr "常時" + +#: sitemap-core.php:771 +msgid "Hourly" +msgstr "毎時" + +#: sitemap-core.php:772 +msgid "Daily" +msgstr "毎日" + +#: sitemap-core.php:773 +msgid "Weekly" +msgstr "毎週" + +#: sitemap-core.php:774 +msgid "Monthly" +msgstr "毎月" + +#: sitemap-core.php:775 +msgid "Yearly" +msgstr "毎年" + +#: sitemap-core.php:776 +msgid "Never" +msgstr "æ›´æ–°ãªã—" + +#: sitemap-loader.php:218 +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +#: sitemap-loader.php:218 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +#: sitemap-loader.php:246 +msgid "Settings" +msgstr "設定" + +#: sitemap-loader.php:247 +msgid "FAQ" +msgstr "FAQ" + +#: sitemap-loader.php:248 +msgid "Support" +msgstr "サãƒãƒ¼ãƒˆ" + +#: sitemap-loader.php:249 +msgid "Donate" +msgstr "寄付" + +#: sitemap-ui.php:630 +msgid "Plugin Homepage" +msgstr "プラグインã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸" + +#: sitemap-ui.php:652 +msgid "My Sitemaps FAQ" +msgstr "Sitemaps プラグイン FAQ" + +#: sitemap-ui.php:198 sitemap-ui.php:585 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Sitemap Generator for WordPress" + +#: sitemap-ui.php:374 +msgid "Configuration updated" +msgstr "設定を更新ã—ã¾ã—ãŸã€‚" + +#: sitemap-ui.php:375 +msgid "Error while saving options" +msgstr "設定ã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚" + +#: sitemap-ui.php:378 +msgid "Pages saved" +msgstr "追加ページã®è¨­å®šã‚’ä¿å­˜ã—ã¾ã—ãŸã€‚" + +#: sitemap-ui.php:379 +msgid "Error while saving pages" +msgstr "追加ページã®è¨­å®šã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚" + +#: sitemap-ui.php:387 +msgid "The default configuration was restored." +msgstr "åˆæœŸè¨­å®šã«æˆ»ã—ã¾ã—ãŸã€‚" + +#: sitemap-ui.php:397 +msgid "The old files could NOT be deleted. Please use an FTP program and delete them by yourself." +msgstr "å¤ã„ファイルãŒå‰Šé™¤ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚FTPプログラムを利用ã—ã¦ã”自身ã§ãれらを消去ã—ã¦ã„ãŸã ãã¾ã™ã‚ˆã†ãŠé¡˜ã„ã„ãŸã—ã¾ã™ã€‚" + +#: sitemap-ui.php:399 +msgid "The old files were successfully deleted." +msgstr "å¤ã„ãƒ•ã‚¡ã‚¤ãƒ«ã¯æ­£ã—ã削除ã•れã¾ã—ãŸã€‚" + +#: sitemap-ui.php:439 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "寄付をã‚りãŒã¨ã†ã”ã–ã„ã¾ã™ã€‚ã‚ãªãŸã®å”力ã«ã‚ˆã‚Šã€ã“ã®ãƒ—ラグインやãã®ä»–ã®ç„¡æ–™ã‚½ãƒ•トã®ã‚µãƒãƒ¼ãƒˆã‚„開発を続ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã™ !" + +#: sitemap-ui.php:439 +msgid "Hide this notice" +msgstr "ã“ã®é€šçŸ¥ã‚’éš ã™" + +#: sitemap-ui.php:445 +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and you are satisfied with the results, isn't it worth at least a few dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "ã“ã®ãƒ—ラグインをã”利用ã„ãŸã ãã‚りãŒã¨ã”ã–ã„ã¾ã™ï¼ãƒ—ラグインをインストールã—ã¦ã‹ã‚‰ä¸€ã‹æœˆä»¥ä¸ŠãŒçµŒéŽã—ã¾ã—ãŸã€‚ã‚‚ã—動作ã—ã¦ã€ãã®æˆæžœã«ã”満足ã„ãŸã ã‘ã¦ãŸã®ã§ã‚れã°ã€å°‘ãªãã¨ã‚‚数ドルã«å€¤ã—ã¾ã›ã‚“ã§ã—ょã†ã‹ï¼Ÿå¯„付ã¯ç§ãŒã“ã®ãƒ•リーソフトウェアã®ã‚µãƒãƒ¼ãƒˆã¨é–‹ç™ºã‚’ç¶šã‘ã‚‹ãŸã‚ã«å½¹ç«‹ã¡ã¾ã™ï¼åˆ†ã‹ã‚Šã¾ã—ãŸã€ãã®é€šã‚Šã§ã™ï¼" + +#: sitemap-ui.php:445 +msgid "Sure, but I already did!" +msgstr "分ã‹ã‚Šã¾ã—ãŸã€‚ã—ã‹ã—ã€ã™ã§ã«ã—ã¾ã—ãŸã€‚" + +#: sitemap-ui.php:445 +msgid "No thanks, please don't bug me anymore!" +msgstr "çµæ§‹ã§ã™ã€‚ã‚‚ã†ã†ã‚‹ã•ã言ã‚ãªã„ã§ãã ã•ã„ !" + +#: sitemap-ui.php:452 +msgid "Thanks for using this plugin! You've installed this plugin some time ago. If it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "ã“ã®ãƒ—ラグインをã”利用ã„ãŸã ãã‚りãŒã¨ã†ã”ã–ã„ã¾ã™ï¼ã“ã®ãƒ—ラグインをインストールã—ã¦ã‹ã‚‰ã—ã°ã‚‰ã経éŽã—ã¾ã—ãŸã€‚ã‚‚ã—動作ã—ã¦ã€ãã®æˆæžœã«ã”満足ã„ãŸã ã‘ã¦ãŸã®ã§ã‚れã°ã€è©•価ã—ã¦ã»ã‹ã®æ–¹ã«æŽ¨è–¦ã—ã¦ãŸã ã‘ã¾ã›ã‚“ã§ã—ょã†ã‹ï¼Ÿ :-)" + +#: sitemap-ui.php:452 +msgid "Don't show this anymore" +msgstr "ã“れ以上表示ã—ãªã„" + +#: sitemap-ui.php:601 +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® %1$s ãŒã‚りã¾ã™ã€‚ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %3$s をダウンロード" + +#: sitemap-ui.php:603 +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® %1$s ãŒã‚りã¾ã™ã€‚ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %3$s をダウンロードã“ã®ãƒ—ラグインã§ã¯è‡ªå‹•アップグレードã¯ä½¿ãˆã¾ã›ã‚“。" + +#: sitemap-ui.php:605 +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® %1$s ãŒã‚りã¾ã™ã€‚ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %3$s をダウンロードã™ã‚‹ã‹ã€è‡ªå‹•アップグレードを行ã£ã¦ãã ã•ã„。" + +#: sitemap-ui.php:613 +msgid "Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "ã“ã®ãƒ–ログã¯ç¾åœ¨æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³ã‚’ブロック中ã§ã™ï¼å¤‰æ›´ã™ã‚‹ã«ã¯è¡¨ç¤ºè¨­å®šã«è¡Œã£ã¦ãã ã•ã„。" + +#: sitemap-ui.php:629 +msgid "About this Plugin:" +msgstr "ã“ã®ãƒ—ラグインã«ã¤ã„ã¦:" + +#: sitemap-ui.php:631 +msgid "Suggest a Feature" +msgstr "æ©Ÿèƒ½ã‚’ææ¡ˆ" + +#: sitemap-ui.php:632 +msgid "Notify List" +msgstr "通知一覧" + +#: sitemap-ui.php:633 +msgid "Support Forum" +msgstr "サãƒãƒ¼ãƒˆãƒ•ォーラム" + +#: sitemap-ui.php:634 +msgid "Report a Bug" +msgstr "ãƒã‚°ã‚’報告" + +#: sitemap-ui.php:636 +msgid "Donate with PayPal" +msgstr "PayPal ã§å¯„付" + +#: sitemap-ui.php:637 +msgid "My Amazon Wish List" +msgstr "Amazon ã»ã—ã„物リスト" + +#: sitemap-ui.php:638 +msgid "translator_name" +msgstr "translator_name" + +#: sitemap-ui.php:638 +msgid "translator_url" +msgstr "translator_url" + +#: sitemap-ui.php:641 +msgid "Sitemap Resources:" +msgstr "ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—ã®æƒ…å ±æº:" + +#: sitemap-ui.php:642 sitemap-ui.php:647 +msgid "Webmaster Tools" +msgstr "ウェブマスターツール" + +#: sitemap-ui.php:643 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +#: sitemap-ui.php:645 +msgid "Search Blog" +msgstr "ブログ検索" + +#: sitemap-ui.php:648 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +#: sitemap-ui.php:650 +msgid "Sitemaps Protocol" +msgstr "サイトマッププロトコル" + +#: sitemap-ui.php:651 +msgid "Official Sitemaps FAQ" +msgstr "Sitemaps ãƒ—ãƒ©ã‚°ã‚¤ãƒ³å…¬å¼ FAQ" + +#: sitemap-ui.php:655 +msgid "Recent Donations:" +msgstr "最近ã®å¯„付:" + +#: sitemap-ui.php:658 +msgid "List of the donors" +msgstr "寄付者一覧" + +#: sitemap-ui.php:660 +msgid "Hide this list" +msgstr "一覧を隠ã™" + +#: sitemap-ui.php:663 +msgid "Thanks for your support!" +msgstr "サãƒãƒ¼ãƒˆã‚りãŒã¨ã†ã”ã–ã„ã¾ã™ !" + +#: sitemap-ui.php:683 +msgid "Search engines haven't been notified yet" +msgstr "検索エンジンã¯ã¾ã é€šçŸ¥ã•れã¦ã„ã¾ã›ã‚“" + +#: sitemap-ui.php:687 +msgid "Result of the last ping, started on %date%." +msgstr "%date%ã«é–‹å§‹ã•れãŸpingã®çµæžœ" + +#: sitemap-ui.php:702 +msgid "There is still a sitemap.xml or sitemap.xml.gz file in your blog directory. Please delete them as no static files are used anymore or try to delete them automatically." +msgstr "ã„ã¾ã ã«sitemap.xmlã‹sitemap.xml.gzファイルãŒã“ã®ãƒ–ログã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«ã‚りã¾ã™ã€‚ã“れ以上é™çš„ファイルãŒä½¿ç”¨ã•れãªã„よã†ã«ã“れらを削除ã™ã‚‹ã‹è‡ªå‹•çš„ã«å‰Šé™¤ã‚’試ã¿ã¾ã™ã€‚" + +#: sitemap-ui.php:705 +msgid "The URL to your sitemap index file is: %s." +msgstr "ã‚ãªãŸã®ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãƒ•ァイルã®URL: %s" + +#: sitemap-ui.php:708 +msgid "Search engines haven't been notified yet. Write a post to let them know about your sitemap." +msgstr "検索エンジンã¯é€šçŸ¥ã•れã¦ã„ã¾ã›ã‚“。ã‚ãªãŸã®ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—を知らã›ã‚‹ã«ã¯æŠ•稿を書ã„ã¦ãã ã•ã„。" + +#: sitemap-ui.php:717 +msgid "%s was successfully notified about changes." +msgstr "%sã¯å¤‰æ›´ã«ã¤ã„ã¦æ­£ã—ã通知ã•れã¾ã—ãŸã€‚" + +#: sitemap-ui.php:720 +msgid "It took %time% seconds to notify %name%, maybe you want to disable this feature to reduce the building time." +msgstr "%name%ã«é€šçŸ¥ã™ã‚‹ãŸã‚ã«%time%ç§’ã‹ã‹ã‚Šã¾ã—ãŸã€‚ã‚‚ã—ã‹ã™ã‚‹ã¨ã€æ§‹ç¯‰ã®æ™‚間を短縮ã™ã‚‹ãŸã‚ã«ã“ã®æ©Ÿèƒ½ã‚’無効ã«ã—ãŸã„ã‹ã‚‚ã—れã¾ã›ã‚“。" + +#: sitemap-ui.php:723 +msgid "There was a problem while notifying %name%. View result" +msgstr "%name% ã«é€šçŸ¥ã—ã¦ã„る最中ã«å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚çµæžœã‚’見る" + +#: sitemap-ui.php:727 +msgid "If you encounter any problems with your sitemap you can use the debug function to get more information." +msgstr "ã‚‚ã—ã€ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—ã«é–¢ã—ã¦ä½•らã‹ã®å•題ã«é­é‡ã—ã¦ã„ã‚‹å ´åˆã«ã¯ã€æƒ…報を得るãŸã‚ã«ãƒ‡ãƒãƒƒã‚¯æ©Ÿèƒ½ã‚’使ã†ã“ã¨ãŒã§ãã¾ã™ã€‚" + +#: sitemap-ui.php:735 +msgid "Basic Options" +msgstr "基本的ãªè¨­å®š" + +#: sitemap-ui.php:737 +msgid "Update notification:" +msgstr "通知を更新:" + +#: sitemap-ui.php:737 sitemap-ui.php:760 sitemap-ui.php:783 +msgid "Learn more" +msgstr "ã•らã«è©³ã—ã" + +#: sitemap-ui.php:741 +msgid "Notify Google about updates of your Blog" +msgstr "Google ã«ãƒ–ãƒ­ã‚°ã®æ›´æ–°ã‚’通知" + +#: sitemap-ui.php:742 +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "登録ã¯å¿…è¦ã‚りã¾ã›ã‚“ãŒã€Google ウェブマスターツール ã§ã‚¯ãƒ­ãƒ¼ãƒ«é–¢é€£ã®çµ±è¨ˆã‚’見るã“ã¨ãŒã§ãã¾ã™ã€‚" + +#: sitemap-ui.php:746 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "Bing (æ—§å MSN Live サーãƒ) ã«ãƒ–ãƒ­ã‚°ã®æ›´æ–°ã‚’通知" + +#: sitemap-ui.php:747 +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "登録ã¯å¿…è¦ã‚りã¾ã›ã‚“ãŒã€Bing ウェブマスターツール ã§ã‚¯ãƒ­ãƒ¼ãƒ«é–¢é€£ã®çµ±è¨ˆã‚’見るã“ã¨ãŒã§ãã¾ã™ã€‚" + +#: sitemap-ui.php:752 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "サイトマップ㮠URL を仮想 robots.txt ファイルã«è¿½åŠ " + +#: sitemap-ui.php:756 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "WordPress ãŒç”Ÿæˆã—ãŸä»®æƒ³ robots.txt ファイルを使用ã—ã¦ã„ã¾ã™ã€‚実際㮠robots.txt ファイルをブログディレクトリã«ç½®ã‹ãªã„ã§ãã ã•ã„。" + +#: sitemap-ui.php:760 +msgid "Advanced options:" +msgstr "高度ãªè¨­å®š:" + +#: sitemap-ui.php:763 +msgid "Try to increase the memory limit to:" +msgstr "ãƒ¡ãƒ¢ãƒªã®æœ€å¤§å€¤ã‚’以下ã«å¢—加:" + +#: sitemap-ui.php:763 +msgid "e.g. \"4M\", \"16M\"" +msgstr "例: \"4M\"ã€\"16M\"" + +#: sitemap-ui.php:766 +msgid "Try to increase the execution time limit to:" +msgstr "実行時間制é™ã‚’以下ã«å¢—加:" + +#: sitemap-ui.php:766 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "ç§’ã§æŒ‡å®šï¼ˆä¾‹: \"60\" ãªã©ã€ã¾ãŸã¯ç„¡åˆ¶é™ã®å ´åˆã¯ \"0\")" + +#: sitemap-ui.php:770 +msgid "Include a XSLT stylesheet:" +msgstr "XSLT スタイルシートをå«ã‚ã‚‹:" + +#: sitemap-ui.php:771 +msgid "Full or relative URL to your .xsl file" +msgstr ".xsl ファイルã¸ã®çµ¶å¯¾ã¾ãŸã¯ç›¸å¯¾ãƒ‘ス" + +#: sitemap-ui.php:771 +msgid "Use default" +msgstr "デフォルト設定を使用" + +#: sitemap-ui.php:776 +msgid "Include sitemap in HTML format" +msgstr "HTMLå½¢å¼ã§ã®ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—ã‚’å«ã‚ã‚‹" + +#: sitemap-ui.php:791 +msgid "Additional pages" +msgstr "追加ページã®è¨­å®š" + +#: sitemap-ui.php:794 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "WordPress ブログ㮠URL 以外ã§ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—ã«å«ã‚ã‚‹ URL を指定ã§ãã¾ã™
        例ãˆã°ãƒ‰ãƒ¡ã‚¤ãƒ³ãŒ www.foo.com ã§ãƒ–ログ㮠URL ㌠www.foo.com/blog ã®å ´åˆã€www.foo.com を指定ã—ã¦ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—ã«å«ã‚ã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚" + +#: sitemap-ui.php:796 sitemap-ui.php:1000 sitemap-ui.php:1011 +#: sitemap-ui.php:1020 +msgid "Note" +msgstr "メモ" + +#: sitemap-ui.php:797 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "ã‚‚ã—ã“ã®ãƒ–ログãŒã‚µãƒ–ディレクトリã«é…ç½®ã•れã¦ã„ã¦ã€ãƒ–ログディレクトリ以外ã®ãƒšãƒ¼ã‚¸ã‚’サイトマップã«å«ã‚ãŸã„ã¨ãã¯ã€ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—ファイルを必ãšãƒ«ãƒ¼ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«é…ç½®ã—ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“ (ã“ã®ãƒšãƒ¼ã‚¸ã® "サイトマップファイルã®å ´æ‰€" 設定を確èªã—ã¦ä¸‹ã•ã„) 。" + +#: sitemap-ui.php:799 sitemap-ui.php:838 +msgid "URL to the page" +msgstr "ページ㮠URL" + +#: sitemap-ui.php:800 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "ページ㮠URL を入力ã—ã¦ä¸‹ã•ã„。 例: http://www.foo.com/index.html ã‚„ www.foo.com/home " + +#: sitemap-ui.php:802 sitemap-ui.php:839 +msgid "Priority" +msgstr "優先順ä½ã®è¨­å®š (priority)" + +#: sitemap-ui.php:803 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "ä»–ã®ãƒšãƒ¼ã‚¸ã«å¯¾ã—ã€ç›¸å¯¾çš„ãªå„ªå…ˆé †ä½ã‚’é¸ã‚“ã§ãã ã•ã„。 例ãˆã°ã€ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã®å„ªå…ˆé †ä½ã‚’ä»–ã®ãƒšãƒ¼ã‚¸ã‚ˆã‚Šé«˜ãã§ãã¾ã™ã€‚" + +#: sitemap-ui.php:805 sitemap-ui.php:841 +msgid "Last Changed" +msgstr "最終更新日" + +#: sitemap-ui.php:806 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "最終更新日を YYYY-MM-DD å½¢å¼ã§å…¥åŠ›ã—ã¦ä¸‹ã•ã„。" + +#: sitemap-ui.php:840 +msgid "Change Frequency" +msgstr "更新頻度ã®è¨­å®š (changefreq)" + +#: sitemap-ui.php:842 +msgid "#" +msgstr "#" + +#: sitemap-ui.php:847 +msgid "No pages defined." +msgstr "追加ページã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“。" + +#: sitemap-ui.php:852 +msgid "Add new page" +msgstr "æ–°ã—ã„ページã®è¿½åŠ " + +#: sitemap-ui.php:858 +msgid "Post Priority" +msgstr "投稿ã®å„ªå…ˆé †ä½" + +#: sitemap-ui.php:860 +msgid "Please select how the priority of each post should be calculated:" +msgstr "投稿ã®å„ªå…ˆé †ä½ã®è¨ˆç®—æ–¹æ³•ã‚’é¸æŠžã—ã¦ãã ã•ã„:" + +#: sitemap-ui.php:862 +msgid "Do not use automatic priority calculation" +msgstr "優先順ä½ã‚’自動的ã«è¨ˆç®—ã—ãªã„" + +#: sitemap-ui.php:862 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "ã™ã¹ã¦ã®æŠ•稿㌠"優先順ä½" ã§å®šç¾©ã•れãŸã®ã¨åŒã˜å„ªå…ˆåº¦ã‚’æŒã¤ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚" + +#: sitemap-ui.php:873 +msgid "Sitemap Content" +msgstr "Sitemap コンテンツ" + +#: sitemap-ui.php:874 +msgid "WordPress standard content" +msgstr "WordPress標準コンテンツ" + +#: sitemap-ui.php:879 +msgid "Include homepage" +msgstr "ホームページ" + +#: sitemap-ui.php:885 +msgid "Include posts" +msgstr "投稿 (個別記事) ã‚’å«ã‚ã‚‹" + +#: sitemap-ui.php:891 +msgid "Include static pages" +msgstr "固定ページをå«ã‚ã‚‹" + +#: sitemap-ui.php:897 +msgid "Include categories" +msgstr "カテゴリーページをå«ã‚ã‚‹" + +#: sitemap-ui.php:903 +msgid "Include archives" +msgstr "アーカイブページをå«ã‚ã‚‹" + +#: sitemap-ui.php:909 +msgid "Include author pages" +msgstr "投稿者ページをå«ã‚ã‚‹" + +#: sitemap-ui.php:916 +msgid "Include tag pages" +msgstr "タグページをå«ã‚ã‚‹" + +#: sitemap-ui.php:930 +msgid "Custom taxonomies" +msgstr "カスタムタクソノミー" + +#: sitemap-ui.php:941 +msgid "Include taxonomy pages for %s" +msgstr "%sã®ã‚¿ã‚¯ã‚½ãƒŽãƒŸãƒ¼ãƒšãƒ¼ã‚¸ã‚’å«ã‚ã‚‹" + +#: sitemap-ui.php:959 +msgid "Custom post types" +msgstr "カスタム投稿タイプ" + +#: sitemap-ui.php:970 +msgid "Include custom post type %s" +msgstr "カスタム投稿タイプ %s ã‚’å«ã‚ã‚‹" + +#: sitemap-ui.php:982 +msgid "Further options" +msgstr "詳細ãªã‚ªãƒ—ション" + +#: sitemap-ui.php:987 +msgid "Include the last modification time." +msgstr "最終更新時刻をå«ã‚る。" + +#: sitemap-ui.php:989 +msgid "This is highly recommended and helps the search engines to know when your content has changed. This option affects all sitemap entries." +msgstr "ã“れã¯éžå¸¸ã«æŽ¨å¥¨ã§ã‚ã‚Šã€æ¤œç´¢ã‚¨ãƒ³ã‚¸ãƒ³ãŒã‚ãªãŸã®ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå¤‰æ›´ã•ã‚ŒãŸæ™‚間を知る助ã‘ã«ãªã‚Šã¾ã™ã€‚ã“ã®ã‚ªãƒ—ションã¯ã™ã¹ã¦ã®ã‚µã‚¤ãƒˆãƒžãƒƒãƒ—エントリã«å½±éŸ¿ã—ã¾ã™ã€‚" + +#: sitemap-ui.php:996 +msgid "Excluded items" +msgstr "å«ã‚ãªã„é …ç›®" + +#: sitemap-ui.php:998 +msgid "Excluded categories" +msgstr "å«ã‚ãªã„カテゴリー" + +#: sitemap-ui.php:1000 +msgid "Using this feature will increase build time and memory usage!" +msgstr "ã“ã®æ©Ÿèƒ½ã‚’使用ã™ã‚‹ã¨ã€æ§‹ç¯‰æ™‚é–“ãŠã‚ˆã³ä½¿ç”¨ãƒ¡ãƒ¢ãƒªãŒå¢—加ã—ã¾ã™ã€‚" + +#: sitemap-ui.php:1007 +msgid "Exclude posts" +msgstr "投稿 (個別記事) ã‚’å«ã‚ãªã„" + +#: sitemap-ui.php:1009 +msgid "Exclude the following posts or pages:" +msgstr "ä»¥ä¸‹ã®æŠ•ç¨¿ã¾ãŸã¯å›ºå®šãƒšãƒ¼ã‚¸ã‚’å«ã‚ãªã„:" + +#: sitemap-ui.php:1009 +msgid "List of IDs, separated by comma" +msgstr "カンマ区切り㮠ID 一覧" + +#: sitemap-ui.php:1011 +msgid "Child posts won't be excluded automatically!" +msgstr "å­ã‚«ãƒ†ã‚´ãƒªãƒ¼ã¯è‡ªå‹•çš„ã«é™¤å¤–ã•れã¾ã›ã‚“。" + +#: sitemap-ui.php:1017 +msgid "Change frequencies" +msgstr "更新頻度ã®è¨­å®š (changefreq)" + +#: sitemap-ui.php:1021 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "ã“ã®ã‚¿ã‚°ã®å€¤ã¯çµ¶å¯¾çš„ãªå‘½ä»¤ã§ã¯ãªãヒントã¨ã¿ãªã•れã¾ã™ã€‚検索エンジンã®ã‚¯ãƒ­ãƒ¼ãƒ©ã¯ã“ã®è¨­å®šã‚’考慮ã«å…¥ã‚Œã¾ã™ãŒã€\"1時間ãŠã\" ã®è¨­å®šã«ã—ã¦ã‚‚ãã®é »åº¦ã§ã‚¯ãƒ­ãƒ¼ãƒ«ã—ãªã„ã‹ã‚‚ã—れãªã„ã—ã€\"å¹´ã«1度\" ã®è¨­å®šã«ã—ã¦ã‚‚より頻ç¹ã«ã‚¯ãƒ­ãƒ¼ãƒ«ã•れるã‹ã‚‚ã—れã¾ã›ã‚“。ã¾ãŸ \"æ›´æ–°ãªã—\" ã«è¨­å®šã•れãŸãƒšãƒ¼ã‚¸ã‚‚ã€äºˆæƒ³å¤–ã®å¤‰æ›´ã«å¯¾å¿œã™ã‚‹ãŸã‚ã€ãŠãらã定期的ã«ã‚¯ãƒ­ãƒ¼ãƒ«ãŒè¡Œã‚れるã§ã—ょã†ã€‚" + +#: sitemap-ui.php:1027 sitemap-ui.php:1084 +msgid "Homepage" +msgstr "ホームページ" + +#: sitemap-ui.php:1033 +msgid "Posts" +msgstr "投稿 (個別記事) " + +#: sitemap-ui.php:1039 sitemap-ui.php:1102 +msgid "Static pages" +msgstr "固定ページ" + +#: sitemap-ui.php:1045 sitemap-ui.php:1108 +msgid "Categories" +msgstr "カテゴリー別" + +#: sitemap-ui.php:1051 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "今月ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ– (ãŸã„ã¦ã„ã¯\"ホームページ\"ã¨åŒã˜ã§ã—ょã†)" + +#: sitemap-ui.php:1057 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "å¤ã„アーカイブ (å¤ã„投稿を編集ã—ãŸã¨ãã«ã®ã¿å¤‰æ›´ã•れã¾ã™)" + +#: sitemap-ui.php:1064 sitemap-ui.php:1121 +msgid "Tag pages" +msgstr "タグページ" + +#: sitemap-ui.php:1071 sitemap-ui.php:1128 +msgid "Author pages" +msgstr "投稿者ページ" + +#: sitemap-ui.php:1079 +msgid "Priorities" +msgstr "優先順ä½ã®è¨­å®š (priority)" + +#: sitemap-ui.php:1090 +msgid "Posts (If auto calculation is disabled)" +msgstr "投稿 (個別記事) (\"基本的ãªè¨­å®š\"ã§è‡ªå‹•計算ã«è¨­å®šã—ã¦ã„ãªã„å ´åˆã«æœ‰åй)" + +#: sitemap-ui.php:1096 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "æŠ•ç¨¿å„ªå…ˆåº¦ã®æœ€å°å€¤ (\"基本的ãªè¨­å®š\"ã§è‡ªå‹•計算ã«è¨­å®šã—ã¦ã„ã‚‹å ´åˆã«æœ‰åй)" + +#: sitemap-ui.php:1114 +msgid "Archives" +msgstr "アーカイブ別" + +#: sitemap-ui.php:1139 +msgid "Update options" +msgstr "設定を更新 »" + +#: sitemap-ui.php:1140 +msgid "Reset options" +msgstr "設定をリセット" + +#: sitemap.php:82 +msgid "Your WordPress version is too old for XML Sitemaps." +msgstr "WordPressã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒXML Sitemapsã«ã¯å¤ã™ãŽã¾ã™ã€‚" + +#: sitemap.php:82 +msgid "Unfortunately this release of Google XML Sitemaps requires at least WordPress %4$s. You are using Wordpress %2$s, which is out-dated and insecure. Please upgrade or go to active plugins and deactivate the Google XML Sitemaps plugin to hide this message. You can download an older version of this plugin from the plugin website." +msgstr "ã‚ã„ã«ãGoogle XML Sitemapsã®ã“ã®ãƒªãƒªãƒ¼ã‚¹ã¯æœ€ä½Žã§ã‚‚WordPress %4$sãŒå¿…è¦ã§ã™ã€‚時代é…れã§å®‰å…¨ã§ã¯ãªã„WordPress %2$sã‚’ã”利用中ã§ã™ã€‚ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’éš ã™ã«ã¯ã‚¢ãƒƒãƒ—グレードã™ã‚‹ã‹ä½¿ç”¨ä¸­ã®ãƒ—ラグインã«è¡Œãã€Google XML Sitemapsプラグインを無効化ã—ã¦ãã ã•ã„。プラグインã®ã‚¦ã‚§ãƒ–サイトã‹ã‚‰ã“ã®ãƒ—ラグインã®å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" + +#: sitemap.php:92 +msgid "Your PHP version is too old for XML Sitemaps." +msgstr "PHPã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒXML Sitemapsã«ã¯å¤ã™ãŽã¾ã™ã€‚" + +#: sitemap.php:92 +msgid "Unfortunately this release of Google XML Sitemaps requires at least PHP %4$s. You are using PHP %2$s, which is out-dated and insecure. Please ask your web host to update your PHP installation or go to active plugins and deactivate the Google XML Sitemaps plugin to hide this message. You can download an older version of this plugin from the plugin website." +msgstr "ã‚ã„ã«ãGoogle XML Sitemapsã®ã“ã®ãƒªãƒªãƒ¼ã‚¹ã¯æœ€ä½Žã§ã‚‚PHP %4$sãŒå¿…è¦ã§ã™ã€‚時代é…れã§å®‰å…¨ã§ã¯ãªã„PHP %2$sã‚’ã”利用中ã§ã™ã€‚ã“ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’éš ã™ã«ã¯ã‚¦ã‚§ãƒ–ホストã«PHPã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’æ›´æ–°ã™ã‚‹ã‚ˆã†ã«é ¼ã‚€ã‹ä½¿ç”¨ä¸­ã®ãƒ—ラグインã«è¡Œãã€Google XML Sitemapsプラグインを無効化ã—ã¦ãã ã•ã„。プラグインã®ã‚¦ã‚§ãƒ–サイトã‹ã‚‰ã“ã®ãƒ—ラグインã®å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" \ No newline at end of file diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_EUC.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_EUC.mo new file mode 100644 index 0000000..0d879f4 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_EUC.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_EUC.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_EUC.po new file mode 100644 index 0000000..bd9abcc --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_EUC.po @@ -0,0 +1,322 @@ +# Japanese Language File for sitemap (sitemap-ja_JP.UTF-8.po) +# Copyright (C) 2005 hiromasa : http://hiromasa.zone.ne.jp/ +# This file is distributed under the same license as the WordPress package. +# hiromasa , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-06-09 02:00+0900\n" +"PO-Revision-Date: 2005-07-03 23:17+0900\n" +"Last-Translator: hiromasa \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=EUC-JP\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" + +#: sitemap.php:375 +msgid "always" +msgstr "¤¤¤Ä¤â" + +msgid "hourly" +msgstr "Ëè»þ" + +msgid "daily" +msgstr "ËèÆü" + +msgid "weekly" +msgstr "Ëè½µ" + +msgid "monthly" +msgstr "Ëè·î" + +msgid "yearly" +msgstr "Ëèǯ" + +msgid "never" +msgstr "¹¹¿·¤µ¤ì¤Ê¤¤" + +msgid "Detected Path" +msgstr "¥Ñ¥¹¤ÎľÀÜÀßÄê" + +msgid "Example" +msgstr "Îã" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "¥Õ¥¡¥¤¥ë̾¤ò´Þ¤à Sitemap ¥Õ¥¡¥¤¥ë¤Ø¤ÎÁêÂФ⤷¤¯¤ÏÀäÂХѥ¹" + +msgid "Complete URL to the sitemap file, including name." +msgstr "¥Õ¥¡¥¤¥ë̾¤ò´Þ¤à Sitemap ¥Õ¥¡¥¤¥ë¤Ø¤Î´°Á´¤Ê URL" + +msgid "Automatic location" +msgstr "¼«Æ°ÇÛÃÖ" + +msgid "Manual location" +msgstr "¼êưÇÛÃÖ" + +msgid "OR" +msgstr "¤â¤·¤¯¤Ï" + +msgid "Location of your sitemap file" +msgstr "Sitemap ¥Õ¥¡¥¤¥ë¤Î¾ì½ê" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "¤â¤·¤¢¤Ê¤¿¤Î¥Ö¥í¥°¤¬¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ËÇÛÃÖ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ë¡¢¥Ö¥í¥°¥Ç¥£¥ì¥¯¥È¥ê°Ê³°¤Î¥Ú¡¼¥¸¤ò Sitemap ¤Ë´Þ¤á¤¿¤¤¤È¤­¤Ï¡¢Sitemap ¥Õ¥¡¥¤¥ë¤ò¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤ËÇÛÃÖ¤¹¤Ù¤­¤Ç¤¹¡£¡Ê¤³¤Î¥Ú¡¼¥¸¤Î "Sitemap ¥Õ¥¡¥¤¥ë¤Î¾ì½ê" ÀßÄê¤ò³Îǧ¤·¤Æ²¼¤µ¤¤¡Ë" + +#: sitemap.php:512 +msgid "Configuration updated" +msgstr "ÀßÄê¤ò¹¹¿·¤·¤Þ¤·¤¿¡£" + +#: sitemap.php:513 +msgid "Error" +msgstr "¥¨¥é¡¼¤Ç¤¹¡£" + +#: sitemap.php:521 +msgid "A new page was added. Click on "Save page changes" to save your changes." +msgstr "¿·¤·¤¤Äɲåڡ¼¥¸¡Ê¤ÎÀßÄêÍó¡Ë¤¬²Ã¤ï¤ê¤Þ¤·¤¿¡£ ¡Ê¥Ú¡¼¥¸¤Î¾ðÊó¤òÆþÎϸå¡Ë"Êѹ¹¤ÎÊݸ" ¤ò²¡²¼¤·¤ÆÀßÄê¤òÊݸ¤·¤Æ²¼¤µ¤¤¡£" + +#: sitemap.php:527 +msgid "Pages saved" +msgstr "Äɲåڡ¼¥¸¤ÎÀßÄê¤òÊݸ¤·¤Þ¤·¤¿¡£" + +#: sitemap.php:528 +msgid "Error while saving pages" +msgstr "Äɲåڡ¼¥¸¤ÎÀßÄê¤ÎÊÝÂ¸Ãæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿¡£" + +#: sitemap.php:539 +msgid "The page was deleted. Click on "Save page changes" to save your changes." +msgstr "»ØÄꤵ¤ì¤¿Äɲåڡ¼¥¸¡Ê¤ÎÀßÄêÍó¡Ë¤òºï½ü¤·¤Þ¤·¤¿¡£ "Êѹ¹¤ÎÊݸ" ¤ò²¡²¼¤·¤ÆÀßÄê¤òÊݸ¤·¤Æ²¼¤µ¤¤¡£" + +#: sitemap.php:542 +msgid "You changes have been cleared." +msgstr "Êѹ¹¤Ï´û¤Ëºï½ü¤µ¤ì¤Æ¤¤¤Þ¤¹¡£" + +#: sitemap.php:555 +msgid "Sitemap Generator" +msgstr "Sitemap Generator" + +#: sitemap.php:558 +msgid "Manual rebuild" +msgstr "¼êư¤Ë¤è¤ë Sitemap ¥Õ¥¡¥¤¥ë¤ÎºÆ¹½ÃÛ" + +#: sitemap.php:559 +msgid "If you want to build the sitemap without editing a post, click on here!" +msgstr "¤â¤·Åê¹Æ¤ÎÊÔ½¸¤Ê¤·¤Ë Sitemap ¥Õ¥¡¥¤¥ë¤òºÆ¹½ÃÛ¤·¤¿¤¤¾ì¹ç¤Ï¤³¤Î¥Ü¥¿¥ó¤ò²¡²¼¤·¤Æ¤¯¤À¤µ¤¤!" + +#: sitemap.php:560 +msgid "Rebuild Sitemap" +msgstr "Sitemap ¤ÎºÆ¹½ÃÛ" + +#: sitemap.php:564 +msgid "Additional pages" +msgstr "Äɲåڡ¼¥¸¤ÎÀßÄê" + +#: sitemap.php:566 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "¤³¤³¤Ç¡¢Sitemap ¤Ë´Þ¤Þ¤ì¤ë¤Ù¤­¤Ç¤¢¤ë URL ¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ ¤·¤«¤·¡¢¤³¤³¤Ç»ØÄꤹ¤ë URL ¤Ï WordPress/Blog ¤Ë°¤·¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£
        Î㤨¤Ð¥É¥á¥¤¥ó¤¬ www.foo.com ¤Ç¥Ö¥í¥°¤¬ www.foo.com/blog ¤À¤Ã¤¿¾ì¹ç¡¢¤¢¤Ê¤¿¤Ï www.foo.com ¤ò Sitemap ¤Ë´Þ¤ß¤¿¤¤¤È»×¤¦¤«¤â¤·¤ì¤Þ¤»¤ó¡£¡ÊÌõÃí: ¤³¤Î¹àÌÜ¤Ç WordPress °Ê³°¤Î URL ¤ò»ØÄꤷ¡¢¥×¥é¥°¥¤¥ó¤Ç½ÐÎϤ¹¤ë Sitemap ¤Ë´Þ¤á¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡Ë" + +#: sitemap.php:568 +msgid "URL to the page" +msgstr "¤½¤Î¥Ú¡¼¥¸¤ÎURL" + +#: sitemap.php:569 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "¤½¤Î¥Ú¡¼¥¸¤ÎURL ¤òÆþÎϤ·¤Æ²¼¤µ¤¤¡£ Îã: http://www.foo.com/index.html ¤ä www.foo.com/home " + +#: sitemap.php:571 +msgid "Priority" +msgstr "Í¥Àè½ç°Ì(priority)¤ÎÀßÄê" + +#: sitemap.php:572 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "¾¤Î¥Ú¡¼¥¸¤ËÈæÎ㤷¤¿¥Ú¡¼¥¸¤ÎÍ¥Àè½ç°Ì(priority)¤òÁª¤ó¤Ç¤¯¤À¤µ¤¤¡£ Î㤨¤Ð¡¢¤¢¤Ê¤¿¤Î¥Û¡¼¥à¥Ú¡¼¥¸¤Ï¡¢Ìõ­¤Î¥Ú¡¼¥¸¤è¤ê¹â¤¤Í¥ÀèÅÙ¤¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£" + +#: sitemap.php:574 +msgid "Last Changed" +msgstr "ºÇ½ª¹¹¿·Æü" + +#: sitemap.php:575 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "ºÇ½ª¹¹¿·Æü¤ò YYYY-MM-DD ·Á¼°¤ÇÆþÎϤ·¤Æ²¼¤µ¤¤¡£" + +#: sitemap.php:583 +msgid "Change Frequency" +msgstr "¹¹¿·ÉÑÅÙ(changefreq)¤ÎÀßÄê" + +#: sitemap.php:585 +msgid "#" +msgstr "#" + +#: sitemap.php:609 +msgid "No pages defined." +msgstr "Äɲåڡ¼¥¸¤ÏÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£" + +#: sitemap.php:616 +msgid "Add new page" +msgstr "¿·¤·¤¤¥Ú¡¼¥¸¤ÎÄɲÃ" + +#: sitemap.php:617 +msgid "Save page changes" +msgstr "Êѹ¹¤ÎÊݸ" + +#: sitemap.php:618 +msgid "Undo all page changes" +msgstr "¥Ú¡¼¥¸¤ÎÊѹ¹¤ò¸µ¤ËÌ᤹" + +#: sitemap.php:621 +msgid "Delete marked page" +msgstr "¥Þ¡¼¥¯¤µ¤ì¤¿¥Ú¡¼¥¸¤Îºï½ü" + +#: sitemap.php:627 +msgid "Basic Options" +msgstr "´ðËÜŪ¤ÊÀßÄê" + +#: sitemap.php:632 +msgid "Enable automatic priority calculation for posts based on comment count" +msgstr "Åê¹Æ¤ËÂФ¹¤ë¥³¥á¥ó¥È¿ô¤Ç¡¢Åê¹Æ¡Ê³Æ¥¨¥ó¥È¥ê¡Ë¤ÎÍ¥Àè½ç°Ì(priority)¤ò¼«Æ°·×»»¤¹¤ëµ¡Ç½¤òÍ­¸ú¤Ë¤¹¤ë" + +#: sitemap.php:638 +msgid "Write debug comments" +msgstr "¥Ç¥Ð¥Ã¥°ÍÑ¥³¥á¥ó¥È½ÐÎϤò¹Ô¤¦" + +#: sitemap.php:643 +msgid "Filename of the sitemap file" +msgstr "Sitemap ¤Î¥Õ¥¡¥¤¥ë̾" + +#: sitemap.php:650 +msgid "Write a normal XML file (your filename)" +msgstr "ɸ½à¤Î XML ¥Õ¥¡¥¤¥ë¤ò½ÐÎϤ¹¤ë (filename)" + +#: sitemap.php:652 +msgid "Detected URL" +msgstr "Detected URL" + +#: sitemap.php:657 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "gz °µ½Ì¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤ò½ÐÎϤ¹¤ë (filename + .gz)" + +#: sitemap.php:664 +msgid "Auto-Ping Google Sitemaps" +msgstr "Google Sitemap ¤Ë¹¹¿· ping ¤òÁ÷¤ë" + +#: sitemap.php:665 +msgid "This option will automatically tell Google about changes." +msgstr "¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¡¢Êѹ¹¤ò Google ¤Ë¼«Æ°Åª¤ËÄÌÃΤ·¤Þ¤¹¡£" + +#: sitemap.php:672 +msgid "Includings" +msgstr "Sitemap ¤Ë´Þ¤á¤ë ¹àÌܤÎÀßÄê" + +#: sitemap.php:677 +msgid "Include homepage" +msgstr "¥Û¡¼¥à¥Ú¡¼¥¸" + +#: sitemap.php:683 +msgid "Include posts" +msgstr "Åê¹Æ¡Ê³Æ¥¨¥ó¥È¥ê¡Ë" + +#: sitemap.php:689 +msgid "Include static pages" +msgstr "ÀÅŪ¤Ê¥Ú¡¼¥¸" + +#: sitemap.php:695 +msgid "Include categories" +msgstr "¥«¥Æ¥´¥êÊÌ" + +#: sitemap.php:701 +msgid "Include archives" +msgstr "¥¢¡¼¥«¥¤¥ÖÊÌ" + +#: sitemap.php:708 +msgid "Change frequencies" +msgstr "¹¹¿·ÉÑÅÙ(changefreq)¤ÎÀßÄê" + +#: sitemap.php:709 +msgid "Note" +msgstr "¥á¥â" + +#: sitemap.php:710 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "¤³¤Î¥¿¥°¤ÎÃͤÏÌ¿Îá¤Ç¤Ï¤Ê¤¯¥Ò¥ó¥È¤À¤È¹Í¤¨¤é¤ì¤Þ¤¹¡£¥µ¡¼¥Á¥¨¥ó¥¸¥ó¤Î¥¯¥í¡¼¥é¤Ï¤³¤ÎÀßÄê¤ò¹Íθ¤ËÆþ¤ì¤Þ¤¹¤¬¡¢\"1»þ´Ö¤ª¤­\" ¤ÎÀßÄê¤Ë¤·¤Æ¤â¤½¤ÎÉÑÅ٤ǥ¯¥í¡¼¥ë¤·¤Ê¤¤¤«¤â¤·¤ì¤Ê¤¤¤·¡¢\"ǯ°ìÅÙ¤Î\" ÀßÄê¤Ë¤·¤Æ¤â¤½¤ì¤è¤êÉÑÈˤ˥¯¥í¡¼¥ë¤µ¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤Þ¤¿ \"¹¹¿·¤µ¤ì¤Ê¤¤\" ¤ËÀßÄꤵ¤ì¤¿¥Ú¡¼¥¸¤â¡¢»×¤¤¤¬¤±¤Ê¤¤ÊѲ½¤ò¤³¤ì¤é¤Î¥Ú¡¼¥¸¤«¤éÆÀ¤ë¤¿¤á¤Ë¡¢¤ª¤½¤é¤¯¥¯¥í¡¼¥é¤ÏÄê´üŪ¤Ë¥¯¥í¡¼¥ë¤¹¤ë¤Ç¤·¤ç¤¦¡£" + +#: sitemap.php:715 +msgid "Homepage" +msgstr "¥Û¡¼¥à¥Ú¡¼¥¸" + +#: sitemap.php:721 +msgid "Posts" +msgstr "Åê¹Æ¡Ê³Æ¥¨¥ó¥È¥ê¡Ë" + +#: sitemap.php:727 +msgid "Static pages" +msgstr "ÀÅŪ¤Ê¥Ú¡¼¥¸" + +#: sitemap.php:733 +msgid "Categories" +msgstr "¥«¥Æ¥´¥êÊÌ" + +#: sitemap.php:739 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Åö·î¤Î¥¢¡¼¥«¥¤¥Ö (\"¥Û¡¼¥à¥Ú¡¼¥¸\" ¤ÎÀßÄê¤ÈƱ¤¸¤Ë¤¹¤Ù¤­¤Ç¤¹)" + +#: sitemap.php:745 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "¸Å¤¤¥¢¡¼¥«¥¤¥Ö (¸Å¤¤Åê¹Æ¤òÊÔ½¸¤·¤¿¤È¤­¤À¤±Êѹ¹¤·¤Æ¤¯¤À¤µ¤¤)" + +#: sitemap.php:752 +msgid "Priorities" +msgstr "Í¥Àè½ç°Ì(priority)¤ÎÀßÄê" + +#: sitemap.php:763 +msgid "Posts (If auto calculation is disabled)" +msgstr "Åê¹Æ¡Ê³Æ¥¨¥ó¥È¥ê¡Ë (\"´ðËÜŪ¤ÊÀßÄê\"¤Ç¼«Æ°·×»»¤ËÀßÄꤷ¤Æ¤¤¤Ê¤¤¾ì¹ç¤ËÍ­¸ú)" + +#: sitemap.php:769 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Åê¹Æ¡Ê³Æ¥¨¥ó¥È¥ê¡Ë¤ÎºÇ¾®ÃÍ (\"´ðËÜŪ¤ÊÀßÄê\"¤Ç¼«Æ°·×»»¤ËÀßÄꤷ¤Æ¤¤¤ë¾ì¹ç¤ËÍ­¸ú)" + +#: sitemap.php:787 +msgid "Archives" +msgstr "¥¢¡¼¥«¥¤¥ÖÊÌ" + +#: sitemap.php:793 +msgid "Informations and support" +msgstr "¾ðÊó¤È¥µ¥Ý¡¼¥È" + +#: sitemap.php:794 +msgid "Check %s for updates and comment there if you have any problems / questions / suggestions." +msgstr "¤â¤·¡¢ÌäÂê¤äµ¿Ìä¡¢Ä󰯤¬¤¢¤ì¤Ð %s ¤Î¥¢¥Ã¥×¥Ç¡¼¥È¾ðÊó¤ä¥³¥á¥ó¥È¤ò³Îǧ¤·¤Æ²¼¤µ¤¤¡£" + +#: sitemap.php:797 +msgid "Update options" +msgstr "ÀßÄê¤ò¹¹¿· »" + +#: sitemap.php:1033 +msgid "URL:" +msgstr "URL:" + +#: sitemap.php:1034 +msgid "Path:" +msgstr "Path:" + +#: sitemap.php:1037 +msgid "Could not write into %s" +msgstr "%s ¤Ë½ñ¤­¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡£" + +#: sitemap.php:1048 +msgid "Successfully built sitemap file:" +msgstr "¹½ÃÛ¤ËÀ®¸ù¤·¤¿ Sitemap ¥Õ¥¡¥¤¥ë:" + +#: sitemap.php:1048 +msgid "Successfully built gzipped sitemap file:" +msgstr "¹½ÃÛ¤ËÀ®¸ù¤·¤¿ gz °µ½Ì¤µ¤ì¤¿ Sitemap ¥Õ¥¡¥¤¥ë:" + +#: sitemap.php:1062 +msgid "Could not ping to Google at %s" +msgstr "Google ¤Ø¤Î¹¹¿· ping ¤ÎÁ÷¿®¤¬¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£ %s" + +#: sitemap.php:1064 +msgid "Successfully pinged Google at %s" +msgstr "Google ¤Ø¤Î¹¹¿· ping ¤ÎÁ÷¿®¤¬À®¸ù¤·¤Þ¤·¤¿¡£ %s" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_SJIS.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_SJIS.mo new file mode 100644 index 0000000..33386d8 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_SJIS.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_SJIS.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_SJIS.po new file mode 100644 index 0000000..4b6de01 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_SJIS.po @@ -0,0 +1,322 @@ +# Japanese Language File for sitemap (sitemap-ja_JP.UTF-8.po) +# Copyright (C) 2005 hiromasa : http://hiromasa.zone.ne.jp/ +# This file is distributed under the same license as the WordPress package. +# hiromasa , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-06-09 02:00+0900\n" +"PO-Revision-Date: 2005-07-03 23:17+0900\n" +"Last-Translator: hiromasa \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=Shift_JIS\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" + +#: sitemap.php:375 +msgid "always" +msgstr "‚¢‚‚à" + +msgid "hourly" +msgstr "–ˆŽž" + +msgid "daily" +msgstr "–ˆ“ú" + +msgid "weekly" +msgstr "–ˆT" + +msgid "monthly" +msgstr "–ˆŒŽ" + +msgid "yearly" +msgstr "–ˆ”N" + +msgid "never" +msgstr "XV‚³‚ê‚È‚¢" + +msgid "Detected Path" +msgstr "ƒpƒX‚Ì’¼ÚÝ’è" + +msgid "Example" +msgstr "—á" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "ƒtƒ@ƒCƒ‹–¼‚ðŠÜ‚Þ Sitemap ƒtƒ@ƒCƒ‹‚Ö‚Ì‘Š‘Î‚à‚µ‚­‚Íâ‘΃pƒX" + +msgid "Complete URL to the sitemap file, including name." +msgstr "ƒtƒ@ƒCƒ‹–¼‚ðŠÜ‚Þ Sitemap ƒtƒ@ƒCƒ‹‚Ö‚ÌŠ®‘S‚È URL" + +msgid "Automatic location" +msgstr "Ž©“®”z’u" + +msgid "Manual location" +msgstr "Žè“®”z’u" + +msgid "OR" +msgstr "‚à‚µ‚­‚Í" + +msgid "Location of your sitemap file" +msgstr "Sitemap ƒtƒ@ƒCƒ‹‚ÌêŠ" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "‚à‚µ‚ ‚È‚½‚̃uƒƒO‚ªƒTƒuƒfƒBƒŒƒNƒgƒŠ‚É”z’u‚³‚ê‚Ä‚¢‚éꇂÉAƒuƒƒOƒfƒBƒŒƒNƒgƒŠˆÈŠO‚̃y[ƒW‚ð Sitemap ‚Ɋ܂߂½‚¢‚Æ‚«‚ÍASitemap ƒtƒ@ƒCƒ‹‚ðƒ‹[ƒgƒfƒBƒŒƒNƒgƒŠ‚É”z’u‚·‚ׂ«‚Å‚·Bi‚±‚̃y[ƒW‚Ì "Sitemap ƒtƒ@ƒCƒ‹‚ÌêŠ" Ý’è‚ðŠm”F‚µ‚ĉº‚³‚¢j" + +#: sitemap.php:512 +msgid "Configuration updated" +msgstr "Ý’è‚ðXV‚µ‚Ü‚µ‚½B" + +#: sitemap.php:513 +msgid "Error" +msgstr "ƒGƒ‰[‚Å‚·B" + +#: sitemap.php:521 +msgid "A new page was added. Click on "Save page changes" to save your changes." +msgstr "V‚µ‚¢’ljÁƒy[ƒWi‚ÌÝ’è—“j‚ª‰Á‚í‚è‚Ü‚µ‚½B iƒy[ƒW‚Ìî•ñ‚ð“ü—ÍŒãj"•ÏX‚̕ۑ¶" ‚ð‰Ÿ‰º‚µ‚ÄÝ’è‚ð•Û‘¶‚µ‚ĉº‚³‚¢B" + +#: sitemap.php:527 +msgid "Pages saved" +msgstr "’ljÁƒy[ƒW‚ÌÝ’è‚ð•Û‘¶‚µ‚Ü‚µ‚½B" + +#: sitemap.php:528 +msgid "Error while saving pages" +msgstr "’ljÁƒy[ƒW‚ÌÝ’è‚̕ۑ¶’†‚ɃGƒ‰[‚ª”­¶‚µ‚Ü‚µ‚½B" + +#: sitemap.php:539 +msgid "The page was deleted. Click on "Save page changes" to save your changes." +msgstr "Žw’肳‚ꂽ’ljÁƒy[ƒWi‚ÌÝ’è—“j‚ð휂µ‚Ü‚µ‚½B "•ÏX‚̕ۑ¶" ‚ð‰Ÿ‰º‚µ‚ÄÝ’è‚ð•Û‘¶‚µ‚ĉº‚³‚¢B" + +#: sitemap.php:542 +msgid "You changes have been cleared." +msgstr "•ÏX‚ÍŠù‚É휂³‚ê‚Ä‚¢‚Ü‚·B" + +#: sitemap.php:555 +msgid "Sitemap Generator" +msgstr "Sitemap Generator" + +#: sitemap.php:558 +msgid "Manual rebuild" +msgstr "Žè“®‚É‚æ‚é Sitemap ƒtƒ@ƒCƒ‹‚ÌÄ\’z" + +#: sitemap.php:559 +msgid "If you want to build the sitemap without editing a post, click on here!" +msgstr "‚à‚µ“Še‚Ì•ÒW‚È‚µ‚É Sitemap ƒtƒ@ƒCƒ‹‚ðÄ\’z‚µ‚½‚¢ê‡‚Í‚±‚̃{ƒ^ƒ“‚ð‰Ÿ‰º‚µ‚Ä‚­‚¾‚³‚¢!" + +#: sitemap.php:560 +msgid "Rebuild Sitemap" +msgstr "Sitemap ‚ÌÄ\’z" + +#: sitemap.php:564 +msgid "Additional pages" +msgstr "’ljÁƒy[ƒW‚ÌÝ’è" + +#: sitemap.php:566 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "‚±‚±‚ÅASitemap ‚Ɋ܂܂ê‚é‚ׂ«‚Å‚ ‚é URL ‚ðŽw’è‚·‚邱‚Æ‚ª‚Å‚«‚Ü‚·B ‚µ‚©‚µA‚±‚±‚ÅŽw’è‚·‚é URL ‚Í WordPress/Blog ‚É‘®‚µ‚Ă͂¢‚¯‚Ü‚¹‚ñB
        —Ⴆ‚΃hƒƒCƒ“‚ª www.foo.com ‚ŃuƒƒO‚ª www.foo.com/blog ‚¾‚Á‚½ê‡A‚ ‚È‚½‚Í www.foo.com ‚ð Sitemap ‚Ɋ܂݂½‚¢‚ÆŽv‚¤‚©‚à‚µ‚ê‚Ü‚¹‚ñBi–ó’: ‚±‚Ì€–Ú‚Å WordPress ˆÈŠO‚Ì URL ‚ðŽw’肵Aƒvƒ‰ƒOƒCƒ“‚Åo—Í‚·‚é Sitemap ‚Ɋ܂߂邱‚Æ‚ª‚Å‚«‚Ü‚·j" + +#: sitemap.php:568 +msgid "URL to the page" +msgstr "‚»‚̃y[ƒW‚ÌURL" + +#: sitemap.php:569 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "‚»‚̃y[ƒW‚ÌURL ‚ð“ü—Í‚µ‚ĉº‚³‚¢B —á: http://www.foo.com/index.html ‚â www.foo.com/home " + +#: sitemap.php:571 +msgid "Priority" +msgstr "—D懈Ê(priority)‚ÌÝ’è" + +#: sitemap.php:572 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "‘¼‚̃y[ƒW‚É”ä—Ⴕ‚½ƒy[ƒW‚Ì—D懈Ê(priority)‚ð‘I‚ñ‚Å‚­‚¾‚³‚¢B —Ⴆ‚ÎA‚ ‚È‚½‚̃z[ƒ€ƒy[ƒW‚ÍA–Á‹L‚̃y[ƒW‚æ‚è‚‚¢—Dæ“x‚ª‚ ‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñB" + +#: sitemap.php:574 +msgid "Last Changed" +msgstr "ÅIXV“ú" + +#: sitemap.php:575 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "ÅIXV“ú‚ð YYYY-MM-DD Œ`Ž®‚Å“ü—Í‚µ‚ĉº‚³‚¢B" + +#: sitemap.php:583 +msgid "Change Frequency" +msgstr "XV•p“x(changefreq)‚ÌÝ’è" + +#: sitemap.php:585 +msgid "#" +msgstr "#" + +#: sitemap.php:609 +msgid "No pages defined." +msgstr "’ljÁƒy[ƒW‚Í’è‹`‚³‚ê‚Ä‚¢‚Ü‚¹‚ñB" + +#: sitemap.php:616 +msgid "Add new page" +msgstr "V‚µ‚¢ƒy[ƒW‚̒ljÁ" + +#: sitemap.php:617 +msgid "Save page changes" +msgstr "•ÏX‚̕ۑ¶" + +#: sitemap.php:618 +msgid "Undo all page changes" +msgstr "ƒy[ƒW‚Ì•ÏX‚ðŒ³‚É–ß‚·" + +#: sitemap.php:621 +msgid "Delete marked page" +msgstr "ƒ}[ƒN‚³‚ꂽƒy[ƒW‚Ìíœ" + +#: sitemap.php:627 +msgid "Basic Options" +msgstr "Šî–{“I‚ÈÝ’è" + +#: sitemap.php:632 +msgid "Enable automatic priority calculation for posts based on comment count" +msgstr "“Še‚ɑ΂·‚éƒRƒƒ“ƒg”‚ÅA“ŠeiŠeƒGƒ“ƒgƒŠj‚Ì—D懈Ê(priority)‚ðŽ©“®ŒvŽZ‚·‚é‹@”\‚ð—LŒø‚É‚·‚é" + +#: sitemap.php:638 +msgid "Write debug comments" +msgstr "ƒfƒoƒbƒO—pƒRƒƒ“ƒgo—Í‚ðs‚¤" + +#: sitemap.php:643 +msgid "Filename of the sitemap file" +msgstr "Sitemap ‚̃tƒ@ƒCƒ‹–¼" + +#: sitemap.php:650 +msgid "Write a normal XML file (your filename)" +msgstr "•W€‚Ì XML ƒtƒ@ƒCƒ‹‚ðo—Í‚·‚é (filename)" + +#: sitemap.php:652 +msgid "Detected URL" +msgstr "Detected URL" + +#: sitemap.php:657 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "gz ˆ³k‚³‚ꂽƒtƒ@ƒCƒ‹‚ðo—Í‚·‚é (filename + .gz)" + +#: sitemap.php:664 +msgid "Auto-Ping Google Sitemaps" +msgstr "Google Sitemap ‚ÉXV ping ‚ð‘—‚é" + +#: sitemap.php:665 +msgid "This option will automatically tell Google about changes." +msgstr "‚±‚̃IƒvƒVƒ‡ƒ“‚ÍA•ÏX‚ð Google ‚ÉŽ©“®“I‚É’Ê’m‚µ‚Ü‚·B" + +#: sitemap.php:672 +msgid "Includings" +msgstr "Sitemap ‚ÉŠÜ‚ß‚é €–Ú‚ÌÝ’è" + +#: sitemap.php:677 +msgid "Include homepage" +msgstr "ƒz[ƒ€ƒy[ƒW" + +#: sitemap.php:683 +msgid "Include posts" +msgstr "“ŠeiŠeƒGƒ“ƒgƒŠj" + +#: sitemap.php:689 +msgid "Include static pages" +msgstr "ÓI‚ȃy[ƒW" + +#: sitemap.php:695 +msgid "Include categories" +msgstr "ƒJƒeƒSƒŠ•Ê" + +#: sitemap.php:701 +msgid "Include archives" +msgstr "ƒA[ƒJƒCƒu•Ê" + +#: sitemap.php:708 +msgid "Change frequencies" +msgstr "XV•p“x(changefreq)‚ÌÝ’è" + +#: sitemap.php:709 +msgid "Note" +msgstr "ƒƒ‚" + +#: sitemap.php:710 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "‚±‚̃^ƒO‚Ì’l‚Í–½—߂ł͂Ȃ­ƒqƒ“ƒg‚¾‚Æl‚¦‚ç‚ê‚Ü‚·BƒT[ƒ`ƒGƒ“ƒWƒ“‚̃Nƒ[ƒ‰‚Í‚±‚ÌÝ’è‚ðl—¶‚É“ü‚ê‚Ü‚·‚ªA\"1ŽžŠÔ‚¨‚«\" ‚ÌÝ’è‚É‚µ‚Ä‚à‚»‚Ì•p“x‚ŃNƒ[ƒ‹‚µ‚È‚¢‚©‚à‚µ‚ê‚È‚¢‚µA\"”Nˆê“x‚Ì\" Ý’è‚É‚µ‚Ä‚à‚»‚ê‚æ‚è•p”ɂɃNƒ[ƒ‹‚³‚ê‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñB‚Ü‚½ \"XV‚³‚ê‚È‚¢\" ‚Éݒ肳‚ꂽƒy[ƒW‚àAŽv‚¢‚ª‚¯‚È‚¢•ω»‚ð‚±‚ê‚ç‚̃y[ƒW‚©‚瓾‚邽‚ß‚ÉA‚¨‚»‚ç‚­ƒNƒ[ƒ‰‚Í’èŠú“I‚ɃNƒ[ƒ‹‚·‚é‚Å‚µ‚傤B" + +#: sitemap.php:715 +msgid "Homepage" +msgstr "ƒz[ƒ€ƒy[ƒW" + +#: sitemap.php:721 +msgid "Posts" +msgstr "“ŠeiŠeƒGƒ“ƒgƒŠj" + +#: sitemap.php:727 +msgid "Static pages" +msgstr "ÓI‚ȃy[ƒW" + +#: sitemap.php:733 +msgid "Categories" +msgstr "ƒJƒeƒSƒŠ•Ê" + +#: sitemap.php:739 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "“–ŒŽ‚̃A[ƒJƒCƒu (\"ƒz[ƒ€ƒy[ƒW\" ‚ÌÝ’è‚Æ“¯‚¶‚É‚·‚ׂ«‚Å‚·)" + +#: sitemap.php:745 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "ŒÃ‚¢ƒA[ƒJƒCƒu (ŒÃ‚¢“Še‚ð•ÒW‚µ‚½‚Æ‚«‚¾‚¯•ÏX‚µ‚Ä‚­‚¾‚³‚¢)" + +#: sitemap.php:752 +msgid "Priorities" +msgstr "—D懈Ê(priority)‚ÌÝ’è" + +#: sitemap.php:763 +msgid "Posts (If auto calculation is disabled)" +msgstr "“ŠeiŠeƒGƒ“ƒgƒŠj (\"Šî–{“I‚ÈÝ’è\"‚ÅŽ©“®ŒvŽZ‚Éݒ肵‚Ä‚¢‚È‚¢ê‡‚É—LŒø)" + +#: sitemap.php:769 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "“ŠeiŠeƒGƒ“ƒgƒŠj‚ÌŬ’l (\"Šî–{“I‚ÈÝ’è\"‚ÅŽ©“®ŒvŽZ‚Éݒ肵‚Ä‚¢‚éꇂɗLŒø)" + +#: sitemap.php:787 +msgid "Archives" +msgstr "ƒA[ƒJƒCƒu•Ê" + +#: sitemap.php:793 +msgid "Informations and support" +msgstr "î•ñ‚ƃTƒ|[ƒg" + +#: sitemap.php:794 +msgid "Check %s for updates and comment there if you have any problems / questions / suggestions." +msgstr "‚à‚µA–â‘è‚â‹^–âA’ñˆÄ‚ª‚ ‚ê‚Î %s ‚̃Aƒbƒvƒf[ƒgî•ñ‚âƒRƒƒ“ƒg‚ðŠm”F‚µ‚ĉº‚³‚¢B" + +#: sitemap.php:797 +msgid "Update options" +msgstr "Ý’è‚ðXV »" + +#: sitemap.php:1033 +msgid "URL:" +msgstr "URL:" + +#: sitemap.php:1034 +msgid "Path:" +msgstr "Path:" + +#: sitemap.php:1037 +msgid "Could not write into %s" +msgstr "%s ‚É‘‚«ž‚Þ‚±‚Æ‚ª‚Å‚«‚Ü‚¹‚ñB" + +#: sitemap.php:1048 +msgid "Successfully built sitemap file:" +msgstr "\’z‚ɬŒ÷‚µ‚½ Sitemap ƒtƒ@ƒCƒ‹:" + +#: sitemap.php:1048 +msgid "Successfully built gzipped sitemap file:" +msgstr "\’z‚ɬŒ÷‚µ‚½ gz ˆ³k‚³‚ꂽ Sitemap ƒtƒ@ƒCƒ‹:" + +#: sitemap.php:1062 +msgid "Could not ping to Google at %s" +msgstr "Google ‚Ö‚ÌXV ping ‚Ì‘—M‚ª‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½B %s" + +#: sitemap.php:1064 +msgid "Successfully pinged Google at %s" +msgstr "Google ‚Ö‚ÌXV ping ‚Ì‘—M‚ª¬Œ÷‚µ‚Ü‚µ‚½B %s" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_UTF.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_UTF.mo new file mode 100644 index 0000000..1e1aa9d Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_UTF.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_UTF.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_UTF.po new file mode 100644 index 0000000..9e67691 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ja_UTF.po @@ -0,0 +1,322 @@ +# Japanese Language File for sitemap (sitemap-ja_JP.UTF-8.po) +# Copyright (C) 2005 hiromasa : http://hiromasa.zone.ne.jp/ +# This file is distributed under the same license as the WordPress package. +# hiromasa , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-06-09 02:00+0900\n" +"PO-Revision-Date: 2005-07-03 23:17+0900\n" +"Last-Translator: hiromasa \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" + +#: sitemap.php:375 +msgid "always" +msgstr "ã„ã¤ã‚‚" + +msgid "hourly" +msgstr "毎時" + +msgid "daily" +msgstr "毎日" + +msgid "weekly" +msgstr "毎週" + +msgid "monthly" +msgstr "毎月" + +msgid "yearly" +msgstr "毎年" + +msgid "never" +msgstr "æ›´æ–°ã•れãªã„" + +msgid "Detected Path" +msgstr "パスã®ç›´æŽ¥è¨­å®š" + +msgid "Example" +msgstr "例" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "ファイルåã‚’å«ã‚€ Sitemap ファイルã¸ã®ç›¸å¯¾ã‚‚ã—ãã¯çµ¶å¯¾ãƒ‘ス" + +msgid "Complete URL to the sitemap file, including name." +msgstr "ファイルåã‚’å«ã‚€ Sitemap ファイルã¸ã®å®Œå…¨ãª URL" + +msgid "Automatic location" +msgstr "自動é…ç½®" + +msgid "Manual location" +msgstr "手動é…ç½®" + +msgid "OR" +msgstr "ã‚‚ã—ãã¯" + +msgid "Location of your sitemap file" +msgstr "Sitemap ファイルã®å ´æ‰€" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "ã‚‚ã—ã‚ãªãŸã®ãƒ–ログãŒã‚µãƒ–ディレクトリã«é…ç½®ã•れã¦ã„ã‚‹å ´åˆã«ã€ãƒ–ログディレクトリ以外ã®ãƒšãƒ¼ã‚¸ã‚’ Sitemap ã«å«ã‚ãŸã„ã¨ãã¯ã€Sitemap ファイルをルートディレクトリã«é…ç½®ã™ã¹ãã§ã™ã€‚(ã“ã®ãƒšãƒ¼ã‚¸ã® "Sitemap ファイルã®å ´æ‰€" 設定を確èªã—ã¦ä¸‹ã•ã„)" + +#: sitemap.php:512 +msgid "Configuration updated" +msgstr "設定を更新ã—ã¾ã—ãŸã€‚" + +#: sitemap.php:513 +msgid "Error" +msgstr "エラーã§ã™ã€‚" + +#: sitemap.php:521 +msgid "A new page was added. Click on "Save page changes" to save your changes." +msgstr "æ–°ã—ã„追加ページ(ã®è¨­å®šæ¬„)ãŒåŠ ã‚りã¾ã—ãŸã€‚ ï¼ˆãƒšãƒ¼ã‚¸ã®æƒ…報を入力後)"変更ã®ä¿å­˜" を押下ã—ã¦è¨­å®šã‚’ä¿å­˜ã—ã¦ä¸‹ã•ã„。" + +#: sitemap.php:527 +msgid "Pages saved" +msgstr "追加ページã®è¨­å®šã‚’ä¿å­˜ã—ã¾ã—ãŸã€‚" + +#: sitemap.php:528 +msgid "Error while saving pages" +msgstr "追加ページã®è¨­å®šã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚" + +#: sitemap.php:539 +msgid "The page was deleted. Click on "Save page changes" to save your changes." +msgstr "指定ã•れãŸè¿½åŠ ãƒšãƒ¼ã‚¸ï¼ˆã®è¨­å®šæ¬„)を削除ã—ã¾ã—ãŸã€‚ "変更ã®ä¿å­˜" を押下ã—ã¦è¨­å®šã‚’ä¿å­˜ã—ã¦ä¸‹ã•ã„。" + +#: sitemap.php:542 +msgid "You changes have been cleared." +msgstr "å¤‰æ›´ã¯æ—¢ã«å‰Šé™¤ã•れã¦ã„ã¾ã™ã€‚" + +#: sitemap.php:555 +msgid "Sitemap Generator" +msgstr "Sitemap Generator" + +#: sitemap.php:558 +msgid "Manual rebuild" +msgstr "手動ã«ã‚ˆã‚‹ Sitemap ファイルã®å†æ§‹ç¯‰" + +#: sitemap.php:559 +msgid "If you want to build the sitemap without editing a post, click on here!" +msgstr "ã‚‚ã—æŠ•ç¨¿ã®ç·¨é›†ãªã—ã« Sitemap ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å†æ§‹ç¯‰ã—ãŸã„å ´åˆã¯ã“ã®ãƒœã‚¿ãƒ³ã‚’押下ã—ã¦ãã ã•ã„!" + +#: sitemap.php:560 +msgid "Rebuild Sitemap" +msgstr "Sitemap ã®å†æ§‹ç¯‰" + +#: sitemap.php:564 +msgid "Additional pages" +msgstr "追加ページã®è¨­å®š" + +#: sitemap.php:566 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "ã“ã“ã§ã€Sitemap ã«å«ã¾ã‚Œã‚‹ã¹ãã§ã‚ã‚‹ URL を指定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ ã—ã‹ã—ã€ã“ã“ã§æŒ‡å®šã™ã‚‹ URL 㯠WordPress/Blog ã«å±žã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。
        例ãˆã°ãƒ‰ãƒ¡ã‚¤ãƒ³ãŒ www.foo.com ã§ãƒ–ログ㌠www.foo.com/blog ã ã£ãŸå ´åˆã€ã‚ãªãŸã¯ www.foo.com ã‚’ Sitemap ã«å«ã¿ãŸã„ã¨æ€ã†ã‹ã‚‚ã—れã¾ã›ã‚“。(訳注: ã“ã®é …目㧠WordPress 以外㮠URL を指定ã—ã€ãƒ—ラグインã§å‡ºåŠ›ã™ã‚‹ Sitemap ã«å«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã™ï¼‰" + +#: sitemap.php:568 +msgid "URL to the page" +msgstr "ãã®ãƒšãƒ¼ã‚¸ã®URL" + +#: sitemap.php:569 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "ãã®ãƒšãƒ¼ã‚¸ã®URL を入力ã—ã¦ä¸‹ã•ã„。 例: http://www.foo.com/index.html ã‚„ www.foo.com/home " + +#: sitemap.php:571 +msgid "Priority" +msgstr "優先順ä½(priority)ã®è¨­å®š" + +#: sitemap.php:572 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "ä»–ã®ãƒšãƒ¼ã‚¸ã«æ¯”例ã—ãŸãƒšãƒ¼ã‚¸ã®å„ªå…ˆé †ä½(priority)ã‚’é¸ã‚“ã§ãã ã•ã„。 例ãˆã°ã€ã‚ãªãŸã®ãƒ›ãƒ¼ãƒ ãƒšãƒ¼ã‚¸ã¯ã€éŠ˜è¨˜ã®ãƒšãƒ¼ã‚¸ã‚ˆã‚Šé«˜ã„優先度ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。" + +#: sitemap.php:574 +msgid "Last Changed" +msgstr "最終更新日" + +#: sitemap.php:575 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "最終更新日を YYYY-MM-DD å½¢å¼ã§å…¥åŠ›ã—ã¦ä¸‹ã•ã„。" + +#: sitemap.php:583 +msgid "Change Frequency" +msgstr "更新頻度(changefreq)ã®è¨­å®š" + +#: sitemap.php:585 +msgid "#" +msgstr "#" + +#: sitemap.php:609 +msgid "No pages defined." +msgstr "追加ページã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“。" + +#: sitemap.php:616 +msgid "Add new page" +msgstr "æ–°ã—ã„ページã®è¿½åŠ " + +#: sitemap.php:617 +msgid "Save page changes" +msgstr "変更ã®ä¿å­˜" + +#: sitemap.php:618 +msgid "Undo all page changes" +msgstr "ページã®å¤‰æ›´ã‚’å…ƒã«æˆ»ã™" + +#: sitemap.php:621 +msgid "Delete marked page" +msgstr "マークã•れãŸãƒšãƒ¼ã‚¸ã®å‰Šé™¤" + +#: sitemap.php:627 +msgid "Basic Options" +msgstr "基本的ãªè¨­å®š" + +#: sitemap.php:632 +msgid "Enable automatic priority calculation for posts based on comment count" +msgstr "投稿ã«å¯¾ã™ã‚‹ã‚³ãƒ¡ãƒ³ãƒˆæ•°ã§ã€æŠ•稿(å„エントリ)ã®å„ªå…ˆé †ä½(priority)を自動計算ã™ã‚‹æ©Ÿèƒ½ã‚’有効ã«ã™ã‚‹" + +#: sitemap.php:638 +msgid "Write debug comments" +msgstr "デãƒãƒƒã‚°ç”¨ã‚³ãƒ¡ãƒ³ãƒˆå‡ºåŠ›ã‚’è¡Œã†" + +#: sitemap.php:643 +msgid "Filename of the sitemap file" +msgstr "Sitemap ã®ãƒ•ァイルå" + +#: sitemap.php:650 +msgid "Write a normal XML file (your filename)" +msgstr "標準㮠XML ファイルを出力ã™ã‚‹ (filename)" + +#: sitemap.php:652 +msgid "Detected URL" +msgstr "Detected URL" + +#: sitemap.php:657 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "gz 圧縮ã•れãŸãƒ•ァイルを出力ã™ã‚‹ (filename + .gz)" + +#: sitemap.php:664 +msgid "Auto-Ping Google Sitemaps" +msgstr "Google Sitemap ã«æ›´æ–° ping ã‚’é€ã‚‹" + +#: sitemap.php:665 +msgid "This option will automatically tell Google about changes." +msgstr "ã“ã®ã‚ªãƒ—ションã¯ã€å¤‰æ›´ã‚’ Google ã«è‡ªå‹•çš„ã«é€šçŸ¥ã—ã¾ã™ã€‚" + +#: sitemap.php:672 +msgid "Includings" +msgstr "Sitemap ã«å«ã‚ã‚‹ é …ç›®ã®è¨­å®š" + +#: sitemap.php:677 +msgid "Include homepage" +msgstr "ホームページ" + +#: sitemap.php:683 +msgid "Include posts" +msgstr "投稿(å„エントリ)" + +#: sitemap.php:689 +msgid "Include static pages" +msgstr "é™çš„ãªãƒšãƒ¼ã‚¸" + +#: sitemap.php:695 +msgid "Include categories" +msgstr "カテゴリ別" + +#: sitemap.php:701 +msgid "Include archives" +msgstr "アーカイブ別" + +#: sitemap.php:708 +msgid "Change frequencies" +msgstr "更新頻度(changefreq)ã®è¨­å®š" + +#: sitemap.php:709 +msgid "Note" +msgstr "メモ" + +#: sitemap.php:710 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "ã“ã®ã‚¿ã‚°ã®å€¤ã¯å‘½ä»¤ã§ã¯ãªãヒントã ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚サーãƒã‚¨ãƒ³ã‚¸ãƒ³ã®ã‚¯ãƒ­ãƒ¼ãƒ©ã¯ã“ã®è¨­å®šã‚’考慮ã«å…¥ã‚Œã¾ã™ãŒã€\"1時間ãŠã\" ã®è¨­å®šã«ã—ã¦ã‚‚ãã®é »åº¦ã§ã‚¯ãƒ­ãƒ¼ãƒ«ã—ãªã„ã‹ã‚‚ã—れãªã„ã—ã€\"年一度ã®\" 設定ã«ã—ã¦ã‚‚ãれより頻ç¹ã«ã‚¯ãƒ­ãƒ¼ãƒ«ã•れるã‹ã‚‚ã—れã¾ã›ã‚“。ã¾ãŸ \"æ›´æ–°ã•れãªã„\" ã«è¨­å®šã•れãŸãƒšãƒ¼ã‚¸ã‚‚ã€æ€ã„ãŒã‘ãªã„変化をã“れらã®ãƒšãƒ¼ã‚¸ã‹ã‚‰å¾—ã‚‹ãŸã‚ã«ã€ãŠãらãクローラã¯å®šæœŸçš„ã«ã‚¯ãƒ­ãƒ¼ãƒ«ã™ã‚‹ã§ã—ょã†ã€‚" + +#: sitemap.php:715 +msgid "Homepage" +msgstr "ホームページ" + +#: sitemap.php:721 +msgid "Posts" +msgstr "投稿(å„エントリ)" + +#: sitemap.php:727 +msgid "Static pages" +msgstr "é™çš„ãªãƒšãƒ¼ã‚¸" + +#: sitemap.php:733 +msgid "Categories" +msgstr "カテゴリ別" + +#: sitemap.php:739 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "当月ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ– (\"ホームページ\" ã®è¨­å®šã¨åŒã˜ã«ã™ã¹ãã§ã™)" + +#: sitemap.php:745 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "å¤ã„アーカイブ (å¤ã„投稿を編集ã—ãŸã¨ãã ã‘変更ã—ã¦ãã ã•ã„)" + +#: sitemap.php:752 +msgid "Priorities" +msgstr "優先順ä½(priority)ã®è¨­å®š" + +#: sitemap.php:763 +msgid "Posts (If auto calculation is disabled)" +msgstr "投稿(å„エントリ) (\"基本的ãªè¨­å®š\"ã§è‡ªå‹•計算ã«è¨­å®šã—ã¦ã„ãªã„å ´åˆã«æœ‰åй)" + +#: sitemap.php:769 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "投稿(å„ã‚¨ãƒ³ãƒˆãƒªï¼‰ã®æœ€å°å€¤ (\"基本的ãªè¨­å®š\"ã§è‡ªå‹•計算ã«è¨­å®šã—ã¦ã„ã‚‹å ´åˆã«æœ‰åй)" + +#: sitemap.php:787 +msgid "Archives" +msgstr "アーカイブ別" + +#: sitemap.php:793 +msgid "Informations and support" +msgstr "情報ã¨ã‚µãƒãƒ¼ãƒˆ" + +#: sitemap.php:794 +msgid "Check %s for updates and comment there if you have any problems / questions / suggestions." +msgstr "ã‚‚ã—ã€å•題や疑å•ã€ææ¡ˆãŒã‚れ㰠%s ã®ã‚¢ãƒƒãƒ—デート情報やコメントを確èªã—ã¦ä¸‹ã•ã„。" + +#: sitemap.php:797 +msgid "Update options" +msgstr "設定を更新 »" + +#: sitemap.php:1033 +msgid "URL:" +msgstr "URL:" + +#: sitemap.php:1034 +msgid "Path:" +msgstr "Path:" + +#: sitemap.php:1037 +msgid "Could not write into %s" +msgstr "%s ã«æ›¸ã込むã“ã¨ãŒã§ãã¾ã›ã‚“。" + +#: sitemap.php:1048 +msgid "Successfully built sitemap file:" +msgstr "æ§‹ç¯‰ã«æˆåŠŸã—㟠Sitemap ファイル:" + +#: sitemap.php:1048 +msgid "Successfully built gzipped sitemap file:" +msgstr "æ§‹ç¯‰ã«æˆåŠŸã—㟠gz 圧縮ã•れ㟠Sitemap ファイル:" + +#: sitemap.php:1062 +msgid "Could not ping to Google at %s" +msgstr "Google ã¸ã®æ›´æ–° ping ã®é€ä¿¡ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ %s" + +#: sitemap.php:1064 +msgid "Successfully pinged Google at %s" +msgstr "Google ã¸ã®æ›´æ–° ping ã®é€ä¿¡ãŒæˆåŠŸã—ã¾ã—ãŸã€‚ %s" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ko_KR.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ko_KR.mo new file mode 100644 index 0000000..1fbbcc2 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ko_KR.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ko_KR.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ko_KR.po new file mode 100644 index 0000000..bfbd900 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ko_KR.po @@ -0,0 +1,703 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2008-04-15 13:17+0900\n" +"Last-Translator: 김승엽 \n" +"Language-Team: Wordpress Korea \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Korean\n" +"X-Poedit-Country: KOREA, REPUBLIC OF\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +msgid "Comment Count" +msgstr "코멘트 갯수" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "í¬ìŠ¤íŠ¸ì˜ ì½”ë©˜íŠ¸ 갯수를 ì´ìš©í•´ 우선순위를 계산합니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +msgid "Comment Average" +msgstr "코멘트 í‰ê· " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +msgid "Uses the average comment count to calculate the priority" +msgstr "ì½”ë©˜íŠ¸ì˜ í‰ê·  갯수를 ì´ìš©í•´ 우선순위를 계산합니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +msgid "Popularity Contest" +msgstr "Popularity Contest" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "활성화 ëœAlex Kingì˜ Popularity Contest Pluginì„ ì´ìš©í•©ë‹ˆë‹¤. 설정 ê³¼ Most Popular Posts를 확ì¸í•˜ì‹­ì‹œì˜¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap Generator" +msgstr "XML-사ì´íЏ ë§µ ìƒì„±ê¸°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap" +msgstr "XML-사ì´íЏ ë§µ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "ê¸°ë¶€ì— ì •ë§ ê°ì‚¬ë“œë¦½ë‹ˆë‹¤. 제가 ì´ í”ŒëŸ¬ê·¸ì¸ì´ë‚˜ 다른 무료 í”„ë¡œê·¸ëž¨ì„ ê³„ì† ìž‘ì„±í•˜ê³  ì§€ì›í•  수 있ë„ë¡ ë„와주십시오!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Hide this notice" +msgstr "ì´ ì£¼ì˜ì‚¬í•­ 숨기기." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "ì´ í”ŒëŸ¬ê·¸ì¸ì„ 사용해 주셔서 ê°ì‚¬í•©ë‹ˆë‹¤! ë‹¹ì‹ ì´ ì´ í”ŒëŸ¬ê·¸ì¸ì„ 사용한 ì§€ í•œë‹¬ì´ ë˜ì—ˆìŠµë‹ˆë‹¤. 만약 ì´ í”ŒëŸ¬ê·¸ì¸ì˜ ìž‘ë™ê³¼ 결과가 만족스러웠고 1달러 ì´ìƒì˜ 가치가 있다고 ìƒê°í•˜ì‹­ë‹ˆê¹Œ? 기부로 제가 ì´ ë¬´ë£Œ ì†Œí”„íŠ¸ì›¨ì–´ì˜ ê°œë°œê³¼ ì§€ì›ì„ 계ì†í•˜ë„ë¡ ë„ì›€ì„ ì£¼ì‹­ì‹œì˜¤! 네, 문제없습니다!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +msgid "No thanks, please don't bug me anymore!" +msgstr "사양합니다, ë” ì´ìƒ 귀찮게 하지 ë§ì•„주십시오." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +msgid "XML Sitemap Generator for WordPress" +msgstr "워드프레스 ìš© XML 사ì´íЏ ë§µ ìƒì„±ê¸°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +msgid "Configuration updated" +msgstr "ì„¤ì •ì´ ì—…ë°ì´íЏ ë˜ì—ˆìŠµë‹ˆë‹¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +msgid "Error while saving options" +msgstr "ì˜µì…˜ì„ ì €ìž¥í•˜ëŠ” ì¤‘ì— ì—러가 ë°œìƒí–ˆìŠµë‹ˆë‹¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +msgid "Pages saved" +msgstr "페ì´ì§€ê°€ 저장ë˜ì—ˆìŠµë‹ˆë‹¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +msgid "Error while saving pages" +msgstr "페ì´ì§€ë¥¼ 저장하는 ì¤‘ì— ì—러가 ë°œìƒí–ˆìŠµë‹ˆë‹¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2748 +#, php-format +msgid "Robots.txt file saved" +msgstr "Robots.txt 파ì¼ì´ 저장ë˜ì—ˆìŠµë‹ˆë‹¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2750 +msgid "Error while saving Robots.txt file" +msgstr "Robots.txt 파ì¼ì„ 저장하는 ì¤‘ì— ì—러가 ë°œìƒí–ˆìŠµë‹ˆë‹¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +msgid "The default configuration was restored." +msgstr "기본 ì„¤ì •ì´ ë³µì›ë˜ì—ˆìŠµë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +msgid "open" +msgstr "열기" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +msgid "close" +msgstr "닫기" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +msgid "click-down and drag to move this box" +msgstr "ì´ ìƒìžë¥¼ 움ì§ì´ë ¤ë©´ í´ë¦­í•˜ê³  드래그 하십시오" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +msgid "click to %toggle% this box" +msgstr "í´ë¦­í•˜ë©´ ì´ ìƒìžë¥¼ %toggle%" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +msgid "use the arrow keys to move this box" +msgstr "방향키를 사용해서 ì´ ìƒìžë¥¼ ì´ë™" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +msgid ", or press the enter key to %toggle% it" +msgstr ", ë˜ëŠ” 엔터키를 눌러 %toggle%" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +msgid "About this Plugin:" +msgstr "ì´ í”ŒëŸ¬ê·¸ì¸ ëŒ€í•´:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +msgid "Plugin Homepage" +msgstr "í”ŒëŸ¬ê·¸ì¸ í™ˆíŽ˜ì´ì§€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +msgid "Notify List" +msgstr "ë©”ì¼ í†µì§€ 리스트" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +msgid "Support Forum" +msgstr "서í¬íЏ í¬ëŸ¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +msgid "Donate with PayPal" +msgstr "PayPal 기부" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +msgid "My Amazon Wish List" +msgstr "ë‚´ Amazon 위시 리스트" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_name" +msgstr "ë²ˆì—­ìž ê¹€ìŠ¹ì—½" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_url" +msgstr "http://unfusion.kunsan.ac.kr/word" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +msgid "Sitemap Resources:" +msgstr "사ì´íŠ¸ë§µ Resources:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +msgid "Webmaster Tools" +msgstr "웹마스터 ë„구" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +msgid "Webmaster Blog" +msgstr "웹마스터 블로그" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +msgid "Site Explorer" +msgstr "사ì´íЏ ìµìŠ¤í”Œë¡œëŸ¬" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +msgid "Search Blog" +msgstr "블로그 검색" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +msgid "Webmaster Center Blog" +msgstr "웹마스터 센터 블로그" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +msgid "Sitemaps Protocol" +msgstr "사ì´íЏ ë§µ 프로토콜" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +msgid "Official Sitemaps FAQ" +msgstr "사ì´íЏ ë§µ FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +msgid "My Sitemaps FAQ" +msgstr "사ì´íЏ ë§µ ìƒì„±ê¸° FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +msgid "Recent Donations:" +msgstr "최근 기부:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +msgid "List of the donors" +msgstr "ê¸°ë¶€ìž ëª©ë¡" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +msgid "Hide this list" +msgstr "ëª©ë¡ ìˆ¨ê¸°ê¸°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +msgid "Thanks for your support!" +msgstr "ë‹¹ì‹ ì˜ ì§€ì›ì— ê°ì‚¬ë“œë¦½ë‹ˆë‹¤!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +msgid "Status" +msgstr "ìƒíƒœ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "사ì´íЏ ë§µì´ ì•„ì§ ë§Œë“¤ì–´ì§€ì§€ 않았습니다. 여기를 í´ë¦­í•˜ë©´ 처ìŒìœ¼ë¡œ 사ì´íЏ ë§µì„ ìƒì„±í•©ë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +msgid "Your sitemap was last built on %date%." +msgstr "ë‹¹ì‹ ì˜ ì‚¬ì´íЏ ë§µ ì€ %date%ì— ë§ˆì§€ë§‰ìœ¼ë¡œ ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreì •ë³´ ë” ë³´ê¸°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "ë‹¹ì‹ ì˜ ì‚¬ì´íЏ ë§µ(ì••ì¶•ë¨)ì€ %date%ì— ë§ˆì§€ë§‰ìœ¼ë¡œ ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreì •ë³´ ë” ë³´ê¸°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +msgid "Google was successfully notified about changes." +msgstr "Googleì— ë³€ê²½ì‚¬í•­ì„ ì„±ê³µì ìœ¼ë¡œ 통보하였습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Googleì— í†µë³´í•˜ëŠ”ë° %time% 초가 걸렸습니다. 만약 ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì§€ 않으면 사ì´íЏ ë§µ ìž‘ì„±ì‹œê°„ì„ ì¤„ì¼ ìˆ˜ 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Googleì— í†µë³´í•˜ëŠ” ë™ì•ˆ 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. ê²°ê³¼ 보기" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOOì— ë³€ê²½ì‚¬í•­ì„ ì„±ê³µì ìœ¼ë¡œ 통보하였습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "YAHOOì— í†µë³´í•˜ëŠ”ë° %time% 초가 걸렸습니다. 만약 ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì§€ 않으면 사ì´íЏ ë§µ ìž‘ì„±ì‹œê°„ì„ ì¤„ì¼ ìˆ˜ 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "YAHOOì— í†µë³´í•˜ëŠ” ë™ì•ˆ 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. ê²°ê³¼ 보기" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +msgid "MSN was successfully notified about changes." +msgstr "MSNì— ë³€ê²½ì‚¬í•­ì„ ì„±ê³µì ìœ¼ë¡œ 통보하였습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +msgid "It took %time% seconds to notify MSN.com, maybe you want to disable this feature to reduce the building time." +msgstr "MSN.comì— í†µë³´í•˜ëŠ”ë° %time% 초가 걸렸습니다. 만약 ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì§€ 않으면 사ì´íЏ ë§µ ìž‘ì„±ì‹œê°„ì„ ì¤„ì¼ ìˆ˜ 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#, php-format +msgid "There was a problem while notifying MSN.com. View result" +msgstr "MSN.comì— í†µë³´í•˜ëŠ” ë™ì•ˆ 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. ê²°ê³¼ 보기" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.comì— ë³€ê²½ì‚¬í•­ì„ ì„±ê³µì ìœ¼ë¡œ 통보하였습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Ask.comì— í†µë³´í•˜ëŠ”ë° %time% 초가 걸렸습니다. 만약 ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì§€ 않으면 사ì´íЏ ë§µ ìž‘ì„±ì‹œê°„ì„ ì¤„ì¼ ìˆ˜ 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Ask.comì— í†µë³´í•˜ëŠ” ë™ì•ˆ 문제가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. ê²°ê³¼ 보기" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "작성 ê³¼ì •ì„ ì™„ë£Œí•˜ëŠ”ë° ì•½ %time% 초가 걸렸고, %memory% MB ì˜ ë©”ëª¨ë¦¬ê°€ 사용 ë˜ì—ˆìŠµë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +msgid "The building process took about %time% seconds to complete." +msgstr "작성 ê³¼ì •ì„ ì™„ë£Œí•˜ëŠ”ë° %time% 초가 걸렸습니다. " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "마지막 ì‹¤í–‰ì´ ì™„ë£Œë˜ì§€ 않았습니다! PHP 스í¬ë¦½íŠ¸ì˜ ì‹œê°„ì œí•œì´ë‚˜ 메모리 한계를 올려 보시기 ë°”ëžë‹ˆë‹¤. ì •ë³´ ë” ë³´ê¸°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "ìµœê·¼ì— ìŠ¤í¬ë¦½íŠ¸ê°€ 사용한 메모리는 %memused%MB ì´ë©°, ì„œë²„ì˜ ë©”ëª¨ë¦¬ 한계는 %memlimit%입니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "ìµœê·¼ì— ìŠ¤íŠ¸ë¦½íŠ¸ê°€ 실행하면서 걸린 ì‹œê°„ì€ %timeused%ì´ˆ ì´ê³ , ì„œë²„ì˜ ì œí•œì‹œê°„ì€ %timelimit%ì´ˆ 입니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "스í¬ë¦½íŠ¸ê°€ í¬ìŠ¤íŠ¸ 넘버 %lastpost% (+/- 100) 부근ì—서 멈추었습니다" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "만약 서버 ë˜ëŠ” ë¸”ë¡œê·¸ì— ë³€ê²½ì‚¬í•­ì´ ìžˆë‹¤ë©´ 수ë™ìœ¼ë¡œ 사ì´íЏ ë§µì„ ìž¬ìž‘ì„±í•´ì•¼ 합니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "만약 작성 ê³¼ì •ì— ì–´ë– í•œ 문제가 ë°œìƒí•œë‹¤ë©´ 디버그 ê¸°ëŠ¥ì„ ì´ìš©í•˜ì—¬ ë” ë§Žì€ ì •ë³´ë¥¼ ì–»ì„ ìˆ˜ 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +msgid "Basic Options" +msgstr "기본 옵션" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +msgid "Sitemap files:" +msgstr "사ì´íЏ ë§µ 파ì¼:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Learn more" +msgstr "ì •ë³´ ë” ë³´ê¸°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3049 +msgid "Write a normal XML file (your filename)" +msgstr "표준 XML íŒŒì¼ ìž‘ì„± ( ì‚¬ìš©ìž íŒŒì¼ì´ë¦„ )" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3055 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "ì••ì¶• íŒŒì¼ ìž‘ì„± ( ì‚¬ìš©ìž íŒŒì¼ì´ë¦„ + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +msgid "Building mode:" +msgstr "작성 모드:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "ë¸”ë¡œê·¸ì˜ ë‚´ìš©ì´ ë³€ê²½ë˜ì—ˆì„ 때 사ì´íЏ ë§µì„ ìž¬ìž‘ì„±í•¨" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +msgid "Enable manual sitemap building via GET Request" +msgstr "GET Request를 통해 ìˆ˜ë™ ì‚¬ì´íЏ ë§µ ìž‘ì„±ì´ ê°€ëŠ¥í† ë¡ í•¨" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "ì´ í•­ëª©ì€ ì›Œë“œí”„ë ˆìŠ¤ API를 사용하지 않고 워드프레스 ë°ì´íƒ€ ë² ì´ìŠ¤ì— ë‚´ìš©ì„ ìž‘ì„±í•˜ëŠ” 외부 í”„ë¡œê·¸ëž¨ì´ ìžˆì„ ë•Œ 사ì´íЏ ë§µì„ ìž¬ìƒì„±í•  수 있ë„ë¡ í•´ì¤ë‹ˆë‹¤. 다ìŒì˜ ë§í¬ë¥¼ ë”°ë¼ ê°€ë©´ ì²˜ë¦¬ê³¼ì •ì„ ì‹œìž‘í•  수 있습니다.: %1 사ì´íЏ ë§µì„ ì„±ê³µì ìœ¼ë¡œ 작성했는지 확ì¸í•˜ë ¤ë©´ ìœ„ì˜ ë¡œê·¸íŒŒì¼ì„ 확ì¸í•˜ì‹œê¸° ë°”ëžë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +msgid "Update notification:" +msgstr "ì—…ë°ì´íЏ 통지:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +msgid "Notify Google about updates of your Blog" +msgstr "ë¸”ë¡œê·¸ì˜ ì—…ë°ì´íŠ¸ë¥¼ Googleì— í†µë³´" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "등ë¡ì´ 필요하진 않지만, 구글 웹마스터 툴 ì— ê°€ìž…í•˜ë©´ 수집 통계를 확ì¸í•  수 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +msgid "Notify MSN Live Search about updates of your Blog" +msgstr "ë¸”ë¡œê·¸ì˜ ì—…ë°ì´íŠ¸ë¥¼ MSN Liveì— í†µë³´" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#, php-format +msgid "No registration required, but you can join the MSN Live Webmaster Tools to check crawling statistics." +msgstr "등ë¡ì´ 필요하진 않지만, MSN Live 웹마스터 툴 ì— ê°€ìž…í•˜ë©´ 수집 통계를 확ì¸í•  수 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +msgid "Notify Ask.com about updates of your Blog" +msgstr "ë¸”ë¡œê·¸ì˜ ì—…ë°ì´íŠ¸ë¥¼ Ask.comì— í†µë³´" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +msgid "No registration required." +msgstr "ë“±ë¡ í•„ìš” ì—†ìŒ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +msgid "Notify YAHOO about updates of your Blog" +msgstr "ë¸”ë¡œê·¸ì˜ ì—…ë°ì´íŠ¸ë¥¼ YAHOOì— í†µë³´" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +msgid "Your Application ID:" +msgstr "ë‹¹ì‹ ì˜ Application ID:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "Key를 가지고 있지 않나요? 여기서 신청하세요! %s2" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3099 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "사ì´íЏ ë§µ 위치를 í¬í•¨í•˜ê³  있는 블로그 ë£¨íŠ¸ì˜ %s 파ì¼ì„ ìƒì„± ë˜ëŠ” 변경합니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3102 +msgid "File permissions: " +msgstr "íŒŒì¼ ê¶Œí•œ:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3107 +msgid "OK, robots.txt is writable." +msgstr "OK, robox.txtê°€ 쓰기 가능한 ìƒíƒœìž…니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3109 +msgid "Error, robots.txt is not writable." +msgstr "Error, robots.txtê°€ 쓰기 불가능한 ìƒíƒœìž…니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3113 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, robots.txt 파ì¼ì€ 존재하지 않지만 디렉토리가 쓰기 가능한 ìƒíƒœìž…니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3115 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Error, robots.txt ê°€ 존재하지 않으며 ë””ë ‰í† ë¦¬ë„ ì“°ê¸° 불가능한 ìƒíƒœìž…니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Advanced options:" +msgstr "고급 옵션:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Limit the number of posts in the sitemap:" +msgstr "사ì´íЏ ë§µì— í¬í•¨ë  í¬ìŠ¤íŠ¸ì˜ ê°¯ìˆ˜ë¥¼ 제한함:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Newer posts will be included first" +msgstr "최근 í¬ìŠ¤íŠ¸ê°€ 먼저 í¬í•¨ë©ë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "Try to increase the memory limit to:" +msgstr "메모리 한계를 ì¦ê°€ì‹œí‚´:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "e.g. \"4M\", \"16M\"" +msgstr "예. \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "Try to increase the execution time limit to:" +msgstr "실행 시간 ì œí•œì„ ì¦ê°€ì‹œí‚¤ë„ë¡í•¨:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "ì´ˆ 단위로 기입, 예.\"60\" ë˜ëŠ” \"0\" (제한 ì—†ìŒ)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Include a XSLT stylesheet:" +msgstr "XSLT 스타ì¼ì‹œíŠ¸ë¥¼ í¬í•¨:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Use Default" +msgstr "기본설정 사용" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Full or relative URL to your .xsl file" +msgstr ".xsl 파ì¼ì˜ ì „ì²´ ë˜ëŠ” ìƒëŒ€ 주소" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "MySQL 스탠다드 모드를 가능하게 함. MySQL ì—러가 ë°œìƒí•  때만 사용하십시오. (ë” ë§Žì€ ë©”ëª¨ë¦¬ê°€ 필요함!)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "백그ë¼ìš´ë“œ 작업으로 사ì´íЏ ë§µì„ ìƒì„± (í¬ìŠ¤íŠ¸ë¥¼ 저장할 때 기다리지 ì•Šì•„ë„ ë©ë‹ˆë‹¤.)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "Exclude the following posts or pages:" +msgstr "다ìŒì˜ í¬ìŠ¤íŠ¸ë‚˜ 페ì´ì§€ë¥¼ 제외:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "List of IDs, separated by comma" +msgstr "콤마로 êµ¬ë¶„ëœ ID 리스트" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +msgid "Additional pages" +msgstr "페ì´ì§€ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "여기서 특정 파ì¼ì´ë‚˜ URLì„ ì‚¬ì´íЏ ë§µì— ì¶”ê°€í•  수 있지만 Blog/WordPressì— ì†í•´ 있는 ê²ƒì€ ì¶”ê°€ í•  수 없습니다.
        예를 들어, ë„ë©”ì¸ì´ www.foo.comì´ê³  ë¸”ë¡œê·¸ì˜ ìœ„ì¹˜ê°€ www.foo.com/blog ë¼ë©´ www.foo.comì„ í™ˆíŽ˜ì´ì§€ë¡œ 추가할 수 있습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +msgid "Note" +msgstr "주ì˜" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "블로그가 서브 ë””ë ‰í† ë¦¬ì— ìœ„ì¹˜í•˜ëŠ”ë° ìƒˆ 페ì´ì§€ë¥¼ 추가하길 ì›í•œë‹¤ë©´ 사ì´íЏ ë§µ 파ì¼ì´ 블로그 디렉토리나 ê·¸ ì•„ëž˜ì— ìžˆìœ¼ë©´ 안ë˜ê³  root ë””ë ‰í† ë¦¬ì— ìžˆì–´ì•¼ 합니다. (ì´ íŽ˜ì´ì§€ì˜ "사ì´íЏ ë§µ 파ì¼ì˜ 위치" ë¶€ë¶„ì„ ë³´ì‹­ì‹œì˜¤.)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +msgid "URL to the page" +msgstr "페ì´ì§€ì˜ 주소" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "페ì´ì§€ì˜ 주소를 입력하십시오.예:http://www.foo.com/index.html or www.foo.com/home" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +msgid "Priority" +msgstr "우선순위" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "다른 페ì´ì§€ì— 비êµí•˜ì—¬ 페ì´ì§€ì˜ ìš°ì„  순위를 ì„ íƒí•˜ì‹­ì‹œì˜¤. 예를 들어 홈페ì´ì§€ëŠ” 다른 ê²ƒì— ë¹„í•´ ë†’ì€ ìš°ì„  순위를 가져야 합니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +msgid "Last Changed" +msgstr "마지막 변경" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "최근 ë³€ê²½ëœ ë‚ ì§œë¥¼ YYYY-MM-DD (예 : 2005-12-31 ) 형ì‹ìœ¼ë¡œ 입력하십시오 ( ì„ íƒì‚¬í•­ )" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +msgid "Change Frequency" +msgstr "변경 빈ë„" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +msgid "#" +msgstr "#" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +msgid "No pages defined." +msgstr "페ì´ì§€ê°€ 지정ë˜ì§€ 않았습니다." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +msgid "Add new page" +msgstr "새 페ì´ì§€ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +msgid "Post Priority" +msgstr "í¬ìŠ¤íŠ¸ 우선순위" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +msgid "Please select how the priority of each post should be calculated:" +msgstr "ê° í¬ìŠ¤íŠ¸ì˜ ìš°ì„ ìˆœìœ„ë¥¼ 어떻게 계산할 것ì¸ì§€ ì„ íƒí•´ 주십시오:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "Do not use automatic priority calculation" +msgstr "ìžë™ 우선순위 ê³„ì‚°ì„ ì‚¬ìš©í•˜ì§€ 않ìŒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "모든 í¬ìŠ¤íŠ¸ê°€ "ìš°ì„ ê¶Œ"ì—서 ì„¤ì •ëœ ìš°ì„ ìˆœìœ„ë¥¼ 같게 ë©ë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3348 +msgid "Location of your sitemap file" +msgstr "사ì´íЏ ë§µ 파ì¼ì˜ 위치" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3353 +msgid "Automatic detection" +msgstr "ìžë™ íƒì§€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3357 +msgid "Filename of the sitemap file" +msgstr "사ì´íЏ ë§µ 파ì¼ì˜ ì´ë¦„" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +msgid "Detected Path" +msgstr "íƒì§€ëœ 경로" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +msgid "Detected URL" +msgstr "íƒì§€ëœ 주소" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3365 +msgid "Custom location" +msgstr "커스텀 로케ì´ì…˜" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3369 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "파ì¼ì´ë¦„ì„ í¬í•¨í•œ 사ì´íЏ ë§µ 파ì¼ì˜ 절대 ë˜ëŠ” ìƒëŒ€ 경로" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3371 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3380 +msgid "Example" +msgstr "예제" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3378 +msgid "Complete URL to the sitemap file, including name." +msgstr "파ì¼ì´ë¦„ì„ í¬í•¨í•œ 사ì´íЏ ë§µ 파ì¼ì˜ 완전한 주소." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +msgid "Sitemap Content" +msgstr "사ì´íЏ ë§µ ë‚´ìš©" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +msgid "Include homepage" +msgstr "홈페ì´ì§€ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +msgid "Include posts" +msgstr "í¬ìŠ¤íŠ¸ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +msgid "Include static pages" +msgstr "ì •ì  íŽ˜ì´ì§€ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +msgid "Include categories" +msgstr "카테고리 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +msgid "Include archives" +msgstr "ì•„ì¹´ì´ë¸Œ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +msgid "Include tag pages" +msgstr "íƒœí¬ íŽ˜ì´ì§€ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +msgid "Include author pages" +msgstr "ìž‘ì„±ìž íŽ˜ì´ì§€ 추가" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +msgid "Change frequencies" +msgstr "수집 ë¹ˆë„ ë³€ê²½" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "ê° íƒœê·¸ì— ìžˆëŠ” ìˆ˜ì¹˜ë“¤ì€ ê³ ë ¤í•  수 있는 ì‚¬í•­ì¼ ë¿ ì ˆëŒ€ì ì¸ ëª…ë ¹ì€ ì•„ë‹™ë‹ˆë‹¤. 서치 ì—”ì§„ì˜ Crawlerê°€ ì•„ëž˜ì˜ ì •ë³´ë¥¼ 수집 ê²°ì •ì„ ë‚´ë¦´ 때 고려한다고 í•´ë„ \"매시간\" 으로 ëœ íŽ˜ì´ì§€ë¥¼ ë” ê¸´ 주기로 수집할 ìˆ˜ë„ ìžˆê³  \"매년\" 으로 ëœ íŽ˜ì´ì§€ë¥¼ ë” ì§§ì€ ì£¼ê¸°ë¡œ 수집할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. ì´ê²ƒì€ \"하지않ìŒ\"으로 ëœ íŽ˜ì´ì§€ë„ 마찬가지로 ì£¼ê¸°ì  ìˆ˜ì§‘ì„ í•  ìˆ˜ë„ ìžˆì–´ì„œ 그러한 페ì´ì§€ì— ë°œìƒí•œ 변화를 예기치 않게 수집할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +msgid "Homepage" +msgstr "홈페ì´ì§€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +msgid "Posts" +msgstr "í¬ìŠ¤íŠ¸ë“¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +msgid "Static pages" +msgstr "ì •ì  íŽ˜ì´ì§€ë“¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +msgid "Categories" +msgstr "카테고리들" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "ì´ë²ˆ ë‹¬ì˜ ì•„ì¹´ì´ë¸Œ ( 홈페ì´ì§€ì™€ 같아야 합니다.)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "ì˜¤ëž˜ëœ ì•„ì¹´ì´ë¸Œ ( 예전 í¬ìŠ¤íŠ¸ë¥¼ ìˆ˜ì •í–ˆì„ ë•Œë§Œ 변경 하십시오.)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +msgid "Tag pages" +msgstr "태그 페ì´ì§€ë“¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +msgid "Author pages" +msgstr "ìž‘ì„±ìž íŽ˜ì´ì§€ë“¤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +msgid "Priorities" +msgstr "ìš°ì„ ê¶Œ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +msgid "Posts (If auto calculation is disabled)" +msgstr "í¬ìŠ¤íŠ¸ ( 만약 ìžë™ ê³„ì‚°ì´ ì¤‘ì§€ ë˜ì—ˆì„ 경우 )" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "최소 í¬ìŠ¤íŠ¸ ìš°ì„ ê¶Œ (만약 ìžë™ ê³„ì‚°ì´ í™œì„±í™” ë˜ì–´ìžˆì„ 때ë„)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +msgid "Archives" +msgstr "ì•„ì¹´ì´ë¸Œ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +msgid "Update options" +msgstr "옵션 ì—…ë°ì´íЏ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +msgid "Reset options" +msgstr "옵션 초기화" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-nl_NL.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-nl_NL.mo new file mode 100644 index 0000000..d3e84e1 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-nl_NL.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-nl_NL.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-nl_NL.po new file mode 100644 index 0000000..6a3896a --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-nl_NL.po @@ -0,0 +1,505 @@ +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2008-03-15 10:27+0100\n" +"Last-Translator: forkless \n" +"Language-Team: Arne Brachhold \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" + +msgid "Comment Count" +msgstr "Aantal Reacties" + +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Gebruikt het aantal reacties van het bericht om de prioriteit te berekenen" + +msgid "Comment Average" +msgstr "Reactie Gemiddelde" + +msgid "Uses the average comment count to calculate the priority" +msgstr "Gebruik het reactie gemiddelde om de prioriteit te berekenen" + +msgid "Popularity Contest" +msgstr "Popularity Contest" + +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Gebruikt het geactiveerde Popularity Contest Plugin van Alex King. Zie instellingen en meest populaire berichten" + +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Hartelijke dank voor je donatie! Je helpt hierbij deze gratis plugin te ondersteunen en verder te ontwikkelen!" + +msgid "Hide this notice" +msgstr "Deze melding verbergen" + +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Bedankt voor het gebruiken van deze plugin! Je hebt deze plugin meer dan een maand geleden geinstalleerd. Wanneer het naar behoren werkt en je met het resultaat tevreden bent is het dan niet minsten één dollar waard? Donaties helpen mij deze diese gratis software te ondersteunen en verder te ontwikkelen! Natuurlijk, geen probleem! " + +msgid "No thanks, please don't bug me anymore!" +msgstr "Nee dankjewel, val me hier niet meer mee lastig! " + +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Sitemap Generator voor WordPress" + +msgid "Configuration updated" +msgstr "De instellingen zijn opgeslagen" + +msgid "Error while saving options" +msgstr "Bij het opslaan van de instellingen is een fout opgetreden." + +msgid "Pages saved" +msgstr "Pagina's opgeslagen" + +msgid "Error while saving pages" +msgstr "Bij het opslaan van de pagina's is een fout opgetreden" + +msgid "Robots.txt file saved" +msgstr "Robots.txt bestand opgeslagen" + +msgid "Error while saving Robots.txt file" +msgstr "Er is een fout opgetreden tijdens het opslaan van robots.txt" + +msgid "The default configuration was restored." +msgstr "De standaard instellingen zijn weer hersteld." + +msgid "open" +msgstr "openen" + +msgid "close" +msgstr "sluiten" + +msgid "click-down and drag to move this box" +msgstr "Klik en sleep om dit venster te verplaatsen" + +msgid "click to %toggle% this box" +msgstr "Klik om dit venster te %toggle%" + +msgid "use the arrow keys to move this box" +msgstr "gebruik de cursor toetsen om dit venster te verplaatsen" + +msgid ", or press the enter key to %toggle% it" +msgstr ", of druk op de enter toets om het te %toggle%" + +msgid "About this Plugin:" +msgstr "Over deze plugin:" + +msgid "Plugin Homepage" +msgstr "Plugin homepage" + +msgid "Notify List" +msgstr "E-Mail wanneer er een update is" + +msgid "Support Forum" +msgstr "Support Forum" + +msgid "Donate with PayPal" +msgstr "Met PayPal doneren" + +msgid "My Amazon Wish List" +msgstr "Amazon wensenlijst" + +msgid "translator_name" +msgstr "Mark Peters" + +msgid "translator_url" +msgstr "http://www.zinloosverteld.nl" + +msgid "Sitemap Resources:" +msgstr "Sitemap informatie:" + +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +msgid "Site Explorer" +msgstr "Site Explorer" + +msgid "Search Blog" +msgstr "Doorzoek Blog" + +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +msgid "Sitemaps Protocol" +msgstr "Sitemaps Protocol" + +msgid "Official Sitemaps FAQ" +msgstr "Officiële Sitemaps FAQ" + +msgid "My Sitemaps FAQ" +msgstr "Mijn Sitemaps FAQ" + +msgid "Recent Donations:" +msgstr "Recente Donaties:" + +msgid "List of the donors" +msgstr "Lijst van donateurs" + +msgid "Hide this list" +msgstr "Lijst verbergen" + +msgid "Thanks for your support!" +msgstr "Bedankt voor je support!" + +msgid "Status" +msgstr "Status" + +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "De sitemap is nog niet gegenereerd. Klik hier om deze voor de eerste keer aan te maken." + +msgid "Your sitemap was last built on %date%." +msgstr "Jouw Sitemap werd voor het laatst op %date% gegenereerd." + +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreMeer informatiezipped) was last built on %date%." +msgstr "Jouw (gezipt) sitemap werd voor het laatst op %date% gegenereerd." + +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreMeer informatiesuccessfully notified
        about changes." +msgstr "Google is succesvol op de hoogte gesteld van de veranderingen." + +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Het duurde %time% seconden om Google op de hoogte te stellen. Misschien wil je deze optie deactiveren om de doorlooptijd van de sitemap generatie te verkorten?" + +msgid "There was a problem while notifying Google. View result" +msgstr "Er was een probleem bij het informeren van Google. Resultaat weergeven" + +msgid "YAHOO was successfully notified about changes." +msgstr "Yahoo is succesvol op de hoogte gesteld van de veranderingen." + +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Het duurde %time% seconden om Yahoo op de hoogte te stellen. Misschien wil je deze optie deactiveren om de doorlooptijd van de sitemap generatie te verkorten?" + +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Er was een probleem bij het informeren van Yahoo. Resultaat weergeven" + +msgid "MSN was successfully notified about changes." +msgstr "MSN.com is succesvol op de hoogte gesteld van de veranderingen." + +msgid "It took %time% seconds to notify MSN.com, maybe you want to disable this feature to reduce the building time." +msgstr "Het duurde %time% seconden om MSN.com op de hoogte te stellen. Misschien wil je deze optie deactiveren om de doorlooptijd van de sitemap generatie te verkorten?" + +msgid "There was a problem while notifying MSN.com. View result" +msgstr "Er was een probleem bij het informeren van MSN.com. Resultaat weergeven" + +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com is succesvol op de hoogte gesteld van de veranderingen." + +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Het duurde %time% seconden om Ask.com op de hoogte te stellen. Misschien wil je deze optie deactiveren om de doorlooptijd van de sitemap generatie te verkorten?" + +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Er was een probleem bij het informeren van Ask.com. Resultaat weergeven" + +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Het sitemap genereren duurde %time% seconden en gebruikte %memory%MB geheugen." + +msgid "The building process took about %time% seconds to complete." +msgstr "Het sitemap genereren duurde %time% seconden." + +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "De inhoud van de sitemap heeft zich niet gewijzigd sinds de laatste keer, als gevolgd zijn er geen bestanden weggeschreven en zijn de zoekmachines niet op de hoogte gesteld." + +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "De laatste generatie van de sitemap is niet afgesloten! Het kan helpen de geheugenlimiet voor PHP scripts te verhogen. Meer informatie" + +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "Het laatst bekende geheugengebruik van het script lag op %memused%MB, het limiet voor PHP scripts op deze server is %memlimit%." + +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "De laatst bekende doorlooptijd lag op %timeused% seconden, het limiet voor PHP scripts voor deze server is %timelimit% seconden." + +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Het script is ongeveer gestopt bij bericht nummer %lastpost% (+/- 100)" + +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Wanneer er iets gewijzigd is op de server of aan het Blog, dan kan men de sitemap met de hand opnieuw genereren." + +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Indien er bij het genereren van de sitemap problemen zijn kan men de Debug Functie gebruiken om meer informatie over de opgetreden fout te achterhalen." + +msgid "Basic Options" +msgstr "Basisinstellingen" + +msgid "Sitemap files:" +msgstr "Sitemap bestanden:" + +msgid "Learn more" +msgstr "Meer informatie" + +msgid "Write a normal XML file (your filename)" +msgstr "Sitemap als XML bestand aanmaken (bestandsnaam)" + +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Gezipte sitemap aanmaken (bestandsnaam + .gz)" + +msgid "Building mode:" +msgstr "Generatie mode::" + +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Sitemap opnieuw genereren wanneer je de inhoud van je Blog wijzigt" + +msgid "Enable manual sitemap building via GET Request" +msgstr "Handmatig genereren van de sitemap via GET aanvragen toestaan" + +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Hiermee kun je je sitemap opnieuw genereren indien een externe tool in de database van WordPress geschreven heeft zonder gebruik te maken van de API. Gebruik de volgende URL om het process te starten: %1 Controleer het logbestand hierboven om te kijken of de sitemap succesvol is gegenereerd." + +msgid "Update notification:" +msgstr "Wijzigings notificatie:" + +msgid "Notify Google about updates of your Blog" +msgstr "Google YAHOO op de hoogte stellen van de Blog wijzigingen" + +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Registratie niet noodzakelijk, maar je kunt je optioneel aanmelden bij de Google Webmaster Tools om de indexeringsstatistieken van de site te bekijken." + +msgid "Notify MSN Live Search about updates of your Blog" +msgstr "MSN Live Search op de hoogte stellen van de Blog wijzigingen" + +msgid "No registration required, but you can join the MSN Live Webmaster Tools to check crawling statistics." +msgstr "Registratie niet noodzakelijk, maar je kunt je optioneel aanmelden bij de MSN Live Webmaster Tools om de indexeringsstatistieken van de site te bekijken." + +msgid "Notify Ask.com about updates of your Blog" +msgstr "Ask.com YAHOO op de hoogte stellen van de Blog wijzigingen" + +msgid "No registration required." +msgstr "Geen registratie noodzakelijk" + +msgid "Notify YAHOO about updates of your Blog" +msgstr "YAHOO op de hoogte stellen van de Blog wijzigingen" + +msgid "Your Application ID:" +msgstr "Jouw Application ID:" + +msgid "Don't you have such a key? Request one here! %s2" +msgstr "Nog geen key? Hier aanvragen! %s2" + +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "Maak of wijzig het %s bestand in de root directory van je Blog." + +msgid "File permissions: " +msgstr "Bestands permissies:" + +msgid "OK, robots.txt is writable." +msgstr "OK, robots.txt kan weggeschreven worden." + +msgid "Error, robots.txt is not writable." +msgstr "Error, robots.txt kan niet weggeschreven worden." + +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, robots.txt bestaat nog niet, maar de directory kan beschreven worden." + +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Error, robots.txt bestaat niet en de directory is niet beschrijfbaar" + +msgid "Advanced options:" +msgstr "Uitgebreide instellingen" + +msgid "Limit the number of posts in the sitemap:" +msgstr "Het aantal berichten in de sitemap limiteren:" + +msgid "Newer posts will be included first" +msgstr "Nieuwe berichten worden het eerst opgenomen" + +msgid "Try to increase the memory limit to:" +msgstr "Probeer de geheugenlimiet te verhogen naar: " + +msgid "e.g. \"4M\", \"16M\"" +msgstr "bijv. \"4M\", \"16M\"" + +msgid "Try to increase the execution time limit to:" +msgstr "Probeer de tijdslimiet van de generatie aan te passen naar:" + +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "in seconden, bijv. \"60\" of \"0\" voor geen limiet" + +msgid "Include a XSLT stylesheet:" +msgstr "XSLT stylesheet toevoegen:" + +msgid "Use Default" +msgstr "Gebruik de standaard" + +msgid "Full or relative URL to your .xsl file" +msgstr "Volledige of relatieve pad naar het .xsl bestand" + +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "MySQL standaard mode activeren. Gebruik deze optie indien MYSQL fouten optreden (gebruikt meer geheugen!)" + +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Genereer de sitemap in de achtergrond (Hierdoor is er geen wachttijd wanneer er een bericht wordt geplaatst)" + +msgid "Exclude the following posts or pages:" +msgstr "Volgende berichten of pagina's uitsluiten:" + +msgid "List of IDs, separated by comma" +msgstr "Lijst van de IDs, gescheiden door komma" + +msgid "Additional pages" +msgstr "Addtionele pagina's" + +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Hier kunnen de bestanden of URLHier können Sie zusätzliche Seiten in Form von URLs angeben, welche mit in Ihre Sitemap aufgenommen werden sollen aber nicht von WordPress erzeugt werden. Falls Sie z.B. Ihre Homepage auf www.beispiel.com haben, Ihr Blog aber unter www.beispiel.com/blog zu erreichen ist, tragen Sie Ihre Homepage als http://www.beispiel.com hier ein." + +msgid "Note" +msgstr "Notitie" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Indien het Blog in een subdirectory staat en je wilt pagina's toevoegen die NIET in de Blog of onderliggende directories liggen, dan MOET je je sitemap bestand in de root direcotry van de webserver plaatsten. (Kijk naar de "Locatie van het sitemap bestand" sectiew op deze pagina)!" + +msgid "URL to the page" +msgstr "URL naar de pagina" + +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Vul hier de URL naar de pagina in. Voorbeeld: http://www.zinloosverteld.nl of http://www.zinloosverteld.nl/blog" + +msgid "Priority" +msgstr "Prioriteit" + +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Kies hier de prioriteit van de pagina relatief ten opzichte van andere pagina's. Bijvoorbeeld, de homepage heeft een hogere prioriteit dan een colofon pagina." + +msgid "Last Changed" +msgstr "Laatste wijziging" + +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Voer hier de laatste wijziging in in het formaat JJJJ-MM-DD (bijv. 2005-12-31). Dit veld is optioneel en hoeft niet ingevuld te worden." + +msgid "Change Frequency" +msgstr "Wijzigingsfrequentie" + +msgid "#" +msgstr "#" + +msgid "No pages defined." +msgstr "Er zijn geen pagina's gedefiniëerd." + +msgid "Add new page" +msgstr "Nieuwe pagina toevoegen" + +msgid "Post Priority" +msgstr "Bericht prioriteit" + +msgid "Please select how the priority of each post should be calculated:" +msgstr "Kies hier de berekeningsmethode voor de prioriteit van de berichten." + +msgid "Do not use automatic priority calculation" +msgstr "Geen automatische prioriteitsberekening gebruiken" + +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Alle berichten hebben dezelfde prioriteit die onder "Prioriteiten" is ingesteld." + +msgid "Location of your sitemap file" +msgstr "Locatie van het sitemap bestand" + +msgid "Automatic detection" +msgstr "Automatische herkenning" + +msgid "Filename of the sitemap file" +msgstr "Bestandsnaam van de sitemap" + +msgid "Detected Path" +msgstr "Herkend pad" + +msgid "Detected URL" +msgstr "Herkende URL" + +msgid "Custom location" +msgstr "Handmatig ingesteld pad" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Absoluut of relatief pad naar het sitemap bestand inclusief bestandsnaam." + +msgid "Example" +msgstr "Voorbeeld" + +msgid "Complete URL to the sitemap file, including name." +msgstr "Absolute URL naar het sitemap bestand inclusief de bestandsnaam." + +msgid "Sitemap Content" +msgstr "Sitemap inhoud" + +msgid "Include homepage" +msgstr "Bevat homepage" + +msgid "Include posts" +msgstr "Bevat berichten" + +msgid "Include static pages" +msgstr "Bevat statische pagina's" + +msgid "Include categories" +msgstr "Bevat categorieën" + +msgid "Include archives" +msgstr "Bevat archieven" + +msgid "Include tag pages" +msgstr "Bevag tag pagina's" + +msgid "Include author pages" +msgstr "Bevat auteur pagina's" + +msgid "Change frequencies" +msgstr "Wijzigingsfrequentie" + +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Let er op dat de waarde van deze tag als tip gezien wordt en niet als commando. Zoekmachines kunnen deze tip oppakken, echter hoeven zij zich er niet aan te houden. Ze kunnen pagina's per \"Hourly\" gemarkeerd minder bezoeken. En pagina's gemarkeerd \"Yearly\" kunnen frequentere controles krijgen. Ook pagina's gemarkeerd \"Never\" kunnen worden bezocht om zo onverwachte veranderingen op te pakken." + +msgid "Homepage" +msgstr "Homepage" + +msgid "Posts" +msgstr "Berichten" + +msgid "Static pages" +msgstr "Statische pagina's" + +msgid "Categories" +msgstr "Categorieën" + +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Het archief van de huidige maand (Zou hetzelfde moeten zijn als de homepage)" + +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Archieven van voorgaande maanden" + +msgid "Tag pages" +msgstr "Tag pagina's" + +msgid "Author pages" +msgstr "Auteur pagina's" + +msgid "Priorities" +msgstr "Prioriteiten" + +msgid "Posts (If auto calculation is disabled)" +msgstr "Berichten (Wanneer automatische berekening is geactiveerd)" + +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Minimale prioriteit voor berichten (ook wanneer de automatische berekening is geactiveerd)" + +msgid "Archives" +msgstr "Archieven" + +msgid "Update options" +msgstr "Instellingen opslaan" + +msgid "Reset options" +msgstr "Instellingen herstellen" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pl_PL.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pl_PL.mo new file mode 100644 index 0000000..8e7168b Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pl_PL.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pl_PL.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pl_PL.po new file mode 100644 index 0000000..e59e399 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pl_PL.po @@ -0,0 +1,640 @@ +# Polish Language File for Google XML Sitemaps - sitemap-pl_PL.po) +# Copyright (C) 2007 Kuba Zwolinski : http://kubazwolinski.com +# This file is distributed under the same license as the WordPress package. +# kuba , 2007. +# $Id: sitemap-pl_PL.po 2504 2007-10-03 09:19:18Z +# +msgid "" +msgstr "" +"Project-Id-Version: Google Sitemap Generator PL\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2007-12-30 12:52+0100\n" +"Last-Translator: Kuba Zwolinski \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: SnowDog \n" +"X-Poedit-Language: Polish\n" +"X-Poedit-Country: POLAND\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e\n" +"X-Poedit-Basepath: .\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:846 +msgid "Comment Count" +msgstr "Liczba komentarzy" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:858 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Używa liczbÄ™ komentarzy do obliczania priorytetu wpisu" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:918 +msgid "Comment Average" +msgstr "Åšrednia komentarzy" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:930 +msgid "Uses the average comment count to calculate the priority" +msgstr "Używa Å›redniÄ… liczbÄ™ komentarzy do obliczania priorytetu wpisu" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:993 +msgid "Popularity Contest" +msgstr "Konkurs popularnoÅ›ci" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:1005 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Używa włączonej wtyczki Popularity Contest od Alex King. Zobaczustawienia i najbardziej popularne wpisy" + +msgid "XML-Sitemap Generator" +msgstr "Generator XML-Sitemap" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2397 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2582 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Wielkie dziÄ™ki za wsparcie. Pomagasz mi rozwijać tÄ™ wtyczkÄ™ oraz inne darmowe oprogramowanie!" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2582 +msgid "Hide this notice" +msgstr "Ukryj tÄ™ informacjÄ™" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2606 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "DziÄ™ki za używanie tej wtyczki! Wtyczka zostaÅ‚a zainstalowana ponad miesiÄ…c temu. JeÅ›li dziaÅ‚a dobrze i rezultaty sa zgodne z Twoimi oczekiwaniami, czy nie jest to wart paru zÅ‚otych? Dotacje pomagajÄ… mi kontynuowac rozwój wtyczki oraz zapewnić pomoc technicznÄ… użytkownikom tego darmowego programu! Jasne, bardzo chÄ™tnie!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2606 +msgid "No thanks, please don't bug me anymore!" +msgstr "Nie, dziÄ™ki. I nie zawracaj mi wiÄ™cej tym gÅ‚owy!" + +msgid "XML Sitemap Generator for WordPress" +msgstr "Generator XML-Sitemap" + +msgid "Configuration updated" +msgstr "Konfiguracja zaktualizowana" + +msgid "Error while saving options" +msgstr "WystÄ…piÅ‚ błąd podczas zapisywania opcji" + +msgid "Pages saved" +msgstr "Strony zostaÅ‚y zapisane" + +msgid "Error while saving pages" +msgstr "WystÄ…piÅ‚ błąd podczas zapisywania stron." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2711 +#, php-format +msgid "Robots.txt file saved" +msgstr "Plik Robots.txt zostaÅ‚ zapisany" + +msgid "Error while saving Robots.txt file" +msgstr "WystÄ…piÅ‚ błąd podczas zapisu pliku Robots.txt" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2721 +msgid "The default configuration was restored." +msgstr "DomyÅ›lna konfiguracja zostaÅ‚a przywrócona." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2814 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2831 +msgid "open" +msgstr "otworzyć" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2815 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2832 +msgid "close" +msgstr "zamknąć" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2816 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2833 +msgid "click-down and drag to move this box" +msgstr "wciÅ›nik klawisz i przeciÄ…gnij żeby przesunąć" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2817 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2834 +msgid "click to %toggle% this box" +msgstr "kliknij aby %toggle% to pole" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2818 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2835 +msgid "use the arrow keys to move this box" +msgstr "użyj kursorów aby przesunąć ten blok" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2819 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2836 +msgid ", or press the enter key to %toggle% it" +msgstr ", lub wciÅ›nij enter aby %toggle%" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2847 +msgid "About this Plugin:" +msgstr "O wtyczce:" + +msgid "Plugin Homepage" +msgstr "Strona główna wtyczki" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2850 +msgid "Notify List" +msgstr "Lista zmian wtyczki" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2851 +msgid "Support Forum" +msgstr "Forum pomocy" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2852 +msgid "Donate with PayPal" +msgstr "Wspomóż nas przez PayPal" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2853 +msgid "My Amazon Wish List" +msgstr "Lista życzeÅ„ Amazon" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2854 +msgid "translator_name" +msgstr "Strona tÅ‚umaczenia" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2854 +msgid "translator_url" +msgstr "http://kubazwolinski.com/wordpress/tlumaczenie-wtyczki-google-xml-sitemaps/" + +msgid "Sitemap Resources:" +msgstr "O mapie strony:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2860 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2861 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2863 +msgid "Site Explorer" +msgstr "Site Explorer" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2864 +msgid "Search Blog" +msgstr "Search Blog" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2861 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +msgid "Sitemaps Protocol" +msgstr "Sitemaps Protocol" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2867 +msgid "Official Sitemaps FAQ" +msgstr "Official Sitemaps FAQ" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2868 +msgid "My Sitemaps FAQ" +msgstr "FAQ wtyczki" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2873 +msgid "Recent Donations:" +msgstr "Ostatnie dotacje:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2877 +msgid "List of the donors" +msgstr "Lista darczyÅ„ców" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2879 +msgid "Hide this list" +msgstr "Ukryj tÄ™ listÄ™" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2882 +msgid "Thanks for your support!" +msgstr "DziÄ™ki za wsparcie!" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2894 +msgid "Status" +msgstr "Status" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2904 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Mapa strony nie zostaÅ‚a jeszcze zbudowana. Kliknij tutaj, aby jÄ… zbudować po raz pierwszy." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2910 +msgid "Your sitemap was last built on %date%." +msgstr "Ostatnia modyfikacja twojej mapy strony: %date%." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2912 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreDowiedz siÄ™ wiÄ™cejzipped) was last built on %date%." +msgstr "Ostatnia modyfikacja twojej spakowanej mapy strony: %date%." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2921 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreDowiedz siÄ™ wiÄ™cejsuccessfully notified about changes." +msgstr "Google zostaÅ‚ pomyÅ›lnie powiadomiony o zmianach." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2930 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Powiadomienie Google zajęło %time% sekund, możesz wyłączyć tÄ™ opcjÄ™, aby zredukować czas publikacji." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2933 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "WystÄ…piÅ‚ problem z powiadomieniem Google. Obejrzyj rezultat" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2939 +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOO zostaÅ‚ pomyÅ›lnie powiadomiony o zmianach." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2942 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Powiadomienie YAHOO zajęło %time% sekund, możesz wyłączyć tÄ™ opcjÄ™, aby zredukować czas publikacji." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2945 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "WystÄ…piÅ‚ problem z powiadomieniem YAHOO. Obejrzyj rezultat" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2939 +msgid "MSN was successfully notified about changes." +msgstr "MSN zostaÅ‚ pomyÅ›lnie powiadomiony o zmianach." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2954 +msgid "It took %time% seconds to notify MSN.com, maybe you want to disable this feature to reduce the building time." +msgstr "Powiadomienie MSN.com zajęło %time% sekund, możesz wyłączyć tÄ™ opcjÄ™, aby zredukować czas publikacji." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2957 +#, php-format +msgid "There was a problem while notifying MSN.com. View result" +msgstr "WystÄ…piÅ‚ problem z powiadomieniem MSN.com. Obejrzyj rezultat" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2951 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com zostaÅ‚ pomyÅ›lnie powiadomiony o zmianach." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2954 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Powiadomienie Ask.com zajęło %time% sekund, możesz wyłączyć tÄ™ opcjÄ™, aby zredukować czas publikacji." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2957 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "WystÄ…piÅ‚ problem z powiadomieniem Ask.com. Obejrzyj rezultat" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2965 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Proces budowy mapy zajÄ…Å‚ %time% sek. i wykorzystaÅ‚ %memory% MB pamiÄ™ci." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2967 +msgid "The building process took about %time% seconds to complete." +msgstr "Proces budowy mapy zajÄ…Å‚ %time% sek." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2971 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Zawartość twojej mapy nie zmieniÅ‚a siÄ™ /strong> od ostatniego razu, wiÄ™c pliki nie zostaÅ‚y nadpisane i żadna wyszukiwarka nie zostaÅ‚a powiadomiona." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2975 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "Ostatnia operacja nie zostaÅ‚a zakoÅ„czona! Może należy zwiÄ™kszyć limit pamieci lub czasu wykonywania dla skryptów PHP. Dowiedz siÄ™ wiÄ™cej" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2977 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "Ostatnie znane zużycie pamiÄ™ci wyniosÅ‚o %memused%MB, limit twojego serwera to %memlimit%." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2981 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "Ostatni znany czas wykonywania skryptu wyniósÅ‚ %timeused% sek., limit twojego serwera wynosi %timelimit% sek." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2985 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Skrypt przerwaÅ‚ wykonywanie w okolicach wpisu nr %lastpost% (+/- 100)" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2988 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "JeÅ›li na blogu coÅ› zostaÅ‚o zmienione, należy przebudować mapÄ™ rÄ™cznie." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:2990 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "JeÅ›li napotkasz jakiÅ› problem podczas procesu budowy mapy, możesz użyć funkcji debugowania aby uzyskać wiÄ™cej informacji." + +msgid "Basic Options" +msgstr "Opcje podstawowe" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3007 +msgid "Sitemap files:" +msgstr "Pliki mapy strony:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3007 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3022 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3042 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3067 +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3084 +msgid "Learn more" +msgstr "Dowiedz siÄ™ wiÄ™cej" + +msgid "Write a normal XML file (your filename)" +msgstr "Zapisz normalny plik XML (wÅ‚asna nazwa)" + +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Zapisz plik gzip (wÅ‚asna nazwa + .gz)" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3022 +msgid "Building mode:" +msgstr "Tryb budowy:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3027 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Przebudowuj mapÄ™ przy zmianie zawartoÅ›ci bloga" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3034 +msgid "Enable manual sitemap building via GET Request" +msgstr "Włącz manualne przebudowywanie mapy przez polecenie GET" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3038 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Ta opcja pozwoli na odÅ›wieżenie mapy strony jeÅ›li jakieÅ› zewnÄ™trzne narzÄ™dzie dokona zapisu w bazie danych WordPress z pominiÄ™ciem WordPress API. Użyj nastÄ™pujÄ…cego adresu w celu rozpoczÄ™cia procesu: %1 Sprawdź plik logu powyżej, aby sprawdzić czy mapa zostaÅ‚a odpowiednio przebudowana." + +msgid "Update notification:" +msgstr "Powiadomienia o aktualizacjach:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3046 +msgid "Notify Google about updates of your Blog" +msgstr "Powiadamiaj Google o aktualizacjach twojego bloga" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3047 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Rejestracja nie jest wymagana, ale możesz sprawdzić Google Webmaster Tools aby kontrolować statystyki indeksowania." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3046 +msgid "Notify MSN Live Search about updates of your Blog" +msgstr "Powiadamiaj MSN Live Search o aktualizacjach twojego bloga" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3047 +#, php-format +msgid "No registration required, but you can join the MSN Live Webmaster Tools to check crawling statistics." +msgstr "Rejestracja nie jest wymagana, ale możesz sprawdzić MSN Live Webmaster Tools aby kontrolować statystyki indeksowania." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3051 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Powiadamiaj Ask.com o aktualizacjach twojego bloga" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3052 +msgid "No registration required." +msgstr "Rejestracja nie jest konieczna" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3056 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Powiadamiaj YAHOO o aktualizacjach twojego bloga" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +msgid "Your Application ID:" +msgstr "ID aplikacji:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "Nie masz takiego klucza? Zamów go tutaj! %s2" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3062 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "Modyfikuj lub utwórz plik %s w katalogu strony gdzie znajduje siÄ™ mapa strony." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3065 +msgid "File permissions: " +msgstr "Status pliku: " + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3070 +msgid "OK, robots.txt is writable." +msgstr "OK, plik robots.txt ma prawa do zapisu." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3072 +msgid "Error, robots.txt is not writable." +msgstr "Błąd, plik robots.txt nie ma praw do zapisu." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3076 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, plik robots.txt nie istnieje, ale katalog ma prawa do zapisu przez serwer." + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3078 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Błąd, plik robots.txt nie istnieje i katalog nie ma prawa do zapisu przez serwer" + +msgid "Advanced options:" +msgstr "Zaawansowane opcje:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3087 +msgid "Limit the number of posts in the sitemap:" +msgstr "Limituj ilość wpisów w mapie:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3087 +msgid "Newer posts will be included first" +msgstr "Nowsze wpisy bÄ™dÄ… załączone jako pierwsze" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3090 +msgid "Try to increase the memory limit to:" +msgstr "Spróbuj zwiÄ™kszyć limit pamiÄ™ci do:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3090 +msgid "e.g. \"4M\", \"16M\"" +msgstr "np. \"4M\", \"16M\"" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3093 +msgid "Try to increase the execution time limit to:" +msgstr "Spróbuj zwiÄ™kszyć limit czasu wykonywania do:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3093 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "w sekundach, np. \"60\" lub \"0\" dla nieograniczonego" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3096 +msgid "Include a XSLT stylesheet:" +msgstr "Załącz arkusz stylu XSLT: " + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3096 +msgid "Use Default" +msgstr "Użyj wartoÅ›ci domyÅ›lnych" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3096 +msgid "Full or relative URL to your .xsl file" +msgstr "Absolutna lub relatywna Å›cieżka to twojego plik .xsl " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Włącz standardowy tryb MySQL. Użyj tego tylko w przypadku wystÄ™powania błędów MySQL (zużywa duzo wiÄ™cej pamiÄ™ci!)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Buduj mapÄ™ strony w tle (nie musisz czekać kiedy zapisujesz swój wpis)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "Exclude the following posts or pages:" +msgstr "Wyłącz nastÄ™pujÄ…ce wpisy lub strony:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "List of IDs, separated by comma" +msgstr "Lista ID, oddzielonych przecinkami" + +msgid "Additional pages" +msgstr "Dodatkowe strony" + +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Tutaj możesz podąć pliki lub adresy URL, które powinny znaleźć się w twojej mapie strony, chociaż nie należą do blogu/WordPress'a.
        Na przykład, jeśli twoja domena to www.foo.com i twój blog znajduje się na www.foo.com/blog, możesz chcieć umieścić także stronę główną (czyli www.foo.com)" + +msgid "Note" +msgstr "Notatka" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Jeśli twój blog znajduje się w podkatalogu i chcesz dodać strony które NIE znajdują się katalogu blogu lub jego subkatalogu, MUSISZ umieścić swoją mapę strony w katalogu głównym (zobacz sekcję " Lokalizacja twojej mapy strony" na tej stronie)!" + +msgid "URL to the page" +msgstr "URL strony" + +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Wpisz adres URL strony. Przykłady: http://www.foo.com/index.html lub www.foo.com/home " + +msgid "Priority" +msgstr "Priorytet" + +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Wybierz priorytet strony w odniesieniu do innych stron. Na przykład, strona główna może mieć wyższy priorytet niż informacje o tobie." + +msgid "Last Changed" +msgstr "Ostatnio zmieniony" + +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Wpisz datę ostatniej zmiany jako YYYY-MM-DD (na przykład: 2005-12-31) (opcja)." + +msgid "Change Frequency" +msgstr "Zmień częstotliwość" + +msgid "#" +msgstr "#" + +msgid "No pages defined." +msgstr "Brak zdefiniowanych stron" + +msgid "Add new page" +msgstr "Dodaj nową stronę" + +msgid "Post Priority" +msgstr "Priorytet wpisu" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3292 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Wybierz sposób obliczania priorytetu poszczególnych wpisów:" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3294 +msgid "Do not use automatic priority calculation" +msgstr "Nie używaj automatycznego obliczania priorytetu" + +# F:\apache\htdocs\wordpress2-3\wp-content\plugins\google-sitemap-generator/sitemap.php:3294 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Wszystkie wpisy mają ten sam priorytet, który jest zdefiniowany "Priorytety"" + +msgid "Location of your sitemap file" +msgstr "Lokalizacja twojego pliku mapy strony" + +msgid "Automatic detection" +msgstr "Automatycznw wykrywanie" + +msgid "Filename of the sitemap file" +msgstr "Nazwa pliku mapy strony" + +msgid "Detected Path" +msgstr "Wykryta ścieżka" + +msgid "Detected URL" +msgstr "Wykryty URL" + +msgid "Custom location" +msgstr "Własna lokalizacja" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Absolutna ścieżka do pliku mapy strony, zawierający nazwę. " + +msgid "Example" +msgstr "Przykład" + +msgid "Complete URL to the sitemap file, including name." +msgstr "Pełen adres URL to pliku mapy strony, zawierający nazwę." + +msgid "Sitemap Content" +msgstr "Zawartość mapy strony" + +msgid "Include homepage" +msgstr "Zawiera stronę główną" + +msgid "Include posts" +msgstr "Zawiera wpisy" + +msgid "Include static pages" +msgstr "Zawiera statyczne strony" + +msgid "Include categories" +msgstr "Zawiera kategorie" + +msgid "Include archives" +msgstr "Zawiera archiwa" + +msgid "Include tag pages" +msgstr "Zawiera strony tagów" + +msgid "Include author pages" +msgstr "Zawiera strony autorów" + +msgid "Change frequencies" +msgstr "Zmień częstotliwość" + +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Proszę wziąść pod uwagę, że zawartość tego znacznika jest wskazówką, a nie poleceniem. Nawet jeśli wyszukiwarki biorą tą informację pod uwagę podczas podejmowania decyzji, to mogą one przeglądać strony zaznaczone jako \"co godzinę\" rzadziej. Jest również prawdopodobne, że strony oznaczone jako \"co rok\" będą przeglądane częściej. Również jest możliwe, że mimo oznaczenia \"nigdy\", wyszukiwarki mogą takie strony czasem przeglądać i wychwytywać nieoczekiwanie zmiany na tych stronach." + +msgid "Homepage" +msgstr "Strona główna" + +msgid "Posts" +msgstr "Wpisy" + +msgid "Static pages" +msgstr "Statyczne strony" + +msgid "Categories" +msgstr "Kategorie" + +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Aktualne archiwum tego miesiąca (powinno mieć taką samą częstotliwość jak strona główna)" + +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Starsz archiwa (zmień tylko jeśli edytujesz stare wpisy)" + +msgid "Tag pages" +msgstr "Strony tagów" + +msgid "Author pages" +msgstr "Strony autorów" + +msgid "Priorities" +msgstr "Priorytety" + +msgid "Posts (If auto calculation is disabled)" +msgstr "Wpisy (jeśli automatyczne przeliczanie jest wyłączone)" + +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Minimalny priorytet wpisu (nawet jeśli automatyczne przeliczanie jest włączone)" + +msgid "Archives" +msgstr "Archiwa" + +msgid "Update options" +msgstr "Zaktualizuj opcje" + +msgid "Reset options" +msgstr "Reset opcji" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_BR.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_BR.mo new file mode 100644 index 0000000..2c7283e Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_BR.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_BR.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_BR.po new file mode 100644 index 0000000..f13e0fb --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_BR.po @@ -0,0 +1,327 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap-es_ES.po 2504 2005-07-03 22:19:18Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2006-11-24 18:57-0300\n" +"Last-Translator: Rafael Lima \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: Pedro Polonia \n" +"X-Poedit-Language: Portuguese\n" +"X-Poedit-Country: PORTUGAL\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-Bookmarks: -1,59,-1,-1,-1,71,-1,-1,-1,-1\n" + +#: sitemap.php:375 +msgid "always" +msgstr "sempre" + +msgid "hourly" +msgstr "a cada hora" + +msgid "daily" +msgstr "diariamente" + +msgid "weekly" +msgstr "semanalmente" + +msgid "monthly" +msgstr "mensalmente" + +msgid "yearly" +msgstr "anualmente" + +msgid "never" +msgstr "nunca" + +msgid "Detected Path" +msgstr "Caminho detectado" + +msgid "Example" +msgstr "Exemplo" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Caminho absoluto ou relativo para o arquivo sitemap, incluindo o nome." + +msgid "Complete URL to the sitemap file, including name." +msgstr "URL completo para o arquivo sitemap, incluindo o nome." + +msgid "Automatic location" +msgstr "Localização automática" + +msgid "Manual location" +msgstr "Localização manual" + +msgid "OR" +msgstr "OU" + +msgid "Location of your sitemap file" +msgstr "Localização do arquivo sitemap" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Se o seu blog está numa pasta e quer adicionar paginas que NÃO estão na pasta do seu blog ou em sub-pastas, DEVE colocar o seu arquivo sitemap na raiz dos directórios (Olhe na secção \"Localização do seu arquivo sitemap\" nesta página)! " + +#: sitemap.php:512 +msgid "Configuration updated" +msgstr "Configuração actualizada" + +#: sitemap.php:513 +msgid "Error" +msgstr "Erro" + +#: sitemap.php:521 +msgid "A new page was added. Click on "Save page changes" to save your changes." +msgstr "Uma nova página foi adicionada. Seleccione em \"Gravar alterações\" para guardar as alterações. " + +#: sitemap.php:527 +msgid "Pages saved" +msgstr "Páginas guardadas" + +#: sitemap.php:528 +msgid "Error while saving pages" +msgstr "Erro durante a gravação das páginas " + +#: sitemap.php:539 +msgid "The page was deleted. Click on "Save page changes" to save your changes." +msgstr "A página foi eliminada. Seleccione em \"Gravar alterações\" para guardar as alterações. " + +#: sitemap.php:542 +msgid "You changes have been cleared." +msgstr "As suas alterações foram anuladas." + +#: sitemap.php:555 +msgid "Sitemap Generator" +msgstr "Gerador Sitemap" + +#: sitemap.php:558 +msgid "Manual rebuild" +msgstr "Reconstrução manual" + +#: sitemap.php:559 +msgid "If you want to build the sitemap without editing a post, click on here!" +msgstr "Se deseja construir o sitemap sem editar nenhum artigo, clique aqui!" + +#: sitemap.php:560 +msgid "Rebuild Sitemap" +msgstr "Reconstruir Sitemap" + +#: sitemap.php:564 +msgid "Additional pages" +msgstr "Páginas adicionais" + +#: sitemap.php:566 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Aqui pode especificar os arquivos ou URLs que devem ser incluídas no sitemap mas que não pertencem ao seu blog/WordPress.
        Por exemplo: se o teu domínio é www.foo.com e o teu blog está localizado em www.foo.com/blog, deve querer incluir a sua página inicial em www.foo.com " + +#: sitemap.php:568 +msgid "URL to the page" +msgstr "URL da página" + +#: sitemap.php:569 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "URL da página. Exemplos: http://www.foo.com/index.html ou www.foo.com/home" + +#: sitemap.php:571 +msgid "Priority" +msgstr "Prioridade" + +#: sitemap.php:572 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Escolha a prioridade relativa da página relativa a outras páginas. Por exemplo, a sua página inicial deve ter uma maior prioridade que os seus dados pessoais." + +#: sitemap.php:574 +msgid "Last Changed" +msgstr "Última Alteração" + +#: sitemap.php:575 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Entre a data da última alteração como AAAA-MM-DD (por exemplo: 2005-12-31) (opcional). " + +#: sitemap.php:583 +msgid "Change Frequency" +msgstr "Frequência das Alterações " + +#: sitemap.php:585 +msgid "#" +msgstr "#" + +#: sitemap.php:609 +msgid "No pages defined." +msgstr "Nenhuma página definida" + +#: sitemap.php:616 +msgid "Add new page" +msgstr "Adicionar nova página " + +#: sitemap.php:617: +msgid "Save page changes" +msgstr "Guardar as alterações da página" + +#: sitemap.php:618: +msgid "Undo all page changes" +msgstr "Desfazer todas as alterações da página" + +#: sitemap.php:621: +msgid "Delete marked page" +msgstr "Apagar a página marcada" + +#: sitemap.php:627 +msgid "Basic Options" +msgstr "Opções Básicas" + +#: sitemap.php:632 +msgid "Enable automatic priority calculation for posts based on comment count" +msgstr "Activar o cálculo automático de prioridades para artigos baseado no número de comentários. " + +#: sitemap.php:638 +msgid "Write debug comments" +msgstr "Escrever comentários de depuração (debug) " + +#: sitemap.php:643 +msgid "Filename of the sitemap file" +msgstr "Nome do arquivo sitemap" + +#: sitemap.php:650 +msgid "Write a normal XML file (your filename)" +msgstr "Escrever um arquivo XML normal (nome do arquivo)" + +#: sitemap.php:652 +msgid "Detected URL" +msgstr "URL detectada" + +#: sitemap.php:657 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Gravar um arquivo comprimido com gzip (nome_arquivo +.gz)" + +#: sitemap.php:664 +msgid "Auto-Ping Google Sitemaps" +msgstr "Ping automático a Google Sitemaps" + +#: sitemap.php:665 +msgid "This option will automatically tell Google about changes." +msgstr "Esta opção indicará automaticamente as alterações ao Google." + +#: sitemap.php:672 +msgid "Includings" +msgstr "Inclusões" + +#: sitemap.php:677 +msgid "Include homepage" +msgstr "Incluir página principal" + +#: sitemap.php:683 +msgid "Include posts" +msgstr "Incluir artigos" + +#: sitemap.php:689 +msgid "Include static pages" +msgstr "Incluir páginas estáticas" + +#: sitemap.php:695 +msgid "Include categories" +msgstr "Incluir categorías" + +#: sitemap.php:701 +msgid "Include archives" +msgstr "Incluir arquivos" + +#: sitemap.php:708 +msgid "Change frequencies" +msgstr "Frequência das mudanças " + +#: sitemap.php:709 +msgid "Note" +msgstr "Nota" + +#: sitemap.php:710 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Por favor, considere que o valor desta etiqueta é um conselho e não um comando. Mesmo quando alguns agentes de pesquisa (search engine crawlers) consideram esta informação para tomar decisões, eles podem verificar as páginas marcadas como \"a cada hora\" com menor frequência, e visitar varias vezes por ano, as páginas marcadas com \"anualmente\".É igualmente possível que sejam verificadas páginas marcadas com \"nunca\" para gerir possíveis mudanças inesperadas nas mesmas." + +#: sitemap.php:715 +msgid "Homepage" +msgstr "Página principal" + +#: sitemap.php:721 +msgid "Posts" +msgstr "Artigos" + +#: sitemap.php:727 +msgid "Static pages" +msgstr "Páginas estáticas" + +#: sitemap.php:733 +msgid "Categories" +msgstr "Categorias" + +#: sitemap.php:739 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Arquivo deste mês (Deve ser igual ao da sua pagina principal)" + +#: sitemap.php:745 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Arquivos antigos (Alterar só se editou um artigo antigo)" + +#: sitemap.php:752 +msgid "Priorities" +msgstr "Prioridades" + +#: sitemap.php:763 +msgid "Posts (If auto calculation is disabled)" +msgstr "Artigos (Se o calculo automático está inativo) " + +#: sitemap.php:769 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Prioridade mínima para artigos (Mesmo quando o cálculo automático está ativo) " + +#: sitemap.php:787 +msgid "Archives" +msgstr "Arquivos" + +#: sitemap.php:793 +msgid "Informations and support" +msgstr "Informação e suporte" + +#: sitemap.php:794 +msgid "Check %s for updates and comment there if you have any problems / questions / suggestions." +msgstr "Consulte %s para atualizações e comentários se tiver algum problema, questão ou sugestão." + +#: sitemap.php:797 +msgid "Update options" +msgstr "Atualizar opções" + +#: sitemap.php:1033 +msgid "URL:" +msgstr "URL:" + +#: sitemap.php:1034 +msgid "Path:" +msgstr "Caminho:" + +#: sitemap.php:1037 +msgid "Could not write into %s" +msgstr "Não foi possivel escrever em %s" + +#: sitemap.php:1048 +msgid "Successfully built sitemap file:" +msgstr "Arquivo sitemap criado com sucesso:" + +#: sitemap.php:1048 +msgid "Successfully built gzipped sitemap file:" +msgstr "Arquivo sitemap comprimido criado com sucesso:" + +#: sitemap.php:1062 +msgid "Could not ping to Google at %s" +msgstr "Não foi possível realizar ping no Google em %s" + +#: sitemap.php:1064 +msgid "Successfully pinged Google at %s" +msgstr "Ping a Google realizado com sucesso em %s" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_PT.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_PT.mo new file mode 100644 index 0000000..5d5e39a Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_PT.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_PT.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_PT.po new file mode 100644 index 0000000..2ec1035 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-pt_PT.po @@ -0,0 +1,985 @@ +msgid "" +msgstr "" +"Project-Id-Version: Google XML Sitemaps v4.0.3\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2014-04-19 19:06+0100\n" +"Last-Translator: \n" +"Language-Team: wordpress.mowster.net \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 1.6.4\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;" +"_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-Bookmarks: -1,59,-1,-1,-1,71,-1,-1,-1,-1\n" +"X-Textdomain-Support: yes\n" +"Language: pt_PT\n" +"X-Poedit-SearchPath-0: .\n" + +# @ sitemap +#: sitemap-ui.php:816 +msgid "" +"If your blog is in a subdirectory and you want to add pages which are NOT in " +"the blog directory or beneath, you MUST place your sitemap file in the root " +"directory (Look at the "Location of your sitemap file" section on " +"this page)!" +msgstr "" +"Se o seu blog está numa pasta e quer adicionar paginas que NÃO estão na " +"pasta do seu blog ou em sub-pastas, DEVE colocar o seu ficheiro sitemap na " +"raiz dos diretorias (Verifique na secção \"Localização do seu ficheiro " +"sitemap\" nesta página)!" + +# @ sitemap +#: sitemap-ui.php:374 +msgid "Configuration updated" +msgstr "Configuração atualizada" + +# @ sitemap +#: sitemap-ui.php:378 +msgid "Pages saved" +msgstr "Páginas guardadas" + +# @ sitemap +#: sitemap-ui.php:379 +msgid "Error while saving pages" +msgstr "Erro durante a gravação das páginas" + +# @ sitemap +#: sitemap-ui.php:810 +msgid "Additional pages" +msgstr "Páginas adicionais" + +# @ sitemap +#: sitemap-ui.php:813 +msgid "" +"Here you can specify files or URLs which should be included in the sitemap, " +"but do not belong to your Blog/WordPress.
        For example, if your domain " +"is www.foo.com and your blog is located on www.foo.com/blog you might want " +"to include your homepage at www.foo.com" +msgstr "" +"Aqui pode especificar os ficheiros ou URLs que devem ser incluídas no " +"sitemap mas que não pertencem ao seu blog/WordPress.
        Por exemplo: se o " +"seu domínio é www.foo.com e o seu blog está localizado em www.foo.com/blog, " +"deve querer incluir a sua página inicial em www.foo.com" + +# @ sitemap +#: sitemap-ui.php:818 sitemap-ui.php:857 +msgid "URL to the page" +msgstr "URL da página" + +# @ sitemap +#: sitemap-ui.php:819 +msgid "" +"Enter the URL to the page. Examples: http://www.foo.com/index.html or www." +"foo.com/home " +msgstr "" +"URL da página. Exemplos: http://www.foo.com/index.html ou www.foo.com/home " + +# @ sitemap +#: sitemap-ui.php:821 sitemap-ui.php:858 +msgid "Priority" +msgstr "Prioridade" + +# @ sitemap +#: sitemap-ui.php:822 +msgid "" +"Choose the priority of the page relative to the other pages. For example, " +"your homepage might have a higher priority than your imprint." +msgstr "" +"Escolha a prioridade relativa da página em relação a outras páginas. Por " +"exemplo, a sua página inicial deve ter uma maior prioridade que os seus " +"dados pessoais." + +# @ sitemap +#: sitemap-ui.php:824 sitemap-ui.php:860 +msgid "Last Changed" +msgstr "Última Alteração" + +# @ sitemap +#: sitemap-ui.php:825 +msgid "" +"Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) " +"(optional)." +msgstr "" +"Introduza a data da última alteração com o formato AAAA-MM-DD (por exemplo: " +"2005-12-31) (opcional)." + +# @ sitemap +#: sitemap-ui.php:859 +msgid "Change Frequency" +msgstr "Alterar Frequência" + +# @ sitemap +#: sitemap-ui.php:861 +msgid "#" +msgstr "#" + +# @ sitemap +#: sitemap-ui.php:866 +msgid "No pages defined." +msgstr "Nenhuma página definida." + +# @ sitemap +#: sitemap-ui.php:871 +msgid "Add new page" +msgstr "Adicionar nova página" + +# @ sitemap +#: sitemap-ui.php:754 +msgid "Basic Options" +msgstr "Opções Básicas" + +# @ sitemap +#: sitemap-ui.php:898 +msgid "Include homepage" +msgstr "Incluir página principal" + +# @ sitemap +#: sitemap-ui.php:904 +msgid "Include posts" +msgstr "Incluir artigos" + +# @ sitemap +#: sitemap-ui.php:910 +msgid "Include static pages" +msgstr "Incluir páginas estáticas" + +# @ sitemap +#: sitemap-ui.php:916 +msgid "Include categories" +msgstr "Incluir categorias" + +# @ sitemap +#: sitemap-ui.php:922 +msgid "Include archives" +msgstr "Incluir arquivos" + +# @ sitemap +#: sitemap-ui.php:1036 +msgid "Change frequencies" +msgstr "Alterar frequências" + +# @ sitemap +#: sitemap-ui.php:815 sitemap-ui.php:1019 sitemap-ui.php:1030 +#: sitemap-ui.php:1039 +msgid "Note" +msgstr "Nota" + +# @ sitemap +#: sitemap-ui.php:1040 +msgid "" +"Please note that the value of this tag is considered a hint and not a " +"command. Even though search engine crawlers consider this information when " +"making decisions, they may crawl pages marked \"hourly\" less frequently " +"than that, and they may crawl pages marked \"yearly\" more frequently than " +"that. It is also likely that crawlers will periodically crawl pages marked " +"\"never\" so that they can handle unexpected changes to those pages." +msgstr "" +"Por favor, considere que o valor desta etiqueta é um conselho e não um " +"comando. Mesmo quando alguns motores de busca consideram esta informação " +"para tomar decisões, eles podem verificar as páginas marcadas como \"de hora " +"em hora\" com menor frequência, e visitar varias vezes por ano, as páginas " +"marcadas com \"anualmente\". É igualmente possível que sejam verificadas " +"páginas marcadas com \"nunca\" para gerir possíveis mudanças inesperadas nas " +"mesmas." + +# @ sitemap +#: sitemap-ui.php:1046 sitemap-ui.php:1103 +msgid "Homepage" +msgstr "Página principal" + +# @ sitemap +#: sitemap-ui.php:1052 +msgid "Posts" +msgstr "Artigos" + +# @ sitemap +#: sitemap-ui.php:1058 sitemap-ui.php:1121 +msgid "Static pages" +msgstr "Páginas estáticas" + +# @ sitemap +#: sitemap-ui.php:1064 sitemap-ui.php:1127 +msgid "Categories" +msgstr "Categorias" + +# @ sitemap +#: sitemap-ui.php:1070 +msgid "" +"The current archive of this month (Should be the same like your homepage)" +msgstr "Arquivo deste mês (Deve ser igual ao da sua pagina principal)" + +# @ sitemap +#: sitemap-ui.php:1076 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Arquivos antigos (Alterar só se editou um artigo antigo)" + +# @ sitemap +#: sitemap-ui.php:1098 +msgid "Priorities" +msgstr "Prioridades" + +# @ sitemap +#: sitemap-ui.php:1109 +msgid "Posts (If auto calculation is disabled)" +msgstr "Artigos (Se o calculo automático está desabilitado)" + +# @ sitemap +#: sitemap-ui.php:1115 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "" +"Prioridade mínima para artigos (Mesmo quando o cálculo automático esteja " +"ativo)" + +# @ sitemap +#: sitemap-ui.php:1133 +msgid "Archives" +msgstr "Arquivos" + +# @ sitemap +#: sitemap-ui.php:1158 +msgid "Update options" +msgstr "Atualizar opções" + +# @ sitemap +#: sitemap-core.php:536 +msgid "Comment Count" +msgstr "Número de comentários" + +# @ sitemap +#: sitemap-core.php:546 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Utiliza o número de comentários do artigo para calcular a prioridade" + +# @ sitemap +#: sitemap-core.php:599 +msgid "Comment Average" +msgstr "Média de comentários" + +# @ sitemap +#: sitemap-core.php:609 +msgid "Uses the average comment count to calculate the priority" +msgstr "Utiliza a contagem média de comentários para calcular a prioridade" + +# @ sitemap +#: sitemap-core.php:770 +msgid "Always" +msgstr "Sempre" + +# @ sitemap +#: sitemap-core.php:771 +msgid "Hourly" +msgstr "De hora em hora" + +# @ sitemap +#: sitemap-core.php:772 +msgid "Daily" +msgstr "Diariamente" + +# @ sitemap +#: sitemap-core.php:773 +msgid "Weekly" +msgstr "Semanalmente" + +# @ sitemap +#: sitemap-core.php:774 +msgid "Monthly" +msgstr "Mensalmente" + +# @ sitemap +#: sitemap-core.php:775 +msgid "Yearly" +msgstr "Anualmente" + +# @ sitemap +#: sitemap-core.php:776 +msgid "Never" +msgstr "Nunca" + +# @ sitemap +#: sitemap-loader.php:233 +msgid "XML-Sitemap Generator" +msgstr "Gerador XML-Sitemap" + +# @ sitemap +#: sitemap-loader.php:233 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +# @ sitemap +#: sitemap-loader.php:261 +msgid "Settings" +msgstr "Configurações" + +# @ sitemap +#: sitemap-loader.php:262 +msgid "FAQ" +msgstr "FAQ" + +# @ sitemap +#: sitemap-loader.php:263 +msgid "Support" +msgstr "Suporte" + +# @ sitemap +#: sitemap-loader.php:264 +msgid "Donate" +msgstr "Donativo" + +# @ sitemap +#: sitemap-ui.php:198 sitemap-ui.php:585 +msgid "XML Sitemap Generator for WordPress" +msgstr "Gerador XML Sitemap para o WordPress" + +# @ sitemap +#: sitemap-ui.php:375 +msgid "Error while saving options" +msgstr "Erro enquanto guardava opções" + +# @ sitemap +#: sitemap-ui.php:387 +msgid "The default configuration was restored." +msgstr "A configuração padrão foi restabelecida." + +# @ sitemap +#: sitemap-ui.php:397 +msgid "" +"The old files could NOT be deleted. Please use an FTP program and delete " +"them by yourself." +msgstr "" +"Os ficheiros antigos não podem ser apagados. Por favor, utilize um programa " +"de FTP e apague-os manualmente." + +# @ sitemap +#: sitemap-ui.php:399 +msgid "The old files were successfully deleted." +msgstr "Os ficheiros antigos foram apagados com sucesso." + +# @ sitemap +#: sitemap-ui.php:439 +msgid "" +"Thank you very much for your donation. You help me to continue support and " +"development of this plugin and other free software!" +msgstr "" +"Muito obrigado pela sua contribuição. Ajuda-me a continuar a apoiar e a " +"desenvolver este plugin e outros softwares grátis!" + +# @ sitemap +#: sitemap-ui.php:439 +msgid "Hide this notice" +msgstr "Esconder esta notícia" + +# @ sitemap +#: sitemap-ui.php:445 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin over a month ago. " +"If it works and you are satisfied with the results, isn't it worth at least " +"a few dollar? Donations help me to continue support and " +"development of this free software! Sure, no problem!" +msgstr "" +"Obrigado por utilizar este plugin! Você instalou o plugin há mais de um mês. " +"Se funciona e você está satisfeito com os resultados, não vale pelo menos um " +"dólar? Donativos ajuda-me a continuar a apoiar e a " +"desenvolver software livre! Claro, sem problema!" + +# @ sitemap +#: sitemap-ui.php:445 +msgid "Sure, but I already did!" +msgstr "Claro, mas já o fiz anteriormente!" + +# @ sitemap +#: sitemap-ui.php:445 +msgid "No thanks, please don't bug me anymore!" +msgstr "Não obrigado, não me incomode mais!" + +# @ sitemap +#: sitemap-ui.php:452 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin some time ago. If " +"it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "" +"Obrigado por utilizar este plugin! Você instalou este plugin há algum tempo. " +"Se ele funciona e você está satisfeito, por que não avaliar e recomendar a outros utilizadores? :-)" + +# @ sitemap +#: sitemap-ui.php:452 +msgid "Don't show this anymore" +msgstr "Não exibir" + +# @ default +#: sitemap-ui.php:601 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here." +msgstr "" + +# @ default +#: sitemap-ui.php:603 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here automatic upgrade unavailable for this plugin." +msgstr "" + +# @ default +#: sitemap-ui.php:605 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here or upgrade automatically." +msgstr "" + +# @ sitemap +#: sitemap-ui.php:613 +#, php-format +msgid "" +"Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "" +"O seu blog está neste momento a bloquear a indexação dos motores de busca! " +"Visite a privacidade para alterar esta limitação." + +# @ sitemap +#: sitemap-ui.php:629 +msgid "About this Plugin:" +msgstr "Sobre o Plugin:" + +# @ sitemap +#: sitemap-ui.php:630 +msgid "Plugin Homepage" +msgstr "Página principal do Plugin" + +# @ sitemap +#: sitemap-ui.php:631 +msgid "Suggest a Feature" +msgstr "Sugerir nova funcionalidade" + +# @ sitemap +#: sitemap-ui.php:632 +msgid "Notify List" +msgstr "Receber notificações" + +# @ sitemap +#: sitemap-ui.php:633 +msgid "Support Forum" +msgstr "Fórum de suporte" + +# @ sitemap +#: sitemap-ui.php:634 +msgid "Report a Bug" +msgstr "Reportar um Bug" + +# @ sitemap +#: sitemap-ui.php:636 +msgid "Donate with PayPal" +msgstr "Donativo via PayPal" + +# @ sitemap +#: sitemap-ui.php:637 +msgid "My Amazon Wish List" +msgstr "Lista Amazon" + +# @ sitemap +#: sitemap-ui.php:638 +msgid "translator_name" +msgstr "Mowster" + +# @ sitemap +#: sitemap-ui.php:638 +msgid "translator_url" +msgstr "http://wordpress.mowster.net" + +# @ sitemap +#: sitemap-ui.php:641 +msgid "Sitemap Resources:" +msgstr "Recursos Sitemap:" + +# @ sitemap +#: sitemap-ui.php:642 sitemap-ui.php:647 +msgid "Webmaster Tools" +msgstr "Ferramentas para Webmasters" + +# @ sitemap +#: sitemap-ui.php:643 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# @ sitemap +#: sitemap-ui.php:645 +msgid "Search Blog" +msgstr "Procurar no Blog" + +# @ sitemap +#: sitemap-ui.php:648 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +# @ sitemap +#: sitemap-ui.php:650 +msgid "Sitemaps Protocol" +msgstr "Protocolo Sitemaps" + +# @ sitemap +#: sitemap-ui.php:651 +msgid "Official Sitemaps FAQ" +msgstr "Oficial FAQ Sitemaps" + +# @ sitemap +#: sitemap-ui.php:652 +msgid "My Sitemaps FAQ" +msgstr "FAQ Sitemaps" + +# @ sitemap +#: sitemap-ui.php:655 +msgid "Recent Donations:" +msgstr "Donativos Recentes:" + +# @ sitemap +#: sitemap-ui.php:658 +msgid "List of the donors" +msgstr "Lista de doadores" + +# @ sitemap +#: sitemap-ui.php:660 +msgid "Hide this list" +msgstr "Ocultar lista" + +# @ sitemap +#: sitemap-ui.php:663 +msgid "Thanks for your support!" +msgstr "Obrigado pelo apoio!" + +# @ sitemap +#: sitemap-ui.php:683 +msgid "Search engines haven't been notified yet" +msgstr "Motores de busca ainda não foram notificados" + +# @ sitemap +#: sitemap-ui.php:687 +#, php-format +msgid "Result of the last ping, started on %date%." +msgstr "Resultado do último ping, iniciado em %date%." + +# @ sitemap +#: sitemap-ui.php:702 +#, php-format +msgid "" +"There is still a sitemap.xml or sitemap.xml.gz file in your blog directory. " +"Please delete them as no static files are used anymore or try " +"to delete them automatically." +msgstr "" +"Existe ainda um ficheiro sitemap.xml ou sitemap.xml.gz na sua pasta do blog. " +"Por favor, apague-os uma vez que os ficheiros físicos não são mais " +"utilizados ​​ou tente apaga-los automaticamente." + +# @ sitemap +#: sitemap-ui.php:705 +#, php-format +msgid "The URL to your sitemap index file is: %s." +msgstr "O URL para o seu ficheiro sitemap é: %s." + +# @ sitemap +#: sitemap-ui.php:708 +msgid "" +"Search engines haven't been notified yet. Write a post to let them know " +"about your sitemap." +msgstr "" +"Motores de busca ainda não foram notificados. Escreva um artigo e permita-" +"lhes que tomem conhecimento do seu sitemap." + +# @ sitemap +#: sitemap-ui.php:717 +#, php-format +msgid "%s was successfully notified about changes." +msgstr "%s foi notificado com sucesso sobre as alterações." + +# @ sitemap +#: sitemap-ui.php:720 +#, php-format +msgid "" +"It took %time% seconds to notify %name%, maybe you want to disable this " +"feature to reduce the building time." +msgstr "" +"Demorou %time% segundos para notificar %name%, talvez queira desabilitar " +"este recurso para reduzir o tempo de construção." + +# @ sitemap +#: sitemap-ui.php:723 +#, php-format +msgid "" +"There was a problem while notifying %name%. View result" +msgstr "" +"Houve um problema enquanto notificava %name%. Ver resultados" + +# @ sitemap +#: sitemap-ui.php:727 +#, php-format +msgid "" +"If you encounter any problems with your sitemap you can use the debug function to get more information." +msgstr "" +"Se teve problemas com seu sitemap pode usar a função debug para obter mais informações." + +# @ sitemap +#: sitemap-ui.php:756 +msgid "Update notification:" +msgstr "Notificação de atualizações:" + +# @ sitemap +#: sitemap-ui.php:756 sitemap-ui.php:779 sitemap-ui.php:802 +msgid "Learn more" +msgstr "Saber mais" + +# @ sitemap +#: sitemap-ui.php:760 +msgid "Notify Google about updates of your Blog" +msgstr "Notificar o Google sobre as atualizações do seu Blog" + +# @ sitemap +#: sitemap-ui.php:761 +#, php-format +msgid "" +"No registration required, but you can join the Google " +"Webmaster Tools to check crawling statistics." +msgstr "" +"Nenhum registo necessário, mas pode utilizar o Google " +"Webmaster Tools para verificar as estatísticas de rastreamento." + +# @ sitemap +#: sitemap-ui.php:765 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "" +"Notificar o Bing (antigo MSN Live Search) sobre as atualizações do seu Blog" + +# @ sitemap +#: sitemap-ui.php:766 +#, php-format +msgid "" +"No registration required, but you can join the Bing Webmaster " +"Tools to check crawling statistics." +msgstr "" +"Nenhum registo necessário, mas pode utilizar o Bing Webmaster " +"Tools para verificar as estatísticas de rastreamento." + +# @ sitemap +#: sitemap-ui.php:771 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Adicionar o URL do sitemap ao ficheiro virtual robots.txt." + +# @ sitemap +#: sitemap-ui.php:775 +msgid "" +"The virtual robots.txt generated by WordPress is used. A real robots.txt " +"file must NOT exist in the blog directory!" +msgstr "" +"O robots.txt virtual é gerado pelo WordPress. Um ficheiro robots.txt real " +"não deve existir no diretório do blog!" + +# @ sitemap +#: sitemap-ui.php:779 +msgid "Advanced options:" +msgstr "Opções avançadas:" + +# @ sitemap +#: sitemap-ui.php:782 +msgid "Try to increase the memory limit to:" +msgstr "Aumentar o limite de memória para:" + +# @ sitemap +#: sitemap-ui.php:782 +msgid "e.g. \"4M\", \"16M\"" +msgstr "ex. \"4M\", \"16M\"" + +# @ sitemap +#: sitemap-ui.php:785 +msgid "Try to increase the execution time limit to:" +msgstr "Aumentar o tempo de execução para:" + +# @ sitemap +#: sitemap-ui.php:785 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "em segundos, ex: \"60\" or \"0\" para ilimitado" + +# @ sitemap +#: sitemap-ui.php:789 +msgid "Include a XSLT stylesheet:" +msgstr "Incluir uma folha de estilo XSLT:" + +# @ sitemap +#: sitemap-ui.php:790 +msgid "Full or relative URL to your .xsl file" +msgstr "URL completo ou relativo para o ficheiro .xsl" + +# @ sitemap +#: sitemap-ui.php:790 +msgid "Use default" +msgstr "Utilizar padrão" + +# @ sitemap +#: sitemap-ui.php:795 +msgid "Include sitemap in HTML format" +msgstr "Incluir o sitemap num formato HTML" + +# @ sitemap +#: sitemap-ui.php:877 +msgid "Post Priority" +msgstr "Prioridade do Artigo" + +# @ sitemap +#: sitemap-ui.php:879 +msgid "Please select how the priority of each post should be calculated:" +msgstr "" +"Por favor, selecione como a prioridade de cada artigo deve ser calculada:" + +# @ sitemap +#: sitemap-ui.php:881 +msgid "Do not use automatic priority calculation" +msgstr "Não utilizar o cálculo automático de prioridades" + +# @ sitemap +#: sitemap-ui.php:881 +msgid "" +"All posts will have the same priority which is defined in "" +"Priorities"" +msgstr "" +"Todo os artigos irão ter a mesma prioridade definida em "" +"Prioridades"" + +# @ sitemap +#: sitemap-ui.php:892 +msgid "Sitemap Content" +msgstr "Conteúdo Sitemap" + +# @ sitemap +#: sitemap-ui.php:893 +msgid "WordPress standard content" +msgstr "Conteúdo padrão do WordPress" + +# @ sitemap +#: sitemap-ui.php:928 +msgid "Include author pages" +msgstr "Incluir páginas de autores" + +# @ sitemap +#: sitemap-ui.php:935 +msgid "Include tag pages" +msgstr "Incluir páginas de etiquetas" + +# @ sitemap +#: sitemap-ui.php:949 +msgid "Custom taxonomies" +msgstr "Taxonomias personalizadas" + +# @ sitemap +#: sitemap-ui.php:960 +#, php-format +msgid "Include taxonomy pages for %s" +msgstr "Incluir páginas de taxonomias para %s" + +# @ sitemap +#: sitemap-ui.php:978 +msgid "Custom post types" +msgstr "Tipos de artigos personalizados" + +# @ sitemap +#: sitemap-ui.php:989 +#, php-format +msgid "Include custom post type %s" +msgstr "Incluir tipos de artigos personalizados %s" + +# @ sitemap +#: sitemap-ui.php:1001 +msgid "Further options" +msgstr "Mais opções" + +# @ sitemap +#: sitemap-ui.php:1006 +msgid "Include the last modification time." +msgstr "Incluir a hora da última modificação." + +# @ sitemap +#: sitemap-ui.php:1008 +msgid "" +"This is highly recommended and helps the search engines to know when your " +"content has changed. This option affects all sitemap entries." +msgstr "" +"É extremamente recomendável e ajuda os motores de busca a saber quando seu " +"conteúdo foi alterado. Esta opção afeta todos os registos do sitemap." + +# @ sitemap +#: sitemap-ui.php:1015 +msgid "Excluded items" +msgstr "Itens excluídos" + +# @ sitemap +#: sitemap-ui.php:1017 +msgid "Excluded categories" +msgstr "Categorias excluídas" + +# @ sitemap +#: sitemap-ui.php:1019 +msgid "Using this feature will increase build time and memory usage!" +msgstr "" +"Utilizar este recurso irá aumentar o tempo de compilação e utilização de " +"memória!" + +# @ sitemap +#: sitemap-ui.php:1026 +msgid "Exclude posts" +msgstr "Artigos excluídos" + +# @ sitemap +#: sitemap-ui.php:1028 +msgid "Exclude the following posts or pages:" +msgstr "Excluir os seguintes artigos ou páginas:" + +# @ sitemap +#: sitemap-ui.php:1028 +msgid "List of IDs, separated by comma" +msgstr "Listagem de IDs, separados por vírgual" + +# @ sitemap +#: sitemap-ui.php:1030 +msgid "Child posts won't be excluded automatically!" +msgstr "Artigos subsequentes não serão excluídos automaticamente!" + +# @ sitemap +#: sitemap-ui.php:1083 sitemap-ui.php:1140 +msgid "Tag pages" +msgstr "Páginas de etiquetas" + +# @ sitemap +#: sitemap-ui.php:1090 sitemap-ui.php:1147 +msgid "Author pages" +msgstr "Páginas de autores" + +# @ sitemap +#: sitemap-ui.php:1159 +msgid "Reset options" +msgstr "Redefinir opções" + +# @ sitemap +#. translators: plugin header field 'Name' +#: sitemap.php:0 +msgid "Google XML Sitemaps" +msgstr "Google XML Sitemaps" + +# @ sitemap +#. translators: plugin header field 'PluginURI' +#: sitemap.php:0 +msgid "http://www.arnebrachhold.de/redir/sitemap-home/" +msgstr "http://www.arnebrachhold.de/redir/sitemap-home/" + +# @ sitemap +#. translators: plugin header field 'Description' +#: sitemap.php:0 +msgid "" +"This plugin will generate a special XML sitemap which will help search " +"engines like Google, Yahoo, Bing and Ask.com to better index your blog." +msgstr "" +"Este plugin irá gerar um sitemap XML especial que irá ajudar os motores de " +"busca como Google, Yahoo, Bing e Ask.com a indexar mais facilmente o seu " +"blog." + +# @ sitemap +#. translators: plugin header field 'Author' +#: sitemap.php:0 +msgid "Arne Brachhold" +msgstr "Arne Brachhold" + +# @ sitemap +#. translators: plugin header field 'AuthorURI' +#: sitemap.php:0 +msgid "http://www.arnebrachhold.de/" +msgstr "http://www.arnebrachhold.de/" + +# @ sitemap +#: sitemap.php:82 +msgid "Your WordPress version is too old for XML Sitemaps." +msgstr "" +"A sua versão WordPress é demasiadamente antigo para poder executar o XML " +"Sitemaps." + +# @ sitemap +#: sitemap.php:82 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least " +"WordPress %4$s. You are using Wordpress %2$s, which is out-dated and " +"insecure. Please upgrade or go to active plugins and " +"deactivate the Google XML Sitemaps plugin to hide this message. You can " +"download an older version of this plugin from the plugin " +"website." +msgstr "" +"Infelizmente esta versão do Google XML Sitemaps requer pelo menos o " +"WordPress %4$s. Está utilizando o Wordpress %2$s, que está caduco e " +"inseguro. Por favor, atualize ou nos plugins ativos " +"desative o Google XML Sitemaps para ocultar esta mensagem. Pode utilizar uma " +"versão mais antiga deste plugin, é possível encontrá-la no site oficial." + +# @ sitemap +#: sitemap.php:92 +msgid "Your PHP version is too old for XML Sitemaps." +msgstr "" +"A sua versão PHP é demasiadamente antiga para poder executar o XML Sitemaps." + +# @ sitemap +#: sitemap.php:92 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least PHP " +"%4$s. You are using PHP %2$s, which is out-dated and insecure. Please ask " +"your web host to update your PHP installation or go to active plugins and deactivate the Google XML Sitemaps plugin to hide " +"this message. You can download an older version of this plugin from the plugin website." +msgstr "" +"Infelizmente esta versão do Google XML Sitemaps requer pelo menos o PHP " +"%4$s. Está utilizando o PHP %2$s, que está caduco e inseguro. Por favor, " +"peça à sua empresa de alojamento para o atualizar o nos plugins ativos desative o Google XML Sitemaps para ocultar esta " +"mensagem. Pode utilizar uma versão mais antiga deste plugin, é possível " +"encontrá-la no site oficial." + +# @ sitemap +#: sitemap-ui.php:795 +msgid "(The required PHP XSL Module is not installed)" +msgstr "(O módulo PHP XSL necessário não está instalado)" + +# @ sitemap +#: sitemap-ui.php:801 +msgid "Allow anonymous statistics (no personal information)" +msgstr "Permitir estatísticas anónimas (nenhuma informação pessoal)" + +# @ sitemap +#: sitemap-ui.php:737 +msgid "Webserver Configuration" +msgstr "Configuração do Servidor Web" + +# @ sitemap +#: sitemap-ui.php:738 +msgid "" +"Since you are using Nginx as your web-server, please configure the following " +"rewrite rules in case you get 404 Not Found errors for your sitemap:" +msgstr "" +"Uma vez que o Nginx é o servidor web, por favor, configure as seguintes " +"regras rewrite no caso de existirem erros 404 no sitemap:" + +# @ sitemap +#. translators: plugin header field 'Version' +#: sitemap.php:0 +msgid "4.0.3" +msgstr "4.0.3" diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ru_RU.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ru_RU.mo new file mode 100644 index 0000000..d4f8c37 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ru_RU.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ru_RU.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ru_RU.po new file mode 100644 index 0000000..a1af8e0 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-ru_RU.po @@ -0,0 +1,685 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 24948 2007-11-18 16:37:44Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: <[mail-address]>\n" +"POT-Creation-Date: 2005-06-15 00:00+0000\n" +"PO-Revision-Date: 2007-11-27 12:24+0300\n" +"Last-Translator: Sergey Ryvkin \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language-Team: \n" +"X-Poedit-KeywordsList: _e;__\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: C:\\Inetpub\\wwwroot\\wp\\wp-content\\plugins\\sitemap_beta\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +msgid "Comment Count" +msgstr "КоличеÑтво комментариев" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "ИÑпользует количеÑтво комментариев к Ñтатье Ð´Ð»Ñ Ð²Ñ‹Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +msgid "Comment Average" +msgstr "Среднее количеÑтво комментариев" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +msgid "Uses the average comment count to calculate the priority" +msgstr "ИÑпользует Ñреднее количеÑтво комментариев Ð´Ð»Ñ Ð²Ñ‹Ñ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +msgid "Popularity Contest" +msgstr "ПопулÑрноÑть диÑкуÑÑии" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "ИÑпользуйте активированный Плагин популÑрноÑти диÑкуÑÑий от Alex King. См. ÐаÑтройки и Самые популÑрные запиÑи" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap Generator" +msgstr "Генератор XML-карты Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +msgid "XML-Sitemap" +msgstr "XML-карта Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Премного благодарю за пожертвованиÑ. Ð’Ñ‹ помогаете мне в продалжении поддержки и разработки Ñтого плагина и другого Ñвободного ПО!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +msgid "Hide this notice" +msgstr "Скрыть Ñто замечание" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Благодарю Ð’Ð°Ñ Ð·Ð° иÑпользование Ñтого плагина! Ð’Ñ‹ уÑтановили его Ñвыше меÑÑца назад. ЕÑли он работает и Ð’Ñ‹ удовлетворены его результатами, вышлите мне Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ $1? ÐŸÐ¾Ð¶ÐµÑ€Ñ‚Ð²Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð¼Ð¾Ð³ÑƒÑ‚ мне в поддержке и разработке Ñтого беÑплатного ПО! Конечно, без проблем!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +msgid "No thanks, please don't bug me anymore!" +msgstr "Ðет, ÑпаÑибо. Прошу Ð¼ÐµÐ½Ñ Ð±Ð¾Ð»ÑŒÑˆÐµ не беÑпокоить!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +msgid "XML Sitemap Generator for WordPress" +msgstr "Генератор XML-карты Ñайта Ð´Ð»Ñ WordPress" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +msgid "Configuration updated" +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð°" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +msgid "Error while saving options" +msgstr "Ошибка при Ñохранении параметров" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +msgid "Pages saved" +msgstr "Страницы Ñохранены" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +msgid "Error while saving pages" +msgstr "Ошибка при Ñохранении Ñтраниц" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2748 +#, php-format +msgid "Robots.txt file saved" +msgstr "Файл Robots.txt Ñохранен" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2750 +msgid "Error while saving Robots.txt file" +msgstr "Ошибка при Ñохранении файла Robots.txt" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +msgid "The default configuration was restored." +msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ умолчанию воÑÑтановлена." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +msgid "open" +msgstr "открыть" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +msgid "close" +msgstr "закрыть" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +msgid "click-down and drag to move this box" +msgstr "Ðажмите кнопку мыши и тащите Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñтого блока" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +msgid "click to %toggle% this box" +msgstr "Ðажмите Ð´Ð»Ñ %toggle% на Ñтот блок" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +msgid "use the arrow keys to move this box" +msgstr "иÑпользуйте Ñтрелки Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñтого блока" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +msgid ", or press the enter key to %toggle% it" +msgstr ", или нажмите копку ввод (enter) Ð´Ð»Ñ %toggle% его" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +msgid "About this Plugin:" +msgstr "Об Ñто плагине:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +msgid "Plugin Homepage" +msgstr "ДомашнÑÑ Ñтраница плагина" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +msgid "Notify List" +msgstr "СпиÑок напоминаниÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +msgid "Support Forum" +msgstr "Форум техничеÑкой поддержки" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +msgid "Donate with PayPal" +msgstr "Пожертвовать через PayPal" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +msgid "My Amazon Wish List" +msgstr "Мой ÑпиÑок пожеланий на Amazon" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_name" +msgstr "Перевёл Сергей Рывкин" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +msgid "translator_url" +msgstr "http://ryvkin.ru" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +msgid "Sitemap Resources:" +msgstr "РеÑурÑÑ‹ карыт Ñайта:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +msgid "Webmaster Tools" +msgstr "ИнÑтрументы веб-маÑтера" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +msgid "Webmaster Blog" +msgstr "Дневник веб-маÑтера" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +msgid "Site Explorer" +msgstr "ПроÑмотр Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +msgid "Search Blog" +msgstr "ИÑкать в дневнике" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +msgid "Sitemaps Protocol" +msgstr "Протокол иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹ Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +msgid "Official Sitemaps FAQ" +msgstr "Официальный ЧÐВО по картам Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +msgid "My Sitemaps FAQ" +msgstr "Мой ЧÐВО по картам Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +msgid "Recent Donations:" +msgstr "ПоÑледние пожертвованиÑ:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +msgid "List of the donors" +msgstr "СпиÑок ÑпонÑоров" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +msgid "Hide this list" +msgstr "Скрыть Ñтот ÑпиÑок" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +msgid "Thanks for your support!" +msgstr "СпаÑибо за Вашу поддержку!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +msgid "Status" +msgstr "СтатуÑ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Карта Ñайта ещё не поÑтроена. Ðажмите здеÑÑŒ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐµÑ‘ впервые." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +msgid "Your sitemap was last built on %date%." +msgstr "Ваша карта Ñайта поÑледний раз была поÑтроена: %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreПочитать ещё" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "Ваша карта Ñайта (ÑжатаÑ) поÑледний раз была поÑтроена: %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreПочитать ещё" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +msgid "Google was successfully notified about changes." +msgstr "Google был уÑпешно проинформирован об изменениÑÑ…." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "%time% Ñекунд занÑло информирование Google; возможно, Ð’Ð°Ñ Ñтоит отключить Ñту функцию, чтобы Ñнизить Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "При информировании Google произошла ошибка. ПоÑмотреть результат" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOO был уÑпешно проинформирован об изменениÑÑ…." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "%time% Ñекунд занÑло информирование YAHOO; возможно, Ð’Ð°Ñ Ñтоит отключить Ñту функцию, чтобы Ñнизить Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "При информировании YAHOO произошла ошибка. ПоÑмотреть результат" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com был уÑпешно проинформирован об изменениÑÑ…." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "%time% Ñекунд занÑло информирование Ask.com; возможно, Ð’Ð°Ñ Ñтоит отключить Ñту функцию, чтобы Ñнизить Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "При информировании Ask.com произошла ошибка. ПоÑмотреть результат" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "ПроцеÑÑ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ Ð·Ð°Ð½Ñл примерно %time% Ñекунд и иÑпользовал %memory% MB памÑти." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +msgid "The building process took about %time% seconds to complete." +msgstr "ПроцеÑÑ Ð¿Ð¾ÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ Ð·Ð°Ð½Ñл примерно %time% Ñекунд." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Содержание Вашей карты Ñайта не изменÑлоÑÑŒ за поÑледнее времÑ, поÑтому файлы не запиÑывалиÑÑŒ и поиÑковые ÑиÑтемы не информировалиÑÑŒ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "ПоÑледний запуÑк не был завершен! Возможно, Ð’Ñ‹ превыÑили лимиты памÑти или времени иÑполнениÑ. Почитать ещё" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "ПоÑледний раз Ñкрипт иÑпользовал %memused%MB памÑти, лимит памÑти Вашего Ñервера ÑоÑтавлÑет %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "ПоÑледний раз Ñкрипт работал %timeused% Ñекунд, ограничение времени на Вашем Ñервере ÑоÑтавлÑет %timelimit% Ñекунд." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Скрипт оÑтановилÑÑ Ð¾ÐºÐ¾Ð»Ð¾ Ñтатьи номер %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "ЕÑли Ð’Ñ‹ что-то поменÑли на Вашем Ñервре или в дневнике, Вам необходимо заново поÑтроить карту Ñайта вручную." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "ЕÑли Ð’Ñ‹ ÑтолкнулиÑÑŒ Ñ ÐºÐ°ÐºÐ¸Ð¼Ð¸-либо проблемами в процеÑÑе поÑтроениÑ, Ð’Ñ‹ можете воÑпользоватьÑÑ Ñ„ÑƒÐ½ÐºÑ†Ð¸ÐµÐ¹ отладки Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +msgid "Basic Options" +msgstr "Базовые параметры" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +msgid "Sitemap files:" +msgstr "Файлы карты Ñайта:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Learn more" +msgstr "Почитать ещё" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3049 +msgid "Write a normal XML file (your filename)" +msgstr "ЗапиÑать обычный XML файл (Ваше Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3055 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "ЗапиÑать запакованный XML файл (Ваше Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +msgid "Building mode:" +msgstr "Режим поÑÑ‚Ñ€Ð¾ÐµÐ½Ð¸Ñ ÐºÐ°Ñ€Ñ‚Ñ‹:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "ПоÑтройте заново карту Ñайта, еÑли Ð’Ñ‹ изменили Ñодержание Вашего дневника" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +msgid "Enable manual sitemap building via GET Request" +msgstr "Разрешить ручное поÑтроение карты Ñайта Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ запроÑа GET" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Это разрешит Вам обновить карту Ñайта, еÑли внешний инÑтрумент будет пиÑать в базу WordPress? не иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ WordPress API. ИÑпользуйте Ñледующий URL Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа: %1 ПоÑмотрите протокол (Ñм. выше) Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸, поÑтроена ли карта Ñайта." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +msgid "Update notification:" +msgstr "Обновить уведомление:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +msgid "Notify Google about updates of your Blog" +msgstr "Уведомить Google об изменениÑÑ… в Вашем дневнике" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ðµ требуетÑÑ, но Ð’Ñ‹ можете приÑоединитьÑÑ Ðº ИнÑтрументам веб-маÑтера Google Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра ÑтатиÑтики поиÑковых роботов." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Уведомить Asc.com об изменениÑÑ… в Вашем дневнике" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +msgid "No registration required." +msgstr "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð½Ðµ требуетÑÑ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Уведомить YAHOO об изменениÑÑ… в Вашем дневнике" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +msgid "Your Application ID:" +msgstr "Ваш идентификатор Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (Application ID):" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "У Ð’Ð°Ñ Ð½ÐµÑ‚ такого ключа?? ЗапроÑите здеÑÑŒ! %s2" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3099 +#, php-format +msgid "Modify or create %s file in blog root which contains the sitemap location." +msgstr "Изменить или Ñоздать файл %s в дневнике, который Ñодержит информацию о раÑположении карты Ñайта." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3102 +msgid "File permissions: " +msgstr "Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° доÑтуп к файлам: " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3107 +msgid "OK, robots.txt is writable." +msgstr "OK, robots.txt открыт на запиÑÑŒ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3109 +msgid "Error, robots.txt is not writable." +msgstr "Ошибка, robots.txt не открыт на запиÑÑŒ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3113 +msgid "OK, robots.txt doesn't exist but the directory is writable." +msgstr "OK, robots.txt не ÑущеÑтвует, но каталог открыт на запиÑÑŒ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3115 +msgid "Error, robots.txt doesn't exist and the directory is not writable" +msgstr "Ошибка, robots.txt не ÑущеÑтвует, и каталог не открыт на запиÑÑŒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +msgid "Advanced options:" +msgstr "РаÑширенные параметры:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Limit the number of posts in the sitemap:" +msgstr "Ограничить количеÑтво Ñтатей в карте Ñайта:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +msgid "Newer posts will be included first" +msgstr "Более новые Ñтатьи будут включены первыми" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "Try to increase the memory limit to:" +msgstr "ПопытатьÑÑ ÑƒÐ²ÐµÐ»Ð¸Ñ‡Ð¸Ñ‚ÑŒ лимит памÑти до:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +msgid "e.g. \"4M\", \"16M\"" +msgstr "например, \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "Try to increase the execution time limit to:" +msgstr "ПопытатьÑÑ ÑƒÐ²ÐµÐ»Ð¸Ñ‡Ð¸Ñ‚ÑŒ ограничение времени иÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð¾:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "в Ñекундах, например, \"60\" или \"0\" Ð´Ð»Ñ Ð½ÐµÐ¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð½Ð¾Ð³Ð¾ времени" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Include a XSLT stylesheet:" +msgstr "Включить таблицу Ñтилей XSLT:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Use Default" +msgstr "ИÑпользовать значение по умолчанию" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +msgid "Full or relative URL to your .xsl file" +msgstr "Полный или отноÑительный URL к Вашему файлу .xsl" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Разрешить Ñтандартный режим MySQL. ИÑпользовать только в Ñлучае ошибок MySQL. (Требует намного больше памÑти!)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Строить карту Ñайта в фоновом процеÑÑе (Вам не надо ждать ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñтатьи)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "Exclude the following posts or pages:" +msgstr "ИÑключить Ñледующие Ñтатьи или Ñтраницы:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +msgid "List of IDs, separated by comma" +msgstr "СпиÑок идентификаторов (ID), разделенных запÑтыми" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +msgid "Additional pages" +msgstr "Дополнительные Ñтраницы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "ЗдеÑÑŒ Ð’Ñ‹ можете указать файлы или URL, которые должны быть включены в карту Ñайта, но не принадлежащие Вашему дневнику/WordPress.
        Ðапример,еÑли Ваш домен www.foo.com, а Ваш дневник раÑположен в www.foo.com/blog, Вам может понадобитьÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ домашнюю Ñтраницу из www.foo.com" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +msgid "Note" +msgstr "Замечание" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "ЕÑли Ваш дневник раÑположен в подкаталоге, и Ð’Ñ‹ хотите добавить Ñтраницы, которые находÑÑ‚ÑÑ Ð’Ð«Ð¨Ð• в Ñтруктуре каталогов, Вам ÐЕОБХОДИМО помеÑтить карту Ñайта в корневой каталог (См. Ñекцию "Размещение файла Ñ ÐºÐ°Ñ€Ñ‚Ð¾Ð¹ Ñайта" на Ñтой Ñтранице)!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +msgid "URL to the page" +msgstr "URL Ñтраницы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Введите URL Ñтой Ñтраницы. Примеры: http://www.foo.com/index.html или www.foo.com/home " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +msgid "Priority" +msgstr "Приоритет" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Выберите приоритет Ñтой Ñтраницы отноÑительно других Ñтраниц. Ðапример, Ваша Ð³Ð»Ð°Ð²Ð½Ð°Ñ Ñтраница может иметь более выÑокий приоритет, чем Ñтраница Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ о Ñайте." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +msgid "Last Changed" +msgstr "ПоÑледний раз изменÑлаÑÑŒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Введите дату поÑледнего Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² формате YYYY-MM-DD (2005-12-31, например) (не обÑзательно)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +msgid "Change Frequency" +msgstr "ЧаÑтота изменений" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +msgid "#" +msgstr "â„–" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +msgid "No pages defined." +msgstr "Ðет Ñтраниц." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +msgid "Add new page" +msgstr "Добавить новую Ñтраницу" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +msgid "Post Priority" +msgstr "Приоритет Ñтатьи" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Выберите, как будет вычиÑлÑтьÑÑ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚ каждой Ñтатьи:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "Do not use automatic priority calculation" +msgstr "Ðе иÑпользовать автоматичеÑкое вычиÑление приоритета" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Ð’Ñе Ñтатьи будут иметь одинаковый приоритет, который определен в "Приоритетах"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3348 +msgid "Location of your sitemap file" +msgstr "РаÑположение Вашего файла Ñ ÐºÐ°Ñ€Ñ‚Ð¾Ð¹ Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3353 +msgid "Automatic detection" +msgstr "ÐвтоматичеÑкое определение" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3357 +msgid "Filename of the sitemap file" +msgstr "Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ñ ÐºÐ°Ñ€Ñ‚Ð¾Ð¹ Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +msgid "Detected Path" +msgstr "Обнаруженный путь" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +msgid "Detected URL" +msgstr "Обнаруженный URL" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3365 +msgid "Custom location" +msgstr "ПользовательÑкое раÑположение" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3369 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "ÐбÑолютный или отноÑительный путь к файлу Ñ ÐºÐ°Ñ€Ñ‚Ð¾Ð¹ Ñайта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3371 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3380 +msgid "Example" +msgstr "Пример" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3378 +msgid "Complete URL to the sitemap file, including name." +msgstr "Заполните URL к файлу Ñ ÐºÐ°Ñ€Ñ‚Ð¾Ð¹ Ñайта, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +msgid "Sitemap Content" +msgstr "Содержание карты Ñайта" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +msgid "Include homepage" +msgstr "Включить домашнюю Ñтраницу" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +msgid "Include posts" +msgstr "Включить Ñтатьи" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +msgid "Include static pages" +msgstr "Включить ÑтатичеÑкие Ñтраницы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +msgid "Include categories" +msgstr "Включить категории" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +msgid "Include archives" +msgstr "Включить архивы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +msgid "Include tag pages" +msgstr "Включить Ñтраницы меток" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +msgid "Include author pages" +msgstr "Включить Ñтраницы авторов" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +msgid "Change frequencies" +msgstr "Изменить чаÑтоты" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Обратите внимание, что значение Ñтой метки ÑчитаетÑÑ Ñ€ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ð°Ñ†Ð¸ÐµÐ¹ и не ÑвлÑетÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹. Даже когда поиÑковые роботы берут Ñту информацию к Ñведению Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð½ÑÑ‚Ð¸Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ð¹, они могут оÑматривать Ñтраницы, помеченные \"раз в чаÑ\" реже, чем запрошено, и они могут оÑматривать Ñтраницы, помеченные как \"раз в год\" чаще, чем запрошено. Также бывает, что поиÑковые роботы оÑматривают Ñтраницы, помеченные как \"никогда\", Ð¾Ñ‚Ð¼ÐµÑ‡Ð°Ñ Ð½Ðµ предуÑмотренные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ð° Ñтих Ñтраницах." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +msgid "Homepage" +msgstr "Ð“Ð»Ð°Ð²Ð½Ð°Ñ Ñтраница" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +msgid "Posts" +msgstr "Статьи" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +msgid "Static pages" +msgstr "Статичные Ñтраницы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +msgid "Categories" +msgstr "Категории" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Текущий архив за Ñтот меÑÑц (Должен быть тем же, что и Ð“Ð»Ð°Ð²Ð½Ð°Ñ Ñтраница)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Старые архивы (ИзменÑÑŽÑ‚ÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в Ñлучае, еÑли Ð’Ñ‹ редактируете Ñтарые Ñтатьи)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +msgid "Tag pages" +msgstr "Страницы меток" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +msgid "Author pages" +msgstr "Страницы авторов" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +msgid "Priorities" +msgstr "Приоритеты" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +msgid "Posts (If auto calculation is disabled)" +msgstr "Статьи (ЕÑли автоматичеÑкое вычиÑление запрещено)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Минимальный приоритет Ñтатьи (Даже еÑли автоматичеÑкое вычиÑление разрешено)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +msgid "Archives" +msgstr "Ðрхивы" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +msgid "Update options" +msgstr "Обновить параметры" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +msgid "Reset options" +msgstr "Вернуть иÑходные значениÑ" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sl_SI.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sl_SI.mo new file mode 100644 index 0000000..823312b Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sl_SI.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sl_SI.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sl_SI.po new file mode 100644 index 0000000..0a7a57f --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sl_SI.po @@ -0,0 +1,325 @@ +msgid "" +msgstr "" +"Project-Id-Version: sitemap-sl_SI\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2006-11-13 09:33+0100\n" +"Last-Translator: m2-j \n" +"Language-Team: Milan Jungic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Slovenian\n" +"X-Poedit-Country: SLOVENIA\n" + +#: sitemap.php:375 +msgid "always" +msgstr "vedno" + +msgid "hourly" +msgstr "vsako uro" + +msgid "daily" +msgstr "dnevno" + +msgid "weekly" +msgstr "tedensko" + +msgid "monthly" +msgstr "meseÄno" + +msgid "yearly" +msgstr "letno" + +msgid "never" +msgstr "nikoli" + +msgid "Detected Path" +msgstr "Zaznana pot:" + +msgid "Example" +msgstr "Primer" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Absolutna ali relativna pot do datoteke naÄrta strani (vkljuÄno z imenom datoteke)" + +msgid "Complete URL to the sitemap file, including name." +msgstr "URL naslov datoteke naÄrta strani (vkljuÄno z imenom datoteke)." + +msgid "Automatic location" +msgstr "Samodejno lociranje" + +msgid "Manual location" +msgstr "RoÄno lociranje" + +msgid "OR" +msgstr "ALI" + +msgid "Location of your sitemap file" +msgstr "Ime datoteke naÄrta strani" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "ÄŒe je vaÅ¡ blog v podimeniku in želite v naÄrt strani dodatki datoteke, ki se nahajajo izven tega podimenika, morate datoteko naÄrta strani shraniti v korenski imenik, ki se nahaja nad vsemi imeniki katere želite v naÄrt strani vkljuÄiti (glejte sekcijo "Ime datoteke naÄrta strani" na tej strani)!" + +#: sitemap.php:512 +msgid "Configuration updated" +msgstr "Nastavitve so posodobljene" + +#: sitemap.php:513 +msgid "Error" +msgstr "Napaka" + +#: sitemap.php:521 +msgid "A new page was added. Click on "Save page changes" to save your changes." +msgstr "Nova stran je dodana. Za uveljavitev sprememb, izberite "Shrani stran"." + +#: sitemap.php:527 +msgid "Pages saved" +msgstr "Strani so shranjene." + +#: sitemap.php:528 +msgid "Error while saving pages" +msgstr "Napaka pri shranjevanju strani" + +#: sitemap.php:539 +msgid "The page was deleted. Click on "Save page changes" to save your changes." +msgstr "Stran je izbrisana. Za uveljavitev sprememb, izberite "Shrani stran"." + +#: sitemap.php:542 +msgid "You changes have been cleared." +msgstr "Spremembe so razveljavljene." + +#: sitemap.php:555 +msgid "Sitemap Generator" +msgstr "Generator naÄrta strani" + +#: sitemap.php:558 +msgid "Manual rebuild" +msgstr "RoÄno" + +#: sitemap.php:559 +msgid "If you want to build the sitemap without editing a post, click on here!" +msgstr "Izberite to možnost, Äe želite takoj ustvariti naÄrt strani." + +#: sitemap.php:560 +msgid "Rebuild Sitemap" +msgstr "Ustvari naÄrt strani" + +#: sitemap.php:564 +msgid "Additional pages" +msgstr "Dodatne strani" + +#: sitemap.php:566 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Tukaj lahko navedete datoteke in URL naslove, ki niso del vaÅ¡e Wordpress namestitve, želite jih pa vkljuÄiti v naÄrt strani.
        Primer: VaÅ¡a domena je www.foo.com, blog se nahaja na naslovu www.foo.com/blog, medtem, ko vi v naÄrt strani želite vkljuÄiti tudi naslov www.foo.com s pripadajoÄo vsebino." + +#: sitemap.php:568 +msgid "URL to the page" +msgstr "URL naslov strani" + +#: sitemap.php:569 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Vnestite URL naslov strani. Primer: www.foo.com ali www.foo.com/home" + +#: sitemap.php:571 +msgid "Priority" +msgstr "Prioriteta" + +#: sitemap.php:572 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Izberi prioriteto strani, glede na ostale strani. Npr. za vaÅ¡o domaÄo stran www.foo.com želite morda viÅ¡jo prioriteto kot za vaÅ¡ blog www.foo.com/blog? " + +#: sitemap.php:574 +msgid "Last Changed" +msgstr "ZadnjiÄ spremenjeno" + +#: sitemap.php:575 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Vnesite datum zadnje spremembe JJJJ-MM-TT (oblika: 2005-12-31). (opcija)" + +#: sitemap.php:583 +msgid "Change Frequency" +msgstr "Spremeni frekvenco" + +#: sitemap.php:585 +msgid "#" +msgstr "#" + +#: sitemap.php:609 +msgid "No pages defined." +msgstr "Nobena stran ni bila Å¡e definirana." + +#: sitemap.php:616 +msgid "Add new page" +msgstr "Dodaj novo stran" + +# sitemap.php:617: +#: sitemap.php:617 +msgid "Save page changes" +msgstr "Shrani spremembe" + +# sitemap.php:618: +#: sitemap.php:618 +msgid "Undo all page changes" +msgstr "Razveljavi spremembe" + +# sitemap.php:621: +#: sitemap.php:621 +msgid "Delete marked page" +msgstr "IzbriÅ¡i izbrane strani" + +#: sitemap.php:627 +msgid "Basic Options" +msgstr "Osnovne nastavitve" + +#: sitemap.php:632 +msgid "Enable automatic priority calculation for posts based on comment count" +msgstr "DoloÄi prioriteto objav glede na Å¡tevilo komentarjev pod posameznimi objavami" + +#: sitemap.php:638 +msgid "Write debug comments" +msgstr "ZapiÅ¡i komentarje za iskanje in odpravljanje napak" + +#: sitemap.php:643 +msgid "Filename of the sitemap file" +msgstr "Ime datoteke naÄrta strani" + +#: sitemap.php:650 +msgid "Write a normal XML file (your filename)" +msgstr "Shrani naÄrt strani kot standardno XML datoteko" + +#: sitemap.php:652 +msgid "Detected URL" +msgstr "Zaznan URL naslov" + +#: sitemap.php:657 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Shrani kot stisnjeno (gzip) datoteko (ime datoteke + .gz)" + +#: sitemap.php:664 +msgid "Auto-Ping Google Sitemaps" +msgstr "Samodejno obvesti Google o spremembah (ping)" + +#: sitemap.php:665 +msgid "This option will automatically tell Google about changes." +msgstr "ÄŒe izberete to možnost, bodo morebitne spremembe v naÄrtu strani samodejno posredovane Googlu." + +#: sitemap.php:672 +msgid "Includings" +msgstr "Vsebina" + +#: sitemap.php:677 +msgid "Include homepage" +msgstr "VkljuÄi osnovno (prvo) stran" + +#: sitemap.php:683 +msgid "Include posts" +msgstr "VkljuÄi objave" + +#: sitemap.php:689 +msgid "Include static pages" +msgstr "VkljuÄi statiÄne strani" + +#: sitemap.php:695 +msgid "Include categories" +msgstr "VkljuÄi kategorije" + +#: sitemap.php:701 +msgid "Include archives" +msgstr "VkljuÄi zgodovino (arhivi)" + +#: sitemap.php:708 +msgid "Change frequencies" +msgstr "Spremeni frekvenco" + +#: sitemap.php:709 +msgid "Note" +msgstr "Opomba" + +#: sitemap.php:710 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Ta nastavitev je zgolj predlagana. ÄŒeprav spletni iskalniki nastavljeno frekvenco upoÅ¡tevajo, se zna zgoditi, da bodo strani nastavljene na urno osveževanje pregledovali redkeje, kot strani nastavljene na letno osveževanje. Ravno tako se zna zgoditi, da bodo iskalniki pregledovali strani, katerim ste nastavili, da se ne osvežujejo." + +#: sitemap.php:715 +msgid "Homepage" +msgstr "Osnovna stran" + +#: sitemap.php:721 +msgid "Posts" +msgstr "Objave" + +#: sitemap.php:727 +msgid "Static pages" +msgstr "StatiÄne strani" + +#: sitemap.php:733 +msgid "Categories" +msgstr "Kategorije" + +#: sitemap.php:739 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Aktualni arhiv tega meseca (enako kot za osnovno stran)" + +#: sitemap.php:745 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "StarejÅ¡i arhivi" + +#: sitemap.php:752 +msgid "Priorities" +msgstr "Prioritete" + +#: sitemap.php:763 +msgid "Posts (If auto calculation is disabled)" +msgstr "Å tevilo objav (v primeru, ko je samodejno seÅ¡tevanje onemogoÄeno)" + +#: sitemap.php:769 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "NajmanjÅ¡a prioriteta za objave (tudi, ko je izbrana možnost samodejnega izraÄunavanja prioritet)" + +#: sitemap.php:787 +msgid "Archives" +msgstr "Arhivi" + +#: sitemap.php:793 +msgid "Informations and support" +msgstr "Informacije in podpora" + +#: sitemap.php:794 +msgid "Check %s for updates and comment there if you have any problems / questions / suggestions." +msgstr "Popravke in pomoÄ za vtiÄnik boste naÅ¡li na %s." + +#: sitemap.php:797 +msgid "Update options" +msgstr "Shrani nastavitve" + +#: sitemap.php:1033 +msgid "URL:" +msgstr "URL:" + +#: sitemap.php:1034 +msgid "Path:" +msgstr "Pot:" + +# msgid "URL:" +# msgstr "" +# msgid "Path:" +# msgstr "" +#: sitemap.php:1037 +msgid "Could not write into %s" +msgstr "Napaka pri shranjevanju datoteke "%s"." + +#: sitemap.php:1048 +msgid "Successfully built sitemap file:" +msgstr "NaÄrt strani je bil uspeÅ¡no zapisan:" + +#: sitemap.php:1048 +msgid "Successfully built gzipped sitemap file:" +msgstr "NaÄrt strani je bil uspeÅ¡no zapisan v stisnjeno (gzip) datoteko:" + +#: sitemap.php:1062 +msgid "Could not ping to Google at %s" +msgstr "Napaka pri obveÅ¡Äanju Googla o spremembah (%s)" + +#: sitemap.php:1064 +msgid "Successfully pinged Google at %s" +msgstr "Google je uspeÅ¡no obveÅ¡Äen o spremembah (%s)" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sr_RS.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sr_RS.mo new file mode 100644 index 0000000..0676bf8 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sr_RS.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sr_RS.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sr_RS.po new file mode 100644 index 0000000..53b5aa8 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sr_RS.po @@ -0,0 +1,964 @@ +msgid "" +msgstr "" +"Project-Id-Version: Google XML Sitemaps v4.0beta9\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-05-05 20:24+0100\n" +"PO-Revision-Date: 2012-06-02 14:54:30+0000\n" +"Last-Translator: Arne Brachhold \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Poedit-Language: \n" +"X-Poedit-Country: \n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-Bookmarks: \n" +"X-Poedit-SearchPath-0: C:/Inetpub/wwwroot/wp_plugins/sitemap_beta\n" +"X-Textdomain-Support: yes" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:846 +#: sitemap-core.php:527 +#@ sitemap +msgid "Comment Count" +msgstr "Broj Komentara" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:858 +#: sitemap-core.php:537 +#@ sitemap +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "Koristi broj komentara na postu za kalkulaciju prioriteta" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:918 +#: sitemap-core.php:590 +#@ sitemap +msgid "Comment Average" +msgstr "ProseÄan Broj Komentara" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:930 +#: sitemap-core.php:600 +#@ sitemap +msgid "Uses the average comment count to calculate the priority" +msgstr "Koristi proseÄan broj komentara za raÄunanje prioriteta" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:993 +#: sitemap-core.php:661 +#@ sitemap +msgid "Popularity Contest" +msgstr "TakmiÄenje Popularnosti" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:1005 +#: sitemap-core.php:671 +#, php-format +#@ sitemap +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Koristi aktivirani TakmiÄenje Popularnosti plugin od Alex King-a. Proveri PodeÅ¡avanja i Najpopularnije Postove" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-core.php:1118 +#: sitemap-core.php:840 +#@ sitemap +msgid "Always" +msgstr "Uvek" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-core.php:1119 +#: sitemap-core.php:841 +#@ sitemap +msgid "Hourly" +msgstr "Svakog sata" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-core.php:1120 +#: sitemap-core.php:842 +#@ sitemap +msgid "Daily" +msgstr "Dnevno" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-core.php:1121 +#: sitemap-core.php:843 +#@ sitemap +msgid "Weekly" +msgstr "Nedeljno" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-core.php:1122 +#: sitemap-core.php:844 +#@ sitemap +msgid "Monthly" +msgstr "MeseÄno" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-core.php:1123 +#: sitemap-core.php:845 +#@ sitemap +msgid "Yearly" +msgstr "GodiÅ¡nje" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-core.php:1124 +#: sitemap-core.php:846 +#@ sitemap +msgid "Never" +msgstr "Nikad" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2415 +#: sitemap-loader.php:212 +#@ sitemap +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap Generator" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2415 +#: sitemap-loader.php:212 +#@ sitemap +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +#: sitemap-loader.php:239 +#@ sitemap +msgid "Settings" +msgstr "PodeÅ¡avanja" + +#: sitemap-loader.php:240 +#@ sitemap +msgid "FAQ" +msgstr "FAQ" + +#: sitemap-loader.php:241 +#@ sitemap +msgid "Support" +msgstr "PodrÅ¡ka" + +#: sitemap-loader.php:242 +#@ sitemap +msgid "Donate" +msgstr "Donacije" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2886 +#: sitemap-loader.php:328 +#: sitemap-ui.php:630 +#@ sitemap +msgid "Plugin Homepage" +msgstr "Homepage Plugin-a" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2905 +#: sitemap-loader.php:329 +#: sitemap-ui.php:652 +#@ sitemap +msgid "My Sitemaps FAQ" +msgstr "ÄŒesta pitanja o Sitemap-ima" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2635 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2835 +#: sitemap-ui.php:198 +#: sitemap-ui.php:585 +#@ sitemap +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Sitemap Generator za WordPress" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2740 +#: sitemap-ui.php:374 +#@ sitemap +msgid "Configuration updated" +msgstr "Konfiguracije ažurirane" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2741 +#: sitemap-ui.php:375 +#@ sitemap +msgid "Error while saving options" +msgstr "GreÅ¡ka prilikom snimanja opcija" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2743 +#: sitemap-ui.php:378 +#@ sitemap +msgid "Pages saved" +msgstr "Stranice snimljene" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2744 +#: sitemap-ui.php:379 +#@ sitemap +msgid "Error while saving pages" +msgstr "GreÅ¡ka za vreme snimanja stranica" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2758 +#: sitemap-ui.php:387 +#@ sitemap +msgid "The default configuration was restored." +msgstr "Osnovna podeÅ¡avanja su vraćena" + +#: sitemap-ui.php:397 +#@ sitemap +msgid "The old files could NOT be deleted. Please use an FTP program and delete them by yourself." +msgstr "Nismo mogli izbrisati stare fajlove. Molimo vas da koristite FTP program i obriÅ¡ete ih liÄno." + +#: sitemap-ui.php:399 +#@ sitemap +msgid "The old files were successfully deleted." +msgstr "Stari fajlovi su uspeÅ¡no obrisani." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2600 +#: sitemap-ui.php:439 +#@ sitemap +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Hvala vam na donaciji. Pomažete mi da nastavim rad i razvoj ovog plugin-a i drugih besplatnih programa." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2600 +#: sitemap-ui.php:439 +#@ sitemap +msgid "Hide this notice" +msgstr "Sakrijte ovo obaveÅ¡tenje" + +#: sitemap-ui.php:445 +#, php-format +#@ sitemap +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and you are satisfied with the results, isn't it worth at least a few dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "Hvala vam Å¡to koristite ovaj plugin. Instalirali ste plugin pre meseca dana. Ako plugin radi i zadovoljni ste rezultatima, nadam se da je vredno makar par dolara? Donacije mi pomažu da nastavim rad na ovom besplatnom softveru! Naravno, nema problema!" + +#: sitemap-ui.php:445 +#@ sitemap +msgid "Sure, but I already did!" +msgstr "Naravno, ali već sam donirao!" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2657 +#: sitemap-ui.php:445 +#@ sitemap +msgid "No thanks, please don't bug me anymore!" +msgstr "Ne hvala, molim vas ne uznemiravajte me viÅ¡e!" + +#: sitemap-ui.php:452 +#, php-format +#@ sitemap +msgid "Thanks for using this plugin! You've installed this plugin some time ago. If it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "Hvala vam Å¡to koristite ovaj plugin! Instalirali ste ovaj plugin pre nekog vremena. Ako radi i zadovoljni ste, zaÅ¡to ne biste dali ocenu i preporuÄili ga drugima? :-)" + +#: sitemap-ui.php:452 +#@ sitemap +msgid "Don't show this anymore" +msgstr "Ne pokazuj viÅ¡e" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-ui.php:374 +#: sitemap-ui.php:601 +#, php-format +#@ default +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "Postoji nova verzija %1$s. Skinite verziju %3$s ovde." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-ui.php:376 +#: sitemap-ui.php:603 +#, php-format +#@ default +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "Postoji nova verzija %1$s. Skinite novu verziju %3$s ovde automatsko osvežavanje verzije nije dostupno za ovaj plugin." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-ui.php:378 +#: sitemap-ui.php:605 +#, php-format +#@ default +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "Postoji nova verzija %1$s. Skinite verziju %3$s ovde ili uradite update automatski." + +#: sitemap-ui.php:613 +#, php-format +#@ sitemap +msgid "Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "VaÅ¡ blog trenutno blokira pretraživaÄe! Posetite podeÅ¡avanja privatnosti da bi ste promenili." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2884 +#: sitemap-ui.php:629 +#@ sitemap +msgid "About this Plugin:" +msgstr "O ovom plugin-u:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-ui.php:421 +#: sitemap-ui.php:631 +#@ sitemap +msgid "Suggest a Feature" +msgstr "Predložite Funkciju" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2887 +#: sitemap-ui.php:632 +#@ sitemap +msgid "Notify List" +msgstr "Lista Notifikacija" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2888 +#: sitemap-ui.php:633 +#@ sitemap +msgid "Support Forum" +msgstr "Forum za PodrÅ¡ku" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap-ui.php:424 +#: sitemap-ui.php:634 +#@ sitemap +msgid "Report a Bug" +msgstr "Prijavite GreÅ¡ku" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2889 +#: sitemap-ui.php:636 +#@ sitemap +msgid "Donate with PayPal" +msgstr "Donirajte putem PayPal-a" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2890 +#: sitemap-ui.php:637 +#@ sitemap +msgid "My Amazon Wish List" +msgstr "Moje želje na Amazon-u" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2891 +#: sitemap-ui.php:638 +#@ sitemap +msgid "translator_name" +msgstr "ime_prevodioca" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2891 +#: sitemap-ui.php:638 +#@ sitemap +msgid "translator_url" +msgstr "url_prevodioca" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2895 +#: sitemap-ui.php:641 +#@ sitemap +msgid "Sitemap Resources:" +msgstr "ViÅ¡e o Sitemap-u" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2897 +#: sitemap-ui.php:642 +#: sitemap-ui.php:647 +#@ sitemap +msgid "Webmaster Tools" +msgstr "Alatke za Webmastere" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2898 +#: sitemap-ui.php:643 +#@ sitemap +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2901 +#: sitemap-ui.php:645 +#@ sitemap +msgid "Search Blog" +msgstr "Pretražite Blog" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3010 +#: sitemap-ui.php:648 +#@ sitemap +msgid "Webmaster Center Blog" +msgstr "Webmaster Central Blog" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2903 +#: sitemap-ui.php:650 +#@ sitemap +msgid "Sitemaps Protocol" +msgstr "Sitemap Protokol" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2904 +#: sitemap-ui.php:651 +#@ sitemap +msgid "Official Sitemaps FAQ" +msgstr "Oficijalni Sitemap FAW" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2910 +#: sitemap-ui.php:655 +#@ sitemap +msgid "Recent Donations:" +msgstr "Zadnje Donacije:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2914 +#: sitemap-ui.php:658 +#@ sitemap +msgid "List of the donors" +msgstr "Lista Donatora" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2916 +#: sitemap-ui.php:660 +#@ sitemap +msgid "Hide this list" +msgstr "Sakrijte listu" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:2919 +#: sitemap-ui.php:663 +#@ sitemap +msgid "Thanks for your support!" +msgstr "Hvala vam na podrÅ¡ci!" + +#: sitemap-ui.php:683 +#@ sitemap +msgid "Search engines haven't been notified yet" +msgstr "PretraživaÄi joÅ¡ uvek nisu obaveÅ¡teni" + +#: sitemap-ui.php:687 +#, php-format +#@ sitemap +msgid "Result of the last ping, started on %date%." +msgstr "Rezultati zadnjeg ping-a, zapoÄeto %date%." + +#: sitemap-ui.php:702 +#, php-format +#@ sitemap +msgid "There is still a sitemap.xml or sitemap.xml.gz file in your blog directory. Please delete them as no static files are used anymore or try to delete them automatically." +msgstr "JoÅ¡ uvek postoji sitemap.xml ili sitemap.xml.gz fajl na vaÅ¡em blog direktorijumu. Molimo vas da ih obriÅ¡ete jer se viÅ¡e ne koristi ni jeda statiÄni fajl ili pokuÅ¡ajte da ih obriÅ¡ete automatski." + +#: sitemap-ui.php:705 +#, php-format +#@ sitemap +msgid "The URL to your sitemap index file is: %s." +msgstr "URL do vaÅ¡eg sitemap index fajl-a je: %s." + +#: sitemap-ui.php:708 +#@ sitemap +msgid "Search engines haven't been notified yet. Write a post to let them know about your sitemap." +msgstr "PretraživaÄi joÅ¡ uvek nisu obaveÅ¡teni. NapiÅ¡ite post da bi ste ih obavestili o vaÅ¡em sitemap-u." + +#: sitemap-ui.php:717 +#, php-format +#@ sitemap +msgid "%s was successfully notified about changes." +msgstr "%s je uspeÅ¡no obaveÅ¡ten o promenama." + +#: sitemap-ui.php:720 +#, php-format +#@ sitemap +msgid "It took %time% seconds to notify %name%, maybe you want to disable this feature to reduce the building time." +msgstr "Trebalo je %time% sekundi da obavestimo %name%, možda želite da onesposobite ovu funkciju da bi ste smanjili vreme izgradnje." + +#: sitemap-ui.php:723 +#, php-format +#@ sitemap +msgid "There was a problem while notifying %name%. View result" +msgstr "Imali smo problem sa obaveÅ¡tavanjem %name%. Pogledajte rezultate" + +#: sitemap-ui.php:727 +#, php-format +#@ sitemap +msgid "If you encounter any problems with your sitemap you can use the debug function to get more information." +msgstr "Ako naiÄ‘ete na neke probleme u vezi sa sitemap-om možete iskoristiti debug funkciju da bi ste dobili viÅ¡e podataka." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3040 +#: sitemap-ui.php:735 +#@ sitemap +msgid "Basic Options" +msgstr "Onsovne Opcije" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3079 +#: sitemap-ui.php:737 +#@ sitemap +msgid "Update notification:" +msgstr "Ažurirajte notifikacije:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3044 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3059 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3079 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3104 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3121 +#: sitemap-ui.php:737 +#: sitemap-ui.php:765 +#@ sitemap +msgid "Learn more" +msgstr "Saznajte viÅ¡e" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3083 +#: sitemap-ui.php:741 +#@ sitemap +msgid "Notify Google about updates of your Blog" +msgstr "Obavestite Google o promenama na vaÅ¡em Blogu" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3084 +#: sitemap-ui.php:742 +#, php-format +#@ sitemap +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Registracija nije potrebna, ali možete otovriti nalog na Google Webmaster Tools da bi ste preverili statistiku." + +#: sitemap-ui.php:746 +#@ sitemap +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "Obavestite Bing (bivÅ¡i MSN Live Search) o promenama na vaÅ¡em Blogu" + +#: sitemap-ui.php:747 +#, php-format +#@ sitemap +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "Registracija nije potrebna, ali možete napraviti nalog na Bing Webmaster Tools da proverite statistiku." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3088 +#: sitemap-ui.php:751 +#@ sitemap +msgid "Notify Ask.com about updates of your Blog" +msgstr "Obavestite Ask.com o promenama na vaÅ¡em Blogu" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3089 +#: sitemap-ui.php:752 +#@ sitemap +msgid "No registration required." +msgstr "Registracija nije potrebna." + +#: sitemap-ui.php:757 +#@ sitemap +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Dodajte URL vaÅ¡eg sitemap-a u robots.txt fajl." + +#: sitemap-ui.php:761 +#@ sitemap +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "Virtualni robots.txt fajl generisan od strane WordPress-a je iskorišćen. Pravi robots.txt fajl NE SME postojati u direktorijumu vaÅ¡eg bloga!" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3121 +#: sitemap-ui.php:765 +#@ sitemap +msgid "Advanced options:" +msgstr "Napredne opcija:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3127 +#: sitemap-ui.php:768 +#@ sitemap +msgid "Try to increase the memory limit to:" +msgstr "PokuÅ¡ajte da povećate limit memorije na:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3127 +#: sitemap-ui.php:768 +#@ sitemap +msgid "e.g. \"4M\", \"16M\"" +msgstr "npr. \"4M\", \"16M\"" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3130 +#: sitemap-ui.php:771 +#@ sitemap +msgid "Try to increase the execution time limit to:" +msgstr "PokuÅ¡ajte da povećate vreme izvrÅ¡enja na:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3130 +#: sitemap-ui.php:771 +#@ sitemap +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "u sekundama, npr. \"60\" or \"0\" za neograniÄeno" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3133 +#: sitemap-ui.php:775 +#@ sitemap +msgid "Include a XSLT stylesheet:" +msgstr "Dodajte XSLT stylesheet:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3133 +#: sitemap-ui.php:776 +#@ sitemap +msgid "Full or relative URL to your .xsl file" +msgstr "Absolutni ili relativni URL do vasÅ¡eg .xsl fajla." + +#: sitemap-ui.php:776 +#@ sitemap +msgid "Use default" +msgstr "Koristite default-ni" + +#: sitemap-ui.php:781 +#@ sitemap +msgid "Include sitemap in HTML format" +msgstr "Dodajte sitemap u HTML formatu" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3144 +#: sitemap-ui.php:790 +#@ sitemap +msgid "Additional pages" +msgstr "Dodatne stranice" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3149 +#: sitemap-ui.php:793 +#@ sitemap +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Ovde možete specificirati fajlove ili URL-ove koje bi trebalo dodati u sitemap, ali ne pripadaju vašem Blog-u/WordPress-u.
        Na primer, ako je vaÅ¡ domen www.foo.com a vaÅ¡ blog se nalazi na www.foo.com-blog mozda želite da dodate vaÅ¡u poÄetnu stranu www.foo.com" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3151 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3462 +#: sitemap-ui.php:795 +#: sitemap-ui.php:999 +#: sitemap-ui.php:1010 +#: sitemap-ui.php:1019 +#@ sitemap +msgid "Note" +msgstr "Opazite" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3152 +#: sitemap-ui.php:796 +#@ sitemap +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Ako se vaÅ¡ blog nalazi u pod direktorijumu i ako želite da doddate stranice koje se ne nalaze u blog direktorijumu ili ispod, MORATE staviti sitemap fajl u korenu direktorijuma (Pogledajte "Lokaciju vaÅ¡eg sitemap-a " sekciju na ovoj stranici)!" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3154 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3300 +#: sitemap-ui.php:798 +#: sitemap-ui.php:837 +#@ sitemap +msgid "URL to the page" +msgstr "URL do stranice" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3155 +#: sitemap-ui.php:799 +#@ sitemap +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Unesite URL do stranice. Primeri: http://www.foo.com/index.html ili www.foo.com/home " + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3157 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3301 +#: sitemap-ui.php:801 +#: sitemap-ui.php:838 +#@ sitemap +msgid "Priority" +msgstr "Prioritet" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3158 +#: sitemap-ui.php:802 +#@ sitemap +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Izaberite prioritet stranice u odnosu na druge stranice. Na primer, vaÅ¡a poÄetna stranica može imati veći prioritet nego niće stranice." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3160 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3303 +#: sitemap-ui.php:804 +#: sitemap-ui.php:840 +#@ sitemap +msgid "Last Changed" +msgstr "Zadjne promene" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3161 +#: sitemap-ui.php:805 +#@ sitemap +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Unesti datum zadnje prmene u formatu YYYY-MM-DD (2005-12-31 na primer) (opciono)." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3302 +#: sitemap-ui.php:839 +#@ sitemap +msgid "Change Frequency" +msgstr "Promente UÄestalost" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3304 +#: sitemap-ui.php:841 +#@ sitemap +msgid "#" +msgstr "#" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3309 +#: sitemap-ui.php:846 +#@ sitemap +msgid "No pages defined." +msgstr "Stranice nisu definisane." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3314 +#: sitemap-ui.php:851 +#@ sitemap +msgid "Add new page" +msgstr "Dodajte novu stranicu" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3325 +#: sitemap-ui.php:857 +#@ sitemap +msgid "Post Priority" +msgstr "Prioritet postova" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3329 +#: sitemap-ui.php:859 +#@ sitemap +msgid "Please select how the priority of each post should be calculated:" +msgstr "Molimo vas izaberite kako se raÄuna prioritet postova:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3331 +#: sitemap-ui.php:861 +#@ sitemap +msgid "Do not use automatic priority calculation" +msgstr "Ne koristi automatsku kalkulaciju prioriteta" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3331 +#: sitemap-ui.php:861 +#@ sitemap +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Svi postovi će imati isti prioritet koji je definisan u "Priorities"" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3397 +#: sitemap-ui.php:872 +#@ sitemap +msgid "Sitemap Content" +msgstr "Sadržaj sitemap-a" + +#: sitemap-ui.php:873 +#@ sitemap +msgid "WordPress standard content" +msgstr "WordPress standardni sadržaj" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3405 +#: sitemap-ui.php:878 +#@ sitemap +msgid "Include homepage" +msgstr "Dodajte poÄetnu " + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3411 +#: sitemap-ui.php:884 +#@ sitemap +msgid "Include posts" +msgstr "Dodajte postove" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3417 +#: sitemap-ui.php:890 +#@ sitemap +msgid "Include static pages" +msgstr "Dodajte statiÄke stranice" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3423 +#: sitemap-ui.php:896 +#@ sitemap +msgid "Include categories" +msgstr "Dodajte kategorije" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3429 +#: sitemap-ui.php:902 +#@ sitemap +msgid "Include archives" +msgstr "Dodajte arhive" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3443 +#: sitemap-ui.php:908 +#@ sitemap +msgid "Include author pages" +msgstr "Dodajte stranice autora" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3436 +#: sitemap-ui.php:915 +#@ sitemap +msgid "Include tag pages" +msgstr "Dodajte tag stranice" + +#: sitemap-ui.php:929 +#@ sitemap +msgid "Custom taxonomies" +msgstr "UobiÄajene taxonomije" + +#: sitemap-ui.php:940 +#, php-format +#@ sitemap +msgid "Include taxonomy pages for %s" +msgstr "Dodajte stranice taxonomije za %s" + +#: sitemap-ui.php:958 +#@ sitemap +msgid "Custom post types" +msgstr "UobiÄajeni tipovi postova" + +#: sitemap-ui.php:969 +#, php-format +#@ sitemap +msgid "Include custom post type %s" +msgstr "Dodajte uobiÄajene tipove postova %s" + +#: sitemap-ui.php:981 +#@ sitemap +msgid "Further options" +msgstr "JoÅ¡ opcija" + +#: sitemap-ui.php:986 +#@ sitemap +msgid "Include the last modification time." +msgstr "Dodajte vreme zadnje modifikacije" + +#: sitemap-ui.php:988 +#@ sitemap +msgid "This is highly recommended and helps the search engines to know when your content has changed. This option affects all sitemap entries." +msgstr "Ovo je preporuÄljivo jer govori pretraživaÄima kada se vaÅ¡ sadržaj promeni. Ova opcija utiÄe sve unose u sitemap." + +#: sitemap-ui.php:995 +#@ sitemap +msgid "Excluded items" +msgstr "Uklonite" + +#: sitemap-ui.php:997 +#@ sitemap +msgid "Excluded categories" +msgstr "Uklonite kategorije" + +#: sitemap-ui.php:999 +#@ sitemap +msgid "Using this feature will increase build time and memory usage!" +msgstr "Korišćenje ove funkcije će povećati vreme pravljenja i korišćenje memorije." + +#: sitemap-ui.php:1006 +#@ sitemap +msgid "Exclude posts" +msgstr "Uklonite postove" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3206 +#: sitemap-ui.php:1008 +#@ sitemap +msgid "Exclude the following posts or pages:" +msgstr "Uklonite sledeće postove ili stranice:" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3206 +#: sitemap-ui.php:1008 +#@ sitemap +msgid "List of IDs, separated by comma" +msgstr "Lista ID-a, odvojene zarezom" + +#: sitemap-ui.php:1010 +#@ sitemap +msgid "Child posts won't be excluded automatically!" +msgstr "Pod postovi neće biti ukljuÄeni automatski!" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3457 +#: sitemap-ui.php:1016 +#@ sitemap +msgid "Change frequencies" +msgstr "Promenite uÄestalost" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3463 +#: sitemap-ui.php:1020 +#@ sitemap +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Molimo vas da zapamtite da vrednost ovog tag-a je koristi kao predlog a ne kao komanda. Iako pretraživaÄi razmatraju ovu infomaciju kada donose odluke, možda će proći kroz stranice obeležene \"hourly\" reÄ‘e nego naznaÄeno, a možda će stranice naznaÄene \"yearly\" posećivati Äešće. Isto tako je verovatno da će s'vremena na vreme prolaziti kroz stranice naznaÄene sa \"never\" da bi mogli da reaguju na neoÄekivane promene na tim stranicama." + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3469 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3535 +#: sitemap-ui.php:1026 +#: sitemap-ui.php:1083 +#@ sitemap +msgid "Homepage" +msgstr "PoÄetna" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3475 +#: sitemap-ui.php:1032 +#@ sitemap +msgid "Posts" +msgstr "Postovi" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3481 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3553 +#: sitemap-ui.php:1038 +#: sitemap-ui.php:1101 +#@ sitemap +msgid "Static pages" +msgstr "StatiÄne stranice" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3487 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3559 +#: sitemap-ui.php:1044 +#: sitemap-ui.php:1107 +#@ sitemap +msgid "Categories" +msgstr "Kategorije" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3493 +#: sitemap-ui.php:1050 +#@ sitemap +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Trenutna arhiva za ovaj mesec (Treba biti ista kao i vaÅ¡a poÄetna stranica)" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3499 +#: sitemap-ui.php:1056 +#@ sitemap +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Starije arhive (Menja se samo ako promenti stariji post)" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3506 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3572 +#: sitemap-ui.php:1063 +#: sitemap-ui.php:1120 +#@ sitemap +msgid "Tag pages" +msgstr "Tag stranice" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3513 +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3579 +#: sitemap-ui.php:1070 +#: sitemap-ui.php:1127 +#@ sitemap +msgid "Author pages" +msgstr "Stranice autora" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3527 +#: sitemap-ui.php:1078 +#@ sitemap +msgid "Priorities" +msgstr "Prioriteti" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3541 +#: sitemap-ui.php:1089 +#@ sitemap +msgid "Posts (If auto calculation is disabled)" +msgstr "Postovi (ako je auto kalkulacija iskljuÄena)" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3547 +#: sitemap-ui.php:1095 +#@ sitemap +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Minimalni prioritet za postove (ÄŒak iako je auto kalkulacija ukljuÄena)" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3565 +#: sitemap-ui.php:1113 +#@ sitemap +msgid "Archives" +msgstr "Arhive" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3590 +#: sitemap-ui.php:1138 +#@ sitemap +msgid "Update options" +msgstr "Opcije ažuriranja" + +# C:Inetpubwwwrootwpwp-contentpluginssitemap_beta/sitemap.php:3591 +#: sitemap-ui.php:1139 +#@ sitemap +msgid "Reset options" +msgstr "Opcije za resetovanje" + +#: sitemap.php:82 +#@ sitemap +msgid "Your WordPress version is too old for XML Sitemaps." +msgstr "VaÅ¡a verzija WordPress-a je previÅ¡e stara za XML Sitemap." + +#: sitemap.php:82 +#, php-format +#@ sitemap +msgid "Unfortunately this release of Google XML Sitemaps requires at least WordPress %4$s. You are using Wordpress %2$s, which is out-dated and insecure. Please upgrade or go to active plugins and deactivate the Google XML Sitemaps plugin to hide this message. You can download an older version of this plugin from the plugin website." +msgstr "Nažalost ova verzija Google XML Sitemap-a zahteva barem WordPress verziju %4$s. Vi koristite WordPress verziju %2$s, koja je zastarela i nesigurna. Molimo vas da update-ujete ili odete na aktivne plugin-ove i deaktivirate Google XML Sitemap plugin da bi ste sakrili ovu poruku. Možete skinuti stariju verziju ovog plugin-a sa naÅ¡eg sajta." + +#: sitemap.php:92 +#@ sitemap +msgid "Your PHP version is too old for XML Sitemaps." +msgstr "PHP verzija koju koristite je previÅ¡e stara za XML sitemap." + +#: sitemap.php:92 +#, php-format +#@ sitemap +msgid "Unfortunately this release of Google XML Sitemaps requires at least PHP %4$s. You are using PHP %2$s, which is out-dated and insecure. Please ask your web host to update your PHP installation or go to active plugins and deactivate the Google XML Sitemaps plugin to hide this message. You can download an older version of this plugin from the plugin website." +msgstr "nažalost ova verzija Google XML Sitemap-a zahteva najmanje verziju PHP %4$s. Vi koristite PHP %2$s, koji je zastareo i nesiguran. Zamolite vaÅ¡ hosting da ažuriraju verziju PHP instalacije ili idite na aktivne plugin-ove i deaktivirajte Google XML Sitemap plugin da bi ste sakrili ovu poruku. Možete skinuti straiju verziju ovog plugin-a sa naÅ¡eg sajta." + +#. translators: plugin header field 'Name' +#: sitemap.php:0 +#@ sitemap +msgid "Google XML Sitemaps" +msgstr "" + +#. translators: plugin header field 'PluginURI' +#: sitemap.php:0 +#@ sitemap +msgid "http://www.arnebrachhold.de/redir/sitemap-home/" +msgstr "" + +#. translators: plugin header field 'Description' +#: sitemap.php:0 +#@ sitemap +msgid "This plugin will generate a special XML sitemap which will help search engines like Google, Yahoo, Bing and Ask.com to better index your blog." +msgstr "" + +#. translators: plugin header field 'Author' +#: sitemap.php:0 +#@ sitemap +msgid "Arne Brachhold" +msgstr "" + +#. translators: plugin header field 'AuthorURI' +#: sitemap.php:0 +#@ sitemap +msgid "http://www.arnebrachhold.de/" +msgstr "" + +#. translators: plugin header field 'Version' +#: sitemap.php:0 +#@ sitemap +msgid "4.0beta9" +msgstr "" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sv_SE.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sv_SE.mo new file mode 100644 index 0000000..aabe565 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sv_SE.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sv_SE.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sv_SE.po new file mode 100644 index 0000000..0094df5 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-sv_SE.po @@ -0,0 +1,322 @@ +msgid "" +msgstr "" +"Project-Id-Version: Google Sitemap Generator Swedish Translation 1.0\n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2008-01-08 12:16+0100\n" +"Last-Translator: Markus \n" +"Language-Team: Tobias Bergius \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=iso-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Swedish\n" +"X-Poedit-Country: SWEDEN\n" +"X-Poedit-SourceCharset: iso-8859-1\n" + +#: sitemap.php:375 +msgid "always" +msgstr "alltid" + +msgid "hourly" +msgstr "varje timme" + +msgid "daily" +msgstr "dagligen" + +msgid "weekly" +msgstr "varje vecka" + +msgid "monthly" +msgstr "månatligen" + +msgid "yearly" +msgstr "Årligen" + +msgid "never" +msgstr "aldrig" + +msgid "Detected Path" +msgstr "Funnen sökväg" + +msgid "Example" +msgstr "Exempel" + +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Absolut eller relativ sökväg till sajtkartan, inklusive namn." + +msgid "Complete URL to the sitemap file, including name." +msgstr "Komplett URL till sajtkartan, inklusive namn." + +msgid "Automatic location" +msgstr "Automatisk sökväg" + +msgid "Manual location" +msgstr "Manuell sökväg" + +msgid "OR" +msgstr "eller" + +msgid "Location of your sitemap file" +msgstr "Sökväg till din sajtkarta" + +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Om din blogg är i en underkatalog och du vill lägga till sidor som inte är i blogg-katalogen, eller under, måste du placera din sajtkarta i root-katalogen (se "Sökväg till din sajtkarta" på den här sidan)!" + +#: sitemap.php:512 +msgid "Configuration updated" +msgstr "Konfiguration uppdaterad" + +#: sitemap.php:513 +msgid "Error" +msgstr "Fel" + +#: sitemap.php:521 +msgid "A new page was added. Click on "Save page changes" to save your changes." +msgstr "En ny sida tillagd. Klicka på "Spara ändringar" för att spara." + +#: sitemap.php:527 +msgid "Pages saved" +msgstr "Sidor sparade" + +#: sitemap.php:528 +msgid "Error while saving pages" +msgstr "Fel vid sparande av sida" + +#: sitemap.php:539 +msgid "The page was deleted. Click on "Save page changes" to save your changes." +msgstr "Sidan borttagen. Klicka på "Spara ändringar" för att spara." + +#: sitemap.php:542 +msgid "You changes have been cleared." +msgstr "Dina ändringar har rensats." + +#: sitemap.php:555 +msgid "Sitemap Generator" +msgstr "Sitemap Generator" + +#: sitemap.php:558 +msgid "Manual rebuild" +msgstr "Manuell återskapning" + +#: sitemap.php:559 +msgid "If you want to build the sitemap without editing a post, click on here!" +msgstr "Om du vill skapa sajtkartan utan att redigera en artikel, klicka här!" + +#: sitemap.php:560 +msgid "Rebuild Sitemap" +msgstr "Återskapa sajtkarta" + +#: sitemap.php:564 +msgid "Additional pages" +msgstr "Ytterligare sidor" + +#: sitemap.php:566 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Här kan du lägga till URL:er i sajtkartan, som inte tillhör Wordpress.
        Till exempel, om din domän är www.foo.com och din blogg finns på www.foo.com/blogg, vill du nog lägga till din startsida på www.foo.com." + +#: sitemap.php:568 +msgid "URL to the page" +msgstr "URL till sidan" + +#: sitemap.php:569 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Ange URL till sidan. Exempel: http://www.foo.com/index.html eller www.foo.com/home" + +#: sitemap.php:571 +msgid "Priority" +msgstr "Prioritet" + +#: sitemap.php:572 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Välj prioritet relativt till de andra sidorna. Till exempel, din startsida kanske bör ha högre prioritet än dina undersidor." + +#: sitemap.php:574 +msgid "Last Changed" +msgstr "Senast ändrad" + +#: sitemap.php:575 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Ändra datum för senaste ändringar enligt ÅÅÅÅ-MM-DD (2005-12-31 t.ex.) (valfritt)." + +#: sitemap.php:583 +msgid "Change Frequency" +msgstr "Ändra frekvens" + +#: sitemap.php:585 +msgid "#" +msgstr "#" + +#: sitemap.php:609 +msgid "No pages defined." +msgstr "Inga sidor tillagda." + +#: sitemap.php:616 +msgid "Add new page" +msgstr "Lägg till sida" + +# sitemap.php:617: +#: sitemap.php:617 +msgid "Save page changes" +msgstr "Spara ändringar" + +# sitemap.php:618: +#: sitemap.php:618 +msgid "Undo all page changes" +msgstr "Ångra alla ändringar" + +# sitemap.php:621: +#: sitemap.php:621 +msgid "Delete marked page" +msgstr "Ta bort markerad sida" + +#: sitemap.php:627 +msgid "Basic Options" +msgstr "Generella ändringar" + +#: sitemap.php:632 +msgid "Enable automatic priority calculation for posts based on comment count" +msgstr "Aktivera automatisk prioritering för artiklar, baserat på antal kommentarer" + +#: sitemap.php:638 +msgid "Write debug comments" +msgstr "Skriv debuggkommentarer" + +#: sitemap.php:643 +msgid "Filename of the sitemap file" +msgstr "Filnamn på sajtkartan" + +#: sitemap.php:650 +msgid "Write a normal XML file (your filename)" +msgstr "Skapa en vanlig XML-fil (ditt filnamn)" + +#: sitemap.php:652 +msgid "Detected URL" +msgstr "Funnen URL" + +#: sitemap.php:657 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Skapa en gzippad fil (filnamn + .gz)" + +#: sitemap.php:664 +msgid "Auto-Ping Google Sitemaps" +msgstr "Auto-pinga Google Sitemaps" + +#: sitemap.php:665 +msgid "This option will automatically tell Google about changes." +msgstr "Det här gör att Google automatiskt notifieras om uppdateringar" + +#: sitemap.php:672 +msgid "Includings" +msgstr "Inkluderingar" + +#: sitemap.php:677 +msgid "Include homepage" +msgstr "Inkludera startsida" + +#: sitemap.php:683 +msgid "Include posts" +msgstr "Inkludera artiklar" + +#: sitemap.php:689 +msgid "Include static pages" +msgstr "Inkludera statiska sidor" + +#: sitemap.php:695 +msgid "Include categories" +msgstr "Inkludera kategorier" + +#: sitemap.php:701 +msgid "Include archives" +msgstr "Inkluder arkiv" + +#: sitemap.php:708 +msgid "Change frequencies" +msgstr "Ändra frekvenser" + +#: sitemap.php:709 +msgid "Note" +msgstr "Observera" + +#: sitemap.php:710 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Den här inställningen ska ses som en ledtråd och inte ett kommando. Även om sökmotorerna lägger märke till den här informationen, så kan de indexera sidor markerade \"per timme\" mer sällan än det. Och dom kan indexera sidor markerade \"årligen\" oftare än så. Det är också vanligt att sökmotorer regelbundet kontrollerar sidor markerade \"aldrig\", så att de kan hantera oväntade händelser." + +#: sitemap.php:715 +msgid "Homepage" +msgstr "Startsida" + +#: sitemap.php:721 +msgid "Posts" +msgstr "Artiklar" + +#: sitemap.php:727 +msgid "Static pages" +msgstr "Statiska sidor" + +#: sitemap.php:733 +msgid "Categories" +msgstr "Kategorier" + +#: sitemap.php:739 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Aktuellt arkiv för denna månad (borde vara samma som din startsida)" + +#: sitemap.php:745 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Äldre arkiv (ändras bara om du ändrar en äldre artikel)" + +#: sitemap.php:752 +msgid "Priorities" +msgstr "Prioriteringar" + +#: sitemap.php:763 +msgid "Posts (If auto calculation is disabled)" +msgstr "Artiklar (om autoprioritering är avaktiverat)" + +#: sitemap.php:769 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Minsta artikeprioritet (även om autoprioritering är aktiverat)" + +#: sitemap.php:787 +msgid "Archives" +msgstr "Arkiv" + +#: sitemap.php:793 +msgid "Informations and support" +msgstr "Information och support" + +#: sitemap.php:794 +msgid "Check %s for updates and comment there if you have any problems / questions / suggestions." +msgstr "Kontrollera %s efter uppdateringar och kommentera om du har några problem, frågor eller förslag." + +#: sitemap.php:797 +msgid "Update options" +msgstr "Uppdatera inställningar" + +#: sitemap.php:1033 +msgid "URL:" +msgstr "URL:" + +#: sitemap.php:1034 +msgid "Path:" +msgstr "Sökväg:" + +#: sitemap.php:1037 +msgid "Could not write into %s" +msgstr "Kan inte skriva till %s" + +#: sitemap.php:1048 +msgid "Successfully built sitemap file:" +msgstr "Sajtkarta skapad:" + +#: sitemap.php:1048 +msgid "Successfully built gzipped sitemap file:" +msgstr "Gzippad sajtkarta skapad:" + +#: sitemap.php:1062 +msgid "Could not ping to Google at %s" +msgstr "Kan inte pinga Google på %s" + +#: sitemap.php:1064 +msgid "Successfully pinged Google at %s" +msgstr "Google pingad på %s" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-tr_TR.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-tr_TR.mo new file mode 100644 index 0000000..2065950 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-tr_TR.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-tr_TR.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-tr_TR.po new file mode 100644 index 0000000..fe75997 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-tr_TR.po @@ -0,0 +1,913 @@ +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-06-07 01:15+0100\n" +"PO-Revision-Date: 2009-06-08 17:31+0200\n" +"Last-Translator: Baris Unver \n" +"Language-Team: Stefano Aglietti \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Italian\n" +"X-Poedit-Country: ITALY\n" +"X-Poedit-SourceCharset: utf-8\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:642 +msgid "Comment Count" +msgstr "Yorum Sayımı" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:654 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "ÖnceliÄŸi belirlemek için yazıya yapılmış yorum sayısını kullan" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:714 +msgid "Comment Average" +msgstr "Yorum Ortalaması" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:726 +msgid "Uses the average comment count to calculate the priority" +msgstr "ÖnceliÄŸi hesaplamak için yazıların ortalama yorum sayısını kullanır" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:789 +msgid "Popularity Contest" +msgstr "Popularity Contest" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:801 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "Alex King tarafından yaratılmış Popularity Contest Eklentisi ile uyumlu olarak çalışır, öncelikleri Popularity Contest'in raporlarına göre hesaplar. Ayarlar için buraya, en popüler yazılar içinse buraya tıklayın." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1118 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1187 +msgid "Always" +msgstr "Her zaman" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1119 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1188 +msgid "Hourly" +msgstr "Saatte bir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1120 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1189 +msgid "Daily" +msgstr "Günde bir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1190 +msgid "Weekly" +msgstr "Haftada bir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1122 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1191 +msgid "Monthly" +msgstr "Ayda bir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1123 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1192 +msgid "Yearly" +msgstr "Yılda bir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1193 +msgid "Never" +msgstr "Hiçbir zaman" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "Bağışınız için çok teÅŸekkürler. Bu eklenti üzerinde çalışmam ve destek sunabilmem için yardım saÄŸlamış oldunuz!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Hide this notice" +msgstr "Bu bildiriyi sakla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2606 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "" +"Bu eklentiyi kullandığınız için teÅŸekkürler! Bu eklentiyi bir aydan daha uzun süredir kullanıyorsunuz. EÄŸer eklenti sizin iÅŸinize yaradıysa ve sevdiyseniz, sizce bu en azından bir dolar etmez mi? Yapılan bağışlar, bu ücretsiz eklentiyi geliÅŸtirmeye devam etmemi ve eklenti hakkında destek sunmamı saÄŸlıyor!\n" +"Tabii canım, ne demek!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2606 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +msgid "No thanks, please don't bug me anymore!" +msgstr "Yok teÅŸekkürler, lütfen beni bir daha rahatsız etme!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:119 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "Site haritanız ÅŸu anda yenileniyor. Blog'unuzun büyüklüğüne göre bu iÅŸlem biraz zaman alabilir!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:121 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "Site haritanız %s saniye içinde yenilenecek. Blog'unuzun büyüklüğüne göre bu iÅŸlem biraz zaman alabilir!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:146 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:453 +msgid "XML Sitemap Generator for WordPress" +msgstr "Wordpress için XML Site Haritası OluÅŸturucusu" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:298 +msgid "Configuration updated" +msgstr "Ayarlar kaydedildi" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:299 +msgid "Error while saving options" +msgstr "Seçenekler kaydedilirken hata oluÅŸtu" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:301 +msgid "Pages saved" +msgstr "Sayfalar kaydedildi" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:302 +msgid "Error while saving pages" +msgstr "Sayfalar kaydedilirken hata oluÅŸtu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:309 +msgid "The default configuration was restored." +msgstr "Varsayılan seçenekler yüklendi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:466 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "%1$s eklentisinin yeni bir sürümü var. %3$s sürümünü buradan indirin." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:468 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "%1$s eklentisinin yeni bir sürümü var. %3$s sürümünü buradan indirin. bu eklenti için otomatik güncelleme mümkün deÄŸil." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:470 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "%1$s eklentisinin yeni bir sürümü var. %3$s sürümünü buradan indirin. veya otomatik güncelleyin." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:493 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:510 +msgid "open" +msgstr "açmak" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:494 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:511 +msgid "close" +msgstr "kapamak" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:495 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:512 +msgid "click-down and drag to move this box" +msgstr "kutuyu taşımak için tıklayıp sürükleyin" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:496 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:513 +msgid "click to %toggle% this box" +msgstr "kutuyu %toggle% için tıklayın" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:497 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:514 +msgid "use the arrow keys to move this box" +msgstr "bu kutuyu taşımak için yön tuÅŸlarını kullanın" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:498 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:515 +msgid ", or press the enter key to %toggle% it" +msgstr "%toggle% için , veya enter tuÅŸuna basın" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +msgid "About this Plugin:" +msgstr "Bu Eklenti Hakkında:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:534 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:141 +msgid "Plugin Homepage" +msgstr "Eklenti Anasayfası" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:535 +msgid "Suggest a Feature" +msgstr "Bir Özellik Öner" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:536 +msgid "Notify List" +msgstr "Bildiri listesi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:537 +msgid "Support Forum" +msgstr "Destek Forumu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:538 +msgid "Report a Bug" +msgstr "Bir Hata Raporla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:540 +msgid "Donate with PayPal" +msgstr "PayPal ile Bağış Yap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:541 +msgid "My Amazon Wish List" +msgstr "Amazon Wish List'im" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:542 +msgid "translator_name" +msgstr "Eklenti Çevirmeni: Barış Ünver" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:542 +msgid "translator_url" +msgstr "http://beyn.org" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:545 +msgid "Sitemap Resources:" +msgstr "Site Haritası Kaynakları:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:546 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:552 +msgid "Webmaster Tools" +msgstr "Webmaster Araçları" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:547 +msgid "Webmaster Blog" +msgstr "Webmaster Blog'u" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:549 +msgid "Site Explorer" +msgstr "Site Explorer" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:550 +msgid "Search Blog" +msgstr "Search Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:553 +msgid "Webmaster Center Blog" +msgstr "Webmaster Merkezi Blog'u" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:555 +msgid "Sitemaps Protocol" +msgstr "Site Haritası Protokolü" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:556 +msgid "Official Sitemaps FAQ" +msgstr "Resmi Sitemap SSS'si" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:557 +msgid "My Sitemaps FAQ" +msgstr "Bu Eklentinin SSS'si" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:560 +msgid "Recent Donations:" +msgstr "Son Bağışlar:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:564 +msgid "List of the donors" +msgstr "Bağış Yapanların Listesi:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:566 +msgid "Hide this list" +msgstr "Bu listeyi sakla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:569 +msgid "Thanks for your support!" +msgstr "DesteÄŸiniz için teÅŸekkürler!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:587 +msgid "Status" +msgstr "Durum" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:595 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Site haritanız henüz oluÅŸturulmamış. OluÅŸturmak için buraya tıklayın." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:601 +msgid "Your sitemap was last built on %date%." +msgstr "Site haritanız en son %date% tarihinde oluÅŸturulmuÅŸ." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:603 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreDaha fazla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:610 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "Sıkıştırılmış site haritanız" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:612 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreDaha fazla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:618 +msgid "Google was successfully notified about changes." +msgstr "Google baÅŸarıyla bilgilendirildi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:621 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Google'ın bilgilendirilmesi %time% saniye sürdü, kurulum süresini düşürmek için bu seçeneÄŸi kaldırabilirsiniz" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2970 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:624 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "Google bilgilendirilirken hata oluÅŸtu. Hatayı göster" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:630 +msgid "YAHOO was successfully notified about changes." +msgstr "Yahoo! baÅŸarıyla bilgilendirildi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:633 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Yahoo!'nun bilgilendirilmesi %time% saniye sürdü, kurulum süresini düşürmek için bu seçeneÄŸi kaldırabilirsiniz" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2982 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:636 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Yahoo! bilgilendirilirken hata oluÅŸtu. Hatayı göster" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:642 +msgid "Bing was successfully notified about changes." +msgstr "Bing baÅŸarıyla bilgilendirildi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:645 +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "Bing'in bilgilendirilmesi %time% saniye sürdü, kurulum süresini düşürmek için bu seçeneÄŸi kaldırabilirsiniz" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2970 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:648 +#, php-format +msgid "There was a problem while notifying Bing. View result" +msgstr "Bing bilgilendirilirken hata oluÅŸtu. Hatayı göster" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:654 +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com baÅŸarıyla bilgilendirildi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:657 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Ask.com'un bilgilendirilmesi %time% saniye sürdü, kurulum süresini düşürmek için bu seçeneÄŸi kaldırabilirsiniz" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2994 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:660 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Ask.com bilgilendirilirken hata oluÅŸtu. Hatayı göster" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:668 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "Kurulum toplam %time% saniye sürdü ve %memory% MB bellek kullandı." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:670 +msgid "The building process took about %time% seconds to complete." +msgstr "Kurulum toplam %time% saniye sürdü." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:674 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "Site haritanızın içeriÄŸi önceki güncellemeyle aynı olduÄŸundan dolayı herhangi bir güncelleme yapılmadı ve herhangi bir arama motoru ping'lenmedi." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:682 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "Kurulum iÅŸlemi hala aktif olabilir! Bu sayfayı birkaç saniye sonra yenileyip bir ÅŸeyin deÄŸiÅŸip deÄŸiÅŸmediÄŸini kontrol edin." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:685 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "Son güncelleme daha bitmedi! Kullanılan bellek miktarını yükseltebilir veya kurulum süresini uzatabilirsiniz. Daha fazla" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:687 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "BetiÄŸin son bilinen bellek kullanımı %memused%MB oldu, sunucunuzun saÄŸladığı bellek sınırı ise %memlimit%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:691 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "BetiÄŸin son çalıştırılması %timeused% saniye sürdü, sunucunuzun saÄŸladığı süre sınırı ise %timelimit% saniye." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:695 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Betik, %lastpost% numaralı yazı civarında (+/- 100) durdu." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:698 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "EÄŸer sunucunuzda veya blog'unuzda bir deÄŸiÅŸiklik yaptıysanız, site haritanızı güncellemek isteyebilirsiniz." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:700 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "EÄŸer bir sorunla (veya sorunlarla) karşılaşırsanız, hata ayıklama kipini kullanıp sorun(lar) hakkında bilgi sahibi olabilirsiniz." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:707 +msgid "Basic Options" +msgstr "Temel Ayarlar" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:709 +msgid "Sitemap files:" +msgstr "Site haritası dosyaları:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:709 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Learn more" +msgstr "Daha fazla" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:714 +msgid "Write a normal XML file (your filename)" +msgstr "Normal bir XML dosyası oluÅŸtur (dosya isminiz.xml)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:720 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Gzip ile sıkıştırılmış bir dosya oluÅŸtur (dosya isminiz.xml.gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +msgid "Building mode:" +msgstr "Kurma kipi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:729 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Blog'un içeriÄŸi deÄŸiÅŸtiÄŸinde site haritasını güncelle" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:736 +msgid "Enable manual sitemap building via GET Request" +msgstr "GET talebiyle site haritasının elle kurulumunu etkinleÅŸtir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:740 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "" +"EÄŸer blog'unuzu güncellemek için Wordpress API'sini kullanmayan üçüncü parti bir yazılım kullanıyorsanız bu araç iÅŸinize yarayacaktır. BaÅŸlatmak için aÅŸağıdaki baÄŸlantıyı kullanın:\n" +"%1\n" +"Lütfen site haritasının baÅŸarıyla kurulup kurulmadığını kontrol etmek için raporlara bakınız." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +msgid "Update notification:" +msgstr "Güncelleme bildirisi:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:748 +msgid "Notify Google about updates of your Blog" +msgstr "Blog'unuzun güncellenimini Google'a bildir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:749 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Kayıt gerektirmez, ama Google Webmaster Tools'a katılarak crawl istatistiklerini görebilirsiniz." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:753 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "Blog'unuzun güncelleniÅŸini Bing'e bildir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:754 +#, php-format +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "Kayıt gerektirmez, ama Bing Webmaster Tools'a katılarak taranma istatistiklerini görebilirsiniz." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:758 +msgid "Notify Ask.com about updates of your Blog" +msgstr "Blog'unuzun güncellenimini Ask.com'a bildir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:759 +msgid "No registration required." +msgstr "Kayıt gerektirmez." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:763 +msgid "Notify YAHOO about updates of your Blog" +msgstr "Blog'unuzun güncellenimini Yahoo!'ya bildir" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:764 +msgid "Your Application ID:" +msgstr "Uygulama ID'niz:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:765 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "Böyle bir anahtarınız yok mu? Buradan bir tane isteyin! %s2" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:770 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Sanal robots.txt dosyasına site haritası URL'ini ekle." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:774 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "WordPress'in oluÅŸturduÄŸu sanal robots.txt dosyası kullanılacaktır; gerçek bir robots.txt dosyası kök dizinde BULUNMAMALIDIR!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Advanced options:" +msgstr "GeliÅŸmiÅŸ seçenekler:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Limit the number of posts in the sitemap:" +msgstr "Site haritasındaki yazı sayısını sınırlandır:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Newer posts will be included first" +msgstr "Yeni yazılar site haritasında ilk sıraya yerleÅŸtirilsin" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "Try to increase the memory limit to:" +msgstr "Kullanılacak bellek sınırını ÅŸuna yükseltmeyi dene:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "e.g. \"4M\", \"16M\"" +msgstr "(örn. \"4M\", \"16M\")" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "Try to increase the execution time limit to:" +msgstr "İşlemi gerçekleÅŸtirmek için gereken zaman sınırını ÅŸuna yükseltmeyi dene:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "saniye olarak belirtin (örn. \"60\") (sınırsız için \"0\" kullanın)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:790 +msgid "Include a XSLT stylesheet:" +msgstr "Bir XSLT Sayfa Yönergesi (Stylesheet) Kullan:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Full or relative URL to your .xsl file" +msgstr ".xsl dosyanızın tam veya bağıl yolu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Use default" +msgstr "Varsayılanı kullan" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:797 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "MySQL standart kipini etkinleÅŸtirin. Yalnızca MySQL hataları alıyorsanız bunu kullanın, çok fazla belleÄŸe ihtiyaç duyar!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:798 +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "Daha hızlı MySQL eriÅŸimi için WordPress sürümünüzü en azından 2.2'ye yükseltin." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:805 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Site haritasını bir arkaplan iÅŸleminde oluÅŸtur (Bir yazıyı kaydederken beklemek zorunda kalmazsınız)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:806 +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "Haritanın arkaplanda oluÅŸturulabilmesi için WordPress sürümünüzü en azından 2.1'e yükseltin." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:813 +msgid "Additional pages" +msgstr "Ek sayfalar" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:816 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Burada blog'unuza ait olmayan sayfaları site haritasında yer alacak şekilde ekleyebilirsiniz.
        ÖrneÄŸin, eÄŸer sayfanız www.foo.com ise ve blog'unuz www.foo.com/blog ise, anasayfanız olan www.foo.com adresini de eklemek isteyebilirsiniz." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:818 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:997 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1020 +msgid "Note" +msgstr "Not" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:819 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "EÄŸer blog'unuz bir alt klasördeyse ve blog'da OLMAYAN sayfalar eklemek istiyorsanız, site haritası dosyanızı KESİNLİKLE kök klasöre koymanız gereklidir (Bu sayfadaki "Site haritanızın konumu" bölümüne bakın)!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:821 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:860 +msgid "URL to the page" +msgstr "Sayfanın URL'i" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Sayfanın URL'ini ekleyin. Örnekler: http://www.foo.com/index.html veya www.foo.com/home " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:824 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:861 +msgid "Priority" +msgstr "Öncelik" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:825 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Sayfanın, diÄŸer sayfalara göre alacağı önceliÄŸi belirleyin. ÖrneÄŸin, anasayfanızın daha yüksek bir öncelik alması gerekebilir." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:827 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "Last Changed" +msgstr "Son Düzenlenen" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:828 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Son deÄŸiÅŸikliÄŸin tarihini YYYY-AA-GG olarak yazın (örneÄŸin 2005-12-31) (isteÄŸe baÄŸlı)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:862 +msgid "Change Frequency" +msgstr "Sıklık DeÄŸiÅŸtir" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:864 +msgid "#" +msgstr "#" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:869 +msgid "No pages defined." +msgstr "Hiç sayfa tanımlanmamış." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:874 +msgid "Add new page" +msgstr "Yeni sayfa ekle" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:879 +msgid "Post Priority" +msgstr "Yazı önceliÄŸi" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:881 +msgid "Please select how the priority of each post should be calculated:" +msgstr "Lütfen yazıların önceliklerinin nasıl hesaplanmasını istediÄŸinizi seçin:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:883 +msgid "Do not use automatic priority calculation" +msgstr "Otomatik öncelik hesaplamasını kullanma" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:883 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr ""Öncelikler"de tanımlanmış tüm yazılar aynı önceliÄŸe sahip olur." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:894 +msgid "Location of your sitemap file" +msgstr "Site haritanızın konumu" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:897 +msgid "Automatic detection" +msgstr "Otomatik tespit" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:901 +msgid "Filename of the sitemap file" +msgstr "Site haritası dosyasının ismi" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:904 +msgid "Detected Path" +msgstr "Bulunan Yol" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:904 +msgid "Detected URL" +msgstr "Bulunan URL" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:909 +msgid "Custom location" +msgstr "Özel konum" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:913 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "Site haritasının tam veya bağıl yolu (ismi dahil)." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:915 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:924 +msgid "Example" +msgstr "Örnek" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:922 +msgid "Complete URL to the sitemap file, including name." +msgstr "Site haritasının tam URL'i (ismi dahil)." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:935 +msgid "Sitemap Content" +msgstr "Site Haritas İçeriÄŸi" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:941 +msgid "Include homepage" +msgstr "Anasayfayı dahil et" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:947 +msgid "Include posts" +msgstr "Blog yazılarını dahil et" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:1013 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:953 +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "Çoklu sayfalardan aÅŸağıdakileri dahil et (Bellek kullanımını ve site haritası kurulum süresini uzatır!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:959 +msgid "Include static pages" +msgstr "Sabit sayfaları dahil et" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:965 +msgid "Include categories" +msgstr "Kategorileri dahil et" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:971 +msgid "Include archives" +msgstr "ArÅŸivleri dahil et" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:978 +msgid "Include tag pages" +msgstr "Etiket sayfalarını dahil et" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:985 +msgid "Include author pages" +msgstr "Yazar sayfalarını dahil et" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:993 +msgid "Excluded items" +msgstr "Hariç tutulacaklar" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:995 +msgid "Excluded categories" +msgstr "Hariç tutulan kategoriler" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:997 +msgid "Using this feature will increase build time and memory usage!" +msgstr "Bu özelliÄŸi kullanmak bellek kullanımını artırır ve harita oluÅŸturma süresini uzatır!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1004 +#, php-format +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "Bu özellik WordPress 2.5.1 sürümünü gerektirir, sizinki %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1007 +msgid "Exclude posts" +msgstr "Blog yazılarını hariç tut" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +msgid "Exclude the following posts or pages:" +msgstr "Åžu yazı veya sayfaları hariç tut:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +msgid "List of IDs, separated by comma" +msgstr "ID listesi, virgülle ayırın:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1011 +msgid "Child posts won't be excluded automatically!" +msgstr "Bu yazının altındaki iç yazılar otomatik olarak dahil edilmeyecektir!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1017 +msgid "Change frequencies" +msgstr "Sıklıkları deÄŸiÅŸtir" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1021 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Lütfen bu etiketin bir ipucu olduÄŸuna, bir komut olmadığına dikkat edin. Her ne kadar arama motoru robotları bu bilgiyi karar verirken göz önünde bulunduruyor olsa da; "her saat" olarak iÅŸaretlenen sayfaları da daha az sıklıkla tarayabilir, "her yıl" olarak iÅŸaretlenen sayfaları da daha sık tarayabilir. Hatta robotlar bazen "hiçbir zaman" olarak iÅŸaretlenmiÅŸ sayfaları da, beklenmedik deÄŸiÅŸiklikleri ele alabilmek için tarayabilirler." + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1084 +msgid "Homepage" +msgstr "Anasayfa" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1033 +msgid "Posts" +msgstr "Blog yazıları" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1039 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1102 +msgid "Static pages" +msgstr "Sabit sayfalar" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1045 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1108 +msgid "Categories" +msgstr "Kategoriler" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1051 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Bu ayın arÅŸivi (anasayfanızla aynı olacaktır)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1057 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Daha eski arÅŸivler (Yalnızca eski bir blog yazısını düzenlerseniz güncellenir)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1121 +msgid "Tag pages" +msgstr "Etiket sayfaları" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1128 +msgid "Author pages" +msgstr "Yazar sayfaları" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1079 +msgid "Priorities" +msgstr "Öncelikler" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1090 +msgid "Posts (If auto calculation is disabled)" +msgstr "Blog yazıları (yalnızca otomatik hesaplama devre dışıysa)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1096 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "En düşük blog yazısı önceliÄŸi (otomatik hesaplama devre dışı olsa bile)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1114 +msgid "Archives" +msgstr "ArÅŸivler" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1139 +msgid "Update options" +msgstr "Seçenekleri güncelle" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1140 +msgid "Reset options" +msgstr "Seçenekleri sıfırla" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:84 +msgid "XML-Sitemap Generator" +msgstr "XML Site Haritası OluÅŸturucusu" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:84 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:142 +msgid "Sitemap FAQ" +msgstr "Bu Eklentinin SSS'si" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-uk_UA.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-uk_UA.mo new file mode 100644 index 0000000..389fc4e Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-uk_UA.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-uk_UA.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-uk_UA.po new file mode 100644 index 0000000..a2cfd92 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-uk_UA.po @@ -0,0 +1,1005 @@ +msgid "" +msgstr "" +"Project-Id-Version: Google XML Sitemaps v3.1.4\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: 2009-08-22 13:42+0300\n" +"Last-Translator: elenka \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Poedit-Language: Ukrainian\n" +"X-Poedit-Country: UKRAINE\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n" +"X-Poedit-Basepath: ../\n" +"X-Poedit-Bookmarks: \n" +"X-Poedit-SearchPath-0: .\n" +"X-Textdomain-Support: yes" + +#: sitemap-core.php:642 +#@ sitemap +msgid "Comment Count" +msgstr "Личільник коментарів" + +#: sitemap-core.php:654 +#@ sitemap +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "ВикориÑтовує кількіÑть коментарів до публікацій Ð´Ð»Ñ ÐºÐ°Ð»ÑŒÐºÑƒÐ»Ñції пріорітету" + +#: sitemap-core.php:714 +#@ sitemap +msgid "Comment Average" +msgstr "Коментарів Середнє" + +#: sitemap-core.php:726 +#@ sitemap +msgid "Uses the average comment count to calculate the priority" +msgstr "ВикориÑтовує кількіÑть коментарів у Ñередньому Ð´Ð»Ñ ÐºÐ°Ð»ÑŒÐºÑƒÐ»Ñції пріорітету" + +#: sitemap-core.php:789 +#@ sitemap +msgid "Popularity Contest" +msgstr "ÐšÐ¾Ð½ÐºÑƒÑ€Ñ ÐŸÐ¾Ð¿ÑƒÐ»ÑрноÑті" + +#: sitemap-core.php:801 +#, php-format +#@ sitemap +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "ВикориÑтовує активований Popularity Contest Plugin від Alex King< . Див. ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° ПопулÑрні Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ " + +#: sitemap-core.php:1187 +#@ sitemap +msgid "Always" +msgstr "Завжди" + +#: sitemap-core.php:1188 +#@ sitemap +msgid "Hourly" +msgstr "ЩочаÑу" + +#: sitemap-core.php:1189 +#@ sitemap +msgid "Daily" +msgstr "Щоденно" + +#: sitemap-core.php:1190 +#@ sitemap +msgid "Weekly" +msgstr "Щонедільно" + +#: sitemap-core.php:1191 +#@ sitemap +msgid "Monthly" +msgstr "ЩоміÑÑчно" + +#: sitemap-core.php:1192 +#@ sitemap +msgid "Yearly" +msgstr "Щорічно" + +#: sitemap-core.php:1193 +#@ sitemap +msgid "Never" +msgstr "Ðіколи" + +#: sitemap-ui.php:97 +#@ sitemap +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "ДÑкую вам дуже за ваше пожертвуваннÑ. Ви допомагаете мені підтримувати та розроблÑти цій плагін та інше вільне програмне забеÑпеченнÑ." + +#: sitemap-ui.php:97 +#@ sitemap +msgid "Hide this notice" +msgstr "Приховати це повідомленнÑ" + +#: sitemap-ui.php:103 +#, php-format +#@ sitemap +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "ДÑкую за викориÑÑ‚Ð°Ð½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ плагіна! Ви вÑтановили цей плагін більше міÑÑÑ†Ñ Ñ‚Ð¾Ð¼Ñƒ. Якщо він працює, Ñ– Ви задоволені результатами, чи не варто це щонайменше один долар? ÐŸÐ¾Ð¶ÐµÑ€Ñ‚Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð¿Ð¾Ð¼Ð°ÑŽÑ‚ÑŒ мені продовжити підтримку Ñ– розвиток цього безкоштовного програмного забезпеченнÑ! Звичайно, немає проблем! " + +#: sitemap-ui.php:103 +#@ sitemap +msgid "No thanks, please don't bug me anymore!" +msgstr "ÐÑ–, дÑкую, будь лаÑка, не турбуйте мене!" + +#: sitemap-ui.php:114 +#@ sitemap +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "Ваша мапа Ñайту наразі оновлюєтьÑÑ. Ð’ залежноÑті від розміру вашого блогу це може зайнÑти деÑкий чаÑ!" + +#: sitemap-ui.php:116 +#, php-format +#@ sitemap +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "Ваша мапа Ñайту буде оновлена за % S Ñекунд. Ð’ залежноÑті від розміру вашого блогу це може зайнÑти деÑкий чаÑ!" + +#: sitemap-ui.php:145 +#: sitemap-ui.php:448 +#@ sitemap +msgid "XML Sitemap Generator for WordPress" +msgstr "XML Генератор Мапи Ñайту Ð´Ð»Ñ WordPress" + +#: sitemap-ui.php:293 +#@ sitemap +msgid "Configuration updated" +msgstr "ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð°" + +#: sitemap-ui.php:294 +#@ sitemap +msgid "Error while saving options" +msgstr "Помилка при збереженні опцій" + +#: sitemap-ui.php:296 +#@ sitemap +msgid "Pages saved" +msgstr "Сторінка збережена" + +#: sitemap-ui.php:297 +#@ sitemap +msgid "Error while saving pages" +msgstr "Помилка при збереженні Ñторінок" + +#: sitemap-ui.php:304 +#@ sitemap +msgid "The default configuration was restored." +msgstr "ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð·Ð° замовчуваннÑм була відновлена." + +#: sitemap-ui.php:461 +#, php-format +#@ default +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "" + +#: sitemap-ui.php:463 +#, php-format +#@ default +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "" + +#: sitemap-ui.php:465 +#, php-format +#@ default +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "" + +#: sitemap-ui.php:488 +#: sitemap-ui.php:505 +msgid "open" +msgstr "" + +#: sitemap-ui.php:489 +#: sitemap-ui.php:506 +msgid "close" +msgstr "" + +#: sitemap-ui.php:490 +#: sitemap-ui.php:507 +msgid "click-down and drag to move this box" +msgstr "" + +#: sitemap-ui.php:491 +#: sitemap-ui.php:508 +#, php-format +msgid "click to %toggle% this box" +msgstr "" + +#: sitemap-ui.php:492 +#: sitemap-ui.php:509 +msgid "use the arrow keys to move this box" +msgstr "" + +#: sitemap-ui.php:493 +#: sitemap-ui.php:510 +#, php-format +msgid ", or press the enter key to %toggle% it" +msgstr "" + +#: sitemap-ui.php:528 +#@ sitemap +msgid "About this Plugin:" +msgstr "Про цей Плагін:" + +#: sitemap-ui.php:529 +#: sitemap.php:153 +#@ sitemap +msgid "Plugin Homepage" +msgstr "Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка Плагіну" + +#: sitemap-ui.php:530 +#@ sitemap +msgid "Suggest a Feature" +msgstr "Замовити Функціонал" + +#: sitemap-ui.php:531 +#@ sitemap +msgid "Notify List" +msgstr "ЛиÑÑ‚ Повідомленнь" + +#: sitemap-ui.php:532 +#@ sitemap +msgid "Support Forum" +msgstr "Форум Підтримки " + +#: sitemap-ui.php:533 +#@ sitemap +msgid "Report a Bug" +msgstr "Повідомити про помилку" + +#: sitemap-ui.php:535 +#@ sitemap +msgid "Donate with PayPal" +msgstr "Пожертвувати через PayPal" + +#: sitemap-ui.php:536 +#@ sitemap +msgid "My Amazon Wish List" +msgstr "Мій ліÑÑ‚ побажаннь на Amazon" + +#: sitemap-ui.php:537 +#@ sitemap +msgid "translator_name" +msgstr "Ð§ÐµÐ¼Ñ–Ñ ÐžÐ»ÐµÐ½Ð°" + +#: sitemap-ui.php:537 +#@ sitemap +msgid "translator_url" +msgstr "http://stereo-lisa.org.ua" + +#: sitemap-ui.php:540 +#@ sitemap +msgid "Sitemap Resources:" +msgstr "РеÑурÑи Мапи Ñайту" + +#: sitemap-ui.php:541 +#: sitemap-ui.php:547 +#@ sitemap +msgid "Webmaster Tools" +msgstr "ІнÑтрумент Веб-майÑтрів" + +#: sitemap-ui.php:542 +#@ sitemap +msgid "Webmaster Blog" +msgstr "Блог Веб-майÑтера" + +#: sitemap-ui.php:544 +#@ sitemap +msgid "Site Explorer" +msgstr "ПереглÑд Сайту" + +#: sitemap-ui.php:545 +#@ sitemap +msgid "Search Blog" +msgstr "Пошук Блога" + +#: sitemap-ui.php:548 +#@ sitemap +msgid "Webmaster Center Blog" +msgstr "Блог Центра Веб-майÑтрів" + +#: sitemap-ui.php:550 +#@ sitemap +msgid "Sitemaps Protocol" +msgstr "Протокол Sitemaps" + +#: sitemap-ui.php:551 +#@ sitemap +msgid "Official Sitemaps FAQ" +msgstr "Офіційний Sitemaps FAQ" + +#: sitemap-ui.php:552 +#@ sitemap +msgid "My Sitemaps FAQ" +msgstr "Мій Sitemaps FAQ" + +#: sitemap-ui.php:555 +#@ sitemap +msgid "Recent Donations:" +msgstr "ОÑтанні ПожертвуваннÑ" + +#: sitemap-ui.php:559 +#@ sitemap +msgid "List of the donors" +msgstr "Перелік СпонÑорів" + +#: sitemap-ui.php:561 +#@ sitemap +msgid "Hide this list" +msgstr "Сховати цей перелік" + +#: sitemap-ui.php:564 +#@ sitemap +msgid "Thanks for your support!" +msgstr "ДÑкую за вашу підтримку!" + +#: sitemap-ui.php:582 +#@ sitemap +msgid "Status" +msgstr "СтатуÑ" + +#: sitemap-ui.php:590 +#, php-format +#@ sitemap +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "Мапа Ñайту ще не була побудована. ÐатиÑніть тут , щоб побудувати Ñ—Ñ— в перший раз." + +#: sitemap-ui.php:596 +#, php-format +#@ sitemap +msgid "Your sitemap was last built on %date%." +msgstr "Ваша мапа Ñайту була в оÑтаннє побудована %date%." + +#: sitemap-ui.php:598 +#, php-format +#@ sitemap +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn moreДізнатиÑÑŒ більше" + +#: sitemap-ui.php:605 +#, php-format +#@ sitemap +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "Вашу (ÑтиÑнуту) мапу Ñайту минулого разу побудовано %date%." + +#: sitemap-ui.php:607 +#, php-format +#@ sitemap +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn moreДізнатиÑÑŒ більше" + +#: sitemap-ui.php:613 +#@ sitemap +msgid "Google was successfully notified about changes." +msgstr "Google був уÑпішно повідомлений про зміни." + +#: sitemap-ui.php:616 +#, php-format +#@ sitemap +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "Це займе %time% Ñекунд щоб повідомити Google, можливо, ви хочете вимкнути цю функцію Ð´Ð»Ñ ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу побудови." + +#: sitemap-ui.php:619 +#, php-format +#@ sitemap +msgid "There was a problem while notifying Google. View result" +msgstr "Виникла проблема при повідомленні Google. ДивитиÑÑŒ результат" + +#: sitemap-ui.php:625 +#@ sitemap +msgid "YAHOO was successfully notified about changes." +msgstr "YAHOO був уÑпішно повідомлений про зміни." + +#: sitemap-ui.php:628 +#, php-format +#@ sitemap +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "Це займе %time% Ñекунд щоб повідомити YAHOO, можливо, ви хочете вимкнути цю функцію Ð´Ð»Ñ ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу побудови." + +#: sitemap-ui.php:631 +#, php-format +#@ sitemap +msgid "There was a problem while notifying YAHOO. View result" +msgstr "Виникла проблема при повідомленні YAHOO. ДивитиÑÑŒ результат" + +#: sitemap-ui.php:637 +#@ sitemap +msgid "Bing was successfully notified about changes." +msgstr "Bing був уÑпішно повідомлений про зміни." + +#: sitemap-ui.php:640 +#, php-format +#@ sitemap +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "Це займе %time% Ñекунд щоб повідомити Bing, можливо, ви хочете вимкнути цю функцію Ð´Ð»Ñ ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу побудови." + +#: sitemap-ui.php:643 +#, php-format +#@ sitemap +msgid "There was a problem while notifying Bing. View result" +msgstr "Виникла проблема при повідомленні Bing. ДивитиÑÑŒ результат" + +#: sitemap-ui.php:649 +#@ sitemap +msgid "Ask.com was successfully notified about changes." +msgstr "Ask.com був уÑпішно повідомлений про зміни." + +#: sitemap-ui.php:652 +#, php-format +#@ sitemap +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "Це займе %time% Ñекунд щоб повідомити Ask.com, можливо, ви хочете вимкнути цю функцію Ð´Ð»Ñ ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу побудови." + +#: sitemap-ui.php:655 +#, php-format +#@ sitemap +msgid "There was a problem while notifying Ask.com. View result" +msgstr "Виникла проблема при повідомленні Ask.com. ДивитиÑÑŒ результат" + +#: sitemap-ui.php:663 +#, php-format +#@ sitemap +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "ÐŸÑ€Ð¾Ñ†ÐµÑ Ð¿Ð¾Ð±ÑƒÐ´Ð¾Ð²Ð¸ зайнÑв %time% Ñекунд Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ– викориÑтував %memory% MB пам'Ñті." + +#: sitemap-ui.php:665 +#, php-format +#@ sitemap +msgid "The building process took about %time% seconds to complete." +msgstr "ÐŸÑ€Ð¾Ñ†ÐµÑ Ð¿Ð¾Ð±ÑƒÐ´Ð¾Ð²Ð¸ зайнÑв близько %time% Ñекунд до завершеннÑ." + +#: sitemap-ui.php:669 +#@ sitemap +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "ЗміÑÑ‚ Вашогої мапи Ñайту не змінивÑÑ , оÑкільки оÑтанній раз, файли не було запиÑано, Ñ– не відбувÑÑ Ð¿Ñ–Ð½Ð³ пошукової ÑиÑтеми." + +#: sitemap-ui.php:677 +#@ sitemap +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "ÐŸÑ€Ð¾Ñ†ÐµÑ Ð¿Ð¾Ð±ÑƒÐ´Ð¾Ð²Ð¸ може бути ще активним! Перезавантажте Ñторінку через кілька Ñекунд, Ñ– перевірьте - чи відбулиÑÑŒ зміни." + +#: sitemap-ui.php:680 +#, php-format +#@ sitemap +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "ОÑтанній запуÑк не закінчивÑÑ! Можливо ви збільшите пам'Ñть або лімит чаÑу Ð´Ð»Ñ PHP Ñкриптів. ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ" + +#: sitemap-ui.php:682 +#, php-format +#@ sitemap +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "ОÑтаннє відоме викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті Ñценарієм було %memused%MB, межа Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ Ñервера Ñ” %memlimit%. " + +#: sitemap-ui.php:686 +#, php-format +#@ sitemap +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "ОÑтанній відомий Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñценарію був %timeused% Ñекунд, межа Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ Ñервера Ñ” %timelimit% Ñекунд. " + +#: sitemap-ui.php:690 +#, php-format +#@ sitemap +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "Сценарій зупинено Ð±Ñ–Ð»Ñ Ð¿ÑƒÐ±Ð»Ñ–ÐºÐ°Ñ†Ñ–Ñ— номер %lastpost% (+/- 100)" + +#: sitemap-ui.php:693 +#, php-format +#@ sitemap +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "Якщо ви змінювали Ñкі-небудь елементи на вашому Ñервері або блогі, потрібно відновити мапу Ñайту вручну." + +#: sitemap-ui.php:695 +#, php-format +#@ sitemap +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "Якщо у Ð²Ð°Ñ Ð²Ð¸Ð½Ð¸ÐºÐ½ÑƒÑ‚ÑŒ проблеми з процеÑом побудови можна викориÑтовувати відлагоджувальна функції , щоб одержати більш докладну інформацію." + +#: sitemap-ui.php:702 +#@ sitemap +msgid "Basic Options" +msgstr "Базові Опції" + +#: sitemap-ui.php:704 +#@ sitemap +msgid "Sitemap files:" +msgstr "Файли Мапи Ñайту" + +#: sitemap-ui.php:704 +#: sitemap-ui.php:719 +#: sitemap-ui.php:739 +#: sitemap-ui.php:772 +#@ sitemap +msgid "Learn more" +msgstr "ДізнатиÑÑŒ більше" + +#: sitemap-ui.php:709 +#@ sitemap +msgid "Write a normal XML file (your filename)" +msgstr "Запишіть нормальний XML файл (ваша назва файлу )" + +#: sitemap-ui.php:715 +#@ sitemap +msgid "Write a gzipped file (your filename + .gz)" +msgstr "Запишіть ÑтиÑнутий файл (ваша назва файлу + .gz)" + +#: sitemap-ui.php:719 +#@ sitemap +msgid "Building mode:" +msgstr "Режим побудови:" + +#: sitemap-ui.php:724 +#@ sitemap +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "Перебудуйте мапу Ñайту, Ñкщо ви змінили зміÑÑ‚ вашого блогу" + +#: sitemap-ui.php:731 +#@ sitemap +msgid "Enable manual sitemap building via GET Request" +msgstr "Включити ручну побудову мапи Ñайту через GET запит" + +#: sitemap-ui.php:735 +#, php-format +#@ sitemap +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "Це дозволить вам оновити ваш Ñайт, Ñкщо зовнішній інÑтрумент пиÑав у WordPress бази даних без викориÑÑ‚Ð°Ð½Ð½Ñ WordPress API. ВикориÑтовуйте наÑтупний URL, щоб розпочати цей процеÑ: %1 Будь лаÑка, перевірте логи вище, щоб побачити, Ñкщо мапа Ñайту була уÑпішно побудована." + +#: sitemap-ui.php:739 +#@ sitemap +msgid "Update notification:" +msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ оновленнÑ:" + +#: sitemap-ui.php:743 +#@ sitemap +msgid "Notify Google about updates of your Blog" +msgstr "Повідомити Google про Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð’Ð°ÑˆÐ¾Ð³Ð¾ блогу\n" + +#: sitemap-ui.php:744 +#, php-format +#@ sitemap +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "Ðе потрібна реєÑтраціÑ, але ви можете приєднатиÑÑ Ð´Ð¾ Google ІнÑтрументи Ð´Ð»Ñ Ð²ÐµÐ±-майÑтрів , щоб перевірити ÑтатиÑтику ÑкануваннÑ." + +#: sitemap-ui.php:748 +#@ sitemap +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "ПовідомлÑти Бінго (колишній MSN Live Search) про Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð’Ð°ÑˆÐ¾Ð³Ð¾ блогу" + +#: sitemap-ui.php:749 +#, php-format +#@ sitemap +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "Ðе потрібна реєÑтраціÑ, але ви можете приєднатиÑÑ Ð´Ð¾ Bing ІнÑтрументи Ð´Ð»Ñ Ð²ÐµÐ±-майÑтрів , щоб перевірити ÑтатиÑтику ÑкануваннÑ." + +#: sitemap-ui.php:753 +#@ sitemap +msgid "Notify Ask.com about updates of your Blog" +msgstr "Повідомити Ask.com про Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð’Ð°ÑˆÐ¾Ð³Ð¾ блогу" + +#: sitemap-ui.php:754 +#@ sitemap +msgid "No registration required." +msgstr "Ðе потрібна реєÑтраціÑ." + +#: sitemap-ui.php:758 +#@ sitemap +msgid "Notify YAHOO about updates of your Blog" +msgstr "Повідомити YAHOO про Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð’Ð°ÑˆÐ¾Ð³Ð¾ блогу" + +#: sitemap-ui.php:759 +#@ sitemap +msgid "Your Application ID:" +msgstr "Ваш идентифікатор :" + +#: sitemap-ui.php:760 +#, php-format +#@ sitemap +msgid "Don't you have such a key? Request one here! %s2" +msgstr "Ви не маєте такого ключа? Запитати його тут! %s2" + +#: sitemap-ui.php:765 +#@ sitemap +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "Додати URL файлу Sitemap в віртуальний файл robots.txt ." + +#: sitemap-ui.php:769 +#@ sitemap +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "ВикориÑтовуєтьÑÑ Ð²Ñ–Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð¸Ð¹ robots.txt Ñгенерований WordPress. Реального файлу robots.txt ÐЕ ПОВИÐÐО бути в каталозі блогу!" + +#: sitemap-ui.php:772 +#@ sitemap +msgid "Advanced options:" +msgstr "Додаткові опції:" + +#: sitemap-ui.php:775 +#@ sitemap +msgid "Limit the number of posts in the sitemap:" +msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÑ–Ð»ÑŒÐºÐ¾Ñті публікацій в Sitemap:" + +#: sitemap-ui.php:775 +#@ sitemap +msgid "Newer posts will be included first" +msgstr "Ðові Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¼Ð°ÑŽÑ‚ÑŒ бути включеними першими" + +#: sitemap-ui.php:778 +#@ sitemap +msgid "Try to increase the memory limit to:" +msgstr "Спробуйте збільшити ліміт пам'Ñті:" + +#: sitemap-ui.php:778 +#@ sitemap +msgid "e.g. \"4M\", \"16M\"" +msgstr "наприклад \"4M\", \"16M\"" + +#: sitemap-ui.php:781 +#@ sitemap +msgid "Try to increase the execution time limit to:" +msgstr "Спробуйте збільшити ліміт чаÑу Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð´Ð¾:" + +#: sitemap-ui.php:781 +#@ sitemap +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "у Ñекундах, наприклад \"60\" або \"0\" Ð´Ð»Ñ Ð½ÐµÐ¾Ð±Ð¼ÐµÐ¶Ð½Ð¾Ð³Ð¾" + +#: sitemap-ui.php:785 +#@ sitemap +msgid "Include a XSLT stylesheet:" +msgstr "Додати таблиці Ñтилів XSLT:" + +#: sitemap-ui.php:786 +#@ sitemap +msgid "Full or relative URL to your .xsl file" +msgstr "Повний або відноÑний URL до вашого. XSL-файлу" + +#: sitemap-ui.php:786 +#@ sitemap +msgid "Use default" +msgstr "ВикориÑтовувати параметри за замовчуваннÑм" + +#: sitemap-ui.php:792 +#@ sitemap +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "Увімкнути Ñтандартний режим MySQL. ВикориÑтовуйте це тільки Ñкщо ви отримуєте помилки від MySQL. (Потрібно набагато більше пам'Ñті!)" + +#: sitemap-ui.php:793 +#@ sitemap +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "Оновіть WordPress, принаймні до 2.2, з тим щоб увімкнути швидший доÑтуп до MySQL " + +#: sitemap-ui.php:800 +#@ sitemap +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "Побудувати Мапу Ñайту у фоновому режимі (Вам не доведетьÑÑ Ñ‡ÐµÐºÐ°Ñ‚Ð¸, коли ви збережете публікацію)" + +#: sitemap-ui.php:801 +#@ sitemap +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "Оновіть WordPress, принаймні до 2.1 щоб влючити побудову у фоновому режимі " + +#: sitemap-ui.php:808 +#@ sitemap +msgid "Additional pages" +msgstr "Додаткові Ñторінки" + +#: sitemap-ui.php:811 +#@ sitemap +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "Тут ви можете вказати файли, або URL-адреÑ, Ñкі повинні бути включені в Sitemap, але не належать до блогу/WordPress.
        Ðаприклад, Ñкщо ваш домен www.foo.com Ñ– ваш блог знаходитьÑÑ Ð½Ð° www.foo.com/blog можна включити в вашу домашню Ñторінку www.foo.com" + +#: sitemap-ui.php:813 +#: sitemap-ui.php:992 +#: sitemap-ui.php:1006 +#: sitemap-ui.php:1015 +#@ sitemap +msgid "Note" +msgstr "Примітка" + +#: sitemap-ui.php:814 +#@ sitemap +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "Якщо ваш блог знаходитьÑÑ Ñƒ підкаталозі, Ñ– ви хочете додати Ñторінок, Ñкі не в блозі, Ви повинні розміÑтити Ñвій файл Sitemap в кореневий каталог (ПодивітьÑÑ Ð½Ð° \\\"МіÑце Ð·Ð½Ð°Ñ…Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ Ñайту файл"Розділ на цій Ñторінці) !" + +#: sitemap-ui.php:816 +#: sitemap-ui.php:855 +#@ sitemap +msgid "URL to the page" +msgstr "URL Ñторінки" + +#: sitemap-ui.php:817 +#@ sitemap +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "Введіть URL Ð´Ð»Ñ Ñторінки. Приклади: http://www.foo.com/index.html or www.foo.com/home " + +#: sitemap-ui.php:819 +#: sitemap-ui.php:856 +#@ sitemap +msgid "Priority" +msgstr "Пріорітет" + +#: sitemap-ui.php:820 +#@ sitemap +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "Виберіть пріоритет Ñторінки в порівнÑнні з іншими Ñторінками. Ðаприклад, ваша Ð´Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка, можливо, має більш виÑокий пріоритет, ніж інші." + +#: sitemap-ui.php:822 +#: sitemap-ui.php:858 +#@ sitemap +msgid "Last Changed" +msgstr "ОÑтанні Зміни" + +#: sitemap-ui.php:823 +#@ sitemap +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "Введіть дату оÑтаннього зміни Ñк РРРР-ММ-ДД (наприклад, 2005-12-31) (не обов'Ñзково)." + +#: sitemap-ui.php:857 +#@ sitemap +msgid "Change Frequency" +msgstr "Зміна чаÑтоти" + +#: sitemap-ui.php:859 +#@ sitemap +msgid "#" +msgstr "â„–" + +#: sitemap-ui.php:864 +#@ sitemap +msgid "No pages defined." +msgstr "Ðе зазначена жодна Ñторінка " + +#: sitemap-ui.php:869 +#@ sitemap +msgid "Add new page" +msgstr "Додати нову Ñторінку" + +#: sitemap-ui.php:874 +#@ sitemap +msgid "Post Priority" +msgstr "Пріорітет Публікації" + +#: sitemap-ui.php:876 +#@ sitemap +msgid "Please select how the priority of each post should be calculated:" +msgstr "Будь лаÑка, виберіть Ñкий пріоритет повинен бути розрахований Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ñ— публікації :" + +#: sitemap-ui.php:878 +#@ sitemap +msgid "Do not use automatic priority calculation" +msgstr "Ðе робити автоматичну калькулÑцію приорітету" + +#: sitemap-ui.php:878 +#@ sitemap +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "Ð’ÑÑ– публікацї, будуть мати такий же пріоритет, Ñкий визначений в "пріоритети"" + +#: sitemap-ui.php:889 +#@ sitemap +msgid "Location of your sitemap file" +msgstr "МіÑце роÑÑ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ файлу Sitemap" + +#: sitemap-ui.php:892 +#@ sitemap +msgid "Automatic detection" +msgstr "Ðвтоматичне виÑвленнÑ" + +#: sitemap-ui.php:896 +#@ sitemap +msgid "Filename of the sitemap file" +msgstr "Ім'Ñ Sitemap файлу" + +#: sitemap-ui.php:899 +#@ sitemap +msgid "Detected Path" +msgstr "Знайдений Путь" + +#: sitemap-ui.php:899 +#@ sitemap +msgid "Detected URL" +msgstr "Знайдений URL" + +#: sitemap-ui.php:904 +#@ sitemap +msgid "Custom location" +msgstr "МіÑце Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ðµ кориÑтувачем" + +#: sitemap-ui.php:908 +#@ sitemap +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "ÐбÑолютний або відноÑний шлÑÑ… до файлу Sitemap, в тому чиÑлі ім'Ñ." + +#: sitemap-ui.php:910 +#: sitemap-ui.php:919 +#@ sitemap +msgid "Example" +msgstr "Приклад" + +#: sitemap-ui.php:917 +#@ sitemap +msgid "Complete URL to the sitemap file, including name." +msgstr "Повний URL Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ñƒ Sitemap, в тому чиÑлі ім'Ñ." + +#: sitemap-ui.php:930 +#@ sitemap +msgid "Sitemap Content" +msgstr "ЗміÑÑ‚ мапи Ñайту" + +#: sitemap-ui.php:936 +#@ sitemap +msgid "Include homepage" +msgstr "Включити домашні Ñторінки" + +#: sitemap-ui.php:942 +#@ sitemap +msgid "Include posts" +msgstr "Включити публікації" + +#: sitemap-ui.php:948 +#@ sitemap +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "Включити наÑтупні Ñторінки декількох публікацій (збільшує Ñ‡Ð°Ñ Ð¿Ð¾Ð±ÑƒÐ´Ð¾Ð²Ð¸ та викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті!)" + +#: sitemap-ui.php:954 +#@ sitemap +msgid "Include static pages" +msgstr "Включити Ñтатичні Ñторінки" + +#: sitemap-ui.php:960 +#@ sitemap +msgid "Include categories" +msgstr "Включити категорії" + +#: sitemap-ui.php:966 +#@ sitemap +msgid "Include archives" +msgstr "Включити архіви" + +#: sitemap-ui.php:973 +#@ sitemap +msgid "Include tag pages" +msgstr "Включити Ñторінки тегів" + +#: sitemap-ui.php:980 +#@ sitemap +msgid "Include author pages" +msgstr "Включити Ñторінки авторів" + +#: sitemap-ui.php:988 +#@ sitemap +msgid "Excluded items" +msgstr "" +"\t\n" +"Виключені пункти" + +#: sitemap-ui.php:990 +#@ sitemap +msgid "Excluded categories" +msgstr "Виключити категорії" + +#: sitemap-ui.php:992 +#@ sitemap +msgid "Using this feature will increase build time and memory usage!" +msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñ†Ñ–Ñ”Ñ— функції збільшує Ñ‡Ð°Ñ Ð¿Ð¾Ð±ÑƒÐ´Ð¾Ð²Ð¸ та викориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ð°Ð¼'Ñті!" + +#: sitemap-ui.php:999 +#, php-format +#@ sitemap +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "Ð¦Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ”, що найменьше WordPress 2.5.1, ви викориÑтовуєте %s" + +#: sitemap-ui.php:1002 +#@ sitemap +msgid "Exclude posts" +msgstr "Виключити публікації" + +#: sitemap-ui.php:1004 +#@ sitemap +msgid "Exclude the following posts or pages:" +msgstr "Виключити наÑтупні публікації або Ñторінки:" + +#: sitemap-ui.php:1004 +#@ sitemap +msgid "List of IDs, separated by comma" +msgstr "Перелік ID, розділених комою" + +#: sitemap-ui.php:1006 +#@ sitemap +msgid "Child posts won't be excluded automatically!" +msgstr "Дочірні публікації не виключаютьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾!" + +#: sitemap-ui.php:1012 +#@ sitemap +msgid "Change frequencies" +msgstr "Зміна чаÑтоти" + +#: sitemap-ui.php:1016 +#@ sitemap +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "Майте на увазі, що Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ тега розглÑдаєтьÑÑ Ñк підказка, а не команда. Ðезважаючи на те, що Ñканери пошукової ÑиÑтеми враховують цю інформацію при прийнÑтті рішень, вони можуть Ñканувати Ñторінки з позначкою \\\"щогодини \" рідше, ніж Ñторінки з позначкою \\ \\\"щорічно \". Імовірно також, що Ñканери будуть періодично Ñканувати Ñторінки з позначкою \\ \\\"ніколи \", з тим щоб вони могли знайти неÑподівані зміни на цих Ñторінках." + +#: sitemap-ui.php:1022 +#: sitemap-ui.php:1079 +#@ sitemap +msgid "Homepage" +msgstr "Ð”Ð¾Ð¼Ð°ÑˆÐ½Ñ Ñторінка" + +#: sitemap-ui.php:1028 +#@ sitemap +msgid "Posts" +msgstr "Пулікації" + +#: sitemap-ui.php:1034 +#: sitemap-ui.php:1097 +#@ sitemap +msgid "Static pages" +msgstr "Статичні Ñторінки" + +#: sitemap-ui.php:1040 +#: sitemap-ui.php:1103 +#@ sitemap +msgid "Categories" +msgstr "Катергорії" + +#: sitemap-ui.php:1046 +#@ sitemap +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "Поточний архів за цей міÑÑць (Повинен бути таким Ñамим, Ñк ваша головна Ñторінка)" + +#: sitemap-ui.php:1052 +#@ sitemap +msgid "Older archives (Changes only if you edit an old post)" +msgstr "Попередні архіви (змінютьÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ тоді, коли ви редагуєте Ñтарі публікації)" + +#: sitemap-ui.php:1059 +#: sitemap-ui.php:1116 +#@ sitemap +msgid "Tag pages" +msgstr "Сторінки тегів" + +#: sitemap-ui.php:1066 +#: sitemap-ui.php:1123 +#@ sitemap +msgid "Author pages" +msgstr "Сторінки Ðвтора" + +#: sitemap-ui.php:1074 +#@ sitemap +msgid "Priorities" +msgstr "Пріоритети" + +#: sitemap-ui.php:1085 +#@ sitemap +msgid "Posts (If auto calculation is disabled)" +msgstr "Публікації (Якщо авторозрахунок відключено)" + +#: sitemap-ui.php:1091 +#@ sitemap +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "Мінімальний пріоритет публікації (Ðавіть Ñкщо автоматичний розрахунок було включено)" + +#: sitemap-ui.php:1109 +#@ sitemap +msgid "Archives" +msgstr "Ðрхіви" + +#: sitemap-ui.php:1134 +#@ sitemap +msgid "Update options" +msgstr "Оновити опції" + +#: sitemap-ui.php:1135 +#@ sitemap +msgid "Reset options" +msgstr "Скинути опції" + +#: sitemap.php:87 +#@ sitemap +msgid "XML-Sitemap Generator" +msgstr "XML-Генератор Мапи Ñайту" + +#: sitemap.php:87 +#@ sitemap +msgid "XML-Sitemap" +msgstr "XML-Мапа Ñайту" + +#: sitemap.php:101 +msgid "Settings" +msgstr "" + +#: sitemap.php:102 +msgid "FAQ" +msgstr "" + +#: sitemap.php:103 +msgid "Support" +msgstr "" + +#: sitemap.php:104 +msgid "Donate" +msgstr "" + +#: sitemap.php:154 +msgid "Sitemap FAQ" +msgstr "" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_CN.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_CN.mo new file mode 100644 index 0000000..a599579 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_CN.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_CN.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_CN.po new file mode 100644 index 0000000..0384e2e --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_CN.po @@ -0,0 +1,1054 @@ +msgid "" +msgstr "" +"Project-Id-Version: 3.1.9\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-20 03:31+0800\n" +"PO-Revision-Date: 2009-12-21 17:59+0100\n" +"Last-Translator: Arne Brachhold\n" +"Language-Team: dupola \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Chinese\n" +"X-Poedit-Country: China\n" +"X-Poedit-Basepath: D:\\usr\\www\\wp-content\\plugins\\google-sitemap-generator\n" +"X-Poedit-KeywordsList: _e;__\n" +"X-Poedit-SearchPath-0: D:\\usr\\www\\wp-content\\plugins\\google-sitemap-generator\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:525 +msgid "Comment Count" +msgstr "评论数é‡" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:537 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "通过文章评论数é‡çš„多少æ¥å†³å®šä¼˜å…ˆ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:597 +msgid "Comment Average" +msgstr "评论平å‡" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:609 +msgid "Uses the average comment count to calculate the priority" +msgstr "é€šè¿‡è¯„è®ºå¹³å‡æ¥å†³å®šè®¡ç®—优先" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:672 +msgid "Popularity Contest" +msgstr "热门内容" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:684 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "ä½¿ç”¨å·²ç»æ¿€æ´»çš„ Alex King çš„ 热门日志æ’件。 查看 设置 and 最æµè¡Œæ—¥å¿—" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1123 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1084 +msgid "Always" +msgstr "总是" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1124 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1085 +msgid "Hourly" +msgstr "æ¯å°æ—¶" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1125 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1086 +msgid "Daily" +msgstr "æ¯å¤©" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1126 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1087 +msgid "Weekly" +msgstr "æ¯å‘¨" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1127 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1088 +msgid "Monthly" +msgstr "æ¯æœˆ" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1128 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1089 +msgid "Yearly" +msgstr "æ¯æœˆ" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1129 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-core.php:1090 +msgid "Never" +msgstr "从ä¸" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:97 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:482 +msgid "XML Sitemap Generator for WordPress" +msgstr "XML 地图生æˆå™¨" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:257 +msgid "Configuration updated" +msgstr "é…置已更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:258 +msgid "Error while saving options" +msgstr "ä¿å­˜è®¾ç½®æ—¶å‡ºé”™" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:260 +msgid "Pages saved" +msgstr "页é¢å·²ä¿å­˜" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:261 +msgid "Error while saving pages" +msgstr "ä¿å­˜é¡µé¢æ—¶å‡ºé”™" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:268 +msgid "The default configuration was restored." +msgstr "默认结构已ç»è¢«ä¿®å¤ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:307 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "éžå¸¸æ„Ÿè°¢ä½ çš„æèµ ï¼Œä½ çš„帮助å¯ä»¥ä½¿æˆ‘ç»§ç»­å¼€å‘该这个和其他项目ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:307 +msgid "Hide this notice" +msgstr "éšè—æç¤º" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:313 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and you are satisfied with the results, isn't it worth at least a few dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "感谢使用本æ’ä»¶ï¼ä½ å·²ç»ä½¿ç”¨äº†ä¸€æ®µæ—¶é—´äº†ï¼ŒçŽ°åœ¨çœ‹èµ·æ¥å®ƒè¿è¡Œçš„很ä¸é”™ï¼Œå¸®äº†ä½ ä¸å°‘忙。你会考虑支æŒå®ƒçš„å‘展å—? æèµ  几美元,作者就å¯ä»¥æŒç»­å¼€å‘这个 å…费软件了。没问题?点这里开始æèµ ï¼" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:313 +msgid "Sure, but I already did!" +msgstr "当然,我已ç»åšäº†ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:313 +msgid "No thanks, please don't bug me anymore!" +msgstr "ä¸ï¼Œè¯·åˆ«å†å†éªšæ‰°æˆ‘啦ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:320 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin some time ago. If it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "感谢你使用这个æ’ä»¶ï¼ä½ å·²ç»å¯ç”¨è¿™ä¸ªæ’件一段时间了。它è¿è¡Œå¾—很ä¸é”™å¹¶ä¸”你也很满æ„,å¯å¦ 为它评分 å¹¶ 推è 给你的朋å‹ä»¬ï¼Ÿ :-)" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:320 +msgid "Don't show this anymore" +msgstr "ä¸è¦å†æ˜¾ç¤º" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:332 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!
        Due to limitations of the WordPress scheduler, it might take another 60 seconds until the build process is actually started." +msgstr "ä½ çš„ Sitemap å·²ç»æ›´æ–°ï¼Œå®Œå…¨åº”用到你的 blog å¯èƒ½éœ€è¦ç‚¹æ—¶é—´ã€‚" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:69 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:334 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "ä½ çš„ sitemap 将在 %s 秒内更新,Blog é…ç½®ä¸åŒï¼Œå®ƒå®Œå…¨ç”Ÿæ•ˆçš„æ—¶é—´ä¹Ÿä¸åŒã€‚" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:374 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:498 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "XML Sitemap 有新版本 %1$s å‘布了。 这里æ¥ä¸‹è½½ %3$s 版。" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:376 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:500 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "XML Sitemap 的新版本 %1$s å‘布了. 到这里下载 %3$s 版 。无法自动更新这个æ’ä»¶." + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:378 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:502 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "XML Sitemap 新版 %1$s å‘布了。 到这里下载 %3$s 版 或者 自动å‡çº§ã€‚" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:510 +#, php-format +msgid "Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "ä½ çš„ Blog 现在正在å±è”½æœç´¢å¼•擎ï¼å¦‚è¦æ›´æ”¹è¯·å‰åŽ» éšç§è®¾ç½® 页é¢ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:531 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:548 +msgid "open" +msgstr "打开" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:532 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:549 +msgid "close" +msgstr "关闭" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:533 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:550 +msgid "click-down and drag to move this box" +msgstr "点击并拖动它到这个区域" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:534 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:551 +msgid "click to %toggle% this box" +msgstr "点击并 %toggle% 这个区域" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:535 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:552 +msgid "use the arrow keys to move this box" +msgstr "ä½¿ç”¨ç®­å¤´æŒ‡å‘æ¥ç§»åŠ¨è¿™ä¸ªåŒºå—" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:536 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:553 +msgid ", or press the enter key to %toggle% it" +msgstr ",或者按这里to %toggle% it" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:582 +msgid "About this Plugin:" +msgstr "关于这个æ’件:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:583 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:187 +msgid "Plugin Homepage" +msgstr "æ’件主页" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:438 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:584 +msgid "Suggest a Feature" +msgstr "建议新功能" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:585 +msgid "Notify List" +msgstr "通告列表" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:586 +msgid "Support Forum" +msgstr "支æŒè®ºå›" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:441 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:587 +msgid "Report a Bug" +msgstr "报告 Bug" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:589 +msgid "Donate with PayPal" +msgstr "通过 PayPal æèµ " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:590 +msgid "My Amazon Wish List" +msgstr "我想è¦çš„东西(Amazon)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:591 +msgid "translator_name" +msgstr "肚破惊天(@dupola)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:591 +msgid "translator_url" +msgstr "http://dupola.net" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:595 +msgid "Sitemap Resources:" +msgstr "Sitemap 资æºï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:596 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:602 +msgid "Webmaster Tools" +msgstr "Webmaster Tools" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:597 +msgid "Webmaster Blog" +msgstr "Webmaster Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:599 +msgid "Site Explorer" +msgstr "Site Explorer" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:600 +msgid "Search Blog" +msgstr "Search Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:603 +msgid "Webmaster Center Blog" +msgstr "Webmaster Center Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:605 +msgid "Sitemaps Protocol" +msgstr "Sitemaps åè®®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:606 +msgid "Official Sitemaps FAQ" +msgstr "通用 Sitemaps FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:607 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:188 +msgid "My Sitemaps FAQ" +msgstr "我的 Sitemaps FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:610 +msgid "Recent Donations:" +msgstr "最近æèµ è€…:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:613 +msgid "List of the donors" +msgstr "æèµ è€…列表" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:615 +msgid "Hide this list" +msgstr "éšè—这个列表" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:618 +msgid "Thanks for your support!" +msgstr "谢谢支æŒï¼" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:640 +msgid "The sitemap wasn't generated yet." +msgstr "Sitemap 还没生æˆã€‚" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:643 +msgid "Result of the last build process, started on %date%." +msgstr "上一次执行的结果,始于 %date%." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:652 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "sitemap 还没建立,点击这里建立。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:658 +msgid "Your sitemap was last built on %date%." +msgstr "ä½ çš„ sitemap 上一次建立是在%date%。" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:659 +msgid "The last build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "Sitemap 上一次建立æˆåŠŸï¼Œä¸è¿‡æ–‡ä»¶è¢«åˆ é™¤äº†æˆ–è€…æ˜¯æ— æ³•è®¿é—®äº†ã€‚ä½ æ˜¯ä¸æ˜¯å°† blog 转移到了其他主机或域å?" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:661 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "写入 sitemap 文件时å‘生错误。ä¿è¯è¿™ä¸ªæ–‡ä»¶å­˜åœ¨å¹¶ä¸”å¯å†™ã€‚学习更多" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:668 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "ä½ çš„ sitemap (zipped) 上一次建立是在 %date%." + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:669 +msgid "The last zipped build succeeded, but the file was deleted later or can't be accessed anymore. Did you move your blog to another server or domain?" +msgstr "Sitemap zipped 上一次执行æˆåŠŸï¼Œä¸è¿‡æ–‡ä»¶è¢«åˆ é™¤äº†æˆ–è€…æ˜¯æ— æ³•è®¿é—®äº†ã€‚ä½ æ˜¯ä¸æ˜¯å°† blog 转移到了其他主机或域å?" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:671 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn more" +msgstr "在创建 zipped sitemap 文件时å‘生了错误。ä¿è¯è¿™ä¸ªæ–‡ä»¶å­˜åœ¨å¹¶ä¸”å¯å†™ã€‚学习更多" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:677 +msgid "Google was successfully notified about changes." +msgstr "æ›´æ–°å·²ç»æˆåŠŸé€šçŸ¥ Google。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:680 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "通知 Google 用了%time% ,也许你应该ç¦ç”¨è¿™ä¸€åŠŸèƒ½ä»¥å‡å°‘创建时间。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:683 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "在通知 Google æ—¶å‘生错误,查看结果" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:689 +msgid "YAHOO was successfully notified about changes." +msgstr "æ›´æ–°å·²ç»æˆåŠŸé€šçŸ¥ YAHOO。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:692 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "通知 YAHOO 用了 %time% ,也许你应该ç¦ç”¨è¿™é¡¹åŠŸèƒ½ä»¥å‡å°‘建立时间。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:695 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "通知 YAHOO 时出错。查看结果" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3097 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:701 +msgid "Bing was successfully notified about changes." +msgstr "æ‚¨çš„æ›´æ”¹å·²ç»æˆåŠŸé€šçŸ¥ Bing。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:704 +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "通知 Bing 用了%time% ,也许你应该ç¦ç”¨è¿™ä¸€åŠŸèƒ½ä»¥å‡å°‘创建时间。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:707 +#, php-format +msgid "There was a problem while notifying Bing. View result" +msgstr "在通知 Bing æ—¶å‘生错误,查看结果" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:713 +msgid "Ask.com was successfully notified about changes." +msgstr "æ›´æ–°å·²ç»æˆåŠŸé€šçŸ¥ Ask.com。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:716 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "通知 Ask.com 用了%time% ,也许你应该ç¦ç”¨è¿™ä¸€åŠŸèƒ½ä»¥å‡å°‘创建时间。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:719 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "通知 MSN.com 时出错。查看结果" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:727 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "此次建立大约用了 %time% ç§’ 完æˆï¼Œä½¿ç”¨äº† %memory% MB 内存。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:729 +msgid "The building process took about %time% seconds to complete." +msgstr "此次建立用了大约 %time% ç§’ 完æˆã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:733 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "从上次这个文件ä¸å¯å†™ä»¥åŽï¼Œä½ çš„ sitemap 就没有更新 ,并且也没有通知任何æœç´¢å¼•擎。" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:586 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:741 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "这项处ç†å°†ä¼šç”Ÿæ•ˆï¼å‡ ç§’é’ŸåŽåˆ·æ–°è¿™ä¸ªé¡µé¢ï¼ŒæŸ¥çœ‹æ˜¯å¦æœ‰æ‰€å˜åŒ–。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:744 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "上次è¿è¡Œæ²¡æœ‰å®Œæˆï¼ä½ åº”该为 PHP scripts 增加内存或时间é™åˆ¶ã€‚学习更多" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:746 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "上次执行用了 was %memused%MB, ä½ çš„æœåС噍é™åˆ¶æ˜¯ %memlimit%。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:750 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "上次执行时间 %timeused% 秒,你的æœåС噍é™åˆ¶æ˜¯ %timelimit% ç§’." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:754 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "è¿™ä¸ªè„šæœ¬åœæ­¢äºŽè¿™ç¯‡æ—¥å¿—: %lastpost% (+/- 100)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:757 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "如果你 Blog 或æœåŠ¡å™¨æ›´æ–°äº†æŸäº›ä¸œè¥¿ï¼Œä½ åº”该手动 é‡å»º sitemap。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:759 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "å¦‚æžœåœ¨æ‰§è¡Œå»ºç«‹ç¨‹åºæ—¶é‡åˆ°é—®é¢˜ï¼Œä½ å¯ä»¥ä½¿ç”¨ debug functionæ¥èŽ·å–æ›´å¤šä¿¡æ¯ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:766 +msgid "Basic Options" +msgstr "基本设置" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:768 +msgid "Sitemap files:" +msgstr "sitemap 文件" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:768 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:783 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:803 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:836 +msgid "Learn more" +msgstr "学习更多" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3049 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:773 +msgid "Write a normal XML file (your filename)" +msgstr "创建一个 XML 文件 (你的文件å)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3055 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:779 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "创建一个 gzipped 文件 (你的文件å + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:783 +msgid "Building mode:" +msgstr "建立模å¼ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:788 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "在你更改了 Blog 内容åŽé‡å»º sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:795 +msgid "Enable manual sitemap building via GET Request" +msgstr "通过 GET Request å¯ç”¨æ‰‹åŠ¨å»ºç«‹ sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:799 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the result box above to see if sitemap was successfully built." +msgstr "å¦‚æžœå¤–éƒ¨å·¥å…·ä¸æ˜¯é€šè¿‡ WordPress API写入 WordPress æ•°æ®ï¼Œé‚£æ­¤é¡¹å°†å…许你刷新你的 sitemap,。使用下é¢è¿™ä¸ªé“¾æŽ¥å¼€å§‹è¿è¡Œï¼š%1 请检查上é¢çš„æ—¥å¿—文件,看看 sitemap 有没有æˆåŠŸå»ºç«‹ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:803 +msgid "Update notification:" +msgstr "更新通知:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:807 +msgid "Notify Google about updates of your Blog" +msgstr "通知 Google 关于你 Blog 的更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:808 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "éžå¿…须注册,ä¸è¿‡ä½ å¯ä»¥ä½¿ç”¨Google 管ç†å‘˜å·¥å…·æŸ¥çœ‹çˆ¬è™«ç»Ÿè®¡ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3209 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:812 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "通知 Bing/MSN Live Search 关于你 Blog 的更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:813 +#, php-format +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "éžå¿…须注册,ä¸è¿‡ä½ å¯ä»¥ä½¿ç”¨ Bing 管ç†å‘˜å·¥å…·æŸ¥çœ‹çˆ¬è™«ç»Ÿè®¡ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:817 +msgid "Notify Ask.com about updates of your Blog" +msgstr "æé†’ Ask.com 关于你 Blog 的更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:818 +msgid "No registration required." +msgstr "éžå¿…须注册。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:822 +msgid "Notify YAHOO about updates of your Blog" +msgstr "æé†’ Yahoo 关于你 Blog 的更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:823 +msgid "Your Application ID:" +msgstr "ä½ çš„ Application ID:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:824 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "没有 key?点这里申请一个! %s2" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:829 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "å°† sitemap åœ°å€æ·»åŠ åˆ°è™šæ‹Ÿ robots.txt 文件中。" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:833 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "ç”± WordPress 生æˆçš„虚拟 robots.txt 文件已ç»å¯ç”¨ï¼Œè¯·ç¡®ä¿ blog 文档中已无原æ¥çš„ robots.txt 文件。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:836 +msgid "Advanced options:" +msgstr "高级设置:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:839 +msgid "Limit the number of posts in the sitemap:" +msgstr "sitemap 里日志数é‡çš„é™åˆ¶ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:839 +msgid "Newer posts will be included first" +msgstr "较早的日志将首先被包å«è¿›æ¥" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:842 +msgid "Try to increase the memory limit to:" +msgstr "增加内存é™åˆ¶åˆ°ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:842 +msgid "e.g. \"4M\", \"16M\"" +msgstr "比如: \"4M\", \"16M\"" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:845 +msgid "Try to increase the execution time limit to:" +msgstr "增加执行时间é™åˆ¶åˆ°ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:845 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "按秒计算,比如 \"60\" or \"0\" 没有é™åˆ¶" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:849 +msgid "Include a XSLT stylesheet:" +msgstr "包å«ä¸€ä¸ª XSLT 清å•" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:850 +msgid "Full or relative URL to your .xsl file" +msgstr ".xsl 文件的ç»å¯¹æˆ–相对路径" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:850 +msgid "Use default" +msgstr "使用默认的" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:856 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "å¯ç”¨ MySQL 标准模å¼ã€‚仅在 MySQL å‘生错误的时候使用。(将会å ç”¨æ›´å¤šå†…å­˜ï¼)" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:857 +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "MySQL å¿«é€Ÿè¿žæŽ¥ä»…æ”¯æŒ WordPress 2.2 或以上版本,请å‡çº§ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:864 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "在åŽå°å»ºç«‹ sitemap(你ä¸éœ€è¦åœ¨ä¿å­˜æ—¥å¿—时等待)" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:865 +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "åŽå°ç”Ÿæˆä»…æ”¯æŒ WordPress 2.1 或以上版本,请å‡çº§ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:872 +msgid "Additional pages" +msgstr "附加页é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:875 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "在这里你å¯ä»¥ä¸º sitemap 加入一些特殊的但并ä¸å­˜åœ¨äºŽä½  Blog/WordPress 的地å€ã€‚æ¯”å¦‚ï¼Œå¦‚æžœä½ çš„åŸŸåæ˜¯ www.dupola.com,你的blog在 www.dupola.com/blog 上,你å¯ä»¥åŠ å…¥ä½ çš„é¦–é¡µ www.dupola.com" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:877 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1085 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1099 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1108 +msgid "Note" +msgstr "注æ„" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:878 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "如果你的 blog 在å­ç›®å½•é‡Œï¼Œä½ è¦æ·»åŠ  blog 目录或下级目录没有的页é¢ï¼Œä½ å¿…须将 sitemap 文件放到这个目录里(查看本页的 " sitemap 文件的ä½ç½® " 一节)ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:880 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:919 +msgid "URL to the page" +msgstr "这个页é¢çš„ URL" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:881 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "输入这个页é¢çš„地å€ï¼Œæ¯”如:http://dupola.com/dreamhost 或 https://twitter.com/dupola 或 http://caodan.net" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:883 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:920 +msgid "Priority" +msgstr "优先" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:884 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "选择该页é¢çš„相关页é¢çš„优先æƒã€‚比如,你的主页应该拥有一个更高的优先æƒã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:886 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:922 +msgid "Last Changed" +msgstr "最近更改" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:887 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "è¾“å…¥æœ€åŽæ›´æ”¹çš„æ—¥æœŸï¼Œæ ¼å¼ä¸º YYYY-MM-DD (例如 2005-12-31) (å¯é€‰çš„l)." + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:921 +msgid "Change Frequency" +msgstr "更改频率" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:923 +msgid "#" +msgstr "#" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:928 +msgid "No pages defined." +msgstr "没有页é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:933 +msgid "Add new page" +msgstr "增加一个新的页é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:938 +msgid "Post Priority" +msgstr "日志优先" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:940 +msgid "Please select how the priority of each post should be calculated:" +msgstr "请选择æ¯ç¯‡æ—¥å¿—å¯é¢„设的优先æƒï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:942 +msgid "Do not use automatic priority calculation" +msgstr "ä¸è¦ä½¿ç”¨é»˜è®¤ä¼˜å…ˆè®¡ç®—" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:942 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "所有日志都将拥有 "优先æƒ" 设定中设置的那样的优先æƒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3348 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:953 +msgid "Location of your sitemap file" +msgstr "ä½ çš„ sitemap 文件的ä½ç½®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3353 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:956 +msgid "Automatic detection" +msgstr "自动检查" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3357 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:960 +msgid "Filename of the sitemap file" +msgstr "sitemap 文件的åå­—" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:963 +msgid "Detected Path" +msgstr "检查路径" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:963 +msgid "Detected URL" +msgstr "检查地å€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3365 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:968 +msgid "Custom location" +msgstr "自定义ä½ç½®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3369 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:972 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "sitemap çš„ç»å¯¹æˆ–相对路径,包括å字。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3371 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3380 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:974 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:983 +msgid "Example" +msgstr "例如" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3378 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:981 +msgid "Complete URL to the sitemap file, including name." +msgstr "sitemap 文件的完全地å€ï¼ŒåŒ…括å字。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:994 +msgid "Sitemap Content" +msgstr "sitemap 内容" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1000 +msgid "Include homepage" +msgstr "包å«é¦–页" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1006 +msgid "Include posts" +msgstr "åŒ…å«æ—¥å¿—" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1013 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1012 +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "包括所有多é‡é¡µé¢ï¼ˆè¿™å°†å¢žåŠ ä½¿ç”¨å†…å­˜å’Œç”Ÿæˆæ—¶é—´ï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1018 +msgid "Include static pages" +msgstr "包å«ç‹¬ç«‹é¡µé¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1024 +msgid "Include categories" +msgstr "包å«åˆ†ç±»" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1030 +msgid "Include archives" +msgstr "包å«å­˜æ¡£é¡µé¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1037 +msgid "Include tag pages" +msgstr "åŒ…å« Tag 页é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1053 +#, php-format +msgid "Include taxonomy pages for %s" +msgstr "包括 %s çš„ tag 页é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1063 +msgid "Include author pages" +msgstr "包å«ä½œè€…页é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1067 +msgid "Further options" +msgstr "高级设置" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1072 +msgid "Include the last modification time." +msgstr "包括最åŽä¿®æ”¹æ—¶é—´ã€‚" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1074 +msgid "This is highly recommended and helps the search engines to know when your content has changed. This option affects all sitemap entries." +msgstr "强烈推è开坿­¤é¡¹ï¼Œå®ƒä¼šåœ¨ä½ çš„内容å‘生å˜åŠ¨æ—¶å¸®ä½ å‘Šè¯‰æœç´¢å¼•擎。这个设置将影å“到 所有 sitemap 日志。" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:981 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1081 +msgid "Excluded items" +msgstr "ä¸åŒ…å«çš„项目" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1083 +msgid "Excluded categories" +msgstr "ä¸åŒ…å«åˆ†ç±»" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:985 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1085 +msgid "Using this feature will increase build time and memory usage!" +msgstr "使用这个特性将增大建立时间和使用内存ï¼" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:992 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1092 +#, php-format +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "è¿™ä¸ªç‰¹æ€§è¦æ±‚ WordPress 版本至少是 2.5,你正在使用 %s" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1095 +msgid "Exclude posts" +msgstr "ä¸åŒ…嫿—¥å¿—" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1097 +msgid "Exclude the following posts or pages:" +msgstr "ä¸åŒ…括下é¢çš„æ—¥å¿—或页é¢ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1097 +msgid "List of IDs, separated by comma" +msgstr "ID 列表,用英文逗å·éš”å¼€" + +# D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:999 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1099 +msgid "Child posts won't be excluded automatically!" +msgstr "å­æ—¥å¿—ä¸ä¼šè¢«è‡ªåŠ¨æŽ’é™¤ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1105 +msgid "Change frequencies" +msgstr "更改频率" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1109 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "请注æ„,这些值仅仅是å‚è€ƒå»ºç«‹è€Œå¹¶éžæ˜¯å‡†ç¡®æ— è¯¯çš„。 " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1115 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1172 +msgid "Homepage" +msgstr "首页" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1121 +msgid "Posts" +msgstr "日志" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1127 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1190 +msgid "Static pages" +msgstr "独立页é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1133 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1196 +msgid "Categories" +msgstr "分类" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1139 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "è¿™ä¸ªæœˆçš„å­˜æ¡£ï¼ˆåº”è¯¥å’Œä½ çš„é¦–é¡µä¿æŒä¸€è‡´ï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1145 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "较早的存档(åªåœ¨ä½ ç¼–è¾‘äº†æ—§æ—¥å¿—åŽæ‰æ›´æ–°ï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1152 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1209 +msgid "Tag pages" +msgstr "Tag 页" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1159 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1216 +msgid "Author pages" +msgstr "作者页" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1167 +msgid "Priorities" +msgstr "优先æƒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1178 +msgid "Posts (If auto calculation is disabled)" +msgstr "日志(如果自动计算已ç¦ç”¨ï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1184 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "日志最å°ä¼˜å…ˆï¼ˆå³ä½¿è‡ªåŠ¨è®¡ç®—å·²ç»å¼€å¯ï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1202 +msgid "Archives" +msgstr "存档" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1227 +msgid "Update options" +msgstr "更新设置" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap-ui.php:1228 +msgid "Reset options" +msgstr "é‡ç½®è®¾ç½®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:98 +msgid "XML-Sitemap Generator" +msgstr "XML-Sitemap 生æˆå™¨" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:98 +msgid "XML-Sitemap" +msgstr "XML-Sitemap" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:112 +msgid "Settings" +msgstr "设置" + +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:113 +msgid "FAQ" +msgstr "FAQ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:114 +msgid "Support" +msgstr "支æŒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +#: D:\usr\www\wp-content\plugins\google-sitemap-generator/sitemap.php:115 +msgid "Donate" +msgstr "æèµ " + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_TW.mo b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_TW.mo new file mode 100644 index 0000000..5ec9c55 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_TW.mo differ diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_TW.po b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_TW.po new file mode 100644 index 0000000..87c8c04 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap-zh_TW.po @@ -0,0 +1,980 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 123431 2009-06-07 00:17:10Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-06-07 01:15+0100\n" +"PO-Revision-Date: 2009-06-08 12:10+0800\n" +"Last-Translator: \n" +"Language-Team: hugo5688 \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-KeywordsList: _e;__\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: H:\\Webdev\\htdocs\\wp_plugins\\sitemap_beta\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:642 +msgid "Comment Count" +msgstr "迴響數目" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:654 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "使用迴響的數é‡ä¾†è¨ˆç®—優先權" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:714 +msgid "Comment Average" +msgstr "迴響平å‡å€¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:726 +msgid "Uses the average comment count to calculate the priority" +msgstr "使用迴響數é‡å¹³å‡å€¼ä¾†è¨ˆç®—優先權" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:993 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:789 +msgid "Popularity Contest" +msgstr "熱門競賽" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:1005 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:801 +msgid "Uses the activated Popularity Contest Plugin from Alex King. See Settings and Most Popular Posts" +msgstr "使用 Alex King æä¾›çš„ Popularity Contest 外掛(需啟用)。詳見 é¸é … 以åŠMost Popular Posts" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1118 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1187 +msgid "Always" +msgstr "隨時" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1119 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1188 +msgid "Hourly" +msgstr "æ¯å°æ™‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1120 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1189 +msgid "Daily" +msgstr "æ¯æ—¥" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1190 +msgid "Weekly" +msgstr "æ¯é€±" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1122 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1191 +msgid "Monthly" +msgstr "æ¯æœˆ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1123 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1192 +msgid "Yearly" +msgstr "æ¯å¹´" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-core.php:1193 +msgid "Never" +msgstr "從ä¸" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Thank you very much for your donation. You help me to continue support and development of this plugin and other free software!" +msgstr "éžå¸¸æ„Ÿè¬æ‚¨çš„贊助。由於您的幫助,讓我能夠繼續支æ´é–‹ç™¼é€™å€‹å¤–掛以åŠå…¶ä»–å…費軟體ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:102 +msgid "Hide this notice" +msgstr "éš±è—這個通知" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +#, php-format +msgid "Thanks for using this plugin! You've installed this plugin over a month ago. If it works and your are satisfied with the results, isn't it worth at least one dollar? Donations help me to continue support and development of this free software! Sure, no problem!" +msgstr "æ„Ÿè¬æ‚¨ä½¿ç”¨æ­¤å¤–掛!您已在一個月å‰å®‰è£æ­¤å¤–æŽ›ã€‚å¦‚æžœå®ƒæ­£å¸¸å·¥ä½œä¸¦è®“æ‚¨å°æ–¼æ­¤çµæžœæ„Ÿåˆ°å®‰å¿ƒï¼Œæ˜¯ä¸æ˜¯è‡³å°‘價值一美元呢? è«‹è´ŠåŠ©æˆ‘ä¾†è®“æˆ‘æœ‰ç¹¼çºŒé–‹ç™¼åŠæ”¯æ´æ­¤å…è²» 外掛軟體的動力。好的,沒å•題!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:108 +msgid "No thanks, please don't bug me anymore!" +msgstr "ä¸äº†ï¼Œè«‹ä¸è¦å†ç…©æˆ‘!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:67 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:119 +msgid "Your sitemap is being refreshed at the moment. Depending on your blog size this might take some time!" +msgstr "æ‚¨çš„ç¶²ç«™åœ°åœ–åœ¨æ­¤åˆ»å·²é–‹å§‹æ›´æ–°ã€‚é€™å®Œå…¨å–æ±ºæ–¼æ‚¨çš„blog大å°ï¼Œæˆ–許會花上一點時間!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:69 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:121 +#, php-format +msgid "Your sitemap will be refreshed in %s seconds. Depending on your blog size this might take some time!" +msgstr "您的網站地圖將會在%sç§’é˜å¾Œæ›´æ–°ã€‚é€™å®Œå…¨å–æ±ºæ–¼æ‚¨çš„blog大å°ï¼Œæˆ–許會花上一點時間!" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:146 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:453 +msgid "XML Sitemap Generator for WordPress" +msgstr "WordPress 專用 XML 網站地圖產生器" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:298 +msgid "Configuration updated" +msgstr "設定已更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:299 +msgid "Error while saving options" +msgstr "儲存é¸é …時產生錯誤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:301 +msgid "Pages saved" +msgstr "é é¢å·²å„²å­˜" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:302 +msgid "Error while saving pages" +msgstr "儲存é é¢æ™‚產生錯誤" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:309 +msgid "The default configuration was restored." +msgstr "設定已é‡ç½®ç‚ºé è¨­å€¼ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:466 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here." +msgstr "有較新的版本 %1$s å¯ä¾›ä¸‹è¼‰ã€‚下載版本 %3$s" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:468 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here automatic upgrade unavailable for this plugin." +msgstr "有較新的版本 %1$s å¯ä¾›ä¸‹è¼‰ã€‚下載版本 %3$s 自動更新ä¸å¯é©ç”¨æ–¼æ­¤å¤–掛程å¼ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:470 +#, php-format +msgid "There is a new version of %1$s available. Download version %3$s here or upgrade automatically." +msgstr "有較新的版本 %1$s å¯ä¾›ä¸‹è¼‰ã€‚下載版本 %3$s或者自動更新。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2851 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2868 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:493 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:510 +msgid "open" +msgstr "打開" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2852 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2869 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:494 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:511 +msgid "close" +msgstr "關閉" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2853 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2870 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:495 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:512 +msgid "click-down and drag to move this box" +msgstr "按下並拖曳這個矩形" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2854 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2871 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:496 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:513 +msgid "click to %toggle% this box" +msgstr "按了「%toggle%ã€é€™å€‹çŸ©å½¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2855 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2872 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:497 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:514 +msgid "use the arrow keys to move this box" +msgstr "使用方å‘éµç§»å‹•這個矩形" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2856 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2873 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:498 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:515 +msgid ", or press the enter key to %toggle% it" +msgstr ",或者按下 Enter éµä¾†ã€Œ%toggle%ã€å®ƒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:533 +msgid "About this Plugin:" +msgstr "關於這個外掛:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:534 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:141 +msgid "Plugin Homepage" +msgstr "外掛首é " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:535 +msgid "Suggest a Feature" +msgstr "功能推薦" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:536 +msgid "Notify List" +msgstr "郵件通知" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:537 +msgid "Support Forum" +msgstr "支æ´è«–壇" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:538 +msgid "Report a Bug" +msgstr "臭蟲回報" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:540 +msgid "Donate with PayPal" +msgstr "PayPal 贊助" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:541 +msgid "My Amazon Wish List" +msgstr "我的 Amazon 願望清單" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:542 +msgid "translator_name" +msgstr "Hugo5688" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:542 +msgid "translator_url" +msgstr "http://take-ez.com" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:545 +msgid "Sitemap Resources:" +msgstr "網站地圖資æºï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:546 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:552 +msgid "Webmaster Tools" +msgstr "網站管ç†å“¡å·¥å…·" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:547 +msgid "Webmaster Blog" +msgstr "網站管ç†å“¡ç¶²èªŒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2900 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:549 +msgid "Site Explorer" +msgstr "Site Explorer" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:550 +msgid "Search Blog" +msgstr "Search Blog" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:553 +msgid "Webmaster Center Blog" +msgstr "網站管ç†å“¡ç¶²èªŒ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:555 +msgid "Sitemaps Protocol" +msgstr "網站地圖通訊å”定" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:556 +msgid "Official Sitemaps FAQ" +msgstr "官方版網站地圖答客å•" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:557 +msgid "My Sitemaps FAQ" +msgstr "網站地圖答客å•" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:560 +msgid "Recent Donations:" +msgstr "近期贊助清單:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:564 +msgid "List of the donors" +msgstr "贊助者清單" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:566 +msgid "Hide this list" +msgstr "éš±è—æœ¬æ¸…å–®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:569 +msgid "Thanks for your support!" +msgstr "æ„Ÿè¬æ‚¨çš„贊助ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2931 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:587 +msgid "Status" +msgstr "狀態" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2941 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:595 +#, php-format +msgid "The sitemap wasn't built yet. Click here to build it the first time." +msgstr "您的網站地圖還沒產生éŽã€‚點這裡來產生它å§ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2947 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:601 +msgid "Your sitemap was last built on %date%." +msgstr "您的網站地圖上次發佈時間為:%date%。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2949 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:603 +msgid "There was a problem writing your sitemap file. Make sure the file exists and is writable. Learn more更多資訊" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2956 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:610 +msgid "Your sitemap (zipped) was last built on %date%." +msgstr "網站地圖(壓縮檔)上回產生於:%date%。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2958 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:612 +msgid "There was a problem writing your zipped sitemap file. Make sure the file exists and is writable. Learn more更多資訊" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2964 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:618 +msgid "Google was successfully notified about changes." +msgstr "已經æˆåŠŸåœ°é€šçŸ¥ Google 您網站的更新。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2967 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:621 +msgid "It took %time% seconds to notify Google, maybe you want to disable this feature to reduce the building time." +msgstr "花了 %time% 秒來通知 Google,或許您想è¦é—œé–‰æ­¤åŠŸèƒ½ä¾†å¢žåŠ æ•ˆèƒ½ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:624 +#, php-format +msgid "There was a problem while notifying Google. View result" +msgstr "通知 Google 時發生了å•é¡Œã€‚æª¢è¦–çµæžœ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2976 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:630 +msgid "YAHOO was successfully notified about changes." +msgstr "已經æˆåŠŸåœ°é€šçŸ¥ YAHOO 您網站的更新。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2979 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:633 +msgid "It took %time% seconds to notify YAHOO, maybe you want to disable this feature to reduce the building time." +msgstr "花了 %time% 秒來通知 YAHOO,或許您想è¦é—œé–‰æ­¤åŠŸèƒ½ä¾†å¢žåŠ æ•ˆèƒ½ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3023 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:636 +#, php-format +msgid "There was a problem while notifying YAHOO. View result" +msgstr "通知 YAHOO 時發生了å•é¡Œã€‚æª¢è¦–çµæžœ" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:642 +msgid "Bing was successfully notified about changes." +msgstr "已經æˆåŠŸåœ°é€šçŸ¥ Bing 您網站的更新。" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:645 +msgid "It took %time% seconds to notify Bing, maybe you want to disable this feature to reduce the building time." +msgstr "花了 %time% 秒來通知 Bing,或許您想è¦é—œé–‰æ­¤åŠŸèƒ½ä¾†å¢žåŠ æ•ˆèƒ½ã€‚" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:648 +#, php-format +msgid "There was a problem while notifying Bing. View result" +msgstr "通知 Bing 時發生了å•é¡Œã€‚æª¢è¦–çµæžœ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2988 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:654 +msgid "Ask.com was successfully notified about changes." +msgstr "已經æˆåŠŸåœ°é€šçŸ¥ Ask.com 您網站的更新。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2991 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:657 +msgid "It took %time% seconds to notify Ask.com, maybe you want to disable this feature to reduce the building time." +msgstr "花了 %time% 秒來通知 Ask.com,或許您想è¦é—œé–‰æ­¤åŠŸèƒ½ä¾†å¢žåŠ æ•ˆèƒ½ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3035 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:660 +#, php-format +msgid "There was a problem while notifying Ask.com. View result" +msgstr "通知 Ask.com 時發生了å•é¡Œã€‚æª¢è¦–çµæžœ" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3002 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:668 +msgid "The building process took about %time% seconds to complete and used %memory% MB of memory." +msgstr "整個建置éŽç¨‹å¤§ç´„花費 %time% ç§’ 來完æˆï¼Œä¸¦ä¸”使用了 %memory% MB 的記憶體。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3004 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:670 +msgid "The building process took about %time% seconds to complete." +msgstr "整個建置éŽç¨‹å¤§ç´„花費 %time% ç§’ 來完æˆã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3008 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:674 +msgid "The content of your sitemap didn't change since the last time so the files were not written and no search engine was pinged." +msgstr "您的網站地圖內容與上次比較並沒有變更,所以沒有產生新檔案,而且æœå°‹å¼•擎也沒有被通知。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:586 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:682 +msgid "The building process might still be active! Reload the page in a few seconds and check if something has changed." +msgstr "å»ºç«‹ç¶²ç«™åœ°åœ–çš„ç¨‹åºæˆ–許ä¾ç„¶å•Ÿå‹•著。é é¢å°‡åœ¨å¹¾ç§’é˜å¾Œé‡æ–°è¼‰å…¥ï¼Œä¸¦ä¸”ç¢ºèªæ˜¯å¦æ”¹è®Šã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3012 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:685 +msgid "The last run didn't finish! Maybe you can raise the memory or time limit for PHP scripts. Learn more" +msgstr "ä¸Šæ¬¡çš„åŸ·è¡Œä¸¦æœªçµæŸï¼ä¹Ÿè¨±æ‚¨éœ€è¦æ›¿ PHP 增加記憶體或者時間é™åˆ¶ã€‚更多資訊" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3014 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:687 +msgid "The last known memory usage of the script was %memused%MB, the limit of your server is %memlimit%." +msgstr "最後一次執行本程å¼ä½¿ç”¨ %memused% MB 記憶體,您伺æœå™¨çš„é™åˆ¶ç‚º %memlimit%。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3018 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:691 +msgid "The last known execution time of the script was %timeused% seconds, the limit of your server is %timelimit% seconds." +msgstr "最後一次執行本程å¼çš„æ™‚間花 %timeused% 秒,您伺æœå™¨çš„é™åˆ¶ç‚º %timelimit% 秒。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3022 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:695 +msgid "The script stopped around post number %lastpost% (+/- 100)" +msgstr "這支程å¼å¤§ç´„åœåœ¨ç¬¬ %lastpost% (+/- 100)篇文章" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3025 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:698 +#, php-format +msgid "If you changed something on your server or blog, you should rebuild the sitemap manually." +msgstr "若是您å°ä¼ºæœå™¨æˆ–者網誌åšäº†æŸäº›æ›´å‹•ï¼Œæ‚¨æ‡‰è©²æ‰‹å‹•é‡æ–°ç”¢ç”Ÿç¶²ç«™åœ°åœ–。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:700 +#, php-format +msgid "If you encounter any problems with the build process you can use the debug function to get more information." +msgstr "如果您在建立的éŽç¨‹é‡åˆ°äº†å•題,您å¯ä»¥ä½¿ç”¨é™¤éŒ¯åŠŸèƒ½ä¾†å¾—çŸ¥æ›´å¤šçš„è¨Šæ¯ã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:707 +msgid "Basic Options" +msgstr "基本é¸é …" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:709 +msgid "Sitemap files:" +msgstr "網站地圖檔案:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:709 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Learn more" +msgstr "更多資訊" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3049 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:714 +msgid "Write a normal XML file (your filename)" +msgstr "寫入 XML 檔案(檔案å稱)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3055 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:720 +msgid "Write a gzipped file (your filename + .gz)" +msgstr "寫入壓縮檔(檔案å稱 + .gz)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:724 +msgid "Building mode:" +msgstr "產生模å¼ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:729 +msgid "Rebuild sitemap if you change the content of your blog" +msgstr "ç•¶ä¿®æ”¹ç¶²èªŒå…§å®¹æ™‚é‡æ–°å»ºç«‹ç¶²ç«™åœ°åœ–。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:736 +msgid "Enable manual sitemap building via GET Request" +msgstr "啟用é€éŽç™¼é€ GET è¦æ±‚手動建立網站地圖。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3075 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:740 +msgid "This will allow you to refresh your sitemap if an external tool wrote into the WordPress database without using the WordPress API. Use the following URL to start the process: %1 Please check the logfile above to see if sitemap was successfully built." +msgstr "本é¸é …å…許您刷新您的網站地圖。當您使用外部工具直接將文章寫入 WordPress 資料庫,而éžé€éŽ WordPress API 時,使用以下網å€å•Ÿå‹•這個作業: %1 若是è¦çŸ¥é“æ˜¯å¦æˆåŠŸè«‹æª¢æŸ¥ç´€éŒ„æª”æ¡ˆã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:744 +msgid "Update notification:" +msgstr "更新通知:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:748 +msgid "Notify Google about updates of your Blog" +msgstr "通知 Google 關於您網站的更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:749 +#, php-format +msgid "No registration required, but you can join the Google Webmaster Tools to check crawling statistics." +msgstr "ä¸éœ€è¦è¨»å†Šï¼Œä½†æ‚¨å¯åŠ å…¥ Google 網站管ç†å“¡å·¥å…·ä¾†æª¢æŸ¥æœç´¢çµ±è¨ˆã€‚" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:753 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "" +"通知 Bing (å‰èº«ç‚º MSN Live Search\r\n" +") 關於您網站的更新" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:754 +#, php-format +msgid "No registration required, but you can join the Bing Webmaster Tools to check crawling statistics." +msgstr "ä¸éœ€è¦è¨»å†Šï¼Œä½†æ‚¨å¯åŠ å…¥ Bing 網站管ç†å“¡å·¥å…·ä¾†æª¢æŸ¥æœç´¢çµ±è¨ˆã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3088 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:758 +msgid "Notify Ask.com about updates of your Blog" +msgstr "通知 Ask.com 關於您網站的更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3089 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:759 +msgid "No registration required." +msgstr "ä¸éœ€è¦è¨»å†Šã€‚" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3093 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:763 +msgid "Notify YAHOO about updates of your Blog" +msgstr "通知 YAHOO 關於您網站的更新" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:764 +msgid "Your Application ID:" +msgstr "æ‚¨çš„æ‡‰ç”¨ç¨‹å¼ ID:" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:765 +#, php-format +msgid "Don't you have such a key? Request one here! %s2" +msgstr "您沒有åƒä¸€å€‹é€™æ¨£çš„金鑰嗎? 請擊點此處申請! %s2" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:770 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "在虛擬 robots.txt 檔案中加入網站地圖ä½å€" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:774 +msgid "The virtual robots.txt generated by WordPress is used. A real robots.txt file must NOT exist in the blog directory!" +msgstr "此虛擬的 robots.txt 將會由 WordPress 來使用。真實的 robots.txt ä¸å¾—å­˜åœ¨æ–¼éƒ¨è½æ ¼çš„目錄中ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:777 +msgid "Advanced options:" +msgstr "進階é¸é …:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Limit the number of posts in the sitemap:" +msgstr "網站地圖裡文章數的最å°å€¼:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3124 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:780 +msgid "Newer posts will be included first" +msgstr "較新的文章將會優先包å«" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "Try to increase the memory limit to:" +msgstr "試著將記憶體é™åˆ¶å¢žåŠ è‡³ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:783 +msgid "e.g. \"4M\", \"16M\"" +msgstr "例如:「4Mã€ã€ã€Œ16Mã€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "Try to increase the execution time limit to:" +msgstr "試著將執行時間é™åˆ¶å¢žåŠ è‡³ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:786 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "以秒為單ä½ï¼Œä¾‹å¦‚:「60ã€æˆ–者「0ã€å‰‡ä¸é™åˆ¶" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:790 +msgid "Include a XSLT stylesheet:" +msgstr "åŒ…å« XSLT 樣å¼ï¼š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Full or relative URL to your .xsl file" +msgstr "您 .xsl æª”æ¡ˆçš„çµ•å°æˆ–者相å°è·¯å¾‘" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:791 +msgid "Use default" +msgstr "使用é è¨­" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:797 +msgid "Enable MySQL standard mode. Use this only if you're getting MySQL errors. (Needs much more memory!)" +msgstr "啟用 MySQL 標準模å¼ã€‚ç•¶æ‚¨ç™¼ç¾æœ‰ MySQL 錯誤時,å¯ä»¥ä½¿ç”¨æ­¤é¸é …。 (需è¦è¼ƒå¤šçš„記憶體!)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:798 +msgid "Upgrade WordPress at least to 2.2 to enable the faster MySQL access" +msgstr "如è¦é–‹å•Ÿè¼ƒå¿«çš„ MySQL å­˜å–,請至少將 WordPress å‡ç´šæˆ 2.2 版以上" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3166 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:805 +msgid "Build the sitemap in a background process (You don't have to wait when you save a post)" +msgstr "自動在背景程åºä¸­å»ºç«‹ç¶²ç«™åœ°åœ– (當儲存文章時,您就ä¸éœ€å†æ¬¡ç”¢ç”Ÿç¶²ç«™åœ°åœ–)" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:806 +msgid "Upgrade WordPress at least to 2.1 to enable background building" +msgstr "如è¦å•Ÿç”¨èƒŒæ™¯å»ºç«‹ç¶²ç«™åœ°åœ–,請至少將 WordPress å‡ç´šæˆ 2.1 版以上" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:813 +msgid "Additional pages" +msgstr "å…¶ä»–çš„é é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:816 +msgid "Here you can specify files or URLs which should be included in the sitemap, but do not belong to your Blog/WordPress.
        For example, if your domain is www.foo.com and your blog is located on www.foo.com/blog you might want to include your homepage at www.foo.com" +msgstr "您å¯ä»¥åœ¨æ­¤æŒ‡å®šé‚£äº›æ‡‰è¢«ç´å…¥ç¶²ç«™åœ°åœ–的檔案或者網å€ï¼Œä½†æ˜¯ä¸å±¬æ–¼æ‚¨çš„éƒ¨è½æ ¼(Blog/WordPress)。
        èˆ‰ä¾‹ä¾†èªªï¼Œè‹¥æ˜¯æ‚¨çš„éƒ¨è½æ ¼æ˜¯ www.foo.com/blog,而您想è¦å°‡æ‚¨ www.foo.com 下的網é ç´å…¥æ­¤ç¶²ç«™åœ°åœ–。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:818 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:997 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1011 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1020 +msgid "Note" +msgstr "注æ„" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:819 +msgid "If your blog is in a subdirectory and you want to add pages which are NOT in the blog directory or beneath, you MUST place your sitemap file in the root directory (Look at the "Location of your sitemap file" section on this page)!" +msgstr "è‹¥æ˜¯æ‚¨çš„éƒ¨è½æ ¼æ˜¯åœ¨å­ç›®éŒ„下而您想è¦å¢žåŠ çš„é é¢ä¸¦ä¸åœ¨éƒ¨è½æ ¼çš„目錄下é¢ï¼Œæ‚¨å¿…須將您的網站地圖置於網站的根目錄下。(請見本é ã€Œç¶²ç«™åœ°åœ–çš„ä½ç½®ã€å°ç¯€)ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:821 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:860 +msgid "URL to the page" +msgstr "é é¢ç¶²å€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:822 +msgid "Enter the URL to the page. Examples: http://www.foo.com/index.html or www.foo.com/home " +msgstr "輸入é é¢çš„ç¶²å€ã€‚例如:http://www.foo.com/index.html 或者 www.foo.com/home " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:824 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:861 +msgid "Priority" +msgstr "優先權 " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:825 +msgid "Choose the priority of the page relative to the other pages. For example, your homepage might have a higher priority than your imprint." +msgstr "鏿“‡è©²é é¢çš„優先權(相較於其他é é¢è€Œè¨€ï¼‰ã€‚ä¾‹å¦‚ï¼šæ‚¨çš„é¦–é æˆ–許會比版權說明é çš„優先權來得高。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:827 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:863 +msgid "Last Changed" +msgstr "最近更動" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:828 +msgid "Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) (optional)." +msgstr "輸入最近更動的日期,格å¼ç‚º YYYY-MM-DD(例如:2005-12-31)(éžå¿…è¦ï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:862 +msgid "Change Frequency" +msgstr "設定更新頻率" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:864 +msgid "#" +msgstr "#" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:869 +msgid "No pages defined." +msgstr "還沒有é é¢å·²è¢«è¨­å®š" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:874 +msgid "Add new page" +msgstr "新增é é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:879 +msgid "Post Priority" +msgstr "文章優先權 " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:881 +msgid "Please select how the priority of each post should be calculated:" +msgstr "è«‹é¸æ“‡æ¯ç¯‡æ–‡ç« æ‡‰è©²ç”¨å¤šå°‘優先權來計算:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:883 +msgid "Do not use automatic priority calculation" +msgstr "ä¸ä½¿ç”¨è‡ªå‹•優先權計算" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:883 +msgid "All posts will have the same priority which is defined in "Priorities"" +msgstr "所有的文章使用相åŒå®šç¾©åœ¨"優先權"內的優先權。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3348 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:894 +msgid "Location of your sitemap file" +msgstr "網站地圖的ä½ç½®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3353 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:897 +msgid "Automatic detection" +msgstr "自動ä½ç½®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3357 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:901 +msgid "Filename of the sitemap file" +msgstr "網站地圖的檔å" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:904 +msgid "Detected Path" +msgstr "嵿¸¬åˆ°çš„路徑" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3360 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:904 +msgid "Detected URL" +msgstr "嵿¸¬åˆ°çš„ç¶²å€" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3365 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:909 +msgid "Custom location" +msgstr "自定ä½ç½®" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3369 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:913 +msgid "Absolute or relative path to the sitemap file, including name." +msgstr "ç¶²ç«™åœ°åœ–çš„çµ•å°æˆ–相å°è·¯å¾‘,包括檔å。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3371 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3380 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:915 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:924 +msgid "Example" +msgstr "範例" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3378 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:922 +msgid "Complete URL to the sitemap file, including name." +msgstr "網站地圖的完整網å€ï¼ŒåŒ…括檔å。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:935 +msgid "Sitemap Content" +msgstr "網站地圖內容" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:941 +msgid "Include homepage" +msgstr "包å«é¦–é " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:947 +msgid "Include posts" +msgstr "åŒ…å«æ–‡ç« " + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:953 +msgid "Include following pages of multi-page posts (Increases build time and memory usage!)" +msgstr "包å«ä¸‹åˆ—é é¢çš„åˆ†é æ–‡ç«  (會增加建立時間åŠè¨˜æ†¶é«”使用é‡ï¼)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:959 +msgid "Include static pages" +msgstr "包å«ç¶²èªŒåˆ†é " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:965 +msgid "Include categories" +msgstr "包å«åˆ†é¡ž" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:971 +msgid "Include archives" +msgstr "包å«åŒ¯æ•´" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:978 +msgid "Include tag pages" +msgstr "åŒ…å«æ¨™ç±¤é é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:985 +msgid "Include author pages" +msgstr "包å«ä½œè€…é é¢" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:993 +msgid "Excluded items" +msgstr "排除的項目" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:995 +msgid "Excluded categories" +msgstr "排除的類型" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:997 +msgid "Using this feature will increase build time and memory usage!" +msgstr "使用此功能將會增加建立的時間åŠè¨˜æ†¶é«”使用é‡!" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1004 +#, php-format +msgid "This feature requires at least WordPress 2.5.1, you are using %s" +msgstr "æ­¤åŠŸèƒ½è‡³å°‘éœ€è¦ WordPress 2.5.1 版本,您目å‰ä½¿ç”¨çš„版本是 %s" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1007 +msgid "Exclude posts" +msgstr "åŒ…å«æ–‡ç« " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +msgid "Exclude the following posts or pages:" +msgstr "包å«ä¸‹åˆ—的文章或é é¢:" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1009 +msgid "List of IDs, separated by comma" +msgstr "列出 IDs,以逗號å€éš”。" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1011 +msgid "Child posts won't be excluded automatically!" +msgstr "å­æ–‡ç« ä¸æœƒè‡ªå‹•包å«ï¼" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1017 +msgid "Change frequencies" +msgstr "更新頻率設定" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1021 +msgid "Please note that the value of this tag is considered a hint and not a command. Even though search engine crawlers consider this information when making decisions, they may crawl pages marked \"hourly\" less frequently than that, and they may crawl pages marked \"yearly\" more frequently than that. It is also likely that crawlers will periodically crawl pages marked \"never\" so that they can handle unexpected changes to those pages." +msgstr "請注æ„下列å„設定值僅被視為æç¤ºè€Œéžå‘½ä»¤ã€‚é›–ç„¶æœå°‹å¼•擎漫éŠå™¨æœƒè€ƒæ…®é€™è³‡è¨Šåšå‡ºæ±ºå®šï¼Œä»–們也許會較少漫éŠè¢«æ¨™è¨˜ç‚ºã€ŒHourlyã€çš„é é¢ï¼Œæˆ–者更加頻ç¹åœ°æ¼«éŠè¢«æ¨™è¨˜ç‚ºã€ŒYearlyã€çš„é é¢ã€‚æœå°‹å¼•æ“Žæ¼«éŠæ©Ÿåˆ¶æœƒé€±æœŸæ€§åœ°æ¼«éŠè¢«æ¨™è¨˜ç‚ºã€ŒNeverã€çš„é é¢ï¼Œä»¥ä¾¿ä»–們能處ç†å°é‚£äº›é é¢çš„變動。" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1027 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1084 +msgid "Homepage" +msgstr "首é " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1033 +msgid "Posts" +msgstr "文章" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1039 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1102 +msgid "Static pages" +msgstr "網誌分é " + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1045 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1108 +msgid "Categories" +msgstr "分類" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1051 +msgid "The current archive of this month (Should be the same like your homepage)" +msgstr "ç¾æœ‰çš„æ¯æœˆå½™æ•´ï¼ˆæ‡‰è©²èˆ‡æ‚¨çš„é¦–é ç›¸åŒï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1057 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "è¼ƒèˆŠçš„å½™æ•´ï¼ˆåªæœ‰åœ¨æ‚¨ä¿®æ”¹èˆŠæ–‡ç« çš„æ™‚å€™æ‰æœƒæ”¹è®Šï¼‰" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1064 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1121 +msgid "Tag pages" +msgstr "標籤é é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1071 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1128 +msgid "Author pages" +msgstr "作者é é¢" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1079 +msgid "Priorities" +msgstr "優先權" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1090 +msgid "Posts (If auto calculation is disabled)" +msgstr "文章(如果自動計算沒有打開)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1096 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "優先權最å°å€¼ï¼ˆå³ä½¿è‡ªå‹•計算有打開)" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1114 +msgid "Archives" +msgstr "彙整" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1139 +msgid "Update options" +msgstr "æ›´æ–°é¸é …" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap-ui.php:1140 +msgid "Reset options" +msgstr "é‡ç½®é¸é …" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:84 +msgid "XML-Sitemap Generator" +msgstr "XML 網站地圖產生器" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:84 +msgid "XML-Sitemap" +msgstr "XML 網站地圖" + +#: H:\Webdev\htdocs\wp_plugins\sitemap_beta/sitemap.php:142 +msgid "Sitemap FAQ" +msgstr "網站地圖答客å•" + diff --git a/html/wp-content/plugins/google-sitemap-generator/lang/sitemap.pot b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap.pot new file mode 100644 index 0000000..ed33402 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/lang/sitemap.pot @@ -0,0 +1,919 @@ +# [Countryname] Language File for sitemap (sitemap-[localname].po) +# Copyright (C) 2005 [name] : [URL] +# This file is distributed under the same license as the WordPress package. +# [name] <[mail-address]>, 2005. +# $Id: sitemap.pot 918833 2014-05-21 17:56:43Z arnee $ +# +msgid "" +msgstr "" +"Project-Id-Version: sitemap\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-05-21 19:54+0100\n" +"PO-Revision-Date: 2014-05-21 19:54+0100\n" +"Last-Translator: Arne Brachhold \n" +"Language-Team: \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-KeywordsList: _e;__\n" +"X-Poedit-Basepath: .\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.6.4\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-SearchPath-0: C:\\Inetpub\\wwwroot\\wp_svn\\wp-content\\plugins" +"\\sitemap_beta\n" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:846 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:547 +msgid "Comment Count" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:858 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:557 +msgid "Uses the number of comments of the post to calculate the priority" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:918 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:608 +msgid "Comment Average" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:930 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:618 +msgid "Uses the average comment count to calculate the priority" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1118 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:778 +msgid "Always" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1119 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:779 +msgid "Hourly" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1120 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:780 +msgid "Daily" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1121 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:781 +msgid "Weekly" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1122 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:782 +msgid "Monthly" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1123 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:783 +msgid "Yearly" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-core.php:1124 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-core.php:784 +msgid "Never" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:233 +msgid "XML-Sitemap Generator" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2415 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:233 +msgid "XML-Sitemap" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:260 +msgid "Settings" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:261 +msgid "FAQ" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:262 +msgid "Support" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-loader.php:263 +msgid "Donate" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2635 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2835 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:181 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:663 +msgid "XML Sitemap Generator for WordPress" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2740 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:368 +msgid "Configuration updated" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2741 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:369 +msgid "Error while saving options" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2743 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:372 +msgid "Pages saved" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2744 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:373 +msgid "Error while saving pages" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2758 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:381 +msgid "The default configuration was restored." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:391 +msgid "" +"The old files could NOT be deleted. Please use an FTP program and delete " +"them by yourself." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:393 +msgid "The old files were successfully deleted." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:430 +msgid "Notify Search Engines about all sitemaps" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:431 +msgid "" +"The plugin is notifying the selected search engines about your main sitemap " +"and all sub-sitemaps. This might take a minute or two." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:453 +msgid "All done!" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:470 +msgid "Ping was executed, please see below for the result." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:513 +msgid "" +"Thank you very much for your donation. You help me to continue support and " +"development of this plugin and other free software!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2600 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:513 +msgid "Hide this notice" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:519 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin over a month ago. " +"If it works and you are satisfied with the results, isn't it worth at least " +"a few dollar? Donations help me to continue support and " +"development of this free software! Sure, no problem!" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:519 +msgid "Sure, but I already did!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2657 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:519 +msgid "No thanks, please don't bug me anymore!" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:526 +#, php-format +msgid "" +"Thanks for using this plugin! You've installed this plugin some time ago. If " +"it works and your are satisfied, why not rate it and recommend it to others? :-)" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:526 +msgid "Don't show this anymore" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:374 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:679 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:376 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:681 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here automatic upgrade unavailable for this plugin." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:378 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:683 +#, php-format +msgid "" +"There is a new version of %1$s available. Download version " +"%3$s here or upgrade automatically." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:691 +#, php-format +msgid "" +"Your blog is currently blocking search engines! Visit the privacy settings to change this." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2884 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:706 +msgid "About this Plugin:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2886 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:707 +msgid "Plugin Homepage" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:421 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:708 +msgid "Suggest a Feature" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:709 +msgid "Help / FAQ" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2887 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:710 +msgid "Notify List" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2888 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:711 +msgid "Support Forum" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap-ui.php:424 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:712 +msgid "Report a Bug" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2889 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:714 +msgid "Donate with PayPal" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2890 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:715 +msgid "My Amazon Wish List" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:716 +msgid "translator_name" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2891 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:716 +msgid "translator_url" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2895 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:719 +msgid "Sitemap Resources:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2897 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:720 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:725 +msgid "Webmaster Tools" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2898 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:721 +msgid "Webmaster Blog" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2901 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:723 +msgid "Search Blog" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3010 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:726 +msgid "Webmaster Center Blog" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2903 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:728 +msgid "Sitemaps Protocol" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2904 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:729 +msgid "Official Sitemaps FAQ" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2905 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:730 +msgid "My Sitemaps FAQ" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2910 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:733 +msgid "Recent Donations:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2914 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:736 +msgid "List of the donors" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2916 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:738 +msgid "Hide this list" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:2919 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:741 +msgid "Thanks for your support!" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:761 +msgid "Search engines haven't been notified yet" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:765 +msgid "Result of the last ping, started on %date%." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:772 +msgid "Recent Support Topics / News" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:776 +msgid "Disable" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:794 +msgid "No support topics available or an error occurred while fetching them." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:797 +msgid "" +"Support Topics have been disabled. Enable them to see useful information " +"regarding this plugin. No Ads or Spam!" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:797 +msgid "Enable" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:808 +#, php-format +msgid "" +"There is still a sitemap.xml or sitemap.xml.gz file in your blog directory. " +"Please delete them as no static files are used anymore or try " +"to delete them automatically." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:811 +#, php-format +msgid "The URL to your sitemap index file is: %s." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:814 +msgid "" +"Search engines haven't been notified yet. Write a post to let them know " +"about your sitemap." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:823 +#, php-format +msgid "%s was successfully notified about changes." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:826 +msgid "" +"It took %time% seconds to notify %name%, maybe you want to disable this " +"feature to reduce the building time." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:829 +msgid "" +"There was a problem while notifying %name%. View result" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:841 +#, php-format +msgid "" +"If you encounter any problems with your sitemap you can use the debug function to get more information." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:845 +#, php-format +msgid "" +"If you like the plugin, please rate it 5 " +"stars or donate via PayPal! I'm supporting this " +"plugin since over 9 years! Thanks a lot! :)" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:853 +msgid "Webserver Configuration" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:854 +msgid "" +"Since you are using Nginx as your web-server, please configure the following " +"rewrite rules in case you get 404 Not Found errors for your sitemap:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3040 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:870 +msgid "Basic Options" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:872 +msgid "Update notification:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3044 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3059 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3079 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3104 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:872 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:895 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:917 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:929 +msgid "Learn more" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3083 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:876 +msgid "Notify Google about updates of your Blog" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3084 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:877 +#, php-format +msgid "" +"No registration required, but you can join the Google " +"Webmaster Tools to check crawling statistics." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:881 +msgid "Notify Bing (formerly MSN Live Search) about updates of your Blog" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:882 +#, php-format +msgid "" +"No registration required, but you can join the Bing Webmaster " +"Tools to check crawling statistics." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:887 +msgid "Add sitemap URL to the virtual robots.txt file." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:891 +msgid "" +"The virtual robots.txt generated by WordPress is used. A real robots.txt " +"file must NOT exist in the blog directory!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3121 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:895 +msgid "Advanced options:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:898 +msgid "Try to increase the memory limit to:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3127 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:898 +msgid "e.g. \"4M\", \"16M\"" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:901 +msgid "Try to increase the execution time limit to:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3130 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:901 +msgid "in seconds, e.g. \"60\" or \"0\" for unlimited" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:906 +msgid "" +"Try to automatically compress the sitemap if the requesting client supports " +"it." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:908 +msgid "" +"Disable this option if you get garbled content or encoding errors in your " +"sitemap." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:912 +msgid "Include a XSLT stylesheet:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3133 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:913 +msgid "Full or relative URL to your .xsl file" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:913 +msgid "Use default" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:916 +msgid "Override the base URL of the sitemap:" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:917 +msgid "" +"Use this if your blog is in a sub-directory, but you want the sitemap be " +"located in the root. Requires .htaccess modification." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:922 +msgid "Include sitemap in HTML format" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:922 +msgid "(The required PHP XSL Module is not installed)" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:928 +msgid "Allow anonymous statistics (no personal information)" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3144 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:937 +msgid "Additional pages" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3149 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:940 +msgid "" +"Here you can specify files or URLs which should be included in the sitemap, " +"but do not belong to your Blog/WordPress.
        For example, if your domain " +"is www.foo.com and your blog is located on www.foo.com/blog you might want " +"to include your homepage at www.foo.com" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3151 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3462 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:942 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1156 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1165 +msgid "Note" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3152 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:943 +msgid "" +"If your blog is in a subdirectory and you want to add pages which are NOT in " +"the blog directory or beneath, you MUST place your sitemap file in the root " +"directory (Look at the "Location of your sitemap file" section on " +"this page)!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3154 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3300 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:945 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:984 +msgid "URL to the page" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3155 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:946 +msgid "" +"Enter the URL to the page. Examples: http://www.foo.com/index.html or www." +"foo.com/home " +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3157 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3301 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:948 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:985 +msgid "Priority" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3158 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:949 +msgid "" +"Choose the priority of the page relative to the other pages. For example, " +"your homepage might have a higher priority than your imprint." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3160 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3303 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:951 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:987 +msgid "Last Changed" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3161 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:952 +msgid "" +"Enter the date of the last change as YYYY-MM-DD (2005-12-31 for example) " +"(optional)." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3302 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:986 +msgid "Change Frequency" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3304 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:988 +msgid "#" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3309 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:993 +msgid "No pages defined." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3314 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:998 +msgid "Add new page" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3325 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1004 +msgid "Post Priority" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3329 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1006 +msgid "Please select how the priority of each post should be calculated:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1008 +msgid "Do not use automatic priority calculation" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3331 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1008 +msgid "" +"All posts will have the same priority which is defined in "" +"Priorities"" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3397 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1019 +msgid "Sitemap Content" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1020 +msgid "WordPress standard content" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3405 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1025 +msgid "Include homepage" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3411 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1031 +msgid "Include posts" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3417 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1037 +msgid "Include static pages" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3423 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1043 +msgid "Include categories" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3429 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1049 +msgid "Include archives" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3443 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1055 +msgid "Include author pages" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3436 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1062 +msgid "Include tag pages" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1076 +msgid "Custom taxonomies" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1087 +#, php-format +msgid "Include taxonomy pages for %s" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1105 +msgid "Custom post types" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1116 +#, php-format +msgid "Include custom post type %s" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1128 +msgid "Further options" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1133 +msgid "Include the last modification time." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1135 +msgid "" +"This is highly recommended and helps the search engines to know when your " +"content has changed. This option affects all sitemap entries." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1142 +msgid "Excluded items" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1144 +msgid "Excluded categories" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1152 +msgid "Exclude posts" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1154 +msgid "Exclude the following posts or pages:" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3206 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1154 +msgid "List of IDs, separated by comma" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1156 +msgid "Child posts won't be excluded automatically!" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3457 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1162 +msgid "Change frequencies" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3463 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1166 +msgid "" +"Please note that the value of this tag is considered a hint and not a " +"command. Even though search engine crawlers consider this information when " +"making decisions, they may crawl pages marked \"hourly\" less frequently " +"than that, and they may crawl pages marked \"yearly\" more frequently than " +"that. It is also likely that crawlers will periodically crawl pages marked " +"\"never\" so that they can handle unexpected changes to those pages." +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3469 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3535 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1172 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1229 +msgid "Homepage" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3475 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1178 +msgid "Posts" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3481 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3553 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1184 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1247 +msgid "Static pages" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3487 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3559 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1190 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1253 +msgid "Categories" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3493 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1196 +msgid "" +"The current archive of this month (Should be the same like your homepage)" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3499 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1202 +msgid "Older archives (Changes only if you edit an old post)" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3506 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3572 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1209 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1266 +msgid "Tag pages" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3513 +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3579 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1216 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1273 +msgid "Author pages" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3527 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1224 +msgid "Priorities" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3541 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1235 +msgid "Posts (If auto calculation is disabled)" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3547 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1241 +msgid "Minimum post priority (Even if auto calculation is enabled)" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3565 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1259 +msgid "Archives" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3590 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1284 +msgid "Update options" +msgstr "" + +# C:\Inetpub\wwwroot\wp\wp-content\plugins\sitemap_beta/sitemap.php:3591 +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap-ui.php:1285 +msgid "Reset options" +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:85 +msgid "Your WordPress version is too old for XML Sitemaps." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:85 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least " +"WordPress %4$s. You are using Wordpress %2$s, which is out-dated and " +"insecure. Please upgrade or go to active plugins and " +"deactivate the Google XML Sitemaps plugin to hide this message. You can " +"download an older version of this plugin from the plugin " +"website." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:95 +msgid "Your PHP version is too old for XML Sitemaps." +msgstr "" + +#: C:\Inetpub\wwwroot\wp_svn\wp-content\plugins\sitemap_beta/sitemap.php:95 +#, php-format +msgid "" +"Unfortunately this release of Google XML Sitemaps requires at least PHP " +"%4$s. You are using PHP %2$s, which is out-dated and insecure. Please ask " +"your web host to update your PHP installation or go to active plugins and deactivate the Google XML Sitemaps plugin to hide " +"this message. You can download an older version of this plugin from the plugin website." +msgstr "" diff --git a/html/wp-content/plugins/google-sitemap-generator/license.txt b/html/wp-content/plugins/google-sitemap-generator/license.txt new file mode 100644 index 0000000..ecbc059 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/license.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/html/wp-content/plugins/google-sitemap-generator/readme.txt b/html/wp-content/plugins/google-sitemap-generator/readme.txt new file mode 100644 index 0000000..4018cfb --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/readme.txt @@ -0,0 +1,636 @@ +=== XML Sitemap Generator for Google === +Contributors: auctollo +Tags: SEO, xml sitemap, video sitemap, news sitemap, html sitemap +Requires at least: 4.6 +Tested up to: 6.9 +Stable tag: 4.1.23 +Requires PHP: 5.0 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Generate multiple types of sitemaps to improve SEO and get your website indexed quickly. + +== Description == + +Generate XML and HTML sitemaps for your website with ease using the XML Sitemap Generator for Google. This plugin enables you to improve your SEO rankings by creating page, image, news, video, HTML, and RSS sitemaps. It also supports custom post types and taxonomies, allowing you to ensure that all of your content is being indexed by search engines. With a user-friendly interface, you can easily configure the plugin to suit your needs and generate sitemaps in just a few clicks. Keep your website up-to-date and make sure that search engines are aware of all of your content by using the XML Sitemap Generator for Google. + +The plugin supports all kinds of WordPress generated pages as well as custom URLs. Additionally it notifies all major search engines every time you create a post about the new content. + +Supported for more than a decade and [rated among the best](https://wordpress.org/plugins/browse/popular/page/2/#:~:text=XML%20Sitemap%20Generator%20for%20Google), it will do exactly what it's supposed to do - providing a complete XML sitemap for search engines! + +> If you like the plugin, feel free to rate it! :) + +Related Links: + +* Support Forum + +== Installation == + +1. Deactivate or disable other sitemap generators. +2. Install the plugin like you always install plugins, either by uploading it via FTP or by using the "Add Plugin" function of WordPress. +3. Activate the plugin on the plugin administration page +4. If you want: Open the plugin configuration page, which is located under Settings -> XML-Sitemap and customize settings like priorities and change frequencies. +5. The plugin will automatically update your sitemap if you publish new content, so there is nothing more to do :) + +== Frequently Asked Questions == + += How do I generate a sitemap for my website? = + +To generate a sitemap for your website, follow these steps: + +* Install and activate the XML Sitemap Generator for Google plugin on your WordPress site. +* Once activated, the plugin will automatically generate a sitemap.xml file for your website. +* You can access the sitemap by appending `/sitemap.xml` to your website's URL (e.g., [https://example.com/sitemap.xml](#)). +* Submit your sitemap to search engines like Google, Bing, Yandex, and Baidu to ensure that your site is indexed and crawled properly. + += How do I submit my sitemap to search engines? = + +* Go to the Google Search Console and sign in with your Google account. +* Click on the "Sitemaps" tab and enter the URL of your sitemap.xml file (e.g., [https://example.com/sitemap.xml](#)). +* Click on "Submit" to submit your sitemap to Google. +* Repeat the process for other search engines like Bing, Yandex, and Baidu. + += How often should I update my sitemap? = + +It's recommended that you update your sitemap whenever you make significant changes to your website's content or structure. This will ensure that search engines are aware of any new pages or changes to existing pages on your site. + += What types of sitemaps does the plugin generate? = + +The XML Sitemap Generator for Google plugin can generate sitemaps in XML, HTML, RSS formats and in various types, including: Pages/Posts, Google News, Video, Image, Mobile, and more! Note: Some formats and types are only available to subscribers. + += Can I include images and videos in my sitemap? = + +Yes, you can include images and videos in your sitemap using the Google XML Sitemap Generator plugin. This will help search engines like Google and Bing to crawl and index your media files more efficiently. + += How does the plugin work with WooCommerce? = + +The XML Sitemap Generator for Google plugin is compatible with WooCommerce and can generate sitemaps for your online store's product pages, categories, and tags. This will help search engines to index your products and improve your store's visibility in search results. + += Can I customize the robots.txt file using this plugin? = + +Yes, you can customize the robots.txt file using the Google XML Sitemap Generator for Google plugin. This will allow you to control which pages and directories search engines can crawl and index on your site. + += Does this plugin support the Google Site Kit? = + +Yes, the XML Sitemap Generator for Google plugin is compatible with the Google Site Kit. This will allow you to track your site's performance in Google Search Console and Google Analytics directly from your WordPress dashboard. + += Does this plugin support schema markup? = + +Yes, the XML Sitemap Generator for Google plugin supports schema markup, which can help improve your site's visibility in search results by providing more information about your content to search engines. + += Where can I find the options page of the plugin? = + +It is under Settings > XML-Sitemap. I know nowadays many plugins add top-level menu items, but in most of the cases it is just not necessary. I've seen WP installations which looked like an Internet Explorer ten years ago with 20 toolbars installed. ;-) + += Does this plugin use static files or "I can't find the sitemap.xml file!" = + +Not anymore. Since version 4, these files are dynamically generated just like any other WordPress content. + += There are no comments yet (or I've disabled them) and all my postings have a priority of zero! = + +Please disable automatic priority calculation and define a static priority for posts. + += So many configuration options... Do I need to change them? = + +No, only if you want to. Default values are ok for most sites. + += My question isn't answered here = + +Please post your question at the [WordPress support forum](https://wordpress.org/support/plugin/google-sitemap-generator/). + + +== Changelog == + += 4.1.22 (2026-02-09) = +* Improved security further for unauthenticated users from modifying plugin settings by enforcing proper permission and security‑token checks. CVE-2025-64632 + += 4.1.22 (2025-12-23) = +* Fixed preventing unauthenticated users from modifying plugin settings by enforcing proper permission and security‑token checks. + += 4.1.21 (2024-04-21) = +* Fixed a regression with saving post/page exclusions. +* Fixed an issue with post/tag priority settings. + += 4.1.20 (2024-04-14) = +* Fixed empty ping error +* Fixed response code issue with index sitemap +* Fixed interoperability with existing robots.txt file +* Fixed URL for guest authors +* Fixed uninstalled plugin error +* Fixed sitemap indexation +* Fixed "Trying to access array offset on value of type bool..." warning +* Fixed setting of custom taxonomy change frequency and priority +* Fixed missing custom taxonomies issue +* Fixed issue with hierarchical taxonomies +* Fixed missing categories issue +* Fixed sort order of URLs (changed from descending to ascending) +* Improved WooCommerce support (added products sitemap) +* Improved multisite support +* Improved SEO plugin interoperability +* Improved Nginx configuration +* Improved sitemap generation performance for large sites +* Added [filter support](https://auctollo.com/products/google-xml-sitemap-generator/help/#:~:text=not%20be%20useful.-,Filters,-Customize%20the%20behavior) for behavior/settings customization +* Added latest Microsoft Bing API Key to settings page + += 4.1.19 (2024-01-31) = +* Fixed "Links per page" bug causing sitemaps to not include all posts depending on the setting. Following Search Engine guidance is minimum links per sitemap is 1,000 pages. +* Fixed Google Search Console errors including "Fetch error" and "noindex" header +* Fixed the issue with "null" sitemaps +* Fixed sitemap generation for tags, categories, etc for large sites +* Improved performance by optimizing queries +* Improved IndexNow implementation +* Added WordPress' sitemap to the list of detected sitemaps for deactivation + += 4.1.18 (2024-01-12) = +* Resolved functionality regressions since v4.1.13 +* Improved IndexNow Protocol implementation +* Improved WooCommerce support +* Improved WPML support +* Fixed sitemap 404 issues (for Single and Multisite modes) +* Fixed auto update rewrite rule +* Fixed rewrite issues during plugin upgrade +* Fixed invalid XML syntax (cause of parsing issues in Google Search Console) + += 4.1.17 (2024-01-05) = +* Fixed sitemap URL issue in robots.txt etc +* Improved LastMod syntax for better support for indexation by Google +* Improved Network mode support +* Improved localization plugin support +* Improved custom taxonomy support +* Added IndexNow Protocol support for Microsoft Bing. Deprecated Sitemap Ping Protocol +* Added JetPack sitemap generator conflict detection + += 4.1.16 (2023-12-18) = +* Fixed a syntax error causing fatal errors for some users. + += 4.1.15 (2023-12-14) = +* Improved security by adding capability check via the current_user_can() calls +* Changed the text domain from "sitemap" to "google-sitemap-generator" + += 4.1.14 (2023-12-05) = +* Improved security with authentication and plugin management anchors +* Fixed an error in sitemap file name conventions +* Fixed an issue with disabling conflicting sitemap generators +* Added last modified date to category sitemaps +* Added min and max option for number of posts per sitemap +* Added support for local links in sitemap for different languages + += 4.1.13 (2023-08-04) = +* Fixed warning error displayed when Yoast SEO is not installed/active + += 4.1.12 (2023-08-02) = +* Improved various UI elements and notifications +* Fixed browser console errors +* Fixed null value in set_time_limit + += 4.1.11 (2023-05-19) = +* Fixed version compatibility thresholds +* Improved user interface + += 4.1.10 (2023-04-24) = +* Added support for automatic updates + += 4.1.9 (2023-04-12) = +* Improved beta program notifications and workflow to comply with guidelines +* Improved various UI elements + += 4.1.8 (2023-03-31) = +* Added Beta testing program +* Added check for disabled PHP functions +* Fixed handling of taxonomies containing hyphens + += 4.1.7 (2022-11-24) = +* Fixed custom taxonomy unit generation issue +* Fixed plugin deactivation notice + += 4.1.6 (2022-11-23) = +* Fixed mishandling of empty categories +* Fixed _url undefined notice error +* Fixed error when build_taxonomies throws a fatal error when accessing sub-sitemap without pagination +* Improved handling of line breaks e.g. showing
        tag without escaping HTML +* Improved handling of the Google TID field optional to ping Google +* Improved documentation, given some renaming of the methods +* Added support for paginated sitemap posts, pages, and product links +* Added conditional statements to prevent rewrite rules from being checked every time the sitemap loads + += 4.1.5 (2022-06-14) = +* Fixed code regressions moving from git to svn (preventing recent fixes from being available) + += 4.1.4 (2022-06-06) = +* Fixed the issue of PHP warnings +* Fixed links per page issue +* Improved WordPress 6.0 compatibility + += 4.1.3 (2022-05-31) = +* Added backward compatibility settings +* Changed Google Tracking ID field to optional +* Fixed PHP warnings + += 4.1.2 (2022-04-15) = +* Fixed security issue related to Cross-Site Scripting attacks on debug page +* Fixed HTTP error while generating sitemap (because of conflict of www and now www site) +* Fixed handling WordPress core sitemap entry from robots.txt +* Added option to flush database rewrite on plugin deactivation +* Added option to split the custom categories into multiple sitemaps by custom taxonomy +* Added option to omit the posts specified as disallow in robots.txt +* Added option to set links per page for tags and categories +* Added option to set a custom filename for the sitemap +* Added option to list custom post in the archive sitemap + += 4.1.1 (2022-04-07) = +* fix security issue related to Cross-Site Scripting attacks on debug page +* fix HTTP error while generating sitemap (because of conflict of www and now www site) +* fix handles the removal of Wordpress native sitemap entry from robots.txt +* added option for flush database rewrite on deactivate plugin +* added options for split the custom categories into multiple sitemap by custom taxonomy +* added options to omit the posts which added in robots.txt to disallow +* added option to set links per page for tags and categories +* added option for provide the custom name for the sitemap.xml file +* added option for custom post type's list into the archive sitemap +* added support of manage priorities and frequencies for products category + += 4.1.0 (2018-12-18) = +* Fixed security issue related to escaping external URLs +* Fixed security issue related to option tags in forms + += 4.0.9 (2017-07-24) = +* Fixed security issue related to donation functionality. + += 4.0.8 (2014-11-15) = +* Fixed bug regarding the exclude categories feature, thanks to Claus Schöffel! + += 4.0.7.1 (2014-09-02) = +* Sorry, no new features this time… This release only updates the Compatibility-Tag to WordPress 4.0. Unfortunately there is no way to do this anymore without a new version + += 4.0.7 (2014-06-23) = +* Better compatibility with GoDaddy managed WP hosting +* Better compatibility with QuickCache +* Removed WordPress version from the sitemap +* Corrected link to WordPress privacy settings (if search engines are blocked) +* Changed hook which is being used for sitemap pings to avoid pings on draft edit + += 4.0.6 (2014-06-03) = +* Added option to disable automatic gzipping +* Fixed bug with duplicated external sitemap entries +* Don’t gzip if behind Varnish since Varnish can do that + += 4.0.5 (2014-05-18) = +* Added function to manually start ping for main-sitemap or all sub-sitemaps +* Added support for changing the base of the sitemap URL to another URL (for WP installations in sub-folders) +* Fixed issue with empty post sitemaps (related to GMT/local time offset) +* Fixed some timing issues in archives +* Improved check for possible problems before gzipping +* Fixed empty archives and author sitemaps in case there were no posts +* Fixed bug which caused the Priority Provider to disappear in recent PHP versions +* Plugin will also ping with the corresponding sub-sitemap in case a post was modified +* Better checking for empty external urls +* Changed text in XSL template to be more clear about sitemap-index and sub-sitemaps +* Changed content type to text/xml to improve compatibility with caching plugins +* Changed query parameters to is_feed=true to improve compatibility with caching plugins +* Switched from using WP_Query to load posts to a custom SQL statement to avoid problems with other plugin filters +* Added caching of some SQL statements +* Added support feed for more help topics +* Added link to new help page +* Cleaned up code and renamed variables to be more readable +* Updated Japanese Translation, thanks to Daisuke Takahashi + += 4.0.4 (2014-04-19) = +* Removed deprecated get_page call +* Changed last modification time of sub-sitemaps to the last modification date of the posts instead of the publish date +* Removed information window if the statistic option has not been activated +* Added link regarding new sitemap format +* Updated Portuguese translation, thanks to Pedro Martinho +* Updated German translation + += 4.0.3 (2014-04-13) = +* Fixed compression if an gzlib handler was already active +* Help regarding permalinks for Nginx users +* Fix with gzip compression in case there was other output before already +* Return 404 for HTML sitemaps if the option has been disabled +* Updated translations + += 4.0.2 (2014-04-01) = +* Fixed warning if an gzip handler is already active + += 4.0.1 (2014-03-31) = +* Fixed bug with custom post types including a "-" +* Fixed some 404 Not Found Errors + += 4.0 (2014-03-30) = +* No static files anymore, sitemap is created on the fly! +* Sitemap is split-up into sub-sitemaps by month, allowing up to 50.000 posts per month! [More information](http://www.arnebrachhold.de/projects/wordpress-plugins/google-xml-sitemaps-generator/google-xml-sitemap-generator-new-sitemap-format/) +* Support for custom post types and custom taxonomis! +* 100% Multisite compatible, including by-blog and network activation. +* Reduced server resource usage due to less content per request. +* New API allows other plugins to add their own, separate sitemaps. +* Note: PHP 5.1 and WordPress 3.3 is required! The plugin will not work with lower versions! +* Note: This version will try to rename your old sitemap files to *-old.xml. If that doesn’t work, please delete them manually since no static files are needed anymore! + += 3.4.1 (2014-04-10) = +* Compatibility with mysqli + += Version 3.4 (2013-11-24) = +* Fixed deprecation warnings in PHP 5.4, thanks to Dion Hulse! + += 3.3 (2013-09-28) = +* Fixed problem with file permission checking +* Filter out hashs (#) in URLs + += 3.2.9 (2013-01-11) = +* Fixed security issue with change frequencies and filename of sitemap file. Exploit was only possible with admin account. + += 3.2.8 (2012-08-08) = +* Fixed wrong custom taxonomy URLs, thanks to ramon fincken of the wordpress.org forum! +* Removed ASK ping since they shut down their service. +* Exclude post_format taxonomy from custom taxonomy list + += 3.2.7 (2012-04-24) = +* Fixed custom post types, thanks to clearsite of the wordpress.org forum! +* Fixed broken admin layout on WP 3.4 + += 3.2.6 (2011-09-19) = +* Removed YAHOO ping since YAHOO uses bing now +* Removed deprecated function call + += 3.2.5 (2011-07-11) = +* Backported Bing ping success fix from beta +* Added friendly hint to try out the new beta + += 3.2.4 (2010-05-29) = +* Added (GMT) to date column in sitemap xslt template to avoid confusion with different time zones +* Fixed wrong SQL statement for author pages, thanks to twoenoug +* Fixed several deprecated function calls +* Note: This release does not support the new multisite feature of WordPress yet and will not be active when multisite is enabled. + += 3.2.3 (2010-04-02) = +* Fixed that all pages were missing in the sitemap if the “Uncategorized†category was excluded + += 3.2.2 (2009-12-19) = +* Updated compatibility tag to WordPress 2.9 +* Fixed PHP4 problems + += 3.2.1 (2009-12-16) = +* Notes and update messages at the top of the admin page could interfere with the manual build function +* Help links in the WP contextual help were not shown anymore since the last update +* IE 7 sometimes displayed a cached admin page +* Removed invalid link to config page from the plugin description (The link lead to a "Not enough permission error") +* Improved performance of getting the current plugin version by caching +* Updated Spanish language files + += 3.2 (2009-11-23) = +* Added function to show the actual results of a ping instead of only linking to the url +* Added new hook (sm_rebuild) for third party plugins to start building the sitemap +* Fixed bug which showed the wrong URL for the latest Google ping result +* Added some missing documentation +* Removed hardcoded php name for sitemap file in admin urls +* Uses KSES for showing ping test results +* Ping test fixed for WP < 2.3 + += 3.1.9 (2009-11-13) = +* Fixed MySQL Error if author pages were included + += 3.1.8 (2009-11-07) = +* Improved custom taxonomy handling and fixed wrong last modification date +* Fixed fatal error in WordPress versions lower than 2.3 +* Fixed Update Notice for WordPress 2.8 and higher +* Added warning if blog privacy is activated +* Fixed priorities of additional pages were shown as 0 instead of 1 + += 3.1.7 (2009-10-21) = +* Added support for custom taxonomies. Thanks to Lee! + += 3.1.6 (2009-08-31) = +* Fixed PHP error “Only variables can be passed by reference†+* Fixed wrong URLS of multi-page posts (Thanks artstorm!) +* Updated many language files + += 3.1.5 (2009-08-24) = +* Added option to completely disable the last modification time +* Fixed problem with HTTPS url for the XSL stylesheet if the sitemap was build via the admin panel +* Improved handling of homepage entry if a single page was set for it +* Fixed mktime warning which appeared sometimes +* Fixed bug which caused inf. reloads after rebuilding the sitemap via the admin panel +* Improved handling of missing sitemaps files if WP was moved to another location + += 3.1.4 (2009-06-22) = +* Fixed bug which broke all pings in WP older than 2.7 +* Added more output in debug mode if pings fail +* Moved global post variable so other plugins can use it in get_permalink() +* Added small icon for ozh admin menu +* Added more help links in UI + += 3.1.3 (2009-06-07) = +* Changed MSN Live Search to Bing +* Exclude categories also now exludes the category itself and not only the posts +* Pings now use the new WordPress HTTP API instead of Snoopy +* Fixed bug that in localized WP installations priorities could not be saved +* The sitemap cron job is now cleared after a manual rebuild or after changing the config +* Adjusted style of admin area for WP 2.8 and refreshed icons +* Disabled the “Exclude categories†feature for WP 2.5.1, since it doesn’t have the required functions yet + += 3.1.2 (2008-12-26) = +* Changed the way the stylesheet is saved (default / custom stylesheet) +* Sitemap is now rebuild when a page is published +* Removed support for static robots.txt files, this is now handled via WordPress functions +* Added compat. exceptions for WP 2.0 and WP 2.1 + += 3.1.1 (2008-12-21) = +* Fixed redirect issue if wp-admin is rewritten via mod_rewrite, thanks to macjoost +* Fixed wrong path to assets, thanks PozHonks +* Fixed wrong plugin URL if wp-content was renamed / redirected, thanks to wnorris +* Updated WP User Interface for 2.7 +* Various other small things + += 3.1.0.1 (2008-05-27) = +* Extracted UI JS to external file +* Enabled the option to include following pages of multi-page posts +* Script tries to raise memory and time limit if active + += 3.1 (2008-05-22) = +* Marked as stable + += 3.1b3 (2008-05-19) = +* Cleaned up plugin directory and moved img files to subfolders +* Fixed background building bug in WP 2.1 +* Removed auto-update plugin link for WP < 2.5 + += 3.1b2 (2008-05-18) = +* Fixed critical bug with the build in background option +* Added notification if a build is scheduled + += 3.1b1 (2008-05-08) = +* Splitted plugin in loader, generator and user interface to save memory +* Generator and UI will only be loaded when needed +* Secured all admin actions with nonces +* Improved WP 2.5 handling +* New "Suggest a Feature" link + += 3.0.3.3 (2008-04-29) = +* Fixed author pages +* Enhanced background building and increased delay to 15 seconds +* Enabled background building by default + += 3.0.3.2 (2008-04-28) = +* Improved WP 2.5 handling (fixes blank screens and timeouts) + += 3.0.3.1 (2008-03-30) = +* Added compatibility CSS for WP 2.5 + += 3.0.3 (2007-12-30) = +* Added option to ping MSN Live Search +* Removed some WordPress hooks (the sitemap isn’t updates with every comment anymore) + += 3.0.2.1 (2007-11-28) = +* Fixed wrong XML Schema Location (Thanks to Emanuele Tessore) +* Added Russian Language files by Sergey http://ryvkin.ru + += 3.0.2 (2007-11-25) = +* Fixed bug which caused that some settings were not saved correctly +* Added option to exclude pages or post by ID +* Restored YAHOO ping service with API key since the other one is to unreliable + += 3.0.1 (2007-11-03) = +* Changed HTTP client for ping requests to Snoopy +* Added "safemode" for SQL which doesn’t use unbuffered results +* Added option to run the building process in background using wp-cron +* Added links to test the ping if it failed + += 3.0 final (2007-09-24) = +* Marked as stable +* Removed useless functions + += 3.0b11 (2007-09-23) = +* Changed mysql queries to unbuffered queries +* Uses MUCH less memory +* Option to limit the number of posts + += 3.0b10 (2007-09-04) = +* Added category support for WordPress 2.3 +* Fixed bug with empty URLs in sitemap +* Repaired GET building + += 3.0b9 (2007-09-02) = +* Added tag support for WordPress 2.3 +* Fixed archive bug with static pages (Thanks to Peter Claus Lamprecht) +* Fixed some missing translation strings, thanks to Kirin Lin + += 3.0b8 (2007-07-22) = +* Fixed bug with empty categories +* Fixed bug with translation plugins +* Added support for robots.txt +* Switched YAHOO ping API from YAHOO Web Services to the “normal†ping service +* Search engines will only be pinged if the sitemap file has changed + += 3.0b7 (2007-05-17) = +* Added Ask.com notification +* Added option to include the author pages like /author/john +* Fixed WP 2.1 / Pre 2.1 post / pages database changes +* Added check to not build the sitemap if importing posts +* Fixed wrong XSLT location (Thanks froosh) +* Small enhancements and bug fixes + += 3.0b6 (2007-01-23) = +* sitemap.xml.gz was not compressed +* YAHOO update-notification was PHP5 only (Thanks to Joseph Abboud!) +* More WP 2.1 optimizations +* Reduced memory usage with PHP5 + += 3.0b5 (2007-01-19) = +* WordPress 2 Design +* YAHOO update notification +* New status report, removed ugly logfiles +* Added option to define a XSLT stylesheet and added a default one +* Fixed bug with sub-pages, thanks to [Mike](http://baptiste.us/), [Peter](http://fastagent.de/) and [Glenn](http://publicityship.com.au/) +* Improved file handling, thanks to [VJTD3](http://www.vjtd3.com/) +* WP 2.1 improvements + += 3.0b4 (2006-11-16) = +* Fixed some smaller bugs +* Decreased memory usage which should solve timeout and memory problems +* Updated namespace to support YAHOO and MSN + += 3.0b2 (2006-01-14) = +* Fixed several bugs reported by users + += 3.0b (2005-11-25) = +* WordPress 2.0 (Beta, RC1) compatible +* Added different priority calculation modes and introduced an API to create custom ones (Some people didn’t like the way to calculate the post priority based on the count of user comments. This will give you the possibility to develop custom priority providers which fit your needs.) +* Added support to use the [Popularity Contest](http://www.alexking.org/blog/2005/07/27/popularity-contest-11/) plugin by [Alex King](http://www.alexking.org/) to calculate post priority (If you are already using the Popularity Contest plugin, this will be the best way to determine the priority of the posts. Uses to new priority API noted above.) +* Added option to exclude password protected posts (This was one of the most requested features.) +* Posts and pages marked for publish with a date in the future won’t be included +* Added function to start sitemap creation via GET and a secret key (If you are using external software which directly writes into the database without using the WordPress API, you can rebuild the sitemap with a simple HTTP Request. This can be made with a cron job for example.) +* Improved compatibility with other plugins (There should no longer be problems with other plugins now which checked for existence of a specified function to determine if you are in the control panel or not.) +* Recoded plugin architecture which is now fully OOP (The code is now cleaner and better to understand which makes it easier to modify. This should also avoid namespace problems.) +* Improved speed and optimized settings handling (Settings and pages are only loaded if the sitemap generation process starts and not every time a page loads. This saves one MySQL Query on every request.) +* Added Button to restore default configuration (Messed up the config? You’ll need just one click to restore all settings.) +* Added log file to check everything is running (In the new log window you can see when your sitemap was rebuilt or if there was any error.) +* Improved user-interface +* Added several links to homepage and support (This includes the Notify List about new releases and the WordPress support forum.) + += 2.7 (2005-11-25) = +* Added Polish Translation by [kuba](http://kubazwolinski.com/) + += 2.7 (2005-11-01) = +* Added French Translation by [Thierry Lanfranchi](http://www.chezthierry.info/) + += 2.7 (2005-07-21) = +* Fixed bug with incorrect date in additional pages (wrong format) +* Added Swedish Translation by [Tobias Bergius](http://tobiasbergius.se/) + += 2.6 (2005-07-16) = +* Included Chinese (Simplified) language files by [june6](http://www.june6.cn/) + += 2.6 (2005-07-04) = +* Added support to store the files at a custom location +* Changed the home URL to have a slash at the end +* Fixed errors with wp-mail +* Added support for other plugins to add content to the sitemap + += 2.5 (2005-06-15) = +* You can include now external pages which aren’t generated by WordPress or are not recognized by this plugin +* You can define a minimum post priority, which will overrride the calculated value if it’s too low +* The plugin will automatically ping Google whenever the sitemap gets regenerated +* Update 1: Included Spanish translations by [Cesar Gomez Martin](http://www.cesargomez.org/) +* Update 2: Included Italian translations by [Stefano Aglietti](http://wordpress-it.it/) +* Update 3: Included Traditional Chinese translations by [Kirin Lin](http://kirin-lin.idv.tw/) + += 2.2 (2005-06-08) = +* Language file support: [Hiromasa](http://hiromasa.zone.ne.jp/) from [http://hiromasa.zone.ne.jp](http://hiromasa.zone.ne.jp/) sent me a japanese version of the user interface and modified the script to support it! Thanks for this! Check [the WordPress Codex](http://codex.wordpress.org/WordPress_Localization) how to set the language in WordPress. +* Added Japanese user interface by [Hiromasa](http://hiromasa.zone.ne.jp/) +* Added German user interface by me + += 2.12 (2005-06-07) = +* Changed SQL Statement for categories that it also works on MySQL 3 + += 2.11 (2005-06-07) = +* Fixed a hardcoded tablename which made a SQL error + += 2.1 (2005-06-07) = +* Can also generate a gzipped version of the xml file (sitemap.xml.gz) +* Uses correct last modification dates for categories and archives. (Thanks to thx [Rodney Shupe](http://www.shupe.ca/) for the SQL) +* Supports now different WordPress / Blog directories +* Fixed bug which ignored different post/page priorities (Reported by [Brad](http://h3h.net/)) + += 2.01 (2005-06-07) = +* Fixed compatibility for PHP installations which are not configured to use short open tags +* Changed Line 147 from _e($i); to _e(strval($i)); +* Thanks to [Christian Aust](http://publicvoidblog.de/) for reporting this! + +== Screenshots == + +1. Plugin options page +2. Sample XML sitemap (with a stylesheet for making it readable) +3. Sample XML sitemap (without stylesheet) + +== License == + +Good news, this plugin is free for everyone! Since it's released under the GPL, you can use it free of charge on your personal or commercial site. + +== Translations == + +The plugin comes with various translations, please refer to the [WordPress Codex](http://codex.wordpress.org/Installing_WordPress_in_Your_Language "Installing WordPress in Your Language") for more information about activating the translation. If you want to help to translate the plugin to your language, please have a look at the sitemap.pot file which contains all definitions and may be used with a [gettext](http://www.gnu.org/software/gettext/) editor like [Poedit](http://www.poedit.net/) (Windows). + +== Upgrade Notice == + += 4.1.23 = +Critical Security Fix: Resolved a flaw where certain actions could be triggered without verifying the requester’s identity, privileges, or a valid security token. CVE-2025-64632 \ No newline at end of file diff --git a/html/wp-content/plugins/google-sitemap-generator/screenshot-1.png b/html/wp-content/plugins/google-sitemap-generator/screenshot-1.png new file mode 100644 index 0000000..a7e69b8 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/screenshot-1.png differ diff --git a/html/wp-content/plugins/google-sitemap-generator/screenshot-2.png b/html/wp-content/plugins/google-sitemap-generator/screenshot-2.png new file mode 100644 index 0000000..c877e03 Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/screenshot-2.png differ diff --git a/html/wp-content/plugins/google-sitemap-generator/screenshot-3.png b/html/wp-content/plugins/google-sitemap-generator/screenshot-3.png new file mode 100644 index 0000000..0fef20a Binary files /dev/null and b/html/wp-content/plugins/google-sitemap-generator/screenshot-3.png differ diff --git a/html/wp-content/plugins/google-sitemap-generator/sitemap-core.php b/html/wp-content/plugins/google-sitemap-generator/sitemap-core.php new file mode 100644 index 0000000..676e485 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/sitemap-core.php @@ -0,0 +1,2928 @@ +start_time = microtime( true ); + + $this->auto_save = $auto_save; + + if ( $auto_save ) { + + $exists = get_option( 'sm_status' ); + + if ( false === $exists ) { + add_option( 'sm_status', '', '', 'no' ); + } + $this->save(); + } + } + + /** + * Saves the status back to the database + */ + public function save() { + update_option( 'sm_status', $this ); + } + + /** + * Returns the last saved status object or null + * + * @return GoogleSitemapGeneratorStatus + */ + public static function load() { + $status = get_option( 'sm_status' ); + if ( is_a( $status, 'GoogleSitemapGeneratorStatus' ) ) { + return $status; + } else { + return null; + } + } + + /** + * Ends the ping process + */ + public function end() { + $this->end_time = microtime( true ); + if ( $this->auto_save ) { + $this->save(); + } + } + + /** + * Returns the duration of the ping process + * + * @return int + */ + public function get_duration() { + return round( $this->end_time - $this->start_time, 2 ); + } + + /** + * Returns the time when the pings were started + * + * @return int + */ + public function get_start_time() { + return round( $this->start_time, 2 ); + } + + /** + * Start ping . + * + * @param string $service string The internal name of the ping service . + * @param string $url string The URL to ping . + * @param string $name string The display name of the service . + * @return void + */ + public function start_ping( $service, $url, $name = null ) { + $this->ping_results[ $service ] = array( + 'start_time' => microtime( true ), + 'end_time' => 0, + 'success' => false, + 'url' => $url, + 'name' => $name ? $name : $service, + ); + + if ( $this->auto_save ) { + $this->save(); + } + } + + /** + * End ping . + * + * @param string $service string The internal name of the ping service . + * @param string $success boolean If the ping was successful . + * @return void + */ + public function end_ping( $service, $success ) { + $this->ping_results[ $service ]['end_time'] = microtime( true ); + $this->ping_results[ $service ]['success'] = $success; + + if ( $this->auto_save ) { + $this->save(); + } + } + + /** + * Returns the duration of the last ping of a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return float + */ + public function get_ping_duration( $service ) { + $res = $this->ping_results[ $service ]; + return round( $res['end_time'] - $res['start_time'], 2 ); + } + + /** + * Returns the last result for a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return array + */ + public function get_ping_result( $service ) { + return $this->ping_results[ $service ]['success']; + } + + /** + * Returns the URL for a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return array + */ + public function get_ping_url( $service ) { + return $this->ping_results[ $service ]['url']; + } + + /** + * Returns the name for a specific ping service + * + * @param string $service string The internal name of the ping service . + * @return array + */ + public function get_service_name( $service ) { + return $this->ping_results[ $service ]['name']; + } + + /** + * Returns if a service was used in the last ping + * + * @param string $service string The internal name of the ping service . + * @return bool + */ + public function used_ping_service( $service ) { + return array_key_exists( $service, $this->ping_results ); + } + + /** + * Returns the services which were used in the last ping + * + * @return array + */ + public function get_used_ping_services() { + return array_keys( $this->ping_results ); + } +} + +/** + * Represents an item in the page list + * + * @author Arne Brachhold + * @package sitemap + * @since 3.0 + */ +class GoogleSitemapGeneratorPage { + + /** + * Sets the URL or the relative path to the site dir of the page . + * + * @var string $_url Sets the URL or the relative path to the site dir of the page + */ + public $url; + + /** + * Sets the priority of this page . + * + * @var float $_priority Sets the priority of this page + */ + public $priority; + + /** + * Sets the chanfe frequency of the page. I want Enums! . + * + * @var string $_change_freq Sets the chanfe frequency of the page. I want Enums! + */ + public $change_freq; + + /** + * Sets the last_mod date as a UNIX timestamp. . + * + * @var int $_last_mod Sets the last_mod date as a UNIX timestamp. + */ + public $last_mod; + + /** + * Sets the post ID in case this item is a WordPress post or page . + * + * @var int $_post_id Sets the post ID in case this item is a WordPress post or page + */ + public $post_id; + + /** + * Initialize a new page object + * + * @since 3.0 + * @param string $url The URL or path of the file . + * @param float $priority The Priority of the page 0.0 to 1.0 . + * @param string $change_freq The change frequency like daily, hourly, weekly . + * @param int $last_mod The last mod date as a unix timestamp . + * @param int $post_id The post ID of this page . + */ + public function __construct( $url = '', $priority = 0.0, $change_freq = 'never', $last_mod = 0, $post_id = 0 ) { + $this->set_url( $url ); + $this->set_priority( $priority ); + $this->set_change_freq( $change_freq ); + $this->set_last_mod( $last_mod ); + $this->set_post_id( $post_id ); + } + + /** + * Returns the URL of the page + * + * @return string The URL + */ + public function get_url() { + return $this->url; + } + + /** + * Sets the URL of the page + * + * @param string $url The new URL . + */ + public function set_url( $url ) { + $this->url = (string) $url; + } + + /** + * Returns the priority of this page + * + * @return float the priority, from 0.0 to 1.0 + */ + public function get_priority() { + return $this->priority; + } + + /** + * Sets the priority of the page + * + * @param float $priority The new priority from 0.1 to 1.0 . + */ + public function set_priority( $priority ) { + $this->priority = floatval( $priority ); + } + + /** + * Returns the change frequency of the page + * + * @return string The change frequncy like hourly, weekly, monthly etc. + */ + public function get_change_freq() { + return $this->change_freq; + } + + /** + * Sets the change frequency of the page + * + * @param string $change_freq The new change frequency . + */ + public function set_change_freq( $change_freq ) { + $this->change_freq = (string) $change_freq; + } + + /** + * Returns the last mod of the page + * + * @return int The lastmod value in seconds + */ + public function get_last_mod() { + return $this->last_mod; + } + + /** + * Sets the last mod of the page + * + * @param int $last_mod The lastmod of the page . + */ + public function set_last_mod( $last_mod ) { + $this->last_mod = intval( $last_mod ); + } + + /** + * Returns the ID of the post + * + * @return int The post ID + */ + public function get_post_id() { + return $this->post_id; + } + + /** + * Sets the ID of the post + * + * @param int $post_id The new ID . + */ + public function set_post_id( $post_id ) { + $this->post_id = intval( $post_id ); + } + + /** + * Render method . + */ + public function render() { + + if ( '/' === $this->url || empty( $this->url ) ) { + return ''; + } + + $r = ''; + $r .= "\t\n"; + $r .= "\t\t" . $this->escape_xml( esc_url_raw( $this->url ) ) . "\n"; + + if ( $this->last_mod > 0 ) { + //$r .= "\t\t" . gmdate( 'Y-m-d\TH:i:s+00:00', $this->last_mod ) . "\n"; + $r .= "\t\t" . gmdate( 'Y-m-d\TH:i:sP', $this->last_mod ) . "\n"; + } + + if ( ! empty( $this->change_freq ) ) { + $r .= "\t\t" . $this->change_freq . "\n"; + } + if ( false !== $this->priority && '' !== $this->priority ) { + $r .= "\t\t" . number_format( $this->priority, 1 ) . "\n"; + } + $r .= "\t\n"; + + return $r; + } + + /** + * Escape xml . + * + * @param string $string . + */ + protected function escape_xml( $string ) { + return str_replace( array( '&', '"', '\'', '<', '>' ), array( '&', '"', ''', '<', '>' ), $string ); + } +} + +/** + * Represents an XML entry, like definitions + * + * @author Arne Brachhold + * @package sitemap + * @since 3.0 + */ +class GoogleSitemapGeneratorXmlEntry { + + /** + * Xml + * + * @var string $_xml . + */ + protected $xml; + + /** + * Constructor function + * + * @param string $xml . + */ + public function __construct( $xml ) { + $this->xml = $xml; + } + + /** + * Render function + */ + public function render() { + return $this->xml; + } +} + +/** + * Represents an comment + * + * @author Arne Brachhold + * @package sitemap + * @since 3.0 + * @uses GoogleSitemapGeneratorXmlEntry + */ +class GoogleSitemapGeneratorDebugEntry extends GoogleSitemapGeneratorXmlEntry { + /** + * Render function + */ + public function render() { + return '\n"; + } +} + +/** + * Represents an item in the sitemap + * + * @author Arne Brachhold + * @package sitemap + * @since 3.0 + */ +class GoogleSitemapGeneratorSitemapEntry { + + /** + * Sets the URL or the relative path to the site dir of the page . + * + * @var string $_url Sets the URL or the relative path to the site dir of the page + */ + protected $url; + + /** + * Sets the last_mod date as a UNIX timestamp. . + * + * @var int $_last_mod Sets the last_mod date as a UNIX timestamp. + */ + protected $last_mod; + + /** + * Returns the URL of the page + * + * @return string The URL + */ + public function get_url() { + return $this->url; + } + + /** + * Sets the URL of the page + * + * @param string $url The new URL . + */ + public function set_url( $url ) { + $this->url = (string) $url; + } + + /** + * Returns the last mod of the page + * + * @return int The lastmod value in seconds + */ + public function get_last_mod() { + return $this->last_mod; + } + + /** + * Sets the last mod of the page + * + * @param int $last_mod The lastmod of the page . + */ + public function set_last_mod( $last_mod ) { + $this->last_mod = intval( $last_mod ); + } + /** + * Constructor + * + * @param string $url . + * @param int $last_mod . + */ + public function __construct( $url = '', $last_mod = 0 ) { + $this->set_url( $url ); + $this->set_last_mod( $last_mod ); + } + /** + * Render function + */ + public function render() { + + if ( '/' === $this->url || empty( $this->url ) ) { + return ''; + } + + $r = ''; + $r .= "\t\n"; + $r .= "\t\t" . $this->escape_xml( esc_url_raw( $this->url ) ) . "\n"; + if ( $this->last_mod > 0 ) { + $r .= "\t\t" . gmdate( 'Y-m-d\TH:i:s+00:00', $this->last_mod ) . "\n"; + } + $r .= "\t\n"; + return $r; + } + + /** + * Escape_xml function . + * + * @param string $string . + */ + protected function escape_xml( $string ) { + return str_replace( array( '&', '\'', '\'', '<', '>' ), array( '&', '"', ''', '<', '>' ), $string ); + } +} + +/** + * Interface for all priority providers + * + * @author Arne Brachhold + * @package sitemap + * @since 3.0 + */ +interface Google_Sitemap_Generator_Prio_Provider_Base { + + /** + * Initializes a new priority provider + * + * @param int $total_comments int The total number of comments of all posts . + * @param int $total_posts int The total number of posts . + * @since 3.0 + */ + public function __construct( $total_comments, $total_posts ); + + /** + * Returns the (translated) name of this priority provider + * + * @since 3.0 + * @return string The translated name + */ + public static function get_name(); + + /** + * Returns the (translated) description of this priority provider + * + * @since 3.0 + * @return string The translated description + */ + public static function get_description(); + + /** + * Returns the priority for a specified post + * + * @param int $post_id int The ID of the post . + * @param int $comment_count int The number of comments for this post . + * @since 3.0 + * @return int The calculated priority + */ + public function get_post_priority( $post_id, $comment_count ); +} + +/** + * Priority Provider which calculates the priority based on the number of comments + * + * @author Arne Brachhold + * @package sitemap + * @since 3.0 + */ +class GoogleSitemapGeneratorPrioByCountProvider implements Google_Sitemap_Generator_Prio_Provider_Base { + + /** + * The total number of comments of all posts . + * + * @var int $total_comments The total number of comments of all posts + */ + protected $total_comments = 0; + + /** + * The total number of posts . + * + * @var int $total_posts The total number of posts + */ + protected $total_posts = 0; + + /** + * Initializes a new priority provider + * + * @param int $total_comments int The total number of comments of all posts . + * @param int $total_posts int The total number of posts . + * @since 3.0 + */ + public function __construct( $total_comments, $total_posts ) { + $this->total_comments = $total_comments; + $this->total_posts = $total_posts; + } + + /** + * Returns the (translated) name of this priority provider + * + * @since 3.0 + * @return string The translated name + */ + public static function get_name() { + return __( 'Comment Count', 'google-sitemap-generator' ); + } + + /** + * Returns the (translated) description of this priority provider + * + * @since 3.0 + * @return string The translated description + */ + public static function get_description() { + return __( 'Uses the number of comments of the post to calculate the priority', 'google-sitemap-generator' ); + } + + /** + * Returns the priority for a specified post + * + * @param int $post_id int The ID of the post . + * @param int $comment_count int The number of comments for this post . + * @since 3.0 + * @return int The calculated priority + */ + public function get_post_priority( $post_id, $comment_count ) { + if ( $this->total_comments > 0 && $comment_count > 0 ) { + return round( ( $comment_count * 100 / $this->total_comments ) / 100, 1 ); + } else { + return 0; + } + } +} + +/** + * Priority Provider which calculates the priority based on the average number of comments + * + * @author Arne Brachhold + * @package sitemap + * @since 3.0 + */ +class GoogleSitemapGeneratorPrioByAverageProvider implements Google_Sitemap_Generator_Prio_Provider_Base { + + + /** + * The total number of comments of all posts . + * + * @var int $total_comments The total number of comments of all posts + */ + protected $total_comments = 0; + + /** + * The total number of posts . + * + * @var int $total_comments The total number of posts + */ + protected $total_posts = 0; + + /** + * The average number of comments per post . + * + * @var int $average The average number of comments per post + */ + protected $average = 0.0; + + /** + * Returns the (translated) name of this priority provider + * + * @since 3.0 + * @return string The translated name + */ + public static function get_name() { + return __( 'Comment Average', 'google-sitemap-generator' ); + } + + /** + * Returns the (translated) description of this priority provider + * + * @since 3.0 + * @return string The translated description + */ + public static function get_description() { + return __( 'Uses the average comment count to calculate the priority', 'google-sitemap-generator' ); + } + + /** + * Initializes a new priority provider which calculates the post priority based on the average number of comments + * + * @param int $total_comments int The total number of comments of all posts . + * @param int $total_posts int The total number of posts . + * @since 3.0 + */ + public function __construct( $total_comments, $total_posts ) { + + $this->total_comments = $total_comments; + $this->total_posts = $total_posts; + + if ( $this->total_comments > 0 && $this->total_posts > 0 ) { + $this->average = (float) $this->total_comments / $this->total_posts; + } + } + + /** + * Returns the priority for a specified post + * + * @param int $post_id int The ID of the post . + * @param int $comment_count int The number of comments for this post . + * @since 3.0 + * @return int The calculated priority + */ + public function get_post_priority( $post_id, $comment_count ) { + + // Do not divide by zero ! + if ( 0 === $this->average|| 0.0 === $this->average ) { + if ( $comment_count > 0 ) { + $priority = 1; + } else { + $priority = 0; + } + } else { + $priority = $comment_count / $this->average; + if ( $priority > 1 ) { + $priority = 1; + } elseif ( $priority < 0 ) { + $priority = 0; + } + } + + return round( $priority, 1 ); + } +} + +/** + * Class to generate a sitemaps.org Sitemaps compliant sitemap of a WordPress site. + * + * @package sitemap + * @author Arne Brachhold + * @since 3.0 + */ +final class GoogleSitemapGenerator { + /** + * The unserialized array with the stored options . + * + * @var array The unserialized array with the stored options + */ + private $options = array(); + + /** + * The saved additional pages . + * + * @var array The saved additional pages + */ + private $pages = array(); + + /** + * The values and names of the change frequencies . + * + * @var array The values and names of the change frequencies + */ + private $freq_names = array(); + + /** + * A list of class names which my be called for priority calculation . + * + * @var array A list of class names which my be called for priority calculation + */ + private $prio_providers = array(); + + /** + * True if init complete (options loaded etc) . + * + * @var bool True if init complete (options loaded etc) + */ + private $is_initiated = false; + + /** + * Defines if the sitemap building process is active at the moment . + * + * @var bool Defines if the sitemap building process is active at the moment + */ + private $is_active = false; + + /** + * Holds options like output format and compression for the current request . + * + * @var array Holds options like output format and compression for the current request + */ + private $build_options = array(); + + /** + * Holds the user interface object + * + * @since 3.1.1 + * @var GoogleSitemapGeneratorUI + */ + private $ui = null; + + /** + * Defines if the simulation mode is on. In this case, data is not echoed but saved instead. + * + * @var boolean + */ + private $sim_mode = false; + + /** + * Holds the data if simulation mode is on + * + * @var array + */ + private $sim_data = array( + 'sitemaps' => array(), + 'content' => array(), + ); + + /** + * Defines if the options have been loaded. + * + * @var bool Defines if the options have been loaded + */ + private $options_loaded = false; + + + /*************************************** CONSTRUCTION AND INITIALIZING ***************************************/ + + /** + * Initializes a new Google Sitemap Generator + * + * @since 4.0 + */ + private function __construct() { + } + + /** + * Returns the instance of the Sitemap Generator + * + * @since 3.0 + * @return GoogleSitemapGenerator The instance or null if not available. + */ + public static function get_instance() { + if ( isset( $GLOBALS['sm_instance'] ) ) { + return $GLOBALS['sm_instance']; + } else { + return null; + } + } + + /** + * Enables the Google Sitemap Generator and registers the WordPress hooks + * + * @since 3.0 + */ + public static function enable() { + if ( ! isset( $GLOBALS['sm_instance'] ) ) { + $GLOBALS['sm_instance'] = new GoogleSitemapGenerator(); + } + } + + /** + * Loads up the configuration and validates the prioity providers + * + * This method is only called if the sitemaps needs to be build or the admin page is displayed. + * + * @since 3.0 + */ + public function initate() { + if ( ! $this->is_initiated ) { + + load_plugin_textdomain( 'sitemap', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' ); + + $this->freq_names = array( + 'always' => __( 'Always', 'google-sitemap-generator' ), + 'hourly' => __( 'Hourly', 'google-sitemap-generator' ), + 'daily' => __( 'Daily', 'google-sitemap-generator' ), + 'weekly' => __( 'Weekly', 'google-sitemap-generator' ), + 'monthly' => __( 'Monthly', 'google-sitemap-generator' ), + 'yearly' => __( 'Yearly', 'google-sitemap-generator' ), + 'never' => __( 'Never', 'google-sitemap-generator' ), + ); + + $this->load_options(); + $this->load_pages(); + + // Register our own priority providers. + add_filter( 'sm_add_prio_provider', array( $this, 'add_default_prio_providers' ) ); + + // Let other plugins register their providers. + $r = apply_filters( 'sm_add_prio_provider', $this->prio_providers ); + + // Check if no plugin return null. + if ( null !== $r ) { + $this->prio_providers = $r; + } + + $this->validate_prio_providers(); + + $this->is_initiated = true; + } + } + + + /*************************************** VERSION AND LINK HELPERS ***************************************/ + + /** + * Returns the version of the generator + * + * @since 3.0 + * @return int The version + */ + public static function get_version() { + return GoogleSitemapGeneratorLoader::get_version(); + } + + /** + * Returns the SVN version of the generator + * + * @since 4.0 + * @return string The SVN version string + */ + public static function get_svn_version() { + return GoogleSitemapGeneratorLoader::get_svn_version(); + } + + /** + * Returns a link pointing to a specific page of the authors website + * + * @since 3.0 + * @param string $redir string The to link to . + * @return string The full url + */ + public static function get_redirect_link( $redir ) { + return trailingslashit( 'http://url.auctollo.com/' . $redir ); + } + + /** + * Returns a link pointing back to the plugin page in WordPress + * + * @since 3.0 + * @param string $extra . + * @return string The full url + */ + public static function get_back_link( $extra = '' ) { + global $wp_version; + $url = admin_url( 'options-general.php?page=' . GoogleSitemapGeneratorLoader::get_base_name() . $extra ); + return $url; + } + + /** + * Converts a mysql datetime value into a unix timestamp + * + * @param string $mysql_date_time string The timestamp in the mysql datetime format . + * @return int The time in seconds + */ + public static function get_timestamp_from_my_sql( $mysql_date_time ) { + list( $date, $hours) = explode( ' ', $mysql_date_time ); + list( $year, $month, $day) = explode( '-', $date ); + list( $hour, $min, $sec) = explode( ':', $hours ); + return mktime( intval( $hour ), intval( $min ), intval( $sec ), intval( $month ), intval( $day ), intval( $year ) ); + } + + + /*************************************** SIMPLE GETTERS ***************************************/ + + /** + * Returns the names for the frequency values + * + * @return array + */ + public function get_freq_names() { + return $this->freq_names; + } + + /** + * Returns if the site is running in multi site mode + * + * @since 4.0 + * @return bool + */ + public function is_multi_site() { + return ( function_exists( 'is_multisite' ) && is_multisite() ); + } + + /** + * Returns if the sitemap building process is currently active + * + * @since 3.0 + * @return bool true if active + */ + public function is_active() { + $inst = self::get_instance(); + return ( null !== $inst && $inst->is_active ); + } + + /** + * Returns if the compressed sitemap was activated + * + * @since 3.0b8 + * @return true if compressed + */ + public function is_gzip_enabled() { + return ( function_exists( 'gzwrite' ) && $this->get_option( 'b_autozip' ) ); + } + + /** + * Returns if the XML Dom and XSLT functions are enabled + * + * @since 4.0b1 + * @return true if compressed + */ + public function is_xsl_enabled() { + return ( class_exists( 'DomDocument' ) && class_exists( 'XSLTProcessor' ) ); + } + + /** + * Returns if Nginx is used as the server software + * + * @since 4.0.3 + * + * @return bool + */ + public function is_nginx() { + if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && stristr( sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ), 'nginx' ) !== false ) { + return true; + } + return false; + } + + + + /*************************************** TAXONOMIES AND CUSTOM POST TYPES ***************************************/ + + /** + * Returns if this version of WordPress supports the new taxonomy system + * + * @since 3.0b8 + * @return true if supported + */ + public function is_taxonomy_supported() { + return ( function_exists( 'get_taxonomy' ) && function_exists( 'get_terms' ) && function_exists( 'get_taxonomies' ) ); + } + + /** + * Returns the list of custom taxonomies. These are basically all taxonomies without categories and post tags + * + * @since 3.1.7 + * @return array Array of names of user-defined taxonomies + */ + public function get_custom_taxonomies() { + $taxonomies = get_taxonomies( array( 'public' => 1 ) ); + return array_diff( $taxonomies, array( 'category', 'product_cat', 'post_tag', 'nav_menu', 'link_category', 'post_format' ) ); + } + + /** + * Returns if this version of WordPress supports custom post types + * + * @since 3.2.5 + * @return true if supported + */ + public function is_custom_post_types_supported() { + return ( function_exists( 'get_post_types' ) && function_exists( 'register_post_type' ) ); + } + + /** + * Returns the list of custom post types. These are all custom post types except post, page and attachment + * + * @since 3.2.5 + * @return array Array of custom post types as per get_post_types + */ + public function get_custom_post_types() { + $post_types = get_post_types( array( 'public' => 1 ) ); + $post_types = array_diff( $post_types, array( 'post', 'page', 'attachment' ) ); + return $post_types; + } + + + /** + * Returns the list of active post types, built-in and custom ones. + * + * @since 4.0b5 + * @return array Array of custom post types as per get_post_types + */ + public function get_active_post_types() { + + $cache_key = __CLASS__ . '::get_active_post_types'; + + $active_post_types = wp_cache_get( $cache_key, 'sitemap' ); + + if ( false === $active_post_types ) { + $all_post_types = get_post_types(); + $enabled_post_types = $this->get_option( 'in_customtypes' ); + if ( $this->get_option( 'in_posts' ) ) { + $enabled_post_types[] = 'post'; + } + if ( $this->get_option( 'in_pages' ) ) { + $enabled_post_types[] = 'page'; + } + + $active_post_types = array(); + foreach ( $enabled_post_types as $post_type ) { + if ( ! empty( $post_type ) && in_array( $post_type, $all_post_types, true ) ) { + $active_post_types[] = $post_type; + } + } + + /** + * Filter: 'sm_sitemap_exclude_post_type' - Allow extending and modifying the post types to exclude. + * + * @param array $post_types_to_exclude The post types to exclude. + */ + $post_types_to_exclude = []; + $post_types_to_exclude = apply_filters( 'sm_sitemap_exclude_post_types', $post_types_to_exclude ); + if ( ! is_array( $post_types_to_exclude ) ) { + $post_types_to_exclude = []; + } + if ( ! empty( $post_types_to_exclude ) ) { + foreach ( $active_post_types as $key => $active_post_type ) { + if ( in_array( $active_post_type, $post_types_to_exclude ) ) { + unset( $active_post_types[ $key ] ); + } + } + } + + /** + * Filter: 'sm_sitemap_include_post_type' - Allow extending and modifying the post types to include. + * + * @param array $post_types_to_include The post types to include. + */ + $post_types_to_include = []; + $post_types_to_include = apply_filters( 'sm_sitemap_include_post_type', $post_types_to_include ); + if ( ! is_array( $post_types_to_include ) ) { + $post_types_to_include = []; + } + if ( ! empty( $post_types_to_include ) ) { + $active_post_types = array_merge( $active_post_types, $post_types_to_include ); + $active_post_types = array_unique( $active_post_types ); + } + + wp_cache_set( $cache_key, $active_post_types, 'sitemap', 20 ); + } + + return $active_post_types; + } + + /** + * Returns an array with all excluded post IDs + * + * @since 4.0b11 + * @return int[] Array with excluded post IDs + */ + public function get_excluded_post_ids() { + $posts_to_exclude = []; + + $excludes = (array) $this->get_option( 'b_exclude' ); + + $excluded_posts_ids = array_filter( array_map( 'intval', $excludes ), array( $this, 'is_greater_zero' ) ); + + /** + * Filter: 'sm_exclude_from_sitemap_by_post_ids' - Allow extending and modifying the posts to exclude. + * + * @param array $posts_to_exclude The posts to exclude. + */ + $posts_to_exclude = apply_filters( 'sm_exclude_from_sitemap_by_post_ids', $posts_to_exclude ); + if ( ! is_array( $posts_to_exclude ) ) { + $posts_to_exclude = []; + } + + $excluded_posts_ids = array_merge( $excluded_posts_ids, $posts_to_exclude ); + + return array_unique( $excluded_posts_ids ); + } + + /** + * Robots disallowed + */ + public function robots_disallowed() { + + // parse url to retrieve host and path. + $parsed = home_url(); + $rules = array(); + + // location of robots.txt file. + try { + if ( file_exists( $parsed . '/robots.txt' ) ) { + $robotstxt = file( $parsed . '/robots.txt' ); + + } elseif ( file_exists( ABSPATH . '/robots.txt' ) ) { + // if there isn't a robots, then we're allowed in. + $robotstxt = file( ABSPATH . '/robots.txt' ); + + } + } catch ( Exception $e ) { + return $rules; + } + + if ( empty( $robotstxt ) ) { + return $rules; + } + + foreach ( $robotstxt as $line ) { + $line = trim( $line ); + // Skip blank lines . + if ( ! $line ) { + continue; + } + + if ( preg_match( '/^\s*Disallow:(.*)/i', $line, $regs ) ) { + + // An empty rule implies full access - no further tests required . + if ( ! $regs[1] ) { + continue; + } + + // Add rules that apply to array for testing . + $id = url_to_postid( home_url( trim( $regs[1] ) ) ); + if ( $id > 0 ) { + $rules[] = $id; + } + } + } + + $rules = apply_filters( 'sm_robots_disallowed_ids', array_unique( $rules ) ); + + return $rules; + } + /** + * Returns an array with all excluded category IDs. + * + * @since 4.0b11 + * @return int[] Array with excluded category IDs + */ + public function get_excluded_category_i_ds() { + $excl_cats = (array) $this->get_option( 'b_exclude_cats' ); + return array_filter( array_map( 'intval', $excl_cats ), array( $this, 'is_greater_zero' ) ); + } + + /*************************************** PRIORITY PROVIDERS ***************************************/ + + /** + * Returns the list of PriorityProviders + * + * @return array + */ + public function get_prio_providers() { + return $this->prio_providers; + } + + /** + * Adds the default Priority Providers to the provider list + * + * @since 3.0 + * @param array $providers . + * @return array + */ + public function add_default_prio_providers( $providers ) { + array_push( $providers, 'GoogleSitemapGeneratorPrioByCountProvider' ); + array_push( $providers, 'GoogleSitemapGeneratorPrioByAverageProvider' ); + if ( class_exists( 'ak_popularity_contest' ) ) { + array_push( $providers, 'GoogleSitemapGeneratorPrioByPopularityContestProvider' ); + } + return $providers; + } + + /** + * Validates all given Priority Providers by checking them for required methods and existence + * + * @since 3.0 + */ + private function validate_prio_providers() { + $valid_providers = array(); + $len = count( $this->prio_providers ); + for ( $i = 0; $i < $len; $i++ ) { + if ( class_exists( $this->prio_providers[ $i ] ) ) { + if ( class_implements( $this->prio_providers[ $i ], 'Google_Sitemap_Generator_Prio_Provider_Base' ) ) { + array_push( $valid_providers, $this->prio_providers[ $i ] ); + } + } + } + $this->prio_providers = $valid_providers; + + if ( ! $this->get_option( 'b_prio_provider' ) ) { + if ( ! in_array( $this->get_option( 'b_prio_provider' ), $this->prio_providers, true ) ) { + $this->set_option( 'b_prio_provider', '' ); + } + } + } + + + /*************************************** COMMENT HANDLING FOR PRIO. PROVIDERS ***************************************/ + + /** + * Retrieves the number of comments of a post in a asso. array + * The key is the post_id, the value the number of comments + * + * @since 3.0 + * @return array An array with post_ids and their comment count + */ + public function get_comments() { + // @var $wpdb wpdb . + global $wpdb; + $comments = array(); + + // Query comments and add them into the array . + $comment_res = $wpdb->get_results( 'SELECT `comment_post_ID` as `post_id`, COUNT( comment_ID ) as `comment_count` FROM `' . $wpdb->comments . '` WHERE `comment_approved`=\'1\' GROUP BY `comment_post_ID`' ); // db call ok; no-cache ok. + if ( $comment_res ) { + foreach ( $comment_res as $comment ) { + $comments[ $comment->post_id ] = $comment->comment_count; + } + } + return $comments; + } + + /** + * Calculates the full number of comments from an sm_getComments() generated array + * + * @since 3.0 + * @param object $comments array The Array with posts and c0mment count . + * @see sm_getComments + * @return int The full number of comments + */ + public function get_comment_count( $comments ) { + $comment_count = 0; + foreach ( $comments as $k => $v ) { + $comment_count += $v; + } + return $comment_count; + } + + + /*************************************** OPTION HANDLING ***************************************/ + + /** + * Sets up the default configuration + * + * @since 3.0 + */ + public function init_options() { + + $this->options = array(); + $this->options['sm_b_prio_provider'] = 'GoogleSitemapGeneratorPrioByCountProvider'; // Provider for automatic priority calculation . + $this->options['sm_b_ping'] = true; // Auto ping Google . + $this->options['sm_b_stats'] = false; // Send anonymous stats . + $this->options['sm_b_autozip'] = true; // Try to gzip the output . + $this->options['sm_b_memory'] = ''; // Set Memory Limit (e.g. 16M) . + $this->options['sm_b_time'] = -1; // Set time limit in seconds, 0 for unlimited, -1 for disabled . + $this->options['sm_b_style_default'] = true; // Use default style . + $this->options['sm_b_style'] = ''; // Include a stylesheet in the XML . + $this->options['sm_b_baseurl'] = ''; // The base URL of the sitemap . + $this->options['sm_b_rewrites2'] = false; //status updating url rules + $this->options['sm_b_indexnow'] = true; //On indexnow functionality + $this->options['sm_b_activate_indexnow'] = false; //On indexnow functionality + $this->options['sm_b_index_date'] = ''; //On indexnow date + $this->options['sm_b_robots'] = true; // Add sitemap location to WordPress' virtual robots.txt file . + $this->options['sm_b_html'] = true; // Include a link to a html version of the sitemap in the XML sitemap . + $this->options['sm_b_exclude'] = array(); // List of post / page IDs to exclude . + $this->options['sm_b_exclude_cats'] = array(); // List of post / page IDs to exclude . + + $this->options['sm_in_home'] = true; // Include homepage . + $this->options['sm_in_posts'] = true; // Include posts . + $this->options['sm_in_posts_sub'] = false; // Include post pages ( tag) . + $this->options['sm_in_pages'] = true; // Include static pages . + $this->options['sm_in_cats'] = false; // Include categories . + $this->options['sm_product_tags'] = true; // Hide product tags in sitemap . + $this->options['sm_in_product_cat'] = true; // Include product categories . + $this->options['sm_in_product_assortment'] = true; // Include products . + $this->options['sm_in_arch'] = false; // Include archives . + $this->options['sm_in_auth'] = false; // Include author pages . + $this->options['sm_in_tags'] = false; // Include tag pages . + $this->options['sm_in_tax'] = array(); // Include additional taxonomies . + $this->options['sm_in_customtypes'] = array(); // Include custom post types . + $this->options['sm_in_lastmod'] = true; // Include the last modification date . + $this->options['sm_b_sitemap_name'] = 'sitemap'; // Name of custom sitemap. + $this->options['sm_b_old_sm_name'] = 'sitemap'; // Name of previously defined sitemap. + $this->options['sm_cf_home'] = 'daily'; // Change frequency of the homepage . + $this->options['sm_cf_posts'] = 'monthly'; // Change frequency of posts . + $this->options['sm_cf_pages'] = 'weekly'; // Change frequency of static pages . + $this->options['sm_cf_cats'] = 'weekly'; // Change frequency of categories . + $this->options['sm_cf_product_cat'] = 'weekly'; // Change frequency of categories . + $this->options['sm_cf_auth'] = 'weekly'; // Change frequency of author pages . + $this->options['sm_cf_arch_curr'] = 'daily'; // Change frequency of the current archive (this month) . + $this->options['sm_cf_arch_old'] = 'yearly'; // Change frequency of older archives . + $this->options['sm_cf_tags'] = 'weekly'; // Change frequency of tags . + + $this->options['sm_pr_home'] = 1.0; // Priority of the homepage . + $this->options['sm_pr_posts'] = 0.6; // Priority of posts (if auto prio is disabled) . + $this->options['sm_pr_posts_min'] = 0.2; // Minimum Priority of posts, even if autocalc is enabled . + $this->options['sm_pr_pages'] = 0.6; // Priority of static pages . + $this->options['sm_pr_cats'] = 0.3; // Priority of categories . + $this->options['sm_pr_product_cat'] = 0.3; // Priority of categories . + $this->options['sm_pr_arch'] = 0.3; // Priority of archives . + $this->options['sm_pr_auth'] = 0.3; // Priority of author pages . + $this->options['sm_pr_tags'] = 0.3; // Priority of tags . + + $this->options['sm_i_donated'] = false; // Did you donate? Thank you! :) . + $this->options['sm_i_hide_donated'] = false; // And hide the thank you.. . + $this->options['sm_i_install_date'] = time(); // The installation date . + $this->options['sm_i_hide_survey'] = false; // Hide the survey note . + $this->options['sm_i_hide_note'] = false; // Hide the note which appears after 30 days . + $this->options['sm_i_hide_works'] = false; // Hide the 'works?' message which appears after 15 days . + $this->options['sm_i_hide_donors'] = false; // Hide the list of donations . + $this->options['sm_i_hash'] = substr( sha1( sha1( get_bloginfo( 'url' ) ) ), 0, 20 ); // Partial hash for GA stats, NOT identifiable! . + $this->options['sm_i_tid'] = ''; + $this->options['sm_i_lastping'] = 0; // When was the last ping . + $this->options['sm_i_supportfeed'] = true; // shows the support feed . + $this->options['sm_i_supportfeed_cache'] = 0; // Last refresh of support feed . + $this->options['sm_links_page'] = 1000; // Link per page support with default value 1000. . + $this->options['sm_user_consent'] = false; + $this->options['sm_wp_sitemap_status'] = true; + } + + /** + * Loads the configuration from the database + * + * @since 3.0 + */ + private function load_options() { + + if ( $this->options_loaded ) { + return; + } + + $this->init_options(); + + // First init default values, then overwrite it with stored values so we can add default + // values with an update which get stored by the next edit. + $stored_options = get_option( 'sm_options' ); + + // Custom Taxonomies + if ( !empty( $stored_options['sm_in_tax'] ) ) { + foreach ( $stored_options['sm_in_tax'] as $custom_tax ) { + $this->options[ "sm_cf_" . $custom_tax ] = 'weekly'; // Change frequency of custom taxonomy . + $this->options[ "sm_pr_" . $custom_tax ] = 0.3; // Priority of custom taxonomy . + } + } + + if ( $stored_options && is_array( $stored_options ) ) { + foreach ( $stored_options as $k => $v ) { + if ( array_key_exists( $k, $this->options ) ) { + $this->options[ $k ] = $v; + } + } + } else { + update_option( 'sm_options', $this->options ); // First time use, store default values . + } + + $this->options_loaded = true; + } + + /** + * Returns the option value for the given key + * + * @since 3.0 + * @param string $key string The Configuration Key . + * @return mixed The value + */ + public function get_option( $key ) { + $key = 'sm_' . $key; + if ( array_key_exists( $key, $this->options ) ) { + return $this->options[ $key ]; + } else { + return null; + } + } + /** + * Get options . + */ + public function get_options() { + return $this->options; + } + + /** + * Sets an option to a new value + * + * @since 3.0 + * @param string $key string The configuration key . + * @param string $value mixed The new object . + */ + public function set_option( $key, $value ) { + if ( 0 !== strpos( $key, 'sm_' ) ) { + $key = 'sm_' . $key; + } + $this->options[ $key ] = $value; + } + + /** + * Saves the options back to the database + * + * @since 3.0 + * @return bool true on success + */ + public function save_options() { + $oldvalue = get_option( 'sm_options' ); + // add_filter('pre_update_option_sm_options', [$this,'modify_excluded_sitemap_ids'], 10, 2); + if ( $oldvalue === $this->options ) { + return true; + } else { + return update_option( 'sm_options', $this->options ); + } + } + + + /** + * Excluded posts via code + */ + public function modify_excluded_sitemap_ids($new_value, $old_value) { + $hidden_product_ids = $this->exclude_hidden_products_from_sitemap(); + $new_value['sm_b_exclude'] = array_unique($hidden_product_ids); + return $new_value; + } + + public function exclude_hidden_products_from_sitemap(){ + $excludedArray = []; // here array of posts ID + return $excludedArray; + } + /** + * Returns the additional pages + * + * @since 4.0 + * @return GoogleSitemapGeneratorPage[] + */ + public function get_pages() { + return $this->pages; + } + + /** + * Returns the additional pages + * + * @since 4.0 + * @param array $pages . + */ + public function set_pages( array $pages ) { + $this->pages = $pages; + } + + /** + * Loads the stored pages from the database + * + * @since 3.0 + */ + private function load_pages() { + // @var $wpdb wpdb . + global $wpdb; + + $needs_update = false; + + $pages_string = $wpdb->get_var( "SELECT option_value FROM $wpdb->options WHERE option_name = 'sm_cpages'" ); // db call ok; no-cache ok. + + // Class sm_page was renamed with 3.0 -> rename it in serialized value for compatibility . + if ( ! empty( $pages_string ) && strpos( $pages_string, 'sm_page' ) !== false ) { + $pages_string = str_replace( 'O:7:\'sm_page\'', 'O:26:\'GoogleSitemapGeneratorPage\'', $pages_string ); + $needs_update = true; + } + + if ( ! empty( $pages_string ) ) { + $storedpages = unserialize( $pages_string ); + $this->pages = $storedpages; + } else { + $this->pages = array(); + } + + if ( $needs_update ) { + $this->save_pages(); + } + } + + /** + * Saved the additional pages back to the database + * + * @since 3.0 + * @return true on success + */ + public function save_pages() { + $oldvalue = get_option( 'sm_cpages' ); + if ( $oldvalue === $this->pages ) { + return true; + } else { + delete_option( 'sm_cpages' ); + // Add the option, Note the autoload=false because when the autoload happens, our class GoogleSitemapGeneratorPage doesn't exist . + add_option( 'sm_cpages', $this->pages, '', 'no' ); + return true; + } + } + + /** + * Get the maximum number of entries per XML sitemap. + * + * @return int The maximum number of entries. + */ + public function get_entries_per_page() { + /** + * Filter the maximum number of entries per XML sitemap. + * + * @param int $entries The maximum number of entries per XML sitemap. + */ + $entries = (int) apply_filters( 'sm_sitemap_entries_per_page', $this->get_option( 'links_page' ) ); + + return $entries; + } + + + /*************************************** URL AND PATH FUNCTIONS ***************************************/ + + /** + * Returns the URL to the directory where the plugin file is located + * + * @since 3.0b5 + * @return string The URL to the plugin directory + */ + public function get_plugin_url() { + + $url = trailingslashit( plugins_url( '', __FILE__ ) ); + + return $url; + } + + /** + * Returns the path to the directory where the plugin file is located + * + * @since 3.0b5 + * @return string The path to the plugin directory + */ + public function get_plugin_path() { + $path = dirname( __FILE__ ); + return trailingslashit( str_replace( '\\', '/', $path ) ); + } + + /** + * Returns the URL to default XSLT style if it exists + * + * @since 3.0b5 + * @return string The URL to the default stylesheet, empty string if not available. + */ + public function get_default_style() { + $p = $this->get_plugin_path(); + if ( file_exists( $p . 'sitemap.xsl' ) ) { + $url = $this->get_plugin_url(); + // If called over the admin area using HTTPS, the stylesheet would also be https url, even if the site frontend is not. + if ( substr( get_bloginfo( 'url' ), 0, 5 ) !== 'https' && substr( $url, 0, 5 ) === 'https' ) { + $url = 'http' . substr( $url, 5 ); + } + if ( isset( $_SERVER['HTTP_HOST'] ) ) { + $host = sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ); + } + $url = $this->get_xsl_url( $url, $host ); + return $url . 'sitemap.xsl'; + } + return ''; + } + + /** + * Returns of Permalinks are used + * + * @return bool + */ + public function is_using_permalinks() { + // @var $wp_rewrite WP_Rewrite . + global $wp_rewrite; + + return $wp_rewrite->using_mod_rewrite_permalinks(); + } + + /** + * Registers the plugin specific rewrite rules + * + * Combined: sitemap(-+([a-zA-Z0-9_-]+))?\.(xml|html)(.gz)?$ + * + * @since 4.0 + * @param string $wp_rules Array of existing rewrite rules. + * @return Array An array containing the new rewrite rules. + */ + public static function add_rewrite_rules( $wp_rules ) { + $sm_sitemap_name = $GLOBALS['sm_instance']->get_option( 'b_sitemap_name' ); + $sm_rules = array( + $sm_sitemap_name . '(-+([a-zA-Z0-9_-]+))?\.xml$' => 'index.php?xml_sitemap=params=$matches[2]', + $sm_sitemap_name . '(-+([a-zA-Z0-9_-]+))?\.xml\.gz$' => 'index.php?xml_sitemap=params=$matches[2];zip=true', + $sm_sitemap_name . '(-+([a-zA-Z0-9_-]+))?\.html$' => 'index.php?xml_sitemap=params=$matches[2];html=true', + $sm_sitemap_name . '(-+([a-zA-Z0-9_-]+))?\.html.gz$' => 'index.php?xml_sitemap=params=$matches[2];html=true;zip=true', + ); + return array_merge( $sm_rules, $wp_rules ); + } + + /** + * Adds the filters for wp rewrite rule adding + * + * @since 4.0 + * @uses add_filter() + */ + public static function setup_rewrite_hooks() { + add_filter( 'rewrite_rules_array', array( __CLASS__, 'add_rewrite_rules' ), 1, 1 ); + } + /** + * Removes the filters for wp rewrite rule adding + * + * @since 4.0 + * @uses remove_filter() + */ + public static function remove_rewrite_hooks() { + add_filter( 'rewrite_rules_array', array( __CLASS__, 'remove_rewrite_rules' ), 1, 1 ); + } + + /** + * Deregisters the plugin specific rewrite rules + * + * Combined: sitemap(-+([a-zA-Z0-9_-]+))?\.(xml|html)(.gz)?$ + * + * @since 4.0 + * @param array $wp_rules Array of existing rewrite rules. + * @return Array An array containing the new rewrite rules + */ + public static function remove_rewrite_rules( $wp_rules ) { + $sm_rules = array( + 'sitemap(-+([a-zA-Z0-9_-]+))?\.xml$' => 'index.php?xml_sitemap=params=$matches[2]', + 'sitemap(-+([a-zA-Z0-9_-]+))?\.xml\.gz$' => 'index.php?xml_sitemap=params=$matches[2];zip=true', + 'sitemap(-+([a-zA-Z0-9_-]+))?\.html$' => 'index.php?xml_sitemap=params=$matches[2];html=true', + 'sitemap(-+([a-zA-Z0-9_-]+))?\.html.gz$' => 'index.php?xml_sitemap=params=$matches[2];html=true;zip=true', + 'post(-+([a-zA-Z0-9_-]+))?\.xml$' => 'index.php?xml_sitemap=params=$matches[2]', + ); + foreach ( $wp_rules as $key => $value ) { + if ( array_key_exists( $key, $sm_rules ) ) { + unset( $wp_rules[ $key ] ); + } + } + return $wp_rules; + } + + /** + * Returns the URL for the sitemap file + * + * @since 3.0 + * + * @param string $type . + * @param string $params . + * @param array $build_options . + * @return string The URL to the Sitemap file + */ + public function get_xml_url( $type = '', $params = '', $build_options = array() ) { + + $pl = $this->is_using_permalinks(); + $options = ''; + if ( ! empty( $type ) ) { + if($type != 'pt') $options .= $type; + if ( ! empty( $params ) ) { + //$options .= '-' . $params; + $options .= $params; + } + } + + $build_options = array_merge( $this->build_options, $build_options ); + + $html = ( isset( $build_options['html'] ) ? $build_options['html'] : false ); + $zip = ( isset( $build_options['zip'] ) ? $build_options['zip'] : false ); + + $base_url = get_bloginfo( 'url' ); + + // Manual override for root URL . + $base_url_settings = $this->get_option( 'b_baseurl' ); + $sm_sitemap_name = $this->get_option( 'b_sitemap_name' ); + $old_sm_name = $this->get_option( 'b_old_sm_name' ); + if ( ! empty( $base_url_settings ) ) { + $base_url = $base_url_settings; + } elseif ( defined( 'SM_BASE_URL' ) && SM_BASE_URL ) { + $base_url = SM_BASE_URL; + } + global $wp_rewrite; + if ( $old_sm_name !== $sm_sitemap_name ) { + $this->set_option( 'sm_b_old_sm_name', $sm_sitemap_name ); + delete_option( 'sm_rewrite_done' ); + wp_clear_scheduled_hook( 'sm_ping_daily' ); + self::remove_rewrite_hooks(); + $wp_rewrite->flush_rules( false ); + self::setup_rewrite_hooks(); + GoogleSitemapGeneratorLoader::activate_rewrite(); + } + + if ( $pl ) { + //return trailingslashit( $base_url ) . ( '' === $sm_sitemap_name ? 'sitemap' : $sm_sitemap_name ) . ( $options ? '-' . $options : '' ) . ( $html + // ? '.html' : '.xml' ) . ( $zip ? '.gz' : '' ); + if($type === 'misc') return trailingslashit( $base_url ) . ( '' === $sm_sitemap_name ? 'sitemap' : $sm_sitemap_name ) . ( $options ? '-' . $options : '' ) . ( $html + ? '.html' : '.xml' ) . ( $zip ? '.gz' : '' ); + else if($type === 'main') return trailingslashit( $base_url ). ( substr($_SERVER['REQUEST_URI'], -4) === '.xml' ? '.html' : '.html' ) . ( $zip ? '.gz' : '' ); + else return trailingslashit( $base_url ) . ( '' !== $sm_sitemap_name ? '' : $sm_sitemap_name ) . ( $options ? '' . $options : '' ) . ( $html + ? '.html' : '.xml' ) . ( $zip ? '.gz' : '' ); + } else { + return trailingslashit( $base_url ) . 'index.php?xml_sitemap=params=' . $options . ( $html + ? ';html=true' : '' ) . ( $zip ? ';zip=true' : '' ); + } + } + + /* + Returns base sitemap url + */ + + public function get_base_sitemap_url(){ + $build_options = []; + $build_options = array_merge( $this->build_options, $build_options ); + + $html = ( isset( $build_options['html'] ) ? $build_options['html'] : false ); + $zip = ( isset( $build_options['zip'] ) ? $build_options['zip'] : false ); + $base_url = get_bloginfo( 'url' ); + if($this->get_options()['sm_b_sitemap_name']) $file_name = $this->get_options()['sm_b_sitemap_name']; + return trailingslashit( $base_url ) . ($file_name?$file_name:'sitemap') . ( $html ? '.html' : '.xml' ) . ( $zip ? '.gz' : '' ); + } + + /** + * Returns if there is still an old sitemap file in the site directory + * + * @return Boolean True if a sitemap file still exists + */ + public function old_file_exists() { + $sm_sitemap_name = $this->get_option( 'b_sitemap_name' ); + $path = trailingslashit( get_home_path() ); + return ( file_exists( $path . $sm_sitemap_name . '.xml' ) || file_exists( $path . 'sitemap.xml.gz' ) ); + } + + /** + * Renames old sitemap files in the site directory from previous versions of this plugin + * + * @return bool True on success + */ + public function delete_old_files() { + $path = trailingslashit( get_home_path() ); + + $res = true; + $f = $path . 'sitemap.xml'; + if ( file_exists( $f ) ) { + if ( ! rename( $f, $path . 'sitemap.backup.xml' ) ) { + $res = false; + } + } + $f = $path . 'sitemap.xml.gz'; + if ( file_exists( $f ) ) { + if ( ! rename( $f, $path . 'sitemap.backup.xml.gz' ) ) { + $res = false; + } + } + + return $res; + } + + + /*************************************** SITEMAP SIMULATION ***************************************/ + + /** + * Simulates the building of the sitemap index file. + * + * @see GoogleSitemapGenerator::simulate_sitemap + * @since 4.0 + * @return array The data of the sitemap index file + */ + public function simulate_index() { + + $this->sim_mode = true; + + require_once trailingslashit( dirname( __FILE__ ) ) . 'class-googlesitemapgeneratorstandardbuilder.php'; + do_action( 'sm_build_index', $this ); + + $this->sim_mode = false; + + $r = $this->sim_data['sitemaps']; + + $this->clear_sim_data( 'sitemaps' ); + + return $r; + } + + /** + * Simulates the building of the sitemap file. + * + * @see GoogleSitemapGenerator::simulate_index + * @since 4.0 + * @param string $type string The type of the sitemap . + * @param string $params string Additional parameters for this type . + * @return array The data of the sitemap file + */ + public function simulate_sitemap( $type, $params ) { + + $this->sim_mode = true; + + require_once trailingslashit( dirname( __FILE__ ) ) . 'class-googlesitemapgeneratorstandardbuilder.php'; + do_action( 'sm_build_content', $this, $type, $params ); + + $this->sim_mode = false; + + $r = $this->sim_data['content']; + + $this->clear_sim_data( 'content' ); + + return $r; + } + + /** + * Clears the data of the simulation + * + * @param string $what Defines what to clear, either both, sitemaps or content . + * @see GoogleSitemapGenerator::simulate_index + * @see GoogleSitemapGenerator::simulate_sitemap + * @since 4.0 + */ + public function clear_sim_data( $what ) { + if ( 'both' === $what || 'sitemaps' === $what ) { + $this->sim_data['sitemaps'] = array(); + } + + if ( 'both' === $what || 'content' === $what ) { + $this->sim_data['content'] = array(); + } + } + + /** + * Returns the first caller outside of this __CLASS__ + * + * @param array $trace The backtrace . + * @return array The caller information + */ + private function get_external_backtrace( $trace ) { + $caller = null; + foreach ( $trace as $b ) { + if ( __CLASS__ !== $b['class'] ) { + $caller = $b; + break; + } + } + return $caller; + } + + + /*************************************** SITEMAP BUILDING ***************************************/ + + /** + * Shows the sitemap. Main entry point from HTTP + * + * @param string $options Options for the sitemap. What type, what parameters. + * @since 4.0 + */ + public function show_sitemap( $options ) { + + $start_time = microtime( true ); + $start_queries = $GLOBALS['wpdb']->num_queries; + $start_memory = memory_get_peak_usage( true ); + $disable_functions = ini_get( 'disable_functions' ); + + // Raise memory and time limits . + if ( $this->get_option( 'b_memory' ) !== '' ) { + wp_raise_memory_limit( $this->get_option( 'b_memory' ) ); + + } + if ( $this->get_option( 'b_time' ) !== -1 && $this->get_option( 'b_time' ) !== null ) { + if ( strpos( $disable_functions, 'set_time_limit' ) === false ) { + set_time_limit( $this->get_option( 'b_time' ) ); + } + } + + do_action( 'sm_init', $this ); + + $this->is_active = true; + + $parsed_options = array(); + + $options = explode( ';', $options ); + foreach ( $options as $k ) { + $kv = explode( '=', $k ); + $parsed_options[ $kv[0] ] = $kv[1]; + } + + $options = $parsed_options; + + $this->build_options = $options; + + // Do not index the actual XML pages, only process them. + // This avoids that the XML sitemaps show up in the search results. + if ( ! headers_sent() && isset( $this->build_options['html'] ) ) { + if ( $this->build_options['html'] == "true" ) { + header( 'X-Robots-Tag: index, follow', true, 200 ); + } + } + + $this->initate(); + + $html = ( isset( $options['html'] ) ? $options['html'] : false ) && $this->is_xsl_enabled(); + if ( $html && ! $this->get_option( 'b_html' ) ) { + $GLOBALS['wp_query']->is_404 = true; + return; + } + + // Don't zip if anything happened before which could break the output or if the client does not support gzip. + // If there are already other output filters, there might be some content on another + // filter level already, which we can't detect. Zipping then would lead to invalid content. + $pack = ( isset( $options['zip'] ) ? $options['zip'] : $this->get_option( 'b_autozip' ) ); + if ( + empty( $_SERVER['HTTP_ACCEPT_ENCODING'] ) // No encoding support. + || strpos( sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_ENCODING'] ) ), 'gzip' ) === false // or no gzip. + || ! $this->is_gzip_enabled() // No PHP gzip support. + || headers_sent() // Headers already sent. + || ob_get_contents() // there was already some output.... + || in_array( 'ob_gzhandler', ob_list_handlers(), true ) // Some other plugin (or PHP) is already gzipping. + || $this->get_php_ini_boolean( ini_get( 'zlib.output_compression' ) ) // Zlib compression in php.ini enabled. + || ob_get_level() > ( ! $this->get_php_ini_boolean( ini_get( 'output_buffering' ) ) ? 0 : 1 ) // Another output buffer (beside of the default one) is already active. + || ( isset( $_SERVER['HTTP_X_VARNISH'] ) && is_numeric( $_SERVER['HTTP_X_VARNISH'] ) ) // Behind a Varnish proxy. + ) { + $pack = false; + } + + $packed = false; + + if ( $pack ) { + $packed = ob_start( 'ob_gzhandler' ); + } + + $builders = array( 'class-googlesitemapgeneratorstandardbuilder.php' ); + foreach ( $builders as $b ) { + $f = trailingslashit( dirname( __FILE__ ) ) . $b; + if ( file_exists( $f ) ) { + require_once $f; + } + } + + if ( $html ) { + ob_start(); + } else { + header( 'Content-Type: text/xml; charset=utf-8' ); + } + + if ( empty( $options['params'] ) || 'index' === $options['params'] ) { + + $this->build_sitemap_header( 'index' ); + + do_action( 'sm_build_index', $this ); + + $this->build_sitemap_footer( 'index' ); + $this->add_end_commend( $start_time, $start_queries, $start_memory ); + } else { + $all_params = $options['params']; + $type = null; + $params = null; + + if ( strpos( $all_params, '-' ) !== false ) { + $type = substr( $all_params, 0, strpos( $all_params, '-' ) ); + if($type === 'pt' && explode("-", $all_params)[1] === 'externals' ) $type = 'externals'; + $params = substr( $all_params, strpos( $all_params, '-' ) + 1 ); + } else { + $type = $all_params; + } + + $this->build_sitemap_header( 'sitemap' ); + + do_action( 'sm_build_content', $this, $type, $params ); + + $this->build_sitemap_footer( 'sitemap' ); + + $this->add_end_commend( $start_time, $start_queries, $start_memory ); + } + + if ( $html ) { + $xml_source = ob_get_clean(); + + // Load the XML source. + $xml = new DOMDocument(); + $xml->loadXML( $xml_source ); + + $xsl = new DOMDocument(); + $xsl->load( $this->get_plugin_path() . 'sitemap.xsl' ); + + // Configure the transformer. + $proc = new XSLTProcessor(); + $proc->importStyleSheet( $xsl ); // Attach the xsl rules. + + $dom_tran_obj = $proc->transformToDoc( $xml ); + + // This will also output doctype and comments at top level. + // phpcs:disable + global $allowedposttags; + $allowed_atts = array( + 'align' => array(), + 'class' => array(), + 'type' => array(), + 'id' => array(), + 'dir' => array(), + 'lang' => array(), + 'style' => array(), + 'xml:lang' => array(), + 'src' => array(), + 'alt' => array(), + 'href' => array(), + 'rel' => array(), + 'rev' => array(), + 'target' => array(), + 'novalidate' => array(), + 'type' => array(), + 'value' => array(), + 'name' => array(), + 'tabindex' => array(), + 'action' => array(), + 'method' => array(), + 'for' => array(), + 'width' => array(), + 'height' => array(), + 'data' => array(), + 'title' => array(), + ); + $allowedposttags['form'] = $allowed_atts; + $allowedposttags['label'] = $allowed_atts; + $allowedposttags['input'] = $allowed_atts; + $allowedposttags['textarea'] = $allowed_atts; + $allowedposttags['iframe'] = $allowed_atts; + $allowedposttags['script'] = $allowed_atts; + $allowedposttags['style'] = $allowed_atts; + $allowedposttags['strong'] = $allowed_atts; + $allowedposttags['small'] = $allowed_atts; + $allowedposttags['table'] = $allowed_atts; + $allowedposttags['span'] = $allowed_atts; + $allowedposttags['abbr'] = $allowed_atts; + $allowedposttags['code'] = $allowed_atts; + $allowedposttags['pre'] = $allowed_atts; + $allowedposttags['div'] = $allowed_atts; + $allowedposttags['img'] = $allowed_atts; + $allowedposttags['h1'] = $allowed_atts; + $allowedposttags['h2'] = $allowed_atts; + $allowedposttags['h3'] = $allowed_atts; + $allowedposttags['h4'] = $allowed_atts; + $allowedposttags['h5'] = $allowed_atts; + $allowedposttags['h6'] = $allowed_atts; + $allowedposttags['ol'] = $allowed_atts; + $allowedposttags['ul'] = $allowed_atts; + $allowedposttags['li'] = $allowed_atts; + $allowedposttags['em'] = $allowed_atts; + $allowedposttags['hr'] = $allowed_atts; + $allowedposttags['br'] = $allowed_atts; + $allowedposttags['tr'] = $allowed_atts; + $allowedposttags['td'] = $allowed_atts; + $allowedposttags['p'] = $allowed_atts; + $allowedposttags['a'] = $allowed_atts; + $allowedposttags['b'] = $allowed_atts; + $allowedposttags['i'] = $allowed_atts; + foreach ( $dom_tran_obj->childNodes as $node ) { + // phpcs:enable + echo wp_kses( $dom_tran_obj->saveXML( $node ), $allowedposttags ) . "\n"; + } + } + + if ( $packed ) { + ob_end_flush(); + } + $this->is_active = false; + exit; + } + + /** + * Generates the header for the sitemap with XML declarations, stylesheet and so on. + * + * @since 4.0 + * @param string $format The format, either sitemap for a sitemap or index for the sitemap index . + */ + private function build_sitemap_header( $format ) { + + if ( ! in_array( $format, array( 'sitemap', 'index' ), true ) ) { + $format = 'sitemap'; + } + $this->add_element( new GoogleSitemapGeneratorXmlEntry( '' ) ); + $style_sheet = ( $this->get_default_style() && $this->get_option( 'b_style_default' ) === true + ? $this->get_default_style() : $this->get_option( 'b_style' ) ); + + if ( ! empty( $style_sheet ) ) { + $this->add_element( new GoogleSitemapGeneratorXmlEntry( '<' . '?xml-stylesheet type=\'text/xsl\' href=\'' . esc_url( $style_sheet ) . '\'?>' ) ); + } + $this->add_element( new GoogleSitemapGeneratorDebugEntry( 'sitemap-generator-url=\'http://www.arnebrachhold.de\' sitemap-generator-version=\'' . $this->get_version() . '\'' ) ); + $this->add_element( new GoogleSitemapGeneratorDebugEntry( 'generated-on=\'' . gmdate( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ) . '\'' ) ); + + switch ( $format ) { + case 'sitemap': + $urlset = ''; + $urlset = apply_filters( 'sm_sitemap_urlset', $urlset ); + $this->add_element( new GoogleSitemapGeneratorXmlEntry( $urlset ) ); + break; + case 'index': + $urlset = ''; + $this->add_element( new GoogleSitemapGeneratorXmlEntry( $urlset ) ); + break; + } + } + + /** + * Generates the footer for the sitemap with XML ending tag + * + * @since 4.0 + * @param string $format The format, either sitemap for a sitemap or index for the sitemap index. + */ + private function build_sitemap_footer( $format ) { + if ( ! in_array( $format, array( 'sitemap', 'index' ), true ) ) { + $format = 'sitemap'; + } + switch ( $format ) { + case 'sitemap': + $this->add_element( new GoogleSitemapGeneratorXmlEntry( '' ) ); + break; + case 'index': + $this->add_element( new GoogleSitemapGeneratorXmlEntry( '' ) ); + break; + } + } + + /** + * Adds information about time and memory usage to the sitemap + * + * @since 4.0 + * @param float $start_time The microtime of the start . + * @param int $start_queries . + * @param int $start_memory . + */ + private function add_end_commend( $start_time, $start_queries = 0, $start_memory = 0 ) { + if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { + echo ' '; + } + $end_time = microtime( true ); + + $end_time = round( $end_time - $start_time, 2 ); + $spent_memory = intval((memory_get_peak_usage( true ) - $start_memory) / 1024); + if ($spent_memory > 1023) { + $spent_memory = intval($spent_memory / 1024) . 'MB'; + } else { + $spent_memory = ceil($spent_memory) + 1 . 'KB'; + } + //$this->add_element( new GoogleSitemapGeneratorDebugEntry( 'Request ID: ' . md5( microtime() ) . '; Queries for sitemap: ' . ( $GLOBALS['wpdb']->num_queries - $start_queries ) . '; Total queries: ' . $GLOBALS['wpdb']->num_queries . "; Seconds: $end_time; Memory for sitemap: " . ( ( memory_get_peak_usage( true ) - $start_memory ) / 1024 / 1024 ) . 'MB; Total memory: ' . ( memory_get_peak_usage( true ) / 1024 / 1024 ) . 'MB' ) ); + $this->add_element( new GoogleSitemapGeneratorDebugEntry( 'Request ID: ' . md5( microtime() ) . '; Queries for sitemap: ' . ( $GLOBALS['wpdb']->num_queries - $start_queries ) . '; Total queries: ' . $GLOBALS['wpdb']->num_queries . "; Seconds: $end_time; Memory for sitemap: " . $spent_memory. '; Total memory: ' . ( memory_get_peak_usage( true ) / 1024 / 1024 ) . 'MB' ) ); + } + + /** + * Adds the sitemap to the virtual robots.txt file + * This function is executed by WordPress with the do_robots hook + * + * @since 3.1.2 + */ + public function do_robots() { + $this->initate(); + if ( $this->get_option( 'b_robots' ) === true ) { + + //$sm_url = $this->get_xml_url(); + // $html = ( isset( $build_options['html'] ) ? $build_options['html'] : false ); + $zip = ( isset( $build_options['zip'] ) ? $build_options['zip'] : false ); + $b_html = ( null !== $this->get_option('b_html') ? $this->get_option('b_html') : false ); + if ( $this->get_option( 'b_sitemap_name' ) ) { + $sm_url = trailingslashit( get_bloginfo( 'url' ) ) . ( '' === $this->get_option( 'b_sitemap_name' ) ? '' : $this->get_option( 'b_sitemap_name' ) ) . '.xml' . ( $zip ? '.gz' : '' ); + $sm_html_url = trailingslashit( get_bloginfo( 'url' ) ) . ( '' === $this->get_option( 'b_sitemap_name' ) ? '' : $this->get_option( 'b_sitemap_name' ) ) . '.html' . ( $zip ? '.gz' : '' ); + } + else { + $sm_url = get_bloginfo( 'url' ) . '/sitemap.xml'; + $sm_html_url = get_bloginfo( 'url' ) . '/sitemap.html'; + } + + echo "\nSitemap: " . esc_url( $sm_url ) . "\n"; + if ( $b_html ) echo "Sitemap: " . esc_url( $sm_html_url ) . "\n"; + } + } + + + /*************************************** SITEMAP CONTENT BUILDING ***************************************/ + + /** + * Outputs an element in the sitemap + * + * @since 3.0 + * @param object $page GoogleSitemapGeneratorXmlEntry The element . + */ + public function add_element( $page ) { + + if ( empty( $page ) ) { + return; + } + + // phpcs:disable + echo $page->render(); + // phpcs:enable + } + + /** + * Adds a url to the sitemap. You can use this method or call add_element directly. + * + * @since 3.0 + * @param int $loc string The location (url) of the page . + * @param int $last_mod int The last Modification time as a UNIX timestamp . + * @param string $change_freq string The change frequenty of the page, Valid values are 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly' and 'never'. . + * @param float $priority float The priority of the page, between 0.0 and 1.0 . + * @param int $post_id int The post ID in case this is a post or page . + * @see add_element + */ + public function add_url( $loc, $last_mod = 0, $change_freq = 'monthly', $priority = 0.5, $post_id = 0 ) { + // Strip out the last modification time if activated . + if ( $this->get_option( 'in_lastmod' ) === false ) { + $last_mod = 0; + } + $page = new GoogleSitemapGeneratorPage( $loc, $priority, $change_freq, $last_mod, $post_id ); + + do_action( 'sm_addurl', $page ); + + if ( $this->sim_mode ) { + // phpcs:disable WordPress.PHP.DevelopmentFunctions + $caller = $this->get_external_backtrace( debug_backtrace() ); + // phpcs:enable + $this->sim_data['content'][] = array( + 'data' => $page, + 'caller' => $caller, + ); + } else { + $this->add_element( $page ); + } + } + + /** + * Add a sitemap entry to the index file + * + * @param string $type . + * @param string $params . + * @param int $last_mod . + */ + public function add_sitemap( $type, $params = '', $last_mod = 0 ) { + + $url = $this->get_xml_url( $type, $params ); + + $sitemap = new GoogleSitemapGeneratorSitemapEntry( $url, $last_mod ); + + do_action( 'sm_addsitemap', $sitemap ); + + if ( $this->sim_mode ) { + // phpcs:disable WordPress.PHP.DevelopmentFunctions + $caller = $this->get_external_backtrace( debug_backtrace() ); + // phpcs:enable + $this->sim_data['sitemaps'][] = array( + 'data' => $sitemap, + 'type' => $type, + 'params' => $params, + 'caller' => $caller, + ); + } else { + $this->add_element( $sitemap ); + } + } + + + /*************************************** PINGS ***************************************/ + + /** + * Sends the pings to the search engines + * + * @return GoogleSitemapGeneratorStatus The status object + */ + public function send_ping() { + + $this->load_options(); + + $ping_url = $this->get_xml_url(); + + $baseUrl = substr($ping_url, 0, -4); + $kind = substr($ping_url, -4); + $ping_url = $baseUrl . $this->get_options()['sm_b_sitemap_name'] . $kind; + + $result = $this->execute_ping( $ping_url, true ); + + $post_id = get_transient( 'sm_ping_post_id' ); + + if ( $post_id ) { + + require_once trailingslashit( dirname( __FILE__ ) ) . 'class-googlesitemapgeneratorstandardbuilder.php'; + + $urls = array(); + + $urls = apply_filters( 'sm_sitemap_for_post', $urls, $this, $post_id ); + if ( is_array( $urls ) && count( $urls ) > 0 ) { + foreach ( $urls as $url ) { + $this->execute_ping( $url, false ); + } + } + + delete_transient( 'sm_ping_post_id' ); + } + + return $result; + } + + + /** + * Execute Ping + * + * @param string $ping_url string The Sitemap URL to ping . + * @param bool $update_status If the global ping status should be updated . + * + * @return \GoogleSitemapGeneratorStatus + */ + protected function execute_ping( $ping_url, $update_status = true ) { + + $status = new GoogleSitemapGeneratorStatus( $update_status ); + + if ( $ping_url ) { + $pings = array(); + + if ( $this->get_option( 'b_ping' ) ) { + $pings['bing'] = array( + 'name' => 'Bing', + 'check' => 'successfully', + ); + } + + if ($pings) { + foreach ( $pings as $service_id => $service ) { + //$url = rawurlencode( $ping_url ); + $url = $ping_url; + $status->start_ping( $service_id, $url, $service['name'] ); + + $newUrlToIndex = new GoogleSitemapGeneratorIndexNow(); + $pingres = $newUrlToIndex->start( $url ); + + if ( null === $pingres || false === $pingres || false === strpos( $pingres, $service['check'] ) ) { + $status->end_ping( $service_id, false ); + } else { + $status->end_ping( $service_id, true ); + } + } + } + + $this->set_option( 'i_lastping', time() ); + $this->save_options(); + } + + $status->end(); + + return $status; + } + + /** + * Tries to ping a specific service showing as much as debug output as possible + * + * @since 4.1 + * @return array + */ + public function send_ping_all() { + + $this->load_options(); + + $sitemaps = $this->simulate_index(); + + $urls = array(); + + $ping_url = $this->get_xml_url(); + $baseUrl = substr($ping_url, 0, -4); + $kind = substr($ping_url, -4); + $urls[] = $baseUrl . $this->get_options()['sm_b_sitemap_name'] . $kind; + //$urls[] = $this->get_xml_url(); + + foreach ( $sitemaps as $sitemap ) { + + // @var $s GoogleSitemapGeneratorSitemapEntry . + $s = $sitemap['data']; + + $urls[] = $s->get_url(); + } + + $results = array(); + + $first = true; + + foreach ( $urls as $url ) { + $status = $this->execute_ping( $url, $first ); + $results[] = array( + 'sitemap' => $url, + 'status' => $status, + ); + $first = false; + } + return $results; + } + + /** + * Tries to ping a specific service showing as much as debug output as possible + * + * @since 3.1.9 + * @return null + */ + public function show_ping_result() { + + check_admin_referer( 'sitemap' ); + + if ( ! current_user_can( 'administrator' ) ) { + echo '

        Please log in as admin

        '; + return; + } + + $service = ! empty( $_GET['sm_ping_service'] ) ? sanitize_text_field( wp_unslash( $_GET['sm_ping_service'] ) ) : null; + + $status = GoogleSitemapGeneratorStatus::load(); + + if ( ! $status ) { + die( 'No build status yet. Write something first.' ); + } + + $url = null; + + $services = $status->get_used_ping_services(); + + if ( ! in_array( $service, $services, true ) ) { + die( 'Invalid service' ); + } + + $url = $status->get_ping_url( $service ); + + if ( empty( $url ) ) { + die( 'Invalid ping url' ); + } + + echo 'Ping Test'; + if ( function_exists( 'wp_admin_css' ) ) { + wp_admin_css( 'css/global', true ); + } + echo '

        Ping Test

        '; + + echo '

        Trying to ping: ' . esc_html( $url ) . '. The sections below should give you an idea whats going on.

        '; + + // Try to get as much as debug / error output as possible . + $err_level = error_reporting( E_ALL ); + if ( ! defined( 'WP_DEBUG_DISPLAY' ) ) { + define( 'WP_DEBUG_DISPLAY', true ); + } + + if ( ! defined( 'WP_DEBUG' ) ) { + define( 'WP_DEBUG', true ); + } + + echo '

        Errors, Warnings, Notices:

        '; + + if ( WP_DEBUG === false ) { + echo 'WP_DEBUG was set to false somewhere before. You might not see all debug information until you remove this declaration!
        '; + } + if ( ini_get( 'display_errors' ) !== 1 ) { + echo 'Your display_errors setting currently prevents the plugin from showing errors here. Please check your webserver logfile instead.
        '; + } + + $res = $this->remote_open( $url ); + + echo '

        Result (text only):

        '; + + echo wp_kses( + $res, + array( + 'a' => array( 'href' => array() ), + 'p' => array(), + 'ul' => array(), + 'ol' => array(), + 'li' => array(), + ) + ); + + echo '

        Result (HTML):

        '; + + esc_html( htmlspecialchars( $res ) ); + + // Revert back old values . + // error_reporting( $err_level ); . + echo ''; + exit; + } + + /** + * Opens a remote file using the WordPress API + * + * @since 3.0 + * @param string $url string The URL to open . + * @param string $method string get or post . + * @param object $post_data array An array with key=>value paris . + * @param int $timeout int Timeout for the request, by default 10 . + * @return mixed False on error, the body of the response on success + */ + public static function remote_open( $url, $method = 'get', $post_data = null, $timeout = 10 ) { + $options = array(); + $options['timeout'] = $timeout; + + if ( 'get' === $method ) { + $response = wp_remote_get( $url, $options ); + } else { + $response = wp_remote_post( + $url, + array_merge( + $options, + array( + 'body' => $post_data, + ) + ) + ); + } + + if ( is_wp_error( $response ) ) { + $errs = $response->get_error_messages(); + $errs = htmlspecialchars( implode( '; ', $errs ) ); + // phpcs:disable WordPress.PHP.DevelopmentFunctions + trigger_error( 'WP HTTP API Web Request failed: ' . esc_html( $errs ), E_USER_NOTICE ); + // phpcs:enable + return false; + } + + return $response['body']; + } + + /** + * Sends anonymous statistics (disabled by default) + */ + private function send_stats() { + global $wp_version, $wpdb; + $post_count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts} p WHERE p.post_status='publish'" ); // db call ok; no-cache ok. + + // Send simple post count statistic to get an idea in which direction this plugin should be optimized . + // Only a rough number is required, so we are rounding things up . + if ( $post_count <= 5 ) { + $post_count = 5; + } elseif ( $post_count < 25 ) { + $post_count = 10; + } elseif ( $post_count < 35 ) { + $post_count = 25; + } elseif ( $post_count < 75 ) { + $post_count = 50; + } elseif ( $post_count < 125 ) { + $post_count = 100; + } elseif ( $post_count < 2000 ) { + $post_count = round( $post_count / 200 ) * 200; + } elseif ( $post_count < 10000 ) { + $post_count = round( $post_count / 1000 ) * 1000; + } else { + $post_count = round( $post_count / 10000 ) * 10000; + } + $user = wp_get_current_user(); + + $post_data = array( + 'v' => 1, + 'tid' => $this->get_option( 'i_tid' ), + 'cid' => $this->get_option( 'i_hash' ), + 'aip' => 1, // Anonymize . + 't' => 'event', + 'ec' => 'ping', + 'el' => 'settings_saved', + 'ea' => 'auto', + 'ev' => 1, + 'cd1' => $wp_version, + 'cd2' => $this->get_version(), + 'cd3' => PHP_VERSION, + 'cd4' => $post_count, + 'cd5' => $user->user_email, + 'cd6' => 'https://' . $_SERVER['HTTP_HOST'], + 'ul' => get_bloginfo( 'language' ), + ); + + $this->remote_open( 'http://www.google-analytics.com/collect', 'post', $post_data ); + } + + /** + * Returns the number of seconds the support feed should be cached (1 week) + * + * @return int The number of seconds + */ + public static function get_support_feed_cache_lifetime() { + return 60 * 60 * 24 * 7; + } + + /** + * Returns the SimplePie instance of the support feed + * The feed is cached for one week + * + * @return SimplePie|WP_Error + */ + public function get_support_feed() { + + $call_back = array( __CLASS__, 'get_support_feed_cache_lifetime' ); + + // Extend cache lifetime so we don't request the feed to often . + add_filter( 'wp_feed_cache_transient_lifetime', $call_back ); + $result = fetch_feed( SM_SUPPORTFEED_URL ); + remove_filter( 'wp_feed_cache_transient_lifetime', $call_back ); + + return $result; + } + + /** + * Handles daily ping + */ + public function send_ping_daily() { + + $this->load_options(); + + $blog_update = strtotime( get_lastpostdate( 'blog' ) ); + $last_ping = $this->get_option( 'i_lastping' ); + $yesterday = time() - ( 60 * 60 * 24 ); + + if ( $blog_update >= $yesterday && ( 0 === $last_ping || $last_ping <= $yesterday ) ) { + $this->send_ping(); + } + + // Send statistics if enabled (disabled by default) . + if ( $this->get_option( 'b_stats' ) ) { + $this->send_stats(); + } + + // Cache the support feed so there is no delay when loading the user interface . + if ( $this->get_option( 'i_supportfeed' ) ) { + $last = $this->get_option( 'i_supportfeed_cache' ); + if ( $last <= ( time() - $this->get_support_feed_cache_lifetime() ) ) { + $support_feed = $this->get_support_feed(); + if ( ! is_wp_error( $support_feed ) && $support_feed ) { + $this->set_option( 'i_supportfeed_cache', time() ); + $this->save_options(); + } + } + } + } + + + /*************************************** USER INTERFACE ***************************************/ + + /** + * Includes the user interface class and initializes it + * + * @since 3.1.1 + * @see GoogleSitemapGeneratorUI + * @return GoogleSitemapGeneratorUI + */ + private function get_ui() { + + if ( null === $this->ui ) { + + $class_name = 'GoogleSitemapGeneratorUI'; + $file_name = 'class-googlesitemapgeneratorui.php'; + + if ( ! class_exists( $class_name ) ) { + + $path = trailingslashit( dirname( __FILE__ ) ); + + if ( ! file_exists( $path . $file_name ) ) { + return false; + } + require_once $path . $file_name; + } + + $this->ui = new $class_name( $this, new GoogleSitemapGeneratorIndexNow() ); + } + + return $this->ui; + } + + /** + * Shows the option page of the plugin. Before 3.1.1, this function was basically the UI, afterwards the UI was outsourced to another class + * + * @see GoogleSitemapGeneratorUI + * @since 3.0 + * @return bool + */ + public function html_show_options_page() { + + $ui = $this->get_ui(); + if ( $ui ) { + $ui->html_show_options_page(); + return true; + } + + return false; + } + + /*************************************** HELPERS ***************************************/ + + /** + * Returns if the given value is greater than zero + * + * @param int $value int The value to check . + * @since 4.0b10 + * @return bool True if greater than zero + */ + public function is_greater_zero( $value ) { + return ( $value > 0 ); + } + + /** + * Converts the various possible php.ini values for true and false to boolean + * + * @param string $value string The value from ini_get . + * + * @return bool The converted value + */ + public function get_php_ini_boolean( $value ) { + if ( is_string( $value ) ) { + switch ( strtolower( $value ) ) { + case '+': + case '1': + case 'y': + case 'on': + case 'yes': + case 'true': + case 'enabled': + return true; + + case '-': + case '0': + case 'n': + case 'no': + case 'off': + case 'false': + case 'disabled': + return false; + } + } + + return (bool) $value; + } + + + /** + * Show surevey method . + */ + public function show_survey() { + $this->load_options(); + if ( isset( $_REQUEST['sm_survey'] ) ) { + return ( sanitize_text_field( wp_unslash( $_REQUEST['sm_survey'] ) ) ) || ! $this->get_option( 'i_hide_survey' ); + } + } + + /** + * Html survey method . + */ + public function html_survey() { + ?> +
        + +

        + Please help us improve by taking this short survey!', 'google-sitemap-generator' ) + ) + ); + ?> + ' style='float:right; display:block; border:none;'> +

        +
        +
        +
        + 4 ) { + include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api.. +} + +require_once trailingslashit( dirname( __FILE__ ) ) . 'sitemap-core.php'; +require_once trailingslashit( dirname( __FILE__ ) ) . 'class-googlesitemapgeneratorindexnow.php'; //add class indexNow file + +include_once( ABSPATH . 'wp-admin/includes/file.php' ); +include_once( ABSPATH . 'wp-admin/includes/misc.php' ); +include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); + +define( 'SM_SUPPORTFEED_URL', 'https://wordpress.org/support/plugin/google-sitemap-generator/feed/' ); +define( 'SM_BETA_USER_INFO_URL', 'https://api.auctollo.com/beta/consent' ); +define( 'SM_LEARN_MORE_API_URL', 'https://api.auctollo.com/lp' ); +define( 'SM_BANNER_HIDE_DURATION_IN_DAYS', 7 ); +define( 'SM_CONFLICT_PLUGIN_LIST', 'All in One SEO,Yoast SEO, Jetpack, Wordpress Sitemap' ); +add_action( 'admin_init', 'register_consent', 1 ); +add_action( 'admin_head', 'ga_header' ); +add_action( 'admin_footer', 'ga_footer' ); +add_action( 'plugins_loaded', function() { + load_plugin_textdomain( 'google-sitemap-generator', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' ); + + +}); + +add_action( 'transition_post_status', 'indexnow_after_post_save', 10, 3 ); //send to indexNow + +add_action('wpmu_new_blog', 'disable_conflict_sitemaps_on_new_blog', 10, 6); + +function disable_conflict_sitemaps_on_new_blog($blog_id, $user_id, $domain, $path, $site_id, $meta) { + switch_to_blog($blog_id); + $aioseo_option_key = 'aioseo_options'; + if (get_option($aioseo_option_key) !== null) { + $aioseo_options = get_option($aioseo_option_key); + $aioseo_options = json_decode($aioseo_options, true); + $aioseo_options['sitemap']['general']['enable'] = false; + update_option($aioseo_option_key, json_encode($aioseo_options)); + } + restore_current_blog(); +} + +add_action('parse_request', 'plugin_check_sitemap_request'); +function plugin_check_sitemap_request($wp) { + if(is_multisite()) { + if(isset(get_blog_option( get_current_blog_id(), 'sm_options' )['sm_b_sitemap_name'])) { + $sm_sitemap_name = get_blog_option( get_current_blog_id(), 'sm_options' )['sm_b_sitemap_name']; + } + } else if(isset(get_option('sm_options')['sm_b_sitemap_name'])) $sm_sitemap_name = get_option('sm_options')['sm_b_sitemap_name']; + + if(isset($wp->request) && $wp->request === 'wp-sitemap.xml' && $sm_sitemap_name !== 'sitemap') { + status_header(404); + nocache_headers(); + include( get_query_template( '404' ) ); + exit; + } +} + +/** + * Google analytics . + */ +function ga_header() { + if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { + global $wp_version; + $window_url = 'http://' . $_SERVER[ 'HTTP_HOST' ] . $_SERVER[ 'REQUEST_URI' ]; + $parts = wp_parse_url( $window_url ); + $current_page = ''; + + $window_url = home_url() . $_SERVER[ 'REQUEST_URI' ]; + $parts = wp_parse_url( $window_url ); + $current_page = ''; + $current_url = $_SERVER['REQUEST_URI']; + if ( isset( $parts['query'] ) ) { + parse_str( $parts['query'], $query ); + if ( isset( $query['page'] ) ) { + $current_page = $query['page']; + } + } + $plugin_version = GoogleSitemapGeneratorLoader::get_version(); + + $consent_value = get_option( 'sm_user_consent' ); + + echo ""; + if ( 'yes' === $consent_value && 'google-sitemap-generator/sitemap.php' === $current_page ) { + echo " + + "; + } + if ( isset( $parts['query'] ) ) { + parse_str( $parts['query'], $query ); + if ( isset( $query['page'] ) ) { + $current_page = $query['page']; + if ( strpos( $current_page, 'google-sitemap-generator' ) !== false ) { + echo " + "; + } else { + echo ''; + } + } else { + echo ''; + } + } else { + echo ""; + return; + } + } +} + +/** + * Google analytics . + */ +function ga_footer() { + if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { + $banner_discarded_count = get_option( 'sm_beta_banner_discarded_count' ); + if ( 1 === $banner_discarded_count || '1' === $banner_discarded_count ) { + echo ''; + } + } +} + +/** + * Check if the requirements of the sitemap plugin are met and loads the actual loader + * + * @package sitemap + * @since 4.0 + */ +function sm_setup() { + + $fail = false; + + // Check minimum PHP requirements, which is 5.2 at the moment. + if ( version_compare( PHP_VERSION, '5.2', '<' ) ) { + add_action( 'admin_notices', 'sm_add_php_version_error' ); + $fail = true; + } + + // Check minimum WP requirements, which is 3.3 at the moment. + if ( version_compare( $GLOBALS['wp_version'], '3.3', '<' ) ) { + add_action( 'admin_notices', 'sm_add_wp_version_error' ); + $fail = true; + } + + if ( ! $fail ) { + require_once trailingslashit( dirname( __FILE__ ) ) . 'class-googlesitemapgeneratorloader.php'; + } + +} + +/** + * Adds a notice to the admin interface that the WordPress version is too old for the plugin + * + * @package sitemap + * @since 4.0 + */ +function sm_add_wp_version_error() { + /* translators: %s: search term */ + + echo '

        ' . esc_html( __( 'Your WordPress version is too old for XML Sitemaps.', 'google-sitemap-generator' ) ) . '
        ' . esc_html( sprintf( __( 'Unfortunately this release of Google XML Sitemaps requires at least WordPress %4$s. You are using WordPress %2$s, which is out-dated and insecure. Please upgrade or go to active plugins and deactivate the Google XML Sitemaps plugin to hide this message. You can download an older version of this plugin from the plugin website.', 'google-sitemap-generator' ), 'plugins.php?plugin_status=active', esc_html( $GLOBALS['wp_version'] ), 'http://www.arnebrachhold.de/redir/sitemap-home/', '3.3' ) ) . '

        '; +} + +/** + * Adds a notice to the admin interface that the WordPress version is too old for the plugin + * + * @package sitemap + * @since 4.0 + */ +function sm_add_php_version_error() { + /* translators: %s: search term */ + + echo '

        ' . esc_html( __( 'Your PHP version is too old for XML Sitemaps.', 'google-sitemap-generator' ) ) . '
        ' . esc_html( sprintf( __( 'Unfortunately this release of Google XML Sitemaps requires at least PHP %4$s. You are using PHP %2$s, which is out-dated and insecure. Please ask your web host to update your PHP installation or go to active plugins and deactivate the Google XML Sitemaps plugin to hide this message. You can download an older version of this plugin from the plugin website.', 'google-sitemap-generator' ), 'plugins.php?plugin_status=active', PHP_VERSION, 'http://www.arnebrachhold.de/redir/sitemap-home/', '5.2' ) ) . '

        '; +} + +/** + * Returns the file used to load the sitemap plugin + * + * @package sitemap + * @since 4.0 + * @return string The path and file of the sitemap plugin entry point + */ +function sm_get_init_file() { + return __FILE__; +} + +/** + * Register beta user consent function. + */ +function register_consent() { + if ( ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { + if ( is_user_logged_in() && current_user_can( 'manage_options' ) ) { + if ( isset( $_POST['user_consent_yes'] ) ) { + if (isset($_POST['user_consent_yesno_nonce_token']) && check_admin_referer('user_consent_yesno_nonce', 'user_consent_yesno_nonce_token')){ + update_option( 'sm_user_consent', 'yes' ); + } + } + if ( isset( $_POST['user_consent_no'] ) ) { + if (isset($_POST['user_consent_yesno_nonce_token']) && check_admin_referer('user_consent_yesno_nonce', 'user_consent_yesno_nonce_token')){ + update_option( 'sm_user_consent', 'no' ); + } + } + if ( isset( $_GET['action'] ) ) { + if ( 'no' === $_GET['action'] ) { + if ( $_SERVER['QUERY_STRING'] ) { + if( strpos( $_SERVER['QUERY_STRING'], 'google-sitemap-generator' ) ) { + update_option( 'sm_show_beta_banner', 'false' ); + $count = get_option( 'sm_beta_banner_discarded_count' ); + if ( gettype( $count ) !== 'boolean' ) { + update_option( 'sm_beta_banner_discarded_count', (int) $count + 1 ); + } else { + add_option( 'sm_beta_banner_discarded_on', gmdate( 'Y/m/d' ) ); + update_option( 'sm_beta_banner_discarded_count', (int) 1 ); + } + GoogleSitemapGeneratorLoader::setup_rewrite_hooks(); + GoogleSitemapGeneratorLoader::activate_rewrite(); + } else { + add_option( 'sm_beta_notice_dismissed_from_wp_admin', 'true' ); + } + } else { + add_option( 'sm_beta_notice_dismissed_from_wp_admin', 'true' ); + } + } + } + if ( isset( $_POST['enable_updates'] ) ) { + if (isset($_POST['enable_updates_nonce_token']) && check_admin_referer('enable_updates_nonce', 'enable_updates_nonce_token')){ + if ( 'true' === $_POST['enable_updates'] ) { + $auto_update_plugins = get_option( 'auto_update_plugins' ); + if ( ! is_array( $auto_update_plugins ) ) { + $auto_update_plugins = array(); + } + array_push( $auto_update_plugins, 'google-sitemap-generator/sitemap.php' ); + update_option( 'auto_update_plugins', $auto_update_plugins ); + } elseif ( 'false' === $_POST['enable_updates'] ) { + update_option( 'sm_hide_auto_update_banner', 'yes' ); + } + } + } + + /* + if ( isset( $_POST['disable_plugin'] ) ) { + if (isset($_POST['disable_plugin_sitemap_nonce_token']) && check_admin_referer('disable_plugin_sitemap_nonce', 'disable_plugin_sitemap_nonce_token')){ + if ( strpos( $_POST['disable_plugin'], 'all_in_one' ) !== false ) { + $default_value = 'default'; + $aio_seo_options = get_option( 'aioseo_options', $default_value ); + if ( $aio_seo_options !== $default_value ) { + $aio_seo_options = json_decode( $aio_seo_options ); + $aio_seo_options->sitemap->general->enable = 0; + update_option( 'aioseo_options', json_encode( $aio_seo_options ) ); + } + } elseif( strpos( $_POST['disable_plugin'], 'wp-seo' ) !== false ) { + $yoast_options = get_option( 'wpseo' ); + $yoast_options['enable_xml_sitemap'] = false; + update_option( 'wpseo', $yoast_options ); + } + } + } + */ + } + } + $updateUrlRules = get_option('sm_options'); + if(!isset($updateUrlRules['sm_b_rewrites2']) || $updateUrlRules['sm_b_rewrites2'] == false){ + GoogleSitemapGeneratorLoader::setup_rewrite_hooks(); + GoogleSitemapGeneratorLoader::activate_rewrite(); + GoogleSitemapGeneratorLoader::activation_indexnow_setup(); + + if (isset($updateUrlRules['sm_b_rewrites2'])) { + $updateUrlRules['sm_b_rewrites2'] = true; + update_option('sm_options', $updateUrlRules); + } else { + $updateUrlRules['sm_b_rewrites2'] = true; + add_option('sm_options', $updateUrlRules); + update_option('sm_options', $updateUrlRules); + } + + } + if(isset($updateUrlRules['sm_links_page'] )){ + $sm_links_page = intval($updateUrlRules['sm_links_page']); + if($sm_links_page < 1000) { + $updateUrlRules['sm_links_page'] = 1000; + update_option('sm_options', $updateUrlRules); + } + } + + if(!isset($updateUrlRules['sm_b_activate_indexnow']) || $updateUrlRules['sm_b_activate_indexnow'] == false){ + $updateUrlRules['sm_b_activate_indexnow'] = true; + $updateUrlRules['sm_b_indexnow'] = true; + update_option('sm_options', $updateUrlRules); + } + +} + +function disable_plugins_callback(){ + if (current_user_can('manage_options')) { + check_ajax_referer('disable_plugin_sitemap_nonce', 'nonce'); + + $pluginList = sanitize_text_field($_POST['pluginList']); + $pluginsToDisable = explode(',', $pluginList); + + foreach ($pluginsToDisable as $plugin) { + if ($plugin === 'all-in-one-seo-pack/all_in_one_seo_pack.php') { + /* all in one seo deactivation */ + $aioseo_option_key = 'aioseo_options'; + if ($aioseo_options = get_option($aioseo_option_key)) { + $aioseo_options = json_decode($aioseo_options, true); + $aioseo_options['sitemap']['general']['enable'] = false; + update_option($aioseo_option_key, json_encode($aioseo_options)); + } + } + if ($plugin === 'wordpress-seo/wp-seo.php') { + /* yoast sitemap deactivation */ + if ($yoast_options = get_option('wpseo')) { + $yoast_options['enable_xml_sitemap'] = false; + update_option('wpseo', $yoast_options); + } + } + if ($plugin === 'jetpack/jetpack.php') { + /* jetpack sitemap deactivation */ + $modules_array = get_option('jetpack_active_modules'); + if(is_array($modules_array)) { + if (in_array('sitemaps', $modules_array)) { + $key = array_search('sitemaps', $modules_array); + unset($modules_array[$key]); + update_option('jetpack_active_modules', $modules_array); + } + } + } + if ($plugin === 'wordpress-sitemap') { + /* Wordpress sitemap deactivation */ + $options = get_option('sm_options', array()); + if (isset($options['sm_wp_sitemap_status'])) $options['sm_wp_sitemap_status'] = false; + else $options['sm_wp_sitemap_status'] = false; + update_option('sm_options', $options); + } + } + + echo 'Plugins sitemaps disabled successfully'; + wp_die(); + } +} + +function conflict_plugins_admin_notice(){ + GoogleSitemapGeneratorLoader::create_notice_conflict_plugin(); +} + + /* send to index updated url */ +function indexnow_after_post_save($new_status, $old_status, $post) { + $indexnow = get_option('sm_options'); + $indexNowStatus = isset($indexnow['sm_b_indexnow']) ? $indexnow['sm_b_indexnow'] : false; + if ($indexNowStatus === true) { + $newUrlToIndex = new GoogleSitemapGeneratorIndexNow(); + $is_changed = false; + $type = "add"; + if ($old_status === 'publish' && $new_status === 'publish') { + $is_changed = true; + $type = "update"; + } + else if ($old_status != 'publish' && $new_status === 'publish') { + $is_changed = true; + $type = "add"; + } + else if ($old_status === 'publish' && $new_status === 'trash') { + $is_changed = true; + $type = "delete"; + } + if ($is_changed) $newUrlToIndex->start(get_permalink($post)); + } +} + +// Don't do anything if this file was called directly. +if ( defined( 'ABSPATH' ) && defined( 'WPINC' ) && ! class_exists( 'GoogleSitemapGeneratorLoader', false ) ) { + sm_setup(); + + if(isset(get_option('sm_options')['sm_wp_sitemap_status']) ) $wp_sitemap_status = get_option('sm_options')['sm_wp_sitemap_status']; + else $wp_sitemap_status = true; + if($wp_sitemap_status = true) $wp_sitemap_status = '__return_true'; + else $wp_sitemap_status = '__return_false'; + add_filter( 'wp_sitemaps_enabled', $wp_sitemap_status ); + + add_action('wp_ajax_disable_plugins', 'disable_plugins_callback'); + + add_action('admin_notices', 'conflict_plugins_admin_notice'); + +} diff --git a/html/wp-content/plugins/google-sitemap-generator/sitemap.xsl b/html/wp-content/plugins/google-sitemap-generator/sitemap.xsl new file mode 100644 index 0000000..a75448f --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/sitemap.xsl @@ -0,0 +1,166 @@ + + + + + + + XML Sitemap + + + + + + + + + + + + +

        XML Sitemap

        +
        +

        + This XML sitemap is used by search engines which follow the XML sitemap standard. +

        +

        + This file was dynamically generated using the WordPress content management system and XML Sitemap Generator for Google by Auctollo. +

        +

        + +

        +
        +
        + + + + + + + + + + + + + high + + + + + + + +
        URLPriorityChange frequencyLast modified (GMT)
        + + + + + + + + + + + + +
        +
        +
        + + + +

        XML Sitemap Index

        +
        +

        + This XML sitemap is used by search engines which follow the XML sitemap standard. This file contains links to sub-sitemaps, follow them to see the actual sitemap content. +

        +

        + This file was dynamically generated using the WordPress content management system and XML Sitemap Generator for Google by Auctollo. +

        +
        +
        + + + + + + + + + high + + + + + +
        URL of sub-sitemapLast modified (GMT)
        + + + + + + + + +
        +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/google-sitemap-generator/upgrade-plugin.php b/html/wp-content/plugins/google-sitemap-generator/upgrade-plugin.php new file mode 100644 index 0000000..596a3f2 --- /dev/null +++ b/html/wp-content/plugins/google-sitemap-generator/upgrade-plugin.php @@ -0,0 +1,85 @@ + 4 ) { + include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); //for plugins_api.. +} +include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); +include_once( ABSPATH . 'wp-admin/includes/file.php' ); +include_once( ABSPATH . 'wp-admin/includes/misc.php' ); +include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ); +include_once( ABSPATH . 'wp-content/plugins/google-sitemap-generator/upgrade-plugin.php' ); +include_once( ABSPATH . 'wp-includes/pluggable.php' ); +include_once( ABSPATH . 'wp-content/plugins/google-sitemap-generator/class-googlesitemapgeneratorloader.php' ); + + if ( isset( $_GET['action'] ) ) { + if ( 'yes' === sanitize_text_field( wp_unslash( $_GET['action'] ) ) ) { + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( 'Forbidden', '', array( 'response' => 403 ) ); + } + + if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'user_consent_yesno_nonce' ) ) { + wp_die( 'Forbidden', '', array( 'response' => 403 ) ); + } + } + + update_option( 'sm_user_consent', 'yes' ); + $plugin_version = GoogleSitemapGeneratorLoader::get_version(); + global $wp_version; + $user = wp_get_current_user(); + $user_id = $user->ID; + $mydomain = $user->user_url ? $user->user_url : home_url(); + $user_name = $user->user_nicename; + $useremail = $user->user_email; + global $wpdb; + $result = $wpdb->get_results( $wpdb->prepare( "SELECT user_id, meta_value FROM {$wpdb->usermeta} WHERE meta_key = %s AND user_id = %d", 'session_tokens', (int) $user_id ) ); + $user_login_details = array(); + $last_login = ''; + if ( ! empty( $result ) && isset( $result[0]->meta_value ) ) { + $user_login_details = maybe_unserialize( $result[0]->meta_value ); + } + if ( is_array( $user_login_details ) ) { + foreach ( $user_login_details as $item ) { + if ( isset( $item['login'] ) ) { + $last_login = $item['login']; + } + } + $data = array( + 'domain' => $mydomain, + 'userID' => $user_id, + 'userEmail' => $useremail, + 'userName' => $user_name, + 'lastLogin' => $last_login, + 'wp_version' => $wp_version, + 'plugin_version' => $plugin_version, + 'phpVersion' => PHP_VERSION, + ); + $args = array( + 'headers' => array( + 'Content-type : application/json', + ), + 'method' => 'POST', + 'body' => wp_json_encode( $data ), + ); + $response = wp_remote_post( SM_BETA_USER_INFO_URL, $args ); + $body = json_decode( $response['body'] ); + if ( 200 === $body->status ) { + add_option( 'sm_show_beta_banner', 'false' ); + add_option( 'sm_beta_opt_in', true ); + update_option( 'sm_beta_banner_discarded_count', (int) 2 ); + GoogleSitemapGeneratorLoader::setup_rewrite_hooks(); + GoogleSitemapGeneratorLoader::activate_rewrite(); + GoogleSitemapGeneratorLoader::activation_indexnow_setup(); //activtion indexNow + echo ""; + } + } +} diff --git a/html/wp-content/plugins/honeypot/includes/css/wpa.css b/html/wp-content/plugins/honeypot/includes/css/wpa.css new file mode 100644 index 0000000..418a7d2 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/css/wpa.css @@ -0,0 +1,4 @@ +.wpa-test-msg{background: #d1ecf1 !important; border: 1px solid #bee5eb !important; border-radius: 5px !important;color: #0c5460 !important; font-size: 14px !important; padding:.75rem 1.25rem !important; font-family: Arial !important; margin-top:5px !important;} +span.wpa-button{ display: inline-block !important; padding-top: 5px !important; color: #fff !important;background-color: #6c757d !important;border-color: #6c757d !important; padding: 5px 10px !important; border-radius: 5px !important; margin-top:5px !important; cursor: pointer !important; } + +#altEmail_container, .altEmail_container{position:absolute !important; overflow: hidden !important; display: inline !important; height:1px !important; width: 1px !important;z-index:-1000 !important;} \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/img/dashboard_stats.png b/html/wp-content/plugins/honeypot/includes/img/dashboard_stats.png new file mode 100644 index 0000000..474f7c3 Binary files /dev/null and b/html/wp-content/plugins/honeypot/includes/img/dashboard_stats.png differ diff --git a/html/wp-content/plugins/honeypot/includes/img/route_pricing.jpg b/html/wp-content/plugins/honeypot/includes/img/route_pricing.jpg new file mode 100644 index 0000000..ed012b5 Binary files /dev/null and b/html/wp-content/plugins/honeypot/includes/img/route_pricing.jpg differ diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_bbpress.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_bbpress.php new file mode 100644 index 0000000..10466bd --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_bbpress.php @@ -0,0 +1,16 @@ +get_invalid_fields() ) ) { // only check spam if validation OK (Imp for Level 2) + if (wpa_check_is_spam($_POST)){ + do_action('wpa_handle_spammers','contactform7', $_POST); + $result->invalidate('', $GLOBALS['wpa_error_message']); + } + } + return $result; + } + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_diviengineform.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_diviengineform.php new file mode 100644 index 0000000..e517c02 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_diviengineform.php @@ -0,0 +1,30 @@ + $value){ + if(strpos($param, 'divi-form-submit') === 0){ + $is_divi_engine_form = 'true'; + $divi_engine_form_additional = esc_attr(str_replace('divi-form-submit', '', $param)); + } + } + do_action('wpa_handle_spammers','divi_engine_form', $_POST); + if (str_ends_with($_SERVER["REQUEST_URI"],"admin-ajax.php")){ + // ajax post + $result = array( 'result' => 'failed', 'redirect' => '', 'message' => '' . esc_html($GLOBALS['wpa_error_message']) . '', 'message_position' => 'after_button'); + wp_send_json( $result ); + } + else + { + echo "

        ".$GLOBALS['wpa_error_message']."

        "; + } + + die(); + } + } + add_action( 'df_before_process', 'my_df_before_process', 10, 3 ); + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_diviform.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_diviform.php new file mode 100644 index 0000000..b7f1728 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_diviform.php @@ -0,0 +1,31 @@ + $value){ + if(strpos($param, 'et_pb_contactform_submit') === 0){ + $is_divi_form = 'true'; + $divi_form_additional = esc_attr(str_replace('et_pb_contactform_submit', '', $param)); + } + } + + if(!empty($is_divi_form) && $is_divi_form == 'true'){ + if (wpa_check_is_spam($_POST)){ + do_action('wpa_handle_spammers','divi_form', $_POST); + echo "

        ".esc_html($GLOBALS['wpa_error_message'])."

        "; + die(); + } else { // REMOVE OUR TEST FIELD BEFORE SENDING TO DIVI + $fields_data_json = str_replace( '\\', '',$_POST['et_pb_contact_email_fields'.$divi_form_additional]); + $fields_data_array = json_decode( $fields_data_json, true ); + if (is_array($fields_data_array)) { + $filteredArray = array_filter($fields_data_array, function ($item) { + return $item['field_id'] !== 'alt_s' + && $item['field_id'] !== $GLOBALS['wpa_field_name']; + }); + $_POST['et_pb_contact_email_fields'.$divi_form_additional] = json_encode( $filteredArray, JSON_UNESCAPED_UNICODE ); + } + } + } + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_elementor.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_elementor.php new file mode 100644 index 0000000..25f9e38 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_elementor.php @@ -0,0 +1,16 @@ +get( 'fields' ); + $firstField = array_key_first($all_fields); + do_action('wpa_handle_spammers','elementor', $_POST); + $ajax_handler->add_error($all_fields[$firstField]['id'], $GLOBALS['wpa_error_message']); + } + }; + add_action( 'elementor_pro/forms/validation', 'wpa_elementor_extra_validation', 10, 2 ); + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_fluentform.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_fluentform.php new file mode 100644 index 0000000..d8ce60c --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_fluentform.php @@ -0,0 +1,17 @@ + $GLOBALS['wpa_error_message']]); + wp_die(); + } + }; + //add_action( 'fluentform_before_insert_submission', 'wpa_fluent_form_extra_validation', 10, 3 ); + add_action( 'fluentform/before_insert_submission', 'wpa_fluent_form_extra_validation', 10, 3 ); + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_formidable.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_formidable.php new file mode 100644 index 0000000..ffe24c9 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_formidable.php @@ -0,0 +1,16 @@ +failed_validation = true; + $form['fields'][0]->validation_message = $GLOBALS['wpa_error_message']; + $validation_result['form'] = $form; + } + return $validation_result; + } +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_toolsetform.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_toolsetform.php new file mode 100644 index 0000000..5e222aa --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_toolsetform.php @@ -0,0 +1,18 @@ +process->errors[ $form_data['id'] ][ '0' ] = $GLOBALS['wpa_error_message']; + } + } + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_wplogin.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_wplogin.php new file mode 100644 index 0000000..cfd4806 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_wplogin.php @@ -0,0 +1,41 @@ +'; + } + + add_action('lostpassword_form', 'wpa_wplogin_add_initiator_field'); + add_action('woocommerce_lostpassword_form', 'wpa_wplogin_add_initiator_field'); + + add_action( 'login_form', 'wpa_wplogin_add_initiator_field' ); + add_action( 'woocommerce_login_form', 'wpa_wplogin_add_initiator_field' ); // FIX FOR WOOCOMMERCE LOGIN. + + + function wpae_wplogin_extra_validation( $user, $username, $password ) { + if ( ! empty( $_POST ) ) { + if (wpa_check_is_spam($_POST)){ + $postData = $_POST; + $postData['pwd'] = '**removed**'; + do_action('wpa_handle_spammers','wplogin', $postData); + return new WP_Error( 'error', $GLOBALS['wpa_error_message']); + } + } + //return $user; + } + add_filter( 'authenticate', 'wpae_wplogin_extra_validation', 10, 3 ); + + + function wpae_lostpassword_extra_validation( $errors ) { + if ( is_admin() ) { return; } + + if (wpa_check_is_spam($_POST)){ + do_action('wpa_handle_spammers','losspassword', $_POST); + $errors->add( 'user_login', __($GLOBALS['wpa_error_message']) ); + } + } + add_action( 'lostpassword_post', 'wpae_lostpassword_extra_validation' ); + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/integration/wpa_wpregistration.php b/html/wp-content/plugins/honeypot/includes/integration/wpa_wpregistration.php new file mode 100644 index 0000000..4e46c2f --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/integration/wpa_wpregistration.php @@ -0,0 +1,25 @@ +'; + } + + add_filter( 'registration_errors', 'wpa_wpregistration_extra_validation', 10, 3 ); + + function wpa_wpregistration_extra_validation( $errors, $sanitized_user_login, $user_email ) { + + if (wpa_check_is_spam($_POST)){ + do_action('wpa_handle_spammers','wpregistration', $_POST); + + if ( !is_object( $errors ) ) { $errors = new WP_Error(); } + + $errors->add( 'wpa_extra_email', __($GLOBALS['wpa_error_message']) ); + } + return $errors; + } + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/js/wpa.js b/html/wp-content/plugins/honeypot/includes/js/wpa.js new file mode 100644 index 0000000..36e70e5 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/js/wpa.js @@ -0,0 +1,128 @@ +var wpa_field_name, wpa_unique_id, wpa_add_test, wpa_hidden_field; + +jQuery(document).ready(function(){ + wpa_field_name = wpa_field_info.wpa_field_name; + wpa_unique_id = wpa_field_info.wpa_field_value; + wpa_add_test = wpa_field_info.wpa_add_test; + + wpa_hidden_field = "
        "; + + wpa_add_honeypot_field(); + + if (typeof wpae_add_honeypot_field == 'function') { // IF EXTENDED version exists. + wpae_add_honeypot_field(); + } + + if (wpa_add_test == 'yes'){ + wpa_add_test_block(); + } +}); + +function wpa_act_as_spam(){ + actiontype = jQuery('span.wpa-button').data('actiontype'); + if (actiontype == 'remove'){ + wpa_remove_honeypot_field(); + jQuery('span.wpa-button').data('actiontype','add'); + jQuery('span.wpa-button').html('Acting as Spam Bot'); + } else { + wpa_add_honeypot_field(); + jQuery('span.wpa-button').data('actiontype','remove'); + jQuery('span.wpa-button').html('Act as Spam Bot'); + } +} + +function wpa_add_honeypot_field(){ + + // Combined form selectors + var allFormSelectors = [ + // Main forms + 'form.wpcf7-form, .wpcf7 form', // CONTACT FORM 7 + 'form.wpforms-form', // WPForms + '.gform_wrapper form', // Gravity Forms + '.frm_forms form', // Formidable Forms + '.caldera-grid form', // Caldera Forms + '.wp-block-toolset-cred-form form', // Toolset Forms + 'form.cred-user-form', // Toolset Forms + 'form.cred-form', // Toolset Forms + 'form.et_pb_contact_form', // Divi Form + 'form.fb_form', // Divi Form Builder - Divi Engine + 'form.elementor-form', // Elementor + 'form.form-contribution', // WooCommerce Reviews Pro + 'form.cart', // WooCommerce Cart + 'form#learn-press-checkout-form', // LearnPress Checkout Form + + 'form.wpa_form', // Generic Class + '.wpa_form form', // Generic Class + + '.um-form form', // Ulimate Membership Form + + // Login forms + 'form.spectra-pro-login-form', // SPECTRA LOGIN FORM + 'form#loginform', // Default Login Form + 'form#edd_login_form', // EDD LOGIN FORM + 'form.uwp-login-form', // USER WP LOGIN FORM + '.et_pb_login_form form', // For Elementor login form + 'form.eael-login-form', // essential-addons login form + 'form.user-registration-form-login', // User Registration & Membership for WordPress + + 'form#lostpasswordform', // Lost Password Form + 'form.lost_reset_password', // Tutor Password Form + 'form.ur_lost_reset_password', // User Registration & Membership for WordPress + + + //Registration Forms + 'form.register', // User Registration & Membership for WordPress + + // Comment forms + 'form#commentform', // WP Comment with ID + 'form.ast-commentform', // Astra Comment Form with class + 'form#fl-comment-form', // Beaver Builder Theme Form with ID + 'form.comment-form', // WP Comment with class + '.review-form form', // LearnPress Review + 'form#edd-reviews-form', // EDD Reviews with ID + 'form.wpr-comment-form', + + // BBPress forms + '.bbp-topic-form form', // BBPress Topic Form + '.bbp-reply-form form' // BBPress Reply Form + ]; + + // Append hidden field to all forms in the combined selector list + jQuery(allFormSelectors.join(', ')).append(wpa_hidden_field); + + // FOR FLUENT FORMS + jQuery('form.frm-fluent-form').append(wpa_hidden_field); // FOR Fluent Forms + jQuery('.ff_conv_app').append(wpa_hidden_field); // FOR Fluent Convertional Forms + + if (typeof fluent_forms_global_var_1 !== 'undefined') { // QUICK HACK FOR FLUENT FORMS CONVERSIONAL + fluent_forms_global_var_1.extra_inputs[wpa_field_name] = wpa_unique_id; + fluent_forms_global_var_1.extra_inputs['alt_s'] = ''; + } + // EOF FLUENT FORMS + + jQuery('input.wpa_initiator').each(function() { + var $form = jQuery(this).closest('form'); // Get the parent form of input.wpa_initiator + + // Check if wpa_hidden_field exists in the form, if not, insert it after input.wpa_initiator + if ($form.find('.wpa_hidden_field').length === 0) { + jQuery(wpa_hidden_field).insertAfter(this); + } + }); + +} + +function wpa_add_test_block(){ + checkingTest = '
        WP Armour ( Only visible to site administrators. Not visible to other users. )
        This form has a honeypot trap enabled. If you want to act as spam bot for testing purposes, please click the button below.
        Act as Spam Bot
        '; + jQuery('.wpa-test-msg').remove(); // Clear First + jQuery('span.wpa_hidden_field').after(checkingTest); +} + +function wpa_remove_honeypot_field(){ + jQuery('.wpa_hidden_field').remove(); + jQuery('#altEmail_container, .altEmail_container').remove(); + + if (typeof fluent_forms_global_var_1 !== 'undefined') { + delete fluent_forms_global_var_1.extra_inputs[wpa_field_name]; + delete fluent_forms_global_var_1.extra_inputs['alt_s']; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/js/wpa_vanilla.js b/html/wp-content/plugins/honeypot/includes/js/wpa_vanilla.js new file mode 100644 index 0000000..556abea --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/js/wpa_vanilla.js @@ -0,0 +1,131 @@ +var wpa_field_name, wpa_unique_id, wpa_add_test, wpa_hidden_field; + +document.addEventListener('DOMContentLoaded', function() { + wpa_field_name = wpa_field_info.wpa_field_name; + wpa_unique_id = wpa_field_info.wpa_field_value; + wpa_add_test = wpa_field_info.wpa_add_test; + + wpa_hidden_field = "
        "; + + wpa_add_honeypot_field(); + + if (typeof wpae_add_honeypot_field === 'function') { // IF EXTENDED version exists. + wpae_add_honeypot_field(); + } + + if (wpa_add_test === 'yes') { + wpa_add_test_block(); + } +}); + +function wpa_act_as_spam() { + const wpaButton = document.querySelector('span.wpa-button'); + const actiontype = wpaButton.dataset.actiontype; + + if (actiontype === 'remove') { + wpa_remove_honeypot_field(); + wpaButton.dataset.actiontype = 'add'; + wpaButton.textContent = 'Acting as Spam Bot'; + } else { + wpa_add_honeypot_field(); + wpaButton.dataset.actiontype = 'remove'; + wpaButton.textContent = 'Act as Spam Bot'; + } +} + +function wpa_add_honeypot_field() { + // Combined form selectors + const allFormSelectors = [ + // Main forms + 'form.wpcf7-form, .wpcf7 form', // CONTACT FORM 7 + 'form.wpforms-form', // WPForms + '.gform_wrapper form', // Gravity Forms + '.frm_forms form', // Formidable Forms + '.caldera-grid form', // Caldera Forms + '.wp-block-toolset-cred-form form', // Toolset Forms + 'form.cred-user-form', // Toolset Forms + 'form.cred-form', // Toolset Forms + 'form.et_pb_contact_form', // Divi Form + 'form.fb_form', // Divi Form Builder - Divi Engine + 'form.elementor-form', // Elementor + 'form.form-contribution', // WooCommerce Reviews Pro + 'form.cart', // WooCommerce Cart + 'form#learn-press-checkout-form', // LearnPress Checkout Form + + 'form.wpa_form', // Generic Class + '.wpa_form form', // Generic Class + + '.um-form form', // Ulimate Membership Form + + // Login forms + 'form.spectra-pro-login-form', // SPECTRA LOGIN FORM + 'form#loginform', // Default Login Form + 'form#edd_login_form', // EDD LOGIN FORM + 'form.uwp-login-form', // USER WP LOGIN FORM + '.et_pb_login_form form', // For Elementor login form + 'form.eael-login-form', // essential-addons login form + 'form.user-registration-form-login', // User Registration & Membership for WordPress + + 'form#lostpasswordform', // Lost Password Form + 'form.lost_reset_password', // Tutor Password Form + 'form.ur_lost_reset_password', // User Registration & Membership for WordPress + + //Registration Forms + 'form.register', // User Registration & Membership for WordPress + + // Comment forms + 'form#commentform', // WP Comment with ID + 'form.ast-commentform', // Astra Comment Form with class + 'form#fl-comment-form', // Beaver Builder Theme Form with ID + 'form.comment-form', // WP Comment with class + '.review-form form', // LearnPress Review + 'form#edd-reviews-form', // EDD Reviews with ID + 'form.wpr-comment-form', + + // BBPress forms + '.bbp-topic-form form', // BBPress Topic Form + '.bbp-reply-form form' // BBPress Reply Form + ]; + + const forms = document.querySelectorAll(allFormSelectors.join(', ')); + forms.forEach(form => { + form.insertAdjacentHTML('beforeend', wpa_hidden_field); + }); + + // FOR FLUENT FORMS + const fluentForms = document.querySelectorAll('form.frm-fluent-form, .ff_conv_app'); + fluentForms.forEach(form => { + form.insertAdjacentHTML('beforeend', wpa_hidden_field); + }); + + if (typeof fluent_forms_global_var_1 !== 'undefined') { // QUICK HACK FOR FLUENT FORMS CONVERSIONAL + fluent_forms_global_var_1.extra_inputs[wpa_field_name] = wpa_unique_id; + fluent_forms_global_var_1.extra_inputs['alt_s'] = ''; + } + // EOF FLUENT FORMS + + const wpaInitiators = document.querySelectorAll('input.wpa_initiator'); + wpaInitiators.forEach(initiator => { + const form = initiator.closest('form'); + if (form && !form.querySelector('.wpa_hidden_field')) { + initiator.insertAdjacentHTML('afterend', wpa_hidden_field); + } + }); +} + +function wpa_add_test_block() { + const checkingTest = '
        WP Armour ( Only visible to site administrators. Not visible to other users. )
        This form has a honeypot trap enabled. If you want to act as spam bot for testing purposes, please click the button below.
        Act as Spam Bot
        '; + document.querySelectorAll('.wpa-test-msg').forEach(el => el.remove()); + document.querySelectorAll('span.wpa_hidden_field').forEach(span => { + span.insertAdjacentHTML('afterend', checkingTest); + }); +} + +function wpa_remove_honeypot_field() { + document.querySelectorAll('.wpa_hidden_field, #altEmail_container, .altEmail_container').forEach(el => el.remove()); + + if (typeof fluent_forms_global_var_1 !== 'undefined') { + delete fluent_forms_global_var_1.extra_inputs[wpa_field_name]; + delete fluent_forms_global_var_1.extra_inputs['alt_s']; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/views/wpa_extended_version.php b/html/wp-content/plugins/honeypot/includes/views/wpa_extended_version.php new file mode 100644 index 0000000..a700360 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/views/wpa_extended_version.php @@ -0,0 +1,47 @@ + + +
        +

        Extra Tools that WP Armour Extended offers to make WP Armour more powerfull.

        +
          +
        • + * WooCommerce & Easy Digital Downloads
          + * QuForm, MC4WP, HTMLform plugin
          + * BuddyPress, BuddyBoss
          + * NinjaForms, S2 Member, Avia Enfold Theme
          + * Gravity Forms (For Ajax enabled and multi page form) and more.. +
        • + + + +
        • + Record spammers' IPs to block them from future submissions. +
        • + +
        • + See what data spam bot was trying to submit. +
        • + +
        • + Allows you to block the spam bot IP so that they can't visit your website. +
        • + +
        • + Get WP Armour Extended and make WP Armour more powerful. +
          + GET IT NOW +
        • + +
        • + In the long run, spam bots learn how to bypass antispam systems. Staying on top of new methodologies is key. You can motivate us to continue development of the plugin by getting a license for the WP Armour Extended. +
        • + + +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/views/wpa_main.php b/html/wp-content/plugins/honeypot/includes/views/wpa_main.php new file mode 100644 index 0000000..eb113ab --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/views/wpa_main.php @@ -0,0 +1,52 @@ + + + +

        + + +
        + +

        WP Armour - HoneyPot Anti Spam

        + + + +
        + + + + + + +
        + +  
        +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/views/wpa_notice.php b/html/wp-content/plugins/honeypot/includes/views/wpa_notice.php new file mode 100644 index 0000000..e3d36dc --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/views/wpa_notice.php @@ -0,0 +1,103 @@ + +

        IMPORTANT : Your are using older version of WP Armour Extended. Please update to 1.17 or above for it to work properly.

        +
        '; + } + } + + if (current_user_can( 'manage_options' )): // ONLY SHOW IF ADMIN + + // FOR REVIEWS + if (get_option('wpa_reviews_notice_hide') != 'yes'){ + $installedDate = strtotime(get_option('wpa_installed_date')); + $todayDate = time(); + $installedDays = round(($todayDate - $installedDate) / (60 * 60 * 24)); + $wpa_stats = json_decode(get_option('wpa_stats'),true); + $all_spam_blocked = $wpa_stats ? $wpa_stats['total']['all_time'] : 0; + + + if ($installedDays > 30 && $all_spam_blocked > 30){ + echo '
        + Hey, WP Armour has blocked '.$all_spam_blocked.' spam submissions till date - that’s awesome! Could you please do us a BIG favor and give it a 5-star rating on WordPress ? Just to help us spread the word and boost our motivation.

        + + + +
        '; + } + } + + // FOR PATERON + if (!is_plugin_active('wp-armour-extended/wp-armour-extended.php')){ + if (get_option('wpa_pateron_notice_hide') != 'yes'){ + $installedDate = strtotime(get_option('wpa_installed_date')); + $todayDate = time(); + $installedDays = round(($todayDate - $installedDate) / (60 * 60 * 24)); + $wpa_stats = json_decode(get_option('wpa_stats'),true); + $all_spam_blocked = $wpa_stats ? $wpa_stats['total']['all_time'] : 0; + + + if ($installedDays > 100 && $all_spam_blocked > 300 ){ + echo '
        + Your support is vital for us to keep fighting spam. By supporting us on Patreon with as little as USD 1, you will help us continue developing of WP Armour Anti Spam Plugin. + + +
        '; + } + } + } + + // UPSELLING EXTENDED VERSION + if (get_option('wpa_extended_notice_hide') != 'yes' && !is_plugin_active('wp-armour-extended/wp-armour-extended.php') ){ + $installedDate = strtotime(get_option('wpa_installed_date')); + $todayDate = time(); + $installedDays = round(($todayDate - $installedDate) / (60 * 60 * 24)); + $wpa_stats = json_decode(get_option('wpa_stats'),true); + $all_spam_blocked = $wpa_stats ? $wpa_stats['total']['all_time'] : 0; + + + if ($installedDays > 90 && $all_spam_blocked > 1000){ + echo '
        + Hey, WP Armour has blocked '.$all_spam_blocked.' spam submissions till date - that’s awesome!

        + + Can you help us by purchasing our Extended Version ? This will helps up maintain and support the plugin in upcoming days and make it even better. Our Extended version starts from 19.99 USD and comes with yearly license, No API calls & Fully GDPR Complaint.

        + + It has additional support including WooCommerce ( Blocks card testing orders), Ajax and Multi page Gravity Forms, Easy Digital Downloads, QuForm, MC4WP: Mailchimp for WordPress and have Spammer blocking based on IP, Record Spam Submission and many more. + + +
        '; + } + } + + endif; // CAN MANAGE OPTION +} \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/views/wpa_settings.php b/html/wp-content/plugins/honeypot/includes/views/wpa_settings.php new file mode 100644 index 0000000..f6cc1cd --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/views/wpa_settings.php @@ -0,0 +1,87 @@ + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        General Settings
        This plugin should work with default settings, however if you begin to get spam, update the field name below.
        Honey Pot Field Name + + + + +
        + Changing the field name regularly is a good idea. Please click on icon above to generate new field name. +
        Honey Pot Error Message +
        Mesage for bots. No average human users will see though. +
        Disable Honeypot Test Widget + + Only visible when Admin user is logged in. +
        Disable jQuery? + + âš ï¸ This is a new feature. Please test carefully before using on a live site. +
        + + +
        +

        Only Administrators can make changes to these settings.

        +

        + + \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/views/wpa_sidebar.php b/html/wp-content/plugins/honeypot/includes/views/wpa_sidebar.php new file mode 100644 index 0000000..68835b4 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/views/wpa_sidebar.php @@ -0,0 +1,53 @@ + + +
        + + + +

        + + + + + + + + + + + + + +
        Quick Link
        + +
        +
        + + + + + + + + + + + + +
        Plugins You May Like
        + +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/views/wpa_stats.php b/html/wp-content/plugins/honeypot/includes/views/wpa_stats.php new file mode 100644 index 0000000..1dda63d --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/views/wpa_stats.php @@ -0,0 +1,67 @@ + 'ok','body'=>'Stats Reset' ); + } + break; + } +} +$currentStats = json_decode(get_option('wpa_stats'), true); +?> + + +

        + + +
        + + + + + + + + + + + + */ ?> + + + + + + + + + + + $statData): ?> + + + + + + + + + + + + +
        Quick Stats
        SourceTodayThis WeekThis MonthAll Time
        No Record Found

        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/includes/views/wpa_stats_widget.php b/html/wp-content/plugins/honeypot/includes/views/wpa_stats_widget.php new file mode 100644 index 0000000..13f70d4 --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/views/wpa_stats_widget.php @@ -0,0 +1,28 @@ + + + + +
        + +
        +
        + View all spam statistics from dashboard +
        +
        +

        Enable stats widgets with WP Armour Extended.

        +

        Also, it can auto block spammer's IP and record what spammer are trying to submit.

        +
        + + +
        +
        + diff --git a/html/wp-content/plugins/honeypot/includes/wpa_config.php b/html/wp-content/plugins/honeypot/includes/wpa_config.php new file mode 100644 index 0000000..82cdaee --- /dev/null +++ b/html/wp-content/plugins/honeypot/includes/wpa_config.php @@ -0,0 +1,6 @@ + array('name'=>'Settings','path'=>'wpa_settings.php'), + 'stats' => array('name'=>'Statistics','path'=>'wpa_stats.php'), + 'extended_version' => array('name'=>"What's in WP Armour Extended ?",'path'=>'wpa_extended_version.php') + ); + + $wpa_tabs = apply_filters( 'wpa_tabs_filter', $wpa_tabs); + + include 'views/wpa_main.php'; +} + +function wpa_save_settings(){ + if ( isset($_POST['wpa_nonce']) && wp_verify_nonce($_POST['wpa_nonce'], 'wpa_save_settings')) { + if (empty($_POST['wpa_field_name'])){ + $return['status'] = 'error'; + $return['body'] = "Honey Pot Field Name can't be empty"; + } else { + update_option('wpa_field_name',sanitize_title_with_dashes($_POST['wpa_field_name'])); + update_option('wpa_error_message',sanitize_text_field(stripslashes($_POST['wpa_error_message']))); + update_option('wpa_disable_test_widget',sanitize_text_field($_POST['wpa_disable_test_widget'])); + update_option('wpa_disable_jquery', sanitize_text_field($_POST['wpa_disable_jquery'])); + + $GLOBALS['wpa_field_name'] = get_option('wpa_field_name'); + $GLOBALS['wpa_error_message'] = get_option('wpa_error_message'); + + $return['status'] = 'ok'; + $return['body'] = 'Settings Saved'; + } + } else { + $return['status'] = 'error'; + $return['body'] = 'Sorry, your nonce did not verify. Please try again.'; + } + return $return; +} + +function wpa_save_stats($wp_system, $data){ + $currentStats = json_decode(get_option('wpa_stats'), true) ?? array(); + $timeArray = array('today','week','month'); + + if (!array_key_exists($wp_system,$currentStats)){ + $currentStats[$wp_system]['today']['count'] = 0; + $currentStats[$wp_system]['week']['count'] = 0; + $currentStats[$wp_system]['month']['count'] = 0; + $currentStats[$wp_system]['today']['date'] = date('Ymd'); + $currentStats[$wp_system]['week']['date'] = date('Ymd'); + $currentStats[$wp_system]['month']['date'] = date('Ymd'); + } + + foreach ($timeArray as $key => $time) { + if (wpa_check_date($currentStats['total'][$time]['date'],$time)){ + $currentStats['total'][$time]['count'] += 1; + } else { + $currentStats['total'][$time]['count'] = 1; + } + + if (wpa_check_date($currentStats[$wp_system][$time]['date'],$time)){ + $currentStats[$wp_system][$time]['count'] += 1; + } else { + $currentStats[$wp_system][$time]['count'] = 1; + } + + $currentStats['total'][$time]['date'] = date('Ymd'); + $currentStats[$wp_system][$time]['date'] = date('Ymd'); + } + + $currentStats['total']['all_time'] += 1; + @$currentStats[$wp_system]['all_time'] += 1; + update_option('wpa_stats', json_encode($currentStats)); +} + +function wpa_check_date($timestamp, $comparision){ + switch ($comparision) { + case 'today': + if (date('Ymd') == $timestamp){ + return true; + } else { + return false; + } + break; + + case 'week': + $firstWeekDay = date("Ymd", strtotime('monday this week')); + $lastWeekDay = date("Ymd", strtotime('sunday this week')); + + if($timestamp >= $firstWeekDay && $timestamp <= $lastWeekDay) { + return true; + } else { + return false; + } + break; + + case 'month': + if(date('Ym',strtotime($timestamp)) == date('Ym')) { + return true; + } else { + return false; + } + break; + } +} + +function wpa_unqiue_field_name(){ + $permitted_chars = 'abcdefghijklmnopqrstuvwxyz'; + return substr(str_shuffle($permitted_chars), 0, 6).rand(1,9999); +} + +function wpa_unqiue_field_value(){ + /* DEPRECATED LEVEL 2 + if (function_exists('wpae_unqiue_field_value')){ // IF EXTENDED VERSION AVAILABLE + return wpae_unqiue_field_value(); + } else { + return rand(1111, 999999); + }*/ + return rand(1111, 999999); +} + +function wpa_check_is_spam($form_data){ + if ( + (isset($form_data[$GLOBALS['wpa_field_name']])) && + (isset($form_data['alt_s'])) && + (empty($form_data['alt_s'])) + + ){ + /* DEPRECATED LEVEL 2 + if (function_exists('wpae_2level_spam_check')){ + return wpae_2level_spam_check($form_data[$GLOBALS['wpa_field_name']]); + } else { + return false; // FALSE MEANS NOT SPAM + }*/ + return false; // FALSE MEANS NOT SPAM + } else { + return true; // TRUE MEANS SPAM + } +} + +function wpa_field_info(){ + if (current_user_can('activate_plugins') && (get_option('wpa_disable_test_widget') != 'yes')){ + $wpa_add_test = 'yes'; + } else { + $wpa_add_test = 'no'; + } + + $return = array( + 'wpa_field_name' => $GLOBALS['wpa_field_name'], + 'wpa_field_value' => wpa_unqiue_field_value(), + 'wpa_add_test' => $wpa_add_test + ); + + return $return; +} \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/readme.txt b/html/wp-content/plugins/honeypot/readme.txt new file mode 100644 index 0000000..831cee9 --- /dev/null +++ b/html/wp-content/plugins/honeypot/readme.txt @@ -0,0 +1,442 @@ +=== WP Armour - Honeypot Anti Spam === +Contributors: dnesscarkey +Donate link: https://www.patreon.com/wp_armour +Tags: anti spam, spam protection, comment spam , contact form spam, akismet +Requires at least: 5.0 +Tested up to: 6.8.3 +Stable tag: 2.3.04 +License: GPLv2 or later +License URI: https://www.gnu.org/licenses/gpl-2.0.html + +Fastest growing Anti Spam plugin. No API calls, subscriptions, captcha or puzzle. Full GDPR complaint. For comments, contact form, login, registration + +== Description == +This plugins block spam submissions using honeypot anti spam technic. No Captcha or extra verification field hassle to the users. Only lets spam bots to suffer using our anti spam filter. + +Automatic anti spam protection for following forms (Available in Free Version) . No setup required. + +* WP Comments +* WP Registraton +* BBPress Forum (bbpress.org) +* Contact Form 7 (wordpress.org/plugins/contact-form-7) +* Gravity Forms (For Non Ajax and Single Page/Step Form - gravityforms.com) +* WPForms (wpforms.com) +* Formidable Forms (formidableforms.com) +* Caldera Forms (calderaforms.com) +* Toolset Forms (toolset.com) +* Elementor Forms (elementor.com) +* Fluent Forms (fluentforms.com) +* Divi Theme Contact Form (elegantthemes.com) +* Theme My Login ( https://wordpress.org/plugins/theme-my-login/ ) +* WooCommerce Reviews Pro +* GDPR compliant. No tracking, cookie storage or external server calls. + +WP Armour Extended (Paid Version) supports additional anti spam protection and features. + +* Record Spam Submission, view what spam bot are trying to submit +* Logs spam bot IPs. +* Block spam bot IPs if multiple spam is submitted. Add extra level of anti spam filter based on IPs. Stops spam bot from using unwanted bandwidth and save valuable server resource. +* WooCommerce Checkout & Registration including Card Testing Orders (woocommerce.com) +* Easy Digital Downloads Checkout and Registration (easydigitaldownloads.com) +* QuForm Contact Form (quform.com) +* Ninja Forms (https://ninjaforms.com) +* Gravity Forms (For Ajax Based and Multi Step Forms - gravityforms.com) +* MC4WP: Mailchimp for WordPress (mc4wp.com) +* S2 Members (s2member.com) +* Ulimate Members (ultimatemember.com) +* Bricks Builder Form (bricksbuilder.io) +* BricksForge Pro Form (bricksforge.io) +* Beaver Builder Contact Form Module (Beaver Builder) +* Strong Testimonials (wordpress.org/plugins/strong-testimonials) +* Formcraft Form (formcraft-wp.com) +* Forminator Form (wordpress.org/plugins/forminator) +* WS Form (wordpress.org/plugins/ws-form) +* YITH Easy Login & Register Popup for WooCommerce +* UsersWP (wordpress.org/plugins/userswp) +* Youzify (youzify.com/) +* MailPoet (wordpress.org/plugins/mailpoet) +* Brevo - SendInBlue (wordpress.org/plugins/mailin) +* JetForm Builder (jetformbuilder.com) +* HTMLform plugin (htmlformsplugin.com) +* Avia Enfold Theme (kriesi.at/themes/enfold) +* BuddyPress (buddypress.org) +* BuddyBoss (buddyboss.com) +* Sure Forms (wordpress.org/plugins/sureforms) +* Everest Forms (wordpress.org/plugins/everest-forms) + +You can get the WP Armour - Anti Spam Extended from here + + +How our plugin is different than other honeypot anti spam plugins ? + +* Works for most of the forms and wordpress system including registation and comments. So All in one anti spam solution. +* No external API calls like Akismet or CleanTalk for spam filtering. +* GDPR Compliant. +* Spam bots can't use javascript so we use javascript to insert honeypot anti spam field in the form and spam bots can't fill it to pass anti spam test. +* Unique honeypot field name generated for each wordpress installation, so it is hard for spam bots to make one fit for all solution to bypass honeypot anti spam test. +* No setup required. Just activate the plugin and it enables anti spam for all supported forms, comment and registration. +* No API or monthly subscription needed like other plugins. Though we have Premium extended version of the plugin for more support with yearly license. + +Support + +If you have any issue, you can write to using support forum. + +Need distance-based delivery fees in WooCommerce? + +Calculate accurate shipping costs automatically with RoutePricing. +Uses Google Maps to set dynamic prices per km/mi — perfect for restaurants, local shops, and delivery businesses. + +Support Us at Patreon + +Your support is vital for us to keep fighting spam. By supporting us on Patreon with as little as USD 1, you will help us continue developing of our anti spam plugin. + +Our other plugins + +* Use Any Font +* Jquery Validation For Contact Form 7 +* Jquery Validation For Gravity Forms +* Block Specific Plugin Updates + +== Installation == +1. You can install plugin directly from Wordpress Plugin menu. Search for WP Armour - Honeypot Anti Spam plugin and click on Install OR you can download the plugin and install honeypot.zip from Upload Plugin button from Wordpress Plugin menu. +2. You can also access the settings from WP Armour menu. From there you can change honeypot anti spam field name and honeypot spam submission message. +3. Please check your forms, comments, bbpress, registration to confirm they are working after honeypot is placed. There will be widgets below the forms to confirm anti spam protection is enabled and ready to block spam. + +== Frequently Asked Questions == + += How this plugin is different than other honeypot anti spam plugins ? = + +We have used the honeypot technic differently in this plugin to make it work better. What other plugin does is, they add honeypot anti spam field from server side (PHP) and check if the spam bot have filled or not. If it is filled it is marked as spam. But in our case, we add honeypot anti spam field from client side (Javascript) and check if honeypot field exists or not. Spam bots can't use javascript and honeypot field is not available for them. This way we can better trap spam bot. + += Will it block all the spam submission ? = + +Spam submission are either created by spam bot or by manual submission from users. Honeypot trap is for spam bots only. So there won't be submission from spam bots. So you get rid of around 98% of spam. And ya, it can block russian spam, chinese spam effectively. + += How can i verify that honeypot anti spam protection is enabled ? = + +Honeypot Anti Spam is a trap for spam bots, so it is not visible for users. However, if you are logged in as Administrator, WP Armour Test widget is shown below the form. This will confirm Honeypot anti spam checker is active in that form. And also allows you to test it as spam bot. + += Do i need Captcha verification ? = + +No, with this plugin you don't need Captcha, reCaptcha or Invisble Captcha at all. Lets avoid hassle for common users. Just activate the plugin and for all supported forms, anti spam filter is enabled automatically. + += I am already using reCaptcha but still getting spam. Can this plugin stop spammers ? = + +Yes. Spam bots are now able to solve the captcha puzzle. So they are no longer effective as anti spam checker . Our plugin's javascript based anti spam filter can block them as spam bots can't use javascript. + += I see settings to change honeypot anti spam field name. Do i need to change it ? = + +By default our plugin generates unqiue honeypot anti spam field name so that the slim chance of spam bots using the field to submit spam is more slimmer. This blocks them to create one for all type solution to bypass the honeypot field. But even in that case if you get spam bot submission, chaging the field name should work. + += Can i see what data spammers are trying to submit ? = + +With WP Armour - Honeypot Anti Spam plugin it is No. But if you want you can use WP Armour Extended and can see what data spammers are trying to submit. It also have feature to block ip address if there are multiple submission from same IP and adds extra layer of spam protection. + +== Screenshots == + +1. Screenshot #1. WP Armour - Honeypot Anti Spam Settings +1. Screenshot #2. WP Armour - Honeypot Anti Spam Statistics +1. Screenshot #3. Honeypot for Contact Form 7 ( anti spam for contact form 7 ) +1. Screenshot #4. Honeypot for Formidable Forms ( anti spam for formidable forms) +1. Screenshot #5. Honeypot for Gravity Forms ( anti spam for gravity forms ) +1. Screenshot #6. Honeypot for BBpress Wordpress Forum ( anti spam for bbpress forums ) +1. Screenshot #7. Honeypot for Comment ( anti spam for comments ) +1. Screenshot #8. Honeypot for WPForms ( anti spam for WPForms ) +1. Screenshot #9. Honeypot for Caldera Forms ( anti spam for caldera forms) +1. Screenshot #10. Honeypot for Divi Contact Forms ( anti spam for Divi contact forms ) +1. Screenshot #11. Anti Spam for WooCommerce Checkout (Available in Extended version) +1. Screenshot #11. Anti Spam for Fluent Forms + +== Changelog == + += = 2.3.04 = + +* Changes in Honeypot field + += = 2.3.03 = + +* Sidebar Update + += = 2.3.02 = + +* Fixed the login issue. We are really sorry for the trouble it has occured. + += = 2.3.01 = + +* Divi Form Issue Fixed + += = 2.3 = + +* Option to disable Jquery Usage. + += = 2.2.14 = + +* Comment Form Fixes + += = 2.2.13 = + +* Fixes for Ultimate Memebership form +* Remove widgets for Non administrator. + += = 2.2.12 = + +* Registration and Login support for User Registration & Membership + += = 2.2.11 = + +* Fixed Forgot Password issue for TutorLMS. + += = 2.2.10 = + +* Fixed Forgot Password issue. + += = 2.2.09 = + +* Fixed Admin password reset issue. + += = 2.2.08 = + +* WP Armour Anti Spam Statistics available for Editor role. +* Filter by Forms and IP search available in WP Armour Extended version + += = 2.2.07 = + +* Added support for Elementor Login Form +* Anti spam support for Lost Password ( Reset Password ) + += = 2.2.06 = + +* Fixed Divi Notice Issue. + += = 2.2.05 = + +* Fixed WooCommerce issue that came after 2.2.04 update. + += = 2.2.04 = + +* Code Optimization +* Fix multiple span check widgets being shown for some forms. + += = 2.2.03 = + +* Gravity Form Error Fixed. +* Learnpress error fixes. + += = 2.2.02 = + +* All integrations disbale/enable option added in Extended version. + += = 2.2.01 = + +* Removed Level 2 anti spam check as it is no more needed. + += = 2.1.23 = + +* Issue fixed for Contact Form 7. + += = 2.1.22 = + +* Fixed admin url path issues. + += = 2.1.21 = + +* Fixed multiple test widget issue. + += = 2.1.20 = + +* Fixes for Easy Digital Downloads reviews (EDD Reviews). +* Fixed issues related to current stats being empty. + += = 2.1.19 = + +* Fixes for Toolset forms. + += = 2.1.18 = + +* Roll back of version 2.1.17 as it created more issues for Elementor Forms. + += = 2.1.17 = + +* Fixed Elementor Admin Form Submission issue. + += = 2.1.16 = + +* Fixed comment form isuse for few themes. + += = 2.1.15 = + +* Fixes for Toolset Registration Form + += = 2.1.14 = + +* Fixed XSS vulnerabilities issue for Divi + += = 2.1.13 = + +* Fixed field visible isssue. +* Fixed login issue to UserWP + += = 2.1.12 = + +* Fixed login submission issue. + += = 2.1.11 = + +* Fixed Divi Submission issue when field has special characters. + += = 2.1.10 = + +* Fixed Divi Submission issue + += = 2.1.9 = + +* Fixed Autocomplete issue + += = 2.1.8 = + +* Hidden Field Css issue fixed. + += = 2.1.7 = + +* Added extra spam check + += = 2.1.6 = + +* Fix Contact Form 7 issue when validation error occurs. + += = 2.1.5 = + +* Fluent Form deprecated hooks update. + += = 2.1.4 = + +* Fixed cart issue when using custom form. + += = 2.1.3 = + +* Fixed WCAG compatibility + += = 2.1.2 = + +* Fixed login recording issue. + += = 2.1.1 = + +* Fixed WP Form submission data issue. + += = 2.1 = + +* Added support for Divi Engine Form + += = 2.0.2 = + +* Added support for Beaver Builder Theme's comment form. + += = 2.0.1 = + +* Fixed error message due to removal of ajax call. + += = 2.0 = + +* Fixed false notification message regarding version conflict. + += = 1.10 = + +* Fixed Popup Form issue +* Removed wpa_field_info Ajax call + += = 1.9.2 = +* Fixed Astra Theme Comment Issue + + += = 1.9.1 = +* Removed alert msg error. + += = 1.9 = +* Removed inline javascript for better performance. + += = 1.8.5 = +* Added support for WooCommerce Reviews Pro. +* Added support for Fluent Form Conversional Forms. +* Better Protection against WooCommerce Fake Credit Card Test Orders + += = 1.8.4 = +* removed complicated spam checker as it was creating issue for some users. + += = 1.8.3 = +* Fixed false spam issue for some users. + += = 1.8.2 = +* Added extra security check + += = 1.8.1 = +* Fixed session issue. + += = 1.8 = +* Added dynamic value for honeypot field test for more powerfull spam blocker. + += = 1.7.2 = +* Added random field name generate button +* Fixed stats issue. + += = 1.7.1 = +* Fixed Test Widget not showing issue +* Fixed stats issue. + += = 1.7 = +* Fixed Hide Notification issue. +* Tested with 5.7. + += = 1.6 = +* Removed WooCommerce Support from Lite version due to complications. +* Added option to disable Wp Armour Anti Spam Widget. + += = 1.5.9 = +* Removed WooCommerce checkout spam protection. + += = 1.5.8 = +* Fixed Extended verion save settings. + += = 1.5.7 = +* Fixed security issue. + + += = 1.5.6 = +* Fixed Gravity Form Ajax Issue +* Added anti spam protection for Elementor Form Widget +* Added anti spam protection for Fluent Forms. + += = 1.5.5 = +* Added anti spam protection for woocommerce. +* Added anti spam protection for divi contact form. + += = 1.5.4 = +* Added anti spam statictic in Dashboard for Extended version users. + += = 1.5.3 = +* Added anti spam support for Toolset Forms. +* Fixed Caldera Forms anti spam message issue in Admin. + += = 1.5.2 = +* Removed anti spam filter from admin comment section. Before it was marking the comment as spam when trying to add from admin panel. + += = 1.5.1 = +* Added honeypot anti spam support for Caldera Forms. + += = 1.5 = +* WP Armour Test Panel added in forms to confirm spam protection is enabled. Only visible for Admin. + += = 1.4 = +* Added honeypot anti spam for Formidable Forms +* Added honeypot anti spam statistics + += = 1.3 = +* Rebranding to WP Armour - Honeypot Anti Spam Plugin. + += = 1.1 = +* Removed unwanted settings. + += = 1.0 = +* First Release +* Added anti spam honeypot for contact form 7 +* Added anti spam honeypot for gravity forms \ No newline at end of file diff --git a/html/wp-content/plugins/honeypot/screenshot-1.png b/html/wp-content/plugins/honeypot/screenshot-1.png new file mode 100644 index 0000000..3081f72 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-1.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-10.png b/html/wp-content/plugins/honeypot/screenshot-10.png new file mode 100644 index 0000000..a76db1f Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-10.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-11.png b/html/wp-content/plugins/honeypot/screenshot-11.png new file mode 100644 index 0000000..deed18c Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-11.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-12.png b/html/wp-content/plugins/honeypot/screenshot-12.png new file mode 100644 index 0000000..0cd70b0 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-12.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-2.png b/html/wp-content/plugins/honeypot/screenshot-2.png new file mode 100644 index 0000000..bb89afc Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-2.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-3.png b/html/wp-content/plugins/honeypot/screenshot-3.png new file mode 100644 index 0000000..31c7fa6 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-3.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-4.png b/html/wp-content/plugins/honeypot/screenshot-4.png new file mode 100644 index 0000000..f644df7 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-4.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-5.png b/html/wp-content/plugins/honeypot/screenshot-5.png new file mode 100644 index 0000000..d153009 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-5.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-6.png b/html/wp-content/plugins/honeypot/screenshot-6.png new file mode 100644 index 0000000..3a83aad Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-6.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-7.png b/html/wp-content/plugins/honeypot/screenshot-7.png new file mode 100644 index 0000000..7265710 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-7.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-8.png b/html/wp-content/plugins/honeypot/screenshot-8.png new file mode 100644 index 0000000..4919451 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-8.png differ diff --git a/html/wp-content/plugins/honeypot/screenshot-9.png b/html/wp-content/plugins/honeypot/screenshot-9.png new file mode 100644 index 0000000..4c1db06 Binary files /dev/null and b/html/wp-content/plugins/honeypot/screenshot-9.png differ diff --git a/html/wp-content/plugins/honeypot/wp-armour.php b/html/wp-content/plugins/honeypot/wp-armour.php new file mode 100644 index 0000000..4749396 --- /dev/null +++ b/html/wp-content/plugins/honeypot/wp-armour.php @@ -0,0 +1,53 @@ +` to allowed HTML elements for GDPR disclaimer text on settings pages. +- Remove all references to obsolete placeholders.js polyfill. +- Move the GiveWP sign-up checkbox closer to the email input field. Thanks [Matthew Lewis](https://github.com/Matthew-Lewis). + + +#### 4.8.10 - Sep 14, 2022 + +- Fix mc4wp_get_request_ip_address() to return an IP address that matches Mailchimp's validation format when X-Forwarded-For header contains a port component. + + +#### 4.8.8 - Aug 25, 2022 + +- Fix mc4wp_get_request_ip_address() to pass new Mailchimp validation format. This fixes the "This value is not a valid IP." error some users using a proxy may have been seeing. + + +#### 4.8.7 - Mar 2, 2022 + +- Fix PHP 8.1 deprecation warnings in `MC4WP_Container` class. +- Fix name of action hook that fires before Mailchimp settings rows are displayed on the settings page. Thanks [LoonSongSoftware](https://github.com/LoonSongSoftware). +- Improve WPML compatibility. Thanks [Sumit Singh](https://github.com/5um17). +- Fix deprecated function for AMP integration. +- Only allow unfiltered HTML if user has `unfiltered_html` capability. Please read the below. + +Despite extensive testing, we may have missed some more obscure HTML elements or attributes from our whitelist. +If you notice that some of your form HTML is stripped after saving your form, please get in touch with our support team and provide the HTML you attempted to save. + + +#### 4.8.6 - Jun 24, 2021 + +- Add nonce field to button for dismissing notice asking for plugin review. +- Add strings from config/ directory to POT file. +- Add nonce check to AJAX endpoint for refreshing cached Mailchimp lists. +- Add capability check to AJAX endpoint for retrieving list details. +- Schedule event to refresh cached Mailchimp list upon plugin activation. + +Thanks to the team over at [pluginvulnerabilities.com](https://www.pluginvulnerabilities.com/) for bringing some of these changes to our attention. + + +#### 4.8.5 - Jun 1, 2021 + +Add nonce verification to all URL's using `_mc4wp_action` query parameter. +This fixes a CSRF vulnerability where a malicious website could trick a logged-in admin user in performing unwanted actions. + +A special thanks to Erwan from [WPScan](https://wpscan.com/) for bringing this issue to our attention. + + +#### 4.8.4 - May 7, 2021 + +- Add `defer` attribute to JS file, so page parsing isn't blocked at all. +- Rewrite plugin CSS to optimize for selector performance and get rid of some duplication. + +After installing this update, make sure to also update any add-on plugins like [Mailchimp for WordPress Premium](https://www.mc4wp.com/premium-features/) and [Mailchimp Top Bar](https://wordpress.org/plugins/mailchimp-top-bar/). + + +#### 4.8.3 - Jan 21, 2021 + +- Fix fatal error on older PHP versions when submitting form without any subscriber tags set in the form settings. +- Minor performance improvement in bootstrap method of the plugin. + + +#### 4.8.2 - Jan 20, 2021 + +- Allow short-circuiting `mc4wp_subscriber_data` filter by returning `null` or `false`. +- Use a subdirectory for the default debug log file location, so that it's easier to protect using htaccess. +- Improved reliability for fetching lists from mailchimp when lists have high stats.member_count property. + + +#### 4.8.1 - Aug 25, 2020 + +- Fix notice by explicitly setting `permission_callback` on registered REST route. +- Minor internal code improvements. + +#### 4.8 - Jul 9, 2020 + +- Plugin now requires PHP 5.3 or higher. +- Prefix overlay classname to prevent styling collissions with other plugins. +- Form sign-ups can now add tags to both new and existing subscribers. +- Update JavaScript dependencies. +- Register script early to work with Gutenberg preview. + + +#### 4.7.8 - Jun 04, 2020 + +- Add `MC4WP_API_V3::add_template` method. +- Minor code hardening to ensure a default form is always set. +- Update JS dependencies to their latest versions. +- Fix icon for Gutenberg block. + + +#### 4.7.7 - Apr 28, 2020 + +- Update JS dependencies to their latest versions. +- API client `add_list_member` method now has an additional parameter to skip merge field validation. +- Simplify code for updating an existing form. + + +#### 4.7.6 - Apr 9, 2020 + +- Update JS dependencies to their latest versions. +- Check if className is of type string, fixes a console warning when clicking inside a SVG element. +- Minor improvements to the AMP implementation to address harmless validation warnings. + + +#### 4.7.5 - Feb 10, 2020 + +- Add AMP compatibility to sign-up forms, thanks to Claudiu Lodromanean. This uses the [official AMP plugin for WordPress](https://amp-wp.org). +- Add settings key to WPML config so settings can easily by copied over to translated versions of a form. +- Optimize size & performance of JavaScript code, resulting in a file that is 40% smaller. +- Update CodeMirror to its latest version. +- Escape all string translations. + + +#### 4.7.4 - Dec 7, 2019 + +**Fixes** + +- htaccess config for servers running Apache 2.4 or later. + + +#### 4.7.3 - Dec 4, 2019 + +**Fixes** + +- Top Bar & User Sync add-on using API v2 since version 4.7.1. +- Revert change in formatter for date fields, breaking all forms with date fields in them. + +**Improvements** + +- Add getter method for raw (unmodified) data on form class. + + +#### 4.7.2 - Nov 27, 2019 + +**Fixes** + +- Invalid .htaccess file in case there already is one in the uploads directory. + + +#### 4.7.1 - Nov 26, 2019 + +**Improvements** + +- Update MemberPress hook names. Thanks [Ian Heggaton](https://github.com/pixelated-au)! +- Use WordPress.org translations instead of bundling translation files in plugin itself. +- Write .htaccess to directory of debug log file, to prevent file access. +- Add some convenient hooks for Checkout for WooCommerce. +- Stop parsing shortcodes in text widgets as WordPress core does this since version 4.9. + + +#### 4.7 - Nov 7, 2019 + +**Improvements** + +- Add role=alert to form notices. +- Add setting to pre-check sign-up checkbox for Gravity Forms integrations. +- Add new position for WooCommerce integration: directly after the billing_email field. +- Fix PHP notices for submitting a form and saving a form as an administrator. +- Add link to [Koko Analytics plugin](https://wordpress.org/plugins/koko-analytics/). + + +#### 4.6.2 - Oct 24, 2019 + +**Fixes** + +- Address fields in forms would always be required (even if really optional). + +**Improvements** + +- Add proper SVG admin menu icon. +- Minor overall performance and memory usage improvements. + + +#### 4.6.1 - Oct 7, 2019 + +**Fixes** + +- Fixed list cache usage for WPForms, Gravity Forms and Ninja Forms integrations. + + +#### 4.6.0 - Oct 7, 2019 + +**Improvements** + +- Improved fetch and cache mechanism for retrieving Mailchimp account details, fetching data only when it is required. +- Updated [Mithril](https://mithril.js.org/) and [CodeMirror](https://codemirror.net/) dependencies. +- Decreased size of `forms.js` from 22KB to 9KB. +- No longer requiring jQuery anywhere. +- Increase API HTTP request timeout to 15 seconds. + +Please note that installing this update requires you to also update any add-ons like [Mailchimp Top Bar](https://wordpress.org/plugins/mailchimp-top-bar/) and [Mailchimp for WordPress Premium](https://www.mc4wp.com/premium-features/) (if installed). + + +#### 4.5.5 - Sep 12, 2019 + +**Fixes** + +- Google reCAPTCHA script was still loading even if no forms have it enabled. + + +#### 4.5.4 - Sep 11, 2019 + +**Improvements** + +- Removed custom color from menu item for improved accessibility. +- Take birthday field format into account when sending data to Mailchimp. +- Print Google reCAPTCHA script in footer. + +**Changes** + +- Changed plugin name to MC4WP instead of Mailchimp for WordPress. + + +#### 4.5.3 - July 23, 2019 + +**Fixes** + +- Temporarily switch status of pending subscribers to "unsubscribe" versus deleting susbcriber before re-subscribing. +- Deprecation notice for Gravity Forms version 2.4 and higher. + +**Improvements** + +- Filter out empty tags when applying tags to new subscribers. +- Show all not installed integrations. +- Show notice when form doesn't have a Mailchimp list selected to subscribe people to. +- Check function existence for compatibility with WordPress 4.7 +- Don't submit form when Google reCAPTCHA is enabled but errors. +- Update third-party JavaScript dependencies. + + +#### 4.5.2 - May 8, 2019 + +**Improvements** + +- Accept more truthy values in custom integration for improved compatibility with third-party forms. +- Update JavaScript dependencies. +- Load Google reCaptcha script in footer (if needed). + + +#### 4.5.1 - April 8, 2019 + +**Additions** + +- Add sign-up integration for [Give](https://wordpress.org/plugins/give/) +- Add sign-up integration for [UltimateMember](https://wordpress.org/plugins/ultimate-member/) + +**Improvements** + +- Write to debug log if Google reCAPTCHA secret key is incorrect. +- Validate reCAPTCHA keys when savings form settings. +- Allow setting an empty "successfully subscribed" message. + + +#### 4.5.0 - March 27, 2019 + +**Additions** + +- Built-in integration with Google reCAPTCHA to prevent bots from subscribing to your Mailchimp lists. + +**Improvements** + +- Minor improvements to the JavaScript that is loaded on admin pages. + + +#### 4.4.0 - March 1, 2019 + +**Fixes** + +- AffiliateWP integration subscribing the wrong user if affiliate ID differs from user ID. + +**Improvements** + +- Renamed "MailChimp" to "Mailchimp" to match Mailchimp's new branding. +- More accurate handling of timeouts for accounts with many MailChimp lists. +- UX improvements for integrations overview page. +- Validate MailChimp API key format when it's entered. +- Improved compatibility with Klarna Checkout in the WooCommerce checkout integration. +- Bumped required PHP version to 5.3 (soft requirement for now). + +**Additions** + +- Added Gutenberg block for easily adding a form to a post or page. +- Added subscriber tags setting to forms. + + +#### 4.3.3 - December 31, 2018 + +**Fixes** + +- Update WPForms integration to properly detect if the WPForms plugin is activated. + +**Improvements** + +- Write API request parameters to the debug log in case of connection timeouts. +- Update JavaScript dependencies. + + +#### 4.3.2 - December 11, 2018 + +**Fixes** + +- Use of `readonly` function, which is only available in WordPress 4.9 or later. + + +#### 4.3.1 - November 28, 2018 + +**Fixes** + +- Fatal error on PHP versions older than 5.5 + + +#### 4.3 - November 28, 2018 + +**Additions** + +- Added `MC4WP_API_KEY` PHP constant which can be used to set your Mailchimp API key. +- Add `mc4wp_mailchimp_list_limit` filter hook to modify the maximum number of Mailchimp lists to fetch. Defaults to 200. + +**Improvements** + +- Apply `mc4wp_integration_gravity-forms_options` filter hook on Gravity Forms integration options so the checkbox can be prechecked and the checkbox label text modified. +- The `updated_subscriber` JS event is now fired forms not using AJAX as well (when applicable). + + +#### 4.2.5 - Sep 11, 2018 + +**Improvements** + +- Only re-add subscriber to list if we want to re-trigger a double opt-in confirmation email. +- Change Gravity Forms field name to "Mailchimp for WordPress" +- Get rid of cached result of Mailchimp API connection. + + +#### 4.2.4 - July 9, 2018 + +**Improvements** + +- Ensure type-safety on some global variables. +- Stop showing trashed forms immediately. +- Pre-check Mailchimp list when creating a new form if there is only 1 list. +- Send `null` for unknown values in usage tracking data (only when opted-in). + +**Additions** + +- Add methods for accessing Mailchimp's e-commerce promo code endpoints to API class. + + +#### 4.2.3 - June 11, 2018 + +**Fixes** + +- Don't wrap "agree to terms" input in hyperlink element. +- Allow [ENTER] key again after field helper overlay is closed. + +**Improvements** + +- Fallback to meta-refresh if redirect fails because of "headers already sent" error. + + + +#### 4.2.2 - May 22, 2018 + +**Fixes** + +- Events Manager integration was not working with logged-in users. +- Form preview URL should respect admin HTTP(S) scheme. +- Removed use of PHP 5.4 function. + +**Improvements** + +- Add "agree to terms" checkbox to field helper. + +**Additions** + +- Add filter `mc4wp_http_request_args`. + + +#### 4.2.1 - April 11, 2018 + +**Fixes** + +- Namespace usage warning when running PHP 5.2 + +**Improvements** + +- Remove obsolete `type` attribute from all `'; + } + + /** + * Outputs the inline JavaScript that is used to enhance forms + */ + public function load_scripts() + { + $load_scripts = apply_filters('mc4wp_load_form_scripts', $this->load_scripts); + if (! $load_scripts) { + return; + } + + // load general client-side form API + wp_enqueue_script('mc4wp-forms-api'); + + // maybe load JS file for when a form was submitted over HTTP POST + $submitted_form_data = $this->get_submitted_form_data(); + if ($submitted_form_data !== null) { + wp_enqueue_script('mc4wp-forms-submitted', mc4wp_plugin_url('assets/js/forms-submitted.js'), [ 'mc4wp-forms-api' ], MC4WP_VERSION, true); + wp_localize_script('mc4wp-forms-submitted', 'mc4wp_submitted_form', $submitted_form_data); + } + + // print inline scripts + echo ''; + + /** @ignore */ + do_action('mc4wp_load_form_scripts'); + } + + /** + * Adds `defer` attribute to all form-related ` + + + + +
        + +
        + + diff --git a/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/admin-footer.php b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/admin-footer.php new file mode 100644 index 0000000..4c26b46 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/admin-footer.php @@ -0,0 +1,35 @@ +' . sprintf(wp_kses(__('Mailchimp for WordPress is in need of translations. Is the plugin not translated in your language or do you spot errors with the current translations? Helping out is easy! Please help translate the plugin using your WordPress.org account.', 'mailchimp-for-wp'), ['a' => ['href' => []]]), 'https://translate.wordpress.org/projects/wp-plugins/mailchimp-for-wp/stable/') . '

        '; +} + +function _mc4wp_admin_github_notice() +{ + if (strpos($_SERVER['HTTP_HOST'], 'localhost') === false && ! WP_DEBUG) { + return; + } + + echo '

        Developer? Follow Mailchimp for WordPress on GitHub or have a look at our repository of sample code snippets.

        '; +} + +function _mc4wp_admin_disclaimer_notice() +{ + echo '

        ', esc_html__('This plugin is not developed by or affiliated with Mailchimp in any way.', 'mailchimp-for-wp'), '

        '; +} + +add_action('mc4wp_admin_footer', '_mc4wp_admin_translation_notice', 20); +add_action('mc4wp_admin_footer', '_mc4wp_admin_github_notice', 50); +add_action('mc4wp_admin_footer', '_mc4wp_admin_disclaimer_notice', 80); + +?> +
        + +
        diff --git a/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/admin-sidebar.php b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/admin-sidebar.php new file mode 100644 index 0000000..647d619 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/admin-sidebar.php @@ -0,0 +1,59 @@ + +
        +

        +

        +
          +
        • +
        • +
        +

        support forums on WordPress.org.', 'mailchimp-for-wp'), [ 'a' => [ 'href' => [] ] ]), 'https://wordpress.org/support/plugin/mailchimp-for-wp'); ?>

        +

        open an issue on GitHub.', 'mailchimp-for-wp'), [ 'a' => [ 'href' => [] ] ]), 'https://github.com/ibericode/mailchimp-for-wordpress/issues'); ?>

        +
        + '; + echo '

        ', esc_html__('Other plugins by ibericode', 'mailchimp-for-wp'), '

        '; + echo '
          '; + + // Koko Analytics + echo '
        • '; + echo 'Koko Analytics
          '; + echo esc_html__('Privacy-friendly analytics plugin that does not use any external services.', 'mailchimp-for-wp'); + echo '
        • '; + + // Boxzilla + echo '
        • '; + echo 'Boxzilla Pop-ups
          '; + echo esc_html__('Pop-ups or boxes that slide-in with a newsletter sign-up form. A sure-fire way to grow your email lists.', 'mailchimp-for-wp'); + echo '
        • '; + + echo '
        '; + echo ''; +} + +add_action('mc4wp_admin_sidebar', '_mc4wp_admin_sidebar_other_plugins', 40); +add_action('mc4wp_admin_sidebar', '_mc4wp_admin_sidebar_support_notice', 50); + +/** + * Runs when the sidebar is outputted on Mailchimp for WordPress settings pages. + * + * Please note that not all pages have a sidebar. + * + * @since 3.0 + */ +do_action('mc4wp_admin_sidebar'); diff --git a/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/lists-overview-details.php b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/lists-overview-details.php new file mode 100644 index 0000000..40dfc69 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/lists-overview-details.php @@ -0,0 +1,104 @@ + +

        Merge fields

        + + + + + + + + + + + + + + + + + +
        NameTagType
        name); ?> required) { + ?> + * + tag); ?> + type); ?> + options && $f->options->date_format) { + echo esc_html('(' . $f->options->date_format . ')'); + } + ?> + options && $f->options->choices) { + echo esc_html('(' . join(', ', $f->options->choices) . ')'); + } + ?> +
        + + +

        Interest Categories

        + + + + + + + + + + + + + + + + + +
        NameTypeInterests
        + title); ?> +
        +
        + ID: id); ?> +
        type); ?> + + + + + + interests as $id => $name) { ?> + + + + + + +
        NameID
        + +
        + + + +

        Marketing Permissions

        + + + + + + + + + + + + + + + +
        IDName
        marketing_permission_id); ?>text); ?>
        + diff --git a/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/lists-overview.php b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/lists-overview.php new file mode 100644 index 0000000..d65bf8a --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/includes/views/parts/lists-overview.php @@ -0,0 +1,60 @@ +

        +

        + +
        +
        + +

        + +

        +
        +
        + +
        + +

        .

        + ', sprintf(esc_html__('A total of %d audiences were found in your Mailchimp account.', 'mailchimp-for-wp'), count($lists)), '

        '; + echo ''; + + $headings = [ + esc_html__('Audience name', 'mailchimp-for-wp'), + esc_html__('Audience ID', 'mailchimp-for-wp'), + esc_html__('# of contacts', 'mailchimp-for-wp'), + ]; + + echo ''; + echo ''; + foreach ($headings as $heading) { + echo ''; + } + echo ''; + echo ''; + echo ''; + + foreach ($lists as $list) { + $attr_data_list_id = esc_attr($list->id); + $list_name = esc_html($list->name); + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + ?> + '; + echo '
        ', $heading, '
        ', $list_name, '', esc_html($list->id), '', esc_html($list->stats->member_count), '
        '; + } // end if empty + ?> +
        diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/affiliatewp/class-affiliatewp.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/affiliatewp/class-affiliatewp.php new file mode 100644 index 0000000..85e96a7 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/affiliatewp/class-affiliatewp.php @@ -0,0 +1,88 @@ +options['implicit']) { + add_action('affwp_register_fields_before_tos', [ $this, 'maybe_output_checkbox' ], 20); + } + + add_action('affwp_register_user', [ $this, 'subscribe_from_registration' ], 90, 1); + } + + /** + * Output checkbox, once. + */ + public function maybe_output_checkbox() + { + if (! $this->shown) { + $this->output_checkbox(); + $this->shown = true; + } + } + + /** + * Subscribes from WP Registration Form + * + * @param int $affiliate_id + * + * @return bool|string + */ + public function subscribe_from_registration($affiliate_id) + { + + // was sign-up checkbox checked? + if (! $this->triggered()) { + return false; + } + + // gather emailadress from user who WordPress registered + $user_id = affwp_get_affiliate_user_id($affiliate_id); + $user = get_userdata($user_id); + + // was a user found with the given ID? + if (! $user instanceof WP_User) { + return false; + } + + $data = $this->user_merge_vars($user); + + return $this->subscribe($data, $user_id); + } + /* End registration form functions */ + + + /** + * @return bool + */ + public function is_installed() + { + return class_exists('Affiliate_WP'); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/bootstrap.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/bootstrap.php new file mode 100644 index 0000000..1aa0567 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/bootstrap.php @@ -0,0 +1,52 @@ +slug . '/admin-before.php'; + if (file_exists($file)) { + include $file; + } +} + +/** + * Try to include a file before each integration's settings page + * + * @param MC4WP_Integration $integration + * @param array $opts + * @ignore + */ +function mc4wp_admin_after_integration_settings(MC4WP_Integration $integration, $opts) +{ + $file = __DIR__ . '/' . $integration->slug . '/admin-after.php'; + if (file_exists($file)) { + include $file; + } +} + +add_action('mc4wp_admin_before_integration_settings', 'mc4wp_admin_before_integration_settings', 30, 2); +add_action('mc4wp_admin_after_integration_settings', 'mc4wp_admin_after_integration_settings', 30, 2); + +// Register core integrations +mc4wp_register_integration('wp-comment-form', 'MC4WP_Comment_Form_Integration'); +mc4wp_register_integration('wp-registration-form', 'MC4WP_Registration_Form_Integration'); +mc4wp_register_integration('buddypress', 'MC4WP_BuddyPress_Integration'); +mc4wp_register_integration('easy-digital-downloads', 'MC4WP_Easy_Digital_Downloads_Integration'); +mc4wp_register_integration('contact-form-7', 'MC4WP_Contact_Form_7_Integration', true); +mc4wp_register_integration('events-manager', 'MC4WP_Events_Manager_Integration'); +mc4wp_register_integration('memberpress', 'MC4WP_MemberPress_Integration'); +mc4wp_register_integration('affiliatewp', 'MC4WP_AffiliateWP_Integration'); +mc4wp_register_integration('give', 'MC4WP_Give_Integration'); +mc4wp_register_integration('custom', 'MC4WP_Custom_Integration', true); +mc4wp_register_integration('woocommerce', 'MC4WP_WooCommerce_Integration'); + +require __DIR__ . '/prosopo-procaptcha/bootstrap.php'; +require __DIR__ . '/wpforms/bootstrap.php'; +require __DIR__ . '/gravity-forms/bootstrap.php'; +require __DIR__ . '/ninja-forms/bootstrap.php'; diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/buddypress/class-buddypress.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/buddypress/class-buddypress.php new file mode 100644 index 0000000..fbfe3d9 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/buddypress/class-buddypress.php @@ -0,0 +1,183 @@ +options['implicit']) { + add_action('bp_before_registration_submit_buttons', [ $this, 'output_checkbox' ], 20); + } + + if (is_multisite()) { + + /** + * Multisite signups are a two-stage process - the data is first added to + * the 'signups' table and then converted into an actual user during the + * activation process. + * + * To avoid all signups being subscribed to the Mailchimp list until they + * have responded to the activation email, a value is stored in the signup + * usermeta data which is retrieved on activation and acted upon. + */ + add_filter('bp_signup_usermeta', [ $this, 'store_usermeta' ], 10, 1); + add_action('bp_core_activated_user', [ $this, 'subscribe_from_usermeta' ], 10, 3); + } else { + add_action('bp_core_signup_user', [ $this, 'subscribe_from_form' ], 10, 4); + } + + /** + * There is one further issue to consider, which is that many BuddyPress + * installs have a user moderation plugin (e.g. BP Registration Options) + * installed. This is because email activation on itself is sometimes not enough to ensure + * that user signups are not spammers. There should therefore be a way for + * plugins to delay the Mailchimp signup process. + * + * Plugins can hook into the 'mc4wp_integration_buddypress_should_subscribe' filter to prevent + * subscriptions from taking place: + * + * add_filter( 'mc4wp_integration_buddypress_should_subscribe', '__return_false' ); + * + * The plugin would then then call: + * + * do_action( 'mc4wp_integration_buddypress_subscribe_user', $user_id ); + * + * to perform the subscription at a later point. + */ + add_action('mc4wp_integration_buddypress_subscribe_user', [ $this, 'subscribe_buddypress_user' ], 10, 1); + } + + /** + * Subscribes from BuddyPress Registration Form. + * + * @param int $user_id + * @param string $user_login + * @param string $user_password + * @param string $user_email + * @return bool + */ + public function subscribe_from_form($user_id, $user_login, $user_password, $user_email) + { + if (! $this->triggered()) { + return false; + } + + $subscribe = true; + + /** + * Allow other plugins to prevent the Mailchimp sign-up. + * + * @param bool $subscribe False does not subscribe the user. + * @param int $user_id The user ID to subscribe + */ + $subscribe = apply_filters('mc4wp_integration_buddypress_should_subscribe', $subscribe, $user_id); + + if (! $subscribe) { + return false; + } + + return $this->subscribe_buddypress_user($user_id); + } + + /** + * Stores subscription data from BuddyPress Registration Form. + * + * @param array $usermeta The existing usermeta + * @return array $usermeta The modified usermeta + */ + public function store_usermeta($usermeta) + { + + // only add meta if triggered (checked) + if ($this->triggered()) { + $usermeta['mc4wp_subscribe'] = '1'; + } + + return $usermeta; + } + + /** + * Subscribes from BuddyPress Activation. + * + * @param int $user_id The activated user ID + * @param string $key the activation key (not used) + * @param array $userdata An array containing the activated user data + * @return bool + */ + public function subscribe_from_usermeta($user_id, $key, $userdata) + { + + // sanity check + if (empty($user_id)) { + return false; + } + + // bail if our usermeta key is not switched on + $meta = ( isset($userdata['meta']) ) ? $userdata['meta'] : []; + if (empty($meta['mc4wp_subscribe'])) { + return false; + } + + $subscribe = true; + + /** + * @ignore Documented elsewhere, see MC4WP_BuddyPress_Integration::subscribe_from_form. + */ + $subscribe = apply_filters('mc4wp_integration_buddypress_should_subscribe', $subscribe, $user_id); + if (! $subscribe) { + return false; + } + + return $this->subscribe_buddypress_user($user_id); + } + + /** + * Subscribes a user to Mailchimp list(s). + * + * @param int $user_id The user ID to subscribe + * @return bool + */ + public function subscribe_buddypress_user($user_id) + { + $user = get_userdata($user_id); + + // was a user found with the given ID? + if (! $user instanceof WP_User) { + return false; + } + + // gather email address and name from user + $data = $this->user_merge_vars($user); + + return $this->subscribe($data, $user_id); + } + /* End BuddyPress functions */ + + /** + * @return bool + */ + public function is_installed() + { + return class_exists('BuddyPress'); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/contact-form-7/admin-before.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/contact-form-7/admin-before.php new file mode 100644 index 0000000..f270742 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/contact-form-7/admin-before.php @@ -0,0 +1,3 @@ +

        + '); ?> +

        diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/contact-form-7/class-contact-form-7.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/contact-form-7/class-contact-form-7.php new file mode 100644 index 0000000..79c1a20 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/contact-form-7/class-contact-form-7.php @@ -0,0 +1,176 @@ +get_data(); + + return ( isset($data[ $this->checkbox_name ]) && (int) $data[ $this->checkbox_name ] === 1 ) + || ( isset($data['mc4wp-subscribe']) && (int) $data['mc4wp-subscribe'] === 1 ); + } + + /** + * Alter Contact Form 7 data. + * + * Adds mc4wp_checkbox to post data so users can use `mc4wp_checkbox` in their email templates + * + * @param array $data + * @return array + */ + public function alter_cf7_data($data = []) + { + $data['mc4wp_checkbox'] = $this->checkbox_was_checked() ? __('Yes', 'mailchimp-for-wp') : __('No', 'mailchimp-for-wp'); + return $data; + } + + /** + * Subscribe from Contact Form 7 Forms + * + * @todo improve smart guessing based on selected Mailchimp lists + * + * @param WPCF7_ContactForm $cf7_form + * @return bool + */ + public function process($cf7_form) + { + + // was sign-up checkbox checked? + if (! $this->checkbox_was_checked()) { + return false; + } + + $parser = new MC4WP_Field_Guesser($this->get_data()); + $data = $parser->combine([ 'guessed', 'namespaced' ]); + + // do nothing if no email was found + if (empty($data['EMAIL'])) { + $this->get_log()->warning(sprintf('%s > Unable to find EMAIL field.', $this->name)); + return false; + } + + return $this->subscribe($data, $cf7_form->id()); + } + + /** + * Return the shortcode output + * + * @return string + */ + public function shortcode($args = []) + { + if (! empty($args['labels'][0])) { + $this->options['label'] = $args['labels'][0]; + } + + if (isset($args['options'])) { + // check for default:0 or default:1 to set the checked attribute + if (in_array('default:1', $args['options'], true)) { + $this->options['precheck'] = true; + } elseif (in_array('default:0', $args['options'], true)) { + $this->options['precheck'] = false; + } + } + + // disable paragraph wrap because CF7 defaults to `wpautop` + $this->options['wrap_p'] = 0; + + return $this->get_checkbox_html(); + } + + /** + * @return bool + */ + public function is_installed() + { + return function_exists('wpcf7_contact_form'); + } + + /** + * @since 3.0 + * @return array + */ + public function get_ui_elements() + { + return array_diff(parent::get_ui_elements(), [ 'enabled', 'implicit' ]); + } + + /** + * @param int $object_id + * @since 3.0 + * @return string + */ + public function get_object_link($object_id) + { + + // for backwards compatibility, not all CF7 sign-ups have an object id + if (empty($object_id)) { + return ''; + } + + // Return empty string if CF7 is no longer activated. + if (! function_exists('wpcf7_contact_form')) { + return ''; + } + + $form = wpcf7_contact_form($object_id); + if (! is_object($form)) { + return ''; + } + return sprintf('%s', admin_url('admin.php?page=wpcf7&post=' . $object_id), $form->title()); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/custom/admin-before.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/custom/admin-before.php new file mode 100644 index 0000000..58fc5d4 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/custom/admin-before.php @@ -0,0 +1,15 @@ +

        + +

        + + +

        + +

        + + + + diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/custom/class-custom.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/custom/class-custom.php new file mode 100644 index 0000000..bf13143 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/custom/class-custom.php @@ -0,0 +1,133 @@ +get_data(); + $value = isset($data[ $this->checkbox_name ]) ? $data[ $this->checkbox_name ] : ''; + $truthy_values = [ 1, '1', 'yes', true, 'true', 'y' ]; + return in_array($value, $truthy_values, true); + } + + /** + * Maybe fire a general subscription request + * + * @return bool|string + */ + public function listen() + { + if (! $this->checkbox_was_checked()) { + return false; + } + + // ignore requests from bots, crawlers and link previews + if (empty($_SERVER['HTTP_USER_AGENT']) || preg_match('/bot|crawl|spider|seo|lighthouse|facebookexternalhit|preview/i', $_SERVER['HTTP_USER_AGENT'])) { + return false; + } + + // ignore requests without an HTTP referrer + if (empty($_SERVER['HTTP_REFERER'])) { + return false; + } + + // ignore requests where HTTP Referer does not contain hostname from home_url + $site_hostname = parse_url(get_home_url(), PHP_URL_HOST); + if (strpos($_SERVER['HTTP_REFERER'], $site_hostname) === false) { + return false; + } + + $data = $this->get_data(); + + // don't run for CF7 or Events Manager requests + // (since they use the same "mc4wp-subscribe" trigger) + $disable_triggers = [ + '_wpcf7' => '', + 'action' => 'booking_add', + ]; + + foreach ($disable_triggers as $trigger => $trigger_value) { + if (isset($data[ $trigger ])) { + $value = $data[ $trigger ]; + + // do nothing if trigger value is optional + // or if trigger value matches + if (empty($trigger_value) || $value === $trigger_value) { + return false; + } + } + } + + // run! + return $this->process(); + } + + /** + * Process custom form + * + * @return bool|string + */ + public function process() + { + $parser = new MC4WP_Field_Guesser($this->get_data()); + $data = $parser->combine([ 'guessed', 'namespaced' ]); + + // do nothing if no email was found + if (empty($data['EMAIL'])) { + $this->get_log()->warning(sprintf('%s > Unable to find EMAIL field.', $this->name)); + return false; + } + + return $this->subscribe($data); + } + + /** + * @return bool + */ + public function is_installed() + { + return true; + } + + /** + * @return array + */ + public function get_ui_elements() + { + return [ 'lists', 'double_optin', 'update_existing', 'replace_interests' ]; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/easy-digital-downloads/class-easy-digital-downloads.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/easy-digital-downloads/class-easy-digital-downloads.php new file mode 100644 index 0000000..5e93614 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/easy-digital-downloads/class-easy-digital-downloads.php @@ -0,0 +1,119 @@ +options['implicit']) { + // TODO: Allow more positions + add_action('edd_purchase_form_user_info_fields', [ $this, 'output_checkbox' ], 1); + add_action('edd_payment_meta', [ $this, 'save_checkbox_value' ]); + } + + add_action('edd_complete_purchase', [ $this, 'subscribe_from_edd' ], 50); + } + + /** + * @param array $meta + * + * @return array + */ + public function save_checkbox_value($meta) + { + + // don't save anything if the checkbox was not checked + if (! $this->checkbox_was_checked()) { + return $meta; + } + + $meta['_mc4wp_optin'] = 1; + return $meta; + } + + /** + * {@inheritdoc} + * + * @param $object_id + * + * @return bool + */ + public function triggered($object_id = null) + { + if ($this->options['implicit']) { + return true; + } + + if (! $object_id) { + return false; + } + + $meta = edd_get_payment_meta($object_id); + if (is_array($meta) && isset($meta['_mc4wp_optin']) && $meta['_mc4wp_optin']) { + return true; + } + + return false; + } + + /** + * @param int $payment_id The ID of the payment + * + * @return bool|string + */ + public function subscribe_from_edd($payment_id) + { + if (! $this->triggered($payment_id)) { + return false; + } + + $email = (string) edd_get_payment_user_email($payment_id); + $data = [ + 'EMAIL' => $email, + ]; + + // add first and last name to merge vars, if given + $user_info = (array) edd_get_payment_meta_user_info($payment_id); + + if (! empty($user_info['first_name']) && ! empty($user_info['last_name'])) { + $data['NAME'] = $user_info['first_name'] . ' ' . $user_info['last_name']; + } + + if (! empty($user_info['first_name'])) { + $data['FNAME'] = $user_info['first_name']; + } + + if (! empty($user_info['last_name'])) { + $data['LNAME'] = $user_info['last_name']; + } + + return $this->subscribe($data, $payment_id); + } + + /** + * @return bool + */ + public function is_installed() + { + return class_exists('Easy_Digital_Downloads'); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/events-manager/class-events-manager.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/events-manager/class-events-manager.php new file mode 100644 index 0000000..243ea23 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/events-manager/class-events-manager.php @@ -0,0 +1,80 @@ +options['implicit']) { + add_action('em_booking_form_footer', [ $this, 'output_checkbox' ]); + } + + add_action('em_bookings_added', [ $this, 'subscribe_from_events_manager' ], 5); + } + + + + /** + * Subscribe from Events Manager booking forms. + * + * @param EM_Booking $args + * @return bool + */ + public function subscribe_from_events_manager($args) + { + + // Is this integration triggered? (checkbox checked or implicit) + if (! $this->triggered()) { + return false; + } + + $em_data = $this->get_data(); + + // logged-in users do not have these form fields, so grab from user object instead + if (empty($em_data['user_email']) && is_user_logged_in()) { + $user = wp_get_current_user(); + $em_data['user_email'] = $user->user_email; + $em_data['user_name'] = sprintf('%s %s', $user->first_name, $user->last_name); + } + + if (empty($em_data['user_email'])) { + return false; + } + + $data = [ + 'EMAIL' => $em_data['user_email'], + 'NAME' => $em_data['user_name'], + ]; + + // subscribe using email and name + return $this->subscribe($data, $args->booking_id); + } + + /** + * @return bool + */ + public function is_installed() + { + return defined('EM_VERSION'); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/give/class-give.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/give/class-give.php new file mode 100644 index 0000000..1dafc7c --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/give/class-give.php @@ -0,0 +1,49 @@ +options['implicit']) { + add_action('give_purchase_form_register_login_fields', [ $this, 'output_checkbox' ], 50); + } + + add_action('give_checkout_before_gateway', [ $this, 'subscribe_from_give' ], 90, 2); + } + + public function subscribe_from_give($posted, $user) + { + // was sign-up checkbox checked? + if (true !== $this->triggered()) { + return; + } + + $merge_fields = [ + 'EMAIL' => $user['email'], + ]; + + if (! empty($user['first_name'])) { + $merge_fields['FNAME'] = $user['first_name']; + } + + if (! empty($user['last_name'])) { + $merge_fields['LNAME'] = $user['last_name']; + } + + return $this->subscribe($merge_fields); + } + + public function is_installed() + { + return defined('GIVE_VERSION'); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/admin-before.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/admin-before.php new file mode 100644 index 0000000..179c015 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/admin-before.php @@ -0,0 +1,6 @@ +

        + one of your Gravity Forms forms.', 'mailchimp-for-wp'), admin_url('admin.php?page=gf_edit_forms')); + ?> +

        diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/bootstrap.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/bootstrap.php new file mode 100644 index 0000000..a1d0030 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/bootstrap.php @@ -0,0 +1,11 @@ +failed_validation && ! empty($this->validation_message) ) ? sprintf("
        %s
        ", $this->validation_message) : ''; + $is_form_editor = $this->is_form_editor(); + $is_entry_detail = $this->is_entry_detail(); + $is_admin = $is_form_editor || $is_entry_detail; + + $admin_buttons = $this->get_admin_buttons(); + + $description = $this->get_description($this->description, 'gfield_description'); + if ($this->is_description_above($form)) { + $clear = $is_admin ? "
        " : ''; + $field_content = sprintf("%s%s{FIELD}%s$clear", $admin_buttons, $description, $validation_message); + } else { + $field_content = sprintf('%s{FIELD}%s%s', $admin_buttons, $description, $validation_message); + } + + return $field_content; + } + + public function get_form_editor_field_title() + { + return esc_attr__('Mailchimp for WordPress', 'mailchimp-for-wp'); + } + + public function get_form_editor_field_settings() + { + return [ + 'label_setting', + 'description_setting', + 'css_class_setting', + 'mailchimp_list_setting', + 'mailchimp_double_optin', + 'mailchimp_precheck', + 'rules_setting', + ]; + } + + public function get_field_input($form, $value = '', $entry = null) + { + $form_id = absint($form['id']); + $is_entry_detail = $this->is_entry_detail(); + $is_form_editor = $this->is_form_editor(); + + $id = $this->id; + $field_id = $is_entry_detail || $is_form_editor || 0 === (int) $form_id ? "input_$id" : 'input_' . $form_id . "_$id"; + $disabled_text = $is_form_editor ? 'disabled="disabled"' : ''; + + return sprintf("
          %s
        ", esc_attr($field_id), $this->get_checkbox_choices($value, $disabled_text, $form_id)); + } + + private function apply_mc4wp_options_filters($options) + { + $options = apply_filters('mc4wp_integration_gravity-forms_options', $options); + return $options; + } + + + public function get_checkbox_choices($value, $disabled_text, $form_id = 0) + { + $choices = ''; + $is_entry_detail = $this->is_entry_detail(); + $is_form_editor = $this->is_form_editor(); + + $options = [ + 'label' => $this->get_field_label(false, $value), + 'precheck' => isset($this->mailchimp_precheck) ? $this->mailchimp_precheck : false, + ]; + $options = $this->apply_mc4wp_options_filters($options); + + // generate html + $choice = [ + 'text' => $options['label'], + 'value' => '1', + 'isSelected' => $options['precheck'], + ]; + + $input_id = $this->id; + if ($is_entry_detail || $is_form_editor || 0 === (int) $form_id) { + $id = $this->id; + } else { + $id = $form_id . '_' . $this->id; + } + + if (! isset($_GET['gf_token']) && empty($_POST) && rgar($choice, 'isSelected')) { + $checked = "checked='checked'"; + } elseif (is_array($value) && RGFormsModel::choice_value_match($this, $choice, rgget($input_id, $value))) { + $checked = "checked='checked'"; + } elseif (! is_array($value) && RGFormsModel::choice_value_match($this, $choice, $value)) { + $checked = "checked='checked'"; + } else { + $checked = ''; + } + + $tabindex = $this->get_tabindex(); + $choice_value = $choice['value']; + $choice_value = esc_attr($choice_value); + $choice_markup = "
      • + + +
      • "; + + $choices .= gf_apply_filters( + [ + 'gform_field_choice_markup_pre_render', + $this->formId, + $this->id, + ], + $choice_markup, + $choice, + $this, + $value + ); + + return gf_apply_filters([ 'gform_field_choices', $this->formId, $this->id ], $choices, $this); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/class-gravity-forms.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/class-gravity-forms.php new file mode 100644 index 0000000..dc562d6 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/gravity-forms/class-gravity-forms.php @@ -0,0 +1,166 @@ +options['double_optin']; + + // find email field & checkbox value + foreach ($form['fields'] as $field) { + if ($field->type === 'email' && empty($email_address) && ! empty($submission[ $field->id ])) { + $email_address = $submission[ $field->id ]; + } + + if ($field->type === 'mailchimp' && ! empty($submission[ $field->id ])) { + $subscribe = true; + $mailchimp_list_id = $field->mailchimp_list; + + if (isset($field->mailchimp_double_optin)) { + $double_optin = $field->mailchimp_double_optin; + } + } + } + + if (! $subscribe || empty($email_address)) { + return; + } + + // override integration settings with field options + $orig_options = $this->options; + $this->options['lists'] = [ $mailchimp_list_id ]; + $this->options['double_optin'] = $double_optin; + + // perform the sign-up + $this->subscribe([ 'EMAIL' => $email_address ], $submission['form_id']); + + // revert back to original options in case request lives on + $this->options = $orig_options; + } + + public function editor_js() + { + ?> + + get_lists(); + ?> +
      • + + +

        + +

        +
      • +
      • + + +

        + +

        +
      • +
      • + + +

        + '; + printf(__('Warning: enabling this may affect your GDPR compliance.', 'mailchimp-for-wp'), 'https://www.mc4wp.com/kb/gdpr-compliance/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=integrations-page'); + ?> +

        +
      • + Gravity Forms'; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/memberpress/class-memberpress.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/memberpress/class-memberpress.php new file mode 100644 index 0000000..395a4d7 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/memberpress/class-memberpress.php @@ -0,0 +1,77 @@ +options['implicit']) { + if (has_action('mepr_checkout_before_submit')) { + add_action('mepr_checkout_before_submit', [ $this, 'output_checkbox' ]); + } else { + add_action('mepr-checkout-before-submit', [ $this, 'output_checkbox' ]); + } + } + if (has_action('mepr_signup')) { + add_action('mepr_signup', [ $this, 'subscribe_from_memberpress' ], 5); + } else { + add_action('mepr-signup', [ $this, 'subscribe_from_memberpress' ], 5); + } + } + + + + /** + * Subscribe from MemberPress sign-up forms. + * + * @param MeprTransaction $txn + * @return bool + */ + public function subscribe_from_memberpress($txn) + { + + // Is this integration triggered? (checkbox checked or implicit) + if (! $this->triggered()) { + return false; + } + + $user = get_userdata($txn->user_id); + + $data = [ + 'EMAIL' => $user->user_email, + 'FNAME' => $user->first_name, + 'LNAME' => $user->last_name, + ]; + + // subscribe using email and name + return $this->subscribe($data, $txn->id); + } + + /** + * @return bool + */ + public function is_installed() + { + return defined('MEPR_VERSION'); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/admin-before.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/admin-before.php new file mode 100644 index 0000000..0bb4808 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/admin-before.php @@ -0,0 +1,3 @@ +

        + one of your Ninja Forms forms.', 'mailchimp-for-wp'), admin_url('admin.php?page=ninja-forms')); ?> +

        diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/bootstrap.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/bootstrap.php new file mode 100644 index 0000000..b419942 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/bootstrap.php @@ -0,0 +1,17 @@ + 'List', + 'fields' => 'List Field Mapping', + ]; + + public function __construct() + { + $this->_settings['double_optin'] = [ + 'name' => 'double_optin', + 'type' => 'select', + 'label' => 'Use double opt-in?', + 'width' => 'full', + 'group' => 'primary', + 'value' => 1, + 'options' => [ + [ + 'value' => 1, + 'label' => 'Yes', + ], + [ + 'value' => 0, + 'label' => 'No', + ], + ], + ]; + $this->_settings['update_existing'] = [ + 'name' => 'update_existing', + 'type' => 'select', + 'label' => 'Update existing subscribers?', + 'width' => 'full', + 'group' => 'primary', + 'value' => 0, + 'options' => [ + [ + 'value' => 1, + 'label' => 'Yes', + ], + [ + 'value' => 0, + 'label' => 'No', + ], + ], + ]; + + add_action('wp_ajax_nf_' . $this->_name . '_get_lists', [$this, '_get_lists']); + add_action('init', [$this, 'translate_props']); + add_action('init', [$this, 'get_list_settings']); + } + + public function translate_props() + { + $this->_settings['double_optin']['label'] = __('Use double opt-in?', 'mailchimp-for-wp'); + $this->_settings['update_existing']['label'] = __('Update existing subscribers?', 'mailchimp-for-wp'); + + if (isset($this->_settings[ $this->get_name() . 'newsletter_list_fields' ])) { + $this->_settings[ $this->get_name() . 'newsletter_list_fields' ]['label'] = __('List Field Mapping', 'mailchimp-for-wp'); + } + } + + /* + * PUBLIC METHODS + */ + + public function save($action_settings) + { + } + + public function process($action_settings, $form_id, $data) + { + if (empty($action_settings['newsletter_list']) || empty($action_settings['EMAIL'])) { + return; + } + + // find "mc4wp_optin" type field, bail if not checked. + foreach ($data['fields'] as $field_data) { + if ($field_data['type'] === 'mc4wp_optin' && empty($field_data['value'])) { + return; + } + } + + $list_id = $action_settings['newsletter_list']; + $email_address = $action_settings['EMAIL']; + $mailchimp = new MC4WP_MailChimp(); + + $merge_fields = $mailchimp->get_list_merge_fields($list_id); + foreach ($merge_fields as $merge_field) { + if (! empty($action_settings[ $merge_field->tag ])) { + $merge_fields[ $merge_field->tag ] = $action_settings[ $merge_field->tag ]; + } + } + + $double_optin = (int) $action_settings['double_optin'] !== 0; + $update_existing = (int) $action_settings['update_existing'] === 1; + $replace_interests = isset($action_settings['replace_interests']) && (int) $action_settings['replace_interests'] === 1; + + do_action('mc4wp_integration_ninja_forms_subscribe', $email_address, $merge_fields, $list_id, $double_optin, $update_existing, $replace_interests, $form_id); + } + + public function ajax_get_lists_handler() + { + check_ajax_referer('ninja_forms_builder_nonce', 'security'); + $lists = $this->get_lists(); + array_unshift($return, [ 'value' => 0, 'label' => '-', 'fields' => [], 'groups' => [] ]); + echo wp_json_encode([ 'lists' => $return ]); + wp_die(); + } + + private function get_lists() + { + $mailchimp = new MC4WP_MailChimp(); + + /** @var array $lists */ + $lists = $mailchimp->get_lists(); + $return = []; + + foreach ($lists as $list) { + $list_fields = []; + + foreach ($mailchimp->get_list_merge_fields($list->id) as $merge_field) { + $list_fields[] = [ + 'value' => $merge_field->tag, + 'label' => $merge_field->name, + ]; + } + + // TODO: Add support for groups once base class supports this. + $return[] = [ + 'value' => $list->id, + 'label' => $list->name, + 'fields' => $list_fields, + ]; + } + + return $return; + } + + public function get_list_settings() + { + $label_defaults = [ + 'list' => 'List', + 'fields' => 'List Field Mapping', + ]; + $labels = array_merge($label_defaults, $this->_setting_labels); + $prefix = $this->get_name(); + $lists = $this->get_lists(); + + $this->_settings[ $prefix . 'newsletter_list' ] = [ + 'name' => 'newsletter_list', + 'type' => 'select', + 'label' => $labels[ 'list' ] . ' ', + 'width' => 'full', + 'group' => 'primary', + 'value' => '0', + 'options' => [], + ]; + + if (empty($lists)) { + return; + } + + $fields = []; + foreach ($lists as $list) { + $this->_settings[ $prefix . 'newsletter_list' ][ 'options' ][] = $list; + + //Check to see if list has fields array set. + if (isset($list[ 'fields' ])) { + foreach ($list[ 'fields' ] as $field) { + $name = $list[ 'value' ] . '_' . $field[ 'value' ]; + $fields[] = [ + 'name' => $name, + 'type' => 'textbox', + 'label' => $field[ 'label' ], + 'width' => 'full', + 'use_merge_tags' => [ + 'exclude' => [ + 'user', 'post', 'system', 'querystrings', + ], + ], + ]; + } + } + } + + $this->_settings[ $prefix . 'newsletter_list_fields' ] = [ + 'name' => 'newsletter_list_fields', + 'label' => 'List Field Mapping', + 'type' => 'fieldset', + 'group' => 'primary', + 'settings' => [], + ]; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/class-field.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/class-field.php new file mode 100644 index 0000000..ec8fcd2 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/class-field.php @@ -0,0 +1,96 @@ +_settings['label_pos']['value'] = 'right'; + + add_filter('ninja_forms_custom_columns', [ $this, 'custom_columns' ], 10, 2); + add_action('init', [$this, 'translate_nicename']); + } + + public function translate_nicename() + { + $this->_nicename = __('Mailchimp opt-in', 'mailchimp-for-wp'); + } + + /** + * Admin Form Element + * Display the checkbox on the edit submissions area. + * @since 3.0 + * + * @param $id Field ID. + * @param $value Field value. + * @return string HTML used for display of checkbox. + */ + public function admin_form_element($id, $value) + { + // If the checkboxes value is one... + if (1 === (int) $value) { + // ...this variable to checked. + $checked = 'checked'; + } else { + // ...else leave the variable empty. + $checked = ''; + } + + // Return HTML to be output to the submission edit page. + return ""; + } + + /** + * Custom Columns + * Creates what is displayed in the columns on the submissions page. + * @since 3.0 + * + * @param string $value checkbox value + * @param MC4WP_Ninja_Forms_Field $field field model. + * @return $value string|void + */ + public function custom_columns($value, $field) + { + // If the field type is equal to checkbox... + if ('mc4wp_optin' === $field->get_setting('type')) { + // Backwards compatibility check for the new checked value setting. + if (null === $field->get_setting('checked_value') && 1 === (int) $value) { + return __('Checked', 'ninja-forms'); + } elseif (null === $field->get_setting('unchecked_value') && 0 === (int) $value) { + return __('Unchecked', 'ninja-forms'); + } + + // If the field value is set to 1.... + if (1 === (int) $value) { + // Set the value to the checked value setting. + $value = $field->get_setting('checked_value'); + } else { + // Else set the value to the unchecked value setting. + $value = $field->get_setting('unchecked_value'); + } + } + return $value; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/class-ninja-forms.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/class-ninja-forms.php new file mode 100644 index 0000000..28ab027 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/ninja-forms/class-ninja-forms.php @@ -0,0 +1,74 @@ +options; + $this->options['double_optin'] = $double_optin; + $this->options['update_existing'] = $update_existing; + $this->options['replace_interests'] = $replace_interests; + $this->options['lists'] = [ $list_id ]; + + $data = $merge_fields; + $data['EMAIL'] = $email_address; + + $this->subscribe($data, $form_id); + + // revert to original options + $this->options = $orig_options; + } + + /** + * @return bool + */ + public function is_installed() + { + return class_exists('Ninja_Forms'); + } + + /** + * @since 3.0 + * @return array + */ + public function get_ui_elements() + { + return []; + } + + /** + * @param int $form_id + * @return string + */ + public function get_object_link($form_id) + { + return 'Ninja Forms'; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/admin-after.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/admin-after.php new file mode 100644 index 0000000..96fc7f1 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/admin-after.php @@ -0,0 +1,148 @@ + esc_html__('Light', 'mailchimp-for-wp'), + 'dark' => esc_html__('Dark', 'mailchimp-for-wp'), +]; +$type_options = [ + 'frictionless' => esc_html__('Frictionless', 'mailchimp-for-wp'), + 'pow' => esc_html__('Proof of Work', 'mailchimp-for-wp'), + 'image' => esc_html__('Image Captcha', 'mailchimp-for-wp'), +]; + +?> + + +

        + +

        + print_captcha_element(true, true); +?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + +

        + ', + '' + ); + ?> +

        +
        + +
        + +
        + +
        +   + +

        +
        + + + + diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/admin-before.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/admin-before.php new file mode 100644 index 0000000..4a2e65e --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/admin-before.php @@ -0,0 +1,11 @@ +', + '' +); diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/bootstrap.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/bootstrap.php new file mode 100644 index 0000000..d1c3c49 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/bootstrap.php @@ -0,0 +1,5 @@ +set_hooks(); diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/class-procaptcha-integration.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/class-procaptcha-integration.php new file mode 100644 index 0000000..76b43ae --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/class-procaptcha-integration.php @@ -0,0 +1,63 @@ + '0', + 'css' => '0', + 'site_key' => '', + 'secret_key' => '', + 'theme' => 'light', + 'type' => 'frictionless', + 'display_for_authorized' => '0', + ]; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/class-procaptcha.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/class-procaptcha.php new file mode 100644 index 0000000..c484f7e --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/prosopo-procaptcha/class-procaptcha.php @@ -0,0 +1,382 @@ +is_in_use = false; + $this->is_enabled = false; + $this->is_displayed_for_authorized = false; + $this->site_key = ''; + $this->secret_key = ''; + $this->theme = ''; + $this->type = ''; + + $this->read_settings(); + } + + /** + * @return void + */ + protected function read_settings() + { + $integrations = get_option('mc4wp_integrations', []); + if ( + false === is_array($integrations) || + false === key_exists('prosopo-procaptcha', $integrations) || + false === is_array($integrations['prosopo-procaptcha']) + ) { + return; + } + + $settings = $integrations['prosopo-procaptcha']; + + $this->is_enabled = true === key_exists('enabled', $settings) && + '1' === $settings['enabled']; + $this->is_displayed_for_authorized = true === key_exists('display_for_authorized', $settings) && + '1' === $settings['display_for_authorized']; + $this->site_key = true === key_exists('site_key', $settings) && + true === is_string($settings['site_key']) ? + $settings['site_key'] : + ''; + $this->secret_key = true === key_exists('secret_key', $settings) && + true === is_string($settings['secret_key']) ? + $settings['secret_key'] : + ''; + $this->theme = true === key_exists('theme', $settings) && + true === is_string($settings['theme']) ? + $settings['theme'] : + ''; + $this->type = true === key_exists('type', $settings) && + true === is_string($settings['type']) ? + $settings['type'] : + ''; + } + + /** + * @return MC4WP_Procaptcha + */ + public static function get_instance() + { + if (null === self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * @return void + */ + protected function print_captcha_js() + { + $attributes = [ + 'siteKey' => $this->site_key, + 'theme' => $this->theme, + 'captchaType' => $this->type, + ]; + ?> + + 'POST', + // limit waiting time to 20 seconds. + 'timeout' => 20, + 'headers' => [ + 'Content-Type' => 'application/json', + ], + 'body' => (string) wp_json_encode( + [ + 'secret' => $this->secret_key, + 'token' => $token, + ] + ), + ] + ); + + // Check if request failed, either locally or remotely + if (true === is_wp_error($response) || wp_remote_retrieve_response_code($response) >= 400) { + /** @var MC4WP_Debug_Log */ + $logger = mc4wp('log'); + $logger->error(sprintf('ProCaptcha request error: %d %s - %s', wp_remote_retrieve_response_code($response), wp_remote_retrieve_response_message($response), wp_remote_retrieve_body($response))); + return false; + } + + $body = wp_remote_retrieve_body($response); + $body = json_decode($body, true); + $is_verified = is_array($body) && isset($body['verified']) && $body['verified']; + + return true === $is_verified; + } + + public function maybe_add_type_module_attribute(string $tag, string $handle, string $src): string + { + if ( + 'prosopo-procaptcha' !== $handle || + // make sure we don't make it twice if other Procaptcha integrations are present. + false !== strpos('type="module"', $tag) + ) { + return $tag; + } + + // for old WP versions. + $tag = str_replace(' type="text/javascript"', '', $tag); + + return str_replace(' src=', ' type="module" src=', $tag); + } + + /** + * @return bool + */ + public function is_enabled() + { + return $this->is_enabled; + } + + /** + * @param bool $is_without_validation_element + * @param bool $is_forced_render E.g. if it's a preview. + * + * @return string + */ + public function print_captcha_element($is_without_validation_element = false, $is_forced_render = false) + { + if ( + false === $this->is_displayed_for_authorized && + true === is_user_logged_in() && + false === $is_forced_render + ) { + return ''; + } + + $this->is_in_use = true; + + $html = ''; + $html .= '
        '; + + // The element is optional, e.g. should be missing on the settings page. + if (false === $is_without_validation_element) { + $html .= ''; + } + + $html .= '
        '; + + return $html; + } + + /** + * @return void + */ + public function maybe_enqueue_captcha_js() + { + if (false === $this->is_in_use) { + return; + } + + // do not use wp_enqueue_module() because it doesn't work on the login screens. + wp_enqueue_script( + 'prosopo-procaptcha', + self::SCRIPT_URL, + [], + null, + [ + 'in_footer' => true, + 'strategy' => 'defer', + ] + ); + + $this->print_captcha_js(); + } + + /** + * @param array $messages + * @return array + */ + public function register_error_message(array $messages) + { + $messages['procaptcha_required'] = 'Please verify that you are human.'; + + return $messages; + } + + /** + * @param string[] $error_keys + * @param MC4WP_Form $form + * + * @return string[] + */ + public function validate_form($error_keys, $form) + { + if ( + false === strpos($form->content, $this->get_field_stub()) || + (false === $this->is_displayed_for_authorized && true === is_user_logged_in()) || + true === $this->is_human_made_request() + ) { + return $error_keys; + } + + $error_keys[] = 'procaptcha_required'; + + return $error_keys; + } + + /** + * @param string $html + * @return string + */ + public function inject_captcha_element($html) + { + $stub = $this->get_field_stub(); + + if (false === strpos($html, $stub)) { + return $html; + } + + $captcha_element = $this->print_captcha_element(); + + return str_replace($stub, $captcha_element, $html); + } + + /** + * @return string + */ + protected function get_field_stub() + { + return ''; + } + + public function set_hooks(): void + { + if (false === $this->is_enabled) { + return; + } + + add_filter('mc4wp_form_messages', [$this, 'register_error_message']); + add_action('mc4wp_form_content', [$this, 'inject_captcha_element']); + add_filter('mc4wp_form_errors', [$this, 'validate_form'], 10, 2); + + add_filter('script_loader_tag', [$this, 'maybe_add_type_module_attribute'], 10, 3); + + $hook = true === is_admin() ? + 'admin_print_footer_scripts' : + 'wp_print_footer_scripts'; + + // priority must be less than 10, to make sure the wp_enqueue_script still has effect. + add_action($hook, [$this, 'maybe_enqueue_captcha_js'], 9); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/woocommerce/admin-after.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/woocommerce/admin-after.php new file mode 100644 index 0000000..7bfbfce --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/woocommerce/admin-after.php @@ -0,0 +1,52 @@ + __('After email field', 'mailchimp-for-wp'), + 'checkout_billing' => __('After billing details', 'mailchimp-for-wp'), + 'checkout_shipping' => __('After shipping details', 'mailchimp-for-wp'), + 'checkout_after_customer_details' => __('After customer details', 'mailchimp-for-wp'), + 'review_order_before_submit' => __('Before submit button', 'mailchimp-for-wp'), + 'after_order_notes' => __('After order notes', 'mailchimp-for-wp'), +]; + +if (defined('CFW_NAME')) { + $position_options['cfw_checkout_before_payment_method_tab_nav'] = __('Checkout for WooCommerce: Before complete order button', 'mailchimp-for-wp'); + $position_options['cfw_after_customer_info_account_details'] = __('Checkout for WooCommerce: After account info', 'mailchimp-for-wp'); + $position_options['cfw_checkout_after_customer_info_address'] = __('Checkout for WooCommerce: After customer info', 'mailchimp-for-wp'); +} + +/** @var MC4WP_Integration $integration */ + +$body_config = [ + 'element' => 'mc4wp_integrations[' . $integration->slug . '][enabled]', + 'value' => '1', + 'hide' => false, +]; + +$config = [ + 'element' => 'mc4wp_integrations[' . $integration->slug . '][implicit]', + 'value' => '0', +]; + +?> + + + + + + + +
        + + + +

        +
        diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/woocommerce/class-woocommerce.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/woocommerce/class-woocommerce.php new file mode 100644 index 0000000..ceb8213 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/woocommerce/class-woocommerce.php @@ -0,0 +1,254 @@ +options['implicit']) { + if ($this->options['position'] !== 'after_email_field') { + // create hook name based on position setting + $hook = $this->options['position']; + + // prefix hook with woocommerce_ if not already properly prefixed + // note: we check for cfw_ prefix here to not override the Checkout for WC hook names + if (strpos($hook, 'cfw_') !== 0 && strpos($hook, 'woocommerce_') !== 0) { + $hook = "woocommerce_{$hook}"; + } + + add_action($hook, [$this, 'output_checkbox'], 20); + } else { + add_filter('woocommerce_form_field_email', [$this, 'add_checkbox_after_email_field'], 10, 4); + } + + add_action('woocommerce_checkout_update_order_meta', [$this, 'save_woocommerce_checkout_checkbox_value']); + + // specific hooks for klarna + add_filter('kco_create_order', [$this, 'add_klarna_field']); + add_filter('klarna_after_kco_confirmation', [$this, 'subscribe_from_klarna_checkout'], 10, 2); + + // hooks for when using WooCommerce Checkout Block + add_action('woocommerce_init', [$this, 'add_checkout_block_field']); + } + + add_action('woocommerce_checkout_order_processed', [$this, 'subscribe_from_woocommerce_checkout']); + add_action('woocommerce_store_api_checkout_order_processed', [$this, 'subscribe_from_woocommerce_checkout']); + if ($this->options['precheck']) { + add_filter('woocommerce_get_default_value_for_mc4wp/optin', function ($value) { + return '1'; + }); + } + } + + /** + * Add default value for "position" setting + * + * @return array + */ + protected function get_default_options() + { + $defaults = parent::get_default_options(); + $defaults['position'] = 'billing'; + return $defaults; + } + + public function add_checkout_block_field() + { + // for compatibility with older WooCommerce versions + // check if function exists before calling + if (!function_exists('woocommerce_register_additional_checkout_field')) { + return; + } + + woocommerce_register_additional_checkout_field( + [ + 'id' => 'mc4wp/optin', + 'location' => 'order', + 'type' => 'checkbox', + 'label' => $this->get_label_text(), + 'optionalLabel' => $this->get_label_text(), + ] + ); + } + + public function add_klarna_field($create) + { + $create['options']['additional_checkbox']['text'] = $this->get_label_text(); + $create['options']['additional_checkbox']['checked'] = (bool) $this->options['precheck']; + $create['options']['additional_checkbox']['required'] = false; + return $create; + } + + public function add_checkbox_after_email_field($field, $key, $args, $value) + { + if ($key !== 'billing_email') { + return $field; + } + + return $field . PHP_EOL . $this->get_checkbox_html(); + } + + /** + * @param int $order_id + */ + public function save_woocommerce_checkout_checkbox_value($order_id) + { + $order = wc_get_order($order_id); + if (!$order) { + return; + } + + $order->update_meta_data('_mc4wp_optin', $this->checkbox_was_checked()); + $order->save(); + } + + /** + * {@inheritdoc} + * + * @param int|\WC_Order $order_id + * @return bool|mixed + */ + public function triggered($order_id = null) + { + if ($this->options['implicit']) { + return true; + } + + $order = wc_get_order($order_id); + if (!$order) { + return false; + } + + // value from default checkout form (shortcode) + $a = $order->get_meta('_mc4wp_optin'); + + // alternatively, value from Checkout Block field + $b = false; + if (class_exists(Package::class) && class_exists(CheckoutFields::class)) { + $checkout_fields = Package::container()->get(CheckoutFields::class); + + if ( + $checkout_fields + + && method_exists($checkout_fields, 'get_field_from_object') + // method was private in earlier versions of WooCommerce, so check if callable + && is_callable([$checkout_fields, 'get_field_from_object']) + ) { + $b = $checkout_fields->get_field_from_object('mc4wp/optin', $order, 'contact'); + } + } + + return $a || $b; + } + + public function subscribe_from_klarna_checkout($order_id, $klarna_order) + { + // $klarna_order is the returned object from Klarna + if (false === (bool) $klarna_order['merchant_requested']['additional_checkbox']) { + return; + } + + $order = wc_get_order($order_id); + if (!$order) { + return; + } + + // store _mc4wp_optin in order meta + $order->update_meta_data('_mc4wp_optin', true); + $order->save(); + + // continue in regular subscribe flow + $this->subscribe_from_woocommerce_checkout($order_id); + return; + } + + /** + * @param int|\WC_Order $order_id + * @return boolean + */ + public function subscribe_from_woocommerce_checkout($order_id) + { + if (!$this->triggered($order_id)) { + return false; + } + + $order = wc_get_order($order_id); + if (!$order) { + return false; + } + + if (method_exists($order, 'get_billing_email')) { + $data = [ + 'EMAIL' => $order->get_billing_email(), + 'NAME' => "{$order->get_billing_first_name()} {$order->get_billing_last_name()}", + 'FNAME' => $order->get_billing_first_name(), + 'LNAME' => $order->get_billing_last_name(), + ]; + } else { + // NOTE: for compatibility with WooCommerce < 3.0 + $data = [ + 'EMAIL' => $order->billing_email, + 'NAME' => "{$order->billing_first_name} {$order->billing_last_name}", + 'FNAME' => $order->billing_first_name, + 'LNAME' => $order->billing_last_name, + ]; + } + + // TODO: add billing address fields, maybe by finding Mailchimp field of type "address"? + + return $this->subscribe($data, $order_id); + } + + /** + * @return bool + */ + public function is_installed() + { + return class_exists('WooCommerce'); + } + + /** + * {@inheritdoc} + * + * @return string + */ + public function get_object_link($object_id) + { + return sprintf('%s', get_edit_post_link($object_id), sprintf(__('Order #%d', 'mailchimp-for-wp'), $object_id)); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/wp-comment-form/class-comment-form.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/wp-comment-form/class-comment-form.php new file mode 100644 index 0000000..d773cff --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/wp-comment-form/class-comment-form.php @@ -0,0 +1,121 @@ +options['implicit']) { + // hooks for outputting the checkbox + add_filter('comment_form_submit_field', [ $this, 'add_checkbox_before_submit_button' ], 90); + + add_action('thesis_hook_after_comment_box', [ $this, 'maybe_output_checkbox' ], 90); + add_action('comment_form', [ $this, 'maybe_output_checkbox' ], 90); + } + + // hooks for checking if we should subscribe the commenter + add_action('comment_post', [ $this, 'subscribe_from_comment' ], 40, 2); + } + + /** + * This adds the checkbox just before the submit button and sets a flag to prevent it from outputting twice + * + * @param $submit_button_html + * + * @return string + */ + public function add_checkbox_before_submit_button($submit_button_html) + { + $this->added_through_filter = true; + return $this->get_checkbox_html() . $submit_button_html; + } + + /** + * Output fallback + * Will output the checkbox if comment_form() function does not use `comment_form_submit_field` filter yet. + */ + public function maybe_output_checkbox() + { + if (! $this->added_through_filter) { + $this->output_checkbox(); + } + } + + /** + * Grabs data from WP Comment Form + * + * @param int $comment_id + * @param string $comment_approved + * + * @return bool|string + */ + public function subscribe_from_comment($comment_id, $comment_approved = '') + { + + // was sign-up checkbox checked? + if (! $this->triggered()) { + return false; + } + + // is this a spam comment? + if ($comment_approved === 'spam') { + return false; + } + + $comment = get_comment($comment_id); + + $data = [ + 'EMAIL' => $comment->comment_author_email, + 'NAME' => $comment->comment_author, + 'OPTIN_IP' => $comment->comment_author_IP, + ]; + + return $this->subscribe($data, $comment_id); + } + + /** + * @return bool + */ + public function is_installed() + { + return true; + } + + /** + * {@inheritdoc } + */ + public function get_object_link($object_id) + { + $comment = get_comment($object_id); + + if (! $comment) { + return ''; + } + + return sprintf('Comment #%d', get_edit_comment_link($object_id), $object_id); + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/wp-registration-form/class-registration-form.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/wp-registration-form/class-registration-form.php new file mode 100644 index 0000000..862188e --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/wp-registration-form/class-registration-form.php @@ -0,0 +1,96 @@ +options['implicit']) { + add_action('login_head', [ $this, 'print_css_reset' ]); + add_action('um_after_register_fields', [ $this, 'maybe_output_checkbox' ], 20); + add_action('register_form', [ $this, 'maybe_output_checkbox' ], 20); + add_action('woocommerce_register_form', [ $this, 'maybe_output_checkbox' ], 20); + } + + add_action('um_user_register', [ $this, 'subscribe_from_registration' ], 90, 1); + add_action('user_register', [ $this, 'subscribe_from_registration' ], 90, 1); + + if (defined('um_plugin') && class_exists('UM')) { + $this->name = 'UltimateMember'; + $this->description = 'Subscribes people from your UltimateMember registration form.'; + } + } + + /** + * Output checkbox, once. + */ + public function maybe_output_checkbox() + { + if (! $this->shown) { + $this->output_checkbox(); + $this->shown = true; + } + } + + /** + * Subscribes from WP Registration Form + * + * @param int $user_id + * + * @return bool|string + */ + public function subscribe_from_registration($user_id) + { + + // was sign-up checkbox checked? + if (! $this->triggered()) { + return false; + } + + // gather emailadress from user who WordPress registered + $user = get_userdata($user_id); + + // was a user found with the given ID? + if (! $user instanceof WP_User) { + return false; + } + + $data = $this->user_merge_vars($user); + + return $this->subscribe($data, $user_id); + } + /* End registration form functions */ + + + /** + * @return bool + */ + public function is_installed() + { + return true; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/admin-before.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/admin-before.php new file mode 100644 index 0000000..cb40aba --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/admin-before.php @@ -0,0 +1,3 @@ +

        + your WPForms forms.', 'mailchimp-for-wp'), admin_url('admin.php?page=wpforms-overview')); ?> +

        diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/bootstrap.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/bootstrap.php new file mode 100644 index 0000000..1ed7cf6 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/bootstrap.php @@ -0,0 +1,9 @@ +name = 'Mailchimp'; + $this->type = 'mailchimp'; + $this->icon = 'fa-envelope-o'; + $this->order = 21; + $this->defaults = [ + [ + 'label' => __('Sign-up to our newsletter?', 'mailchimp-for-wp'), + 'value' => '1', + 'default' => '', + ], + ]; + } + + /** + * Field options panel inside the builder. + * + * @since 1.0.0 + * @param array $field + */ + public function field_options($field) + { + + //--------------------------------------------------------------------// + // Basic field options + //--------------------------------------------------------------------// + + // Options open markup + $this->field_option('basic-options', $field, [ 'markup' => 'open' ]); + + // Mailchimp list + $this->field_option_mailchimp_list($field); + + // Choices + $this->field_option_choices($field); + + // Description + $this->field_option('description', $field); + + // Required toggle + $this->field_option('required', $field); + + // Options close markup + $this->field_option('basic-options', $field, [ 'markup' => 'close' ]); + + //--------------------------------------------------------------------// + // Advanced field options + //--------------------------------------------------------------------// + + // Options open markup + $this->field_option('advanced-options', $field, [ 'markup' => 'open' ]); + + // Custom CSS classes + $this->field_option('css', $field); + + // Options close markup + $this->field_option('advanced-options', $field, [ 'markup' => 'close' ]); + } + + private function field_option_mailchimp_list($field) + { + $mailchimp = new MC4WP_MailChimp(); + + // Field option label + $tooltip = __('Select the Mailchimp list to subscribe to.', 'mailchimp-for-wp'); + $option_label = $this->field_element( + 'label', + $field, + [ + 'slug' => 'mailchimp-list', + 'value' => __('Mailchimp list', 'mailchimp-for-wp'), + 'tooltip' => $tooltip, + ], + false + ); + + $option_select = sprintf(''; + + // Field option row (markup) including label and input. + $output = $this->field_element( + 'row', + $field, + [ + 'slug' => 'mailchimp-list', + 'content' => $option_label . $option_select, + ] + ); + } + + private function field_option_choices($field) + { + $tooltip = __('Set your sign-up label text and whether it should be pre-checked.', 'mailchimp-for-wp'); + $values = ! empty($field['choices']) ? $field['choices'] : $this->defaults; + $class = ! empty($field['show_values']) && (int) $field['show_values'] === 1 ? 'show-values' : ''; + $class .= ! empty($dynamic) ? ' wpforms-hidden' : ''; + + // Field option label + $option_label = $this->field_element( + 'label', + $field, + [ + 'slug' => 'mailchimp-checkbox', + 'value' => __('Sign-up checkbox', 'mailchimp-for-wp'), + 'tooltip' => $tooltip, + ], + false + ); + + // Field option choices inputs + $option_choices = sprintf('
          ', $class, $field['id'], $this->type); + foreach ($values as $key => $value) { + $default = ! empty($value['default']) ? $value['default'] : ''; + $option_choices .= sprintf('
        • ', $key); + $option_choices .= sprintf('', $field['id'], $key, checked('1', $default, false)); + $option_choices .= sprintf('', $field['id'], $key, esc_attr($value['label'])); + $option_choices .= sprintf('', $field['id'], $key, esc_attr($value['value'])); + $option_choices .= '
        • '; + } + $option_choices .= '
        '; + + // Field option row (markup) including label and input. + $output = $this->field_element( + 'row', + $field, + [ + 'slug' => 'choices', + 'content' => $option_label . $option_choices, + ] + ); + } + + /** + * Field preview inside the builder. + * + * @since 1.0.0 + * @param array $field + */ + public function field_preview($field) + { + $values = ! empty($field['choices']) ? $field['choices'] : $this->defaults; + + // Field checkbox elements + echo '
          '; + + // Notify if currently empty + if (empty($values)) { + $values = [ 'label' => __('(empty)', 'wpforms') ]; + } + + // Individual checkbox options + foreach ($values as $key => $value) { + $default = isset($value['default']) ? $value['default'] : ''; + $selected = checked('1', $default, false); + + printf('
        • %s
        • ', $selected, $value['label']); + } + + echo '
        '; + + // Dynamic population is enabled and contains more than 20 items + if (isset($total) && $total > 20) { + echo '
        '; + printf(__('Showing the first 20 choices.
        All %d choices will be displayed when viewing the form.', 'wpforms'), absint($total)); + echo '
        '; + } + + // Description + $this->field_preview_option('description', $field); + } + + /** + * Field display on the form front-end. + * + * @since 1.0.0 + * @param array $field + * @param array $form_data + */ + public function field_display($field, $field_atts, $form_data) + { + // Setup some defaults because WPForms broke their integration in v1.8.1.1 + $field_atts = array_merge([ + 'input_class' => [], + 'input_id' => [], + ], $field_atts); + + // Setup and sanitize the necessary data + $field_required = ! empty($field['required']) ? ' required' : ''; + $field_class = implode(' ', array_map('sanitize_html_class', (array) $field_atts['input_class'])); + $field_id = implode(' ', array_map('sanitize_html_class', (array) $field_atts['input_id'])); + $form_id = $form_data['id']; + $choices = (array) $field['choices']; + + // List + printf('
          ', $field_id, $field_class); + + foreach ($choices as $key => $choice) { + $selected = isset($choice['default']) ? '1' : '0'; + $depth = isset($choice['depth']) ? absint($choice['depth']) : 1; + + printf('
        • ', $key, $depth); + + // Checkbox elements + printf( + '', + $form_id, + $field['id'], + $key, + $field['id'], + esc_attr($choice['value']), + checked('1', $selected, false), + $field_required + ); + + printf('', $form_id, $field['id'], $key, wp_kses_post($choice['label'])); + + echo '
        • '; + } + + echo '
        '; + } + + /** + * Formats and sanitizes field. + * + * @since 1.0.2 + * @param int $field_id + * @param array $field_submit + * @param array $form_data + */ + public function format($field_id, $field_submit, $form_data) + { + $field = $form_data['fields'][ $field_id ]; + $choice = array_pop($field['choices']); + $name = sanitize_text_field($choice['label']); + + $data = [ + 'name' => $name, + 'value' => empty($field_submit) ? __('No', 'mailchimp-for-wp') : __('Yes', 'mailchimp-for-wp'), + 'value_raw' => $field_submit, + 'id' => absint($field_id), + 'type' => $this->type, + ]; + + wpforms()->process->fields[ $field_id ] = $data; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/class-wpforms.php b/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/class-wpforms.php new file mode 100644 index 0000000..74d4045 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/integrations/wpforms/class-wpforms.php @@ -0,0 +1,81 @@ + $field) { + if ($field['type'] === 'mailchimp' && (int) $field['value_raw'] === 1) { + return $this->subscribe_from_wpforms($field_id, $fields, $form_data); + } + } + } + + public function subscribe_from_wpforms($checkbox_field_id, $fields, $form_data) + { + foreach ($fields as $field) { + if ($field['type'] === 'email') { + $email_address = $field['value']; + } + } + + $mailchimp_list_id = $form_data['fields'][ $checkbox_field_id ]['mailchimp_list']; + $this->options['lists'] = [ $mailchimp_list_id ]; + + if (! empty($email_address)) { + return $this->subscribe([ 'EMAIL' => $email_address ], $form_data['id']); + } + } + + /** + * @param int $form_id + * @return string + */ + public function get_object_link($form_id) + { + return 'WPForms'; + } +} diff --git a/html/wp-content/plugins/mailchimp-for-wp/languages/index.php b/html/wp-content/plugins/mailchimp-for-wp/languages/index.php new file mode 100644 index 0000000..6f9447a --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/languages/index.php @@ -0,0 +1,7 @@ +\n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"POT-Creation-Date: 2024-04-25T16:06:39+00:00\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"X-Generator: WP-CLI 2.10.0\n" +"X-Domain: mailchimp-for-wp\n" + +#. Plugin Name of the plugin +#: mailchimp-for-wp.php +msgid "MC4WP: Mailchimp for WordPress" +msgstr "" + +#. Plugin URI of the plugin +#: mailchimp-for-wp.php +msgid "https://www.mc4wp.com/#utm_source=wp-plugin&utm_medium=mailchimp-for-wp&utm_campaign=plugins-page" +msgstr "" + +#. Description of the plugin +#: mailchimp-for-wp.php +msgid "Mailchimp for WordPress by ibericode. Adds various highly effective sign-up methods to your site." +msgstr "" + +#. Author of the plugin +#: mailchimp-for-wp.php +msgid "ibericode" +msgstr "" + +#. Author URI of the plugin +#: mailchimp-for-wp.php +msgid "https://www.ibericode.com/" +msgstr "" + +#: config/default-form-content.php:3 +#: includes/class-mailchimp.php:250 +#: includes/forms/class-admin.php:82 +msgid "Email address" +msgstr "" + +#: config/default-form-content.php:4 +msgid "Your email address" +msgstr "" + +#: config/default-form-content.php:5 +msgid "Sign up" +msgstr "" + +#: config/default-form-messages.php:5 +msgid "Thank you, your sign-up request was successful! Please check your email inbox to confirm." +msgstr "" + +#: config/default-form-messages.php:9 +msgid "Thank you, your records have been updated!" +msgstr "" + +#: config/default-form-messages.php:13 +msgid "You were successfully unsubscribed." +msgstr "" + +#: config/default-form-messages.php:17 +msgid "Given email address is not subscribed." +msgstr "" + +#: config/default-form-messages.php:21 +msgid "Oops. Something went wrong. Please try again later." +msgstr "" + +#: config/default-form-messages.php:25 +msgid "Please provide a valid email address." +msgstr "" + +#: config/default-form-messages.php:29 +msgid "Given email address is already subscribed, thank you!" +msgstr "" + +#: config/default-form-messages.php:33 +msgid "Please fill in the required fields." +msgstr "" + +#: config/default-form-messages.php:37 +msgid "Please select at least one list." +msgstr "" + +#: includes/admin/class-admin-texts.php:66 +#: includes/forms/views/edit-form.php:6 +msgid "Settings" +msgstr "" + +#: includes/admin/class-admin-texts.php:84 +msgid "Documentation" +msgstr "" + +#: includes/admin/class-admin.php:209 +msgid "Success! The cached configuration for your Mailchimp lists has been renewed." +msgstr "" + +#: includes/admin/class-admin.php:289 +msgid "The given value does not look like a valid Mailchimp API key." +msgstr "" + +#: includes/admin/class-admin.php:290 +msgid "This is a premium feature. Please upgrade to Mailchimp for WordPress Premium to be able to use it." +msgstr "" + +#: includes/admin/class-admin.php:291 +#: includes/forms/views/parts/add-fields-help.php:58 +#: includes/views/parts/lists-overview.php:10 +msgid "Renew Mailchimp lists" +msgstr "" + +#: includes/admin/class-admin.php:292 +msgid "Fetching Mailchimp lists" +msgstr "" + +#: includes/admin/class-admin.php:293 +msgid "Done! Mailchimp lists renewed." +msgstr "" + +#: includes/admin/class-admin.php:294 +msgid "Failed to renew your lists. An error occured." +msgstr "" + +#: includes/admin/class-admin.php:320 +msgid "Mailchimp API Settings" +msgstr "" + +#: includes/admin/class-admin.php:327 +#: includes/views/other-settings.php:14 +#: includes/views/other-settings.php:24 +msgid "Other Settings" +msgstr "" + +#: includes/admin/class-admin.php:328 +msgid "Other" +msgstr "" + +#: includes/admin/class-admin.php:406 +msgid "Error connecting to Mailchimp:" +msgstr "" + +#: includes/admin/class-admin.php:409 +msgid "Looks like your server is blocked by Mailchimp's firewall. Please contact Mailchimp support and include the following reference number: %s" +msgstr "" + +#: includes/admin/class-admin.php:412 +msgid "Here's some info on solving common connectivity issues." +msgstr "" + +#: includes/admin/class-admin.php:417 +msgid "Mailchimp returned the following error:" +msgstr "" + +#: includes/admin/class-admin.php:456 +msgid "Log successfully emptied." +msgstr "" + +#: includes/admin/class-admin.php:486 +msgid "To get started with Mailchimp for WordPress, please enter your Mailchimp API key on the settings page of the plugin." +msgstr "" + +#: includes/admin/class-ads.php:37 +#: includes/admin/class-ads.php:38 +msgid "Add-ons" +msgstr "" + +#: includes/admin/class-ads.php:54 +msgid "Want to customize the style of your form? Try our Styles Builder & edit the look of your forms with just a few clicks." +msgstr "" + +#: includes/admin/class-ads.php:69 +msgid "Be notified whenever someone subscribes? Mailchimp for WordPress Premium allows you to set up email notifications for your forms." +msgstr "" + +#: includes/admin/class-ads.php:71 +msgid "Increased conversions? Mailchimp for WordPress Premium submits forms without reloading the entire page, resulting in a much better experience for your visitors." +msgstr "" + +#: includes/admin/class-ads.php:85 +msgid "Upgrade to Premium" +msgstr "" + +#: includes/admin/class-ads.php:97 +msgid "Do you want translated forms for all of your languages? Try Mailchimp for WordPress Premium, which does just that plus more." +msgstr "" + +#: includes/admin/class-ads.php:102 +msgid "Do you want to create more than one form? Our Premium add-on does just that! Have a look at all Premium benefits." +msgstr "" + +#: includes/admin/class-ads.php:107 +msgid "Are you enjoying this plugin? The Premium add-on unlocks several powerful features. Find out about all benefits now." +msgstr "" + +#: includes/admin/class-ads.php:145 +msgid "Do you want to track all WooCommerce orders in Mailchimp so you can send emails based on the purchase activity of your subscribers?" +msgstr "" + +#: includes/admin/class-ads.php:148 +msgid "Upgrade to Mailchimp for WordPress Premium or read more about Mailchimp's E-Commerce features." +msgstr "" + +#: includes/admin/class-review-notice.php:69 +msgid "You've been using Mailchimp for WordPress for some time now; we hope you love it!" +msgstr "" + +#: includes/admin/class-review-notice.php:70 +msgid "If you do, please leave us a 5★ rating on WordPress.org. It would be of great help to us." +msgstr "" + +#: includes/admin/class-review-notice.php:72 +msgid "Dismiss this notice." +msgstr "" + +#: includes/admin/migrations/3.0.0-form-1-post-type.php:35 +msgid "Default sign-up form" +msgstr "" + +#: includes/class-dynamic-content-tags.php:27 +msgid "Data from a cookie." +msgstr "" + +#: includes/class-dynamic-content-tags.php:33 +msgid "The email address of the current visitor (if known)." +msgstr "" + +#: includes/class-dynamic-content-tags.php:38 +msgid "The URL of the page." +msgstr "" + +#: includes/class-dynamic-content-tags.php:43 +msgid "The path of the page." +msgstr "" + +#: includes/class-dynamic-content-tags.php:48 +msgid "The current date. Example: %s." +msgstr "" + +#: includes/class-dynamic-content-tags.php:53 +msgid "The current time. Example: %s." +msgstr "" + +#: includes/class-dynamic-content-tags.php:58 +msgid "The site's language. Example: %s." +msgstr "" + +#: includes/class-dynamic-content-tags.php:63 +msgid "The visitor's IP address. Example: %s." +msgstr "" + +#: includes/class-dynamic-content-tags.php:68 +msgid "The property of the currently logged-in user." +msgstr "" + +#: includes/class-dynamic-content-tags.php:74 +msgid "Property of the current page or post." +msgstr "" + +#: includes/forms/class-admin.php:70 +msgid "Add to form" +msgstr "" + +#: includes/forms/class-admin.php:71 +msgid "I have read and agree to the terms & conditions" +msgstr "" + +#: includes/forms/class-admin.php:72 +msgid "Agree to terms" +msgstr "" + +#: includes/forms/class-admin.php:73 +msgid "Link to your terms & conditions page" +msgstr "" + +#: includes/forms/class-admin.php:74 +msgid "City" +msgstr "" + +#: includes/forms/class-admin.php:75 +msgid "Checkboxes" +msgstr "" + +#: includes/forms/class-admin.php:76 +msgid "Choices" +msgstr "" + +#: includes/forms/class-admin.php:77 +msgid "Choice type" +msgstr "" + +#: includes/forms/class-admin.php:78 +msgid "Choose a field to add to the form" +msgstr "" + +#: includes/forms/class-admin.php:79 +msgid "Close" +msgstr "" + +#: includes/forms/class-admin.php:80 +msgid "Country" +msgstr "" + +#: includes/forms/class-admin.php:81 +msgid "Dropdown" +msgstr "" + +#: includes/forms/class-admin.php:83 +msgid "Field type" +msgstr "" + +#: includes/forms/class-admin.php:84 +msgid "Field label" +msgstr "" + +#: includes/forms/class-admin.php:85 +msgid "Form action" +msgstr "" + +#: includes/forms/class-admin.php:86 +msgid "This field will allow your visitors to choose whether they would like to subscribe or unsubscribe" +msgstr "" + +#: includes/forms/class-admin.php:87 +msgid "Form fields" +msgstr "" + +#: includes/forms/class-admin.php:88 +msgid "This field is marked as required in Mailchimp." +msgstr "" + +#: includes/forms/class-admin.php:89 +msgid "Initial value" +msgstr "" + +#: includes/forms/class-admin.php:90 +msgid "Interest categories" +msgstr "" + +#: includes/forms/class-admin.php:91 +msgid "Is this field required?" +msgstr "" + +#: includes/forms/class-admin.php:92 +msgid "List choice" +msgstr "" + +#: includes/forms/class-admin.php:93 +msgid "This field will allow your visitors to choose a list to subscribe to." +msgstr "" + +#: includes/forms/class-admin.php:94 +msgid "List fields" +msgstr "" + +#: includes/forms/class-admin.php:95 +msgid "Min" +msgstr "" + +#: includes/forms/class-admin.php:96 +msgid "Max" +msgstr "" + +#: includes/forms/class-admin.php:97 +msgid "No available fields. Did you select a Mailchimp list in the form settings?" +msgstr "" + +#: includes/forms/class-admin.php:98 +msgid "Optional" +msgstr "" + +#: includes/forms/class-admin.php:99 +msgid "Placeholder" +msgstr "" + +#: includes/forms/class-admin.php:100 +msgid "Text to show when field has no value." +msgstr "" + +#: includes/forms/class-admin.php:101 +msgid "Preselect" +msgstr "" + +#: includes/forms/class-admin.php:102 +msgid "Remove" +msgstr "" + +#: includes/forms/class-admin.php:103 +msgid "Radio buttons" +msgstr "" + +#: includes/forms/class-admin.php:104 +msgid "Street Address" +msgstr "" + +#: includes/forms/class-admin.php:105 +msgid "State" +msgstr "" + +#: includes/forms/class-admin.php:106 +msgid "Subscribe" +msgstr "" + +#: includes/forms/class-admin.php:107 +msgid "Submit button" +msgstr "" + +#: includes/forms/class-admin.php:108 +msgid "Wrap in paragraph tags?" +msgstr "" + +#: includes/forms/class-admin.php:109 +msgid "Value" +msgstr "" + +#: includes/forms/class-admin.php:110 +msgid "Text to prefill this field with." +msgstr "" + +#: includes/forms/class-admin.php:111 +msgid "ZIP" +msgstr "" + +#: includes/forms/class-admin.php:123 +#: includes/forms/views/edit-form.php:24 +msgid "Forms" +msgstr "" + +#: includes/forms/class-admin.php:124 +#: includes/forms/views/edit-form.php:26 +msgid "Form" +msgstr "" + +#: includes/forms/class-admin.php:161 +#: includes/forms/class-admin.php:288 +msgid "Form saved." +msgstr "" + +#: includes/forms/class-admin.php:397 +msgid "Form not found." +msgstr "" + +#: includes/forms/class-admin.php:399 +msgid "Go back" +msgstr "" + +#: includes/forms/class-admin.php:462 +#: includes/forms/class-widget.php:31 +msgid "Mailchimp Sign-Up Form" +msgstr "" + +#: includes/forms/class-admin.php:466 +msgid "Select the form to show" +msgstr "" + +#: includes/forms/class-form-amp.php:33 +msgid "Submitting..." +msgstr "" + +#: includes/forms/class-form-element.php:82 +msgid "Leave this field empty if you're human:" +msgstr "" + +#: includes/forms/class-form-manager.php:144 +msgid "Resource does not exist." +msgstr "" + +#: includes/forms/class-form-tags.php:34 +msgid "Replaced with the form response (error or success messages)." +msgstr "" + +#: includes/forms/class-form-tags.php:39 +msgid "Data from the URL or a submitted form." +msgstr "" + +#: includes/forms/class-form-tags.php:45 +#: includes/integrations/class-integration-tags.php:30 +msgid "Replaced with the number of subscribers on the selected list(s)" +msgstr "" + +#: includes/forms/class-form.php:26 +msgid "There is no form with ID %d, perhaps it was deleted?" +msgstr "" + +#: includes/forms/class-widget.php:27 +msgid "Newsletter" +msgstr "" + +#: includes/forms/class-widget.php:33 +msgid "Displays your Mailchimp for WordPress sign-up form" +msgstr "" + +#: includes/forms/class-widget.php:79 +msgid "Title:" +msgstr "" + +#: includes/forms/class-widget.php:96 +msgid "You can edit your sign-up form in the Mailchimp for WordPress form settings." +msgstr "" + +#: includes/forms/views/add-form.php:10 +#: includes/forms/views/add-form.php:69 +msgid "Add new form" +msgstr "" + +#: includes/forms/views/add-form.php:26 +msgid "What is the name of this form?" +msgstr "" + +#: includes/forms/views/add-form.php:29 +msgid "Enter your form title.." +msgstr "" + +#: includes/forms/views/add-form.php:36 +msgid "To which Mailchimp lists should this form subscribe?" +msgstr "" + +#: includes/forms/views/add-form.php:61 +msgid "No lists found. Did you connect with Mailchimp?" +msgstr "" + +#: includes/forms/views/edit-form.php:4 +msgid "Fields" +msgstr "" + +#: includes/forms/views/edit-form.php:5 +msgid "Messages" +msgstr "" + +#: includes/forms/views/edit-form.php:7 +msgid "Appearance" +msgstr "" + +#: includes/forms/views/edit-form.php:22 +#: includes/integrations/views/integration-settings.php:8 +#: includes/integrations/views/integrations.php:99 +#: includes/views/general-settings.php:7 +#: includes/views/other-settings.php:12 +msgid "You are here: " +msgstr "" + +#: includes/forms/views/edit-form.php:34 +msgid "Edit Form" +msgstr "" + +#: includes/forms/views/edit-form.php:59 +msgid "Enter form title here" +msgstr "" + +#: includes/forms/views/edit-form.php:63 +msgid "Enter the title of your sign-up form" +msgstr "" + +#: includes/forms/views/edit-form.php:67 +#: includes/forms/views/tabs/form-fields.php:39 +msgid "Use the shortcode %s to display this form inside a post, page or text widget." +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:4 +#: includes/forms/views/tabs/form-fields.php:10 +msgid "Add more fields" +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:9 +msgid "To add more fields to your form, you will need to create those fields in Mailchimp first." +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:12 +msgid "Here's how:" +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:17 +msgid "Log in to your Mailchimp account." +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:22 +msgid "Add list fields to any of your selected lists." +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:23 +msgid "Clicking the following links will take you to the right screen." +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:31 +msgid "Edit list fields for" +msgstr "" + +#: includes/forms/views/parts/add-fields-help.php:42 +msgid "Click the following button to have Mailchimp for WordPress pick up on your changes." +msgstr "" + +#: includes/forms/views/parts/dynamic-content-tags.php:6 +msgid "Add dynamic form variable" +msgstr "" + +#: includes/forms/views/parts/dynamic-content-tags.php:8 +msgid "The following list of variables can be used to add some dynamic content to your form or success and error messages." +msgstr "" + +#: includes/forms/views/parts/dynamic-content-tags.php:8 +msgid "This allows you to personalise your form or response messages." +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:5 +msgid "Inherit from %s theme" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:6 +msgid "Basic" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:7 +msgid "Form Themes" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:8 +msgid "Light Theme" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:9 +msgid "Dark Theme" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:10 +msgid "Red Theme" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:11 +msgid "Green Theme" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:12 +msgid "Blue Theme" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:25 +msgid "Form Appearance" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:29 +msgid "Form Style" +msgstr "" + +#: includes/forms/views/tabs/form-appearance.php:50 +msgid "If you want to load some default CSS styles, select \"basic formatting styles\" or choose one of the color themes" +msgstr "" + +#: includes/forms/views/tabs/form-fields.php:6 +msgid "Form variables" +msgstr "" + +#: includes/forms/views/tabs/form-fields.php:13 +msgid "Form Fields" +msgstr "" + +#: includes/forms/views/tabs/form-fields.php:20 +msgid "Form code" +msgstr "" + +#: includes/forms/views/tabs/form-fields.php:22 +msgid "Enter the HTML code for your form fields.." +msgstr "" + +#: includes/forms/views/tabs/form-fields.php:26 +msgid "Form preview" +msgstr "" + +#: includes/forms/views/tabs/form-fields.php:27 +msgid "The form may look slightly different than this when shown in a post, page or widget area." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:6 +msgid "Form Messages" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:16 +msgid "Successfully subscribed" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:19 +msgid "The text that shows when an email address is successfully subscribed to the selected list(s)." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:23 +msgid "Invalid email address" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:26 +msgid "The text that shows when an invalid email address is given." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:30 +msgid "Required field missing" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:33 +msgid "The text that shows when a required field for the selected list(s) is missing." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:37 +msgid "Already subscribed" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:40 +msgid "The text that shows when the given email is already subscribed to the selected list(s)." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:44 +msgid "General error" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:47 +msgid "The text that shows when a general error occured." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:51 +msgid "Unsubscribed" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:54 +msgid "When using the unsubscribe method, this is the text that shows when the given email address is successfully unsubscribed from the selected list(s)." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:58 +msgid "Not subscribed" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:61 +msgid "When using the unsubscribe method, this is the text that shows when the given email address is not on the selected list(s)." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:65 +msgid "No list selected" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:68 +msgid "When offering a list choice, this is the text that shows when no lists were selected." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:79 +msgid "Updated" +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:82 +msgid "The text that shows when an existing subscriber is updated." +msgstr "" + +#: includes/forms/views/tabs/form-messages.php:94 +msgid "HTML tags like %s are allowed in the message fields." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:1 +msgid "Form Settings" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:5 +msgid "Mailchimp specific settings" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:15 +msgid "Lists this form subscribes to" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:20 +#: includes/integrations/views/integration-settings.php:140 +msgid "No lists found, are you connected to Mailchimp?" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:39 +msgid "Select the list(s) to which people who submit this form should be subscribed." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:47 +#: integrations/ninja-forms/class-action.php:29 +msgid "Use double opt-in?" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:51 +#: includes/forms/views/tabs/form-settings.php:66 +#: includes/forms/views/tabs/form-settings.php:87 +#: includes/forms/views/tabs/form-settings.php:135 +#: includes/integrations/views/integration-settings.php:66 +#: includes/integrations/views/integration-settings.php:90 +#: includes/integrations/views/integration-settings.php:177 +#: includes/integrations/views/integration-settings.php:210 +#: includes/integrations/views/integration-settings.php:227 +#: includes/integrations/views/integration-settings.php:250 +#: includes/integrations/views/integration-settings.php:275 +#: integrations/contact-form-7/class-contact-form-7.php:74 +#: integrations/gravity-forms/class-gravity-forms.php:112 +#: integrations/gravity-forms/class-gravity-forms.php:124 +#: integrations/wpforms/class-field.php:247 +msgid "Yes" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:54 +msgid "Are you sure you want to disable double opt-in?" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:55 +#: includes/forms/views/tabs/form-settings.php:70 +#: includes/forms/views/tabs/form-settings.php:91 +#: includes/forms/views/tabs/form-settings.php:139 +#: includes/integrations/views/integration-settings.php:67 +#: includes/integrations/views/integration-settings.php:91 +#: includes/integrations/views/integration-settings.php:178 +#: includes/integrations/views/integration-settings.php:211 +#: includes/integrations/views/integration-settings.php:231 +#: includes/integrations/views/integration-settings.php:254 +#: includes/integrations/views/integration-settings.php:279 +#: integrations/contact-form-7/class-contact-form-7.php:74 +#: integrations/gravity-forms/class-gravity-forms.php:113 +#: integrations/gravity-forms/class-gravity-forms.php:125 +#: integrations/wpforms/class-field.php:247 +msgid "No" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:57 +msgid "We strongly suggest keeping double opt-in enabled. Disabling double opt-in may affect your GDPR compliance." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:62 +#: includes/integrations/views/integration-settings.php:246 +#: integrations/ninja-forms/class-action.php:48 +msgid "Update existing subscribers?" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:72 +#: includes/integrations/views/integration-settings.php:256 +msgid "Select \"yes\" if you want to update existing subscribers with the data that is sent." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:83 +#: includes/integrations/views/integration-settings.php:271 +msgid "Replace interest groups?" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:94 +#: includes/integrations/views/integration-settings.php:282 +msgid "Select \"no\" if you want to add the selected interests to any previously selected interests when updating a subscriber." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:95 +#: includes/integrations/views/integration-settings.php:283 +msgid "What does this do?" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:101 +msgid "Subscriber tags" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:103 +msgid "Example: My tag, another tag" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:105 +msgid "The listed tags will be applied to all subscribers added or updated by this form." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:106 +msgid "Separate multiple values with a comma." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:121 +msgid "Form behaviour" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:131 +msgid "Hide form after a successful sign-up?" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:142 +msgid "Select \"yes\" to hide the form fields after a successful sign-up." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:147 +msgid "Redirect to URL after successful sign-ups" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:149 +msgid "Example: %s" +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:151 +msgid "Leave empty or enter 0 for no redirect. Otherwise, use complete (absolute) URLs, including http://." +msgstr "" + +#: includes/forms/views/tabs/form-settings.php:154 +msgid "Your \"subscribed\" message will not show when redirecting to another page, so make sure to let your visitors know they were successfully subscribed." +msgstr "" + +#: includes/integrations/class-admin.php:72 +#: includes/integrations/class-admin.php:73 +#: includes/integrations/views/integration-settings.php:10 +#: includes/integrations/views/integrations.php:101 +#: includes/integrations/views/integrations.php:109 +#: includes/integrations/views/integrations.php:123 +msgid "Integrations" +msgstr "" + +#: includes/integrations/class-integration.php:79 +msgid "Sign me up for the newsletter!" +msgstr "" + +#: includes/integrations/views/integration-settings.php:20 +msgid "%s integration" +msgstr "" + +#: includes/integrations/views/integration-settings.php:27 +msgid "The selected Mailchimp lists require non-default fields, which may prevent this integration from working." +msgstr "" + +#: includes/integrations/views/integration-settings.php:28 +msgid "Please ensure you configure the plugin to send all required fields or log into your Mailchimp account and make sure only the email & name fields are marked as required fields for the selected list(s)." +msgstr "" + +#: includes/integrations/views/integration-settings.php:64 +msgid "Enabled?" +msgstr "" + +#: includes/integrations/views/integration-settings.php:68 +msgid "Enable the %s integration? This will add a sign-up checkbox to the form." +msgstr "" + +#: includes/integrations/views/integration-settings.php:88 +msgid "Implicit?" +msgstr "" + +#: includes/integrations/views/integration-settings.php:91 +#: includes/integrations/views/integration-settings.php:178 +msgid "(recommended)" +msgstr "" + +#: includes/integrations/views/integration-settings.php:95 +msgid "Select \"yes\" if you want to subscribe people without asking them explicitly." +msgstr "" + +#: includes/integrations/views/integration-settings.php:100 +#: includes/integrations/views/integration-settings.php:185 +#: integrations/gravity-forms/class-gravity-forms.php:131 +msgid "Warning: enabling this may affect your GDPR compliance." +msgstr "" + +#: includes/integrations/views/integration-settings.php:122 +msgid "Mailchimp Lists" +msgstr "" + +#: includes/integrations/views/integration-settings.php:136 +#: integrations/gravity-forms/class-gravity-forms.php:104 +msgid "Select the list(s) to which people who check the checkbox should be subscribed." +msgstr "" + +#: includes/integrations/views/integration-settings.php:156 +msgid "Checkbox label text" +msgstr "" + +#: includes/integrations/views/integration-settings.php:159 +msgid "HTML tags like %s are allowed in the label text." +msgstr "" + +#: includes/integrations/views/integration-settings.php:175 +#: integrations/gravity-forms/class-gravity-forms.php:121 +msgid "Pre-check the checkbox?" +msgstr "" + +#: includes/integrations/views/integration-settings.php:181 +#: integrations/gravity-forms/class-gravity-forms.php:129 +msgid "Select \"yes\" if the checkbox should be pre-checked." +msgstr "" + +#: includes/integrations/views/integration-settings.php:208 +msgid "Load some default CSS?" +msgstr "" + +#: includes/integrations/views/integration-settings.php:212 +msgid "Select \"yes\" if the checkbox appears in a weird place." +msgstr "" + +#: includes/integrations/views/integration-settings.php:223 +#: integrations/gravity-forms/class-gravity-forms.php:109 +msgid "Double opt-in?" +msgstr "" + +#: includes/integrations/views/integration-settings.php:234 +#: integrations/gravity-forms/class-gravity-forms.php:116 +msgid "Select \"yes\" if you want people to confirm their email address before being subscribed (recommended)" +msgstr "" + +#: includes/integrations/views/integrations.php:20 +msgid "Configure this integration" +msgstr "" + +#: includes/integrations/views/integrations.php:36 +msgid "Active" +msgstr "" + +#: includes/integrations/views/integrations.php:38 +msgid "Inactive" +msgstr "" + +#: includes/integrations/views/integrations.php:40 +msgid "Not installed" +msgstr "" + +#: includes/integrations/views/integrations.php:60 +msgid "Name" +msgstr "" + +#: includes/integrations/views/integrations.php:61 +msgid "Description" +msgstr "" + +#: includes/integrations/views/integrations.php:62 +#: includes/views/general-settings.php:34 +msgid "Status" +msgstr "" + +#: includes/integrations/views/integrations.php:115 +msgid "The table below shows all available integrations." +msgstr "" + +#: includes/integrations/views/integrations.php:116 +msgid "Click on the name of an integration to edit all settings specific to that integration." +msgstr "" + +#: includes/integrations/views/integrations.php:126 +msgid "Greyed out integrations will become available after installing & activating the corresponding plugin." +msgstr "" + +#: includes/views/general-settings.php:18 +msgid "API Settings" +msgstr "" + +#: includes/views/general-settings.php:40 +msgid "CONNECTED" +msgstr "" + +#: includes/views/general-settings.php:44 +msgid "NOT CONNECTED" +msgstr "" + +#: includes/views/general-settings.php:53 +msgid "API Key" +msgstr "" + +#: includes/views/general-settings.php:55 +msgid "Your Mailchimp API key" +msgstr "" + +#: includes/views/general-settings.php:57 +msgid "The API key for connecting with your Mailchimp account." +msgstr "" + +#: includes/views/general-settings.php:58 +msgid "Get your API key here." +msgstr "" + +#: includes/views/general-settings.php:63 +msgid "You defined your Mailchimp API key using the MC4WP_API_KEY constant." +msgstr "" + +#: includes/views/other-settings.php:42 +msgid "Miscellaneous settings" +msgstr "" + +#: includes/views/other-settings.php:45 +msgid "Logging" +msgstr "" + +#: includes/views/other-settings.php:48 +msgid "Errors & warnings only" +msgstr "" + +#: includes/views/other-settings.php:49 +msgid "Everything" +msgstr "" + +#: includes/views/other-settings.php:52 +msgid "Determines what events should be written to the debug log (see below)." +msgstr "" + +#: includes/views/other-settings.php:71 +msgid "Debug Log" +msgstr "" + +#: includes/views/other-settings.php:71 +msgid "Filter.." +msgstr "" + +#: includes/views/other-settings.php:76 +msgid "Log file is not writable." +msgstr "" + +#: includes/views/other-settings.php:77 +msgid "Please ensure %1$s has the proper file permissions." +msgstr "" + +#: includes/views/other-settings.php:98 +msgid "Nothing here. Which means there are no errors!" +msgstr "" + +#: includes/views/other-settings.php:108 +msgid "Empty Log" +msgstr "" + +#: includes/views/other-settings.php:116 +msgid "Right now, the plugin is configured to only log errors and warnings." +msgstr "" + +#. translators: %s links to the WordPress.org translation project +#: includes/views/parts/admin-footer.php:13 +msgid "Mailchimp for WordPress is in need of translations. Is the plugin not translated in your language or do you spot errors with the current translations? Helping out is easy! Please help translate the plugin using your WordPress.org account." +msgstr "" + +#: includes/views/parts/admin-footer.php:31 +msgid "This plugin is not developed by or affiliated with Mailchimp in any way." +msgstr "" + +#: includes/views/parts/admin-sidebar.php:11 +msgid "Looking for help?" +msgstr "" + +#: includes/views/parts/admin-sidebar.php:12 +msgid "We have some resources available to help you in the right direction." +msgstr "" + +#: includes/views/parts/admin-sidebar.php:14 +msgid "Knowledge Base" +msgstr "" + +#: includes/views/parts/admin-sidebar.php:15 +msgid "Frequently Asked Questions" +msgstr "" + +#: includes/views/parts/admin-sidebar.php:17 +msgid "If your answer can not be found in the resources listed above, please use the support forums on WordPress.org." +msgstr "" + +#: includes/views/parts/admin-sidebar.php:18 +msgid "Found a bug? Please open an issue on GitHub." +msgstr "" + +#: includes/views/parts/admin-sidebar.php:28 +msgid "Other plugins by ibericode" +msgstr "" + +#: includes/views/parts/admin-sidebar.php:34 +msgid "Privacy-friendly analytics plugin that does not use any external services." +msgstr "" + +#: includes/views/parts/admin-sidebar.php:40 +msgid "Pop-ups or boxes that slide-in with a newsletter sign-up form. A sure-fire way to grow your email lists." +msgstr "" + +#: includes/views/parts/admin-sidebar.php:46 +msgid "Super flexible forms using native HTML. Just like Mailchimp for WordPress forms but for other purposes, like a contact form." +msgstr "" + +#: includes/views/parts/lists-overview.php:1 +msgid "Your Mailchimp Account" +msgstr "" + +#: includes/views/parts/lists-overview.php:2 +msgid "The table below shows your Mailchimp lists and their details. If you just applied changes to your Mailchimp lists, please use the following button to renew the cached lists configuration." +msgstr "" + +#: includes/views/parts/lists-overview.php:19 +msgid "No lists were found in your Mailchimp account" +msgstr "" + +#: includes/views/parts/lists-overview.php:22 +msgid "A total of %d lists were found in your Mailchimp account." +msgstr "" + +#: includes/views/parts/lists-overview.php:27 +msgid "List Name" +msgstr "" + +#: includes/views/parts/lists-overview.php:28 +msgid "ID" +msgstr "" + +#: includes/views/parts/lists-overview.php:29 +msgid "Subscribers" +msgstr "" + +#: includes/views/parts/lists-overview.php:49 +msgid "Edit this list in Mailchimp" +msgstr "" + +#: includes/views/parts/lists-overview.php:50 +msgid "Loading... Please wait." +msgstr "" + +#: integrations/contact-form-7/admin-before.php:2 +msgid "To integrate with Contact Form 7, configure the settings below and then add %s to your CF7 form mark-up." +msgstr "" + +#: integrations/custom/admin-before.php:2 +msgid "To get a custom integration to work, include the following HTML in the form you are trying to integrate with." +msgstr "" + +#: integrations/custom/admin-before.php:9 +msgid "Subscribe to our newsletter." +msgstr "" + +#. translators: %s links to the Gravity Forms overview page +#: integrations/gravity-forms/admin-before.php:4 +msgid "To integrate with Gravity Forms, add the \"Mailchimp for WordPress\" field to one of your Gravity Forms forms." +msgstr "" + +#: integrations/gravity-forms/class-field.php:38 +msgid "Mailchimp for WordPress" +msgstr "" + +#: integrations/gravity-forms/class-gravity-forms.php:93 +#: integrations/wpforms/class-field.php:79 +msgid "Mailchimp list" +msgstr "" + +#: integrations/gravity-forms/class-gravity-forms.php:96 +msgid "Select a Mailchimp list" +msgstr "" + +#: integrations/ninja-forms-2/admin-before.php:2 +msgid "To integrate with Ninja Forms, add the \"Mailchimp\" field to your Ninja Forms forms." +msgstr "" + +#: integrations/ninja-forms/admin-before.php:2 +msgid "To integrate with Ninja Forms, add the \"Mailchimp\" action to one of your Ninja Forms forms." +msgstr "" + +#: integrations/ninja-forms/class-action.php:21 +msgid "Mailchimp" +msgstr "" + +#: integrations/ninja-forms/class-field.php:35 +msgid "Mailchimp opt-in" +msgstr "" + +#: integrations/woocommerce/admin-after.php:4 +msgid "After email field" +msgstr "" + +#: integrations/woocommerce/admin-after.php:5 +msgid "After billing details" +msgstr "" + +#: integrations/woocommerce/admin-after.php:6 +msgid "After shipping details" +msgstr "" + +#: integrations/woocommerce/admin-after.php:7 +msgid "After customer details" +msgstr "" + +#: integrations/woocommerce/admin-after.php:8 +msgid "Before submit button" +msgstr "" + +#: integrations/woocommerce/admin-after.php:9 +msgid "After order notes" +msgstr "" + +#: integrations/woocommerce/admin-after.php:13 +msgid "Checkout for WooCommerce: Before complete order button" +msgstr "" + +#: integrations/woocommerce/admin-after.php:14 +msgid "Checkout for WooCommerce: After account info" +msgstr "" + +#: integrations/woocommerce/admin-after.php:15 +msgid "Checkout for WooCommerce: After customer info" +msgstr "" + +#: integrations/woocommerce/admin-after.php:36 +msgid "Position" +msgstr "" + +#: integrations/woocommerce/class-woocommerce.php:179 +msgid "Order #%d" +msgstr "" + +#: integrations/wpforms/admin-before.php:2 +msgid "Use this integration by adding the \"Mailchimp\" field to your WPForms forms." +msgstr "" + +#: integrations/wpforms/class-field.php:18 +msgid "Sign-up to our newsletter?" +msgstr "" + +#: integrations/wpforms/class-field.php:73 +msgid "Select the Mailchimp list to subscribe to." +msgstr "" + +#: integrations/wpforms/class-field.php:104 +msgid "Set your sign-up label text and whether it should be pre-checked." +msgstr "" + +#: integrations/wpforms/class-field.php:115 +msgid "Sign-up checkbox" +msgstr "" diff --git a/html/wp-content/plugins/mailchimp-for-wp/mailchimp-for-wp.php b/html/wp-content/plugins/mailchimp-for-wp/mailchimp-for-wp.php new file mode 100644 index 0000000..5ec1f45 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/mailchimp-for-wp.php @@ -0,0 +1,107 @@ +. + */ + +// Prevent direct file access +defined('ABSPATH') or exit; + +// bootstrap main plugin +add_action('plugins_loaded', function () { + global $mc4wp; + + // don't run if Mailchimp for WP Pro 2.x is activated + // don't run if PHP version is lower than 7.4.0 + if (defined('MC4WP_VERSION') || PHP_VERSION_ID < 70400) { + return; + } + + // bootstrap the core plugin + define('MC4WP_VERSION', '4.10.1'); + define('MC4WP_PLUGIN_DIR', __DIR__); + define('MC4WP_PLUGIN_FILE', __FILE__); + + require __DIR__ . '/autoload.php'; + require __DIR__ . '/includes/default-actions.php'; + require __DIR__ . '/includes/default-filters.php'; + + /** + * @global MC4WP_Container $GLOBALS['mc4wp'] + * @name $mc4wp + */ + $mc4wp = mc4wp(); + $mc4wp['api'] = 'mc4wp_get_api_v3'; + $mc4wp['log'] = 'mc4wp_get_debug_log'; + + // forms + $form_manager = new MC4WP_Form_Manager(); + $form_manager->add_hooks(); + $mc4wp['forms'] = $form_manager; + + // integration core + $integration_manager = new MC4WP_Integration_Manager(); + $integration_manager->add_hooks(); + $mc4wp['integrations'] = $integration_manager; + + // Initialize admin section of plugin + if (is_admin()) { + $admin_tools = new MC4WP_Admin_Tools(); + + if (defined('DOING_AJAX') && DOING_AJAX) { + $ajax = new MC4WP_Admin_Ajax($admin_tools); + $ajax->add_hooks(); + } else { + $messages = new MC4WP_Admin_Messages(); + $mc4wp['admin.messages'] = $messages; + + $admin = new MC4WP_Admin($admin_tools, $messages); + $admin->add_hooks(); + + $forms_admin = new MC4WP_Forms_Admin($messages); + $forms_admin->add_hooks(); + + $integrations_admin = new MC4WP_Integration_Admin($integration_manager, $messages); + $integrations_admin->add_hooks(); + } + } + + // bootstrap integrations + require __DIR__ . '/integrations/bootstrap.php'; +}, 8); + +// schedule the action hook to refresh the stored Mailchimp lists on a daily basis +register_activation_hook(__FILE__, function () { + $time_string = sprintf('tomorrow %d:%d am', rand(0, 7), rand(0, 59)); + wp_schedule_event(strtotime($time_string), 'daily', 'mc4wp_refresh_mailchimp_lists'); +}); + +// remove scheduled hook when plugin is deactivated +register_deactivation_hook(__FILE__, function () { + wp_clear_scheduled_hook('mc4wp_refresh_mailchimp_lists'); +}); diff --git a/html/wp-content/plugins/mailchimp-for-wp/readme.txt b/html/wp-content/plugins/mailchimp-for-wp/readme.txt new file mode 100644 index 0000000..a17f249 --- /dev/null +++ b/html/wp-content/plugins/mailchimp-for-wp/readme.txt @@ -0,0 +1,1169 @@ +=== MC4WP: Mailchimp for WordPress === +Contributors: Ibericode, DvanKooten, hchouhan, lapzor +Donate link: https://www.mc4wp.com/contribute/#utm_source=wp-plugin-repo&utm_medium=mailchimp-for-wp&utm_campaign=donate-link +Tags: mailchimp, subscribe, email, newsletter, form +Requires at least: 4.6 +Tested up to: 6.7 +Stable tag: 4.10.1 +License: GPL-3.0-or-later +License URI: http://www.gnu.org/licenses/gpl-3.0.html +Requires PHP: 7.4 + +The #1 Mailchimp plugin for WordPress. Allows you to add a multitude of newsletter sign-up methods to your site. + +== Description == + +*Allowing your visitors to subscribe to your newsletter should be easy. With this plugin, it finally is.* + +This plugins helps you grow your email list in Mailchimp. You can use it to create good looking and accessible sign-up forms or integrate with any other existing form on your WordPress site, like your contact, comment or checkout form. + +[youtube https://www.youtube.com/watch?v=fZCYPnFybqU] + +#### Some (but not all) features + +- Connect with your Mailchimp account in seconds. + +- Sign-up forms which are good looking, user-friendly and mobile optimized. You have complete control over the form fields and can build your forms using native HTML. + +- Seamless integration with the following plugins: + - WordPress Comment Form + - WordPress Registration Form + - Contact Form 7 + - WooCommerce + - Gravity Forms + - Ninja Forms 3 + - WPForms + - BuddyPress + - MemberPress + - Events Manager + - Easy Digital Downloads + - Give + - UltimateMember + - HTML Forms + - AffiliateWP + +- Is the plugin you want to integrate with not listed above? You can probably still use our [custom integration](https://www.mc4wp.com/kb/add-subscribe-checkbox-custom-form/) feature. Alternatively, the plugin comes with a PHP API to programmatically add a new subscriber to Mailchimp. + +- [Mailchimp for WordPress Premium](https://www.mc4wp.com/): Send your WooCommerce orders to Mailchimp so you can see exactly what each subscriber purchased and how much revenue your email campaigns are generating. + +- A multitude of available add-on plugins and integrations: + - [Mailchimp for WordPress Premium](https://www.mc4wp.com/) + - [Mailchimp Top Bar](https://wordpress.org/plugins/mailchimp-top-bar/) + - [Boxzilla Pop-ups](https://wordpress.org/plugins/boxzilla/) + +- Well documented through our [knowledge base](https://www.mc4wp.com/kb/). + +- Developer friendly. For some inspiration, check out our [repository of example code snippets](https://github.com/ibericode/mailchimp-for-wordpress/tree/main/sample-code-snippets). + +- Ready for PHP 8.4, but backwards-compatible all the way down to PHP 7.4. + +#### What is Mailchimp? + +Mailchimp is a newsletter service that allows you to send out email campaigns to a list of email subscribers. It is free for lists with up to 500 email subscribers, which is why it is the newsletter-service of choice for thousands of small businesses across the globe. + +If you are not yet using Mailchimp, [creating an account is 100% free and only takes you about 30 seconds](http://eepurl.com/igOGeX). + +== Installation == + +#### Installing the plugin +1. In your WordPress admin panel, go to *Plugins > New Plugin*, search for **Mailchimp for WordPress** and click "*Install now*" +1. Alternatively, download the plugin and upload the contents of `mailchimp-for-wp.zip` to your plugins directory, which usually is `/wp-content/plugins/`. +1. Activate the plugin +1. Set [your API key](https://admin.mailchimp.com/account/api) in the plugin settings. + +#### Configuring Sign-Up Form(s) +1. Go to *Mailchimp for WP > Forms* +2. Select at least one list to subscribe people to. +3. *(Optional)* Add more fields to your form. +4. Embed a sign-up form in pages or posts using the `[mc4wp_form]` shortcode or Gutenberg block. +5. Show a sign-up form in your widget areas using the "Mailchimp Sign-Up Form" widget. +6. Show a sign-up form from your theme files by using the `mc4wp_show_form()` PHP function. + +#### Need help? +Please take a look at the [MC4WP knowledge base](https://www.mc4wp.com/kb/#utm_source=wp-plugin-repo&utm_medium=mailchimp-for-wp&utm_campaign=installation-instructions-link) first. + +If you can't find an answer there, please look through the [plugin support forums](https://wordpress.org/support/plugin/mailchimp-for-wp) or start your own topic. + +== Frequently Asked Questions == + +#### Where can I find my Mailchimp API key? +You can [find your API key here](http://kb.mailchimp.com/accounts/management/about-api-keys#Find-or-Generate-Your-API-Key) + +#### How to display a form in posts or pages? +Use the `[mc4wp_form]` shortcode or the Gutenberg block. + +#### How to display a form in widget areas like the sidebar or footer? +Go to **Appearance > Widgets** and use the **Mailchimp for WP Form** widget that comes with the plugin. + +#### How to add a sign-up checkbox to my Contact Form 7 form? +Use the following shortcode in your CF7 form to display a newsletter sign-up checkbox. + +` +[mc4wp_checkbox "Subscribe to our newsletter?"] +` + +Our knowledge base has more information on [connecting Contact Form 7 and Mailchimp](https://www.mc4wp.com/kb/connecting-contact-form-7-and-mailchimp/). + +#### The form shows a success message but subscribers are not added to my list(s)? +If the form shows a success message, there is no doubt that the sign-up request succeeded. Mailchimp could have a slight delay sending the confirmation email though. Please check again in a few minutes (sometimes hours) and don't forget to check your junk folder too. + +When you have double opt-in disabled, new subscribers will be seen as *imports* by Mailchimp. They will not show up in your daily digest emails or statistics. [We always recommend leaving double opt-in enabled](http://blog.mailchimp.com/double-opt-in-vs-single-opt-in-stats/). + +#### How can I style the sign-up form? +You can use custom CSS to style the sign-up form if you do not like the themes that come with the plugin. The following selectors can be used to target the various form elements. + +` +.mc4wp-form { ... } /* the form element */ +.mc4wp-form p { ... } /* form paragraphs */ +.mc4wp-form label { ... } /* labels */ +.mc4wp-form input { ... } /* input fields */ +.mc4wp-form input[type="checkbox"] { ... } /* checkboxes */ +.mc4wp-form input[type="submit"] { ... } /* submit button */ +.mc4wp-alert { ... } /* success & error messages */ +.mc4wp-success { ... } /* success message */ +.mc4wp-error { ... } /* error messages */ +` + +You can add your custom CSS to your theme stylesheet or (easier) by using a plugin like [Simple Custom CSS](https://wordpress.org/plugins/simple-custom-css/#utm_source=wp-plugin-repo&utm_medium=mailchimp-for-wp&utm_campaign=after-css-link) + +#### How do I show a sign-up form in a pop-up? + +We recommend the [Boxzilla pop-up plugin](https://wordpress.org/plugins/boxzilla/) for this. You can use the form shortcode in your pop-up box to show a sign-up form. + +### How do I subscribe from my WooCommerce checkout form? + +You can use our WooCommerce integration for that. [How to subscribe to Mailchimp from the WooCommerce checkout form](https://www.mc4wp.com/kb/connect-woocommerce-store-mailchimp/). + +### How to connect my WooCommerce store with Mailchimp? + +You can find instructions for [connecting your WooCommerce store with Mailchimp](https://www.mc4wp.com/kb/connect-woocommerce-store-mailchimp/) on our website. + +#### I'm getting an "HTTP Error" when trying to connect to Mailchimp. + +the "HTTP Error" type is usually because of a firewall configuration issue or outdated software on your web server. + +Please contact your webhost and ask them to check the following: + +- Whether remote HTTP requests to `https://api.mailchimp.com` are allowed. +- Whether cURL and the PHP-cURL extension are installed and updated to a recent version. + +#### My question is not listed here. + +Please search through our [knowledge base](https://www.mc4wp.com/kb/#utm_source=wp-plugin-repo&utm_medium=mailchimp-for-wp&utm_campaign=faq). + + +== Other Notes == + +#### Support + +If you need some help in setting up the plugin, you have various options: + +- Search through our [knowledge base](https://www.mc4wp.com/kb/#utm_source=wp-plugin-repo&utm_medium=mailchimp-for-wp&utm_campaign=description). +- Open a topic in the [WordPress.org plugin support forums](https://wordpress.org/support/plugin/mailchimp-for-wp) +- If you're a premium user, send an email to the email address listed inside the plugin. + +#### Translations + +You can [help translate this plugin into your language](https://translate.wordpress.org/projects/wp-plugins/mailchimp-for-wp/stable/) using your WordPress.org account. + +#### Development + +This plugin is being developed on GitHub. If you want to collaborate, please look at [ibericode/mailchimp-for-wordpress](https://github.com/ibericode/mailchimp-for-wordpress). + +#### Customizing the plugin + +The plugin provides various filter and action hooks that allow you to modify or extend the default behavior. We're also maintaining a [collection of sample code snippets](https://github.com/ibericode/mailchimp-for-wordpress/tree/main/sample-code-snippets). + +== Screenshots == + +1. Example sign-up form in the TwentyTwenty theme. +2. Example sign-up integration with a contact form. +3. Settings page to connect with your Mailchimp account. +4. Overview of sign-up integrations. +5. Overview of sign-up forms. +6. Settings page to configure an integration. +7. Page where you edit your sign-up forms. +8. Page where you modify your form messages. +9. Settings page for e-commerce integration with Mailchimp. Requires [Mailchimp for WordPress Premium](https://www.mc4wp.com/). + +== Changelog == + + +#### 4.10.1 - Feb 06, 2025 + +- Fix JS error breaking Ninja Forms edit form page when not connected to a Mailchimp account or account has no audiences. +- Remove `sprintf` usage in hot path. +- Lazy load `MC4WP_API_V3` class to save some memory and parse time. +- Save a tiny bit of memory in autoloader implementation by not repeatedly storing plugin directory. +- Remove unused setting key from default options. + + +#### 4.10.0 - Jan 23, 2025 + +- Bump required PHP version to 7.4 or higher. +- Obfuscate API key the same way as in the Mailchimp.com interface. +- Delete all plugin data when plugin is uninstalled / deleted via WP Admin. +- Fix several PHP 8.4 deprecation warnings. +- Address warning about translations being loaded too early if using Ninja Forms integration. +- Run stored setting values related to user-facing textual messages through i18n functions to allow translating them through plugins like Loco Translate or WPML. + + +#### 4.9.21 - Jan 08, 2025 + +- [Forms] Rename "list choice" to "audience choice" in available form fields. +- [Ninja Forms] Fix gettext being called too early warning in Ninja Forms base class. +- [WooCommerce] Allow pre-checking of sign-up checkbox in Checkout Block. + + +#### 4.9.20 - Dec 18, 2024 + +- Fix Ninja Forms integration field no longer showing up. +- Fix "link is expired" message because of missing nonce on button to dismiss API key notice. +- [WPML] Added text_no_lists_selected to the config file so it can be translated. Thanks [Diego Pereira](https://github.com/diiegopereira)! + + +#### 4.9.19 - Nov 11, 2024 + +- Add integration with [Prosopo](https://prosopo.io/), a GDPR compliant anti-spam solution for protecting your sign-up forms against bot sign-ups. Thanks [Maxim Akimov](https://github.com/light-source)! + + +#### 4.9.18 - Oct 21, 2024 + +- Bump required PHP version to 7.2. +- Prevent non-functional checkbox from showing up on WooCommerce my account page if WooCommerce checkout integration is enabled. +- Update default form content to include a "for" attribute on the label element. +- Minor performance optimizations to `MC4WP_Form::get_subscriber_tags()` +- Begrudgingly rename Mailchimp lists to Mailchimp audiences throughout the plugin's admin interfaces. + + +#### 4.9.17 - Sep 17, 2024 + +- Fix compatibility with WooCommerce versions 8.5 to 8.8 because of private method that was later made public. +- Fix potential reflected XSS by stripping and escaping all HTML from `{email}` tag replacements. Thanks to kauenavarro for responsibly disclosing. +- Fix potential stored XSS for attackers with both administrator access and Mailchimp account access by escaping HTML from interest group name. Thanks to Jorge Diaz (ddiax) for responsibly disclosing. + + +#### 4.9.16 - Sep 11, 2024 + +- Add support for WooCommerce Checkout Block in sign-up checkbox integration. + + +#### 4.9.15 - Aug 13, 2024 + +- Improved anti-spam measures on the [custom form integration](https://www.mc4wp.com/kb/subscribe-mailchimp-custom-html-form/). If you are using the custom form integration (using the `mc4wp-subscribe` checkbox), please test your forms after upgrading and report any issues to us. +- Improved anti-spam measures on all sign-up forms. +- Remove unsupported filter hook from Gravity Forms integration. + + +#### 4.9.14 - Jul 17, 2024 + +- Very minor code-size improvements to public forms related JavaScript. +- Update third-party JS dependencies. +- Bump tested WordPress version to 6.6. + + +#### 4.9.13 - Apr 25, 2024 + +- Fix issue with Composer classmap throwing a fatal error when an older version of Composer is already loaded. + + +#### 4.9.12 - Apr 22, 2024 + +- Fix last 10 Mailchimp lists not being pulled-in when having more than 10 lists. + + +#### 4.9.11 - Jan 8, 2024 + +- Update third-party JS dependencies. +- Bump tested WordPress version. + + +#### 4.9.10 - Nov 20, 2023 + +- Integrations: Update CheckoutWC hook name for WooCommerce checkbox integration. +- Forms: Don't show form preview to users without `edit_posts` capability. +- Forms: Explicitly exclude form preview from search engine indexing. +- General: Don't unnecessarily go through service contrainer while bootstrapping plugin. +- General: Remove some unnecessary JavaScript now that browser support has caught up. + + +#### 4.9.9 - Oct 3, 2023 + +- Fix class "MC4WP_Usage_Tracking" not found error for WP Cron / WP CLI processes. + + +#### 4.9.8 - Oct 3, 2023 + +- Remove the opt-in usage tracking functionality as we're not really using it for decision making anymore. +- Add missing label element to the select element for setting the logging level. +- Our JavaScript assets are now transpiled to support the same set of browsers as WordPress core. +This drops support for some very old browsers, but results in smaller bundle sizes for the supported set of browsers. +- Update third-party JS dependencies to their latest versions. + + +#### 4.9.7 - Aug 29, 2023 + +- Update third-party JS dependencies. +- Minor textual improvements. +- Bump tested WordPress version. + + +#### 4.9.6 - Jul 12, 2023 + +- Update third-party JS dependencies. +- Address some minor codestyle issues. + + +#### 4.9.5 - Jun 7, 2023 + +- Fix generated HTML for list/audience choice fields. +- Fix deprecation warning in includes/admin/class-review-notice.php. +- Update JavaScript dependencies. + + +#### 4.9.4 - May 2, 2023 + +- Fallback to default checkbox label if none given. Thanks to [Shojib Khan](https://github.com/kshojib). +- Improve WooCommerce integration settings page by disabling position field if integration is disabled. Thanks to [Shojib Khan](https://github.com/kshojib). +- Update JavaScript dependencies. + + +#### 4.9.3 - Mar 31, 2023 + +- Defend against breaking change in latest WPForms update. + + +#### 4.9.2 - Mar 21, 2023 + +- Add support for a field named `MARKETING_PERMISSIONS` to enable GDPR fields configured in Mailchimp. A [sample code snippet can be found here](https://github.com/ibericode/mailchimp-for-wordpress/blob/main/sample-code-snippets/forms/gdpr-marketing-permissions.md). +- Remove Google reCaptcha feature. This was already disabled if you were not already using it. + + +#### 4.9.1 - Feb 7, 2023 + +- Fix generated value attribute for fields of type choice (dropdown, checkboxes, radio fields). +- Fix type of `marketing_permissions` field in API requests. Thanks to [George Korakas](https://github.com/gkorakas-eli). +- Refactor list overview JS to not depend on Mithril.js anymore. +- Simplify admin footer text asking for a plugin review. +- When renewing lists, renew cached marketing permissions too. + + +#### 4.9.0 - Jan 13, 2023 + +- Removed deprecated filter hook `mc4wp_settings_cap`, use `mc4wp_admin_required_capability` instead. +- Removed deprecated filter hook `mc4wp_merge_vars`, use `mc4wp_form_data` or `mc4wp_integration_data` instead. +- Removed deprecated filter hook `mc4wp_form_merge_vars`, use `mc4wp_form_data` instead. +- Removed deprecated filter hook `mc4wp_integration_merge_vars`, use `mc4wp_integration_data` instead. +- Removed deprecated filter hook `mc4wp_valid_form_request`, use `mc4wp_form_errors` instead. +- Removed deprecated function `mc4wp_get_api()` and deprecated class `MC4WP_API`. +- Removed deprecated function `mc4wp_checkbox()`. +- Removed deprecated function `mc4wp_form()`, use `mc4wp_show_form()` instead. +- Added filter `mc4wp_debug_log_message` to modify or disable messages that are written to the debug log. +- Fix color of invalid Mailchimp API key notice. +- Sanitize IP address value from `$_SERVER['REMOTE_ADDR']` too. +- Fetch GDPR marketing permissions via first subscriber on list and show them in lists overview table. + + +#### 4.8.12 - Dec 06, 2022 + +- Minor performance, memory usage & size optimizations for all JavaScript code bundled with this plugin. + + +#### 4.8.11 - Nov 1, 2022 + +- Improved default styling for the WooCommerce sign-up checkbox integration. +- Add `` to allowed HTML elements for GDPR disclaimer text on settings pages. +- Remove all references to obsolete placeholders.js polyfill. +- Move the GiveWP sign-up checkbox closer to the email input field. Thanks [Matthew Lewis](https://github.com/Matthew-Lewis). + + +#### 4.8.10 - Sep 14, 2022 + +- Fix mc4wp_get_request_ip_address() to return an IP address that matches Mailchimp's validation format when X-Forwarded-For header contains a port component. + + +#### 4.8.8 - Aug 25, 2022 + +- Fix mc4wp_get_request_ip_address() to pass new Mailchimp validation format. This fixes the "This value is not a valid IP." error some users using a proxy may have been seeing. + + +#### 4.8.7 - Mar 2, 2022 + +- Fix PHP 8.1 deprecation warnings in `MC4WP_Container` class. +- Fix name of action hook that fires before Mailchimp settings rows are displayed on the settings page. Thanks [LoonSongSoftware](https://github.com/LoonSongSoftware). +- Improve WPML compatibility. Thanks [Sumit Singh](https://github.com/5um17). +- Fix deprecated function for AMP integration. +- Only allow unfiltered HTML if user has `unfiltered_html` capability. Please read the below. + +Despite extensive testing, we may have missed some more obscure HTML elements or attributes from our whitelist. +If you notice that some of your form HTML is stripped after saving your form, please get in touch with our support team and provide the HTML you attempted to save. + + +#### 4.8.6 - Jun 24, 2021 + +- Add nonce field to button for dismissing notice asking for plugin review. +- Add strings from config/ directory to POT file. +- Add nonce check to AJAX endpoint for refreshing cached Mailchimp lists. +- Add capability check to AJAX endpoint for retrieving list details. +- Schedule event to refresh cached Mailchimp list upon plugin activation. + +Thanks to the team over at [pluginvulnerabilities.com](https://www.pluginvulnerabilities.com/) for bringing some of these changes to our attention. + + +#### 4.8.5 - Jun 1, 2021 + +Add nonce verification to all URL's using `_mc4wp_action` query parameter. +This fixes a CSRF vulnerability where a malicious website could trick a logged-in admin user in performing unwanted actions. + +A special thanks to Erwan from [WPScan](https://wpscan.com/) for bringing this issue to our attention. + + +#### 4.8.4 - May 7, 2021 + +- Add `defer` attribute to JS file, so page parsing isn't blocked at all. +- Rewrite plugin CSS to optimize for selector performance and get rid of some duplication. + +After installing this update, make sure to also update any add-on plugins like [Mailchimp for WordPress Premium](https://www.mc4wp.com/premium-features/) and [Mailchimp Top Bar](https://wordpress.org/plugins/mailchimp-top-bar/). + + +#### 4.8.3 - Jan 21, 2021 + +- Fix fatal error on older PHP versions when submitting form without any subscriber tags set in the form settings. +- Minor performance improvement in bootstrap method of the plugin. + + +#### 4.8.2 - Jan 20, 2021 + +- Allow short-circuiting `mc4wp_subscriber_data` filter by returning `null` or `false`. +- Use a subdirectory for the default debug log file location, so that it's easier to protect using htaccess. +- Improved reliability for fetching lists from mailchimp when lists have high stats.member_count property. + + +#### 4.8.1 - Aug 25, 2020 + +- Fix notice by explicitly setting `permission_callback` on registered REST route. +- Minor internal code improvements. + +#### 4.8 - Jul 9, 2020 + +- Plugin now requires PHP 5.3 or higher. +- Prefix overlay classname to prevent styling collissions with other plugins. +- Form sign-ups can now add tags to both new and existing subscribers. +- Update JavaScript dependencies. +- Register script early to work with Gutenberg preview. + + +#### 4.7.8 - Jun 04, 2020 + +- Add `MC4WP_API_V3::add_template` method. +- Minor code hardening to ensure a default form is always set. +- Update JS dependencies to their latest versions. +- Fix icon for Gutenberg block. + + +#### 4.7.7 - Apr 28, 2020 + +- Update JS dependencies to their latest versions. +- API client `add_list_member` method now has an additional parameter to skip merge field validation. +- Simplify code for updating an existing form. + + +#### 4.7.6 - Apr 9, 2020 + +- Update JS dependencies to their latest versions. +- Check if className is of type string, fixes a console warning when clicking inside a SVG element. +- Minor improvements to the AMP implementation to address harmless validation warnings. + + +#### 4.7.5 - Feb 10, 2020 + +- Add AMP compatibility to sign-up forms, thanks to Claudiu Lodromanean. This uses the [official AMP plugin for WordPress](https://amp-wp.org). +- Add settings key to WPML config so settings can easily by copied over to translated versions of a form. +- Optimize size & performance of JavaScript code, resulting in a file that is 40% smaller. +- Update CodeMirror to its latest version. +- Escape all string translations. + + +#### 4.7.4 - Dec 7, 2019 + +**Fixes** + +- htaccess config for servers running Apache 2.4 or later. + + +#### 4.7.3 - Dec 4, 2019 + +**Fixes** + +- Top Bar & User Sync add-on using API v2 since version 4.7.1. +- Revert change in formatter for date fields, breaking all forms with date fields in them. + +**Improvements** + +- Add getter method for raw (unmodified) data on form class. + + +#### 4.7.2 - Nov 27, 2019 + +**Fixes** + +- Invalid .htaccess file in case there already is one in the uploads directory. + + +#### 4.7.1 - Nov 26, 2019 + +**Improvements** + +- Update MemberPress hook names. Thanks [Ian Heggaton](https://github.com/pixelated-au)! +- Use WordPress.org translations instead of bundling translation files in plugin itself. +- Write .htaccess to directory of debug log file, to prevent file access. +- Add some convenient hooks for Checkout for WooCommerce. +- Stop parsing shortcodes in text widgets as WordPress core does this since version 4.9. + + +#### 4.7 - Nov 7, 2019 + +**Improvements** + +- Add role=alert to form notices. +- Add setting to pre-check sign-up checkbox for Gravity Forms integrations. +- Add new position for WooCommerce integration: directly after the billing_email field. +- Fix PHP notices for submitting a form and saving a form as an administrator. +- Add link to [Koko Analytics plugin](https://wordpress.org/plugins/koko-analytics/). + + +#### 4.6.2 - Oct 24, 2019 + +**Fixes** + +- Address fields in forms would always be required (even if really optional). + +**Improvements** + +- Add proper SVG admin menu icon. +- Minor overall performance and memory usage improvements. + + +#### 4.6.1 - Oct 7, 2019 + +**Fixes** + +- Fixed list cache usage for WPForms, Gravity Forms and Ninja Forms integrations. + + +#### 4.6.0 - Oct 7, 2019 + +**Improvements** + +- Improved fetch and cache mechanism for retrieving Mailchimp account details, fetching data only when it is required. +- Updated [Mithril](https://mithril.js.org/) and [CodeMirror](https://codemirror.net/) dependencies. +- Decreased size of `forms.js` from 22KB to 9KB. +- No longer requiring jQuery anywhere. +- Increase API HTTP request timeout to 15 seconds. + +Please note that installing this update requires you to also update any add-ons like [Mailchimp Top Bar](https://wordpress.org/plugins/mailchimp-top-bar/) and [Mailchimp for WordPress Premium](https://www.mc4wp.com/premium-features/) (if installed). + + +#### 4.5.5 - Sep 12, 2019 + +**Fixes** + +- Google reCAPTCHA script was still loading even if no forms have it enabled. + + +#### 4.5.4 - Sep 11, 2019 + +**Improvements** + +- Removed custom color from menu item for improved accessibility. +- Take birthday field format into account when sending data to Mailchimp. +- Print Google reCAPTCHA script in footer. + +**Changes** + +- Changed plugin name to MC4WP instead of Mailchimp for WordPress. + + +#### 4.5.3 - July 23, 2019 + +**Fixes** + +- Temporarily switch status of pending subscribers to "unsubscribe" versus deleting susbcriber before re-subscribing. +- Deprecation notice for Gravity Forms version 2.4 and higher. + +**Improvements** + +- Filter out empty tags when applying tags to new subscribers. +- Show all not installed integrations. +- Show notice when form doesn't have a Mailchimp list selected to subscribe people to. +- Check function existence for compatibility with WordPress 4.7 +- Don't submit form when Google reCAPTCHA is enabled but errors. +- Update third-party JavaScript dependencies. + + +#### 4.5.2 - May 8, 2019 + +**Improvements** + +- Accept more truthy values in custom integration for improved compatibility with third-party forms. +- Update JavaScript dependencies. +- Load Google reCaptcha script in footer (if needed). + + +#### 4.5.1 - April 8, 2019 + +**Additions** + +- Add sign-up integration for [Give](https://wordpress.org/plugins/give/) +- Add sign-up integration for [UltimateMember](https://wordpress.org/plugins/ultimate-member/) + +**Improvements** + +- Write to debug log if Google reCAPTCHA secret key is incorrect. +- Validate reCAPTCHA keys when savings form settings. +- Allow setting an empty "successfully subscribed" message. + + +#### 4.5.0 - March 27, 2019 + +**Additions** + +- Built-in integration with Google reCAPTCHA to prevent bots from subscribing to your Mailchimp lists. + +**Improvements** + +- Minor improvements to the JavaScript that is loaded on admin pages. + + +#### 4.4.0 - March 1, 2019 + +**Fixes** + +- AffiliateWP integration subscribing the wrong user if affiliate ID differs from user ID. + +**Improvements** + +- Renamed "MailChimp" to "Mailchimp" to match Mailchimp's new branding. +- More accurate handling of timeouts for accounts with many MailChimp lists. +- UX improvements for integrations overview page. +- Validate MailChimp API key format when it's entered. +- Improved compatibility with Klarna Checkout in the WooCommerce checkout integration. +- Bumped required PHP version to 5.3 (soft requirement for now). + +**Additions** + +- Added Gutenberg block for easily adding a form to a post or page. +- Added subscriber tags setting to forms. + + +#### 4.3.3 - December 31, 2018 + +**Fixes** + +- Update WPForms integration to properly detect if the WPForms plugin is activated. + +**Improvements** + +- Write API request parameters to the debug log in case of connection timeouts. +- Update JavaScript dependencies. + + +#### 4.3.2 - December 11, 2018 + +**Fixes** + +- Use of `readonly` function, which is only available in WordPress 4.9 or later. + + +#### 4.3.1 - November 28, 2018 + +**Fixes** + +- Fatal error on PHP versions older than 5.5 + + +#### 4.3 - November 28, 2018 + +**Additions** + +- Added `MC4WP_API_KEY` PHP constant which can be used to set your Mailchimp API key. +- Add `mc4wp_mailchimp_list_limit` filter hook to modify the maximum number of Mailchimp lists to fetch. Defaults to 200. + +**Improvements** + +- Apply `mc4wp_integration_gravity-forms_options` filter hook on Gravity Forms integration options so the checkbox can be prechecked and the checkbox label text modified. +- The `updated_subscriber` JS event is now fired forms not using AJAX as well (when applicable). + + +#### 4.2.5 - Sep 11, 2018 + +**Improvements** + +- Only re-add subscriber to list if we want to re-trigger a double opt-in confirmation email. +- Change Gravity Forms field name to "Mailchimp for WordPress" +- Get rid of cached result of Mailchimp API connection. + + +#### 4.2.4 - July 9, 2018 + +**Improvements** + +- Ensure type-safety on some global variables. +- Stop showing trashed forms immediately. +- Pre-check Mailchimp list when creating a new form if there is only 1 list. +- Send `null` for unknown values in usage tracking data (only when opted-in). + +**Additions** + +- Add methods for accessing Mailchimp's e-commerce promo code endpoints to API class. + + +#### 4.2.3 - June 11, 2018 + +**Fixes** + +- Don't wrap "agree to terms" input in hyperlink element. +- Allow [ENTER] key again after field helper overlay is closed. + +**Improvements** + +- Fallback to meta-refresh if redirect fails because of "headers already sent" error. + + + +#### 4.2.2 - May 22, 2018 + +**Fixes** + +- Events Manager integration was not working with logged-in users. +- Form preview URL should respect admin HTTP(S) scheme. +- Removed use of PHP 5.4 function. + +**Improvements** + +- Add "agree to terms" checkbox to field helper. + +**Additions** + +- Add filter `mc4wp_http_request_args`. + + +#### 4.2.1 - April 11, 2018 + +**Fixes** + +- Namespace usage warning when running PHP 5.2 + +**Improvements** + +- Remove obsolete `type` attribute from all ` + $item) { + $selected =''; + if ($key == $saved_value) + $selected = "selected='selected'"; + $output .= "\n"; + + } + echo $output; +} + +function mtm_input_checkbox_items($name, $array, $saved_values, $horizontal = true) { + $output = ""; + foreach($array as $key => $item) { + $checked = ""; + if (in_array($key, $saved_values)) $checked = "checked='checked'"; + $output .= "  "; + if(!$horizontal) + $output .= "
        \n"; + } + echo $output; + +} +function mtm_input_text($title, $name, $value='', $description ='', $ph = false, $classes = '') { + ?> + + + + > + +

        + + + + + + + + +

        + + + + + + + +

        + + + + + + + + + + + + $text): ?> + + + + + +
        >
        + + + __('No','events-manager'), 1 => __('Yes','events-manager')); + $trigger_att = ($trigger) ? 'data-trigger="'.esc_attr($trigger).'" class="em-trigger"':''; + ?> + + + +     + +

        + + + + + + + +

        + + +

        ' . __('Settings saved.') . '

        '; // No textdomain: phrase used in core, too +} +// get tabs settings, in case we want to split them page by page rather than one page +if( defined('MTM_SETTINGS_TABS') && MTM_SETTINGS_TABS ){ + $tabs_enabled = true; + $builder_tab_link = esc_url(add_query_arg( array('mtm_tab'=>'builder'))); + $general_tab_link = esc_url(add_query_arg( array('mtm_tab'=>'general'))); +}else{ + $general_tab_link = $builder_tab_link = ''; +} +// button for submission (reused) +global $mtm_submit_button; +$mtm_submit_button = '

        '; + +?> +
        + +

        + +
        +
        +
        +
        + +
        + +
        + +
        + +
        + +
        + +
        + +
        + +
        + +
        + +
        + +
        + + +
        + $tab_name ){ + if( !empty($fixed_tabs[$tab_key]) ) continue; + ?> + + +
        +
        + +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/mtm-builder.php b/html/wp-content/plugins/meta-tag-manager/admin/mtm-builder.php new file mode 100644 index 0000000..0dd07e3 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/mtm-builder.php @@ -0,0 +1,236 @@ + $posted_tag ){ + if( $k === 't' ) continue; //skip the template + $tag = new MTM_Tag_Admin($posted_tag); + $mtm_data[] = $tag->to_array(); + } + } + return $mtm_data; + } + + public static function output($meta_tags, $args = array() ){ + ?> +
        + +
        + '.esc_html__('No tags added yet, click here or on the button below to add one!','meta-tag-manager').'
        '; + ?> +
        +
        + +
        + + + + + +
        +
        +
        +
        + +
        + +
        + + reference) ? __('Custom Meta Tag','meta-tag-manager') : $tag->reference; ?> + + + + + + + context) ? array('all') : $tag->context; + echo static::get_contexts_list( $context_value ); + ?> + + + + +
        + + + <meta + + value) ? $tag->value:'...'; + ?> + type); ?>="" + + + content) ? $tag->content:'...' ?> + content="" + + /> + + +
        + +
        +
        + +
        + +
        +
        + +
        +
        + +
        + +
        + +
        + + +
        + +
        +
        +
        + $option ){ + $selected_attr = ( (is_array($selected) && in_array($option, $selected)) || $selected == $option ) ? ' selected="selected"':''; + if( is_array($option) ){ + $html .= ''; + $html .= self::output_select_options($option, $selected, false); + $html .= ''; + }else{ + //single option, output value no key + if( is_numeric($key) ){ + $html .= ''; + }else{ + $html .= ''; + } + } + } + if( !preg_match('/selected="selected"/', $html) && !empty($selected) && $add_selected_option ){ + //value not existing, so we add it as an option + if( is_array($selected) ){ + foreach( $selected as $s ){ + $html = '' . $html; + } + }else{ + $html = '' . $html; + } + } + return apply_filters('mtm_builder_output_select_options', $html, $options, $selected, $add_selected_option); + } + + public static function get_contexts_list( $contexts ){ + if( empty($contexts) ) return ''; + $display_contexts = array(); + foreach( self::get_context_options() as $context_label => $context_option ){ + if( is_array($context_option) ){ + foreach( $context_option as $context_option_label => $context_option_value ) + if( in_array($context_option_value, $contexts) ){ + $display_contexts[] = $context_option_label; + } + }else{ + if( in_array($context_option, $contexts) ){ + $display_contexts[] = $context_label; + } + } + } + return apply_filters('mtm_builder_get_contexts_list', implode(', ', $display_contexts), $display_contexts, $contexts); + } + + public static function get_context_options(){ + if( !empty(self::$context_options) ) return self::$context_options; + $context_options = apply_filters('mtm_builder_context_options_main', array( + __('All Pages', 'meta-tag-manager') => 'all', + __('Front Page', 'meta-tag-manager') => 'home' + )); + // Post Types + $post_types_label = __('Post Types', 'meta-tag-manager'); + foreach( get_post_types(array('public'=>true), 'objects') as $post_type){ + $context_options[$post_types_label][$post_type->labels->name] = 'post-type_' . $post_type->name; + } + // Taxonomies + $taxonomies_label = __('Taxonomies', 'meta-tag-manager'); + foreach( get_taxonomies(array('public'=>true), 'objects') as $taxonomy ){ + $context_options[$taxonomies_label][$taxonomy->labels->name] = 'taxonomy_' . $taxonomy->name; + } + self::$context_options = apply_filters('mtm_builder_context_options', $context_options); + return $context_options; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/mtm-tag-admin.php b/html/wp-content/plugins/meta-tag-manager/admin/mtm-tag-admin.php new file mode 100644 index 0000000..d9e34a0 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/mtm-tag-admin.php @@ -0,0 +1,92 @@ + $v ){ + if( $k == 'content'){ + // handle refresh specifically + if ( $values['type'] ?? '' == 'http-equiv' && $values['value'] ?? '' == 'refresh' ) { + // if user is an admin, allow urls, otherwise only numbers + if ( current_user_can( 'manage_options' ) ) { + $values_cleaned[$k] = wp_kses( wp_unslash( $v ), array( 'http' => array( 'url' => true ) ) ); + } else { + $values_cleaned[$k] = absint($v); + } + } else { + $values_cleaned[$k] = wp_unslash($v); + } + } else{ + $values_cleaned[$k] = wp_kses(wp_unslash($v), array()); + } + } + $values_cleaned = apply_filters('mtm_tag_admin_values_cleaned', $values_cleaned, $values, $this); + //now pass cleaned values to parent constructor + parent::__construct($values_cleaned); + } + + public static function get_type_values($type = false){ + if( empty(self::$type_options) ){ + $options = array( + 'name' => array( + __('Common values','meta-tag-manager') => array( 'application-name', 'google-site-verification', 'facebook-domain-verification', 'author', 'description', 'generator', 'keywords', 'referrer' ), + __('Other possible values','meta-tag-manager') => array( 'creator', 'googlebot', 'publisher', 'robots', 'slurp', 'viewport') + ), + 'http-equiv' => array( 'Content-Security-Policy', 'default-style', 'refresh' ), + 'property' => array( + 'OpenGraph Properties' => array( 'og:url', 'og:type', 'og:title', 'og:locale', 'og:image', 'og:image:secure_url', 'og:image:type', 'og:image:width', 'og:image:height', 'og:video', 'og:video:secure_url', 'og:video:type', 'og:video:width', 'og:video:height', 'og:audio', 'og:audio:secure_url', 'og:audio:type', 'og:description', 'og:site_name', 'og:determiner' ), + 'Twitter Card Properties' => array( 'twitter:card', 'twitter:site', 'twitter:site:id', 'twitter:creator', 'twitter:creator:id', 'twitter:description', 'twitter:title', 'twitter:image', 'twitter:image:alt', 'twitter:player', 'twitter:player:width', 'twitter:player:height', 'twitter:player:stream', 'twitter:app:name:iphone', 'twitter:app:id:iphone', 'twitter:app:url:iphone', 'twitter:app:name:ipad', 'twitter:app:id:ipad', 'twitter:app:url:ipad', 'twitter:app:name:googleplay', 'twitter:app:id:googleplay', 'twitter:app:url:googleplay' ) + ) + ); + self::$type_options = apply_filters('mtm_tag_type_options', $options); + } + if( !empty($type) ){ + return array_key_exists($type, self::$type_options) ? self::$type_options[$type] : array(); + } + return apply_filters('mtm_tag_admin_get_type_values', self::$type_options); + } + + + public static function sanitize_contexts( $contexts ){ + Meta_Tag_Manager_Admin::load_builder(); // just in case + $context_options = MTM_Builder::get_context_options(); + $valid_contexts = array(); + // flatten the valid contexts array + foreach( $context_options as $context ){ + if( is_array($context) ){ + foreach( $context as $subcontext ){ + if( !is_array($subcontext) ) $valid_contexts[] = $subcontext; + } + }else{ + $valid_contexts[] = $context; + } + } + $clean_contexts = array(); + foreach( $contexts as $k => $context ){ + if( in_array($context, $valid_contexts) ){ + $clean_contexts[] = $context; + } + } + return apply_filters('mtm_tag_admin_sanitize_contexts', $clean_contexts, $contexts); + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/mtm-update.php b/html/wp-content/plugins/meta-tag-manager/admin/mtm-update.php new file mode 100644 index 0000000..70bf87c --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/mtm-update.php @@ -0,0 +1,60 @@ + $mtm_tag[0], + 'content' => $mtm_tag[1], + 'reference' => $mtm_tag[2], + 'type' => 'name' + ); + if( !empty($mtm_tag[3]) ){ + $new_tag['location'] = 'home'; + }else{ + $new_tag['location'] = 'all'; + } + $new_mtm_data[] = $new_tag; + } + update_option('mtm_data', $new_mtm_data); + update_option('mtm_custom', array('post-types'=>get_post_types())); + }elseif( version_compare( MTM_VERSION, $mtm_version ) ){ + delete_option('mtm_shiny_update_notice'); + $mtm_custom = get_option('mtm_custom'); + if( version_compare( '3.0.1', $mtm_version ) ){ + if( empty($mtm_custom['admin_notices']) ) $mtm_custom['admin_notices'] = array(); + $admin_notice = sprintf(esc_html__('Meta Tag Manager 3.0 introduces many new features including Open Graph and Schema support. Check out the newly updated %s!', 'meta-tag-manager'), ''. esc_html__('Settings Page', 'meta-tag-manager') .''); + $admin_notice .= '

        '. esc_html__('We are also proud to announce a new Pro add-on to help fund further development of this plugin, which has been freely available since 2009!', 'meta-tag-manager'); + $admin_notice .= '

        '. esc_html__('Learn More', 'meta-tag-manager') .' '.__('Dismiss').''; + $Admin_Notice = new \Meta_Tag_Manager\Admin_Notice('new-features-3-0', 'info', $admin_notice, 'all'); + \Meta_Tag_Manager\Admin_Notices::add( $Admin_Notice ); + } + } + + if( version_compare( MTM_VERSION, '3.1', '<' ) ){ + if( empty($mtm_custom['admin_notices']) ) $mtm_custom['admin_notices'] = array(); + $admin_notice = sprintf(esc_html__('Hello, testing, see the %s!', 'meta-tag-manager'), ''. esc_html__('Settings Page', 'meta-tag-manager') .''); + $Admin_Notice = new \Meta_Tag_Manager\Admin_Notice('update', 'info', $admin_notice, 'all'); + \Meta_Tag_Manager\Admin_Notices::add( $Admin_Notice ); + } + + // reviews + $data = is_multisite() ? get_site_option('mtm_admin_notices') : get_option('mtm_admin_notices'); + if( empty($mtm_version) || !isset($data['admin-modals']) ){ // if admin-modals isn't set, it was never added before + if( empty($data['admin-modals']) ) $data['admin-modals'] = array(); + if( !is_array($data['admin-modals']) ) $data['admin-modals'] = array(); + $data['admin-modals']['review-nudge'] = empty($mtm_version) ? time() + (DAY_IN_SECONDS * 14) : time() + (DAY_IN_SECONDS * 7); + update_site_option('mtm_admin_notices', $data); + } + // temp promo + if( time() < 1711962000 && version_compare($mtm_version, '3.1', '<') ) { + if( empty($data['admin-modals']) ) $data['admin-modals'] = array(); + $data['admin-modals']['promo-popup'] = true; + update_site_option('mtm_admin_notices', $data); + } + + update_option('mtm_version', MTM_VERSION); +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/notices/admin-notice.php b/html/wp-content/plugins/meta-tag-manager/admin/notices/admin-notice.php new file mode 100644 index 0000000..edf2adf --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/notices/admin-notice.php @@ -0,0 +1,179 @@ +name} + * @var string + */ + public $message = false; //the message + /** + * Whether a message is dismissable + * @var boolean + */ + public $dismissible = true; + /** + * If a message is dismissable and this is set to true, it will be shown to every user matching the who property until dismissed. + * This is also set to true by default if the user type is not 'admin' and not previously set to true or false by the mtm_admin_notice_ hook. + * @var boolean + */ + protected $user_notice = null; + /** + * If set to true, this is treated as a network-level notice, meaning it can apply to all sites on the network or the network admin in MultiSite mode. + * @var bool + */ + public $network = false; + + public function __construct( $key, $type = false, $message = false, $where = false ){ + //process the supplied data + if( empty($message) ){ + if( empty($type) && is_array($key) ){ + $notice = $key; + }elseif( is_array($type) ){ + $this->name = $key; + $notice = $type; + }elseif( is_array($key) ){ + $notice = $key; + }else{ + //we may even have simply a key/name for this notice, for hooking later on + if( is_string($key) ) $this->name = $key; + $notice = array(); + } + }else{ + //here we expect a string for eveything + $notice = array('name'=> (string) $key, 'what' => (string) $type, 'message' => (string) $message) ; + } + //we should have an array to process at this point + foreach( $notice as $key => $value ){ + $this->$key = $value; + } + //add where if defined + if( !empty($where) ) $this->where = $where; + //call a hook + do_action('mtm_admin_notice_'.$this->name, $this); + if( !is_multisite() && $this->where == 'network_admin' ) $this->where = 'settings'; + } + + public function __set( $prop, $val ){ + $this->$prop = $val; + } + + public function __get( $prop ){ + if( $prop == 'user_notice' ){ + return $this->is_user_notice(); + } + } + + /** + * Returns whether or not this object should be dismissed on a per-user basis. + * @return boolean + */ + public function is_user_notice(){ + if( $this->who != 'admin' && $this->user_notice === null ){ + //user_notice was not specifically set, so if notice is dismissible and not targetted at admins we assume it's dismissed at per-user basis + return $this->dismissible; + } + return $this->user_notice; + } + + /** + * Returns notice as an array with non-default values. + * @return array + */ + public function to_array(){ + $default = new Admin_Notice('default'); + $notice = array(); + foreach( get_class_vars('Meta_Tag_Manager\Admin_Notice') as $var => $val ){ + if( $this->$var != $default->$var ) $notice[$var] = $this->$var; + } + return $notice; + } + + public function can_show(){ + //check that we have at least a notice to show + if( empty($this->name) ) return false; + //can we display due to time? + $return = ( empty($this->when) || $this->when <= time() ); + //who to display it to + if( $return && !empty($this->who) && $this->who != 'all' ){ + $return = false; //unless this test passes, don't show it + if( $this->who == 'all' ) $return = true; + elseif ( $this->who == 'admin' ){ + if( $this->network && is_super_admin() ) $return = true; + elseif( current_user_can('manage_options') ) $return = true; + } + elseif( $this->who == 'blog_admin' && current_user_can('manage_options') ) $return = true; + elseif( !$return && current_user_can($this->who) ) $return = true; + } + //can we display due to location? + if( $return ){ + $return = false; //unless this test passes, don't show it + if( empty($this->where) || $this->where == 'all' ){ + $return = true; + }elseif( !empty($_REQUEST['page']) && $_REQUEST['page'] == 'meta-tag-manager' ){ + if( $this->where == 'plugin' || $this->where == 'settings' ) $return = true; + }elseif( is_network_admin() && !empty($_REQUEST['page']) && preg_match('/^meta\-tag\-manager\-/', $_REQUEST['page']) ){ + $return = $this->where == 'plugin' || $this->where == 'settings' || $this->where == 'network_admin'; + }elseif( !empty($_REQUEST['page']) && ($this->where == $_REQUEST['page'] || (is_array($this->where) && in_array($_REQUEST['page'], $this->where))) ){ + $return = true; + } + } + //does this even have a message we can display? + if( $return && empty($this->message)){ + $this->message = apply_filters('mtm_admin_notice_'.$this->name .'_message', false, $this); + $return = !empty($this->message); + } + //is this user-dismissable, and if so, did this user dismiss it? + if( $return && $this->is_user_notice() ){ + $user_id = get_current_user_id(); + $dismissed_notices = get_user_meta( $user_id, '_mtm_dismissed_notices', true); + $return = empty($dismissed_notices) || !in_array($this->name, $dismissed_notices); + } + return $return; + } + + public function output(){ + if( empty($this->message) ) return false; + $action = $this->network ? 'mtm_dismiss_network_admin_notice':'mtm_dismiss_admin_notice'; + $url = add_query_arg( array('action' => $action, 'notice' => $this->name, 'nonce' => wp_create_nonce($action.$this->name.get_current_user_id()) ), admin_url('admin-ajax.php') ); + ?> +

        +

        message; ?>

        +
        + name ) return false; + //get options data + $data = $network ? get_site_option('mtm_custom') : get_option('mtm_custom'); + $data = empty($data) ? array() : maybe_unserialize($data); + if( !is_array($data)) $data = array(); + $notices_data = $network ? get_site_option('mtm_admin_notices') : get_option('mtm_admin_notices'); + $notices_data = empty($notices_data) ? array() : maybe_unserialize($notices_data); + if( !is_array($notices_data)) $notices_data = array(); //we store the data regarldess of whether a message will require a hook, since it contains location and caps considtions + //start building data + $notices = !empty($data['admin_notices']) ? $data['admin_notices'] : array(); + $notices[$MTM_Admin_Notice->name] = !empty($MTM_Admin_Notice->when) ? $MTM_Admin_Notice->when : 0; + if( empty($hook_notice) ){ //we only skip this if simply a key is provided initially in $MTM_Admin_Notice + $notices_data[$MTM_Admin_Notice->name] = $MTM_Admin_Notice->to_array(); + } + if( !empty($notices) ){ + $data['admin_notices'] = $notices; + $update_notices = $network ? update_site_option('mtm_custom', $data) : update_option('mtm_custom', $data); + $update_notices_data = true; + if( !empty($notices_data) ){ + $update_notices_data = $network ? update_site_option('mtm_admin_notices', $notices_data) : update_option('mtm_admin_notices', $notices_data, false); + } + return $update_notices && $update_notices_data; + } + return false; + } + + /** + * Remove an admin notice. If $network is true, then a network-level admin notice will be removed. + * @param string $notice_key + * @param string $network + * @return boolean Returns true if successfully deleted, false if there's an error or if there's nothing to delete. + */ + public static function remove( $notice_key, $network = false ){ + $network = $network && is_multisite(); //make sure we are actually in multisite! + $data = $network ? get_site_option('mtm_custom') : get_option('mtm_custom'); + if( !empty($data['admin_notices']) && isset($data['admin_notices'][$notice_key])){ + unset($data['admin_notices'][$notice_key]); + if( empty($data['admin_notices']) ) unset($data['admin_notices']); + $result = $update_notices_data = $network ? update_site_option('mtm_custom', $data) : update_option('mtm_custom', $data); + $notices_data = $network ? get_site_option('mtm_admin_notices') : get_option('mtm_admin_notices'); + if( !empty($notices_data[$notice_key]) ){ + unset($notices_data[$notice_key]); + if( empty($notices_data) ){ + $update_notices_data = $network ? delete_site_option('mtm_admin_notices') : delete_option('mtm_admin_notices'); + }else{ + $update_notices_data = $network ? update_site_option('mtm_admin_notices', $notices_data) : update_option('mtm_admin_notices', $notices_data, false); + } + } + return $result && $update_notices_data; + } + return false; + } + + /** + * Adds admin notice to network rather than specific blog. Equivalent to self::add( $MTM_Admin_Notice, true ); + * @see Admin_Notices::add() + */ + public static function network_add( $MTM_Admin_Notice ){ return self::add( $MTM_Admin_Notice, true ); } + + /** + * Removes admin notice from network rather than specific blog. Equivalent to self::remove( $MTM_Admin_Notice, true ); + * @see Admin_Notices::remove() + */ + public static function network_remove( $notice_key ){ return self::remove( $notice_key, true ); } + + /** + * Output the admin notices we need to output now. If $network is true, MultiSite network messages will be output. + * @param string $network + */ + public static function admin_notices( $network = false ){ + $notices = array(); + $data = $network ? get_site_option('mtm_custom') : get_option('mtm_custom'); + $possible_notices = is_array($data) && !empty($data['admin_notices']) ? $data['admin_notices'] : array(); + //we may have something to show, so we make sure that there's something to show right now + foreach( $possible_notices as $key => $val ){ + //to avoid extra loading etc. we weed out time-based notices that aren't triggered right now + if( empty($val) || ($val > 0 && $val < time()) ){ + //we have a match, so we add this to $notices + $notices[$key] = self::get_notice($key, $network); + } + } + self::output( $notices, $network ); + } + + public static function get_notice( $key, $network = false ){ + //build notice object + $notice_data = $network ? get_site_option('mtm_admin_notices') : get_option('mtm_admin_notices'); + if( empty($notice_data[$key]) || !is_array($notice_data[$key]) ){ + $notice = array('name'=>$key, 'network'=>$network); + }else{ + $notice = $notice_data[$key]; + $notice['network'] = $network; + } + return new Admin_Notice($notice); + } + + /** + * Outputs admin notices at network level, same as Meta_Tag_Manager\Admin_Notices::admin_notices(true) + * @see Admin_Notices::admin_notices() + */ + public static function network_admin_notices(){ self::admin_notices(true); } + + /** + * Outputs admin notices and calls the dismissable JS to be output at footer of admin page. + * If $network is true, only MultiSite network-level notices will be shown. + * @param array $notices + * @param boolean $network + */ + public static function output( $notices, $network = false ){ + foreach( $notices as $MTM_Admin_Notice ){ + //output the notice if meant to + if( $MTM_Admin_Notice->can_show() ){ + if( $MTM_Admin_Notice->output() ) self::$js_footer = true; + } + } + if( self::$js_footer ){ + add_action('admin_footer', 'Meta_Tag_Manager\Admin_Notices::admin_footer'); + } + } + + /** + * If called via AJAX, the notice will be removed. + */ + public static function dismiss_admin_notice(){ + if( empty($_REQUEST['notice']) ) return; + if( empty($_REQUEST['nonce']) || !wp_verify_nonce($_REQUEST['nonce'], $_REQUEST['action'].$_REQUEST['notice'].get_current_user_id() ) ) die('Invalid Nonce'); + $key = $_REQUEST['notice']; + $network = $_REQUEST['action'] == 'mtm_dismiss_network_admin_notice'; + //get the notice + $MTM_Admin_Notice = self::get_notice($key, $network); + if( $MTM_Admin_Notice->is_user_notice() ){ + //user-specific notices are flagged on the user-level + $user_id = get_current_user_id(); + $dismissed_notices = get_user_meta( $user_id, '_mtm_dismissed_notices', true); + $dismissed_notices = is_array($dismissed_notices) ? $dismissed_notices : array(); + if( !in_array($MTM_Admin_Notice->name, $dismissed_notices) ){ + $dismissed_notices[] = $MTM_Admin_Notice->name; + $result = update_user_meta( $user_id, '_mtm_dismissed_notices', $dismissed_notices); + } + }else{ + $result = self::remove($_REQUEST['notice'], $network); + } + if( !empty($_REQUEST['redirect']) ){ + wp_safe_redirect( wp_get_referer() ); + exit(); + } + echo !empty($result) ? 'Thou art dismissed!' : 'Thou shall not pass!'; + exit(); + } + + /** + * Outputs JS for dismissing notices. + */ + public static function admin_footer(){ + ?> + + array(), 'infos'=>array(), 'alerts'=>array(), 'confirms'=>array()); + + function __construct( $set_cookies = true ){ + //Grab from cookie, if it exists + $this->set_cookies = $set_cookies == true; + if( $this->set_cookies ){ + if( !empty($_COOKIE['mtm_notices']) ) { + $notices = json_decode(base64_decode($_COOKIE['mtm_notices']), true); + if( is_array($notices) ){ + $this->notices = $notices; + setcookie('mtm_notices', '', time() - 3600, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); //unset the cookie + } + } + } + add_filter('wp_redirect', array(&$this,'destruct'), 1,1); + } + + function destruct($redirect = false){ + //Flush notices that weren't made to stay cross-requests, we can do this if initialized immediately. + foreach($this->notices as $notice_type => $notices){ + foreach ($notices as $key => $notice){ + if( empty($notice['static']) ){ + unset($this->notices[$notice_type][$key]); + }else{ + unset($this->notices[$notice_type][$key]['static']); //so it gets removed next request + $has_static = true; + } + } + } + if( $this->set_cookies ){ + if(count($this->notices['errors']) > 0 || count($this->notices['alerts']) > 0 || count($this->notices['infos']) > 0 || count($this->notices['confirms']) > 0){ + setcookie('mtm_notices', base64_encode(json_encode($this->notices)), time() + 30, COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); //sets cookie for 30 seconds, which may be too much + } + } + return $redirect; + } + + function __toString(){ + $string = false; + if(count($this->notices['errors']) > 0){ + $string .= "
        {$this->get_errors()}
        "; + } + if(count($this->notices['alerts']) > 0){ + $string .= "
        {$this->get_alerts()}
        "; + } + if(count($this->notices['infos']) > 0){ + $string .= "
        {$this->get_infos()}
        "; + } + if(count($this->notices['confirms']) > 0){ + $string .= "
        {$this->get_confirms()}
        "; + } + $this->displayed = true; + return ($string !== false) ? "
        ".$string."
        " : ''; + } + + /* General */ + function add($string, $type, $static = false){ + if( is_array($string) ){ + $result = true; + foreach($string as $key => $string_item){ + if( !is_array($string_item) ){ + if( $this->add($string_item, $type, $static) === false ){ $result = false; } + }else{ + if( $this->add_item($string_item, $type, $static) === false ){ $result = false; } + } + } + return $result; + } + if($string != ''){ + return $this->add_item($string, $type, $static); + }else{ + return false; + } + } + + function add_item($string, $type, $static = false){ + if( isset($this->notices[$type]) ){ + $notice_key = 0; + foreach( $this->notices[$type] as $notice_key => $notice ){ + if($string == $notice['string']){ + return $notice_key; + }elseif( is_array($string) && !empty($notice['title']) && $this->get_array_title($string) == $notice['title'] ){ + return $notice_key; + } + } + $i = $notice_key+1; + if( is_array($string) ){ + $this->notices[$type][$i]['title'] = $this->get_array_title($string); + $this->notices[$type][$i]['string'] = array_shift($string); + }else{ + $this->notices[$type][$i]['string'] = $string; + } + if( $static ){ + $this->notices[$type][$i]['static'] = true; + } + return $i; + }else{ + return false; + } + } + + /** + * Returns title of an array, assumes a assoc array with one item containing title => messages + * @param unknown_type $array + * @return unknown + */ + function get_array_title($array){ + foreach($array as $title => $msgs) + return $title; + } + + function remove($key, $type){ + if( isset($this->notices[$type]) ){ + unset($this->notices[$type][$key]); + return true; + }else{ + return false; + } + } + + function remove_all(){ + $this->notices = array('errors'=>array(), 'infos'=>array(), 'alerts'=>array(), 'confirms'=>array()); + } + + function get($type){ + if( isset($this->notices[$type]) ){ + $string = ''; + foreach ($this->notices[$type] as $message){ + if( !is_array($message['string']) ){ + if( preg_match('/

        /', $message['string']) ){ + $string .= $message['string']; + }else{ + $string .= "

        {$message['string']}

        "; + } + }else{ + $string .= "

        ".$message['title']."

          "; + foreach($message['string'] as $msg){ + if( trim($msg) != '' ){ + $string .= "
        • $msg
        • "; + } + } + $string .= "

        "; + } + } + return $string; + } + return false; + } + + function count($type){ + if( isset($this->notices[$type]) ){ + return count($this->notices[$type]); + } + return 0; + } + + /* Errors */ + function add_error($string, $static=false){ + return $this->add($string, 'errors', $static); + } + function remove_error($key){ + return $this->remove($key, 'errors'); + } + function get_errors(){ + return $this->get('errors'); + } + function count_errors(){ + return $this->count('errors'); + } + + /* Alerts */ + function add_alert($string, $static=false){ + return $this->add($string, 'alerts', $static); + } + function remove_alert($key){ + return $this->remove($key, 'alerts'); + } + function get_alerts(){ + return $this->get('alerts'); + } + function count_alerts(){ + return $this->count('alerts'); + } + + /* Info */ + function add_info($string, $static=false){ + return $this->add($string, 'infos', $static); + } + function remove_info($key){ + return $this->remove($key, 'infos'); + } + function get_infos(){ + return $this->get('infos'); + } + function count_infos(){ + return $this->count('infos'); + } + + /* Confirms */ + function add_confirm($string, $static=false){ + return $this->add($string, 'confirms', $static); + } + function remove_confirm($key){ + return $this->remove($key, 'confirms'); + } + function get_confirms(){ + return $this->get('confirms'); + } + function count_confirms(){ + return $this->count('confirms'); + } + + // Encoiding in JsonSerializable + #[\ReturnTypeWillChange] + function jsonSerialize(){ + $notices = array(); + foreach( $notices as $k => $v ){ + if( !empty($v) ){ + $notices[$k] = $v; + } + } + return $notices; + } + + //Iterator Implementation + #[\ReturnTypeWillChange] + function rewind(){ + reset($this->bookings); + } + #[\ReturnTypeWillChange] + function current(){ + $var = current($this->bookings); + return $var; + } + #[\ReturnTypeWillChange] + function key(){ + $var = key($this->bookings); + return $var; + } + #[\ReturnTypeWillChange] + function next(){ + $var = next($this->bookings); + return $var; + } + #[\ReturnTypeWillChange] + function valid(){ + $key = key($this->bookings); + $var = ($key !== NULL && $key !== FALSE); + return $var; + } + +} +function mtm_notices_init(){ + global $MTM_Notices; + $MTM_Notices = new MTM_Notices(); +} +add_action('plugins_loaded', 'mtm_notices_init'); +?> \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/settings/custom-meta-tags.php b/html/wp-content/plugins/meta-tag-manager/admin/settings/custom-meta-tags.php new file mode 100644 index 0000000..f94acd2 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/settings/custom-meta-tags.php @@ -0,0 +1,12 @@ + +
        +

        +

        +

        keywords, description'); ?>

        +

        + true, 'reference'=>true)); ?> + + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/settings/general.php b/html/wp-content/plugins/meta-tag-manager/admin/settings/general.php new file mode 100644 index 0000000..27d61ce --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/settings/general.php @@ -0,0 +1,25 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/settings/go-pro.php b/html/wp-content/plugins/meta-tag-manager/admin/settings/go-pro.php new file mode 100644 index 0000000..6155b26 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/settings/go-pro.php @@ -0,0 +1,180 @@ + +
        +

        Meta Tags Manager has been freely developed, maintained and supported since 2009. We've decided to provide premium support and create some new premium features to enable us to keep doing so for more years to come!

        +

        + Get the Pro version and unlock new features! See below for a feature list comparison, hover over the feature for more info. +

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Free/Main PluginPro Add-On
        General Meta Tags
        Meta Tag Builder
        Sitewide Meta Tags
        Basic display conditions
        Exclude display conditions
        Advanced display/exclusion contexts
        Dynamic placeholders
        Unique tag detection
        Unique tag overriding
        Shortcode Support
        Individual Pages, Posts and Custom Post Types
        Pages and Posts
        Custom Post Types
        Taxonomy Support
        General Taxonomy Meta Tags
        Specific Taxonomy Terms
        Dynamic placeholders
        Structured Data Support
        Home Page Schema
        Sitelinks Support
        Sitelinks Search Support
        Open Graph Support
        Home Page Open Graph
        Home Page Twitter Cards
        Custom Open Graph Tags
        Custom Twitter Card Tags
        Site Verification
        Verify Google, Bing, Yandex, Twitter, etc.
        + + From $49Limited Offer! + Go Pro! +
        +
        + \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/settings/open-graph.php b/html/wp-content/plugins/meta-tag-manager/admin/settings/open-graph.php new file mode 100644 index 0000000..d0b6992 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/settings/open-graph.php @@ -0,0 +1,97 @@ + +

        + +

        +

        + + +

        + +
        +

        +

        + +

        +

        + + + +

        +

        + + 0 ? wp_get_attachment_image( $image_id ) : ''; + ?> + + + + + +
        +
        + + + +

        +
        + +

        +

        + + +

        +

        <meta name="twitter:card" content="summary" />'); ?>

        +

        + +

        +
        +

        + + +
        +
        + window.open("'. $test_url_google .'");'; + if( !empty($_GET['og_test']) && $_GET['og_test'] == 'fb' ) echo ''; + if( !empty($_GET['og_test']) && $_GET['og_test'] == 'twitter' ) echo ''; + ?> +
        + +

        + +

        +

        + + + +

        + \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/settings/schema.php b/html/wp-content/plugins/meta-tag-manager/admin/settings/schema.php new file mode 100644 index 0000000..4db2496 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/settings/schema.php @@ -0,0 +1,341 @@ + array( array( 'description' => esc_html__('Person', 'meta-tag-manager') ), ), + 'Organization' => array( + 'description' => esc_html__('Organization'), + 'types' => array( + 'Airline' => array( 'description' => esc_html__('Airline', 'meta-tag-manager') ), + 'Consortium' => array( 'description' => esc_html__('Consortium', 'meta-tag-manager') ), + 'Corporation' => array( 'description' => esc_html__('Corporation', 'meta-tag-manager') ), + 'EducationalOrganization' => array( + 'description' => esc_html__('Educational Organization', 'meta-tag-manager'), + 'types' => array( + 'CollegeOrUniversity' => array( 'description' => esc_html__('College Or University', 'meta-tag-manager') ), + 'ElementarySchool' => array( 'description' => esc_html__('Elementary School', 'meta-tag-manager') ), + 'HighSchool' => array( 'description' => esc_html__('High School', 'meta-tag-manager') ), + 'MiddleSchool' => array( 'description' => esc_html__('Middle School', 'meta-tag-manager') ), + 'Preschool' => array( 'description' => esc_html__('Preschool', 'meta-tag-manager') ), + 'School' => array( 'description' => esc_html__('School', 'meta-tag-manager') ), + ), + ), + 'FundingScheme' => array( 'description' => esc_html__('Funding Scheme', 'meta-tag-manager') ), + 'GovernmentOrganization' => array( 'description' => esc_html__('Government Organization', 'meta-tag-manager') ), + 'LibrarySystem' => array( 'description' => esc_html__('Library System', 'meta-tag-manager') ), + /* + 'LocalBusiness' => array( + 'description' => esc_html__('Local Business', 'meta-tag-manager'), + 'types' => array( + 'AnimalShelter' => array('description' => esc_html__('Animal Shelter', 'meta-tag-manager')), + 'ArchiveOrganization' => array('description' => esc_html__('Archive Organization', 'meta-tag-manager')), + 'AutomotiveBusiness' => array('description' => esc_html__('Automotive Business', 'meta-tag-manager')), + 'ChildCare' => array('description' => esc_html__('Child Care', 'meta-tag-manager')), + 'Dentist' => array('description' => esc_html__('Dentist', 'meta-tag-manager')), + 'DryCleaningOrLaundry' => array('description' => esc_html__('Dry Cleaning Or Laundry', 'meta-tag-manager')), + 'EmergencyService' => array('description' => esc_html__('Emergency Service', 'meta-tag-manager')), + 'EmploymentAgency' => array('description' => esc_html__('Employment Agency', 'meta-tag-manager')), + 'EntertainmentBusiness' => array('description' => esc_html__('Entertainment Business', 'meta-tag-manager')), + 'FinancialService' => array('description' => esc_html__('Financial Service', 'meta-tag-manager')), + 'FoodEstablishment' => array('description' => esc_html__('Food Establishment', 'meta-tag-manager')), + 'GovernmentOffice' => array('description' => esc_html__('Government Office', 'meta-tag-manager')), + 'HealthAndBeautyBusiness' => array('description' => esc_html__('Health And Beauty Business', 'meta-tag-manager')), + 'HomeAndConstructionBusiness' => array('description' => esc_html__('Home And Construction Business', 'meta-tag-manager')), + 'InternetCafe' => array('description' => esc_html__('Internet Cafe', 'meta-tag-manager')), + 'LegalService' => array('description' => esc_html__('Legal Service', 'meta-tag-manager')), + 'Library' => array('description' => esc_html__('Library', 'meta-tag-manager')), + 'LodgingBusiness' => array('description' => esc_html__('Lodging Business', 'meta-tag-manager')), + 'MedicalBusiness' => array('description' => esc_html__('Medical Business', 'meta-tag-manager')), + 'ProfessionalService' => array('description' => esc_html__('Professional Service', 'meta-tag-manager')), + 'RadioStation' => array('description' => esc_html__('Radio Station', 'meta-tag-manager')), + 'RealEstateAgent' => array('description' => esc_html__('Real Estate Agent', 'meta-tag-manager')), + 'RecyclingCenter' => array('description' => esc_html__('Recycling Center', 'meta-tag-manager')), + 'SelfStorage' => array('description' => esc_html__('Self Storage', 'meta-tag-manager')), + 'ShoppingCenter' => array('description' => esc_html__('Shopping Center', 'meta-tag-manager')), + 'SportsActivityLocation' => array('description' => esc_html__('Sports Activity Location', 'meta-tag-manager')), + 'Store' => array('description' => esc_html__('Store', 'meta-tag-manager')), + 'TelevisionStation' => array('description' => esc_html__('Television Station', 'meta-tag-manager')), + 'TouristInformationCenter' => array('description' => esc_html__('Tourist Information Center', 'meta-tag-manager')), + 'TravelAgency' => array('description' => esc_html__('Travel Agency', 'meta-tag-manager')), + ) + ), + */ + 'MedicalOrganization' => array( + 'description' => esc_html__('Medical Organization', 'meta-tag-manager'), + 'types' => array( + 'Dentist' => array( 'description' => esc_html__('Dentist', 'meta-tag-manager') ), + 'DiagnosticLab' => array( 'description' => esc_html__('Diagnostic Lab', 'meta-tag-manager') ), + 'Hospital' => array( 'description' => esc_html__('Hospital', 'meta-tag-manager') ), + 'MedicalClinic' => array( 'description' => esc_html__('Medical Clinic', 'meta-tag-manager') ), + 'Pharmacy' => array( 'description' => esc_html__('Pharmacy', 'meta-tag-manager') ), + 'Physician' => array( 'description' => esc_html__('Physician', 'meta-tag-manager') ), + 'VeterinaryCare' => array( 'description' => esc_html__('Veterinary Care', 'meta-tag-manager') ), + ) + ), + 'NGO' => array( 'description' => esc_html__('NGO', 'meta-tag-manager') ), + 'NewsMediaOrganization' => array( 'description' => esc_html__('News Media Organization', 'meta-tag-manager') ), + 'PerformingGroup' => array( + 'description' => esc_html__('Performing Group', 'meta-tag-manager'), + 'types' => array( + 'DanceGroup' => array( 'description' => esc_html__('Dance Group', 'meta-tag-manager') ), + 'MusicGroup' => array( 'description' => esc_html__('Music Group', 'meta-tag-manager') ), + 'TheaterGroup' => array( 'description' => esc_html__('Theater Group', 'meta-tag-manager') ), + ) + ), + 'Project' => array( + 'description' => esc_html__('Project', 'meta-tag-manager'), + 'types' => array( + 'FundingAgency' => array( 'description' => esc_html__('Funding Agency', 'meta-tag-manager') ), + 'ResearchProject' => array( 'description' => esc_html__('Research Project', 'meta-tag-manager') ), + ), + ), + 'ResearchOrganization' => array( 'description' => esc_html__('Research Organization', 'meta-tag-manager') ), + 'SportsOrganization' => array( + 'description' => esc_html__('Sports Organization', 'meta-tag-manager'), + 'types' => array( + 'SportsTeam' => array( 'description' => esc_html__('Sports Team', 'meta-tag-manager') ), + ), + ), + 'WorkersUnion' => array( 'description' => esc_html__('Workers Union', 'meta-tag-manager') ), + ), + ) + ); + $site_type_options = array( + '0' => esc_html__('Chooase a site type', 'meta-tag-manager'), + 'Person' => esc_html__('Personal Website or Blog', 'meta-tag-manager'), + 'Organization' => esc_html__('Business or Organization', 'meta-tag-manager'), + ); +?> +

        + +

        +

        + +

        +

        +

        + +

        +

        + + +

        +

        + + esc_html__('General/Other', 'meta-tag-manager') ); + $org_subtypes = array(); + foreach( $schema_types['Organization']['types'] as $type => $type_data ){ + $org_types[$type] = $type_data['description']; + if( !empty($type_data['types']) ){ + $org_subtypes[$type] = array( $type => esc_html__('General/Other', 'meta-tag-manager') ); + foreach( $type_data['types'] as $subtype => $subtype_data ){ + $org_subtypes[$type][$subtype] = $subtype_data['description']; + } + } + } + $image_id = empty($schema['logo']) ? get_theme_mod( 'custom_logo' ) : $schema['logo']; + $image = intval( $image_id ) > 0 ? wp_get_attachment_image( $image_id ) : ''; + ?> + + + + +
        +
        + + + +

        +
        + + +
        + + + '. esc_html__('Local Business types are currently unavailable, coming soon!', 'meta-tag-manager'); + mtm_input_select( esc_html__('Organization Type', 'meta-tag-manager'), 'mtm_schema_site_type_organization', $org_types, $schema['Organization']['type'], $description); + ?> + + + $specific_org_subtypes ){ + $description = sprintf(esc_html__('Choose a more specific type of %s your site represents. If none of these options fit, then leave it as General/Other.', 'meta-tag-manager'), $org_types[$type]); + mtm_input_select( esc_html__('Organization Subtype', 'meta-tag-manager'), 'mtm_schema_site_type_organization_specific_'.$type, $specific_org_subtypes, $schema['Organization']['subtype'], $description ); + } + ?> + +
        +

        + + + + + + + + + '.esc_html__('country code', 'meta-tag-manager').'', '+1-800-123-1234'); + mtm_input_text( esc_html__('Contact Phone', 'meta-tag-manager'), 'mtm_schema_contact_telephone', $schema['Contact']['telephone'], $description, '+1-800-123-1234'); + mtm_input_text( esc_html__('Contact Email', 'meta-tag-manager'), 'mtm_schema_contact_email', $schema['Contact']['email'], '', 'contact@yoursite.com'); + ?> + +
        + 'mtm_schema_contact_page', 'selected'=> $contact_page_id, 'show_option_none'=> esc_html__('Custom URL', 'meta-tag-manager') )); ?> +
        + + +

        +

        +

        + + '', 'instagram' => '', 'linkedin' => '', 'twitter' => ''); + $schema['profiles'] = empty($schema['profiles']) ? $default_profiles : array_merge($default_profiles, $schema['profiles']); + mtm_input_text( 'Facebook', 'mtm_schema_profiles[facebook]', $schema['profiles']['facebook'], '', 'https://facebook.com/username'); + mtm_input_text( 'Twitter', 'mtm_schema_profiles[twitter]', $schema['profiles']['twitter'], '', 'https://twitter.com/username'); + mtm_input_text( 'Instagram', 'mtm_schema_profiles[instagram]', $schema['profiles']['instagram'], '', 'https://instagram.com/username'); + mtm_input_text( 'LinkedIn', 'mtm_schema_profiles[linkedin]', $schema['profiles']['linkedin'], '', 'https://www.linkedin.com/in/username'); + foreach( $schema['profiles'] as $k => $v ){ + if( is_numeric($k) ){ + ?> + + + + + + + + + +
        + + + + +
        + + + + +
        + + + +

        +

        + + esc_html__('No Sitelinks Map', 'meta-tag-manager') ); + foreach( $menus as $menu ){ + $nav_menus[$menu->term_id] = $menu->name; + } + $description = esc_html__("Choose a menu containing the links you'd like Google to include in Sitelinks. This can be a menu you already have, or preferably a dedicated menu for sitelinks. It is not guaranteed they'll use them, but it will certainly increase the chances of them doing so. %s", 'meta-tag-manager'); + $description = sprintf( $description, ''. esc_html__('Learn more', 'meta-tag-manager') .''); + mtm_input_select( esc_html__('Sitelinks Map', 'meta-tag-manager'), 'mtm_schema_sitelinks_menu', $nav_menus, $schema['sitelinks']['menu'], $description); + + $description = esc_html__("Google can choose to display a search box below your search result, directly allowing users to search your site. You can choose to enable this or specifically ask Google not to include it. %s", 'meta-tag-manager'); + $description = sprintf( $description, ''. esc_html__('Learn more', 'meta-tag-manager') .''); + $search_options = array( 0 => esc_html__('Enable or Disable', 'meta-tag-manager'), 1 => esc_html__('Enable Sitelinks Search', 'meta-tag-manager'), 2 => esc_html__('Disable Sitelinks Search', 'meta-tag-manager') ); + mtm_input_select( esc_html__('Enable Sitelinks Searchbox?', 'meta-tag-manager'), 'mtm_schema_sitelinks_search', $search_options, $schema['sitelinks']['search'], $description) + ?> + + + + window.open("'. $test_url_google .'");'; + if( !empty($_GET['schema_test']) && $_GET['schema_test'] == 'schema.org' ) echo ''; + ?> +
        +

        + + + + + +

        \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/settings/sidebar.php b/html/wp-content/plugins/meta-tag-manager/admin/settings/sidebar.php new file mode 100644 index 0000000..53afa0f --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/settings/sidebar.php @@ -0,0 +1,40 @@ + +
        +
        + +

        + +

        +
        +

        + Marcus Sykes'); ?> +

        +

        + ★★★★★', + 'WordPress.org' + ); + ?> +

        +
        +
        +
        + +

        + +

        +
        +

        + '.esc_html__('Support Forum','meta-tag-manager').''); ?> +

        +
        +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/admin/settings/verify-sites.php b/html/wp-content/plugins/meta-tag-manager/admin/settings/verify-sites.php new file mode 100644 index 0000000..e7a9e76 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/admin/settings/verify-sites.php @@ -0,0 +1,20 @@ + +

        +

        +

        +

        contents="..."', '<meta name="google-site-verification" contents="your_unique_id" />'); ?>

        + + +
        + + \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/classes/open-graph-admin.php b/html/wp-content/plugins/meta-tag-manager/classes/open-graph-admin.php new file mode 100644 index 0000000..a31d8b3 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/classes/open-graph-admin.php @@ -0,0 +1,24 @@ + false); + } else { + $og['enabled'] = true; + $og['generate_singular'] = !empty($_REQUEST['mtm_og_generate_singular']); + if( !empty($_REQUEST['mtm_og_site_title']) ) $og['home']['title'] = sanitize_text_field($_REQUEST['mtm_og_site_title']); + if( !empty($_REQUEST['mtm_og_site_description']) ) $og['home']['description'] = sanitize_text_field($_REQUEST['mtm_og_site_description']); + if( !empty($_REQUEST['mtm_og_site_logo']) ) $og['home']['image'] = absint($_REQUEST['mtm_og_site_logo']); + $og['twitter'] = array('enabled' => !empty($_REQUEST['mtm_og_twitter_enabled'])); + if( $og['twitter']['enabled'] ){ + if( !empty($_REQUEST['mtm_og_twitter_site']) && preg_match('/^@[a-zA-Z0-9_]{4,15}$/', $_REQUEST['mtm_og_twitter_site']) ) $og['twitter']['site'] = sanitize_text_field($_REQUEST['mtm_og_twitter_site']); + if( !empty($_REQUEST['mtm_og_twitter_creator']) && preg_match('/^@[a-zA-Z0-9_]{4,15}$/', $_REQUEST['mtm_og_twitter_creator']) ) $og['twitter']['creator'] = sanitize_text_field($_REQUEST['mtm_og_twitter_creator']); + } + } + return $og; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/classes/open-graph.php b/html/wp-content/plugins/meta-tag-manager/classes/open-graph.php new file mode 100644 index 0000000..27dbeeb --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/classes/open-graph.php @@ -0,0 +1,88 @@ + $v ){ + if( empty($v) ) continue; + $this_page[] = array('type' => 'name', 'value' => 'og:'.$k, 'content' => $v, 'context' => 'home'); + } + if( !empty($og['twitter']['enabled']) ){ + $this_page[] = array('type' => 'name', 'value' => 'twitter:card', 'content' => 'summary', 'context' => 'home'); + if( !empty($og['twitter']['site']) ) $this_page[] = array('type' => 'name', 'value' => 'twitter:site', 'content' => $og['twitter']['site'], 'context' => 'home'); + if( !empty($og['twitter']['creator']) ) $this_page[] = array('type' => 'name', 'value' => 'twitter:creator', 'content' => $og['twitter']['creator'], 'context' => 'home'); + } + foreach( array_reverse($this_page) as $tag_array ){ + $meta_tag = new MTM_Tag($tag_array); + array_unshift($mtm_tags, $meta_tag); + } + }elseif( !empty($og['generate_singular']) && is_singular() ){ + // generate og tags based on current page + $this_page = array( + 'og:type' => 'webssite', + 'og:title' => get_the_title(), + 'og:description' => get_the_excerpt(), + 'og:image' => get_the_post_thumbnail_url(), + 'og:locale' => determine_locale(), + 'og:site_name' => $og['home']['site_name'], + ); + if( !empty($og['twitter']['enabled']) ){ + $this_page['twitter:card'] = 'summary'; + if( !empty($og['twitter']['site']) ) $this_page['twitter:site'] = $og['twitter']['site']; + if( !empty($og['twitter']['creator']) ) $this_page['twitter:site'] = $og['twitter']['creator']; + } + foreach( array_reverse( $this_page ) as $k => $v ){ + $tag_array = array('type' => 'name', 'value' => $k, 'content' => $v, 'context' => 'post-type_'.get_post_type() ); + $meta_tag = new MTM_Tag($tag_array); + array_unshift($mtm_tags, $meta_tag); + } + } + return $mtm_tags; + } + + public static function get_options( $defaults = null ){ + $mtm_custom = get_option('mtm_custom'); + if( $defaults === null ) { + return !empty($mtm_custom['og']) ? $mtm_custom['og'] : false; + }else{ + $locale = (function_exists('determine_locale')) ? determine_locale() : get_locale(); + $og = array( + 'enabled' => false, + 'generate_singular' => false, + 'home' => array( + 'type' => 'website', + 'title' => get_bloginfo('name'), + 'description' => get_bloginfo('description'), + 'image' => get_theme_mod( 'custom_logo' ), + 'locale' => $locale, + 'site_name' => get_bloginfo('name'), + ), + 'twitter' => array( + 'enabled' => true, // enabled if og is enabled, no harm + 'site' => '', + 'creator' => '', + ) + ); + if( !$defaults ){ + $og = empty($mtm_custom['og']) ? $og : Meta_Tag_Manager::array_merge($og, $mtm_custom['og']); + $og['home']['site_name'] = $og['home']['title']; + } + } + return $og; + } +} +Open_Graph::init(); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/classes/schema-admin.php b/html/wp-content/plugins/meta-tag-manager/classes/schema-admin.php new file mode 100644 index 0000000..32e0fae --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/classes/schema-admin.php @@ -0,0 +1,54 @@ +add( sprintf(esc_html__('You must select a value in the %s field in the %s tab in order for schema markup to show up on your homepage.', 'meta-tag-manager'), ''.esc_html__('This website represents a', 'meta-tag-manager').'', ''.esc_html__('Structured Data (Schema)', 'meta-tag-manager').''), 'errors', true ); + } + if( !empty($_REQUEST['mtm_schema_site_logo']) ) $schema['logo'] = absint($_REQUEST['mtm_schema_site_logo']); + if( $schema['type'] == 'Person' ){ + if( !empty($_REQUEST['mtm_schema_person_name']) ) $schema['name'] = sanitize_text_field($_REQUEST['mtm_schema_person_name']); + }elseif( $schema['type'] == 'Organization' ) { + if( !empty($_REQUEST['mtm_schema_organization_name']) ) $schema['name'] = sanitize_text_field($_REQUEST['mtm_schema_organization_name']); + if( !empty($_REQUEST['mtm_schema_site_type_organization']) ) $schema['Organization']['type'] = sanitize_text_field($_REQUEST['mtm_schema_site_type_organization']); + if( !empty($_REQUEST['mtm_schema_site_type_organization_specific_'. $schema['Organization']['type']]) ) { + $schema['Organization']['subtype'] = sanitize_text_field($_REQUEST['mtm_schema_site_type_organization_specific_' . $schema['Organization']['type']]); + }else { + $schema['Organization']['subtype'] = $schema['Organization']['type']; + } + } + $schema['Contact']['enabled'] = !empty($_REQUEST['mtm_schema_contact']); + if( $schema['Contact']['enabled'] ) { + if( !empty($_REQUEST['mtm_schema_contact_name']) ) $schema['Contact']['name'] = sanitize_text_field($_REQUEST['mtm_schema_contact_name']); + if( !empty($_REQUEST['mtm_schema_contact_page']) ) { + $schema['Contact']['url'] = absint($_REQUEST['mtm_schema_contact_page']); + }elseif( !empty($_REQUEST['mtm_schema_contact_url']) ) { + $schema['Contact']['url'] = esc_url_raw($_REQUEST['mtm_schema_contact_url']); + } + if( !empty($_REQUEST['mtm_schema_contact_telephone']) ) $schema['Contact']['telephone'] = sanitize_text_field($_REQUEST['mtm_schema_contact_telephone']); + if( !empty($_REQUEST['mtm_schema_contact_email']) ) $schema['Contact']['email'] = sanitize_email($_REQUEST['mtm_schema_contact_email']); + } + if( isset($_REQUEST['mtm_schema_sitelinks_menu']) ) $schema['sitelinks']['menu'] = absint($_REQUEST['mtm_schema_sitelinks_menu']); + if( !empty($_REQUEST['mtm_schema_sitelinks_search']) ) $schema['sitelinks']['search'] = absint($_REQUEST['mtm_schema_sitelinks_search']); + if( !empty($_REQUEST['mtm_schema_profiles']) && is_array($_REQUEST['mtm_schema_profiles']) ){ + $schema['profiles'] = array(); + foreach( $_REQUEST['mtm_schema_profiles'] as $k => $profile ){ + if( !empty($profile) && !in_array($profile, $schema['profiles']) ){ + if( is_numeric($k) ){ + $schema['profiles'][] = esc_url_raw($profile); + }else{ + $k = sanitize_key($k); + $schema['profiles'][$k] = esc_url_raw($profile); + } + } + } + } + return $schema; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/classes/schema.php b/html/wp-content/plugins/meta-tag-manager/classes/schema.php new file mode 100644 index 0000000..faacee4 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/classes/schema.php @@ -0,0 +1,162 @@ + + + + '."\n\t\t\t"; + echo static::output_sitelinks_search(); + echo "\n\t\t".''; + }else{ + echo ''; + } + } + if( !empty($schema_options['sitelinks']['menu']) ){ + $sitelinks = static::output_sitelinks(); + if( !empty($sitelinks) ){ + echo "\n\t\t".''; + } + } + echo "\n"; + ?> + + 'https://schema.org'); + // get the type of + $schema['@type'] = esc_js($schema_options['type']); + $schema['name'] = esc_js($schema_options['name']); + $schema['url'] = get_site_url(); + if( $schema_options['type'] == 'Organization' && !empty($schema_options['Organization']['subtype']) ){ + $schema['@type'] = esc_js($schema_options['Organization']['subtype']); + } + if( !empty($schema_options['logo']) ){ + $image = wp_get_attachment_image_src( $schema_options['logo'], 'full' ); + if( $image ){ + $schema['logo'] = array( + '@type' => 'ImageObject', + 'url' => $image[0], + 'width' => $image[1], + 'height' => $image[2], + ); + } + } + if( !empty($schema_options['Contact']['enabled']) ){ + $schema['ContactPoint'] = array( + '@type' => 'ContactPoint', + 'contactType' => esc_js($schema_options['Contact']['name']), + ); + if( !empty($schema_options['Contact']['telephone']) ) $schema['ContactPoint']['telephone'] = esc_js($schema_options['Contact']['telephone']); + if( !empty($schema_options['Contact']['email']) ) $schema['ContactPoint']['email'] = esc_js($schema_options['Contact']['email']); + if( !empty($schema_options['Contact']['url']) ){ + if( is_numeric($schema_options['Contact']['url']) ){ + $schema['ContactPoint']['url'] = get_permalink($schema_options['Contact']['url']); + }else{ + $schema['ContactPoint']['url'] = esc_url($schema_options['Contact']['url']); + } + } + } + if( !empty($schema_options['profiles']) ){ + $schema['sameAs'] = array(); + foreach( $schema_options['profiles'] as $profile ){ + $schema['sameAs'][] = esc_url($profile); + } + } + return json_encode($schema); + } + + public static function output_sitelinks(){ + $schema_options = static::get_options(); + if( !empty($schema_options['sitelinks']['menu']) ){ + $menu_items = wp_get_nav_menu_items($schema_options['sitelinks']['menu']); + if( !empty($menu_items) ){ + $schema = array ( + '@context' => 'https://schema.org', + '@graph' => array (), + ); + foreach( $menu_items as $menu_item ){ + $schema['@graph'][] = array ( + '@context' => 'https://schema.org', + '@type' => 'SiteNavigationElement', + 'id' => 'site-navigation', + 'name' => $menu_item->title, + 'url' => esc_js(esc_url($menu_item->url)), + ); + } + return json_encode($schema); + } + } + return ''; + } + + public static function output_sitelinks_search(){ + $schema = array ( + '@context' => 'https://schema.org', + '@type' => 'WebSite', + 'name' => get_bloginfo('name'), + 'url' => get_site_url(), + 'potentialAction' => + array ( + 0 => + array ( + '@type' => 'SearchAction', + 'target' => home_url( '?s={search_term_string}' ), + 'query-input' => 'required name=search_term_string', + ), + ), + ); + return json_encode($schema); + } + + public static function get_options( $defaults = false ){ + $mtm_custom = get_option('mtm_custom'); + $schema_default = array( + 'enabled' => false, + 'type' => '', + 'logo' => 0, + 'name' => '', + 'Organization' => array( + 'type' => 'Organization', + 'subtype' => 'Organization', + ), + 'Contact' => array( + 'enabled' => 0, + 'name' => '', + 'telephone' => '', + 'url' => '', + 'email' => '', + ), + 'sitelinks' => array( + 'menu' => null, + 'search' => null, + ), + 'profiles' => array(), + ); + return empty($mtm_custom['schema']) || $defaults ? $schema_default : Meta_Tag_Manager::array_merge($schema_default, $mtm_custom['schema']); + } + +} +Schema::init(); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/classes/verify-sites-admin.php b/html/wp-content/plugins/meta-tag-manager/classes/verify-sites-admin.php new file mode 100644 index 0000000..0708374 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/classes/verify-sites-admin.php @@ -0,0 +1,20 @@ + $value ){ + if( !empty($_REQUEST['mtm_verify_sites_'.$site]) ){ + if( preg_match('/content=(["][^"]+|[\'][^\']+)/', wp_unslash($_REQUEST['mtm_verify_sites_'.$site]), $match) ){ + $verify_sites[$site] = substr($match[1], 1); + }else{ + $verify_sites[$site] = sanitize_text_field($_REQUEST['mtm_verify_sites_'.$site]); + } + } + } + return $verify_sites; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/classes/verify-sites.php b/html/wp-content/plugins/meta-tag-manager/classes/verify-sites.php new file mode 100644 index 0000000..f976978 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/classes/verify-sites.php @@ -0,0 +1,52 @@ + $site_key ){ + if( !empty($sites[$site]) ) { + $mtm_tags[] = new MTM_Tag(array('type' => 'name', 'value' => $sites[$site], 'content' => $site_key, 'context' => 'home')); + } + } + } + return $mtm_tags; + } + + public static function get_sites(){ + return array( + 'google' => 'google-site-verification', + 'bing' => 'msvalidate.01', // https://www.bing.com/webmasters/help/add-and-verify-site-12184f8b + 'facebook' => 'facebook-domain-verification', + 'pintrest' => 'p:domain_verify', // https://help.pinterest.com/en/business/article/claim-your-website#section-12101 + 'sitelock' => 'sitelock-site-verification', + 'yandex' => 'yandex-verification', // https://yandex.com/support/webmaster/service/rights.html + ); + } + + public static function get_options( $defaults = null ){ + $mtm_custom = get_option('mtm_custom'); + if( $defaults === null ) { + return !empty($mtm_custom['verify']) ? $mtm_custom['verify'] : false; + }else{ + $verify = static::get_sites(); + foreach( $verify as $k => $v ) $verify[$k] = ''; // empty string it + if( !$defaults ){ + $verify = empty($mtm_custom['verify']) ? $verify : Meta_Tag_Manager::array_merge($verify, $mtm_custom['verify']); + } + } + return $verify; + } +} +Verify_Sites::init(); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.css b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.css new file mode 100644 index 0000000..64a3f5c --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.css @@ -0,0 +1,919 @@ +/* .mtm.postbox { background-color:#dedede;} */ +.mtm-menu-builder { + margin-bottom: 15px; +} +.mtm-field-template { + display: none; + visibility: hidden; +} +.mtm-field-placeholder { + width: 100%; + border: 1px dashed #aaa; + background-color: #ddd; + font-size: 18px; + padding: 30px 0px; + color: #555; + text-align: center; + margin: 10px 0px; + cursor: pointer; +} +.no-reference.no-context .mtm-field-placeholder { + padding: 20px 0px; +} +.mtm-field { + display: block; + clear: both; + width: 100%; + border: 1px solid #c3c3c3; + background-color: #fff; + margin: 10px 0px; +} +.mtm-field.closed .mtm-field-data { + display: none; + visibility: hidden; +} +.mtm-field .mtm-field-actions { + clear: both; +} +/* Field Header / Title section */ +.mtm-field-header { + padding: 10px 0px; + cursor: pointer; +} +.mtm-col-sort { + display: block; + float: left; + width: 20px; + height: 20px; + padding: 10px 0px 0px 10px; + margin: 0px; + font-size: 20px; + align: center; + cursor: move; + color: #dedede; +} +.no-reference.no-context .mtm-col-sort { + padding: 0px 0px 0px 10px; +} +/* Display Title for each Card */ +.mtm-field-title { + margin-left: 40px; + min-height: 50px; +} +.no-reference.no-context .mtm-field-title { + min-height: 20px; +} +.mtm-field-title .mtm-meta-reference { + font-size: 18px; + padding-bottom: 5px; +} +.mtm-field-title .mtm-meta-reference-value { + display: inline-block; +} +.mtm-field-title .mtm-meta-context { + font-size: 12px; + padding-bottom: 3px; + color: #bcbcbc; + font-weight: bold; + font-style: italic; +} +.mtm-field-title .mtm-meta-context .dashicons { + font-size: 15px; + vertical-align: baseline; +} +.mtm-field-title code { + font-weight: bold; +} +.mtm-field-title code .mtm-meta-type-val, +.mtm-field-title code .mtm-meta-content-value { + font-style: italic; + font-weight: normal; + background-color: #fefefe; +} +.mtm-field-title code .mtm-meta-content.hidden { + display: none; +} +/* Header toggles */ +.mtm-field-header-toggle:hover, +.mtm-field-section-toggle:hover { + cursor: pointer; +} +.mtm-field-header-toggle:before, +.mtm-field-section-toggle:before { + float: right; + width: 32px; + height: 32px; + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.mtm-field.closed .mtm-field-header-toggle:before { + content: "\f140"; +} +/* Field form data */ +.mtm-field-data { + /* display: none; */ + border-top: 1px solid #e5e5e5; + padding: 10px 10px 15px; +} +.mtm-field-input { + margin: 0px 0px 15px 0px; + clear: both; +} +.mtm-field-input-label { + display: inline-block; + margin-bottom: 3px; + padding: 2px; + font-weight: bold; + display: block; +} +.mtm-field-input-label em { + font-style: normal; + background: #eaeaea; + padding: 1px 2px; +} +.mtm-field-input input, +.mtm-field-input select { + width: 100%; + padding: 4px; + font-size: 13px; + /* matches selectize */ +} +.mtm-field-type-custom { + clear: both; +} +.mtm-field-type-custom > div { + clear: none; + float: left; + width: 48%; + margin: 10px 1%; +} +/* Specific type field selectors */ +.mtm-field-input.mtm-field-type-type { + width: 20%; + float: left; + clear: none; +} +.mtm-field-input.mtm-field-type-value { + width: 79% !important; + margin-left: 21%; + clear: none; +} +.mtm-field-input input.mtm-field-input-tag-value { + float: left; + clear: none; +} +.mtm-field-section { + margin-top: 20px; +} +.mtm-field-section-header { + border-bottom: 1px solid #e3e3e3; + padding-bottom: 10px; +} +.mtm-field-section-title { + font-weight: bold; + font-size: 15px; +} +.mtm-field-section-data { + margin: 10px 10px 20px; + padding-bottom: 10px; + border-bottom: 1px solid #e3e3e3; +} +/*.mtm-builder .selectize-input { padding:4px; }*/ +.mtm-settings .selectize-dropdown-content .optgroup .option { + padding-left: 10px; +} +.mtm-settings .selectize-dropdown-content .optgroup .optgroup-header { + font-weight: bold; +} +.mtm-settings .selectize-control.multi .selectize-input > .item { + background: #5cb85c; + border-color: #4cae4c; + color: #fff; +} +.mtm-settings .selectize-control.multi .selectize-input > .item .remove { + border-color: #4cae4c; +} +.mtm-builder .mtm-field button.mtm-field-remove { + background-color: #f4e3e3; + border-color: #d8c5c5; + color: #565656; +} +.mtm-builder .mtm-field a.mtm-field-remove { + cursor: pointer; + color: #d66b6b; +} +.mtm-builder button .dashicons { + padding: 3px 0px; + margin-left: -5px; + color: #888; +} +.mtm-builder button.mtm-add-field .dashicons { + padding: 4px 0px; +} +.mtm-builder .mtm-actions { + padding-top: 15px; +} +/* Settings Page */ +.mtm-settings select:invalid { + color: gray; +} +.mtm-settings h3 { + border-top: 1px solid #dedede; + padding-top: 25px; + margin-top: 20px; +} +.mtm-settings .postbox .handlediv { + display: none; + visibility: hidden; +} +.mtm-settings .postbox .inside { + border-top: 1px solid #dedede; + margin-top: 0px; + padding-top: 10px; +} +.mtm-settings .postbox h3 { + font-size: 16px; +} +.mtm-settings .postbox td, +.mtm-settings .postbox th { + vertical-align: top; +} +.mtm-settings .postbox th { + padding: 15px 20px; + margin: 0 !important; + font-size: 0.97em; +} +.mtm-settings .postbox .mtm-boxheader { + font-style: italic; + margin: 0; + padding: 10px 5px; +} +.mtm-settings .postbox tr.mtm-header td { + font-style: italic; + padding: 10px 5px; + margin: 0; +} +.mtm-settings .postbox tr.mtm-header h4, +.mtm-settings .postbox .postbox h4 { + font-weight: bold; + font-size: 15px; + font-style: normal; + border-bottom: 1px solid #dedede; + margin: 0 0 10px; + padding: 0 0 10px; +} +.mtm-settings .postbox tr.mtm-subheader td { + font-style: italic; + margin: 0; + padding: 5px 20px 2px; +} +.mtm-settings .postbox tr.mtm-subheader h5 { + font-style: normal; + margin: 10px 0; + padding: 0 0 5px; + font-weight: bold; + font-size: 15px; + border-bottom: 1px solid #efefef; + color: #000; +} +/* Schema Settings */ +.mtm-settings .mtm-image-upload-preview { + margin-bottom: 10px; +} +.mtm-settings #mtm_schema_profiles_other_row { + display: none; +} +.mtm-settings .mtm-schema-profiles-other a.mtm-schema-profile-remove { + text-decoration: none; + color: black; +} +/* Go Pro Stuff */ +.mtm-settings table.features { + border-spacing: 0; + border: 1px solid #dedede; +} +.mtm-settings table.features th, +table.features td { + background: #fff; + border: 0; + border-bottom: 1px solid #dedede; + padding: 5px; +} +.mtm-settings table.features tbody tr { + border-bottom: 1px solid #EFEFEF; +} +.mtm-settings table.features tbody tr:first-child th { + background: #EFEFEF; +} +.mtm-settings table.features tbody th { + text-align: left; + padding-left: 10px; +} +.mtm-settings table.features tr th:not(:first-child), +table.features tr td:not(:first-child) { + width: 150px; + padding-left: 10px; + padding-right: 10px; + text-align: center; +} +.mtm-settings table.features .dashicons-yes-alt { + color: darkgreen; + font-size: 20px; +} +.mtm-settings table.features tfoot th span { + display: block; + margin-bottom: 5px; + color: #8bc976; + font-size: 18px; +} +.mtm-settings table.features tfoot th span.deal { + color: #FC9840; + font-size: 14px; +} +.mtm-settings table.features tbody th[data-title] { + cursor: pointer; +} +/*! Tippy.js v6.2.7 - https://unpkg.com/tippy.js@6.2.7/themes/light-border.css */ +.tippy-box[data-theme~=light-border] { + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 8, 16, 0.15); + color: #333; + box-shadow: 0 4px 14px -2px rgba(0, 8, 16, 0.08); +} +.tippy-box[data-theme~=light-border] > .tippy-backdrop { + background-color: #fff; +} +.tippy-box[data-theme~=light-border] > .tippy-arrow:after, +.tippy-box[data-theme~=light-border] > .tippy-svg-arrow:after { + content: ""; + position: absolute; + z-index: -1; +} +.tippy-box[data-theme~=light-border] > .tippy-arrow:after { + border-color: transparent; + border-style: solid; +} +.tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-arrow:before { + border-top-color: #fff; +} +.tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-arrow:after { + border-top-color: rgba(0, 8, 16, 0.2); + border-width: 7px 7px 0; + top: 17px; + left: 1px; +} +.tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-svg-arrow > svg { + top: 16px; +} +.tippy-box[data-theme~=light-border][data-placement^=top] > .tippy-svg-arrow:after { + top: 17px; +} +.tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-arrow:before { + border-bottom-color: #fff; + bottom: 16px; +} +.tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-arrow:after { + border-bottom-color: rgba(0, 8, 16, 0.2); + border-width: 0 7px 7px; + bottom: 17px; + left: 1px; +} +.tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-svg-arrow > svg { + bottom: 16px; +} +.tippy-box[data-theme~=light-border][data-placement^=bottom] > .tippy-svg-arrow:after { + bottom: 17px; +} +.tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-arrow:before { + border-left-color: #fff; +} +.tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-arrow:after { + border-left-color: rgba(0, 8, 16, 0.2); + border-width: 7px 0 7px 7px; + left: 17px; + top: 1px; +} +.tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-svg-arrow > svg { + left: 11px; +} +.tippy-box[data-theme~=light-border][data-placement^=left] > .tippy-svg-arrow:after { + left: 12px; +} +.tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-arrow:before { + border-right-color: #fff; + right: 16px; +} +.tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-arrow:after { + border-width: 7px 7px 7px 0; + right: 17px; + top: 1px; + border-right-color: rgba(0, 8, 16, 0.2); +} +.tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-svg-arrow > svg { + right: 11px; +} +.tippy-box[data-theme~=light-border][data-placement^=right] > .tippy-svg-arrow:after { + right: 12px; +} +.tippy-box[data-theme~=light-border] > .tippy-svg-arrow { + fill: #fff; +} +.tippy-box[data-theme~=light-border] > .tippy-svg-arrow:after { + background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=); + background-size: 16px 6px; + width: 16px; + height: 6px; +} +.mtm-builder { + .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #fff; + box-shadow: inset 0 0 12px 4px #fff; +} +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; +} +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} +.selectize-dropdown-header { + position: relative; + padding: 5px 8px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.selectize-dropdown-header-close { + position: absolute; + right: 8px; + top: 50%; + color: #303030; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: #000000; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 2px 0 0 0; + border-left: 1px solid #d0d0d0; + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: #cacaca; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: #ffffff; +} +.selectize-control.plugin-remove_button .remove-single { + position: absolute; + right: 0; + top: 0; + font-size: 23px; +} +.selectize-control { + position: relative; +} +.selectize-dropdown, +.selectize-input, +.selectize-input input { + color: #303030; + font-family: inherit; + font-size: 13px; + line-height: 18px; + -webkit-font-smoothing: inherit; +} +.selectize-input, +.selectize-control.single .selectize-input.input-active { + background: #fff; + cursor: text; + display: inline-block; +} +.selectize-input { + border: 1px solid #d0d0d0; + padding: 8px 8px; + display: inline-block; + width: 100%; + overflow: hidden; + position: relative; + z-index: 1; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.selectize-control.multi .selectize-input.has-items { + padding: 6px 8px 3px; +} +.selectize-input.full { + background-color: #fff; +} +.selectize-input.disabled, +.selectize-input.disabled * { + cursor: default !important; +} +.selectize-input.focus { + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); +} +.selectize-input.dropdown-active { + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.selectize-input > * { + vertical-align: baseline; + display: -moz-inline-stack; + display: inline-block; + zoom: 1; + *display: inline; +} +.selectize-control.multi .selectize-input > div { + cursor: pointer; + margin: 0 3px 3px 0; + padding: 2px 6px; + background: #f2f2f2; + color: #303030; + border: 0 solid #d0d0d0; +} +.selectize-control.multi .selectize-input > div.active { + background: #e8e8e8; + color: #303030; + border: 0 solid #cacaca; +} +.selectize-control.multi .selectize-input.disabled > div, +.selectize-control.multi .selectize-input.disabled > div.active { + color: #7d7d7d; + background: #ffffff; + border: 0 solid #ffffff; +} +.selectize-input > input { + display: inline-block !important; + padding: 0 !important; + min-height: 0 !important; + max-height: none !important; + max-width: 100% !important; + margin: 0 2px 0 0 !important; + text-indent: 0 !important; + border: 0 none !important; + background: none !important; + line-height: inherit !important; + -webkit-user-select: auto !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} +.selectize-input > input::-ms-clear { + display: none; +} +.selectize-input > input:focus { + outline: none !important; +} +.selectize-input > input[placeholder] { + box-sizing: initial; +} +.selectize-input::after { + content: ' '; + display: block; + clear: left; +} +.selectize-input.dropdown-active::before { + content: ' '; + display: block; + position: absolute; + background: #f0f0f0; + height: 1px; + bottom: 0; + left: 0; + right: 0; +} +.selectize-dropdown { + position: absolute; + z-index: 10; + border: 1px solid #d0d0d0; + background: #fff; + margin: -1px 0 0 0; + border-top: 0 none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} +.selectize-dropdown [data-selectable] { + cursor: pointer; + overflow: hidden; +} +.selectize-dropdown [data-selectable] .highlight { + background: rgba(125, 168, 208, 0.2); + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; +} +.selectize-dropdown .option, +.selectize-dropdown .optgroup-header { + padding: 5px 8px; +} +.selectize-dropdown .option, +.selectize-dropdown [data-disabled], +.selectize-dropdown [data-disabled] [data-selectable].option { + cursor: inherit; + opacity: 0.5; +} +.selectize-dropdown [data-selectable].option { + opacity: 1; +} +.selectize-dropdown .optgroup:first-child .optgroup-header { + border-top: 0 none; +} +.selectize-dropdown .optgroup-header { + color: #303030; + background: #fff; + cursor: default; +} +.selectize-dropdown .active { + background-color: #f5fafd; + color: #495c68; +} +.selectize-dropdown .active.create { + color: #495c68; +} +.selectize-dropdown .create { + color: rgba(48, 48, 48, 0.5); +} +.selectize-dropdown-content { + overflow-y: auto; + overflow-x: hidden; + max-height: 200px; + -webkit-overflow-scrolling: touch; +} +.selectize-control.single .selectize-input, +.selectize-control.single .selectize-input input { + cursor: pointer; +} +.selectize-control.single .selectize-input.input-active, +.selectize-control.single .selectize-input.input-active input { + cursor: text; +} +.selectize-control.single .selectize-input:after { + content: ' '; + display: block; + position: absolute; + top: 50%; + right: 15px; + margin-top: -3px; + width: 0; + height: 0; + border-style: solid; + border-width: 5px 5px 0 5px; + border-color: #808080 transparent transparent transparent; +} +.selectize-control.single .selectize-input.dropdown-active:after { + margin-top: -4px; + border-width: 0 5px 5px 5px; + border-color: transparent transparent #808080 transparent; +} +.selectize-control.rtl.single .selectize-input:after { + left: 15px; + right: auto; +} +.selectize-control.rtl .selectize-input > input { + margin: 0 4px 0 -2px !important; +} +.selectize-control .selectize-input.disabled { + opacity: 0.5; + background-color: #fafafa; +} +/*# sourceMappingURL=selectize.css.map */ +} +.mtm-modal-overlay { + display: none; +} +.mtm-modal-overlay.active { + display: block !important; +} +@media only screen and (min-width: 40rem) { + .mtm-modal-overlay { + align-items: center !important; + justify-content: center !important; + position: fixed !important; + top: 0 !important; + left: 0 !important; + width: 100% !important; + height: 100% !important; + z-index: 99998 !important; + background-color: rgba(0, 0, 0, 0.6) !important; + opacity: 0 !important; + visibility: hidden !important; + backface-visibility: hidden !important; + transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important; + -webkit-transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important; + transition-delay: 0.3s !important; + } + .mtm-modal-overlay.active { + display: flex !important; + opacity: 1 !important; + visibility: visible !important; + } +} +.mtm-modal-overlay .mtm-modal-popup { + align-items: start !important; + justify-content: center !important; + position: relative !important; + margin: 0 !important; + background-color: #fff !important; + width: 100% !important; + max-width: 750px !important; + min-height: 200px !important; + max-height: 98% !important; + padding: 10px !important; + border-radius: 3px !important; + opacity: 0 !important; + visibility: hidden !important; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1) !important; + backface-visibility: hidden !important; + transform: scale(1.2) !important; + transition: all 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important; + z-index: 99999 !important; + /** + * Mobile styling for popups + */ +} +.mtm-modal-overlay .mtm-modal-popup > header { + box-sizing: border-box; + width: 100%; + border-bottom: 1px solid #dedede; + margin: 0; + padding: 10px 0 7px 15px; +} +.mtm-modal-overlay .mtm-modal-popup > header .mtm-modal-title { + font-size: 24px !important; + line-height: 1.3 !important; + padding: 0 32px 0 0 !important; + margin: 0 !important; +} +.mtm-modal-overlay .mtm-modal-popup > header .mtm-modal-title a { + color: var(--text-color-normal) !important; +} +.mtm-modal-overlay .mtm-modal-popup > header .mtm-modal-title a:hover { + text-decoration: underline; +} +.mtm-modal-overlay .mtm-modal-popup .mtm-close-modal { + position: absolute !important; + cursor: pointer !important; + top: 15px !important; + right: 15px !important; + opacity: 0 !important; + backface-visibility: hidden !important; + transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important; + -webkit-transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1), visibility 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important; + transition-delay: 0.3s !important; +} +.mtm-modal-overlay .mtm-modal-popup svg { + width: 17.5px !important; + height: 17.5px !important; +} +.mtm-modal-overlay .mtm-modal-popup .mtm-modal-content { + opacity: 0 !important; + backface-visibility: hidden !important; + transition: opacity 0.6s cubic-bezier(0.55, 0, 0.1, 1) !important; + transition-delay: 0.3s !important; + width: 100% !important; + margin: 20px 5px 5px !important; +} +.mtm-modal-overlay .mtm-modal-popup .mtm-modal-content .mtm-form .mtm-title { + display: block !important; +} +.mtm-modal-overlay .mtm-modal-popup .mtm-modal-content form { + margin-bottom: 0 !important; +} +.mtm-modal-overlay .mtm-modal-popup.active { + visibility: visible !important; + opacity: 1 !important; + transform: scale(1) !important; +} +.mtm-modal-overlay .mtm-modal-popup.active .mtm-modal-content, +.mtm-modal-overlay .mtm-modal-popup.active .mtm-close-modal { + opacity: 1 !important; +} +.mtm-modal-overlay .mtm-modal-popup > footer { + width: 100% !important; + border-top: 1px solid #dedede !important; +} +.mtm-modal-overlay .mtm-modal-popup > footer > div { + padding: 10px 25px !important; +} +.mtm-modal-overlay .mtm-modal-popup > footer > div button, +.mtm-modal-overlay .mtm-modal-popup > footer > div .button { + margin: 0 !important; +} +@media only screen and (max-width: 39.99rem) { + .mtm-modal-overlay .mtm-modal-popup { + position: fixed !important; + top: 0 !important; + left: 0 !important; + width: 100% !important; + height: 100% !important; + max-height: 100% !important; + -webkit-overflow-scrolling: touch !important; + border-radius: 0 !important; + transform: scale(1.1) !important; + padding: 10px !important; + } + .mtm-modal-overlay .mtm-modal-popup .mtm-close-modal { + top: 0 !important; + right: 10px !important; + } + .mtm-modal-overlay .mtm-modal-popup .mtm-close-modal svg { + width: 28px !important; + height: 28px !important; + } +} +.mtm-admin-modal { + --font-size: 15px; + --line-height: 20px; +} +.mtm-admin-modal .mtm-modal-content p { + font-size: var(--font-size) !important; + line-height: var(--line-height) !important; + text-align: justify; +} +.mtm-admin-modal .mtm-modal-content.has-image { + display: grid; + grid-template-columns: auto minmax(80px, 150px); + grid-gap: 40px; +} +.mtm-admin-modal .mtm-modal-content.has-image > div.image { + text-align: center; +} +.mtm-admin-modal .mtm-modal-content.has-image > div.image img { + width: 100%; +} +/*# sourceMappingURL=meta-tag-manager.css.map */ \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.css.map b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.css.map new file mode 100644 index 0000000..4f6b029 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["meta-tag-manager.less","selectize/selectize.css"],"names":[],"mappings":";AACA;EAAoB,mBAAA;;AAGpB;EAAsB,aAAA;EAAc,kBAAA;;AAGpC;EACE,WAAA;EACA,uBAAA;EACA,sBAAA;EACA,eAAA;EACA,iBAAA;EACA,WAAA;EACA,kBAAA;EACA,gBAAA;EACA,eAAA;;AAEF,aAAa,WAAY;EAAyB,iBAAA;;AAElD;EACE,cAAA;EACA,WAAA;EACA,WAAA;EACA,yBAAA;EACA,sBAAA;EACA,gBAAA;;AAEF,UAAU,OAAQ;EAAkB,aAAA;EAAc,kBAAA;;AAElD,UAAW;EAAqB,WAAA;;;AAGhC;EACE,iBAAA;EACA,eAAA;;AAEF;EACE,cAAA;EACA,WAAA;EACA,WAAA;EACA,YAAA;EACA,0BAAA;EACA,WAAA;EACA,eAAA;EACA,aAAA;EACA,YAAA;EACA,cAAA;;AAEF,aAAa,WAAY;EAAgB,yBAAA;;;AAGzC;EAAmB,iBAAA;EAAkB,gBAAA;;AACrC,aAAa,WAAY;EAAmB,gBAAA;;AAC5C,gBAAiB;EAAsB,eAAA;EAAiB,mBAAA;;AACxD,gBAAiB;EAA4B,qBAAA;;AAE7C,gBAAiB;EACf,eAAA;EACA,mBAAA;EACA,cAAA;EACA,iBAAA;EACA,kBAAA;;AAEF,gBAAiB,kBAAkB;EAAa,eAAA;EAAgB,wBAAA;;AAEhE,gBAAiB;EAAO,iBAAA;;AACxB,gBAAiB,KAAK;AAAoB,gBAAiB,KAAK;EAC9D,kBAAA;EACA,mBAAA;EACA,yBAAA;;AAEF,gBAAiB,KAAK,kBAAiB;EAAU,aAAA;;;AAGjD,wBAAwB;AACxB,yBAAyB;EACvB,eAAA;;AAEF,wBAAwB;AACxB,yBAAyB;EACvB,YAAA;EACA,WAAA;EACA,YAAA;EACA,SAAS,OAAT;EACA,qBAAA;EACA,6BAAA;EACA,WAAA;EACA,mCAAA;EACA,kCAAA;EACA,gCAAA;;AAEF,UAAU,OAAQ,yBAAwB;EACxC,SAAS,OAAT;;;AAIF;;EAEE,6BAAA;EACA,uBAAA;;AAEF;EAAmB,wBAAA;EAAyB,WAAA;;AAC5C;EACE,qBAAA;EACA,kBAAA;EACA,YAAA;EACA,iBAAA;EACA,cAAA;;AAEF,sBAAuB;EAAK,kBAAA;EAAmB,mBAAA;EAAoB,gBAAA;;AACnE,gBAAiB;AAAO,gBAAiB;EACvC,WAAA;EACA,YAAA;EACA,eAAA;;;AAGF;EAAyB,WAAA;;AACzB,sBAAuB;EACrB,WAAA;EACA,WAAA;EACA,UAAA;EACA,eAAA;;;AAIF,gBAAgB;EACd,UAAA;EACA,WAAA;EACA,WAAA;;AAEF,gBAAgB;EACd,qBAAA;EACA,gBAAA;EACA,WAAA;;AAEF,gBAAiB,MAAK;EAA6B,WAAA;EAAY,WAAA;;AAI/D;EAAqB,gBAAA;;AACrB;EAA4B,gCAAA;EAAiC,oBAAA;;AAC7D;EAA2B,iBAAA;EAAkB,eAAA;;AAC7C;EAA0B,sBAAA;EAAuB,oBAAA;EAAqB,gCAAA;;;AAGtE,aAAc,4BAA4B,UAAU;EAAU,kBAAA;;AAC9D,aAAc,4BAA4B,UAAU;EAAmB,iBAAA;;AACvE,aAAc,mBAAkB,MAAO,iBAAiB;EAAU,mBAAA;EAAoB,qBAAA;EAAsB,WAAA;;AAC5G,aAAc,mBAAkB,MAAO,iBAAiB,QAAQ;EAAU,qBAAA;;AAE1E,YAAa,WAAW,OAAM;EAAoB,yBAAA;EAA0B,qBAAA;EAAsB,cAAA;;AAClG,YAAa,WAAW,EAAC;EAAoB,eAAA;EAAgB,cAAA;;AAC7D,YAAa,OAAO;EAAa,gBAAA;EAAkB,iBAAA;EAAmB,WAAA;;AACtE,YAAa,OAAM,cAAe;EAAa,gBAAA;;AAE/C,YAAa;EAAe,iBAAA;;;AAG5B,aAAc,OAAM;EAAW,WAAA;;AAC/B,aAAc;EAAK,6BAAA;EAA+B,iBAAA;EAAkB,gBAAA;;AACpE,aAAc,SAAS;EAAa,aAAA;EAAc,kBAAA;;AAClD,aAAc,SAAS;EAAU,6BAAA;EAA+B,eAAA;EAAgB,iBAAA;;AAChF,aAAc,SAAS;EAAK,eAAA;;AAC5B,aAAc,SAAS;AAAI,aAAc,SAAS;EAAK,mBAAA;;AACvD,aAAc,SAAS;EAAK,kBAAA;EAAoB,oBAAA;EAAqB,iBAAA;;AACrE,aAAc,SAAS;EAAiB,kBAAA;EAAmB,SAAA;EAAU,iBAAA;;AACrE,aAAc,SAAS,GAAE,WAAY;EAAK,kBAAA;EAAmB,iBAAA;EAAkB,SAAA;;AAC/E,aAAc,SAAS,GAAE,WAAY;AAAI,aAAc,SAAS,SAAS;EAAK,iBAAA;EAAkB,eAAA;EAAgB,kBAAA;EAAmB,gCAAA;EAAkC,gBAAA;EAAiB,iBAAA;;AACtL,aAAc,SAAS,GAAE,cAAe;EAAK,kBAAA;EAAmB,SAAA;EAAU,qBAAA;;AAC1E,aAAc,SAAS,GAAE,cAAe;EAAK,kBAAA;EAAmB,cAAA;EAAe,gBAAA;EAAiB,iBAAA;EAAkB,eAAA;EAAgB,gCAAA;EAAkC,WAAA;;;AAGpK,aAAc;EAA4B,mBAAA;;AAC1C,aAAc;EAAiC,aAAA;;AAC/C,aAAc,2BAA2B,EAAC;EAA6B,qBAAA;EAAuB,YAAA;;;AAG9F,aAAc,MAAK;EAAY,iBAAA;EAAmB,yBAAA;;AAClD,aAAc,MAAK,SAAU;AAAI,KAAK,SAAU;EAAK,gBAAA;EAAiB,SAAA;EAAU,gCAAA;EAAkC,YAAA;;AAClH,aAAc,MAAK,SAAU,MAAM;EAAK,gCAAA;;AACxC,aAAc,MAAK,SAAU,MAAM,GAAE,YAAa;EAAK,mBAAA;;AACvD,aAAc,MAAK,SAAU,MAAM;EAAM,gBAAA;EAAiB,kBAAA;;AAC1D,aAAc,MAAK,SAAU,GAAG,GAAE,IAAI;AAAgB,KAAK,SAAU,GAAG,GAAE,IAAI;EAAiB,YAAA;EAAa,kBAAA;EAAmB,mBAAA;EAAoB,kBAAA;;AACnJ,aAAc,MAAK,SAAU;EAAqB,gBAAA;EAAiB,eAAA;;AACnE,aAAc,MAAK,SAAU,MAAM,GAAG;EAAO,cAAA;EAAe,kBAAA;EAAmB,cAAA;EAAe,eAAA;;AAC9F,aAAc,MAAK,SAAU,MAAM,GAAG,KAAI;EAAQ,cAAA;EAAe,eAAA;;AACjE,aAAc,MAAK,SAAU,MAAM,GAAE;EAAe,eAAA;;;AAGpD,UAAU;EAA2B,sBAAA;EAAsB,4BAAA;EAA4B,sCAAA;EAAkC,WAAA;EAAW,gDAAA;;AAA4C,UAAU,0BAA0B;EAAiB,sBAAA;;AAAsB,UAAU,0BAA0B,eAAa;AAAO,UAAU,0BAA0B,mBAAiB;EAAO,SAAQ,EAAR;EAAW,kBAAA;EAAkB,WAAA;;AAAW,UAAU,0BAA0B,eAAa;EAAO,yBAAA;EAAyB,mBAAA;;AAAmB,UAAU,0BAA0B,qBAAqB,eAAa;EAAQ,sBAAA;;AAAsB,UAAU,0BAA0B,qBAAqB,eAAa;EAAO,qCAAA;EAAiC,uBAAA;EAAuB,SAAA;EAAS,SAAA;;AAAS,UAAU,0BAA0B,qBAAqB,mBAAiB;EAAK,SAAA;;AAAS,UAAU,0BAA0B,qBAAqB,mBAAiB;EAAO,SAAA;;AAAS,UAAU,0BAA0B,wBAAwB,eAAa;EAAQ,yBAAA;EAAyB,YAAA;;AAAY,UAAU,0BAA0B,wBAAwB,eAAa;EAAO,wCAAA;EAAoC,uBAAA;EAAuB,YAAA;EAAY,SAAA;;AAAS,UAAU,0BAA0B,wBAAwB,mBAAiB;EAAK,YAAA;;AAAY,UAAU,0BAA0B,wBAAwB,mBAAiB;EAAO,YAAA;;AAAY,UAAU,0BAA0B,sBAAsB,eAAa;EAAQ,uBAAA;;AAAuB,UAAU,0BAA0B,sBAAsB,eAAa;EAAO,sCAAA;EAAkC,2BAAA;EAA2B,UAAA;EAAU,QAAA;;AAAQ,UAAU,0BAA0B,sBAAsB,mBAAiB;EAAK,UAAA;;AAAU,UAAU,0BAA0B,sBAAsB,mBAAiB;EAAO,UAAA;;AAAU,UAAU,0BAA0B,uBAAuB,eAAa;EAAQ,wBAAA;EAAwB,WAAA;;AAAW,UAAU,0BAA0B,uBAAuB,eAAa;EAAO,2BAAA;EAA2B,WAAA;EAAW,QAAA;EAAQ,uCAAA;;AAAmC,UAAU,0BAA0B,uBAAuB,mBAAiB;EAAK,WAAA;;AAAW,UAAU,0BAA0B,uBAAuB,mBAAiB;EAAO,WAAA;;AAAW,UAAU,0BAA0B;EAAkB,UAAA;;AAAU,UAAU,0BAA0B,mBAAiB;EAAO,6UAAA;EAA6U,yBAAA;EAAyB,WAAA;EAAW,WAAA;;AAE/uF;EChMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AD3HA;EAME,aAAA;;AACA,kBAAC;EACC,yBAAA;;AAKF,wBAA0C;EAA1C;IACE,8BAAA;IACA,kCAAA;IACA,0BAAA;IACA,iBAAA;IACA,kBAAA;IACA,sBAAA;IACA,uBAAA;IACA,yBAAA;IACA,oCAAA;IACA,qBAAA;IACA,6BAAA;IACA,sCAAA;IACA,yBAtBO,+CAAA,6BAsBP;IACA,iCAvBO,+CAAA,6BAuBP;IACA,sBAAA;;EAEA,kBAAC;IACC,wBAAA;IACA,qBAAA;IACA,8BAAA;;;AAjCN,kBAsCE;EAEE,6BAAA;EACA,kCAAA;EACA,6BAAA;EACA,oBAAA;EACA,sBAAA;EACA,sBAAA;EACA,2BAAA;EACA,4BAAA;EACA,0BAAA;EACA,wBAAA;EACA,6BAAA;EACA,qBAAA;EAEA,6BAAA;EACA,yCAAA;EACA,sCAAA;EACA,WAAW,UAAX;EACA,qBArDO,6BAqDP;EACA,yBAAA;;;;;AA1DJ,kBAsCE,iBAuBE;EACE,sBAAA;EACA,WAAA;EACA,gCAAA;EACA,SAAA;EACA,wBAAA;;AAlEN,kBAsCE,iBAuBE,SAOE;EACE,0BAAA;EACA,gBAAA;EACA,8BAAA;EACA,oBAAA;;AAxER,kBAsCE,iBAuBE,SAOE,iBAME;EACE,OAAO,wBAAP;;AAEA,kBAvCR,iBAuBE,SAOE,iBAME,EAGG;EACC,0BAAA;;AA9EZ,kBAsCE,iBA+CE;EACE,6BAAA;EACA,0BAAA;EACA,oBAAA;EACA,sBAAA;EACA,qBAAA;EACA,sCAAA;EACA,yBAxFK,+CAAA,6BAwFL;EACA,iCAzFK,+CAAA,6BAyFL;EACA,sBAAA;;AA9FN,kBAsCE,iBA2DE;EACE,aAAA;EACA,cAAA;;AAnGN,kBAsCE,iBAiEE;EACE,qBAAA;EACA,sCAAA;EACA,yBAtGK,6BAsGL;EACA,sBAAA;EACA,sBAAA;EACA,+BAAA;;AA7GN,kBAsCE,iBAiEE,mBAQE,UAAU;EAAa,yBAAA;;AA/G7B,kBAsCE,iBAiEE,mBAUE;EAAO,2BAAA;;AAGT,kBA9EF,iBA8EG;EACC,8BAAA;EACA,qBAAA;EACA,WAAW,QAAX;;AAHF,kBA9EF,iBA8EG,OAKC;AALF,kBA9EF,iBA8EG,OAKqB;EAClB,qBAAA;;AA1HR,kBAsCE,iBAwFE;EACE,sBAAA;EACA,6BAAA;;AAhIN,kBAsCE,iBAwFE,SAGE;EACE,6BAAA;;AAlIR,kBAsCE,iBAwFE,SAGE,MAEE;AAnIR,kBAsCE,iBAwFE,SAGE,MAEU;EACN,oBAAA;;AAQN,wBAA6C;EAA7C,kBAtGF;IAuGI,0BAAA;IACA,iBAAA;IACA,kBAAA;IACA,sBAAA;IACA,uBAAA;IACA,2BAAA;IACA,4CAAA;IACA,2BAAA;IACA,WAAW,UAAX;IACA,wBAAA;;EAVF,kBAtGF,iBAkHI;IACE,iBAAA;IACA,sBAAA;;EAdJ,kBAtGF,iBAkHI,iBAIE;IACE,sBAAA;IACA,uBAAA;;;AAOV;EACE,iBAAA;EACA,mBAAA;;AAFF,gBAIE,mBACE;EACE,WAAW,gBAAX;EACA,aAAa,kBAAb;EACA,mBAAA;;AAGF,gBAPF,mBAOG;EACC,aAAA;EACA,4BAA4B,mBAA5B;EACA,cAAA;;AAHF,gBAPF,mBAOG,UAKC,MAAK;EACH,kBAAA;;AANJ,gBAPF,mBAOG,UAKC,MAAK,MAEH;EACE,WAAA","file":"meta-tag-manager.css"} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.less b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.less new file mode 100644 index 0000000..b8055d3 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.less @@ -0,0 +1,387 @@ +/* .mtm.postbox { background-color:#dedede;} */ +.mtm-menu-builder { margin-bottom:15px; } +.mtm-builder {} + +.mtm-field-template { display:none; visibility:hidden; } +.mtm-fields {} + +.mtm-field-placeholder { + width:100%; + border:1px dashed #aaa; + background-color: #ddd; + font-size:18px; + padding:30px 0px; + color:#555; + text-align:center; + margin:10px 0px; + cursor:pointer; +} +.no-reference.no-context .mtm-field-placeholder { padding:20px 0px; } + +.mtm-field { + display:block; + clear:both; + width:100%; + border: 1px solid #c3c3c3; + background-color: #fff; + margin:10px 0px; +} +.mtm-field.closed .mtm-field-data { display:none; visibility:hidden; } + +.mtm-field .mtm-field-actions { clear:both; } + +/* Field Header / Title section */ +.mtm-field-header { + padding: 10px 0px; + cursor:pointer; +} +.mtm-col-sort { + display:block; + float:left; + width:20px; + height:20px; + padding:10px 0px 0px 10px; + margin:0px; + font-size:20px; + align:center; + cursor:move; + color:#dedede +} +.no-reference.no-context .mtm-col-sort { padding:0px 0px 0px 10px;} + +/* Display Title for each Card */ +.mtm-field-title { margin-left:40px; min-height:50px;} +.no-reference.no-context .mtm-field-title { min-height:20px; } +.mtm-field-title .mtm-meta-reference { font-size: 18px; padding-bottom:5px; } +.mtm-field-title .mtm-meta-reference-value { display: inline-block; } + +.mtm-field-title .mtm-meta-context { + font-size:12px; + padding-bottom:3px; + color:#bcbcbc; + font-weight:bold; + font-style:italic; +} +.mtm-field-title .mtm-meta-context .dashicons { font-size:15px; vertical-align: baseline; } + +.mtm-field-title code { font-weight:bold; } +.mtm-field-title code .mtm-meta-type-val, .mtm-field-title code .mtm-meta-content-value { + font-style:italic; + font-weight:normal; + background-color:#fefefe; +} +.mtm-field-title code .mtm-meta-content.hidden { display:none; } + +/* Header toggles */ +.mtm-field-header-toggle:hover, +.mtm-field-section-toggle:hover { + cursor:pointer; +} +.mtm-field-header-toggle:before, +.mtm-field-section-toggle:before { + float:right; + width: 32px; + height: 32px; + content: "\f142"; + display: inline-block; + font: normal 20px/1 dashicons; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-decoration: none !important; +} +.mtm-field.closed .mtm-field-header-toggle:before { + content: "\f140"; +} + +/* Field form data */ +.mtm-field-data { + /* display: none; */ + border-top: 1px solid #e5e5e5; + padding:10px 10px 15px; +} +.mtm-field-input { margin:0px 0px 15px 0px; clear:both; } +.mtm-field-input-label { + display:inline-block; + margin-bottom:3px; + padding:2px; + font-weight:bold; + display:block; +} +.mtm-field-input-label em { font-style:normal; background:#eaeaea; padding:1px 2px; } +.mtm-field-input input, .mtm-field-input select { + width:100%; + padding:4px; + font-size:13px; /* matches selectize */ +} + +.mtm-field-type-custom { clear:both; } +.mtm-field-type-custom > div { + clear:none; + float:left; + width:48%; + margin:10px 1%; +} + +/* Specific type field selectors */ +.mtm-field-input.mtm-field-type-type { + width:20%; + float:left; + clear:none; +} +.mtm-field-input.mtm-field-type-value { + width:79% !important; + margin-left: 21%; + clear:none; +} +.mtm-field-input input.mtm-field-input-tag-value { float:left; clear:none; } + + + +.mtm-field-section { margin-top:20px; } +.mtm-field-section-header { border-bottom:1px solid #e3e3e3; padding-bottom:10px; } +.mtm-field-section-title { font-weight:bold; font-size:15px; } +.mtm-field-section-data { margin:10px 10px 20px; padding-bottom:10px; border-bottom:1px solid #e3e3e3; } + +/*.mtm-builder .selectize-input { padding:4px; }*/ +.mtm-settings .selectize-dropdown-content .optgroup .option { padding-left:10px; } +.mtm-settings .selectize-dropdown-content .optgroup .optgroup-header { font-weight:bold; } +.mtm-settings .selectize-control.multi .selectize-input > .item { background:#5cb85c; border-color:#4cae4c; color:#fff; } +.mtm-settings .selectize-control.multi .selectize-input > .item .remove { border-color:#4cae4c; } + +.mtm-builder .mtm-field button.mtm-field-remove { background-color:#f4e3e3; border-color:#d8c5c5; color:#565656; } +.mtm-builder .mtm-field a.mtm-field-remove { cursor:pointer; color:#d66b6b; } +.mtm-builder button .dashicons { padding: 3px 0px; margin-left: -5px; color: #888; } +.mtm-builder button.mtm-add-field .dashicons { padding: 4px 0px; } + +.mtm-builder .mtm-actions { padding-top:15px; } + +/* Settings Page */ +.mtm-settings select:invalid { color: gray; } +.mtm-settings h3 { border-top: 1px solid #dedede; padding-top:25px; margin-top:20px; } +.mtm-settings .postbox .handlediv { display:none; visibility: hidden; } +.mtm-settings .postbox .inside { border-top: 1px solid #dedede; margin-top:0px; padding-top:10px; } +.mtm-settings .postbox h3 { font-size:16px; } +.mtm-settings .postbox td, .mtm-settings .postbox th { vertical-align:top; } +.mtm-settings .postbox th { padding: 15px 20px; margin:0 !important; font-size:0.97em; } +.mtm-settings .postbox .mtm-boxheader { font-style:italic; margin:0; padding:10px 5px; } +.mtm-settings .postbox tr.mtm-header td { font-style:italic; padding:10px 5px; margin:0; } +.mtm-settings .postbox tr.mtm-header h4, .mtm-settings .postbox .postbox h4 { font-weight:bold; font-size:15px; font-style:normal; border-bottom: 1px solid #dedede; margin:0 0 10px; padding:0 0 10px; } +.mtm-settings .postbox tr.mtm-subheader td { font-style:italic; margin:0; padding:5px 20px 2px; } +.mtm-settings .postbox tr.mtm-subheader h5 { font-style:normal; margin:10px 0; padding:0 0 5px; font-weight:bold; font-size:15px; border-bottom: 1px solid #efefef; color:#000; } + +/* Schema Settings */ +.mtm-settings .mtm-image-upload-preview { margin-bottom:10px; } +.mtm-settings #mtm_schema_profiles_other_row { display:none; } +.mtm-settings .mtm-schema-profiles-other a.mtm-schema-profile-remove { text-decoration: none; color:black; } + +/* Go Pro Stuff */ +.mtm-settings table.features { border-spacing: 0; border: 1px solid #dedede; } +.mtm-settings table.features th, table.features td { background:#fff; border:0; border-bottom: 1px solid #dedede; padding:5px; } +.mtm-settings table.features tbody tr { border-bottom:1px solid #EFEFEF; } +.mtm-settings table.features tbody tr:first-child th { background:#EFEFEF; } +.mtm-settings table.features tbody th { text-align:left; padding-left:10px; } +.mtm-settings table.features tr th:not(:first-child), table.features tr td:not(:first-child) { width:150px; padding-left:10px; padding-right:10px; text-align: center; } +.mtm-settings table.features .dashicons-yes-alt { color:darkgreen; font-size:20px; } +.mtm-settings table.features tfoot th span { display:block; margin-bottom:5px; color:#8bc976; font-size:18px; } +.mtm-settings table.features tfoot th span.deal { color:#FC9840; font-size:14px; } +.mtm-settings table.features tbody th[data-title] { cursor: pointer; } + +/*! Tippy.js v6.2.7 - https://unpkg.com/tippy.js@6.2.7/themes/light-border.css */ +.tippy-box[data-theme~=light-border]{background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,8,16,.15);color:#333;box-shadow:0 4px 14px -2px rgba(0,8,16,.08)}.tippy-box[data-theme~=light-border]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light-border]>.tippy-arrow:after,.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=light-border]>.tippy-arrow:after{border-color:transparent;border-style:solid}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:after{border-top-color:rgba(0,8,16,.2);border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:rgba(0,8,16,.2);border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:after{border-left-color:rgba(0,8,16,.2);border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:rgba(0,8,16,.2)}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow{fill:#fff}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px} + +.mtm-builder { + @import (inline) "selectize/selectize.css"; +} + +// Modal Theme +.mtm-modal-overlay { + // Variables + @speed: 0.6s; + @delay: (@speed * .5); + @easing: cubic-bezier(.55, 0, .1, 1); + + display : none; + &.active { + display: block !important; + } + + + // Overlay -- only show for tablet and up + @media only screen and (min-width: 40rem) { + align-items: center !important; + justify-content: center !important; + position: fixed !important; + top: 0 !important; + left: 0 !important; + width: 100% !important; + height: 100% !important; + z-index: 99998 !important; + background-color: rgba(#000, 0.6) !important; + opacity: 0 !important; + visibility: hidden !important; + backface-visibility: hidden !important; + transition: opacity @speed @easing, visibility @speed @easing !important; + -webkit-transition: opacity @speed @easing, visibility @speed @easing !important; + transition-delay: @delay !important; + + &.active { + display: flex !important; + opacity: 1 !important; + visibility: visible !important; + } + } + + // Modal + .mtm-modal-popup { + //display: flex !important; + align-items: start !important; + justify-content: center !important; + position: relative !important; + margin: 0 !important; + background-color: #fff !important; + width: 100% !important; + max-width: 750px !important; + min-height: 200px !important; + max-height: 98% !important; + padding: 10px !important; + border-radius: 3px !important; + opacity: 0 !important; + //overflow-y: auto !important; + visibility: hidden !important; + box-shadow: 0 2px 10px rgba(#000, 0.1) !important; + backface-visibility: hidden !important; + transform: scale(1.2) !important; + transition: all @speed @easing !important; + z-index: 99999 !important; + + // close modal + > header { + box-sizing: border-box; + width: 100%; + border-bottom: 1px solid #dedede; + margin: 0; + padding: 10px 0 7px 15px; + + .mtm-modal-title { + font-size: 24px !important; + line-height: 1.3 !important; + padding: 0 32px 0 0 !important; + margin: 0 !important; + + a { + color: var(--text-color-normal) !important; + + &:hover { + text-decoration: underline; + } + } + } + } + + // close modal + .mtm-close-modal { + position: absolute !important; + cursor: pointer !important; + top: 15px !important; + right: 15px !important; + opacity: 0 !important; + backface-visibility: hidden !important; + transition: opacity @speed @easing, visibility @speed @easing !important; + -webkit-transition: opacity @speed @easing, visibility @speed @easing !important; + transition-delay: @delay !important; + } + + svg { + width: 17.5px !important; + height: 17.5px !important; + } + + // content + .mtm-modal-content { + opacity: 0 !important; + backface-visibility: hidden !important; + transition: opacity @speed @easing !important; + transition-delay: @delay !important; + width:100% !important; + margin:20px 5px 5px !important; + + .mtm-form .mtm-title { display:block !important; } + + form { margin-bottom: 0 !important; } + } + + &.active { + visibility: visible !important; + opacity: 1 !important; + transform: scale(1) !important; + + .mtm-modal-content, .mtm-close-modal { + opacity: 1 !important; + } + } + + > footer { + width: 100% !important; + border-top: 1px solid #dedede !important; + > div { + padding: 10px 25px !important; + button, .button { + margin: 0 !important; + } + } + } + + /** + * Mobile styling for popups + */ + @media only screen and (max-width: 39.99rem) { + position: fixed !important; + top: 0 !important; + left: 0 !important; + width: 100% !important; + height: 100% !important; + max-height: 100% !important; + -webkit-overflow-scrolling: touch !important; + border-radius: 0 !important; + transform: scale(1.1) !important; + padding: 10px !important; + + .mtm-close-modal { + top: 0 !important; + right: 10px !important; + + svg{ + width:28px !important; + height:28px !important; + } + } + } + } +} + +.mtm-admin-modal { + --font-size: 15px; + --line-height: 20px; + + .mtm-modal-content { + p { + font-size: var(--font-size) !important; + line-height: var(--line-height) !important; + text-align: justify; + } + + &.has-image { + display: grid; + grid-template-columns: auto minmax(80px, 150px); + grid-gap: 40px; + + > div.image { + text-align: center; + img { + width: 100%; + } + } + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.min.css b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.min.css new file mode 100644 index 0000000..00c6cc0 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/meta-tag-manager.min.css @@ -0,0 +1,3 @@ +.mtm-menu-builder{margin-bottom:15px}.mtm-field-template{display:none;visibility:hidden}.mtm-field-placeholder{width:100%;border:1px dashed #aaa;background-color:#ddd;font-size:18px;padding:30px 0;color:#555;text-align:center;margin:10px 0;cursor:pointer}.no-reference.no-context .mtm-field-placeholder{padding:20px 0}.mtm-field{display:block;clear:both;width:100%;border:1px solid #c3c3c3;background-color:#fff;margin:10px 0}.mtm-field.closed .mtm-field-data{display:none;visibility:hidden}.mtm-field .mtm-field-actions{clear:both}.mtm-field-header{padding:10px 0;cursor:pointer}.mtm-col-sort{display:block;float:left;width:20px;height:20px;padding:10px 0 0 10px;margin:0;font-size:20px;align:center;cursor:move;color:#dedede}.no-reference.no-context .mtm-col-sort{padding:0 0 0 10px}.mtm-field-title{margin-left:40px;min-height:50px}.no-reference.no-context .mtm-field-title{min-height:20px}.mtm-field-title .mtm-meta-reference{font-size:18px;padding-bottom:5px}.mtm-field-title .mtm-meta-reference-value{display:inline-block}.mtm-field-title .mtm-meta-context{font-size:12px;padding-bottom:3px;color:#bcbcbc;font-weight:700;font-style:italic}.mtm-field-title .mtm-meta-context .dashicons{font-size:15px;vertical-align:baseline}.mtm-field-title code{font-weight:700}.mtm-field-title code .mtm-meta-content-value,.mtm-field-title code .mtm-meta-type-val{font-style:italic;font-weight:400;background-color:#fefefe}.mtm-field-title code .mtm-meta-content.hidden,.mtm-settings #mtm_schema_profiles_other_row{display:none}.mtm-field-header-toggle:hover,.mtm-field-section-toggle:hover{cursor:pointer}.mtm-field-header-toggle:before,.mtm-field-section-toggle:before{float:right;width:32px;height:32px;content:"\f142";display:inline-block;font:20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}.mtm-field.closed .mtm-field-header-toggle:before{content:"\f140"}.mtm-field-data{border-top:1px solid #e5e5e5;padding:10px 10px 15px}.mtm-field-input{margin:0 0 15px;clear:both}.mtm-field-input-label{margin-bottom:3px;padding:2px;font-weight:700;display:block}.mtm-field-input-label em{font-style:normal;background:#eaeaea;padding:1px 2px}.mtm-field-input input,.mtm-field-input select{width:100%;padding:4px;font-size:13px}.mtm-field-type-custom{clear:both}.mtm-field-type-custom>div{clear:none;float:left;width:48%;margin:10px 1%}.mtm-field-input.mtm-field-type-type{width:20%;float:left;clear:none}.mtm-field-input.mtm-field-type-value{width:79%!important;margin-left:21%;clear:none}.mtm-field-input input.mtm-field-input-tag-value{float:left;clear:none}.mtm-field-section{margin-top:20px}.mtm-field-section-header{border-bottom:1px solid #e3e3e3;padding-bottom:10px}.mtm-field-section-title{font-weight:700;font-size:15px}.mtm-field-section-data{margin:10px 10px 20px;padding-bottom:10px;border-bottom:1px solid #e3e3e3}.mtm-settings .selectize-dropdown-content .optgroup .option{padding-left:10px}.mtm-settings .selectize-dropdown-content .optgroup .optgroup-header{font-weight:700}.mtm-settings .selectize-control.multi .selectize-input>.item{background:#5cb85c;border-color:#4cae4c;color:#fff}.mtm-settings .selectize-control.multi .selectize-input>.item .remove{border-color:#4cae4c}.mtm-builder .mtm-field button.mtm-field-remove{background-color:#f4e3e3;border-color:#d8c5c5;color:#565656}.mtm-builder .mtm-field a.mtm-field-remove{cursor:pointer;color:#d66b6b}.mtm-builder button .dashicons{padding:3px 0;margin-left:-5px;color:#888}.mtm-builder button.mtm-add-field .dashicons{padding:4px 0}.mtm-builder .mtm-actions{padding-top:15px}.mtm-settings select:invalid{color:gray}.mtm-settings h3{border-top:1px solid #dedede;padding-top:25px;margin-top:20px}.mtm-settings .postbox .handlediv{display:none;visibility:hidden}.mtm-settings .postbox .inside{border-top:1px solid #dedede;margin-top:0;padding-top:10px}.mtm-settings .postbox h3{font-size:16px}.mtm-settings .postbox td,.mtm-settings .postbox th{vertical-align:top}.mtm-settings .postbox th{padding:15px 20px;margin:0!important;font-size:.97em}.mtm-settings .postbox .mtm-boxheader,.mtm-settings .postbox tr.mtm-header td{font-style:italic;padding:10px 5px;margin:0}.mtm-settings .postbox .postbox h4,.mtm-settings .postbox tr.mtm-header h4,.mtm-settings .postbox tr.mtm-subheader h5{font-weight:700;font-size:15px;font-style:normal;border-bottom:1px solid #dedede;margin:0 0 10px;padding:0 0 10px}.mtm-settings .postbox tr.mtm-subheader td{font-style:italic;margin:0;padding:5px 20px 2px}.mtm-settings .postbox tr.mtm-subheader h5{margin:10px 0;padding:0 0 5px;border-bottom:1px solid #efefef;color:#000}.mtm-settings .mtm-image-upload-preview{margin-bottom:10px}.mtm-settings .mtm-schema-profiles-other a.mtm-schema-profile-remove{text-decoration:none;color:#000}.mtm-settings table.features{border-spacing:0;border:1px solid #dedede}.mtm-settings table.features th,table.features td{background:#fff;border:0;border-bottom:1px solid #dedede;padding:5px}.mtm-settings table.features tbody tr{border-bottom:1px solid #efefef}.mtm-settings table.features tbody tr:first-child th{background:#efefef}.mtm-settings table.features tbody th{text-align:left;padding-left:10px}.mtm-settings table.features tr th:not(:first-child),table.features tr td:not(:first-child){width:150px;padding-left:10px;padding-right:10px;text-align:center}.mtm-settings table.features .dashicons-yes-alt{color:#006400;font-size:20px}.mtm-settings table.features tfoot th span{display:block;margin-bottom:5px;color:#8bc976;font-size:18px}.mtm-settings table.features tfoot th span.deal{color:#fc9840;font-size:14px}.mtm-settings table.features tbody th[data-title]{cursor:pointer} +/*! Tippy.js v6.2.7 - https://unpkg.com/tippy.js@6.2.7/themes/light-border.css */ +.tippy-box[data-theme~=light-border]{background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,8,16,.15);color:#333;box-shadow:0 4px 14px -2px rgba(0,8,16,.08)}.tippy-box[data-theme~=light-border]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=light-border]>.tippy-arrow:after,.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=light-border]>.tippy-arrow:after{border-color:transparent;border-style:solid}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-arrow:after{border-top-color:rgba(0,8,16,.2);border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=light-border][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:rgba(0,8,16,.2);border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:16px}.tippy-box[data-theme~=light-border][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-arrow:after{border-left-color:rgba(0,8,16,.2);border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=light-border][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:rgba(0,8,16,.2)}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=light-border][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow{fill:#fff}.tippy-box[data-theme~=light-border]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}.mtm-modal-overlay{display:none}.mtm-modal-overlay .mtm-modal-popup .mtm-modal-content .mtm-form .mtm-title,.mtm-modal-overlay.active{display:block!important}@media only screen and (min-width:40rem){.mtm-modal-overlay{align-items:center!important;justify-content:center!important;position:fixed!important;top:0!important;left:0!important;width:100%!important;height:100%!important;z-index:99998!important;background-color:rgba(0,0,0,.6)!important;opacity:0!important;visibility:hidden!important;backface-visibility:hidden!important;transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;-webkit-transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;transition-delay:.3s!important}.mtm-modal-overlay.active{display:flex!important;opacity:1!important;visibility:visible!important}}.mtm-modal-overlay .mtm-modal-popup{align-items:start!important;justify-content:center!important;position:relative!important;margin:0!important;background-color:#fff!important;width:100%!important;max-width:750px!important;min-height:200px!important;max-height:98%!important;padding:10px!important;border-radius:3px!important;opacity:0!important;visibility:hidden!important;box-shadow:0 2px 10px rgba(0,0,0,.1)!important;backface-visibility:hidden!important;transform:scale(1.2)!important;transition:all .6s cubic-bezier(.55,0,.1,1)!important;z-index:99999!important}.mtm-modal-overlay .mtm-modal-popup>header{box-sizing:border-box;width:100%;border-bottom:1px solid #dedede;margin:0;padding:10px 0 7px 15px}.mtm-modal-overlay .mtm-modal-popup>header .mtm-modal-title{font-size:24px!important;line-height:1.3!important;padding:0 32px 0 0!important;margin:0!important}.mtm-modal-overlay .mtm-modal-popup>header .mtm-modal-title a{color:var(--text-color-normal)!important}.mtm-modal-overlay .mtm-modal-popup>header .mtm-modal-title a:hover{text-decoration:underline}.mtm-modal-overlay .mtm-modal-popup .mtm-close-modal{position:absolute!important;cursor:pointer!important;top:15px!important;right:15px!important;opacity:0!important;backface-visibility:hidden!important;transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;-webkit-transition:opacity .6s cubic-bezier(.55,0,.1,1),visibility .6s cubic-bezier(.55,0,.1,1)!important;transition-delay:.3s!important}.mtm-modal-overlay .mtm-modal-popup svg{width:17.5px!important;height:17.5px!important}.mtm-modal-overlay .mtm-modal-popup .mtm-modal-content{opacity:0!important;backface-visibility:hidden!important;transition:opacity .6s cubic-bezier(.55,0,.1,1)!important;transition-delay:.3s!important;width:100%!important;margin:20px 5px 5px!important}.mtm-modal-overlay .mtm-modal-popup .mtm-modal-content form{margin-bottom:0!important}.mtm-modal-overlay .mtm-modal-popup.active{visibility:visible!important;opacity:1!important;transform:scale(1)!important}.mtm-modal-overlay .mtm-modal-popup.active .mtm-close-modal,.mtm-modal-overlay .mtm-modal-popup.active .mtm-modal-content{opacity:1!important}.mtm-modal-overlay .mtm-modal-popup>footer{width:100%!important;border-top:1px solid #dedede!important}.mtm-modal-overlay .mtm-modal-popup>footer>div{padding:10px 25px!important}.mtm-modal-overlay .mtm-modal-popup>footer>div .button,.mtm-modal-overlay .mtm-modal-popup>footer>div button{margin:0!important}@media only screen and (max-width:39.99rem){.mtm-modal-overlay .mtm-modal-popup{position:fixed!important;top:0!important;left:0!important;width:100%!important;height:100%!important;max-height:100%!important;-webkit-overflow-scrolling:touch!important;border-radius:0!important;transform:scale(1.1)!important;padding:10px!important}.mtm-modal-overlay .mtm-modal-popup .mtm-close-modal{top:0!important;right:10px!important}.mtm-modal-overlay .mtm-modal-popup .mtm-close-modal svg{width:28px!important;height:28px!important}}.mtm-admin-modal{--font-size:15px;--line-height:20px}.mtm-admin-modal .mtm-modal-content p{font-size:var(--font-size)!important;line-height:var(--line-height)!important;text-align:justify}.mtm-admin-modal .mtm-modal-content.has-image{display:grid;grid-template-columns:auto minmax(80px,150px);grid-gap:40px}.mtm-admin-modal .mtm-modal-content.has-image>div.image{text-align:center}.mtm-admin-modal .mtm-modal-content.has-image>div.image img{width:100%} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/drag_drop.less b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/drag_drop.less new file mode 100644 index 0000000..bb0b2aa --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/drag_drop.less @@ -0,0 +1,16 @@ +.selectize-control.plugin-drag_drop { + &.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0,0,0,0.06) !important; + border: 0 none !important; + .selectize-box-shadow(inset 0 0 12px 4px #fff); + } + .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; + } + .ui-sortable-helper { + .selectize-box-shadow(0 2px 5px rgba(0,0,0,0.2)); + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/dropdown_header.less b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/dropdown_header.less new file mode 100644 index 0000000..bf28cce --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/dropdown_header.less @@ -0,0 +1,20 @@ +.selectize-dropdown-header { + position: relative; + padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; + border-bottom: 1px solid @selectize-color-border; + background: mix(@selectize-color-dropdown, @selectize-color-border, 85%); + .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); +} +.selectize-dropdown-header-close { + position: absolute; + right: @selectize-padding-dropdown-item-x; + top: 50%; + color: @selectize-color-text; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: darken(@selectize-color-text, 25%); +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/optgroup_columns.less b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/optgroup_columns.less new file mode 100644 index 0000000..ee67e42 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/optgroup_columns.less @@ -0,0 +1,17 @@ +.selectize-dropdown.plugin-optgroup_columns { + .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + .selectize-box-sizing(border-box); + } + .optgroup:last-child { + border-right: 0 none; + } + .optgroup:before { + display: none; + } + .optgroup-header { + border-top: 0 none; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/remove_button.less b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/remove_button.less new file mode 100644 index 0000000..14f7928 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/plugins/remove_button.less @@ -0,0 +1,43 @@ +.selectize-control.plugin-remove_button { + [data-value] { + position: relative; + padding-right: 24px !important; + } + [data-value] .remove { + z-index: 1; /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: @selectize-padding-item-y 0 0 0; + border-left: 1px solid @selectize-color-item-border; + .selectize-border-radius(0 2px 2px 0); + .selectize-box-sizing(border-box); + } + [data-value] .remove:hover { + background: rgba(0,0,0,0.05); + } + [data-value].active .remove { + border-left-color: @selectize-color-item-active-border; + } + .disabled [data-value] .remove:hover { + background: none; + } + .disabled [data-value] .remove { + border-left-color: lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); + } + .remove-single { + position: absolute; + right: 0; + top: 0; + font-size: 23px; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.css b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.css new file mode 100644 index 0000000..545937d --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.css @@ -0,0 +1,321 @@ +.selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder { + visibility: visible !important; + background: #f2f2f2 !important; + background: rgba(0, 0, 0, 0.06) !important; + border: 0 none !important; + -webkit-box-shadow: inset 0 0 12px 4px #fff; + box-shadow: inset 0 0 12px 4px #fff; +} +.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after { + content: '!'; + visibility: hidden; +} +.selectize-control.plugin-drag_drop .ui-sortable-helper { + -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); +} +.selectize-dropdown-header { + position: relative; + padding: 5px 8px; + border-bottom: 1px solid #d0d0d0; + background: #f8f8f8; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.selectize-dropdown-header-close { + position: absolute; + right: 8px; + top: 50%; + color: #303030; + opacity: 0.4; + margin-top: -12px; + line-height: 20px; + font-size: 20px !important; +} +.selectize-dropdown-header-close:hover { + color: #000000; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup { + border-right: 1px solid #f2f2f2; + border-top: 0 none; + float: left; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child { + border-right: 0 none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup:before { + display: none; +} +.selectize-dropdown.plugin-optgroup_columns .optgroup-header { + border-top: 0 none; +} +.selectize-control.plugin-remove_button [data-value] { + position: relative; + padding-right: 24px !important; +} +.selectize-control.plugin-remove_button [data-value] .remove { + z-index: 1; + /* fixes ie bug (see #392) */ + position: absolute; + top: 0; + right: 0; + bottom: 0; + width: 17px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: inherit; + text-decoration: none; + vertical-align: middle; + display: inline-block; + padding: 2px 0 0 0; + border-left: 1px solid #d0d0d0; + -webkit-border-radius: 0 2px 2px 0; + -moz-border-radius: 0 2px 2px 0; + border-radius: 0 2px 2px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.selectize-control.plugin-remove_button [data-value] .remove:hover { + background: rgba(0, 0, 0, 0.05); +} +.selectize-control.plugin-remove_button [data-value].active .remove { + border-left-color: #cacaca; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover { + background: none; +} +.selectize-control.plugin-remove_button .disabled [data-value] .remove { + border-left-color: #ffffff; +} +.selectize-control.plugin-remove_button .remove-single { + position: absolute; + right: 0; + top: 0; + font-size: 23px; +} +.selectize-control { + position: relative; +} +.selectize-dropdown, +.selectize-input, +.selectize-input input { + color: #303030; + font-family: inherit; + font-size: 13px; + line-height: 18px; + -webkit-font-smoothing: inherit; +} +.selectize-input, +.selectize-control.single .selectize-input.input-active { + background: #fff; + cursor: text; + display: inline-block; +} +.selectize-input { + border: 1px solid #d0d0d0; + padding: 8px 8px; + display: inline-block; + width: 100%; + overflow: hidden; + position: relative; + z-index: 1; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.selectize-control.multi .selectize-input.has-items { + padding: 6px 8px 3px; +} +.selectize-input.full { + background-color: #fff; +} +.selectize-input.disabled, +.selectize-input.disabled * { + cursor: default !important; +} +.selectize-input.focus { + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15); +} +.selectize-input.dropdown-active { + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} +.selectize-input > * { + vertical-align: baseline; + display: -moz-inline-stack; + display: inline-block; + zoom: 1; + *display: inline; +} +.selectize-control.multi .selectize-input > div { + cursor: pointer; + margin: 0 3px 3px 0; + padding: 2px 6px; + background: #f2f2f2; + color: #303030; + border: 0 solid #d0d0d0; +} +.selectize-control.multi .selectize-input > div.active { + background: #e8e8e8; + color: #303030; + border: 0 solid #cacaca; +} +.selectize-control.multi .selectize-input.disabled > div, +.selectize-control.multi .selectize-input.disabled > div.active { + color: #7d7d7d; + background: #ffffff; + border: 0 solid #ffffff; +} +.selectize-input > input { + display: inline-block !important; + padding: 0 !important; + min-height: 0 !important; + max-height: none !important; + max-width: 100% !important; + margin: 0 2px 0 0 !important; + text-indent: 0 !important; + border: 0 none !important; + background: none !important; + line-height: inherit !important; + -webkit-user-select: auto !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} +.selectize-input > input::-ms-clear { + display: none; +} +.selectize-input > input:focus { + outline: none !important; +} +.selectize-input > input[placeholder] { + box-sizing: initial; +} +.selectize-input::after { + content: ' '; + display: block; + clear: left; +} +.selectize-input.dropdown-active::before { + content: ' '; + display: block; + position: absolute; + background: #f0f0f0; + height: 1px; + bottom: 0; + left: 0; + right: 0; +} +.selectize-dropdown { + position: absolute; + z-index: 10; + border: 1px solid #d0d0d0; + background: #fff; + margin: -1px 0 0 0; + border-top: 0 none; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -webkit-border-radius: 0 0 3px 3px; + -moz-border-radius: 0 0 3px 3px; + border-radius: 0 0 3px 3px; +} +.selectize-dropdown [data-selectable] { + cursor: pointer; + overflow: hidden; +} +.selectize-dropdown [data-selectable] .highlight { + background: rgba(125, 168, 208, 0.2); + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; +} +.selectize-dropdown .option, +.selectize-dropdown .optgroup-header { + padding: 5px 8px; +} +.selectize-dropdown .option, +.selectize-dropdown [data-disabled], +.selectize-dropdown [data-disabled] [data-selectable].option { + cursor: inherit; + opacity: 0.5; +} +.selectize-dropdown [data-selectable].option { + opacity: 1; +} +.selectize-dropdown .optgroup:first-child .optgroup-header { + border-top: 0 none; +} +.selectize-dropdown .optgroup-header { + color: #303030; + background: #fff; + cursor: default; +} +.selectize-dropdown .active { + background-color: #f5fafd; + color: #495c68; +} +.selectize-dropdown .active.create { + color: #495c68; +} +.selectize-dropdown .create { + color: rgba(48, 48, 48, 0.5); +} +.selectize-dropdown-content { + overflow-y: auto; + overflow-x: hidden; + max-height: 200px; + -webkit-overflow-scrolling: touch; +} +.selectize-control.single .selectize-input, +.selectize-control.single .selectize-input input { + cursor: pointer; +} +.selectize-control.single .selectize-input.input-active, +.selectize-control.single .selectize-input.input-active input { + cursor: text; +} +.selectize-control.single .selectize-input:after { + content: ' '; + display: block; + position: absolute; + top: 50%; + right: 15px; + margin-top: -3px; + width: 0; + height: 0; + border-style: solid; + border-width: 5px 5px 0 5px; + border-color: #808080 transparent transparent transparent; +} +.selectize-control.single .selectize-input.dropdown-active:after { + margin-top: -4px; + border-width: 0 5px 5px 5px; + border-color: transparent transparent #808080 transparent; +} +.selectize-control.rtl.single .selectize-input:after { + left: 15px; + right: auto; +} +.selectize-control.rtl .selectize-input > input { + margin: 0 4px 0 -2px !important; +} +.selectize-control .selectize-input.disabled { + opacity: 0.5; + background-color: #fafafa; +} +/*# sourceMappingURL=selectize.css.map */ \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.css.map b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.css.map new file mode 100644 index 0000000..333aba4 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["plugins/drag_drop.less","selectize.less","plugins/dropdown_header.less","plugins/optgroup_columns.less","plugins/remove_button.less"],"names":[],"mappings":"AACE,kBADgB,iBACf,MAAO,mBAAmB,MAAK;EAC9B,8BAAA;EACA,mBAAA;EACA,+BAAA;EACA,yBAAA;ECsEF,2CAAA;EACA,mCAAA;;AD5EF,kBAAkB,iBAQhB,yBAAwB;EACtB,SAAS,GAAT;EACA,kBAAA;;AAVJ,kBAAkB,iBAYhB;EC+DA,gDAAA;EACA,wCAAA;;AC5EF;EACE,kBAAA;EACA,gBAAA;EACA,gCAAA;EACA,mBAAA;ED4DA,kCAAA;EACA,+BAAA;EACA,0BAAA;;AC3DF;EACE,kBAAA;EACA,UAAA;EACA,QAAA;EACA,cAAA;EACA,YAAA;EACA,iBAAA;EACA,iBAAA;EACA,0BAAA;;AAEF,gCAAgC;EAC9B,cAAA;;AClBF,mBAAmB,wBACjB;EACE,+BAAA;EACA,kBAAA;EACA,WAAA;EF2EF,8BAAA;EACA,2BAAA;EACA,sBAAA;;AEjFF,mBAAmB,wBAOjB,UAAS;EACP,oBAAA;;AARJ,mBAAmB,wBAUjB,UAAS;EACP,aAAA;;AAXJ,mBAAmB,wBAajB;EACE,kBAAA;;ACdJ,kBAAkB,qBAChB;EACE,kBAAA;EACA,8BAAA;;AAHJ,kBAAkB,qBAKhB,aAAa;EACX,UAAA;;EACA,kBAAA;EACA,MAAA;EACA,QAAA;EACA,SAAA;EACA,WAAA;EACA,kBAAA;EACA,iBAAA;EACA,eAAA;EACA,cAAA;EACA,qBAAA;EACA,sBAAA;EACA,qBAAA;EACA,kBAAA;EACA,8BAAA;EH4CF,kCAAA;EACA,+BAAA;EACA,0BAAA;EAaA,8BAAA;EACA,2BAAA;EACA,sBAAA;;AGjFF,kBAAkB,qBAwBhB,aAAa,QAAO;EAClB,+BAAA;;AAzBJ,kBAAkB,qBA2BhB,aAAY,OAAQ;EAClB,0BAAA;;AA5BJ,kBAAkB,qBA8BhB,UAAU,aAAa,QAAO;EAC5B,gBAAA;;AA/BJ,kBAAkB,qBAiChB,UAAU,aAAa;EACrB,0BAAA;;AAlCJ,kBAAkB,qBAoChB;EACE,kBAAA;EACA,QAAA;EACA,MAAA;EACA,eAAA;;AHsDJ;EACE,kBAAA;;AAGF;AAAqB;AAAkB,gBAAiB;EACtD,cAAA;EACA,oBAAA;EACA,eAAA;EACA,iBAAA;EACA,+BAAA;;AAGF;AAAkB,kBAAkB,OAAQ,iBAAgB;EAC1D,gBAAA;EACA,YAAA;EACA,qBAAA;;AAGF;EACE,yBAAA;EACA,gBAAA;EACA,qBAAA;EACA,WAAA;EACA,gBAAA;EACA,kBAAA;EACA,UAAA;EAxCA,8BAAA;EACA,2BAAA;EACA,sBAAA;EANA,sDAAA;EACA,8CAAA;EAZA,0BAAA;EACA,uBAAA;EACA,kBAAA;;AA0DA,kBAAkB,MAAO,iBAAC;EAIxB,oBAAA;;AAGF,gBAAC;EACC,sBAAA;;AAEF,gBAAC;AAAW,gBAAC,SAAU;EACrB,0BAAA;;AAEF,gBAAC;EA9DD,uDAAA;EACA,+CAAA;;AAgEA,gBAAC;EA5ED,kCAAA;EACA,+BAAA;EACA,0BAAA;;AA8CF,gBAgCE;EACE,wBAAA;EACA,0BAAA;EACA,qBAAA;EACA,OAAA;EACA,gBAAA;;AAEF,kBAAkB,MAAO,iBAAE;EACzB,eAAA;EACA,mBAAA;EACA,gBAAA;EACA,mBAAA;EACA,cAAA;EACA,uBAAA;;AAEA,kBARgB,MAAO,iBAAE,MAQxB;EACC,mBAAA;EACA,cAAA;EACA,uBAAA;;AAIF,kBADgB,MAAO,iBAAC,SAAU;AAC/B,kBADa,MAAO,iBAAC,SAAU,MAC9B;EACF,cAAA;EACA,mBAAA;EACA,uBAAA;;AAzDN,gBA4DE;EAIE,qBAAA;EACA,qBAAA;EACA,wBAAA;EACA,2BAAA;EACA,0BAAA;EACA,iBAAA;EACA,yBAAA;EACA,yBAAA;EACA,2BAAA;EACA,+BAAA;EACA,oCAAA;EA/GF,wBAAA;EACA,gBAAA;;AAiGE,gBADF,QACG;EACC,aAAA;;AAcF,gBAhBF,QAgBG;EAAS,wBAAA;;AACV,gBAjBF,QAiBG;EACC,mBAAA;;AAKN,gBAAgB;EACd,SAAS,GAAT;EACA,cAAA;EACA,WAAA;;AAGF,gBAAgB,gBAAgB;EAC9B,SAAS,GAAT;EACA,cAAA;EACA,kBAAA;EACA,mBAAA;EACA,WAAA;EACA,SAAA;EACA,OAAA;EACA,QAAA;;AAGF;EACE,kBAAA;EACA,WAAA;EACA,yBAAA;EACA,gBAAA;EACA,kBAAA;EACA,kBAAA;EA3IA,8BAAA;EACA,2BAAA;EACA,sBAAA;EANA,gDAAA;EACA,wCAAA;EAZA,kCAAA;EACA,+BAAA;EACA,0BAAA;;AAkJF,mBAWE;EACE,eAAA;EACA,gBAAA;;AAbJ,mBAWE,kBAGE;EACE,oCAAA;EAnKJ,0BAAA;EACA,uBAAA;EACA,kBAAA;;AAkJF,mBAmBE;AAnBF,mBAmBW;EACP,gBAAA;;AApBJ,mBAsBE;AAtBF,mBAsBW;AAtBX,mBAsB4B,gBAAgB,kBAAiB;EACzD,eAAA;EACA,YAAA;;AAxBJ,mBA0BE,kBAAiB;EACf,UAAA;;AA3BJ,mBA6BE,UAAS,YAAa;EACpB,kBAAA;;AA9BJ,mBAgCE;EACE,cAAA;EACA,gBAAA;EACA,eAAA;;AAnCJ,mBAqCE;EACE,yBAAA;EACA,cAAA;;AACA,mBAHF,QAGG;EACC,cAAA;;AAzCN,mBA4CE;EACE,4BAAA;;AAIJ;EACE,gBAAA;EACA,kBAAA;EACA,iBAAA;EACA,iCAAA;;AAIA,kBADgB,OAAQ;AAA1B,kBAAkB,OAAQ,iBACrB;EAAQ,eAAA;;AACX,kBAFgB,OAAQ,iBAEvB;AAAe,kBAFA,OAAQ,iBAEP,aAAc;EAAQ,YAAA;;AAEvC,kBAJgB,OAAQ,iBAIvB;EACC,SAAS,GAAT;EACA,cAAA;EACA,kBAAA;EACA,QAAA;EACA,WAAA;EACA,gBAAA;EACA,QAAA;EACA,SAAA;EACA,mBAAA;EACA,2BAAA;EACA,yDAAA;;AAEF,kBAjBgB,OAAQ,iBAiBvB,gBAAgB;EACf,gBAAA;EACA,2BAAA;EACA,yDAAA;;AAKF,kBADgB,IACf,OAAQ,iBAAgB;EACvB,UAAA;EACA,WAAA;;AAHJ,kBAAkB,IAKhB,iBAAiB;EACf,oBAAA;;AAIJ,kBAAmB,iBAAgB;EACjC,YAAA;EACA,yBAAA","file":"selectize.css"} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.less b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.less new file mode 100644 index 0000000..c7c04d7 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.less @@ -0,0 +1,306 @@ +@import "plugins/drag_drop"; +@import "plugins/dropdown_header"; +@import "plugins/optgroup_columns"; +@import "plugins/remove_button"; + +// base styles + +@selectize-font-family: inherit; +@selectize-font-smoothing: inherit; +@selectize-font-size: 13px; +@selectize-line-height: 18px; + +@selectize-color-text: #303030; +@selectize-color-border: #d0d0d0; +@selectize-color-highlight: rgba(125,168,208,0.2); +@selectize-color-input: #fff; +@selectize-color-input-full: @selectize-color-input; +@selectize-color-disabled: #fafafa; +@selectize-color-item: #f2f2f2; +@selectize-color-item-text: @selectize-color-text; +@selectize-color-item-border: #d0d0d0; +@selectize-color-item-active: #e8e8e8; +@selectize-color-item-active-text: @selectize-color-text; +@selectize-color-item-active-border: #cacaca; +@selectize-color-dropdown: #fff; +@selectize-color-dropdown-border: @selectize-color-border; +@selectize-color-dropdown-border-top: #f0f0f0; +@selectize-color-dropdown-item-active: #f5fafd; +@selectize-color-dropdown-item-active-text: #495c68; +@selectize-color-dropdown-item-create-text: rgba(red(@selectize-color-text), green(@selectize-color-text), blue(@selectize-color-text), 0.5); +@selectize-color-dropdown-item-create-active-text: @selectize-color-dropdown-item-active-text; +@selectize-color-optgroup: @selectize-color-dropdown; +@selectize-color-optgroup-text: @selectize-color-text; +@selectize-lighten-disabled-item: 30%; +@selectize-lighten-disabled-item-text: 30%; +@selectize-lighten-disabled-item-border: 30%; +@selectize-opacity-disabled: 0.5; + +@selectize-shadow-input: inset 0 1px 1px rgba(0,0,0,0.1); +@selectize-shadow-input-focus: inset 0 1px 2px rgba(0,0,0,0.15); +@selectize-border: 1px solid @selectize-color-border; +@selectize-dropdown-border: 1px solid @selectize-color-dropdown-border; +@selectize-border-radius: 3px; + +@selectize-width-item-border: 0; +@selectize-max-height-dropdown: 200px; + +@selectize-padding-x: 8px; +@selectize-padding-y: 8px; +@selectize-padding-item-x: 6px; +@selectize-padding-item-y: 2px; +@selectize-padding-dropdown-item-x: @selectize-padding-x; +@selectize-padding-dropdown-item-y: 5px; +@selectize-margin-item-x: 3px; +@selectize-margin-item-y: 3px; + +@selectize-arrow-size: 5px; +@selectize-arrow-color: #808080; +@selectize-arrow-offset: 15px; + +@selectize-caret-margin: 0 2px 0 0; +@selectize-caret-margin-rtl: 0 4px 0 -2px; + +.selectize-border-radius (@radii) { + -webkit-border-radius: @radii; + -moz-border-radius: @radii; + border-radius: @radii; +} +.selectize-unselectable () { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.selectize-box-shadow (@shadow) { + -webkit-box-shadow: @shadow; + box-shadow: @shadow; +} +.selectize-box-sizing (@type: border-box) { + -webkit-box-sizing: @type; + -moz-box-sizing: @type; + box-sizing: @type; +} +.selectize-vertical-gradient (@color-top, @color-bottom) { + background-color: mix(@color-top, @color-bottom, 60%); + background-image: -moz-linear-gradient(top, @color-top, @color-bottom); // FF 3.6+ + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@color-top), to(@color-bottom)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(top, @color-top, @color-bottom); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(top, @color-top, @color-bottom); // Opera 11.10 + background-image: linear-gradient(to bottom, @color-top, @color-bottom); // Standard, IE10 + background-repeat: repeat-x; + filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@color-top),argb(@color-bottom))); // IE9 and down +} + +.selectize-control { + position: relative; +} + +.selectize-dropdown, .selectize-input, .selectize-input input { + color: @selectize-color-text; + font-family: @selectize-font-family; + font-size: @selectize-font-size; + line-height: @selectize-line-height; + -webkit-font-smoothing: @selectize-font-smoothing; +} + +.selectize-input, .selectize-control.single .selectize-input.input-active { + background: @selectize-color-input; + cursor: text; + display: inline-block; +} + +.selectize-input { + border: @selectize-border; + padding: @selectize-padding-y @selectize-padding-x; + display: inline-block; + width: 100%; + overflow: hidden; + position: relative; + z-index: 1; + .selectize-box-sizing(border-box); + .selectize-box-shadow(@selectize-shadow-input); + .selectize-border-radius(@selectize-border-radius); + + .selectize-control.multi &.has-items { + @padding-x: @selectize-padding-x; + @padding-top: @selectize-padding-y - @selectize-padding-item-y - @selectize-width-item-border; + @padding-bottom: @selectize-padding-y - @selectize-padding-item-y - @selectize-margin-item-y - @selectize-width-item-border; + padding: @padding-top @padding-x @padding-bottom; + } + + &.full { + background-color: @selectize-color-input-full; + } + &.disabled, &.disabled * { + cursor: default !important; + } + &.focus { + .selectize-box-shadow(@selectize-shadow-input-focus); + } + &.dropdown-active { + .selectize-border-radius(@selectize-border-radius @selectize-border-radius 0 0); + } + + > * { + vertical-align: baseline; + display: -moz-inline-stack; + display: inline-block; + zoom: 1; + *display: inline; + } + .selectize-control.multi & > div { + cursor: pointer; + margin: 0 @selectize-margin-item-x @selectize-margin-item-y 0; + padding: @selectize-padding-item-y @selectize-padding-item-x; + background: @selectize-color-item; + color: @selectize-color-item-text; + border: @selectize-width-item-border solid @selectize-color-item-border; + + &.active { + background: @selectize-color-item-active; + color: @selectize-color-item-active-text; + border: @selectize-width-item-border solid @selectize-color-item-active-border; + } + } + .selectize-control.multi &.disabled > div { + &, &.active { + color: lighten(desaturate(@selectize-color-item-text, 100%), @selectize-lighten-disabled-item-text); + background: lighten(desaturate(@selectize-color-item, 100%), @selectize-lighten-disabled-item); + border: @selectize-width-item-border solid lighten(desaturate(@selectize-color-item-border, 100%), @selectize-lighten-disabled-item-border); + } + } + > input { + &::-ms-clear { + display: none; + } + display: inline-block !important; + padding: 0 !important; + min-height: 0 !important; + max-height: none !important; + max-width: 100% !important; + margin: @selectize-caret-margin !important; + text-indent: 0 !important; + border: 0 none !important; + background: none !important; + line-height: inherit !important; + -webkit-user-select: auto !important; + .selectize-box-shadow(none) !important; + &:focus { outline: none !important; } + &[placeholder] { + box-sizing: initial; + } + } +} + +.selectize-input::after { + content: ' '; + display: block; + clear: left; +} + +.selectize-input.dropdown-active::before { + content: ' '; + display: block; + position: absolute; + background: @selectize-color-dropdown-border-top; + height: 1px; + bottom: 0; + left: 0; + right: 0; +} + +.selectize-dropdown { + position: absolute; + z-index: 10; + border: @selectize-dropdown-border; + background: @selectize-color-dropdown; + margin: -1px 0 0 0; + border-top: 0 none; + .selectize-box-sizing(border-box); + .selectize-box-shadow(0 1px 3px rgba(0,0,0,0.1)); + .selectize-border-radius(0 0 @selectize-border-radius @selectize-border-radius); + + [data-selectable] { + cursor: pointer; + overflow: hidden; + .highlight { + background: @selectize-color-highlight; + .selectize-border-radius(1px); + } + } + .option, .optgroup-header { + padding: @selectize-padding-dropdown-item-y @selectize-padding-dropdown-item-x; + } + .option, [data-disabled], [data-disabled] [data-selectable].option { + cursor: inherit; + opacity: 0.5; + } + [data-selectable].option { + opacity: 1; + } + .optgroup:first-child .optgroup-header { + border-top: 0 none; + } + .optgroup-header { + color: @selectize-color-optgroup-text; + background: @selectize-color-optgroup; + cursor: default; + } + .active { + background-color: @selectize-color-dropdown-item-active; + color: @selectize-color-dropdown-item-active-text; + &.create { + color: @selectize-color-dropdown-item-create-active-text; + } + } + .create { + color: @selectize-color-dropdown-item-create-text; + } +} + +.selectize-dropdown-content { + overflow-y: auto; + overflow-x: hidden; + max-height: @selectize-max-height-dropdown; + -webkit-overflow-scrolling: touch; +} + +.selectize-control.single .selectize-input { + &, input { cursor: pointer; } + &.input-active, &.input-active input { cursor: text; } + + &:after { + content: ' '; + display: block; + position: absolute; + top: 50%; + right: @selectize-arrow-offset; + margin-top: round((-1 * @selectize-arrow-size / 2)); + width: 0; + height: 0; + border-style: solid; + border-width: @selectize-arrow-size @selectize-arrow-size 0 @selectize-arrow-size; + border-color: @selectize-arrow-color transparent transparent transparent; + } + &.dropdown-active:after { + margin-top: @selectize-arrow-size * -0.8; + border-width: 0 @selectize-arrow-size @selectize-arrow-size @selectize-arrow-size; + border-color: transparent transparent @selectize-arrow-color transparent; + } +} + +.selectize-control.rtl { + &.single .selectize-input:after { + left: @selectize-arrow-offset; + right: auto; + } + .selectize-input > input { + margin: @selectize-caret-margin-rtl !important; + } +} + +.selectize-control .selectize-input.disabled { + opacity: @selectize-opacity-disabled; + background-color: @selectize-color-disabled; +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.min.css b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.min.css new file mode 100644 index 0000000..a28edda --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/css/selectize/selectize.min.css @@ -0,0 +1 @@ +.selectize-control.plugin-drag_drop.multi>.selectize-input>div.ui-sortable-placeholder{visibility:visible!important;background:#f2f2f2!important;background:rgba(0,0,0,.06)!important;border:0!important;-webkit-box-shadow:inset 0 0 12px 4px #fff;box-shadow:inset 0 0 12px 4px #fff}.selectize-control.plugin-drag_drop .ui-sortable-placeholder::after{content:'!';visibility:hidden}.selectize-control.plugin-drag_drop .ui-sortable-helper{-webkit-box-shadow:0 2px 5px rgba(0,0,0,.2);box-shadow:0 2px 5px rgba(0,0,0,.2)}.selectize-dropdown-header{position:relative;padding:5px 8px;border-bottom:1px solid #d0d0d0;background:#f8f8f8;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-dropdown-header-close{position:absolute;right:8px;top:50%;color:#303030;opacity:.4;margin-top:-12px;line-height:20px;font-size:20px!important}.selectize-dropdown-header-close:hover{color:#000}.selectize-dropdown.plugin-optgroup_columns .optgroup{border-right:1px solid #f2f2f2;border-top:0 none;float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child{border-right:0 none}.selectize-dropdown.plugin-optgroup_columns .optgroup:before{display:none}.selectize-dropdown.plugin-optgroup_columns .optgroup-header{border-top:0 none}.selectize-control.plugin-remove_button [data-value]{position:relative;padding-right:24px!important}.selectize-control.plugin-remove_button [data-value] .remove{z-index:1;position:absolute;top:0;right:0;bottom:0;width:17px;text-align:center;font-weight:700;font-size:12px;color:inherit;text-decoration:none;vertical-align:middle;display:inline-block;padding:2px 0 0;border-left:1px solid #d0d0d0;-webkit-border-radius:0 2px 2px 0;-moz-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.selectize-control.plugin-remove_button [data-value] .remove:hover{background:rgba(0,0,0,.05)}.selectize-control.plugin-remove_button [data-value].active .remove{border-left-color:#cacaca}.selectize-control.plugin-remove_button .disabled [data-value] .remove:hover{background:0 0}.selectize-control.plugin-remove_button .disabled [data-value] .remove{border-left-color:#fff}.selectize-control.plugin-remove_button .remove-single{position:absolute;right:0;top:0;font-size:23px}.selectize-control{position:relative}.selectize-dropdown,.selectize-input,.selectize-input input{color:#303030;font-family:inherit;font-size:13px;line-height:18px;-webkit-font-smoothing:inherit}.selectize-input{cursor:text;border:1px solid #d0d0d0;padding:8px;width:100%;overflow:hidden;position:relative;z-index:1;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.1);box-shadow:inset 0 1px 1px rgba(0,0,0,.1);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.selectize-control.single .selectize-input.input-active,.selectize-input{background:#fff;display:inline-block}.selectize-control.multi .selectize-input.has-items{padding:6px 8px 3px}.selectize-input.full{background-color:#fff}.selectize-input.disabled,.selectize-input.disabled *{cursor:default!important}.selectize-input.focus{-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.15)}.selectize-input.dropdown-active{-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.selectize-input>*{vertical-align:baseline;display:-moz-inline-stack;display:inline-block;zoom:1;*display:inline}.selectize-control.multi .selectize-input>div{cursor:pointer;margin:0 3px 3px 0;padding:2px 6px;background:#f2f2f2;color:#303030;border:0 solid #d0d0d0}.selectize-control.multi .selectize-input>div.active{background:#e8e8e8;color:#303030;border:0 solid #cacaca}.selectize-control.multi .selectize-input.disabled>div,.selectize-control.multi .selectize-input.disabled>div.active{color:#7d7d7d;background:#fff;border:0 solid #fff}.selectize-input>input{display:inline-block!important;padding:0!important;min-height:0!important;max-height:none!important;max-width:100%!important;margin:0 2px 0 0!important;text-indent:0!important;border:0!important;background:0 0!important;line-height:inherit!important;-webkit-user-select:auto!important;-webkit-box-shadow:none!important;box-shadow:none!important}.selectize-input>input::-ms-clear{display:none}.selectize-input>input:focus{outline:0!important}.selectize-input>input[placeholder]{box-sizing:initial}.selectize-input::after{content:' ';display:block;clear:left}.selectize-input.dropdown-active::before{content:' ';display:block;position:absolute;background:#f0f0f0;height:1px;bottom:0;left:0;right:0}.selectize-dropdown{position:absolute;z-index:10;border:1px solid #d0d0d0;background:#fff;margin:-1px 0 0;border-top:0 none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1);-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.selectize-dropdown [data-selectable]{cursor:pointer;overflow:hidden}.selectize-dropdown [data-selectable] .highlight{background:rgba(125,168,208,.2);-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px}.selectize-dropdown .optgroup-header,.selectize-dropdown .option{padding:5px 8px}.selectize-dropdown .option,.selectize-dropdown [data-disabled],.selectize-dropdown [data-disabled] [data-selectable].option{cursor:inherit;opacity:.5}.selectize-dropdown [data-selectable].option{opacity:1}.selectize-dropdown .optgroup:first-child .optgroup-header{border-top:0 none}.selectize-dropdown .optgroup-header{color:#303030;background:#fff;cursor:default}.selectize-dropdown .active{background-color:#f5fafd;color:#495c68}.selectize-dropdown .active.create{color:#495c68}.selectize-dropdown .create{color:rgba(48,48,48,.5)}.selectize-dropdown-content{overflow-y:auto;overflow-x:hidden;max-height:200px;-webkit-overflow-scrolling:touch}.selectize-control.single .selectize-input,.selectize-control.single .selectize-input input{cursor:pointer}.selectize-control.single .selectize-input.input-active,.selectize-control.single .selectize-input.input-active input{cursor:text}.selectize-control.single .selectize-input:after{content:' ';display:block;position:absolute;top:50%;right:15px;margin-top:-3px;width:0;height:0;border-style:solid;border-width:5px 5px 0;border-color:gray transparent transparent}.selectize-control.single .selectize-input.dropdown-active:after{margin-top:-4px;border-width:0 5px 5px;border-color:transparent transparent gray}.selectize-control.rtl.single .selectize-input:after{left:15px;right:auto}.selectize-control.rtl .selectize-input>input{margin:0 4px 0 -2px!important}.selectize-control .selectize-input.disabled{opacity:.5;background-color:#fafafa} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/images/five-stars.svg b/html/wp-content/plugins/meta-tag-manager/images/five-stars.svg new file mode 100644 index 0000000..9ce8522 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/images/five-stars.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/meta-tag-manager/images/logo.png b/html/wp-content/plugins/meta-tag-manager/images/logo.png new file mode 100644 index 0000000..935e884 Binary files /dev/null and b/html/wp-content/plugins/meta-tag-manager/images/logo.png differ diff --git a/html/wp-content/plugins/meta-tag-manager/images/star-halo.svg b/html/wp-content/plugins/meta-tag-manager/images/star-halo.svg new file mode 100644 index 0000000..84bed5b --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/images/star-halo.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager-settings.js b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager-settings.js new file mode 100644 index 0000000..1fc1cb2 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager-settings.js @@ -0,0 +1,117 @@ +jQuery(document).ready(function($){ + //Meta Box Options + //$(".postbox > h2").on('click', function(){ $(this).parent().toggleClass('closed'); }); + //$(".postbox").addClass('closed'); + //Navigation Tabs + $('.tabs-active .nav-tab-wrapper .nav-tab').on('click', function(){ + el = $(this); + elid = el.attr('id'); + $('.mtm-menu-group').hide(); + $('.'+elid).show(); + //$(".postbox").addClass('closed'); + //open_close.text(EM.open_text); + }); + $('.nav-tab-wrapper .nav-tab').on('click', function(){ + $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active'); + $(this).addClass('nav-tab-active').blur(); + }); + var navUrl = document.location.toString(); + if (navUrl.match('#')) { //anchor-based navigation + var nav_tab = navUrl.split('#'); + var current_tab = 'a#mtm-menu-' + nav_tab[1]; + $(current_tab).trigger('click'); + if( nav_tab.length > 2 ){ + section = $("#mtm-opt-"+nav_tab[2]); + if( section.length > 0 ){ + section.children('h2').trigger('click'); + $('html, body').animate({ scrollTop: section.offset().top - 30 }); //sends user back to current section + } + } + }else{ + //set to general tab by default, so we can also add clicked subsections + document.location = navUrl+"#custom-meta-tags"; + } + $('.tabs-active .nav-tab-wrapper .nav-tab.nav-tab-active').trigger('click'); + $('.nav-tab-link').on('click', function(){ $($(this).attr('rel')).trigger('click'); }); //links to mimick tabs + $('input[type="submit"]').on('click', function(){ + var el = $(this).parents('.postbox').first(); + var docloc = document.location.toString().split('#'); + var newloc = docloc[0]; + if( docloc.length > 1 ){ + var nav_tab = docloc[1].split('#'); + newloc = newloc + "#" + nav_tab[0]; + if( el.attr('id') ){ + newloc = newloc + "#" + el.attr('id').replace('mtm-opt-',''); + } + } + document.location = newloc; + }); + + // settings trigger + $('.mtm-settings-binary-trigger').on('change', function(){ + var el = $(this); + if( el.prop('checked') ){ + $(el.data('trigger-content')).show(); + }else{ + $(el.data('trigger-content')).hide(); + } + }).trigger('change'); + + // image uploader + + jQuery(document).ready( function($) { + + $('.mtm-image-upload input.mtm-image-upload-submit').on('click', function(e) { + e.preventDefault(); + var wrap = $(this).closest('.mtm-image-upload'); + var image_frame; + if(image_frame){ + image_frame.open(); + } + image_frame = wp.media({ + title: 'Select Media', + multiple : false, + library : { + type : 'image', + } + }); + image_frame.on('close',function() { + // get selections and save to hidden input plus other AJAX stuff etc. + var selection = image_frame.state().get('selection'); + var gallery_ids = new Array(); + var my_index = 0; + selection.each(function(attachment) { + gallery_ids[my_index] = attachment['id']; + my_index++; + }); + var ids = gallery_ids.join(","); + wrap.find('.mtm-image-upload-input').val(ids); + // refresh image + var data = { + action: wrap.data('action'), + nonce: wrap.data('nonce'), + id: ids + }; + jQuery.get( ajaxurl, data, function (response) { + if (response.success === true) { + wrap.find('.mtm-image-upload-preview').html(response.data.image); + } + }); + }); + image_frame.on('open',function() { + var selection = image_frame.state().get('selection'); + ids = wrap.find('.mtm-image-upload-input').val().split(','); + ids.forEach(function(id) { + attachment = wp.media.attachment(id); + attachment.fetch(); + selection.add( attachment ? [ attachment ] : [] ); + }); + + }); + image_frame.on('toolbar:create:select',function() { + image_frame.state().set('filterable', 'uploaded'); + }); + image_frame.open(); + }); + }); +}); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager-settings.min.js b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager-settings.min.js new file mode 100644 index 0000000..dd74301 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager-settings.min.js @@ -0,0 +1 @@ +jQuery(document).ready(function($){$(".tabs-active .nav-tab-wrapper .nav-tab").on("click",function(){el=$(this);elid=el.attr("id");$(".mtm-menu-group").hide();$("."+elid).show()});$(".nav-tab-wrapper .nav-tab").on("click",function(){$(".nav-tab-wrapper .nav-tab").removeClass("nav-tab-active");$(this).addClass("nav-tab-active").blur()});var navUrl=document.location.toString();if(navUrl.match("#")){var nav_tab=navUrl.split("#");var current_tab="a#mtm-menu-"+nav_tab[1];$(current_tab).trigger("click");if(nav_tab.length>2){section=$("#mtm-opt-"+nav_tab[2]);if(section.length>0){section.children("h2").trigger("click");$("html, body").animate({scrollTop:section.offset().top-30})}}}else{document.location=navUrl+"#custom-meta-tags"}$(".tabs-active .nav-tab-wrapper .nav-tab.nav-tab-active").trigger("click");$(".nav-tab-link").on("click",function(){$($(this).attr("rel")).trigger("click")});$('input[type="submit"]').on("click",function(){var el=$(this).parents(".postbox").first();var docloc=document.location.toString().split("#");var newloc=docloc[0];if(docloc.length>1){var nav_tab=docloc[1].split("#");newloc=newloc+"#"+nav_tab[0];if(el.attr("id")){newloc=newloc+"#"+el.attr("id").replace("mtm-opt-","")}}document.location=newloc});$(".mtm-settings-binary-trigger").on("change",function(){var el=$(this);if(el.prop("checked")){$(el.data("trigger-content")).show()}else{$(el.data("trigger-content")).hide()}}).trigger("change");jQuery(document).ready(function($){$(".mtm-image-upload input.mtm-image-upload-submit").on("click",function(e){e.preventDefault();var wrap=$(this).closest(".mtm-image-upload");var image_frame;if(image_frame){image_frame.open()}image_frame=wp.media({title:"Select Media",multiple:false,library:{type:"image"}});image_frame.on("close",function(){var selection=image_frame.state().get("selection");var gallery_ids=new Array;var my_index=0;selection.each(function(attachment){gallery_ids[my_index]=attachment["id"];my_index++});var ids=gallery_ids.join(",");wrap.find(".mtm-image-upload-input").val(ids);var data={action:wrap.data("action"),nonce:wrap.data("nonce"),id:ids};jQuery.get(ajaxurl,data,function(response){if(response.success===true){wrap.find(".mtm-image-upload-preview").html(response.data.image)}})});image_frame.on("open",function(){var selection=image_frame.state().get("selection");ids=wrap.find(".mtm-image-upload-input").val().split(",");ids.forEach(function(id){attachment=wp.media.attachment(id);attachment.fetch();selection.add(attachment?[attachment]:[])})});image_frame.on("toolbar:create:select",function(){image_frame.state().set("filterable","uploaded")});image_frame.open()})})}); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager.js b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager.js new file mode 100644 index 0000000..7e3dc85 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager.js @@ -0,0 +1,219 @@ +jQuery(document).ready( function($) { + //initialize one or many meta tag field forms + var init_fields = function( container ){ + //add selectize for the type selector + container.find('.mtm-field-input-tag-type').each( function(e){ + if( this.value == 'charset' ){ + $(this).closest('.mtm-field').find('.mtm-field-type-content').show(); + } + }); + container.find('.mtm-field-input-tag-type').selectize().on('change', function(e){ + var parent = $(this).closest('.mtm-field'); + parent.find('.mtm-field-type-content').hide(); + if( this.value != 'charset' ){ + parent.find('.mtm-field-type-content').show(); + } + //get value input from template and selectize + var value_template = $(this).closest('.mtm-builder').find('.mtm-field-type-templates .mtm-field-input-tag-'+this.value).first().clone(); + if( value_template.length > 0 ){ + //clone, rename, selectize + value_template = value_template.clone(); + var current_value = parent.find('select.mtm-field-input-tag-value, input.mtm-field-input-tag-value'); + var current_value_name = current_value.attr('name'); + current_value.each(function(){ if( typeof this.selectize != 'undefined' ) this.selectize.destroy(); }).replaceWith(value_template); + parent.find('.mtm-field-input.mtm-field-type-value label em').text(this.value); + value_template.attr('name', current_value_name).trigger('change'); + if( value_template.is('select') ) value_template.selectize({ create: true }); + } + }); + //add selectize for contexts, which is a tag-style selection + var selectize_context_options = { + plugins: ['remove_button'], + maxItems: 100, + closeAfterSelect: true, + //add some extra functions in case 'all' is selected, hence no need to select other things + onItemAdd: function(value, item){ + if( this.items.length > 1 ){ + if( value == 'all' ){ + this.clear(true); + this.addItem('all', true); + //this.settings.maxItems = 1; + }else if( this.getItem('all').length ){ + this.removeItem('all', true); + } + } + }, + //update display values on header of field card + onChange: function(items){ + var field = this.$control.closest('.mtm-field'); + var context_class = $(this.$input[0]).data('values-container'); + var context_text_class = $(this.$input[0]).data('values-text'); + var context_default = $(this.$input[0]).data('values-default'); + if( items.length == 0 ){ + if( context_default ){ + var default_option = this.options[context_default]; + var default_text = this.options.all.text; + field.find('.' + context_text_class).text(default_text); + }else{ + field.find('.' + context_text_class).text(''); + field.find('.' + context_class).first().hide(); + } + }else { + var values = []; + if (typeof items == 'object' && items) { + items.forEach(function (item) { + values.push(this.getItem(item).text().replace(/×$/i, '')); + }, this); + } + field.find('.' + context_class).first().show(); + field.find('.' + context_text_class).text(values.join(', ')); + } + } + }; + $(document).triggerHandler('mtm_selectize_context_options', [selectize_context_options]); + container.find('.mtm-field-input-tag-context').selectize(selectize_context_options).on('click', function(){ this.selectize.open(); }); + //general selectize for other selectizable dropdowns + container.find('.mtm-field-input-selectize').selectize({ + create: true, + }); + container.find('.mtm-field-input-tag-reference').hide(); + $(document).triggerHandler('mtm_tag_init', [container]); + } + //init displayed fields on page load + $('.mtm-builder .mtm-fields .mtm-field').addClass('closed') + init_fields($('.mtm-builder .mtm-fields')); + + //build meta tag dynamically + var build_meta_tag = function( container ){ + var meta_type = container.find('.mtm-field-input-tag-type option:selected').val(); + if( meta_type ){ + container.find('.mtm-field-title code').show(); + var meta_value = container.find('select.mtm-field-input-tag-'+ meta_type +' option:selected').val(); + container.find('.mtm-field-title code .mtm-meta-type-att').text(meta_type).css('opacity','0.1').animate({'opacity':'1'}); + container.find('.mtm-field-title code .mtm-meta-type-val').text(meta_value).css('opacity','0.1').animate({'opacity':'1'}); + if( meta_type == 'charset' ){ + container.find('.mtm-field-title code .mtm-meta-content').hide(); + }else{ + container.find('.mtm-field-title code .mtm-meta-content').fadeIn().children('.mtm-meta-content-value').text(container.find('.mtm-field-input-tag-content').val()).css('opacity','0.1').animate({'opacity':'1'}); + } + } + } + $('.mtm-builder').on('change', '.mtm-field-input-tag-type', function(){ + build_meta_tag( $(this).closest('.mtm-field') ); + }); + $('.mtm-builder').on('keyup change', '.mtm-field-input-tag-content', function(){ + $(this).closest('.mtm-field').find('.mtm-field-title code .mtm-meta-content-value').css('opacity','0.1').animate({'opacity':'1'}).text(this.value); + }); + $('.mtm-builder').on('change keyup', '.mtm-field-input-tag-value', function(){ + $(this).closest('.mtm-field').find('.mtm-field-title code .mtm-meta-type-val').css('opacity','0.1').animate({'opacity':'1'}).text(this.value); + }); + $('.mtm-builder').on('keyup change', '.mtm-field-input-tag-reference', function(){ + $(this).closest('.mtm-field').find('.mtm-field-title .mtm-meta-reference .mtm-meta-reference-value').text(this.value); + }); + $('.mtm-builder').on('blur', '.mtm-field-input-tag-reference', function(e){ + e.preventDefault(); + }); + + //make sortable + $(".mtm-builder .mtm-fields" ).sortable({ + placeholder: "mtm-field-placeholder", + handle: '.mtm-field-header', + start: function( event, ui ){ + ui.item.addClass('closed').data('openField', false); + ui.item.css('height', 'auto'); + } + }); + //actions for field cards + $('.mtm-builder').on('mousedown mouseup', '.mtm-field-header, button.mtm-field-close', function(e){ + //open/close functionality for fields + if( $(e.target).hasClass('mtm-field-input-tag-reference') ) return; + var field = $(this).closest('.mtm-field'); + if( e.type == 'mousedown' ){ + field.data('openField', field.hasClass('closed')); //allow sortable overriding + field.addClass('closed'); + field.find('.mtm-meta-reference .mtm-meta-reference-value').show(); + field.find('.mtm-meta-reference .mtm-field-input-tag-reference').hide(); + }else if( field.data('openField') ){ + field.siblings('.mtm-field').addClass('closed'); + field.removeClass('closed'); + field.find('.mtm-meta-reference .mtm-meta-reference-value').hide(); + field.find('.mtm-meta-reference .mtm-field-input-tag-reference').show(); + } + }).on('click', '.mtm-field-remove', function(){ + //removing a card + if( $(this).closest('.mtm-fields').children('.mtm-field').length <= 1 ){ + $(this).closest('.mtm-builder').find('.mtm-field-placeholder').show(); + } + $(this).closest('.mtm-field').remove(); + }).on('click', '.mtm-add-field', function(e){ + //adding a field + e.preventDefault(); + var container = $(this).closest('.mtm-builder'); + container.find('.mtm-field-placeholder').hide(); + container.find('.mtm-field').addClass('closed'); + var index = container.data('nextIndex'); + container.data('nextIndex', index + 1); + var new_field = $('.mtm-field-template .mtm-field').clone().data('thisIndex', index); + new_field.find("[name*='[t]']").each( function( i ){ + var new_attribute = $(this).attr('name').replace('mtm-fields[t]', 'mtm-fields['+ index +']'); + $(this).attr('name', new_attribute); + }); + $('.mtm-builder .mtm-fields').append(new_field); + init_fields(new_field); + new_field.removeClass('closed'); + new_field.find('.mtm-meta-reference .mtm-meta-reference-value').hide(); + new_field.find('.mtm-meta-reference .mtm-field-input-tag-reference').show(); + $(this).blur(); + }).data('nextIndex', $('.mtm-builder .mtm-fields .mtm-field').length); //set index counter + + $('.mtm-settings .mtm-post-types .mtm-post-types-select').selectize({ + plugins: ['remove_button'], + maxItems: 100, + closeAfterSelect: false + }).on('click', function(){ this.selectize.open(); }); + + + // Modal Open/Close + let openModal = function( modal, onOpen = null ){ + modal = jQuery(modal); + modal.appendTo(document.body); + setTimeout( function(){ + modal.addClass('active').find('.mtm-modal-popup').addClass('active'); + jQuery(document).triggerHandler('mtm_modal_open', [modal]); + if( typeof onOpen === 'function' ){ + setTimeout( onOpen, 200); // timeout allows css transition + } + }, 100); // timeout allows css transition + }; + let closeModal = function( modal, onClose = null ){ + modal = jQuery(modal); + modal.removeClass('active').find('.mtm-modal-popup').removeClass('active'); + setTimeout( function(){ + if( modal.attr('data-parent') ){ + let wrapper = jQuery('#' + modal.attr('data-parent') ); + if( wrapper.length ) { + modal.appendTo(wrapper); + } + } + modal.triggerHandler('mtm_modal_close'); + if( typeof onClose === 'function' ){ + onClose(); + } + }, 500); // timeout allows css transition + } + jQuery(document).on('click', '.mtm-modal .mtm-close-modal', function(e){ + let modal = jQuery(this).closest('.mtm-modal'); + if( !modal.attr('data-prevent-close') ) { + closeModal(modal); + } + }); + jQuery(document).on('click', '.mtm-modal', function(e){ + var target = jQuery(e.target); + if( target.hasClass('mtm-modal') ) { + let modal = jQuery(this); + if( !modal.attr('data-prevent-close') ){ + closeModal(modal); + } + } + }); +}); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager.min.js b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager.min.js new file mode 100644 index 0000000..44cac63 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/js/meta-tag-manager.min.js @@ -0,0 +1 @@ +jQuery(document).ready(function($){var init_fields=function(container){container.find(".mtm-field-input-tag-type").each(function(e){if(this.value=="charset"){$(this).closest(".mtm-field").find(".mtm-field-type-content").show()}});container.find(".mtm-field-input-tag-type").selectize().on("change",function(e){var parent=$(this).closest(".mtm-field");parent.find(".mtm-field-type-content").hide();if(this.value!="charset"){parent.find(".mtm-field-type-content").show()}var value_template=$(this).closest(".mtm-builder").find(".mtm-field-type-templates .mtm-field-input-tag-"+this.value).first().clone();if(value_template.length>0){value_template=value_template.clone();var current_value=parent.find("select.mtm-field-input-tag-value, input.mtm-field-input-tag-value");var current_value_name=current_value.attr("name");current_value.each(function(){if(typeof this.selectize!="undefined")this.selectize.destroy()}).replaceWith(value_template);parent.find(".mtm-field-input.mtm-field-type-value label em").text(this.value);value_template.attr("name",current_value_name).trigger("change");if(value_template.is("select"))value_template.selectize({create:true})}});var selectize_context_options={plugins:["remove_button"],maxItems:100,closeAfterSelect:true,onItemAdd:function(value,item){if(this.items.length>1){if(value=="all"){this.clear(true);this.addItem("all",true)}else if(this.getItem("all").length){this.removeItem("all",true)}}},onChange:function(items){var field=this.$control.closest(".mtm-field");var context_class=$(this.$input[0]).data("values-container");var context_text_class=$(this.$input[0]).data("values-text");var context_default=$(this.$input[0]).data("values-default");if(items.length==0){if(context_default){var default_option=this.options[context_default];var default_text=this.options.all.text;field.find("."+context_text_class).text(default_text)}else{field.find("."+context_text_class).text("");field.find("."+context_class).first().hide()}}else{var values=[];if(typeof items=="object"&&items){items.forEach(function(item){values.push(this.getItem(item).text().replace(/×$/i,""))},this)}field.find("."+context_class).first().show();field.find("."+context_text_class).text(values.join(", "))}}};$(document).triggerHandler("mtm_selectize_context_options",[selectize_context_options]);container.find(".mtm-field-input-tag-context").selectize(selectize_context_options).on("click",function(){this.selectize.open()});container.find(".mtm-field-input-selectize").selectize({create:true});container.find(".mtm-field-input-tag-reference").hide();$(document).triggerHandler("mtm_tag_init",[container])};$(".mtm-builder .mtm-fields .mtm-field").addClass("closed");init_fields($(".mtm-builder .mtm-fields"));var build_meta_tag=function(container){var meta_type=container.find(".mtm-field-input-tag-type option:selected").val();if(meta_type){container.find(".mtm-field-title code").show();var meta_value=container.find("select.mtm-field-input-tag-"+meta_type+" option:selected").val();container.find(".mtm-field-title code .mtm-meta-type-att").text(meta_type).css("opacity","0.1").animate({opacity:"1"});container.find(".mtm-field-title code .mtm-meta-type-val").text(meta_value).css("opacity","0.1").animate({opacity:"1"});if(meta_type=="charset"){container.find(".mtm-field-title code .mtm-meta-content").hide()}else{container.find(".mtm-field-title code .mtm-meta-content").fadeIn().children(".mtm-meta-content-value").text(container.find(".mtm-field-input-tag-content").val()).css("opacity","0.1").animate({opacity:"1"})}}};$(".mtm-builder").on("change",".mtm-field-input-tag-type",function(){build_meta_tag($(this).closest(".mtm-field"))});$(".mtm-builder").on("keyup change",".mtm-field-input-tag-content",function(){$(this).closest(".mtm-field").find(".mtm-field-title code .mtm-meta-content-value").css("opacity","0.1").animate({opacity:"1"}).text(this.value)});$(".mtm-builder").on("change keyup",".mtm-field-input-tag-value",function(){$(this).closest(".mtm-field").find(".mtm-field-title code .mtm-meta-type-val").css("opacity","0.1").animate({opacity:"1"}).text(this.value)});$(".mtm-builder").on("keyup change",".mtm-field-input-tag-reference",function(){$(this).closest(".mtm-field").find(".mtm-field-title .mtm-meta-reference .mtm-meta-reference-value").text(this.value)});$(".mtm-builder").on("blur",".mtm-field-input-tag-reference",function(e){e.preventDefault()});$(".mtm-builder .mtm-fields").sortable({placeholder:"mtm-field-placeholder",handle:".mtm-field-header",start:function(event,ui){ui.item.addClass("closed").data("openField",false);ui.item.css("height","auto")}});$(".mtm-builder").on("mousedown mouseup",".mtm-field-header, button.mtm-field-close",function(e){if($(e.target).hasClass("mtm-field-input-tag-reference"))return;var field=$(this).closest(".mtm-field");if(e.type=="mousedown"){field.data("openField",field.hasClass("closed"));field.addClass("closed");field.find(".mtm-meta-reference .mtm-meta-reference-value").show();field.find(".mtm-meta-reference .mtm-field-input-tag-reference").hide()}else if(field.data("openField")){field.siblings(".mtm-field").addClass("closed");field.removeClass("closed");field.find(".mtm-meta-reference .mtm-meta-reference-value").hide();field.find(".mtm-meta-reference .mtm-field-input-tag-reference").show()}}).on("click",".mtm-field-remove",function(){if($(this).closest(".mtm-fields").children(".mtm-field").length<=1){$(this).closest(".mtm-builder").find(".mtm-field-placeholder").show()}$(this).closest(".mtm-field").remove()}).on("click",".mtm-add-field",function(e){e.preventDefault();var container=$(this).closest(".mtm-builder");container.find(".mtm-field-placeholder").hide();container.find(".mtm-field").addClass("closed");var index=container.data("nextIndex");container.data("nextIndex",index+1);var new_field=$(".mtm-field-template .mtm-field").clone().data("thisIndex",index);new_field.find("[name*='[t]']").each(function(i){var new_attribute=$(this).attr("name").replace("mtm-fields[t]","mtm-fields["+index+"]");$(this).attr("name",new_attribute)});$(".mtm-builder .mtm-fields").append(new_field);init_fields(new_field);new_field.removeClass("closed");new_field.find(".mtm-meta-reference .mtm-meta-reference-value").hide();new_field.find(".mtm-meta-reference .mtm-field-input-tag-reference").show();$(this).blur()}).data("nextIndex",$(".mtm-builder .mtm-fields .mtm-field").length);$(".mtm-settings .mtm-post-types .mtm-post-types-select").selectize({plugins:["remove_button"],maxItems:100,closeAfterSelect:false}).on("click",function(){this.selectize.open()});let openModal=function(modal,onOpen=null){modal=jQuery(modal);modal.appendTo(document.body);setTimeout(function(){modal.addClass("active").find(".mtm-modal-popup").addClass("active");jQuery(document).triggerHandler("mtm_modal_open",[modal]);if(typeof onOpen==="function"){setTimeout(onOpen,200)}},100)};let closeModal=function(modal,onClose=null){modal=jQuery(modal);modal.removeClass("active").find(".mtm-modal-popup").removeClass("active");setTimeout(function(){if(modal.attr("data-parent")){let wrapper=jQuery("#"+modal.attr("data-parent"));if(wrapper.length){modal.appendTo(wrapper)}}modal.triggerHandler("mtm_modal_close");if(typeof onClose==="function"){onClose()}},500)};jQuery(document).on("click",".mtm-modal .mtm-close-modal",function(e){let modal=jQuery(this).closest(".mtm-modal");if(!modal.attr("data-prevent-close")){closeModal(modal)}});jQuery(document).on("click",".mtm-modal",function(e){var target=jQuery(e.target);if(target.hasClass("mtm-modal")){let modal=jQuery(this);if(!modal.attr("data-prevent-close")){closeModal(modal)}}})}); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/js/selectize.js b/html/wp-content/plugins/meta-tag-manager/js/selectize.js new file mode 100644 index 0000000..66b7d2d --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/js/selectize.js @@ -0,0 +1,4063 @@ +/** + * sifter.js + * Copyright (c) 2013–2020 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.Sifter = factory(); + } +}(this, function() { + + /** + * Textually searches arrays and hashes of objects + * by property (or multiple properties). Designed + * specifically for autocomplete. + * + * @constructor + * @param {array|object} items + * @param {object} items + */ + var Sifter = function(items, settings) { + this.items = items; + this.settings = settings || {diacritics: true}; + }; + + /** + * Splits a search string into an array of individual + * regexps to be used to match results. + * + * @param {string} query + * @returns {array} + */ + Sifter.prototype.tokenize = function(query, respect_word_boundaries) { + query = trim(String(query || '').toLowerCase()); + if (!query || !query.length) return []; + + var i, n, regex, letter; + var tokens = []; + var words = query.split(/ +/); + + for (i = 0, n = words.length; i < n; i++) { + regex = escape_regex(words[i]); + if (this.settings.diacritics) { + for (letter in DIACRITICS) { + if (DIACRITICS.hasOwnProperty(letter)) { + regex = regex.replace(new RegExp(letter, 'g'), DIACRITICS[letter]); + } + } + } + if (respect_word_boundaries) regex = "\\b"+regex + tokens.push({ + string : words[i], + regex : new RegExp(regex, 'i') + }); + } + + return tokens; + }; + + /** + * Iterates over arrays and hashes. + * + * ``` + * this.iterator(this.items, function(item, id) { + * // invoked for each item + * }); + * ``` + * + * @param {array|object} object + */ + Sifter.prototype.iterator = function(object, callback) { + var iterator; + if (is_array(object)) { + iterator = Array.prototype.forEach || function(callback) { + for (var i = 0, n = this.length; i < n; i++) { + callback(this[i], i, this); + } + }; + } else { + iterator = function(callback) { + for (var key in this) { + if (this.hasOwnProperty(key)) { + callback(this[key], key, this); + } + } + }; + } + + iterator.apply(object, [callback]); + }; + + /** + * Returns a function to be used to score individual results. + * + * Good matches will have a higher score than poor matches. + * If an item is not a match, 0 will be returned by the function. + * + * @param {object|string} search + * @param {object} options (optional) + * @returns {function} + */ + Sifter.prototype.getScoreFunction = function(search, options) { + var self, fields, tokens, token_count, nesting; + + self = this; + search = self.prepareSearch(search, options); + tokens = search.tokens; + fields = search.options.fields; + token_count = tokens.length; + nesting = search.options.nesting; + + /** + * Calculates how close of a match the + * given value is against a search token. + * + * @param {mixed} value + * @param {object} token + * @return {number} + */ + var scoreValue = function(value, token) { + var score, pos; + + if (!value) return 0; + value = String(value || ''); + pos = value.search(token.regex); + if (pos === -1) return 0; + score = token.string.length / value.length; + if (pos === 0) score += 0.5; + return score; + }; + + /** + * Calculates the score of an object + * against the search query. + * + * @param {object} token + * @param {object} data + * @return {number} + */ + var scoreObject = (function() { + var field_count = fields.length; + if (!field_count) { + return function() { return 0; }; + } + if (field_count === 1) { + return function(token, data) { + return scoreValue(getattr(data, fields[0], nesting), token); + }; + } + return function(token, data) { + for (var i = 0, sum = 0; i < field_count; i++) { + sum += scoreValue(getattr(data, fields[i], nesting), token); + } + return sum / field_count; + }; + })(); + + if (!token_count) { + return function() { return 0; }; + } + if (token_count === 1) { + return function(data) { + return scoreObject(tokens[0], data); + }; + } + + if (search.options.conjunction === 'and') { + return function(data) { + var score; + for (var i = 0, sum = 0; i < token_count; i++) { + score = scoreObject(tokens[i], data); + if (score <= 0) return 0; + sum += score; + } + return sum / token_count; + }; + } else { + return function(data) { + for (var i = 0, sum = 0; i < token_count; i++) { + sum += scoreObject(tokens[i], data); + } + return sum / token_count; + }; + } + }; + + /** + * Returns a function that can be used to compare two + * results, for sorting purposes. If no sorting should + * be performed, `null` will be returned. + * + * @param {string|object} search + * @param {object} options + * @return function(a,b) + */ + Sifter.prototype.getSortFunction = function(search, options) { + var i, n, self, field, fields, fields_count, multiplier, multipliers, get_field, implicit_score, sort; + + self = this; + search = self.prepareSearch(search, options); + sort = (!search.query && options.sort_empty) || options.sort; + + /** + * Fetches the specified sort field value + * from a search result item. + * + * @param {string} name + * @param {object} result + * @return {mixed} + */ + get_field = function(name, result) { + if (name === '$score') return result.score; + return getattr(self.items[result.id], name, options.nesting); + }; + + // parse options + fields = []; + if (sort) { + for (i = 0, n = sort.length; i < n; i++) { + if (search.query || sort[i].field !== '$score') { + fields.push(sort[i]); + } + } + } + + // the "$score" field is implied to be the primary + // sort field, unless it's manually specified + if (search.query) { + implicit_score = true; + for (i = 0, n = fields.length; i < n; i++) { + if (fields[i].field === '$score') { + implicit_score = false; + break; + } + } + if (implicit_score) { + fields.unshift({field: '$score', direction: 'desc'}); + } + } else { + for (i = 0, n = fields.length; i < n; i++) { + if (fields[i].field === '$score') { + fields.splice(i, 1); + break; + } + } + } + + multipliers = []; + for (i = 0, n = fields.length; i < n; i++) { + multipliers.push(fields[i].direction === 'desc' ? -1 : 1); + } + + // build function + fields_count = fields.length; + if (!fields_count) { + return null; + } else if (fields_count === 1) { + field = fields[0].field; + multiplier = multipliers[0]; + return function(a, b) { + return multiplier * cmp( + get_field(field, a), + get_field(field, b) + ); + }; + } else { + return function(a, b) { + var i, result, a_value, b_value, field; + for (i = 0; i < fields_count; i++) { + field = fields[i].field; + result = multipliers[i] * cmp( + get_field(field, a), + get_field(field, b) + ); + if (result) return result; + } + return 0; + }; + } + }; + + /** + * Parses a search query and returns an object + * with tokens and fields ready to be populated + * with results. + * + * @param {string} query + * @param {object} options + * @returns {object} + */ + Sifter.prototype.prepareSearch = function(query, options) { + if (typeof query === 'object') return query; + + options = extend({}, options); + + var option_fields = options.fields; + var option_sort = options.sort; + var option_sort_empty = options.sort_empty; + + if (option_fields && !is_array(option_fields)) options.fields = [option_fields]; + if (option_sort && !is_array(option_sort)) options.sort = [option_sort]; + if (option_sort_empty && !is_array(option_sort_empty)) options.sort_empty = [option_sort_empty]; + + return { + options : options, + query : String(query || '').toLowerCase(), + tokens : this.tokenize(query, options.respect_word_boundaries), + total : 0, + items : [] + }; + }; + + /** + * Searches through all items and returns a sorted array of matches. + * + * The `options` parameter can contain: + * + * - fields {string|array} + * - sort {array} + * - score {function} + * - filter {bool} + * - limit {integer} + * + * Returns an object containing: + * + * - options {object} + * - query {string} + * - tokens {array} + * - total {int} + * - items {array} + * + * @param {string} query + * @param {object} options + * @returns {object} + */ + Sifter.prototype.search = function(query, options) { + var self = this, value, score, search, calculateScore; + var fn_sort; + var fn_score; + + search = this.prepareSearch(query, options); + options = search.options; + query = search.query; + + // generate result scoring function + fn_score = options.score || self.getScoreFunction(search); + + // perform search and sort + if (query.length) { + self.iterator(self.items, function(item, id) { + score = fn_score(item); + if (options.filter === false || score > 0) { + search.items.push({'score': score, 'id': id}); + } + }); + } else { + self.iterator(self.items, function(item, id) { + search.items.push({'score': 1, 'id': id}); + }); + } + + fn_sort = self.getSortFunction(search, options); + if (fn_sort) search.items.sort(fn_sort); + + // apply limits + search.total = search.items.length; + if (typeof options.limit === 'number') { + search.items = search.items.slice(0, options.limit); + } + + return search; + }; + + // utilities + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + var cmp = function(a, b) { + if (typeof a === 'number' && typeof b === 'number') { + return a > b ? 1 : (a < b ? -1 : 0); + } + a = asciifold(String(a || '')); + b = asciifold(String(b || '')); + if (a > b) return 1; + if (b > a) return -1; + return 0; + }; + + var extend = function(a, b) { + var i, n, k, object; + for (i = 1, n = arguments.length; i < n; i++) { + object = arguments[i]; + if (!object) continue; + for (k in object) { + if (object.hasOwnProperty(k)) { + a[k] = object[k]; + } + } + } + return a; + }; + + /** + * A property getter resolving dot-notation + * @param {Object} obj The root object to fetch property on + * @param {String} name The optionally dotted property name to fetch + * @param {Boolean} nesting Handle nesting or not + * @return {Object} The resolved property value + */ + var getattr = function(obj, name, nesting) { + if (!obj || !name) return; + if (!nesting) return obj[name]; + var names = name.split("."); + while(names.length && (obj = obj[names.shift()])); + return obj; + }; + + var trim = function(str) { + return (str + '').replace(/^\s+|\s+$|/g, ''); + }; + + var escape_regex = function(str) { + return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'); + }; + + var is_array = Array.isArray || (typeof $ !== 'undefined' && $.isArray) || function(object) { + return Object.prototype.toString.call(object) === '[object Array]'; + }; + + var DIACRITICS = { + 'a': '[aḀá¸Ä‚ăÂâÇǎȺⱥȦȧẠạÄäÀàÃáĀÄÃãÅåąĄÃąĄ]', + 'b': '[bâ¢Î²Î’B฿ðŒá›’]', + 'c': '[cĆćĈĉČÄÄŠÄ‹CÌ„c̄ÇçḈḉȻȼƇƈɕᴄCc]', + 'd': '[dÄŽÄḊḋá¸á¸‘Ḍá¸á¸’ḓḎá¸ÄÄ‘D̦d̦ƉɖƊɗƋƌᵭá¶á¶‘ȡᴅDdð]', + 'e': '[eÉéÈèÊêḘḙĚěĔĕẼẽḚḛẺẻĖėËëĒēȨȩĘęᶒɆɇȄȅẾếỀá»á»„ễỂểḜá¸á¸–á¸—á¸”á¸•È†È‡áº¸áº¹á»†á»‡â±¸á´‡ï¼¥ï½…É˜ÇÆÆÎµ]', + 'f': '[fƑƒḞḟ]', + 'g': '[gɢ₲ǤǥĜÄĞğĢģƓɠĠġ]', + 'h': '[hĤĥĦħḨḩẖẖḤḥḢḣɦʰǶƕ]', + 'i': '[iÃíÌìĬĭÎîÇÇÃïḮḯĨĩĮįĪīỈỉȈȉȊȋỊịḬḭƗɨɨ̆ᵻᶖİiIıɪIi]', + 'j': '[jȷĴĵɈɉÊɟʲ]', + 'k': '[kƘƙê€êḰḱǨǩḲḳḴḵκϰ₭]', + 'l': '[lÅłĽľĻļĹĺḶḷḸḹḼḽḺḻĿŀȽƚⱠⱡⱢɫɬᶅɭȴʟLl]', + 'n': '[nŃńǸǹŇňÑñṄṅŅņṆṇṊṋṈṉN̈n̈ÆÉ²È Æžáµ°á¶‡É³ÈµÉ´ï¼®ï½ŽÅŠÅ‹]', + 'o': '[oØøÖöÓóÒòÔôǑǒÅőŎÅÈ®È¯á»Œá»ÆŸÉµÆ Æ¡á»Žá»ÅŒÅÕõǪǫȌÈÕ•Ö…]', + 'p': '[pṔṕṖṗⱣᵽƤƥᵱ]', + 'q': '[qê–ê—Ê ÉŠÉ‹ê˜ê™q̃]', + 'r': '[rŔŕɌÉŘřŖŗṘṙÈȑȒȓṚṛⱤɽ]', + 's': '[sŚśṠṡṢṣꞨꞩŜÅŠšŞşȘșS̈s̈]', + 't': '[tŤťṪṫŢţṬṭƮʈȚțṰṱṮṯƬƭ]', + 'u': '[uŬŭɄʉỤụÜüÚúÙùÛûǓǔŰűŬŭƯưỦủŪūŨũŲųȔȕ∪]', + 'v': '[vṼṽṾṿƲʋêžêŸâ±±Ê‹]', + 'w': '[wẂẃẀáºÅ´Åµáº„ẅẆẇẈẉ]', + 'x': '[xẌáºáºŠáº‹Ï‡]', + 'y': '[yÃýỲỳŶŷŸÿỸỹẎáºá»´á»µÉŽÉƳƴ]', + 'z': '[zŹźáºáº‘ŽžŻżẒẓẔẕƵƶ]' + }; + + var asciifold = (function() { + var i, n, k, chunk; + var foreignletters = ''; + var lookup = {}; + for (k in DIACRITICS) { + if (DIACRITICS.hasOwnProperty(k)) { + chunk = DIACRITICS[k].substring(2, DIACRITICS[k].length - 1); + foreignletters += chunk; + for (i = 0, n = chunk.length; i < n; i++) { + lookup[chunk.charAt(i)] = k; + } + } + } + var regexp = new RegExp('[' + foreignletters + ']', 'g'); + return function(str) { + return str.replace(regexp, function(foreignletter) { + return lookup[foreignletter]; + }).toLowerCase(); + }; + })(); + + + // export + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + return Sifter; +})); + +/** + * microplugin.js + * Copyright (c) 2013 Brian Reavis & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.MicroPlugin = factory(); + } +}(this, function() { + var MicroPlugin = {}; + + MicroPlugin.mixin = function(Interface) { + Interface.plugins = {}; + + /** + * Initializes the listed plugins (with options). + * Acceptable formats: + * + * List (without options): + * ['a', 'b', 'c'] + * + * List (with options): + * [{'name': 'a', options: {}}, {'name': 'b', options: {}}] + * + * Hash (with options): + * {'a': { ... }, 'b': { ... }, 'c': { ... }} + * + * @param {mixed} plugins + */ + Interface.prototype.initializePlugins = function(plugins) { + var i, n, key; + var self = this; + var queue = []; + + self.plugins = { + names : [], + settings : {}, + requested : {}, + loaded : {} + }; + + if (utils.isArray(plugins)) { + for (i = 0, n = plugins.length; i < n; i++) { + if (typeof plugins[i] === 'string') { + queue.push(plugins[i]); + } else { + self.plugins.settings[plugins[i].name] = plugins[i].options; + queue.push(plugins[i].name); + } + } + } else if (plugins) { + for (key in plugins) { + if (plugins.hasOwnProperty(key)) { + self.plugins.settings[key] = plugins[key]; + queue.push(key); + } + } + } + + while (queue.length) { + self.require(queue.shift()); + } + }; + + Interface.prototype.loadPlugin = function(name) { + var self = this; + var plugins = self.plugins; + var plugin = Interface.plugins[name]; + + if (!Interface.plugins.hasOwnProperty(name)) { + throw new Error('Unable to find "' + name + '" plugin'); + } + + plugins.requested[name] = true; + plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]); + plugins.names.push(name); + }; + + /** + * Initializes a plugin. + * + * @param {string} name + */ + Interface.prototype.require = function(name) { + var self = this; + var plugins = self.plugins; + + if (!self.plugins.loaded.hasOwnProperty(name)) { + if (plugins.requested[name]) { + throw new Error('Plugin has circular dependency ("' + name + '")'); + } + self.loadPlugin(name); + } + + return plugins.loaded[name]; + }; + + /** + * Registers a plugin. + * + * @param {string} name + * @param {function} fn + */ + Interface.define = function(name, fn) { + Interface.plugins[name] = { + 'name' : name, + 'fn' : fn + }; + }; + }; + + var utils = { + isArray: Array.isArray || function(vArg) { + return Object.prototype.toString.call(vArg) === '[object Array]'; + } + }; + + return MicroPlugin; +})); + + +/** + * selectize.js (v0.13.3) + * Copyright (c) 2013–2015 Brian Reavis & contributors + * Copyright (c) 2020 Selectize Team & contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF + * ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + * + * @author Brian Reavis + * @author Ris Adams + */ + +/*jshint curly:false */ +/*jshint browser:true */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery','sifter','microplugin'], factory); + } else if (typeof module === 'object' && typeof module.exports === 'object') { + module.exports = factory(require('jquery'), require('sifter'), require('microplugin')); + } else { + root.Selectize = factory(root.jQuery, root.Sifter, root.MicroPlugin); + } +}(this, function($, Sifter, MicroPlugin) { + 'use strict'; + + var highlight = function($element, pattern) { + if (typeof pattern === 'string' && !pattern.length) return; + var regex = (typeof pattern === 'string') ? new RegExp(pattern, 'i') : pattern; + + var highlight = function(node) { + var skip = 0; + // Wrap matching part of text node with highlighting , e.g. + // Soccer -> Soccer for regex = /soc/i + if (node.nodeType === 3) { + var pos = node.data.search(regex); + if (pos >= 0 && node.data.length > 0) { + var match = node.data.match(regex); + var spannode = document.createElement('span'); + spannode.className = 'highlight'; + var middlebit = node.splitText(pos); + var endbit = middlebit.splitText(match[0].length); + var middleclone = middlebit.cloneNode(true); + spannode.appendChild(middleclone); + middlebit.parentNode.replaceChild(spannode, middlebit); + skip = 1; + } + } + // Recurse element node, looking for child text nodes to highlight, unless element + // is childless, + . + */ +if( !defined('ABSPATH') ) exit; + +define('MTM_VERSION', '3.3'); +define('MTM_DIR_URL', trailingslashit(plugin_dir_url(__FILE__))); +define('MTM_DIR', dirname( __FILE__ )); //an absolute path to this directory + +class Meta_Tag_Manager { + /** loads the plugin */ + public static function init() { + // Include admin backend if needed + if ( is_admin() ) { + require_once ( 'meta-tag-manager-admin.php' ); + } + add_action ('wp_head', 'Meta_Tag_Manager::head', 1); + do_action('metatagmanager_loaded'); + } + + /** puts the meta tags in the head */ + public static function head() { + static::load('meta-tags'); + //If options form has been submitted, create a $_POST value that will be saved on databse + $meta_tags = array(); + $mtm_custom = get_option('mtm_custom'); + // load open graph + if( !empty($mtm_custom['og']['enabled']) ){ + Meta_Tag_Manager::load('open-graph'); + } + // load and output schema - front page only (for now) + if( !empty($mtm_custom['schema']['enabled']) && is_front_page() ){ + Meta_Tag_Manager::load('schema'); + } + // load and output schema - front page only (for now) + if( !empty($mtm_custom['verify']) && is_front_page() ){ + Meta_Tag_Manager::load('verify-sites'); + } + //check global tags and filter out ones we'll show for this page + $meta_tags_data = apply_filters('mtm_head_meta_tags_pre', self::get_data()); + foreach( $meta_tags_data as $tag ){ + if( $tag->is_in_context() ){ + $meta_tags[] = $tag; + } + } + //check individual post in case we have specific post meta tags to show + if( is_single() || is_page() ){ + if( !empty($mtm_custom['post-types']) && in_array(get_post_type(), $mtm_custom['post-types']) ){ + $post_meta_tags = self::get_post_data(); + //remove unique meta tags from being output within MTM (not other plugins), where specific tags take precendence + $unique_types = apply_filters('mtm_unique_meta_name_values', array('description', 'keywords')); + $meta_tags_unique_name_values = array(); + foreach( $unique_types as $name_value ){ + foreach( $meta_tags as $k => $tag ){ /* @var MTM_Tag $tag */ + if( $tag->type == 'name' && $tag->value == $name_value ){ + if( !empty($meta_tags_unique_name_values[$name_value]) ){ + //remove first one, last one takes precendence + unset($meta_tags[$meta_tags_unique_name_values[$name_value]]); + } + $meta_tags_unique_name_values[$name_value] = $k; + } + } + if( !empty($meta_tags_unique_name_values) ){ + foreach( $post_meta_tags as $k => $tag ){ + if( $tag->type == 'name' && $tag->value == $name_value && !empty($meta_tags_unique_name_values[$name_value]) ){ + unset($meta_tags[$meta_tags_unique_name_values[$name_value]]); + } + } + } + } + $meta_tags = array_merge($meta_tags, $post_meta_tags); + } + } + $meta_tags = apply_filters('mtm_head_meta_tags', $meta_tags); + //output the filtered out tags that pass validation + if( !empty($meta_tags) ){ + //add as keys to prevent duplicates + $meta_tag_strings = array(); + foreach( $meta_tags as $tag ){ + //only output valid keys + if( $tag->is_valid() ){ + $meta_tag_strings[$tag->output()] = 1; + } + } + //output tags if there are any + if( !empty($meta_tag_strings) ){ + echo "\r\n\t\t".''; + foreach( $meta_tag_strings as $tag_string => $v ){ + echo "\r\n\t\t".$tag_string; + } + echo "\r\n\t\t".''; + echo "\r\n"; + } + } + do_action('mtm_head', $meta_tags); + } + + public static function get_data(){ + $mtm_data = get_option('mtm_data'); + $meta_tags = array(); + if( is_array($mtm_data) ){ + foreach( $mtm_data as $meta_tag_data ){ + $meta_tags[] = new MTM_Tag($meta_tag_data); + } + } + return apply_filters('mtm_get_data', $meta_tags, $mtm_data); + } + + public static function get_post_data( $post_id = false ){ + if( empty($post_id) ) $post_id = get_the_ID(); + $meta_tag_data = get_post_meta($post_id, 'mtm_data', true); + if ( is_serialized( $meta_tag_data ) ) { // Don't attempt to unserialize data that wasn't serialized going in. + $meta_tag_data = @unserialize( trim( $meta_tag_data ), array('allowed_classes' => array()) ); + } + $meta_tags = array(); + if( is_array($meta_tag_data) ){ + foreach( $meta_tag_data as $tag_data ){ + $meta_tags[] = new MTM_Tag($tag_data); + } + } + return $meta_tags; + } + + // Page type conditionals + + public static function is_cpt_page( $post_type = null ){ + return apply_filters('mtm_is_cpt_page', is_singular($post_type), $post_type); + } + + public static function is_taxonomy_page( $taxonomy = null ) { + if( empty($taxonomy) ){ + $result = is_tax() || is_category() || is_tag(); + }else{ + $result = is_tax( $taxonomy ) || ($taxonomy == 'category' && is_category()) || ($taxonomy == 'post_tag' && is_tag()); + } + return apply_filters('mtm_is_taxonomy_page', $result, $taxonomy); + } + + public static function is_archive_page( $post_type = null ){ + $is_archive = is_post_type_archive( $post_type ) || get_option( 'page_for_posts' ) == get_queried_object_id(); + return apply_filters('mtm_is_archive_page', $is_archive, $post_type); + } + + public static function is_archive(){ + return apply_filters('mtm_is_archive', is_archive()); + } + + // util functions + + public static function array_merge( array &$array1, array &$array2 ) { + $merged = $array1; + foreach ( $array2 as $key => &$value ) { + if( is_array($value) && isset($merged[$key]) && is_array($merged[$key]) ){ + $merged[$key] = self::array_merge($merged[$key], $value); + } else { + $merged[$key] = $value; + } + } + return $merged; + } + + public static function load( $module = 'all' ){ + if( $module == 'meta-tags' || $module == 'all' ){ + include_once('mtm-tag.php'); + } + if( $module == 'schema' || $module == 'all'){ + include_once('classes/schema.php'); + } + if( $module == 'open-graph' || $module == 'all'){ + include_once('classes/open-graph.php'); + } + if( $module == 'verify-sites' || $module == 'all'){ + include_once('classes/verify-sites.php'); + } + if( $module == 'builder' || $module == 'all' ){ + include_once('mtm-tag.php'); + include_once('admin/mtm-builder.php'); + } + } +} +// Start this plugin once all other plugins are fully loaded +add_action( 'plugins_loaded', array('Meta_Tag_Manager', 'init'), 100 ); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/mtm-encodings.php b/html/wp-content/plugins/meta-tag-manager/mtm-encodings.php new file mode 100644 index 0000000..97eb6ac --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/mtm-encodings.php @@ -0,0 +1,16 @@ + array( 'UTF-8' ), + 'Legacy single-byte encodings' => array( + 'IBM866', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-8-I', 'ISO-8859-10', 'ISO-8859-13', + 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16', 'KOI8-R', 'KOI8-U', 'macintosh', 'windows-874', 'windows-1250', 'windows-1251', 'windows-1252', 'windows-1253', + 'windows-1254', 'windows-1255', 'windows-1256', 'windows-1257', 'windows-1258', 'x-mac-cyrillic' + ), + 'Legacy multi-byte Chinese (simplified) encodings' => array( 'GBK', 'gb18030' ), + 'Legacy multi-byte Chinese (traditional) encodings' => array( 'Big5' ), + 'Legacy multi-byte Japanese encodings' => array( 'EUC-JP', 'ISO-2022-JP', 'Shift_JIS', ), + 'Legacy multi-byte Korean encodings' => array( 'EUC-KR' ), + 'Legacy miscellaneous encodings' => array( 'replacement', 'UTF-16BE', 'UTF-16LE', 'x-user-defined' ) +)); \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/mtm-options.php b/html/wp-content/plugins/meta-tag-manager/mtm-options.php new file mode 100644 index 0000000..8520621 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/mtm-options.php @@ -0,0 +1,131 @@ + $option_value ); + }else{ + $data[$option_name][$option_key] = $option_value; + } + return $site ? update_site_option($dataset, $data) : update_option($dataset, $data); + } + + /** + * Removes an item from an array in the EM options array, it assumes the supplied option name is an array. + * + * @param string $option_name + * @param string $option_key + * @param string $dataset + * @param boolean $site + * @return boolean + */ + public static function remove( $option_name, $option_key = null, $dataset = 'mtm_data', $site = false ){ + $data = $site ? get_site_option($dataset) : get_option($dataset); + if( $option_key === null && isset($data[$option_name]) ){ + unset($data[$option_name]); + return $site ? update_site_option($dataset, $data) : update_option($dataset, $data); + }elseif( !empty($data[$option_name][$option_key]) ){ + unset($data[$option_name][$option_key]); + if( empty($data[$option_name]) ) unset($data[$option_name]); + return $site ? update_site_option($dataset, $data) : update_option($dataset, $data); + } + return false; + } + + /** + * @see Options::get() + * @param string $option_name + * @param mixed $default + * @param string $dataset + * @return boolean + */ + public static function site_get( $option_name, $default = array(), $dataset = 'mtm_data' ){ + return self::get( $option_name, $default, $dataset, true ); + } + + /** + * @see Options::set() + * @param string $option_name + * @param mixed $option_value + * @param string $dataset + * @return boolean + */ + public static function site_set( $option_name, $option_value, $dataset = 'mtm_data' ){ + return self::set( $option_name, $option_value, $dataset, true ); + } + + /** + * @see Options::add() + * @param string $option_name + * @param string $option_key + * @param mixed $option_value + * @param string $dataset + * @return boolean + */ + public static function site_add( $option_name, $option_key, $option_value, $dataset = 'mtm_data' ){ + return self::add( $option_name, $option_key, $option_value, $dataset, true ); + } + + /** + * @see Options::remove() + * @param string $option_name + * @param string $option_key + * @param string $dataset + * @return boolean + */ + public static function site_remove( $option_name, $option_key = null, $dataset = 'mtm_data' ){ + return self::remove( $option_name, $option_key, $dataset, true ); + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/mtm-tag.php b/html/wp-content/plugins/meta-tag-manager/mtm-tag.php new file mode 100644 index 0000000..a41cdf3 --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/mtm-tag.php @@ -0,0 +1,121 @@ +reference = !empty($values['reference']) ? $values['reference']:''; + $this->type = !empty($values['type']) ? $values['type']:''; + $this->value = !empty($values['value']) ? $values['value']:''; + $this->content = !empty($values['content']) ? $values['content']:''; + if( !empty($values['context']) ){ + $this->context = explode(',', $values['context']); + } + do_action('mtm_tag', $values, $this); + } + + public function output(){ + $output = apply_filters('mtm_tag_output_pre', null, $this); + if( $output !== null ){ + return apply_filters('mtm_tag_output', $output, $this); + } + $tag_string = 'type).'="'.esc_attr($this->value).'"'; + if( $this->has_content() ){ + if( $this->type == 'http-equiv' && $this->value == 'Link' ){ + //escape the attribute but allow for the ; format to pass through + $tag_string .= ' content="'.preg_replace('/<(.+)>;/', '<$1>;', esc_attr($this->get_content())).'"'; + }else{ + $tag_string .= ' content="'.esc_attr($this->get_content()).'"'; + } + } + $tag_string .= ' />'; + return apply_filters('mtm_tag_output', $tag_string, $this); + } + + public function to_array(){ + $array = array( + 'reference' => $this->reference, + 'type' => $this->type, + 'value' => $this->value + ); + if( $this->has_content() ){ + $array['content'] = $this->content; + } + if( $this->context !== false && is_array($this->context) ){ + $array['context'] = implode(',', $this->context); + } + return apply_filters('mtm_tag_to_array', $array, $this); + } + + public function is_valid(){ + $return = false; + if( in_array($this->type, static::get_types()) ){ //pass + if( !empty($this->value) ){ // pass ... so far + if( !($this->has_content() && empty($this->content)) ){ // if this doesn't pass, it fails + $return = true; //if we get here, we're good + } + } + } + return apply_filters('mtm_tag_is_valid', $return, $this); + } + + public function get_content(){ + return apply_filters('mtm_tag_get_content', $this->content, $this); + } + + public static function get_types(){ + if( empty(static::$types) ){ + static::$types = apply_filters('mtm_tag_get_types', array('name','http-equiv','charset','itemprop','property')); + } + return static::$types; + } + + public function has_content(){ + if( empty(static::$types_with_content) ){ + static::$types_with_content = apply_filters('mtm_types_with_content', array('name','http-equiv','itemprop','property')); + } + return in_array($this->type, static::$types_with_content); + } + + public function is_in_context(){ + $return = true; + if( !empty($this->context) ){ //if empty, we assume it's meant to be output everywhere + $return = static::check_context( $this->context ); + } + return apply_filters('mtm_tag_is_in_context', $return, $this); + } + + /** + * Checks if the currently displayed page meets the array of supplied contexts + * @param array $contexts + * @return bool + */ + public static function check_context( $contexts ){ + $return = empty($contexts); + foreach( $contexts as $context ){ + if( $context == 'home' && is_front_page() ){ + $return = true; + }else{ + //check post types and taxonomies + if( preg_match('/^post-type_/', $context) ){ + $post_type = str_replace('post-type_', '', $context); + if( Meta_Tag_Manager::is_cpt_page($post_type) ){ + $return = true; + } + }elseif( preg_match('/^taxonomy_/', $context) ){ + $taxonomy = str_replace('taxonomy_', '', $context); + if( Meta_Tag_Manager::is_taxonomy_page( $taxonomy ) ){ + $return = true; + } + } + } + } + return apply_filters('mtm_tag_check_context', $return, $contexts); + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/meta-tag-manager/readme.txt b/html/wp-content/plugins/meta-tag-manager/readme.txt new file mode 100644 index 0000000..17b5fce --- /dev/null +++ b/html/wp-content/plugins/meta-tag-manager/readme.txt @@ -0,0 +1,186 @@ +=== Meta Tag Manager === +Contributors: pxlite, msykes, netweblogic +Tags: meta, tags, meta tags, open graph, seo +Text Domain: meta-tag-manager +Requires at least: 3.6 +Tested up to: 6.9 +Stable tag: 3.3 +License: GPLv2 + +Easily add and manage custom meta tags to various parts of your site or on individual posts, such as Yahoo and Google verification tags. + +== Description == + +Meta Tags Manager is a powerful yet simple, lightweight plugin which allows you to add custom meta tags to your site. Features include: + +* Supports meta tags including the name, property, http-equiv, charset and itemprop attributes. +* Choose from predefined types, such as 'name="keyword"' or create your own by typing it in. +* Add meta tags to specific posts, choose what Custom Post Types to support from our settings page. +* Add global meta tags that will display on specific CPTs, Taxonomies, your front page or your whole site. +* Automatically add Open Graph details to your home page. +* Automatically add Schema and Structured Data to your home page. +* Add Google Sitelinks and Sitelinks Search markup. +* Easily add verification codes for services like Facebook, Google Webmaster Tools, Bing Webmaster Tools, Yandex and more (or... create your own custom meta tags!). + +Use cases include: + +* Adding Google and Yahoo site verification tags +* Adding additional open graph, twitter card or other social media meta info not supported by other SEO/Meta plugins + +Go Pro for many newly added features, including: + +* Dynamic placeholders to include data about the page being displayed, such as page title, comment count, thumbnail URLs and more! +* Additional contexts to add global meta tags, as well as exclusion rules for finer-grained controls. +* Shortcode support within meta descriptions, allowing for more dynamic data insertion with plugins such as ACF +* Unique tag detaction of Meta Tag Manager tags with hierarchical precedence, avoid creating duplicate meta tags. +* Taxonomy support - create meta tags for individual taxonomy term pages such as a single tag or category. +* More to come! Go Pro now and get an early-bird discount of up to 50%! + +== Installation == + +1. Upload the entire `meta-tag-manager` directory to the `/wp-content/plugins/` directory +1. Activate the plugin through the 'Plugins' menu in WordPress +1. Go to *Settings > Meta Tag Manager* +1. Start adding Meta Tags! See the FAQ for + +== Frequently Asked Questions == + += OK, I've installed the plugin, how and where do I start adding meta tags? = + +You can manage your meta tags in two areas of your WordPress dashboard. + +* Within Settings > Meta Tag Manager. + +*The general settings page is where you can add tags that appear on various areas of your site, such as your front page, archive pages, category/taxonomy pages, etc. Each tag you create can be assigned to a specific are of the site.* + +* On specific post type pages. + +*When editing a post, page, or other CPT (such as an event, product, etc.) you can add meta tags that will only be displayed on that item's page. The Meta Tag Manager will be available as an individual meta box.* + += I don't see the Meta Tag Manager meta box when editing a page on my site = + +This may be because your editing a CPT and it's not selected within our settings page for Meta Tag Management. See next question for more information. + += How do I enable/disable Meta Tag Manager for specific Custom Post Types (CPTs)? = + +By default (since 2.1) all custom post types are enabled, previous versions only had posts/pages enabled. If you install a plugin that introduces a new CPT, that also needs to be added, as it is not added automatically. + +You can add or remove this via Settings > Meta Tag Manager > General Options (tab). You'll see an input box containing a list of already enabled CPTs and you can click the input box to show and select other available CPTs to include, or click the X next to the CPT you wish to remove. + += I'm stuck, or have a suggestion. = + +Please visit our support forums if you have any questions. + +== Screenshots == + +1. Once the plugin is activated you can add/edit/delete tags from the menu in *Settings > Meta Tag Manager* + +2. You can also choose what post types to manage specific meta tags + +3. If enabled you can add meta tags to a specific post in it's own meta box + +== Changelog == += 3.3 = +* scoped selectize CSS to avoid conflicts with other plugins using selectize +* fixed low-severuty vulnerability allowing unauthorized redirects to other sites in posts created by editors or lower + += 3.2 = +* fixed security vulnerability CVE-2025-22260 reported by Rafie Muhammad via PatchStack + += 3.1 = +* fixed PHP 8.x warnings +* fixed minor PHP warning +* fixed minor security vulnerability where admin notices can be dismissed by unauthenitcated user (reported by Patchstack) +* fixed security vulnerability where arbritrary code could be exeuted by unserialize (kudos to Wordfence Security) + += 3.0.2 = +* fixed bug preventing settings from saving if schema settings are not selected +* added backward compatibility to 4.9 by allowing determine_locale() > get_locale() fallback + += 3.0.1 = +* fixed issues with schema settings saving +* fixed open graph twitter test link +* fixed some admin notice dismiss issues + += 3.0 = +* added open graph settings and support for home page +* added twitter card open graph settings and support for home page +* added schema / structured data / rich snippets front-page support +* added easy site verification settings +* added SCRIPT_DEBUG and MTM_DEBUG constant checks to decide whether to load non-minified files +* moved context checking for a tag into MTM_Tag functions, +* added Meta_Tag_Manager::is_archive() +* fixed Meta_Tag_Manager::is_archive_page() to account for static posts page +* added multiple actions and filters to MTM_Builder output +* added multiple actions and filters to MTM_Tag object +* fixed Array PHP caused by potentially non-existent contexts in a meta tag admin panel +* added extra sanitization/validation of submitted context list in a tag +* added MTM_Builder::get_contexts_list() to remove redundant code when excluding +* tweaked JS and display issues for showing context lists in header of admin meta tag card +* fixed css aesthetic issue when clicking a selectize active item turing grey +* tweaked context selectize js to be more flexible and reusable for other context fields +* moved admin-related files into admin folder +* moved settings tab sections into dedicated files +* moved handling of setting saving to Meta_Tag_Manager_Admin with a redirect instead of saving on same page load + += 2.3 = +* added multiple filters and actions for easier extension +* added use of overridable MTM_Tag::get_content() during the output() method +* fixed empty choice of post types resulting in 'Array' default selection value +* fixed display/functionality issues of MTM editor in post editors when no custom post types are chosen for MTM inclusion on settings page +* added facebook-domain-verification name type selection + += 2.2 = +* updated jQuery scripts to remove deprecated functions in jQuery 3.5 +* updated selectize.js library to 0.13.3 + += 2.1.3 = +* updated selectize library to v0.13 which fixes issues with name tags containing custom values +* fixed minor php warning + += 2.1.2 = +* fixed WordPress 5.5 conflict (props to @seserss) + += 2.1.1 = +* fixed tags not getting deleted from CPT pages +* fixed attachments not saving meta information +* added precedence for duplicate meta tags within MTM so only one is shown per page depending on specificity + += 2.1 = +* removed freemius insights +* changed default instllation to include all CPTs +* fixed PHP warning when mtm_data is missing during initial installation +* changed sanitization of content attribute when http-equiv="Link", allowing for prefetch rules + += 2.0.2 = +* fixed front page meta tags not showing if using a static front page + += 2.0.1 = +* updated freemius SDK to prevent PHP notices + += 2.0 = +* complete rewrite of plugin using up-to-date WP best practices +* improved interface for adding meta tags including support for creating tags using either the property, charset, http-equiv or itemprop attributes +* added ability to add individual meta tags to specific individual CPTs which can be chosen in settings page + += 1.2 = +* fixed stripslashes bug +* added languages + += 1.1 = +* Added danish translation +* Fixed added slashes for apostrophe values + += 1.0 = +* code styling: code now wrapped in classes +* bug fixed: magic quotes +* bug fixed: character escaping using wp_specialchars on the site and htmlspecialchars on the admin page +* separated the code into two .php files + * meta-tag-manager.php the main plugin file, always loaded, contains minimal code to reduce loading time + * meta-tag-manager-admin.php contains the admin backend parts of the plugin and is only loaded in the backend +* i18n +* l10n for: de_DE (language file by [Martin Lormes](http://ten-fingers-and-a-brain.com)) +* meta tags can be flagged to appear on the homepage only +* fixed bug which threw a Notice error when no meta tags were defined +* fixed the bug where the rss feeds kept breaking + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/NewDashboard.php b/html/wp-content/plugins/post-smtp/Postman/Dashboard/NewDashboard.php new file mode 100644 index 0000000..8f9d807 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/NewDashboard.php @@ -0,0 +1,105 @@ +include(); + + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + add_filter( 'post_smtp__new_dashboard', '__return_true' ); + add_action( 'post_smtp__new_dashboard_content', array( $this, 'dashboard_content' ) ); + + if ( + is_plugin_active( 'report-and-tracking-addon-premium/post-smtp-report-and-tracking.php' ) + || + is_plugin_active( 'post-smtp-pro/post-smtp-pro.php' ) + ) { + add_filter( 'post_smtp_dashboard_opened_emails_count', array( $this, 'opened_email_count' ), 10, 2 ); + } + + } + + private function include() { + require_once POST_SMTP_PATH . '/Postman/Dashboard/includes/rest-api/v1/class-psd-rest-api.php'; + } + + public function admin_enqueue_scripts( $hook ) { + $i18n = require_once POST_SMTP_PATH . '/Postman/Dashboard/includes/i18n.php'; + if ( 'toplevel_page_postman' === $hook ) { + wp_enqueue_script( 'post-smtp-dashboard', POST_SMTP_URL . '/Postman/Dashboard/assets/js/app.js', array( 'wp-i18n' ), POST_SMTP_VER, true ); + wp_localize_script( + 'post-smtp-dashboard', + 'postSmtpNewDashboard', + array( + 'plugin_dir_url' => plugin_dir_url( __FILE__ ), + 'json_url' => rest_url( 'psd/v1' ), + 'nonce' => wp_create_nonce( 'wp_rest' ), + 'admin_url' => admin_url( 'admin.php' ), + 'page_hook' => $hook, + 'is_bfcm' => postman_is_bfcm(), + 'i18n' => $i18n, + ) + ); + + wp_enqueue_style( 'post-smtp-dashboard', POST_SMTP_URL . '/Postman/Dashboard/assets/css/app.css', array(), POST_SMTP_VER, 'all' ); + wp_enqueue_style( 'post-smtp-dashboard-responsive', POST_SMTP_URL . '/Postman/Dashboard/assets/css/responsive-style.css', array(), POST_SMTP_VER, 'all' ); + } + } + + public function dashboard_content() { + $transport = PostmanTransportRegistry::getInstance()->getActiveTransport(); + $postman_options = get_option( 'postman_options', array() ); + $app_connected = get_option( 'post_smtp_mobile_app_connection' ); + $main_wp_configured = get_option( 'post_smtp_use_from_main_site' ); + $configured = $transport->isConfiguredAndReady() ? 'true' : 'false'; + $app_connected = empty( $app_connected ) ? 'false' : 'true'; + $main_wp_configured = empty( $main_wp_configured ) ? 'false' : 'true'; + $has_post_smtp_pro = apply_filters( 'active_plugins', get_option( 'active_plugins' ) ); + $has_post_smtp_pro = in_array( 'post-smtp-pro/post-smtp-pro.php', $has_post_smtp_pro, true ) + ? 'true' : 'false'; + $log_only_mode = is_array( $postman_options ) && isset( $postman_options['run_mode'] ) && 'log_only' === $postman_options['run_mode'] + ? 'true' : 'false' ; + + // Check if user has Professional or Basic plan + $is_professional_or_basic = 'false'; + if ( function_exists( 'pspro_fs' ) ) { + if ( pspro_fs()->is_plan( 'professional', true ) || pspro_fs()->is_plan( 'basic', true ) ) { + $is_professional_or_basic = 'true'; + } + } + + $ad_position = get_option('postman_dashboard_ad', 'maximize' ); + echo '
        + +
        '; + } + + public function opened_email_count( $count, $args ) { + $current_time = $args['current_time']; + $filter = $args['filter']; + + global $wpdb; + $sql = 'SELECT COUNT( * ) FROM %i WHERE event_type = "open-email" AND time <= %d AND time >= %d'; + $sql = $wpdb->prepare( $sql, $wpdb->prefix . 'post_smtp_tracking', $current_time, $filter ); + + return $wpdb->get_var( $sql ); + } + } + + new Post_SMTP_New_Dashboard(); +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/04d7d2697b6ad1074fcc.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/04d7d2697b6ad1074fcc.png new file mode 100644 index 0000000..a495968 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/04d7d2697b6ad1074fcc.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0762235fe75fa43063e7.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0762235fe75fa43063e7.png new file mode 100644 index 0000000..e0740ea Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0762235fe75fa43063e7.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/080727baa513e48c626e.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/080727baa513e48c626e.png new file mode 100644 index 0000000..380cf90 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/080727baa513e48c626e.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0a5db2fa24bc10426198.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0a5db2fa24bc10426198.svg new file mode 100644 index 0000000..f872d07 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0a5db2fa24bc10426198.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0a9f9bc45b15ab068aea.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0a9f9bc45b15ab068aea.svg new file mode 100644 index 0000000..d51a64c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/0a9f9bc45b15ab068aea.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1c7dc8d09d20ecab18fb.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1c7dc8d09d20ecab18fb.png new file mode 100644 index 0000000..ef57c84 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1c7dc8d09d20ecab18fb.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1d1ed72328324fa15873.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1d1ed72328324fa15873.png new file mode 100644 index 0000000..dce5a14 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1d1ed72328324fa15873.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1f30527ba4ffa819f296.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1f30527ba4ffa819f296.png new file mode 100644 index 0000000..d53c0d0 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/1f30527ba4ffa819f296.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/217775238ea2f2b33ca7.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/217775238ea2f2b33ca7.svg new file mode 100644 index 0000000..d837b7b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/217775238ea2f2b33ca7.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/258d1cba1f474caf0c4b.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/258d1cba1f474caf0c4b.svg new file mode 100644 index 0000000..d51a64c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/258d1cba1f474caf0c4b.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/27b2ae161d3d48de6aa4.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/27b2ae161d3d48de6aa4.png new file mode 100644 index 0000000..6aed9a8 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/27b2ae161d3d48de6aa4.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/2b70fc947e7d243045cc.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/2b70fc947e7d243045cc.svg new file mode 100644 index 0000000..f1e9279 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/2b70fc947e7d243045cc.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/2eb9c91de5efa416e660.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/2eb9c91de5efa416e660.svg new file mode 100644 index 0000000..30194ae --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/2eb9c91de5efa416e660.svg @@ -0,0 +1,3 @@ + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/33faa49fa2c81c425660.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/33faa49fa2c81c425660.png new file mode 100644 index 0000000..ce81e1a Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/33faa49fa2c81c425660.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/349dcbb416433fe72de2.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/349dcbb416433fe72de2.svg new file mode 100644 index 0000000..623c941 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/349dcbb416433fe72de2.svg @@ -0,0 +1,3 @@ + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/3fbf6e3924d7ed6d39ea.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/3fbf6e3924d7ed6d39ea.svg new file mode 100644 index 0000000..30194ae --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/3fbf6e3924d7ed6d39ea.svg @@ -0,0 +1,3 @@ + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5228f6e3f64c7ce0d516.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5228f6e3f64c7ce0d516.png new file mode 100644 index 0000000..b09dd18 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5228f6e3f64c7ce0d516.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/57f4451f3be03da17463.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/57f4451f3be03da17463.svg new file mode 100644 index 0000000..60ac8d0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/57f4451f3be03da17463.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5b3b23f40a94debde9f1.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5b3b23f40a94debde9f1.svg new file mode 100644 index 0000000..2b5ed8a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5b3b23f40a94debde9f1.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5b76dc43e6c63f11fb6d.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5b76dc43e6c63f11fb6d.svg new file mode 100644 index 0000000..171d56d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/5b76dc43e6c63f11fb6d.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/86fe1bec08f081521e92.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/86fe1bec08f081521e92.svg new file mode 100644 index 0000000..623c941 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/86fe1bec08f081521e92.svg @@ -0,0 +1,3 @@ + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/899ac40ae3c4456657ba.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/899ac40ae3c4456657ba.svg new file mode 100644 index 0000000..f1e9279 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/899ac40ae3c4456657ba.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/9fd2c918204f11be1da3.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/9fd2c918204f11be1da3.svg new file mode 100644 index 0000000..e76257b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/9fd2c918204f11be1da3.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/9fdeee5472f16554c9e9.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/9fdeee5472f16554c9e9.svg new file mode 100644 index 0000000..2b5ed8a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/9fdeee5472f16554c9e9.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/ab4683e6647723934b06.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/ab4683e6647723934b06.svg new file mode 100644 index 0000000..a77a19d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/ab4683e6647723934b06.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/acc721b33f3d1b7d3795.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/acc721b33f3d1b7d3795.png new file mode 100644 index 0000000..e3649a2 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/acc721b33f3d1b7d3795.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/b5d4a4bc5f5d5c2cc5ec.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/b5d4a4bc5f5d5c2cc5ec.png new file mode 100644 index 0000000..7d8e6f4 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/b5d4a4bc5f5d5c2cc5ec.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/b8b619f58474a8697fb4.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/b8b619f58474a8697fb4.svg new file mode 100644 index 0000000..57fe48b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/b8b619f58474a8697fb4.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/bd29e69106d31e4a6f1f.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/bd29e69106d31e4a6f1f.png new file mode 100644 index 0000000..b1a5eb8 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/bd29e69106d31e4a6f1f.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/c34cd1b2ca6f1ec46977.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/c34cd1b2ca6f1ec46977.svg new file mode 100644 index 0000000..60ac8d0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/c34cd1b2ca6f1ec46977.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/c9bdfeedfc807a5015cc.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/c9bdfeedfc807a5015cc.svg new file mode 100644 index 0000000..171d56d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/c9bdfeedfc807a5015cc.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/app.css b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/app.css new file mode 100644 index 0000000..de7d37a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/app.css @@ -0,0 +1,1360 @@ +@import url(https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap); + +.post-smtp__wrapper[data-v-3112b8ca] { + background: #F9FBFF; +} +.mr-25[data-v-3112b8ca] { + margin-right: 25px; +} +.container[data-v-3112b8ca] { + padding: 0 51px; +} +.mt-32[data-v-3112b8ca] { + margin-top: 32px; +} +.app-wrapper[data-v-3112b8ca] { + width: calc( 100% - 276px - 25px ); +} +.app-sidebar[data-v-3112b8ca] { + width: 276px; +} +.float-left[data-v-3112b8ca] { + float: left; +} +.clearfix[data-v-3112b8ca]::after { + clear: both; + content: ""; + display: table; +} + + +.header[data-v-65055dc1] { + height: 84px; + flex-shrink: 0; + background: #ffffff; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 40px; +} + + +.settings__button[data-v-84d0a47e] { + background: none; + border: none; + cursor: pointer; + + padding-right: 16px; +} +.settings__button[data-v-84d0a47e]:last-child { + padding-right: 0; +} + + +.post-smtp-settings-menu-wrapper[data-v-a06ecf4c] { + width: 190px; + height: 312px; + + + border-radius: 4px; + background: #FFF; + box-shadow: 0px 0px 20px 0px rgba(35, 31, 32, 0.10); + + position: absolute; + top: 60px; + right: 41px; +} +.post-smtp-dropdown-menu[data-v-a06ecf4c] { + width: 100%; + height: 52px; +} +.post-smtp-button[data-v-a06ecf4c]:hover { + background: #375CAF; + color: #fff; +} +.post-smtp-button:hover img[data-v-a06ecf4c] { + filter: invert(100%); +} +.post-smtp-button img[fallback="true"][data-v-a06ecf4c] { + filter: invert(100%); +} +.post-smtp-button:hover img[fallback="true"][data-v-a06ecf4c] { + filter: invert(0); +} +.post-smtp-button[data-v-a06ecf4c] { + display: block; + padding: 0 20px; + line-height: 52px; + + color: #231F20; + font-family: Poppins; + font-size: 14px; + font-style: normal; + font-weight: 400; + text-decoration: none; +} + + +.post-smtp-notification-bar-wrapper[data-v-1d82fd54] * { + padding: 0; + margin: 0; +} +.post-smtp-notification-bar-wrapper[data-v-1d82fd54] { + width: 380px; + max-height: 320px; + + box-shadow: 0px 0px 20px 0px rgba(35, 31, 32, 0.10); + position: absolute; + top: 60px; + right: 98px; + + background: #ffffff; + overflow-y: auto; + z-index: 1; +} +.post-smtp-notification-wrapper[data-v-1d82fd54] { + width: calc( 100% - 4px ); + + border-radius: 0 4px 0 0; + background: #FFF8F8; + border-left: 4px solid #E57373; + cursor: pointer; + + position: relative; +} +[post-smtp-opened="false"][data-v-1d82fd54] { + border-left: none; + cursor: default; +} +.post-smtp-notification-content-wrapper[data-v-1d82fd54] { + padding: 16px 20px; + border-bottom: 1px solid #E5E9F1; +} +.post-smtp-notification-content-wrapper[data-v-1d82fd54]::after { + content: ''; + display: table; + clear: both; +} +.post-smtp-notification-title[data-v-1d82fd54] { + color: #8B8F9A; + font-family: Poppins; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 20px; /* 142.857% */ +} +[post-smtp-opened="true"] .post-smtp-notification-title[data-v-1d82fd54] { + color: #B25858; +} +.post-smtp-notification-content[data-v-1d82fd54] { + color: #8B8F9A; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 130%; /* 15.6px */ + + margin-top: 4px; +} +[post-smtp-opened="true"] .post-smtp-notification-content[data-v-1d82fd54] { + color: #231F20; +} +.mt-10[data-v-1d82fd54] { + margin-top: 10px; +} +.notification-timeline[data-v-1d82fd54] { + color: #8B8F9A; + text-align: right; + font-family: Poppins; + font-size: 11px; + font-style: normal; + font-weight: 400; + line-height: 20px; /* 181.818% */ +} +.left-side-content[data-v-1d82fd54] { + width: 70%; + float: left; +} +.full-width-content[data-v-1d82fd54] { + display: block; +} +.clearfix[data-v-1d82fd54] { + clear: both; + display: table; +} +.full-width-content[data-v-1d82fd54]::after { + content: ''; + display: table; + clear: both; +} +.right-side-content[data-v-1d82fd54] { + width: 30%; + float: right; +} +.right-side-content[data-v-1d82fd54]::after { + content: ''; + display: table; + clear: both; +} +.notification-bin[data-v-1d82fd54] { + display: block; + width: 16px; + height: 16px; +} + + +.customer-support[data-v-7b742791] { + padding: 0 !important; + background: linear-gradient(180deg, #40518E 0%, #231F20 100%); + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + height: 268px; +} +.customer-support-content[data-v-7b742791] { + width: 213px; +} +.customer-support-content p[data-v-7b742791] { + font-family: Poppins; + font-size: 14px; + font-weight: 500; + line-height: 20px; + text-align: center; + color: #B8BDCA; +} +.troubleshooting[data-v-7b742791] { + padding: 0 !important; +} +.mb-24[data-v-7b742791] { + margin-bottom: 24px; +} +.troubleshooting-header[data-v-7b742791] { + border-radius: 4px 4px 0 0; + background: #EFF4FD; + padding: 16px 24px; + + font-family: Poppins; + font-size: 16px; + font-weight: 600; + line-height: 20px; + color: #231F20; +} +.troubleshooting-content[data-v-7b742791] { + padding: 24px; +} +.troubleshoot.email[data-v-7b742791] { + list-style: url(../57f4451f3be03da17463.svg) inside; +} +.troubleshoot.import-export[data-v-7b742791] { + list-style: url(../d0a8e6270627cef66c74.svg) inside; +} +.troubleshoot.connectivity[data-v-7b742791] { + list-style: url(../5b76dc43e6c63f11fb6d.svg) inside; +} +.troubleshoot.diagnostic[data-v-7b742791] { + list-style: url(../258d1cba1f474caf0c4b.svg) inside; +} +.troubleshoot.reset[data-v-7b742791] { + list-style: url(../9fdeee5472f16554c9e9.svg) inside; +} +.troubleshoot a[data-v-7b742791] { + font-family: Poppins; + font-size: 14px; + font-weight: 400; + line-height: 20px; + color: #8B8F9A; + text-decoration: underline; +} + + +.widget-wrapper[data-v-61b1c642] { + border: 1px solid #DCDFE5; + margin-bottom: 24px; + padding: 20px 0 0 24px; + border-radius: 4px; +} +.widget-wrapper[data-v-61b1c642]:last-child { + margin-bottom: 0; +} + + +.mobile-wrapper[data-v-2975379f] { + background: linear-gradient(180deg, #FFFFFF 50%, #DCE7FF 100%); +} +.mobile-wrapper[data-v-2975379f] * { + padding: 0; + margin: 0; +} +.mobile-header[data-v-2975379f] { + font-family: Montserrat; + font-size: 14px; + font-weight: 500; + line-height: 17.5px; + text-align: left; + color: #375CAF; +} +.mobile-header strong[data-v-2975379f] { + font-family: Montserrat; + font-size: 14px; + font-weight: 700; + line-height: 17.5px; + text-align: left; + color: #375CAF; +} +.post-smtp-main-wp-wrapper .main-wp-header h3[data-v-2975379f] { + color: #231F20; + font-family: Montserrat; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 130%; /* 18.2px */ +} +.post-smtp-main-wp-wrapper .main-wp-header h3 span[data-v-2975379f] { + background: linear-gradient(269deg, #3662C7 18.26%, #32B495 47.83%, #B4D859 80.52%); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-family: Montserrat; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 130%; +} +.mobile-unstyles-list li[data-v-2975379f] { + font-family: Montserrat; + font-size: 11px; + font-weight: 500; + line-height: 13.75px; + text-align: left; + color: #646464; + margin-top: 10px; + list-style: url(../2eb9c91de5efa416e660.svg) inside; +} +.img-wrapper[data-v-2975379f] { + margin-top: 7px; +} +.img-wrapper[data-v-2975379f]::after { + content: ""; + display: table; + clear: both; +} +.qrcode-img[data-v-2975379f] { + float: left; + margin-top: 47px; +} +.qrcode-mobile-app[data-v-2975379f] { + float: left; +} +.post-smtp-main-wp-wrapper[data-v-2975379f] { + border-radius: 4px; + border: 1px solid #DCDFE5; + background: url( ../b5d4a4bc5f5d5c2cc5ec.png ), linear-gradient(180deg, #FFF 0%, #EDF2FE 100%); + padding: 24px 24px; + background-position: right bottom; + background-repeat: no-repeat; +} +.main-wp-unstyled-list[data-v-2975379f] { + margin-bottom: 86px; +} +.main-wp-unstyled-list li[data-v-2975379f] { + color: #646464; + font-family: Montserrat; + font-size: 11px; + font-style: normal; + font-weight: 500; + line-height: 13.75px; /* 13.75px */ + + list-style: url( ../9fd2c918204f11be1da3.svg ) inside; +} +.main-wp-footer a[data-v-2975379f] { + display: inline-flex; + padding: 10px 20px; + justify-content: center; + align-items: center; + gap: 4px; + + color: #FFF; + font-family: Poppins; + font-size: 14px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 142.857% */ + + border-radius: 50px; + background: linear-gradient(312deg, #3662C7 21.21%, #32B495 64.57%, #B4D859 112.5%); + text-decoration: none; +} +.post-smtp-spam-score-wrapper[data-v-2975379f] { + border-radius: 4px; + border: 1px solid #DCDFE5; + background: url( ../27b2ae161d3d48de6aa4.png ), linear-gradient(180deg, #FFF 0%, #EDF2FE 100%); + background-repeat: no-repeat; + background-position: top right; + padding: 20px 25px; +} +.post-smtp-spam-score-header h2[data-v-2975379f] { + color: #231F20; + font-family: Montserrat; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 20.8px; /* 20.8px */ +} +.post-smtp-spam-score-header h2 span[data-v-2975379f] { + font-weight: 700; +} +.post-smtp-spam-score-footer a[data-v-2975379f] { + padding: 10px 20px; + + color: #FFF; + font-family: Poppins; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 20px; /* 142.857% */ + + display: inline-flex; + justify-content: center; + align-items: center; + gap: 4px; + + border-radius: 4px; + background: #375CAF; + + text-decoration: none; +} +.post-smtp-spam-score-list-unstyled[data-v-2975379f] { + margin-bottom: 20px; +} +.post-smtp-spam-score-list-unstyled li[data-v-2975379f] { + color: #646464; + font-family: Montserrat; + font-size: 11px; + font-style: normal; + font-weight: 500; + line-height: 13.75px; + + list-style: url(../ff6653d27332dc8ab22a.svg) inside; +} + + +.btn[data-v-e27b9696] { + cursor: pointer; + display: block; + padding: 12px 32px 12px 32px; + border-radius: 50px; + background: #FFFFFF1A; + + text-decoration: none; +} +.btn-secondary[data-v-e27b9696] { + font-family: Poppins; + font-size: 14px; + font-weight: 500; + line-height: 20px; + text-align: left; + color: #FFFFFF; +} +.btn-get-pro[data-v-e27b9696] { + background: linear-gradient(270deg, #F9AA39 0%, #FFDAA5 100%); + font-family: Poppins; + font-size: 14px; + font-weight: 600; + line-height: 20px; + text-align: left; + color: #231F20; + padding: 12px 32px !important; + display: block; +} + + +.mb-24[data-v-b8fab578] { + margin-bottom: 24px; +} +.post-smtp-selector-wrapper[data-v-b8fab578] { + position: relative; +} +.post-smtp-selector-wrapper a.re-launch-wizard[data-v-b8fab578] { + float: right; + padding: 8px 16px; + background: #f3f7ff; + border: 1px solid #e2ebff; + color: #375CAF; + font-family: Poppins; + font-size: 12px; + font-weight: 600; + line-height: 18px; + text-align: left; + text-decoration: none; +} +.post-smtp-selector-wrapper[data-v-b8fab578]::after { + content: ''; + clear: both; + display: table; +} + + +.wrapper[data-v-0ba96be9] { + width: 177px; + height: 32px; + top: 146px; + left: 213px; + border-radius: 16px; + background: #FFFFFF; + border: 1px solid #DCDFE5 +} +.days-selector[data-v-0ba96be9] { + margin: 4px 0 0 2px; + + cursor: pointer; + + width: 56px; + height: 24px; + display: inline-block; + + font-family: Poppins; + font-size: 12px; + font-weight: 500; + line-height: 12px; + text-align: center; + + color: #44566C; + + border: none; + outline: none; + background: none; +} +.days-selector.active[data-v-0ba96be9] { + border-radius: 12px; + background: #F3F7FF; + color: #375CAF; +} +.disabled[data-v-0ba96be9] { + pointer-events: none; +} +.disabled .days-selector[data-v-0ba96be9] { + cursor: not-allowed; +} +.disabled .days-selector.active[data-v-0ba96be9] { + background: none; + cursor: not-allowed; + color: #44566C; +} + + +.card-container[data-v-2dc01e40] * { + padding: 0; + margin: 0; +} +.card-container[data-v-2dc01e40]::after { + content: ""; + display: table; + clear: both; +} +.post-smtp-content-lighter[data-v-2dc01e40] { + color: #231F20; + font-family: Poppins; + font-size: 10px; + font-style: normal; + font-weight: 500; + line-height: 13px; +} +.pro-content-header[data-v-2dc01e40] { + color: #5A3F17; + text-align: center; + font-family: Poppins; + font-size: 14px; + font-style: normal; + font-weight: 600; + line-height: 14px; /* 100% */ +} +.pro-content[data-v-2dc01e40] { + color: #5A3F17; + text-align: center; + font-family: Poppins; + font-size: 11px; + font-style: normal; + font-weight: 500; + line-height: 13px; /* 118.182% */ + text-decoration-line: underline; +} +.post-smtp-card-box[is-pro="true"] .post-smtp-content-lighter[data-v-2dc01e40] { + color: #fff; +} + + +.post-smtp-card[data-v-3753d82c] { + width: calc( 25% - 16px + 2px ); + height: 140px; + border-radius: 4px; + float: left; + margin-right: 16px; +} +.post-smtp-card[data-v-3753d82c]:last-child { + margin-right: 0; +} +.post-smtp-card-all[data-v-3753d82c] { + background: #EDF4FF; + border: 1px solid #D3DDEB; +} +.post-smtp-card-success[data-v-3753d82c] { + background: #EDFFEF; + border: 1px solid #D3EBD6; +} +.post-smtp-card-failed[data-v-3753d82c] { + background: #FFEDED; + border: 1px solid #EBD3D3; +} +.post-smtp-card-opened--pro[data-v-3753d82c] { + background: url( ../2b70fc947e7d243045cc.svg ), radial-gradient(95.39% 99.9% at 49.79% 0%, #FFD291 0%, #F9AA39 100%); + border: 1px solid #EBE1D3; + background-repeat: no-repeat; + background-position: 275px 10px, center; +} +.post-smtp-card-content-wrapper[data-v-3753d82c] { + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + + width: 100%; + height: 100%; +} +.post-smtp-image-container[data-v-3753d82c] { + margin-right: 15px; + + width: 42px; + height: 42px; + + display: flex; + justify-content: center; + align-items: center; + + border-radius: 50%; +} +.post-smtp-card-all .post-smtp-image-container[data-v-3753d82c] { + background: url( ../5228f6e3f64c7ce0d516.png ); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} +.post-smtp-card-success .post-smtp-image-container[data-v-3753d82c] { + background: url( ../33faa49fa2c81c425660.png ); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} +.post-smtp-card-failed .post-smtp-image-container[data-v-3753d82c] { + background: url( ../080727baa513e48c626e.png ); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} +.post-smtp-card-opened--pro .post-smtp-image-container[data-v-3753d82c] { + background: url( ../1f30527ba4ffa819f296.png ); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} +.post-smtp-card-pro.post-smtp-card-all .post-smtp-image-container[data-v-3753d82c] { + background: url( ../acc721b33f3d1b7d3795.png ); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} +.post-smtp-card-pro.post-smtp-card-success .post-smtp-image-container[data-v-3753d82c] { + background: url( ../0762235fe75fa43063e7.png ); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} +.post-smtp-card-pro.post-smtp-card-failed .post-smtp-image-container[data-v-3753d82c] { + background: url( ../1c7dc8d09d20ecab18fb.png ); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} +.post-smtp-count[data-v-3753d82c] { + color: #231F20; + font-family: Poppins; + font-size: 20px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 100% */ +} +.post-smtp-content[data-v-3753d82c] { + color: #231F20; + font-family: Poppins; + font-size: 11px; + font-style: normal; + font-weight: 500; + line-height: 13px; /* 118.182% */ +} +.post-smtp-card-pro .post-smtp-count[data-v-3753d82c], +.post-smtp-card-pro .post-smtp-content[data-v-3753d82c] { + color: #fff; +} +.post-smtp-card-pro.post-smtp-card-all[data-v-3753d82c] { + background: #6291D9; +} +.post-smtp-card-pro.post-smtp-card-success[data-v-3753d82c] { + background: #74B27B; +} +.post-smtp-card-pro.post-smtp-card-failed[data-v-3753d82c] { + background: #E57373; +} +.post-smtp-card-pro.post-smtp-card-opened--pro[data-v-3753d82c] { + background: radial-gradient(95.39% 99.9% at 49.79% 0%, #FFD291 0%, #F9AA39 100%); +} + + +.post-smtp-button[data-v-b0a24b2e] { + display: inline-block; + padding: 8px 16px !important; + justify-content: center; + align-items: center; + gap: 4px; + + border-radius: 4px; + background: linear-gradient(95deg, #375CAF 18.84%, #3161CD 84.93%); + + color: #fff; + + text-decoration: none; + + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 600; + line-height: 18px; /* 150% */ +} + + +.post-smtp-notice-wrapper[data-v-d473dc1c] * { + padding: 0; + margin: 0; +} +.post-smtp-notice[data-v-d473dc1c] { + width: calc( 100% - 33px ); + height: 44px; + padding: 5px 16px 5px 16px; + display: inline-flex; + justify-content: space-between; + align-items: center; +} +.post-smtp-notice-success[data-v-d473dc1c] { + border-radius: 4px; + border: 1px solid #DDE6E0; + background: #F4F9F6; +} +.post-smtp-notice-warning[data-v-d473dc1c] { + border-radius: 4px; + border: 1px solid #E6DDDD; + background: #F9F4F4; +} +.post-smtp-notice-content[data-v-d473dc1c] { + color: #263E30; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 18px; +} +.post-smtp-notice-content strong[data-v-d473dc1c] { + font-weight: 600; + + padding-right: 4px; +} +.post-smtp-notice-icon[data-v-d473dc1c] { + margin-right: 8px; +} + + +.post-smtp-logs-wrapper[data-v-82c3bb58] * { + padding: 0; + margin: 0; +} +.post-smtp-logs-wrapper[data-v-82c3bb58] { + width: 100%; +} +.post-smtp-logs-header[data-v-82c3bb58] { + width: calc( 100% - 2px - 48px ); + height: calc( 52px - 1px - 32px ); + + padding: 16px 24px; + + border-radius: 4px 4px 0px 0px; + border-top: 1px solid #DCDFE5; + border-right: 1px solid #DCDFE5; + border-left: 1px solid #DCDFE5; + background: #EFF4FD; +} +.post-smtp-logs-body[data-v-82c3bb58] { + width: calc( 100% - 2px ); + + border-radius: 0px 0px 4px 4px; + border-right: 1px solid #DCDFE5; + border-bottom: 1px solid #DCDFE5; + border-left: 1px solid #DCDFE5; + background: #FFF; +} +.post-smtp-logs-body th[data-v-82c3bb58], +.post-smtp-logs-body td[data-v-82c3bb58] { + height: 48px; + padding: 0 16px; +} +.post-smtp-logs-header[data-v-82c3bb58]::after { + content: ''; + display: block; + clear: both; +} +.float-left[data-v-82c3bb58] { + float: left; +} +.float-right[data-v-82c3bb58] { + float: right; +} +.post-smtp-logs-header h2[data-v-82c3bb58] { + color: #231F20; + text-align: center; + font-family: Poppins; + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 125% */ +} +.post-smtp-logs-header a[data-v-82c3bb58] { + color: #375CAF; + text-align: center; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 500; + line-height: 20px; /* 166.667% */ + text-decoration-line: underline; +} +.post-smtp-logs-body table[data-v-82c3bb58] { + width: 100%; +} +.post-smtp-logs-body table thead th[data-v-82c3bb58] { + color: #231F20; + text-align: center; + font-family: Poppins; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 14px; /* 100% */ +} +.post-smtp-logs-body table tbody td[data-v-82c3bb58] { + color: #646464; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 18px; /* 150% */ + + border-bottom: 1px solid #DCDFE5; +} +.post-smtp-logs-body table tbody tr:last-child td[data-v-82c3bb58] { + border-bottom: none; +} +.post-smtp-logs-body table tbody td[data-v-82c3bb58] { + text-align: left; +} +.post-smtp-status[data-v-82c3bb58] { + display: inline-flex; + padding: 4px; + flex-direction: column; + align-items: center; + text-align: center; + font-family: Poppins; + font-size: 10px; + font-style: normal; + font-weight: 500; + line-height: 12px; /* 120% */ + border-radius: 14px; + width: 62px; +} +.post-smtp-status.post-smtp-success[data-v-82c3bb58] { + color: #74B27B; + background: #EDFFEF; +} +.post-smtp-status.post-smtp-failed[data-v-82c3bb58] { + color: #E57373; + background: #FFEDED; +} +.post-smtp-status-wrapper[data-v-82c3bb58] { + width: 100%; + position: relative; +} +.post-smtp-logs-empty[data-v-82c3bb58] { + width: 100%; + height: 300px; + + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} +.post-smtp-logs-empty .post-smtp-logs-head[data-v-82c3bb58] {} +.post-smtp-logs-empty .post-smtp-logs-content[data-v-82c3bb58] { + text-align: center; + + margin-bottom: 16px; + margin-top: 24px; +} +.post-smtp-logs-empty .post-smtp-logs-content h3[data-v-82c3bb58] { + color: #646464; + text-align: center; + font-family: Poppins; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 14px; /* 100% */ + margin-bottom: 8px; +} +.post-smtp-logs-empty .post-smtp-logs-content p[data-v-82c3bb58] { + color: #646464; + text-align: center; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 18px; /* 150% */ +} +.post-smtp-logs-empty .post-smtp-logs-footer a[data-v-82c3bb58] { + display: block; + color: #FFF; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 600; + line-height: 18px; /* 150% */ + + padding: 8px 16px; + justify-content: center; + align-items: center; + gap: 4px; + + border-radius: 4px; + background: #375CAF; + + text-decoration: none; +} + + +.post-smtp-log-action-menu-wrapper[data-v-1121e3a1] { + display: inline-flex; + padding: 16px 20px; + flex-direction: column; + align-items: flex-start; + gap: 12px; + + border-radius: 4px; + background: #FFF; + box-shadow: 0px 0px 20px 0px rgba(35, 31, 32, 0.10); + + position: absolute; + + z-index: 925; + + top: -13px; + right: 32px; + + width: 100px; +} +.post-smtp-log-action-menu-wrapper a[data-v-1121e3a1] { + color: #231F20; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 16px; /* 133.333% */ + + text-decoration: none; +} +.post-smtp-link i[data-v-1121e3a1] { + margin-right: 6px; +} +.post-smtp-link[data-v-1121e3a1] { + margin-bottom: 12px; +} +.post-smtp-link[data-v-1121e3a1]:last-child { + margin-bottom: 0; +} +.post-smtp-error-details[data-v-1121e3a1] { + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur( 1px ); + z-index: 99999; +} +.post-smtp-details-wrapper[data-v-1121e3a1] { + width: 700px; + height: 500px; + padding: 20px; + box-shadow: 0 2px 16px rgb(0 0 0 / 50% ); + background: #fff; + overflow: auto; + position: relative; +} +.post-smtp-close-button[data-v-1121e3a1] { + position: absolute; + top: 10px; + right: 10px; + font-size: 24px; + color: #231F20; + text-decoration: none; +} +.resend-email-wrapper[data-v-1121e3a1] { + width: 100%; + height: 500px; + + display: flex; + justify-content: center; + align-items: center; +} +.form-group[data-v-1121e3a1] { + width: 100%; +} +.form-group label[data-v-1121e3a1] { + display: block; + margin-bottom: 6px; +} +.form-group textarea[data-v-1121e3a1] { + width: 100%; + height: 100px; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; +} +.form-control[data-v-1121e3a1] { + width: 100%; + height: 40px; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; +} +.post-smtp-button[data-v-1121e3a1] { + padding: 10px 20px; + border: none; + border-radius: 4px; + cursor: pointer; +} +.post-smtp-button.primary[data-v-1121e3a1] { + background: #0073aa; + color: #fff; +} +.email-menu-wrapper[data-v-1121e3a1] { + position: absolute; + right: 27px; + top: 0px; + cursor: pointer; +} +.email-menu-action[data-v-1121e3a1]::after { + + + content: ''; + display: block; + width: 4px; + height: 4px; + border-radius: 50%; + background: #B0B0B0; + margin: 4px 0; +} + + + +.pro-features[data-v-670574d9] * { + padding: 0; + margin: 0; +} +.pro-features[data-v-670574d9] { + position: relative; + height: 397px; + background: url( ../1d1ed72328324fa15873.png ), url( ../bd29e69106d31e4a6f1f.png ), url( ../db67b70d37a34f75ab17.png ), linear-gradient(180deg, #375CAF 0%, #2C4A8C 100%); + background-repeat: no-repeat; + background-position: left bottom, right bottom, 0 0, 0 0; + background-size: auto, auto, cover, cover; + border-radius: 4px; +} +.container[data-v-670574d9] { + display: flex; + justify-content: center; + align-items: center; + padding: 38px 62px; + flex-direction: column; +} +.header h2[data-v-670574d9] { + background: -webkit-linear-gradient(270deg, #F9AA39 0%, #FFDAA5 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-family: Poppins; + font-size: 24px; + font-weight: 600; + line-height: 25.83px; + text-align: center; +} +.d-inline-block[data-v-670574d9] { + display: inline-block; +} +.header p[data-v-670574d9] { + font-family: Poppins; + font-size: 16px; + font-weight: 400; + line-height: 25.83px; + text-align: center; + + + background: -webkit-linear-gradient(270deg, #F9AA39 0%, #FFDAA5 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + + margin-left: 83px; +} +.header[data-v-670574d9] { + margin-bottom: 20px; +} +.footer[data-v-670574d9] { + margin-top: 20px; +} +.create-container[data-v-670574d9] { + width: 56px; + height: 56px; + background: url( ../86fe1bec08f081521e92.svg ); + background-repeat: no-repeat; + background-size: contain; + background-position: center; + display: flex; + justify-content: center; + align-items: center; +} +.body[data-v-670574d9] { + display: grid; + grid-template-columns: auto auto auto auto ; + width: 100%; +} +.feature-block[data-v-670574d9] { + display: flex; + flex-direction: row; + align-items: center; + margin-bottom: 20px; +} +.block-content[data-v-670574d9] { + margin-left: 20px; + + font-family: Poppins; + font-size: 12px; + font-weight: 500; + line-height: 16px; + text-align: left; + color: #E2E9FB; +} +.post-smtp-minimize-ad[data-v-670574d9] { + position: absolute; + top: 20px; + right: 24px; + + color: #BAD0FF; + font-family: Poppins; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 12px; /* 100% */ + + cursor: pointer; +} +.post-smtp-minimize-ad i[data-v-670574d9] { + margin-right: 10px; +} +.bcfm[data-v-670574d9] { + background: url( ../e2f9e8c4d311f9c91473.png ), url( ../1d1ed72328324fa15873.png ), url( ../bd29e69106d31e4a6f1f.png ), url( ../db67b70d37a34f75ab17.png ), linear-gradient(180deg, #375CAF 0%, #2C4A8C 100%); + background-repeat: no-repeat; + background-position: top right, left bottom, right bottom, 0 0, 0 0; + background-size: auto, auto, auto, cover, cover; +} + + +.documentation[data-v-7fb6e671] * { + padding: 0; + margin: 0; +} +.header[data-v-7fb6e671] { + border-radius: 4px 4px 0 0; + border-width: 1px 1px 0 1px; + border-style: solid; + border-color: #DCDFE5; + padding: 16px 24px; + background: #FFFFFF; +} +.header h3[data-v-7fb6e671] { + font-family: Poppins; + font-size: 16px; + font-weight: 600; + line-height: 20px; + text-align: left; + color: #231F20; +} +.float-left[data-v-7fb6e671] { + float: left; +} +.float-right[data-v-7fb6e671] { + float: right; +} +.header[data-v-7fb6e671]::after { + content: ''; + display: block; + clear: both; +} +.transform-image[data-v-7fb6e671] { + transform: rotate(0deg); + transition: transform 0.5s; +} +.maximize[data-v-7fb6e671] { + transform: rotate(180deg); +} +.minimize[data-v-7fb6e671] { + transform: rotate(0deg); +} +.body[data-v-7fb6e671] { + background: #EFF4FD; + border-width: 0 1px 1px 1px; + border-style: solid; + border-color: #DCDFE5; + padding: 48px 0; +} +.body[data-v-7fb6e671] { + width: calc( 100% - 2px ); + display: flex; + justify-content: center; + align-items: center; +} +.content[data-v-7fb6e671] { + display: grid; + grid-template-columns: auto auto auto; +} +.content[data-v-7fb6e671]::after { + content: ''; + display: block; + clear: both; +} + + +.documentation[data-v-7ae3eba2] { + width: 222px; + float: left; + padding: 20px; + background: #ffffff; + margin: 0 24px 24px 0; +} +.documentation h3[data-v-7ae3eba2] { + font-family: Poppins; + font-size: 14px; + font-weight: 500; + line-height: 14px; + text-align: left; + color: #231F20; +} +.doc-unstyled-list[data-v-7ae3eba2] { + margin-top: 20px; + margin-bottom: 22px; +} +.doc-unstyled-list li[data-v-7ae3eba2] { + line-height: 18px; + margin: 10px 0; +} +.doc-unstyled-list li a[data-v-7ae3eba2] { + font-family: Poppins; + font-size: 12px; + font-weight: 400; + text-align: left; + color: #375CAF; +} +.view-more-button[data-v-7ae3eba2] { + font-family: Poppins; + font-size: 12px; + font-weight: 500; + line-height: 18px; + text-align: left; + color: #375CAF; + text-decoration: none; +} +.clearfix[data-v-7ae3eba2]::after { + content: ""; + clear: both; + display: table; +} + +.animated { + animation-duration: 0.5s; +} + +.slideIn { + animation-name: slideIn; +} + +.slideOut { + animation-name: slideOut; +} + +@keyframes slideIn { + from { + opacity: 0; + transform: translateY(-50%); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes slideOut { + from { + opacity: 1; + transform: translateY(0); + } + + to { + opacity: 0; + transform: translateY(-50%); + } +} + +#wpcontent { + background: #F9FBFF; +} + +.gmail-one-click{ + width:274px +} +.gmail-wrapper{ + padding: 0px !important; + border-bottom: none !important; +} +a.gmail-click:active, a.gmail-click:visited{ + color: #fff; + text-decoration: none; +} +a.gmail-click:hover,a.gmail-click:focus{ + color: #fff; + text-decoration: none; + box-shadow: none; +} + +.office-one-click{ + width:274px +} +.office-wrapper{ + padding: 0px !important; + border-bottom: none !important; +} + +/*# sourceMappingURL=app.css.map*/ \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/app.css.map b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/app.css.map new file mode 100644 index 0000000..5052916 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/app.css.map @@ -0,0 +1 @@ +{"version":3,"file":"css/app.css","mappings":";;AAkFA;CACC,mBAAmB;AACpB;AAEA;CACC,kBAAkB;AACnB;AAEA;CACC,eAAe;AAChB;AAEA;CACC,gBAAgB;AACjB;AAEA;CACC,kCAAkC;AACnC;AAEA;CACC,YAAY;AACb;AAEA;CACC,WAAW;AACZ;AAEA;CACC,WAAW;CACX,WAAW;CACX,cAAc;AACf;;;AChEA;CACC,YAAY;CACZ,cAAc;CACd,mBAAmB;CACnB,aAAa;CACb,8BAA8B;CAC9B,mBAAmB;CACnB,eAAe;AAChB;;;ACqFA;CACC,gBAAgB;CAChB,YAAY;CACZ,eAAe;;CAEf,mBAAmB;AACpB;AAEA;CACC,gBAAgB;AACjB;;;AC3HA;CACC,YAAY;CACZ,aAAa;;;CAGb,kBAAkB;CAClB,gBAAgB;CAChB,mDAAmD;;CAEnD,kBAAkB;CAClB,SAAS;CACT,WAAW;AACZ;AAEA;CACC,WAAW;CACX,YAAY;AACb;AAEA;CACC,mBAAmB;CACnB,WAAW;AACZ;AAEA;CACC,oBAAoB;AACrB;AAEA;CACC,oBAAoB;AACrB;AAEA;CACC,iBAAiB;AAClB;AAEA;CACC,cAAc;CACd,eAAe;CACf,iBAAiB;;CAEjB,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,qBAAqB;AACtB;;;ACmDA;CACC,UAAU;CACV,SAAS;AACV;AAEA;CACC,YAAY;CACZ,iBAAiB;;CAEjB,mDAAmD;CACnD,kBAAkB;CAClB,SAAS;CACT,WAAW;;CAEX,mBAAmB;CACnB,gBAAgB;CAChB,UAAU;AACX;AAEA;CACC,yBAAyB;;CAEzB,wBAAwB;CACxB,mBAAmB;CACnB,8BAA8B;CAC9B,eAAe;;CAEf,kBAAkB;AACnB;AAEA;CACC,iBAAiB;CACjB,eAAe;AAChB;AAEA;CACC,kBAAkB;CAClB,gCAAgC;AACjC;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;AAEA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;AACjC;AAEA;CACC,cAAc;AACf;AAEA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,WAAW;;CAE9B,eAAe;AAChB;AAEA;CACC,cAAc;AACf;AAEA;CACC,gBAAgB;AACjB;AAEA;CACC,cAAc;CACd,iBAAiB;CACjB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;AACjC;AAEA;CACC,UAAU;CACV,WAAW;AACZ;AAEA;CACC,cAAc;AACf;AAEA;CACC,WAAW;CACX,cAAc;AACf;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;AAEA;CACC,UAAU;CACV,YAAY;AACb;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;AAEA;CACC,cAAc;CACd,WAAW;CACX,YAAY;AACb;;;AChFA;CACC,qBAAqB;CACrB,6DAA6D;CAC7D,aAAa;CACb,uBAAuB;CACvB,mBAAmB;CACnB,sBAAsB;CACtB,aAAa;AACd;AAEA;CACC,YAAY;AACb;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;CAClB,cAAc;AACf;AAEA;CACC,qBAAqB;AACtB;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,0BAA0B;CAC1B,mBAAmB;CACnB,kBAAkB;;CAElB,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,cAAc;AACf;AAGA;CACC,aAAa;AACd;AAEA;CACC,0DAA6C;AAC9C;AAEA;CACC,0DAAqD;AACtD;AAEA;CACC,0DAAoD;AACrD;AAEA;CACC,0DAAkD;AACnD;AAEA;CACC,0DAA6C;AAC9C;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,cAAc;CACd,0BAA0B;AAC3B;;;ACpOA;CACC,yBAAyB;CACzB,mBAAmB;CACnB,sBAAsB;CACtB,kBAAkB;AACnB;AAEA;CACC,gBAAgB;AACjB;;;ACqFA;CACC,8DAA8D;AAC/D;AAEA;CACC,UAAU;CACV,SAAS;AACV;AAEA;CACC,uBAAuB;CACvB,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,gBAAgB;CAChB,cAAc;AACf;AAEA;CACC,uBAAuB;CACvB,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,gBAAgB;CAChB,cAAc;AACf;AAEA;CACC,cAAc;CACd,uBAAuB;CACvB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,WAAW;AAC/B;AAEA;CACC,mFAAmF;CACnF,qBAAqB;CACrB,6BAA6B;CAC7B,oCAAoC;CACpC,uBAAuB;CACvB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;AAClB;AAEA;CACC,uBAAuB;CACvB,eAAe;CACf,gBAAgB;CAChB,oBAAoB;CACpB,gBAAgB;CAChB,cAAc;CACd,gBAAgB;CAChB,0DAA8C;AAC/C;AAEA;CACC,eAAe;AAChB;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;AAEA;CACC,WAAW;CACX,gBAAgB;AACjB;AAEA;CACC,WAAW;AACZ;AAEA;CACC,kBAAkB;CAClB,yBAAyB;CACzB,qGAA2F;CAC3F,kBAAkB;CAClB,iCAAiC;CACjC,4BAA4B;AAC7B;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,cAAc;CACd,uBAAuB;CACvB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,oBAAoB,EAAE,YAAY;;CAElC,4DAAgD;AACjD;AAEA;CACC,oBAAoB;CACpB,kBAAkB;CAClB,uBAAuB;CACvB,mBAAmB;CACnB,QAAQ;;CAER,WAAW;CACX,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;;CAEhC,mBAAmB;CACnB,mFAAmF;CACnF,qBAAqB;AACtB;AAEA;CACC,kBAAkB;CAClB,yBAAyB;CACzB,qGAA8F;CAC9F,4BAA4B;CAC5B,8BAA8B;CAC9B,kBAAkB;AACnB;AAEA;CACC,cAAc;CACd,uBAAuB;CACvB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,mBAAmB,EAAE,WAAW;AACjC;AAEA;CACC,gBAAgB;AACjB;AAEA;CACC,kBAAkB;;CAElB,WAAW;CACX,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;;CAEhC,oBAAoB;CACpB,uBAAuB;CACvB,mBAAmB;CACnB,QAAQ;;CAER,kBAAkB;CAClB,mBAAmB;;CAEnB,qBAAqB;AACtB;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,cAAc;CACd,uBAAuB;CACvB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,oBAAoB;;CAEpB,0DAAgD;AACjD;;;ACtPA;CACC,eAAe;CACf,cAAc;CACd,4BAA4B;CAC5B,mBAAmB;CACnB,qBAAqB;;CAErB,qBAAqB;AACtB;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,cAAc;AACf;AAEA;CACC,6DAA6D;CAC7D,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,cAAc;CACd,6BAA6B;CAC7B,cAAc;AACf;;;AC6BA;CACC,mBAAmB;AACpB;AAEA;CACC,kBAAkB;AACnB;AAEA;CACC,YAAY;CACZ,iBAAiB;CACjB,mBAAmB;CACnB,yBAAyB;CACzB,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,qBAAqB;AACtB;AAEA;CACC,WAAW;CACX,WAAW;CACX,cAAc;AACf;;;ACpEA;CACC,YAAY;CACZ,YAAY;CACZ,UAAU;CACV,WAAW;CACX,mBAAmB;CACnB,mBAAmB;CACnB;AACD;AAEA;CACC,mBAAmB;;CAEnB,eAAe;;CAEf,WAAW;CACX,YAAY;CACZ,qBAAqB;;CAErB,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;;CAElB,cAAc;;CAEd,YAAY;CACZ,aAAa;CACb,gBAAgB;AACjB;AAEA;CACC,mBAAmB;CACnB,mBAAmB;CACnB,cAAc;AACf;AAEA;CACC,oBAAoB;AACrB;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,gBAAgB;CAChB,mBAAmB;CACnB,cAAc;AACf;;;AC4JA;CACC,UAAU;CACV,SAAS;AACV;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;AAEA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;AAClB;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;AAC7B;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;CAChC,+BAA+B;AAChC;AAEA;CACC,WAAW;AACZ;;;ACxPA;CACC,+BAA+B;CAC/B,aAAa;CACb,kBAAkB;CAClB,WAAW;CACX,kBAAkB;AACnB;AAEA;CACC,eAAe;AAChB;AAEA;CACC,mBAAmB;CACnB,yBAAyB;AAC1B;AAEA;CACC,mBAAmB;CACnB,yBAAyB;AAC1B;AAEA;CACC,mBAAmB;CACnB,yBAAyB;AAC1B;AAEA;CACC,2HAAqH;CACrH,yBAAyB;CACzB,4BAA4B;CAC5B,uCAAuC;AACxC;AAEA;CACC,aAAa;CACb,uBAAuB;CACvB,mBAAmB;CACnB,mBAAmB;;CAEnB,WAAW;CACX,YAAY;AACb;AAEA;CACC,kBAAkB;;CAElB,WAAW;CACX,YAAY;;CAEZ,aAAa;CACb,uBAAuB;CACvB,mBAAmB;;CAEnB,kBAAkB;AACnB;AAEA;CACC,qDAA+C;CAC/C,4BAA4B;CAC5B,2BAA2B;CAC3B,sBAAsB;AACvB;AAEA;CACC,qDAAqD;CACrD,4BAA4B;CAC5B,2BAA2B;CAC3B,sBAAsB;AACvB;AAEA;CACC,qDAAgD;CAChD,4BAA4B;CAC5B,2BAA2B;CAC3B,sBAAsB;AACvB;AAEA;CACC,qDAAgD;CAChD,4BAA4B;CAC5B,2BAA2B;CAC3B,sBAAsB;AACvB;AAEA;CACC,qDAAuD;CACvD,4BAA4B;CAC5B,2BAA2B;CAC3B,sBAAsB;AACvB;AAEA;CACC,qDAAyD;CACzD,4BAA4B;CAC5B,2BAA2B;CAC3B,sBAAsB;AACvB;AAEA;CACC,qDAAoD;CACpD,4BAA4B;CAC5B,2BAA2B;CAC3B,sBAAsB;AACvB;AAEA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;AAC7B;AAEA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;AACjC;AAEA;;CAEC,WAAW;AACZ;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,gFAAgF;AACjF;;;AC/FA;CACC,qBAAqB;CACrB,4BAA4B;CAC5B,uBAAuB;CACvB,mBAAmB;CACnB,QAAQ;;CAER,kBAAkB;CAClB,kEAAkE;;CAElE,WAAW;;CAEX,qBAAqB;;CAErB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;AAC7B;;;AClEA;CACC,UAAU;CACV,SAAS;AACV;AAEA;CACC,0BAA0B;CAC1B,YAAY;CACZ,0BAA0B;CAC1B,oBAAoB;CACpB,8BAA8B;CAC9B,mBAAmB;AACpB;AAEA;CACC,kBAAkB;CAClB,yBAAyB;CACzB,mBAAmB;AACpB;AAEA;CACC,kBAAkB;CAClB,yBAAyB;CACzB,mBAAmB;AACpB;AAGA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB;AAClB;AAEA;CACC,gBAAgB;;CAEhB,kBAAkB;AACnB;AAEA;CACC,iBAAiB;AAClB;;;AC4DA;CACC,UAAU;CACV,SAAS;AACV;AAEA;CACC,WAAW;AACZ;AAEA;CACC,gCAAgC;CAChC,iCAAiC;;CAEjC,kBAAkB;;CAElB,8BAA8B;CAC9B,6BAA6B;CAC7B,+BAA+B;CAC/B,8BAA8B;CAC9B,mBAAmB;AACpB;AAEA;CACC,yBAAyB;;CAEzB,8BAA8B;CAC9B,+BAA+B;CAC/B,gCAAgC;CAChC,8BAA8B;CAC9B,gBAAgB;AACjB;AAEA;;CAEC,YAAY;CACZ,eAAe;AAChB;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;AAEA;CACC,WAAW;AACZ;AAEA;CACC,YAAY;AACb;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;AAC7B;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;CAChC,+BAA+B;AAChC;AAEA;CACC,WAAW;AACZ;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;AAC7B;AAEA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;;CAE5B,gCAAgC;AACjC;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,gBAAgB;AACjB;AAEA;CACC,oBAAoB;CACpB,YAAY;CACZ,sBAAsB;CACtB,mBAAmB;CACnB,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;CAC5B,mBAAmB;CACnB,WAAW;AACZ;AAEA;CACC,cAAc;CACd,mBAAmB;AACpB;AAEA;CACC,cAAc;CACd,mBAAmB;AACpB;AAEA;CACC,WAAW;CACX,kBAAkB;AACnB;AAEA;CACC,WAAW;CACX,aAAa;;CAEb,aAAa;CACb,uBAAuB;CACvB,mBAAmB;CACnB,sBAAsB;AACvB;AAEA,6DAA4C;AAE5C;CACC,kBAAkB;;CAElB,mBAAmB;CACnB,gBAAgB;AACjB;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;CAC5B,kBAAkB;AACnB;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;AAC7B;AAEA;CACC,cAAc;CACd,WAAW;CACX,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;;CAE5B,iBAAiB;CACjB,uBAAuB;CACvB,mBAAmB;CACnB,QAAQ;;CAER,kBAAkB;CAClB,mBAAmB;;CAEnB,qBAAqB;AACtB;;;ACtBA;CACC,oBAAoB;CACpB,kBAAkB;CAClB,sBAAsB;CACtB,uBAAuB;CACvB,SAAS;;CAET,kBAAkB;CAClB,gBAAgB;CAChB,mDAAmD;;CAEnD,kBAAkB;;CAElB,YAAY;;CAEZ,UAAU;CACV,WAAW;;CAEX,YAAY;AACb;AAEA;CACC,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,aAAa;;CAEhC,qBAAqB;AACtB;AAEA;CACC,iBAAiB;AAClB;AAEA;CACC,mBAAmB;AACpB;AAEA;CACC,gBAAgB;AACjB;AAEA;CACC,WAAW;CACX,YAAY;CACZ,eAAe;CACf,MAAM;CACN,OAAO;CACP,aAAa;CACb,uBAAuB;CACvB,mBAAmB;CACnB,8BAA8B;CAC9B,4BAA4B;CAC5B,cAAc;AACf;AAEA;CACC,YAAY;CACZ,aAAa;CACb,aAAa;CACb,wCAAwC;CACxC,gBAAgB;CAChB,cAAc;CACd,kBAAkB;AACnB;AAEA;CACC,kBAAkB;CAClB,SAAS;CACT,WAAW;CACX,eAAe;CACf,cAAc;CACd,qBAAqB;AACtB;AAEA;CACC,WAAW;CACX,aAAa;;CAEb,aAAa;CACb,uBAAuB;CACvB,mBAAmB;AACpB;AAEA;CACC,WAAW;AACZ;AAEA;CACC,cAAc;CACd,kBAAkB;AACnB;AAEA;CACC,WAAW;CACX,aAAa;CACb,aAAa;CACb,sBAAsB;CACtB,kBAAkB;AACnB;AAEA;CACC,WAAW;CACX,YAAY;CACZ,aAAa;CACb,sBAAsB;CACtB,kBAAkB;AACnB;AAEA;CACC,kBAAkB;CAClB,YAAY;CACZ,kBAAkB;CAClB,eAAe;AAChB;AAEA;CACC,mBAAmB;CACnB,WAAW;AACZ;AAEA;CACC,kBAAkB;CAClB,WAAW;CACX,QAAQ;CACR,eAAe;AAChB;AAEA;;;CAGC,WAAW;CACX,cAAc;CACd,UAAU;CACV,WAAW;CACX,kBAAkB;CAClB,mBAAmB;CACnB,aAAa;AACd;;;;ACnTA;CACC,UAAU;CACV,SAAS;AACV;AAEA;CACC,kBAAkB;CAClB,aAAa;CACb,8LAA6K;CAC7K,4BAA4B;CAC5B,wDAAwD;CACxD,yCAAyC;CACzC,kBAAkB;AACnB;AAEA;CACC,aAAa;CACb,uBAAuB;CACvB,mBAAmB;CACnB,kBAAkB;CAClB,sBAAsB;AACvB;AAEA;CACC,qEAAqE;CACrE,6BAA6B;CAC7B,oCAAoC;CACpC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;AACnB;AAEA;CACC,qBAAqB;AACtB;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,oBAAoB;CACpB,kBAAkB;;;CAGlB,qEAAqE;CACrE,6BAA6B;CAC7B,oCAAoC;;CAEpC,iBAAiB;AAClB;AAEA;CACC,mBAAmB;AACpB;AACA;CACC,gBAAgB;AACjB;AAEA;CACC,WAAW;CACX,YAAY;CACZ,qDAA8C;CAC9C,4BAA4B;CAC5B,wBAAwB;CACxB,2BAA2B;CAC3B,aAAa;CACb,uBAAuB;CACvB,mBAAmB;AACpB;AAEA;CACC,aAAa;CACb,2CAA2C;CAC3C,WAAW;AACZ;AAEA;CACC,aAAa;CACb,mBAAmB;CACnB,mBAAmB;CACnB,mBAAmB;AACpB;AAEA;CACC,iBAAiB;;CAEjB,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,cAAc;AACf;AAEA;CACC,kBAAkB;CAClB,SAAS;CACT,WAAW;;CAEX,cAAc;CACd,oBAAoB;CACpB,eAAe;CACf,kBAAkB;CAClB,gBAAgB;CAChB,iBAAiB,EAAE,SAAS;;CAE5B,eAAe;AAChB;AAEA;CACC,kBAAkB;AACnB;AAEA;CACC,yOAAoO;CACpO,4BAA4B;CAC5B,mEAAmE;CACnE,+CAA+C;AAChD;;;AC9NA;CACC,UAAU;CACV,SAAS;AACV;AACA;CACC,0BAA0B;CAC1B,2BAA2B;CAC3B,mBAAmB;CACnB,qBAAqB;CACrB,kBAAkB;CAClB,mBAAmB;AACpB;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,cAAc;AACf;AAEA;CACC,WAAW;AACZ;AAEA;CACC,YAAY;AACb;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;AAEA;CACC,uBAAuB;CACvB,0BAA0B;AAC3B;AAEA;CACC,yBAAyB;AAC1B;AAEA;CACC,uBAAuB;AACxB;AAEA;CACC,mBAAmB;CACnB,2BAA2B;CAC3B,mBAAmB;CACnB,qBAAqB;CACrB,eAAe;AAChB;AAEA;CACC,yBAAyB;CACzB,aAAa;CACb,uBAAuB;CACvB,mBAAmB;AACpB;AAEA;CACC,aAAa;CACb,qCAAqC;AACtC;AAEA;CACC,WAAW;CACX,cAAc;CACd,WAAW;AACZ;;;AC5EA;CACC,YAAY;CACZ,WAAW;CACX,aAAa;CACb,mBAAmB;CACnB,qBAAqB;AACtB;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,cAAc;AACf;AAEA;CACC,gBAAgB;CAChB,mBAAmB;AACpB;AAEA;CACC,iBAAiB;CACjB,cAAc;AACf;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,gBAAgB;CAChB,cAAc;AACf;AAEA;CACC,oBAAoB;CACpB,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CACjB,gBAAgB;CAChB,cAAc;CACd,qBAAqB;AACtB;AAEA;CACC,WAAW;CACX,WAAW;CACX,cAAc;AACf;;AChHA;IACI,wBAAwB;AAC5B;;AAEA;IACI,uBAAuB;AAC3B;;AAEA;IACI,wBAAwB;AAC5B;;AAEA;IACI;QACI,UAAU;QACV,2BAA2B;IAC/B;;IAEA;QACI,UAAU;QACV,wBAAwB;IAC5B;AACJ;;AAEA;IACI;QACI,UAAU;QACV,wBAAwB;IAC5B;;IAEA;QACI,UAAU;QACV,2BAA2B;IAC/B;AACJ;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI;AACJ;AACA;IACI,uBAAuB;IACvB,8BAA8B;AAClC;AACA;IACI,WAAW;IACX,qBAAqB;AACzB;AACA;IACI,WAAW;IACX,qBAAqB;IACrB,gBAAgB;AACpB;;AAEA;IACI;AACJ;AACA;IACI,uBAAuB;IACvB,8BAA8B;AAClC,C","sources":["webpack://saa-new-dashboard/./src/components/post-smtp-app-wrapper.vue","webpack://saa-new-dashboard/./src/components/post-smtp-header.vue","webpack://saa-new-dashboard/./src/components/post-smtp-settings.vue","webpack://saa-new-dashboard/./src/components/post-smtp-settings-menu.vue","webpack://saa-new-dashboard/./src/components/post-smtp-notification-bar.vue","webpack://saa-new-dashboard/./src/components/post-smtp-sidebar.vue","webpack://saa-new-dashboard/./src/components/post-smtp-widget.vue","webpack://saa-new-dashboard/./src/components/post-smtp-ads.vue","webpack://saa-new-dashboard/./src/components/post-smtp-button.vue","webpack://saa-new-dashboard/./src/components/post-smtp-dashboard.vue","webpack://saa-new-dashboard/./src/components/post-smtp-days-selector.vue","webpack://saa-new-dashboard/./src/components/post-smtp-cards-container.vue","webpack://saa-new-dashboard/./src/components/post-smtp-card.vue","webpack://saa-new-dashboard/./src/components/post-smtp-banners.vue","webpack://saa-new-dashboard/./src/components/post-smtp-notice.vue","webpack://saa-new-dashboard/./src/components/post-smtp-logs-section.vue","webpack://saa-new-dashboard/./src/components/post-smtp-log-action-menu.vue","webpack://saa-new-dashboard/./src/components/post-smtp-pro-features.vue","webpack://saa-new-dashboard/./src/components/post-smtp-guide.vue","webpack://saa-new-dashboard/./src/components/post-smtp-documentation.vue","webpack://saa-new-dashboard/./src/app.css"],"sourcesContent":["\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","\r\n\r\n\r\n\r\n","@import url( 'https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap' );\r\n\r\n.animated {\r\n animation-duration: 0.5s;\r\n}\r\n\r\n.slideIn {\r\n animation-name: slideIn;\r\n}\r\n\r\n.slideOut {\r\n animation-name: slideOut;\r\n}\r\n\r\n@keyframes slideIn {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-50%);\r\n }\r\n\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n}\r\n\r\n@keyframes slideOut {\r\n from {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n to {\r\n opacity: 0;\r\n transform: translateY(-50%);\r\n }\r\n}\r\n\r\n#wpcontent {\r\n background: #F9FBFF;\r\n}\r\n\r\n.gmail-one-click{\r\n width:274px\r\n}\r\n.gmail-wrapper{\r\n padding: 0px !important;\r\n border-bottom: none !important;\r\n}\r\na.gmail-click:active, a.gmail-click:visited{\r\n color: #fff;\r\n text-decoration: none;\r\n}\r\na.gmail-click:hover,a.gmail-click:focus{\r\n color: #fff;\r\n text-decoration: none;\r\n box-shadow: none;\r\n}\r\n\r\n.office-one-click{\r\n width:274px\r\n}\r\n.office-wrapper{\r\n padding: 0px !important;\r\n border-bottom: none !important;\r\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/responsive-style.css b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/responsive-style.css new file mode 100644 index 0000000..4ff474a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/css/responsive-style.css @@ -0,0 +1,184 @@ +#post-smtp-app .header div[data-v-65055dc1] img[data-v-65055dc1] { + /*width: 220px;*/ +} +.header[data-v-65055dc1], +.container[data-v-64b6d796] { + padding: 0 20px; + box-sizing: border-box; +} +.post-smtp-card-opened--pro[data-v-36caffee] { + background-position: 95% 10% !important; +} + +#post-smtp-app .card-container { + gap: 10px 1%; + display: flex; + justify-content: space-around; + flex-wrap: wrap; +} +#post-smtp-app .card-container .post-smtp-card { + float: none; + width: 24%; + height: auto; + margin: 0; + padding: 25px; + box-sizing: border-box; +} +#post-smtp-app .card-container:after { + display: none; +} +#post-smtp-app .card-container .post-smtp-card .post-smtp-card-content-wrapper { + justify-content: flex-start; + width: auto; + height: 100%; + gap: 15px; +} +#post-smtp-app .card-container .post-smtp-card .post-smtp-card-content-wrapper .post-smtp-image-container { + margin: 0 !important; +} +#post-smtp-app .pro-features { + height: auto; +} + +#post-smtp-app .pro-features .container { + box-sizing: border-box; + padding: 30px 40px; + gap: 40px; +} + +#post-smtp-app .pro-features .container .header, +#post-smtp-app .pro-features .container .body, +#post-smtp-app .pro-features .container .footer { + margin: 0; +} + +#post-smtp-app .pro-features .container .body .feature-block { + margin: 0; + gap: 10px; + align-items: center; + width: 23.5%; +} + +#post-smtp-app .pro-features .container .body { + gap: 20px 2%; + display: flex; + flex-wrap: wrap; +} + +#post-smtp-app .pro-features .container .body .block-content { + margin: 0; +} +#post-smtp-app .documentation .content { + display: flex; + flex-wrap: wrap; + padding: 0 25px; + gap: 20px 2%; +} +#post-smtp-app .documentation .content .documentation { + float: none; + margin: 0; + width: 31.9%; + box-sizing: border-box; +} +#post-smtp-app .documentation .body { + padding: 50px 0 25px; +} +#post-smtp-app .card-container .post-smtp-card * { + text-transform: capitalize; +} +@media only screen and (max-width: 1400px) { + #post-smtp-app .card-container .post-smtp-card { + padding: 20px 15px; + } +} + +@media only screen and (max-width: 1300px) { + #post-smtp-app .container[data-v-64b6d796] { + display: flex; + flex-wrap: wrap; + } + #post-smtp-app .app-wrapper, + #post-smtp-app .app-sidebar { + float: none; + width: 100%; + margin: 0; + } + #post-smtp-app .app-wrapper { + + } + #post-smtp-app .app-sidebar { + + } +} + +@media only screen and (max-width: 1024px) { + #post-smtp-app .card-container .post-smtp-card { + width: 49%; + } + #post-smtp-app .pro-features .container .body{ + justify-content: center; + } + #post-smtp-app .pro-features .container .body .feature-block { + width: 32%; + } + #post-smtp-app .documentation .content .documentation { + width: 49%; + } +} +@media only screen and (max-width: 767px) { + #post-smtp-app .pro-features .container .body .feature-block { + width: 49%; + } +} +@media only screen and (max-width: 575px) { + #post-smtp-app .documentation .content .documentation { + width: 100%; + } + #post-smtp-app .email-menu-wrapper[data-v-383c7fd0] { + right: -10px; + top: -5px; + } + #post-smtp-app .post-smtp-logs-body { + overflow: scroll; + } +} +@media only screen and (max-width: 480px) { + #post-smtp-app .pro-features .container .body .feature-block { + width: 100%; + } + #post-smtp-app .pro-features .container .body .feature-block { + width: 100%; + flex-direction: column; + justify-content: center; + } + #post-smtp-app .pro-features .container .body .block-content { + text-align: center; + } + #post-smtp-app .pro-features .container .body .block-content br { + + } + #post-smtp-app .card-container .post-smtp-card { + width: 100%; + } + #post-smtp-app .post-smtp-selector-wrapper { + display: flex; + flex-direction: column; + justify-content: center; + gap: 10px; + } + + #post-smtp-app .post-smtp-selector-wrapper .wrapper, + #post-smtp-app .post-smtp-selector-wrapper a.re-launch-wizard{ + float: none !important; + margin: 0 auto; + } + + #post-smtp-app .post-smtp-notice { + flex-direction: column; + gap: 10px; + height: auto; + box-sizing: border-box; + width: 100%; + padding: 20px 10px; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/d0a8e6270627cef66c74.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/d0a8e6270627cef66c74.svg new file mode 100644 index 0000000..a77a19d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/d0a8e6270627cef66c74.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/db67b70d37a34f75ab17.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/db67b70d37a34f75ab17.png new file mode 100644 index 0000000..c2e789d Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/db67b70d37a34f75ab17.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/e2f9e8c4d311f9c91473.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/e2f9e8c4d311f9c91473.png new file mode 100644 index 0000000..c2164c1 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/e2f9e8c4d311f9c91473.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/ff6653d27332dc8ab22a.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/ff6653d27332dc8ab22a.svg new file mode 100644 index 0000000..1a4f4df --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/ff6653d27332dc8ab22a.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/Folder illustration.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/Folder illustration.svg new file mode 100644 index 0000000..555b3e2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/Folder illustration.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bell-point.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bell-point.svg new file mode 100644 index 0000000..57d8a47 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bell-point.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bell.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bell.svg new file mode 100644 index 0000000..660f721 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bell.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bin.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bin.svg new file mode 100644 index 0000000..5286d62 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/bin.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-checkbox.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-checkbox.svg new file mode 100644 index 0000000..3a2aa72 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-checkbox.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-email.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-email.svg new file mode 100644 index 0000000..6152658 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-email.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-img-background.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-img-background.svg new file mode 100644 index 0000000..d837b7b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-img-background.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-opened-email.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-opened-email.svg new file mode 100644 index 0000000..503ca24 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-opened-email.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-warning.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-warning.svg new file mode 100644 index 0000000..257f677 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/card-warning.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/connectivity.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/connectivity.svg new file mode 100644 index 0000000..171d56d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/connectivity.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/customer-support.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/customer-support.png new file mode 100644 index 0000000..ad280aa Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/customer-support.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/diagnostic.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/diagnostic.svg new file mode 100644 index 0000000..d51a64c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/diagnostic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/docs.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/docs.svg new file mode 100644 index 0000000..4c75919 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/docs.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/email.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/email.svg new file mode 100644 index 0000000..60ac8d0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/email.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/gmail_one_click.gif b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/gmail_one_click.gif new file mode 100644 index 0000000..899b04f Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/gmail_one_click.gif differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/gmail_oneclick.gif b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/gmail_oneclick.gif new file mode 100644 index 0000000..7b7f01c Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/gmail_oneclick.gif differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/import-export.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/import-export.svg new file mode 100644 index 0000000..a77a19d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/import-export.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/logo.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/logo.png new file mode 100644 index 0000000..e57bdb4 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/logo.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/marker.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/marker.svg new file mode 100644 index 0000000..30194ae --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/marker.svg @@ -0,0 +1,3 @@ + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/maximize.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/maximize.png new file mode 100644 index 0000000..ac74407 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/maximize.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-bell.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-bell.svg new file mode 100644 index 0000000..6331df0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-bell.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-fallback.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-fallback.svg new file mode 100644 index 0000000..d756978 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-fallback.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-logging.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-logging.svg new file mode 100644 index 0000000..090f9fe --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-logging.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-message.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-message.svg new file mode 100644 index 0000000..3d3b726 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-message.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-profile.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-profile.svg new file mode 100644 index 0000000..36d723a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-profile.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-settings.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-settings.svg new file mode 100644 index 0000000..052827b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/menu-settings.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/mobile-app.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/mobile-app.svg new file mode 100644 index 0000000..9201ced --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/mobile-app.svg @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/office_oneclick.gif b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/office_oneclick.gif new file mode 100644 index 0000000..12dd9f9 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/office_oneclick.gif differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-365-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-365-icon.svg new file mode 100644 index 0000000..60d873a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-365-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-amazon-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-amazon-icon.svg new file mode 100644 index 0000000..814ea3e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-amazon-icon.svg @@ -0,0 +1,16 @@ + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-background.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-background.png new file mode 100644 index 0000000..c2e789d Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-background.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-bg-left.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-bg-left.png new file mode 100644 index 0000000..dce5a14 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-bg-left.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-bg-right.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-bg-right.png new file mode 100644 index 0000000..b1a5eb8 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-bg-right.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-crown.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-crown.png new file mode 100644 index 0000000..3357b13 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-crown.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-icon-bg.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-icon-bg.svg new file mode 100644 index 0000000..623c941 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-icon-bg.svg @@ -0,0 +1,3 @@ + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-lock.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-lock.svg new file mode 100644 index 0000000..f9d81f9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-lock.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-log-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-log-icon.svg new file mode 100644 index 0000000..5df9528 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-log-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-reporting-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-reporting-icon.svg new file mode 100644 index 0000000..d180e9d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-reporting-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-resend-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-resend-icon.svg new file mode 100644 index 0000000..3adc76c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-resend-icon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-schedule-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-schedule-icon.svg new file mode 100644 index 0000000..35e8c0a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-schedule-icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-sms-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-sms-icon.svg new file mode 100644 index 0000000..8b87e55 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-sms-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-zoho-icon.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-zoho-icon.svg new file mode 100644 index 0000000..118d1df --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/pro-zoho-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/qrcode.png b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/qrcode.png new file mode 100644 index 0000000..6b697d4 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/qrcode.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/reset.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/reset.svg new file mode 100644 index 0000000..2b5ed8a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/reset.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/settings.svg b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/settings.svg new file mode 100644 index 0000000..b061da1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/images/settings.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js new file mode 100644 index 0000000..667dee7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js @@ -0,0 +1,3 @@ +/*! For license information please see app.js.LICENSE.txt */ +(()=>{var e={229:(e,t,n)=>{"use strict";var o=n(425);const s={class:"post-smtp__wrapper"},r={class:"mt-32 clearfix container"},i={class:"app-wrapper float-left mr-25"},a={class:"app-sidebar float-left"},l={name:"PostSMTPAppWrapper",props:{postSmtpConfigured:{type:Boolean,default:!1},postSmtpPro:{type:Boolean,default:!1},isMobileAppConfigured:{type:Boolean,default:!1},isMainWpConfigured:{type:Boolean,default:!1},isDomainSpamScoreConfigured:{type:Boolean,default:!1},adPosition:{type:String,default:"maximize"},isLogOnlyMode:{type:Boolean,default:!1},isProfessionalOrBasic:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url})};var c=n(262);const u=(0,c.A)(l,[["render",function(e,t,n,l,c,u){const p=(0,o.resolveComponent)("post-smtp-header"),d=(0,o.resolveComponent)("post-smtp-dashboard"),f=(0,o.resolveComponent)("post-smtp-sidebar");return(0,o.openBlock)(),(0,o.createElementBlock)("div",s,[(0,o.createVNode)(p),(0,o.createElementVNode)("div",r,[(0,o.createElementVNode)("div",i,[(0,o.createVNode)(d,{"post-smtp-configured":n.postSmtpConfigured,"is-main-wp-configured":n.isMainWpConfigured,"post-smtp-pro":n.postSmtpPro,"post-smtp-ad-position":n.adPosition,"is-log-only-mode":n.isLogOnlyMode},null,8,["post-smtp-configured","is-main-wp-configured","post-smtp-pro","post-smtp-ad-position","is-log-only-mode"])]),(0,o.createElementVNode)("div",a,[(0,o.createVNode)(f,{"post-smtp-configured":n.postSmtpConfigured,"post-smtp-pro":n.postSmtpPro,"is-mobile-app-configured":n.isMobileAppConfigured,"is-main-wp-configured":n.isMainWpConfigured,"is-domain-spam-score-configured":n.isDomainSpamScoreConfigured,"is-professional-or-basic":n.isProfessionalOrBasic},null,8,["post-smtp-configured","post-smtp-pro","is-mobile-app-configured","is-main-wp-configured","is-domain-spam-score-configured","is-professional-or-basic"])])])])}],["__scopeId","data-v-3112b8ca"]]),p={class:"header"},d={name:"PostSMTPHeader",data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url}),computed:{image_url(){return this.$parent.$parent.plugin_dir_url+"assets/images/logo.png"}},methods:{get_image_url(e){return this.plugin_dir_url+"assets/images/"+e}}},f=(0,c.A)(d,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-img"),l=(0,o.resolveComponent)("post-smtp-settings");return(0,o.openBlock)(),(0,o.createElementBlock)("div",p,[(0,o.createElementVNode)("div",null,[(0,o.createVNode)(a,{src:i.image_url},null,8,["src"])]),(0,o.createElementVNode)("div",null,[(0,o.createVNode)(l,{buttons:[{icon:i.get_image_url("bell.svg"),action:"bell"},{icon:i.get_image_url("settings.svg"),action:"setting"}]},null,8,["buttons"])])])}],["__scopeId","data-v-65055dc1"]]),h=["src","alt"],m={name:"PostSMTPImg",props:{src:{type:String,required:!0},style:{type:Object,default:()=>({})},showPoint:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url}),methods:{explode:(e,t)=>String(t).split(e),strContains:(e,t)=>-1!==String(t).indexOf(e)},computed:{imgSrc(){return this.strContains("bell.svg",this.src)&&this.showPoint?this.explode("bell.svg",this.src)[0]+"bell-point.svg":this.src}}},g=(0,c.A)(m,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("img",{src:i.imgSrc,alt:"Post SMTP "+n.src,style:(0,o.normalizeStyle)(n.style)},null,12,h)}]]),y={class:"settings"},v=["onClick"],_={name:"PostSMTPSettings",props:{buttons:{type:Array,default:()=>[]}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.settings,setting:!1,notification:!1,failed_notifications:[]}),watch:{},computed:{showHideNotificationBar(){return{display:this.notification?"block":"none"}},showHideSettingBar(){return{display:this.setting?"block":"none"}}},methods:{openMenu(e,t){e.preventDefault(),"setting"===t.action&&(this.notification=!1,this.setting=!this.setting),"bell"===t.action&&(this.setting=!1,this.notification=!this.notification)},getFailedNotifications(){axios.get("get-failed-logs").then(e=>{this.failed_notifications=e.data.logs,this.failed_notifications=Object.values(this.failed_notifications)})}},mounted(){this.getFailedNotifications(),document.body.addEventListener("click",e=>{e.target.closest(".settings")||(this.setting=!1,this.notification=!1)})}},b=(0,c.A)(_,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-img"),l=(0,o.resolveComponent)("post-smtp-settings-menu"),c=(0,o.resolveComponent)("post-smtp-notification-bar");return(0,o.openBlock)(),(0,o.createElementBlock)("div",y,[(0,o.createElementVNode)("div",null,[((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,null,(0,o.renderList)(n.buttons,t=>((0,o.openBlock)(),(0,o.createElementBlock)("button",{onClick:e=>i.openMenu(e,t),class:"settings__button"},[(0,o.createVNode)(a,{"show-point":!!e.failed_notifications.length,src:t.icon},null,8,["show-point","src"])],8,v))),256))]),(0,o.createVNode)(l,{style:(0,o.normalizeStyle)(i.showHideSettingBar),menus:[{title:e.i18n[0],icon:"menu-profile",url:e.admin_url+"?page=postman%2Fconfiguration#account_config"},{title:e.i18n[1],icon:"menu-fallback",url:e.admin_url+"?page=postman%2Fconfiguration#fallback"},{title:e.i18n[2],icon:"menu-message",url:e.admin_url+"?page=postman%2Fconfiguration#message_config"},{title:e.i18n[3],icon:"menu-logging",url:e.admin_url+"?page=postman%2Fconfiguration#logging_config"},{title:e.i18n[4],icon:"menu-settings",url:e.admin_url+"?page=postman%2Fconfiguration#advanced_options_config"},{title:e.i18n[5],icon:"menu-bell",url:e.admin_url+"?page=postman%2Fconfiguration#notifications"}]},null,8,["style","menus"]),(0,o.createVNode)(c,{style:(0,o.normalizeStyle)(i.showHideNotificationBar),notifications:e.failed_notifications},null,8,["style","notifications"])])}],["__scopeId","data-v-84d0a47e"]]),S={class:"post-smtp-settings-menu-wrapper"},w={class:"post-smtp-dropdown-menu"},C=["href"],E={name:"PostSmtpSettingsMenu",props:{menus:{type:Array,default:()=>[]}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url})},k=(0,c.A)(E,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-img");return(0,o.openBlock)(),(0,o.createElementBlock)("div",S,[((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,null,(0,o.renderList)(n.menus,t=>((0,o.openBlock)(),(0,o.createElementBlock)("div",w,[(0,o.createElementVNode)("a",{href:t.url,class:"post-smtp-button"},[(0,o.createVNode)(a,{fallback:"menu-fallback"===t.icon,style:{"margin-bottom":"-4px","margin-right":"8px"},src:e.plugin_dir_url+"assets/images/"+t.icon+".svg"},null,8,["fallback","src"]),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(t.title),1)],8,C)]))),256))])}],["__scopeId","data-v-a06ecf4c"]]),x={class:"post-smtp-notification-bar-wrapper"},N=["post-smtp-opened"],T=["onClick"],V={class:"post-smtp-notification-content-wrapper"},A={class:"full-width-content"},B={class:"left-side-content"},O={class:"post-smtp-notification-title"},R={class:"post-smtp-notification-content"},D={style:{"text-align":"right"},class:"right-side-content notification-timeline"},P=["onClick"],L={key:1},I={class:"post-smtp-notification-content-wrapper"},M={class:"left-side-content"},F={class:"post-smtp-notification-title"},$={class:"post-smtp-notification-content"},j={name:"post-smtp-notification-bar",props:{notifications:{type:Array,default:()=>[]}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.notification}),methods:{openNotification(e,t,n){e.preventDefault(),axios.post("open-notification",{id:t.id}).then(e=>{t.opened=!0,window.location.href=n})},removeNotification(e,t){e.preventDefault(),t.opened&&axios.post("remove-notification/",{id:t.id}).then(e=>{const n=this.notifications.indexOf(t);n>-1&&this.notifications.splice(n,1)})}},mounted(){}},U=(0,c.A)(j,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-img");return(0,o.openBlock)(),(0,o.createElementBlock)("div",x,[n.notifications.length?((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,{key:0},(0,o.renderList)(n.notifications,n=>((0,o.openBlock)(),(0,o.createElementBlock)("div",{class:"post-smtp-notification-wrapper","post-smtp-opened":!n.opened},[(0,o.createElementVNode)("a",{href:"#",onClick:t=>i.openNotification(t,n,e.admin_url+"?page=postman_email_log&status=failed"),style:{"text-decoration":"none"}},[(0,o.createElementVNode)("div",V,[(0,o.createElementVNode)("div",A,[(0,o.createElementVNode)("div",B,[(0,o.createElementVNode)("h2",O,[t[0]||(t[0]=(0,o.createElementVNode)("span",{style:{"margin-right":"6px",display:"inline-block"}},[(0,o.createElementVNode)("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[(0,o.createElementVNode)("path",{d:"M18.0335 14.1727L11.9273 3.6083C11.8346 3.44494 11.7256 3.30335 11.6056 3.1781C10.6188 2.14889 8.84146 2.29047 8.07819 3.6083L1.97198 14.1727C1.75936 14.5322 1.66667 14.9079 1.66667 15.2782C1.66667 15.8609 1.90111 16.4163 2.29365 16.8247C2.68619 17.2386 3.24774 17.5 3.89653 17.5H16.1089C17.4065 17.5 18.3333 16.4381 18.3333 15.2728C18.3333 14.9079 18.2407 14.5322 18.0335 14.1727ZM9.11951 7.43111C9.11951 7.02269 9.45208 6.68506 9.86643 6.68506H10.3626C10.7715 6.68506 11.1095 7.01724 11.1095 7.43111V11.0415C11.1095 11.45 10.7769 11.7876 10.3626 11.7876H9.86643C9.45753 11.7876 9.11951 11.4554 9.11951 11.0415V7.43111ZM10.1172 15.3599C9.39211 15.3599 8.80875 14.7718 8.80875 14.0529C8.80875 13.3287 9.39756 12.746 10.1172 12.746C10.8369 12.746 11.4257 13.3341 11.4257 14.0529C11.4257 14.7772 10.8369 15.3599 10.1172 15.3599Z",fill:"#E67373"})])],-1)),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.title),1)]),(0,o.createElementVNode)("p",R,(0,o.toDisplayString)(n.subject),1)]),(0,o.createElementVNode)("div",D,(0,o.toDisplayString)(n.delivery_time),1),t[1]||(t[1]=(0,o.createElementVNode)("div",{class:"clearfix"},null,-1))])])],8,T),n.opened?((0,o.openBlock)(),(0,o.createElementBlock)("a",{key:0,class:"notification-bin left-side-content",onClick:e=>i.removeNotification(e,n),style:{"text-decoration":"none",position:"absolute",bottom:"20px",right:"20px","z-index":"20"}},[(0,o.createVNode)(a,{src:e.plugin_dir_url+"assets/images/bin.svg"},null,8,["src"])],8,P)):(0,o.createCommentVNode)("v-if",!0)],8,N))),256)):((0,o.openBlock)(),(0,o.createElementBlock)("div",L,[(0,o.createElementVNode)("div",I,[(0,o.createElementVNode)("div",M,[(0,o.createElementVNode)("h2",F,[t[2]||(t[2]=(0,o.createElementVNode)("span",{style:{"margin-right":"6px",display:"inline-block"}},[(0,o.createElementVNode)("svg",{width:"20",height:"20",viewBox:"0 0 20 20",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[(0,o.createElementVNode)("path",{d:"M18.0335 14.1727L11.9273 3.6083C11.8346 3.44494 11.7256 3.30335 11.6056 3.1781C10.6188 2.14889 8.84146 2.29047 8.07819 3.6083L1.97198 14.1727C1.75936 14.5322 1.66667 14.9079 1.66667 15.2782C1.66667 15.8609 1.90111 16.4163 2.29365 16.8247C2.68619 17.2386 3.24774 17.5 3.89653 17.5H16.1089C17.4065 17.5 18.3333 16.4381 18.3333 15.2728C18.3333 14.9079 18.2407 14.5322 18.0335 14.1727ZM9.11951 7.43111C9.11951 7.02269 9.45208 6.68506 9.86643 6.68506H10.3626C10.7715 6.68506 11.1095 7.01724 11.1095 7.43111V11.0415C11.1095 11.45 10.7769 11.7876 10.3626 11.7876H9.86643C9.45753 11.7876 9.11951 11.4554 9.11951 11.0415V7.43111ZM10.1172 15.3599C9.39211 15.3599 8.80875 14.7718 8.80875 14.0529C8.80875 13.3287 9.39756 12.746 10.1172 12.746C10.8369 12.746 11.4257 13.3341 11.4257 14.0529C11.4257 14.7772 10.8369 15.3599 10.1172 15.3599Z",fill:"#E67373"})])],-1)),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.title),1)]),(0,o.createElementVNode)("p",$,(0,o.toDisplayString)(e.i18n.description),1)]),t[3]||(t[3]=(0,o.createElementVNode)("div",{class:"clearfix"},null,-1)),t[4]||(t[4]=(0,o.createElementVNode)("div",{class:"full-width-content mt-10"},[(0,o.createElementVNode)("span",{class:"notification-timeline right-side-content"})],-1))])]))])}],["__scopeId","data-v-1d82fd54"]]),H={class:"img-wrapper"},q={class:"gmail-click",target:"_blank",href:"https://postmansmtp.com/pricing/?utm_source=plugin&utm_medium=dashboard&utm_campaign=gmail_one_click"},z={class:"img-wrapper"},W={class:"office-click",target:"_blank",href:"https://postmansmtp.com/pricing/"},K={class:"troubleshooting-header"},J={class:"troubleshooting-content"},Z={class:"troubleshoot"},G={key:0},X=["src"],Q=["target","href"],Y={key:0,style:{color:"#8B8F9A","font-size":"15px","margin-left":"-3px"},class:"dashicons dashicons-external"},ee={class:"customer-support-content"},te={name:"PostSmtpSidebar",props:{postSmtpPro:{type:Boolean,default:!1},postSmtpConfigured:{type:Boolean,default:!1},isMobileAppConfigured:{type:Boolean,default:!1},isMainWpConfigured:{type:Boolean,default:!1},isDomainSpamScoreConfigured:{type:Boolean,default:!1},isProfessionalOrBasic:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.sidebar,troubleshooting:[{title:postSmtpNewDashboard.i18n.sidebar.troubleshooting[0],icon:"email.svg",url:e.$parent.admin_url+"?page=postman/email_test",image:!0,target:!1,show:!0},{title:postSmtpNewDashboard.i18n.sidebar.troubleshooting[1],url:"https://postmansmtp.com/domain-health-checker/",icon:"dashicons dashicons-performance",image:!1,target:"_blank",show:!0},{title:postSmtpNewDashboard.i18n.sidebar.troubleshooting[2],icon:"import-export.svg",url:e.$parent.admin_url+"?page=postman/manage-options",image:!0,target:!1,show:!0},{title:postSmtpNewDashboard.i18n.sidebar.troubleshooting[3],icon:"connectivity.svg",url:e.$parent.admin_url+"?page=postman/port_test",image:!0,target:!1,show:!0},{title:postSmtpNewDashboard.i18n.sidebar.troubleshooting[4],icon:"diagnostic.svg",url:e.$parent.admin_url+"?page=postman/diagnostics",image:!0,target:!1,show:!0},{title:postSmtpNewDashboard.i18n.sidebar.troubleshooting[5],icon:"reset.svg",url:e.$parent.admin_url+"?page=postman/manage-options",image:!0,target:!1,show:!0}]})},ne=(0,c.A)(te,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-img"),l=(0,o.resolveComponent)("post-smtp-widget"),c=(0,o.resolveComponent)("post-smtp-ads"),u=(0,o.resolveComponent)("post-smtp-button");return(0,o.openBlock)(),(0,o.createElementBlock)("div",null,[(0,o.createCommentVNode)(" ✅ Show Gmail One Click widget only if Pro is NOT active "),n.postSmtpPro?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createBlock)(l,{key:0,class:"gmail-wrapper"},{default:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",H,[(0,o.createElementVNode)("a",q,[(0,o.createVNode)(a,{class:"gmail-one-click",src:e.plugin_dir_url+"assets/images/gmail_one_click.gif"},null,8,["src"])])])]),_:1})),(0,o.createCommentVNode)(" ✅ Show Office One Click widget only if Professional or Basic plan is active "),n.isProfessionalOrBasic?((0,o.openBlock)(),(0,o.createBlock)(l,{key:1,class:"office-wrapper"},{default:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",z,[(0,o.createElementVNode)("a",W,[(0,o.createVNode)(a,{class:"office-one-click",src:e.plugin_dir_url+"assets/images/office_oneclick.gif"},null,8,["src"])])])]),_:1})):(0,o.createCommentVNode)("v-if",!0),(0,o.createCommentVNode)(" ✅ Show Ads only if Pro is active and configured "),n.postSmtpPro&&n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createBlock)(c,{key:2,class:"mb-24","post-smtp-pro":n.postSmtpPro,"is-mobile-app-configured":n.isMobileAppConfigured,"is-main-wp-configured":n.isMainWpConfigured,"is-domain-spam-score-configured":n.isDomainSpamScoreConfigured},null,8,["post-smtp-pro","is-mobile-app-configured","is-main-wp-configured","is-domain-spam-score-configured"])):(0,o.createCommentVNode)("v-if",!0),(0,o.createCommentVNode)(" ✅ Always show Troubleshooting widget "),(0,o.createVNode)(l,{class:"troubleshooting"},{default:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",K,(0,o.toDisplayString)(e.i18n.titleTroubleshooting),1),(0,o.createElementVNode)("div",J,[(0,o.createElementVNode)("ul",null,[((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,null,(0,o.renderList)(e.troubleshooting,t=>((0,o.openBlock)(),(0,o.createElementBlock)("li",Z,[t.show?((0,o.openBlock)(),(0,o.createElementBlock)("div",G,[t.image?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createElementBlock)("span",{key:0,style:{"margin-right":"15px",color:"#3c5daa"},class:(0,o.normalizeClass)(t.icon)},null,2)),t.image?((0,o.openBlock)(),(0,o.createElementBlock)("img",{key:1,style:{"margin-bottom":"-5px","margin-right":"16px"},src:e.plugin_dir_url+"assets/images/"+t.icon},null,8,X)):(0,o.createCommentVNode)("v-if",!0),(0,o.createElementVNode)("a",{target:t.target,href:t.url},[(0,o.createTextVNode)((0,o.toDisplayString)(t.title)+" ",1),t.target?((0,o.openBlock)(),(0,o.createElementBlock)("span",Y)):(0,o.createCommentVNode)("v-if",!0)],8,Q)])):(0,o.createCommentVNode)("v-if",!0)]))),256))])])]),_:1}),(0,o.createCommentVNode)(" ✅ Always show Customer Support widget "),(0,o.createVNode)(l,{class:"customer-support"},{default:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",null,[(0,o.createVNode)(a,{src:e.plugin_dir_url+"assets/images/customer-support.png"},null,8,["src"])]),(0,o.createElementVNode)("div",ee,[(0,o.createElementVNode)("p",null,(0,o.toDisplayString)(e.i18n.appointment.description),1)]),(0,o.createElementVNode)("div",null,[(0,o.createVNode)(u,{href:"https://postmansmtp.com/configuration-request/?utm_source=plugin&utm_medium=dashboard_side_banner&utm_campaign=plugin",type:"secondary"},{default:(0,o.withCtx)(()=>[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.appointment.button),1)]),_:1})])]),_:1})])}],["__scopeId","data-v-7b742791"]]),oe={class:"widget-wrapper"},se={name:"PostSmtpWidget",data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url})},re=(0,c.A)(se,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("div",oe,[(0,o.renderSlot)(e.$slots,"default",{},void 0,!0)])}],["__scopeId","data-v-61b1c642"]]),ie={class:"mobile-header"},ae={class:"mobile-unstyles-list"},le={class:"img-wrapper"},ce={class:"main-wp-header"},ue={class:"main-wp-unstyled-list"},pe={class:"main-wp-footer"},de={href:"https://postmansmtp.com/mainwp-post-smtp/?utm_source=plugin&utm_medium=mainwp_banner&utm_campaign=plugin"},fe={class:"post-smtp-spam-score-header"},he={class:"post-smtp-spam-score-list-unstyled"},me={class:"post-smtp-spam-score-footer"},ge={href:"https://postmansmtp.com/domain-health-checker/?utm_source=plugin&utm_medium=dashboard_banner&utm_campaign=plugin"},ye={name:"PostSmtpAds",props:{postSmtpPro:{type:Boolean,default:!1},isMobileAppConfigured:{type:Boolean,default:!1},isMainWpConfigured:{type:Boolean,default:!1},isDomainSpamScoreConfigured:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.ads})},ve=(0,c.A)(ye,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-img"),l=(0,o.resolveComponent)("post-smtp-widget");return(0,o.openBlock)(),(0,o.createElementBlock)("div",null,[n.isMobileAppConfigured?n.isMainWpConfigured?n.isDomainSpamScoreConfigured?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createBlock)(l,{key:2,class:"post-smtp-spam-score-wrapper"},{default:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",null,[(0,o.createElementVNode)("div",fe,[(0,o.createElementVNode)("h2",null,[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.spamScore.title)+" ",1),t[1]||(t[1]=(0,o.createElementVNode)("br",null,null,-1)),(0,o.createElementVNode)("b",null,(0,o.toDisplayString)(e.i18n.spamScore.subTitle),1)])]),(0,o.createElementVNode)("ul",he,[(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.spamScore.list[0]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.spamScore.list[1]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.spamScore.list[2]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.spamScore.list[3]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.spamScore.list[4]),1)]),(0,o.createElementVNode)("div",me,[(0,o.createElementVNode)("a",ge,(0,o.toDisplayString)(e.i18n.spamScore.link),1)])])]),_:1})):((0,o.openBlock)(),(0,o.createBlock)(l,{key:1,class:"post-smtp-main-wp-wrapper"},{default:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",ce,[(0,o.createElementVNode)("h3",null,[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.mainWP.title)+" ",1),(0,o.createElementVNode)("span",null,(0,o.toDisplayString)(e.i18n.mainWP.subTitle),1)])]),(0,o.createElementVNode)("ul",ue,[(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mainWP.list[0]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mainWP.list[1]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mainWP.list[2]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mainWP.list[3]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mainWP.list[4]),1)]),(0,o.createElementVNode)("div",pe,[(0,o.createElementVNode)("a",de,(0,o.toDisplayString)(e.i18n.mainWP.link),1)])]),_:1})):((0,o.openBlock)(),(0,o.createBlock)(l,{key:0,class:"mobile-wrapper"},{default:(0,o.withCtx)(()=>[(0,o.createElementVNode)("h3",ie,[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.mobileApp.title)+" ",1),t[0]||(t[0]=(0,o.createElementVNode)("br",null,null,-1)),(0,o.createElementVNode)("strong",null,(0,o.toDisplayString)(e.i18n.mobileApp.subTitle),1)]),(0,o.createElementVNode)("ul",ae,[(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mobileApp.list[0]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mobileApp.list[1]),1),(0,o.createElementVNode)("li",null,(0,o.toDisplayString)(e.i18n.mobileApp.list[2]),1)]),(0,o.createElementVNode)("div",le,[(0,o.createVNode)(a,{class:"qrcode-img",src:e.plugin_dir_url+"assets/images/qrcode.png"},null,8,["src"]),(0,o.createVNode)(a,{class:"qrcode-mobile-app",src:e.plugin_dir_url+"assets/images/mobile-app.svg"},null,8,["src"])])]),_:1}))])}],["__scopeId","data-v-2975379f"]]),_e=["href","target"],be={name:"PostSmtpButton",props:{type:{type:String,default:()=>"primary"},href:{type:String,default:()=>"#"},target:{type:String,default:()=>"_self"}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url}),computed:{class(){return`btn btn-${this.type}`}}},Se=(0,c.A)(be,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("div",null,[(0,o.createElementVNode)("a",{href:n.href,class:(0,o.normalizeClass)(i.class),target:n.target},[(0,o.renderSlot)(e.$slots,"default",{},void 0,!0)],10,_e)])}],["__scopeId","data-v-e27b9696"]]),we={class:"mb-24 post-smtp-selector-wrapper"},Ce=["href"],Ee={style:{"margin-bottom":"-4px"},width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},ke={name:"PostSmtpDashboard",props:{postSmtpConfigured:{type:Boolean,default:!1},isMainWpConfigured:{type:Boolean,default:!1},postSmtpPro:{type:Boolean,default:!1},postSmtpAdPosition:{type:String,default:"maximize"},isLogOnlyMode:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,period:"week",i18n:postSmtpNewDashboard.i18n.dashboard}),methods:{selectingDataFromDaysSelector(e){this.period=e}}},xe=(0,c.A)(ke,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-days-selector"),l=(0,o.resolveComponent)("post-smtp-banners"),c=(0,o.resolveComponent)("post-smtp-cards-container"),u=(0,o.resolveComponent)("post-smtp-logs-section"),p=(0,o.resolveComponent)("post-smtp-pro-features"),d=(0,o.resolveComponent)("post-smtp-guide");return(0,o.openBlock)(),(0,o.createElementBlock)("div",null,[(0,o.createElementVNode)("div",we,[(0,o.createVNode)(a,{onDaysSelectorEvent:i.selectingDataFromDaysSelector,style:{float:"left"},"post-smtp-configured":n.postSmtpConfigured},null,8,["onDaysSelectorEvent","post-smtp-configured"]),n.postSmtpConfigured||n.isMainWpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("a",{key:0,style:{float:"right"},class:"re-launch-wizard",href:e.admin_url+"?page=postman/configuration_wizard"},[((0,o.openBlock)(),(0,o.createElementBlock)("svg",Ee,[...t[0]||(t[0]=[(0,o.createElementVNode)("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12.75 7.99998C12.7504 9.03089 12.3967 10.0307 11.7483 10.8321C11.0998 11.6335 10.1958 12.188 9.1875 12.4028C8.17921 12.6176 7.12773 12.4796 6.20895 12.012C5.29017 11.5444 4.5598 10.7755 4.14 9.83397L2.749 10.399C3.30042 11.6624 4.27003 12.6975 5.49482 13.3302C6.7196 13.9629 8.12488 14.1546 9.47438 13.8731C10.8239 13.5916 12.0353 12.8541 12.905 11.7845C13.7747 10.7149 14.2497 9.37852 14.25 7.99998C14.2501 6.74771 13.8583 5.5268 13.1296 4.50837C12.4009 3.48994 11.3719 2.72503 10.1866 2.32083C9.00138 1.91664 7.71937 1.89342 6.52027 2.25443C5.32117 2.61545 4.26508 3.3426 3.5 4.33398V2.49998H2V6.49998L2.75 7.24998H6.25V5.74998H4.352C4.84711 4.89165 5.61167 4.22073 6.52705 3.84134C7.44243 3.46196 8.45744 3.39531 9.41457 3.65174C10.3717 3.90818 11.2174 4.47336 11.8205 5.25958C12.4236 6.04579 12.7503 7.00909 12.75 7.99998Z",fill:"#375CAF"},null,-1)])])),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.relaunch),1)],8,Ce)):(0,o.createCommentVNode)("v-if",!0)]),n.postSmtpConfigured?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createBlock)(l,{key:0,class:"mb-24","is-log-only-mode":n.isLogOnlyMode,"post-smtp-configured":n.postSmtpConfigured},null,8,["is-log-only-mode","post-smtp-configured"])),(0,o.createVNode)(c,{period:e.period,class:"mb-24","post-smtp-configured":n.postSmtpConfigured,"post-smtp-pro":n.postSmtpPro},null,8,["period","post-smtp-configured","post-smtp-pro"]),n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createBlock)(l,{key:1,class:"mb-24","post-smtp-configured":n.postSmtpConfigured,"is-log-only-mode":n.isLogOnlyMode},null,8,["post-smtp-configured","is-log-only-mode"])):(0,o.createCommentVNode)("v-if",!0),(0,o.createVNode)(u,{class:"mb-24","post-smtp-configured":n.postSmtpConfigured},null,8,["post-smtp-configured"]),n.postSmtpPro?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createBlock)(p,{key:2,class:"mb-24","post-smtp-ad-position":n.postSmtpAdPosition},null,8,["post-smtp-ad-position"])),(0,o.createVNode)(d,{class:"mb-24"})])}],["__scopeId","data-v-b8fab578"]]),Ne={props:{postSmtpConfigured:{type:Boolean,default:!1}},name:"PostSmtpDaysSelector",data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.days}),methods:{daysSelectorEventHandler(e,t){e.preventDefault(),document.querySelectorAll(".days-selector").forEach(e=>{e.classList.remove("active")}),e.target.classList.add("active"),this.$emit("days-selector-event",t)}},computed:{disable_when_not_configure(){let e={wrapper:!0};return this.postSmtpConfigured||(e.disabled=!0),e}}},Te=(0,c.A)(Ne,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("div",{class:(0,o.normalizeClass)(i.disable_when_not_configure)},[(0,o.createElementVNode)("button",{onClick:t[0]||(t[0]=e=>i.daysSelectorEventHandler(e,"month")),class:"days-selector"},(0,o.toDisplayString)(e.i18n[0]),1),(0,o.createElementVNode)("button",{onClick:t[1]||(t[1]=e=>i.daysSelectorEventHandler(e,"week")),class:"active days-selector"},(0,o.toDisplayString)(e.i18n[1]),1),(0,o.createElementVNode)("button",{onClick:t[2]||(t[2]=e=>i.daysSelectorEventHandler(e,"day")),class:"days-selector"},(0,o.toDisplayString)(e.i18n[2]),1)],2)}],["__scopeId","data-v-0ba96be9"]]),Ve={class:"card-container"},Ae={key:0},Be={key:1},Oe={key:0,class:"post-smtp-content-lighter"},Re={key:1,class:"post-smtp-content-lighter"},De={key:0},Pe={key:1},Le={key:0,class:"post-smtp-content-lighter"},Ie={key:1,class:"post-smtp-content-lighter"},Me={key:0},Fe={key:1},$e={key:0,class:"post-smtp-content-lighter"},je={key:1,class:"post-smtp-content-lighter"},Ue={style:{"margin-bottom":"5px"},class:"pro-content-header"},He={target:"_blank",href:"https://postmansmtp.com/pricing/?utm_source=dashboard&utm_medium=pro_grid&utm_campaign=plugin"},qe={class:"pro-content"},ze={key:0},We={key:1},Ke={key:0,class:"post-smtp-content-lighter"},Je={key:1,class:"post-smtp-content-lighter"},Ze={name:"PostSmtpCardsContainer",props:{period:{type:String,default:()=>"month"},postSmtpConfigured:{type:Boolean,default:!1},postSmtpPro:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,totalEmails:"0",successEmails:"0",failedEmails:"0",title:"",openedEmails:"0",i18n:postSmtpNewDashboard.i18n.cards}),watch:{period(e){this.getLogsCounts(e)}},methods:{getTitle(e){switch(e){case"day":return this.i18n.days[0];case"week":return this.i18n.days[1];case"month":return this.i18n.days[2]}},getLogsCounts(e){axios.get("email-count",{params:{period:e}}).then(t=>{void 0!==t.data.count&&(this.totalEmails=t.data.count.total,this.successEmails=t.data.count.success,this.failedEmails=t.data.count.failed),this.postSmtpPro&&(this.openedEmails=t.data.count.opened||0),this.title=this.getTitle(e)})},redirectToPro(){window.open("https://postmansmtp.com/pricing/?utm_source=dashboard&utm_medium=pro_grid&utm_campaign=plugin","_blank")}},mounted(){this.getLogsCounts(this.period)}},Ge=(0,c.A)(Ze,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-card"),l=(0,o.resolveComponent)("post-smtp-img");return(0,o.openBlock)(),(0,o.createElementBlock)("div",Ve,[(0,o.createVNode)(a,{type:"all","is-pro":n.postSmtpPro,class:"post-smtp-card-box"},{count:(0,o.withCtx)(()=>[n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("div",Ae,(0,o.toDisplayString)(e.totalEmails),1)):((0,o.openBlock)(),(0,o.createElementBlock)("div",Be," 0 "))]),content:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",null,[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.total)+" ",1),t[0]||(t[0]=(0,o.createElementVNode)("br",null,null,-1)),n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("span",Oe,(0,o.toDisplayString)(e.title),1)):((0,o.openBlock)(),(0,o.createElementBlock)("span",Re,"-"))])]),_:1},8,["is-pro"]),(0,o.createVNode)(a,{type:"success","is-pro":n.postSmtpPro,class:"post-smtp-card-box"},{count:(0,o.withCtx)(()=>[n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("div",De,(0,o.toDisplayString)(e.successEmails),1)):((0,o.openBlock)(),(0,o.createElementBlock)("div",Pe,"0"))]),content:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",null,[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.success)+" ",1),t[1]||(t[1]=(0,o.createElementVNode)("br",null,null,-1)),n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("span",Le,(0,o.toDisplayString)(e.title),1)):((0,o.openBlock)(),(0,o.createElementBlock)("span",Ie,"-"))])]),_:1},8,["is-pro"]),(0,o.createVNode)(a,{type:"failed","is-pro":n.postSmtpPro,class:"post-smtp-card-box"},{count:(0,o.withCtx)(()=>[n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("div",Me,(0,o.toDisplayString)(e.failedEmails),1)):((0,o.openBlock)(),(0,o.createElementBlock)("div",Fe,"0"))]),content:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",null,[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.failed)+" ",1),t[2]||(t[2]=(0,o.createElementVNode)("br",null,null,-1)),n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("span",$e,(0,o.toDisplayString)(e.title),1)):((0,o.openBlock)(),(0,o.createElementBlock)("span",je,"-"))])]),_:1},8,["is-pro"]),(0,o.createCommentVNode)("\tv-if=! isPro\t"),n.postSmtpPro?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createBlock)(a,{key:0,type:"opened--pro",class:"pro-remove-margin",onClick:i.redirectToPro,style:{cursor:"pointer"}},{count:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",Ue,(0,o.toDisplayString)(e.i18n.openedPro.title),1)]),content:(0,o.withCtx)(()=>[(0,o.createVNode)(l,{style:{"margin-right":"4px","margin-bottom":"-2px"},src:e.plugin_dir_url+"assets/images/pro-lock.svg",alt:"Unlock"},null,8,["src"]),(0,o.createElementVNode)("a",He,[(0,o.createElementVNode)("span",qe,(0,o.toDisplayString)(e.i18n.openedPro.subTitle),1)])]),_:1},8,["onClick"])),(0,o.createCommentVNode)("\tv-endif\t"),n.postSmtpPro?((0,o.openBlock)(),(0,o.createBlock)(a,{key:1,type:"opened--pro","is-pro":n.postSmtpPro,class:"post-smtp-card-box"},{count:(0,o.withCtx)(()=>[n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("div",ze,(0,o.toDisplayString)(e.openedEmails),1)):((0,o.openBlock)(),(0,o.createElementBlock)("div",We,"0"))]),content:(0,o.withCtx)(()=>[(0,o.createElementVNode)("div",null,[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.opened)+" ",1),t[3]||(t[3]=(0,o.createElementVNode)("br",null,null,-1)),n.postSmtpConfigured?((0,o.openBlock)(),(0,o.createElementBlock)("span",Ke,(0,o.toDisplayString)(e.title),1)):((0,o.openBlock)(),(0,o.createElementBlock)("span",Je,"-"))])]),_:1},8,["is-pro"])):(0,o.createCommentVNode)("v-if",!0)])}],["__scopeId","data-v-2dc01e40"]]),Xe=["is-pro"],Qe={class:"post-smtp-card-content-wrapper"},Ye={class:"post-smtp-image-container",style:{"margin-right":"15px"}},et={class:"post-smtp-count"},tt={class:"post-smtp-content"},nt={name:"PostSmtpCard",props:{type:{type:String,required:!0},isPro:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url}),computed:{classes(){return{"post-smtp-card":!0,"post-smtp-card-all":"all"===this.type,"post-smtp-card-success":"success"===this.type,"post-smtp-card-failed":"failed"===this.type,"post-smtp-card-opened--pro":"opened--pro"===this.type,"post-smtp-card-pro":this.isPro}}}},ot=(0,c.A)(nt,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("div",{class:(0,o.normalizeClass)(i.classes),"is-pro":n.isPro},[(0,o.createElementVNode)("div",Qe,[(0,o.createElementVNode)("div",Ye,[(0,o.renderSlot)(e.$slots,"image",{},void 0,!0)]),(0,o.createElementVNode)("div",null,[(0,o.createElementVNode)("div",{class:"post-smtp-count-wrapper",style:(0,o.normalizeStyle)("margin-bottom: "+("opened--pro"===n.type?"5px":"8.36px")+";")},[(0,o.createElementVNode)("h2",et,[(0,o.renderSlot)(e.$slots,"count",{},void 0,!0)])],4),(0,o.createElementVNode)("div",null,[(0,o.createElementVNode)("p",tt,[(0,o.renderSlot)(e.$slots,"content",{},void 0,!0)])])])])],10,Xe)}],["__scopeId","data-v-3753d82c"]]),st=["href"],rt={style:{"margin-bottom":"-1px"},width:"12",height:"13",viewBox:"0 0 12 13",fill:"none",xmlns:"http://www.w3.org/2000/svg"},it=["href"],at={style:{"margin-bottom":"-4px"},width:"15",height:"16",viewBox:"0 0 15 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},lt=["href"],ct={style:{"margin-bottom":"-4px"},width:"15",height:"16",viewBox:"0 0 15 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},ut={name:"post-smtp-banners",props:{postSmtpConfigured:{type:Boolean,default:!1},isMainWpConfigured:{type:Boolean,default:!1},isLogOnlyMode:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.banners}),computed:{send_test_email_url(){return`${this.admin_url}?page=postman/email_test`},wizard_url(){return`${this.admin_url}?page=postman/configuration_wizard`}},mounted(){console.log(this.isLogOnlyMode)}},pt=(0,c.A)(ut,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-notice");return(0,o.openBlock)(),(0,o.createElementBlock)("div",null,[!n.postSmtpConfigured&&!n.isMainWpConfigured||n.isLogOnlyMode?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createBlock)(a,{key:0,type:"success"},{title:(0,o.withCtx)(()=>[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.configured.text),1)]),button:(0,o.withCtx)(()=>[(0,o.createElementVNode)("a",{href:i.send_test_email_url,class:"post-smtp-button"},[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.configured.button)+" ",1),(0,o.createElementVNode)("i",null,[((0,o.openBlock)(),(0,o.createElementBlock)("svg",rt,[...t[0]||(t[0]=[(0,o.createElementVNode)("g",{"clip-path":"url(#clip0_67_1316)"},[(0,o.createElementVNode)("path",{d:"M11.8124 0.173758C11.9597 0.280901 12.02 0.423758 11.9932 0.60233L10.2789 10.888C10.2566 11.0175 10.1852 11.118 10.0646 11.1894C10.0021 11.2251 9.93293 11.243 9.85703 11.243C9.80793 11.243 9.75435 11.2318 9.69632 11.2095L6.66284 9.97063L5.0423 11.9461C4.96194 12.0488 4.85257 12.1001 4.71418 12.1001C4.65614 12.1001 4.60703 12.0912 4.56685 12.0733C4.48203 12.0421 4.41395 11.9896 4.36261 11.9159C4.31127 11.8423 4.2856 11.7608 4.2856 11.6715V9.33447L10.0713 2.24295L2.91284 8.43715L0.267747 7.35233C0.102568 7.28983 0.0132824 7.16706 -0.000110445 6.98403C-0.00903902 6.80545 0.0623896 6.67376 0.214175 6.58894L11.357 0.160366C11.424 0.120187 11.4954 0.100098 11.5713 0.100098C11.6606 0.100098 11.741 0.124651 11.8124 0.173758Z",fill:"white"})],-1),(0,o.createElementVNode)("defs",null,[(0,o.createElementVNode)("clipPath",{id:"clip0_67_1316"},[(0,o.createElementVNode)("rect",{width:"12",height:"12",fill:"white",transform:"translate(0 0.100098)"})])],-1)])]))])],8,st)]),_:1})),n.postSmtpConfigured||n.isMainWpConfigured||n.isLogOnlyMode?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createBlock)(a,{key:1,type:"warning"},{title:(0,o.withCtx)(()=>[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.notConfigured.text),1)]),button:(0,o.withCtx)(()=>[(0,o.createElementVNode)("a",{href:i.wizard_url,class:"post-smtp-button"},[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.notConfigured.button)+" ",1),(0,o.createElementVNode)("i",null,[((0,o.openBlock)(),(0,o.createElementBlock)("svg",at,[...t[1]||(t[1]=[(0,o.createElementVNode)("path",{d:"M8.293 2.79303C8.48053 2.60556 8.73484 2.50024 9 2.50024C9.26516 2.50024 9.51947 2.60556 9.707 2.79303L14.207 7.29303C14.3945 7.48056 14.4998 7.73487 14.4998 8.00003C14.4998 8.26519 14.3945 8.5195 14.207 8.70703L9.707 13.207C9.5184 13.3892 9.2658 13.49 9.0036 13.4877C8.7414 13.4854 8.49059 13.3803 8.30518 13.1948C8.11977 13.0094 8.0146 12.7586 8.01233 12.4964C8.01005 12.2342 8.11084 11.9816 8.293 11.793L11 9.00003H1.5C1.23478 9.00003 0.98043 8.89467 0.792893 8.70714C0.605357 8.5196 0.5 8.26525 0.5 8.00003C0.5 7.73481 0.605357 7.48046 0.792893 7.29292C0.98043 7.10539 1.23478 7.00003 1.5 7.00003H11L8.293 4.20703C8.10553 4.0195 8.00021 3.76519 8.00021 3.50003C8.00021 3.23487 8.10553 2.98056 8.293 2.79303Z",fill:"#EEEEEE"},null,-1)])]))])],8,it)]),_:1})),n.isLogOnlyMode?((0,o.openBlock)(),(0,o.createBlock)(a,{key:2,type:"warning"},{title:(0,o.withCtx)(()=>[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.isLogOnly.text),1)]),button:(0,o.withCtx)(()=>[(0,o.createElementVNode)("a",{href:i.wizard_url,class:"post-smtp-button"},[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.isLogOnly.button)+" ",1),(0,o.createElementVNode)("i",null,[((0,o.openBlock)(),(0,o.createElementBlock)("svg",ct,[...t[2]||(t[2]=[(0,o.createElementVNode)("path",{d:"M8.293 2.79303C8.48053 2.60556 8.73484 2.50024 9 2.50024C9.26516 2.50024 9.51947 2.60556 9.707 2.79303L14.207 7.29303C14.3945 7.48056 14.4998 7.73487 14.4998 8.00003C14.4998 8.26519 14.3945 8.5195 14.207 8.70703L9.707 13.207C9.5184 13.3892 9.2658 13.49 9.0036 13.4877C8.7414 13.4854 8.49059 13.3803 8.30518 13.1948C8.11977 13.0094 8.0146 12.7586 8.01233 12.4964C8.01005 12.2342 8.11084 11.9816 8.293 11.793L11 9.00003H1.5C1.23478 9.00003 0.98043 8.89467 0.792893 8.70714C0.605357 8.5196 0.5 8.26525 0.5 8.00003C0.5 7.73481 0.605357 7.48046 0.792893 7.29292C0.98043 7.10539 1.23478 7.00003 1.5 7.00003H11L8.293 4.20703C8.10553 4.0195 8.00021 3.76519 8.00021 3.50003C8.00021 3.23487 8.10553 2.98056 8.293 2.79303Z",fill:"#EEEEEE"},null,-1)])]))])],8,lt)]),_:1})):(0,o.createCommentVNode)("v-if",!0)])}],["__scopeId","data-v-b0a24b2e"]]),dt={class:"post-smtp-notice-wrapper"},ft={class:"post-smtp-notice-content"},ht={class:"post-smtp-notice-icon"},mt={key:0,style:{"margin-bottom":"-5px"},width:"16",height:"17",viewBox:"0 0 16 17",fill:"none",xmlns:"http://www.w3.org/2000/svg"},gt={key:1,style:{"margin-bottom":"-2px"},width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},yt={name:"postSmtpNotice",props:{type:{type:String,required:!0}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url}),computed:{classes(){return{"post-smtp-notice":!0,"post-smtp-notice-success":"success"===this.type,"post-smtp-notice-error":"error"===this.type,"post-smtp-notice-warning":"warning"===this.type}}}},vt=(0,c.A)(yt,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("div",dt,[(0,o.createElementVNode)("div",{class:(0,o.normalizeClass)(i.classes)},[(0,o.createElementVNode)("div",null,[(0,o.createElementVNode)("p",ft,[(0,o.createElementVNode)("span",ht,["success"===n.type?((0,o.openBlock)(),(0,o.createElementBlock)("svg",mt,[...t[0]||(t[0]=[(0,o.createElementVNode)("path",{d:"M8 0.100098C3.58 0.100098 0 3.6801 0 8.1001C0 12.5201 3.58 16.1001 8 16.1001C12.42 16.1001 16 12.5201 16 8.1001C16 3.6801 12.42 0.100098 8 0.100098ZM7.385 12.7601H6.045L2.805 8.2201L4.145 6.9701L6.715 9.3701L11.855 3.4401L13.195 4.3801L7.385 12.7601Z",fill:"#6EB68B"},null,-1)])])):(0,o.createCommentVNode)("v-if",!0),"warning"===n.type?((0,o.openBlock)(),(0,o.createElementBlock)("svg",gt,[...t[1]||(t[1]=[(0,o.createElementVNode)("path",{d:"M8 0C12.42 0 16 3.58 16 8C16 12.42 12.42 16 8 16C3.58 16 0 12.42 0 8C0 3.58 3.58 0 8 0ZM13 11L10 8L13 5L11 3L8 6L5 3L3 5L6 8L3 11L5 13L8 10L11 13L13 11Z",fill:"#CF6969"},null,-1)])])):(0,o.createCommentVNode)("v-if",!0)]),(0,o.createElementVNode)("strong",null,[(0,o.renderSlot)(e.$slots,"title",{},void 0,!0)]),(0,o.renderSlot)(e.$slots,"message",{},void 0,!0)])]),(0,o.createElementVNode)("div",null,[(0,o.renderSlot)(e.$slots,"button",{},void 0,!0)])],2)])}],["__scopeId","data-v-d473dc1c"]]),_t={class:"post-smtp-logs-wrapper"},bt={class:"post-smtp-logs-header"},St={class:"float-left"},wt={class:"float-right"},Ct=["href"],Et={class:"post-smtp-logs-body"},kt={key:0},xt={style:{"text-align":"left",width:"253px"}},Nt={style:{"text-align":"left",width:"233.01px"}},Tt={style:{"text-align":"left",width:"192.99px"}},Vt={style:{"text-align":"left",width:"173px"}},At={class:"post-smtp-status-wrapper"},Bt={key:0,class:"post-smtp-status post-smtp-success"},Ot={key:1,style:{"background-color":"#ffa500",color:"#ffffff"},class:"post-smtp-status"},Rt={key:2,class:"post-smtp-status post-smtp-failed"},Dt={key:1,class:"post-smtp-logs-empty"},Pt={class:"post-smtp-logs-content"},Lt={key:0,class:"post-smtp-logs-footer"},It=["href"],Mt={name:"PostSmtpLogsSection",props:{postSmtpConfigured:{type:Boolean,default:!1}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.logs,logs:[]}),watch:{},computed:{is_post_smtp_logs_are_ready(){return this.logs.length},get_logs_url(){return`${this.admin_url}?page=postman_email_log`},wizard_url(){return`${this.admin_url}?page=postman/configuration_wizard`}},methods:{get_logs(){axios.get("get-logs").then(e=>{this.logs=e.data.logs})},getLatestLogs(){this.get_logs()},showHideLogActionMenu:e=>({display:e.show_log_menu?"block":"none"})},mounted(){this.get_logs(),document.body.addEventListener("click",e=>{e.target.closest(".email-menu-wrapper")||this.logs.forEach(e=>{e.show_log_menu=!1})})}},Ft=(0,c.A)(Mt,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-log-action-menu");return(0,o.openBlock)(),(0,o.createElementBlock)("div",_t,[(0,o.createElementVNode)("div",bt,[(0,o.createElementVNode)("div",St,[(0,o.createElementVNode)("h2",null,(0,o.toDisplayString)(e.i18n.title),1)]),(0,o.createElementVNode)("div",wt,[(0,o.createElementVNode)("a",{href:i.get_logs_url},(0,o.toDisplayString)(e.i18n.button),9,Ct)])]),(0,o.createElementVNode)("div",Et,[i.is_post_smtp_logs_are_ready?((0,o.openBlock)(),(0,o.createElementBlock)("table",kt,[(0,o.createElementVNode)("thead",null,[(0,o.createElementVNode)("tr",null,[(0,o.createElementVNode)("th",xt,(0,o.toDisplayString)(e.i18n.headers[0]),1),(0,o.createElementVNode)("th",Nt,(0,o.toDisplayString)(e.i18n.headers[1]),1),(0,o.createElementVNode)("th",Tt,(0,o.toDisplayString)(e.i18n.headers[2]),1),(0,o.createElementVNode)("th",Vt,(0,o.toDisplayString)(e.i18n.headers[3]),1)])]),(0,o.createElementVNode)("tbody",null,[((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,null,(0,o.renderList)(e.logs,t=>((0,o.openBlock)(),(0,o.createElementBlock)("tr",{key:t.id},[(0,o.createElementVNode)("td",null,(0,o.toDisplayString)(t.subject),1),(0,o.createElementVNode)("td",null,(0,o.toDisplayString)(t.sent_to),1),(0,o.createElementVNode)("td",null,(0,o.toDisplayString)(t.delivery_time),1),(0,o.createElementVNode)("td",null,[(0,o.createElementVNode)("div",At,["success"===t.status?((0,o.openBlock)(),(0,o.createElementBlock)("span",Bt,(0,o.toDisplayString)(e.i18n.success),1)):(0,o.createCommentVNode)("v-if",!0),"in_queue"===t.status?((0,o.openBlock)(),(0,o.createElementBlock)("span",Ot,"In Queue")):(0,o.createCommentVNode)("v-if",!0),"failed"===t.status?((0,o.openBlock)(),(0,o.createElementBlock)("span",Rt,(0,o.toDisplayString)(e.i18n.failed),1)):(0,o.createCommentVNode)("v-if",!0),(0,o.createVNode)(a,{onEmailTriggered:i.getLatestLogs,item:t,"dynamic-id":t.id},null,8,["onEmailTriggered","item","dynamic-id"])])])]))),128))])])):((0,o.openBlock)(),(0,o.createElementBlock)("div",Dt,[t[0]||(t[0]=(0,o.createStaticVNode)('
        ',1)),(0,o.createElementVNode)("div",Pt,[(0,o.createElementVNode)("h3",null,(0,o.toDisplayString)(e.i18n.noLogs.title),1),(0,o.createElementVNode)("p",null,(0,o.toDisplayString)(e.i18n.noLogs.description),1)]),n.postSmtpConfigured?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createElementBlock)("div",Lt,[(0,o.createElementVNode)("a",{href:i.wizard_url},(0,o.toDisplayString)(e.i18n.notConfigured),9,It)]))]))])])}],["__scopeId","data-v-82c3bb58"]]),$t={class:"post-smtp-link"},jt={class:"post-smtp-link"},Ut={class:"post-smtp-link"},Ht={key:0,class:"post-smtp-link"},qt={key:0,class:"post-smtp-error-details"},zt={class:"post-smtp-details-wrapper"},Wt={key:0,style:{width:"100%",height:"calc( 100% - 25px )",position:"absolute",top:"25px",left:"0",display:"flex","justify-content":"center","align-items":"center"}},Kt={key:1},Jt={key:2},Zt={key:3},Gt={class:"post-smtp--headers"},Xt=["innerHTML"],Qt=["innerHTML"],Yt=["innerHTML"],en=["innerHTML"],tn=["innerHTML"],nn=["src"],on={key:4},sn={class:"resend-email-wrapper"},rn={class:"form-group"},an={for:"email"},ln={class:"description",style:{"margin-bottom":"15px"}},cn={name:"PostSmtpLogActionMenu",props:{item:{type:Object,required:!0},dynamicId:{type:String,required:!0}},data:e=>({plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,i18n:postSmtpNewDashboard.i18n.logActionMenu,show_popup:!1,show_error:!1,show_view:!1,show_transcript:!1,resend_email:!1,session_transcript:"Loading...",content_loading:!1,message_object:{from:"",to:"",date:"",subject:"",delivery_uri:"",message_url:""},sent_to:"",open_action_menu:!1}),watch:{show_popup(e){e||(this.show_error=!1,this.show_view=!1,this.show_transcript=!1,this.resend_email=!1,this.open_action_menu=!1,this.session_transcript="Loading...",this.message_object.from="",this.message_object.to="",this.message_object.date="",this.message_object.subject="",this.message_object.delivery_uri="",this.message_object.message_url="",this.$emit("close-log-menu",this.item))}},computed:{showHidePopup(){return{display:this.show_popup?"block":"none"}},showHideActionMenu(){return{display:this.open_action_menu?"block":"none"}}},methods:{viewDetails(e,t){e.preventDefault(),this.$nextTick(()=>{this.show_popup=!0,"resend_email"!==t?"show_error"!==t&&this.$nextTick(()=>{this.getDetails(t)}):this.sent_to=this.item.sent_to,this[t]=!0}).then(()=>{})},closeDetails(e){e.preventDefault(),this.show_popup=!1},getDetails(e){return this.content_loading=!0,axios.get("get-details",{params:{id:this.item.id,type:e}}).then(t=>{if(this.content_loading=!1,"show_transcript"===e)this.session_transcript=t.data.details.session_transcript;else if("show_view"===e){let e=t.data.details;this.message_object.from=e.from_header,this.message_object.to=e.to_header,this.message_object.date=e.time,this.message_object.subject=e.original_subject,this.message_object.delivery_uri=e.transport_uri,this.message_object.message_url=e.log_url}this[e]=!0})},resendEmail(e){e.preventDefault(),axios.post("resend-email",{id:this.item.id,sent_to:this.sent_to}).then(e=>{this.show_popup=!1,this.$emit("email-triggered",e.data.details)})},openActionMenu(e){this.open_action_menu=!this.open_action_menu}},mounted(){document.body.addEventListener("click",e=>{e.target.closest(".log-action-menu-wrapper-"+this.dynamicId)||(this.open_action_menu=!1)})}},un=(0,c.A)(cn,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("div",{class:(0,o.normalizeClass)(`log-action-menu-wrapper log-action-menu-wrapper-${n.dynamicId}`)},[(0,o.createElementVNode)("div",{class:"post-smtp-log-action-menu-wrapper",style:(0,o.normalizeStyle)(i.showHideActionMenu)},[(0,o.createElementVNode)("div",$t,[(0,o.createElementVNode)("a",{onClick:t[0]||(t[0]=e=>i.viewDetails(e,"show_view")),href:"#"},[t[8]||(t[8]=(0,o.createElementVNode)("i",null,[(0,o.createElementVNode)("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[(0,o.createElementVNode)("path",{d:"M7.99999 6C7.46956 6 6.96085 6.21071 6.58578 6.58579C6.2107 6.96086 5.99999 7.46957 5.99999 8C5.99999 8.53043 6.2107 9.03914 6.58578 9.41421C6.96085 9.78929 7.46956 10 7.99999 10C8.53042 10 9.03913 9.78929 9.4142 9.41421C9.78928 9.03914 9.99999 8.53043 9.99999 8C9.99999 7.46957 9.78928 6.96086 9.4142 6.58579C9.03913 6.21071 8.53042 6 7.99999 6ZM7.99999 11.3333C7.11594 11.3333 6.26809 10.9821 5.64297 10.357C5.01785 9.7319 4.66666 8.88406 4.66666 8C4.66666 7.11595 5.01785 6.2681 5.64297 5.64298C6.26809 5.01786 7.11594 4.66667 7.99999 4.66667C8.88405 4.66667 9.73189 5.01786 10.357 5.64298C10.9821 6.2681 11.3333 7.11595 11.3333 8C11.3333 8.88406 10.9821 9.7319 10.357 10.357C9.73189 10.9821 8.88405 11.3333 7.99999 11.3333ZM7.99999 3C4.66666 3 1.81999 5.07333 0.666656 8C1.81999 10.9267 4.66666 13 7.99999 13C11.3333 13 14.18 10.9267 15.3333 8C14.18 5.07333 11.3333 3 7.99999 3Z",fill:"#231F20"})])],-1)),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.action.view),1)])]),(0,o.createElementVNode)("div",jt,[(0,o.createElementVNode)("a",{href:"#",onClick:t[1]||(t[1]=e=>i.viewDetails(e,"resend_email"))},[t[9]||(t[9]=(0,o.createElementVNode)("i",null,[(0,o.createElementVNode)("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[(0,o.createElementVNode)("path",{d:"M1.34001 14L15.3333 8L1.34001 2L1.33334 6.66667L11.3333 8L1.33334 9.33333L1.34001 14Z",fill:"#231F20"})])],-1)),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.action.resend),1)])]),(0,o.createElementVNode)("div",Ut,[(0,o.createElementVNode)("a",{onClick:t[2]||(t[2]=e=>i.viewDetails(e,"show_transcript")),href:"#"},[t[10]||(t[10]=(0,o.createStaticVNode)('',1)),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.action.transcript),1)])]),"failed"===n.item.status?((0,o.openBlock)(),(0,o.createElementBlock)("div",Ht,[(0,o.createElementVNode)("a",{onClick:t[3]||(t[3]=e=>i.viewDetails(e,"show_error")),href:"#"},[t[11]||(t[11]=(0,o.createElementVNode)("i",null,[(0,o.createElementVNode)("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg"},[(0,o.createElementVNode)("path",{d:"M0.666656 14H15.3333L7.99999 1.33331L0.666656 14ZM8.66666 12H7.33332V10.6666H8.66666V12ZM8.66666 9.33331H7.33332V6.66665H8.66666V9.33331Z",fill:"#231F20"})])],-1)),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.action.details),1)])])):(0,o.createCommentVNode)("v-if",!0)],4),e.show_popup?((0,o.openBlock)(),(0,o.createElementBlock)("div",qt,[(0,o.createElementVNode)("div",zt,[(0,o.createElementVNode)("a",{class:"post-smtp-close-button",onClick:t[4]||(t[4]=(...e)=>i.closeDetails&&i.closeDetails(...e)),href:"#"},"×"),e.content_loading?((0,o.openBlock)(),(0,o.createElementBlock)("div",Wt,[...t[12]||(t[12]=[(0,o.createElementVNode)("div",null,"loading...",-1)])])):(0,o.createCommentVNode)("v-if",!0),e.show_error?((0,o.openBlock)(),(0,o.createElementBlock)("div",Kt,(0,o.toDisplayString)(n.item.error),1)):(0,o.createCommentVNode)("v-if",!0),e.show_transcript?((0,o.openBlock)(),(0,o.createElementBlock)("div",Jt,(0,o.toDisplayString)(e.session_transcript),1)):(0,o.createCommentVNode)("v-if",!0),e.show_view?((0,o.openBlock)(),(0,o.createElementBlock)("div",Zt,[(0,o.createElementVNode)("div",Gt,[(0,o.createElementVNode)("table",null,[(0,o.createElementVNode)("tbody",null,[(0,o.createElementVNode)("tr",null,[(0,o.createElementVNode)("td",null,[(0,o.createElementVNode)("strong",null,(0,o.toDisplayString)(e.i18n.headers.from)+": ",1)]),(0,o.createElementVNode)("td",{innerHTML:e.message_object.from},null,8,Xt)]),(0,o.createElementVNode)("tr",null,[(0,o.createElementVNode)("td",null,[(0,o.createElementVNode)("strong",null,(0,o.toDisplayString)(e.i18n.headers.to)+": ",1)]),(0,o.createElementVNode)("td",{innerHTML:e.message_object.to},null,8,Qt)]),(0,o.createElementVNode)("tr",null,[(0,o.createElementVNode)("td",null,[(0,o.createElementVNode)("strong",null,(0,o.toDisplayString)(e.i18n.headers.date)+": ",1)]),(0,o.createElementVNode)("td",{innerHTML:e.message_object.date},null,8,Yt)]),(0,o.createElementVNode)("tr",null,[(0,o.createElementVNode)("td",null,[(0,o.createElementVNode)("strong",null,(0,o.toDisplayString)(e.i18n.headers.subject)+": ",1)]),(0,o.createElementVNode)("td",{innerHTML:e.message_object.subject},null,8,en)]),(0,o.createElementVNode)("tr",null,[(0,o.createElementVNode)("td",null,[(0,o.createElementVNode)("strong",null,(0,o.toDisplayString)(e.i18n.headers.deliveryURI)+": ",1)]),(0,o.createElementVNode)("td",{innerHTML:e.message_object.delivery_uri},null,8,tn)])])]),t[13]||(t[13]=(0,o.createElementVNode)("hr",null,null,-1)),(0,o.createElementVNode)("div",null,[(0,o.createElementVNode)("iframe",{width:"100%",height:"310px",src:e.message_object.message_url},null,8,nn)])])])):(0,o.createCommentVNode)("v-if",!0),e.resend_email?((0,o.openBlock)(),(0,o.createElementBlock)("div",on,[(0,o.createElementVNode)("div",sn,[(0,o.createElementVNode)("div",rn,[(0,o.createElementVNode)("label",an,(0,o.toDisplayString)(e.i18n.resendEmail.emailAddress),1),(0,o.withDirectives)((0,o.createElementVNode)("textarea",{"onUpdate:modelValue":t[5]||(t[5]=t=>e.sent_to=t),class:"form-control"},(0,o.toDisplayString)(n.item.sent_to),513),[[o.vModelText,e.sent_to]]),(0,o.createElementVNode)("p",ln,[(0,o.createElementVNode)("strong",null,(0,o.toDisplayString)(e.i18n.resendEmail.description),1)]),(0,o.createElementVNode)("button",{onClick:t[6]||(t[6]=e=>i.resendEmail(e)),class:"post-smtp-button primary"},(0,o.toDisplayString)(e.i18n.resendEmail.button),1)])])])):(0,o.createCommentVNode)("v-if",!0)])])):(0,o.createCommentVNode)("v-if",!0),(0,o.createElementVNode)("div",{onClick:t[7]||(t[7]=()=>i.openActionMenu(n.item)),class:"email-menu-wrapper"},[...t[14]||(t[14]=[(0,o.createElementVNode)("span",{class:"email-menu-action"},null,-1),(0,o.createElementVNode)("span",{class:"email-menu-action"},null,-1),(0,o.createElementVNode)("span",{class:"email-menu-action"},null,-1)])])],2)}],["__scopeId","data-v-1121e3a1"]]),pn={class:"header"},dn={key:0,class:"body"},fn={key:0},hn={key:1,class:"create-container"},mn={class:"block-content"},gn=["innerHTML"],yn={key:0,class:"footer"},vn={name:"postSmtpProFeatures",props:{postSmtpAdPosition:{type:String,default:"maximize"}},data:e=>({i18n:postSmtpNewDashboard.i18n.proFeatures,plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,is_bcfm:postSmtpNewDashboard.is_bfcm,click_link:"",features:[{title:postSmtpNewDashboard.i18n.proFeatures.list[0],img:"pro-schedule-icon.svg",has_container:!0},{title:postSmtpNewDashboard.i18n.proFeatures.list[1],img:"pro-reporting-icon.svg",has_container:!0},{title:postSmtpNewDashboard.i18n.proFeatures.list[2],img:"pro-log-icon.svg",has_container:!1},{title:postSmtpNewDashboard.i18n.proFeatures.list[3],img:"pro-sms-icon.svg",has_container:!1},{title:postSmtpNewDashboard.i18n.proFeatures.list[4],img:"pro-resend-icon.svg",has_container:!0},{title:postSmtpNewDashboard.i18n.proFeatures.list[5],img:"pro-365-icon.svg",has_container:!1},{title:postSmtpNewDashboard.i18n.proFeatures.list[6],img:"pro-amazon-icon.svg",has_container:!1},{title:postSmtpNewDashboard.i18n.proFeatures.list[7],img:"pro-zoho-icon.svg",has_container:!1}],minimize_ad:"minimize"===e.postSmtpAdPosition}),methods:{addLineBreak:e=>e.replace(/\r\n/g,"
        "),minimizeAd(){this.minimize_ad=!this.minimize_ad;var e=this.minimize_ad?"minimize":"maximize";axios.post("minimize-maximize-ad",{minimize_maximize:e}).then(e=>{})}},computed:{concatenate_bcfm_class(){return{bcfm:this.is_bcfm,"pro-features":!0}}},mounted(){this.is_bcfm="1"===this.is_bcfm,this.click_link=this.is_bcfm?"https://postmansmtp.com/cyber-monday-sale?utm_source=plugin&utm_medium=section_name&utm_campaign=BFCM&utm_id=BFCM_2024":"https://postmansmtp.com/pricing/?utm_source=plugin&utm_medium=dashboard_pro_banner&utm_campaign=plugin"}},_n=(0,c.A)(vn,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-img"),l=(0,o.resolveComponent)("post-smtp-button");return(0,o.openBlock)(),(0,o.createElementBlock)("div",{class:(0,o.normalizeClass)(i.concatenate_bcfm_class),style:(0,o.normalizeStyle)(e.minimize_ad?"height: 85px;":"")},[(0,o.createElementVNode)("div",{class:"container",style:(0,o.normalizeStyle)(e.minimize_ad?"padding:0":"")},[(0,o.createElementVNode)("div",pn,[(0,o.createElementVNode)("h2",null,[(0,o.createVNode)(a,{style:{"margin-bottom":"-25px","margin-right":"-15px"},class:"d-inline-block",src:e.plugin_dir_url+"assets/images/pro-crown.png"},null,8,["src"]),(0,o.createTextVNode)(" "+(0,o.toDisplayString)(e.i18n.title),1)]),(0,o.createElementVNode)("p",null,(0,o.toDisplayString)(e.i18n.description),1)]),(0,o.createVNode)(o.Transition,{name:"fade","enter-active-class":"animated slideIn"},{default:(0,o.withCtx)(()=>[e.minimize_ad?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createElementBlock)("div",dn,[((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,null,(0,o.renderList)(e.features,t=>((0,o.openBlock)(),(0,o.createElementBlock)("div",{class:"feature-block",key:t.title},[t.has_container?((0,o.openBlock)(),(0,o.createElementBlock)("div",fn,[(0,o.createVNode)(a,{src:e.plugin_dir_url+"assets/images/"+t.img},null,8,["src"])])):((0,o.openBlock)(),(0,o.createElementBlock)("div",hn,[(0,o.createVNode)(a,{src:e.plugin_dir_url+"assets/images/"+t.img},null,8,["src"])])),(0,o.createElementVNode)("div",mn,[(0,o.createElementVNode)("p",{innerHTML:i.addLineBreak(t.title)},null,8,gn)])]))),128))]))]),_:1}),(0,o.createVNode)(o.Transition,{name:"fade","enter-active-class":"animated slideIn"},{default:(0,o.withCtx)(()=>[e.minimize_ad?(0,o.createCommentVNode)("v-if",!0):((0,o.openBlock)(),(0,o.createElementBlock)("div",yn,[(0,o.createVNode)(l,{type:"get-pro",href:e.click_link,target:"_blank"},{default:(0,o.withCtx)(()=>[(0,o.createTextVNode)((0,o.toDisplayString)(e.i18n.button)+" → ",1)]),_:1},8,["href"])]))]),_:1}),e.minimize_ad?((0,o.openBlock)(),(0,o.createElementBlock)("div",{key:0,class:"post-smtp-minimize-ad",onClick:t[0]||(t[0]=(...e)=>i.minimizeAd&&i.minimizeAd(...e))},[...t[2]||(t[2]=[(0,o.createElementVNode)("span",{class:"dashicons dashicons-arrow-down-alt2"},null,-1)])])):((0,o.openBlock)(),(0,o.createElementBlock)("div",{key:1,class:"post-smtp-minimize-ad",onClick:t[1]||(t[1]=(...e)=>i.minimizeAd&&i.minimizeAd(...e))},[...t[3]||(t[3]=[(0,o.createElementVNode)("span",{class:"dashicons dashicons-arrow-up-alt2"},null,-1)])]))],4)],6)}],["__scopeId","data-v-670574d9"]]),bn={class:"documentation"},Sn={class:"header"},wn={class:"float-left"},Cn={class:"float-right"},En={href:"https://postmansmtp.com/documentation/?utm_source=dashboard&utm_medium=documentation&utm_campaign=plugin"},kn=["src"],xn={key:0,class:"body"},Nn={class:"content"},Tn={name:"PostSMTPGuide",data:e=>({i18n:postSmtpNewDashboard.i18n.documentation,plugin_dir_url:e.$parent.plugin_dir_url,admin_url:e.$parent.admin_url,documentation:postSmtpNewDashboard.i18n.documentation.documentation,show_documentation:!0}),methods:{toggleTransition(e){e.preventDefault(),document.querySelector(".transform-image").classList.toggle("minimize"),this.show_documentation=!this.show_documentation}}},Vn=(0,c.A)(Tn,[["render",function(e,t,n,s,r,i){const a=(0,o.resolveComponent)("post-smtp-documentation");return(0,o.openBlock)(),(0,o.createElementBlock)("div",bn,[(0,o.createElementVNode)("div",Sn,[(0,o.createElementVNode)("div",wn,[(0,o.createElementVNode)("h3",null,(0,o.toDisplayString)(e.i18n.title),1)]),(0,o.createElementVNode)("div",Cn,[(0,o.createElementVNode)("a",En,(0,o.toDisplayString)(e.i18n.viewAll),1),(0,o.createElementVNode)("a",{href:"#",onClick:t[0]||(t[0]=e=>i.toggleTransition(e)),style:{"box-shadow":"none",border:"none",outline:"none"}},[(0,o.createElementVNode)("img",{class:"transform-image maximize",style:{"margin-left":"10px"},src:e.plugin_dir_url+"assets/images/maximize.png"},null,8,kn)])])]),(0,o.createVNode)(o.Transition,{name:"fade","enter-active-class":"animated slideIn"},{default:(0,o.withCtx)(()=>[e.show_documentation?((0,o.openBlock)(),(0,o.createElementBlock)("div",xn,[(0,o.createElementVNode)("div",Nn,[((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,null,(0,o.renderList)(e.documentation,t=>((0,o.openBlock)(),(0,o.createBlock)(a,{key:t.title,title:t.title,"docs-links":t.links,"view-more":t.view_more,"plugin-dir-url":e.plugin_dir_url,"admin-url":e.admin_url},null,8,["title","docs-links","view-more","plugin-dir-url","admin-url"]))),128))])])):(0,o.createCommentVNode)("v-if",!0)]),_:1})])}],["__scopeId","data-v-7fb6e671"]]),An={class:"documentation"},Bn={class:"doc-unstyled-list"},On={class:"clearfix"},Rn={style:{float:"left",width:"23px"}},Dn=["src"],Pn={style:{float:"right","text-align":"left",width:"calc( 100% - 23px )"}},Ln=["href"],In=["href"],Mn={name:"PostSMTPDocumentation",props:{title:{type:String,required:!0},docsLinks:{type:Array,required:!0},viewMore:{type:String,required:!0},pluginDirUrl:{type:String,required:!0},adminUrl:{type:String,required:!0}},data:e=>({plugin_dir_url:e.pluginDirUrl,admin_url:e.adminUrl,i18n:postSmtpNewDashboard.i18n.documentation})},Fn=(0,c.A)(Mn,[["render",function(e,t,n,s,r,i){return(0,o.openBlock)(),(0,o.createElementBlock)("div",An,[(0,o.createElementVNode)("h3",null,(0,o.toDisplayString)(n.title),1),(0,o.createElementVNode)("ul",Bn,[((0,o.openBlock)(!0),(0,o.createElementBlock)(o.Fragment,null,(0,o.renderList)(n.docsLinks,t=>((0,o.openBlock)(),(0,o.createElementBlock)("li",{key:t.title},[(0,o.createElementVNode)("div",On,[(0,o.createElementVNode)("div",Rn,[(0,o.createElementVNode)("img",{src:e.plugin_dir_url+"assets/images/docs.svg",style:{"margin-bottom":"-3px","margin-right":"9px"}},null,8,Dn)]),(0,o.createElementVNode)("div",Pn,[(0,o.createElementVNode)("a",{href:t.href,style:{"text-decoration":"none"}},(0,o.toDisplayString)(t.title),9,Ln)])])]))),128))]),(0,o.createElementVNode)("a",{class:"view-more-button",href:n.viewMore},(0,o.toDisplayString)(e.i18n.more)+" →",9,In)])}],["__scopeId","data-v-7ae3eba2"]]);let{Vue:$n,wp:jn,axios:Un}=window,{i18n:Hn}=jn,{createApp:qn}=$n;const zn=qn({setup:()=>({plugin_dir_url:postSmtpNewDashboard.plugin_dir_url,admin_url:postSmtpNewDashboard.admin_url}),data:()=>({}),watch:{},computed:{},methods:{},mounted(){}});zn.use({install(e,t){e.provide("i18n",t)}},Hn),zn.component("post-smtp-app-wrapper",u),zn.component("post-smtp-header",f),zn.component("post-smtp-img",g),zn.component("post-smtp-settings",b),zn.component("post-smtp-settings-menu",k),zn.component("post-smtp-notification-bar",U),zn.component("post-smtp-sidebar",ne),zn.component("post-smtp-widget",re),zn.component("post-smtp-ads",ve),zn.component("post-smtp-button",Se),zn.component("post-smtp-dashboard",xe),zn.component("post-smtp-days-selector",Te),zn.component("post-smtp-cards-container",Ge),zn.component("post-smtp-card",ot),zn.component("post-smtp-banners",pt),zn.component("post-smtp-notice",vt),zn.component("post-smtp-logs-section",Ft),zn.component("post-smtp-log-action-menu",un),zn.component("post-smtp-pro-features",_n),zn.component("post-smtp-guide",Vn),zn.component("post-smtp-documentation",Fn),zn.mount("#post-smtp-app"),window.$post_smtp__app=zn},262:(e,t)=>{"use strict";t.A=(e,t)=>{const n=e.__vccOpts||e;for(const[e,o]of t)n[e]=o;return n}},425:(e,t,n)=>{"use strict";n.r(t),n.d(t,{BaseTransition:()=>uo,BaseTransitionPropsValidators:()=>ao,Comment:()=>li,DeprecationTypes:()=>va,EffectScope:()=>he,ErrorCodes:()=>hn,ErrorTypeStrings:()=>da,Fragment:()=>ii,KeepAlive:()=>Ho,ReactiveEffect:()=>_e,Static:()=>ci,Suspense:()=>ei,Teleport:()=>eo,Text:()=>ai,TrackOpTypes:()=>on,Transition:()=>Aa,TransitionGroup:()=>kl,TriggerOpTypes:()=>sn,VueElement:()=>yl,assertNumber:()=>fn,callWithAsyncErrorHandling:()=>gn,callWithErrorHandling:()=>mn,camelize:()=>R,capitalize:()=>L,cloneVNode:()=>Ti,compatUtils:()=>ya,compile:()=>Qd,computed:()=>ra,createApp:()=>nc,createBlock:()=>_i,createCommentVNode:()=>Bi,createElementBlock:()=>vi,createElementVNode:()=>ki,createHydrationRenderer:()=>Er,createPropsRestProxy:()=>$s,createRenderer:()=>Cr,createSSRApp:()=>oc,createSlots:()=>vs,createStaticVNode:()=>Ai,createTextVNode:()=>Vi,createVNode:()=>xi,customRef:()=>Gt,defineAsyncComponent:()=>$o,defineComponent:()=>vo,defineCustomElement:()=>hl,defineEmits:()=>Ts,defineExpose:()=>Vs,defineModel:()=>Os,defineOptions:()=>As,defineProps:()=>Ns,defineSSRCustomElement:()=>ml,defineSlots:()=>Bs,devtools:()=>fa,effect:()=>Oe,effectScope:()=>me,getCurrentInstance:()=>ji,getCurrentScope:()=>ge,getCurrentWatcher:()=>cn,getTransitionRawChildren:()=>yo,guardReactiveProps:()=>Ni,h:()=>ia,handleError:()=>yn,hasInjectionContext:()=>rr,hydrate:()=>tc,hydrateOnIdle:()=>Po,hydrateOnInteraction:()=>Mo,hydrateOnMediaQuery:()=>Io,hydrateOnVisible:()=>Lo,initCustomFormatter:()=>aa,initDirectivesForSSR:()=>ac,inject:()=>sr,isMemoSame:()=>ca,isProxy:()=>Dt,isReactive:()=>Bt,isReadonly:()=>Ot,isRef:()=>Ft,isRuntimeOnly:()=>Yi,isShallow:()=>Rt,isVNode:()=>bi,markRaw:()=>Lt,mergeDefaults:()=>Ms,mergeModels:()=>Fs,mergeProps:()=>Pi,nextTick:()=>kn,normalizeClass:()=>X,normalizeProps:()=>Q,normalizeStyle:()=>W,onActivated:()=>zo,onBeforeMount:()=>Yo,onBeforeUnmount:()=>os,onBeforeUpdate:()=>ts,onDeactivated:()=>Wo,onErrorCaptured:()=>ls,onMounted:()=>es,onRenderTracked:()=>as,onRenderTriggered:()=>is,onScopeDispose:()=>ye,onServerPrefetch:()=>rs,onUnmounted:()=>ss,onUpdated:()=>ns,onWatcherCleanup:()=>un,openBlock:()=>di,popScopeId:()=>$n,provide:()=>or,proxyRefs:()=>Jt,pushScopeId:()=>Fn,queuePostFlushCb:()=>Tn,reactive:()=>xt,readonly:()=>Tt,ref:()=>$t,registerRuntimeCompiler:()=>Qi,render:()=>ec,renderList:()=>ys,renderSlot:()=>_s,resolveComponent:()=>ps,resolveDirective:()=>hs,resolveDynamicComponent:()=>fs,resolveFilter:()=>ga,resolveTransitionHooks:()=>fo,setBlockTracking:()=>gi,setDevtoolsHook:()=>ha,setTransitionHooks:()=>go,shallowReactive:()=>Nt,shallowReadonly:()=>Vt,shallowRef:()=>jt,ssrContextKey:()=>Or,ssrUtils:()=>ma,stop:()=>Re,toDisplayString:()=>le,toHandlerKey:()=>I,toHandlers:()=>Ss,toRaw:()=>Pt,toRef:()=>en,toRefs:()=>Xt,toValue:()=>Wt,transformVNodeArgs:()=>wi,triggerRef:()=>qt,unref:()=>zt,useAttrs:()=>Ps,useCssModule:()=>bl,useCssVars:()=>Za,useHost:()=>vl,useId:()=>_o,useModel:()=>jr,useSSRContext:()=>Rr,useShadowRoot:()=>_l,useSlots:()=>Ds,useTemplateRef:()=>So,useTransitionState:()=>ro,vModelCheckbox:()=>Dl,vModelDynamic:()=>jl,vModelRadio:()=>Ll,vModelSelect:()=>Il,vModelText:()=>Rl,vShow:()=>Wa,version:()=>ua,warn:()=>pa,watch:()=>Ir,watchEffect:()=>Dr,watchPostEffect:()=>Pr,watchSyncEffect:()=>Lr,withAsyncContext:()=>js,withCtx:()=>Un,withDefaults:()=>Rs,withDirectives:()=>Hn,withKeys:()=>Jl,withMemo:()=>la,withModifiers:()=>Wl,withScopeId:()=>jn});var o={};function s(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return e=>e in t}n.r(o),n.d(o,{BaseTransition:()=>uo,BaseTransitionPropsValidators:()=>ao,Comment:()=>li,DeprecationTypes:()=>va,EffectScope:()=>he,ErrorCodes:()=>hn,ErrorTypeStrings:()=>da,Fragment:()=>ii,KeepAlive:()=>Ho,ReactiveEffect:()=>_e,Static:()=>ci,Suspense:()=>ei,Teleport:()=>eo,Text:()=>ai,TrackOpTypes:()=>on,Transition:()=>Aa,TransitionGroup:()=>kl,TriggerOpTypes:()=>sn,VueElement:()=>yl,assertNumber:()=>fn,callWithAsyncErrorHandling:()=>gn,callWithErrorHandling:()=>mn,camelize:()=>R,capitalize:()=>L,cloneVNode:()=>Ti,compatUtils:()=>ya,computed:()=>ra,createApp:()=>nc,createBlock:()=>_i,createCommentVNode:()=>Bi,createElementBlock:()=>vi,createElementVNode:()=>ki,createHydrationRenderer:()=>Er,createPropsRestProxy:()=>$s,createRenderer:()=>Cr,createSSRApp:()=>oc,createSlots:()=>vs,createStaticVNode:()=>Ai,createTextVNode:()=>Vi,createVNode:()=>xi,customRef:()=>Gt,defineAsyncComponent:()=>$o,defineComponent:()=>vo,defineCustomElement:()=>hl,defineEmits:()=>Ts,defineExpose:()=>Vs,defineModel:()=>Os,defineOptions:()=>As,defineProps:()=>Ns,defineSSRCustomElement:()=>ml,defineSlots:()=>Bs,devtools:()=>fa,effect:()=>Oe,effectScope:()=>me,getCurrentInstance:()=>ji,getCurrentScope:()=>ge,getCurrentWatcher:()=>cn,getTransitionRawChildren:()=>yo,guardReactiveProps:()=>Ni,h:()=>ia,handleError:()=>yn,hasInjectionContext:()=>rr,hydrate:()=>tc,hydrateOnIdle:()=>Po,hydrateOnInteraction:()=>Mo,hydrateOnMediaQuery:()=>Io,hydrateOnVisible:()=>Lo,initCustomFormatter:()=>aa,initDirectivesForSSR:()=>ac,inject:()=>sr,isMemoSame:()=>ca,isProxy:()=>Dt,isReactive:()=>Bt,isReadonly:()=>Ot,isRef:()=>Ft,isRuntimeOnly:()=>Yi,isShallow:()=>Rt,isVNode:()=>bi,markRaw:()=>Lt,mergeDefaults:()=>Ms,mergeModels:()=>Fs,mergeProps:()=>Pi,nextTick:()=>kn,normalizeClass:()=>X,normalizeProps:()=>Q,normalizeStyle:()=>W,onActivated:()=>zo,onBeforeMount:()=>Yo,onBeforeUnmount:()=>os,onBeforeUpdate:()=>ts,onDeactivated:()=>Wo,onErrorCaptured:()=>ls,onMounted:()=>es,onRenderTracked:()=>as,onRenderTriggered:()=>is,onScopeDispose:()=>ye,onServerPrefetch:()=>rs,onUnmounted:()=>ss,onUpdated:()=>ns,onWatcherCleanup:()=>un,openBlock:()=>di,popScopeId:()=>$n,provide:()=>or,proxyRefs:()=>Jt,pushScopeId:()=>Fn,queuePostFlushCb:()=>Tn,reactive:()=>xt,readonly:()=>Tt,ref:()=>$t,registerRuntimeCompiler:()=>Qi,render:()=>ec,renderList:()=>ys,renderSlot:()=>_s,resolveComponent:()=>ps,resolveDirective:()=>hs,resolveDynamicComponent:()=>fs,resolveFilter:()=>ga,resolveTransitionHooks:()=>fo,setBlockTracking:()=>gi,setDevtoolsHook:()=>ha,setTransitionHooks:()=>go,shallowReactive:()=>Nt,shallowReadonly:()=>Vt,shallowRef:()=>jt,ssrContextKey:()=>Or,ssrUtils:()=>ma,stop:()=>Re,toDisplayString:()=>le,toHandlerKey:()=>I,toHandlers:()=>Ss,toRaw:()=>Pt,toRef:()=>en,toRefs:()=>Xt,toValue:()=>Wt,transformVNodeArgs:()=>wi,triggerRef:()=>qt,unref:()=>zt,useAttrs:()=>Ps,useCssModule:()=>bl,useCssVars:()=>Za,useHost:()=>vl,useId:()=>_o,useModel:()=>jr,useSSRContext:()=>Rr,useShadowRoot:()=>_l,useSlots:()=>Ds,useTemplateRef:()=>So,useTransitionState:()=>ro,vModelCheckbox:()=>Dl,vModelDynamic:()=>jl,vModelRadio:()=>Ll,vModelSelect:()=>Il,vModelText:()=>Rl,vShow:()=>Wa,version:()=>ua,warn:()=>pa,watch:()=>Ir,watchEffect:()=>Dr,watchPostEffect:()=>Pr,watchSyncEffect:()=>Lr,withAsyncContext:()=>js,withCtx:()=>Un,withDefaults:()=>Rs,withDirectives:()=>Hn,withKeys:()=>Jl,withMemo:()=>la,withModifiers:()=>Wl,withScopeId:()=>jn});const r={},i=[],a=()=>{},l=()=>!1,c=e=>111===e.charCodeAt(0)&&110===e.charCodeAt(1)&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),u=e=>e.startsWith("onUpdate:"),p=Object.assign,d=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},f=Object.prototype.hasOwnProperty,h=(e,t)=>f.call(e,t),m=Array.isArray,g=e=>"[object Map]"===k(e),y=e=>"[object Set]"===k(e),v=e=>"[object Date]"===k(e),_=e=>"function"==typeof e,b=e=>"string"==typeof e,S=e=>"symbol"==typeof e,w=e=>null!==e&&"object"==typeof e,C=e=>(w(e)||_(e))&&_(e.then)&&_(e.catch),E=Object.prototype.toString,k=e=>E.call(e),x=e=>k(e).slice(8,-1),N=e=>"[object Object]"===k(e),T=e=>b(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,V=s(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),A=s("bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo"),B=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},O=/-\w/g,R=B(e=>e.replace(O,e=>e.slice(1).toUpperCase())),D=/\B([A-Z])/g,P=B(e=>e.replace(D,"-$1").toLowerCase()),L=B(e=>e.charAt(0).toUpperCase()+e.slice(1)),I=B(e=>e?`on${L(e)}`:""),M=(e,t)=>!Object.is(e,t),F=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:o,value:n})},j=e=>{const t=parseFloat(e);return isNaN(t)?e:t},U=e=>{const t=b(e)?Number(e):NaN;return isNaN(t)?e:t};let H;const q=()=>H||(H="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==n.g?n.g:{}),z=s("Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error,Symbol");function W(e){if(m(e)){const t={};for(let n=0;n{if(e){const n=e.split(J);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function X(e){let t="";if(b(e))t=e;else if(m(e))for(let n=0;nre(e,t))}const ae=e=>!(!e||!0!==e.__v_isRef),le=e=>b(e)?e:null==e?"":m(e)||w(e)&&(e.toString===E||!_(e.toString))?ae(e)?le(e.value):JSON.stringify(e,ce,2):String(e),ce=(e,t)=>ae(t)?ce(e,t.value):g(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((e,[t,n],o)=>(e[ue(t,o)+" =>"]=n,e),{})}:y(t)?{[`Set(${t.size})`]:[...t.values()].map(e=>ue(e))}:S(t)?ue(t):!w(t)||m(t)||N(t)?t:String(t),ue=(e,t="")=>{var n;return S(e)?`Symbol(${null!=(n=e.description)?n:t})`:e};function pe(e){return null==e?"initial":"string"==typeof e?""===e?" ":e:("number"==typeof e&&Number.isFinite(e),String(e))}let de,fe;class he{constructor(e=!1){this.detached=e,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=de,!e&&de&&(this.index=(de.scopes||(de.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){let e,t;if(this._isPaused=!0,this.scopes)for(e=0,t=this.scopes.length;e0&&0===--this._on&&(de=this.prevScope,this.prevScope=void 0)}stop(e){if(this._active){let t,n;for(this._active=!1,t=0,n=this.effects.length;t0)return;if(Se){let e=Se;for(Se=void 0;e;){const t=e.next;e.next=void 0,e.flags&=-9,e=t}}let e;for(;be;){let t=be;for(be=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,1&t.flags)try{t.trigger()}catch(t){e||(e=t)}t=n}}if(e)throw e}function xe(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Ne(e){let t,n=e.depsTail,o=n;for(;o;){const e=o.prevDep;-1===o.version?(o===n&&(n=e),Ae(o),Be(o)):t=o,o.dep.activeLink=o.prevActiveLink,o.prevActiveLink=void 0,o=e}e.deps=t,e.depsTail=n}function Te(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(Ve(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function Ve(e){if(4&e.flags&&!(16&e.flags))return;if(e.flags&=-17,e.globalVersion===Fe)return;if(e.globalVersion=Fe,!e.isSSR&&128&e.flags&&(!e.deps&&!e._dirty||!Te(e)))return;e.flags|=2;const t=e.dep,n=fe,o=De;fe=e,De=!0;try{xe(e);const n=e.fn(e._value);(0===t.version||M(n,e._value))&&(e.flags|=128,e._value=n,t.version++)}catch(e){throw t.version++,e}finally{fe=n,De=o,Ne(e),e.flags&=-3}}function Ae(e,t=!1){const{dep:n,prevSub:o,nextSub:s}=e;if(o&&(o.nextSub=s,e.prevSub=void 0),s&&(s.prevSub=o,e.nextSub=void 0),n.subs===e&&(n.subs=o,!o&&n.computed)){n.computed.flags&=-5;for(let e=n.computed.deps;e;e=e.nextDep)Ae(e,!0)}t||--n.sc||!n.map||n.map.delete(n.key)}function Be(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}function Oe(e,t){e.effect instanceof _e&&(e=e.effect.fn);const n=new _e(e);t&&p(n,t);try{n.run()}catch(e){throw n.stop(),e}const o=n.run.bind(n);return o.effect=n,o}function Re(e){e.effect.stop()}let De=!0;const Pe=[];function Le(){Pe.push(De),De=!1}function Ie(){const e=Pe.pop();De=void 0===e||e}function Me(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const e=fe;fe=void 0;try{t()}finally{fe=e}}}let Fe=0;class $e{constructor(e,t){this.sub=e,this.dep=t,this.version=t.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class je{constructor(e){this.computed=e,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(e){if(!fe||!De||fe===this.computed)return;let t=this.activeLink;if(void 0===t||t.sub!==fe)t=this.activeLink=new $e(fe,this),fe.deps?(t.prevDep=fe.depsTail,fe.depsTail.nextDep=t,fe.depsTail=t):fe.deps=fe.depsTail=t,Ue(t);else if(-1===t.version&&(t.version=this.version,t.nextDep)){const e=t.nextDep;e.prevDep=t.prevDep,t.prevDep&&(t.prevDep.nextDep=e),t.prevDep=fe.depsTail,t.nextDep=void 0,fe.depsTail.nextDep=t,fe.depsTail=t,fe.deps===t&&(fe.deps=e)}return t}trigger(e){this.version++,Fe++,this.notify(e)}notify(e){Ee();try{for(let e=this.subs;e;e=e.prevSub)e.sub.notify()&&e.sub.dep.notify()}finally{ke()}}}function Ue(e){if(e.dep.sc++,4&e.sub.flags){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let e=t.deps;e;e=e.nextDep)Ue(e)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const He=new WeakMap,qe=Symbol(""),ze=Symbol(""),We=Symbol("");function Ke(e,t,n){if(De&&fe){let t=He.get(e);t||He.set(e,t=new Map);let o=t.get(n);o||(t.set(n,o=new je),o.map=t,o.key=n),o.track()}}function Je(e,t,n,o,s,r){const i=He.get(e);if(!i)return void Fe++;const a=e=>{e&&e.trigger()};if(Ee(),"clear"===t)i.forEach(a);else{const s=m(e),r=s&&T(n);if(s&&"length"===n){const e=Number(o);i.forEach((t,n)=>{("length"===n||n===We||!S(n)&&n>=e)&&a(t)})}else switch((void 0!==n||i.has(void 0))&&a(i.get(n)),r&&a(i.get(We)),t){case"add":s?r&&a(i.get("length")):(a(i.get(qe)),g(e)&&a(i.get(ze)));break;case"delete":s||(a(i.get(qe)),g(e)&&a(i.get(ze)));break;case"set":g(e)&&a(i.get(qe))}}ke()}function Ze(e){const t=Pt(e);return t===e?t:(Ke(t,0,We),Rt(e)?t:t.map(It))}function Ge(e){return Ke(e=Pt(e),0,We),e}const Xe={__proto__:null,[Symbol.iterator](){return Qe(this,Symbol.iterator,It)},concat(...e){return Ze(this).concat(...e.map(e=>m(e)?Ze(e):e))},entries(){return Qe(this,"entries",e=>(e[1]=It(e[1]),e))},every(e,t){return et(this,"every",e,t,void 0,arguments)},filter(e,t){return et(this,"filter",e,t,e=>e.map(It),arguments)},find(e,t){return et(this,"find",e,t,It,arguments)},findIndex(e,t){return et(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return et(this,"findLast",e,t,It,arguments)},findLastIndex(e,t){return et(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return et(this,"forEach",e,t,void 0,arguments)},includes(...e){return nt(this,"includes",e)},indexOf(...e){return nt(this,"indexOf",e)},join(e){return Ze(this).join(e)},lastIndexOf(...e){return nt(this,"lastIndexOf",e)},map(e,t){return et(this,"map",e,t,void 0,arguments)},pop(){return ot(this,"pop")},push(...e){return ot(this,"push",e)},reduce(e,...t){return tt(this,"reduce",e,t)},reduceRight(e,...t){return tt(this,"reduceRight",e,t)},shift(){return ot(this,"shift")},some(e,t){return et(this,"some",e,t,void 0,arguments)},splice(...e){return ot(this,"splice",e)},toReversed(){return Ze(this).toReversed()},toSorted(e){return Ze(this).toSorted(e)},toSpliced(...e){return Ze(this).toSpliced(...e)},unshift(...e){return ot(this,"unshift",e)},values(){return Qe(this,"values",It)}};function Qe(e,t,n){const o=Ge(e),s=o[t]();return o===e||Rt(e)||(s._next=s.next,s.next=()=>{const e=s._next();return e.done||(e.value=n(e.value)),e}),s}const Ye=Array.prototype;function et(e,t,n,o,s,r){const i=Ge(e),a=i!==e&&!Rt(e),l=i[t];if(l!==Ye[t]){const t=l.apply(e,r);return a?It(t):t}let c=n;i!==e&&(a?c=function(t,o){return n.call(this,It(t),o,e)}:n.length>2&&(c=function(t,o){return n.call(this,t,o,e)}));const u=l.call(i,c,o);return a&&s?s(u):u}function tt(e,t,n,o){const s=Ge(e);let r=n;return s!==e&&(Rt(e)?n.length>3&&(r=function(t,o,s){return n.call(this,t,o,s,e)}):r=function(t,o,s){return n.call(this,t,It(o),s,e)}),s[t](r,...o)}function nt(e,t,n){const o=Pt(e);Ke(o,0,We);const s=o[t](...n);return-1!==s&&!1!==s||!Dt(n[0])?s:(n[0]=Pt(n[0]),o[t](...n))}function ot(e,t,n=[]){Le(),Ee();const o=Pt(e)[t].apply(e,n);return ke(),Ie(),o}const st=s("__proto__,__v_isRef,__isVue"),rt=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>"arguments"!==e&&"caller"!==e).map(e=>Symbol[e]).filter(S));function it(e){S(e)||(e=String(e));const t=Pt(this);return Ke(t,0,e),t.hasOwnProperty(e)}class at{constructor(e=!1,t=!1){this._isReadonly=e,this._isShallow=t}get(e,t,n){if("__v_skip"===t)return e.__v_skip;const o=this._isReadonly,s=this._isShallow;if("__v_isReactive"===t)return!o;if("__v_isReadonly"===t)return o;if("__v_isShallow"===t)return s;if("__v_raw"===t)return n===(o?s?kt:Et:s?Ct:wt).get(e)||Object.getPrototypeOf(e)===Object.getPrototypeOf(n)?e:void 0;const r=m(e);if(!o){let e;if(r&&(e=Xe[t]))return e;if("hasOwnProperty"===t)return it}const i=Reflect.get(e,t,Ft(e)?e:n);if(S(t)?rt.has(t):st(t))return i;if(o||Ke(e,0,t),s)return i;if(Ft(i)){const e=r&&T(t)?i:i.value;return o&&w(e)?Tt(e):e}return w(i)?o?Tt(i):xt(i):i}}class lt extends at{constructor(e=!1){super(!1,e)}set(e,t,n,o){let s=e[t];if(!this._isShallow){const t=Ot(s);if(Rt(n)||Ot(n)||(s=Pt(s),n=Pt(n)),!m(e)&&Ft(s)&&!Ft(n))return t||(s.value=n),!0}const r=m(e)&&T(t)?Number(t)e,mt=e=>Reflect.getPrototypeOf(e);function gt(e){return function(...t){return"delete"!==e&&("clear"===e?void 0:this)}}function yt(e,t){const n=function(e,t){const n={get(n){const o=this.__v_raw,s=Pt(o),r=Pt(n);e||(M(n,r)&&Ke(s,0,n),Ke(s,0,r));const{has:i}=mt(s),a=t?ht:e?Mt:It;return i.call(s,n)?a(o.get(n)):i.call(s,r)?a(o.get(r)):void(o!==s&&o.get(n))},get size(){const t=this.__v_raw;return!e&&Ke(Pt(t),0,qe),t.size},has(t){const n=this.__v_raw,o=Pt(n),s=Pt(t);return e||(M(t,s)&&Ke(o,0,t),Ke(o,0,s)),t===s?n.has(t):n.has(t)||n.has(s)},forEach(n,o){const s=this,r=s.__v_raw,i=Pt(r),a=t?ht:e?Mt:It;return!e&&Ke(i,0,qe),r.forEach((e,t)=>n.call(o,a(e),a(t),s))}};return p(n,e?{add:gt("add"),set:gt("set"),delete:gt("delete"),clear:gt("clear")}:{add(e){t||Rt(e)||Ot(e)||(e=Pt(e));const n=Pt(this);return mt(n).has.call(n,e)||(n.add(e),Je(n,"add",e,e)),this},set(e,n){t||Rt(n)||Ot(n)||(n=Pt(n));const o=Pt(this),{has:s,get:r}=mt(o);let i=s.call(o,e);i||(e=Pt(e),i=s.call(o,e));const a=r.call(o,e);return o.set(e,n),i?M(n,a)&&Je(o,"set",e,n):Je(o,"add",e,n),this},delete(e){const t=Pt(this),{has:n,get:o}=mt(t);let s=n.call(t,e);s||(e=Pt(e),s=n.call(t,e)),o&&o.call(t,e);const r=t.delete(e);return s&&Je(t,"delete",e,void 0),r},clear(){const e=Pt(this),t=0!==e.size,n=e.clear();return t&&Je(e,"clear",void 0,void 0),n}}),["keys","values","entries",Symbol.iterator].forEach(o=>{n[o]=function(e,t,n){return function(...o){const s=this.__v_raw,r=Pt(s),i=g(r),a="entries"===e||e===Symbol.iterator&&i,l="keys"===e&&i,c=s[e](...o),u=n?ht:t?Mt:It;return!t&&Ke(r,0,l?ze:qe),{next(){const{value:e,done:t}=c.next();return t?{value:e,done:t}:{value:a?[u(e[0]),u(e[1])]:u(e),done:t}},[Symbol.iterator](){return this}}}}(o,e,t)}),n}(e,t);return(t,o,s)=>"__v_isReactive"===o?!e:"__v_isReadonly"===o?e:"__v_raw"===o?t:Reflect.get(h(n,o)&&o in t?n:t,o,s)}const vt={get:yt(!1,!1)},_t={get:yt(!1,!0)},bt={get:yt(!0,!1)},St={get:yt(!0,!0)},wt=new WeakMap,Ct=new WeakMap,Et=new WeakMap,kt=new WeakMap;function xt(e){return Ot(e)?e:At(e,!1,ut,vt,wt)}function Nt(e){return At(e,!1,dt,_t,Ct)}function Tt(e){return At(e,!0,pt,bt,Et)}function Vt(e){return At(e,!0,ft,St,kt)}function At(e,t,n,o,s){if(!w(e))return e;if(e.__v_raw&&(!t||!e.__v_isReactive))return e;const r=(i=e).__v_skip||!Object.isExtensible(i)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}(x(i));var i;if(0===r)return e;const a=s.get(e);if(a)return a;const l=new Proxy(e,2===r?o:n);return s.set(e,l),l}function Bt(e){return Ot(e)?Bt(e.__v_raw):!(!e||!e.__v_isReactive)}function Ot(e){return!(!e||!e.__v_isReadonly)}function Rt(e){return!(!e||!e.__v_isShallow)}function Dt(e){return!!e&&!!e.__v_raw}function Pt(e){const t=e&&e.__v_raw;return t?Pt(t):e}function Lt(e){return!h(e,"__v_skip")&&Object.isExtensible(e)&&$(e,"__v_skip",!0),e}const It=e=>w(e)?xt(e):e,Mt=e=>w(e)?Tt(e):e;function Ft(e){return!!e&&!0===e.__v_isRef}function $t(e){return Ut(e,!1)}function jt(e){return Ut(e,!0)}function Ut(e,t){return Ft(e)?e:new Ht(e,t)}class Ht{constructor(e,t){this.dep=new je,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=t?e:Pt(e),this._value=t?e:It(e),this.__v_isShallow=t}get value(){return this.dep.track(),this._value}set value(e){const t=this._rawValue,n=this.__v_isShallow||Rt(e)||Ot(e);e=n?e:Pt(e),M(e,t)&&(this._rawValue=e,this._value=n?e:It(e),this.dep.trigger())}}function qt(e){e.dep&&e.dep.trigger()}function zt(e){return Ft(e)?e.value:e}function Wt(e){return _(e)?e():zt(e)}const Kt={get:(e,t,n)=>"__v_raw"===t?e:zt(Reflect.get(e,t,n)),set:(e,t,n,o)=>{const s=e[t];return Ft(s)&&!Ft(n)?(s.value=n,!0):Reflect.set(e,t,n,o)}};function Jt(e){return Bt(e)?e:new Proxy(e,Kt)}class Zt{constructor(e){this.__v_isRef=!0,this._value=void 0;const t=this.dep=new je,{get:n,set:o}=e(t.track.bind(t),t.trigger.bind(t));this._get=n,this._set=o}get value(){return this._value=this._get()}set value(e){this._set(e)}}function Gt(e){return new Zt(e)}function Xt(e){const t=m(e)?new Array(e.length):{};for(const n in e)t[n]=tn(e,n);return t}class Qt{constructor(e,t,n){this._object=e,this._key=t,this._defaultValue=n,this.__v_isRef=!0,this._value=void 0}get value(){const e=this._object[this._key];return this._value=void 0===e?this._defaultValue:e}set value(e){this._object[this._key]=e}get dep(){return function(e,t){const n=He.get(e);return n&&n.get(t)}(Pt(this._object),this._key)}}class Yt{constructor(e){this._getter=e,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function en(e,t,n){return Ft(e)?e:_(e)?new Yt(e):w(e)&&arguments.length>1?tn(e,t,n):$t(e)}function tn(e,t,n){const o=e[t];return Ft(o)?o:new Qt(e,t,n)}class nn{constructor(e,t,n){this.fn=e,this.setter=t,this._value=void 0,this.dep=new je(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Fe-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!t,this.isSSR=n}notify(){if(this.flags|=16,!(8&this.flags||fe===this))return Ce(this,!0),!0}get value(){const e=this.dep.track();return Ve(this),e&&(e.version=this.dep.version),this._value}set value(e){this.setter&&this.setter(e)}}const on={GET:"get",HAS:"has",ITERATE:"iterate"},sn={SET:"set",ADD:"add",DELETE:"delete",CLEAR:"clear"},rn={},an=new WeakMap;let ln;function cn(){return ln}function un(e,t=!1,n=ln){if(n){let t=an.get(n);t||an.set(n,t=[]),t.push(e)}}function pn(e,t=1/0,n){if(t<=0||!w(e)||e.__v_skip)return e;if(((n=n||new Map).get(e)||0)>=t)return e;if(n.set(e,t),t--,Ft(e))pn(e.value,t,n);else if(m(e))for(let o=0;o{pn(e,t,n)});else if(N(e)){for(const o in e)pn(e[o],t,n);for(const o of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,o)&&pn(e[o],t,n)}return e}const dn=[];function fn(e,t){}const hn={SETUP_FUNCTION:0,0:"SETUP_FUNCTION",RENDER_FUNCTION:1,1:"RENDER_FUNCTION",NATIVE_EVENT_HANDLER:5,5:"NATIVE_EVENT_HANDLER",COMPONENT_EVENT_HANDLER:6,6:"COMPONENT_EVENT_HANDLER",VNODE_HOOK:7,7:"VNODE_HOOK",DIRECTIVE_HOOK:8,8:"DIRECTIVE_HOOK",TRANSITION_HOOK:9,9:"TRANSITION_HOOK",APP_ERROR_HANDLER:10,10:"APP_ERROR_HANDLER",APP_WARN_HANDLER:11,11:"APP_WARN_HANDLER",FUNCTION_REF:12,12:"FUNCTION_REF",ASYNC_COMPONENT_LOADER:13,13:"ASYNC_COMPONENT_LOADER",SCHEDULER:14,14:"SCHEDULER",COMPONENT_UPDATE:15,15:"COMPONENT_UPDATE",APP_UNMOUNT_CLEANUP:16,16:"APP_UNMOUNT_CLEANUP"};function mn(e,t,n,o){try{return o?e(...o):e()}catch(e){yn(e,t,n)}}function gn(e,t,n,o){if(_(e)){const s=mn(e,t,n,o);return s&&C(s)&&s.catch(e=>{yn(e,t,n)}),s}if(m(e)){const s=[];for(let r=0;r=Bn(n)?vn.push(e):vn.splice(function(e){let t=_n+1,n=vn.length;for(;t>>1,s=vn[o],r=Bn(s);rBn(e)-Bn(t));if(bn.length=0,Sn)return void Sn.push(...e);for(Sn=e,wn=0;wnnull==e.id?2&e.flags?-1:1/0:e.id;function On(e){try{for(_n=0;_nUn;function Un(e,t=Ln,n){if(!t)return e;if(e._n)return e;const o=(...n)=>{o._d&&gi(-1);const s=Mn(t);let r;try{r=e(...n)}finally{Mn(s),o._d&&gi(1)}return r};return o._n=!0,o._c=!0,o._d=!0,o}function Hn(e,t){if(null===Ln)return e;const n=oa(Ln),o=e.dirs||(e.dirs=[]);for(let e=0;ee.__isTeleport,Kn=e=>e&&(e.disabled||""===e.disabled),Jn=e=>e&&(e.defer||""===e.defer),Zn=e=>"undefined"!=typeof SVGElement&&e instanceof SVGElement,Gn=e=>"function"==typeof MathMLElement&&e instanceof MathMLElement,Xn=(e,t)=>{const n=e&&e.to;return b(n)?t?t(n):null:n},Qn={name:"Teleport",__isTeleport:!0,process(e,t,n,o,s,r,i,a,l,c){const{mc:u,pc:p,pbc:d,o:{insert:f,querySelector:h,createText:m,createComment:g}}=c,y=Kn(t.props);let{shapeFlag:v,children:_,dynamicChildren:b}=t;if(null==e){const e=t.el=m(""),c=t.anchor=m("");f(e,n,o),f(c,n,o);const p=(e,t)=>{16&v&&u(_,e,t,s,r,i,a,l)},d=()=>{const e=t.target=Xn(t.props,h),n=no(e,t,m,f);e&&("svg"!==i&&Zn(e)?i="svg":"mathml"!==i&&Gn(e)&&(i="mathml"),s&&s.isCE&&(s.ce._teleportTargets||(s.ce._teleportTargets=new Set)).add(e),y||(p(e,n),to(t,!1)))};y&&(p(n,c),to(t,!0)),Jn(t.props)?(t.el.__isMounted=!1,wr(()=>{d(),delete t.el.__isMounted},r)):d()}else{if(Jn(t.props)&&!1===e.el.__isMounted)return void wr(()=>{Qn.process(e,t,n,o,s,r,i,a,l,c)},r);t.el=e.el,t.targetStart=e.targetStart;const u=t.anchor=e.anchor,f=t.target=e.target,m=t.targetAnchor=e.targetAnchor,g=Kn(e.props),v=g?n:f,_=g?u:m;if("svg"===i||Zn(f)?i="svg":("mathml"===i||Gn(f))&&(i="mathml"),b?(d(e.dynamicChildren,b,v,s,r,i,a),Vr(e,t,!0)):l||p(e,t,v,_,s,r,i,a,!1),y)g?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):Yn(t,n,u,c,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const e=t.target=Xn(t.props,h);e&&Yn(t,e,null,c,0)}else g&&Yn(t,f,m,c,1);to(t,y)}},remove(e,t,n,{um:o,o:{remove:s}},r){const{shapeFlag:i,children:a,anchor:l,targetStart:c,targetAnchor:u,target:p,props:d}=e;if(p&&(s(c),s(u)),r&&s(l),16&i){const e=r||!Kn(d);for(let s=0;s{e.isMounted=!0}),os(()=>{e.isUnmounting=!0}),e}const io=[Function,Array],ao={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:io,onEnter:io,onAfterEnter:io,onEnterCancelled:io,onBeforeLeave:io,onLeave:io,onAfterLeave:io,onLeaveCancelled:io,onBeforeAppear:io,onAppear:io,onAfterAppear:io,onAppearCancelled:io},lo=e=>{const t=e.subTree;return t.component?lo(t.component):t};function co(e){let t=e[0];if(e.length>1){let n=!1;for(const o of e)if(o.type!==li){t=o,n=!0;break}}return t}const uo={name:"BaseTransition",props:ao,setup(e,{slots:t}){const n=ji(),o=ro();return()=>{const s=t.default&&yo(t.default(),!0);if(!s||!s.length)return;const r=co(s),i=Pt(e),{mode:a}=i;if(o.isLeaving)return ho(r);const l=mo(r);if(!l)return ho(r);let c=fo(l,i,o,n,e=>c=e);l.type!==li&&go(l,c);let u=n.subTree&&mo(n.subTree);if(u&&u.type!==li&&!Si(u,l)&&lo(n).type!==li){let e=fo(u,i,o,n);if(go(u,e),"out-in"===a&&l.type!==li)return o.isLeaving=!0,e.afterLeave=()=>{o.isLeaving=!1,8&n.job.flags||n.update(),delete e.afterLeave,u=void 0},ho(r);"in-out"===a&&l.type!==li?e.delayLeave=(e,t,n)=>{po(o,u)[String(u.key)]=u,e[oo]=()=>{t(),e[oo]=void 0,delete c.delayedLeave,u=void 0},c.delayedLeave=()=>{n(),delete c.delayedLeave,u=void 0}}:u=void 0}else u&&(u=void 0);return r}}};function po(e,t){const{leavingVNodes:n}=e;let o=n.get(t.type);return o||(o=Object.create(null),n.set(t.type,o)),o}function fo(e,t,n,o,s){const{appear:r,mode:i,persisted:a=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:u,onEnterCancelled:p,onBeforeLeave:d,onLeave:f,onAfterLeave:h,onLeaveCancelled:g,onBeforeAppear:y,onAppear:v,onAfterAppear:_,onAppearCancelled:b}=t,S=String(e.key),w=po(n,e),C=(e,t)=>{e&&gn(e,o,9,t)},E=(e,t)=>{const n=t[1];C(e,t),m(e)?e.every(e=>e.length<=1)&&n():e.length<=1&&n()},k={mode:i,persisted:a,beforeEnter(t){let o=l;if(!n.isMounted){if(!r)return;o=y||l}t[oo]&&t[oo](!0);const s=w[S];s&&Si(e,s)&&s.el[oo]&&s.el[oo](),C(o,[t])},enter(e){let t=c,o=u,s=p;if(!n.isMounted){if(!r)return;t=v||c,o=_||u,s=b||p}let i=!1;const a=e[so]=t=>{i||(i=!0,C(t?s:o,[e]),k.delayedLeave&&k.delayedLeave(),e[so]=void 0)};t?E(t,[e,a]):a()},leave(t,o){const s=String(e.key);if(t[so]&&t[so](!0),n.isUnmounting)return o();C(d,[t]);let r=!1;const i=t[oo]=n=>{r||(r=!0,o(),C(n?g:h,[t]),t[oo]=void 0,w[s]===e&&delete w[s])};w[s]=e,f?E(f,[t,i]):i()},clone(e){const r=fo(e,t,n,o,s);return s&&s(r),r}};return k}function ho(e){if(Uo(e))return(e=Ti(e)).children=null,e}function mo(e){if(!Uo(e))return Wn(e.type)&&e.children?co(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(16&t)return n[0];if(32&t&&_(n.default))return n.default()}}function go(e,t){6&e.shapeFlag&&e.component?(e.transition=t,go(e.component.subTree,t)):128&e.shapeFlag?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function yo(e,t=!1,n){let o=[],s=0;for(let r=0;r1)for(let e=0;ep({name:e.name},t,{setup:e}))():e}function _o(){const e=ji();return e?(e.appContext.config.idPrefix||"v")+"-"+e.ids[0]+e.ids[1]++:""}function bo(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function So(e){const t=ji(),n=jt(null);if(t){const o=t.refs===r?t.refs={}:t.refs;Object.defineProperty(o,e,{enumerable:!0,get:()=>n.value,set:e=>n.value=e})}return n}const wo=new WeakMap;function Co(e,t,n,o,s=!1){if(m(e))return void e.forEach((e,r)=>Co(e,t&&(m(t)?t[r]:t),n,o,s));if(Fo(o)&&!s)return void(512&o.shapeFlag&&o.type.__asyncResolved&&o.component.subTree.component&&Co(e,t,n,o.component.subTree));const i=4&o.shapeFlag?oa(o.component):o.el,a=s?null:i,{i:c,r:u}=e,p=t&&t.r,f=c.refs===r?c.refs={}:c.refs,g=c.setupState,y=Pt(g),v=g===r?l:e=>h(y,e);if(null!=p&&p!==u)if(Eo(t),b(p))f[p]=null,v(p)&&(g[p]=null);else if(Ft(p)){p.value=null;const e=t;e.k&&(f[e.k]=null)}if(_(u))mn(u,c,12,[a,f]);else{const t=b(u),o=Ft(u);if(t||o){const r=()=>{if(e.f){const n=t?v(u)?g[u]:f[u]:u.value;if(s)m(n)&&d(n,i);else if(m(n))n.includes(i)||n.push(i);else if(t)f[u]=[i],v(u)&&(g[u]=f[u]);else{const t=[i];u.value=t,e.k&&(f[e.k]=t)}}else t?(f[u]=a,v(u)&&(g[u]=a)):o&&(u.value=a,e.k&&(f[e.k]=a))};if(a){const t=()=>{r(),wo.delete(e)};t.id=-1,wo.set(e,t),wr(t,n)}else Eo(e),r()}}}function Eo(e){const t=wo.get(e);t&&(t.flags|=8,wo.delete(e))}let ko=!1;const xo=()=>{ko||(console.error("Hydration completed but contains mismatches."),ko=!0)},No=e=>{if(1===e.nodeType)return(e=>e.namespaceURI.includes("svg")&&"foreignObject"!==e.tagName)(e)?"svg":(e=>e.namespaceURI.includes("MathML"))(e)?"mathml":void 0},To=e=>8===e.nodeType;function Vo(e){const{mt:t,p:n,o:{patchProp:o,createText:s,nextSibling:r,parentNode:i,remove:a,insert:l,createComment:u}}=e,p=(n,o,a,c,u,_=!1)=>{_=_||!!o.dynamicChildren;const b=To(n)&&"["===n.data,S=()=>m(n,o,a,c,u,b),{type:w,ref:C,shapeFlag:E,patchFlag:k}=o;let x=n.nodeType;o.el=n,-2===k&&(_=!1,o.dynamicChildren=null);let N=null;switch(w){case ai:3!==x?""===o.children?(l(o.el=s(""),i(n),n),N=n):N=S():(n.data!==o.children&&(xo(),n.data=o.children),N=r(n));break;case li:v(n)?(N=r(n),y(o.el=n.content.firstChild,n,a)):N=8!==x||b?S():r(n);break;case ci:if(b&&(x=(n=r(n)).nodeType),1===x||3===x){N=n;const e=!o.children.length;for(let t=0;t{i=i||!!t.dynamicChildren;const{type:l,props:u,patchFlag:p,shapeFlag:d,dirs:h,transition:m}=t,g="input"===l||"option"===l;if(g||-1!==p){h&&qn(t,null,n,"created");let l,_=!1;if(v(e)){_=Tr(null,m)&&n&&n.vnode.props&&n.vnode.props.appear;const o=e.content.firstChild;if(_){const e=o.getAttribute("class");e&&(o.$cls=e),m.beforeEnter(o)}y(o,e,n),t.el=e=o}if(16&d&&(!u||!u.innerHTML&&!u.textContent)){let o=f(e.firstChild,t,e,n,s,r,i);for(;o;){Oo(e,1)||xo();const t=o;o=o.nextSibling,a(t)}}else if(8&d){let n=t.children;"\n"!==n[0]||"PRE"!==e.tagName&&"TEXTAREA"!==e.tagName||(n=n.slice(1)),e.textContent!==n&&(Oo(e,0)||xo(),e.textContent=t.children)}if(u)if(g||!i||48&p){const t=e.tagName.includes("-");for(const s in u)(g&&(s.endsWith("value")||"indeterminate"===s)||c(s)&&!V(s)||"."===s[0]||t)&&o(e,s,null,u[s],void 0,n)}else if(u.onClick)o(e,"onClick",null,u.onClick,void 0,n);else if(4&p&&Bt(u.style))for(const e in u.style)u.style[e];(l=u&&u.onVnodeBeforeMount)&&Li(l,n,t),h&&qn(t,null,n,"beforeMount"),((l=u&&u.onVnodeMounted)||h||_)&&si(()=>{l&&Li(l,n,t),_&&m.enter(e),h&&qn(t,null,n,"mounted")},s)}return e.nextSibling},f=(e,t,o,i,a,c,u)=>{u=u||!!t.dynamicChildren;const d=t.children,f=d.length;for(let t=0;t{const{slotScopeIds:c}=t;c&&(s=s?s.concat(c):c);const p=i(e),d=f(r(e),t,p,n,o,s,a);return d&&To(d)&&"]"===d.data?r(t.anchor=d):(xo(),l(t.anchor=u("]"),p,d),d)},m=(e,t,o,s,l,c)=>{if(Oo(e.parentElement,1)||xo(),t.el=null,c){const t=g(e);for(;;){const n=r(e);if(!n||n===t)break;a(n)}}const u=r(e),p=i(e);return a(e),n(null,t,p,u,o,s,No(p),l),o&&(o.vnode.el=t.el,Xr(o,t.el)),u},g=(e,t="[",n="]")=>{let o=0;for(;e;)if((e=r(e))&&To(e)&&(e.data===t&&o++,e.data===n)){if(0===o)return r(e);o--}return e},y=(e,t,n)=>{const o=t.parentNode;o&&o.replaceChild(e,t);let s=n;for(;s;)s.vnode.el===t&&(s.vnode.el=s.subTree.el=e),s=s.parent},v=e=>1===e.nodeType&&"TEMPLATE"===e.tagName;return[(e,t)=>{if(!t.hasChildNodes())return n(null,e,t),An(),void(t._vnode=e);p(t.firstChild,e,null,null,null),An(),t._vnode=e},p]}const Ao="data-allow-mismatch",Bo={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function Oo(e,t){if(0===t||1===t)for(;e&&!e.hasAttribute(Ao);)e=e.parentElement;const n=e&&e.getAttribute(Ao);if(null==n)return!1;if(""===n)return!0;{const e=n.split(",");return!(0!==t||!e.includes("children"))||e.includes(Bo[t])}}const Ro=q().requestIdleCallback||(e=>setTimeout(e,1)),Do=q().cancelIdleCallback||(e=>clearTimeout(e)),Po=(e=1e4)=>t=>{const n=Ro(t,{timeout:e});return()=>Do(n)},Lo=e=>(t,n)=>{const o=new IntersectionObserver(e=>{for(const n of e)if(n.isIntersecting){o.disconnect(),t();break}},e);return n(e=>{if(e instanceof Element)return function(e){const{top:t,left:n,bottom:o,right:s}=e.getBoundingClientRect(),{innerHeight:r,innerWidth:i}=window;return(t>0&&t0&&o0&&n0&&so.disconnect()},Io=e=>t=>{if(e){const n=matchMedia(e);if(!n.matches)return n.addEventListener("change",t,{once:!0}),()=>n.removeEventListener("change",t);t()}},Mo=(e=[])=>(t,n)=>{b(e)&&(e=[e]);let o=!1;const s=e=>{o||(o=!0,r(),t(),e.target.dispatchEvent(new e.constructor(e.type,e)))},r=()=>{n(t=>{for(const n of e)t.removeEventListener(n,s)})};return n(t=>{for(const n of e)t.addEventListener(n,s,{once:!0})}),r},Fo=e=>!!e.type.__asyncLoader;function $o(e){_(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:o,delay:s=200,hydrate:r,timeout:i,suspensible:a=!0,onError:l}=e;let c,u=null,p=0;const d=()=>{let e;return u||(e=u=t().catch(e=>{if(e=e instanceof Error?e:new Error(String(e)),l)return new Promise((t,n)=>{l(e,()=>t((p++,u=null,d())),()=>n(e),p+1)});throw e}).then(t=>e!==u&&u?u:(t&&(t.__esModule||"Module"===t[Symbol.toStringTag])&&(t=t.default),c=t,t)))};return vo({name:"AsyncComponentWrapper",__asyncLoader:d,__asyncHydrate(e,t,n){let o=!1;(t.bu||(t.bu=[])).push(()=>o=!0);const s=()=>{o||n()},i=r?()=>{const n=r(s,t=>function(e,t){if(To(e)&&"["===e.data){let n=1,o=e.nextSibling;for(;o;){if(1===o.nodeType){if(!1===t(o))break}else if(To(o))if("]"===o.data){if(0===--n)break}else"["===o.data&&n++;o=o.nextSibling}}else t(e)}(e,t));n&&(t.bum||(t.bum=[])).push(n)}:s;c?i():d().then(()=>!t.isUnmounted&&i())},get __asyncResolved(){return c},setup(){const e=$i;if(bo(e),c)return()=>jo(c,e);const t=t=>{u=null,yn(t,e,13,!o)};if(a&&e.suspense||Zi)return d().then(t=>()=>jo(t,e)).catch(e=>(t(e),()=>o?xi(o,{error:e}):null));const r=$t(!1),l=$t(),p=$t(!!s);return s&&setTimeout(()=>{p.value=!1},s),null!=i&&setTimeout(()=>{if(!r.value&&!l.value){const e=new Error(`Async component timed out after ${i}ms.`);t(e),l.value=e}},i),d().then(()=>{r.value=!0,e.parent&&Uo(e.parent.vnode)&&e.parent.update()}).catch(e=>{t(e),l.value=e}),()=>r.value&&c?jo(c,e):l.value&&o?xi(o,{error:l.value}):n&&!p.value?xi(n):void 0}})}function jo(e,t){const{ref:n,props:o,children:s,ce:r}=t.vnode,i=xi(e,o,s);return i.ref=n,i.ce=r,delete t.vnode.ce,i}const Uo=e=>e.type.__isKeepAlive,Ho={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=ji(),o=n.ctx;if(!o.renderer)return()=>{const e=t.default&&t.default();return e&&1===e.length?e[0]:e};const s=new Map,r=new Set;let i=null;const a=n.suspense,{renderer:{p:l,m:c,um:u,o:{createElement:p}}}=o,d=p("div");function f(e){Zo(e),u(e,n,a,!0)}function h(e){s.forEach((t,n)=>{const o=sa(t.type);o&&!e(o)&&m(n)})}function m(e){const t=s.get(e);!t||i&&Si(t,i)?i&&Zo(i):f(t),s.delete(e),r.delete(e)}o.activate=(e,t,n,o,s)=>{const r=e.component;c(e,t,n,0,a),l(r.vnode,e,t,n,r,a,o,e.slotScopeIds,s),wr(()=>{r.isDeactivated=!1,r.a&&F(r.a);const t=e.props&&e.props.onVnodeMounted;t&&Li(t,r.parent,e)},a)},o.deactivate=e=>{const t=e.component;Br(t.m),Br(t.a),c(e,d,null,1,a),wr(()=>{t.da&&F(t.da);const n=e.props&&e.props.onVnodeUnmounted;n&&Li(n,t.parent,e),t.isDeactivated=!0},a)},Ir(()=>[e.include,e.exclude],([e,t])=>{e&&h(t=>qo(e,t)),t&&h(e=>!qo(t,e))},{flush:"post",deep:!0});let g=null;const y=()=>{null!=g&&(Qr(n.subTree.type)?wr(()=>{s.set(g,Go(n.subTree))},n.subTree.suspense):s.set(g,Go(n.subTree)))};return es(y),ns(y),os(()=>{s.forEach(e=>{const{subTree:t,suspense:o}=n,s=Go(t);if(e.type===s.type&&e.key===s.key){Zo(s);const e=s.component.da;return void(e&&wr(e,o))}f(e)})}),()=>{if(g=null,!t.default)return i=null;const n=t.default(),o=n[0];if(n.length>1)return i=null,n;if(!bi(o)||!(4&o.shapeFlag||128&o.shapeFlag))return i=null,o;let a=Go(o);if(a.type===li)return i=null,a;const l=a.type,c=sa(Fo(a)?a.type.__asyncResolved||{}:l),{include:u,exclude:p,max:d}=e;if(u&&(!c||!qo(u,c))||p&&c&&qo(p,c))return a.shapeFlag&=-257,i=a,o;const f=null==a.key?l:a.key,h=s.get(f);return a.el&&(a=Ti(a),128&o.shapeFlag&&(o.ssContent=a)),g=f,h?(a.el=h.el,a.component=h.component,a.transition&&go(a,a.transition),a.shapeFlag|=512,r.delete(f),r.add(f)):(r.add(f),d&&r.size>parseInt(d,10)&&m(r.values().next().value)),a.shapeFlag|=256,i=a,Qr(o.type)?o:a}}};function qo(e,t){return m(e)?e.some(e=>qo(e,t)):b(e)?e.split(",").includes(t):"[object RegExp]"===k(e)&&(e.lastIndex=0,e.test(t))}function zo(e,t){Ko(e,"a",t)}function Wo(e,t){Ko(e,"da",t)}function Ko(e,t,n=$i){const o=e.__wdc||(e.__wdc=()=>{let t=n;for(;t;){if(t.isDeactivated)return;t=t.parent}return e()});if(Xo(t,o,n),n){let e=n.parent;for(;e&&e.parent;)Uo(e.parent.vnode)&&Jo(o,t,n,e),e=e.parent}}function Jo(e,t,n,o){const s=Xo(t,e,o,!0);ss(()=>{d(o[t],s)},n)}function Zo(e){e.shapeFlag&=-257,e.shapeFlag&=-513}function Go(e){return 128&e.shapeFlag?e.ssContent:e}function Xo(e,t,n=$i,o=!1){if(n){const s=n[e]||(n[e]=[]),r=t.__weh||(t.__weh=(...o)=>{Le();const s=qi(n),r=gn(t,n,e,o);return s(),Ie(),r});return o?s.unshift(r):s.push(r),r}}const Qo=e=>(t,n=$i)=>{Zi&&"sp"!==e||Xo(e,(...e)=>t(...e),n)},Yo=Qo("bm"),es=Qo("m"),ts=Qo("bu"),ns=Qo("u"),os=Qo("bum"),ss=Qo("um"),rs=Qo("sp"),is=Qo("rtg"),as=Qo("rtc");function ls(e,t=$i){Xo("ec",e,t)}const cs="components",us="directives";function ps(e,t){return ms(cs,e,!0,t)||e}const ds=Symbol.for("v-ndc");function fs(e){return b(e)?ms(cs,e,!1)||e:e||ds}function hs(e){return ms(us,e)}function ms(e,t,n=!0,o=!1){const s=Ln||$i;if(s){const n=s.type;if(e===cs){const e=sa(n,!1);if(e&&(e===t||e===R(t)||e===L(R(t))))return n}const r=gs(s[e]||n[e],t)||gs(s.appContext[e],t);return!r&&o?n:r}}function gs(e,t){return e&&(e[t]||e[R(t)]||e[L(R(t))])}function ys(e,t,n,o){let s;const r=n&&n[o],i=m(e);if(i||b(e)){let n=!1,o=!1;i&&Bt(e)&&(n=!Rt(e),o=Ot(e),e=Ge(e)),s=new Array(e.length);for(let i=0,a=e.length;it(e,n,void 0,r&&r[n]));else{const n=Object.keys(e);s=new Array(n.length);for(let o=0,i=n.length;o{const t=o.fn(...e);return t&&(t.key=o.key),t}:o.fn)}return e}function _s(e,t,n={},o,s){if(Ln.ce||Ln.parent&&Fo(Ln.parent)&&Ln.parent.ce){const e=Object.keys(n).length>0;return"default"!==t&&(n.name=t),di(),_i(ii,null,[xi("slot",n,o&&o())],e?-2:64)}let r=e[t];r&&r._c&&(r._d=!1),di();const i=r&&bs(r(n)),a=n.key||i&&i.key,l=_i(ii,{key:(a&&!S(a)?a:`_${t}`)+(!i&&o?"_fb":"")},i||(o?o():[]),i&&1===e._?64:-2);return!s&&l.scopeId&&(l.slotScopeIds=[l.scopeId+"-s"]),r&&r._c&&(r._d=!0),l}function bs(e){return e.some(e=>!bi(e)||e.type!==li&&!(e.type===ii&&!bs(e.children)))?e:null}function Ss(e,t){const n={};for(const o in e)n[t&&/[A-Z]/.test(o)?`on:${o}`:I(o)]=e[o];return n}const ws=e=>e?Wi(e)?oa(e):ws(e.parent):null,Cs=p(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>ws(e.parent),$root:e=>ws(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>zs(e),$forceUpdate:e=>e.f||(e.f=()=>{xn(e.update)}),$nextTick:e=>e.n||(e.n=kn.bind(e.proxy)),$watch:e=>Fr.bind(e)}),Es=(e,t)=>e!==r&&!e.__isScriptSetup&&h(e,t),ks={get({_:e},t){if("__v_skip"===t)return!0;const{ctx:n,setupState:o,data:s,props:i,accessCache:a,type:l,appContext:c}=e;let u;if("$"!==t[0]){const l=a[t];if(void 0!==l)switch(l){case 1:return o[t];case 2:return s[t];case 4:return n[t];case 3:return i[t]}else{if(Es(o,t))return a[t]=1,o[t];if(s!==r&&h(s,t))return a[t]=2,s[t];if((u=e.propsOptions[0])&&h(u,t))return a[t]=3,i[t];if(n!==r&&h(n,t))return a[t]=4,n[t];Us&&(a[t]=0)}}const p=Cs[t];let d,f;return p?("$attrs"===t&&Ke(e.attrs,0,""),p(e)):(d=l.__cssModules)&&(d=d[t])?d:n!==r&&h(n,t)?(a[t]=4,n[t]):(f=c.config.globalProperties,h(f,t)?f[t]:void 0)},set({_:e},t,n){const{data:o,setupState:s,ctx:i}=e;return Es(s,t)?(s[t]=n,!0):o!==r&&h(o,t)?(o[t]=n,!0):!(h(e.props,t)||"$"===t[0]&&t.slice(1)in e||(i[t]=n,0))},has({_:{data:e,setupState:t,accessCache:n,ctx:o,appContext:s,propsOptions:i,type:a}},l){let c,u;return!!(n[l]||e!==r&&"$"!==l[0]&&h(e,l)||Es(t,l)||(c=i[0])&&h(c,l)||h(o,l)||h(Cs,l)||h(s.config.globalProperties,l)||(u=a.__cssModules)&&u[l])},defineProperty(e,t,n){return null!=n.get?e._.accessCache[t]=0:h(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}},xs=p({},ks,{get(e,t){if(t!==Symbol.unscopables)return ks.get(e,t,e)},has:(e,t)=>"_"!==t[0]&&!z(t)});function Ns(){return null}function Ts(){return null}function Vs(e){}function As(e){}function Bs(){return null}function Os(){}function Rs(e,t){return null}function Ds(){return Ls().slots}function Ps(){return Ls().attrs}function Ls(e){const t=ji();return t.setupContext||(t.setupContext=na(t))}function Is(e){return m(e)?e.reduce((e,t)=>(e[t]=null,e),{}):e}function Ms(e,t){const n=Is(e);for(const e in t){if(e.startsWith("__skip"))continue;let o=n[e];o?m(o)||_(o)?o=n[e]={type:o,default:t[e]}:o.default=t[e]:null===o&&(o=n[e]={default:t[e]}),o&&t[`__skip_${e}`]&&(o.skipFactory=!0)}return n}function Fs(e,t){return e&&t?m(e)&&m(t)?e.concat(t):p({},Is(e),Is(t)):e||t}function $s(e,t){const n={};for(const o in e)t.includes(o)||Object.defineProperty(n,o,{enumerable:!0,get:()=>e[o]});return n}function js(e){const t=ji();let n=e();return zi(),C(n)&&(n=n.catch(e=>{throw qi(t),e})),[n,()=>qi(t)]}let Us=!0;function Hs(e,t,n){gn(m(e)?e.map(e=>e.bind(t.proxy)):e.bind(t.proxy),t,n)}function qs(e,t,n,o){let s=o.includes(".")?$r(n,o):()=>n[o];if(b(e)){const n=t[e];_(n)&&Ir(s,n)}else if(_(e))Ir(s,e.bind(n));else if(w(e))if(m(e))e.forEach(e=>qs(e,t,n,o));else{const o=_(e.handler)?e.handler.bind(n):t[e.handler];_(o)&&Ir(s,o,e)}}function zs(e){const t=e.type,{mixins:n,extends:o}=t,{mixins:s,optionsCache:r,config:{optionMergeStrategies:i}}=e.appContext,a=r.get(t);let l;return a?l=a:s.length||n||o?(l={},s.length&&s.forEach(e=>Ws(l,e,i,!0)),Ws(l,t,i)):l=t,w(t)&&r.set(t,l),l}function Ws(e,t,n,o=!1){const{mixins:s,extends:r}=t;r&&Ws(e,r,n,!0),s&&s.forEach(t=>Ws(e,t,n,!0));for(const s in t)if(o&&"expose"===s);else{const o=Ks[s]||n&&n[s];e[s]=o?o(e[s],t[s]):t[s]}return e}const Ks={data:Js,props:Qs,emits:Qs,methods:Xs,computed:Xs,beforeCreate:Gs,created:Gs,beforeMount:Gs,mounted:Gs,beforeUpdate:Gs,updated:Gs,beforeDestroy:Gs,beforeUnmount:Gs,destroyed:Gs,unmounted:Gs,activated:Gs,deactivated:Gs,errorCaptured:Gs,serverPrefetch:Gs,components:Xs,directives:Xs,watch:function(e,t){if(!e)return t;if(!t)return e;const n=p(Object.create(null),e);for(const o in t)n[o]=Gs(e[o],t[o]);return n},provide:Js,inject:function(e,t){return Xs(Zs(e),Zs(t))}};function Js(e,t){return t?e?function(){return p(_(e)?e.call(this,this):e,_(t)?t.call(this,this):t)}:t:e}function Zs(e){if(m(e)){const t={};for(let n=0;n(r.has(e)||(e&&_(e.install)?(r.add(e),e.install(l,...t)):_(e)&&(r.add(e),e(l,...t))),l),mixin:e=>(s.mixins.includes(e)||s.mixins.push(e),l),component:(e,t)=>t?(s.components[e]=t,l):s.components[e],directive:(e,t)=>t?(s.directives[e]=t,l):s.directives[e],mount(r,i,c){if(!a){const u=l._ceVNode||xi(n,o);return u.appContext=s,!0===c?c="svg":!1===c&&(c=void 0),i&&t?t(u,r):e(u,r,c),a=!0,l._container=r,r.__vue_app__=l,oa(u.component)}},onUnmount(e){i.push(e)},unmount(){a&&(gn(i,l._instance,16),e(null,l._container),delete l._container.__vue_app__)},provide:(e,t)=>(s.provides[e]=t,l),runWithContext(e){const t=nr;nr=l;try{return e()}finally{nr=t}}};return l}}let nr=null;function or(e,t){if($i){let n=$i.provides;const o=$i.parent&&$i.parent.provides;o===n&&(n=$i.provides=Object.create(o)),n[e]=t}}function sr(e,t,n=!1){const o=ji();if(o||nr){let s=nr?nr._context.provides:o?null==o.parent||o.ce?o.vnode.appContext&&o.vnode.appContext.provides:o.parent.provides:void 0;if(s&&e in s)return s[e];if(arguments.length>1)return n&&_(t)?t.call(o&&o.proxy):t}}function rr(){return!(!ji()&&!nr)}const ir={},ar=()=>Object.create(ir),lr=e=>Object.getPrototypeOf(e)===ir;function cr(e,t,n,o){const[s,i]=e.propsOptions;let a,l=!1;if(t)for(let r in t){if(V(r))continue;const c=t[r];let u;s&&h(s,u=R(r))?i&&i.includes(u)?(a||(a={}))[u]=c:n[u]=c:Wr(e.emitsOptions,r)||r in o&&c===o[r]||(o[r]=c,l=!0)}if(i){const t=Pt(n),o=a||r;for(let r=0;r{u=!0;const[n,o]=dr(e,t,!0);p(l,n),o&&c.push(...o)};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}if(!a&&!u)return w(e)&&o.set(e,i),i;if(m(a))for(let e=0;e"_"===e||"_ctx"===e||"$stable"===e,mr=e=>m(e)?e.map(Oi):[Oi(e)],gr=(e,t,n)=>{if(t._n)return t;const o=Un((...e)=>mr(t(...e)),n);return o._c=!1,o},yr=(e,t,n)=>{const o=e._ctx;for(const n in e){if(hr(n))continue;const s=e[n];if(_(s))t[n]=gr(0,s,o);else if(null!=s){const e=mr(s);t[n]=()=>e}}},vr=(e,t)=>{const n=mr(t);e.slots.default=()=>n},_r=(e,t,n)=>{for(const o in t)!n&&hr(o)||(e[o]=t[o])},br=(e,t,n)=>{const o=e.slots=ar();if(32&e.vnode.shapeFlag){const e=t._;e?(_r(o,t,n),n&&$(o,"_",e,!0)):yr(t,o)}else t&&vr(e,t)},Sr=(e,t,n)=>{const{vnode:o,slots:s}=e;let i=!0,a=r;if(32&o.shapeFlag){const e=t._;e?n&&1===e?i=!1:_r(s,t,n):(i=!t.$stable,yr(t,s)),a=t}else t&&(vr(e,t),a={default:1});if(i)for(const e in s)hr(e)||null!=a[e]||delete s[e]},wr=si;function Cr(e){return kr(e)}function Er(e){return kr(e,Vo)}function kr(e,t){q().__VUE__=!0;const{insert:n,remove:o,patchProp:s,createElement:l,createText:c,createComment:u,setText:p,setElementText:d,parentNode:f,nextSibling:m,setScopeId:g=a,insertStaticContent:y}=e,v=(e,t,n,o=null,s=null,r=null,i=void 0,a=null,l=!!t.dynamicChildren)=>{if(e===t)return;e&&!Si(e,t)&&(o=Z(e),H(e,s,r,!0),e=null),-2===t.patchFlag&&(l=!1,t.dynamicChildren=null);const{type:c,ref:u,shapeFlag:p}=t;switch(c){case ai:_(e,t,n,o);break;case li:b(e,t,n,o);break;case ci:null==e&&S(t,n,o,i);break;case ii:A(e,t,n,o,s,r,i,a,l);break;default:1&p?w(e,t,n,o,s,r,i,a,l):6&p?B(e,t,n,o,s,r,i,a,l):(64&p||128&p)&&c.process(e,t,n,o,s,r,i,a,l,Q)}null!=u&&s?Co(u,e&&e.ref,r,t||e,!t):null==u&&e&&null!=e.ref&&Co(e.ref,null,r,e,!0)},_=(e,t,o,s)=>{if(null==e)n(t.el=c(t.children),o,s);else{const n=t.el=e.el;t.children!==e.children&&p(n,t.children)}},b=(e,t,o,s)=>{null==e?n(t.el=u(t.children||""),o,s):t.el=e.el},S=(e,t,n,o)=>{[e.el,e.anchor]=y(e.children,t,n,o,e.el,e.anchor)},w=(e,t,n,o,s,r,i,a,l)=>{"svg"===t.type?i="svg":"math"===t.type&&(i="mathml"),null==e?C(t,n,o,s,r,i,a,l):x(e,t,s,r,i,a,l)},C=(e,t,o,r,i,a,c,u)=>{let p,f;const{props:h,shapeFlag:m,transition:g,dirs:y}=e;if(p=e.el=l(e.type,a,h&&h.is,h),8&m?d(p,e.children):16&m&&k(e.children,p,null,r,i,xr(e,a),c,u),y&&qn(e,null,r,"created"),E(p,e,e.scopeId,c,r),h){for(const e in h)"value"===e||V(e)||s(p,e,null,h[e],a,r);"value"in h&&s(p,"value",null,h.value,a),(f=h.onVnodeBeforeMount)&&Li(f,r,e)}y&&qn(e,null,r,"beforeMount");const v=Tr(i,g);v&&g.beforeEnter(p),n(p,t,o),((f=h&&h.onVnodeMounted)||v||y)&&wr(()=>{f&&Li(f,r,e),v&&g.enter(p),y&&qn(e,null,r,"mounted")},i)},E=(e,t,n,o,s)=>{if(n&&g(e,n),o)for(let t=0;t{for(let c=l;c{const c=t.el=e.el;let{patchFlag:u,dynamicChildren:p,dirs:f}=t;u|=16&e.patchFlag;const h=e.props||r,m=t.props||r;let g;if(n&&Nr(n,!1),(g=m.onVnodeBeforeUpdate)&&Li(g,n,t,e),f&&qn(t,e,n,"beforeUpdate"),n&&Nr(n,!0),(h.innerHTML&&null==m.innerHTML||h.textContent&&null==m.textContent)&&d(c,""),p?N(e.dynamicChildren,p,c,n,o,xr(t,i),a):l||M(e,t,c,null,n,o,xr(t,i),a,!1),u>0){if(16&u)T(c,h,m,n,i);else if(2&u&&h.class!==m.class&&s(c,"class",null,m.class,i),4&u&&s(c,"style",h.style,m.style,i),8&u){const e=t.dynamicProps;for(let t=0;t{g&&Li(g,n,t,e),f&&qn(t,e,n,"updated")},o)},N=(e,t,n,o,s,r,i)=>{for(let a=0;a{if(t!==n){if(t!==r)for(const r in t)V(r)||r in n||s(e,r,t[r],null,i,o);for(const r in n){if(V(r))continue;const a=n[r],l=t[r];a!==l&&"value"!==r&&s(e,r,l,a,i,o)}"value"in n&&s(e,"value",t.value,n.value,i)}},A=(e,t,o,s,r,i,a,l,u)=>{const p=t.el=e?e.el:c(""),d=t.anchor=e?e.anchor:c("");let{patchFlag:f,dynamicChildren:h,slotScopeIds:m}=t;m&&(l=l?l.concat(m):m),null==e?(n(p,o,s),n(d,o,s),k(t.children||[],o,d,r,i,a,l,u)):f>0&&64&f&&h&&e.dynamicChildren?(N(e.dynamicChildren,h,o,r,i,a,l),(null!=t.key||r&&t===r.subTree)&&Vr(e,t,!0)):M(e,t,o,d,r,i,a,l,u)},B=(e,t,n,o,s,r,i,a,l)=>{t.slotScopeIds=a,null==e?512&t.shapeFlag?s.ctx.activate(t,n,o,i,l):O(t,n,o,s,r,i,l):D(e,t,l)},O=(e,t,n,o,s,r,i)=>{const a=e.component=Fi(e,o,s);if(Uo(e)&&(a.ctx.renderer=Q),Gi(a,!1,i),a.asyncDep){if(s&&s.registerDep(a,L,i),!e.el){const o=a.subTree=xi(li);b(null,o,t,n),e.placeholder=o.el}}else L(a,e,t,n,s,r,i)},D=(e,t,n)=>{const o=t.component=e.component;if(function(e,t,n){const{props:o,children:s,component:r}=e,{props:i,children:a,patchFlag:l}=t,c=r.emitsOptions;if(t.dirs||t.transition)return!0;if(!(n&&l>=0))return!(!s&&!a||a&&a.$stable)||o!==i&&(o?!i||Gr(o,i,c):!!i);if(1024&l)return!0;if(16&l)return o?Gr(o,i,c):!!i;if(8&l){const e=t.dynamicProps;for(let t=0;t{const a=()=>{if(e.isMounted){let{next:t,bu:n,u:o,parent:l,vnode:c}=e;{const n=Ar(e);if(n)return t&&(t.el=c.el,I(e,t,i)),void n.asyncDep.then(()=>{e.isUnmounted||a()})}let u,p=t;Nr(e,!1),t?(t.el=c.el,I(e,t,i)):t=c,n&&F(n),(u=t.props&&t.props.onVnodeBeforeUpdate)&&Li(u,l,t,c),Nr(e,!0);const d=Kr(e),h=e.subTree;e.subTree=d,v(h,d,f(h.el),Z(h),e,s,r),t.el=d.el,null===p&&Xr(e,d.el),o&&wr(o,s),(u=t.props&&t.props.onVnodeUpdated)&&wr(()=>Li(u,l,t,c),s)}else{let i;const{el:a,props:l}=t,{bm:c,m:u,parent:p,root:d,type:f}=e,h=Fo(t);if(Nr(e,!1),c&&F(c),!h&&(i=l&&l.onVnodeBeforeMount)&&Li(i,p,t),Nr(e,!0),a&&ee){const t=()=>{e.subTree=Kr(e),ee(a,e.subTree,e,s,null)};h&&f.__asyncHydrate?f.__asyncHydrate(a,e,t):t()}else{d.ce&&!1!==d.ce._def.shadowRoot&&d.ce._injectChildStyle(f);const i=e.subTree=Kr(e);v(null,i,n,o,e,s,r),t.el=i.el}if(u&&wr(u,s),!h&&(i=l&&l.onVnodeMounted)){const e=t;wr(()=>Li(i,p,e),s)}(256&t.shapeFlag||p&&Fo(p.vnode)&&256&p.vnode.shapeFlag)&&e.a&&wr(e.a,s),e.isMounted=!0,t=n=o=null}};e.scope.on();const l=e.effect=new _e(a);e.scope.off();const c=e.update=l.run.bind(l),u=e.job=l.runIfDirty.bind(l);u.i=e,u.id=e.uid,l.scheduler=()=>xn(u),Nr(e,!0),c()},I=(e,t,n)=>{t.component=e;const o=e.vnode.props;e.vnode=t,e.next=null,function(e,t,n,o){const{props:s,attrs:r,vnode:{patchFlag:i}}=e,a=Pt(s),[l]=e.propsOptions;let c=!1;if(!(o||i>0)||16&i){let o;cr(e,t,s,r)&&(c=!0);for(const r in a)t&&(h(t,r)||(o=P(r))!==r&&h(t,o))||(l?!n||void 0===n[r]&&void 0===n[o]||(s[r]=ur(l,a,r,void 0,e,!0)):delete s[r]);if(r!==a)for(const e in r)t&&h(t,e)||(delete r[e],c=!0)}else if(8&i){const n=e.vnode.dynamicProps;for(let o=0;o{const c=e&&e.children,u=e?e.shapeFlag:0,p=t.children,{patchFlag:f,shapeFlag:h}=t;if(f>0){if(128&f)return void j(c,p,n,o,s,r,i,a,l);if(256&f)return void $(c,p,n,o,s,r,i,a,l)}8&h?(16&u&&J(c,s,r),p!==c&&d(n,p)):16&u?16&h?j(c,p,n,o,s,r,i,a,l):J(c,s,r,!0):(8&u&&d(n,""),16&h&&k(p,n,o,s,r,i,a,l))},$=(e,t,n,o,s,r,a,l,c)=>{t=t||i;const u=(e=e||i).length,p=t.length,d=Math.min(u,p);let f;for(f=0;fp?J(e,s,r,!0,!1,d):k(t,n,o,s,r,a,l,c,d)},j=(e,t,n,o,s,r,a,l,c)=>{let u=0;const p=t.length;let d=e.length-1,f=p-1;for(;u<=d&&u<=f;){const o=e[u],i=t[u]=c?Ri(t[u]):Oi(t[u]);if(!Si(o,i))break;v(o,i,n,null,s,r,a,l,c),u++}for(;u<=d&&u<=f;){const o=e[d],i=t[f]=c?Ri(t[f]):Oi(t[f]);if(!Si(o,i))break;v(o,i,n,null,s,r,a,l,c),d--,f--}if(u>d){if(u<=f){const e=f+1,i=ef)for(;u<=d;)H(e[u],s,r,!0),u++;else{const h=u,m=u,g=new Map;for(u=m;u<=f;u++){const e=t[u]=c?Ri(t[u]):Oi(t[u]);null!=e.key&&g.set(e.key,u)}let y,_=0;const b=f-m+1;let S=!1,w=0;const C=new Array(b);for(u=0;u=b){H(o,s,r,!0);continue}let i;if(null!=o.key)i=g.get(o.key);else for(y=m;y<=f;y++)if(0===C[y-m]&&Si(o,t[y])){i=y;break}void 0===i?H(o,s,r,!0):(C[i-m]=u+1,i>=w?w=i:S=!0,v(o,t[i],n,null,s,r,a,l,c),_++)}const E=S?function(e){const t=e.slice(),n=[0];let o,s,r,i,a;const l=e.length;for(o=0;o>1,e[n[a]]0&&(t[o]=n[r-1]),n[r]=o)}}for(r=n.length,i=n[r-1];r-- >0;)n[r]=i,i=t[i];return n}(C):i;for(y=E.length-1,u=b-1;u>=0;u--){const e=m+u,i=t[e],d=t[e+1],f=e+1{const{el:a,type:l,transition:c,children:u,shapeFlag:p}=e;if(6&p)U(e.component.subTree,t,s,r);else if(128&p)e.suspense.move(t,s,r);else if(64&p)l.move(e,t,s,Q);else if(l!==ii)if(l!==ci)if(2!==r&&1&p&&c)if(0===r)c.beforeEnter(a),n(a,t,s),wr(()=>c.enter(a),i);else{const{leave:r,delayLeave:i,afterLeave:l}=c,u=()=>{e.ctx.isUnmounted?o(a):n(a,t,s)},p=()=>{a._isLeaving&&a[oo](!0),r(a,()=>{u(),l&&l()})};i?i(a,u,p):p()}else n(a,t,s);else(({el:e,anchor:t},o,s)=>{let r;for(;e&&e!==t;)r=m(e),n(e,o,s),e=r;n(t,o,s)})(e,t,s);else{n(a,t,s);for(let e=0;e{const{type:r,props:i,ref:a,children:l,dynamicChildren:c,shapeFlag:u,patchFlag:p,dirs:d,cacheIndex:f}=e;if(-2===p&&(s=!1),null!=a&&(Le(),Co(a,null,n,e,!0),Ie()),null!=f&&(t.renderCache[f]=void 0),256&u)return void t.ctx.deactivate(e);const h=1&u&&d,m=!Fo(e);let g;if(m&&(g=i&&i.onVnodeBeforeUnmount)&&Li(g,t,e),6&u)K(e.component,n,o);else{if(128&u)return void e.suspense.unmount(n,o);h&&qn(e,null,t,"beforeUnmount"),64&u?e.type.remove(e,t,n,Q,o):c&&!c.hasOnce&&(r!==ii||p>0&&64&p)?J(c,t,n,!1,!0):(r===ii&&384&p||!s&&16&u)&&J(l,t,n),o&&z(e)}(m&&(g=i&&i.onVnodeUnmounted)||h)&&wr(()=>{g&&Li(g,t,e),h&&qn(e,null,t,"unmounted")},n)},z=e=>{const{type:t,el:n,anchor:s,transition:r}=e;if(t===ii)return void W(n,s);if(t===ci)return void(({el:e,anchor:t})=>{let n;for(;e&&e!==t;)n=m(e),o(e),e=n;o(t)})(e);const i=()=>{o(n),r&&!r.persisted&&r.afterLeave&&r.afterLeave()};if(1&e.shapeFlag&&r&&!r.persisted){const{leave:t,delayLeave:o}=r,s=()=>t(n,i);o?o(e.el,i,s):s()}else i()},W=(e,t)=>{let n;for(;e!==t;)n=m(e),o(e),e=n;o(t)},K=(e,t,n)=>{const{bum:o,scope:s,job:r,subTree:i,um:a,m:l,a:c}=e;Br(l),Br(c),o&&F(o),s.stop(),r&&(r.flags|=8,H(i,e,t,n)),a&&wr(a,t),wr(()=>{e.isUnmounted=!0},t)},J=(e,t,n,o=!1,s=!1,r=0)=>{for(let i=r;i{if(6&e.shapeFlag)return Z(e.component.subTree);if(128&e.shapeFlag)return e.suspense.next();const t=m(e.anchor||e.el),n=t&&t[zn];return n?m(n):t};let G=!1;const X=(e,t,n)=>{null==e?t._vnode&&H(t._vnode,null,null,!0):v(t._vnode||null,e,t,null,null,null,n),t._vnode=e,G||(G=!0,Vn(),An(),G=!1)},Q={p:v,um:H,m:U,r:z,mt:O,mc:k,pc:M,pbc:N,n:Z,o:e};let Y,ee;return t&&([Y,ee]=t(Q)),{render:X,hydrate:Y,createApp:tr(X,Y)}}function xr({type:e,props:t},n){return"svg"===n&&"foreignObject"===e||"mathml"===n&&"annotation-xml"===e&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Nr({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Tr(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Vr(e,t,n=!1){const o=e.children,s=t.children;if(m(o)&&m(s))for(let e=0;esr(Or);function Dr(e,t){return Mr(e,null,t)}function Pr(e,t){return Mr(e,null,{flush:"post"})}function Lr(e,t){return Mr(e,null,{flush:"sync"})}function Ir(e,t,n){return Mr(e,t,n)}function Mr(e,t,n=r){const{immediate:o,deep:s,flush:i,once:l}=n,c=p({},n),u=t&&o||!t&&"post"!==i;let f;if(Zi)if("sync"===i){const e=Rr();f=e.__watcherHandles||(e.__watcherHandles=[])}else if(!u){const e=()=>{};return e.stop=a,e.resume=a,e.pause=a,e}const h=$i;c.call=(e,t,n)=>gn(e,h,t,n);let g=!1;"post"===i?c.scheduler=e=>{wr(e,h&&h.suspense)}:"sync"!==i&&(g=!0,c.scheduler=(e,t)=>{t?e():xn(e)}),c.augmentJob=e=>{t&&(e.flags|=4),g&&(e.flags|=2,h&&(e.id=h.uid,e.i=h))};const y=function(e,t,n=r){const{immediate:o,deep:s,once:i,scheduler:l,augmentJob:c,call:u}=n,p=e=>s?e:Rt(e)||!1===s||0===s?pn(e,1):pn(e);let f,h,g,y,v=!1,b=!1;if(Ft(e)?(h=()=>e.value,v=Rt(e)):Bt(e)?(h=()=>p(e),v=!0):m(e)?(b=!0,v=e.some(e=>Bt(e)||Rt(e)),h=()=>e.map(e=>Ft(e)?e.value:Bt(e)?p(e):_(e)?u?u(e,2):e():void 0)):h=_(e)?t?u?()=>u(e,2):e:()=>{if(g){Le();try{g()}finally{Ie()}}const t=ln;ln=f;try{return u?u(e,3,[y]):e(y)}finally{ln=t}}:a,t&&s){const e=h,t=!0===s?1/0:s;h=()=>pn(e(),t)}const S=ge(),w=()=>{f.stop(),S&&S.active&&d(S.effects,f)};if(i&&t){const e=t;t=(...t)=>{e(...t),w()}}let C=b?new Array(e.length).fill(rn):rn;const E=e=>{if(1&f.flags&&(f.dirty||e))if(t){const e=f.run();if(s||v||(b?e.some((e,t)=>M(e,C[t])):M(e,C))){g&&g();const n=ln;ln=f;try{const n=[e,C===rn?void 0:b&&C[0]===rn?[]:C,y];C=e,u?u(t,3,n):t(...n)}finally{ln=n}}}else f.run()};return c&&c(E),f=new _e(h),f.scheduler=l?()=>l(E,!1):E,y=e=>un(e,!1,f),g=f.onStop=()=>{const e=an.get(f);if(e){if(u)u(e,4);else for(const t of e)t();an.delete(f)}},t?o?E(!0):C=f.run():l?l(E.bind(null,!0),!0):f.run(),w.pause=f.pause.bind(f),w.resume=f.resume.bind(f),w.stop=w,w}(e,t,c);return Zi&&(f?f.push(y):u&&y()),y}function Fr(e,t,n){const o=this.proxy,s=b(e)?e.includes(".")?$r(o,e):()=>o[e]:e.bind(o,o);let r;_(t)?r=t:(r=t.handler,n=t);const i=qi(this),a=Mr(s,r.bind(o),n);return i(),a}function $r(e,t){const n=t.split(".");return()=>{let t=e;for(let e=0;e{let c,u,p=r;return Lr(()=>{const t=e[s];M(c,t)&&(c=t,l())}),{get:()=>(a(),n.get?n.get(c):c),set(e){const a=n.set?n.set(e):e;if(!(M(a,c)||p!==r&&M(e,p)))return;const d=o.vnode.props;d&&(t in d||s in d||i in d)&&(`onUpdate:${t}`in d||`onUpdate:${s}`in d||`onUpdate:${i}`in d)||(c=e,l()),o.emit(`update:${t}`,a),M(e,a)&&M(e,p)&&!M(a,u)&&l(),p=e,u=a}}});return l[Symbol.iterator]=()=>{let e=0;return{next:()=>e<2?{value:e++?a||r:l,done:!1}:{done:!0}}},l}const Ur=(e,t)=>"modelValue"===t||"model-value"===t?e.modelModifiers:e[`${t}Modifiers`]||e[`${R(t)}Modifiers`]||e[`${P(t)}Modifiers`];function Hr(e,t,...n){if(e.isUnmounted)return;const o=e.vnode.props||r;let s=n;const i=t.startsWith("update:"),a=i&&Ur(o,t.slice(7));let l;a&&(a.trim&&(s=n.map(e=>b(e)?e.trim():e)),a.number&&(s=n.map(j)));let c=o[l=I(t)]||o[l=I(R(t))];!c&&i&&(c=o[l=I(P(t))]),c&&gn(c,e,6,s);const u=o[l+"Once"];if(u){if(e.emitted){if(e.emitted[l])return}else e.emitted={};e.emitted[l]=!0,gn(u,e,6,s)}}const qr=new WeakMap;function zr(e,t,n=!1){const o=n?qr:t.emitsCache,s=o.get(e);if(void 0!==s)return s;const r=e.emits;let i={},a=!1;if(!_(e)){const o=e=>{const n=zr(e,t,!0);n&&(a=!0,p(i,n))};!n&&t.mixins.length&&t.mixins.forEach(o),e.extends&&o(e.extends),e.mixins&&e.mixins.forEach(o)}return r||a?(m(r)?r.forEach(e=>i[e]=null):p(i,r),w(e)&&o.set(e,i),i):(w(e)&&o.set(e,null),null)}function Wr(e,t){return!(!e||!c(t))&&(t=t.slice(2).replace(/Once$/,""),h(e,t[0].toLowerCase()+t.slice(1))||h(e,P(t))||h(e,t))}function Kr(e){const{type:t,vnode:n,proxy:o,withProxy:s,propsOptions:[r],slots:i,attrs:a,emit:l,render:c,renderCache:p,props:d,data:f,setupState:h,ctx:m,inheritAttrs:g}=e,y=Mn(e);let v,_;try{if(4&n.shapeFlag){const e=s||o,t=e;v=Oi(c.call(t,e,p,d,h,f,m)),_=a}else{const e=t;v=Oi(e.length>1?e(d,{attrs:a,slots:i,emit:l}):e(d,null)),_=t.props?a:Jr(a)}}catch(t){ui.length=0,yn(t,e,1),v=xi(li)}let b=v;if(_&&!1!==g){const e=Object.keys(_),{shapeFlag:t}=b;e.length&&7&t&&(r&&e.some(u)&&(_=Zr(_,r)),b=Ti(b,_,!1,!0))}return n.dirs&&(b=Ti(b,null,!1,!0),b.dirs=b.dirs?b.dirs.concat(n.dirs):n.dirs),n.transition&&go(b,n.transition),v=b,Mn(y),v}const Jr=e=>{let t;for(const n in e)("class"===n||"style"===n||c(n))&&((t||(t={}))[n]=e[n]);return t},Zr=(e,t)=>{const n={};for(const o in e)u(o)&&o.slice(9)in t||(n[o]=e[o]);return n};function Gr(e,t,n){const o=Object.keys(t);if(o.length!==Object.keys(e).length)return!0;for(let s=0;se.__isSuspense;let Yr=0;const ei={name:"Suspense",__isSuspense:!0,process(e,t,n,o,s,r,i,a,l,c){if(null==e)!function(e,t,n,o,s,r,i,a,l){const{p:c,o:{createElement:u}}=l,p=u("div"),d=e.suspense=ni(e,s,o,t,p,n,r,i,a,l);c(null,d.pendingBranch=e.ssContent,p,null,o,d,r,i),d.deps>0?(ti(e,"onPending"),ti(e,"onFallback"),c(null,e.ssFallback,t,n,o,null,r,i),ri(d,e.ssFallback)):d.resolve(!1,!0)}(t,n,o,s,r,i,a,l,c);else{if(r&&r.deps>0&&!e.suspense.isInFallback)return t.suspense=e.suspense,t.suspense.vnode=t,void(t.el=e.el);!function(e,t,n,o,s,r,i,a,{p:l,um:c,o:{createElement:u}}){const p=t.suspense=e.suspense;p.vnode=t,t.el=e.el;const d=t.ssContent,f=t.ssFallback,{activeBranch:h,pendingBranch:m,isInFallback:g,isHydrating:y}=p;if(m)p.pendingBranch=d,Si(m,d)?(l(m,d,p.hiddenContainer,null,s,p,r,i,a),p.deps<=0?p.resolve():g&&(y||(l(h,f,n,o,s,null,r,i,a),ri(p,f)))):(p.pendingId=Yr++,y?(p.isHydrating=!1,p.activeBranch=m):c(m,s,p),p.deps=0,p.effects.length=0,p.hiddenContainer=u("div"),g?(l(null,d,p.hiddenContainer,null,s,p,r,i,a),p.deps<=0?p.resolve():(l(h,f,n,o,s,null,r,i,a),ri(p,f))):h&&Si(h,d)?(l(h,d,n,o,s,p,r,i,a),p.resolve(!0)):(l(null,d,p.hiddenContainer,null,s,p,r,i,a),p.deps<=0&&p.resolve()));else if(h&&Si(h,d))l(h,d,n,o,s,p,r,i,a),ri(p,d);else if(ti(t,"onPending"),p.pendingBranch=d,512&d.shapeFlag?p.pendingId=d.component.suspenseId:p.pendingId=Yr++,l(null,d,p.hiddenContainer,null,s,p,r,i,a),p.deps<=0)p.resolve();else{const{timeout:e,pendingId:t}=p;e>0?setTimeout(()=>{p.pendingId===t&&p.fallback(f)},e):0===e&&p.fallback(f)}}(e,t,n,o,s,i,a,l,c)}},hydrate:function(e,t,n,o,s,r,i,a,l){const c=t.suspense=ni(t,o,n,e.parentNode,document.createElement("div"),null,s,r,i,a,!0),u=l(e,c.pendingBranch=t.ssContent,n,c,r,i);return 0===c.deps&&c.resolve(!1,!0),u},normalize:function(e){const{shapeFlag:t,children:n}=e,o=32&t;e.ssContent=oi(o?n.default:n),e.ssFallback=o?oi(n.fallback):xi(li)}};function ti(e,t){const n=e.props&&e.props[t];_(n)&&n()}function ni(e,t,n,o,s,r,i,a,l,c,u=!1){const{p,m:d,um:f,n:h,o:{parentNode:m,remove:g}}=c;let y;const v=function(e){const t=e.props&&e.props.suspensible;return null!=t&&!1!==t}(e);v&&t&&t.pendingBranch&&(y=t.pendingId,t.deps++);const _=e.props?U(e.props.timeout):void 0,b=r,S={vnode:e,parent:t,parentComponent:n,namespace:i,container:o,hiddenContainer:s,deps:0,pendingId:Yr++,timeout:"number"==typeof _?_:-1,activeBranch:null,pendingBranch:null,isInFallback:!u,isHydrating:u,isUnmounted:!1,effects:[],resolve(e=!1,n=!1){const{vnode:o,activeBranch:s,pendingBranch:i,pendingId:a,effects:l,parentComponent:c,container:u}=S;let p=!1;S.isHydrating?S.isHydrating=!1:e||(p=s&&i.transition&&"out-in"===i.transition.mode,p&&(s.transition.afterLeave=()=>{a===S.pendingId&&(d(i,u,r===b?h(s):r,0),Tn(l))}),s&&(m(s.el)===u&&(r=h(s)),f(s,c,S,!0)),p||d(i,u,r,0)),ri(S,i),S.pendingBranch=null,S.isInFallback=!1;let g=S.parent,_=!1;for(;g;){if(g.pendingBranch){g.effects.push(...l),_=!0;break}g=g.parent}_||p||Tn(l),S.effects=[],v&&t&&t.pendingBranch&&y===t.pendingId&&(t.deps--,0!==t.deps||n||t.resolve()),ti(o,"onResolve")},fallback(e){if(!S.pendingBranch)return;const{vnode:t,activeBranch:n,parentComponent:o,container:s,namespace:r}=S;ti(t,"onFallback");const i=h(n),c=()=>{S.isInFallback&&(p(null,e,s,i,o,null,r,a,l),ri(S,e))},u=e.transition&&"out-in"===e.transition.mode;u&&(n.transition.afterLeave=c),S.isInFallback=!0,f(n,o,null,!0),u||c()},move(e,t,n){S.activeBranch&&d(S.activeBranch,e,t,n),S.container=e},next:()=>S.activeBranch&&h(S.activeBranch),registerDep(e,t,n){const o=!!S.pendingBranch;o&&S.deps++;const s=e.vnode.el;e.asyncDep.catch(t=>{yn(t,e,0)}).then(r=>{if(e.isUnmounted||S.isUnmounted||S.pendingId!==e.suspenseId)return;e.asyncResolved=!0;const{vnode:a}=e;Xi(e,r,!1),s&&(a.el=s);const l=!s&&e.subTree.el;t(e,a,m(s||e.subTree.el),s?null:h(e.subTree),S,i,n),l&&g(l),Xr(e,a.el),o&&0===--S.deps&&S.resolve()})},unmount(e,t){S.isUnmounted=!0,S.activeBranch&&f(S.activeBranch,n,e,t),S.pendingBranch&&f(S.pendingBranch,n,e,t)}};return S}function oi(e){let t;if(_(e)){const n=mi&&e._c;n&&(e._d=!1,di()),e=e(),n&&(e._d=!0,t=pi,fi())}if(m(e)){const t=function(e){let t;for(let n=0;nt!==e)),e}function si(e,t){t&&t.pendingBranch?m(e)?t.effects.push(...e):t.effects.push(e):Tn(e)}function ri(e,t){e.activeBranch=t;const{vnode:n,parentComponent:o}=e;let s=t.el;for(;!s&&t.component;)s=(t=t.component.subTree).el;n.el=s,o&&o.subTree===n&&(o.vnode.el=s,Xr(o,s))}const ii=Symbol.for("v-fgt"),ai=Symbol.for("v-txt"),li=Symbol.for("v-cmt"),ci=Symbol.for("v-stc"),ui=[];let pi=null;function di(e=!1){ui.push(pi=e?null:[])}function fi(){ui.pop(),pi=ui[ui.length-1]||null}let hi,mi=1;function gi(e,t=!1){mi+=e,e<0&&pi&&t&&(pi.hasOnce=!0)}function yi(e){return e.dynamicChildren=mi>0?pi||i:null,fi(),mi>0&&pi&&pi.push(e),e}function vi(e,t,n,o,s,r){return yi(ki(e,t,n,o,s,r,!0))}function _i(e,t,n,o,s){return yi(xi(e,t,n,o,s,!0))}function bi(e){return!!e&&!0===e.__v_isVNode}function Si(e,t){return e.type===t.type&&e.key===t.key}function wi(e){hi=e}const Ci=({key:e})=>null!=e?e:null,Ei=({ref:e,ref_key:t,ref_for:n})=>("number"==typeof e&&(e=""+e),null!=e?b(e)||Ft(e)||_(e)?{i:Ln,r:e,k:t,f:!!n}:e:null);function ki(e,t=null,n=null,o=0,s=null,r=(e===ii?0:1),i=!1,a=!1){const l={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Ci(t),ref:t&&Ei(t),scopeId:In,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:o,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:Ln};return a?(Di(l,n),128&r&&e.normalize(l)):n&&(l.shapeFlag|=b(n)?8:16),mi>0&&!i&&pi&&(l.patchFlag>0||6&r)&&32!==l.patchFlag&&pi.push(l),l}const xi=function(e,t=null,n=null,o=0,s=null,r=!1){if(e&&e!==ds||(e=li),bi(e)){const o=Ti(e,t,!0);return n&&Di(o,n),mi>0&&!r&&pi&&(6&o.shapeFlag?pi[pi.indexOf(e)]=o:pi.push(o)),o.patchFlag=-2,o}if(i=e,_(i)&&"__vccOpts"in i&&(e=e.__vccOpts),t){t=Ni(t);let{class:e,style:n}=t;e&&!b(e)&&(t.class=X(e)),w(n)&&(Dt(n)&&!m(n)&&(n=p({},n)),t.style=W(n))}var i;return ki(e,t,n,o,s,b(e)?1:Qr(e)?128:Wn(e)?64:w(e)?4:_(e)?2:0,r,!0)};function Ni(e){return e?Dt(e)||lr(e)?p({},e):e:null}function Ti(e,t,n=!1,o=!1){const{props:s,ref:r,patchFlag:i,children:a,transition:l}=e,c=t?Pi(s||{},t):s,u={__v_isVNode:!0,__v_skip:!0,type:e.type,props:c,key:c&&Ci(c),ref:t&&t.ref?n&&r?m(r)?r.concat(Ei(t)):[r,Ei(t)]:Ei(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:a,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ii?-1===i?16:16|i:i,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:l,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ti(e.ssContent),ssFallback:e.ssFallback&&Ti(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return l&&o&&go(u,l.clone(u)),u}function Vi(e=" ",t=0){return xi(ai,null,e,t)}function Ai(e,t){const n=xi(ci,null,e);return n.staticCount=t,n}function Bi(e="",t=!1){return t?(di(),_i(li,null,e)):xi(li,null,e)}function Oi(e){return null==e||"boolean"==typeof e?xi(li):m(e)?xi(ii,null,e.slice()):bi(e)?Ri(e):xi(ai,null,String(e))}function Ri(e){return null===e.el&&-1!==e.patchFlag||e.memo?e:Ti(e)}function Di(e,t){let n=0;const{shapeFlag:o}=e;if(null==t)t=null;else if(m(t))n=16;else if("object"==typeof t){if(65&o){const n=t.default;return void(n&&(n._c&&(n._d=!1),Di(e,n()),n._c&&(n._d=!0)))}{n=32;const o=t._;o||lr(t)?3===o&&Ln&&(1===Ln.slots._?t._=1:(t._=2,e.patchFlag|=1024)):t._ctx=Ln}}else _(t)?(t={default:t,_ctx:Ln},n=32):(t=String(t),64&o?(n=16,t=[Vi(t)]):n=8);e.children=t,e.shapeFlag|=n}function Pi(...e){const t={};for(let n=0;n$i||Ln;let Ui,Hi;{const e=q(),t=(t,n)=>{let o;return(o=e[t])||(o=e[t]=[]),o.push(n),e=>{o.length>1?o.forEach(t=>t(e)):o[0](e)}};Ui=t("__VUE_INSTANCE_SETTERS__",e=>$i=e),Hi=t("__VUE_SSR_SETTERS__",e=>Zi=e)}const qi=e=>{const t=$i;return Ui(e),e.scope.on(),()=>{e.scope.off(),Ui(t)}},zi=()=>{$i&&$i.scope.off(),Ui(null)};function Wi(e){return 4&e.vnode.shapeFlag}let Ki,Ji,Zi=!1;function Gi(e,t=!1,n=!1){t&&Hi(t);const{props:o,children:s}=e.vnode,r=Wi(e);!function(e,t,n,o=!1){const s={},r=ar();e.propsDefaults=Object.create(null),cr(e,t,s,r);for(const t in e.propsOptions[0])t in s||(s[t]=void 0);n?e.props=o?s:Nt(s):e.type.props?e.props=s:e.props=r,e.attrs=r}(e,o,r,t),br(e,s,n||t);const i=r?function(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,ks);const{setup:o}=n;if(o){Le();const n=e.setupContext=o.length>1?na(e):null,s=qi(e),r=mn(o,e,0,[e.props,n]),i=C(r);if(Ie(),s(),!i&&!e.sp||Fo(e)||bo(e),i){if(r.then(zi,zi),t)return r.then(n=>{Xi(e,n,t)}).catch(t=>{yn(t,e,0)});e.asyncDep=r}else Xi(e,r,t)}else ea(e,t)}(e,t):void 0;return t&&Hi(!1),i}function Xi(e,t,n){_(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:w(t)&&(e.setupState=Jt(t)),ea(e,n)}function Qi(e){Ki=e,Ji=e=>{e.render._rc&&(e.withProxy=new Proxy(e.ctx,xs))}}const Yi=()=>!Ki;function ea(e,t,n){const o=e.type;if(!e.render){if(!t&&Ki&&!o.render){const t=o.template||zs(e).template;if(t){const{isCustomElement:n,compilerOptions:s}=e.appContext.config,{delimiters:r,compilerOptions:i}=o,a=p(p({isCustomElement:n,delimiters:r},s),i);o.render=Ki(t,a)}}e.render=o.render||a,Ji&&Ji(e)}{const t=qi(e);Le();try{!function(e){const t=zs(e),n=e.proxy,o=e.ctx;Us=!1,t.beforeCreate&&Hs(t.beforeCreate,e,"bc");const{data:s,computed:r,methods:i,watch:l,provide:c,inject:u,created:p,beforeMount:d,mounted:f,beforeUpdate:h,updated:g,activated:y,deactivated:v,beforeDestroy:b,beforeUnmount:S,destroyed:C,unmounted:E,render:k,renderTracked:x,renderTriggered:N,errorCaptured:T,serverPrefetch:V,expose:A,inheritAttrs:B,components:O,directives:R,filters:D}=t;if(u&&function(e,t){m(e)&&(e=Zs(e));for(const n in e){const o=e[n];let s;s=w(o)?"default"in o?sr(o.from||n,o.default,!0):sr(o.from||n):sr(o),Ft(s)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>s.value,set:e=>s.value=e}):t[n]=s}}(u,o),i)for(const e in i){const t=i[e];_(t)&&(o[e]=t.bind(n))}if(s){const t=s.call(n,n);w(t)&&(e.data=xt(t))}if(Us=!0,r)for(const e in r){const t=r[e],s=_(t)?t.bind(n,n):_(t.get)?t.get.bind(n,n):a,i=!_(t)&&_(t.set)?t.set.bind(n):a,l=ra({get:s,set:i});Object.defineProperty(o,e,{enumerable:!0,configurable:!0,get:()=>l.value,set:e=>l.value=e})}if(l)for(const e in l)qs(l[e],o,n,e);if(c){const e=_(c)?c.call(n):c;Reflect.ownKeys(e).forEach(t=>{or(t,e[t])})}function P(e,t){m(t)?t.forEach(t=>e(t.bind(n))):t&&e(t.bind(n))}if(p&&Hs(p,e,"c"),P(Yo,d),P(es,f),P(ts,h),P(ns,g),P(zo,y),P(Wo,v),P(ls,T),P(as,x),P(is,N),P(os,S),P(ss,E),P(rs,V),m(A))if(A.length){const t=e.exposed||(e.exposed={});A.forEach(e=>{Object.defineProperty(t,e,{get:()=>n[e],set:t=>n[e]=t,enumerable:!0})})}else e.exposed||(e.exposed={});k&&e.render===a&&(e.render=k),null!=B&&(e.inheritAttrs=B),O&&(e.components=O),R&&(e.directives=R),V&&bo(e)}(e)}finally{Ie(),t()}}}const ta={get:(e,t)=>(Ke(e,0,""),e[t])};function na(e){return{attrs:new Proxy(e.attrs,ta),slots:e.slots,emit:e.emit,expose:t=>{e.exposed=t||{}}}}function oa(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Jt(Lt(e.exposed)),{get:(t,n)=>n in t?t[n]:n in Cs?Cs[n](e):void 0,has:(e,t)=>t in e||t in Cs})):e.proxy}function sa(e,t=!0){return _(e)?e.displayName||e.name:e.name||t&&e.__name}const ra=(e,t)=>{const n=function(e,t,n=!1){let o,s;return _(e)?o=e:(o=e.get,s=e.set),new nn(o,s,n)}(e,0,Zi);return n};function ia(e,t,n){try{gi(-1);const o=arguments.length;return 2===o?w(t)&&!m(t)?bi(t)?xi(e,null,[t]):xi(e,t):xi(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):3===o&&bi(n)&&(n=[n]),xi(e,t,n))}finally{gi(1)}}function aa(){}function la(e,t,n,o){const s=n[o];if(s&&ca(s,e))return s;const r=t();return r.memo=e.slice(),r.cacheIndex=o,n[o]=r}function ca(e,t){const n=e.memo;if(n.length!=t.length)return!1;for(let e=0;e0&&pi&&pi.push(e),!0}const ua="3.5.22",pa=a,da={sp:"serverPrefetch hook",bc:"beforeCreate hook",c:"created hook",bm:"beforeMount hook",m:"mounted hook",bu:"beforeUpdate hook",u:"updated",bum:"beforeUnmount hook",um:"unmounted hook",a:"activated hook",da:"deactivated hook",ec:"errorCaptured hook",rtc:"renderTracked hook",rtg:"renderTriggered hook",0:"setup function",1:"render function",2:"watcher getter",3:"watcher callback",4:"watcher cleanup function",5:"native event handler",6:"component event handler",7:"vnode hook",8:"directive hook",9:"transition hook",10:"app errorHandler",11:"app warnHandler",12:"ref function",13:"async component loader",14:"scheduler flush",15:"component update",16:"app unmount cleanup function"},fa=Rn,ha=function e(t,n){var o,s;Rn=t,Rn?(Rn.enabled=!0,Dn.forEach(({event:e,args:t})=>Rn.emit(e,...t)),Dn=[]):"undefined"!=typeof window&&window.HTMLElement&&!(null==(s=null==(o=window.navigator)?void 0:o.userAgent)?void 0:s.includes("jsdom"))?((n.__VUE_DEVTOOLS_HOOK_REPLAY__=n.__VUE_DEVTOOLS_HOOK_REPLAY__||[]).push(t=>{e(t,n)}),setTimeout(()=>{Rn||(n.__VUE_DEVTOOLS_HOOK_REPLAY__=null,Pn=!0,Dn=[])},3e3)):(Pn=!0,Dn=[])},ma={createComponentInstance:Fi,setupComponent:Gi,renderComponentRoot:Kr,setCurrentRenderingInstance:Mn,isVNode:bi,normalizeVNode:Oi,getComponentPublicInstance:oa,ensureValidVNode:bs,pushWarningContext:function(e){dn.push(e)},popWarningContext:function(){dn.pop()}},ga=null,ya=null,va=null;let _a;const ba="undefined"!=typeof window&&window.trustedTypes;if(ba)try{_a=ba.createPolicy("vue",{createHTML:e=>e})}catch(e){}const Sa=_a?e=>_a.createHTML(e):e=>e,wa="undefined"!=typeof document?document:null,Ca=wa&&wa.createElement("template"),Ea={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const s="svg"===t?wa.createElementNS("http://www.w3.org/2000/svg",e):"mathml"===t?wa.createElementNS("http://www.w3.org/1998/Math/MathML",e):n?wa.createElement(e,{is:n}):wa.createElement(e);return"select"===e&&o&&null!=o.multiple&&s.setAttribute("multiple",o.multiple),s},createText:e=>wa.createTextNode(e),createComment:e=>wa.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>wa.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,o,s,r){const i=n?n.previousSibling:t.lastChild;if(s&&(s===r||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),s!==r&&(s=s.nextSibling););else{Ca.innerHTML=Sa("svg"===o?`${e}`:"mathml"===o?`${e}`:e);const s=Ca.content;if("svg"===o||"mathml"===o){const e=s.firstChild;for(;e.firstChild;)s.appendChild(e.firstChild);s.removeChild(e)}t.insertBefore(s,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ka="transition",xa="animation",Na=Symbol("_vtc"),Ta={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Va=p({},ao,Ta),Aa=(e=>(e.displayName="Transition",e.props=Va,e))((e,{slots:t})=>ia(uo,Ra(e),t)),Ba=(e,t=[])=>{m(e)?e.forEach(e=>e(...t)):e&&e(...t)},Oa=e=>!!e&&(m(e)?e.some(e=>e.length>1):e.length>1);function Ra(e){const t={};for(const n in e)n in Ta||(t[n]=e[n]);if(!1===e.css)return t;const{name:n="v",type:o,duration:s,enterFromClass:r=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:a=`${n}-enter-to`,appearFromClass:l=r,appearActiveClass:c=i,appearToClass:u=a,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,m=function(e){if(null==e)return null;if(w(e))return[Da(e.enter),Da(e.leave)];{const t=Da(e);return[t,t]}}(s),g=m&&m[0],y=m&&m[1],{onBeforeEnter:v,onEnter:_,onEnterCancelled:b,onLeave:S,onLeaveCancelled:C,onBeforeAppear:E=v,onAppear:k=_,onAppearCancelled:x=b}=t,N=(e,t,n,o)=>{e._enterCancelled=o,La(e,t?u:a),La(e,t?c:i),n&&n()},T=(e,t)=>{e._isLeaving=!1,La(e,d),La(e,h),La(e,f),t&&t()},V=e=>(t,n)=>{const s=e?k:_,i=()=>N(t,e,n);Ba(s,[t,i]),Ia(()=>{La(t,e?l:r),Pa(t,e?u:a),Oa(s)||Fa(t,o,g,i)})};return p(t,{onBeforeEnter(e){Ba(v,[e]),Pa(e,r),Pa(e,i)},onBeforeAppear(e){Ba(E,[e]),Pa(e,l),Pa(e,c)},onEnter:V(!1),onAppear:V(!0),onLeave(e,t){e._isLeaving=!0;const n=()=>T(e,t);Pa(e,d),e._enterCancelled?(Pa(e,f),Ha(e)):(Ha(e),Pa(e,f)),Ia(()=>{e._isLeaving&&(La(e,d),Pa(e,h),Oa(S)||Fa(e,o,y,n))}),Ba(S,[e,n])},onEnterCancelled(e){N(e,!1,void 0,!0),Ba(b,[e])},onAppearCancelled(e){N(e,!0,void 0,!0),Ba(x,[e])},onLeaveCancelled(e){T(e),Ba(C,[e])}})}function Da(e){return U(e)}function Pa(e,t){t.split(/\s+/).forEach(t=>t&&e.classList.add(t)),(e[Na]||(e[Na]=new Set)).add(t)}function La(e,t){t.split(/\s+/).forEach(t=>t&&e.classList.remove(t));const n=e[Na];n&&(n.delete(t),n.size||(e[Na]=void 0))}function Ia(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Ma=0;function Fa(e,t,n,o){const s=e._endId=++Ma,r=()=>{s===e._endId&&o()};if(null!=n)return setTimeout(r,n);const{type:i,timeout:a,propCount:l}=$a(e,t);if(!i)return o();const c=i+"end";let u=0;const p=()=>{e.removeEventListener(c,d),r()},d=t=>{t.target===e&&++u>=l&&p()};setTimeout(()=>{u(n[e]||"").split(", "),s=o(`${ka}Delay`),r=o(`${ka}Duration`),i=ja(s,r),a=o(`${xa}Delay`),l=o(`${xa}Duration`),c=ja(a,l);let u=null,p=0,d=0;return t===ka?i>0&&(u=ka,p=i,d=r.length):t===xa?c>0&&(u=xa,p=c,d=l.length):(p=Math.max(i,c),u=p>0?i>c?ka:xa:null,d=u?u===ka?r.length:l.length:0),{type:u,timeout:p,propCount:d,hasTransform:u===ka&&/\b(?:transform|all)(?:,|$)/.test(o(`${ka}Property`).toString())}}function ja(e,t){for(;e.lengthUa(t)+Ua(e[n])))}function Ua(e){return"auto"===e?0:1e3*Number(e.slice(0,-1).replace(",","."))}function Ha(e){return(e?e.ownerDocument:document).body.offsetHeight}const qa=Symbol("_vod"),za=Symbol("_vsh"),Wa={name:"show",beforeMount(e,{value:t},{transition:n}){e[qa]="none"===e.style.display?"":e.style.display,n&&t?n.beforeEnter(e):Ka(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:o}){!t!=!n&&(o?t?(o.beforeEnter(e),Ka(e,!0),o.enter(e)):o.leave(e,()=>{Ka(e,!1)}):Ka(e,t))},beforeUnmount(e,{value:t}){Ka(e,t)}};function Ka(e,t){e.style.display=t?e[qa]:"none",e[za]=!t}const Ja=Symbol("");function Za(e){const t=ji();if(!t)return;const n=t.ut=(n=e(t.proxy))=>{Array.from(document.querySelectorAll(`[data-v-owner="${t.uid}"]`)).forEach(e=>Xa(e,n))},o=()=>{const o=e(t.proxy);t.ce?Xa(t.ce,o):Ga(t.subTree,o),n(o)};ts(()=>{Tn(o)}),es(()=>{Ir(o,a,{flush:"post"});const e=new MutationObserver(o);e.observe(t.subTree.el.parentNode,{childList:!0}),ss(()=>e.disconnect())})}function Ga(e,t){if(128&e.shapeFlag){const n=e.suspense;e=n.activeBranch,n.pendingBranch&&!n.isHydrating&&n.effects.push(()=>{Ga(n.activeBranch,t)})}for(;e.component;)e=e.component.subTree;if(1&e.shapeFlag&&e.el)Xa(e.el,t);else if(e.type===ii)e.children.forEach(e=>Ga(e,t));else if(e.type===ci){let{el:n,anchor:o}=e;for(;n&&(Xa(n,t),n!==o);)n=n.nextSibling}}function Xa(e,t){if(1===e.nodeType){const n=e.style;let o="";for(const e in t){const s=pe(t[e]);n.setProperty(`--${e}`,s),o+=`--${e}: ${s};`}n[Ja]=o}}const Qa=/(?:^|;)\s*display\s*:/,Ya=/\s*!important$/;function el(e,t,n){if(m(n))n.forEach(n=>el(e,t,n));else if(null==n&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const o=function(e,t){const n=nl[t];if(n)return n;let o=R(t);if("filter"!==o&&o in e)return nl[t]=o;o=L(o);for(let n=0;ncl||(ul.then(()=>cl=0),cl=Date.now()),dl=e=>111===e.charCodeAt(0)&&110===e.charCodeAt(1)&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,fl={};function hl(e,t,n){let o=vo(e,t);N(o)&&(o=p({},o,t));class s extends yl{constructor(e){super(o,e,n)}}return s.def=o,s}const ml=(e,t)=>hl(e,t,oc),gl="undefined"!=typeof HTMLElement?HTMLElement:class{};class yl extends gl{constructor(e,t={},n=nc){super(),this._def=e,this._props=t,this._createApp=n,this._isVueCE=!0,this._instance=null,this._app=null,this._nonce=this._def.nonce,this._connected=!1,this._resolved=!1,this._numberProps=null,this._styleChildren=new WeakSet,this._ob=null,this.shadowRoot&&n!==nc?this._root=this.shadowRoot:!1!==e.shadowRoot?(this.attachShadow(p({},e.shadowRootOptions,{mode:"open"})),this._root=this.shadowRoot):this._root=this}connectedCallback(){if(!this.isConnected)return;this.shadowRoot||this._resolved||this._parseSlots(),this._connected=!0;let e=this;for(;e=e&&(e.parentNode||e.host);)if(e instanceof yl){this._parent=e;break}this._instance||(this._resolved?this._mount(this._def):e&&e._pendingResolve?this._pendingResolve=e._pendingResolve.then(()=>{this._pendingResolve=void 0,this._resolveDef()}):this._resolveDef())}_setParent(e=this._parent){e&&(this._instance.parent=e._instance,this._inheritParentContext(e))}_inheritParentContext(e=this._parent){e&&this._app&&Object.setPrototypeOf(this._app._context.provides,e._instance.provides)}disconnectedCallback(){this._connected=!1,kn(()=>{this._connected||(this._ob&&(this._ob.disconnect(),this._ob=null),this._app&&this._app.unmount(),this._instance&&(this._instance.ce=void 0),this._app=this._instance=null,this._teleportTargets&&(this._teleportTargets.clear(),this._teleportTargets=void 0))})}_processMutations(e){for(const t of e)this._setAttr(t.attributeName)}_resolveDef(){if(this._pendingResolve)return;for(let e=0;e{this._resolved=!0,this._pendingResolve=void 0;const{props:n,styles:o}=e;let s;if(n&&!m(n))for(const e in n){const t=n[e];(t===Number||t&&t.type===Number)&&(e in this._props&&(this._props[e]=U(this._props[e])),(s||(s=Object.create(null)))[R(e)]=!0)}this._numberProps=s,this._resolveProps(e),this.shadowRoot&&this._applyStyles(o),this._mount(e)},t=this._def.__asyncLoader;t?this._pendingResolve=t().then(t=>{t.configureApp=this._def.configureApp,e(this._def=t,!0)}):e(this._def)}_mount(e){this._app=this._createApp(e),this._inheritParentContext(),e.configureApp&&e.configureApp(this._app),this._app._ceVNode=this._createVNode(),this._app.mount(this._root);const t=this._instance&&this._instance.exposed;if(t)for(const e in t)h(this,e)||Object.defineProperty(this,e,{get:()=>zt(t[e])})}_resolveProps(e){const{props:t}=e,n=m(t)?t:Object.keys(t||{});for(const e of Object.keys(this))"_"!==e[0]&&n.includes(e)&&this._setProp(e,this[e]);for(const e of n.map(R))Object.defineProperty(this,e,{get(){return this._getProp(e)},set(t){this._setProp(e,t,!0,!0)}})}_setAttr(e){if(e.startsWith("data-v-"))return;const t=this.hasAttribute(e);let n=t?this.getAttribute(e):fl;const o=R(e);t&&this._numberProps&&this._numberProps[o]&&(n=U(n)),this._setProp(o,n,!1,!0)}_getProp(e){return this._props[e]}_setProp(e,t,n=!0,o=!1){if(t!==this._props[e]&&(t===fl?delete this._props[e]:(this._props[e]=t,"key"===e&&this._app&&(this._app._ceVNode.key=t)),o&&this._instance&&this._update(),n)){const n=this._ob;n&&(this._processMutations(n.takeRecords()),n.disconnect()),!0===t?this.setAttribute(P(e),""):"string"==typeof t||"number"==typeof t?this.setAttribute(P(e),t+""):t||this.removeAttribute(P(e)),n&&n.observe(this,{attributes:!0})}}_update(){const e=this._createVNode();this._app&&(e.appContext=this._app._context),ec(e,this._root)}_createVNode(){const e={};this.shadowRoot||(e.onVnodeMounted=e.onVnodeUpdated=this._renderSlots.bind(this));const t=xi(this._def,p(e,this._props));return this._instance||(t.ce=e=>{this._instance=e,e.ce=this,e.isCE=!0;const t=(e,t)=>{this.dispatchEvent(new CustomEvent(e,N(t[0])?p({detail:t},t[0]):{detail:t}))};e.emit=(e,...n)=>{t(e,n),P(e)!==e&&t(P(e),n)},this._setParent()}),t}_applyStyles(e,t){if(!e)return;if(t){if(t===this._def||this._styleChildren.has(t))return;this._styleChildren.add(t)}const n=this._nonce;for(let t=e.length-1;t>=0;t--){const o=document.createElement("style");n&&o.setAttribute("nonce",n),o.textContent=e[t],this.shadowRoot.prepend(o)}}_parseSlots(){const e=this._slots={};let t;for(;t=this.firstChild;){const n=1===t.nodeType&&t.getAttribute("slot")||"default";(e[n]||(e[n]=[])).push(t),this.removeChild(t)}}_renderSlots(){const e=this._getSlots(),t=this._instance.type.__scopeId;for(let n=0;n(e.push(...Array.from(t.querySelectorAll("slot"))),e),[])}_injectChildStyle(e){this._applyStyles(e.styles,e)}_removeChildStyle(e){}}function vl(e){const t=ji();return t&&t.ce||null}function _l(){const e=vl();return e&&e.shadowRoot}function bl(e="$style"){{const t=ji();if(!t)return r;const n=t.type.__cssModules;if(!n)return r;return n[e]||r}}const Sl=new WeakMap,wl=new WeakMap,Cl=Symbol("_moveCb"),El=Symbol("_enterCb"),kl=(e=>(delete e.props.mode,e))({name:"TransitionGroup",props:p({},Va,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=ji(),o=ro();let s,r;return ns(()=>{if(!s.length)return;const t=e.moveClass||`${e.name||"v"}-move`;if(!function(e,t,n){const o=e.cloneNode(),s=e[Na];s&&s.forEach(e=>{e.split(/\s+/).forEach(e=>e&&o.classList.remove(e))}),n.split(/\s+/).forEach(e=>e&&o.classList.add(e)),o.style.display="none";const r=1===t.nodeType?t:t.parentNode;r.appendChild(o);const{hasTransform:i}=$a(o);return r.removeChild(o),i}(s[0].el,n.vnode.el,t))return void(s=[]);s.forEach(xl),s.forEach(Nl);const o=s.filter(Tl);Ha(n.vnode.el),o.forEach(e=>{const n=e.el,o=n.style;Pa(n,t),o.transform=o.webkitTransform=o.transitionDuration="";const s=n[Cl]=e=>{e&&e.target!==n||e&&!e.propertyName.endsWith("transform")||(n.removeEventListener("transitionend",s),n[Cl]=null,La(n,t))};n.addEventListener("transitionend",s)}),s=[]}),()=>{const i=Pt(e),a=Ra(i);let l=i.tag||ii;if(s=[],r)for(let e=0;e{const t=e.props["onUpdate:modelValue"]||!1;return m(t)?e=>F(t,e):t};function Al(e){e.target.composing=!0}function Bl(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ol=Symbol("_assign"),Rl={created(e,{modifiers:{lazy:t,trim:n,number:o}},s){e[Ol]=Vl(s);const r=o||s.props&&"number"===s.props.type;il(e,t?"change":"input",t=>{if(t.target.composing)return;let o=e.value;n&&(o=o.trim()),r&&(o=j(o)),e[Ol](o)}),n&&il(e,"change",()=>{e.value=e.value.trim()}),t||(il(e,"compositionstart",Al),il(e,"compositionend",Bl),il(e,"change",Bl))},mounted(e,{value:t}){e.value=null==t?"":t},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:o,trim:s,number:r}},i){if(e[Ol]=Vl(i),e.composing)return;const a=null==t?"":t;if((!r&&"number"!==e.type||/^0\d/.test(e.value)?e.value:j(e.value))!==a){if(document.activeElement===e&&"range"!==e.type){if(o&&t===n)return;if(s&&e.value.trim()===a)return}e.value=a}}},Dl={deep:!0,created(e,t,n){e[Ol]=Vl(n),il(e,"change",()=>{const t=e._modelValue,n=Fl(e),o=e.checked,s=e[Ol];if(m(t)){const e=ie(t,n),r=-1!==e;if(o&&!r)s(t.concat(n));else if(!o&&r){const n=[...t];n.splice(e,1),s(n)}}else if(y(t)){const e=new Set(t);o?e.add(n):e.delete(n),s(e)}else s($l(e,o))})},mounted:Pl,beforeUpdate(e,t,n){e[Ol]=Vl(n),Pl(e,t,n)}};function Pl(e,{value:t,oldValue:n},o){let s;if(e._modelValue=t,m(t))s=ie(t,o.props.value)>-1;else if(y(t))s=t.has(o.props.value);else{if(t===n)return;s=re(t,$l(e,!0))}e.checked!==s&&(e.checked=s)}const Ll={created(e,{value:t},n){e.checked=re(t,n.props.value),e[Ol]=Vl(n),il(e,"change",()=>{e[Ol](Fl(e))})},beforeUpdate(e,{value:t,oldValue:n},o){e[Ol]=Vl(o),t!==n&&(e.checked=re(t,o.props.value))}},Il={deep:!0,created(e,{value:t,modifiers:{number:n}},o){const s=y(t);il(e,"change",()=>{const t=Array.prototype.filter.call(e.options,e=>e.selected).map(e=>n?j(Fl(e)):Fl(e));e[Ol](e.multiple?s?new Set(t):t:t[0]),e._assigning=!0,kn(()=>{e._assigning=!1})}),e[Ol]=Vl(o)},mounted(e,{value:t}){Ml(e,t)},beforeUpdate(e,t,n){e[Ol]=Vl(n)},updated(e,{value:t}){e._assigning||Ml(e,t)}};function Ml(e,t){const n=e.multiple,o=m(t);if(!n||o||y(t)){for(let s=0,r=e.options.length;sString(e)===String(i)):ie(t,i)>-1}else r.selected=t.has(i);else if(re(Fl(r),t))return void(e.selectedIndex!==s&&(e.selectedIndex=s))}n||-1===e.selectedIndex||(e.selectedIndex=-1)}}function Fl(e){return"_value"in e?e._value:e.value}function $l(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const jl={created(e,t,n){Hl(e,t,n,null,"created")},mounted(e,t,n){Hl(e,t,n,null,"mounted")},beforeUpdate(e,t,n,o){Hl(e,t,n,o,"beforeUpdate")},updated(e,t,n,o){Hl(e,t,n,o,"updated")}};function Ul(e,t){switch(e){case"SELECT":return Il;case"TEXTAREA":return Rl;default:switch(t){case"checkbox":return Dl;case"radio":return Ll;default:return Rl}}}function Hl(e,t,n,o,s){const r=Ul(e.tagName,n.props&&n.props.type)[s];r&&r(e,t,n,o)}const ql=["ctrl","shift","alt","meta"],zl={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&0!==e.button,middle:e=>"button"in e&&1!==e.button,right:e=>"button"in e&&2!==e.button,exact:(e,t)=>ql.some(n=>e[`${n}Key`]&&!t.includes(n))},Wl=(e,t)=>{const n=e._withMods||(e._withMods={}),o=t.join(".");return n[o]||(n[o]=(n,...o)=>{for(let e=0;e{const n=e._withKeys||(e._withKeys={}),o=t.join(".");return n[o]||(n[o]=n=>{if(!("key"in n))return;const o=P(n.key);return t.some(e=>e===o||Kl[e]===o)?e(n):void 0})},Zl=p({patchProp:(e,t,n,o,s,r)=>{const i="svg"===s;"class"===t?function(e,t,n){const o=e[Na];o&&(t=(t?[t,...o]:[...o]).join(" ")),null==t?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}(e,o,i):"style"===t?function(e,t,n){const o=e.style,s=b(n);let r=!1;if(n&&!s){if(t)if(b(t))for(const e of t.split(";")){const t=e.slice(0,e.indexOf(":")).trim();null==n[t]&&el(o,t,"")}else for(const e in t)null==n[e]&&el(o,e,"");for(const e in n)"display"===e&&(r=!0),el(o,e,n[e])}else if(s){if(t!==n){const e=o[Ja];e&&(n+=";"+e),o.cssText=n,r=Qa.test(n)}}else t&&e.removeAttribute("style");qa in e&&(e[qa]=r?o.display:"",e[za]&&(o.display="none"))}(e,n,o):c(t)?u(t)||function(e,t,n,o,s=null){const r=e[al]||(e[al]={}),i=r[t];if(o&&i)i.value=o;else{const[n,a]=function(e){let t;if(ll.test(e)){let n;for(t={};n=e.match(ll);)e=e.slice(0,e.length-n[0].length),t[n[0].toLowerCase()]=!0}return[":"===e[2]?e.slice(3):P(e.slice(2)),t]}(t);if(o){const i=r[t]=function(e,t){const n=e=>{if(e._vts){if(e._vts<=n.attached)return}else e._vts=Date.now();gn(function(e,t){if(m(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(e=>t=>!t._stopped&&e&&e(t))}return t}(e,n.value),t,5,[e])};return n.value=e,n.attached=pl(),n}(o,s);il(e,n,i,a)}else i&&(function(e,t,n,o){e.removeEventListener(t,n,o)}(e,n,i,a),r[t]=void 0)}}(e,t,0,o,r):("."===t[0]?(t=t.slice(1),1):"^"===t[0]?(t=t.slice(1),0):function(e,t,n,o){if(o)return"innerHTML"===t||"textContent"===t||!!(t in e&&dl(t)&&_(n));if("spellcheck"===t||"draggable"===t||"translate"===t||"autocorrect"===t)return!1;if("form"===t)return!1;if("list"===t&&"INPUT"===e.tagName)return!1;if("type"===t&&"TEXTAREA"===e.tagName)return!1;if("width"===t||"height"===t){const t=e.tagName;if("IMG"===t||"VIDEO"===t||"CANVAS"===t||"SOURCE"===t)return!1}return(!dl(t)||!b(n))&&t in e}(e,t,o,i))?(rl(e,t,o),e.tagName.includes("-")||"value"!==t&&"checked"!==t&&"selected"!==t||sl(e,t,o,i,0,"value"!==t)):!e._isVueCE||!/[A-Z]/.test(t)&&b(o)?("true-value"===t?e._trueValue=o:"false-value"===t&&(e._falseValue=o),sl(e,t,o,i)):rl(e,R(t),o,0,t)}},Ea);let Gl,Xl=!1;function Ql(){return Gl||(Gl=Cr(Zl))}function Yl(){return Gl=Xl?Gl:Er(Zl),Xl=!0,Gl}const ec=(...e)=>{Ql().render(...e)},tc=(...e)=>{Yl().hydrate(...e)},nc=(...e)=>{const t=Ql().createApp(...e),{mount:n}=t;return t.mount=e=>{const o=rc(e);if(!o)return;const s=t._component;_(s)||s.render||s.template||(s.template=o.innerHTML),1===o.nodeType&&(o.textContent="");const r=n(o,!1,sc(o));return o instanceof Element&&(o.removeAttribute("v-cloak"),o.setAttribute("data-v-app","")),r},t},oc=(...e)=>{const t=Yl().createApp(...e),{mount:n}=t;return t.mount=e=>{const t=rc(e);if(t)return n(t,!0,sc(t))},t};function sc(e){return e instanceof SVGElement?"svg":"function"==typeof MathMLElement&&e instanceof MathMLElement?"mathml":void 0}function rc(e){return b(e)?document.querySelector(e):e}let ic=!1;const ac=()=>{ic||(ic=!0,Rl.getSSRProps=({value:e})=>({value:e}),Ll.getSSRProps=({value:e},t)=>{if(t.props&&re(t.props.value,e))return{checked:!0}},Dl.getSSRProps=({value:e},t)=>{if(m(e)){if(t.props&&ie(e,t.props.value)>-1)return{checked:!0}}else if(y(e)){if(t.props&&e.has(t.props.value))return{checked:!0}}else if(e)return{checked:!0}},jl.getSSRProps=(e,t)=>{if("string"!=typeof t.type)return;const n=Ul(t.type.toUpperCase(),t.props&&t.props.type);return n.getSSRProps?n.getSSRProps(e,t):void 0},Wa.getSSRProps=({value:e})=>{if(!e)return{style:{display:"none"}}})},lc=Symbol(""),cc=Symbol(""),uc=Symbol(""),pc=Symbol(""),dc=Symbol(""),fc=Symbol(""),hc=Symbol(""),mc=Symbol(""),gc=Symbol(""),yc=Symbol(""),vc=Symbol(""),_c=Symbol(""),bc=Symbol(""),Sc=Symbol(""),wc=Symbol(""),Cc=Symbol(""),Ec=Symbol(""),kc=Symbol(""),xc=Symbol(""),Nc=Symbol(""),Tc=Symbol(""),Vc=Symbol(""),Ac=Symbol(""),Bc=Symbol(""),Oc=Symbol(""),Rc=Symbol(""),Dc=Symbol(""),Pc=Symbol(""),Lc=Symbol(""),Ic=Symbol(""),Mc=Symbol(""),Fc=Symbol(""),$c=Symbol(""),jc=Symbol(""),Uc=Symbol(""),Hc=Symbol(""),qc=Symbol(""),zc=Symbol(""),Wc=Symbol(""),Kc={[lc]:"Fragment",[cc]:"Teleport",[uc]:"Suspense",[pc]:"KeepAlive",[dc]:"BaseTransition",[fc]:"openBlock",[hc]:"createBlock",[mc]:"createElementBlock",[gc]:"createVNode",[yc]:"createElementVNode",[vc]:"createCommentVNode",[_c]:"createTextVNode",[bc]:"createStaticVNode",[Sc]:"resolveComponent",[wc]:"resolveDynamicComponent",[Cc]:"resolveDirective",[Ec]:"resolveFilter",[kc]:"withDirectives",[xc]:"renderList",[Nc]:"renderSlot",[Tc]:"createSlots",[Vc]:"toDisplayString",[Ac]:"mergeProps",[Bc]:"normalizeClass",[Oc]:"normalizeStyle",[Rc]:"normalizeProps",[Dc]:"guardReactiveProps",[Pc]:"toHandlers",[Lc]:"camelize",[Ic]:"capitalize",[Mc]:"toHandlerKey",[Fc]:"setBlockTracking",[$c]:"pushScopeId",[jc]:"popScopeId",[Uc]:"withCtx",[Hc]:"unref",[qc]:"isRef",[zc]:"withMemo",[Wc]:"isMemoSame"},Jc={start:{line:1,column:1,offset:0},end:{line:1,column:1,offset:0},source:""};function Zc(e,t,n,o,s,r,i,a=!1,l=!1,c=!1,u=Jc){return e&&(a?(e.helper(fc),e.helper(ru(e.inSSR,c))):e.helper(su(e.inSSR,c)),i&&e.helper(kc)),{type:13,tag:t,props:n,children:o,patchFlag:s,dynamicProps:r,directives:i,isBlock:a,disableTracking:l,isComponent:c,loc:u}}function Gc(e,t=Jc){return{type:17,loc:t,elements:e}}function Xc(e,t=Jc){return{type:15,loc:t,properties:e}}function Qc(e,t){return{type:16,loc:Jc,key:b(e)?Yc(e,!0):e,value:t}}function Yc(e,t=!1,n=Jc,o=0){return{type:4,loc:n,content:e,isStatic:t,constType:t?3:o}}function eu(e,t=Jc){return{type:8,loc:t,children:e}}function tu(e,t=[],n=Jc){return{type:14,loc:n,callee:e,arguments:t}}function nu(e,t=void 0,n=!1,o=!1,s=Jc){return{type:18,params:e,returns:t,newline:n,isSlot:o,loc:s}}function ou(e,t,n,o=!0){return{type:19,test:e,consequent:t,alternate:n,newline:o,loc:Jc}}function su(e,t){return e||t?gc:yc}function ru(e,t){return e||t?hc:mc}function iu(e,{helper:t,removeHelper:n,inSSR:o}){e.isBlock||(e.isBlock=!0,n(su(o,e.isComponent)),t(fc),t(ru(o,e.isComponent)))}const au=new Uint8Array([123,123]),lu=new Uint8Array([125,125]);function cu(e){return e>=97&&e<=122||e>=65&&e<=90}function uu(e){return 32===e||10===e||9===e||12===e||13===e}function pu(e){return 47===e||62===e||uu(e)}function du(e){const t=new Uint8Array(e.length);for(let n=0;n4===e.type&&e.isStatic;function Su(e){switch(e){case"Teleport":case"teleport":return cc;case"Suspense":case"suspense":return uc;case"KeepAlive":case"keep-alive":return pc;case"BaseTransition":case"base-transition":return dc}}const wu=/^$|^\d|[^\$\w\xA0-\uFFFF]/,Cu=e=>!wu.test(e),Eu=/[A-Za-z_$\xA0-\uFFFF]/,ku=/[\.\?\w$\xA0-\uFFFF]/,xu=/\s+[.[]\s*|\s*[.[]\s+/g,Nu=e=>4===e.type?e.content:e.loc.source,Tu=e=>{const t=Nu(e).trim().replace(xu,e=>e.trim());let n=0,o=[],s=0,r=0,i=null;for(let e=0;e|^\s*(?:async\s+)?function(?:\s+[\w$]+)?\s*\(/;function Au(e,t,n=!1){for(let o=0;o4===e.key.type&&e.key.content===o)}return n}function Uu(e,t){return`_${t}_${e.replace(/[^\w]/g,(t,n)=>"-"===t?"_":e.charCodeAt(n).toString())}`}const Hu=/([\s\S]*?)\s+(?:in|of)\s+(\S[\s\S]*)/,qu={parseMode:"base",ns:0,delimiters:["{{","}}"],getNamespace:()=>0,isVoidTag:l,isPreTag:l,isIgnoreNewlineTag:l,isCustomElement:l,onError:yu,onWarn:vu,comments:!1,prefixIdentifiers:!1};let zu=qu,Wu=null,Ku="",Ju=null,Zu=null,Gu="",Xu=-1,Qu=-1,Yu=0,ep=!1,tp=null;const np=[],op=new class{constructor(e,t){this.stack=e,this.cbs=t,this.state=1,this.buffer="",this.sectionStart=0,this.index=0,this.entityStart=0,this.baseState=1,this.inRCDATA=!1,this.inXML=!1,this.inVPre=!1,this.newlines=[],this.mode=0,this.delimiterOpen=au,this.delimiterClose=lu,this.delimiterIndex=-1,this.currentSequence=void 0,this.sequenceIndex=0}get inSFCRoot(){return 2===this.mode&&0===this.stack.length}reset(){this.state=1,this.mode=0,this.buffer="",this.sectionStart=0,this.index=0,this.baseState=1,this.inRCDATA=!1,this.currentSequence=void 0,this.newlines.length=0,this.delimiterOpen=au,this.delimiterClose=lu}getPos(e){let t=1,n=e+1;for(let o=this.newlines.length-1;o>=0;o--){const s=this.newlines[o];if(e>s){t=o+2,n=e-s;break}}return{column:n,line:t,offset:e}}peek(){return this.buffer.charCodeAt(this.index+1)}stateText(e){60===e?(this.index>this.sectionStart&&this.cbs.ontext(this.sectionStart,this.index),this.state=5,this.sectionStart=this.index):this.inVPre||e!==this.delimiterOpen[0]||(this.state=2,this.delimiterIndex=0,this.stateInterpolationOpen(e))}stateInterpolationOpen(e){if(e===this.delimiterOpen[this.delimiterIndex])if(this.delimiterIndex===this.delimiterOpen.length-1){const e=this.index+1-this.delimiterOpen.length;e>this.sectionStart&&this.cbs.ontext(this.sectionStart,e),this.state=3,this.sectionStart=e}else this.delimiterIndex++;else this.inRCDATA?(this.state=32,this.stateInRCDATA(e)):(this.state=1,this.stateText(e))}stateInterpolation(e){e===this.delimiterClose[0]&&(this.state=4,this.delimiterIndex=0,this.stateInterpolationClose(e))}stateInterpolationClose(e){e===this.delimiterClose[this.delimiterIndex]?this.delimiterIndex===this.delimiterClose.length-1?(this.cbs.oninterpolation(this.sectionStart,this.index+1),this.inRCDATA?this.state=32:this.state=1,this.sectionStart=this.index+1):this.delimiterIndex++:(this.state=3,this.stateInterpolation(e))}stateSpecialStartSequence(e){const t=this.sequenceIndex===this.currentSequence.length;if(t?pu(e):(32|e)===this.currentSequence[this.sequenceIndex]){if(!t)return void this.sequenceIndex++}else this.inRCDATA=!1;this.sequenceIndex=0,this.state=6,this.stateInTagName(e)}stateInRCDATA(e){if(this.sequenceIndex===this.currentSequence.length){if(62===e||uu(e)){const t=this.index-this.currentSequence.length;if(this.sectionStart=e||(28===this.state?this.currentSequence===fu.CdataEnd?this.cbs.oncdata(this.sectionStart,e):this.cbs.oncomment(this.sectionStart,e):6===this.state||11===this.state||18===this.state||17===this.state||12===this.state||13===this.state||14===this.state||15===this.state||16===this.state||20===this.state||19===this.state||21===this.state||9===this.state||this.cbs.ontext(this.sectionStart,e))}emitCodePoint(e,t){}}(np,{onerr:Cp,ontext(e,t){lp(ip(e,t),e,t)},ontextentity(e,t,n){lp(e,t,n)},oninterpolation(e,t){if(ep)return lp(ip(e,t),e,t);let n=e+op.delimiterOpen.length,o=t-op.delimiterClose.length;for(;uu(Ku.charCodeAt(n));)n++;for(;uu(Ku.charCodeAt(o-1));)o--;let s=ip(n,o);s.includes("&")&&(s=zu.decodeEntities(s,!1)),vp({type:5,content:wp(s,!1,_p(n,o)),loc:_p(e,t)})},onopentagname(e,t){const n=ip(e,t);Ju={type:1,tag:n,ns:zu.getNamespace(n,np[0],zu.ns),tagType:0,props:[],children:[],loc:_p(e-1,t),codegenNode:void 0}},onopentagend(e){ap(e)},onclosetag(e,t){const n=ip(e,t);if(!zu.isVoidTag(n)){let o=!1;for(let e=0;e0&&Cp(24,np[0].loc.start.offset);for(let n=0;n<=e;n++)cp(np.shift(),t,n(7===e.type?e.rawName:e.name)===n)&&Cp(2,t)},onattribend(e,t){if(Ju&&Zu){if(bp(Zu.loc,t),0!==e)if(Gu.includes("&")&&(Gu=zu.decodeEntities(Gu,!0)),6===Zu.type)"class"===Zu.name&&(Gu=yp(Gu).trim()),1!==e||Gu||Cp(13,t),Zu.value={type:2,content:Gu,loc:1===e?_p(Xu,Qu):_p(Xu-1,Qu+1)},op.inSFCRoot&&"template"===Ju.tag&&"lang"===Zu.name&&Gu&&"html"!==Gu&&op.enterRCDATA(du("{const s=t.start.offset+n;return wp(e,!1,_p(s,s+e.length),0,o?1:0)},a={source:i(r.trim(),n.indexOf(r,s.length)),value:void 0,key:void 0,index:void 0,finalized:!1};let l=s.trim().replace(rp,"").trim();const c=s.indexOf(l),u=l.match(sp);if(u){l=l.replace(sp,"").trim();const e=u[1].trim();let t;if(e&&(t=n.indexOf(e,c+l.length),a.key=i(e,t,!0)),u[2]){const o=u[2].trim();o&&(a.index=i(o,n.indexOf(o,a.key?t+e.length:c+l.length),!0))}}return l&&(a.value=i(l,c,!0)),a}(Zu.exp));let t=-1;"bind"===Zu.name&&(t=Zu.modifiers.findIndex(e=>"sync"===e.content))>-1&&gu("COMPILER_V_BIND_SYNC",zu,Zu.loc,Zu.arg.loc.source)&&(Zu.name="model",Zu.modifiers.splice(t,1))}7===Zu.type&&"pre"===Zu.name||Ju.props.push(Zu)}Gu="",Xu=Qu=-1},oncomment(e,t){zu.comments&&vp({type:3,content:ip(e,t),loc:_p(e-4,t+3)})},onend(){const e=Ku.length;for(let t=0;t64&&n<91||Su(e)||zu.isBuiltInComponent&&zu.isBuiltInComponent(e)||zu.isNativeTag&&!zu.isNativeTag(e))return!0;var n;for(let e=0;e6===e.type&&"inline-template"===e.name);n&&gu("COMPILER_INLINE_TEMPLATE",zu,n.loc)&&e.children.length&&(n.value={type:2,content:ip(e.children[0].loc.start.offset,e.children[e.children.length-1].loc.end.offset),loc:n.loc})}}function up(e,t){let n=e;for(;Ku.charCodeAt(n)!==t&&n>=0;)n--;return n}const pp=new Set(["if","else","else-if","for","slot"]);function dp({tag:e,props:t}){if("template"===e)for(let e=0;e3!==e.type);return 1!==t.length||1!==t[0].type||Iu(t[0])?null:t[0]}function xp(e,t,n,o=!1,s=!1){const{children:r}=e,i=[];for(let t=0;t0){if(e>=2){a.codegenNode.patchFlag=-1,i.push(a);continue}}else{const e=a.codegenNode;if(13===e.type){const t=e.patchFlag;if((void 0===t||512===t||1===t)&&Ap(a,n)>=2){const t=Bp(a);t&&(e.props=n.hoist(t))}e.dynamicProps&&(e.dynamicProps=n.hoist(e.dynamicProps))}}}else if(12===a.type&&(o?0:Np(a,n))>=2){14===a.codegenNode.type&&a.codegenNode.arguments.length>0&&a.codegenNode.arguments.push("-1"),i.push(a);continue}if(1===a.type){const t=1===a.tagType;t&&n.scopes.vSlot++,xp(a,e,n,!1,s),t&&n.scopes.vSlot--}else if(11===a.type)xp(a,e,n,1===a.children.length,!0);else if(9===a.type)for(let t=0;te.key===t||e.key.content===t);return n&&n.value}}i.length&&n.transformHoist&&n.transformHoist(r,n,e)}function Np(e,t){const{constantCache:n}=t;switch(e.type){case 1:if(0!==e.tagType)return 0;const o=n.get(e);if(void 0!==o)return o;const s=e.codegenNode;if(13!==s.type)return 0;if(s.isBlock&&"svg"!==e.tag&&"foreignObject"!==e.tag&&"math"!==e.tag)return 0;if(void 0===s.patchFlag){let o=3;const r=Ap(e,t);if(0===r)return n.set(e,0),0;r1)for(let s=0;s`_${Kc[N.helper(e)]}`,replaceNode(e){N.parent.children[N.childIndex]=N.currentNode=e},removeNode(e){const t=N.parent.children,n=e?t.indexOf(e):N.currentNode?N.childIndex:-1;e&&e!==N.currentNode?N.childIndex>n&&(N.childIndex--,N.onNodeRemoved()):(N.currentNode=null,N.onNodeRemoved()),N.parent.children.splice(n,1)},onNodeRemoved:a,addIdentifiers(e){},removeIdentifiers(e){},hoist(e){b(e)&&(e=Yc(e)),N.hoists.push(e);const t=Yc(`_hoisted_${N.hoists.length}`,!1,e.loc,2);return t.hoisted=e,t},cache(e,t=!1,n=!1){const o=function(e,t,n=!1,o=!1){return{type:20,index:e,value:t,needPauseTracking:n,inVOnce:o,needArraySpread:!1,loc:Jc}}(N.cached.length,e,t,n);return N.cached.push(o),o}};return N.filters=new Set,N}(e,t);Rp(e,n),t.hoistStatic&&Ep(e,n),t.ssr||function(e,t){const{helper:n}=t,{children:o}=e;if(1===o.length){const n=kp(e);if(n&&n.codegenNode){const o=n.codegenNode;13===o.type&&iu(o,t),e.codegenNode=o}else e.codegenNode=o[0]}else if(o.length>1){let o=64;e.codegenNode=Zc(t,n(lc),void 0,e.children,o,void 0,void 0,!0,void 0,!1)}}(e,n),e.helpers=new Set([...n.helpers.keys()]),e.components=[...n.components],e.directives=[...n.directives],e.imports=n.imports,e.hoists=n.hoists,e.temps=n.temps,e.cached=n.cached,e.transformed=!0,e.filters=[...n.filters]}function Rp(e,t){t.currentNode=e;const{nodeTransforms:n}=t,o=[];for(let s=0;s{n--};for(;nt===e:t=>e.test(t);return(e,o)=>{if(1===e.type){const{props:s}=e;if(3===e.tagType&&s.some(Pu))return;const r=[];for(let i=0;i`${Kc[e]}: _${Kc[e]}`;function Ip(e,t,{helper:n,push:o,newline:s,isTS:r}){const i=n("filter"===t?Ec:"component"===t?Sc:Cc);for(let n=0;n3||!1;t.push("["),n&&t.indent(),Fp(e,t,n),n&&t.deindent(),t.push("]")}function Fp(e,t,n=!1,o=!0){const{push:s,newline:r}=t;for(let i=0;ie||"null")}([r,i,a,h,c]),t),n(")"),p&&n(")"),u&&(n(", "),$p(u,t),n(")"))}(e,t);break;case 14:!function(e,t){const{push:n,helper:o,pure:s}=t,r=b(e.callee)?e.callee:o(e.callee);s&&n(Pp),n(r+"(",-2,e),Fp(e.arguments,t),n(")")}(e,t);break;case 15:!function(e,t){const{push:n,indent:o,deindent:s,newline:r}=t,{properties:i}=e;if(!i.length)return void n("{}",-2,e);const a=i.length>1||!1;n(a?"{":"{ "),a&&o();for(let e=0;e "),(l||a)&&(n("{"),o()),i?(l&&n("return "),m(i)?Mp(i,t):$p(i,t)):a&&$p(a,t),(l||a)&&(s(),n("}")),c&&(e.isNonScopedSlot&&n(", undefined, true"),n(")"))}(e,t);break;case 19:!function(e,t){const{test:n,consequent:o,alternate:s,newline:r}=e,{push:i,indent:a,deindent:l,newline:c}=t;if(4===n.type){const e=!Cu(n.content);e&&i("("),jp(n,t),e&&i(")")}else i("("),$p(n,t),i(")");r&&a(),t.indentLevel++,r||i(" "),i("? "),$p(o,t),t.indentLevel--,r&&c(),r||i(" "),i(": ");const u=19===s.type;u||t.indentLevel++,$p(s,t),u||t.indentLevel--,r&&l(!0)}(e,t);break;case 20:!function(e,t){const{push:n,helper:o,indent:s,deindent:r,newline:i}=t,{needPauseTracking:a,needArraySpread:l}=e;l&&n("[...("),n(`_cache[${e.index}] || (`),a&&(s(),n(`${o(Fc)}(-1`),e.inVOnce&&n(", true"),n("),"),i(),n("(")),n(`_cache[${e.index}] = `),$p(e.value,t),a&&(n(`).cacheIndex = ${e.index},`),i(),n(`${o(Fc)}(1),`),i(),n(`_cache[${e.index}]`),r()),n(")"),l&&n(")]")}(e,t);break;case 21:Fp(e.body,t,!0,!1)}}function jp(e,t){const{content:n,isStatic:o}=e;t.push(o?JSON.stringify(n):n,-3,e)}function Up(e,t){for(let n=0;nfunction(e,t,n,o){if(!("else"===t.name||t.exp&&t.exp.content.trim())){const o=t.exp?t.exp.loc:e.loc;n.onError(_u(28,t.loc)),t.exp=Yc("true",!1,o)}if("if"===t.name){const r=zp(e,t),i={type:9,loc:(s=e.loc,_p(s.start.offset,s.end.offset)),branches:[r]};if(n.replaceNode(i),o)return o(i,r,!0)}else{const s=n.parent.children;let r=s.indexOf(e);for(;r-- >=-1;){const i=s[r];if(i&&3===i.type)n.removeNode(i);else{if(!i||2!==i.type||i.content.trim().length){if(i&&9===i.type){"else-if"!==t.name&&"else"!==t.name||void 0!==i.branches[i.branches.length-1].condition||n.onError(_u(30,e.loc)),n.removeNode();const s=zp(e,t);i.branches.push(s);const r=o&&o(i,s,!1);Rp(s,n),r&&r(),n.currentNode=null}else n.onError(_u(30,e.loc));break}n.removeNode(i)}}}var s}(e,t,n,(e,t,o)=>{const s=n.parent.children;let r=s.indexOf(e),i=0;for(;r-- >=0;){const e=s[r];e&&9===e.type&&(i+=e.branches.length)}return()=>{if(o)e.codegenNode=Wp(t,i,n);else{const o=function(e){for(;;)if(19===e.type){if(19!==e.alternate.type)return e;e=e.alternate}else 20===e.type&&(e=e.value)}(e.codegenNode);o.alternate=Wp(t,i+e.branches.length-1,n)}}}));function zp(e,t){const n=3===e.tagType;return{type:10,loc:e.loc,condition:"else"===t.name?void 0:t.exp,children:n&&!Au(e,"for")?e.children:[e],userKey:Bu(e,"key"),isTemplateIf:n}}function Wp(e,t,n){return e.condition?ou(e.condition,Kp(e,t,n),tu(n.helper(vc),['""',"true"])):Kp(e,t,n)}function Kp(e,t,n){const{helper:o}=n,s=Qc("key",Yc(`${t}`,!1,Jc,2)),{children:r}=e,i=r[0];if(1!==r.length||1!==i.type){if(1===r.length&&11===i.type){const e=i.codegenNode;return $u(e,s,n),e}{let t=64;return Zc(n,o(lc),Xc([s]),r,t,void 0,void 0,!0,!1,!1,e.loc)}}{const e=i.codegenNode,t=14===(a=e).type&&a.callee===zc?a.arguments[1].returns:a;return 13===t.type&&iu(t,n),$u(t,s,n),e}var a}const Jp=Dp("for",(e,t,n)=>{const{helper:o,removeHelper:s}=n;return function(e,t,n,o){if(!t.exp)return void n.onError(_u(31,t.loc));const s=t.forParseResult;if(!s)return void n.onError(_u(32,t.loc));Zp(s);const{addIdentifiers:r,removeIdentifiers:i,scopes:a}=n,{source:l,value:c,key:u,index:p}=s,d={type:11,loc:t.loc,source:l,valueAlias:c,keyAlias:u,objectIndexAlias:p,parseResult:s,children:Lu(e)?e.children:[e]};n.replaceNode(d),a.vFor++;const f=o&&o(d);return()=>{a.vFor--,f&&f()}}(e,t,n,t=>{const r=tu(o(xc),[t.source]),i=Lu(e),a=Au(e,"memo"),l=Bu(e,"key",!1,!0);l&&l.type;let c=l&&(6===l.type?l.value?Yc(l.value.content,!0):void 0:l.exp);const u=l&&c?Qc("key",c):null,p=4===t.source.type&&t.source.constType>0,d=p?64:l?128:256;return t.codegenNode=Zc(n,o(lc),void 0,r,d,void 0,void 0,!0,!p,!1,e.loc),()=>{let l;const{children:d}=t,f=1!==d.length||1!==d[0].type,h=Iu(e)?e:i&&1===e.children.length&&Iu(e.children[0])?e.children[0]:null;if(h?(l=h.codegenNode,i&&u&&$u(l,u,n)):f?l=Zc(n,o(lc),u?Xc([u]):void 0,e.children,64,void 0,void 0,!0,void 0,!1):(l=d[0].codegenNode,i&&u&&$u(l,u,n),l.isBlock!==!p&&(l.isBlock?(s(fc),s(ru(n.inSSR,l.isComponent))):s(su(n.inSSR,l.isComponent))),l.isBlock=!p,l.isBlock?(o(fc),o(ru(n.inSSR,l.isComponent))):o(su(n.inSSR,l.isComponent))),a){const e=nu(Gp(t.parseResult,[Yc("_cached")]));e.body={type:21,body:[eu(["const _memo = (",a.exp,")"]),eu(["if (_cached",...c?[" && _cached.key === ",c]:[],` && ${n.helperString(Wc)}(_cached, _memo)) return _cached`]),eu(["const _item = ",l]),Yc("_item.memo = _memo"),Yc("return _item")],loc:Jc},r.arguments.push(e,Yc("_cache"),Yc(String(n.cached.length))),n.cached.push(null)}else r.arguments.push(nu(Gp(t.parseResult),l,!0))}})});function Zp(e,t){e.finalized||(e.finalized=!0)}function Gp({value:e,key:t,index:n},o=[]){return function(e){let t=e.length;for(;t--&&!e[t];);return e.slice(0,t+1).map((e,t)=>e||Yc("_".repeat(t+1),!1))}([e,t,n,...o])}const Xp=Yc("undefined",!1),Qp=(e,t)=>{if(1===e.type&&(1===e.tagType||3===e.tagType)){const n=Au(e,"slot");if(n)return n.exp,t.scopes.vSlot++,()=>{t.scopes.vSlot--}}},Yp=(e,t,n,o)=>nu(e,n,!1,!0,n.length?n[0].loc:o);function ed(e,t,n=Yp){t.helper(Uc);const{children:o,loc:s}=e,r=[],i=[];let a=t.scopes.vSlot>0||t.scopes.vFor>0;const l=Au(e,"slot",!0);if(l){const{arg:e,exp:t}=l;e&&!bu(e)&&(a=!0),r.push(Qc(e||Yc("default",!0),n(t,void 0,o,s)))}let c=!1,u=!1;const p=[],d=new Set;let f=0;for(let e=0;e{const r=n(e,void 0,o,s);return t.compatConfig&&(r.isNonScopedSlot=!0),Qc("default",r)};c?p.length&&p.some(e=>od(e))&&(u?t.onError(_u(39,p[0].loc)):r.push(e(void 0,p))):r.push(e(void 0,o))}const h=a?2:nd(e.children)?3:1;let m=Xc(r.concat(Qc("_",Yc(h+"",!1))),s);return i.length&&(m=tu(t.helper(Tc),[m,Gc(i)])),{slots:m,hasDynamicSlots:a}}function td(e,t,n){const o=[Qc("name",e),Qc("fn",t)];return null!=n&&o.push(Qc("key",Yc(String(n),!0))),Xc(o)}function nd(e){for(let t=0;tfunction(){if(1!==(e=t.currentNode).type||0!==e.tagType&&1!==e.tagType)return;const{tag:n,props:o}=e,s=1===e.tagType;let r=s?function(e,t,n=!1){let{tag:o}=e;const s=cd(o),r=Bu(e,"is",!1,!0);if(r)if(s||mu("COMPILER_IS_ON_ELEMENT",t)){let e;if(6===r.type?e=r.value&&Yc(r.value.content,!0):(e=r.exp,e||(e=Yc("is",!1,r.arg.loc))),e)return tu(t.helper(wc),[e])}else 6===r.type&&r.value.content.startsWith("vue:")&&(o=r.value.content.slice(4));const i=Su(o)||t.isBuiltInComponent(o);return i?(n||t.helper(i),i):(t.helper(Sc),t.components.add(o),Uu(o,"component"))}(e,t):`"${n}"`;const i=w(r)&&r.callee===wc;let a,l,c,u,p,d=0,f=i||r===cc||r===uc||!s&&("svg"===n||"foreignObject"===n||"math"===n);if(o.length>0){const n=id(e,t,void 0,s,i);a=n.props,d=n.patchFlag,u=n.dynamicPropNames;const o=n.directives;p=o&&o.length?Gc(o.map(e=>function(e,t){const n=[],o=sd.get(e);o?n.push(t.helperString(o)):(t.helper(Cc),t.directives.add(e.name),n.push(Uu(e.name,"directive")));const{loc:s}=e;if(e.exp&&n.push(e.exp),e.arg&&(e.exp||n.push("void 0"),n.push(e.arg)),Object.keys(e.modifiers).length){e.arg||(e.exp||n.push("void 0"),n.push("void 0"));const t=Yc("true",!1,s);n.push(Xc(e.modifiers.map(e=>Qc(e,t)),s))}return Gc(n,e.loc)}(e,t))):void 0,n.shouldUseBlock&&(f=!0)}if(e.children.length>0)if(r===pc&&(f=!0,d|=1024),s&&r!==cc&&r!==pc){const{slots:n,hasDynamicSlots:o}=ed(e,t);l=n,o&&(d|=1024)}else if(1===e.children.length&&r!==cc){const n=e.children[0],o=n.type,s=5===o||8===o;s&&0===Np(n,t)&&(d|=1),l=s||2===o?n:e.children}else l=e.children;u&&u.length&&(c=function(e){let t="[";for(let n=0,o=e.length;n0;let h=!1,m=0,g=!1,y=!1,v=!1,_=!1,b=!1,w=!1;const C=[],E=e=>{u.length&&(p.push(Xc(ad(u),a)),u=[]),e&&p.push(e)},k=()=>{t.scopes.vFor>0&&u.push(Qc(Yc("ref_for",!0),Yc("true")))},x=({key:e,value:n})=>{if(bu(e)){const r=e.content,i=c(r);if(!i||o&&!s||"onclick"===r.toLowerCase()||"onUpdate:modelValue"===r||V(r)||(_=!0),i&&V(r)&&(w=!0),i&&14===n.type&&(n=n.arguments[0]),20===n.type||(4===n.type||8===n.type)&&Np(n,t)>0)return;"ref"===r?g=!0:"class"===r?y=!0:"style"===r?v=!0:"key"===r||C.includes(r)||C.push(r),!o||"class"!==r&&"style"!==r||C.includes(r)||C.push(r)}else b=!0};for(let s=0;s"prop"===e.content)&&(m|=32);const w=t.directiveTransforms[n];if(w){const{props:n,needRuntime:o}=w(l,e,t);!r&&n.forEach(x),_&&s&&!bu(s)?E(Xc(n,a)):u.push(...n),o&&(d.push(l),S(o)&&sd.set(l,o))}else A(n)||(d.push(l),f&&(h=!0))}}let N;if(p.length?(E(),N=p.length>1?tu(t.helper(Ac),p,a):p[0]):u.length&&(N=Xc(ad(u),a)),b?m|=16:(y&&!o&&(m|=2),v&&!o&&(m|=4),C.length&&(m|=8),_&&(m|=32)),h||0!==m&&32!==m||!(g||w||d.length>0)||(m|=512),!t.inSSR&&N)switch(N.type){case 15:let e=-1,n=-1,o=!1;for(let t=0;t{if(Iu(e)){const{children:n,loc:o}=e,{slotName:s,slotProps:r}=function(e,t){let n,o='"default"';const s=[];for(let t=0;t0){const{props:o,directives:r}=id(e,t,s,!1,!1);n=o,r.length&&t.onError(_u(36,r[0].loc))}return{slotName:o,slotProps:n}}(e,t),i=[t.prefixIdentifiers?"_ctx.$slots":"$slots",s,"{}","undefined","true"];let a=2;r&&(i[2]=r,a=3),n.length&&(i[3]=nu([],n,!1,!1,o),a=4),t.scopeId&&!t.slotted&&(a=5),i.splice(a),e.codegenNode=tu(t.helper(Nc),i,o)}},pd=(e,t,n,o)=>{const{loc:s,modifiers:r,arg:i}=e;let a;if(e.exp||r.length||n.onError(_u(35,s)),4===i.type)if(i.isStatic){let e=i.content;e.startsWith("vue:")&&(e=`vnode-${e.slice(4)}`),a=Yc(0!==t.tagType||e.startsWith("vnode")||!/[A-Z]/.test(e)?I(R(e)):`on:${e}`,!0,i.loc)}else a=eu([`${n.helperString(Mc)}(`,i,")"]);else a=i,a.children.unshift(`${n.helperString(Mc)}(`),a.children.push(")");let l=e.exp;l&&!l.content.trim()&&(l=void 0);let c=n.cacheHandlers&&!l&&!n.inVOnce;if(l){const e=Tu(l),t=!(e||(e=>Vu.test(Nu(e)))(l)),n=l.content.includes(";");(t||c&&e)&&(l=eu([`${t?"$event":"(...args)"} => ${n?"{":"("}`,l,n?"}":")"]))}let u={props:[Qc(a,l||Yc("() => {}",!1,s))]};return o&&(u=o(u)),c&&(u.props[0].value=n.cache(u.props[0].value)),u.props.forEach(e=>e.key.isHandlerKey=!0),u},dd=(e,t,n)=>{const{modifiers:o,loc:s}=e,r=e.arg;let{exp:i}=e;return i&&4===i.type&&!i.content.trim()&&(i=void 0),4!==r.type?(r.children.unshift("("),r.children.push(') || ""')):r.isStatic||(r.content=r.content?`${r.content} || ""`:'""'),o.some(e=>"camel"===e.content)&&(4===r.type?r.isStatic?r.content=R(r.content):r.content=`${n.helperString(Lc)}(${r.content})`:(r.children.unshift(`${n.helperString(Lc)}(`),r.children.push(")"))),n.inSSR||(o.some(e=>"prop"===e.content)&&fd(r,"."),o.some(e=>"attr"===e.content)&&fd(r,"^")),{props:[Qc(r,i)]}},fd=(e,t)=>{4===e.type?e.isStatic?e.content=t+e.content:e.content=`\`${t}\${${e.content}}\``:(e.children.unshift(`'${t}' + (`),e.children.push(")"))},hd=(e,t)=>{if(0===e.type||1===e.type||11===e.type||10===e.type)return()=>{const n=e.children;let o,s=!1;for(let e=0;e7===e.type&&!t.directiveTransforms[e.name])||"template"===e.tag)))for(let e=0;e{if(1===e.type&&Au(e,"once",!0)){if(md.has(e)||t.inVOnce||t.inSSR)return;return md.add(e),t.inVOnce=!0,t.helper(Fc),()=>{t.inVOnce=!1;const e=t.currentNode;e.codegenNode&&(e.codegenNode=t.cache(e.codegenNode,!0,!0))}}},yd=(e,t,n)=>{const{exp:o,arg:s}=e;if(!o)return n.onError(_u(41,e.loc)),vd();const r=o.loc.source.trim(),i=4===o.type?o.content:r,a=n.bindingMetadata[r];if("props"===a||"props-aliased"===a)return n.onError(_u(44,o.loc)),vd();if(!i.trim()||!Tu(o))return n.onError(_u(42,o.loc)),vd();const l=s||Yc("modelValue",!0),c=s?bu(s)?`onUpdate:${R(s.content)}`:eu(['"onUpdate:" + ',s]):"onUpdate:modelValue";let u;u=eu([(n.isTS?"($event: any)":"$event")+" => ((",o,") = $event)"]);const p=[Qc(l,e.exp),Qc(c,u)];if(e.modifiers.length&&1===t.tagType){const t=e.modifiers.map(e=>e.content).map(e=>(Cu(e)?e:JSON.stringify(e))+": true").join(", "),n=s?bu(s)?`${s.content}Modifiers`:eu([s,' + "Modifiers"']):"modelModifiers";p.push(Qc(n,Yc(`{ ${t} }`,!1,e.loc,2)))}return vd(p)};function vd(e=[]){return{props:e}}const _d=/[\w).+\-_$\]]/,bd=(e,t)=>{mu("COMPILER_FILTERS",t)&&(5===e.type?Sd(e.content,t):1===e.type&&e.props.forEach(e=>{7===e.type&&"for"!==e.name&&e.exp&&Sd(e.exp,t)}))};function Sd(e,t){if(4===e.type)wd(e,t);else for(let n=0;n=0&&(e=n.charAt(t)," "===e);t--);e&&_d.test(e)||(u=!0)}}else void 0===i?(h=r+1,i=n.slice(0,r).trim()):g();function g(){m.push(n.slice(h,r).trim()),h=r+1}if(void 0===i?i=n.slice(0,r).trim():0!==h&&g(),m.length){for(r=0;r{if(1===e.type){const n=Au(e,"memo");if(!n||Ed.has(e)||t.inSSR)return;return Ed.add(e),()=>{const o=e.codegenNode||t.currentNode.codegenNode;o&&13===o.type&&(1!==e.tagType&&iu(o,t),e.codegenNode=tu(t.helper(zc),[n.exp,nu(void 0,o),"_cache",String(t.cached.length)]),t.cached.push(null))}}},xd=(e,t)=>{if(1===e.type)for(const n of e.props)if(7===n.type&&"bind"===n.name&&!n.exp){const e=n.arg;if(4===e.type&&e.isStatic){const t=R(e.content);(Eu.test(t[0])||"-"===t[0])&&(n.exp=Yc(t,!1,e.loc))}else t.onError(_u(52,e.loc)),n.exp=Yc("",!0,e.loc)}};function Nd(e,t={}){const n=t.onError||yu,o="module"===t.mode;!0===t.prefixIdentifiers?n(_u(47)):o&&n(_u(48)),t.cacheHandlers&&n(_u(49)),t.scopeId&&!o&&n(_u(50));const s=p({},t,{prefixIdentifiers:!1}),r=b(e)?function(e,t){if(op.reset(),Ju=null,Zu=null,Gu="",Xu=-1,Qu=-1,np.length=0,Ku=e,zu=p({},qu),t){let e;for(e in t)null!=t[e]&&(zu[e]=t[e])}op.mode="html"===zu.parseMode?1:"sfc"===zu.parseMode?2:0,op.inXML=1===zu.ns||2===zu.ns;const n=t&&t.delimiters;n&&(op.delimiterOpen=du(n[0]),op.delimiterClose=du(n[1]));const o=Wu=function(e,t=""){return{type:0,source:t,children:[],helpers:new Set,components:[],directives:[],hoists:[],imports:[],cached:[],temps:0,codegenNode:void 0,loc:Jc}}(0,e);return op.parse(Ku),o.loc=_p(0,e.length),o.children=hp(o.children),Wu=null,o}(e,s):e,[i,a]=[[xd,gd,qp,kd,Jp,bd,ud,rd,Qp,hd],{on:pd,bind:dd,model:yd}];return Op(r,p({},s,{nodeTransforms:[...i,...t.nodeTransforms||[]],directiveTransforms:p({},a,t.directiveTransforms||{})})),function(e,t={}){const n=function(e,{mode:t="function",prefixIdentifiers:n="module"===t,sourceMap:o=!1,filename:s="template.vue.html",scopeId:r=null,optimizeImports:i=!1,runtimeGlobalName:a="Vue",runtimeModuleName:l="vue",ssrRuntimeModuleName:c="vue/server-renderer",ssr:u=!1,isTS:p=!1,inSSR:d=!1}){const f={mode:t,prefixIdentifiers:n,sourceMap:o,filename:s,scopeId:r,optimizeImports:i,runtimeGlobalName:a,runtimeModuleName:l,ssrRuntimeModuleName:c,ssr:u,isTS:p,inSSR:d,source:e.source,code:"",column:1,line:1,offset:0,indentLevel:0,pure:!1,map:void 0,helper:e=>`_${Kc[e]}`,push(e,t=-2,n){f.code+=e},indent(){h(++f.indentLevel)},deindent(e=!1){e?--f.indentLevel:h(--f.indentLevel)},newline(){h(f.indentLevel)}};function h(e){f.push("\n"+" ".repeat(e),0)}return f}(e,t);t.onContextCreated&&t.onContextCreated(n);const{mode:o,push:s,prefixIdentifiers:r,indent:i,deindent:a,newline:l,scopeId:c,ssr:u}=n,p=Array.from(e.helpers),d=p.length>0,f=!r&&"module"!==o;if(function(e,t){const{ssr:n,prefixIdentifiers:o,push:s,newline:r,runtimeModuleName:i,runtimeGlobalName:a,ssrRuntimeModuleName:l}=t,c=a,u=Array.from(e.helpers);u.length>0&&(s(`const _Vue = ${c}\n`,-1),e.hoists.length)&&s(`const { ${[gc,yc,vc,_c,bc].filter(e=>u.includes(e)).map(Lp).join(", ")} } = _Vue\n`,-1),function(e,t){if(!e.length)return;t.pure=!0;const{push:n,newline:o}=t;o();for(let s=0;s0)&&l()),e.directives.length&&(Ip(e.directives,"directive",n),e.temps>0&&l()),e.filters&&e.filters.length&&(l(),Ip(e.filters,"filter",n),l()),e.temps>0){s("let ");for(let t=0;t0?", ":""}_temp${t}`)}return(e.components.length||e.directives.length||e.temps)&&(s("\n",0),l()),u||s("return "),e.codegenNode?$p(e.codegenNode,n):s("null"),f&&(a(),s("}")),a(),s("}"),{ast:e,code:n.code,preamble:"",map:n.map?n.map.toJSON():void 0}}(r,s)}const Td=Symbol(""),Vd=Symbol(""),Ad=Symbol(""),Bd=Symbol(""),Od=Symbol(""),Rd=Symbol(""),Dd=Symbol(""),Pd=Symbol(""),Ld=Symbol(""),Id=Symbol("");var Md;let Fd;Md={[Td]:"vModelRadio",[Vd]:"vModelCheckbox",[Ad]:"vModelText",[Bd]:"vModelSelect",[Od]:"vModelDynamic",[Rd]:"withModifiers",[Dd]:"withKeys",[Pd]:"vShow",[Ld]:"Transition",[Id]:"TransitionGroup"},Object.getOwnPropertySymbols(Md).forEach(e=>{Kc[e]=Md[e]});const $d={parseMode:"html",isVoidTag:ne,isNativeTag:e=>Y(e)||ee(e)||te(e),isPreTag:e=>"pre"===e,isIgnoreNewlineTag:e=>"pre"===e||"textarea"===e,decodeEntities:function(e,t=!1){return Fd||(Fd=document.createElement("div")),t?(Fd.innerHTML=`
        +
        + + + +

        + +
        + +
        + + +
        + + + + + + + + + + + + + + + +_add_tabs_after_content(); + } diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/data-debug-mode.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/data-debug-mode.php new file mode 100644 index 0000000..24c3648 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/data-debug-mode.php @@ -0,0 +1,213 @@ +get_slug(); + $unique_affix = $fs->get_unique_affix(); + $last_license_user_id = $fs->get_last_license_user_id(); + $has_last_license_user_id = FS_User::is_valid_id( $last_license_user_id ); + + $message_above_input_field = ( ! $has_last_license_user_id ) ? + fs_text_inline( 'Please enter the license key to enable the debug mode:', 'submit-developer-license-key-message', $slug ) : + sprintf( + fs_text_inline( 'To enter the debug mode, please enter the secret key of the license owner (UserID = %d), which you can find in your "My Profile" section of your User Dashboard:', 'submit-addon-developer-key-message', $slug ), + $last_license_user_id + ); + + $processing_text = ( fs_esc_js_inline( 'Processing', 'processing', $slug ) . '...' ); + $submit_button_text = fs_text_inline( 'Submit', 'submit', $slug ); + $debug_license_link_text = fs_esc_html_inline( 'Start Debug', 'start-debug-license', $slug ); + $license_or_user_key_text = ( ! $has_last_license_user_id ) ? + fs_text_inline( 'License key', 'license-key' , $slug ) : + fs_text_inline( 'User key', 'user-key' , $slug ); + $input_html = ""; + + $modal_content_html = <<< HTML +

        +

        {$message_above_input_field}

        + {$input_html} +HTML; + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/contact.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/contact.php new file mode 100644 index 0000000..24d67e7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/contact.php @@ -0,0 +1,23 @@ +get_slug(); + + echo fs_text_inline( 'Sorry for the inconvenience and we are here to help if you give us a chance.', 'contact-support-before-deactivation', $slug ) + . sprintf(" %s", + $fs->contact_url( 'technical_support' ), + fs_text_inline( 'Contact Support', 'contact-support', $slug ) + ); diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/form.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/form.php new file mode 100644 index 0000000..ec9fcf1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/form.php @@ -0,0 +1,666 @@ +get_slug(); + + $subscription_cancellation_dialog_box_template_params = $VARS['subscription_cancellation_dialog_box_template_params']; + $show_deactivation_feedback_form = $VARS['show_deactivation_feedback_form']; + $confirmation_message = $VARS['uninstall_confirmation_message']; + + $is_anonymous = ( ! $fs->is_registered() ); + $anonymous_feedback_checkbox_html = ''; + + $reasons_list_items_html = ''; + $snooze_select_html = ''; + + if ( $show_deactivation_feedback_form ) { + $reasons = $VARS['reasons']; + + foreach ( $reasons as $reason ) { + $list_item_classes = 'reason' . ( ! empty( $reason['input_type'] ) ? ' has-input' : '' ); + + if ( isset( $reason['internal_message'] ) && ! empty( $reason['internal_message'] ) ) { + $list_item_classes .= ' has-internal-message'; + $reason_internal_message = $reason['internal_message']; + } else { + $reason_internal_message = ''; + } + + $reason_input_type = ( ! empty( $reason['input_type'] ) ? $reason['input_type'] : '' ); + $reason_input_placeholder = ( ! empty( $reason['input_placeholder'] ) ? $reason['input_placeholder'] : '' ); + + $reason_list_item_html = <<< HTML +
      • + +
        {$reason_internal_message}
        +
      • +HTML; + + $reasons_list_items_html .= $reason_list_item_html; + } + + if ( $is_anonymous ) { + $anonymous_feedback_checkbox_html = sprintf( + '', + fs_esc_html_inline( 'Anonymous feedback', 'anonymous-feedback', $slug ) + ); + } + + $snooze_periods = array( + array( + 'increment' => fs_text_inline( 'hour', $slug ), + 'quantity' => number_format_i18n(1), + 'value' => 6 * WP_FS__TIME_10_MIN_IN_SEC, + ), + array( + 'increment' => fs_text_inline( 'hours', $slug ), + 'quantity' => number_format_i18n(24), + 'value' => WP_FS__TIME_24_HOURS_IN_SEC, + ), + array( + 'increment' => fs_text_inline( 'days', $slug ), + 'quantity' => number_format_i18n(7), + 'value' => WP_FS__TIME_WEEK_IN_SEC, + ), + array( + 'increment' => fs_text_inline( 'days', $slug ), + 'quantity' => number_format_i18n(30), + 'value' => 30 * WP_FS__TIME_24_HOURS_IN_SEC, + ), + ); + + $snooze_select_html = ''; + } + + // Aliases. + $deactivate_text = fs_text_inline( 'Deactivate', 'deactivate', $slug ); + $theme_text = fs_text_inline( 'Theme', 'theme', $slug ); + $activate_x_text = fs_text_inline( 'Activate %s', 'activate-x', $slug ); + + $submit_deactivate_text = sprintf( + fs_text_inline( 'Submit & %s', 'deactivation-modal-button-submit', $slug ), + $fs->is_plugin() ? + $deactivate_text : + sprintf( $activate_x_text, $theme_text ) + ); + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); + + if ( ! empty( $subscription_cancellation_dialog_box_template_params ) ) { + fs_require_template( 'forms/subscription-cancellation.php', $subscription_cancellation_dialog_box_template_params ); + } +?> + diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/index.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/index.php new file mode 100644 index 0000000..0316c6a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/deactivation/index.php @@ -0,0 +1,3 @@ +get_slug(); + + $skip_url = fs_nonce_url( $fs->_get_admin_page_url( '', array( 'fs_action' => $fs->get_unique_affix() . '_skip_activation' ) ), $fs->get_unique_affix() . '_skip_activation' ); + $skip_text = strtolower( fs_text_x_inline( 'Skip', 'verb', 'skip', $slug ) ); + $use_plugin_anonymously_text = fs_text_inline( 'Click here to use the plugin anonymously', 'click-here-to-use-plugin-anonymously', $slug ); + + echo sprintf( fs_text_inline( "You might have missed it, but you don't have to share any data and can just %s the opt-in.", 'dont-have-to-share-any-data', $slug ), "{$skip_text}" ) + . " {$use_plugin_anonymously_text}"; \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/email-address-update.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/email-address-update.php new file mode 100644 index 0000000..49a300f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/email-address-update.php @@ -0,0 +1,347 @@ +get_slug(); + + $user = $fs->get_user(); + $current_email_address = $user->email; + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/index.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/index.php new file mode 100644 index 0000000..0316c6a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/index.php @@ -0,0 +1,3 @@ +get_slug(); + $unique_affix = $fs->get_unique_affix(); + + $cant_find_license_key_text = fs_text_inline( "Can't find your license key?", 'cant-find-license-key', $slug ); + $message_above_input_field = fs_text_inline( 'Please enter the license key that you received in the email right after the purchase:', 'activate-license-message', $slug ); + $message_below_input_field = ''; + + $header_title = $fs->is_free_plan() ? + fs_text_inline( 'Activate License', 'activate-license', $slug ) : + fs_text_inline( 'Update License', 'update-license', $slug ); + + if ( $fs->is_registered() ) { + $activate_button_text = $header_title; + } else { + $message_below_input_field = sprintf( + fs_text_inline( 'The %1$s will be periodically sending essential license data to %2$s to check for security and feature updates, and verify the validity of your license.', 'license-sync-disclaimer', $slug ), + $fs->get_module_label( true ), + "{$fs->get_plugin_title()}" + ); + + $activate_button_text = fs_text_inline( 'Agree & Activate License', 'agree-activate-license', $slug ); + } + + $license_key_text = fs_text_inline( 'License key', 'license-key' , $slug ); + + $is_network_activation = ( + $fs->is_network_active() && + fs_is_network_admin() && + ! $fs->is_delegated_connection() + ); + $network_activation_html = ''; + + $sites_details = array(); + if ( $is_network_activation ) { + $all_sites = Freemius::get_sites(); + + $all_site_details = array(); + $subsite_url_by_install_id = array(); + $install_url_by_install_id = array(); + + foreach ( $all_sites as $site ) { + $site_details = $fs->get_site_info( $site ); + + if ( FS_Clone_Manager::instance()->is_temporary_duplicate_by_blog_id( $site_details['blog_id'] ) ) { + continue; + } + + $blog_id = Freemius::get_site_blog_id( $site ); + $install = $fs->get_install_by_blog_id($blog_id); + + if ( is_object( $install ) ) { + if ( isset( $subsite_url_by_install_id[ $install->id ] ) ) { + $clone_subsite_url = $subsite_url_by_install_id[ $install->id ]; + $clone_install_url = $install_url_by_install_id[ $install->id ]; + + if ( + /** + * If we already have an install with the same URL as the subsite it's stored in, skip the current subsite. Otherwise, replace the existing install's data with the current subsite's install's data if the URLs match. + * + * @author Leo Fajardo (@leorw) + * @since 2.5.0 + */ + fs_strip_url_protocol( untrailingslashit( $clone_install_url ) ) === fs_strip_url_protocol( untrailingslashit( $clone_subsite_url ) ) || + fs_strip_url_protocol( untrailingslashit( $install->url ) ) !== fs_strip_url_protocol( untrailingslashit( $site_details['url'] ) ) + ) { + continue; + } + } + + if ( FS_Plugin_License::is_valid_id( $install->license_id ) ) { + $site_details['license_id'] = $install->license_id; + } + + $subsite_url_by_install_id[ $install->id ] = $site_details['url']; + $install_url_by_install_id[ $install->id ] = $install->url; + } + + $all_site_details[] = $site_details; + } + + if ( $is_network_activation ) { + $vars = array( + 'id' => $fs->get_id(), + 'sites' => $all_site_details, + 'require_license_key' => true + ); + + $network_activation_html = fs_get_template( 'partials/network-activation.php', $vars ); + } + } + + $premium_licenses = $fs->get_available_premium_licenses(); + $available_licenses = array(); + foreach ( $premium_licenses as $premium_license ) { + $activations_left = $premium_license->left(); + if ( ! ( $activations_left > 0 ) ) { + continue; + } + + $available_licenses[ $activations_left . '_' . $premium_license->id ] = $premium_license; + } + + $total_available_licenses = count( $available_licenses ); + if ( $total_available_licenses > 0 ) { + $license_input_html = <<< HTML +
        + + + + + + + + + + + +
        +HTML; + + if ( $total_available_licenses > 1 ) { + // Sort the licenses by number of activations left in descending order. + krsort( $available_licenses ); + + $license_input_html .= ''; + } else { + $available_licenses = array_values( $available_licenses ); + + /** + * @var FS_Plugin_License $available_license + */ + $available_license = $available_licenses[0]; + $value = sprintf( + "%s-Site %s License - %s", + ( 1 == $available_license->quota ? + 'Single' : + ( $available_license->is_unlimited() ? 'Unlimited' : $available_license->quota ) + ), + $fs->_get_plan_by_id( $available_license->plan_id )->title, + $available_license->get_html_escaped_masked_secret_key() + ); + + $license_input_html .= <<< HTML + +HTML; + } + + $license_input_html .= <<< HTML +
        + +
        + +
        +
        +
        +HTML; + } else { + $license_input_html = ""; + } + + $ownership_change_option_text = fs_text_inline( "Associate with the license owner's account.", 'associate-account-with-license-owner', $slug ); + $ownership_change_option_html = ""; + + /** + * IMPORTANT: + * DO NOT ADD MAXLENGTH OR LIMIT THE LICENSE KEY LENGTH SINCE + * WE DO WANT TO ALLOW INPUT OF LONGER KEYS (E.G. WooCommerce Keys) + * FOR MIGRATED MODULES. + */ + $modal_content_html = <<< HTML +

        +

        {$message_above_input_field}

        + {$license_input_html} + {$cant_find_license_key_text} + {$network_activation_html} +

        {$message_below_input_field}

        + {$ownership_change_option_html} +HTML; + + /** + * Handle the ownership change option if not an add-on or if no license yet is activated for the + * parent product in case of an add-on. + * + * @author Leo Fajardo (@leorw) + * @since 2.3.2 + */ + $is_user_change_supported = ( ! $fs->is_addon() || ! $fs->get_parent_instance()->has_active_valid_license() ); + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + +get_slug(); + + $reconnect_url = $fs->get_activation_url( array( + 'nonce' => wp_create_nonce( $fs->get_unique_affix() . '_reconnect' ), + 'fs_action' => ( $fs->get_unique_affix() . '_reconnect' ), + ) ); + + $plugin_title = "" . esc_html( $fs->get_plugin()->title ) . ""; + $opt_out_text = fs_text_x_inline( 'Opt Out', 'verb', 'opt-out', $slug ); + + $permission_manager = FS_Permission_Manager::instance( $fs ); + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); + fs_enqueue_local_style( 'fs_optout', '/admin/optout.css' ); + fs_enqueue_local_style( 'fs_common', '/admin/common.css' ); + + if ( ! $permission_manager->is_premium_context() ) { + $optional_permissions = array( $permission_manager->get_extensions_permission( false, + false, + true + ) ); + + $permission_groups = array( + array( + 'id' => 'communication', + 'type' => 'required', + 'title' => $fs->get_text_inline( 'Communication', 'communication' ), + 'desc' => '', + 'permissions' => $permission_manager->get_opt_in_required_permissions( true ), + 'is_enabled' => $fs->is_registered(), + 'prompt' => array( + $fs->esc_html_inline( "Sharing your name and email allows us to keep you in the loop about new features and important updates, warn you about security issues before they become public knowledge, and send you special offers.", 'opt-out-message_user' ), + sprintf( + $fs->esc_html_inline( 'By clicking "Opt Out", %s will no longer be able to view your name and email.', + 'opt-out-message-clicking-opt-out' ), + $plugin_title + ), + ), + 'prompt_cancel_label' => $fs->get_text_inline( 'Stay Connected', 'stay-connected' ) + ), + array( + 'id' => 'diagnostic', + 'type' => 'required', + 'title' => $fs->get_text_inline( 'Diagnostic Info', 'diagnostic-info' ), + 'desc' => '', + 'permissions' => $permission_manager->get_opt_in_diagnostic_permissions( true ), + 'is_enabled' => $fs->is_tracking_allowed(), + 'prompt' => array( + sprintf( + $fs->esc_html_inline( 'Sharing diagnostic data helps to provide additional functionality that\'s relevant to your website, avoid WordPress or PHP version incompatibilities that can break the website, and recognize which languages & regions the %s should be translated and tailored to.', + 'opt-out-message-clicking-opt-out' ), + $fs->get_module_type() + ), + sprintf( + $fs->esc_html_inline( 'By clicking "Opt Out", diagnostic data will no longer be sent to %s.', + 'opt-out-message-clicking-opt-out' ), + $plugin_title + ), + ), + 'prompt_cancel_label' => $fs->get_text_inline( 'Keep Sharing', 'keep-sharing' ) + ), + array( + 'id' => 'extensions', + 'type' => 'optional', + 'title' => $fs->get_text_inline( 'Extensions', 'extensions' ), + 'desc' => '', + 'permissions' => $optional_permissions, + ), + ); + } else { + $optional_permissions = $permission_manager->get_license_optional_permissions( false, true ); + + $permission_groups = array( + array( + 'id' => 'essentials', + 'type' => 'required', + 'title' => $fs->esc_html_inline( 'Required', 'required' ), + 'desc' => sprintf( $fs->esc_html_inline( 'For automatic delivery of security & feature updates, and license management & protection, %s needs to:', + 'license-sync-disclaimer' ), + '' . esc_html( $fs->get_plugin_title() ) . '' ), + 'permissions' => $permission_manager->get_license_required_permissions( true ), + 'is_enabled' => $permission_manager->is_essentials_tracking_allowed(), + 'prompt' => array( + sprintf( $fs->esc_html_inline( 'To ensure that security & feature updates are automatically delivered directly to your WordPress Admin Dashboard while protecting your license from unauthorized abuse, %2$s needs to view the website’s homepage URL, %1$s version, SDK version, and whether the %1$s is active.', 'premium-opt-out-message-usage-tracking' ), $fs->get_module_type(), $plugin_title ), + sprintf( $fs->esc_html_inline( 'By opting out from sharing this information with the updates server, you’ll have to check for new %1$s releases and manually download & install them. Not just a hassle, but missing an update can put your site at risk and cause undue compatibility issues, so we highly recommend keeping these essential permissions on.', 'opt-out-message-clicking-opt-out' ), $fs->get_module_type(), $plugin_title ), + ), + 'prompt_cancel_label' => $fs->get_text_inline( 'Keep automatic updates', 'premium-opt-out-cancel' ) + ), + array( + 'id' => 'optional', + 'type' => 'optional', + 'title' => $fs->esc_html_inline( 'Optional', 'optional' ), + 'desc' => sprintf( $fs->esc_html_inline( 'For ongoing compatibility with your website, you can optionally allow %s to:', + 'optional-permissions-disclaimer' ), $plugin_title ), + 'permissions' => $optional_permissions, + ), + ); + } + + $ajax_action = 'toggle_permission_tracking'; + + $form_id = "fs_opt_out_{$fs->get_id()}"; +?> + + +require_permissions_js( false ) ?> + + diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/premium-versions-upgrade-handler.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/premium-versions-upgrade-handler.php new file mode 100644 index 0000000..f30639b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/premium-versions-upgrade-handler.php @@ -0,0 +1,205 @@ +get_slug(); + + $plugin_data = $fs->get_plugin_data(); + $plugin_name = $plugin_data['Name']; + $plugin_basename = $fs->get_plugin_basename(); + + $license = $fs->_get_license(); + + if ( ! is_object( $license ) ) { + $purchase_url = $fs->pricing_url(); + } else { + $subscription = $fs->_get_subscription( $license->id ); + + $purchase_url = $fs->checkout_url( + is_object( $subscription ) ? + ( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) : + WP_FS__PERIOD_LIFETIME, + false, + array( 'licenses' => $license->quota ) + ); + } + + $message = sprintf( + fs_text_inline( 'There is a new version of %s available.', 'new-version-available-message', $slug ) . + fs_text_inline( ' %s to access version %s security & feature updates, and support.', 'x-for-updates-and-support', $slug ), + '', + sprintf( + '%s', + is_object( $license ) ? + fs_text_inline( 'Renew your license now', 'renew-license-now', $slug ) : + fs_text_inline( 'Buy a license now', 'buy-license-now', $slug ) + ), + '' + ); + + $modal_content_html = "

        {$message}

        "; + + $header_title = fs_text_inline( 'New Version Available', 'new-version-available', $slug ); + + $renew_license_button_text = is_object( $license ) ? + fs_text_inline( 'Renew license', 'renew-license', $slug ) : + fs_text_inline( 'Buy license', 'buy-license', $slug ); + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/premium-versions-upgrade-metadata.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/premium-versions-upgrade-metadata.php new file mode 100644 index 0000000..5f9fddd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/premium-versions-upgrade-metadata.php @@ -0,0 +1,47 @@ +_get_license(); + + if ( ! is_object( $license ) ) { + $purchase_url = $fs->pricing_url(); + } else { + $subscription = $fs->_get_subscription( $license->id ); + + $purchase_url = $fs->checkout_url( + is_object( $subscription ) ? + ( 1 == $subscription->billing_cycle ? WP_FS__PERIOD_MONTHLY : WP_FS__PERIOD_ANNUALLY ) : + WP_FS__PERIOD_LIFETIME, + false, + array( 'licenses' => $license->quota ) + ); + } + + $plugin_data = $fs->get_plugin_data(); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/resend-key.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/resend-key.php new file mode 100644 index 0000000..dc723e5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/resend-key.php @@ -0,0 +1,250 @@ +get_slug(); + + $send_button_text = fs_text_inline( 'Send License Key', 'send-license-key', $slug ); + $cancel_button_text = fs_text_inline( 'Cancel', 'cancel', $slug ); + $email_address_placeholder = fs_esc_attr_inline( 'Email address', 'email-address', $slug ); + $other_text = fs_text_inline( 'Other', 'other', $slug ); + + $is_freemium = $fs->is_freemium(); + + $send_button_text_html = esc_html($send_button_text); + + $button_html = <<< HTML + +HTML; + + if ( $is_freemium ) { + $current_user = Freemius::_get_current_wp_user(); + $email = $current_user->user_email; + $esc_email = esc_attr( $email ); + $form_html = <<< HTML + +{$button_html} +HTML; + } else { + $email = ''; + $form_html = <<< HTML +{$button_html} + +HTML; + } + + $message_above_input_field = $fs->is_only_premium() ? + fs_esc_html_inline( "Enter the email address you've used during the purchase and we will resend you the license key.", 'ask-for-upgrade-email-address-premium-only', $slug ) : + fs_esc_html_inline( "Enter the email address you've used for the upgrade below and we will resend you the license key.", 'ask-for-upgrade-email-address', $slug ); + + $modal_content_html = <<< HTML +

        +

        {$message_above_input_field}

        +
        + {$form_html} +
        +HTML; + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/subscription-cancellation.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/subscription-cancellation.php new file mode 100644 index 0000000..7a02fde --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/subscription-cancellation.php @@ -0,0 +1,277 @@ +get_slug(); + +/** + * @var FS_Plugin_License $license + */ +$license = $VARS['license']; + +$has_trial = $VARS['has_trial']; + +$subscription_cancellation_context = $has_trial ? + fs_text_inline( 'trial', 'trial', $slug ) : + fs_text_inline( 'subscription', 'subscription', $slug ); + +$plan = $fs->get_plan(); +$module_label = $fs->get_module_label( true ); + +if ( $VARS['is_license_deactivation'] ) { + $subscription_cancellation_text = ''; +} else { + $subscription_cancellation_text = sprintf( + fs_text_inline( + "Deactivating or uninstalling the %s will automatically disable the license, which you'll be able to use on another site.", + 'deactivation-or-uninstall-message', + $slug + ), + $module_label + ) . ' '; +} + + $subscription_cancellation_text .= sprintf( + fs_text_inline( + 'In case you are NOT planning on using this %s on this site (or any other site) - would you like to cancel the %s as well?', + 'cancel-subscription-message', + $slug + ), + ( $VARS['is_license_deactivation'] ? fs_text_inline( 'license', 'license', $slug ) : $module_label ), + $subscription_cancellation_context +); + +$cancel_subscription_action_label = sprintf( + fs_esc_html_inline( + "Cancel %s - I no longer need any security & feature updates, nor support for %s because I'm not planning to use the %s on this, or any other site.", + 'cancel-x', + $slug + ), + esc_html( $subscription_cancellation_context ), + sprintf( '%s', esc_html( $fs->get_plugin_title() ) ), + esc_html( $module_label ) +); + +$keep_subscription_active_action_label = esc_html( sprintf( + fs_text_inline( + "Don't cancel %s - I'm still interested in getting security & feature updates, as well as be able to contact support.", + 'dont-cancel-x', + $slug + ), + $subscription_cancellation_context +) ); + +$subscription_cancellation_text = esc_html( $subscription_cancellation_text ); + +$subscription_cancellation_html = <<< HTML +

        {$subscription_cancellation_text}

        +
          +
        • + +
        • +
        • + +
        • +
        +HTML; + +$downgrading_plan_text = fs_text_inline( 'Downgrading your plan', 'downgrading-plan', $slug ); +$cancelling_subscription_text = fs_text_inline( 'Cancelling the subscription', 'cancelling-subscription', $slug ); +/* translators: %1$s: Either 'Downgrading your plan' or 'Cancelling the subscription' */ +$downgrade_x_confirm_text = fs_text_inline( '%1$s will immediately stop all future recurring payments and your %2$s plan license will expire in %3$s.', 'downgrade-x-confirm', $slug ); +$prices_increase_text = fs_text_inline( 'Please note that we will not be able to grandfather outdated pricing for renewals/new subscriptions after a cancellation. If you choose to renew the subscription manually in the future, after a price increase, which typically occurs once a year, you will be charged the updated price.', 'pricing-increase-warning', $slug ); +$after_downgrade_non_blocking_text = fs_text_inline( 'You can still enjoy all %s features but you will not have access to %s security & feature updates, nor support.', 'after-downgrade-non-blocking', $slug ); +$after_downgrade_blocking_text = fs_text_inline( 'Once your license expires you can still use the Free version but you will NOT have access to the %s features.', 'after-downgrade-blocking', $slug ); +$after_downgrade_blocking_text_premium_only = fs_text_inline( 'Once your license expires you will no longer be able to use the %s, unless you activate it again with a valid premium license.', 'after-downgrade-blocking-premium-only', $slug ); + +$subscription_cancellation_confirmation_message = $has_trial ? + fs_text_inline( 'Cancelling the trial will immediately block access to all premium features. Are you sure?', 'cancel-trial-confirm', $slug ) : + sprintf( + '%s %s %s %s', + sprintf( + $downgrade_x_confirm_text, + ($fs->is_only_premium() ? $cancelling_subscription_text : $downgrading_plan_text ), + $plan->title, + human_time_diff( time(), strtotime( $license->expiration ) ) + ), + ( + $license->is_block_features ? + ( + $fs->is_only_premium() ? + sprintf( $after_downgrade_blocking_text_premium_only, $module_label ) : + sprintf( $after_downgrade_blocking_text, $plan->title ) + ) : + sprintf( $after_downgrade_non_blocking_text, $plan->title, $fs->get_module_label( true ) ) + ), + $prices_increase_text, + fs_esc_attr_inline( 'Are you sure you want to proceed?', 'proceed-confirmation', $slug ) + ); + +fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/trial-start.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/trial-start.php new file mode 100644 index 0000000..812363b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/trial-start.php @@ -0,0 +1,181 @@ +get_slug(); + + $message_header = sprintf( + /* translators: %1$s: Number of trial days; %2$s: Plan name; */ + fs_text_inline( 'You are 1-click away from starting your %1$s-day free trial of the %2$s plan.', 'start-trial-prompt-header', $slug ), + '', + '' + ); + $message_content = sprintf( + /* translators: %s: Link to freemius.com */ + fs_text_inline( 'For compliance with the WordPress.org guidelines, before we start the trial we ask that you opt in with your user and non-sensitive site information, allowing the %s to periodically send data to %s to check for version updates and to validate your trial.', 'start-trial-prompt-message', $slug ), + $fs->get_module_type(), + sprintf( + '%s', + 'https://freemius.com', + 'freemius.com' + ) + ); + + $modal_content_html = <<< HTML +

        +

        {$message_header}

        +

        {$message_content}

        +HTML; + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/forms/user-change.php b/html/wp-content/plugins/post-smtp/freemius/templates/forms/user-change.php new file mode 100644 index 0000000..3051b38 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/forms/user-change.php @@ -0,0 +1,296 @@ +get_slug(); + + /** + * @var object[] $license_owners + */ + $license_owners = $VARS['license_owners']; + + $change_user_message = fs_text_inline( 'By changing the user, you agree to transfer the account ownership to:', 'change-user--message', $slug ); + $header_title = fs_text_inline( 'Change User', 'change-user', $slug ); + $user_change_button_text = fs_text_inline( 'I Agree - Change User', 'agree-change-user', $slug ); + $other_text = fs_text_inline( 'Other', 'other', $slug ); + $enter_email_address_placeholder_text = fs_text_inline( 'Enter email address', 'enter-email-address', $slug ); + + $user_change_options_html = <<< HTML +
        + + +HTML; + + foreach ( $license_owners as $license_owner ) { + $user_change_options_html .= <<< HTML + + + + +HTML; + } + + $user_change_options_html .= <<< HTML + + + + + +
        +
        + +
        + +
        +
        +
        +
        +HTML; + + $modal_content_html = <<< HTML +

        +

        {$change_user_message}

        + {$user_change_options_html} +HTML; + + fs_enqueue_local_style( 'fs_dialog_boxes', '/admin/dialog-boxes.css' ); +?> + diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/gdpr-optin-js.php b/html/wp-content/plugins/post-smtp/freemius/templates/gdpr-optin-js.php new file mode 100644 index 0000000..80d1eac --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/gdpr-optin-js.php @@ -0,0 +1,67 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/index.php b/html/wp-content/plugins/post-smtp/freemius/templates/index.php new file mode 100644 index 0000000..0316c6a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/index.php @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/js/open-license-activation.php b/html/wp-content/plugins/post-smtp/freemius/templates/js/open-license-activation.php new file mode 100644 index 0000000..a88e6f9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/js/open-license-activation.php @@ -0,0 +1,37 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/js/permissions.php b/html/wp-content/plugins/post-smtp/freemius/templates/js/permissions.php new file mode 100644 index 0000000..dbc7dfd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/js/permissions.php @@ -0,0 +1,546 @@ + + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/js/style-premium-theme.php b/html/wp-content/plugins/post-smtp/freemius/templates/js/style-premium-theme.php new file mode 100644 index 0000000..942da64 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/js/style-premium-theme.php @@ -0,0 +1,53 @@ +get_slug(); + +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/partials/index.php b/html/wp-content/plugins/post-smtp/freemius/templates/partials/index.php new file mode 100644 index 0000000..cd6990e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/partials/index.php @@ -0,0 +1,2 @@ +get_slug(); + + $sites = $VARS['sites']; + $require_license_key = $VARS['require_license_key']; + + $show_delegation_option = $fs->apply_filters( 'show_delegation_option', true ); + $enable_per_site_activation = $fs->apply_filters( 'enable_per_site_activation', true ); +?> +|' ?> + diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/plugin-icon.php b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-icon.php new file mode 100644 index 0000000..4422c90 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-icon.php @@ -0,0 +1,22 @@ + +
        + +
        \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/description.php b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/description.php new file mode 100644 index 0000000..cbef32b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/description.php @@ -0,0 +1,73 @@ +info->selling_point_0 ) || + ! empty( $plugin->info->selling_point_1 ) || + ! empty( $plugin->info->selling_point_2 ) + ) : ?> +
        +
          + + info->{'selling_point_' . $i} ) ) : ?> +
        • + +

          info->{'selling_point_' . $i} ) ?>

        • + + +
        +
        + +
        + info->description, array( + 'a' => array( 'href' => array(), 'title' => array(), 'target' => array() ), + 'b' => array(), + 'i' => array(), + 'p' => array(), + 'blockquote' => array(), + 'h2' => array(), + 'h3' => array(), + 'ul' => array(), + 'ol' => array(), + 'li' => array() + ) ); + ?> +
        +info->screenshots ) ) : ?> + info->screenshots ?> +
        +

        slug ) ?>

        +
          + $url ) : ?> +
        • + + +
        • + +
        +
        + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/features.php b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/features.php new file mode 100644 index 0000000..25d59d2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/features.php @@ -0,0 +1,113 @@ +features) && is_array($plan->features)) { + foreach ( $plan->features as $feature ) { + if ( ! isset( $features_plan_map[ $feature->id ] ) ) { + $features_plan_map[ $feature->id ] = array( 'feature' => $feature, 'plans' => array() ); + } + + $features_plan_map[ $feature->id ]['plans'][ $plan->id ] = $feature; + } + } + + // Add support as a feature. + if ( ! empty( $plan->support_email ) || + ! empty( $plan->support_phone ) || + true === $plan->is_success_manager + ) { + if ( ! isset( $features_plan_map['support'] ) ) { + $support_feature = new stdClass(); + $support_feature->id = 'support'; + $support_feature->title = fs_text_inline( 'Support', $plugin->slug ); + $features_plan_map[ $support_feature->id ] = array( 'feature' => $support_feature, 'plans' => array() ); + } else { + $support_feature = $features_plan_map['support']['feature']; + } + + $features_plan_map[ $support_feature->id ]['plans'][ $plan->id ] = $support_feature; + } + } + + // Add updates as a feature for all plans. + $updates_feature = new stdClass(); + $updates_feature->id = 'updates'; + $updates_feature->title = fs_text_inline( 'Unlimited Updates', 'unlimited-updates', $plugin->slug ); + $features_plan_map[ $updates_feature->id ] = array( 'feature' => $updates_feature, 'plans' => array() ); + foreach ( $plans as $plan ) { + $features_plan_map[ $updates_feature->id ]['plans'][ $plan->id ] = $updates_feature; + } +?> +
        + + + + + + + + + + + $data ) : ?> + + + + + + + + +
        + title ?> + pricing ) ) { + fs_esc_html_echo_inline( 'Free', 'free', $plugin->slug ); + } else { + foreach ( $plan->pricing as $pricing ) { + /** + * @var FS_Pricing $pricing + */ + if ( 1 == $pricing->licenses ) { + if ( $pricing->has_annual() ) { + echo "\${$pricing->annual_price} / " . fs_esc_html_x_inline( 'year', 'as annual period', 'year', $plugin->slug ); + } else if ( $pricing->has_monthly() ) { + echo "\${$pricing->monthly_price} / " . fs_esc_html_x_inline( 'mo', 'as monthly period', 'mo', $plugin->slug ); + } else { + echo "\${$pricing->lifetime_price}"; + } + } + } + } + ?> +
        title ) ) ?> + id ] ) ) : ?> + id ]->value ) ) : ?> + id ]->value ) ?> + + + + +
        +
        \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/index.php b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/index.php new file mode 100644 index 0000000..0316c6a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/plugin-info/index.php @@ -0,0 +1,3 @@ + +
          + $url ) : ?> +
        1. + +
        2. + +
        diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/pricing.php b/html/wp-content/plugins/post-smtp/freemius/templates/pricing.php new file mode 100644 index 0000000..af2fe84 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/pricing.php @@ -0,0 +1,113 @@ +get_slug(); + $timestamp = time(); + + $context_params = array( + 'plugin_id' => $fs->get_id(), + 'plugin_public_key' => $fs->get_public_key(), + 'plugin_version' => $fs->get_plugin_version(), + ); + + $bundle_id = $fs->get_bundle_id(); + if ( ! is_null( $bundle_id ) ) { + $context_params['bundle_id'] = $bundle_id; + } + + // Get site context secure params. + if ( $fs->is_registered() ) { + $context_params = array_merge( $context_params, FS_Security::instance()->get_context_params( + $fs->get_site(), + $timestamp, + 'upgrade' + ) ); + } else { + $context_params['home_url'] = home_url(); + } + + if ( $fs->is_payments_sandbox() ) // Append plugin secure token for sandbox mode authentication.) + { + $context_params['sandbox'] = FS_Security::instance()->get_secure_token( + $fs->get_plugin(), + $timestamp, + 'checkout' + ); + } + + $query_params = array_merge( $context_params, $_GET, array( + 'next' => $fs->_get_sync_license_url( false, false ), + 'plugin_version' => $fs->get_plugin_version(), + // Billing cycle. + 'billing_cycle' => fs_request_get( 'billing_cycle', WP_FS__PERIOD_ANNUALLY ), + 'is_network_admin' => fs_is_network_admin() ? 'true' : 'false', + 'currency' => $fs->apply_filters( 'default_currency', 'usd' ), + 'discounts_model' => $fs->apply_filters( 'pricing/discounts_model', 'absolute' ), + ) ); + + $pricing_js_url = fs_asset_url( $fs->get_pricing_js_path() ); + + wp_enqueue_script( 'freemius-pricing', $pricing_js_url ); + + $pricing_css_path = $fs->apply_filters( 'pricing/css_path', null ); + if ( is_string( $pricing_css_path ) ) { + wp_enqueue_style( 'freemius-pricing', fs_asset_url( $pricing_css_path ) ); + } + + $has_tabs = $fs->_add_tabs_before_content(); + + if ( $has_tabs ) { + $query_params['tabs'] = 'true'; + } +?> +
        +
        + $fs->contact_url(), + 'is_production' => ( defined( 'WP_FS__IS_PRODUCTION_MODE' ) ? WP_FS__IS_PRODUCTION_MODE : null ), + 'menu_slug' => $fs->get_menu_slug(), + 'mode' => 'dashboard', + 'fs_wp_endpoint_url' => WP_FS__ADDRESS, + 'request_handler_url' => admin_url( + 'admin-ajax.php?' . http_build_query( array( + 'module_id' => $fs->get_id(), + 'action' => $fs->get_ajax_action( 'pricing_ajax_action' ), + 'security' => $fs->get_ajax_security( 'pricing_ajax_action' ) + ) ) + ), + 'selector' => '#fs_pricing_wrapper', + 'unique_affix' => $fs->get_unique_affix(), + 'show_annual_in_monthly' => $fs->apply_filters( 'pricing/show_annual_in_monthly', true ), + 'license' => $fs->has_active_valid_license() ? $fs->_get_license() : null, + 'plugin_icon' => $fs->get_local_icon_url(), + 'disable_single_package' => $fs->apply_filters( 'pricing/disable_single_package', false ), + ), $query_params ); + + wp_add_inline_script( 'freemius-pricing', 'Freemius.pricing.new( ' . json_encode( $pricing_config ) . ' )' ); + ?> +
        +_add_tabs_after_content(); + } diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/secure-https-header.php b/html/wp-content/plugins/post-smtp/freemius/templates/secure-https-header.php new file mode 100644 index 0000000..3d0a81e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/secure-https-header.php @@ -0,0 +1,39 @@ + +
        + + get_text_inline( 'Secure HTTPS %s page, running from an external domain', 'secure-x-page-header' ), + $VARS['page'] + ) ) . + ' - ' . + sprintf( + '%s', + 'https://www.mcafeesecure.com/verify?host=' . WP_FS__ROOT_DOMAIN_PRODUCTION, + 'Freemius Inc. [US]' + ); + } + ?> +
        \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/sticky-admin-notice-js.php b/html/wp-content/plugins/post-smtp/freemius/templates/sticky-admin-notice-js.php new file mode 100644 index 0000000..1930ef6 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/sticky-admin-notice-js.php @@ -0,0 +1,40 @@ + + diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/tabs-capture-js.php b/html/wp-content/plugins/post-smtp/freemius/templates/tabs-capture-js.php new file mode 100644 index 0000000..70c5edf --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/tabs-capture-js.php @@ -0,0 +1,64 @@ +get_slug(); +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/freemius/templates/tabs.php b/html/wp-content/plugins/post-smtp/freemius/templates/tabs.php new file mode 100644 index 0000000..2a20b70 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/freemius/templates/tabs.php @@ -0,0 +1,190 @@ +get_slug(); + + $menu_items = $fs->get_menu_items(); + + $show_settings_with_tabs = $fs->show_settings_with_tabs(); + + $tabs = array(); + foreach ( $menu_items as $priority => $items ) { + foreach ( $items as $item ) { + if ( ! $item['show_submenu'] ) { + $submenu_name = ('wp-support-forum' === $item['menu_slug']) ? + 'support' : + $item['menu_slug']; + + if ( 'pricing' === $submenu_name && ! $fs->is_pricing_page_visible() ) { + continue; + } + + if ( ! $show_settings_with_tabs || ! $fs->is_submenu_item_visible( $submenu_name, true ) ) { + continue; + } + } + + $url = $fs->_get_admin_page_url( $item['menu_slug'] ); + $title = $item['menu_title']; + + $tab = array( + 'label' => $title, + 'href' => $url, + 'slug' => $item['menu_slug'], + ); + + if ( 'pricing' === $item['menu_slug'] && $fs->is_in_trial_promotion() ) { + $tab['href'] .= '&trial=true'; + } + + $tabs[] = $tab; + } + } +?> + \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.auto.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.auto.php new file mode 100644 index 0000000..1960c39 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.auto.php @@ -0,0 +1,11 @@ +purify($html, $config); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.includes.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.includes.php new file mode 100644 index 0000000..4c713a3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.includes.php @@ -0,0 +1,236 @@ + $attributes) { + $allowed_elements[$element] = true; + foreach ($attributes as $attribute => $x) { + $allowed_attributes["$element.$attribute"] = true; + } + } + $config->set('HTML.AllowedElements', $allowed_elements); + $config->set('HTML.AllowedAttributes', $allowed_attributes); + if ($allowed_protocols !== null) { + $config->set('URI.AllowedSchemes', $allowed_protocols); + } + $purifier = new HTMLPurifier($config); + return $purifier->purify($string); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.path.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.path.php new file mode 100644 index 0000000..39b1b65 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.path.php @@ -0,0 +1,11 @@ +config = HTMLPurifier_Config::create($config); + $this->strategy = new HTMLPurifier_Strategy_Core(); + } + + /** + * Adds a filter to process the output. First come first serve + * + * @param HTMLPurifier_Filter $filter HTMLPurifier_Filter object + */ + public function addFilter($filter) + { + trigger_error( + 'HTMLPurifier->addFilter() is deprecated, use configuration directives' . + ' in the Filter namespace or Filter.Custom', + E_USER_WARNING + ); + $this->filters[] = $filter; + } + + /** + * Filters an HTML snippet/document to be XSS-free and standards-compliant. + * + * @param string $html String of HTML to purify + * @param HTMLPurifier_Config $config Config object for this operation, + * if omitted, defaults to the config object specified during this + * object's construction. The parameter can also be any type + * that HTMLPurifier_Config::create() supports. + * + * @return string Purified HTML + */ + public function purify($html, $config = null) + { + // :TODO: make the config merge in, instead of replace + $config = $config ? HTMLPurifier_Config::create($config) : $this->config; + + // implementation is partially environment dependant, partially + // configuration dependant + $lexer = HTMLPurifier_Lexer::create($config); + + $context = new HTMLPurifier_Context(); + + // setup HTML generator + $this->generator = new HTMLPurifier_Generator($config, $context); + $context->register('Generator', $this->generator); + + // set up global context variables + if ($config->get('Core.CollectErrors')) { + // may get moved out if other facilities use it + $language_factory = HTMLPurifier_LanguageFactory::instance(); + $language = $language_factory->create($config, $context); + $context->register('Locale', $language); + + $error_collector = new HTMLPurifier_ErrorCollector($context); + $context->register('ErrorCollector', $error_collector); + } + + // setup id_accumulator context, necessary due to the fact that + // AttrValidator can be called from many places + $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); + $context->register('IDAccumulator', $id_accumulator); + + $html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context); + + // setup filters + $filter_flags = $config->getBatch('Filter'); + $custom_filters = $filter_flags['Custom']; + unset($filter_flags['Custom']); + $filters = array(); + foreach ($filter_flags as $filter => $flag) { + if (!$flag) { + continue; + } + if (strpos($filter, '.') !== false) { + continue; + } + $class = "HTMLPurifier_Filter_$filter"; + $filters[] = new $class; + } + foreach ($custom_filters as $filter) { + // maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat + $filters[] = $filter; + } + $filters = array_merge($filters, $this->filters); + // maybe prepare(), but later + + for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) { + $html = $filters[$i]->preFilter($html, $config, $context); + } + + // purified HTML + $html = + $this->generator->generateFromTokens( + // list of tokens + $this->strategy->execute( + // list of un-purified tokens + $lexer->tokenizeHTML( + // un-purified HTML + $html, + $config, + $context + ), + $config, + $context + ) + ); + + for ($i = $filter_size - 1; $i >= 0; $i--) { + $html = $filters[$i]->postFilter($html, $config, $context); + } + + $html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context); + $this->context =& $context; + return $html; + } + + /** + * Filters an array of HTML snippets + * + * @param string[] $array_of_html Array of html snippets + * @param HTMLPurifier_Config $config Optional config object for this operation. + * See HTMLPurifier::purify() for more details. + * + * @return string[] Array of purified HTML + */ + public function purifyArray($array_of_html, $config = null) + { + $context_array = array(); + $array = array(); + foreach($array_of_html as $key=>$value){ + if (is_array($value)) { + $array[$key] = $this->purifyArray($value, $config); + } else { + $array[$key] = $this->purify($value, $config); + } + $context_array[$key] = $this->context; + } + $this->context = $context_array; + return $array; + } + + /** + * Singleton for enforcing just one HTML Purifier in your system + * + * @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype + * HTMLPurifier instance to overload singleton with, + * or HTMLPurifier_Config instance to configure the + * generated version with. + * + * @return HTMLPurifier + */ + public static function instance($prototype = null) + { + if (!self::$instance || $prototype) { + if ($prototype instanceof HTMLPurifier) { + self::$instance = $prototype; + } elseif ($prototype) { + self::$instance = new HTMLPurifier($prototype); + } else { + self::$instance = new HTMLPurifier(); + } + } + return self::$instance; + } + + /** + * Singleton for enforcing just one HTML Purifier in your system + * + * @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype + * HTMLPurifier instance to overload singleton with, + * or HTMLPurifier_Config instance to configure the + * generated version with. + * + * @return HTMLPurifier + * @note Backwards compatibility, see instance() + */ + public static function getInstance($prototype = null) + { + return HTMLPurifier::instance($prototype); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.safe-includes.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.safe-includes.php new file mode 100644 index 0000000..8a417d2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier.safe-includes.php @@ -0,0 +1,230 @@ +getHTMLDefinition(); + $parent = new HTMLPurifier_Token_Start($definition->info_parent); + $stack = array($parent->toNode()); + foreach ($tokens as $token) { + $token->skip = null; // [MUT] + $token->carryover = null; // [MUT] + if ($token instanceof HTMLPurifier_Token_End) { + $token->start = null; // [MUT] + $r = array_pop($stack); + //assert($r->name === $token->name); + //assert(empty($token->attr)); + $r->endCol = $token->col; + $r->endLine = $token->line; + $r->endArmor = $token->armor; + continue; + } + $node = $token->toNode(); + $stack[count($stack)-1]->children[] = $node; + if ($token instanceof HTMLPurifier_Token_Start) { + $stack[] = $node; + } + } + //assert(count($stack) == 1); + return $stack[0]; + } + + public static function flatten($node, $config, $context) { + $level = 0; + $nodes = array($level => new HTMLPurifier_Queue(array($node))); + $closingTokens = array(); + $tokens = array(); + do { + while (!$nodes[$level]->isEmpty()) { + $node = $nodes[$level]->shift(); // FIFO + list($start, $end) = $node->toTokenPair(); + if ($level > 0) { + $tokens[] = $start; + } + if ($end !== NULL) { + $closingTokens[$level][] = $end; + } + if ($node instanceof HTMLPurifier_Node_Element) { + $level++; + $nodes[$level] = new HTMLPurifier_Queue(); + foreach ($node->children as $childNode) { + $nodes[$level]->push($childNode); + } + } + } + $level--; + if ($level && isset($closingTokens[$level])) { + while ($token = array_pop($closingTokens[$level])) { + $tokens[] = $token; + } + } + } while ($level > 0); + return $tokens; + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrCollections.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrCollections.php new file mode 100644 index 0000000..c7b17cf --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrCollections.php @@ -0,0 +1,148 @@ +doConstruct($attr_types, $modules); + } + + public function doConstruct($attr_types, $modules) + { + // load extensions from the modules + foreach ($modules as $module) { + foreach ($module->attr_collections as $coll_i => $coll) { + if (!isset($this->info[$coll_i])) { + $this->info[$coll_i] = array(); + } + foreach ($coll as $attr_i => $attr) { + if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) { + // merge in includes + $this->info[$coll_i][$attr_i] = array_merge( + $this->info[$coll_i][$attr_i], + $attr + ); + continue; + } + $this->info[$coll_i][$attr_i] = $attr; + } + } + } + // perform internal expansions and inclusions + foreach ($this->info as $name => $attr) { + // merge attribute collections that include others + $this->performInclusions($this->info[$name]); + // replace string identifiers with actual attribute objects + $this->expandIdentifiers($this->info[$name], $attr_types); + } + } + + /** + * Takes a reference to an attribute associative array and performs + * all inclusions specified by the zero index. + * @param array &$attr Reference to attribute array + */ + public function performInclusions(&$attr) + { + if (!isset($attr[0])) { + return; + } + $merge = $attr[0]; + $seen = array(); // recursion guard + // loop through all the inclusions + for ($i = 0; isset($merge[$i]); $i++) { + if (isset($seen[$merge[$i]])) { + continue; + } + $seen[$merge[$i]] = true; + // foreach attribute of the inclusion, copy it over + if (!isset($this->info[$merge[$i]])) { + continue; + } + foreach ($this->info[$merge[$i]] as $key => $value) { + if (isset($attr[$key])) { + continue; + } // also catches more inclusions + $attr[$key] = $value; + } + if (isset($this->info[$merge[$i]][0])) { + // recursion + $merge = array_merge($merge, $this->info[$merge[$i]][0]); + } + } + unset($attr[0]); + } + + /** + * Expands all string identifiers in an attribute array by replacing + * them with the appropriate values inside HTMLPurifier_AttrTypes + * @param array &$attr Reference to attribute array + * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance + */ + public function expandIdentifiers(&$attr, $attr_types) + { + // because foreach will process new elements we add, make sure we + // skip duplicates + $processed = array(); + + foreach ($attr as $def_i => $def) { + // skip inclusions + if ($def_i === 0) { + continue; + } + + if (isset($processed[$def_i])) { + continue; + } + + // determine whether or not attribute is required + if ($required = (strpos($def_i, '*') !== false)) { + // rename the definition + unset($attr[$def_i]); + $def_i = trim($def_i, '*'); + $attr[$def_i] = $def; + } + + $processed[$def_i] = true; + + // if we've already got a literal object, move on + if (is_object($def)) { + // preserve previous required + $attr[$def_i]->required = ($required || $attr[$def_i]->required); + continue; + } + + if ($def === false) { + unset($attr[$def_i]); + continue; + } + + if ($t = $attr_types->get($def)) { + $attr[$def_i] = $t; + $attr[$def_i]->required = $required; + } else { + unset($attr[$def_i]); + } + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef.php new file mode 100644 index 0000000..739646f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef.php @@ -0,0 +1,144 @@ + by removing + * leading and trailing whitespace, ignoring line feeds, and replacing + * carriage returns and tabs with spaces. While most useful for HTML + * attributes specified as CDATA, it can also be applied to most CSS + * values. + * + * @note This method is not entirely standards compliant, as trim() removes + * more types of whitespace than specified in the spec. In practice, + * this is rarely a problem, as those extra characters usually have + * already been removed by HTMLPurifier_Encoder. + * + * @warning This processing is inconsistent with XML's whitespace handling + * as specified by section 3.3.3 and referenced XHTML 1.0 section + * 4.7. However, note that we are NOT necessarily + * parsing XML, thus, this behavior may still be correct. We + * assume that newlines have been normalized. + */ + public function parseCDATA($string) + { + $string = trim($string); + $string = str_replace(array("\n", "\t", "\r"), ' ', $string); + return $string; + } + + /** + * Factory method for creating this class from a string. + * @param string $string String construction info + * @return HTMLPurifier_AttrDef Created AttrDef object corresponding to $string + */ + public function make($string) + { + // default implementation, return a flyweight of this object. + // If $string has an effect on the returned object (i.e. you + // need to overload this method), it is best + // to clone or instantiate new copies. (Instantiation is safer.) + return $this; + } + + /** + * Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work + * properly. THIS IS A HACK! + * @param string $string a CSS colour definition + * @return string + */ + protected function mungeRgb($string) + { + $p = '\s*(\d+(\.\d+)?([%]?))\s*'; + + if (preg_match('/(rgba|hsla)\(/', $string)) { + return preg_replace('/(rgba|hsla)\('.$p.','.$p.','.$p.','.$p.'\)/', '\1(\2,\5,\8,\11)', $string); + } + + return preg_replace('/(rgb|hsl)\('.$p.','.$p.','.$p.'\)/', '\1(\2,\5,\8)', $string); + } + + /** + * Parses a possibly escaped CSS string and returns the "pure" + * version of it. + */ + protected function expandCSSEscape($string) + { + // flexibly parse it + $ret = ''; + for ($i = 0, $c = strlen($string); $i < $c; $i++) { + if ($string[$i] === '\\') { + $i++; + if ($i >= $c) { + $ret .= '\\'; + break; + } + if (ctype_xdigit($string[$i])) { + $code = $string[$i]; + for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) { + if (!ctype_xdigit($string[$i])) { + break; + } + $code .= $string[$i]; + } + // We have to be extremely careful when adding + // new characters, to make sure we're not breaking + // the encoding. + $char = HTMLPurifier_Encoder::unichr(hexdec($code)); + if (HTMLPurifier_Encoder::cleanUTF8($char) === '') { + continue; + } + $ret .= $char; + if ($i < $c && trim($string[$i]) !== '') { + $i--; + } + continue; + } + if ($string[$i] === "\n") { + continue; + } + } + $ret .= $string[$i]; + } + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS.php new file mode 100644 index 0000000..af6b8a0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS.php @@ -0,0 +1,140 @@ +parseCDATA($css); + + $definition = $config->getCSSDefinition(); + $allow_duplicates = $config->get("CSS.AllowDuplicates"); + + $universal_attrdef = new HTMLPurifier_AttrDef_Enum( + array( + 'initial', + 'inherit', + 'unset', + ) + ); + + // According to the CSS2.1 spec, the places where a + // non-delimiting semicolon can appear are in strings + // escape sequences. So here is some dumb hack to + // handle quotes. + $len = strlen($css); + $accum = ""; + $declarations = array(); + $quoted = false; + for ($i = 0; $i < $len; $i++) { + $c = strcspn($css, ";'\"", $i); + $accum .= substr($css, $i, $c); + $i += $c; + if ($i == $len) break; + $d = $css[$i]; + if ($quoted) { + $accum .= $d; + if ($d == $quoted) { + $quoted = false; + } + } else { + if ($d == ";") { + $declarations[] = $accum; + $accum = ""; + } else { + $accum .= $d; + $quoted = $d; + } + } + } + if ($accum != "") $declarations[] = $accum; + + $propvalues = array(); + $new_declarations = ''; + + /** + * Name of the current CSS property being validated. + */ + $property = false; + $context->register('CurrentCSSProperty', $property); + + foreach ($declarations as $declaration) { + if (!$declaration) { + continue; + } + if (!strpos($declaration, ':')) { + continue; + } + list($property, $value) = explode(':', $declaration, 2); + $property = trim($property); + $value = trim($value); + $ok = false; + do { + if (isset($definition->info[$property])) { + $ok = true; + break; + } + if (ctype_lower($property)) { + break; + } + $property = strtolower($property); + if (isset($definition->info[$property])) { + $ok = true; + break; + } + } while (0); + if (!$ok) { + continue; + } + $result = $universal_attrdef->validate($value, $config, $context); + if ($result === false) { + $result = $definition->info[$property]->validate( + $value, + $config, + $context + ); + } + if ($result === false) { + continue; + } + if ($allow_duplicates) { + $new_declarations .= "$property:$result;"; + } else { + $propvalues[$property] = $result; + } + } + + $context->destroy('CurrentCSSProperty'); + + // procedure does not write the new CSS simultaneously, so it's + // slightly inefficient, but it's the only way of getting rid of + // duplicates. Perhaps config to optimize it, but not now. + + foreach ($propvalues as $prop => $value) { + $new_declarations .= "$prop:$value;"; + } + + return $new_declarations ? $new_declarations : false; + + } + +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/AlphaValue.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/AlphaValue.php new file mode 100644 index 0000000..af2b83d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/AlphaValue.php @@ -0,0 +1,34 @@ + 1.0) { + $result = '1'; + } + return $result; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Background.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Background.php new file mode 100644 index 0000000..28c4988 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Background.php @@ -0,0 +1,113 @@ +getCSSDefinition(); + $this->info['background-color'] = $def->info['background-color']; + $this->info['background-image'] = $def->info['background-image']; + $this->info['background-repeat'] = $def->info['background-repeat']; + $this->info['background-attachment'] = $def->info['background-attachment']; + $this->info['background-position'] = $def->info['background-position']; + $this->info['background-size'] = $def->info['background-size']; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + // regular pre-processing + $string = $this->parseCDATA($string); + if ($string === '') { + return false; + } + + // munge rgb() decl if necessary + $string = $this->mungeRgb($string); + + // assumes URI doesn't have spaces in it + $bits = explode(' ', $string); // bits to process + + $caught = array(); + $caught['color'] = false; + $caught['image'] = false; + $caught['repeat'] = false; + $caught['attachment'] = false; + $caught['position'] = false; + $caught['size'] = false; + + $i = 0; // number of catches + + foreach ($bits as $bit) { + if ($bit === '') { + continue; + } + foreach ($caught as $key => $status) { + if ($key != 'position') { + if ($status !== false) { + continue; + } + $r = $this->info['background-' . $key]->validate($bit, $config, $context); + } else { + $r = $bit; + } + if ($r === false) { + continue; + } + if ($key == 'position') { + if ($caught[$key] === false) { + $caught[$key] = ''; + } + $caught[$key] .= $r . ' '; + } else { + $caught[$key] = $r; + } + $i++; + break; + } + } + + if (!$i) { + return false; + } + if ($caught['position'] !== false) { + $caught['position'] = $this->info['background-position']-> + validate($caught['position'], $config, $context); + } + + $ret = array(); + foreach ($caught as $value) { + if ($value === false) { + continue; + } + $ret[] = $value; + } + + if (empty($ret)) { + return false; + } + return implode(' ', $ret); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php new file mode 100644 index 0000000..4580ef5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php @@ -0,0 +1,157 @@ + | | left | center | right + ] + [ + | | top | center | bottom + ]? + ] | + [ // this signifies that the vertical and horizontal adjectives + // can be arbitrarily ordered, however, there can only be two, + // one of each, or none at all + [ + left | center | right + ] || + [ + top | center | bottom + ] + ] + top, left = 0% + center, (none) = 50% + bottom, right = 100% +*/ + +/* QuirksMode says: + keyword + length/percentage must be ordered correctly, as per W3C + + Internet Explorer and Opera, however, support arbitrary ordering. We + should fix it up. + + Minor issue though, not strictly necessary. +*/ + +// control freaks may appreciate the ability to convert these to +// percentages or something, but it's not necessary + +/** + * Validates the value of background-position. + */ +class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef +{ + + /** + * @type HTMLPurifier_AttrDef_CSS_Length + */ + protected $length; + + /** + * @type HTMLPurifier_AttrDef_CSS_Percentage + */ + protected $percentage; + + public function __construct() + { + $this->length = new HTMLPurifier_AttrDef_CSS_Length(); + $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage(); + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $string = $this->parseCDATA($string); + $bits = explode(' ', $string); + + $keywords = array(); + $keywords['h'] = false; // left, right + $keywords['v'] = false; // top, bottom + $keywords['ch'] = false; // center (first word) + $keywords['cv'] = false; // center (second word) + $measures = array(); + + $i = 0; + + $lookup = array( + 'top' => 'v', + 'bottom' => 'v', + 'left' => 'h', + 'right' => 'h', + 'center' => 'c' + ); + + foreach ($bits as $bit) { + if ($bit === '') { + continue; + } + + // test for keyword + $lbit = ctype_lower($bit) ? $bit : strtolower($bit); + if (isset($lookup[$lbit])) { + $status = $lookup[$lbit]; + if ($status == 'c') { + if ($i == 0) { + $status = 'ch'; + } else { + $status = 'cv'; + } + } + $keywords[$status] = $lbit; + $i++; + } + + // test for length + $r = $this->length->validate($bit, $config, $context); + if ($r !== false) { + $measures[] = $r; + $i++; + } + + // test for percentage + $r = $this->percentage->validate($bit, $config, $context); + if ($r !== false) { + $measures[] = $r; + $i++; + } + } + + if (!$i) { + return false; + } // no valid values were caught + + $ret = array(); + + // first keyword + if ($keywords['h']) { + $ret[] = $keywords['h']; + } elseif ($keywords['ch']) { + $ret[] = $keywords['ch']; + $keywords['cv'] = false; // prevent re-use: center = center center + } elseif (count($measures)) { + $ret[] = array_shift($measures); + } + + if ($keywords['v']) { + $ret[] = $keywords['v']; + } elseif ($keywords['cv']) { + $ret[] = $keywords['cv']; + } elseif (count($measures)) { + $ret[] = array_shift($measures); + } + + if (empty($ret)) { + return false; + } + return implode(' ', $ret); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Border.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Border.php new file mode 100644 index 0000000..16243ba --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Border.php @@ -0,0 +1,56 @@ +getCSSDefinition(); + $this->info['border-width'] = $def->info['border-width']; + $this->info['border-style'] = $def->info['border-style']; + $this->info['border-top-color'] = $def->info['border-top-color']; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $string = $this->parseCDATA($string); + $string = $this->mungeRgb($string); + $bits = explode(' ', $string); + $done = array(); // segments we've finished + $ret = ''; // return value + foreach ($bits as $bit) { + foreach ($this->info as $propname => $validator) { + if (isset($done[$propname])) { + continue; + } + $r = $validator->validate($bit, $config, $context); + if ($r !== false) { + $ret .= $r . ' '; + $done[$propname] = true; + break; + } + } + } + return rtrim($ret); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Color.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Color.php new file mode 100644 index 0000000..d7287a0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Color.php @@ -0,0 +1,161 @@ +alpha = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + } + + /** + * @param string $color + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($color, $config, $context) + { + static $colors = null; + if ($colors === null) { + $colors = $config->get('Core.ColorKeywords'); + } + + $color = trim($color); + if ($color === '') { + return false; + } + + $lower = strtolower($color); + if (isset($colors[$lower])) { + return $colors[$lower]; + } + + if (preg_match('#(rgb|rgba|hsl|hsla)\(#', $color, $matches) === 1) { + $length = strlen($color); + if (strpos($color, ')') !== $length - 1) { + return false; + } + + // get used function : rgb, rgba, hsl or hsla + $function = $matches[1]; + + $parameters_size = 3; + $alpha_channel = false; + if (substr($function, -1) === 'a') { + $parameters_size = 4; + $alpha_channel = true; + } + + /* + * Allowed types for values : + * parameter_position => [type => max_value] + */ + $allowed_types = array( + 1 => array('percentage' => 100, 'integer' => 255), + 2 => array('percentage' => 100, 'integer' => 255), + 3 => array('percentage' => 100, 'integer' => 255), + ); + $allow_different_types = false; + + if (strpos($function, 'hsl') !== false) { + $allowed_types = array( + 1 => array('integer' => 360), + 2 => array('percentage' => 100), + 3 => array('percentage' => 100), + ); + $allow_different_types = true; + } + + $values = trim(str_replace($function, '', $color), ' ()'); + + $parts = explode(',', $values); + if (count($parts) !== $parameters_size) { + return false; + } + + $type = false; + $new_parts = array(); + $i = 0; + + foreach ($parts as $part) { + $i++; + $part = trim($part); + + if ($part === '') { + return false; + } + + // different check for alpha channel + if ($alpha_channel === true && $i === count($parts)) { + $result = $this->alpha->validate($part, $config, $context); + + if ($result === false) { + return false; + } + + $new_parts[] = (string)$result; + continue; + } + + if (substr($part, -1) === '%') { + $current_type = 'percentage'; + } else { + $current_type = 'integer'; + } + + if (!array_key_exists($current_type, $allowed_types[$i])) { + return false; + } + + if (!$type) { + $type = $current_type; + } + + if ($allow_different_types === false && $type != $current_type) { + return false; + } + + $max_value = $allowed_types[$i][$current_type]; + + if ($current_type == 'integer') { + // Return value between range 0 -> $max_value + $new_parts[] = (int)max(min($part, $max_value), 0); + } elseif ($current_type == 'percentage') { + $new_parts[] = (float)max(min(rtrim($part, '%'), $max_value), 0) . '%'; + } + } + + $new_values = implode(',', $new_parts); + + $color = $function . '(' . $new_values . ')'; + } else { + // hexadecimal handling + if ($color[0] === '#') { + $hex = substr($color, 1); + } else { + $hex = $color; + $color = '#' . $color; + } + $length = strlen($hex); + if ($length !== 3 && $length !== 6) { + return false; + } + if (!ctype_xdigit($hex)) { + return false; + } + } + return $color; + } + +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Composite.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Composite.php new file mode 100644 index 0000000..9c17505 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Composite.php @@ -0,0 +1,48 @@ +defs = $defs; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + foreach ($this->defs as $i => $def) { + $result = $this->defs[$i]->validate($string, $config, $context); + if ($result !== false) { + return $result; + } + } + return false; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php new file mode 100644 index 0000000..9d77cc9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/DenyElementDecorator.php @@ -0,0 +1,44 @@ +def = $def; + $this->element = $element; + } + + /** + * Checks if CurrentToken is set and equal to $this->element + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $token = $context->get('CurrentToken', true); + if ($token && $token->name == $this->element) { + return false; + } + return $this->def->validate($string, $config, $context); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Filter.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Filter.php new file mode 100644 index 0000000..bde4c33 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Filter.php @@ -0,0 +1,77 @@ +intValidator = new HTMLPurifier_AttrDef_Integer(); + } + + /** + * @param string $value + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($value, $config, $context) + { + $value = $this->parseCDATA($value); + if ($value === 'none') { + return $value; + } + // if we looped this we could support multiple filters + $function_length = strcspn($value, '('); + $function = trim(substr($value, 0, $function_length)); + if ($function !== 'alpha' && + $function !== 'Alpha' && + $function !== 'progid:DXImageTransform.Microsoft.Alpha' + ) { + return false; + } + $cursor = $function_length + 1; + $parameters_length = strcspn($value, ')', $cursor); + $parameters = substr($value, $cursor, $parameters_length); + $params = explode(',', $parameters); + $ret_params = array(); + $lookup = array(); + foreach ($params as $param) { + list($key, $value) = explode('=', $param); + $key = trim($key); + $value = trim($value); + if (isset($lookup[$key])) { + continue; + } + if ($key !== 'opacity') { + continue; + } + $value = $this->intValidator->validate($value, $config, $context); + if ($value === false) { + continue; + } + $int = (int)$value; + if ($int > 100) { + $value = '100'; + } + if ($int < 0) { + $value = '0'; + } + $ret_params[] = "$key=$value"; + $lookup[$key] = true; + } + $ret_parameters = implode(',', $ret_params); + $ret_function = "$function($ret_parameters)"; + return $ret_function; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Font.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Font.php new file mode 100644 index 0000000..579b97e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Font.php @@ -0,0 +1,176 @@ +getCSSDefinition(); + $this->info['font-style'] = $def->info['font-style']; + $this->info['font-variant'] = $def->info['font-variant']; + $this->info['font-weight'] = $def->info['font-weight']; + $this->info['font-size'] = $def->info['font-size']; + $this->info['line-height'] = $def->info['line-height']; + $this->info['font-family'] = $def->info['font-family']; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + static $system_fonts = array( + 'caption' => true, + 'icon' => true, + 'menu' => true, + 'message-box' => true, + 'small-caption' => true, + 'status-bar' => true + ); + + // regular pre-processing + $string = $this->parseCDATA($string); + if ($string === '') { + return false; + } + + // check if it's one of the keywords + $lowercase_string = strtolower($string); + if (isset($system_fonts[$lowercase_string])) { + return $lowercase_string; + } + + $bits = explode(' ', $string); // bits to process + $stage = 0; // this indicates what we're looking for + $caught = array(); // which stage 0 properties have we caught? + $stage_1 = array('font-style', 'font-variant', 'font-weight'); + $final = ''; // output + + for ($i = 0, $size = count($bits); $i < $size; $i++) { + if ($bits[$i] === '') { + continue; + } + switch ($stage) { + case 0: // attempting to catch font-style, font-variant or font-weight + foreach ($stage_1 as $validator_name) { + if (isset($caught[$validator_name])) { + continue; + } + $r = $this->info[$validator_name]->validate( + $bits[$i], + $config, + $context + ); + if ($r !== false) { + $final .= $r . ' '; + $caught[$validator_name] = true; + break; + } + } + // all three caught, continue on + if (count($caught) >= 3) { + $stage = 1; + } + if ($r !== false) { + break; + } + case 1: // attempting to catch font-size and perhaps line-height + $found_slash = false; + if (strpos($bits[$i], '/') !== false) { + list($font_size, $line_height) = + explode('/', $bits[$i]); + if ($line_height === '') { + // ooh, there's a space after the slash! + $line_height = false; + $found_slash = true; + } + } else { + $font_size = $bits[$i]; + $line_height = false; + } + $r = $this->info['font-size']->validate( + $font_size, + $config, + $context + ); + if ($r !== false) { + $final .= $r; + // attempt to catch line-height + if ($line_height === false) { + // we need to scroll forward + for ($j = $i + 1; $j < $size; $j++) { + if ($bits[$j] === '') { + continue; + } + if ($bits[$j] === '/') { + if ($found_slash) { + return false; + } else { + $found_slash = true; + continue; + } + } + $line_height = $bits[$j]; + break; + } + } else { + // slash already found + $found_slash = true; + $j = $i; + } + if ($found_slash) { + $i = $j; + $r = $this->info['line-height']->validate( + $line_height, + $config, + $context + ); + if ($r !== false) { + $final .= '/' . $r; + } + } + $final .= ' '; + $stage = 2; + break; + } + return false; + case 2: // attempting to catch font-family + $font_family = + implode(' ', array_slice($bits, $i, $size - $i)); + $r = $this->info['font-family']->validate( + $font_family, + $config, + $context + ); + if ($r !== false) { + $final .= $r . ' '; + // processing completed successfully + return rtrim($final); + } + return false; + } + } + return false; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/FontFamily.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/FontFamily.php new file mode 100644 index 0000000..f1ff116 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/FontFamily.php @@ -0,0 +1,217 @@ +mask = array_reduce($c, function ($carry, $value) { + return $carry . $value; + }, '_- '); + + /* + PHP's internal strcspn implementation is + O(length of string * length of mask), making it inefficient + for large masks. However, it's still faster than + preg_match 8) + for (p = s1;;) { + spanp = s2; + do { + if (*spanp == c || p == s1_end) { + return p - s1; + } + } while (spanp++ < (s2_end - 1)); + c = *++p; + } + */ + // possible optimization: invert the mask. + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + static $generic_names = array( + 'serif' => true, + 'sans-serif' => true, + 'monospace' => true, + 'fantasy' => true, + 'cursive' => true + ); + $allowed_fonts = $config->get('CSS.AllowedFonts'); + + // assume that no font names contain commas in them + $fonts = explode(',', $string); + $final = ''; + foreach ($fonts as $font) { + $font = trim($font); + if ($font === '') { + continue; + } + // match a generic name + if (isset($generic_names[$font])) { + if ($allowed_fonts === null || isset($allowed_fonts[$font])) { + $final .= $font . ', '; + } + continue; + } + // match a quoted name + if ($font[0] === '"' || $font[0] === "'") { + $length = strlen($font); + if ($length <= 2) { + continue; + } + $quote = $font[0]; + if ($font[$length - 1] !== $quote) { + continue; + } + $font = substr($font, 1, $length - 2); + } + + $font = $this->expandCSSEscape($font); + + // $font is a pure representation of the font name + + if ($allowed_fonts !== null && !isset($allowed_fonts[$font])) { + continue; + } + + if (ctype_alnum($font) && $font !== '') { + // very simple font, allow it in unharmed + $final .= $font . ', '; + continue; + } + + // bugger out on whitespace. form feed (0C) really + // shouldn't show up regardless + $font = str_replace(array("\n", "\t", "\r", "\x0C"), ' ', $font); + + // Here, there are various classes of characters which need + // to be treated differently: + // - Alphanumeric characters are essentially safe. We + // handled these above. + // - Spaces require quoting, though most parsers will do + // the right thing if there aren't any characters that + // can be misinterpreted + // - Dashes rarely occur, but they fairly unproblematic + // for parsing/rendering purposes. + // The above characters cover the majority of Western font + // names. + // - Arbitrary Unicode characters not in ASCII. Because + // most parsers give little thought to Unicode, treatment + // of these codepoints is basically uniform, even for + // punctuation-like codepoints. These characters can + // show up in non-Western pages and are supported by most + // major browsers, for example: "ï¼­ï¼³ 明æœ" is a + // legitimate font-name + // . See + // the CSS3 spec for more examples: + // + // You can see live samples of these on the Internet: + // + // However, most of these fonts have ASCII equivalents: + // for example, 'MS Mincho', and it's considered + // professional to use ASCII font names instead of + // Unicode font names. Thanks Takeshi Terada for + // providing this information. + // The following characters, to my knowledge, have not been + // used to name font names. + // - Single quote. While theoretically you might find a + // font name that has a single quote in its name (serving + // as an apostrophe, e.g. Dave's Scribble), I haven't + // been able to find any actual examples of this. + // Internet Explorer's cssText translation (which I + // believe is invoked by innerHTML) normalizes any + // quoting to single quotes, and fails to escape single + // quotes. (Note that this is not IE's behavior for all + // CSS properties, just some sort of special casing for + // font-family). So a single quote *cannot* be used + // safely in the font-family context if there will be an + // innerHTML/cssText translation. Note that Firefox 3.x + // does this too. + // - Double quote. In IE, these get normalized to + // single-quotes, no matter what the encoding. (Fun + // fact, in IE8, the 'content' CSS property gained + // support, where they special cased to preserve encoded + // double quotes, but still translate unadorned double + // quotes into single quotes.) So, because their + // fixpoint behavior is identical to single quotes, they + // cannot be allowed either. Firefox 3.x displays + // single-quote style behavior. + // - Backslashes are reduced by one (so \\ -> \) every + // iteration, so they cannot be used safely. This shows + // up in IE7, IE8 and FF3 + // - Semicolons, commas and backticks are handled properly. + // - The rest of the ASCII punctuation is handled properly. + // We haven't checked what browsers do to unadorned + // versions, but this is not important as long as the + // browser doesn't /remove/ surrounding quotes (as IE does + // for HTML). + // + // With these results in hand, we conclude that there are + // various levels of safety: + // - Paranoid: alphanumeric, spaces and dashes(?) + // - International: Paranoid + non-ASCII Unicode + // - Edgy: Everything except quotes, backslashes + // - NoJS: Standards compliance, e.g. sod IE. Note that + // with some judicious character escaping (since certain + // types of escaping doesn't work) this is theoretically + // OK as long as innerHTML/cssText is not called. + // We believe that international is a reasonable default + // (that we will implement now), and once we do more + // extensive research, we may feel comfortable with dropping + // it down to edgy. + + // Edgy: alphanumeric, spaces, dashes, underscores and Unicode. Use of + // str(c)spn assumes that the string was already well formed + // Unicode (which of course it is). + if (strspn($font, $this->mask) !== strlen($font)) { + continue; + } + + // Historical: + // In the absence of innerHTML/cssText, these ugly + // transforms don't pose a security risk (as \\ and \" + // might--these escapes are not supported by most browsers). + // We could try to be clever and use single-quote wrapping + // when there is a double quote present, but I have choosen + // not to implement that. (NOTE: you can reduce the amount + // of escapes by one depending on what quoting style you use) + // $font = str_replace('\\', '\\5C ', $font); + // $font = str_replace('"', '\\22 ', $font); + // $font = str_replace("'", '\\27 ', $font); + + // font possibly with spaces, requires quoting + $final .= "'$font', "; + } + $final = rtrim($final, ', '); + if ($final === '') { + return false; + } + return $final; + } + +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Ident.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Ident.php new file mode 100644 index 0000000..973002c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Ident.php @@ -0,0 +1,32 @@ +def = $def; + $this->allow = $allow; + } + + /** + * Intercepts and removes !important if necessary + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + // test for ! and important tokens + $string = trim($string); + $is_important = false; + // :TODO: optimization: test directly for !important and ! important + if (strlen($string) >= 9 && substr($string, -9) === 'important') { + $temp = rtrim(substr($string, 0, -9)); + // use a temp, because we might want to restore important + if (strlen($temp) >= 1 && substr($temp, -1) === '!') { + $string = rtrim(substr($temp, 0, -1)); + $is_important = true; + } + } + $string = $this->def->validate($string, $config, $context); + if ($this->allow && $is_important) { + $string .= ' !important'; + } + return $string; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Length.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Length.php new file mode 100644 index 0000000..f12453a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Length.php @@ -0,0 +1,77 @@ +min = $min !== null ? HTMLPurifier_Length::make($min) : null; + $this->max = $max !== null ? HTMLPurifier_Length::make($max) : null; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $string = $this->parseCDATA($string); + + // Optimizations + if ($string === '') { + return false; + } + if ($string === '0') { + return '0'; + } + if (strlen($string) === 1) { + return false; + } + + $length = HTMLPurifier_Length::make($string); + if (!$length->isValid()) { + return false; + } + + if ($this->min) { + $c = $length->compareTo($this->min); + if ($c === false) { + return false; + } + if ($c < 0) { + return false; + } + } + if ($this->max) { + $c = $length->compareTo($this->max); + if ($c === false) { + return false; + } + if ($c > 0) { + return false; + } + } + return $length->toString(); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/ListStyle.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/ListStyle.php new file mode 100644 index 0000000..e74d426 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/ListStyle.php @@ -0,0 +1,112 @@ +getCSSDefinition(); + $this->info['list-style-type'] = $def->info['list-style-type']; + $this->info['list-style-position'] = $def->info['list-style-position']; + $this->info['list-style-image'] = $def->info['list-style-image']; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + // regular pre-processing + $string = $this->parseCDATA($string); + if ($string === '') { + return false; + } + + // assumes URI doesn't have spaces in it + $bits = explode(' ', strtolower($string)); // bits to process + + $caught = array(); + $caught['type'] = false; + $caught['position'] = false; + $caught['image'] = false; + + $i = 0; // number of catches + $none = false; + + foreach ($bits as $bit) { + if ($i >= 3) { + return; + } // optimization bit + if ($bit === '') { + continue; + } + foreach ($caught as $key => $status) { + if ($status !== false) { + continue; + } + $r = $this->info['list-style-' . $key]->validate($bit, $config, $context); + if ($r === false) { + continue; + } + if ($r === 'none') { + if ($none) { + continue; + } else { + $none = true; + } + if ($key == 'image') { + continue; + } + } + $caught[$key] = $r; + $i++; + break; + } + } + + if (!$i) { + return false; + } + + $ret = array(); + + // construct type + if ($caught['type']) { + $ret[] = $caught['type']; + } + + // construct image + if ($caught['image']) { + $ret[] = $caught['image']; + } + + // construct position + if ($caught['position']) { + $ret[] = $caught['position']; + } + + if (empty($ret)) { + return false; + } + return implode(' ', $ret); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Multiple.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Multiple.php new file mode 100644 index 0000000..e707f87 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Multiple.php @@ -0,0 +1,71 @@ +single = $single; + $this->max = $max; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $string = $this->mungeRgb($this->parseCDATA($string)); + if ($string === '') { + return false; + } + $parts = explode(' ', $string); // parseCDATA replaced \r, \t and \n + $length = count($parts); + $final = ''; + for ($i = 0, $num = 0; $i < $length && $num < $this->max; $i++) { + if (ctype_space($parts[$i])) { + continue; + } + $result = $this->single->validate($parts[$i], $config, $context); + if ($result !== false) { + $final .= $result . ' '; + $num++; + } + } + if ($final === '') { + return false; + } + return rtrim($final); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Number.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Number.php new file mode 100644 index 0000000..ef49d20 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Number.php @@ -0,0 +1,90 @@ +non_negative = $non_negative; + } + + /** + * @param string $number + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string|bool + * @warning Some contexts do not pass $config, $context. These + * variables should not be used without checking HTMLPurifier_Length + */ + public function validate($number, $config, $context) + { + $number = $this->parseCDATA($number); + + if ($number === '') { + return false; + } + if ($number === '0') { + return '0'; + } + + $sign = ''; + switch ($number[0]) { + case '-': + if ($this->non_negative) { + return false; + } + $sign = '-'; + case '+': + $number = substr($number, 1); + } + + if (ctype_digit($number)) { + $number = ltrim($number, '0'); + return $number ? $sign . $number : '0'; + } + + // Period is the only non-numeric character allowed + if (strpos($number, '.') === false) { + return false; + } + + list($left, $right) = explode('.', $number, 2); + + if ($left === '' && $right === '') { + return false; + } + if ($left !== '' && !ctype_digit($left)) { + return false; + } + + // Remove leading zeros until positive number or a zero stays left + if (ltrim($left, '0') != '') { + $left = ltrim($left, '0'); + } else { + $left = '0'; + } + + $right = rtrim($right, '0'); + + if ($right === '') { + return $left ? $sign . $left : '0'; + } elseif (!ctype_digit($right)) { + return false; + } + return $sign . $left . '.' . $right; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Percentage.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Percentage.php new file mode 100644 index 0000000..f0f25c5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Percentage.php @@ -0,0 +1,54 @@ +number_def = new HTMLPurifier_AttrDef_CSS_Number($non_negative); + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $string = $this->parseCDATA($string); + + if ($string === '') { + return false; + } + $length = strlen($string); + if ($length === 1) { + return false; + } + if ($string[$length - 1] !== '%') { + return false; + } + + $number = substr($string, 0, $length - 1); + $number = $this->number_def->validate($number, $config, $context); + + if ($number === false) { + return false; + } + return "$number%"; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Ratio.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Ratio.php new file mode 100644 index 0000000..e08e2c4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/Ratio.php @@ -0,0 +1,46 @@ +parseCDATA($ratio); + + $parts = explode('/', $ratio, 2); + $length = count($parts); + + if ($length < 1 || $length > 2) { + return false; + } + + $num = new \HTMLPurifier_AttrDef_CSS_Number(); + + if ($length === 1) { + return $num->validate($parts[0], $config, $context); + } + + $num1 = $num->validate($parts[0], $config, $context); + $num2 = $num->validate($parts[1], $config, $context); + + if ($num1 === false || $num2 === false) { + return false; + } + + return $num1 . '/' . $num2; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/TextDecoration.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/TextDecoration.php new file mode 100644 index 0000000..5fd4b7f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/TextDecoration.php @@ -0,0 +1,46 @@ + true, + 'overline' => true, + 'underline' => true, + ); + + $string = strtolower($this->parseCDATA($string)); + + if ($string === 'none') { + return $string; + } + + $parts = explode(' ', $string); + $final = ''; + foreach ($parts as $part) { + if (isset($allowed_values[$part])) { + $final .= $part . ' '; + } + } + $final = rtrim($final); + if ($final === '') { + return false; + } + return $final; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/URI.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/URI.php new file mode 100644 index 0000000..6617aca --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/CSS/URI.php @@ -0,0 +1,77 @@ +parseCDATA($uri_string); + if (strpos($uri_string, 'url(') !== 0) { + return false; + } + $uri_string = substr($uri_string, 4); + if (strlen($uri_string) == 0) { + return false; + } + $new_length = strlen($uri_string) - 1; + if ($uri_string[$new_length] != ')') { + return false; + } + $uri = trim(substr($uri_string, 0, $new_length)); + + if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) { + $quote = $uri[0]; + $new_length = strlen($uri) - 1; + if ($uri[$new_length] !== $quote) { + return false; + } + $uri = substr($uri, 1, $new_length - 1); + } + + $uri = $this->expandCSSEscape($uri); + + $result = parent::validate($uri, $config, $context); + + if ($result === false) { + return false; + } + + // extra sanity check; should have been done by URI + $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result); + + // suspicious characters are ()'; we're going to percent encode + // them for safety. + $result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result); + + // there's an extra bug where ampersands lose their escaping on + // an innerHTML cycle, so a very unlucky query parameter could + // then change the meaning of the URL. Unfortunately, there's + // not much we can do about that... + return "url(\"$result\")"; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Clone.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Clone.php new file mode 100644 index 0000000..6698a00 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Clone.php @@ -0,0 +1,44 @@ +clone = $clone; + } + + /** + * @param string $v + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($v, $config, $context) + { + return $this->clone->validate($v, $config, $context); + } + + /** + * @param string $string + * @return HTMLPurifier_AttrDef + */ + public function make($string) + { + return clone $this->clone; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Enum.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Enum.php new file mode 100644 index 0000000..8abda7f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Enum.php @@ -0,0 +1,73 @@ +valid_values = array_flip($valid_values); + $this->case_sensitive = $case_sensitive; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $string = trim($string); + if (!$this->case_sensitive) { + // we may want to do full case-insensitive libraries + $string = ctype_lower($string) ? $string : strtolower($string); + } + $result = isset($this->valid_values[$string]); + + return $result ? $string : false; + } + + /** + * @param string $string In form of comma-delimited list of case-insensitive + * valid values. Example: "foo,bar,baz". Prepend "s:" to make + * case sensitive + * @return HTMLPurifier_AttrDef_Enum + */ + public function make($string) + { + if (strlen($string) > 2 && $string[0] == 's' && $string[1] == ':') { + $string = substr($string, 2); + $sensitive = true; + } else { + $sensitive = false; + } + $values = explode(',', $string); + return new HTMLPurifier_AttrDef_Enum($values, $sensitive); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Bool.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Bool.php new file mode 100644 index 0000000..be3bbc8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Bool.php @@ -0,0 +1,48 @@ +name = $name; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + return $this->name; + } + + /** + * @param string $string Name of attribute + * @return HTMLPurifier_AttrDef_HTML_Bool + */ + public function make($string) + { + return new HTMLPurifier_AttrDef_HTML_Bool($string); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Class.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Class.php new file mode 100644 index 0000000..d501348 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Class.php @@ -0,0 +1,48 @@ +getDefinition('HTML')->doctype->name; + if ($name == "XHTML 1.1" || $name == "XHTML 2.0") { + return parent::split($string, $config, $context); + } else { + return preg_split('/\s+/', $string); + } + } + + /** + * @param array $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + protected function filter($tokens, $config, $context) + { + $allowed = $config->get('Attr.AllowedClasses'); + $forbidden = $config->get('Attr.ForbiddenClasses'); + $ret = array(); + foreach ($tokens as $token) { + if (($allowed === null || isset($allowed[$token])) && + !isset($forbidden[$token]) && + // We need this O(n) check because of PHP's array + // implementation that casts -0 to 0. + !in_array($token, $ret, true) + ) { + $ret[] = $token; + } + } + return $ret; + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Color.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Color.php new file mode 100644 index 0000000..946ebb7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Color.php @@ -0,0 +1,51 @@ +get('Core.ColorKeywords'); + } + + $string = trim($string); + + if (empty($string)) { + return false; + } + $lower = strtolower($string); + if (isset($colors[$lower])) { + return $colors[$lower]; + } + if ($string[0] === '#') { + $hex = substr($string, 1); + } else { + $hex = $string; + } + + $length = strlen($hex); + if ($length !== 3 && $length !== 6) { + return false; + } + if (!ctype_xdigit($hex)) { + return false; + } + if ($length === 3) { + $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; + } + return "#$hex"; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/ContentEditable.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/ContentEditable.php new file mode 100644 index 0000000..5b03d3e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/ContentEditable.php @@ -0,0 +1,16 @@ +get('HTML.Trusted')) { + $allowed = array('', 'true', 'false'); + } + + $enum = new HTMLPurifier_AttrDef_Enum($allowed); + + return $enum->validate($string, $config, $context); + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/FrameTarget.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/FrameTarget.php new file mode 100644 index 0000000..d79ba12 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/FrameTarget.php @@ -0,0 +1,38 @@ +valid_values === false) { + $this->valid_values = $config->get('Attr.AllowedFrameTargets'); + } + return parent::validate($string, $config, $context); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/ID.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/ID.php new file mode 100644 index 0000000..4ba4561 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/ID.php @@ -0,0 +1,113 @@ +selector = $selector; + } + + /** + * @param string $id + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($id, $config, $context) + { + if (!$this->selector && !$config->get('Attr.EnableID')) { + return false; + } + + $id = trim($id); // trim it first + + if ($id === '') { + return false; + } + + $prefix = $config->get('Attr.IDPrefix'); + if ($prefix !== '') { + $prefix .= $config->get('Attr.IDPrefixLocal'); + // prevent re-appending the prefix + if (strpos($id, $prefix) !== 0) { + $id = $prefix . $id; + } + } elseif ($config->get('Attr.IDPrefixLocal') !== '') { + trigger_error( + '%Attr.IDPrefixLocal cannot be used unless ' . + '%Attr.IDPrefix is set', + E_USER_WARNING + ); + } + + if (!$this->selector) { + $id_accumulator =& $context->get('IDAccumulator'); + if (isset($id_accumulator->ids[$id])) { + return false; + } + } + + // we purposely avoid using regex, hopefully this is faster + + if ($config->get('Attr.ID.HTML5') === true) { + if (preg_match('/[\t\n\x0b\x0c ]/', $id)) { + return false; + } + } else { + if (ctype_alpha($id)) { + // OK + } else { + if (!ctype_alpha(@$id[0])) { + return false; + } + // primitive style of regexps, I suppose + $trim = trim( + $id, + 'A..Za..z0..9:-._' + ); + if ($trim !== '') { + return false; + } + } + } + + $regexp = $config->get('Attr.IDBlacklistRegexp'); + if ($regexp && preg_match($regexp, $id)) { + return false; + } + + if (!$this->selector) { + $id_accumulator->add($id); + } + + // if no change was made to the ID, return the result + // else, return the new id if stripping whitespace made it + // valid, or return false. + return $id; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Length.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Length.php new file mode 100644 index 0000000..1c4006f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Length.php @@ -0,0 +1,56 @@ + 100) { + return '100%'; + } + return ((string)$points) . '%'; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/LinkTypes.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/LinkTypes.php new file mode 100644 index 0000000..63fa04c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/LinkTypes.php @@ -0,0 +1,72 @@ + 'AllowedRel', + 'rev' => 'AllowedRev' + ); + if (!isset($configLookup[$name])) { + trigger_error( + 'Unrecognized attribute name for link ' . + 'relationship.', + E_USER_ERROR + ); + return; + } + $this->name = $configLookup[$name]; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $allowed = $config->get('Attr.' . $this->name); + if (empty($allowed)) { + return false; + } + + $string = $this->parseCDATA($string); + $parts = explode(' ', $string); + + // lookup to prevent duplicates + $ret_lookup = array(); + foreach ($parts as $part) { + $part = strtolower(trim($part)); + if (!isset($allowed[$part])) { + continue; + } + $ret_lookup[$part] = true; + } + + if (empty($ret_lookup)) { + return false; + } + $string = implode(' ', array_keys($ret_lookup)); + return $string; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/MultiLength.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/MultiLength.php new file mode 100644 index 0000000..bbb20f2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/MultiLength.php @@ -0,0 +1,60 @@ +split($string, $config, $context); + $tokens = $this->filter($tokens, $config, $context); + if (empty($tokens)) { + return false; + } + return implode(' ', $tokens); + } + + /** + * Splits a space separated list of tokens into its constituent parts. + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + protected function split($string, $config, $context) + { + // OPTIMIZABLE! + // do the preg_match, capture all subpatterns for reformulation + + // we don't support U+00A1 and up codepoints or + // escaping because I don't know how to do that with regexps + // and plus it would complicate optimization efforts (you never + // see that anyway). + $pattern = '/(?:(?<=\s)|\A)' . // look behind for space or string start + '((?:--|-?[A-Za-z_])[A-Za-z_\-0-9]*)' . + '(?:(?=\s)|\z)/'; // look ahead for space or string end + preg_match_all($pattern, $string, $matches); + return $matches[1]; + } + + /** + * Template method for removing certain tokens based on arbitrary criteria. + * @note If we wanted to be really functional, we'd do an array_filter + * with a callback. But... we're not. + * @param array $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + protected function filter($tokens, $config, $context) + { + return $tokens; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Pixels.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Pixels.php new file mode 100644 index 0000000..a1d019e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/HTML/Pixels.php @@ -0,0 +1,76 @@ +max = $max; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $string = trim($string); + if ($string === '0') { + return $string; + } + if ($string === '') { + return false; + } + $length = strlen($string); + if (substr($string, $length - 2) == 'px') { + $string = substr($string, 0, $length - 2); + } + if (!is_numeric($string)) { + return false; + } + $int = (int)$string; + + if ($int < 0) { + return '0'; + } + + // upper-bound value, extremely high values can + // crash operating systems, see + // WARNING, above link WILL crash you if you're using Windows + + if ($this->max !== null && $int > $this->max) { + return (string)$this->max; + } + return (string)$int; + } + + /** + * @param string $string + * @return HTMLPurifier_AttrDef + */ + public function make($string) + { + if ($string === '') { + $max = null; + } else { + $max = (int)$string; + } + $class = get_class($this); + return new $class($max); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Integer.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Integer.php new file mode 100644 index 0000000..400e707 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Integer.php @@ -0,0 +1,91 @@ +negative = $negative; + $this->zero = $zero; + $this->positive = $positive; + } + + /** + * @param string $integer + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($integer, $config, $context) + { + $integer = $this->parseCDATA($integer); + if ($integer === '') { + return false; + } + + // we could possibly simply typecast it to integer, but there are + // certain fringe cases that must not return an integer. + + // clip leading sign + if ($this->negative && $integer[0] === '-') { + $digits = substr($integer, 1); + if ($digits === '0') { + $integer = '0'; + } // rm minus sign for zero + } elseif ($this->positive && $integer[0] === '+') { + $digits = $integer = substr($integer, 1); // rm unnecessary plus + } else { + $digits = $integer; + } + + // test if it's numeric + if (!ctype_digit($digits)) { + return false; + } + + // perform scope tests + if (!$this->zero && $integer == 0) { + return false; + } + if (!$this->positive && $integer > 0) { + return false; + } + if (!$this->negative && $integer < 0) { + return false; + } + + return $integer; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Lang.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Lang.php new file mode 100644 index 0000000..2a55cea --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Lang.php @@ -0,0 +1,86 @@ + 8 || !ctype_alnum($subtags[1])) { + return $new_string; + } + if (!ctype_lower($subtags[1])) { + $subtags[1] = strtolower($subtags[1]); + } + + $new_string .= '-' . $subtags[1]; + if ($num_subtags == 2) { + return $new_string; + } + + // process all other subtags, index 2 and up + for ($i = 2; $i < $num_subtags; $i++) { + $length = strlen($subtags[$i]); + if ($length == 0 || $length > 8 || !ctype_alnum($subtags[$i])) { + return $new_string; + } + if (!ctype_lower($subtags[$i])) { + $subtags[$i] = strtolower($subtags[$i]); + } + $new_string .= '-' . $subtags[$i]; + } + return $new_string; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Switch.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Switch.php new file mode 100644 index 0000000..c7eb319 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Switch.php @@ -0,0 +1,53 @@ +tag = $tag; + $this->withTag = $with_tag; + $this->withoutTag = $without_tag; + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $token = $context->get('CurrentToken', true); + if (!$token || $token->name !== $this->tag) { + return $this->withoutTag->validate($string, $config, $context); + } else { + return $this->withTag->validate($string, $config, $context); + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Text.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Text.php new file mode 100644 index 0000000..4553a4e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/Text.php @@ -0,0 +1,21 @@ +parseCDATA($string); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI.php new file mode 100644 index 0000000..c1cd897 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI.php @@ -0,0 +1,111 @@ +parser = new HTMLPurifier_URIParser(); + $this->embedsResource = (bool)$embeds_resource; + } + + /** + * @param string $string + * @return HTMLPurifier_AttrDef_URI + */ + public function make($string) + { + $embeds = ($string === 'embedded'); + return new HTMLPurifier_AttrDef_URI($embeds); + } + + /** + * @param string $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($uri, $config, $context) + { + if ($config->get('URI.Disable')) { + return false; + } + + $uri = $this->parseCDATA($uri); + + // parse the URI + $uri = $this->parser->parse($uri); + if ($uri === false) { + return false; + } + + // add embedded flag to context for validators + $context->register('EmbeddedURI', $this->embedsResource); + + $ok = false; + do { + + // generic validation + $result = $uri->validate($config, $context); + if (!$result) { + break; + } + + // chained filtering + $uri_def = $config->getDefinition('URI'); + $result = $uri_def->filter($uri, $config, $context); + if (!$result) { + break; + } + + // scheme-specific validation + $scheme_obj = $uri->getSchemeObj($config, $context); + if (!$scheme_obj) { + break; + } + if ($this->embedsResource && !$scheme_obj->browsable) { + break; + } + $result = $scheme_obj->validate($uri, $config, $context); + if (!$result) { + break; + } + + // Post chained filtering + $result = $uri_def->postFilter($uri, $config, $context); + if (!$result) { + break; + } + + // survived gauntlet + $ok = true; + + } while (false); + + $context->destroy('EmbeddedURI'); + if (!$ok) { + return false; + } + // back to string + return $uri->toString(); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/Email.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/Email.php new file mode 100644 index 0000000..daf32b7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/Email.php @@ -0,0 +1,20 @@ +" + // that needs more percent encoding to be done + if ($string == '') { + return false; + } + $string = trim($string); + $result = preg_match('/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i', $string); + return $result ? $string : false; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/Host.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/Host.php new file mode 100644 index 0000000..17a97c1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/Host.php @@ -0,0 +1,136 @@ +ipv4 = new HTMLPurifier_AttrDef_URI_IPv4(); + $this->ipv6 = new HTMLPurifier_AttrDef_URI_IPv6(); + } + + /** + * @param string $string + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool|string + */ + public function validate($string, $config, $context) + { + $length = strlen($string); + // empty hostname is OK; it's usually semantically equivalent: + // the default host as defined by a URI scheme is used: + // + // If the URI scheme defines a default for host, then that + // default applies when the host subcomponent is undefined + // or when the registered name is empty (zero length). + if ($string === '') { + return ''; + } + if ($length > 1 && $string[0] === '[' && $string[$length - 1] === ']') { + //IPv6 + $ip = substr($string, 1, $length - 2); + $valid = $this->ipv6->validate($ip, $config, $context); + if ($valid === false) { + return false; + } + return '[' . $valid . ']'; + } + + // need to do checks on unusual encodings too + $ipv4 = $this->ipv4->validate($string, $config, $context); + if ($ipv4 !== false) { + return $ipv4; + } + + // A regular domain name. + + // This doesn't match I18N domain names, but we don't have proper IRI support, + // so force users to insert Punycode. + + // Underscores defined as Unreserved Characters in RFC 3986 are + // allowed in a URI. There are cases where we want to consider a + // URI containing "_" such as "_dmarc.example.com". + // Underscores are not allowed in the default. If you want to + // allow it, set Core.AllowHostnameUnderscore to true. + $underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : ''; + + // Based off of RFC 1738, but amended so that + // as per RFC 3696, the top label need only not be all numeric. + // The productions describing this are: + $a = '[a-z]'; // alpha + $an = "[a-z0-9$underscore]"; // alphanum + $and = "[a-z0-9-$underscore]"; // alphanum | "-" + // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + $domainlabel = "$an(?:$and*$an)?"; + // AMENDED as per RFC 3696 + // toplabel = alphanum | alphanum *( alphanum | "-" ) alphanum + // side condition: not all numeric + $toplabel = "$an(?:$and*$an)?"; + // hostname = *( domainlabel "." ) toplabel [ "." ] + if (preg_match("/^(?:$domainlabel\.)*($toplabel)\.?$/i", $string, $matches)) { + if (!ctype_digit($matches[1])) { + return $string; + } + } + + // PHP 5.3 and later support this functionality natively + if (function_exists('idn_to_ascii')) { + if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) { + $string = idn_to_ascii($string, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46); + } else { + $string = idn_to_ascii($string); + } + + // If we have Net_IDNA2 support, we can support IRIs by + // punycoding them. (This is the most portable thing to do, + // since otherwise we have to assume browsers support + } elseif ($config->get('Core.EnableIDNA') && class_exists('Net_IDNA2')) { + $idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true)); + // we need to encode each period separately + $parts = explode('.', $string); + try { + $new_parts = array(); + foreach ($parts as $part) { + $encodable = false; + for ($i = 0, $c = strlen($part); $i < $c; $i++) { + if (ord($part[$i]) > 0x7a) { + $encodable = true; + break; + } + } + if (!$encodable) { + $new_parts[] = $part; + } else { + $new_parts[] = $idna->encode($part); + } + } + $string = implode('.', $new_parts); + } catch (Exception $e) { + // XXX error reporting + } + } + // Try again + if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) { + return $string; + } + return false; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/IPv4.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/IPv4.php new file mode 100644 index 0000000..30ac16c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/IPv4.php @@ -0,0 +1,45 @@ +ip4) { + $this->_loadRegex(); + } + + if (preg_match('#^' . $this->ip4 . '$#s', $aIP)) { + return $aIP; + } + return false; + } + + /** + * Lazy load function to prevent regex from being stuffed in + * cache. + */ + protected function _loadRegex() + { + $oct = '(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])'; // 0-255 + $this->ip4 = "(?:{$oct}\\.{$oct}\\.{$oct}\\.{$oct})"; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/IPv6.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/IPv6.php new file mode 100644 index 0000000..f243793 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrDef/URI/IPv6.php @@ -0,0 +1,89 @@ +ip4) { + $this->_loadRegex(); + } + + $original = $aIP; + + $hex = '[0-9a-fA-F]'; + $blk = '(?:' . $hex . '{1,4})'; + $pre = '(?:/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))'; // /0 - /128 + + // prefix check + if (strpos($aIP, '/') !== false) { + if (preg_match('#' . $pre . '$#s', $aIP, $find)) { + $aIP = substr($aIP, 0, 0 - strlen($find[0])); + unset($find); + } else { + return false; + } + } + + // IPv4-compatiblity check + if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) { + $aIP = substr($aIP, 0, 0 - strlen($find[0])); + $ip = explode('.', $find[0]); + $ip = array_map('dechex', $ip); + $aIP .= $ip[0] . $ip[1] . ':' . $ip[2] . $ip[3]; + unset($find, $ip); + } + + // compression check + $aIP = explode('::', $aIP); + $c = count($aIP); + if ($c > 2) { + return false; + } elseif ($c == 2) { + list($first, $second) = $aIP; + $first = explode(':', $first); + $second = explode(':', $second); + + if (count($first) + count($second) > 8) { + return false; + } + + while (count($first) < 8) { + array_push($first, '0'); + } + + array_splice($first, 8 - count($second), 8, $second); + $aIP = $first; + unset($first, $second); + } else { + $aIP = explode(':', $aIP[0]); + } + $c = count($aIP); + + if ($c != 8) { + return false; + } + + // All the pieces should be 16-bit hex strings. Are they? + foreach ($aIP as $piece) { + if (!preg_match('#^[0-9a-fA-F]{4}$#s', sprintf('%04s', $piece))) { + return false; + } + } + return $original; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform.php new file mode 100644 index 0000000..b428331 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform.php @@ -0,0 +1,60 @@ +confiscateAttr($attr, 'background'); + // some validation should happen here + + $this->prependCSS($attr, "background-image:url($background);"); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BdoDir.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BdoDir.php new file mode 100644 index 0000000..d66c04a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BdoDir.php @@ -0,0 +1,27 @@ +get('Attr.DefaultTextDir'); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BgColor.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BgColor.php new file mode 100644 index 0000000..0f51fd2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BgColor.php @@ -0,0 +1,28 @@ +confiscateAttr($attr, 'bgcolor'); + // some validation should happen here + + $this->prependCSS($attr, "background-color:$bgcolor;"); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BoolToCSS.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BoolToCSS.php new file mode 100644 index 0000000..f25cd01 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/BoolToCSS.php @@ -0,0 +1,47 @@ +attr = $attr; + $this->css = $css; + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->attr])) { + return $attr; + } + unset($attr[$this->attr]); + $this->prependCSS($attr, $this->css); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Border.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Border.php new file mode 100644 index 0000000..057dc01 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Border.php @@ -0,0 +1,26 @@ +confiscateAttr($attr, 'border'); + // some validation should happen here + $this->prependCSS($attr, "border:{$border_width}px solid;"); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/EnumToCSS.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/EnumToCSS.php new file mode 100644 index 0000000..7ccd0e3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/EnumToCSS.php @@ -0,0 +1,68 @@ +attr = $attr; + $this->enumToCSS = $enum_to_css; + $this->caseSensitive = (bool)$case_sensitive; + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->attr])) { + return $attr; + } + + $value = trim($attr[$this->attr]); + unset($attr[$this->attr]); + + if (!$this->caseSensitive) { + $value = strtolower($value); + } + + if (!isset($this->enumToCSS[$value])) { + return $attr; + } + $this->prependCSS($attr, $this->enumToCSS[$value]); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ImgRequired.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ImgRequired.php new file mode 100644 index 0000000..235ebb3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ImgRequired.php @@ -0,0 +1,47 @@ +get('Core.RemoveInvalidImg')) { + return $attr; + } + $attr['src'] = $config->get('Attr.DefaultInvalidImage'); + $src = false; + } + + if (!isset($attr['alt'])) { + if ($src) { + $alt = $config->get('Attr.DefaultImageAlt'); + if ($alt === null) { + $attr['alt'] = basename($attr['src']); + } else { + $attr['alt'] = $alt; + } + } else { + $attr['alt'] = $config->get('Attr.DefaultInvalidImageAlt'); + } + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ImgSpace.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ImgSpace.php new file mode 100644 index 0000000..350b335 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ImgSpace.php @@ -0,0 +1,61 @@ + array('left', 'right'), + 'vspace' => array('top', 'bottom') + ); + + /** + * @param string $attr + */ + public function __construct($attr) + { + $this->attr = $attr; + if (!isset($this->css[$attr])) { + trigger_error(htmlspecialchars($attr) . ' is not valid space attribute'); + } + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->attr])) { + return $attr; + } + + $width = $this->confiscateAttr($attr, $this->attr); + // some validation could happen here + + if (!isset($this->css[$this->attr])) { + return $attr; + } + + $style = ''; + foreach ($this->css[$this->attr] as $suffix) { + $property = "margin-$suffix"; + $style .= "$property:{$width}px;"; + } + $this->prependCSS($attr, $style); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Input.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Input.php new file mode 100644 index 0000000..3ab47ed --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Input.php @@ -0,0 +1,56 @@ +pixels = new HTMLPurifier_AttrDef_HTML_Pixels(); + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['type'])) { + $t = 'text'; + } else { + $t = strtolower($attr['type']); + } + if (isset($attr['checked']) && $t !== 'radio' && $t !== 'checkbox') { + unset($attr['checked']); + } + if (isset($attr['maxlength']) && $t !== 'text' && $t !== 'password') { + unset($attr['maxlength']); + } + if (isset($attr['size']) && $t !== 'text' && $t !== 'password') { + $result = $this->pixels->validate($attr['size'], $config, $context); + if ($result === false) { + unset($attr['size']); + } else { + $attr['size'] = $result; + } + } + if (isset($attr['src']) && $t !== 'image') { + unset($attr['src']); + } + if (!isset($attr['value']) && ($t === 'radio' || $t === 'checkbox')) { + $attr['value'] = ''; + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Lang.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Lang.php new file mode 100644 index 0000000..5b0aff0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Lang.php @@ -0,0 +1,31 @@ +name = $name; + $this->cssName = $css_name ? $css_name : $name; + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr[$this->name])) { + return $attr; + } + $length = $this->confiscateAttr($attr, $this->name); + if (ctype_digit($length)) { + $length .= 'px'; + } + $this->prependCSS($attr, $this->cssName . ":$length;"); + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Name.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Name.php new file mode 100644 index 0000000..63cce68 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Name.php @@ -0,0 +1,33 @@ +get('HTML.Attr.Name.UseCDATA')) { + return $attr; + } + if (!isset($attr['name'])) { + return $attr; + } + $id = $this->confiscateAttr($attr, 'name'); + if (isset($attr['id'])) { + return $attr; + } + $attr['id'] = $id; + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/NameSync.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/NameSync.php new file mode 100644 index 0000000..5a1fdbb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/NameSync.php @@ -0,0 +1,46 @@ +idDef = new HTMLPurifier_AttrDef_HTML_ID(); + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['name'])) { + return $attr; + } + $name = $attr['name']; + if (isset($attr['id']) && $attr['id'] === $name) { + return $attr; + } + $result = $this->idDef->validate($name, $config, $context); + if ($result === false) { + unset($attr['name']); + } else { + $attr['name'] = $result; + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Nofollow.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Nofollow.php new file mode 100644 index 0000000..1057ebe --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/Nofollow.php @@ -0,0 +1,52 @@ +parser = new HTMLPurifier_URIParser(); + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['href'])) { + return $attr; + } + + // XXX Kind of inefficient + $url = $this->parser->parse($attr['href']); + $scheme = $url->getSchemeObj($config, $context); + + if ($scheme->browsable && !$url->isLocal($config, $context)) { + if (isset($attr['rel'])) { + $rels = explode(' ', $attr['rel']); + if (!in_array('nofollow', $rels)) { + $rels[] = 'nofollow'; + } + $attr['rel'] = implode(' ', $rels); + } else { + $attr['rel'] = 'nofollow'; + } + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/SafeEmbed.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/SafeEmbed.php new file mode 100644 index 0000000..231c81a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/SafeEmbed.php @@ -0,0 +1,25 @@ +uri = new HTMLPurifier_AttrDef_URI(true); // embedded + $this->wmode = new HTMLPurifier_AttrDef_Enum(array('window', 'opaque', 'transparent')); + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + // If we add support for other objects, we'll need to alter the + // transforms. + switch ($attr['name']) { + // application/x-shockwave-flash + // Keep this synchronized with Injector/SafeObject.php + case 'allowScriptAccess': + $attr['value'] = 'never'; + break; + case 'allowNetworking': + $attr['value'] = 'internal'; + break; + case 'allowFullScreen': + if ($config->get('HTML.FlashAllowFullScreen')) { + $attr['value'] = ($attr['value'] == 'true') ? 'true' : 'false'; + } else { + $attr['value'] = 'false'; + } + break; + case 'wmode': + $attr['value'] = $this->wmode->validate($attr['value'], $config, $context); + break; + case 'movie': + case 'src': + $attr['name'] = "movie"; + $attr['value'] = $this->uri->validate($attr['value'], $config, $context); + break; + case 'flashvars': + // we're going to allow arbitrary inputs to the SWF, on + // the reasoning that it could only hack the SWF, not us. + break; + // add other cases to support other param name/value pairs + default: + $attr['name'] = $attr['value'] = null; + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ScriptRequired.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ScriptRequired.php new file mode 100644 index 0000000..b7057bb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/ScriptRequired.php @@ -0,0 +1,23 @@ + + */ +class HTMLPurifier_AttrTransform_ScriptRequired extends HTMLPurifier_AttrTransform +{ + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['type'])) { + $attr['type'] = 'text/javascript'; + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/TargetBlank.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/TargetBlank.php new file mode 100644 index 0000000..cc30ab8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/TargetBlank.php @@ -0,0 +1,49 @@ +parser = new HTMLPurifier_URIParser(); + } + + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + if (!isset($attr['href'])) { + return $attr; + } + + // XXX Kind of inefficient + $url = $this->parser->parse($attr['href']); + + // Ignore invalid schemes (e.g. `javascript:`) + if (!($scheme = $url->getSchemeObj($config, $context))) { + return $attr; + } + + if ($scheme->browsable && !$url->isBenign($config, $context)) { + $attr['target'] = '_blank'; + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/TargetNoopener.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/TargetNoopener.php new file mode 100644 index 0000000..1db3c6c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTransform/TargetNoopener.php @@ -0,0 +1,37 @@ + + */ +class HTMLPurifier_AttrTransform_Textarea extends HTMLPurifier_AttrTransform +{ + /** + * @param array $attr + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function transform($attr, $config, $context) + { + // Calculated from Firefox + if (!isset($attr['cols'])) { + $attr['cols'] = '22'; + } + if (!isset($attr['rows'])) { + $attr['rows'] = '3'; + } + return $attr; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTypes.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTypes.php new file mode 100644 index 0000000..e4429e8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrTypes.php @@ -0,0 +1,97 @@ +info['Enum'] = new HTMLPurifier_AttrDef_Enum(); + $this->info['Bool'] = new HTMLPurifier_AttrDef_HTML_Bool(); + + $this->info['CDATA'] = new HTMLPurifier_AttrDef_Text(); + $this->info['ID'] = new HTMLPurifier_AttrDef_HTML_ID(); + $this->info['Length'] = new HTMLPurifier_AttrDef_HTML_Length(); + $this->info['MultiLength'] = new HTMLPurifier_AttrDef_HTML_MultiLength(); + $this->info['NMTOKENS'] = new HTMLPurifier_AttrDef_HTML_Nmtokens(); + $this->info['Pixels'] = new HTMLPurifier_AttrDef_HTML_Pixels(); + $this->info['Text'] = new HTMLPurifier_AttrDef_Text(); + $this->info['URI'] = new HTMLPurifier_AttrDef_URI(); + $this->info['LanguageCode'] = new HTMLPurifier_AttrDef_Lang(); + $this->info['Color'] = new HTMLPurifier_AttrDef_HTML_Color(); + $this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right'); + $this->info['LAlign'] = self::makeEnum('top,bottom,left,right'); + $this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget(); + $this->info['ContentEditable'] = new HTMLPurifier_AttrDef_HTML_ContentEditable(); + + // unimplemented aliases + $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text(); + $this->info['ContentTypes'] = new HTMLPurifier_AttrDef_Text(); + $this->info['Charsets'] = new HTMLPurifier_AttrDef_Text(); + $this->info['Character'] = new HTMLPurifier_AttrDef_Text(); + + // "proprietary" types + $this->info['Class'] = new HTMLPurifier_AttrDef_HTML_Class(); + + // number is really a positive integer (one or more digits) + // FIXME: ^^ not always, see start and value of list items + $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true); + } + + private static function makeEnum($in) + { + return new HTMLPurifier_AttrDef_Clone(new HTMLPurifier_AttrDef_Enum(explode(',', $in))); + } + + /** + * Retrieves a type + * @param string $type String type name + * @return HTMLPurifier_AttrDef Object AttrDef for type + */ + public function get($type) + { + // determine if there is any extra info tacked on + if (strpos($type, '#') !== false) { + list($type, $string) = explode('#', $type, 2); + } else { + $string = ''; + } + + if (!isset($this->info[$type])) { + trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR); + return; + } + return $this->info[$type]->make($string); + } + + /** + * Sets a new implementation for a type + * @param string $type String type name + * @param HTMLPurifier_AttrDef $impl Object AttrDef for type + */ + public function set($type, $impl) + { + $this->info[$type] = $impl; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrValidator.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrValidator.php new file mode 100644 index 0000000..f97dc93 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/AttrValidator.php @@ -0,0 +1,178 @@ +getHTMLDefinition(); + $e =& $context->get('ErrorCollector', true); + + // initialize IDAccumulator if necessary + $ok =& $context->get('IDAccumulator', true); + if (!$ok) { + $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); + $context->register('IDAccumulator', $id_accumulator); + } + + // initialize CurrentToken if necessary + $current_token =& $context->get('CurrentToken', true); + if (!$current_token) { + $context->register('CurrentToken', $token); + } + + if (!$token instanceof HTMLPurifier_Token_Start && + !$token instanceof HTMLPurifier_Token_Empty + ) { + return; + } + + // create alias to global definition array, see also $defs + // DEFINITION CALL + $d_defs = $definition->info_global_attr; + + // don't update token until the very end, to ensure an atomic update + $attr = $token->attr; + + // do global transformations (pre) + // nothing currently utilizes this + foreach ($definition->info_attr_transform_pre as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + // do local transformations only applicable to this element (pre) + // ex.

        to

        + foreach ($definition->info[$token->name]->attr_transform_pre as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + // create alias to this element's attribute definition array, see + // also $d_defs (global attribute definition array) + // DEFINITION CALL + $defs = $definition->info[$token->name]->attr; + + $attr_key = false; + $context->register('CurrentAttr', $attr_key); + + // iterate through all the attribute keypairs + // Watch out for name collisions: $key has previously been used + foreach ($attr as $attr_key => $value) { + + // call the definition + if (isset($defs[$attr_key])) { + // there is a local definition defined + if ($defs[$attr_key] === false) { + // We've explicitly been told not to allow this element. + // This is usually when there's a global definition + // that must be overridden. + // Theoretically speaking, we could have a + // AttrDef_DenyAll, but this is faster! + $result = false; + } else { + // validate according to the element's definition + $result = $defs[$attr_key]->validate( + $value, + $config, + $context + ); + } + } elseif (isset($d_defs[$attr_key])) { + // there is a global definition defined, validate according + // to the global definition + $result = $d_defs[$attr_key]->validate( + $value, + $config, + $context + ); + } else { + // system never heard of the attribute? DELETE! + $result = false; + } + + // put the results into effect + if ($result === false || $result === null) { + // this is a generic error message that should replaced + // with more specific ones when possible + if ($e) { + $e->send(E_ERROR, 'AttrValidator: Attribute removed'); + } + + // remove the attribute + unset($attr[$attr_key]); + } elseif (is_string($result)) { + // generally, if a substitution is happening, there + // was some sort of implicit correction going on. We'll + // delegate it to the attribute classes to say exactly what. + + // simple substitution + $attr[$attr_key] = $result; + } else { + // nothing happens + } + + // we'd also want slightly more complicated substitution + // involving an array as the return value, + // although we're not sure how colliding attributes would + // resolve (certain ones would be completely overriden, + // others would prepend themselves). + } + + $context->destroy('CurrentAttr'); + + // post transforms + + // global (error reporting untested) + foreach ($definition->info_attr_transform_post as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + // local (error reporting untested) + foreach ($definition->info[$token->name]->attr_transform_post as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + $token->attr = $attr; + + // destroy CurrentToken if we made it ourselves + if (!$current_token) { + $context->destroy('CurrentToken'); + } + + } + + +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Bootstrap.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Bootstrap.php new file mode 100644 index 0000000..bd8f998 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Bootstrap.php @@ -0,0 +1,91 @@ + +if (!defined('PHP_EOL')) { + switch (strtoupper(substr(PHP_OS, 0, 3))) { + case 'WIN': + define('PHP_EOL', "\r\n"); + break; + case 'DAR': + define('PHP_EOL', "\r"); + break; + default: + define('PHP_EOL', "\n"); + } +} + +/** + * Bootstrap class that contains meta-functionality for HTML Purifier such as + * the autoload function. + * + * @note + * This class may be used without any other files from HTML Purifier. + */ +class HTMLPurifier_Bootstrap +{ + + /** + * Autoload function for HTML Purifier + * @param string $class Class to load + * @return bool + */ + public static function autoload($class) + { + $file = HTMLPurifier_Bootstrap::getPath($class); + if (!$file) { + return false; + } + // Technically speaking, it should be ok and more efficient to + // just do 'require', but Antonio Parraga reports that with + // Zend extensions such as Zend debugger and APC, this invariant + // may be broken. Since we have efficient alternatives, pay + // the cost here and avoid the bug. + require_once HTMLPURIFIER_PREFIX . '/' . $file; + return true; + } + + /** + * Returns the path for a specific class. + * @param string $class Class path to get + * @return string + */ + public static function getPath($class) + { + if (strncmp('HTMLPurifier', $class, 12) !== 0) { + return false; + } + // Custom implementations + if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) { + $code = str_replace('_', '-', substr($class, 22)); + $file = 'HTMLPurifier/Language/classes/' . $code . '.php'; + } else { + $file = str_replace('_', '/', $class) . '.php'; + } + if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) { + return false; + } + return $file; + } + + /** + * "Pre-registers" our autoloader on the SPL stack. + */ + public static function registerAutoload() + { + $autoload = array('HTMLPurifier_Bootstrap', 'autoload'); + if (spl_autoload_functions() === false) { + spl_autoload_register($autoload); + } else { + // prepend flag exists, no need for shenanigans + spl_autoload_register($autoload, true, true); + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/CSSDefinition.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/CSSDefinition.php new file mode 100644 index 0000000..3732c07 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/CSSDefinition.php @@ -0,0 +1,565 @@ +info['text-align'] = new HTMLPurifier_AttrDef_Enum( + ['left', 'right', 'center', 'justify'], + false + ); + + $border_style = + $this->info['border-bottom-style'] = + $this->info['border-right-style'] = + $this->info['border-left-style'] = + $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( + [ + 'none', + 'hidden', + 'dotted', + 'dashed', + 'solid', + 'double', + 'groove', + 'ridge', + 'inset', + 'outset' + ], + false + ); + + $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); + + $this->info['clear'] = new HTMLPurifier_AttrDef_Enum( + ['none', 'left', 'right', 'both'], + false + ); + $this->info['float'] = new HTMLPurifier_AttrDef_Enum( + ['none', 'left', 'right'], + false + ); + $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( + ['normal', 'italic', 'oblique'], + false + ); + $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( + ['normal', 'small-caps'], + false + ); + + $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum(['none']), + new HTMLPurifier_AttrDef_CSS_URI() + ] + ); + + $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( + ['inside', 'outside'], + false + ); + $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( + [ + 'disc', + 'circle', + 'square', + 'decimal', + 'lower-roman', + 'upper-roman', + 'lower-alpha', + 'upper-alpha', + 'none' + ], + false + ); + $this->info['list-style-image'] = $uri_or_none; + + $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); + + $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( + ['capitalize', 'uppercase', 'lowercase', 'none'], + false + ); + $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + $this->info['background-image'] = $uri_or_none; + $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum( + ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] + ); + $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( + ['scroll', 'fixed'] + ); + $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); + + $this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum( + [ + 'auto', + 'cover', + 'contain', + ] + ), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_CSS_Length() + ] + ); + + $border_color = + $this->info['border-top-color'] = + $this->info['border-bottom-color'] = + $this->info['border-left-color'] = + $this->info['border-right-color'] = + $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum(['transparent']), + new HTMLPurifier_AttrDef_CSS_Color() + ] + ); + + $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); + + $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color); + + $border_width = + $this->info['border-top-width'] = + $this->info['border-bottom-width'] = + $this->info['border-left-width'] = + $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum(['thin', 'medium', 'thick']), + new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative + ] + ); + + $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); + + $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum(['normal']), + new HTMLPurifier_AttrDef_CSS_Length() + ] + ); + + $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum(['normal']), + new HTMLPurifier_AttrDef_CSS_Length() + ] + ); + + $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum( + [ + 'xx-small', + 'x-small', + 'small', + 'medium', + 'large', + 'x-large', + 'xx-large', + 'larger', + 'smaller' + ] + ), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_CSS_Length() + ] + ); + + $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum(['normal']), + new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + ] + ); + + $margin = + $this->info['margin-top'] = + $this->info['margin-bottom'] = + $this->info['margin-left'] = + $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(['auto']) + ] + ); + + $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); + + // non-negative + $padding = + $this->info['padding-top'] = + $this->info['padding-bottom'] = + $this->info['padding-left'] = + $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + ] + ); + + $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); + + $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + ] + ); + + $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true), + new HTMLPurifier_AttrDef_Enum(['auto']) + ] + ); + $trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true), + ] + ); + $trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true), + new HTMLPurifier_AttrDef_Enum(['none']) + ] + ); + $max = $config->get('CSS.MaxImgLength'); + + $this->info['width'] = + $this->info['height'] = + $max === null ? + $trusted_wh : + new HTMLPurifier_AttrDef_Switch( + 'img', + // For img tags: + new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length('0', $max), + new HTMLPurifier_AttrDef_Enum(['auto']) + ] + ), + // For everyone else: + $trusted_wh + ); + $this->info['min-width'] = + $this->info['min-height'] = + $max === null ? + $trusted_min_wh : + new HTMLPurifier_AttrDef_Switch( + 'img', + // For img tags: + new HTMLPurifier_AttrDef_CSS_Length('0', $max), + // For everyone else: + $trusted_min_wh + ); + $this->info['max-width'] = + $this->info['max-height'] = + $max === null ? + $trusted_max_wh : + new HTMLPurifier_AttrDef_Switch( + 'img', + // For img tags: + new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length('0', $max), + new HTMLPurifier_AttrDef_Enum(['none']) + ] + ), + // For everyone else: + $trusted_max_wh + ); + + $this->info['aspect-ratio'] = new HTMLPurifier_AttrDef_CSS_Multiple( + new HTMLPurifier_AttrDef_CSS_Composite([ + new HTMLPurifier_AttrDef_CSS_Ratio(), + new HTMLPurifier_AttrDef_Enum(['auto']), + ]) + ); + + // text-decoration and related shorthands + $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); + + $this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum( + ['none', 'underline', 'overline', 'line-through'] + ); + + $this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum( + ['solid', 'double', 'dotted', 'dashed', 'wavy'] + ); + + $this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + $this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([ + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(['auto', 'from-font']) + ]); + + $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); + + // this could use specialized code + $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( + [ + 'normal', + 'bold', + 'bolder', + 'lighter', + '100', + '200', + '300', + '400', + '500', + '600', + '700', + '800', + '900' + ], + false + ); + + // MUST be called after other font properties, as it references + // a CSSDefinition object + $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config); + + // same here + $this->info['border'] = + $this->info['border-bottom'] = + $this->info['border-top'] = + $this->info['border-left'] = + $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); + + $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( + ['collapse', 'separate'] + ); + + $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( + ['top', 'bottom'] + ); + + $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( + ['auto', 'fixed'] + ); + + $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Enum( + [ + 'baseline', + 'sub', + 'super', + 'top', + 'text-top', + 'middle', + 'bottom', + 'text-bottom' + ] + ), + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + ] + ); + + $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); + + // These CSS properties don't work on many browsers, but we live + // in THE FUTURE! + $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( + ['nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line'] + ); + + if ($config->get('CSS.Proprietary')) { + $this->doSetupProprietary($config); + } + + if ($config->get('CSS.AllowTricky')) { + $this->doSetupTricky($config); + } + + if ($config->get('CSS.Trusted')) { + $this->doSetupTrusted($config); + } + + $allow_important = $config->get('CSS.AllowImportant'); + // wrap all attr-defs with decorator that handles !important + foreach ($this->info as $k => $v) { + $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important); + } + + $this->setupConfigStuff($config); + } + + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupProprietary($config) + { + // Internet Explorer only scrollbar colors + $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + // vendor specific prefixes of opacity + $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + + // only opacity, for now + $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter(); + + // more CSS3 + $this->info['page-break-after'] = + $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( + [ + 'auto', + 'always', + 'avoid', + 'left', + 'right' + ] + ); + $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(['auto', 'avoid']); + + $border_radius = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative + new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative + ]); + + $this->info['border-top-left-radius'] = + $this->info['border-top-right-radius'] = + $this->info['border-bottom-right-radius'] = + $this->info['border-bottom-left-radius'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_radius, 2); + // TODO: support SLASH syntax + $this->info['border-radius'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_radius, 4); + + } + + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupTricky($config) + { + $this->info['display'] = new HTMLPurifier_AttrDef_Enum( + [ + 'inline', + 'block', + 'list-item', + 'run-in', + 'compact', + 'marker', + 'table', + 'inline-block', + 'inline-table', + 'table-row-group', + 'table-header-group', + 'table-footer-group', + 'table-row', + 'table-column-group', + 'table-column', + 'table-cell', + 'table-caption', + 'none' + ] + ); + $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( + ['visible', 'hidden', 'collapse'] + ); + $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(['visible', 'hidden', 'auto', 'scroll']); + $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + } + + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupTrusted($config) + { + $this->info['position'] = new HTMLPurifier_AttrDef_Enum( + ['static', 'relative', 'absolute', 'fixed'] + ); + $this->info['top'] = + $this->info['left'] = + $this->info['right'] = + $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(['auto']), + ] + ); + $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( + [ + new HTMLPurifier_AttrDef_Integer(), + new HTMLPurifier_AttrDef_Enum(['auto']), + ] + ); + } + + /** + * Performs extra config-based processing. Based off of + * HTMLPurifier_HTMLDefinition. + * @param HTMLPurifier_Config $config + * @todo Refactor duplicate elements into common class (probably using + * composition, not inheritance). + */ + protected function setupConfigStuff($config) + { + // setup allowed elements + $support = "(for information on implementing this, see the " . + "support forums) "; + $allowed_properties = $config->get('CSS.AllowedProperties'); + if ($allowed_properties !== null) { + foreach ($this->info as $name => $d) { + if (!isset($allowed_properties[$name])) { + unset($this->info[$name]); + } + unset($allowed_properties[$name]); + } + // emit errors + foreach ($allowed_properties as $name => $d) { + // :TODO: Is this htmlspecialchars() call really necessary? + $name = htmlspecialchars($name); + trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING); + } + } + + $forbidden_properties = $config->get('CSS.ForbiddenProperties'); + if ($forbidden_properties !== null) { + foreach ($this->info as $name => $d) { + if (isset($forbidden_properties[$name])) { + unset($this->info[$name]); + } + } + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef.php new file mode 100644 index 0000000..8eb17b8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef.php @@ -0,0 +1,52 @@ +elements; + } + + /** + * Validates nodes according to definition and returns modification. + * + * @param HTMLPurifier_Node[] $children Array of HTMLPurifier_Node + * @param HTMLPurifier_Config $config HTMLPurifier_Config object + * @param HTMLPurifier_Context $context HTMLPurifier_Context object + * @return bool|array true to leave nodes as is, false to remove parent node, array of replacement children + */ + abstract public function validateChildren($children, $config, $context); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Chameleon.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Chameleon.php new file mode 100644 index 0000000..7439be2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Chameleon.php @@ -0,0 +1,67 @@ +inline = new HTMLPurifier_ChildDef_Optional($inline); + $this->block = new HTMLPurifier_ChildDef_Optional($block); + $this->elements = $this->block->elements; + } + + /** + * @param HTMLPurifier_Node[] $children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function validateChildren($children, $config, $context) + { + if ($context->get('IsInline') === false) { + return $this->block->validateChildren( + $children, + $config, + $context + ); + } else { + return $this->inline->validateChildren( + $children, + $config, + $context + ); + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Custom.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Custom.php new file mode 100644 index 0000000..f515888 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Custom.php @@ -0,0 +1,102 @@ +dtd_regex = $dtd_regex; + $this->_compileRegex(); + } + + /** + * Compiles the PCRE regex from a DTD regex ($dtd_regex to $_pcre_regex) + */ + protected function _compileRegex() + { + $raw = str_replace(' ', '', $this->dtd_regex); + if ($raw[0] != '(') { + $raw = "($raw)"; + } + $el = '[#a-zA-Z0-9_.-]+'; + $reg = $raw; + + // COMPLICATED! AND MIGHT BE BUGGY! I HAVE NO CLUE WHAT I'M + // DOING! Seriously: if there's problems, please report them. + + // collect all elements into the $elements array + preg_match_all("/$el/", $reg, $matches); + foreach ($matches[0] as $match) { + $this->elements[$match] = true; + } + + // setup all elements as parentheticals with leading commas + $reg = preg_replace("/$el/", '(,\\0)', $reg); + + // remove commas when they were not solicited + $reg = preg_replace("/([^,(|]\(+),/", '\\1', $reg); + + // remove all non-paranthetical commas: they are handled by first regex + $reg = preg_replace("/,\(/", '(', $reg); + + $this->_pcre_regex = $reg; + } + + /** + * @param HTMLPurifier_Node[] $children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function validateChildren($children, $config, $context) + { + $list_of_children = ''; + $nesting = 0; // depth into the nest + foreach ($children as $node) { + if (!empty($node->is_whitespace)) { + continue; + } + $list_of_children .= $node->name . ','; + } + // add leading comma to deal with stray comma declarations + $list_of_children = ',' . rtrim($list_of_children, ','); + $okay = + preg_match( + '/^,?' . $this->_pcre_regex . '$/', + $list_of_children + ); + return (bool)$okay; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Empty.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Empty.php new file mode 100644 index 0000000..a8a6cbd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Empty.php @@ -0,0 +1,38 @@ + true, 'ul' => true, 'ol' => true); + + public $whitespace; + + /** + * @param array $children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($children, $config, $context) + { + // Flag for subclasses + $this->whitespace = false; + + // if there are no tokens, delete parent node + if (empty($children)) { + return false; + } + + // if li is not allowed, delete parent node + if (!isset($config->getHTMLDefinition()->info['li'])) { + trigger_error("Cannot allow ul/ol without allowing li", E_USER_WARNING); + return false; + } + + // the new set of children + $result = array(); + + // a little sanity check to make sure it's not ALL whitespace + $all_whitespace = true; + + $current_li = null; + + foreach ($children as $node) { + if (!empty($node->is_whitespace)) { + $result[] = $node; + continue; + } + $all_whitespace = false; // phew, we're not talking about whitespace + + if ($node->name === 'li') { + // good + $current_li = $node; + $result[] = $node; + } else { + // we want to tuck this into the previous li + // Invariant: we expect the node to be ol/ul + // ToDo: Make this more robust in the case of not ol/ul + // by distinguishing between existing li and li created + // to handle non-list elements; non-list elements should + // not be appended to an existing li; only li created + // for non-list. This distinction is not currently made. + if ($current_li === null) { + $current_li = new HTMLPurifier_Node_Element('li'); + $result[] = $current_li; + } + $current_li->children[] = $node; + $current_li->empty = false; // XXX fascinating! Check for this error elsewhere ToDo + } + } + if (empty($result)) { + return false; + } + if ($all_whitespace) { + return false; + } + return $result; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Optional.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Optional.php new file mode 100644 index 0000000..b946806 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Optional.php @@ -0,0 +1,45 @@ +whitespace) { + return $children; + } else { + return array(); + } + } + return $result; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Required.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Required.php new file mode 100644 index 0000000..0d1c8f5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Required.php @@ -0,0 +1,118 @@ + $x) { + $elements[$i] = true; + if (empty($i)) { + unset($elements[$i]); + } // remove blank + } + } + $this->elements = $elements; + } + + /** + * @type bool + */ + public $allow_empty = false; + + /** + * @type string + */ + public $type = 'required'; + + /** + * @param array $children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($children, $config, $context) + { + // Flag for subclasses + $this->whitespace = false; + + // if there are no tokens, delete parent node + if (empty($children)) { + return false; + } + + // the new set of children + $result = array(); + + // whether or not parsed character data is allowed + // this controls whether or not we silently drop a tag + // or generate escaped HTML from it + $pcdata_allowed = isset($this->elements['#PCDATA']); + + // a little sanity check to make sure it's not ALL whitespace + $all_whitespace = true; + + $stack = array_reverse($children); + while (!empty($stack)) { + $node = array_pop($stack); + if (!empty($node->is_whitespace)) { + $result[] = $node; + continue; + } + $all_whitespace = false; // phew, we're not talking about whitespace + + if (!isset($this->elements[$node->name])) { + // special case text + // XXX One of these ought to be redundant or something + if ($pcdata_allowed && $node instanceof HTMLPurifier_Node_Text) { + $result[] = $node; + continue; + } + // spill the child contents in + // ToDo: Make configurable + if ($node instanceof HTMLPurifier_Node_Element) { + for ($i = count($node->children) - 1; $i >= 0; $i--) { + $stack[] = $node->children[$i]; + } + continue; + } + continue; + } + $result[] = $node; + } + if (empty($result)) { + return false; + } + if ($all_whitespace) { + $this->whitespace = true; + return false; + } + return $result; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/StrictBlockquote.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/StrictBlockquote.php new file mode 100644 index 0000000..3270a46 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/StrictBlockquote.php @@ -0,0 +1,110 @@ +init($config); + return $this->fake_elements; + } + + /** + * @param array $children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($children, $config, $context) + { + $this->init($config); + + // trick the parent class into thinking it allows more + $this->elements = $this->fake_elements; + $result = parent::validateChildren($children, $config, $context); + $this->elements = $this->real_elements; + + if ($result === false) { + return array(); + } + if ($result === true) { + $result = $children; + } + + $def = $config->getHTMLDefinition(); + $block_wrap_name = $def->info_block_wrapper; + $block_wrap = false; + $ret = array(); + + foreach ($result as $node) { + if ($block_wrap === false) { + if (($node instanceof HTMLPurifier_Node_Text && !$node->is_whitespace) || + ($node instanceof HTMLPurifier_Node_Element && !isset($this->elements[$node->name]))) { + $block_wrap = new HTMLPurifier_Node_Element($def->info_block_wrapper); + $ret[] = $block_wrap; + } + } else { + if ($node instanceof HTMLPurifier_Node_Element && isset($this->elements[$node->name])) { + $block_wrap = false; + + } + } + if ($block_wrap) { + $block_wrap->children[] = $node; + } else { + $ret[] = $node; + } + } + return $ret; + } + + /** + * @param HTMLPurifier_Config $config + */ + private function init($config) + { + if (!$this->init) { + $def = $config->getHTMLDefinition(); + // allow all inline elements + $this->real_elements = $this->elements; + $this->fake_elements = $def->info_content_sets['Flow']; + $this->fake_elements['#PCDATA'] = true; + $this->init = true; + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Table.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Table.php new file mode 100644 index 0000000..d92205b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ChildDef/Table.php @@ -0,0 +1,227 @@ + true, + 'tbody' => true, + 'thead' => true, + 'tfoot' => true, + 'caption' => true, + 'colgroup' => true, + 'col' => true + ); + + public function __construct() + { + } + + /** + * @param array $children + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array + */ + public function validateChildren($children, $config, $context) + { + if (empty($children)) { + return false; + } + + // only one of these elements is allowed in a table + $caption = false; + $thead = false; + $tfoot = false; + + // whitespace + $initial_ws = array(); + $after_caption_ws = array(); + $after_thead_ws = array(); + $after_tfoot_ws = array(); + + // as many of these as you want + $cols = array(); + $content = array(); + + $tbody_mode = false; // if true, then we need to wrap any stray + // s with a . + + $ws_accum =& $initial_ws; + + foreach ($children as $node) { + if ($node instanceof HTMLPurifier_Node_Comment) { + $ws_accum[] = $node; + continue; + } + switch ($node->name) { + case 'tbody': + $tbody_mode = true; + // fall through + case 'tr': + $content[] = $node; + $ws_accum =& $content; + break; + case 'caption': + // there can only be one caption! + if ($caption !== false) break; + $caption = $node; + $ws_accum =& $after_caption_ws; + break; + case 'thead': + $tbody_mode = true; + // XXX This breaks rendering properties with + // Firefox, which never floats a to + // the top. Ever. (Our scheme will float the + // first to the top.) So maybe + // s that are not first should be + // turned into ? Very tricky, indeed. + if ($thead === false) { + $thead = $node; + $ws_accum =& $after_thead_ws; + } else { + // Oops, there's a second one! What + // should we do? Current behavior is to + // transmutate the first and last entries into + // tbody tags, and then put into content. + // Maybe a better idea is to *attach + // it* to the existing thead or tfoot? + // We don't do this, because Firefox + // doesn't float an extra tfoot to the + // bottom like it does for the first one. + $node->name = 'tbody'; + $content[] = $node; + $ws_accum =& $content; + } + break; + case 'tfoot': + // see above for some aveats + $tbody_mode = true; + if ($tfoot === false) { + $tfoot = $node; + $ws_accum =& $after_tfoot_ws; + } else { + $node->name = 'tbody'; + $content[] = $node; + $ws_accum =& $content; + } + break; + case 'colgroup': + case 'col': + $cols[] = $node; + $ws_accum =& $cols; + break; + case '#PCDATA': + // How is whitespace handled? We treat is as sticky to + // the *end* of the previous element. So all of the + // nonsense we have worked on is to keep things + // together. + if (!empty($node->is_whitespace)) { + $ws_accum[] = $node; + } + break; + } + } + + if (empty($content) && $thead === false && $tfoot === false) { + return false; + } + + $ret = $initial_ws; + if ($caption !== false) { + $ret[] = $caption; + $ret = array_merge($ret, $after_caption_ws); + } + if ($cols !== false) { + $ret = array_merge($ret, $cols); + } + if ($thead !== false) { + $ret[] = $thead; + $ret = array_merge($ret, $after_thead_ws); + } + if ($tfoot !== false) { + $ret[] = $tfoot; + $ret = array_merge($ret, $after_tfoot_ws); + } + + if ($tbody_mode) { + // we have to shuffle tr into tbody + $current_tr_tbody = null; + + foreach($content as $node) { + if (!isset($node->name)) { + continue; + } + switch ($node->name) { + case 'tbody': + $current_tr_tbody = null; + $ret[] = $node; + break; + case 'tr': + if ($current_tr_tbody === null) { + $current_tr_tbody = new HTMLPurifier_Node_Element('tbody'); + $ret[] = $current_tr_tbody; + } + $current_tr_tbody->children[] = $node; + break; + case '#PCDATA': + //assert($node->is_whitespace); + if ($current_tr_tbody === null) { + $ret[] = $node; + } else { + $current_tr_tbody->children[] = $node; + } + break; + } + } + } else { + $ret = array_merge($ret, $content); + } + + return $ret; + + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Config.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Config.php new file mode 100644 index 0000000..e6566e8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Config.php @@ -0,0 +1,920 @@ +defaultPlist; + $this->plist = new HTMLPurifier_PropertyList($parent); + $this->def = $definition; // keep a copy around for checking + $this->parser = new HTMLPurifier_VarParser_Flexible(); + } + + /** + * Convenience constructor that creates a config object based on a mixed var + * @param mixed $config Variable that defines the state of the config + * object. Can be: a HTMLPurifier_Config() object, + * an array of directives based on loadArray(), + * or a string filename of an ini file. + * @param HTMLPurifier_ConfigSchema $schema Schema object + * @return HTMLPurifier_Config Configured object + */ + public static function create($config, $schema = null) + { + if ($config instanceof HTMLPurifier_Config) { + // pass-through + return $config; + } + if (!$schema) { + $ret = HTMLPurifier_Config::createDefault(); + } else { + $ret = new HTMLPurifier_Config($schema); + } + if (is_string($config)) { + $ret->loadIni($config); + } elseif (is_array($config)) $ret->loadArray($config); + return $ret; + } + + /** + * Creates a new config object that inherits from a previous one. + * @param HTMLPurifier_Config $config Configuration object to inherit from. + * @return HTMLPurifier_Config object with $config as its parent. + */ + public static function inherit(HTMLPurifier_Config $config) + { + return new HTMLPurifier_Config($config->def, $config->plist); + } + + /** + * Convenience constructor that creates a default configuration object. + * @return HTMLPurifier_Config default object. + */ + public static function createDefault() + { + $definition = HTMLPurifier_ConfigSchema::instance(); + $config = new HTMLPurifier_Config($definition); + return $config; + } + + /** + * Retrieves a value from the configuration. + * + * @param string $key String key + * @param mixed $a + * + * @return mixed + */ + public function get($key, $a = null) + { + if ($a !== null) { + $this->triggerError( + "Using deprecated API: use \$config->get('$key.$a') instead", + E_USER_WARNING + ); + $key = "$key.$a"; + } + if (!$this->finalized) { + $this->autoFinalize(); + } + if (!isset($this->def->info[$key])) { + // can't add % due to SimpleTest bug + $this->triggerError( + 'Cannot retrieve value of undefined directive ' . htmlspecialchars($key), + E_USER_WARNING + ); + return; + } + if (isset($this->def->info[$key]->isAlias)) { + $d = $this->def->info[$key]; + $this->triggerError( + 'Cannot get value from aliased directive, use real name ' . $d->key, + E_USER_ERROR + ); + return; + } + if ($this->lock) { + list($ns) = explode('.', $key); + if ($ns !== $this->lock) { + $this->triggerError( + 'Cannot get value of namespace ' . $ns . ' when lock for ' . + $this->lock . + ' is active, this probably indicates a Definition setup method ' . + 'is accessing directives that are not within its namespace', + E_USER_ERROR + ); + return; + } + } + return $this->plist->get($key); + } + + /** + * Retrieves an array of directives to values from a given namespace + * + * @param string $namespace String namespace + * + * @return array + */ + public function getBatch($namespace) + { + if (!$this->finalized) { + $this->autoFinalize(); + } + $full = $this->getAll(); + if (!isset($full[$namespace])) { + $this->triggerError( + 'Cannot retrieve undefined namespace ' . + htmlspecialchars($namespace), + E_USER_WARNING + ); + return; + } + return $full[$namespace]; + } + + /** + * Returns a SHA-1 signature of a segment of the configuration object + * that uniquely identifies that particular configuration + * + * @param string $namespace Namespace to get serial for + * + * @return string + * @note Revision is handled specially and is removed from the batch + * before processing! + */ + public function getBatchSerial($namespace) + { + if (empty($this->serials[$namespace])) { + $batch = $this->getBatch($namespace); + unset($batch['DefinitionRev']); + $this->serials[$namespace] = sha1(serialize($batch)); + } + return $this->serials[$namespace]; + } + + /** + * Returns a SHA-1 signature for the entire configuration object + * that uniquely identifies that particular configuration + * + * @return string + */ + public function getSerial() + { + if (empty($this->serial)) { + $this->serial = sha1(serialize($this->getAll())); + } + return $this->serial; + } + + /** + * Retrieves all directives, organized by namespace + * + * @warning This is a pretty inefficient function, avoid if you can + */ + public function getAll() + { + if (!$this->finalized) { + $this->autoFinalize(); + } + $ret = array(); + foreach ($this->plist->squash() as $name => $value) { + list($ns, $key) = explode('.', $name, 2); + $ret[$ns][$key] = $value; + } + return $ret; + } + + /** + * Sets a value to configuration. + * + * @param string $key key + * @param mixed $value value + * @param mixed $a + */ + public function set($key, $value, $a = null) + { + if (strpos($key, '.') === false) { + $namespace = $key; + $directive = $value; + $value = $a; + $key = "$key.$directive"; + $this->triggerError("Using deprecated API: use \$config->set('$key', ...) instead", E_USER_NOTICE); + } else { + list($namespace) = explode('.', $key); + } + if ($this->isFinalized('Cannot set directive after finalization')) { + return; + } + if (!isset($this->def->info[$key])) { + $this->triggerError( + 'Cannot set undefined directive ' . htmlspecialchars($key) . ' to value', + E_USER_WARNING + ); + return; + } + $def = $this->def->info[$key]; + + if (isset($def->isAlias)) { + if ($this->aliasMode) { + $this->triggerError( + 'Double-aliases not allowed, please fix '. + 'ConfigSchema bug with' . $key, + E_USER_ERROR + ); + return; + } + $this->aliasMode = true; + $this->set($def->key, $value); + $this->aliasMode = false; + $this->triggerError("$key is an alias, preferred directive name is {$def->key}", E_USER_NOTICE); + return; + } + + // Raw type might be negative when using the fully optimized form + // of stdClass, which indicates allow_null == true + $rtype = is_int($def) ? $def : $def->type; + if ($rtype < 0) { + $type = -$rtype; + $allow_null = true; + } else { + $type = $rtype; + $allow_null = isset($def->allow_null); + } + + try { + $value = $this->parser->parse($value, $type, $allow_null); + } catch (HTMLPurifier_VarParserException $e) { + $this->triggerError( + 'Value for ' . $key . ' is of invalid type, should be ' . + HTMLPurifier_VarParser::getTypeName($type), + E_USER_WARNING + ); + return; + } + if (is_string($value) && is_object($def)) { + // resolve value alias if defined + if (isset($def->aliases[$value])) { + $value = $def->aliases[$value]; + } + // check to see if the value is allowed + if (isset($def->allowed) && !isset($def->allowed[$value])) { + $this->triggerError( + 'Value not supported, valid values are: ' . + $this->_listify($def->allowed), + E_USER_WARNING + ); + return; + } + } + $this->plist->set($key, $value); + + // reset definitions if the directives they depend on changed + // this is a very costly process, so it's discouraged + // with finalization + if ($namespace == 'HTML' || $namespace == 'CSS' || $namespace == 'URI') { + $this->definitions[$namespace] = null; + } + + $this->serials[$namespace] = false; + } + + /** + * Convenience function for error reporting + * + * @param array $lookup + * + * @return string + */ + private function _listify($lookup) + { + $list = array(); + foreach ($lookup as $name => $b) { + $list[] = $name; + } + return implode(', ', $list); + } + + /** + * Retrieves object reference to the HTML definition. + * + * @param bool $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + * @param bool $optimized If true, this method may return null, to + * indicate that a cached version of the modified + * definition object is available and no further edits + * are necessary. Consider using + * maybeGetRawHTMLDefinition, which is more explicitly + * named, instead. + * + * @return HTMLPurifier_HTMLDefinition|null + */ + public function getHTMLDefinition($raw = false, $optimized = false) + { + return $this->getDefinition('HTML', $raw, $optimized); + } + + /** + * Retrieves object reference to the CSS definition + * + * @param bool $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + * @param bool $optimized If true, this method may return null, to + * indicate that a cached version of the modified + * definition object is available and no further edits + * are necessary. Consider using + * maybeGetRawCSSDefinition, which is more explicitly + * named, instead. + * + * @return HTMLPurifier_CSSDefinition|null + */ + public function getCSSDefinition($raw = false, $optimized = false) + { + return $this->getDefinition('CSS', $raw, $optimized); + } + + /** + * Retrieves object reference to the URI definition + * + * @param bool $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + * @param bool $optimized If true, this method may return null, to + * indicate that a cached version of the modified + * definition object is available and no further edits + * are necessary. Consider using + * maybeGetRawURIDefinition, which is more explicitly + * named, instead. + * + * @return HTMLPurifier_URIDefinition|null + */ + public function getURIDefinition($raw = false, $optimized = false) + { + return $this->getDefinition('URI', $raw, $optimized); + } + + /** + * Retrieves a definition + * + * @param string $type Type of definition: HTML, CSS, etc + * @param bool $raw Whether or not definition should be returned raw + * @param bool $optimized Only has an effect when $raw is true. Whether + * or not to return null if the result is already present in + * the cache. This is off by default for backwards + * compatibility reasons, but you need to do things this + * way in order to ensure that caching is done properly. + * Check out enduser-customize.html for more details. + * We probably won't ever change this default, as much as the + * maybe semantics is the "right thing to do." + * + * @throws HTMLPurifier_Exception + * @return HTMLPurifier_Definition|null + */ + public function getDefinition($type, $raw = false, $optimized = false) + { + if ($optimized && !$raw) { + throw new HTMLPurifier_Exception("Cannot set optimized = true when raw = false"); + } + if (!$this->finalized) { + $this->autoFinalize(); + } + // temporarily suspend locks, so we can handle recursive definition calls + $lock = $this->lock; + $this->lock = null; + $factory = HTMLPurifier_DefinitionCacheFactory::instance(); + $cache = $factory->create($type, $this); + $this->lock = $lock; + if (!$raw) { + // full definition + // --------------- + // check if definition is in memory + if (!empty($this->definitions[$type])) { + $def = $this->definitions[$type]; + // check if the definition is setup + if ($def->setup) { + return $def; + } else { + $def->setup($this); + if ($def->optimized) { + $cache->add($def, $this); + } + return $def; + } + } + // check if definition is in cache + $def = $cache->get($this); + if ($def) { + // definition in cache, save to memory and return it + $this->definitions[$type] = $def; + return $def; + } + // initialize it + $def = $this->initDefinition($type); + // set it up + $this->lock = $type; + $def->setup($this); + $this->lock = null; + // save in cache + $cache->add($def, $this); + // return it + return $def; + } else { + // raw definition + // -------------- + // check preconditions + $def = null; + if ($optimized) { + if (is_null($this->get($type . '.DefinitionID'))) { + // fatally error out if definition ID not set + throw new HTMLPurifier_Exception( + "Cannot retrieve raw version without specifying %$type.DefinitionID" + ); + } + } + if (!empty($this->definitions[$type])) { + $def = $this->definitions[$type]; + if ($def->setup && !$optimized) { + $extra = $this->chatty ? + " (try moving this code block earlier in your initialization)" : + ""; + throw new HTMLPurifier_Exception( + "Cannot retrieve raw definition after it has already been setup" . + $extra + ); + } + if ($def->optimized === null) { + $extra = $this->chatty ? " (try flushing your cache)" : ""; + throw new HTMLPurifier_Exception( + "Optimization status of definition is unknown" . $extra + ); + } + if ($def->optimized !== $optimized) { + $msg = $optimized ? "optimized" : "unoptimized"; + $extra = $this->chatty ? + " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)" + : ""; + throw new HTMLPurifier_Exception( + "Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra + ); + } + } + // check if definition was in memory + if ($def) { + if ($def->setup) { + // invariant: $optimized === true (checked above) + return null; + } else { + return $def; + } + } + // if optimized, check if definition was in cache + // (because we do the memory check first, this formulation + // is prone to cache slamming, but I think + // guaranteeing that either /all/ of the raw + // setup code or /none/ of it is run is more important.) + if ($optimized) { + // This code path only gets run once; once we put + // something in $definitions (which is guaranteed by the + // trailing code), we always short-circuit above. + $def = $cache->get($this); + if ($def) { + // save the full definition for later, but don't + // return it yet + $this->definitions[$type] = $def; + return null; + } + } + // check invariants for creation + if (!$optimized) { + if (!is_null($this->get($type . '.DefinitionID'))) { + if ($this->chatty) { + $this->triggerError( + 'Due to a documentation error in previous version of HTML Purifier, your ' . + 'definitions are not being cached. If this is OK, you can remove the ' . + '%$type.DefinitionRev and %$type.DefinitionID declaration. Otherwise, ' . + 'modify your code to use maybeGetRawDefinition, and test if the returned ' . + 'value is null before making any edits (if it is null, that means that a ' . + 'cached version is available, and no raw operations are necessary). See ' . + '' . + 'Customize for more details', + E_USER_WARNING + ); + } else { + $this->triggerError( + "Useless DefinitionID declaration", + E_USER_WARNING + ); + } + } + } + // initialize it + $def = $this->initDefinition($type); + $def->optimized = $optimized; + return $def; + } + throw new HTMLPurifier_Exception("The impossible happened!"); + } + + /** + * Initialise definition + * + * @param string $type What type of definition to create + * + * @return HTMLPurifier_CSSDefinition|HTMLPurifier_HTMLDefinition|HTMLPurifier_URIDefinition + * @throws HTMLPurifier_Exception + */ + private function initDefinition($type) + { + // quick checks failed, let's create the object + if ($type == 'HTML') { + $def = new HTMLPurifier_HTMLDefinition(); + } elseif ($type == 'CSS') { + $def = new HTMLPurifier_CSSDefinition(); + } elseif ($type == 'URI') { + $def = new HTMLPurifier_URIDefinition(); + } else { + throw new HTMLPurifier_Exception( + "Definition of $type type not supported" + ); + } + $this->definitions[$type] = $def; + return $def; + } + + public function maybeGetRawDefinition($name) + { + return $this->getDefinition($name, true, true); + } + + /** + * @return HTMLPurifier_HTMLDefinition|null + */ + public function maybeGetRawHTMLDefinition() + { + return $this->getDefinition('HTML', true, true); + } + + /** + * @return HTMLPurifier_CSSDefinition|null + */ + public function maybeGetRawCSSDefinition() + { + return $this->getDefinition('CSS', true, true); + } + + /** + * @return HTMLPurifier_URIDefinition|null + */ + public function maybeGetRawURIDefinition() + { + return $this->getDefinition('URI', true, true); + } + + /** + * Loads configuration values from an array with the following structure: + * Namespace.Directive => Value + * + * @param array $config_array Configuration associative array + */ + public function loadArray($config_array) + { + if ($this->isFinalized('Cannot load directives after finalization')) { + return; + } + foreach ($config_array as $key => $value) { + $key = str_replace('_', '.', $key); + if (strpos($key, '.') !== false) { + $this->set($key, $value); + } else { + $namespace = $key; + $namespace_values = $value; + foreach ($namespace_values as $directive => $value2) { + $this->set($namespace .'.'. $directive, $value2); + } + } + } + } + + /** + * Returns a list of array(namespace, directive) for all directives + * that are allowed in a web-form context as per an allowed + * namespaces/directives list. + * + * @param array $allowed List of allowed namespaces/directives + * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy + * + * @return array + */ + public static function getAllowedDirectivesForForm($allowed, $schema = null) + { + if (!$schema) { + $schema = HTMLPurifier_ConfigSchema::instance(); + } + if ($allowed !== true) { + if (is_string($allowed)) { + $allowed = array($allowed); + } + $allowed_ns = array(); + $allowed_directives = array(); + $blacklisted_directives = array(); + foreach ($allowed as $ns_or_directive) { + if (strpos($ns_or_directive, '.') !== false) { + // directive + if ($ns_or_directive[0] == '-') { + $blacklisted_directives[substr($ns_or_directive, 1)] = true; + } else { + $allowed_directives[$ns_or_directive] = true; + } + } else { + // namespace + $allowed_ns[$ns_or_directive] = true; + } + } + } + $ret = array(); + foreach ($schema->info as $key => $def) { + list($ns, $directive) = explode('.', $key, 2); + if ($allowed !== true) { + if (isset($blacklisted_directives["$ns.$directive"])) { + continue; + } + if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) { + continue; + } + } + if (isset($def->isAlias)) { + continue; + } + if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') { + continue; + } + $ret[] = array($ns, $directive); + } + return $ret; + } + + /** + * Loads configuration values from $_GET/$_POST that were posted + * via ConfigForm + * + * @param array $array $_GET or $_POST array to import + * @param string|bool $index Index/name that the config variables are in + * @param array|bool $allowed List of allowed namespaces/directives + * @param bool $mq_fix Boolean whether or not to enable magic quotes fix + * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy + * + * @return mixed + */ + public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) + { + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema); + $config = HTMLPurifier_Config::create($ret, $schema); + return $config; + } + + /** + * Merges in configuration values from $_GET/$_POST to object. NOT STATIC. + * + * @param array $array $_GET or $_POST array to import + * @param string|bool $index Index/name that the config variables are in + * @param array|bool $allowed List of allowed namespaces/directives + * @param bool $mq_fix Boolean whether or not to enable magic quotes fix + */ + public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true) + { + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def); + $this->loadArray($ret); + } + + /** + * Prepares an array from a form into something usable for the more + * strict parts of HTMLPurifier_Config + * + * @param array $array $_GET or $_POST array to import + * @param string|bool $index Index/name that the config variables are in + * @param array|bool $allowed List of allowed namespaces/directives + * @param bool $mq_fix Boolean whether or not to enable magic quotes fix + * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy + * + * @return array + */ + public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) + { + if ($index !== false) { + $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array(); + } + $mq = $mq_fix && version_compare(PHP_VERSION, '7.4.0', '<') && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); + + $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema); + $ret = array(); + foreach ($allowed as $key) { + list($ns, $directive) = $key; + $skey = "$ns.$directive"; + if (!empty($array["Null_$skey"])) { + $ret[$ns][$directive] = null; + continue; + } + if (!isset($array[$skey])) { + continue; + } + $value = $mq ? stripslashes($array[$skey]) : $array[$skey]; + $ret[$ns][$directive] = $value; + } + return $ret; + } + + /** + * Loads configuration values from an ini file + * + * @param string $filename Name of ini file + */ + public function loadIni($filename) + { + if ($this->isFinalized('Cannot load directives after finalization')) { + return; + } + $array = parse_ini_file($filename, true); + $this->loadArray($array); + } + + /** + * Checks whether or not the configuration object is finalized. + * + * @param string|bool $error String error message, or false for no error + * + * @return bool + */ + public function isFinalized($error = false) + { + if ($this->finalized && $error) { + $this->triggerError($error, E_USER_ERROR); + } + return $this->finalized; + } + + /** + * Finalizes configuration only if auto finalize is on and not + * already finalized + */ + public function autoFinalize() + { + if ($this->autoFinalize) { + $this->finalize(); + } else { + $this->plist->squash(true); + } + } + + /** + * Finalizes a configuration object, prohibiting further change + */ + public function finalize() + { + $this->finalized = true; + $this->parser = null; + } + + /** + * Produces a nicely formatted error message by supplying the + * stack frame information OUTSIDE of HTMLPurifier_Config. + * + * @param string $msg An error message + * @param int $no An error number + */ + protected function triggerError($msg, $no) + { + // determine previous stack frame + $extra = ''; + if ($this->chatty) { + $trace = debug_backtrace(); + // zip(tail(trace), trace) -- but PHP is not Haskell har har + for ($i = 0, $c = count($trace); $i < $c - 1; $i++) { + // XXX this is not correct on some versions of HTML Purifier + if (isset($trace[$i + 1]['class']) && $trace[$i + 1]['class'] === 'HTMLPurifier_Config') { + continue; + } + $frame = $trace[$i]; + $extra = " invoked on line {$frame['line']} in file {$frame['file']}"; + break; + } + } + trigger_error($msg . $extra, $no); + } + + /** + * Returns a serialized form of the configuration object that can + * be reconstituted. + * + * @return string + */ + public function serialize() + { + $this->getDefinition('HTML'); + $this->getDefinition('CSS'); + $this->getDefinition('URI'); + return serialize($this); + } + +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema.php new file mode 100644 index 0000000..c3fe8cd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema.php @@ -0,0 +1,176 @@ + array( + * 'Directive' => new stdClass(), + * ) + * ) + * + * The stdClass may have the following properties: + * + * - If isAlias isn't set: + * - type: Integer type of directive, see HTMLPurifier_VarParser for definitions + * - allow_null: If set, this directive allows null values + * - aliases: If set, an associative array of value aliases to real values + * - allowed: If set, a lookup array of allowed (string) values + * - If isAlias is set: + * - namespace: Namespace this directive aliases to + * - name: Directive name this directive aliases to + * + * In certain degenerate cases, stdClass will actually be an integer. In + * that case, the value is equivalent to an stdClass with the type + * property set to the integer. If the integer is negative, type is + * equal to the absolute value of integer, and allow_null is true. + * + * This class is friendly with HTMLPurifier_Config. If you need introspection + * about the schema, you're better of using the ConfigSchema_Interchange, + * which uses more memory but has much richer information. + * @type array + */ + public $info = array(); + + /** + * Application-wide singleton + * @type HTMLPurifier_ConfigSchema + */ + protected static $singleton; + + public function __construct() + { + $this->defaultPlist = new HTMLPurifier_PropertyList(); + } + + /** + * Unserializes the default ConfigSchema. + * @return HTMLPurifier_ConfigSchema + */ + public static function makeFromSerial() + { + $contents = file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'); + $r = unserialize($contents); + if (!$r) { + $hash = sha1($contents); + trigger_error("Unserialization of configuration schema failed, sha1 of file was $hash", E_USER_ERROR); + } + return $r; + } + + /** + * Retrieves an instance of the application-wide configuration definition. + * @param HTMLPurifier_ConfigSchema $prototype + * @return HTMLPurifier_ConfigSchema + */ + public static function instance($prototype = null) + { + if ($prototype !== null) { + HTMLPurifier_ConfigSchema::$singleton = $prototype; + } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) { + HTMLPurifier_ConfigSchema::$singleton = HTMLPurifier_ConfigSchema::makeFromSerial(); + } + return HTMLPurifier_ConfigSchema::$singleton; + } + + /** + * Defines a directive for configuration + * @warning Will fail of directive's namespace is defined. + * @warning This method's signature is slightly different from the legacy + * define() static method! Beware! + * @param string $key Name of directive + * @param mixed $default Default value of directive + * @param string $type Allowed type of the directive. See + * HTMLPurifier_VarParser::$types for allowed values + * @param bool $allow_null Whether or not to allow null values + */ + public function add($key, $default, $type, $allow_null) + { + $obj = new stdClass(); + $obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type]; + if ($allow_null) { + $obj->allow_null = true; + } + $this->info[$key] = $obj; + $this->defaults[$key] = $default; + $this->defaultPlist->set($key, $default); + } + + /** + * Defines a directive value alias. + * + * Directive value aliases are convenient for developers because it lets + * them set a directive to several values and get the same result. + * @param string $key Name of Directive + * @param array $aliases Hash of aliased values to the real alias + */ + public function addValueAliases($key, $aliases) + { + if (!isset($this->info[$key]->aliases)) { + $this->info[$key]->aliases = array(); + } + foreach ($aliases as $alias => $real) { + $this->info[$key]->aliases[$alias] = $real; + } + } + + /** + * Defines a set of allowed values for a directive. + * @warning This is slightly different from the corresponding static + * method definition. + * @param string $key Name of directive + * @param array $allowed Lookup array of allowed values + */ + public function addAllowedValues($key, $allowed) + { + $this->info[$key]->allowed = $allowed; + } + + /** + * Defines a directive alias for backwards compatibility + * @param string $key Directive that will be aliased + * @param string $new_key Directive that the alias will be to + */ + public function addAlias($key, $new_key) + { + $obj = new stdClass; + $obj->key = $new_key; + $obj->isAlias = true; + $this->info[$key] = $obj; + } + + /** + * Replaces any stdClass that only has the type property with type integer. + */ + public function postProcess() + { + foreach ($this->info as $key => $v) { + if (count((array) $v) == 1) { + $this->info[$key] = $v->type; + } elseif (count((array) $v) == 2 && isset($v->allow_null)) { + $this->info[$key] = -$v->type; + } + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php new file mode 100644 index 0000000..d5906cd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php @@ -0,0 +1,48 @@ +directives as $d) { + $schema->add( + $d->id->key, + $d->default, + $d->type, + $d->typeAllowsNull + ); + if ($d->allowed !== null) { + $schema->addAllowedValues( + $d->id->key, + $d->allowed + ); + } + foreach ($d->aliases as $alias) { + $schema->addAlias( + $alias->key, + $d->id->key + ); + } + if ($d->valueAliases !== null) { + $schema->addValueAliases( + $d->id->key, + $d->valueAliases + ); + } + } + $schema->postProcess(); + return $schema; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Builder/Xml.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Builder/Xml.php new file mode 100644 index 0000000..5fa56f7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Builder/Xml.php @@ -0,0 +1,144 @@ +startElement('div'); + + $purifier = HTMLPurifier::getInstance(); + $html = $purifier->purify($html); + $this->writeAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + $this->writeRaw($html); + + $this->endElement(); // div + } + + /** + * @param mixed $var + * @return string + */ + protected function export($var) + { + if ($var === array()) { + return 'array()'; + } + return var_export($var, true); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + */ + public function build($interchange) + { + // global access, only use as last resort + $this->interchange = $interchange; + + $this->setIndent(true); + $this->startDocument('1.0', 'UTF-8'); + $this->startElement('configdoc'); + $this->writeElement('title', $interchange->name); + + foreach ($interchange->directives as $directive) { + $this->buildDirective($directive); + } + + if ($this->namespace) { + $this->endElement(); + } // namespace + + $this->endElement(); // configdoc + $this->flush(); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive + */ + public function buildDirective($directive) + { + // Kludge, although I suppose having a notion of a "root namespace" + // certainly makes things look nicer when documentation is built. + // Depends on things being sorted. + if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) { + if ($this->namespace) { + $this->endElement(); + } // namespace + $this->namespace = $directive->id->getRootNamespace(); + $this->startElement('namespace'); + $this->writeAttribute('id', $this->namespace); + $this->writeElement('name', $this->namespace); + } + + $this->startElement('directive'); + $this->writeAttribute('id', $directive->id->toString()); + + $this->writeElement('name', $directive->id->getDirective()); + + $this->startElement('aliases'); + foreach ($directive->aliases as $alias) { + $this->writeElement('alias', $alias->toString()); + } + $this->endElement(); // aliases + + $this->startElement('constraints'); + if ($directive->version) { + $this->writeElement('version', $directive->version); + } + $this->startElement('type'); + if ($directive->typeAllowsNull) { + $this->writeAttribute('allow-null', 'yes'); + } + $this->text($directive->type); + $this->endElement(); // type + if ($directive->allowed) { + $this->startElement('allowed'); + foreach ($directive->allowed as $value => $x) { + $this->writeElement('value', $value); + } + $this->endElement(); // allowed + } + $this->writeElement('default', $this->export($directive->default)); + $this->writeAttribute('xml:space', 'preserve'); + if ($directive->external) { + $this->startElement('external'); + foreach ($directive->external as $project) { + $this->writeElement('project', $project); + } + $this->endElement(); + } + $this->endElement(); // constraints + + if ($directive->deprecatedVersion) { + $this->startElement('deprecated'); + $this->writeElement('version', $directive->deprecatedVersion); + $this->writeElement('use', $directive->deprecatedUse->toString()); + $this->endElement(); // deprecated + } + + $this->startElement('description'); + $this->writeHTMLDiv($directive->description); + $this->endElement(); // description + + $this->endElement(); // directive + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Exception.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Exception.php new file mode 100644 index 0000000..2671516 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Exception.php @@ -0,0 +1,11 @@ + array(directive info) + * @type HTMLPurifier_ConfigSchema_Interchange_Directive[] + */ + public $directives = array(); + + /** + * Adds a directive array to $directives + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive + * @throws HTMLPurifier_ConfigSchema_Exception + */ + public function addDirective($directive) + { + if (isset($this->directives[$i = $directive->id->toString()])) { + throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine directive '$i'"); + } + $this->directives[$i] = $directive; + } + + /** + * Convenience function to perform standard validation. Throws exception + * on failed validation. + */ + public function validate() + { + $validator = new HTMLPurifier_ConfigSchema_Validator(); + return $validator->validate($this); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Interchange/Directive.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Interchange/Directive.php new file mode 100644 index 0000000..127a39a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Interchange/Directive.php @@ -0,0 +1,89 @@ + true). + * Null if all values are allowed. + * @type array + */ + public $allowed; + + /** + * List of aliases for the directive. + * e.g. array(new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir'))). + * @type HTMLPurifier_ConfigSchema_Interchange_Id[] + */ + public $aliases = array(); + + /** + * Hash of value aliases, e.g. array('alt' => 'real'). Null if value + * aliasing is disabled (necessary for non-scalar types). + * @type array + */ + public $valueAliases; + + /** + * Version of HTML Purifier the directive was introduced, e.g. '1.3.1'. + * Null if the directive has always existed. + * @type string + */ + public $version; + + /** + * ID of directive that supercedes this old directive. + * Null if not deprecated. + * @type HTMLPurifier_ConfigSchema_Interchange_Id + */ + public $deprecatedUse; + + /** + * Version of HTML Purifier this directive was deprecated. Null if not + * deprecated. + * @type string + */ + public $deprecatedVersion; + + /** + * List of external projects this directive depends on, e.g. array('CSSTidy'). + * @type array + */ + public $external = array(); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Interchange/Id.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Interchange/Id.php new file mode 100644 index 0000000..126f09d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Interchange/Id.php @@ -0,0 +1,58 @@ +key = $key; + } + + /** + * @return string + * @warning This is NOT magic, to ensure that people don't abuse SPL and + * cause problems for PHP 5.0 support. + */ + public function toString() + { + return $this->key; + } + + /** + * @return string + */ + public function getRootNamespace() + { + return substr($this->key, 0, strpos($this->key, ".")); + } + + /** + * @return string + */ + public function getDirective() + { + return substr($this->key, strpos($this->key, ".") + 1); + } + + /** + * @param string $id + * @return HTMLPurifier_ConfigSchema_Interchange_Id + */ + public static function make($id) + { + return new HTMLPurifier_ConfigSchema_Interchange_Id($id); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/InterchangeBuilder.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/InterchangeBuilder.php new file mode 100644 index 0000000..655e6dd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/InterchangeBuilder.php @@ -0,0 +1,226 @@ +varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native(); + } + + /** + * @param string $dir + * @return HTMLPurifier_ConfigSchema_Interchange + */ + public static function buildFromDirectory($dir = null) + { + $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); + $interchange = new HTMLPurifier_ConfigSchema_Interchange(); + return $builder->buildDir($interchange, $dir); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param string $dir + * @return HTMLPurifier_ConfigSchema_Interchange + */ + public function buildDir($interchange, $dir = null) + { + if (!$dir) { + $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema'; + } + if (file_exists($dir . '/info.ini')) { + $info = parse_ini_file($dir . '/info.ini'); + $interchange->name = $info['name']; + } + + $files = array(); + $dh = opendir($dir); + while (false !== ($file = readdir($dh))) { + if (!$file || $file[0] == '.' || strrchr($file, '.') !== '.txt') { + continue; + } + $files[] = $file; + } + closedir($dh); + + sort($files); + foreach ($files as $file) { + $this->buildFile($interchange, $dir . '/' . $file); + } + return $interchange; + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param string $file + */ + public function buildFile($interchange, $file) + { + $parser = new HTMLPurifier_StringHashParser(); + $this->build( + $interchange, + new HTMLPurifier_StringHash($parser->parseFile($file)) + ); + } + + /** + * Builds an interchange object based on a hash. + * @param HTMLPurifier_ConfigSchema_Interchange $interchange HTMLPurifier_ConfigSchema_Interchange object to build + * @param HTMLPurifier_StringHash $hash source data + * @throws HTMLPurifier_ConfigSchema_Exception + */ + public function build($interchange, $hash) + { + if (!$hash instanceof HTMLPurifier_StringHash) { + $hash = new HTMLPurifier_StringHash($hash); + } + if (!isset($hash['ID'])) { + throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID'); + } + if (strpos($hash['ID'], '.') === false) { + if (count($hash) == 2 && isset($hash['DESCRIPTION'])) { + $hash->offsetGet('DESCRIPTION'); // prevent complaining + } else { + throw new HTMLPurifier_ConfigSchema_Exception('All directives must have a namespace'); + } + } else { + $this->buildDirective($interchange, $hash); + } + $this->_findUnused($hash); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param HTMLPurifier_StringHash $hash + * @throws HTMLPurifier_ConfigSchema_Exception + */ + public function buildDirective($interchange, $hash) + { + $directive = new HTMLPurifier_ConfigSchema_Interchange_Directive(); + + // These are required elements: + $directive->id = $this->id($hash->offsetGet('ID')); + $id = $directive->id->toString(); // convenience + + if (isset($hash['TYPE'])) { + $type = explode('/', $hash->offsetGet('TYPE')); + if (isset($type[1])) { + $directive->typeAllowsNull = true; + } + $directive->type = $type[0]; + } else { + throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined"); + } + + if (isset($hash['DEFAULT'])) { + try { + $directive->default = $this->varParser->parse( + $hash->offsetGet('DEFAULT'), + $directive->type, + $directive->typeAllowsNull + ); + } catch (HTMLPurifier_VarParserException $e) { + throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'"); + } + } + + if (isset($hash['DESCRIPTION'])) { + $directive->description = $hash->offsetGet('DESCRIPTION'); + } + + if (isset($hash['ALLOWED'])) { + $directive->allowed = $this->lookup($this->evalArray($hash->offsetGet('ALLOWED'))); + } + + if (isset($hash['VALUE-ALIASES'])) { + $directive->valueAliases = $this->evalArray($hash->offsetGet('VALUE-ALIASES')); + } + + if (isset($hash['ALIASES'])) { + $raw_aliases = trim($hash->offsetGet('ALIASES')); + $aliases = preg_split('/\s*,\s*/', $raw_aliases); + foreach ($aliases as $alias) { + $directive->aliases[] = $this->id($alias); + } + } + + if (isset($hash['VERSION'])) { + $directive->version = $hash->offsetGet('VERSION'); + } + + if (isset($hash['DEPRECATED-USE'])) { + $directive->deprecatedUse = $this->id($hash->offsetGet('DEPRECATED-USE')); + } + + if (isset($hash['DEPRECATED-VERSION'])) { + $directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION'); + } + + if (isset($hash['EXTERNAL'])) { + $directive->external = preg_split('/\s*,\s*/', trim($hash->offsetGet('EXTERNAL'))); + } + + $interchange->addDirective($directive); + } + + /** + * Evaluates an array PHP code string without array() wrapper + * @param string $contents + */ + protected function evalArray($contents) + { + return eval('return array(' . $contents . ');'); + } + + /** + * Converts an array list into a lookup array. + * @param array $array + * @return array + */ + protected function lookup($array) + { + $ret = array(); + foreach ($array as $val) { + $ret[$val] = true; + } + return $ret; + } + + /** + * Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id + * object based on a string Id. + * @param string $id + * @return HTMLPurifier_ConfigSchema_Interchange_Id + */ + protected function id($id) + { + return HTMLPurifier_ConfigSchema_Interchange_Id::make($id); + } + + /** + * Triggers errors for any unused keys passed in the hash; such keys + * may indicate typos, missing values, etc. + * @param HTMLPurifier_StringHash $hash Hash to check. + */ + protected function _findUnused($hash) + { + $accessed = $hash->getAccessed(); + foreach ($hash as $k => $v) { + if (!isset($accessed[$k])) { + trigger_error("String hash key '$k' not used by builder", E_USER_NOTICE); + } + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Validator.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Validator.php new file mode 100644 index 0000000..fb31277 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/Validator.php @@ -0,0 +1,248 @@ +parser = new HTMLPurifier_VarParser(); + } + + /** + * Validates a fully-formed interchange object. + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @return bool + */ + public function validate($interchange) + { + $this->interchange = $interchange; + $this->aliases = array(); + // PHP is a bit lax with integer <=> string conversions in + // arrays, so we don't use the identical !== comparison + foreach ($interchange->directives as $i => $directive) { + $id = $directive->id->toString(); + if ($i != $id) { + $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'"); + } + $this->validateDirective($directive); + } + return true; + } + + /** + * Validates a HTMLPurifier_ConfigSchema_Interchange_Id object. + * @param HTMLPurifier_ConfigSchema_Interchange_Id $id + */ + public function validateId($id) + { + $id_string = $id->toString(); + $this->context[] = "id '$id_string'"; + if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) { + // handled by InterchangeBuilder + $this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id'); + } + // keys are now unconstrained (we might want to narrow down to A-Za-z0-9.) + // we probably should check that it has at least one namespace + $this->with($id, 'key') + ->assertNotEmpty() + ->assertIsString(); // implicit assertIsString handled by InterchangeBuilder + array_pop($this->context); + } + + /** + * Validates a HTMLPurifier_ConfigSchema_Interchange_Directive object. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirective($d) + { + $id = $d->id->toString(); + $this->context[] = "directive '$id'"; + $this->validateId($d->id); + + $this->with($d, 'description') + ->assertNotEmpty(); + + // BEGIN - handled by InterchangeBuilder + $this->with($d, 'type') + ->assertNotEmpty(); + $this->with($d, 'typeAllowsNull') + ->assertIsBool(); + try { + // This also tests validity of $d->type + $this->parser->parse($d->default, $d->type, $d->typeAllowsNull); + } catch (HTMLPurifier_VarParserException $e) { + $this->error('default', 'had error: ' . $e->getMessage()); + } + // END - handled by InterchangeBuilder + + if (!is_null($d->allowed) || !empty($d->valueAliases)) { + // allowed and valueAliases require that we be dealing with + // strings, so check for that early. + $d_int = HTMLPurifier_VarParser::$types[$d->type]; + if (!isset(HTMLPurifier_VarParser::$stringTypes[$d_int])) { + $this->error('type', 'must be a string type when used with allowed or value aliases'); + } + } + + $this->validateDirectiveAllowed($d); + $this->validateDirectiveValueAliases($d); + $this->validateDirectiveAliases($d); + + array_pop($this->context); + } + + /** + * Extra validation if $allowed member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirectiveAllowed($d) + { + if (is_null($d->allowed)) { + return; + } + $this->with($d, 'allowed') + ->assertNotEmpty() + ->assertIsLookup(); // handled by InterchangeBuilder + if (is_string($d->default) && !isset($d->allowed[$d->default])) { + $this->error('default', 'must be an allowed value'); + } + $this->context[] = 'allowed'; + foreach ($d->allowed as $val => $x) { + if (!is_string($val)) { + $this->error("value $val", 'must be a string'); + } + } + array_pop($this->context); + } + + /** + * Extra validation if $valueAliases member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirectiveValueAliases($d) + { + if (is_null($d->valueAliases)) { + return; + } + $this->with($d, 'valueAliases') + ->assertIsArray(); // handled by InterchangeBuilder + $this->context[] = 'valueAliases'; + foreach ($d->valueAliases as $alias => $real) { + if (!is_string($alias)) { + $this->error("alias $alias", 'must be a string'); + } + if (!is_string($real)) { + $this->error("alias target $real from alias '$alias'", 'must be a string'); + } + if ($alias === $real) { + $this->error("alias '$alias'", "must not be an alias to itself"); + } + } + if (!is_null($d->allowed)) { + foreach ($d->valueAliases as $alias => $real) { + if (isset($d->allowed[$alias])) { + $this->error("alias '$alias'", 'must not be an allowed value'); + } elseif (!isset($d->allowed[$real])) { + $this->error("alias '$alias'", 'must be an alias to an allowed value'); + } + } + } + array_pop($this->context); + } + + /** + * Extra validation if $aliases member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirectiveAliases($d) + { + $this->with($d, 'aliases') + ->assertIsArray(); // handled by InterchangeBuilder + $this->context[] = 'aliases'; + foreach ($d->aliases as $alias) { + $this->validateId($alias); + $s = $alias->toString(); + if (isset($this->interchange->directives[$s])) { + $this->error("alias '$s'", 'collides with another directive'); + } + if (isset($this->aliases[$s])) { + $other_directive = $this->aliases[$s]; + $this->error("alias '$s'", "collides with alias for directive '$other_directive'"); + } + $this->aliases[$s] = $d->id->toString(); + } + array_pop($this->context); + } + + // protected helper functions + + /** + * Convenience function for generating HTMLPurifier_ConfigSchema_ValidatorAtom + * for validating simple member variables of objects. + * @param $obj + * @param $member + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + protected function with($obj, $member) + { + return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member); + } + + /** + * Emits an error, providing helpful context. + * @throws HTMLPurifier_ConfigSchema_Exception + */ + protected function error($target, $msg) + { + if ($target !== false) { + $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext(); + } else { + $prefix = ucfirst($this->getFormattedContext()); + } + throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg)); + } + + /** + * Returns a formatted context string. + * @return string + */ + protected function getFormattedContext() + { + return implode(' in ', array_reverse($this->context)); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/ValidatorAtom.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/ValidatorAtom.php new file mode 100644 index 0000000..c9aa364 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/ValidatorAtom.php @@ -0,0 +1,130 @@ +context = $context; + $this->obj = $obj; + $this->member = $member; + $this->contents =& $obj->$member; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsString() + { + if (!is_string($this->contents)) { + $this->error('must be a string'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsBool() + { + if (!is_bool($this->contents)) { + $this->error('must be a boolean'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsArray() + { + if (!is_array($this->contents)) { + $this->error('must be an array'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertNotNull() + { + if ($this->contents === null) { + $this->error('must not be null'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertAlnum() + { + $this->assertIsString(); + if (!ctype_alnum($this->contents)) { + $this->error('must be alphanumeric'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertNotEmpty() + { + if (empty($this->contents)) { + $this->error('must not be empty'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsLookup() + { + $this->assertIsArray(); + foreach ($this->contents as $v) { + if ($v !== true) { + $this->error('must be a lookup array'); + } + } + return $this; + } + + /** + * @param string $msg + * @throws HTMLPurifier_ConfigSchema_Exception + */ + protected function error($msg) + { + throw new HTMLPurifier_ConfigSchema_Exception(ucfirst($this->member) . ' in ' . $this->context . ' ' . $msg); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema.ser b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema.ser new file mode 100644 index 0000000..3cd756b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema.ser @@ -0,0 +1 @@ +O:25:"HTMLPurifier_ConfigSchema":3:{s:8:"defaults";a:128:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:17:"Core.RemoveBlanks";b:0;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:10:"HTML.Forms";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:12:"defaultPlist";O:25:"HTMLPurifier_PropertyList":3:{s:7:"*data";a:128:{s:19:"Attr.AllowedClasses";N;s:24:"Attr.AllowedFrameTargets";a:0:{}s:15:"Attr.AllowedRel";a:0:{}s:15:"Attr.AllowedRev";a:0:{}s:18:"Attr.ClassUseCDATA";N;s:20:"Attr.DefaultImageAlt";N;s:24:"Attr.DefaultInvalidImage";s:0:"";s:27:"Attr.DefaultInvalidImageAlt";s:13:"Invalid image";s:19:"Attr.DefaultTextDir";s:3:"ltr";s:13:"Attr.EnableID";b:0;s:21:"Attr.ForbiddenClasses";a:0:{}s:13:"Attr.ID.HTML5";N;s:16:"Attr.IDBlacklist";a:0:{}s:22:"Attr.IDBlacklistRegexp";N;s:13:"Attr.IDPrefix";s:0:"";s:18:"Attr.IDPrefixLocal";s:0:"";s:24:"AutoFormat.AutoParagraph";b:0;s:17:"AutoFormat.Custom";a:0:{}s:25:"AutoFormat.DisplayLinkURI";b:0;s:18:"AutoFormat.Linkify";b:0;s:33:"AutoFormat.PurifierLinkify.DocURL";s:3:"#%s";s:26:"AutoFormat.PurifierLinkify";b:0;s:32:"AutoFormat.RemoveEmpty.Predicate";a:4:{s:8:"colgroup";a:0:{}s:2:"th";a:0:{}s:2:"td";a:0:{}s:6:"iframe";a:1:{i:0;s:3:"src";}}s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";a:2:{s:2:"td";b:1;s:2:"th";b:1;}s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";b:0;s:22:"AutoFormat.RemoveEmpty";b:0;s:39:"AutoFormat.RemoveSpansWithoutAttributes";b:0;s:19:"CSS.AllowDuplicates";b:0;s:18:"CSS.AllowImportant";b:0;s:15:"CSS.AllowTricky";b:0;s:16:"CSS.AllowedFonts";N;s:21:"CSS.AllowedProperties";N;s:17:"CSS.DefinitionRev";i:1;s:23:"CSS.ForbiddenProperties";a:0:{}s:16:"CSS.MaxImgLength";s:6:"1200px";s:15:"CSS.Proprietary";b:0;s:11:"CSS.Trusted";b:0;s:20:"Cache.DefinitionImpl";s:10:"Serializer";s:20:"Cache.SerializerPath";N;s:27:"Cache.SerializerPermissions";i:493;s:22:"Core.AggressivelyFixLt";b:1;s:29:"Core.AggressivelyRemoveScript";b:1;s:28:"Core.AllowHostnameUnderscore";b:0;s:23:"Core.AllowParseManyTags";b:0;s:18:"Core.CollectErrors";b:0;s:18:"Core.ColorKeywords";a:148:{s:9:"aliceblue";s:7:"#F0F8FF";s:12:"antiquewhite";s:7:"#FAEBD7";s:4:"aqua";s:7:"#00FFFF";s:10:"aquamarine";s:7:"#7FFFD4";s:5:"azure";s:7:"#F0FFFF";s:5:"beige";s:7:"#F5F5DC";s:6:"bisque";s:7:"#FFE4C4";s:5:"black";s:7:"#000000";s:14:"blanchedalmond";s:7:"#FFEBCD";s:4:"blue";s:7:"#0000FF";s:10:"blueviolet";s:7:"#8A2BE2";s:5:"brown";s:7:"#A52A2A";s:9:"burlywood";s:7:"#DEB887";s:9:"cadetblue";s:7:"#5F9EA0";s:10:"chartreuse";s:7:"#7FFF00";s:9:"chocolate";s:7:"#D2691E";s:5:"coral";s:7:"#FF7F50";s:14:"cornflowerblue";s:7:"#6495ED";s:8:"cornsilk";s:7:"#FFF8DC";s:7:"crimson";s:7:"#DC143C";s:4:"cyan";s:7:"#00FFFF";s:8:"darkblue";s:7:"#00008B";s:8:"darkcyan";s:7:"#008B8B";s:13:"darkgoldenrod";s:7:"#B8860B";s:8:"darkgray";s:7:"#A9A9A9";s:8:"darkgrey";s:7:"#A9A9A9";s:9:"darkgreen";s:7:"#006400";s:9:"darkkhaki";s:7:"#BDB76B";s:11:"darkmagenta";s:7:"#8B008B";s:14:"darkolivegreen";s:7:"#556B2F";s:10:"darkorange";s:7:"#FF8C00";s:10:"darkorchid";s:7:"#9932CC";s:7:"darkred";s:7:"#8B0000";s:10:"darksalmon";s:7:"#E9967A";s:12:"darkseagreen";s:7:"#8FBC8F";s:13:"darkslateblue";s:7:"#483D8B";s:13:"darkslategray";s:7:"#2F4F4F";s:13:"darkslategrey";s:7:"#2F4F4F";s:13:"darkturquoise";s:7:"#00CED1";s:10:"darkviolet";s:7:"#9400D3";s:8:"deeppink";s:7:"#FF1493";s:11:"deepskyblue";s:7:"#00BFFF";s:7:"dimgray";s:7:"#696969";s:7:"dimgrey";s:7:"#696969";s:10:"dodgerblue";s:7:"#1E90FF";s:9:"firebrick";s:7:"#B22222";s:11:"floralwhite";s:7:"#FFFAF0";s:11:"forestgreen";s:7:"#228B22";s:7:"fuchsia";s:7:"#FF00FF";s:9:"gainsboro";s:7:"#DCDCDC";s:10:"ghostwhite";s:7:"#F8F8FF";s:4:"gold";s:7:"#FFD700";s:9:"goldenrod";s:7:"#DAA520";s:4:"gray";s:7:"#808080";s:4:"grey";s:7:"#808080";s:5:"green";s:7:"#008000";s:11:"greenyellow";s:7:"#ADFF2F";s:8:"honeydew";s:7:"#F0FFF0";s:7:"hotpink";s:7:"#FF69B4";s:9:"indianred";s:7:"#CD5C5C";s:6:"indigo";s:7:"#4B0082";s:5:"ivory";s:7:"#FFFFF0";s:5:"khaki";s:7:"#F0E68C";s:8:"lavender";s:7:"#E6E6FA";s:13:"lavenderblush";s:7:"#FFF0F5";s:9:"lawngreen";s:7:"#7CFC00";s:12:"lemonchiffon";s:7:"#FFFACD";s:9:"lightblue";s:7:"#ADD8E6";s:10:"lightcoral";s:7:"#F08080";s:9:"lightcyan";s:7:"#E0FFFF";s:20:"lightgoldenrodyellow";s:7:"#FAFAD2";s:9:"lightgray";s:7:"#D3D3D3";s:9:"lightgrey";s:7:"#D3D3D3";s:10:"lightgreen";s:7:"#90EE90";s:9:"lightpink";s:7:"#FFB6C1";s:11:"lightsalmon";s:7:"#FFA07A";s:13:"lightseagreen";s:7:"#20B2AA";s:12:"lightskyblue";s:7:"#87CEFA";s:14:"lightslategray";s:7:"#778899";s:14:"lightslategrey";s:7:"#778899";s:14:"lightsteelblue";s:7:"#B0C4DE";s:11:"lightyellow";s:7:"#FFFFE0";s:4:"lime";s:7:"#00FF00";s:9:"limegreen";s:7:"#32CD32";s:5:"linen";s:7:"#FAF0E6";s:7:"magenta";s:7:"#FF00FF";s:6:"maroon";s:7:"#800000";s:16:"mediumaquamarine";s:7:"#66CDAA";s:10:"mediumblue";s:7:"#0000CD";s:12:"mediumorchid";s:7:"#BA55D3";s:12:"mediumpurple";s:7:"#9370DB";s:14:"mediumseagreen";s:7:"#3CB371";s:15:"mediumslateblue";s:7:"#7B68EE";s:17:"mediumspringgreen";s:7:"#00FA9A";s:15:"mediumturquoise";s:7:"#48D1CC";s:15:"mediumvioletred";s:7:"#C71585";s:12:"midnightblue";s:7:"#191970";s:9:"mintcream";s:7:"#F5FFFA";s:9:"mistyrose";s:7:"#FFE4E1";s:8:"moccasin";s:7:"#FFE4B5";s:11:"navajowhite";s:7:"#FFDEAD";s:4:"navy";s:7:"#000080";s:7:"oldlace";s:7:"#FDF5E6";s:5:"olive";s:7:"#808000";s:9:"olivedrab";s:7:"#6B8E23";s:6:"orange";s:7:"#FFA500";s:9:"orangered";s:7:"#FF4500";s:6:"orchid";s:7:"#DA70D6";s:13:"palegoldenrod";s:7:"#EEE8AA";s:9:"palegreen";s:7:"#98FB98";s:13:"paleturquoise";s:7:"#AFEEEE";s:13:"palevioletred";s:7:"#DB7093";s:10:"papayawhip";s:7:"#FFEFD5";s:9:"peachpuff";s:7:"#FFDAB9";s:4:"peru";s:7:"#CD853F";s:4:"pink";s:7:"#FFC0CB";s:4:"plum";s:7:"#DDA0DD";s:10:"powderblue";s:7:"#B0E0E6";s:6:"purple";s:7:"#800080";s:13:"rebeccapurple";s:7:"#663399";s:3:"red";s:7:"#FF0000";s:9:"rosybrown";s:7:"#BC8F8F";s:9:"royalblue";s:7:"#4169E1";s:11:"saddlebrown";s:7:"#8B4513";s:6:"salmon";s:7:"#FA8072";s:10:"sandybrown";s:7:"#F4A460";s:8:"seagreen";s:7:"#2E8B57";s:8:"seashell";s:7:"#FFF5EE";s:6:"sienna";s:7:"#A0522D";s:6:"silver";s:7:"#C0C0C0";s:7:"skyblue";s:7:"#87CEEB";s:9:"slateblue";s:7:"#6A5ACD";s:9:"slategray";s:7:"#708090";s:9:"slategrey";s:7:"#708090";s:4:"snow";s:7:"#FFFAFA";s:11:"springgreen";s:7:"#00FF7F";s:9:"steelblue";s:7:"#4682B4";s:3:"tan";s:7:"#D2B48C";s:4:"teal";s:7:"#008080";s:7:"thistle";s:7:"#D8BFD8";s:6:"tomato";s:7:"#FF6347";s:9:"turquoise";s:7:"#40E0D0";s:6:"violet";s:7:"#EE82EE";s:5:"wheat";s:7:"#F5DEB3";s:5:"white";s:7:"#FFFFFF";s:10:"whitesmoke";s:7:"#F5F5F5";s:6:"yellow";s:7:"#FFFF00";s:11:"yellowgreen";s:7:"#9ACD32";}s:30:"Core.ConvertDocumentToFragment";b:1;s:36:"Core.DirectLexLineNumberSyncInterval";i:0;s:20:"Core.DisableExcludes";b:0;s:15:"Core.EnableIDNA";b:0;s:13:"Core.Encoding";s:5:"utf-8";s:26:"Core.EscapeInvalidChildren";b:0;s:22:"Core.EscapeInvalidTags";b:0;s:29:"Core.EscapeNonASCIICharacters";b:0;s:19:"Core.HiddenElements";a:2:{s:6:"script";b:1;s:5:"style";b:1;}s:13:"Core.Language";s:2:"en";s:24:"Core.LegacyEntityDecoder";b:0;s:14:"Core.LexerImpl";N;s:24:"Core.MaintainLineNumbers";N;s:22:"Core.NormalizeNewlines";b:1;s:17:"Core.RemoveBlanks";b:0;s:21:"Core.RemoveInvalidImg";b:1;s:33:"Core.RemoveProcessingInstructions";b:0;s:25:"Core.RemoveScriptContents";N;s:13:"Filter.Custom";a:0:{}s:34:"Filter.ExtractStyleBlocks.Escaping";b:1;s:31:"Filter.ExtractStyleBlocks.Scope";N;s:34:"Filter.ExtractStyleBlocks.TidyImpl";N;s:25:"Filter.ExtractStyleBlocks";b:0;s:14:"Filter.YouTube";b:0;s:12:"HTML.Allowed";N;s:22:"HTML.AllowedAttributes";N;s:20:"HTML.AllowedComments";a:0:{}s:26:"HTML.AllowedCommentsRegexp";N;s:20:"HTML.AllowedElements";N;s:19:"HTML.AllowedModules";N;s:23:"HTML.Attr.Name.UseCDATA";b:0;s:17:"HTML.BlockWrapper";s:1:"p";s:16:"HTML.CoreModules";a:7:{s:9:"Structure";b:1;s:4:"Text";b:1;s:9:"Hypertext";b:1;s:4:"List";b:1;s:22:"NonXMLCommonAttributes";b:1;s:19:"XMLCommonAttributes";b:1;s:16:"CommonAttributes";b:1;}s:18:"HTML.CustomDoctype";N;s:17:"HTML.DefinitionID";N;s:18:"HTML.DefinitionRev";i:1;s:12:"HTML.Doctype";N;s:25:"HTML.FlashAllowFullScreen";b:0;s:24:"HTML.ForbiddenAttributes";a:0:{}s:22:"HTML.ForbiddenElements";a:0:{}s:10:"HTML.Forms";b:0;s:17:"HTML.MaxImgLength";i:1200;s:13:"HTML.Nofollow";b:0;s:11:"HTML.Parent";s:3:"div";s:16:"HTML.Proprietary";b:0;s:14:"HTML.SafeEmbed";b:0;s:15:"HTML.SafeIframe";b:0;s:15:"HTML.SafeObject";b:0;s:18:"HTML.SafeScripting";a:0:{}s:11:"HTML.Strict";b:0;s:16:"HTML.TargetBlank";b:0;s:19:"HTML.TargetNoopener";b:1;s:21:"HTML.TargetNoreferrer";b:1;s:12:"HTML.TidyAdd";a:0:{}s:14:"HTML.TidyLevel";s:6:"medium";s:15:"HTML.TidyRemove";a:0:{}s:12:"HTML.Trusted";b:0;s:10:"HTML.XHTML";b:1;s:28:"Output.CommentScriptContents";b:1;s:19:"Output.FixInnerHTML";b:1;s:18:"Output.FlashCompat";b:0;s:14:"Output.Newline";N;s:15:"Output.SortAttr";b:0;s:17:"Output.TidyFormat";b:0;s:17:"Test.ForceNoIconv";b:0;s:18:"URI.AllowedSchemes";a:7:{s:4:"http";b:1;s:5:"https";b:1;s:6:"mailto";b:1;s:3:"ftp";b:1;s:4:"nntp";b:1;s:4:"news";b:1;s:3:"tel";b:1;}s:8:"URI.Base";N;s:17:"URI.DefaultScheme";s:4:"http";s:16:"URI.DefinitionID";N;s:17:"URI.DefinitionRev";i:1;s:11:"URI.Disable";b:0;s:19:"URI.DisableExternal";b:0;s:28:"URI.DisableExternalResources";b:0;s:20:"URI.DisableResources";b:0;s:8:"URI.Host";N;s:17:"URI.HostBlacklist";a:0:{}s:16:"URI.MakeAbsolute";b:0;s:9:"URI.Munge";N;s:18:"URI.MungeResources";b:0;s:18:"URI.MungeSecretKey";N;s:26:"URI.OverrideAllowedSchemes";b:1;s:20:"URI.SafeIframeRegexp";N;}s:9:"*parent";N;s:8:"*cache";N;}s:4:"info";a:141:{s:19:"Attr.AllowedClasses";i:-8;s:24:"Attr.AllowedFrameTargets";i:8;s:15:"Attr.AllowedRel";i:8;s:15:"Attr.AllowedRev";i:8;s:18:"Attr.ClassUseCDATA";i:-7;s:20:"Attr.DefaultImageAlt";i:-1;s:24:"Attr.DefaultInvalidImage";i:1;s:27:"Attr.DefaultInvalidImageAlt";i:1;s:19:"Attr.DefaultTextDir";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:2:{s:3:"ltr";b:1;s:3:"rtl";b:1;}}s:13:"Attr.EnableID";i:7;s:17:"HTML.EnableAttrID";O:8:"stdClass":2:{s:3:"key";s:13:"Attr.EnableID";s:7:"isAlias";b:1;}s:21:"Attr.ForbiddenClasses";i:8;s:13:"Attr.ID.HTML5";i:-7;s:16:"Attr.IDBlacklist";i:9;s:22:"Attr.IDBlacklistRegexp";i:-1;s:13:"Attr.IDPrefix";i:1;s:18:"Attr.IDPrefixLocal";i:1;s:24:"AutoFormat.AutoParagraph";i:7;s:17:"AutoFormat.Custom";i:9;s:25:"AutoFormat.DisplayLinkURI";i:7;s:18:"AutoFormat.Linkify";i:7;s:33:"AutoFormat.PurifierLinkify.DocURL";i:1;s:37:"AutoFormatParam.PurifierLinkifyDocURL";O:8:"stdClass":2:{s:3:"key";s:33:"AutoFormat.PurifierLinkify.DocURL";s:7:"isAlias";b:1;}s:26:"AutoFormat.PurifierLinkify";i:7;s:32:"AutoFormat.RemoveEmpty.Predicate";i:10;s:44:"AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions";i:8;s:33:"AutoFormat.RemoveEmpty.RemoveNbsp";i:7;s:22:"AutoFormat.RemoveEmpty";i:7;s:39:"AutoFormat.RemoveSpansWithoutAttributes";i:7;s:19:"CSS.AllowDuplicates";i:7;s:18:"CSS.AllowImportant";i:7;s:15:"CSS.AllowTricky";i:7;s:16:"CSS.AllowedFonts";i:-8;s:21:"CSS.AllowedProperties";i:-8;s:17:"CSS.DefinitionRev";i:5;s:23:"CSS.ForbiddenProperties";i:8;s:16:"CSS.MaxImgLength";i:-1;s:15:"CSS.Proprietary";i:7;s:11:"CSS.Trusted";i:7;s:20:"Cache.DefinitionImpl";i:-1;s:20:"Core.DefinitionCache";O:8:"stdClass":2:{s:3:"key";s:20:"Cache.DefinitionImpl";s:7:"isAlias";b:1;}s:20:"Cache.SerializerPath";i:-1;s:27:"Cache.SerializerPermissions";i:-5;s:22:"Core.AggressivelyFixLt";i:7;s:29:"Core.AggressivelyRemoveScript";i:7;s:28:"Core.AllowHostnameUnderscore";i:7;s:23:"Core.AllowParseManyTags";i:7;s:18:"Core.CollectErrors";i:7;s:18:"Core.ColorKeywords";i:10;s:30:"Core.ConvertDocumentToFragment";i:7;s:24:"Core.AcceptFullDocuments";O:8:"stdClass":2:{s:3:"key";s:30:"Core.ConvertDocumentToFragment";s:7:"isAlias";b:1;}s:36:"Core.DirectLexLineNumberSyncInterval";i:5;s:20:"Core.DisableExcludes";i:7;s:15:"Core.EnableIDNA";i:7;s:13:"Core.Encoding";i:2;s:26:"Core.EscapeInvalidChildren";i:7;s:22:"Core.EscapeInvalidTags";i:7;s:29:"Core.EscapeNonASCIICharacters";i:7;s:19:"Core.HiddenElements";i:8;s:13:"Core.Language";i:1;s:24:"Core.LegacyEntityDecoder";i:7;s:14:"Core.LexerImpl";i:-11;s:24:"Core.MaintainLineNumbers";i:-7;s:22:"Core.NormalizeNewlines";i:7;s:17:"Core.RemoveBlanks";i:7;s:21:"Core.RemoveInvalidImg";i:7;s:33:"Core.RemoveProcessingInstructions";i:7;s:25:"Core.RemoveScriptContents";i:-7;s:13:"Filter.Custom";i:9;s:34:"Filter.ExtractStyleBlocks.Escaping";i:7;s:33:"Filter.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:38:"FilterParam.ExtractStyleBlocksEscaping";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.Escaping";s:7:"isAlias";b:1;}s:31:"Filter.ExtractStyleBlocks.Scope";i:-1;s:30:"Filter.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:35:"FilterParam.ExtractStyleBlocksScope";O:8:"stdClass":2:{s:3:"key";s:31:"Filter.ExtractStyleBlocks.Scope";s:7:"isAlias";b:1;}s:34:"Filter.ExtractStyleBlocks.TidyImpl";i:-11;s:38:"FilterParam.ExtractStyleBlocksTidyImpl";O:8:"stdClass":2:{s:3:"key";s:34:"Filter.ExtractStyleBlocks.TidyImpl";s:7:"isAlias";b:1;}s:25:"Filter.ExtractStyleBlocks";i:7;s:14:"Filter.YouTube";i:7;s:12:"HTML.Allowed";i:-4;s:22:"HTML.AllowedAttributes";i:-8;s:20:"HTML.AllowedComments";i:8;s:26:"HTML.AllowedCommentsRegexp";i:-1;s:20:"HTML.AllowedElements";i:-8;s:19:"HTML.AllowedModules";i:-8;s:23:"HTML.Attr.Name.UseCDATA";i:7;s:17:"HTML.BlockWrapper";i:1;s:16:"HTML.CoreModules";i:8;s:18:"HTML.CustomDoctype";i:-1;s:17:"HTML.DefinitionID";i:-1;s:18:"HTML.DefinitionRev";i:5;s:12:"HTML.Doctype";O:8:"stdClass":3:{s:4:"type";i:1;s:10:"allow_null";b:1;s:7:"allowed";a:5:{s:22:"HTML 4.01 Transitional";b:1;s:16:"HTML 4.01 Strict";b:1;s:22:"XHTML 1.0 Transitional";b:1;s:16:"XHTML 1.0 Strict";b:1;s:9:"XHTML 1.1";b:1;}}s:25:"HTML.FlashAllowFullScreen";i:7;s:24:"HTML.ForbiddenAttributes";i:8;s:22:"HTML.ForbiddenElements";i:8;s:10:"HTML.Forms";i:7;s:17:"HTML.MaxImgLength";i:-5;s:13:"HTML.Nofollow";i:7;s:11:"HTML.Parent";i:1;s:16:"HTML.Proprietary";i:7;s:14:"HTML.SafeEmbed";i:7;s:15:"HTML.SafeIframe";i:7;s:15:"HTML.SafeObject";i:7;s:18:"HTML.SafeScripting";i:8;s:11:"HTML.Strict";i:7;s:16:"HTML.TargetBlank";i:7;s:19:"HTML.TargetNoopener";i:7;s:21:"HTML.TargetNoreferrer";i:7;s:12:"HTML.TidyAdd";i:8;s:14:"HTML.TidyLevel";O:8:"stdClass":2:{s:4:"type";i:1;s:7:"allowed";a:4:{s:4:"none";b:1;s:5:"light";b:1;s:6:"medium";b:1;s:5:"heavy";b:1;}}s:15:"HTML.TidyRemove";i:8;s:12:"HTML.Trusted";i:7;s:10:"HTML.XHTML";i:7;s:10:"Core.XHTML";O:8:"stdClass":2:{s:3:"key";s:10:"HTML.XHTML";s:7:"isAlias";b:1;}s:28:"Output.CommentScriptContents";i:7;s:26:"Core.CommentScriptContents";O:8:"stdClass":2:{s:3:"key";s:28:"Output.CommentScriptContents";s:7:"isAlias";b:1;}s:19:"Output.FixInnerHTML";i:7;s:18:"Output.FlashCompat";i:7;s:14:"Output.Newline";i:-1;s:15:"Output.SortAttr";i:7;s:17:"Output.TidyFormat";i:7;s:15:"Core.TidyFormat";O:8:"stdClass":2:{s:3:"key";s:17:"Output.TidyFormat";s:7:"isAlias";b:1;}s:17:"Test.ForceNoIconv";i:7;s:18:"URI.AllowedSchemes";i:8;s:8:"URI.Base";i:-1;s:17:"URI.DefaultScheme";i:-1;s:16:"URI.DefinitionID";i:-1;s:17:"URI.DefinitionRev";i:5;s:11:"URI.Disable";i:7;s:15:"Attr.DisableURI";O:8:"stdClass":2:{s:3:"key";s:11:"URI.Disable";s:7:"isAlias";b:1;}s:19:"URI.DisableExternal";i:7;s:28:"URI.DisableExternalResources";i:7;s:20:"URI.DisableResources";i:7;s:8:"URI.Host";i:-1;s:17:"URI.HostBlacklist";i:9;s:16:"URI.MakeAbsolute";i:7;s:9:"URI.Munge";i:-1;s:18:"URI.MungeResources";i:7;s:18:"URI.MungeSecretKey";i:-1;s:26:"URI.OverrideAllowedSchemes";i:7;s:20:"URI.SafeIframeRegexp";i:-1;}} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt new file mode 100644 index 0000000..0517fed --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt @@ -0,0 +1,8 @@ +Attr.AllowedClasses +TYPE: lookup/null +VERSION: 4.0.0 +DEFAULT: null +--DESCRIPTION-- +List of allowed class values in the class attribute. By default, this is null, +which means all classes are allowed. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt new file mode 100644 index 0000000..249edd6 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt @@ -0,0 +1,12 @@ +Attr.AllowedFrameTargets +TYPE: lookup +DEFAULT: array() +--DESCRIPTION-- +Lookup table of all allowed link frame targets. Some commonly used link +targets include _blank, _self, _parent and _top. Values should be +lowercase, as validation will be done in a case-sensitive manner despite +W3C's recommendation. XHTML 1.0 Strict does not permit the target attribute +so this directive will have no effect in that doctype. XHTML 1.1 does not +enable the Target module by default, you will have to manually enable it +(see the module documentation for more details.) +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt new file mode 100644 index 0000000..9a8fa6a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt @@ -0,0 +1,9 @@ +Attr.AllowedRel +TYPE: lookup +VERSION: 1.6.0 +DEFAULT: array() +--DESCRIPTION-- +List of allowed forward document relationships in the rel attribute. Common +values may be nofollow or print. By default, this is empty, meaning that no +document relationships are allowed. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt new file mode 100644 index 0000000..b017883 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt @@ -0,0 +1,9 @@ +Attr.AllowedRev +TYPE: lookup +VERSION: 1.6.0 +DEFAULT: array() +--DESCRIPTION-- +List of allowed reverse document relationships in the rev attribute. This +attribute is a bit of an edge-case; if you don't know what it is for, stay +away. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt new file mode 100644 index 0000000..e774b82 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt @@ -0,0 +1,19 @@ +Attr.ClassUseCDATA +TYPE: bool/null +DEFAULT: null +VERSION: 4.0.0 +--DESCRIPTION-- +If null, class will auto-detect the doctype and, if matching XHTML 1.1 or +XHTML 2.0, will use the restrictive NMTOKENS specification of class. Otherwise, +it will use a relaxed CDATA definition. If true, the relaxed CDATA definition +is forced; if false, the NMTOKENS definition is forced. To get behavior +of HTML Purifier prior to 4.0.0, set this directive to false. + +Some rational behind the auto-detection: +in previous versions of HTML Purifier, it was assumed that the form of +class was NMTOKENS, as specified by the XHTML Modularization (representing +XHTML 1.1 and XHTML 2.0). The DTDs for HTML 4.01 and XHTML 1.0, however +specify class as CDATA. HTML 5 effectively defines it as CDATA, but +with the additional constraint that each name should be unique (this is not +explicitly outlined in previous specifications). +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt new file mode 100644 index 0000000..533165e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt @@ -0,0 +1,11 @@ +Attr.DefaultImageAlt +TYPE: string/null +DEFAULT: null +VERSION: 3.2.0 +--DESCRIPTION-- +This is the content of the alt tag of an image if the user had not +previously specified an alt attribute. This applies to all images without +a valid alt attribute, as opposed to %Attr.DefaultInvalidImageAlt, which +only applies to invalid images, and overrides in the case of an invalid image. +Default behavior with null is to use the basename of the src tag for the alt. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt new file mode 100644 index 0000000..9eb7e38 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt @@ -0,0 +1,9 @@ +Attr.DefaultInvalidImage +TYPE: string +DEFAULT: '' +--DESCRIPTION-- +This is the default image an img tag will be pointed to if it does not have +a valid src attribute. In future versions, we may allow the image tag to +be removed completely, but due to design issues, this is not possible right +now. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt new file mode 100644 index 0000000..2f17bf4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt @@ -0,0 +1,8 @@ +Attr.DefaultInvalidImageAlt +TYPE: string +DEFAULT: 'Invalid image' +--DESCRIPTION-- +This is the content of the alt tag of an invalid image if the user had not +previously specified an alt attribute. It has no effect when the image is +valid but there was no alt attribute present. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt new file mode 100644 index 0000000..52654b5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt @@ -0,0 +1,10 @@ +Attr.DefaultTextDir +TYPE: string +DEFAULT: 'ltr' +--DESCRIPTION-- +Defines the default text direction (ltr or rtl) of the document being +parsed. This generally is the same as the value of the dir attribute in +HTML, or ltr if that is not specified. +--ALLOWED-- +'ltr', 'rtl' +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt new file mode 100644 index 0000000..6440d21 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt @@ -0,0 +1,16 @@ +Attr.EnableID +TYPE: bool +DEFAULT: false +VERSION: 1.2.0 +--DESCRIPTION-- +Allows the ID attribute in HTML. This is disabled by default due to the +fact that without proper configuration user input can easily break the +validation of a webpage by specifying an ID that is already on the +surrounding HTML. If you don't mind throwing caution to the wind, enable +this directive, but I strongly recommend you also consider blacklisting IDs +you use (%Attr.IDBlacklist) or prefixing all user supplied IDs +(%Attr.IDPrefix). When set to true HTML Purifier reverts to the behavior of +pre-1.2.0 versions. +--ALIASES-- +HTML.EnableAttrID +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt new file mode 100644 index 0000000..f31d226 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt @@ -0,0 +1,8 @@ +Attr.ForbiddenClasses +TYPE: lookup +VERSION: 4.0.0 +DEFAULT: array() +--DESCRIPTION-- +List of forbidden class values in the class attribute. By default, this is +empty, which means that no classes are forbidden. See also %Attr.AllowedClasses. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ID.HTML5.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ID.HTML5.txt new file mode 100644 index 0000000..735d4b7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.ID.HTML5.txt @@ -0,0 +1,10 @@ +Attr.ID.HTML5 +TYPE: bool/null +DEFAULT: null +VERSION: 4.8.0 +--DESCRIPTION-- +In HTML5, restrictions on the format of the id attribute have been significantly +relaxed, such that any string is valid so long as it contains no spaces and +is at least one character. In lieu of a general HTML5 compatibility flag, +set this configuration directive to true to use the relaxed rules. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt new file mode 100644 index 0000000..5f2b5e3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt @@ -0,0 +1,5 @@ +Attr.IDBlacklist +TYPE: list +DEFAULT: array() +DESCRIPTION: Array of IDs not allowed in the document. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt new file mode 100644 index 0000000..6f58245 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt @@ -0,0 +1,9 @@ +Attr.IDBlacklistRegexp +TYPE: string/null +VERSION: 1.6.0 +DEFAULT: NULL +--DESCRIPTION-- +PCRE regular expression to be matched against all IDs. If the expression is +matches, the ID is rejected. Use this with care: may cause significant +degradation. ID matching is done after all other validation. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt new file mode 100644 index 0000000..cc49d43 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt @@ -0,0 +1,12 @@ +Attr.IDPrefix +TYPE: string +VERSION: 1.2.0 +DEFAULT: '' +--DESCRIPTION-- +String to prefix to IDs. If you have no idea what IDs your pages may use, +you may opt to simply add a prefix to all user-submitted ID attributes so +that they are still usable, but will not conflict with core page IDs. +Example: setting the directive to 'user_' will result in a user submitted +'foo' to become 'user_foo' Be sure to set %HTML.EnableAttrID to true +before using this. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt new file mode 100644 index 0000000..2c5924a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt @@ -0,0 +1,14 @@ +Attr.IDPrefixLocal +TYPE: string +VERSION: 1.2.0 +DEFAULT: '' +--DESCRIPTION-- +Temporary prefix for IDs used in conjunction with %Attr.IDPrefix. If you +need to allow multiple sets of user content on web page, you may need to +have a seperate prefix that changes with each iteration. This way, +seperately submitted user content displayed on the same page doesn't +clobber each other. Ideal values are unique identifiers for the content it +represents (i.e. the id of the row in the database). Be sure to add a +seperator (like an underscore) at the end. Warning: this directive will +not work unless %Attr.IDPrefix is set to a non-empty value! +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt new file mode 100644 index 0000000..d5caa1b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt @@ -0,0 +1,31 @@ +AutoFormat.AutoParagraph +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + This directive turns on auto-paragraphing, where double newlines are + converted in to paragraphs whenever possible. Auto-paragraphing: +

        +
          +
        • Always applies to inline elements or text in the root node,
        • +
        • Applies to inline elements or text with double newlines in nodes + that allow paragraph tags,
        • +
        • Applies to double newlines in paragraph tags
        • +
        +

        + p tags must be allowed for this directive to take effect. + We do not use br tags for paragraphing, as that is + semantically incorrect. +

        +

        + To prevent auto-paragraphing as a content-producer, refrain from using + double-newlines except to specify a new paragraph or in contexts where + it has special meaning (whitespace usually has no meaning except in + tags like pre, so this should not be difficult.) To prevent + the paragraphing of inline text adjacent to block elements, wrap them + in div tags (the behavior is slightly different outside of + the root node.) +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt new file mode 100644 index 0000000..2a47648 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt @@ -0,0 +1,12 @@ +AutoFormat.Custom +TYPE: list +VERSION: 2.0.1 +DEFAULT: array() +--DESCRIPTION-- + +

        + This directive can be used to add custom auto-format injectors. + Specify an array of injector names (class name minus the prefix) + or concrete implementations. Injector class must exist. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt new file mode 100644 index 0000000..663064a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt @@ -0,0 +1,11 @@ +AutoFormat.DisplayLinkURI +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + This directive turns on the in-text display of URIs in <a> tags, and disables + those links. For example, example becomes + example (http://example.com). +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt new file mode 100644 index 0000000..3a48ba9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt @@ -0,0 +1,12 @@ +AutoFormat.Linkify +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + This directive turns on linkification, auto-linking http, ftp and + https URLs. a tags with the href attribute + must be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt new file mode 100644 index 0000000..db58b13 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt @@ -0,0 +1,12 @@ +AutoFormat.PurifierLinkify.DocURL +TYPE: string +VERSION: 2.0.1 +DEFAULT: '#%s' +ALIASES: AutoFormatParam.PurifierLinkifyDocURL +--DESCRIPTION-- +

        + Location of configuration documentation to link to, let %s substitute + into the configuration's namespace and directive names sans the percent + sign. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt new file mode 100644 index 0000000..7996488 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt @@ -0,0 +1,12 @@ +AutoFormat.PurifierLinkify +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + Internal auto-formatter that converts configuration directives in + syntax %Namespace.Directive to links. a tags + with the href attribute must be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.Predicate.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.Predicate.txt new file mode 100644 index 0000000..6367fe2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.Predicate.txt @@ -0,0 +1,14 @@ +AutoFormat.RemoveEmpty.Predicate +TYPE: hash +VERSION: 4.7.0 +DEFAULT: array('colgroup' => array(), 'th' => array(), 'td' => array(), 'iframe' => array('src')) +--DESCRIPTION-- +

        + Given that an element has no contents, it will be removed by default, unless + this predicate dictates otherwise. The predicate can either be an associative + map from tag name to list of attributes that must be present for the element + to be considered preserved: thus, the default always preserves colgroup, + th and td, and also iframe if it + has a src. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt new file mode 100644 index 0000000..35c393b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt @@ -0,0 +1,11 @@ +AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions +TYPE: lookup +VERSION: 4.0.0 +DEFAULT: array('td' => true, 'th' => true) +--DESCRIPTION-- +

        + When %AutoFormat.RemoveEmpty and %AutoFormat.RemoveEmpty.RemoveNbsp + are enabled, this directive defines what HTML elements should not be + removede if they have only a non-breaking space in them. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt new file mode 100644 index 0000000..9228dee --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt @@ -0,0 +1,15 @@ +AutoFormat.RemoveEmpty.RemoveNbsp +TYPE: bool +VERSION: 4.0.0 +DEFAULT: false +--DESCRIPTION-- +

        + When enabled, HTML Purifier will treat any elements that contain only + non-breaking spaces as well as regular whitespace as empty, and remove + them when %AutoFormat.RemoveEmpty is enabled. +

        +

        + See %AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions for a list of elements + that don't have this behavior applied to them. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt new file mode 100644 index 0000000..34657ba --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt @@ -0,0 +1,46 @@ +AutoFormat.RemoveEmpty +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + When enabled, HTML Purifier will attempt to remove empty elements that + contribute no semantic information to the document. The following types + of nodes will be removed: +

        +
        • + Tags with no attributes and no content, and that are not empty + elements (remove <a></a> but not + <br />), and +
        • +
        • + Tags with no content, except for:
            +
          • The colgroup element, or
          • +
          • + Elements with the id or name attribute, + when those attributes are permitted on those elements. +
          • +
        • +
        +

        + Please be very careful when using this functionality; while it may not + seem that empty elements contain useful information, they can alter the + layout of a document given appropriate styling. This directive is most + useful when you are processing machine-generated HTML, please avoid using + it on regular user HTML. +

        +

        + Elements that contain only whitespace will be treated as empty. Non-breaking + spaces, however, do not count as whitespace. See + %AutoFormat.RemoveEmpty.RemoveNbsp for alternate behavior. +

        +

        + This algorithm is not perfect; you may still notice some empty tags, + particularly if a node had elements, but those elements were later removed + because they were not permitted in that context, or tags that, after + being auto-closed by another tag, where empty. This is for safety reasons + to prevent clever code from breaking validation. The general rule of thumb: + if a tag looked empty on the way in, it will get removed; if HTML Purifier + made it empty, it will stay. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt new file mode 100644 index 0000000..dde990a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt @@ -0,0 +1,11 @@ +AutoFormat.RemoveSpansWithoutAttributes +TYPE: bool +VERSION: 4.0.1 +DEFAULT: false +--DESCRIPTION-- +

        + This directive causes span tags without any attributes + to be removed. It will also remove spans that had all attributes + removed during processing. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowDuplicates.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowDuplicates.txt new file mode 100644 index 0000000..4d054b1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowDuplicates.txt @@ -0,0 +1,11 @@ +CSS.AllowDuplicates +TYPE: bool +DEFAULT: false +VERSION: 4.8.0 +--DESCRIPTION-- +

        + By default, HTML Purifier removes duplicate CSS properties, + like color:red; color:blue. If this is set to + true, duplicate properties are allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt new file mode 100644 index 0000000..b324608 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt @@ -0,0 +1,8 @@ +CSS.AllowImportant +TYPE: bool +DEFAULT: false +VERSION: 3.1.0 +--DESCRIPTION-- +This parameter determines whether or not !important cascade modifiers should +be allowed in user CSS. If false, !important will stripped. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt new file mode 100644 index 0000000..748be0e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt @@ -0,0 +1,11 @@ +CSS.AllowTricky +TYPE: bool +DEFAULT: false +VERSION: 3.1.0 +--DESCRIPTION-- +This parameter determines whether or not to allow "tricky" CSS properties and +values. Tricky CSS properties/values can drastically modify page layout or +be used for deceptive practices but do not directly constitute a security risk. +For example, display:none; is considered a tricky property that +will only be allowed if this directive is set to true. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt new file mode 100644 index 0000000..3fd4654 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt @@ -0,0 +1,12 @@ +CSS.AllowedFonts +TYPE: lookup/null +VERSION: 4.3.0 +DEFAULT: NULL +--DESCRIPTION-- +

        + Allows you to manually specify a set of allowed fonts. If + NULL, all fonts are allowed. This directive + affects generic names (serif, sans-serif, monospace, cursive, + fantasy) as well as specific font families. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt new file mode 100644 index 0000000..460112e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt @@ -0,0 +1,18 @@ +CSS.AllowedProperties +TYPE: lookup/null +VERSION: 3.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If HTML Purifier's style attributes set is unsatisfactory for your needs, + you can overload it with your own list of tags to allow. Note that this + method is subtractive: it does its job by taking away from HTML Purifier + usual feature set, so you cannot add an attribute that HTML Purifier never + supported in the first place. +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt new file mode 100644 index 0000000..5cb7dda --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt @@ -0,0 +1,11 @@ +CSS.DefinitionRev +TYPE: int +VERSION: 2.0.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition. See + %HTML.DefinitionRev for details. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt new file mode 100644 index 0000000..f1f5c5f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt @@ -0,0 +1,13 @@ +CSS.ForbiddenProperties +TYPE: lookup +VERSION: 4.2.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This is the logical inverse of %CSS.AllowedProperties, and it will + override that directive or any other directive. If possible, + %CSS.AllowedProperties is recommended over this directive, + because it can sometimes be difficult to tell whether or not you've + forbidden all of the CSS properties you truly would like to disallow. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt new file mode 100644 index 0000000..7a32914 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt @@ -0,0 +1,16 @@ +CSS.MaxImgLength +TYPE: string/null +DEFAULT: '1200px' +VERSION: 3.1.1 +--DESCRIPTION-- +

        + This parameter sets the maximum allowed length on img tags, + effectively the width and height properties. + Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %HTML.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the CSS max is a number with + a unit). +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt new file mode 100644 index 0000000..148eedb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt @@ -0,0 +1,10 @@ +CSS.Proprietary +TYPE: bool +VERSION: 3.0.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Whether or not to allow safe, proprietary CSS values. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt new file mode 100644 index 0000000..e733a61 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt @@ -0,0 +1,9 @@ +CSS.Trusted +TYPE: bool +VERSION: 4.2.1 +DEFAULT: false +--DESCRIPTION-- +Indicates whether or not the user's CSS input is trusted or not. If the +input is trusted, a more expansive set of allowed properties. See +also %HTML.Trusted. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt new file mode 100644 index 0000000..c486724 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt @@ -0,0 +1,14 @@ +Cache.DefinitionImpl +TYPE: string/null +VERSION: 2.0.0 +DEFAULT: 'Serializer' +--DESCRIPTION-- + +This directive defines which method to use when caching definitions, +the complex data-type that makes HTML Purifier tick. Set to null +to disable caching (not recommended, as you will see a definite +performance degradation). + +--ALIASES-- +Core.DefinitionCache +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt new file mode 100644 index 0000000..5403650 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt @@ -0,0 +1,13 @@ +Cache.SerializerPath +TYPE: string/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Absolute path with no trailing slash to store serialized definitions in. + Default is within the + HTML Purifier library inside DefinitionCache/Serializer. This + path must be writable by the webserver. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt new file mode 100644 index 0000000..2e0cc81 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt @@ -0,0 +1,16 @@ +Cache.SerializerPermissions +TYPE: int/null +VERSION: 4.3.0 +DEFAULT: 0755 +--DESCRIPTION-- + +

        + Directory permissions of the files and directories created inside + the DefinitionCache/Serializer or other custom serializer path. +

        +

        + In HTML Purifier 4.8.0, this also supports NULL, + which means that no chmod'ing or directory creation shall + occur. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt new file mode 100644 index 0000000..568cbf3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt @@ -0,0 +1,18 @@ +Core.AggressivelyFixLt +TYPE: bool +VERSION: 2.1.0 +DEFAULT: true +--DESCRIPTION-- +

        + This directive enables aggressive pre-filter fixes HTML Purifier can + perform in order to ensure that open angled-brackets do not get killed + during parsing stage. Enabling this will result in two preg_replace_callback + calls and at least two preg_replace calls for every HTML document parsed; + if your users make very well-formed HTML, you can set this directive false. + This has no effect when DirectLex is used. +

        +

        + Notice: This directive's default turned from false to true + in HTML Purifier 3.2.0. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyRemoveScript.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyRemoveScript.txt new file mode 100644 index 0000000..b2b6ab1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyRemoveScript.txt @@ -0,0 +1,16 @@ +Core.AggressivelyRemoveScript +TYPE: bool +VERSION: 4.9.0 +DEFAULT: true +--DESCRIPTION-- +

        + This directive enables aggressive pre-filter removal of + script tags. This is not necessary for security, + but it can help work around a bug in libxml where embedded + HTML elements inside script sections cause the parser to + choke. To revert to pre-4.9.0 behavior, set this to false. + This directive has no effect if %Core.Trusted is true, + %Core.RemoveScriptContents is false, or %Core.HiddenElements + does not contain script. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AllowHostnameUnderscore.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AllowHostnameUnderscore.txt new file mode 100644 index 0000000..2c910cc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AllowHostnameUnderscore.txt @@ -0,0 +1,16 @@ +Core.AllowHostnameUnderscore +TYPE: bool +VERSION: 4.6.0 +DEFAULT: false +--DESCRIPTION-- +

        + By RFC 1123, underscores are not permitted in host names. + (This is in contrast to the specification for DNS, RFC + 2181, which allows underscores.) + However, most browsers do the right thing when faced with + an underscore in the host name, and so some poorly written + websites are written with the expectation this should work. + Setting this parameter to true relaxes our allowed character + check so that underscores are permitted. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AllowParseManyTags.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AllowParseManyTags.txt new file mode 100644 index 0000000..06278f8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.AllowParseManyTags.txt @@ -0,0 +1,12 @@ +Core.AllowParseManyTags +TYPE: bool +DEFAULT: false +VERSION: 4.10.1 +--DESCRIPTION-- +

        + This directive allows parsing of many nested tags. + If you set true, relaxes any hardcoded limit from the parser. + However, in that case it may cause a Dos attack. + Be careful when enabling it. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt new file mode 100644 index 0000000..d731791 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt @@ -0,0 +1,12 @@ +Core.CollectErrors +TYPE: bool +VERSION: 2.0.0 +DEFAULT: false +--DESCRIPTION-- + +Whether or not to collect errors found while filtering the document. This +is a useful way to give feedback to your users. Warning: +Currently this feature is very patchy and experimental, with lots of +possible error messages not yet implemented. It will not cause any +problems, but it may not help your users either. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt new file mode 100644 index 0000000..a75844c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt @@ -0,0 +1,160 @@ +Core.ColorKeywords +TYPE: hash +VERSION: 2.0.0 +--DEFAULT-- +array ( + 'aliceblue' => '#F0F8FF', + 'antiquewhite' => '#FAEBD7', + 'aqua' => '#00FFFF', + 'aquamarine' => '#7FFFD4', + 'azure' => '#F0FFFF', + 'beige' => '#F5F5DC', + 'bisque' => '#FFE4C4', + 'black' => '#000000', + 'blanchedalmond' => '#FFEBCD', + 'blue' => '#0000FF', + 'blueviolet' => '#8A2BE2', + 'brown' => '#A52A2A', + 'burlywood' => '#DEB887', + 'cadetblue' => '#5F9EA0', + 'chartreuse' => '#7FFF00', + 'chocolate' => '#D2691E', + 'coral' => '#FF7F50', + 'cornflowerblue' => '#6495ED', + 'cornsilk' => '#FFF8DC', + 'crimson' => '#DC143C', + 'cyan' => '#00FFFF', + 'darkblue' => '#00008B', + 'darkcyan' => '#008B8B', + 'darkgoldenrod' => '#B8860B', + 'darkgray' => '#A9A9A9', + 'darkgrey' => '#A9A9A9', + 'darkgreen' => '#006400', + 'darkkhaki' => '#BDB76B', + 'darkmagenta' => '#8B008B', + 'darkolivegreen' => '#556B2F', + 'darkorange' => '#FF8C00', + 'darkorchid' => '#9932CC', + 'darkred' => '#8B0000', + 'darksalmon' => '#E9967A', + 'darkseagreen' => '#8FBC8F', + 'darkslateblue' => '#483D8B', + 'darkslategray' => '#2F4F4F', + 'darkslategrey' => '#2F4F4F', + 'darkturquoise' => '#00CED1', + 'darkviolet' => '#9400D3', + 'deeppink' => '#FF1493', + 'deepskyblue' => '#00BFFF', + 'dimgray' => '#696969', + 'dimgrey' => '#696969', + 'dodgerblue' => '#1E90FF', + 'firebrick' => '#B22222', + 'floralwhite' => '#FFFAF0', + 'forestgreen' => '#228B22', + 'fuchsia' => '#FF00FF', + 'gainsboro' => '#DCDCDC', + 'ghostwhite' => '#F8F8FF', + 'gold' => '#FFD700', + 'goldenrod' => '#DAA520', + 'gray' => '#808080', + 'grey' => '#808080', + 'green' => '#008000', + 'greenyellow' => '#ADFF2F', + 'honeydew' => '#F0FFF0', + 'hotpink' => '#FF69B4', + 'indianred' => '#CD5C5C', + 'indigo' => '#4B0082', + 'ivory' => '#FFFFF0', + 'khaki' => '#F0E68C', + 'lavender' => '#E6E6FA', + 'lavenderblush' => '#FFF0F5', + 'lawngreen' => '#7CFC00', + 'lemonchiffon' => '#FFFACD', + 'lightblue' => '#ADD8E6', + 'lightcoral' => '#F08080', + 'lightcyan' => '#E0FFFF', + 'lightgoldenrodyellow' => '#FAFAD2', + 'lightgray' => '#D3D3D3', + 'lightgrey' => '#D3D3D3', + 'lightgreen' => '#90EE90', + 'lightpink' => '#FFB6C1', + 'lightsalmon' => '#FFA07A', + 'lightseagreen' => '#20B2AA', + 'lightskyblue' => '#87CEFA', + 'lightslategray' => '#778899', + 'lightslategrey' => '#778899', + 'lightsteelblue' => '#B0C4DE', + 'lightyellow' => '#FFFFE0', + 'lime' => '#00FF00', + 'limegreen' => '#32CD32', + 'linen' => '#FAF0E6', + 'magenta' => '#FF00FF', + 'maroon' => '#800000', + 'mediumaquamarine' => '#66CDAA', + 'mediumblue' => '#0000CD', + 'mediumorchid' => '#BA55D3', + 'mediumpurple' => '#9370DB', + 'mediumseagreen' => '#3CB371', + 'mediumslateblue' => '#7B68EE', + 'mediumspringgreen' => '#00FA9A', + 'mediumturquoise' => '#48D1CC', + 'mediumvioletred' => '#C71585', + 'midnightblue' => '#191970', + 'mintcream' => '#F5FFFA', + 'mistyrose' => '#FFE4E1', + 'moccasin' => '#FFE4B5', + 'navajowhite' => '#FFDEAD', + 'navy' => '#000080', + 'oldlace' => '#FDF5E6', + 'olive' => '#808000', + 'olivedrab' => '#6B8E23', + 'orange' => '#FFA500', + 'orangered' => '#FF4500', + 'orchid' => '#DA70D6', + 'palegoldenrod' => '#EEE8AA', + 'palegreen' => '#98FB98', + 'paleturquoise' => '#AFEEEE', + 'palevioletred' => '#DB7093', + 'papayawhip' => '#FFEFD5', + 'peachpuff' => '#FFDAB9', + 'peru' => '#CD853F', + 'pink' => '#FFC0CB', + 'plum' => '#DDA0DD', + 'powderblue' => '#B0E0E6', + 'purple' => '#800080', + 'rebeccapurple' => '#663399', + 'red' => '#FF0000', + 'rosybrown' => '#BC8F8F', + 'royalblue' => '#4169E1', + 'saddlebrown' => '#8B4513', + 'salmon' => '#FA8072', + 'sandybrown' => '#F4A460', + 'seagreen' => '#2E8B57', + 'seashell' => '#FFF5EE', + 'sienna' => '#A0522D', + 'silver' => '#C0C0C0', + 'skyblue' => '#87CEEB', + 'slateblue' => '#6A5ACD', + 'slategray' => '#708090', + 'slategrey' => '#708090', + 'snow' => '#FFFAFA', + 'springgreen' => '#00FF7F', + 'steelblue' => '#4682B4', + 'tan' => '#D2B48C', + 'teal' => '#008080', + 'thistle' => '#D8BFD8', + 'tomato' => '#FF6347', + 'turquoise' => '#40E0D0', + 'violet' => '#EE82EE', + 'wheat' => '#F5DEB3', + 'white' => '#FFFFFF', + 'whitesmoke' => '#F5F5F5', + 'yellow' => '#FFFF00', + 'yellowgreen' => '#9ACD32' +) +--DESCRIPTION-- + +Lookup array of color names to six digit hexadecimal number corresponding +to color, with preceding hash mark. Used when parsing colors. The lookup +is done in a case-insensitive manner. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt new file mode 100644 index 0000000..64b114f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt @@ -0,0 +1,14 @@ +Core.ConvertDocumentToFragment +TYPE: bool +DEFAULT: true +--DESCRIPTION-- + +This parameter determines whether or not the filter should convert +input that is a full document with html and body tags to a fragment +of just the contents of a body tag. This parameter is simply something +HTML Purifier can do during an edge-case: for most inputs, this +processing is not necessary. + +--ALIASES-- +Core.AcceptFullDocuments +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt new file mode 100644 index 0000000..36f16e0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt @@ -0,0 +1,17 @@ +Core.DirectLexLineNumberSyncInterval +TYPE: int +VERSION: 2.0.0 +DEFAULT: 0 +--DESCRIPTION-- + +

        + Specifies the number of tokens the DirectLex line number tracking + implementations should process before attempting to resyncronize the + current line count by manually counting all previous new-lines. When + at 0, this functionality is disabled. Lower values will decrease + performance, and this is only strictly necessary if the counting + algorithm is buggy (in which case you should report it as a bug). + This has no effect when %Core.MaintainLineNumbers is disabled or DirectLex is + not being used. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt new file mode 100644 index 0000000..1cd4c2c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt @@ -0,0 +1,14 @@ +Core.DisableExcludes +TYPE: bool +DEFAULT: false +VERSION: 4.5.0 +--DESCRIPTION-- +

        + This directive disables SGML-style exclusions, e.g. the exclusion of + <object> in any descendant of a + <pre> tag. Disabling excludes will allow some + invalid documents to pass through HTML Purifier, but HTML Purifier + will also be less likely to accidentally remove large documents during + processing. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt new file mode 100644 index 0000000..ce243c3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt @@ -0,0 +1,9 @@ +Core.EnableIDNA +TYPE: bool +DEFAULT: false +VERSION: 4.4.0 +--DESCRIPTION-- +Allows international domain names in URLs. This configuration option +requires the PEAR Net_IDNA2 module to be installed. It operates by +punycoding any internationalized host names for maximum portability. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt new file mode 100644 index 0000000..8bfb47c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt @@ -0,0 +1,15 @@ +Core.Encoding +TYPE: istring +DEFAULT: 'utf-8' +--DESCRIPTION-- +If for some reason you are unable to convert all webpages to UTF-8, you can +use this directive as a stop-gap compatibility change to let HTML Purifier +deal with non UTF-8 input. This technique has notable deficiencies: +absolutely no characters outside of the selected character encoding will be +preserved, not even the ones that have been ampersand escaped (this is due +to a UTF-8 specific feature that automatically resolves all +entities), making it pretty useless for anything except the most I18N-blind +applications, although %Core.EscapeNonASCIICharacters offers fixes this +trouble with another tradeoff. This directive only accepts ISO-8859-1 if +iconv is not enabled. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt new file mode 100644 index 0000000..a3881be --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt @@ -0,0 +1,12 @@ +Core.EscapeInvalidChildren +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +

        Warning: this configuration option is no longer does anything as of 4.6.0.

        + +

        When true, a child is found that is not allowed in the context of the +parent element will be transformed into text as if it were ASCII. When +false, that element and all internal tags will be dropped, though text will +be preserved. There is no option for dropping the element but preserving +child nodes.

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt new file mode 100644 index 0000000..a7a5b24 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt @@ -0,0 +1,7 @@ +Core.EscapeInvalidTags +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +When true, invalid tags will be written back to the document as plain text. +Otherwise, they are silently dropped. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt new file mode 100644 index 0000000..abb4999 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt @@ -0,0 +1,13 @@ +Core.EscapeNonASCIICharacters +TYPE: bool +VERSION: 1.4.0 +DEFAULT: false +--DESCRIPTION-- +This directive overcomes a deficiency in %Core.Encoding by blindly +converting all non-ASCII characters into decimal numeric entities before +converting it to its native encoding. This means that even characters that +can be expressed in the non-UTF-8 encoding will be entity-ized, which can +be a real downer for encodings like Big5. It also assumes that the ASCII +repetoire is available, although this is the case for almost all encodings. +Anyway, use UTF-8! +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt new file mode 100644 index 0000000..915391e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt @@ -0,0 +1,19 @@ +Core.HiddenElements +TYPE: lookup +--DEFAULT-- +array ( + 'script' => true, + 'style' => true, +) +--DESCRIPTION-- + +

        + This directive is a lookup array of elements which should have their + contents removed when they are not allowed by the HTML definition. + For example, the contents of a script tag are not + normally shown in a document, so if script tags are to be removed, + their contents should be removed to. This is opposed to a b + tag, which defines some presentational changes but does not hide its + contents. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.Language.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.Language.txt new file mode 100644 index 0000000..233fca1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.Language.txt @@ -0,0 +1,10 @@ +Core.Language +TYPE: string +VERSION: 2.0.0 +DEFAULT: 'en' +--DESCRIPTION-- + +ISO 639 language code for localizable things in HTML Purifier to use, +which is mainly error reporting. There is currently only an English (en) +translation, so this directive is currently useless. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.LegacyEntityDecoder.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.LegacyEntityDecoder.txt new file mode 100644 index 0000000..392b436 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.LegacyEntityDecoder.txt @@ -0,0 +1,36 @@ +Core.LegacyEntityDecoder +TYPE: bool +VERSION: 4.9.0 +DEFAULT: false +--DESCRIPTION-- +

        + Prior to HTML Purifier 4.9.0, entities were decoded by performing + a global search replace for all entities whose decoded versions + did not have special meanings under HTML, and replaced them with + their decoded versions. We would match all entities, even if they did + not have a trailing semicolon, but only if there weren't any trailing + alphanumeric characters. +

        + + + + + + +
        OriginalTextAttribute
        &yen;¥¥
        &yen¥¥
        &yena&yena&yena
        &yen=¥=¥=
        +

        + In HTML Purifier 4.9.0, we changed the behavior of entity parsing + to match entities that had missing trailing semicolons in less + cases, to more closely match HTML5 parsing behavior: +

        + + + + + + +
        OriginalTextAttribute
        &yen;¥¥
        &yen¥¥
        &yena¥a&yena
        &yen=¥=&yen=
        +

        + This flag reverts back to pre-HTML Purifier 4.9.0 behavior. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt new file mode 100644 index 0000000..8983e2c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt @@ -0,0 +1,34 @@ +Core.LexerImpl +TYPE: mixed/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + This parameter determines what lexer implementation can be used. The + valid values are: +

        +
        +
        null
        +
        + Recommended, the lexer implementation will be auto-detected based on + your PHP-version and configuration. +
        +
        string lexer identifier
        +
        + This is a slim way of manually overridding the implementation. + Currently recognized values are: DOMLex (the default PHP5 +implementation) + and DirectLex (the default PHP4 implementation). Only use this if + you know what you are doing: usually, the auto-detection will + manage things for cases you aren't even aware of. +
        +
        object lexer instance
        +
        + Super-advanced: you can specify your own, custom, implementation that + implements the interface defined by HTMLPurifier_Lexer. + I may remove this option simply because I don't expect anyone + to use it. +
        +
        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt new file mode 100644 index 0000000..eb841a7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt @@ -0,0 +1,16 @@ +Core.MaintainLineNumbers +TYPE: bool/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If true, HTML Purifier will add line number information to all tokens. + This is useful when error reporting is turned on, but can result in + significant performance degradation and should not be used when + unnecessary. This directive must be used with the DirectLex lexer, + as the DOMLex lexer does not (yet) support this functionality. + If the value is null, an appropriate value will be selected based + on other configuration. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt new file mode 100644 index 0000000..d77f536 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt @@ -0,0 +1,11 @@ +Core.NormalizeNewlines +TYPE: bool +VERSION: 4.2.0 +DEFAULT: true +--DESCRIPTION-- +

        + Whether or not to normalize newlines to the operating + system default. When false, HTML Purifier + will attempt to preserve mixed newline files. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveBlanks.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveBlanks.txt new file mode 100644 index 0000000..95e5285 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveBlanks.txt @@ -0,0 +1,10 @@ +Core.RemoveBlanks +TYPE: bool +DEFAULT: false +VERSION: 4.18 +--DESCRIPTION-- +

        + If set to true, blank nodes will be removed. This can be useful for maintaining + backwards compatibility when upgrading from previous versions of PHP. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt new file mode 100644 index 0000000..4070c2a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt @@ -0,0 +1,12 @@ +Core.RemoveInvalidImg +TYPE: bool +DEFAULT: true +VERSION: 1.3.0 +--DESCRIPTION-- + +

        + This directive enables pre-emptive URI checking in img + tags, as the attribute validation strategy is not authorized to + remove elements from the document. Revert to pre-1.3.0 behavior by setting to false. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt new file mode 100644 index 0000000..3397d9f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt @@ -0,0 +1,11 @@ +Core.RemoveProcessingInstructions +TYPE: bool +VERSION: 4.2.0 +DEFAULT: false +--DESCRIPTION-- +Instead of escaping processing instructions in the form <? ... +?>, remove it out-right. This may be useful if the HTML +you are validating contains XML processing instruction gunk, however, +it can also be user-unfriendly for people attempting to post PHP +snippets. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt new file mode 100644 index 0000000..a4cd966 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt @@ -0,0 +1,12 @@ +Core.RemoveScriptContents +TYPE: bool/null +DEFAULT: NULL +VERSION: 2.0.0 +DEPRECATED-VERSION: 2.1.0 +DEPRECATED-USE: Core.HiddenElements +--DESCRIPTION-- +

        + This directive enables HTML Purifier to remove not only script tags + but all of their contents. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt new file mode 100644 index 0000000..3db50ef --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt @@ -0,0 +1,11 @@ +Filter.Custom +TYPE: list +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This directive can be used to add custom filters; it is nearly the + equivalent of the now deprecated HTMLPurifier->addFilter() + method. Specify an array of concrete implementations. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt new file mode 100644 index 0000000..16829bc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt @@ -0,0 +1,14 @@ +Filter.ExtractStyleBlocks.Escaping +TYPE: bool +VERSION: 3.0.0 +DEFAULT: true +ALIASES: Filter.ExtractStyleBlocksEscaping, FilterParam.ExtractStyleBlocksEscaping +--DESCRIPTION-- + +

        + Whether or not to escape the dangerous characters <, > and & + as \3C, \3E and \26, respectively. This is can be safely set to false + if the contents of StyleBlocks will be placed in an external stylesheet, + where there is no risk of it being interpreted as HTML. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt new file mode 100644 index 0000000..7f95f54 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt @@ -0,0 +1,29 @@ +Filter.ExtractStyleBlocks.Scope +TYPE: string/null +VERSION: 3.0.0 +DEFAULT: NULL +ALIASES: Filter.ExtractStyleBlocksScope, FilterParam.ExtractStyleBlocksScope +--DESCRIPTION-- + +

        + If you would like users to be able to define external stylesheets, but + only allow them to specify CSS declarations for a specific node and + prevent them from fiddling with other elements, use this directive. + It accepts any valid CSS selector, and will prepend this to any + CSS declaration extracted from the document. For example, if this + directive is set to #user-content and a user uses the + selector a:hover, the final selector will be + #user-content a:hover. +

        +

        + The comma shorthand may be used; consider the above example, with + #user-content, #user-content2, the final selector will + be #user-content a:hover, #user-content2 a:hover. +

        +

        + Warning: It is possible for users to bypass this measure + using a naughty + selector. This is a bug in CSS Tidy 1.3, not HTML + Purifier, and I am working to get it fixed. Until then, HTML Purifier + performs a basic check to prevent this. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt new file mode 100644 index 0000000..6c231b2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt @@ -0,0 +1,16 @@ +Filter.ExtractStyleBlocks.TidyImpl +TYPE: mixed/null +VERSION: 3.1.0 +DEFAULT: NULL +ALIASES: FilterParam.ExtractStyleBlocksTidyImpl +--DESCRIPTION-- +

        + If left NULL, HTML Purifier will attempt to instantiate a csstidy + class to use for internal cleaning. This will usually be good enough. +

        +

        + However, for trusted user input, you can set this to false to + disable cleaning. In addition, you can supply your own concrete implementation + of Tidy's interface to use, although I don't know why you'd want to do that. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt new file mode 100644 index 0000000..078d087 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt @@ -0,0 +1,74 @@ +Filter.ExtractStyleBlocks +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +EXTERNAL: CSSTidy +--DESCRIPTION-- +

        + This directive turns on the style block extraction filter, which removes + style blocks from input HTML, cleans them up with CSSTidy, + and places them in the StyleBlocks context variable, for further + use by you, usually to be placed in an external stylesheet, or a + style block in the head of your document. +

        +

        + Sample usage: +

        +
        ';
        +?>
        +
        +
        +
        +  Filter.ExtractStyleBlocks
        +body {color:#F00;} Some text';
        +
        +    $config = HTMLPurifier_Config::createDefault();
        +    $config->set('Filter', 'ExtractStyleBlocks', true);
        +    $purifier = new HTMLPurifier($config);
        +
        +    $html = $purifier->purify($dirty);
        +
        +    // This implementation writes the stylesheets to the styles/ directory.
        +    // You can also echo the styles inside the document, but it's a bit
        +    // more difficult to make sure they get interpreted properly by
        +    // browsers; try the usual CSS armoring techniques.
        +    $styles = $purifier->context->get('StyleBlocks');
        +    $dir = 'styles/';
        +    if (!is_dir($dir)) mkdir($dir);
        +    $hash = sha1($_GET['html']);
        +    foreach ($styles as $i => $style) {
        +        file_put_contents($name = $dir . $hash . "_$i");
        +        echo '';
        +    }
        +?>
        +
        +
        +  
        + +
        + + +]]>
        +

        + Warning: It is possible for a user to mount an + imagecrash attack using this CSS. Counter-measures are difficult; + it is not simply enough to limit the range of CSS lengths (using + relative lengths with many nesting levels allows for large values + to be attained without actually specifying them in the stylesheet), + and the flexible nature of selectors makes it difficult to selectively + disable lengths on image tags (HTML Purifier, however, does disable + CSS width and height in inline styling). There are probably two effective + counter measures: an explicit width and height set to auto in all + images in your document (unlikely) or the disabling of width and + height (somewhat reasonable). Whether or not these measures should be + used is left to the reader. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt new file mode 100644 index 0000000..321eaa2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt @@ -0,0 +1,16 @@ +Filter.YouTube +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + Warning: Deprecated in favor of %HTML.SafeObject and + %Output.FlashCompat (turn both on to allow YouTube videos and other + Flash content). +

        +

        + This directive enables YouTube video embedding in HTML Purifier. Check + this document + on embedding videos for more information on what this filter does. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt new file mode 100644 index 0000000..0b2c106 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt @@ -0,0 +1,25 @@ +HTML.Allowed +TYPE: itext/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + This is a preferred convenience directive that combines + %HTML.AllowedElements and %HTML.AllowedAttributes. + Specify elements and attributes that are allowed using: + element1[attr1|attr2],element2.... For example, + if you would like to only allow paragraphs and links, specify + a[href],p. You can specify attributes that apply + to all elements using an asterisk, e.g. *[lang]. + You can also use newlines instead of commas to separate elements. +

        +

        + Warning: + All of the constraints on the component directives are still enforced. + The syntax is a subset of TinyMCE's valid_elements + whitelist: directly copy-pasting it here will probably result in + broken whitelists. If %HTML.AllowedElements or %HTML.AllowedAttributes + are set, this directive has no effect. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt new file mode 100644 index 0000000..fcf093f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt @@ -0,0 +1,19 @@ +HTML.AllowedAttributes +TYPE: lookup/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If HTML Purifier's attribute set is unsatisfactory, overload it! + The syntax is "tag.attr" or "*.attr" for the global attributes + (style, id, class, dir, lang, xml:lang). +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. For + example, %HTML.EnableAttrID will take precedence over *.id in this + directive. You must set that directive to true before you can use + IDs at all. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt new file mode 100644 index 0000000..140e214 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt @@ -0,0 +1,10 @@ +HTML.AllowedComments +TYPE: lookup +VERSION: 4.4.0 +DEFAULT: array() +--DESCRIPTION-- +A whitelist which indicates what explicit comment bodies should be +allowed, modulo leading and trailing whitespace. See also %HTML.AllowedCommentsRegexp +(these directives are union'ed together, so a comment is considered +valid if any directive deems it valid.) +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt new file mode 100644 index 0000000..f22e977 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt @@ -0,0 +1,15 @@ +HTML.AllowedCommentsRegexp +TYPE: string/null +VERSION: 4.4.0 +DEFAULT: NULL +--DESCRIPTION-- +A regexp, which if it matches the body of a comment, indicates that +it should be allowed. Trailing and leading spaces are removed prior +to running this regular expression. +Warning: Make sure you specify +correct anchor metacharacters ^regex$, otherwise you may accept +comments that you did not mean to! In particular, the regex /foo|bar/ +is probably not sufficiently strict, since it also allows foobar. +See also %HTML.AllowedComments (these directives are union'ed together, +so a comment is considered valid if any directive deems it valid.) +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt new file mode 100644 index 0000000..1d3fa79 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt @@ -0,0 +1,23 @@ +HTML.AllowedElements +TYPE: lookup/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- +

        + If HTML Purifier's tag set is unsatisfactory for your needs, you can + overload it with your own list of tags to allow. If you change + this, you probably also want to change %HTML.AllowedAttributes; see + also %HTML.Allowed which lets you set allowed elements and + attributes at the same time. +

        +

        + If you attempt to allow an element that HTML Purifier does not know + about, HTML Purifier will raise an error. You will need to manually + tell HTML Purifier about this element by using the + advanced customization features. +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt new file mode 100644 index 0000000..5a59a55 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt @@ -0,0 +1,20 @@ +HTML.AllowedModules +TYPE: lookup/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + A doctype comes with a set of usual modules to use. Without having + to mucking about with the doctypes, you can quickly activate or + disable these modules by specifying which modules you wish to allow + with this directive. This is most useful for unit testing specific + modules, although end users may find it useful for their own ends. +

        +

        + If you specify a module that does not exist, the manager will silently + fail to use it, so be careful! User-defined modules are not affected + by this directive. Modules defined in %HTML.CoreModules are not + affected by this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt new file mode 100644 index 0000000..151fb7b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt @@ -0,0 +1,11 @@ +HTML.Attr.Name.UseCDATA +TYPE: bool +DEFAULT: false +VERSION: 4.0.0 +--DESCRIPTION-- +The W3C specification DTD defines the name attribute to be CDATA, not ID, due +to limitations of DTD. In certain documents, this relaxed behavior is desired, +whether it is to specify duplicate names, or to specify names that would be +illegal IDs (for example, names that begin with a digit.) Set this configuration +directive to true to use the relaxed parsing rules. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt new file mode 100644 index 0000000..45ae469 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt @@ -0,0 +1,18 @@ +HTML.BlockWrapper +TYPE: string +VERSION: 1.3.0 +DEFAULT: 'p' +--DESCRIPTION-- + +

        + String name of element to wrap inline elements that are inside a block + context. This only occurs in the children of blockquote in strict mode. +

        +

        + Example: by default value, + <blockquote>Foo</blockquote> would become + <blockquote><p>Foo</p></blockquote>. + The <p> tags can be replaced with whatever you desire, + as long as it is a block level element. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt new file mode 100644 index 0000000..5246188 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt @@ -0,0 +1,23 @@ +HTML.CoreModules +TYPE: lookup +VERSION: 2.0.0 +--DEFAULT-- +array ( + 'Structure' => true, + 'Text' => true, + 'Hypertext' => true, + 'List' => true, + 'NonXMLCommonAttributes' => true, + 'XMLCommonAttributes' => true, + 'CommonAttributes' => true, +) +--DESCRIPTION-- + +

        + Certain modularized doctypes (XHTML, namely), have certain modules + that must be included for the doctype to be an conforming document + type: put those modules here. By default, XHTML's core modules + are used. You can set this to a blank array to disable core module + protection, but this is not recommended. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt new file mode 100644 index 0000000..6ed70b5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt @@ -0,0 +1,9 @@ +HTML.CustomDoctype +TYPE: string/null +VERSION: 2.0.1 +DEFAULT: NULL +--DESCRIPTION-- + +A custom doctype for power-users who defined their own document +type. This directive only applies when %HTML.Doctype is blank. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt new file mode 100644 index 0000000..103db75 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt @@ -0,0 +1,33 @@ +HTML.DefinitionID +TYPE: string/null +DEFAULT: NULL +VERSION: 2.0.0 +--DESCRIPTION-- + +

        + Unique identifier for a custom-built HTML definition. If you edit + the raw version of the HTMLDefinition, introducing changes that the + configuration object does not reflect, you must specify this variable. + If you change your custom edits, you should change this directive, or + clear your cache. Example: +

        +
        +$config = HTMLPurifier_Config::createDefault();
        +$config->set('HTML', 'DefinitionID', '1');
        +$def = $config->getHTMLDefinition();
        +$def->addAttribute('a', 'tabindex', 'Number');
        +
        +

        + In the above example, the configuration is still at the defaults, but + using the advanced API, an extra attribute has been added. The + configuration object normally has no way of knowing that this change + has taken place, so it needs an extra directive: %HTML.DefinitionID. + If someone else attempts to use the default configuration, these two + pieces of code will not clobber each other in the cache, since one has + an extra directive attached to it. +

        +

        + You must specify a value to this directive to use the + advanced API features. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt new file mode 100644 index 0000000..229ae02 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt @@ -0,0 +1,16 @@ +HTML.DefinitionRev +TYPE: int +VERSION: 2.0.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition specified in + %HTML.DefinitionID. This serves the same purpose: uniquely identifying + your custom definition, but this one does so in a chronological + context: revision 3 is more up-to-date then revision 2. Thus, when + this gets incremented, the cache handling is smart enough to clean + up any older revisions of your definition as well as flush the + cache. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt new file mode 100644 index 0000000..9dab497 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt @@ -0,0 +1,11 @@ +HTML.Doctype +TYPE: string/null +DEFAULT: NULL +--DESCRIPTION-- +Doctype to use during filtering. Technically speaking this is not actually +a doctype (as it does not identify a corresponding DTD), but we are using +this name for sake of simplicity. When non-blank, this will override any +older directives like %HTML.XHTML or %HTML.Strict. +--ALLOWED-- +'HTML 4.01 Transitional', 'HTML 4.01 Strict', 'XHTML 1.0 Transitional', 'XHTML 1.0 Strict', 'XHTML 1.1' +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt new file mode 100644 index 0000000..7878dc0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt @@ -0,0 +1,11 @@ +HTML.FlashAllowFullScreen +TYPE: bool +VERSION: 4.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit embedded Flash content from + %HTML.SafeObject to expand to the full screen. Corresponds to + the allowFullScreen parameter. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt new file mode 100644 index 0000000..57358f9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt @@ -0,0 +1,21 @@ +HTML.ForbiddenAttributes +TYPE: lookup +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + While this directive is similar to %HTML.AllowedAttributes, for + forwards-compatibility with XML, this attribute has a different syntax. Instead of + tag.attr, use tag@attr. To disallow href + attributes in a tags, set this directive to + a@href. You can also disallow an attribute globally with + attr or *@attr (either syntax is fine; the latter + is provided for consistency with %HTML.AllowedAttributes). +

        +

        + Warning: This directive complements %HTML.ForbiddenElements, + accordingly, check + out that directive for a discussion of why you + should think twice before using this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt new file mode 100644 index 0000000..93a53e1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt @@ -0,0 +1,20 @@ +HTML.ForbiddenElements +TYPE: lookup +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This was, perhaps, the most requested feature ever in HTML + Purifier. Please don't abuse it! This is the logical inverse of + %HTML.AllowedElements, and it will override that directive, or any + other directive. +

        +

        + If possible, %HTML.Allowed is recommended over this directive, because it + can sometimes be difficult to tell whether or not you've forbidden all of + the behavior you would like to disallow. If you forbid img + with the expectation of preventing images on your site, you'll be in for + a nasty surprise when people start using the background-image + CSS property. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt new file mode 100644 index 0000000..4a432d8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Forms.txt @@ -0,0 +1,11 @@ +HTML.Forms +TYPE: bool +VERSION: 4.13.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit form elements in the user input, regardless of + %HTML.Trusted value. Please be very careful when using this functionality, as + enabling forms in untrusted documents may allow for phishing attacks. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt new file mode 100644 index 0000000..e424c38 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt @@ -0,0 +1,14 @@ +HTML.MaxImgLength +TYPE: int/null +DEFAULT: 1200 +VERSION: 3.1.1 +--DESCRIPTION-- +

        + This directive controls the maximum number of pixels in the width and + height attributes in img tags. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %CSS.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the HTML max is an integer). +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt new file mode 100644 index 0000000..700b309 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt @@ -0,0 +1,7 @@ +HTML.Nofollow +TYPE: bool +VERSION: 4.3.0 +DEFAULT: FALSE +--DESCRIPTION-- +If enabled, nofollow rel attributes are added to all outgoing links. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt new file mode 100644 index 0000000..62e8e16 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt @@ -0,0 +1,12 @@ +HTML.Parent +TYPE: string +VERSION: 1.3.0 +DEFAULT: 'div' +--DESCRIPTION-- + +

        + String name of element that HTML fragment passed to library will be + inserted in. An interesting variation would be using span as the + parent element, meaning that only inline tags would be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt new file mode 100644 index 0000000..dfb7204 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt @@ -0,0 +1,12 @@ +HTML.Proprietary +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to allow proprietary elements and attributes in your + documents, as per HTMLPurifier_HTMLModule_Proprietary. + Warning: This can cause your documents to stop + validating! +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt new file mode 100644 index 0000000..cdda09a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt @@ -0,0 +1,13 @@ +HTML.SafeEmbed +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit embed tags in documents, with a number of extra + security features added to prevent script execution. This is similar to + what websites like MySpace do to embed tags. Embed is a proprietary + element and will cause your website to stop validating; you should + see if you can use %Output.FlashCompat with %HTML.SafeObject instead + first.

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt new file mode 100644 index 0000000..5eb6ec2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt @@ -0,0 +1,13 @@ +HTML.SafeIframe +TYPE: bool +VERSION: 4.4.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit iframe tags in untrusted documents. This + directive must be accompanied by a whitelist of permitted iframes, + such as %URI.SafeIframeRegexp, otherwise it will fatally error. + This directive has no effect on strict doctypes, as iframes are not + valid. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt new file mode 100644 index 0000000..ceb342e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt @@ -0,0 +1,13 @@ +HTML.SafeObject +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit object tags in documents, with a number of extra + security features added to prevent script execution. This is similar to + what websites like MySpace do to object tags. You should also enable + %Output.FlashCompat in order to generate Internet Explorer + compatibility code for your object tags. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt new file mode 100644 index 0000000..5ebc7a1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt @@ -0,0 +1,10 @@ +HTML.SafeScripting +TYPE: lookup +VERSION: 4.5.0 +DEFAULT: array() +--DESCRIPTION-- +

        + Whether or not to permit script tags to external scripts in documents. + Inline scripting is not allowed, and the script must match an explicit whitelist. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt new file mode 100644 index 0000000..a8b1de5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt @@ -0,0 +1,9 @@ +HTML.Strict +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +DEPRECATED-VERSION: 1.7.0 +DEPRECATED-USE: HTML.Doctype +--DESCRIPTION-- +Determines whether or not to use Transitional (loose) or Strict rulesets. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt new file mode 100644 index 0000000..587a167 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt @@ -0,0 +1,8 @@ +HTML.TargetBlank +TYPE: bool +VERSION: 4.4.0 +DEFAULT: FALSE +--DESCRIPTION-- +If enabled, target=blank attributes are added to all outgoing links. +(This includes links from an HTTPS version of a page to an HTTP version.) +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoopener.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoopener.txt new file mode 100644 index 0000000..dd514c0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoopener.txt @@ -0,0 +1,10 @@ +--# vim: et sw=4 sts=4 +HTML.TargetNoopener +TYPE: bool +VERSION: 4.8.0 +DEFAULT: TRUE +--DESCRIPTION-- +If enabled, noopener rel attributes are added to links which have +a target attribute associated with them. This prevents malicious +destinations from overwriting the original window. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoreferrer.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoreferrer.txt new file mode 100644 index 0000000..cb5a0b0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoreferrer.txt @@ -0,0 +1,9 @@ +HTML.TargetNoreferrer +TYPE: bool +VERSION: 4.8.0 +DEFAULT: TRUE +--DESCRIPTION-- +If enabled, noreferrer rel attributes are added to links which have +a target attribute associated with them. This prevents malicious +destinations from overwriting the original window. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt new file mode 100644 index 0000000..b4c271b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt @@ -0,0 +1,8 @@ +HTML.TidyAdd +TYPE: lookup +VERSION: 2.0.0 +DEFAULT: array() +--DESCRIPTION-- + +Fixes to add to the default set of Tidy fixes as per your level. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt new file mode 100644 index 0000000..4186ccd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt @@ -0,0 +1,24 @@ +HTML.TidyLevel +TYPE: string +VERSION: 2.0.0 +DEFAULT: 'medium' +--DESCRIPTION-- + +

        General level of cleanliness the Tidy module should enforce. +There are four allowed values:

        +
        +
        none
        +
        No extra tidying should be done
        +
        light
        +
        Only fix elements that would be discarded otherwise due to + lack of support in doctype
        +
        medium
        +
        Enforce best practices
        +
        heavy
        +
        Transform all deprecated elements and attributes to standards + compliant equivalents
        +
        + +--ALLOWED-- +'none', 'light', 'medium', 'heavy' +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt new file mode 100644 index 0000000..996762b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt @@ -0,0 +1,8 @@ +HTML.TidyRemove +TYPE: lookup +VERSION: 2.0.0 +DEFAULT: array() +--DESCRIPTION-- + +Fixes to remove from the default set of Tidy fixes as per your level. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt new file mode 100644 index 0000000..1db9237 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt @@ -0,0 +1,9 @@ +HTML.Trusted +TYPE: bool +VERSION: 2.0.0 +DEFAULT: false +--DESCRIPTION-- +Indicates whether or not the user input is trusted or not. If the input is +trusted, a more expansive set of allowed tags and attributes will be used. +See also %CSS.Trusted. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt new file mode 100644 index 0000000..2a47e38 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt @@ -0,0 +1,11 @@ +HTML.XHTML +TYPE: bool +DEFAULT: true +VERSION: 1.1.0 +DEPRECATED-VERSION: 1.7.0 +DEPRECATED-USE: HTML.Doctype +--DESCRIPTION-- +Determines whether or not output is XHTML 1.0 or HTML 4.01 flavor. +--ALIASES-- +Core.XHTML +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt new file mode 100644 index 0000000..08921fd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt @@ -0,0 +1,10 @@ +Output.CommentScriptContents +TYPE: bool +VERSION: 2.0.0 +DEFAULT: true +--DESCRIPTION-- +Determines whether or not HTML Purifier should attempt to fix up the +contents of script tags for legacy browsers with comments. +--ALIASES-- +Core.CommentScriptContents +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt new file mode 100644 index 0000000..d6f0d9f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt @@ -0,0 +1,15 @@ +Output.FixInnerHTML +TYPE: bool +VERSION: 4.3.0 +DEFAULT: true +--DESCRIPTION-- +

        + If true, HTML Purifier will protect against Internet Explorer's + mishandling of the innerHTML attribute by appending + a space to any attribute that does not contain angled brackets, spaces + or quotes, but contains a backtick. This slightly changes the + semantics of any given attribute, so if this is unacceptable and + you do not use innerHTML on any of your pages, you can + turn this directive off. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt new file mode 100644 index 0000000..93398e8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt @@ -0,0 +1,11 @@ +Output.FlashCompat +TYPE: bool +VERSION: 4.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + If true, HTML Purifier will generate Internet Explorer compatibility + code for all object code. This is highly recommended if you enable + %HTML.SafeObject. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt new file mode 100644 index 0000000..79f8ad8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt @@ -0,0 +1,13 @@ +Output.Newline +TYPE: string/null +VERSION: 2.0.1 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Newline string to format final output with. If left null, HTML Purifier + will auto-detect the default newline type of the system and use that; + you can manually override it here. Remember, \r\n is Windows, \r + is Mac, and \n is Unix. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt new file mode 100644 index 0000000..232b023 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt @@ -0,0 +1,14 @@ +Output.SortAttr +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + If true, HTML Purifier will sort attributes by name before writing them back + to the document, converting a tag like: <el b="" a="" c="" /> + to <el a="" b="" c="" />. This is a workaround for + a bug in FCKeditor which causes it to swap attributes order, adding noise + to text diffs. If you're not seeing this bug, chances are, you don't need + this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt new file mode 100644 index 0000000..06bab00 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt @@ -0,0 +1,25 @@ +Output.TidyFormat +TYPE: bool +VERSION: 1.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Determines whether or not to run Tidy on the final output for pretty + formatting reasons, such as indentation and wrap. +

        +

        + This can greatly improve readability for editors who are hand-editing + the HTML, but is by no means necessary as HTML Purifier has already + fixed all major errors the HTML may have had. Tidy is a non-default + extension, and this directive will silently fail if Tidy is not + available. +

        +

        + If you are looking to make the overall look of your page's source + better, I recommend running Tidy on the entire page rather than just + user-content (after all, the indentation relative to the containing + blocks will be incorrect). +

        +--ALIASES-- +Core.TidyFormat +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt new file mode 100644 index 0000000..071bc02 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt @@ -0,0 +1,7 @@ +Test.ForceNoIconv +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +When set to true, HTMLPurifier_Encoder will act as if iconv does not exist +and use only pure PHP implementations. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt new file mode 100644 index 0000000..eb97307 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt @@ -0,0 +1,18 @@ +URI.AllowedSchemes +TYPE: lookup +--DEFAULT-- +array ( + 'http' => true, + 'https' => true, + 'mailto' => true, + 'ftp' => true, + 'nntp' => true, + 'news' => true, + 'tel' => true, +) +--DESCRIPTION-- +Whitelist that defines the schemes that a URI is allowed to have. This +prevents XSS attacks from using pseudo-schemes like javascript or mocha. +There is also support for the data and file +URI schemes, but they are not enabled by default. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Base.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Base.txt new file mode 100644 index 0000000..876f068 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Base.txt @@ -0,0 +1,17 @@ +URI.Base +TYPE: string/null +VERSION: 2.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + The base URI is the URI of the document this purified HTML will be + inserted into. This information is important if HTML Purifier needs + to calculate absolute URIs from relative URIs, such as when %URI.MakeAbsolute + is on. You may use a non-absolute URI for this value, but behavior + may vary (%URI.MakeAbsolute deals nicely with both absolute and + relative paths, but forwards-compatibility is not guaranteed). + Warning: If set, the scheme on this URI + overrides the one specified by %URI.DefaultScheme. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt new file mode 100644 index 0000000..834bc08 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt @@ -0,0 +1,15 @@ +URI.DefaultScheme +TYPE: string/null +DEFAULT: 'http' +--DESCRIPTION-- + +

        + Defines through what scheme the output will be served, in order to + select the proper object validator when no scheme information is present. +

        + +

        + Starting with HTML Purifier 4.9.0, the default scheme can be null, in + which case we reject all URIs which do not have explicit schemes. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt new file mode 100644 index 0000000..f05312b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt @@ -0,0 +1,11 @@ +URI.DefinitionID +TYPE: string/null +VERSION: 2.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Unique identifier for a custom-built URI definition. If you want + to add custom URIFilters, you must specify this value. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt new file mode 100644 index 0000000..80cfea9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt @@ -0,0 +1,11 @@ +URI.DefinitionRev +TYPE: int +VERSION: 2.1.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition. See + %HTML.DefinitionRev for details. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt new file mode 100644 index 0000000..71ce025 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt @@ -0,0 +1,14 @@ +URI.Disable +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Disables all URIs in all forms. Not sure why you'd want to do that + (after all, the Internet's founded on the notion of a hyperlink). +

        + +--ALIASES-- +Attr.DisableURI +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt new file mode 100644 index 0000000..13c122c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt @@ -0,0 +1,11 @@ +URI.DisableExternal +TYPE: bool +VERSION: 1.2.0 +DEFAULT: false +--DESCRIPTION-- +Disables links to external websites. This is a highly effective anti-spam +and anti-pagerank-leech measure, but comes at a hefty price: nolinks or +images outside of your domain will be allowed. Non-linkified URIs will +still be preserved. If you want to be able to link to subdomains or use +absolute URIs, specify %URI.Host for your website. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt new file mode 100644 index 0000000..abcc1ef --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt @@ -0,0 +1,13 @@ +URI.DisableExternalResources +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +--DESCRIPTION-- +Disables the embedding of external resources, preventing users from +embedding things like images from other hosts. This prevents access +tracking (good for email viewers), bandwidth leeching, cross-site request +forging, goatse.cx posting, and other nasties, but also results in a loss +of end-user functionality (they can't directly post a pic they posted from +Flickr anymore). Use it if you don't have a robust user-content moderation +team. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt new file mode 100644 index 0000000..f891de4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt @@ -0,0 +1,15 @@ +URI.DisableResources +TYPE: bool +VERSION: 4.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + Disables embedding resources, essentially meaning no pictures. You can + still link to them though. See %URI.DisableExternalResources for why + this might be a good idea. +

        +

        + Note: While this directive has been available since 1.3.0, + it didn't actually start doing anything until 4.2.0. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Host.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Host.txt new file mode 100644 index 0000000..ee83b12 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Host.txt @@ -0,0 +1,19 @@ +URI.Host +TYPE: string/null +VERSION: 1.2.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Defines the domain name of the server, so we can determine whether or + an absolute URI is from your website or not. Not strictly necessary, + as users should be using relative URIs to reference resources on your + website. It will, however, let you use absolute URIs to link to + subdomains of the domain you post here: i.e. example.com will allow + sub.example.com. However, higher up domains will still be excluded: + if you set %URI.Host to sub.example.com, example.com will be blocked. + Note: This directive overrides %URI.Base because + a given page may be on a sub-domain, but you wish HTML Purifier to be + more relaxed and allow some of the parent domains too. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt new file mode 100644 index 0000000..0b6df76 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt @@ -0,0 +1,9 @@ +URI.HostBlacklist +TYPE: list +VERSION: 1.3.0 +DEFAULT: array() +--DESCRIPTION-- +List of strings that are forbidden in the host of any URI. Use it to kill +domain names of spam, etc. Note that it will catch anything in the domain, +so moo.com will catch moo.com.example.com. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt new file mode 100644 index 0000000..4214900 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt @@ -0,0 +1,13 @@ +URI.MakeAbsolute +TYPE: bool +VERSION: 2.1.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Converts all URIs into absolute forms. This is useful when the HTML + being filtered assumes a specific base path, but will actually be + viewed in a different context (and setting an alternate base URI is + not possible). %URI.Base must be set for this directive to work. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt new file mode 100644 index 0000000..58c81dc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt @@ -0,0 +1,83 @@ +URI.Munge +TYPE: string/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Munges all browsable (usually http, https and ftp) + absolute URIs into another URI, usually a URI redirection service. + This directive accepts a URI, formatted with a %s where + the url-encoded original URI should be inserted (sample: + http://www.google.com/url?q=%s). +

        +

        + Uses for this directive: +

        +
          +
        • + Prevent PageRank leaks, while being fairly transparent + to users (you may also want to add some client side JavaScript to + override the text in the statusbar). Notice: + Many security experts believe that this form of protection does not deter spam-bots. +
        • +
        • + Redirect users to a splash page telling them they are leaving your + website. While this is poor usability practice, it is often mandated + in corporate environments. +
        • +
        +

        + Prior to HTML Purifier 3.1.1, this directive also enabled the munging + of browsable external resources, which could break things if your redirection + script was a splash page or used meta tags. To revert to + previous behavior, please use %URI.MungeResources. +

        +

        + You may want to also use %URI.MungeSecretKey along with this directive + in order to enforce what URIs your redirector script allows. Open + redirector scripts can be a security risk and negatively affect the + reputation of your domain name. +

        +

        + Starting with HTML Purifier 3.1.1, there is also these substitutions: +

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        KeyDescriptionExample <a href="">
        %r1 - The URI embeds a resource
        (blank) - The URI is merely a link
        %nThe name of the tag this URI came froma
        %mThe name of the attribute this URI came fromhref
        %pThe name of the CSS property this URI came from, or blank if irrelevant
        +

        + Admittedly, these letters are somewhat arbitrary; the only stipulation + was that they couldn't be a through f. r is for resource (I would have preferred + e, but you take what you can get), n is for name, m + was picked because it came after n (and I couldn't use a), p is for + property. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt new file mode 100644 index 0000000..6fce0fd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt @@ -0,0 +1,17 @@ +URI.MungeResources +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + If true, any URI munging directives like %URI.Munge + will also apply to embedded resources, such as <img src="">. + Be careful enabling this directive if you have a redirector script + that does not use the Location HTTP header; all of your images + and other embedded resources will break. +

        +

        + Warning: It is strongly advised you use this in conjunction + %URI.MungeSecretKey to mitigate the security risk of an open redirector. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt new file mode 100644 index 0000000..1e17c1d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt @@ -0,0 +1,30 @@ +URI.MungeSecretKey +TYPE: string/null +VERSION: 3.1.1 +DEFAULT: NULL +--DESCRIPTION-- +

        + This directive enables secure checksum generation along with %URI.Munge. + It should be set to a secure key that is not shared with anyone else. + The checksum can be placed in the URI using %t. Use of this checksum + affords an additional level of protection by allowing a redirector + to check if a URI has passed through HTML Purifier with this line: +

        + +
        $checksum === hash_hmac("sha256", $url, $secret_key)
        + +

        + If the output is TRUE, the redirector script should accept the URI. +

        + +

        + Please note that it would still be possible for an attacker to procure + secure hashes en-mass by abusing your website's Preview feature or the + like, but this service affords an additional level of protection + that should be combined with website blacklisting. +

        + +

        + Remember this has no effect if %URI.Munge is not on. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt new file mode 100644 index 0000000..23331a4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt @@ -0,0 +1,9 @@ +URI.OverrideAllowedSchemes +TYPE: bool +DEFAULT: true +--DESCRIPTION-- +If this is set to true (which it is by default), you can override +%URI.AllowedSchemes by simply registering a HTMLPurifier_URIScheme to the +registry. If false, you will also have to update that directive in order +to add more schemes. +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt new file mode 100644 index 0000000..7908483 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt @@ -0,0 +1,22 @@ +URI.SafeIframeRegexp +TYPE: string/null +VERSION: 4.4.0 +DEFAULT: NULL +--DESCRIPTION-- +

        + A PCRE regular expression that will be matched against an iframe URI. This is + a relatively inflexible scheme, but works well enough for the most common + use-case of iframes: embedded video. This directive only has an effect if + %HTML.SafeIframe is enabled. Here are some example values: +

        +
          +
        • %^http://www.youtube.com/embed/% - Allow YouTube videos
        • +
        • %^http://player.vimeo.com/video/% - Allow Vimeo videos
        • +
        • %^http://(www.youtube.com/embed/|player.vimeo.com/video/)% - Allow both
        • +
        +

        + Note that this directive does not give you enough granularity to, say, disable + all autoplay videos. Pipe up on the HTML Purifier forums if this + is a capability you want. +

        +--# vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/info.ini b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/info.ini new file mode 100644 index 0000000..5de4505 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ConfigSchema/schema/info.ini @@ -0,0 +1,3 @@ +name = "HTML Purifier" + +; vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ContentSets.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ContentSets.php new file mode 100644 index 0000000..543e3f8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ContentSets.php @@ -0,0 +1,170 @@ + true) indexed by name. + * @type array + * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets + */ + public $lookup = array(); + + /** + * Synchronized list of defined content sets (keys of info). + * @type array + */ + protected $keys = array(); + /** + * Synchronized list of defined content values (values of info). + * @type array + */ + protected $values = array(); + + /** + * Merges in module's content sets, expands identifiers in the content + * sets and populates the keys, values and lookup member variables. + * @param HTMLPurifier_HTMLModule[] $modules List of HTMLPurifier_HTMLModule + */ + public function __construct($modules) + { + if (!is_array($modules)) { + $modules = array($modules); + } + // populate content_sets based on module hints + // sorry, no way of overloading + foreach ($modules as $module) { + foreach ($module->content_sets as $key => $value) { + $temp = $this->convertToLookup($value); + if (isset($this->lookup[$key])) { + // add it into the existing content set + $this->lookup[$key] = array_merge($this->lookup[$key], $temp); + } else { + $this->lookup[$key] = $temp; + } + } + } + $old_lookup = false; + while ($old_lookup !== $this->lookup) { + $old_lookup = $this->lookup; + foreach ($this->lookup as $i => $set) { + $add = array(); + foreach ($set as $element => $x) { + if (isset($this->lookup[$element])) { + $add += $this->lookup[$element]; + unset($this->lookup[$i][$element]); + } + } + $this->lookup[$i] += $add; + } + } + + foreach ($this->lookup as $key => $lookup) { + $this->info[$key] = implode(' | ', array_keys($lookup)); + } + $this->keys = array_keys($this->info); + $this->values = array_values($this->info); + } + + /** + * Accepts a definition; generates and assigns a ChildDef for it + * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef reference + * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef + */ + public function generateChildDef(&$def, $module) + { + if (!empty($def->child)) { // already done! + return; + } + $content_model = $def->content_model; + if (is_string($content_model)) { + // Assume that $this->keys is alphanumeric + $def->content_model = preg_replace_callback( + '/\b(' . implode('|', $this->keys) . ')\b/', + array($this, 'generateChildDefCallback'), + $content_model + ); + //$def->content_model = str_replace( + // $this->keys, $this->values, $content_model); + } + $def->child = $this->getChildDef($def, $module); + } + + public function generateChildDefCallback($matches) + { + return $this->info[$matches[0]]; + } + + /** + * Instantiates a ChildDef based on content_model and content_model_type + * member variables in HTMLPurifier_ElementDef + * @note This will also defer to modules for custom HTMLPurifier_ChildDef + * subclasses that need content set expansion + * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef to have ChildDef extracted + * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef + * @return HTMLPurifier_ChildDef corresponding to ElementDef + */ + public function getChildDef($def, $module) + { + $value = $def->content_model; + if (is_object($value)) { + trigger_error( + 'Literal object child definitions should be stored in '. + 'ElementDef->child not ElementDef->content_model', + E_USER_NOTICE + ); + return $value; + } + switch ($def->content_model_type) { + case 'required': + return new HTMLPurifier_ChildDef_Required($value); + case 'optional': + return new HTMLPurifier_ChildDef_Optional($value); + case 'empty': + return new HTMLPurifier_ChildDef_Empty(); + case 'custom': + return new HTMLPurifier_ChildDef_Custom($value); + } + // defer to its module + $return = false; + if ($module->defines_child_def) { // save a func call + $return = $module->getChildDef($def); + } + if ($return !== false) { + return $return; + } + // error-out + trigger_error( + 'Could not determine which ChildDef class to instantiate', + E_USER_ERROR + ); + return false; + } + + /** + * Converts a string list of elements separated by pipes into + * a lookup array. + * @param string $string List of elements + * @return array Lookup array of elements + */ + protected function convertToLookup($string) + { + $array = explode('|', str_replace(' ', '', $string)); + $ret = array(); + foreach ($array as $k) { + $ret[$k] = true; + } + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Context.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Context.php new file mode 100644 index 0000000..00e509c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Context.php @@ -0,0 +1,95 @@ +_storage)) { + trigger_error( + "Name $name produces collision, cannot re-register", + E_USER_ERROR + ); + return; + } + $this->_storage[$name] =& $ref; + } + + /** + * Retrieves a variable reference from the context. + * @param string $name String name + * @param bool $ignore_error Boolean whether or not to ignore error + * @return mixed + */ + public function &get($name, $ignore_error = false) + { + if (!array_key_exists($name, $this->_storage)) { + if (!$ignore_error) { + trigger_error( + "Attempted to retrieve non-existent variable $name", + E_USER_ERROR + ); + } + $var = null; // so we can return by reference + return $var; + } + return $this->_storage[$name]; + } + + /** + * Destroys a variable in the context. + * @param string $name String name + */ + public function destroy($name) + { + if (!array_key_exists($name, $this->_storage)) { + trigger_error( + "Attempted to destroy non-existent variable $name", + E_USER_ERROR + ); + return; + } + unset($this->_storage[$name]); + } + + /** + * Checks whether or not the variable exists. + * @param string $name String name + * @return bool + */ + public function exists($name) + { + return array_key_exists($name, $this->_storage); + } + + /** + * Loads a series of variables from an associative array + * @param array $context_array Assoc array of variables to load + */ + public function loadArray($context_array) + { + foreach ($context_array as $key => $discard) { + $this->register($key, $context_array[$key]); + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Definition.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Definition.php new file mode 100644 index 0000000..bc6d433 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Definition.php @@ -0,0 +1,55 @@ +setup) { + return; + } + $this->setup = true; + $this->doSetup($config); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache.php new file mode 100644 index 0000000..9aa8ff3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache.php @@ -0,0 +1,129 @@ +type = $type; + } + + /** + * Generates a unique identifier for a particular configuration + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config + * @return string + */ + public function generateKey($config) + { + return $config->version . ',' . // possibly replace with function calls + $config->getBatchSerial($this->type) . ',' . + $config->get($this->type . '.DefinitionRev'); + } + + /** + * Tests whether or not a key is old with respect to the configuration's + * version and revision number. + * @param string $key Key to test + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config to test against + * @return bool + */ + public function isOld($key, $config) + { + if (substr_count($key, ',') < 2) { + return true; + } + list($version, $hash, $revision) = explode(',', $key, 3); + $compare = version_compare($version, $config->version); + // version mismatch, is always old + if ($compare != 0) { + return true; + } + // versions match, ids match, check revision number + if ($hash == $config->getBatchSerial($this->type) && + $revision < $config->get($this->type . '.DefinitionRev')) { + return true; + } + return false; + } + + /** + * Checks if a definition's type jives with the cache's type + * @note Throws an error on failure + * @param HTMLPurifier_Definition $def Definition object to check + * @return bool true if good, false if not + */ + public function checkDefType($def) + { + if ($def->type !== $this->type) { + trigger_error("Cannot use definition of type {$def->type} in cache for {$this->type}"); + return false; + } + return true; + } + + /** + * Adds a definition object to the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + */ + abstract public function add($def, $config); + + /** + * Unconditionally saves a definition object to the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + */ + abstract public function set($def, $config); + + /** + * Replace an object in the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + */ + abstract public function replace($def, $config); + + /** + * Retrieves a definition object from the cache + * @param HTMLPurifier_Config $config + */ + abstract public function get($config); + + /** + * Removes a definition object to the cache + * @param HTMLPurifier_Config $config + */ + abstract public function remove($config); + + /** + * Clears all objects from cache + * @param HTMLPurifier_Config $config + */ + abstract public function flush($config); + + /** + * Clears all expired (older version or revision) objects from cache + * @note Be careful implementing this method as flush. Flush must + * not interfere with other Definition types, and cleanup() + * should not be repeatedly called by userland code. + * @param HTMLPurifier_Config $config + */ + abstract public function cleanup($config); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator.php new file mode 100644 index 0000000..b57a51b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator.php @@ -0,0 +1,112 @@ +copy(); + // reference is necessary for mocks in PHP 4 + $decorator->cache =& $cache; + $decorator->type = $cache->type; + return $decorator; + } + + /** + * Cross-compatible clone substitute + * @return HTMLPurifier_DefinitionCache_Decorator + */ + public function copy() + { + return new HTMLPurifier_DefinitionCache_Decorator(); + } + + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function add($def, $config) + { + return $this->cache->add($def, $config); + } + + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function set($def, $config) + { + return $this->cache->set($def, $config); + } + + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function replace($def, $config) + { + return $this->cache->replace($def, $config); + } + + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function get($config) + { + return $this->cache->get($config); + } + + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function remove($config) + { + return $this->cache->remove($config); + } + + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function flush($config) + { + return $this->cache->flush($config); + } + + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function cleanup($config) + { + return $this->cache->cleanup($config); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php new file mode 100644 index 0000000..4991777 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator/Cleanup.php @@ -0,0 +1,78 @@ +definitions[$this->generateKey($config)] = $def; + } + return $status; + } + + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function set($def, $config) + { + $status = parent::set($def, $config); + if ($status) { + $this->definitions[$this->generateKey($config)] = $def; + } + return $status; + } + + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function replace($def, $config) + { + $status = parent::replace($def, $config); + if ($status) { + $this->definitions[$this->generateKey($config)] = $def; + } + return $status; + } + + /** + * @param HTMLPurifier_Config $config + * @return mixed + */ + public function get($config) + { + $key = $this->generateKey($config); + if (isset($this->definitions[$key])) { + return $this->definitions[$key]; + } + $this->definitions[$key] = parent::get($config); + return $this->definitions[$key]; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator/Template.php.in b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator/Template.php.in new file mode 100644 index 0000000..b1fec8d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Decorator/Template.php.in @@ -0,0 +1,82 @@ +checkDefType($def)) { + return; + } + $file = $this->generateFilePath($config); + if (file_exists($file)) { + return false; + } + if (!$this->_prepareDir($config)) { + return false; + } + return $this->_write($file, serialize($def), $config); + } + + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return int|bool + */ + public function set($def, $config) + { + if (!$this->checkDefType($def)) { + return; + } + $file = $this->generateFilePath($config); + if (!$this->_prepareDir($config)) { + return false; + } + return $this->_write($file, serialize($def), $config); + } + + /** + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + * @return int|bool + */ + public function replace($def, $config) + { + if (!$this->checkDefType($def)) { + return; + } + $file = $this->generateFilePath($config); + if (!file_exists($file)) { + return false; + } + if (!$this->_prepareDir($config)) { + return false; + } + return $this->_write($file, serialize($def), $config); + } + + /** + * @param HTMLPurifier_Config $config + * @return bool|HTMLPurifier_Config + */ + public function get($config) + { + $file = $this->generateFilePath($config); + if (!file_exists($file)) { + return false; + } + return unserialize(file_get_contents($file)); + } + + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function remove($config) + { + $file = $this->generateFilePath($config); + if (!file_exists($file)) { + return false; + } + return unlink($file); + } + + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function flush($config) + { + if (!$this->_prepareDir($config)) { + return false; + } + $dir = $this->generateDirectoryPath($config); + $dh = opendir($dir); + // Apparently, on some versions of PHP, readdir will return + // an empty string if you pass an invalid argument to readdir. + // So you need this test. See #49. + if (false === $dh) { + return false; + } + while (false !== ($filename = readdir($dh))) { + if (empty($filename)) { + continue; + } + if ($filename[0] === '.') { + continue; + } + unlink($dir . '/' . $filename); + } + closedir($dh); + return true; + } + + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function cleanup($config) + { + if (!$this->_prepareDir($config)) { + return false; + } + $dir = $this->generateDirectoryPath($config); + $dh = opendir($dir); + // See #49 (and above). + if (false === $dh) { + return false; + } + while (false !== ($filename = readdir($dh))) { + if (empty($filename)) { + continue; + } + if ($filename[0] === '.') { + continue; + } + $key = substr($filename, 0, strlen($filename) - 4); + if ($this->isOld($key, $config)) { + unlink($dir . '/' . $filename); + } + } + closedir($dh); + return true; + } + + /** + * Generates the file path to the serial file corresponding to + * the configuration and definition name + * @param HTMLPurifier_Config $config + * @return string + * @todo Make protected + */ + public function generateFilePath($config) + { + $key = $this->generateKey($config); + return $this->generateDirectoryPath($config) . '/' . $key . '.ser'; + } + + /** + * Generates the path to the directory contain this cache's serial files + * @param HTMLPurifier_Config $config + * @return string + * @note No trailing slash + * @todo Make protected + */ + public function generateDirectoryPath($config) + { + $base = $this->generateBaseDirectoryPath($config); + return $base . '/' . $this->type; + } + + /** + * Generates path to base directory that contains all definition type + * serials + * @param HTMLPurifier_Config $config + * @return mixed|string + * @todo Make protected + */ + public function generateBaseDirectoryPath($config) + { + $base = $config->get('Cache.SerializerPath'); + $base = is_null($base) ? HTMLPURIFIER_PREFIX . '/HTMLPurifier/DefinitionCache/Serializer' : $base; + return $base; + } + + /** + * Convenience wrapper function for file_put_contents + * @param string $file File name to write to + * @param string $data Data to write into file + * @param HTMLPurifier_Config $config + * @return int|bool Number of bytes written if success, or false if failure. + */ + private function _write($file, $data, $config) + { + $result = file_put_contents($file, $data); + if ($result !== false) { + // set permissions of the new file (no execute) + $chmod = $config->get('Cache.SerializerPermissions'); + if ($chmod !== null) { + chmod($file, $chmod & 0666); + } + } + return $result; + } + + /** + * Prepares the directory that this type stores the serials in + * @param HTMLPurifier_Config $config + * @return bool True if successful + */ + private function _prepareDir($config) + { + $directory = $this->generateDirectoryPath($config); + $chmod = $config->get('Cache.SerializerPermissions'); + if ($chmod === null) { + if (!@mkdir($directory) && !is_dir($directory)) { + trigger_error( + 'Could not create directory ' . $directory . '', + E_USER_WARNING + ); + return false; + } + return true; + } + if (!is_dir($directory)) { + $base = $this->generateBaseDirectoryPath($config); + if (!is_dir($base)) { + trigger_error( + 'Base directory ' . $base . ' does not exist, + please create or change using %Cache.SerializerPath', + E_USER_WARNING + ); + return false; + } elseif (!$this->_testPermissions($base, $chmod)) { + return false; + } + if (!@mkdir($directory, $chmod) && !is_dir($directory)) { + trigger_error( + 'Could not create directory ' . $directory . '', + E_USER_WARNING + ); + return false; + } + if (!$this->_testPermissions($directory, $chmod)) { + return false; + } + } elseif (!$this->_testPermissions($directory, $chmod)) { + return false; + } + return true; + } + + /** + * Tests permissions on a directory and throws out friendly + * error messages and attempts to chmod it itself if possible + * @param string $dir Directory path + * @param int $chmod Permissions + * @return bool True if directory is writable + */ + private function _testPermissions($dir, $chmod) + { + // early abort, if it is writable, everything is hunky-dory + if (is_writable($dir)) { + return true; + } + if (!is_dir($dir)) { + // generally, you'll want to handle this beforehand + // so a more specific error message can be given + trigger_error( + 'Directory ' . $dir . ' does not exist', + E_USER_WARNING + ); + return false; + } + if (function_exists('posix_getuid') && $chmod !== null) { + // POSIX system, we can give more specific advice + if (fileowner($dir) === posix_getuid()) { + // we can chmod it ourselves + $chmod = $chmod | 0700; + if (chmod($dir, $chmod)) { + return true; + } + } elseif (filegroup($dir) === posix_getgid()) { + $chmod = $chmod | 0070; + } else { + // PHP's probably running as nobody, it is + // not obvious how to fix this (777 is probably + // bad if you are multi-user), let the user figure it out + $chmod = null; + } + trigger_error( + 'Directory ' . $dir . ' not writable. ' . + ($chmod === null ? '' : 'Please chmod to ' . decoct($chmod)), + E_USER_WARNING + ); + } else { + // generic error message + trigger_error( + 'Directory ' . $dir . ' not writable, ' . + 'please alter file permissions', + E_USER_WARNING + ); + } + return false; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/CSS/4.18.0,4114918a13a428a8482a8a449792a5a8747582b5,1.ser b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/CSS/4.18.0,4114918a13a428a8482a8a449792a5a8747582b5,1.ser new file mode 100644 index 0000000..9d89a0a Binary files /dev/null and b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/CSS/4.18.0,4114918a13a428a8482a8a449792a5a8747582b5,1.ser differ diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/CSS/4.18.0,666c14d9f7a7a725d9787edbb20f25995a46ccec,1.ser b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/CSS/4.18.0,666c14d9f7a7a725d9787edbb20f25995a46ccec,1.ser new file mode 100644 index 0000000..bb86db9 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/CSS/4.18.0,666c14d9f7a7a725d9787edbb20f25995a46ccec,1.ser differ diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/HTML/4.18.0,3990ba1a78445d84f05f47b4c6f68bd0ad7b538c,1.ser b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/HTML/4.18.0,3990ba1a78445d84f05f47b4c6f68bd0ad7b538c,1.ser new file mode 100644 index 0000000..e2c4292 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/HTML/4.18.0,3990ba1a78445d84f05f47b4c6f68bd0ad7b538c,1.ser differ diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/HTML/4.18.0,b3800efc2bd7d3eacd6de47e324fdcc60d230915,1.ser b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/HTML/4.18.0,b3800efc2bd7d3eacd6de47e324fdcc60d230915,1.ser new file mode 100644 index 0000000..94a9136 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/HTML/4.18.0,b3800efc2bd7d3eacd6de47e324fdcc60d230915,1.ser differ diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/README b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/README new file mode 100644 index 0000000..2e35c1c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/README @@ -0,0 +1,3 @@ +This is a dummy file to prevent Git from ignoring this empty directory. + + vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/URI/4.18.0,2466b7673879a0d4a348461e7e46426e4d8c9631,1.ser b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/URI/4.18.0,2466b7673879a0d4a348461e7e46426e4d8c9631,1.ser new file mode 100644 index 0000000..1c15bd7 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCache/Serializer/URI/4.18.0,2466b7673879a0d4a348461e7e46426e4d8c9631,1.ser differ diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCacheFactory.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCacheFactory.php new file mode 100644 index 0000000..3a0f461 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DefinitionCacheFactory.php @@ -0,0 +1,106 @@ + array()); + + /** + * @type array + */ + protected $implementations = array(); + + /** + * @type HTMLPurifier_DefinitionCache_Decorator[] + */ + protected $decorators = array(); + + /** + * Initialize default decorators + */ + public function setup() + { + $this->addDecorator('Cleanup'); + } + + /** + * Retrieves an instance of global definition cache factory. + * @param HTMLPurifier_DefinitionCacheFactory $prototype + * @return HTMLPurifier_DefinitionCacheFactory + */ + public static function instance($prototype = null) + { + static $instance; + if ($prototype !== null) { + $instance = $prototype; + } elseif ($instance === null || $prototype === true) { + $instance = new HTMLPurifier_DefinitionCacheFactory(); + $instance->setup(); + } + return $instance; + } + + /** + * Registers a new definition cache object + * @param string $short Short name of cache object, for reference + * @param string $long Full class name of cache object, for construction + */ + public function register($short, $long) + { + $this->implementations[$short] = $long; + } + + /** + * Factory method that creates a cache object based on configuration + * @param string $type Name of definitions handled by cache + * @param HTMLPurifier_Config $config Config instance + * @return mixed + */ + public function create($type, $config) + { + $method = $config->get('Cache.DefinitionImpl'); + if ($method === null) { + return new HTMLPurifier_DefinitionCache_Null($type); + } + if (!empty($this->caches[$method][$type])) { + return $this->caches[$method][$type]; + } + if (isset($this->implementations[$method]) && + class_exists($class = $this->implementations[$method])) { + $cache = new $class($type); + } else { + if ($method != 'Serializer') { + trigger_error("Unrecognized DefinitionCache $method, using Serializer instead", E_USER_WARNING); + } + $cache = new HTMLPurifier_DefinitionCache_Serializer($type); + } + foreach ($this->decorators as $decorator) { + $new_cache = $decorator->decorate($cache); + // prevent infinite recursion in PHP 4 + unset($cache); + $cache = $new_cache; + } + $this->caches[$method][$type] = $cache; + return $this->caches[$method][$type]; + } + + /** + * Registers a decorator to add to all new cache objects + * @param HTMLPurifier_DefinitionCache_Decorator|string $decorator An instance or the name of a decorator + */ + public function addDecorator($decorator) + { + if (is_string($decorator)) { + $class = "HTMLPurifier_DefinitionCache_Decorator_$decorator"; + $decorator = new $class; + } + $this->decorators[$decorator->name] = $decorator; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Doctype.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Doctype.php new file mode 100644 index 0000000..4acd06e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Doctype.php @@ -0,0 +1,73 @@ +renderDoctype. + * If structure changes, please update that function. + */ +class HTMLPurifier_Doctype +{ + /** + * Full name of doctype + * @type string + */ + public $name; + + /** + * List of standard modules (string identifiers or literal objects) + * that this doctype uses + * @type array + */ + public $modules = array(); + + /** + * List of modules to use for tidying up code + * @type array + */ + public $tidyModules = array(); + + /** + * Is the language derived from XML (i.e. XHTML)? + * @type bool + */ + public $xml = true; + + /** + * List of aliases for this doctype + * @type array + */ + public $aliases = array(); + + /** + * Public DTD identifier + * @type string + */ + public $dtdPublic; + + /** + * System DTD identifier + * @type string + */ + public $dtdSystem; + + public function __construct( + $name = null, + $xml = true, + $modules = array(), + $tidyModules = array(), + $aliases = array(), + $dtd_public = null, + $dtd_system = null + ) { + $this->name = $name; + $this->xml = $xml; + $this->modules = $modules; + $this->tidyModules = $tidyModules; + $this->aliases = $aliases; + $this->dtdPublic = $dtd_public; + $this->dtdSystem = $dtd_system; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DoctypeRegistry.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DoctypeRegistry.php new file mode 100644 index 0000000..acc1d64 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/DoctypeRegistry.php @@ -0,0 +1,142 @@ +doctypes[$doctype->name] = $doctype; + $name = $doctype->name; + // hookup aliases + foreach ($doctype->aliases as $alias) { + if (isset($this->doctypes[$alias])) { + continue; + } + $this->aliases[$alias] = $name; + } + // remove old aliases + if (isset($this->aliases[$name])) { + unset($this->aliases[$name]); + } + return $doctype; + } + + /** + * Retrieves reference to a doctype of a certain name + * @note This function resolves aliases + * @note When possible, use the more fully-featured make() + * @param string $doctype Name of doctype + * @return HTMLPurifier_Doctype Editable doctype object + */ + public function get($doctype) + { + if (isset($this->aliases[$doctype])) { + $doctype = $this->aliases[$doctype]; + } + if (!isset($this->doctypes[$doctype])) { + trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR); + $anon = new HTMLPurifier_Doctype($doctype); + return $anon; + } + return $this->doctypes[$doctype]; + } + + /** + * Creates a doctype based on a configuration object, + * will perform initialization on the doctype + * @note Use this function to get a copy of doctype that config + * can hold on to (this is necessary in order to tell + * Generator whether or not the current document is XML + * based or not). + * @param HTMLPurifier_Config $config + * @return HTMLPurifier_Doctype + */ + public function make($config) + { + return clone $this->get($this->getDoctypeFromConfig($config)); + } + + /** + * Retrieves the doctype from the configuration object + * @param HTMLPurifier_Config $config + * @return string + */ + public function getDoctypeFromConfig($config) + { + // recommended test + $doctype = $config->get('HTML.Doctype'); + if (!empty($doctype)) { + return $doctype; + } + $doctype = $config->get('HTML.CustomDoctype'); + if (!empty($doctype)) { + return $doctype; + } + // backwards-compatibility + if ($config->get('HTML.XHTML')) { + $doctype = 'XHTML 1.0'; + } else { + $doctype = 'HTML 4.01'; + } + if ($config->get('HTML.Strict')) { + $doctype .= ' Strict'; + } else { + $doctype .= ' Transitional'; + } + return $doctype; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ElementDef.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ElementDef.php new file mode 100644 index 0000000..57cfd2b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ElementDef.php @@ -0,0 +1,216 @@ +setup(), this array may also + * contain an array at index 0 that indicates which attribute + * collections to load into the full array. It may also + * contain string indentifiers in lieu of HTMLPurifier_AttrDef, + * see HTMLPurifier_AttrTypes on how they are expanded during + * HTMLPurifier_HTMLDefinition->setup() processing. + */ + public $attr = array(); + + // XXX: Design note: currently, it's not possible to override + // previously defined AttrTransforms without messing around with + // the final generated config. This is by design; a previous version + // used an associated list of attr_transform, but it was extremely + // easy to accidentally override other attribute transforms by + // forgetting to specify an index (and just using 0.) While we + // could check this by checking the index number and complaining, + // there is a second problem which is that it is not at all easy to + // tell when something is getting overridden. Combine this with a + // codebase where this isn't really being used, and it's perfect for + // nuking. + + /** + * List of tags HTMLPurifier_AttrTransform to be done before validation. + * @type array + */ + public $attr_transform_pre = array(); + + /** + * List of tags HTMLPurifier_AttrTransform to be done after validation. + * @type array + */ + public $attr_transform_post = array(); + + /** + * HTMLPurifier_ChildDef of this tag. + * @type HTMLPurifier_ChildDef + */ + public $child; + + /** + * Abstract string representation of internal ChildDef rules. + * @see HTMLPurifier_ContentSets for how this is parsed and then transformed + * into an HTMLPurifier_ChildDef. + * @warning This is a temporary variable that is not available after + * being processed by HTMLDefinition + * @type string + */ + public $content_model; + + /** + * Value of $child->type, used to determine which ChildDef to use, + * used in combination with $content_model. + * @warning This must be lowercase + * @warning This is a temporary variable that is not available after + * being processed by HTMLDefinition + * @type string + */ + public $content_model_type; + + /** + * Does the element have a content model (#PCDATA | Inline)*? This + * is important for chameleon ins and del processing in + * HTMLPurifier_ChildDef_Chameleon. Dynamically set: modules don't + * have to worry about this one. + * @type bool + */ + public $descendants_are_inline = false; + + /** + * List of the names of required attributes this element has. + * Dynamically populated by HTMLPurifier_HTMLDefinition::getElement() + * @type array + */ + public $required_attr = array(); + + /** + * Lookup table of tags excluded from all descendants of this tag. + * @type array + * @note SGML permits exclusions for all descendants, but this is + * not possible with DTDs or XML Schemas. W3C has elected to + * use complicated compositions of content_models to simulate + * exclusion for children, but we go the simpler, SGML-style + * route of flat-out exclusions, which correctly apply to + * all descendants and not just children. Note that the XHTML + * Modularization Abstract Modules are blithely unaware of such + * distinctions. + */ + public $excludes = array(); + + /** + * This tag is explicitly auto-closed by the following tags. + * @type array + */ + public $autoclose = array(); + + /** + * If a foreign element is found in this element, test if it is + * allowed by this sub-element; if it is, instead of closing the + * current element, place it inside this element. + * @type string + */ + public $wrap; + + /** + * Whether or not this is a formatting element affected by the + * "Active Formatting Elements" algorithm. + * @type bool + */ + public $formatting; + + /** + * Low-level factory constructor for creating new standalone element defs + */ + public static function create($content_model, $content_model_type, $attr) + { + $def = new HTMLPurifier_ElementDef(); + $def->content_model = $content_model; + $def->content_model_type = $content_model_type; + $def->attr = $attr; + return $def; + } + + /** + * Merges the values of another element definition into this one. + * Values from the new element def take precedence if a value is + * not mergeable. + * @param HTMLPurifier_ElementDef $def + */ + public function mergeIn($def) + { + // later keys takes precedence + foreach ($def->attr as $k => $v) { + if ($k === 0) { + // merge in the includes + // sorry, no way to override an include + foreach ($v as $v2) { + $this->attr[0][] = $v2; + } + continue; + } + if ($v === false) { + if (isset($this->attr[$k])) { + unset($this->attr[$k]); + } + continue; + } + $this->attr[$k] = $v; + } + $this->_mergeAssocArray($this->excludes, $def->excludes); + $this->attr_transform_pre = array_merge($this->attr_transform_pre, $def->attr_transform_pre); + $this->attr_transform_post = array_merge($this->attr_transform_post, $def->attr_transform_post); + + if (!empty($def->content_model)) { + $this->content_model = + str_replace("#SUPER", (string)$this->content_model, $def->content_model); + $this->child = false; + } + if (!empty($def->content_model_type)) { + $this->content_model_type = $def->content_model_type; + $this->child = false; + } + if (!is_null($def->child)) { + $this->child = $def->child; + } + if (!is_null($def->formatting)) { + $this->formatting = $def->formatting; + } + if ($def->descendants_are_inline) { + $this->descendants_are_inline = $def->descendants_are_inline; + } + } + + /** + * Merges one array into another, removes values which equal false + * @param $a1 Array by reference that is merged into + * @param $a2 Array that merges into $a1 + */ + private function _mergeAssocArray(&$a1, $a2) + { + foreach ($a2 as $k => $v) { + if ($v === false) { + if (isset($a1[$k])) { + unset($a1[$k]); + } + continue; + } + $a1[$k] = $v; + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Encoder.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Encoder.php new file mode 100644 index 0000000..d4791cc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Encoder.php @@ -0,0 +1,617 @@ += $c) { + $r .= self::unsafeIconv($in, $out, substr($text, $i)); + break; + } + // wibble the boundary + if (0x80 != (0xC0 & ord($text[$i + $max_chunk_size]))) { + $chunk_size = $max_chunk_size; + } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 1]))) { + $chunk_size = $max_chunk_size - 1; + } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 2]))) { + $chunk_size = $max_chunk_size - 2; + } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 3]))) { + $chunk_size = $max_chunk_size - 3; + } else { + return false; // rather confusing UTF-8... + } + $chunk = substr($text, $i, $chunk_size); // substr doesn't mind overlong lengths + $r .= self::unsafeIconv($in, $out, $chunk); + $i += $chunk_size; + } + return $r; + } else { + return false; + } + } else { + return false; + } + } + + /** + * Cleans a UTF-8 string for well-formedness and SGML validity + * + * It will parse according to UTF-8 and return a valid UTF8 string, with + * non-SGML codepoints excluded. + * + * Specifically, it will permit: + * \x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF} + * Source: https://www.w3.org/TR/REC-xml/#NT-Char + * Arguably this function should be modernized to the HTML5 set + * of allowed characters: + * https://www.w3.org/TR/html5/syntax.html#preprocessing-the-input-stream + * which simultaneously expand and restrict the set of allowed characters. + * + * @param string $str The string to clean + * @param bool $force_php + * @return string + * + * @note Just for reference, the non-SGML code points are 0 to 31 and + * 127 to 159, inclusive. However, we allow code points 9, 10 + * and 13, which are the tab, line feed and carriage return + * respectively. 128 and above the code points map to multibyte + * UTF-8 representations. + * + * @note Fallback code adapted from utf8ToUnicode by Henri Sivonen and + * hsivonen@iki.fi at under the + * LGPL license. Notes on what changed are inside, but in general, + * the original code transformed UTF-8 text into an array of integer + * Unicode codepoints. Understandably, transforming that back to + * a string would be somewhat expensive, so the function was modded to + * directly operate on the string. However, this discourages code + * reuse, and the logic enumerated here would be useful for any + * function that needs to be able to understand UTF-8 characters. + * As of right now, only smart lossless character encoding converters + * would need that, and I'm probably not going to implement them. + */ + public static function cleanUTF8($str, $force_php = false) + { + // UTF-8 validity is checked since PHP 4.3.5 + // This is an optimization: if the string is already valid UTF-8, no + // need to do PHP stuff. 99% of the time, this will be the case. + if (preg_match( + '/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', + $str + )) { + return $str; + } + + $mState = 0; // cached expected number of octets after the current octet + // until the beginning of the next UTF8 character sequence + $mUcs4 = 0; // cached Unicode character + $mBytes = 1; // cached expected number of octets in the current sequence + + // original code involved an $out that was an array of Unicode + // codepoints. Instead of having to convert back into UTF-8, we've + // decided to directly append valid UTF-8 characters onto a string + // $out once they're done. $char accumulates raw bytes, while $mUcs4 + // turns into the Unicode code point, so there's some redundancy. + + $out = ''; + $char = ''; + + $len = strlen($str); + for ($i = 0; $i < $len; $i++) { + $in = ord($str[$i]); + $char .= $str[$i]; // append byte to char + if (0 == $mState) { + // When mState is zero we expect either a US-ASCII character + // or a multi-octet sequence. + if (0 == (0x80 & ($in))) { + // US-ASCII, pass straight through. + if (($in <= 31 || $in == 127) && + !($in == 9 || $in == 13 || $in == 10) // save \r\t\n + ) { + // control characters, remove + } else { + $out .= $char; + } + // reset + $char = ''; + $mBytes = 1; + } elseif (0xC0 == (0xE0 & ($in))) { + // First octet of 2 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x1F) << 6; + $mState = 1; + $mBytes = 2; + } elseif (0xE0 == (0xF0 & ($in))) { + // First octet of 3 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x0F) << 12; + $mState = 2; + $mBytes = 3; + } elseif (0xF0 == (0xF8 & ($in))) { + // First octet of 4 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x07) << 18; + $mState = 3; + $mBytes = 4; + } elseif (0xF8 == (0xFC & ($in))) { + // First octet of 5 octet sequence. + // + // This is illegal because the encoded codepoint must be + // either: + // (a) not the shortest form or + // (b) outside the Unicode range of 0-0x10FFFF. + // Rather than trying to resynchronize, we will carry on + // until the end of the sequence and let the later error + // handling code catch it. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x03) << 24; + $mState = 4; + $mBytes = 5; + } elseif (0xFC == (0xFE & ($in))) { + // First octet of 6 octet sequence, see comments for 5 + // octet sequence. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 1) << 30; + $mState = 5; + $mBytes = 6; + } else { + // Current octet is neither in the US-ASCII range nor a + // legal first octet of a multi-octet sequence. + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char = ''; + } + } else { + // When mState is non-zero, we expect a continuation of the + // multi-octet sequence + if (0x80 == (0xC0 & ($in))) { + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + + if (0 == --$mState) { + // End of the multi-octet sequence. mUcs4 now contains + // the final Unicode codepoint to be output + + // Check for illegal sequences and codepoints. + + // From Unicode 3.1, non-shortest form is illegal + if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || + ((3 == $mBytes) && ($mUcs4 < 0x0800)) || + ((4 == $mBytes) && ($mUcs4 < 0x10000)) || + (4 < $mBytes) || + // From Unicode 3.2, surrogate characters = illegal + (($mUcs4 & 0xFFFFF800) == 0xD800) || + // Codepoints outside the Unicode range are illegal + ($mUcs4 > 0x10FFFF) + ) { + + } elseif (0xFEFF != $mUcs4 && // omit BOM + // check for valid Char unicode codepoints + ( + 0x9 == $mUcs4 || + 0xA == $mUcs4 || + 0xD == $mUcs4 || + (0x20 <= $mUcs4 && 0x7E >= $mUcs4) || + // 7F-9F is not strictly prohibited by XML, + // but it is non-SGML, and thus we don't allow it + (0xA0 <= $mUcs4 && 0xD7FF >= $mUcs4) || + (0xE000 <= $mUcs4 && 0xFFFD >= $mUcs4) || + (0x10000 <= $mUcs4 && 0x10FFFF >= $mUcs4) + ) + ) { + $out .= $char; + } + // initialize UTF8 cache (reset) + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char = ''; + } + } else { + // ((0xC0 & (*in) != 0x80) && (mState != 0)) + // Incomplete multi-octet sequence. + // used to result in complete fail, but we'll reset + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char =''; + } + } + } + return $out; + } + + /** + * Translates a Unicode codepoint into its corresponding UTF-8 character. + * @note Based on Feyd's function at + * , + * which is in public domain. + * @note While we're going to do code point parsing anyway, a good + * optimization would be to refuse to translate code points that + * are non-SGML characters. However, this could lead to duplication. + * @note This is very similar to the unichr function in + * maintenance/generate-entity-file.php (although this is superior, + * due to its sanity checks). + */ + + // +----------+----------+----------+----------+ + // | 33222222 | 22221111 | 111111 | | + // | 10987654 | 32109876 | 54321098 | 76543210 | bit + // +----------+----------+----------+----------+ + // | | | | 0xxxxxxx | 1 byte 0x00000000..0x0000007F + // | | | 110yyyyy | 10xxxxxx | 2 byte 0x00000080..0x000007FF + // | | 1110zzzz | 10yyyyyy | 10xxxxxx | 3 byte 0x00000800..0x0000FFFF + // | 11110www | 10wwzzzz | 10yyyyyy | 10xxxxxx | 4 byte 0x00010000..0x0010FFFF + // +----------+----------+----------+----------+ + // | 00000000 | 00011111 | 11111111 | 11111111 | Theoretical upper limit of legal scalars: 2097151 (0x001FFFFF) + // | 00000000 | 00010000 | 11111111 | 11111111 | Defined upper limit of legal scalar codes + // +----------+----------+----------+----------+ + + public static function unichr($code) + { + if ($code > 1114111 or $code < 0 or + ($code >= 55296 and $code <= 57343) ) { + // bits are set outside the "valid" range as defined + // by UNICODE 4.1.0 + return ''; + } + + $x = $y = $z = $w = 0; + if ($code < 128) { + // regular ASCII character + $x = $code; + } else { + // set up bits for UTF-8 + $x = ($code & 63) | 128; + if ($code < 2048) { + $y = (($code & 2047) >> 6) | 192; + } else { + $y = (($code & 4032) >> 6) | 128; + if ($code < 65536) { + $z = (($code >> 12) & 15) | 224; + } else { + $z = (($code >> 12) & 63) | 128; + $w = (($code >> 18) & 7) | 240; + } + } + } + // set up the actual character + $ret = ''; + if ($w) { + $ret .= chr($w); + } + if ($z) { + $ret .= chr($z); + } + if ($y) { + $ret .= chr($y); + } + $ret .= chr($x); + + return $ret; + } + + /** + * @return bool + */ + public static function iconvAvailable() + { + static $iconv = null; + if ($iconv === null) { + $iconv = function_exists('iconv') && self::testIconvTruncateBug() != self::ICONV_UNUSABLE; + } + return $iconv; + } + + /** + * Convert a string to UTF-8 based on configuration. + * @param string $str The string to convert + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public static function convertToUTF8($str, $config, $context) + { + $encoding = $config->get('Core.Encoding'); + if ($encoding === 'utf-8') { + return $str; + } + static $iconv = null; + if ($iconv === null) { + $iconv = self::iconvAvailable(); + } + if ($iconv && !$config->get('Test.ForceNoIconv')) { + // unaffected by bugs, since UTF-8 support all characters + $str = self::unsafeIconv($encoding, 'utf-8//IGNORE', $str); + if ($str === false) { + // $encoding is not a valid encoding + trigger_error('Invalid encoding ' . $encoding, E_USER_ERROR); + return ''; + } + // If the string is bjorked by Shift_JIS or a similar encoding + // that doesn't support all of ASCII, convert the naughty + // characters to their true byte-wise ASCII/UTF-8 equivalents. + $str = strtr($str, self::testEncodingSupportsASCII($encoding)); + return $str; + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1'); + return $str; + } + $bug = HTMLPurifier_Encoder::testIconvTruncateBug(); + if ($bug == self::ICONV_OK) { + trigger_error('Encoding not supported, please install iconv', E_USER_ERROR); + } else { + trigger_error( + 'You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 ' . + 'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541', + E_USER_ERROR + ); + } + } + + /** + * Converts a string from UTF-8 based on configuration. + * @param string $str The string to convert + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + * @note Currently, this is a lossy conversion, with unexpressable + * characters being omitted. + */ + public static function convertFromUTF8($str, $config, $context) + { + $encoding = $config->get('Core.Encoding'); + if ($escape = $config->get('Core.EscapeNonASCIICharacters')) { + $str = self::convertToASCIIDumbLossless($str); + } + if ($encoding === 'utf-8') { + return $str; + } + static $iconv = null; + if ($iconv === null) { + $iconv = self::iconvAvailable(); + } + if ($iconv && !$config->get('Test.ForceNoIconv')) { + // Undo our previous fix in convertToUTF8, otherwise iconv will barf + $ascii_fix = self::testEncodingSupportsASCII($encoding); + if (!$escape && !empty($ascii_fix)) { + $clear_fix = array(); + foreach ($ascii_fix as $utf8 => $native) { + $clear_fix[$utf8] = ''; + } + $str = strtr($str, $clear_fix); + } + $str = strtr($str, array_flip($ascii_fix)); + // Normal stuff + $str = self::iconv('utf-8', $encoding . '//IGNORE', $str); + return $str; + } elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) { + $str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8'); + return $str; + } + trigger_error('Encoding not supported', E_USER_ERROR); + // You might be tempted to assume that the ASCII representation + // might be OK, however, this is *not* universally true over all + // encodings. So we take the conservative route here, rather + // than forcibly turn on %Core.EscapeNonASCIICharacters + } + + /** + * Lossless (character-wise) conversion of HTML to ASCII + * @param string $str UTF-8 string to be converted to ASCII + * @return string ASCII encoded string with non-ASCII character entity-ized + * @warning Adapted from MediaWiki, claiming fair use: this is a common + * algorithm. If you disagree with this license fudgery, + * implement it yourself. + * @note Uses decimal numeric entities since they are best supported. + * @note This is a DUMB function: it has no concept of keeping + * character entities that the projected character encoding + * can allow. We could possibly implement a smart version + * but that would require it to also know which Unicode + * codepoints the charset supported (not an easy task). + * @note Sort of with cleanUTF8() but it assumes that $str is + * well-formed UTF-8 + */ + public static function convertToASCIIDumbLossless($str) + { + $bytesleft = 0; + $result = ''; + $working = 0; + $len = strlen($str); + for ($i = 0; $i < $len; $i++) { + $bytevalue = ord($str[$i]); + if ($bytevalue <= 0x7F) { //0xxx xxxx + $result .= chr($bytevalue); + $bytesleft = 0; + } elseif ($bytevalue <= 0xBF) { //10xx xxxx + $working = $working << 6; + $working += ($bytevalue & 0x3F); + $bytesleft--; + if ($bytesleft <= 0) { + $result .= "&#" . $working . ";"; + } + } elseif ($bytevalue <= 0xDF) { //110x xxxx + $working = $bytevalue & 0x1F; + $bytesleft = 1; + } elseif ($bytevalue <= 0xEF) { //1110 xxxx + $working = $bytevalue & 0x0F; + $bytesleft = 2; + } else { //1111 0xxx + $working = $bytevalue & 0x07; + $bytesleft = 3; + } + } + return $result; + } + + /** No bugs detected in iconv. */ + const ICONV_OK = 0; + + /** Iconv truncates output if converting from UTF-8 to another + * character set with //IGNORE, and a non-encodable character is found */ + const ICONV_TRUNCATES = 1; + + /** Iconv does not support //IGNORE, making it unusable for + * transcoding purposes */ + const ICONV_UNUSABLE = 2; + + /** + * glibc iconv has a known bug where it doesn't handle the magic + * //IGNORE stanza correctly. In particular, rather than ignore + * characters, it will return an EILSEQ after consuming some number + * of characters, and expect you to restart iconv as if it were + * an E2BIG. Old versions of PHP did not respect the errno, and + * returned the fragment, so as a result you would see iconv + * mysteriously truncating output. We can work around this by + * manually chopping our input into segments of about 8000 + * characters, as long as PHP ignores the error code. If PHP starts + * paying attention to the error code, iconv becomes unusable. + * + * @return int Error code indicating severity of bug. + */ + public static function testIconvTruncateBug() + { + static $code = null; + if ($code === null) { + // better not use iconv, otherwise infinite loop! + $r = self::unsafeIconv('utf-8', 'ascii//IGNORE', "\xCE\xB1" . str_repeat('a', 9000)); + if ($r === false) { + $code = self::ICONV_UNUSABLE; + } elseif (($c = strlen($r)) < 9000) { + $code = self::ICONV_TRUNCATES; + } elseif ($c > 9000) { + trigger_error( + 'Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: ' . + 'include your iconv version as per phpversion()', + E_USER_ERROR + ); + } else { + $code = self::ICONV_OK; + } + } + return $code; + } + + /** + * This expensive function tests whether or not a given character + * encoding supports ASCII. 7/8-bit encodings like Shift_JIS will + * fail this test, and require special processing. Variable width + * encodings shouldn't ever fail. + * + * @param string $encoding Encoding name to test, as per iconv format + * @param bool $bypass Whether or not to bypass the precompiled arrays. + * @return Array of UTF-8 characters to their corresponding ASCII, + * which can be used to "undo" any overzealous iconv action. + */ + public static function testEncodingSupportsASCII($encoding, $bypass = false) + { + // All calls to iconv here are unsafe, proof by case analysis: + // If ICONV_OK, no difference. + // If ICONV_TRUNCATE, all calls involve one character inputs, + // so bug is not triggered. + // If ICONV_UNUSABLE, this call is irrelevant + static $encodings = array(); + if (!$bypass) { + if (isset($encodings[$encoding])) { + return $encodings[$encoding]; + } + $lenc = strtolower($encoding); + switch ($lenc) { + case 'shift_jis': + return array("\xC2\xA5" => '\\', "\xE2\x80\xBE" => '~'); + case 'johab': + return array("\xE2\x82\xA9" => '\\'); + } + if (strpos($lenc, 'iso-8859-') === 0) { + return array(); + } + } + $ret = array(); + if (self::unsafeIconv('UTF-8', $encoding, 'a') === false) { + return false; + } + for ($i = 0x20; $i <= 0x7E; $i++) { // all printable ASCII chars + $c = chr($i); // UTF-8 char + $r = self::unsafeIconv('UTF-8', "$encoding//IGNORE", $c); // initial conversion + if ($r === '' || + // This line is needed for iconv implementations that do not + // omit characters that do not exist in the target character set + ($r === $c && self::unsafeIconv($encoding, 'UTF-8//IGNORE', $r) !== $c) + ) { + // Reverse engineer: what's the UTF-8 equiv of this byte + // sequence? This assumes that there's no variable width + // encoding that doesn't support ASCII. + $ret[self::unsafeIconv($encoding, 'UTF-8//IGNORE', $c)] = $c; + } + } + $encodings[$encoding] = $ret; + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityLookup.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityLookup.php new file mode 100644 index 0000000..f12ff13 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityLookup.php @@ -0,0 +1,48 @@ +table = unserialize(file_get_contents($file)); + } + + /** + * Retrieves sole instance of the object. + * @param bool|HTMLPurifier_EntityLookup $prototype Optional prototype of custom lookup table to overload with. + * @return HTMLPurifier_EntityLookup + */ + public static function instance($prototype = false) + { + // no references, since PHP doesn't copy unless modified + static $instance = null; + if ($prototype) { + $instance = $prototype; + } elseif (!$instance) { + $instance = new HTMLPurifier_EntityLookup(); + $instance->setup(); + } + return $instance; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityLookup/entities.ser b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityLookup/entities.ser new file mode 100644 index 0000000..e8b0812 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityLookup/entities.ser @@ -0,0 +1 @@ +a:253:{s:4:"fnof";s:2:"Æ’";s:5:"Alpha";s:2:"Α";s:4:"Beta";s:2:"Î’";s:5:"Gamma";s:2:"Γ";s:5:"Delta";s:2:"Δ";s:7:"Epsilon";s:2:"Ε";s:4:"Zeta";s:2:"Ζ";s:3:"Eta";s:2:"Η";s:5:"Theta";s:2:"Θ";s:4:"Iota";s:2:"Ι";s:5:"Kappa";s:2:"Κ";s:6:"Lambda";s:2:"Λ";s:2:"Mu";s:2:"Μ";s:2:"Nu";s:2:"Î";s:2:"Xi";s:2:"Ξ";s:7:"Omicron";s:2:"Ο";s:2:"Pi";s:2:"Π";s:3:"Rho";s:2:"Ρ";s:5:"Sigma";s:2:"Σ";s:3:"Tau";s:2:"Τ";s:7:"Upsilon";s:2:"Î¥";s:3:"Phi";s:2:"Φ";s:3:"Chi";s:2:"Χ";s:3:"Psi";s:2:"Ψ";s:5:"Omega";s:2:"Ω";s:5:"alpha";s:2:"α";s:4:"beta";s:2:"β";s:5:"gamma";s:2:"γ";s:5:"delta";s:2:"δ";s:7:"epsilon";s:2:"ε";s:4:"zeta";s:2:"ζ";s:3:"eta";s:2:"η";s:5:"theta";s:2:"θ";s:4:"iota";s:2:"ι";s:5:"kappa";s:2:"κ";s:6:"lambda";s:2:"λ";s:2:"mu";s:2:"μ";s:2:"nu";s:2:"ν";s:2:"xi";s:2:"ξ";s:7:"omicron";s:2:"ο";s:2:"pi";s:2:"Ï€";s:3:"rho";s:2:"Ï";s:6:"sigmaf";s:2:"Ï‚";s:5:"sigma";s:2:"σ";s:3:"tau";s:2:"Ï„";s:7:"upsilon";s:2:"Ï…";s:3:"phi";s:2:"φ";s:3:"chi";s:2:"χ";s:3:"psi";s:2:"ψ";s:5:"omega";s:2:"ω";s:8:"thetasym";s:2:"Ï‘";s:5:"upsih";s:2:"Ï’";s:3:"piv";s:2:"Ï–";s:4:"bull";s:3:"•";s:6:"hellip";s:3:"…";s:5:"prime";s:3:"′";s:5:"Prime";s:3:"″";s:5:"oline";s:3:"‾";s:5:"frasl";s:3:"â„";s:6:"weierp";s:3:"℘";s:5:"image";s:3:"â„‘";s:4:"real";s:3:"ℜ";s:5:"trade";s:3:"â„¢";s:7:"alefsym";s:3:"ℵ";s:4:"larr";s:3:"â†";s:4:"uarr";s:3:"↑";s:4:"rarr";s:3:"→";s:4:"darr";s:3:"↓";s:4:"harr";s:3:"↔";s:5:"crarr";s:3:"↵";s:4:"lArr";s:3:"â‡";s:4:"uArr";s:3:"⇑";s:4:"rArr";s:3:"⇒";s:4:"dArr";s:3:"⇓";s:4:"hArr";s:3:"⇔";s:6:"forall";s:3:"∀";s:4:"part";s:3:"∂";s:5:"exist";s:3:"∃";s:5:"empty";s:3:"∅";s:5:"nabla";s:3:"∇";s:4:"isin";s:3:"∈";s:5:"notin";s:3:"∉";s:2:"ni";s:3:"∋";s:4:"prod";s:3:"âˆ";s:3:"sum";s:3:"∑";s:5:"minus";s:3:"−";s:6:"lowast";s:3:"∗";s:5:"radic";s:3:"√";s:4:"prop";s:3:"âˆ";s:5:"infin";s:3:"∞";s:3:"ang";s:3:"∠";s:3:"and";s:3:"∧";s:2:"or";s:3:"∨";s:3:"cap";s:3:"∩";s:3:"cup";s:3:"∪";s:3:"int";s:3:"∫";s:6:"there4";s:3:"∴";s:3:"sim";s:3:"∼";s:4:"cong";s:3:"≅";s:5:"asymp";s:3:"≈";s:2:"ne";s:3:"≠";s:5:"equiv";s:3:"≡";s:2:"le";s:3:"≤";s:2:"ge";s:3:"≥";s:3:"sub";s:3:"⊂";s:3:"sup";s:3:"⊃";s:4:"nsub";s:3:"⊄";s:4:"sube";s:3:"⊆";s:4:"supe";s:3:"⊇";s:5:"oplus";s:3:"⊕";s:6:"otimes";s:3:"⊗";s:4:"perp";s:3:"⊥";s:4:"sdot";s:3:"â‹…";s:5:"lceil";s:3:"⌈";s:5:"rceil";s:3:"⌉";s:6:"lfloor";s:3:"⌊";s:6:"rfloor";s:3:"⌋";s:4:"lang";s:3:"〈";s:4:"rang";s:3:"〉";s:3:"loz";s:3:"â—Š";s:6:"spades";s:3:"â™ ";s:5:"clubs";s:3:"♣";s:6:"hearts";s:3:"♥";s:5:"diams";s:3:"♦";s:4:"quot";s:1:""";s:3:"amp";s:1:"&";s:2:"lt";s:1:"<";s:2:"gt";s:1:">";s:4:"apos";s:1:"'";s:5:"OElig";s:2:"Å’";s:5:"oelig";s:2:"Å“";s:6:"Scaron";s:2:"Å ";s:6:"scaron";s:2:"Å¡";s:4:"Yuml";s:2:"Ÿ";s:4:"circ";s:2:"ˆ";s:5:"tilde";s:2:"Ëœ";s:4:"ensp";s:3:" ";s:4:"emsp";s:3:" ";s:6:"thinsp";s:3:" ";s:4:"zwnj";s:3:"‌";s:3:"zwj";s:3:"â€";s:3:"lrm";s:3:"‎";s:3:"rlm";s:3:"â€";s:5:"ndash";s:3:"–";s:5:"mdash";s:3:"—";s:5:"lsquo";s:3:"‘";s:5:"rsquo";s:3:"’";s:5:"sbquo";s:3:"‚";s:5:"ldquo";s:3:"“";s:5:"rdquo";s:3:"â€";s:5:"bdquo";s:3:"„";s:6:"dagger";s:3:"†";s:6:"Dagger";s:3:"‡";s:6:"permil";s:3:"‰";s:6:"lsaquo";s:3:"‹";s:6:"rsaquo";s:3:"›";s:4:"euro";s:3:"€";s:4:"nbsp";s:2:" ";s:5:"iexcl";s:2:"¡";s:4:"cent";s:2:"¢";s:5:"pound";s:2:"£";s:6:"curren";s:2:"¤";s:3:"yen";s:2:"Â¥";s:6:"brvbar";s:2:"¦";s:4:"sect";s:2:"§";s:3:"uml";s:2:"¨";s:4:"copy";s:2:"©";s:4:"ordf";s:2:"ª";s:5:"laquo";s:2:"«";s:3:"not";s:2:"¬";s:3:"shy";s:2:"­";s:3:"reg";s:2:"®";s:4:"macr";s:2:"¯";s:3:"deg";s:2:"°";s:6:"plusmn";s:2:"±";s:4:"sup2";s:2:"²";s:4:"sup3";s:2:"³";s:5:"acute";s:2:"´";s:5:"micro";s:2:"µ";s:4:"para";s:2:"¶";s:6:"middot";s:2:"·";s:5:"cedil";s:2:"¸";s:4:"sup1";s:2:"¹";s:4:"ordm";s:2:"º";s:5:"raquo";s:2:"»";s:6:"frac14";s:2:"¼";s:6:"frac12";s:2:"½";s:6:"frac34";s:2:"¾";s:6:"iquest";s:2:"¿";s:6:"Agrave";s:2:"À";s:6:"Aacute";s:2:"Ã";s:5:"Acirc";s:2:"Â";s:6:"Atilde";s:2:"Ã";s:4:"Auml";s:2:"Ä";s:5:"Aring";s:2:"Ã…";s:5:"AElig";s:2:"Æ";s:6:"Ccedil";s:2:"Ç";s:6:"Egrave";s:2:"È";s:6:"Eacute";s:2:"É";s:5:"Ecirc";s:2:"Ê";s:4:"Euml";s:2:"Ë";s:6:"Igrave";s:2:"ÃŒ";s:6:"Iacute";s:2:"Ã";s:5:"Icirc";s:2:"ÃŽ";s:4:"Iuml";s:2:"Ã";s:3:"ETH";s:2:"Ã";s:6:"Ntilde";s:2:"Ñ";s:6:"Ograve";s:2:"Ã’";s:6:"Oacute";s:2:"Ó";s:5:"Ocirc";s:2:"Ô";s:6:"Otilde";s:2:"Õ";s:4:"Ouml";s:2:"Ö";s:5:"times";s:2:"×";s:6:"Oslash";s:2:"Ø";s:6:"Ugrave";s:2:"Ù";s:6:"Uacute";s:2:"Ú";s:5:"Ucirc";s:2:"Û";s:4:"Uuml";s:2:"Ü";s:6:"Yacute";s:2:"Ã";s:5:"THORN";s:2:"Þ";s:5:"szlig";s:2:"ß";s:6:"agrave";s:2:"à";s:6:"aacute";s:2:"á";s:5:"acirc";s:2:"â";s:6:"atilde";s:2:"ã";s:4:"auml";s:2:"ä";s:5:"aring";s:2:"Ã¥";s:5:"aelig";s:2:"æ";s:6:"ccedil";s:2:"ç";s:6:"egrave";s:2:"è";s:6:"eacute";s:2:"é";s:5:"ecirc";s:2:"ê";s:4:"euml";s:2:"ë";s:6:"igrave";s:2:"ì";s:6:"iacute";s:2:"í";s:5:"icirc";s:2:"î";s:4:"iuml";s:2:"ï";s:3:"eth";s:2:"ð";s:6:"ntilde";s:2:"ñ";s:6:"ograve";s:2:"ò";s:6:"oacute";s:2:"ó";s:5:"ocirc";s:2:"ô";s:6:"otilde";s:2:"õ";s:4:"ouml";s:2:"ö";s:6:"divide";s:2:"÷";s:6:"oslash";s:2:"ø";s:6:"ugrave";s:2:"ù";s:6:"uacute";s:2:"ú";s:5:"ucirc";s:2:"û";s:4:"uuml";s:2:"ü";s:6:"yacute";s:2:"ý";s:5:"thorn";s:2:"þ";s:4:"yuml";s:2:"ÿ";} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityParser.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityParser.php new file mode 100644 index 0000000..0f2b83d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/EntityParser.php @@ -0,0 +1,285 @@ +_semiOptionalPrefixRegex = "/&()()()($semi_optional)/"; + + $this->_textEntitiesRegex = + '/&(?:'. + // hex + '[#]x([a-fA-F0-9]+);?|'. + // dec + '[#]0*(\d+);?|'. + // string (mandatory semicolon) + // NB: order matters: match semicolon preferentially + '([A-Za-z_:][A-Za-z0-9.\-_:]*);|'. + // string (optional semicolon) + "($semi_optional)". + ')/'; + + $this->_attrEntitiesRegex = + '/&(?:'. + // hex + '[#]x([a-fA-F0-9]+);?|'. + // dec + '[#]0*(\d+);?|'. + // string (mandatory semicolon) + // NB: order matters: match semicolon preferentially + '([A-Za-z_:][A-Za-z0-9.\-_:]*);|'. + // string (optional semicolon) + // don't match if trailing is equals or alphanumeric (URL + // like) + "($semi_optional)(?![=;A-Za-z0-9])". + ')/'; + + } + + /** + * Substitute entities with the parsed equivalents. Use this on + * textual data in an HTML document (as opposed to attributes.) + * + * @param string $string String to have entities parsed. + * @return string Parsed string. + */ + public function substituteTextEntities($string) + { + return preg_replace_callback( + $this->_textEntitiesRegex, + array($this, 'entityCallback'), + $string + ); + } + + /** + * Substitute entities with the parsed equivalents. Use this on + * attribute contents in documents. + * + * @param string $string String to have entities parsed. + * @return string Parsed string. + */ + public function substituteAttrEntities($string) + { + return preg_replace_callback( + $this->_attrEntitiesRegex, + array($this, 'entityCallback'), + $string + ); + } + + /** + * Callback function for substituteNonSpecialEntities() that does the work. + * + * @param array $matches PCRE matches array, with 0 the entire match, and + * either index 1, 2 or 3 set with a hex value, dec value, + * or string (respectively). + * @return string Replacement string. + */ + + protected function entityCallback($matches) + { + $entity = $matches[0]; + $hex_part = isset($matches[1]) ? $matches[1] : null; + $dec_part = isset($matches[2]) ? $matches[2] : null; + $named_part = empty($matches[3]) ? (empty($matches[4]) ? "" : $matches[4]) : $matches[3]; + if ($hex_part !== NULL && $hex_part !== "") { + return HTMLPurifier_Encoder::unichr(hexdec($hex_part)); + } elseif ($dec_part !== NULL && $dec_part !== "") { + return HTMLPurifier_Encoder::unichr((int) $dec_part); + } else { + if (!$this->_entity_lookup) { + $this->_entity_lookup = HTMLPurifier_EntityLookup::instance(); + } + if (isset($this->_entity_lookup->table[$named_part])) { + return $this->_entity_lookup->table[$named_part]; + } else { + // exact match didn't match anything, so test if + // any of the semicolon optional match the prefix. + // Test that this is an EXACT match is important to + // prevent infinite loop + if (!empty($matches[3])) { + return preg_replace_callback( + $this->_semiOptionalPrefixRegex, + array($this, 'entityCallback'), + $entity + ); + } + return $entity; + } + } + } + + // LEGACY CODE BELOW + + /** + * Callback regex string for parsing entities. + * @type string + */ + protected $_substituteEntitiesRegex = + '/&(?:[#]x([a-fA-F0-9]+)|[#]0*(\d+)|([A-Za-z_:][A-Za-z0-9.\-_:]*));?/'; + // 1. hex 2. dec 3. string (XML style) + + /** + * Decimal to parsed string conversion table for special entities. + * @type array + */ + protected $_special_dec2str = + array( + 34 => '"', + 38 => '&', + 39 => "'", + 60 => '<', + 62 => '>' + ); + + /** + * Stripped entity names to decimal conversion table for special entities. + * @type array + */ + protected $_special_ent2dec = + array( + 'quot' => 34, + 'amp' => 38, + 'lt' => 60, + 'gt' => 62 + ); + + /** + * Substitutes non-special entities with their parsed equivalents. Since + * running this whenever you have parsed character is t3h 5uck, we run + * it before everything else. + * + * @param string $string String to have non-special entities parsed. + * @return string Parsed string. + */ + public function substituteNonSpecialEntities($string) + { + // it will try to detect missing semicolons, but don't rely on it + return preg_replace_callback( + $this->_substituteEntitiesRegex, + array($this, 'nonSpecialEntityCallback'), + $string + ); + } + + /** + * Callback function for substituteNonSpecialEntities() that does the work. + * + * @param array $matches PCRE matches array, with 0 the entire match, and + * either index 1, 2 or 3 set with a hex value, dec value, + * or string (respectively). + * @return string Replacement string. + */ + + protected function nonSpecialEntityCallback($matches) + { + // replaces all but big five + $entity = $matches[0]; + $is_num = (@$matches[0][1] === '#'); + if ($is_num) { + $is_hex = (@$entity[2] === 'x'); + $code = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; + // abort for special characters + if (isset($this->_special_dec2str[$code])) { + return $entity; + } + return HTMLPurifier_Encoder::unichr($code); + } else { + if (isset($this->_special_ent2dec[$matches[3]])) { + return $entity; + } + if (!$this->_entity_lookup) { + $this->_entity_lookup = HTMLPurifier_EntityLookup::instance(); + } + if (isset($this->_entity_lookup->table[$matches[3]])) { + return $this->_entity_lookup->table[$matches[3]]; + } else { + return $entity; + } + } + } + + /** + * Substitutes only special entities with their parsed equivalents. + * + * @notice We try to avoid calling this function because otherwise, it + * would have to be called a lot (for every parsed section). + * + * @param string $string String to have non-special entities parsed. + * @return string Parsed string. + */ + public function substituteSpecialEntities($string) + { + return preg_replace_callback( + $this->_substituteEntitiesRegex, + array($this, 'specialEntityCallback'), + $string + ); + } + + /** + * Callback function for substituteSpecialEntities() that does the work. + * + * This callback has same syntax as nonSpecialEntityCallback(). + * + * @param array $matches PCRE-style matches array, with 0 the entire match, and + * either index 1, 2 or 3 set with a hex value, dec value, + * or string (respectively). + * @return string Replacement string. + */ + protected function specialEntityCallback($matches) + { + $entity = $matches[0]; + $is_num = (@$matches[0][1] === '#'); + if ($is_num) { + $is_hex = (@$entity[2] === 'x'); + $int = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; + return isset($this->_special_dec2str[$int]) ? + $this->_special_dec2str[$int] : + $entity; + } else { + return isset($this->_special_ent2dec[$matches[3]]) ? + $this->_special_dec2str[$this->_special_ent2dec[$matches[3]]] : + $entity; + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ErrorCollector.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ErrorCollector.php new file mode 100644 index 0000000..d47e3f2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ErrorCollector.php @@ -0,0 +1,244 @@ +locale =& $context->get('Locale'); + $this->context = $context; + $this->_current =& $this->_stacks[0]; + $this->errors =& $this->_stacks[0]; + } + + /** + * Sends an error message to the collector for later use + * @param int $severity Error severity, PHP error style (don't use E_USER_) + * @param string $msg Error message text + */ + public function send($severity, $msg) + { + $args = array(); + if (func_num_args() > 2) { + $args = func_get_args(); + array_shift($args); + unset($args[0]); + } + + $token = $this->context->get('CurrentToken', true); + $line = $token ? $token->line : $this->context->get('CurrentLine', true); + $col = $token ? $token->col : $this->context->get('CurrentCol', true); + $attr = $this->context->get('CurrentAttr', true); + + // perform special substitutions, also add custom parameters + $subst = array(); + if (!is_null($token)) { + $args['CurrentToken'] = $token; + } + if (!is_null($attr)) { + $subst['$CurrentAttr.Name'] = $attr; + if (isset($token->attr[$attr])) { + $subst['$CurrentAttr.Value'] = $token->attr[$attr]; + } + } + + if (empty($args)) { + $msg = $this->locale->getMessage($msg); + } else { + $msg = $this->locale->formatMessage($msg, $args); + } + + if (!empty($subst)) { + $msg = strtr($msg, $subst); + } + + // (numerically indexed) + $error = array( + self::LINENO => $line, + self::SEVERITY => $severity, + self::MESSAGE => $msg, + self::CHILDREN => array() + ); + $this->_current[] = $error; + + // NEW CODE BELOW ... + // Top-level errors are either: + // TOKEN type, if $value is set appropriately, or + // "syntax" type, if $value is null + $new_struct = new HTMLPurifier_ErrorStruct(); + $new_struct->type = HTMLPurifier_ErrorStruct::TOKEN; + if ($token) { + $new_struct->value = clone $token; + } + if (is_int($line) && is_int($col)) { + if (isset($this->lines[$line][$col])) { + $struct = $this->lines[$line][$col]; + } else { + $struct = $this->lines[$line][$col] = $new_struct; + } + // These ksorts may present a performance problem + ksort($this->lines[$line], SORT_NUMERIC); + } else { + if (isset($this->lines[-1])) { + $struct = $this->lines[-1]; + } else { + $struct = $this->lines[-1] = $new_struct; + } + } + ksort($this->lines, SORT_NUMERIC); + + // Now, check if we need to operate on a lower structure + if (!empty($attr)) { + $struct = $struct->getChild(HTMLPurifier_ErrorStruct::ATTR, $attr); + if (!$struct->value) { + $struct->value = array($attr, 'PUT VALUE HERE'); + } + } + if (!empty($cssprop)) { + $struct = $struct->getChild(HTMLPurifier_ErrorStruct::CSSPROP, $cssprop); + if (!$struct->value) { + // if we tokenize CSS this might be a little more difficult to do + $struct->value = array($cssprop, 'PUT VALUE HERE'); + } + } + + // Ok, structs are all setup, now time to register the error + $struct->addError($severity, $msg); + } + + /** + * Retrieves raw error data for custom formatter to use + */ + public function getRaw() + { + return $this->errors; + } + + /** + * Default HTML formatting implementation for error messages + * @param HTMLPurifier_Config $config Configuration, vital for HTML output nature + * @param array $errors Errors array to display; used for recursion. + * @return string + */ + public function getHTMLFormatted($config, $errors = null) + { + $ret = array(); + + $this->generator = new HTMLPurifier_Generator($config, $this->context); + if ($errors === null) { + $errors = $this->errors; + } + + // 'At line' message needs to be removed + + // generation code for new structure goes here. It needs to be recursive. + foreach ($this->lines as $line => $col_array) { + if ($line == -1) { + continue; + } + foreach ($col_array as $col => $struct) { + $this->_renderStruct($ret, $struct, $line, $col); + } + } + if (isset($this->lines[-1])) { + $this->_renderStruct($ret, $this->lines[-1]); + } + + if (empty($errors)) { + return '

        ' . $this->locale->getMessage('ErrorCollector: No errors') . '

        '; + } else { + return '
        • ' . implode('
        • ', $ret) . '
        '; + } + + } + + private function _renderStruct(&$ret, $struct, $line = null, $col = null) + { + $stack = array($struct); + $context_stack = array(array()); + while ($current = array_pop($stack)) { + $context = array_pop($context_stack); + foreach ($current->errors as $error) { + list($severity, $msg) = $error; + $string = ''; + $string .= '
        '; + // W3C uses an icon to indicate the severity of the error. + $error = $this->locale->getErrorName($severity); + $string .= "$error "; + if (!is_null($line) && !is_null($col)) { + $string .= "Line $line, Column $col: "; + } else { + $string .= 'End of Document: '; + } + $string .= '' . $this->generator->escape($msg) . ' '; + $string .= '
        '; + // Here, have a marker for the character on the column appropriate. + // Be sure to clip extremely long lines. + //$string .= '
        ';
        +                //$string .= '';
        +                //$string .= '
        '; + $ret[] = $string; + } + foreach ($current->children as $array) { + $context[] = $current; + $stack = array_merge($stack, array_reverse($array, true)); + for ($i = count($array); $i > 0; $i--) { + $context_stack[] = $context; + } + } + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ErrorStruct.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ErrorStruct.php new file mode 100644 index 0000000..cf869d3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/ErrorStruct.php @@ -0,0 +1,74 @@ +children[$type][$id])) { + $this->children[$type][$id] = new HTMLPurifier_ErrorStruct(); + $this->children[$type][$id]->type = $type; + } + return $this->children[$type][$id]; + } + + /** + * @param int $severity + * @param string $message + */ + public function addError($severity, $message) + { + $this->errors[] = array($severity, $message); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Exception.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Exception.php new file mode 100644 index 0000000..be85b4c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Exception.php @@ -0,0 +1,12 @@ +preFilter, + * 2->preFilter, 3->preFilter, purify, 3->postFilter, 2->postFilter, + * 1->postFilter. + * + * @note Methods are not declared abstract as it is perfectly legitimate + * for an implementation not to want anything to happen on a step + */ + +class HTMLPurifier_Filter +{ + + /** + * Name of the filter for identification purposes. + * @type string + */ + public $name; + + /** + * Pre-processor function, handles HTML before HTML Purifier + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function preFilter($html, $config, $context) + { + return $html; + } + + /** + * Post-processor function, handles HTML after HTML Purifier + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function postFilter($html, $config, $context) + { + return $html; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Filter/ExtractStyleBlocks.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Filter/ExtractStyleBlocks.php new file mode 100644 index 0000000..e7e3cac --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Filter/ExtractStyleBlocks.php @@ -0,0 +1,362 @@ + blocks from input HTML, cleans them up + * using CSSTidy, and then places them in $purifier->context->get('StyleBlocks') + * so they can be used elsewhere in the document. + * + * @note + * See tests/HTMLPurifier/Filter/ExtractStyleBlocksTest.php for + * sample usage. + * + * @note + * This filter can also be used on stylesheets not included in the + * document--something purists would probably prefer. Just directly + * call HTMLPurifier_Filter_ExtractStyleBlocks->cleanCSS() + */ +class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter +{ + /** + * @type string + */ + public $name = 'ExtractStyleBlocks'; + + /** + * @type array + */ + private $_styleMatches = array(); + + /** + * @type csstidy + */ + private $_tidy; + + /** + * @type HTMLPurifier_AttrDef_HTML_ID + */ + private $_id_attrdef; + + /** + * @type HTMLPurifier_AttrDef_CSS_Ident + */ + private $_class_attrdef; + + /** + * @type HTMLPurifier_AttrDef_Enum + */ + private $_enum_attrdef; + + /** + * @type HTMLPurifier_AttrDef_Enum + */ + private $_universal_attrdef; + + public function __construct() + { + $this->_tidy = new csstidy(); + $this->_tidy->set_cfg('lowercase_s', false); + $this->_id_attrdef = new HTMLPurifier_AttrDef_HTML_ID(true); + $this->_class_attrdef = new HTMLPurifier_AttrDef_CSS_Ident(); + $this->_enum_attrdef = new HTMLPurifier_AttrDef_Enum( + array( + 'first-child', + 'link', + 'visited', + 'active', + 'hover', + 'focus' + ) + ); + $this->_universal_attrdef = new HTMLPurifier_AttrDef_Enum( + array( + 'initial', + 'inherit', + 'unset', + ) + ); + } + + /** + * Save the contents of CSS blocks to style matches + * @param array $matches preg_replace style $matches array + */ + protected function styleCallback($matches) + { + $this->_styleMatches[] = $matches[1]; + } + + /** + * Removes inline + // we must not grab foo in a font-family prop). + if ($config->get('Filter.ExtractStyleBlocks.Escaping')) { + $css = str_replace( + array('<', '>', '&'), + array('\3C ', '\3E ', '\26 '), + $css + ); + } + return $css; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Filter/YouTube.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Filter/YouTube.php new file mode 100644 index 0000000..276d836 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Filter/YouTube.php @@ -0,0 +1,65 @@ +]+>.+?' . + '(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?#s'; + $pre_replace = '\1'; + return preg_replace($pre_regex, $pre_replace, $html); + } + + /** + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function postFilter($html, $config, $context) + { + $post_regex = '#((?:v|cp)/[A-Za-z0-9\-_=]+)#'; + return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html); + } + + /** + * @param $url + * @return string + */ + protected function armorUrl($url) + { + return str_replace('--', '--', $url); + } + + /** + * @param array $matches + * @return string + */ + protected function postFilterCallback($matches) + { + $url = $this->armorUrl($matches[1]); + return '' . + '' . + '' . + ''; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Generator.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Generator.php new file mode 100644 index 0000000..eb56e2d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Generator.php @@ -0,0 +1,286 @@ + tags. + * @type bool + */ + private $_scriptFix = false; + + /** + * Cache of HTMLDefinition during HTML output to determine whether or + * not attributes should be minimized. + * @type HTMLPurifier_HTMLDefinition + */ + private $_def; + + /** + * Cache of %Output.SortAttr. + * @type bool + */ + private $_sortAttr; + + /** + * Cache of %Output.FlashCompat. + * @type bool + */ + private $_flashCompat; + + /** + * Cache of %Output.FixInnerHTML. + * @type bool + */ + private $_innerHTMLFix; + + /** + * Stack for keeping track of object information when outputting IE + * compatibility code. + * @type array + */ + private $_flashStack = array(); + + /** + * Configuration for the generator + * @type HTMLPurifier_Config + */ + protected $config; + + /** + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + */ + public function __construct($config, $context) + { + $this->config = $config; + $this->_scriptFix = $config->get('Output.CommentScriptContents'); + $this->_innerHTMLFix = $config->get('Output.FixInnerHTML'); + $this->_sortAttr = $config->get('Output.SortAttr'); + $this->_flashCompat = $config->get('Output.FlashCompat'); + $this->_def = $config->getHTMLDefinition(); + $this->_xhtml = $this->_def->doctype->xml; + } + + /** + * Generates HTML from an array of tokens. + * @param HTMLPurifier_Token[] $tokens Array of HTMLPurifier_Token + * @return string Generated HTML + */ + public function generateFromTokens($tokens) + { + if (!$tokens) { + return ''; + } + + // Basic algorithm + $html = ''; + for ($i = 0, $size = count($tokens); $i < $size; $i++) { + if ($this->_scriptFix && $tokens[$i]->name === 'script' + && $i + 2 < $size && $tokens[$i+2] instanceof HTMLPurifier_Token_End) { + // script special case + // the contents of the script block must be ONE token + // for this to work. + $html .= $this->generateFromToken($tokens[$i++]); + $html .= $this->generateScriptFromToken($tokens[$i++]); + } + $html .= $this->generateFromToken($tokens[$i]); + } + + // Tidy cleanup + if (extension_loaded('tidy') && $this->config->get('Output.TidyFormat')) { + $tidy = new Tidy; + $tidy->parseString( + $html, + array( + 'indent'=> true, + 'output-xhtml' => $this->_xhtml, + 'show-body-only' => true, + 'indent-spaces' => 2, + 'wrap' => 68, + ), + 'utf8' + ); + $tidy->cleanRepair(); + $html = (string) $tidy; // explicit cast necessary + } + + // Normalize newlines to system defined value + if ($this->config->get('Core.NormalizeNewlines')) { + $nl = $this->config->get('Output.Newline'); + if ($nl === null) { + $nl = PHP_EOL; + } + if ($nl !== "\n") { + $html = str_replace("\n", $nl, $html); + } + } + return $html; + } + + /** + * Generates HTML from a single token. + * @param HTMLPurifier_Token $token HTMLPurifier_Token object. + * @return string Generated HTML + */ + public function generateFromToken($token) + { + if (!$token instanceof HTMLPurifier_Token) { + trigger_error('Cannot generate HTML from non-HTMLPurifier_Token object', E_USER_WARNING); + return ''; + + } elseif ($token instanceof HTMLPurifier_Token_Start) { + $attr = $this->generateAttributes($token->attr, $token->name); + if ($this->_flashCompat) { + if ($token->name == "object") { + $flash = new stdClass(); + $flash->attr = $token->attr; + $flash->param = array(); + $this->_flashStack[] = $flash; + } + } + return '<' . $token->name . ($attr ? ' ' : '') . $attr . '>'; + + } elseif ($token instanceof HTMLPurifier_Token_End) { + $_extra = ''; + if ($this->_flashCompat) { + if ($token->name == "object" && !empty($this->_flashStack)) { + // doesn't do anything for now + } + } + return $_extra . 'name . '>'; + + } elseif ($token instanceof HTMLPurifier_Token_Empty) { + if ($this->_flashCompat && $token->name == "param" && !empty($this->_flashStack)) { + $this->_flashStack[count($this->_flashStack)-1]->param[$token->attr['name']] = $token->attr['value']; + } + $attr = $this->generateAttributes($token->attr, $token->name); + return '<' . $token->name . ($attr ? ' ' : '') . $attr . + ( $this->_xhtml ? ' /': '' ) //
        v.
        + . '>'; + + } elseif ($token instanceof HTMLPurifier_Token_Text) { + return $this->escape($token->data, ENT_NOQUOTES); + + } elseif ($token instanceof HTMLPurifier_Token_Comment) { + return ''; + } else { + return ''; + + } + } + + /** + * Special case processor for the contents of script tags + * @param HTMLPurifier_Token $token HTMLPurifier_Token object. + * @return string + * @warning This runs into problems if there's already a literal + * --> somewhere inside the script contents. + */ + public function generateScriptFromToken($token) + { + if (!$token instanceof HTMLPurifier_Token_Text) { + return $this->generateFromToken($token); + } + // Thanks + $data = preg_replace('#//\s*$#', '', $token->data); + return ''; + } + + /** + * Generates attribute declarations from attribute array. + * @note This does not include the leading or trailing space. + * @param array $assoc_array_of_attributes Attribute array + * @param string $element Name of element attributes are for, used to check + * attribute minimization. + * @return string Generated HTML fragment for insertion. + */ + public function generateAttributes($assoc_array_of_attributes, $element = '') + { + $html = ''; + if ($this->_sortAttr) { + ksort($assoc_array_of_attributes); + } + foreach ($assoc_array_of_attributes as $key => $value) { + if (!$this->_xhtml) { + // Remove namespaced attributes + if (strpos($key, ':') !== false) { + continue; + } + // Check if we should minimize the attribute: val="val" -> val + if ($element && !empty($this->_def->info[$element]->attr[$key]->minimized)) { + $html .= $key . ' '; + continue; + } + } + // Workaround for Internet Explorer innerHTML bug. + // Essentially, Internet Explorer, when calculating + // innerHTML, omits quotes if there are no instances of + // angled brackets, quotes or spaces. However, when parsing + // HTML (for example, when you assign to innerHTML), it + // treats backticks as quotes. Thus, + // `` + // becomes + // `` + // becomes + // + // Fortunately, all we need to do is trigger an appropriate + // quoting style, which we do by adding an extra space. + // This also is consistent with the W3C spec, which states + // that user agents may ignore leading or trailing + // whitespace (in fact, most don't, at least for attributes + // like alt, but an extra space at the end is barely + // noticeable). Still, we have a configuration knob for + // this, since this transformation is not necesary if you + // don't process user input with innerHTML or you don't plan + // on supporting Internet Explorer. + if ($this->_innerHTMLFix) { + if (strpos($value, '`') !== false) { + // check if correct quoting style would not already be + // triggered + if (strcspn($value, '"\' <>') === strlen($value)) { + // protect! + $value .= ' '; + } + } + } + $html .= $key.'="'.$this->escape($value).'" '; + } + return rtrim($html); + } + + /** + * Escapes raw text data. + * @todo This really ought to be protected, but until we have a facility + * for properly generating HTML here w/o using tokens, it stays + * public. + * @param string $string String data to escape for HTML. + * @param int $quote Quoting style, like htmlspecialchars. ENT_NOQUOTES is + * permissible for non-attribute output. + * @return string escaped data. + */ + public function escape($string, $quote = null) + { + // Workaround for APC bug on Mac Leopard reported by sidepodcast + // http://htmlpurifier.org/phorum/read.php?3,4823,4846 + if ($quote === null) { + $quote = ENT_COMPAT; + } + return htmlspecialchars($string, $quote, 'UTF-8'); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLDefinition.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLDefinition.php new file mode 100644 index 0000000..9b7b334 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLDefinition.php @@ -0,0 +1,493 @@ +getAnonymousModule(); + if (!isset($module->info[$element_name])) { + $element = $module->addBlankElement($element_name); + } else { + $element = $module->info[$element_name]; + } + $element->attr[$attr_name] = $def; + } + + /** + * Adds a custom element to your HTML definition + * @see HTMLPurifier_HTMLModule::addElement() for detailed + * parameter and return value descriptions. + */ + public function addElement($element_name, $type, $contents, $attr_collections, $attributes = array()) + { + $module = $this->getAnonymousModule(); + // assume that if the user is calling this, the element + // is safe. This may not be a good idea + $element = $module->addElement($element_name, $type, $contents, $attr_collections, $attributes); + return $element; + } + + /** + * Adds a blank element to your HTML definition, for overriding + * existing behavior + * @param string $element_name + * @return HTMLPurifier_ElementDef + * @see HTMLPurifier_HTMLModule::addBlankElement() for detailed + * parameter and return value descriptions. + */ + public function addBlankElement($element_name) + { + $module = $this->getAnonymousModule(); + $element = $module->addBlankElement($element_name); + return $element; + } + + /** + * Retrieves a reference to the anonymous module, so you can + * bust out advanced features without having to make your own + * module. + * @return HTMLPurifier_HTMLModule + */ + public function getAnonymousModule() + { + if (!$this->_anonModule) { + $this->_anonModule = new HTMLPurifier_HTMLModule(); + $this->_anonModule->name = 'Anonymous'; + } + return $this->_anonModule; + } + + private $_anonModule = null; + + // PUBLIC BUT INTERNAL VARIABLES -------------------------------------- + + /** + * @type string + */ + public $type = 'HTML'; + + /** + * @type HTMLPurifier_HTMLModuleManager + */ + public $manager; + + /** + * Performs low-cost, preliminary initialization. + */ + public function __construct() + { + $this->manager = new HTMLPurifier_HTMLModuleManager(); + } + + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetup($config) + { + $this->processModules($config); + $this->setupConfigStuff($config); + unset($this->manager); + + // cleanup some of the element definitions + foreach ($this->info as $k => $v) { + unset($this->info[$k]->content_model); + unset($this->info[$k]->content_model_type); + } + } + + /** + * Extract out the information from the manager + * @param HTMLPurifier_Config $config + */ + protected function processModules($config) + { + if ($this->_anonModule) { + // for user specific changes + // this is late-loaded so we don't have to deal with PHP4 + // reference wonky-ness + $this->manager->addModule($this->_anonModule); + unset($this->_anonModule); + } + + $this->manager->setup($config); + $this->doctype = $this->manager->doctype; + + foreach ($this->manager->modules as $module) { + foreach ($module->info_tag_transform as $k => $v) { + if ($v === false) { + unset($this->info_tag_transform[$k]); + } else { + $this->info_tag_transform[$k] = $v; + } + } + foreach ($module->info_attr_transform_pre as $k => $v) { + if ($v === false) { + unset($this->info_attr_transform_pre[$k]); + } else { + $this->info_attr_transform_pre[$k] = $v; + } + } + foreach ($module->info_attr_transform_post as $k => $v) { + if ($v === false) { + unset($this->info_attr_transform_post[$k]); + } else { + $this->info_attr_transform_post[$k] = $v; + } + } + foreach ($module->info_injector as $k => $v) { + if ($v === false) { + unset($this->info_injector[$k]); + } else { + $this->info_injector[$k] = $v; + } + } + } + $this->info = $this->manager->getElements(); + $this->info_content_sets = $this->manager->contentSets->lookup; + } + + /** + * Sets up stuff based on config. We need a better way of doing this. + * @param HTMLPurifier_Config $config + */ + protected function setupConfigStuff($config) + { + $block_wrapper = $config->get('HTML.BlockWrapper'); + if (isset($this->info_content_sets['Block'][$block_wrapper])) { + $this->info_block_wrapper = $block_wrapper; + } else { + trigger_error( + 'Cannot use non-block element as block wrapper', + E_USER_ERROR + ); + } + + $parent = $config->get('HTML.Parent'); + $def = $this->manager->getElement($parent, true); + if ($def) { + $this->info_parent = $parent; + $this->info_parent_def = $def; + } else { + trigger_error( + 'Cannot use unrecognized element as parent', + E_USER_ERROR + ); + $this->info_parent_def = $this->manager->getElement($this->info_parent, true); + } + + // support template text + $support = "(for information on implementing this, see the support forums) "; + + // setup allowed elements ----------------------------------------- + + $allowed_elements = $config->get('HTML.AllowedElements'); + $allowed_attributes = $config->get('HTML.AllowedAttributes'); // retrieve early + + if (!is_array($allowed_elements) && !is_array($allowed_attributes)) { + $allowed = $config->get('HTML.Allowed'); + if (is_string($allowed)) { + list($allowed_elements, $allowed_attributes) = $this->parseTinyMCEAllowedList($allowed); + } + } + + if (is_array($allowed_elements)) { + foreach ($this->info as $name => $d) { + if (!isset($allowed_elements[$name])) { + unset($this->info[$name]); + } + unset($allowed_elements[$name]); + } + // emit errors + foreach ($allowed_elements as $element => $d) { + $element = htmlspecialchars($element); // PHP doesn't escape errors, be careful! + trigger_error("Element '$element' is not supported $support", E_USER_WARNING); + } + } + + // setup allowed attributes --------------------------------------- + + $allowed_attributes_mutable = $allowed_attributes; // by copy! + if (is_array($allowed_attributes)) { + // This actually doesn't do anything, since we went away from + // global attributes. It's possible that userland code uses + // it, but HTMLModuleManager doesn't! + foreach ($this->info_global_attr as $attr => $x) { + $keys = array($attr, "*@$attr", "*.$attr"); + $delete = true; + foreach ($keys as $key) { + if ($delete && isset($allowed_attributes[$key])) { + $delete = false; + } + if (isset($allowed_attributes_mutable[$key])) { + unset($allowed_attributes_mutable[$key]); + } + } + if ($delete) { + unset($this->info_global_attr[$attr]); + } + } + + foreach ($this->info as $tag => $info) { + foreach ($info->attr as $attr => $x) { + $keys = array("$tag@$attr", $attr, "*@$attr", "$tag.$attr", "*.$attr"); + $delete = true; + foreach ($keys as $key) { + if ($delete && isset($allowed_attributes[$key])) { + $delete = false; + } + if (isset($allowed_attributes_mutable[$key])) { + unset($allowed_attributes_mutable[$key]); + } + } + if ($delete) { + if ($this->info[$tag]->attr[$attr]->required) { + trigger_error( + "Required attribute '$attr' in element '$tag' " . + "was not allowed, which means '$tag' will not be allowed either", + E_USER_WARNING + ); + } + unset($this->info[$tag]->attr[$attr]); + } + } + } + // emit errors + foreach ($allowed_attributes_mutable as $elattr => $d) { + $bits = preg_split('/[.@]/', $elattr, 2); + $c = count($bits); + switch ($c) { + case 2: + if ($bits[0] !== '*') { + $element = htmlspecialchars($bits[0]); + $attribute = htmlspecialchars($bits[1]); + if (!isset($this->info[$element])) { + trigger_error( + "Cannot allow attribute '$attribute' if element " . + "'$element' is not allowed/supported $support" + ); + } else { + trigger_error( + "Attribute '$attribute' in element '$element' not supported $support", + E_USER_WARNING + ); + } + break; + } + // otherwise fall through + case 1: + $attribute = htmlspecialchars($bits[0]); + trigger_error( + "Global attribute '$attribute' is not ". + "supported in any elements $support", + E_USER_WARNING + ); + break; + } + } + } + + // setup forbidden elements --------------------------------------- + + $forbidden_elements = $config->get('HTML.ForbiddenElements'); + $forbidden_attributes = $config->get('HTML.ForbiddenAttributes'); + + foreach ($this->info as $tag => $info) { + if (isset($forbidden_elements[$tag])) { + unset($this->info[$tag]); + continue; + } + foreach ($info->attr as $attr => $x) { + if (isset($forbidden_attributes["$tag@$attr"]) || + isset($forbidden_attributes["*@$attr"]) || + isset($forbidden_attributes[$attr]) + ) { + unset($this->info[$tag]->attr[$attr]); + continue; + } elseif (isset($forbidden_attributes["$tag.$attr"])) { // this segment might get removed eventually + // $tag.$attr are not user supplied, so no worries! + trigger_error( + "Error with $tag.$attr: tag.attr syntax not supported for " . + "HTML.ForbiddenAttributes; use tag@attr instead", + E_USER_WARNING + ); + } + } + } + foreach ($forbidden_attributes as $key => $v) { + if (strlen($key) < 2) { + continue; + } + if ($key[0] != '*') { + continue; + } + if ($key[1] == '.') { + trigger_error( + "Error with $key: *.attr syntax not supported for HTML.ForbiddenAttributes; use attr instead", + E_USER_WARNING + ); + } + } + + // setup injectors ----------------------------------------------------- + foreach ($this->info_injector as $i => $injector) { + if ($injector->checkNeeded($config) !== false) { + // remove injector that does not have it's required + // elements/attributes present, and is thus not needed. + unset($this->info_injector[$i]); + } + } + } + + /** + * Parses a TinyMCE-flavored Allowed Elements and Attributes list into + * separate lists for processing. Format is element[attr1|attr2],element2... + * @warning Although it's largely drawn from TinyMCE's implementation, + * it is different, and you'll probably have to modify your lists + * @param array $list String list to parse + * @return array + * @todo Give this its own class, probably static interface + */ + public function parseTinyMCEAllowedList($list) + { + $list = str_replace(array(' ', "\t"), '', $list); + + $elements = array(); + $attributes = array(); + + $chunks = preg_split('/(,|[\n\r]+)/', $list); + foreach ($chunks as $chunk) { + if (empty($chunk)) { + continue; + } + // remove TinyMCE element control characters + if (!strpos($chunk, '[')) { + $element = $chunk; + $attr = false; + } else { + list($element, $attr) = explode('[', $chunk); + } + if ($element !== '*') { + $elements[$element] = true; + } + if (!$attr) { + continue; + } + $attr = substr($attr, 0, strlen($attr) - 1); // remove trailing ] + $attr = explode('|', $attr); + foreach ($attr as $key) { + $attributes["$element.$key"] = true; + } + } + return array($elements, $attributes); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule.php new file mode 100644 index 0000000..9dbb987 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule.php @@ -0,0 +1,285 @@ +info, since the object's data is only info, + * with extra behavior associated with it. + * @type array + */ + public $attr_collections = array(); + + /** + * Associative array of deprecated tag name to HTMLPurifier_TagTransform. + * @type array + */ + public $info_tag_transform = array(); + + /** + * List of HTMLPurifier_AttrTransform to be performed before validation. + * @type array + */ + public $info_attr_transform_pre = array(); + + /** + * List of HTMLPurifier_AttrTransform to be performed after validation. + * @type array + */ + public $info_attr_transform_post = array(); + + /** + * List of HTMLPurifier_Injector to be performed during well-formedness fixing. + * An injector will only be invoked if all of it's pre-requisites are met; + * if an injector fails setup, there will be no error; it will simply be + * silently disabled. + * @type array + */ + public $info_injector = array(); + + /** + * Boolean flag that indicates whether or not getChildDef is implemented. + * For optimization reasons: may save a call to a function. Be sure + * to set it if you do implement getChildDef(), otherwise it will have + * no effect! + * @type bool + */ + public $defines_child_def = false; + + /** + * Boolean flag whether or not this module is safe. If it is not safe, all + * of its members are unsafe. Modules are safe by default (this might be + * slightly dangerous, but it doesn't make much sense to force HTML Purifier, + * which is based off of safe HTML, to explicitly say, "This is safe," even + * though there are modules which are "unsafe") + * + * @type bool + * @note Previously, safety could be applied at an element level granularity. + * We've removed this ability, so in order to add "unsafe" elements + * or attributes, a dedicated module with this property set to false + * must be used. + */ + public $safe = true; + + /** + * Retrieves a proper HTMLPurifier_ChildDef subclass based on + * content_model and content_model_type member variables of + * the HTMLPurifier_ElementDef class. There is a similar function + * in HTMLPurifier_HTMLDefinition. + * @param HTMLPurifier_ElementDef $def + * @return HTMLPurifier_ChildDef subclass + */ + public function getChildDef($def) + { + return false; + } + + // -- Convenience ----------------------------------------------------- + + /** + * Convenience function that sets up a new element + * @param string $element Name of element to add + * @param string|bool $type What content set should element be registered to? + * Set as false to skip this step. + * @param string|HTMLPurifier_ChildDef $contents Allowed children in form of: + * "$content_model_type: $content_model" + * @param array|string $attr_includes What attribute collections to register to + * element? + * @param array $attr What unique attributes does the element define? + * @see HTMLPurifier_ElementDef:: for in-depth descriptions of these parameters. + * @return HTMLPurifier_ElementDef Created element definition object, so you + * can set advanced parameters + */ + public function addElement($element, $type, $contents, $attr_includes = array(), $attr = array()) + { + $this->elements[] = $element; + // parse content_model + list($content_model_type, $content_model) = $this->parseContents($contents); + // merge in attribute inclusions + $this->mergeInAttrIncludes($attr, $attr_includes); + // add element to content sets + if ($type) { + $this->addElementToContentSet($element, $type); + } + // create element + $this->info[$element] = HTMLPurifier_ElementDef::create( + $content_model, + $content_model_type, + $attr + ); + // literal object $contents means direct child manipulation + if (!is_string($contents)) { + $this->info[$element]->child = $contents; + } + return $this->info[$element]; + } + + /** + * Convenience function that creates a totally blank, non-standalone + * element. + * @param string $element Name of element to create + * @return HTMLPurifier_ElementDef Created element + */ + public function addBlankElement($element) + { + if (!isset($this->info[$element])) { + $this->elements[] = $element; + $this->info[$element] = new HTMLPurifier_ElementDef(); + $this->info[$element]->standalone = false; + } else { + trigger_error("Definition for $element already exists in module, cannot redefine"); + } + return $this->info[$element]; + } + + /** + * Convenience function that registers an element to a content set + * @param string $element Element to register + * @param string $type Name content set (warning: case sensitive, usually upper-case + * first letter) + */ + public function addElementToContentSet($element, $type) + { + if (!isset($this->content_sets[$type])) { + $this->content_sets[$type] = ''; + } else { + $this->content_sets[$type] .= ' | '; + } + $this->content_sets[$type] .= $element; + } + + /** + * Convenience function that transforms single-string contents + * into separate content model and content model type + * @param string $contents Allowed children in form of: + * "$content_model_type: $content_model" + * @return array + * @note If contents is an object, an array of two nulls will be + * returned, and the callee needs to take the original $contents + * and use it directly. + */ + public function parseContents($contents) + { + if (!is_string($contents)) { + return array(null, null); + } // defer + switch ($contents) { + // check for shorthand content model forms + case 'Empty': + return array('empty', ''); + case 'Inline': + return array('optional', 'Inline | #PCDATA'); + case 'Flow': + return array('optional', 'Flow | #PCDATA'); + } + list($content_model_type, $content_model) = explode(':', $contents); + $content_model_type = strtolower(trim($content_model_type)); + $content_model = trim($content_model); + return array($content_model_type, $content_model); + } + + /** + * Convenience function that merges a list of attribute includes into + * an attribute array. + * @param array $attr Reference to attr array to modify + * @param array $attr_includes Array of includes / string include to merge in + */ + public function mergeInAttrIncludes(&$attr, $attr_includes) + { + if (!is_array($attr_includes)) { + if (empty($attr_includes)) { + $attr_includes = array(); + } else { + $attr_includes = array($attr_includes); + } + } + $attr[0] = $attr_includes; + } + + /** + * Convenience function that generates a lookup table with boolean + * true as value. + * @param string $list List of values to turn into a lookup + * @note You can also pass an arbitrary number of arguments in + * place of the regular argument + * @return array array equivalent of list + */ + public function makeLookup($list) + { + $args = func_get_args(); + if (is_string($list)) { + $list = $args; + } + $ret = array(); + foreach ($list as $value) { + if (is_null($value)) { + continue; + } + $ret[$value] = true; + } + return $ret; + } + + /** + * Lazy load construction of the module after determining whether + * or not it's needed, and also when a finalized configuration object + * is available. + * @param HTMLPurifier_Config $config + */ + public function setup($config) + { + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Bdo.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Bdo.php new file mode 100644 index 0000000..1e67c79 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Bdo.php @@ -0,0 +1,44 @@ + array('dir' => false) + ); + + /** + * @param HTMLPurifier_Config $config + */ + public function setup($config) + { + $bdo = $this->addElement( + 'bdo', + 'Inline', + 'Inline', + array('Core', 'Lang'), + array( + 'dir' => 'Enum#ltr,rtl', // required + // The Abstract Module specification has the attribute + // inclusions wrong for bdo: bdo allows Lang + ) + ); + $bdo->attr_transform_post[] = new HTMLPurifier_AttrTransform_BdoDir(); + + $this->attr_collections['I18N']['dir'] = 'Enum#ltr,rtl'; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/CommonAttributes.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/CommonAttributes.php new file mode 100644 index 0000000..7220c14 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/CommonAttributes.php @@ -0,0 +1,32 @@ + array( + 0 => array('Style'), + // 'xml:space' => false, + 'class' => 'Class', + 'id' => 'ID', + 'title' => 'CDATA', + 'contenteditable' => 'ContentEditable', + ), + 'Lang' => array(), + 'I18N' => array( + 0 => array('Lang'), // proprietary, for xml:lang/lang + ), + 'Common' => array( + 0 => array('Core', 'I18N') + ) + ); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Edit.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Edit.php new file mode 100644 index 0000000..a9042a3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Edit.php @@ -0,0 +1,55 @@ + 'URI', + // 'datetime' => 'Datetime', // not implemented + ); + $this->addElement('del', 'Inline', $contents, 'Common', $attr); + $this->addElement('ins', 'Inline', $contents, 'Common', $attr); + } + + // HTML 4.01 specifies that ins/del must not contain block + // elements when used in an inline context, chameleon is + // a complicated workaround to acheive this effect + + // Inline context ! Block context (exclamation mark is + // separator, see getChildDef for parsing) + + /** + * @type bool + */ + public $defines_child_def = true; + + /** + * @param HTMLPurifier_ElementDef $def + * @return HTMLPurifier_ChildDef_Chameleon + */ + public function getChildDef($def) + { + if ($def->content_model_type != 'chameleon') { + return false; + } + $value = explode('!', $def->content_model); + return new HTMLPurifier_ChildDef_Chameleon($value[0], $value[1]); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Forms.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Forms.php new file mode 100644 index 0000000..eb0edcf --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Forms.php @@ -0,0 +1,194 @@ + 'Form', + 'Inline' => 'Formctrl', + ); + + /** + * @param HTMLPurifier_Config $config + */ + public function setup($config) + { + if ($config->get('HTML.Forms')) { + $this->safe = true; + } + + $form = $this->addElement( + 'form', + 'Form', + 'Required: Heading | List | Block | fieldset', + 'Common', + array( + 'accept' => 'ContentTypes', + 'accept-charset' => 'Charsets', + 'action*' => 'URI', + 'method' => 'Enum#get,post', + // really ContentType, but these two are the only ones used today + 'enctype' => 'Enum#application/x-www-form-urlencoded,multipart/form-data', + ) + ); + $form->excludes = array('form' => true); + + $input = $this->addElement( + 'input', + 'Formctrl', + 'Empty', + 'Common', + array( + 'accept' => 'ContentTypes', + 'accesskey' => 'Character', + 'alt' => 'Text', + 'checked' => 'Bool#checked', + 'disabled' => 'Bool#disabled', + 'maxlength' => 'Number', + 'name' => 'CDATA', + 'readonly' => 'Bool#readonly', + 'size' => 'Number', + 'src' => 'URI#embedded', + 'tabindex' => 'Number', + 'type' => 'Enum#text,password,checkbox,button,radio,submit,reset,file,hidden,image', + 'value' => 'CDATA', + ) + ); + $input->attr_transform_post[] = new HTMLPurifier_AttrTransform_Input(); + + $this->addElement( + 'select', + 'Formctrl', + 'Required: optgroup | option', + 'Common', + array( + 'disabled' => 'Bool#disabled', + 'multiple' => 'Bool#multiple', + 'name' => 'CDATA', + 'size' => 'Number', + 'tabindex' => 'Number', + ) + ); + + $this->addElement( + 'option', + false, + 'Optional: #PCDATA', + 'Common', + array( + 'disabled' => 'Bool#disabled', + 'label' => 'Text', + 'selected' => 'Bool#selected', + 'value' => 'CDATA', + ) + ); + // It's illegal for there to be more than one selected, but not + // be multiple. Also, no selected means undefined behavior. This might + // be difficult to implement; perhaps an injector, or a context variable. + + $textarea = $this->addElement( + 'textarea', + 'Formctrl', + 'Optional: #PCDATA', + 'Common', + array( + 'accesskey' => 'Character', + 'cols*' => 'Number', + 'disabled' => 'Bool#disabled', + 'name' => 'CDATA', + 'readonly' => 'Bool#readonly', + 'rows*' => 'Number', + 'tabindex' => 'Number', + ) + ); + $textarea->attr_transform_pre[] = new HTMLPurifier_AttrTransform_Textarea(); + + $button = $this->addElement( + 'button', + 'Formctrl', + 'Optional: #PCDATA | Heading | List | Block | Inline', + 'Common', + array( + 'accesskey' => 'Character', + 'disabled' => 'Bool#disabled', + 'name' => 'CDATA', + 'tabindex' => 'Number', + 'type' => 'Enum#button,submit,reset', + 'value' => 'CDATA', + ) + ); + + // For exclusions, ideally we'd specify content sets, not literal elements + $button->excludes = $this->makeLookup( + 'form', + 'fieldset', // Form + 'input', + 'select', + 'textarea', + 'label', + 'button', // Formctrl + 'a', // as per HTML 4.01 spec, this is omitted by modularization + 'isindex', + 'iframe' // legacy items + ); + + // Extra exclusion: img usemap="" is not permitted within this element. + // We'll omit this for now, since we don't have any good way of + // indicating it yet. + + // This is HIGHLY user-unfriendly; we need a custom child-def for this + $this->addElement('fieldset', 'Form', 'Custom: (#WS?,legend,(Flow|#PCDATA)*)', 'Common'); + + $label = $this->addElement( + 'label', + 'Formctrl', + 'Optional: #PCDATA | Inline', + 'Common', + array( + 'accesskey' => 'Character', + // 'for' => 'IDREF', // IDREF not implemented, cannot allow + ) + ); + $label->excludes = array('label' => true); + + $this->addElement( + 'legend', + false, + 'Optional: #PCDATA | Inline', + 'Common', + array( + 'accesskey' => 'Character', + ) + ); + + $this->addElement( + 'optgroup', + false, + 'Required: option', + 'Common', + array( + 'disabled' => 'Bool#disabled', + 'label*' => 'Text', + ) + ); + // Don't forget an injector for . This one's a little complex + // because it maps to multiple elements. + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Hypertext.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Hypertext.php new file mode 100644 index 0000000..72d7a31 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Hypertext.php @@ -0,0 +1,40 @@ +addElement( + 'a', + 'Inline', + 'Inline', + 'Common', + array( + // 'accesskey' => 'Character', + // 'charset' => 'Charset', + 'href' => 'URI', + // 'hreflang' => 'LanguageCode', + 'rel' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rel'), + 'rev' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rev'), + // 'tabindex' => 'Number', + // 'type' => 'ContentType', + ) + ); + $a->formatting = true; + $a->excludes = array('a' => true); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Iframe.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Iframe.php new file mode 100644 index 0000000..71dfc77 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Iframe.php @@ -0,0 +1,57 @@ +get('HTML.SafeIframe')) { + $this->safe = true; + } + $attrs = array( + 'src' => 'URI#embedded', + 'width' => 'Length', + 'height' => 'Length', + 'name' => 'ID', + 'scrolling' => 'Enum#yes,no,auto', + 'frameborder' => 'Enum#0,1', + 'longdesc' => 'URI', + 'marginheight' => 'Pixels', + 'marginwidth' => 'Pixels', + ); + + if ($config->get('HTML.Trusted')) { + $attrs['allowfullscreen'] = 'Bool#allowfullscreen'; + } + + $this->addElement( + 'iframe', + 'Inline', + 'Flow', + 'Common', + $attrs + ); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Image.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Image.php new file mode 100644 index 0000000..0f5fdb3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Image.php @@ -0,0 +1,49 @@ +get('HTML.MaxImgLength'); + $img = $this->addElement( + 'img', + 'Inline', + 'Empty', + 'Common', + array( + 'alt*' => 'Text', + // According to the spec, it's Length, but percents can + // be abused, so we allow only Pixels. + 'height' => 'Pixels#' . $max, + 'width' => 'Pixels#' . $max, + 'longdesc' => 'URI', + 'src*' => new HTMLPurifier_AttrDef_URI(true), // embedded + ) + ); + if ($max === null || $config->get('HTML.Trusted')) { + $img->attr['height'] = + $img->attr['width'] = 'Length'; + } + + // kind of strange, but splitting things up would be inefficient + $img->attr_transform_pre[] = + $img->attr_transform_post[] = + new HTMLPurifier_AttrTransform_ImgRequired(); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Legacy.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Legacy.php new file mode 100644 index 0000000..86b5299 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Legacy.php @@ -0,0 +1,186 @@ +addElement( + 'basefont', + 'Inline', + 'Empty', + null, + array( + 'color' => 'Color', + 'face' => 'Text', // extremely broad, we should + 'size' => 'Text', // tighten it + 'id' => 'ID' + ) + ); + $this->addElement('center', 'Block', 'Flow', 'Common'); + $this->addElement( + 'dir', + 'Block', + 'Required: li', + 'Common', + array( + 'compact' => 'Bool#compact' + ) + ); + $this->addElement( + 'font', + 'Inline', + 'Inline', + array('Core', 'I18N'), + array( + 'color' => 'Color', + 'face' => 'Text', // extremely broad, we should + 'size' => 'Text', // tighten it + ) + ); + $this->addElement( + 'menu', + 'Block', + 'Required: li', + 'Common', + array( + 'compact' => 'Bool#compact' + ) + ); + + $s = $this->addElement('s', 'Inline', 'Inline', 'Common'); + $s->formatting = true; + + $strike = $this->addElement('strike', 'Inline', 'Inline', 'Common'); + $strike->formatting = true; + + $u = $this->addElement('u', 'Inline', 'Inline', 'Common'); + $u->formatting = true; + + // setup modifications to old elements + + $align = 'Enum#left,right,center,justify'; + + $address = $this->addBlankElement('address'); + $address->content_model = 'Inline | #PCDATA | p'; + $address->content_model_type = 'optional'; + $address->child = false; + + $blockquote = $this->addBlankElement('blockquote'); + $blockquote->content_model = 'Flow | #PCDATA'; + $blockquote->content_model_type = 'optional'; + $blockquote->child = false; + + $br = $this->addBlankElement('br'); + $br->attr['clear'] = 'Enum#left,all,right,none'; + + $caption = $this->addBlankElement('caption'); + $caption->attr['align'] = 'Enum#top,bottom,left,right'; + + $div = $this->addBlankElement('div'); + $div->attr['align'] = $align; + + $dl = $this->addBlankElement('dl'); + $dl->attr['compact'] = 'Bool#compact'; + + for ($i = 1; $i <= 6; $i++) { + $h = $this->addBlankElement("h$i"); + $h->attr['align'] = $align; + } + + $hr = $this->addBlankElement('hr'); + $hr->attr['align'] = $align; + $hr->attr['noshade'] = 'Bool#noshade'; + $hr->attr['size'] = 'Pixels'; + $hr->attr['width'] = 'Length'; + + $img = $this->addBlankElement('img'); + $img->attr['align'] = 'IAlign'; + $img->attr['border'] = 'Pixels'; + $img->attr['hspace'] = 'Pixels'; + $img->attr['vspace'] = 'Pixels'; + + // figure out this integer business + + $li = $this->addBlankElement('li'); + $li->attr['value'] = new HTMLPurifier_AttrDef_Integer(); + $li->attr['type'] = 'Enum#s:1,i,I,a,A,disc,square,circle'; + + $ol = $this->addBlankElement('ol'); + $ol->attr['compact'] = 'Bool#compact'; + $ol->attr['start'] = new HTMLPurifier_AttrDef_Integer(); + $ol->attr['type'] = 'Enum#s:1,i,I,a,A'; + + $p = $this->addBlankElement('p'); + $p->attr['align'] = $align; + + $pre = $this->addBlankElement('pre'); + $pre->attr['width'] = 'Number'; + + // script omitted + + $table = $this->addBlankElement('table'); + $table->attr['align'] = 'Enum#left,center,right'; + $table->attr['bgcolor'] = 'Color'; + + $tr = $this->addBlankElement('tr'); + $tr->attr['bgcolor'] = 'Color'; + + $th = $this->addBlankElement('th'); + $th->attr['bgcolor'] = 'Color'; + $th->attr['height'] = 'Length'; + $th->attr['nowrap'] = 'Bool#nowrap'; + $th->attr['width'] = 'Length'; + + $td = $this->addBlankElement('td'); + $td->attr['bgcolor'] = 'Color'; + $td->attr['height'] = 'Length'; + $td->attr['nowrap'] = 'Bool#nowrap'; + $td->attr['width'] = 'Length'; + + $ul = $this->addBlankElement('ul'); + $ul->attr['compact'] = 'Bool#compact'; + $ul->attr['type'] = 'Enum#square,disc,circle'; + + // "safe" modifications to "unsafe" elements + // WARNING: If you want to add support for an unsafe, legacy + // attribute, make a new TrustedLegacy module with the trusted + // bit set appropriately + + $form = $this->addBlankElement('form'); + $form->content_model = 'Flow | #PCDATA'; + $form->content_model_type = 'optional'; + $form->attr['target'] = 'FrameTarget'; + + $input = $this->addBlankElement('input'); + $input->attr['align'] = 'IAlign'; + + $legend = $this->addBlankElement('legend'); + $legend->attr['align'] = 'LAlign'; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/List.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/List.php new file mode 100644 index 0000000..7a20ff7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/List.php @@ -0,0 +1,51 @@ + 'List'); + + /** + * @param HTMLPurifier_Config $config + */ + public function setup($config) + { + $ol = $this->addElement('ol', 'List', new HTMLPurifier_ChildDef_List(), 'Common'); + $ul = $this->addElement('ul', 'List', new HTMLPurifier_ChildDef_List(), 'Common'); + // XXX The wrap attribute is handled by MakeWellFormed. This is all + // quite unsatisfactory, because we generated this + // *specifically* for lists, and now a big chunk of the handling + // is done properly by the List ChildDef. So actually, we just + // want enough information to make autoclosing work properly, + // and then hand off the tricky stuff to the ChildDef. + $ol->wrap = 'li'; + $ul->wrap = 'li'; + $this->addElement('dl', 'List', 'Required: dt | dd', 'Common'); + + $this->addElement('li', false, 'Flow', 'Common'); + + $this->addElement('dd', false, 'Flow', 'Common'); + $this->addElement('dt', false, 'Inline', 'Common'); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Name.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Name.php new file mode 100644 index 0000000..60c0545 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Name.php @@ -0,0 +1,26 @@ +addBlankElement($name); + $element->attr['name'] = 'CDATA'; + if (!$config->get('HTML.Attr.Name.UseCDATA')) { + $element->attr_transform_post[] = new HTMLPurifier_AttrTransform_NameSync(); + } + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Nofollow.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Nofollow.php new file mode 100644 index 0000000..dc9410a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Nofollow.php @@ -0,0 +1,25 @@ +addBlankElement('a'); + $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_Nofollow(); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php new file mode 100644 index 0000000..da72225 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php @@ -0,0 +1,20 @@ + array( + 'lang' => 'LanguageCode', + ) + ); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Object.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Object.php new file mode 100644 index 0000000..2f9efc5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Object.php @@ -0,0 +1,62 @@ + to cater to legacy browsers: this + * module does not allow this sort of behavior + */ +class HTMLPurifier_HTMLModule_Object extends HTMLPurifier_HTMLModule +{ + /** + * @type string + */ + public $name = 'Object'; + + /** + * @type bool + */ + public $safe = false; + + /** + * @param HTMLPurifier_Config $config + */ + public function setup($config) + { + $this->addElement( + 'object', + 'Inline', + 'Optional: #PCDATA | Flow | param', + 'Common', + array( + 'archive' => 'URI', + 'classid' => 'URI', + 'codebase' => 'URI', + 'codetype' => 'Text', + 'data' => 'URI', + 'declare' => 'Bool#declare', + 'height' => 'Length', + 'name' => 'CDATA', + 'standby' => 'Text', + 'tabindex' => 'Number', + 'type' => 'ContentType', + 'width' => 'Length' + ) + ); + + $this->addElement( + 'param', + false, + 'Empty', + null, + array( + 'id' => 'ID', + 'name*' => 'Text', + 'type' => 'Text', + 'value' => 'Text', + 'valuetype' => 'Enum#data,ref,object' + ) + ); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Presentation.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Presentation.php new file mode 100644 index 0000000..6458ce9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Presentation.php @@ -0,0 +1,42 @@ +addElement('hr', 'Block', 'Empty', 'Common'); + $this->addElement('sub', 'Inline', 'Inline', 'Common'); + $this->addElement('sup', 'Inline', 'Inline', 'Common'); + $b = $this->addElement('b', 'Inline', 'Inline', 'Common'); + $b->formatting = true; + $big = $this->addElement('big', 'Inline', 'Inline', 'Common'); + $big->formatting = true; + $i = $this->addElement('i', 'Inline', 'Inline', 'Common'); + $i->formatting = true; + $small = $this->addElement('small', 'Inline', 'Inline', 'Common'); + $small->formatting = true; + $tt = $this->addElement('tt', 'Inline', 'Inline', 'Common'); + $tt->formatting = true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Proprietary.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Proprietary.php new file mode 100644 index 0000000..5ee3c8e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Proprietary.php @@ -0,0 +1,40 @@ +addElement( + 'marquee', + 'Inline', + 'Flow', + 'Common', + array( + 'direction' => 'Enum#left,right,up,down', + 'behavior' => 'Enum#alternate', + 'width' => 'Length', + 'height' => 'Length', + 'scrolldelay' => 'Number', + 'scrollamount' => 'Number', + 'loop' => 'Number', + 'bgcolor' => 'Color', + 'hspace' => 'Pixels', + 'vspace' => 'Pixels', + ) + ); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Ruby.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Ruby.php new file mode 100644 index 0000000..a0d4892 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/Ruby.php @@ -0,0 +1,36 @@ +addElement( + 'ruby', + 'Inline', + 'Custom: ((rb, (rt | (rp, rt, rp))) | (rbc, rtc, rtc?))', + 'Common' + ); + $this->addElement('rbc', false, 'Required: rb', 'Common'); + $this->addElement('rtc', false, 'Required: rt', 'Common'); + $rb = $this->addElement('rb', false, 'Inline', 'Common'); + $rb->excludes = array('ruby' => true); + $rt = $this->addElement('rt', false, 'Inline', 'Common', array('rbspan' => 'Number')); + $rt->excludes = array('ruby' => true); + $this->addElement('rp', false, 'Optional: #PCDATA', 'Common'); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeEmbed.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeEmbed.php new file mode 100644 index 0000000..04e6689 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeEmbed.php @@ -0,0 +1,40 @@ +get('HTML.MaxImgLength'); + $embed = $this->addElement( + 'embed', + 'Inline', + 'Empty', + 'Common', + array( + 'src*' => 'URI#embedded', + 'type' => 'Enum#application/x-shockwave-flash', + 'width' => 'Pixels#' . $max, + 'height' => 'Pixels#' . $max, + 'allowscriptaccess' => 'Enum#never', + 'allownetworking' => 'Enum#internal', + 'flashvars' => 'Text', + 'wmode' => 'Enum#window,transparent,opaque', + 'name' => 'ID', + ) + ); + $embed->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeEmbed(); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeObject.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeObject.php new file mode 100644 index 0000000..1297f80 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeObject.php @@ -0,0 +1,62 @@ +get('HTML.MaxImgLength'); + $object = $this->addElement( + 'object', + 'Inline', + 'Optional: param | Flow | #PCDATA', + 'Common', + array( + // While technically not required by the spec, we're forcing + // it to this value. + 'type' => 'Enum#application/x-shockwave-flash', + 'width' => 'Pixels#' . $max, + 'height' => 'Pixels#' . $max, + 'data' => 'URI#embedded', + 'codebase' => new HTMLPurifier_AttrDef_Enum( + array( + 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0' + ) + ), + ) + ); + $object->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeObject(); + + $param = $this->addElement( + 'param', + false, + 'Empty', + false, + array( + 'id' => 'ID', + 'name*' => 'Text', + 'value' => 'Text' + ) + ); + $param->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeParam(); + $this->info_injector[] = 'SafeObject'; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeScripting.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeScripting.php new file mode 100644 index 0000000..aea7584 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/HTMLModule/SafeScripting.php @@ -0,0 +1,40 @@ +get('HTML.SafeScripting'); + $script = $this->addElement( + 'script', + 'Inline', + 'Optional:', // Not `Empty` to not allow to autoclose the #i', '', $html); + } + + return $html; + } + + /** + * Takes a string of HTML (fragment or document) and returns the content + * @todo Consider making protected + */ + public function extractBody($html) + { + $matches = array(); + $result = preg_match('|(.*?)]*>(.*)|is', $html, $matches); + if ($result) { + // Make sure it's not in a comment + $comment_start = strrpos($matches[1], ''); + if ($comment_start === false || + ($comment_end !== false && $comment_end > $comment_start)) { + return $matches[2]; + } + } + return $html; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Lexer/DOMLex.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Lexer/DOMLex.php new file mode 100644 index 0000000..7d57983 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Lexer/DOMLex.php @@ -0,0 +1,340 @@ +factory = new HTMLPurifier_TokenFactory(); + } + + /** + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] + */ + public function tokenizeHTML($html, $config, $context) + { + $html = $this->normalize($html, $config, $context); + + // attempt to armor stray angled brackets that cannot possibly + // form tags and thus are probably being used as emoticons + if ($config->get('Core.AggressivelyFixLt')) { + $char = '[^a-z!\/]'; + $comment = "/|\z)/is"; + $html = preg_replace_callback($comment, array($this, 'callbackArmorCommentEntities'), $html); + do { + $old = $html; + $html = preg_replace("/<($char)/i", '<\\1', $html); + } while ($html !== $old); + $html = preg_replace_callback($comment, array($this, 'callbackUndoCommentSubst'), $html); // fix comments + } + + // preprocess html, essential for UTF-8 + $html = $this->wrapHTML($html, $config, $context); + + $doc = new DOMDocument(); + $doc->encoding = 'UTF-8'; // theoretically, the above has this covered + + $options = 0; + if ($config->get('Core.AllowParseManyTags') && defined('LIBXML_PARSEHUGE')) { + $options |= LIBXML_PARSEHUGE; + } + if ($config->get('Core.RemoveBlanks') && defined('LIBXML_NOBLANKS')) { + $options |= LIBXML_NOBLANKS; + } + + set_error_handler(array($this, 'muteErrorHandler')); + // loadHTML() fails on PHP 5.3 when second parameter is given + if ($options) { + $doc->loadHTML($html, $options); + } else { + $doc->loadHTML($html); + } + restore_error_handler(); + + $body = $doc->getElementsByTagName('html')->item(0)-> // + getElementsByTagName('body')->item(0); // + + $div = $body->getElementsByTagName('div')->item(0); //
        + $tokens = array(); + $this->tokenizeDOM($div, $tokens, $config); + // If the div has a sibling, that means we tripped across + // a premature
        tag. So remove the div we parsed, + // and then tokenize the rest of body. We can't tokenize + // the sibling directly as we'll lose the tags in that case. + if ($div->nextSibling) { + $body->removeChild($div); + $this->tokenizeDOM($body, $tokens, $config); + } + return $tokens; + } + + /** + * Iterative function that tokenizes a node, putting it into an accumulator. + * To iterate is human, to recurse divine - L. Peter Deutsch + * @param DOMNode $node DOMNode to be tokenized. + * @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens. + */ + protected function tokenizeDOM($node, &$tokens, $config) + { + $level = 0; + $nodes = array($level => new HTMLPurifier_Queue(array($node))); + $closingNodes = array(); + do { + while (!$nodes[$level]->isEmpty()) { + $node = $nodes[$level]->shift(); // FIFO + $collect = $level > 0 ? true : false; + $needEndingTag = $this->createStartNode($node, $tokens, $collect, $config); + if ($needEndingTag) { + $closingNodes[$level][] = $node; + } + if ($node->childNodes && $node->childNodes->length) { + $level++; + $nodes[$level] = new HTMLPurifier_Queue(); + foreach ($node->childNodes as $childNode) { + $nodes[$level]->push($childNode); + } + } + } + $level--; + if ($level && isset($closingNodes[$level])) { + while ($node = array_pop($closingNodes[$level])) { + $this->createEndNode($node, $tokens); + } + } + } while ($level > 0); + } + + /** + * Portably retrieve the tag name of a node; deals with older versions + * of libxml like 2.7.6 + * @param DOMNode $node + */ + protected function getTagName($node) + { + if (isset($node->tagName)) { + return $node->tagName; + } else if (isset($node->nodeName)) { + return $node->nodeName; + } else if (isset($node->localName)) { + return $node->localName; + } + return null; + } + + /** + * Portably retrieve the data of a node; deals with older versions + * of libxml like 2.7.6 + * @param DOMNode $node + */ + protected function getData($node) + { + if (isset($node->data)) { + return $node->data; + } else if (isset($node->nodeValue)) { + return $node->nodeValue; + } else if (isset($node->textContent)) { + return $node->textContent; + } + return null; + } + + + /** + * @param DOMNode $node DOMNode to be tokenized. + * @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens. + * @param bool $collect Says whether or start and close are collected, set to + * false at first recursion because it's the implicit DIV + * tag you're dealing with. + * @return bool if the token needs an endtoken + * @todo data and tagName properties don't seem to exist in DOMNode? + */ + protected function createStartNode($node, &$tokens, $collect, $config) + { + // intercept non element nodes. WE MUST catch all of them, + // but we're not getting the character reference nodes because + // those should have been preprocessed + if ($node->nodeType === XML_TEXT_NODE) { + $data = $this->getData($node); // Handle variable data property + if ($data !== null) { + $tokens[] = $this->factory->createText($data); + } + return false; + } elseif ($node->nodeType === XML_CDATA_SECTION_NODE) { + // undo libxml's special treatment of )#si', + array($this, 'scriptCallback'), + $html + ); + } + + $html = $this->normalize($html, $config, $context); + + $cursor = 0; // our location in the text + $inside_tag = false; // whether or not we're parsing the inside of a tag + $array = array(); // result array + + // This is also treated to mean maintain *column* numbers too + $maintain_line_numbers = $config->get('Core.MaintainLineNumbers'); + + if ($maintain_line_numbers === null) { + // automatically determine line numbering by checking + // if error collection is on + $maintain_line_numbers = $config->get('Core.CollectErrors'); + } + + if ($maintain_line_numbers) { + $current_line = 1; + $current_col = 0; + $length = strlen($html); + } else { + $current_line = false; + $current_col = false; + $length = false; + } + $context->register('CurrentLine', $current_line); + $context->register('CurrentCol', $current_col); + $nl = "\n"; + // how often to manually recalculate. This will ALWAYS be right, + // but it's pretty wasteful. Set to 0 to turn off + $synchronize_interval = $config->get('Core.DirectLexLineNumberSyncInterval'); + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + // for testing synchronization + $loops = 0; + + while (++$loops) { + // $cursor is either at the start of a token, or inside of + // a tag (i.e. there was a < immediately before it), as indicated + // by $inside_tag + + if ($maintain_line_numbers) { + // $rcursor, however, is always at the start of a token. + $rcursor = $cursor - (int)$inside_tag; + + // Column number is cheap, so we calculate it every round. + // We're interested at the *end* of the newline string, so + // we need to add strlen($nl) == 1 to $nl_pos before subtracting it + // from our "rcursor" position. + $nl_pos = strrpos($html, $nl, $rcursor - $length); + $current_col = $rcursor - (is_bool($nl_pos) ? 0 : $nl_pos + 1); + + // recalculate lines + if ($synchronize_interval && // synchronization is on + $cursor > 0 && // cursor is further than zero + $loops % $synchronize_interval === 0) { // time to synchronize! + $current_line = 1 + $this->substrCount($html, $nl, 0, $cursor); + } + } + + $position_next_lt = strpos($html, '<', $cursor); + $position_next_gt = strpos($html, '>', $cursor); + + // triggers on "asdf" but not "asdf " + // special case to set up context + if ($position_next_lt === $cursor) { + $inside_tag = true; + $cursor++; + } + + if (!$inside_tag && $position_next_lt !== false) { + // We are not inside tag and there still is another tag to parse + $token = new + HTMLPurifier_Token_Text( + $this->parseText( + substr( + $html, + $cursor, + $position_next_lt - $cursor + ), $config + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor); + } + $array[] = $token; + $cursor = $position_next_lt + 1; + $inside_tag = true; + continue; + } elseif (!$inside_tag) { + // We are not inside tag but there are no more tags + // If we're already at the end, break + if ($cursor === strlen($html)) { + break; + } + // Create Text of rest of string + $token = new + HTMLPurifier_Token_Text( + $this->parseText( + substr( + $html, + $cursor + ), $config + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + } + $array[] = $token; + break; + } elseif ($inside_tag && $position_next_gt !== false) { + // We are in tag and it is well formed + // Grab the internals of the tag + $strlen_segment = $position_next_gt - $cursor; + + if ($strlen_segment < 1) { + // there's nothing to process! + $token = new HTMLPurifier_Token_Text('<'); + $cursor++; + continue; + } + + $segment = substr($html, $cursor, $strlen_segment); + + if ($segment === false) { + // somehow, we attempted to access beyond the end of + // the string, defense-in-depth, reported by Nate Abele + break; + } + + // Check if it's a comment + if (substr($segment, 0, 3) === '!--') { + // re-determine segment length, looking for --> + $position_comment_end = strpos($html, '-->', $cursor); + if ($position_comment_end === false) { + // uh oh, we have a comment that extends to + // infinity. Can't be helped: set comment + // end position to end of string + if ($e) { + $e->send(E_WARNING, 'Lexer: Unclosed comment'); + } + $position_comment_end = strlen($html); + $end = true; + } else { + $end = false; + } + $strlen_segment = $position_comment_end - $cursor; + $segment = substr($html, $cursor, $strlen_segment); + $token = new + HTMLPurifier_Token_Comment( + substr( + $segment, + 3, + $strlen_segment - 3 + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment); + } + $array[] = $token; + $cursor = $end ? $position_comment_end : $position_comment_end + 3; + $inside_tag = false; + continue; + } + + // Check if it's an end tag + $is_end_tag = (strpos($segment, '/') === 0); + if ($is_end_tag) { + $type = substr($segment, 1); + $token = new HTMLPurifier_Token_End($type); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + $cursor = $position_next_gt + 1; + continue; + } + + // Check leading character is alnum, if not, we may + // have accidently grabbed an emoticon. Translate into + // text and go our merry way + if (!ctype_alpha($segment[0])) { + // XML: $segment[0] !== '_' && $segment[0] !== ':' + if ($e) { + $e->send(E_NOTICE, 'Lexer: Unescaped lt'); + } + $token = new HTMLPurifier_Token_Text('<'); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + continue; + } + + // Check if it is explicitly self closing, if so, remove + // trailing slash. Remember, we could have a tag like
        , so + // any later token processing scripts must convert improperly + // classified EmptyTags from StartTags. + $is_self_closing = (strrpos($segment, '/') === $strlen_segment - 1); + if ($is_self_closing) { + $strlen_segment--; + $segment = substr($segment, 0, $strlen_segment); + } + + // Check if there are any attributes + $position_first_space = strcspn($segment, $this->_whitespace); + + if ($position_first_space >= $strlen_segment) { + if ($is_self_closing) { + $token = new HTMLPurifier_Token_Empty($segment); + } else { + $token = new HTMLPurifier_Token_Start($segment); + } + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + $cursor = $position_next_gt + 1; + continue; + } + + // Grab out all the data + $type = substr($segment, 0, $position_first_space); + $attribute_string = + trim( + substr( + $segment, + $position_first_space + ) + ); + if ($attribute_string) { + $attr = $this->parseAttributeString( + $attribute_string, + $config, + $context + ); + } else { + $attr = array(); + } + + if ($is_self_closing) { + $token = new HTMLPurifier_Token_Empty($type, $attr); + } else { + $token = new HTMLPurifier_Token_Start($type, $attr); + } + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $cursor = $position_next_gt + 1; + $inside_tag = false; + continue; + } else { + // inside tag, but there's no ending > sign + if ($e) { + $e->send(E_WARNING, 'Lexer: Missing gt'); + } + $token = new + HTMLPurifier_Token_Text( + '<' . + $this->parseText( + substr($html, $cursor), $config + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + } + // no cursor scroll? Hmm... + $array[] = $token; + break; + } + break; + } + + $context->destroy('CurrentLine'); + $context->destroy('CurrentCol'); + return $array; + } + + /** + * PHP 5.0.x compatible substr_count that implements offset and length + * @param string $haystack + * @param string $needle + * @param int $offset + * @param int $length + * @return int + */ + protected function substrCount($haystack, $needle, $offset, $length) + { + static $oldVersion; + if ($oldVersion === null) { + $oldVersion = version_compare(PHP_VERSION, '5.1', '<'); + } + if ($oldVersion) { + $haystack = substr($haystack, $offset, $length); + return substr_count($haystack, $needle); + } else { + return substr_count($haystack, $needle, $offset, $length); + } + } + + /** + * Takes the inside of an HTML tag and makes an assoc array of attributes. + * + * @param string $string Inside of tag excluding name. + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array Assoc array of attributes. + */ + public function parseAttributeString($string, $config, $context) + { + $string = (string)$string; // quick typecast + + if ($string == '') { + return array(); + } // no attributes + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + // let's see if we can abort as quickly as possible + // one equal sign, no spaces => one attribute + $num_equal = substr_count($string, '='); + $has_space = strpos($string, ' '); + if ($num_equal === 0 && !$has_space) { + // bool attribute + return array($string => $string); + } elseif ($num_equal === 1 && !$has_space) { + // only one attribute + list($key, $quoted_value) = explode('=', $string); + $quoted_value = trim($quoted_value); + if (!$key) { + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } + return array(); + } + if (!$quoted_value) { + return array($key => ''); + } + $first_char = @$quoted_value[0]; + $last_char = @$quoted_value[strlen($quoted_value) - 1]; + + $same_quote = ($first_char == $last_char); + $open_quote = ($first_char == '"' || $first_char == "'"); + + if ($same_quote && $open_quote) { + // well behaved + $value = substr($quoted_value, 1, strlen($quoted_value) - 2); + } else { + // not well behaved + if ($open_quote) { + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing end quote'); + } + $value = substr($quoted_value, 1); + } else { + $value = $quoted_value; + } + } + if ($value === false) { + $value = ''; + } + return array($key => $this->parseAttr($value, $config)); + } + + // setup loop environment + $array = array(); // return assoc array of attributes + $cursor = 0; // current position in string (moves forward) + $size = strlen($string); // size of the string (stays the same) + + // if we have unquoted attributes, the parser expects a terminating + // space, so let's guarantee that there's always a terminating space. + $string .= ' '; + + $old_cursor = -1; + while ($cursor < $size) { + if ($old_cursor >= $cursor) { + throw new Exception("Infinite loop detected"); + } + $old_cursor = $cursor; + + $cursor += ($value = strspn($string, $this->_whitespace, $cursor)); + // grab the key + + $key_begin = $cursor; //we're currently at the start of the key + + // scroll past all characters that are the key (not whitespace or =) + $cursor += strcspn($string, $this->_whitespace . '=', $cursor); + + $key_end = $cursor; // now at the end of the key + + $key = substr($string, $key_begin, $key_end - $key_begin); + + if (!$key) { + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } + $cursor += 1 + strcspn($string, $this->_whitespace, $cursor + 1); // prevent infinite loop + continue; // empty key + } + + // scroll past all whitespace + $cursor += strspn($string, $this->_whitespace, $cursor); + + if ($cursor >= $size) { + $array[$key] = $key; + break; + } + + // if the next character is an equal sign, we've got a regular + // pair, otherwise, it's a bool attribute + $first_char = @$string[$cursor]; + + if ($first_char == '=') { + // key="value" + + $cursor++; + $cursor += strspn($string, $this->_whitespace, $cursor); + + if ($cursor === false) { + $array[$key] = ''; + break; + } + + // we might be in front of a quote right now + + $char = @$string[$cursor]; + + if ($char == '"' || $char == "'") { + // it's quoted, end bound is $char + $cursor++; + $value_begin = $cursor; + $cursor = strpos($string, $char, $cursor); + $value_end = $cursor; + } else { + // it's not quoted, end bound is whitespace + $value_begin = $cursor; + $cursor += strcspn($string, $this->_whitespace, $cursor); + $value_end = $cursor; + } + + // we reached a premature end + if ($cursor === false) { + $cursor = $size; + $value_end = $cursor; + } + + $value = substr($string, $value_begin, $value_end - $value_begin); + if ($value === false) { + $value = ''; + } + $array[$key] = $this->parseAttr($value, $config); + $cursor++; + } else { + // boolattr + if ($key !== '') { + $array[$key] = $key; + } else { + // purely theoretical + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } + } + } + } + return $array; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php new file mode 100644 index 0000000..1564f28 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Lexer/PH5P.php @@ -0,0 +1,4788 @@ +normalize($html, $config, $context); + $new_html = $this->wrapHTML($new_html, $config, $context, false /* no div */); + try { + $parser = new HTML5($new_html); + $doc = $parser->save(); + } catch (DOMException $e) { + // Uh oh, it failed. Punt to DirectLex. + $lexer = new HTMLPurifier_Lexer_DirectLex(); + $context->register('PH5PError', $e); // save the error, so we can detect it + return $lexer->tokenizeHTML($html, $config, $context); // use original HTML + } + $tokens = array(); + $this->tokenizeDOM( + $doc->getElementsByTagName('html')->item(0)-> // + getElementsByTagName('body')->item(0) // + , + $tokens, $config + ); + return $tokens; + } +} + +/* + +Copyright 2007 Jeroen van der Meer + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +class HTML5 +{ + private $data; + private $char; + private $EOF; + private $state; + private $tree; + private $token; + private $content_model; + private $escape = false; + private $entities = array( + 'AElig;', + 'AElig', + 'AMP;', + 'AMP', + 'Aacute;', + 'Aacute', + 'Acirc;', + 'Acirc', + 'Agrave;', + 'Agrave', + 'Alpha;', + 'Aring;', + 'Aring', + 'Atilde;', + 'Atilde', + 'Auml;', + 'Auml', + 'Beta;', + 'COPY;', + 'COPY', + 'Ccedil;', + 'Ccedil', + 'Chi;', + 'Dagger;', + 'Delta;', + 'ETH;', + 'ETH', + 'Eacute;', + 'Eacute', + 'Ecirc;', + 'Ecirc', + 'Egrave;', + 'Egrave', + 'Epsilon;', + 'Eta;', + 'Euml;', + 'Euml', + 'GT;', + 'GT', + 'Gamma;', + 'Iacute;', + 'Iacute', + 'Icirc;', + 'Icirc', + 'Igrave;', + 'Igrave', + 'Iota;', + 'Iuml;', + 'Iuml', + 'Kappa;', + 'LT;', + 'LT', + 'Lambda;', + 'Mu;', + 'Ntilde;', + 'Ntilde', + 'Nu;', + 'OElig;', + 'Oacute;', + 'Oacute', + 'Ocirc;', + 'Ocirc', + 'Ograve;', + 'Ograve', + 'Omega;', + 'Omicron;', + 'Oslash;', + 'Oslash', + 'Otilde;', + 'Otilde', + 'Ouml;', + 'Ouml', + 'Phi;', + 'Pi;', + 'Prime;', + 'Psi;', + 'QUOT;', + 'QUOT', + 'REG;', + 'REG', + 'Rho;', + 'Scaron;', + 'Sigma;', + 'THORN;', + 'THORN', + 'TRADE;', + 'Tau;', + 'Theta;', + 'Uacute;', + 'Uacute', + 'Ucirc;', + 'Ucirc', + 'Ugrave;', + 'Ugrave', + 'Upsilon;', + 'Uuml;', + 'Uuml', + 'Xi;', + 'Yacute;', + 'Yacute', + 'Yuml;', + 'Zeta;', + 'aacute;', + 'aacute', + 'acirc;', + 'acirc', + 'acute;', + 'acute', + 'aelig;', + 'aelig', + 'agrave;', + 'agrave', + 'alefsym;', + 'alpha;', + 'amp;', + 'amp', + 'and;', + 'ang;', + 'apos;', + 'aring;', + 'aring', + 'asymp;', + 'atilde;', + 'atilde', + 'auml;', + 'auml', + 'bdquo;', + 'beta;', + 'brvbar;', + 'brvbar', + 'bull;', + 'cap;', + 'ccedil;', + 'ccedil', + 'cedil;', + 'cedil', + 'cent;', + 'cent', + 'chi;', + 'circ;', + 'clubs;', + 'cong;', + 'copy;', + 'copy', + 'crarr;', + 'cup;', + 'curren;', + 'curren', + 'dArr;', + 'dagger;', + 'darr;', + 'deg;', + 'deg', + 'delta;', + 'diams;', + 'divide;', + 'divide', + 'eacute;', + 'eacute', + 'ecirc;', + 'ecirc', + 'egrave;', + 'egrave', + 'empty;', + 'emsp;', + 'ensp;', + 'epsilon;', + 'equiv;', + 'eta;', + 'eth;', + 'eth', + 'euml;', + 'euml', + 'euro;', + 'exist;', + 'fnof;', + 'forall;', + 'frac12;', + 'frac12', + 'frac14;', + 'frac14', + 'frac34;', + 'frac34', + 'frasl;', + 'gamma;', + 'ge;', + 'gt;', + 'gt', + 'hArr;', + 'harr;', + 'hearts;', + 'hellip;', + 'iacute;', + 'iacute', + 'icirc;', + 'icirc', + 'iexcl;', + 'iexcl', + 'igrave;', + 'igrave', + 'image;', + 'infin;', + 'int;', + 'iota;', + 'iquest;', + 'iquest', + 'isin;', + 'iuml;', + 'iuml', + 'kappa;', + 'lArr;', + 'lambda;', + 'lang;', + 'laquo;', + 'laquo', + 'larr;', + 'lceil;', + 'ldquo;', + 'le;', + 'lfloor;', + 'lowast;', + 'loz;', + 'lrm;', + 'lsaquo;', + 'lsquo;', + 'lt;', + 'lt', + 'macr;', + 'macr', + 'mdash;', + 'micro;', + 'micro', + 'middot;', + 'middot', + 'minus;', + 'mu;', + 'nabla;', + 'nbsp;', + 'nbsp', + 'ndash;', + 'ne;', + 'ni;', + 'not;', + 'not', + 'notin;', + 'nsub;', + 'ntilde;', + 'ntilde', + 'nu;', + 'oacute;', + 'oacute', + 'ocirc;', + 'ocirc', + 'oelig;', + 'ograve;', + 'ograve', + 'oline;', + 'omega;', + 'omicron;', + 'oplus;', + 'or;', + 'ordf;', + 'ordf', + 'ordm;', + 'ordm', + 'oslash;', + 'oslash', + 'otilde;', + 'otilde', + 'otimes;', + 'ouml;', + 'ouml', + 'para;', + 'para', + 'part;', + 'permil;', + 'perp;', + 'phi;', + 'pi;', + 'piv;', + 'plusmn;', + 'plusmn', + 'pound;', + 'pound', + 'prime;', + 'prod;', + 'prop;', + 'psi;', + 'quot;', + 'quot', + 'rArr;', + 'radic;', + 'rang;', + 'raquo;', + 'raquo', + 'rarr;', + 'rceil;', + 'rdquo;', + 'real;', + 'reg;', + 'reg', + 'rfloor;', + 'rho;', + 'rlm;', + 'rsaquo;', + 'rsquo;', + 'sbquo;', + 'scaron;', + 'sdot;', + 'sect;', + 'sect', + 'shy;', + 'shy', + 'sigma;', + 'sigmaf;', + 'sim;', + 'spades;', + 'sub;', + 'sube;', + 'sum;', + 'sup1;', + 'sup1', + 'sup2;', + 'sup2', + 'sup3;', + 'sup3', + 'sup;', + 'supe;', + 'szlig;', + 'szlig', + 'tau;', + 'there4;', + 'theta;', + 'thetasym;', + 'thinsp;', + 'thorn;', + 'thorn', + 'tilde;', + 'times;', + 'times', + 'trade;', + 'uArr;', + 'uacute;', + 'uacute', + 'uarr;', + 'ucirc;', + 'ucirc', + 'ugrave;', + 'ugrave', + 'uml;', + 'uml', + 'upsih;', + 'upsilon;', + 'uuml;', + 'uuml', + 'weierp;', + 'xi;', + 'yacute;', + 'yacute', + 'yen;', + 'yen', + 'yuml;', + 'yuml', + 'zeta;', + 'zwj;', + 'zwnj;' + ); + + const PCDATA = 0; + const RCDATA = 1; + const CDATA = 2; + const PLAINTEXT = 3; + + const DOCTYPE = 0; + const STARTTAG = 1; + const ENDTAG = 2; + const COMMENT = 3; + const CHARACTR = 4; + const EOF = 5; + + public function __construct($data) + { + $this->data = $data; + $this->char = -1; + $this->EOF = strlen($data); + $this->tree = new HTML5TreeConstructer; + $this->content_model = self::PCDATA; + + $this->state = 'data'; + + while ($this->state !== null) { + $this->{$this->state . 'State'}(); + } + } + + public function save() + { + return $this->tree->save(); + } + + private function char() + { + return ($this->char < $this->EOF) + ? $this->data[$this->char] + : false; + } + + private function character($s, $l = 0) + { + if ($s + $l < $this->EOF) { + if ($l === 0) { + return $this->data[$s]; + } else { + return substr($this->data, $s, $l); + } + } + } + + private function characters($char_class, $start) + { + return preg_replace('#^([' . $char_class . ']+).*#s', '\\1', substr($this->data, $start)); + } + + private function dataState() + { + // Consume the next input character + $this->char++; + $char = $this->char(); + + if ($char === '&' && ($this->content_model === self::PCDATA || $this->content_model === self::RCDATA)) { + /* U+0026 AMPERSAND (&) + When the content model flag is set to one of the PCDATA or RCDATA + states: switch to the entity data state. Otherwise: treat it as per + the "anything else" entry below. */ + $this->state = 'entityData'; + + } elseif ($char === '-') { + /* If the content model flag is set to either the RCDATA state or + the CDATA state, and the escape flag is false, and there are at + least three characters before this one in the input stream, and the + last four characters in the input stream, including this one, are + U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, + and U+002D HYPHEN-MINUS (""), + set the escape flag to false. */ + if (($this->content_model === self::RCDATA || + $this->content_model === self::CDATA) && $this->escape === true && + $this->character($this->char, 3) === '-->' + ) { + $this->escape = false; + } + + /* In any case, emit the input character as a character token. + Stay in the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); + + } elseif ($this->char === $this->EOF) { + /* EOF + Emit an end-of-file token. */ + $this->EOF(); + + } elseif ($this->content_model === self::PLAINTEXT) { + /* When the content model flag is set to the PLAINTEXT state + THIS DIFFERS GREATLY FROM THE SPEC: Get the remaining characters of + the text and emit it as a character token. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => substr($this->data, $this->char) + ) + ); + + $this->EOF(); + + } else { + /* Anything else + THIS DIFFERS GREATLY FROM THE SPEC: Get as many character that + otherwise would also be treated as a character token and emit it + as a single character token. Stay in the data state. */ + $len = strcspn($this->data, '<&', $this->char); + $char = substr($this->data, $this->char, $len); + $this->char += $len - 1; + + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); + + $this->state = 'data'; + } + } + + private function entityDataState() + { + // Attempt to consume an entity. + $entity = $this->entity(); + + // If nothing is returned, emit a U+0026 AMPERSAND character token. + // Otherwise, emit the character token that was returned. + $char = (!$entity) ? '&' : $entity; + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); + + // Finally, switch to the data state. + $this->state = 'data'; + } + + private function tagOpenState() + { + switch ($this->content_model) { + case self::RCDATA: + case self::CDATA: + /* If the next input character is a U+002F SOLIDUS (/) character, + consume it and switch to the close tag open state. If the next + input character is not a U+002F SOLIDUS (/) character, emit a + U+003C LESS-THAN SIGN character token and switch to the data + state to process the next input character. */ + if ($this->character($this->char + 1) === '/') { + $this->char++; + $this->state = 'closeTagOpen'; + + } else { + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<' + ) + ); + + $this->state = 'data'; + } + break; + + case self::PCDATA: + // If the content model flag is set to the PCDATA state + // Consume the next input character: + $this->char++; + $char = $this->char(); + + if ($char === '!') { + /* U+0021 EXCLAMATION MARK (!) + Switch to the markup declaration open state. */ + $this->state = 'markupDeclarationOpen'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the close tag open state. */ + $this->state = 'closeTagOpen'; + + } elseif (preg_match('/^[A-Za-z]$/', $char)) { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new start tag token, set its tag name to the lowercase + version of the input character (add 0x0020 to the character's code + point), then switch to the tag name state. (Don't emit the token + yet; further details will be filled in before it is emitted.) */ + $this->token = array( + 'name' => strtolower($char), + 'type' => self::STARTTAG, + 'attr' => array() + ); + + $this->state = 'tagName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Emit a U+003C LESS-THAN SIGN character token and a + U+003E GREATER-THAN SIGN character token. Switch to the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<>' + ) + ); + + $this->state = 'data'; + + } elseif ($char === '?') { + /* U+003F QUESTION MARK (?) + Parse error. Switch to the bogus comment state. */ + $this->state = 'bogusComment'; + + } else { + /* Anything else + Parse error. Emit a U+003C LESS-THAN SIGN character token and + reconsume the current input character in the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<' + ) + ); + + $this->char--; + $this->state = 'data'; + } + break; + } + } + + private function closeTagOpenState() + { + $next_node = strtolower($this->characters('A-Za-z', $this->char + 1)); + $the_same = count($this->tree->stack) > 0 && $next_node === end($this->tree->stack)->nodeName; + + if (($this->content_model === self::RCDATA || $this->content_model === self::CDATA) && + (!$the_same || ($the_same && (!preg_match( + '/[\t\n\x0b\x0c >\/]/', + $this->character($this->char + 1 + strlen($next_node)) + ) || $this->EOF === $this->char))) + ) { + /* If the content model flag is set to the RCDATA or CDATA states then + examine the next few characters. If they do not match the tag name of + the last start tag token emitted (case insensitively), or if they do but + they are not immediately followed by one of the following characters: + * U+0009 CHARACTER TABULATION + * U+000A LINE FEED (LF) + * U+000B LINE TABULATION + * U+000C FORM FEED (FF) + * U+0020 SPACE + * U+003E GREATER-THAN SIGN (>) + * U+002F SOLIDUS (/) + * EOF + ...then there is a parse error. Emit a U+003C LESS-THAN SIGN character + token, a U+002F SOLIDUS character token, and switch to the data state + to process the next input character. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => 'state = 'data'; + + } else { + /* Otherwise, if the content model flag is set to the PCDATA state, + or if the next few characters do match that tag name, consume the + next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[A-Za-z]$/', $char)) { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new end tag token, set its tag name to the lowercase version + of the input character (add 0x0020 to the character's code point), then + switch to the tag name state. (Don't emit the token yet; further details + will be filled in before it is emitted.) */ + $this->token = array( + 'name' => strtolower($char), + 'type' => self::ENDTAG + ); + + $this->state = 'tagName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Switch to the data state. */ + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F + SOLIDUS character token. Reconsume the EOF character in the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => 'char--; + $this->state = 'data'; + + } else { + /* Parse error. Switch to the bogus comment state. */ + $this->state = 'bogusComment'; + } + } + } + + private function tagNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } else { + /* Anything else + Append the current input character to the current tag token's tag name. + Stay in the tag name state. */ + $this->token['name'] .= strtolower($char); + $this->state = 'tagName'; + } + } + + private function beforeAttributeNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Stay in the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = array( + 'name' => strtolower($char), + 'value' => null + ); + + $this->state = 'attributeName'; + } + } + + private function attributeNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute name state. */ + $this->state = 'afterAttributeName'; + + } elseif ($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '/' && $this->character($this->char + 1) !== '>') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's name. + Stay in the attribute name state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['name'] .= strtolower($char); + + $this->state = 'attributeName'; + } + } + + private function afterAttributeNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the after attribute name state. */ + $this->state = 'afterAttributeName'; + + } elseif ($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '/' && $this->character($this->char + 1) !== '>') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the + before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = array( + 'name' => strtolower($char), + 'value' => null + ); + + $this->state = 'attributeName'; + } + } + + private function beforeAttributeValueState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the attribute value (double-quoted) state. */ + $this->state = 'attributeValueDoubleQuoted'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the attribute value (unquoted) state and reconsume + this input character. */ + $this->char--; + $this->state = 'attributeValueUnquoted'; + + } elseif ($char === '\'') { + /* U+0027 APOSTROPHE (') + Switch to the attribute value (single-quoted) state. */ + $this->state = 'attributeValueSingleQuoted'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Switch to the attribute value (unquoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueUnquoted'; + } + } + + private function attributeValueDoubleQuotedState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState('double'); + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the character + in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (double-quoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueDoubleQuoted'; + } + } + + private function attributeValueSingleQuotedState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if ($char === '\'') { + /* U+0022 QUOTATION MARK (') + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState('single'); + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the character + in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (single-quoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueSingleQuoted'; + } + } + + private function attributeValueUnquotedState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState(); + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (unquoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueUnquoted'; + } + } + + private function entityInAttributeValueState() + { + // Attempt to consume an entity. + $entity = $this->entity(); + + // If nothing is returned, append a U+0026 AMPERSAND character to the + // current attribute's value. Otherwise, emit the character token that + // was returned. + $char = (!$entity) + ? '&' + : $entity; + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + } + + private function bogusCommentState() + { + /* Consume every character up to the first U+003E GREATER-THAN SIGN + character (>) or the end of the file (EOF), whichever comes first. Emit + a comment token whose data is the concatenation of all the characters + starting from and including the character that caused the state machine + to switch into the bogus comment state, up to and including the last + consumed character before the U+003E character, if any, or up to the + end of the file otherwise. (If the comment was started by the end of + the file (EOF), the token is empty.) */ + $data = $this->characters('^>', $this->char); + $this->emitToken( + array( + 'data' => $data, + 'type' => self::COMMENT + ) + ); + + $this->char += strlen($data); + + /* Switch to the data state. */ + $this->state = 'data'; + + /* If the end of the file was reached, reconsume the EOF character. */ + if ($this->char === $this->EOF) { + $this->char = $this->EOF - 1; + } + } + + private function markupDeclarationOpenState() + { + /* If the next two characters are both U+002D HYPHEN-MINUS (-) + characters, consume those two characters, create a comment token whose + data is the empty string, and switch to the comment state. */ + if ($this->character($this->char + 1, 2) === '--') { + $this->char += 2; + $this->state = 'comment'; + $this->token = array( + 'data' => null, + 'type' => self::COMMENT + ); + + /* Otherwise if the next seven chacacters are a case-insensitive match + for the word "DOCTYPE", then consume those characters and switch to the + DOCTYPE state. */ + } elseif (strtolower($this->character($this->char + 1, 7)) === 'doctype') { + $this->char += 7; + $this->state = 'doctype'; + + /* Otherwise, is is a parse error. Switch to the bogus comment state. + The next character that is consumed, if any, is the first character + that will be in the comment. */ + } else { + $this->char++; + $this->state = 'bogusComment'; + } + } + + private function commentState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + /* U+002D HYPHEN-MINUS (-) */ + if ($char === '-') { + /* Switch to the comment dash state */ + $this->state = 'commentDash'; + + /* EOF */ + } elseif ($this->char === $this->EOF) { + /* Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + /* Anything else */ + } else { + /* Append the input character to the comment token's data. Stay in + the comment state. */ + $this->token['data'] .= $char; + } + } + + private function commentDashState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + /* U+002D HYPHEN-MINUS (-) */ + if ($char === '-') { + /* Switch to the comment end state */ + $this->state = 'commentEnd'; + + /* EOF */ + } elseif ($this->char === $this->EOF) { + /* Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + /* Anything else */ + } else { + /* Append a U+002D HYPHEN-MINUS (-) character and the input + character to the comment token's data. Switch to the comment state. */ + $this->token['data'] .= '-' . $char; + $this->state = 'comment'; + } + } + + private function commentEndState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '-') { + $this->token['data'] .= '-'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['data'] .= '--' . $char; + $this->state = 'comment'; + } + } + + private function doctypeState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + $this->state = 'beforeDoctypeName'; + + } else { + $this->char--; + $this->state = 'beforeDoctypeName'; + } + } + + private function beforeDoctypeNameState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + // Stay in the before DOCTYPE name state. + + } elseif (preg_match('/^[a-z]$/', $char)) { + $this->token = array( + 'name' => strtoupper($char), + 'type' => self::DOCTYPE, + 'error' => true + ); + + $this->state = 'doctypeName'; + + } elseif ($char === '>') { + $this->emitToken( + array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + ) + ); + + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken( + array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + ) + ); + + $this->char--; + $this->state = 'data'; + + } else { + $this->token = array( + 'name' => $char, + 'type' => self::DOCTYPE, + 'error' => true + ); + + $this->state = 'doctypeName'; + } + } + + private function doctypeNameState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + $this->state = 'AfterDoctypeName'; + + } elseif ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif (preg_match('/^[a-z]$/', $char)) { + $this->token['name'] .= strtoupper($char); + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['name'] .= $char; + } + + $this->token['error'] = ($this->token['name'] === 'HTML') + ? false + : true; + } + + private function afterDoctypeNameState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + // Stay in the DOCTYPE name state. + + } elseif ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['error'] = true; + $this->state = 'bogusDoctype'; + } + } + + private function bogusDoctypeState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + // Stay in the bogus DOCTYPE state. + } + } + + private function entity() + { + $start = $this->char; + + // This section defines how to consume an entity. This definition is + // used when parsing entities in text and in attributes. + + // The behaviour depends on the identity of the next character (the + // one immediately after the U+0026 AMPERSAND character): + + switch ($this->character($this->char + 1)) { + // U+0023 NUMBER SIGN (#) + case '#': + + // The behaviour further depends on the character after the + // U+0023 NUMBER SIGN: + switch ($this->character($this->char + 1)) { + // U+0078 LATIN SMALL LETTER X + // U+0058 LATIN CAPITAL LETTER X + case 'x': + case 'X': + // Follow the steps below, but using the range of + // characters U+0030 DIGIT ZERO through to U+0039 DIGIT + // NINE, U+0061 LATIN SMALL LETTER A through to U+0066 + // LATIN SMALL LETTER F, and U+0041 LATIN CAPITAL LETTER + // A, through to U+0046 LATIN CAPITAL LETTER F (in other + // words, 0-9, A-F, a-f). + $char = 1; + $char_class = '0-9A-Fa-f'; + break; + + // Anything else + default: + // Follow the steps below, but using the range of + // characters U+0030 DIGIT ZERO through to U+0039 DIGIT + // NINE (i.e. just 0-9). + $char = 0; + $char_class = '0-9'; + break; + } + + // Consume as many characters as match the range of characters + // given above. + $this->char++; + $e_name = $this->characters($char_class, $this->char + $char + 1); + $entity = $this->character($start, $this->char); + $cond = strlen($e_name) > 0; + + // The rest of the parsing happens below. + break; + + // Anything else + default: + // Consume the maximum number of characters possible, with the + // consumed characters case-sensitively matching one of the + // identifiers in the first column of the entities table. + + $e_name = $this->characters('0-9A-Za-z;', $this->char + 1); + $len = strlen($e_name); + + for ($c = 1; $c <= $len; $c++) { + $id = substr($e_name, 0, $c); + $this->char++; + + if (in_array($id, $this->entities)) { + if ($e_name[$c - 1] !== ';') { + if ($c < $len && $e_name[$c] == ';') { + $this->char++; // consume extra semicolon + } + } + $entity = $id; + break; + } + } + + $cond = isset($entity); + // The rest of the parsing happens below. + break; + } + + if (!$cond) { + // If no match can be made, then this is a parse error. No + // characters are consumed, and nothing is returned. + $this->char = $start; + return false; + } + + // Return a character token for the character corresponding to the + // entity name (as given by the second column of the entities table). + return html_entity_decode('&' . rtrim($entity, ';') . ';', ENT_QUOTES, 'UTF-8'); + } + + private function emitToken($token) + { + $emit = $this->tree->emitToken($token); + + if (is_int($emit)) { + $this->content_model = $emit; + + } elseif ($token['type'] === self::ENDTAG) { + $this->content_model = self::PCDATA; + } + } + + private function EOF() + { + $this->state = null; + $this->tree->emitToken( + array( + 'type' => self::EOF + ) + ); + } +} + +class HTML5TreeConstructer +{ + public $stack = array(); + + private $phase; + private $mode; + private $dom; + private $foster_parent = null; + private $a_formatting = array(); + + private $head_pointer = null; + private $form_pointer = null; + + private $scoping = array('button', 'caption', 'html', 'marquee', 'object', 'table', 'td', 'th'); + private $formatting = array( + 'a', + 'b', + 'big', + 'em', + 'font', + 'i', + 'nobr', + 's', + 'small', + 'strike', + 'strong', + 'tt', + 'u' + ); + private $special = array( + 'address', + 'area', + 'base', + 'basefont', + 'bgsound', + 'blockquote', + 'body', + 'br', + 'center', + 'col', + 'colgroup', + 'dd', + 'dir', + 'div', + 'dl', + 'dt', + 'embed', + 'fieldset', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'hr', + 'iframe', + 'image', + 'img', + 'input', + 'isindex', + 'li', + 'link', + 'listing', + 'menu', + 'meta', + 'noembed', + 'noframes', + 'noscript', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'plaintext', + 'pre', + 'script', + 'select', + 'spacer', + 'style', + 'tbody', + 'textarea', + 'tfoot', + 'thead', + 'title', + 'tr', + 'ul', + 'wbr' + ); + + // The different phases. + const INIT_PHASE = 0; + const ROOT_PHASE = 1; + const MAIN_PHASE = 2; + const END_PHASE = 3; + + // The different insertion modes for the main phase. + const BEFOR_HEAD = 0; + const IN_HEAD = 1; + const AFTER_HEAD = 2; + const IN_BODY = 3; + const IN_TABLE = 4; + const IN_CAPTION = 5; + const IN_CGROUP = 6; + const IN_TBODY = 7; + const IN_ROW = 8; + const IN_CELL = 9; + const IN_SELECT = 10; + const AFTER_BODY = 11; + const IN_FRAME = 12; + const AFTR_FRAME = 13; + + // The different types of elements. + const SPECIAL = 0; + const SCOPING = 1; + const FORMATTING = 2; + const PHRASING = 3; + + const MARKER = 0; + + public function __construct() + { + $this->phase = self::INIT_PHASE; + $this->mode = self::BEFOR_HEAD; + $this->dom = new DOMDocument; + + $this->dom->encoding = 'UTF-8'; + $this->dom->preserveWhiteSpace = true; + $this->dom->substituteEntities = true; + $this->dom->strictErrorChecking = false; + } + + // Process tag tokens + public function emitToken($token) + { + switch ($this->phase) { + case self::INIT_PHASE: + return $this->initPhase($token); + break; + case self::ROOT_PHASE: + return $this->rootElementPhase($token); + break; + case self::MAIN_PHASE: + return $this->mainPhase($token); + break; + case self::END_PHASE : + return $this->trailingEndPhase($token); + break; + } + } + + private function initPhase($token) + { + /* Initially, the tree construction stage must handle each token + emitted from the tokenisation stage as follows: */ + + /* A DOCTYPE token that is marked as being in error + A comment token + A start tag token + An end tag token + A character token that is not one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE + An end-of-file token */ + if ((isset($token['error']) && $token['error']) || + $token['type'] === HTML5::COMMENT || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF || + ($token['type'] === HTML5::CHARACTR && isset($token['data']) && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) + ) { + /* This specification does not define how to handle this case. In + particular, user agents may ignore the entirety of this specification + altogether for such documents, and instead invoke special parse modes + with a greater emphasis on backwards compatibility. */ + + $this->phase = self::ROOT_PHASE; + return $this->rootElementPhase($token); + + /* A DOCTYPE token marked as being correct */ + } elseif (isset($token['error']) && !$token['error']) { + /* Append a DocumentType node to the Document node, with the name + attribute set to the name given in the DOCTYPE token (which will be + "HTML"), and the other attributes specific to DocumentType objects + set to null, empty lists, or the empty string as appropriate. */ + $doctype = new DOMDocumentType(null, null, 'HTML'); + + /* Then, switch to the root element phase of the tree construction + stage. */ + $this->phase = self::ROOT_PHASE; + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif (isset($token['data']) && preg_match( + '/^[\t\n\x0b\x0c ]+$/', + $token['data'] + ) + ) { + /* Append that character to the Document node. */ + $text = $this->dom->createTextNode($token['data']); + $this->dom->appendChild($text); + } + } + + private function rootElementPhase($token) + { + /* After the initial phase, as each token is emitted from the tokenisation + stage, it must be processed as described in this section. */ + + /* A DOCTYPE token */ + if ($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the Document object with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->dom->appendChild($comment); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append that character to the Document node. */ + $text = $this->dom->createTextNode($token['data']); + $this->dom->appendChild($text); + + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED + (FF), or U+0020 SPACE + A start tag token + An end tag token + An end-of-file token */ + } elseif (($token['type'] === HTML5::CHARACTR && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF + ) { + /* Create an HTMLElement node with the tag name html, in the HTML + namespace. Append it to the Document object. Switch to the main + phase and reprocess the current token. */ + $html = $this->dom->createElement('html'); + $this->dom->appendChild($html); + $this->stack[] = $html; + + $this->phase = self::MAIN_PHASE; + return $this->mainPhase($token); + } + } + + private function mainPhase($token) + { + /* Tokens in the main phase must be handled as follows: */ + + /* A DOCTYPE token */ + if ($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A start tag token with the tag name "html" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') { + /* If this start tag token was not the first start tag token, then + it is a parse error. */ + + /* For each attribute on the token, check to see if the attribute + is already present on the top element of the stack of open elements. + If it is not, add the attribute and its corresponding value to that + element. */ + foreach ($token['attr'] as $attr) { + if (!$this->stack[0]->hasAttribute($attr['name'])) { + $this->stack[0]->setAttribute($attr['name'], $attr['value']); + } + } + + /* An end-of-file token */ + } elseif ($token['type'] === HTML5::EOF) { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Anything else. */ + } else { + /* Depends on the insertion mode: */ + switch ($this->mode) { + case self::BEFOR_HEAD: + return $this->beforeHead($token); + break; + case self::IN_HEAD: + return $this->inHead($token); + break; + case self::AFTER_HEAD: + return $this->afterHead($token); + break; + case self::IN_BODY: + return $this->inBody($token); + break; + case self::IN_TABLE: + return $this->inTable($token); + break; + case self::IN_CAPTION: + return $this->inCaption($token); + break; + case self::IN_CGROUP: + return $this->inColumnGroup($token); + break; + case self::IN_TBODY: + return $this->inTableBody($token); + break; + case self::IN_ROW: + return $this->inRow($token); + break; + case self::IN_CELL: + return $this->inCell($token); + break; + case self::IN_SELECT: + return $this->inSelect($token); + break; + case self::AFTER_BODY: + return $this->afterBody($token); + break; + case self::IN_FRAME: + return $this->inFrameset($token); + break; + case self::AFTR_FRAME: + return $this->afterFrameset($token); + break; + case self::END_PHASE: + return $this->trailingEndPhase($token); + break; + } + } + } + + private function beforeHead($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token with the tag name "head" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') { + /* Create an element for the token, append the new element to the + current node and push it onto the stack of open elements. */ + $element = $this->insertElement($token); + + /* Set the head element pointer to this new element node. */ + $this->head_pointer = $element; + + /* Change the insertion mode to "in head". */ + $this->mode = self::IN_HEAD; + + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title". Or an end tag with the tag name "html". + Or a character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or any other start tag token */ + } elseif ($token['type'] === HTML5::STARTTAG || + ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') || + ($token['type'] === HTML5::CHARACTR && !preg_match( + '/^[\t\n\x0b\x0c ]$/', + $token['data'] + )) + ) { + /* Act as if a start tag token with the tag name "head" and no + attributes had been seen, then reprocess the current token. */ + $this->beforeHead( + array( + 'name' => 'head', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inHead($token); + + /* Any other end tag */ + } elseif ($token['type'] === HTML5::ENDTAG) { + /* Parse error. Ignore the token. */ + } + } + + private function inHead($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. + + THIS DIFFERS FROM THE SPEC: If the current node is either a title, style + or script element, append the character to the current node regardless + of its content. */ + if (($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || ( + $token['type'] === HTML5::CHARACTR && in_array( + end($this->stack)->nodeName, + array('title', 'style', 'script') + )) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('title', 'style', 'script')) + ) { + array_pop($this->stack); + return HTML5::PCDATA; + + /* A start tag with the tag name "title" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if ($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + } else { + $element = $this->insertElement($token); + } + + /* Switch the tokeniser's content model flag to the RCDATA state. */ + return HTML5::RCDATA; + + /* A start tag with the tag name "style" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if ($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + } else { + $this->insertElement($token); + } + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + + /* A start tag with the tag name "script" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') { + /* Create an element for the token. */ + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + + /* A start tag with the tag name "base", "link", or "meta" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('base', 'link', 'meta') + ) + ) { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if ($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + array_pop($this->stack); + + } else { + $this->insertElement($token); + } + + /* An end tag with the tag name "head" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') { + /* If the current node is a head element, pop the current node off + the stack of open elements. */ + if ($this->head_pointer->isSameNode(end($this->stack))) { + array_pop($this->stack); + + /* Otherwise, this is a parse error. */ + } else { + // k + } + + /* Change the insertion mode to "after head". */ + $this->mode = self::AFTER_HEAD; + + /* A start tag with the tag name "head" or an end tag except "html". */ + } elseif (($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') || + ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html') + ) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* If the current node is a head element, act as if an end tag + token with the tag name "head" had been seen. */ + if ($this->head_pointer->isSameNode(end($this->stack))) { + $this->inHead( + array( + 'name' => 'head', + 'type' => HTML5::ENDTAG + ) + ); + + /* Otherwise, change the insertion mode to "after head". */ + } else { + $this->mode = self::AFTER_HEAD; + } + + /* Then, reprocess the current token. */ + return $this->afterHead($token); + } + } + + private function afterHead($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token with the tag name "body" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') { + /* Insert a body element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in body". */ + $this->mode = self::IN_BODY; + + /* A start tag token with the tag name "frameset" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') { + /* Insert a frameset element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in frameset". */ + $this->mode = self::IN_FRAME; + + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('base', 'link', 'meta', 'script', 'style', 'title') + ) + ) { + /* Parse error. Switch the insertion mode back to "in head" and + reprocess the token. */ + $this->mode = self::IN_HEAD; + return $this->inHead($token); + + /* Anything else */ + } else { + /* Act as if a start tag token with the tag name "body" and no + attributes had been seen, and then reprocess the current token. */ + $this->afterHead( + array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inBody($token); + } + } + + private function inBody($token) + { + /* Handle the token as follows: */ + + switch ($token['type']) { + /* A character token */ + case HTML5::CHARACTR: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Append the token's character to the current node. */ + $this->insertText($token['data']); + break; + + /* A comment token */ + case HTML5::COMMENT: + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + break; + + case HTML5::STARTTAG: + switch ($token['name']) { + /* A start tag token whose tag name is one of: "script", + "style" */ + case 'script': + case 'style': + /* Process the token as if the insertion mode had been "in + head". */ + return $this->inHead($token); + break; + + /* A start tag token whose tag name is one of: "base", "link", + "meta", "title" */ + case 'base': + case 'link': + case 'meta': + case 'title': + /* Parse error. Process the token as if the insertion mode + had been "in head". */ + return $this->inHead($token); + break; + + /* A start tag token with the tag name "body" */ + case 'body': + /* Parse error. If the second element on the stack of open + elements is not a body element, or, if the stack of open + elements has only one node on it, then ignore the token. + (innerHTML case) */ + if (count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') { + // Ignore + + /* Otherwise, for each attribute on the token, check to see + if the attribute is already present on the body element (the + second element) on the stack of open elements. If it is not, + add the attribute and its corresponding value to that + element. */ + } else { + foreach ($token['attr'] as $attr) { + if (!$this->stack[1]->hasAttribute($attr['name'])) { + $this->stack[1]->setAttribute($attr['name'], $attr['value']); + } + } + } + break; + + /* A start tag whose tag name is one of: "address", + "blockquote", "center", "dir", "div", "dl", "fieldset", + "listing", "menu", "ol", "p", "ul" */ + case 'address': + case 'blockquote': + case 'center': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'listing': + case 'menu': + case 'ol': + case 'p': + case 'ul': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + /* A start tag whose tag name is "form" */ + case 'form': + /* If the form element pointer is not null, ignore the + token with a parse error. */ + if ($this->form_pointer !== null) { + // Ignore. + + /* Otherwise: */ + } else { + /* If the stack of open elements has a p element in + scope, then act as if an end tag with the tag name p + had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token, and set the + form element pointer to point to the element created. */ + $element = $this->insertElement($token); + $this->form_pointer = $element; + } + break; + + /* A start tag whose tag name is "li", "dd" or "dt" */ + case 'li': + case 'dd': + case 'dt': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + $stack_length = count($this->stack) - 1; + + for ($n = $stack_length; 0 <= $n; $n--) { + /* 1. Initialise node to be the current node (the + bottommost node of the stack). */ + $stop = false; + $node = $this->stack[$n]; + $cat = $this->getElementCategory($node->tagName); + + /* 2. If node is an li, dd or dt element, then pop all + the nodes from the current node up to node, including + node, then stop this algorithm. */ + if ($token['name'] === $node->tagName || ($token['name'] !== 'li' + && ($node->tagName === 'dd' || $node->tagName === 'dt')) + ) { + for ($x = $stack_length; $x >= $n; $x--) { + array_pop($this->stack); + } + + break; + } + + /* 3. If node is not in the formatting category, and is + not in the phrasing category, and is not an address or + div element, then stop this algorithm. */ + if ($cat !== self::FORMATTING && $cat !== self::PHRASING && + $node->tagName !== 'address' && $node->tagName !== 'div' + ) { + break; + } + } + + /* Finally, insert an HTML element with the same tag + name as the token's. */ + $this->insertElement($token); + break; + + /* A start tag token whose tag name is "plaintext" */ + case 'plaintext': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + return HTML5::PLAINTEXT; + break; + + /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + this is a parse error; pop elements from the stack until an + element with one of those tag names has been popped from the + stack. */ + while ($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { + array_pop($this->stack); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + /* A start tag whose tag name is "a" */ + case 'a': + /* If the list of active formatting elements contains + an element whose tag name is "a" between the end of the + list and the last marker on the list (or the start of + the list if there is no marker on the list), then this + is a parse error; act as if an end tag with the tag name + "a" had been seen, then remove that element from the list + of active formatting elements and the stack of open + elements if the end tag didn't already remove it (it + might not have if the element is not in table scope). */ + $leng = count($this->a_formatting); + + for ($n = $leng - 1; $n >= 0; $n--) { + if ($this->a_formatting[$n] === self::MARKER) { + break; + + } elseif ($this->a_formatting[$n]->nodeName === 'a') { + $this->emitToken( + array( + 'name' => 'a', + 'type' => HTML5::ENDTAG + ) + ); + break; + } + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + /* A start tag whose tag name is one of: "b", "big", "em", "font", + "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'b': + case 'big': + case 'em': + case 'font': + case 'i': + case 'nobr': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + /* A start tag token whose tag name is "button" */ + case 'button': + /* If the stack of open elements has a button element in scope, + then this is a parse error; act as if an end tag with the tag + name "button" had been seen, then reprocess the token. (We don't + do that. Unnecessary.) */ + if ($this->elementInScope('button')) { + $this->inBody( + array( + 'name' => 'button', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; + + /* A start tag token whose tag name is one of: "marquee", "object" */ + case 'marquee': + case 'object': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; + + /* A start tag token whose tag name is "xmp" */ + case 'xmp': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Switch the content model flag to the CDATA state. */ + return HTML5::CDATA; + break; + + /* A start tag whose tag name is "table" */ + case 'table': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + break; + + /* A start tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */ + case 'area': + case 'basefont': + case 'bgsound': + case 'br': + case 'embed': + case 'img': + case 'param': + case 'spacer': + case 'wbr': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "hr" */ + case 'hr': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "image" */ + case 'image': + /* Parse error. Change the token's tag name to "img" and + reprocess it. (Don't ask.) */ + $token['name'] = 'img'; + return $this->inBody($token); + break; + + /* A start tag whose tag name is "input" */ + case 'input': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an input element for the token. */ + $element = $this->insertElement($token, false); + + /* If the form element pointer is not null, then associate the + input element with the form element pointed to by the form + element pointer. */ + $this->form_pointer !== null + ? $this->form_pointer->appendChild($element) + : end($this->stack)->appendChild($element); + + /* Pop that input element off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "isindex" */ + case 'isindex': + /* Parse error. */ + // w/e + + /* If the form element pointer is not null, + then ignore the token. */ + if ($this->form_pointer === null) { + /* Act as if a start tag token with the tag name "form" had + been seen. */ + $this->inBody( + array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody( + array( + 'name' => 'hr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "p" had + been seen. */ + $this->inBody( + array( + 'name' => 'p', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "label" + had been seen. */ + $this->inBody( + array( + 'name' => 'label', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a stream of character tokens had been seen. */ + $this->insertText( + 'This is a searchable index. ' . + 'Insert your search keywords here: ' + ); + + /* Act as if a start tag token with the tag name "input" + had been seen, with all the attributes from the "isindex" + token, except with the "name" attribute set to the value + "isindex" (ignoring any explicit "name" attribute). */ + $attr = $token['attr']; + $attr[] = array('name' => 'name', 'value' => 'isindex'); + + $this->inBody( + array( + 'name' => 'input', + 'type' => HTML5::STARTTAG, + 'attr' => $attr + ) + ); + + /* Act as if a stream of character tokens had been seen + (see below for what they should say). */ + $this->insertText( + 'This is a searchable index. ' . + 'Insert your search keywords here: ' + ); + + /* Act as if an end tag token with the tag name "label" + had been seen. */ + $this->inBody( + array( + 'name' => 'label', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if an end tag token with the tag name "p" had + been seen. */ + $this->inBody( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody( + array( + 'name' => 'hr', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if an end tag token with the tag name "form" had + been seen. */ + $this->inBody( + array( + 'name' => 'form', + 'type' => HTML5::ENDTAG + ) + ); + } + break; + + /* A start tag whose tag name is "textarea" */ + case 'textarea': + $this->insertElement($token); + + /* Switch the tokeniser's content model flag to the + RCDATA state. */ + return HTML5::RCDATA; + break; + + /* A start tag whose tag name is one of: "iframe", "noembed", + "noframes" */ + case 'iframe': + case 'noembed': + case 'noframes': + $this->insertElement($token); + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + break; + + /* A start tag whose tag name is "select" */ + case 'select': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in select". */ + $this->mode = self::IN_SELECT; + break; + + /* A start or end tag whose tag name is one of: "caption", "col", + "colgroup", "frame", "frameset", "head", "option", "optgroup", + "tbody", "td", "tfoot", "th", "thead", "tr". */ + case 'caption': + case 'col': + case 'colgroup': + case 'frame': + case 'frameset': + case 'head': + case 'option': + case 'optgroup': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + // Parse error. Ignore the token. + break; + + /* A start or end tag whose tag name is one of: "event-source", + "section", "nav", "article", "aside", "header", "footer", + "datagrid", "command" */ + case 'event-source': + case 'section': + case 'nav': + case 'article': + case 'aside': + case 'header': + case 'footer': + case 'datagrid': + case 'command': + // Work in progress! + break; + + /* A start tag token not covered by the previous entries */ + default: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + $this->insertElement($token, true, true); + break; + } + break; + + case HTML5::ENDTAG: + switch ($token['name']) { + /* An end tag with the tag name "body" */ + case 'body': + /* If the second element in the stack of open elements is + not a body element, this is a parse error. Ignore the token. + (innerHTML case) */ + if (count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') { + // Ignore. + + /* If the current node is not the body element, then this + is a parse error. */ + } elseif (end($this->stack)->nodeName !== 'body') { + // Parse error. + } + + /* Change the insertion mode to "after body". */ + $this->mode = self::AFTER_BODY; + break; + + /* An end tag with the tag name "html" */ + case 'html': + /* Act as if an end tag with tag name "body" had been seen, + then, if that token wasn't ignored, reprocess the current + token. */ + $this->inBody( + array( + 'name' => 'body', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->afterBody($token); + break; + + /* An end tag whose tag name is one of: "address", "blockquote", + "center", "dir", "div", "dl", "fieldset", "listing", "menu", + "ol", "pre", "ul" */ + case 'address': + case 'blockquote': + case 'center': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'listing': + case 'menu': + case 'ol': + case 'pre': + case 'ul': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with + the same tag name as that of the token, then this + is a parse error. */ + // w/e + + /* If the stack of open elements has an element in + scope with the same tag name as that of the token, + then pop elements from this stack until an element + with that tag name has been popped from the stack. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is "form" */ + case 'form': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + } + + if (end($this->stack)->nodeName !== $token['name']) { + /* Now, if the current node is not an element with the + same tag name as that of the token, then this is a parse + error. */ + // w/e + + } else { + /* Otherwise, if the current node is an element with + the same tag name as that of the token pop that element + from the stack. */ + array_pop($this->stack); + } + + /* In any case, set the form element pointer to null. */ + $this->form_pointer = null; + break; + + /* An end tag whose tag name is "p" */ + case 'p': + /* If the stack of open elements has a p element in scope, + then generate implied end tags, except for p elements. */ + if ($this->elementInScope('p')) { + $this->generateImpliedEndTags(array('p')); + + /* If the current node is not a p element, then this is + a parse error. */ + // k + + /* If the stack of open elements has a p element in + scope, then pop elements from this stack until the stack + no longer has a p element in scope. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->elementInScope('p')) { + array_pop($this->stack); + + } else { + break; + } + } + } + break; + + /* An end tag whose tag name is "dd", "dt", or "li" */ + case 'dd': + case 'dt': + case 'li': + /* If the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then + generate implied end tags, except for elements with the + same tag name as the token. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(array($token['name'])); + + /* If the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // w/e + + /* If the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then + pop elements from this stack until an element with that + tag name has been popped from the stack. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); + + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + generate implied end tags. */ + if ($this->elementInScope($elements)) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with the same + tag name as that of the token, then this is a parse error. */ + // w/e + + /* If the stack of open elements has in scope an element + whose tag name is one of "h1", "h2", "h3", "h4", "h5", or + "h6", then pop elements from the stack until an element + with one of those tag names has been popped from the stack. */ + while ($this->elementInScope($elements)) { + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is one of: "a", "b", "big", "em", + "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'a': + case 'b': + case 'big': + case 'em': + case 'font': + case 'i': + case 'nobr': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + /* 1. Let the formatting element be the last element in + the list of active formatting elements that: + * is between the end of the list and the last scope + marker in the list, if any, or the start of the list + otherwise, and + * has the same tag name as the token. + */ + while (true) { + for ($a = count($this->a_formatting) - 1; $a >= 0; $a--) { + if ($this->a_formatting[$a] === self::MARKER) { + break; + + } elseif ($this->a_formatting[$a]->tagName === $token['name']) { + $formatting_element = $this->a_formatting[$a]; + $in_stack = in_array($formatting_element, $this->stack, true); + $fe_af_pos = $a; + break; + } + } + + /* If there is no such node, or, if that node is + also in the stack of open elements but the element + is not in scope, then this is a parse error. Abort + these steps. The token is ignored. */ + if (!isset($formatting_element) || ($in_stack && + !$this->elementInScope($token['name'])) + ) { + break; + + /* Otherwise, if there is such a node, but that node + is not in the stack of open elements, then this is a + parse error; remove the element from the list, and + abort these steps. */ + } elseif (isset($formatting_element) && !$in_stack) { + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + break; + } + + /* 2. Let the furthest block be the topmost node in the + stack of open elements that is lower in the stack + than the formatting element, and is not an element in + the phrasing or formatting categories. There might + not be one. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $length = count($this->stack); + + for ($s = $fe_s_pos + 1; $s < $length; $s++) { + $category = $this->getElementCategory($this->stack[$s]->nodeName); + + if ($category !== self::PHRASING && $category !== self::FORMATTING) { + $furthest_block = $this->stack[$s]; + } + } + + /* 3. If there is no furthest block, then the UA must + skip the subsequent steps and instead just pop all + the nodes from the bottom of the stack of open + elements, from the current node up to the formatting + element, and remove the formatting element from the + list of active formatting elements. */ + if (!isset($furthest_block)) { + for ($n = $length - 1; $n >= $fe_s_pos; $n--) { + array_pop($this->stack); + } + + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + break; + } + + /* 4. Let the common ancestor be the element + immediately above the formatting element in the stack + of open elements. */ + $common_ancestor = $this->stack[$fe_s_pos - 1]; + + /* 5. If the furthest block has a parent node, then + remove the furthest block from its parent node. */ + if ($furthest_block->parentNode !== null) { + $furthest_block->parentNode->removeChild($furthest_block); + } + + /* 6. Let a bookmark note the position of the + formatting element in the list of active formatting + elements relative to the elements on either side + of it in the list. */ + $bookmark = $fe_af_pos; + + /* 7. Let node and last node be the furthest block. + Follow these steps: */ + $node = $furthest_block; + $last_node = $furthest_block; + + while (true) { + for ($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) { + /* 7.1 Let node be the element immediately + prior to node in the stack of open elements. */ + $node = $this->stack[$n]; + + /* 7.2 If node is not in the list of active + formatting elements, then remove node from + the stack of open elements and then go back + to step 1. */ + if (!in_array($node, $this->a_formatting, true)) { + unset($this->stack[$n]); + $this->stack = array_merge($this->stack); + + } else { + break; + } + } + + /* 7.3 Otherwise, if node is the formatting + element, then go to the next step in the overall + algorithm. */ + if ($node === $formatting_element) { + break; + + /* 7.4 Otherwise, if last node is the furthest + block, then move the aforementioned bookmark to + be immediately after the node in the list of + active formatting elements. */ + } elseif ($last_node === $furthest_block) { + $bookmark = array_search($node, $this->a_formatting, true) + 1; + } + + /* 7.5 If node has any children, perform a + shallow clone of node, replace the entry for + node in the list of active formatting elements + with an entry for the clone, replace the entry + for node in the stack of open elements with an + entry for the clone, and let node be the clone. */ + if ($node->hasChildNodes()) { + $clone = $node->cloneNode(); + $s_pos = array_search($node, $this->stack, true); + $a_pos = array_search($node, $this->a_formatting, true); + + $this->stack[$s_pos] = $clone; + $this->a_formatting[$a_pos] = $clone; + $node = $clone; + } + + /* 7.6 Insert last node into node, first removing + it from its previous parent node if any. */ + if ($last_node->parentNode !== null) { + $last_node->parentNode->removeChild($last_node); + } + + $node->appendChild($last_node); + + /* 7.7 Let last node be node. */ + $last_node = $node; + } + + /* 8. Insert whatever last node ended up being in + the previous step into the common ancestor node, + first removing it from its previous parent node if + any. */ + if ($last_node->parentNode !== null) { + $last_node->parentNode->removeChild($last_node); + } + + $common_ancestor->appendChild($last_node); + + /* 9. Perform a shallow clone of the formatting + element. */ + $clone = $formatting_element->cloneNode(); + + /* 10. Take all of the child nodes of the furthest + block and append them to the clone created in the + last step. */ + while ($furthest_block->hasChildNodes()) { + $child = $furthest_block->firstChild; + $furthest_block->removeChild($child); + $clone->appendChild($child); + } + + /* 11. Append that clone to the furthest block. */ + $furthest_block->appendChild($clone); + + /* 12. Remove the formatting element from the list + of active formatting elements, and insert the clone + into the list of active formatting elements at the + position of the aforementioned bookmark. */ + $fe_af_pos = array_search($formatting_element, $this->a_formatting, true); + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + + $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1); + $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting)); + $this->a_formatting = array_merge($af_part1, array($clone), $af_part2); + + /* 13. Remove the formatting element from the stack + of open elements, and insert the clone into the stack + of open elements immediately after (i.e. in a more + deeply nested position than) the position of the + furthest block in that stack. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $fb_s_pos = array_search($furthest_block, $this->stack, true); + unset($this->stack[$fe_s_pos]); + + $s_part1 = array_slice($this->stack, 0, $fb_s_pos); + $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack)); + $this->stack = array_merge($s_part1, array($clone), $s_part2); + + /* 14. Jump back to step 1 in this series of steps. */ + unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block); + } + break; + + /* An end tag token whose tag name is one of: "button", + "marquee", "object" */ + case 'button': + case 'marquee': + case 'object': + /* If the stack of open elements has an element in scope whose + tag name matches the tag name of the token, then generate implied + tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // k + + /* Now, if the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then pop + elements from the stack until that element has been popped from + the stack, and clear the list of active formatting elements up + to the last marker. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + + $marker = end(array_keys($this->a_formatting, self::MARKER, true)); + + for ($n = count($this->a_formatting) - 1; $n > $marker; $n--) { + array_pop($this->a_formatting); + } + } + break; + + /* Or an end tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "hr", "iframe", "image", "img", + "input", "isindex", "noembed", "noframes", "param", "select", + "spacer", "table", "textarea", "wbr" */ + case 'area': + case 'basefont': + case 'bgsound': + case 'br': + case 'embed': + case 'hr': + case 'iframe': + case 'image': + case 'img': + case 'input': + case 'isindex': + case 'noembed': + case 'noframes': + case 'param': + case 'select': + case 'spacer': + case 'table': + case 'textarea': + case 'wbr': + // Parse error. Ignore the token. + break; + + /* An end tag token not covered by the previous entries */ + default: + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + /* Initialise node to be the current node (the bottommost + node of the stack). */ + $node = end($this->stack); + + /* If node has the same tag name as the end tag token, + then: */ + if ($token['name'] === $node->nodeName) { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* If the tag name of the end tag token does not + match the tag name of the current node, this is a + parse error. */ + // k + + /* Pop all the nodes from the current node up to + node, including node, then stop this algorithm. */ + for ($x = count($this->stack) - $n; $x >= $n; $x--) { + array_pop($this->stack); + } + + } else { + $category = $this->getElementCategory($node); + + if ($category !== self::SPECIAL && $category !== self::SCOPING) { + /* Otherwise, if node is in neither the formatting + category nor the phrasing category, then this is a + parse error. Stop this algorithm. The end tag token + is ignored. */ + return false; + } + } + } + break; + } + break; + } + } + + private function inTable($token) + { + $clear = array('html', 'table'); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $text = $this->dom->createTextNode($token['data']); + end($this->stack)->appendChild($text); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + end($this->stack)->appendChild($comment); + + /* A start tag whose tag name is "caption" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'caption' + ) { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + + /* Insert an HTML element for the token, then switch the + insertion mode to "in caption". */ + $this->insertElement($token); + $this->mode = self::IN_CAPTION; + + /* A start tag whose tag name is "colgroup" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'colgroup' + ) { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the + insertion mode to "in column group". */ + $this->insertElement($token); + $this->mode = self::IN_CGROUP; + + /* A start tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'col' + ) { + $this->inTable( + array( + 'name' => 'colgroup', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + $this->inColumnGroup($token); + + /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('tbody', 'tfoot', 'thead') + ) + ) { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the insertion + mode to "in table body". */ + $this->insertElement($token); + $this->mode = self::IN_TBODY; + + /* A start tag whose tag name is one of: "td", "th", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && + in_array($token['name'], array('td', 'th', 'tr')) + ) { + /* Act as if a start tag token with the tag name "tbody" had been + seen, then reprocess the current token. */ + $this->inTable( + array( + 'name' => 'tbody', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inTableBody($token); + + /* A start tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'table' + ) { + /* Parse error. Act as if an end tag token with the tag name "table" + had been seen, then, if that token wasn't ignored, reprocess the + current token. */ + $this->inTable( + array( + 'name' => 'table', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->mainPhase($token); + + /* An end tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table' + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + return false; + + /* Otherwise: */ + } else { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Now, if the current node is not a table element, then this + is a parse error. */ + // w/e + + /* Pop elements from this stack until a table element has been + popped from the stack. */ + while (true) { + $current = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($current === 'table') { + break; + } + } + + /* Reset the insertion mode appropriately. */ + $this->resetInsertionMode(); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array( + 'body', + 'caption', + 'col', + 'colgroup', + 'html', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* Parse error. Process the token as if the insertion mode was "in + body", with the following exception: */ + + /* If the current node is a table, tbody, tfoot, thead, or tr + element, then, whenever a node would be inserted into the current + node, it must instead be inserted into the foster parent element. */ + if (in_array( + end($this->stack)->nodeName, + array('table', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { + /* The foster parent element is the parent element of the last + table element in the stack of open elements, if there is a + table element and it has such a parent element. If there is no + table element in the stack of open elements (innerHTML case), + then the foster parent element is the first element in the + stack of open elements (the html element). Otherwise, if there + is a table element in the stack of open elements, but the last + table element in the stack of open elements has no parent, or + its parent node is not an element, then the foster parent + element is the element before the last table element in the + stack of open elements. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === 'table') { + $table = $this->stack[$n]; + break; + } + } + + if (isset($table) && $table->parentNode !== null) { + $this->foster_parent = $table->parentNode; + + } elseif (!isset($table)) { + $this->foster_parent = $this->stack[0]; + + } elseif (isset($table) && ($table->parentNode === null || + $table->parentNode->nodeType !== XML_ELEMENT_NODE) + ) { + $this->foster_parent = $this->stack[$n - 1]; + } + } + + $this->inBody($token); + } + } + + private function inCaption($token) + { + /* An end tag whose tag name is "caption" */ + if ($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore + + /* Otherwise: */ + } else { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Now, if the current node is not a caption element, then this + is a parse error. */ + // w/e + + /* Pop elements from this stack until a caption element has + been popped from the stack. */ + while (true) { + $node = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($node === 'caption') { + break; + } + } + + /* Clear the list of active formatting elements up to the last + marker. */ + $this->clearTheActiveFormattingElementsUpToTheLastMarker(); + + /* Switch the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag + name is "table" */ + } elseif (($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + )) || ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table') + ) { + /* Parse error. Act as if an end tag with the tag name "caption" + had been seen, then, if that token wasn't ignored, reprocess the + current token. */ + $this->inCaption( + array( + 'name' => 'caption', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inTable($token); + + /* An end tag whose tag name is one of: "body", "col", "colgroup", + "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array( + 'body', + 'col', + 'colgroup', + 'html', + 'tbody', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in body". */ + $this->inBody($token); + } + } + + private function inColumnGroup($token) + { + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $text = $this->dom->createTextNode($token['data']); + end($this->stack)->appendChild($text); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + end($this->stack)->appendChild($comment); + + /* A start tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') { + /* Insert a col element for the token. Immediately pop the current + node off the stack of open elements. */ + $this->insertElement($token); + array_pop($this->stack); + + /* An end tag whose tag name is "colgroup" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'colgroup' + ) { + /* If the current node is the root html element, then this is a + parse error, ignore the token. (innerHTML case) */ + if (end($this->stack)->nodeName === 'html') { + // Ignore + + /* Otherwise, pop the current node (which will be a colgroup + element) from the stack of open elements. Switch the insertion + mode to "in table". */ + } else { + array_pop($this->stack); + $this->mode = self::IN_TABLE; + } + + /* An end tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Act as if an end tag with the tag name "colgroup" had been seen, + and then, if that token wasn't ignored, reprocess the current token. */ + $this->inColumnGroup( + array( + 'name' => 'colgroup', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inTable($token); + } + } + + private function inTableBody($token) + { + $clear = array('tbody', 'tfoot', 'thead', 'html'); + + /* A start tag whose tag name is "tr" */ + if ($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Insert a tr element for the token, then switch the insertion + mode to "in row". */ + $this->insertElement($token); + $this->mode = self::IN_ROW; + + /* A start tag whose tag name is one of: "th", "td" */ + } elseif ($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td') + ) { + /* Parse error. Act as if a start tag with the tag name "tr" had + been seen, then reprocess the current token. */ + $this->inTableBody( + array( + 'name' => 'tr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inRow($token); + + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead')) + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore + + /* Otherwise: */ + } else { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Pop the current node from the stack of open elements. Switch + the insertion mode to "in table". */ + array_pop($this->stack); + $this->mode = self::IN_TABLE; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */ + } elseif (($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead') + )) || + ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table') + ) { + /* If the stack of open elements does not have a tbody, thead, or + tfoot element in table scope, this is a parse error. Ignore the + token. (innerHTML case) */ + if (!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Act as if an end tag with the same tag name as the current + node ("tbody", "tfoot", or "thead") had been seen, then + reprocess the current token. */ + $this->inTableBody( + array( + 'name' => end($this->stack)->nodeName, + 'type' => HTML5::ENDTAG + ) + ); + + return $this->mainPhase($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr') + ) + ) { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in table". */ + $this->inTable($token); + } + } + + private function inRow($token) + { + $clear = array('tr', 'html'); + + /* A start tag whose tag name is one of: "th", "td" */ + if ($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td') + ) { + /* Clear the stack back to a table row context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the insertion + mode to "in cell". */ + $this->insertElement($token); + $this->mode = self::IN_CELL; + + /* Insert a marker at the end of the list of active formatting + elements. */ + $this->a_formatting[] = self::MARKER; + + /* An end tag whose tag name is "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Clear the stack back to a table row context. */ + $this->clearStackToTableContext($clear); + + /* Pop the current node (which will be a tr element) from the + stack of open elements. Switch the insertion mode to "in table + body". */ + array_pop($this->stack); + $this->mode = self::IN_TBODY; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { + /* Act as if an end tag with the tag name "tr" had been seen, then, + if that token wasn't ignored, reprocess the current token. */ + $this->inRow( + array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inCell($token); + + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead')) + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Otherwise, act as if an end tag with the tag name "tr" had + been seen, then reprocess the current token. */ + $this->inRow( + array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inCell($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr') + ) + ) { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in table". */ + $this->inTable($token); + } + } + + private function inCell($token) + { + /* An end tag whose tag name is one of: "td", "th" */ + if ($token['type'] === HTML5::ENDTAG && + ($token['name'] === 'td' || $token['name'] === 'th') + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as that of the token, then this is a + parse error and the token must be ignored. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Generate implied end tags, except for elements with the same + tag name as the token. */ + $this->generateImpliedEndTags(array($token['name'])); + + /* Now, if the current node is not an element with the same tag + name as the token, then this is a parse error. */ + // k + + /* Pop elements from this stack until an element with the same + tag name as the token has been popped from the stack. */ + while (true) { + $node = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($node === $token['name']) { + break; + } + } + + /* Clear the list of active formatting elements up to the last + marker. */ + $this->clearTheActiveFormattingElementsUpToTheLastMarker(); + + /* Switch the insertion mode to "in row". (The current node + will be a tr element at this point.) */ + $this->mode = self::IN_ROW; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + /* If the stack of open elements does not have a td or th element + in table scope, then this is a parse error; ignore the token. + (innerHTML case) */ + if (!$this->elementInScope(array('td', 'th'), true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + /* If the stack of open elements does not have a td or th element + in table scope, then this is a parse error; ignore the token. + (innerHTML case) */ + if (!$this->elementInScope(array('td', 'th'), true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html') + ) + ) { + /* Parse error. Ignore the token. */ + + /* An end tag whose tag name is one of: "table", "tbody", "tfoot", + "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('table', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as that of the token (which can only + happen for "tbody", "tfoot" and "thead", or, in the innerHTML case), + then this is a parse error and the token must be ignored. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in body". */ + $this->inBody($token); + } + } + + private function inSelect($token) + { + /* Handle the token as follows: */ + + /* A character token */ + if ($token['type'] === HTML5::CHARACTR) { + /* Append the token's character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token whose tag name is "option" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'option' + ) { + /* If the current node is an option element, act as if an end tag + with the tag name "option" had been seen. */ + if (end($this->stack)->nodeName === 'option') { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* A start tag token whose tag name is "optgroup" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'optgroup' + ) { + /* If the current node is an option element, act as if an end tag + with the tag name "option" had been seen. */ + if (end($this->stack)->nodeName === 'option') { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* If the current node is an optgroup element, act as if an end tag + with the tag name "optgroup" had been seen. */ + if (end($this->stack)->nodeName === 'optgroup') { + $this->inSelect( + array( + 'name' => 'optgroup', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* An end tag token whose tag name is "optgroup" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'optgroup' + ) { + /* First, if the current node is an option element, and the node + immediately before it in the stack of open elements is an optgroup + element, then act as if an end tag with the tag name "option" had + been seen. */ + $elements_in_stack = count($this->stack); + + if ($this->stack[$elements_in_stack - 1]->nodeName === 'option' && + $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup' + ) { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* If the current node is an optgroup element, then pop that node + from the stack of open elements. Otherwise, this is a parse error, + ignore the token. */ + if ($this->stack[$elements_in_stack - 1] === 'optgroup') { + array_pop($this->stack); + } + + /* An end tag token whose tag name is "option" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'option' + ) { + /* If the current node is an option element, then pop that node + from the stack of open elements. Otherwise, this is a parse error, + ignore the token. */ + if (end($this->stack)->nodeName === 'option') { + array_pop($this->stack); + } + + /* An end tag whose tag name is "select" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'select' + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + // w/e + + /* Otherwise: */ + } else { + /* Pop elements from the stack of open elements until a select + element has been popped from the stack. */ + while (true) { + $current = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($current === 'select') { + break; + } + } + + /* Reset the insertion mode appropriately. */ + $this->resetInsertionMode(); + } + + /* A start tag whose tag name is "select" */ + } elseif ($token['name'] === 'select' && + $token['type'] === HTML5::STARTTAG + ) { + /* Parse error. Act as if the token had been an end tag with the + tag name "select" instead. */ + $this->inSelect( + array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + ) + ); + + /* An end tag whose tag name is one of: "caption", "table", "tbody", + "tfoot", "thead", "tr", "td", "th" */ + } elseif (in_array( + $token['name'], + array( + 'caption', + 'table', + 'tbody', + 'tfoot', + 'thead', + 'tr', + 'td', + 'th' + ) + ) && $token['type'] === HTML5::ENDTAG + ) { + /* Parse error. */ + // w/e + + /* If the stack of open elements has an element in table scope with + the same tag name as that of the token, then act as if an end tag + with the tag name "select" had been seen, and reprocess the token. + Otherwise, ignore the token. */ + if ($this->elementInScope($token['name'], true)) { + $this->inSelect( + array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + ) + ); + + $this->mainPhase($token); + } + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function afterBody($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Process the token as it would be processed if the insertion mode + was "in body". */ + $this->inBody($token); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the first element in the stack of open + elements (the html element), with the data attribute set to the + data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->stack[0]->appendChild($comment); + + /* An end tag with the tag name "html" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') { + /* If the parser was originally created in order to handle the + setting of an element's innerHTML attribute, this is a parse error; + ignore the token. (The element will be an html element in this + case.) (innerHTML case) */ + + /* Otherwise, switch to the trailing end phase. */ + $this->phase = self::END_PHASE; + + /* Anything else */ + } else { + /* Parse error. Set the insertion mode to "in body" and reprocess + the token. */ + $this->mode = self::IN_BODY; + return $this->inBody($token); + } + } + + private function inFrameset($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag with the tag name "frameset" */ + } elseif ($token['name'] === 'frameset' && + $token['type'] === HTML5::STARTTAG + ) { + $this->insertElement($token); + + /* An end tag with the tag name "frameset" */ + } elseif ($token['name'] === 'frameset' && + $token['type'] === HTML5::ENDTAG + ) { + /* If the current node is the root html element, then this is a + parse error; ignore the token. (innerHTML case) */ + if (end($this->stack)->nodeName === 'html') { + // Ignore + + } else { + /* Otherwise, pop the current node from the stack of open + elements. */ + array_pop($this->stack); + + /* If the parser was not originally created in order to handle + the setting of an element's innerHTML attribute (innerHTML case), + and the current node is no longer a frameset element, then change + the insertion mode to "after frameset". */ + $this->mode = self::AFTR_FRAME; + } + + /* A start tag with the tag name "frame" */ + } elseif ($token['name'] === 'frame' && + $token['type'] === HTML5::STARTTAG + ) { + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + + /* A start tag with the tag name "noframes" */ + } elseif ($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG + ) { + /* Process the token as if the insertion mode had been "in body". */ + $this->inBody($token); + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function afterFrameset($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* An end tag with the tag name "html" */ + } elseif ($token['name'] === 'html' && + $token['type'] === HTML5::ENDTAG + ) { + /* Switch to the trailing end phase. */ + $this->phase = self::END_PHASE; + + /* A start tag with the tag name "noframes" */ + } elseif ($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG + ) { + /* Process the token as if the insertion mode had been "in body". */ + $this->inBody($token); + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function trailingEndPhase($token) + { + /* After the main phase, as each token is emitted from the tokenisation + stage, it must be processed as described in this section. */ + + /* A DOCTYPE token */ + if ($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the Document object with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->dom->appendChild($comment); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Process the token as it would be processed in the main phase. */ + $this->mainPhase($token); + + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or a start tag token. Or an end tag token. */ + } elseif (($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG + ) { + /* Parse error. Switch back to the main phase and reprocess the + token. */ + $this->phase = self::MAIN_PHASE; + return $this->mainPhase($token); + + /* An end-of-file token */ + } elseif ($token['type'] === HTML5::EOF) { + /* OMG DONE!! */ + } + } + + private function insertElement($token, $append = true, $check = false) + { + // Proprietary workaround for libxml2's limitations with tag names + if ($check) { + // Slightly modified HTML5 tag-name modification, + // removing anything that's not an ASCII letter, digit, or hyphen + $token['name'] = preg_replace('/[^a-z0-9-]/i', '', $token['name']); + // Remove leading hyphens and numbers + $token['name'] = ltrim($token['name'], '-0..9'); + // In theory, this should ever be needed, but just in case + if ($token['name'] === '') { + $token['name'] = 'span'; + } // arbitrary generic choice + } + + $el = $this->dom->createElement($token['name']); + + foreach ($token['attr'] as $attr) { + if (!$el->hasAttribute($attr['name'])) { + $el->setAttribute($attr['name'], (string)$attr['value']); + } + } + + $this->appendToRealParent($el); + $this->stack[] = $el; + + return $el; + } + + private function insertText($data) + { + $text = $this->dom->createTextNode($data); + $this->appendToRealParent($text); + } + + private function insertComment($data) + { + $comment = $this->dom->createComment($data); + $this->appendToRealParent($comment); + } + + private function appendToRealParent($node) + { + if ($this->foster_parent === null) { + end($this->stack)->appendChild($node); + + } elseif ($this->foster_parent !== null) { + /* If the foster parent element is the parent element of the + last table element in the stack of open elements, then the new + node must be inserted immediately before the last table element + in the stack of open elements in the foster parent element; + otherwise, the new node must be appended to the foster parent + element. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === 'table' && + $this->stack[$n]->parentNode !== null + ) { + $table = $this->stack[$n]; + break; + } + } + + if (isset($table) && $this->foster_parent->isSameNode($table->parentNode)) { + $this->foster_parent->insertBefore($node, $table); + } else { + $this->foster_parent->appendChild($node); + } + + $this->foster_parent = null; + } + } + + private function elementInScope($el, $table = false) + { + if (is_array($el)) { + foreach ($el as $element) { + if ($this->elementInScope($element, $table)) { + return true; + } + } + + return false; + } + + $leng = count($this->stack); + + for ($n = 0; $n < $leng; $n++) { + /* 1. Initialise node to be the current node (the bottommost node of + the stack). */ + $node = $this->stack[$leng - 1 - $n]; + + if ($node->tagName === $el) { + /* 2. If node is the target node, terminate in a match state. */ + return true; + + } elseif ($node->tagName === 'table') { + /* 3. Otherwise, if node is a table element, terminate in a failure + state. */ + return false; + + } elseif ($table === true && in_array( + $node->tagName, + array( + 'caption', + 'td', + 'th', + 'button', + 'marquee', + 'object' + ) + ) + ) { + /* 4. Otherwise, if the algorithm is the "has an element in scope" + variant (rather than the "has an element in table scope" variant), + and node is one of the following, terminate in a failure state. */ + return false; + + } elseif ($node === $node->ownerDocument->documentElement) { + /* 5. Otherwise, if node is an html element (root element), terminate + in a failure state. (This can only happen if the node is the topmost + node of the stack of open elements, and prevents the next step from + being invoked if there are no more elements in the stack.) */ + return false; + } + + /* Otherwise, set node to the previous entry in the stack of open + elements and return to step 2. (This will never fail, since the loop + will always terminate in the previous step if the top of the stack + is reached.) */ + } + } + + private function reconstructActiveFormattingElements() + { + /* 1. If there are no entries in the list of active formatting elements, + then there is nothing to reconstruct; stop this algorithm. */ + $formatting_elements = count($this->a_formatting); + + if ($formatting_elements === 0) { + return false; + } + + /* 3. Let entry be the last (most recently added) element in the list + of active formatting elements. */ + $entry = end($this->a_formatting); + + /* 2. If the last (most recently added) entry in the list of active + formatting elements is a marker, or if it is an element that is in the + stack of open elements, then there is nothing to reconstruct; stop this + algorithm. */ + if ($entry === self::MARKER || in_array($entry, $this->stack, true)) { + return false; + } + + for ($a = $formatting_elements - 1; $a >= 0; true) { + /* 4. If there are no entries before entry in the list of active + formatting elements, then jump to step 8. */ + if ($a === 0) { + $step_seven = false; + break; + } + + /* 5. Let entry be the entry one earlier than entry in the list of + active formatting elements. */ + $a--; + $entry = $this->a_formatting[$a]; + + /* 6. If entry is neither a marker nor an element that is also in + thetack of open elements, go to step 4. */ + if ($entry === self::MARKER || in_array($entry, $this->stack, true)) { + break; + } + } + + while (true) { + /* 7. Let entry be the element one later than entry in the list of + active formatting elements. */ + if (isset($step_seven) && $step_seven === true) { + $a++; + $entry = $this->a_formatting[$a]; + } + + /* 8. Perform a shallow clone of the element entry to obtain clone. */ + $clone = $entry->cloneNode(); + + /* 9. Append clone to the current node and push it onto the stack + of open elements so that it is the new current node. */ + end($this->stack)->appendChild($clone); + $this->stack[] = $clone; + + /* 10. Replace the entry for entry in the list with an entry for + clone. */ + $this->a_formatting[$a] = $clone; + + /* 11. If the entry for clone in the list of active formatting + elements is not the last entry in the list, return to step 7. */ + if (end($this->a_formatting) !== $clone) { + $step_seven = true; + } else { + break; + } + } + } + + private function clearTheActiveFormattingElementsUpToTheLastMarker() + { + /* When the steps below require the UA to clear the list of active + formatting elements up to the last marker, the UA must perform the + following steps: */ + + while (true) { + /* 1. Let entry be the last (most recently added) entry in the list + of active formatting elements. */ + $entry = end($this->a_formatting); + + /* 2. Remove entry from the list of active formatting elements. */ + array_pop($this->a_formatting); + + /* 3. If entry was a marker, then stop the algorithm at this point. + The list has been cleared up to the last marker. */ + if ($entry === self::MARKER) { + break; + } + } + } + + private function generateImpliedEndTags($exclude = array()) + { + /* When the steps below require the UA to generate implied end tags, + then, if the current node is a dd element, a dt element, an li element, + a p element, a td element, a th element, or a tr element, the UA must + act as if an end tag with the respective tag name had been seen and + then generate implied end tags again. */ + $node = end($this->stack); + $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude); + + while (in_array(end($this->stack)->nodeName, $elements)) { + array_pop($this->stack); + } + } + + private function getElementCategory($node) + { + $name = $node->tagName; + if (in_array($name, $this->special)) { + return self::SPECIAL; + } elseif (in_array($name, $this->scoping)) { + return self::SCOPING; + } elseif (in_array($name, $this->formatting)) { + return self::FORMATTING; + } else { + return self::PHRASING; + } + } + + private function clearStackToTableContext($elements) + { + /* When the steps above require the UA to clear the stack back to a + table context, it means that the UA must, while the current node is not + a table element or an html element, pop elements from the stack of open + elements. If this causes any elements to be popped from the stack, then + this is a parse error. */ + while (true) { + $node = end($this->stack)->nodeName; + + if (in_array($node, $elements)) { + break; + } else { + array_pop($this->stack); + } + } + } + + private function resetInsertionMode() + { + /* 1. Let last be false. */ + $last = false; + $leng = count($this->stack); + + for ($n = $leng - 1; $n >= 0; $n--) { + /* 2. Let node be the last node in the stack of open elements. */ + $node = $this->stack[$n]; + + /* 3. If node is the first node in the stack of open elements, then + set last to true. If the element whose innerHTML attribute is being + set is neither a td element nor a th element, then set node to the + element whose innerHTML attribute is being set. (innerHTML case) */ + if ($this->stack[0]->isSameNode($node)) { + $last = true; + } + + /* 4. If node is a select element, then switch the insertion mode to + "in select" and abort these steps. (innerHTML case) */ + if ($node->nodeName === 'select') { + $this->mode = self::IN_SELECT; + break; + + /* 5. If node is a td or th element, then switch the insertion mode + to "in cell" and abort these steps. */ + } elseif ($node->nodeName === 'td' || $node->nodeName === 'th') { + $this->mode = self::IN_CELL; + break; + + /* 6. If node is a tr element, then switch the insertion mode to + "in row" and abort these steps. */ + } elseif ($node->nodeName === 'tr') { + $this->mode = self::IN_ROW; + break; + + /* 7. If node is a tbody, thead, or tfoot element, then switch the + insertion mode to "in table body" and abort these steps. */ + } elseif (in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) { + $this->mode = self::IN_TBODY; + break; + + /* 8. If node is a caption element, then switch the insertion mode + to "in caption" and abort these steps. */ + } elseif ($node->nodeName === 'caption') { + $this->mode = self::IN_CAPTION; + break; + + /* 9. If node is a colgroup element, then switch the insertion mode + to "in column group" and abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'colgroup') { + $this->mode = self::IN_CGROUP; + break; + + /* 10. If node is a table element, then switch the insertion mode + to "in table" and abort these steps. */ + } elseif ($node->nodeName === 'table') { + $this->mode = self::IN_TABLE; + break; + + /* 11. If node is a head element, then switch the insertion mode + to "in body" ("in body"! not "in head"!) and abort these steps. + (innerHTML case) */ + } elseif ($node->nodeName === 'head') { + $this->mode = self::IN_BODY; + break; + + /* 12. If node is a body element, then switch the insertion mode to + "in body" and abort these steps. */ + } elseif ($node->nodeName === 'body') { + $this->mode = self::IN_BODY; + break; + + /* 13. If node is a frameset element, then switch the insertion + mode to "in frameset" and abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'frameset') { + $this->mode = self::IN_FRAME; + break; + + /* 14. If node is an html element, then: if the head element + pointer is null, switch the insertion mode to "before head", + otherwise, switch the insertion mode to "after head". In either + case, abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'html') { + $this->mode = ($this->head_pointer === null) + ? self::BEFOR_HEAD + : self::AFTER_HEAD; + + break; + + /* 15. If last is true, then set the insertion mode to "in body" + and abort these steps. (innerHTML case) */ + } elseif ($last) { + $this->mode = self::IN_BODY; + break; + } + } + } + + private function closeCell() + { + /* If the stack of open elements has a td or th element in table scope, + then act as if an end tag token with that tag name had been seen. */ + foreach (array('td', 'th') as $cell) { + if ($this->elementInScope($cell, true)) { + $this->inCell( + array( + 'name' => $cell, + 'type' => HTML5::ENDTAG + ) + ); + + break; + } + } + } + + public function save() + { + return $this->dom; + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node.php new file mode 100644 index 0000000..3995fec --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node.php @@ -0,0 +1,49 @@ +data = $data; + $this->line = $line; + $this->col = $col; + } + + public function toTokenPair() { + return array(new HTMLPurifier_Token_Comment($this->data, $this->line, $this->col), null); + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node/Element.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node/Element.php new file mode 100644 index 0000000..6cbf56d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node/Element.php @@ -0,0 +1,59 @@ + form or the form, i.e. + * is it a pair of start/end tokens or an empty token. + * @bool + */ + public $empty = false; + + public $endCol = null, $endLine = null, $endArmor = array(); + + public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) { + $this->name = $name; + $this->attr = $attr; + $this->line = $line; + $this->col = $col; + $this->armor = $armor; + } + + public function toTokenPair() { + // XXX inefficiency here, normalization is not necessary + if ($this->empty) { + return array(new HTMLPurifier_Token_Empty($this->name, $this->attr, $this->line, $this->col, $this->armor), null); + } else { + $start = new HTMLPurifier_Token_Start($this->name, $this->attr, $this->line, $this->col, $this->armor); + $end = new HTMLPurifier_Token_End($this->name, array(), $this->endLine, $this->endCol, $this->endArmor); + //$end->start = $start; + return array($start, $end); + } + } +} + diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node/Text.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node/Text.php new file mode 100644 index 0000000..aec9166 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Node/Text.php @@ -0,0 +1,54 @@ +data = $data; + $this->is_whitespace = $is_whitespace; + $this->line = $line; + $this->col = $col; + } + + public function toTokenPair() { + return array(new HTMLPurifier_Token_Text($this->data, $this->line, $this->col), null); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PercentEncoder.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PercentEncoder.php new file mode 100644 index 0000000..18c8bbb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PercentEncoder.php @@ -0,0 +1,111 @@ +preserve[$i] = true; + } + for ($i = 65; $i <= 90; $i++) { // upper-case + $this->preserve[$i] = true; + } + for ($i = 97; $i <= 122; $i++) { // lower-case + $this->preserve[$i] = true; + } + $this->preserve[45] = true; // Dash - + $this->preserve[46] = true; // Period . + $this->preserve[95] = true; // Underscore _ + $this->preserve[126]= true; // Tilde ~ + + // extra letters not to escape + if ($preserve !== false) { + for ($i = 0, $c = strlen($preserve); $i < $c; $i++) { + $this->preserve[ord($preserve[$i])] = true; + } + } + } + + /** + * Our replacement for urlencode, it encodes all non-reserved characters, + * as well as any extra characters that were instructed to be preserved. + * @note + * Assumes that the string has already been normalized, making any + * and all percent escape sequences valid. Percents will not be + * re-escaped, regardless of their status in $preserve + * @param string $string String to be encoded + * @return string Encoded string. + */ + public function encode($string) + { + $ret = ''; + for ($i = 0, $c = strlen($string); $i < $c; $i++) { + if ($string[$i] !== '%' && !isset($this->preserve[$int = ord($string[$i])])) { + $ret .= '%' . sprintf('%02X', $int); + } else { + $ret .= $string[$i]; + } + } + return $ret; + } + + /** + * Fix up percent-encoding by decoding unreserved characters and normalizing. + * @warning This function is affected by $preserve, even though the + * usual desired behavior is for this not to preserve those + * characters. Be careful when reusing instances of PercentEncoder! + * @param string $string String to normalize + * @return string + */ + public function normalize($string) + { + if ($string == '') { + return ''; + } + $parts = explode('%', $string); + $ret = array_shift($parts); + foreach ($parts as $part) { + $length = strlen($part); + if ($length < 2) { + $ret .= '%25' . $part; + continue; + } + $encoding = substr($part, 0, 2); + $text = substr($part, 2); + if (!ctype_xdigit($encoding)) { + $ret .= '%25' . $part; + continue; + } + $int = hexdec($encoding); + if (isset($this->preserve[$int])) { + $ret .= chr($int) . $text; + continue; + } + $encoding = strtoupper($encoding); + $ret .= '%' . $encoding . $text; + } + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer.php new file mode 100644 index 0000000..549e4ce --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer.php @@ -0,0 +1,218 @@ +getAll(); + $context = new HTMLPurifier_Context(); + $this->generator = new HTMLPurifier_Generator($config, $context); + } + + /** + * Main function that renders object or aspect of that object + * @note Parameters vary depending on printer + */ + // function render() {} + + /** + * Returns a start tag + * @param string $tag Tag name + * @param array $attr Attribute array + * @return string + */ + protected function start($tag, $attr = array()) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Start($tag, $attr ? $attr : array()) + ); + } + + /** + * Returns an end tag + * @param string $tag Tag name + * @return string + */ + protected function end($tag) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_End($tag) + ); + } + + /** + * Prints a complete element with content inside + * @param string $tag Tag name + * @param string $contents Element contents + * @param array $attr Tag attributes + * @param bool $escape whether or not to escape contents + * @return string + */ + protected function element($tag, $contents, $attr = array(), $escape = true) + { + return $this->start($tag, $attr) . + ($escape ? $this->escape($contents) : $contents) . + $this->end($tag); + } + + /** + * @param string $tag + * @param array $attr + * @return string + */ + protected function elementEmpty($tag, $attr = array()) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Empty($tag, $attr) + ); + } + + /** + * @param string $text + * @return string + */ + protected function text($text) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Text($text) + ); + } + + /** + * Prints a simple key/value row in a table. + * @param string $name Key + * @param mixed $value Value + * @return string + */ + protected function row($name, $value) + { + if (is_bool($value)) { + $value = $value ? 'On' : 'Off'; + } + return + $this->start('tr') . "\n" . + $this->element('th', $name) . "\n" . + $this->element('td', $value) . "\n" . + $this->end('tr'); + } + + /** + * Escapes a string for HTML output. + * @param string $string String to escape + * @return string + */ + protected function escape($string) + { + $string = HTMLPurifier_Encoder::cleanUTF8($string); + $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8'); + return $string; + } + + /** + * Takes a list of strings and turns them into a single list + * @param string[] $array List of strings + * @param bool $polite Bool whether or not to add an end before the last + * @return string + */ + protected function listify($array, $polite = false) + { + if (empty($array)) { + return 'None'; + } + $ret = ''; + $i = count($array); + foreach ($array as $value) { + $i--; + $ret .= $value; + if ($i > 0 && !($polite && $i == 1)) { + $ret .= ', '; + } + if ($polite && $i == 1) { + $ret .= 'and '; + } + } + return $ret; + } + + /** + * Retrieves the class of an object without prefixes, as well as metadata + * @param object $obj Object to determine class of + * @param string $sec_prefix Further prefix to remove + * @return string + */ + protected function getClass($obj, $sec_prefix = '') + { + static $five = null; + if ($five === null) { + $five = version_compare(PHP_VERSION, '5', '>='); + } + $prefix = 'HTMLPurifier_' . $sec_prefix; + if (!$five) { + $prefix = strtolower($prefix); + } + $class = str_replace($prefix, '', get_class($obj)); + $lclass = strtolower($class); + $class .= '('; + switch ($lclass) { + case 'enum': + $values = array(); + foreach ($obj->valid_values as $value => $bool) { + $values[] = $value; + } + $class .= implode(', ', $values); + break; + case 'css_composite': + $values = array(); + foreach ($obj->defs as $def) { + $values[] = $this->getClass($def, $sec_prefix); + } + $class .= implode(', ', $values); + break; + case 'css_multiple': + $class .= $this->getClass($obj->single, $sec_prefix) . ', '; + $class .= $obj->max; + break; + case 'css_denyelementdecorator': + $class .= $this->getClass($obj->def, $sec_prefix) . ', '; + $class .= $obj->element; + break; + case 'css_importantdecorator': + $class .= $this->getClass($obj->def, $sec_prefix); + if ($obj->allow) { + $class .= ', !important'; + } + break; + } + $class .= ')'; + return $class; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/CSSDefinition.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/CSSDefinition.php new file mode 100644 index 0000000..29505fe --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/CSSDefinition.php @@ -0,0 +1,44 @@ +def = $config->getCSSDefinition(); + $ret = ''; + + $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer')); + $ret .= $this->start('table'); + + $ret .= $this->element('caption', 'Properties ($info)'); + + $ret .= $this->start('thead'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Property', array('class' => 'heavy')); + $ret .= $this->element('th', 'Definition', array('class' => 'heavy', 'style' => 'width:auto;')); + $ret .= $this->end('tr'); + $ret .= $this->end('thead'); + + ksort($this->def->info); + foreach ($this->def->info as $property => $obj) { + $name = $this->getClass($obj, 'AttrDef_'); + $ret .= $this->row($property, $name); + } + + $ret .= $this->end('table'); + $ret .= $this->end('div'); + + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.css b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.css new file mode 100644 index 0000000..3ff1a88 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.css @@ -0,0 +1,10 @@ + +.hp-config {} + +.hp-config tbody th {text-align:right; padding-right:0.5em;} +.hp-config thead, .hp-config .namespace {background:#3C578C; color:#FFF;} +.hp-config .namespace th {text-align:center;} +.hp-config .verbose {display:none;} +.hp-config .controls {text-align:center;} + +/* vim: et sw=4 sts=4 */ diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.js b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.js new file mode 100644 index 0000000..cba00c9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.js @@ -0,0 +1,5 @@ +function toggleWriteability(id_of_patient, checked) { + document.getElementById(id_of_patient).disabled = checked; +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.php new file mode 100644 index 0000000..4c3ce17 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/ConfigForm.php @@ -0,0 +1,456 @@ +docURL = $doc_url; + $this->name = $name; + $this->compress = $compress; + // initialize sub-printers + $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default(); + $this->fields[HTMLPurifier_VarParser::C_BOOL] = new HTMLPurifier_Printer_ConfigForm_bool(); + } + + /** + * Sets default column and row size for textareas in sub-printers + * @param $cols Integer columns of textarea, null to use default + * @param $rows Integer rows of textarea, null to use default + */ + public function setTextareaDimensions($cols = null, $rows = null) + { + if ($cols) { + $this->fields['default']->cols = $cols; + } + if ($rows) { + $this->fields['default']->rows = $rows; + } + } + + /** + * Retrieves styling, in case it is not accessible by webserver + */ + public static function getCSS() + { + return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css'); + } + + /** + * Retrieves JavaScript, in case it is not accessible by webserver + */ + public static function getJavaScript() + { + return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js'); + } + + /** + * Returns HTML output for a configuration form + * @param HTMLPurifier_Config|array $config Configuration object of current form state, or an array + * where [0] has an HTML namespace and [1] is being rendered. + * @param array|bool $allowed Optional namespace(s) and directives to restrict form to. + * @param bool $render_controls + * @return string + */ + public function render($config, $allowed = true, $render_controls = true) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + + $this->config = $config; + $this->genConfig = $gen_config; + $this->prepareGenerator($gen_config); + + $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $config->def); + $all = array(); + foreach ($allowed as $key) { + list($ns, $directive) = $key; + $all[$ns][$directive] = $config->get($ns . '.' . $directive); + } + + $ret = ''; + $ret .= $this->start('table', array('class' => 'hp-config')); + $ret .= $this->start('thead'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive')); + $ret .= $this->element('th', 'Value', array('class' => 'hp-value')); + $ret .= $this->end('tr'); + $ret .= $this->end('thead'); + foreach ($all as $ns => $directives) { + $ret .= $this->renderNamespace($ns, $directives); + } + if ($render_controls) { + $ret .= $this->start('tbody'); + $ret .= $this->start('tr'); + $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls')); + $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit')); + $ret .= '[Reset]'; + $ret .= $this->end('td'); + $ret .= $this->end('tr'); + $ret .= $this->end('tbody'); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders a single namespace + * @param $ns String namespace name + * @param array $directives array of directives to values + * @return string + */ + protected function renderNamespace($ns, $directives) + { + $ret = ''; + $ret .= $this->start('tbody', array('class' => 'namespace')); + $ret .= $this->start('tr'); + $ret .= $this->element('th', $ns, array('colspan' => 2)); + $ret .= $this->end('tr'); + $ret .= $this->end('tbody'); + $ret .= $this->start('tbody'); + foreach ($directives as $directive => $value) { + $ret .= $this->start('tr'); + $ret .= $this->start('th'); + if ($this->docURL) { + $url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL); + $ret .= $this->start('a', array('href' => $url)); + } + $attr = array('for' => "{$this->name}:$ns.$directive"); + + // crop directive name if it's too long + if (!$this->compress || (strlen($directive) < $this->compress)) { + $directive_disp = $directive; + } else { + $directive_disp = substr($directive, 0, $this->compress - 2) . '...'; + $attr['title'] = $directive; + } + + $ret .= $this->element( + 'label', + $directive_disp, + // component printers must create an element with this id + $attr + ); + if ($this->docURL) { + $ret .= $this->end('a'); + } + $ret .= $this->end('th'); + + $ret .= $this->start('td'); + $def = $this->config->def->info["$ns.$directive"]; + if (is_int($def)) { + $allow_null = $def < 0; + $type = abs($def); + } else { + $type = $def->type; + $allow_null = isset($def->allow_null); + } + if (!isset($this->fields[$type])) { + $type = 0; + } // default + $type_obj = $this->fields[$type]; + if ($allow_null) { + $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj); + } + $ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config)); + $ret .= $this->end('td'); + $ret .= $this->end('tr'); + } + $ret .= $this->end('tbody'); + return $ret; + } + +} + +/** + * Printer decorator for directives that accept null + */ +class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer +{ + /** + * Printer being decorated + * @type HTMLPurifier_Printer + */ + protected $obj; + + /** + * @param HTMLPurifier_Printer $obj Printer to decorate + */ + public function __construct($obj) + { + parent::__construct(); + $this->obj = $obj; + } + + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + + $ret = ''; + $ret .= $this->start('label', array('for' => "$name:Null_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' Null/Disabled'); + $ret .= $this->end('label'); + $attr = array( + 'type' => 'checkbox', + 'value' => '1', + 'class' => 'null-toggle', + 'name' => "$name" . "[Null_$ns.$directive]", + 'id' => "$name:Null_$ns.$directive", + 'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!! + ); + if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) { + // modify inline javascript slightly + $attr['onclick'] = + "toggleWriteability('$name:Yes_$ns.$directive',checked);" . + "toggleWriteability('$name:No_$ns.$directive',checked)"; + } + if ($value === null) { + $attr['checked'] = 'checked'; + } + $ret .= $this->elementEmpty('input', $attr); + $ret .= $this->text(' or '); + $ret .= $this->elementEmpty('br'); + $ret .= $this->obj->render($ns, $directive, $value, $name, array($gen_config, $config)); + return $ret; + } +} + +/** + * Swiss-army knife configuration form field printer + */ +class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer +{ + /** + * @type int + */ + public $cols = 18; + + /** + * @type int + */ + public $rows = 5; + + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + // this should probably be split up a little + $ret = ''; + $def = $config->def->info["$ns.$directive"]; + if (is_int($def)) { + $type = abs($def); + } else { + $type = $def->type; + } + if (is_array($value)) { + switch ($type) { + case HTMLPurifier_VarParser::LOOKUP: + $array = $value; + $value = array(); + foreach ($array as $val => $b) { + $value[] = $val; + } + //TODO does this need a break? + case HTMLPurifier_VarParser::ALIST: + $value = implode(PHP_EOL, $value); + break; + case HTMLPurifier_VarParser::HASH: + $nvalue = ''; + foreach ($value as $i => $v) { + if (is_array($v)) { + // HACK + $v = implode(";", $v); + } + $nvalue .= "$i:$v" . PHP_EOL; + } + $value = $nvalue; + break; + default: + $value = ''; + } + } + if ($type === HTMLPurifier_VarParser::C_MIXED) { + return 'Not supported'; + $value = serialize($value); + } + $attr = array( + 'name' => "$name" . "[$ns.$directive]", + 'id' => "$name:$ns.$directive" + ); + if ($value === null) { + $attr['disabled'] = 'disabled'; + } + if (isset($def->allowed)) { + $ret .= $this->start('select', $attr); + foreach ($def->allowed as $val => $b) { + $attr = array(); + if ($value == $val) { + $attr['selected'] = 'selected'; + } + $ret .= $this->element('option', $val, $attr); + } + $ret .= $this->end('select'); + } elseif ($type === HTMLPurifier_VarParser::TEXT || + $type === HTMLPurifier_VarParser::ITEXT || + $type === HTMLPurifier_VarParser::ALIST || + $type === HTMLPurifier_VarParser::HASH || + $type === HTMLPurifier_VarParser::LOOKUP) { + $attr['cols'] = $this->cols; + $attr['rows'] = $this->rows; + $ret .= $this->start('textarea', $attr); + $ret .= $this->text($value); + $ret .= $this->end('textarea'); + } else { + $attr['value'] = $value; + $attr['type'] = 'text'; + $ret .= $this->elementEmpty('input', $attr); + } + return $ret; + } +} + +/** + * Bool form field printer + */ +class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer +{ + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + $ret = ''; + $ret .= $this->start('div', array('id' => "$name:$ns.$directive")); + + $ret .= $this->start('label', array('for' => "$name:Yes_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' Yes'); + $ret .= $this->end('label'); + + $attr = array( + 'type' => 'radio', + 'name' => "$name" . "[$ns.$directive]", + 'id' => "$name:Yes_$ns.$directive", + 'value' => '1' + ); + if ($value === true) { + $attr['checked'] = 'checked'; + } + if ($value === null) { + $attr['disabled'] = 'disabled'; + } + $ret .= $this->elementEmpty('input', $attr); + + $ret .= $this->start('label', array('for' => "$name:No_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' No'); + $ret .= $this->end('label'); + + $attr = array( + 'type' => 'radio', + 'name' => "$name" . "[$ns.$directive]", + 'id' => "$name:No_$ns.$directive", + 'value' => '0' + ); + if ($value === false) { + $attr['checked'] = 'checked'; + } + if ($value === null) { + $attr['disabled'] = 'disabled'; + } + $ret .= $this->elementEmpty('input', $attr); + + $ret .= $this->end('div'); + + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/HTMLDefinition.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/HTMLDefinition.php new file mode 100644 index 0000000..ae86391 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Printer/HTMLDefinition.php @@ -0,0 +1,324 @@ +config =& $config; + + $this->def = $config->getHTMLDefinition(); + + $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer')); + + $ret .= $this->renderDoctype(); + $ret .= $this->renderEnvironment(); + $ret .= $this->renderContentSets(); + $ret .= $this->renderInfo(); + + $ret .= $this->end('div'); + + return $ret; + } + + /** + * Renders the Doctype table + * @return string + */ + protected function renderDoctype() + { + $doctype = $this->def->doctype; + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Doctype'); + $ret .= $this->row('Name', $doctype->name); + $ret .= $this->row('XML', $doctype->xml ? 'Yes' : 'No'); + $ret .= $this->row('Default Modules', implode(', ', $doctype->modules)); + $ret .= $this->row('Default Tidy Modules', implode(', ', $doctype->tidyModules)); + $ret .= $this->end('table'); + return $ret; + } + + + /** + * Renders environment table, which is miscellaneous info + * @return string + */ + protected function renderEnvironment() + { + $def = $this->def; + + $ret = ''; + + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Environment'); + + $ret .= $this->row('Parent of fragment', $def->info_parent); + $ret .= $this->renderChildren($def->info_parent_def->child); + $ret .= $this->row('Block wrap name', $def->info_block_wrapper); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Global attributes'); + $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr), null, 0); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Tag transforms'); + $list = array(); + foreach ($def->info_tag_transform as $old => $new) { + $new = $this->getClass($new, 'TagTransform_'); + $list[] = "<$old> with $new"; + } + $ret .= $this->element('td', $this->listify($list)); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre)); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post)); + $ret .= $this->end('tr'); + + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders the Content Sets table + * @return string + */ + protected function renderContentSets() + { + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Content Sets'); + foreach ($this->def->info_content_sets as $name => $lookup) { + $ret .= $this->heavyHeader($name); + $ret .= $this->start('tr'); + $ret .= $this->element('td', $this->listifyTagLookup($lookup)); + $ret .= $this->end('tr'); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders the Elements ($info) table + * @return string + */ + protected function renderInfo() + { + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Elements ($info)'); + ksort($this->def->info); + $ret .= $this->heavyHeader('Allowed tags', 2); + $ret .= $this->start('tr'); + $ret .= $this->element('td', $this->listifyTagLookup($this->def->info), array('colspan' => 2)); + $ret .= $this->end('tr'); + foreach ($this->def->info as $name => $def) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', "<$name>", array('class' => 'heavy', 'colspan' => 2)); + $ret .= $this->end('tr'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Inline content'); + $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No'); + $ret .= $this->end('tr'); + if (!empty($def->excludes)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Excludes'); + $ret .= $this->element('td', $this->listifyTagLookup($def->excludes)); + $ret .= $this->end('tr'); + } + if (!empty($def->attr_transform_pre)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre)); + $ret .= $this->end('tr'); + } + if (!empty($def->attr_transform_post)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post)); + $ret .= $this->end('tr'); + } + if (!empty($def->auto_close)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Auto closed by'); + $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close)); + $ret .= $this->end('tr'); + } + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Allowed attributes'); + $ret .= $this->element('td', $this->listifyAttr($def->attr), array(), 0); + $ret .= $this->end('tr'); + + if (!empty($def->required_attr)) { + $ret .= $this->row('Required attributes', $this->listify($def->required_attr)); + } + + $ret .= $this->renderChildren($def->child); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders a row describing the allowed children of an element + * @param HTMLPurifier_ChildDef $def HTMLPurifier_ChildDef of pertinent element + * @return string + */ + protected function renderChildren($def) + { + $context = new HTMLPurifier_Context(); + $ret = ''; + $ret .= $this->start('tr'); + $elements = array(); + $attr = array(); + if (isset($def->elements)) { + if ($def->type == 'strictblockquote') { + $def->validateChildren(array(), $this->config, $context); + } + $elements = $def->elements; + } + if ($def->type == 'chameleon') { + $attr['rowspan'] = 2; + } elseif ($def->type == 'empty') { + $elements = array(); + } elseif ($def->type == 'table') { + $elements = array_flip( + array( + 'col', + 'caption', + 'colgroup', + 'thead', + 'tfoot', + 'tbody', + 'tr' + ) + ); + } + $ret .= $this->element('th', 'Allowed children', $attr); + + if ($def->type == 'chameleon') { + + $ret .= $this->element( + 'td', + 'Block: ' . + $this->escape($this->listifyTagLookup($def->block->elements)), + null, + 0 + ); + $ret .= $this->end('tr'); + $ret .= $this->start('tr'); + $ret .= $this->element( + 'td', + 'Inline: ' . + $this->escape($this->listifyTagLookup($def->inline->elements)), + null, + 0 + ); + + } elseif ($def->type == 'custom') { + + $ret .= $this->element( + 'td', + '' . ucfirst($def->type) . ': ' . + $def->dtd_regex + ); + + } else { + $ret .= $this->element( + 'td', + '' . ucfirst($def->type) . ': ' . + $this->escape($this->listifyTagLookup($elements)), + null, + 0 + ); + } + $ret .= $this->end('tr'); + return $ret; + } + + /** + * Listifies a tag lookup table. + * @param array $array Tag lookup array in form of array('tagname' => true) + * @return string + */ + protected function listifyTagLookup($array) + { + ksort($array); + $list = array(); + foreach ($array as $name => $discard) { + if ($name !== '#PCDATA' && !isset($this->def->info[$name])) { + continue; + } + $list[] = $name; + } + return $this->listify($list); + } + + /** + * Listifies a list of objects by retrieving class names and internal state + * @param array $array List of objects + * @return string + * @todo Also add information about internal state + */ + protected function listifyObjectList($array) + { + ksort($array); + $list = array(); + foreach ($array as $obj) { + $list[] = $this->getClass($obj, 'AttrTransform_'); + } + return $this->listify($list); + } + + /** + * Listifies a hash of attributes to AttrDef classes + * @param array $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef) + * @return string + */ + protected function listifyAttr($array) + { + ksort($array); + $list = array(); + foreach ($array as $name => $obj) { + if ($obj === false) { + continue; + } + $list[] = "$name = " . $this->getClass($obj, 'AttrDef_') . ''; + } + return $this->listify($list); + } + + /** + * Creates a heavy header row + * @param string $text + * @param int $num + * @return string + */ + protected function heavyHeader($text, $num = 1) + { + $ret = ''; + $ret .= $this->start('tr'); + $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy')); + $ret .= $this->end('tr'); + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PropertyList.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PropertyList.php new file mode 100644 index 0000000..189348f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PropertyList.php @@ -0,0 +1,122 @@ +parent = $parent; + } + + /** + * Recursively retrieves the value for a key + * @param string $name + * @throws HTMLPurifier_Exception + */ + public function get($name) + { + if ($this->has($name)) { + return $this->data[$name]; + } + // possible performance bottleneck, convert to iterative if necessary + if ($this->parent) { + return $this->parent->get($name); + } + throw new HTMLPurifier_Exception("Key '$name' not found"); + } + + /** + * Sets the value of a key, for this plist + * @param string $name + * @param mixed $value + */ + public function set($name, $value) + { + $this->data[$name] = $value; + } + + /** + * Returns true if a given key exists + * @param string $name + * @return bool + */ + public function has($name) + { + return array_key_exists($name, $this->data); + } + + /** + * Resets a value to the value of it's parent, usually the default. If + * no value is specified, the entire plist is reset. + * @param string $name + */ + public function reset($name = null) + { + if ($name == null) { + $this->data = array(); + } else { + unset($this->data[$name]); + } + } + + /** + * Squashes this property list and all of its property lists into a single + * array, and returns the array. This value is cached by default. + * @param bool $force If true, ignores the cache and regenerates the array. + * @return array + */ + public function squash($force = false) + { + if ($this->cache !== null && !$force) { + return $this->cache; + } + if ($this->parent) { + return $this->cache = array_merge($this->parent->squash($force), $this->data); + } else { + return $this->cache = $this->data; + } + } + + /** + * Returns the parent plist. + * @return HTMLPurifier_PropertyList + */ + public function getParent() + { + return $this->parent; + } + + /** + * Sets the parent plist. + * @param HTMLPurifier_PropertyList $plist Parent plist + */ + public function setParent($plist) + { + $this->parent = $plist; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PropertyListIterator.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PropertyListIterator.php new file mode 100644 index 0000000..f68fc8c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/PropertyListIterator.php @@ -0,0 +1,43 @@ +l = strlen($filter); + $this->filter = $filter; + } + + /** + * @return bool + */ + #[\ReturnTypeWillChange] + public function accept() + { + $key = $this->getInnerIterator()->key(); + if (strncmp($key, $this->filter, $this->l) !== 0) { + return false; + } + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Queue.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Queue.php new file mode 100644 index 0000000..f58db90 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Queue.php @@ -0,0 +1,56 @@ +input = $input; + $this->output = array(); + } + + /** + * Shifts an element off the front of the queue. + */ + public function shift() { + if (empty($this->output)) { + $this->output = array_reverse($this->input); + $this->input = array(); + } + if (empty($this->output)) { + return NULL; + } + return array_pop($this->output); + } + + /** + * Pushes an element onto the front of the queue. + */ + public function push($x) { + array_push($this->input, $x); + } + + /** + * Checks if it's empty. + */ + public function isEmpty() { + return empty($this->input) && empty($this->output); + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy.php new file mode 100644 index 0000000..e1ff3b7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy.php @@ -0,0 +1,26 @@ +strategies as $strategy) { + $tokens = $strategy->execute($tokens, $config, $context); + } + return $tokens; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/Core.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/Core.php new file mode 100644 index 0000000..4414c17 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/Core.php @@ -0,0 +1,17 @@ +strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements(); + $this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed(); + $this->strategies[] = new HTMLPurifier_Strategy_FixNesting(); + $this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes(); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/FixNesting.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/FixNesting.php new file mode 100644 index 0000000..6fa673d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/FixNesting.php @@ -0,0 +1,181 @@ +getHTMLDefinition(); + + $excludes_enabled = !$config->get('Core.DisableExcludes'); + + // setup the context variable 'IsInline', for chameleon processing + // is 'false' when we are not inline, 'true' when it must always + // be inline, and an integer when it is inline for a certain + // branch of the document tree + $is_inline = $definition->info_parent_def->descendants_are_inline; + $context->register('IsInline', $is_inline); + + // setup error collector + $e =& $context->get('ErrorCollector', true); + + //####################################################################// + // Loop initialization + + // stack that contains all elements that are excluded + // it is organized by parent elements, similar to $stack, + // but it is only populated when an element with exclusions is + // processed, i.e. there won't be empty exclusions. + $exclude_stack = array($definition->info_parent_def->excludes); + + // variable that contains the start token while we are processing + // nodes. This enables error reporting to do its job + $node = $top_node; + // dummy token + list($token, $d) = $node->toTokenPair(); + $context->register('CurrentNode', $node); + $context->register('CurrentToken', $token); + + //####################################################################// + // Loop + + // We need to implement a post-order traversal iteratively, to + // avoid running into stack space limits. This is pretty tricky + // to reason about, so we just manually stack-ify the recursive + // variant: + // + // function f($node) { + // foreach ($node->children as $child) { + // f($child); + // } + // validate($node); + // } + // + // Thus, we will represent a stack frame as array($node, + // $is_inline, stack of children) + // e.g. array_reverse($node->children) - already processed + // children. + + $parent_def = $definition->info_parent_def; + $stack = array( + array($top_node, + $parent_def->descendants_are_inline, + $parent_def->excludes, // exclusions + 0) + ); + + while (!empty($stack)) { + list($node, $is_inline, $excludes, $ix) = array_pop($stack); + // recursive call + $go = false; + $def = empty($stack) ? $definition->info_parent_def : $definition->info[$node->name]; + while (isset($node->children[$ix])) { + $child = $node->children[$ix++]; + if ($child instanceof HTMLPurifier_Node_Element) { + $go = true; + $stack[] = array($node, $is_inline, $excludes, $ix); + $stack[] = array($child, + // ToDo: I don't think it matters if it's def or + // child_def, but double check this... + $is_inline || $def->descendants_are_inline, + empty($def->excludes) ? $excludes + : array_merge($excludes, $def->excludes), + 0); + break; + } + }; + if ($go) continue; + list($token, $d) = $node->toTokenPair(); + // base case + if ($excludes_enabled && isset($excludes[$node->name])) { + $node->dead = true; + if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node excluded'); + } else { + // XXX I suppose it would be slightly more efficient to + // avoid the allocation here and have children + // strategies handle it + $children = array(); + foreach ($node->children as $child) { + if (!$child->dead) $children[] = $child; + } + $result = $def->child->validateChildren($children, $config, $context); + if ($result === true) { + // nop + $node->children = $children; + } elseif ($result === false) { + $node->dead = true; + if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node removed'); + } else { + $node->children = $result; + if ($e) { + // XXX This will miss mutations of internal nodes. Perhaps defer to the child validators + if (empty($result) && !empty($children)) { + $e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed'); + } else if ($result != $children) { + $e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized'); + } + } + } + } + } + + //####################################################################// + // Post-processing + + // remove context variables + $context->destroy('IsInline'); + $context->destroy('CurrentNode'); + $context->destroy('CurrentToken'); + + //####################################################################// + // Return + + return HTMLPurifier_Arborize::flatten($node, $config, $context); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/MakeWellFormed.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/MakeWellFormed.php new file mode 100644 index 0000000..a6eb09e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/MakeWellFormed.php @@ -0,0 +1,659 @@ +getHTMLDefinition(); + + // local variables + $generator = new HTMLPurifier_Generator($config, $context); + $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); + // used for autoclose early abortion + $global_parent_allowed_elements = $definition->info_parent_def->child->getAllowedElements($config); + $e = $context->get('ErrorCollector', true); + $i = false; // injector index + list($zipper, $token) = HTMLPurifier_Zipper::fromArray($tokens); + if ($token === NULL) { + return array(); + } + $reprocess = false; // whether or not to reprocess the same token + $stack = array(); + + // member variables + $this->stack =& $stack; + $this->tokens =& $tokens; + $this->token =& $token; + $this->zipper =& $zipper; + $this->config = $config; + $this->context = $context; + + // context variables + $context->register('CurrentNesting', $stack); + $context->register('InputZipper', $zipper); + $context->register('CurrentToken', $token); + + // -- begin INJECTOR -- + + $this->injectors = array(); + + $injectors = $config->getBatch('AutoFormat'); + $def_injectors = $definition->info_injector; + $custom_injectors = $injectors['Custom']; + unset($injectors['Custom']); // special case + foreach ($injectors as $injector => $b) { + // XXX: Fix with a legitimate lookup table of enabled filters + if (strpos($injector, '.') !== false) { + continue; + } + $injector = "HTMLPurifier_Injector_$injector"; + if (!$b) { + continue; + } + $this->injectors[] = new $injector; + } + foreach ($def_injectors as $injector) { + // assumed to be objects + $this->injectors[] = $injector; + } + foreach ($custom_injectors as $injector) { + if (!$injector) { + continue; + } + if (is_string($injector)) { + $injector = "HTMLPurifier_Injector_$injector"; + $injector = new $injector; + } + $this->injectors[] = $injector; + } + + // give the injectors references to the definition and context + // variables for performance reasons + foreach ($this->injectors as $ix => $injector) { + $error = $injector->prepare($config, $context); + if (!$error) { + continue; + } + array_splice($this->injectors, $ix, 1); // rm the injector + trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING); + } + + // -- end INJECTOR -- + + // a note on reprocessing: + // In order to reduce code duplication, whenever some code needs + // to make HTML changes in order to make things "correct", the + // new HTML gets sent through the purifier, regardless of its + // status. This means that if we add a start token, because it + // was totally necessary, we don't have to update nesting; we just + // punt ($reprocess = true; continue;) and it does that for us. + + // isset is in loop because $tokens size changes during loop exec + for (;; + // only increment if we don't need to reprocess + $reprocess ? $reprocess = false : $token = $zipper->next($token)) { + + // check for a rewind + if (is_int($i)) { + // possibility: disable rewinding if the current token has a + // rewind set on it already. This would offer protection from + // infinite loop, but might hinder some advanced rewinding. + $rewind_offset = $this->injectors[$i]->getRewindOffset(); + if (is_int($rewind_offset)) { + for ($j = 0; $j < $rewind_offset; $j++) { + if (empty($zipper->front)) break; + $token = $zipper->prev($token); + // indicate that other injectors should not process this token, + // but we need to reprocess it. See Note [Injector skips] + unset($token->skip[$i]); + $token->rewind = $i; + if ($token instanceof HTMLPurifier_Token_Start) { + array_pop($this->stack); + } elseif ($token instanceof HTMLPurifier_Token_End) { + $this->stack[] = $token->start; + } + } + } + $i = false; + } + + // handle case of document end + if ($token === NULL) { + // kill processing if stack is empty + if (empty($this->stack)) { + break; + } + + // peek + $top_nesting = array_pop($this->stack); + $this->stack[] = $top_nesting; + + // send error [TagClosedSuppress] + if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting); + } + + // append, don't splice, since this is the end + $token = new HTMLPurifier_Token_End($top_nesting->name); + + // punt! + $reprocess = true; + continue; + } + + //echo '
        '; printZipper($zipper, $token);//printTokens($this->stack); + //flush(); + + // quick-check: if it's not a tag, no need to process + if (empty($token->is_tag)) { + if ($token instanceof HTMLPurifier_Token_Text) { + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) { + // See Note [Injector skips] + continue; + } + if ($token->rewind !== null && $token->rewind !== $i) { + continue; + } + // XXX fuckup + $r = $token; + $injector->handleText($r); + $token = $this->processToken($r, $i); + $reprocess = true; + break; + } + } + // another possibility is a comment + continue; + } + + if (isset($definition->info[$token->name])) { + $type = $definition->info[$token->name]->child->type; + } else { + $type = false; // Type is unknown, treat accordingly + } + + // quick tag checks: anything that's *not* an end tag + $ok = false; + if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) { + // claims to be a start tag but is empty + $token = new HTMLPurifier_Token_Empty( + $token->name, + $token->attr, + $token->line, + $token->col, + $token->armor + ); + $ok = true; + } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) { + // claims to be empty but really is a start tag + // NB: this assignment is required + $old_token = $token; + $token = new HTMLPurifier_Token_End($token->name); + $token = $this->insertBefore( + new HTMLPurifier_Token_Start($old_token->name, $old_token->attr, $old_token->line, $old_token->col, $old_token->armor) + ); + // punt (since we had to modify the input stream in a non-trivial way) + $reprocess = true; + continue; + } elseif ($token instanceof HTMLPurifier_Token_Empty) { + // real empty token + $ok = true; + } elseif ($token instanceof HTMLPurifier_Token_Start) { + // start tag + + // ...unless they also have to close their parent + if (!empty($this->stack)) { + + // Performance note: you might think that it's rather + // inefficient, recalculating the autoclose information + // for every tag that a token closes (since when we + // do an autoclose, we push a new token into the + // stream and then /process/ that, before + // re-processing this token.) But this is + // necessary, because an injector can make an + // arbitrary transformations to the autoclosing + // tokens we introduce, so things may have changed + // in the meantime. Also, doing the inefficient thing is + // "easy" to reason about (for certain perverse definitions + // of "easy") + + $parent = array_pop($this->stack); + $this->stack[] = $parent; + + $parent_def = null; + $parent_elements = null; + $autoclose = false; + if (isset($definition->info[$parent->name])) { + $parent_def = $definition->info[$parent->name]; + $parent_elements = $parent_def->child->getAllowedElements($config); + $autoclose = !isset($parent_elements[$token->name]); + } + + if ($autoclose && $definition->info[$token->name]->wrap) { + // Check if an element can be wrapped by another + // element to make it valid in a context (for + // example,
            needs a
          • in between) + $wrapname = $definition->info[$token->name]->wrap; + $wrapdef = $definition->info[$wrapname]; + $elements = $wrapdef->child->getAllowedElements($config); + if (isset($elements[$token->name]) && isset($parent_elements[$wrapname])) { + $newtoken = new HTMLPurifier_Token_Start($wrapname); + $token = $this->insertBefore($newtoken); + $reprocess = true; + continue; + } + } + + $carryover = false; + if ($autoclose && $parent_def->formatting) { + $carryover = true; + } + + if ($autoclose) { + // check if this autoclose is doomed to fail + // (this rechecks $parent, which his harmless) + $autoclose_ok = isset($global_parent_allowed_elements[$token->name]); + if (!$autoclose_ok) { + foreach ($this->stack as $ancestor) { + $elements = $definition->info[$ancestor->name]->child->getAllowedElements($config); + if (isset($elements[$token->name])) { + $autoclose_ok = true; + break; + } + if ($definition->info[$token->name]->wrap) { + $wrapname = $definition->info[$token->name]->wrap; + $wrapdef = $definition->info[$wrapname]; + $wrap_elements = $wrapdef->child->getAllowedElements($config); + if (isset($wrap_elements[$token->name]) && isset($elements[$wrapname])) { + $autoclose_ok = true; + break; + } + } + } + } + if ($autoclose_ok) { + // errors need to be updated + $new_token = new HTMLPurifier_Token_End($parent->name); + $new_token->start = $parent; + // [TagClosedSuppress] + if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) { + if (!$carryover) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent); + } else { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent); + } + } + if ($carryover) { + $element = clone $parent; + // [TagClosedAuto] + $element->armor['MakeWellFormed_TagClosedError'] = true; + $element->carryover = true; + $token = $this->processToken(array($new_token, $token, $element)); + } else { + $token = $this->insertBefore($new_token); + } + } else { + $token = $this->remove(); + } + $reprocess = true; + continue; + } + + } + $ok = true; + } + + if ($ok) { + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) { + // See Note [Injector skips] + continue; + } + if ($token->rewind !== null && $token->rewind !== $i) { + continue; + } + $r = $token; + $injector->handleElement($r); + $token = $this->processToken($r, $i); + $reprocess = true; + break; + } + if (!$reprocess) { + // ah, nothing interesting happened; do normal processing + if ($token instanceof HTMLPurifier_Token_Start) { + $this->stack[] = $token; + } elseif ($token instanceof HTMLPurifier_Token_End) { + throw new HTMLPurifier_Exception( + 'Improper handling of end tag in start code; possible error in MakeWellFormed' + ); + } + } + continue; + } + + // sanity check: we should be dealing with a closing tag + if (!$token instanceof HTMLPurifier_Token_End) { + throw new HTMLPurifier_Exception('Unaccounted for tag token in input stream, bug in HTML Purifier'); + } + + // make sure that we have something open + if (empty($this->stack)) { + if ($escape_invalid_tags) { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text'); + } + $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token)); + } else { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed'); + } + $token = $this->remove(); + } + $reprocess = true; + continue; + } + + // first, check for the simplest case: everything closes neatly. + // Eventually, everything passes through here; if there are problems + // we modify the input stream accordingly and then punt, so that + // the tokens get processed again. + $current_parent = array_pop($this->stack); + if ($current_parent->name == $token->name) { + $token->start = $current_parent; + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) { + // See Note [Injector skips] + continue; + } + if ($token->rewind !== null && $token->rewind !== $i) { + continue; + } + $r = $token; + $injector->handleEnd($r); + $token = $this->processToken($r, $i); + $this->stack[] = $current_parent; + $reprocess = true; + break; + } + continue; + } + + // okay, so we're trying to close the wrong tag + + // undo the pop previous pop + $this->stack[] = $current_parent; + + // scroll back the entire nest, trying to find our tag. + // (feature could be to specify how far you'd like to go) + $size = count($this->stack); + // -2 because -1 is the last element, but we already checked that + $skipped_tags = false; + for ($j = $size - 2; $j >= 0; $j--) { + if ($this->stack[$j]->name == $token->name) { + $skipped_tags = array_slice($this->stack, $j); + break; + } + } + + // we didn't find the tag, so remove + if ($skipped_tags === false) { + if ($escape_invalid_tags) { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text'); + } + $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token)); + } else { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed'); + } + $token = $this->remove(); + } + $reprocess = true; + continue; + } + + // do errors, in REVERSE $j order: a,b,c with + $c = count($skipped_tags); + if ($e) { + for ($j = $c - 1; $j > 0; $j--) { + // notice we exclude $j == 0, i.e. the current ending tag, from + // the errors... [TagClosedSuppress] + if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]); + } + } + } + + // insert tags, in FORWARD $j order: c,b,a with + $replace = array($token); + for ($j = 1; $j < $c; $j++) { + // ...as well as from the insertions + $new_token = new HTMLPurifier_Token_End($skipped_tags[$j]->name); + $new_token->start = $skipped_tags[$j]; + array_unshift($replace, $new_token); + if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) { + // [TagClosedAuto] + $element = clone $skipped_tags[$j]; + $element->carryover = true; + $element->armor['MakeWellFormed_TagClosedError'] = true; + $replace[] = $element; + } + } + $token = $this->processToken($replace); + $reprocess = true; + continue; + } + + $context->destroy('CurrentToken'); + $context->destroy('CurrentNesting'); + $context->destroy('InputZipper'); + + unset($this->injectors, $this->stack, $this->tokens); + return $zipper->toArray($token); + } + + /** + * Processes arbitrary token values for complicated substitution patterns. + * In general: + * + * If $token is an array, it is a list of tokens to substitute for the + * current token. These tokens then get individually processed. If there + * is a leading integer in the list, that integer determines how many + * tokens from the stream should be removed. + * + * If $token is a regular token, it is swapped with the current token. + * + * If $token is false, the current token is deleted. + * + * If $token is an integer, that number of tokens (with the first token + * being the current one) will be deleted. + * + * @param HTMLPurifier_Token|array|int|bool $token Token substitution value + * @param HTMLPurifier_Injector|int $injector Injector that performed the substitution; default is if + * this is not an injector related operation. + * @throws HTMLPurifier_Exception + */ + protected function processToken($token, $injector = -1) + { + // Zend OpCache miscompiles $token = array($token), so + // avoid this pattern. See: https://github.com/ezyang/htmlpurifier/issues/108 + + // normalize forms of token + if (is_object($token)) { + $tmp = $token; + $token = array(1, $tmp); + } + if (is_int($token)) { + $tmp = $token; + $token = array($tmp); + } + if ($token === false) { + $token = array(1); + } + if (!is_array($token)) { + throw new HTMLPurifier_Exception('Invalid token type from injector'); + } + if (!is_int($token[0])) { + array_unshift($token, 1); + } + if ($token[0] === 0) { + throw new HTMLPurifier_Exception('Deleting zero tokens is not valid'); + } + + // $token is now an array with the following form: + // array(number nodes to delete, new node 1, new node 2, ...) + + $delete = array_shift($token); + list($old, $r) = $this->zipper->splice($this->token, $delete, $token); + + if ($injector > -1) { + // See Note [Injector skips] + // Determine appropriate skips. Here's what the code does: + // *If* we deleted one or more tokens, copy the skips + // of those tokens into the skips of the new tokens (in $token). + // Also, mark the newly inserted tokens as having come from + // $injector. + $oldskip = isset($old[0]) ? $old[0]->skip : array(); + foreach ($token as $object) { + $object->skip = $oldskip; + $object->skip[$injector] = true; + } + } + + return $r; + + } + + /** + * Inserts a token before the current token. Cursor now points to + * this token. You must reprocess after this. + * @param HTMLPurifier_Token $token + */ + private function insertBefore($token) + { + // NB not $this->zipper->insertBefore(), due to positioning + // differences + $splice = $this->zipper->splice($this->token, 0, array($token)); + + return $splice[1]; + } + + /** + * Removes current token. Cursor now points to new token occupying previously + * occupied space. You must reprocess after this. + */ + private function remove() + { + return $this->zipper->delete(); + } +} + +// Note [Injector skips] +// ~~~~~~~~~~~~~~~~~~~~~ +// When I originally designed this class, the idea behind the 'skip' +// property of HTMLPurifier_Token was to help avoid infinite loops +// in injector processing. For example, suppose you wrote an injector +// that bolded swear words. Naively, you might write it so that +// whenever you saw ****, you replaced it with ****. +// +// When this happens, we will reprocess all of the tokens with the +// other injectors. Now there is an opportunity for infinite loop: +// if we rerun the swear-word injector on these tokens, we might +// see **** and then reprocess again to get +// **** ad infinitum. +// +// Thus, the idea of a skip is that once we process a token with +// an injector, we mark all of those tokens as having "come from" +// the injector, and we never run the injector again on these +// tokens. +// +// There were two more complications, however: +// +// - With HTMLPurifier_Injector_RemoveEmpty, we noticed that if +// you had , after you removed the , you +// really would like this injector to go back and reprocess +// the tag, discovering that it is now empty and can be +// removed. So we reintroduced the possibility of infinite looping +// by adding a "rewind" function, which let you go back to an +// earlier point in the token stream and reprocess it with injectors. +// Needless to say, we need to UN-skip the token so it gets +// reprocessed. +// +// - Suppose that you successfuly process a token, replace it with +// one with your skip mark, but now another injector wants to +// process the skipped token with another token. Should you continue +// to skip that new token, or reprocess it? If you reprocess, +// you can end up with an infinite loop where one injector converts +// to , and then another injector converts it back. So +// we inherit the skips, but for some reason, I thought that we +// should inherit the skip from the first token of the token +// that we deleted. Why? Well, it seems to work OK. +// +// If I were to redesign this functionality, I would absolutely not +// go about doing it this way: the semantics are just not very well +// defined, and in any case you probably wanted to operate on trees, +// not token streams. + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/RemoveForeignElements.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/RemoveForeignElements.php new file mode 100644 index 0000000..1a8149e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/RemoveForeignElements.php @@ -0,0 +1,207 @@ +getHTMLDefinition(); + $generator = new HTMLPurifier_Generator($config, $context); + $result = array(); + + $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); + $remove_invalid_img = $config->get('Core.RemoveInvalidImg'); + + // currently only used to determine if comments should be kept + $trusted = $config->get('HTML.Trusted'); + $comment_lookup = $config->get('HTML.AllowedComments'); + $comment_regexp = $config->get('HTML.AllowedCommentsRegexp'); + $check_comments = $comment_lookup !== array() || $comment_regexp !== null; + + $remove_script_contents = $config->get('Core.RemoveScriptContents'); + $hidden_elements = $config->get('Core.HiddenElements'); + + // remove script contents compatibility + if ($remove_script_contents === true) { + $hidden_elements['script'] = true; + } elseif ($remove_script_contents === false && isset($hidden_elements['script'])) { + unset($hidden_elements['script']); + } + + $attr_validator = new HTMLPurifier_AttrValidator(); + + // removes tokens until it reaches a closing tag with its value + $remove_until = false; + + // converts comments into text tokens when this is equal to a tag name + $textify_comments = false; + + $token = false; + $context->register('CurrentToken', $token); + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + foreach ($tokens as $token) { + if ($remove_until) { + if (empty($token->is_tag) || $token->name !== $remove_until) { + continue; + } + } + if (!empty($token->is_tag)) { + // DEFINITION CALL + + // before any processing, try to transform the element + if (isset($definition->info_tag_transform[$token->name])) { + $original_name = $token->name; + // there is a transformation for this tag + // DEFINITION CALL + $token = $definition-> + info_tag_transform[$token->name]->transform($token, $config, $context); + if ($e) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name); + } + } + + if (isset($definition->info[$token->name])) { + // mostly everything's good, but + // we need to make sure required attributes are in order + if (($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) && + $definition->info[$token->name]->required_attr && + ($token->name != 'img' || $remove_invalid_img) // ensure config option still works + ) { + $attr_validator->validateToken($token, $config, $context); + $ok = true; + foreach ($definition->info[$token->name]->required_attr as $name) { + if (!isset($token->attr[$name])) { + $ok = false; + break; + } + } + if (!$ok) { + if ($e) { + $e->send( + E_ERROR, + 'Strategy_RemoveForeignElements: Missing required attribute', + $name + ); + } + continue; + } + $token->armor['ValidateAttributes'] = true; + } + + if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) { + $textify_comments = $token->name; + } elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) { + $textify_comments = false; + } + + } elseif ($escape_invalid_tags) { + // invalid tag, generate HTML representation and insert in + if ($e) { + $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text'); + } + $token = new HTMLPurifier_Token_Text( + $generator->generateFromToken($token) + ); + } else { + // check if we need to destroy all of the tag's children + // CAN BE GENERICIZED + if (isset($hidden_elements[$token->name])) { + if ($token instanceof HTMLPurifier_Token_Start) { + $remove_until = $token->name; + } elseif ($token instanceof HTMLPurifier_Token_Empty) { + // do nothing: we're still looking + } else { + $remove_until = false; + } + if ($e) { + $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed'); + } + } else { + if ($e) { + $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed'); + } + } + continue; + } + } elseif ($token instanceof HTMLPurifier_Token_Comment) { + // textify comments in script tags when they are allowed + if ($textify_comments !== false) { + $data = $token->data; + $token = new HTMLPurifier_Token_Text($data); + } elseif ($trusted || $check_comments) { + // always cleanup comments + $trailing_hyphen = false; + if ($e) { + // perform check whether or not there's a trailing hyphen + if (substr($token->data, -1) == '-') { + $trailing_hyphen = true; + } + } + $token->data = rtrim($token->data, '-'); + $found_double_hyphen = false; + while (strpos($token->data, '--') !== false) { + $found_double_hyphen = true; + $token->data = str_replace('--', '-', $token->data); + } + if ($trusted || !empty($comment_lookup[trim($token->data)]) || + ($comment_regexp !== null && preg_match($comment_regexp, trim($token->data)))) { + // OK good + if ($e) { + if ($trailing_hyphen) { + $e->send( + E_NOTICE, + 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' + ); + } + if ($found_double_hyphen) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed'); + } + } + } else { + if ($e) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed'); + } + continue; + } + } else { + // strip comments + if ($e) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed'); + } + continue; + } + } elseif ($token instanceof HTMLPurifier_Token_Text) { + } else { + continue; + } + $result[] = $token; + } + if ($remove_until && $e) { + // we removed tokens until the end, throw error + $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until); + } + $context->destroy('CurrentToken'); + return $result; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/ValidateAttributes.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/ValidateAttributes.php new file mode 100644 index 0000000..fbb3d27 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Strategy/ValidateAttributes.php @@ -0,0 +1,45 @@ +register('CurrentToken', $token); + + foreach ($tokens as $key => $token) { + + // only process tokens that have attributes, + // namely start and empty tags + if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) { + continue; + } + + // skip tokens that are armored + if (!empty($token->armor['ValidateAttributes'])) { + continue; + } + + // note that we have no facilities here for removing tokens + $validator->validateToken($token, $config, $context); + } + $context->destroy('CurrentToken'); + return $tokens; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/StringHash.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/StringHash.php new file mode 100644 index 0000000..c41ae3a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/StringHash.php @@ -0,0 +1,48 @@ +accessed[$index] = true; + return parent::offsetGet($index); + } + + /** + * Returns a lookup array of all array indexes that have been accessed. + * @return array in form array($index => true). + */ + public function getAccessed() + { + return $this->accessed; + } + + /** + * Resets the access array. + */ + public function resetAccessed() + { + $this->accessed = array(); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/StringHashParser.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/StringHashParser.php new file mode 100644 index 0000000..7c73f80 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/StringHashParser.php @@ -0,0 +1,136 @@ + 'DefaultKeyValue', + * 'KEY' => 'Value', + * 'KEY2' => 'Value2', + * 'MULTILINE-KEY' => "Multiline\nvalue.\n", + * ) + * + * We use this as an easy to use file-format for configuration schema + * files, but the class itself is usage agnostic. + * + * You can use ---- to forcibly terminate parsing of a single string-hash; + * this marker is used in multi string-hashes to delimit boundaries. + */ +class HTMLPurifier_StringHashParser +{ + + /** + * @type string + */ + public $default = 'ID'; + + /** + * Parses a file that contains a single string-hash. + * @param string $file + * @return array + */ + public function parseFile($file) + { + if (!file_exists($file)) { + return false; + } + $fh = fopen($file, 'r'); + if (!$fh) { + return false; + } + $ret = $this->parseHandle($fh); + fclose($fh); + return $ret; + } + + /** + * Parses a file that contains multiple string-hashes delimited by '----' + * @param string $file + * @return array + */ + public function parseMultiFile($file) + { + if (!file_exists($file)) { + return false; + } + $ret = array(); + $fh = fopen($file, 'r'); + if (!$fh) { + return false; + } + while (!feof($fh)) { + $ret[] = $this->parseHandle($fh); + } + fclose($fh); + return $ret; + } + + /** + * Internal parser that acepts a file handle. + * @note While it's possible to simulate in-memory parsing by using + * custom stream wrappers, if such a use-case arises we should + * factor out the file handle into its own class. + * @param resource $fh File handle with pointer at start of valid string-hash + * block. + * @return array + */ + protected function parseHandle($fh) + { + $state = false; + $single = false; + $ret = array(); + do { + $line = fgets($fh); + if ($line === false) { + break; + } + $line = rtrim($line, "\n\r"); + if (!$state && $line === '') { + continue; + } + if ($line === '----') { + break; + } + if (strncmp('--#', $line, 3) === 0) { + // Comment + continue; + } elseif (strncmp('--', $line, 2) === 0) { + // Multiline declaration + $state = trim($line, '- '); + if (!isset($ret[$state])) { + $ret[$state] = ''; + } + continue; + } elseif (!$state) { + $single = true; + if (strpos($line, ':') !== false) { + // Single-line declaration + list($state, $line) = explode(':', $line, 2); + $line = trim($line); + } else { + // Use default declaration + $state = $this->default; + } + } + if ($single) { + $ret[$state] = $line; + $single = false; + $state = false; + } else { + $ret[$state] .= "$line\n"; + } + } while (!feof($fh)); + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TagTransform.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TagTransform.php new file mode 100644 index 0000000..7b8d833 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TagTransform.php @@ -0,0 +1,37 @@ + 'xx-small', + '1' => 'xx-small', + '2' => 'small', + '3' => 'medium', + '4' => 'large', + '5' => 'x-large', + '6' => 'xx-large', + '7' => '300%', + '-1' => 'smaller', + '-2' => '60%', + '+1' => 'larger', + '+2' => '150%', + '+3' => '200%', + '+4' => '300%' + ); + + /** + * @param HTMLPurifier_Token_Tag $tag + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token_End|string + */ + public function transform($tag, $config, $context) + { + if ($tag instanceof HTMLPurifier_Token_End) { + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + return $new_tag; + } + + $attr = $tag->attr; + $prepend_style = ''; + + // handle color transform + if (isset($attr['color'])) { + $prepend_style .= 'color:' . $attr['color'] . ';'; + unset($attr['color']); + } + + // handle face transform + if (isset($attr['face'])) { + $prepend_style .= 'font-family:' . $attr['face'] . ';'; + unset($attr['face']); + } + + // handle size transform + if (isset($attr['size'])) { + // normalize large numbers + if ($attr['size'] !== '') { + if ($attr['size'][0] == '+' || $attr['size'][0] == '-') { + $size = (int)$attr['size']; + if ($size < -2) { + $attr['size'] = '-2'; + } + if ($size > 4) { + $attr['size'] = '+4'; + } + } else { + $size = (int)$attr['size']; + if ($size > 7) { + $attr['size'] = '7'; + } + } + } + if (isset($this->_size_lookup[$attr['size']])) { + $prepend_style .= 'font-size:' . + $this->_size_lookup[$attr['size']] . ';'; + } + unset($attr['size']); + } + + if ($prepend_style) { + $attr['style'] = isset($attr['style']) ? + $prepend_style . $attr['style'] : + $prepend_style; + } + + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + $new_tag->attr = $attr; + + return $new_tag; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TagTransform/Simple.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TagTransform/Simple.php new file mode 100644 index 0000000..71bf10b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TagTransform/Simple.php @@ -0,0 +1,44 @@ +transform_to = $transform_to; + $this->style = $style; + } + + /** + * @param HTMLPurifier_Token_Tag $tag + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function transform($tag, $config, $context) + { + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + if (!is_null($this->style) && + ($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty) + ) { + $this->prependCSS($new_tag->attr, $this->style); + } + return $new_tag; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token.php new file mode 100644 index 0000000..84d3619 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token.php @@ -0,0 +1,100 @@ +line = $l; + $this->col = $c; + } + + /** + * Convenience function for DirectLex settings line/col position. + * @param int $l + * @param int $c + */ + public function rawPosition($l, $c) + { + if ($c === -1) { + $l++; + } + $this->line = $l; + $this->col = $c; + } + + /** + * Converts a token into its corresponding node. + */ + abstract public function toNode(); +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Comment.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Comment.php new file mode 100644 index 0000000..23453c7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Comment.php @@ -0,0 +1,38 @@ +data = $data; + $this->line = $line; + $this->col = $col; + } + + public function toNode() { + return new HTMLPurifier_Node_Comment($this->data, $this->line, $this->col); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Empty.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Empty.php new file mode 100644 index 0000000..78a95f5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Empty.php @@ -0,0 +1,15 @@ +empty = true; + return $n; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/End.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/End.php new file mode 100644 index 0000000..59b38fd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/End.php @@ -0,0 +1,24 @@ +toNode not supported!"); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Start.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Start.php new file mode 100644 index 0000000..019f317 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Start.php @@ -0,0 +1,10 @@ +!empty($obj->is_tag) + * without having to use a function call is_a(). + * @type bool + */ + public $is_tag = true; + + /** + * The lower-case name of the tag, like 'a', 'b' or 'blockquote'. + * + * @note Strictly speaking, XML tags are case sensitive, so we shouldn't + * be lower-casing them, but these tokens cater to HTML tags, which are + * insensitive. + * @type string + */ + public $name; + + /** + * Associative array of the tag's attributes. + * @type array + */ + public $attr = array(); + + /** + * Non-overloaded constructor, which lower-cases passed tag name. + * + * @param string $name String name. + * @param array $attr Associative array of attributes. + * @param int $line + * @param int $col + * @param array $armor + */ + public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) + { + $this->name = ctype_lower($name) ? $name : strtolower($name); + foreach ($attr as $key => $value) { + // normalization only necessary when key is not lowercase + if (!ctype_lower((string)$key)) { + $new_key = strtolower($key); + if (!isset($attr[$new_key])) { + $attr[$new_key] = $attr[$key]; + } + if ($new_key !== $key) { + unset($attr[$key]); + } + } + } + $this->attr = $attr; + $this->line = $line; + $this->col = $col; + $this->armor = $armor; + } + + public function toNode() { + return new HTMLPurifier_Node_Element($this->name, $this->attr, $this->line, $this->col, $this->armor); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Text.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Text.php new file mode 100644 index 0000000..f26a1c2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/Token/Text.php @@ -0,0 +1,53 @@ +data = $data; + $this->is_whitespace = ctype_space($data); + $this->line = $line; + $this->col = $col; + } + + public function toNode() { + return new HTMLPurifier_Node_Text($this->data, $this->is_whitespace, $this->line, $this->col); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TokenFactory.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TokenFactory.php new file mode 100644 index 0000000..dea2446 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/TokenFactory.php @@ -0,0 +1,118 @@ +p_start = new HTMLPurifier_Token_Start('', array()); + $this->p_end = new HTMLPurifier_Token_End(''); + $this->p_empty = new HTMLPurifier_Token_Empty('', array()); + $this->p_text = new HTMLPurifier_Token_Text(''); + $this->p_comment = new HTMLPurifier_Token_Comment(''); + } + + /** + * Creates a HTMLPurifier_Token_Start. + * @param string $name Tag name + * @param array $attr Associative array of attributes + * @return HTMLPurifier_Token_Start Generated HTMLPurifier_Token_Start + */ + public function createStart($name, $attr = array()) + { + $p = clone $this->p_start; + $p->__construct($name, $attr); + return $p; + } + + /** + * Creates a HTMLPurifier_Token_End. + * @param string $name Tag name + * @return HTMLPurifier_Token_End Generated HTMLPurifier_Token_End + */ + public function createEnd($name) + { + $p = clone $this->p_end; + $p->__construct($name); + return $p; + } + + /** + * Creates a HTMLPurifier_Token_Empty. + * @param string $name Tag name + * @param array $attr Associative array of attributes + * @return HTMLPurifier_Token_Empty Generated HTMLPurifier_Token_Empty + */ + public function createEmpty($name, $attr = array()) + { + $p = clone $this->p_empty; + $p->__construct($name, $attr); + return $p; + } + + /** + * Creates a HTMLPurifier_Token_Text. + * @param string $data Data of text token + * @return HTMLPurifier_Token_Text Generated HTMLPurifier_Token_Text + */ + public function createText($data) + { + $p = clone $this->p_text; + $p->__construct($data); + return $p; + } + + /** + * Creates a HTMLPurifier_Token_Comment. + * @param string $data Data of comment token + * @return HTMLPurifier_Token_Comment Generated HTMLPurifier_Token_Comment + */ + public function createComment($data) + { + $p = clone $this->p_comment; + $p->__construct($data); + return $p; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URI.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URI.php new file mode 100644 index 0000000..9c5be39 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URI.php @@ -0,0 +1,316 @@ +scheme = is_null($scheme) || ctype_lower($scheme) ? $scheme : strtolower($scheme); + $this->userinfo = $userinfo; + $this->host = $host; + $this->port = is_null($port) ? $port : (int)$port; + $this->path = $path; + $this->query = $query; + $this->fragment = $fragment; + } + + /** + * Retrieves a scheme object corresponding to the URI's scheme/default + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_URIScheme Scheme object appropriate for validating this URI + */ + public function getSchemeObj($config, $context) + { + $registry = HTMLPurifier_URISchemeRegistry::instance(); + if ($this->scheme !== null) { + $scheme_obj = $registry->getScheme($this->scheme, $config, $context); + if (!$scheme_obj) { + return false; + } // invalid scheme, clean it out + } else { + // no scheme: retrieve the default one + $def = $config->getDefinition('URI'); + $scheme_obj = $def->getDefaultScheme($config, $context); + if (!$scheme_obj) { + if ($def->defaultScheme !== null) { + // something funky happened to the default scheme object + trigger_error( + 'Default scheme object "' . $def->defaultScheme . '" was not readable', + E_USER_WARNING + ); + } // suppress error if it's null + return false; + } + } + return $scheme_obj; + } + + /** + * Generic validation method applicable for all schemes. May modify + * this URI in order to get it into a compliant form. + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool True if validation/filtering succeeds, false if failure + */ + public function validate($config, $context) + { + // ABNF definitions from RFC 3986 + $chars_sub_delims = '!$&\'()*+,;='; + $chars_gen_delims = ':/?#[]@'; + $chars_pchar = $chars_sub_delims . ':@'; + + // validate host + if (!is_null($this->host)) { + $host_def = new HTMLPurifier_AttrDef_URI_Host(); + $this->host = $host_def->validate($this->host, $config, $context); + if ($this->host === false) { + $this->host = null; + } + } + + // validate scheme + // NOTE: It's not appropriate to check whether or not this + // scheme is in our registry, since a URIFilter may convert a + // URI that we don't allow into one we do. So instead, we just + // check if the scheme can be dropped because there is no host + // and it is our default scheme. + if (!is_null($this->scheme) && is_null($this->host) || $this->host === '') { + // support for relative paths is pretty abysmal when the + // scheme is present, so axe it when possible + $def = $config->getDefinition('URI'); + if ($def->defaultScheme === $this->scheme) { + $this->scheme = null; + } + } + + // validate username + if (!is_null($this->userinfo)) { + $encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . ':'); + $this->userinfo = $encoder->encode($this->userinfo); + } + + // validate port + if (!is_null($this->port)) { + if ($this->port < 1 || $this->port > 65535) { + $this->port = null; + } + } + + // validate path + $segments_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/'); + if (!is_null($this->host)) { // this catches $this->host === '' + // path-abempty (hier and relative) + // http://www.example.com/my/path + // //www.example.com/my/path (looks odd, but works, and + // recognized by most browsers) + // (this set is valid or invalid on a scheme by scheme + // basis, so we'll deal with it later) + // file:///my/path + // ///my/path + $this->path = $segments_encoder->encode($this->path); + } elseif ($this->path !== '') { + if ($this->path[0] === '/') { + // path-absolute (hier and relative) + // http:/my/path + // /my/path + if (strlen($this->path) >= 2 && $this->path[1] === '/') { + // This could happen if both the host gets stripped + // out + // http://my/path + // //my/path + $this->path = ''; + } else { + $this->path = $segments_encoder->encode($this->path); + } + } elseif (!is_null($this->scheme)) { + // path-rootless (hier) + // http:my/path + // Short circuit evaluation means we don't need to check nz + $this->path = $segments_encoder->encode($this->path); + } else { + // path-noscheme (relative) + // my/path + // (once again, not checking nz) + $segment_nc_encoder = new HTMLPurifier_PercentEncoder($chars_sub_delims . '@'); + $c = strpos($this->path, '/'); + if ($c !== false) { + $this->path = + $segment_nc_encoder->encode(substr($this->path, 0, $c)) . + $segments_encoder->encode(substr($this->path, $c)); + } else { + $this->path = $segment_nc_encoder->encode($this->path); + } + } + } else { + // path-empty (hier and relative) + $this->path = ''; // just to be safe + } + + // qf = query and fragment + $qf_encoder = new HTMLPurifier_PercentEncoder($chars_pchar . '/?'); + + if (!is_null($this->query)) { + $this->query = $qf_encoder->encode($this->query); + } + + if (!is_null($this->fragment)) { + $this->fragment = $qf_encoder->encode($this->fragment); + } + return true; + } + + /** + * Convert URI back to string + * @return string URI appropriate for output + */ + public function toString() + { + // reconstruct authority + $authority = null; + // there is a rendering difference between a null authority + // (http:foo-bar) and an empty string authority + // (http:///foo-bar). + if (!is_null($this->host)) { + $authority = ''; + if (!is_null($this->userinfo)) { + $authority .= $this->userinfo . '@'; + } + $authority .= $this->host; + if (!is_null($this->port)) { + $authority .= ':' . $this->port; + } + } + + // Reconstruct the result + // One might wonder about parsing quirks from browsers after + // this reconstruction. Unfortunately, parsing behavior depends + // on what *scheme* was employed (file:///foo is handled *very* + // differently than http:///foo), so unfortunately we have to + // defer to the schemes to do the right thing. + $result = ''; + if (!is_null($this->scheme)) { + $result .= $this->scheme . ':'; + } + if (!is_null($authority)) { + $result .= '//' . $authority; + } + $result .= $this->path; + if (!is_null($this->query)) { + $result .= '?' . $this->query; + } + if (!is_null($this->fragment)) { + $result .= '#' . $this->fragment; + } + + return $result; + } + + /** + * Returns true if this URL might be considered a 'local' URL given + * the current context. This is true when the host is null, or + * when it matches the host supplied to the configuration. + * + * Note that this does not do any scheme checking, so it is mostly + * only appropriate for metadata that doesn't care about protocol + * security. isBenign is probably what you actually want. + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function isLocal($config, $context) + { + if ($this->host === null) { + return true; + } + $uri_def = $config->getDefinition('URI'); + if ($uri_def->host === $this->host) { + return true; + } + return false; + } + + /** + * Returns true if this URL should be considered a 'benign' URL, + * that is: + * + * - It is a local URL (isLocal), and + * - It has a equal or better level of security + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function isBenign($config, $context) + { + if (!$this->isLocal($config, $context)) { + return false; + } + + $scheme_obj = $this->getSchemeObj($config, $context); + if (!$scheme_obj) { + return false; + } // conservative approach + + $current_scheme_obj = $config->getDefinition('URI')->getDefaultScheme($config, $context); + if ($current_scheme_obj->secure) { + if (!$scheme_obj->secure) { + return false; + } + } + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIDefinition.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIDefinition.php new file mode 100644 index 0000000..e0bd8bc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIDefinition.php @@ -0,0 +1,112 @@ +registerFilter(new HTMLPurifier_URIFilter_DisableExternal()); + $this->registerFilter(new HTMLPurifier_URIFilter_DisableExternalResources()); + $this->registerFilter(new HTMLPurifier_URIFilter_DisableResources()); + $this->registerFilter(new HTMLPurifier_URIFilter_HostBlacklist()); + $this->registerFilter(new HTMLPurifier_URIFilter_SafeIframe()); + $this->registerFilter(new HTMLPurifier_URIFilter_MakeAbsolute()); + $this->registerFilter(new HTMLPurifier_URIFilter_Munge()); + } + + public function registerFilter($filter) + { + $this->registeredFilters[$filter->name] = $filter; + } + + public function addFilter($filter, $config) + { + $r = $filter->prepare($config); + if ($r === false) return; // null is ok, for backwards compat + if ($filter->post) { + $this->postFilters[$filter->name] = $filter; + } else { + $this->filters[$filter->name] = $filter; + } + } + + protected function doSetup($config) + { + $this->setupMemberVariables($config); + $this->setupFilters($config); + } + + protected function setupFilters($config) + { + foreach ($this->registeredFilters as $name => $filter) { + if ($filter->always_load) { + $this->addFilter($filter, $config); + } else { + $conf = $config->get('URI.' . $name); + if ($conf !== false && $conf !== null) { + $this->addFilter($filter, $config); + } + } + } + unset($this->registeredFilters); + } + + protected function setupMemberVariables($config) + { + $this->host = $config->get('URI.Host'); + $base_uri = $config->get('URI.Base'); + if (!is_null($base_uri)) { + $parser = new HTMLPurifier_URIParser(); + $this->base = $parser->parse($base_uri); + $this->defaultScheme = $this->base->scheme; + if (is_null($this->host)) $this->host = $this->base->host; + } + if (is_null($this->defaultScheme)) $this->defaultScheme = $config->get('URI.DefaultScheme'); + } + + public function getDefaultScheme($config, $context) + { + return HTMLPurifier_URISchemeRegistry::instance()->getScheme($this->defaultScheme, $config, $context); + } + + public function filter(&$uri, $config, $context) + { + foreach ($this->filters as $name => $f) { + $result = $f->filter($uri, $config, $context); + if (!$result) return false; + } + return true; + } + + public function postFilter(&$uri, $config, $context) + { + foreach ($this->postFilters as $name => $f) { + $result = $f->filter($uri, $config, $context); + if (!$result) return false; + } + return true; + } + +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter.php new file mode 100644 index 0000000..09724e9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter.php @@ -0,0 +1,74 @@ +getDefinition('URI')->host; + if ($our_host !== null) { + $this->ourHostParts = array_reverse(explode('.', $our_host)); + } + } + + /** + * @param HTMLPurifier_URI $uri Reference + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + if (is_null($uri->host)) { + return true; + } + if ($this->ourHostParts === false) { + return false; + } + $host_parts = array_reverse(explode('.', $uri->host)); + foreach ($this->ourHostParts as $i => $x) { + if (!isset($host_parts[$i])) { + return false; + } + if ($host_parts[$i] != $this->ourHostParts[$i]) { + return false; + } + } + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/DisableExternalResources.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/DisableExternalResources.php new file mode 100644 index 0000000..c656216 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/DisableExternalResources.php @@ -0,0 +1,25 @@ +get('EmbeddedURI', true)) { + return true; + } + return parent::filter($uri, $config, $context); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/DisableResources.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/DisableResources.php new file mode 100644 index 0000000..d5c412c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/DisableResources.php @@ -0,0 +1,22 @@ +get('EmbeddedURI', true); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/HostBlacklist.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/HostBlacklist.php new file mode 100644 index 0000000..32197c0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/HostBlacklist.php @@ -0,0 +1,46 @@ +blacklist = $config->get('URI.HostBlacklist'); + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + foreach ($this->blacklist as $blacklisted_host_fragment) { + if ($uri->host !== null && strpos($uri->host, $blacklisted_host_fragment) !== false) { + return false; + } + } + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/MakeAbsolute.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/MakeAbsolute.php new file mode 100644 index 0000000..c507bbf --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/MakeAbsolute.php @@ -0,0 +1,158 @@ +getDefinition('URI'); + $this->base = $def->base; + if (is_null($this->base)) { + trigger_error( + 'URI.MakeAbsolute is being ignored due to lack of ' . + 'value for URI.Base configuration', + E_USER_WARNING + ); + return false; + } + $this->base->fragment = null; // fragment is invalid for base URI + $stack = explode('/', $this->base->path); + array_pop($stack); // discard last segment + $stack = $this->_collapseStack($stack); // do pre-parsing + $this->basePathStack = $stack; + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + if (is_null($this->base)) { + return true; + } // abort early + if ($uri->path === '' && is_null($uri->scheme) && + is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)) { + // reference to current document + $uri = clone $this->base; + return true; + } + if (!is_null($uri->scheme)) { + // absolute URI already: don't change + if (!is_null($uri->host)) { + return true; + } + $scheme_obj = $uri->getSchemeObj($config, $context); + if (!$scheme_obj) { + // scheme not recognized + return false; + } + if (!$scheme_obj->hierarchical) { + // non-hierarchal URI with explicit scheme, don't change + return true; + } + // special case: had a scheme but always is hierarchical and had no authority + } + if (!is_null($uri->host)) { + // network path, don't bother + return true; + } + if ($uri->path === '') { + $uri->path = $this->base->path; + } elseif ($uri->path[0] !== '/') { + // relative path, needs more complicated processing + $stack = explode('/', $uri->path); + $new_stack = array_merge($this->basePathStack, $stack); + if ($new_stack[0] !== '' && !is_null($this->base->host)) { + array_unshift($new_stack, ''); + } + $new_stack = $this->_collapseStack($new_stack); + $uri->path = implode('/', $new_stack); + } else { + // absolute path, but still we should collapse + $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path))); + } + // re-combine + $uri->scheme = $this->base->scheme; + if (is_null($uri->userinfo)) { + $uri->userinfo = $this->base->userinfo; + } + if (is_null($uri->host)) { + $uri->host = $this->base->host; + } + if (is_null($uri->port)) { + $uri->port = $this->base->port; + } + return true; + } + + /** + * Resolve dots and double-dots in a path stack + * @param array $stack + * @return array + */ + private function _collapseStack($stack) + { + $result = array(); + $is_folder = false; + for ($i = 0; isset($stack[$i]); $i++) { + $is_folder = false; + // absorb an internally duplicated slash + if ($stack[$i] == '' && $i && isset($stack[$i + 1])) { + continue; + } + if ($stack[$i] == '..') { + if (!empty($result)) { + $segment = array_pop($result); + if ($segment === '' && empty($result)) { + // error case: attempted to back out too far: + // restore the leading slash + $result[] = ''; + } elseif ($segment === '..') { + $result[] = '..'; // cannot remove .. with .. + } + } else { + // relative path, preserve the double-dots + $result[] = '..'; + } + $is_folder = true; + continue; + } + if ($stack[$i] == '.') { + // silently absorb + $is_folder = true; + continue; + } + $result[] = $stack[$i]; + } + if ($is_folder) { + $result[] = ''; + } + return $result; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php new file mode 100644 index 0000000..e1393de --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/Munge.php @@ -0,0 +1,115 @@ +target = $config->get('URI.' . $this->name); + $this->parser = new HTMLPurifier_URIParser(); + $this->doEmbed = $config->get('URI.MungeResources'); + $this->secretKey = $config->get('URI.MungeSecretKey'); + if ($this->secretKey && !function_exists('hash_hmac')) { + throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support."); + } + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + if ($context->get('EmbeddedURI', true) && !$this->doEmbed) { + return true; + } + + $scheme_obj = $uri->getSchemeObj($config, $context); + if (!$scheme_obj) { + return true; + } // ignore unknown schemes, maybe another postfilter did it + if (!$scheme_obj->browsable) { + return true; + } // ignore non-browseable schemes, since we can't munge those in a reasonable way + if ($uri->isBenign($config, $context)) { + return true; + } // don't redirect if a benign URL + + $this->makeReplace($uri, $config, $context); + $this->replace = array_map('rawurlencode', $this->replace); + + $new_uri = strtr($this->target, $this->replace); + $new_uri = $this->parser->parse($new_uri); + // don't redirect if the target host is the same as the + // starting host + if ($uri->host === $new_uri->host) { + return true; + } + $uri = $new_uri; // overwrite + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + */ + protected function makeReplace($uri, $config, $context) + { + $string = $uri->toString(); + // always available + $this->replace['%s'] = $string; + $this->replace['%r'] = $context->get('EmbeddedURI', true) ?: ''; + $token = $context->get('CurrentToken', true) ?: ''; + $this->replace['%n'] = $token ? $token->name : ''; + $this->replace['%m'] = $context->get('CurrentAttr', true) ?: ''; + $this->replace['%p'] = $context->get('CurrentCSSProperty', true) ?: ''; + // not always available + if ($this->secretKey) { + $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); + } + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/SafeIframe.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/SafeIframe.php new file mode 100644 index 0000000..f609c47 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIFilter/SafeIframe.php @@ -0,0 +1,68 @@ +regexp = $config->get('URI.SafeIframeRegexp'); + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + // check if filter not applicable + if (!$config->get('HTML.SafeIframe')) { + return true; + } + // check if the filter should actually trigger + if (!$context->get('EmbeddedURI', true)) { + return true; + } + $token = $context->get('CurrentToken', true); + if (!($token && $token->name == 'iframe')) { + return true; + } + // check if we actually have some whitelists enabled + if ($this->regexp === null) { + return false; + } + // actually check the whitelists + return preg_match($this->regexp, $uri->toString()); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIParser.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIParser.php new file mode 100644 index 0000000..0e7381a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIParser.php @@ -0,0 +1,71 @@ +percentEncoder = new HTMLPurifier_PercentEncoder(); + } + + /** + * Parses a URI. + * @param $uri string URI to parse + * @return HTMLPurifier_URI representation of URI. This representation has + * not been validated yet and may not conform to RFC. + */ + public function parse($uri) + { + $uri = $this->percentEncoder->normalize($uri); + + // Regexp is as per Appendix B. + // Note that ["<>] are an addition to the RFC's recommended + // characters, because they represent external delimeters. + $r_URI = '!'. + '(([a-zA-Z0-9\.\+\-]+):)?'. // 2. Scheme + '(//([^/?#"<>]*))?'. // 4. Authority + '([^?#"<>]*)'. // 5. Path + '(\?([^#"<>]*))?'. // 7. Query + '(#([^"<>]*))?'. // 8. Fragment + '!'; + + $matches = array(); + $result = preg_match($r_URI, $uri, $matches); + + if (!$result) return false; // *really* invalid URI + + // seperate out parts + $scheme = !empty($matches[1]) ? $matches[2] : null; + $authority = !empty($matches[3]) ? $matches[4] : null; + $path = $matches[5]; // always present, can be empty + $query = !empty($matches[6]) ? $matches[7] : null; + $fragment = !empty($matches[8]) ? $matches[9] : null; + + // further parse authority + if ($authority !== null) { + $r_authority = "/^((.+?)@)?(\[[^\]]+\]|[^:]*)(:(\d*))?/"; + $matches = array(); + preg_match($r_authority, $authority, $matches); + $userinfo = !empty($matches[1]) ? $matches[2] : null; + $host = !empty($matches[3]) ? $matches[3] : ''; + $port = !empty($matches[4]) ? (int) $matches[5] : null; + } else { + $port = $host = $userinfo = null; + } + + return new HTMLPurifier_URI( + $scheme, $userinfo, $host, $port, $path, $query, $fragment); + } + +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme.php new file mode 100644 index 0000000..fe9e82c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme.php @@ -0,0 +1,102 @@ +, resolves edge cases + * with making relative URIs absolute + * @type bool + */ + public $hierarchical = false; + + /** + * Whether or not the URI may omit a hostname when the scheme is + * explicitly specified, ala file:///path/to/file. As of writing, + * 'file' is the only scheme that browsers support his properly. + * @type bool + */ + public $may_omit_host = false; + + /** + * Validates the components of a URI for a specific scheme. + * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool success or failure + */ + abstract public function doValidate(&$uri, $config, $context); + + /** + * Public interface for validating components of a URI. Performs a + * bunch of default actions. Don't overload this method. + * @param HTMLPurifier_URI $uri Reference to a HTMLPurifier_URI object + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool success or failure + */ + public function validate(&$uri, $config, $context) + { + if ($this->default_port == $uri->port) { + $uri->port = null; + } + // kludge: browsers do funny things when the scheme but not the + // authority is set + if (!$this->may_omit_host && + // if the scheme is present, a missing host is always in error + (!is_null($uri->scheme) && ($uri->host === '' || is_null($uri->host))) || + // if the scheme is not present, a *blank* host is in error, + // since this translates into '///path' which most browsers + // interpret as being 'http://path'. + (is_null($uri->scheme) && $uri->host === '') + ) { + do { + if (is_null($uri->scheme)) { + if (substr($uri->path, 0, 2) != '//') { + $uri->host = null; + break; + } + // URI is '////path', so we cannot nullify the + // host to preserve semantics. Try expanding the + // hostname instead (fall through) + } + // first see if we can manually insert a hostname + $host = $config->get('URI.Host'); + if (!is_null($host)) { + $uri->host = $host; + } else { + // we can't do anything sensible, reject the URL. + return false; + } + } while (false); + } + return $this->doValidate($uri, $config, $context); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/data.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/data.php new file mode 100644 index 0000000..41c49d5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/data.php @@ -0,0 +1,136 @@ + true, + 'image/gif' => true, + 'image/png' => true, + ); + // this is actually irrelevant since we only write out the path + // component + /** + * @type bool + */ + public $may_omit_host = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $result = explode(',', $uri->path, 2); + $is_base64 = false; + $charset = null; + $content_type = null; + if (count($result) == 2) { + list($metadata, $data) = $result; + // do some legwork on the metadata + $metas = explode(';', $metadata); + while (!empty($metas)) { + $cur = array_shift($metas); + if ($cur == 'base64') { + $is_base64 = true; + break; + } + if (substr($cur, 0, 8) == 'charset=') { + // doesn't match if there are arbitrary spaces, but + // whatever dude + if ($charset !== null) { + continue; + } // garbage + $charset = substr($cur, 8); // not used + } else { + if ($content_type !== null) { + continue; + } // garbage + $content_type = $cur; + } + } + } else { + $data = $result[0]; + } + if ($content_type !== null && empty($this->allowed_types[$content_type])) { + return false; + } + if ($charset !== null) { + // error; we don't allow plaintext stuff + $charset = null; + } + $data = rawurldecode($data); + if ($is_base64) { + $raw_data = base64_decode($data); + } else { + $raw_data = $data; + } + if ( strlen($raw_data) < 12 ) { + // error; exif_imagetype throws exception with small files, + // and this likely indicates a corrupt URI/failed parse anyway + return false; + } + // XXX probably want to refactor this into a general mechanism + // for filtering arbitrary content types + if (function_exists('sys_get_temp_dir')) { + $file = tempnam(sys_get_temp_dir(), ""); + } else { + $file = tempnam("/tmp", ""); + } + file_put_contents($file, $raw_data); + if (function_exists('exif_imagetype')) { + $image_code = exif_imagetype($file); + unlink($file); + } elseif (function_exists('getimagesize')) { + set_error_handler(array($this, 'muteErrorHandler')); + $info = getimagesize($file); + restore_error_handler(); + unlink($file); + if ($info == false) { + return false; + } + $image_code = $info[2]; + } else { + trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR); + } + $real_content_type = image_type_to_mime_type($image_code); + if ($real_content_type != $content_type) { + // we're nice guys; if the content type is something else we + // support, change it over + if (empty($this->allowed_types[$real_content_type])) { + return false; + } + $content_type = $real_content_type; + } + // ok, it's kosher, rewrite what we need + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + $uri->fragment = null; + $uri->query = null; + $uri->path = "$content_type;base64," . base64_encode($raw_data); + return true; + } + + /** + * @param int $errno + * @param string $errstr + */ + public function muteErrorHandler($errno, $errstr) + { + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/file.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/file.php new file mode 100644 index 0000000..215be4b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/file.php @@ -0,0 +1,44 @@ +userinfo = null; + // file:// makes no provisions for accessing the resource + $uri->port = null; + // While it seems to work on Firefox, the querystring has + // no possible effect and is thus stripped. + $uri->query = null; + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/ftp.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/ftp.php new file mode 100644 index 0000000..1eb43ee --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/ftp.php @@ -0,0 +1,58 @@ +query = null; + + // typecode check + $semicolon_pos = strrpos($uri->path, ';'); // reverse + if ($semicolon_pos !== false) { + $type = substr($uri->path, $semicolon_pos + 1); // no semicolon + $uri->path = substr($uri->path, 0, $semicolon_pos); + $type_ret = ''; + if (strpos($type, '=') !== false) { + // figure out whether or not the declaration is correct + list($key, $typecode) = explode('=', $type, 2); + if ($key !== 'type') { + // invalid key, tack it back on encoded + $uri->path .= '%3B' . $type; + } elseif ($typecode === 'a' || $typecode === 'i' || $typecode === 'd') { + $type_ret = ";type=$typecode"; + } + } else { + $uri->path .= '%3B' . $type; + } + $uri->path = str_replace(';', '%3B', $uri->path); + $uri->path .= $type_ret; + } + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/http.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/http.php new file mode 100644 index 0000000..ce69ec4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/http.php @@ -0,0 +1,36 @@ +userinfo = null; + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/https.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/https.php new file mode 100644 index 0000000..0e96882 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/https.php @@ -0,0 +1,18 @@ +userinfo = null; + $uri->host = null; + $uri->port = null; + // we need to validate path against RFC 2368's addr-spec + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/news.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/news.php new file mode 100644 index 0000000..7490927 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/news.php @@ -0,0 +1,35 @@ +userinfo = null; + $uri->host = null; + $uri->port = null; + $uri->query = null; + // typecode check needed on path + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/nntp.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/nntp.php new file mode 100644 index 0000000..f211d71 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/nntp.php @@ -0,0 +1,32 @@ +userinfo = null; + $uri->query = null; + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/tel.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/tel.php new file mode 100644 index 0000000..dfad8ef --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URIScheme/tel.php @@ -0,0 +1,46 @@ +userinfo = null; + $uri->host = null; + $uri->port = null; + + // Delete all non-numeric characters, commas, and non-x characters + // from phone number, EXCEPT for a leading plus sign. + $uri->path = preg_replace('/(?!^\+)[^\dx,]/', '', + // Normalize e(x)tension to lower-case + str_replace('X', 'x', rawurldecode($uri->path))); + + return true; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URISchemeRegistry.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URISchemeRegistry.php new file mode 100644 index 0000000..4ac8a0b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/URISchemeRegistry.php @@ -0,0 +1,81 @@ +get('URI.AllowedSchemes'); + if (!$config->get('URI.OverrideAllowedSchemes') && + !isset($allowed_schemes[$scheme]) + ) { + return; + } + + if (isset($this->schemes[$scheme])) { + return $this->schemes[$scheme]; + } + if (!isset($allowed_schemes[$scheme])) { + return; + } + + $class = 'HTMLPurifier_URIScheme_' . $scheme; + if (!class_exists($class)) { + return; + } + $this->schemes[$scheme] = new $class(); + return $this->schemes[$scheme]; + } + + /** + * Registers a custom scheme to the cache, bypassing reflection. + * @param string $scheme Scheme name + * @param HTMLPurifier_URIScheme $scheme_obj + */ + public function register($scheme, $scheme_obj) + { + $this->schemes[$scheme] = $scheme_obj; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/UnitConverter.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/UnitConverter.php new file mode 100644 index 0000000..b5a1eab --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/UnitConverter.php @@ -0,0 +1,307 @@ + array( + 'px' => 3, // This is as per CSS 2.1 and Firefox. Your mileage may vary + 'pt' => 4, + 'pc' => 48, + 'in' => 288, + self::METRIC => array('pt', '0.352777778', 'mm'), + ), + self::METRIC => array( + 'mm' => 1, + 'cm' => 10, + self::ENGLISH => array('mm', '2.83464567', 'pt'), + ), + ); + + /** + * Minimum bcmath precision for output. + * @type int + */ + protected $outputPrecision; + + /** + * Bcmath precision for internal calculations. + * @type int + */ + protected $internalPrecision; + + /** + * Whether or not BCMath is available. + * @type bool + */ + private $bcmath; + + public function __construct($output_precision = 4, $internal_precision = 10, $force_no_bcmath = false) + { + $this->outputPrecision = $output_precision; + $this->internalPrecision = $internal_precision; + $this->bcmath = !$force_no_bcmath && function_exists('bcmul'); + } + + /** + * Converts a length object of one unit into another unit. + * @param HTMLPurifier_Length $length + * Instance of HTMLPurifier_Length to convert. You must validate() + * it before passing it here! + * @param string $to_unit + * Unit to convert to. + * @return HTMLPurifier_Length|bool + * @note + * About precision: This conversion function pays very special + * attention to the incoming precision of values and attempts + * to maintain a number of significant figure. Results are + * fairly accurate up to nine digits. Some caveats: + * - If a number is zero-padded as a result of this significant + * figure tracking, the zeroes will be eliminated. + * - If a number contains less than four sigfigs ($outputPrecision) + * and this causes some decimals to be excluded, those + * decimals will be added on. + */ + public function convert($length, $to_unit) + { + if (!$length->isValid()) { + return false; + } + + $n = $length->getN(); + $unit = $length->getUnit(); + + if ($n === '0' || $unit === false) { + return new HTMLPurifier_Length('0', false); + } + + $state = $dest_state = false; + foreach (self::$units as $k => $x) { + if (isset($x[$unit])) { + $state = $k; + } + if (isset($x[$to_unit])) { + $dest_state = $k; + } + } + if (!$state || !$dest_state) { + return false; + } + + // Some calculations about the initial precision of the number; + // this will be useful when we need to do final rounding. + $sigfigs = $this->getSigFigs($n); + if ($sigfigs < $this->outputPrecision) { + $sigfigs = $this->outputPrecision; + } + + // BCMath's internal precision deals only with decimals. Use + // our default if the initial number has no decimals, or increase + // it by how ever many decimals, thus, the number of guard digits + // will always be greater than or equal to internalPrecision. + $log = (int)floor(log(abs($n), 10)); + $cp = ($log < 0) ? $this->internalPrecision - $log : $this->internalPrecision; // internal precision + + for ($i = 0; $i < 2; $i++) { + + // Determine what unit IN THIS SYSTEM we need to convert to + if ($dest_state === $state) { + // Simple conversion + $dest_unit = $to_unit; + } else { + // Convert to the smallest unit, pending a system shift + $dest_unit = self::$units[$state][$dest_state][0]; + } + + // Do the conversion if necessary + if ($dest_unit !== $unit) { + $factor = $this->div(self::$units[$state][$unit], self::$units[$state][$dest_unit], $cp); + $n = $this->mul($n, $factor, $cp); + $unit = $dest_unit; + } + + // Output was zero, so bail out early. Shouldn't ever happen. + if ($n === '') { + $n = '0'; + $unit = $to_unit; + break; + } + + // It was a simple conversion, so bail out + if ($dest_state === $state) { + break; + } + + if ($i !== 0) { + // Conversion failed! Apparently, the system we forwarded + // to didn't have this unit. This should never happen! + return false; + } + + // Pre-condition: $i == 0 + + // Perform conversion to next system of units + $n = $this->mul($n, self::$units[$state][$dest_state][1], $cp); + $unit = self::$units[$state][$dest_state][2]; + $state = $dest_state; + + // One more loop around to convert the unit in the new system. + + } + + // Post-condition: $unit == $to_unit + if ($unit !== $to_unit) { + return false; + } + + // Useful for debugging: + //echo "
            n";
            +        //echo "$n\nsigfigs = $sigfigs\nnew_log = $new_log\nlog = $log\nrp = $rp\n
            \n"; + + $n = $this->round($n, $sigfigs); + if (strpos($n, '.') !== false) { + $n = rtrim($n, '0'); + } + $n = rtrim($n, '.'); + + return new HTMLPurifier_Length($n, $unit); + } + + /** + * Returns the number of significant figures in a string number. + * @param string $n Decimal number + * @return int number of sigfigs + */ + public function getSigFigs($n) + { + $n = ltrim($n, '0+-'); + $dp = strpos($n, '.'); // decimal position + if ($dp === false) { + $sigfigs = strlen(rtrim($n, '0')); + } else { + $sigfigs = strlen(ltrim($n, '0.')); // eliminate extra decimal character + if ($dp !== 0) { + $sigfigs--; + } + } + return $sigfigs; + } + + /** + * Adds two numbers, using arbitrary precision when available. + * @param string $s1 + * @param string $s2 + * @param int $scale + * @return string + */ + private function add($s1, $s2, $scale) + { + if ($this->bcmath) { + return bcadd($s1, $s2, $scale); + } else { + return $this->scale((float)$s1 + (float)$s2, $scale); + } + } + + /** + * Multiples two numbers, using arbitrary precision when available. + * @param string $s1 + * @param string $s2 + * @param int $scale + * @return string + */ + private function mul($s1, $s2, $scale) + { + if ($this->bcmath) { + return bcmul($s1, $s2, $scale); + } else { + return $this->scale((float)$s1 * (float)$s2, $scale); + } + } + + /** + * Divides two numbers, using arbitrary precision when available. + * @param string $s1 + * @param string $s2 + * @param int $scale + * @return string + */ + private function div($s1, $s2, $scale) + { + if ($this->bcmath) { + return bcdiv($s1, $s2, $scale); + } else { + return $this->scale((float)$s1 / (float)$s2, $scale); + } + } + + /** + * Rounds a number according to the number of sigfigs it should have, + * using arbitrary precision when available. + * @param float $n + * @param int $sigfigs + * @return string + */ + private function round($n, $sigfigs) + { + $new_log = (int)floor(log(abs((float)$n), 10)); // Number of digits left of decimal - 1 + $rp = $sigfigs - $new_log - 1; // Number of decimal places needed + $neg = $n < 0 ? '-' : ''; // Negative sign + if ($this->bcmath) { + if ($rp >= 0) { + $n = bcadd($n, $neg . '0.' . str_repeat('0', $rp) . '5', $rp + 1); + $n = bcdiv($n, '1', $rp); + } else { + // This algorithm partially depends on the standardized + // form of numbers that comes out of bcmath. + $n = bcadd($n, $neg . '5' . str_repeat('0', $new_log - $sigfigs), 0); + $n = substr($n, 0, $sigfigs + strlen($neg)) . str_repeat('0', $new_log - $sigfigs + 1); + } + return $n; + } else { + return $this->scale(round((float)$n, $sigfigs - $new_log - 1), $rp + 1); + } + } + + /** + * Scales a float to $scale digits right of decimal point, like BCMath. + * @param float $r + * @param int $scale + * @return string + */ + private function scale($r, $scale) + { + if ($scale < 0) { + // The f sprintf type doesn't support negative numbers, so we + // need to cludge things manually. First get the string. + $r = sprintf('%.0f', (float)$r); + // Due to floating point precision loss, $r will more than likely + // look something like 4652999999999.9234. We grab one more digit + // than we need to precise from $r and then use that to round + // appropriately. + $precise = (string)round(substr($r, 0, strlen($r) + $scale), -1); + // Now we return it, truncating the zero that was rounded off. + return substr($precise, 0, -1) . str_repeat('0', -$scale + 1); + } + return number_format((float)$r, $scale, '.', ''); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser.php new file mode 100644 index 0000000..0c97c82 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser.php @@ -0,0 +1,198 @@ + self::C_STRING, + 'istring' => self::ISTRING, + 'text' => self::TEXT, + 'itext' => self::ITEXT, + 'int' => self::C_INT, + 'float' => self::C_FLOAT, + 'bool' => self::C_BOOL, + 'lookup' => self::LOOKUP, + 'list' => self::ALIST, + 'hash' => self::HASH, + 'mixed' => self::C_MIXED + ); + + /** + * Lookup table of types that are string, and can have aliases or + * allowed value lists. + */ + public static $stringTypes = array( + self::C_STRING => true, + self::ISTRING => true, + self::TEXT => true, + self::ITEXT => true, + ); + + /** + * Validate a variable according to type. + * It may return NULL as a valid type if $allow_null is true. + * + * @param mixed $var Variable to validate + * @param int $type Type of variable, see HTMLPurifier_VarParser->types + * @param bool $allow_null Whether or not to permit null as a value + * @return string Validated and type-coerced variable + * @throws HTMLPurifier_VarParserException + */ + final public function parse($var, $type, $allow_null = false) + { + if (is_string($type)) { + if (!isset(HTMLPurifier_VarParser::$types[$type])) { + throw new HTMLPurifier_VarParserException("Invalid type '$type'"); + } else { + $type = HTMLPurifier_VarParser::$types[$type]; + } + } + $var = $this->parseImplementation($var, $type, $allow_null); + if ($allow_null && $var === null) { + return null; + } + // These are basic checks, to make sure nothing horribly wrong + // happened in our implementations. + switch ($type) { + case (self::C_STRING): + case (self::ISTRING): + case (self::TEXT): + case (self::ITEXT): + if (!is_string($var)) { + break; + } + if ($type == self::ISTRING || $type == self::ITEXT) { + $var = strtolower($var); + } + return $var; + case (self::C_INT): + if (!is_int($var)) { + break; + } + return $var; + case (self::C_FLOAT): + if (!is_float($var)) { + break; + } + return $var; + case (self::C_BOOL): + if (!is_bool($var)) { + break; + } + return $var; + case (self::LOOKUP): + case (self::ALIST): + case (self::HASH): + if (!is_array($var)) { + break; + } + if ($type === self::LOOKUP) { + foreach ($var as $k) { + if ($k !== true) { + $this->error('Lookup table contains value other than true'); + } + } + } elseif ($type === self::ALIST) { + $keys = array_keys($var); + if (array_keys($keys) !== $keys) { + $this->error('Indices for list are not uniform'); + } + } + return $var; + case (self::C_MIXED): + return $var; + default: + $this->errorInconsistent(get_class($this), $type); + } + $this->errorGeneric($var, $type); + } + + /** + * Actually implements the parsing. Base implementation does not + * do anything to $var. Subclasses should overload this! + * @param mixed $var + * @param int $type + * @param bool $allow_null + * @return string + */ + protected function parseImplementation($var, $type, $allow_null) + { + return $var; + } + + /** + * Throws an exception. + * @throws HTMLPurifier_VarParserException + */ + protected function error($msg) + { + throw new HTMLPurifier_VarParserException($msg); + } + + /** + * Throws an inconsistency exception. + * @note This should not ever be called. It would be called if we + * extend the allowed values of HTMLPurifier_VarParser without + * updating subclasses. + * @param string $class + * @param int $type + * @throws HTMLPurifier_Exception + */ + protected function errorInconsistent($class, $type) + { + throw new HTMLPurifier_Exception( + "Inconsistency in $class: " . HTMLPurifier_VarParser::getTypeName($type) . + " not implemented" + ); + } + + /** + * Generic error for if a type didn't work. + * @param mixed $var + * @param int $type + */ + protected function errorGeneric($var, $type) + { + $vtype = gettype($var); + $this->error("Expected type " . HTMLPurifier_VarParser::getTypeName($type) . ", got $vtype"); + } + + /** + * @param int $type + * @return string + */ + public static function getTypeName($type) + { + static $lookup; + if (!$lookup) { + // Lazy load the alternative lookup table + $lookup = array_flip(HTMLPurifier_VarParser::$types); + } + if (!isset($lookup[$type])) { + return 'unknown'; + } + return $lookup[$type]; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser/Flexible.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser/Flexible.php new file mode 100644 index 0000000..3bfbe83 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser/Flexible.php @@ -0,0 +1,130 @@ + $j) { + $var[$i] = trim($j); + } + if ($type === self::HASH) { + // key:value,key2:value2 + $nvar = array(); + foreach ($var as $keypair) { + $c = explode(':', $keypair, 2); + if (!isset($c[1])) { + continue; + } + $nvar[trim($c[0])] = trim($c[1]); + } + $var = $nvar; + } + } + if (!is_array($var)) { + break; + } + $keys = array_keys($var); + if ($keys === array_keys($keys)) { + if ($type == self::ALIST) { + return $var; + } elseif ($type == self::LOOKUP) { + $new = array(); + foreach ($var as $key) { + $new[$key] = true; + } + return $new; + } else { + break; + } + } + if ($type === self::ALIST) { + trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING); + return array_values($var); + } + if ($type === self::LOOKUP) { + foreach ($var as $key => $value) { + if ($value !== true) { + trigger_error( + "Lookup array has non-true value at key '$key'; " . + "maybe your input array was not indexed numerically", + E_USER_WARNING + ); + } + $var[$key] = true; + } + } + return $var; + default: + $this->errorInconsistent(__CLASS__, $type); + } + $this->errorGeneric($var, $type); + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser/Native.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser/Native.php new file mode 100644 index 0000000..f11c318 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParser/Native.php @@ -0,0 +1,38 @@ +evalExpression($var); + } + + /** + * @param string $expr + * @return mixed + * @throws HTMLPurifier_VarParserException + */ + protected function evalExpression($expr) + { + $var = null; + $result = eval("\$var = $expr;"); + if ($result === false) { + throw new HTMLPurifier_VarParserException("Fatal error in evaluated code"); + } + return $var; + } +} + +// vim: et sw=4 sts=4 diff --git a/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParserException.php b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParserException.php new file mode 100644 index 0000000..5df3414 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/libs/HTMLPurifier/HTMLPurifier/VarParserException.php @@ -0,0 +1,11 @@ +front = $front; + $this->back = $back; + } + + /** + * Creates a zipper from an array, with a hole in the + * 0-index position. + * @param Array to zipper-ify. + * @return Tuple of zipper and element of first position. + */ + static public function fromArray($array) { + $z = new self(array(), array_reverse($array)); + $t = $z->delete(); // delete the "dummy hole" + return array($z, $t); + } + + /** + * Convert zipper back into a normal array, optionally filling in + * the hole with a value. (Usually you should supply a $t, unless you + * are at the end of the array.) + */ + public function toArray($t = NULL) { + $a = $this->front; + if ($t !== NULL) $a[] = $t; + for ($i = count($this->back)-1; $i >= 0; $i--) { + $a[] = $this->back[$i]; + } + return $a; + } + + /** + * Move hole to the next element. + * @param $t Element to fill hole with + * @return Original contents of new hole. + */ + public function next($t) { + if ($t !== NULL) array_push($this->front, $t); + return empty($this->back) ? NULL : array_pop($this->back); + } + + /** + * Iterated hole advancement. + * @param $t Element to fill hole with + * @param $i How many forward to advance hole + * @return Original contents of new hole, i away + */ + public function advance($t, $n) { + for ($i = 0; $i < $n; $i++) { + $t = $this->next($t); + } + return $t; + } + + /** + * Move hole to the previous element + * @param $t Element to fill hole with + * @return Original contents of new hole. + */ + public function prev($t) { + if ($t !== NULL) array_push($this->back, $t); + return empty($this->front) ? NULL : array_pop($this->front); + } + + /** + * Delete contents of current hole, shifting hole to + * next element. + * @return Original contents of new hole. + */ + public function delete() { + return empty($this->back) ? NULL : array_pop($this->back); + } + + /** + * Returns true if we are at the end of the list. + * @return bool + */ + public function done() { + return empty($this->back); + } + + /** + * Insert element before hole. + * @param Element to insert + */ + public function insertBefore($t) { + if ($t !== NULL) array_push($this->front, $t); + } + + /** + * Insert element after hole. + * @param Element to insert + */ + public function insertAfter($t) { + if ($t !== NULL) array_push($this->back, $t); + } + + /** + * Splice in multiple elements at hole. Functional specification + * in terms of array_splice: + * + * $arr1 = $arr; + * $old1 = array_splice($arr1, $i, $delete, $replacement); + * + * list($z, $t) = HTMLPurifier_Zipper::fromArray($arr); + * $t = $z->advance($t, $i); + * list($old2, $t) = $z->splice($t, $delete, $replacement); + * $arr2 = $z->toArray($t); + * + * assert($old1 === $old2); + * assert($arr1 === $arr2); + * + * NB: the absolute index location after this operation is + * *unchanged!* + * + * @param Current contents of hole. + */ + public function splice($t, $delete, $replacement) { + // delete + $old = array(); + $r = $t; + for ($i = $delete; $i > 0; $i--) { + $old[] = $r; + $r = $this->delete(); + } + // insert + for ($i = count($replacement)-1; $i >= 0; $i--) { + $this->insertAfter($r); + $r = $replacement[$i]; + } + return array($old, $r); + } +} diff --git a/html/wp-content/plugins/post-smtp/includes/postman-functions.php b/html/wp-content/plugins/post-smtp/includes/postman-functions.php new file mode 100644 index 0000000..d846e18 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/includes/postman-functions.php @@ -0,0 +1,251 @@ +insert( + $wpdb->prefix . $email_logs->meta_table, + array( + 'log_id' => $log_id, + 'meta_key' => $meta_key, + 'meta_value' => $meta_value + ), + array( + '%d', + '%s', + '%s' + ) + ); + +} +endif; + + +/** + * Updates a log meta field based on the given log ID. + * + * @since 2.5.0 + * @version 1.0.0 + */ +if ( ! function_exists( 'postman_update_log_meta' ) ) { + function postman_update_log_meta( $log_id, $meta_key, $meta_value ) { + global $wpdb; + $email_logs = new PostmanEmailLogs(); + + $existing_meta = $wpdb->get_row( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}{$email_logs->meta_table} WHERE log_id = %d AND meta_key = %s", + $log_id, + $meta_key + ) + ); + + if ( $existing_meta ) { + return $wpdb->update( + $wpdb->prefix . $email_logs->meta_table, + array( + 'meta_value' => $meta_value + ), + array( + 'log_id' => $log_id, + 'meta_key' => $meta_key + ), + array( + '%s' + ), + array( + '%d', + '%s' + ) + ); + } else { + return $wpdb->insert( + $wpdb->prefix . $email_logs->meta_table, + array( + 'log_id' => $log_id, + 'meta_key' => $meta_key, + 'meta_value' => $meta_value + ), + array( + '%d', + '%s', + '%s' + ) + ); + } + } +} + + + +/** + * Retrieves a log meta field for the given log ID. + * + * @since 2.5.0 + * @version 1.0.0 + */ +if( !function_exists( 'postman_get_log_meta' ) ): +function postman_get_log_meta( $log_id, $key = '' ) { + + global $wpdb; + $email_logs = new PostmanEmailLogs(); + + if( empty( $key ) ) { + + return $wpdb->get_results( + $wpdb->prepare( + "SELECT `meta_key`, `meta_value` FROM {$wpdb->prefix}{$email_logs->meta_table} + WHERE `log_id` = %d", + $log_id + ) + ); + + } + + $result = $wpdb->get_row( + $wpdb->prepare( + "SELECT `meta_value` FROM {$wpdb->prefix}{$email_logs->meta_table} + WHERE `log_id` = %d && `meta_key` = %s", + $log_id, + $key + ) + ); + + return $result ? $result->meta_value : false; + +} +endif; + + +/** + * Deletes a log meta field for the given log ID. + * + * @since 2.5.0 + * @version 1.0.0 + */ +if( !function_exists( 'postman_delete_log_meta' ) ): +function postman_delete_log_meta( $log_id, $meta_key, $meta_value = '' ) { + + global $wpdb; + $email_logs = new PostmanEmailLogs(); + + $where = array( + 'log_id' => $log_id, + 'meta_key' => $meta_key + ); + + $where_format = array( + '%d', + '%s' + ); + + if( !empty( $meta_value ) ) { + + $where['meta_value'] = $meta_value; + $where_format[] = '%s'; + + } + + return $wpdb->delete( + $wpdb->prefix . $email_logs->meta_table, + $where, + $where_format + ); + +} +endif; + +/** + * Sanitizes an array of values. + * + * @since 2.7.0 + * @version 1.0.0 + */ +if( !function_exists( 'post_smtp_sanitize_array' ) ): +function post_smtp_sanitize_array( $_array ) { + + $array = array(); + + foreach( $_array as $key => $value ) { + + $array[$key] = sanitize_text_field( $value ); + + } + + return $array; + +} +endif; + +/** + * Check pro extenstions is activated or not + * + * @since 2.8.6 + * @version 1.0 + */ + +if( !function_exists( 'post_smtp_has_pro' )): +function post_smtp_has_pro(){ + + if( is_plugin_active( 'zoho-premium/postsmtp-extension-zoho-mail.php' ) + || + is_plugin_active( 'twilio-notifications-postsmtp-extension-premium/plugin.php' ) + || + is_plugin_active( 'post-smtp-extension-amazon-ses-premium/plugin.php' ) + || + is_plugin_active( 'report-and-tracking-addon-premium/post-smtp-report-and-tracking.php' ) + || + is_plugin_active( 'post-smtp-extension-office365-premium/plugin.php' ) + || + is_plugin_active( 'attachment-support-premium/post-smtp-attachment-support.php' ) + || + is_plugin_active( 'advance-email-delivery-and-logs-premium/post-smtp-advanced-email-delivery-and-logs.php' ) + || + is_plugin_active( 'post-smtp-pro/post-smtp-pro.php' ) + ){ + return true; + } + else{ + + return false; + } + +} +endif; + +/** + * Check if the BFCM is active. + * + * @since 2.9.10 + */ +if( ! function_exists( 'postman_is_bfcm' ) ): +function postman_is_bfcm() { + + if( get_transient( 'ps-skip-bfcm' ) || post_smtp_has_pro() ) { + + return false; + + } + + $promotion = Postman_Promotion_Manager::get_instance()->is_promotion_active( 'bfcm-2024' ); + + return $promotion; + +} +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/postman-smtp.php b/html/wp-content/plugins/post-smtp/postman-smtp.php new file mode 100644 index 0000000..36b8fb9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/postman-smtp.php @@ -0,0 +1,243 @@ + '10461', + 'slug' => 'post-smtp', + 'type' => 'plugin', + 'public_key' => 'pk_28fcefa3d0ae86f8cdf6b7f71c0cc', + 'is_premium' => false, + 'has_addons' => true, + 'bundle_id' => '10910', + 'bundle_public_key' => 'pk_c5110ef04ba30cd57dd970a269a1a', + 'has_paid_plans' => false, + 'menu' => array( + 'slug' => 'postman', + 'first-path' => 'admin.php?page=postman/configuration_wizard', + 'account' => false, + ), + ) ); + } + + return $ps_fs; + } + + // Init Freemius. + ps_fs(); + // Signal that SDK was initiated. + do_action( 'ps_fs_loaded' ); +} + +function ps_fs_custom_connect_message_on_update( + $message, + $user_first_name, + $product_title, + $user_login, + $site_link, + $freemius_link +) { + return sprintf( + '
            ' . + '

            ' . __( 'Stay on the safe side', 'post-smtp' ) . '

            ' . + '

            '.__( 'Receive our plugin\'s alert in case of critical security and feature updates and allow non-sensitive diagnostic tracking.', 'post-smtp' ).'

            ' . + '
            ' . + '
            ' + ); +} + +ps_fs()->add_filter('connect_message', 'ps_fs_custom_connect_message_on_update', 10, 6); + +function ps_fs_custom_icon() { + return dirname( __FILE__ ) . '/assets/images/icons/optin.png'; +} + +ps_fs()->add_filter( 'plugin_icon' , 'ps_fs_custom_icon' ); + + +/** + * DO some check and Start Postman + */ + +define( 'POST_SMTP_BASE', __FILE__ ); +define( 'POST_SMTP_PATH', __DIR__ ); +define( 'POST_SMTP_URL', plugins_url('', POST_SMTP_BASE ) ); +define( 'POST_SMTP_VER', '3.8.0' ); +define( 'POST_SMTP_DB_VERSION', '1.0.1' ); +define( 'POST_SMTP_ASSETS', plugin_dir_url( __FILE__ ) . 'assets/' ); + +$postman_smtp_exist = in_array( 'postman-smtp/postman-smtp.php', (array) get_option( 'active_plugins', array() ) ); +$required_php_version = version_compare( PHP_VERSION, '5.6.0', '<' ); + +if( ! function_exists( 'post_smtp_load_textdomain' ) ): +function post_smtp_load_textdomain() { + // had to hardcode the third parameter, Relative path to WP_PLUGIN_DIR, + // because __FILE__ returns the wrong path if the plugin is installed as a symlink + $shortLocale = substr( get_locale(), 0, 2 ); + if ( $shortLocale != 'en' ) { + $langDir = 'post-smtp/Postman/languages'; + $success = load_plugin_textdomain( 'post-smtp', false, $langDir ); + } +} +endif; + +add_action( 'init', 'post_smtp_load_textdomain' ); + +if ( $postman_smtp_exist || $required_php_version ) { + add_action( 'admin_init', 'post_smtp_plugin_deactivate' ); + + if ( $postman_smtp_exist ) { + add_action( 'admin_notices', 'post_smtp_plugin_admin_notice' ); + } + + if ( $required_php_version ) { + add_action( 'admin_notices', 'post_smtp_plugin_admin_notice_version' ); + } +} else { + post_smtp_start( memory_get_usage() ); +} + + +function post_smtp_plugin_deactivate() { + deactivate_plugins( plugin_basename( __FILE__ ) ); + + $timestamp = wp_next_scheduled( 'postman_rat_email_report' ); + if ( $timestamp ) { + wp_unschedule_event( $timestamp, 'postman_rat_email_report' ); + } + +} + +function post_smtp_plugin_admin_notice_version() { + echo '
            '; + + if ( isset( $_GET['activate'] ) ) { + unset( $_GET['activate'] ); } +} + +function post_smtp_plugin_admin_notice() { + echo '

            Post SMTP plugin is a fork (twin brother) of the original Postman SMTP, you must disable Postman SMTP to use this plugin.

            '; + + if ( isset( $_GET['activate'] ) ) { + unset( $_GET['activate'] ); } +} + +/** + * @todo + */ +function post_dismiss_not_configured() { + ?> + +add_filter( 'is_submenu_visible', 'ps_fs_submenu_addon_visibility_handler', 10, 2 ); diff --git a/html/wp-content/plugins/post-smtp/readme.txt b/html/wp-content/plugins/post-smtp/readme.txt new file mode 100644 index 0000000..fe3d624 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/readme.txt @@ -0,0 +1,1176 @@ +=== Post SMTP – Complete Email Deliverability and SMTP Solution with Email Logs, Alerts, Backup SMTP & Mobile App === +Plugin URI: https://postmansmtp.com/ +Contributors: wpexpertsio +Tags: smtp, gmail smtp, email, email logs, office 365 +Requires at least: 5.6.0 +Tested up to: 6.9 +Stable tag: 3.8.0 +Requires PHP: 7.0 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Improve WordPress email deliverability. Connect Gmail SMTP, Microsoft 365, Brevo, SendGrid, Mailgun, Zoho, Amazon SES, etc. #1 WordPress SMTP Plugin. + +== Description == + +[👑 Go Pro](https://postmansmtp.com/pricing/?utm_source=wp_org&utm_medium=read_me) | [💻Live Demo](https://www.tastewp.com/plugins/post-smtp) | [🔌Extensions](https://postmansmtp.com/extension/?utm_source=wp_org&utm_medium=readme_top) | [📱Mobile Application](https://postmansmtp.com/documentation/advance-functionality/postsmtp-mobile-app/?utm_source=wp_org&utm_medium=readme_top) + +### WordPress Mail SMTP Plugin + +https://www.youtube.com/watch?v=KOWGLQ0MaX0 + +Are you facing the WordPress not sending emails issueâ“Don't worry! Install the Post SMTP Plugin **aka** (WordPress mail SMTP plugin), for smooth WordPress email deliverability. + + +Over **400,000** website owners use **Post SMTP** daily to send WordPress emails securely and reliably💯 using Gmail SMTP, Microsoft Office 365/Outlook, and other SMTP integrations. + +Post SMTP is a free, next-generation WordPress SMTP plugin that improves email deliverability for your WordPress site. + +The best part is that the Post SMTP plugin helps you configure any SMTP mailer, including Gmail one-click setup and Microsoft Office 365 (formerly Office 365), to prevent spam marking and ensure high email deliverability. + +With the ✨[Post SMTP Pro version](https://postmansmtp.com/pricing/?utm_source=wp_org&utm_medium=read_me)✨, you can unlock even more advanced features, such as detailed email logs, email delivery stats and reporting, Microsoft 365 (formerly Office 365), Amazon SES, Zoho Mail SMTP integration, multiple options for email alerts (i.e., Teams, Webhook, Twilio, and Slack), and much more. + + +== What is SMTP, and Why Do You Need It? == +**SMTP**, short for Simple Mail Transfer Protocol, is the most widely used protocol for online email transmission. SMTP configuration with proper authentication for your WordPress site ensures that your WordPress emails do not end up in spam. + +**By default**, WordPress sends emails using the PHP mail function, which isn't ideal because most WordPress hosting servers don't support PHP email. + +On top of that, most email clients, such as Outlook (Office 365 / Microsoft365), Yahoo, Gmail, Brevo, Zoho, Amazon SES, Mailgun, etc., automatically block or mark spam emails that lack proper authentication. + +That's why you need to install the Post SMTP plugin on your WordPress site to configure the SMTP mailer of your choice with one-click SMTP setup for Gmail, Microsoft 365, and more. + +== How Does Post SMTP Work? == +Post SMTP allows you to easily replace the default PHP mail function (wp_mail) of your WordPress site with the SMTP mailer of your choice, like [Microsoft 365 (Office 365)](https://postmansmtp.com/extensions/office-365-extension-for-post-smtp/?utm_source=wp_org&utm_medium=read_me), Brevo, Zoho, [SendGrid](https://postmansmtp.com/configure-wordpress-with-sendgrid/), [Mailgun SMTP](https://postmansmtp.com/setup-mailgun-for-wordpress/), Gmail [(Gmail SMTP Server)](https://postmansmtp.com/how-to-configure-post-smtp-with-gmailgsuite-using-oauth/), Post Mark, Amazon SES etc., which in turn improves WordPress email deliverability. + +**This WordPress mail SMTP plugin provides detailed email logs, email open tracking, email alerts, and a mobile app to monitor WordPress email deliverability.** + +Additionally, with a [3-step setup wizard](https://postmansmtp.com/introducing-the-new-3-step-setup-wizard-for-post-smtp/?utm_source=wp_org&utm_medium=read_me) you can configure any SMTP mailer (e.g., Gmail SMTP (Gmail one-click setup), Microsoft Office 365, Mailgun, Brevo, etc.) securely via API Keys in seconds without providing your SMTP account credentials. + +**NOTE:** If you want to set up a Gmail SMTP server for WordPress, check out our detailed guide on [how to configure Gmail SMTP server](https://postmansmtp.com/how-to-configure-post-smtp-with-gmailgsuite-using-oauth/) to send WordPress emails reliably. + +Ultimately, this WordPress SMTP plugin helps you fix all your issues related to [WordPress not sending emails.](https://postmansmtp.com/wordpress-not-sending-emails/?utm_source=wp_org&utm_medium=read_me) + +== âš¡ Features That Make Post SMTP Stand Out == +✅ **Quick Setup Wizard:** Easy-to-use and powerful 3-Step Setup Wizard for quick WordPress SMTP configuration with One-click SMTP setup for Gmail SMTP and Microsoft 365 SMTP. + +✅ **SPF, DKIM & DMARC Checks:** Keep an eye on domain’s reputation with out built-in Spam Score Checker that looks at your DNS records.. + +✅ **Detailed Email Logs:** Quickly view, filter, and check the status of all your WordPress emails and error messages with a simple click, ensuring your email logs are always up to date. + +✅ **Post SMTP Mobile App:** Get WordPress email alerts directly on your mobile phone so you can track email deliverability on the go. + + +✅ **Extensive Email Reporting:** Get a thorough report at a glance regarding your WordPress email deliverability performance, including email open tracking and other important stats. + +✅ **Resend Email Attachments [PRO]:** With a single click, you can resend any email attachment right through your email log screen, maintaining a seamless record in your email logs. + +✅ **OAuth 2.0 Support:** Authenticate all major SMTP service providers' accounts (i.e., Microsoft Office 365/Microsoft365, Brevo, Gmail SMTP (Gmail one-click setup), Amazon SES, SendGrid, Mailgun, etc.) securely using APIs. + +✅ **Fallback Mailing:** Easily set up a backup WordPress SMTP mailer to send any transactional email in case of a failure with the main mailer. + +✅ **Instant Failure Notification:** In case of any WordPress email delivery failure, you'll get an instant email alert, Slack notification, SMS (via Twilio), push notification (via webhook and Chrome Extension), etc. + +✅ **Free Chrome Extension:**Receive all your WordPress email alerts for failed email deliveries directly into your Chrome browser window. + +✅ **Weekly Email Summary:** Get a snapshot of your WordPress email deliverability report right in your inbox every week, which reveals the total number of emails, the number of failed emails, total successful email deliveries, and your recent email logs. + +✅ **Unparalleled Customer Support:** We offer multiple support options, including email, a WordPress forum, and even one-on-one expert assistance for [WordPress SMTP Configuration](https://postmansmtp.com/configuration-request/?utm_source=wp_org&utm_medium=read_me) and all your email delivery issues. + +https://www.youtube.com/watch?v=Oxs3qintyLU + +== âš¡ Post SMTP Mobile App: Get an Instant Pulse of Your WordPress Emails == +✅ **Keep track of Your Emails:** You can monitor all the emails sent from your WordPress site and check the status of each email. + +✅ **Get Instant Alerts:** When an email fails to deliver, you will receive an instant notification on your phone. + +✅ **Resend Failed Emails [PRO]:** With one tap on your app, you can resend any failed email. +Preview Any Email: You can preview your emails and see how it looks. + +✅ **Connect Multiple Sites [PRO]:** Monitor email logs and get email failure notifications (email alerts) for all your WordPress sites right from the app. + +✅ **Troubleshoot Errors:** Quickly fix email failure issues by viewing the error details with a single tap. + +== SMTP Mailer Options for Post SMTP == +With Post SMTP, you get many SMTP mailer options, such as: + +* [Sweego SMTP](https://postmansmtp.com/docs/mailers/how-to-setup-sweego-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) - **Newly Added** + +* [Mailtrap SMTP](https://postmansmtp.com/docs/mailers/how-to-setup-mailtrap-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) - **Newly Added** + +* [Emailit SMTP](https://postmansmtp.com/docs/mailers/how-to-setup-emailit-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) + +* [Resend SMTP](https://postmansmtp.com/docs/mailers/how-to-setup-resend-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) + +* [MailerSend SMTP](https://postmansmtp.com/documentation/sockets-addons/how-to-setup-mailersend-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) + +* [Brevo (formerly Sendinblue) SMTP](https://postmansmtp.com/documentation/sockets-addons/how-to-setup-sendinblue-aka-brevo-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) + +* [Microsoft 365 SMTP (Formerly Office 365 and Outlook)](https://postmansmtp.com/office-365-for-wordpress/?utm_source=wp_org&utm_medium=read_me) + +* [Gmail SMTP (Gmail API, G Suite, Google Workspace)](https://postmansmtp.com/how-to-configure-post-smtp-with-gmailgsuite-using-oauth/?utm_source=wp_org&utm_medium=read_me) + +* [Amazon SES SMTP](https://postmansmtp.com/extensions/post-smtp-extension-for-amazon-ses/?utm_source=wp_org&utm_medium=read_me) + +* [Zoho Mail SMTP](https://postmansmtp.com/extensions/zoho-mail-pro-extension/?utm_source=wp_org&utm_medium=read_me) + +* [Mandrill SMTP](https://postmansmtp.com/documentation/sockets-addons/how-to-setup-mandrill-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) + +* [Mailgun SMTP](https://postmansmtp.com/setup-mailgun-for-wordpress/?utm_source=wp_org&utm_medium=read_me) + +* [SendGrid SMTP](https://postmansmtp.com/documentation/sockets-addons/how-to-setup-sendgrid-with-post-smtp/?utm_source=wp_org&utm_medium=read_me) + +* [Mailjet SMTP](https://postmansmtp.com/documentation/sockets-addons/configure-post-smtp-with-mailjet/?utm_source=wp_org&utm_medium=read_me) + +* [SparkPost SMTP](https://postmansmtp.com/documentation/sockets-addons/sparkpost/?utm_source=wp_org&utm_medium=read_me) + +* [Postmark SMTP](https://postmansmtp.com/documentation/sockets-addons/postmark/?utm_source=wp_org&utm_medium=read_me) + +* [Elastic Email SMTP](https://postmansmtp.com/documentation/sockets-addons/configure-post-smtp-with-elastic-email/?utm_source=wp_org&utm_medium=read_me) + +* [Other SMTP](https://postmansmtp.com/documentation/sockets-addons/configure-post-smtp-with-other-smtp/?utm_source=wp_org&utm_medium=read_me) (To connect any SMTP server) + +You often need to install a different WordPress mail smtp plugin for each SMTP mailer setup. However, with Post SMTP, you can set up all popular SMTP providers, such as Gmail one-click setup, Microsoft Office 365, Mailgun, Amazon SES, Zoho Mail, etc. + +== Microsoft 365 SMTP == +Millions of businesses around the world use Microsoft 365 (formerly Office 365) or Outlook for their email communications. With Post SMTP Pro, you can easily connect your existing [Outlook or Microsoft 365 (formerly Office365) account with WordPress](https://postmansmtp.com/connect-microsoft-outlook-to-wordpress/?utm_source=wp_org&utm_medium=read_me) via **one-click SMTP setup** to improve email deliverability. + + +👉 For more details, check out our guide on [how to set up Microsoft 365 for WordPress emails.](https://postmansmtp.com/office-365-for-wordpress/?utm_source=wp_org&utm_medium=read_me) + +== Amazon SES SMTP == +Amazon SES (Simple Email Service) is a cloud-based email service that can send transactional and mass emails. SES is cost-effective, reliable, and scalable. Using the Post SMTP Pro, you can securely integrate your Amazon SES account with WordPress via APIs so that you can send large numbers of emails on a budget. + +👉 For more details, check out our [Amazon SES documentation.](https://postmansmtp.com/documentation/sockets-addons/amazon-ses-pro/?utm_source=wp_org&utm_medium=read_me) + +== Zoho Mail SMTP == +Connect your Zoho mail personal or business account with WordPress via Post SMTP Pro to improve email deliverability. It has a 99.9% server uptime and offers a free option. + +👉 For more details, check out our [Zoho Mail documentation](https://postmansmtp.com/documentation/sockets-addons/zoho-with-post-smtp/?utm_source=wp_org&utm_medium=read_me). + +👉 To learn about all the supported SMTP mailers, check out our [Complete SMTP Mailer Guide.](https://postmansmtp.com/documentation/sockets-addons/post-smtp-complete-mailer-guide/?utm_source=wp_org&utm_medium=read_me) + +== âš¡ Added Benefits of Getting Post SMTP Pro == +The Post SMTP Pro gives you an edge that makes your WordPress email management and performance reporting a breeze! With Post SMTP Pro, you get the following additional perks: + +✅ **Microsoft 365 One-Click Setup:** Upgrade to unlock a smooth and effortless Microsoft email setup. Just enable Microsoft 365 One-Click Setup. With a single toggle, Post SMTP automatically configures everything needed for secure and reliable Outlook / Office 365 email delivery no manual settings required, no technical steps to worry about. + +✅ **Google (Gmail) SMTP One-Click:** Upgrade now for a worry-free Gmail SMTP integration. Activate Gmail One-Click Setup and let Post SMTP Setup Wizard handle all the API-related technicalities. + +✅ **Microsoft Teams Notifications:** This WordPress SMTP plugin enables you to receive real-time notifications for your emails on Microsoft Teams with a simple webhook. + +✅ **Native SMTP Integration:** You can use this WordPress SMTP plugin to securely configure 15+ SMTP service provider accounts, such as Microsoft 365 (Microsoft Office 365), Gmail SMTP, Amazon SES, Zoho Mail, Mailgun, Postmark, etc., with WordPress using APIs. + +✅ **Twilio (SMS)** With this WordPress SMTP plugin, you can easily configure and receive all your WordPress email failure alerts through SMS by connecting your Twilio account. + +✅ **Secondary SMTP Connection:** Using the Post SMTP Pro, you can set up multiple SMTP mailers so that for any reason, whenever an email fails to deliver, Post SMTP will automatically route that email through the secondary SMTP connection. In turn, this will improve your email delivery rate. + +✅ **Weekly Email Health Report:** As a Post SMTP Pro member, you get a weekly email report that reveals all your deliverability statistics at a glance, such as the total number of emails sent from your WordPress site, the number of failed emails, the total number of successful email deliveries, and the complete email logs report so you can identify any issues right away without login into your WordPress. + +✅ **Email Open Tracking:** Are you curious about which of your emails get opened? With Post SMTP Pro, you can easily view email open tracking right on your email log screen, which greatly enhances your ability to analyze the performance of your WordPress emails. + +✅ **Auto Resend Failed Emails:** With Post SMTP Pro, you can effortlessly increase your WordPress email delivery success rate by simply specifying the number of resubmission attempts after the first failed submission. + +✅ **Email Batching and Quota Scheduling:** Avoid any spam detection and daily email limit exceeding issues with the Post SMTP email batching and quota scheduling feature. As a pro user, you can easily specify the duration and number of emails per batch and choose how often to send the emails (hourly, daily, weekly, or monthly) for optimal email delivery. + +✅ **Priority Support:** We offer exceptional customer support to all the Post SMTP Pro users. You can access our team of WordPress experts on one-on-one email support 24/7 for any WordPress email-related issue. Also, we offer WordPress SMTP Configuration service on demand. + +== 🆕 MainWP Post SMTP Extension - NEW == +**Manage WordPress SMTP Configuration Across All Your Sites From A Single Dashboard** + +With MainWP Post SMTP Extension, you can: + +* **Set up and sync your SMTP** settings for all your sites with one click. +* **Ensure email deliverability** with backup SMTP connections. +* **Receive instant email failure alerts via email** webhook, Slack, SMS, and Microsoft Teams. +* **Track and resend your WordPress emails** with a dedicated mobile app +* **Access detailed email logs** of all your sites in one place + +**MainWP Post SMTP Extension** is the ultimate solution for WordPress email management. Get it today and enjoy the benefits of easy and efficient WP SMTP management.🙃 + +== ⛑ Need Help? Get Expert Assistance on Demand!!! == +With our Expert Assistance, you can get help with email deliverability and SMTP plugin configuration for Gmail, Microsoft Office 365, and any SMTP setup for WordPress. + +All you need is to [click here](https://postmansmtp.com/configuration-request/?utm_source=wp_org&utm_medium=read_me), fill out the form, sit back, and relax while our WordPress expert sets up your SMTP configuration. Also, you can request us to configure all your [DNS records](https://postmansmtp.com/dmarc-spf-dkim/?utm_source=wp_org&utm_medium=read_me) for proper email authentication. + +In short, our Expert Assistance is your one-stop destination for all your WordPress email delivery issues. + +== Compatibility and Support == +* Contact Form 7 + +* Woocommerce + +* New User Approve + +* Password Protected + +* Elementor Forms + +* Gravity Forms + +* Login Designer + +* Visual Forms Builder + +* Mailster Newsletter plugin + +* SendPress Newsletters + +* WP HTML Mail + +* Email Templates + +.. and every other plugin that uses the WordPress API wp_mail to send mail! + +== Try Our Other Awesome WordPress Plugins == + +* **[Gutena Forms](https://wordpress.org/plugins/gutena-forms/)** – Create modern, responsive contact forms directly in the Gutenberg block editor. Add advanced fields, protect against spam with reCAPTCHA and Cloudflare Turnstile, manage form entries, and more. + +* **[Password Protected](https://wordpress.org/plugins/password-protected/)** – Secure your WordPress site, posts, pages, and categories with simple password protection. + +* **[WP EasyPay](https://wordpress.org/plugins/wp-easypay/)** – Accept Square payments and donations easily on your WordPress site. + +* **[WC Shop Sync](https://wordpress.org/plugins/wc-shop-sync/)** – Add Square payments and sync WooCommerce products, customers, and orders with your Square POS. + +* **[Advanced File Manager](https://wordpress.org/plugins/file-manager-advanced/)** – Easily manage and organize your WordPress files directly from the dashboard. + +* **[CF7 Apps](https://wordpress.org/plugins/cf7-apps/)** – Add honeypot, hCaptcha, and database entries to Contact Form 7. New extensions are continuously added. + +* **[myCred](https://wordpress.org/plugins/mycred/)** – Add gamification, rewards, ranks, badges, and points management systems to your WordPress website. + +* **[New User Approve](https://wordpress.org/plugins/new-user-approve/)** – Control user registrations by manually approving or denying new signups. + +* **[Bookify](https://wordpress.org/plugins/bookify/)** – Your go-to online bookings and appointment scheduling plugin for WordPress. + +* **[All In One Login](https://wordpress.org/plugins/all-in-one-login/)** – Secure your WordPress login page, change the wp-login.php URL, and add social logins like Google, Facebook, Microsoft, LINE, and more. + +* **[WPExperts WooCommerce Store](https://store.wpexperts.io/woocommerce/)** – Explore premium WooCommerce plugins and professional solutions by WPExperts. + + +== Requirements == +* WordPress v6.2 and above is recommended +* PHP v7.6 and above is recommended. +* Memory should be at least 800KiB per processing at idle. +* Ensure your email service provider allows SMTP connection through 3rd party applications, if not you can have it enabled.(Other SMTP) +* For reliable email deliverability, valid credentials are required. + + + +== Frequently Asked Questions == + += What is OAuth 2.0? = + +A modern replacement for traditional password-based authentication. Post supports the OAuth 2.0 implementations of all three major e-mail providers: Gmail, Office365, Brevo, Mailgun, Hotmail and Yahoo Mail. + += How does OAuth 2.0 work? = + +Post requests a limited access OAuth 2.0 token (valet key) to access the APIs (enter the house) and perform a specific service (handle Gmail SMTP, stay out of Google Docs) with no need for you to surrender your username and password credentials (master house key). + +Once access is granted, Post commandeers the WordPress wp_mail() function to provide an incredibly stable mail sub-system. + +There are many reasons why OAuth 2.0 is better than any password-based mechanism: + +* Post will never ask for your password, so your password can't be stolen +* If you change your password regularly, you will never have to update Post's configuration +* You have tighter control over the data Post has access to. For Google users, it can never access your Calendar or Docs or YouTube; for Yahoo users, it can never access your Flickr +* If your WordPress site gets hacked, you can revoke Post's email access without impacting any other application or website that has access to your account + +> **[NEVER give out your Gmail, Microsoft or Yahoo password](http://blog.varonis.com/giving-away-your-passwords/)** to a 3rd-party or 3rd-party program that you don't fully trust. + += Can I use this plugin to send via Outlook, Microsoft 365, Gmail SMTP, Zoho, Yahoo, or SendGrid SMTP? = +Yes! With the Post SMTP Plugin, you can configure any SMTP mailer account, including Brevo, Mailgun, and SendGrid on your WordPress site. Check out our [detailed SMTP configuration documentation](https://postmansmtp.com/documentation/sockets-addons/?utm_source=wp_org&utm_medium=read_me) for all major SMTP service providers. + += What is a Client ID? = +To use OAuth, your website needs its own Client ID. The Client ID is used to control authentication and authorization and is tied to the specific URL of your website. If you manage several websites, you will need a different Client ID for each one. + += How do I get a Microsoft Client ID? (For Hotmail/Live/Outlook.com users only!) = +1. Go to [Microsoft account Developer Center](https://account.live.com/developers/applications/index) and select 'Create application'. +1. In the 'Application name' field, enter 'Post SMTP'. Select 'I accept.' +1. Select 'API Settings' from under 'Settings'. +1. In 'Redirect URL', enter the redirect URI given by Post (either from the wizard or from the manual configuration page). Select Save. +1. Select 'App Settings' from under 'Settings'. +1. Enter the Client ID and Client Secret displayed here into the Post's settings page. + += How do I get a Yahoo Client ID? (For Yahoo Mail users only!) = +1. Go to [Yahoo Developer Network](https://developer.yahoo.com/apps/) and select 'Create an App'. +1. In the 'Application Name' field, enter 'Post SMTP'. For 'Application Type', choose 'Web Application'. +1. In 'Home Page URL', enter the 'Home Page URL' given by Post. +1. In 'Callback Domain', enter the 'Callback Domain' given by Post. +1. Under 'API Permissions', choose 'Mail.' Under 'Mail' choose 'Read/Write' +1. Click 'Create App' +1. Enter the Client ID and Client Secret displayed here into the Post's settings page. + += How can I revoke Post's OAuth 2.0 access? = +* If you have a Google Account from the [Google Developer's Console](https://www.google.com/accounts/Logout?continue=https://console.developers.google.com), use the Delete button under the Client ID. + +* If you have a Microsoft Live account, from the [Microsoft account Developer Center](https://account.live.com/developers/applications/index), select the Application and choose Delete Application. + +* If you have a Yahoo Account, from the [Yahoo Developer Network My Apps](https://developer.yahoo.com/apps/), select the Application and choose Delete App. + += How can I report security bugs? = +You can report security bugs through the Patchstack Vulnerability Disclosure Program. The Patchstack team helps validate, triage, and handle any security vulnerabilities. [Report a security vulnerability.](https://patchstack.com/database/vulnerability/post-smtp) + +== Screenshots == + +1. WordPress Post SMTP Dashboard - To access all the Post SMTP functionality at a glance. +2. Post SMTP New Setup Wizard (Step-01) - Choose your SMTP mailer +3. Post SMTP New Setup Wizard (Step -02) - Configure your mailer settings +4. Post New Setup Wizard (Step -03) - Send test email +5. Detailed Email Logs - View failed and successfully sent emails, resend, preview, and analyze error details +6. Post SMTP Mobile App Screen - Scan the QR code from the mobile app and connect it to track your WordPress emails. +7. Post SMTP Settings - Set email failure alerts on Microsoft Teams, Slack, Admin Email, Twilio, and Chrome extension + +## Upgrade Notice ## + +### 2.8.11 ### +Important: If you are using version 2.8.7 or lower of our plugin, please update to the latest version as soon as possible. This update contains an urgent security fix that prevents potential vulnerabilities and attacks. We apologize for any inconvenience this may cause you and we appreciate your cooperation. Thank you for using our plugin. + +== Changelog == + += 3.8.0 – Jan 20, 2026 = +* NEW – Added [Sweego](https://www.sweego.io/) as an email service provider. +* NEW – Introduced the "Send Test Notification" feature for Post SMTP failure alerts. +* TWEAK – Added a hide option for wp_mail conflict notice. +* FIX – PHPMailer with "Log Only" mode was sending emails. +* FIX – Corrected improper call to the function _load_textdomain_just_in_time. +* FIX – Fixed redirection issue that incorrectly navigated users to the Post SMTP settings page. + += 3.7.0 - Dec 24, 2025 = +* NEW – Added Mailtrap.io as an email service provider. +* FIX – The PHPMailerException already exist. +* FIX – Call to undefined method QRcode. +* FIX – Emailit API Emails were going without From name + += 3.6.3 - Dec 17, 2025 = +* FIX - Escape email content. += 3.6.2 - Nov 24, 2025 = +* IMPROVEMENT - Added PHP 8+ compatibility. +* FIX - Added authorization checks related to OAuth token updates for authenticated users. + += 3.6.1 – Oct 29, 2025 = +* IMPROVEMENT: Removed GIF from the plugin to enhance performance and reduce load time. +* IMPROVEMENT: Increased the request timeout for email sending to improve reliability and prevent timeouts. +* FIX: Resolved a missing authorization vulnerability. +* FIX: Addressed a WordPress error triggered when accessing the plugin settings page due to conflict with another theme/ plugin. + += 3.6.0 – Oct 14, 2025 = +* NEW – Added [Maileroo](https://postmansmtp.com/docs/mailers/how-to-setup-maileroo-with-post-smtp/) as an email service provider. +* TWEAK – Enhanced Setup Wizard content for better user guidance. +* TWEAK – Added a “Notify†button on the WordPress dashboard. +* IMPROVEMENT – Updated multiple recipient view in email logs for better clarity. +* FIX – Resolved undefined property issue in Post SMTP report after update. +* FIX – Fixed “Limit Exceeded†error during Email DNS test. +* FIX – Corrected failed message entries in logs. +* FIX – Resolved issue with “Save Password†reappearing unexpectedly. +* FIX – Fixed changelog display issue in Post SMTP. +* FIX – Addressed PHPMailer BCC and CC handling issues. +* FIX – Fixed host impersonation domain name issue. +* FIX – Removed unnecessary console logs from the admin dashboard. + += 3.5.0 - Sept 17, 2025 = +* NEW - Added [Emailit](https://postmansmtp.com/smtp-integrations/Emailit/) email service providers. +* TWEAK - Wizard Send Test Email disble button till the email is being sent. +* TWEAK - Limited the scope of Gmail. +* IMPROVEMENT - PHP 8+ compatibility added. +* IMPROVEMENT - Dashboard widget UI improvement. +* FIX - Fallback mailer was not working. +* FIX - SendGrid attachments were not working in some cases. +* FIX - Resending emails to multiple recipients was not working in some cases. +* FIX - PHP warning was appearing in some cases. +* FIX - PHP error was appearing in some cases Uncaught Error: Call to a member function getFromEmailAddress(). + += 3.4.2 - Sept 01, 2025 = +* Enhancement - Improved AJAX call security. +* Improvement - PHP 8+ version compatibility. + += 3.4.1 - Aug 20, 2025 = +* TWEAK - Updated Plugin URI in header + += 3.4.0 - Aug 18, 2025 = +* NEW - Added [Resend](https://postmansmtp.com/smtp-integrations/resend/) email service providers. +* UPDATED: Feedback SDK to the latest version. +* TWEAK - Removed irrelevant notices from Post SMTP Wizard. +* FIX - BCC/ CC fails with Sparkpost. +* FIX - reply-to was not working with Gravit Forms notifications with SMTP2GO. + += 3.3.0 - June 11, 2025 = +* NEW - WP Dashboard Widget +* NEW - Diagnostic Report Send Form +* NEW - [Mailersend](https://postmansmtp.com/smtp-integrations/mailersend-smtp/) Mailer Integration +* FIX - Added Validation In Domain Checker DNS, SPF, DMARC +* FIX - LOCO Translate Issue +* FIX - Email Summary Improvement +* FIX - Vulnerability Fix. + += 3.2.0 - May 19, 2025 = +* New - Introducing Email Tester to test your email deliverability. +* Fix - Removed id duplication in the Wizard. + += 3.1.4 - Apr 08, 2025 = +* FIX - To column in email logs was empty in some cases. + += 3.1.3 - Mar 03, 2025 = +* Enhancement: Email logs security enhancement. + += 3.1.2 - Feb 24, 2025 = +* Enhancement: Email logs security enhancement. + += 3.1.1 - Feb 11, 2025 = +* Fix: Raw HTML was sent when resending emails from the log section. +* Fix: AJAX error with some Form plugins. + += 3.1.0 - Feb 10, 2025 = +* New: Added SendGrid EU support. +* Optimization: Improved email reporting. +* Fix: Translation warning was appearing in some cases. +* Fix: Security enhancement. +* Fix: Prevent From Name was not working, if Prevent From Email was not enabled. +* Fix: Send Test was not appearing in Log Only mode. + += 3.0.2 - Jan 27, 2025 = +* Updated: Feedback SDK to the latest version. + += 3.0.1 - Jan 14, 2025 = +* Fix: Fixed the UI conflict. +* Fix: Fixed MySQL warning. +* Fix: Translation warning fixed. + += 3.0.0 - Jan 07, 2025 = +* New: Introduced all New Post SMTP Dashboard for users' ease. +* New: Introduced new SMTP socket SMTP2GO. +* New: Introduced new Send Mail user interface. +* New: Introduced Webhook, so you can add Webhook URL to get notified when an email is failed. + += 2.9.14 - December 18, 2024 = +* Tweak - WordPress 6.7 Transalation compatibility added. + += 2.9.13 - December 10, 2024 = +* Fix - Users were unable to regenerate [Mobile App](https://postmansmtp.com/post-smtp-mobile-app/) QR code in admin view. +* Tweak - WordPress 6.7 Transalation compatibility added. + += 2.9.12 - December 02, 2024 = +* Enhancement - Regenerate QR Code Mobile Applicaion security enhancement in admin view reported by Patchstack. + += 2.9.11 - November 21, 2024 = +* Updated: Feedback SDK to the latest version. +* Tweak: Failed email notification typo fixed. + += 2.9.10 - November 19, 2024 = +* Email logs search security enhancement in admin view reported by [Patchstack](https://patchstack.com/database/vulnerability/post-smtp/wordpress-post-smtp-plugin-2-9-9-sql-injection-vulnerability) + += 2.9.9 - October 01, 2024 = +* Tweak: Typo fixes. +* Tweak: Improved user interface in wizard. +* Fix: PHP deprecated warning on 8.x. +* Fix: Emails count was not accurate in [Weekly email](https://postmansmtp.com/post-smtp-release-v2-9-0-smtp-mailer-and-email-health-report/) in some cases. + += 2.9.8 - August 21, 2024 = +* New: Added SendGrid EU support. +* New: Added [pre_wp_mail](https://developer.wordpress.org/reference/hooks/pre_wp_mail/) filter. +* Tweak: Sometimes Post SMTP was not detecting Post SMTP Pro. +* Updated: Feedback SDK to the latest version. +* Fix - Mailjet - Reply-To email was not working properly. + += 2.9.7 - July 01, 2024 = +* Fix: Logs filter was not working in [Post SMTP Mobile Application](https://postmansmtp.com/post-smtp-mobile-app/?utm_source=wp_org&utm_medium=changelog) + += 2.9.6 2024-06-27 = +* Tweak - Some strings were not translatable. +* Fix - Compatibility added for old PHP Versions. +* Fix - Notice: Only variables should be passed by reference. + += 2.9.5 - 2024-06-25 = +* Added: New Successful, Failed, and All email filter on email logs. +* Added: Option to print email. +* Updated: The user interface of settings tabs + += 2.9.4 - 2024-05-29 = +* Security Improvement: Sanitized SQL queries suggested by Wordfence team. + += 2.9.3 - 2024-05-22 = +* IMPROVEMENT – Email health report settings and template UI +* FIX – Remove false email delivery count from the WordPress dashboard. + += 2.9.2 - 2024-05-13 = +* NEW - Added new filter post_smtp_postmark_content for developers ease. +* UPDATED - Google Client SDK to latest version. +* IMPROVEMENT - Site URL was missing in [Post SMTP Chrome Extension](https://chromewebstore.google.com/detail/post-smtp-notifications/npklmbkpbknkmbohdbpikeidiaekjoch). + += 2.9.1 - 2024-04-22 = +* Bug Fix: error appearing "syntax error, unexpected ')'". + += 2.9.0 - 2024-04-16 = +* New - Added email health report +* New - Added new socket/ email service SendPulse +* Fix - AJAX call was being interrupted by register_setting when specific plugins were activated. + += 2.8.13 - 2024-03-26 = +* FIXED: Reverted last fix as it was conflicting in some cases. + += 2.8.12 - 2024-03-26 = +* FIXED: AJAX call was being interrupted by register_setting when specific plugins were activated. + += 2.8.11 - 2024-01-19 = + +* Added link to the [new POST SMTP app for iOS](https://apps.apple.com/us/app/post-smtp/id6473368559) released. + += 2.8.10 - 2024-01-18 = + +* Security Improvement: Added check to automatically remove any connected device with incomplete information. + += 2.8.9 - 2024-01-11 = + +* Added compatibility for [InstaWP](https://www.instawp.com/) + += 2.8.8 - 2024-01-01 = + +* Improvement: Added sanitization and escape functions in [POST SMTP Mobile App](https://postmansmtp.com/post-smtp-app/?utm_source=wp_org&utm_medium=changelog) QR code scanning window. + += 2.8.7 - 2023-12-20 = + +* Improvement - added sanitization where missing to improve security +* Improvement - added nonce where missing to improve security + += 2.8.6 - 2023-12-07 = + +* Improvement - Changed banner placement for NEW mobile app for POST SMTP to improve UX. +* Improvement - Tweaked dashboard UI for better usability. + += 2.8.5 - 2023-11-23 = + +* Fix: In some cases, there was an issue disconnecting mobile application. + += 2.8.4 - 2023-11-20 = + +* Fix: From name and emails, prevention settings were not being saved correctly in some cases in the new wizard. +* Fix: In some sockets, the API keys getting saved were encoded in multiple layers. + += 2.8.3 - 2023-11-17 = + +* Fix - Getting error when saving settings in some scenarios. +* Improvement - Optimized QR code scanning module for [Post SMTP mobile app](https://postmansmtp.com/documentation/post-smtp-mobile-app/download-the-app-and-connect-with-plugin/?utm_source=wp_org&utm_medium=changelog) to avoid any scanning delays + += 2.8.2 - 2023-11-14 = + +* Improvement - PHP < 7.3 compatibility added. + += 2.8.1 - 2023-11-13 = + +* Fix - Other SMTP option in the wizard was not saving the settings correctly. + += 2.8.0 - 2023-11-13 = + +* NEW - Introducing a NEW 3-step wizard to speed up the initial setup. +* NEW - Added documentation within the wizard to ease out the setup +* NEW - Added new socket/email service for [Mailjet](https://www.mailjet.com/) +* NEW - Added support for default socket within wizard (you can use this option in case you want to use the logs functionality only) +* Fix - Updated the error string as reported by @interaptivre + += 2.7.2 - 2023-11-01 = + +* Improvement - Mobile App banner improvement. + += 2.7.1 - 2023-11-01 = + +* NEW - Show Mobile App Notice on Post SMTP dashboard +* Improvement - Improved SQL query to meet latest security standards +* Improvement - Added patch to avoid script execution in log content. + += 2.7.0 - 2023-10-26 = + +* NEW - Added support for POST SMTP app. [Visit documentation for more information](https://postmansmtp.com/documentation/post-smtp-mobile-app/download-the-app-and-connect-with-plugin/?utm_source=wp_org&utm_medium=changelog) +* Fix - Raw HTML was sent when using ElasticEmail service. +* Fix - Raw HTML was sent when resending emails from the log section. + += 2.6.2 - 2023-10-19 = + +* Tested up to WordPress v6.3.2 + += 2.6.1 - 2023-10-03 = + +* Fix: Removed broken link from test email. +* Improvement: Improved SQL query to meet latest security standards. +* Improvement: Replaced sanitize_text_field() with intval() as suggested by WP Scan team. + += 2.6.0 - 2023-09-12 = + +**NEW** + +* Elastic mail socket added +* When resetting the plugin settings, the user can check to preserve logs from getting removed +* MainWP integration added. How-to instructions will be available publicly soon. + +**FIX** + +* When using PHPMailer, the failed email log was not creating + +**IMPROVEMENT** + +* Now, users can skip the banner from the dashboard. + += 2.5.9.4 - 2023-08-29 = + +* API endpoint "SendinBlue" has been updated to "Brevo" + += 2.5.9.3 - 2023-08-17 = + +* Minor Tweaks + += 2.5.9.2 - 2023-08-16 = +* Compatible & Tested up to WordPress v6.3 + += 2.5.9.1 = +**NEW** + +* Added option to refresh recent logs in the dashboard without loading the page. +* Added new hooks in the code to make the functionality extendable. + += 2.5.9 - 2023-07-18 = +**IMPROVEMENTS** + +* Improved email log popup content + +**FIX** + +* Reverted support for HTML view in email content popup with proper checks to avoid CSS conflicts. + +**NEW** + +* Added new filter post_smtp_before_view_log to extend log section view. + += 2.5.8 - 2023-07-11 = +**IMPROVEMENTS** + +* Added function to escape backend email content popup HTML. +* Added Failed/success labels for better visibility. +* Displayed error message on hover and in the popup to simplify the interface and UX in the log section. +* Updated Feedback SDK to the latest version + +**FIXES** + +* Fix: Pagination was getting reset on resending emails. + += 2.5.7 - 2023-06-21 = +**IMPROVEMENTS** + +* Enhance code quality and strengthen security measures. + += 2.5.6 - 2023-06-08 = +**FIXES** + +* Critical error was being thrown when reseting the plugin. + += 2.5.5 - 2023-05-29 = +**FIXES** + +* Some of logs were overriding log page CSS. + +**IMPROVEMENTS** + +* Added title on log status for better user experience. +* Translation string improvement. + += 2.5.4 - 2023-05-24 = +**FIXES** + +* Logs were not created in some cases. + += 2.5.3 2023-05-16 = +**FIXES** + +* Fixed E_WARNING appearing on activation in some cases. + += 2.5.2 - 2023-05-12 = +**FIXES** + +* Fixed the issue where users were getting stuck in the initial migration stage. + +**IMPROVEMENTS** + +* On completing the migration process, limit the notice to the logs section only to delete old logs. +* Added an option to disable migration notifications for seven days on clicking the cross icon on notice. +* Added a new feature that allows users to revert a migration. This way, they can retry the migration process or switch back to the old logs interface if required. +* Added an option to skip the migration process for those who do not wish to transfer their old logs and want to switch to the new interface. +* Added permission check before creating/writing error log during migration. + += 2.5.1 - 2023-05-10 = +**NEW** + +* Added a link to learn more about migration. +* Added a condition to initiate the migration and logging only if the new custom table exists. + +**IMPROVEMENTS** + +* Improved database migration process to handle potential failures. + += 2.5.0 - 2023-05-09 = +**NEW** + +* Introducing a new log section that is both lightweight and optimized, capable of accommodating millions of entries. +* Added a migration wizard to help move existing logs to new custom tables from the old version. + += 2.4.9 - 2023-04-27 = +**FIXES** + +* Uncaught Error: Cannot use object of type WP_Error as array +* Fixed deprecation notice for PHP Version > 8.0 + +**IMPROVEMENTS** + +* Added condition for notice on how to fix broken emails + += 2.4.8 - 2023-04-17 = +**Bug Fix** + +* Fixed deprecated functions on Php 8.x + += 2.4.7 - 2023-04-10 = +**Improvements** + +* Updated feedback SDK to latest version +* Added PHP 8.1 compatibility + += 2.4.6 - 2023-03-27 = +**Bug Fixes** + +* Added new option in the settings to fix broken emails. + += 2.4.5 - 2023-03-14 = +**Bug Fixes** + +* Reverted the fix to support minor PHP versions, impacting some other PHP versions. +* NEW Filter post_smtp_incompatible_php added to fix the compatibility of minor PHP versions. + += 2.4.4 - 2023-03-08 = +**Bug Fixes** + +* Resolved an issue where warnings were generated due to an array to string conversion. +* Fixed a problem where CC and BCC recipients were not properly added when using SendInBlue. +* Addressed an issue where multiple recipients using SendInBlue were receiving emails individually instead of as a group. +* Fixed an email formatting issue that occurred in certain PHP versions. +* Corrected an issue where the friendly name feature was not functioning properly with SendInBlue. + += 2.4.3 - 2023-02-27 = +**Bug Fixes** + +* Fix - Code 400 error appearing in some cases for SendGrid with cc headers + += 2.4.2 - 2023-02-24 = +**Bug Fixes** + +* Email header request issue fixed for MailGun +* Email attachment issue is fixed in SendGrid + += 2.4.1 - 2023-02-22 = +**Bug Fixes** + +* Fixed parse error on Php 7.2 + += 2.4 - 2023-02-21 = +**Improvements** + +* Replaced Mandrill SDK with Endpoints +* Replaced SendGrid SDK with Endpoints + += 2.3.2 - 2023-01-06 = +**Bug Fixes** + +* Fixed error related to Reply-To appearing in some cases. + += 2.3.1 - 2023-01-05 = +**Bug Fixes** + +* Fixed issues appearing in PostmanLogFields.php +* Emails were getting broken in some cases + += 2.3 - 2023-01-03 = +**Bug Fixes** + +* PHP errors appear in ajax requests in some cases. +* Fixed comma breaking the From name in the log section +* Reply-to Header not being added in some instances (Reported by @pierrehooker) + +**Improvements** + +* Updated sender header as per RFC-2822 +* Added PHP 8 Compatibility +* Updated Google API SDK +* Replaced MailGun SDK with endpoints +* Replaced SendInBlue SDK with Endpoints + += 2.2.3 - 2022-12-27 = +**FIX** + +* Bug Fix - Support menu was disappearing in some cases + += 2.2.2 - 2022-12-19 = +**FIX** + +* SendGrid was missing on wizard +* PHP Warnings + += 2.2.1 - 2022-12-13 = +**FIX** + +* Email template HTML was broken + += 2.2 - 2022-12-08 = +* **NEW** +* Added New Socket/ Email Service Postmark +* Added New Socket/ Email Service SparkPost +* **IMPROVEMENTS** +* SSRF Prevention +* SQL Warning Removed +* MailGun SDK Updated to Latest Version +* Compatibility with BackupBuddy added +* **FIXES** +* Multisite Plugin Update +* Additional Headers were not saved properly in some cases +* Import Button was not working in some cases + += 2.1.10 - 2022-10-10 = +* **FIXES** +* Avoid redirection to wizard on activation +* Issue in resend emails +* Made backend setting fields visible +* **IMPROVEMENTS** +* Email host message +* Sendgrid message id to prevent spam emails + += 2.1.9 - 2022-09-9 = +* **FIX** +* User Compatibility Fix +* Unauthorized error on wizard + += 2.1.8 - 2022-09-5 = +* **FIX** +* Php warnings + += 2.1.7 - 2022-08-30 = +* **FIX** +* Server side request forgery + += 2.1.6 - 2022-08-29 = +* **FIX** +* Server side request forgery + += 2.1.5 - 2022-08-25 = +* **FIX** +* Updated email header to prevent email from being SPAM + += 2.1.4 - 2022-08-18 = +* **NEW** +* Redirect the user to the setup wizard on activating the Plugin +* Added action hook, "post_smtp_before_reset_plugin" to add an event before resetting plugin +* Added action hook, "post_smtp_after_reset_plugin" to add an event after resetting plugin +* Added notice to Grant Access after getting done with the wizard step to improve the UX + +* **FIXES** +* Tweaks for PHP Version 8+ compatibility +* Freemius Language FIX +* Security Fix to avoid XSS from admin settings +* Mailster support updated for the latest version (thanks to @evrpress) +* Typo fix: defualt to default (thanks to @jsilvermist) +* Updated email header to prevent email from being SPAM + += 2.1.3- 2022-07-1 = +* **FIX** +* PHP Version Compatibility. + += 2.1.2- 2022-06-30 = +* **NEW** +* Integrated SDK for Feedback and support. +* Added "Start wizard" button in setup notification to optimize UX for the end-user. + +* **Improved** +Removed unused code + +* **FIX** +Less secure App Banner appearing in non-appropriate cases + + += 2.1.1.1 - 2022-06-15 = +* **FIX** +* Sendinblue email header + += 2.1.1 - 2022-06-09 = +* **FIX** +* PHP Version Compatibility. + += 2.1 - 2022-06-09 = +* **NEW** +* All New UI +* Sendinblue API Integration + += 2.0.27 - 2022-05-19 = +Add notice about Google Less Secure App. + += 2.0.26 - 2022-04-22 = +* **Bug Fixes** +* Email header was broken in some cases. + +* **Improvements** +* Minor UI improvement. +* `llc` Hostname added in ZendMail. + += 2.0.25 - 2022-04-06 = +* **Bug Fixes** +* WP 5.9 Compatibility Ballon UI issue. +* Uncaught Error: Class PostmanAdminController not found. +* Ajax error appearing due to Google API depreciated function. + +* **Improvements** +* Code Optimization. +* MIME version added to test mails to prevent emails from spam. +* NEW Filter `postman_test_email_args` added to modify test email arguments. +* NEW Action `wp_mail_succeeded` added to exectue on every success email delivery. + += 2.0.24 - 2022-02-13 +* Update: THE FUTURE OF Post SMTP - https://postmansmtp.com/the-future-of-post-smtp/ + += 2.0.23 - 2021-04-22 +* Fixed: `WP_Scripts::localize called incorrectly` message. + += 2.0.22 - 2021-02-14 +* Update: Chrome extension URL change +* Fixed: Double save when extension save to option + += 2.0.21 - 2021-02-11 +* Fixed: Security issue - nonce validation. +* Fixed: Class PostmanViewController not found +* New: New wp-config.php constant to disable the email logger = `POST_SMTP_CORE_MAIL_LOG`. + += 2.0.20 - 2021-01-19 +* Fixed: All reported office 365 issues. +* New: Add link to Amazon SES Extension + += 2.0.19 - 2021-01-19 +* Fixed: All reported office 365 issues. +* New: Add link to Amazon SES Extension + += 2.0.18 - 2021-01-17 +* New: Plugin Extensions + += 2.0.16 - 2020-12-13 +* Update: General Info + += 2.0.15 - 2020-08-12 +* Fixed: WordPress 5.5 compatibility (stable) + += 2.0.14 - 2020-08-11 +* Removed: WordPress 5.5 compatibility (bug) + += 2.0.13 - 2020-08-11 +* Fixed: WordPress 5.5 compatibility +* Fixed: Email log filtering +* Fixed: Pushover notifications +* New: Suggest solution for email delivery errors + += 2.0.12 - 2020-05-18 +* Updated: Readme file info + += 2.0.11 - 2020-02-25 +* Fixed: Slack notifications + += 2.0.10 - 2020-01-21 +* Fixed: HTML content type +* Fixed: Sendgrid crash when has duplicates recipients (bypass, Sendgrid issue). +* Fixed: Few OAuth undefined notifications +* Fixed: Duplicate Emails - When you have notify and confirm (Ninja forms, etc..) +* Fixed: Logs wp_error convert + += 2.0.9 - 2020-01-13 +* Fixed: Notify on error bug - crash site +* Fixed: From header + += 2.0.8 - 2020-01-12 +* Updated: Reply-To header bug + += 2.0.7 - 2020-01-12 +* Updated: Improve PHPMailer method. +* Updated: Bug fixes. + += 2.0.6 - 2019-10-08 +* Updated: Bug fixes. + += 2.0.5 - 2019-09-26 +* New: You can now export logs to CSV. +* Updated: Few notifications errors, and minor improvements. + += 2.0.4 - 2019-08-27 +* Updated: More security. + += 2.0.3 - 2019-08-21 +* Fixed: A few security issues. + += 2.0.2 - 2019-05-19 +* Fixed: Sendgrid code fix. +* Fixed: Default method (nothing configured) will use the default mail on the server and not SMTP. + += 2.0.1 - 2019-05-15 +* New: Mailer Type - Added an option to send without overwrite the 'wp_mail' function, better compability to WordPress delivery. hopefully will be the default in the future. +* Updated: Sendgrid API was upgraded and rewritten to the new version. +* Fixed: Message-Id header was missing on SMTP +* Fixed: Email logger optimization - better query for large amount of records. +* Fixed: The localization was fixed to match translate.wordpress.org translation system ( Thanks to Niels de Blaauw from Level-Level ). +* Fixed: Code and optimization ( Thanks to Niels de Blaauw from Level-Level ). + += 1.9.8 - 2019-02-18 +* New: a new from field to the fallback - Can't trust the username as "from" value (email address). + += 1.9.7 - 2019-02-17 +* New: Fallback Feature - Configure a backup SMTP when emails are failing. +* New: WordPress Multisite compability - with global settings. +* New: Email Log capability - give other user cheking the logs. +* Fixed: compatibility with mailster plugin +* Fixed: Mandrill exception bug - Thanks to Niels de Blaauw from Level-Level + += 1.9.6 - 2019-01-29 +* Added support for our new chrome notification extension. +* few fixes + += 1.9.5 - 2018-10-02 +* Added support for Mailgun Europe region. +* Replace "buggy" mime_content_type php function + += 1.9.4 - 2018-08-03 +The most stupid idea ever remove (auto security select) + += 1.9.3 - 2018-07-26 +Removed auto configure for port 25 (can be TLS) + += 1.9.2 - 2018-07-23 +Removed deprecated functions from 7.2 + comment unready feature + += 1.9.1 - 2018-07-22 +Syntx stupid mistake + += 1.9.0 - 2018-07-22 +* Better support for secure delivery +* Support for constants auth (inside wp-config), check the detailes our [Blog](https://postmansmtp.com/post-smtp-1-9-0-better-support-for-secure-delivery) +* Automatic encryption select base on the port input - 25, 465, 587, 2525 + += 1.8.9 - 2018-04-24 +* Sendgrid bug + += 1.8.8 - 2018-04-24 +* file added to svn - contactform7 + += 1.8.6 - 2018-04-24 +* Fix lockfile erros +* Contact form 7 integration +* PHP 5.6 requirement + += 1.8.5 - 2018-04-19 +* Remove Beta Woocommerce integration +* Better check for WPML less then version 3.9 + += 1.8.4 - 2018-04-18 +* New: Multiple notification options to failed emails +* Upgrade: The Gmail code was upgraded and code change to support large attachments +* Add: Fix release lock file error +* Change: "Not configured..." message is now dismissible + += 1.8.3 - 2018-03-21 +* Fix: SendGrid API Call Structure (The previous try didn't work) + += 1.8.2 - 2018-03-21 +* Fix: SendGrid API Call Structure + += 1.8.1 - 2018-03-20 +* New: Sendgrid API & Client Version 6 +* New: Add email log 'send to' column +* Fix: fallback emails on hosting require the '-f' parameter +* Fix: Using hostname insted of an IP +* Fix: Remove mailgun test folder ( virustotal issue ) +* Fix: Additional bugs collected from support tickets. +* Added: added filters to from_name and from_email filters (local connection) +* change hostname extrect logic + += 1.8 - 2017-12-24 +* New: Mailgun API integration +* New: New filter controls +* New: WPML conflict fix +* Fix: Minor old bugs + += 1.7.10 - 2017-11-21 == +* Fixed: bug while detecting transcript error + += 1.7.9 - 2017-11-20 +* Fixed: misspled false +* Fixed: feedback form +* Fixed: Some localization strings +* Removed: deprecated function +* New: Option to input emails when resend email +* Added: explain message on email log filter + += 1.7.8 - 2017-11-17 +* = Menu Items grouping = +* Fixed: IP detection error in some web hosts +* Fixed: Link open in new page attribute = _blank +* Fixed: Replace deprecated PHP 7 functions. +* Updated: Validator TLD's list +* Added: Email log date and search filter. +* Added: Alert on sending error (Fallback to local mail) +* Added: Email body preview (not raw) + += 1.7.7 - 2017-10-17 +* Fixed: Error sending files with sendgrid +* Fixed: Wrong attachments format in Mandrill +* Fixed: Wrong Sender Header in Mandrill + += 1.7.6 - 2017-10-17 +* Missing sendgrid files +* Fixed: Localization slug + += 1.7.5 - 2017-10-07 = +* Fixed: security issue (XSS) +* Fixed: Small bug with Google API + += 1.7.2 - 2015-11-08 = +* [[Ticket](https://wordpress.org/support/topic/having-troble-in-17-while-set-content-type-to-texthtml?replies=8)] - v1.7 ignores the content-type header set in the Additional Headers. Fixed. +* [[Ticket](https://wordpress.org/support/topic/do-not-network-activate-17-on-multisite?replies=15)] - Fixed an issue where v1.7 admin screens crash for non-admin users when Post is not configured. Fixed a multiste issue where v1.7 site admins lose access to their Post settings screen. Special thank-you to Domi2015 for giving me access for testing! :) +* Localized jQuery Validation messages +* Localized MyMail messages +* Put the local translation files back, as WordPress on-line translations do not work as advertised + += 1.7.1 - 2015-11-05 = +* [[Ticket](https://wordpress.org/support/topic/cant-send-an-email-using-optimizepress?replies=8)] - the Optimizepress plugin calls wp_mail before the WordPress init hook, before Post is fully initialized, so I made a change to accomodate this behavior +* [[Ticket](https://wordpress.org/support/topic/v17?replies=13)] - v1.7 admin screen may become inaccessible after upgrading. Fixed. +* [[Ticket](https://wordpress.org/support/topic/inboundnow-html-e-mail-templates-are-not-being-recognized-with-170?replies=3)] - v1.7 breaks compatibility with [WordPress Leads](https://wordpress.org/plugins/leads/). Fixed. + += 1.7.0 "Iliana" - 2015-11-03 = +* Happy Halowe'en! 30,000 installations! - 2015-10-31 +* Integrated Mandrill API +* Integrated SendGrid API +* Language files have been removed from the plugin as [translations are now performed on-line](https://translate.wordpress.org/projects/wp-plugins/Post-smtp). If you are a non-English speaker please constribute! +* Post commandeers email when activated and sends using the WordPress default of localhost:25 - this is for people who want to use it to diagnose email problems without configuring SMTP +* Re-send failed e-mails from the Email Log screen +* Added an internal 'manage_Post_smtp' capability for advanced management with, for example, [User Role Editor](https://wordpress.org/plugins/user-role-editor/) +* [[Ticket](https://wordpress.org/support/topic/exportimport-settings-4?replies=2)][[Ticket](https://wordpress.org/support/topic/export-import-configuration?replies=1)] Added an import/export tab to the Advanced Configuration screen for those who want to duplicate settings between sites. +* [[Ticket](https://wordpress.org/support/topic/gateway-error-invalid-envelope-from-mail-address?replies=9#post-7528068)] Added option to disable e-mail address validation +* [[Ticket](https://wordpress.org/support/topic/error-665?replies=7#post-7581776)] Fix for fatal error when using a non-administrator in the admin menu. + += 1.6.24 - 2015-09-10 = +* 20,000 installations! - 2015-09-09 +* Translated into Greek, thank-you Michael Kotsarinis! +* Diagnostic Test displays all the wp_mail-related hooks of active plugins and themes +* When validating e-mail addresses, Post will disclose which field has a validation issue in the error message +* Default log entries bumped from 10 to 250 +* [[Ticket](https://wordpress.org/support/topic/for-your-consideration-backup-email-notification?replies=5)] Added nasty fake input field hack to prevent browsers from autofilling username/password fields. +* [[Ticket](https://wordpress.org/support/topic/cf7-godaddy-emails-not-delivered?replies=5)] Added a warning to the Email Log for emails that have an empty subject line +* [[Ticket](https://wordpress.org/support/topic/test-failed-but-meesage-is-sent?replies=12)] Test Email detects Ajax errors and displays them in the Status window +* [[Ticket](https://wordpress.org/support/topic/missing-image-files-of-jquery-ui-1?replies=4)] Removed the references to images in Post's copy of jquery-ui.css causing HTTP 404 +* [[Ticket](https://wordpress.org/support/topic/test-email-keeps-on-failing?replies=17)] Fixed an Ajax name collision with the plugin [MemberPress](https://www.memberpress.com) +* [[Ticket](https://wordpress.org/support/topic/message-body-not-send?replies=15)] Some sites can not handle International (UTF-8) characters in the Test Email. Fixed. +* [[Ticket](https://wordpress.org/support/topic/notices-for-google-api-php-client?replies=10)] Fix for PHP Notice: Undefined offset: 1 in Post-smtp/Post/Post-Mail/google-api-php-client-1.1.2/autoload.php on line 22 +* [[Ticket](https://wordpress.org/support/topic/test-failed-but-meesage-is-sent?replies=13)] Silenced PHP warnings in Zend_Mail from ini_set + += 1.6.23 - 2015-06-27 = +* 10,000 installations! - 2015-06-27 +* 9,000 installations! - 2015-06-20 +* [[Ticket](https://wordpress.org/support/topic/conflict-with-bbpress-and-buddy-press-in-1622?replies=2)] Causes bbPress or Buddy Press to generate warning messages. Fixed. +* [[Ticket](https://wordpress.org/support/topic/fatal-error-internal-zend-error-missing-class-information?replies=2#post-7092317)] User reported error "Fatal error: Internal Zend error - Missing class information" - Whoops, used 'require' PostState.php instead of 'require_once' PostState.php which was causing errors. Fixed. +* [[Ticket](https://wordpress.org/support/topic/error-send-mymail-email-marketing?replies=5)] [[Ticket](https://wordpress.org/support/topic/how-configure-mymail-in-plugin?replies=6)] MyMail Newsletter Plugin for WordPress refuses to use wp_mail. I don't want to make this a habit, but I've integrated Post with MyMail's proprietary delivery mechanism. +* [[Ticket](https://wordpress.org/support/topic/cant-send-error-500?replies=11#post-7103035)] Found an environment where the plugin's call to new Exception was creating PHP Fatal errors. Fixed. +* [[Ticket](https://wordpress.org/support/topic/error-calling-post-400-invalid-to-header?replies=4)] Perform validation on all email headers before send \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/script/feedback/feedback.js b/html/wp-content/plugins/post-smtp/script/feedback/feedback.js new file mode 100644 index 0000000..da94efc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/script/feedback/feedback.js @@ -0,0 +1,102 @@ +jQuery(document).ready(function($) { + + $( '#the-list #postman-plugin-disbale-link' ).click(function(e) { + e.preventDefault(); + + var reason = $( '#postman-feedback-dialog-content .postman-reason' ), + deactivateLink = $( this ).attr( 'href' ); + + $( "#postman-feedback-dialog-content" ).dialog({ + title: 'Post SMTP Feedback Form', + dialogClass: 'postman-feedback-dialog-form', + resizable: false, + minWidth: 400, + minHeight: 300, + modal: true, + buttons: { + 'go' : { + text: 'Continue', + icons: { primary: "dashicons dashicons-update" }, + id: 'postman-feedback-dialog-go', + class: 'button', + click: function() { + + var dialog = $(this), + go = $('#postman-feedback-dialog-go'), + form = dialog.find( 'form' ).serializeArray(), + result = {}; + + $.each( form, function() { + if ( '' !== this.value ) + result[ this.name ] = this.value; + }); + + if ( ! jQuery.isEmptyObject( result ) ) { + result.action = 'post_user_feedback'; + + $.ajax({ + url: post_feedback.admin_ajax, + type: 'POST', + data: result, + error: function(){}, + success: function(msg){}, + beforeSend: function() { + go.addClass('postman-ajax-progress'); + }, + complete: function() { + go.removeClass('postman-ajax-progress'); + + dialog.dialog( "close" ); + location.href = deactivateLink; + } + }); + + } + + + }, + }, + 'cancel' : { + text: 'Cancel', + id: 'postman-feedback-dialog-cancel', + class: 'button button-primary', + click: function() { + $( this ).dialog( "close" ); + } + }, + 'skip' : { + text: 'Skip', + id: 'postman-feedback-dialog-skip', + click: function() { + $( this ).dialog( "close" ); + + location.href = deactivateLink; + } + }, + } + }); + + reason.change(function() { + $( '.postman-reason-input' ).hide(); + + if ( $( this ).hasClass( 'postman-custom-input' ) ) { + var reason = $(this).find('input').data('reason'); + var wrap = $( '#postman-deactivate-reasons' ).next( '.postman-reason-input' ); + var input = wrap.find('input'); + console.log(input); + + if ( reason ) { + input.attr('placeholder',reason); + } else { + input.attr('placeholder','Do you mind help and give more detailes?'); + } + wrap.show(); + } + + if ( $( this ).hasClass( 'postman-support-input' ) ) { + $( this ).find( '.postman-reason-input' ).show(); + } + }); + + }); +}); \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/script/jquery-steps/jquery.steps.js b/html/wp-content/plugins/post-smtp/script/jquery-steps/jquery.steps.js new file mode 100644 index 0000000..4d0525a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/script/jquery-steps/jquery.steps.js @@ -0,0 +1,2042 @@ +/*! + * jQuery Steps v1.1.0 - 09/04/2014 + * Copyright (c) 2014 Rafael Staib (http://www.jquery-steps.com) + * Licensed under MIT http://www.opensource.org/licenses/MIT + */ +;(function ($, undefined) +{ +$.fn.extend({ + _aria: function (name, value) + { + return this.attr("aria-" + name, value); + }, + + _removeAria: function (name) + { + return this.removeAttr("aria-" + name); + }, + + _enableAria: function (enable) + { + return (enable == null || enable) ? + this.removeClass("disabled")._aria("disabled", "false") : + this.addClass("disabled")._aria("disabled", "true"); + }, + + _showAria: function (show) + { + return (show == null || show) ? + this.show()._aria("hidden", "false") : + this.hide()._aria("hidden", "true"); + }, + + _selectAria: function (select) + { + return (select == null || select) ? + this.addClass("current")._aria("selected", "true") : + this.removeClass("current")._aria("selected", "false"); + }, + + _id: function (id) + { + return (id) ? this.attr("id", id) : this.attr("id"); + } +}); + +if (!String.prototype.format) +{ + String.prototype.format = function() + { + var args = (arguments.length === 1 && $.isArray(arguments[0])) ? arguments[0] : arguments; + var formattedString = this; + for (var i = 0; i < args.length; i++) + { + var pattern = new RegExp("\\{" + i + "\\}", "gm"); + formattedString = formattedString.replace(pattern, args[i]); + } + return formattedString; + }; +} + +/** + * A global unique id count. + * + * @static + * @private + * @property _uniqueId + * @type Integer + **/ +var _uniqueId = 0; + +/** + * The plugin prefix for cookies. + * + * @final + * @private + * @property _cookiePrefix + * @type String + **/ +var _cookiePrefix = "jQu3ry_5teps_St@te_"; + +/** + * Suffix for the unique tab id. + * + * @final + * @private + * @property _tabSuffix + * @type String + * @since 0.9.7 + **/ +var _tabSuffix = "-t-"; + +/** + * Suffix for the unique tabpanel id. + * + * @final + * @private + * @property _tabpanelSuffix + * @type String + * @since 0.9.7 + **/ +var _tabpanelSuffix = "-p-"; + +/** + * Suffix for the unique title id. + * + * @final + * @private + * @property _titleSuffix + * @type String + * @since 0.9.7 + **/ +var _titleSuffix = "-h-"; + +/** + * An error message for an "index out of range" error. + * + * @final + * @private + * @property _indexOutOfRangeErrorMessage + * @type String + **/ +var _indexOutOfRangeErrorMessage = "Index out of range."; + +/** + * An error message for an "missing corresponding element" error. + * + * @final + * @private + * @property _missingCorrespondingElementErrorMessage + * @type String + **/ +var _missingCorrespondingElementErrorMessage = "One or more corresponding step {0} are missing."; + +/** + * Adds a step to the cache. + * + * @static + * @private + * @method addStepToCache + * @param wizard {Object} A jQuery wizard object + * @param step {Object} The step object to add + **/ +function addStepToCache(wizard, step) +{ + getSteps(wizard).push(step); +} + +function analyzeData(wizard, options, state) +{ + var stepTitles = wizard.children(options.headerTag), + stepContents = wizard.children(options.bodyTag); + + // Validate content + if (stepTitles.length > stepContents.length) + { + throwError(_missingCorrespondingElementErrorMessage, "contents"); + } + else if (stepTitles.length < stepContents.length) + { + throwError(_missingCorrespondingElementErrorMessage, "titles"); + } + + var startIndex = options.startIndex; + + state.stepCount = stepTitles.length; + + // Tries to load the saved state (step position) + if (options.saveState && $.cookie) + { + var savedState = $.cookie(_cookiePrefix + getUniqueId(wizard)); + // Sets the saved position to the start index if not undefined or out of range + var savedIndex = parseInt(savedState, 0); + if (!isNaN(savedIndex) && savedIndex < state.stepCount) + { + startIndex = savedIndex; + } + } + + state.currentIndex = startIndex; + + stepTitles.each(function (index) + { + var item = $(this), // item == header + content = stepContents.eq(index), + modeData = content.data("mode"), + mode = (modeData == null) ? contentMode.html : getValidEnumValue(contentMode, + (/^\s*$/.test(modeData) || isNaN(modeData)) ? modeData : parseInt(modeData, 0)), + contentUrl = (mode === contentMode.html || content.data("url") === undefined) ? + "" : content.data("url"), + contentLoaded = (mode !== contentMode.html && content.data("loaded") === "1"), + step = jQuery.extend({}, stepModel, { + title: item.html(), + content: (mode === contentMode.html) ? content.html() : "", + contentUrl: contentUrl, + contentMode: mode, + contentLoaded: contentLoaded + }); + + addStepToCache(wizard, step); + }); +} + +/** + * Triggers the onCanceled event. + * + * @static + * @private + * @method cancel + * @param wizard {Object} The jQuery wizard object + **/ +function cancel(wizard) +{ + wizard.triggerHandler("canceled"); +} + +function decreaseCurrentIndexBy(state, decreaseBy) +{ + return state.currentIndex - decreaseBy; +} + +/** + * Removes the control functionality completely and transforms the current state to the initial HTML structure. + * + * @static + * @private + * @method destroy + * @param wizard {Object} A jQuery wizard object + **/ +function destroy(wizard, options) +{ + var eventNamespace = getEventNamespace(wizard); + + // Remove virtual data objects from the wizard + wizard.unbind(eventNamespace).removeData("uid").removeData("options") + .removeData("state").removeData("steps").removeData("eventNamespace") + .find(".actions a").unbind(eventNamespace); + + // Remove attributes and CSS classes from the wizard + wizard.removeClass(options.clearFixCssClass + " vertical"); + + var contents = wizard.find(".content > *"); + + // Remove virtual data objects from panels and their titles + contents.removeData("loaded").removeData("mode").removeData("url"); + + // Remove attributes, CSS classes and reset inline styles on all panels and their titles + contents.removeAttr("id").removeAttr("role").removeAttr("tabindex") + .removeAttr("class").removeAttr("style")._removeAria("labelledby") + ._removeAria("hidden"); + + // Empty panels if the mode is set to 'async' or 'iframe' + wizard.find(".content > [data-mode='async'],.content > [data-mode='iframe']").empty(); + + var wizardSubstitute = $("<{0} class=\"{1}\">".format(wizard.get(0).tagName, wizard.attr("class"))); + + var wizardId = wizard._id(); + if (wizardId != null && wizardId !== "") + { + wizardSubstitute._id(wizardId); + } + + wizardSubstitute.html(wizard.find(".content").html()); + wizard.after(wizardSubstitute); + wizard.remove(); + + return wizardSubstitute; +} + +/** + * Triggers the onFinishing and onFinished event. + * + * @static + * @private + * @method finishStep + * @param wizard {Object} The jQuery wizard object + * @param state {Object} The state container of the current wizard + **/ +function finishStep(wizard, state) +{ + var currentStep = wizard.find(".steps li").eq(state.currentIndex); + + if (wizard.triggerHandler("finishing", [state.currentIndex])) + { + currentStep.addClass("done").removeClass("error"); + wizard.triggerHandler("finished", [state.currentIndex]); + } + else + { + currentStep.addClass("error"); + } +} + +/** + * Gets or creates if not exist an unique event namespace for the given wizard instance. + * + * @static + * @private + * @method getEventNamespace + * @param wizard {Object} A jQuery wizard object + * @return {String} Returns the unique event namespace for the given wizard + */ +function getEventNamespace(wizard) +{ + var eventNamespace = wizard.data("eventNamespace"); + + if (eventNamespace == null) + { + eventNamespace = "." + getUniqueId(wizard); + wizard.data("eventNamespace", eventNamespace); + } + + return eventNamespace; +} + +function getStepAnchor(wizard, index) +{ + var uniqueId = getUniqueId(wizard); + + return wizard.find("#" + uniqueId + _tabSuffix + index); +} + +function getStepPanel(wizard, index) +{ + var uniqueId = getUniqueId(wizard); + + return wizard.find("#" + uniqueId + _tabpanelSuffix + index); +} + +function getStepTitle(wizard, index) +{ + var uniqueId = getUniqueId(wizard); + + return wizard.find("#" + uniqueId + _titleSuffix + index); +} + +function getOptions(wizard) +{ + return wizard.data("options"); +} + +function getState(wizard) +{ + return wizard.data("state"); +} + +function getSteps(wizard) +{ + return wizard.data("steps"); +} + +/** + * Gets a specific step object by index. + * + * @static + * @private + * @method getStep + * @param index {Integer} An integer that belongs to the position of a step + * @return {Object} A specific step object + **/ +function getStep(wizard, index) +{ + var steps = getSteps(wizard); + + if (index < 0 || index >= steps.length) + { + throwError(_indexOutOfRangeErrorMessage); + } + + return steps[index]; +} + +/** + * Gets or creates if not exist an unique id from the given wizard instance. + * + * @static + * @private + * @method getUniqueId + * @param wizard {Object} A jQuery wizard object + * @return {String} Returns the unique id for the given wizard + */ +function getUniqueId(wizard) +{ + var uniqueId = wizard.data("uid"); + + if (uniqueId == null) + { + uniqueId = wizard._id(); + if (uniqueId == null) + { + uniqueId = "steps-uid-".concat(_uniqueId); + wizard._id(uniqueId); + } + + _uniqueId++; + wizard.data("uid", uniqueId); + } + + return uniqueId; +} + +/** + * Gets a valid enum value by checking a specific enum key or value. + * + * @static + * @private + * @method getValidEnumValue + * @param enumType {Object} Type of enum + * @param keyOrValue {Object} Key as `String` or value as `Integer` to check for + */ +function getValidEnumValue(enumType, keyOrValue) +{ + validateArgument("enumType", enumType); + validateArgument("keyOrValue", keyOrValue); + + // Is key + if (typeof keyOrValue === "string") + { + var value = enumType[keyOrValue]; + if (value === undefined) + { + throwError("The enum key '{0}' does not exist.", keyOrValue); + } + + return value; + } + // Is value + else if (typeof keyOrValue === "number") + { + for (var key in enumType) + { + if (enumType[key] === keyOrValue) + { + return keyOrValue; + } + } + + throwError("Invalid enum value '{0}'.", keyOrValue); + } + // Type is not supported + else + { + throwError("Invalid key or value type."); + } +} + +/** + * Routes to the next step. + * + * @static + * @private + * @method goToNextStep + * @param wizard {Object} The jQuery wizard object + * @param options {Object} Settings of the current wizard + * @param state {Object} The state container of the current wizard + * @return {Boolean} Indicates whether the action executed + **/ +function goToNextStep(wizard, options, state) +{ + return paginationClick(wizard, options, state, increaseCurrentIndexBy(state, 1)); +} + +/** + * Routes to the previous step. + * + * @static + * @private + * @method goToPreviousStep + * @param wizard {Object} The jQuery wizard object + * @param options {Object} Settings of the current wizard + * @param state {Object} The state container of the current wizard + * @return {Boolean} Indicates whether the action executed + **/ +function goToPreviousStep(wizard, options, state) +{ + return paginationClick(wizard, options, state, decreaseCurrentIndexBy(state, 1)); +} + +/** + * Routes to a specific step by a given index. + * + * @static + * @private + * @method goToStep + * @param wizard {Object} The jQuery wizard object + * @param options {Object} Settings of the current wizard + * @param state {Object} The state container of the current wizard + * @param index {Integer} The position (zero-based) to route to + * @return {Boolean} Indicates whether the action succeeded or failed + **/ +function goToStep(wizard, options, state, index) +{ + if (index < 0 || index >= state.stepCount) + { + throwError(_indexOutOfRangeErrorMessage); + } + + if (options.forceMoveForward && index < state.currentIndex) + { + return; + } + + var oldIndex = state.currentIndex; + if (wizard.triggerHandler("stepChanging", [state.currentIndex, index])) + { + // Save new state + state.currentIndex = index; + saveCurrentStateToCookie(wizard, options, state); + + // Change visualisation + refreshStepNavigation(wizard, options, state, oldIndex); + refreshPagination(wizard, options, state); + loadAsyncContent(wizard, options, state); + startTransitionEffect(wizard, options, state, index, oldIndex, function() + { + wizard.triggerHandler("stepChanged", [index, oldIndex]); + }); + } + else + { + wizard.find(".steps li").eq(oldIndex).addClass("error"); + } + + return true; +} + +function increaseCurrentIndexBy(state, increaseBy) +{ + return state.currentIndex + increaseBy; +} + +/** + * Initializes the component. + * + * @static + * @private + * @method initialize + * @param options {Object} The component settings + **/ +function initialize(options) +{ + /*jshint -W040 */ + var opts = jQuery.extend(true, {}, defaults, options); + + return this.each(function () + { + var wizard = $(this); + var state = { + currentIndex: opts.startIndex, + currentStep: null, + stepCount: 0, + transitionElement: null + }; + + // Create data container + wizard.data("options", opts); + wizard.data("state", state); + wizard.data("steps", []); + + analyzeData(wizard, opts, state); + render(wizard, opts, state); + registerEvents(wizard, opts); + + // Trigger focus + if (opts.autoFocus && _uniqueId === 0) + { + getStepAnchor(wizard, opts.startIndex).focus(); + } + + wizard.triggerHandler("init", [opts.startIndex]); + }); +} + +/** + * Inserts a new step to a specific position. + * + * @static + * @private + * @method insertStep + * @param wizard {Object} The jQuery wizard object + * @param options {Object} Settings of the current wizard + * @param state {Object} The state container of the current wizard + * @param index {Integer} The position (zero-based) to add + * @param step {Object} The step object to add + * @example + * $("#wizard").steps().insert(0, { + * title: "Title", + * content: "", // optional + * contentMode: "async", // optional + * contentUrl: "/Content/Step/1" // optional + * }); + * @chainable + **/ +function insertStep(wizard, options, state, index, step) +{ + if (index < 0 || index > state.stepCount) + { + throwError(_indexOutOfRangeErrorMessage); + } + + // TODO: Validate step object + + // Change data + step = jQuery.extend({}, stepModel, step); + insertStepToCache(wizard, index, step); + if (state.currentIndex !== state.stepCount && state.currentIndex >= index) + { + state.currentIndex++; + saveCurrentStateToCookie(wizard, options, state); + } + state.stepCount++; + + var contentContainer = wizard.find(".content"), + header = $("<{0}>{1}".format(options.headerTag, step.title)), + body = $("<{0}>".format(options.bodyTag)); + + if (step.contentMode == null || step.contentMode === contentMode.html) + { + body.html(step.content); + } + + if (index === 0) + { + contentContainer.prepend(body).prepend(header); + } + else + { + getStepPanel(wizard, (index - 1)).after(body).after(header); + } + + renderBody(wizard, state, body, index); + renderTitle(wizard, options, state, header, index); + refreshSteps(wizard, options, state, index); + if (index === state.currentIndex) + { + refreshStepNavigation(wizard, options, state); + } + refreshPagination(wizard, options, state); + + return wizard; +} + +/** + * Inserts a step object to the cache at a specific position. + * + * @static + * @private + * @method insertStepToCache + * @param wizard {Object} A jQuery wizard object + * @param index {Integer} The position (zero-based) to add + * @param step {Object} The step object to add + **/ +function insertStepToCache(wizard, index, step) +{ + getSteps(wizard).splice(index, 0, step); +} + +/** + * Handles the keyup DOM event for pagination. + * + * @static + * @private + * @event keyup + * @param event {Object} An event object + */ +function keyUpHandler(event) +{ + var wizard = $(this), + options = getOptions(wizard), + state = getState(wizard); + + if (options.suppressPaginationOnFocus && wizard.find(":focus").is(":input")) + { + event.preventDefault(); + return false; + } + + var keyCodes = { left: 37, right: 39 }; + if (event.keyCode === keyCodes.left) + { + event.preventDefault(); + goToPreviousStep(wizard, options, state); + } + else if (event.keyCode === keyCodes.right) + { + event.preventDefault(); + goToNextStep(wizard, options, state); + } +} + +/** + * Loads and includes async content. + * + * @static + * @private + * @method loadAsyncContent + * @param wizard {Object} A jQuery wizard object + * @param options {Object} Settings of the current wizard + * @param state {Object} The state container of the current wizard + */ +function loadAsyncContent(wizard, options, state) +{ + if (state.stepCount > 0) + { + var currentIndex = state.currentIndex, + currentStep = getStep(wizard, currentIndex); + + if (!options.enableContentCache || !currentStep.contentLoaded) + { + switch (getValidEnumValue(contentMode, currentStep.contentMode)) + { + case contentMode.iframe: + wizard.find(".content > .body").eq(state.currentIndex).empty() + .html(" + + `; + + //Show Attachments + if( response.data.attachments !== undefined ) { + + popupContent += ` +
            +
            `; + + jQuery.each( response.data.attachments, function( i, attachment ) { + + popupContent += `${attachment}
            `; + + } ); + + popupContent += `
            `; + + } + + jQuery( '.ps-popup-container' ).find( 'h1' ).after( popupContent ); + + } + + } + else { + + alert( response.message ); + + } + + + } + + } ); + + } ); + + //Refresh Logs + jQuery( document ).on( 'click', '.ps-refresh-logs', function( e ) { + + e.preventDefault(); + logsDT.ajax.reload(); + + } ); + + //View And Session Transcript Popup + jQuery( document ).on( 'click', '.ps-popup-btn', function( e ) { + + jQuery( '.ps-popup-wrap' ).fadeIn( 500 ); + jQuery( '.ps-popup-box' ).removeClass( 'transform-out' ).addClass( 'transform-in' ); + + e.preventDefault(); + + } ); + + jQuery( document ).on( 'click', '.ps-popup-close', function( e ) { + + jQuery( '.ps-popup-wrap' ).fadeOut( 500 ); + jQuery( '.ps-popup-box' ).removeClass( 'transform-in' ).addClass( 'transform-out' ); + jQuery( '.ps-print-email' ).remove(); + + e.preventDefault(); + + }); + + //Delete Log + jQuery( document ).on( 'click', '.ps-email-log-delete', function( e ) { + + e.preventDefault(); + var id = jQuery( this ).closest( 'tr' ).find( '.ps-email-log-cb' ).val(); + var confirmation = confirm( 'Are you sure you want to delete this email log?' ); + var selected = []; + selected.push( id ); + + if( confirmation === false ) { + + return; + + } + + jQuery( this ).closest( 'tr' ).fadeOut(); + + jQuery.ajax( { + url: ajaxurl, + type: 'POST', + data: { + action: 'ps-delete-email-logs', + security: logsDTSecirity, + selected: selected + }, + success: function( response ) { + + if( response.success === true ) { + + + + } + else { + + alert( response.message ); + logsDT.ajax.reload( null, false ); + + } + + } + } ); + + + } ); + + //MainWP | Lets do somthing on changing site + jQuery( document ).on( 'change', '.ps-mainwp-site-selector', function() { + + var siteID = this.value; + logsDT.ajax.url( `${ajaxurl}?action=ps-get-email-logs&security=${logsDTSecirity}&site_id=${siteID}` ).load(); + + } ); + + //If site already selected + jQuery( document ).on( 'click', '.ps-mainwp-site', function( e ) { + + e.preventDefault(); + var href = $(this).attr('href'); + + var siteID = PostSMTPGetParameterByName( 'site_id', href ); + + jQuery( `.ps-mainwp-site-selector option[value="${siteID}"]` ).prop( 'selected', true ) + + if( siteID != null && siteID != -1 ) { + + logsDT.ajax.url( `${ajaxurl}?action=ps-get-email-logs&security=${logsDTSecirity}&site_id=${siteID}` ).load(); + + } + + } ) + + + //Resend + jQuery( document ).on( 'click', '.ps-email-log-resend', function( e ) { + + e.preventDefault(); + var sendTo = jQuery( this ).closest( 'tr' ).find( 'td:nth-child(3)' ).attr('title'); + var currentRow = jQuery( this ).closest( 'tr' ); + + jQuery( currentRow ).find( '.ps-email-log-resend-container' ).html( ` +
            + + +

            For multiple recipients, separate them with a comma.

            +
            + ` ); + + } ); + + //Resend + jQuery( document ).on( 'click', '.ps-email-resend-btn', function( e ) { + + e.preventDefault(); + var id = jQuery( this ).closest( 'tr' ).find( '.ps-email-log-cb' ).val(); + var to = jQuery( this ).closest( 'tr' ).find( '.ps-email-log-resend-to' ).val(); + + jQuery.ajax( { + url: ajaxurl, + type: 'POST', + data: { + action: 'ps-resend-email', + security: logsDTSecirity, + id: id, + to: to + }, + success: function( response ) { + + if( response.success === true ) { + + alert( response.message ); + logsDT.ajax.reload( null, false ); + + } + else { + + alert( response.message ); + logsDT.ajax.reload( null, false ); + + } + + } + } ); + + + } ); + + + jQuery( document ).on( 'click', '.ps-status-log', function( e ) { + + e.preventDefault(); + var _details = jQuery( this ).siblings( 'span' ).attr( 'title' ); + jQuery( '.ps-popup-container' ).html( `

            ${_details}` ); + + } ); + +}) \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/script/postman-smtp-conflict-notice.js b/html/wp-content/plugins/post-smtp/script/postman-smtp-conflict-notice.js new file mode 100644 index 0000000..947d1b5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/script/postman-smtp-conflict-notice.js @@ -0,0 +1,48 @@ +/** + * Post SMTP Conflict Notice Dismissal Handler + */ +(function($) { + 'use strict'; + + $(document).ready(function() { + $(document).on('click', '.postman-smtp-conflict-notice .notice-dismiss', function(e) { + e.preventDefault(); + + var $notice = $(this).closest('.postman-smtp-conflict-notice'); + var noticeId = $notice.data('notice-id'); + + if (!noticeId) { + return; + } + + // Check if localized data is available + if (typeof postmanSmtpConflict === 'undefined' || !postmanSmtpConflict.nonce) { + console.error('Post SMTP Conflict Notice: Localized data not available'); + return; + } + + $.ajax({ + url: ajaxurl, + type: 'POST', + data: { + action: 'dismiss_smtp_conflict_notice', + nonce: postmanSmtpConflict.nonce, + notice_id: noticeId + }, + success: function(response) { + if (response.success) { + $notice.fadeOut('fast', function() { + $(this).remove(); + }); + } else { + console.error('Failed to dismiss notice:', response.data); + } + }, + error: function(xhr, status, error) { + console.error('AJAX error:', error); + } + }); + }); + }); +})(jQuery); + diff --git a/html/wp-content/plugins/post-smtp/script/postman.js b/html/wp-content/plugins/post-smtp/script/postman.js new file mode 100644 index 0000000..17f4e95 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/script/postman.js @@ -0,0 +1,333 @@ +jQuery(document).ready(function($) { + $( ".email-log-date" ).datepicker(); + + $('.post-smtp-reset-options').on('submit', function(e) { + var result = confirm('Are you sure?'); + + if ( ! result ) { + e.preventDefault(); + return false; + } + }); + + $('.notice-dismiss.postman-release-message').on('click', function() { + var $this = $(this); + var args = { + action: 'dismiss_version_notify', + security: $this.data('security'), + version: $this.data('version'), + }; + + $.post(ajaxurl, args, function() { + $this.parent().slideUp(); + }); + }); + + $('.post-smtp-donation .donation-dismiss').on('click', function() { + var $this = $(this); + var args = { + action: 'dismiss_donation_notify', + security: $this.data('security'), + }; + + $.post(ajaxurl, args, function() { + $this.parent().slideUp(); + }); + }); + + $('#postman_trash_all').on('click',function(e) { + e.preventDefault(); + + if (confirm("Are You Sure?") == false) { + return false; + } + + let security = $('#post-smtp-log-nonce').val(); + + $.post(ajaxurl, {action: 'post_smtp_log_trash_all', security: security}, function(result) { + if ( result.success ) { + location.reload(); + } else { + alert(result.data); + } + }, 'json'); + }); + + $('.release-lock-file').on('click', function(e) { + e.preventDefault(); + + var security = $(this).data('security'); + + $.post(ajaxurl, {action: 'delete_lock_file', security: security}, function(result) { + alert(result); + }); + + }); + + //Discard less secure notification + $( document ).on( 'click', '#discard-less-secure-notification', function( e ) { + e.preventDefault(); + + $.ajax( { + type: 'POST', + url: ajaxurl, + data: { + action: 'ps-discard-less-secure-notification', + _wp_nonce: postman_ajax.lessSecureNotice + }, + success: function(data) { + $( '.ps-less-secure-notice .notice-dismiss' ).click(); + } + } ) + + $( '.ps-less-secure-notice .notice-dismiss' ).click(); + } ) +}); + +var redirectUrlWarning = false; +if (!console) + console = { + log : function() { + } + } +function disable(identifier) { + var el = jQuery(identifier); + console.debug('disabling ' + identifier); + el.attr('disabled', 'disabled'); +} +function enable(identifier) { + var el = jQuery(identifier); + console.debug('enabling ' + identifier); + el.removeAttr('disabled'); +} +function hide(identifier) { + var el = jQuery(identifier); + console.debug('hiding ' + identifier); + el.hide("fast"); +} +function show(identifier) { + var el = jQuery(identifier); + console.debug('showing ' + identifier); + el.show("fast"); +} +function writeable(identifier) { + var el = jQuery(identifier); + el.prop("readonly", false); +} +function readonly(identifier) { + var el = jQuery(identifier); + el.prop("readonly", true); +} +function hideLoaderIcon() { + hide('.ajax-loader'); +} +function showLoaderIcon() { + show('.ajax-loader'); +} +function handleConfigurationResponse(response) { + response = response.data; + if (response.display_auth == 'oauth2') { + show('p#wizard_oauth2_help'); + jQuery('p#wizard_oauth2_help').html(response.help_text); + jQuery(post_smtp_localize.postman_redirect_url_el).val(response.redirect_url); + jQuery('#input_oauth_callback_domain').val(response.callback_domain); + jQuery('#client_id').html(response.client_id_label); + jQuery('#client_secret').html(response.client_secret_label); + jQuery('#redirect_url').html(response.redirect_url_label); + jQuery('#callback_domain').html(response.callback_domain_label); + } +} +// add an event on the authentication input field +// on user changing the auth type, determine whether to show +// password or oauth section +jQuery(document).ready(function() { + jQuery('a#show-diagnostics').click(function() { + show('#diagnostic-text'); + }); +}); + +// http://www.electrictoolbox.com/toggle-password-field-text-password/ +function setupPasswordToggle(passwordFieldId, togglePasswordFieldId) { + try { + /** + * switch the password field to text, then back to password to see if it + * supports changing the field type (IE9+, and all other browsers do). + * then switch it back. + */ + passwordField = document.getElementById(passwordFieldId); + for (var i = 0, len = passwordField.value.length; i < len; i++) { + if (passwordField.value[i] == '*') + return false; + } + passwordField.type = 'text'; + passwordField.type = 'password'; + + /** + * if it does support changing the field type then add the event handler + * and make the button visible. if the browser doesn't support it, then + * this is bypassed and code execution continues in the catch() section + * below + */ + togglePasswordField = document.getElementById(togglePasswordFieldId); + togglePasswordField.addEventListener('click', + togglePasswordFieldClicked, false); + togglePasswordField.style.visibility = 'visible'; + + return true; + } + + catch (err) { + return true; + } + +} + +function togglePasswordFieldClicked() { + + // var passwordField = document.getElementById('passwordField'); + var value = passwordField.value; + + if (passwordField.type == 'password') { + passwordField.type = 'text'; + togglePasswordField.disabled = true; + } else { + // nah, let's not toggle it back + // passwordField.type = 'password'; + } + passwordField.value = value; + +} + +// password toggle +showPassword = false; + +function enablePasswordDisplayOnEntry($el1, $el2) { + // http://stackoverflow.com/questions/1948332/detect-all-changes-to-a-input-type-text-immediately-using-jquery + console.debug('in enablePasswordDisplayEntryOn'); + jQuery('#' + $el1).each( + function() { + var elem = jQuery(this); + + // Save current value of element + elem.data('oldVal', elem.val()); + + // Look for changes in the value + elem.bind("propertychange change click keyup input paste", + function(event) { + + // If value has changed... + if (elem.data('oldVal') != elem.val()) { + // Updated stored value + elem.data('oldVal', elem.val()); + + if (!showPassword) + showPassword = setupPasswordToggle($el1, + $el2); + } + }); + }); + +} + +jQuery('body').ajaxStart(function() { + jQuery(this).css({ + 'cursor' : 'wait' + }); +}).ajaxStop(function() { + jQuery(this).css({ + 'cursor' : 'default' + }); +}); + +function ajaxFailed(response) { + if (response.responseText) { + alert(postman_ajax_msg.bad_response + " " + + JSON.stringify(response, null, 4)); + } +} + +// Production steps of ECMA-262, Edition 5, 15.4.4.18 +// Reference: http://es5.github.io/#x15.4.4.18 +if (!Array.prototype.forEach) { + + Array.prototype.forEach = function(callback, thisArg) { + + var T, k; + + if (this == null) { + throw new TypeError(' this is null or not defined'); + } + + // 1. Let O be the result of calling ToObject passing the |this| value + // as the argument. + var O = Object(this); + + // 2. Let lenValue be the result of calling the Get internal method of O + // with the argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + + // 4. If IsCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if (typeof callback !== "function") { + throw new TypeError(callback + ' is not a function'); + } + + // 5. If thisArg was supplied, let T be thisArg; else let T be + // undefined. + if (arguments.length > 1) { + T = thisArg; + } + + // 6. Let k be 0 + k = 0; + + // 7. Repeat, while k < len + while (k < len) { + + var kValue; + + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty internal + // method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if (k in O) { + + // i. Let kValue be the result of calling the Get internal + // method of O with argument Pk. + kValue = O[k]; + + // ii. Call the Call internal method of callback with T as the + // this value and + // argument list containing kValue, k, and O. + callback.call(T, kValue, k, O); + } + // d. Increase k by 1. + k++; + } + // 8. return undefined + }; +} +function postmanValidateAjaxResponse(response) { + if (response.data == undefined) { + // handle corrupt response + jQuery('#postman_test_message_status').html( + postman_email_test.ajax_error); + jQuery('#postman_test_message_status').css('color', 'red'); + jQuery('#postman_test_message_error_message').val( + postman_ajax_msg.corrupt_response + ":\n\n" + response); + jQuery('li + li').removeClass('disabled'); + return false; + } + return true; +} +function postmanValidateAjaxResponseWithPopup(response) { + if (response.data == undefined) { + alert(postman_ajax_msg.corrupt_response + ":\n\n" + + JSON.stringify(response, null, 4)); + return false; + } + return true; +} diff --git a/html/wp-content/plugins/post-smtp/script/postman_resend_email_sript.js b/html/wp-content/plugins/post-smtp/script/postman_resend_email_sript.js new file mode 100644 index 0000000..d41c2b0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/script/postman_resend_email_sript.js @@ -0,0 +1,43 @@ +jQuery(document).ready(function($) { + $('.postman-open-resend').on('click', function(e) { + e.preventDefault(); + + $(this).parent().next('div').fadeToggle(); + }); + + $('.postman-resend').on('click', function(e) { + e.preventDefault(); + + var parent = $(this).closest('div'), + mailField = $(this).prev('input'), + emailId = mailField.data('id'), + mail_to = mailField.val(), + security = parent.find('input[name="security"]').val(); + + + postman_resend_email(emailId, mail_to, security); + + }); + + function postman_resend_email(emailId, mail_to, security ) { + var data = { + 'action' : 'postman_resend_mail', + 'email' : emailId, + 'mail_to' : mail_to, + 'security' : security + }; + + jQuery.post(ajaxurl, data, function(response) { + if (response.success) { + alert(response.data.message); + // jQuery('span#resend-' + emailId).text(post_smtp_localize.postman_js_resend_label); + } else { + alert(sprintf(post_smtp_localize.postman_js_email_not_resent, response.data.message)); + } + }).fail(function(response) { + ajaxFailed(response); + }); + } + +}) + diff --git a/html/wp-content/plugins/post-smtp/script/sprintf/sprintf.min.js b/html/wp-content/plugins/post-smtp/script/sprintf/sprintf.min.js new file mode 100644 index 0000000..d5bcd09 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/script/sprintf/sprintf.min.js @@ -0,0 +1,4 @@ +/*! sprintf-js | Alexandru Marasteanu (http://alexei.ro/) | BSD-3-Clause */ + +!function(a){function b(){var a=arguments[0],c=b.cache;return c[a]&&c.hasOwnProperty(a)||(c[a]=b.parse(a)),b.format.call(null,c[a],arguments)}function c(a){return Object.prototype.toString.call(a).slice(8,-1).toLowerCase()}function d(a,b){return Array(b+1).join(a)}var e={not_string:/[^s]/,number:/[dief]/,text:/^[^\x25]+/,modulo:/^\x25{2}/,placeholder:/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fiosuxX])/,key:/^([a-z_][a-z_\d]*)/i,key_access:/^\.([a-z_][a-z_\d]*)/i,index_access:/^\[(\d+)\]/,sign:/^[\+\-]/};b.format=function(a,f){var g,h,i,j,k,l,m,n=1,o=a.length,p="",q=[],r=!0,s="";for(h=0;o>h;h++)if(p=c(a[h]),"string"===p)q[q.length]=a[h];else if("array"===p){if(j=a[h],j[2])for(g=f[n],i=0;i=0),j[8]){case"b":g=g.toString(2);break;case"c":g=String.fromCharCode(g);break;case"d":case"i":g=parseInt(g,10);break;case"e":g=j[7]?g.toExponential(j[7]):g.toExponential();break;case"f":g=j[7]?parseFloat(g).toFixed(j[7]):parseFloat(g);break;case"o":g=g.toString(8);break;case"s":g=(g=String(g))&&j[7]?g.substring(0,j[7]):g;break;case"u":g>>>=0;break;case"x":g=g.toString(16);break;case"X":g=g.toString(16).toUpperCase()}!e.number.test(j[8])||r&&!j[3]?s="":(s=r?"+":"-",g=g.toString().replace(e.sign,"")),l=j[4]?"0"===j[4]?"0":j[4].charAt(1):" ",m=j[6]-(s+g).length,k=j[6]&&m>0?d(l,m):"",q[q.length]=j[5]?s+g+k:"0"===l?s+k+g:k+s+g}return q.join("")},b.cache={},b.parse=function(a){for(var b=a,c=[],d=[],f=0;b;){if(null!==(c=e.text.exec(b)))d[d.length]=c[0];else if(null!==(c=e.modulo.exec(b)))d[d.length]="%";else{if(null===(c=e.placeholder.exec(b)))throw new SyntaxError("[sprintf] unexpected placeholder");if(c[2]){f|=1;var g=[],h=c[2],i=[];if(null===(i=e.key.exec(h)))throw new SyntaxError("[sprintf] failed to parse named argument key");for(g[g.length]=i[1];""!==(h=h.substring(i[0].length));)if(null!==(i=e.key_access.exec(h)))g[g.length]=i[1];else{if(null===(i=e.index_access.exec(h)))throw new SyntaxError("[sprintf] failed to parse named argument key");g[g.length]=i[1]}c[2]=g}else f|=2;if(3===f)throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported");d[d.length]=c}b=b.substring(c[0].length)}return d};var f=function(a,c,d){return d=(c||[]).slice(0),d.splice(0,0,a),b.apply(null,d)};"undefined"!=typeof exports?(exports.sprintf=b,exports.vsprintf=f):(a.sprintf=b,a.vsprintf=f,"function"==typeof define&&define.amd&&define(function(){return{sprintf:b,vsprintf:f}}))}("undefined"==typeof window?this:window); +//# sourceMappingURL=sprintf.min.map \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/script/sprintf/sprintf.min.map b/html/wp-content/plugins/post-smtp/script/sprintf/sprintf.min.map new file mode 100644 index 0000000..33fe163 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/script/sprintf/sprintf.min.map @@ -0,0 +1 @@ +{"version":3,"file":"sprintf.min.js","sources":["../src/sprintf.js"],"names":["window","sprintf","key","arguments","cache","hasOwnProperty","parse","format","call","get_type","variable","Object","prototype","toString","slice","toLowerCase","str_repeat","input","multiplier","Array","join","re","not_string","number","text","modulo","placeholder","key_access","index_access","sign","parse_tree","argv","arg","i","k","match","pad","pad_character","pad_length","cursor","tree_length","length","node_type","output","is_positive","Error","test","isNaN","TypeError","String","fromCharCode","parseInt","toExponential","parseFloat","toFixed","substring","toUpperCase","replace","charAt","fmt","_fmt","arg_names","exec","SyntaxError","field_list","replacement_field","field_match","vsprintf","_argv","splice","apply","exports","define","amd","this"],"mappings":";;CAAA,SAAUA,GAaN,QAASC,KACL,GAAIC,GAAMC,UAAU,GAAIC,EAAQH,EAAQG,KAIxC,OAHMA,GAAMF,IAAQE,EAAMC,eAAeH,KACrCE,EAAMF,GAAOD,EAAQK,MAAMJ,IAExBD,EAAQM,OAAOC,KAAK,KAAMJ,EAAMF,GAAMC,WAoJjD,QAASM,GAASC,GACd,MAAOC,QAAOC,UAAUC,SAASL,KAAKE,GAAUI,MAAM,EAAG,IAAIC,cAGjE,QAASC,GAAWC,EAAOC,GACvB,MAAOC,OAAMD,EAAa,GAAGE,KAAKH,GA1KtC,GAAII,IACAC,WAAY,OACZC,OAAQ,SACRC,KAAM,YACNC,OAAQ,WACRC,YAAa,wFACbxB,IAAK,sBACLyB,WAAY,wBACZC,aAAc,aACdC,KAAM,UAWV5B,GAAQM,OAAS,SAASuB,EAAYC,GAClC,GAAiEC,GAAkBC,EAAGC,EAAGC,EAAOC,EAAKC,EAAeC,EAAhHC,EAAS,EAAGC,EAAcV,EAAWW,OAAQC,EAAY,GAASC,KAA0DC,GAAc,EAAMf,EAAO,EAC3J,KAAKI,EAAI,EAAOO,EAAJP,EAAiBA,IAEzB,GADAS,EAAYjC,EAASqB,EAAWG,IACd,WAAdS,EACAC,EAAOA,EAAOF,QAAUX,EAAWG,OAElC,IAAkB,UAAdS,EAAuB,CAE5B,GADAP,EAAQL,EAAWG,GACfE,EAAM,GAEN,IADAH,EAAMD,EAAKQ,GACNL,EAAI,EAAGA,EAAIC,EAAM,GAAGM,OAAQP,IAAK,CAClC,IAAKF,EAAI3B,eAAe8B,EAAM,GAAGD,IAC7B,KAAM,IAAIW,OAAM5C,EAAQ,yCAA0CkC,EAAM,GAAGD,IAE/EF,GAAMA,EAAIG,EAAM,GAAGD,QAIvBF,GADKG,EAAM,GACLJ,EAAKI,EAAM,IAGXJ,EAAKQ,IAOf,IAJqB,YAAjB9B,EAASuB,KACTA,EAAMA,KAGNX,EAAGC,WAAWwB,KAAKX,EAAM,KAAyB,UAAjB1B,EAASuB,IAAoBe,MAAMf,GACpE,KAAM,IAAIgB,WAAU/C,EAAQ,0CAA2CQ,EAASuB,IAOpF,QAJIX,EAAGE,OAAOuB,KAAKX,EAAM,MACrBS,EAAcZ,GAAO,GAGjBG,EAAM,IACV,IAAK,IACDH,EAAMA,EAAInB,SAAS,EACvB,MACA,KAAK,IACDmB,EAAMiB,OAAOC,aAAalB,EAC9B,MACA,KAAK,IACL,IAAK,IACDA,EAAMmB,SAASnB,EAAK,GACxB,MACA,KAAK,IACDA,EAAMG,EAAM,GAAKH,EAAIoB,cAAcjB,EAAM,IAAMH,EAAIoB,eACvD,MACA,KAAK,IACDpB,EAAMG,EAAM,GAAKkB,WAAWrB,GAAKsB,QAAQnB,EAAM,IAAMkB,WAAWrB,EACpE,MACA,KAAK,IACDA,EAAMA,EAAInB,SAAS,EACvB,MACA,KAAK,IACDmB,GAAQA,EAAMiB,OAAOjB,KAASG,EAAM,GAAKH,EAAIuB,UAAU,EAAGpB,EAAM,IAAMH,CAC1E,MACA,KAAK,IACDA,KAAc,CAClB,MACA,KAAK,IACDA,EAAMA,EAAInB,SAAS,GACvB,MACA,KAAK,IACDmB,EAAMA,EAAInB,SAAS,IAAI2C,eAG3BnC,EAAGE,OAAOuB,KAAKX,EAAM,KAASS,IAAeT,EAAM,GAKnDN,EAAO,IAJPA,EAAOe,EAAc,IAAM,IAC3BZ,EAAMA,EAAInB,WAAW4C,QAAQpC,EAAGQ,KAAM,KAK1CQ,EAAgBF,EAAM,GAAkB,MAAbA,EAAM,GAAa,IAAMA,EAAM,GAAGuB,OAAO,GAAK,IACzEpB,EAAaH,EAAM,IAAMN,EAAOG,GAAKS,OACrCL,EAAMD,EAAM,IAAMG,EAAa,EAAItB,EAAWqB,EAAeC,GAAoB,GACjFK,EAAOA,EAAOF,QAAUN,EAAM,GAAKN,EAAOG,EAAMI,EAAyB,MAAlBC,EAAwBR,EAAOO,EAAMJ,EAAMI,EAAMP,EAAOG,EAGvH,MAAOW,GAAOvB,KAAK,KAGvBnB,EAAQG,SAERH,EAAQK,MAAQ,SAASqD,GAErB,IADA,GAAIC,GAAOD,EAAKxB,KAAYL,KAAiB+B,EAAY,EAClDD,GAAM,CACT,GAAqC,QAAhCzB,EAAQd,EAAGG,KAAKsC,KAAKF,IACtB9B,EAAWA,EAAWW,QAAUN,EAAM,OAErC,IAAuC,QAAlCA,EAAQd,EAAGI,OAAOqC,KAAKF,IAC7B9B,EAAWA,EAAWW,QAAU,QAE/B,CAAA,GAA4C,QAAvCN,EAAQd,EAAGK,YAAYoC,KAAKF,IAgClC,KAAM,IAAIG,aAAY,mCA/BtB,IAAI5B,EAAM,GAAI,CACV0B,GAAa,CACb,IAAIG,MAAiBC,EAAoB9B,EAAM,GAAI+B,IACnD,IAAuD,QAAlDA,EAAc7C,EAAGnB,IAAI4D,KAAKG,IAe3B,KAAM,IAAIF,aAAY,+CAbtB,KADAC,EAAWA,EAAWvB,QAAUyB,EAAY,GACwC,MAA5ED,EAAoBA,EAAkBV,UAAUW,EAAY,GAAGzB,UACnE,GAA8D,QAAzDyB,EAAc7C,EAAGM,WAAWmC,KAAKG,IAClCD,EAAWA,EAAWvB,QAAUyB,EAAY,OAE3C,CAAA,GAAgE,QAA3DA,EAAc7C,EAAGO,aAAakC,KAAKG,IAIzC,KAAM,IAAIF,aAAY,+CAHtBC,GAAWA,EAAWvB,QAAUyB,EAAY,GAUxD/B,EAAM,GAAK6B,MAGXH,IAAa,CAEjB,IAAkB,IAAdA,EACA,KAAM,IAAIhB,OAAM,4EAEpBf,GAAWA,EAAWW,QAAUN,EAKpCyB,EAAOA,EAAKL,UAAUpB,EAAM,GAAGM,QAEnC,MAAOX,GAGX,IAAIqC,GAAW,SAASR,EAAK5B,EAAMqC,GAG/B,MAFAA,IAASrC,OAAYjB,MAAM,GAC3BsD,EAAMC,OAAO,EAAG,EAAGV,GACZ1D,EAAQqE,MAAM,KAAMF,GAiBR,oBAAZG,UACPA,QAAQtE,QAAUA,EAClBsE,QAAQJ,SAAWA,IAGnBnE,EAAOC,QAAUA,EACjBD,EAAOmE,SAAWA,EAEI,kBAAXK,SAAyBA,OAAOC,KACvCD,OAAO,WACH,OACIvE,QAASA,EACTkE,SAAUA,OAKT,mBAAXnE,QAAyB0E,KAAO1E"} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/style/ajax-loader.gif b/html/wp-content/plugins/post-smtp/style/ajax-loader.gif new file mode 100644 index 0000000..b600571 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/style/ajax-loader.gif differ diff --git a/html/wp-content/plugins/post-smtp/style/feeds.css b/html/wp-content/plugins/post-smtp/style/feeds.css new file mode 100644 index 0000000..ed93c8c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/style/feeds.css @@ -0,0 +1,93 @@ +#post_smtp_feeds_widget.postbox .inside { + padding: 0; +} + +#post-smtp-dashboard-overview .dashicons { + vertical-align: middle; + font-size: 17px; } + +#post-smtp-dashboard-overview .e-overview__header { + display: table; + width: 100%; + -webkit-box-shadow: 0 5px 8px rgba(0, 0, 0, 0.05); + box-shadow: 0 5px 8px rgba(0, 0, 0, 0.05); + margin: 0 -12px 8px; + padding: 0 12px 12px; } + +#post-smtp-dashboard-overview .e-overview__logo, #post-smtp-dashboard-overview .e-overview__versions, #post-smtp-dashboard-overview .e-overview__create { + display: table-cell; + vertical-align: middle; } + +#post-smtp-dashboard-overview .e-overview__logo { + width: 30px; } + +#post-smtp-dashboard-overview .e-overview__versions { + padding: 0 10px; + font-size: 0.9em; + line-height: 1.5; } + +#post-smtp-dashboard-overview .e-overview__version { + display: block; } + +#post-smtp-dashboard-overview .e-overview__create { + text-align: right; } + +#post-smtp-dashboard-overview .e-overview__post { + margin-top: 10px; } + +#post-smtp-dashboard-overview .e-overview__post-link { + display: inline-block; } + +#post-smtp-dashboard-overview .e-overview__badge { + background: #39b54a; + color: white; + font-size: 0.75em; + padding: 3px 6px; + -webkit-border-radius: 3px; + border-radius: 3px; + text-transform: uppercase; } + +#post-smtp-dashboard-overview ul li { + padding: 5px 10px; +} + +#post-smtp-dashboard-overview ul li:nth-child(even) { + background-color: #FAFAFA; +} + +#post-smtp-dashboard-overview .e-overview__post-description { + margin: 0 0 1.5em; } + +#post-smtp-dashboard-overview .e-overview__recently-edited li { + color: #72777c; } + +#post-smtp-dashboard-overview .e-overview__feed { + font-size: 14px; + font-weight: 500; } +#post-smtp-dashboard-overview .e-overview__feed .e-overview__post-link { + padding-bottom: 5px; } + +#post-smtp-dashboard-overview .e-overview__recently-edited .e-overview__heading, #post-smtp-dashboard-overview .e-overview__feed .e-overview__heading { + font-weight: 700; + border-bottom: 1px solid #eee; + margin: 0 -12px; + padding: 6px 12px; } + +#post-smtp-dashboard-overview .e-overview__footer { + margin: 0 -12px -12px; + padding: 12px; + border-top: 1px solid #eee; } +#post-smtp-dashboard-overview .e-overview__footer ul { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + list-style: none; + margin: 0; + padding: 0; } +#post-smtp-dashboard-overview .e-overview__footer ul li { + padding: 0 10px; + margin: 0; + border-left: 1px solid #ddd; } +#post-smtp-dashboard-overview .e-overview__footer ul li:first-child { + padding-left: 0; + border: none; } diff --git a/html/wp-content/plugins/post-smtp/style/images/badge.png b/html/wp-content/plugins/post-smtp/style/images/badge.png new file mode 100644 index 0000000..8f5281b Binary files /dev/null and b/html/wp-content/plugins/post-smtp/style/images/badge.png differ diff --git a/html/wp-content/plugins/post-smtp/style/images/filter-preview.gif b/html/wp-content/plugins/post-smtp/style/images/filter-preview.gif new file mode 100644 index 0000000..d269183 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/style/images/filter-preview.gif differ diff --git a/html/wp-content/plugins/post-smtp/style/images/gmail-once-click.gif b/html/wp-content/plugins/post-smtp/style/images/gmail-once-click.gif new file mode 100644 index 0000000..7b7f01c Binary files /dev/null and b/html/wp-content/plugins/post-smtp/style/images/gmail-once-click.gif differ diff --git a/html/wp-content/plugins/post-smtp/style/images/new.gif b/html/wp-content/plugins/post-smtp/style/images/new.gif new file mode 100644 index 0000000..3470f28 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/style/images/new.gif differ diff --git a/html/wp-content/plugins/post-smtp/style/images/resend-preview.gif b/html/wp-content/plugins/post-smtp/style/images/resend-preview.gif new file mode 100644 index 0000000..0022607 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/style/images/resend-preview.gif differ diff --git a/html/wp-content/plugins/post-smtp/style/jquery-steps/jquery-ui.css b/html/wp-content/plugins/post-smtp/style/jquery-steps/jquery-ui.css new file mode 100644 index 0000000..53b290a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/style/jquery-steps/jquery-ui.css @@ -0,0 +1,1175 @@ +/*! jQuery UI - v1.10.3 - 2013-05-03 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:Alpha(Opacity=0); +} + +.ui-front { + z-index: 100; +} + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; +} + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin-top: 2px; + padding: .5em .5em .5em .7em; + min-height: 0; /* support: IE7 */ +} +.ui-accordion .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-noicons { + padding-left: .7em; +} +.ui-accordion .ui-accordion-icons .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { + position: absolute; + left: .5em; + top: 50%; + margin-top: -8px; +} +.ui-accordion .ui-accordion-content { + padding: 1em 2.2em; + border-top: 0; + overflow: auto; +} +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: default; +} +.ui-button { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + margin-right: .1em; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ +} +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 2.2em; +} +/* button elements seem to need a little more width */ +button.ui-button-icon-only { + width: 2.4em; +} +.ui-button-icons-only { + width: 3.4em; +} +button.ui-button-icons-only { + width: 3.7em; +} + +/* button text element */ +.ui-button .ui-button-text { + display: block; + line-height: normal; +} +.ui-button-text-only .ui-button-text { + padding: .4em 1em; +} +.ui-button-icon-only .ui-button-text, +.ui-button-icons-only .ui-button-text { + padding: .4em; + text-indent: -9999999px; +} +.ui-button-text-icon-primary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 1em .4em 2.1em; +} +.ui-button-text-icon-secondary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 2.1em .4em 1em; +} +.ui-button-text-icons .ui-button-text { + padding-left: 2.1em; + padding-right: 2.1em; +} +/* no icon support for input elements, provide padding by default */ +input.ui-button { + padding: .4em 1em; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon, +.ui-button-text-icon-primary .ui-icon, +.ui-button-text-icon-secondary .ui-icon, +.ui-button-text-icons .ui-icon, +.ui-button-icons-only .ui-icon { + position: absolute; + top: 50%; + margin-top: -8px; +} +.ui-button-icon-only .ui-icon { + left: 50%; + margin-left: -8px; +} +.ui-button-text-icon-primary .ui-button-icon-primary, +.ui-button-text-icons .ui-button-icon-primary, +.ui-button-icons-only .ui-button-icon-primary { + left: .5em; +} +.ui-button-text-icon-secondary .ui-button-icon-secondary, +.ui-button-text-icons .ui-button-icon-secondary, +.ui-button-icons-only .ui-button-icon-secondary { + right: .5em; +} + +/* button sets */ +.ui-buttonset { + margin-right: 7px; +} +.ui-buttonset .ui-button { + margin-left: 0; + margin-right: -.3em; +} + +/* workarounds */ +/* reset extra padding in Firefox, see h5bp.com/l */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 1px; +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 1px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-datepicker select.ui-datepicker-month-year { + width: 100%; +} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 49%; +} +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: .2em; + outline: 0; +} +.ui-dialog .ui-dialog-titlebar { + padding: .4em 1em; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: .1em 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 21px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: .5em 1em; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + margin-top: .5em; + padding: .3em 1em .5em .4em; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: .5em .4em .5em 0; + cursor: pointer; +} +.ui-dialog .ui-resizable-se { + width: 12px; + height: 12px; + right: -5px; + bottom: -5px; + background-position: 16px 16px; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} +.ui-menu { + list-style: none; + padding: 2px; + margin: 0; + display: block; + outline: none; +} +.ui-menu .ui-menu { + margin-top: -3px; + position: absolute; +} +.ui-menu .ui-menu-item { + margin: 0; + padding: 0; + width: 100%; + /* support: IE10, see #8844 */ + list-style-image: none; +} +.ui-menu .ui-menu-divider { + margin: 5px -2px 5px -2px; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; +} +.ui-menu .ui-menu-item a { + text-decoration: none; + display: block; + padding: 2px .4em; + line-height: 1.5; + min-height: 0; /* support: IE7 */ + font-weight: normal; +} +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} + +.ui-menu .ui-state-disabled { + font-weight: normal; + margin: .4em 0 .2em; + line-height: 1.5; +} +.ui-menu .ui-state-disabled a { + cursor: default; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item a { + position: relative; + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: .2em; + left: .2em; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + position: static; + float: right; +} +.ui-progressbar { + height: 2em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + background: none; + height: 100%; + filter: alpha(opacity=25); + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} +.ui-slider { + position: relative; + text-align: left; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + cursor: default; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} + +/* For IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: .8em; +} +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: .8em; + height: 100px; +} +.ui-slider-vertical .ui-slider-handle { + left: -.3em; + margin-left: 0; + margin-bottom: -.6em; +} +.ui-slider-vertical .ui-slider-range { + left: 0; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} +.ui-spinner { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; +} +.ui-spinner-input { + border: none; + background: none; + color: inherit; + padding: 0; + margin: .2em 0; + vertical-align: middle; + margin-left: .4em; + margin-right: 22px; +} +.ui-spinner-button { + width: 16px; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to overide default borders */ +.ui-spinner a.ui-spinner-button { + border-top: none; + border-bottom: none; + border-right: none; +} +/* vertical centre icon */ +.ui-spinner .ui-icon { + position: absolute; + margin-top: -8px; + top: 50%; + left: 0; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position: -65px -16px; +} +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ + padding: .2em; +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav li a { + float: left; + padding: .5em 1em; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, +.ui-tabs .ui-tabs-nav li.ui-state-disabled a, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading a { + cursor: text; +} +.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none; +} +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +body .ui-tooltip { + border-width: 2px; +} + +/* Component containers +----------------------------------*/ +.ui-widget { + font-size: 1.1em; +} +.ui-widget .ui-widget { + font-size: 1em; +} +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-size: 1em; +} +.ui-widget-content { + border: none; + background-color: #eee; + color: #222222; +} +.ui-widget-content a { + color: #222222; +} +.ui-widget-header { + border-bottom: 1px solid #ccc; + background-color: white; + color: #222222; + font-weight: bold; +} +.ui-widget-header a { + color: #222222; +} + +/* Interaction states +----------------------------------*/ +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default { + border: 1px solid #d3d3d3; + background-color: #9dc8e2; + font-weight: normal; + color: white; +} +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited { + color: white; + text-decoration: none; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus { + border: 1px solid #999999; + background-color: 9dc8e2; + font-weight: normal; + color: white; +} +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited { + color: white; + text-decoration: none; +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active { + border: 1px solid #aaaaaa; + background-color: #2184be; + font-weight: normal; + color: white; +} +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + color: white; + text-decoration: none; +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #fcefa1; + background-color: #fbf9ee; + color: #363636; +} +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a { + color: #363636; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #cd0a0a; + background-color: #fef1ec; + color: #cd0a0a; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a { + color: #cd0a0a; +} +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #cd0a0a; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .7; + filter:Alpha(Opacity=70); + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .35; + filter:Alpha(Opacity=35); + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:Alpha(Opacity=35); /* For IE8 - See #6059 */ +} + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + width: 16px; + height: 16px; +} +.ui-icon, +.ui-widget-content .ui-icon { + background-image: none; +} +.ui-widget-header .ui-icon { + background-image: none; +} +.ui-state-default .ui-icon { + background-image: none; +} +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon { + background-image: none; +} +.ui-state-active .ui-icon { + background-image: none; +} +.ui-state-highlight .ui-icon { + background-image: none; +} +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon { + background-image: none; +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl { + border-top-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr { + border-top-right-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl { + border-bottom-left-radius: 4px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br { + border-bottom-right-radius: 4px; +} + +/* Overlays */ +.ui-widget-overlay { + background-color: #aaaaaa; + opacity: .3; + filter: Alpha(Opacity=30); +} +.ui-widget-shadow { + margin: -8px 0 0 -8px; + padding: 8px; + background-color: #aaaaaa; + opacity: .3; + filter: Alpha(Opacity=30); + border-radius: 8px; +} diff --git a/html/wp-content/plugins/post-smtp/style/jquery-steps/jquery.steps.css b/html/wp-content/plugins/post-smtp/style/jquery-steps/jquery.steps.css new file mode 100644 index 0000000..ac157c7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/style/jquery-steps/jquery.steps.css @@ -0,0 +1,381 @@ +/* + Common +*/ + +.wizard, +.tabcontrol +{ + display: block; + width: 100%; + overflow: hidden; +} + +.wizard a, +.tabcontrol a +{ + outline: 0; +} + +.wizard ul, +.tabcontrol ul +{ + list-style: none !important; + padding: 0; + margin: 0; +} + +.wizard ul > li, +.tabcontrol ul > li +{ + display: block; + padding: 0; +} + +/* Accessibility */ +.wizard > .steps .current-info, +.tabcontrol > .steps .current-info +{ + position: absolute; + left: -999em; +} + +.wizard > .content > .title, +.tabcontrol > .content > .title +{ + position: absolute; + left: -999em; +} + + + +/* + Wizard +*/ + +.wizard > .steps +{ + position: relative; + display: block; + width: 100%; +} + +.wizard.vertical > .steps +{ + display: inline; + float: left; + width: 30%; +} + +.wizard > .steps .number +{ + font-size: 1.429em; +} + +.wizard > .steps > ul > li +{ + width: 25%; +} + +.wizard > .steps > ul > li, +.wizard > .actions > ul > li +{ + float: left; +} + +.wizard.vertical > .steps > ul > li +{ + float: none; + width: 100%; +} + +.wizard > .steps a, +.wizard > .steps a:hover, +.wizard > .steps a:active +{ + display: block; + width: auto; + margin: 0 0.5em 0.5em; + padding: 1em 1em; + text-decoration: none; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.wizard > .steps .disabled a, +.wizard > .steps .disabled a:hover, +.wizard > .steps .disabled a:active +{ + background: #eee; + color: #aaa; + cursor: default; +} + +.wizard > .steps .current a, +.wizard > .steps .current a:hover, +.wizard > .steps .current a:active +{ + background: #2184be; + color: #fff; + cursor: default; +} + +.wizard > .steps .done a, +.wizard > .steps .done a:hover, +.wizard > .steps .done a:active +{ + background: #9dc8e2; + color: #fff; +} + +.wizard > .steps .error a, +.wizard > .steps .error a:hover, +.wizard > .steps .error a:active +{ + background: #ff3111; + color: #fff; +} + +.wizard > .content +{ + background: #eee; + display: block; + margin: 0.5em; + min-height: 26em; + overflow: hidden; + position: relative; + width: auto; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.wizard.vertical > .content +{ + display: inline; + float: left; + margin: 0 2.5% 0.5em 2.5%; + width: 65%; +} + +.wizard > .content > .body +{ + float: left; + width: 95%; + height: 95%; + padding: 2.5%; +} + +.wizard > .content > .body ul +{ + list-style: disc !important; +} + +.wizard > .content > .body ul > li +{ + display: list-item; +} + +.wizard > .content > .body > iframe +{ + border: 0 none; + width: 100%; + height: 100%; +} + +.wizard > .content > .body input +{ + display: block; + border: 1px solid #ccc; +} + +.wizard > .content > .body input[type="checkbox"] +{ + display: inline-block; +} + +.wizard > .content > .body input.error +{ + background: rgb(251, 227, 228); + border: 1px solid #fbc2c4; + color: #8a1f11; +} + +.wizard > .content > .body label +{ + display: inline-block; + margin-bottom: 0.5em; +} + +.wizard > .content > .body label.error +{ + color: #8a1f11; + display: inline-block; + margin-left: 1.5em; +} + +.wizard > .actions +{ + position: relative; + display: block; + text-align: right; + width: 100%; +} + +.wizard.vertical > .actions +{ + display: inline; + float: right; + margin: 0 2.5%; + width: 95%; +} + +.wizard > .actions > ul +{ + display: inline-block; + text-align: right; +} + +.wizard > .actions > ul > li +{ + margin: 0 0.5em; +} + +.wizard.vertical > .actions > ul > li +{ + margin: 0 0 0 1em; +} + +.wizard > .actions a, +.wizard > .actions a:hover, +.wizard > .actions a:active +{ + background: #2184be; + color: #fff; + display: block; + padding: 0.5em 1em; + text-decoration: none; + + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.wizard > .actions .disabled a, +.wizard > .actions .disabled a:hover, +.wizard > .actions .disabled a:active +{ + background: #eee; + color: #aaa; +} + +.wizard > .loading +{ +} + +.wizard > .loading .spinner +{ +} + + + +/* + Tabcontrol +*/ + +.tabcontrol > .steps +{ + position: relative; + display: block; + width: 100%; +} + +.tabcontrol > .steps > ul +{ + position: relative; + margin: 6px 0 0 0; + top: 1px; + z-index: 1; +} + +.tabcontrol > .steps > ul > li +{ + float: left; + margin: 5px 2px 0 0; + padding: 1px; + + -webkit-border-top-left-radius: 5px; + -webkit-border-top-right-radius: 5px; + -moz-border-radius-topleft: 5px; + -moz-border-radius-topright: 5px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.tabcontrol > .steps > ul > li:hover +{ + background: #edecec; + border: 1px solid #bbb; + padding: 0; +} + +.tabcontrol > .steps > ul > li.current +{ + background: #fff; + border: 1px solid #bbb; + border-bottom: 0 none; + padding: 0 0 1px 0; + margin-top: 0; +} + +.tabcontrol > .steps > ul > li > a +{ + color: #5f5f5f; + display: inline-block; + border: 0 none; + margin: 0; + padding: 10px 30px; + text-decoration: none; +} + +.tabcontrol > .steps > ul > li > a:hover +{ + text-decoration: none; +} + +.tabcontrol > .steps > ul > li.current > a +{ + padding: 15px 30px 10px 30px; +} + +.tabcontrol > .content +{ + position: relative; + display: inline-block; + width: 100%; + height: 35em; + overflow: hidden; + border-top: 1px solid #bbb; + padding-top: 20px; +} + +.tabcontrol > .content > .body +{ + float: left; + position: absolute; + width: 95%; + height: 95%; + padding: 2.5%; +} + +.tabcontrol > .content > .body ul +{ + list-style: disc !important; +} + +.tabcontrol > .content > .body ul > li +{ + display: list-item; +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/style/postman.css b/html/wp-content/plugins/post-smtp/style/postman.css new file mode 100644 index 0000000..5b39ec5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/style/postman.css @@ -0,0 +1,1744 @@ +@CHARSET "UTF-8"; + +/* Opt-in popup Styling Starts */ + +.toplevel_page_postman #fs_connect .fs-actions .button.button-primary { + background-color: #66AF3A; + border: #66AF3A; + font-weight: bold; + width: 240px; +} + +.toplevel_page_postman #fs_connect .fs-terms, +.toplevel_page_postman #fs_connect .fs-actions, +.toplevel_page_postman #fs_connect .fs-visual { + background: #fff; +} + +.toplevel_page_postman #fs_connect { + box-shadow: 1px 5px 10px #b5b598; +} + +.ps-optin-popup h1 { + color: #3A5EAF; + font-weight: bold; +} + +.toplevel_page_postman .fs-site-icon, +.toplevel_page_postman .fs-first, +.toplevel_page_postman .fs-second, +.toplevel_page_postman .fs-connect-logo { + display: none; +} + +.toplevel_page_postman .fs-plugin-icon { + border: none!important; +} + +.toplevel_page_postman #skip_activation { + background: #fff; + border: none; + font-size: 15px!important; + color: #999; +} + +.toplevel_page_postman .fs-visual { + float: left; + vertical-align: middle; +} + +.toplevel_page_postman .ps-optin-popup { + float: left; + width: 315px; +} + +.toplevel_page_postman #fs_connect .fs-visual .fs-plugin-icon { + position: unset; + top: 0px; + left: unset; + margin-left: 0px; + padding: 15px 10px; + text-align: center; +} + +.toplevel_page_postman #fs_connect .fs-visual { + padding: 12px; + line-height: 0; + background: #fff; + height: 0px; + position: unset; +} + +.toplevel_page_postman #fs_connect .fs-actions { + padding: 15px 40px; +} + +.toplevel_page_postman #fs_connect .fs-actions .button.button-secondary { + float: right; + width: 145px; +} + + +/* Opt-in popup Styling Ends */ + +/* Post SMTP Global Classes Starts */ + +body.admin_page_postman-configuration_wizard, +body.admin_page_postman-manage-options, +body.admin_page_postman-configuration, +body.toplevel_page_postman, +body.post-smtp_page_postman_email_log { + background-color: #fff; +} + +.ps-home-main a { + font-size: 16px; +} + +.ps-main-header.post-smtp-welcome-panel h2 { + padding: 0px 15px; + font-size: 19px; +} + +.ps-config-bar { + margin-bottom: 25px; + border: 1px solid #e6e6e6; + padding: 25px; + font-size: 18px; + font-weight: bold; + line-height: 30px; +} + +.ps-config-bar span { + vertical-align: middle; +} + +.ps-config-bar a { + margin-left: 15px!important; +} + +.ps-left { + float: left; +} + +.ps-right { + float: right; +} + +.ps-socket-wizad-row { + display: inline-flex; + margin: 20px 0; +} + +.ps-single-socket-outer { + border: 1px solid #e4e4e6; + background: #f9f9f9; + text-align: center; + padding: 5px 10px; + margin: 0 7px; + border-radius: 13px; + min-height: 106px; + max-width: 187px; +} + +.ps-socket-wizad-row input { + display: inline-block!important; + margin-left: 15px; +} + +.ps-socket-wizad-row label { + font-size: 12px; +} + +.ps-container-90 { + width: 90%; + margin: 0 auto; +} + +.ps-textarea { + border: 2px solid #e4e4e6; + border-radius: 12px; + scroll-behavior: auto; + background: #fff!important; + padding: 13px; + color: #7e7e7e; + width: 100%; +} + +.ps-btn-orange { + background: #faaa39!important; + color: #FFF!important; + text-decoration: none; + border-radius: 7px!important; + border: none!important; + padding: 6px 8px; + position: relative; + line-height: normal; +} + +.ps-btn-red { + background: #ef090b!important; + color: #FFF!important; + text-decoration: none; + border-radius: 7px!important; + border: none!important; + padding: 6px 8px; + position: relative; + line-height: normal; +} + +.ps-btn-light-blue { + background: #1d9ad2! important; + color: #FFF!important; + text-decoration: none; + border-radius: 7px!important; + border: none!important; + padding: 6px 8px; + position: relative; + line-height: normal; +} + +.ps-btn-blue { + background: #123694! important; + color: #FFF!important; + text-decoration: none; + border-radius: 7px!important; + border: none!important; + padding: 6px 8px; + position: relative; + line-height: normal; +} + +.ps-btn-orange:hover { + color: #fff; +} + +.ps-ib { + display: inline-block; +} + +.ps-w-50 { + width: 50%; +} + +.ps-input { + border-color: #e4e4e6!important; + color: #838383!important; + padding: 2px 10px!important; +} + +.ps-w-75 { + width: 75%; +} + +.ps-flex { + display: flex; + flex-wrap: wrap; + justify-content: space-around; + line-height: 30px; +} + + +.ps-vm { + vertical-align: middle; +} + + +/* Post SMTP Global Classes Ends */ + +.ps-home-main .ps-wizard { + text-align: center; + margin: 35px 0; +} + +.ps-flex.ps-home-main { + width: 100%; + background: #f9f9f9; + border: 1px solid #e6e6e6; +} + +.ps-home-main img { + vertical-align: middle; +} + +.ps-home-main a { + color: #1d9ad2; +} + +.ps-setting-box { + padding: 25px; + min-height: 275px; +} + +.ps-main-container-wrap { + margin: 0 auto; +} + +.ps-email-templates { + border: 2px solid #2b96ce; + padding: 5px 35px; + border-radius: 30px; + margin: 30px 0; + width: 33vw; +} + +.ps-login-designer { + border: 2px solid #123694; + padding: 5px 35px; + border-radius: 30px; + margin: 30px 0; + width: 33vw; +} + +.ps-email-templates h4 { + margin: 0px; + color: #2b96ce; +} + +.ps-login-designer h4 { + margin: 0px; + color: #123694; +} + +.ps-home-bottom h1 { + text-align: center; + font-weight: bold; + font-size: 20px; +} + +.ps-home-bottom li { + margin: 0; +} + +.ps-email-templates ul li::before { + content: "\2022"; + color: #2b96ce; + font-weight: bold; + display: inline-block; + width: 1em; + margin-left: -1em; +} + +.ps-login-designer ul li::before { + content: "\2022"; + color: #123694; + font-weight: bold; + display: inline-block; + width: 1em; + margin-left: -1em; +} + +.ps-email-templates h4 { + margin: 0px; +} + +.ps-home-bottom a { + color: #faaa39; +} + +.ps-home-bottom { + margin: 25px auto; +} + +.ps-config-bar .ps-right { + color: #817d7d; +} + +.ps-home-middle { + border-bottom: 3px dashed #e6e6e6; + margin: 35px auto; + padding-bottom: 20px; +} + +.ps-single-socket-outer.ps-sib { + position: relative; +} + +img.ps-sib-recommended { + position: absolute; + left: -8px; + top: 1px; +} + +.twitter-wrap { + display: flex; +} + +.twitter-wrap #postman-main-menu { + flex: 1; + margin: 0; + margin-right: 10px; + overflow: hidden; + border-radius: 5px; +} + +.post-smtp-welcome-panel-content { + width: 100%; +} + +#postman-main-menu.welcome-panel { + padding: 0px 10px 5px; + overflow: hidden; +} + +#postman-main-menu.advanced_config { + margin: 0; +} + +form#postman_wizard legend, form#postman_test_email_wizard legend { + font-weight: bold; +} + +form label { + font-weight: bold; + margin-right: 10px; +} + +form span.postman_input_description { + font-size: 0.8em; +} + +table#connectivity_test_table { + width: 100%; + display: none; + border: solid 1px #ddd; +} + +table#connectivity_test_table tr { + background-color: #fff; +} + +table#connectivity_test_table tr td { + padding: 5px; + margin: 0; + text-align: center; +} + +table th.port_25, table th.port_443, table th.port_465, table th.port_587 + { + width: 17%; +} + +table#testing_table td.port { + width: 100px; +} + +p#wizard_oauth2_help span.error { + color: red; +} + +form#postman_wizard span.postman_input_description + label { + margin-top:2em; +} + +input.input_plugin_radio { + margin-left: 20px; +} + +.wizard>.content { + min-height: 1000px; +} + +dt { + font-style: italic; +} + +dt em { + font-style: normal; +} + +p#back_to_main_menu { + text-align: right; + margin-top: 10px; + padding-right: 10px; +} + +.new-item { + display: inline-block; + padding: 5px; + border-radius: 20px; + background-color: red; + margin-right: 10px; +} + +.new-item span { + font-weight: bold; + color: white; + animation: pulse 2s linear 0s infinite; +} + +.align-middle { + display: inline-block; + vertical-align: middle; +} + +.post-badge { + position: absolute; + top: 0; + right: 0; + padding-top: 142px; + height: 50px; + width: 173px; + color: #fafafa; + font-weight: bold; + font-size: 14px; + text-align: center; + margin: 0 -5px; + background: url(images/badge.png) no-repeat; +} + +.post-smtp-welcome-panel { + background: #f9f9f9; + border: 1px solid #e6e6e6; + margin: 25px 0; +} + +.clear { + clear: both; +} + +.welcome-panel-column-container { + width: 95%; + margin: 0 auto; +} + +.back-to-menu-link { + padding: 15px 0; +} + +.post-smtp-welcome-panel { + background: #f9f9f9; + border: 1px solid #e6e6e6; + margin: 25px 0; + border-radius: 9px; +} + +#postman_wizard-p-2 { + line-height: 55px; +} + +.no-configuration.ps-config-bar { + background: #ffe0b2; +} + +/* +* Modifying jquery-steps.css Starts +* @since 2.1 +*/ + +.wizard > .steps .number { + font-size: 13px; + margin-right: 15px; +} + +.wizard > .steps { + font-weight: bold; +} + +.wizard > .steps a, +.wizard > .steps a:hover, +.wizard > .steps a:active { + margin-bottom: 20px; +} + +.wizard > .steps .disabled a, +.wizard > .steps .disabled a:hover, +.wizard > .steps .disabled a:active { + background: #ffff; + color: #aaa; + cursor: default; + border: 1px solid #e4e4e6; +} + +.wizard > .steps .current a, +.wizard > .steps .current a:hover, +.wizard > .steps .current a:active { + background: #456dff; + color: #fff; + cursor: default; +} + +.wizard > .steps .done a, +.wizard > .steps .done a:hover, +.wizard > .steps .done a:active { + background: #4db556; + color: #fff; +} + +.wizard.vertical > .steps { + background: #f9f9f9; + border: 1px solid #e6e6e6; + border-radius: 9px; + padding: 25px 21px; + width: 33%; +} + +.wizard.vertical > .content { + float: right; + background: #fff; + width: 50%; + padding: 25px 35px; + border-left: 4px solid #e4e4e6; + border-radius: 0; +} + +.wizard > .steps .done a, .wizard > .steps .done a:hover, .wizard > .steps .done a:active { + padding: 12px; +} + +legend#wizard_recommendation span { + color: #000!important; +} + +#postman_wizard .steps li .number, +#postman_test_email_wizard .steps li .number { + background: #e6e6e6; + padding: 1px 3px 2px 7px; + border-radius: 50%; + color: #707175; + font-size: 11px; +} + +/* +* Modifying jquery-steps.css Ends +*/ + +.user_override input { + display: inline-block!important; +} + +.user_override label { + font-size: 12px; +} + +section#export_settings, +section#import_settings { + border: 2px solid #e4e4e6; + display: inline-block; + padding: 35px; + background: #f9f9f9; + border-radius: 9px; + min-height: 385px; + width: 43%; +} + +section#delete_settings { + margin-top: 40px; +} + +.ui-widget-header { + border-bottom: none; +} + +.ui-widget-content, +.ui-widget-header { + background-color: transparent; +} + +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default { + background-color: #f9f9fa; +} + +.ui-tabs .ui-tabs-nav li { + border: none; + margin-top: 5px; +} + +.ui-widget-content .ui-state-default a { + color: #797979; +} + +.ui-tabs .ui-tabs-nav li a { + padding: 0.8em 1.8em; + font-size: 15px; + font-weight: bold; +} + +.ui-tabs .ui-tabs-nav li a:focus { + box-shadow: none; +} + +.ui-tabs .ui-tabs-active, +.ui-tabs .ui-tabs-nav li.visited-config-ui-tab.ui-tabs-active { + background: #ffffff; +} + +.ui-tabs .ui-tabs-active a { + color: #375caf; +} +.ps-less-secure { + color: red; +} + +#user_auth_override td { + padding-bottom: 15px; +} + + +@keyframes pulse { + 0% { + opacity: 0; + } + + 25% { + opacity: 0.25; + } + + 50% { + opacity: 0.5; + } + + 75% { + opacity: 0.75; + } + + 100% { + opacity: 1; + } +} + +@media (min-width: 1024px) and (max-width: 1171px) { + + .ps-email-templates, + .ps-login-designer { + width: 30vw; + } + + .ps-config-bar { + font-size: 14px; + } + + .ps-flex { + justify-content: space-between; + } +} + +/* Wizard Responsive */ +@media (min-width: 1024px) and (max-width: 1393px) { + + .wizard > .steps { + font-size: 11px; + } + + .wizard.vertical > .content { + width: 47%; + } + + .ps-single-socket-outer { + max-width: 152px; + } + + .ps-wizard-socket-logo { + width: 144px; + } + + #email-log-filter { + line-height: 40px; + } + +} + +/* Email Log Styling */ + +#postman-email-log-filter .form-control { + margin: 0 5px; +} + +.post-smtp_page_postman_email_log .ps-config-bar { + padding: 10px +} + +@CHARSET "UTF-8"; + +th#date { + width:15%; +} + +.postman-log-row { + padding: 20px; + display: flex; + align-items: center; + border-bottom: 1px solid #ddd; + flex-wrap: wrap; +} + +#postman-log-actions postman-log-actions + +/* Date Picker Default Styles */ +.ui-datepicker { + padding: 0; + margin: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; + background-color: #fff; + border: 1px solid #dfdfdf; + border-top: none; + -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.075); + min-width: 17em; + width: auto; +} + +.ui-datepicker * { + padding: 0; + font-family: "Open Sans", sans-serif; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.ui-datepicker table { + font-size: 13px; + margin: 0; + border: none; + border-collapse: collapse; +} + +.ui-datepicker .ui-widget-header, +.ui-datepicker .ui-datepicker-header { + background-image: none; + border: none; + color: #fff; + font-weight: normal; +} + +.ui-datepicker .ui-datepicker-header .ui-state-hover { + background: transparent; + border-color: transparent; + cursor: pointer; +} + +.ui-datepicker .ui-datepicker-title { + margin: 0; + padding: 10px 0; + color: #fff; + font-size: 14px; + line-height: 14px; + text-align: center; +} + +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: relative; + top: 0; + height: 34px; + width: 34px; +} + +.ui-datepicker .ui-state-hover.ui-datepicker-prev, +.ui-datepicker .ui-state-hover.ui-datepicker-next { + border: none; +} + +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-prev-hover { + left: 0; +} + +.ui-datepicker .ui-datepicker-next, +.ui-datepicker .ui-datepicker-next-hover { + right: 0; +} + +.ui-datepicker .ui-datepicker-next span, +.ui-datepicker .ui-datepicker-prev span { + display: none; +} + +.ui-datepicker .ui-datepicker-prev { + float: left; +} + +.ui-datepicker .ui-datepicker-next { + float: right; +} + +.ui-datepicker .ui-datepicker-prev:before, +.ui-datepicker .ui-datepicker-next:before { + font: normal 20px/34px 'dashicons'; + padding-left: 7px; + color: #fff; + speak: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + width: 34px; + height: 34px; +} + +.ui-datepicker .ui-datepicker-prev:before { + content: '\f341'; +} + +.ui-datepicker .ui-datepicker-next:before { + content: '\f345'; +} + +.ui-datepicker .ui-datepicker-prev-hover:before, +.ui-datepicker .ui-datepicker-next-hover:before { + opacity: 0.7; +} + +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 33%; +} + +.ui-datepicker thead { + color: #fff; + font-weight: 600; +} + +.ui-datepicker th { + padding: 10px; +} + +.ui-datepicker td { + padding: 0; + border: 1px solid #f4f4f4; + background-color: #f4f4f4; +} + +.ui-datepicker td.ui-datepicker-other-month { + border: transparent; +} + +.ui-datepicker td.ui-datepicker-week-end { + background-color: #f4f4f4; + border: 1px solid #f4f4f4; +} + +.ui-datepicker td.ui-datepicker-today { + background-color: #f0f0c0; +} + +.ui-datepicker td.ui-datepicker-current-day { + background: #bbdd88; +} + +.ui-datepicker td .ui-state-default { + background: transparent; + border: none; + text-align: center; + text-decoration: none; + width: auto; + display: block; + padding: 5px 10px; + font-weight: normal; + color: #444; +} + +.ui-datepicker td.ui-state-disabled .ui-state-default { + opacity: 0.5; +} + +/* Default Color Scheme */ +.ui-datepicker .ui-widget-header, +.ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +.ui-datepicker thead { + background: #32373c; +} + +.ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* WordPress Color Schemes */ + +/* Fresh */ +.admin-color-fresh .ui-datepicker .ui-widget-header, +.admin-color-fresh .ui-datepicker .ui-datepicker-header { + background: #00a0d2; +} + +.admin-color-fresh .ui-datepicker thead { + background: #32373c; +} + +.admin-color-fresh .ui-datepicker td .ui-state-hover { + background: #0073aa; + color: #fff; +} + +/* Blue */ +.admin-color-blue .ui-datepicker .ui-widget-header, +.admin-color-blue .ui-datepicker .ui-datepicker-header { + background: #52accc; +} + +.admin-color-blue .ui-datepicker thead { + background: #4796b3; +} + +.admin-color-blue .ui-datepicker td .ui-state-hover { + background: #096484; + color: #fff; +} + +/* Coffee */ +.admin-color-coffee .ui-datepicker .ui-widget-header, +.admin-color-coffee .ui-datepicker .ui-datepicker-header { + background: #59524c; +} + +.admin-color-coffee .ui-datepicker thead { + background: #46403c; +} + +.admin-color-coffee .ui-datepicker td .ui-state-hover { + background: #c7a589; + color: #fff; +} + +/* Ectoplasm */ +.admin-color-ectoplasm .ui-datepicker .ui-widget-header, +.admin-color-ectoplasm .ui-datepicker .ui-datepicker-header { + background: #523f6d; +} + +.admin-color-ectoplasm .ui-datepicker thead { + background: #413256; +} + +.admin-color-ectoplasm .ui-datepicker td .ui-state-hover { + background: #a3b745; + color: #fff; +} + +/* Midnight */ +.admin-color-midnight .ui-datepicker .ui-widget-header, +.admin-color-midnight .ui-datepicker .ui-datepicker-header { + background: #363b3f; +} + +.admin-color-midnight .ui-datepicker thead { + background: #26292c; +} + +.admin-color-midnight .ui-datepicker td .ui-state-hover { + background: #e14d43; + color: #fff; +} + +/* Ocean */ +.admin-color-ocean .ui-datepicker .ui-widget-header, +.admin-color-ocean .ui-datepicker .ui-datepicker-header { + background: #738e96; +} + +.admin-color-ocean .ui-datepicker thead { + background: #627c83; +} + +.admin-color-ocean .ui-datepicker td .ui-state-hover { + background: #9ebaa0; + color: #fff; +} + +/* Sunrise */ +.admin-color-sunrise .ui-datepicker .ui-widget-header, +.admin-color-sunrise .ui-datepicker .ui-datepicker-header, +.admin-color-sunrise .ui-datepicker .ui-datepicker-header .ui-state-hover { + background: #cf4944; +} + +.admin-color-sunrise .ui-datepicker th { + border-color: #be3631; + background: #be3631; +} + +.admin-color-sunrise .ui-datepicker td .ui-state-hover { + background: #dd823b; + color: #fff; +} + +/* Light */ +.admin-color-light .ui-datepicker .ui-widget-header, +.admin-color-light .ui-datepicker .ui-datepicker-header { + background: #e5e5e5; +} + +.admin-color-light .ui-datepicker thead { + background: #888; +} + +.admin-color-light .ui-datepicker .ui-datepicker-title, +.admin-color-light .ui-datepicker td .ui-state-default, +.admin-color-light .ui-datepicker .ui-datepicker-prev:before, +.admin-color-light .ui-datepicker .ui-datepicker-next:before { + color: #555; +} + +.admin-color-light .ui-datepicker td .ui-state-hover { + background: #e5e5e5; +} + +/* bbPress Color Schemes */ + +/* Evergreen */ +.admin-color-bbp-evergreen .ui-datepicker .ui-widget-header, +.admin-color-bbp-evergreen .ui-datepicker .ui-datepicker-header { + background: #56b274; +} + +.admin-color-bbp-evergreen .ui-datepicker thead { + background: #36533f; +} + +.admin-color-bbp-evergreen .ui-datepicker td .ui-state-hover { + background: #446950; + color: #fff; +} + +/* Mint */ +.admin-color-bbp-mint .ui-datepicker .ui-widget-header, +.admin-color-bbp-mint .ui-datepicker .ui-datepicker-header { + background: #4ca26a; +} + +.admin-color-bbp-mint .ui-datepicker thead { + background: #4f6d59; +} + +.admin-color-bbp-mint .ui-datepicker td .ui-state-hover { + background: #5fb37c; + color: #fff; +} + +#fs_connect .fs-box-container { + background: white !important; +} + +.ps-chrome-download { + border: 1px solid #000; + padding: 5px 35px 9px 25px; + border-radius: 7px; + box-shadow: 1px 4px 10px #979797; + margin-right: 20px; + background-color: #f9f9f9; + text-decoration: none; + color: #000; +} + +.ps-chrome-download img { + margin-right: 15px; + vertical-align: middle; +} + +.ps-use-chrome-extension { + margin-top: 25px; + line-height: 40px; +} + +.ps-notify-radios { + display: flex; + margin: 30px 0; +} + +.ps-notify-radio label { + margin: 0; + overflow: hidden; + position: relative; +} + +.ps-notify-radio img { + width: 30px; + cursor: pointer; + transition: transform 1s; + object-fit: cover; + padding: 8px 20px 3px 20px; +} + +.ps-notify-tick-container { + transition: .5s ease; + opacity: 0; + position: absolute; + top: 29%; + left: 29%; + transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + cursor: pointer; +} + +.input_notification_service:checked + label > .ps-notify-tick-container{ + opacity: 1; +} + +.ps-notify-radio { + margin: 0px 15px; + border: 1px solid #000; +} + +.ps-notify-radio input { + display: none!important; +} + +.ps-notify-radio label { + margin: 0!important; + display: inline-block; +} + +.ps-notify-tick span { + font-size: 15px; + background-color: #4caf50; + color: #fff; + border-radius: 100%; + height: 15px; + width: 16px; + border: 2px solid #fff; +} + +#postman_wizard-p-5 td { + padding: 5px; +} + +.ps-notify-radio-outer { + text-align: center; +} + +.ps-notify-radio-outer h4 { + margin: 10px; + font-weight: normal; +} + +.pro-container { + position: relative; +} + +.pro-icon { + position: absolute; + left: -4px; + top: 0; + padding: 0!important; +} + +.pro-container label { + position: initial; +} + +#use-chrome-extension table { + margin-top: 10px; +} + +.ps-chrome-extension { + line-height: 50px; + margin: 30px 0 15px 0; +} + +.ps-notify-radio:has(.input_notification_service:checked) { + border: 1px solid #4db556; +} + +.ps-switch-1 { + position: relative; + display: inline-block; + width: 30px; + height: 17px; +} + +.ps-switch-1 input { + opacity: 0; + width: 0; + height: 0; +} + +.ps-switch-1 input:checked + .slider { + background-color: #4db556; +} + +.ps-switch-1 .slider.round { + border-radius: 34px; +} + +.ps-switch-1 .slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: 0.4s; + transition: 0.4s; +} + +.ps-switch-1 input:checked + .slider:before { + -webkit-transform: translateX(13px); + -ms-transform: translateX(13px); + transform: translateX(13px); +} + +.ps-switch-1 .slider.round:before { + + border-radius: 50%; +} +.ps-switch-1 .slider:before { + position: absolute; + content: ""; + height: 13px; + width: 12px; + left: 2px; + bottom: 2px; + background-color: #fff; + -webkit-transition: 0.4s; + transition: 0.4s; +} + +/* +Sample Code + +*/ + +.welcome-panel-last h1 { + line-height: 34px; +} + +progress#ps-migration-progress::-moz-progress-bar { + background: #2271b1; +} + +/* For Chrome or Safari */ +progress#ps-migration-progress::-webkit-progress-value { + background: #2271b1; +} + +/* For IE10 */ +progress#ps-migration-progress { + background: #2271b1; +} + +h5#ps-progress { + margin: 5px; +} + +.ps-email-log-status-success span, +.ps-email-log-status-failed span, +.ps-email-log-status-queued span { + color: #fff; + font-weight: 600; + border-radius: 25px; + display: inline-block; + margin-right: 5px; + cursor: pointer; + padding: 2px 10px; +} + +.ps-email-log-status-success span { + background: #3FA500; +} + +.ps-email-log-status-failed span { + background: #DC3545; +} + +.ps-email-log-status-queued span { + background: #ffa500; +} + +.ps-email-log-view, +.ps-email-log-resend, +.ps-email-log-transcript { + color: #0086FD; +} + +.ps-email-log-delete { + color: #DC3545; +} + +.dataTables_wrapper #ps-email-log_filter { + float: left; + text-align: initial; +} + +div#ps-email-log_length{ + margin-right: 25px; +} + +#ps-email-log_filter input { + background: #F8F9FA; + border: none; + border-radius: 50px; + font-size: 13px; + padding-left: 12px; +} + +#ps-email-log, +#ps-email-reporting-logs { + padding-top: 15px; +} + +.post-smtp_page_postman_email_log h1 { + margin-bottom: 15px; +} + +.dataTables_wrapper #ps-email-log_length select, +.dataTables_wrapper #ps-email-reporting-logs_length select { + border: none; + padding: 0px 20px 0px 8px; + font-size: 13px; +} + +.ps-email-log-date-filter { + float: left; +} + +.ps-email-log-date-filter input { + border-radius: 50px; + border: none; + background: #f8f9fa; + padding: 5px; + padding-left: 12px; + font-size: 13px; +} + +.ps-email-log-date-filter label { + margin-left: 20px; +} + +.ps-email-log-top-buttons span { + vertical-align: middle; +} + +.ps-email-log-top-buttons { + float: right; +} + +.ps-email-log-export-btn { + background: #0086FD!important; + border: none!important; + border-radius: 50px!important; +} + +.ps-email-log-delete-btn { + background: #DC3545!important; + border: none!important; + border-radius: 50px!important; +} + +.ps-email-log-resend-to { + margin: 3px 0; +} + +.ps-email-log-status-buttons { + margin-top: 15px; +} + +/* View And Session Transcript Popup */ +.ps-popup-wrap { + width: 100%; + height: 100%; + display: none; + position: fixed; + top: 0px; + left: 0px; + bottom: 0; + right: 0; + content: ''; +} + +.ps-popup-box { + width: 700px; + height: 500px; + padding: 20px; + transform: translate(-50%, -50%) scale(0.5); + position: absolute; + top: 50%; + left: 50%; + box-shadow: 0px 2px 16px rgb(0 0 0 / 50%); + border-radius: 3px; + background: #fff; + overflow: auto; +} + +.ps-popup-close-btn, .ps-print-email { + text-align: center; + width: 19px; + height: 19px; + display: inline-block; + position: absolute; + top: 10px; + right: 10px; + border-radius: 1000px; + font-weight: bold; + text-decoration: none; + color: #000; + line-height: 190%; +} + +.ps-popup-close-btn { + top: 6px; +} + +.ps-popup-close-btn span { + font-size: 27px; +} + +.ps-popup-close-btn:hover { + color: #000; +} + +.ps-print-email { + right: 33px; + background: none; + color: #000; +} + +.transform-in, .transform-out { + display:block; + -webkit-transition:all ease 0.5s; + transition:all ease 0.5s; +} + +.transform-in { + -webkit-transform:translate(-50%, -50%) scale(1); + transform:translate(-50%, -50%) scale(1); +} + +.transform-out { + -webkit-transform:translate(-50%, -50%) scale(0.5); + transform:translate(-50%, -50%) scale(0.5); +} + +.ps-email-log-actions span{ + vertical-align: middle; +} + +.ps-email-resend-btn span { + vertical-align: middle; +} + +.ps-broken-mail-notice { + margin: 20px 0; + padding: 10px; + border-radius: 3px; + box-shadow: 0 1px 1px rgba(0,0,0,.04); + background: #cce5ff; + border: #b8daff; + color: #004085; + border-radius: 9px; +} + +#ps-email-reporting-logs_wrapper { + padding-top: 15px; +} + +#ps-email-log_paginate .paginate_button.current { + background: #dc3545; + color: #fff!important; + border-radius: 5px; +} + +#ps-email-log_paginate .paginate_button:hover { + background: #0086fd; + border-radius: 5px; + border: none; +} + +#ps-email-log_paginate .paginate_button { + border: none; +} + +#ps-email-log_next, +#ps-email-log_previous { + background: #dfdfdf; + color: #000; + border-radius: 5px; +} + +#ps-email-log_paginate a { + margin: 0 4px; +} + +.ps-status-log { + display: inline-block; + font-family: inherit; + margin-left: 5px; +} + +.ps-refresh-logs span { + vertical-align: middle; + background: #f8f9fa; + padding: 6px; + border-radius: 50px; + color: #0086fd; +} + +.ps-refresh-logs span:hover { + cursor: pointer; +} +#toplevel_page_postman ul li:nth-last-child(3) a { + color: #adff2f!important; +} + +.ps-dashboard-pro { + background: #eef2f4; + color: #1d9ad2; + font-size: 11px; + padding: 0px 4px; + border-radius: 3px; + margin-left: 1px; +} + +.ps-dashboard-pro-hide{ + display: none; + +} + +.ps-home-middle-left { + float: left; +} + +.ps-pro-icon { + color: #fed90f; +} + +.button.ps-status-btn { + border-radius: 50px; +} + +.ps-status-btn { + background-color: #ffffff!important; + color: #000000!important; + border: 1px solid #4578ea!important; +} + +.ps-status-btn.active { + background-color: #4578ea!important;; + color: #ffffff!important; + border: none; +} + +.ps-status-btn:focus { + box-shadow: none!important; +} + +.post-smtp-remove-webhook-url { + vertical-align: text-top; +} + +.post-smtp-remove-webhook-url { + color: #999999; + border-radius: 50px; + margin-left: 6px; + cursor: pointer; +} + +.post-smtp-webhook-urls input { + width: 400px; +} + +.post_smtp_diagnostic_container { + background-color: #fff; + padding: 30px; + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.post_smtp_diagnostic_container h2 { + font-size: 24px; + margin-bottom: 20px; + color: #333; +} + +#post_smtp_diagnostic_form .form-group { + margin-bottom: 15px; +} + +#post_smtp_diagnostic_form .form-group label { + display: block; + font-weight: bold; + color: #333; + margin-bottom: 5px; +} + +#post_smtp_diagnostic_form .form-group input[type="text"], #post_smtp_diagnostic_form .form-group input[type="email"], #post_smtp_diagnostic_form .form-group select { + width: 100%; + padding: 5px; + font-size: 14px; + border: 1px solid #ccc; + border-radius: 5px; + box-sizing: border-box; +} + +#post_smtp_diagnostic_form .form-group .post-smtp-diagnostic-submit-btn { + background-color: #2271b1; + color: white; + padding: 8px 16px; + font-size: 14px; + border: none; + border-radius: 5px; + cursor: pointer; +} + +#post_smtp_diagnostic_form .form-group .post-smtp-diagnostic-submit-btn:hover { + background-color: #1a5a8f; +} +.report_sent_message{ + display: none; + color: green; +} +.report_validation_error{ + display: none; + color: red; +} +h3.diagnostic-report-heading { + align-items: center; + font-size: 18px; + font-weight: bold; +} +.copy_diagnostic_report{ + background-color: #2271b1; + color: white; + padding: 5px 10px; + font-size: 14px; + border: none; + border-radius: 3px; + cursor: pointer; + margin-left: 5px; + font-weight: normal; +} +.copy_diagnostic_report:disabled{ + background-color: #a0a0a0; + cursor: not-allowed; +} +.post-smtp-diagnostic-submit-btn:disabled{ + background-color: #a0a0a0; + cursor: not-allowed; +} +hr { + border: none; + border-top: 1px solid #ddd; + margin: 25px 0; /* Space between divs */ +} +@media (min-width: 800px) { + #post_smtp_diagnostic_form .form-group input[type="text"], #post_smtp_diagnostic_form .form-group input[type="email"], #post_smtp_diagnostic_form .form-group select { + width: 30%; + } +} +label.ps-switch-1.ps-gmail-one-click { + position: relative; +} +label.ps-switch-1.ps-gmail-one-click:hover:before { + content: ""; + position: absolute; + left: 160px; + right: 0; + width: 400px; + height: 288px; + background: url(images/gmail-once-click.gif) no-repeat #ffff; + box-shadow: 0px 3px 36px -7px #000; + border-radius: 5px; + z-index: 2; + top: -40px; + background-size: 100%; + +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/style/snail-mail-email-explained.jpg b/html/wp-content/plugins/post-smtp/style/snail-mail-email-explained.jpg new file mode 100644 index 0000000..ec3d439 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/style/snail-mail-email-explained.jpg differ diff --git a/html/wp-content/plugins/post-smtp/style/testEmail.html b/html/wp-content/plugins/post-smtp/style/testEmail.html new file mode 100644 index 0000000..55d3d26 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/style/testEmail.html @@ -0,0 +1,39 @@ + + + + + + + +
            + + + + + + + +
            + + + + + + +
            +
            +
            Hello! - 你好 - Bonjour! - नमसà¥à¤¤à¥‡ - ¡Hola! - Olá - Привет! - 今日ã¯
            + +
            +

            Image source: poofytoo - Used with permission
            + + + diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/FONTLOG.txt b/html/wp-content/plugins/really-simple-captcha/gentium/FONTLOG.txt new file mode 100644 index 0000000..080bbd3 --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/gentium/FONTLOG.txt @@ -0,0 +1,156 @@ +FONTLOG +Gentium Basic and Gentium Book Basic v1.102 +========================================================== + + +This file provides detailed information on the Gentium Basic and Gentium Book Basic font families. This information should be distributed along with the Gentium Basic and Gentium Book Basic fonts and any derivative works. + + +Basic Font Information +---------------------- + +Gentium ("belonging to the nations" in Latin) is a Unicode typeface family designed to enable the many diverse ethnic groups around the world who use the Latin script to produce readable, high-quality publications. The design is intended to be highly readable, reasonably compact, and visually attractive. Gentium has won a "Certificate of Excellence in Typeface Design" in two major international typeface design competitions: bukva:raz! (2001), TDC2003 (2003). + +The Gentium Basic and Gentium Book Basic font famililes are based on the original design, but with additional weights. The "Book" family is slightly heavier. Both families come with a complete regular, bold, italic and bold italic set of fonts. + +The supported character set, however, is much smaller than for the main Gentium fonts. These "Basic" fonts support only the Basic Latin and Latin-1 Supplement Unicode ranges, plus a selection of the more commonly used extended Latin characters, with miscellaneous diacritical marks, symbols and punctuation. For a complete list of supported characters see the list at the end of this document. + +In particular, these fonts do not support: + +- Full extended Latin IPA +- Complete support for Central European languages +- Greek +- Cyrillic + +A much more complete character set will be supported in a future version of the complete Gentium fonts. These "Basic" fonts are intended as a way to provide additional weights for basic font users without waiting until the complete Gentium character set is finished. So please don't request additional glyphs or characters to be supported in the Basic fonts - such support will become available in the main Gentium family in the future. + +There are also some other limitations of the Basic fonts: + +- They are not completely metric-compatible with the full Gentium family + (some glyphs may have different widths, although changes have been minimal) +- There is no kerning +- There are no "Alt" versions, or ones with low-profile diacritics +- The default stacking style for some diacritic combinations does not match Vietnamese-style conventions (although this is available through a OpenType/Graphite feature) +- No support for TypeTuner + +There are, however, some wonderful new features that are still missing from the main Gentium family: + +- Bold! +- Bold Italic! +- The slightly-heavier Book family! +- OpenType and Graphite smart code for diacritic placement! +- A few useful OpenType and Graphite features +- Support for a few more recent additions to Unicode and the SIL PUA (http://scripts.sil.org/UnicodePUA) +- Character assignments are updated to conform to Unicode 5.1 + +In particular, the Basic fonts support a subset of the smart font features that the Doulos SIL font supports. Those features are: + +- Capital Eng alternates +- Literacy alternates +- Capital Y-hook alternate +- Capital N-left-hook alternate +- Modifier apostrophe alternate +- Modifier colon alternate +- Open o alternate +- Vietnamese-style diacritics + +More detail on the features can be seen in the Doulos SIL Technical Documentation (http://scripts.sil.org/DoulosSIL_Technical). + + +Known Problems +-------------- + +We know of the following problems. Please report any other problems you encounter. + +- logicalnot (U+00AC) appears distorted in Bold Italic and Book Italic. +- Opening the fonts with FontLab 5.0.x, then closing them, crashes FontLab. We are working to get this bug fixed in the next version of FontLab. A workaround is to open the font, save as a .vfb file, close (which still causes a crash). Then restart FontLab and open the .vfb file. + + +ChangeLog +--------- +(This should list both major and minor changes, most recent first.) + +28 Nov 2013 (Victor Gaultney) Gentium Basic/Gentium Book Basic version 1.102 +- Minor bug fix to OpenType coverage tables - no other changes + +4 Apr 2008 (Victor Gaultney) Gentium Basic/Gentium Book Basic version 1.1 +- Final release + +12 Nov 2007 (Victor Gaultney) Gentium Basic/Gentium Book Basic version 1.1b1 +- trimmed character set down to Basic +- added additional weights +- no FontLab source files + +28 Nov 2005 (Victor Gaultney) Gentium version 1.02 +- Changed licensing to the SIL Open Font License +- Included FontLab source files +- Fixed some duplicate PostScript glyphs names +- Fixed italic angle + +19 Sep 2003 (Victor Gaultney) Gentium version 1.01 +- Maintenance release focused on changing internal font +- Information to reflect the changeover to an SIL project +- There is only one bug fix - the Greek mu PS name was changed to try and fix a display/printing problem. There is still no manual hinting + +16 Sep 2002 (Victor Gaultney) Gentium version 1.00 +- First public release +- No manual hinting is included in this version. Some has been done - with good results - but is not yet complete enough. + + +Information for Developers/Contributors +--------------------------------------- + +The source release contains FontLab source files for the eight fonts, but those files do not include the OpenType and Graphite code, as those are inserted after the fonts are generated from FontLab. The files are included as a source for the PostScript-style cubic curves. You are welcome, however, to open the font files themselves to gain access to the smart font code, although most editors will not let you edit that code directly. We will provide a richer set of sources for the full Gentium fonts at a later time. + +SIL will remain as maintainers of this font project, but we do not intend any further major releases. Our primary efforts will be going into the full Gentium package. Any contributions should be directed toward that project. + + +Acknowledgements +---------------- +(Here is where contributors can be acknowledged. If you make modifications be sure to add your name (N), email (E), web-address (W) and description (D). This list is sorted by last name in alphabetical order.) + +N: Victor Gaultney +E: victor_gaultney@sil.org +W: http://www.sil.org/~gaultney/ +D: Original Designer + +N: Annie Olsen +E: nrsi@sil.org +W: http://scripts.sil.org/ +D: Contributed some extended Latin glyphs + +N: SIL font engineers +E: nrsi@sil.org +W: http://scripts.sil.org/ +D: OpenType code and build support + +The Gentium project, and the Gentium Basic and Gentium Book Basic fonts, are maintained by SIL International. + +For more information please visit the Gentium page on SIL International's Computers and Writing systems website: +http://scripts.sil.org/gentium + +Or send an email to + + +Character Range Coverage +------------------------ + +C0 Controls and Basic Latin (U+0020..U+007E) +C1 Controls and Latin-1 Supplement (U+00A0..U+00FF) +Latin Extended-A (U+0100..U+0103, U+0106..U+010E, U+011A..U+0121, U+0124..U+0125, U+0128..U+012D, U+0130..U+0133, U+0139..U+013A, U+0141..U+0144, U+0147..U+0148, U+014A..U+0155, U+0158..U+015D, U+0160..U+0161, U+0164, U+0168..U+0171, U+00174..U+017E) +Latin Extended-B (U+0181, U+0186, U+0189..U+018A, U+018E, U+0190, U+0192, U+0197..U+019A, U+019D, U+019F..U+01A1, U+01A9..U+01AA, U+01AF..U+01B0, U+01B3..U+01B4, U+01B7, U+01CD..U+01E3, U+01E6..U+01E9, U+01EE..U+01EF, U+01F4..U+01F5, U+01F8..U+01FF, U+021E..U+021F, U+0226..U+0233, U+0237, U+023D, U+0241..U+0242, U+0244..U+0245, U+024A..U+024B) +IPA Extensions (U+0251, U+0253..U+0254, U+0256..U+0257, U+0259, U+025B, U+0263, U+0268..U+0269, U+026B, U+0272, U+0275, U+0283, U+0289..U+028A, U+028C, U+0292, U+0294, U+02A0) +Spacing Modifier Letters (U+02BC, U+02C0, U+02C6..U+02C7, U+02C9..U+02CB, U+02CD, U+02D7..U+02DD) +Combining Diacritical Marks (U+0300..U+0304,U+0306..U+030C, U+031B, U+0323, U+0327..U+0328, U+0331, U+033F, U+035F) +Greek and Coptic (U+03A0, U+03A9, U+03C0) +Latin Extended Additional (U+1E02..U+1E0F, U+1E14..U+1E17, U+1E1C..U+1E27, U+1E2E..U+1E3B, U+1E3E..U+1E49, U+1E4C..U+1E6F, U+1E78..U+1E99, U+1EA0..U+1EF9) +General Punctuation (U+2011, U+2013..U+2014, U+2018..U+201A, U+201C..U+201E, U+2020..U+2022, U+2026, U+2030, U+2039..U+203A, U+2044) +Currency Symbols (U+20AC) +Letterlike Symbols (U+2122..U+2123, U+2126) +Mathematical Operators (U+2202, U+2205..U+2206, U+220F, U+2211..U+2212, U+2219..U+221A, U+221E, U+222B, U+2248, U+2260, U+2264..U+2265) +Geometric Shapes (U+25CA, U+25CC) +Latin Extended-C (U+2C60..U+2C62) +Modifier Tone Letters (U+A700..U+A71A) +Latin Extended-D (U+A789..U+A78C) +Alphabetic Presentation Forms (U+FB01..U+FB02) +SIL PUA (U+F130..U+F131, U+F195, U+F197, U+F1C8, U+F1E9..U+F1EA, U+F20E..U+F20F, U+F211..U+F212, U+F218..U+F219, U+F21D..U+F21F, U+F242, U+F26A) diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GENTIUM-FAQ.txt b/html/wp-content/plugins/really-simple-captcha/gentium/GENTIUM-FAQ.txt new file mode 100644 index 0000000..911ab38 --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/gentium/GENTIUM-FAQ.txt @@ -0,0 +1,249 @@ +GENTIUM-FAQ +Gentium Basic Release 1.102 +28 November 2013 +======================== + +Here are some answers to frequently asked questions about the Gentium fonts: + + +General +======== + +How do you pronounce Gentium? + + The preferred pronunciation is with a soft G as in 'general', not a + hard one as in 'gold': JEN-tee-oom. + +What is GentiumAlt? + + It is a version of the font with redesigned diacritics (flatter + ones) to make it more suitable for use with stacking diacritics, and + for languages such as Vietnamese. The Greek glyphs also use the + Porsonic (single-curve) design for the circumflex. Since the main + Gentium fonts do not currently include any 'smart' rendering routines, + there is no easy way to access these alternate diacritic shapes from + within the regular Gentium font. The encoding of the fonts are the same, + so the same text can be viewed with either one. There is also no + problem with having both font families installed at the same time. + + +Licensing +========= + +I want to use Gentium in my publication - can I? + + Gentium is released under the SIL Open Font License, which permits use + for any publication, whether electronic or printed. For more answers + to use questions see the OFL-FAQ. The license, alongside information + specific to Gentium, is in the release package. + +I would like to bundle Gentium with my application - can I? + + This is our most common question. The SIL Open Font License allows + bundling with applications, even commercial ones, with some restrictions. + See the OFL file. + +Can I use the font on my web site? + + You can certainly create web pages that request that Gentium be used to + display them (if that font is available on the user's system). According + to the license, you are even allowed to place the font on your site for + people to download it. We would strongly recommend, however, that you + direct users to our site to download the font. This ensures that they + are always using the most recent version with bug fixes, etc. To make + this easier, we've simplified the URL for Gentium: + http://scripts.sil.org/gentium + +Is Gentium going to stay free? + + There is no intention to ever charge users for using Gentium. The + current version is licensed under a free/open license and future + versions will be similar. + + +Modification +============ + +I would like to modify Gentium to add a couple of characters I need. Can I? + + Yes - that is allowed as long as you abide by the conditions of the + SIL Open Font License. + +So will you add glyphs upon request? + + If you have a special symbol that you need (say, for a particular + transcription system), the best means of doing so will be to ensure + that the symbol makes it into the Unicode Standard. It is impossible + for us to add every glyph that every person desires, but we do place + a high priority on adding pretty much anything that falls in certain + Unicode ranges (extended Latin, Greek, Cyrillic). You can send us your + requests, but please understand that we are unlikely to add symbols + where the user base is very small, unless they have been accepted + into Unicode. + +Can I send you work I've done to be incorporated into Gentium? + + Yes! See the FONTLOG for information on becoming a contributor. + + +Technical +========= + +Can you help me get Gentium working on my system? + + We cannot afford to offer individual technical support. The best + resource is this website, where we hope to offer some limited help. + However, we do want to hear of any problems you encounter, so that + we can add them to the list of bugs to fix in later releases. + + Our contact address is . Please understand + that we cannot guarantee a personal response. + +I can't find all the extended Latin letters in the font. How do I type them? + + Gentium is Unicode-encoded, which means that the computer stores a + special, unique code for each letter in your document. Since most + keyboards do not have hundreds of keys, special software is needed + in order to type the hundreds of special characters supported by the + font. + +I can't find the 'o with right hook' in the font. Where is it? + + Combinations of base letters with diacritics are often called + composite, or pre-composed glyphs. Gentium has hundreds of these + (the ones that are included in Unicode). There are, however, many + common combinations that are not represented by a single composite. + It is possible to enter these into a document, but only as + individual components. So 'o with right hook' would be entered as + 'o', then 'right hook'. Although this may not look very good in some + cases, we're not able to anticipate every possible combination. + Future versions of Gentium will include 'smart font' support for + technologies such as OpenType and SIL's Graphite. This will make + diacritic positioning much better. The Gentium Basic fonts do, + however, include limited support for both OpenType and Graphite, + and demonstrate the type of support that will eventually be provided. + +Some diacritics are not aligning well with base glyphs, and if I type more +than one diacritic, they run into each other. Why is that? + + Gentium currently has no 'smart font' code for automatic diacritic + positioning, but the Gentium Basic fonts do, and similar support will + appear in the main fonts in the near future. + +How do I type the Greek letters? + + You need a Unicode-compatible keyboarding system, which is not + included in the distribution package. + +I'm having problems making PDFs -- why won't my document distill? + + Gentium is a large font, with lots of glyphs. As a result, some + printers can balk at PDFs that have the complete font embedded. The + easiest way to avoid this is to have Acrobat/Distiller subset the + font. This is generally a good idea anyway (with any font) and can + reduce the size of your files. + + +Basic +===== + +How are the Basic fonts (Gentium Basic, Gentium Book Basic) different +from Gentium? + + These font families are based on the original Gentium design, but with + additional weights. Both families come with a complete regular, bold, + italic and bold italic set of fonts. The supported character set, + however, is much smaller than for the main Gentium fonts. These + 'Basic' fonts support only the Basic Latin and Latin-1 Supplement + Unicode ranges, plus a selection of the more commonly used extended + Latin characters, with miscellaneous diacritical marks, symbols and + punctuation. In particular, these fonts do not support full extended + Latin IPA, complete support for Central European languages, Greek and + Cyrillic. + +What is the Book weight? + + It is a complete second font family that is slightly heavier overall, + and more useful for some purposes. The main Gentium family will + eventually have a complete matching Book weight, along with matching + italics. + +Why is the line spacing greater for the Basic fonts? + + In some environments, stacked diacritics in Gentium could display as + 'chopped-off'. Gentium Basic has slightly wider default line spacing + in order to avoid this problem. Most applications do, however, let you + set the line spacing explicitly, so you can have the lines spaced + precisely as you wish. + +Will you be accepting requests for additions to the Basic character set? + + No. We are now focusing our development efforts on the main Gentium + fonts, which already provide richer character set support. + +Is there an Alt version of the Basic fonts? + + No, although you may notice that capitals and some tall lowercase + letters do use 'low-profile' versions. + + +Future +====== + +Now that SIL International has taken over Gentium, who will be the next +designer? + + Victor Gaultney will remain as primary designer, but Annie Olsen, a + fellow type designer from the SIL Non-Roman Script Initiative, has + joined the project team. She is a former calligraphy teacher, and is + well suited for the task. Other members of the NRSI team will also + add their expertise in technical matters. + +Do you plan to include other typographic enhancements (small caps, old style +figures, etc.)? + + Those would be nice, wouldn't they? From a design point of view, + it would be great to have these refinements, and we haven't ruled + them out. But there are other needs that are much higher priority + (Bold, Cyrillic, etc.). If you think you could contribute some of + your time and effort to these enhancements, see the FONTLOG file for + information on becoming a contributor. + +What about bold? + + The Gentium Basic fonts include Bold and Bold Italic versions. The + main Gentium fonts will also include them in the future. + +Sans-serif? + + There is a definite need for a sans-serif font that shares some of + Gentium's strengths -- high readability, economy of space, etc. It + would also be great if that font also harmonized well with Gentium. + We don't currently have any plans for a companion face, although one + of our other projects - Andika - may be useful. Andika is a sans-serif + font designed specifically for use in literacy programs around the + world, and is available from our web site. + +Will you be extending Gentium to cover other scripts, and Hebrew in +particular? + + It is very unlikely that we would do this, as there are so many + pressing needs in Latin, Greek and Cyrillic scripts. But you could + contribute to the project. + +When will Cyrillic be completed? + + As soon as we can get it done, but it is still a few months away. + +I need a couple of ancient Greek glyphs, such as the digamma. When will +those be ready? + + These have already been designed and will be in the next main release. + +Will there be a Type 1 version? What about OpenType? + + The next generation of Gentium will have OpenType, Graphite and AAT + support. We do not plan to produce Type 1 versions at this time, but + please write us if this is important (and tell us why). We are, however, + considering releasing a version in OT-CFF format, but it will not go + through the same careful testing as the standard OT/Graphite/AAT version. \ No newline at end of file diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBasB.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasB.ttf new file mode 100644 index 0000000..636cbc1 Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasB.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBasBI.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasBI.ttf new file mode 100644 index 0000000..ec064a2 Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasBI.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBasI.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasI.ttf new file mode 100644 index 0000000..0dd6405 Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasI.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBasR.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasR.ttf new file mode 100644 index 0000000..4d263b8 Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBasR.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasB.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasB.ttf new file mode 100644 index 0000000..5a852af Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasB.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasBI.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasBI.ttf new file mode 100644 index 0000000..6635b45 Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasBI.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasI.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasI.ttf new file mode 100644 index 0000000..79c3fb5 Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasI.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasR.ttf b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasR.ttf new file mode 100644 index 0000000..0154bae Binary files /dev/null and b/html/wp-content/plugins/really-simple-captcha/gentium/GenBkBasR.ttf differ diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/OFL-FAQ.txt b/html/wp-content/plugins/really-simple-captcha/gentium/OFL-FAQ.txt new file mode 100644 index 0000000..0893d7c --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/gentium/OFL-FAQ.txt @@ -0,0 +1,425 @@ +OFL FAQ - Frequently Asked Questions about the SIL Open Font License (OFL) +Version 1.1-update3 - Sept 2013 +(See http://scripts.sil.org/OFL for updates) + + +CONTENTS OF THIS FAQ +1 USING AND DISTRIBUTING FONTS LICENSED UNDER THE OFL +2 USING OFL FONTS FOR WEB PAGES AND ONLINE WEB FONT SERVICES +3 MODIFYING OFL-LICENSED FONTS +4 LICENSING YOUR ORIGINAL FONTS UNDER THE OFL +5 CHOOSING RESERVED FONT NAMES +6 ABOUT THE FONTLOG +7 MAKING CONTRIBUTIONS TO OFL PROJECTS +8 ABOUT THE LICENSE ITSELF +9 ABOUT SIL INTERNATIONAL +APPENDIX A - FONTLOG EXAMPLE + +1 USING AND DISTRIBUTING FONTS LICENSED UNDER THE OFL + +1.1 Can I use the fonts for a book or other print publication, to create logos or other graphics or even to manufacture objects based on their outlines? +Yes. You are very welcome to do so. Authors of fonts released under the OFL allow you to use their font software as such for any kind of design work. No additional license or permission is required, unlike with some other licenses. Some examples of these uses are: logos, posters, business cards, stationery, video titling, signage, t-shirts, personalised fabric, 3D-printed/laser-cut shapes, sculptures, rubber stamps, cookie cutters and lead type. + +1.1.1 Does that restrict the license or distribution of that artwork? +No. You remain the author and copyright holder of that newly derived graphic or object. You are simply using an open font in the design process. It is only when you redistribute, bundle or modify the font itself that other conditions of the license have to be respected (see below for more details). + +1.1.2 Is any kind of acknowledgement required? +No. Font authors may appreciate being mentioned in your artwork's acknowledgements alongside the name of the font, possibly with a link to their website, but that is not required. + +1.2 Can the fonts be included with Free/Libre and Open Source Software collections such as GNU/Linux and BSD distributions and repositories? +Yes! Fonts licensed under the OFL can be freely included alongside other software under FLOSS (Free/Libre and Open Source Software) licenses. Since fonts are typically aggregated with, not merged into, existing software, there is little need to be concerned about incompatibility with existing software licenses. You may also repackage the fonts and the accompanying components in a .rpm or .deb package (or other similar package formats or installers) and include them in distribution CD/DVDs and online repositories. (Also see section 5.9 about rebuilding from source.) + +1.3 I want to distribute the fonts with my program. Does this mean my program also has to be Free/Libre and Open Source Software? +No. Only the portions based on the Font Software are required to be released under the OFL. The intent of the license is to allow aggregation or bundling with software under restricted licensing as well. + +1.4 Can I sell a software package that includes these fonts? +Yes, you can do this with both the Original Version and a Modified Version of the fonts. Examples of bundling made possible by the OFL would include: word processors, design and publishing applications, training and educational software, games and entertainment software, mobile device applications, etc. + +1.5 Can I include the fonts on a CD of freeware or commercial fonts? +Yes, as long some other font or software is also on the disk, so the OFL font is not sold by itself. + +1.6 Why won't the OFL let me sell the fonts alone? +The intent is to keep people from making money by simply redistributing the fonts. The only people who ought to profit directly from the fonts should be the original authors, and those authors have kindly given up potential direct income to distribute their fonts under the OFL. Please honour and respect their contribution! + +1.7 What about sharing OFL fonts with friends on a CD, DVD or USB stick? +You are very welcome to share open fonts with friends, family and colleagues through removable media. Just remember to include the full font package, including any copyright notices and licensing information as available in OFL.txt. In the case where you sell the font, it has to come bundled with software. + +1.8 Can I host the fonts on a web site for others to use? +Yes, as long as you make the full font package available. In most cases it may be best to point users to the main site that distributes the Original Version so they always get the most recent stable and complete version. See also discussion of web fonts in Section 2. + +1.9 Can I host the fonts on a server for use over our internal network? +Yes. If the fonts are transferred from the server to the client computer by means that allow them to be used even if the computer is no longer attached to the network, the full package (copyright notices, licensing information, etc.) should be included. + +1.10 Does the full OFL license text always need to accompany the font? +The only situation in which an OFL font can be distributed without the text of the OFL (either in a separate file or in font metadata), is when a font is embedded in a document or bundled within a program. In the case of metadata included within a font, it is legally sufficient to include only a link to the text of the OFL on http://scripts.sil.org/OFL, but we strongly recommend against this. Most modern font formats include metadata fields that will accept the full OFL text, and full inclusion increases the likelihood that users will understand and properly apply the license. + +1.11 What do you mean by 'embedding'? How does that differ from other means of distribution? +By 'embedding' we mean inclusion of the font in a document or file in a way that makes extraction (and redistribution) difficult or clearly discouraged. In many cases the names of embedded fonts might also not be obvious to those reading the document, the font data format might be altered, and only a subset of the font - only the glyphs required for the text - might be included. Any other means of delivering a font to another person is considered 'distribution', and needs to be accompanied by any copyright notices and licensing information available in OFL.txt. + +1.12 So can I embed OFL fonts in my document? +Yes, either in full or a subset. The restrictions regarding font modification and redistribution do not apply, as the font is not intended for use outside the document. + +1.13 Does embedding alter the license of the document itself? +No. Referencing or embedding an OFL font in any document does not change the license of the document itself. The requirement for fonts to remain under the OFL does not apply to any document created using the fonts and their derivatives. Similarly, creating any kind of graphic using a font under OFL does not make the resulting artwork subject to the OFL. + +1.14 If OFL fonts are extracted from a document in which they are embedded (such as a PDF file), what can be done with them? Is this a risk to author(s)? +The few utilities that can extract fonts embedded in a PDF will typically output limited amounts of outlines - not a complete font. To create a working font from this method is much more difficult and time consuming than finding the source of the original OFL font. So there is little chance that an OFL font would be extracted and redistributed inappropriately through this method. Even so, copyright laws address any misrepresentation of authorship. All Font Software released under the OFL and marked as such by the author(s) is intended to remain under this license regardless of the distribution method, and cannot be redistributed under any other license. We strongly discourage any font extraction - we recommend directly using the font sources instead - but if you extract font outlines from a document, please be considerate: respect the work of the author(s) and the licensing model. + +1.15 What about distributing fonts with a document? Within a compressed folder structure? Is it distribution, bundling or embedding? +Certain document formats may allow the inclusion of an unmodified font within their file structure which may consist of a compressed folder containing the various resources forming the document (such as pictures and thumbnails). Including fonts within such a structure is understood as being different from embedding but rather similar to bundling (or mere aggregation) which the license explicitly allows. In this case the font is conveyed unchanged whereas embedding a font usually transforms it from the original format. The OFL does not allow anyone to extract the font from such a structure to then redistribute it under another license. The explicit permission to redistribute and embed does not cancel the requirement for the Font Software to remain under the license chosen by its author(s). Even if the font travels inside the document as one of its assets, it should not lose its authorship information and licensing. + +1.16 What about ebooks shipping with open fonts? +The requirements differ depending on whether the fonts are linked, embedded or distributed (bundled or aggregated). Some ebook formats use web technologies to do font linking via @font-face, others are designed for font embedding, some use fonts distributed with the document or reading software, and a few rely solely on the fonts already present on the target system. The license requirements depend on the type of inclusion as discussed in 1.15. + +1.17 Can Font Software released under the OFL be subject to URL-based access restrictions methods or DRM (Digital Rights Management) mechanisms? +Yes, but these issues are out-of-scope for the OFL. The license itself neither encourages their use nor prohibits them since such mechanisms are not implemented in the components of the Font Software but through external software. Such restrictions are put in place for many different purposes corresponding to various usage scenarios. One common example is to limit potentially dangerous cross-site scripting attacks. However, in the spirit of libre/open fonts and unrestricted writing systems, we strongly encourage open sharing and reuse of OFL fonts, and the establishment of an environment where such restrictions are unnecessary. Note that whether you wish to use such mechanisms or you prefer not to, you must still abide by the rules set forth by the OFL when using fonts released by their authors under this license. Derivative fonts must be licensed under the OFL, even if they are part of a service for which you charge fees and/or for which access to source code is restricted. You may not sell the fonts on their own - they must be part of a larger software package, bundle or subscription plan. For example, even if the OFL font is distributed in a software package or via an online service using a DRM mechanism, the user would still have the right to extract that font, use, study, modify and redistribute it under the OFL. + +1.18 I've come across a font released under the OFL. How can I easily get more information about the Original Version? How can I know where it stands compared to the Original Version or other Modified Versions? +Consult the copyright statement(s) in the license for ways to contact the original authors. Consult the FONTLOG (see section 6 for more details and examples) for information on how the font differs from the Original Version, and get in touch with the various contributors via the information in the acknowledgement section. Please consider using the Original Versions of the fonts whenever possible. + +1.19 What do you mean in condition 4 of the OFL's permissions and conditions? Can you provide examples of abusive promotion / endorsement / advertisement vs. normal acknowledgement? +The intent is that the goodwill and reputation of the author(s) should not be used in a way that makes it sound like the original author(s) endorse or approve of a specific Modified Version or software bundle. For example, it would not be right to advertise a word processor by naming the author(s) in a listing of software features, or to promote a Modified Version on a web site by saying "designed by ...". However, it would be appropriate to acknowledge the author(s) if your software package has a list of people who deserve thanks. We realize that this can seem to be a grey area, but the standard used to judge an acknowledgement is that if the acknowledgement benefits the author(s) it is allowed, but if it primarily benefits other parties, or could reflect poorly on the author(s), then it is not. + +1.20 I'm writing a small app for mobile platforms, do I need to include the whole package? +If you bundle a font under the OFL with your mobile app you must comply with the terms of the license. At a minimum you must include the copyright statement, the license notice and the license text. A mention of this information in your About box or Changelog, with a link to where the font package is from, is good practice, and the extra space needed to carry these items is very small. You do not, however, need to include the full contents of the font package - only the fonts you use and the copyright and license that apply to them. For example, if you only use the regular weight in your app, you do not need to include the italic and bold versions. + +1.21 What about including OFL fonts by default in my firmware or dedicated operating system? +Many such systems are restricted and turned into appliances so that users cannot study or modify them. Using open fonts to increase quality and language coverage is a great idea, but you need to be aware that if there is a way for users to extract fonts you cannot legally prevent them from doing that. The fonts themselves, including any changes you make to them, must be distributed under the OFL even if your firmware has a more restrictive license. If you do transform the fonts and change their formats when you include them in your firmware you must respect any names reserved by the font authors via the RFN mechanism and pick your own font name. Alternatively if you directly add a font under the OFL to the font folder of your firmware without modifying or optimizing it you are simply bundling the font like with any other software collection, and do not need to make any further changes. + +1.22 Can I make and publish CMS themes or templates that use OFL fonts? Can I include the fonts themselves in the themes or templates? Can I sell the whole package? +Yes, you are very welcome to integrate open fonts into themes and templates for your preferred CMS and make them more widely available. Remember that you can only sell the fonts and your CMS add-on as part of a software bundle. (See 1.4 for details and examples about selling bundles). + +1.23 Can OFL fonts be included in services that deliver fonts to the desktop from remote repositories? Even if they contain both OFL and non-OFL fonts? +Yes. Some foundries have set up services to deliver fonts to subscribers directly to desktops from their online repositories; similarly, plugins are available to preview and use fonts directly in your design tool or publishing suite. These services may mix open and restricted fonts in the same channel, however they should make a clear distinction between them to users. These services should also not hinder users (such as through DRM or obfuscation mechanisms) from extracting and using the OFL fonts in other environments, or continuing to use OFL fonts after subscription terms have ended, as those uses are specifically allowed by the OFL. + +1.24 Can services that provide or distribute OFL fonts restrict my use of them? +No. The terms of use of such services cannot replace or restrict the terms of the OFL, as that would be the same as distributing the fonts under a different license, which is not allowed. You are still entitled to use, modify and redistribute them as the original authors have intended outside of the sole control of that particular distribution channel. Note, however, that the fonts provided by these services may differ from the Original Versions. + + +2 USING OFL FONTS FOR WEBPAGES AND ONLINE WEB FONT SERVICES + +NOTE: This section often refers to a separate paper on 'Web Fonts & RFNs'. This is available at http://scripts.sil.org/OFL_web_fonts_and_RFNs + +2.1 Can I make webpages using these fonts? +Yes! Go ahead! Using CSS (Cascading Style Sheets) is recommended. Your three best options are: +- referring directly in your stylesheet to open fonts which may be available on the user's system +- providing links to download the full package of the font - either from your own website or from elsewhere - so users can install it themselves +- using @font-face to distribute the font directly to browsers. This is recommended and explicitly allowed by the licensing model because it is distribution. The font file itself is distributed with other components of the webpage. It is not embedded in the webpage but referenced through a web address which will cause the browser to retrieve and use the corresponding font to render the webpage (see 1.11 and 1.15 for details related to embedding fonts into documents). As you take advantage of the @font-face cross-platform standard, be aware that web fonts are often tuned for a web environment and not intended for installation and use outside a browser. The reasons in favour of using web fonts are to allow design of dynamic text elements instead of static graphics, to make it easier for content to be localized and translated, indexed and searched, and all this with cross-platform open standards without depending on restricted extensions or plugins. You should check the CSS cascade (the order in which fonts are being called or delivered to your users) when testing. + +2.2 Can I make and use WOFF (Web Open Font Format) versions of OFL fonts? +Yes, but you need to be careful. A change in font format normally is considered modification, and Reserved Font Names (RFNs) cannot be used. Because of the design of the WOFF format, however, it is possible to create a WOFF version that is not considered modification, and so would not require a name change. You are allowed to create, use and distribute a WOFF version of an OFL font without changing the font name, but only if: + +- the original font data remains unchanged except for WOFF compression, and +- WOFF-specific metadata is either omitted altogether or present and includes, unaltered, the contents of all equivalent metadata in the original font. + +If the original font data or metadata is changed, or the WOFF-specific metadata is incomplete, the font must be considered a Modified Version, the OFL restrictions would apply and the name of the font must be changed: any RFNs cannot be used and copyright notices and licensing information must be included and cannot be deleted or modified. You must come up with a unique name - we recommend one corresponding to your domain or your particular web application. Be aware that only the original author(s) can use RFNs. This is to prevent collisions between a derivative tuned to your audience and the original upstream version and so to reduce confusion. + +Please note that most WOFF conversion tools and online services do not meet the two requirements listed above, and so their output must be considered a Modified Version. So be very careful and check to be sure that the tool or service you're using is compressing unchanged data and completely and accurately reflecting the original font metadata. + +2.3 What about other web font formats such as EOT/EOTLite/CWT/etc.? +In most cases these formats alter the original font data more than WOFF, and do not completely support appropriate metadata, so their use must be considered modification and RFNs may not be used. However, there may be certain formats or usage scenarios that may allow the use of RFNs. See http://scripts.sil.org/OFL_web_fonts_and_RFNs + +2.4 Can I make OFL fonts available through web font online services? +Yes, you are welcome to include OFL fonts in online web font services as long as you properly meet all the conditions of the license. The origin and open status of the font should be clear among the other fonts you are hosting. Authorship, copyright notices and license information must be sufficiently visible to your users or subscribers so they know where the font comes from and the rights granted by the author(s). Make sure the font file contains the needed copyright notice(s) and licensing information in its metadata. Please double-check the accuracy of every field to prevent contradictory information. Other font formats, including EOT/EOTLite/CWT and superior alternatives like WOFF, already provide fields for this information. Remember that if you modify the font within your library or convert it to another format for any reason the OFL restrictions apply and you need to change the names accordingly. Please respect the author's wishes as expressed in the OFL and do not misrepresent original designers and their work. Don't lump quality open fonts together with dubious freeware or public domain fonts. Consider how you can best work with the original designers and foundries, support their efforts and generate goodwill that will benefit your service. (See 1.17 for details related to URL-based access restrictions methods or DRM mechanisms). + +2.5 Some web font formats and services provide ways of "optimizing" the font for a particular website or web application; is that allowed? +Yes, it is permitted, but remember that these optimized versions are Modified Versions and so must follow OFL requirements like appropriate renaming. Also you need to bear in mind the other important parameters beyond compression, speed and responsiveness: you need to consider the audience of your particular website or web application, as choosing some optimization parameters may turn out to be less than ideal for them. Subsetting by removing certain glyphs or features may seriously limit functionality of the font in various languages that your users expect. It may also introduce degradation of quality in the rendering or specific bugs on the various target platforms compared to the original font from upstream. In other words, remember that one person's optimized font may be another person's missing feature. Various advanced typographic features (OpenType, Graphite or AAT) are also available through CSS and may provide the desired effects without the need to modify the font. + +2.6 Is subsetting a web font considered modification? +Yes. Removing any parts of the font when delivering a web font to a browser, including unused glyphs and smart font code, is considered modification. This is permitted by the OFL but would not normally allow the use of RFNs. Some newer subsetting technologies may be able to subset in a way that allows users to effectively have access to the complete font, including smart font behaviour. See 2.8 and http://scripts.sil.org/OFL_web_fonts_and_RFNs + +2.7 Are there any situations in which a modified web font could use RFNs? +Yes. If a web font is optimized only in ways that preserve Functional Equivalence (see 2.8), then it may use RFNs, as it reasonably represents the Original Version and respects the intentions of the author(s) and the main purposes of the RFN mechanism (avoids collisions, protects authors, minimizes support, encourages derivatives). However this is technically very difficult and often impractical, so a much better scenario is for the web font service or provider to sign a separate agreement with the author(s) that allows the use of RFNs for Modified Versions. + +2.8 How do you know if an optimization to a web font preserves Functional Equivalence? +Functional Equivalence is described in full in the 'Web fonts and RFNs' paper at http://scripts.sil.org/OFL_web_fonts_and_RFNs, in general, an optimized font is deemed to be Functionally Equivalent (FE) to the Original Version if it: + +- Supports the same full character inventory. If a character can be properly displayed using the Original Version, then that same character, encoded correctly on a web page, will display properly. +- Provides the same smart font behavior. Any dynamic shaping behavior that works with the Original Version should work when optimized, unless the browser or environment does not support it. There does not need to be guaranteed support in the client, but there should be no forced degradation of smart font or shaping behavior, such as the removal or obfuscation of OpenType, Graphite or AAT tables. +- Presents text with no obvious degradation in visual quality. The lettershapes should be equally (or more) readable, within limits of the rendering platform. +- Preserves original author, project and license metadata. At a minimum, this should include: Copyright and authorship; The license as stated in the Original Version, whether that is the full text of the OFL or a link to the web version; Any RFN declarations; Information already present in the font or documentation that points back to the Original Version, such as a link to the project or the author's website. + +If an optimized font meets these requirements, and so is considered to be FE, then it's very likely that the original author would feel that the optimized font is a good and reasonable equivalent. If it falls short of any of these requirements, the optimized font does not reasonably represent the Original Version, and so should be considered to be a Modified Version. Like other Modified Versions, it would not be allowed to use any RFNs and you simply need to pick your own font name. + +2.9 Isn't use of web fonts another form of embedding? +No. Unlike embedded fonts in a PDF, web fonts are not an integrated part of the document itself. They are not specific to a single document and are often applied to thousands of documents around the world. The font data is not stored alongside the document data and often originates from a different location. The ease by which the web fonts used by a document may be identified and downloaded for desktop use demonstrates that they are philosophically and technically separate from the web pages that specify them. See http://scripts.sil.org/OFL_web_fonts_and_RFNs + +2.10 So would it be better to not use RFNs at all if you want your font to be distributed by a web fonts service? +No. Although the OFL does not require authors to use RFNs, the RFN mechanism is an important part of the OFL model and completely compatible with web font services. If that web font service modifies the fonts, then the best solution is to sign a separate agreement for the use of any RFNs. It is perfectly valid for an author to not declare any RFNs, but before they do so they need to fully understand the benefits they are giving up, and the overall negative effect of allowing many different versions bearing the same name to be widely distributed. As a result, we don't generally recommend it. + +2.11 What should an agreement for the use of RFNs say? Are there any examples? +There is no prescribed format for this agreement, as legal systems vary, and no recommended examples. Authors may wish to add specific clauses to further restrict use, require author review of Modified Versions, establish user support mechanisms or provide terms for ending the agreement. Such agreements are usually not public, and apply only to the main parties. However, it would be very beneficial for web font services to clearly state when they have established such agreements, so that the public understands clearly that their service is operating appropriately. + +See the separate paper on 'Web Fonts & RFNs' for in-depth discussion of issues related to the use of RFNs for web fonts. This is available at http://scripts.sil.org/OFL_web_fonts_and_RFNs + + +3 MODIFYING OFL-LICENSED FONTS + +3.1 Can I change the fonts? Are there any limitations to what things I can and cannot change? +You are allowed to change anything, as long as such changes do not violate the terms of the license. In other words, you are not allowed to remove the copyright statement(s) from the font, but you could put additional information into it that covers your contribution. See the placeholders in the OFL header template for recommendations on where to add your own statements. (Remember that, when authors have reserved names via the RFN mechanism, you need to change the internal names of the font to your own font name when making your modified version even if it is just a small change.) + +3.2 I have a font that needs a few extra glyphs - can I take them from an OFL licensed font and copy them into mine? +Yes, but if you distribute that font to others it must be under the OFL, and include the information mentioned in condition 2 of the license. + +3.3 Can I charge people for my additional work? In other words, if I add a bunch of special glyphs or OpenType/Graphite/AAT code, can I sell the enhanced font? +Not by itself. Derivative fonts must be released under the OFL and cannot be sold by themselves. It is permitted, however, to include them in a larger software package (such as text editors, office suites or operating systems), even if the larger package is sold. In that case, you are strongly encouraged, but not required, to also make that derived font easily and freely available outside of the larger package. + +3.4 Can I pay someone to enhance the fonts for my use and distribution? +Yes. This is a good way to fund the further development of the fonts. Keep in mind, however, that if the font is distributed to others it must be under the OFL. You won't be able to recover your investment by exclusively selling the font, but you will be making a valuable contribution to the community. Please remember how you have benefited from the contributions of others. + +3.5 I need to make substantial revisions to the font to make it work with my program. It will be a lot of work, and a big investment, and I want to be sure that it can only be distributed with my program. Can I restrict its use? +No. If you redistribute a Modified Version of the font it must be under the OFL. You may not restrict it in any way beyond what the OFL permits and requires. This is intended to ensure that all released improvements to the fonts become available to everyone. But you will likely get an edge over competitors by being the first to distribute a bundle with the enhancements. Again, please remember how you have benefited from the contributions of others. + +3.6 Do I have to make any derivative fonts (including extended source files, build scripts, documentation, etc.) publicly available? +No, but please consider sharing your improvements with others. You may find that you receive in return more than what you gave. + +3.7 If a trademark is claimed in the OFL font, does that trademark need to remain in modified fonts? +Yes. Any trademark notices must remain in any derivative fonts to respect trademark laws, but you may add any additional trademarks you claim, officially registered or not. For example if an OFL font called "Foo" contains a notice that "Foo is a trademark of Acme", then if you rename the font to "Bar" when creating a Modified Version, the new trademark notice could say "Foo is a trademark of Acme Inc. - Bar is a trademark of Roadrunner Technologies Ltd.". Trademarks work alongside the OFL and are not subject to the terms of the licensing agreement. The OFL does not grant any rights under trademark law. Bear in mind that trademark law varies from country to country and that there are no international trademark conventions as there are for copyright. You may need to significantly invest in registering and defending a trademark for it to remain valid in the countries you are interested in. This may be costly for an individual independent designer. + +3.8 If I commit changes to a font (or publish a branch in a DVCS) as part of a public open source software project, do I have to change the internal font names? +Only if there are declared RFNs. Making a public commit or publishing a public branch is effectively redistributing your modifications, so any change to the font will require that you do not use the RFNs. Even if there are no RFNs, it may be useful to change the name or add a suffix indicating that a particular version of the font is still in development and not released yet. This will clearly indicate to users and fellow designers that this particular font is not ready for release yet. See section 5 for more details. + + +4 LICENSING YOUR ORIGINAL FONTS UNDER THE OFL + +4.1 Can I use the SIL OFL for my own fonts? +Yes! We heartily encourage everyone to use the OFL to distribute their own original fonts. It is a carefully constructed license that allows great freedom along with enough artistic integrity protection for the work of the authors as well as clear rules for other contributors and those who redistribute the fonts. The licensing model is used successfully by various organisations, both for-profit and not-for-profit, to release fonts of varying levels of scope and complexity. + +4.2 What do I have to do to apply the OFL to my font? +If you want to release your fonts under the OFL, we recommend you do the following: + +4.2.1 Put your copyright and Reserved Font Names information at the beginning of the main OFL.txt file in place of the dedicated placeholders (marked with the <> characters). Include this file in your release package. + +4.2.2 Put your copyright and the OFL text with your chosen Reserved Font Name(s) into your font files (the copyright and license fields). A link to the OFL text on the OFL web site is an acceptable (but not recommended) alternative. Also add this information to any other components (build scripts, glyph databases, documentation, test files, etc). Accurate metadata in your font files is beneficial to you as an increasing number of applications are exposing this information to the user. For example, clickable links can bring users back to your website and let them know about other work you have done or services you provide. Depending on the format of your fonts and sources, you can use template human-readable headers or machine-readable metadata. You should also double-check that there is no conflicting metadata in the font itself contradicting the license, such as the fstype bits in the os2 table or fields in the name table. + +4.2.3 Write an initial FONTLOG.txt for your font and include it in the release package (see Section 6 and Appendix A for details including a template). + +4.2.4 Include the relevant practical documentation on the license by adding the current OFL-FAQ.txt file in your package. + +4.2.5 If you wish you can use the OFL graphics (http://scripts.sil.org/OFL_logo) on your website. + +4.3 Will you make my font OFL for me? +We won't do the work for you. We can, however, try to answer your questions, unfortunately we do not have the resources to review and check your font packages for correct use of the OFL. We recommend you turn to designers, foundries or consulting companies with experience in doing open font design to provide this service to you. + +4.4 Will you distribute my OFL font for me? +No, although if the font is of sufficient quality and general interest we may include a link to it on our partial list of OFL fonts on the OFL web site. You may wish to consider other open font catalogs or hosting services, such as the Unifont Font Guide (http://unifont.org/fontguide), The League of Movable Type (http://theleagueofmovabletype.com) or the Open Font Library (http://openfontlibrary.org/), which despite the name has no direct relationship to the OFL or SIL. We do not endorse any particular catalog or hosting service - it is your responsibility to determine if the service is right for you and if it treats authors with fairness. + +4.5 Why should I use the OFL for my fonts? +- to meet needs for fonts that can be modified to support lesser-known languages +- to provide a legal and clear way for people to respect your work but still use it (and reduce piracy) +- to involve others in your font project +- to enable your fonts to be expanded with new weights and improved writing system/language support +- to allow more technical font developers to add features to your design (such as OpenType, Graphite or AAT support) +- to renew the life of an old font lying on your hard drive with no business model +- to allow your font to be included in Libre Software operating systems like Ubuntu +- to give your font world status and wide, unrestricted distribution +- to educate students about quality typeface and font design +- to expand your test base and get more useful feedback +- to extend your reach to new markets when users see your metadata and go to your website +- to get your font more easily into one of the web font online services +- to attract attention for your commercial fonts +- to make money through web font services +- to make money by bundling fonts with applications +- to make money adjusting and extending existing open fonts +- to get a better chance that foundations/NGOs/charities/companies who commission fonts will pick you +- to be part of a sharing design and development community +- to give back and contribute to a growing body of font sources + + +5 CHOOSING RESERVED FONT NAMES + +5.1 What are Reserved Font Names? +These are font names, or portions of font names, that the author has chosen to reserve for use only with the Original Version of the font, or for Modified Version(s) created by the original author. + +5.2 Why can't I use the Reserved Font Names in my derivative font names? I'd like people to know where the design came from. +The best way to acknowledge the source of the design is to thank the original authors and any other contributors in the files that are distributed with your revised font (although no acknowledgement is required). The FONTLOG is a natural place to do this. Reserved Font Names ensure that the only fonts that have the original names are the unmodified Original Versions. This allows designers to maintain artistic integrity while allowing collaboration to happen. It eliminates potential confusion and name conflicts. When choosing a name, be creative and avoid names that reuse almost all the same letters in the same order or sound like the original. It will help everyone if Original Versions and Modified Versions can easily be distinguished from one another and from other derivatives. Any substitution and matching mechanism is outside the scope of the license. + +5.3 What do you mean by "primary name as presented to the user"? Are you referring to the font menu name? +Yes, this applies to the font menu name and other mechanisms that specify a font in a document. It would be fine, however, to keep a text reference to the original fonts in the description field, in your modified source file or in documentation provided alongside your derivative as long as no one could be confused that your modified source is the original. But you cannot use the Reserved Font Names in any way to identify the font to the user (unless the Copyright Holder(s) allow(s) it through a separate agreement). Users who install derivatives (Modified Versions) on their systems should not see any of the original Reserved Font Names in their font menus, for example. Again, this is to ensure that users are not confused and do not mistake one font for another and so expect features only another derivative or the Original Version can actually offer. + +5.4 Am I not allowed to use any part of the Reserved Font Names? +You may not use individual words from the Reserved Font Names, but you would be allowed to use parts of words, as long as you do not use any word from the Reserved Font Names entirely. We do not recommend using parts of words because of potential confusion, but it is allowed. For example, if "Foobar" was a Reserved Font Name, you would be allowed to use "Foo" or "bar", although we would not recommend it. Such an unfortunate choice would confuse the users of your fonts as well as make it harder for other designers to contribute. + +5.5 So what should I, as an author, identify as Reserved Font Names? +Original authors are encouraged to name their fonts using clear, distinct names, and only declare the unique parts of the name as Reserved Font Names. For example, the author of a font called "Foobar Sans" would declare "Foobar" as a Reserved Font Name, but not "Sans", as that is a common typographical term, and may be a useful word to use in a derivative font name. Reserved Font Names should also be single words for simplicity and legibility. A font called "Flowing River" should have Reserved Font Names "Flowing" and "River", not "Flowing River". You also need to be very careful about reserving font names which are already linked to trademarks (whether registered or not) which you do not own. + +5.6 Do I, as an author, have to identify any Reserved Font Names? +No. RFNs are optional and not required, but we encourage you to use them. This is primarily to avoid confusion between your work and Modified Versions. As an author you can release a font under the OFL and not declare any Reserved Font Names. There may be situations where you find that using no RFNs and letting your font be changed and modified - including any kind of modification - without having to change the original name is desirable. However you need to be fully aware of the consequences. There will be no direct way for end-users and other designers to distinguish your Original Version from many Modified Versions that may be created. You have to trust whoever is making the changes and the optimizations to not introduce problematic changes. The RFNs you choose for your own creation have value to you as an author because they allow you to maintain artistic integrity and keep some control over the distribution channel to your end-users. For discussion of RFNs and web fonts see section 2. + +5.7 Are any names (such as the main font name) reserved by default? +No. That is a change to the license as of version 1.1. If you want any names to be Reserved Font Names, they must be specified after the copyright statement(s). + +5.8 Is there any situation in which I can use Reserved Font Names for a Modified Version? +The Copyright Holder(s) can give certain trusted parties the right to use any of the Reserved Font Names through separate written agreements. For example, even if "Foobar" is a RFN, you could write up an agreement to give company "XYZ" the right to distribute a modified version with a name that includes "Foobar". This allows for freedom without confusion. The existence of such an agreement should be made as clear as possible to downstream users and designers in the distribution package and the relevant documentation. They need to know if they are a party to the agreement or not and what they are practically allowed to do or not even if all the details of the agreement are not public. + +5.9 Do font rebuilds require a name change? Do I have to change the name of the font when my packaging workflow includes a full rebuild from source? +Yes, all rebuilds which change the font data and the smart code are Modified Versions and the requirements of the OFL apply: you need to respect what the Author(s) have chosen in terms of Reserved Font Names. However if a package (or installer) is simply a wrapper or a compressed structure around the final font - leaving them intact on the inside - then no name change is required. Please get in touch with the author(s) and copyright holder(s) to inquire about the presence of font sources beyond the final font file(s) and the recommended build path. That build path may very well be non-trivial and hard to reproduce accurately by the maintainer. If a full font build path is made available by the upstream author(s) please be aware that any regressions and changes you may introduce when doing a rebuild for packaging purposes is your own responsibility as a package maintainer since you are effectively creating a separate branch. You should make it very clear to your users that your rebuilt version is not the canonical one from upstream. + +5.10 Can I add other Reserved Font Names when making a derivative font? +Yes. List your additional Reserved Font Names after your additional copyright statement, as indicated with example placeholders at the top of the OFL.txt file. Be sure you do not remove any existing RFNs but only add your own. RFN statements should be placed next to the copyright statement of the relevant author as indicated in the OFL.txt template to make them visible to designers wishing to make their separate version. + + +6 ABOUT THE FONTLOG + +6.1 What is this FONTLOG thing exactly? +It has three purposes: 1) to provide basic information on the font to users and other designers and developers, 2) to document changes that have been made to the font or accompanying files, either by the original authors or others, and 3) to provide a place to acknowledge authors and other contributors. Please use it! + +6.2 Is the FONTLOG required? +It is not a requirement of the license, but we strongly recommend you have one. + +6.3 Am I required to update the FONTLOG when making Modified Versions? +No, but users, designers and other developers might get very frustrated with you if you don't. People need to know how derivative fonts differ from the original, and how to take advantage of the changes, or build on them. There are utilities that can help create and maintain a FONTLOG, such as the FONTLOG support in FontForge. + +6.4 What should the FONTLOG look like? +It is typically a separate text file (FONTLOG.txt), but can take other formats. It commonly includes these four sections: + +- brief header describing the FONTLOG itself and name of the font family +- Basic Font Information - description of the font family, purpose and breadth +- ChangeLog - chronological listing of changes +- Acknowledgements - list of authors and contributors with contact information + +It could also include other sections, such as: where to find documentation, how to make contributions, information on contributing organizations, source code details, and a short design guide. See Appendix A for an example FONTLOG. + + +7 MAKING CONTRIBUTIONS TO OFL PROJECTS + +7.1 Can I contribute work to OFL projects? +In many cases, yes. It is common for OFL fonts to be developed by a team of people who welcome contributions from the wider community. Contact the original authors for specific information on how to participate in their projects. + +7.2 Why should I contribute my changes back to the original authors? +It would benefit many people if you contributed back in response to what you've received. Your contributions and improvements to the fonts and other components could be a tremendous help and would encourage others to contribute as well and 'give back'. You will then benefit from other people's contributions as well. Sometimes maintaining your own separate version takes more effort than merging back with the original. Be aware that any contributions, however, must be either your own original creation or work that you own, and you may be asked to affirm that clearly when you contribute. + +7.3 I've made some very nice improvements to the font. Will you consider adopting them and putting them into future Original Versions? +Most authors would be very happy to receive such contributions. Keep in mind that it is unlikely that they would want to incorporate major changes that would require additional work on their end. Any contributions would likely need to be made for all the fonts in a family and match the overall design and style. Authors are encouraged to include a guide to the design with the fonts. It would also help to have contributions submitted as patches or clearly marked changes - the use of smart source revision control systems like subversion, mercurial, git or bzr is a good idea. Please follow the recommendations given by the author(s) in terms of preferred source formats and configuration parameters for sending contributions. If this is not indicated in a FONTLOG or other documentation of the font, consider asking them directly. Examples of useful contributions are bug fixes, additional glyphs, stylistic alternates (and the smart font code to access them) or improved hinting. Keep in mind that some kinds of changes (esp. hinting) may be technically difficult to integrate. + +7.4 How can I financially support the development of OFL fonts? +It is likely that most authors of OFL fonts would accept financial contributions - contact them for instructions on how to do this. Such contributions would support future development. You can also pay for others to enhance the fonts and contribute the results back to the original authors for inclusion in the Original Version. + + +8 ABOUT THE LICENSE ITSELF + +8.1 I see that this is version 1.1 of the license. Will there be later changes? +Version 1.1 is the first minor revision of the OFL. We are confident that version 1.1 will meet most needs, but are open to future improvements. Any revisions would be for future font releases, and previously existing licenses would remain in effect. No retroactive changes are possible, although the Copyright Holder(s) can re-release the font under a revised OFL. All versions will be available on our web site: http://scripts.sil.org/OFL. + +8.2 Does this license restrict the rights of the Copyright Holder(s)? +No. The Copyright Holder(s) still retain(s) all the rights to their creation; they are only releasing a portion of it for use in a specific way. For example, the Copyright Holder(s) may choose to release a 'basic' version of their font under the OFL, but sell a restricted 'enhanced' version. Only the Copyright Holder(s) can do this. + +8.3 Is the OFL a contract or a license? +The OFL is a license and not a contract and so does not require you to sign it to have legal validity. By using, modifying and redistributing components under the OFL you indicate that you accept the license. + +8.4 I really like the terms of the OFL, but want to change it a little. Am I allowed to take ideas and actual wording from the OFL and put them into my own custom license for distributing my fonts? +We strongly recommend against creating your very own unique open licensing model. Using a modified or derivative license will likely cut you off - along with the font(s) under that license - from the community of designers using the OFL, potentially expose you and your users to legal liabilities, and possibly put your work and rights at risk. The OFL went though a community and legal review process that took years of effort, and that review is only applicable to an unmodified OFL. The text of the OFL has been written by SIL (with review and consultation from the community) and is copyright (c) 2005-2013 SIL International. You may re-use the ideas and wording (in part, not in whole) in another non-proprietary license provided that you call your license by another unambiguous name, that you do not use the preamble, that you do not mention SIL and that you clearly present your license as different from the OFL so as not to cause confusion by being too similar to the original. If you feel the OFL does not meet your needs for an open license, please contact us. + +8.5 Can I translate the license and the FAQ into other languages? +SIL certainly recognises the need for people who are not familiar with English to be able to understand the OFL and its use. Making the license very clear and readable has been a key goal for the OFL, but we know that people understand their own language best. + +If you are an experienced translator, you are very welcome to translate the OFL and OFL-FAQ so that designers and users in your language community can understand the license better. But only the original English version of the license has legal value and has been approved by the community. Translations do not count as legal substitutes and should only serve as a way to explain the original license. SIL - as the author and steward of the license for the community at large - does not approve any translation of the OFL as legally valid because even small translation ambiguities could be abused and create problems. + +SIL gives permission to publish unofficial translations into other languages provided that they comply with the following guidelines: + +- Put the following disclaimer in both English and the target language stating clearly that the translation is unofficial: + +"This is an unofficial translation of the SIL Open Font License into . It was not published by SIL International, and does not legally state the distribution terms for fonts that use the OFL. A release under the OFL is only valid when using the original English text. However, we recognize that this unofficial translation will help users and designers not familiar with English to better understand and use the OFL. We encourage designers who consider releasing their creation under the OFL to read the OFL-FAQ in their own language if it is available. Please go to http://scripts.sil.org/OFL for the official version of the license and the accompanying OFL-FAQ." + +- Keep your unofficial translation current and update it at our request if needed, for example if there is any ambiguity which could lead to confusion. + +If you start such a unofficial translation effort of the OFL and OFL-FAQ please let us know. + + +9 ABOUT SIL INTERNATIONAL + +9.1 Who is SIL International and what do they do? +SIL serves language communities worldwide, building their capacity for sustainable language development, by means of research, translation, training and materials development. SIL makes its services available to all without regard to religious belief, political ideology, gender, race, or ethnic background. SIL's members and volunteers share a Christian commitment. + +9.2 What does this have to do with font licensing? +The ability to read, write, type and publish in one's own language is one of the most critical needs for millions of people around the world. This requires fonts that are widely available and support lesser-known languages. SIL develops - and encourages others to develop - a complete stack of writing systems implementation components available under open licenses. This open stack includes input methods, smart fonts, smart rendering libraries and smart applications. There has been a need for a common open license that is specifically applicable to fonts and related software (a crucial component of this stack), so SIL developed the SIL Open Font License with the help of the Free/Libre and Open Source Software community. + +9.3 How can I contact SIL? +Our main web site is: http://www.sil.org/ +Our site about complex scripts is: http://scripts.sil.org/ +Information about this license (and contact information) is at: http://scripts.sil.org/OFL + + +APPENDIX A - FONTLOG EXAMPLE + +Here is an example of the recommended format for a FONTLOG, although other formats are allowed. + +----- +FONTLOG for the GlobalFontFamily fonts + +This file provides detailed information on the GlobalFontFamily Font Software. This information should be distributed along with the GlobalFontFamily fonts and any derivative works. + +Basic Font Information + +GlobalFontFamily is a Unicode typeface family that supports all languages that use the Latin script and its variants, and could be expanded to support other scripts. + +NewWorldFontFamily is based on the GlobalFontFamily and also supports Greek, Hebrew, Cyrillic and Armenian. + +More specifically, this release supports the following Unicode ranges... +This release contains... +Documentation can be found at... +To contribute to the project... + +ChangeLog + +10 December 2010 (Fred Foobar) GlobalFontFamily-devel version 1.4 +- fix new build and testing system (bug #123456) + +1 August 2008 (Tom Parker) GlobalFontFamily version 1.2.1 +- Tweaked the smart font code (Branch merged with trunk version) +- Provided improved build and debugging environment for smart behaviours + +7 February 2007 (Pat Johnson) NewWorldFontFamily Version 1.3 +- Added Greek and Cyrillic glyphs + +7 March 2006 (Fred Foobar) NewWorldFontFamily Version 1.2 +- Tweaked contextual behaviours + +1 Feb 2005 (Jane Doe) NewWorldFontFamily Version 1.1 +- Improved build script performance and verbosity +- Extended the smart code documentation +- Corrected minor typos in the documentation +- Fixed position of combining inverted breve below (U+032F) +- Added OpenType/Graphite smart code for Armenian +- Added Armenian glyphs (U+0531 -> U+0587) +- Released as "NewWorldFontFamily" + +1 Jan 2005 (Joe Smith) GlobalFontFamily Version 1.0 +- Initial release + +Acknowledgements + +If you make modifications be sure to add your name (N), email (E), web-address (if you have one) (W) and description (D). This list is in alphabetical order. + +N: Jane Doe +E: jane@university.edu +W: http://art.university.edu/projects/fonts +D: Contributor - Armenian glyphs and code + +N: Fred Foobar +E: fred@foobar.org +W: http://foobar.org +D: Contributor - misc Graphite fixes + +N: Pat Johnson +E: pat@fontstudio.org +W: http://pat.fontstudio.org +D: Designer - Greek & Cyrillic glyphs based on Roman design + +N: Tom Parker +E: tom@company.com +W: http://www.company.com/tom/projects/fonts +D: Engineer - original smart font code + +N: Joe Smith +E: joe@fontstudio.org +W: http://joe.fontstudio.org +D: Designer - original Roman glyphs + +Fontstudio.org is an not-for-profit design group whose purpose is... +Foobar.org is a distributed community of developers... +Company.com is a small business who likes to support community designers... +University.edu is a renowned educational institution with a strong design department... +----- + + diff --git a/html/wp-content/plugins/really-simple-captcha/gentium/OFL.txt b/html/wp-content/plugins/really-simple-captcha/gentium/OFL.txt new file mode 100644 index 0000000..022a807 --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/gentium/OFL.txt @@ -0,0 +1,94 @@ +Copyright (c) 2003-2013 SIL International (http://www.sil.org/), +with Reserved Font Names "Gentium" and "SIL". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/html/wp-content/plugins/really-simple-captcha/includes/filesystem.php b/html/wp-content/plugins/really-simple-captcha/includes/filesystem.php new file mode 100644 index 0000000..e0749a3 --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/includes/filesystem.php @@ -0,0 +1,107 @@ +filesystem = $wp_filesystem; + } else { + $this->filesystem = new WP_Filesystem_Direct( 1 ); + } + + if ( ! defined( 'FS_CHMOD_DIR' ) ) { + define( 'FS_CHMOD_DIR', fileperms( ABSPATH ) & 0777 | 0755 ); + } + + if ( ! defined( 'FS_CHMOD_FILE' ) ) { + define( 'FS_CHMOD_FILE', fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ); + } + } + + + /** + * Changes filesystem permissions. + * + * @param string $file Path to the file. + * @param int $mode The permissions as octal number. + * @param bool $recursive Optional. If set to true, changes + * file permissions recursively. Default false. + * @return bool True on success, false on failure. + */ + public function chmod( $file, $mode, $recursive = false ) { + return $this->filesystem->chmod( $file, $mode, $recursive ); + } + + + /** + * Deletes a file or directory. + * + * @param string $file Path to the file or directory. + * @param bool $recursive Optional. If set to true, deletes + * files and folders recursively. Default false. + * @param string|false $type Type of resource. + * 'f' for file, 'd' for directory. Default false. + * @return bool True on success, false on failure. + */ + public function delete( $file, $recursive = false, $type = false ) { + return $this->filesystem->delete( $file, $recursive, $type ); + } + + + /** + * Reads entire file into a string. + * + * @param string $file Path to the file. + * @return string|false Read data on success, false on failure. + */ + public function get_contents( $file ) { + return $this->filesystem->get_contents( $file ); + } + + + /** + * Writes a string to a file. + * + * @param string $file Path to the file where to write the data. + * @param string $contents The data to write. + * @param int $mode The file permissions as octal number. + * @return bool True on success, false on failure. + */ + public function put_contents( $file, $contents, $mode ) { + return $this->filesystem->put_contents( $file, $contents, $mode ); + } + +} diff --git a/html/wp-content/plugins/really-simple-captcha/license.txt b/html/wp-content/plugins/really-simple-captcha/license.txt new file mode 100644 index 0000000..6f15052 --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/license.txt @@ -0,0 +1,366 @@ +Really Simple CAPTCHA - WordPress Plugin, 2007-2025 Takayuki Miyoshi +Really Simple CAPTCHA is distributed under the terms of the GNU GPL + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Really Simple CAPTCHA WordPress Plugin bundles the following third-party resources: + +Gentium Basic Release 1.102 +Gentium is released under the SIL Open Font License +Source: https://software.sil.org/gentium/ + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/html/wp-content/plugins/really-simple-captcha/readme.txt b/html/wp-content/plugins/really-simple-captcha/readme.txt new file mode 100644 index 0000000..8f46a45 --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/readme.txt @@ -0,0 +1,100 @@ +=== Really Simple CAPTCHA === +Contributors: takayukister +Donate link: https://contactform7.com/donate/ +Tags: captcha +Requires at least: 6.6 +Tested up to: 6.7 +Stable tag: 2.4 +Requires PHP: 7.4 +License: GPLv2 or later +License URI: https://www.gnu.org/licenses/gpl-2.0.html + +Really Simple CAPTCHA is a CAPTCHA module intended to be called from other plugins. It is originally created for my Contact Form 7 plugin. + +== Description == + +Really Simple CAPTCHA does not work alone and is intended to work with other plugins. It is originally created for [Contact Form 7](https://contactform7.com/), however, you can use it with your own plugin. + +Note: This product is "really simple" as its name suggests, i.e., it is not strongly secure. If you need perfect security, you should try other solutions. + += How does it work? = + +Really Simple CAPTCHA does not use PHP "Sessions" for storing states, unlike many other PHP CAPTCHA solutions, but stores them as temporary files. This allows you to embed it into WordPress without worrying about conflicts. + +When you generate a CAPTCHA, Really Simple CAPTCHA creates two files for it; one is an image file of CAPTCHA, and the other is a text file which stores the correct answer to the CAPTCHA. + +The two files have the same (random) prefix in their file names, for example, "a7hk3ux8p.png" and "a7hk3ux8p.txt." In this case, for example, when the respondent answers "K5GF" as an answer to the "a7hk3ux8p.png" image, then Really Simple CAPTCHA calculates hash of "K5GF" and tests it against the hash stored in the "a7hk3ux8p.txt" file. If the two match, the answer is confirmed as correct. + += How to use with your plugin = + +Note: Below are instructions for plugin developers. + +First, create an instance of ReallySimpleCaptcha class: + + $captcha_instance = new ReallySimpleCaptcha(); + +You can change the instance variables as you wish. + + // Change the background color of CAPTCHA image to black + $captcha_instance->bg = array( 0, 0, 0 ); + +See really-simple-captcha.php if you are interested in other variables. + +Generate a random word for CAPTCHA. + + $word = $captcha_instance->generate_random_word(); + +Generate an image file and a corresponding text file in the temporary directory. + + $prefix = wp_rand(); + $captcha_instance->generate_image( $prefix, $word ); + +Then, show the image and get an answer from respondent. + +Check the correctness of the answer. + + $correct = $captcha_instance->check( $prefix, $the_answer_from_respondent ); + +If the $correct is true, go ahead. Otherwise, block the respondent -- as it would appear not to be human. + +And last, remove the temporary image and text files, as they are no longer in use. + + $captcha_instance->remove( $prefix ); + +That's all. + +If you wish to see a live sample of this, you can try [Contact Form 7](https://contactform7.com/captcha/). + +== Installation == + +In most cases you can install automatically from WordPress. + +However, if you install this manually, follow these steps: + +1. Upload the entire `really-simple-captcha` folder to the `/wp-content/plugins/` directory. +1. Activate the plugin through the 'Plugins' menu in WordPress. + +FYI: There is no "control panel" for this plugin. + +== Frequently Asked Questions == + += CAPTCHA does not work; the image does not show up. = + +Really Simple CAPTCHA needs GD and FreeType library installed on your server. Ask your server administrator if they are installed. + +Also, make the temporary file folder writable. The location of the temporary file folder is managed by the instance variable `tmp_dir` of ReallySimpleCaptcha class. Note that the setting varies depending on the calling plugin. For example, Contact Form 7 uses `wp-contents/uploads/wpcf7_captcha` as the temporary folder basically, but it can use different folder depending on your settings. + +If you have any further questions, please submit them [to the support forum](https://wordpress.org/support/plugin/really-simple-captcha). + +== Screenshots == + +1. screenshot-1.png + +== Changelog == + += 2.4 = + +* Bumps up the minimum required WordPress version to 6.6. +* Introduces the ReallySimpleCaptcha_Filesystem trait. +* Uses SHA-256 as the hash algorithm. +* Uses `wp_rand()` instead of `mt_rand()`. diff --git a/html/wp-content/plugins/really-simple-captcha/really-simple-captcha.php b/html/wp-content/plugins/really-simple-captcha/really-simple-captcha.php new file mode 100644 index 0000000..07a3f16 --- /dev/null +++ b/html/wp-content/plugins/really-simple-captcha/really-simple-captcha.php @@ -0,0 +1,389 @@ +connect(); + } + + + /** + * Generate and return a random word. + * + * @return string Random word with $chars characters x $char_length length + */ + public function generate_random_word() { + $word = ''; + + for ( $i = 0; $i < $this->char_length; $i++ ) { + $pos = wp_rand( 0, strlen( $this->chars ) - 1 ); + $char = $this->chars[$pos]; + $word .= $char; + } + + return $word; + } + + + /** + * Generate CAPTCHA image and corresponding answer file. + * + * @param string $prefix File prefix used for both files + * @param string $word Random word generated by generate_random_word() + * @return string|bool The file name of the CAPTCHA image. Return false if temp directory is not available. + */ + public function generate_image( $prefix, $word ) { + if ( ! $this->make_tmp_dir() ) { + return false; + } + + $this->cleanup(); + + $dir = trailingslashit( $this->tmp_dir ); + $filename = null; + + $im = imagecreatetruecolor( + $this->img_size[0], + $this->img_size[1] + ); + + if ( $im ) { + $bg = imagecolorallocate( $im, $this->bg[0], $this->bg[1], $this->bg[2] ); + $fg = imagecolorallocate( $im, $this->fg[0], $this->fg[1], $this->fg[2] ); + + imagefill( $im, 0, 0, $bg ); + + $x = $this->base[0] + wp_rand( -2, 2 ); + + for ( $i = 0; $i < strlen( $word ); $i++ ) { + $font = $this->fonts[array_rand( $this->fonts )]; + $font = wp_normalize_path( $font ); + + imagettftext( + $im, $this->font_size, wp_rand( -12, 12 ), $x, + $this->base[1] + wp_rand( -2, 2 ), $fg, $font, $word[$i] + ); + + $x += $this->font_char_width; + } + + switch ( $this->img_type ) { + case 'jpeg': + $filename = sanitize_file_name( $prefix . '.jpeg' ); + $file = wp_normalize_path( path_join( $dir, $filename ) ); + imagejpeg( $im, $file ); + break; + case 'gif': + $filename = sanitize_file_name( $prefix . '.gif' ); + $file = wp_normalize_path( path_join( $dir, $filename ) ); + imagegif( $im, $file ); + break; + case 'png': + default: + $filename = sanitize_file_name( $prefix . '.png' ); + $file = wp_normalize_path( path_join( $dir, $filename ) ); + imagepng( $im, $file ); + } + + imagedestroy( $im ); + + $this->chmod( $file, $this->file_mode ); + } + + $this->generate_answer_file( $prefix, $word ); + + return $filename; + } + + + /** + * Generate answer file corresponding to CAPTCHA image. + * + * @param string $prefix File prefix used for answer file + * @param string $word Random word generated by generate_random_word() + */ + public function generate_answer_file( $prefix, $word ) { + $dir = trailingslashit( $this->tmp_dir ); + $answer_file = path_join( $dir, sanitize_file_name( $prefix . '.txt' ) ); + $answer_file = wp_normalize_path( $answer_file ); + + $word = strtoupper( $word ); + $salt = wp_generate_password( 64 ); + $hash = hash_hmac( 'sha256', $word, $salt ); + $code = $salt . '|' . $hash; + + $this->put_contents( $answer_file, $code, $this->answer_file_mode ); + } + + + /** + * Check a response against the code kept in the temporary file. + * + * @param string $prefix File prefix used for both files + * @param string $response CAPTCHA response + * @return bool Return true if the two match, otherwise return false. + */ + public function check( $prefix, $response ) { + if ( 0 === strlen( $prefix ) ) { + return false; + } + + $response = str_replace( array( " ", "\t" ), '', $response ); + $response = strtoupper( $response ); + + $dir = trailingslashit( $this->tmp_dir ); + $filename = sanitize_file_name( $prefix . '.txt' ); + $file = wp_normalize_path( path_join( $dir, $filename ) ); + + if ( is_readable( $file ) and $code = $this->get_contents( $file ) ) { + $code = explode( '|', $code, 2 ); + $salt = $code[0]; + $hash = $code[1]; + + return hash_equals( $hash, hash_hmac( 'sha256', $response, $salt ) ); + } + + return false; + } + + + /** + * Remove temporary files with given prefix. + * + * @param string $prefix File prefix + */ + public function remove( $prefix ) { + $dir = trailingslashit( $this->tmp_dir ); + $suffixes = array( '.jpeg', '.gif', '.png', '.php', '.txt' ); + + foreach ( $suffixes as $suffix ) { + $filename = sanitize_file_name( $prefix . $suffix ); + $file = wp_normalize_path( path_join( $dir, $filename ) ); + + if ( is_file( $file ) ) { + $this->delete( $file ); + } + } + } + + + /** + * Clean up dead files older than given length of time. + * + * @param int $minutes Consider older files than this time as dead files + * @return int|bool The number of removed files. Return false if error occurred. + */ + public function cleanup( $minutes = 60, $max = 100 ) { + $dir = trailingslashit( $this->tmp_dir ); + $dir = wp_normalize_path( $dir ); + + if ( + ! is_dir( $dir ) or + ! is_readable( $dir ) or + ! wp_is_writable( $dir ) + ) { + return false; + } + + $count = 0; + + if ( $handle = opendir( $dir ) ) { + while ( false !== ( $filename = readdir( $handle ) ) ) { + if ( ! preg_match( '/^[0-9]+\.(php|txt|png|gif|jpeg)$/', $filename ) ) { + continue; + } + + $file = wp_normalize_path( path_join( $dir, $filename ) ); + + if ( ! file_exists( $file ) or ! $stat = stat( $file ) ) { + continue; + } + + if ( ( $stat['mtime'] + $minutes * MINUTE_IN_SECONDS ) < time() ) { + if ( ! $this->delete( $file ) ) { + $this->chmod( $file, 0644 ); + $this->delete( $file ); + } + + $count += 1; + } + + if ( $max <= $count ) { + break; + } + } + + closedir( $handle ); + } + + return $count; + } + + + /** + * Make a temporary directory and generate .htaccess file in it. + * + * @return bool True on successful create, false on failure. + */ + public function make_tmp_dir() { + $dir = trailingslashit( $this->tmp_dir ); + $dir = wp_normalize_path( $dir ); + + if ( ! wp_mkdir_p( $dir ) ) { + return false; + } + + $htaccess_file = wp_normalize_path( path_join( $dir, '.htaccess' ) ); + + if ( file_exists( $htaccess_file ) ) { + list( $first_line_comment ) = (array) file( + $htaccess_file, + FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES + ); + + if ( '# Apache 2.4+' === $first_line_comment ) { + return true; + } + } + + $htaccess_body = ' +# Apache 2.4+ + + Require all denied + + Require all granted + + + +# Apache 2.2 + + Order deny,allow + Deny from all + + Allow from all + + +'; + + return $this->put_contents( $htaccess_file, ltrim( $htaccess_body ), 0644 ); + } + +} diff --git a/htdocs/wp-content/themes/index.php b/html/wp-content/plugins/really-simple-captcha/tmp/index.php similarity index 100% rename from htdocs/wp-content/themes/index.php rename to html/wp-content/plugins/really-simple-captcha/tmp/index.php diff --git a/html/wp-content/plugins/s3-uploads/.phpcsignore b/html/wp-content/plugins/s3-uploads/.phpcsignore new file mode 100644 index 0000000..8596760 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/.phpcsignore @@ -0,0 +1,2 @@ +lib/ +psalm/ diff --git a/html/wp-content/plugins/s3-uploads/CHANGELOG.md b/html/wp-content/plugins/s3-uploads/CHANGELOG.md new file mode 100644 index 0000000..45b916e --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/CHANGELOG.md @@ -0,0 +1,7 @@ +# Changelog + +## 2.1.0-RC2 + +- Remove `lib/aws-sdk` from repository [#305](https://github.com/humanmade/S3-Uploads/pull/305) +- Fix delete files on delete attachment [#307](https://github.com/humanmade/S3-Uploads/pull/307) +- Fix Imagick with s3 compatibility [#306](https://github.com/humanmade/S3-Uploads/pull/306) diff --git a/html/wp-content/plugins/s3-uploads/LICENSE b/html/wp-content/plugins/s3-uploads/LICENSE new file mode 100644 index 0000000..19e05fc --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/LICENSE @@ -0,0 +1,92 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS diff --git a/html/wp-content/plugins/s3-uploads/README.md b/html/wp-content/plugins/s3-uploads/README.md new file mode 100644 index 0000000..c0b52d6 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/README.md @@ -0,0 +1,276 @@ + + + + + + + + + +
            + S3 Uploads
            + Lightweight "drop-in" for storing WordPress uploads on Amazon S3 instead of the local filesystem. +
            + + Psalm coverage + + + CI + + + + +
            + A Human Made project. Maintained by @joehoyle. + + +
            + +S3 Uploads is a WordPress plugin to store uploads on S3. S3 Uploads aims to be a lightweight "drop-in" for storing uploads on Amazon S3 instead of the local filesystem. + +It's focused on providing a highly robust S3 interface with no "bells and whistles", WP-Admin UI or much otherwise. It comes with some helpful WP-CLI commands for generating IAM users, listing files on S3 and Migrating your existing library to S3. + +## Requirements + +- PHP >= 7.4 +- WordPress >= 5.3 + +## Getting Set Up + +S3 Uploads requires installation via Composer: + +``` +composer require humanmade/s3-uploads +``` + +**Note:** [Composer's autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading) must be loaded before S3 Uploads is loaded. We recommend loading it in your `wp-config.php` before `wp-settings.php` is loaded as shown below. + +```php +require_once __DIR__ . '/vendor/autoload.php'; +``` + +## Configuration + +Once you've installed the plugin, add the following constants to your `wp-config.php`: + +```PHP +define( 'S3_UPLOADS_BUCKET', 'my-bucket' ); +define( 'S3_UPLOADS_REGION', '' ); // the s3 bucket region (excluding the rest of the URL) + +// You can set access key and secret directly: +define( 'S3_UPLOADS_KEY', '' ); +define( 'S3_UPLOADS_SECRET', '' ); + +// Or if using IAM instance profiles, you can use the instance's credentials: +define( 'S3_UPLOADS_USE_INSTANCE_PROFILE', true ); +``` +Please refer to this [Region list](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) for the S3_UPLOADS_REGION values. + +Use of path prefix after the bucket name is allowed and is optional. For example, if you want to upload all files to 'my-folder' inside a bucket called 'my-bucket', you can use: + +```PHP +define( 'S3_UPLOADS_BUCKET', 'my-bucket/my-folder' ); +``` + +Please refer to this document outlining [Best Practices for managing AWS access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#securing_access-keys) + +You must then enable the plugin. To do this via WP-CLI use command: + +``` +wp plugin activate S3-Uploads +``` + +The plugin name must match the directory you have cloned S3 Uploads into; +If you're using Composer, use +``` +wp plugin activate s3-uploads +``` + + +The next thing that you should do is to verify your setup. You can do this using the `verify` command +like so: + +``` +wp s3-uploads verify +``` + +You will need to create your IAM user yourself, or attach the necessary permissions to an existing user, you can output the policy via `wp s3-uploads generate-iam-policy` + + +## Listing files on S3 + +S3-Uploads comes with a WP-CLI command for listing files in the S3 bucket for debugging etc. + +``` +wp s3-uploads ls [] +``` + +## Uploading files to S3 + +If you have an existing media library with attachment files, use the below command to copy them all to S3 from local disk. + +``` +wp s3-uploads upload-directory [--verbose] +``` + +For example, to migrate your whole uploads directory to S3, you'd run: + +``` +wp s3-uploads upload-directory /path/to/uploads/ uploads +``` + +There is also an all purpose `cp` command for arbitrary copying to and from S3. + +``` +wp s3-uploads cp +``` + +Note: as either `` or `` can be S3 or local locations, you must specify the full S3 location via `s3://mybucket/mydirectory` for example `cp ./test.txt s3://mybucket/test.txt`. + +## Private Uploads + +WordPress (and therefore S3 Uploads) default behaviour is that all uploaded media files are publicly accessible. In certain cases which may not be desireable. S3 Uploads supports setting S3 Objects to a `private` ACL and providing temporarily signed URLs for all files that are marked as private. + +S3 Uploads does not make assumptions or provide UI for marking attachments as private, instead you should integrate the `s3_uploads_is_attachment_private` WordPress filter to control the behaviour. For example, to mark _all_ attachments as private: + +```php +add_filter( 's3_uploads_is_attachment_private', '__return_true' ); +``` + +Private uploads can be transitioned to public by calling `S3_Uploads::set_attachment_files_acl( $id, 'public-read' )` or vica-versa. For example: + +```php +S3_Uploads::get_instance()->set_attachment_files_acl( 15, 'public-read' ); +``` + +The default expiry for all private file URLs is 6 hours. You can modify this by using the `s3_uploads_private_attachment_url_expiry` WordPress filter. The value can be any string interpreted by `strtotime`. For example: + +```php +add_filter( 's3_uploads_private_attachment_url_expiry', function ( $expiry ) { + return '+1 hour'; +} ); +``` + +If you're using [Stream](https://wordpress.org/plugins/stream/) for audit logs, [S3 Uploads Audit](https://github.com/humanmade/s3-uploads-audit) is an add-on plugin which supports logging some S3 Uploads actions e.g any setting of ACL for files of an attachment. So you can install it for such audit functionality. + +## Cache Control + +You can define the default HTTP `Cache-Control` header for uploaded media using the +following constant: + +```PHP +define( 'S3_UPLOADS_HTTP_CACHE_CONTROL', 30 * 24 * 60 * 60 ); + // will expire in 30 days time +``` + +You can also configure the `Expires` header using the `S3_UPLOADS_HTTP_EXPIRES` constant +For instance if you wanted to set an asset to effectively not expire, you could +set the Expires header way off in the future. For example: + +```PHP +define( 'S3_UPLOADS_HTTP_EXPIRES', gmdate( 'D, d M Y H:i:s', time() + (10 * 365 * 24 * 60 * 60) ) .' GMT' ); + // will expire in 10 years time +``` + +## Default Behaviour + +As S3 Uploads is a plug and play plugin, activating it will start rewriting image URLs to S3, and also put +new uploads on S3. Sometimes this isn't required behaviour as a site owner may want to upload a large +amount of media to S3 using the `wp-cli` commands before enabling S3 Uploads to direct all uploads requests +to S3. In this case one can define the `S3_UPLOADS_AUTOENABLE` to `false`. For example, place the following +in your `wp-config.php`: + +```PHP +define( 'S3_UPLOADS_AUTOENABLE', false ); +``` + +To then enable S3 Uploads rewriting, use the wp-cli command: `wp s3-uploads enable` / `wp s3-uploads disable` +to toggle the behaviour. + +## URL Rewrites + +By default, S3 Uploads will use the canonical S3 URIs for referencing the uploads, i.e. `[bucket name].s3.amazonaws.com/uploads/[file path]`. If you want to use another URL to serve the images from (for instance, if you [wish to use S3 as an origin for CloudFlare](https://support.cloudflare.com/hc/en-us/articles/200168926-How-do-I-use-CloudFlare-with-Amazon-s-S3-Service-)), you should define `S3_UPLOADS_BUCKET_URL` in your `wp-config.php`: + +```PHP +// Define the base bucket URL (without trailing slash) +define( 'S3_UPLOADS_BUCKET_URL', 'https://your.origin.url.example/path' ); +``` +S3 Uploads' URL rewriting feature can be disabled if the current website does not require it, nginx proxy to s3 etc. In this case the plugin will only upload files to the S3 bucket. +```PHP +// disable URL rewriting alltogether +define( 'S3_UPLOADS_DISABLE_REPLACE_UPLOAD_URL', true ); +``` + +## S3 Object Permissions + +The object permission of files uploaded to S3 by this plugin can be controlled by setting the `S3_UPLOADS_OBJECT_ACL` +constant. The default setting if not specified is `public-read` to allow objects to be read by anyone. If you don't +want the uploads to be publicly readable then you can define `S3_UPLOADS_OBJECT_ACL` as one of `private` or `authenticated-read` +in you wp-config file: + +```PHP +// Set the S3 object permission to private +define('S3_UPLOADS_OBJECT_ACL', 'private'); +``` + +For more information on S3 permissions please see the Amazon S3 permissions documentation. + +## Custom Endpoints + +Depending on your requirements you may wish to use an alternative S3 compatible object storage system such as Minio, Ceph, +Digital Ocean Spaces, Scaleway and others. + +You can configure the endpoint by adding the following code to a file in the `wp-content/mu-plugins/` directory, for example `wp-content/mu-plugins/s3-endpoint.php`: + +```php +=8.0", + "composer/installers": "~1.0 || ^2.0", + "aws/aws-sdk-php": "^3.366" + }, + "require-dev": { + "phpunit/phpunit": "^9.6", + "pcov/clobber": "^2.0", + "vimeo/psalm": "^5.0", + "humanmade/psalm-plugin-wordpress": "^3.1", + "yoast/phpunit-polyfills": "^4.0" + }, + "scripts": { + "test": "./tests/run-tests.sh", + "check-types": "./vendor/bin/psalm" + }, + "config": { + "allow-plugins": { + "composer/installers": true + } + } +} diff --git a/html/wp-content/plugins/s3-uploads/composer.lock b/html/wp-content/plugins/s3-uploads/composer.lock new file mode 100644 index 0000000..828717d --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/composer.lock @@ -0,0 +1,5067 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "261083a32441a32c20b5d65e9ad03243", + "packages": [ + { + "name": "aws/aws-crt-php", + "version": "v1.2.7", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "support": { + "issues": "https://github.com/awslabs/aws-crt-php/issues", + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7" + }, + "time": "2024-10-18T22:15:13+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.371.0", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "80bafcdc7f22362e204f49c5adfea66e85939cc8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/80bafcdc7f22362e204f49c5adfea66e85939cc8", + "reference": "80bafcdc7f22362e204f49c5adfea66e85939cc8", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.2.3", + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/promises": "^2.0", + "guzzlehttp/psr7": "^2.4.5", + "mtdowling/jmespath.php": "^2.8.0", + "php": ">=8.1", + "psr/http-message": "^1.0 || ^2.0", + "symfony/filesystem": "^v5.4.45 || ^v6.4.3 || ^v7.1.0 || ^v8.0.0" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "composer/composer": "^2.7.8", + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-sockets": "*", + "phpunit/phpunit": "^9.6", + "psr/cache": "^2.0 || ^3.0", + "psr/simple-cache": "^2.0 || ^3.0", + "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0", + "yoast/phpunit-polyfills": "^2.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-pcntl": "To use client-side monitoring", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + }, + "exclude-from-classmap": [ + "src/data/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "support": { + "forum": "https://github.com/aws/aws-sdk-php/discussions", + "issues": "https://github.com/aws/aws-sdk-php/issues", + "source": "https://github.com/aws/aws-sdk-php/tree/3.371.0" + }, + "time": "2026-02-24T19:08:17+00:00" + }, + { + "name": "composer/installers", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/12fb2dfe5e16183de69e784a7b84046c43d97e8e", + "reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "composer/composer": "^1.10.27 || ^2.7", + "composer/semver": "^1.7.2 || ^3.4.0", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-phpunit": "^1", + "symfony/phpunit-bridge": "^7.1.1", + "symfony/process": "^5 || ^6 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-main": "2.x-dev" + }, + "plugin-modifies-install-path": true + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Starbug", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "concreteCMS", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "matomo", + "mediawiki", + "miaoxing", + "modulework", + "modx", + "moodle", + "osclass", + "pantheon", + "phpbb", + "piwik", + "ppi", + "processwire", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "tastyigniter", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-06-24T20:46:46+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.10.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2025-08-23T22:36:01+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "481557b130ef3790cf82b713667b43030dc9c957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.3.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2025-08-22T14:34:08+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "21dc724a0583619cd1652f673303492272778051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", + "reference": "21dc724a0583619cd1652f673303492272778051", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.8.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2025-08-23T21:21:41+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.33" + }, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" + }, + "time": "2024-09-04T18:46:31+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "d551b38811096d0be9c4691d406991b47c0c630a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a", + "reference": "d551b38811096d0be9c4691d406991b47c0c630a", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-11-27T13:27:24+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + } + ], + "packages-dev": [ + { + "name": "amphp/amp", + "version": "v2.6.5", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "d7dda98dae26e56f3f6fcfbf1c1f819c9a993207" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/d7dda98dae26e56f3f6fcfbf1c1f819c9a993207", + "reference": "d7dda98dae26e56f3f6fcfbf1c1f819c9a993207", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^7 | ^8 | ^9", + "react/promise": "^2", + "vimeo/psalm": "^3.12" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ], + "psr-4": { + "Amp\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "https://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v2.6.5" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-09-03T19:41:28+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.8.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc", + "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.4", + "friendsofphp/php-cs-fixer": "^2.3", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^6 || ^7 || ^8", + "psalm/phar": "^3.11.4" + }, + "type": "library", + "autoload": { + "files": [ + "lib/functions.php" + ], + "psr-4": { + "Amp\\ByteStream\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "https://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/v1.8.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-13T18:00:56+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.6", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=14" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" + }, + "time": "2026-02-07T07:09:04+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/23da848e1a2308728fe5fdddabf4be17ff9720c7", + "reference": "23da848e1a2308728fe5fdddabf4be17ff9720c7", + "shasum": "" + }, + "require": { + "php": "^8.4" + }, + "require-dev": { + "doctrine/coding-standard": "^14", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5.58" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.1.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2026-01-05T06:47:08+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.5.3", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/a9e113dbc7d849e35b8776da39edaf4313b7b6c9", + "reference": "a9e113dbc7d849e35b8776da39edaf4313b7b6c9", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "^3.1", + "vimeo/psalm": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.3" + }, + "time": "2024-04-30T00:40:11+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2025-08-14T07:29:31+00:00" + }, + { + "name": "humanmade/psalm-plugin-wordpress", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/psalm/psalm-plugin-wordpress.git", + "reference": "3f4689ad5264eee7b37121053cec810a3754f7e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/psalm/psalm-plugin-wordpress/zipball/3f4689ad5264eee7b37121053cec810a3754f7e4", + "reference": "3f4689ad5264eee7b37121053cec810a3754f7e4", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "php-stubs/wordpress-globals": "^0.2.0", + "php-stubs/wordpress-stubs": "^6.0", + "php-stubs/wp-cli-stubs": "^2.7", + "vimeo/psalm": "^5 || ^6", + "wp-hooks/wordpress-core": "^1.3.0" + }, + "require-dev": { + "humanmade/coding-standards": "^1.2", + "phpunit/phpunit": "^9.0", + "psalm/plugin-phpunit": "^0.18.4" + }, + "type": "psalm-plugin", + "extra": { + "psalm": { + "pluginClass": "PsalmWordPress\\Plugin" + } + }, + "autoload": { + "psr-4": { + "PsalmWordPress\\": [ + "." + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "kkmuffme", + "role": "Maintainer" + }, + { + "name": "Joe Hoyle", + "role": "Creator" + } + ], + "description": "WordPress stubs and plugin for Psalm static analysis.", + "support": { + "issues": "https://github.com/psalm/psalm-plugin-wordpress/issues", + "source": "https://github.com/psalm/psalm-plugin-wordpress" + }, + "time": "2024-04-01T10:36:11+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v4.5.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8e76efb98ee8b6afc54687045e1b8dba55ac76e5", + "reference": "8e76efb98ee8b6afc54687045e1b8dba55ac76e5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.5.0" + }, + "time": "2024-09-08T10:13:13+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.19.5", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.1" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.5" + }, + "time": "2025-12-06T11:45:25+00:00" + }, + { + "name": "pcov/clobber", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/krakjoe/pcov-clobber.git", + "reference": "4c30759e912e6e5d5bf833fb3d77b5bd51709f05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/krakjoe/pcov-clobber/zipball/4c30759e912e6e5d5bf833fb3d77b5bd51709f05", + "reference": "4c30759e912e6e5d5bf833fb3d77b5bd51709f05", + "shasum": "" + }, + "require": { + "ext-pcov": "^1.0", + "nikic/php-parser": "^4.2" + }, + "bin": [ + "bin/pcov" + ], + "type": "library", + "autoload": { + "psr-4": { + "pcov\\Clobber\\": "src/pcov/clobber" + } + }, + "notification-url": "https://packagist.org/downloads/", + "support": { + "issues": "https://github.com/krakjoe/pcov-clobber/issues", + "source": "https://github.com/krakjoe/pcov-clobber/tree/v2.0.3" + }, + "time": "2019-10-29T05:03:37+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "php-stubs/wordpress-globals", + "version": "v0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wordpress-globals.git", + "reference": "748a1fb2ae8fda94844bd0545935095dbf404b32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wordpress-globals/zipball/748a1fb2ae8fda94844bd0545935095dbf404b32", + "reference": "748a1fb2ae8fda94844bd0545935095dbf404b32", + "shasum": "" + }, + "require-dev": { + "php": "~7.1" + }, + "suggest": { + "php-stubs/wordpress-stubs": "Up-to-date WordPress function and class declaration stubs", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Global variables and global constants from WordPress core.", + "homepage": "https://github.com/php-stubs/wordpress-globals", + "keywords": [ + "PHPStan", + "constants", + "globals", + "static analysis", + "wordpress" + ], + "support": { + "issues": "https://github.com/php-stubs/wordpress-globals/issues", + "source": "https://github.com/php-stubs/wordpress-globals/tree/master" + }, + "time": "2020-01-13T06:12:59+00:00" + }, + { + "name": "php-stubs/wordpress-stubs", + "version": "v6.9.1", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wordpress-stubs.git", + "reference": "f12220f303e0d7c0844c0e5e957b0c3cee48d2f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/f12220f303e0d7c0844c0e5e957b0c3cee48d2f7", + "reference": "f12220f303e0d7c0844c0e5e957b0c3cee48d2f7", + "shasum": "" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "5.6.1" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "nikic/php-parser": "^5.5", + "php": "^7.4 || ^8.0", + "php-stubs/generator": "^0.8.3", + "phpdocumentor/reflection-docblock": "^6.0", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^9.5", + "symfony/polyfill-php80": "*", + "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^1.1.1", + "wp-coding-standards/wpcs": "3.1.0 as 2.3.0" + }, + "suggest": { + "paragonie/sodium_compat": "Pure PHP implementation of libsodium", + "symfony/polyfill-php80": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WordPress function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wordpress-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress" + ], + "support": { + "issues": "https://github.com/php-stubs/wordpress-stubs/issues", + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.9.1" + }, + "time": "2026-02-03T19:29:21+00:00" + }, + { + "name": "php-stubs/wp-cli-stubs", + "version": "v2.12.0", + "source": { + "type": "git", + "url": "https://github.com/php-stubs/wp-cli-stubs.git", + "reference": "af16401e299a3fd2229bd0fa9a037638a4174a9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-stubs/wp-cli-stubs/zipball/af16401e299a3fd2229bd0fa9a037638a4174a9d", + "reference": "af16401e299a3fd2229bd0fa9a037638a4174a9d", + "shasum": "" + }, + "require": { + "php-stubs/wordpress-stubs": "^4.7 || ^5.0 || ^6.0" + }, + "require-dev": { + "php": "~7.3 || ~8.0", + "php-stubs/generator": "^0.8.0" + }, + "suggest": { + "symfony/polyfill-php73": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "szepeviktor/phpstan-wordpress": "WordPress extensions for PHPStan" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "WP-CLI function and class declaration stubs for static analysis.", + "homepage": "https://github.com/php-stubs/wp-cli-stubs", + "keywords": [ + "PHPStan", + "static analysis", + "wordpress", + "wp-cli" + ], + "support": { + "issues": "https://github.com/php-stubs/wp-cli-stubs/issues", + "source": "https://github.com/php-stubs/wp-cli-stubs/tree/v2.12.0" + }, + "time": "2025-06-10T09:58:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.6.6", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.1", + "ext-filter": "*", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", + "webmozart/assert": "^1.9.1 || ^2" + }, + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6" + }, + "time": "2025-12-22T21:13:58+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.12.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + }, + "time": "2025-11-21T15:09:14+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" + }, + "time": "2026-01-25T14:56:51+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.32", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "9.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:23:01+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.34", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "b36f02317466907a230d3aa1d34467041271ef4a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a", + "reference": "b36f02317466907a230d3aa1d34467041271ef4a", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.5.0 || ^2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.32", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", + "sebastian/comparator": "^4.0.10", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.8", + "sebastian/global-state": "^5.0.8", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-01-27T05:45:00+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:27:43+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d", + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:22:56+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:19:30+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:30:58+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c", + "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:03:27+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6", + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" + } + ], + "time": "2025-08-10T07:10:35+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:20:34+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "539c6691e0623af6dc6f9c20384c120f963465a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0", + "reference": "539c6691e0623af6dc6f9c20384c120f963465a0", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-10T06:57:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-14T16:00:52+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "spatie/array-to-xml", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/array-to-xml.git", + "reference": "88b2f3852a922dd73177a68938f8eb2ec70c7224" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/88b2f3852a922dd73177a68938f8eb2ec70c7224", + "reference": "88b2f3852a922dd73177a68938f8eb2ec70c7224", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "pestphp/pest": "^1.21", + "spatie/pest-plugin-snapshots": "^1.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Spatie\\ArrayToXml\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://freek.dev", + "role": "Developer" + } + ], + "description": "Convert an array to xml", + "homepage": "https://github.com/spatie/array-to-xml", + "keywords": [ + "array", + "convert", + "xml" + ], + "support": { + "source": "https://github.com/spatie/array-to-xml/tree/3.4.4" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-12-15T09:00:41+00:00" + }, + { + "name": "symfony/console", + "version": "v7.4.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/41e38717ac1dd7a46b6bda7d6a82af2d98a78894", + "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2|^8.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-13T11:36:38+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T09:58:17+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:30:57+00:00" + }, + { + "name": "symfony/string", + "version": "v8.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "758b372d6882506821ed666032e43020c4f57194" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/758b372d6882506821ed666032e43020c4f57194", + "reference": "758b372d6882506821ed666032e43020c4f57194", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-intl-grapheme": "^1.33", + "symfony/polyfill-intl-normalizer": "^1.0", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v8.0.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-01-12T12:37:40+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" + }, + { + "name": "vimeo/psalm", + "version": "5.26.1", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", + "reference": "d747f6500b38ac4f7dfc5edbcae6e4b637d7add0", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.4.2", + "amphp/byte-stream": "^1.5", + "composer-runtime-api": "^2", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^2.0 || ^3.0", + "dnoegel/php-xdg-base-dir": "^0.1.1", + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.1", + "felixfbecker/language-server-protocol": "^1.5.2", + "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "nikic/php-parser": "^4.17", + "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "spatie/array-to-xml": "^2.17.0 || ^3.0", + "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0" + }, + "conflict": { + "nikic/php-parser": "4.17.0" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "amphp/phpunit-util": "^2.0", + "bamarni/composer-bin-plugin": "^1.4", + "brianium/paratest": "^6.9", + "ext-curl": "*", + "mockery/mockery": "^1.5", + "nunomaduro/mock-final-classes": "^1.1", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpdoc-parser": "^1.6", + "phpunit/phpunit": "^9.6", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18", + "slevomat/coding-standard": "^8.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/process": "^4.4 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "ext-curl": "In order to send data to shepherd", + "ext-igbinary": "^2.0.5 is required, used to serialize caching data" + }, + "bin": [ + "psalm", + "psalm-language-server", + "psalm-plugin", + "psalm-refactor", + "psalter" + ], + "type": "project", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev", + "dev-3.x": "3.x-dev", + "dev-4.x": "4.x-dev", + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\": "src/Psalm/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php", + "static analysis" + ], + "support": { + "docs": "https://psalm.dev/docs", + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm" + }, + "time": "2024-09-08T18:53:08+00:00" + }, + { + "name": "webmozart/assert", + "version": "2.1.5", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "79155f94852fa27e2f73b459f6503f5e87e2c188" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/79155f94852fa27e2f73b459f6503f5e87e2c188", + "reference": "79155f94852fa27e2f73b459f6503f5e87e2c188", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", + "php": "^8.2" + }, + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-feature/2-0": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/2.1.5" + }, + "time": "2026-02-18T14:09:36+00:00" + }, + { + "name": "wp-hooks/wordpress-core", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/wp-hooks/wordpress-core-hooks.git", + "reference": "610a3721216797daa72a16044c40938ac040551a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-hooks/wordpress-core-hooks/zipball/610a3721216797daa72a16044c40938ac040551a", + "reference": "610a3721216797daa72a16044c40938ac040551a", + "shasum": "" + }, + "replace": { + "johnbillion/wp-hooks": "*" + }, + "require-dev": { + "erusev/parsedown": "1.8.0-beta-7", + "oomphinc/composer-installers-extender": "^2", + "roots/wordpress-core-installer": "^1.0.0", + "roots/wordpress-full": "6.9", + "wp-hooks/generator": "1.0.0" + }, + "type": "library", + "extra": { + "wp-hooks": { + "ignore-files": [ + "wp-admin/includes/deprecated.php", + "wp-admin/includes/ms-deprecated.php", + "wp-content/", + "wp-includes/deprecated.php", + "wp-includes/ID3/", + "wp-includes/ms-deprecated.php", + "wp-includes/pomo/", + "wp-includes/random_compat/", + "wp-includes/Requests/", + "wp-includes/SimplePie/", + "wp-includes/sodium_compat/", + "wp-includes/Text/" + ], + "ignore-hooks": [ + "load-categories.php", + "load-edit-link-categories.php", + "load-edit-tags.php", + "load-page-new.php", + "load-page.php", + "option_enable_xmlrpc", + "edit_post_{$field}", + "pre_post_{$field}", + "post_{$field}", + "pre_option_enable_xmlrpc", + "$page_hook", + "$hook", + "$hook_name" + ] + }, + "wordpress-install-dir": "vendor/wordpress/wordpress" + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "John Blackbourn", + "homepage": "https://johnblackbourn.com/" + } + ], + "description": "All the actions and filters from WordPress core in machine-readable JSON format.", + "support": { + "issues": "https://github.com/wp-hooks/wordpress-core-hooks/issues", + "source": "https://github.com/wp-hooks/wordpress-core-hooks/tree/1.11.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/johnbillion", + "type": "github" + } + ], + "time": "2025-12-03T22:11:59+00:00" + }, + { + "name": "yoast/phpunit-polyfills", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", + "reference": "134921bfca9b02d8f374c48381451da1d98402f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/134921bfca9b02d8f374c48381451da1d98402f9", + "reference": "134921bfca9b02d8f374c48381451da1d98402f9", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0 || ^11.0 || ^12.0" + }, + "require-dev": { + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "yoast/yoastcs": "^3.1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "files": [ + "phpunitpolyfills-autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Team Yoast", + "email": "support@yoast.com", + "homepage": "https://yoast.com" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills/graphs/contributors" + } + ], + "description": "Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills", + "keywords": [ + "phpunit", + "polyfill", + "testing" + ], + "support": { + "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", + "security": "https://github.com/Yoast/PHPUnit-Polyfills/security/policy", + "source": "https://github.com/Yoast/PHPUnit-Polyfills" + }, + "time": "2025-02-09T18:58:54+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=8.0" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/html/wp-content/plugins/s3-uploads/inc/class-image-editor-imagick.php b/html/wp-content/plugins/s3-uploads/inc/class-image-editor-imagick.php new file mode 100644 index 0000000..052ad94 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/inc/class-image-editor-imagick.php @@ -0,0 +1,139 @@ +file into new Imagick Object. + * + * @return true|WP_Error True if loaded; WP_Error on failure. + */ + public function load() { + if ( $this->image instanceof Imagick ) { + return true; + } + + if ( $this->file !== null && $this->file !== '' && ! is_file( $this->file ) && ! preg_match( '|^https?://|', $this->file ) ) { + return new WP_Error( 'error_loading_image', __( 'File doesn’t exist?' ), $this->file ); + } + + $upload_dir = wp_upload_dir(); + + if ( $this->file === null || $this->file === '' || strpos( $this->file, $upload_dir['basedir'] ) !== 0 ) { + return parent::load(); + } + + $temp_filename = tempnam( get_temp_dir(), 's3-uploads' ); + $this->temp_files_to_cleanup[] = $temp_filename; + + copy( $this->file, $temp_filename ); + $this->remote_filename = $this->file; + $this->file = $temp_filename; + + $result = parent::load(); + + $this->file = $this->remote_filename; + return $result; + } + + /** + * Imagick by default can't handle s3:// paths + * for saving images. We have instead save it to a file file, + * then copy it to the s3:// path as a workaround. + * + * @param Imagick $image + * @param ?string $filename + * @param ?string $mime_type + * @return WP_Error|array{path: string, file: string, width: int, height: int, mime-type: string} + */ + protected function _save( $image, $filename = null, $mime_type = null ) { + list( $filename, $extension, $mime_type ) = $this->get_output_format( $filename, $mime_type ); + + if ( ! $filename ) { + $filename = $this->generate_filename( null, null, $extension ); + } + + $upload_dir = wp_upload_dir(); + + if ( strpos( $filename, $upload_dir['basedir'] ) === 0 ) { + $temp_filename = tempnam( get_temp_dir(), 's3-uploads' ); + } else { + $temp_filename = false; + } + + /** + * @var WP_Error|array{path: string, file: string, width: int, height: int, mime-type: string} + */ + $parent_call = parent::_save( $image, $temp_filename !== false ? $temp_filename : $filename, $mime_type ); + + if ( is_wp_error( $parent_call ) ) { + if ( $temp_filename !== false ) { + unlink( $temp_filename ); + } + + return $parent_call; + } else { + $save = $parent_call; + } + + $copy_result = copy( $save['path'], $filename ); + + unlink( $save['path'] ); + if ( $temp_filename !== false ) { + unlink( $temp_filename ); + } + + if ( ! $copy_result ) { + return new WP_Error( 'unable-to-copy-to-s3', 'Unable to copy the temp image to S3' ); + } + + $response = [ + 'path' => $filename, + 'file' => wp_basename( apply_filters( 'image_make_intermediate_size', $filename ) ), + 'width' => $this->size['width'] ?? 0, + 'height' => $this->size['height'] ?? 0, + 'mime-type' => $mime_type, + ]; + + return $response; + } + + public function __destruct() { + array_map( 'unlink', $this->temp_files_to_cleanup ); + parent::__destruct(); + } +} diff --git a/html/wp-content/plugins/s3-uploads/inc/class-local-stream-wrapper.php b/html/wp-content/plugins/s3-uploads/inc/class-local-stream-wrapper.php new file mode 100644 index 0000000..f246b6d --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/inc/class-local-stream-wrapper.php @@ -0,0 +1,572 @@ +get_original_upload_dir(); + return $upload_dir['basedir'] . '/s3'; + } + + function setUri( string $uri ) : void { + $this->uri = $uri; + } + + function getUri() : string { + return $this->uri ?? ''; + } + + /** + * Returns the local writable target of the resource within the stream. + * + * This function should be used in place of calls to realpath() or similar + * functions when attempting to determine the location of a file. While + * functions like realpath() may return the location of a read-only file, this + * method may return a URI or path suitable for writing that is completely + * separate from the URI used for reading. + * + * @param string $uri + * Optional URI. + * + * @return string + * Returns a string representing a location suitable for writing of a file, + * or FALSE if unable to write to the file such as with read-only streams. + */ + protected function getTarget( $uri = null ) : string { + if ( ! isset( $uri ) ) { + $uri = $this->uri ?? ''; + } + + $parts = explode( '://', $uri, 2 ); + $target = $parts[1] ?? ''; + + // Remove erroneous leading or trailing, forward-slashes and backslashes. + return trim( $target, '\/' ); + } + + /** + * Get mime type for URI + * + * @param string $uri + * @param array{extensions?: string[], mimetypes: array} $mapping + * @return string + */ + static function getMimeType( string $uri, ?array $mapping = null ) : string { + + $extension = ''; + $file_parts = explode( '.', basename( $uri ) ); + + // Remove the first part: a full filename should not match an extension. + array_shift( $file_parts ); + + // Iterate over the file parts, trying to find a match. + // For my.awesome.image.jpeg, we try: + // - jpeg + // - image.jpeg, and + // - awesome.image.jpeg + while ( $additional_part = array_pop( $file_parts ) ) { + $extension = strtolower( $additional_part . ( $extension ? '.' . $extension : '' ) ); + if ( isset( $mapping['extensions'][ $extension ] ) ) { + return $mapping['mimetypes'][ $mapping['extensions'][ $extension ] ]; + } + } + + return 'application/octet-stream'; + } + + function chmod( int $mode ) : bool { + $output = @chmod( $this->getLocalPath(), $mode ); // // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged + // We are modifying the underlying file here, so we have to clear the stat + // cache so that PHP understands that URI has changed too. + clearstatcache( true, $this->getLocalPath() ); + return $output; + } + + function realpath() : string { + return $this->getLocalPath(); + } + + /** + * Returns the canonical absolute path of the URI, if possible. + * + * @param string $uri + * (optional) The stream wrapper URI to be converted to a canonical + * absolute path. This may point to a directory or another type of file. + * + * @return string + * If $uri is not set, returns the canonical absolute path of the URI + * previously. If $uri is set and valid for this class, returns its canonical absolute + * path, as determined by the realpath() function. If $uri is set but not + * valid, returns empty string. + */ + protected function getLocalPath( $uri = null ) : string { + if ( ! isset( $uri ) ) { + $uri = $this->uri; + } + $path = $this->getDirectoryPath() . '/' . $this->getTarget( $uri ); + $realpath = str_replace( '/', DIRECTORY_SEPARATOR, $path ); // ensure check against realpath passes on Windows machines + + $directory = realpath( $this->getDirectoryPath() ); + + if ( $directory === false || strpos( $realpath, $directory ) !== 0 ) { + return ''; + } + return $realpath; + } + + /** + * Support for fopen(), file_get_contents(), file_put_contents() etc. + * + * @param string $uri + * A string containing the URI to the file to open. + * @param string $mode + * The file mode ("r", "wb" etc.). + * @param int $options + * A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS. + * @param string $opened_path + * A string containing the path actually opened. + * @param-out string $opened_path + * + * @return bool + * Returns TRUE if file was opened successfully. + * + * @see http://php.net/manual/streamwrapper.stream-open.php + */ + public function stream_open( $uri, $mode, $options, &$opened_path ) { + $this->uri = $uri; + $path = $this->getLocalPath(); + $this->handle = ( $options & STREAM_REPORT_ERRORS ) ? fopen( $path, $mode ) : @fopen( $path, $mode ); + + if ( (bool) $this->handle && $options & STREAM_USE_PATH ) { + $opened_path = $path; + } + + return (bool) $this->handle; + } + + /** + * Support for chmod(), chown(), etc. + * + * @return bool + * Returns TRUE on success or FALSE on failure. + * + * @see http://php.net/manual/streamwrapper.stream-metadata.php + */ + public function stream_metadata() { + return true; + } + + /** + * Support for flock(). + * + * @param int $operation + * One of the following: + * - LOCK_SH to acquire a shared lock (reader). + * - LOCK_EX to acquire an exclusive lock (writer). + * - LOCK_UN to release a lock (shared or exclusive). + * - LOCK_NB if you don't want flock() to block while locking (not + * supported on Windows). + * + * @return bool + * Always returns TRUE at the present time. + * + * @see http://php.net/manual/streamwrapper.stream-lock.php + */ + public function stream_lock( $operation ) { + if ( in_array( $operation, [ LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB ] ) && $this->handle ) { + return flock( $this->handle, $operation ); + } + + return true; + } + + /** + * Support for fread(), file_get_contents() etc. + * + * @param int $count + * Maximum number of bytes to be read. + * + * @return string|bool + * The string that was read, or FALSE in case of an error. + * + * @see http://php.net/manual/streamwrapper.stream-read.php + */ + public function stream_read( $count ) { + if ( ! $this->handle ) { + return false; + } + return fread( $this->handle, $count ); + } + + /** + * Support for fwrite(), file_put_contents() etc. + * + * @param string $data + * The string to be written. + * + * @return int + * The number of bytes written. + * + * @see http://php.net/manual/streamwrapper.stream-write.php + */ + public function stream_write( $data ) { + if ( ! $this->handle ) { + return 0; + } + return fwrite( $this->handle, $data ); + } + + /** + * Support for feof(). + * + * @return bool + * TRUE if end-of-file has been reached. + * + * @see http://php.net/manual/streamwrapper.stream-eof.php + */ + public function stream_eof() { + if ( ! $this->handle ) { + return false; + } + return feof( $this->handle ); + } + + /** + * Support for fseek(). + * + * @param int $offset + * The byte offset to got to. + * @param int $whence + * SEEK_SET, SEEK_CUR, or SEEK_END. + * + * @return bool + * TRUE on success. + * + * @see http://php.net/manual/streamwrapper.stream-seek.php + */ + public function stream_seek( $offset, $whence ) { + if ( ! $this->handle ) { + return false; + } + // fseek returns 0 on success and -1 on a failure. + // stream_seek 1 on success and 0 on a failure. + return ! fseek( $this->handle, $offset, $whence ); + } + + /** + * Support for fflush(). + * + * @return bool + * TRUE if data was successfully stored (or there was no data to store). + * + * @see http://php.net/manual/streamwrapper.stream-flush.php + */ + public function stream_flush() { + if ( ! $this->handle ) { + return false; + } + $result = fflush( $this->handle ); + + $params = [ + 'Bucket' => S3_UPLOADS_BUCKET, + 'Key' => trim( str_replace( S3_UPLOADS_BUCKET, '', $this->getTarget() ), '/' ), + ]; + + /** + * Action when a new object has been uploaded to s3. + * + * @param array $params S3Client::putObject parameters. + */ + do_action( 's3_uploads_putObject', $params ); + + return $result; + } + + /** + * Support for ftell(). + * + * @return false|int + * The current offset in bytes from the beginning of file. + * + * @see http://php.net/manual/streamwrapper.stream-tell.php + */ + public function stream_tell() { + if ( ! $this->handle ) { + return false; + } + return ftell( $this->handle ); + } + + /** + * Support for fstat(). + * + * @return array|false + * An array with file status, or FALSE in case of an error - see fstat() + * for a description of this array. + * + * @see http://php.net/manual/streamwrapper.stream-stat.php + */ + public function stream_stat() { + if ( ! $this->handle ) { + return false; + } + return fstat( $this->handle ); + } + + /** + * Support for fclose(). + * + * @return bool + * TRUE if stream was successfully closed. + * + * @see http://php.net/manual/streamwrapper.stream-close.php + */ + public function stream_close() { + if ( ! $this->handle ) { + return false; + } + $resource = $this->handle; + return fclose( $resource ); + } + + /** + * Gets the underlying stream resource for stream_select(). + * + * @param int $cast_as + * Can be STREAM_CAST_FOR_SELECT or STREAM_CAST_AS_STREAM. + * + * @return resource|false + * The underlying stream resource or FALSE if stream_select() is not + * supported. + * + * @see http://php.net/manual/streamwrapper.stream-cast.php + */ + public function stream_cast( $cast_as ) { + return false; + } + + /** + * Support for unlink(). + * + * @param string $uri + * A string containing the URI to the resource to delete. + * + * @return bool + * TRUE if resource was successfully deleted. + * + * @see http://php.net/manual/streamwrapper.unlink.php + */ + public function unlink( $uri ) { + $this->uri = $uri; + return unlink( $this->getLocalPath() ); + } + + /** + * Support for rename(). + * + * @param string $from_uri, + * The URI to the file to rename. + * @param string $to_uri + * The new URI for file. + * + * @return bool + * TRUE if file was successfully renamed. + * + * @see http://php.net/manual/streamwrapper.rename.php + */ + public function rename( $from_uri, $to_uri ) { + return rename( $this->getLocalPath( $from_uri ), $this->getLocalPath( $to_uri ) ); + } + + /** + * Support for mkdir(). + * + * @param string $uri + * A string containing the URI to the directory to create. + * @param int $mode + * Permission flags - see mkdir(). + * @param int $options + * A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE. + * + * @return bool + * TRUE if directory was successfully created. + * + * @see http://php.net/manual/streamwrapper.mkdir.php + */ + public function mkdir( $uri, $mode, $options ) { + $this->uri = $uri; + $recursive = (bool) ( $options & STREAM_MKDIR_RECURSIVE ); + if ( $recursive ) { + // $this->getLocalPath() fails if $uri has multiple levels of directories + // that do not yet exist. + $localpath = $this->getDirectoryPath() . '/' . $this->getTarget( $uri ); + } else { + $localpath = $this->getLocalPath( $uri ); + } + if ( $options & STREAM_REPORT_ERRORS ) { + return mkdir( $localpath, $mode, $recursive ); + } else { + return @mkdir( $localpath, $mode, $recursive ); + } + } + + /** + * Support for rmdir(). + * + * @param string $uri + * A string containing the URI to the directory to delete. + * @param int $options + * A bit mask of STREAM_REPORT_ERRORS. + * + * @return bool + * TRUE if directory was successfully removed. + * + * @see http://php.net/manual/streamwrapper.rmdir.php + */ + public function rmdir( $uri, $options ) { + $this->uri = $uri; + if ( $options & STREAM_REPORT_ERRORS ) { + return rmdir( $this->getLocalPath() ); + } else { + return @rmdir( $this->getLocalPath() ); + } + } + + /** + * Support for stat(). + * + * @param string $uri + * A string containing the URI to get information about. + * @param int $flags + * A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET. + * + * @return array + * An array with file status, or FALSE in case of an error - see fstat() + * for a description of this array. + * + * @see http://php.net/manual/streamwrapper.url-stat.php + */ + public function url_stat( $uri, $flags ) { + $this->uri = $uri; + $path = $this->getLocalPath(); + // Suppress warnings if requested or if the file or directory does not + // exist. This is consistent with PHP's plain filesystem stream wrapper. + if ( $flags & STREAM_URL_STAT_QUIET || ! file_exists( $path ) ) { + return @stat( $path ); + } else { + return stat( $path ); + } + } + + /** + * Support for opendir(). + * + * @param string $uri + * A string containing the URI to the directory to open. + * @param int $options + * Unknown (parameter is not documented in PHP Manual). + * + * @return bool + * TRUE on success. + * + * @see http://php.net/manual/streamwrapper.dir-opendir.php + */ + public function dir_opendir( $uri, $options ) { + $this->uri = $uri; + $this->handle = opendir( $this->getLocalPath() ); + + return (bool) $this->handle; + } + + /** + * Support for readdir(). + * + * @return string + * The next filename, or FALSE if there are no more files in the directory. + * + * @see http://php.net/manual/streamwrapper.dir-readdir.php + */ + public function dir_readdir() { + if ( ! $this->handle ) { + return ''; + } + return readdir( $this->handle ); + } + + /** + * Support for rewinddir(). + * + * @return bool + * TRUE on success. + * + * @see http://php.net/manual/streamwrapper.dir-rewinddir.php + */ + public function dir_rewinddir() { + if ( ! $this->handle ) { + return false; + } + rewinddir( $this->handle ); + // We do not really have a way to signal a failure as rewinddir() does not + // have a return value and there is no way to read a directory handler + // without advancing to the next file. + return true; + } + + /** + * Support for closedir(). + * + * @return bool + * TRUE on success. + * + * @see http://php.net/manual/streamwrapper.dir-closedir.php + */ + public function dir_closedir() { + if ( ! $this->handle ) { + return false; + } + closedir( $this->handle ); + // We do not really have a way to signal a failure as closedir() does not + // have a return value. + return true; + } +} diff --git a/html/wp-content/plugins/s3-uploads/inc/class-plugin.php b/html/wp-content/plugins/s3-uploads/inc/class-plugin.php new file mode 100644 index 0000000..3e40459 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/inc/class-plugin.php @@ -0,0 +1,691 @@ +bucket = $bucket; + $this->key = $key; + $this->secret = $secret; + $this->bucket_url = $bucket_url; + $this->region = $region; + } + + /** + * Setup the hooks, urls filtering etc for S3 Uploads + */ + public function setup() : void { + $this->register_stream_wrapper(); + + add_filter( 'upload_dir', [ $this, 'filter_upload_dir' ] ); + add_filter( 'wp_image_editors', [ $this, 'filter_editors' ], 9 ); + add_action( 'delete_attachment', [ $this, 'delete_attachment_files' ] ); + add_filter( 'wp_read_image_metadata', [ $this, 'wp_filter_read_image_metadata' ], 10, 2 ); + add_filter( 'wp_resource_hints', [ $this, 'wp_filter_resource_hints' ], 10, 2 ); + + add_filter( 'wp_handle_sideload_prefilter', [ $this, 'filter_sideload_move_temp_file_to_s3' ] ); + add_filter( 'wp_generate_attachment_metadata', [ $this, 'set_filesize_in_attachment_meta' ], 10, 2 ); + + add_filter( 'wp_get_attachment_url', [ $this, 'add_s3_signed_params_to_attachment_url' ], 10, 2 ); + add_filter( 'wp_get_attachment_image_src', [ $this, 'add_s3_signed_params_to_attachment_image_src' ], 10, 2 ); + add_filter( 'wp_calculate_image_srcset', [ $this, 'add_s3_signed_params_to_attachment_image_srcset' ], 10, 5 ); + + add_filter( 'wp_generate_attachment_metadata', [ $this, 'set_attachment_private_on_generate_attachment_metadata' ], 10, 2 ); + + add_filter( 'pre_wp_unique_filename_file_list', [ $this, 'get_files_for_unique_filename_file_list' ], 10, 3 ); + } + + /** + * Tear down the hooks, url filtering etc for S3 Uploads + */ + public function tear_down() : void { + + stream_wrapper_unregister( 's3' ); + remove_filter( 'upload_dir', [ $this, 'filter_upload_dir' ] ); + remove_filter( 'wp_image_editors', [ $this, 'filter_editors' ], 9 ); + remove_filter( 'wp_handle_sideload_prefilter', [ $this, 'filter_sideload_move_temp_file_to_s3' ] ); + remove_filter( 'wp_generate_attachment_metadata', [ $this, 'set_filesize_in_attachment_meta' ] ); + + remove_filter( 'wp_get_attachment_url', [ $this, 'add_s3_signed_params_to_attachment_url' ] ); + remove_filter( 'wp_get_attachment_image_src', [ $this, 'add_s3_signed_params_to_attachment_image_src' ] ); + remove_filter( 'wp_calculate_image_srcset', [ $this, 'add_s3_signed_params_to_attachment_image_srcset' ] ); + + remove_filter( 'wp_generate_attachment_metadata', [ $this, 'set_attachment_private_on_generate_attachment_metadata' ] ); + } + + /** + * Register the stream wrapper for s3 + */ + public function register_stream_wrapper() : void { + if ( defined( 'S3_UPLOADS_USE_LOCAL' ) && S3_UPLOADS_USE_LOCAL ) { + stream_wrapper_register( 's3', 'S3_Uploads\Local_Stream_Wrapper', STREAM_IS_URL ); + } else { + Stream_Wrapper::register( $this ); + $acl = defined( 'S3_UPLOADS_OBJECT_ACL' ) ? S3_UPLOADS_OBJECT_ACL : 'public-read'; + stream_context_set_option( stream_context_get_default(), 's3', 'ACL', $acl ); + } + + stream_context_set_option( stream_context_get_default(), 's3', 'seekable', true ); + } + + /** + * Get the s3:// path for the bucket. + */ + public function get_s3_path() : string { + return 's3://' . $this->bucket; + } + + /** + * Overwrite the default wp_upload_dir. + * + * @param array{path: string, basedir: string, baseurl: string, url: string, subdir: string, error: string|false} $dirs + * @return array{path: string, basedir: string, baseurl: string, url: string, subdir: string, error: string|false} + */ + public function filter_upload_dir( array $dirs ) : array { + + $this->original_upload_dir = $dirs; + $s3_path = $this->get_s3_path(); + + $dirs['path'] = str_replace( WP_CONTENT_DIR, $s3_path, $dirs['path'] ); + $dirs['basedir'] = str_replace( WP_CONTENT_DIR, $s3_path, $dirs['basedir'] ); + + if ( ! defined( 'S3_UPLOADS_DISABLE_REPLACE_UPLOAD_URL' ) || ! S3_UPLOADS_DISABLE_REPLACE_UPLOAD_URL ) { + + if ( defined( 'S3_UPLOADS_USE_LOCAL' ) && S3_UPLOADS_USE_LOCAL ) { + $dirs['url'] = str_replace( $s3_path, $dirs['baseurl'] . '/s3/' . $this->bucket, $dirs['path'] ); + $dirs['baseurl'] = str_replace( $s3_path, $dirs['baseurl'] . '/s3/' . $this->bucket, $dirs['basedir'] ); + + } else { + $dirs['url'] = str_replace( $s3_path, $this->get_s3_url(), $dirs['path'] ); + $dirs['baseurl'] = str_replace( $s3_path, $this->get_s3_url(), $dirs['basedir'] ); + } + } + + return $dirs; + } + + /** + * Delete all attachment files from S3 when an attachment is deleted. + * + * WordPress Core's handling of deleting files for attachments via + * wp_delete_attachment_files is not compatible with remote streams, as + * it makes many assumptions about local file paths. The hooks also do + * not exist to be able to modify their behavior. As such, we just clean + * up the s3 files when an attachment is removed, and leave WordPress to try + * a failed attempt at mangling the s3:// urls. + * + * @param int $post_id + */ + public function delete_attachment_files( int $post_id ) : void { + $meta = wp_get_attachment_metadata( $post_id ); + $file = get_attached_file( $post_id ); + if ( $file === false ) { + return; + } + + if ( isset( $meta['sizes'] ) ) { + foreach ( $meta['sizes'] as $sizeinfo ) { + $intermediate_file = str_replace( basename( $file ), $sizeinfo['file'], $file ); + wp_delete_file( $intermediate_file ); + } + } + + wp_delete_file( $file ); + } + + /** + * Get the S3 URL base for uploads. + * + * @return string + */ + public function get_s3_url() : string { + if ( $this->bucket_url !== null ) { + return $this->bucket_url; + } + + $bucket = strtok( $this->bucket, '/' ); + $path = substr( $this->bucket, strlen( $bucket ) ); + + return apply_filters( 's3_uploads_bucket_url', 'https://' . $bucket . '.s3.amazonaws.com' . $path ); + } + + /** + * Get the S3 bucket name + * + * @return string + */ + public function get_s3_bucket() : string { + return strtok( $this->bucket, '/' ); + } + + /** + * Get the region of the S3 bucket. + * + * @return string + */ + public function get_s3_bucket_region() : ?string { + return $this->region; + } + + /** + * Get the original upload directory before it was replaced by S3 uploads. + * + * @return array{path: string, basedir: string, baseurl: string, url: string, subdir: string, error: string|false} + */ + public function get_original_upload_dir() : array { + + if ( empty( $this->original_upload_dir ) ) { + wp_upload_dir(); + } + + /** + * @var array{path: string, basedir: string, baseurl: string, url: string, subdir: string, error: string|false} + */ + $upload_dir = $this->original_upload_dir; + return $upload_dir; + } + + /** + * Reverse a file url in the uploads directory to the params needed for S3. + * + * @param string $url + * @return array{bucket: string, key: string, query: string|null}|null + */ + public function get_s3_location_for_url( string $url ) : ?array { + $s3_url = 'https://' . $this->get_s3_bucket() . '.s3.amazonaws.com/'; + if ( strpos( $url, $s3_url ) === 0 ) { + $parsed = wp_parse_url( $url ); + return [ + 'bucket' => $this->get_s3_bucket(), + 'key' => isset( $parsed['path'] ) ? ltrim( $parsed['path'], '/' ) : '', + 'query' => $parsed['query'] ?? null, + ]; + } + $upload_dir = wp_upload_dir(); + + if ( strpos( $url, $upload_dir['baseurl'] ) === false ) { + return null; + } + + $path = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $url ); + $parsed = wp_parse_url( $path ); + if ( ! isset( $parsed['host'] ) || ! isset( $parsed['path'] ) ) { + return null; + } + return [ + 'bucket' => $parsed['host'], + 'key' => ltrim( $parsed['path'], '/' ), + 'query' => $parsed['query'] ?? null, + ]; + } + + /** + * Reverse a file path in the uploads directory to the params needed for S3. + * + * @param string $url + * @return array{key: string, bucket: string} + */ + public function get_s3_location_for_path( string $path ) : ?array { + $parsed = wp_parse_url( $path ); + if ( ! isset( $parsed['path'] ) || ! isset( $parsed['host'] ) || ! isset( $parsed['scheme'] ) || $parsed['scheme'] !== 's3' ) { + return null; + } + return [ + 'bucket' => $parsed['host'], + 'key' => ltrim( $parsed['path'], '/' ), + ]; + } + + /** + * @return Aws\S3\S3Client + */ + public function s3() : Aws\S3\S3Client { + + if ( ! empty( $this->s3 ) ) { + return $this->s3; + } + + $this->s3 = $this->get_aws_sdk()->createS3(); + return $this->s3; + } + + /** + * Get the AWS Sdk. + * + * @return Aws\Sdk + */ + public function get_aws_sdk() : Aws\Sdk { + /** @var null|Aws\Sdk */ + $sdk = apply_filters( 's3_uploads_aws_sdk', null, $this ); + if ( $sdk ) { + return $sdk; + } + + $params = [ 'version' => 'latest' ]; + + if ( $this->key !== null && $this->secret !== null ) { + $params['credentials']['key'] = $this->key; + $params['credentials']['secret'] = $this->secret; + } + + if ( $this->region !== null ) { + $params['signature'] = 'v4'; + $params['region'] = $this->region; + } + + if ( defined( 'WP_PROXY_HOST' ) && defined( 'WP_PROXY_PORT' ) ) { + $proxy_auth = ''; + $proxy_address = WP_PROXY_HOST . ':' . WP_PROXY_PORT; + + if ( defined( 'WP_PROXY_USERNAME' ) && defined( 'WP_PROXY_PASSWORD' ) ) { + $proxy_auth = WP_PROXY_USERNAME . ':' . WP_PROXY_PASSWORD . '@'; + } + + $params['request.options']['proxy'] = $proxy_auth . $proxy_address; + } + + $params = apply_filters( 's3_uploads_s3_client_params', $params ); + + $sdk = new Aws\Sdk( $params ); + return $sdk; + } + + public function filter_editors( array $editors ) : array { + $position = array_search( 'WP_Image_Editor_Imagick', $editors ); + if ( $position !== false ) { + unset( $editors[ $position ] ); + } + + array_unshift( $editors, __NAMESPACE__ . '\\Image_Editor_Imagick' ); + + return $editors; + } + /** + * Copy the file from /tmp to an s3 dir so handle_sideload doesn't fail due to + * trying to do a rename() on the file cross streams. This is somewhat of a hack + * to work around the core issue https://core.trac.wordpress.org/ticket/29257 + * + * @param array{tmp_name: string, name: string, type: string, size: int, error: int} $file File array + * @return array{tmp_name: string, name: string, type: string, size: int, error: int} + */ + public function filter_sideload_move_temp_file_to_s3( array $file ) { + $upload_dir = wp_upload_dir(); + $new_path = $upload_dir['basedir'] . '/tmp/' . basename( $file['tmp_name'] ); + + copy( $file['tmp_name'], $new_path ); + unlink( $file['tmp_name'] ); + $file['tmp_name'] = $new_path; + + return $file; + } + + /** + * Store the attachment filesize in the attachment meta array. + * + * Getting the filesize of an image in S3 involves a remote HEAD request, + * which is a bit slower than a local filesystem operation would be. As a + * result, operations like `wp_prepare_attachments_for_js' take substantially + * longer to complete against s3 uploads than if they were performed with a + * local filesystem.i + * + * Saving the filesize in the attachment metadata when the image is + * uploaded allows core to skip this stat when retrieving and formatting it. + * + * @param array $metadata Attachment metadata. + * @param int $attachment_id Attachment ID. + * @return array Attachment metadata array, with "filesize" value added. + */ + function set_filesize_in_attachment_meta( array $metadata, int $attachment_id ) : array { + $file = get_attached_file( $attachment_id ); + if ( $file === false ) { + return $metadata; + } + if ( ! isset( $metadata['filesize'] ) && file_exists( $file ) ) { + $metadata['filesize'] = filesize( $file ); + } + + return $metadata; + } + + /** + * Filters wp_read_image_metadata. exif_read_data() doesn't work on + * file streams so we need to make a temporary local copy to extract + * exif data from. + * + * @param array $meta + * @param string $file + * @return array|false + */ + public function wp_filter_read_image_metadata( array $meta, string $file ) { + remove_filter( 'wp_read_image_metadata', [ $this, 'wp_filter_read_image_metadata' ], 10 ); + $temp_file = $this->copy_image_from_s3( $file ); + $meta = wp_read_image_metadata( $temp_file ); + add_filter( 'wp_read_image_metadata', [ $this, 'wp_filter_read_image_metadata' ], 10, 2 ); + unlink( $temp_file ); + return $meta; + } + + /** + * Add the DNS address for the S3 Bucket to list for DNS prefetch. + * + * @param array $hints + * @param string $relation_type + * @return array + */ + function wp_filter_resource_hints( array $hints, string $relation_type ) : array { + if ( + ( defined( 'S3_UPLOADS_DISABLE_REPLACE_UPLOAD_URL' ) && S3_UPLOADS_DISABLE_REPLACE_UPLOAD_URL ) || + ( defined( 'S3_UPLOADS_USE_LOCAL' ) && S3_UPLOADS_USE_LOCAL ) + ) { + return $hints; + } + + if ( 'dns-prefetch' === $relation_type ) { + $hints[] = $this->get_s3_url(); + } + + return $hints; + } + + /** + * Get a local copy of the file. + * + * @param string $file + * @return string + */ + public function copy_image_from_s3( string $file ) : string { + if ( ! function_exists( 'wp_tempnam' ) ) { + require_once( ABSPATH . 'wp-admin/includes/file.php' ); + } + $temp_filename = wp_tempnam( $file ); + copy( $file, $temp_filename ); + return $temp_filename; + } + + /** + * Check if the attachment is private. + * + * @param integer $attachment_id + * @return boolean + */ + public function is_private_attachment( int $attachment_id ) : bool { + /** + * Filters whether an attachment should be private. + * + * @param bool Whether the attachment is private. + * @param int The attachment ID. + */ + $private = apply_filters( 's3_uploads_is_attachment_private', false, $attachment_id ); + return $private; + } + + /** + * Update the ACL (Access Control List) for an attachments files. + * + * @param integer $attachment_id + * @param 'public-read'|'private' $acl public-read|private + * @return WP_Error|null + */ + public function set_attachment_files_acl( int $attachment_id, string $acl ) : ?WP_Error { + $files = static::get_attachment_files( $attachment_id ); + $locations = array_map( [ $this, 'get_s3_location_for_path' ], $files ); + // Remove any null items in the array from get_s3_location_for_path(). + $locations = array_filter( $locations ); + $s3 = $this->s3(); + $commands = []; + foreach ( $locations as $location ) { + $commands[] = $s3->getCommand( 'putObjectAcl', [ + 'Bucket' => $location['bucket'], + 'Key' => $location['key'], + 'ACL' => $acl, + ] ); + } + + try { + Aws\CommandPool::batch( $s3, $commands ); + } catch ( Exception $e ) { + return new WP_Error( $e->getCode(), $e->getMessage() ); + } + + /** + * Fires after ACL of files of an attachment is set. + * + * @param int $attachment_id Attachment whose ACL has been changed. + * @param string $acl The new ACL that's been set. + * @psalm-suppress TooManyArguments -- Currently do_action doesn't detect variable number of arguments. + */ + do_action( 's3_uploads_set_attachment_files_acl', $attachment_id, $acl ); + + return null; + } + + /** + * Get all the files stored for a given attachment. + * + * @param integer $attachment_id + * @return list Array of all full paths to the attachment's files. + */ + public static function get_attachment_files( int $attachment_id ) : array { + /** @var string */ + $main_file = get_attached_file( $attachment_id ); + $main_file_directory = dirname( $main_file ); + $files = [ $main_file ]; + + $meta = wp_get_attachment_metadata( $attachment_id ); + if ( isset( $meta['sizes'] ) ) { + foreach ( $meta['sizes'] as $size => $sizeinfo ) { + $files[] = $main_file_directory . '/' . $sizeinfo['file']; + } + } + + /** @var string|false */ + $original_image = get_post_meta( $attachment_id, 'original_image', true ); + if ( $original_image !== false && $original_image !== '' ) { + $files[] = $main_file_directory . '/' . $original_image; + } + + /** @var array */ + $backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true ); + if ( $backup_sizes ) { + foreach ( $backup_sizes as $size => $sizeinfo ) { + // Backup sizes only store the backup filename, which is relative to the + // main attached file, unlike the metadata sizes array. + $files[] = $main_file_directory . '/' . $sizeinfo['file']; + } + } + + $files = apply_filters( 's3_uploads_get_attachment_files', $files, $attachment_id ); + + return $files; + } + + /** + * Add the S3 signed params onto an image for for a given attachment. + * + * This function determines whether the attachment needs a signed URL, so is safe to + * pass any URL. + * + * @param string $url + * @param integer $post_id + * @return string + */ + public function add_s3_signed_params_to_attachment_url( string $url, int $post_id ) : string { + if ( ! $this->is_private_attachment( $post_id ) ) { + return $url; + } + $path = $this->get_s3_location_for_url( $url ); + if ( ! $path ) { + return $url; + } + $cmd = $this->s3()->getCommand( + 'GetObject', + [ + 'Bucket' => $path['bucket'], + 'Key' => $path['key'], + ] + ); + + $presigned_url_expires = apply_filters( 's3_uploads_private_attachment_url_expiry', '+6 hours', $post_id ); + $query = $this->s3()->createPresignedRequest( $cmd, $presigned_url_expires )->getUri()->getQuery(); + + // The URL could have query params on it already (such as being an already signed URL), + // but query params will mean the S3 signed URL will become corrupt. So, we have to + // remove all query params. + $url = strtok( $url, '?' ) . '?' . $query; + $url = apply_filters( 's3_uploads_presigned_url', $url, $post_id ); + + return $url; + } + + /** + * Add the S3 signed params to an image src array. + * + * @param array{0: string, 1: int, 2: int}|false $image + * @param integer|"" $post_id The post id, due to WordPress hook, this can be "", so can't just hint as int. + * @return array{0: string, 1: int, 2: int}|false + */ + public function add_s3_signed_params_to_attachment_image_src( $image, $post_id ) { + if ( $image === false || $post_id === '' || $post_id === 0 ) { + return $image; + } + + $image[0] = $this->add_s3_signed_params_to_attachment_url( $image[0], $post_id ); + return $image; + } + + /** + * Add the S3 signed params to the image srcset (response image) sizes. + * + * @param array{url: string, descriptor: string, value: int}[] $sources + * @param array $sizes + * @param string $src + * @param array $meta + * @param integer $post_id + * @return array{url: string, descriptor: string, value: int}[] + */ + public function add_s3_signed_params_to_attachment_image_srcset( array $sources, array $sizes, string $src, array $meta, int $post_id ) : array { + foreach ( $sources as &$source ) { + $source['url'] = $this->add_s3_signed_params_to_attachment_url( $source['url'], $post_id ); + } + return $sources; + } + + /** + * Whenever attachment metadata is generated, set the attachment files to private if it's a private attachment. + * + * @param array $metadata The attachment metadata. + * @param int $attachment_id The attachment ID + * @return array + */ + public function set_attachment_private_on_generate_attachment_metadata( array $metadata, int $attachment_id ) : array { + if ( $this->is_private_attachment( $attachment_id ) ) { + $this->set_attachment_files_acl( $attachment_id, 'private' ); + } + + return $metadata; + } + + /** + * Override the files used for wp_unique_filename() comparisons + * + * @param array|null $files + * @param string $dir + * @return array + */ + public function get_files_for_unique_filename_file_list( ?array $files, string $dir, string $filename ) : array { + $name = pathinfo( $filename, PATHINFO_FILENAME ); + // The s3:// streamwrapper support listing by partial prefixes with wildcards. + // For example, scandir( s3://bucket/2019/06/my-image* ) + $scandir = scandir( trailingslashit( $dir ) . $name . '*' ); + if ( $scandir === false ) { + $scandir = []; // Set as empty array for return + } + return $scandir; + } +} diff --git a/html/wp-content/plugins/s3-uploads/inc/class-stream-wrapper.php b/html/wp-content/plugins/s3-uploads/inc/class-stream-wrapper.php new file mode 100644 index 0000000..e6a2499 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/inc/class-stream-wrapper.php @@ -0,0 +1,1229 @@ +/" files with PHP + * streams, supporting "r", "w", "a", "x". + * + * # Opening "r" (read only) streams: + * + * Read only streams are truly streaming by default and will not allow you to + * seek. This is because data read from the stream is not kept in memory or on + * the local filesystem. You can force a "r" stream to be seekable by setting + * the "seekable" stream context option true. This will allow true streaming of + * data from Amazon S3, but will maintain a buffer of previously read bytes in + * a 'php://temp' stream to allow seeking to previously read bytes from the + * stream. + * + * You may pass any GetObject parameters as 's3' stream context options. These + * options will affect how the data is downloaded from Amazon S3. + * + * # Opening "w" and "x" (write only) streams: + * + * Because Amazon S3 requires a Content-Length header, write only streams will + * maintain a 'php://temp' stream to buffer data written to the stream until + * the stream is flushed (usually by closing the stream with fclose). + * + * You may pass any PutObject parameters as 's3' stream context options. These + * options will affect how the data is uploaded to Amazon S3. + * + * When opening an "x" stream, the file must exist on Amazon S3 for the stream + * to open successfully. + * + * # Opening "a" (write only append) streams: + * + * Similar to "w" streams, opening append streams requires that the data be + * buffered in a "php://temp" stream. Append streams will attempt to download + * the contents of an object in Amazon S3, seek to the end of the object, then + * allow you to append to the contents of the object. The data will then be + * uploaded using a PutObject operation when the stream is flushed (usually + * with fclose). + * + * You may pass any GetObject and/or PutObject parameters as 's3' stream + * context options. These options will affect how the data is downloaded and + * uploaded from Amazon S3. + * + * Stream context options: + * + * - "seekable": Set to true to create a seekable "r" (read only) stream by + * using a php://temp stream buffer + * - For "unlink" only: Any option that can be passed to the DeleteObject + * operation + * + * @psalm-type StatArray = array{0: int, 1: int, 2: int|string, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int|string, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int} + * @psalm-type S3ObjectResultArray = array{ContentLength: int, Size: int, LastModified: string, Key: string, Prefix?: string} + * @psalm-type OptionsArray = array{plugin?: Plugin, cache?: CacheInterface, client?: S3ClientInterface, Bucket: string, Key: string|null, acl: string, seekable?: bool, ACL?: string, ContentType?: string, Body?: StreamInterface, Expires?: string, CacheControl?: string} + */ +class Stream_Wrapper { + + /** @var ?resource Stream context (this is set by PHP) */ + public $context; + + /** @var ?StreamInterface Underlying stream resource */ + private $body; + + /** @var ?int Size of the body that is opened */ + private $size; + + /** @var array Hash of opened stream parameters */ + private $params = []; + + /** @var ?string Mode in which the stream was opened */ + private $mode; + + /** @var ?\Iterator Iterator used with opendir() related calls */ + private $objectIterator; + + /** @var ?string The bucket that was opened when opendir() was called */ + private $openedBucket; + + /** @var ?string The prefix of the bucket that was opened with opendir() */ + private $openedBucketPrefix; + + /** @var ?string Opened bucket path */ + private $openedPath; + + /** @var ?CacheInterface Cache for object and dir lookups */ + private $cache; + + /** @var string The opened protocol (e.g., "s3") */ + private $protocol = 's3'; + + /** + * Register the 's3://' stream wrapper + * + * @param S3ClientInterface $client Client to use with the stream wrapper + * @param string $protocol Protocol to register as. + * @param CacheInterface $cache Default cache for the protocol. + */ + public static function register( + Plugin $plugin, + $protocol = 's3', + ?CacheInterface $cache = null + ) : void { + if ( in_array( $protocol, stream_get_wrappers() ) ) { + stream_wrapper_unregister( $protocol ); + } + + // Set the client passed in as the default stream context client + stream_wrapper_register( $protocol, get_called_class(), STREAM_IS_URL ); + /** @var array{s3: array} */ + $default = stream_context_get_options( stream_context_get_default() ); + $default[ $protocol ]['plugin'] = $plugin; + + if ( $cache ) { + $default[ $protocol ]['cache'] = $cache; + } elseif ( ! isset( $default[ $protocol ]['cache'] ) ) { + // Set a default cache adapter. + $default[ $protocol ]['cache'] = new LruArrayCache(); + } + + stream_context_set_default( $default ); + } + + public function stream_close() : void { + $this->body = null; + $this->cache = null; + } + + /** + * Undocumented function + * + * @param string $path + * @param string $mode + * @param array $options + * @param string $opened_path + * @return bool + */ + public function stream_open( $path, $mode, $options, &$opened_path ) { + $this->initProtocol( $path ); + $this->params = $this->getBucketKey( $path ); + $this->mode = rtrim( $mode, 'bt' ); + + $errors = $this->validate( $path, $this->mode ); + if ( $errors ) { + return $this->triggerError( $errors ); + } + + return $this->boolCall( + function() : bool { + switch ( $this->mode ) { + case 'r': + return $this->openReadStream(); + case 'a': + return $this->openAppendStream(); + default: + /** + * As we open a temp stream, we don't actually know if we have writing ability yet. + * This means functions like copy() will not fail correctly, as the write to s3 + * is only attempted on stream_flush() which is too late to report to copy() + * et al that the write has failed. + * + * As a work around, we attempt to write an empty object. + * + * Added by Joe Hoyle + */ + try { + $p = $this->params; + $p['Body'] = ''; + $p = apply_filters( 's3_uploads_putObject_params', $p ); + $this->getClient()->putObject( $p ); + } catch ( Exception $e ) { + return $this->triggerError( $e->getMessage() ); + } + + return $this->openWriteStream(); + } + } + ); + } + + public function stream_eof() : bool { + if ( ! $this->body ) { + return true; + } + return $this->body->eof(); + } + + public function stream_flush() : bool { + if ( $this->mode == 'r' ) { + return false; + } + + if ( ! $this->body ) { + return false; + } + + if ( $this->body->isSeekable() ) { + $this->body->seek( 0 ); + } + $params = $this->getOptions( true ); + $params['Body'] = $this->body; + + // Attempt to guess the ContentType of the upload based on the + // file extension of the key. Added by Joe Hoyle + if ( ! isset( $params['ContentType'] ) && $params['Key'] !== null && $params['Key'] !== '' ) { + $mime = MimeType::fromFilename( $params['Key'] ); + if ( $mime !== null ) { + $params['ContentType'] = $mime; + } + } + + /// Expires: + if ( defined( 'S3_UPLOADS_HTTP_EXPIRES' ) ) { + $params['Expires'] = S3_UPLOADS_HTTP_EXPIRES; + } + // Cache-Control: + if ( defined( 'S3_UPLOADS_HTTP_CACHE_CONTROL' ) ) { + /** + * @psalm-suppress RedundantCondition + */ + if ( is_numeric( S3_UPLOADS_HTTP_CACHE_CONTROL ) ) { + $params['CacheControl'] = 'max-age=' . S3_UPLOADS_HTTP_CACHE_CONTROL; + } else { + $params['CacheControl'] = S3_UPLOADS_HTTP_CACHE_CONTROL; + } + } + + /** + * Filter the parameters passed to S3 + * Theses are the parameters passed to S3Client::putObject() + * See; http://docs.aws.amazon.com/aws-sdk-php/latest/class-Aws.S3.S3Client.html#_putObject + * + * @param array $params S3Client::putObject parameters. + */ + $params = apply_filters( 's3_uploads_putObject_params', $params ); + + /** @var OptionsArray $params */ + $this->clearCacheKey( "s3://{$params['Bucket']}/{$params['Key']}" ); + return $this->boolCall( + function () use ( $params ) { + $bool = (bool) $this->getClient()->putObject( $params ); + + /** + * Action when a new object has been uploaded to s3. + * + * @param array $params S3Client::putObject parameters. + */ + do_action( 's3_uploads_putObject', $params ); + + return $bool; + } + ); + } + + public function stream_read( int $count ) : ?string { + if ( ! $this->body ) { + return null; + } + return $this->body->read( $count ); + } + + public function stream_seek( int $offset, int $whence = SEEK_SET ) : bool { + if ( ! $this->body ) { + return false; + } + return ! $this->body->isSeekable() + ? false + : $this->boolCall( + function () use ( $offset, $whence ) { + if ( ! $this->body ) { + return false; + } + $this->body->seek( $offset, $whence ); + return true; + } + ); + } + + /** + * @param string $path + * @param mixed $option + * @param mixed $value + * @return boolean + */ + public function stream_metadata( string $path, $option, $value ) : bool { + return false; + } + + /** + * @return bool|int + */ + public function stream_tell() { + return $this->boolCall( + function() { + if ( ! $this->body ) { + return false; + } + return $this->body->tell(); + } + ); + } + + public function stream_write( string $data ) : int { + if ( ! $this->body ) { + return 0; + } + return $this->body->write( $data ); + } + + public function unlink( string $path ) : bool { + $this->initProtocol( $path ); + + return $this->boolCall( + function () use ( $path ) { + $this->clearCacheKey( $path ); + $this->getClient()->deleteObject( $this->withPath( $path ) ); + return true; + } + ); + } + + /** + * @return StatArray + */ + public function stream_stat() { + $stat = $this->getStatTemplate(); + $stat[7] = $this->getSize() ?? 0; + $stat['size'] = $stat[7]; + $stat[2] = $this->mode ?? 0; + $stat['mode'] = $stat[2]; + + return $stat; + } + + /** + * Provides information for is_dir, is_file, filesize, etc. Works on + * buckets, keys, and prefixes. + * @link http://www.php.net/manual/en/streamwrapper.url-stat.php + * + * @return StatArray|bool + */ + public function url_stat( string $path, int $flags ) { + $this->initProtocol( $path ); + + $extension = pathinfo( $path, PATHINFO_EXTENSION ); + /** + * If the file is actually just a path to a directory + * then return it as always existing. This is to work + * around wp_upload_dir doing file_exists checks on + * the uploads directory on every page load. + * + * Added by Joe Hoyle + */ + if ( ! $extension ) { + return [ + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 16895, + 'mode' => 16895, + 3 => 0, + 'nlink' => 0, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => -1, + 'rdev' => -1, + 7 => 0, + 'size' => 0, + 8 => 0, + 'atime' => 0, + 9 => 0, + 'mtime' => 0, + 10 => 0, + 'ctime' => 0, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ]; + } + + // Some paths come through as S3:// for some reason. + $split = explode( '://', $path ); + $path = strtolower( $split[0] ) . '://' . $split[1]; + + // Check if this path is in the url_stat cache + /** @var StatArray|null */ + $value = $this->getCacheStorage()->get( $path ); + if ( $value ) { + return $value; + } + + $stat = $this->createStat( $path, $flags ); + + if ( is_array( $stat ) ) { + $this->getCacheStorage()->set( $path, $stat ); + } + + return $stat; + } + + /** + * Parse the protocol out of the given path. + * + * @param $path + */ + private function initProtocol( string $path ) : void { + $parts = explode( '://', $path, 2 ); + $this->protocol = $parts[0] ?: 's3'; + } + + /** + * + * @param string $path + * @param integer $flags + * @return StatArray|bool + */ + private function createStat( string $path, int $flags ) { + $this->initProtocol( $path ); + $parts = $this->withPath( $path ); + + if ( $parts['Key'] === null || $parts['Key'] === '' ) { + return $this->statDirectory( $parts, $path, $flags ); + } + + return $this->boolCall( + function () use ( $parts, $path ) { + try { + $result = $this->getClient()->headObject( $parts ); + if ( substr( $parts['Key'], -1, 1 ) == '/' && + $result['ContentLength'] == 0 + ) { + // Return as if it is a bucket to account for console + // bucket objects (e.g., zero-byte object "foo/") + return $this->formatUrlStat( $path ); + } else { + // Attempt to stat and cache regular object + /** @var S3ObjectResultArray */ + $result_array = $result->toArray(); + return $this->formatUrlStat( $result_array ); + } + } catch ( S3Exception $e ) { + // Maybe this isn't an actual key, but a prefix. Do a prefix + // listing of objects to determine. + $result = $this->getClient()->listObjectsV2( + [ + 'Bucket' => $parts['Bucket'], + 'Prefix' => rtrim( $parts['Key'], '/' ) . '/', + 'MaxKeys' => 1, + ] + ); + if ( ! isset( $result['Contents'] ) && ! isset( $result['CommonPrefixes'] ) ) { + throw new \Exception( "File or directory not found: $path" ); + } + return $this->formatUrlStat( $path ); + } + }, $flags + ); + } + + /** + * @param OptionsArray $parts + * @param string $path + * @param int $flags + * @return StatArray|bool + */ + private function statDirectory( $parts, $path, $flags ) { + // Stat "directories": buckets, or "s3://" + if ( ! $parts['Bucket'] || + $this->getClient()->doesBucketExistV2( $parts['Bucket'], false ) + ) { + return $this->formatUrlStat( $path ); + } + + return $this->triggerError( "File or directory not found: $path", $flags ); + } + + /** + * Support for mkdir(). + * + * @param string $path Directory which should be created. + * @param int $mode Permissions. 700-range permissions map to + * ACL_PUBLIC. 600-range permissions map to + * ACL_AUTH_READ. All other permissions map to + * ACL_PRIVATE. Expects octal form. + * @param int $options A bitwise mask of values, such as + * STREAM_MKDIR_RECURSIVE. + * + * @return bool + * @link http://www.php.net/manual/en/streamwrapper.mkdir.php + */ + public function mkdir( string $path, int $mode, $options ) : bool { + $this->initProtocol( $path ); + $params = $this->withPath( $path ); + $this->clearCacheKey( $path ); + if ( $params['Bucket'] === '' ) { + return false; + } + + if ( ! isset( $params['ACL'] ) ) { + $params['ACL'] = $this->determineAcl( $mode ); + } + + return ( $params['Key'] === null || $params['Key'] === '' ) + ? $this->createBucket( $path, $params ) + : $this->createSubfolder( $path, $params ); + } + + /** + * @param string $path + * @param mixed $options + * @return bool + */ + public function rmdir( string $path, $options ) : bool { + $this->initProtocol( $path ); + $this->clearCacheKey( $path ); + $params = $this->withPath( $path ); + $client = $this->getClient(); + + if ( $params['Bucket'] === '' ) { + return $this->triggerError( 'You must specify a bucket' ); + } + + return $this->boolCall( + function () use ( $params, $path, $client ) { + if ( $params['Key'] === null || $params['Key'] === '' ) { + $client->deleteBucket( [ 'Bucket' => $params['Bucket'] ] ); + return true; + } + return $this->deleteSubfolder( $path, $params ); + } + ); + } + + /** + * Support for opendir(). + * + * The opendir() method of the Amazon S3 stream wrapper supports a stream + * context option of "listFilter". listFilter must be a callable that + * accepts an associative array of object data and returns true if the + * object should be yielded when iterating the keys in a bucket. + * + * @param string $path The path to the directory + * (e.g. "s3://dir[]") + * @param string|null $options Unused option variable + * + * @return bool true on success + * @see http://www.php.net/manual/en/function.opendir.php + */ + public function dir_opendir( $path, $options ) { + $this->initProtocol( $path ); + $this->openedPath = $path; + $params = $this->withPath( $path ); + /** @var string|null */ + $delimiter = $this->getOption( 'delimiter' ); + /** @var callable|null $filterFn */ + $filterFn = $this->getOption( 'listFilter' ); + $op = [ 'Bucket' => $params['Bucket'] ]; + $this->openedBucket = $params['Bucket']; + + if ( $delimiter === null ) { + $delimiter = '/'; + } + + if ( $delimiter ) { + $op['Delimiter'] = $delimiter; + } + + if ( $params['Key'] !== null && $params['Key'] !== '' ) { + // Support paths ending in "*" to allow listing of arbitrary prefixes. + if ( substr( $params['Key'], -1, 1 ) === '*' ) { + $params['Key'] = rtrim( $params['Key'], '*' ); + // Set the opened bucket prefix to be the directory. This is because $this->openedBucketPrefix + // will be removed from the resulting keys, and we want to return all files in the directory + // of the wildcard. + $pos = strrpos( $params['Key'], '/' ); + $this->openedBucketPrefix = substr( $params['Key'], 0, ( $pos !== false ? $pos : 0 ) + 1 ); + } else { + $params['Key'] = rtrim( $params['Key'], $delimiter ) . $delimiter; + $this->openedBucketPrefix = $params['Key']; + } + $op['Prefix'] = $params['Key']; + } + + // WordPress attempts to scan whole directories via wp_unique_filename(), which can be very slow + // when there are thousands of files in a single uploads sub directory. This is due to behaviour + // introduced in https://core.trac.wordpress.org/changeset/46822/. Essentially when a file is uploaded, + // it's not enough to make sure no filename already exists (and append a `-1` to the end), because + // image sizes of that image could also conflict with already existing files too. Because image sizes + // (in the form of -800x600.jpg) can be arbitrary integers, it's not possible to iterate the filesystem + // for all possible matching / colliding file names. WordPress core uses a preg-match on all files that + // might conflict with the given filename. + // + // Fortunately, we can make use of S3 arbitrary prefixes to optimize this query. The WordPress regex + // done via _wp_check_existing_file_names() is essentially `^$filename-...`, so we can modify the prefix + // to include the filename, therefore only return a subset of files from S3 that are more likely to match + // the preg_match() call. + // + // Essentially, wp_unique_filename( my-file.jpg ) doing a `scandir( s3://bucket/2019/04/ )` will actually result in an s3 + // listObjectsV2 query for `s3://bucket/2019/04/my-file` which means even if there are millions of files in `2019/04/` we only + // return a much smaller subset. + // + // Anyone reading this far, brace yourselves for a mighty horrible hack. + $backtrace = debug_backtrace( 0, 3 ); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection + if ( isset( $backtrace[1]['function'] ) + && $backtrace[1]['function'] === 'scandir' + && isset( $backtrace[2]['function'] ) + && $backtrace[2]['function'] === 'wp_unique_filename' && isset( $backtrace[2]['args'][1] ) + && isset( $op['Prefix'] ) + ) { + /** @var string $filename */ + $filename = $backtrace[2]['args'][1]; + $name = pathinfo( $filename, PATHINFO_FILENAME ); + $op['Prefix'] .= $name; + } + + // Filter our "/" keys added by the console as directories, and ensure + // that if a filter function is provided that it passes the filter. + $this->objectIterator = \Aws\flatmap( + $this->getClient()->getPaginator( 'ListObjectsV2', $op ), + function ( Result $result ) use ( $filterFn ) { + /** @var list */ + $contentsAndPrefixes = $result->search( '[Contents[], CommonPrefixes[]][]' ); + // Filter out dir place holder keys and use the filter fn. + return array_filter( + $contentsAndPrefixes, + function ( $key ) use ( $filterFn ) { + return ( $filterFn === null || call_user_func( $filterFn, $key ) ) + && ( ! isset( $key['Key'] ) || substr( $key['Key'], -1, 1 ) !== '/' ); + } + ); + } + ); + + return true; + } + + /** + * Close the directory listing handles + * + * @return bool true on success + */ + public function dir_closedir() : bool { + $this->objectIterator = null; + gc_collect_cycles(); + + return true; + } + + /** + * This method is called in response to rewinddir() + * + * @return bool true on success + */ + public function dir_rewinddir() { + return $this->boolCall( + function() { + if ( $this->openedPath === null ) { + return false; + } + $this->objectIterator = null; + $this->dir_opendir( $this->openedPath, null ); + return true; + } + ); + } + + /** + * This method is called in response to readdir() + * + * @return string|bool Should return a string representing the next filename, or + * false if there is no next file. + * @link http://www.php.net/manual/en/function.readdir.php + */ + public function dir_readdir() { + // Skip empty result keys + if ( ! $this->objectIterator || ! $this->objectIterator->valid() ) { + return false; + } + + // First we need to create a cache key. This key is the full path to + // then object in s3: protocol://bucket/key. + // Next we need to create a result value. The result value is the + // current value of the iterator without the opened bucket prefix to + // emulate how readdir() works on directories. + // The cache key and result value will depend on if this is a prefix + // or a key. + /** @var S3ObjectResultArray */ + $cur = $this->objectIterator->current(); + if ( isset( $cur['Prefix'] ) ) { + // Include "directories". Be sure to strip a trailing "/" + // on prefixes. + $result = rtrim( $cur['Prefix'], '/' ); + $key = $this->formatKey( $result ); + $stat = $this->formatUrlStat( $key ); + } else { + $result = $cur['Key']; + $key = $this->formatKey( $cur['Key'] ); + $stat = $this->formatUrlStat( $cur ); + } + + // Cache the object data for quick url_stat lookups used with + // RecursiveDirectoryIterator. + $this->getCacheStorage()->set( $key, $stat ); + $this->objectIterator->next(); + + // Remove the prefix from the result to emulate other stream wrappers. + $retVal = ( $this->openedBucketPrefix !== null && $this->openedBucketPrefix !== '' ) + ? substr( $result, strlen( $this->openedBucketPrefix ) ) + : $result; + if ( $retVal === '' ) { + $retVal = false; + } + return $retVal; + } + + private function formatKey( string $key ) : string { + $protocol = explode( '://', $this->openedPath ?? '' )[0]; + return "{$protocol}://{$this->openedBucket}/{$key}"; + } + + /** + * Called in response to rename() to rename a file or directory. Currently + * only supports renaming objects. + * + * @param string $path_from the path to the file to rename + * @param string $path_to the new path to the file + * + * @return bool true if file was successfully renamed + * @link http://www.php.net/manual/en/function.rename.php + */ + public function rename( $path_from, $path_to ) { + // PHP will not allow rename across wrapper types, so we can safely + // assume $path_from and $path_to have the same protocol + $this->initProtocol( $path_from ); + $partsFrom = $this->withPath( $path_from ); + $partsTo = $this->withPath( $path_to ); + $this->clearCacheKey( $path_from ); + $this->clearCacheKey( $path_to ); + + if ( $partsFrom['Key'] === null || $partsFrom['Key'] === '' || $partsTo['Key'] === null || $partsTo['Key'] === '' ) { + return $this->triggerError( + 'The Amazon S3 stream wrapper only ' + . 'supports copying objects' + ); + } + + return $this->boolCall( + function () use ( $partsFrom, $partsTo ) { + $options = $this->getOptions( true ); + // Copy the object and allow overriding default parameters if + // desired, but by default copy metadata + $this->getClient()->copy( + $partsFrom['Bucket'], + $partsFrom['Key'], + $partsTo['Bucket'], + $partsTo['Key'], + isset( $options['acl'] ) ? $options['acl'] : 'private', + $options + ); + // Delete the original object + $this->getClient()->deleteObject( + [ + 'Bucket' => $partsFrom['Bucket'], + 'Key' => $partsFrom['Key'], + ] + $options + ); + return true; + } + ); + } + + public function stream_cast( int $cast_as ) : bool { + return false; + } + + /** + * Validates the provided stream arguments for fopen and returns an array + * of errors. + * + * @param string $path + * @param string $mode + * @return string[] + */ + private function validate( $path, $mode ) { + $errors = []; + + if ( ! $this->getOption( 'Key' ) ) { + $errors[] = 'Cannot open a bucket. You must specify a path in the ' + . 'form of s3://bucket/key'; + } + + if ( ! in_array( $mode, [ 'r', 'w', 'a', 'x' ] ) ) { + $errors[] = "Mode not supported: {$mode}. " + . "Use one 'r', 'w', 'a', or 'x'."; + } + + // When using mode "x" validate if the file exists before attempting + // to read + /** @var string */ + $bucket = $this->getOption( 'Bucket' ); + /** @var string */ + $key = $this->getOption( 'Key' ); + if ( $mode == 'x' && + $this->getClient()->doesObjectExistV2( + $bucket, + $key, + false, + $this->getOptions( true ) + ) + ) { + $errors[] = "{$path} already exists on Amazon S3"; + } + + return $errors; + } + + /** + * Get the stream context options available to the current stream + * + * @param bool $removeContextData Set to true to remove contextual kvp's + * like 'client' from the result. + * + * @return OptionsArray + */ + private function getOptions( $removeContextData = false ) { + // Context is not set when doing things like stat + if ( $this->context === null ) { + $options = []; + } else { + $options = stream_context_get_options( $this->context ); + /** @var OptionsArray */ + $options = isset( $options[ $this->protocol ] ) + ? $options[ $this->protocol ] + : []; + } + + $default = stream_context_get_options( stream_context_get_default() ); + /** @var OptionsArray */ + $default = isset( $default[ $this->protocol ] ) + ? $default[ $this->protocol ] + : []; + /** @var OptionsArray */ + $result = $this->params + $options + $default; + + if ( $removeContextData ) { + unset( $result['client'], $result['seekable'], $result['cache'] ); + } + + return $result; + } + + /** + * Get a specific stream context option + * + * @param string $name + * @return mixed + */ + private function getOption( $name ) { + $options = $this->getOptions(); + return $options[ $name ] ?? null; + } + + /** + * Gets the client from the stream context + * + * @return S3ClientInterface + * @throws \RuntimeException if no client has been configured + */ + private function getClient() : S3ClientInterface { + /** @var Plugin|null */ + $plugin = $this->getOption( 'plugin' ); + if ( ! $plugin ) { + throw new \RuntimeException( 'No plugin in stream context' ); + } + + return $plugin->s3(); + } + + /** + * Get the bucket and key for a given path. + * + * @param string $path + * @return array{Bucket: string, Key: string|null} + */ + private function getBucketKey( string $path ) : array { + // Remove the protocol + $parts = explode( '://', $path ); + // Get the bucket, key + $parts = explode( '/', $parts[1], 2 ); + + return [ + 'Bucket' => $parts[0], + 'Key' => isset( $parts[1] ) ? $parts[1] : null, + ]; + } + + /** + * Get the bucket and key from the passed path (e.g. s3://bucket/key) + * + * @param string $path Path passed to the stream wrapper + * + * @return OptionsArray Hash of 'Bucket', 'Key', and custom params from the context + */ + private function withPath( $path ) { + $params = $this->getOptions( true ); + + return $this->getBucketKey( $path ) + $params; + } + + private function openReadStream() : bool { + $client = $this->getClient(); + $command = $client->getCommand( 'GetObject', $this->getOptions( true ) ); + if ( is_array( $command['@http'] ) ) { + $command['@http']['stream'] = true; + } + /** @var array{Body: StreamInterface, ContentLength: int} */ + $result = $client->execute( $command ); + $this->size = $result['ContentLength']; + $this->body = $result['Body']; + + // Wrap the body in a caching entity body if seeking is allowed + if ( $this->getOption( 'seekable' ) && ! $this->body->isSeekable() ) { + $this->body = new CachingStream( $this->body ); + } + + return true; + } + + private function openWriteStream() : bool { + $this->body = new Stream( fopen( 'php://temp', 'r+' ) ); + return true; + } + + private function openAppendStream() : bool { + try { + // Get the body of the object and seek to the end of the stream + $client = $this->getClient(); + /** @var array */ + $request = $this->getOptions( true ); + /** @var StreamInterface */ + $this->body = $client->getObject( $request )['Body']; + $this->body->seek( 0, SEEK_END ); + return true; + } catch ( S3Exception $e ) { + // The object does not exist, so use a simple write stream + return $this->openWriteStream(); + } + } + + /** + * Trigger one or more errors + * + * @param string[]|string $errors Errors to trigger + * @param int $flags If set to STREAM_URL_STAT_QUIET, then no + * error or exception occurs + * + * @return bool Returns false + */ + private function triggerError( $errors, $flags = null ) { + // This is triggered with things like file_exists() + if ( $flags !== null && $flags & STREAM_URL_STAT_QUIET ) { + return false; + } + + // This is triggered when doing things like lstat() or stat() + trigger_error( implode( "\n", (array) $errors ), E_USER_WARNING ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + return false; + } + + /** + * Prepare a url_stat result array + * + * @param S3ObjectResultArray|null|false|string $result Data to add + * + * @return StatArray Returns the modified url_stat result + */ + private function formatUrlStat( $result = null ) { + $stat = $this->getStatTemplate(); + switch ( gettype( $result ) ) { + case 'NULL': + case 'string': + // Directory with 0777 access - see "man 2 stat". + $stat[2] = 0040777; + $stat['mode'] = 0040777; + break; + case 'array': + // Regular file with 0777 access - see "man 2 stat". + $stat[2] = 0100777; + $stat['mode'] = 0100777; + // Pluck the content-length if available. + if ( isset( $result['ContentLength'] ) ) { + $stat[7] = $result['ContentLength']; + $stat['size'] = $result['ContentLength']; + } elseif ( isset( $result['Size'] ) ) { + $stat[7] = $result['Size']; + $stat['size'] = $stat[7]; + } + if ( isset( $result['LastModified'] ) ) { + // ListObjects or HeadObject result + $stat[10] = strtotime( $result['LastModified'] ); + $stat['ctime'] = $stat[10]; + $stat[9] = $stat[10]; + $stat['mtime'] = $stat[10]; + } + } + + return $stat; + } + + /** + * Creates a bucket for the given parameters. + * + * @param string $path Stream wrapper path + * @param OptionsArray $params A result of StreamWrapper::withPath() + * + * @return bool Returns true on success or false on failure + */ + private function createBucket( $path, array $params ) { + if ( $this->getClient()->doesBucketExistV2( $params['Bucket'], false ) ) { + return $this->triggerError( "Bucket already exists: {$path}" ); + } + + return $this->boolCall( + function () use ( $params, $path ) { + $this->getClient()->createBucket( $params ); + $this->clearCacheKey( $path ); + return true; + } + ); + } + + /** + * Creates a pseudo-folder by creating an empty "/" suffixed key + * + * @param string $path Stream wrapper path + * @param OptionsArray $params A result of StreamWrapper::withPath() + * + * @return bool + */ + private function createSubfolder( string $path, array $params ) { + // Ensure the path ends in "/" and the body is empty. + $params['Key'] = rtrim( $params['Key'] ?? '', '/' ) . '/'; + $params['Body'] = ''; + + // Fail if this pseudo directory key already exists + if ( $this->getClient()->doesObjectExistV2( + $params['Bucket'], + $params['Key'] + ) + ) { + return $this->triggerError( "Subfolder already exists: {$path}" ); + } + + return $this->boolCall( + function () use ( $params, $path ) { + $this->getClient()->putObject( $params ); + $this->clearCacheKey( $path ); + return true; + } + ); + } + + /** + * Deletes a nested subfolder if it is empty. + * + * @param string $path Path that is being deleted (e.g., 's3://a/b/c') + * @param OptionsArray $params A result of StreamWrapper::withPath() + * + * @return bool + */ + private function deleteSubfolder( string $path, array $params ) : bool { + // Use a key that adds a trailing slash if needed. + $prefix = rtrim( $params['Key'] ?? '', '/' ) . '/'; + /** @var array{Contents: list, CommonPrefixes:array} */ + $result = $this->getClient()->listObjectsV2( + [ + 'Bucket' => $params['Bucket'], + 'Prefix' => $prefix, + 'MaxKeys' => 1, + ] + ); + + // Check if the bucket contains keys other than the placeholder + $contents = $result['Contents']; + if ( $contents ) { + return ( count( $contents ) > 1 || $contents[0]['Key'] != $prefix ) + ? $this->triggerError( 'Subfolder is not empty' ) + : $this->unlink( rtrim( $path, '/' ) . '/' ); + } + + return $result['CommonPrefixes'] + ? $this->triggerError( 'Subfolder contains nested folders' ) + : true; + } + + /** + * Determine the most appropriate ACL based on a file mode. + * + * @param int $mode File mode + * + * @return 'public-read'|'authenticated-read'|'private' + */ + private function determineAcl( int $mode ) : string { + switch ( substr( decoct( $mode ), 0, 1 ) ) { + case '7': + return 'public-read'; + case '6': + return 'authenticated-read'; + default: + return 'private'; + } + } + + /** + * Gets a URL stat template with default values + * + * @return StatArray + * + */ + private function getStatTemplate() { + return [ + 0 => 0, + 'dev' => 0, + 1 => 0, + 'ino' => 0, + 2 => 0, + 'mode' => 0, + 3 => 0, + 'nlink' => 0, + 4 => 0, + 'uid' => 0, + 5 => 0, + 'gid' => 0, + 6 => -1, + 'rdev' => -1, + 7 => 0, + 'size' => 0, + 8 => 0, + 'atime' => 0, + 9 => 0, + 'mtime' => 0, + 10 => 0, + 'ctime' => 0, + 11 => -1, + 'blksize' => -1, + 12 => -1, + 'blocks' => -1, + ]; + } + + /** + * Invokes a callable and triggers an error if an exception occurs while + * calling the function. + * + * @psalm-template T + * @psalm-param callable():T $fn + * @param int $flags + * + * @psalm-return T|bool + */ + private function boolCall( callable $fn, $flags = null ) { + try { + return $fn(); + } catch ( \Exception $e ) { + return $this->triggerError( $e->getMessage(), $flags ); + } + } + + /** + * @return CacheInterface + */ + private function getCacheStorage() : CacheInterface { + if ( ! $this->cache ) { + /** @var CacheInterface */ + $this->cache = $this->getOption( 'cache' ) ?: new LruArrayCache(); + } + + return $this->cache; + } + + /** + * Clears a specific stat cache value from the stat cache and LRU cache. + * + * @param string $key S3 path (s3://bucket/key). + */ + private function clearCacheKey( $key ) : void { + clearstatcache( true, $key ); + $this->getCacheStorage()->remove( $key ); + } + + /** + * Returns the size of the opened object body. + * + * @return int|null + */ + private function getSize() { + if ( ! $this->body ) { + return null; + } + $size = $this->body->getSize(); + + return $size !== null ? $size : $this->size; + } +} diff --git a/html/wp-content/plugins/s3-uploads/inc/class-wp-cli-command.php b/html/wp-content/plugins/s3-uploads/inc/class-wp-cli-command.php new file mode 100644 index 0000000..5fc9aad --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/inc/class-wp-cli-command.php @@ -0,0 +1,360 @@ +verify_s3_access_constants() ) { + return; + } + + // Get S3 Upload instance. + Plugin::get_instance(); + + // Create a path in the base directory, with a random file name to avoid potentially overwriting existing data. + $upload_dir = wp_upload_dir(); + $s3_path = $upload_dir['basedir'] . '/' . wp_rand() . '.txt'; + + // Attempt to copy the local Canola test file to the generated path on S3. + WP_CLI::print_value( 'Attempting to upload file ' . $s3_path ); + + $copy = copy( + dirname( dirname( __FILE__ ) ) . '/verify.txt', + $s3_path + ); + + // Check that the copy worked. + if ( ! $copy ) { + WP_CLI::error( 'Failed to copy / write to S3 - check your policy?' ); + + return; + } + + WP_CLI::print_value( 'File uploaded to S3 successfully.' ); + + // Delete the file off S3. + WP_CLI::print_value( 'Attempting to delete file. ' . $s3_path ); + $delete = unlink( $s3_path ); + + // Check that the delete worked. + if ( ! $delete ) { + WP_CLI::error( 'Failed to delete ' . $s3_path ); + + return; + } + + WP_CLI::print_value( 'File deleted from S3 successfully.' ); + + WP_CLI::success( 'Looks like your configuration is correct.' ); + } + + private function get_iam_policy() : string { + + $bucket = strtok( S3_UPLOADS_BUCKET, '/' ); + + $path = null; + + if ( strpos( S3_UPLOADS_BUCKET, '/' ) !== false ) { + $path = str_replace( strtok( S3_UPLOADS_BUCKET, '/' ) . '/', '', S3_UPLOADS_BUCKET ); + } + + return '{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Stmt1392016154000", + "Effect": "Allow", + "Action": [ + "s3:AbortMultipartUpload", + "s3:DeleteObject", + "s3:GetBucketAcl", + "s3:GetBucketLocation", + "s3:GetBucketPolicy", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:ListBucket", + "s3:ListBucketMultipartUploads", + "s3:ListMultipartUploadParts", + "s3:PutObject", + "s3:PutObjectAcl" + ], + "Resource": [ + "arn:aws:s3:::' . S3_UPLOADS_BUCKET . '/*" + ] + }, + { + "Sid": "AllowRootAndHomeListingOfBucket", + "Action": ["s3:ListBucket"], + "Effect": "Allow", + "Resource": ["arn:aws:s3:::' . $bucket . '"], + "Condition":{"StringLike":{"s3:prefix":["' . ( $path !== null ? $path . '/' : '' ) . '*"]}} + } + ] +}'; + } + + /** + * Create AWS IAM Policy that S3 Uploads requires + * + * It's typically not a good idea to use access keys that have full access to your S3 account, + * as if the keys are compromised through the WordPress site somehow, you don't + * want to give full control via those keys. + * + * @subcommand generate-iam-policy + */ + public function generate_iam_policy() : void { + + WP_Cli::print_value( $this->get_iam_policy() ); + + } + + /** + * List files in the S3 bucket + * + * @synopsis [] + * + * @param array{0: string} $args + */ + public function ls( array $args ) : void { + + $s3 = Plugin::get_instance()->s3(); + + $prefix = ''; + + if ( strpos( S3_UPLOADS_BUCKET, '/' ) !== false ) { + $prefix = trailingslashit( str_replace( strtok( S3_UPLOADS_BUCKET, '/' ) . '/', '', S3_UPLOADS_BUCKET ) ); + } + + if ( isset( $args[0] ) ) { + $prefix .= trailingslashit( ltrim( $args[0], '/' ) ); + } + + try { + $objects = $s3->getIterator( + 'ListObjectsV2', [ + 'Bucket' => strtok( S3_UPLOADS_BUCKET, '/' ), + 'Prefix' => $prefix, + ] + ); + /** @var array{Key: string} $object */ + foreach ( $objects as $object ) { + WP_CLI::line( str_replace( $prefix, '', $object['Key'] ) ); + } + } catch ( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } + + } + + /** + * Copy files to / from the uploads directory. Use s3://bucket/location for S3 + * + * @synopsis + * + * @param array{0: string, 1: string} $args + */ + public function cp( array $args ) : void { + + $from = $args[0]; + $to = $args[1]; + + if ( is_dir( $from ) ) { + $this->recurse_copy( $from, $to ); + } else { + copy( $from, $to ); + } + + WP_CLI::success( sprintf( 'Completed copy from %s to %s', $from, $to ) ); + } + + /** + * Upload a directory to S3 + * + * @subcommand upload-directory + * @synopsis [] [--concurrency=] [--verbose] + * + * @param array{0: string, 1: string} $args + * @param array{concurrency?: int, verbose?: bool} $args_assoc + */ + public function upload_directory( array $args, array $args_assoc ) : void { + + $from = $args[0]; + $to = ''; + if ( isset( $args[1] ) ) { + $to = $args[1]; + } + + $s3 = Plugin::get_instance()->s3(); + $args_assoc = wp_parse_args( + $args_assoc, [ + 'concurrency' => 5, + 'verbose' => false, + ] + ); + + $transfer_args = [ + 'concurrency' => $args_assoc['concurrency'], + 'debug' => (bool) $args_assoc['verbose'], + 'before' => function ( Command $command ) : void { + if ( in_array( $command->getName(), [ 'PutObject', 'CreateMultipartUpload' ], true ) ) { + $acl = defined( 'S3_UPLOADS_OBJECT_ACL' ) ? S3_UPLOADS_OBJECT_ACL : 'public-read'; + $command['ACL'] = $acl; + } + }, + ]; + try { + $manager = new Transfer( $s3, $from, 's3://' . S3_UPLOADS_BUCKET . '/' . $to, $transfer_args ); + $manager->transfer(); + } catch ( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } + } + + /** + * Delete files from S3 + * + * @synopsis [--regex=] + * + * @param array{0: string} $args + * @param array{regex?: string} $args_assoc + */ + public function rm( array $args, array $args_assoc ) : void { + + $s3 = Plugin::get_instance()->s3(); + + $prefix = ''; + $regex = isset( $args_assoc['regex'] ) ? $args_assoc['regex'] : ''; + + if ( strpos( S3_UPLOADS_BUCKET, '/' ) !== false ) { + $prefix = trailingslashit( str_replace( strtok( S3_UPLOADS_BUCKET, '/' ) . '/', '', S3_UPLOADS_BUCKET ) ); + } + + if ( isset( $args[0] ) ) { + $prefix .= ltrim( $args[0], '/' ); + + if ( strpos( $args[0], '.' ) === false ) { + $prefix = trailingslashit( $prefix ); + } + } + + try { + $s3->deleteMatchingObjects( + strtok( S3_UPLOADS_BUCKET, '/' ), + $prefix, + $regex, + [ + 'before_delete', + function() { + WP_CLI::line( 'Deleting file' ); + }, + ] + ); + + } catch ( Exception $e ) { + WP_CLI::error( $e->getMessage() ); + } + + WP_CLI::success( sprintf( 'Successfully deleted %s', $prefix ) ); + } + + /** + * Enable the auto-rewriting of media links to S3 + */ + public function enable() : void { + update_option( 's3_uploads_enabled', 'enabled' ); + + WP_CLI::success( 'Media URL rewriting enabled.' ); + } + + /** + * Disable the auto-rewriting of media links to S3 + */ + public function disable() : void { + delete_option( 's3_uploads_enabled' ); + + WP_CLI::success( 'Media URL rewriting disabled.' ); + } + + /** + * List all files for a given attachment. + * + * Useful for debugging. + * + * @subcommand get-attachment-files + * @synopsis + * + * @param array{0: int} $args + */ + public function get_attachment_files( array $args ) : void { + WP_CLI::print_value( Plugin::get_attachment_files( $args[0] ) ); + } + + /** + * Update the ACL of all files for an attachment. + * + * Useful for debugging. + * + * @subcommand set-attachment-acl + * @synopsis + * + * @param array{0: int, 1: 'public-read'|'private'} $args + */ + public function set_attachment_acl( array $args ) : void { + $result = Plugin::get_instance()->set_attachment_files_acl( $args[0], $args[1] ); + WP_CLI::print_value( $result ); + } + + private function recurse_copy( string $src, string $dst ) : void { + $dir = opendir( $src ); + @mkdir( $dst ); + while ( false !== ( $file = readdir( $dir ) ) ) { + if ( ( '.' !== $file ) && ( '..' !== $file ) ) { + if ( is_dir( $src . '/' . $file ) ) { + $this->recurse_copy( $src . '/' . $file, $dst . '/' . $file ); + } else { + WP_CLI::line( sprintf( 'Copying from %s to %s', $src . '/' . $file, $dst . '/' . $file ) ); + copy( $src . '/' . $file, $dst . '/' . $file ); + } + } + } + closedir( $dir ); + } + + /** + * Verify that the required constants for the S3 connections are set. + * + * @return bool true if all constants are set, else false. + */ + private function verify_s3_access_constants() { + $required_constants = [ + 'S3_UPLOADS_BUCKET', + ]; + + // Credentials do not need to be set when using AWS Instance Profiles. + if ( ! defined( 'S3_UPLOADS_USE_INSTANCE_PROFILE' ) || ! S3_UPLOADS_USE_INSTANCE_PROFILE ) { + array_push( $required_constants, 'S3_UPLOADS_KEY', 'S3_UPLOADS_SECRET' ); + } + + $all_set = true; + foreach ( $required_constants as $constant ) { + if ( ! defined( $constant ) ) { + WP_CLI::error( sprintf( 'The required constant %s is not defined.', $constant ), false ); + $all_set = false; + } + } + + return $all_set; + } +} diff --git a/html/wp-content/plugins/s3-uploads/inc/namespace.php b/html/wp-content/plugins/s3-uploads/inc/namespace.php new file mode 100644 index 0000000..3956859 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/inc/namespace.php @@ -0,0 +1,192 @@ +setup(); + + // Add filters to "wrap" the wp_privacy_personal_data_export_file function call as we need to + // switch out the personal_data directory to a local temp folder, and then upload after it's + // complete, as Core tries to write directly to the ZipArchive which won't work with the + // S3 streamWrapper. + add_action( 'wp_privacy_personal_data_export_file', __NAMESPACE__ . '\\before_export_personal_data', 9, 0 ); + add_action( 'wp_privacy_personal_data_export_file', __NAMESPACE__ . '\\after_export_personal_data', 11, 0 ); + add_action( 'wp_privacy_personal_data_export_file_created', __NAMESPACE__ . '\\move_temp_personal_data_to_s3', 1000 ); +} + +/** + * Check whether the environment meets the plugin's requirements, like the minimum PHP version. + * + * @return bool True if the requirements are met, else false. + */ +function check_requirements() : bool { + global $wp_version; + + if ( version_compare( PHP_VERSION, '7.4', '<' ) ) { + if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { + add_action( 'admin_notices', __NAMESPACE__ . '\\outdated_php_version_notice', 10, 0 ); + } + + return false; + } + + if ( version_compare( $wp_version, '5.3.0', '<' ) ) { + if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { + add_action( 'admin_notices', __NAMESPACE__ . '\\outdated_wp_version_notice', 10, 0 ); + } + + return false; + } + + if ( ini_get( 'allow_url_fopen' ) === false || ini_get( 'allow_url_fopen' ) === '' ) { + if ( is_admin() && ! defined( 'DOING_AJAX' ) ) { + add_action( 'admin_notices', __NAMESPACE__ . '\\url_fopen_disabled_notice', 10, 0 ); + } + + return false; + } + + return true; +} + +/** + * Print an admin notice when the PHP version is not high enough. + * + * This has to be a named function for compatibility with PHP 5.2. + */ +function outdated_php_version_notice() : void { + printf( + '

            The S3 Uploads plugin requires PHP version 7.4 or higher. Your server is running PHP version %s.

            ', + PHP_VERSION + ); +} + +/** + * Print an admin notice when the PHP version is not high enough. + * + * This has to be a named function for compatibility with PHP 5.2. + */ +function url_fopen_disabled_notice() : void { + printf( '

            The S3 Uploads plugin requires PHP option allow_url_fopen to be enabled. Learn more.

            ', + 'https://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen' + ); +} + +/** + * Print an admin notice when the WP version is not high enough. + * + * This has to be a named function for compatibility with PHP 5.2. + */ +function outdated_wp_version_notice() : void { + global $wp_version; + + printf( + '

            The S3 Uploads plugin requires WordPress version 5.3 or higher. Your server is running WordPress version %s.

            ', + esc_html( $wp_version ) + ); +} + +/** + * Check if URL rewriting is enabled. + * + * Define S3_UPLOADS_AUTOENABLE to false in your wp-config to disable, or use the + * s3_uploads_enabled option. + * + * @return bool + */ +function enabled() : bool { + // Make sure the plugin is enabled when autoenable is on + $constant_autoenable_off = ( defined( 'S3_UPLOADS_AUTOENABLE' ) && false === S3_UPLOADS_AUTOENABLE ); + + if ( $constant_autoenable_off && 'enabled' !== get_option( 's3_uploads_enabled' ) ) { // If the plugin is not enabled, skip + return false; + } + + return true; +} + +/** + * Setup the filters for wp_privacy_exports_dir to use a temp folder location. + */ +function before_export_personal_data() : void { + add_filter( 'wp_privacy_exports_dir', __NAMESPACE__ . '\\set_wp_privacy_exports_dir' ); +} + +/** + * Remove the filters for wp_privacy_exports_dir as we only want it added in some cases. + */ +function after_export_personal_data() : void { + remove_filter( 'wp_privacy_exports_dir', __NAMESPACE__ . '\\set_wp_privacy_exports_dir' ); +} + +/** + * Override the wp_privacy_exports_dir location + * + * We don't want to use the default uploads folder location, as with S3 Uploads this is + * going to the a s3:// custom URL handler, which is going to fail with the use of ZipArchive. + * Instead we set to to WP's get_temp_dir and move the fail in the wp_privacy_personal_data_export_file_created + * hook. + * + * @param string $dir + * @return string + */ +function set_wp_privacy_exports_dir( string $dir ) { + if ( strpos( $dir, 's3://' ) !== 0 ) { + return $dir; + } + $dir = get_temp_dir() . 'wp_privacy_exports_dir/'; + if ( ! is_dir( $dir ) ) { + mkdir( $dir ); + file_put_contents( $dir . 'index.html', '' ); // @codingStandardsIgnoreLine FS write is ok. + } + return $dir; +} + +/** + * Move the tmp personal data file to the true uploads location + * + * Once a personal data file has been written, move it from the overridden "temp" + * location to the S3 location where it should have been stored all along, and where + * the "natural" Core URL is going to be pointing to. + */ +function move_temp_personal_data_to_s3( string $archive_pathname ) : void { + if ( strpos( $archive_pathname, get_temp_dir() ) !== 0 ) { + return; + } + $upload_dir = wp_upload_dir(); + $exports_dir = trailingslashit( $upload_dir['basedir'] ) . 'wp-personal-data-exports/'; + $destination = $exports_dir . pathinfo( $archive_pathname, PATHINFO_FILENAME ) . '.' . pathinfo( $archive_pathname, PATHINFO_EXTENSION ); + copy( $archive_pathname, $destination ); + unlink( $archive_pathname ); +} diff --git a/html/wp-content/plugins/s3-uploads/psalm.xml b/html/wp-content/plugins/s3-uploads/psalm.xml new file mode 100644 index 0000000..26f88a1 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/psalm.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/s3-uploads/psalm/stubs/constants.php b/html/wp-content/plugins/s3-uploads/psalm/stubs/constants.php new file mode 100644 index 0000000..8a4277b --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/psalm/stubs/constants.php @@ -0,0 +1,14 @@ +Makes an exact copy of the Imagick object + * @link https://php.net/manual/en/class.imagick.php + */ + class Imagick implements Iterator, Countable { + + } +} + +namespace WP_CLI { + /** + * + * @param string $command + * @param callable|class-string $class + * @return void + */ + function add_command( string $command, $class ) { + + } +} diff --git a/html/wp-content/plugins/s3-uploads/s3-uploads.php b/html/wp-content/plugins/s3-uploads/s3-uploads.php new file mode 100644 index 0000000..1235bb9 --- /dev/null +++ b/html/wp-content/plugins/s3-uploads/s3-uploads.php @@ -0,0 +1,13 @@ + **âš ï¸ Development Repository Notice** +> +> This is the latest development version of SVG Support. Code here may be unstable during active development. For production sites, please use the official release from the [WordPress.org plugin repository](https://wordpress.org/plugins/svg-support/). +> +> The official plugin is managed via SVN as per WordPress.org standards. This GitHub repository serves as a development workspace and for issue tracking. Once changes are stable, they will be copied to the SVN repository for release. + +## Description + +SVG Support allows you to securely upload SVG files to your WordPress Media Library and use them like any other image, with additional features for inline rendering, styling, and animation. + +### Key Features + +- **SVG Upload Support**: Easily upload SVG files to your media library +- **Automatic Sanitization**: All SVG uploads are sanitized by default for security +- **Minification Options**: Reduce SVG file sizes with optional minification +- **Inline Rendering**: Render SVG code inline by adding the `"style-svg"` class +- **Role-Based Control**: Restrict SVG upload capabilities to specific user roles +- **Custom Target Class**: Define your own CSS class for targeting SVGs +- **Featured Image Support**: Special handling for SVG files as featured images +- **Advanced Mode**: Toggle advanced features for more control + +## Installation + +1. Install through the WordPress plugin repository or upload to your `/wp-plugins/` directory +2. Activate the plugin through the 'Plugins' menu in WordPress +3. Go to "Settings > SVG Support" to configure the plugin + +## Basic Usage + +Once activated, you can upload SVG files to your media library like any other image file. + +### Inline SVG Rendering + +To render an SVG inline (enabling CSS/JS targeting of internal elements): + +``` +alt-text +``` + +Or with a custom class: + +``` +alt-text +``` + +## Security + +SVG Support takes security seriously and provides several features to ensure safe SVG handling: + +- Sanitization by default (since v2.5.8) +- Role-based upload restrictions +- Optional sanitization bypass for trusted users +- Secure file handling through WordPress APIs + +## Development + +This is the development repository for SVG Support. The official release version is maintained on WordPress.org's SVN repository. + +- [Plugin Page on WordPress.org](https://wordpress.org/plugins/svg-support/) +- [SVN Repository](https://plugins.svn.wordpress.org/svg-support/) + +### Quick Test + +Want to try it out? Spin up a test site instantly: +[Click here to create a test site with SVG Support pre-installed](https://tastewp.com/new?pre-installed-plugin-slug=svg-support&redirect=options-general.php%3Fpage%3Dsvg-support&ni=true) + +## Contributing + +Contributions are welcome! Feel free to: + +- Submit bug reports or feature requests through the [issue tracker](https://github.com/your-username/svg-support/issues) +- Create pull requests for bug fixes or new features +- Help with translations through [WordPress.org's translation platform](https://translate.wordpress.org/projects/wp-plugins/svg-support) + +## Support + +- For general support, please use the [WordPress.org support forums](https://wordpress.org/support/plugin/svg-support/) +- For bug reports and feature requests, use the GitHub issues + +## License + +This plugin is licensed under the GPL v2 or later. + +## Author + +Created and maintained by [Benbodhi](https://benbodhi.com) + +### Follow SVG Support + +- [@SVGSupport on Twitter](https://twitter.com/svgsupport) +- [@benbodhi on Twitter](https://twitter.com/benbodhi) +- [@benbodhi on Warpcast](https://warpcast.com/benbodhi) + +## Support the Development + +If you find this plugin useful, please consider: +- [Rating it on WordPress.org](https://wordpress.org/support/plugin/svg-support/reviews/#new-post) +- [Making a donation](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z9R7JERS82EQQ) \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/admin/admin-init.php b/html/wp-content/plugins/svg-support/admin/admin-init.php new file mode 100644 index 0000000..fe6e334 --- /dev/null +++ b/html/wp-content/plugins/svg-support/admin/admin-init.php @@ -0,0 +1,240 @@ + 'bodhi_svgs_settings_sanitize' + ); + + register_setting( 'bodhi_svgs_settings_group', 'bodhi_svgs_settings', $args ); + +} +add_action( 'admin_init', 'bodhi_svgs_register_settings' ); + +/** + * Remove old sanitize setting + */ +function bodhi_svgs_remove_old_sanitize_setting() { + // Fetch current settings + $bodhi_svgs_options = get_option('bodhi_svgs_settings'); + + // Remove the old 'sanitize_svg' setting if it exists + if (isset($bodhi_svgs_options['sanitize_svg'])) { + unset($bodhi_svgs_options['sanitize_svg']); + update_option('bodhi_svgs_settings', $bodhi_svgs_options); + } +} +add_action('admin_init', 'bodhi_svgs_remove_old_sanitize_setting'); + +/** + * Advanced Mode Check + * Creates a usable function for conditionals around the plugin + */ +function bodhi_svgs_advanced_mode() { + + global $bodhi_svgs_options; + + if ( ! empty( $bodhi_svgs_options['advanced_mode'] ) ) { + + return true; + + } else { + + return false; + + } + +} +add_action( 'admin_init', 'bodhi_svgs_advanced_mode' ); + +/** + * Screen check function + * Checks if current page is SVG Support settings page + */ +function bodhi_svgs_specific_pages_settings() { + + // check current page + $screen = get_current_screen(); + + // check if we're on SVG Support settings page + if ( is_object( $screen ) && $screen->id == 'settings_page_svg-support' ) { + + return true; + + } else { + + return false; + + } + +} + +/** + * Screen check function + * Checks if the current page is the Media Library page + */ +function bodhi_svgs_specific_pages_media_library() { + + // check current page + $screen = get_current_screen(); + + // check if we're on Media Library page + if ( is_object( $screen ) && $screen->id == 'upload' ) { + + return true; + + } else { + + return false; + + } +} + +/** + * Screen check function + * Check if the current page is a post edit page + */ +function bodhi_svgs_is_edit_page( $new_edit = null ) { + + global $pagenow; + + if ( ! is_admin() ) return false; + + if ( $new_edit == 'edit' ) { + + return in_array( $pagenow, array( 'post.php', ) ); + + } elseif ( $new_edit == "new" ) { //check for new post page + + return in_array( $pagenow, array( 'post-new.php' ) ); + + } else { //check for either new or edit + + return in_array( $pagenow, array( 'post.php', 'post-new.php' ) ); + + } + +} + +/** + * Add rating text to footer on settings page + */ +function bodhi_svgs_admin_footer_text( $default ) { + + if ( bodhi_svgs_specific_pages_settings() || bodhi_svgs_specific_pages_media_library() ) { + + $strong_open = ''; + $strong_close = ''; + $link_open = ''; + $link_close = ''; + + // translators: %1$s: Opening strong tag, %2$s: Closing strong tag, %3$s: Opening anchor tag for rating link, %4$s: Closing anchor tag + $text = esc_html__( 'If you like %1$sSVG Support%2$s please leave a %3$s★★★★★%4$s rating. A huge thanks in advance!', 'svg-support' ); + + echo wp_kses( + sprintf( + $text, + $strong_open, + $strong_close, + $link_open, + $link_close + ), + array( + 'strong' => array(), + 'a' => array( + 'href' => array(), + 'target' => array(), + 'class' => array() + ) + ) + ); + + } else { + + return $default; + + } + +} +add_filter( 'admin_footer_text', 'bodhi_svgs_admin_footer_text' ); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/admin/img/shortpixel.png b/html/wp-content/plugins/svg-support/admin/img/shortpixel.png new file mode 100644 index 0000000..761cb13 Binary files /dev/null and b/html/wp-content/plugins/svg-support/admin/img/shortpixel.png differ diff --git a/html/wp-content/plugins/svg-support/admin/plugin-action-meta-links.php b/html/wp-content/plugins/svg-support/admin/plugin-action-meta-links.php new file mode 100644 index 0000000..e041657 --- /dev/null +++ b/html/wp-content/plugins/svg-support/admin/plugin-action-meta-links.php @@ -0,0 +1,45 @@ +' . __( 'Settings', 'svg-support') . '' + ), $links + ); + + return $links; + +} +add_filter( 'plugin_action_links_' . plugin_basename(BODHI_SVGS_PLUGIN_FILE), 'bodhi_svgs_plugin_action_links' ); + +/** + * Add plugin_row_meta links + */ +function bodhi_svgs_plugin_meta_links( $links, $file ) { + + if ( $file == plugin_basename(BODHI_SVGS_PLUGIN_FILE) ) { + return array_merge( + $links, + array( + '' . __( 'Get Support', 'svg-support') . '', + '' . __( 'Leave a Review', 'svg-support' ) . '', + '' . __( 'Donate to author', 'svg-support') . '' + ) + ); + } + + return $links; + +} +add_filter( 'plugin_row_meta', 'bodhi_svgs_plugin_meta_links', 10, 2 ); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/admin/svgs-settings-page-help.php b/html/wp-content/plugins/svg-support/admin/svgs-settings-page-help.php new file mode 100644 index 0000000..be190e7 --- /dev/null +++ b/html/wp-content/plugins/svg-support/admin/svgs-settings-page-help.php @@ -0,0 +1,160 @@ +' . __( 'Overview', 'svg-support' ) . ''; + + $bodhi_svgs_help_tab_overview .= '

            ' . __( 'At it\'s core, SVG Support allows you to upload SVG files and use them as you would any regular image with the added benefit of being scalable and looking great on any screen size, no matter what size it\'s displayed. Additionally, SVG file sizes are (more often than not) much smaller than conventional image formats.', 'svg-support' ) . '

            ' . __( 'Even this most basic of usage is very powerful for modern websites, however, there\'s lots of cool stuff you can do with SVG files!', 'svg-support' ) . '

            ' . __( 'SVG Support features an "Advanced Mode" which toggles extra features, allowing you to take more control of how your SVG files are used. By rendering SVG files inline, it opens up a huge number of possibilities including animations, embedded links within the SVG, odd shaped link areas, custom CSS targeting elements within the SVG and whole lot more!', 'svg-support' ) . '

            ' . __( 'So let\'s get into some more details! Simply click the tabs to the left to get more of an understanding of how powerful SVG Support is.', 'svg-support' ) . '

            '; + + // register overview tab + $screen->add_help_tab( array( + 'id' => 'bodhi_svgs_help_tab-overview', + 'title' => __( 'Overview', 'svg-support' ), + 'content' => $bodhi_svgs_help_tab_overview + )); + + /** + * The Settings Tab + */ + // the settings tab content + $bodhi_svgs_help_tab_the_settings = '

            ' . __( 'The Settings', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_the_settings .= '

            ' . __( 'Restrict To Administrators:', 'svg-support' ) . '
            ' . __( 'SVG files are actually XML code, so allowing regular users to upload them can pose serious security risks. Please leave this checked unless you really know what you\'re doing.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_the_settings .= '

            ' . __( 'Enable Advanced Mode:', 'svg-support' ) . '
            ' . __( 'When using SVG files like regular images just isn\'t enough ;)', 'svg-support' ) . '
            ' . __( 'Enabling "Advanced Mode" displays options to give you more control over how you use SVG files on your site. It also includes extra JS on the front end, so leave this disabled unless you\'re actually using any of the advanced features.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_the_settings .= '

            ' . __( 'Output JS in Footer:', 'svg-support' ) . '
            ' . __( 'This setting allows you to choose whether the SVG Support JS file is enqueued in the header or the footer of the site. Usually you would enqueue in the footer unless you need it to be loaded sooner for some reason.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_the_settings .= '

            ' . __( 'Use Expanded JS:', 'svg-support' ) . '
            ' . __( 'This setting gives you the choice of JS file that is enqueued, the full expanded version or the minified version. You would usually enqueue the minified version, but if you want to bundle the JS file using a caching or minification plugin or similar, then you might want to enqueue the expanded, non-minified version.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_the_settings .= '

            ' . __( 'CSS Class To Target:', 'svg-support' ) . '
            ' . __( 'This allows you to set your own custom class that you will use in your SVG source IMG tags that you would like rendered inline. For example, it might be easier for you to remember to add the class "inline-svg" or something, in which case you would use your desired class name in this field to be used across your site.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_the_settings .= '

            ' . __( 'Automatically Insert Class:', 'svg-support' ) . '
            ' . __( 'When this is checked, you won\'t have to add the class to your SVG files during the embed process in the editor. When you pick your SVG, it will be placed in the editor with just the SVG Support class and others stripped. It does not change existing code, it\'s only a helper to allow you to quickly embed your SVG files and have them render inline without having to fiddle with the classes.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_the_settings .= '

            ' . __( 'Force Inline SVG:', 'svg-support' ) . '
            ' . __( 'This feature is to force all SVG files that are found in your site to be rendered inline. This can help if you aren\'t able to set a custom class on your IMG tags for some reason, usually when used in theme options or page builder elements.', 'svg-support' ) . '

            '; + + // register the settings tab + $screen->add_help_tab( array( + 'id' => 'bodhi_svgs_help_tab-the_settings', + 'title' => __( 'The Settings', 'svg-support' ), + 'content' => $bodhi_svgs_help_tab_the_settings + )); + + /** + * Standard Usage Tab + */ + // standard usage tab content + $bodhi_svgs_help_tab_usage_standard = '

            ' . __( 'Standard Usage', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_usage_standard .= '

            ' . __( 'You can simply upload SVG files to your media library like any other image.
            Make sure to select "Restrict to Administrators" if you only want to allow admins to upload SVG files.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_usage_standard .= '

            ' . __( 'If you want to enable sanitization or minification of uploaded SVG files, please enable advanced settings and then enable sanitization and/or minification.', 'svg-support' ) . '

            '; + + // register standard usage tab + $screen->add_help_tab( array( + 'id' => 'bodhi_svgs_help_tab_usage-standard', + 'title' => __( 'Standard Usage', 'svg-support' ), + 'content' => $bodhi_svgs_help_tab_usage_standard + )); + + /** + * Inline SVG Tab + */ + // inline SVG tab content + $bodhi_svgs_help_tab_inlining_svg = '

            ' . __( 'Render SVG Inline', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_inlining_svg .= '

            ' . __( 'You can embed your SVG image like any standard image with the addition of adding the class style-svg (or your custom class) to any IMG tags that you want this plugin to swap out with your actual SVG code.', 'svg-support' ) . '
            ' . __( 'For example:', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_inlining_svg .= '
            <img class="style-svg" alt="alt-text" src="image-source.svg" />
            ' . __( 'or', 'svg-support' ) . '
            <img class="your-custom-class" alt="alt-text" src="image-source.svg" />
            '; + + $bodhi_svgs_help_tab_inlining_svg .= '

            ' . __( 'The whole IMG tag element will now be dynamically replaced by the actual code of your SVG, making the inner content targetable.', 'svg-support' ) . '
            ' . __( 'This allows you to target elements within your SVG using CSS.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_inlining_svg .= '

            ' . __( 'Please Note:', 'svg-support' ) . '
            - ' . __( 'You will likely need to set your own height and width in your CSS for SVG files to display correctly.', 'svg-support' ) . '
            - ' . __( 'Your uploaded image needs to be an SVG file for this plugin to replace the img tag with the inline SVG code. It will not create SVG files for you.', 'svg-support' ) . '
            - ' . __( 'You can set this target class on any element and the script will traverse all children of that target element looking for IMG tags with SVG in the src to replace.', 'svg-support' ) . '

            '; + + // register inline SVG tab + $screen->add_help_tab( array( + 'id' => 'bodhi_svgs_help_tab-inlining_svg', + 'title' => __( 'Render SVG Inline', 'svg-support' ), + 'content' => $bodhi_svgs_help_tab_inlining_svg + )); + + /** + * Featured Images Tab + */ + // featured images tab content + $bodhi_svgs_help_tab_featured_images = '

            ' . __( 'Featured Images', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_featured_images .= '

            ' . __( 'You can use SVG files as featured images just like any other image format, with the addition of being able to render your featured SVG inline on a per-post basis.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_featured_images .= '

            ' . __( 'To render your featured SVG inline:', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_featured_images .= '
            1. ' . __( 'Make sure "Advanced Mode" is enabled.', 'svg-support' ) . '
            2. ' . __( 'Add your featured SVG like you would any regular featured image format.', 'svg-support' ) . '
            3. ' . __( 'Publish, Save Draft, or Update the post.', 'svg-support' ) . '
            4. ' . __( 'Once the screen reloads, click the new checkbox below the featured image to render your SVG inline.', 'svg-support' ) . '
            5. ' . __( 'Publish, Save Draft, or Update the post a final time to render the SVG inline.', 'svg-support' ) . '
            '; + + // register featured images tab + $screen->add_help_tab( array( + 'id' => 'bodhi_svgs_help_tab-featured_images', + 'title' => __( 'Featured Images', 'svg-support' ), + 'content' => $bodhi_svgs_help_tab_featured_images + )); + + /** + * Animation Tab + */ + $bodhi_svgs_help_tab_animation = '

            ' . __( 'Animation', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_animation .= '

            ' . __( 'So you want to animate your SVG?', 'svg-support' ) . '
            ' . __( 'There\'s a number of ways you can animate an SVG. You could use CSS or JS to target elements within your SVG or even embed the animations in the file itself. Whichever way you choose, there is always a little bit of preparation required before uploading your SVG to your media library.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_animation .= '

            ' . __( 'First, let\'s talk about using CSS or JS to target elements within your SVG.', 'svg-support' ) . '
            ' . __( 'Before you upload your SVG, you\'re going to need some classes to target inside your SVG. To do this, open your SVG file in the code editor of choice (I use Sublime Text). You will see each element within your SVG file written in XML code. Each little part of your SVG has it\'s own bit of code, so it\'s up to you which ones you want to target. It\'s in here that you\'ll place your new classes on each element you want to target.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_animation .= '

            ' . __( 'Then there\'s the option of animating the SVG file itself. There is a number of online tools to do this, or you can use the software of your choice. Once your SVG is animated and ready to go, you then upload it like any other image to your WordPress media library. When you embed it on a page/post, you will need to make sure to add the class to the IMG tag so SVG Support can render it inline. This will ensure your animations are displayed.', 'svg-support' ) . '

            '; + + // register animation tab + $screen->add_help_tab( array( + 'id' => 'bodhi_svgs_help_tab-animation', + 'title' => __( 'Animation', 'svg-support' ), + 'content' => $bodhi_svgs_help_tab_animation + )); + + /** + * DONATIONS Tab + */ + // donations tab content + $bodhi_svgs_help_tab_donations = '

            ' . __( 'Donations', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_donations .= '

            ' . __( 'SVG Support (this plugin) has grown to be used by over 1 million websites actively and is maintained solely by one person. I couldn\'t possibly tell you how many hours have gone into the development, maintenance and support of this plugin. If you find it useful and would like to donate to help keep it going, that would be amazing! I truly appreciate the support and how far this has come.', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_donations .= '

            ' . __( 'Donation Methods:', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_donations .= '

            ' . __( 'PayPal: ', 'svg-support' ) . 'Click Here
            ' . __( 'BTC: 1qF8r2HkTLifND7WLGfWmvxfXc9ze55DZ', 'svg-support' ) . '
            ' . __( 'LTC: LUnQPJrSk6cVFmMqBMv5FAqweJbnzRUz4o', 'svg-support' ) . '
            ' . __( 'ETH: 0x599695Eb51aFe2e5a0DAD60aD9c89Bc8f10B54f4', 'svg-support' ) . '

            '; + + $bodhi_svgs_help_tab_donations .= '

            ' . __( 'Need to buy some crypto to donate?', 'svg-support' ) . '
            ' . __( 'My Coinbase referral link will get $10 USD worth of BTC for free when you spend $100.', 'svg-support' ) . '
            ' . __( '(You don\'t need to send me that much though, anything is appreciated!)', 'svg-support' ) . '
            https://www.coinbase.com/join/59be646cb87715012bbdcc6b

            '; + + // register featured images tab + $screen->add_help_tab( array( + 'id' => 'bodhi_svgs_help_tab-donations', + 'title' => __( 'DONATIONS', 'svg-support' ), + 'content' => $bodhi_svgs_help_tab_donations + )); + + /** + * Help Tab Sidebar + */ + // add help tab sidebar + $screen->set_help_sidebar( + '

            ' . __( 'For more help, visit:', 'svg-support' ) . '

            ' . + '

            ' . __( 'SVG Support Forum', 'svg-support' ) . '

            ' + ); + +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/admin/svgs-settings-page.php b/html/wp-content/plugins/svg-support/admin/svgs-settings-page.php new file mode 100644 index 0000000..788cc17 --- /dev/null +++ b/html/wp-content/plugins/svg-support/admin/svgs-settings-page.php @@ -0,0 +1,503 @@ + + +
            + +
            +

            Version

            + +
            + +
            + +
            + +

            +
            + +

            + + +

            +

            + + + + + +

            +

            + + , + , + + + +

            +

            + +

            + +
            + +
            + +
            + +
            + +
            + +

            +
            + +

            +

            +
            + +

            +

            + +
            + +
            + +
            + +
            + + +
            + +
            + +
            + +

            +
            + +
            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + +
            + + +
            + +
            + + +
            + roles; // Fetch all available roles + $sanitize_roles_array = $bodhi_svgs_options['sanitize_on_upload_roles']; + ?> + +
            + +
            + + + +
            + + +
            + + + +
            + + + +
            +

            +
            +
            +
            + + + +
            + + + +
            + + + +
            + + + +
            + + + +
            +

            +
            +
            +
            + + + +
            + + + +
            + +
            +

            +
            + + + + + +
            + + + +
            +
            +
            + +

            + +

            + +
            + +
            + +
            + +
            + + '; + esc_html_e( 'Usage', 'svg-support' ); + echo ''; + } else { + echo '

            '; + esc_html_e( 'Advanced Usage', 'svg-support' ); + echo '

            '; + } + + ?> + +
            + +

            + +
            +

            + + + +
            + +

            + +

            + +

            <img class="style-svg" alt="alt-text" src="image-source.svg" />
            + +
            <img class="your-custom-class" alt="alt-text" src="image-source.svg" />
            +

            + +

            +
            + +

            + +

            +
            +
            +

            +
            + +
            + +
            + +
            +

            +
            + %s', + esc_url(plugins_url('admin/img/shortpixel.png', BODHI_SVGS_PLUGIN_FILE)), + esc_attr__('ShortPixel logo', 'svg-support') + ); + ?> +

            +

            +

            +

            +
            +
            + + + +
            + +
            + + +
            + +
            + +
            +

            +
            +

            + + + + ★★★★★ + +
            + +

            +

            Leave a rating

            +
            +
            + +
            +

            +
            +

            +

            +

            +
            +
            + +
            +

            +
            +
              +
            • +
            • +
            • +
              +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            • +
            +
            +
            + +
            +

            +
            +


            +


            +

            + + + +

            +

            +
            + | + +

            +

            © | Benbodhi.com

            +

            +
            + +

            +
            +
            + +
            + +
            + +
            + +
            +
            + +
            diff --git a/html/wp-content/plugins/svg-support/composer.json b/html/wp-content/plugins/svg-support/composer.json new file mode 100644 index 0000000..72c8a7e --- /dev/null +++ b/html/wp-content/plugins/svg-support/composer.json @@ -0,0 +1,39 @@ +{ + "name": "benbodhi/svg-support", + "description": "Upload SVG files to the Media Library and render SVG files inline for direct styling/animation of an SVG's internal elements using CSS/JS.", + "type": "wordpress-plugin", + "license": "GPL-2.0-or-later", + "repositories": [ + { + "type": "package", + "package": { + "name": "cure53/dompurify", + "version": "2.5.8", + "dist": { + "url": "https://github.com/cure53/DOMPurify/archive/refs/tags/2.5.8.zip", + "type": "zip" + } + } + } + ], + "require": { + "php": ">=7.4", + "cure53/dompurify": "2.5.8", + "enshrined/svg-sanitize": "^0.21.0" + }, + "scripts": { + "post-install-cmd": [ + "mkdir -p vendor/DOMPurify", + "cp vendor/cure53/dompurify/dist/purify.min.js vendor/DOMPurify/DOMPurify.min.js" + ], + "post-update-cmd": [ + "mkdir -p vendor/DOMPurify", + "cp vendor/cure53/dompurify/dist/purify.min.js vendor/DOMPurify/DOMPurify.min.js" + ] + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/config.codekit3 b/html/wp-content/plugins/svg-support/config.codekit3 new file mode 100644 index 0000000..01f1267 --- /dev/null +++ b/html/wp-content/plugins/svg-support/config.codekit3 @@ -0,0 +1,3267 @@ +{ + "AAInfo" : "This is a CodeKit 3 project config file. EDITING THIS FILE IS A POOR LIFE DECISION. Doing so may cause CodeKit to crash and\/or corrupt your project. Several critical values in this file are 64-bit integers, which JavaScript JSON parsers do not support because JavaScript cannot handle 64-bit integers. These values will be corrupted if the file is parsed with JavaScript. This file is not backwards-compatible with CodeKit 1 or 2. For details, see https:\/\/codekitapp.com\/", + "buildSteps" : [ + { + "name" : "Process All Remaining Files and Folders", + "stepType" : 1, + "uuidString" : "FDF09C14-788E-4A4D-A218-DA6A56580A0D" + } + ], + "creatorBuild" : "34576", + "files" : { + "\/.gitignore" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/.gitignore", + "oF" : 0 + }, + "\/admin\/admin-init.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/admin\/admin-init.php", + "oF" : 0 + }, + "\/admin\/img\/shortpixel.png" : { + "ft" : 32768, + "iS" : 3373, + "oA" : 0, + "oAP" : "\/admin\/img\/shortpixel.png", + "oF" : 0, + "oIPL" : 0, + "opt" : 0, + "oT" : 1, + "ou" : "lpckwebp-none", + "q" : 100, + "rq" : 75 + }, + "\/admin\/plugin-action-meta-links.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/admin\/plugin-action-meta-links.php", + "oF" : 0 + }, + "\/admin\/svgs-settings-page-help.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/admin\/svgs-settings-page-help.php", + "oF" : 0 + }, + "\/admin\/svgs-settings-page.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/admin\/svgs-settings-page.php", + "oF" : 0 + }, + "\/composer.json" : { + "ft" : 524288, + "oA" : 1, + "oAP" : "\/composer-min.json", + "oF" : 0, + "oO" : 0, + "oS" : 1 + }, + "\/composer.lock" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/composer.lock", + "oF" : 0 + }, + "\/css\/jquery.dropdown-min.css" : { + "aP" : 1, + "bl" : 0, + "ci" : 0, + "co" : 0, + "ft" : 16, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/jquery.dropdown-min-min.css", + "oF" : 0, + "pg" : 0 + }, + "\/css\/svgs-admin-edit-post.css" : { + "aP" : 1, + "bl" : 0, + "ci" : 0, + "co" : 0, + "ft" : 16, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-admin-edit-post-min.css", + "oF" : 0, + "pg" : 0 + }, + "\/css\/svgs-admin-simple-mode.css" : { + "aP" : 1, + "bl" : 0, + "ci" : 0, + "co" : 0, + "ft" : 16, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-admin-simple-mode-min.css", + "oF" : 0, + "pg" : 0 + }, + "\/css\/svgs-admin.css" : { + "aP" : 1, + "bl" : 0, + "ci" : 0, + "co" : 0, + "ft" : 16, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-admin-min.css", + "oF" : 0, + "pg" : 0 + }, + "\/css\/svgs-attachment.css" : { + "aP" : 1, + "bl" : 0, + "ci" : 0, + "co" : 0, + "ft" : 16, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-attachment-min.css", + "oF" : 0, + "pg" : 0 + }, + "\/functions\/attachment.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/attachment.php", + "oF" : 0 + }, + "\/functions\/attribute-control.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/attribute-control.php", + "oF" : 0 + }, + "\/functions\/enqueue.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/enqueue.php", + "oF" : 0 + }, + "\/functions\/featured-image.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/featured-image.php", + "oF" : 0 + }, + "\/functions\/localization.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/localization.php", + "oF" : 0 + }, + "\/functions\/meta-cleanup.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/meta-cleanup.php", + "oF" : 0 + }, + "\/functions\/mime-types.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/mime-types.php", + "oF" : 0 + }, + "\/functions\/thumbnail-display.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/functions\/thumbnail-display.php", + "oF" : 0 + }, + "\/includes\/svg-attributes.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/includes\/svg-attributes.php", + "oF" : 0 + }, + "\/includes\/svg-tags.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/includes\/svg-tags.php", + "oF" : 0 + }, + "\/integrations\/wp-all-import.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/integrations\/wp-all-import.php", + "oF" : 0 + }, + "\/js\/gutenberg-filters.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/gutenberg-filters-min.js", + "oF" : 2, + "sC" : 3, + "tS" : 0 + }, + "\/js\/jquery.dropdown.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/jquery.dropdown-min.js", + "oF" : 2, + "sC" : 3, + "tS" : 0 + }, + "\/js\/min\/gutenberg-filters-min.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/gutenberg-filters-min-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/js\/min\/jquery.dropdown-min.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/jquery.dropdown-min-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/js\/min\/svgs-inline-min.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/svgs-inline-min-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/js\/min\/svgs-inline-vanilla-min.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/svgs-inline-vanilla-min-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/js\/svgs-inline-vanilla.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/svgs-inline-vanilla-min.js", + "oF" : 2, + "sC" : 3, + "tS" : 0 + }, + "\/js\/svgs-inline.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/js\/min\/svgs-inline-min.js", + "oF" : 2, + "sC" : 3, + "tS" : 0 + }, + "\/languages\/svgsupport-es_ES.mo" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/languages\/svgsupport-es_ES.mo", + "oF" : 0 + }, + "\/languages\/svgsupport-es_ES.po" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/languages\/svgsupport-es_ES.po", + "oF" : 0 + }, + "\/languages\/svgsupport-sr_RS.mo" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/languages\/svgsupport-sr_RS.mo", + "oF" : 0 + }, + "\/languages\/svgsupport-sr_RS.po" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/languages\/svgsupport-sr_RS.po", + "oF" : 0 + }, + "\/languages\/svgsupport.pot" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/languages\/svgsupport.pot", + "oF" : 0 + }, + "\/README.md" : { + "cB" : 0, + "cS" : 0, + "eF" : 1, + "eL" : 1, + "ema" : 1, + "eSQ" : 1, + "ft" : 4096, + "hM" : 0, + "oA" : 1, + "oAP" : "\/README.html", + "oF" : 1, + "oFM" : 0, + "oS" : 0, + "pHT" : 0, + "pME" : 1, + "rFN" : 0, + "uCM" : 0 + }, + "\/readme.txt" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/readme.txt", + "oF" : 0 + }, + "\/scss\/jquery.dropdown.scss" : { + "aP" : 1, + "bl" : 1, + "co" : 0, + "dP" : 10, + "ec" : 1, + "ft" : 4, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/jquery.dropdown-min.css", + "oF" : 2, + "oS" : 3, + "pg" : 0, + "sct" : 1 + }, + "\/scss\/svgs-admin-edit-post.scss" : { + "aP" : 0, + "bl" : 0, + "co" : 0, + "dP" : 10, + "ec" : 1, + "ft" : 4, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-admin-edit-post.css", + "oF" : 2, + "oS" : 3, + "pg" : 0, + "sct" : 1 + }, + "\/scss\/svgs-admin-simple-mode.scss" : { + "aP" : 0, + "bl" : 0, + "co" : 0, + "dP" : 10, + "ec" : 1, + "ft" : 4, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-admin-simple-mode.css", + "oF" : 2, + "oS" : 3, + "pg" : 0, + "sct" : 1 + }, + "\/scss\/svgs-admin.scss" : { + "aP" : 0, + "bl" : 0, + "co" : 0, + "dP" : 10, + "ec" : 1, + "ft" : 4, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-admin.css", + "oF" : 2, + "oS" : 3, + "pg" : 0, + "sct" : 1 + }, + "\/scss\/svgs-attachment.scss" : { + "aP" : 0, + "bl" : 0, + "co" : 0, + "dP" : 10, + "ec" : 1, + "ft" : 4, + "ma" : 0, + "oA" : 0, + "oAP" : "\/css\/svgs-attachment.css", + "oF" : 2, + "oS" : 3, + "pg" : 0, + "sct" : 1 + }, + "\/svg-support.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/svg-support.php", + "oF" : 0 + }, + "\/svg-support.png" : { + "ft" : 32768, + "iS" : 38215, + "oA" : 0, + "oAP" : "\/svg-support.png", + "oF" : 0, + "oIPL" : 0, + "opt" : 0, + "oT" : 1, + "ou" : "lpckwebp-none", + "q" : 100, + "rq" : 75 + }, + "\/uninstall.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/uninstall.php", + "oF" : 0 + }, + "\/vendor\/autoload.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/autoload.php", + "oF" : 0 + }, + "\/vendor\/composer\/autoload_classmap.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/autoload_classmap.php", + "oF" : 0 + }, + "\/vendor\/composer\/autoload_namespaces.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/autoload_namespaces.php", + "oF" : 0 + }, + "\/vendor\/composer\/autoload_psr4.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/autoload_psr4.php", + "oF" : 0 + }, + "\/vendor\/composer\/autoload_real.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/autoload_real.php", + "oF" : 0 + }, + "\/vendor\/composer\/autoload_static.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/autoload_static.php", + "oF" : 0 + }, + "\/vendor\/composer\/ClassLoader.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/ClassLoader.php", + "oF" : 0 + }, + "\/vendor\/composer\/installed.json" : { + "ft" : 524288, + "oA" : 1, + "oAP" : "\/vendor\/composer\/installed-min.json", + "oF" : 0, + "oO" : 0, + "oS" : 1 + }, + "\/vendor\/composer\/installed.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/installed.php", + "oF" : 0 + }, + "\/vendor\/composer\/InstalledVersions.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/InstalledVersions.php", + "oF" : 0 + }, + "\/vendor\/composer\/LICENSE" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/LICENSE", + "oF" : 0 + }, + "\/vendor\/composer\/platform_check.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/composer\/platform_check.php", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.babelrc" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/.babelrc", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.editorconfig" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.editorconfig", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.github\/dependabot.yml" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.github\/dependabot.yml", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.github\/FUNDING.yml" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.github\/FUNDING.yml", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.github\/ISSUE_TEMPLATE.md" : { + "cB" : 0, + "cS" : 0, + "eF" : 1, + "eL" : 1, + "ema" : 1, + "eSQ" : 1, + "ft" : 4096, + "hM" : 0, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/.github\/ISSUE_TEMPLATE.html", + "oF" : 0, + "oFM" : 0, + "oS" : 0, + "pHT" : 0, + "pME" : 1, + "rFN" : 0, + "uCM" : 0 + }, + "\/vendor\/cure53\/dompurify\/.github\/PULL_REQUEST_TEMPLATE.md" : { + "cB" : 0, + "cS" : 0, + "eF" : 1, + "eL" : 1, + "ema" : 1, + "eSQ" : 1, + "ft" : 4096, + "hM" : 0, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/.github\/PULL_REQUEST_TEMPLATE.html", + "oF" : 0, + "oFM" : 0, + "oS" : 0, + "pHT" : 0, + "pME" : 1, + "rFN" : 0, + "uCM" : 0 + }, + "\/vendor\/cure53\/dompurify\/.github\/workflows\/build-and-test.yml" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.github\/workflows\/build-and-test.yml", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.github\/workflows\/codeql-analysis.yml" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.github\/workflows\/codeql-analysis.yml", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.gitignore" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.gitignore", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.nvmrc" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.nvmrc", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.prettierignore" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.prettierignore", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.prettierrc" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.prettierrc", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/.settings\/.gitignore" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/.settings\/.gitignore", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/bower.json" : { + "ft" : 524288, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/bower-min.json", + "oF" : 0, + "oO" : 0, + "oS" : 1 + }, + "\/vendor\/cure53\/dompurify\/demos\/advanced-config-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/advanced-config-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/basic-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/basic-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/config-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/config-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-link-proxy-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-link-proxy-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-mentaljs-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-mentaljs-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-node-removal-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-node-removal-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-node-removal2-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-node-removal2-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-proxy-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-proxy-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-removal-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-removal-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-sanitize-css-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-sanitize-css-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-scheme-allowlist.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-scheme-allowlist.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-svg-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-svg-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/hooks-target-blank-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/hooks-target-blank-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/lib\/Mental.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/lib\/Mental-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/README.md" : { + "cB" : 0, + "cS" : 0, + "eF" : 1, + "eL" : 1, + "ema" : 1, + "eSQ" : 1, + "ft" : 4096, + "hM" : 0, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/README.html", + "oF" : 0, + "oFM" : 0, + "oS" : 0, + "pHT" : 0, + "pME" : 1, + "rFN" : 0, + "uCM" : 0 + }, + "\/vendor\/cure53\/dompurify\/demos\/trusted-types-demo.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/demos\/trusted-types-demo.html", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.cjs.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify.cjs-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.cjs.js.map" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify.cjs.js.map", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.es.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify.es-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.es.js.map" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify.es.js.map", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.js.map" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify.js.map", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.min.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify.min-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/dist\/purify.min.js.map" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/dist\/purify.min.js.map", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/LICENSE" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/LICENSE", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/package-lock.json" : { + "ft" : 524288, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/package-lock-min.json", + "oF" : 0, + "oO" : 0, + "oS" : 1 + }, + "\/vendor\/cure53\/dompurify\/package.json" : { + "ft" : 524288, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/package-min.json", + "oF" : 0, + "oO" : 0, + "oS" : 1 + }, + "\/vendor\/cure53\/dompurify\/README.md" : { + "cB" : 0, + "cS" : 0, + "eF" : 1, + "eL" : 1, + "ema" : 1, + "eSQ" : 1, + "ft" : 4096, + "hM" : 0, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/README.html", + "oF" : 0, + "oFM" : 0, + "oS" : 0, + "pHT" : 0, + "pME" : 1, + "rFN" : 0, + "uCM" : 0 + }, + "\/vendor\/cure53\/dompurify\/rollup.config.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/rollup.config-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/scripts\/commit-amend-build.sh" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/scripts\/commit-amend-build.sh", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/scripts\/server.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/scripts\/server-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/SECURITY.md" : { + "cB" : 0, + "cS" : 0, + "eF" : 1, + "eL" : 1, + "ema" : 1, + "eSQ" : 1, + "ft" : 4096, + "hM" : 0, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/SECURITY.html", + "oF" : 0, + "oFM" : 0, + "oS" : 0, + "pHT" : 0, + "pME" : 1, + "rFN" : 0, + "uCM" : 0 + }, + "\/vendor\/cure53\/dompurify\/src\/attrs.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/src\/attrs-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/src\/license_header" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/src\/license_header", + "oF" : 0 + }, + "\/vendor\/cure53\/dompurify\/src\/purify.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/src\/purify-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/src\/regexp.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/src\/regexp-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/src\/tags.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/src\/tags-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/src\/utils.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/src\/utils-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/bootstrap-test-suite.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/bootstrap-test-suite-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/config\/setup.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/config\/setup-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/fixtures\/expect.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/fixtures\/expect-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/jsdom-node-runner.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/jsdom-node-runner-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/jsdom-node.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/jsdom-node-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/karma.conf.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/karma.conf-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/karma.custom-launchers.config.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/karma.custom-launchers.config-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/purify.min.spec.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/purify.min.spec-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/purify.spec.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/purify.spec-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/test\/test-suite.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 1, + "oAP" : "\/vendor\/cure53\/dompurify\/test\/test-suite-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/cure53\/dompurify\/website\/index.html" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/cure53\/dompurify\/website\/index.html", + "oF" : 0 + }, + "\/vendor\/DOMPurify\/DOMPurify.min.js" : { + "bF" : 0, + "ft" : 64, + "ma" : 0, + "mi" : 1, + "oA" : 0, + "oAP" : "\/vendor\/DOMPurify\/DOMPurify.min-min.js", + "oF" : 0, + "sC" : 3, + "tS" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/composer.json" : { + "ft" : 524288, + "oA" : 1, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/composer-min.json", + "oF" : 0, + "oO" : 0, + "oS" : 1 + }, + "\/vendor\/enshrined\/svg-sanitize\/LICENSE" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/LICENSE", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/README.md" : { + "cB" : 0, + "cS" : 0, + "eF" : 1, + "eL" : 1, + "ema" : 1, + "eSQ" : 1, + "ft" : 4096, + "hM" : 0, + "oA" : 0, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/README.html", + "oF" : 0, + "oFM" : 0, + "oS" : 0, + "pHT" : 0, + "pME" : 1, + "rFN" : 0, + "uCM" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/data\/AllowedAttributes.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/data\/AllowedAttributes.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/data\/AllowedTags.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/data\/AllowedTags.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/data\/AttributeInterface.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/data\/AttributeInterface.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/data\/TagInterface.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/data\/TagInterface.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/data\/XPath.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/data\/XPath.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/ElementReference\/Resolver.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/ElementReference\/Resolver.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/ElementReference\/Subject.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/ElementReference\/Subject.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/ElementReference\/Usage.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/ElementReference\/Usage.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/Exceptions\/NestingException.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/Exceptions\/NestingException.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/Helper.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/Helper.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/Sanitizer.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/Sanitizer.php", + "oF" : 0 + }, + "\/vendor\/enshrined\/svg-sanitize\/src\/svg-scanner.php" : { + "cB" : 0, + "ft" : 8192, + "hM" : 0, + "oA" : 2, + "oAP" : "\/vendor\/enshrined\/svg-sanitize\/src\/svg-scanner.php", + "oF" : 0 + } + }, + "hooks" : [ + + ], + "manualImportLinks" : { + + }, + "projectAttributes" : { + "creationDate" : 507572464, + "displayValue" : "svg-support", + "displayValueWasSetByUser" : 0, + "iconImageName" : "\/svg-support.png", + "iconImageWasSetByUser" : 1 + }, + "projectSettings" : { + "abortBuildOnError" : 1, + "allowInjectionReloads" : 1, + "alwaysUseExternalServer" : 0, + "animateCSSInjections" : 1, + "autoBuildNewItems" : 1, + "autoprefixerEnableIEGrid" : 0, + "babel7PresetType" : 1, + "babelAllowRCFiles" : 0, + "babelAuxiliaryCommentAfter" : "", + "babelAuxiliaryCommentBefore" : "", + "babelConfigType" : 0, + "babelCustomPluginsList" : "", + "babelCustomPresetsList" : "", + "babelExcludeString" : "\/\\\/node_modules\\\/\/, \/\\\/core-js\\\/\/, \/\\\/bower_components\\\/\/", + "babelInsertModuleIDs" : 0, + "babelModuleID" : "", + "babelNoComments" : 0, + "babelPlugins" : { + "arrow-functions" : { + "active" : 0 + }, + "async-generator-functions" : { + "active" : 0 + }, + "async-to-generator" : { + "active" : 0 + }, + "block-scoped-functions" : { + "active" : 0 + }, + "block-scoping" : { + "active" : 0 + }, + "class-properties" : { + "active" : 0 + }, + "classes" : { + "active" : 0 + }, + "computed-properties" : { + "active" : 0 + }, + "decorators" : { + "active" : 0 + }, + "destructuring" : { + "active" : 0 + }, + "do-expressions" : { + "active" : 0 + }, + "dotall-regex" : { + "active" : 0 + }, + "duplicate-keys" : { + "active" : 0 + }, + "exponentiation-operator" : { + "active" : 0 + }, + "export-default-from" : { + "active" : 0 + }, + "export-namespace-from" : { + "active" : 0 + }, + "external-helpers" : { + "active" : 0 + }, + "flow-strip-types" : { + "active" : 0 + }, + "for-of" : { + "active" : 0 + }, + "function-bind" : { + "active" : 0 + }, + "function-name" : { + "active" : 0 + }, + "function-sent" : { + "active" : 0 + }, + "inline-consecutive-adds" : { + "active" : 0 + }, + "inline-environment-variables" : { + "active" : 0 + }, + "instanceof" : { + "active" : 0 + }, + "jscript" : { + "active" : 0 + }, + "literals" : { + "active" : 0 + }, + "logical-assignment-operators" : { + "active" : 0 + }, + "member-expression-literals" : { + "active" : 0 + }, + "merge-sibling-variables" : { + "active" : 0 + }, + "minify-booleans" : { + "active" : 0 + }, + "minify-builtins" : { + "active" : 0 + }, + "minify-constant-folding" : { + "active" : 0 + }, + "minify-dead-code-elimination" : { + "active" : 0 + }, + "minify-flip-comparisons" : { + "active" : 0 + }, + "minify-guarded-expressions" : { + "active" : 0 + }, + "minify-infinity" : { + "active" : 0 + }, + "minify-mangle-names" : { + "active" : 0 + }, + "minify-numeric-literals" : { + "active" : 0 + }, + "minify-simplify" : { + "active" : 0 + }, + "minify-type-constructors" : { + "active" : 0 + }, + "modules-amd" : { + "active" : 0 + }, + "modules-commonjs" : { + "active" : 0 + }, + "modules-systemjs" : { + "active" : 0 + }, + "modules-umd" : { + "active" : 0 + }, + "named-capturing-groups-regex" : { + "active" : 0 + }, + "new-target" : { + "active" : 0 + }, + "node-env-inline" : { + "active" : 0 + }, + "nullish-coalescing-operator" : { + "active" : 0 + }, + "numeric-separator" : { + "active" : 0 + }, + "object-assign" : { + "active" : 0 + }, + "object-rest-spread" : { + "active" : 0 + }, + "object-set-prototype-of-to-assign" : { + "active" : 0 + }, + "object-super" : { + "active" : 0 + }, + "optional-catch-binding" : { + "active" : 0 + }, + "optional-chaining" : { + "active" : 0 + }, + "parameters" : { + "active" : 0 + }, + "partial-application" : { + "active" : 0 + }, + "pipeline-operator" : { + "active" : 0 + }, + "private-methods" : { + "active" : 0 + }, + "property-literals" : { + "active" : 0 + }, + "property-mutators" : { + "active" : 0 + }, + "proto-to-assign" : { + "active" : 0 + }, + "react-constant-elements" : { + "active" : 0 + }, + "react-display-name" : { + "active" : 0 + }, + "react-inline-elements" : { + "active" : 0 + }, + "react-jsx" : { + "active" : 0 + }, + "react-jsx-compat" : { + "active" : 0 + }, + "react-jsx-self" : { + "active" : 0 + }, + "react-jsx-source" : { + "active" : 0 + }, + "regenerator" : { + "active" : 0 + }, + "regexp-constructors" : { + "active" : 0 + }, + "remove-console" : { + "active" : 0 + }, + "remove-debugger" : { + "active" : 0 + }, + "remove-undefined" : { + "active" : 0 + }, + "reserved-words" : { + "active" : 0 + }, + "runtime" : { + "active" : 0 + }, + "shorthand-properties" : { + "active" : 0 + }, + "simplify-comparison-operators" : { + "active" : 0 + }, + "spread" : { + "active" : 0 + }, + "sticky-regex" : { + "active" : 0 + }, + "strict-mode" : { + "active" : 0 + }, + "template-literals" : { + "active" : 0 + }, + "throw-expressions" : { + "active" : 0 + }, + "typeof-symbol" : { + "active" : 0 + }, + "undefined-to-void" : { + "active" : 0 + }, + "unicode-property-regex" : { + "active" : 0 + }, + "unicode-regex" : { + "active" : 0 + } + }, + "babelRetainLines" : 0, + "babelUseBuiltInsType" : 0, + "bowerAbbreviatedPath" : "bower_components", + "bowerForceLatestOnConflict" : 1, + "bowerTargetDependencyListType" : 1, + "bowerUseExactVersion" : 0, + "browserRefreshDelay" : 0, + "browserslistString" : ">0.2%, last 2 versions, Firefox ESR, not dead", + "buildEnvironment" : 0, + "buildFolderActive" : 0, + "buildFolderName" : "build", + "cleanBuild" : 1, + "cssoForceMediaMerge" : 0, + "cssoRestructure" : 1, + "environmentVariableEntries" : [ + "NODE_ENV:::production" + ], + "esLintConfigFileHandlingType" : 0, + "esLintECMAVersion" : 7, + "esLintEnvironmentsMask" : 1, + "esLintRules" : { + "accessor-pairs" : { + "active" : 0, + "optionString" : "{'setWithoutGet': true, 'getWithoutSet': false}" + }, + "array-bracket-newline" : { + "active" : 0, + "optionString" : "{'multiline': true, 'minItems': null}" + }, + "array-bracket-spacing" : { + "active" : 0, + "optionString" : "'never', {'singleValue': false, 'objectsInArrays': false, 'arraysInArrays': false}" + }, + "array-callback-return" : { + "active" : 0, + "optionString" : "" + }, + "array-element-newline" : { + "active" : 0, + "optionString" : "'always'" + }, + "arrow-body-style" : { + "active" : 0, + "optionString" : "'as-needed', {'requireReturnForObjectLiteral': false}" + }, + "arrow-parens" : { + "active" : 0, + "optionString" : "'always'" + }, + "arrow-spacing" : { + "active" : 0, + "optionString" : "{'before': true, 'after': true}" + }, + "block-scoped-var" : { + "active" : 0 + }, + "block-spacing" : { + "active" : 0, + "optionString" : "'always'" + }, + "brace-style" : { + "active" : 0, + "optionString" : "'1tbs', {'allowSingleLine': true}" + }, + "camelcase" : { + "active" : 0, + "optionString" : "{'properties': 'always'}" + }, + "capitalized-comments" : { + "active" : 0, + "optionString" : "'always', {'ignoreInlineComments': false, 'ignoreConsecutiveComments': false}" + }, + "class-methods-use-this" : { + "active" : 0, + "optionString" : "{'exceptMethods': []}" + }, + "comma-dangle" : { + "active" : 1, + "optionString" : "'never'" + }, + "comma-spacing" : { + "active" : 0, + "optionString" : "{'before': false, 'after': true}" + }, + "comma-style" : { + "active" : 0, + "optionString" : "'last'" + }, + "complexity" : { + "active" : 0, + "optionString" : "20" + }, + "computed-property-spacing" : { + "active" : 0, + "optionString" : "'never'" + }, + "consistent-return" : { + "active" : 0, + "optionString" : "{'treatUndefinedAsUnspecified': false}" + }, + "consistent-this" : { + "active" : 0, + "optionString" : "'that'" + }, + "constructor-super" : { + "active" : 1 + }, + "curly" : { + "active" : 0, + "optionString" : "'all'" + }, + "default-case" : { + "active" : 0 + }, + "default-case-last" : { + "active" : 0 + }, + "default-param-last" : { + "active" : 0 + }, + "dot-location" : { + "active" : 0, + "optionString" : "'object'" + }, + "dot-notation" : { + "active" : 0, + "optionString" : "{'allowKeywords': false}" + }, + "eol-last" : { + "active" : 0, + "optionString" : "'always'" + }, + "eqeqeq" : { + "active" : 0, + "optionString" : "'always', {'null': 'always'}" + }, + "for-direction" : { + "active" : 0 + }, + "func-call-spacing" : { + "active" : 0, + "optionString" : "'never'" + }, + "func-name-matching" : { + "active" : 0, + "optionString" : "'always', {'includeCommonJSModuleExports': false}" + }, + "func-names" : { + "active" : 0, + "optionString" : "'always'" + }, + "func-style" : { + "active" : 0, + "optionString" : "'expression'" + }, + "function-call-argument-newline" : { + "active" : 0, + "optionString" : "'always'" + }, + "function-paren-newline" : { + "active" : 0, + "optionString" : "'multiline'" + }, + "generator-star-spacing" : { + "active" : 0, + "optionString" : "{'before': true, 'after': false}" + }, + "getter-return" : { + "active" : 0, + "optionString" : "{'allowImplicit': false}" + }, + "grouped-accessor-pairs" : { + "active" : 0, + "optionString" : "'anyOrder'" + }, + "guard-for-in" : { + "active" : 0 + }, + "id-denylist" : { + "active" : 0, + "optionString" : "'data', 'err', 'e', 'cb', 'callback'" + }, + "id-length" : { + "active" : 0, + "optionString" : "{'min': 2, 'max': 1000, 'properties': 'always', 'exceptions': ['x', 'i', 'y']}" + }, + "id-match" : { + "active" : 0, + "optionString" : "'^[a-z]+([A-Z][a-z]+)*$', {'properties': false, 'onlyDeclarations': true}" + }, + "implicit-arrow-linebreak" : { + "active" : 0, + "optionString" : "'beside'" + }, + "indent" : { + "active" : 0, + "optionString" : "4, {'SwitchCase': 0, 'VariableDeclarator': 1, 'outerIIFEBody': 1, }" + }, + "init-declarations" : { + "active" : 0, + "optionString" : "'always', {'ignoreForLoopInit': true}" + }, + "jsx-quotes" : { + "active" : 0, + "optionString" : "'prefer-double'" + }, + "key-spacing" : { + "active" : 0, + "optionString" : "{'singleLine': {'beforeColon': false, 'afterColon': true, 'mode':'strict'}, 'multiLine': {'beforeColon': false, 'afterColon': true, 'align': 'value', 'mode':'minimum'}}" + }, + "keyword-spacing" : { + "active" : 0, + "optionString" : "{'before': true, 'after': true, 'overrides': {}}" + }, + "line-comment-position" : { + "active" : 0, + "optionString" : "{'position': 'above'}" + }, + "linebreak-style" : { + "active" : 0, + "optionString" : "'unix'" + }, + "lines-around-comment" : { + "active" : 0, + "optionString" : "{'beforeBlockComment': true}" + }, + "lines-between-class-members" : { + "active" : 0, + "optionString" : "'always', {exceptAfterSingleLine: false}" + }, + "logical-assignment-operators" : { + "active" : 0, + "optionString" : "'always', {'enforceForIfStatements': false}" + }, + "max-classes-per-file" : { + "active" : 0, + "optionString" : "1" + }, + "max-depth" : { + "active" : 0, + "optionString" : "{'max': 4}" + }, + "max-len" : { + "active" : 0, + "optionString" : "{'code': 80, 'comments': 80, 'tabWidth': 4, 'ignoreUrls': true, 'ignoreStrings': true, 'ignoreTemplateLiterals': true, 'ignoreRegExpLiterals': true}" + }, + "max-lines" : { + "active" : 0, + "optionString" : "{'max': 300, 'skipBlankLines': true, 'skipComments': true}" + }, + "max-lines-per-function" : { + "active" : 0, + "optionString" : "{'max': 50, 'skipBlankLines': true, 'skipComments': true, 'IIFEs': false}" + }, + "max-nested-callbacks" : { + "active" : 0, + "optionString" : "{'max': 10}" + }, + "max-params" : { + "active" : 0, + "optionString" : "{'max': 4}" + }, + "max-statements" : { + "active" : 0, + "optionString" : "{'max': 10}, {'ignoreTopLevelFunctions': true}" + }, + "max-statements-per-line" : { + "active" : 0, + "optionString" : "{'max': 1}" + }, + "multiline-comment-style" : { + "active" : 0, + "optionString" : "'starred-block'" + }, + "multiline-ternary" : { + "active" : 0, + "optionString" : "'always'" + }, + "new-cap" : { + "active" : 0, + "optionString" : "{'newIsCap': true, 'capIsNew': true, 'newIsCapExceptions': [], 'capIsNewExceptions': ['Array', 'Boolean', 'Date', 'Error', 'Function', 'Number', 'Object', 'RegExp', 'String', 'Symbol'], 'properties': true}" + }, + "new-parens" : { + "active" : 0, + "optionString" : "" + }, + "newline-per-chained-call" : { + "active" : 0, + "optionString" : "{'ignoreChainWithDepth': 2}" + }, + "no-alert" : { + "active" : 0 + }, + "no-array-constructor" : { + "active" : 0 + }, + "no-async-promise-executor" : { + "active" : 0 + }, + "no-await-in-loop" : { + "active" : 0 + }, + "no-bitwise" : { + "active" : 0, + "optionString" : "{'allow': ['~'], 'int32Hint': true}" + }, + "no-caller" : { + "active" : 0 + }, + "no-case-declarations" : { + "active" : 1 + }, + "no-class-assign" : { + "active" : 1 + }, + "no-compare-neg-zero" : { + "active" : 0 + }, + "no-cond-assign" : { + "active" : 1, + "optionString" : "'except-parens'" + }, + "no-confusing-arrow" : { + "active" : 0, + "optionString" : "{'allowParens': false}" + }, + "no-console" : { + "active" : 1, + "optionString" : "{'allow': ['warn', 'error']}" + }, + "no-const-assign" : { + "active" : 1 + }, + "no-constant-binary-expression" : { + "active" : 0 + }, + "no-constant-condition" : { + "active" : 1, + "optionString" : "{'checkLoops': true}" + }, + "no-constructor-return" : { + "active" : 0 + }, + "no-continue" : { + "active" : 0 + }, + "no-control-regex" : { + "active" : 1 + }, + "no-debugger" : { + "active" : 1 + }, + "no-delete-var" : { + "active" : 1 + }, + "no-div-regex" : { + "active" : 0 + }, + "no-dupe-args" : { + "active" : 1 + }, + "no-dupe-class-members" : { + "active" : 1 + }, + "no-dupe-else-if" : { + "active" : 1 + }, + "no-dupe-keys" : { + "active" : 1 + }, + "no-duplicate-case" : { + "active" : 1 + }, + "no-duplicate-imports" : { + "active" : 0, + "optionString" : "{'includeExports': false}" + }, + "no-else-return" : { + "active" : 0 + }, + "no-empty" : { + "active" : 1, + "optionString" : "{'allowEmptyCatch': false}" + }, + "no-empty-character-class" : { + "active" : 1 + }, + "no-empty-function" : { + "active" : 0, + "optionString" : "{'allow': []}" + }, + "no-empty-pattern" : { + "active" : 1 + }, + "no-empty-static-block" : { + "active" : 1 + }, + "no-eq-null" : { + "active" : 0 + }, + "no-eval" : { + "active" : 0, + "optionString" : "{'allowIndirect': false}" + }, + "no-ex-assign" : { + "active" : 1 + }, + "no-extend-native" : { + "active" : 0, + "optionString" : "{'exceptions': []}" + }, + "no-extra-bind" : { + "active" : 0 + }, + "no-extra-boolean-cast" : { + "active" : 1 + }, + "no-extra-label" : { + "active" : 0 + }, + "no-extra-parens" : { + "active" : 1, + "optionString" : "'all', {'conditionalAssign': false, 'returnAssign': false, 'nestedBinaryExpressions': false}" + }, + "no-extra-semi" : { + "active" : 1 + }, + "no-fallthrough" : { + "active" : 1, + "optionString" : "{'allowEmptyCase': false}" + }, + "no-floating-decimal" : { + "active" : 0 + }, + "no-func-assign" : { + "active" : 1 + }, + "no-global-assign" : { + "active" : 0, + "optionString" : "{'exceptions': []}" + }, + "no-implicit-coercion" : { + "active" : 0, + "optionString" : "{'boolean': true, 'number': true, 'string': true, 'allow': []}" + }, + "no-implicit-globals" : { + "active" : 0 + }, + "no-implied-eval" : { + "active" : 0 + }, + "no-import-assign" : { + "active" : 1 + }, + "no-inline-comments" : { + "active" : 0 + }, + "no-inner-declarations" : { + "active" : 1, + "optionString" : "'functions'" + }, + "no-invalid-regexp" : { + "active" : 1, + "optionString" : "{'allowConstructorFlags': ['u', 'y']}" + }, + "no-invalid-this" : { + "active" : 0, + "optionString" : "" + }, + "no-irregular-whitespace" : { + "active" : 1, + "optionString" : "{'skipStrings': true, 'skipComments': false, 'skipRegExps': true, 'skipTemplates': true}" + }, + "no-iterator" : { + "active" : 0 + }, + "no-label-var" : { + "active" : 0 + }, + "no-labels" : { + "active" : 0, + "optionString" : "{'allowLoop': false, 'allowSwitch': false}" + }, + "no-lone-blocks" : { + "active" : 0 + }, + "no-lonely-if" : { + "active" : 0 + }, + "no-loop-func" : { + "active" : 0 + }, + "no-loss-of-precision" : { + "active" : 0 + }, + "no-magic-numbers" : { + "active" : 0, + "optionString" : "{'ignore': [], 'ignoreArrayIndexes': true, 'enforceConst': false, 'detectObjects': false}" + }, + "no-misleading-character-class" : { + "active" : 0 + }, + "no-mixed-operators" : { + "active" : 0, + "optionString" : "{'groups': [['+', '-', '*', '\/', '%', '**'], ['&', '|', '^', '~', '<<', '>>', '>>>'], ['==', '!=', '===', '!==', '>', '>=', '<', '<='], ['&&', '||'], ['in', 'instanceof']], 'allowSamePrecedence': true}" + }, + "no-mixed-spaces-and-tabs" : { + "active" : 0, + "optionString" : "" + }, + "no-multi-assign" : { + "active" : 0, + "optionString" : "{'ignoreNonDeclaration': false}" + }, + "no-multi-spaces" : { + "active" : 0, + "optionString" : "{'exceptions': {'Property': true, 'BinaryExpression': false, 'VariableDeclarator': false, 'ImportDeclaration': false}}" + }, + "no-multi-str" : { + "active" : 0 + }, + "no-multiple-empty-lines" : { + "active" : 0, + "optionString" : "{'max': 2, 'maxBOF': 2, 'maxEOF': 2}" + }, + "no-negated-condition" : { + "active" : 0 + }, + "no-nested-ternary" : { + "active" : 0 + }, + "no-new" : { + "active" : 0 + }, + "no-new-func" : { + "active" : 0 + }, + "no-new-native-nonconstructor" : { + "active" : 1 + }, + "no-new-symbol" : { + "active" : 1 + }, + "no-new-wrappers" : { + "active" : 0 + }, + "no-nonoctal-decimal-escape" : { + "active" : 0 + }, + "no-obj-calls" : { + "active" : 1 + }, + "no-object-constructor" : { + "active" : 0 + }, + "no-octal" : { + "active" : 1 + }, + "no-octal-escape" : { + "active" : 0 + }, + "no-param-reassign" : { + "active" : 0, + "optionString" : "{'props': false}" + }, + "no-plusplus" : { + "active" : 0, + "optionString" : "{'allowForLoopAfterthoughts': false}" + }, + "no-promise-executor-return" : { + "active" : 0 + }, + "no-proto" : { + "active" : 0 + }, + "no-prototype-builtins" : { + "active" : 0 + }, + "no-redeclare" : { + "active" : 1, + "optionString" : "{'builtinGlobals': false}" + }, + "no-regex-spaces" : { + "active" : 1 + }, + "no-restricted-exports" : { + "active" : 0, + "optionString" : "{'restrictedNamedExports': []}" + }, + "no-restricted-globals" : { + "active" : 0, + "optionString" : "'event', 'fdescribe'" + }, + "no-restricted-imports" : { + "active" : 0, + "optionString" : "" + }, + "no-restricted-properties" : { + "active" : 0, + "optionString" : "[{'object': 'disallowedObjectName', 'property': 'disallowedPropertyName'}, {'object': 'disallowedObjectName', 'property': 'anotherDisallowedPropertyName', 'message': 'Please use allowedObjectName.allowedPropertyName.'}]" + }, + "no-restricted-syntax" : { + "active" : 0, + "optionString" : "'FunctionExpression', 'WithStatement'" + }, + "no-return-assign" : { + "active" : 0, + "optionString" : "'except-parens'" + }, + "no-script-url" : { + "active" : 0 + }, + "no-self-assign" : { + "active" : 1, + "optionString" : "{'props': false}" + }, + "no-self-compare" : { + "active" : 1 + }, + "no-sequences" : { + "active" : 0, + "optionString" : "{'allowInParentheses': true}" + }, + "no-setter-return" : { + "active" : 1 + }, + "no-shadow" : { + "active" : 0, + "optionString" : "{'builtinGlobals': false, 'hoist': 'functions', 'allow': []}" + }, + "no-shadow-restricted-names" : { + "active" : 0 + }, + "no-sparse-arrays" : { + "active" : 1 + }, + "no-tabs" : { + "active" : 0, + "optionString" : "" + }, + "no-template-curly-in-string" : { + "active" : 1 + }, + "no-ternary" : { + "active" : 0 + }, + "no-this-before-super" : { + "active" : 1 + }, + "no-throw-literal" : { + "active" : 0 + }, + "no-trailing-spaces" : { + "active" : 0, + "optionString" : "{'skipBlankLines': false}" + }, + "no-undef" : { + "active" : 1, + "optionString" : "{'typeof': false}" + }, + "no-undef-init" : { + "active" : 0 + }, + "no-undefined" : { + "active" : 0 + }, + "no-underscore-dangle" : { + "active" : 0, + "optionString" : "{'allow': [], 'allowAfterThis': false, 'allowAfterSuper': false}" + }, + "no-unexpected-multiline" : { + "active" : 1 + }, + "no-unmodified-loop-condition" : { + "active" : 0 + }, + "no-unneeded-ternary" : { + "active" : 0, + "optionString" : "{'defaultAssignment': true}" + }, + "no-unreachable" : { + "active" : 1 + }, + "no-unreachable-loop" : { + "active" : 0, + "optionString" : "{'ignore': []}" + }, + "no-unsafe-finally" : { + "active" : 1 + }, + "no-unsafe-negation" : { + "active" : 0, + "optionString" : "" + }, + "no-unsafe-optional-chaining" : { + "active" : 0, + "optionString" : "{'disallowArithmeticOperators': false}" + }, + "no-unused-expressions" : { + "active" : 0, + "optionString" : "{'allowShortCircuit': false, 'allowTernary': false}" + }, + "no-unused-labels" : { + "active" : 1 + }, + "no-unused-private-class-members" : { + "active" : 0 + }, + "no-unused-vars" : { + "active" : 1, + "optionString" : "{'vars': 'all', 'args': 'after-used', 'caughtErrors': 'none'}" + }, + "no-use-before-define" : { + "active" : 0, + "optionString" : "{'functions': true, 'classes': true}" + }, + "no-useless-backreference" : { + "active" : 0 + }, + "no-useless-call" : { + "active" : 0 + }, + "no-useless-catch" : { + "active" : 0 + }, + "no-useless-computed-key" : { + "active" : 1, + "optionString" : "" + }, + "no-useless-concat" : { + "active" : 0 + }, + "no-useless-constructor" : { + "active" : 0 + }, + "no-useless-escape" : { + "active" : 0 + }, + "no-useless-rename" : { + "active" : 0, + "optionString" : "{'ignoreDestructuring': false, 'ignoreImport': false, 'ignoreExport': false}" + }, + "no-useless-return" : { + "active" : 0 + }, + "no-var" : { + "active" : 0 + }, + "no-void" : { + "active" : 0, + "optionString" : "" + }, + "no-warning-comments" : { + "active" : 0, + "optionString" : "{'terms': ['todo', 'fixme', 'xxx'], 'location': 'start'}" + }, + "no-whitespace-before-property" : { + "active" : 0 + }, + "no-with" : { + "active" : 0 + }, + "nonblock-statement-body-position" : { + "active" : 0, + "optionString" : "'beside'" + }, + "object-curly-newline" : { + "active" : 0, + "optionString" : "{'ObjectExpression': {'multiline': true}, 'ObjectPattern': {'multiline': true}}" + }, + "object-curly-spacing" : { + "active" : 0, + "optionString" : "'never'" + }, + "object-property-newline" : { + "active" : 0, + "optionString" : "{'allowMultiplePropertiesPerLine': true}" + }, + "object-shorthand" : { + "active" : 0, + "optionString" : "'always', {'avoidQuotes': false, 'ignoreConstructors': false}" + }, + "one-var" : { + "active" : 0, + "optionString" : "'always'" + }, + "one-var-declaration-per-line" : { + "active" : 0, + "optionString" : "'always'" + }, + "operator-assignment" : { + "active" : 0, + "optionString" : "'always'" + }, + "operator-linebreak" : { + "active" : 0, + "optionString" : "'after', {'overrides': {'?': 'after', '+=': 'none'}}" + }, + "padded-blocks" : { + "active" : 0, + "optionString" : "{'blocks': 'always', 'switches': 'always', 'classes': 'always'}" + }, + "padding-line-between-statements" : { + "active" : 0, + "optionString" : "{blankLine: 'always', prev:'*', next:'return'}" + }, + "prefer-arrow-callback" : { + "active" : 0 + }, + "prefer-const" : { + "active" : 0, + "optionString" : "{'destructuring': 'any', 'ignoreReadBeforeAssign': false}" + }, + "prefer-destructuring" : { + "active" : 0, + "optionString" : "{'array': true, 'object': true}, {'enforceForRenamedProperties': false}" + }, + "prefer-exponentiation-operator" : { + "active" : 0 + }, + "prefer-named-capture-group" : { + "active" : 0 + }, + "prefer-numeric-literals" : { + "active" : 0 + }, + "prefer-object-has-own" : { + "active" : 0 + }, + "prefer-object-spread" : { + "active" : 0 + }, + "prefer-promise-reject-errors" : { + "active" : 0, + "optionString" : "{'allowEmptyReject': false}" + }, + "prefer-regex-literals" : { + "active" : 0 + }, + "prefer-rest-params" : { + "active" : 0 + }, + "prefer-spread" : { + "active" : 0 + }, + "prefer-template" : { + "active" : 0 + }, + "quote-props" : { + "active" : 0, + "optionString" : "'always'" + }, + "quotes" : { + "active" : 0, + "optionString" : "'double', {'avoidEscape': true, 'allowTemplateLiterals': true}" + }, + "radix" : { + "active" : 0, + "optionString" : "'always'" + }, + "require-atomic-updates" : { + "active" : 0, + "optionString" : "{'allowProperties': false}" + }, + "require-await" : { + "active" : 0 + }, + "require-unicode-regexp" : { + "active" : 0 + }, + "require-yield" : { + "active" : 0 + }, + "rest-spread-spacing" : { + "active" : 0, + "optionString" : "'never'" + }, + "semi" : { + "active" : 0, + "optionString" : "'always', {'omitLastInOneLineBlock': false}" + }, + "semi-spacing" : { + "active" : 0, + "optionString" : "{'before': false, 'after': true}" + }, + "semi-style" : { + "active" : 0, + "optionString" : "'last'" + }, + "sort-imports" : { + "active" : 0, + "optionString" : "{'ignoreCase': false, 'ignoreMemberSort': true, 'memberSyntaxSortOrder': ['none', 'all', 'multiple', 'single']}" + }, + "sort-keys" : { + "active" : 0, + "optionString" : "'asc', {'caseSensitive': true, 'natural': false}" + }, + "sort-vars" : { + "active" : 0, + "optionString" : "{'ignoreCase': false}" + }, + "space-before-blocks" : { + "active" : 0, + "optionString" : "{'functions': 'always', 'keywords': 'always', 'classes': 'always'}" + }, + "space-before-function-paren" : { + "active" : 0, + "optionString" : "{'anonymous': 'always', 'named': 'never'}" + }, + "space-in-parens" : { + "active" : 0, + "optionString" : "'never', {'exceptions': []}" + }, + "space-infix-ops" : { + "active" : 0, + "optionString" : "{'int32Hint': false}" + }, + "space-unary-ops" : { + "active" : 0, + "optionString" : "{'words': true, 'nonwords': false, 'overrides': {}}" + }, + "spaced-comment" : { + "active" : 0, + "optionString" : "'always', {'line': {'markers': ['\/'], 'exceptions': ['-', '+']}, 'block': {'markers': ['!'], 'exceptions': ['*'], 'balanced': false}}" + }, + "strict" : { + "active" : 0, + "optionString" : "'safe'" + }, + "switch-colon-spacing" : { + "active" : 0, + "optionString" : "{'after': true, 'before': false}" + }, + "symbol-description" : { + "active" : 0 + }, + "template-curly-spacing" : { + "active" : 0, + "optionString" : "'never'" + }, + "template-tag-spacing" : { + "active" : 0, + "optionString" : "'never'" + }, + "unicode-bom" : { + "active" : 0, + "optionString" : "'never'" + }, + "use-isnan" : { + "active" : 1, + "optionString" : "" + }, + "valid-typeof" : { + "active" : 1, + "optionString" : "{'requireStringLiterals': true}" + }, + "vars-on-top" : { + "active" : 0 + }, + "wrap-iife" : { + "active" : 0, + "optionString" : "'outside'" + }, + "wrap-regex" : { + "active" : 0 + }, + "yield-star-spacing" : { + "active" : 0, + "optionString" : "{'before': false, 'after': true}" + }, + "yoda" : { + "active" : 0, + "optionString" : "'never', {'exceptRange': false, 'onlyEquality': false}" + } + }, + "esLintSourceType" : 0, + "externalServerAddress" : "http:\/\/localhost:8888", + "gitIgnoreBuildFolder" : 1, + "hideConfigFile" : 0, + "jsCheckerReservedNamesString" : "", + "languageDefaultsCOFFEE" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.js", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "minifierStyle" : 1, + "outputStyle" : 0, + "sourceMapStyle" : 0, + "transpilerStyle" : 1 + }, + "languageDefaultsCSS" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*-min.css", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "combineImports" : 0, + "cssoStyle" : 0, + "purgeCSSStyle" : 0, + "shouldRunAutoprefixer" : 1, + "shouldRunBless" : 0, + "sourceMapStyle" : 0 + }, + "languageDefaultsGIF" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.gif", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "webpOptimizationPresetUUID" : "lpckwebp-none", + "webpRGBQuality" : 75 + }, + "languageDefaultsHAML" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.html", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "escapeHTMLCharacters" : 0, + "htmlMinifierStyle" : 0, + "noEscapeInAttributes" : 0, + "outputFormat" : 2, + "shouldRunCacheBuster" : 0, + "useCDATA" : 0, + "useDoubleQuotes" : 0, + "useUnixNewlines" : 0 + }, + "languageDefaultsJPG" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.jpg", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "outputFormat" : 0, + "quality" : 100, + "webpOptimizationPresetUUID" : "lpckwebp-none", + "webpRGBQuality" : 75 + }, + "languageDefaultsJS" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*-min.js", + "autoOutputPathRelativePath" : "\/min", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "bundleFormat" : 0, + "minifierStyle" : 1, + "sourceMapStyle" : 0, + "syntaxCheckerStyle" : 3, + "transpilerStyle" : 0 + }, + "languageDefaultsJSON" : { + "autoOutputAction" : 1, + "autoOutputPathFilenamePattern" : "*-min.json", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "orderOutput" : 0, + "outputStyle" : 1 + }, + "languageDefaultsKIT" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.html", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "kit", + "autoOutputPathReplace2" : "html", + "autoOutputPathStyle" : 0, + "htmlMinifierStyle" : 0, + "shouldRunCacheBuster" : 0 + }, + "languageDefaultsLESS" : { + "allowInsecureImports" : 0, + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.css", + "autoOutputPathRelativePath" : "..\/css", + "autoOutputPathReplace1" : "less", + "autoOutputPathReplace2" : "css", + "autoOutputPathStyle" : 0, + "cssoStyle" : 0, + "enableJavascript" : 0, + "mathStyle" : 0, + "outputStyle" : 0, + "purgeCSSStyle" : 0, + "rewriteURLStyle" : 0, + "shouldRunAutoprefixer" : 0, + "shouldRunBless" : 0, + "sourceMapStyle" : 1, + "strictImports" : 0, + "strictUnits" : 0 + }, + "languageDefaultsMARKDOWN" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.html", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "criticStyle" : 0, + "enableFootnotes" : 1, + "enableLabels" : 1, + "enableSmartQuotes" : 1, + "htmlMinifierStyle" : 0, + "maskEmailAddresses" : 1, + "outputFormat" : 0, + "outputStyle" : 0, + "parseMetadata" : 1, + "processHTML" : 0, + "randomFootnoteNumbers" : 0, + "shouldRunCacheBuster" : 0, + "useCompatibilityMode" : 0 + }, + "languageDefaultsOTHER" : { + "autoOutputAction" : 2, + "autoOutputPathFilenamePattern" : "*.*", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "htmlMinifierStyle" : 0, + "shouldRunCacheBuster" : 0 + }, + "languageDefaultsPNG" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.png", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "optimizerType" : 1, + "quality" : 100, + "webpOptimizationPresetUUID" : "lpckwebp-none", + "webpRGBQuality" : 75 + }, + "languageDefaultsPUG" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.html", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "compileDebug" : 1, + "htmlMinifierStyle" : 0, + "outputStyle" : 0, + "shouldRunCacheBuster" : 0 + }, + "languageDefaultsSASS" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.css", + "autoOutputPathRelativePath" : "..\/css", + "autoOutputPathReplace1" : "sass", + "autoOutputPathReplace2" : "css", + "autoOutputPathStyle" : 0, + "compilerType" : 1, + "cssoStyle" : 0, + "decimalPrecision" : 10, + "emitCharset" : 1, + "outputStyle" : 0, + "purgeCSSStyle" : 0, + "shouldRunAutoprefixer" : 0, + "shouldRunBless" : 0, + "sourceMapStyle" : 0 + }, + "languageDefaultsSLIM" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.html", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "compileOnly" : 0, + "htmlMinifierStyle" : 0, + "logicless" : 0, + "outputFormat" : 0, + "outputStyle" : 1, + "railsCompatible" : 0, + "shouldRunCacheBuster" : 0 + }, + "languageDefaultsSTYLUS" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.css", + "autoOutputPathRelativePath" : "..\/css", + "autoOutputPathReplace1" : "stylus", + "autoOutputPathReplace2" : "css", + "autoOutputPathStyle" : 0, + "cssoStyle" : 0, + "debugStyle" : 0, + "importCSS" : 0, + "outputStyle" : 0, + "purgeCSSStyle" : 0, + "resolveRelativeURLS" : 0, + "shouldRunAutoprefixer" : 0, + "shouldRunBless" : 0, + "sourceMapStyle" : 0 + }, + "languageDefaultsSVG" : { + "autoOutputAction" : 2, + "autoOutputPathFilenamePattern" : "*.svg", + "autoOutputPathRelativePath" : "", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "pluginMask" : 3758088159 + }, + "languageDefaultsTS" : { + "autoOutputAction" : 0, + "autoOutputPathFilenamePattern" : "*.js", + "autoOutputPathRelativePath" : "\/js", + "autoOutputPathReplace1" : "", + "autoOutputPathReplace2" : "", + "autoOutputPathStyle" : 0, + "createDeclarationFile" : 0, + "jsxMode" : 0, + "minifierStyle" : 0, + "moduleDetectionType" : 0, + "moduleResolutionType" : 0, + "moduleType" : 2, + "removeComments" : 0, + "sourceMapStyle" : 0, + "targetECMAVersion" : 2018 + }, + "languageDefaultsUserDefined" : [ + + ], + "npmAbbreviatedPath" : "", + "npmCreatePackageLock" : 1, + "npmInstallOptionalDependencies" : 0, + "npmSaveExactVersion" : 0, + "npmTargetDependencyListType" : 1, + "overrideExternalServerCSS" : 0, + "previewPathAddition" : "", + "purgeCSS" : { + "blocklistEntries" : [ + + ], + "contentEntries" : [ + "**\/*.html", + "**\/*.htm", + "**\/*.shtml", + "**\/*.xhtml", + "**\/*.php", + "**\/*.js", + "**\/*.ts", + "**\/*.coffee", + "**\/*.erb", + "**\/*.pug", + "**\/*.jade", + "**\/*.slim", + "**\/*.haml", + "**\/*.md", + "**\/*.kit" + ], + "removeFontFace" : 0, + "removeKeyframes" : 0, + "removeVariables" : 0, + "safelistEntries" : [ + + ], + "skippedEntries" : [ + "node_modules\/**" + ] + }, + "rollupContext" : "", + "rollupExternalEntries" : [ + + ], + "rollupReplacementEntries" : [ + "process.env.NODE_ENV:::$NODE_ENV", + "ENVIRONMENT:::$NODE_ENV" + ], + "rollupTreeshakingEnabled" : 1, + "rollupTreeshakingModuleSideEffects" : 1, + "skippedFoldersString" : "log, _logs, logs, _cache, cache, \/storage\/framework\/sessions, node_modules", + "sourceFolderName" : "source", + "susyVersion" : 3, + "tsAllowArbitraryExtensions" : 0, + "tsAllowImportingTSExtensions" : 0, + "tsAllowSyntheticDefaultImports" : 0, + "tsAllowUMDGlobalAccess" : 0, + "tsAllowUnreachableCode" : 0, + "tsAllowUnusedLabels" : 0, + "tsAlwaysStrict" : 0, + "tsDownlevelIteration" : 0, + "tsEmitBOM" : 0, + "tsEmitDecoratorMetadata" : 0, + "tsESModuleInterop" : 0, + "tsExactOptionalPropertyTypes" : 0, + "tsExperimentalDecorators" : 0, + "tsForceConsistentCasingInFileNames" : 0, + "tsImportHelpers" : 0, + "tsIsolatedModules" : 0, + "tsJSXFactory" : "React.createElement", + "tsNoEmitHelpers" : 0, + "tsNoFallthroughCasesInSwitch" : 0, + "tsNoImplicitAny" : 0, + "tsNoImplicitOverride" : 0, + "tsNoImplicitReturns" : 0, + "tsNoImplicitThis" : 0, + "tsNoLib" : 0, + "tsNoPropertyAccessFromIndexSignature" : 0, + "tsNoResolve" : 0, + "tsNoUncheckedIndexAccess" : 0, + "tsNoUnusedLocals" : 0, + "tsNoUnusedParameters" : 0, + "tsPreserveConstEnums" : 0, + "tsPreserveSymlinks" : 0, + "tsResolveJsonModule" : 0, + "tsSkipDefaultLibCheck" : 0, + "tsSkipLibCheck" : 0, + "tsStrictBindCallApply" : 0, + "tsStrictFunctionTypes" : 0, + "tsStrictNullChecks" : 0, + "tsStrictPropertyInitialization" : 0, + "tsStripInternal" : 0, + "tsUseDefineForClassFields" : 0, + "tsUseUnknownInCatchVariables" : 0, + "tsVerbatimModuleSyntax" : 0, + "uglifyDefinesString" : "", + "uglifyFlags2" : { + "arguments" : { + "active" : 1, + "flagValue" : -1 + }, + "arrows" : { + "active" : 1, + "flagValue" : -1 + }, + "ascii_only" : { + "active" : 0, + "flagValue" : -1 + }, + "booleans" : { + "active" : 1, + "flagValue" : -1 + }, + "booleans_as_integers" : { + "active" : 0, + "flagValue" : -1 + }, + "braces" : { + "active" : 0, + "flagValue" : -1 + }, + "collapse_vars" : { + "active" : 1, + "flagValue" : -1 + }, + "comments" : { + "active" : 0, + "flagValue" : 1 + }, + "comparisons" : { + "active" : 1, + "flagValue" : -1 + }, + "computed_props" : { + "active" : 1, + "flagValue" : -1 + }, + "conditionals" : { + "active" : 1, + "flagValue" : -1 + }, + "dead_code" : { + "active" : 0, + "flagValue" : -1 + }, + "directives" : { + "active" : 1, + "flagValue" : -1 + }, + "drop_console" : { + "active" : 0, + "flagValue" : -1 + }, + "drop_debugger" : { + "active" : 1, + "flagValue" : -1 + }, + "ecma" : { + "active" : 1, + "flagValue" : 5 + }, + "eval" : { + "active" : 0, + "flagValue" : -1 + }, + "evaluate" : { + "active" : 1, + "flagValue" : -1 + }, + "expression" : { + "active" : 0, + "flagValue" : -1 + }, + "hoist_funs" : { + "active" : 1, + "flagValue" : -1 + }, + "hoist_props" : { + "active" : 1, + "flagValue" : -1 + }, + "hoist_vars" : { + "active" : 0, + "flagValue" : -1 + }, + "ie8" : { + "active" : 0, + "flagValue" : -1 + }, + "if_return" : { + "active" : 1, + "flagValue" : -1 + }, + "indent_level" : { + "active" : 0, + "flagValue" : 4 + }, + "indent_start" : { + "active" : 0, + "flagValue" : 0 + }, + "inline" : { + "active" : 1, + "flagValue" : 3 + }, + "inline_script" : { + "active" : 1, + "flagValue" : -1 + }, + "join_vars" : { + "active" : 1, + "flagValue" : -1 + }, + "keep_classnames" : { + "active" : 0, + "flagValue" : -1 + }, + "keep_fargs" : { + "active" : 0, + "flagValue" : -1 + }, + "keep_fnames" : { + "active" : 0, + "flagValue" : -1 + }, + "keep_infinity" : { + "active" : 0, + "flagValue" : -1 + }, + "keep_numbers" : { + "active" : 0, + "flagValue" : -1 + }, + "keep_quoted_props" : { + "active" : 0, + "flagValue" : -1 + }, + "loops" : { + "active" : 1, + "flagValue" : -1 + }, + "max_line_len" : { + "active" : 1, + "flagValue" : 32000 + }, + "module" : { + "active" : 0, + "flagValue" : -1 + }, + "negate_iife" : { + "active" : 1, + "flagValue" : -1 + }, + "passes" : { + "active" : 1, + "flagValue" : 1 + }, + "preserve_annotations" : { + "active" : 0, + "flagValue" : -1 + }, + "properties" : { + "active" : 1, + "flagValue" : -1 + }, + "pure_getters" : { + "active" : 0, + "flagValue" : -1 + }, + "quote_keys" : { + "active" : 0, + "flagValue" : -1 + }, + "quote_style" : { + "active" : 1, + "flagValue" : 0 + }, + "reduce_funcs" : { + "active" : 1, + "flagValue" : -1 + }, + "reduce_vars" : { + "active" : 1, + "flagValue" : -1 + }, + "safari10" : { + "active" : 0, + "flagValue" : -1 + }, + "semicolons" : { + "active" : 1, + "flagValue" : -1 + }, + "sequences" : { + "active" : 1, + "flagValue" : -1 + }, + "shebang" : { + "active" : 1, + "flagValue" : -1 + }, + "side_effects" : { + "active" : 1, + "flagValue" : -1 + }, + "switches" : { + "active" : 1, + "flagValue" : -1 + }, + "toplevel" : { + "active" : 0, + "flagValue" : -1 + }, + "typeofs" : { + "active" : 1, + "flagValue" : -1 + }, + "unsafe" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_arrows" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_comps" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_Function" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_math" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_methods" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_proto" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_regexp" : { + "active" : 0, + "flagValue" : -1 + }, + "unsafe_undefined" : { + "active" : 0, + "flagValue" : -1 + }, + "unused" : { + "active" : 0, + "flagValue" : -1 + }, + "warnings" : { + "active" : 0, + "flagValue" : -1 + }, + "webkit" : { + "active" : 0, + "flagValue" : -1 + }, + "wrap_func_args" : { + "active" : 1, + "flagValue" : -1 + }, + "wrap_iife" : { + "active" : 0, + "flagValue" : -1 + } + }, + "uglifyMangleNames" : 1, + "uglifyReservedNamesString" : "$", + "webpPresets" : { + + }, + "websiteRelativeRoot" : "" + }, + "settingsFileVersion" : "3" +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/css/jquery.dropdown-min.css b/html/wp-content/plugins/svg-support/css/jquery.dropdown-min.css new file mode 100644 index 0000000..2a688d4 --- /dev/null +++ b/html/wp-content/plugins/svg-support/css/jquery.dropdown-min.css @@ -0,0 +1 @@ +@-webkit-keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@keyframes iui-fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}@keyframes iui-fadeOut{0%{opacity:1}100%{opacity:0}}.dropdown-multiple,.dropdown-multiple-label,.dropdown-single{position:relative}.dropdown-multiple-label.active .dropdown-main,.dropdown-multiple.active .dropdown-main,.dropdown-single.active .dropdown-main{display:block;-webkit-animation:iui-fadeIn .2s ease-in forwards;animation:iui-fadeIn .2s ease-in forwards}.dropdown-multiple-label.active .dropdown-display-label:after,.dropdown-multiple-label.active .dropdown-display:after,.dropdown-multiple.active .dropdown-display-label:after,.dropdown-multiple.active .dropdown-display:after,.dropdown-single.active .dropdown-display-label:after,.dropdown-single.active .dropdown-display:after{border-top:none;border-bottom:10px solid #999;border-left:5px solid transparent;border-right:5px solid transparent}.dropdown-multiple-label.active .dropdown-display,.dropdown-multiple-label.active .dropdown-display-label,.dropdown-multiple.active .dropdown-display,.dropdown-multiple.active .dropdown-display-label,.dropdown-single.active .dropdown-display,.dropdown-single.active .dropdown-display-label{border-bottom-left-radius:0;border-bottom-right-radius:0}.dropdown-display,.dropdown-display-label{position:relative;display:block;margin-bottom:0;font-size:14px;line-height:1.42857143;vertical-align:middle;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-image:none;border:1px solid #ccc;border-radius:4px;color:#333;background-color:#fff}.dropdown-display-label:after,.dropdown-display:after{content:'';position:absolute;border-top:10px solid #999;border-left:5px solid transparent;border-right:5px solid transparent;top:15px;right:8px}.dropdown-clear-all{background-color:#fff;border:none;font-size:22px;z-index:999;color:#999;position:absolute;right:2px;top:2px;display:none;width:25px;height:30px;text-align:center;line-height:30px}.dropdown-clear-all:focus{outline:0}.dropdown-clear-all:hover{color:#ccc;text-decoration:none}.dropdown-display{white-space:nowrap;padding:6px 20px 6px 12px}.dropdown-multiple:hover .dropdown-clear-all,.dropdown-single:hover .dropdown-clear-all{display:block}.dropdown-display .dropdown-chose-list{display:inline-block;vertical-align:middle;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dropdown-display .dropdown-chose-list span:before{content:','}.dropdown-display .dropdown-chose-list span:first-child:before{content:''}.dropdown-display .placeholder{display:none}.dropdown-display .placeholder:first-child{position:absolute;height:100%;width:100%;top:0;left:0;color:#999;display:block;text-indent:10px;font-size:13px;line-height:32px}.dropdown-display input{border:0;outline:0}.dropdown-display-label{cursor:text;padding:6px 25px 5px 0}.dropdown-display-label .dropdown-search{display:block;width:100%;border:1px solid #eee}.dropdown-display-label .dropdown-search input{width:100%}.dropdown-option.dropdown-chose{font-weight:bold}.dropdown-display-label input,.dropdown-display-label input:focus{border:none;outline:0}.dropdown-display-label .dropdown-chose-list{width:100%;display:inline-block;padding:0 5px}.dropdown-display-label .dropdown-chose-list .placeholder{display:none}.dropdown-display-label .dropdown-selected{position:relative;margin:0 5px 5px 0;padding:0 20px 0 5px;border:1px solid #aaa;max-width:100%;border-radius:3px;background-repeat:repeat-x;color:#333;cursor:default;display:inline-block}.dropdown-display-label .dropdown-selected .del{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0;float:right;line-height:1;color:#999;position:absolute;right:3px;top:0}.dropdown-display-label .dropdown-selected .del:after{content:'\D7';font-size:16px}.dropdown-main{position:absolute;top:100%;left:0;z-index:1010;width:100%;color:#444;box-sizing:border-box;background-color:#fff;border:1px solid #ccc;border-radius:0 0 4px 4px;box-shadow:0 6px 12px rgba(0,0,0,0.175);margin-top:-1px;border-top:0;padding:4px 7px;display:none}.dropdown-main ul{overflow-x:hidden;overflow-y:auto;max-height:240px;margin:0;padding:0}.dropdown-main input{margin-top:0;display:block;box-sizing:border-box;height:30px;border:1px solid #ccc;width:100%;text-indent:5px;border-radius:3px}.dropdown-main .dropdown-search{display:block;padding:5px 0}.dropdown-group{font-weight:700}.dropdown-group,.dropdown-option{margin:0;padding-left:12px;list-style:none;line-height:26px;word-wrap:break-word}.dropdown-option{cursor:pointer}.dropdown-option:focus,.dropdown-option:hover{background-color:#efefef;outline:0}.dropdown-option[disabled]{color:#ddd;background-color:#fff;cursor:not-allowed;text-decoration:line-through}.dropdown-option.dropdown-chose:after{content:'';float:right;width:10px;height:10px;background:#4AB1E9;border-radius:100%;margin:8px 5px 0 0}.dropdown-maxItem-alert,.dropdown-minItem-alert{position:absolute;top:0;left:0;background-color:#e4e3e2;width:100%;height:39px;line-height:39px;padding:0 5px;border-radius:5px;color:#999;-webkit-animation:iui-fadeIn .2s ease-in forwards;animation:iui-fadeIn .2s ease-in forwards} diff --git a/html/wp-content/plugins/svg-support/css/svgs-admin-edit-post.css b/html/wp-content/plugins/svg-support/css/svgs-admin-edit-post.css new file mode 100644 index 0000000..14cc2d7 --- /dev/null +++ b/html/wp-content/plugins/svg-support/css/svgs-admin-edit-post.css @@ -0,0 +1 @@ +body #set-post-thumbnail,body #postimagediv .inside img[src$=".svg"]{width:100%}body .block-editor__container .components-panel .editor-post-featured-image__container img[src$='.svg']{position:relative}body .block-editor__container .edit-post-sidebar .components-panel .components-checkbox-control{margin-top:10px} diff --git a/html/wp-content/plugins/svg-support/css/svgs-admin-simple-mode.css b/html/wp-content/plugins/svg-support/css/svgs-admin-simple-mode.css new file mode 100644 index 0000000..30d1b80 --- /dev/null +++ b/html/wp-content/plugins/svg-support/css/svgs-admin-simple-mode.css @@ -0,0 +1 @@ +.svgs-advanced{display:none} diff --git a/html/wp-content/plugins/svg-support/css/svgs-admin.css b/html/wp-content/plugins/svg-support/css/svgs-admin.css new file mode 100644 index 0000000..8e14357 --- /dev/null +++ b/html/wp-content/plugins/svg-support/css/svgs-admin.css @@ -0,0 +1 @@ +.svgs-version{font-size:10px;margin-left:7px}.postbox .inside a{text-decoration:none}h3{padding:0 12px}.help-tab-content h3{padding:0}h3.inner-title{padding:0;font-size:1.2em}.metabox-holder .postbox>h3,.metabox-holder .stuffbox>h3,.metabox-holder h2.hndle,.metabox-holder h3.hndle{font-size:1.3em;font-weight:600}.shortpixel-logo img{position:absolute;right:10px;bottom:0;width:140px}table.media .column-title .media-icon img{width:60px} diff --git a/html/wp-content/plugins/svg-support/css/svgs-attachment.css b/html/wp-content/plugins/svg-support/css/svgs-attachment.css new file mode 100644 index 0000000..844092b --- /dev/null +++ b/html/wp-content/plugins/svg-support/css/svgs-attachment.css @@ -0,0 +1 @@ +.attachment svg,.widget_media_image svg{max-width:100%;height:auto} diff --git a/html/wp-content/plugins/svg-support/functions/attachment.php b/html/wp-content/plugins/svg-support/functions/attachment.php new file mode 100644 index 0000000..5134193 --- /dev/null +++ b/html/wp-content/plugins/svg-support/functions/attachment.php @@ -0,0 +1,563 @@ +ID ); + + if ( ! file_exists( $svg_path ) ) { + // If SVG is external, use the URL instead of the path + $svg_path = $response['url']; + } + + $dimensions = bodhi_svgs_get_dimensions( $svg_path ); + + $response['sizes'] = array( + 'full' => array( + 'url' => $response['url'], + 'width' => $dimensions->width, + 'height' => $dimensions->height, + 'orientation' => $dimensions->width > $dimensions->height ? 'landscape' : 'portrait' + ) + ); + + } + + return $response; + +} +add_filter( 'wp_prepare_attachment_for_js', 'bodhi_svgs_response_for_svg', 10, 3 ); + +/** + * Get the dimensions of an SVG file. + * + * This function checks if the SVG is a local file or a remote URL, retrieves its content, and + * parses the width and height from the SVG attributes. + * + * @param string $svg The file path or URL of the SVG. + * + * @return object An object containing the width and height of the SVG. + */ +function bodhi_svgs_get_dimensions( $svg ) { + + $svg_content = ''; + + // Check if $svg is a URL or a local file path + if ( filter_var( $svg, FILTER_VALIDATE_URL ) ) { + // For remote SVGs, use wp_remote_get() + $response = wp_remote_get( $svg ); + if ( is_wp_error( $response ) ) { + return (object) array( 'width' => 0, 'height' => 0 ); + } + $svg_content = wp_remote_retrieve_body( $response ); + } else { + // For local files, use WP_Filesystem to read the file content + if ( ! function_exists( 'WP_Filesystem' ) ) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + } + global $wp_filesystem; + WP_Filesystem(); + $svg_content = $wp_filesystem->get_contents( $svg ); + } + + if ( empty( $svg_content ) ) { + return (object) array( 'width' => 0, 'height' => 0 ); + } + + $svg = simplexml_load_string( $svg_content ); + + if ( $svg === FALSE ) { + $width = '0'; + $height = '0'; + } else { + $attributes = $svg->attributes(); + $width = (string) $attributes->width; + $height = (string) $attributes->height; + } + + return (object) array( 'width' => $width, 'height' => $height ); + +} + +/** + * Generate attachment metadata for SVGs. (Thanks @surml) + * + * This function generates metadata for SVG attachments, including dimensions and file path. + * It is used to fix warnings related to missing width and height metadata for SVGs. + * + * @param array $metadata The attachment metadata. + * @param int $attachment_id The attachment ID. + * + * @return array Modified metadata including SVG dimensions. + */ +function bodhi_svgs_generate_svg_attachment_metadata( $metadata, $attachment_id ) { + + $mime = get_post_mime_type( $attachment_id ); + + if ( $mime == 'image/svg+xml' ) { + + $svg_path = get_attached_file( $attachment_id ); + $upload_dir = wp_upload_dir(); + // Get the path relative to /uploads/ + $relative_path = $svg_path ? str_replace($upload_dir['basedir'], '', $svg_path) : ''; + $filename = basename( $svg_path ); + + $dimensions = bodhi_svgs_get_dimensions( $svg_path ); + + $metadata = array( + 'width' => intval($dimensions->width), + 'height' => intval($dimensions->height), + 'file' => $relative_path + ); + + $height = intval($dimensions->height); + $width = intval($dimensions->width); + + // Generate sizes array for future implementations, if needed + $sizes = array(); + foreach ( get_intermediate_image_sizes() as $s ) { + + $sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false ); + + if ( $width !== 0 && $height !== 0 ) { + + if ( isset( $_wp_additional_image_sizes[$s]['width'] ) ) { + $width_current_size = intval( $_wp_additional_image_sizes[$s]['width'] ); + } else { + $width_current_size = get_option( "{$s}_size_w" ); + } + + if ( $width > $height ) { + $ratio = round($width / $height, 2); + $new_height = round($width_current_size / $ratio); + } else { + $ratio = round($height / $width, 2); + $new_height = round($width_current_size * $ratio); + } + + $sizes[$s]['width'] = $width_current_size; + $sizes[$s]['height'] = $new_height; + + $sizes[$s]['crop'] = false; + + } else { + + if ( isset( $_wp_additional_image_sizes[$s]['width'] ) ) { + $sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); + } else { + $sizes[$s]['width'] = get_option( "{$s}_size_w" ); + } + + if ( isset( $_wp_additional_image_sizes[$s]['height'] ) ) { + $sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); + } else { + $sizes[$s]['height'] = get_option( "{$s}_size_h" ); + } + + if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) ) { + $sizes[$s]['crop'] = intval( $_wp_additional_image_sizes[$s]['crop'] ); + } else { + $sizes[$s]['crop'] = get_option( "{$s}_crop" ); + } + + } + + $sizes[$s]['file'] = $filename; + $sizes[$s]['mime-type'] = 'image/svg+xml'; + + } + + $metadata['sizes'] = $sizes; + + } + + return $metadata; + +} +add_filter( 'wp_generate_attachment_metadata', 'bodhi_svgs_generate_svg_attachment_metadata', 10, 3 ); + +/** + * Sanitize SVG files. + * + * This function sanitizes SVG files by removing potentially harmful elements and attributes. + * It also optionally minifies the SVG content and re-encodes it if it was originally gzipped. + * + * @param string $file The file path of the SVG to sanitize. + * + * @return bool True if the file was successfully sanitized, false otherwise. + */ +function bodhi_svgs_sanitize( $file ){ + + global $sanitizer; + + $sanitizer->setAllowedTags( new bodhi_svg_tags() ); + $sanitizer->setAllowedAttrs( new bodhi_svg_attributes() ); + + $dirty = ''; + + // Using WP_Filesystem to read the SVG file content + if ( ! function_exists( 'WP_Filesystem' ) ) { + require_once ABSPATH . 'wp-admin/includes/file.php'; + } + global $wp_filesystem; + WP_Filesystem(); + $dirty = $wp_filesystem->get_contents( $file ); + + // Try to decode if gzipped is enabled + if ( $is_zipped = bodhi_svgs_is_gzipped( $dirty ) ) { + + $dirty = gzdecode( $dirty ); + + // Return on failure, since we can't read file + if ( $dirty === false ) { + return false; + } + + } + + // Remove remote references since they are dangerous and lead to injection + $sanitizer->removeRemoteReferences(true); + + // Enable minify in library if its enabled in admin panel + bodhi_svgs_minify(); + + $clean = $sanitizer->sanitize( $dirty ); + + if ( $clean === false ) { + return false; + } + + // If the file was gzipped, we need to re-zip it + if ( $is_zipped ) { + $clean = gzencode( $clean ); + } + + // Use WP_Filesystem to write the sanitized content back + if ( ! $wp_filesystem->put_contents( $file, $clean, FS_CHMOD_FILE ) ) { + return false; + } + + return true; + +} + +/** + * Enable minification for SVG files. + * + * This function enables minification for SVG files if the option is set in the plugin settings. + */ +function bodhi_svgs_minify() { + + global $bodhi_svgs_options; + global $sanitizer; + + if ( !empty($bodhi_svgs_options['minify_svg']) && $bodhi_svgs_options['minify_svg'] === 'on' ) { + $sanitizer->minify(true); + } + +} + +/** + * Check if a string is gzipped. + * + * @param string $contents The contents to check. + * + * @return bool True if the contents are gzipped, false otherwise. + */ +function bodhi_svgs_is_gzipped( $contents ) { + if ($contents === null) { + return false; + } + + if ( function_exists( 'mb_strpos' ) ) { + return 0 === mb_strpos( $contents, "\x1f" . "\x8b" . "\x08" ); + } else { + return 0 === strpos( $contents, "\x1f" . "\x8b" . "\x08" ); + } +} + +/** + * Pre-filter for handling SVG uploads. + * + * This function checks if the uploaded file is an SVG and applies sanitization if required. + * + * @param array $file The uploaded file data. + * + * @return array The modified file data. + */ +function bodhi_svgs_sanitize_svg($file) { + global $bodhi_svgs_options; + + $file_path = $file['tmp_name']; + $file_name = $file['name']; + + // First quick check - if it's clearly not an SVG, return early + if (!empty($file_name) && strtolower(pathinfo($file_name, PATHINFO_EXTENSION)) !== 'svg') { + return $file; + } + + // Multiple validation checks for SVG + if ( $file_path && file_exists( $file_path ) ) { + // 1. Check MIME type using fileinfo + $finfo = finfo_open( FILEINFO_MIME_TYPE ); + $real_mime = finfo_file( $finfo, $file_path ); + finfo_close( $finfo ); + + // 2. Read first bytes of the file to check for SVG header + $file_content = file_get_contents( $file_path ); + + // Check for XML declaration and SVG tag + $pattern1 = '/^[\s\n]*(?:<\?xml[^>]*>[\s\n]*)?(?:[\s\n]*)*(?:]*>[\s\n]*)?(?:[\s\n]*)*]*>/is'; + $pattern2 = '/^[\s\n]*(?:[\s\n]*)*]*>/is'; + + $match1 = preg_match( $pattern1, $file_content ); + $match2 = preg_match( $pattern2, $file_content ); + $has_closing = strpos( $file_content, '' ) !== false; + + $is_svg_content = ( $match1 || $match2 ) && $has_closing; + + // If content validation fails OR (mime type isn't SVG AND isn't a plain text file containing SVG) + if ( !$is_svg_content || + ( $real_mime !== 'image/svg+xml' && + $real_mime !== 'image/svg' && + !( $real_mime === 'text/plain' && $is_svg_content ) ) ) { + $file['error'] = __( 'File is not a valid SVG.', 'svg-support' ); + return $file; + } + } + + // Now we know it's an SVG, continue with security checks + if (!defined('REST_REQUEST') && !wp_verify_nonce( + sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'] ?? '')), + 'media-form' + )) { + $file['error'] = __('Security check failed.', 'svg-support'); + return $file; + } + + // Get the roles that do not require SVG sanitization + $sanitize_on_upload_roles_array = (array) $bodhi_svgs_options['sanitize_on_upload_roles']; + $user = wp_get_current_user(); + $current_user_roles = (array) $user->roles; + + // Check if the current user's roles intersect with the roles that do not need sanitization + $no_sanitize_needed = array_intersect($sanitize_on_upload_roles_array, $current_user_roles); + + // Check if the user has the capability to upload SVGs + $can_upload_files = current_user_can('upload_files'); + + // Force sanitize unless user is in roles that bypass sanitization + if ($can_upload_files && empty($no_sanitize_needed)) { + global $sanitizer; + + // Read file contents + $file_content = file_get_contents($file_path); + if ($file_content === false) { + $file['error'] = __("Unable to read SVG file for sanitization.", 'svg-support'); + return $file; + } + + // Sanitize the content + $clean_svg = $sanitizer->sanitize($file_content); + + if ($clean_svg === false) { + $file['error'] = __("Sorry, this file couldn't be sanitized for security reasons and wasn't uploaded.", 'svg-support'); + return $file; + } + + // Write sanitized content back + $write_result = file_put_contents($file_path, $clean_svg); + if ($write_result === false) { + $file['error'] = __("Unable to save sanitized SVG file.", 'svg-support'); + return $file; + } + } + + return $file; +} +// Add filter to handle upload pre-filtering for sanitization +add_filter('wp_handle_upload_prefilter', 'bodhi_svgs_sanitize_svg'); + +/** + * Fix for image widget PHP warnings related to metadata. + * + * @param array $data The attachment metadata. + * + * @return array|false The modified metadata or false if invalid. + */ +function bodhi_svgs_get_attachment_metadata( $data ) { + + $res = $data; + + if ( !isset( $data['width'] ) || !isset( $data['height'] ) ) { + $res = false; + } + + return $res; + +} +// add_filter( 'wp_get_attachment_metadata' , 'bodhi_svgs_get_attachment_metadata' ); +// Commented this out 20200307 because it was stripping metadata from other attachments as well. Need to make this target only SVG attachments. + +/** + * Remove srcset attribute for SVG images. + * + * @param array $sources The sources array for the image. + * + * @return array The modified sources array. + */ +function bodhi_svgs_disable_srcset( $sources ) { + + $first_element = reset($sources); + if ( isset($first_element) && !empty($first_element['url']) ) { + + $ext = pathinfo(reset($sources)['url'], PATHINFO_EXTENSION); + + if ( $ext == 'svg' ) { + + // return empty array + $sources = array(); + + return $sources; + + } else { + + return $sources; + + } + + } else { + + return $sources; + + } + +} +add_filter( 'wp_calculate_image_srcset', 'bodhi_svgs_disable_srcset' ); + +/** + * Fix for division by zero error for SVGs. (Proposed by @starsis) + * + * This function ensures that SVGs do not cause division by zero errors by providing default + * dimensions if they are missing. + * + * @param array $image The image data. + * @param int $attachment_id The attachment ID. + * @param string $size The requested image size. + * @param bool $icon Whether the image is an icon. + * + * @return array The modified image data. + */ +function bodhi_svgs_dimension_fallback( $image, $attachment_id, $size, $icon ) { + + // only manipulate for svgs + if ( get_post_mime_type($attachment_id) == 'image/svg+xml' ) { + + if ( isset($image[1]) && $image[1] === 0 ) { + $image[1] = 1; + } + if ( isset($image[2]) && $image[2] === 0 ) { + $image[2] = 1; + } + + } + + return $image; + +} +add_filter( 'wp_get_attachment_image_src', 'bodhi_svgs_dimension_fallback', 10, 4 ); + +/** + * Pre-process SVG files uploaded via REST API + * + * @param array $file File data before processing + * @param array $request The full request payload + * @return array|WP_Error Modified file data or error + */ +function bodhi_svgs_rest_pre_upload($file, $request) { + if ($file['type'] === 'image/svg+xml') { + // Randomize filename for REST API uploads + $ext = pathinfo($file['name'], PATHINFO_EXTENSION); + $random_name = wp_generate_password(12, false) . '.' . $ext; + $file['name'] = sanitize_file_name($random_name); + + // Force sanitization + if (!bodhi_svgs_sanitize($file['tmp_name'])) { + return new WP_Error( + 'svg_sanitization_failed', + __('SVG sanitization failed for security reasons.', 'svg-support'), + array('status' => 400) + ); + } + } + return $file; +} +add_filter('rest_pre_upload_file', 'bodhi_svgs_rest_pre_upload', 10, 2); + +function bodhi_svgs_handle_upload_check($fileinfo) { + if ($fileinfo['type'] === 'image/svg+xml') { + global $bodhi_last_upload_info; + $bodhi_last_upload_info = $fileinfo; + } + return $fileinfo; +} +add_filter('wp_handle_upload', 'bodhi_svgs_handle_upload_check'); + +function bodhi_svgs_rest_insert_attachment($prepared_attachment, $request) { + if ($request->get_header('content-type') !== 'image/svg+xml') { + return $prepared_attachment; + } + + global $bodhi_svgs_options; + $user = wp_get_current_user(); + $current_user_roles = (array) $user->roles; + $sanitize_on_upload_roles_array = (array) $bodhi_svgs_options['sanitize_on_upload_roles']; + + $should_sanitize = empty(array_intersect($sanitize_on_upload_roles_array, $current_user_roles)); + + if ($should_sanitize) { + $file_path = get_attached_file($prepared_attachment->ID); + if (!$file_path) { + global $bodhi_last_upload_info; + if (isset($bodhi_last_upload_info['file'])) { + $file_path = $bodhi_last_upload_info['file']; + } + } + + if ($file_path && file_exists($file_path)) { + global $sanitizer; + $file_content = file_get_contents($file_path); + + if ($file_content !== false) { + $clean_svg = $sanitizer->sanitize($file_content); + if ($clean_svg !== false) { + file_put_contents($file_path, $clean_svg); + } + } + } + } + + return $prepared_attachment; +} +add_filter('rest_insert_attachment', 'bodhi_svgs_rest_insert_attachment', 10, 2); diff --git a/html/wp-content/plugins/svg-support/functions/attribute-control.php b/html/wp-content/plugins/svg-support/functions/attribute-control.php new file mode 100644 index 0000000..813a8d8 --- /dev/null +++ b/html/wp-content/plugins/svg-support/functions/attribute-control.php @@ -0,0 +1,58 @@ +\',searchNoData: \'
          • No Results
          • \'});});', 'after' ); + wp_add_inline_script( 'js-for-multiselect', 'jQuery(document).ready(function(){jQuery(".sanitize_on_upload_roles").dropdown({multipleMode: "label",input: \'\',searchNoData: \'
          • No Results
          • \'});});', 'after' ); + } +} +add_action( 'admin_enqueue_scripts', 'bodhi_svgs_admin_multiselect' ); + +/** + * Enqueue Block editor JS + */ +function bodhi_svgs_block_editor() { + global $svgs_plugin_version; + + if ( bodhi_svgs_advanced_mode() ) { + wp_enqueue_script( 'bodhi-svgs-gutenberg-filters', BODHI_SVGS_PLUGIN_URL . '/js/min/gutenberg-filters-min.js', ['wp-edit-post'], $svgs_plugin_version, true ); + } +} +add_action( 'enqueue_block_editor_assets', 'bodhi_svgs_block_editor' ); + +/** + * Enqueue frontend CSS + */ +function bodhi_svgs_frontend_css() { + global $bodhi_svgs_options; + global $svgs_plugin_version; + + if ( ! empty( $bodhi_svgs_options['frontend_css'] ) ) { + wp_enqueue_style( 'bodhi-svgs-attachment', BODHI_SVGS_PLUGIN_URL . 'css/svgs-attachment.css', array(), $svgs_plugin_version ); + } +} +add_action( 'wp_enqueue_scripts', 'bodhi_svgs_frontend_css' ); + +/** + * Enqueue frontend JS + */ +function bodhi_svgs_frontend_js() { + global $bodhi_svgs_options; + global $svgs_plugin_version; + + if ( ! empty( $bodhi_svgs_options['sanitize_svg_front_end'] ) && $bodhi_svgs_options['sanitize_svg_front_end'] === 'on' && bodhi_svgs_advanced_mode() === true ) { + $bodhi_svgs_js_footer = ! empty( $bodhi_svgs_options['js_foot_choice'] ); + wp_enqueue_script( 'bodhi-dompurify-library', BODHI_SVGS_PLUGIN_URL . 'vendor/DOMPurify/DOMPurify.min.js', array(), '2.5.8', $bodhi_svgs_js_footer ); + } +} +add_action( 'wp_enqueue_scripts', 'bodhi_svgs_frontend_js', 9 ); + +/** + * Enqueue and localize JS for IMG tag replacement + */ +function bodhi_svgs_inline() { + global $bodhi_svgs_options; + global $svgs_plugin_version; + + if ( bodhi_svgs_advanced_mode() ) { + $force_inline_svg_active = ! empty( $bodhi_svgs_options['force_inline_svg'] ) ? 'true' : 'false'; + + if ( ! empty( $bodhi_svgs_options['css_target'] ) ) { + $css_target_array = array( + 'Bodhi' => 'img.' . esc_attr( $bodhi_svgs_options['css_target'] ), + 'ForceInlineSVG' => esc_attr( $bodhi_svgs_options['css_target'] ) + ); + } else { + $css_target_array = array( + 'Bodhi' => 'img.style-svg', + 'ForceInlineSVG' => 'style-svg' + ); + } + + if ( ! empty( $bodhi_svgs_options['use_expanded_js'] ) ) { + $bodhi_svgs_js_folder = ''; + $bodhi_svgs_js_file = ''; + } else { + $bodhi_svgs_js_folder = 'min/'; + $bodhi_svgs_js_file = '-min'; + } + + $bodhi_svgs_js_footer = ! empty( $bodhi_svgs_options['js_foot_choice'] ); + $bodhi_svgs_js_vanilla = ! empty( $bodhi_svgs_options['use_vanilla_js'] ) ? '-vanilla' : ''; + + $bodhi_svgs_js_path = 'js/' . $bodhi_svgs_js_folder . 'svgs-inline' . $bodhi_svgs_js_vanilla . $bodhi_svgs_js_file . '.js'; + + // Only change: Make jQuery dependency conditional on vanilla JS setting + $bodhi_svgs_dependencies = ! empty( $bodhi_svgs_options['use_vanilla_js'] ) ? array() : array( 'jquery' ); + + wp_register_script( 'bodhi_svg_inline', BODHI_SVGS_PLUGIN_URL . $bodhi_svgs_js_path, $bodhi_svgs_dependencies, $svgs_plugin_version, $bodhi_svgs_js_footer ); + wp_enqueue_script( 'bodhi_svg_inline' ); + + wp_localize_script('bodhi_svg_inline', 'svgSettings', array( + 'skipNested' => !empty($bodhi_svgs_options['skip_nested_svg']) + )); + + wp_add_inline_script( + 'bodhi_svg_inline', + sprintf( + 'cssTarget=%s;ForceInlineSVGActive=%s;frontSanitizationEnabled=%s;', + wp_json_encode( $css_target_array ), + wp_json_encode( $force_inline_svg_active ), + wp_json_encode( $bodhi_svgs_options['sanitize_svg_front_end'] ) + ) + ); + } +} +add_action( 'wp_enqueue_scripts', 'bodhi_svgs_inline' ); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/functions/featured-image.php b/html/wp-content/plugins/svg-support/functions/featured-image.php new file mode 100644 index 0000000..e8e3832 --- /dev/null +++ b/html/wp-content/plugins/svg-support/functions/featured-image.php @@ -0,0 +1,160 @@ +ID, $id, true ) ); + $label = ''; + $nonce = wp_nonce_field( 'bodhi_svgs_save_featured_image_meta', 'bodhi_svgs_featured_image_nonce', true, false ); + + return $content .= $label . $nonce; + + } else { + + return $content; + + } + +} +if ( bodhi_svgs_advanced_mode() ) { + add_filter( 'admin_post_thumbnail_html', 'bodhi_svgs_featured_image_meta' ); +} + +/** + * Save featured image meta data when saved. + */ +function bodhi_svgs_save_featured_image_meta( $post_id, $post, $update ) { + + // Verify nonce + if ( ! isset( $_POST['bodhi_svgs_featured_image_nonce'] ) || + ! wp_verify_nonce( + sanitize_text_field( wp_unslash( $_POST['bodhi_svgs_featured_image_nonce'] ) ), + 'bodhi_svgs_save_featured_image_meta' + ) + ) { + return $post_id; + } + + // If this is an autosave, our form has not been submitted, so we don't want to do anything. + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { + return $post_id; + } + + // If the user does not have permission to edit posts, do nothing. + if ( ! current_user_can( 'edit_post', $post_id ) ) { + return $post_id; + } + + // If checkbox is checked, add/update meta + if ( isset( $_POST['inline_featured_image'] ) ) { + update_post_meta( $post_id, 'inline_featured_image', 1 ); + } else { + // If unchecked, delete the meta entirely + delete_post_meta( $post_id, 'inline_featured_image' ); + } +} +add_action( 'save_post', 'bodhi_svgs_save_featured_image_meta', 10, 3 ); + +/* + * Save featured image meta for Gutenberg Editor + */ +function bodhi_svgs_register_meta() { + + register_meta( 'post', 'inline_featured_image', array( + 'show_in_rest' => true, + 'single' => true, + 'type' => 'boolean', + 'auth_callback' => '__return_true' + ) ); + +} +add_action( 'init', 'bodhi_svgs_register_meta' ); + +/** + * Add class to the featured image output on front end. + */ +function bodhi_svgs_add_class_to_thumbnail( $thumb ) { + + $inline_featured_image = get_post_meta( get_the_ID(), 'inline_featured_image' ); + + if ( is_array( $inline_featured_image ) && in_array( 1, $inline_featured_image ) ) { + + global $bodhi_svgs_options; + + $target_class = ! empty( $bodhi_svgs_options['css_target'] ) ? $bodhi_svgs_options['css_target'] : 'style-svg'; + + if ( is_singular() ) { + + $thumb = str_replace( 'attachment-', $target_class . ' attachment-', $thumb ); + + } + + } + + return $thumb; + +} +if ( bodhi_svgs_advanced_mode() ) { + add_filter( 'post_thumbnail_html', 'bodhi_svgs_add_class_to_thumbnail' ); +} + +/** + * Safe update of inline featured image meta + */ +function bodhi_svgs_update_featured_image_meta($post_id, $value) { + // Delete any existing meta first + delete_post_meta($post_id, 'inline_featured_image'); + + // Add the new value + add_post_meta($post_id, 'inline_featured_image', $value, true); +} + +/** + * Handle the AJAX request for updating featured image inline status + */ +function bodhi_svgs_featured_image_inline_toggle() { + // Verify nonce and permissions + if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'svg-support-featured')) { + wp_send_json_error('Invalid nonce'); + } + + if (!current_user_can('edit_posts')) { + wp_send_json_error('Insufficient permissions'); + } + + // Validate and sanitize input + if (!isset($_POST['post_id']) || !isset($_POST['checked'])) { + wp_send_json_error('Missing parameters'); + } + + $post_id = intval($_POST['post_id']); + $checked = ($_POST['checked'] === 'true'); + + // Update the meta safely + bodhi_svgs_update_featured_image_meta($post_id, $checked); + + wp_send_json_success(); +} + +// Hook the AJAX actions for both logged-in and non-logged-in users +add_action('wp_ajax_bodhi_svgs_featured_image_inline_toggle', 'bodhi_svgs_featured_image_inline_toggle'); +add_action('wp_ajax_nopriv_bodhi_svgs_featured_image_inline_toggle', 'bodhi_svgs_featured_image_inline_toggle'); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/functions/localization.php b/html/wp-content/plugins/svg-support/functions/localization.php new file mode 100644 index 0000000..452a807 --- /dev/null +++ b/html/wp-content/plugins/svg-support/functions/localization.php @@ -0,0 +1,14 @@ +query(" + DELETE pm FROM {$wpdb->postmeta} pm + JOIN ( + SELECT post_id, meta_id FROM ( + SELECT post_id, meta_id, + ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY meta_id DESC) AS row_num + FROM {$wpdb->postmeta} + WHERE meta_key = 'inline_featured_image' + ) as duplicates + WHERE row_num > 1 + ) to_delete ON pm.meta_id = to_delete.meta_id + "); + + // Delete all inline_featured_image meta entries that aren't explicitly set to 1 + $wpdb->query(" + DELETE FROM {$wpdb->postmeta} + WHERE meta_key = 'inline_featured_image' + AND (meta_value = '' OR meta_value = '0' OR meta_value IS NULL) + "); +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/functions/mime-types.php b/html/wp-content/plugins/svg-support/functions/mime-types.php new file mode 100644 index 0000000..148f693 --- /dev/null +++ b/html/wp-content/plugins/svg-support/functions/mime-types.php @@ -0,0 +1,117 @@ +roles; + + // For multisite, add network admin to allowed roles + if (is_multisite() && is_super_admin()) { + $current_user_roles[] = 'administrator'; + } + + // Check if the user has the capability or the role + $is_role_allowed = array_intersect($allowed_roles_array, $current_user_roles); + if ( empty($is_role_allowed) || !current_user_can('upload_files') ) { + return $mimes; + } + + // Allow SVG file upload + $mimes['svg'] = 'image/svg+xml'; + $mimes['svgz'] = 'image/svg+xml'; + + return $mimes; +} +add_filter( 'upload_mimes', 'bodhi_svgs_upload_mimes', 99 ); + +/** + * Check Mime Types + */ +function bodhi_svgs_upload_check( $checked, $file, $filename, $mimes ) { + + if ( ! $checked['type'] ) { + + $check_filetype = wp_check_filetype( $filename, $mimes ); + $ext = $check_filetype['ext']; + $type = $check_filetype['type']; + $proper_filename = $filename; + + // Check if the file is an SVG or SVGZ + if ( ( $ext === 'svg' || $ext === 'svgz' ) && $type === 'image/svg+xml' ) { + $checked = compact( 'ext', 'type', 'proper_filename' ); + } + } + + return $checked; +} +add_filter( 'wp_check_filetype_and_ext', 'bodhi_svgs_upload_check', 10, 4 ); + + +/** + * Mime Check fix for WP 4.7.1 / 4.7.2 + * + * Fixes uploads for these 2 versions of WordPress. + * Issue was fixed in 4.7.3 core. + */ +function bodhi_svgs_allow_svg_upload( $data, $file, $filename, $mimes ) { + + global $wp_version; + // Corrected the version check condition + if ( version_compare($wp_version, '4.7.1', '>=') && version_compare($wp_version, '4.7.3', '<') ) { + $filetype = wp_check_filetype( $filename, $mimes ); + + // Check if the file is an SVG or SVGZ + if ( ( $filetype['ext'] === 'svg' || $filetype['ext'] === 'svgz' ) && $filetype['type'] === 'image/svg+xml' ) { + return [ + 'ext' => $filetype['ext'], + 'type' => $filetype['type'], + 'proper_filename' => $data['proper_filename'] + ]; + } + } + + return $data; +} +add_filter( 'wp_check_filetype_and_ext', 'bodhi_svgs_allow_svg_upload', 10, 4 ); + +function bodhi_svgs_multisite_settings($mimes) { + // Check if this is a multisite installation + if (is_multisite()) { + // Get the site ID + $blog_id = get_current_blog_id(); + + // Allow SVG on main site + if (is_main_site()) { + return $mimes; + } + + // For subsites, check if upload_files capability is allowed + if (get_site_option('upload_space_check_disabled')) { + return $mimes; + } + } + return $mimes; +} +add_filter('upload_mimes', 'bodhi_svgs_multisite_settings', 98); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/functions/thumbnail-display.php b/html/wp-content/plugins/svg-support/functions/thumbnail-display.php new file mode 100644 index 0000000..f9c6daa --- /dev/null +++ b/html/wp-content/plugins/svg-support/functions/thumbnail-display.php @@ -0,0 +1,51 @@ +', + '<# } else if ( \'svg+xml\' === data.subtype ) { #> + + <# } else if ( \'image\' === data.type && data.sizes && data.sizes.full ) { #>', + $content + ); + + $content = str_replace( + '<# } else if ( \'image\' === data.type && data.sizes ) { #>', + '<# } else if ( \'svg+xml\' === data.subtype ) { #> +
            + +
            + <# } else if ( \'image\' === data.type && data.sizes ) { #>', + $content + ); + + return $content; + } + + } + +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/includes/svg-attributes.php b/html/wp-content/plugins/svg-support/includes/svg-attributes.php new file mode 100644 index 0000000..99d312d --- /dev/null +++ b/html/wp-content/plugins/svg-support/includes/svg-attributes.php @@ -0,0 +1,20 @@ +

            ' . + esc_html__('SVG Support: SVG Sanitizer library not found. Some features may be limited.', 'svg-support') . + '

            '; + } + }); + + // Fallback class if the sanitizer isn't available + class bodhi_svg_tags { + /** + * Returns an array of tags + * + * @return array + */ + public static function getTags() { + $tags = array( + 'svg', + 'g', + 'path', + 'circle', + 'rect', + 'line', + 'polyline', + 'polygon', + ); + return apply_filters( 'svg_allowed_tags', $tags ); + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/integrations/wp-all-import.php b/html/wp-content/plugins/svg-support/integrations/wp-all-import.php new file mode 100644 index 0000000..f745b34 --- /dev/null +++ b/html/wp-content/plugins/svg-support/integrations/wp-all-import.php @@ -0,0 +1,69 @@ + intval( $dimensions->width ), + 'height' => intval( $dimensions->height ), + 'file' => basename( $file_path ), + ); + return true; + } else { + // error_log( sprintf( 'Sanitization failed for SVG file at path %s.', $file_path ) ); + return false; + } + } + + // error_log( sprintf( 'SVG file at path %s is either missing or not readable.', $file_path ) ); + return false; +} + +// Hook the function into WP All Import's `pmxi_attachment_uploaded`. +add_action( 'pmxi_attachment_uploaded', 'bodhi_svgs_wpallimport_handle_svg' ); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/js/gutenberg-filters.js b/html/wp-content/plugins/svg-support/js/gutenberg-filters.js new file mode 100644 index 0000000..f0c893c --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/gutenberg-filters.js @@ -0,0 +1,68 @@ +"use strict" + +const { createElement, Fragment, useState } = wp.element; +const { withSelect, withDispatch } = wp.data; +const { compose } = wp.compose; + +function CheckBoxCustom(props) { + const [isChecked, setIsChecked] = useState(props.meta.inline_featured_image); + const { + meta, + updateInlineFeaturedSvg, + } = props; + + return createElement( + wp.components.CheckboxControl, + { + label: "Render this SVG inline (Advanced)", + checked: isChecked, + onChange: (value) => { + setIsChecked(value); + updateInlineFeaturedSvg(value, meta); + }, + __nextHasNoMarginBottom: true + } + ); +} + +const composedCheckBox = compose([ + withSelect((select) => { + const currentMeta = select('core/editor').getCurrentPostAttribute('meta'); + const editedMeta = select('core/editor').getEditedPostAttribute('meta'); + return { + meta: { ...currentMeta, ...editedMeta }, + }; + }), + withDispatch((dispatch) => ({ + updateInlineFeaturedSvg(value, meta) { + meta = { + ...meta, + inline_featured_image: value, + }; + dispatch('core/editor').editPost({ meta }); + }, + })), +])(CheckBoxCustom); + +function wrapPostFeaturedImage(OriginalComponent) { + return function(props) { + return createElement( + Fragment, + {}, + '', + createElement( + OriginalComponent, + props + ), + createElement( + composedCheckBox + ) + ); + } +} + +wp.hooks.addFilter( + 'editor.PostFeaturedImage', + 'bodhi-svgs-featured-image/render-inline-image-checkbox', + wrapPostFeaturedImage +); diff --git a/html/wp-content/plugins/svg-support/js/jquery.dropdown.js b/html/wp-content/plugins/svg-support/js/jquery.dropdown.js new file mode 100644 index 0000000..a3bcc29 --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/jquery.dropdown.js @@ -0,0 +1,643 @@ +; +(function ($) { + 'use strict'; + + function noop() { } + + function throttle(func, wait, options) { + var context, args, result; + var timeout = null; + // 上次执行时间点 + var previous = 0; + if (!options) options = {}; + // 延迟执行函数 + var later = function () { + // è‹¥è®¾å®šäº†å¼€å§‹è¾¹ç•Œä¸æ‰§è¡Œé€‰é¡¹ï¼Œä¸Šæ¬¡æ‰§è¡Œæ—¶é—´å§‹ç»ˆä¸º0 + previous = options.leading === false ? 0 : new Date().getTime(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + return function () { + var now = new Date().getTime(); + // é¦–æ¬¡æ‰§è¡Œæ—¶ï¼Œå¦‚æžœè®¾å®šäº†å¼€å§‹è¾¹ç•Œä¸æ‰§è¡Œé€‰é¡¹ï¼Œå°†ä¸Šæ¬¡æ‰§è¡Œæ—¶é—´è®¾å®šä¸ºå½“剿—¶é—´ã€‚ + if (!previous && options.leading === false) previous = now; + // 延迟执行时间间隔 + var remaining = wait - (now - previous); + context = this; + args = arguments; + // 延迟时间间隔remainingå°äºŽç­‰äºŽ0,表示上次执行至此所间隔时间已ç»è¶…è¿‡ä¸€ä¸ªæ—¶é—´çª—å£ + // remaining大于时间窗å£wait,表示客户端系统时间被调整过 + if (remaining <= 0 || remaining > wait) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + if (!timeout) context = args = null; + //如果延迟执行ä¸å­˜åœ¨ï¼Œä¸”æ²¡æœ‰è®¾å®šç»“å°¾è¾¹ç•Œä¸æ‰§è¡Œé€‰é¡¹ + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + } + + var isSafari = function () { + var ua = navigator.userAgent.toLowerCase(); + if (ua.indexOf('safari') !== -1) { + return ua.indexOf('chrome') > -1 ? false : true; + } + }(); + + var settings = { + readonly: false, + minCount: 0, + minCountErrorMessage: '', + limitCount: Infinity, + limitCountErrorMessage: '', + input: '', + data: [], + searchable: true, + searchNoData: '
          • No Results.
          • ', + init: noop, + choice: noop, + extendProps: [] + }; + + var KEY_CODE = { + up: 38, + down: 40, + enter: 13 + }; + + var EVENT_SPACE = { + click: 'click.iui-dropdown', + focus: 'focus.iui-dropdown', + keydown: 'keydown.iui-dropdown', + keyup: 'keyup.iui-dropdown' + }; + + var ALERT_TIMEOUT_PERIOD = 1000; + + // åˆ›å»ºæ¨¡æ¿ + function createTemplate() { + var isLabelMode = this.isLabelMode; + var searchable = this.config.searchable; + var templateSearch = searchable ? '' + this.config.input + '' : ''; + + return isLabelMode ? '' : '\xD7'; + } + + // å°äºŽminCountæç¤ºçš„元素 + function minItemsAlert() { + var _dropdown = this; + var _config = _dropdown.config; + var $el = _dropdown.$el; + var $alert = $el.find('.dropdown-minItem-alert'); + var alertMessage = _config.minCountErrorMessage; + clearTimeout(_dropdown.itemCountAlertTimer); + + if ($alert.length === 0) { + if (!alertMessage) { + alertMessage = '\u6700\u4f4e\u9009\u62e9' + _config.minCount + '\u4E2A'; + } + $alert = $(''); + } + + $el.append($alert); + _dropdown.itemCountAlertTimer = setTimeout(function () { + $el.find('.dropdown-minItem-alert').remove(); + }, ALERT_TIMEOUT_PERIOD); + } + + // 超出é™åˆ¶æç¤º + function maxItemAlert() { + var _dropdown = this; + var _config = _dropdown.config; + var $el = _dropdown.$el; + var $alert = $el.find('.dropdown-maxItem-alert'); + var alertMessage = _config.limitCountErrorMessage; + clearTimeout(_dropdown.itemLimitAlertTimer); + + if ($alert.length === 0) { + if (!alertMessage) { + alertMessage = '\u6700\u591A\u53EF\u9009\u62E9' + _config.limitCount + '\u4E2A'; + } + $alert = $(''); + } + + $el.append($alert); + _dropdown.itemLimitAlertTimer = setTimeout(function () { + $el.find('.dropdown-maxItem-alert').remove(); + }, ALERT_TIMEOUT_PERIOD); + } + + // select-option 转 ul-li + function selectToDiv(str) { + var result = str || ''; + // 移除select标签 + result = result.replace(/]*>/gi, '').replace('', ''); + // 移除 optgroup ç»“æŸæ ‡ç­¾ + result = result.replace(/<\/optgroup>/gi, ''); + result = result.replace(/]*>/gi, function (matcher) { + var groupName = /label="(.[^"]*)"(\s|>)/.exec(matcher); + var groupId = /data\-group\-id="(.[^"]*)"(\s|>)/.exec(matcher); + return ''; + }); + result = result.replace(//gi, function (matcher) { + // var value = /value="?([\w\u4E00-\u9FA5\uF900-\uFA2D]+)"?/.exec(matcher); + var value = $(matcher).val(); + var name = />(.*)<\//.exec(matcher); + // å¼ºåˆ¶è¦æ±‚html中使用selected/disabledï¼Œè€Œä¸æ˜¯selected="selected","disabled="disabled" + var isSelected = matcher.indexOf('selected') > -1 ? true : false; + var isDisabled = matcher.indexOf('disabled') > -1 ? true : false; + var extendAttr = '' + var extendProps = matcher.replace(/data-(\w+)="?(.[^"]+)"?/g, function ($1) { + extendAttr += $1 + ' ' + }); + return ''; + }); + + return result; + } + + // object-data 转 select-option + function objectToSelect(data) { + var dropdown = this; + var map = {}; + var result = ''; + var name = []; + var selectAmount = 0; + var extendProps = dropdown.config.extendProps; + + if (!data || !data.length) { + return false; + } + + $.each(data, function (index, val) { + // disable æƒé‡é«˜äºŽ selected + var hasGroup = val.groupId; + var isDisabled = val.disabled ? ' disabled' : ''; + var isSelected = val.selected && !isDisabled ? ' selected' : ''; + var extendAttr = '' + $.each(extendProps, function (index, value) { + if (val[value]) { + extendAttr += 'data-' + value + '="' + val[value] + '" ' + } + }) + var temp = '' + val.name + ''; + if (isSelected) { + name.push('' + val.name + ''); + selectAmount++; + } + // åˆ¤æ–­æ˜¯å¦æœ‰åˆ†ç»„ + if (hasGroup) { + if (map[val.groupId]) { + map[val.groupId] += temp; + } else { + // &janking& just a separator + map[val.groupId] = val.groupName + '&janking&' + temp; + } + } else { + map[index] = temp; + } + }); + + $.each(map, function (index, val) { + var option = val.split('&janking&'); + // åˆ¤æ–­æ˜¯å¦æœ‰åˆ†ç»„ + if (option.length === 2) { + var groupName = option[0]; + var items = option[1]; + result += '' + items + ''; + } else { + result += val; + } + }); + + return [result, name, selectAmount]; + } + + // select-option 转 object-data + // + function selectToObject(el) { + var $select = el; + var result = []; + + function readOption(key, el) { + var $option = $(el); + this.id = $option.prop('value'); + this.name = $option.text(); + this.disabled = $option.prop('disabled'); + this.selected = $option.prop('selected'); + } + + $.each($select.children(), function (key, el) { + var tmp = {}; + var tmpGroup = {}; + var $el = $(el); + if (el.nodeName === 'OPTGROUP') { + tmpGroup.groupId = $el.data('groupId'); + tmpGroup.groupName = $el.attr('label'); + $.each($el.children(), $.proxy(readOption, tmp)); + $.extend(tmp, tmpGroup); + } else { + $.each($el, $.proxy(readOption, tmp)); + } + result.push(tmp); + }); + + return result; + } + + var action = { + show: function (event) { + event.stopPropagation(); + var _dropdown = this; + $(document).trigger('click.dropdown'); + _dropdown.$el.addClass('active'); + }, + search: throttle(function (event) { + var _dropdown = this; + var _config = _dropdown.config; + var $el = _dropdown.$el; + var $input = $(event.target); + var intputValue = $input.val(); + var data = _dropdown.config.data; + var result = []; + if (event.keyCode > 36 && event.keyCode < 41) { + return; + } + $.each(data, function (key, value) { + if ((value.groupName && value.groupName.toLowerCase().indexOf(intputValue.toLowerCase()) > -1) || value.name.toLowerCase().indexOf(intputValue.toLowerCase()) > -1 || '' + value.id === '' + intputValue) { + result.push(value); + } + }); + $el.find('ul').html(selectToDiv(objectToSelect.call(_dropdown, result)[0]) || _config.searchNoData); + }, 300), + control: function (event) { + var keyCode = event.keyCode; + var KC = KEY_CODE; + var index = 0; + var direct; + var itemIndex; + var $items; + if (keyCode === KC.down || keyCode === KC.up) { + // æ–¹å‘ + direct = keyCode === KC.up ? -1 : 1; + $items = this.$el.find('[tabindex]'); + itemIndex = $items.index($(document.activeElement)); + // åˆå§‹ + if (itemIndex === -1) { + index = direct + 1 ? -1 : 0; + } else { + index = itemIndex; + } + // 确认ä½åº + index = index + direct; + // 最åŽä½å¾ªçޝ + if (index === $items.length) { + index = 0; + } + $items.eq(index).focus(); + event.preventDefault(); + } + }, + multiChoose: function (event, status) { + var _dropdown = this; + var _config = _dropdown.config; + var $select = _dropdown.$select; + var $target = $(event.target); + var value = $target.attr('data-value'); + var hasSelected = $target.hasClass('dropdown-chose'); + var selectedName = []; + var selectedProp; + + if ($target.hasClass('dropdown-display')) { + return false; + } + + if (hasSelected) { + $target.removeClass('dropdown-chose'); + _dropdown.selectAmount--; + } else { + if (_dropdown.selectAmount < _config.limitCount) { + $target.addClass('dropdown-chose'); + _dropdown.selectAmount++; + } else { + maxItemAlert.call(_dropdown); + return false; + } + } + + _dropdown.name = []; + + $.each(_config.data, function (key, item) { + if ('' + item.id === '' + value) { + selectedProp = item; + item.selected = hasSelected ? false : true; + } + if (item.selected) { + selectedName.push(item.name); + _dropdown.name.push('' + item.name + ''); + } + }); + + $select.find('option[value="' + value + '"]').prop('selected', hasSelected ? false : true); + + if (hasSelected && _dropdown.selectAmount < _config.minCount) { + minItemsAlert.call(_dropdown); + } + + _dropdown.$choseList.find('.dropdown-selected').remove(); + _dropdown.$choseList.prepend(_dropdown.name.join('')); + _dropdown.$el.find('.dropdown-display').attr('title', selectedName.join(',')); + _config.choice.call(_dropdown, event, selectedProp); + }, + singleChoose: function (event) { + var _dropdown = this; + var _config = _dropdown.config; + var $el = _dropdown.$el; + var $select = _dropdown.$select; + var $target = $(event.target); + var value = $target.attr('data-value'); + var hasSelected = $target.hasClass('dropdown-chose'); + + if ($target.hasClass('dropdown-chose') || $target.hasClass('dropdown-display')) { + return false; + } + + _dropdown.name = []; + + + $el.removeClass('active').find('li').not($target).removeClass('dropdown-chose'); + + $target.toggleClass('dropdown-chose'); + $.each(_config.data, function (key, item) { + // id 有å¯èƒ½æ˜¯æ•°å­—也有å¯èƒ½æ˜¯å­—符串,强制全等有弊端 2017-03-20 22:19:21 + item.selected = false; + if ('' + item.id === '' + value) { + item.selected = hasSelected ? 0 : 1; + if (item.selected) { + _dropdown.name.push('' + item.name + ''); + } + } + }); + + $select.find('option[value="' + value + '"]').prop('selected', true); + + _dropdown.name.push('' + _dropdown.placeholder + ''); + _dropdown.$choseList.html(_dropdown.name.join('')); + _config.choice.call(_dropdown, event); + }, + del: function (event) { + var _dropdown = this; + var _config = _dropdown.config; + var $target = $(event.target); + var id = $target.data('id'); + // 2017-03-23 15:58:50 测试 + // 10000æ¡æ•°æ®æµ‹è¯•删除,耗时 ~3ms + $.each(_dropdown.name, function (key, value) { + if (value.indexOf('data-id="' + id + '"') !== -1) { + _dropdown.name.splice(key, 1); + return false; + } + }); + + $.each(_dropdown.config.data, function (key, item) { + if ('' + item.id == '' + id) { + item.selected = false; + return false; + } + }); + + _dropdown.selectAmount--; + _dropdown.$el.find('[data-value="' + id + '"]').removeClass('dropdown-chose'); + _dropdown.$el.find('[value="' + id + '"]').prop('selected', false).removeAttr('selected'); + $target.closest('.dropdown-selected').remove(); + _config.choice.call(_dropdown, event); + + return false; + }, + clearAll: function (event) { + var _dropdown = this; + var _config = _dropdown.config; + event && event.preventDefault(); + console.log(this) + this.$choseList.find('.del').each(function (index, el) { + $(el).trigger('click'); + }); + + if (_config.minCount > 0) { + minItemsAlert.call(_dropdown); + } + + this.$el.find('.dropdown-display').removeAttr('title'); + return false; + } + }; + + function Dropdown(options, el) { + this.$el = $(el); + this.$select = this.$el.find('select'); + this.placeholder = this.$select.attr('placeholder'); + this.config = options; + this.name = []; + this.isSingleSelect = !this.$select.prop('multiple'); + this.selectAmount = 0; + this.itemLimitAlertTimer = null; + this.isLabelMode = this.config.multipleMode === 'label'; + this.init(); + } + + Dropdown.prototype = { + init: function () { + var _this = this; + var _config = _this.config; + var $el = _this.$el; + _this.$select.hide(); + // 判断dropdown是å¦å•选,是å¦tokenæ¨¡å¼ + $el.addClass(_this.isSingleSelect ? 'dropdown-single' : _this.isLabelMode ? 'dropdown-multiple-label' : 'dropdown-multiple'); + + if (_config.data.length === 0) { + _config.data = selectToObject(_this.$select); + } + + var processResult = objectToSelect.call(_this, _config.data); + + _this.name = processResult[1]; + _this.selectAmount = processResult[2]; + _this.$select.html(processResult[0]); + _this.renderSelect(); + // disabledæƒé‡é«˜äºŽreadonly + _this.changeStatus(_config.disabled ? 'disabled' : _config.readonly ? 'readonly' : false); + + _this.config.init(); + }, + // 渲染 select 为 dropdown + renderSelect: function (isUpdate, isCover) { + var _this = this; + var $el = _this.$el; + var $select = _this.$select; + var elemLi = selectToDiv($select.prop('outerHTML')); + var template; + + if (isUpdate) { + $el.find('ul')[isCover ? 'html' : 'append'](elemLi); + } else { + template = createTemplate.call(_this).replace('{{ul}}', '
              ' + elemLi + '
            '); + $el.append(template).find('ul').removeAttr('style class'); + } + + if (isCover) { + _this.name = []; + _this.$el.find('.dropdown-selected').remove(); + _this.$select.val(''); + } + + _this.$choseList = $el.find('.dropdown-chose-list'); + + if (!_this.isLabelMode) { + _this.$choseList.html($('').text(_this.placeholder)); + } + + _this.$choseList.prepend(_this.name ? _this.name.join('') : []); + }, + bindEvent: function () { + var _this = this; + var $el = _this.$el; + var openHandle = isSafari ? EVENT_SPACE.click : EVENT_SPACE.focus; + + $el.on(EVENT_SPACE.click, function (event) { + event.stopPropagation(); + }); + + $el.on(EVENT_SPACE.click, '.del', $.proxy(action.del, _this)); + + // show + if (_this.isLabelMode) { + $el.on(EVENT_SPACE.click, '.dropdown-display-label', function () { + $el.find('input').focus(); + }); + if (_this.config.searchable) { + $el.on(EVENT_SPACE.focus, 'input', $.proxy(action.show, _this)); + } else { + $el.on(EVENT_SPACE.click, $.proxy(action.show, _this)); + } + $el.on(EVENT_SPACE.keydown, 'input', function (event) { + if (event.keyCode === 8 && this.value === '' && _this.name.length) { + $el.find('.del').eq(-1).trigger('click'); + } + }); + } else { + $el.on(openHandle, '.dropdown-display', $.proxy(action.show, _this)); + $el.on(openHandle, '.dropdown-clear-all', $.proxy(action.clearAll, _this)); + } + + // æœç´¢ + $el.on(EVENT_SPACE.keyup, 'input', $.proxy(action.search, _this)); + + // 按下enter键设置token + $el.on(EVENT_SPACE.keyup, function (event) { + var keyCode = event.keyCode; + var KC = KEY_CODE; + if (keyCode === KC.enter) { + $.proxy(_this.isSingleSelect ? action.singleChoose : action.multiChoose, _this, event)(); + } + }); + + // 按下上下键切æ¢token + $el.on(EVENT_SPACE.keydown, $.proxy(action.control, _this)); + + $el.on(EVENT_SPACE.click, 'li[tabindex]', $.proxy(_this.isSingleSelect ? action.singleChoose : action.multiChoose, _this)); + }, + unbindEvent: function () { + var _this = this; + var $el = _this.$el; + var openHandle = isSafari ? EVENT_SPACE.click : EVENT_SPACE.focus; + + $el.off(EVENT_SPACE.click); + $el.off(EVENT_SPACE.click, '.del'); + + // show + if (_this.isLabelMode) { + $el.off(EVENT_SPACE.click, '.dropdown-display-label'); + $el.off(EVENT_SPACE.focus, 'input'); + $el.off(EVENT_SPACE.keydown, 'input'); + } else { + $el.off(openHandle, '.dropdown-display'); + $el.off(openHandle, '.dropdown-clear-all'); + } + // æœç´¢ + $el.off(EVENT_SPACE.keyup, 'input'); + // 按下enter键设置token + $el.off(EVENT_SPACE.keyup); + // 按下上下键切æ¢token + $el.off(EVENT_SPACE.keydown); + $el.off(EVENT_SPACE.click, '[tabindex]'); + }, + changeStatus: function (status) { + var _this = this; + if (status === 'readonly') { + _this.unbindEvent(); + } else if (status === 'disabled') { + _this.$select.prop('disabled', true); + _this.unbindEvent(); + } else { + _this.$select.prop('disabled', false); + _this.bindEvent(); + } + }, + update: function (data, isCover) { + var _this = this; + var _config = _this.config; + var $el = _this.$el; + var _isCover = isCover || false; + + if (Object.prototype.toString.call(data) !== '[object Array]') { + return; + } + + _config.data = _isCover ? data.slice(0) : _config.data.concat(data); + + var processResult = objectToSelect.call(_this, _config.data); + + _this.name = processResult[1]; + _this.selectAmount = processResult[2]; + _this.$select.html(processResult[0]); + _this.renderSelect(true, _isCover); + }, + destroy: function () { + this.unbindEvent(); + this.$el.children().not('select').remove(); + this.$el.removeClass('dropdown-single dropdown-multiple-label dropdown-multiple'); + this.$select.show(); + }, + choose: function (values, status) { + var valArr = Object.prototype.toString.call(values) === '[object Array]' ? values : [values]; + var _this = this; + var _status = status !== void 0 ? !!status : true + $.each(valArr, function (index, value) { + var $target = _this.$el.find('[data-value="' + value + '"]'); + var targetStatus = $target.hasClass('dropdown-chose'); + if (targetStatus !== _status) { + $target.trigger(EVENT_SPACE.click, status || true) + } + }); + }, + reset: function () { + action.clearAll.call(this) + } + }; + + $(document).on('click.dropdown', function () { + $('.dropdown-single,.dropdown-multiple,.dropdown-multiple-label').removeClass('active'); + }); + + $.fn.dropdown = function (options) { + this.each(function (index, el) { + $(el).data('dropdown', new Dropdown($.extend(true, {}, settings, options), el)); + }); + return this; + } +})(jQuery); diff --git a/html/wp-content/plugins/svg-support/js/min/gutenberg-filters-min.js b/html/wp-content/plugins/svg-support/js/min/gutenberg-filters-min.js new file mode 100644 index 0000000..c0889f5 --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/min/gutenberg-filters-min.js @@ -0,0 +1 @@ +"use strict";function CheckBoxCustom(e){const[t,n]=useState(e.meta.inline_featured_image),{meta:o,updateInlineFeaturedSvg:a}=e;return createElement(wp.components.CheckboxControl,{label:"Render this SVG inline (Advanced)",checked:t,onChange:e=>{n(e),a(e,o)},__nextHasNoMarginBottom:!0})}function wrapPostFeaturedImage(e){return function(t){return createElement(Fragment,{},"",createElement(e,t),createElement(composedCheckBox))}}const{createElement:createElement,Fragment:Fragment,useState:useState}=wp.element,{withSelect:withSelect,withDispatch:withDispatch}=wp.data,{compose:compose}=wp.compose,composedCheckBox=compose([withSelect((e=>{const t=undefined,n=undefined;return{meta:{...e("core/editor").getCurrentPostAttribute("meta"),...e("core/editor").getEditedPostAttribute("meta")}}})),withDispatch((e=>({updateInlineFeaturedSvg(t,n){n={...n,inline_featured_image:t},e("core/editor").editPost({meta:n})}})))])(CheckBoxCustom);wp.hooks.addFilter("editor.PostFeaturedImage","bodhi-svgs-featured-image/render-inline-image-checkbox",wrapPostFeaturedImage); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/js/min/jquery.dropdown-min.js b/html/wp-content/plugins/svg-support/js/min/jquery.dropdown-min.js new file mode 100644 index 0000000..d6896b6 --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/min/jquery.dropdown-min.js @@ -0,0 +1 @@ +(function(e){"use strict";function o(){}function n(e,o,n){var t,i,l,a=null,d=0;n||(n={});var s=function(){d=n.leading===!1?0:(new Date).getTime(),a=null,l=e.apply(t,i),a||(t=i=null)};return function(){var r=(new Date).getTime();d||n.leading!==!1||(d=r);var c=o-(r-d);return t=this,i=arguments,c<=0||c>o?(clearTimeout(a),a=null,d=r,l=e.apply(t,i),a||(t=i=null)):a||n.trailing===!1||(a=setTimeout(s,c)),l}}function t(){var e=this.isLabelMode,o=this.config.searchable,n=o?''+this.config.input+"":"";return e?'':'×"}function i(){var o=this,n=o.config,t=o.$el,i=t.find(".dropdown-minItem-alert"),l=n.minCountErrorMessage;clearTimeout(o.itemCountAlertTimer),0===i.length&&(l||(l="最低选择"+n.minCount+"个"),i=e('")),t.append(i),o.itemCountAlertTimer=setTimeout(function(){t.find(".dropdown-minItem-alert").remove()},f)}function l(){var o=this,n=o.config,t=o.$el,i=t.find(".dropdown-maxItem-alert"),l=n.limitCountErrorMessage;clearTimeout(o.itemLimitAlertTimer),0===i.length&&(l||(l="最多å¯é€‰æ‹©"+n.limitCount+"个"),i=e('")),t.append(i),o.itemLimitAlertTimer=setTimeout(function(){t.find(".dropdown-maxItem-alert").remove()},f)}function a(o){var n=o||"";return n=n.replace(/]*>/gi,"").replace("",""),n=n.replace(/<\/optgroup>/gi,""),n=n.replace(/]*>/gi,function(e){var o=/label="(.[^"]*)"(\s|>)/.exec(e),n=/data\-group\-id="(.[^"]*)"(\s|>)/.exec(e);return'"}),n=n.replace(//gi,function(o){var n=e(o).val(),t=/>(.*)<\//.exec(o),i=o.indexOf("selected")>-1,l=o.indexOf("disabled")>-1,a="";o.replace(/data-(\w+)="?(.[^"]+)"?/g,function(e){a+=e+" "});return""})}function d(o){var n=this,t={},i="",l=[],a=0,d=n.config.extendProps;return!(!o||!o.length)&&(e.each(o,function(o,n){var i=n.groupId,s=n.disabled?" disabled":"",r=n.selected&&!s?" selected":"",c="";e.each(d,function(e,o){n[o]&&(c+="data-"+o+'="'+n[o]+'" ')});var p=""+n.name+"";r&&(l.push(''+n.name+''),a++),i?t[n.groupId]?t[n.groupId]+=p:t[n.groupId]=n.groupName+"&janking&"+p:t[o]=p}),e.each(t,function(e,o){var n=o.split("&janking&");if(2===n.length){var t=n[0],l=n[1];i+=''+l+""}else i+=o}),[i,l,a])}function s(o){function n(o,n){var t=e(n);this.id=t.prop("value"),this.name=t.text(),this.disabled=t.prop("disabled"),this.selected=t.prop("selected")}var t=o,i=[];return e.each(t.children(),function(o,t){var l={},a={},d=e(t);"OPTGROUP"===t.nodeName?(a.groupId=d.data("groupId"),a.groupName=d.attr("label"),e.each(d.children(),e.proxy(n,l)),e.extend(l,a)):e.each(d,e.proxy(n,l)),i.push(l)}),i}function r(o,n){this.$el=e(n),this.$select=this.$el.find("select"),this.placeholder=this.$select.attr("placeholder"),this.config=o,this.name=[],this.isSingleSelect=!this.$select.prop("multiple"),this.selectAmount=0,this.itemLimitAlertTimer=null,this.isLabelMode="label"===this.config.multipleMode,this.init()}var c=function(){var e=navigator.userAgent.toLowerCase();if(e.indexOf("safari")!==-1)return!(e.indexOf("chrome")>-1)}(),p={readonly:!1,minCount:0,minCountErrorMessage:"",limitCount:1/0,limitCountErrorMessage:"",input:'',data:[],searchable:!0,searchNoData:'
          • 查无数æ®ï¼Œæ¢ä¸ªè¯å„¿è¯•试 /(ã„’oã„’)/~~
          • ',init:o,choice:o,extendProps:[]},u={up:38,down:40,enter:13},h={click:"click.iui-dropdown",focus:"focus.iui-dropdown",keydown:"keydown.iui-dropdown",keyup:"keyup.iui-dropdown"},f=1e3,m={show:function(o){o.stopPropagation();var n=this;e(document).trigger("click.dropdown"),n.$el.addClass("active")},search:n(function(o){var n=this,t=n.config,i=n.$el,l=e(o.target),s=l.val(),r=n.config.data,c=[];o.keyCode>36&&o.keyCode<41||(e.each(r,function(e,o){(o.groupName&&o.groupName.toLowerCase().indexOf(s.toLowerCase())>-1||o.name.toLowerCase().indexOf(s.toLowerCase())>-1||""+o.id==""+s)&&c.push(o)}),i.find("ul").html(a(d.call(n,c)[0])||t.searchNoData))},300),control:function(o){var n,t,i,l=o.keyCode,a=u,d=0;l!==a.down&&l!==a.up||(n=l===a.up?-1:1,i=this.$el.find("[tabindex]"),t=i.index(e(document.activeElement)),d=t===-1?n+1?-1:0:t,d+=n,d===i.length&&(d=0),i.eq(d).focus(),o.preventDefault())},multiChoose:function(o,n){var t,a=this,d=a.config,s=a.$select,r=e(o.target),c=r.attr("data-value"),p=r.hasClass("dropdown-chose"),u=[];if(r.hasClass("dropdown-display"))return!1;if(p)r.removeClass("dropdown-chose"),a.selectAmount--;else{if(!(a.selectAmount'+o.name+''))}),s.find('option[value="'+c+'"]').prop("selected",!p),p&&a.selectAmount'+o.name+''))}),l.find('option[value="'+d+'"]').prop("selected",!0),n.name.push(''+n.placeholder+""),n.$choseList.html(n.name.join("")),void t.choice.call(n,o))},del:function(o){var n=this,t=n.config,i=e(o.target),l=i.data("id");return e.each(n.name,function(e,o){if(o.indexOf('data-id="'+l+'"')!==-1)return n.name.splice(e,1),!1}),e.each(n.config.data,function(e,o){if(""+o.id==""+l)return o.selected=!1,!1}),n.selectAmount--,n.$el.find('[data-value="'+l+'"]').removeClass("dropdown-chose"),n.$el.find('[value="'+l+'"]').prop("selected",!1).removeAttr("selected"),i.closest(".dropdown-selected").remove(),t.choice.call(n,o),!1},clearAll:function(o){var n=this,t=n.config;return o&&o.preventDefault(),console.log(this),this.$choseList.find(".del").each(function(o,n){e(n).trigger("click")}),t.minCount>0&&i.call(n),this.$el.find(".dropdown-display").removeAttr("title"),!1}};r.prototype={init:function(){var e=this,o=e.config,n=e.$el;e.$select.hide(),n.addClass(e.isSingleSelect?"dropdown-single":e.isLabelMode?"dropdown-multiple-label":"dropdown-multiple"),0===o.data.length&&(o.data=s(e.$select));var t=d.call(e,o.data);e.name=t[1],e.selectAmount=t[2],e.$select.html(t[0]),e.renderSelect(),e.changeStatus(o.disabled?"disabled":!!o.readonly&&"readonly"),e.config.init()},renderSelect:function(o,n){var i,l=this,d=l.$el,s=l.$select,r=a(s.prop("outerHTML"));o?d.find("ul")[n?"html":"append"](r):(i=t.call(l).replace("{{ul}}","
              "+r+"
            "),d.append(i).find("ul").removeAttr("style class")),n&&(l.name=[],l.$el.find(".dropdown-selected").remove(),l.$select.val("")),l.$choseList=d.find(".dropdown-chose-list"),l.isLabelMode||l.$choseList.html(e('').text(l.placeholder)),l.$choseList.prepend(l.name?l.name.join(""):[])},bindEvent:function(){var o=this,n=o.$el,t=c?h.click:h.focus;n.on(h.click,function(e){e.stopPropagation()}),n.on(h.click,".del",e.proxy(m.del,o)),o.isLabelMode?(n.on(h.click,".dropdown-display-label",function(){n.find("input").focus()}),o.config.searchable?n.on(h.focus,"input",e.proxy(m.show,o)):n.on(h.click,e.proxy(m.show,o)),n.on(h.keydown,"input",function(e){8===e.keyCode&&""===this.value&&o.name.length&&n.find(".del").eq(-1).trigger("click")})):(n.on(t,".dropdown-display",e.proxy(m.show,o)),n.on(t,".dropdown-clear-all",e.proxy(m.clearAll,o))),n.on(h.keyup,"input",e.proxy(m.search,o)),n.on(h.keyup,function(n){var t=n.keyCode,i=u;t===i.enter&&e.proxy(o.isSingleSelect?m.singleChoose:m.multiChoose,o,n)()}),n.on(h.keydown,e.proxy(m.control,o)),n.on(h.click,"li[tabindex]",e.proxy(o.isSingleSelect?m.singleChoose:m.multiChoose,o))},unbindEvent:function(){var e=this,o=e.$el,n=c?h.click:h.focus;o.off(h.click),o.off(h.click,".del"),e.isLabelMode?(o.off(h.click,".dropdown-display-label"),o.off(h.focus,"input"),o.off(h.keydown,"input")):(o.off(n,".dropdown-display"),o.off(n,".dropdown-clear-all")),o.off(h.keyup,"input"),o.off(h.keyup),o.off(h.keydown),o.off(h.click,"[tabindex]")},changeStatus:function(e){var o=this;"readonly"===e?o.unbindEvent():"disabled"===e?(o.$select.prop("disabled",!0),o.unbindEvent()):(o.$select.prop("disabled",!1),o.bindEvent())},update:function(e,o){var n=this,t=n.config,i=(n.$el,o||!1);if("[object Array]"===Object.prototype.toString.call(e)){t.data=i?e.slice(0):t.data.concat(e);var l=d.call(n,t.data);n.name=l[1],n.selectAmount=l[2],n.$select.html(l[0]),n.renderSelect(!0,i)}},destroy:function(){this.unbindEvent(),this.$el.children().not("select").remove(),this.$el.removeClass("dropdown-single dropdown-multiple-label dropdown-multiple"),this.$select.show()},choose:function(o,n){var t="[object Array]"===Object.prototype.toString.call(o)?o:[o],i=this,l=void 0===n||!!n;e.each(t,function(e,o){var t=i.$el.find('[data-value="'+o+'"]'),a=t.hasClass("dropdown-chose");a!==l&&t.trigger(h.click,n||!0)})},reset:function(){m.clearAll.call(this)}},e(document).on("click.dropdown",function(){e(".dropdown-single,.dropdown-multiple,.dropdown-multiple-label").removeClass("active")}),e.fn.dropdown=function(o){return this.each(function(n,t){e(t).data("dropdown",new r(e.extend(!0,{},p,o),t))}),this}})(jQuery); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/js/min/svgs-inline-min.js b/html/wp-content/plugins/svg-support/js/min/svgs-inline-min.js new file mode 100644 index 0000000..43621ad --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/min/svgs-inline-min.js @@ -0,0 +1 @@ +jQuery(document).ready((function($){function t(t){const s=t.hasClass(i),r=t.parent().hasClass(i),n=t.closest("."+i).length>0;if(("true"===ForceInlineSVGActive||s||n)&&(!svgSettings.skipNested||s||r||!n)){var a=t.attr("id"),o=t.attr("class"),c=t.attr("src");c.endsWith("svg")&&$.get(c,(function(i){var s=$(i).find("svg"),r=s.attr("id");void 0===a?void 0===r?(a="svg-replaced-"+e,s=s.attr("id",a)):a=r:s=s.attr("id",a),void 0!==o&&(s=s.attr("class",o+" replaced-svg svg-replaced-"+e)),s=s.removeAttr("xmlns:a"),"on"===frontSanitizationEnabled&&""!=s[0].outerHTML&&(s=DOMPurify.sanitize(s[0].outerHTML)),t.replaceWith(s),e++,$(document).trigger("svg.loaded",[a])}),"xml").fail((function(){}))}}let e=0,i;(bodhisvgsInlineSupport=function(){"true"===ForceInlineSVGActive&&jQuery("img").each((function(){void 0!==jQuery(this).attr("src")&&!1!==jQuery(this).attr("src")&&jQuery(this).attr("src").match(/\.(svg)/)&&(jQuery(this).hasClass(cssTarget.ForceInlineSVG)||jQuery(this).addClass(cssTarget.ForceInlineSVG))})),String.prototype.endsWith||(String.prototype.endsWith=function(t,e){var i=this.toString();("number"!=typeof e||!isFinite(e)||Math.floor(e)!==e||e>i.length)&&(e=i.length),e-=t.length;var s=i.lastIndexOf(t,e);return-1!==s&&s===e}),String.prototype.endsWith=function(t){var e=this.length-t.length;return e>=0&&this.lastIndexOf(t)===e},i="true"===ForceInlineSVGActive?"img."!==cssTarget.Bodhi?cssTarget.ForceInlineSVG:"style-svg":"img."!==cssTarget.Bodhi?cssTarget.Bodhi:"style-svg","string"==typeof i&&(i=i.replace("img.",""),$("."+i).each((function(e){void 0!==$(this).attr("src")&&!1!==$(this).attr("src")?t($(this)):$(this).find("img").each((function(e){void 0!==$(this).attr("src")&&!1!==$(this).attr("src")&&t($(this))}))})))})()})); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/js/min/svgs-inline-vanilla-min.js b/html/wp-content/plugins/svg-support/js/min/svgs-inline-vanilla-min.js new file mode 100644 index 0000000..bad6bc0 --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/min/svgs-inline-vanilla-min.js @@ -0,0 +1 @@ +document.addEventListener("DOMContentLoaded",(function(e){function t(e){if("IMG"!==e.nodeName)return;const t=e.classList.contains(i),n=e.parentElement.classList.contains(i),r=null!==e.closest("."+i);if(("true"===ForceInlineSVGActive||t||r)&&(!svgSettings.skipNested||t||n||!r)){var o=e.id,a=e.className,c=e.src;if(c.endsWith("svg")){var l=new XMLHttpRequest;l.onreadystatechange=function(){if(4===l.readyState&&200===l.status){var t=l.responseText;let c;const d=undefined;var n=(new DOMParser).parseFromString(t,"text/html").getElementsByTagName("svg")[0],i=n.id;if(void 0===o||""===o?void 0===i||""===i?(o="svg-replaced-"+s,n.setAttribute("id",o)):o=i:n.setAttribute("id",o),void 0!==a&&""!==a&&n.setAttribute("class",a+" replaced-svg svg-replaced-"+s),n.removeAttribute("xmlns:a"),"on"===frontSanitizationEnabled&&""!==n.outerHTML){var r=DOMPurify.sanitize(n.outerHTML);e.outerHTML=r}else e.replaceWith(n);s++}else 4===l.readyState&&l.status},l.open("GET",c,!0),l.send(null)}}}function n(e){if(e.childNodes.length>0)for(var s=0;sn.length)&&(t=n.length),t-=e.length;var s=n.lastIndexOf(e,t);return-1!==s&&s===t}),String.prototype.endsWith=function(e){var t=this.length-e.length;return t>=0&&this.lastIndexOf(e)===t},i="true"===ForceInlineSVGActive?"img."!==cssTarget.Bodhi?cssTarget.ForceInlineSVG:"style-svg":"img."!==cssTarget.Bodhi?cssTarget.Bodhi:"style-svg","string"==typeof i&&(i=i.replace("img.",""),document.querySelectorAll("."+i).forEach((function(e){"IMG"===e.nodeName?t(e):n(e)})))})()})); \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/js/svgs-inline-vanilla.js b/html/wp-content/plugins/svg-support/js/svgs-inline-vanilla.js new file mode 100644 index 0000000..7e6ddce --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/svgs-inline-vanilla.js @@ -0,0 +1,168 @@ +/* eslint-env browser */ +/* global svgSettings, ForceInlineSVGActive, cssTarget, frontSanitizationEnabled, DOMPurify */ + +document.addEventListener("DOMContentLoaded", function(event) { + + let bodhisvgsReplacements = 0; + let target; + + // Function to replace the img tag with the SVG + function bodhisvgsReplace(img) { + // Ensure it's an image + if (img.nodeName !== 'IMG') { + return; + } + + const hasTargetClass = img.classList.contains(target); + const parentHasTargetClass = img.parentElement.classList.contains(target); + const insideTargetContainer = img.closest('.' + target) !== null; + + // First check if we should process at all + if (ForceInlineSVGActive !== 'true' && !hasTargetClass && !insideTargetContainer) { + return; + } + + // If skip nested is enabled, only skip if: + // 1. Image doesn't have target class AND + // 2. Image's parent is not the target container but is inside one + if (svgSettings.skipNested && !hasTargetClass && !parentHasTargetClass && insideTargetContainer) { + return; + } + + var imgID = img.id; + var imgClass = img.className; + var imgURL = img.src; + + // Ensure the URL ends with .svg before proceeding + if (!imgURL.endsWith('svg')) { + return; + } + + var xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = function() { + if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { + var data = xmlHttp.responseText; + + // Parse the returned data to extract the SVG + let parser = new DOMParser(); + const doc = parser.parseFromString(data, 'text/html'); + + // Get the SVG tag from the parsed data + var svg = doc.getElementsByTagName('svg')[0]; + + var svgID = svg.id; + + // Add replaced image's ID to the new SVG if necessary + if (typeof imgID === 'undefined' || imgID === '') { + if (typeof svgID === 'undefined' || svgID === '') { + imgID = 'svg-replaced-' + bodhisvgsReplacements; + svg.setAttribute('id', imgID); + } else { + imgID = svgID; + } + } else { + svg.setAttribute('id', imgID); + } + + // Add replaced image's classes to the new SVG + if (typeof imgClass !== 'undefined' && imgClass !== '') { + svg.setAttribute('class', imgClass + ' replaced-svg svg-replaced-' + bodhisvgsReplacements); + } + + // Remove any invalid XML tags as per http://validator.w3.org + svg.removeAttribute('xmlns:a'); + + // If sanitization is enabled, sanitize the SVG code + if (frontSanitizationEnabled === 'on' && svg.outerHTML !== "") { + var sanitizedSVG = DOMPurify.sanitize(svg.outerHTML); + img.outerHTML = sanitizedSVG; + } else { + img.replaceWith(svg); + } + + bodhisvgsReplacements++; + + } else if (xmlHttp.readyState === 4 && xmlHttp.status !== 200) { + // Silently fail + } + }; + + xmlHttp.open("GET", imgURL, true); + xmlHttp.send(null); + } + + // Function to iterate over nodes and replace images + function bodhisvgsIterator(node) { + if (node.childNodes.length > 0) { + for (var i = 0; i < node.childNodes.length; i++) { + if (node.childNodes[i].nodeName === 'IMG') { + var img = node.childNodes[i]; + bodhisvgsReplace(img); + } else { + bodhisvgsIterator(node.childNodes[i]); + } + } + } + } + + // Wrap in IIFE so that it can be called again later as bodhisvgsInlineSupport(); + (bodhisvgsInlineSupport = function() { + // If force inline SVG option is active then add class + if (ForceInlineSVGActive === 'true') { + var allImages = document.getElementsByTagName('img'); + for (var i = 0; i < allImages.length; i++) { + if (typeof allImages[i].src !== 'undefined') { + if (allImages[i].src.match(/\.(svg)/)) { + if (!allImages[i].classList.contains(cssTarget.ForceInlineSVG)) { + allImages[i].classList.add(cssTarget.ForceInlineSVG); + } + } + } + } + } + + // Polyfill to support all older browsers + if (!String.prototype.endsWith) { + String.prototype.endsWith = function(searchString, position) { + var subjectString = this.toString(); + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { + position = subjectString.length; + } + position -= searchString.length; + var lastIndex = subjectString.lastIndexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + } + + // Another snippet to support IE11 + String.prototype.endsWith = function(pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }; + + // Set target before we use it + if (ForceInlineSVGActive === 'true') { + target = cssTarget.Bodhi !== 'img.' ? cssTarget.ForceInlineSVG : 'style-svg'; + } else { + target = cssTarget.Bodhi !== 'img.' ? cssTarget.Bodhi : 'style-svg'; + } + + // Ensure target is a string before applying replace method + if (typeof target === 'string') { + target = target.replace("img.", ""); + } else { + return; + } + + // Replace images with SVGs based on the target class + document.querySelectorAll('.' + target).forEach(function(element) { + if (element.nodeName === 'IMG') { + bodhisvgsReplace(element); + } else { + bodhisvgsIterator(element); + } + }); + + })(); // Execute immediately +}); + diff --git a/html/wp-content/plugins/svg-support/js/svgs-inline.js b/html/wp-content/plugins/svg-support/js/svgs-inline.js new file mode 100644 index 0000000..dfc594e --- /dev/null +++ b/html/wp-content/plugins/svg-support/js/svgs-inline.js @@ -0,0 +1,166 @@ +/* eslint-env jquery */ +/* global svgSettings, ForceInlineSVGActive, cssTarget, frontSanitizationEnabled, DOMPurify, jQuery */ + +jQuery(document).ready(function ($) { + + let bodhisvgsReplacements = 0; + let target; + + // Function to replace the img tag with the SVG + function bodhisvgsReplace(img) { + const hasTargetClass = img.hasClass(target); + const parentHasTargetClass = img.parent().hasClass(target); + const insideTargetContainer = img.closest('.' + target).length > 0; + + // First check if we should process at all + if (ForceInlineSVGActive !== 'true' && !hasTargetClass && !insideTargetContainer) { + return; + } + + // If skip nested is enabled, only skip if: + // 1. Image doesn't have target class AND + // 2. Image's parent is not the target container but is inside one + if (svgSettings.skipNested && !hasTargetClass && !parentHasTargetClass && insideTargetContainer) { + return; + } + + var imgID = img.attr('id'); + var imgClass = img.attr('class'); + var imgURL = img.attr('src'); + + // Ensure the URL ends with .svg before proceeding + if (!imgURL.endsWith('svg')) { + return; + } + + // Use jQuery's get method to fetch the SVG + $.get(imgURL, function(data) { + + // Get the SVG tag, ignore the rest + var $svg = $(data).find('svg'); + + var svgID = $svg.attr('id'); + + // Add replaced image's ID to the new SVG if necessary + if (typeof imgID === 'undefined') { + if (typeof svgID === 'undefined') { + imgID = 'svg-replaced-' + bodhisvgsReplacements; + $svg = $svg.attr('id', imgID); + } else { + imgID = svgID; + } + } else { + $svg = $svg.attr('id', imgID); + } + + // Add replaced image's classes to the new SVG + if (typeof imgClass !== 'undefined') { + $svg = $svg.attr('class', imgClass + ' replaced-svg svg-replaced-' + bodhisvgsReplacements); + } + + // Remove any invalid XML tags as per http://validator.w3.org + $svg = $svg.removeAttr('xmlns:a'); + + // If sanitization is enabled, sanitize the SVG code + if (frontSanitizationEnabled === 'on' && $svg[0]['outerHTML'] != "") { + $svg = DOMPurify.sanitize($svg[0]['outerHTML']); + } + + // Replace image with new SVG + img.replaceWith($svg); + + // Increment the replacements counter + bodhisvgsReplacements++; + + // Trigger custom event after SVG is loaded + $(document).trigger('svg.loaded', [imgID]); + + }, 'xml').fail(function() { + // Silently fail + }); + + } + + // Wrap in IIFE so that it can be called again later as bodhisvgsInlineSupport(); + (bodhisvgsInlineSupport = function () { + + // If force inline SVG option is active then add class + if (ForceInlineSVGActive === 'true') { + + // Find all SVG inside img and add class if it hasn't got it + jQuery('img').each(function () { + + // Check if the SRC attribute is present at all + if (typeof jQuery(this).attr('src') !== typeof undefined && jQuery(this).attr('src') !== false) { + + // Pick only those with the extension we want + if (jQuery(this).attr('src').match(/\.(svg)/)) { + + // Add our class name + if (!jQuery(this).hasClass(cssTarget.ForceInlineSVG)) { + jQuery(this).addClass(cssTarget.ForceInlineSVG); + } + } + } + }); + } + + // Polyfill to support all older browsers + // delete when not needed in the future + if (!String.prototype.endsWith) { + String.prototype.endsWith = function (searchString, position) { + var subjectString = this.toString(); + if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { + position = subjectString.length; + } + position -= searchString.length; + var lastIndex = subjectString.lastIndexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + } // end polyfill + + // Another snippet to support IE11 + String.prototype.endsWith = function (pattern) { + var d = this.length - pattern.length; + return d >= 0 && this.lastIndexOf(pattern) === d; + }; + // End snippet to support IE11 + + // Set target before we use it + if (ForceInlineSVGActive === 'true') { + target = cssTarget.Bodhi !== 'img.' ? cssTarget.ForceInlineSVG : 'style-svg'; + } else { + target = cssTarget.Bodhi !== 'img.' ? cssTarget.Bodhi : 'style-svg'; + } + + // Ensure target is a string before applying replace method + if (typeof target === 'string') { + target = target.replace("img.", ""); + } else { + return; + } + + // Replace images with SVGs based on the target class + $('.' + target).each(function (index) { + + // If image then send for replacement + if (typeof $(this).attr('src') !== typeof undefined && $(this).attr('src') !== false) { + bodhisvgsReplace($(this)); + } else { + + // Look for SVG children and send for replacement + $(this).find("img").each(function (i) { + + if (typeof $(this).attr('src') !== typeof undefined && $(this).attr('src') !== false) { + bodhisvgsReplace($(this)); + } + + }); + + } + + }); + + })(); // Execute immediately + +}); diff --git a/html/wp-content/plugins/svg-support/languages/svgsupport-es_ES.mo b/html/wp-content/plugins/svg-support/languages/svgsupport-es_ES.mo new file mode 100644 index 0000000..3178a1a Binary files /dev/null and b/html/wp-content/plugins/svg-support/languages/svgsupport-es_ES.mo differ diff --git a/html/wp-content/plugins/svg-support/languages/svgsupport-es_ES.po b/html/wp-content/plugins/svg-support/languages/svgsupport-es_ES.po new file mode 100644 index 0000000..5ae7a26 --- /dev/null +++ b/html/wp-content/plugins/svg-support/languages/svgsupport-es_ES.po @@ -0,0 +1,281 @@ +msgid "" +msgstr "" +"Project-Id-Version: SVG Support 2.2.3.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-05-16 20:19:06+00:00\n" +"PO-Revision-Date: Mon May 16 2016 13:54:01 GMT-0700 (PDT)\n" +"Last-Translator: root \n" +"Language-Team: Benbodhi \n" +"Language: Spanish (Spain)\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Generator: Loco - https://localise.biz/\n" +"X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;" +"__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;" +"_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;" +"esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;" +"esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n" +"X-Poedit-Basepath: ..\n" +"X-Textdomain-Support: yes\n" +"X-Loco-Target-Locale: es_ES\n" +"X-Poedit-SearchPath-0: ." + +#. URI of the plugin +msgid "http://wordpress.org/plugins/svg-support" +msgstr "" + +#: ../admin/plugin-action-meta-links.php:32 +msgid "$25 Free Credit from GoWebben" +msgstr "" + +#: ../admin/svgs-settings-page.php:57 +msgid "Output JS in Footer?" +msgstr "" + +#: ../admin/svgs-settings-page.php:62 +msgid "" +" Normally, scripts are placed in head of the HTML document. If " +"this parameter is true, the script is placed before the closing " +"body tag. This requires the theme to have the " +"wp_footer() template tag in the appropriate place." +msgstr "" + +#: ../admin/svgs-settings-page.php:68 +msgid "Automatically insert class?" +msgstr "" + +#: ../admin/svgs-settings-page.php:73 +msgid "" +" Checking this will make sure that either the default class or the custom " +"one you set below is inserted into the style attributes of img " +"tags when you insert images. Additionally, it will remove all of the default " +"WordPress classes." +msgstr "" + +#: ../admin/svgs-settings-page.php:112 +msgid "Please Note:" +msgstr "" + +#: ../admin/svgs-settings-page.php:113 +msgid "" +"- You will need to set your own height and width in your CSS for SVG files " +"to display correctly." +msgstr "" + +#: ../admin/svgs-settings-page.php:114 +msgid "" +"- Your uploaded image needs to be an SVG file for this plugin to replace the " +"img tag with the inline SVG code. It will not create SVG files for you." +msgstr "" + +#: ../admin/svgs-settings-page.php:131 +msgid "Plugin Features" +msgstr "" + +#: ../admin/svgs-settings-page.php:145 +msgid "About The Plugin" +msgstr "" + +#: ../admin/svgs-settings-page.php:157 +msgid "GoWebben Hosting" +msgstr "" + +#: ../admin/svgs-settings-page.php:159 +msgid "Claim your FREE $25 credit from" +msgstr "" + +#: ../admin/svgs-settings-page.php:159 +msgid "" +"No catch, just free credit for using this plugin! It will be applied " +"automatically using the link provided, but in any case you can simply use " +"code: SVGSUPPORT during checkout." +msgstr "" + +msgid "SVG Support" +msgstr "SVG Support" + +msgid "" +"Allow SVG file uploads using the WordPress Media Library uploader plus " +"direct styling of SVG elements using CSS." +msgstr "" +"Permitir la subida de archivos SVG a través de la librería de medios además " +"de dar formato a los elementos SVG usando CSS." + +msgid "Benbodhi" +msgstr "Benbodhi" + +msgid "http://benbodhi.com" +msgstr "http://benbodhi.com" + +#: ../admin/admin-init.php:15 +msgid "SVG Support Options and Instructions" +msgstr "SVG Support Opciones e Instrucciones" + +#: ../admin/admin-init.php:29 +msgid "You can't play with this." +msgstr "No puedes jugar con esto." + +#: ../admin/plugin-action-meta-links.php:30 +msgid "Get Support" +msgstr "Obtener soporte" + +#: ../admin/plugin-action-meta-links.php:31 +msgid "Donate to author" +msgstr "Donar al autor" + +#: ../admin/svgs-settings-page.php:4 +msgid "SVG Support Settings and Usage" +msgstr "SVG Support Configuración y Uso" + +#: ../admin/svgs-settings-page.php:12 +msgid "Introduction" +msgstr "Introducción" + +#: ../admin/svgs-settings-page.php:15 +msgid "" +"When using SVG images on your WordPress site, it can be hard to style " +"elements within the SVG using CSS. Now you can, easily!" +msgstr "" +"Al usar imágenes SVG en un sitio de WordPress es complicado darle formato a " +"los elementos SVG usando CSS. ¡Ahora esto es sencillo!" + +#: ../admin/svgs-settings-page.php:16 +msgid "" +"This plugin not only provides SVG Support like the name says, it also allows " +"you to easily embed your full SVG file's code using a simple IMG tag. By " +"adding the class style-svg to your IMG elements, this plugin " +"dynamically replaces any IMG elements containing the style-svg " +"class with your complete SVG." +msgstr "" +"Este plugin no solo da soporte SVG como su nombre indica, sino que además " +"permite insertar el código completo SVG utilizando una simple etiqueta IMG. " +"Añadiendo la clase style-svg a los elementos IMG este plugin " +"los reemplaza de forma dinámica con los SVG completos." + +#: ../admin/svgs-settings-page.php:17 +msgid "" +"The main purpose of this is to allow styling of SVG elements. Usually your " +"styling options are restricted when using embed, " +"object or img tags alone." +msgstr "" +"El objetivo principal es permitir darle formato a los elementos SVG. " +"Normalmente las opciones de formato están restringidas al usar solo las " +"etiquetas embed, object o img." + +#: ../admin/svgs-settings-page.php:34 +msgid "Settings" +msgstr "Configuración" + +#: ../admin/svgs-settings-page.php:46 +msgid "Restrict to Administrators" +msgstr "Restringir a los administradores" + +#: ../admin/svgs-settings-page.php:51 ../admin/svgs-settings-page.php:62 .. +#: admin/svgs-settings-page.php:73 +msgid "Yes" +msgstr "Si" + +#: ../admin/svgs-settings-page.php:51 +msgid " Restricts SVG upload priveledges to Administrators." +msgstr " Restringe la subida de archivos SVG a los administradores." + +#: ../admin/svgs-settings-page.php:78 +msgid "CSS Class to target" +msgstr "Clase CSS objetivo" + +#: ../admin/svgs-settings-page.php:81 +msgid "" +"The default target class is style-svg. You can change it to " +"your own class such as my-class by typing it here.
            Leave " +"blank to use the default class." +msgstr "" +"La clase por defecto es style-svg. Puedes cambiarla por una " +"clase propia como my-class tecleándola aquí.
            Déjalo en " +"blanco para usar la clase por defecto." + +#: ../admin/svgs-settings-page.php:87 +msgid "Save Changes" +msgstr "Guardar cambios" + +#: ../admin/svgs-settings-page.php:98 +msgid "Usage" +msgstr "Uso" + +#: ../admin/svgs-settings-page.php:101 +msgid "You can simply upload SVG images to your media library like any other file." +msgstr "" +"Puedes subir fácilmente imágenes SVG a tu librería de medios como otros " +"formatos de archivo." + +#: ../admin/svgs-settings-page.php:102 +msgid "" +"Now, embed your SVG image like a standard image with the addition of adding " +"the class style-svg (or your custom class from above) to any " +"IMG tags that you want this plugin to swap out with your actual SVG code." +msgstr "" +"Ahora, incluye tu imagen SVG como una imágen estándar añadiendo la clase " +"style-svg (o tu clase propia definida arriba) a cualquier " +"etiqueta IMG que quieres que se cambie por el código SVG." + +#: ../admin/svgs-settings-page.php:103 +msgid "For example:" +msgstr "por ejemplo:" + +#: ../admin/svgs-settings-page.php:106 +msgid "or" +msgstr "o" + +#: ../admin/svgs-settings-page.php:109 +msgid "" +"The whole IMG tag element will now be dynamically replaced by the actual " +"code of your SVG, making the inner content targetable." +msgstr "" +"Toda la etiqueta IMG ahora se reemplaza de forma dinámica con el código del " +"SVG haciendo su contenido accesible." + +#: ../admin/svgs-settings-page.php:110 +msgid "This allows you to target elements within your SVG using CSS." +msgstr "Esto permite acceder a los elementos SVG usando CSS." + +#: ../admin/svgs-settings-page.php:134 +msgid "SVG Support for your media library" +msgstr "Soporte SVG para la librería de medios" + +#: ../admin/svgs-settings-page.php:135 +msgid "Style SVG elements directly using CSS" +msgstr "Dar formato a los elementos SVG usando CSS" + +#: ../admin/svgs-settings-page.php:136 +msgid "Restrict to Administrators only" +msgstr "Restringido para administradores" + +#: ../admin/svgs-settings-page.php:137 +msgid "Extremely Simple To Use" +msgstr "Muy fácil de usar" + +#: ../admin/svgs-settings-page.php:147 +msgid "You can read about this plugin in detail on" +msgstr "Puedes leer todo sobre el plugin en" + +#: ../admin/svgs-settings-page.php:147 +msgid "The WordPress Plugin Repository" +msgstr "El repositorio de plugins de WordPress" + +#: ../admin/svgs-settings-page.php:148 +msgid "Need help?" +msgstr "¿Necesitas ayuda?" + +#: ../admin/svgs-settings-page.php:148 +msgid "Visit Support" +msgstr "Visitar soporte" + +#: ../admin/svgs-settings-page.php:149 +msgid "Buy Benbodhi a Beer →" +msgstr "Comprar una cerveza para Benbodhi →" + +#: ../admin/svgs-settings-page.php:150 +msgid "from" +msgstr "de" diff --git a/html/wp-content/plugins/svg-support/languages/svgsupport-sr_RS.mo b/html/wp-content/plugins/svg-support/languages/svgsupport-sr_RS.mo new file mode 100644 index 0000000..8719ca0 Binary files /dev/null and b/html/wp-content/plugins/svg-support/languages/svgsupport-sr_RS.mo differ diff --git a/html/wp-content/plugins/svg-support/languages/svgsupport-sr_RS.po b/html/wp-content/plugins/svg-support/languages/svgsupport-sr_RS.po new file mode 100644 index 0000000..ffe02d0 --- /dev/null +++ b/html/wp-content/plugins/svg-support/languages/svgsupport-sr_RS.po @@ -0,0 +1,284 @@ +msgid "" +msgstr "" +"Project-Id-Version: SVG Support 2.2.3.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-05-16 20:19:06+00:00\n" +"PO-Revision-Date: Mon May 16 2016 13:54:09 GMT-0700 (PDT)\n" +"Last-Translator: root \n" +"Language-Team: Benbodhi \n" +"Language: Serbian\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10 >= 2 && " +"n%10<=4 &&(n%100<10||n%100 >= 20)? 1 : 2)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Loco - https://localise.biz/\n" +"X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;" +"__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;" +"_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;" +"esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;" +"esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n" +"X-Poedit-Basepath: ../\n" +"X-Textdomain-Support: yes\n" +"X-Poedit-SearchPath-0: .\n" +"X-Loco-Target-Locale: sr_RS" + +#. URI of the plugin +msgid "http://wordpress.org/plugins/svg-support" +msgstr "" + +#: ../admin/plugin-action-meta-links.php:32 +msgid "$25 Free Credit from GoWebben" +msgstr "" + +#: ../admin/svgs-settings-page.php:57 +msgid "Output JS in Footer?" +msgstr "" + +#: ../admin/svgs-settings-page.php:62 +msgid "" +" Normally, scripts are placed in head of the HTML document. If " +"this parameter is true, the script is placed before the closing " +"body tag. This requires the theme to have the " +"wp_footer() template tag in the appropriate place." +msgstr "" + +#: ../admin/svgs-settings-page.php:68 +msgid "Automatically insert class?" +msgstr "" + +#: ../admin/svgs-settings-page.php:73 +msgid "" +" Checking this will make sure that either the default class or the custom " +"one you set below is inserted into the style attributes of img " +"tags when you insert images. Additionally, it will remove all of the default " +"WordPress classes." +msgstr "" + +#: ../admin/svgs-settings-page.php:112 +msgid "Please Note:" +msgstr "" + +#: ../admin/svgs-settings-page.php:113 +msgid "" +"- You will need to set your own height and width in your CSS for SVG files " +"to display correctly." +msgstr "" + +#: ../admin/svgs-settings-page.php:114 +msgid "" +"- Your uploaded image needs to be an SVG file for this plugin to replace the " +"img tag with the inline SVG code. It will not create SVG files for you." +msgstr "" + +#: ../admin/svgs-settings-page.php:131 +msgid "Plugin Features" +msgstr "" + +#: ../admin/svgs-settings-page.php:145 +msgid "About The Plugin" +msgstr "" + +#: ../admin/svgs-settings-page.php:157 +msgid "GoWebben Hosting" +msgstr "" + +#: ../admin/svgs-settings-page.php:159 +msgid "Claim your FREE $25 credit from" +msgstr "" + +#: ../admin/svgs-settings-page.php:159 +msgid "" +"No catch, just free credit for using this plugin! It will be applied " +"automatically using the link provided, but in any case you can simply use " +"code: SVGSUPPORT during checkout." +msgstr "" + +msgid "SVG Support" +msgstr "SVG PodrÅ¡ka" + +msgid "" +"Allow SVG file uploads using the WordPress Media Library uploader plus " +"direct styling of SVG elements using CSS." +msgstr "" +"Aktivirajte uÄitavanje SVG datoteka uz pomoć WordPress Media Library " +"uploader-a i direktno stilizovanje SVG elemenata uz pomoć CSS-a." + +msgid "Benbodhi" +msgstr "Benbodhi" + +msgid "http://benbodhi.com" +msgstr "http://benbodhi.com" + +#: ../admin/admin-init.php:15 +msgid "SVG Support Options and Instructions" +msgstr "SVG opcije podrÅ¡ke i uputstva" + +#: ../admin/admin-init.php:29 +msgid "You can't play with this." +msgstr "Ne možete se igrati ovim." + +#: ../admin/plugin-action-meta-links.php:30 +msgid "Get Support" +msgstr "Obezbedite podrÅ¡ku" + +#: ../admin/plugin-action-meta-links.php:31 +msgid "Donate to author" +msgstr "Donirajte autoru" + +#: ../admin/svgs-settings-page.php:4 +msgid "SVG Support Settings and Usage" +msgstr "SVG postavke podrÅ¡ke i upotreba" + +#: ../admin/svgs-settings-page.php:12 +msgid "Introduction" +msgstr "Uvod" + +#: ../admin/svgs-settings-page.php:15 +msgid "" +"When using SVG images on your WordPress site, it can be hard to style " +"elements within the SVG using CSS. Now you can, easily!" +msgstr "" +"Kad koristite SVG slike na svom WordPress sajtu, može vam biti teÅ¡ko da " +"stilizujete elemente u SVG-u uz pomoć CSS-a. Sad to možete uraditi s " +"lakoćom!" + +#: ../admin/svgs-settings-page.php:16 +msgid "" +"This plugin not only provides SVG Support like the name says, it also allows " +"you to easily embed your full SVG file's code using a simple IMG tag. By " +"adding the class style-svg to your IMG elements, this plugin " +"dynamically replaces any IMG elements containing the style-svg " +"class with your complete SVG." +msgstr "" +"Ovaj plugin ne obezbeÄ‘uje samo SVG podrÅ¡ku, kao Å¡to mu ime kaže, već vam " +"omogućava i da s lakoćom ugradite svoj puni kod SVG datoteke uz pomoć " +"jednostavne IMG oznake. Dodavanjem klase style-svg svojim IMG " +"elementima, ovaj plugin dinamiÄki zamenjuje bilo koje IMG elemente koji " +"sadrže style-svgembed, " +"object or img tags alone." +msgstr "" +"Osnovna svrha ovoga je da omogući stilizovanje SVG elemenata. ObiÄno su " +"opcije stilizovanja ograniÄene ako koristite samo oznake: embed," +" object or img." + +#: ../admin/svgs-settings-page.php:34 +msgid "Settings" +msgstr "Postavke" + +#: ../admin/svgs-settings-page.php:46 +msgid "Restrict to Administrators" +msgstr "OgraniÄi administratorima" + +#: ../admin/svgs-settings-page.php:51 ../admin/svgs-settings-page.php:62 .. +#: admin/svgs-settings-page.php:73 +msgid "Yes" +msgstr "Da" + +#: ../admin/svgs-settings-page.php:51 +msgid " Restricts SVG upload priveledges to Administrators." +msgstr "OgraniÄava privilegije SVG uÄitavanja administratorima." + +#: ../admin/svgs-settings-page.php:78 +msgid "CSS Class to target" +msgstr "CSS meta za ciljanje" + +#: ../admin/svgs-settings-page.php:81 +msgid "" +"The default target class is style-svg. You can change it to " +"your own class such as my-class by typing it here.
            Leave " +"blank to use the default class." +msgstr "" +"Podrazumevana ciljna klasa je style-svg. Možete je promeniti u " +"svoju klasu, kao što je my-class tako što ćete je ukucati ovde." +"
            Ostavite prazno polje da biste koristili podrazumevanu klasu." + +#: ../admin/svgs-settings-page.php:87 +msgid "Save Changes" +msgstr "SaÄuvaj izmene" + +#: ../admin/svgs-settings-page.php:98 +msgid "Usage" +msgstr "Upotreba" + +#: ../admin/svgs-settings-page.php:101 +msgid "You can simply upload SVG images to your media library like any other file." +msgstr "" +"Jednostavno, možete uÄitati SVG slike u svoju biblioteku medija kao i bilo " +"koju drugu datoteku." + +#: ../admin/svgs-settings-page.php:102 +msgid "" +"Now, embed your SVG image like a standard image with the addition of adding " +"the class style-svg (or your custom class from above) to any " +"IMG tags that you want this plugin to swap out with your actual SVG code." +msgstr "" +"Sada ugradite svoju SVG sliku kao standardnu sliku uz dodatak klase " +"style-svg (ili svoje prilagoÄ‘ene navedene klase) u bilo koju od " +"IMG oznaka koju želite da ovaj plugin zameni vaÅ¡im pravim SVG kodom." + +#: ../admin/svgs-settings-page.php:103 +msgid "For example:" +msgstr "Na primer:" + +#: ../admin/svgs-settings-page.php:106 +msgid "or" +msgstr "ili" + +#: ../admin/svgs-settings-page.php:109 +msgid "" +"The whole IMG tag element will now be dynamically replaced by the actual " +"code of your SVG, making the inner content targetable." +msgstr "" +"Sada će ceo IMG element oznake biti dinamiÄki zamenjen pravim kodom ili " +"vaÅ¡im SVG-om, Å¡to znaÄi da će unutraÅ¡nji sadržaj biti raspoloživ za ciljanje." + +#: ../admin/svgs-settings-page.php:110 +msgid "This allows you to target elements within your SVG using CSS." +msgstr "Omogućava vam da ciljate elemente u svom SVG-u koristeći CSS." + +#: ../admin/svgs-settings-page.php:134 +msgid "SVG Support for your media library" +msgstr "SVG podrÅ¡ka za vaÅ¡e biblioteke medija" + +#: ../admin/svgs-settings-page.php:135 +msgid "Style SVG elements directly using CSS" +msgstr "Stilizuj SVG elemente direktno koristeći CSS" + +#: ../admin/svgs-settings-page.php:136 +msgid "Restrict to Administrators only" +msgstr "OgraniÄi samo za administratore" + +#: ../admin/svgs-settings-page.php:137 +msgid "Extremely Simple To Use" +msgstr "Izuzetno jednostavan za upotrebu" + +#: ../admin/svgs-settings-page.php:147 +msgid "You can read about this plugin in detail on" +msgstr "O ovom plugin-u detaljnije možete proÄitati na:" + +#: ../admin/svgs-settings-page.php:147 +msgid "The WordPress Plugin Repository" +msgstr "WordPress Plugin Repository" + +#: ../admin/svgs-settings-page.php:148 +msgid "Need help?" +msgstr "Potrebna vam je pomoć?" + +#: ../admin/svgs-settings-page.php:148 +msgid "Visit Support" +msgstr "Posetite podrÅ¡ku" + +#: ../admin/svgs-settings-page.php:149 +msgid "Buy Benbodhi a Beer →" +msgstr "Kupite Benbodhi-ju pivo →" + +#: ../admin/svgs-settings-page.php:150 +msgid "from" +msgstr "od" diff --git a/html/wp-content/plugins/svg-support/languages/svgsupport.pot b/html/wp-content/plugins/svg-support/languages/svgsupport.pot new file mode 100644 index 0000000..f62fac5 --- /dev/null +++ b/html/wp-content/plugins/svg-support/languages/svgsupport.pot @@ -0,0 +1,266 @@ +# Loco Gettext template +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: SVG Support 2.2.3.1\n" +"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/svg-support\n" +"POT-Creation-Date: 2016-05-16 20:19:06+00:00\n" +"POT-Revision-Date: Mon May 16 2016 13:53:21 GMT-0700 (PDT)\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Benbodhi \n" +"Language-Team: Benbodhi \n" +"Language: \n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SearchPath-0: ..\n" +"X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;" +"__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;" +"_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;" +"esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;" +"esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n" +"X-Generator: Loco - https://localise.biz/" + +#. #-#-#-#-# plugin.pot (SVG Support 2.2.3.1) #-#-#-#-# +#. Plugin Name of the plugin/theme +msgid "SVG Support" +msgstr "" + +#. URI of the plugin +msgid "http://wordpress.org/plugins/svg-support" +msgstr "" + +#. Description of the plugin/theme +msgid "" +"Allow SVG file uploads using the WordPress Media Library uploader plus " +"direct styling of SVG elements using CSS." +msgstr "" + +#. Author of the plugin/theme +msgid "Benbodhi" +msgstr "" + +#. Author URI of the plugin/theme +msgid "http://benbodhi.com" +msgstr "" + +#: ../admin/admin-init.php:15 +msgid "SVG Support Options and Instructions" +msgstr "" + +#: ../admin/admin-init.php:29 +msgid "You can't play with this." +msgstr "" + +#: ../admin/plugin-action-meta-links.php:30 +msgid "Get Support" +msgstr "" + +#: ../admin/plugin-action-meta-links.php:31 +msgid "Donate to author" +msgstr "" + +#: ../admin/plugin-action-meta-links.php:32 +msgid "$25 Free Credit from GoWebben" +msgstr "" + +#: ../admin/svgs-settings-page.php:4 +msgid "SVG Support Settings and Usage" +msgstr "" + +#: ../admin/svgs-settings-page.php:12 +msgid "Introduction" +msgstr "" + +#: ../admin/svgs-settings-page.php:15 +msgid "" +"When using SVG images on your WordPress site, it can be hard to style " +"elements within the SVG using CSS. Now you can, easily!" +msgstr "" + +#: ../admin/svgs-settings-page.php:16 +msgid "" +"This plugin not only provides SVG Support like the name says, it also allows " +"you to easily embed your full SVG file's code using a simple IMG tag. By " +"adding the class style-svg to your IMG elements, this plugin " +"dynamically replaces any IMG elements containing the style-svg " +"class with your complete SVG." +msgstr "" + +#: ../admin/svgs-settings-page.php:17 +msgid "" +"The main purpose of this is to allow styling of SVG elements. Usually your " +"styling options are restricted when using embed, " +"object or img tags alone." +msgstr "" + +#: ../admin/svgs-settings-page.php:34 +msgid "Settings" +msgstr "" + +#: ../admin/svgs-settings-page.php:46 +msgid "Restrict to Administrators" +msgstr "" + +#: ../admin/svgs-settings-page.php:51 ../admin/svgs-settings-page.php:62 .. +#: /admin/svgs-settings-page.php:73 +msgid "Yes" +msgstr "" + +#: ../admin/svgs-settings-page.php:51 +msgid " Restricts SVG upload priveledges to Administrators." +msgstr "" + +#: ../admin/svgs-settings-page.php:57 +msgid "Output JS in Footer?" +msgstr "" + +#: ../admin/svgs-settings-page.php:62 +msgid "" +" Normally, scripts are placed in head of the HTML document. If " +"this parameter is true, the script is placed before the closing " +"body tag. This requires the theme to have the " +"wp_footer() template tag in the appropriate place." +msgstr "" + +#: ../admin/svgs-settings-page.php:68 +msgid "Automatically insert class?" +msgstr "" + +#: ../admin/svgs-settings-page.php:73 +msgid "" +" Checking this will make sure that either the default class or the custom " +"one you set below is inserted into the style attributes of img " +"tags when you insert images. Additionally, it will remove all of the default " +"WordPress classes." +msgstr "" + +#: ../admin/svgs-settings-page.php:78 +msgid "CSS Class to target" +msgstr "" + +#: ../admin/svgs-settings-page.php:81 +msgid "" +"The default target class is style-svg. You can change it to " +"your own class such as my-class by typing it here.
            Leave " +"blank to use the default class." +msgstr "" + +#: ../admin/svgs-settings-page.php:87 +msgid "Save Changes" +msgstr "" + +#: ../admin/svgs-settings-page.php:98 +msgid "Usage" +msgstr "" + +#: ../admin/svgs-settings-page.php:101 +msgid "You can simply upload SVG images to your media library like any other file." +msgstr "" + +#: ../admin/svgs-settings-page.php:102 +msgid "" +"Now, embed your SVG image like a standard image with the addition of adding " +"the class style-svg (or your custom class from above) to any " +"IMG tags that you want this plugin to swap out with your actual SVG code." +msgstr "" + +#: ../admin/svgs-settings-page.php:103 +msgid "For example:" +msgstr "" + +#: ../admin/svgs-settings-page.php:106 +msgid "or" +msgstr "" + +#: ../admin/svgs-settings-page.php:109 +msgid "" +"The whole IMG tag element will now be dynamically replaced by the actual " +"code of your SVG, making the inner content targetable." +msgstr "" + +#: ../admin/svgs-settings-page.php:110 +msgid "This allows you to target elements within your SVG using CSS." +msgstr "" + +#: ../admin/svgs-settings-page.php:112 +msgid "Please Note:" +msgstr "" + +#: ../admin/svgs-settings-page.php:113 +msgid "" +"- You will need to set your own height and width in your CSS for SVG files " +"to display correctly." +msgstr "" + +#: ../admin/svgs-settings-page.php:114 +msgid "" +"- Your uploaded image needs to be an SVG file for this plugin to replace the " +"img tag with the inline SVG code. It will not create SVG files for you." +msgstr "" + +#: ../admin/svgs-settings-page.php:131 +msgid "Plugin Features" +msgstr "" + +#: ../admin/svgs-settings-page.php:134 +msgid "SVG Support for your media library" +msgstr "" + +#: ../admin/svgs-settings-page.php:135 +msgid "Style SVG elements directly using CSS" +msgstr "" + +#: ../admin/svgs-settings-page.php:136 +msgid "Restrict to Administrators only" +msgstr "" + +#: ../admin/svgs-settings-page.php:137 +msgid "Extremely Simple To Use" +msgstr "" + +#: ../admin/svgs-settings-page.php:145 +msgid "About The Plugin" +msgstr "" + +#: ../admin/svgs-settings-page.php:147 +msgid "You can read about this plugin in detail on" +msgstr "" + +#: ../admin/svgs-settings-page.php:147 +msgid "The WordPress Plugin Repository" +msgstr "" + +#: ../admin/svgs-settings-page.php:148 +msgid "Need help?" +msgstr "" + +#: ../admin/svgs-settings-page.php:148 +msgid "Visit Support" +msgstr "" + +#: ../admin/svgs-settings-page.php:149 +msgid "Buy Benbodhi a Beer →" +msgstr "" + +#: ../admin/svgs-settings-page.php:150 +msgid "from" +msgstr "" + +#: ../admin/svgs-settings-page.php:157 +msgid "GoWebben Hosting" +msgstr "" + +#: ../admin/svgs-settings-page.php:159 +msgid "Claim your FREE $25 credit from" +msgstr "" + +#: ../admin/svgs-settings-page.php:159 +msgid "" +"No catch, just free credit for using this plugin! It will be applied " +"automatically using the link provided, but in any case you can simply use " +"code: SVGSUPPORT during checkout." +msgstr "" diff --git a/html/wp-content/plugins/svg-support/readme.txt b/html/wp-content/plugins/svg-support/readme.txt new file mode 100644 index 0000000..ddd8401 --- /dev/null +++ b/html/wp-content/plugins/svg-support/readme.txt @@ -0,0 +1,675 @@ +=== SVG Support === +Contributors: Benbodhi +Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Z9R7JERS82EQQ +Tags: svg, vector, safe svg, sanitization, mime type +Requires at least: 5.8 +Tested up to: 6.7.3 +Requires PHP: 7.4 +Stable tag: 2.5.14 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Securely upload SVG files to your media library, with built-in sanitization and advanced features for styling and animation. + +== Description == + +**The complete SVG solution for WordPress - secure, flexible, and easy to use.** + +SVG Support enables secure SVG uploads with powerful features for both basic users and developers: + +✨ **Key Features**: +- Secure SVG uploads with automatic sanitization +- Inline rendering for direct CSS/JS manipulation +- File size optimization through minification +- Role-based access control +- Advanced developer options +- Multisite compatible +- Full Block Editor (Gutenberg) compatibility + +🔒 **Security First**: +- Built-in sanitization removes potentially harmful code +- Role-based upload restrictions +- Comprehensive MIME type validation + +🎨 **Designer Friendly**: +- Direct styling of SVG elements +- Animation support +- Custom class targeting +- Automatic dimension handling + +💻 **Developer Ready**: +- Advanced mode for additional features +- REST API support +- Gutenberg compatible +- Extensive hooks and filters + + +== Usage == + +**Basic Usage**: +- First, install and activate SVG Support via your WordPress dashboard +- Upload SVG files to your media library like any other image +- Works seamlessly with Image blocks, Cover blocks and featured images + +**Advanced Usage**: +- Enable "Advanced Mode" for minification and inline rendering +- Customize with hooks and filters for tailored functionality + +**Block Editor Usage**: +- Use Advanced Mode to enable inline rendering: + - Add the `"style-svg"` class to Image blocks + - Add the `"style-svg"` class to Cover blocks to render SVG backgrounds inline +- Use "Skip Nested SVGs" setting to control inline rendering of SVGs within Cover blocks + +**Classic Editor Usage**: +- Use Advanced Mode to add the `"style-svg"` class to `` tags for inline rendering +- Enable "Auto Insert Class" option for automatic class insertion in Classic Editor + +**Common Issues & Solutions**: +- SVG not displaying? Ensure dimensions are set in CSS. +- Need help? Use the support tab and I will do my best to assist you. + + +== Spin up a test site == + +With a single click, you can spin up a completely free test site to test SVG Support using TasteWP! No sign up, no cards, nothing! How cool is that? Give it a go: +[Click Here to spin up a test site in seconds](https://tastewp.com/new?pre-installed-plugin-slug=svg-support&redirect=options-general.php%3Fpage%3Dsvg-support&ni=true) + + +== Security == + +SVG Support prioritizes security with automatic sanitization and role-based restrictions. Only trusted users should have upload permissions. Configure settings to balance functionality and security. + + +== Feedback == + +I'm open to your [suggestions and feedback](mailto:wp@benbodhi.com) - Thanks for using SVG Support! + +Follow [@SVGSupport](https://twitter.com/svgsupport) on Twitter +Follow [@benbodhi](https://twitter.com/benbodhi) on Twitter +Follow [@benbodhi](https://warpcast.com/benbodhi) on Warpcast + +*Note:* I hope you like this plugin! Please take a moment to [rate it](https://wordpress.org/support/view/plugin-reviews/svg-support?filter=5#postform). + + +== Development & Contributing == + +The development version of SVG Support is maintained on GitHub. Feel free to contribute: + +* Submit bug reports or feature suggestions: [GitHub Issues](https://github.com/benbodhi/svg-support/issues) +* Contribute code via [Pull Requests](https://github.com/benbodhi/svg-support/pulls) +* Development repository: [GitHub](https://github.com/benbodhi/svg-support) + + +== Translations == + +Contribute translations [here](https://translate.wordpress.org/projects/wp-plugins/svg-support). New to translating? Check the [Translator Handbook](https://make.wordpress.org/polyglots/handbook/tools/glotpress-translate-wordpress-org/). + + +== Frequently Asked Questions == + += SVG not rendering inline since 2.3 update = +Ensure "Advanced Mode" is enabled in Settings > SVG Support. + += How do I disable the Javascript on the front end if I am not using inline SVG? = +Disable "Advanced Mode" in the settings. + += I'm trying to use SVG in the customizer but it's not working. = +To allow SVG to work in the customizer, you will need to modify/add some code in your child theme's function file. [Here is a great tutorial](https://thebrandid.com/using-svg-logos-wordpress-customizer/) on how to do that. The important part is: +` +'flex-width' => true +'flex-height' => true +` + += How do I add animation to my SVG? = +You will need to edit your SVG file in a code editor so you can add CSS classes to each element you need to target within the SVG. Make sure that your IMG tag is being swapped out for your inline SVG and then you can use CSS or JS to apply animations to elements within your SVG file. + += Why is SVG Support not working in multisite? = +If you installed multisite prior to WordPress 3.5, then you will need to remove your ms-files. Here is a couple of resources to help you: [Dumping ms-files](http://halfelf.org/2012/dumping-ms-files/) [Removing ms-files after 3.5](https://www.yunomie.com/2298/removing-ms-files-php-after-upgrading-an-existing-multisite-installation-to-3-5/). + += Why is my SVG not working in Visual Composer? = +If you are using SVG Support with Visual Composer or any other page builders, you will need to make sure that you can add your own class to the image. The easiest way to do this is by using a simple text or code block in the builder to put your image code in to. Additionally, there is now a setting to force all SVG files to be rendered inline. + += How do I get this to work with the Media Library Assistant plugin? = +You need to add the mime type for svg and svgz to: "MLA Settings > Media Library Assistant > Uploads (tab)" and then it works. + + +== Screenshots == + +1. Basic Settings +2. Advanced Settings +3. Featured Image checkbox to render SVG inline +4. SVG used in WP native Image Widget +5. Inline SVG in the front end markup +6. Help tab - Overview +7. Help tab - The Settings +8. Help tab - Standard Usage +9. Help tab - Render SVG Inline (advanced usage) +91. Help tab - Featured Images +92. Help tab - Animation + + +== Changelog == + += 2.5.14 = +* **Security Enhancements**: + - Remove default roles from the sanitizer bypass settings + +* **Fixes**: + - More comprehensive upload checks, allowing generator tags and comment patterns + +* **Performance Improvements**: + - Cleanup duplicate inline_featured_image meta entries more efficiently + - Remove inline_featured_image meta entries that aren't explicitly set to 1 (enabled) + - Don't store inline_featured_image meta for posts that previously had it enabled but don't anymore + +* **General Updates**: + - Restructured settings layout + - Better cleanup on uninstall when delete plugin data is selected + += 2.5.13 = +* **Code Improvements**: + - Better PHP 8.3 compatibility - added null checks to prevent deprecated warnings in PHP 8.3 + += 2.5.12 = +* **General Updates**: + - Added blueprint.json for the live preview feature on wordpress.org + +* **Fixes**: + - Fixed mime type check that was restricting SVG uploads without the XML tag in PHP 7.4 + += 2.5.11 = +* **Security Enhancement** + - Added more effective handling of sanitization for REST API uploads + += 2.5.10 = +* **Fixes**: + - Fixed issue with upload checks preventing plugin uploads + += 2.5.9 = +* **New Features**: + - Added new Advanced Mode setting "Skip Nested SVGs" to control inlining of SVGs within containers (for example: nested SVGs in Gutenberg Cover blocks) + - Added proper multisite support for SVG uploads across subsites + - Added network administrator support for SVG uploads on all subsites + +* **Security Enhancements**: + - Updated DOMPurify library to version 2.5.8 + - Updated enshrined/svg-sanitize to version 0.21.0 + - Added nonce verification for non-REST uploads to prevent CSRF attacks + - Improved MIME type validation for SVG files + - Enhanced file content validation to ensure only valid SVG files are processed + - Moved security checks earlier in the upload process for better efficiency + - Updated and improved sanitization options for both frontend and admin + +* **Code Improvements**: + - Changed synchronous XMLHttpRequest to asynchronous in vanilla JS version to improve performance and remove Chrome deprecation warnings + - Removed console logging statements from JavaScript files for cleaner browser console + - Reorganized upload validation flow for better performance + - Added proper error messages for failed security checks + - Improved handling of REST API uploads + - Enhanced code documentation and inline comments + - Added proper plugin asset handling and alt text for admin images + - Enhanced multisite compatibility with proper role and capability checks + - Added network-level upload permission validation + - Added AJAX hooks for featured image inline toggle + - Enqueue minified Gutenberg filters script instead of expanded version + - Added better version update handling + +* **Fixes**: + - PHP Warning about undefined array key "css_target" in admin init.php + - Fixed "not allowed to upload this file type" error on multisite installations + - Fixed duplicate meta entries for inline featured images preventing post saves + - Added automatic cleanup of duplicate meta entries during plugin update + - Improved handling of featured image meta to prevent duplicate entries + - Updated and refactored Gutenberg featured image checkbox to use modern React hooks instead of deprecated withState + - Fixed missing file path in SVG attachment metadata causing issues with WPML Media Translation + - Fixed jQuery dependency only being required when not using vanilla JS option + +* **General Updates**: + - Updated security documentation + - Refined error messaging for better user experience + += 2.5.8 = +* **Security Enhancements**: + - Improved sanitization of SVG uploads and attachments for enhanced security. + - Ensured all output in the admin settings page is properly escaped. + - Replaced direct file handling functions with WordPress APIs for better security and compatibility. + - Improved translation support with added translators' comments and ordered placeholders. + +* **Admin Interface Improvements**: + - Updated admin-init.php with better escaping practices and enhanced security for the settings page. + - Added error logging to SVG processing to assist with debugging without disrupting the user experience. + +* **Performance and Compatibility**: + - Updated enqueue functions to ensure scripts and styles are loaded efficiently with proper dependencies. + - Improved metadata handling for SVGs to prevent issues in the Media Library and with ACF integration. + - Optimized nonce verification and meta updates in the featured image functions to prevent unnecessary database writes. + +* **General Code Improvements**: + - Refactored code to reduce redundancy and improve maintainability. + - Added detailed inline documentation for better code clarity and future development. + +* **Experimental Integration with WP All Import**: + - Introduced integration with WP All Import for experimental SVG handling during imports. + - SVG files imported via WP All Import are sanitized, and their metadata is generated and updated correctly. + - Added error logging to track issues during SVG import processing. + - **Note**: This feature is experimental and commented out in the main plugin file for now. Feel free to uncomment the include lines to test it out, but please ensure you back up your data first. + += 2.5.7 = +* Compatibility with newer versions of php. + += 2.5.6 = +* Addressed some security concerns. + += 2.5.5 = +* More error fixes and general clean up. + += 2.5.4 = +* Fixed errors. + += 2.5.3 = +* Fixed fatal php error. + += 2.5.2 = +* Added some defaults for better security by default. + += 2.5.1 = +* Added missing quotes in uninstall.php. + += 2.5 = +* Cleaned up spelling mistakes and general formatting. +* Addressed security concern. +* Added more sanitization options - frontend and admin both supported. +* Added support for SVG minification. +* Added ability to choose jQuery or vanilla JS. +* Added DB cleanup on uninstall. +* Fixed dimensions fallback. + += 2.4.2 = +* Fixed srcset warning for some premium themes. +* Fixed original IMG IDs not getting preserved on replacement. +* Removed some rogue text from featured image box. + += 2.4.1 = +* Fixed issue causing WP-CLI to break. + += 2.4 = +* NEW FEATURE: Added optional SVG sanitization. +* NEW FEATURE: Added optional SVG minification. +* Added inline SVG checkbox to Gutenberg featured image. +* Better Gutenberg support in general. +* Modified class targeting to allow inline rendering of nested SVGs (any level deep) when you can't set the IMG class directly. +* Modified JS to use vanilla JS instead of jQuery. +* Fixed accessibility issues on settings page. +* Fixed dimensions metadata issue. +* Fixed division by 0 issue when SVG had no width or height set. +* Fixed featured image spacing issue in both classic and block editor. +* Bumped required PHP version. +* Removed obsolete admin notice. +* Removed srcset for SVG files. +* Removed directory name from filepath metadata. + += 2.3.21 = +* Fixed featured image SVG overlapping container. + += 2.3.20 = +* Fixed admin setting not being escaped when output. + += 2.3.19 = +* Fixed PHP Warning from localize_script in functions/enqueue.php. +* Added a check for SRC attribute in js/svgs-inline.js. + += 2.3.18 = +* Updated author URL in main plugin file. +* Updated donate links. +* Cleaned up plugin action meta links and settings page. +* Rolled back a fix in functions/attachment.php due to it removing meta from other attachments. + += 2.3.17 = +* Added setting to choose whether to load frontend CSS or not. + += 2.3.16 = +* Fix for files that have the XML declaration. +* Fix for PHP warnings from image widget. +* Some small CSS changes to the frontend when displaying SVG media attachments. + += 2.3.15 = +* Had to roll back a recent PHP warnings fix due to it breaking some theme compatibility. + += 2.3.14 = +* Fixed: Fatal error in some cases when removing old option from the database. + += 2.3.13 = +* Fixed: PHP warnings and notices from the image widget when using SVG files and wp_debug was on. +* Modified: Better front end CSS for displaying SVG attachments, both as images and inline. +* Removed: DB entry for deprecated admin notice. + += 2.3.12 = +* New: Native "Help" tab on the SVG Support settings page. +* New: Wrapped the inline JS in a function so you can call it at will using `bodhisvgsInlineSupport();`. +* Modified: Admin CSS to target SVG src only. +* Modified: SVG Support settings page - cleaned it up a little. +* Removed: Version update admin notice. + += 2.3.11 = +* New: Feature to use expanded JS file rather than the minified/compressed version (useful for bundling and minifying using external caching plugins). +* New: Force Inline SVG option. This feature allows you to force all of your SVG files to be rendered inline regardless of classes applied. Addresses issues where you can't add your own class to an image for some reason. For example, some page builder image elements. Also addresses changing your target class in the settings and needing to change all of your already embedded media, allowing you to simply force render rather than update all of the classes. +* Modified the readme file and descriptions a bit. +* Refined some code in functions/featured-image.php line 69 to address a warning. +* Updated "Requires at least" tag to 4.8 (though it should still work in older versions, there was issues with core during the 4.7 phase and it's time for you to update anyway). + += 2.3.10 = +* Fixed missing links in settings page. + += 2.3.9 = +* Modified plugin action meta link for settings page. +* Changed some language throughout the plugin. +* Added recommendation for ShortPixel Image Optimization. +* Added conditional to check post type supports thumbnail before setting meta data. + += 2.3.8 = +* Added some CSS to make sure featured images show on WooCommerce products, Sensei Courses and Lessons. +* Fix: Auto insert class setting was stripping featured image HTML in some cases. + += 2.3.7 = +* Added WP version check to wrap mime fix function needed for WP v4.7.1 - v4.7.2. +* Moved mime fix into mime type file. +* Modified admin notice code to make it neater. +* Fix: attachment-modal.php issues with some servers and external SVG files (props to @abstractourist & @malthejorgensen for providing fixes, as I could not consistently reproduce the issue). +* Compatibility: Changed a line to provide wider compatibility, specifically for WordPress Bedrock on a LEMP stack. +* Compatibility: Added another snippet to the JS to support IE11 (apparently people still use IE). +* Added more FAQ's. + += 2.3.6 = +* New: Added polyfill to make svgs-inline.js work with older browsers. +* New: Section to leave reviews on settings page. +* Removed: Redundant one time upgrade activate code. +* Fix: Errors reported on activation and on the settings page - [Related Support Thread](https://wordpress.org/support/topic/error-on-plugin-settings-page/). + += 2.3.5 = +* Revision and modification of the thumbnail display code. + += 2.3.4 = +* Fix: Fatal error for some because a function wasn't prefixed. + += 2.3.3 = +* Fix: Missing arguments PHP warnings from new attribute control file. +* Update settings page text. + += 2.3.2 = +* Modified the attribute control code that auto inserts our class to only apply to SVG files. + += 2.3.1 = +* Fix: Fatal error in some cases due to admin notice. + += 2.3 = +* New Feature - Advanced Mode: allows you to turn off the advanced features and simply upload SVG files like normal images. This addition also enables users to turn off the script added on front end by leaving Advanced Mode unchecked. +* New Feature - Featured Image Support: If your featured image is SVG, once the post is saved you will see a checkbox to render the SVG inline (advanced mode only). +* Performance - Stop inlining JS from running if image source is not SVG. +* Added new stylesheet for settings page. +* Moved SCSS files to their own folder. +* Changed donate link so I can track it and properly thank you for your generous donations. +* Added a rating link to the settings and media pages. +* Cleaned up code formatting, added more comments. +* Added a plugin version check. +* Added notice so people are aware they may need to turn on the advanced mode. + += 2.2.5 = +* FIX: Display SVG thumbnails in attachment modals. + += 2.2.4 = +* FIX: Added function to temporarily fix an issue with uploading in WP 4.7.1 + += 2.2.32 = +* Changed text domain to match plugin slug for localization. + += 2.2.31 = +* Attempt to fix ability to translate + += 2.2.3 = +* Modified code in svg-support/js/svg-inline.js and svg-support/js/min/svg-inline-min.js to allow JS control of the SVG elements and detect if they have been loaded (IMG tag swapped out). Thanks to [laurosello](https://wordpress.org/support/profile/laurosollero) for this suggestion and code contribution. +* Fixed SVG thumbnails not displaying correctly in list view of the media library. +* Cleaned up the code and comments a bit. +* Added translation for Spanish. Thanks to [Apasionados del Marketing](http://apasionados.es) for the translation. + += 2.2.2 = +* Changed another anonymous function in svg-support/functions/thumbnail-display.php that was causing errors for some. + += 2.2.1 = +* Changed anonymous function in svg-support/functions/thumbnail-display.php line 15 to prevent fatal error in older PHP versions. + += 2.2 = +* Added support to make SVG thumbnails visible in all media library screens. +* Added SVGZ to the mime types. +* Automatically removes the width and height attributes when inserting SVG files. +* Added ability to choose whether the target class is automatically inserted into img tags or not, stripping the default WordPress classes. +* Added ability to choose whether script is output in footer - true or false. +* Blocked direct access to PHP files. +* Added SCSS support using CodeKit - minified CSS + JS files. +* Updated spelling for incorrect function name. +* Changed comment formatting across all files for consistency. +* Added link to $25 Free credit at GoWebben on the settings page. +* Tested in WordPress 4.3. +* Updated Readme file. + += 2.1.7 = +* Tested in WordPress 4.0 and added plugin icons for the new interface. + += 2.1.6 = +* Added missing jQuery dependency in /functions/enqueue.php (pointed out by [walbach](http://wordpress.org/support/profile/waldbach)) - was loading SVG Support JS before jQuery. + += 2.1.5 = +* Added Serbian translation, submitted by Ogi Djuraskovic. + += 2.1.4 = +* Fixed plugin settings link (on plugins page) +* Added more links - Support & Donate +* Modified the settings page a little +* Cleaned up settings page with CSS +* Satisfied my OCD tendencies a little + += 2.1.3 = +* Added plugin_action_links file for custom menus on plugin page. + += 2.1.2 = +* Cleaned up trunk, tags and readme.txt to show correct changelog and update notice. + += 2.1.1 = +* Fixed JS file conditional - worked in local testing but not live. + += 2.1 = +* Updates to language files for localization. + += 2.0 = +* Added an admin settings page with instructions plus options for restricting to admin use only and setting a custom CSS target class. +* Whole plugin completely re-written and re-structured. +* Added option to restrict SVG uploads to administrators only. +* Added field for custom CSS target class. +* Added stylesheet to admin settings page. + += 1.0 = +* Initial Release. + + +== Upgrade Notice == + += 2.5.14 = +Better DB handling, better upload checks + += 2.5.13 = +Better PHP 8.3 compatibility (added null checks to prevent deprecated warnings in PHP 8.3) + += 2.5.12 = +Fixes mime type check that was restricting SVG uploads without the XML tag in PHP 7.4 + += 2.5.11 = +Security update: added more effective handling of sanitization for REST API uploads + += 2.5.10 = +Fixed issue with upload checks preventing plugin uploads + += 2.5.9 = +Important security update that adds enhanced upload validation, MIME type checking, and CSRF protection. Please backup before updating. No configuration changes required - all security improvements work automatically. + += 2.5.8 = +Improved security, enhanced SVG processing, and updated admin interface. Includes better sanitization and escaping practices. Please take a backup before updating! + += 2.5.7 = +This update addresses issues with newer PHP versions. + += 2.5.6 = +This update addresses some security concerns. + += 2.5.5 = +Updating to 2.5+ Adds new features and addresses a number of earlier issues raised. Please take a backup before updating! +2.5.5 fixes more reported errors in the 2.5 series of updates. + += 2.5.4 = +Updating to 2.5+ Adds new features and addresses a number of earlier issues raised. Please take a backup before updating! +2.5.4 fixes errors in the 2.5 series of updates. + += 2.5.3 = +Updating to 2.5+ Adds new features and addresses a number of earlier issues raised. Please take a backup before updating! +2.5.3 fixes fatal error in 2.5.2. + += 2.5.2 = +Updating to 2.5+ Adds new features and addresses a number of earlier issues raised. Please take a backup before updating! +2.5.2 introduces some defaults for better security. + += 2.5.1 = +2.5 Adds new features and addresses a number of recent issues raised. Please take a backup before updating! +2.5.1 fixes the uninstall file. + += 2.5 = +Adds new features and addresses a number of recent issues raised. Please take a backup before updating! + += 2.4.2 = +2.4.2 fixes srcset issue firing PHP warnings for some themes and original image IDs missing on replacement to inline SVG. + += 2.4.1 = +2.4.1 fixes broken WP-CLI. Now featuring optional SVG sanitization and ability to target nested SVGs! This update contains a lot, please BACKUP YOUR DATABASE AND FILES BEFORE UPDATING! + += 2.4 = +Now featuring optional SVG sanitization and ability to target nested SVGs! This update contains a lot, please BACKUP YOUR DATABASE AND FILES BEFORE UPDATING! + += 2.3.21 = +Fixes featured image display on edit post screen. + += 2.3.20 = +Added more security. + += 2.3.19 = +Quick update to address PHP warnings from localize_script and to add a SRC check. + += 2.3.18 = +General clean up of plugin, testing on latest nightly build plus fixed issue with metadata being removed from non SVG attachments. + += 2.3.17 = +Added a setting to choose whether to load the frontend CSS file or not. It was previously enabled by default, so you may want to flick that on after the update. This allows you to leave it out so your site has one less file to load :) + += 2.3.16 = +This update addresses upload issues, PHP warnings and some frontend CSS changes with attachment display. + += 2.3.15 = +Had to roll back a recent PHP warnings fix due to it breaking some theme compatibility. + += 2.3.14 = +Fixes fatal error in some cases when removing old option from the database. + += 2.3.13 = +Update to address PHP warnings and notices on the image widget when wp_debug is enabled. + += 2.3.12 = +* Inline JS can now be called using `bodhisvgsInlineSupport();`. Added a native help tab and removed the admin update notice. General cleanup of code and settings page. Remember to back up your site before updating. + += 2.3.11 = +* New Features and Fixes: Added "Force Inline SVG" to render all SVG files inline with one click. Option to use an expanded JS version for separate minification with a caching plugin. + += 2.3.10 = +* Fixed missing links in settings page. + += 2.3.9 = +* Cleaned up some code and language, now stores less meta when not needed and added a plugin recommendation for Image Optimization. + += 2.3.8 = +* Adds better support for WooCommerce and Sensei. Fixes issue with featured images not showing up when auto insert class setting is on. + += 2.3.7 = +* Fixes issues with media library not loading for some, attachment-modal errors and adds some wider compatibility. + += 2.3.6 = +* Adds support for older browsers, fixes a couple of seemingly isolated errors reported, removes some redundant code. + += 2.3.5 = +* Modifications to thumbnail display code to prevent output buffer clash with another plugin. + += 2.3.4 = +* Fixes fatal error for some because a function wasn't prefixed. + += 2.3.3 = +* This update fixes some PHP warnings introduced in 2.3.2 and also has updated settings page text. + += 2.3.2 = +* Changes to the way the auto class insert works. + += 2.3.1 = +* Fixes fatal error in some cases due to admin notice in V2.3. + += 2.3 = +IMPORTANT, MAJOR CHANGES, BACKUP BEFORE UPDATING: Users that are inlining SVG will need to make sure "Advanced Mode" is active under "Settings > SVG Support". Your settings should all still be there. Make sure you run a backup before updating just in case!!! + += 2.2.5 = +* Fix to display SVG thumbnails in attachment modals. (NOTE: You can not edit SVG files like other images in WordPress) + += 2.2.4 = +* IMPORTANT: Fixes upload ability in WP 4.7.1 + += 2.2.32 = +* Changed text domain to match plugin slug for localization. + += 2.2.31 = +* This release attempts to fix translation issues. + += 2.2.3 = +* Feature - Changed code to allow JS detection if SVG has loaded and ability to control SVG using JS. +* Fix - Thumbnail display in media library list view. +* Added Spanish translation and cleaned up code/comments a bit. + += 2.2.2 = +* Fix - Another change from anonymous function that was triggering errors for some. + += 2.2.1 = +* Minor change to remove anonymous function that triggered a fatal error in older PHP versions. + += 2.2 = +* Significant changes, added functionality, please BACKUP BEFORE UPDATING just in case. + += 2.1.7 = +* Tested in WordPress 4.0 and added plugin icons for the new interface. + += 2.1.6 = +* Important update! Added missing jQuery dependency in /functions/enqueue.php - was loading SVG Support JS before jQuery. + += 2.1.5 = +* Added Serbian translation, submitted by Ogi Djuraskovic. + += 2.1.4 = +* Some more re-arranging, added a few helpful links, updated language files, tended to my OCD a bit. + += 2.1.3 = +* Added a link on the plugins page to the plugin settings page for easy access after install. + += 2.1.2 = +* A little bit of house cleaning, updates to changelog and readme.txt for correct output with current version. + += 2.1.1 = +* Update to conditional in JS file. + += 2.1 = +* Updated language files for localization that were missed in version 2.0. + += 2.0 = +* SVG Support has been completely re-written and re-structured. It now includes an admin settings page with instructions, plus options for restricting to admin use only and setting a custom CSS target class. + += 1.0 = +* Initial Release. \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/scss/jquery.dropdown.scss b/html/wp-content/plugins/svg-support/scss/jquery.dropdown.scss new file mode 100644 index 0000000..2b0a3b1 --- /dev/null +++ b/html/wp-content/plugins/svg-support/scss/jquery.dropdown.scss @@ -0,0 +1,398 @@ +@-webkit-keyframes iui-fadeIn { + 0% { + opacity: 0 + } + 100% { + opacity: 1 + } +} + +@-moz-keyframes iui-fadeIn { + 0% { + opacity: 0 + } + 100% { + opacity: 1 + } +} + +@-ms-keyframes iui-fadeIn { + 0% { + opacity: 0 + } + 100% { + opacity: 1 + } +} + +@-o-keyframes iui-fadeIn { + 0% { + opacity: 0 + } + 100% { + opacity: 1 + } +} + +@keyframes iui-fadeIn { + 0% { + opacity: 0 + } + 100% { + opacity: 1 + } +} + +@-webkit-keyframes iui-fadeOut { + 0% { + opacity: 1 + } + 100% { + opacity: 0 + } +} + +@-moz-keyframes iui-fadeOut { + 0% { + opacity: 1 + } + 100% { + opacity: 0 + } +} + +@-ms-keyframes iui-fadeOut { + 0% { + opacity: 1 + } + 100% { + opacity: 0 + } +} + +@-o-keyframes iui-fadeOut { + 0% { + opacity: 1 + } + 100% { + opacity: 0 + } +} + +@keyframes iui-fadeOut { + 0% { + opacity: 1 + } + 100% { + opacity: 0 + } +} + +.dropdown-multiple, +.dropdown-multiple-label, +.dropdown-single { + position: relative +} + +.dropdown-multiple-label.active .dropdown-main, +.dropdown-multiple.active .dropdown-main, +.dropdown-single.active .dropdown-main { + display: block; + -webkit-animation: iui-fadeIn .2s ease-in forwards; + -moz-animation: iui-fadeIn .2s ease-in forwards; + -ms-animation: iui-fadeIn .2s ease-in forwards; + -o-animation: iui-fadeIn .2s ease-in forwards; + animation: iui-fadeIn .2s ease-in forwards +} + +.dropdown-multiple-label.active .dropdown-display-label:after, +.dropdown-multiple-label.active .dropdown-display:after, +.dropdown-multiple.active .dropdown-display-label:after, +.dropdown-multiple.active .dropdown-display:after, +.dropdown-single.active .dropdown-display-label:after, +.dropdown-single.active .dropdown-display:after { + border-top: none; + border-bottom: 10px solid #999; + border-left: 5px solid transparent; + border-right: 5px solid transparent +} + +.dropdown-multiple-label.active .dropdown-display, +.dropdown-multiple-label.active .dropdown-display-label, +.dropdown-multiple.active .dropdown-display, +.dropdown-multiple.active .dropdown-display-label, +.dropdown-single.active .dropdown-display, +.dropdown-single.active .dropdown-display-label { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0 +} + +.dropdown-display, +.dropdown-display-label { + position: relative; + display: block; + margin-bottom: 0; + font-size: 14px; + line-height: 1.42857143; + vertical-align: middle; + touch-action: manipulation; + cursor: pointer; + user-select: none; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + color: #333; + background-color: #fff +} + +.dropdown-display-label:after, +.dropdown-display:after { + content: ''; + position: absolute; + border-top: 10px solid #999; + border-left: 5px solid transparent; + border-right: 5px solid transparent; + top: 15px; + right: 8px +} + +.dropdown-clear-all { + background-color: #fff; + border: none; + font-size: 22px; + z-index: 999; + color: #999; + position: absolute; + right: 2px; + top: 2px; + display: none; + width: 25px; + height: 30px; + text-align: center; + line-height: 30px; +} + +.dropdown-clear-all:focus { + outline: 0 +} + +.dropdown-clear-all:hover { + color: #ccc; + text-decoration: none; +} + +.dropdown-display { + white-space: nowrap; + padding: 6px 20px 6px 12px +} + +.dropdown-multiple:hover .dropdown-clear-all, +.dropdown-single:hover .dropdown-clear-all { + display: block +} + +.dropdown-display .dropdown-chose-list { + display: inline-block; + vertical-align: middle; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap +} + +.dropdown-display .dropdown-chose-list span:before { + content: ',' +} + +.dropdown-display .dropdown-chose-list span:first-child:before { + content: '' +} + +.dropdown-display .placeholder { + display: none +} + +.dropdown-display .placeholder:first-child { + position: absolute; + height: 100%; + width: 100%; + top: 0; + left: 0; + color: #999; + display: block; + text-indent: 10px; + font-size: 13px; + line-height: 32px +} + +.dropdown-display input { + border: 0; + outline: 0 +} + +.dropdown-display-label { + cursor: text; + padding: 6px 25px 5px 0 +} + +.dropdown-display-label .dropdown-search { + display: block; + width: 100%; + border: 1px solid #eee; +} + +.dropdown-display-label .dropdown-search input { + width: 100%; +} + +.dropdown-option.dropdown-chose { + font-weight: bold; +} + +.dropdown-display-label input, +.dropdown-display-label input:focus { + border: none; + outline: 0 +} + +.dropdown-display-label .dropdown-chose-list { + width: 100%; + display: inline-block; + padding: 0 5px +} + +.dropdown-display-label .dropdown-chose-list .placeholder { + display: none +} + +.dropdown-display-label .dropdown-selected { + position: relative; + margin: 0 5px 5px 0; + padding: 0 20px 0 5px; + border: 1px solid #aaa; + max-width: 100%; + border-radius: 3px; + background-repeat: repeat-x; + color: #333; + cursor: default; + display: inline-block +} + +.dropdown-display-label .dropdown-selected .del { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: 0 0; + border: 0; + float: right; + line-height: 1; + color: #999; + position: absolute; + right: 3px; + top: 0 +} + +.dropdown-display-label .dropdown-selected .del:after { + content: '\D7'; + font-size: 16px +} + +.dropdown-main { + position: absolute; + top: 100%; + left: 0; + z-index: 1010; + width: 100%; + color: #444; + box-sizing: border-box; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 0 0 4px 4px; + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + margin-top: -1px; + border-top: 0; + padding: 4px 7px; + display: none +} + +.dropdown-main ul { + overflow-x: hidden; + overflow-y: auto; + max-height: 240px; + margin: 0; + padding: 0 +} + +.dropdown-main input { + margin-top: 0; + display: block; + box-sizing: border-box; + height: 30px; + border: 1px solid #ccc; + width: 100%; + text-indent: 5px; + border-radius: 3px +} + +.dropdown-main .dropdown-search { + display: block; + padding: 5px 0 +} + +.dropdown-group { + font-weight: 700 +} + +.dropdown-group, +.dropdown-option { + margin: 0; + padding-left: 12px; + list-style: none; + line-height: 26px; + word-wrap: break-word +} + +.dropdown-option { + cursor: pointer +} + +.dropdown-option:focus, +.dropdown-option:hover { + background-color: #efefef; + outline: 0 +} + +.dropdown-option[disabled] { + color: #ddd; + background-color: #fff; + cursor: not-allowed; + text-decoration: line-through +} + +.dropdown-option.dropdown-chose:after { + content: ''; + float: right; + width: 10px; + height: 10px; + background: #4AB1E9; + border-radius: 100%; + margin: 8px 5px 0 0 +} + +.dropdown-maxItem-alert, .dropdown-minItem-alert { + position: absolute; + top: 0; + left: 0; + background-color: #e4e3e2; + width: 100%; + height: 39px; + line-height: 39px; + padding: 0 5px; + border-radius: 5px; + color: #999; + -webkit-animation: iui-fadeIn .2s ease-in forwards; + -moz-animation: iui-fadeIn .2s ease-in forwards; + -ms-animation: iui-fadeIn .2s ease-in forwards; + -o-animation: iui-fadeIn .2s ease-in forwards; + animation: iui-fadeIn .2s ease-in forwards +} diff --git a/html/wp-content/plugins/svg-support/scss/svgs-admin-edit-post.scss b/html/wp-content/plugins/svg-support/scss/svgs-admin-edit-post.scss new file mode 100644 index 0000000..7927127 --- /dev/null +++ b/html/wp-content/plugins/svg-support/scss/svgs-admin-edit-post.scss @@ -0,0 +1,21 @@ +/** + * Featured Image Display + * + * Fixes the 0px featured image on edit screen + * WooCommerce Product, Sensei Course + */ +body #set-post-thumbnail, +body #postimagediv .inside img[src$=".svg"] { + width: 100%; +} + +// Block display of featured image SVG +body .block-editor__container { + .components-panel .editor-post-featured-image__container img[src$='.svg'] { + position: relative; + } + + .edit-post-sidebar .components-panel .components-checkbox-control { + margin-top: 10px; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/scss/svgs-admin-simple-mode.scss b/html/wp-content/plugins/svg-support/scss/svgs-admin-simple-mode.scss new file mode 100644 index 0000000..62c99bb --- /dev/null +++ b/html/wp-content/plugins/svg-support/scss/svgs-admin-simple-mode.scss @@ -0,0 +1,6 @@ +/** + * Hide advanced features + */ +.svgs-advanced { + display: none; +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/scss/svgs-admin.scss b/html/wp-content/plugins/svg-support/scss/svgs-admin.scss new file mode 100644 index 0000000..0455230 --- /dev/null +++ b/html/wp-content/plugins/svg-support/scss/svgs-admin.scss @@ -0,0 +1,45 @@ +/** + * Settings Page + */ +.svgs-version { + font-size: 10px; + margin-left: 7px; +} +.postbox .inside a { + text-decoration: none; +} +h3 { + padding: 0 12px; +} +.help-tab-content h3 { + padding: 0; +} +h3.inner-title { + padding: 0; + font-size: 1.2em; +} + +.metabox-holder { + .postbox>h3, + .stuffbox>h3, + h2.hndle, + h3.hndle { + font-size: 1.3em; + font-weight: 600; + } +} + +.shortpixel-logo img { + position: absolute; + right: 10px; + bottom: 0; + width: 140px; +} + +/** + * Media Library + */ +table.media .column-title .media-icon img { + width: 60px; + // height: 60px; +} diff --git a/html/wp-content/plugins/svg-support/scss/svgs-attachment.scss b/html/wp-content/plugins/svg-support/scss/svgs-attachment.scss new file mode 100644 index 0000000..ba5bbe9 --- /dev/null +++ b/html/wp-content/plugins/svg-support/scss/svgs-attachment.scss @@ -0,0 +1,17 @@ +// .attachment img[src$=".svg"], +// .widget_media_image img[src$=".svg"] { +// width: 100%; +// } + +.attachment, +.widget_media_image { + + // img[src$=".svg"] { + // width: 100%; + // } + + svg { + max-width: 100%; + height: auto; + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/svg-support/svg-support.php b/html/wp-content/plugins/svg-support/svg-support.php new file mode 100644 index 0000000..a16032f --- /dev/null +++ b/html/wp-content/plugins/svg-support/svg-support.php @@ -0,0 +1,152 @@ + 'Version'))['Version']); +define('BODHI_SVGS_PLUGIN_FILE', __FILE__); // define the absolute plugin file path +define('BODHI_SVGS_PLUGIN_PATH', plugin_dir_path(__FILE__)); // define the absolute plugin path for includes +define('BODHI_SVGS_PLUGIN_URL', plugin_dir_url(__FILE__)); // define the plugin url for use in enqueue +$bodhi_svgs_options = get_option('bodhi_svgs_settings', array()); // Retrieve our plugin settings + +// ensure $bodhi_svgs_options is always an array +if (!is_array($bodhi_svgs_options)) { + $bodhi_svgs_options = []; + update_option('bodhi_svgs_settings', $bodhi_svgs_options); +} + +/** + * SVG Sanitizer class + */ +// init svg sanitizer for usage +use enshrined\svgSanitize\Sanitizer; +// svg sanitizer +include( BODHI_SVGS_PLUGIN_PATH . 'vendor/autoload.php' ); +// interfaces to enable custom whitelisting of svg tags and attributes +include( BODHI_SVGS_PLUGIN_PATH . 'includes/svg-tags.php' ); +include( BODHI_SVGS_PLUGIN_PATH . 'includes/svg-attributes.php' ); +// initialize sanitizer +$sanitizer = new Sanitizer(); + +/** + * Includes - keeping it modular + */ +include( BODHI_SVGS_PLUGIN_PATH . 'admin/admin-init.php' ); // initialize admin menu & settings page +include( BODHI_SVGS_PLUGIN_PATH . 'admin/plugin-action-meta-links.php' ); // add links to the plugin on the plugins page +include( BODHI_SVGS_PLUGIN_PATH . 'functions/mime-types.php' ); // setup mime types support for SVG (with fix for WP 4.7.1 - 4.7.2) +include( BODHI_SVGS_PLUGIN_PATH . 'functions/thumbnail-display.php' ); // make SVG thumbnails display correctly in media library +include( BODHI_SVGS_PLUGIN_PATH . 'functions/attachment.php' ); // make SVG thumbnails display correctly in attachment modals and generate attachment sizes +include( BODHI_SVGS_PLUGIN_PATH . 'functions/enqueue.php' ); // enqueue js & css for inline replacement & admin +include( BODHI_SVGS_PLUGIN_PATH . 'functions/localization.php' ); // setup localization & languages +include( BODHI_SVGS_PLUGIN_PATH . 'functions/attribute-control.php' ); // auto set SVG class & remove dimensions during insertion +include( BODHI_SVGS_PLUGIN_PATH . 'functions/featured-image.php' ); // allow inline SVG for featured images +include( BODHI_SVGS_PLUGIN_PATH . 'functions/meta-cleanup.php' ); // cleanup duplicate meta entries + +// Include WP All Import integration only if WP All Import is active +// if ( defined( 'PMXI_VERSION' ) ) { +// include( BODHI_SVGS_PLUGIN_PATH . 'integrations/wp-all-import.php' ); +// } + +/** + * Handle version updates and migrations + * + * Handles version comparisons for all format types: + * - Single digit versions (1, 2) + * - Zero versions (0, 0.1, 0.5.26) + * - Two-digit versions (1.0, 2.1, 2.5) + * - Three-digit versions (1.5.17, 2.5.9) + * - Fresh installs ('0.0.0') + * - Legacy versions (null, empty, invalid) + */ +function bodhi_svgs_version_updates() { + $stored_version = get_option('bodhi_svgs_plugin_version', '0.0.0'); + + if (!is_string($stored_version) || empty($stored_version)) { + $stored_version = '0.0.0'; + } + + // Skip if already at current version + if ($stored_version === BODHI_SVGS_VERSION) { + return; + } + + // Store the old version for comparison + $old_version = $stored_version; + + // Update to current version + update_option('bodhi_svgs_plugin_version', BODHI_SVGS_VERSION); + + // If coming from before 2.5.14, run cleanup + if (version_compare($old_version, '2.5.14', '<')) { + require_once BODHI_SVGS_PLUGIN_PATH . 'functions/meta-cleanup.php'; + bodhi_svgs_cleanup_duplicate_meta(); + } +} +add_action('admin_init', 'bodhi_svgs_version_updates'); + +/** + * Defaults for better security in versions >= 2.5 + */ +// Enable 'sanitize_svg_front_end' by default +if ( !isset($bodhi_svgs_options['sanitize_svg_front_end']) ) { + $bodhi_svgs_options['sanitize_svg_front_end'] = 'on'; + update_option( 'bodhi_svgs_settings', $bodhi_svgs_options ); +} + +// Allow only admins to upload SVGs by default +if ( !isset($bodhi_svgs_options['restrict']) || $bodhi_svgs_options['restrict'] == "on" ) { + $bodhi_svgs_options['restrict'] = array('administrator'); + update_option( 'bodhi_svgs_settings', $bodhi_svgs_options ); +} +elseif (isset($bodhi_svgs_options['restrict']) && $bodhi_svgs_options['restrict'] == "none" ) { + $bodhi_svgs_options['restrict'] = array("none"); + update_option( 'bodhi_svgs_settings', $bodhi_svgs_options ); +} + +// By default sanitize on upload for everyone (no bypass roles) +if ( !isset($bodhi_svgs_options['sanitize_on_upload_roles']) ) { + $bodhi_svgs_options['sanitize_on_upload_roles'] = array(); + update_option( 'bodhi_svgs_settings', $bodhi_svgs_options ); +} +elseif ( isset($bodhi_svgs_options['sanitize_on_upload_roles']) && $bodhi_svgs_options['sanitize_on_upload_roles'] == "none") { + $bodhi_svgs_options['sanitize_on_upload_roles'] = array("none"); + update_option( 'bodhi_svgs_settings', $bodhi_svgs_options ); +} + +/** + * Register activation and deactivation hooks + */ +// Activation Hook +function bodhi_svgs_plugin_activation() { + bodhi_svgs_remove_old_sanitize_setting(); +} +register_activation_hook(__FILE__, 'bodhi_svgs_plugin_activation'); + +// Deactivation Hook +function bodhi_svgs_plugin_deactivation() { + bodhi_svgs_remove_old_sanitize_setting(); +} +register_deactivation_hook(__FILE__, 'bodhi_svgs_plugin_deactivation'); diff --git a/html/wp-content/plugins/svg-support/svg-support.png b/html/wp-content/plugins/svg-support/svg-support.png new file mode 100644 index 0000000..4c3efe1 Binary files /dev/null and b/html/wp-content/plugins/svg-support/svg-support.png differ diff --git a/html/wp-content/plugins/svg-support/uninstall.php b/html/wp-content/plugins/svg-support/uninstall.php new file mode 100644 index 0000000..6e3ec66 --- /dev/null +++ b/html/wp-content/plugins/svg-support/uninstall.php @@ -0,0 +1,15 @@ +delete($wpdb->postmeta, array('meta_key' => 'inline_featured_image')); +} \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/composer.json b/html/wp-content/plugins/taxonomy-terms-order/composer.json new file mode 100644 index 0000000..e92ff7c --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/composer.json @@ -0,0 +1,17 @@ +{ + "name" : "nsp-code/taxonomy-terms-order", + "description" : "Order Categories and all custom taxonomies terms (hierarchically) and child terms using a Drag and Drop Sortable javascript capability.", + "keywords" : ["category order","terms order", "taxonomy order", "admin order"], + "homepage" : "http://www.nsp-code.com/", + "authors" : [ + { + "name": "Nsp Code", + "email": "contact@nsp-code.com", + "homepage": "http://www.nsp-code.com/" + } + ], + "type" : "wordpress-plugin", + "require" : { + "composer/installers": "~1.0" + } +} diff --git a/html/wp-content/plugins/taxonomy-terms-order/css/to.css b/html/wp-content/plugins/taxonomy-terms-order/css/to.css new file mode 100644 index 0000000..7c13e58 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/css/to.css @@ -0,0 +1,75 @@ + +h2.subtitle {font-size: 15px; font-weight: bold; padding: 20px 0 10px 0} + +#order-terms {} +#order-terms img {vertical-align: middle} +#order-terms #tto_sortable { list-style-type: none; margin: 10px 0 0; padding: 0; width: 100%; } +#order-terms ul {list-style: none;} +#order-terms ul.children {margin-left: 25px} + +#order-terms #tto_sortable li > .item { border: 1px solid #E6E6E6;height: auto;line-height: 27px; padding-left: 10px;position: relative; text-shadow: 0 1px 0 #FFFFFF;width: auto;word-wrap: break-word;cursor: move;background: url("../images/gray-grad.png") repeat-x scroll left top #DFDFDF;-webkit-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px;transition:All 0.5s ease;-webkit-transition:All 0.5s ease;-moz-transition:All 0.5s ease;-o-transition:All 0.5s ease;} +#order-terms #tto_sortable li > .item span { display: inline-block; line-height: 20px; padding: 5px 0; white-space: nowrap; font-weight: bold; cursor: pointer;} +#order-terms #tto_sortable li > .item .options {float: right; padding: 0 10px 0 10px; } +#order-terms #tto_sortable li > .item .options a {text-decoration: none; color: #3c434a;} +#order-terms #tto_sortable li > .item .options a:hover {color: #2271b1;} +#order-terms #tto_sortable li > .item .options span {font-weight: normal} +#order-terms ul.children {margin-left: 20px} +#order-terms .term_type_li ul {margin-top: 6px} +#order-terms #nav-menu-header {background: url("../images/gray-grad.png") repeat-x scroll left top #DFDFDF; -moz-border-radius-topleft: 6px; -moz-border-radius-topright: 6px;border-width: 1px 1px 0;border-color: #CCCCCC;border-style: solid; margin-bottom: 0px} +#order-terms #nav-menu-header .major-publishing-actions {clear: both;padding: 5px 0px;} +#order-terms #nav-menu-header .actions, #order-terms #nav-menu-footer .actions {padding: 0px; margin: 2px 0px; position: relative} +.actions .toggle_thumbnails {margin-right: 30px} +#order-terms #nav-menu-header .img_spacer {width: 18px; height: 18px;} +#order-terms #nav-menu-footer {background: url("../images/gray-grad.png") repeat-x scroll left top #DFDFDF; -moz-border-radius-bottomleft: 6px; -moz-border-radius-bottomright: 6px;border-width: 0 1px 1px 1px;border-color: #CCCCCC;border-style: solid;} +#order-terms #nav-menu-footer .major-publishing-actions {clear: both;padding: 5px 0px;} +#order-terms #nav-menu-footer .submit {padding: 0px;} + +#order-terms .ui-sortable-placeholder{border-color:#bbb;background-color:#FCFCFC; height:32px; background-image: none; -moz-border-radius: 6px 6px 6px 6px; border: 3px dashed #E6E6E6; -webkit-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px; box-sizing: border-box;} +#order-terms .ui-sortable-helper{filter:alpha(opacity=75); /* for internet explorer */opacity: 0.75; /* CSS3 standard */-moz-opacity:0.75; /* for older gecko browsers */-khtml-opacity: 0.75; /* for older webkit browsers */} + +#order-terms #post-body {background: none repeat scroll 0 0 #FFFFFF;border-width: 0 1px 0 1px;border-color: #CCCCCC;border-style: solid; padding: 10px;} + +.wp-list-taxonomy {width: 100%} +.wp-list-taxonomy thead tr th{padding: 10px 0; text-align: left;} +.wp-list-taxonomy tr {background-color: #FCFCFC;} +.wp-list-taxonomy tbody th.check-column { padding: 9px 0 22px;} +.wp-list-taxonomy td { color: #555555;} +.wp-list-taxonomy td, .wp-list-taxonomy th { border-bottom-color: #DFDFDF; border-top-color: #FFFFFF;} +.wp-list-taxonomy th, .wp-list-taxonomy td { overflow: hidden;} +.wp-list-taxonomy td { padding: 9px 7px 4px 7px; vertical-align: top;} +.wp-list-taxonomy td, .wp-list-taxonomy th { border-style: solid; border-width: 1px 0;} +.wp-list-taxonomy * { word-wrap: break-word;} + +#cpt_info_box {padding: 0 10px; border: 1px dashed #6aadcc; background-color: #FFF; margin-top: 10px; +-webkit-box-shadow: 1px 1px 7px rgba(50, 50, 50, 0.17); +-moz-box-shadow: 1px 1px 7px rgba(50, 50, 50, 0.17); +box-shadow: 1px 1px 7px rgba(50, 50, 50, 0.17);} +#cpt_info_box a {text-decoration: none} +#cpt_info_box #donate_form {float: right; padding: 10px 0 17px; text-align: center; width: 100%;} +#p_right {float: right; background-color:#f5f5f5; border: 1px dashed #6aadcc; padding: 0px 10px; margin-top: 10px} +.p_s_item {float: right; padding: 0px 5px; margin-top: 10px; margin-bottom: 5px; } +.p_s_item.s_gp {padding-top: 2px; margin-left: 5px} + +.menu_tto {margin-right: 4px; display: inline; vertical-align: middle; margin-top: -1px;} + +#form_data td {vertical-align: top; padding-top: 20px} +#form_data .pt-list {display:flex; flex-wrap: wrap;} +#form_data .pt-item {flex-basis: calc(25% - 10px); flex-grow: 0; margin: 5px;} +#form_data .pt-list::after { content: ""; flex-basis: calc(25% - 10px); flex-grow: 1; margin: 5px;} +@media screen and (max-width: 1350px) { + #form_data .pt-item {flex-basis: calc(33% - 10px);} + #form_data .pt-list::after { flex-basis: calc(33% - 10px);} +} +@media screen and (max-width: 1100px) { + #form_data .pt-item {flex-basis: calc(50% - 10px);} + #form_data .pt-list::after { flex-basis: calc(50% - 10px);} +} +@media screen and (max-width: 782px) { + #form_data .pt-item {flex-basis: calc(100% - 10px);} + #form_data .pt-list::after { flex-basis: calc(100% - 10px);} + #form_data .form-table th {text-align: left !important} +} + +.clear {clear: both} + + diff --git a/html/wp-content/plugins/taxonomy-terms-order/images/gray-grad.png b/html/wp-content/plugins/taxonomy-terms-order/images/gray-grad.png new file mode 100644 index 0000000..99c45ce Binary files /dev/null and b/html/wp-content/plugins/taxonomy-terms-order/images/gray-grad.png differ diff --git a/html/wp-content/plugins/taxonomy-terms-order/images/logo.png b/html/wp-content/plugins/taxonomy-terms-order/images/logo.png new file mode 100644 index 0000000..68b14dc Binary files /dev/null and b/html/wp-content/plugins/taxonomy-terms-order/images/logo.png differ diff --git a/html/wp-content/plugins/taxonomy-terms-order/images/menu-icon.png b/html/wp-content/plugins/taxonomy-terms-order/images/menu-icon.png new file mode 100644 index 0000000..bb4cdba Binary files /dev/null and b/html/wp-content/plugins/taxonomy-terms-order/images/menu-icon.png differ diff --git a/html/wp-content/plugins/taxonomy-terms-order/images/wpspin_light.gif b/html/wp-content/plugins/taxonomy-terms-order/images/wpspin_light.gif new file mode 100644 index 0000000..09d621e Binary files /dev/null and b/html/wp-content/plugins/taxonomy-terms-order/images/wpspin_light.gif differ diff --git a/html/wp-content/plugins/taxonomy-terms-order/include/class.addons.php b/html/wp-content/plugins/taxonomy-terms-order/include/class.addons.php new file mode 100644 index 0000000..76f9a1b --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/include/class.addons.php @@ -0,0 +1,103 @@ +attribute_name; + } + + if ( ! isset($args['taxonomy']) || count($args['taxonomy']) !== 1 ) + return $ignore; + + if ( count ( array_intersect( $found_attributex_tax, $args['taxonomy']) ) < 1 ) + return $ignore; + + return TRUE; + + } + } + + + new TTO_addons(); \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/include/class.functions.php b/html/wp-content/plugins/taxonomy-terms-order/include/class.functions.php new file mode 100644 index 0000000..dc7494f --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/include/class.functions.php @@ -0,0 +1,91 @@ + array(), + 'capability' => 'manage_options', + 'autosort' => '1', + 'adminsort' => '1' + ); + $settings = wp_parse_args( $settings, $defaults ); + + return $settings; + + } + + + /** + * @desc + * + * Return UserLevel + * + */ + static public function userdata_get_user_level($return_as_numeric = FALSE) + { + global $userdata; + + $user_level = ''; + for ($i=10; $i >= 0;$i--) + { + if (current_user_can('level_' . $i) === TRUE) + { + $user_level = $i; + if ($return_as_numeric === FALSE) + $user_level = 'level_'.$i; + break; + } + } + return ($user_level); + } + + + static public function check_table_column() + { + global $wpdb; + + //check if the menu_order column exists; + $query = "SHOW COLUMNS FROM $wpdb->terms + LIKE 'term_order'"; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared WordPress.DB.DirectDatabaseQuery.DirectQuery + $result = $wpdb->query( $query ); + + if ($result == 0) + { + $query = "ALTER TABLE $wpdb->terms ADD `term_order` INT( 4 ) NULL DEFAULT '0'"; + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared WordPress.DB.DirectDatabaseQuery.DirectQuery + $result = $wpdb->query($query); + } + } + + + static public function info_box() + { + ?> + + + \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/include/class.interface.php b/html/wp-content/plugins/taxonomy-terms-order/include/class.interface.php new file mode 100644 index 0000000..bcc2d63 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/include/class.interface.php @@ -0,0 +1,284 @@ +post_type) && !empty($screen->post_type)) + $post_type = $screen->post_type; + else + { + switch($screen->parent_file) + { + case "upload.php" : + $post_type = 'attachment'; + break; + + default: + $post_type = 'post'; + } + } + } + + $post_type_data = get_post_type_object($post_type); + + if (!taxonomy_exists($taxonomy)) + $taxonomy = ''; + + ?> +
            +

            + + + +
            + + + +
            + + + +
            + + '; + + //output all available taxonomies for this post type + + $post_type_taxonomies = get_object_taxonomies($post_type); + + foreach ($post_type_taxonomies as $key => $taxonomy_name) + { + $taxonomy_info = get_taxonomy($taxonomy_name); + if ($taxonomy_info->hierarchical !== TRUE) + unset($post_type_taxonomies[$key]); + } + + //use the first taxonomy if emtpy taxonomy + if ($taxonomy == '' || !taxonomy_exists($taxonomy)) + { + reset($post_type_taxonomies); + $taxonomy = current($post_type_taxonomies); + } + + if (count($post_type_taxonomies) > 1) + { + + ?> + +

            labels->name) ) ?>

            + + + + + + + + + 0, + 'taxonomy' => $post_type_taxonomy + ); + $taxonomy_terms = get_terms( $args ); + + ?> + + + + + + + + +
             
            name="taxonomy"> label ) ?> (labels->singular_name ); ?>)
            +
            + + +
            + + + +
            + +
              + listTerms($taxonomy); + ?> +
            + +
            +
            + + + +
            + +
            + + + +
            + 'term_order', + 'depth' => 0, + 'child_of' => 0, + 'hide_empty' => 0, + + 'taxonomy' => $taxonomy, + ); + $taxonomy_terms = get_terms( $args ); + + $output = ''; + if (count($taxonomy_terms) > 0) + { + $output = $this->TOwalkTree($taxonomy_terms, $args['depth'], $args); + } + + echo $output; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + + } + + function TOwalkTree($taxonomy_terms, $depth, $r) + { + $walker = new TO_Terms_Walker; + $args = array($taxonomy_terms, $depth, $r); + return call_user_func_array(array(&$walker, 'walk'), $args); + } + + } + +?> \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/include/class.options.php b/html/wp-content/plugins/taxonomy-terms-order/include/class.options.php new file mode 100644 index 0000000..7505c58 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/include/class.options.php @@ -0,0 +1,143 @@ +

            +
            + +

            + + + +
            +
            +

            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            +

            +
            +
            + name ); + + foreach ($post_type_taxonomies as $key => $taxonomy_name) + { + $taxonomy_info = get_taxonomy($taxonomy_name); + if (empty($taxonomy_info->hierarchical) || $taxonomy_info->hierarchical !== TRUE) + unset($post_type_taxonomies[$key]); + } + + if (count($post_type_taxonomies) == 0) + continue; + + + ?> +


             

            + +
            +
            + +
            + + +
            + + +
            + + +

            + +

            + + + + +
            + + '; + + + } + + } + + +?> \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/include/class.terms_walker.php b/html/wp-content/plugins/taxonomy-terms-order/include/class.terms_walker.php new file mode 100644 index 0000000..12b4263 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/include/class.terms_walker.php @@ -0,0 +1,51 @@ + 'parent', 'id' => 'term_id'); + + + function start_lvl(&$output, $depth = 0, $args = array() ) + { + extract($args, EXTR_SKIP); + + $indent = str_repeat("\t", $depth); + $output .= "\n$indent
              \n"; + } + + + function end_lvl(&$output, $depth = 0, $args = array()) + { + extract($args, EXTR_SKIP); + + $indent = str_repeat("\t", $depth); + $output .= "$indent
            \n"; + } + + + function start_el(&$output, $term, $depth = 0, $args = array(), $current_object_id = 0) + { + if ( $depth ) + $indent = str_repeat("\t", $depth); + else + $indent = ''; + + $currentScreen = get_current_screen(); + + $term_link = isset ( $currentScreen->post_type ) ? get_edit_term_link( $term, $term->taxonomy, $currentScreen->post_type ) : get_edit_term_link( $term ); + + $output .= $indent . '
          • '.apply_filters( 'to/term_title', $term->name, $term ).'
            '; + } + + + function end_el(&$output, $object, $depth = 0, $args = array()) + { + $output .= "
          • \n"; + } + + } + +?> \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/include/class.tto.php b/html/wp-content/plugins/taxonomy-terms-order/include/class.tto.php new file mode 100644 index 0000000..33d2c62 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/include/class.tto.php @@ -0,0 +1,224 @@ +' . __('Taxonomy Terms Order', 'taxonomy-terms-order'), 'manage_options', 'to-options', array ( $TTO_plugin_options, 'plugin_options' ) ); + + $options = TTO_functions::get_settings(); + + if(isset($options['capability']) && !empty($options['capability'])) + $capability = $options['capability']; + else if (is_numeric($options['level'])) + { + //maintain the old user level compatibility + $capability = TTO_functions::userdata_get_user_level(); + } + else + { + $capability = 'manage_options'; + } + + //put a menu within all custom types if apply + $post_types = get_post_types(); + foreach( $post_types as $post_type) + { + + //check if there are any taxonomy for this post type + $post_type_taxonomies = get_object_taxonomies($post_type); + + foreach ($post_type_taxonomies as $key => $taxonomy_name) + { + $taxonomy_info = get_taxonomy($taxonomy_name); + if (empty($taxonomy_info->hierarchical) || $taxonomy_info->hierarchical !== TRUE) + unset($post_type_taxonomies[$key]); + } + + if (count($post_type_taxonomies) == 0) + continue; + + if ( isset ( $options['show_reorder_interfaces'][ $post_type ]) && $options['show_reorder_interfaces'][ $post_type ] == 'hide' ) + continue; + + $TTO_Interface = new TTO_Interface(); + + if ($post_type == 'post') + add_submenu_page('edit.php', __('Taxonomy Order', 'taxonomy-terms-order'), __('Taxonomy Order', 'taxonomy-terms-order'), $capability, 'to-interface-'.$post_type, array ( $TTO_Interface, 'Interface' ) ); + elseif ($post_type == 'attachment') + add_submenu_page('upload.php', __('Taxonomy Order', 'taxonomy-terms-order'), __('Taxonomy Order', 'taxonomy-terms-order'), $capability, 'to-interface-'.$post_type, array ( $TTO_Interface, 'Interface' ) ); + else + add_submenu_page('edit.php?post_type='.$post_type, __('Taxonomy Order', 'taxonomy-terms-order'), __('Taxonomy Order', 'taxonomy-terms-order'), $capability, 'to-interface-'.$post_type, array ( $TTO_Interface, 'Interface' ) ); + } + } + + + /** + * Apply order filter + * + * @param mixed $clauses + * @param mixed $taxonomies + * @param mixed $args + */ + function apply_order_filter( $clauses, $taxonomies, $args) + { + if ( apply_filters('to/get_terms_orderby/ignore', FALSE, $clauses['orderby'], $args) ) + return $clauses; + + $options = TTO_functions::get_settings(); + + //if admin make sure use the admin setting + if (is_admin()) + { + + //return if use orderby columns + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + if (isset($_GET['orderby']) && sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) !== 'term_order') + return $clauses; + + if ( $options['adminsort'] == "1" && (!isset($args['ignore_term_order']) || (isset($args['ignore_term_order']) && $args['ignore_term_order'] !== TRUE) ) ) + { + if ( $clauses['orderby'] == 'ORDER BY t.name' ) + $clauses['orderby'] = 'ORDER BY t.term_order '. $clauses['order'] .', t.name'; + else + $clauses['orderby'] = 'ORDER BY t.term_order'; + + } + + return $clauses; + } + + //if autosort, then force the menu_order + if ($options['autosort'] == "1" && (!isset($args['ignore_term_order']) || (isset($args['ignore_term_order']) && $args['ignore_term_order'] !== TRUE) ) ) + { + $clauses['orderby'] = 'ORDER BY t.term_order'; + } + + if ( $options['adminsort'] == "1" && defined( 'REST_REQUEST' ) && REST_REQUEST ) + { + $clauses['orderby'] = 'ORDER BY t.term_order'; + } + + return $clauses; + } + + + /** + * Get terms orderby + * + * @param mixed $orderby + * @param mixed $args + * @return mixed + */ + function get_terms_orderby($orderby, $args) + { + if ( apply_filters('to/get_terms_orderby/ignore', FALSE, $orderby, $args) ) + return $orderby; + + if (isset($args['orderby']) && $args['orderby'] == "term_order" && $orderby != "term_order") + return "t.term_order"; + + return $orderby; + } + + + /** + * Save the AJAX order update + * + */ + function saveAjaxOrder() + { + global $wpdb; + + if ( ! isset ( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field ( wp_unslash ( $_POST['nonce'] ) ), 'update-taxonomy-order' ) ) + die(); + + $data = isset ( $_POST['order'] ) ? stripslashes( sanitize_text_field ( wp_unslash ( $_POST['order'] ) ) ) : ""; + $unserialised_data = json_decode($data, TRUE); + + if (is_array($unserialised_data)) + foreach($unserialised_data as $key => $values ) + { + //$key_parent = str_replace("item_", "", $key); + $items = explode("&", $values); + unset($item); + foreach ($items as $item_key => $item_) + { + $items[$item_key] = trim(str_replace("item[]=", "",$item_)); + } + + if (is_array($items) && count($items) > 0) + { + foreach( $items as $item_key => $term_id ) + { + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery + $wpdb->update( $wpdb->terms, array('term_order' => ($item_key + 1)), array('term_id' => $term_id) ); + } + clean_term_cache($items); + } + } + + do_action('tto/update-order'); + + wp_cache_flush(); + + die(); + } + + } \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/js/to-javascript.js b/html/wp-content/plugins/taxonomy-terms-order/js/to-javascript.js new file mode 100644 index 0000000..9c9b40f --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/js/to-javascript.js @@ -0,0 +1,20 @@ + + function to_change_taxonomy(element) + { + //select the default category (0) + jQuery('#to_form #cat').val(jQuery("#to_form #cat option:first").val()); + jQuery('#to_form').submit(); + } + + var convArrToObj = function(array){ + var thisEleObj = new Object(); + if(typeof array == "object"){ + for(var i in array){ + var thisEle = convArrToObj(array[i]); + thisEleObj[i] = thisEle; + } + }else { + thisEleObj = array; + } + return thisEleObj; + } \ No newline at end of file diff --git a/html/wp-content/plugins/taxonomy-terms-order/languages/taxonomy-terms-order.mo b/html/wp-content/plugins/taxonomy-terms-order/languages/taxonomy-terms-order.mo new file mode 100644 index 0000000..5d7debb Binary files /dev/null and b/html/wp-content/plugins/taxonomy-terms-order/languages/taxonomy-terms-order.mo differ diff --git a/html/wp-content/plugins/taxonomy-terms-order/languages/taxonomy-terms-order.po b/html/wp-content/plugins/taxonomy-terms-order/languages/taxonomy-terms-order.po new file mode 100644 index 0000000..8c4b280 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/languages/taxonomy-terms-order.po @@ -0,0 +1,149 @@ +msgid "" +msgstr "" +"Project-Id-Version: Category Order and Taxonomy Terms Order\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-09-04 16:42+0300\n" +"PO-Revision-Date: 2024-09-04 16:42+0300\n" +"Last-Translator: NspCode \n" +"Language-Team: nsp-code \n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-KeywordsList: _;gettext;__;_e\n" +"X-Poedit-Basepath: ..\n" +"X-Generator: Poedit 3.5\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-SearchPath-0: .\n" + +#: include/class.functions.php:74 +msgid "" +"Did you find this plugin useful? Please support our work with a donation or " +"write an article about this plugin in your blog with a link to our site" +msgstr "" + +#: include/class.functions.php:75 +msgid "Did you know there is an Advanced Version of this plug-in?" +msgstr "" + +#: include/class.functions.php:75 +msgid "Read more" +msgstr "" + +#: include/class.functions.php:76 include/class.functions.php:77 +msgid "Check our" +msgstr "" + +#: include/class.functions.php:76 +msgid "plugin which allows to custom sort all posts, pages, custom post types" +msgstr "" + +#: include/class.functions.php:77 +msgid "" +"plugin which allows to custom sort categories and custom taxonomies terms " +"per post basis" +msgstr "" + +#: include/class.interface.php:42 include/class.to.php:107 +#: include/class.to.php:109 include/class.to.php:111 +msgid "Taxonomy Order" +msgstr "" + +#: include/class.interface.php:50 +msgid "" +"This plugin can't work without javascript, because it's use drag and drop " +"and AJAX." +msgstr "" + +#: include/class.interface.php:104 +msgid "Taxonomies" +msgstr "" + +#: include/class.interface.php:108 +msgid "Taxonomy Title" +msgstr "" + +#: include/class.interface.php:108 +msgid "Total Posts" +msgstr "" + +#: include/class.interface.php:160 +msgid "Update" +msgstr "" + +#: include/class.options.php:20 +msgid "Settings Saved" +msgstr "" + +#: include/class.options.php:28 +msgid "General Settings" +msgstr "" + +#: include/class.options.php:34 +msgid "General" +msgstr "" + +#: include/class.options.php:39 +msgid "Minimum Level to use this plugin" +msgstr "" + +#: include/class.options.php:42 +msgid "Subscriber" +msgstr "" + +#: include/class.options.php:43 +msgid "Contributor" +msgstr "" + +#: include/class.options.php:44 +msgid "Author" +msgstr "" + +#: include/class.options.php:45 +msgid "Editor" +msgstr "" + +#: include/class.options.php:46 +msgid "Administrator" +msgstr "" + +#: include/class.options.php:54 +msgid "Auto Sort" +msgstr "" + +#: include/class.options.php:57 include/class.options.php:68 +msgid "OFF" +msgstr "" + +#: include/class.options.php:58 include/class.options.php:69 +msgid "ON" +msgstr "" + +#: include/class.options.php:60 +msgid "global setting" +msgstr "" + +#: include/class.options.php:60 include/class.options.php:71 +msgid "Additional description and details at " +msgstr "" + +#: include/class.options.php:60 include/class.options.php:71 +msgid "Auto Sort Description" +msgstr "" + +#: include/class.options.php:65 +msgid "Admin Sort" +msgstr "" + +#: include/class.options.php:71 +msgid "This will change the order of terms within the admin interface" +msgstr "" + +#: include/class.options.php:82 +msgid "Save Settings" +msgstr "" + +#: include/class.to.php:70 +msgid "Taxonomy Terms Order" +msgstr "" diff --git a/html/wp-content/plugins/taxonomy-terms-order/readme.txt b/html/wp-content/plugins/taxonomy-terms-order/readme.txt new file mode 100644 index 0000000..fce1330 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/readme.txt @@ -0,0 +1,309 @@ +=== Category Order and Taxonomy Terms Order === +Contributors: nsp-code +Donate link: http://www.nsp-code.com/donate.php +Tags: category order,terms order, taxonomy order, categories sort +Requires at least: 2.8 +Tested up to: 6.9 +Stable tag: 1.9.4 + +Drag-and-drop ordering for Categories & any taxonomy (hierarchically) using a Drag and Drop Sortable JavaScript capability. + +== Description == + +Easily control the order of Categories and any hierarchical taxonomy with a simple drag-and-drop interface. Reorder parent and child terms visually in the admin and choose whether the plugin automatically applies your custom term order to front-end queries. + +

            Key features

            +
              +
            • Intuitive drag-and-drop reordering for Categories and all hierarchical taxonomies.
            • + +
            • Option to auto-apply the custom term order to front-end queries (no theme/plugin edits required).
            • + +
            • Keep the admin term lists in your new order (makes management and editorial workflows consistent).
            • + +
            • Works with multiple taxonomies per post type — switch between taxonomies from the same interface.
            • + +
            • Multisite aware and regularly updated for modern WordPress and PHP versions (see changelog for compatibility notes).
            • +
            + +

            How it works

            +After activating the plugin, a new Taxonomy Order page becomes available under the custom post type menu. Simply open it and drag terms into the exact order you want — including parent/child hierarchy. +Use the plugin’s Taxonomy Order screen to drag terms into the order you want. To apply the custom order automatically across your site, enable the Autosort option — the plugin will adjust term queries on the fly so your chosen order shows without template changes. If you prefer to control ordering in code, include orderby => 'term_order' when calling get_terms() to use the plugin’s order programmatically. + +
            This plugin is developed by Nsp-Code + +
            See the Advanced Taxonomy Terms Order for advanced features. + +== Installation == + +1. Upload `taxonomy-terms-order` folder to your `/wp-content/plugins/` directory. +2. Activate the plugin from Admin > Plugins menu. +3. Once activated you should check with Settings > Taxonomy Terms Order +4. Use Taxonomy Order link which appears into each post type section to make your sort. + +== Screenshots == + +1. Category Order Interface. +2. Multiple Taxonomies Interface. + +== Frequently Asked Questions == + +Feel free to contact me at electronice_delphi@yahoo.com + += Since I have no PHP knowledge at all, is this plugin for me? = + +Absolutely, you can! +Unlike many other plugins, you don't have to do any code changes to make your post order to apply, accordingly to custom-defined order. There is an option to auto-update the WordPress queries so the posts will be returned in customised order. This can be turned off (Autosort) to allow customized code usage. + += I prefer to apply the sort through code, how can be done? = + +Include a 'orderby' => 'term_order' within your get_terms() arguments. + += What taxonomies will allow me to sort? = + +You can sort ALL taxonomies ( hierarhically active ), including the default Categories. + += Is there any way i can get my admin interface to use the custom terms order? = + +Absolutely, the plugin can do that. In fact you can configure so only the admin will update and the front side template will display the terms as before. + += There is a feature that i want it implemented, can you do something about it? = + +All ideas are welcome and i put them on my list to be implemented into the new versions. Anyway this may take time, but if you are in a rush, please consider a small donation and we can arrange something. + += I still need more features = + +Consider upgrading to our advanced version of this plugin at a very resonable price Advanced Taxonomy Terms Order Order + +== Change Log == + += 1.9.4 = + - On Rest Request, evaluate the admin sort settings to apply or not the customized order. + += 1.9.3 = + - Improved plugin page description + - Use sanitize_text_field and wp_unslash for the options form + - Include FALSE argument in the wp_register_script + - WordPress 6.9 compatibility check + - WordPress 6.9 tag update + += 1.9.1 = + - Replace all _e with escaping function esc_html_e + - Use esc_url when output an image url + - Use esc_attr when output html attribute value + - Use isset before using an array argument. + - Minor CSS enhancements + - Other Minor code changes + += 1.9 = + - Style and layout updates for the re-order interface. + - Add version to the CSS/JavaScript files to ensure latest data is loaded instead cached. + - WordPress 6.8.2 compatibility tag + += 1.8.8 = + - PHP 8.3.4 compatibility check + - Slight CSS and layout adjustments. + - WordPress 6.8 compatibility tag + += 1.8.7 = + - CSS adjustments for span action section. + - Option for term edit link. + - Include the term edit link on the ReOrder interface. + - Wordpress 6.7 compatibility check and tag update. + += 1.8.6 = + - Fix: TTO_addons class not loaded which makes the compatibility routines not triggering. + += 1.8.5 = + - Temporary placeholder function to prevent fatal errors when using the Uncode theme. + += 1.8.4 = + - Code structure improvements. + - New option "Show / Hide re-order interface" - Display the Taxonomy Order interface for the specified post types + - WordPress 6.6.1 compatibility check and tag update + += 1.8.2 = + - Polylang fix - Ignore the 'language' to avoid unnecessarily sorting. + - Set-up the Live Preview for the plugin. + - WordPress 6.5.4 compatibility check and tag update + += 1.8.1 = + - WordPress 6.5 compatibility check and tag update + += 1.8 = + - Check if the terms table still includ the custom column, to avoid errors ( mainly when upgrading WordPress ) + - Code improvements + - WordPress 6.4.2 compatibility check and tag update + += 1.7.9 = + - Trigger wp_cache_flush when saving the order to clear the internal caches + - WordPress 6.3 compatibility tag + += 1.7.7 = + - Use term name for admin queries, when the admin sort is active, to avoid "random" returns on certain servers, when term order are empty. + - WordPress 6.2.2 compatibility tag + += 1.7.5 = + - New filter tto/admin/plugin_options/capability to add custom roles and capabilities. + - Compatibility tag update for WordPress 6.2 + += 1.7.4 = + - Compatibility tag update for WordPress 6.1.1 + += 1.7.3 = + - Use esc_html to escape the ajax response message, to avoid single quotes which will break the code. + += 1.7.1 = + - Add the required column when create a new site, when running under MultiSite environment. + += 1.7 = + - Create the required columns for all sites, when running under MultiSite environment. + - Compatibility tag update for WordPress 6.0.1 + += 1.6.1 = + - Compatibility tag update for WordPress 6.0 + += 1.6 = + - Readme file updates, typos fixes. + - Compatibility tag update for WordPress 5.9.1 + += 1.5.9 = + - Remove Twitter button + - Compatibility tag update for WordPress 5.8.2 + += 1.5.7.7 = + - Minor code updates + - Code cleanup + - Compatibility tag update for WordPress 5.8.1 + += 1.5.7.6 = + - Clear the term cache to ensure the updated order reflect for certain caches + += 1.5.7.5 = + - Apply the order within admin if ignore_term_order argument is set and not true + - Compatibility tag update for WordPress 5.7 + += 1.5.7.4 = + - Fix: Call to undefined function wc_get_attribute_taxonomies() + - Compatibility tag update for WordPress 5.6 + += 1.5.7.3 = + - Compatibility tag update for WordPress 5.5 + += 1.5.7.2 = + - Compatibility tag update for WordPress 5.4 + += 1.5.7.1 = + - Compatibility tag update for WordPress 5.3 + += 1.5.7 = + - Ignore WooCOmmerce Attributes order as being changed through default interface + += 1.5.6 = + - Rely on 'terms_clauses' filter than 'get_terms_orderby' as producing issues with the $maybe_orderby_meta backward compatibility. + - Fix WooCommerce category order apply + += 1.5.5 = + - Ignore admin sort when using columns order within Taxonomy interface + += 1.5.4 = + - Replaced serialize with JSON when saving terms order + - New filter to/get_terms_orderby/ignore to allow sort ignore when Autosort is turned On + - Addon code to ignore term_order sorting when Co-Authors plugin term query + += 1.5.3.2 = + - Add nonce field for AJAX sort update + += 1.5.3.1 = + - Removed Google Plus share button which triggered some JavaScript errors + += 1.5.3 = + - Use JSON instead serialize method when sending order through AJAX + - Updated PO language file + += 1.5.2.2 = + - Default admin capability changed from install_plugins to manage_options to prevent DISALLOW_FILE_MODS issue. https://wordpress.org/support/topic/plugin-breaks-when-disallow_file_mods-is-set-to-true/ + - Prepare plugin for Composer package + - Interface table th elements titles left align + - Interface Taxonomy terms count fix + += 1.5 = + - Included 'ignore_term_order' to force menu_order ignore when autosort active. + - Translations issues update + += 1.4.9 = + - Remove translations from the package + - Removed donate banner + - PHP 7 fix + - Unused action remove + += 1.4.8 = + - textdomain folder fix + - Translation fix for user roles + - the_title filter replaced with terms_walker + - Add Nonce for admin settings + += 1.4.7 = + - Texdomain change to taxonomy-terms-order to allow translations through translate.wordpress.org + - WordPress 4.4 compatibility update + - Css updates + += 1.4.6.1 = + - Security bug fix + += 1.4.5 = + - Translation textdomain fix - thanks to Pedro Mendonça + - Portuguese localization update - Pedro Mendonça + += 1.4.4 = + - User role switch from deprecated user_level to capabilities + - Taxonomy sort for media + - Admin Options update + += 1.4.2 = + - Iranian Language (eydaaad@gmail.com) + - Admin css updates. + += 1.4.1 = + - Polish Language(Pozdrawiam - www.difreo.pl/ ; Mateusz - www.czar-net.com ) + += 1.4.0 = + - Hungarian Language(Adam Laki - http://codeguide.hu/) + - Ukrainian translation (Michael Yunat - http://getvoip.com) + - Czech translation + += 1.3.7 = + - Brazilian Portuguese Language (Rafael Forcadell - www.rafaelforcadell.com.br) + += 1.3.6 = + - Traditional Chinese Language (Danny - http://sofree.cc) + - Minor admin styling + += 1.3.4 = + - Menu walker update + - Translations load fix + - Japanese language + += 1.3.0 = + - Headers already sent bug fix + - Slovak Language (Branco Slovak http://webhostinggeeks.com/user-reviews/) + += 1.2.9 = + - Small updates + - German and French languages. + += 1.2.7 = + - Localization implement, Dutch and Romanian. + - Many thanks to Anja Fokker http://www.werkgroepen.net/ + + +== Upgrade Notice == + +Make sure you get the latest version + + +== Localization == + +Available in Catalan, Chinese (China), Chinese (Taiwan), Czech, Dutch, Dutch (Belgium), English (Australia), English (Canada), English (New Zealand), English (UK), English (US), French (France), Galician, German, Italian, Japanese, Norwegian (Bokmål), Polish, Portuguese (Portugal), Russian, Spanish (Chile), Spanish (Spain), Spanish (Venezuela), Swedish, and Turkish. +Whant to contribute with a translation to your language? Please check at https://translate.wordpress.org/projects/wp-plugins/taxonomy-terms-order + +There isn't any Editors for your native language on plugin Contributors? You can help to moderate! https://translate.wordpress.org/projects/wp-plugins/taxonomy-terms-order/contributors diff --git a/html/wp-content/plugins/taxonomy-terms-order/screenshot-1.png b/html/wp-content/plugins/taxonomy-terms-order/screenshot-1.png new file mode 100644 index 0000000..06daedf Binary files /dev/null and b/html/wp-content/plugins/taxonomy-terms-order/screenshot-1.png differ diff --git a/html/wp-content/plugins/taxonomy-terms-order/screenshot-2.png b/html/wp-content/plugins/taxonomy-terms-order/screenshot-2.png new file mode 100644 index 0000000..c30a3fb Binary files /dev/null and b/html/wp-content/plugins/taxonomy-terms-order/screenshot-2.png differ diff --git a/html/wp-content/plugins/taxonomy-terms-order/taxonomy-terms-order.php b/html/wp-content/plugins/taxonomy-terms-order/taxonomy-terms-order.php new file mode 100644 index 0000000..6d3e737 --- /dev/null +++ b/html/wp-content/plugins/taxonomy-terms-order/taxonomy-terms-order.php @@ -0,0 +1,96 @@ +get_col("SELECT blog_id FROM $wpdb->blogs"); + foreach ( $blogids as $blog_id ) + { + switch_to_blog( $blog_id ); + TTO_functions::check_table_column(); + restore_current_blog(); + } + + return; + } + else + TTO_functions::check_table_column(); + } + + + add_action( 'wp_initialize_site', 'TTO_wp_initialize_site', 99, 2 ); + function TTO_wp_initialize_site( $blog_data, $args ) + { + global $wpdb; + + if ( is_plugin_active_for_network('taxonomy-terms-order/taxonomy-terms-order.php') ) + { + switch_to_blog( $blog_data->blog_id ); + TTO_functions::check_table_column(); + restore_current_blog(); + } + } + + + /** + * Load the textdomain + */ + add_action( 'plugins_loaded', 'TTO_load_textdomain'); + function TTO_load_textdomain() + { + load_plugin_textdomain('taxonomy-terms-order', false, dirname( plugin_basename( __FILE__ ) ) . '/languages'); + } + + + /** + * Initialize the main class + * + */ + function TTO_class_load() + { + new TTO(); + } + add_action( 'plugins_loaded', 'TTO_class_load'); + + + /** + * Temporary placeholder function to prevent fatal errors when using the Uncode theme. + * + * @param mixed $clauses + * @param mixed $taxonomies + * @param mixed $args + */ + function TO_apply_order_filter( $clauses, $taxonomies, $args ) + { + return $clauses; + } + + +?> \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/block-editor/classic-paragraph.css b/html/wp-content/plugins/tinymce-advanced/block-editor/classic-paragraph.css new file mode 100644 index 0000000..7b309f7 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/block-editor/classic-paragraph.css @@ -0,0 +1 @@ +div[data-type="tadv/classic-paragraph"].is-selected .block-library-classic__toolbar,div[data-type="tadv/classic-paragraph"].is-typing .block-library-classic__toolbar,div[data-type="tadv/classic-paragraph"] div.mce-toolbar-grp{border-color:rgba(66,88,99,.35)}div[data-type="tadv/classic-paragraph"] .block-library-classic__toolbar:empty{display:none}div[data-type="tadv/classic-paragraph"].is-selected .block-library-classic__toolbar,div[data-type="tadv/classic-paragraph"].is-typing .block-library-classic__toolbar{display:block;z-index:31} \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/block-editor/classic-paragraph.js b/html/wp-content/plugins/tinymce-advanced/block-editor/classic-paragraph.js new file mode 100644 index 0000000..e2a1cb9 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/block-editor/classic-paragraph.js @@ -0,0 +1 @@ +!function(e){var t={};function o(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,o),n.l=!0,n.exports}o.m=e,o.c=t,o.d=function(e,t,r){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)o.d(r,n,function(t){return e[t]}.bind(null,n));return r},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=0)}([function(e,t,o){"use strict";o.r(t);const{wp:r}=window,{debounce:n}=window._,c=window.tadvBlockRegister,{BlockControls:a,useBlockProps:i}=r.blockEditor,{ToolbarGroup:s}=r.components,{Component:l,createElement:d,Fragment:u,useEffect:p,useRef:m}=r.element,{BACKSPACE:b,DELETE:f,F10:g,isKeyboardEvent:k}=r.keycodes;const{RawHTML:y,createElement:h}=wp.element;const{join:v,split:w,create:_,toHTMLString:B}=wp.richText,{createBlock:C,getBlockContent:E}=wp.blocks;var x={from:(()=>{const e=[];return["core-embed/twitter","core-embed/youtube","core-embed/facebook","core-embed/instagram","core-embed/wordpress","core-embed/soundcloud","core-embed/spotify","core-embed/flickr","core-embed/vimeo","core-embed/animoto","core-embed/cloudup","core-embed/collegehumor","core-embed/crowdsignal","core-embed/dailymotion","core-embed/hulu","core-embed/imgur","core-embed/issuu","core-embed/kickstarter","core-embed/meetup-com","core-embed/mixcloud","core-embed/polldaddy","core-embed/reddit","core-embed/reverbnation","core-embed/screencast","core-embed/scribd","core-embed/slideshare","core-embed/smugmug","core-embed/speaker","core-embed/speaker-deck","core-embed/ted","core-embed/tumblr","core-embed/videopress","core-embed/wordpress-tv","core-embed/amazon-kindle"].forEach(t=>{e.push({type:"block",blocks:[t],transform:e=>{if(!e.url)return C("tadv/classic-paragraph",{content:""});const o=E(C(t,e));let r,n="

            "+e.url+"

            ";return o&&o.indexOf("")>-1&&o.replace(/]*>([\s\S]*?)<\/figcaption>/,(function(e,t){r=t})),n+=r?"

            "+r+"

            ":'


            ',C("tadv/classic-paragraph",{content:n})}})}),["core/paragraph","core/image","core/heading","core/gallery","core/list","core/quote","core/code","core/columns","core/freeform","core/html","core/media-text","core/missing","core/preformatted","core/pullquote","core/subhead","core/table","core/text-columns","core/verse"].forEach(t=>{e.push({type:"block",blocks:[t],transform:e=>{let o=E(C(t,e));return(!o||o.indexOf("
            ")>-1)&&(o+='


            '),C("tadv/classic-paragraph",{content:o})}})}),e.push({type:"raw",priority:21,isMatch:()=>!0},{type:"block",isMultiBlock:!0,blocks:["core/paragraph"],transform:e=>{const t=B({value:v(e.map(({content:e})=>_({html:e})),"\u2028"),multilineTag:"p"});return C("tadv/classic-paragraph",{content:t})}},{type:"block",isMultiBlock:!0,blocks:["core/freeform"],transform:e=>{const t=B({value:v(e.map(({content:e})=>_({html:e})),"\u2028")});return C("tadv/classic-paragraph",{content:t})}}),e})(),to:[{type:"block",blocks:["core/freeform"],transform:e=>C("core/freeform",e)},{type:"block",blocks:["core/html"],transform:e=>C("core/html",e)}]};const{__:P}=wp.i18n,T=window.tadvBlockRegister,{name:M,attributes:S,category:L}={name:"tadv/classic-paragraph",category:"common",attributes:{content:{type:"string",source:"html"},align:{type:"string"}}};var N={name:M,attributes:S,category:L,title:T.classicParagraphTitle,description:T.description,keywords:[P("text")],icon:"welcome-widgets-menus",supports:{className:!1,customClassName:!1,reusable:!0},example:{attributes:{content:"

            "+P("Welcome to the wonderful world of blocks…")+"

            "}},merge:(e,t)=>({content:(e.content||"")+(t.content||"")}),transforms:x,edit:function({clientId:e,attributes:{content:t},setAttributes:o,onReplace:a}){const s=m(!1);return p(()=>{if(!s.current)return;const o=window.tinymce.get(`editor-${e}`);let r;o&&(r=o.getContent()),r!==t&&o.setContent(t||"")},[t]),p(()=>{const{baseURL:c,suffix:i}=window.wpEditorL10n.tinymce;function l(e){let r;t&&e.on("loadContent",()=>e.setContent(t)),e.on("blur",()=>{r=e.selection.getBookmark(2,!0);const t=document.querySelector(".interface-interface-skeleton__content"),n=t.scrollTop;return o({content:e.getContent()}),e.once("focus",()=>{r&&(e.selection.moveToBookmark(r),t.scrollTop!==n&&(t.scrollTop=n))}),!1}),e.on("mousedown touchstart",()=>{r=null});const c=n(()=>{const t=e.getContent();t!==e._lastChange&&(e._lastChange=t,o({content:t}))},250);e.on("Paste Change input Undo Redo",c),e.on("remove",c.cancel),e.on("keydown",t=>{k.primary(t,"z")&&t.stopPropagation(),t.keyCode!==b&&t.keyCode!==f||!function(e){const t=e.getBody();return!(t.childNodes.length>1)&&(0===t.childNodes.length||!(t.childNodes[0].childNodes.length>1)&&/^\n?$/.test(t.innerText||t.textContent))}(e)||(a([]),t.preventDefault(),t.stopImmediatePropagation());const{altKey:o}=t;o&&t.keyCode===g&&t.stopPropagation()}),e.on("init",()=>{const t=e.getBody();t.ownerDocument.activeElement===t&&(t.blur(),e.focus())})}function d(){const{settings:t}=window.wpEditorL10n.tinymce;r.oldEditor.initialize(`editor-${e}`,{tinymce:{...t,inline:!0,content_css:!1,fixed_toolbar_container:`#toolbar-${e}`,setup:l}})}function u(){"complete"===document.readyState&&d()}return s.current=!0,window.tinymce.EditorManager.overrideDefaults({base_url:c,suffix:i}),"complete"===document.readyState?d():document.addEventListener("readystatechange",u),()=>{document.removeEventListener("readystatechange",u),r.oldEditor.remove(`editor-${e}`)}},[]),d("div",i(),d("div",{key:"toolbar",id:`toolbar-${e}`,className:"block-library-classic__toolbar tma-classic-paragraph__toolbar",onClick:function(){const t=window.tinymce.get(`editor-${e}`);t&&t.focus()},"data-placeholder":c.classicParagraphTitle,onKeyDown:function(e){e.stopPropagation(),e.nativeEvent.stopImmediatePropagation()}}),d("div",{key:"editor",id:`editor-${e}`,className:"wp-block-freeform block-library-rich-text__tinymce tma-classic-paragraph"}))},save:function({attributes:e}){const{content:t}=e;return h(y,null,t)}};const{dispatch:O,select:j}=wp.data,{createBlock:R,rawHandler:$}=wp.blocks;var D=function(){const e=j("core/block-editor").getSelectedBlock();let t;if(e){let o=e.attributes.content;o?(/

            /.test(o)&&(o=o.replace(/

            /g,"

            ")),t=$({HTML:o})):t=R("core/paragraph"),O("core/block-editor").replaceBlocks(e.clientId,t)}};!function(){const e=window.wp,t=window.tadvBlockRegister;if(!e||!t)return;const{createElement:o}=e.element,{__:r}=e.i18n,{addFilter:n}=e.hooks,{PluginBlockSettingsMenuItem:c}=e.editPost,{registerPlugin:a}=e.plugins,{registerBlockType:i,setDefaultBlockName:s}=e.blocks;t.classicParagraph?(i("tadv/classic-paragraph",N),a("tadv-add-submenu",{render:()=>(t.hybridMode&&s("tadv/classic-paragraph"),o(c,{allowedBlocks:["tadv/classic-paragraph"],icon:"screenoptions",label:r("Convert to Blocks"),onClick:D}))})):t.hybridMode&&a("tadv-set-default-block",{render:()=>(s("core/freeform"),null)})}()}]); \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/block-editor/richtext-buttons.css b/html/wp-content/plugins/tinymce-advanced/block-editor/richtext-buttons.css new file mode 100644 index 0000000..42a3c9e --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/block-editor/richtext-buttons.css @@ -0,0 +1 @@ +.tadv-mark-icon{background-color:#fff9c0;background-clip:content-box} \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/block-editor/richtext-buttons.js b/html/wp-content/plugins/tinymce-advanced/block-editor/richtext-buttons.js new file mode 100644 index 0000000..8f638cd --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/block-editor/richtext-buttons.js @@ -0,0 +1 @@ +!function(t){var e={};function o(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,o),n.l=!0,n.exports}o.m=t,o.c=e,o.d=function(t,e,r){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=1)}([,function(t,e,o){"use strict";o.r(e);const r=window.tadvBlockButtons||{},{wp:n}=window,{RichTextToolbarButton:a}=n.blockEditor,{registerFormatType:c,removeFormat:i}=n.richText,{createElement:l}=n.element,{ToolbarButton:u}=n.components,s=r.strRemoveFormatting||"Clear formatting";let m;function d(t){const e=[];return m||(m=r.formats_to_remove?r.formats_to_remove.split(","):["core/bold","core/italic","core/code","core/underline","core/strikethrough","core/text-color","tadv/sup","tadv/sub","tadv/mark","tadv/color-panel","tadv/background-color-panel"]),t.forEach(t=>{t&&t.forEach(t=>{m.indexOf(t.type)>-1&&-1===e.indexOf(t.type)&&e.push(t.type)})}),e}const{wp:f}=window,v=window.tadvBlockButtons||{},{createElement:p,Fragment:h}=f.element,{__:g}=f.i18n,{ToolbarButton:b}=f.components,{RichTextToolbarButton:y,RichTextShortcut:w}=f.blockEditor,{Path:k,SVG:x}=f.components,{registerFormatType:T,getActiveFormat:F,toggleFormat:_,applyFormat:O,removeFormat:B}=f.richText,E=p(x,{viewBox:"0 0 20 20",xmlns:"http://www.w3.org/2000/svg",className:"dashicon tadv-mark-icon"},p(k,{"aria-hidden":"true",role:"img",focusable:"false",width:"20",height:"20",d:"M13.23 15h1.9L11 4H9L5 15h1.88l1.07-3h4.18zm-1.53-4.54H8.51L10 5.6z"})),P=v.strMark;function j(t,e,o){e(_(t,{type:"tadv/mark"})),o&&o()}const{wp:S}=window,{select:C}=S.data,{registerPlugin:M}=S.plugins,N=["tadv/mark","tadv/removeformat"],A={"tadv/mark":function(){T("tadv/mark",{title:P,tagName:"mark",className:null,edit({value:t,onChange:e,onFocus:o,isActive:r}){const n=p(y,{title:P,icon:E,onClick:()=>j(t,e,o),className:"tadv-icon-button-mark",isActive:r,shortcutType:"access",shortcutCharacter:"m"});return p(h,null,p(w,{type:"access",character:"m",onUse:()=>j(t,e)}),n)}})},"tadv/removeformat":function(){c("tadv/removeformat",{title:s,tagName:"u",className:"remove-format",edit:({value:t,onChange:e,onFocus:o,isActive:r})=>l(a,{icon:"editor-removeformatting",title:s,onClick:()=>e(function(t){let e=t.formats;if(!e.length)return t;let o=0,r=e.length;t.end>t.start&&(o=t.start,r=t.end,e=e.slice(o,r));const n=d(e);return n.length?(n.forEach(e=>{t=i(t,e,o,r)}),t):t}(t)),isActive:null})})}};M("tadv-add-toolbar-buttons",{render:()=>(N.forEach(t=>{A.hasOwnProperty(t)&&!function(t){const e=C("core/rich-text").getFormatTypes();let o=!1;return e.forEach(e=>{e.name===t&&(o=!0)}),o}(t)&&A[t].call(null)}),null)})}]); \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/block-editor/tma-block-editor.css b/html/wp-content/plugins/tinymce-advanced/block-editor/tma-block-editor.css new file mode 100644 index 0000000..88cbefb --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/block-editor/tma-block-editor.css @@ -0,0 +1 @@ +div[data-type="core/freeform"].is-selected .block-library-classic__toolbar,div[data-type="core/freeform"].is-typing .block-library-classic__toolbar{z-index:31}.block-library-classic__toolbar .mce-btn .mce-txt{font-size:13px;color:#454545}.mce-tinymce-inline .mce-menubar>div,.mce-tinymce-inline .mce-toolbar .mce-btn-group>div{white-space:normal}div.mce-menubar,div.mce-menubar *{box-sizing:border-box}.block-library-classic__toolbar .mce-menubar{padding:1px}.block-library-classic__toolbar .mce-menubar .mce-menubtn button span{font-size:13px}.block-library-classic__toolbar .mce-menubar i.mce-caret{margin-top:.4em}.block-library-classic__toolbar .mce-menubar .mce-flow-layout-item{margin:2px 0}div.mce-menubar.mce-toolbar .mce-btn button{padding:3px 4px 2px}div.mce-menubar{border-color:#e5e5e5;background:#fff;border-width:0 0 1px}div.mce-menubar .mce-menubtn:focus{color:#124964;box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8)}div.mce-menu-item-sep:hover,div.mce-menu .mce-menu-item-sep{border-bottom:1px solid #ddd;height:0;margin:5px 0}div.mce-menubtn span{margin-right:0;padding-left:3px}div.mce-menu-has-icons i.mce-ico:before{margin-left:0}div.mce-menu-has-icons i.mce-ico{line-height:18px;width:18px;height:18px}.wp-core-ui .mce-menu-item .mce-text{font-size:13px}.block-library-classic__toolbar .mce-menubar .mce-menubtn.mce-active,.block-library-classic__toolbar .mce-menubar .mce-menubtn:focus,.block-library-classic__toolbar .mce-menubar .mce-menubtn:hover{border-color:transparent}.block-library-classic__toolbar .mce-menubar .mce-menubtn.mce-active span,.block-library-classic__toolbar .mce-menubar .mce-menubtn:focus span,.block-library-classic__toolbar .mce-menubar .mce-menubtn:hover span{color:#000}.mce-inline-toolbar-grp div.wp-link-input{margin:2px 4px}.mce-inline-toolbar-grp div.wp-link-input input{padding:4px}div.mce-menu-item.mce-menu-item-preview.mce-active:hover,div.mce-menu .mce-menu-item-normal.mce-active,div.mce-menu .mce-menu-item-preview.mce-active,div.mce-menu .mce-menu-item.mce-selected,div.mce-menu .mce-menu-item:focus,div.mce-menu .mce-menu-item:hover{background:#0073aa;color:#fff}div.mce-menu-item.mce-active .mce-menu-shortcut,div.mce-menu-item.mce-disabled:hover .mce-ico,div.mce-menu-item.mce-disabled:hover .mce-text,div.mce-menu-item.mce-menu-item-preview.mce-active .mce-ico,div.mce-menu-item.mce-menu-item-preview.mce-active .mce-text,div.mce-menu-item:focus .mce-ico,div.mce-menu-item:focus .mce-menu-shortcut,div.mce-menu-item:focus .mce-text,div.mce-menu-item:hover .mce-ico,div.mce-menu-item:hover .mce-menu-shortcut,div.mce-menu-item:hover .mce-text{color:inherit}div.mce-menu .mce-menu-item.mce-disabled{cursor:default}div.mce-menu .mce-menu-item.mce-disabled:hover{background:#ccc}div.mce-inline-toolbar-grp .mce-btn.mce-active:hover button,div.mce-inline-toolbar-grp .mce-btn.mce-active:hover i,div.mce-inline-toolbar-grp .mce-btn.mce-active button,div.mce-inline-toolbar-grp .mce-btn.mce-active i,div.mce-inline-toolbar-grp .mce-btn:hover button,div.mce-inline-toolbar-grp .mce-btn:hover i,div.mce-toolbar-grp .mce-btn.mce-active:hover button,div.mce-toolbar-grp .mce-btn.mce-active:hover i,div.mce-toolbar-grp .mce-btn.mce-active button,div.mce-toolbar-grp .mce-btn.mce-active i,div.mce-toolbar-grp .mce-btn:hover button,div.mce-toolbar-grp .mce-btn:hover i{color:#191e23}div.mce-inline-toolbar-grp .mce-btn i,div.mce-toolbar-grp .mce-btn i{font-style:normal}div.mce-toolbar-grp .mce-btn i.mce-ico{font-size:20px}div.mce-widget.mce-tooltip .mce-tooltip-inner{font-size:13px;opacity:1}.mce-inline-toolbar-grp.mce-panel .mce-toolbar .mce-btn{margin:1px}.mce-inline-toolbar-grp.mce-panel .mce-toolbar .mce-btn button{padding:3px}.wp-block-freeform.block-library-rich-text__tinymce table{width:100%}.components-button.has-icon.tadv-icon-button .dashicon{margin:0} \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/mce/advlist/plugin.js b/html/wp-content/plugins/tinymce-advanced/mce/advlist/plugin.js new file mode 100644 index 0000000..6dc32b6 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/advlist/plugin.js @@ -0,0 +1,160 @@ +(function () { +var advlist = (function () { + 'use strict'; + + var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); + + var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); + + var applyListFormat = function (editor, listName, styleValue) { + var cmd = listName === 'UL' ? 'InsertUnorderedList' : 'InsertOrderedList'; + editor.execCommand(cmd, false, styleValue === false ? null : { 'list-style-type': styleValue }); + }; + var Actions = { applyListFormat: applyListFormat }; + + var register = function (editor) { + editor.addCommand('ApplyUnorderedListStyle', function (ui, value) { + Actions.applyListFormat(editor, 'UL', value['list-style-type']); + }); + editor.addCommand('ApplyOrderedListStyle', function (ui, value) { + Actions.applyListFormat(editor, 'OL', value['list-style-type']); + }); + }; + var Commands = { register: register }; + + var getNumberStyles = function (editor) { + var styles = editor.getParam('advlist_number_styles', 'default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman'); + return styles ? styles.split(/[ ,]/) : []; + }; + var getBulletStyles = function (editor) { + var styles = editor.getParam('advlist_bullet_styles', 'default,circle,disc,square'); + return styles ? styles.split(/[ ,]/) : []; + }; + var Settings = { + getNumberStyles: getNumberStyles, + getBulletStyles: getBulletStyles + }; + + var isChildOfBody = function (editor, elm) { + return editor.$.contains(editor.getBody(), elm); + }; + var isTableCellNode = function (node) { + return node && /^(TH|TD)$/.test(node.nodeName); + }; + var isListNode = function (editor) { + return function (node) { + return node && /^(OL|UL|DL)$/.test(node.nodeName) && isChildOfBody(editor, node); + }; + }; + var getSelectedStyleType = function (editor) { + var listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul'); + return editor.dom.getStyle(listElm, 'listStyleType') || ''; + }; + var ListUtils = { + isTableCellNode: isTableCellNode, + isListNode: isListNode, + getSelectedStyleType: getSelectedStyleType + }; + + var styleValueToText = function (styleValue) { + return styleValue.replace(/\-/g, ' ').replace(/\b\w/g, function (chr) { + return chr.toUpperCase(); + }); + }; + var toMenuItems = function (styles) { + return global$1.map(styles, function (styleValue) { + var text = styleValueToText(styleValue); + var data = styleValue === 'default' ? '' : styleValue; + return { + text: text, + data: data + }; + }); + }; + var ListStyles = { toMenuItems: toMenuItems }; + + var findIndex = function (list, predicate) { + for (var index = 0; index < list.length; index++) { + var element = list[index]; + if (predicate(element)) { + return index; + } + } + return -1; + }; + var listState = function (editor, listName) { + return function (e) { + var ctrl = e.control; + editor.on('NodeChange', function (e) { + var tableCellIndex = findIndex(e.parents, ListUtils.isTableCellNode); + var parents = tableCellIndex !== -1 ? e.parents.slice(0, tableCellIndex) : e.parents; + var lists = global$1.grep(parents, ListUtils.isListNode(editor)); + ctrl.active(lists.length > 0 && lists[0].nodeName === listName); + }); + }; + }; + var updateSelection = function (editor) { + return function (e) { + var listStyleType = ListUtils.getSelectedStyleType(editor); + e.control.items().each(function (ctrl) { + ctrl.active(ctrl.settings.data === listStyleType); + }); + }; + }; + var addSplitButton = function (editor, id, tooltip, cmd, nodeName, styles) { + editor.addButton(id, { + active: false, + type: 'splitbutton', + tooltip: tooltip, + menu: ListStyles.toMenuItems(styles), + onPostRender: listState(editor, nodeName), + onshow: updateSelection(editor), + onselect: function (e) { + Actions.applyListFormat(editor, nodeName, e.control.settings.data); + }, + onclick: function () { + editor.execCommand(cmd); + } + }); + }; + var addButton = function (editor, id, tooltip, cmd, nodeName, styles) { + editor.addButton(id, { + active: false, + type: 'button', + tooltip: tooltip, + onPostRender: listState(editor, nodeName), + onclick: function () { + editor.execCommand(cmd); + } + }); + }; + var addControl = function (editor, id, tooltip, cmd, nodeName, styles) { + if (styles.length > 0) { + addSplitButton(editor, id, tooltip, cmd, nodeName, styles); + } else { + addButton(editor, id, tooltip, cmd, nodeName); + } + }; + var register$1 = function (editor) { + addControl(editor, 'numlist', 'Numbered list', 'InsertOrderedList', 'OL', Settings.getNumberStyles(editor)); + addControl(editor, 'bullist', 'Bullet list', 'InsertUnorderedList', 'UL', Settings.getBulletStyles(editor)); + }; + var Buttons = { register: register$1 }; + + global.add('advlist', function (editor) { + var hasPlugin = function (editor, plugin) { + var plugins = editor.settings.plugins ? editor.settings.plugins : ''; + return global$1.inArray(plugins.split(/[ ,]/), plugin) !== -1; + }; + if (hasPlugin(editor, 'lists')) { + Buttons.register(editor); + Commands.register(editor); + } + }); + function Plugin () { + } + + return Plugin; + +}()); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/advlist/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/advlist/plugin.min.js new file mode 100644 index 0000000..122cd8f --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/advlist/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.Tools"),s=function(t,e,n){var r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===n?null:{"list-style-type":n})},o=function(n){n.addCommand("ApplyUnorderedListStyle",function(t,e){s(n,"UL",e["list-style-type"])}),n.addCommand("ApplyOrderedListStyle",function(t,e){s(n,"OL",e["list-style-type"])})},e=function(t){var e=t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");return e?e.split(/[ ,]/):[]},n=function(t){var e=t.getParam("advlist_bullet_styles","default,circle,disc,square");return e?e.split(/[ ,]/):[]},u=function(t){return t&&/^(TH|TD)$/.test(t.nodeName)},c=function(r){return function(t){return t&&/^(OL|UL|DL)$/.test(t.nodeName)&&(n=t,(e=r).$.contains(e.getBody(),n));var e,n}},d=function(t){var e=t.dom.getParent(t.selection.getNode(),"ol,ul");return t.dom.getStyle(e,"listStyleType")||""},p=function(t){return a.map(t,function(t){return{text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"===t?"":t}})},f=function(i,l){return function(t){var o=t.control;i.on("NodeChange",function(t){var e=function(t,e){for(var n=0;n' + icon + ''; + }); + + emoticonsHtml += ''; + }); + + emoticonsHtml += ''; + + return emoticonsHtml; + } + + editor.addButton('emoticons', { + type: 'panelbutton', + panel: { + role: 'application', + autohide: true, + html: getHtml, + onclick: function(e) { + var linkElm = editor.dom.getParent( e.target, 'a' ); + + if ( linkElm ) { + editor.insertContent( + ' ' + linkElm.getAttribute('data-mce-alt') + ' ' + ); + + this.hide(); + } + } + }, + tooltip: 'Emoticons' + }); +}); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/emoticons/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/emoticons/plugin.min.js new file mode 100644 index 0000000..91f26d5 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/emoticons/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("emoticons",function(a,b){function c(){var a;return a='',tinymce.each(d,function(c){a+="",tinymce.each(c,function(c,d){var e=b+"/img/icon_"+d+".gif";a+=''}),a+=""}),a+="
            '+c+'
            "}var d=[{smile:":-)",razz:":-P",cool:"8-)",wink:";-)",biggrin:":-D"},{twisted:":twisted:",mrgreen:":mrgreen:",lol:":lol:",rolleyes:":roll:",confused:":-?"},{cry:":cry:",surprised:":-o",evil:":evil:",neutral:":-|",redface:":oops:"},{mad:":-x",eek:"8-O",sad:":-(",arrow:":arrow:",idea:":idea:"}];a.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:c,onclick:function(b){var c=a.dom.getParent(b.target,"a");c&&(a.insertContent(" "+c.getAttribute("data-mce-alt")+" "),this.hide())}},tooltip:"Emoticons"})}); \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/mce/importcss/plugin.js b/html/wp-content/plugins/tinymce-advanced/mce/importcss/plugin.js new file mode 100644 index 0000000..8c21f32 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/importcss/plugin.js @@ -0,0 +1,264 @@ +(function () { +var importcss = (function () { + 'use strict'; + + var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); + + var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); + + var global$2 = tinymce.util.Tools.resolve('tinymce.EditorManager'); + + var global$3 = tinymce.util.Tools.resolve('tinymce.Env'); + + var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); + + var shouldMergeClasses = function (editor) { + return editor.getParam('importcss_merge_classes'); + }; + var shouldImportExclusive = function (editor) { + return editor.getParam('importcss_exclusive'); + }; + var getSelectorConverter = function (editor) { + return editor.getParam('importcss_selector_converter'); + }; + var getSelectorFilter = function (editor) { + return editor.getParam('importcss_selector_filter'); + }; + var getCssGroups = function (editor) { + return editor.getParam('importcss_groups'); + }; + var shouldAppend = function (editor) { + return editor.getParam('importcss_append'); + }; + var getFileFilter = function (editor) { + return editor.getParam('importcss_file_filter'); + }; + var Settings = { + shouldMergeClasses: shouldMergeClasses, + shouldImportExclusive: shouldImportExclusive, + getSelectorConverter: getSelectorConverter, + getSelectorFilter: getSelectorFilter, + getCssGroups: getCssGroups, + shouldAppend: shouldAppend, + getFileFilter: getFileFilter + }; + + var removeCacheSuffix = function (url) { + var cacheSuffix = global$3.cacheSuffix; + if (typeof url === 'string') { + url = url.replace('?' + cacheSuffix, '').replace('&' + cacheSuffix, ''); + } + return url; + }; + var isSkinContentCss = function (editor, href) { + var settings = editor.settings, skin = settings.skin !== false ? settings.skin || 'lightgray' : false; + if (skin) { + var skinUrl = settings.skin_url ? editor.documentBaseURI.toAbsolute(settings.skin_url) : global$2.baseURL + '/skins/' + skin; + return href === skinUrl + '/content' + (editor.inline ? '.inline' : '') + '.min.css'; + } + return false; + }; + var compileFilter = function (filter) { + if (typeof filter === 'string') { + return function (value) { + return value.indexOf(filter) !== -1; + }; + } else if (filter instanceof RegExp) { + return function (value) { + return filter.test(value); + }; + } + return filter; + }; + var getSelectors = function (editor, doc, fileFilter) { + var selectors = [], contentCSSUrls = {}; + function append(styleSheet, imported) { + var href = styleSheet.href, rules; + href = removeCacheSuffix(href); + if (!href || !fileFilter(href, imported) || isSkinContentCss(editor, href)) { + return; + } + global$4.each(styleSheet.imports, function (styleSheet) { + append(styleSheet, true); + }); + try { + rules = styleSheet.cssRules || styleSheet.rules; + } catch (e) { + } + global$4.each(rules, function (cssRule) { + if (cssRule.styleSheet) { + append(cssRule.styleSheet, true); + } else if (cssRule.selectorText) { + global$4.each(cssRule.selectorText.split(','), function (selector) { + selectors.push(global$4.trim(selector)); + }); + } + }); + } + global$4.each(editor.contentCSS, function (url) { + contentCSSUrls[url] = true; + }); + if (!fileFilter) { + fileFilter = function (href, imported) { + return imported || contentCSSUrls[href]; + }; + } + try { + global$4.each(doc.styleSheets, function (styleSheet) { + append(styleSheet); + }); + } catch (e) { + } + return selectors; + }; + var defaultConvertSelectorToFormat = function (editor, selectorText) { + var format; + var selector = /^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(selectorText); + if (!selector) { + return; + } + var elementName = selector[1]; + var classes = selector[2].substr(1).split('.').join(' '); + var inlineSelectorElements = global$4.makeMap('a,img'); + if (selector[1]) { + format = { title: selectorText }; + if (editor.schema.getTextBlockElements()[elementName]) { + format.block = elementName; + } else if (editor.schema.getBlockElements()[elementName] || inlineSelectorElements[elementName.toLowerCase()]) { + format.selector = elementName; + } else { + format.inline = elementName; + } + } else if (selector[2]) { + format = { + inline: 'span', + title: selectorText.substr(1), + classes: classes + }; + } + if (Settings.shouldMergeClasses(editor) !== false) { + format.classes = classes; + } else { + format.attributes = { class: classes }; + } + return format; + }; + var getGroupsBySelector = function (groups, selector) { + return global$4.grep(groups, function (group) { + return !group.filter || group.filter(selector); + }); + }; + var compileUserDefinedGroups = function (groups) { + return global$4.map(groups, function (group) { + return global$4.extend({}, group, { + original: group, + selectors: {}, + filter: compileFilter(group.filter), + item: { + text: group.title, + menu: [] + } + }); + }); + }; + var isExclusiveMode = function (editor, group) { + return group === null || Settings.shouldImportExclusive(editor) !== false; + }; + var isUniqueSelector = function (editor, selector, group, globallyUniqueSelectors) { + return !(isExclusiveMode(editor, group) ? selector in globallyUniqueSelectors : selector in group.selectors); + }; + var markUniqueSelector = function (editor, selector, group, globallyUniqueSelectors) { + if (isExclusiveMode(editor, group)) { + globallyUniqueSelectors[selector] = true; + } else { + group.selectors[selector] = true; + } + }; + var convertSelectorToFormat = function (editor, plugin, selector, group) { + var selectorConverter; + if (group && group.selector_converter) { + selectorConverter = group.selector_converter; + } else if (Settings.getSelectorConverter(editor)) { + selectorConverter = Settings.getSelectorConverter(editor); + } else { + selectorConverter = function () { + return defaultConvertSelectorToFormat(editor, selector); + }; + } + return selectorConverter.call(plugin, selector, group); + }; + var setup = function (editor) { + editor.on('renderFormatsMenu', function (e) { + var globallyUniqueSelectors = {}; + var selectorFilter = compileFilter(Settings.getSelectorFilter(editor)), ctrl = e.control; + var groups = compileUserDefinedGroups(Settings.getCssGroups(editor)); + var processSelector = function (selector, group) { + if (isUniqueSelector(editor, selector, group, globallyUniqueSelectors)) { + markUniqueSelector(editor, selector, group, globallyUniqueSelectors); + var format = convertSelectorToFormat(editor, editor.plugins.importcss, selector, group); + if (format) { + var formatName = format.name || global$1.DOM.uniqueId(); + editor.formatter.register(formatName, format); + return global$4.extend({}, ctrl.settings.itemDefaults, { + text: format.title, + format: formatName + }); + } + } + return null; + }; + if (!Settings.shouldAppend(editor)) { + ctrl.items().remove(); + } + global$4.each(getSelectors(editor, e.doc || editor.getDoc(), compileFilter(Settings.getFileFilter(editor))), function (selector) { + if (selector.indexOf('.mce-') === -1) { + if (!selectorFilter || selectorFilter(selector)) { + var selectorGroups = getGroupsBySelector(groups, selector); + if (selectorGroups.length > 0) { + global$4.each(selectorGroups, function (group) { + var menuItem = processSelector(selector, group); + if (menuItem) { + group.item.menu.push(menuItem); + } + }); + } else { + var menuItem = processSelector(selector, null); + if (menuItem) { + ctrl.add(menuItem); + } + } + } + } + }); + global$4.each(groups, function (group) { + if (group.item.menu.length > 0) { + ctrl.add(group.item); + } + }); + e.control.renderNew(); + }); + }; + var ImportCss = { + defaultConvertSelectorToFormat: defaultConvertSelectorToFormat, + setup: setup + }; + + var get = function (editor) { + var convertSelectorToFormat = function (selectorText) { + return ImportCss.defaultConvertSelectorToFormat(editor, selectorText); + }; + return { convertSelectorToFormat: convertSelectorToFormat }; + }; + var Api = { get: get }; + + global.add('importcss', function (editor) { + ImportCss.setup(editor); + return Api.get(editor); + }); + function Plugin () { + } + + return Plugin; + +}()); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/importcss/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/importcss/plugin.min.js new file mode 100644 index 0000000..8585a1e --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/importcss/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),d=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),v=tinymce.util.Tools.resolve("tinymce.EditorManager"),h=tinymce.util.Tools.resolve("tinymce.Env"),y=tinymce.util.Tools.resolve("tinymce.util.Tools"),o=function(e){return e.getParam("importcss_merge_classes")},n=function(e){return e.getParam("importcss_exclusive")},_=function(e){return e.getParam("importcss_selector_converter")},r=function(e){return e.getParam("importcss_selector_filter")},i=function(e){return e.getParam("importcss_groups")},u=function(e){return e.getParam("importcss_append")},l=function(e){return e.getParam("importcss_file_filter")},a=function(t){return"string"==typeof t?function(e){return-1!==e.indexOf(t)}:t instanceof RegExp?function(e){return t.test(e)}:t},f=function(f,e,m){var g=[],n={};function p(e,t){var n,r,i,c=e.href;if(r=c,i=h.cacheSuffix,"string"==typeof r&&(r=r.replace("?"+i,"").replace("&"+i,"")),(c=r)&&m(c,t)&&(o=c,u=(s=f).settings,!(l=!1!==u.skin&&(u.skin||"lightgray"))||o!==(u.skin_url?s.documentBaseURI.toAbsolute(u.skin_url):v.baseURL+"/skins/"+l)+"/content"+(s.inline?".inline":"")+".min.css")){var s,o,u,l;y.each(e.imports,function(e){p(e,!0)});try{n=e.cssRules||e.rules}catch(a){}y.each(n,function(e){e.styleSheet?p(e.styleSheet,!0):e.selectorText&&y.each(e.selectorText.split(","),function(e){g.push(y.trim(e))})})}}y.each(f.contentCSS,function(e){n[e]=!0}),m||(m=function(e,t){return t||n[e]});try{y.each(e.styleSheets,function(e){p(e)})}catch(t){}return g},x=function(e,t){var n,r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(r){var i=r[1],c=r[2].substr(1).split(".").join(" "),s=y.makeMap("a,img");return r[1]?(n={title:t},e.schema.getTextBlockElements()[i]?n.block=i:e.schema.getBlockElements()[i]||s[i.toLowerCase()]?n.selector=i:n.inline=i):r[2]&&(n={inline:"span",title:t.substr(1),classes:c}),!1!==o(e)?n.classes=c:n.attributes={"class":c},n}},T=function(e,t){return null===t||!1!==n(e)},c=x,t=function(h){h.on("renderFormatsMenu",function(e){var t,p={},c=a(r(h)),v=e.control,s=(t=i(h),y.map(t,function(e){return y.extend({},e,{original:e,selectors:{},filter:a(e.filter),item:{text:e.title,menu:[]}})})),o=function(e,t){if(f=e,g=p,!(T(h,m=t)?f in g:f in m.selectors)){u=e,a=p,T(h,l=t)?a[u]=!0:l.selectors[u]=!0;var n=(c=(i=h).plugins.importcss,s=e,((o=t)&&o.selector_converter?o.selector_converter:_(i)?_(i):function(){return x(i,s)}).call(c,s,o));if(n){var r=n.name||d.DOM.uniqueId();return h.formatter.register(r,n),y.extend({},v.settings.itemDefaults,{text:n.title,format:r})}}var i,c,s,o,u,l,a,f,m,g;return null};u(h)||v.items().remove(),y.each(f(h,e.doc||h.getDoc(),a(l(h))),function(n){if(-1===n.indexOf(".mce-")&&(!c||c(n))){var e=(r=s,i=n,y.grep(r,function(e){return!e.filter||e.filter(i)}));if(0 0 ? formats[0] : getTimeFormat(editor); + }; + var shouldInsertTimeElement = function (editor) { + return editor.getParam('insertdatetime_element', false); + }; + var Settings = { + getDateFormat: getDateFormat, + getTimeFormat: getTimeFormat, + getFormats: getFormats, + getDefaultDateTime: getDefaultDateTime, + shouldInsertTimeElement: shouldInsertTimeElement + }; + + var daysShort = 'Sun Mon Tue Wed Thu Fri Sat Sun'.split(' '); + var daysLong = 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday'.split(' '); + var monthsShort = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '); + var monthsLong = 'January February March April May June July August September October November December'.split(' '); + var addZeros = function (value, len) { + value = '' + value; + if (value.length < len) { + for (var i = 0; i < len - value.length; i++) { + value = '0' + value; + } + } + return value; + }; + var getDateTime = function (editor, fmt, date) { + date = date || new Date(); + fmt = fmt.replace('%D', '%m/%d/%Y'); + fmt = fmt.replace('%r', '%I:%M:%S %p'); + fmt = fmt.replace('%Y', '' + date.getFullYear()); + fmt = fmt.replace('%y', '' + date.getYear()); + fmt = fmt.replace('%m', addZeros(date.getMonth() + 1, 2)); + fmt = fmt.replace('%d', addZeros(date.getDate(), 2)); + fmt = fmt.replace('%H', '' + addZeros(date.getHours(), 2)); + fmt = fmt.replace('%M', '' + addZeros(date.getMinutes(), 2)); + fmt = fmt.replace('%S', '' + addZeros(date.getSeconds(), 2)); + fmt = fmt.replace('%I', '' + ((date.getHours() + 11) % 12 + 1)); + fmt = fmt.replace('%p', '' + (date.getHours() < 12 ? 'AM' : 'PM')); + fmt = fmt.replace('%B', '' + editor.translate(monthsLong[date.getMonth()])); + fmt = fmt.replace('%b', '' + editor.translate(monthsShort[date.getMonth()])); + fmt = fmt.replace('%A', '' + editor.translate(daysLong[date.getDay()])); + fmt = fmt.replace('%a', '' + editor.translate(daysShort[date.getDay()])); + fmt = fmt.replace('%%', '%'); + return fmt; + }; + var updateElement = function (editor, timeElm, computerTime, userTime) { + var newTimeElm = editor.dom.create('time', { datetime: computerTime }, userTime); + timeElm.parentNode.insertBefore(newTimeElm, timeElm); + editor.dom.remove(timeElm); + editor.selection.select(newTimeElm, true); + editor.selection.collapse(false); + }; + var insertDateTime = function (editor, format) { + if (Settings.shouldInsertTimeElement(editor)) { + var userTime = getDateTime(editor, format); + var computerTime = void 0; + if (/%[HMSIp]/.test(format)) { + computerTime = getDateTime(editor, '%Y-%m-%dT%H:%M'); + } else { + computerTime = getDateTime(editor, '%Y-%m-%d'); + } + var timeElm = editor.dom.getParent(editor.selection.getStart(), 'time'); + if (timeElm) { + updateElement(editor, timeElm, computerTime, userTime); + } else { + editor.insertContent(''); + } + } else { + editor.insertContent(getDateTime(editor, format)); + } + }; + var Actions = { + insertDateTime: insertDateTime, + getDateTime: getDateTime + }; + + var register = function (editor) { + editor.addCommand('mceInsertDate', function () { + Actions.insertDateTime(editor, Settings.getDateFormat(editor)); + }); + editor.addCommand('mceInsertTime', function () { + Actions.insertDateTime(editor, Settings.getTimeFormat(editor)); + }); + }; + var Commands = { register: register }; + + var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); + + var createMenuItems = function (editor, lastFormatState) { + var formats = Settings.getFormats(editor); + return global$1.map(formats, function (fmt) { + return { + text: Actions.getDateTime(editor, fmt), + onclick: function () { + lastFormatState.set(fmt); + Actions.insertDateTime(editor, fmt); + } + }; + }); + }; + var register$1 = function (editor, lastFormatState) { + var menuItems = createMenuItems(editor, lastFormatState); + editor.addButton('insertdatetime', { + type: 'splitbutton', + title: 'Insert date/time', + menu: menuItems, + onclick: function () { + var lastFormat = lastFormatState.get(); + Actions.insertDateTime(editor, lastFormat ? lastFormat : Settings.getDefaultDateTime(editor)); + } + }); + editor.addMenuItem('insertdatetime', { + icon: 'date', + text: 'Date/time', + menu: menuItems, + context: 'insert' + }); + }; + var Buttons = { register: register$1 }; + + global.add('insertdatetime', function (editor) { + var lastFormatState = Cell(null); + Commands.register(editor); + Buttons.register(editor, lastFormatState); + }); + function Plugin () { + } + + return Plugin; + +}()); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/insertdatetime/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/insertdatetime/plugin.min.js new file mode 100644 index 0000000..b200240 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/insertdatetime/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";var r=function(e){var t=e,n=function(){return t};return{get:n,set:function(e){t=e},clone:function(){return r(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(e){return e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S"))},a=function(e){return e.getParam("insertdatetime_formats",["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"])},t=function(e){return e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d"))},i=n,o=a,u=function(e){var t=a(e);return 0'+n+"")}else e.insertContent(f(e,t));var i,o,u,c,l},y=f,M=function(e){e.addCommand("mceInsertDate",function(){g(e,t(e))}),e.addCommand("mceInsertTime",function(){g(e,i(e))})},v=tinymce.util.Tools.resolve("tinymce.util.Tools"),S=function(t,n){var r,a,e,i=(a=n,e=o(r=t),v.map(e,function(e){return{text:y(r,e),onclick:function(){a.set(e),g(r,e)}}}));t.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",menu:i,onclick:function(){var e=n.get();g(t,e||u(t))}}),t.addMenuItem("insertdatetime",{icon:"date",text:"Date/time",menu:i,context:"insert"})};e.add("insertdatetime",function(e){var t=r(null);M(e),S(e,t)})}(); \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/mce/link/plugin.js b/html/wp-content/plugins/tinymce-advanced/mce/link/plugin.js new file mode 100644 index 0000000..47d61c2 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/link/plugin.js @@ -0,0 +1,713 @@ +(function () { +var link = (function (domGlobals) { + 'use strict'; + + var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); + + var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK'); + + var assumeExternalTargets = function (editorSettings) { + return typeof editorSettings.link_assume_external_targets === 'boolean' ? editorSettings.link_assume_external_targets : false; + }; + var hasContextToolbar = function (editorSettings) { + return typeof editorSettings.link_context_toolbar === 'boolean' ? editorSettings.link_context_toolbar : false; + }; + var getLinkList = function (editorSettings) { + return editorSettings.link_list; + }; + var hasDefaultLinkTarget = function (editorSettings) { + return typeof editorSettings.default_link_target === 'string'; + }; + var getDefaultLinkTarget = function (editorSettings) { + return editorSettings.default_link_target; + }; + var getTargetList = function (editorSettings) { + return editorSettings.target_list; + }; + var setTargetList = function (editor, list) { + editor.settings.target_list = list; + }; + var shouldShowTargetList = function (editorSettings) { + return getTargetList(editorSettings) !== false; + }; + var getRelList = function (editorSettings) { + return editorSettings.rel_list; + }; + var hasRelList = function (editorSettings) { + return getRelList(editorSettings) !== undefined; + }; + var getLinkClassList = function (editorSettings) { + return editorSettings.link_class_list; + }; + var hasLinkClassList = function (editorSettings) { + return getLinkClassList(editorSettings) !== undefined; + }; + var shouldShowLinkTitle = function (editorSettings) { + return editorSettings.link_title !== false; + }; + var allowUnsafeLinkTarget = function (editorSettings) { + return typeof editorSettings.allow_unsafe_link_target === 'boolean' ? editorSettings.allow_unsafe_link_target : false; + }; + var Settings = { + assumeExternalTargets: assumeExternalTargets, + hasContextToolbar: hasContextToolbar, + getLinkList: getLinkList, + hasDefaultLinkTarget: hasDefaultLinkTarget, + getDefaultLinkTarget: getDefaultLinkTarget, + getTargetList: getTargetList, + setTargetList: setTargetList, + shouldShowTargetList: shouldShowTargetList, + getRelList: getRelList, + hasRelList: hasRelList, + getLinkClassList: getLinkClassList, + hasLinkClassList: hasLinkClassList, + shouldShowLinkTitle: shouldShowLinkTitle, + allowUnsafeLinkTarget: allowUnsafeLinkTarget + }; + + var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); + + var global$3 = tinymce.util.Tools.resolve('tinymce.Env'); + + var appendClickRemove = function (link, evt) { + domGlobals.document.body.appendChild(link); + link.dispatchEvent(evt); + domGlobals.document.body.removeChild(link); + }; + var open = function (url) { + if (!global$3.ie || global$3.ie > 10) { + var link = domGlobals.document.createElement('a'); + link.target = '_blank'; + link.href = url; + link.rel = 'noreferrer noopener'; + var evt = domGlobals.document.createEvent('MouseEvents'); + evt.initMouseEvent('click', true, true, domGlobals.window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + appendClickRemove(link, evt); + } else { + var win = domGlobals.window.open('', '_blank'); + if (win) { + win.opener = null; + var doc = win.document; + doc.open(); + doc.write(''); + doc.close(); + } + } + }; + var OpenUrl = { open: open }; + + var global$4 = tinymce.util.Tools.resolve('tinymce.util.Tools'); + + var toggleTargetRules = function (rel, isUnsafe) { + var rules = ['noopener']; + var newRel = rel ? rel.split(/\s+/) : []; + var toString = function (rel) { + return global$4.trim(rel.sort().join(' ')); + }; + var addTargetRules = function (rel) { + rel = removeTargetRules(rel); + return rel.length ? rel.concat(rules) : rules; + }; + var removeTargetRules = function (rel) { + return rel.filter(function (val) { + return global$4.inArray(rules, val) === -1; + }); + }; + newRel = isUnsafe ? addTargetRules(newRel) : removeTargetRules(newRel); + return newRel.length ? toString(newRel) : null; + }; + var trimCaretContainers = function (text) { + return text.replace(/\uFEFF/g, ''); + }; + var getAnchorElement = function (editor, selectedElm) { + selectedElm = selectedElm || editor.selection.getNode(); + if (isImageFigure(selectedElm)) { + return editor.dom.select('a[href]', selectedElm)[0]; + } else { + return editor.dom.getParent(selectedElm, 'a[href]'); + } + }; + var getAnchorText = function (selection, anchorElm) { + var text = anchorElm ? anchorElm.innerText || anchorElm.textContent : selection.getContent({ format: 'text' }); + return trimCaretContainers(text); + }; + var isLink = function (elm) { + return elm && elm.nodeName === 'A' && elm.href; + }; + var hasLinks = function (elements) { + return global$4.grep(elements, isLink).length > 0; + }; + var isOnlyTextSelected = function (html) { + if (/]+>[^<]+<\/a>$/.test(html) || html.indexOf('href=') === -1)) { + return false; + } + return true; + }; + var isImageFigure = function (node) { + return node && node.nodeName === 'FIGURE' && /\bimage\b/i.test(node.className); + }; + var link = function (editor, attachState) { + return function (data) { + editor.undoManager.transact(function () { + var selectedElm = editor.selection.getNode(); + var anchorElm = getAnchorElement(editor, selectedElm); + var linkAttrs = { + href: data.href, + target: data.target ? data.target : null, + rel: data.rel ? data.rel : null, + class: data.class ? data.class : null, + title: data.title ? data.title : null + }; + if (!Settings.hasRelList(editor.settings) && Settings.allowUnsafeLinkTarget(editor.settings) === false) { + linkAttrs.rel = toggleTargetRules(linkAttrs.rel, linkAttrs.target === '_blank'); + } + if (data.href === attachState.href) { + attachState.attach(); + attachState = {}; + } + if (anchorElm) { + editor.focus(); + if (data.hasOwnProperty('text')) { + if ('innerText' in anchorElm) { + anchorElm.innerText = data.text; + } else { + anchorElm.textContent = data.text; + } + } + editor.dom.setAttribs(anchorElm, linkAttrs); + editor.selection.select(anchorElm); + editor.undoManager.add(); + } else { + if (isImageFigure(selectedElm)) { + linkImageFigure(editor, selectedElm, linkAttrs); + } else if (data.hasOwnProperty('text')) { + editor.insertContent(editor.dom.createHTML('a', linkAttrs, editor.dom.encode(data.text))); + } else { + editor.execCommand('mceInsertLink', false, linkAttrs); + } + } + }); + }; + }; + var unlink = function (editor) { + return function () { + editor.undoManager.transact(function () { + var node = editor.selection.getNode(); + if (isImageFigure(node)) { + unlinkImageFigure(editor, node); + } else { + editor.execCommand('unlink'); + } + }); + }; + }; + var unlinkImageFigure = function (editor, fig) { + var a, img; + img = editor.dom.select('img', fig)[0]; + if (img) { + a = editor.dom.getParents(img, 'a[href]', fig)[0]; + if (a) { + a.parentNode.insertBefore(img, a); + editor.dom.remove(a); + } + } + }; + var linkImageFigure = function (editor, fig, attrs) { + var a, img; + img = editor.dom.select('img', fig)[0]; + if (img) { + a = editor.dom.create('a', attrs); + img.parentNode.insertBefore(a, img); + a.appendChild(img); + } + }; + var Utils = { + link: link, + unlink: unlink, + isLink: isLink, + hasLinks: hasLinks, + isOnlyTextSelected: isOnlyTextSelected, + getAnchorElement: getAnchorElement, + getAnchorText: getAnchorText, + toggleTargetRules: toggleTargetRules + }; + + var global$5 = tinymce.util.Tools.resolve('tinymce.util.Delay'); + + var global$6 = tinymce.util.Tools.resolve('tinymce.util.XHR'); + + var attachState = {}; + var createLinkList = function (editor, callback) { + var linkList = Settings.getLinkList(editor.settings); + if (typeof linkList === 'string') { + global$6.send({ + url: linkList, + success: function (text) { + callback(editor, JSON.parse(text)); + } + }); + } else if (typeof linkList === 'function') { + linkList(function (list) { + callback(editor, list); + }); + } else { + callback(editor, linkList); + } + }; + var buildListItems = function (inputList, itemCallback, startItems) { + var appendItems = function (values, output) { + output = output || []; + global$4.each(values, function (item) { + var menuItem = { text: item.text || item.title }; + if (item.menu) { + menuItem.menu = appendItems(item.menu); + } else { + menuItem.value = item.value; + if (itemCallback) { + itemCallback(menuItem); + } + } + output.push(menuItem); + }); + return output; + }; + return appendItems(inputList, startItems || []); + }; + var delayedConfirm = function (editor, message, callback) { + var rng = editor.selection.getRng(); + global$5.setEditorTimeout(editor, function () { + editor.windowManager.confirm(message, function (state) { + editor.selection.setRng(rng); + callback(state); + }); + }); + }; + var showDialog = function (editor, linkList) { + var data = {}; + var selection = editor.selection; + var dom = editor.dom; + var anchorElm, initialText; + var win, onlyText, textListCtrl, linkListCtrl, relListCtrl, targetListCtrl, classListCtrl, linkTitleCtrl, value; + var linkListChangeHandler = function (e) { + var textCtrl = win.find('#text'); + if (!textCtrl.value() || e.lastControl && textCtrl.value() === e.lastControl.text()) { + textCtrl.value(e.control.text()); + } + win.find('#href').value(e.control.value()); + }; + var buildAnchorListControl = function (url) { + var anchorList = []; + global$4.each(editor.dom.select('a:not([href])'), function (anchor) { + var id = anchor.name || anchor.id; + if (id) { + anchorList.push({ + text: id, + value: '#' + id, + selected: url.indexOf('#' + id) !== -1 + }); + } + }); + if (anchorList.length) { + anchorList.unshift({ + text: 'None', + value: '' + }); + return { + name: 'anchor', + type: 'listbox', + label: 'Anchors', + values: anchorList, + onselect: linkListChangeHandler + }; + } + }; + var updateText = function () { + if (!initialText && onlyText && !data.text) { + this.parent().parent().find('#text')[0].value(this.value()); + } + }; + var urlChange = function (e) { + var meta = e.meta || {}; + if (linkListCtrl) { + linkListCtrl.value(editor.convertURL(this.value(), 'href')); + } + global$4.each(e.meta, function (value, key) { + var inp = win.find('#' + key); + if (key === 'text') { + if (initialText.length === 0) { + inp.value(value); + data.text = value; + } + } else { + inp.value(value); + } + }); + if (meta.attach) { + attachState = { + href: this.value(), + attach: meta.attach + }; + } + if (!meta.text) { + updateText.call(this); + } + }; + var onBeforeCall = function (e) { + e.meta = win.toJSON(); + }; + onlyText = Utils.isOnlyTextSelected(selection.getContent()); + anchorElm = Utils.getAnchorElement(editor); + data.text = initialText = Utils.getAnchorText(editor.selection, anchorElm); + data.href = anchorElm ? dom.getAttrib(anchorElm, 'href') : ''; + if (anchorElm) { + data.target = dom.getAttrib(anchorElm, 'target'); + } else if (Settings.hasDefaultLinkTarget(editor.settings)) { + data.target = Settings.getDefaultLinkTarget(editor.settings); + } + if (value = dom.getAttrib(anchorElm, 'rel')) { + data.rel = value; + } + if (value = dom.getAttrib(anchorElm, 'class')) { + data.class = value; + } + if (value = dom.getAttrib(anchorElm, 'title')) { + data.title = value; + } + if (onlyText) { + textListCtrl = { + name: 'text', + type: 'textbox', + size: 40, + label: 'Text to display', + onchange: function () { + data.text = this.value(); + } + }; + } + if (linkList) { + linkListCtrl = { + type: 'listbox', + label: 'Link list', + values: buildListItems(linkList, function (item) { + item.value = editor.convertURL(item.value || item.url, 'href'); + }, [{ + text: 'None', + value: '' + }]), + onselect: linkListChangeHandler, + value: editor.convertURL(data.href, 'href'), + onPostRender: function () { + linkListCtrl = this; + } + }; + } + if (Settings.shouldShowTargetList(editor.settings)) { + if (Settings.getTargetList(editor.settings) === undefined) { + Settings.setTargetList(editor, [ + { + text: 'None', + value: '' + }, + { + text: 'New window', + value: '_blank' + } + ]); + } + targetListCtrl = { + name: 'target', + type: 'listbox', + label: 'Target', + values: buildListItems(Settings.getTargetList(editor.settings)) + }; + } + if (Settings.hasRelList(editor.settings)) { + relListCtrl = { + name: 'rel', + type: 'listbox', + label: 'Rel', + values: buildListItems(Settings.getRelList(editor.settings), function (item) { + if (Settings.allowUnsafeLinkTarget(editor.settings) === false) { + item.value = Utils.toggleTargetRules(item.value, data.target === '_blank'); + } + }) + }; + } + if (Settings.hasLinkClassList(editor.settings)) { + classListCtrl = { + name: 'class', + type: 'listbox', + label: 'Class', + values: buildListItems(Settings.getLinkClassList(editor.settings), function (item) { + if (item.value) { + item.textStyle = function () { + return editor.formatter.getCssText({ + inline: 'a', + classes: [item.value] + }); + }; + } + }) + }; + } + if (Settings.shouldShowLinkTitle(editor.settings)) { + linkTitleCtrl = { + name: 'title', + type: 'textbox', + label: 'Title', + value: data.title + }; + } + win = editor.windowManager.open({ + title: 'Insert link', + data: data, + body: [ + { + name: 'href', + type: 'filepicker', + filetype: 'file', + size: 40, + autofocus: true, + label: 'Url', + onchange: urlChange, + onkeyup: updateText, + onpaste: updateText, + onbeforecall: onBeforeCall + }, + textListCtrl, + linkTitleCtrl, + buildAnchorListControl(data.href), + linkListCtrl, + relListCtrl, + targetListCtrl, + classListCtrl + ], + onSubmit: function (e) { + var assumeExternalTargets = Settings.assumeExternalTargets(editor.settings); + var insertLink = Utils.link(editor, attachState); + var removeLink = Utils.unlink(editor); + var resultData = global$4.extend({}, data, e.data); + var href = resultData.href; + if (!href) { + removeLink(); + return; + } + if (!onlyText || resultData.text === initialText) { + delete resultData.text; + } + if (href.indexOf('@') > 0 && href.indexOf('//') === -1 && href.indexOf('mailto:') === -1) { + delayedConfirm(editor, 'The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?', function (state) { + if (state) { + resultData.href = 'mailto:' + href; + } + insertLink(resultData); + }); + return; + } + if (assumeExternalTargets === true && !/^\w+:/i.test(href) || assumeExternalTargets === false && /^\s*www[\.|\d\.]/i.test(href)) { + delayedConfirm(editor, 'The URL you entered seems to be an external link. Do you want to add the required http:// prefix?', function (state) { + if (state) { + resultData.href = 'http://' + href; + } + insertLink(resultData); + }); + return; + } + insertLink(resultData); + } + }); + }; + var open$1 = function (editor) { + createLinkList(editor, showDialog); + }; + var Dialog = { open: open$1 }; + + var getLink = function (editor, elm) { + return editor.dom.getParent(elm, 'a[href]'); + }; + var getSelectedLink = function (editor) { + return getLink(editor, editor.selection.getStart()); + }; + var getHref = function (elm) { + var href = elm.getAttribute('data-mce-href'); + return href ? href : elm.getAttribute('href'); + }; + var isContextMenuVisible = function (editor) { + var contextmenu = editor.plugins.contextmenu; + return contextmenu ? contextmenu.isContextMenuVisible() : false; + }; + var hasOnlyAltModifier = function (e) { + return e.altKey === true && e.shiftKey === false && e.ctrlKey === false && e.metaKey === false; + }; + var gotoLink = function (editor, a) { + if (a) { + var href = getHref(a); + if (/^#/.test(href)) { + var targetEl = editor.$(href); + if (targetEl.length) { + editor.selection.scrollIntoView(targetEl[0], true); + } + } else { + OpenUrl.open(a.href); + } + } + }; + var openDialog = function (editor) { + return function () { + Dialog.open(editor); + }; + }; + var gotoSelectedLink = function (editor) { + return function () { + gotoLink(editor, getSelectedLink(editor)); + }; + }; + var leftClickedOnAHref = function (editor) { + return function (elm) { + var sel, rng, node; + if (Settings.hasContextToolbar(editor.settings) && !isContextMenuVisible(editor) && Utils.isLink(elm)) { + sel = editor.selection; + rng = sel.getRng(); + node = rng.startContainer; + if (node.nodeType === 3 && sel.isCollapsed() && rng.startOffset > 0 && rng.startOffset < node.data.length) { + return true; + } + } + return false; + }; + }; + var setupGotoLinks = function (editor) { + editor.on('click', function (e) { + var link = getLink(editor, e.target); + if (link && global$1.metaKeyPressed(e)) { + e.preventDefault(); + gotoLink(editor, link); + } + }); + editor.on('keydown', function (e) { + var link = getSelectedLink(editor); + if (link && e.keyCode === 13 && hasOnlyAltModifier(e)) { + e.preventDefault(); + gotoLink(editor, link); + } + }); + }; + var toggleActiveState = function (editor) { + return function () { + var self = this; + editor.on('nodechange', function (e) { + self.active(!editor.readonly && !!Utils.getAnchorElement(editor, e.element)); + }); + }; + }; + var toggleViewLinkState = function (editor) { + return function () { + var self = this; + var toggleVisibility = function (e) { + if (Utils.hasLinks(e.parents)) { + self.show(); + } else { + self.hide(); + } + }; + if (!Utils.hasLinks(editor.dom.getParents(editor.selection.getStart()))) { + self.hide(); + } + editor.on('nodechange', toggleVisibility); + self.on('remove', function () { + editor.off('nodechange', toggleVisibility); + }); + }; + }; + var Actions = { + openDialog: openDialog, + gotoSelectedLink: gotoSelectedLink, + leftClickedOnAHref: leftClickedOnAHref, + setupGotoLinks: setupGotoLinks, + toggleActiveState: toggleActiveState, + toggleViewLinkState: toggleViewLinkState + }; + + var register = function (editor) { + editor.addCommand('mceLink', Actions.openDialog(editor)); + }; + var Commands = { register: register }; + + var setup = function (editor) { + editor.addShortcut('Meta+K', '', Actions.openDialog(editor)); + }; + var Keyboard = { setup: setup }; + + var setupButtons = function (editor) { + editor.addButton('link', { + active: false, + icon: 'link', + tooltip: 'Insert/edit link', + onclick: Actions.openDialog(editor), + onpostrender: Actions.toggleActiveState(editor) + }); + editor.addButton('unlink', { + active: false, + icon: 'unlink', + tooltip: 'Remove link', + onclick: Utils.unlink(editor), + onpostrender: Actions.toggleActiveState(editor) + }); + if (editor.addContextToolbar) { + editor.addButton('openlink', { + icon: 'newtab', + tooltip: 'Open link', + onclick: Actions.gotoSelectedLink(editor) + }); + } + }; + var setupMenuItems = function (editor) { + editor.addMenuItem('openlink', { + text: 'Open link', + icon: 'newtab', + onclick: Actions.gotoSelectedLink(editor), + onPostRender: Actions.toggleViewLinkState(editor), + prependToContext: true + }); + editor.addMenuItem('link', { + icon: 'link', + text: 'Link', + shortcut: 'Meta+K', + onclick: Actions.openDialog(editor), + stateSelector: 'a[href]', + context: 'insert', + prependToContext: true + }); + editor.addMenuItem('unlink', { + icon: 'unlink', + text: 'Remove link', + onclick: Utils.unlink(editor), + stateSelector: 'a[href]' + }); + }; + var setupContextToolbars = function (editor) { + if (editor.addContextToolbar) { + editor.addContextToolbar(Actions.leftClickedOnAHref(editor), 'openlink | link unlink'); + } + }; + var Controls = { + setupButtons: setupButtons, + setupMenuItems: setupMenuItems, + setupContextToolbars: setupContextToolbars + }; + + global.add('link', function (editor) { + Controls.setupButtons(editor); + Controls.setupMenuItems(editor); + Controls.setupContextToolbars(editor); + Actions.setupGotoLinks(editor); + Commands.register(editor); + Keyboard.setup(editor); + }); + function Plugin () { + } + + return Plugin; + +}(window)); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/link/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/link/plugin.min.js new file mode 100644 index 0000000..e07a912 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/link/plugin.min.js @@ -0,0 +1 @@ +!function(l){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.util.VK"),e=function(t){return t.target_list},o=function(t){return t.rel_list},i=function(t){return t.link_class_list},p=function(t){return"boolean"==typeof t.link_assume_external_targets&&t.link_assume_external_targets},a=function(t){return"boolean"==typeof t.link_context_toolbar&&t.link_context_toolbar},r=function(t){return t.link_list},k=function(t){return"string"==typeof t.default_link_target},y=function(t){return t.default_link_target},b=e,_=function(t,e){t.settings.target_list=e},w=function(t){return!1!==e(t)},T=o,C=function(t){return o(t)!==undefined},M=i,O=function(t){return i(t)!==undefined},R=function(t){return!1!==t.link_title},N=function(t){return"boolean"==typeof t.allow_unsafe_link_target&&t.allow_unsafe_link_target},u=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),c=tinymce.util.Tools.resolve("tinymce.Env"),s=function(t){if(!c.ie||10'),i.close()}}var r,a},A=tinymce.util.Tools.resolve("tinymce.util.Tools"),f=function(t,e){var n,o,i=["noopener"],r=t?t.split(/\s+/):[],a=function(t){return t.filter(function(t){return-1===A.inArray(i,t)})};return(r=e?(n=a(n=r)).length?n.concat(i):i:a(r)).length?(o=r,A.trim(o.sort().join(" "))):null},d=function(t,e){return e=e||t.selection.getNode(),v(e)?t.dom.select("a[href]",e)[0]:t.dom.getParent(e,"a[href]")},m=function(t){return t&&"A"===t.nodeName&&t.href},v=function(t){return t&&"FIGURE"===t.nodeName&&/\bimage\b/i.test(t.className)},g=function(t,e){var n,o;(o=t.dom.select("img",e)[0])&&(n=t.dom.getParents(o,"a[href]",e)[0])&&(n.parentNode.insertBefore(o,n),t.dom.remove(n))},h=function(t,e,n){var o,i;(i=t.dom.select("img",e)[0])&&(o=t.dom.create("a",n),i.parentNode.insertBefore(o,i),o.appendChild(i))},L=function(i,r){return function(o){i.undoManager.transact(function(){var t=i.selection.getNode(),e=d(i,t),n={href:o.href,target:o.target?o.target:null,rel:o.rel?o.rel:null,"class":o["class"]?o["class"]:null,title:o.title?o.title:null};C(i.settings)||!1!==N(i.settings)||(n.rel=f(n.rel,"_blank"===n.target)),o.href===r.href&&(r.attach(),r={}),e?(i.focus(),o.hasOwnProperty("text")&&("innerText"in e?e.innerText=o.text:e.textContent=o.text),i.dom.setAttribs(e,n),i.selection.select(e),i.undoManager.add()):v(t)?h(i,t,n):o.hasOwnProperty("text")?i.insertContent(i.dom.createHTML("a",n,i.dom.encode(o.text))):i.execCommand("mceInsertLink",!1,n)})}},P=function(e){return function(){e.undoManager.transact(function(){var t=e.selection.getNode();v(t)?g(e,t):e.execCommand("unlink")})}},x=m,E=function(t){return 0]+>[^<]+<\/a>$/.test(t)||-1===t.indexOf("href=")))},I=d,K=function(t,e){var n=e?e.innerText||e.textContent:t.getContent({format:"text"});return n.replace(/\uFEFF/g,"")},U=f,D=tinymce.util.Tools.resolve("tinymce.util.Delay"),B=tinymce.util.Tools.resolve("tinymce.util.XHR"),F={},q=function(t,o,e){var i=function(t,n){return n=n||[],A.each(t,function(t){var e={text:t.text||t.title};t.menu?e.menu=i(t.menu):(e.value=t.value,o&&o(e)),n.push(e)}),n};return i(t,e||[])},V=function(e,t,n){var o=e.selection.getRng();D.setEditorTimeout(e,function(){e.windowManager.confirm(t,function(t){e.selection.setRng(o),n(t)})})},z=function(a,t){var e,l,o,u,n,i,r,c,s,f,d,m={},v=a.selection,g=a.dom,h=function(t){var e=o.find("#text");(!e.value()||t.lastControl&&e.value()===t.lastControl.text())&&e.value(t.control.text()),o.find("#href").value(t.control.value())},x=function(){l||!u||m.text||this.parent().parent().find("#text")[0].value(this.value())};u=S(v.getContent()),e=I(a),m.text=l=K(a.selection,e),m.href=e?g.getAttrib(e,"href"):"",e?m.target=g.getAttrib(e,"target"):k(a.settings)&&(m.target=y(a.settings)),(d=g.getAttrib(e,"rel"))&&(m.rel=d),(d=g.getAttrib(e,"class"))&&(m["class"]=d),(d=g.getAttrib(e,"title"))&&(m.title=d),u&&(n={name:"text",type:"textbox",size:40,label:"Text to display",onchange:function(){m.text=this.value()}}),t&&(i={type:"listbox",label:"Link list",values:q(t,function(t){t.value=a.convertURL(t.value||t.url,"href")},[{text:"None",value:""}]),onselect:h,value:a.convertURL(m.href,"href"),onPostRender:function(){i=this}}),w(a.settings)&&(b(a.settings)===undefined&&_(a,[{text:"None",value:""},{text:"New window",value:"_blank"}]),c={name:"target",type:"listbox",label:"Target",values:q(b(a.settings))}),C(a.settings)&&(r={name:"rel",type:"listbox",label:"Rel",values:q(T(a.settings),function(t){!1===N(a.settings)&&(t.value=U(t.value,"_blank"===m.target))})}),O(a.settings)&&(s={name:"class",type:"listbox",label:"Class",values:q(M(a.settings),function(t){t.value&&(t.textStyle=function(){return a.formatter.getCssText({inline:"a",classes:[t.value]})})})}),R(a.settings)&&(f={name:"title",type:"textbox",label:"Title",value:m.title}),o=a.windowManager.open({title:"Insert link",data:m,body:[{name:"href",type:"filepicker",filetype:"file",size:40,autofocus:!0,label:"Url",onchange:function(t){var e=t.meta||{};i&&i.value(a.convertURL(this.value(),"href")),A.each(t.meta,function(t,e){var n=o.find("#"+e);"text"===e?0===l.length&&(n.value(t),m.text=t):n.value(t)}),e.attach&&(F={href:this.value(),attach:e.attach}),e.text||x.call(this)},onkeyup:x,onpaste:x,onbeforecall:function(t){t.meta=o.toJSON()}},n,f,function(n){var o=[];if(A.each(a.dom.select("a:not([href])"),function(t){var e=t.name||t.id;e&&o.push({text:e,value:"#"+e,selected:-1!==n.indexOf("#"+e)})}),o.length)return o.unshift({text:"None",value:""}),{name:"anchor",type:"listbox",label:"Anchors",values:o,onselect:h}}(m.href),i,r,c,s],onSubmit:function(t){var e=p(a.settings),n=L(a,F),o=P(a),i=A.extend({},m,t.data),r=i.href;r?(u&&i.text!==l||delete i.text,0 ' : ' '; + editor.insertContent(stringRepeat(nbsp, times)); + editor.dom.setAttrib(editor.dom.select('span.mce-nbsp'), 'data-mce-bogus', '1'); + }; + var Actions = { insertNbsp: insertNbsp }; + + var register = function (editor) { + editor.addCommand('mceNonBreaking', function () { + Actions.insertNbsp(editor, 1); + }); + }; + var Commands = { register: register }; + + var global$1 = tinymce.util.Tools.resolve('tinymce.util.VK'); + + var getKeyboardSpaces = function (editor) { + var spaces = editor.getParam('nonbreaking_force_tab', 0); + if (typeof spaces === 'boolean') { + return spaces === true ? 3 : 0; + } else { + return spaces; + } + }; + var Settings = { getKeyboardSpaces: getKeyboardSpaces }; + + var setup = function (editor) { + var spaces = Settings.getKeyboardSpaces(editor); + if (spaces > 0) { + editor.on('keydown', function (e) { + if (e.keyCode === global$1.TAB && !e.isDefaultPrevented()) { + if (e.shiftKey) { + return; + } + e.preventDefault(); + e.stopImmediatePropagation(); + Actions.insertNbsp(editor, spaces); + } + }); + } + }; + var Keyboard = { setup: setup }; + + var register$1 = function (editor) { + editor.addButton('nonbreaking', { + title: 'Nonbreaking space', + cmd: 'mceNonBreaking' + }); + editor.addMenuItem('nonbreaking', { + icon: 'nonbreaking', + text: 'Nonbreaking space', + cmd: 'mceNonBreaking', + context: 'insert' + }); + }; + var Buttons = { register: register$1 }; + + global.add('nonbreaking', function (editor) { + Commands.register(editor); + Buttons.register(editor); + Keyboard.setup(editor); + }); + function Plugin () { + } + + return Plugin; + +}()); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/nonbreaking/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/nonbreaking/plugin.min.js new file mode 100644 index 0000000..084d9b2 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/nonbreaking/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(n,e){var t,i=(t=n).plugins.visualchars&&t.plugins.visualchars.isEnabled()?' ':" ";n.insertContent(function(n,e){for(var t="",i=0;i 0) { + var cg = m[captureGroup]; + if (!cg) { + throw new Error('Invalid capture group'); + } + index += m[0].indexOf(cg); + m[0] = cg; + } + return [ + index, + index + m[0].length, + [m[0]] + ]; + } + function getText(node) { + var txt; + if (node.nodeType === 3) { + return node.data; + } + if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) { + return ''; + } + txt = ''; + if (isContentEditableFalse(node)) { + return '\n'; + } + if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) { + txt += '\n'; + } + if (node = node.firstChild) { + do { + txt += getText(node); + } while (node = node.nextSibling); + } + return txt; + } + function stepThroughMatches(node, matches, replaceFn) { + var startNode, endNode, startNodeIndex, endNodeIndex, innerNodes = [], atIndex = 0, curNode = node, matchLocation = matches.shift(), matchIndex = 0; + out: + while (true) { + if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName] || isContentEditableFalse(curNode)) { + atIndex++; + } + if (curNode.nodeType === 3) { + if (!endNode && curNode.length + atIndex >= matchLocation[1]) { + endNode = curNode; + endNodeIndex = matchLocation[1] - atIndex; + } else if (startNode) { + innerNodes.push(curNode); + } + if (!startNode && curNode.length + atIndex > matchLocation[0]) { + startNode = curNode; + startNodeIndex = matchLocation[0] - atIndex; + } + atIndex += curNode.length; + } + if (startNode && endNode) { + curNode = replaceFn({ + startNode: startNode, + startNodeIndex: startNodeIndex, + endNode: endNode, + endNodeIndex: endNodeIndex, + innerNodes: innerNodes, + match: matchLocation[2], + matchIndex: matchIndex + }); + atIndex -= endNode.length - endNodeIndex; + startNode = null; + endNode = null; + innerNodes = []; + matchLocation = matches.shift(); + matchIndex++; + if (!matchLocation) { + break; + } + } else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) { + if (!isContentEditableFalse(curNode)) { + curNode = curNode.firstChild; + continue; + } + } else if (curNode.nextSibling) { + curNode = curNode.nextSibling; + continue; + } + while (true) { + if (curNode.nextSibling) { + curNode = curNode.nextSibling; + break; + } else if (curNode.parentNode !== node) { + curNode = curNode.parentNode; + } else { + break out; + } + } + } + } + function genReplacer(nodeName) { + var makeReplacementNode; + if (typeof nodeName !== 'function') { + var stencilNode_1 = nodeName.nodeType ? nodeName : doc.createElement(nodeName); + makeReplacementNode = function (fill, matchIndex) { + var clone = stencilNode_1.cloneNode(false); + clone.setAttribute('data-mce-index', matchIndex); + if (fill) { + clone.appendChild(doc.createTextNode(fill)); + } + return clone; + }; + } else { + makeReplacementNode = nodeName; + } + return function (range) { + var before; + var after; + var parentNode; + var startNode = range.startNode; + var endNode = range.endNode; + var matchIndex = range.matchIndex; + if (startNode === endNode) { + var node_1 = startNode; + parentNode = node_1.parentNode; + if (range.startNodeIndex > 0) { + before = doc.createTextNode(node_1.data.substring(0, range.startNodeIndex)); + parentNode.insertBefore(before, node_1); + } + var el = makeReplacementNode(range.match[0], matchIndex); + parentNode.insertBefore(el, node_1); + if (range.endNodeIndex < node_1.length) { + after = doc.createTextNode(node_1.data.substring(range.endNodeIndex)); + parentNode.insertBefore(after, node_1); + } + node_1.parentNode.removeChild(node_1); + return el; + } + before = doc.createTextNode(startNode.data.substring(0, range.startNodeIndex)); + after = doc.createTextNode(endNode.data.substring(range.endNodeIndex)); + var elA = makeReplacementNode(startNode.data.substring(range.startNodeIndex), matchIndex); + for (var i = 0, l = range.innerNodes.length; i < l; ++i) { + var innerNode = range.innerNodes[i]; + var innerEl = makeReplacementNode(innerNode.data, matchIndex); + innerNode.parentNode.replaceChild(innerEl, innerNode); + } + var elB = makeReplacementNode(endNode.data.substring(0, range.endNodeIndex), matchIndex); + parentNode = startNode.parentNode; + parentNode.insertBefore(before, startNode); + parentNode.insertBefore(elA, startNode); + parentNode.removeChild(startNode); + parentNode = endNode.parentNode; + parentNode.insertBefore(elB, endNode); + parentNode.insertBefore(after, endNode); + parentNode.removeChild(endNode); + return elB; + }; + } + text = getText(node); + if (!text) { + return; + } + if (regex.global) { + while (m = regex.exec(text)) { + matches.push(getMatchIndexes(m, captureGroup)); + } + } else { + m = text.match(regex); + matches.push(getMatchIndexes(m, captureGroup)); + } + if (matches.length) { + count = matches.length; + stepThroughMatches(node, matches, genReplacer(replacementNode)); + } + return count; + } + var FindReplaceText = { findAndReplaceDOMText: findAndReplaceDOMText }; + + var getElmIndex = function (elm) { + var value = elm.getAttribute('data-mce-index'); + if (typeof value === 'number') { + return '' + value; + } + return value; + }; + var markAllMatches = function (editor, currentIndexState, regex) { + var node, marker; + marker = editor.dom.create('span', { 'data-mce-bogus': 1 }); + marker.className = 'mce-match-marker'; + node = editor.getBody(); + done(editor, currentIndexState, false); + return FindReplaceText.findAndReplaceDOMText(regex, node, marker, false, editor.schema); + }; + var unwrap = function (node) { + var parentNode = node.parentNode; + if (node.firstChild) { + parentNode.insertBefore(node.firstChild, node); + } + node.parentNode.removeChild(node); + }; + var findSpansByIndex = function (editor, index) { + var nodes; + var spans = []; + nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); + if (nodes.length) { + for (var i = 0; i < nodes.length; i++) { + var nodeIndex = getElmIndex(nodes[i]); + if (nodeIndex === null || !nodeIndex.length) { + continue; + } + if (nodeIndex === index.toString()) { + spans.push(nodes[i]); + } + } + } + return spans; + }; + var moveSelection = function (editor, currentIndexState, forward) { + var testIndex = currentIndexState.get(); + var dom = editor.dom; + forward = forward !== false; + if (forward) { + testIndex++; + } else { + testIndex--; + } + dom.removeClass(findSpansByIndex(editor, currentIndexState.get()), 'mce-match-marker-selected'); + var spans = findSpansByIndex(editor, testIndex); + if (spans.length) { + dom.addClass(findSpansByIndex(editor, testIndex), 'mce-match-marker-selected'); + editor.selection.scrollIntoView(spans[0]); + return testIndex; + } + return -1; + }; + var removeNode = function (dom, node) { + var parent = node.parentNode; + dom.remove(node); + if (dom.isEmpty(parent)) { + dom.remove(parent); + } + }; + var find = function (editor, currentIndexState, text, matchCase, wholeWord) { + text = text.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); + text = text.replace(/\s/g, '[^\\S\\r\\n]'); + text = wholeWord ? '\\b' + text + '\\b' : text; + var count = markAllMatches(editor, currentIndexState, new RegExp(text, matchCase ? 'g' : 'gi')); + if (count) { + currentIndexState.set(-1); + currentIndexState.set(moveSelection(editor, currentIndexState, true)); + } + return count; + }; + var next = function (editor, currentIndexState) { + var index = moveSelection(editor, currentIndexState, true); + if (index !== -1) { + currentIndexState.set(index); + } + }; + var prev = function (editor, currentIndexState) { + var index = moveSelection(editor, currentIndexState, false); + if (index !== -1) { + currentIndexState.set(index); + } + }; + var isMatchSpan = function (node) { + var matchIndex = getElmIndex(node); + return matchIndex !== null && matchIndex.length > 0; + }; + var replace = function (editor, currentIndexState, text, forward, all) { + var i, nodes, node, matchIndex, currentMatchIndex, nextIndex = currentIndexState.get(), hasMore; + forward = forward !== false; + node = editor.getBody(); + nodes = global$1.grep(global$1.toArray(node.getElementsByTagName('span')), isMatchSpan); + for (i = 0; i < nodes.length; i++) { + var nodeIndex = getElmIndex(nodes[i]); + matchIndex = currentMatchIndex = parseInt(nodeIndex, 10); + if (all || matchIndex === currentIndexState.get()) { + if (text.length) { + nodes[i].firstChild.nodeValue = text; + unwrap(nodes[i]); + } else { + removeNode(editor.dom, nodes[i]); + } + while (nodes[++i]) { + matchIndex = parseInt(getElmIndex(nodes[i]), 10); + if (matchIndex === currentMatchIndex) { + removeNode(editor.dom, nodes[i]); + } else { + i--; + break; + } + } + if (forward) { + nextIndex--; + } + } else if (currentMatchIndex > currentIndexState.get()) { + nodes[i].setAttribute('data-mce-index', currentMatchIndex - 1); + } + } + currentIndexState.set(nextIndex); + if (forward) { + hasMore = hasNext(editor, currentIndexState); + next(editor, currentIndexState); + } else { + hasMore = hasPrev(editor, currentIndexState); + prev(editor, currentIndexState); + } + return !all && hasMore; + }; + var done = function (editor, currentIndexState, keepEditorSelection) { + var i, nodes, startContainer, endContainer; + nodes = global$1.toArray(editor.getBody().getElementsByTagName('span')); + for (i = 0; i < nodes.length; i++) { + var nodeIndex = getElmIndex(nodes[i]); + if (nodeIndex !== null && nodeIndex.length) { + if (nodeIndex === currentIndexState.get().toString()) { + if (!startContainer) { + startContainer = nodes[i].firstChild; + } + endContainer = nodes[i].firstChild; + } + unwrap(nodes[i]); + } + } + if (startContainer && endContainer) { + var rng = editor.dom.createRng(); + rng.setStart(startContainer, 0); + rng.setEnd(endContainer, endContainer.data.length); + if (keepEditorSelection !== false) { + editor.selection.setRng(rng); + } + return rng; + } + }; + var hasNext = function (editor, currentIndexState) { + return findSpansByIndex(editor, currentIndexState.get() + 1).length > 0; + }; + var hasPrev = function (editor, currentIndexState) { + return findSpansByIndex(editor, currentIndexState.get() - 1).length > 0; + }; + var Actions = { + done: done, + find: find, + next: next, + prev: prev, + replace: replace, + hasNext: hasNext, + hasPrev: hasPrev + }; + + var get = function (editor, currentIndexState) { + var done = function (keepEditorSelection) { + return Actions.done(editor, currentIndexState, keepEditorSelection); + }; + var find = function (text, matchCase, wholeWord) { + return Actions.find(editor, currentIndexState, text, matchCase, wholeWord); + }; + var next = function () { + return Actions.next(editor, currentIndexState); + }; + var prev = function () { + return Actions.prev(editor, currentIndexState); + }; + var replace = function (text, forward, all) { + return Actions.replace(editor, currentIndexState, text, forward, all); + }; + return { + done: done, + find: find, + next: next, + prev: prev, + replace: replace + }; + }; + var Api = { get: get }; + + var open = function (editor, currentIndexState) { + var last = {}, selectedText; + editor.undoManager.add(); + selectedText = global$1.trim(editor.selection.getContent({ format: 'text' })); + function updateButtonStates() { + win.statusbar.find('#next').disabled(Actions.hasNext(editor, currentIndexState) === false); + win.statusbar.find('#prev').disabled(Actions.hasPrev(editor, currentIndexState) === false); + } + function notFoundAlert() { + editor.windowManager.alert('Could not find the specified string.', function () { + win.find('#find')[0].focus(); + }); + } + var win = editor.windowManager.open({ + layout: 'flex', + pack: 'center', + align: 'center', + onClose: function () { + editor.focus(); + Actions.done(editor, currentIndexState); + editor.undoManager.add(); + }, + onSubmit: function (e) { + var count, caseState, text, wholeWord; + e.preventDefault(); + caseState = win.find('#case').checked(); + wholeWord = win.find('#words').checked(); + text = win.find('#find').value(); + if (!text.length) { + Actions.done(editor, currentIndexState, false); + win.statusbar.items().slice(1).disabled(true); + return; + } + if (last.text === text && last.caseState === caseState && last.wholeWord === wholeWord) { + if (!Actions.hasNext(editor, currentIndexState)) { + notFoundAlert(); + return; + } + Actions.next(editor, currentIndexState); + updateButtonStates(); + return; + } + count = Actions.find(editor, currentIndexState, text, caseState, wholeWord); + if (!count) { + notFoundAlert(); + } + win.statusbar.items().slice(1).disabled(count === 0); + updateButtonStates(); + last = { + text: text, + caseState: caseState, + wholeWord: wholeWord + }; + }, + buttons: [ + { + text: 'Find', + subtype: 'primary', + onclick: function () { + win.submit(); + } + }, + { + text: 'Replace', + disabled: true, + onclick: function () { + if (!Actions.replace(editor, currentIndexState, win.find('#replace').value())) { + win.statusbar.items().slice(1).disabled(true); + currentIndexState.set(-1); + last = {}; + } + } + }, + { + text: 'Replace all', + disabled: true, + onclick: function () { + Actions.replace(editor, currentIndexState, win.find('#replace').value(), true, true); + win.statusbar.items().slice(1).disabled(true); + last = {}; + } + }, + { + type: 'spacer', + flex: 1 + }, + { + text: 'Prev', + name: 'prev', + disabled: true, + onclick: function () { + Actions.prev(editor, currentIndexState); + updateButtonStates(); + } + }, + { + text: 'Next', + name: 'next', + disabled: true, + onclick: function () { + Actions.next(editor, currentIndexState); + updateButtonStates(); + } + } + ], + title: 'Find and replace', + items: { + type: 'form', + padding: 20, + labelGap: 30, + spacing: 10, + items: [ + { + type: 'textbox', + name: 'find', + size: 40, + label: 'Find', + value: selectedText + }, + { + type: 'textbox', + name: 'replace', + size: 40, + label: 'Replace with' + }, + { + type: 'checkbox', + name: 'case', + text: 'Match case', + label: ' ' + }, + { + type: 'checkbox', + name: 'words', + text: 'Whole words', + label: ' ' + } + ] + } + }); + }; + var Dialog = { open: open }; + + var register = function (editor, currentIndexState) { + editor.addCommand('SearchReplace', function () { + Dialog.open(editor, currentIndexState); + }); + }; + var Commands = { register: register }; + + var showDialog = function (editor, currentIndexState) { + return function () { + Dialog.open(editor, currentIndexState); + }; + }; + var register$1 = function (editor, currentIndexState) { + editor.addMenuItem('searchreplace', { + text: 'Find and replace', + shortcut: 'Meta+F', + onclick: showDialog(editor, currentIndexState), + separator: 'before', + context: 'edit' + }); + editor.addButton('searchreplace', { + tooltip: 'Find and replace', + onclick: showDialog(editor, currentIndexState) + }); + editor.shortcuts.add('Meta+F', '', showDialog(editor, currentIndexState)); + }; + var Buttons = { register: register$1 }; + + global.add('searchreplace', function (editor) { + var currentIndexState = Cell(-1); + Commands.register(editor, currentIndexState); + Buttons.register(editor, currentIndexState); + return Api.get(editor, currentIndexState); + }); + function Plugin () { + } + + return Plugin; + +}()); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/searchreplace/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/searchreplace/plugin.min.js new file mode 100644 index 0000000..f63ed05 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/searchreplace/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";var r=function(e){var t=e,n=function(){return t};return{get:n,set:function(e){t=e},clone:function(){return r(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),p=tinymce.util.Tools.resolve("tinymce.util.Tools");function h(e){return e&&1===e.nodeType&&"false"===e.contentEditable}var u={findAndReplaceDOMText:function(t,n,r,a,i){var o,d,m,f,p,g,c=[],l=0;function s(e,t){if(t=t||0,!e[0])throw new Error("findAndReplaceDOMText cannot handle zero-length matches");var n=e.index;if(0=s[1]?(a=l,o=s[1]-c):r&&d.push(l),!r&&l.length+c>s[0]&&(r=l,i=s[0]-c),c+=l.length),r&&a){if(l=n({startNode:r,startNodeIndex:i,endNode:a,endNodeIndex:o,innerNodes:d,match:s[2],matchIndex:u}),c-=a.length-o,a=r=null,d=[],u++,!(s=t.shift()))break}else if(p[l.nodeName]&&!f[l.nodeName]||!l.firstChild){if(l.nextSibling){l=l.nextSibling;continue}}else if(!h(l)){l=l.firstChild;continue}for(;;){if(l.nextSibling){l=l.nextSibling;break}if(l.parentNode===e)break e;l=l.parentNode}}}(n,c,function(e){var h;if("function"!=typeof e){var r=e.nodeType?e:m.createElement(e);h=function(e,t){var n=r.cloneNode(!1);return n.setAttribute("data-mce-index",t),e&&n.appendChild(m.createTextNode(e)),n}}else h=e;return function(e){var t,n,r,a=e.startNode,i=e.endNode,o=e.matchIndex;if(a===i){var d=a;r=d.parentNode,0t.get()&&o[i].setAttribute("data-mce-index",l-1)}return t.set(u),r?(s=k(e,t),x(e,t)):(s=C(e,t),b(e,t)),!a&&s},hasNext:k,hasPrev:C},n=function(r,a){return{done:function(e){return T.done(r,a,e)},find:function(e,t,n){return T.find(r,a,e,t,n)},next:function(){return T.next(r,a)},prev:function(){return T.prev(r,a)},replace:function(e,t,n){return T.replace(r,a,e,t,n)}}},a=function(i,o){var e,d={};function c(){s.statusbar.find("#next").disabled(!1===T.hasNext(i,o)),s.statusbar.find("#prev").disabled(!1===T.hasPrev(i,o))}function l(){i.windowManager.alert("Could not find the specified string.",function(){s.find("#find")[0].focus()})}i.undoManager.add(),e=p.trim(i.selection.getContent({format:"text"}));var s=i.windowManager.open({layout:"flex",pack:"center",align:"center",onClose:function(){i.focus(),T.done(i,o),i.undoManager.add()},onSubmit:function(e){var t,n,r,a;return e.preventDefault(),n=s.find("#case").checked(),a=s.find("#words").checked(),(r=s.find("#find").value()).length?d.text===r&&d.caseState===n&&d.wholeWord===a?T.hasNext(i,o)?(T.next(i,o),void c()):void l():((t=T.find(i,o,r,n,a))||l(),s.statusbar.items().slice(1).disabled(0===t),c(),void(d={text:r,caseState:n,wholeWord:a})):(T.done(i,o,!1),void s.statusbar.items().slice(1).disabled(!0))},buttons:[{text:"Find",subtype:"primary",onclick:function(){s.submit()}},{text:"Replace",disabled:!0,onclick:function(){T.replace(i,o,s.find("#replace").value())||(s.statusbar.items().slice(1).disabled(!0),o.set(-1),d={})}},{text:"Replace all",disabled:!0,onclick:function(){T.replace(i,o,s.find("#replace").value(),!0,!0),s.statusbar.items().slice(1).disabled(!0),d={}}},{type:"spacer",flex:1},{text:"Prev",name:"prev",disabled:!0,onclick:function(){T.prev(i,o),c()}},{text:"Next",name:"next",disabled:!0,onclick:function(){T.next(i,o),c()}}],title:"Find and replace",items:{type:"form",padding:20,labelGap:30,spacing:10,items:[{type:"textbox",name:"find",size:40,label:"Find",value:e},{type:"textbox",name:"replace",size:40,label:"Replace with"},{type:"checkbox",name:"case",text:"Match case",label:" "},{type:"checkbox",name:"words",text:"Whole words",label:" "}]}})},i=function(e,t){e.addCommand("SearchReplace",function(){a(e,t)})},d=function(e,t){return function(){a(e,t)}},c=function(e,t){e.addMenuItem("searchreplace",{text:"Find and replace",shortcut:"Meta+F",onclick:d(e,t),separator:"before",context:"edit"}),e.addButton("searchreplace",{tooltip:"Find and replace",onclick:d(e,t)}),e.shortcuts.add("Meta+F","",d(e,t))};e.add("searchreplace",function(e){var t=r(-1);return i(e,t),c(e,t),n(e,t)})}(); \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/mce/table/plugin.js b/html/wp-content/plugins/tinymce-advanced/mce/table/plugin.js new file mode 100644 index 0000000..ae544c3 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/table/plugin.js @@ -0,0 +1,9270 @@ +(function () { +var table = (function (domGlobals) { + 'use strict'; + + var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); + + var noop = function () { + }; + var compose = function (fa, fb) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return fa(fb.apply(null, args)); + }; + }; + var constant = function (value) { + return function () { + return value; + }; + }; + var identity = function (x) { + return x; + }; + function curry(fn) { + var initialArgs = []; + for (var _i = 1; _i < arguments.length; _i++) { + initialArgs[_i - 1] = arguments[_i]; + } + return function () { + var restArgs = []; + for (var _i = 0; _i < arguments.length; _i++) { + restArgs[_i] = arguments[_i]; + } + var all = initialArgs.concat(restArgs); + return fn.apply(null, all); + }; + } + var not = function (f) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return !f.apply(null, args); + }; + }; + var die = function (msg) { + return function () { + throw new Error(msg); + }; + }; + var never = constant(false); + var always = constant(true); + + var none = function () { + return NONE; + }; + var NONE = function () { + var eq = function (o) { + return o.isNone(); + }; + var call = function (thunk) { + return thunk(); + }; + var id = function (n) { + return n; + }; + var me = { + fold: function (n, s) { + return n(); + }, + is: never, + isSome: never, + isNone: always, + getOr: id, + getOrThunk: call, + getOrDie: function (msg) { + throw new Error(msg || 'error: getOrDie called on none.'); + }, + getOrNull: constant(null), + getOrUndefined: constant(undefined), + or: id, + orThunk: call, + map: none, + each: noop, + bind: none, + exists: never, + forall: always, + filter: none, + equals: eq, + equals_: eq, + toArray: function () { + return []; + }, + toString: constant('none()') + }; + if (Object.freeze) { + Object.freeze(me); + } + return me; + }(); + var some = function (a) { + var constant_a = constant(a); + var self = function () { + return me; + }; + var bind = function (f) { + return f(a); + }; + var me = { + fold: function (n, s) { + return s(a); + }, + is: function (v) { + return a === v; + }, + isSome: always, + isNone: never, + getOr: constant_a, + getOrThunk: constant_a, + getOrDie: constant_a, + getOrNull: constant_a, + getOrUndefined: constant_a, + or: self, + orThunk: self, + map: function (f) { + return some(f(a)); + }, + each: function (f) { + f(a); + }, + bind: bind, + exists: bind, + forall: bind, + filter: function (f) { + return f(a) ? me : NONE; + }, + toArray: function () { + return [a]; + }, + toString: function () { + return 'some(' + a + ')'; + }, + equals: function (o) { + return o.is(a); + }, + equals_: function (o, elementEq) { + return o.fold(never, function (b) { + return elementEq(a, b); + }); + } + }; + return me; + }; + var from = function (value) { + return value === null || value === undefined ? NONE : some(value); + }; + var Option = { + some: some, + none: none, + from: from + }; + + var typeOf = function (x) { + if (x === null) { + return 'null'; + } + var t = typeof x; + if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) { + return 'array'; + } + if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) { + return 'string'; + } + return t; + }; + var isType = function (type) { + return function (value) { + return typeOf(value) === type; + }; + }; + var isString = isType('string'); + var isArray = isType('array'); + var isBoolean = isType('boolean'); + var isFunction = isType('function'); + var isNumber = isType('number'); + + var nativeSlice = Array.prototype.slice; + var nativeIndexOf = Array.prototype.indexOf; + var nativePush = Array.prototype.push; + var rawIndexOf = function (ts, t) { + return nativeIndexOf.call(ts, t); + }; + var contains = function (xs, x) { + return rawIndexOf(xs, x) > -1; + }; + var exists = function (xs, pred) { + for (var i = 0, len = xs.length; i < len; i++) { + var x = xs[i]; + if (pred(x, i)) { + return true; + } + } + return false; + }; + var map = function (xs, f) { + var len = xs.length; + var r = new Array(len); + for (var i = 0; i < len; i++) { + var x = xs[i]; + r[i] = f(x, i); + } + return r; + }; + var each = function (xs, f) { + for (var i = 0, len = xs.length; i < len; i++) { + var x = xs[i]; + f(x, i); + } + }; + var eachr = function (xs, f) { + for (var i = xs.length - 1; i >= 0; i--) { + var x = xs[i]; + f(x, i); + } + }; + var filter = function (xs, pred) { + var r = []; + for (var i = 0, len = xs.length; i < len; i++) { + var x = xs[i]; + if (pred(x, i)) { + r.push(x); + } + } + return r; + }; + var foldr = function (xs, f, acc) { + eachr(xs, function (x) { + acc = f(acc, x); + }); + return acc; + }; + var foldl = function (xs, f, acc) { + each(xs, function (x) { + acc = f(acc, x); + }); + return acc; + }; + var find = function (xs, pred) { + for (var i = 0, len = xs.length; i < len; i++) { + var x = xs[i]; + if (pred(x, i)) { + return Option.some(x); + } + } + return Option.none(); + }; + var findIndex = function (xs, pred) { + for (var i = 0, len = xs.length; i < len; i++) { + var x = xs[i]; + if (pred(x, i)) { + return Option.some(i); + } + } + return Option.none(); + }; + var flatten = function (xs) { + var r = []; + for (var i = 0, len = xs.length; i < len; ++i) { + if (!isArray(xs[i])) { + throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); + } + nativePush.apply(r, xs[i]); + } + return r; + }; + var bind = function (xs, f) { + var output = map(xs, f); + return flatten(output); + }; + var forall = function (xs, pred) { + for (var i = 0, len = xs.length; i < len; ++i) { + var x = xs[i]; + if (pred(x, i) !== true) { + return false; + } + } + return true; + }; + var reverse = function (xs) { + var r = nativeSlice.call(xs, 0); + r.reverse(); + return r; + }; + var last = function (xs) { + return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]); + }; + var from$1 = isFunction(Array.from) ? Array.from : function (x) { + return nativeSlice.call(x); + }; + + var keys = Object.keys; + var each$1 = function (obj, f) { + var props = keys(obj); + for (var k = 0, len = props.length; k < len; k++) { + var i = props[k]; + var x = obj[i]; + f(x, i); + } + }; + var map$1 = function (obj, f) { + return tupleMap(obj, function (x, i) { + return { + k: i, + v: f(x, i) + }; + }); + }; + var tupleMap = function (obj, f) { + var r = {}; + each$1(obj, function (x, i) { + var tuple = f(x, i); + r[tuple.k] = tuple.v; + }); + return r; + }; + + var Immutable = function () { + var fields = []; + for (var _i = 0; _i < arguments.length; _i++) { + fields[_i] = arguments[_i]; + } + return function () { + var values = []; + for (var _i = 0; _i < arguments.length; _i++) { + values[_i] = arguments[_i]; + } + if (fields.length !== values.length) { + throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments'); + } + var struct = {}; + each(fields, function (name, i) { + struct[name] = constant(values[i]); + }); + return struct; + }; + }; + + var sort = function (arr) { + return arr.slice(0).sort(); + }; + var reqMessage = function (required, keys) { + throw new Error('All required keys (' + sort(required).join(', ') + ') were not specified. Specified keys were: ' + sort(keys).join(', ') + '.'); + }; + var unsuppMessage = function (unsupported) { + throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', ')); + }; + var validateStrArr = function (label, array) { + if (!isArray(array)) { + throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.'); + } + each(array, function (a) { + if (!isString(a)) { + throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.'); + } + }); + }; + var invalidTypeMessage = function (incorrect, type) { + throw new Error('All values need to be of type: ' + type + '. Keys (' + sort(incorrect).join(', ') + ') were not.'); + }; + var checkDupes = function (everything) { + var sorted = sort(everything); + var dupe = find(sorted, function (s, i) { + return i < sorted.length - 1 && s === sorted[i + 1]; + }); + dupe.each(function (d) { + throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].'); + }); + }; + + var MixedBag = function (required, optional) { + var everything = required.concat(optional); + if (everything.length === 0) { + throw new Error('You must specify at least one required or optional field.'); + } + validateStrArr('required', required); + validateStrArr('optional', optional); + checkDupes(everything); + return function (obj) { + var keys$1 = keys(obj); + var allReqd = forall(required, function (req) { + return contains(keys$1, req); + }); + if (!allReqd) { + reqMessage(required, keys$1); + } + var unsupported = filter(keys$1, function (key) { + return !contains(everything, key); + }); + if (unsupported.length > 0) { + unsuppMessage(unsupported); + } + var r = {}; + each(required, function (req) { + r[req] = constant(obj[req]); + }); + each(optional, function (opt) { + r[opt] = constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]) : Option.none()); + }); + return r; + }; + }; + + var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; + var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; + var COMMENT = domGlobals.Node.COMMENT_NODE; + var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; + var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; + var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; + var ELEMENT = domGlobals.Node.ELEMENT_NODE; + var TEXT = domGlobals.Node.TEXT_NODE; + var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; + var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; + var ENTITY = domGlobals.Node.ENTITY_NODE; + var NOTATION = domGlobals.Node.NOTATION_NODE; + + var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); + + var path = function (parts, scope) { + var o = scope !== undefined && scope !== null ? scope : Global; + for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) { + o = o[parts[i]]; + } + return o; + }; + var resolve = function (p, scope) { + var parts = p.split('.'); + return path(parts, scope); + }; + + var unsafe = function (name, scope) { + return resolve(name, scope); + }; + var getOrDie = function (name, scope) { + var actual = unsafe(name, scope); + if (actual === undefined || actual === null) { + throw new Error(name + ' not available on this browser'); + } + return actual; + }; + var Global$1 = { getOrDie: getOrDie }; + + var name = function (element) { + var r = element.dom().nodeName; + return r.toLowerCase(); + }; + var type = function (element) { + return element.dom().nodeType; + }; + var isType$1 = function (t) { + return function (element) { + return type(element) === t; + }; + }; + var isComment = function (element) { + return type(element) === COMMENT || name(element) === '#comment'; + }; + var isElement = isType$1(ELEMENT); + var isText = isType$1(TEXT); + + var rawSet = function (dom, key, value) { + if (isString(value) || isBoolean(value) || isNumber(value)) { + dom.setAttribute(key, value + ''); + } else { + domGlobals.console.error('Invalid call to Attr.set. Key ', key, ':: Value ', value, ':: Element ', dom); + throw new Error('Attribute value was not simple'); + } + }; + var set = function (element, key, value) { + rawSet(element.dom(), key, value); + }; + var setAll = function (element, attrs) { + var dom = element.dom(); + each$1(attrs, function (v, k) { + rawSet(dom, k, v); + }); + }; + var get = function (element, key) { + var v = element.dom().getAttribute(key); + return v === null ? undefined : v; + }; + var has = function (element, key) { + var dom = element.dom(); + return dom && dom.hasAttribute ? dom.hasAttribute(key) : false; + }; + var remove = function (element, key) { + element.dom().removeAttribute(key); + }; + var clone = function (element) { + return foldl(element.dom().attributes, function (acc, attr) { + acc[attr.name] = attr.value; + return acc; + }, {}); + }; + + var checkRange = function (str, substr, start) { + if (substr === '') { + return true; + } + if (str.length < substr.length) { + return false; + } + var x = str.substr(start, start + substr.length); + return x === substr; + }; + var contains$1 = function (str, substr) { + return str.indexOf(substr) !== -1; + }; + var endsWith = function (str, suffix) { + return checkRange(str, suffix, str.length - suffix.length); + }; + var trim = function (str) { + return str.replace(/^\s+|\s+$/g, ''); + }; + + var isSupported = function (dom) { + return dom.style !== undefined && isFunction(dom.style.getPropertyValue); + }; + + var cached = function (f) { + var called = false; + var r; + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (!called) { + called = true; + r = f.apply(null, args); + } + return r; + }; + }; + + var fromHtml = function (html, scope) { + var doc = scope || domGlobals.document; + var div = doc.createElement('div'); + div.innerHTML = html; + if (!div.hasChildNodes() || div.childNodes.length > 1) { + domGlobals.console.error('HTML does not have a single root node', html); + throw new Error('HTML must have a single root node'); + } + return fromDom(div.childNodes[0]); + }; + var fromTag = function (tag, scope) { + var doc = scope || domGlobals.document; + var node = doc.createElement(tag); + return fromDom(node); + }; + var fromText = function (text, scope) { + var doc = scope || domGlobals.document; + var node = doc.createTextNode(text); + return fromDom(node); + }; + var fromDom = function (node) { + if (node === null || node === undefined) { + throw new Error('Node cannot be null or undefined'); + } + return { dom: constant(node) }; + }; + var fromPoint = function (docElm, x, y) { + var doc = docElm.dom(); + return Option.from(doc.elementFromPoint(x, y)).map(fromDom); + }; + var Element = { + fromHtml: fromHtml, + fromTag: fromTag, + fromText: fromText, + fromDom: fromDom, + fromPoint: fromPoint + }; + + var inBody = function (element) { + var dom = isText(element) ? element.dom().parentNode : element.dom(); + return dom !== undefined && dom !== null && dom.ownerDocument.body.contains(dom); + }; + var body = cached(function () { + return getBody(Element.fromDom(domGlobals.document)); + }); + var getBody = function (doc) { + var b = doc.dom().body; + if (b === null || b === undefined) { + throw new Error('Body is not available yet'); + } + return Element.fromDom(b); + }; + + var internalSet = function (dom, property, value) { + if (!isString(value)) { + domGlobals.console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom); + throw new Error('CSS value must be a string: ' + value); + } + if (isSupported(dom)) { + dom.style.setProperty(property, value); + } + }; + var internalRemove = function (dom, property) { + if (isSupported(dom)) { + dom.style.removeProperty(property); + } + }; + var set$1 = function (element, property, value) { + var dom = element.dom(); + internalSet(dom, property, value); + }; + var setAll$1 = function (element, css) { + var dom = element.dom(); + each$1(css, function (v, k) { + internalSet(dom, k, v); + }); + }; + var get$1 = function (element, property) { + var dom = element.dom(); + var styles = domGlobals.window.getComputedStyle(dom); + var r = styles.getPropertyValue(property); + var v = r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r; + return v === null ? undefined : v; + }; + var getUnsafeProperty = function (dom, property) { + return isSupported(dom) ? dom.style.getPropertyValue(property) : ''; + }; + var getRaw = function (element, property) { + var dom = element.dom(); + var raw = getUnsafeProperty(dom, property); + return Option.from(raw).filter(function (r) { + return r.length > 0; + }); + }; + var remove$1 = function (element, property) { + var dom = element.dom(); + internalRemove(dom, property); + if (has(element, 'style') && trim(get(element, 'style')) === '') { + remove(element, 'style'); + } + }; + var copy = function (source, target) { + var sourceDom = source.dom(); + var targetDom = target.dom(); + if (isSupported(sourceDom) && isSupported(targetDom)) { + targetDom.style.cssText = sourceDom.style.cssText; + } + }; + + var node = function () { + var f = Global$1.getOrDie('Node'); + return f; + }; + var compareDocumentPosition = function (a, b, match) { + return (a.compareDocumentPosition(b) & match) !== 0; + }; + var documentPositionPreceding = function (a, b) { + return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING); + }; + var documentPositionContainedBy = function (a, b) { + return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY); + }; + var Node = { + documentPositionPreceding: documentPositionPreceding, + documentPositionContainedBy: documentPositionContainedBy + }; + + var firstMatch = function (regexes, s) { + for (var i = 0; i < regexes.length; i++) { + var x = regexes[i]; + if (x.test(s)) { + return x; + } + } + return undefined; + }; + var find$1 = function (regexes, agent) { + var r = firstMatch(regexes, agent); + if (!r) { + return { + major: 0, + minor: 0 + }; + } + var group = function (i) { + return Number(agent.replace(r, '$' + i)); + }; + return nu(group(1), group(2)); + }; + var detect = function (versionRegexes, agent) { + var cleanedAgent = String(agent).toLowerCase(); + if (versionRegexes.length === 0) { + return unknown(); + } + return find$1(versionRegexes, cleanedAgent); + }; + var unknown = function () { + return nu(0, 0); + }; + var nu = function (major, minor) { + return { + major: major, + minor: minor + }; + }; + var Version = { + nu: nu, + detect: detect, + unknown: unknown + }; + + var edge = 'Edge'; + var chrome = 'Chrome'; + var ie = 'IE'; + var opera = 'Opera'; + var firefox = 'Firefox'; + var safari = 'Safari'; + var isBrowser = function (name, current) { + return function () { + return current === name; + }; + }; + var unknown$1 = function () { + return nu$1({ + current: undefined, + version: Version.unknown() + }); + }; + var nu$1 = function (info) { + var current = info.current; + var version = info.version; + return { + current: current, + version: version, + isEdge: isBrowser(edge, current), + isChrome: isBrowser(chrome, current), + isIE: isBrowser(ie, current), + isOpera: isBrowser(opera, current), + isFirefox: isBrowser(firefox, current), + isSafari: isBrowser(safari, current) + }; + }; + var Browser = { + unknown: unknown$1, + nu: nu$1, + edge: constant(edge), + chrome: constant(chrome), + ie: constant(ie), + opera: constant(opera), + firefox: constant(firefox), + safari: constant(safari) + }; + + var windows = 'Windows'; + var ios = 'iOS'; + var android = 'Android'; + var linux = 'Linux'; + var osx = 'OSX'; + var solaris = 'Solaris'; + var freebsd = 'FreeBSD'; + var isOS = function (name, current) { + return function () { + return current === name; + }; + }; + var unknown$2 = function () { + return nu$2({ + current: undefined, + version: Version.unknown() + }); + }; + var nu$2 = function (info) { + var current = info.current; + var version = info.version; + return { + current: current, + version: version, + isWindows: isOS(windows, current), + isiOS: isOS(ios, current), + isAndroid: isOS(android, current), + isOSX: isOS(osx, current), + isLinux: isOS(linux, current), + isSolaris: isOS(solaris, current), + isFreeBSD: isOS(freebsd, current) + }; + }; + var OperatingSystem = { + unknown: unknown$2, + nu: nu$2, + windows: constant(windows), + ios: constant(ios), + android: constant(android), + linux: constant(linux), + osx: constant(osx), + solaris: constant(solaris), + freebsd: constant(freebsd) + }; + + var DeviceType = function (os, browser, userAgent) { + var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true; + var isiPhone = os.isiOS() && !isiPad; + var isAndroid3 = os.isAndroid() && os.version.major === 3; + var isAndroid4 = os.isAndroid() && os.version.major === 4; + var isTablet = isiPad || isAndroid3 || isAndroid4 && /mobile/i.test(userAgent) === true; + var isTouch = os.isiOS() || os.isAndroid(); + var isPhone = isTouch && !isTablet; + var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false; + return { + isiPad: constant(isiPad), + isiPhone: constant(isiPhone), + isTablet: constant(isTablet), + isPhone: constant(isPhone), + isTouch: constant(isTouch), + isAndroid: os.isAndroid, + isiOS: os.isiOS, + isWebView: constant(iOSwebview) + }; + }; + + var detect$1 = function (candidates, userAgent) { + var agent = String(userAgent).toLowerCase(); + return find(candidates, function (candidate) { + return candidate.search(agent); + }); + }; + var detectBrowser = function (browsers, userAgent) { + return detect$1(browsers, userAgent).map(function (browser) { + var version = Version.detect(browser.versionRegexes, userAgent); + return { + current: browser.name, + version: version + }; + }); + }; + var detectOs = function (oses, userAgent) { + return detect$1(oses, userAgent).map(function (os) { + var version = Version.detect(os.versionRegexes, userAgent); + return { + current: os.name, + version: version + }; + }); + }; + var UaString = { + detectBrowser: detectBrowser, + detectOs: detectOs + }; + + var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/; + var checkContains = function (target) { + return function (uastring) { + return contains$1(uastring, target); + }; + }; + var browsers = [ + { + name: 'Edge', + versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/], + search: function (uastring) { + return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit'); + } + }, + { + name: 'Chrome', + versionRegexes: [ + /.*?chrome\/([0-9]+)\.([0-9]+).*/, + normalVersionRegex + ], + search: function (uastring) { + return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe'); + } + }, + { + name: 'IE', + versionRegexes: [ + /.*?msie\ ?([0-9]+)\.([0-9]+).*/, + /.*?rv:([0-9]+)\.([0-9]+).*/ + ], + search: function (uastring) { + return contains$1(uastring, 'msie') || contains$1(uastring, 'trident'); + } + }, + { + name: 'Opera', + versionRegexes: [ + normalVersionRegex, + /.*?opera\/([0-9]+)\.([0-9]+).*/ + ], + search: checkContains('opera') + }, + { + name: 'Firefox', + versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/], + search: checkContains('firefox') + }, + { + name: 'Safari', + versionRegexes: [ + normalVersionRegex, + /.*?cpu os ([0-9]+)_([0-9]+).*/ + ], + search: function (uastring) { + return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit'); + } + } + ]; + var oses = [ + { + name: 'Windows', + search: checkContains('win'), + versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/] + }, + { + name: 'iOS', + search: function (uastring) { + return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad'); + }, + versionRegexes: [ + /.*?version\/\ ?([0-9]+)\.([0-9]+).*/, + /.*cpu os ([0-9]+)_([0-9]+).*/, + /.*cpu iphone os ([0-9]+)_([0-9]+).*/ + ] + }, + { + name: 'Android', + search: checkContains('android'), + versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/] + }, + { + name: 'OSX', + search: checkContains('os x'), + versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/] + }, + { + name: 'Linux', + search: checkContains('linux'), + versionRegexes: [] + }, + { + name: 'Solaris', + search: checkContains('sunos'), + versionRegexes: [] + }, + { + name: 'FreeBSD', + search: checkContains('freebsd'), + versionRegexes: [] + } + ]; + var PlatformInfo = { + browsers: constant(browsers), + oses: constant(oses) + }; + + var detect$2 = function (userAgent) { + var browsers = PlatformInfo.browsers(); + var oses = PlatformInfo.oses(); + var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu); + var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu); + var deviceType = DeviceType(os, browser, userAgent); + return { + browser: browser, + os: os, + deviceType: deviceType + }; + }; + var PlatformDetection = { detect: detect$2 }; + + var detect$3 = cached(function () { + var userAgent = domGlobals.navigator.userAgent; + return PlatformDetection.detect(userAgent); + }); + var PlatformDetection$1 = { detect: detect$3 }; + + var ELEMENT$1 = ELEMENT; + var DOCUMENT$1 = DOCUMENT; + var is = function (element, selector) { + var dom = element.dom(); + if (dom.nodeType !== ELEMENT$1) { + return false; + } else { + var elem = dom; + if (elem.matches !== undefined) { + return elem.matches(selector); + } else if (elem.msMatchesSelector !== undefined) { + return elem.msMatchesSelector(selector); + } else if (elem.webkitMatchesSelector !== undefined) { + return elem.webkitMatchesSelector(selector); + } else if (elem.mozMatchesSelector !== undefined) { + return elem.mozMatchesSelector(selector); + } else { + throw new Error('Browser lacks native selectors'); + } + } + }; + var bypassSelector = function (dom) { + return dom.nodeType !== ELEMENT$1 && dom.nodeType !== DOCUMENT$1 || dom.childElementCount === 0; + }; + var all = function (selector, scope) { + var base = scope === undefined ? domGlobals.document : scope.dom(); + return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), Element.fromDom); + }; + var one = function (selector, scope) { + var base = scope === undefined ? domGlobals.document : scope.dom(); + return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom); + }; + + var eq = function (e1, e2) { + return e1.dom() === e2.dom(); + }; + var regularContains = function (e1, e2) { + var d1 = e1.dom(); + var d2 = e2.dom(); + return d1 === d2 ? false : d1.contains(d2); + }; + var ieContains = function (e1, e2) { + return Node.documentPositionContainedBy(e1.dom(), e2.dom()); + }; + var browser = PlatformDetection$1.detect().browser; + var contains$2 = browser.isIE() ? ieContains : regularContains; + var is$1 = is; + + var owner = function (element) { + return Element.fromDom(element.dom().ownerDocument); + }; + var defaultView = function (element) { + return Element.fromDom(element.dom().ownerDocument.defaultView); + }; + var parent = function (element) { + return Option.from(element.dom().parentNode).map(Element.fromDom); + }; + var parents = function (element, isRoot) { + var stop = isFunction(isRoot) ? isRoot : never; + var dom = element.dom(); + var ret = []; + while (dom.parentNode !== null && dom.parentNode !== undefined) { + var rawParent = dom.parentNode; + var p = Element.fromDom(rawParent); + ret.push(p); + if (stop(p) === true) { + break; + } else { + dom = rawParent; + } + } + return ret; + }; + var prevSibling = function (element) { + return Option.from(element.dom().previousSibling).map(Element.fromDom); + }; + var nextSibling = function (element) { + return Option.from(element.dom().nextSibling).map(Element.fromDom); + }; + var children = function (element) { + return map(element.dom().childNodes, Element.fromDom); + }; + var child = function (element, index) { + var cs = element.dom().childNodes; + return Option.from(cs[index]).map(Element.fromDom); + }; + var firstChild = function (element) { + return child(element, 0); + }; + var spot = Immutable('element', 'offset'); + + var before = function (marker, element) { + var parent$1 = parent(marker); + parent$1.each(function (v) { + v.dom().insertBefore(element.dom(), marker.dom()); + }); + }; + var after = function (marker, element) { + var sibling = nextSibling(marker); + sibling.fold(function () { + var parent$1 = parent(marker); + parent$1.each(function (v) { + append(v, element); + }); + }, function (v) { + before(v, element); + }); + }; + var prepend = function (parent, element) { + var firstChild$1 = firstChild(parent); + firstChild$1.fold(function () { + append(parent, element); + }, function (v) { + parent.dom().insertBefore(element.dom(), v.dom()); + }); + }; + var append = function (parent, element) { + parent.dom().appendChild(element.dom()); + }; + var wrap = function (element, wrapper) { + before(element, wrapper); + append(wrapper, element); + }; + + var before$1 = function (marker, elements) { + each(elements, function (x) { + before(marker, x); + }); + }; + var after$1 = function (marker, elements) { + each(elements, function (x, i) { + var e = i === 0 ? marker : elements[i - 1]; + after(e, x); + }); + }; + var append$1 = function (parent, elements) { + each(elements, function (x) { + append(parent, x); + }); + }; + + var empty = function (element) { + element.dom().textContent = ''; + each(children(element), function (rogue) { + remove$2(rogue); + }); + }; + var remove$2 = function (element) { + var dom = element.dom(); + if (dom.parentNode !== null) { + dom.parentNode.removeChild(dom); + } + }; + var unwrap = function (wrapper) { + var children$1 = children(wrapper); + if (children$1.length > 0) { + before$1(wrapper, children$1); + } + remove$2(wrapper); + }; + + var dimension = Immutable('width', 'height'); + var dimensions = Immutable('width', 'height'); + var grid = Immutable('rows', 'columns'); + var address = Immutable('row', 'column'); + var coords = Immutable('x', 'y'); + var detail = Immutable('element', 'rowspan', 'colspan'); + var detailnew = Immutable('element', 'rowspan', 'colspan', 'isNew'); + var extended = Immutable('element', 'rowspan', 'colspan', 'row', 'column'); + var rowdata = Immutable('element', 'cells', 'section'); + var elementnew = Immutable('element', 'isNew'); + var rowdatanew = Immutable('element', 'cells', 'section', 'isNew'); + var rowcells = Immutable('cells', 'section'); + var rowdetails = Immutable('details', 'section'); + var bounds = Immutable('startRow', 'startCol', 'finishRow', 'finishCol'); + + var ancestors = function (scope, predicate, isRoot) { + return filter(parents(scope, isRoot), predicate); + }; + var children$1 = function (scope, predicate) { + return filter(children(scope), predicate); + }; + var descendants = function (scope, predicate) { + var result = []; + each(children(scope), function (x) { + if (predicate(x)) { + result = result.concat([x]); + } + result = result.concat(descendants(x, predicate)); + }); + return result; + }; + + var ancestors$1 = function (scope, selector, isRoot) { + return ancestors(scope, function (e) { + return is(e, selector); + }, isRoot); + }; + var children$2 = function (scope, selector) { + return children$1(scope, function (e) { + return is(e, selector); + }); + }; + var descendants$1 = function (scope, selector) { + return all(selector, scope); + }; + + function ClosestOrAncestor (is, ancestor, scope, a, isRoot) { + return is(scope, a) ? Option.some(scope) : isFunction(isRoot) && isRoot(scope) ? Option.none() : ancestor(scope, a, isRoot); + } + + var ancestor = function (scope, predicate, isRoot) { + var element = scope.dom(); + var stop = isFunction(isRoot) ? isRoot : constant(false); + while (element.parentNode) { + element = element.parentNode; + var el = Element.fromDom(element); + if (predicate(el)) { + return Option.some(el); + } else if (stop(el)) { + break; + } + } + return Option.none(); + }; + var closest = function (scope, predicate, isRoot) { + var is = function (s, test) { + return test(s); + }; + return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot); + }; + var child$1 = function (scope, predicate) { + var pred = function (node) { + return predicate(Element.fromDom(node)); + }; + var result = find(scope.dom().childNodes, pred); + return result.map(Element.fromDom); + }; + var descendant = function (scope, predicate) { + var descend = function (node) { + for (var i = 0; i < node.childNodes.length; i++) { + var child_1 = Element.fromDom(node.childNodes[i]); + if (predicate(child_1)) { + return Option.some(child_1); + } + var res = descend(node.childNodes[i]); + if (res.isSome()) { + return res; + } + } + return Option.none(); + }; + return descend(scope.dom()); + }; + + var ancestor$1 = function (scope, selector, isRoot) { + return ancestor(scope, function (e) { + return is(e, selector); + }, isRoot); + }; + var child$2 = function (scope, selector) { + return child$1(scope, function (e) { + return is(e, selector); + }); + }; + var descendant$1 = function (scope, selector) { + return one(selector, scope); + }; + var closest$1 = function (scope, selector, isRoot) { + return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot); + }; + + var firstLayer = function (scope, selector) { + return filterFirstLayer(scope, selector, constant(true)); + }; + var filterFirstLayer = function (scope, selector, predicate) { + return bind(children(scope), function (x) { + return is(x, selector) ? predicate(x) ? [x] : [] : filterFirstLayer(x, selector, predicate); + }); + }; + var LayerSelector = { + firstLayer: firstLayer, + filterFirstLayer: filterFirstLayer + }; + + var lookup = function (tags, element, isRoot) { + if (isRoot === void 0) { + isRoot = never; + } + if (isRoot(element)) { + return Option.none(); + } + if (contains(tags, name(element))) { + return Option.some(element); + } + var isRootOrUpperTable = function (elm) { + return is(elm, 'table') || isRoot(elm); + }; + return ancestor$1(element, tags.join(','), isRootOrUpperTable); + }; + var cell = function (element, isRoot) { + return lookup([ + 'td', + 'th' + ], element, isRoot); + }; + var cells = function (ancestor) { + return LayerSelector.firstLayer(ancestor, 'th,td'); + }; + var notCell = function (element, isRoot) { + return lookup([ + 'caption', + 'tr', + 'tbody', + 'tfoot', + 'thead' + ], element, isRoot); + }; + var neighbours = function (selector, element) { + return parent(element).map(function (parent) { + return children$2(parent, selector); + }); + }; + var neighbourCells = curry(neighbours, 'th,td'); + var neighbourRows = curry(neighbours, 'tr'); + var firstCell = function (ancestor) { + return descendant$1(ancestor, 'th,td'); + }; + var table = function (element, isRoot) { + return closest$1(element, 'table', isRoot); + }; + var row = function (element, isRoot) { + return lookup(['tr'], element, isRoot); + }; + var rows = function (ancestor) { + return LayerSelector.firstLayer(ancestor, 'tr'); + }; + var attr = function (element, property) { + return parseInt(get(element, property), 10); + }; + var grid$1 = function (element, rowProp, colProp) { + var rowsCount = attr(element, rowProp); + var cols = attr(element, colProp); + return grid(rowsCount, cols); + }; + var TableLookup = { + cell: cell, + firstCell: firstCell, + cells: cells, + neighbourCells: neighbourCells, + table: table, + row: row, + rows: rows, + notCell: notCell, + neighbourRows: neighbourRows, + attr: attr, + grid: grid$1 + }; + + var fromTable = function (table) { + var rows = TableLookup.rows(table); + return map(rows, function (row) { + var element = row; + var parent$1 = parent(element); + var parentSection = parent$1.map(function (p) { + var parentName = name(p); + return parentName === 'tfoot' || parentName === 'thead' || parentName === 'tbody' ? parentName : 'tbody'; + }).getOr('tbody'); + var cells = map(TableLookup.cells(row), function (cell) { + var rowspan = has(cell, 'rowspan') ? parseInt(get(cell, 'rowspan'), 10) : 1; + var colspan = has(cell, 'colspan') ? parseInt(get(cell, 'colspan'), 10) : 1; + return detail(cell, rowspan, colspan); + }); + return rowdata(element, cells, parentSection); + }); + }; + var fromPastedRows = function (rows, example) { + return map(rows, function (row) { + var cells = map(TableLookup.cells(row), function (cell) { + var rowspan = has(cell, 'rowspan') ? parseInt(get(cell, 'rowspan'), 10) : 1; + var colspan = has(cell, 'colspan') ? parseInt(get(cell, 'colspan'), 10) : 1; + return detail(cell, rowspan, colspan); + }); + return rowdata(row, cells, example.section()); + }); + }; + var DetailsList = { + fromTable: fromTable, + fromPastedRows: fromPastedRows + }; + + var key = function (row, column) { + return row + ',' + column; + }; + var getAt = function (warehouse, row, column) { + var raw = warehouse.access()[key(row, column)]; + return raw !== undefined ? Option.some(raw) : Option.none(); + }; + var findItem = function (warehouse, item, comparator) { + var filtered = filterItems(warehouse, function (detail) { + return comparator(item, detail.element()); + }); + return filtered.length > 0 ? Option.some(filtered[0]) : Option.none(); + }; + var filterItems = function (warehouse, predicate) { + var all = bind(warehouse.all(), function (r) { + return r.cells(); + }); + return filter(all, predicate); + }; + var generate = function (list) { + var access = {}; + var cells = []; + var maxRows = list.length; + var maxColumns = 0; + each(list, function (details, r) { + var currentRow = []; + each(details.cells(), function (detail) { + var start = 0; + while (access[key(r, start)] !== undefined) { + start++; + } + var current = extended(detail.element(), detail.rowspan(), detail.colspan(), r, start); + for (var i = 0; i < detail.colspan(); i++) { + for (var j = 0; j < detail.rowspan(); j++) { + var cr = r + j; + var cc = start + i; + var newpos = key(cr, cc); + access[newpos] = current; + maxColumns = Math.max(maxColumns, cc + 1); + } + } + currentRow.push(current); + }); + cells.push(rowdata(details.element(), currentRow, details.section())); + }); + var grid$1 = grid(maxRows, maxColumns); + return { + grid: constant(grid$1), + access: constant(access), + all: constant(cells) + }; + }; + var justCells = function (warehouse) { + var rows = map(warehouse.all(), function (w) { + return w.cells(); + }); + return flatten(rows); + }; + var Warehouse = { + generate: generate, + getAt: getAt, + findItem: findItem, + filterItems: filterItems, + justCells: justCells + }; + + var statsStruct = Immutable('minRow', 'minCol', 'maxRow', 'maxCol'); + var findSelectedStats = function (house, isSelected) { + var totalColumns = house.grid().columns(); + var totalRows = house.grid().rows(); + var minRow = totalRows; + var minCol = totalColumns; + var maxRow = 0; + var maxCol = 0; + each$1(house.access(), function (detail) { + if (isSelected(detail)) { + var startRow = detail.row(); + var endRow = startRow + detail.rowspan() - 1; + var startCol = detail.column(); + var endCol = startCol + detail.colspan() - 1; + if (startRow < minRow) { + minRow = startRow; + } else if (endRow > maxRow) { + maxRow = endRow; + } + if (startCol < minCol) { + minCol = startCol; + } else if (endCol > maxCol) { + maxCol = endCol; + } + } + }); + return statsStruct(minRow, minCol, maxRow, maxCol); + }; + var makeCell = function (list, seenSelected, rowIndex) { + var row = list[rowIndex].element(); + var td = Element.fromTag('td'); + append(td, Element.fromTag('br')); + var f = seenSelected ? append : prepend; + f(row, td); + }; + var fillInGaps = function (list, house, stats, isSelected) { + var totalColumns = house.grid().columns(); + var totalRows = house.grid().rows(); + for (var i = 0; i < totalRows; i++) { + var seenSelected = false; + for (var j = 0; j < totalColumns; j++) { + if (!(i < stats.minRow() || i > stats.maxRow() || j < stats.minCol() || j > stats.maxCol())) { + var needCell = Warehouse.getAt(house, i, j).filter(isSelected).isNone(); + if (needCell) { + makeCell(list, seenSelected, i); + } else { + seenSelected = true; + } + } + } + } + }; + var clean = function (table, stats) { + var emptyRows = filter(LayerSelector.firstLayer(table, 'tr'), function (row) { + return row.dom().childElementCount === 0; + }); + each(emptyRows, remove$2); + if (stats.minCol() === stats.maxCol() || stats.minRow() === stats.maxRow()) { + each(LayerSelector.firstLayer(table, 'th,td'), function (cell) { + remove(cell, 'rowspan'); + remove(cell, 'colspan'); + }); + } + remove(table, 'width'); + remove(table, 'height'); + remove$1(table, 'width'); + remove$1(table, 'height'); + }; + var extract = function (table, selectedSelector) { + var isSelected = function (detail) { + return is(detail.element(), selectedSelector); + }; + var list = DetailsList.fromTable(table); + var house = Warehouse.generate(list); + var stats = findSelectedStats(house, isSelected); + var selector = 'th:not(' + selectedSelector + ')' + ',td:not(' + selectedSelector + ')'; + var unselectedCells = LayerSelector.filterFirstLayer(table, 'th,td', function (cell) { + return is(cell, selector); + }); + each(unselectedCells, remove$2); + fillInGaps(list, house, stats, isSelected); + clean(table, stats); + return table; + }; + var CopySelected = { extract: extract }; + + function NodeValue (is, name) { + var get = function (element) { + if (!is(element)) { + throw new Error('Can only get ' + name + ' value of a ' + name + ' node'); + } + return getOption(element).getOr(''); + }; + var getOption = function (element) { + return is(element) ? Option.from(element.dom().nodeValue) : Option.none(); + }; + var set = function (element, value) { + if (!is(element)) { + throw new Error('Can only set raw ' + name + ' value of a ' + name + ' node'); + } + element.dom().nodeValue = value; + }; + return { + get: get, + getOption: getOption, + set: set + }; + } + + var api = NodeValue(isText, 'text'); + var get$2 = function (element) { + return api.get(element); + }; + var getOption = function (element) { + return api.getOption(element); + }; + var set$2 = function (element, value) { + api.set(element, value); + }; + + var getEnd = function (element) { + return name(element) === 'img' ? 1 : getOption(element).fold(function () { + return children(element).length; + }, function (v) { + return v.length; + }); + }; + var NBSP = '\xA0'; + var isTextNodeWithCursorPosition = function (el) { + return getOption(el).filter(function (text) { + return text.trim().length !== 0 || text.indexOf(NBSP) > -1; + }).isSome(); + }; + var elementsWithCursorPosition = [ + 'img', + 'br' + ]; + var isCursorPosition = function (elem) { + var hasCursorPosition = isTextNodeWithCursorPosition(elem); + return hasCursorPosition || contains(elementsWithCursorPosition, name(elem)); + }; + + var first = function (element) { + return descendant(element, isCursorPosition); + }; + var last$1 = function (element) { + return descendantRtl(element, isCursorPosition); + }; + var descendantRtl = function (scope, predicate) { + var descend = function (element) { + var children$1 = children(element); + for (var i = children$1.length - 1; i >= 0; i--) { + var child = children$1[i]; + if (predicate(child)) { + return Option.some(child); + } + var res = descend(child); + if (res.isSome()) { + return res; + } + } + return Option.none(); + }; + return descend(scope); + }; + + var clone$1 = function (original, isDeep) { + return Element.fromDom(original.dom().cloneNode(isDeep)); + }; + var shallow = function (original) { + return clone$1(original, false); + }; + var deep = function (original) { + return clone$1(original, true); + }; + var shallowAs = function (original, tag) { + var nu = Element.fromTag(tag); + var attributes = clone(original); + setAll(nu, attributes); + return nu; + }; + var copy$1 = function (original, tag) { + var nu = shallowAs(original, tag); + var cloneChildren = children(deep(original)); + append$1(nu, cloneChildren); + return nu; + }; + + var createCell = function () { + var td = Element.fromTag('td'); + append(td, Element.fromTag('br')); + return td; + }; + var replace = function (cell, tag, attrs) { + var replica = copy$1(cell, tag); + each$1(attrs, function (v, k) { + if (v === null) { + remove(replica, k); + } else { + set(replica, k, v); + } + }); + return replica; + }; + var pasteReplace = function (cell) { + return cell; + }; + var newRow = function (doc) { + return function () { + return Element.fromTag('tr', doc.dom()); + }; + }; + var cloneFormats = function (oldCell, newCell, formats) { + var first$1 = first(oldCell); + return first$1.map(function (firstText) { + var formatSelector = formats.join(','); + var parents = ancestors$1(firstText, formatSelector, function (element) { + return eq(element, oldCell); + }); + return foldr(parents, function (last, parent) { + var clonedFormat = shallow(parent); + remove(clonedFormat, 'contenteditable'); + append(last, clonedFormat); + return clonedFormat; + }, newCell); + }).getOr(newCell); + }; + var cellOperations = function (mutate, doc, formatsToClone) { + var newCell = function (prev) { + var docu = owner(prev.element()); + var td = Element.fromTag(name(prev.element()), docu.dom()); + var formats = formatsToClone.getOr([ + 'strong', + 'em', + 'b', + 'i', + 'span', + 'font', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'p', + 'div' + ]); + var lastNode = formats.length > 0 ? cloneFormats(prev.element(), td, formats) : td; + append(lastNode, Element.fromTag('br')); + copy(prev.element(), td); + remove$1(td, 'height'); + if (prev.colspan() !== 1) { + remove$1(prev.element(), 'width'); + } + mutate(prev.element(), td); + return td; + }; + return { + row: newRow(doc), + cell: newCell, + replace: replace, + gap: createCell + }; + }; + var paste = function (doc) { + return { + row: newRow(doc), + cell: createCell, + replace: pasteReplace, + gap: createCell + }; + }; + var TableFill = { + cellOperations: cellOperations, + paste: paste + }; + + var fromHtml$1 = function (html, scope) { + var doc = scope || domGlobals.document; + var div = doc.createElement('div'); + div.innerHTML = html; + return children(Element.fromDom(div)); + }; + + var inSelection = function (bounds, detail) { + var leftEdge = detail.column(); + var rightEdge = detail.column() + detail.colspan() - 1; + var topEdge = detail.row(); + var bottomEdge = detail.row() + detail.rowspan() - 1; + return leftEdge <= bounds.finishCol() && rightEdge >= bounds.startCol() && (topEdge <= bounds.finishRow() && bottomEdge >= bounds.startRow()); + }; + var isWithin = function (bounds, detail) { + return detail.column() >= bounds.startCol() && detail.column() + detail.colspan() - 1 <= bounds.finishCol() && detail.row() >= bounds.startRow() && detail.row() + detail.rowspan() - 1 <= bounds.finishRow(); + }; + var isRectangular = function (warehouse, bounds) { + var isRect = true; + var detailIsWithin = curry(isWithin, bounds); + for (var i = bounds.startRow(); i <= bounds.finishRow(); i++) { + for (var j = bounds.startCol(); j <= bounds.finishCol(); j++) { + isRect = isRect && Warehouse.getAt(warehouse, i, j).exists(detailIsWithin); + } + } + return isRect ? Option.some(bounds) : Option.none(); + }; + var CellBounds = { + inSelection: inSelection, + isWithin: isWithin, + isRectangular: isRectangular + }; + + var getBounds = function (detailA, detailB) { + return bounds(Math.min(detailA.row(), detailB.row()), Math.min(detailA.column(), detailB.column()), Math.max(detailA.row() + detailA.rowspan() - 1, detailB.row() + detailB.rowspan() - 1), Math.max(detailA.column() + detailA.colspan() - 1, detailB.column() + detailB.colspan() - 1)); + }; + var getAnyBox = function (warehouse, startCell, finishCell) { + var startCoords = Warehouse.findItem(warehouse, startCell, eq); + var finishCoords = Warehouse.findItem(warehouse, finishCell, eq); + return startCoords.bind(function (sc) { + return finishCoords.map(function (fc) { + return getBounds(sc, fc); + }); + }); + }; + var getBox = function (warehouse, startCell, finishCell) { + return getAnyBox(warehouse, startCell, finishCell).bind(function (bounds) { + return CellBounds.isRectangular(warehouse, bounds); + }); + }; + var CellGroup = { + getAnyBox: getAnyBox, + getBox: getBox + }; + + var moveBy = function (warehouse, cell, row, column) { + return Warehouse.findItem(warehouse, cell, eq).bind(function (detail) { + var startRow = row > 0 ? detail.row() + detail.rowspan() - 1 : detail.row(); + var startCol = column > 0 ? detail.column() + detail.colspan() - 1 : detail.column(); + var dest = Warehouse.getAt(warehouse, startRow + row, startCol + column); + return dest.map(function (d) { + return d.element(); + }); + }); + }; + var intercepts = function (warehouse, start, finish) { + return CellGroup.getAnyBox(warehouse, start, finish).map(function (bounds) { + var inside = Warehouse.filterItems(warehouse, curry(CellBounds.inSelection, bounds)); + return map(inside, function (detail) { + return detail.element(); + }); + }); + }; + var parentCell = function (warehouse, innerCell) { + var isContainedBy = function (c1, c2) { + return contains$2(c2, c1); + }; + return Warehouse.findItem(warehouse, innerCell, isContainedBy).map(function (detail) { + return detail.element(); + }); + }; + var CellFinder = { + moveBy: moveBy, + intercepts: intercepts, + parentCell: parentCell + }; + + var moveBy$1 = function (cell, deltaRow, deltaColumn) { + return TableLookup.table(cell).bind(function (table) { + var warehouse = getWarehouse(table); + return CellFinder.moveBy(warehouse, cell, deltaRow, deltaColumn); + }); + }; + var intercepts$1 = function (table, first, last) { + var warehouse = getWarehouse(table); + return CellFinder.intercepts(warehouse, first, last); + }; + var nestedIntercepts = function (table, first, firstTable, last, lastTable) { + var warehouse = getWarehouse(table); + var optStartCell = eq(table, firstTable) ? Option.some(first) : CellFinder.parentCell(warehouse, first); + var optLastCell = eq(table, lastTable) ? Option.some(last) : CellFinder.parentCell(warehouse, last); + return optStartCell.bind(function (startCell) { + return optLastCell.bind(function (lastCell) { + return CellFinder.intercepts(warehouse, startCell, lastCell); + }); + }); + }; + var getBox$1 = function (table, first, last) { + var warehouse = getWarehouse(table); + return CellGroup.getBox(warehouse, first, last); + }; + var getWarehouse = function (table) { + var list = DetailsList.fromTable(table); + return Warehouse.generate(list); + }; + var TablePositions = { + moveBy: moveBy$1, + intercepts: intercepts$1, + nestedIntercepts: nestedIntercepts, + getBox: getBox$1 + }; + + var TagBoundaries = [ + 'body', + 'p', + 'div', + 'article', + 'aside', + 'figcaption', + 'figure', + 'footer', + 'header', + 'nav', + 'section', + 'ol', + 'ul', + 'li', + 'table', + 'thead', + 'tbody', + 'tfoot', + 'caption', + 'tr', + 'td', + 'th', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'blockquote', + 'pre', + 'address' + ]; + + function DomUniverse () { + var clone$1 = function (element) { + return Element.fromDom(element.dom().cloneNode(false)); + }; + var document = function (element) { + return element.dom().ownerDocument; + }; + var isBoundary = function (element) { + if (!isElement(element)) { + return false; + } + if (name(element) === 'body') { + return true; + } + return contains(TagBoundaries, name(element)); + }; + var isEmptyTag = function (element) { + if (!isElement(element)) { + return false; + } + return contains([ + 'br', + 'img', + 'hr', + 'input' + ], name(element)); + }; + var comparePosition = function (element, other) { + return element.dom().compareDocumentPosition(other.dom()); + }; + var copyAttributesTo = function (source, destination) { + var as = clone(source); + setAll(destination, as); + }; + return { + up: constant({ + selector: ancestor$1, + closest: closest$1, + predicate: ancestor, + all: parents + }), + down: constant({ + selector: descendants$1, + predicate: descendants + }), + styles: constant({ + get: get$1, + getRaw: getRaw, + set: set$1, + remove: remove$1 + }), + attrs: constant({ + get: get, + set: set, + remove: remove, + copyTo: copyAttributesTo + }), + insert: constant({ + before: before, + after: after, + afterAll: after$1, + append: append, + appendAll: append$1, + prepend: prepend, + wrap: wrap + }), + remove: constant({ + unwrap: unwrap, + remove: remove$2 + }), + create: constant({ + nu: Element.fromTag, + clone: clone$1, + text: Element.fromText + }), + query: constant({ + comparePosition: comparePosition, + prevSibling: prevSibling, + nextSibling: nextSibling + }), + property: constant({ + children: children, + name: name, + parent: parent, + document: document, + isText: isText, + isComment: isComment, + isElement: isElement, + getText: get$2, + setText: set$2, + isBoundary: isBoundary, + isEmptyTag: isEmptyTag + }), + eq: eq, + is: is$1 + }; + } + + var leftRight = Immutable('left', 'right'); + var brokenPath = Immutable('first', 'second', 'splits'); + var bisect = function (universe, parent, child) { + var children = universe.property().children(parent); + var index = findIndex(children, curry(universe.eq, child)); + return index.map(function (ind) { + return { + before: constant(children.slice(0, ind)), + after: constant(children.slice(ind + 1)) + }; + }); + }; + var breakToRight = function (universe, parent, child) { + return bisect(universe, parent, child).map(function (parts) { + var second = universe.create().clone(parent); + universe.insert().appendAll(second, parts.after()); + universe.insert().after(parent, second); + return leftRight(parent, second); + }); + }; + var breakToLeft = function (universe, parent, child) { + return bisect(universe, parent, child).map(function (parts) { + var prior = universe.create().clone(parent); + universe.insert().appendAll(prior, parts.before().concat([child])); + universe.insert().appendAll(parent, parts.after()); + universe.insert().before(parent, prior); + return leftRight(prior, parent); + }); + }; + var breakPath = function (universe, item, isTop, breaker) { + var next = function (child, group, splits) { + var fallback = brokenPath(child, Option.none(), splits); + if (isTop(child)) { + return brokenPath(child, group, splits); + } else { + return universe.property().parent(child).bind(function (parent) { + return breaker(universe, parent, child).map(function (breakage) { + var extra = [{ + first: breakage.left, + second: breakage.right + }]; + var nextChild = isTop(parent) ? parent : breakage.left(); + return next(nextChild, Option.some(breakage.right()), splits.concat(extra)); + }); + }).getOr(fallback); + } + }; + return next(item, Option.none(), []); + }; + + var all$1 = function (universe, look, elements, f) { + var head = elements[0]; + var tail = elements.slice(1); + return f(universe, look, head, tail); + }; + var oneAll = function (universe, look, elements) { + return elements.length > 0 ? all$1(universe, look, elements, unsafeOne) : Option.none(); + }; + var unsafeOne = function (universe, look, head, tail) { + var start = look(universe, head); + return foldr(tail, function (b, a) { + var current = look(universe, a); + return commonElement(universe, b, current); + }, start); + }; + var commonElement = function (universe, start, end) { + return start.bind(function (s) { + return end.filter(curry(universe.eq, s)); + }); + }; + + var eq$1 = function (universe, item) { + return curry(universe.eq, item); + }; + var unsafeSubset = function (universe, common, ps1, ps2) { + var children = universe.property().children(common); + if (universe.eq(common, ps1[0])) { + return Option.some([ps1[0]]); + } + if (universe.eq(common, ps2[0])) { + return Option.some([ps2[0]]); + } + var finder = function (ps) { + var topDown = reverse(ps); + var index = findIndex(topDown, eq$1(universe, common)).getOr(-1); + var item = index < topDown.length - 1 ? topDown[index + 1] : topDown[index]; + return findIndex(children, eq$1(universe, item)); + }; + var startIndex = finder(ps1); + var endIndex = finder(ps2); + return startIndex.bind(function (sIndex) { + return endIndex.map(function (eIndex) { + var first = Math.min(sIndex, eIndex); + var last = Math.max(sIndex, eIndex); + return children.slice(first, last + 1); + }); + }); + }; + var ancestors$2 = function (universe, start, end, isRoot) { + if (isRoot === void 0) { + isRoot = never; + } + var ps1 = [start].concat(universe.up().all(start)); + var ps2 = [end].concat(universe.up().all(end)); + var prune = function (path) { + var index = findIndex(path, isRoot); + return index.fold(function () { + return path; + }, function (ind) { + return path.slice(0, ind + 1); + }); + }; + var pruned1 = prune(ps1); + var pruned2 = prune(ps2); + var shared = find(pruned1, function (x) { + return exists(pruned2, eq$1(universe, x)); + }); + return { + firstpath: constant(pruned1), + secondpath: constant(pruned2), + shared: constant(shared) + }; + }; + var subset = function (universe, start, end) { + var ancs = ancestors$2(universe, start, end); + return ancs.shared().bind(function (shared) { + return unsafeSubset(universe, shared, ancs.firstpath(), ancs.secondpath()); + }); + }; + var SubsetFn = { + subset: subset, + ancestors: ancestors$2 + }; + + var sharedOne = oneAll; + var subset$1 = SubsetFn.subset; + var ancestors$3 = SubsetFn.ancestors; + var breakToLeft$1 = breakToLeft; + var breakToRight$1 = breakToRight; + var breakPath$1 = breakPath; + var Parent = { + sharedOne: sharedOne, + subset: subset$1, + ancestors: ancestors$3, + breakToLeft: breakToLeft$1, + breakToRight: breakToRight$1, + breakPath: breakPath$1 + }; + + var universe = DomUniverse(); + var sharedOne$1 = function (look, elements) { + return Parent.sharedOne(universe, function (_universe, element) { + return look(element); + }, elements); + }; + var subset$2 = function (start, finish) { + return Parent.subset(universe, start, finish); + }; + var ancestors$4 = function (start, finish, isRoot) { + return Parent.ancestors(universe, start, finish, isRoot); + }; + var breakToLeft$2 = function (parent, child) { + return Parent.breakToLeft(universe, parent, child); + }; + var breakToRight$2 = function (parent, child) { + return Parent.breakToRight(universe, parent, child); + }; + var breakPath$2 = function (child, isTop, breaker) { + return Parent.breakPath(universe, child, isTop, function (u, p, c) { + return breaker(p, c); + }); + }; + var DomParent = { + sharedOne: sharedOne$1, + subset: subset$2, + ancestors: ancestors$4, + breakToLeft: breakToLeft$2, + breakToRight: breakToRight$2, + breakPath: breakPath$2 + }; + + var create = MixedBag([ + 'boxes', + 'start', + 'finish' + ], []); + var Identified = { create: create }; + + var lookupTable = function (container) { + return ancestor$1(container, 'table'); + }; + var identify = function (start, finish, isRoot) { + var getIsRoot = function (rootTable) { + return function (element) { + return isRoot !== undefined && isRoot(element) || eq(element, rootTable); + }; + }; + if (eq(start, finish)) { + return Option.some(Identified.create({ + boxes: Option.some([start]), + start: start, + finish: finish + })); + } else { + return lookupTable(start).bind(function (startTable) { + return lookupTable(finish).bind(function (finishTable) { + if (eq(startTable, finishTable)) { + return Option.some(Identified.create({ + boxes: TablePositions.intercepts(startTable, start, finish), + start: start, + finish: finish + })); + } else if (contains$2(startTable, finishTable)) { + var ancestorCells = ancestors$1(finish, 'td,th', getIsRoot(startTable)); + var finishCell = ancestorCells.length > 0 ? ancestorCells[ancestorCells.length - 1] : finish; + return Option.some(Identified.create({ + boxes: TablePositions.nestedIntercepts(startTable, start, startTable, finish, finishTable), + start: start, + finish: finishCell + })); + } else if (contains$2(finishTable, startTable)) { + var ancestorCells = ancestors$1(start, 'td,th', getIsRoot(finishTable)); + var startCell = ancestorCells.length > 0 ? ancestorCells[ancestorCells.length - 1] : start; + return Option.some(Identified.create({ + boxes: TablePositions.nestedIntercepts(finishTable, start, startTable, finish, finishTable), + start: start, + finish: startCell + })); + } else { + return DomParent.ancestors(start, finish).shared().bind(function (lca) { + return closest$1(lca, 'table', isRoot).bind(function (lcaTable) { + var finishAncestorCells = ancestors$1(finish, 'td,th', getIsRoot(lcaTable)); + var finishCell = finishAncestorCells.length > 0 ? finishAncestorCells[finishAncestorCells.length - 1] : finish; + var startAncestorCells = ancestors$1(start, 'td,th', getIsRoot(lcaTable)); + var startCell = startAncestorCells.length > 0 ? startAncestorCells[startAncestorCells.length - 1] : start; + return Option.some(Identified.create({ + boxes: TablePositions.nestedIntercepts(lcaTable, start, startTable, finish, finishTable), + start: startCell, + finish: finishCell + })); + }); + }); + } + }); + }); + } + }; + var retrieve = function (container, selector) { + var sels = descendants$1(container, selector); + return sels.length > 0 ? Option.some(sels) : Option.none(); + }; + var getLast = function (boxes, lastSelectedSelector) { + return find(boxes, function (box) { + return is(box, lastSelectedSelector); + }); + }; + var getEdges = function (container, firstSelectedSelector, lastSelectedSelector) { + return descendant$1(container, firstSelectedSelector).bind(function (first) { + return descendant$1(container, lastSelectedSelector).bind(function (last) { + return DomParent.sharedOne(lookupTable, [ + first, + last + ]).map(function (tbl) { + return { + first: constant(first), + last: constant(last), + table: constant(tbl) + }; + }); + }); + }); + }; + var expandTo = function (finish, firstSelectedSelector) { + return ancestor$1(finish, 'table').bind(function (table) { + return descendant$1(table, firstSelectedSelector).bind(function (start) { + return identify(start, finish).bind(function (identified) { + return identified.boxes().map(function (boxes) { + return { + boxes: constant(boxes), + start: constant(identified.start()), + finish: constant(identified.finish()) + }; + }); + }); + }); + }); + }; + var shiftSelection = function (boxes, deltaRow, deltaColumn, firstSelectedSelector, lastSelectedSelector) { + return getLast(boxes, lastSelectedSelector).bind(function (last) { + return TablePositions.moveBy(last, deltaRow, deltaColumn).bind(function (finish) { + return expandTo(finish, firstSelectedSelector); + }); + }); + }; + var CellSelection = { + identify: identify, + retrieve: retrieve, + shiftSelection: shiftSelection, + getEdges: getEdges + }; + + var retrieve$1 = function (container, selector) { + return CellSelection.retrieve(container, selector); + }; + var retrieveBox = function (container, firstSelectedSelector, lastSelectedSelector) { + return CellSelection.getEdges(container, firstSelectedSelector, lastSelectedSelector).bind(function (edges) { + var isRoot = function (ancestor) { + return eq(container, ancestor); + }; + var firstAncestor = ancestor$1(edges.first(), 'thead,tfoot,tbody,table', isRoot); + var lastAncestor = ancestor$1(edges.last(), 'thead,tfoot,tbody,table', isRoot); + return firstAncestor.bind(function (fA) { + return lastAncestor.bind(function (lA) { + return eq(fA, lA) ? TablePositions.getBox(edges.table(), edges.first(), edges.last()) : Option.none(); + }); + }); + }); + }; + var TableSelection = { + retrieve: retrieve$1, + retrieveBox: retrieveBox + }; + + var selected = 'data-mce-selected'; + var selectedSelector = 'td[' + selected + '],th[' + selected + ']'; + var attributeSelector = '[' + selected + ']'; + var firstSelected = 'data-mce-first-selected'; + var firstSelectedSelector = 'td[' + firstSelected + '],th[' + firstSelected + ']'; + var lastSelected = 'data-mce-last-selected'; + var lastSelectedSelector = 'td[' + lastSelected + '],th[' + lastSelected + ']'; + var Ephemera = { + selected: constant(selected), + selectedSelector: constant(selectedSelector), + attributeSelector: constant(attributeSelector), + firstSelected: constant(firstSelected), + firstSelectedSelector: constant(firstSelectedSelector), + lastSelected: constant(lastSelected), + lastSelectedSelector: constant(lastSelectedSelector) + }; + + var generate$1 = function (cases) { + if (!isArray(cases)) { + throw new Error('cases must be an array'); + } + if (cases.length === 0) { + throw new Error('there must be at least one case'); + } + var constructors = []; + var adt = {}; + each(cases, function (acase, count) { + var keys$1 = keys(acase); + if (keys$1.length !== 1) { + throw new Error('one and only one name per case'); + } + var key = keys$1[0]; + var value = acase[key]; + if (adt[key] !== undefined) { + throw new Error('duplicate key detected:' + key); + } else if (key === 'cata') { + throw new Error('cannot have a case named cata (sorry)'); + } else if (!isArray(value)) { + throw new Error('case arguments must be an array'); + } + constructors.push(key); + adt[key] = function () { + var argLength = arguments.length; + if (argLength !== value.length) { + throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength); + } + var args = new Array(argLength); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + var match = function (branches) { + var branchKeys = keys(branches); + if (constructors.length !== branchKeys.length) { + throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(',')); + } + var allReqd = forall(constructors, function (reqKey) { + return contains(branchKeys, reqKey); + }); + if (!allReqd) { + throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', ')); + } + return branches[key].apply(null, args); + }; + return { + fold: function () { + if (arguments.length !== cases.length) { + throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length); + } + var target = arguments[count]; + return target.apply(null, args); + }, + match: match, + log: function (label) { + domGlobals.console.log(label, { + constructors: constructors, + constructor: key, + params: args + }); + } + }; + }; + }); + return adt; + }; + var Adt = { generate: generate$1 }; + + var type$1 = Adt.generate([ + { none: [] }, + { multiple: ['elements'] }, + { single: ['selection'] } + ]); + var cata = function (subject, onNone, onMultiple, onSingle) { + return subject.fold(onNone, onMultiple, onSingle); + }; + var SelectionTypes = { + cata: cata, + none: type$1.none, + multiple: type$1.multiple, + single: type$1.single + }; + + var selection = function (cell, selections) { + return SelectionTypes.cata(selections.get(), constant([]), identity, constant([cell])); + }; + var unmergable = function (cell, selections) { + var hasSpan = function (elem) { + return has(elem, 'rowspan') && parseInt(get(elem, 'rowspan'), 10) > 1 || has(elem, 'colspan') && parseInt(get(elem, 'colspan'), 10) > 1; + }; + var candidates = selection(cell, selections); + return candidates.length > 0 && forall(candidates, hasSpan) ? Option.some(candidates) : Option.none(); + }; + var mergable = function (table, selections) { + return SelectionTypes.cata(selections.get(), Option.none, function (cells, _env) { + if (cells.length === 0) { + return Option.none(); + } + return TableSelection.retrieveBox(table, Ephemera.firstSelectedSelector(), Ephemera.lastSelectedSelector()).bind(function (bounds) { + return cells.length > 1 ? Option.some({ + bounds: constant(bounds), + cells: constant(cells) + }) : Option.none(); + }); + }, Option.none); + }; + var CellOperations = { + mergable: mergable, + unmergable: unmergable, + selection: selection + }; + + var noMenu = function (cell) { + return { + element: constant(cell), + mergable: Option.none, + unmergable: Option.none, + selection: constant([cell]) + }; + }; + var forMenu = function (selections, table, cell) { + return { + element: constant(cell), + mergable: constant(CellOperations.mergable(table, selections)), + unmergable: constant(CellOperations.unmergable(cell, selections)), + selection: constant(CellOperations.selection(cell, selections)) + }; + }; + var notCell$1 = function (element) { + return noMenu(element); + }; + var paste$1 = Immutable('element', 'clipboard', 'generators'); + var pasteRows = function (selections, table, cell, clipboard, generators) { + return { + element: constant(cell), + mergable: Option.none, + unmergable: Option.none, + selection: constant(CellOperations.selection(cell, selections)), + clipboard: constant(clipboard), + generators: constant(generators) + }; + }; + var TableTargets = { + noMenu: noMenu, + forMenu: forMenu, + notCell: notCell$1, + paste: paste$1, + pasteRows: pasteRows + }; + + var extractSelected = function (cells) { + return TableLookup.table(cells[0]).map(deep).map(function (replica) { + return [CopySelected.extract(replica, Ephemera.attributeSelector())]; + }); + }; + var serializeElements = function (editor, elements) { + return map(elements, function (elm) { + return editor.selection.serializer.serialize(elm.dom(), {}); + }).join(''); + }; + var getTextContent = function (elements) { + return map(elements, function (element) { + return element.dom().innerText; + }).join(''); + }; + var registerEvents = function (editor, selections, actions, cellSelection) { + editor.on('BeforeGetContent', function (e) { + var multiCellContext = function (cells) { + e.preventDefault(); + extractSelected(cells).each(function (elements) { + e.content = e.format === 'text' ? getTextContent(elements) : serializeElements(editor, elements); + }); + }; + if (e.selection === true) { + SelectionTypes.cata(selections.get(), noop, multiCellContext, noop); + } + }); + editor.on('BeforeSetContent', function (e) { + if (e.selection === true && e.paste === true) { + var cellOpt = Option.from(editor.dom.getParent(editor.selection.getStart(), 'th,td')); + cellOpt.each(function (domCell) { + var cell = Element.fromDom(domCell); + TableLookup.table(cell).each(function (table) { + var elements = filter(fromHtml$1(e.content), function (content) { + return name(content) !== 'meta'; + }); + if (elements.length === 1 && name(elements[0]) === 'table') { + e.preventDefault(); + var doc = Element.fromDom(editor.getDoc()); + var generators = TableFill.paste(doc); + var targets = TableTargets.paste(cell, elements[0], generators); + actions.pasteCells(table, targets).each(function (rng) { + editor.selection.setRng(rng); + editor.focus(); + cellSelection.clear(table); + }); + } + }); + }); + } + }); + }; + var Clipboard = { registerEvents: registerEvents }; + + function Dimension (name, getOffset) { + var set = function (element, h) { + if (!isNumber(h) && !h.match(/^[0-9]+$/)) { + throw new Error(name + '.set accepts only positive integer values. Value was ' + h); + } + var dom = element.dom(); + if (isSupported(dom)) { + dom.style[name] = h + 'px'; + } + }; + var get = function (element) { + var r = getOffset(element); + if (r <= 0 || r === null) { + var css = get$1(element, name); + return parseFloat(css) || 0; + } + return r; + }; + var getOuter = get; + var aggregate = function (element, properties) { + return foldl(properties, function (acc, property) { + var val = get$1(element, property); + var value = val === undefined ? 0 : parseInt(val, 10); + return isNaN(value) ? acc : acc + value; + }, 0); + }; + var max = function (element, value, properties) { + var cumulativeInclusions = aggregate(element, properties); + var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0; + return absoluteMax; + }; + return { + set: set, + get: get, + getOuter: getOuter, + aggregate: aggregate, + max: max + }; + } + + var api$1 = Dimension('height', function (element) { + var dom = element.dom(); + return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight; + }); + var get$3 = function (element) { + return api$1.get(element); + }; + var getOuter = function (element) { + return api$1.getOuter(element); + }; + + var api$2 = Dimension('width', function (element) { + return element.dom().offsetWidth; + }); + var get$4 = function (element) { + return api$2.get(element); + }; + var getOuter$1 = function (element) { + return api$2.getOuter(element); + }; + + var platform = PlatformDetection$1.detect(); + var needManualCalc = function () { + return platform.browser.isIE() || platform.browser.isEdge(); + }; + var toNumber = function (px, fallback) { + var num = parseFloat(px); + return isNaN(num) ? fallback : num; + }; + var getProp = function (elm, name, fallback) { + return toNumber(get$1(elm, name), fallback); + }; + var getCalculatedHeight = function (cell) { + var paddingTop = getProp(cell, 'padding-top', 0); + var paddingBottom = getProp(cell, 'padding-bottom', 0); + var borderTop = getProp(cell, 'border-top-width', 0); + var borderBottom = getProp(cell, 'border-bottom-width', 0); + var height = cell.dom().getBoundingClientRect().height; + var boxSizing = get$1(cell, 'box-sizing'); + var borders = borderTop + borderBottom; + return boxSizing === 'border-box' ? height : height - paddingTop - paddingBottom - borders; + }; + var getWidth = function (cell) { + return getProp(cell, 'width', get$4(cell)); + }; + var getHeight = function (cell) { + return needManualCalc() ? getCalculatedHeight(cell) : getProp(cell, 'height', get$3(cell)); + }; + var RuntimeSize = { + getWidth: getWidth, + getHeight: getHeight + }; + + var genericSizeRegex = /(\d+(\.\d+)?)(\w|%)*/; + var percentageBasedSizeRegex = /(\d+(\.\d+)?)%/; + var pixelBasedSizeRegex = /(\d+(\.\d+)?)px|em/; + var setPixelWidth = function (cell, amount) { + set$1(cell, 'width', amount + 'px'); + }; + var setPercentageWidth = function (cell, amount) { + set$1(cell, 'width', amount + '%'); + }; + var setHeight = function (cell, amount) { + set$1(cell, 'height', amount + 'px'); + }; + var getHeightValue = function (cell) { + return getRaw(cell, 'height').getOrThunk(function () { + return RuntimeSize.getHeight(cell) + 'px'; + }); + }; + var convert = function (cell, number, getter, setter) { + var newSize = TableLookup.table(cell).map(function (table) { + var total = getter(table); + return Math.floor(number / 100 * total); + }).getOr(number); + setter(cell, newSize); + return newSize; + }; + var normalizePixelSize = function (value, cell, getter, setter) { + var number = parseInt(value, 10); + return endsWith(value, '%') && name(cell) !== 'table' ? convert(cell, number, getter, setter) : number; + }; + var getTotalHeight = function (cell) { + var value = getHeightValue(cell); + if (!value) { + return get$3(cell); + } + return normalizePixelSize(value, cell, get$3, setHeight); + }; + var get$5 = function (cell, type, f) { + var v = f(cell); + var span = getSpan(cell, type); + return v / span; + }; + var getSpan = function (cell, type) { + return has(cell, type) ? parseInt(get(cell, type), 10) : 1; + }; + var getRawWidth = function (element) { + var cssWidth = getRaw(element, 'width'); + return cssWidth.fold(function () { + return Option.from(get(element, 'width')); + }, function (width) { + return Option.some(width); + }); + }; + var normalizePercentageWidth = function (cellWidth, tableSize) { + return cellWidth / tableSize.pixelWidth() * 100; + }; + var choosePercentageSize = function (element, width, tableSize) { + var percentMatch = percentageBasedSizeRegex.exec(width); + if (percentMatch !== null) { + return parseFloat(percentMatch[1]); + } else { + var intWidth = get$4(element); + return normalizePercentageWidth(intWidth, tableSize); + } + }; + var getPercentageWidth = function (cell, tableSize) { + var width = getRawWidth(cell); + return width.fold(function () { + var intWidth = get$4(cell); + return normalizePercentageWidth(intWidth, tableSize); + }, function (w) { + return choosePercentageSize(cell, w, tableSize); + }); + }; + var normalizePixelWidth = function (cellWidth, tableSize) { + return cellWidth / 100 * tableSize.pixelWidth(); + }; + var choosePixelSize = function (element, width, tableSize) { + var pixelMatch = pixelBasedSizeRegex.exec(width); + if (pixelMatch !== null) { + return parseInt(pixelMatch[1], 10); + } + var percentMatch = percentageBasedSizeRegex.exec(width); + if (percentMatch !== null) { + var floatWidth = parseFloat(percentMatch[1]); + return normalizePixelWidth(floatWidth, tableSize); + } + return get$4(element); + }; + var getPixelWidth = function (cell, tableSize) { + var width = getRawWidth(cell); + return width.fold(function () { + return get$4(cell); + }, function (w) { + return choosePixelSize(cell, w, tableSize); + }); + }; + var getHeight$1 = function (cell) { + return get$5(cell, 'rowspan', getTotalHeight); + }; + var getGenericWidth = function (cell) { + var width = getRawWidth(cell); + return width.bind(function (w) { + var match = genericSizeRegex.exec(w); + if (match !== null) { + return Option.some({ + width: constant(parseFloat(match[1])), + unit: constant(match[3]) + }); + } else { + return Option.none(); + } + }); + }; + var setGenericWidth = function (cell, amount, unit) { + set$1(cell, 'width', amount + unit); + }; + var Sizes = { + percentageBasedSizeRegex: constant(percentageBasedSizeRegex), + pixelBasedSizeRegex: constant(pixelBasedSizeRegex), + setPixelWidth: setPixelWidth, + setPercentageWidth: setPercentageWidth, + setHeight: setHeight, + getPixelWidth: getPixelWidth, + getPercentageWidth: getPercentageWidth, + getGenericWidth: getGenericWidth, + setGenericWidth: setGenericWidth, + getHeight: getHeight$1, + getRawWidth: getRawWidth + }; + + var halve = function (main, other) { + var width = Sizes.getGenericWidth(main); + width.each(function (w) { + var newWidth = w.width() / 2; + Sizes.setGenericWidth(main, newWidth, w.unit()); + Sizes.setGenericWidth(other, newWidth, w.unit()); + }); + }; + var CellMutations = { halve: halve }; + + var r = function (left, top) { + var translate = function (x, y) { + return r(left + x, top + y); + }; + return { + left: constant(left), + top: constant(top), + translate: translate + }; + }; + var Position = r; + + var boxPosition = function (dom) { + var box = dom.getBoundingClientRect(); + return Position(box.left, box.top); + }; + var firstDefinedOrZero = function (a, b) { + return a !== undefined ? a : b !== undefined ? b : 0; + }; + var absolute = function (element) { + var doc = element.dom().ownerDocument; + var body = doc.body; + var win = doc.defaultView; + var html = doc.documentElement; + var scrollTop = firstDefinedOrZero(win.pageYOffset, html.scrollTop); + var scrollLeft = firstDefinedOrZero(win.pageXOffset, html.scrollLeft); + var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop); + var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft); + return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop); + }; + var viewport = function (element) { + var dom = element.dom(); + var doc = dom.ownerDocument; + var body = doc.body; + if (body === dom) { + return Position(body.offsetLeft, body.offsetTop); + } + if (!inBody(element)) { + return Position(0, 0); + } + return boxPosition(dom); + }; + + var rowInfo = Immutable('row', 'y'); + var colInfo = Immutable('col', 'x'); + var rtlEdge = function (cell) { + var pos = absolute(cell); + return pos.left() + getOuter$1(cell); + }; + var ltrEdge = function (cell) { + return absolute(cell).left(); + }; + var getLeftEdge = function (index, cell) { + return colInfo(index, ltrEdge(cell)); + }; + var getRightEdge = function (index, cell) { + return colInfo(index, rtlEdge(cell)); + }; + var getTop = function (cell) { + return absolute(cell).top(); + }; + var getTopEdge = function (index, cell) { + return rowInfo(index, getTop(cell)); + }; + var getBottomEdge = function (index, cell) { + return rowInfo(index, getTop(cell) + getOuter(cell)); + }; + var findPositions = function (getInnerEdge, getOuterEdge, array) { + if (array.length === 0) { + return []; + } + var lines = map(array.slice(1), function (cellOption, index) { + return cellOption.map(function (cell) { + return getInnerEdge(index, cell); + }); + }); + var lastLine = array[array.length - 1].map(function (cell) { + return getOuterEdge(array.length - 1, cell); + }); + return lines.concat([lastLine]); + }; + var negate = function (step) { + return -step; + }; + var height = { + delta: identity, + positions: function (optElements) { + return findPositions(getTopEdge, getBottomEdge, optElements); + }, + edge: getTop + }; + var ltr = { + delta: identity, + edge: ltrEdge, + positions: function (optElements) { + return findPositions(getLeftEdge, getRightEdge, optElements); + } + }; + var rtl = { + delta: negate, + edge: rtlEdge, + positions: function (optElements) { + return findPositions(getRightEdge, getLeftEdge, optElements); + } + }; + var BarPositions = { + height: height, + rtl: rtl, + ltr: ltr + }; + + var ResizeDirection = { + ltr: BarPositions.ltr, + rtl: BarPositions.rtl + }; + + function TableDirection (directionAt) { + var auto = function (table) { + return directionAt(table).isRtl() ? ResizeDirection.rtl : ResizeDirection.ltr; + }; + var delta = function (amount, table) { + return auto(table).delta(amount, table); + }; + var positions = function (cols, table) { + return auto(table).positions(cols, table); + }; + var edge = function (cell) { + return auto(cell).edge(cell); + }; + return { + delta: delta, + edge: edge, + positions: positions + }; + } + + var getGridSize = function (table) { + var input = DetailsList.fromTable(table); + var warehouse = Warehouse.generate(input); + return warehouse.grid(); + }; + var TableGridSize = { getGridSize: getGridSize }; + + var __assign = function () { + __assign = Object.assign || function __assign(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + + var cat = function (arr) { + var r = []; + var push = function (x) { + r.push(x); + }; + for (var i = 0; i < arr.length; i++) { + arr[i].each(push); + } + return r; + }; + var findMap = function (arr, f) { + for (var i = 0; i < arr.length; i++) { + var r = f(arr[i], i); + if (r.isSome()) { + return r; + } + } + return Option.none(); + }; + + var setIfNot = function (element, property, value, ignore) { + if (value === ignore) { + remove(element, property); + } else { + set(element, property, value); + } + }; + var render = function (table, grid) { + var newRows = []; + var newCells = []; + var renderSection = function (gridSection, sectionName) { + var section = child$2(table, sectionName).getOrThunk(function () { + var tb = Element.fromTag(sectionName, owner(table).dom()); + append(table, tb); + return tb; + }); + empty(section); + var rows = map(gridSection, function (row) { + if (row.isNew()) { + newRows.push(row.element()); + } + var tr = row.element(); + empty(tr); + each(row.cells(), function (cell) { + if (cell.isNew()) { + newCells.push(cell.element()); + } + setIfNot(cell.element(), 'colspan', cell.colspan(), 1); + setIfNot(cell.element(), 'rowspan', cell.rowspan(), 1); + append(tr, cell.element()); + }); + return tr; + }); + append$1(section, rows); + }; + var removeSection = function (sectionName) { + child$2(table, sectionName).each(remove$2); + }; + var renderOrRemoveSection = function (gridSection, sectionName) { + if (gridSection.length > 0) { + renderSection(gridSection, sectionName); + } else { + removeSection(sectionName); + } + }; + var headSection = []; + var bodySection = []; + var footSection = []; + each(grid, function (row) { + switch (row.section()) { + case 'thead': + headSection.push(row); + break; + case 'tbody': + bodySection.push(row); + break; + case 'tfoot': + footSection.push(row); + break; + } + }); + renderOrRemoveSection(headSection, 'thead'); + renderOrRemoveSection(bodySection, 'tbody'); + renderOrRemoveSection(footSection, 'tfoot'); + return { + newRows: constant(newRows), + newCells: constant(newCells) + }; + }; + var copy$2 = function (grid) { + var rows = map(grid, function (row) { + var tr = shallow(row.element()); + each(row.cells(), function (cell) { + var clonedCell = deep(cell.element()); + setIfNot(clonedCell, 'colspan', cell.colspan(), 1); + setIfNot(clonedCell, 'rowspan', cell.rowspan(), 1); + append(tr, clonedCell); + }); + return tr; + }); + return rows; + }; + var Redraw = { + render: render, + copy: copy$2 + }; + + var read = function (element, attr) { + var value = get(element, attr); + return value === undefined || value === '' ? [] : value.split(' '); + }; + var add = function (element, attr, id) { + var old = read(element, attr); + var nu = old.concat([id]); + set(element, attr, nu.join(' ')); + return true; + }; + var remove$3 = function (element, attr, id) { + var nu = filter(read(element, attr), function (v) { + return v !== id; + }); + if (nu.length > 0) { + set(element, attr, nu.join(' ')); + } else { + remove(element, attr); + } + return false; + }; + + var supports = function (element) { + return element.dom().classList !== undefined; + }; + var get$6 = function (element) { + return read(element, 'class'); + }; + var add$1 = function (element, clazz) { + return add(element, 'class', clazz); + }; + var remove$4 = function (element, clazz) { + return remove$3(element, 'class', clazz); + }; + + var add$2 = function (element, clazz) { + if (supports(element)) { + element.dom().classList.add(clazz); + } else { + add$1(element, clazz); + } + }; + var cleanClass = function (element) { + var classList = supports(element) ? element.dom().classList : get$6(element); + if (classList.length === 0) { + remove(element, 'class'); + } + }; + var remove$5 = function (element, clazz) { + if (supports(element)) { + var classList = element.dom().classList; + classList.remove(clazz); + } else { + remove$4(element, clazz); + } + cleanClass(element); + }; + var has$1 = function (element, clazz) { + return supports(element) && element.dom().classList.contains(clazz); + }; + + var repeat = function (repititions, f) { + var r = []; + for (var i = 0; i < repititions; i++) { + r.push(f(i)); + } + return r; + }; + var range = function (start, end) { + var r = []; + for (var i = start; i < end; i++) { + r.push(i); + } + return r; + }; + var deduce = function (xs, index) { + if (index < 0 || index >= xs.length - 1) { + return Option.none(); + } + var current = xs[index].fold(function () { + var rest = reverse(xs.slice(0, index)); + return findMap(rest, function (a, i) { + return a.map(function (aa) { + return { + value: aa, + delta: i + 1 + }; + }); + }); + }, function (c) { + return Option.some({ + value: c, + delta: 0 + }); + }); + var next = xs[index + 1].fold(function () { + var rest = xs.slice(index + 1); + return findMap(rest, function (a, i) { + return a.map(function (aa) { + return { + value: aa, + delta: i + 1 + }; + }); + }); + }, function (n) { + return Option.some({ + value: n, + delta: 1 + }); + }); + return current.bind(function (c) { + return next.map(function (n) { + var extras = n.delta + c.delta; + return Math.abs(n.value - c.value) / extras; + }); + }); + }; + + var columns = function (warehouse) { + var grid = warehouse.grid(); + var cols = range(0, grid.columns()); + var rowsArr = range(0, grid.rows()); + return map(cols, function (col) { + var getBlock = function () { + return bind(rowsArr, function (r) { + return Warehouse.getAt(warehouse, r, col).filter(function (detail) { + return detail.column() === col; + }).fold(constant([]), function (detail) { + return [detail]; + }); + }); + }; + var isSingle = function (detail) { + return detail.colspan() === 1; + }; + var getFallback = function () { + return Warehouse.getAt(warehouse, 0, col); + }; + return decide(getBlock, isSingle, getFallback); + }); + }; + var decide = function (getBlock, isSingle, getFallback) { + var inBlock = getBlock(); + var singleInBlock = find(inBlock, isSingle); + var detailOption = singleInBlock.orThunk(function () { + return Option.from(inBlock[0]).orThunk(getFallback); + }); + return detailOption.map(function (detail) { + return detail.element(); + }); + }; + var rows$1 = function (warehouse) { + var grid = warehouse.grid(); + var rowsArr = range(0, grid.rows()); + var cols = range(0, grid.columns()); + return map(rowsArr, function (row) { + var getBlock = function () { + return bind(cols, function (c) { + return Warehouse.getAt(warehouse, row, c).filter(function (detail) { + return detail.row() === row; + }).fold(constant([]), function (detail) { + return [detail]; + }); + }); + }; + var isSingle = function (detail) { + return detail.rowspan() === 1; + }; + var getFallback = function () { + return Warehouse.getAt(warehouse, row, 0); + }; + return decide(getBlock, isSingle, getFallback); + }); + }; + var Blocks = { + columns: columns, + rows: rows$1 + }; + + var css = function (namespace) { + var dashNamespace = namespace.replace(/\./g, '-'); + var resolve = function (str) { + return dashNamespace + '-' + str; + }; + return { resolve: resolve }; + }; + + var styles = css('ephox-snooker'); + var Styles = { resolve: styles.resolve }; + + var col = function (column, x, y, w, h) { + var blocker = Element.fromTag('div'); + setAll$1(blocker, { + position: 'absolute', + left: x - w / 2 + 'px', + top: y + 'px', + height: h + 'px', + width: w + 'px' + }); + setAll(blocker, { + 'data-column': column, + 'role': 'presentation' + }); + return blocker; + }; + var row$1 = function (r, x, y, w, h) { + var blocker = Element.fromTag('div'); + setAll$1(blocker, { + position: 'absolute', + left: x + 'px', + top: y - h / 2 + 'px', + height: h + 'px', + width: w + 'px' + }); + setAll(blocker, { + 'data-row': r, + 'role': 'presentation' + }); + return blocker; + }; + var Bar = { + col: col, + row: row$1 + }; + + var resizeBar = Styles.resolve('resizer-bar'); + var resizeRowBar = Styles.resolve('resizer-rows'); + var resizeColBar = Styles.resolve('resizer-cols'); + var BAR_THICKNESS = 7; + var destroy = function (wire) { + var previous = descendants$1(wire.parent(), '.' + resizeBar); + each(previous, remove$2); + }; + var drawBar = function (wire, positions, create) { + var origin = wire.origin(); + each(positions, function (cpOption, i) { + cpOption.each(function (cp) { + var bar = create(origin, cp); + add$2(bar, resizeBar); + append(wire.parent(), bar); + }); + }); + }; + var refreshCol = function (wire, colPositions, position, tableHeight) { + drawBar(wire, colPositions, function (origin, cp) { + var colBar = Bar.col(cp.col(), cp.x() - origin.left(), position.top() - origin.top(), BAR_THICKNESS, tableHeight); + add$2(colBar, resizeColBar); + return colBar; + }); + }; + var refreshRow = function (wire, rowPositions, position, tableWidth) { + drawBar(wire, rowPositions, function (origin, cp) { + var rowBar = Bar.row(cp.row(), position.left() - origin.left(), cp.y() - origin.top(), tableWidth, BAR_THICKNESS); + add$2(rowBar, resizeRowBar); + return rowBar; + }); + }; + var refreshGrid = function (wire, table, rows, cols, hdirection, vdirection) { + var position = absolute(table); + var rowPositions = rows.length > 0 ? hdirection.positions(rows, table) : []; + refreshRow(wire, rowPositions, position, getOuter$1(table)); + var colPositions = cols.length > 0 ? vdirection.positions(cols, table) : []; + refreshCol(wire, colPositions, position, getOuter(table)); + }; + var refresh = function (wire, table, hdirection, vdirection) { + destroy(wire); + var list = DetailsList.fromTable(table); + var warehouse = Warehouse.generate(list); + var rows = Blocks.rows(warehouse); + var cols = Blocks.columns(warehouse); + refreshGrid(wire, table, rows, cols, hdirection, vdirection); + }; + var each$2 = function (wire, f) { + var bars = descendants$1(wire.parent(), '.' + resizeBar); + each(bars, f); + }; + var hide = function (wire) { + each$2(wire, function (bar) { + set$1(bar, 'display', 'none'); + }); + }; + var show = function (wire) { + each$2(wire, function (bar) { + set$1(bar, 'display', 'block'); + }); + }; + var isRowBar = function (element) { + return has$1(element, resizeRowBar); + }; + var isColBar = function (element) { + return has$1(element, resizeColBar); + }; + var Bars = { + refresh: refresh, + hide: hide, + show: show, + destroy: destroy, + isRowBar: isRowBar, + isColBar: isColBar + }; + + var addCell = function (gridRow, index, cell) { + var cells = gridRow.cells(); + var before = cells.slice(0, index); + var after = cells.slice(index); + var newCells = before.concat([cell]).concat(after); + return setCells(gridRow, newCells); + }; + var mutateCell = function (gridRow, index, cell) { + var cells = gridRow.cells(); + cells[index] = cell; + }; + var setCells = function (gridRow, cells) { + return rowcells(cells, gridRow.section()); + }; + var mapCells = function (gridRow, f) { + var cells = gridRow.cells(); + var r = map(cells, f); + return rowcells(r, gridRow.section()); + }; + var getCell = function (gridRow, index) { + return gridRow.cells()[index]; + }; + var getCellElement = function (gridRow, index) { + return getCell(gridRow, index).element(); + }; + var cellLength = function (gridRow) { + return gridRow.cells().length; + }; + var GridRow = { + addCell: addCell, + setCells: setCells, + mutateCell: mutateCell, + getCell: getCell, + getCellElement: getCellElement, + mapCells: mapCells, + cellLength: cellLength + }; + + var getColumn = function (grid, index) { + return map(grid, function (row) { + return GridRow.getCell(row, index); + }); + }; + var getRow = function (grid, index) { + return grid[index]; + }; + var findDiff = function (xs, comp) { + if (xs.length === 0) { + return 0; + } + var first = xs[0]; + var index = findIndex(xs, function (x) { + return !comp(first.element(), x.element()); + }); + return index.fold(function () { + return xs.length; + }, function (ind) { + return ind; + }); + }; + var subgrid = function (grid, row, column, comparator) { + var restOfRow = getRow(grid, row).cells().slice(column); + var endColIndex = findDiff(restOfRow, comparator); + var restOfColumn = getColumn(grid, column).slice(row); + var endRowIndex = findDiff(restOfColumn, comparator); + return { + colspan: constant(endColIndex), + rowspan: constant(endRowIndex) + }; + }; + var TableGrid = { subgrid: subgrid }; + + var toDetails = function (grid, comparator) { + var seen = map(grid, function (row, ri) { + return map(row.cells(), function (col, ci) { + return false; + }); + }); + var updateSeen = function (ri, ci, rowspan, colspan) { + for (var r = ri; r < ri + rowspan; r++) { + for (var c = ci; c < ci + colspan; c++) { + seen[r][c] = true; + } + } + }; + return map(grid, function (row, ri) { + var details = bind(row.cells(), function (cell, ci) { + if (seen[ri][ci] === false) { + var result = TableGrid.subgrid(grid, ri, ci, comparator); + updateSeen(ri, ci, result.rowspan(), result.colspan()); + return [detailnew(cell.element(), result.rowspan(), result.colspan(), cell.isNew())]; + } else { + return []; + } + }); + return rowdetails(details, row.section()); + }); + }; + var toGrid = function (warehouse, generators, isNew) { + var grid = []; + for (var i = 0; i < warehouse.grid().rows(); i++) { + var rowCells = []; + for (var j = 0; j < warehouse.grid().columns(); j++) { + var element = Warehouse.getAt(warehouse, i, j).map(function (item) { + return elementnew(item.element(), isNew); + }).getOrThunk(function () { + return elementnew(generators.gap(), true); + }); + rowCells.push(element); + } + var row = rowcells(rowCells, warehouse.all()[i].section()); + grid.push(row); + } + return grid; + }; + var Transitions = { + toDetails: toDetails, + toGrid: toGrid + }; + + var fromWarehouse = function (warehouse, generators) { + return Transitions.toGrid(warehouse, generators, false); + }; + var deriveRows = function (rendered, generators) { + var findRow = function (details) { + var rowOfCells = findMap(details, function (detail) { + return parent(detail.element()).map(function (row) { + var isNew = parent(row).isNone(); + return elementnew(row, isNew); + }); + }); + return rowOfCells.getOrThunk(function () { + return elementnew(generators.row(), true); + }); + }; + return map(rendered, function (details) { + var row = findRow(details.details()); + return rowdatanew(row.element(), details.details(), details.section(), row.isNew()); + }); + }; + var toDetailList = function (grid, generators) { + var rendered = Transitions.toDetails(grid, eq); + return deriveRows(rendered, generators); + }; + var findInWarehouse = function (warehouse, element) { + var all = flatten(map(warehouse.all(), function (r) { + return r.cells(); + })); + return find(all, function (e) { + return eq(element, e.element()); + }); + }; + var run = function (operation, extract, adjustment, postAction, genWrappers) { + return function (wire, table, target, generators, direction) { + var input = DetailsList.fromTable(table); + var warehouse = Warehouse.generate(input); + var output = extract(warehouse, target).map(function (info) { + var model = fromWarehouse(warehouse, generators); + var result = operation(model, info, eq, genWrappers(generators)); + var grid = toDetailList(result.grid(), generators); + return { + grid: constant(grid), + cursor: result.cursor + }; + }); + return output.fold(function () { + return Option.none(); + }, function (out) { + var newElements = Redraw.render(table, out.grid()); + adjustment(table, out.grid(), direction); + postAction(table); + Bars.refresh(wire, table, BarPositions.height, direction); + return Option.some({ + cursor: out.cursor, + newRows: newElements.newRows, + newCells: newElements.newCells + }); + }); + }; + }; + var onCell = function (warehouse, target) { + return TableLookup.cell(target.element()).bind(function (cell) { + return findInWarehouse(warehouse, cell); + }); + }; + var onPaste = function (warehouse, target) { + return TableLookup.cell(target.element()).bind(function (cell) { + return findInWarehouse(warehouse, cell).map(function (details) { + var value = __assign(__assign({}, details), { + generators: target.generators, + clipboard: target.clipboard + }); + return value; + }); + }); + }; + var onPasteRows = function (warehouse, target) { + var details = map(target.selection(), function (cell) { + return TableLookup.cell(cell).bind(function (lc) { + return findInWarehouse(warehouse, lc); + }); + }); + var cells = cat(details); + return cells.length > 0 ? Option.some({ + cells: cells, + generators: target.generators, + clipboard: target.clipboard + }) : Option.none(); + }; + var onMergable = function (_warehouse, target) { + return target.mergable(); + }; + var onUnmergable = function (_warehouse, target) { + return target.unmergable(); + }; + var onCells = function (warehouse, target) { + var details = map(target.selection(), function (cell) { + return TableLookup.cell(cell).bind(function (lc) { + return findInWarehouse(warehouse, lc); + }); + }); + var cells = cat(details); + return cells.length > 0 ? Option.some(cells) : Option.none(); + }; + + var value = function (o) { + var is = function (v) { + return o === v; + }; + var or = function (opt) { + return value(o); + }; + var orThunk = function (f) { + return value(o); + }; + var map = function (f) { + return value(f(o)); + }; + var mapError = function (f) { + return value(o); + }; + var each = function (f) { + f(o); + }; + var bind = function (f) { + return f(o); + }; + var fold = function (_, onValue) { + return onValue(o); + }; + var exists = function (f) { + return f(o); + }; + var forall = function (f) { + return f(o); + }; + var toOption = function () { + return Option.some(o); + }; + return { + is: is, + isValue: always, + isError: never, + getOr: constant(o), + getOrThunk: constant(o), + getOrDie: constant(o), + or: or, + orThunk: orThunk, + fold: fold, + map: map, + mapError: mapError, + each: each, + bind: bind, + exists: exists, + forall: forall, + toOption: toOption + }; + }; + var error = function (message) { + var getOrThunk = function (f) { + return f(); + }; + var getOrDie = function () { + return die(String(message))(); + }; + var or = function (opt) { + return opt; + }; + var orThunk = function (f) { + return f(); + }; + var map = function (f) { + return error(message); + }; + var mapError = function (f) { + return error(f(message)); + }; + var bind = function (f) { + return error(message); + }; + var fold = function (onError, _) { + return onError(message); + }; + return { + is: never, + isValue: never, + isError: always, + getOr: identity, + getOrThunk: getOrThunk, + getOrDie: getOrDie, + or: or, + orThunk: orThunk, + fold: fold, + map: map, + mapError: mapError, + each: noop, + bind: bind, + exists: never, + forall: always, + toOption: Option.none + }; + }; + var fromOption = function (opt, err) { + return opt.fold(function () { + return error(err); + }, value); + }; + var Result = { + value: value, + error: error, + fromOption: fromOption + }; + + var measure = function (startAddress, gridA, gridB) { + if (startAddress.row() >= gridA.length || startAddress.column() > GridRow.cellLength(gridA[0])) { + return Result.error('invalid start address out of table bounds, row: ' + startAddress.row() + ', column: ' + startAddress.column()); + } + var rowRemainder = gridA.slice(startAddress.row()); + var colRemainder = rowRemainder[0].cells().slice(startAddress.column()); + var colRequired = GridRow.cellLength(gridB[0]); + var rowRequired = gridB.length; + return Result.value({ + rowDelta: constant(rowRemainder.length - rowRequired), + colDelta: constant(colRemainder.length - colRequired) + }); + }; + var measureWidth = function (gridA, gridB) { + var colLengthA = GridRow.cellLength(gridA[0]); + var colLengthB = GridRow.cellLength(gridB[0]); + return { + rowDelta: constant(0), + colDelta: constant(colLengthA - colLengthB) + }; + }; + var fill = function (cells, generator) { + return map(cells, function () { + return elementnew(generator.cell(), true); + }); + }; + var rowFill = function (grid, amount, generator) { + return grid.concat(repeat(amount, function (_row) { + return GridRow.setCells(grid[grid.length - 1], fill(grid[grid.length - 1].cells(), generator)); + })); + }; + var colFill = function (grid, amount, generator) { + return map(grid, function (row) { + return GridRow.setCells(row, row.cells().concat(fill(range(0, amount), generator))); + }); + }; + var tailor = function (gridA, delta, generator) { + var fillCols = delta.colDelta() < 0 ? colFill : identity; + var fillRows = delta.rowDelta() < 0 ? rowFill : identity; + var modifiedCols = fillCols(gridA, Math.abs(delta.colDelta()), generator); + var tailoredGrid = fillRows(modifiedCols, Math.abs(delta.rowDelta()), generator); + return tailoredGrid; + }; + var Fitment = { + measure: measure, + measureWidth: measureWidth, + tailor: tailor + }; + + var merge = function (grid, bounds, comparator, substitution) { + if (grid.length === 0) { + return grid; + } + for (var i = bounds.startRow(); i <= bounds.finishRow(); i++) { + for (var j = bounds.startCol(); j <= bounds.finishCol(); j++) { + GridRow.mutateCell(grid[i], j, elementnew(substitution(), false)); + } + } + return grid; + }; + var unmerge = function (grid, target, comparator, substitution) { + var first = true; + for (var i = 0; i < grid.length; i++) { + for (var j = 0; j < GridRow.cellLength(grid[0]); j++) { + var current = GridRow.getCellElement(grid[i], j); + var isToReplace = comparator(current, target); + if (isToReplace === true && first === false) { + GridRow.mutateCell(grid[i], j, elementnew(substitution(), true)); + } else if (isToReplace === true) { + first = false; + } + } + } + return grid; + }; + var uniqueCells = function (row, comparator) { + return foldl(row, function (rest, cell) { + return exists(rest, function (currentCell) { + return comparator(currentCell.element(), cell.element()); + }) ? rest : rest.concat([cell]); + }, []); + }; + var splitRows = function (grid, index, comparator, substitution) { + if (index > 0 && index < grid.length) { + var rowPrevCells = grid[index - 1].cells(); + var cells = uniqueCells(rowPrevCells, comparator); + each(cells, function (cell) { + var replacement = Option.none(); + var _loop_1 = function (i) { + var _loop_2 = function (j) { + var current = grid[i].cells()[j]; + var isToReplace = comparator(current.element(), cell.element()); + if (isToReplace) { + if (replacement.isNone()) { + replacement = Option.some(substitution()); + } + replacement.each(function (sub) { + GridRow.mutateCell(grid[i], j, elementnew(sub, true)); + }); + } + }; + for (var j = 0; j < GridRow.cellLength(grid[0]); j++) { + _loop_2(j); + } + }; + for (var i = index; i < grid.length; i++) { + _loop_1(i); + } + }); + } + return grid; + }; + var MergingOperations = { + merge: merge, + unmerge: unmerge, + splitRows: splitRows + }; + + var isSpanning = function (grid, row, col, comparator) { + var candidate = GridRow.getCell(grid[row], col); + var matching = curry(comparator, candidate.element()); + var currentRow = grid[row]; + return grid.length > 1 && GridRow.cellLength(currentRow) > 1 && (col > 0 && matching(GridRow.getCellElement(currentRow, col - 1)) || col < currentRow.cells().length - 1 && matching(GridRow.getCellElement(currentRow, col + 1)) || row > 0 && matching(GridRow.getCellElement(grid[row - 1], col)) || row < grid.length - 1 && matching(GridRow.getCellElement(grid[row + 1], col))); + }; + var mergeTables = function (startAddress, gridA, gridB, generator, comparator) { + var startRow = startAddress.row(); + var startCol = startAddress.column(); + var mergeHeight = gridB.length; + var mergeWidth = GridRow.cellLength(gridB[0]); + var endRow = startRow + mergeHeight; + var endCol = startCol + mergeWidth; + for (var r = startRow; r < endRow; r++) { + for (var c = startCol; c < endCol; c++) { + if (isSpanning(gridA, r, c, comparator)) { + MergingOperations.unmerge(gridA, GridRow.getCellElement(gridA[r], c), comparator, generator.cell); + } + var newCell = GridRow.getCellElement(gridB[r - startRow], c - startCol); + var replacement = generator.replace(newCell); + GridRow.mutateCell(gridA[r], c, elementnew(replacement, true)); + } + } + return gridA; + }; + var merge$1 = function (startAddress, gridA, gridB, generator, comparator) { + var result = Fitment.measure(startAddress, gridA, gridB); + return result.map(function (delta) { + var fittedGrid = Fitment.tailor(gridA, delta, generator); + return mergeTables(startAddress, fittedGrid, gridB, generator, comparator); + }); + }; + var insert = function (index, gridA, gridB, generator, comparator) { + MergingOperations.splitRows(gridA, index, comparator, generator.cell); + var delta = Fitment.measureWidth(gridB, gridA); + var fittedNewGrid = Fitment.tailor(gridB, delta, generator); + var secondDelta = Fitment.measureWidth(gridA, fittedNewGrid); + var fittedOldGrid = Fitment.tailor(gridA, secondDelta, generator); + return fittedOldGrid.slice(0, index).concat(fittedNewGrid).concat(fittedOldGrid.slice(index, fittedOldGrid.length)); + }; + var TableMerge = { + merge: merge$1, + insert: insert + }; + + var insertRowAt = function (grid, index, example, comparator, substitution) { + var before = grid.slice(0, index); + var after = grid.slice(index); + var between = GridRow.mapCells(grid[example], function (ex, c) { + var withinSpan = index > 0 && index < grid.length && comparator(GridRow.getCellElement(grid[index - 1], c), GridRow.getCellElement(grid[index], c)); + var ret = withinSpan ? GridRow.getCell(grid[index], c) : elementnew(substitution(ex.element(), comparator), true); + return ret; + }); + return before.concat([between]).concat(after); + }; + var insertColumnAt = function (grid, index, example, comparator, substitution) { + return map(grid, function (row) { + var withinSpan = index > 0 && index < GridRow.cellLength(row) && comparator(GridRow.getCellElement(row, index - 1), GridRow.getCellElement(row, index)); + var sub = withinSpan ? GridRow.getCell(row, index) : elementnew(substitution(GridRow.getCellElement(row, example), comparator), true); + return GridRow.addCell(row, index, sub); + }); + }; + var splitCellIntoColumns = function (grid, exampleRow, exampleCol, comparator, substitution) { + var index = exampleCol + 1; + return map(grid, function (row, i) { + var isTargetCell = i === exampleRow; + var sub = isTargetCell ? elementnew(substitution(GridRow.getCellElement(row, exampleCol), comparator), true) : GridRow.getCell(row, exampleCol); + return GridRow.addCell(row, index, sub); + }); + }; + var splitCellIntoRows = function (grid, exampleRow, exampleCol, comparator, substitution) { + var index = exampleRow + 1; + var before = grid.slice(0, index); + var after = grid.slice(index); + var between = GridRow.mapCells(grid[exampleRow], function (ex, i) { + var isTargetCell = i === exampleCol; + return isTargetCell ? elementnew(substitution(ex.element(), comparator), true) : ex; + }); + return before.concat([between]).concat(after); + }; + var deleteColumnsAt = function (grid, start, finish) { + var rows = map(grid, function (row) { + var cells = row.cells().slice(0, start).concat(row.cells().slice(finish + 1)); + return rowcells(cells, row.section()); + }); + return filter(rows, function (row) { + return row.cells().length > 0; + }); + }; + var deleteRowsAt = function (grid, start, finish) { + return grid.slice(0, start).concat(grid.slice(finish + 1)); + }; + var ModificationOperations = { + insertRowAt: insertRowAt, + insertColumnAt: insertColumnAt, + splitCellIntoColumns: splitCellIntoColumns, + splitCellIntoRows: splitCellIntoRows, + deleteRowsAt: deleteRowsAt, + deleteColumnsAt: deleteColumnsAt + }; + + var replaceIn = function (grid, targets, comparator, substitution) { + var isTarget = function (cell) { + return exists(targets, function (target) { + return comparator(cell.element(), target.element()); + }); + }; + return map(grid, function (row) { + return GridRow.mapCells(row, function (cell) { + return isTarget(cell) ? elementnew(substitution(cell.element(), comparator), true) : cell; + }); + }); + }; + var notStartRow = function (grid, rowIndex, colIndex, comparator) { + return GridRow.getCellElement(grid[rowIndex], colIndex) !== undefined && (rowIndex > 0 && comparator(GridRow.getCellElement(grid[rowIndex - 1], colIndex), GridRow.getCellElement(grid[rowIndex], colIndex))); + }; + var notStartColumn = function (row, index, comparator) { + return index > 0 && comparator(GridRow.getCellElement(row, index - 1), GridRow.getCellElement(row, index)); + }; + var replaceColumn = function (grid, index, comparator, substitution) { + var targets = bind(grid, function (row, i) { + var alreadyAdded = notStartRow(grid, i, index, comparator) || notStartColumn(row, index, comparator); + return alreadyAdded ? [] : [GridRow.getCell(row, index)]; + }); + return replaceIn(grid, targets, comparator, substitution); + }; + var replaceRow = function (grid, index, comparator, substitution) { + var targetRow = grid[index]; + var targets = bind(targetRow.cells(), function (item, i) { + var alreadyAdded = notStartRow(grid, index, i, comparator) || notStartColumn(targetRow, i, comparator); + return alreadyAdded ? [] : [item]; + }); + return replaceIn(grid, targets, comparator, substitution); + }; + var TransformOperations = { + replaceColumn: replaceColumn, + replaceRow: replaceRow + }; + + var adt = Adt.generate([ + { none: [] }, + { only: ['index'] }, + { + left: [ + 'index', + 'next' + ] + }, + { + middle: [ + 'prev', + 'index', + 'next' + ] + }, + { + right: [ + 'prev', + 'index' + ] + } + ]); + var ColumnContext = __assign({}, adt); + + var neighbours$1 = function (input, index) { + if (input.length === 0) { + return ColumnContext.none(); + } + if (input.length === 1) { + return ColumnContext.only(0); + } + if (index === 0) { + return ColumnContext.left(0, 1); + } + if (index === input.length - 1) { + return ColumnContext.right(index - 1, index); + } + if (index > 0 && index < input.length - 1) { + return ColumnContext.middle(index - 1, index, index + 1); + } + return ColumnContext.none(); + }; + var determine = function (input, column, step, tableSize) { + var result = input.slice(0); + var context = neighbours$1(input, column); + var zero = function (array) { + return map(array, constant(0)); + }; + var onNone = constant(zero(result)); + var onOnly = function (index) { + return tableSize.singleColumnWidth(result[index], step); + }; + var onChange = function (index, next) { + if (step >= 0) { + var newNext = Math.max(tableSize.minCellWidth(), result[next] - step); + return zero(result.slice(0, index)).concat([ + step, + newNext - result[next] + ]).concat(zero(result.slice(next + 1))); + } else { + var newThis = Math.max(tableSize.minCellWidth(), result[index] + step); + var diffx = result[index] - newThis; + return zero(result.slice(0, index)).concat([ + newThis - result[index], + diffx + ]).concat(zero(result.slice(next + 1))); + } + }; + var onLeft = onChange; + var onMiddle = function (_prev, index, next) { + return onChange(index, next); + }; + var onRight = function (_prev, index) { + if (step >= 0) { + return zero(result.slice(0, index)).concat([step]); + } else { + var size = Math.max(tableSize.minCellWidth(), result[index] + step); + return zero(result.slice(0, index)).concat([size - result[index]]); + } + }; + return context.fold(onNone, onOnly, onLeft, onMiddle, onRight); + }; + var Deltas = { determine: determine }; + + var getSpan$1 = function (cell, type) { + return has(cell, type) && parseInt(get(cell, type), 10) > 1; + }; + var hasColspan = function (cell) { + return getSpan$1(cell, 'colspan'); + }; + var hasRowspan = function (cell) { + return getSpan$1(cell, 'rowspan'); + }; + var getInt = function (element, property) { + return parseInt(get$1(element, property), 10); + }; + var CellUtils = { + hasColspan: hasColspan, + hasRowspan: hasRowspan, + minWidth: constant(10), + minHeight: constant(10), + getInt: getInt + }; + + var getRaw$1 = function (cell, property, getter) { + return getRaw(cell, property).fold(function () { + return getter(cell) + 'px'; + }, function (raw) { + return raw; + }); + }; + var getRawW = function (cell, tableSize) { + return getRaw$1(cell, 'width', function (e) { + return Sizes.getPixelWidth(e, tableSize); + }); + }; + var getRawH = function (cell) { + return getRaw$1(cell, 'height', Sizes.getHeight); + }; + var getWidthFrom = function (warehouse, direction, getWidth, fallback, tableSize) { + var columns = Blocks.columns(warehouse); + var backups = map(columns, function (cellOption) { + return cellOption.map(direction.edge); + }); + return map(columns, function (cellOption, c) { + var columnCell = cellOption.filter(not(CellUtils.hasColspan)); + return columnCell.fold(function () { + var deduced = deduce(backups, c); + return fallback(deduced); + }, function (cell) { + return getWidth(cell, tableSize); + }); + }); + }; + var getDeduced = function (deduced) { + return deduced.map(function (d) { + return d + 'px'; + }).getOr(''); + }; + var getRawWidths = function (warehouse, direction, tableSize) { + return getWidthFrom(warehouse, direction, getRawW, getDeduced, tableSize); + }; + var getPercentageWidths = function (warehouse, direction, tableSize) { + return getWidthFrom(warehouse, direction, Sizes.getPercentageWidth, function (deduced) { + return deduced.fold(function () { + return tableSize.minCellWidth(); + }, function (cellWidth) { + return cellWidth / tableSize.pixelWidth() * 100; + }); + }, tableSize); + }; + var getPixelWidths = function (warehouse, direction, tableSize) { + return getWidthFrom(warehouse, direction, Sizes.getPixelWidth, function (deduced) { + return deduced.getOrThunk(tableSize.minCellWidth); + }, tableSize); + }; + var getHeightFrom = function (warehouse, direction, getHeight, fallback) { + var rows = Blocks.rows(warehouse); + var backups = map(rows, function (cellOption) { + return cellOption.map(direction.edge); + }); + return map(rows, function (cellOption, c) { + var rowCell = cellOption.filter(not(CellUtils.hasRowspan)); + return rowCell.fold(function () { + var deduced = deduce(backups, c); + return fallback(deduced); + }, function (cell) { + return getHeight(cell); + }); + }); + }; + var getPixelHeights = function (warehouse, direction) { + return getHeightFrom(warehouse, direction, Sizes.getHeight, function (deduced) { + return deduced.getOrThunk(CellUtils.minHeight); + }); + }; + var getRawHeights = function (warehouse, direction) { + return getHeightFrom(warehouse, direction, getRawH, getDeduced); + }; + var ColumnSizes = { + getRawWidths: getRawWidths, + getPixelWidths: getPixelWidths, + getPercentageWidths: getPercentageWidths, + getPixelHeights: getPixelHeights, + getRawHeights: getRawHeights + }; + + var total = function (start, end, measures) { + var r = 0; + for (var i = start; i < end; i++) { + r += measures[i] !== undefined ? measures[i] : 0; + } + return r; + }; + var recalculateWidth = function (warehouse, widths) { + var all = Warehouse.justCells(warehouse); + return map(all, function (cell) { + var width = total(cell.column(), cell.column() + cell.colspan(), widths); + return { + element: cell.element, + width: constant(width), + colspan: cell.colspan + }; + }); + }; + var recalculateHeight = function (warehouse, heights) { + var all = Warehouse.justCells(warehouse); + return map(all, function (cell) { + var height = total(cell.row(), cell.row() + cell.rowspan(), heights); + return { + element: cell.element, + height: constant(height), + rowspan: cell.rowspan + }; + }); + }; + var matchRowHeight = function (warehouse, heights) { + return map(warehouse.all(), function (row, i) { + return { + element: row.element, + height: constant(heights[i]) + }; + }); + }; + var Recalculations = { + recalculateWidth: recalculateWidth, + recalculateHeight: recalculateHeight, + matchRowHeight: matchRowHeight + }; + + var percentageSize = function (width, element) { + var floatWidth = parseFloat(width); + var pixelWidth = get$4(element); + var getCellDelta = function (delta) { + return delta / pixelWidth * 100; + }; + var singleColumnWidth = function (w, _delta) { + return [100 - w]; + }; + var minCellWidth = function () { + return CellUtils.minWidth() / pixelWidth * 100; + }; + var setTableWidth = function (table, _newWidths, delta) { + var ratio = delta / 100; + var change = ratio * floatWidth; + Sizes.setPercentageWidth(table, floatWidth + change); + }; + return { + width: constant(floatWidth), + pixelWidth: constant(pixelWidth), + getWidths: ColumnSizes.getPercentageWidths, + getCellDelta: getCellDelta, + singleColumnWidth: singleColumnWidth, + minCellWidth: minCellWidth, + setElementWidth: Sizes.setPercentageWidth, + setTableWidth: setTableWidth + }; + }; + var pixelSize = function (width) { + var getCellDelta = identity; + var singleColumnWidth = function (w, delta) { + var newNext = Math.max(CellUtils.minWidth(), w + delta); + return [newNext - w]; + }; + var setTableWidth = function (table, newWidths, _delta) { + var total = foldr(newWidths, function (b, a) { + return b + a; + }, 0); + Sizes.setPixelWidth(table, total); + }; + return { + width: constant(width), + pixelWidth: constant(width), + getWidths: ColumnSizes.getPixelWidths, + getCellDelta: getCellDelta, + singleColumnWidth: singleColumnWidth, + minCellWidth: CellUtils.minWidth, + setElementWidth: Sizes.setPixelWidth, + setTableWidth: setTableWidth + }; + }; + var chooseSize = function (element, width) { + var percentMatch = Sizes.percentageBasedSizeRegex().exec(width); + if (percentMatch !== null) { + return percentageSize(percentMatch[1], element); + } + var pixelMatch = Sizes.pixelBasedSizeRegex().exec(width); + if (pixelMatch !== null) { + var intWidth = parseInt(pixelMatch[1], 10); + return pixelSize(intWidth); + } + var fallbackWidth = get$4(element); + return pixelSize(fallbackWidth); + }; + var getTableSize = function (element) { + var width = Sizes.getRawWidth(element); + return width.fold(function () { + var fallbackWidth = get$4(element); + return pixelSize(fallbackWidth); + }, function (w) { + return chooseSize(element, w); + }); + }; + var TableSize = { getTableSize: getTableSize }; + + var getWarehouse$1 = function (list) { + return Warehouse.generate(list); + }; + var sumUp = function (newSize) { + return foldr(newSize, function (b, a) { + return b + a; + }, 0); + }; + var getTableWarehouse = function (table) { + var list = DetailsList.fromTable(table); + return getWarehouse$1(list); + }; + var adjustWidth = function (table, delta, index, direction) { + var tableSize = TableSize.getTableSize(table); + var step = tableSize.getCellDelta(delta); + var warehouse = getTableWarehouse(table); + var widths = tableSize.getWidths(warehouse, direction, tableSize); + var deltas = Deltas.determine(widths, index, step, tableSize); + var newWidths = map(deltas, function (dx, i) { + return dx + widths[i]; + }); + var newSizes = Recalculations.recalculateWidth(warehouse, newWidths); + each(newSizes, function (cell) { + tableSize.setElementWidth(cell.element(), cell.width()); + }); + if (index === warehouse.grid().columns() - 1) { + tableSize.setTableWidth(table, newWidths, step); + } + }; + var adjustHeight = function (table, delta, index, direction) { + var warehouse = getTableWarehouse(table); + var heights = ColumnSizes.getPixelHeights(warehouse, direction); + var newHeights = map(heights, function (dy, i) { + return index === i ? Math.max(delta + dy, CellUtils.minHeight()) : dy; + }); + var newCellSizes = Recalculations.recalculateHeight(warehouse, newHeights); + var newRowSizes = Recalculations.matchRowHeight(warehouse, newHeights); + each(newRowSizes, function (row) { + Sizes.setHeight(row.element(), row.height()); + }); + each(newCellSizes, function (cell) { + Sizes.setHeight(cell.element(), cell.height()); + }); + var total = sumUp(newHeights); + Sizes.setHeight(table, total); + }; + var adjustWidthTo = function (table, list, direction) { + var tableSize = TableSize.getTableSize(table); + var warehouse = getWarehouse$1(list); + var widths = tableSize.getWidths(warehouse, direction, tableSize); + var newSizes = Recalculations.recalculateWidth(warehouse, widths); + each(newSizes, function (cell) { + tableSize.setElementWidth(cell.element(), cell.width()); + }); + if (newSizes.length > 0) { + tableSize.setTableWidth(table, widths, tableSize.getCellDelta(0)); + } + }; + var Adjustments = { + adjustWidth: adjustWidth, + adjustHeight: adjustHeight, + adjustWidthTo: adjustWidthTo + }; + + var Cell = function (initial) { + var value = initial; + var get = function () { + return value; + }; + var set = function (v) { + value = v; + }; + var clone = function () { + return Cell(get()); + }; + return { + get: get, + set: set, + clone: clone + }; + }; + + var base = function (handleUnsupported, required) { + return baseWith(handleUnsupported, required, { + validate: isFunction, + label: 'function' + }); + }; + var baseWith = function (handleUnsupported, required, pred) { + if (required.length === 0) { + throw new Error('You must specify at least one required field.'); + } + validateStrArr('required', required); + checkDupes(required); + return function (obj) { + var keys$1 = keys(obj); + var allReqd = forall(required, function (req) { + return contains(keys$1, req); + }); + if (!allReqd) { + reqMessage(required, keys$1); + } + handleUnsupported(required, keys$1); + var invalidKeys = filter(required, function (key) { + return !pred.validate(obj[key], key); + }); + if (invalidKeys.length > 0) { + invalidTypeMessage(invalidKeys, pred.label); + } + return obj; + }; + }; + var handleExact = function (required, keys) { + var unsupported = filter(keys, function (key) { + return !contains(required, key); + }); + if (unsupported.length > 0) { + unsuppMessage(unsupported); + } + }; + var exactly = function (required) { + return base(handleExact, required); + }; + + var verifyGenerators = exactly([ + 'cell', + 'row', + 'replace', + 'gap' + ]); + var elementToData = function (element) { + var colspan = has(element, 'colspan') ? parseInt(get(element, 'colspan'), 10) : 1; + var rowspan = has(element, 'rowspan') ? parseInt(get(element, 'rowspan'), 10) : 1; + return { + element: constant(element), + colspan: constant(colspan), + rowspan: constant(rowspan) + }; + }; + var modification = function (generators, toData) { + if (toData === void 0) { + toData = elementToData; + } + verifyGenerators(generators); + var position = Cell(Option.none()); + var nu = function (data) { + return generators.cell(data); + }; + var nuFrom = function (element) { + var data = toData(element); + return nu(data); + }; + var add = function (element) { + var replacement = nuFrom(element); + if (position.get().isNone()) { + position.set(Option.some(replacement)); + } + recent = Option.some({ + item: element, + replacement: replacement + }); + return replacement; + }; + var recent = Option.none(); + var getOrInit = function (element, comparator) { + return recent.fold(function () { + return add(element); + }, function (p) { + return comparator(element, p.item) ? p.replacement : add(element); + }); + }; + return { + getOrInit: getOrInit, + cursor: position.get + }; + }; + var transform = function (scope, tag) { + return function (generators) { + var position = Cell(Option.none()); + verifyGenerators(generators); + var list = []; + var find$1 = function (element, comparator) { + return find(list, function (x) { + return comparator(x.item, element); + }); + }; + var makeNew = function (element) { + var attrs = { scope: scope }; + var cell = generators.replace(element, tag, attrs); + list.push({ + item: element, + sub: cell + }); + if (position.get().isNone()) { + position.set(Option.some(cell)); + } + return cell; + }; + var replaceOrInit = function (element, comparator) { + return find$1(element, comparator).fold(function () { + return makeNew(element); + }, function (p) { + return comparator(element, p.item) ? p.sub : makeNew(element); + }); + }; + return { + replaceOrInit: replaceOrInit, + cursor: position.get + }; + }; + }; + var merging = function (generators) { + verifyGenerators(generators); + var position = Cell(Option.none()); + var combine = function (cell) { + if (position.get().isNone()) { + position.set(Option.some(cell)); + } + return function () { + var raw = generators.cell({ + element: constant(cell), + colspan: constant(1), + rowspan: constant(1) + }); + remove$1(raw, 'width'); + remove$1(cell, 'width'); + return raw; + }; + }; + return { + combine: combine, + cursor: position.get + }; + }; + var Generators = { + modification: modification, + transform: transform, + merging: merging + }; + + var blockList = [ + 'body', + 'p', + 'div', + 'article', + 'aside', + 'figcaption', + 'figure', + 'footer', + 'header', + 'nav', + 'section', + 'ol', + 'ul', + 'table', + 'thead', + 'tfoot', + 'tbody', + 'caption', + 'tr', + 'td', + 'th', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'blockquote', + 'pre', + 'address' + ]; + var isList = function (universe, item) { + var tagName = universe.property().name(item); + return contains([ + 'ol', + 'ul' + ], tagName); + }; + var isBlock = function (universe, item) { + var tagName = universe.property().name(item); + return contains(blockList, tagName); + }; + var isFormatting = function (universe, item) { + var tagName = universe.property().name(item); + return contains([ + 'address', + 'pre', + 'p', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6' + ], tagName); + }; + var isHeading = function (universe, item) { + var tagName = universe.property().name(item); + return contains([ + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6' + ], tagName); + }; + var isContainer = function (universe, item) { + return contains([ + 'div', + 'li', + 'td', + 'th', + 'blockquote', + 'body', + 'caption' + ], universe.property().name(item)); + }; + var isEmptyTag = function (universe, item) { + return contains([ + 'br', + 'img', + 'hr', + 'input' + ], universe.property().name(item)); + }; + var isFrame = function (universe, item) { + return universe.property().name(item) === 'iframe'; + }; + var isInline = function (universe, item) { + return !(isBlock(universe, item) || isEmptyTag(universe, item)) && universe.property().name(item) !== 'li'; + }; + var Structure = { + isBlock: isBlock, + isList: isList, + isFormatting: isFormatting, + isHeading: isHeading, + isContainer: isContainer, + isEmptyTag: isEmptyTag, + isFrame: isFrame, + isInline: isInline + }; + + var universe$1 = DomUniverse(); + var isBlock$1 = function (element) { + return Structure.isBlock(universe$1, element); + }; + var isList$1 = function (element) { + return Structure.isList(universe$1, element); + }; + var isFormatting$1 = function (element) { + return Structure.isFormatting(universe$1, element); + }; + var isHeading$1 = function (element) { + return Structure.isHeading(universe$1, element); + }; + var isContainer$1 = function (element) { + return Structure.isContainer(universe$1, element); + }; + var isEmptyTag$1 = function (element) { + return Structure.isEmptyTag(universe$1, element); + }; + var isFrame$1 = function (element) { + return Structure.isFrame(universe$1, element); + }; + var isInline$1 = function (element) { + return Structure.isInline(universe$1, element); + }; + var DomStructure = { + isBlock: isBlock$1, + isList: isList$1, + isFormatting: isFormatting$1, + isHeading: isHeading$1, + isContainer: isContainer$1, + isEmptyTag: isEmptyTag$1, + isFrame: isFrame$1, + isInline: isInline$1 + }; + + var merge$2 = function (cells) { + var isBr = function (el) { + return name(el) === 'br'; + }; + var advancedBr = function (children) { + return forall(children, function (c) { + return isBr(c) || isText(c) && get$2(c).trim().length === 0; + }); + }; + var isListItem = function (el) { + return name(el) === 'li' || ancestor(el, DomStructure.isList).isSome(); + }; + var siblingIsBlock = function (el) { + return nextSibling(el).map(function (rightSibling) { + if (DomStructure.isBlock(rightSibling)) { + return true; + } + if (DomStructure.isEmptyTag(rightSibling)) { + return name(rightSibling) === 'img' ? false : true; + } + return false; + }).getOr(false); + }; + var markCell = function (cell) { + return last$1(cell).bind(function (rightEdge) { + var rightSiblingIsBlock = siblingIsBlock(rightEdge); + return parent(rightEdge).map(function (parent) { + return rightSiblingIsBlock === true || isListItem(parent) || isBr(rightEdge) || DomStructure.isBlock(parent) && !eq(cell, parent) ? [] : [Element.fromTag('br')]; + }); + }).getOr([]); + }; + var markContent = function () { + var content = bind(cells, function (cell) { + var children$1 = children(cell); + return advancedBr(children$1) ? [] : children$1.concat(markCell(cell)); + }); + return content.length === 0 ? [Element.fromTag('br')] : content; + }; + var contents = markContent(); + empty(cells[0]); + append$1(cells[0], contents); + }; + var TableContent = { merge: merge$2 }; + + var prune = function (table) { + var cells = TableLookup.cells(table); + if (cells.length === 0) { + remove$2(table); + } + }; + var outcome = Immutable('grid', 'cursor'); + var elementFromGrid = function (grid, row, column) { + return findIn(grid, row, column).orThunk(function () { + return findIn(grid, 0, 0); + }); + }; + var findIn = function (grid, row, column) { + return Option.from(grid[row]).bind(function (r) { + return Option.from(r.cells()[column]).bind(function (c) { + return Option.from(c.element()); + }); + }); + }; + var bundle = function (grid, row, column) { + return outcome(grid, findIn(grid, row, column)); + }; + var uniqueRows = function (details) { + return foldl(details, function (rest, detail) { + return exists(rest, function (currentDetail) { + return currentDetail.row() === detail.row(); + }) ? rest : rest.concat([detail]); + }, []).sort(function (detailA, detailB) { + return detailA.row() - detailB.row(); + }); + }; + var uniqueColumns = function (details) { + return foldl(details, function (rest, detail) { + return exists(rest, function (currentDetail) { + return currentDetail.column() === detail.column(); + }) ? rest : rest.concat([detail]); + }, []).sort(function (detailA, detailB) { + return detailA.column() - detailB.column(); + }); + }; + var insertRowBefore = function (grid, detail, comparator, genWrappers) { + var example = detail.row(); + var targetIndex = detail.row(); + var newGrid = ModificationOperations.insertRowAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); + return bundle(newGrid, targetIndex, detail.column()); + }; + var insertRowsBefore = function (grid, details, comparator, genWrappers) { + var example = details[0].row(); + var targetIndex = details[0].row(); + var rows = uniqueRows(details); + var newGrid = foldl(rows, function (newG, _row) { + return ModificationOperations.insertRowAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); + }, grid); + return bundle(newGrid, targetIndex, details[0].column()); + }; + var insertRowAfter = function (grid, detail, comparator, genWrappers) { + var example = detail.row(); + var targetIndex = detail.row() + detail.rowspan(); + var newGrid = ModificationOperations.insertRowAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); + return bundle(newGrid, targetIndex, detail.column()); + }; + var insertRowsAfter = function (grid, details, comparator, genWrappers) { + var rows = uniqueRows(details); + var example = rows[rows.length - 1].row(); + var targetIndex = rows[rows.length - 1].row() + rows[rows.length - 1].rowspan(); + var newGrid = foldl(rows, function (newG, _row) { + return ModificationOperations.insertRowAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); + }, grid); + return bundle(newGrid, targetIndex, details[0].column()); + }; + var insertColumnBefore = function (grid, detail, comparator, genWrappers) { + var example = detail.column(); + var targetIndex = detail.column(); + var newGrid = ModificationOperations.insertColumnAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); + return bundle(newGrid, detail.row(), targetIndex); + }; + var insertColumnsBefore = function (grid, details, comparator, genWrappers) { + var columns = uniqueColumns(details); + var example = columns[0].column(); + var targetIndex = columns[0].column(); + var newGrid = foldl(columns, function (newG, _row) { + return ModificationOperations.insertColumnAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); + }, grid); + return bundle(newGrid, details[0].row(), targetIndex); + }; + var insertColumnAfter = function (grid, detail, comparator, genWrappers) { + var example = detail.column(); + var targetIndex = detail.column() + detail.colspan(); + var newGrid = ModificationOperations.insertColumnAt(grid, targetIndex, example, comparator, genWrappers.getOrInit); + return bundle(newGrid, detail.row(), targetIndex); + }; + var insertColumnsAfter = function (grid, details, comparator, genWrappers) { + var example = details[details.length - 1].column(); + var targetIndex = details[details.length - 1].column() + details[details.length - 1].colspan(); + var columns = uniqueColumns(details); + var newGrid = foldl(columns, function (newG, _row) { + return ModificationOperations.insertColumnAt(newG, targetIndex, example, comparator, genWrappers.getOrInit); + }, grid); + return bundle(newGrid, details[0].row(), targetIndex); + }; + var makeRowHeader = function (grid, detail, comparator, genWrappers) { + var newGrid = TransformOperations.replaceRow(grid, detail.row(), comparator, genWrappers.replaceOrInit); + return bundle(newGrid, detail.row(), detail.column()); + }; + var makeColumnHeader = function (grid, detail, comparator, genWrappers) { + var newGrid = TransformOperations.replaceColumn(grid, detail.column(), comparator, genWrappers.replaceOrInit); + return bundle(newGrid, detail.row(), detail.column()); + }; + var unmakeRowHeader = function (grid, detail, comparator, genWrappers) { + var newGrid = TransformOperations.replaceRow(grid, detail.row(), comparator, genWrappers.replaceOrInit); + return bundle(newGrid, detail.row(), detail.column()); + }; + var unmakeColumnHeader = function (grid, detail, comparator, genWrappers) { + var newGrid = TransformOperations.replaceColumn(grid, detail.column(), comparator, genWrappers.replaceOrInit); + return bundle(newGrid, detail.row(), detail.column()); + }; + var splitCellIntoColumns$1 = function (grid, detail, comparator, genWrappers) { + var newGrid = ModificationOperations.splitCellIntoColumns(grid, detail.row(), detail.column(), comparator, genWrappers.getOrInit); + return bundle(newGrid, detail.row(), detail.column()); + }; + var splitCellIntoRows$1 = function (grid, detail, comparator, genWrappers) { + var newGrid = ModificationOperations.splitCellIntoRows(grid, detail.row(), detail.column(), comparator, genWrappers.getOrInit); + return bundle(newGrid, detail.row(), detail.column()); + }; + var eraseColumns = function (grid, details, _comparator, _genWrappers) { + var columns = uniqueColumns(details); + var newGrid = ModificationOperations.deleteColumnsAt(grid, columns[0].column(), columns[columns.length - 1].column()); + var cursor = elementFromGrid(newGrid, details[0].row(), details[0].column()); + return outcome(newGrid, cursor); + }; + var eraseRows = function (grid, details, _comparator, _genWrappers) { + var rows = uniqueRows(details); + var newGrid = ModificationOperations.deleteRowsAt(grid, rows[0].row(), rows[rows.length - 1].row()); + var cursor = elementFromGrid(newGrid, details[0].row(), details[0].column()); + return outcome(newGrid, cursor); + }; + var mergeCells = function (grid, mergable, comparator, _genWrappers) { + var cells = mergable.cells(); + TableContent.merge(cells); + var newGrid = MergingOperations.merge(grid, mergable.bounds(), comparator, constant(cells[0])); + return outcome(newGrid, Option.from(cells[0])); + }; + var unmergeCells = function (grid, unmergable, comparator, genWrappers) { + var newGrid = foldr(unmergable, function (b, cell) { + return MergingOperations.unmerge(b, cell, comparator, genWrappers.combine(cell)); + }, grid); + return outcome(newGrid, Option.from(unmergable[0])); + }; + var pasteCells = function (grid, pasteDetails, comparator, _genWrappers) { + var gridify = function (table, generators) { + var list = DetailsList.fromTable(table); + var wh = Warehouse.generate(list); + return Transitions.toGrid(wh, generators, true); + }; + var gridB = gridify(pasteDetails.clipboard(), pasteDetails.generators()); + var startAddress = address(pasteDetails.row(), pasteDetails.column()); + var mergedGrid = TableMerge.merge(startAddress, grid, gridB, pasteDetails.generators(), comparator); + return mergedGrid.fold(function () { + return outcome(grid, Option.some(pasteDetails.element())); + }, function (nuGrid) { + var cursor = elementFromGrid(nuGrid, pasteDetails.row(), pasteDetails.column()); + return outcome(nuGrid, cursor); + }); + }; + var gridifyRows = function (rows, generators, example) { + var pasteDetails = DetailsList.fromPastedRows(rows, example); + var wh = Warehouse.generate(pasteDetails); + return Transitions.toGrid(wh, generators, true); + }; + var pasteRowsBefore = function (grid, pasteDetails, comparator, _genWrappers) { + var example = grid[pasteDetails.cells[0].row()]; + var index = pasteDetails.cells[0].row(); + var gridB = gridifyRows(pasteDetails.clipboard(), pasteDetails.generators(), example); + var mergedGrid = TableMerge.insert(index, grid, gridB, pasteDetails.generators(), comparator); + var cursor = elementFromGrid(mergedGrid, pasteDetails.cells[0].row(), pasteDetails.cells[0].column()); + return outcome(mergedGrid, cursor); + }; + var pasteRowsAfter = function (grid, pasteDetails, comparator, _genWrappers) { + var example = grid[pasteDetails.cells[0].row()]; + var index = pasteDetails.cells[pasteDetails.cells.length - 1].row() + pasteDetails.cells[pasteDetails.cells.length - 1].rowspan(); + var gridB = gridifyRows(pasteDetails.clipboard(), pasteDetails.generators(), example); + var mergedGrid = TableMerge.insert(index, grid, gridB, pasteDetails.generators(), comparator); + var cursor = elementFromGrid(mergedGrid, pasteDetails.cells[0].row(), pasteDetails.cells[0].column()); + return outcome(mergedGrid, cursor); + }; + var resize = Adjustments.adjustWidthTo; + var TableOperations = { + insertRowBefore: run(insertRowBefore, onCell, noop, noop, Generators.modification), + insertRowsBefore: run(insertRowsBefore, onCells, noop, noop, Generators.modification), + insertRowAfter: run(insertRowAfter, onCell, noop, noop, Generators.modification), + insertRowsAfter: run(insertRowsAfter, onCells, noop, noop, Generators.modification), + insertColumnBefore: run(insertColumnBefore, onCell, resize, noop, Generators.modification), + insertColumnsBefore: run(insertColumnsBefore, onCells, resize, noop, Generators.modification), + insertColumnAfter: run(insertColumnAfter, onCell, resize, noop, Generators.modification), + insertColumnsAfter: run(insertColumnsAfter, onCells, resize, noop, Generators.modification), + splitCellIntoColumns: run(splitCellIntoColumns$1, onCell, resize, noop, Generators.modification), + splitCellIntoRows: run(splitCellIntoRows$1, onCell, noop, noop, Generators.modification), + eraseColumns: run(eraseColumns, onCells, resize, prune, Generators.modification), + eraseRows: run(eraseRows, onCells, noop, prune, Generators.modification), + makeColumnHeader: run(makeColumnHeader, onCell, noop, noop, Generators.transform('row', 'th')), + unmakeColumnHeader: run(unmakeColumnHeader, onCell, noop, noop, Generators.transform(null, 'td')), + makeRowHeader: run(makeRowHeader, onCell, noop, noop, Generators.transform('col', 'th')), + unmakeRowHeader: run(unmakeRowHeader, onCell, noop, noop, Generators.transform(null, 'td')), + mergeCells: run(mergeCells, onMergable, noop, noop, Generators.merging), + unmergeCells: run(unmergeCells, onUnmergable, resize, noop, Generators.merging), + pasteCells: run(pasteCells, onPaste, resize, noop, Generators.modification), + pasteRowsBefore: run(pasteRowsBefore, onPasteRows, noop, noop, Generators.modification), + pasteRowsAfter: run(pasteRowsAfter, onPasteRows, noop, noop, Generators.modification) + }; + + var getBody$1 = function (editor) { + return Element.fromDom(editor.getBody()); + }; + var getPixelWidth$1 = function (elm) { + return elm.getBoundingClientRect().width; + }; + var getPixelHeight = function (elm) { + return elm.getBoundingClientRect().height; + }; + var getIsRoot = function (editor) { + return function (element) { + return eq(element, getBody$1(editor)); + }; + }; + var removePxSuffix = function (size) { + return size ? size.replace(/px$/, '') : ''; + }; + var addSizeSuffix = function (size) { + if (/^[0-9]+$/.test(size)) { + size += 'px'; + } + return size; + }; + var removeDataStyle = function (table) { + var dataStyleCells = descendants$1(table, 'td[data-mce-style],th[data-mce-style]'); + remove(table, 'data-mce-style'); + each(dataStyleCells, function (cell) { + remove(cell, 'data-mce-style'); + }); + }; + + var getDirection = function (element) { + return get$1(element, 'direction') === 'rtl' ? 'rtl' : 'ltr'; + }; + + var ltr$1 = { isRtl: constant(false) }; + var rtl$1 = { isRtl: constant(true) }; + var directionAt = function (element) { + var dir = getDirection(element); + return dir === 'rtl' ? rtl$1 : ltr$1; + }; + var Direction = { directionAt: directionAt }; + + var defaultTableToolbar = [ + 'tableprops', + 'tabledelete', + '|', + 'tableinsertrowbefore', + 'tableinsertrowafter', + 'tabledeleterow', + '|', + 'tableinsertcolbefore', + 'tableinsertcolafter', + 'tabledeletecol' + ]; + var defaultStyles = { + 'border-collapse': 'collapse', + 'width': '100%' + }; + var defaultAttributes = { border: '1' }; + var getDefaultAttributes = function (editor) { + return editor.getParam('table_default_attributes', defaultAttributes, 'object'); + }; + var getDefaultStyles = function (editor) { + return editor.getParam('table_default_styles', defaultStyles, 'object'); + }; + var hasTableResizeBars = function (editor) { + return editor.getParam('table_resize_bars', true, 'boolean'); + }; + var hasTabNavigation = function (editor) { + return editor.getParam('table_tab_navigation', true, 'boolean'); + }; + var hasAdvancedCellTab = function (editor) { + return editor.getParam('table_cell_advtab', true, 'boolean'); + }; + var hasAdvancedRowTab = function (editor) { + return editor.getParam('table_row_advtab', true, 'boolean'); + }; + var hasAdvancedTableTab = function (editor) { + return editor.getParam('table_advtab', true, 'boolean'); + }; + var hasAppearanceOptions = function (editor) { + return editor.getParam('table_appearance_options', true, 'boolean'); + }; + var hasTableGrid = function (editor) { + return editor.getParam('table_grid', true, 'boolean'); + }; + var shouldStyleWithCss = function (editor) { + return editor.getParam('table_style_by_css', false, 'boolean'); + }; + var getCellClassList = function (editor) { + return editor.getParam('table_cell_class_list', [], 'array'); + }; + var getRowClassList = function (editor) { + return editor.getParam('table_row_class_list', [], 'array'); + }; + var getTableClassList = function (editor) { + return editor.getParam('table_class_list', [], 'array'); + }; + var getColorPickerCallback = function (editor) { + return editor.getParam('color_picker_callback'); + }; + var isPixelsForced = function (editor) { + return editor.getParam('table_responsive_width') === false; + }; + var getCloneElements = function (editor) { + var cloneElements = editor.getParam('table_clone_elements'); + if (isString(cloneElements)) { + return Option.some(cloneElements.split(/[ ,]/)); + } else if (Array.isArray(cloneElements)) { + return Option.some(cloneElements); + } else { + return Option.none(); + } + }; + var hasObjectResizing = function (editor) { + var objectResizing = editor.getParam('object_resizing', true); + return objectResizing === 'table' || objectResizing; + }; + var getToolbar = function (editor) { + var toolbar = editor.getParam('table_toolbar', defaultTableToolbar); + if (toolbar === '' || toolbar === false) { + return []; + } else if (isString(toolbar)) { + return toolbar.split(/[ ,]/); + } else if (isArray(toolbar)) { + return toolbar; + } else { + return []; + } + }; + + var fireNewRow = function (editor, row) { + return editor.fire('newrow', { node: row }); + }; + var fireNewCell = function (editor, cell) { + return editor.fire('newcell', { node: cell }); + }; + var fireObjectResizeStart = function (editor, target, width, height) { + editor.fire('ObjectResizeStart', { + target: target, + width: width, + height: height + }); + }; + var fireObjectResized = function (editor, target, width, height) { + editor.fire('ObjectResized', { + target: target, + width: width, + height: height + }); + }; + + var TableActions = function (editor, lazyWire) { + var isTableBody = function (editor) { + return name(getBody$1(editor)) === 'table'; + }; + var lastRowGuard = function (table) { + var size = TableGridSize.getGridSize(table); + return isTableBody(editor) === false || size.rows() > 1; + }; + var lastColumnGuard = function (table) { + var size = TableGridSize.getGridSize(table); + return isTableBody(editor) === false || size.columns() > 1; + }; + var cloneFormats = getCloneElements(editor); + var execute = function (operation, guard, mutate, lazyWire) { + return function (table, target) { + removeDataStyle(table); + var wire = lazyWire(); + var doc = Element.fromDom(editor.getDoc()); + var direction = TableDirection(Direction.directionAt); + var generators = TableFill.cellOperations(mutate, doc, cloneFormats); + return guard(table) ? operation(wire, table, target, generators, direction).bind(function (result) { + each(result.newRows(), function (row) { + fireNewRow(editor, row.dom()); + }); + each(result.newCells(), function (cell) { + fireNewCell(editor, cell.dom()); + }); + return result.cursor().map(function (cell) { + var rng = editor.dom.createRng(); + rng.setStart(cell.dom(), 0); + rng.setEnd(cell.dom(), 0); + return rng; + }); + }) : Option.none(); + }; + }; + var deleteRow = execute(TableOperations.eraseRows, lastRowGuard, noop, lazyWire); + var deleteColumn = execute(TableOperations.eraseColumns, lastColumnGuard, noop, lazyWire); + var insertRowsBefore = execute(TableOperations.insertRowsBefore, always, noop, lazyWire); + var insertRowsAfter = execute(TableOperations.insertRowsAfter, always, noop, lazyWire); + var insertColumnsBefore = execute(TableOperations.insertColumnsBefore, always, CellMutations.halve, lazyWire); + var insertColumnsAfter = execute(TableOperations.insertColumnsAfter, always, CellMutations.halve, lazyWire); + var mergeCells = execute(TableOperations.mergeCells, always, noop, lazyWire); + var unmergeCells = execute(TableOperations.unmergeCells, always, noop, lazyWire); + var pasteRowsBefore = execute(TableOperations.pasteRowsBefore, always, noop, lazyWire); + var pasteRowsAfter = execute(TableOperations.pasteRowsAfter, always, noop, lazyWire); + var pasteCells = execute(TableOperations.pasteCells, always, noop, lazyWire); + return { + deleteRow: deleteRow, + deleteColumn: deleteColumn, + insertRowsBefore: insertRowsBefore, + insertRowsAfter: insertRowsAfter, + insertColumnsBefore: insertColumnsBefore, + insertColumnsAfter: insertColumnsAfter, + mergeCells: mergeCells, + unmergeCells: unmergeCells, + pasteRowsBefore: pasteRowsBefore, + pasteRowsAfter: pasteRowsAfter, + pasteCells: pasteCells + }; + }; + + var copyRows = function (table, target, generators) { + var list = DetailsList.fromTable(table); + var house = Warehouse.generate(list); + var details = onCells(house, target); + return details.map(function (selectedCells) { + var grid = Transitions.toGrid(house, generators, false); + var slicedGrid = grid.slice(selectedCells[0].row(), selectedCells[selectedCells.length - 1].row() + selectedCells[selectedCells.length - 1].rowspan()); + var slicedDetails = toDetailList(slicedGrid, generators); + return Redraw.copy(slicedDetails); + }); + }; + var CopyRows = { copyRows: copyRows }; + + var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); + + var getTDTHOverallStyle = function (dom, elm, name) { + var cells = dom.select('td,th', elm); + var firstChildStyle; + var checkChildren = function (firstChildStyle, elms) { + for (var i = 0; i < elms.length; i++) { + var currentStyle = dom.getStyle(elms[i], name); + if (typeof firstChildStyle === 'undefined') { + firstChildStyle = currentStyle; + } + if (firstChildStyle !== currentStyle) { + return ''; + } + } + return firstChildStyle; + }; + firstChildStyle = checkChildren(firstChildStyle, cells); + return firstChildStyle; + }; + var applyAlign = function (editor, elm, name) { + if (name) { + editor.formatter.apply('align' + name, {}, elm); + } + }; + var applyVAlign = function (editor, elm, name) { + if (name) { + editor.formatter.apply('valign' + name, {}, elm); + } + }; + var unApplyAlign = function (editor, elm) { + global$1.each('left center right'.split(' '), function (name) { + editor.formatter.remove('align' + name, {}, elm); + }); + }; + var unApplyVAlign = function (editor, elm) { + global$1.each('top middle bottom'.split(' '), function (name) { + editor.formatter.remove('valign' + name, {}, elm); + }); + }; + var Styles$1 = { + applyAlign: applyAlign, + applyVAlign: applyVAlign, + unApplyAlign: unApplyAlign, + unApplyVAlign: unApplyVAlign, + getTDTHOverallStyle: getTDTHOverallStyle + }; + + var buildListItems = function (inputList, itemCallback, startItems) { + var appendItems = function (values, output) { + output = output || []; + global$1.each(values, function (item) { + var menuItem = { text: item.text || item.title }; + if (item.menu) { + menuItem.menu = appendItems(item.menu); + } else { + menuItem.value = item.value; + if (itemCallback) { + itemCallback(menuItem); + } + } + output.push(menuItem); + }); + return output; + }; + return appendItems(inputList, startItems || []); + }; + function styleFieldHasFocus(e) { + return e.control.rootControl.find('#style')[0].getEl().isEqualNode(domGlobals.document.activeElement); + } + var syncAdvancedStyleFields = function (editor, evt) { + if (styleFieldHasFocus(evt)) { + updateAdvancedFields(editor, evt); + } else { + updateStyleField(editor, evt); + } + }; + var updateStyleField = function (editor, evt) { + var dom = editor.dom; + var rootControl = evt.control.rootControl; + var data = rootControl.toJSON(); + var css = dom.parseStyle(data.style); + css['border-style'] = data.borderStyle; + css['border-color'] = data.borderColor; + css['background-color'] = data.backgroundColor; + css.width = data.width ? addSizeSuffix(data.width) : ''; + css.height = data.height ? addSizeSuffix(data.height) : ''; + rootControl.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css)))); + }; + var updateAdvancedFields = function (editor, evt) { + var dom = editor.dom; + var rootControl = evt.control.rootControl; + var data = rootControl.toJSON(); + var css = dom.parseStyle(data.style); + rootControl.find('#borderStyle').value(css['border-style'] || ''); + rootControl.find('#borderColor').value(css['border-color'] || ''); + rootControl.find('#backgroundColor').value(css['background-color'] || ''); + rootControl.find('#width').value(css.width || ''); + rootControl.find('#height').value(css.height || ''); + }; + var extractAdvancedStyles = function (dom, elm) { + var css = dom.parseStyle(dom.getAttrib(elm, 'style')); + var data = {}; + if (css['border-style']) { + data.borderStyle = css['border-style']; + } + if (css['border-color']) { + data.borderColor = css['border-color']; + } + if (css['background-color']) { + data.backgroundColor = css['background-color']; + } + data.style = dom.serializeStyle(css); + return data; + }; + var createStyleForm = function (editor) { + var createColorPickAction = function () { + var colorPickerCallback = getColorPickerCallback(editor); + if (colorPickerCallback) { + return function (evt) { + return colorPickerCallback.call(editor, function (value) { + evt.control.value(value).fire('change'); + }, evt.control.value()); + }; + } + }; + return { + title: 'Advanced', + type: 'form', + defaults: { onchange: curry(updateStyleField, editor) }, + items: [ + { + label: 'Style', + name: 'style', + type: 'textbox', + onchange: curry(updateAdvancedFields, editor) + }, + { + type: 'form', + padding: 0, + formItemDefaults: { + layout: 'grid', + alignH: [ + 'start', + 'right' + ] + }, + defaults: { size: 7 }, + items: [ + { + label: 'Border style', + type: 'listbox', + name: 'borderStyle', + width: 90, + onselect: curry(updateStyleField, editor), + values: [ + { + text: 'Select...', + value: '' + }, + { + text: 'Solid', + value: 'solid' + }, + { + text: 'Dotted', + value: 'dotted' + }, + { + text: 'Dashed', + value: 'dashed' + }, + { + text: 'Double', + value: 'double' + }, + { + text: 'Groove', + value: 'groove' + }, + { + text: 'Ridge', + value: 'ridge' + }, + { + text: 'Inset', + value: 'inset' + }, + { + text: 'Outset', + value: 'outset' + }, + { + text: 'None', + value: 'none' + }, + { + text: 'Hidden', + value: 'hidden' + } + ] + }, + { + label: 'Border color', + type: 'colorbox', + name: 'borderColor', + onaction: createColorPickAction() + }, + { + label: 'Background color', + type: 'colorbox', + name: 'backgroundColor', + onaction: createColorPickAction() + } + ] + } + ] + }; + }; + var Helpers = { + createStyleForm: createStyleForm, + buildListItems: buildListItems, + updateStyleField: updateStyleField, + extractAdvancedStyles: extractAdvancedStyles, + updateAdvancedFields: updateAdvancedFields, + syncAdvancedStyleFields: syncAdvancedStyleFields + }; + + var updateStyles = function (elm, cssText) { + delete elm.dataset.mceStyle; + elm.style.cssText += ';' + cssText; + }; + var extractDataFromElement = function (editor, elm) { + var dom = editor.dom; + var data = { + width: dom.getStyle(elm, 'width') || dom.getAttrib(elm, 'width'), + height: dom.getStyle(elm, 'height') || dom.getAttrib(elm, 'height'), + scope: dom.getAttrib(elm, 'scope'), + class: dom.getAttrib(elm, 'class'), + type: elm.nodeName.toLowerCase(), + style: '', + align: '', + valign: '' + }; + global$1.each('left center right'.split(' '), function (name) { + if (editor.formatter.matchNode(elm, 'align' + name)) { + data.align = name; + } + }); + global$1.each('top middle bottom'.split(' '), function (name) { + if (editor.formatter.matchNode(elm, 'valign' + name)) { + data.valign = name; + } + }); + if (hasAdvancedCellTab(editor)) { + global$1.extend(data, Helpers.extractAdvancedStyles(dom, elm)); + } + return data; + }; + var onSubmitCellForm = function (editor, cells, evt) { + var dom = editor.dom; + var data; + function setAttrib(elm, name, value) { + if (cells.length === 1 || value) { + dom.setAttrib(elm, name, value); + } + } + function setStyle(elm, name, value) { + if (cells.length === 1 || value) { + dom.setStyle(elm, name, value); + } + } + if (hasAdvancedCellTab(editor)) { + Helpers.syncAdvancedStyleFields(editor, evt); + } + data = evt.control.rootControl.toJSON(); + editor.undoManager.transact(function () { + global$1.each(cells, function (cellElm) { + setAttrib(cellElm, 'scope', data.scope); + if (cells.length === 1) { + setAttrib(cellElm, 'style', data.style); + } else { + updateStyles(cellElm, data.style); + } + setAttrib(cellElm, 'class', data.class); + setStyle(cellElm, 'width', addSizeSuffix(data.width)); + setStyle(cellElm, 'height', addSizeSuffix(data.height)); + if (data.type && cellElm.nodeName.toLowerCase() !== data.type) { + cellElm = dom.rename(cellElm, data.type); + } + if (cells.length === 1) { + Styles$1.unApplyAlign(editor, cellElm); + Styles$1.unApplyVAlign(editor, cellElm); + } + if (data.align) { + Styles$1.applyAlign(editor, cellElm, data.align); + } + if (data.valign) { + Styles$1.applyVAlign(editor, cellElm, data.valign); + } + }); + editor.focus(); + }); + }; + var open = function (editor) { + var cellElm, data, classListCtrl, cells = []; + cells = editor.dom.select('td[data-mce-selected],th[data-mce-selected]'); + cellElm = editor.dom.getParent(editor.selection.getStart(), 'td,th'); + if (!cells.length && cellElm) { + cells.push(cellElm); + } + cellElm = cellElm || cells[0]; + if (!cellElm) { + return; + } + if (cells.length > 1) { + data = { + width: '', + height: '', + scope: '', + class: '', + align: '', + valign: '', + style: '', + type: cellElm.nodeName.toLowerCase() + }; + } else { + data = extractDataFromElement(editor, cellElm); + } + if (getCellClassList(editor).length > 0) { + classListCtrl = { + name: 'class', + type: 'listbox', + label: 'Class', + values: Helpers.buildListItems(getCellClassList(editor), function (item) { + if (item.value) { + item.textStyle = function () { + return editor.formatter.getCssText({ + block: 'td', + classes: [item.value] + }); + }; + } + }) + }; + } + var generalCellForm = { + type: 'form', + layout: 'flex', + direction: 'column', + labelGapCalc: 'children', + padding: 0, + items: [ + { + type: 'form', + layout: 'grid', + columns: 2, + labelGapCalc: false, + padding: 0, + defaults: { + type: 'textbox', + maxWidth: 50 + }, + items: [ + { + label: 'Width', + name: 'width', + onchange: curry(Helpers.updateStyleField, editor) + }, + { + label: 'Height', + name: 'height', + onchange: curry(Helpers.updateStyleField, editor) + }, + { + label: 'Cell type', + name: 'type', + type: 'listbox', + text: 'None', + minWidth: 90, + maxWidth: null, + values: [ + { + text: 'Cell', + value: 'td' + }, + { + text: 'Header cell', + value: 'th' + } + ] + }, + { + label: 'Scope', + name: 'scope', + type: 'listbox', + text: 'None', + minWidth: 90, + maxWidth: null, + values: [ + { + text: 'None', + value: '' + }, + { + text: 'Row', + value: 'row' + }, + { + text: 'Column', + value: 'col' + }, + { + text: 'Row group', + value: 'rowgroup' + }, + { + text: 'Column group', + value: 'colgroup' + } + ] + }, + { + label: 'H Align', + name: 'align', + type: 'listbox', + text: 'None', + minWidth: 90, + maxWidth: null, + values: [ + { + text: 'None', + value: '' + }, + { + text: 'Left', + value: 'left' + }, + { + text: 'Center', + value: 'center' + }, + { + text: 'Right', + value: 'right' + } + ] + }, + { + label: 'V Align', + name: 'valign', + type: 'listbox', + text: 'None', + minWidth: 90, + maxWidth: null, + values: [ + { + text: 'None', + value: '' + }, + { + text: 'Top', + value: 'top' + }, + { + text: 'Middle', + value: 'middle' + }, + { + text: 'Bottom', + value: 'bottom' + } + ] + } + ] + }, + classListCtrl + ] + }; + if (hasAdvancedCellTab(editor)) { + editor.windowManager.open({ + title: 'Cell properties', + bodyType: 'tabpanel', + data: data, + body: [ + { + title: 'General', + type: 'form', + items: generalCellForm + }, + Helpers.createStyleForm(editor) + ], + onsubmit: curry(onSubmitCellForm, editor, cells) + }); + } else { + editor.windowManager.open({ + title: 'Cell properties', + data: data, + body: generalCellForm, + onsubmit: curry(onSubmitCellForm, editor, cells) + }); + } + }; + var CellDialog = { open: open }; + + var extractDataFromElement$1 = function (editor, elm) { + var dom = editor.dom; + var data = { + height: dom.getStyle(elm, 'height') || dom.getAttrib(elm, 'height'), + scope: dom.getAttrib(elm, 'scope'), + class: dom.getAttrib(elm, 'class'), + align: '', + style: '', + type: elm.parentNode.nodeName.toLowerCase() + }; + global$1.each('left center right'.split(' '), function (name) { + if (editor.formatter.matchNode(elm, 'align' + name)) { + data.align = name; + } + }); + if (hasAdvancedRowTab(editor)) { + global$1.extend(data, Helpers.extractAdvancedStyles(dom, elm)); + } + return data; + }; + var switchRowType = function (dom, rowElm, toType) { + var tableElm = dom.getParent(rowElm, 'table'); + var oldParentElm = rowElm.parentNode; + var parentElm = dom.select(toType, tableElm)[0]; + if (!parentElm) { + parentElm = dom.create(toType); + if (tableElm.firstChild) { + if (tableElm.firstChild.nodeName === 'CAPTION') { + dom.insertAfter(parentElm, tableElm.firstChild); + } else { + tableElm.insertBefore(parentElm, tableElm.firstChild); + } + } else { + tableElm.appendChild(parentElm); + } + } + parentElm.appendChild(rowElm); + if (!oldParentElm.hasChildNodes()) { + dom.remove(oldParentElm); + } + }; + function onSubmitRowForm(editor, rows, oldData, evt) { + var dom = editor.dom; + function setAttrib(elm, name, value) { + if (rows.length === 1 || value) { + dom.setAttrib(elm, name, value); + } + } + function setStyle(elm, name, value) { + if (rows.length === 1 || value) { + dom.setStyle(elm, name, value); + } + } + if (hasAdvancedRowTab(editor)) { + Helpers.syncAdvancedStyleFields(editor, evt); + } + var data = evt.control.rootControl.toJSON(); + editor.undoManager.transact(function () { + global$1.each(rows, function (rowElm) { + setAttrib(rowElm, 'scope', data.scope); + setAttrib(rowElm, 'style', data.style); + setAttrib(rowElm, 'class', data.class); + setStyle(rowElm, 'height', addSizeSuffix(data.height)); + if (data.type !== rowElm.parentNode.nodeName.toLowerCase()) { + switchRowType(editor.dom, rowElm, data.type); + } + if (data.align !== oldData.align) { + Styles$1.unApplyAlign(editor, rowElm); + Styles$1.applyAlign(editor, rowElm, data.align); + } + }); + editor.focus(); + }); + } + var open$1 = function (editor) { + var dom = editor.dom; + var tableElm, cellElm, rowElm, classListCtrl, data; + var rows = []; + var generalRowForm; + tableElm = dom.getParent(editor.selection.getStart(), 'table'); + cellElm = dom.getParent(editor.selection.getStart(), 'td,th'); + global$1.each(tableElm.rows, function (row) { + global$1.each(row.cells, function (cell) { + if (dom.getAttrib(cell, 'data-mce-selected') || cell === cellElm) { + rows.push(row); + return false; + } + }); + }); + rowElm = rows[0]; + if (!rowElm) { + return; + } + if (rows.length > 1) { + data = { + height: '', + scope: '', + style: '', + class: '', + align: '', + type: rowElm.parentNode.nodeName.toLowerCase() + }; + } else { + data = extractDataFromElement$1(editor, rowElm); + } + if (getRowClassList(editor).length > 0) { + classListCtrl = { + name: 'class', + type: 'listbox', + label: 'Class', + values: Helpers.buildListItems(getRowClassList(editor), function (item) { + if (item.value) { + item.textStyle = function () { + return editor.formatter.getCssText({ + block: 'tr', + classes: [item.value] + }); + }; + } + }) + }; + } + generalRowForm = { + type: 'form', + columns: 2, + padding: 0, + defaults: { type: 'textbox' }, + items: [ + { + type: 'listbox', + name: 'type', + label: 'Row type', + text: 'Header', + maxWidth: null, + values: [ + { + text: 'Header', + value: 'thead' + }, + { + text: 'Body', + value: 'tbody' + }, + { + text: 'Footer', + value: 'tfoot' + } + ] + }, + { + type: 'listbox', + name: 'align', + label: 'Alignment', + text: 'None', + maxWidth: null, + values: [ + { + text: 'None', + value: '' + }, + { + text: 'Left', + value: 'left' + }, + { + text: 'Center', + value: 'center' + }, + { + text: 'Right', + value: 'right' + } + ] + }, + { + label: 'Height', + name: 'height' + }, + classListCtrl + ] + }; + if (hasAdvancedRowTab(editor)) { + editor.windowManager.open({ + title: 'Row properties', + data: data, + bodyType: 'tabpanel', + body: [ + { + title: 'General', + type: 'form', + items: generalRowForm + }, + Helpers.createStyleForm(editor) + ], + onsubmit: curry(onSubmitRowForm, editor, rows, data) + }); + } else { + editor.windowManager.open({ + title: 'Row properties', + data: data, + body: generalRowForm, + onsubmit: curry(onSubmitRowForm, editor, rows, data) + }); + } + }; + var RowDialog = { open: open$1 }; + + var global$2 = tinymce.util.Tools.resolve('tinymce.Env'); + + var DefaultRenderOptions = { + styles: { + 'border-collapse': 'collapse', + 'width': '100%' + }, + attributes: { border: '1' }, + percentages: true + }; + var makeTable = function () { + return Element.fromTag('table'); + }; + var tableBody = function () { + return Element.fromTag('tbody'); + }; + var tableRow = function () { + return Element.fromTag('tr'); + }; + var tableHeaderCell = function () { + return Element.fromTag('th'); + }; + var tableCell = function () { + return Element.fromTag('td'); + }; + var render$1 = function (rows, columns, rowHeaders, columnHeaders, renderOpts) { + if (renderOpts === void 0) { + renderOpts = DefaultRenderOptions; + } + var table = makeTable(); + setAll$1(table, renderOpts.styles); + setAll(table, renderOpts.attributes); + var tbody = tableBody(); + append(table, tbody); + var trs = []; + for (var i = 0; i < rows; i++) { + var tr = tableRow(); + for (var j = 0; j < columns; j++) { + var td = i < rowHeaders || j < columnHeaders ? tableHeaderCell() : tableCell(); + if (j < columnHeaders) { + set(td, 'scope', 'row'); + } + if (i < rowHeaders) { + set(td, 'scope', 'col'); + } + append(td, Element.fromTag('br')); + if (renderOpts.percentages) { + set$1(td, 'width', 100 / columns + '%'); + } + append(tr, td); + } + trs.push(tr); + } + append$1(tbody, trs); + return table; + }; + + var get$7 = function (element) { + return element.dom().innerHTML; + }; + var getOuter$2 = function (element) { + var container = Element.fromTag('div'); + var clone = Element.fromDom(element.dom().cloneNode(true)); + append(container, clone); + return get$7(container); + }; + + var placeCaretInCell = function (editor, cell) { + editor.selection.select(cell.dom(), true); + editor.selection.collapse(true); + }; + var selectFirstCellInTable = function (editor, tableElm) { + descendant$1(tableElm, 'td,th').each(curry(placeCaretInCell, editor)); + }; + var fireEvents = function (editor, table) { + each(descendants$1(table, 'tr'), function (row) { + fireNewRow(editor, row.dom()); + each(descendants$1(row, 'th,td'), function (cell) { + fireNewCell(editor, cell.dom()); + }); + }); + }; + var isPercentage = function (width) { + return isString(width) && width.indexOf('%') !== -1; + }; + var insert$1 = function (editor, columns, rows) { + var defaultStyles = getDefaultStyles(editor); + var options = { + styles: defaultStyles, + attributes: getDefaultAttributes(editor), + percentages: isPercentage(defaultStyles.width) && !isPixelsForced(editor) + }; + var table = render$1(rows, columns, 0, 0, options); + set(table, 'data-mce-id', '__mce'); + var html = getOuter$2(table); + editor.insertContent(html); + return descendant$1(getBody$1(editor), 'table[data-mce-id="__mce"]').map(function (table) { + if (isPixelsForced(editor)) { + set$1(table, 'width', get$1(table, 'width')); + } + remove(table, 'data-mce-id'); + fireEvents(editor, table); + selectFirstCellInTable(editor, table); + return table.dom(); + }).getOr(null); + }; + var InsertTable = { insert: insert$1 }; + + function styleTDTH(dom, elm, name, value) { + if (elm.tagName === 'TD' || elm.tagName === 'TH') { + dom.setStyle(elm, name, value); + } else { + if (elm.children) { + for (var i = 0; i < elm.children.length; i++) { + styleTDTH(dom, elm.children[i], name, value); + } + } + } + } + var extractDataFromElement$2 = function (editor, tableElm) { + var dom = editor.dom; + var data = { + width: dom.getStyle(tableElm, 'width') || dom.getAttrib(tableElm, 'width'), + height: dom.getStyle(tableElm, 'height') || dom.getAttrib(tableElm, 'height'), + cellspacing: dom.getStyle(tableElm, 'border-spacing') || dom.getAttrib(tableElm, 'cellspacing'), + cellpadding: dom.getAttrib(tableElm, 'data-mce-cell-padding') || dom.getAttrib(tableElm, 'cellpadding') || Styles$1.getTDTHOverallStyle(editor.dom, tableElm, 'padding'), + border: dom.getAttrib(tableElm, 'data-mce-border') || dom.getAttrib(tableElm, 'border') || Styles$1.getTDTHOverallStyle(editor.dom, tableElm, 'border'), + borderColor: dom.getAttrib(tableElm, 'data-mce-border-color'), + caption: !!dom.select('caption', tableElm)[0], + class: dom.getAttrib(tableElm, 'class') + }; + global$1.each('left center right'.split(' '), function (name) { + if (editor.formatter.matchNode(tableElm, 'align' + name)) { + data.align = name; + } + }); + if (hasAdvancedTableTab(editor)) { + global$1.extend(data, Helpers.extractAdvancedStyles(dom, tableElm)); + } + return data; + }; + var applyDataToElement = function (editor, tableElm, data) { + var dom = editor.dom; + var attrs = {}; + var styles = {}; + attrs.class = data.class; + styles.height = addSizeSuffix(data.height); + if (dom.getAttrib(tableElm, 'width') && !shouldStyleWithCss(editor)) { + attrs.width = removePxSuffix(data.width); + } else { + styles.width = addSizeSuffix(data.width); + } + if (shouldStyleWithCss(editor)) { + styles['border-width'] = addSizeSuffix(data.border); + styles['border-spacing'] = addSizeSuffix(data.cellspacing); + global$1.extend(attrs, { + 'data-mce-border-color': data.borderColor, + 'data-mce-cell-padding': data.cellpadding, + 'data-mce-border': data.border + }); + } else { + global$1.extend(attrs, { + border: data.border, + cellpadding: data.cellpadding, + cellspacing: data.cellspacing + }); + } + if (shouldStyleWithCss(editor)) { + if (tableElm.children) { + for (var i = 0; i < tableElm.children.length; i++) { + styleTDTH(dom, tableElm.children[i], { + 'border-width': addSizeSuffix(data.border), + 'border-color': data.borderColor, + 'padding': addSizeSuffix(data.cellpadding) + }); + } + } + } + if (data.style) { + global$1.extend(styles, dom.parseStyle(data.style)); + } else { + styles = global$1.extend({}, dom.parseStyle(dom.getAttrib(tableElm, 'style')), styles); + } + attrs.style = dom.serializeStyle(styles); + dom.setAttribs(tableElm, attrs); + }; + var onSubmitTableForm = function (editor, tableElm, evt) { + var dom = editor.dom; + var captionElm; + var data; + if (hasAdvancedTableTab(editor)) { + Helpers.syncAdvancedStyleFields(editor, evt); + } + data = evt.control.rootControl.toJSON(); + if (data.class === false) { + delete data.class; + } + editor.undoManager.transact(function () { + if (!tableElm) { + tableElm = InsertTable.insert(editor, data.cols || 1, data.rows || 1); + } + applyDataToElement(editor, tableElm, data); + captionElm = dom.select('caption', tableElm)[0]; + if (captionElm && !data.caption) { + dom.remove(captionElm); + } + if (!captionElm && data.caption) { + captionElm = dom.create('caption'); + captionElm.innerHTML = !global$2.ie ? '
            ' : '\xA0'; + tableElm.insertBefore(captionElm, tableElm.firstChild); + } + Styles$1.unApplyAlign(editor, tableElm); + if (data.align) { + Styles$1.applyAlign(editor, tableElm, data.align); + } + editor.focus(); + editor.addVisual(); + }); + }; + var open$2 = function (editor, isProps) { + var dom = editor.dom; + var tableElm, colsCtrl, rowsCtrl, classListCtrl, data = {}, generalTableForm; + if (isProps === true) { + tableElm = dom.getParent(editor.selection.getStart(), 'table'); + if (tableElm) { + data = extractDataFromElement$2(editor, tableElm); + } + } else { + colsCtrl = { + label: 'Cols', + name: 'cols' + }; + rowsCtrl = { + label: 'Rows', + name: 'rows' + }; + } + if (getTableClassList(editor).length > 0) { + if (data.class) { + data.class = data.class.replace(/\s*mce\-item\-table\s*/g, ''); + } + classListCtrl = { + name: 'class', + type: 'listbox', + label: 'Class', + values: Helpers.buildListItems(getTableClassList(editor), function (item) { + if (item.value) { + item.textStyle = function () { + return editor.formatter.getCssText({ + block: 'table', + classes: [item.value] + }); + }; + } + }) + }; + } + generalTableForm = { + type: 'form', + layout: 'flex', + direction: 'column', + labelGapCalc: 'children', + padding: 0, + items: [ + { + type: 'form', + labelGapCalc: false, + padding: 0, + layout: 'grid', + columns: 2, + defaults: { + type: 'textbox', + maxWidth: 50 + }, + items: hasAppearanceOptions(editor) ? [ + colsCtrl, + rowsCtrl, + { + label: 'Width', + name: 'width', + onchange: curry(Helpers.updateStyleField, editor) + }, + { + label: 'Height', + name: 'height', + onchange: curry(Helpers.updateStyleField, editor) + }, + { + label: 'Cell spacing', + name: 'cellspacing' + }, + { + label: 'Cell padding', + name: 'cellpadding' + }, + { + label: 'Border', + name: 'border' + }, + { + label: 'Caption', + name: 'caption', + type: 'checkbox' + } + ] : [ + colsCtrl, + rowsCtrl, + { + label: 'Width', + name: 'width', + onchange: curry(Helpers.updateStyleField, editor) + }, + { + label: 'Height', + name: 'height', + onchange: curry(Helpers.updateStyleField, editor) + } + ] + }, + { + label: 'Alignment', + name: 'align', + type: 'listbox', + text: 'None', + values: [ + { + text: 'None', + value: '' + }, + { + text: 'Left', + value: 'left' + }, + { + text: 'Center', + value: 'center' + }, + { + text: 'Right', + value: 'right' + } + ] + }, + classListCtrl + ] + }; + if (hasAdvancedTableTab(editor)) { + editor.windowManager.open({ + title: 'Table properties', + data: data, + bodyType: 'tabpanel', + body: [ + { + title: 'General', + type: 'form', + items: generalTableForm + }, + Helpers.createStyleForm(editor) + ], + onsubmit: curry(onSubmitTableForm, editor, tableElm) + }); + } else { + editor.windowManager.open({ + title: 'Table properties', + data: data, + body: generalTableForm, + onsubmit: curry(onSubmitTableForm, editor, tableElm) + }); + } + }; + var TableDialog = { open: open$2 }; + + var each$3 = global$1.each; + var registerCommands = function (editor, actions, cellSelection, selections, clipboardRows) { + var isRoot = getIsRoot(editor); + var eraseTable = function () { + getSelectionStartCell().orThunk(getSelectionStartCaption).each(function (cellOrCaption) { + var table = TableLookup.table(cellOrCaption, isRoot); + table.filter(not(isRoot)).each(function (table) { + var cursor = Element.fromText(''); + after(table, cursor); + remove$2(table); + var rng = editor.dom.createRng(); + rng.setStart(cursor.dom(), 0); + rng.setEnd(cursor.dom(), 0); + editor.selection.setRng(rng); + }); + }); + }; + var getSelectionStartFromSelector = function (selector) { + return function () { + return Option.from(editor.dom.getParent(editor.selection.getStart(), selector)).map(Element.fromDom); + }; + }; + var getSelectionStartCaption = getSelectionStartFromSelector('caption'); + var getSelectionStartCell = getSelectionStartFromSelector('th,td'); + var getTableFromCell = function (cell) { + return TableLookup.table(cell, isRoot); + }; + var getSize = function (table) { + return { + width: getPixelWidth$1(table.dom()), + height: getPixelWidth$1(table.dom()) + }; + }; + var resizeChange = function (editor, oldSize, table) { + var newSize = getSize(table); + if (oldSize.width !== newSize.width || oldSize.height !== newSize.height) { + fireObjectResizeStart(editor, table.dom(), oldSize.width, oldSize.height); + fireObjectResized(editor, table.dom(), newSize.width, newSize.height); + } + }; + var actOnSelection = function (execute) { + getSelectionStartCell().each(function (cell) { + getTableFromCell(cell).each(function (table) { + var targets = TableTargets.forMenu(selections, table, cell); + var beforeSize = getSize(table); + execute(table, targets).each(function (rng) { + resizeChange(editor, beforeSize, table); + editor.selection.setRng(rng); + editor.focus(); + cellSelection.clear(table); + removeDataStyle(table); + }); + }); + }); + }; + var copyRowSelection = function (execute) { + return getSelectionStartCell().bind(function (cell) { + return getTableFromCell(cell).bind(function (table) { + var doc = Element.fromDom(editor.getDoc()); + var targets = TableTargets.forMenu(selections, table, cell); + var generators = TableFill.cellOperations(noop, doc, Option.none()); + return CopyRows.copyRows(table, targets, generators); + }); + }); + }; + var pasteOnSelection = function (execute) { + clipboardRows.get().each(function (rows) { + var clonedRows = map(rows, function (row) { + return deep(row); + }); + getSelectionStartCell().each(function (cell) { + getTableFromCell(cell).each(function (table) { + var doc = Element.fromDom(editor.getDoc()); + var generators = TableFill.paste(doc); + var targets = TableTargets.pasteRows(selections, table, cell, clonedRows, generators); + execute(table, targets).each(function (rng) { + editor.selection.setRng(rng); + editor.focus(); + cellSelection.clear(table); + }); + }); + }); + }); + }; + each$3({ + mceTableSplitCells: function () { + actOnSelection(actions.unmergeCells); + }, + mceTableMergeCells: function () { + actOnSelection(actions.mergeCells); + }, + mceTableInsertRowBefore: function () { + actOnSelection(actions.insertRowsBefore); + }, + mceTableInsertRowAfter: function () { + actOnSelection(actions.insertRowsAfter); + }, + mceTableInsertColBefore: function () { + actOnSelection(actions.insertColumnsBefore); + }, + mceTableInsertColAfter: function () { + actOnSelection(actions.insertColumnsAfter); + }, + mceTableDeleteCol: function () { + actOnSelection(actions.deleteColumn); + }, + mceTableDeleteRow: function () { + actOnSelection(actions.deleteRow); + }, + mceTableCutRow: function (grid) { + clipboardRows.set(copyRowSelection()); + actOnSelection(actions.deleteRow); + }, + mceTableCopyRow: function (grid) { + clipboardRows.set(copyRowSelection()); + }, + mceTablePasteRowBefore: function (grid) { + pasteOnSelection(actions.pasteRowsBefore); + }, + mceTablePasteRowAfter: function (grid) { + pasteOnSelection(actions.pasteRowsAfter); + }, + mceTableDelete: eraseTable + }, function (func, name) { + editor.addCommand(name, func); + }); + each$3({ + mceInsertTable: curry(TableDialog.open, editor), + mceTableProps: curry(TableDialog.open, editor, true), + mceTableRowProps: curry(RowDialog.open, editor), + mceTableCellProps: curry(CellDialog.open, editor) + }, function (func, name) { + editor.addCommand(name, function (ui, val) { + func(val); + }); + }); + }; + var Commands = { registerCommands: registerCommands }; + + var only = function (element) { + var parent = Option.from(element.dom().documentElement).map(Element.fromDom).getOr(element); + return { + parent: constant(parent), + view: constant(element), + origin: constant(Position(0, 0)) + }; + }; + var detached = function (editable, chrome) { + var origin = function () { + return absolute(chrome); + }; + return { + parent: constant(chrome), + view: constant(editable), + origin: origin + }; + }; + var body$1 = function (editable, chrome) { + return { + parent: constant(chrome), + view: constant(editable), + origin: constant(Position(0, 0)) + }; + }; + var ResizeWire = { + only: only, + detached: detached, + body: body$1 + }; + + var Event = function (fields) { + var struct = Immutable.apply(null, fields); + var handlers = []; + var bind = function (handler) { + if (handler === undefined) { + throw new Error('Event bind error: undefined handler'); + } + handlers.push(handler); + }; + var unbind = function (handler) { + handlers = filter(handlers, function (h) { + return h !== handler; + }); + }; + var trigger = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var event = struct.apply(null, args); + each(handlers, function (handler) { + handler(event); + }); + }; + return { + bind: bind, + unbind: unbind, + trigger: trigger + }; + }; + + var create$1 = function (typeDefs) { + var registry = map$1(typeDefs, function (event) { + return { + bind: event.bind, + unbind: event.unbind + }; + }); + var trigger = map$1(typeDefs, function (event) { + return event.trigger; + }); + return { + registry: registry, + trigger: trigger + }; + }; + var Events = { create: create$1 }; + + var mkEvent = function (target, x, y, stop, prevent, kill, raw) { + return { + target: constant(target), + x: constant(x), + y: constant(y), + stop: stop, + prevent: prevent, + kill: kill, + raw: constant(raw) + }; + }; + var handle = function (filter, handler) { + return function (rawEvent) { + if (!filter(rawEvent)) { + return; + } + var target = Element.fromDom(rawEvent.target); + var stop = function () { + rawEvent.stopPropagation(); + }; + var prevent = function () { + rawEvent.preventDefault(); + }; + var kill = compose(prevent, stop); + var evt = mkEvent(target, rawEvent.clientX, rawEvent.clientY, stop, prevent, kill, rawEvent); + handler(evt); + }; + }; + var binder = function (element, event, filter, handler, useCapture) { + var wrapped = handle(filter, handler); + element.dom().addEventListener(event, wrapped, useCapture); + return { unbind: curry(unbind, element, event, wrapped, useCapture) }; + }; + var bind$1 = function (element, event, filter, handler) { + return binder(element, event, filter, handler, false); + }; + var unbind = function (element, event, handler, useCapture) { + element.dom().removeEventListener(event, handler, useCapture); + }; + + var filter$1 = constant(true); + var bind$2 = function (element, event, handler) { + return bind$1(element, event, filter$1, handler); + }; + + var hasOwnProperty = Object.prototype.hasOwnProperty; + var shallow$1 = function (old, nu) { + return nu; + }; + var baseMerge = function (merger) { + return function () { + var objects = new Array(arguments.length); + for (var i = 0; i < objects.length; i++) { + objects[i] = arguments[i]; + } + if (objects.length === 0) { + throw new Error('Can\'t merge zero objects'); + } + var ret = {}; + for (var j = 0; j < objects.length; j++) { + var curObject = objects[j]; + for (var key in curObject) { + if (hasOwnProperty.call(curObject, key)) { + ret[key] = merger(ret[key], curObject[key]); + } + } + } + return ret; + }; + }; + var merge$3 = baseMerge(shallow$1); + + var styles$1 = css('ephox-dragster'); + var Styles$2 = { resolve: styles$1.resolve }; + + var Blocker = function (options) { + var settings = merge$3({ layerClass: Styles$2.resolve('blocker') }, options); + var div = Element.fromTag('div'); + set(div, 'role', 'presentation'); + setAll$1(div, { + position: 'fixed', + left: '0px', + top: '0px', + width: '100%', + height: '100%' + }); + add$2(div, Styles$2.resolve('blocker')); + add$2(div, settings.layerClass); + var element = function () { + return div; + }; + var destroy = function () { + remove$2(div); + }; + return { + element: element, + destroy: destroy + }; + }; + + var DragMode = exactly([ + 'compare', + 'extract', + 'mutate', + 'sink' + ]); + var DragSink = exactly([ + 'element', + 'start', + 'stop', + 'destroy' + ]); + var DragApi = exactly([ + 'forceDrop', + 'drop', + 'move', + 'delayDrop' + ]); + + var compare = function (old, nu) { + return Position(nu.left() - old.left(), nu.top() - old.top()); + }; + var extract$1 = function (event) { + return Option.some(Position(event.x(), event.y())); + }; + var mutate = function (mutation, info) { + mutation.mutate(info.left(), info.top()); + }; + var sink = function (dragApi, settings) { + var blocker = Blocker(settings); + var mdown = bind$2(blocker.element(), 'mousedown', dragApi.forceDrop); + var mup = bind$2(blocker.element(), 'mouseup', dragApi.drop); + var mmove = bind$2(blocker.element(), 'mousemove', dragApi.move); + var mout = bind$2(blocker.element(), 'mouseout', dragApi.delayDrop); + var destroy = function () { + blocker.destroy(); + mup.unbind(); + mmove.unbind(); + mout.unbind(); + mdown.unbind(); + }; + var start = function (parent) { + append(parent, blocker.element()); + }; + var stop = function () { + remove$2(blocker.element()); + }; + return DragSink({ + element: blocker.element, + start: start, + stop: stop, + destroy: destroy + }); + }; + var MouseDrag = DragMode({ + compare: compare, + extract: extract$1, + sink: sink, + mutate: mutate + }); + + var last$2 = function (fn, rate) { + var timer = null; + var cancel = function () { + if (timer !== null) { + domGlobals.clearTimeout(timer); + timer = null; + } + }; + var throttle = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (timer !== null) { + domGlobals.clearTimeout(timer); + } + timer = domGlobals.setTimeout(function () { + fn.apply(null, args); + timer = null; + }, rate); + }; + return { + cancel: cancel, + throttle: throttle + }; + }; + + function InDrag () { + var previous = Option.none(); + var reset = function () { + previous = Option.none(); + }; + var update = function (mode, nu) { + var result = previous.map(function (old) { + return mode.compare(old, nu); + }); + previous = Option.some(nu); + return result; + }; + var onEvent = function (event, mode) { + var dataOption = mode.extract(event); + dataOption.each(function (data) { + var offset = update(mode, data); + offset.each(function (d) { + events.trigger.move(d); + }); + }); + }; + var events = Events.create({ move: Event(['info']) }); + return { + onEvent: onEvent, + reset: reset, + events: events.registry + }; + } + + function NoDrag () { + return { + onEvent: noop, + reset: noop + }; + } + + function Movement () { + var noDragState = NoDrag(); + var inDragState = InDrag(); + var dragState = noDragState; + var on = function () { + dragState.reset(); + dragState = inDragState; + }; + var off = function () { + dragState.reset(); + dragState = noDragState; + }; + var onEvent = function (event, mode) { + dragState.onEvent(event, mode); + }; + var isOn = function () { + return dragState === inDragState; + }; + return { + on: on, + off: off, + isOn: isOn, + onEvent: onEvent, + events: inDragState.events + }; + } + + var setup = function (mutation, mode, settings) { + var active = false; + var events = Events.create({ + start: Event([]), + stop: Event([]) + }); + var movement = Movement(); + var drop = function () { + sink.stop(); + if (movement.isOn()) { + movement.off(); + events.trigger.stop(); + } + }; + var throttledDrop = last$2(drop, 200); + var go = function (parent) { + sink.start(parent); + movement.on(); + events.trigger.start(); + }; + var mousemove = function (event) { + throttledDrop.cancel(); + movement.onEvent(event, mode); + }; + movement.events.move.bind(function (event) { + mode.mutate(mutation, event.info()); + }); + var on = function () { + active = true; + }; + var off = function () { + active = false; + }; + var runIfActive = function (f) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (active) { + f.apply(null, args); + } + }; + }; + var sink = mode.sink(DragApi({ + forceDrop: drop, + drop: runIfActive(drop), + move: runIfActive(mousemove), + delayDrop: runIfActive(throttledDrop.throttle) + }), settings); + var destroy = function () { + sink.destroy(); + }; + return { + element: sink.element, + go: go, + on: on, + off: off, + destroy: destroy, + events: events.registry + }; + }; + var Dragging = { setup: setup }; + + var transform$1 = function (mutation, settings) { + if (settings === void 0) { + settings = {}; + } + var mode = settings.mode !== undefined ? settings.mode : MouseDrag; + return Dragging.setup(mutation, mode, settings); + }; + var Dragger = { transform: transform$1 }; + + var Mutation = function () { + var events = Events.create({ + drag: Event([ + 'xDelta', + 'yDelta' + ]) + }); + var mutate = function (x, y) { + events.trigger.drag(x, y); + }; + return { + mutate: mutate, + events: events.registry + }; + }; + + var BarMutation = function () { + var events = Events.create({ + drag: Event([ + 'xDelta', + 'yDelta', + 'target' + ]) + }); + var target = Option.none(); + var delegate = Mutation(); + delegate.events.drag.bind(function (event) { + target.each(function (t) { + events.trigger.drag(event.xDelta(), event.yDelta(), t); + }); + }); + var assign = function (t) { + target = Option.some(t); + }; + var get = function () { + return target; + }; + return { + assign: assign, + get: get, + mutate: delegate.mutate, + events: events.registry + }; + }; + + var isContentEditableTrue = function (elm) { + return get(elm, 'contenteditable') === 'true'; + }; + var findClosestContentEditable = function (target, isRoot) { + return closest$1(target, '[contenteditable]', isRoot); + }; + + var resizeBarDragging = Styles.resolve('resizer-bar-dragging'); + var BarManager = function (wire, direction, hdirection) { + var mutation = BarMutation(); + var resizing = Dragger.transform(mutation, {}); + var hoverTable = Option.none(); + var getResizer = function (element, type) { + return Option.from(get(element, type)); + }; + mutation.events.drag.bind(function (event) { + getResizer(event.target(), 'data-row').each(function (_dataRow) { + var currentRow = CellUtils.getInt(event.target(), 'top'); + set$1(event.target(), 'top', currentRow + event.yDelta() + 'px'); + }); + getResizer(event.target(), 'data-column').each(function (_dataCol) { + var currentCol = CellUtils.getInt(event.target(), 'left'); + set$1(event.target(), 'left', currentCol + event.xDelta() + 'px'); + }); + }); + var getDelta = function (target, dir) { + var newX = CellUtils.getInt(target, dir); + var oldX = parseInt(get(target, 'data-initial-' + dir), 10); + return newX - oldX; + }; + resizing.events.stop.bind(function () { + mutation.get().each(function (target) { + hoverTable.each(function (table) { + getResizer(target, 'data-row').each(function (row) { + var delta = getDelta(target, 'top'); + remove(target, 'data-initial-top'); + events.trigger.adjustHeight(table, delta, parseInt(row, 10)); + }); + getResizer(target, 'data-column').each(function (column) { + var delta = getDelta(target, 'left'); + remove(target, 'data-initial-left'); + events.trigger.adjustWidth(table, delta, parseInt(column, 10)); + }); + Bars.refresh(wire, table, hdirection, direction); + }); + }); + }); + var handler = function (target, dir) { + events.trigger.startAdjust(); + mutation.assign(target); + set(target, 'data-initial-' + dir, parseInt(get$1(target, dir), 10)); + add$2(target, resizeBarDragging); + set$1(target, 'opacity', '0.2'); + resizing.go(wire.parent()); + }; + var mousedown = bind$2(wire.parent(), 'mousedown', function (event) { + if (Bars.isRowBar(event.target())) { + handler(event.target(), 'top'); + } + if (Bars.isColBar(event.target())) { + handler(event.target(), 'left'); + } + }); + var isRoot = function (e) { + return eq(e, wire.view()); + }; + var findClosestEditableTable = function (target) { + return closest$1(target, 'table', isRoot).filter(function (table) { + return findClosestContentEditable(table, isRoot).exists(isContentEditableTrue); + }); + }; + var mouseover = bind$2(wire.view(), 'mouseover', function (event) { + findClosestEditableTable(event.target()).fold(function () { + if (inBody(event.target())) { + Bars.destroy(wire); + } + }, function (table) { + hoverTable = Option.some(table); + Bars.refresh(wire, table, hdirection, direction); + }); + }); + var destroy = function () { + mousedown.unbind(); + mouseover.unbind(); + resizing.destroy(); + Bars.destroy(wire); + }; + var refresh = function (tbl) { + Bars.refresh(wire, tbl, hdirection, direction); + }; + var events = Events.create({ + adjustHeight: Event([ + 'table', + 'delta', + 'row' + ]), + adjustWidth: Event([ + 'table', + 'delta', + 'column' + ]), + startAdjust: Event([]) + }); + return { + destroy: destroy, + refresh: refresh, + on: resizing.on, + off: resizing.off, + hideBars: curry(Bars.hide, wire), + showBars: curry(Bars.show, wire), + events: events.registry + }; + }; + + var create$2 = function (wire, vdirection) { + var hdirection = BarPositions.height; + var manager = BarManager(wire, vdirection, hdirection); + var events = Events.create({ + beforeResize: Event(['table']), + afterResize: Event(['table']), + startDrag: Event([]) + }); + manager.events.adjustHeight.bind(function (event) { + events.trigger.beforeResize(event.table()); + var delta = hdirection.delta(event.delta(), event.table()); + Adjustments.adjustHeight(event.table(), delta, event.row(), hdirection); + events.trigger.afterResize(event.table()); + }); + manager.events.startAdjust.bind(function (event) { + events.trigger.startDrag(); + }); + manager.events.adjustWidth.bind(function (event) { + events.trigger.beforeResize(event.table()); + var delta = vdirection.delta(event.delta(), event.table()); + Adjustments.adjustWidth(event.table(), delta, event.column(), vdirection); + events.trigger.afterResize(event.table()); + }); + return { + on: manager.on, + off: manager.off, + hideBars: manager.hideBars, + showBars: manager.showBars, + destroy: manager.destroy, + events: events.registry + }; + }; + var TableResize = { create: create$2 }; + + var createContainer = function () { + var container = Element.fromTag('div'); + setAll$1(container, { + position: 'static', + height: '0', + width: '0', + padding: '0', + margin: '0', + border: '0' + }); + append(body(), container); + return container; + }; + var get$8 = function (editor, container) { + return editor.inline ? ResizeWire.body(getBody$1(editor), createContainer()) : ResizeWire.only(Element.fromDom(editor.getDoc())); + }; + var remove$6 = function (editor, wire) { + if (editor.inline) { + remove$2(wire.parent()); + } + }; + var TableWire = { + get: get$8, + remove: remove$6 + }; + + var ResizeHandler = function (editor) { + var selectionRng = Option.none(); + var resize = Option.none(); + var wire = Option.none(); + var percentageBasedSizeRegex = /(\d+(\.\d+)?)%/; + var startW, startRawW; + var isTable = function (elm) { + return elm.nodeName === 'TABLE'; + }; + var getRawWidth = function (elm) { + return editor.dom.getStyle(elm, 'width') || editor.dom.getAttrib(elm, 'width'); + }; + var lazyResize = function () { + return resize; + }; + var lazyWire = function () { + return wire.getOr(ResizeWire.only(Element.fromDom(editor.getBody()))); + }; + var destroy = function () { + resize.each(function (sz) { + sz.destroy(); + }); + wire.each(function (w) { + TableWire.remove(editor, w); + }); + }; + editor.on('init', function () { + var direction = TableDirection(Direction.directionAt); + var rawWire = TableWire.get(editor); + wire = Option.some(rawWire); + if (hasObjectResizing(editor) && hasTableResizeBars(editor)) { + var sz = TableResize.create(rawWire, direction); + sz.on(); + sz.events.startDrag.bind(function (event) { + selectionRng = Option.some(editor.selection.getRng()); + }); + sz.events.beforeResize.bind(function (event) { + var rawTable = event.table().dom(); + fireObjectResizeStart(editor, rawTable, getPixelWidth$1(rawTable), getPixelHeight(rawTable)); + }); + sz.events.afterResize.bind(function (event) { + var table = event.table(); + var rawTable = table.dom(); + removeDataStyle(table); + selectionRng.each(function (rng) { + editor.selection.setRng(rng); + editor.focus(); + }); + fireObjectResized(editor, rawTable, getPixelWidth$1(rawTable), getPixelHeight(rawTable)); + editor.undoManager.add(); + }); + resize = Option.some(sz); + } + }); + editor.on('ObjectResizeStart', function (e) { + var targetElm = e.target; + if (isTable(targetElm)) { + startW = e.width; + startRawW = getRawWidth(targetElm); + } + }); + editor.on('ObjectResized', function (e) { + var targetElm = e.target; + if (isTable(targetElm)) { + var table = targetElm; + if (percentageBasedSizeRegex.test(startRawW)) { + var percentW = parseFloat(percentageBasedSizeRegex.exec(startRawW)[1]); + var targetPercentW = e.width * percentW / startW; + editor.dom.setStyle(table, 'width', targetPercentW + '%'); + } else { + var newCellSizes_1 = []; + global$1.each(table.rows, function (row) { + global$1.each(row.cells, function (cell) { + var width = editor.dom.getStyle(cell, 'width', true); + newCellSizes_1.push({ + cell: cell, + width: width + }); + }); + }); + global$1.each(newCellSizes_1, function (newCellSize) { + editor.dom.setStyle(newCellSize.cell, 'width', newCellSize.width); + editor.dom.setAttrib(newCellSize.cell, 'width', null); + }); + } + } + }); + return { + lazyResize: lazyResize, + lazyWire: lazyWire, + destroy: destroy + }; + }; + + var adt$1 = Adt.generate([ + { none: ['current'] }, + { first: ['current'] }, + { + middle: [ + 'current', + 'target' + ] + }, + { last: ['current'] } + ]); + var none$1 = function (current) { + if (current === void 0) { + current = undefined; + } + return adt$1.none(current); + }; + var CellLocation = __assign(__assign({}, adt$1), { none: none$1 }); + + var detect$4 = function (current, isRoot) { + return TableLookup.table(current, isRoot).bind(function (table) { + var all = TableLookup.cells(table); + var index = findIndex(all, function (x) { + return eq(current, x); + }); + return index.map(function (ind) { + return { + index: constant(ind), + all: constant(all) + }; + }); + }); + }; + var next = function (current, isRoot) { + var detection = detect$4(current, isRoot); + return detection.fold(function () { + return CellLocation.none(current); + }, function (info) { + return info.index() + 1 < info.all().length ? CellLocation.middle(current, info.all()[info.index() + 1]) : CellLocation.last(current); + }); + }; + var prev = function (current, isRoot) { + var detection = detect$4(current, isRoot); + return detection.fold(function () { + return CellLocation.none(); + }, function (info) { + return info.index() - 1 >= 0 ? CellLocation.middle(current, info.all()[info.index() - 1]) : CellLocation.first(current); + }); + }; + var CellNavigation = { + next: next, + prev: prev + }; + + var create$3 = Immutable('start', 'soffset', 'finish', 'foffset'); + var SimRange = { create: create$3 }; + + var adt$2 = Adt.generate([ + { before: ['element'] }, + { + on: [ + 'element', + 'offset' + ] + }, + { after: ['element'] } + ]); + var cata$1 = function (subject, onBefore, onOn, onAfter) { + return subject.fold(onBefore, onOn, onAfter); + }; + var getStart = function (situ) { + return situ.fold(identity, identity, identity); + }; + var before$2 = adt$2.before; + var on = adt$2.on; + var after$2 = adt$2.after; + var Situ = { + before: before$2, + on: on, + after: after$2, + cata: cata$1, + getStart: getStart + }; + + var adt$3 = Adt.generate([ + { domRange: ['rng'] }, + { + relative: [ + 'startSitu', + 'finishSitu' + ] + }, + { + exact: [ + 'start', + 'soffset', + 'finish', + 'foffset' + ] + } + ]); + var exactFromRange = function (simRange) { + return adt$3.exact(simRange.start(), simRange.soffset(), simRange.finish(), simRange.foffset()); + }; + var getStart$1 = function (selection) { + return selection.match({ + domRange: function (rng) { + return Element.fromDom(rng.startContainer); + }, + relative: function (startSitu, finishSitu) { + return Situ.getStart(startSitu); + }, + exact: function (start, soffset, finish, foffset) { + return start; + } + }); + }; + var domRange = adt$3.domRange; + var relative = adt$3.relative; + var exact = adt$3.exact; + var getWin = function (selection) { + var start = getStart$1(selection); + return defaultView(start); + }; + var range$1 = SimRange.create; + var Selection = { + domRange: domRange, + relative: relative, + exact: exact, + exactFromRange: exactFromRange, + getWin: getWin, + range: range$1 + }; + + var selectNodeContents = function (win, element) { + var rng = win.document.createRange(); + selectNodeContentsUsing(rng, element); + return rng; + }; + var selectNodeContentsUsing = function (rng, element) { + rng.selectNodeContents(element.dom()); + }; + var setStart = function (rng, situ) { + situ.fold(function (e) { + rng.setStartBefore(e.dom()); + }, function (e, o) { + rng.setStart(e.dom(), o); + }, function (e) { + rng.setStartAfter(e.dom()); + }); + }; + var setFinish = function (rng, situ) { + situ.fold(function (e) { + rng.setEndBefore(e.dom()); + }, function (e, o) { + rng.setEnd(e.dom(), o); + }, function (e) { + rng.setEndAfter(e.dom()); + }); + }; + var relativeToNative = function (win, startSitu, finishSitu) { + var range = win.document.createRange(); + setStart(range, startSitu); + setFinish(range, finishSitu); + return range; + }; + var exactToNative = function (win, start, soffset, finish, foffset) { + var rng = win.document.createRange(); + rng.setStart(start.dom(), soffset); + rng.setEnd(finish.dom(), foffset); + return rng; + }; + var toRect = function (rect) { + return { + left: constant(rect.left), + top: constant(rect.top), + right: constant(rect.right), + bottom: constant(rect.bottom), + width: constant(rect.width), + height: constant(rect.height) + }; + }; + var getFirstRect = function (rng) { + var rects = rng.getClientRects(); + var rect = rects.length > 0 ? rects[0] : rng.getBoundingClientRect(); + return rect.width > 0 || rect.height > 0 ? Option.some(rect).map(toRect) : Option.none(); + }; + + var adt$4 = Adt.generate([ + { + ltr: [ + 'start', + 'soffset', + 'finish', + 'foffset' + ] + }, + { + rtl: [ + 'start', + 'soffset', + 'finish', + 'foffset' + ] + } + ]); + var fromRange = function (win, type, range) { + return type(Element.fromDom(range.startContainer), range.startOffset, Element.fromDom(range.endContainer), range.endOffset); + }; + var getRanges = function (win, selection) { + return selection.match({ + domRange: function (rng) { + return { + ltr: constant(rng), + rtl: Option.none + }; + }, + relative: function (startSitu, finishSitu) { + return { + ltr: cached(function () { + return relativeToNative(win, startSitu, finishSitu); + }), + rtl: cached(function () { + return Option.some(relativeToNative(win, finishSitu, startSitu)); + }) + }; + }, + exact: function (start, soffset, finish, foffset) { + return { + ltr: cached(function () { + return exactToNative(win, start, soffset, finish, foffset); + }), + rtl: cached(function () { + return Option.some(exactToNative(win, finish, foffset, start, soffset)); + }) + }; + } + }); + }; + var doDiagnose = function (win, ranges) { + var rng = ranges.ltr(); + if (rng.collapsed) { + var reversed = ranges.rtl().filter(function (rev) { + return rev.collapsed === false; + }); + return reversed.map(function (rev) { + return adt$4.rtl(Element.fromDom(rev.endContainer), rev.endOffset, Element.fromDom(rev.startContainer), rev.startOffset); + }).getOrThunk(function () { + return fromRange(win, adt$4.ltr, rng); + }); + } else { + return fromRange(win, adt$4.ltr, rng); + } + }; + var diagnose = function (win, selection) { + var ranges = getRanges(win, selection); + return doDiagnose(win, ranges); + }; + var asLtrRange = function (win, selection) { + var diagnosis = diagnose(win, selection); + return diagnosis.match({ + ltr: function (start, soffset, finish, foffset) { + var rng = win.document.createRange(); + rng.setStart(start.dom(), soffset); + rng.setEnd(finish.dom(), foffset); + return rng; + }, + rtl: function (start, soffset, finish, foffset) { + var rng = win.document.createRange(); + rng.setStart(finish.dom(), foffset); + rng.setEnd(start.dom(), soffset); + return rng; + } + }); + }; + + var searchForPoint = function (rectForOffset, x, y, maxX, length) { + if (length === 0) { + return 0; + } else if (x === maxX) { + return length - 1; + } + var xDelta = maxX; + for (var i = 1; i < length; i++) { + var rect = rectForOffset(i); + var curDeltaX = Math.abs(x - rect.left); + if (y <= rect.bottom) { + if (y < rect.top || curDeltaX > xDelta) { + return i - 1; + } else { + xDelta = curDeltaX; + } + } + } + return 0; + }; + var inRect = function (rect, x, y) { + return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom; + }; + + var locateOffset = function (doc, textnode, x, y, rect) { + var rangeForOffset = function (o) { + var r = doc.dom().createRange(); + r.setStart(textnode.dom(), o); + r.collapse(true); + return r; + }; + var rectForOffset = function (o) { + var r = rangeForOffset(o); + return r.getBoundingClientRect(); + }; + var length = get$2(textnode).length; + var offset = searchForPoint(rectForOffset, x, y, rect.right, length); + return rangeForOffset(offset); + }; + var locate = function (doc, node, x, y) { + var r = doc.dom().createRange(); + r.selectNode(node.dom()); + var rects = r.getClientRects(); + var foundRect = findMap(rects, function (rect) { + return inRect(rect, x, y) ? Option.some(rect) : Option.none(); + }); + return foundRect.map(function (rect) { + return locateOffset(doc, node, x, y, rect); + }); + }; + + var searchInChildren = function (doc, node, x, y) { + var r = doc.dom().createRange(); + var nodes = children(node); + return findMap(nodes, function (n) { + r.selectNode(n.dom()); + return inRect(r.getBoundingClientRect(), x, y) ? locateNode(doc, n, x, y) : Option.none(); + }); + }; + var locateNode = function (doc, node, x, y) { + return isText(node) ? locate(doc, node, x, y) : searchInChildren(doc, node, x, y); + }; + var locate$1 = function (doc, node, x, y) { + var r = doc.dom().createRange(); + r.selectNode(node.dom()); + var rect = r.getBoundingClientRect(); + var boundedX = Math.max(rect.left, Math.min(rect.right, x)); + var boundedY = Math.max(rect.top, Math.min(rect.bottom, y)); + return locateNode(doc, node, boundedX, boundedY); + }; + + var COLLAPSE_TO_LEFT = true; + var COLLAPSE_TO_RIGHT = false; + var getCollapseDirection = function (rect, x) { + return x - rect.left < rect.right - x ? COLLAPSE_TO_LEFT : COLLAPSE_TO_RIGHT; + }; + var createCollapsedNode = function (doc, target, collapseDirection) { + var r = doc.dom().createRange(); + r.selectNode(target.dom()); + r.collapse(collapseDirection); + return r; + }; + var locateInElement = function (doc, node, x) { + var cursorRange = doc.dom().createRange(); + cursorRange.selectNode(node.dom()); + var rect = cursorRange.getBoundingClientRect(); + var collapseDirection = getCollapseDirection(rect, x); + var f = collapseDirection === COLLAPSE_TO_LEFT ? first : last$1; + return f(node).map(function (target) { + return createCollapsedNode(doc, target, collapseDirection); + }); + }; + var locateInEmpty = function (doc, node, x) { + var rect = node.dom().getBoundingClientRect(); + var collapseDirection = getCollapseDirection(rect, x); + return Option.some(createCollapsedNode(doc, node, collapseDirection)); + }; + var search = function (doc, node, x) { + var f = children(node).length === 0 ? locateInEmpty : locateInElement; + return f(doc, node, x); + }; + + var caretPositionFromPoint = function (doc, x, y) { + return Option.from(doc.dom().caretPositionFromPoint(x, y)).bind(function (pos) { + if (pos.offsetNode === null) { + return Option.none(); + } + var r = doc.dom().createRange(); + r.setStart(pos.offsetNode, pos.offset); + r.collapse(); + return Option.some(r); + }); + }; + var caretRangeFromPoint = function (doc, x, y) { + return Option.from(doc.dom().caretRangeFromPoint(x, y)); + }; + var searchTextNodes = function (doc, node, x, y) { + var r = doc.dom().createRange(); + r.selectNode(node.dom()); + var rect = r.getBoundingClientRect(); + var boundedX = Math.max(rect.left, Math.min(rect.right, x)); + var boundedY = Math.max(rect.top, Math.min(rect.bottom, y)); + return locate$1(doc, node, boundedX, boundedY); + }; + var searchFromPoint = function (doc, x, y) { + return Element.fromPoint(doc, x, y).bind(function (elem) { + var fallback = function () { + return search(doc, elem, x); + }; + return children(elem).length === 0 ? fallback() : searchTextNodes(doc, elem, x, y).orThunk(fallback); + }); + }; + var availableSearch = document.caretPositionFromPoint ? caretPositionFromPoint : document.caretRangeFromPoint ? caretRangeFromPoint : searchFromPoint; + var fromPoint$1 = function (win, x, y) { + var doc = Element.fromDom(win.document); + return availableSearch(doc, x, y).map(function (rng) { + return SimRange.create(Element.fromDom(rng.startContainer), rng.startOffset, Element.fromDom(rng.endContainer), rng.endOffset); + }); + }; + + var beforeSpecial = function (element, offset) { + var name$1 = name(element); + if ('input' === name$1) { + return Situ.after(element); + } else if (!contains([ + 'br', + 'img' + ], name$1)) { + return Situ.on(element, offset); + } else { + return offset === 0 ? Situ.before(element) : Situ.after(element); + } + }; + var preprocessRelative = function (startSitu, finishSitu) { + var start = startSitu.fold(Situ.before, beforeSpecial, Situ.after); + var finish = finishSitu.fold(Situ.before, beforeSpecial, Situ.after); + return Selection.relative(start, finish); + }; + var preprocessExact = function (start, soffset, finish, foffset) { + var startSitu = beforeSpecial(start, soffset); + var finishSitu = beforeSpecial(finish, foffset); + return Selection.relative(startSitu, finishSitu); + }; + var preprocess = function (selection) { + return selection.match({ + domRange: function (rng) { + var start = Element.fromDom(rng.startContainer); + var finish = Element.fromDom(rng.endContainer); + return preprocessExact(start, rng.startOffset, finish, rng.endOffset); + }, + relative: preprocessRelative, + exact: preprocessExact + }); + }; + + var makeRange = function (start, soffset, finish, foffset) { + var doc = owner(start); + var rng = doc.dom().createRange(); + rng.setStart(start.dom(), soffset); + rng.setEnd(finish.dom(), foffset); + return rng; + }; + var after$3 = function (start, soffset, finish, foffset) { + var r = makeRange(start, soffset, finish, foffset); + var same = eq(start, finish) && soffset === foffset; + return r.collapsed && !same; + }; + + var doSetNativeRange = function (win, rng) { + Option.from(win.getSelection()).each(function (selection) { + selection.removeAllRanges(); + selection.addRange(rng); + }); + }; + var doSetRange = function (win, start, soffset, finish, foffset) { + var rng = exactToNative(win, start, soffset, finish, foffset); + doSetNativeRange(win, rng); + }; + var setLegacyRtlRange = function (win, selection, start, soffset, finish, foffset) { + selection.collapse(start.dom(), soffset); + selection.extend(finish.dom(), foffset); + }; + var setRangeFromRelative = function (win, relative) { + return diagnose(win, relative).match({ + ltr: function (start, soffset, finish, foffset) { + doSetRange(win, start, soffset, finish, foffset); + }, + rtl: function (start, soffset, finish, foffset) { + var selection = win.getSelection(); + if (selection.setBaseAndExtent) { + selection.setBaseAndExtent(start.dom(), soffset, finish.dom(), foffset); + } else if (selection.extend) { + try { + setLegacyRtlRange(win, selection, start, soffset, finish, foffset); + } catch (e) { + doSetRange(win, finish, foffset, start, soffset); + } + } else { + doSetRange(win, finish, foffset, start, soffset); + } + } + }); + }; + var setExact = function (win, start, soffset, finish, foffset) { + var relative = preprocessExact(start, soffset, finish, foffset); + setRangeFromRelative(win, relative); + }; + var setRelative = function (win, startSitu, finishSitu) { + var relative = preprocessRelative(startSitu, finishSitu); + setRangeFromRelative(win, relative); + }; + var toNative = function (selection) { + var win = Selection.getWin(selection).dom(); + var getDomRange = function (start, soffset, finish, foffset) { + return exactToNative(win, start, soffset, finish, foffset); + }; + var filtered = preprocess(selection); + return diagnose(win, filtered).match({ + ltr: getDomRange, + rtl: getDomRange + }); + }; + var readRange = function (selection) { + if (selection.rangeCount > 0) { + var firstRng = selection.getRangeAt(0); + var lastRng = selection.getRangeAt(selection.rangeCount - 1); + return Option.some(SimRange.create(Element.fromDom(firstRng.startContainer), firstRng.startOffset, Element.fromDom(lastRng.endContainer), lastRng.endOffset)); + } else { + return Option.none(); + } + }; + var doGetExact = function (selection) { + var anchor = Element.fromDom(selection.anchorNode); + var focus = Element.fromDom(selection.focusNode); + return after$3(anchor, selection.anchorOffset, focus, selection.focusOffset) ? Option.some(SimRange.create(anchor, selection.anchorOffset, focus, selection.focusOffset)) : readRange(selection); + }; + var setToElement = function (win, element) { + var rng = selectNodeContents(win, element); + doSetNativeRange(win, rng); + }; + var getExact = function (win) { + return Option.from(win.getSelection()).filter(function (sel) { + return sel.rangeCount > 0; + }).bind(doGetExact); + }; + var get$9 = function (win) { + return getExact(win).map(function (range) { + return Selection.exact(range.start(), range.soffset(), range.finish(), range.foffset()); + }); + }; + var getFirstRect$1 = function (win, selection) { + var rng = asLtrRange(win, selection); + return getFirstRect(rng); + }; + var getAtPoint = function (win, x, y) { + return fromPoint$1(win, x, y); + }; + var clear = function (win) { + var selection = win.getSelection(); + selection.removeAllRanges(); + }; + + var global$3 = tinymce.util.Tools.resolve('tinymce.util.VK'); + + var forward = function (editor, isRoot, cell, lazyWire) { + return go(editor, isRoot, CellNavigation.next(cell), lazyWire); + }; + var backward = function (editor, isRoot, cell, lazyWire) { + return go(editor, isRoot, CellNavigation.prev(cell), lazyWire); + }; + var getCellFirstCursorPosition = function (editor, cell) { + var selection = Selection.exact(cell, 0, cell, 0); + return toNative(selection); + }; + var getNewRowCursorPosition = function (editor, table) { + var rows = descendants$1(table, 'tr'); + return last(rows).bind(function (last) { + return descendant$1(last, 'td,th').map(function (first) { + return getCellFirstCursorPosition(editor, first); + }); + }); + }; + var go = function (editor, isRoot, cell, actions, lazyWire) { + return cell.fold(Option.none, Option.none, function (current, next) { + return first(next).map(function (cell) { + return getCellFirstCursorPosition(editor, cell); + }); + }, function (current) { + return TableLookup.table(current, isRoot).bind(function (table) { + var targets = TableTargets.noMenu(current); + editor.undoManager.transact(function () { + actions.insertRowsAfter(table, targets); + }); + return getNewRowCursorPosition(editor, table); + }); + }); + }; + var rootElements = [ + 'table', + 'li', + 'dl' + ]; + var handle$1 = function (event, editor, actions, lazyWire) { + if (event.keyCode === global$3.TAB) { + var body_1 = getBody$1(editor); + var isRoot_1 = function (element) { + var name$1 = name(element); + return eq(element, body_1) || contains(rootElements, name$1); + }; + var rng = editor.selection.getRng(); + if (rng.collapsed) { + var start = Element.fromDom(rng.startContainer); + TableLookup.cell(start, isRoot_1).each(function (cell) { + event.preventDefault(); + var navigation = event.shiftKey ? backward : forward; + var rng = navigation(editor, isRoot_1, cell, actions, lazyWire); + rng.each(function (range) { + editor.selection.setRng(range); + }); + }); + } + } + }; + var TabContext = { handle: handle$1 }; + + var create$4 = Immutable('selection', 'kill'); + var Response = { create: create$4 }; + + var create$5 = function (start, soffset, finish, foffset) { + return { + start: constant(Situ.on(start, soffset)), + finish: constant(Situ.on(finish, foffset)) + }; + }; + var Situs = { create: create$5 }; + + var convertToRange = function (win, selection) { + var rng = asLtrRange(win, selection); + return SimRange.create(Element.fromDom(rng.startContainer), rng.startOffset, Element.fromDom(rng.endContainer), rng.endOffset); + }; + var makeSitus = Situs.create; + var Util = { + convertToRange: convertToRange, + makeSitus: makeSitus + }; + + var sync = function (container, isRoot, start, soffset, finish, foffset, selectRange) { + if (!(eq(start, finish) && soffset === foffset)) { + return closest$1(start, 'td,th', isRoot).bind(function (s) { + return closest$1(finish, 'td,th', isRoot).bind(function (f) { + return detect$5(container, isRoot, s, f, selectRange); + }); + }); + } else { + return Option.none(); + } + }; + var detect$5 = function (container, isRoot, start, finish, selectRange) { + if (!eq(start, finish)) { + return CellSelection.identify(start, finish, isRoot).bind(function (cellSel) { + var boxes = cellSel.boxes().getOr([]); + if (boxes.length > 0) { + selectRange(container, boxes, cellSel.start(), cellSel.finish()); + return Option.some(Response.create(Option.some(Util.makeSitus(start, 0, start, getEnd(start))), true)); + } else { + return Option.none(); + } + }); + } else { + return Option.none(); + } + }; + var update = function (rows, columns, container, selected, annotations) { + var updateSelection = function (newSels) { + annotations.clear(container); + annotations.selectRange(container, newSels.boxes(), newSels.start(), newSels.finish()); + return newSels.boxes(); + }; + return CellSelection.shiftSelection(selected, rows, columns, annotations.firstSelectedSelector(), annotations.lastSelectedSelector()).map(updateSelection); + }; + var KeySelection = { + sync: sync, + detect: detect$5, + update: update + }; + + var traverse = Immutable('item', 'mode'); + var backtrack = function (universe, item, _direction, transition) { + if (transition === void 0) { + transition = sidestep; + } + return universe.property().parent(item).map(function (p) { + return traverse(p, transition); + }); + }; + var sidestep = function (universe, item, direction, transition) { + if (transition === void 0) { + transition = advance; + } + return direction.sibling(universe, item).map(function (p) { + return traverse(p, transition); + }); + }; + var advance = function (universe, item, direction, transition) { + if (transition === void 0) { + transition = advance; + } + var children = universe.property().children(item); + var result = direction.first(children); + return result.map(function (r) { + return traverse(r, transition); + }); + }; + var successors = [ + { + current: backtrack, + next: sidestep, + fallback: Option.none() + }, + { + current: sidestep, + next: advance, + fallback: Option.some(backtrack) + }, + { + current: advance, + next: advance, + fallback: Option.some(sidestep) + } + ]; + var go$1 = function (universe, item, mode, direction, rules) { + if (rules === void 0) { + rules = successors; + } + var ruleOpt = find(rules, function (succ) { + return succ.current === mode; + }); + return ruleOpt.bind(function (rule) { + return rule.current(universe, item, direction, rule.next).orThunk(function () { + return rule.fallback.bind(function (fb) { + return go$1(universe, item, fb, direction); + }); + }); + }); + }; + + var left = function () { + var sibling = function (universe, item) { + return universe.query().prevSibling(item); + }; + var first = function (children) { + return children.length > 0 ? Option.some(children[children.length - 1]) : Option.none(); + }; + return { + sibling: sibling, + first: first + }; + }; + var right = function () { + var sibling = function (universe, item) { + return universe.query().nextSibling(item); + }; + var first = function (children) { + return children.length > 0 ? Option.some(children[0]) : Option.none(); + }; + return { + sibling: sibling, + first: first + }; + }; + var Walkers = { + left: left, + right: right + }; + + var hone = function (universe, item, predicate, mode, direction, isRoot) { + var next = go$1(universe, item, mode, direction); + return next.bind(function (n) { + if (isRoot(n.item())) { + return Option.none(); + } else { + return predicate(n.item()) ? Option.some(n.item()) : hone(universe, n.item(), predicate, n.mode(), direction, isRoot); + } + }); + }; + var left$1 = function (universe, item, predicate, isRoot) { + return hone(universe, item, predicate, sidestep, Walkers.left(), isRoot); + }; + var right$1 = function (universe, item, predicate, isRoot) { + return hone(universe, item, predicate, sidestep, Walkers.right(), isRoot); + }; + + var isLeaf = function (universe) { + return function (element) { + return universe.property().children(element).length === 0; + }; + }; + var before$3 = function (universe, item, isRoot) { + return seekLeft(universe, item, isLeaf(universe), isRoot); + }; + var after$4 = function (universe, item, isRoot) { + return seekRight(universe, item, isLeaf(universe), isRoot); + }; + var seekLeft = left$1; + var seekRight = right$1; + + var universe$2 = DomUniverse(); + var before$4 = function (element, isRoot) { + return before$3(universe$2, element, isRoot); + }; + var after$5 = function (element, isRoot) { + return after$4(universe$2, element, isRoot); + }; + var seekLeft$1 = function (element, predicate, isRoot) { + return seekLeft(universe$2, element, predicate, isRoot); + }; + var seekRight$1 = function (element, predicate, isRoot) { + return seekRight(universe$2, element, predicate, isRoot); + }; + + var ancestor$2 = function (scope, predicate, isRoot) { + return ancestor(scope, predicate, isRoot).isSome(); + }; + + var point = Immutable('element', 'offset'); + var delta = Immutable('element', 'deltaOffset'); + var range$2 = Immutable('element', 'start', 'finish'); + var points = Immutable('begin', 'end'); + var text = Immutable('element', 'text'); + + var adt$5 = Adt.generate([ + { none: ['message'] }, + { success: [] }, + { failedUp: ['cell'] }, + { failedDown: ['cell'] } + ]); + var isOverlapping = function (bridge, before, after) { + var beforeBounds = bridge.getRect(before); + var afterBounds = bridge.getRect(after); + return afterBounds.right > beforeBounds.left && afterBounds.left < beforeBounds.right; + }; + var isRow = function (elem) { + return closest$1(elem, 'tr'); + }; + var verify = function (bridge, before, beforeOffset, after, afterOffset, failure, isRoot) { + return closest$1(after, 'td,th', isRoot).bind(function (afterCell) { + return closest$1(before, 'td,th', isRoot).map(function (beforeCell) { + if (!eq(afterCell, beforeCell)) { + return DomParent.sharedOne(isRow, [ + afterCell, + beforeCell + ]).fold(function () { + return isOverlapping(bridge, beforeCell, afterCell) ? adt$5.success() : failure(beforeCell); + }, function (_sharedRow) { + return failure(beforeCell); + }); + } else { + return eq(after, afterCell) && getEnd(afterCell) === afterOffset ? failure(beforeCell) : adt$5.none('in same cell'); + } + }); + }).getOr(adt$5.none('default')); + }; + var cata$2 = function (subject, onNone, onSuccess, onFailedUp, onFailedDown) { + return subject.fold(onNone, onSuccess, onFailedUp, onFailedDown); + }; + var BeforeAfter = __assign(__assign({}, adt$5), { + verify: verify, + cata: cata$2 + }); + + var inAncestor = Immutable('ancestor', 'descendants', 'element', 'index'); + var inParent = Immutable('parent', 'children', 'element', 'index'); + var indexInParent = function (element) { + return parent(element).bind(function (parent) { + var children$1 = children(parent); + return indexOf(children$1, element).map(function (index) { + return inParent(parent, children$1, element, index); + }); + }); + }; + var indexOf = function (elements, element) { + return findIndex(elements, curry(eq, element)); + }; + + var isBr = function (elem) { + return name(elem) === 'br'; + }; + var gatherer = function (cand, gather, isRoot) { + return gather(cand, isRoot).bind(function (target) { + return isText(target) && get$2(target).trim().length === 0 ? gatherer(target, gather, isRoot) : Option.some(target); + }); + }; + var handleBr = function (isRoot, element, direction) { + return direction.traverse(element).orThunk(function () { + return gatherer(element, direction.gather, isRoot); + }).map(direction.relative); + }; + var findBr = function (element, offset) { + return child(element, offset).filter(isBr).orThunk(function () { + return child(element, offset - 1).filter(isBr); + }); + }; + var handleParent = function (isRoot, element, offset, direction) { + return findBr(element, offset).bind(function (br) { + return direction.traverse(br).fold(function () { + return gatherer(br, direction.gather, isRoot).map(direction.relative); + }, function (adjacent) { + return indexInParent(adjacent).map(function (info) { + return Situ.on(info.parent(), info.index()); + }); + }); + }); + }; + var tryBr = function (isRoot, element, offset, direction) { + var target = isBr(element) ? handleBr(isRoot, element, direction) : handleParent(isRoot, element, offset, direction); + return target.map(function (tgt) { + return { + start: constant(tgt), + finish: constant(tgt) + }; + }); + }; + var process = function (analysis) { + return BeforeAfter.cata(analysis, function (message) { + return Option.none(); + }, function () { + return Option.none(); + }, function (cell) { + return Option.some(point(cell, 0)); + }, function (cell) { + return Option.some(point(cell, getEnd(cell))); + }); + }; + var BrTags = { + tryBr: tryBr, + process: process + }; + + var nu$3 = MixedBag([ + 'left', + 'top', + 'right', + 'bottom' + ], []); + var moveDown = function (caret, amount) { + return nu$3({ + left: caret.left(), + top: caret.top() + amount, + right: caret.right(), + bottom: caret.bottom() + amount + }); + }; + var moveUp = function (caret, amount) { + return nu$3({ + left: caret.left(), + top: caret.top() - amount, + right: caret.right(), + bottom: caret.bottom() - amount + }); + }; + var moveBottomTo = function (caret, bottom) { + var height = caret.bottom() - caret.top(); + return nu$3({ + left: caret.left(), + top: bottom - height, + right: caret.right(), + bottom: bottom + }); + }; + var moveTopTo = function (caret, top) { + var height = caret.bottom() - caret.top(); + return nu$3({ + left: caret.left(), + top: top, + right: caret.right(), + bottom: top + height + }); + }; + var translate = function (caret, xDelta, yDelta) { + return nu$3({ + left: caret.left() + xDelta, + top: caret.top() + yDelta, + right: caret.right() + xDelta, + bottom: caret.bottom() + yDelta + }); + }; + var getTop$1 = function (caret) { + return caret.top(); + }; + var getBottom = function (caret) { + return caret.bottom(); + }; + var toString = function (caret) { + return '(' + caret.left() + ', ' + caret.top() + ') -> (' + caret.right() + ', ' + caret.bottom() + ')'; + }; + var Carets = { + nu: nu$3, + moveUp: moveUp, + moveDown: moveDown, + moveBottomTo: moveBottomTo, + moveTopTo: moveTopTo, + getTop: getTop$1, + getBottom: getBottom, + translate: translate, + toString: toString + }; + + var getPartialBox = function (bridge, element, offset) { + if (offset >= 0 && offset < getEnd(element)) { + return bridge.getRangedRect(element, offset, element, offset + 1); + } else if (offset > 0) { + return bridge.getRangedRect(element, offset - 1, element, offset); + } + return Option.none(); + }; + var toCaret = function (rect) { + return Carets.nu({ + left: rect.left, + top: rect.top, + right: rect.right, + bottom: rect.bottom + }); + }; + var getElemBox = function (bridge, element) { + return Option.some(bridge.getRect(element)); + }; + var getBoxAt = function (bridge, element, offset) { + if (isElement(element)) { + return getElemBox(bridge, element).map(toCaret); + } else if (isText(element)) { + return getPartialBox(bridge, element, offset).map(toCaret); + } else { + return Option.none(); + } + }; + var getEntireBox = function (bridge, element) { + if (isElement(element)) { + return getElemBox(bridge, element).map(toCaret); + } else if (isText(element)) { + return bridge.getRangedRect(element, 0, element, getEnd(element)).map(toCaret); + } else { + return Option.none(); + } + }; + var Rectangles = { + getBoxAt: getBoxAt, + getEntireBox: getEntireBox + }; + + var JUMP_SIZE = 5; + var NUM_RETRIES = 100; + var adt$6 = Adt.generate([ + { none: [] }, + { retry: ['caret'] } + ]); + var isOutside = function (caret, box) { + return caret.left() < box.left() || Math.abs(box.right() - caret.left()) < 1 || caret.left() > box.right(); + }; + var inOutsideBlock = function (bridge, element, caret) { + return closest(element, DomStructure.isBlock).fold(constant(false), function (cell) { + return Rectangles.getEntireBox(bridge, cell).exists(function (box) { + return isOutside(caret, box); + }); + }); + }; + var adjustDown = function (bridge, element, guessBox, original, caret) { + var lowerCaret = Carets.moveDown(caret, JUMP_SIZE); + if (Math.abs(guessBox.bottom() - original.bottom()) < 1) { + return adt$6.retry(lowerCaret); + } else if (guessBox.top() > caret.bottom()) { + return adt$6.retry(lowerCaret); + } else if (guessBox.top() === caret.bottom()) { + return adt$6.retry(Carets.moveDown(caret, 1)); + } else { + return inOutsideBlock(bridge, element, caret) ? adt$6.retry(Carets.translate(lowerCaret, JUMP_SIZE, 0)) : adt$6.none(); + } + }; + var adjustUp = function (bridge, element, guessBox, original, caret) { + var higherCaret = Carets.moveUp(caret, JUMP_SIZE); + if (Math.abs(guessBox.top() - original.top()) < 1) { + return adt$6.retry(higherCaret); + } else if (guessBox.bottom() < caret.top()) { + return adt$6.retry(higherCaret); + } else if (guessBox.bottom() === caret.top()) { + return adt$6.retry(Carets.moveUp(caret, 1)); + } else { + return inOutsideBlock(bridge, element, caret) ? adt$6.retry(Carets.translate(higherCaret, JUMP_SIZE, 0)) : adt$6.none(); + } + }; + var upMovement = { + point: Carets.getTop, + adjuster: adjustUp, + move: Carets.moveUp, + gather: before$4 + }; + var downMovement = { + point: Carets.getBottom, + adjuster: adjustDown, + move: Carets.moveDown, + gather: after$5 + }; + var isAtTable = function (bridge, x, y) { + return bridge.elementFromPoint(x, y).filter(function (elm) { + return name(elm) === 'table'; + }).isSome(); + }; + var adjustForTable = function (bridge, movement, original, caret, numRetries) { + return adjustTil(bridge, movement, original, movement.move(caret, JUMP_SIZE), numRetries); + }; + var adjustTil = function (bridge, movement, original, caret, numRetries) { + if (numRetries === 0) { + return Option.some(caret); + } + if (isAtTable(bridge, caret.left(), movement.point(caret))) { + return adjustForTable(bridge, movement, original, caret, numRetries - 1); + } + return bridge.situsFromPoint(caret.left(), movement.point(caret)).bind(function (guess) { + return guess.start().fold(Option.none, function (element) { + return Rectangles.getEntireBox(bridge, element).bind(function (guessBox) { + return movement.adjuster(bridge, element, guessBox, original, caret).fold(Option.none, function (newCaret) { + return adjustTil(bridge, movement, original, newCaret, numRetries - 1); + }); + }).orThunk(function () { + return Option.some(caret); + }); + }, Option.none); + }); + }; + var ieTryDown = function (bridge, caret) { + return bridge.situsFromPoint(caret.left(), caret.bottom() + JUMP_SIZE); + }; + var ieTryUp = function (bridge, caret) { + return bridge.situsFromPoint(caret.left(), caret.top() - JUMP_SIZE); + }; + var checkScroll = function (movement, adjusted, bridge) { + if (movement.point(adjusted) > bridge.getInnerHeight()) { + return Option.some(movement.point(adjusted) - bridge.getInnerHeight()); + } else if (movement.point(adjusted) < 0) { + return Option.some(-movement.point(adjusted)); + } else { + return Option.none(); + } + }; + var retry = function (movement, bridge, caret) { + var moved = movement.move(caret, JUMP_SIZE); + var adjusted = adjustTil(bridge, movement, caret, moved, NUM_RETRIES).getOr(moved); + return checkScroll(movement, adjusted, bridge).fold(function () { + return bridge.situsFromPoint(adjusted.left(), movement.point(adjusted)); + }, function (delta) { + bridge.scrollBy(0, delta); + return bridge.situsFromPoint(adjusted.left(), movement.point(adjusted) - delta); + }); + }; + var Retries = { + tryUp: curry(retry, upMovement), + tryDown: curry(retry, downMovement), + ieTryUp: ieTryUp, + ieTryDown: ieTryDown, + getJumpSize: constant(JUMP_SIZE) + }; + + var MAX_RETRIES = 20; + var platform$1 = PlatformDetection$1.detect(); + var findSpot = function (bridge, isRoot, direction) { + return bridge.getSelection().bind(function (sel) { + return BrTags.tryBr(isRoot, sel.finish(), sel.foffset(), direction).fold(function () { + return Option.some(point(sel.finish(), sel.foffset())); + }, function (brNeighbour) { + var range = bridge.fromSitus(brNeighbour); + var analysis = BeforeAfter.verify(bridge, sel.finish(), sel.foffset(), range.finish(), range.foffset(), direction.failure, isRoot); + return BrTags.process(analysis); + }); + }); + }; + var scan = function (bridge, isRoot, element, offset, direction, numRetries) { + if (numRetries === 0) { + return Option.none(); + } + return tryCursor(bridge, isRoot, element, offset, direction).bind(function (situs) { + var range = bridge.fromSitus(situs); + var analysis = BeforeAfter.verify(bridge, element, offset, range.finish(), range.foffset(), direction.failure, isRoot); + return BeforeAfter.cata(analysis, function () { + return Option.none(); + }, function () { + return Option.some(situs); + }, function (cell) { + if (eq(element, cell) && offset === 0) { + return tryAgain(bridge, element, offset, Carets.moveUp, direction); + } else { + return scan(bridge, isRoot, cell, 0, direction, numRetries - 1); + } + }, function (cell) { + if (eq(element, cell) && offset === getEnd(cell)) { + return tryAgain(bridge, element, offset, Carets.moveDown, direction); + } else { + return scan(bridge, isRoot, cell, getEnd(cell), direction, numRetries - 1); + } + }); + }); + }; + var tryAgain = function (bridge, element, offset, move, direction) { + return Rectangles.getBoxAt(bridge, element, offset).bind(function (box) { + return tryAt(bridge, direction, move(box, Retries.getJumpSize())); + }); + }; + var tryAt = function (bridge, direction, box) { + if (platform$1.browser.isChrome() || platform$1.browser.isSafari() || platform$1.browser.isFirefox() || platform$1.browser.isEdge()) { + return direction.otherRetry(bridge, box); + } else if (platform$1.browser.isIE()) { + return direction.ieRetry(bridge, box); + } else { + return Option.none(); + } + }; + var tryCursor = function (bridge, isRoot, element, offset, direction) { + return Rectangles.getBoxAt(bridge, element, offset).bind(function (box) { + return tryAt(bridge, direction, box); + }); + }; + var handle$2 = function (bridge, isRoot, direction) { + return findSpot(bridge, isRoot, direction).bind(function (spot) { + return scan(bridge, isRoot, spot.element(), spot.offset(), direction, MAX_RETRIES).map(bridge.fromSitus); + }); + }; + var TableKeys = { handle: handle$2 }; + + var detection = PlatformDetection$1.detect(); + var inSameTable = function (elem, table) { + return ancestor$2(elem, function (e) { + return parent(e).exists(function (p) { + return eq(p, table); + }); + }); + }; + var simulate = function (bridge, isRoot, direction, initial, anchor) { + return closest$1(initial, 'td,th', isRoot).bind(function (start) { + return closest$1(start, 'table', isRoot).bind(function (table) { + if (!inSameTable(anchor, table)) { + return Option.none(); + } + return TableKeys.handle(bridge, isRoot, direction).bind(function (range) { + return closest$1(range.finish(), 'td,th', isRoot).map(function (finish) { + return { + start: constant(start), + finish: constant(finish), + range: constant(range) + }; + }); + }); + }); + }); + }; + var navigate = function (bridge, isRoot, direction, initial, anchor, precheck) { + if (detection.browser.isIE()) { + return Option.none(); + } else { + return precheck(initial, isRoot).orThunk(function () { + return simulate(bridge, isRoot, direction, initial, anchor).map(function (info) { + var range = info.range(); + return Response.create(Option.some(Util.makeSitus(range.start(), range.soffset(), range.finish(), range.foffset())), true); + }); + }); + } + }; + var firstUpCheck = function (initial, isRoot) { + return closest$1(initial, 'tr', isRoot).bind(function (startRow) { + return closest$1(startRow, 'table', isRoot).bind(function (table) { + var rows = descendants$1(table, 'tr'); + if (eq(startRow, rows[0])) { + return seekLeft$1(table, function (element) { + return last$1(element).isSome(); + }, isRoot).map(function (last) { + var lastOffset = getEnd(last); + return Response.create(Option.some(Util.makeSitus(last, lastOffset, last, lastOffset)), true); + }); + } else { + return Option.none(); + } + }); + }); + }; + var lastDownCheck = function (initial, isRoot) { + return closest$1(initial, 'tr', isRoot).bind(function (startRow) { + return closest$1(startRow, 'table', isRoot).bind(function (table) { + var rows = descendants$1(table, 'tr'); + if (eq(startRow, rows[rows.length - 1])) { + return seekRight$1(table, function (element) { + return first(element).isSome(); + }, isRoot).map(function (first) { + return Response.create(Option.some(Util.makeSitus(first, 0, first, 0)), true); + }); + } else { + return Option.none(); + } + }); + }); + }; + var select = function (bridge, container, isRoot, direction, initial, anchor, selectRange) { + return simulate(bridge, isRoot, direction, initial, anchor).bind(function (info) { + return KeySelection.detect(container, isRoot, info.start(), info.finish(), selectRange); + }); + }; + var VerticalMovement = { + navigate: navigate, + select: select, + firstUpCheck: firstUpCheck, + lastDownCheck: lastDownCheck + }; + + var findCell = function (target, isRoot) { + return closest$1(target, 'td,th', isRoot); + }; + function MouseSelection (bridge, container, isRoot, annotations) { + var cursor = Option.none(); + var clearState = function () { + cursor = Option.none(); + }; + var mousedown = function (event) { + annotations.clear(container); + cursor = findCell(event.target(), isRoot); + }; + var mouseover = function (event) { + cursor.each(function (start) { + annotations.clear(container); + findCell(event.target(), isRoot).each(function (finish) { + CellSelection.identify(start, finish, isRoot).each(function (cellSel) { + var boxes = cellSel.boxes().getOr([]); + if (boxes.length > 1 || boxes.length === 1 && !eq(start, finish)) { + annotations.selectRange(container, boxes, cellSel.start(), cellSel.finish()); + bridge.selectContents(finish); + } + }); + }); + }); + }; + var mouseup = function (_event) { + cursor.each(clearState); + }; + return { + mousedown: mousedown, + mouseover: mouseover, + mouseup: mouseup + }; + } + + var down = { + traverse: nextSibling, + gather: after$5, + relative: Situ.before, + otherRetry: Retries.tryDown, + ieRetry: Retries.ieTryDown, + failure: BeforeAfter.failedDown + }; + var up = { + traverse: prevSibling, + gather: before$4, + relative: Situ.before, + otherRetry: Retries.tryUp, + ieRetry: Retries.ieTryUp, + failure: BeforeAfter.failedUp + }; + var KeyDirection = { + down: down, + up: up + }; + + var isKey = function (key) { + return function (keycode) { + return keycode === key; + }; + }; + var isUp = isKey(38); + var isDown = isKey(40); + var isNavigation = function (keycode) { + return keycode >= 37 && keycode <= 40; + }; + var SelectionKeys = { + ltr: { + isBackward: isKey(37), + isForward: isKey(39) + }, + rtl: { + isBackward: isKey(39), + isForward: isKey(37) + }, + isUp: isUp, + isDown: isDown, + isNavigation: isNavigation + }; + + var toRaw = function (sr) { + return { + left: sr.left(), + top: sr.top(), + right: sr.right(), + bottom: sr.bottom(), + width: sr.width(), + height: sr.height() + }; + }; + var Rect = { toRaw: toRaw }; + + var isSafari = PlatformDetection$1.detect().browser.isSafari(); + var get$a = function (_DOC) { + var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document; + var x = doc.body.scrollLeft || doc.documentElement.scrollLeft; + var y = doc.body.scrollTop || doc.documentElement.scrollTop; + return Position(x, y); + }; + var by = function (x, y, _DOC) { + var doc = _DOC !== undefined ? _DOC.dom() : domGlobals.document; + var win = doc.defaultView; + win.scrollBy(x, y); + }; + + var WindowBridge = function (win) { + var elementFromPoint = function (x, y) { + return Element.fromPoint(Element.fromDom(win.document), x, y); + }; + var getRect = function (element) { + return element.dom().getBoundingClientRect(); + }; + var getRangedRect = function (start, soffset, finish, foffset) { + var sel = Selection.exact(start, soffset, finish, foffset); + return getFirstRect$1(win, sel).map(Rect.toRaw); + }; + var getSelection = function () { + return get$9(win).map(function (exactAdt) { + return Util.convertToRange(win, exactAdt); + }); + }; + var fromSitus = function (situs) { + var relative = Selection.relative(situs.start(), situs.finish()); + return Util.convertToRange(win, relative); + }; + var situsFromPoint = function (x, y) { + return getAtPoint(win, x, y).map(function (exact) { + return Situs.create(exact.start(), exact.soffset(), exact.finish(), exact.foffset()); + }); + }; + var clearSelection = function () { + clear(win); + }; + var selectContents = function (element) { + setToElement(win, element); + }; + var setSelection = function (sel) { + setExact(win, sel.start(), sel.soffset(), sel.finish(), sel.foffset()); + }; + var setRelativeSelection = function (start, finish) { + setRelative(win, start, finish); + }; + var getInnerHeight = function () { + return win.innerHeight; + }; + var getScrollY = function () { + var pos = get$a(Element.fromDom(win.document)); + return pos.top(); + }; + var scrollBy = function (x, y) { + by(x, y, Element.fromDom(win.document)); + }; + return { + elementFromPoint: elementFromPoint, + getRect: getRect, + getRangedRect: getRangedRect, + getSelection: getSelection, + fromSitus: fromSitus, + situsFromPoint: situsFromPoint, + clearSelection: clearSelection, + setSelection: setSelection, + setRelativeSelection: setRelativeSelection, + selectContents: selectContents, + getInnerHeight: getInnerHeight, + getScrollY: getScrollY, + scrollBy: scrollBy + }; + }; + + var rc = Immutable('rows', 'cols'); + var mouse = function (win, container, isRoot, annotations) { + var bridge = WindowBridge(win); + var handlers = MouseSelection(bridge, container, isRoot, annotations); + return { + mousedown: handlers.mousedown, + mouseover: handlers.mouseover, + mouseup: handlers.mouseup + }; + }; + var keyboard = function (win, container, isRoot, annotations) { + var bridge = WindowBridge(win); + var clearToNavigate = function () { + annotations.clear(container); + return Option.none(); + }; + var keydown = function (event, start, soffset, finish, foffset, direction) { + var realEvent = event.raw(); + var keycode = realEvent.which; + var shiftKey = realEvent.shiftKey === true; + var handler = CellSelection.retrieve(container, annotations.selectedSelector()).fold(function () { + if (SelectionKeys.isDown(keycode) && shiftKey) { + return curry(VerticalMovement.select, bridge, container, isRoot, KeyDirection.down, finish, start, annotations.selectRange); + } else if (SelectionKeys.isUp(keycode) && shiftKey) { + return curry(VerticalMovement.select, bridge, container, isRoot, KeyDirection.up, finish, start, annotations.selectRange); + } else if (SelectionKeys.isDown(keycode)) { + return curry(VerticalMovement.navigate, bridge, isRoot, KeyDirection.down, finish, start, VerticalMovement.lastDownCheck); + } else if (SelectionKeys.isUp(keycode)) { + return curry(VerticalMovement.navigate, bridge, isRoot, KeyDirection.up, finish, start, VerticalMovement.firstUpCheck); + } else { + return Option.none; + } + }, function (selected) { + var update = function (attempts) { + return function () { + var navigation = findMap(attempts, function (delta) { + return KeySelection.update(delta.rows(), delta.cols(), container, selected, annotations); + }); + return navigation.fold(function () { + return CellSelection.getEdges(container, annotations.firstSelectedSelector(), annotations.lastSelectedSelector()).map(function (edges) { + var relative = SelectionKeys.isDown(keycode) || direction.isForward(keycode) ? Situ.after : Situ.before; + bridge.setRelativeSelection(Situ.on(edges.first(), 0), relative(edges.table())); + annotations.clear(container); + return Response.create(Option.none(), true); + }); + }, function (_) { + return Option.some(Response.create(Option.none(), true)); + }); + }; + }; + if (SelectionKeys.isDown(keycode) && shiftKey) { + return update([rc(+1, 0)]); + } else if (SelectionKeys.isUp(keycode) && shiftKey) { + return update([rc(-1, 0)]); + } else if (direction.isBackward(keycode) && shiftKey) { + return update([ + rc(0, -1), + rc(-1, 0) + ]); + } else if (direction.isForward(keycode) && shiftKey) { + return update([ + rc(0, +1), + rc(+1, 0) + ]); + } else if (SelectionKeys.isNavigation(keycode) && shiftKey === false) { + return clearToNavigate; + } else { + return Option.none; + } + }); + return handler(); + }; + var keyup = function (event, start, soffset, finish, foffset) { + return CellSelection.retrieve(container, annotations.selectedSelector()).fold(function () { + var realEvent = event.raw(); + var keycode = realEvent.which; + var shiftKey = realEvent.shiftKey === true; + if (shiftKey === false) { + return Option.none(); + } + if (SelectionKeys.isNavigation(keycode)) { + return KeySelection.sync(container, isRoot, start, soffset, finish, foffset, annotations.selectRange); + } else { + return Option.none(); + } + }, Option.none); + }; + return { + keydown: keydown, + keyup: keyup + }; + }; + var InputHandlers = { + mouse: mouse, + keyboard: keyboard + }; + + var remove$7 = function (element, classes) { + each(classes, function (x) { + remove$5(element, x); + }); + }; + + var addClass = function (clazz) { + return function (element) { + add$2(element, clazz); + }; + }; + var removeClasses = function (classes) { + return function (element) { + remove$7(element, classes); + }; + }; + + var byClass = function (ephemera) { + var addSelectionClass = addClass(ephemera.selected()); + var removeSelectionClasses = removeClasses([ + ephemera.selected(), + ephemera.lastSelected(), + ephemera.firstSelected() + ]); + var clear = function (container) { + var sels = descendants$1(container, ephemera.selectedSelector()); + each(sels, removeSelectionClasses); + }; + var selectRange = function (container, cells, start, finish) { + clear(container); + each(cells, addSelectionClass); + add$2(start, ephemera.firstSelected()); + add$2(finish, ephemera.lastSelected()); + }; + return { + clear: clear, + selectRange: selectRange, + selectedSelector: ephemera.selectedSelector, + firstSelectedSelector: ephemera.firstSelectedSelector, + lastSelectedSelector: ephemera.lastSelectedSelector + }; + }; + var byAttr = function (ephemera) { + var removeSelectionAttributes = function (element) { + remove(element, ephemera.selected()); + remove(element, ephemera.firstSelected()); + remove(element, ephemera.lastSelected()); + }; + var addSelectionAttribute = function (element) { + set(element, ephemera.selected(), '1'); + }; + var clear = function (container) { + var sels = descendants$1(container, ephemera.selectedSelector()); + each(sels, removeSelectionAttributes); + }; + var selectRange = function (container, cells, start, finish) { + clear(container); + each(cells, addSelectionAttribute); + set(start, ephemera.firstSelected(), '1'); + set(finish, ephemera.lastSelected(), '1'); + }; + return { + clear: clear, + selectRange: selectRange, + selectedSelector: ephemera.selectedSelector, + firstSelectedSelector: ephemera.firstSelectedSelector, + lastSelectedSelector: ephemera.lastSelectedSelector + }; + }; + var SelectionAnnotation = { + byClass: byClass, + byAttr: byAttr + }; + + var hasInternalTarget = function (e) { + return has$1(Element.fromDom(e.target), 'ephox-snooker-resizer-bar') === false; + }; + function CellSelection$1 (editor, lazyResize) { + var handlerStruct = MixedBag([ + 'mousedown', + 'mouseover', + 'mouseup', + 'keyup', + 'keydown' + ], []); + var handlers = Option.none(); + var annotations = SelectionAnnotation.byAttr(Ephemera); + editor.on('init', function (e) { + var win = editor.getWin(); + var body = getBody$1(editor); + var isRoot = getIsRoot(editor); + var syncSelection = function () { + var sel = editor.selection; + var start = Element.fromDom(sel.getStart()); + var end = Element.fromDom(sel.getEnd()); + var shared = DomParent.sharedOne(TableLookup.table, [ + start, + end + ]); + shared.fold(function () { + annotations.clear(body); + }, noop); + }; + var mouseHandlers = InputHandlers.mouse(win, body, isRoot, annotations); + var keyHandlers = InputHandlers.keyboard(win, body, isRoot, annotations); + var hasShiftKey = function (event) { + return event.raw().shiftKey === true; + }; + var handleResponse = function (event, response) { + if (!hasShiftKey(event)) { + return; + } + if (response.kill()) { + event.kill(); + } + response.selection().each(function (ns) { + var relative = Selection.relative(ns.start(), ns.finish()); + var rng = asLtrRange(win, relative); + editor.selection.setRng(rng); + }); + }; + var keyup = function (event) { + var wrappedEvent = wrapEvent(event); + if (wrappedEvent.raw().shiftKey && SelectionKeys.isNavigation(wrappedEvent.raw().which)) { + var rng = editor.selection.getRng(); + var start = Element.fromDom(rng.startContainer); + var end = Element.fromDom(rng.endContainer); + keyHandlers.keyup(wrappedEvent, start, rng.startOffset, end, rng.endOffset).each(function (response) { + handleResponse(wrappedEvent, response); + }); + } + }; + var keydown = function (event) { + var wrappedEvent = wrapEvent(event); + lazyResize().each(function (resize) { + resize.hideBars(); + }); + var rng = editor.selection.getRng(); + var startContainer = Element.fromDom(editor.selection.getStart()); + var start = Element.fromDom(rng.startContainer); + var end = Element.fromDom(rng.endContainer); + var direction = Direction.directionAt(startContainer).isRtl() ? SelectionKeys.rtl : SelectionKeys.ltr; + keyHandlers.keydown(wrappedEvent, start, rng.startOffset, end, rng.endOffset, direction).each(function (response) { + handleResponse(wrappedEvent, response); + }); + lazyResize().each(function (resize) { + resize.showBars(); + }); + }; + var isMouseEvent = function (event) { + return event.hasOwnProperty('x') && event.hasOwnProperty('y'); + }; + var wrapEvent = function (event) { + var target = Element.fromDom(event.target); + var stop = function () { + event.stopPropagation(); + }; + var prevent = function () { + event.preventDefault(); + }; + var kill = compose(prevent, stop); + return { + target: constant(target), + x: constant(isMouseEvent(event) ? event.x : null), + y: constant(isMouseEvent(event) ? event.y : null), + stop: stop, + prevent: prevent, + kill: kill, + raw: constant(event) + }; + }; + var isLeftMouse = function (raw) { + return raw.button === 0; + }; + var isLeftButtonPressed = function (raw) { + if (raw.buttons === undefined) { + return true; + } + if (global$2.ie && global$2.ie >= 12 && raw.buttons === 0) { + return true; + } + return (raw.buttons & 1) !== 0; + }; + var mouseDown = function (e) { + if (isLeftMouse(e) && hasInternalTarget(e)) { + mouseHandlers.mousedown(wrapEvent(e)); + } + }; + var mouseOver = function (e) { + if (isLeftButtonPressed(e) && hasInternalTarget(e)) { + mouseHandlers.mouseover(wrapEvent(e)); + } + }; + var mouseUp = function (e) { + if (isLeftMouse(e) && hasInternalTarget(e)) { + mouseHandlers.mouseup(wrapEvent(e)); + } + }; + editor.on('mousedown', mouseDown); + editor.on('mouseover', mouseOver); + editor.on('mouseup', mouseUp); + editor.on('keyup', keyup); + editor.on('keydown', keydown); + editor.on('nodechange', syncSelection); + handlers = Option.some(handlerStruct({ + mousedown: mouseDown, + mouseover: mouseOver, + mouseup: mouseUp, + keyup: keyup, + keydown: keydown + })); + }); + var destroy = function () { + handlers.each(function (handlers) { + }); + }; + return { + clear: annotations.clear, + destroy: destroy + }; + } + + var Selections = function (editor) { + var get = function () { + var body = getBody$1(editor); + return TableSelection.retrieve(body, Ephemera.selectedSelector()).fold(function () { + if (editor.selection.getStart() === undefined) { + return SelectionTypes.none(); + } else { + return SelectionTypes.single(editor.selection); + } + }, function (cells) { + return SelectionTypes.multiple(cells); + }); + }; + return { get: get }; + }; + + var each$4 = global$1.each; + var addButtons = function (editor) { + var menuItems = []; + each$4('inserttable tableprops deletetable | cell row column'.split(' '), function (name) { + if (name === '|') { + menuItems.push({ text: '-' }); + } else { + menuItems.push(editor.menuItems[name]); + } + }); + editor.addButton('table', { + type: 'menubutton', + title: 'Table', + menu: menuItems + }); + function cmd(command) { + return function () { + editor.execCommand(command); + }; + } + editor.addButton('tableprops', { + title: 'Table properties', + onclick: cmd('mceTableProps'), + icon: 'table' + }); + editor.addButton('tabledelete', { + title: 'Delete table', + onclick: cmd('mceTableDelete') + }); + editor.addButton('tablecellprops', { + title: 'Cell properties', + onclick: cmd('mceTableCellProps') + }); + editor.addButton('tablemergecells', { + title: 'Merge cells', + onclick: cmd('mceTableMergeCells') + }); + editor.addButton('tablesplitcells', { + title: 'Split cell', + onclick: cmd('mceTableSplitCells') + }); + editor.addButton('tableinsertrowbefore', { + title: 'Insert row before', + onclick: cmd('mceTableInsertRowBefore') + }); + editor.addButton('tableinsertrowafter', { + title: 'Insert row after', + onclick: cmd('mceTableInsertRowAfter') + }); + editor.addButton('tabledeleterow', { + title: 'Delete row', + onclick: cmd('mceTableDeleteRow') + }); + editor.addButton('tablerowprops', { + title: 'Row properties', + onclick: cmd('mceTableRowProps') + }); + editor.addButton('tablecutrow', { + title: 'Cut row', + onclick: cmd('mceTableCutRow') + }); + editor.addButton('tablecopyrow', { + title: 'Copy row', + onclick: cmd('mceTableCopyRow') + }); + editor.addButton('tablepasterowbefore', { + title: 'Paste row before', + onclick: cmd('mceTablePasteRowBefore') + }); + editor.addButton('tablepasterowafter', { + title: 'Paste row after', + onclick: cmd('mceTablePasteRowAfter') + }); + editor.addButton('tableinsertcolbefore', { + title: 'Insert column before', + onclick: cmd('mceTableInsertColBefore') + }); + editor.addButton('tableinsertcolafter', { + title: 'Insert column after', + onclick: cmd('mceTableInsertColAfter') + }); + editor.addButton('tabledeletecol', { + title: 'Delete column', + onclick: cmd('mceTableDeleteCol') + }); + }; + var addToolbars = function (editor) { + var isTable = function (table) { + var selectorMatched = editor.dom.is(table, 'table') && editor.getBody().contains(table); + return selectorMatched; + }; + var toolbar = getToolbar(editor); + if (toolbar.length > 0) { + editor.addContextToolbar(isTable, toolbar.join(' ')); + } + }; + var Buttons = { + addButtons: addButtons, + addToolbars: addToolbars + }; + + var addMenuItems = function (editor, selections) { + var targets = Option.none(); + var tableCtrls = []; + var cellCtrls = []; + var mergeCtrls = []; + var unmergeCtrls = []; + var noTargetDisable = function (ctrl) { + ctrl.disabled(true); + }; + var ctrlEnable = function (ctrl) { + ctrl.disabled(false); + }; + var pushTable = function () { + var self = this; + tableCtrls.push(self); + targets.fold(function () { + noTargetDisable(self); + }, function (targets) { + ctrlEnable(self); + }); + }; + var pushCell = function () { + var self = this; + cellCtrls.push(self); + targets.fold(function () { + noTargetDisable(self); + }, function (targets) { + ctrlEnable(self); + }); + }; + var pushMerge = function () { + var self = this; + mergeCtrls.push(self); + targets.fold(function () { + noTargetDisable(self); + }, function (targets) { + self.disabled(targets.mergable().isNone()); + }); + }; + var pushUnmerge = function () { + var self = this; + unmergeCtrls.push(self); + targets.fold(function () { + noTargetDisable(self); + }, function (targets) { + self.disabled(targets.unmergable().isNone()); + }); + }; + var setDisabledCtrls = function () { + targets.fold(function () { + each(tableCtrls, noTargetDisable); + each(cellCtrls, noTargetDisable); + each(mergeCtrls, noTargetDisable); + each(unmergeCtrls, noTargetDisable); + }, function (targets) { + each(tableCtrls, ctrlEnable); + each(cellCtrls, ctrlEnable); + each(mergeCtrls, function (mergeCtrl) { + mergeCtrl.disabled(targets.mergable().isNone()); + }); + each(unmergeCtrls, function (unmergeCtrl) { + unmergeCtrl.disabled(targets.unmergable().isNone()); + }); + }); + }; + editor.on('init', function () { + editor.on('nodechange', function (e) { + var cellOpt = Option.from(editor.dom.getParent(editor.selection.getStart(), 'th,td')); + targets = cellOpt.bind(function (cellDom) { + var cell = Element.fromDom(cellDom); + var table = TableLookup.table(cell); + return table.map(function (table) { + return TableTargets.forMenu(selections, table, cell); + }); + }); + setDisabledCtrls(); + }); + }); + var generateTableGrid = function () { + var html = ''; + html = ''; + for (var y = 0; y < 10; y++) { + html += ''; + for (var x = 0; x < 10; x++) { + html += ''; + } + html += ''; + } + html += '
            '; + html += '

            '; + return html; + }; + var selectGrid = function (editor, tx, ty, control) { + var table = control.getEl().getElementsByTagName('table')[0]; + var x, y, focusCell, cell, active; + var rtl = control.isRtl() || control.parent().rel === 'tl-tr'; + table.nextSibling.innerHTML = tx + 1 + ' x ' + (ty + 1); + if (rtl) { + tx = 9 - tx; + } + for (y = 0; y < 10; y++) { + for (x = 0; x < 10; x++) { + cell = table.rows[y].childNodes[x].firstChild; + active = (rtl ? x >= tx : x <= tx) && y <= ty; + editor.dom.toggleClass(cell, 'mce-active', active); + if (active) { + focusCell = cell; + } + } + } + return focusCell.parentNode; + }; + var insertTable = hasTableGrid(editor) === false ? { + text: 'Table', + icon: 'table', + context: 'table', + onclick: cmd('mceInsertTable') + } : { + text: 'Table', + icon: 'table', + context: 'table', + ariaHideMenu: true, + onclick: function (e) { + if (e.aria) { + this.parent().hideAll(); + e.stopImmediatePropagation(); + editor.execCommand('mceInsertTable'); + } + }, + onshow: function () { + selectGrid(editor, 0, 0, this.menu.items()[0]); + }, + onhide: function () { + var elements = this.menu.items()[0].getEl().getElementsByTagName('a'); + editor.dom.removeClass(elements, 'mce-active'); + editor.dom.addClass(elements[0], 'mce-active'); + }, + menu: [{ + type: 'container', + html: generateTableGrid(), + onPostRender: function () { + this.lastX = this.lastY = 0; + }, + onmousemove: function (e) { + var target = e.target; + var x, y; + if (target.tagName.toUpperCase() === 'A') { + x = parseInt(target.getAttribute('data-mce-x'), 10); + y = parseInt(target.getAttribute('data-mce-y'), 10); + if (this.isRtl() || this.parent().rel === 'tl-tr') { + x = 9 - x; + } + if (x !== this.lastX || y !== this.lastY) { + selectGrid(editor, x, y, e.control); + this.lastX = x; + this.lastY = y; + } + } + }, + onclick: function (e) { + var self = this; + if (e.target.tagName.toUpperCase() === 'A') { + e.preventDefault(); + e.stopPropagation(); + self.parent().cancel(); + editor.undoManager.transact(function () { + InsertTable.insert(editor, self.lastX + 1, self.lastY + 1); + }); + editor.addVisual(); + } + } + }] + }; + function cmd(command) { + return function () { + editor.execCommand(command); + }; + } + var tableProperties = { + text: 'Table properties', + context: 'table', + onPostRender: pushTable, + onclick: cmd('mceTableProps') + }; + var deleteTable = { + text: 'Delete table', + context: 'table', + onPostRender: pushTable, + cmd: 'mceTableDelete' + }; + var row = { + text: 'Row', + context: 'table', + menu: [ + { + text: 'Insert row before', + onclick: cmd('mceTableInsertRowBefore'), + onPostRender: pushCell + }, + { + text: 'Insert row after', + onclick: cmd('mceTableInsertRowAfter'), + onPostRender: pushCell + }, + { + text: 'Delete row', + onclick: cmd('mceTableDeleteRow'), + onPostRender: pushCell + }, + { + text: 'Row properties', + onclick: cmd('mceTableRowProps'), + onPostRender: pushCell + }, + { text: '-' }, + { + text: 'Cut row', + onclick: cmd('mceTableCutRow'), + onPostRender: pushCell + }, + { + text: 'Copy row', + onclick: cmd('mceTableCopyRow'), + onPostRender: pushCell + }, + { + text: 'Paste row before', + onclick: cmd('mceTablePasteRowBefore'), + onPostRender: pushCell + }, + { + text: 'Paste row after', + onclick: cmd('mceTablePasteRowAfter'), + onPostRender: pushCell + } + ] + }; + var column = { + text: 'Column', + context: 'table', + menu: [ + { + text: 'Insert column before', + onclick: cmd('mceTableInsertColBefore'), + onPostRender: pushCell + }, + { + text: 'Insert column after', + onclick: cmd('mceTableInsertColAfter'), + onPostRender: pushCell + }, + { + text: 'Delete column', + onclick: cmd('mceTableDeleteCol'), + onPostRender: pushCell + } + ] + }; + var cell = { + separator: 'before', + text: 'Cell', + context: 'table', + menu: [ + { + text: 'Cell properties', + onclick: cmd('mceTableCellProps'), + onPostRender: pushCell + }, + { + text: 'Merge cells', + onclick: cmd('mceTableMergeCells'), + onPostRender: pushMerge + }, + { + text: 'Split cell', + onclick: cmd('mceTableSplitCells'), + onPostRender: pushUnmerge + } + ] + }; + editor.addMenuItem('inserttable', insertTable); + editor.addMenuItem('tableprops', tableProperties); + editor.addMenuItem('deletetable', deleteTable); + editor.addMenuItem('row', row); + editor.addMenuItem('column', column); + editor.addMenuItem('cell', cell); + }; + var MenuItems = { addMenuItems: addMenuItems }; + + var getClipboardRows = function (clipboardRows) { + return clipboardRows.get().fold(function () { + return; + }, function (rows) { + return map(rows, function (row) { + return row.dom(); + }); + }); + }; + var setClipboardRows = function (rows, clipboardRows) { + var sugarRows = map(rows, Element.fromDom); + clipboardRows.set(Option.from(sugarRows)); + }; + var getApi = function (editor, clipboardRows) { + return { + insertTable: function (columns, rows) { + return InsertTable.insert(editor, columns, rows); + }, + setClipboardRows: function (rows) { + return setClipboardRows(rows, clipboardRows); + }, + getClipboardRows: function () { + return getClipboardRows(clipboardRows); + } + }; + }; + + function Plugin(editor) { + var resizeHandler = ResizeHandler(editor); + var cellSelection = CellSelection$1(editor, resizeHandler.lazyResize); + var actions = TableActions(editor, resizeHandler.lazyWire); + var selections = Selections(editor); + var clipboardRows = Cell(Option.none()); + Commands.registerCommands(editor, actions, cellSelection, selections, clipboardRows); + Clipboard.registerEvents(editor, selections, actions, cellSelection); + MenuItems.addMenuItems(editor, selections); + Buttons.addButtons(editor); + Buttons.addToolbars(editor); + editor.on('PreInit', function () { + editor.serializer.addTempAttr(Ephemera.firstSelected()); + editor.serializer.addTempAttr(Ephemera.lastSelected()); + }); + if (hasTabNavigation(editor)) { + editor.on('keydown', function (e) { + TabContext.handle(e, editor, actions, resizeHandler.lazyWire); + }); + } + editor.on('remove', function () { + resizeHandler.destroy(); + cellSelection.destroy(); + }); + return getApi(editor, clipboardRows); + } + global.add('table', Plugin); + function Plugin$1 () { + } + + return Plugin$1; + +}(window)); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/table/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/table/plugin.min.js new file mode 100644 index 0000000..80d078b --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/table/plugin.min.js @@ -0,0 +1 @@ +!function(m){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),y=function(){},x=function(n,r){return function(){for(var e=[],t=0;tn.maxRow()||sn.maxCol()||(mn.getAt(t,l,s).filter(r).isNone()?(o=f,i=e[l].element(),u=xe.fromTag("td"),Rt(u,xe.fromTag("br")),(o?Rt:Ct)(i,u)):f=!0)}(m,g,h,d),o=e,f=h,s=A(tn.firstLayer(o,"tr"),function(e){return 0===e.dom().childElementCount}),k(s,Nt),f.minCol()!==f.maxCol()&&f.minRow()!==f.maxRow()||k(tn.firstLayer(o,"th,td"),function(e){he(e,"rowspan"),he(e,"colspan")}),he(o,"width"),he(o,"height"),Ae(o,"width"),Ae(o,"height"),e},pn=(Gt=le,Yt="text",{get:function(e){if(!Gt(e))throw new Error("Can only get "+Yt+" value of a "+Yt+" node");return Xt(e).getOr("")},getOption:Xt=function(e){return Gt(e)?R.from(e.dom().nodeValue):R.none()},set:function(e,t){if(!Gt(e))throw new Error("Can only set raw "+Yt+" value of a "+Yt+" node");e.dom().nodeValue=t}}),vn=function(e){return pn.get(e)},bn=function(e){return pn.getOption(e)},wn=function(e,t){pn.set(e,t)},yn=function(e){return"img"===oe(e)?1:bn(e).fold(function(){return bt(e).length},function(e){return e.length})},xn=["img","br"],Cn=function(e){return bn(e).filter(function(e){return 0!==e.trim().length||-1=e.startCol()&&t.column()+t.colspan()-1<=e.finishCol()&&t.row()>=e.startRow()&&t.row()+t.rowspan()-1<=e.finishRow()},_n=function(e,t){var n=t.column(),r=t.column()+t.colspan()-1,o=t.row(),i=t.row()+t.rowspan()-1;return n<=e.finishCol()&&r>=e.startCol()&&o<=e.finishRow()&&i>=e.startRow()},Ln=function(e,t){for(var n=!0,r=b(Mn,t),o=t.startRow();o<=t.finishRow();o++)for(var i=t.startCol();i<=t.finishCol();i++)n=n&&mn.getAt(e,o,i).exists(r);return n?R.some(t):R.none()},Fn=function(e,t,n){var r=mn.findItem(e,t,ft),o=mn.findItem(e,n,ft);return r.bind(function(r){return o.map(function(e){return t=r,n=e,jt(Math.min(t.row(),n.row()),Math.min(t.column(),n.column()),Math.max(t.row()+t.rowspan()-1,n.row()+n.rowspan()-1),Math.max(t.column()+t.colspan()-1,n.column()+n.colspan()-1));var t,n})})},jn=Fn,zn=function(t,e,n){return Fn(t,e,n).bind(function(e){return Ln(t,e)})},Hn=function(r,e,o,i){return mn.findItem(r,e,ft).bind(function(e){var t=0=t.length-1)return R.none();var e=t[n].fold(function(){var e=F(t.slice(0,n));return xo(e,function(e,t){return e.map(function(e){return{value:e,delta:t+1}})})},function(e){return R.some({value:e,delta:0})}),r=t[n+1].fold(function(){var e=t.slice(n+1);return xo(e,function(e,t){return e.map(function(e){return{value:e,delta:t+1}})})},function(e){return R.some({value:e,delta:1})});return e.bind(function(n){return r.map(function(e){var t=e.delta+n.delta;return Math.abs(e.value-n.value)/t})})},Bo=function(e,t,n){var r=e();return B(r,t).orThunk(function(){return R.from(r[0]).orThunk(n)}).map(function(e){return e.element()})},Wo=function(n){var e=n.grid(),t=Po(0,e.columns()),r=Po(0,e.rows());return E(t,function(t){return Bo(function(){return _(r,function(e){return mn.getAt(n,e,t).filter(function(e){return e.column()===t}).fold(C([]),function(e){return[e]})})},function(e){return 1===e.colspan()},function(){return mn.getAt(n,0,t)})})},Mo=function(n){var e=n.grid(),t=Po(0,e.rows()),r=Po(0,e.columns());return E(t,function(t){return Bo(function(){return _(r,function(e){return mn.getAt(n,t,e).filter(function(e){return e.row()===t}).fold(C([]),function(e){return[e]})})},function(e){return 1===e.rowspan()},function(){return mn.getAt(n,t,0)})})},_o=function(e){var t=e.replace(/\./g,"-");return{resolve:function(e){return t+"-"+e}}},Lo={resolve:_o("ephox-snooker").resolve},Fo=function(e,t,n,r,o){var i=xe.fromTag("div");return Oe(i,{position:"absolute",left:t-r/2+"px",top:n+"px",height:o+"px",width:r+"px"}),de(i,{"data-column":e,role:"presentation"}),i},jo=function(e,t,n,r,o){var i=xe.fromTag("div");return Oe(i,{position:"absolute",left:t+"px",top:n-o/2+"px",height:o+"px",width:r+"px"}),de(i,{"data-row":e,role:"presentation"}),i},zo=Lo.resolve("resizer-bar"),Ho=Lo.resolve("resizer-rows"),Uo=Lo.resolve("resizer-cols"),qo=function(e){var t=qt(e.parent(),"."+zo);k(t,Nt)},Vo=function(n,e,r){var o=n.origin();k(e,function(e,t){e.each(function(e){var t=r(o,e);Eo(t,zo),Rt(n.parent(),t)})})},Go=function(e,t,n,r,o,i){var u,a,c,l,f=no(t),s=0=t.length||e.column()>ni.cellLength(t[0]))return pi.error("invalid start address out of table bounds, row: "+e.row()+", column: "+e.column());var r=t.slice(e.row()),o=r[0].cells().slice(e.column()),i=ni.cellLength(n[0]),u=n.length;return pi.value({rowDelta:C(r.length-u),colDelta:C(o.length-i)})},xi=function(e,t){var n=ni.cellLength(e[0]),r=ni.cellLength(t[0]);return{rowDelta:C(0),colDelta:C(n-r)}},Ci=function(e,t,n){var r=t.colDelta()<0?wi:o;return(t.rowDelta()<0?bi:o)(r(e,Math.abs(t.colDelta()),n),Math.abs(t.rowDelta()),n)},Ri=function(e,t,n,r){if(0===e.length)return e;for(var o=t.startRow();o<=t.finishRow();o++)for(var i=t.startCol();i<=t.finishCol();i++)ni.mutateCell(e[o],i,Mt(r(),!1));return e},Si=function(e,t,n,r){for(var o=!0,i=0;i',t.insertBefore(r,t.firstChild)),ga(e,t),o.align&&da(e,t,o.align),e.focus(),e.addVisual()})},Pa=function(t,e){var n,r,o,i,u,a,c,l,f,s,d=t.dom,m={};!0===e?(n=d.getParent(t.selection.getStart(),"table"))&&(c=n,l=(a=t).dom,f={width:l.getStyle(c,"width")||l.getAttrib(c,"width"),height:l.getStyle(c,"height")||l.getAttrib(c,"height"),cellspacing:l.getStyle(c,"border-spacing")||l.getAttrib(c,"cellspacing"),cellpadding:l.getAttrib(c,"data-mce-cell-padding")||l.getAttrib(c,"cellpadding")||pa(a.dom,c,"padding"),border:l.getAttrib(c,"data-mce-border")||l.getAttrib(c,"border")||pa(a.dom,c,"border"),borderColor:l.getAttrib(c,"data-mce-border-color"),caption:!!l.select("caption",c)[0],"class":l.getAttrib(c,"class")},sa.each("left center right".split(" "),function(e){a.formatter.matchNode(c,"align"+e)&&(f.align=e)}),Zu(a)&&sa.extend(f,wa.extractAdvancedStyles(l,c)),m=f):(r={label:"Cols",name:"cols"},o={label:"Rows",name:"rows"}),0=e.left&&t<=e.right&&n>=e.top&&n<=e.bottom},Nc=function(n,r,e,t,o){var i=function(e){var t=n.dom().createRange();return t.setStart(r.dom(),e),t.collapse(!0),t},u=vn(r).length,a=function(e,t,n,r,o){if(0===o)return 0;if(t===r)return o-1;for(var i=r,u=1;ur.left&&o.left ("+e.right()+", "+e.bottom()+")"}},Ml=function(e){return Wl.nu({left:e.left,top:e.top,right:e.right,bottom:e.bottom})},_l=function(e,t){return R.some(e.getRect(t))},Ll=function(e,t,n){return ce(t)?_l(e,t).map(Ml):le(t)?(r=e,o=t,i=n,0<=i&&in.right();var t,n})});var n,o,i},Hl={point:Wl.getTop,adjuster:function(e,t,n,r,o){var i=Wl.moveUp(o,5);return Math.abs(n.top()-r.top())<1?jl.retry(i):n.bottom()o.bottom()?jl.retry(i):n.top()===o.bottom()?jl.retry(Wl.moveDown(o,1)):zl(e,t,o)?jl.retry(Wl.translate(i,5,0)):jl.none()},move:Wl.moveDown,gather:Cl},ql=function(n,r,o,i,u){return 0===u?R.some(i):(c=n,l=i.left(),f=r.point(i),c.elementFromPoint(l,f).filter(function(e){return"table"===oe(e)}).isSome()?(t=i,a=u-1,ql(n,e=r,o,e.move(t,5),a)):n.situsFromPoint(i.left(),r.point(i)).bind(function(e){return e.start().fold(R.none,function(t){return Fl(n,t).bind(function(e){return r.adjuster(n,t,e,o,i).fold(R.none,function(e){return ql(n,r,o,e,u-1)})}).orThunk(function(){return R.some(i)})},R.none)}));var e,t,a,c,l,f},Vl=function(t,n,e){var r,o,i,u=t.move(e,5),a=ql(n,t,e,u,100).getOr(u);return(r=t,o=a,i=n,r.point(o)>i.getInnerHeight()?R.some(r.point(o)-i.getInnerHeight()):r.point(o)<0?R.some(-r.point(o)):R.none()).fold(function(){return n.situsFromPoint(a.left(),t.point(a))},function(e){return n.scrollBy(0,e),n.situsFromPoint(a.left(),t.point(a)-e)})},Gl={tryUp:b(Vl,Hl),tryDown:b(Vl,Ul),ieTryUp:function(e,t){return e.situsFromPoint(t.left(),t.top()-5)},ieTryDown:function(e,t){return e.situsFromPoint(t.left(),t.bottom()+5)},getJumpSize:C(5)},Yl=it.detect(),Xl=function(r,o,i,u,a,c){return 0===c?R.none():$l(r,o,i,u,a).bind(function(e){var t=r.fromSitus(e),n=Dl.verify(r,i,u,t.finish(),t.foffset(),a.failure,o);return Dl.cata(n,function(){return R.none()},function(){return R.some(e)},function(e){return ft(i,e)&&0===u?Kl(r,i,u,Wl.moveUp,a):Xl(r,o,e,0,a,c-1)},function(e){return ft(i,e)&&u===yn(e)?Kl(r,i,u,Wl.moveDown,a):Xl(r,o,e,yn(e),a,c-1)})})},Kl=function(t,e,n,r,o){return Ll(t,e,n).bind(function(e){return Jl(t,o,r(e,Gl.getJumpSize()))})},Jl=function(e,t,n){return Yl.browser.isChrome()||Yl.browser.isSafari()||Yl.browser.isFirefox()||Yl.browser.isEdge()?t.otherRetry(e,n):Yl.browser.isIE()?t.ieRetry(e,n):R.none()},$l=function(t,e,n,r,o){return Ll(t,n,r).bind(function(e){return Jl(t,o,e)})},Ql=function(t,n,r){return(o=t,i=n,u=r,o.getSelection().bind(function(r){return Pl(i,r.finish(),r.foffset(),u).fold(function(){return R.some(Rl(r.finish(),r.foffset()))},function(e){var t=o.fromSitus(e),n=Dl.verify(o,r.finish(),r.foffset(),t.finish(),t.foffset(),u.failure,i);return Il(n)})})).bind(function(e){return Xl(t,n,e.element(),e.offset(),r,20).map(t.fromSitus)});var o,i,u},Zl=it.detect(),ef=function(e,t){return Kt(e,function(e){return gt(e).exists(function(e){return ft(e,t)})},n).isSome();var n},tf=function(t,r,o,e,i){return Zt(e,"td,th",r).bind(function(n){return Zt(n,"table",r).bind(function(e){return ef(i,e)?Ql(t,r,o).bind(function(t){return Zt(t.finish(),"td,th",r).map(function(e){return{start:C(n),finish:C(e),range:C(t)}})}):R.none()})})},nf=function(e,t,n,r,o,i){return Zl.browser.isIE()?R.none():i(r,t).orThunk(function(){return tf(e,t,n,r,o).map(function(e){var t=e.range();return rl.create(R.some(il.makeSitus(t.start(),t.soffset(),t.finish(),t.foffset())),!0)})})},rf=function(e,t,n,r,o,i,u){return tf(e,n,r,o,i).bind(function(e){return al.detect(t,n,e.start(),e.finish(),u)})},of=function(e,u){return Zt(e,"tr",u).bind(function(i){return Zt(i,"table",u).bind(function(e){var t,n,r,o=qt(e,"tr");return ft(i,o[0])?(t=e,n=function(e){return Sn(e).isSome()},r=u,bl(yl,t,n,r)).map(function(e){var t=yn(e);return rl.create(R.some(il.makeSitus(e,t,e,t)),!0)}):R.none()})})},uf=function(e,u){return Zt(e,"tr",u).bind(function(i){return Zt(i,"table",u).bind(function(e){var t,n,r,o=qt(e,"tr");return ft(i,o[o.length-1])?(t=e,n=function(e){return Rn(e).isSome()},r=u,wl(yl,t,n,r)).map(function(e){return rl.create(R.some(il.makeSitus(e,0,e,0)),!0)}):R.none()})})},af=function(e,t){return Zt(e,"td,th",t)},cf={down:{traverse:vt,gather:Cl,relative:pc.before,otherRetry:Gl.tryDown,ieRetry:Gl.ieTryDown,failure:Dl.failedDown},up:{traverse:pt,gather:xl,relative:pc.before,otherRetry:Gl.tryUp,ieRetry:Gl.ieTryUp,failure:Dl.failedUp}},lf=function(t){return function(e){return e===t}},ff=lf(38),sf=lf(40),df={ltr:{isBackward:lf(37),isForward:lf(39)},rtl:{isBackward:lf(39),isForward:lf(37)},isUp:ff,isDown:sf,isNavigation:function(e){return 37<=e&&e<=40}},mf=function(e){return{left:e.left(),top:e.top(),right:e.right(),bottom:e.bottom(),width:e.width(),height:e.height()}},gf=(it.detect().browser.isSafari(),function(a){return{elementFromPoint:function(e,t){return xe.fromPoint(xe.fromDom(a.document),e,t)},getRect:function(e){return e.dom().getBoundingClientRect()},getRangedRect:function(e,t,n,r){var o=bc.exact(e,t,n,r);return Yc(a,o).map(mf)},getSelection:function(){return Gc(a).map(function(e){return il.convertToRange(a,e)})},fromSitus:function(e){var t=bc.relative(e.start(),e.finish());return il.convertToRange(a,t)},situsFromPoint:function(e,t){return Xc(a,e,t).map(function(e){return ol(e.start(),e.soffset(),e.finish(),e.foffset())})},clearSelection:function(){a.getSelection().removeAllRanges()},setSelection:function(e){var t,n,r,o,i,u;t=a,n=e.start(),r=e.soffset(),o=e.finish(),i=e.foffset(),u=Lc(n,r,o,i),Hc(t,u)},setRelativeSelection:function(e,t){var n,r;n=a,r=_c(e,t),Hc(n,r)},selectContents:function(e){Vc(a,e)},getInnerHeight:function(){return a.innerHeight},getScrollY:function(){var e,t,n,r;return(e=xe.fromDom(a.document),t=e!==undefined?e.dom():m.document,n=t.body.scrollLeft||t.documentElement.scrollLeft,r=t.body.scrollTop||t.documentElement.scrollTop,eo(n,r)).top()},scrollBy:function(e,t){var n,r,o;n=e,r=t,((o=xe.fromDom(a.document))!==undefined?o.dom():m.document).defaultView.scrollBy(n,r)}}}),hf=q("rows","cols"),pf={mouse:function(e,t,n,r){var o,i,u,a,c,l,f=gf(e),s=(o=f,i=t,u=n,a=r,c=R.none(),l=function(){c=R.none()},{mousedown:function(e){a.clear(i),c=af(e.target(),u)},mouseover:function(e){c.each(function(r){a.clear(i),af(e.target(),u).each(function(n){sr(r,n,u).each(function(e){var t=e.boxes().getOr([]);(1";for(var n=0;n<10;n++)e+='';e+=""}return e+="",e+=''}(),onPostRender:function(){this.lastX=this.lastY=0},onmousemove:function(e){var t,n,r=e.target;"A"===r.tagName.toUpperCase()&&(t=parseInt(r.getAttribute("data-mce-x"),10),n=parseInt(r.getAttribute("data-mce-y"),10),(this.isRtl()||"tl-tr"===this.parent().rel)&&(t=9-t),t===this.lastX&&n===this.lastY||(s(o,t,n,e.control),this.lastX=t,this.lastY=n))},onclick:function(e){var t=this;"A"===e.target.tagName.toUpperCase()&&(e.preventDefault(),e.stopPropagation(),t.parent().cancel(),o.undoManager.transact(function(){Na(o,t.lastX+1,t.lastY+1)}),o.addVisual())}}]};function m(e){return function(){o.execCommand(e)}}var g={text:"Table properties",context:"table",onPostRender:e,onclick:m("mceTableProps")},h={text:"Delete table",context:"table",onPostRender:e,cmd:"mceTableDelete"},p={text:"Row",context:"table",menu:[{text:"Insert row before",onclick:m("mceTableInsertRowBefore"),onPostRender:t},{text:"Insert row after",onclick:m("mceTableInsertRowAfter"),onPostRender:t},{text:"Delete row",onclick:m("mceTableDeleteRow"),onPostRender:t},{text:"Row properties",onclick:m("mceTableRowProps"),onPostRender:t},{text:"-"},{text:"Cut row",onclick:m("mceTableCutRow"),onPostRender:t},{text:"Copy row",onclick:m("mceTableCopyRow"),onPostRender:t},{text:"Paste row before",onclick:m("mceTablePasteRowBefore"),onPostRender:t},{text:"Paste row after",onclick:m("mceTablePasteRowAfter"),onPostRender:t}]},v={text:"Column",context:"table",menu:[{text:"Insert column before",onclick:m("mceTableInsertColBefore"),onPostRender:t},{text:"Insert column after",onclick:m("mceTableInsertColAfter"),onPostRender:t},{text:"Delete column",onclick:m("mceTableDeleteCol"),onPostRender:t}]},b={separator:"before",text:"Cell",context:"table",menu:[{text:"Cell properties",onclick:m("mceTableCellProps"),onPostRender:t},{text:"Merge cells",onclick:m("mceTableMergeCells"),onPostRender:function(){var t=this;a.push(t),r.fold(function(){l(t)},function(e){t.disabled(e.mergable().isNone())})}},{text:"Split cell",onclick:m("mceTableSplitCells"),onPostRender:function(){var t=this;c.push(t),r.fold(function(){l(t)},function(e){t.disabled(e.unmergable().isNone())})}}]};o.addMenuItem("inserttable",d),o.addMenuItem("tableprops",g),o.addMenuItem("deletetable",h),o.addMenuItem("row",p),o.addMenuItem("column",v),o.addMenuItem("cell",b)},Tf=function(n,r){return{insertTable:function(e,t){return Na(n,e,t)},setClipboardRows:function(e){return t=r,n=E(e,xe.fromDom),void t.set(R.from(n));var t,n},getClipboardRows:function(){return r.get().fold(function(){},function(e){return E(e,function(e){return e.dom()})})}}};e.add("table",function(t){var n,r=cc(t),e=yf(t,r.lazyResize),o=la(t,r.lazyWire),i=(n=t,{get:function(){var e=Fu(n);return hr(e,yr.selectedSelector()).fold(function(){return n.selection.getStart()===undefined?Rr.none():Rr.single(n.selection)},function(e){return Rr.multiple(e)})}}),u=lu(R.none());return Ba(t,o,e,i,u),Ar(t,i,o,e),Sf(t,i),Cf(t),Rf(t),t.on("PreInit",function(){t.serializer.addTempAttr(yr.firstSelected()),t.serializer.addTempAttr(yr.lastSelected())}),t.getParam("table_tab_navigation",!0,"boolean")&&t.on("keydown",function(e){nl(e,t,o,r.lazyWire)}),t.on("remove",function(){r.destroy(),e.destroy()}),Tf(t,u)})}(window); \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/css/visualblocks.css b/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/css/visualblocks.css new file mode 100644 index 0000000..96e4d7c --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/css/visualblocks.css @@ -0,0 +1,154 @@ +.mce-visualblocks p { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7); + background-repeat: no-repeat; +} + +.mce-visualblocks h1 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks h2 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks h3 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7); + background-repeat: no-repeat; +} + +.mce-visualblocks h4 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks h5 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks h6 { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks div:not([data-mce-bogus]) { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7); + background-repeat: no-repeat; +} + +.mce-visualblocks section { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=); + background-repeat: no-repeat; +} + +.mce-visualblocks article { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7); + background-repeat: no-repeat; +} + +.mce-visualblocks blockquote { + padding-top: 10px; + border: 1px dashed #BBB; + background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7); + background-repeat: no-repeat; +} + +.mce-visualblocks address { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=); + background-repeat: no-repeat; +} + +.mce-visualblocks pre { + padding-top: 10px; + border: 1px dashed #BBB; + margin-left: 3px; + background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks figure { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7); + background-repeat: no-repeat; +} + +.mce-visualblocks hgroup { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7); + background-repeat: no-repeat; +} + +.mce-visualblocks aside { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=); + background-repeat: no-repeat; +} + +.mce-visualblocks figcaption { + border: 1px dashed #BBB; +} + +.mce-visualblocks ul { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks ol { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==); + background-repeat: no-repeat; +} + +.mce-visualblocks dl { + padding-top: 10px; + border: 1px dashed #BBB; + margin: 0 0 1em 3px; + background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==); + background-repeat: no-repeat; +} diff --git a/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/plugin.js b/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/plugin.js new file mode 100644 index 0000000..267fb07 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/plugin.js @@ -0,0 +1,135 @@ +(function () { +var visualblocks = (function () { + 'use strict'; + + var Cell = function (initial) { + var value = initial; + var get = function () { + return value; + }; + var set = function (v) { + value = v; + }; + var clone = function () { + return Cell(get()); + }; + return { + get: get, + set: set, + clone: clone + }; + }; + + var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); + + var fireVisualBlocks = function (editor, state) { + editor.fire('VisualBlocks', { state: state }); + }; + var Events = { fireVisualBlocks: fireVisualBlocks }; + + var isEnabledByDefault = function (editor) { + return editor.getParam('visualblocks_default_state', false); + }; + var getContentCss = function (editor) { + return editor.settings.visualblocks_content_css; + }; + var Settings = { + isEnabledByDefault: isEnabledByDefault, + getContentCss: getContentCss + }; + + var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); + + var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools'); + + var cssId = global$1.DOM.uniqueId(); + var load = function (doc, url) { + var linkElements = global$2.toArray(doc.getElementsByTagName('link')); + var matchingLinkElms = global$2.grep(linkElements, function (head) { + return head.id === cssId; + }); + if (matchingLinkElms.length === 0) { + var linkElm = global$1.DOM.create('link', { + id: cssId, + rel: 'stylesheet', + href: url + }); + doc.getElementsByTagName('head')[0].appendChild(linkElm); + } + }; + var LoadCss = { load: load }; + + var toggleVisualBlocks = function (editor, pluginUrl, enabledState) { + var dom = editor.dom; + var contentCss = Settings.getContentCss(editor); + LoadCss.load(editor.getDoc(), contentCss ? contentCss : pluginUrl + '/css/visualblocks.css'); + dom.toggleClass(editor.getBody(), 'mce-visualblocks'); + enabledState.set(!enabledState.get()); + Events.fireVisualBlocks(editor, enabledState.get()); + }; + var VisualBlocks = { toggleVisualBlocks: toggleVisualBlocks }; + + var register = function (editor, pluginUrl, enabledState) { + editor.addCommand('mceVisualBlocks', function () { + VisualBlocks.toggleVisualBlocks(editor, pluginUrl, enabledState); + }); + }; + var Commands = { register: register }; + + var setup = function (editor, pluginUrl, enabledState) { + editor.on('PreviewFormats AfterPreviewFormats', function (e) { + if (enabledState.get()) { + editor.dom.toggleClass(editor.getBody(), 'mce-visualblocks', e.type === 'afterpreviewformats'); + } + }); + editor.on('init', function () { + if (Settings.isEnabledByDefault(editor)) { + VisualBlocks.toggleVisualBlocks(editor, pluginUrl, enabledState); + } + }); + editor.on('remove', function () { + editor.dom.removeClass(editor.getBody(), 'mce-visualblocks'); + }); + }; + var Bindings = { setup: setup }; + + var toggleActiveState = function (editor, enabledState) { + return function (e) { + var ctrl = e.control; + ctrl.active(enabledState.get()); + editor.on('VisualBlocks', function (e) { + ctrl.active(e.state); + }); + }; + }; + var register$1 = function (editor, enabledState) { + editor.addButton('visualblocks', { + active: false, + title: 'Show blocks', + cmd: 'mceVisualBlocks', + onPostRender: toggleActiveState(editor, enabledState) + }); + editor.addMenuItem('visualblocks', { + text: 'Show blocks', + cmd: 'mceVisualBlocks', + onPostRender: toggleActiveState(editor, enabledState), + selectable: true, + context: 'view', + prependToContext: true + }); + }; + var Buttons = { register: register$1 }; + + global.add('visualblocks', function (editor, pluginUrl) { + var enabledState = Cell(false); + Commands.register(editor, pluginUrl, enabledState); + Buttons.register(editor, enabledState); + Bindings.setup(editor, pluginUrl, enabledState); + }); + function Plugin () { + } + + return Plugin; + +}()); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/plugin.min.js new file mode 100644 index 0000000..09bfaf2 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/visualblocks/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";var o=function(e){var t=e,n=function(){return t};return{get:n,set:function(e){t=e},clone:function(){return o(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(e,t){e.fire("VisualBlocks",{state:t})},s=function(e){return e.getParam("visualblocks_default_state",!1)},c=function(e){return e.settings.visualblocks_content_css},l=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),u=tinymce.util.Tools.resolve("tinymce.util.Tools"),a=l.DOM.uniqueId(),r=function(e,t){var n=u.toArray(e.getElementsByTagName("link"));if(0===u.grep(n,function(e){return e.id===a}).length){var o=l.DOM.create("link",{id:a,rel:"stylesheet",href:t});e.getElementsByTagName("head")[0].appendChild(o)}},m=function(e,t,n){var o=e.dom,s=c(e);r(e.getDoc(),s||t+"/css/visualblocks.css"),o.toggleClass(e.getBody(),"mce-visualblocks"),n.set(!n.get()),i(e,n.get())},f=function(e,t,n){e.addCommand("mceVisualBlocks",function(){m(e,t,n)})},d=function(t,e,n){t.on("PreviewFormats AfterPreviewFormats",function(e){n.get()&&t.dom.toggleClass(t.getBody(),"mce-visualblocks","afterpreviewformats"===e.type)}),t.on("init",function(){s(t)&&m(t,e,n)}),t.on("remove",function(){t.dom.removeClass(t.getBody(),"mce-visualblocks")})},n=function(n,o){return function(e){var t=e.control;t.active(o.get()),n.on("VisualBlocks",function(e){t.active(e.state)})}},v=function(e,t){e.addButton("visualblocks",{active:!1,title:"Show blocks",cmd:"mceVisualBlocks",onPostRender:n(e,t)}),e.addMenuItem("visualblocks",{text:"Show blocks",cmd:"mceVisualBlocks",onPostRender:n(e,t),selectable:!0,context:"view",prependToContext:!0})};e.add("visualblocks",function(e,t){var n=o(!1);f(e,t,n),v(e,n),d(e,t,n)})}(); \ No newline at end of file diff --git a/html/wp-content/plugins/tinymce-advanced/mce/visualchars/plugin.js b/html/wp-content/plugins/tinymce-advanced/mce/visualchars/plugin.js new file mode 100644 index 0000000..3609e23 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/visualchars/plugin.js @@ -0,0 +1,457 @@ +(function () { +var visualchars = (function (domGlobals) { + 'use strict'; + + var Cell = function (initial) { + var value = initial; + var get = function () { + return value; + }; + var set = function (v) { + value = v; + }; + var clone = function () { + return Cell(get()); + }; + return { + get: get, + set: set, + clone: clone + }; + }; + + var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); + + var get = function (toggleState) { + var isEnabled = function () { + return toggleState.get(); + }; + return { isEnabled: isEnabled }; + }; + var Api = { get: get }; + + var fireVisualChars = function (editor, state) { + return editor.fire('VisualChars', { state: state }); + }; + var Events = { fireVisualChars: fireVisualChars }; + + var noop = function () { + }; + var constant = function (value) { + return function () { + return value; + }; + }; + var never = constant(false); + var always = constant(true); + + var none = function () { + return NONE; + }; + var NONE = function () { + var eq = function (o) { + return o.isNone(); + }; + var call = function (thunk) { + return thunk(); + }; + var id = function (n) { + return n; + }; + var me = { + fold: function (n, s) { + return n(); + }, + is: never, + isSome: never, + isNone: always, + getOr: id, + getOrThunk: call, + getOrDie: function (msg) { + throw new Error(msg || 'error: getOrDie called on none.'); + }, + getOrNull: constant(null), + getOrUndefined: constant(undefined), + or: id, + orThunk: call, + map: none, + each: noop, + bind: none, + exists: never, + forall: always, + filter: none, + equals: eq, + equals_: eq, + toArray: function () { + return []; + }, + toString: constant('none()') + }; + if (Object.freeze) { + Object.freeze(me); + } + return me; + }(); + var some = function (a) { + var constant_a = constant(a); + var self = function () { + return me; + }; + var bind = function (f) { + return f(a); + }; + var me = { + fold: function (n, s) { + return s(a); + }, + is: function (v) { + return a === v; + }, + isSome: always, + isNone: never, + getOr: constant_a, + getOrThunk: constant_a, + getOrDie: constant_a, + getOrNull: constant_a, + getOrUndefined: constant_a, + or: self, + orThunk: self, + map: function (f) { + return some(f(a)); + }, + each: function (f) { + f(a); + }, + bind: bind, + exists: bind, + forall: bind, + filter: function (f) { + return f(a) ? me : NONE; + }, + toArray: function () { + return [a]; + }, + toString: function () { + return 'some(' + a + ')'; + }, + equals: function (o) { + return o.is(a); + }, + equals_: function (o, elementEq) { + return o.fold(never, function (b) { + return elementEq(a, b); + }); + } + }; + return me; + }; + var from = function (value) { + return value === null || value === undefined ? NONE : some(value); + }; + var Option = { + some: some, + none: none, + from: from + }; + + var typeOf = function (x) { + if (x === null) { + return 'null'; + } + var t = typeof x; + if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) { + return 'array'; + } + if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) { + return 'string'; + } + return t; + }; + var isType = function (type) { + return function (value) { + return typeOf(value) === type; + }; + }; + var isFunction = isType('function'); + + var nativeSlice = Array.prototype.slice; + var map = function (xs, f) { + var len = xs.length; + var r = new Array(len); + for (var i = 0; i < len; i++) { + var x = xs[i]; + r[i] = f(x, i); + } + return r; + }; + var each = function (xs, f) { + for (var i = 0, len = xs.length; i < len; i++) { + var x = xs[i]; + f(x, i); + } + }; + var from$1 = isFunction(Array.from) ? Array.from : function (x) { + return nativeSlice.call(x); + }; + + var fromHtml = function (html, scope) { + var doc = scope || domGlobals.document; + var div = doc.createElement('div'); + div.innerHTML = html; + if (!div.hasChildNodes() || div.childNodes.length > 1) { + domGlobals.console.error('HTML does not have a single root node', html); + throw new Error('HTML must have a single root node'); + } + return fromDom(div.childNodes[0]); + }; + var fromTag = function (tag, scope) { + var doc = scope || domGlobals.document; + var node = doc.createElement(tag); + return fromDom(node); + }; + var fromText = function (text, scope) { + var doc = scope || domGlobals.document; + var node = doc.createTextNode(text); + return fromDom(node); + }; + var fromDom = function (node) { + if (node === null || node === undefined) { + throw new Error('Node cannot be null or undefined'); + } + return { dom: constant(node) }; + }; + var fromPoint = function (docElm, x, y) { + var doc = docElm.dom(); + return Option.from(doc.elementFromPoint(x, y)).map(fromDom); + }; + var Element = { + fromHtml: fromHtml, + fromTag: fromTag, + fromText: fromText, + fromDom: fromDom, + fromPoint: fromPoint + }; + + var ATTRIBUTE = domGlobals.Node.ATTRIBUTE_NODE; + var CDATA_SECTION = domGlobals.Node.CDATA_SECTION_NODE; + var COMMENT = domGlobals.Node.COMMENT_NODE; + var DOCUMENT = domGlobals.Node.DOCUMENT_NODE; + var DOCUMENT_TYPE = domGlobals.Node.DOCUMENT_TYPE_NODE; + var DOCUMENT_FRAGMENT = domGlobals.Node.DOCUMENT_FRAGMENT_NODE; + var ELEMENT = domGlobals.Node.ELEMENT_NODE; + var TEXT = domGlobals.Node.TEXT_NODE; + var PROCESSING_INSTRUCTION = domGlobals.Node.PROCESSING_INSTRUCTION_NODE; + var ENTITY_REFERENCE = domGlobals.Node.ENTITY_REFERENCE_NODE; + var ENTITY = domGlobals.Node.ENTITY_NODE; + var NOTATION = domGlobals.Node.NOTATION_NODE; + + var Global = typeof domGlobals.window !== 'undefined' ? domGlobals.window : Function('return this;')(); + + var type = function (element) { + return element.dom().nodeType; + }; + var value = function (element) { + return element.dom().nodeValue; + }; + var isType$1 = function (t) { + return function (element) { + return type(element) === t; + }; + }; + var isText = isType$1(TEXT); + + var charMap = { + '\xA0': 'nbsp', + '\xAD': 'shy' + }; + var charMapToRegExp = function (charMap, global) { + var key, regExp = ''; + for (key in charMap) { + regExp += key; + } + return new RegExp('[' + regExp + ']', global ? 'g' : ''); + }; + var charMapToSelector = function (charMap) { + var key, selector = ''; + for (key in charMap) { + if (selector) { + selector += ','; + } + selector += 'span.mce-' + charMap[key]; + } + return selector; + }; + var Data = { + charMap: charMap, + regExp: charMapToRegExp(charMap), + regExpGlobal: charMapToRegExp(charMap, true), + selector: charMapToSelector(charMap), + charMapToRegExp: charMapToRegExp, + charMapToSelector: charMapToSelector + }; + + var wrapCharWithSpan = function (value) { + return '' + value + ''; + }; + var Html = { wrapCharWithSpan: wrapCharWithSpan }; + + var isMatch = function (n) { + var value$1 = value(n); + return isText(n) && value$1 !== undefined && Data.regExp.test(value$1); + }; + var filterDescendants = function (scope, predicate) { + var result = []; + var dom = scope.dom(); + var children = map(dom.childNodes, Element.fromDom); + each(children, function (x) { + if (predicate(x)) { + result = result.concat([x]); + } + result = result.concat(filterDescendants(x, predicate)); + }); + return result; + }; + var findParentElm = function (elm, rootElm) { + while (elm.parentNode) { + if (elm.parentNode === rootElm) { + return elm; + } + elm = elm.parentNode; + } + }; + var replaceWithSpans = function (text) { + return text.replace(Data.regExpGlobal, Html.wrapCharWithSpan); + }; + var Nodes = { + isMatch: isMatch, + filterDescendants: filterDescendants, + findParentElm: findParentElm, + replaceWithSpans: replaceWithSpans + }; + + var show = function (editor, rootElm) { + var node, div; + var nodeList = Nodes.filterDescendants(Element.fromDom(rootElm), Nodes.isMatch); + each(nodeList, function (n) { + var withSpans = Nodes.replaceWithSpans(editor.dom.encode(value(n))); + div = editor.dom.create('div', null, withSpans); + while (node = div.lastChild) { + editor.dom.insertAfter(node, n.dom()); + } + editor.dom.remove(n.dom()); + }); + }; + var hide = function (editor, body) { + var nodeList = editor.dom.select(Data.selector, body); + each(nodeList, function (node) { + editor.dom.remove(node, 1); + }); + }; + var toggle = function (editor) { + var body = editor.getBody(); + var bookmark = editor.selection.getBookmark(); + var parentNode = Nodes.findParentElm(editor.selection.getNode(), body); + parentNode = parentNode !== undefined ? parentNode : body; + hide(editor, parentNode); + show(editor, parentNode); + editor.selection.moveToBookmark(bookmark); + }; + var VisualChars = { + show: show, + hide: hide, + toggle: toggle + }; + + var toggleVisualChars = function (editor, toggleState) { + var body = editor.getBody(); + var selection = editor.selection; + var bookmark; + toggleState.set(!toggleState.get()); + Events.fireVisualChars(editor, toggleState.get()); + bookmark = selection.getBookmark(); + if (toggleState.get() === true) { + VisualChars.show(editor, body); + } else { + VisualChars.hide(editor, body); + } + selection.moveToBookmark(bookmark); + }; + var Actions = { toggleVisualChars: toggleVisualChars }; + + var register = function (editor, toggleState) { + editor.addCommand('mceVisualChars', function () { + Actions.toggleVisualChars(editor, toggleState); + }); + }; + var Commands = { register: register }; + + var global$1 = tinymce.util.Tools.resolve('tinymce.util.Delay'); + + var setup = function (editor, toggleState) { + var debouncedToggle = global$1.debounce(function () { + VisualChars.toggle(editor); + }, 300); + if (editor.settings.forced_root_block !== false) { + editor.on('keydown', function (e) { + if (toggleState.get() === true) { + e.keyCode === 13 ? VisualChars.toggle(editor) : debouncedToggle(); + } + }); + } + }; + var Keyboard = { setup: setup }; + + var isEnabledByDefault = function (editor) { + return editor.getParam('visualchars_default_state', false); + }; + var Settings = { isEnabledByDefault: isEnabledByDefault }; + + var setup$1 = function (editor, toggleState) { + editor.on('init', function () { + var valueForToggling = !Settings.isEnabledByDefault(editor); + toggleState.set(valueForToggling); + Actions.toggleVisualChars(editor, toggleState); + }); + }; + var Bindings = { setup: setup$1 }; + + var toggleActiveState = function (editor) { + return function (e) { + var ctrl = e.control; + editor.on('VisualChars', function (e) { + ctrl.active(e.state); + }); + }; + }; + var register$1 = function (editor) { + editor.addButton('visualchars', { + active: false, + title: 'Show invisible characters', + cmd: 'mceVisualChars', + onPostRender: toggleActiveState(editor) + }); + editor.addMenuItem('visualchars', { + text: 'Show invisible characters', + cmd: 'mceVisualChars', + onPostRender: toggleActiveState(editor), + selectable: true, + context: 'view', + prependToContext: true + }); + }; + + global.add('visualchars', function (editor) { + var toggleState = Cell(false); + Commands.register(editor, toggleState); + register$1(editor); + Keyboard.setup(editor, toggleState); + Bindings.setup(editor, toggleState); + return Api.get(toggleState); + }); + function Plugin () { + } + + return Plugin; + +}(window)); +})(); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/visualchars/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/visualchars/plugin.min.js new file mode 100644 index 0000000..0a19345 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/visualchars/plugin.min.js @@ -0,0 +1 @@ +!function(r){"use strict";var n,e,t,o,i,u,c=function(n){var e=n,t=function(){return e};return{get:t,set:function(n){e=n},clone:function(){return c(t())}}},a=tinymce.util.Tools.resolve("tinymce.PluginManager"),f=function(n){return{isEnabled:function(){return n.get()}}},d=function(n,e){return n.fire("VisualChars",{state:e})},s=function(){},l=function(n){return function(){return n}},m=l(!1),N=l(!0),g=function(){return E},E=(n=function(n){return n.isNone()},o={fold:function(n,e){return n()},is:m,isSome:m,isNone:N,getOr:t=function(n){return n},getOrThunk:e=function(n){return n()},getOrDie:function(n){throw new Error(n||"error: getOrDie called on none.")},getOrNull:l(null),getOrUndefined:l(undefined),or:t,orThunk:e,map:g,each:s,bind:g,exists:m,forall:N,filter:g,equals:n,equals_:n,toArray:function(){return[]},toString:l("none()")},Object.freeze&&Object.freeze(o),o),h=function(t){var n=l(t),e=function(){return o},r=function(n){return n(t)},o={fold:function(n,e){return e(t)},is:function(n){return t===n},isSome:N,isNone:m,getOr:n,getOrThunk:n,getOrDie:n,getOrNull:n,getOrUndefined:n,or:e,orThunk:e,map:function(n){return h(n(t))},each:function(n){n(t)},bind:r,exists:r,forall:r,filter:function(n){return n(t)?o:E},toArray:function(){return[t]},toString:function(){return"some("+t+")"},equals:function(n){return n.is(t)},equals_:function(n,e){return n.fold(m,function(n){return e(t,n)})}};return o},v=function(n){return null===n||n===undefined?E:h(n)},T=(i="function",function(n){return function(n){if(null===n)return"null";var e=typeof n;return"object"===e&&(Array.prototype.isPrototypeOf(n)||n.constructor&&"Array"===n.constructor.name)?"array":"object"===e&&(String.prototype.isPrototypeOf(n)||n.constructor&&"String"===n.constructor.name)?"string":e}(n)===i}),p=(Array.prototype.slice,function(n,e){for(var t=0,r=n.length;t'+n+""},A=function(n,e){var t=[],r=function(n,e){for(var t=n.length,r=new Array(t),o=0;o]*)?>', 'gi' ), '\n$&' ); + html = html.replace( new RegExp( '', 'gi' ), '$&\n' ); + html = html.replace( /(]*)?>)[\r\n\t]*/gi, '$1\n' ); + html = html.replace( />\n[\r\n\t]+\n<' ); + html = html.replace( /^
          • \u00a0<\/td>/g, ' ' ); + + return tinymce.trim( html ); + } + + editor.addCommand( 'Tadv_Mark', function() { + editor.formatter.toggle('mark'); + }); + + editor.addButton( 'tadv_mark', { + icon: 'backcolor', + tooltip: 'Mark', + cmd: 'Tadv_Mark', + stateSelector: 'mark' + }); + + editor.on( 'init', function() { + if ( noAutop ) { + editor.on( 'SaveContent', function( event ) { + event.content = event.content.replace( /caption\](\s|]*>|

             <\/p>)*\[caption/g, 'caption] [caption' ); + + event.content = event.content.replace( /<(object|audio|video)[\s\S]+?<\/\1>/g, function( match ) { + return match.replace( /[\r\n\t ]+/g, ' ' ); + }); + + event.content = event.content.replace( /]*)?>[\s\S]+?<\/pre>/g, function( match ) { + match = match.replace( /
            (\r\n|\n)?/g, '\n' ); + return match.replace( /<\/?p( [^>]*)?>(\r\n|\n)?/g, '\n' ); + }); + + event.content = addLineBreaks( event.content ); + }); + } + + try { + if ( editor.plugins.searchreplace && ! editor.controlManager.buttons.searchreplace ) { + editor.shortcuts.remove( 'meta+f' ); + } + } catch ( er ) {} + + editor.formatter.register({ + mark: { inline: 'mark' } + }); + }); + + editor.on( 'ObjectResizeStart', function( event ) { + var element = event.target; + var table = editor.$( element ); + var parentWidth; + var tableWidth; + var width; + + if ( table.is( 'table' ) ) { + if ( element.style.width && element.style.width.indexOf( '%' ) !== -1 ) { + return; + } + + parentWidth = parseInt( table.parent().css( 'width' ), 10 ); + tableWidth = parseInt( event.width, 10 ); + + if ( parentWidth && tableWidth ) { + if ( Math.abs( parentWidth - tableWidth ) < 3 ) { + table.css({ width: '100%' }); + } else { + width = Math.round( ( tableWidth / parentWidth ) * 100 ); + + if ( width > 10 && width < 200 ) { + table.css({ width: width + '%' }); + } + } + } + } + }, true ); + + editor.addMenuItem( 'tmaresettablesize', { + text: 'Reset table size', + cmd: 'tmaResetTableSize', + icon: 'dashicon dashicons-image-flip-horizontal', + context: 'format', + }); + + editor.addMenuItem( 'tmaremovetablestyles', { + text: 'Remove table styling', + cmd: 'tmaRemoveTableStyles', + icon: 'dashicon dashicons-editor-table', + context: 'format', + }); + + editor.addButton( 'tmaresettablesize', { + title: 'Reset table size', + cmd: 'tmaResetTableSize', + icon: 'dashicon dashicons-image-flip-horizontal', + } ); + + editor.addButton( 'tmaremovetablestyles', { + title: 'Remove table styling', + cmd: 'tmaRemoveTableStyles', + icon: 'dashicon dashicons-editor-table', + } ); + + editor.addCommand( 'tmaRemoveTableStyles', function() { + var node = editor.selection.getStart(); + var table = editor.dom.getParents( node, 'table' ); + var attr = { + style: null, + 'data-mce-style': null, + width: null, + height: null, + minWidth: null, + maxWidth: null, + minHeight: null, + maxHeight: null, + align: null, + valign: null, + axis: null, + 'char': null, + charoff: null, + bgcolor: null, + border: null, + cellspacing: null, + cellpadding: null + }; + + if ( table ) { + editor.$( table ).attr( attr ).find( 'tr, th, td, thead, tbody, tfoot' ).each( function( i, element ) { + editor.$( element ).attr( attr ); + } ); + } + } ); + + editor.addCommand( 'tmaResetTableSize', function() { + var node = editor.selection.getStart(); + var table = editor.dom.getParents( node, 'table' ); + + if ( table ) { + removeInlineSizes( null, table ); + + editor.$( table ).find( 'tr, th, td, thead, tbody, tfoot' ).each( removeInlineSizes ); + } + } ); + + function removeInlineSizes( i, node ) { + var element = editor.$( node ); + + element.attr( { + width: null, + height: null, + minWidth: null, + maxWidth: null, + minHeight: null, + maxHeight: null + } ); + + element.css({ width: null, height: null }); + + if ( element.is( 'table' ) ) { + element.css({ 'border-collapse': 'collapse', width: '100%;' }); + } + + if ( ! element.attr( 'style' ) ) { + element.attr({ style: null, 'data-mce-style': null }); + } else { + element.attr( 'data-mce-style', element.attr( 'style' ) ); + } + } + + if ( noAutop ) { + editor.on( 'beforeSetContent', function( event ) { + var autop; + var wp = window.wp; + + if ( ! wp ) { + return; + } + + autop = wp.editor && wp.editor.autop; + + if ( ! autop ) { + autop = wp.oldEditor && wp.oldEditor.autop; + } + + if ( event.load && autop && event.content && event.content.indexOf( '\n' ) > -1 && ! /

            /i.test( event.content ) ) { + event.content = autop( event.content ); + } + }, true ); + + if ( editor.settings.classic_block_editor ) { + editor.on( 'beforeGetContent', function( event ) { + if ( event.format === 'raw' ) { + return; + } + + var blocks = tinymce.$( '.block-editor-block-list__block' ); + + if ( blocks.length === 1 && blocks.attr( 'data-type' ) === 'core/freeform' ) { + // Mark all paragraph tags inside a single freeform block so they are not stripped by the block editor... + editor.$( 'p' ).each( function ( i, node ) { + if ( ! node.hasAttributes() ) { + editor.$( node ).attr( 'data-tadv-p', 'keep' ); + } + } ); + } else { + // Remove the above ugliness... + editor.$( 'p[data-tadv-p]' ).removeAttr( 'data-tadv-p' ); + } + }, true ); + } + } + + return { + addLineBreaks: addLineBreaks + }; + }); +}( window.tinymce )); diff --git a/html/wp-content/plugins/tinymce-advanced/mce/wptadv/plugin.min.js b/html/wp-content/plugins/tinymce-advanced/mce/wptadv/plugin.min.js new file mode 100644 index 0000000..46c876b --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/mce/wptadv/plugin.min.js @@ -0,0 +1,233 @@ +/** + * Additional functionality for TinyMCE. + * @package advanced-editor-tools + */ + +( function( tinymce ) { + tinymce.PluginManager.add( 'wptadv', function( editor ) { + var noAutop = ( ! editor.settings.wpautop && editor.settings.tadv_noautop ); + + function addLineBreaks( html ) { + var blocklist = 'table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre' + + '|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section' + + '|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary'; + + html = html.replace( new RegExp( '<(?:' + blocklist + ')(?: [^>]*)?>', 'gi' ), '\n$&' ); + html = html.replace( new RegExp( '', 'gi' ), '$&\n' ); + html = html.replace( /(]*)?>)[\r\n\t]*/gi, '$1\n' ); + html = html.replace( />\n[\r\n\t]+\n<' ); + html = html.replace( /^

          • \u00a0<\/td>/g, ' ' ); + + return tinymce.trim( html ); + } + + editor.addCommand( 'Tadv_Mark', function() { + editor.formatter.toggle('mark'); + }); + + editor.addButton( 'tadv_mark', { + icon: 'backcolor', + tooltip: 'Mark', + cmd: 'Tadv_Mark', + stateSelector: 'mark' + }); + + editor.on( 'init', function() { + if ( noAutop ) { + editor.on( 'SaveContent', function( event ) { + event.content = event.content.replace( /caption\](\s|]*>|

             <\/p>)*\[caption/g, 'caption] [caption' ); + + event.content = event.content.replace( /<(object|audio|video)[\s\S]+?<\/\1>/g, function( match ) { + return match.replace( /[\r\n\t ]+/g, ' ' ); + }); + + event.content = event.content.replace( /]*)?>[\s\S]+?<\/pre>/g, function( match ) { + match = match.replace( /
            (\r\n|\n)?/g, '\n' ); + return match.replace( /<\/?p( [^>]*)?>(\r\n|\n)?/g, '\n' ); + }); + + event.content = addLineBreaks( event.content ); + }); + } + + try { + if ( editor.plugins.searchreplace && ! editor.controlManager.buttons.searchreplace ) { + editor.shortcuts.remove( 'meta+f' ); + } + } catch ( er ) {} + + editor.formatter.register({ + mark: { inline: 'mark' } + }); + }); + + editor.on( 'ObjectResizeStart', function( event ) { + var element = event.target; + var table = editor.$( element ); + var parentWidth; + var tableWidth; + var width; + + if ( table.is( 'table' ) ) { + if ( element.style.width && element.style.width.indexOf( '%' ) !== -1 ) { + return; + } + + parentWidth = parseInt( table.parent().css( 'width' ), 10 ); + tableWidth = parseInt( event.width, 10 ); + + if ( parentWidth && tableWidth ) { + if ( Math.abs( parentWidth - tableWidth ) < 3 ) { + table.css({ width: '100%' }); + } else { + width = Math.round( ( tableWidth / parentWidth ) * 100 ); + + if ( width > 10 && width < 200 ) { + table.css({ width: width + '%' }); + } + } + } + } + }, true ); + + editor.addMenuItem( 'tmaresettablesize', { + text: 'Reset table size', + cmd: 'tmaResetTableSize', + icon: 'dashicon dashicons-image-flip-horizontal', + context: 'format', + }); + + editor.addMenuItem( 'tmaremovetablestyles', { + text: 'Remove table styling', + cmd: 'tmaRemoveTableStyles', + icon: 'dashicon dashicons-editor-table', + context: 'format', + }); + + editor.addButton( 'tmaresettablesize', { + title: 'Reset table size', + cmd: 'tmaResetTableSize', + icon: 'dashicon dashicons-image-flip-horizontal', + } ); + + editor.addButton( 'tmaremovetablestyles', { + title: 'Remove table styling', + cmd: 'tmaRemoveTableStyles', + icon: 'dashicon dashicons-editor-table', + } ); + + editor.addCommand( 'tmaRemoveTableStyles', function() { + var node = editor.selection.getStart(); + var table = editor.dom.getParents( node, 'table' ); + var attr = { + style: null, + 'data-mce-style': null, + width: null, + height: null, + minWidth: null, + maxWidth: null, + minHeight: null, + maxHeight: null, + align: null, + valign: null, + axis: null, + 'char': null, + charoff: null, + bgcolor: null, + border: null, + cellspacing: null, + cellpadding: null + }; + + if ( table ) { + editor.$( table ).attr( attr ).find( 'tr, th, td, thead, tbody, tfoot' ).each( function( i, element ) { + editor.$( element ).attr( attr ); + } ); + } + } ); + + editor.addCommand( 'tmaResetTableSize', function() { + var node = editor.selection.getStart(); + var table = editor.dom.getParents( node, 'table' ); + + if ( table ) { + removeInlineSizes( null, table ); + + editor.$( table ).find( 'tr, th, td, thead, tbody, tfoot' ).each( removeInlineSizes ); + } + } ); + + function removeInlineSizes( i, node ) { + var element = editor.$( node ); + + element.attr( { + width: null, + height: null, + minWidth: null, + maxWidth: null, + minHeight: null, + maxHeight: null + } ); + + element.css({ width: null, height: null }); + + if ( element.is( 'table' ) ) { + element.css({ 'border-collapse': 'collapse', width: '100%;' }); + } + + if ( ! element.attr( 'style' ) ) { + element.attr({ style: null, 'data-mce-style': null }); + } else { + element.attr( 'data-mce-style', element.attr( 'style' ) ); + } + } + + if ( noAutop ) { + editor.on( 'beforeSetContent', function( event ) { + var autop; + var wp = window.wp; + + if ( ! wp ) { + return; + } + + autop = wp.editor && wp.editor.autop; + + if ( ! autop ) { + autop = wp.oldEditor && wp.oldEditor.autop; + } + + if ( event.load && autop && event.content && event.content.indexOf( '\n' ) > -1 && ! /

            /i.test( event.content ) ) { + event.content = autop( event.content ); + } + }, true ); + + if ( editor.settings.classic_block_editor ) { + editor.on( 'beforeGetContent', function( event ) { + if ( event.format === 'raw' ) { + return; + } + + var blocks = tinymce.$( '.block-editor-block-list__block' ); + + if ( blocks.length === 1 && blocks.attr( 'data-type' ) === 'core/freeform' ) { + // Mark all paragraph tags inside a single freeform block so they are not stripped by the block editor... + editor.$( 'p' ).each( function ( i, node ) { + if ( ! node.hasAttributes() ) { + editor.$( node ).attr( 'data-tadv-p', 'keep' ); + } + } ); + } else { + // Remove the above ugliness... + editor.$( 'p[data-tadv-p]' ).removeAttr( 'data-tadv-p' ); + } + }, true ); + } + } + + return { + addLineBreaks: addLineBreaks + }; + }); +}( window.tinymce )); diff --git a/html/wp-content/plugins/tinymce-advanced/plugin-assets/tadv.css b/html/wp-content/plugins/tinymce-advanced/plugin-assets/tadv.css new file mode 100644 index 0000000..082e7e6 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/plugin-assets/tadv.css @@ -0,0 +1,1005 @@ +/** + * Styles for the settings screen. + * @package advanced-editor-tools + */ + +body.settings_page_tinymce-advanced { + background: #ededed; + color: #000; +} + +.advanced-editor-tools h4 { + font-size: 1.1em; +} + +.settings-toggle { + display: inline-block; + padding: 12px 16px 12px 6px; + margin: 0 6px -1px 0; + border: 1px solid #ccc; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + cursor: pointer; +} + +.rtl .settings-toggle { + padding: 12px 6px 12px 16px; + margin: 0 0 -1px 6px; +} + +.settings-toggle:focus { + outline: none; +} + +#classic-editor, +#block-editor { + padding: 0 18px 18px; + border: 1px solid #ccc; +} + +.classic-active .settings-toggle.classic, +.block-active .settings-toggle.block { + border-bottom-color: #f8f9f9; + background-color: #f8f9f9; +} + +.classic-active #block-editor, +.classic-active .block .arrow-open, +.classic-active .classic .dashicons-arrow-down, +.block-active #classic-editor, +.block-active .classic .arrow-open, +.block-active .block .dashicons-arrow-down { + display: none; +} + +.wrap.advanced-editor-tools { + max-width: 760px; + margin: 16px 24px 0 16px; +} + +.rtl .wrap.advanced-editor-tools { + margin: 16px 16px 0 24px; +} + +#classic-editor, +#block-editor { + margin-bottom: 45px; + background-color: #f8f9f9; +} + +.toolbar-block-wrap { + display: inline-block; +} + +/* Block editor buttons */ +#toolbar_block { + display: inline-block; + vertical-align: text-top; +} + +.toolbar-wrap { + margin: 8px 0; +} + +.toolbar-wrap.highlighted ul, +.toolbar-block-wrap.highlighted, +.tma-block-dropdown-toolbar-inner-wrap.highlighted { + background-color: #e4f2fd; +} + +.toolbar-block-wrap { + margin: 0; +} + +#toolbar_block { + border: 0; +} + +.tma-down-addow-wrap { + padding: 16px 13px 0; + display: inline-block; + box-sizing: border-box; + vertical-align: text-top; +} + +span.tma-down-addow::after { + content: ""; + pointer-events: none; + display: block; + width: 0; + height: 0; + border-left: 3px solid transparent; + border-right: 3px solid transparent; + border-top: 5px solid #444; +} + +.tma-block-dropdown-toolbar-wrap { + position: relative; + margin: 3px 0 0 36px; + height: auto; + width: 260px; + box-shadow: 0 3px 30px rgba(25, 30, 35, 0.16); + border: 1px solid #e2e4e7; + background: #fff; +} + +.rtl .tma-block-dropdown-toolbar-wrap { + margin: 3px 72px 0 0; +} + + +/* Drop-down arrow */ +.tma-block-dropdown-toolbar-arrow::before { + top: -8px; + border: 8px solid #e2e4e7; +} + +.tma-block-dropdown-toolbar-arrow::after { + top: -6px; + border: 8px solid #fff; +} + +.tma-block-dropdown-toolbar-arrow::before, +.tma-block-dropdown-toolbar-arrow::after { + content: ""; + position: absolute; + height: 0; + width: 0; + line-height: 0; + + border-bottom-style: solid; + border-left-color: transparent; + border-right-color: transparent; + border-top: none; + margin-left: -10px; + + left: 235px; +} + +.rtl .tma-block-dropdown-toolbar-arrow::before, +.rtl .tma-block-dropdown-toolbar-arrow::after { + left: auto; + right: 226px; +} + +.tma-block-dropdown-toolbar-inner-wrap { + height: 100%; + width: 100%; +} + +ul.toolbar-block-dropdown { + padding: 7px 0; + margin: 0; + height: 100%; + width: 100%; + min-height: 36px; +} + +ul.toolbar-block-dropdown > li { + display: block; + margin: 0 0 4px; + width: auto; + height: 40px; + cursor: move; + outline: none; +} + +ul.toolbar-block-dropdown > li:hover { + color: #191e23; + border: none; + box-shadow: none; + background: #f3f4f5; +} + +ul.toolbar-block-dropdown .tma-components-icon-button { + width: 100%; +} + +ul.toolbar-block-dropdown span { + vertical-align: middle; +} + +.block-button-name { + display: inline-block; + vertical-align: middle; +} + +.tma-components-toolbar *, +.tma-block-dropdown-toolbar-wrap * { + box-sizing: border-box; +} + +.tma-components-toolbar { + border: 1px solid #e2e4e7; + margin: 0; + background-color: #fff; + line-height: 1px; + min-height: 36px; + font-size: 0pt; +} + +.tma-components-toolbar > li { + display: inline-block; + margin: 0; + width: 36px; + height: 36px; + cursor: move; +} + +.tma-components-toolbar .block-button-name { + display: none; +} + +.tma-components-icon-button { + display: inline-block; + vertical-align: middle; + margin: 0; + padding: 3px; + outline: none; + width: 36px; + height: 36px; + border: none; + background: none; + color: #555d66; + overflow: hidden; + border-radius: 4px; + -webkit-appearance: none; +} + +.tma-components-icon-button .dashicons, +.tma-components-icon-button .mce-ico { + display: inline-block; + padding: 5px; + border-radius: 4px; + height: 30px; + width: 30px; + outline: none; + overflow: hidden; +} + +.tma-components-icon-button .mce-ico:before { + font-size: 20px; + margin: 2px; + display: block; +} + +.tma-components-icon-button:hover > span { + color: #555d66; + box-shadow: inset 0 0 0 1px #555d66, inset 0 0 0 2px #fff; +} + +.toolbar-block-dropdown .tma-components-icon-button:hover > span { + box-shadow: none; +} + +.toolbar-side-wrap, +.panel-block-colors { + width: 260px; + border: 1px solid #ddd; + background-color: #fff; +} + +.panel-title { + padding: 15px; + font-weight: 600; + background-color: #f8f9f9; + margin-bottom: 5px; +} + +.panel-title span { + color: #191e23; + float: right; +} + +.rtl .panel-title span { + float: left; +} + +.toolbar-unused-wrap { + width: 350px; +} + +.block-toolbar-unused { + min-height: 72px; +} + +.toolbar-block-title { + margin: 1.2em 0 0.6em; +} + +.block-toolbar-side { + border-color: transparent; + margin: 0 12px 10px; + min-height: 37px; +} + +.highlighted .block-toolbar-side { + border-color: #e2e4e7; +} + +.panel-block-colors-wrap { + margin-top: 40px; +} + +.panel-block-colors { + float: left; +} + +.rtl .panel-block-colors { + float: right; +} + +.panel-block-colors-settings { + margin-left: 280px; + width: auto; + clear: none; +} + +.rtl .panel-block-colors-settings { + margin-left: 0; + margin-right: 280px; +} + +.panel-block-colors-settings__text { + border-top: 40px solid transparent; +} + +.panel-block-colors-settings__background { + border-top: 60px solid transparent; +} + +.panel-block-text-color p, +.panel-block-background-color p { + margin: 10px 16px 5px; + color: #555d66; +} + +.panel-block-text-color.disabled, +.panel-block-background-color.disabled { + opacity: 0.3; +} +/* Block editor buttons end */ + +.yes-no-wrap .yes-no-text { + +} + +.yes-no-wrap .yes-no-buttons { + margin: 1px; +} + +.yes-no-buttons div { + padding-right: 1.5em; + display: inline-block; +} + +.yes-no-buttons label { + vertical-align: top; +} + +/* Set max-width for text blocks for better readability on a large screen */ +.block-toolbars, +.advanced-options, +.yes-no-wrap, +#block-editor p { + max-width: 50em; +} + +.classic-blocks-title-h4 { + margin: 40px 0 1.1em; +} + +form#tadvadmin { + margin-top: 24px; +} + +.tadv-more-plugins label { + font-weight: bold; + padding: 0 10px; +} + +.advanced-options label { + font-weight: 600; +} + +.advanced-editor-tools label { + vertical-align: baseline; +} + +.advanced-editor-tools input[type="checkbox"] { + vertical-align: text-bottom; +} + +.advanced-options { + margin: 40px 0; +} + +.advanced-options div { + margin: 1.2em 0; +} + +.advanced-options p { + margin-left: 22px; + margin-top: 5px; +} + +.advanced-options .tadv-help { + margin: 1em 0; +} + +.advanced-options h3 { + margin-top: 15px; +} + +.tadv-more-plugins { + margin-bottom: 30px; +} + +.tadv-submit .button-large { + float: right; +} + +.rtl .tadv-submit .button-large { + float: left; +} + +#tadv-import-error { + height: 22px; +} + +.import-file { + margin: 2em 0; +} + +#tadv-confirm-uninstall { + display: none; + background: #FFFFE0; + border: 1px solid #E6DB55; + padding: 8px; +} + +#tadv-confirm-uninstall .button { + margin: 0 5px; +} + +.tadv-import-export { + max-width: 800px; + min-width: 320px; +} + +#tadv-import { + width: 100%; + height: 200px; + padding: 8px 12px; +} + +ul.container, +.unused { + position: relative; +} + +.tadvitem i.mce-ico { + width: 20px; + height: 20px; + line-height: 20px; + text-align: center; + vertical-align: middle; + margin: 0; + padding: 0; + color: #555; +} + +.tadvitem i.mce-ico.mce-i-ltr, +.tadvitem i.mce-ico.mce-i-tadv_mark { + font-family: tinymce; + font-size: 16px; + vertical-align: text-top; +} + +.tadvitem i.mce-ico.mce-i-ltr:before { + content: "\e02f"; +} + +.tadvitem i.mce-ico.mce-i-tadv_mark:before { + content: "\e01a"; +} + +.tadvitem i.mce-ico.mce-i-tadv_mark { + text-shadow: none; + background: #ddd; +} + +.tadvitem.mce-listbox i.mce-caret { + right: 6px; +} + +.rtl .tadvitem.mce-listbox i.mce-caret { + right: auto; + left: 6px; +} + +.tadv-mce-menu.mce-menubar { + margin-bottom: 0; + background: #fff; + border: 1px solid #ccc; + border-bottom: 0; + opacity: 0.4; + filter: alpha(opacity=40); +} + +.tadv-mce-menu.enabled { + opacity: 1; + filter: alpha(opacity=100); +} + +.tadv-mce-menu.mce-menubar .mce-menubtn:hover { + background: transparent; + border-color: transparent; +} + +/* Menubar fix... */ +.mce-menubar .mce-menubtn button span { + font-size: 13px; +} + +.tadv-mce-menu.mce-menubar .mce-menubtn:hover button span { + color: #000; +} + +.tadv-mce-menu .mce-btn .mce-caret { + margin-left: 1px; + margin-top: 6px; + border-top-color: #555; +} + +#tadvadmin .mce-menubar .mce-menubtn:hover .mce-caret { + border-top-color: #000; +} + +.tadv-mce-menu * { + cursor: default; +} + +.tadvzones, +.unused { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +#tadvadmin p.submit { + padding-right: 10px; +} + +#tadvadmin #save { + float: right; +} + +.tadvdropzone { + padding: 2px 4px; + margin: 0 0 10px; + background-color: #fff; + border: 1px solid #bbb; +} + +.unuseddiv .highlighted, +.tadvdropzone.highlighted { + background-color: #e4f2fd; + color: #000; + border-color: #aaa; +} + +.tadvdropzone .descr { + display: none; +} + +.tadvdropzone .mce-menubtn .descr { + padding: 0; + font-size: 13px; +} + +.tadvdropzone .tadvmodule .tadvitem { + border: 1px solid transparent; + display: block; + margin: 1px 2px; + padding: 2px 3px; + width: 20px; + height: 20px; + -webkit-border-radius: 2px; + border-radius: 2px; +} + +.tadvdropzone .tadvmodule .tadvitem.mce-widget { + width: auto; + height: 20px; + border-color: #ccc; + background-color: #fff; + cursor: move; +} + +.tadvdropzone.mce-toolbar .mce-btn .the-button { + padding: 2px 3px 0; +} + +.tadvdropzone .tadvmodule .tadvitem:hover { + border-color: #999; + background-image: none; +} + +.tadvdropzone ul { + height: 30px; + width: 100%; + margin: 0; + padding: 1px 0 0; + line-height: 1; +} + +.unuseddiv { + margin: 0 -5px; +} + +.unuseddiv > p { + margin: 16px 5px 6px; +} + +.unused li, +.tadvdropzone li { + margin: 0; + padding: 0; + border: none; + display: inline-block; + cursor: move; + vertical-align: top; +} + +.unused li { + margin: 4px; +} + +.unused { + margin: 0; + min-height: 36px; +} + +.unused .tadvmodule .tadvitem { + display: block; + height: 24px; + width: 140px; + border: 1px solid #bbb; + background-color: #fff; + margin: 2px 1px 1px; + padding: 5px 4px 0; + -webkit-border-radius: 2px; + border-radius: 2px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + background-image: none; + box-shadow: none; +} + +.unused .tadvmodule .descr { + display: inline; + font-size: 12px; + line-height: 20px; +} + +.unused .tadvmodule .the-button .descr { + padding: 0 4px; + font-size: 13px; +} + +.tadvdropzone #formatselect, +.tadvdropzone #styleselect, +.tadvdropzone #fontsizeselect, +.tadvdropzone #fontselect { + width: 115px; +} + +div.tadv-error { + color: #ff0000; + font-weight: bold; + height: 26px; + line-height: 26px; + display: none; +} + +.wp-adv-error #wp-adv-error-message { + visibility: visible; +} + +.wp-adv-error #wp_adv .tadvitem { + border-color: red; +} + +.tadv-placeholder { + vertical-align: bottom; + display: inline-block; + position: static; + visibility: hidden; +} + +.tadvdropzone .tadv-placeholder { + height: 28px; +} + +.tadv-error { + color: #d54e21; +} + +.tadv-block-editor-toolbars-wrap { + max-width: 650px; +} + +.tadv-block-editor .mce-menubtn { + margin: 7px 0 6px; +} + +.tadv-block-editor.tadvdropzone { + height: 60px; +} + +#toolbar_classic_block { + height: 60px; +} + +.tadv-popout-help { + padding: 1px 18px; + background-color: #fff; + margin: 8px 0; + border: 1px solid #e8e8e8; +} + +.tadv-popout-help ol { + padding: 0; + margin: 1em; +} + +.tadv-popout-help-close { + float: right; + margin: 1px -16px; +} + +.rtl .tadv-popout-help-close { + float: left; +} + +.tadv-popout-help-toggle, +.tadv-popout-help-close { + cursor: pointer; +} + +.tadv-mark .dashicons-editor-textcolor { + background-color: #fff9c0; + background-clip: content-box; +} + +.rtl .the-button { + direction: rtl; + text-align: right; +} + +.tadv-block-placeholder { + background: #fff; + vertical-align: middle; +} + +/* Block toolbar */ +.tma-block-toolbar-wrap.editor-block-toolbar { + white-space: nowrap; + overflow-wrap: break-word; + box-sizing: border-box; + font-size: 16px; + line-height: 1.8; + color: #191e23; + + display: flex; + flex-grow: 1; + + width: auto; + overflow: inherit; + border-right: none; + border-left: 1px solid #b5bcc2; +} + +.tma-block-toolbar-wrap.editor-block-toolbar * { + box-sizing: inherit; +} + +.tma-block-toolbar-wrap div.components-toolbar { + border-top: 1px solid #b5bcc2; + border-bottom: 1px solid #b5bcc2; + border-right: 1px solid #b5bcc2; + + margin: 0; + background-color: #fff; + display: flex; + flex-shrink: 0; +} + +.tma-block-toolbar-wrap div.components-toolbar > div { + display: flex; +} + +.tma-block-toolbar-wrap .block-editor-block-switcher { + position: relative; + height: 36px; +} + +.tma-block-toolbar-wrap .components-button { + display: inline-flex; + text-decoration: none; + font-size: 13px; + margin: 0; + border: 0; + cursor: default; + -webkit-appearance: none; + background: none; + outline: none; +} + +.tma-block-toolbar-wrap .components-icon-button { + display: flex; + align-items: center; + padding: 8px; + margin: 0; + border: none; + background: none; + color: #555d66; + position: relative; + overflow: hidden; + border-radius: 4px; +} + +.tma-block-toolbar-wrap .components-toolbar__control.components-button { + display: inline-flex; + align-items: flex-end; + margin: 0; + padding: 3px; + outline: none; + position: relative; + width: 36px; + height: 36px; +} + +.tma-block-toolbar-wrap .components-dropdown-menu { + padding: 3px; +} + +.tma-block-toolbar-wrap div.components-toolbar > div + div { + margin-left: -3px; +} + +.rtl .tma-block-toolbar-wrap div.components-toolbar > div + div { + margin-left: 0; + margin-right: -3px; +} + +.tma-block-toolbar-wrap .components-dropdown-menu .components-dropdown-menu__toggle { + width: auto; + margin: 0; + padding: 4px; + border: 1px solid transparent; + display: flex; + flex-direction: row; + + /* Always hover... */ + color: #555d66; + box-shadow: inset 0 0 0 1px #555d66, inset 0 0 0 2px #fff; +} + +.tma-block-toolbar-wrap .components-dropdown-menu .components-dropdown-menu__toggle .components-dropdown-menu__indicator::after { + content: ""; + pointer-events: none; + display: block; + width: 0; + height: 0; + border-left: 3px solid transparent; + border-right: 3px solid transparent; + border-top: 5px solid currentColor; + margin: 7px; +} + +.components-dropdown-menu .components-dropdown-menu__toggle:hover, +.components-dropdown-menu .components-dropdown-menu__toggle:focus, +.components-dropdown-menu .components-dropdown-menu__toggle:not(:disabled):not([aria-disabled="true"]):not(.is-default):hover { + color: #555d66; + box-shadow: inset 0 0 0 1px #555d66, inset 0 0 0 2px #fff; +} + +.tma-block-toolbar-wrap .block-editor-block-icon { + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + margin: 0; + border-radius: 4px; +} + +.tma-block-toolbar-wrap .block-editor-block-icon.has-colors svg { + fill: currentColor; +} + +.tma-block-toolbar-wrap .block-editor-block-icon svg { + width: 20px; + height: 20px; + max-width: 24px; + max-height: 24px; +} + +.tma-block-toolbar-wrap .components-icon-button svg { + fill: currentColor; + outline: none; +} + +.tma-block-toolbar-wrap .components-toolbar__control.components-button > svg, +.tma-block-toolbar-wrap .components-toolbar__control.components-button > .dashicons { + padding: 5px; + border-radius: 4px; + height: 30px; + width: 30px; +} + +.tma-block-toolbar-wrap .components-toolbar__control .dashicon { + display: block; +} + +.tma-block-toolbar-wrap .components-icon-button.block-editor-block-switcher__toggle .block-editor-block-icon::after { + content: ""; + pointer-events: none; + display: block; + width: 0; + height: 0; + border-left: 3px solid transparent; + border-right: 3px solid transparent; + border-top: 5px solid currentColor; + margin-left: 4px; + margin-right: 2px; +} + +.tma-block-toolbar-wrap .block-editor-block-settings-menu__toggle .dashicon { + transform: rotate(90deg); +} + +.tma-block-toolbar-wrap .components-icon-button.block-editor-block-switcher__toggle, +.tma-block-toolbar-wrap .components-icon-button.block-editor-block-switcher__no-switcher-icon { + width: auto; + margin: 0; + display: block; + height: 36px; + padding: 3px; +} + +.tma-block-toolbar-wrap .components-icon-button.block-editor-block-switcher__toggle .block-editor-block-icon, +.tma-block-toolbar-wrap .components-icon-button.block-editor-block-switcher__toggle .block-editor-block-switcher__transform { + width: 42px; + height: 30px; + position: relative; + margin: 0 auto; + padding: 3px; + display: flex; + align-items: center; +} + +.advanced-options .dashicons { + color: #777; +} + +.tadvmodule .the-button { + margin: 0; +} + +/* Fixes for inadequate css changes in 5.3 :( */ +#tadvadmin .button, +#tadvadmin .button-primary { + font-size: 14px; + line-height: 1.7; + padding: 2px 10px 3px; +} + +span.small-info { + font-weight: 400; + font-size: 13px; +} diff --git a/html/wp-content/plugins/tinymce-advanced/plugin-assets/tadv.js b/html/wp-content/plugins/tinymce-advanced/plugin-assets/tadv.js new file mode 100644 index 0000000..89531f2 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/plugin-assets/tadv.js @@ -0,0 +1,249 @@ +/** + * Scripts for the settings screen in wp-admin. + * @package advanced-editor-tools + */ + +jQuery( document ).ready( function( $ ) { + var $importElement = $('#tadv-import'); + var $importError = $('#tadv-import-error'); + + function sortClassic() { + var container = $('.container'); + + if ( container.sortable( 'instance' ) ) { + container.sortable( 'destroy' ); + } + + container.sortable({ + connectWith: '.container', + items: '> li', + cursor: 'move', + stop: function( event, ui ) { + var toolbar_id; + + if ( ui && ( toolbar_id = ui.item.parent().attr('id') ) ) { + ui.item.find('input.tadv-button').attr('name', toolbar_id + '[]'); + } + }, + activate: function( event, ui ) { + $(this).parent().addClass( 'highlighted' ); + }, + deactivate: function( event, ui ) { + $(this).parent().removeClass( 'highlighted' ); + }, + revert: 300, + opacity: 0.7, + placeholder: 'tadv-placeholder', + forcePlaceholderSize: true + }); + } + + function sortBlock() { + var classicBlock = $( '.container-classic-block' ); + var block = $( '.container-block' ); + var blockToolbar = $( '#toolbar_block' ); + + if ( classicBlock.sortable( 'instance' ) ) { + classicBlock.sortable( 'destroy' ); + } + + if ( block.sortable( 'instance' ) ) { + block.sortable( 'destroy' ); + } + + if ( blockToolbar.sortable( 'instance' ) ) { + blockToolbar.sortable( 'destroy' ); + } + + classicBlock.sortable({ + connectWith: '.container-classic-block', + items: '> li', + cursor: 'move', + stop: function( event, ui ) { + var toolbar_id = ui.item.parent().attr( 'id' ); + resetItemName( toolbar_id, ui.item ); + }, + activate: function( event, ui ) { + $(this).parent().addClass( 'highlighted' ); + }, + deactivate: function( event, ui ) { + $(this).parent().removeClass( 'highlighted' ); + }, + revert: 300, + opacity: 0.7, + placeholder: 'tadv-placeholder', + forcePlaceholderSize: true + }); + + blockToolbar.sortable({ + connectWith: '.container-block', + items: '> li', + cursor: 'move', + stop: function( event, ui ) { + var toolbar_id = ui.item.parent().attr( 'id' ); + + resetItemName( toolbar_id, ui.item ); + sortBlockToolbar(); + }, + activate: function( event, ui ) { + $(this).parent().addClass( 'highlighted' ); + }, + deactivate: function( event, ui ) { + $(this).parent().removeClass( 'highlighted' ); + }, + revert: 300, + opacity: 0.7, + placeholder: 'tadv-placeholder', + forcePlaceholderSize: true + }); + + block.sortable({ + connectWith: '.container-block, #toolbar_block', + items: '> li', + cursor: 'move', + stop: function( event, ui ) { + var toolbar_id = ui.item.parent().attr( 'id' ); + + resetItemName( toolbar_id, ui.item ); + sortBlockToolbar(); + }, + activate: function( event, ui ) { + $(this).parent().addClass( 'highlighted' ); + }, + deactivate: function( event, ui ) { + $(this).parent().removeClass( 'highlighted' ); + }, + receive: function( event, ui ) { + if ( + $( event.target ).is( '#toolbar_block_side' ) && + ( ui.item.is( 'li.core-image' ) || ui.item.is( 'li.core-text-color' ) ) + ) { + block.sortable( 'cancel' ); + } + }, + revert: 300, + opacity: 0.7, + placeholder: 'tadv-block-placeholder', + forcePlaceholderSize: true + }); + } + + function resetItemName( name, item ) { + if ( name ) { + item.find( 'input[type="hidden"]' ).attr( 'name', name + '[]' ); + } + } + + function sortBlockToolbar() { + var container = $( '#toolbar_block' ); + var items = container.find( 'li' ); + + items.sort( function ( a, b ) { + var aa = $( a ).find( 'div' ).attr( 'title' ); + var bb = $( b ).find( 'div' ).attr( 'title' ); + + return ( aa > bb ) ? 1 : -1; + }); + + container.append( items ); + } + + // Make block editor tab sortable on load + sortBlock(); + + $( '.settings-toggle.block' ).on( 'focus', function( event ) { + $( '.wrap' ).removeClass( 'classic-active' ).addClass( 'block-active' ); + sortBlock(); + }); + + $( '.settings-toggle.classic' ).on( 'focus', function( event ) { + $( '.wrap' ).removeClass( 'block-active' ).addClass( 'classic-active' ); + sortClassic(); + }); + + $( '#menubar' ).on( 'change', function() { + $( '.tadv-mce-menu.tadv-classic-editor' ).toggleClass( 'enabled', $(this).prop('checked') ); + }); + + $( '#menubar_block' ).on( 'change', function() { + $( '.tadv-mce-menu.tadv-block-editor' ).toggleClass( 'enabled', $(this).prop('checked') ); + }); + + $( '#tadvadmins' ).on( 'submit', function() { + $( 'ul.container' ).each( function( i, node ) { + $( node ).find( '.tadv-button' ).attr( 'name', node.id ? node.id + '[]' : '' ); + }); + }); + + $( 'input[name="selected_text_color"]' ).on( 'change', function() { + if ( this.id === 'selected_text_color_yes' ) { + $( '.panel-block-text-color' ).removeClass( 'disabled' ); + } else { + $( '.panel-block-text-color' ).addClass( 'disabled' ); + } + } ); + + $( 'input[name="selected_text_background_color"]' ).on( 'change', function() { + if ( this.id === 'selected_text_background_color_yes' ) { + $( '.panel-block-background-color' ).removeClass( 'disabled' ); + } else { + $( '.panel-block-background-color' ).addClass( 'disabled' ); + } + } ); + + $( '.tadv-popout-help-toggle, .tadv-popout-help-close' ).on( 'click', function( event ) { + $( '.tadv-popout-help' ).toggleClass( 'hidden' ); + } ); + + $('#tadv-export-select').click( function() { + $('#tadv-export').focus().select(); + }); + + $importElement.change( function() { + $importError.empty(); + }); + + $('#tadv-import-verify').click( function() { + var string; + + string = ( $importElement.val() || '' ).replace( /^[^{]*/, '' ).replace( /[^}]*$/, '' ); + $importElement.val( string ); + + try { + JSON.parse( string ); + $importError.text( 'No errors.' ); + } catch( error ) { + $importError.text( error ); + } + }); + + function translate( str ) { + if ( window.tadvTranslation.hasOwnProperty( str ) ) { + return window.tadvTranslation[str]; + } + return str; + } + + if ( typeof window.tadvTranslation === 'object' ) { + $( '.tadvitem' ).each( function( i, element ) { + var $element = $( element ), + $descr = $element.find( '.descr' ), + text = $descr.text(); + + if ( text ) { + text = translate( text ); + $descr.text( text ); + $element.find( '.mce-ico' ).attr( 'title', text ); + } + }); + + $( '.tadv-mce-menu .tadv-translate' ).each( function( i, element ) { + var $element = $( element ), + text = $element.text(); + + if ( text ) { + $element.text( translate( text ) ); + } + }); + } +}); diff --git a/html/wp-content/plugins/tinymce-advanced/readme.txt b/html/wp-content/plugins/tinymce-advanced/readme.txt new file mode 100644 index 0000000..f6ad571 --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/readme.txt @@ -0,0 +1,322 @@ +=== Advanced Editor Tools === +Contributors: automattic, azaozz +Tags: block editor, classic editor, editor, Gutenberg, formatting, tinymce, write +Requires at least: 5.9 +Tested up to: 6.3 +Stable tag: 5.9.2 +Requires PHP: 5.6 +License: GPLv2 +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Extends and enhances the block editor (Gutenberg) and the classic editor (TinyMCE). + +== Description == + +Advanced Editor Tools (previously TinyMCE Advanced) introduces a "Classic Paragraph" block for the block editor (Gutenberg). +If you are not quite ready to switch to the block editor, or have plugins that cannot be used there (yet), using the Classic Paragraph block is your best option. It lets you to continue to use the familiar TinyMCE editor for most tasks, and at the same time gives you full access to all blocks and new features in the block editor. + +Version 5.5 continues to improve and enhance the new features introduced in version 5.0 of the plugin. It includes an improved "Clear Formatting" button, several advanced settings for tables, and importing and exporting of the settings to a file. + +If you want to continue to use the previous ("classic") editor in WordPress 5.0 and newer, this plugin has an option to replace the new editor with the previous one. If you prefer to have access to both editors side by side or to allow your users to switch editors, it would be better to install the [Classic Editor plugin](https://wordpress.org/plugins/classic-editor/). Advanced Editor Tools is fully compatible with the classic editor plugin and similar plugins that restore use of the previous WordPress editor. + +As always this plugin will let you add, remove and arrange the buttons that are shown on the Visual Editor toolbar in the Classic Paragraph and Classic blocks in the block editor, and in the classic editor (when enabled by a plugin). There you can configure up to four rows of buttons including Font Sizes, Font Family, text and background colors, tables, etc. + +It includes 15 plugins for [TinyMCE](https://www.tiny.cloud/) that are automatically enabled or disabled depending on the buttons you have chosen. +In addition this plugin adds options for keeping the paragraph tags in text mode and importing the CSS classes from the theme's editor-style.css. + += Some of the features added by this plugin = + +* "Classic Paragraph" block that can be used instead of or together with the standard Paragraph block. +* An option to set the Classic Paragraph or Classic block as the default block in the block editor. +* Supports converting of most default blocks to classic paragraphs, and from classic paragraphs back to the default blocks. +* Support for creating and editing tables in the Classic blocks and the classic editor. +* More options when inserting lists in the Classic blocks and the classic editor. +* Search and Replace in the Classic blocks and the classic editor. +* Ability to set Font Family and Font Sizes in the Classic blocks and the classic editor. +* And many others. + += Privacy = + +Advanced Editor Tools does not collect or store any user related data. It does not set cookies, and it does not connect to any third-party websites. It only uses functionality that is available in [WordPress](https://wordpress.org/), and in the [TinyMCE editor](https://tinymce.com/). + +In that terms Advanced Editor Tools does not affect your website's user privacy in any way. + +== Installation == + +If manual installation is required, please make sure that the plugin files are in a folder named "tinymce-advanced" (not two nested folders) in the WordPress plugins folder, usually "wp-content/plugins". + +== Changelog == + += 5.9.2 = +* Fixed a typo in the plugin header version string. + += 5.9.1 = +* Fixed a warning in PHP 8.0 and never. + += 5.9.0 = +* Updated for WordPress 5.9 and newer. +* Removed the Inline text color and Inline text background color side-panels as this functionality is now available in the block editor. +* Removed the side-panel toolbar. The drop-down on the main rich-text toolbar serves the same purpose - to unclutter the toolbar. +* Fixed some small bugs and compatibility issues. + += 5.6.0 = +* Updated for WordPress 5.6 and TinyMCE 4.9.11. + += 5.5.1 = +* Renamed the plugin to Advanced Editor Tools to comply with trademark requirements. + += 5.5.0 = +* Updated for WordPress 5.5 and TinyMCE 4.9.10. +* Updated/renamed the subscript and superscript buttons as these are now in Gutenberg. +* Minor CSS fixes and enhancements. + += 5.4.0 = +* Updated for WordPress 5.4. +* Improved "Reset Table Size" to reset all table elements (tr, th, td, thead, tbody, tfoot). +* Improved "Remove Table Styling" to remove all current and deprecated styling attributes from all table elements. + += 5.3.0 = +* Updated for WordPress 5.3 and TinyMCE 4.9.6. + += 5.2.1 = +* Updated for WordPress 5.2.1 and TinyMCE 4.9.4. +* Fixed resetting of the advanced options on update when all were unselected. +* Fixed and improved keepig of paragraph tags in the Classic block. + += 5.2.0 = +* Updated for WordPress 5.2. +* Updated the buttons settings for the block editor toolbar. There are a few new limitations there: most buttons are now hidden in a drop-down and the users are not allowed to arrange the buttons. +* Added a new advanced settings section for tables. Makes it possible to better configure how tables are edited and whether to disable use of inline CSS styles. Note that disabling inline styles would make the tables non-resizable in the editor. +* Removed the option to enable pasting of image sources in some browsers. It was not working correctly. +* Added a new option to always keep paragraph tags in the Classic Paragraph and Classic blocks in the block editor. +* Updated exporting and importing of the settings. Now settings are exported to a (downloaded) file, and can be restored by uploading a previously exported settings file. +* Improved the block editor Clear Formatting button. If some text is selected, it only clears the styling from that text. If no selection, all styling from the paragraph is cleared. + += 5.0.1 = +* Fixed importing of backed-up settings. +* Updated the FAQ section in the readme. + += 5.0.0 = +* Added several new buttons to the rich-text toolbar in the block editor. +* Added functionality to add, remove and arrange most buttons on the rich-text toolbar in the block editor. +* Added alternative location for buttons for the rich-text component. That lets users move buttons that are not used frequently out of the way. +* Added settings for selected text color and background color. +* Improved fixes and enhancements for the Classic block. +* Improved the Classic Paragraph block and added support for converting from most blocks to classic paragraphs, and converting a classic paragraph into separate blocks. + += 4.8.2 = +* Fixes and improvements for 4.8.1. +* Added separate option to enable the Classic Paragraph block. +* Added converting of most default blocks to classic paragraphs, and from classic paragraphs to default blocks. + += 4.8.1 = +* Updated for WordPress 5.0. +* Added Hybrid Mode for the block editor. Includes a Classic Paragraph block that replaces the default Paragraph block. +* Added option to replace the block editor with the classic editor. +* Added another settings section for configuring the toolbars in the Classic block and the Classic Paragraph block. +* Added some CSS fixed for the Classic block. +* Fixed (removed) setting of inline CSS for table cells when inserting a table. Inline CSS is still added when a table is resized by dragging. + += 4.8.0 = +* Updated for WordPress 4.9.8 and TinyMCE 4.8.0. + += 4.7.13 = +* Updated the table and anchor plugins to 4.7.13 (2018-05-16). Fixes a bug in the table plugin in Edge. + += 4.7.11 = +* Updated for WordPress 4.9.6 and TinyMCE 4.7.11. + += 4.6.7 = +* Fixed compatibility with Gutenberg freeform block. +* Forced refresh of the TinyMCE plugins after activation. +* Updated for WordPress 4.9 and TinyMCE 4.6.7. + += 4.6.3 = +* Updated for WordPress 4.8 and TinyMCE 4.6.3. + += 4.5.6 = +* Updated for WordPress 4.7.4 and TinyMCE 4.5.6. +* Fixed PHP notice after importing settings. + += 4.4.3 = +* Updated for WordPress 4.7 and TinyMCE 4.4.3. +* Fixed missing "Source code" button bug. + += 4.4.1 = +* Updated for WordPress 4.6 and TinyMCE 4.4.1. +* Fixed multisite saving bug. +* Added new button in the Text editor to add or reset the line breaks. Adds line breaks only between tags. Works only when it detects that line breaks are missing so it doesn't reformat posts with removed paragraphs. + += 4.3.10.1 = +* Fixed adding paragraph tags when loading posts that were saved before turning `wpautop` off. +* Disabled the (new) inline toolbar for tables as it was overlapping the table in some cases. + += 4.3.10 = +* Updated for WordPress 4.5.1 and TinyMCE 4.3.10. +* Fixed support for adding editor-style.css to themes that don't have it. + += 4.3.8 = +* Updated for WordPress 4.5 and TinyMCE 4.3.8. +* Separated standard options and admin options. +* Added settings that can disable the plugin for the main editor, other editors in wp-admin or editors on the front-end. +* Korean translation by Josh Kim and Greek translation by Stathis Mellios. + += 4.2.8 = +* Updated for WordPress 4.4 and TinyMCE 4.2.8. +* Japanese translation by Manabu Miwa. + += 4.2.5 = +* Updated for WordPress 4.3.1 and TinyMCE 4.2.5. +* Fixed text domain and plugin headers. + += 4.2.3.1 = +* Fix error with removing the `textpattern` plugin. + += 4.2.3 = +* Updated for WordPress 4.3 and TinyMCE 4.2.3. +* Removed the `textpattern` plugin as WordPress 4.3 includes similar functionality by default. +* French translation by Nicolas Schneider. + += 4.1.9 = +* Updated for WordPress 4.2 and TinyMCE 4.1.9. +* Fixed bugs with showing oEmbed previews when pasting an URL. +* Fixed bugs with getting the content from TinyMCE with line breaks. + += 4.1.7 = +* Updated for WordPress 4.1 and TinyMCE 4.1.7. +* Fixed bug where consecutive caption shortcodes may be split with an empty paragraph tag. + += 4.1.1 = +* Fix bug with image captions when wpautop is disabled. +* Add translation support to the settings page. Button names/descriptions are translated from JS using the existing WordPress translation, so this part of the settings page will be translated by default. The other text still needs separate translation. + += 4.1 = +* Updated for WordPress 4.0 and TinyMCE 4.1. +* Add the `textpattern` plugin that supports some of the markdown syntax while typing, [(more info)](http://www.tinymce.com/wiki.php/Configuration:textpattern_patterns). +* Add the updated 'table' plugin that supports background and border color. + += 4.0.2 = +* Fix showing of the second, third and forth button rows when the Toolbar Toggle button is not used. +* Fix adding the `directionality` plugin when RTL or LTR button is selected. +* Show the ''Advanced Options'' to super admins on multisite installs. +* Add the `link` plugin including link rel setting. Replaces the Insert/Edit Link dialog when enabled. +* Include updated ''table'' plugin that has support for vertical align for cells. + += 4.0.1 = +Fix warnings on pages other than Edit Post. Update the description. + += 4.0 = +Updated for WordPress 3.9 and TinyMCE 4.0. Refreshed the settings screen. Added support for exporting and importing of the settings. + += 3.5.9.1 = +Updated for WordPress 3.8, fixed auto-embedding of single line URLs when not removing paragraph tags. + += 3.5.9 = +Updated for WordPress 3.7 and TinyMCE 3.5.9. + += 3.5.8 = +Updated for WordPress 3.5 and TinyMCE 3.5.8. + += 3.4.9 = +Updated for WordPress 3.4 and TinyMCE 3.4.9. + += 3.4.5.1 = +Fixed a bug preventing TinyMCE from importing CSS classes from editor-style.css. + += 3.4.5 = +Updated for WordPress 3.3 or later and TinyMCE 3.4.5. + += 3.4.2.1 = +Fix the removal of the *media* plugin so it does not require re-saving the settings. + += 3.4.2 = +Compatibility with WordPress 3.2 and TinyMCE 3.4.2, removed the options for support for iframe and HTML 5.0 elements as they are supported by default in WordPress 3.2, removed the *media* plugin as it is included by default. + += 3.3.9.1 = +Added advanced options: stop removing iframes, stop removing HTML 5.0 elements, moved the support for custom editor styles to editor-style.css in the current theme. + +Attention: if you have a customized `tadv-mce.css` file and your theme doesn't have editor-style.css, please download `tadv-mce.css`, rename it to editor-style.css and upload it to your current theme directory. Alternatively you can add there the editor-style.css from the Twenty Ten theme. If your theme has editor-style.css you can add any custom styles there. + += 3.3.9 = +Compatibility with WordPress 3.1 and TinyMCE 3.3.9, improved P and BR tags option. + += 3.2.7 = +Compatibility with WordPress 2.9 and TinyMCE 3.2.7, several minor bug fixes. + += 3.2.4 = +Compatibility with WordPress 2.8 and TinyMCE 3.2.4, minor bug fixes. + += 3.2 = +Compatibility with WordPress 2.7 and TinyMCE 3.2, minor bug fixes. + += 3.1 = +Compatibility with WordPress 2.6 and TinyMCE 3.1, keeps empty paragraphs when disabling the removal of P and BR tags, the buttons for `MCImageManager` and `MCFileManager` can be arranged (if installed). + += 3.0.1 = +Compatibility with WordPress 2.5.1 and TinyMCE 3.0.7, added option to disable the removal of P and BR tags when saving and in the HTML editor (wpautop), added two more buttons to the HTML editor: `wpautop` and undo, fixed the removal of non-default TinyMCE buttons. + += 3.0 = +Support for WordPress 2.5 and TinyMCE 3.0. + += 2.2 = +Deactivate/Uninstall option page, font size drop-down menu and other small changes. + += 2.1 = +Improved language selection, improved compatibility with WordPress 2.3 and TinyMCE 2.1.1.1, option to override some of the imported css classes and other small improvements and bugfixes. + += 2.0 = +Includes an admin page for arranging the TinyMCE toolbar buttons, easy installation, a lot of bugfixes, customized "Smilies" plugin that uses the built-in WordPress smilies, etc. The admin page uses jQuery and jQuery UI that lets you "drag and drop" the TinyMCE buttons to arrange your own toolbars and enables/disables the corresponding plugins depending on the used buttons. + + +== Frequently Asked Questions == + += I see an error like: "Failed to load plugin from url..." = + +These errors are usually caused by the file in question being blocked by some security setting on the server, or (rarely) by caching issues or wrong permissions. + +The first step to debug this is to try to access the file directly in the browser (i.e. copy the URL and paste in the browser and press Enter). + +If you see the file (that’s usually minified JS, so it is all on one line) chances are it was some sort of caching issue that is now resolved. Try using the editor again. + +If you see an HTTP error (like 403 or 500) best would be to contact your web hosting company for help. In some cases deleting and re-installing the plugin may help. + += Tables look different (inline styles are missing) when I insert a table = + +Please see the new (as of version 5.2.0) advanced settings for tables. It is possible to disable use of inline styles for tables but that would make the table non-resizable in the editor. If the advanced tabs on the table, row, and column dialogs are enabled (default), it will still be possible to enter width and height values which are set as inline styles. + += No styles are imported in the Formats sub-menu = + +These styles are imported from your current theme editor-style.css file. However some themes do not have this functionality. For these themes Advanced Editor Tools has the option to let you add a customized editor-style.css and import it into the editor. + += I have just installed this plugin, but it does not do anything = + +Change some buttons on one of the toolbars, save your changes, clear your browser cache, and try again. If that does not work try reloading the Edit page several times while holding down Shift. There may also be a network cache somewhere between you and your host. You may need to wait for a few hours until this cache expires. + += When I add "Smilies", they do not show in the editor = + +The "Emoticons" button in TinyMCE adds the codes for the smilies. The actual images are added by WordPress when viewing the Post. Make sure the checkbox "Convert emoticons to graphics on display" in "Options - Writing" is checked. + += The plugin does not add any buttons = + +Make sure the "Disable the visual editor when writing" checkbox under "Users - Your Profile" is **not** checked. + += I still see the "old" buttons in the editor = + +Re-save the settings or click the "Restore Default Settings" button on the plugin settings page and then set the buttons again and save. + +== Screenshots == + +1. Rich-text toolbar. +2. Rich-text toolbar and extra formatting buttons in the Inspector (sidebar). +3. Many of the buttons can be moved to the Formatting section in the Inspector. +4. Converting the content of the Classic Paragraph block into separate blocks. +5. Converting several paragraph blocks into a Classic Paragraph block. +6. Settings for the Rich-text toolbar and the optional Formatting section in the Inspector. +7. Settings for the toolbars in Classic Paragraph and Classic blocks. +8. Additional options. +9. Advanced options for tables. + +== Upgrade Notice == + += 5.2.0 = +Another large upgrade. Includes advanced options for tables, updated import and export of settings, and further improvements for the block editor. diff --git a/html/wp-content/plugins/tinymce-advanced/tadv_admin.php b/html/wp-content/plugins/tinymce-advanced/tadv_admin.php new file mode 100644 index 0000000..713b34a --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/tadv_admin.php @@ -0,0 +1,754 @@ +save_settings(); +} elseif ( isset( $_POST['tadv-restore-defaults'] ) ) { + check_admin_referer( 'tadv-save-buttons-order' ); + + // TODO: only for admin || SA + $this->admin_settings = $this->get_default_admin_settings(); + update_option( 'tadv_admin_settings', $this->get_default_admin_settings() ); + + // TODO: all users that can have settings + $this->user_settings = $this->get_default_user_settings(); + update_option( 'tadv_settings', $this->get_default_user_settings() ); + + $message = '

            ' . __( 'Default settings restored.', 'tinymce-advanced' ) . '

            '; +} elseif ( isset( $_POST['tadv-import-settings'] ) ) { + check_admin_referer( 'tadv-save-buttons-order' ); + + // TODO: all users + ?> +
            +

            + +
            +
            +

            +

            +

            + +
            +
            +
            +

            +

            +

            + + +

            + +

            +
            +

            +
            +
            +

            ' . __( 'Importing of settings failed.', 'tinymce-advanced' ) . '

            '; + } else { + $this->save_settings( $import ); + $message = '

            ' . __( 'Settings imported successfully.', 'tinymce-advanced' ) . '

            '; + } +} elseif ( isset( $_GET['tadv-import-file-complete'] ) ) { + $err = (int) $_GET['tadv-import-file-complete']; + + switch( $err ) { + case 1: + $message = __( 'Importing of settings failed. Please import a valid settings file.', 'tinymce-advanced' ); + break; + case 2: + $message = __( 'Importing of settings failed. The imported file is empty.', 'tinymce-advanced' ); + break; + case 3: + $message = __( 'Importing of settings failed. The imported file is invalid.', 'tinymce-advanced' ); + break; + } + + if ( empty( $message ) ) { + $message = '

            ' . __( 'Settings imported successfully.', 'tinymce-advanced' ) . '

            '; + } else { + $message = '

            ' . $message . '

            '; + } +} + +$this->load_settings(); + +if ( empty( $this->toolbar_1 ) && empty( $this->toolbar_2 ) && empty( $this->toolbar_3 ) && empty( $this->toolbar_4 ) ) { + $message = '

            ' . __( 'ERROR: All toolbars are empty. Default settings loaded.', 'tinymce-advanced' ) . '

            '; + + $this->admin_settings = $this->get_default_admin_settings(); + $this->user_settings = $this->get_default_user_settings(); + $this->load_settings(); +} + +$all_buttons = $this->get_all_buttons(); + +?> +
            +

            +warn_if_unsupported(); + +if ( isset( $_POST['tadv-save'] ) && empty( $message ) ) { + ?>

            +
            + +
            +

            + +

            +

            + + + +

            +

            + + + +

            +
            + +
            +

            +
            +
            +

            + Mark button will wrap the selected text in a plain <mark> HTML element. The appearance would depend on your theme and usually resembles highlighted text.', 'tinymce-advanced' ); ?> +

            +

            + Clear formatting button will remove text formatting from the selected text, or from the whole paragraph if there is no selection. This includes femoval of most text styling like bold, italic, underline, background and foreground color, etc.', 'tinymce-advanced' ); ?> +

            +
            +
            +
            + check_user_setting( 'disable_richtext_buttons' ) ) echo ' checked'; ?>> + +
            +
            + check_user_setting( 'disable_richtext_buttons' ) ) echo ' checked'; ?>> + +
            +
            +
            + +

            + +

            + + + +

            + +

            + check_user_setting( 'menubar_block' ) ) { echo ' checked'; } ?>> + +

            + +
            +
            +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            +
            + +
            +
              + toolbar_classic_block as $button_id ) { + $name = ''; + + if ( strpos( $button_id, 'separator' ) !== false || in_array( $button_id, array( 'moveforward', 'movebackward', 'absolute' ) ) ) { + continue; + } + + if ( isset( $all_buttons_block[ $button_id ] ) ) { + $name = $all_buttons_block[ $button_id ]; + unset( $all_buttons_block[ $button_id ] ); + } else { + continue; + } + + ?> +
            • + +
              +
              + + + +
              +
              + +
              + + + +
              + +
            • + +
            +
            +
            + +

            + +
            +

            +
            +
              + $name ) { + if ( strpos( $button_id, 'separator' ) !== false ) { + continue; + } + + ?> +
            • + +
              +
              + + + +
              +
              + +
              + + + +
              + +
            • + +
            +
            +
            +
            + +
            +

            + +
            +

            + check_user_setting( 'menubar' ) ) { echo ' checked="checked"'; } ?>> + +

            + +
            +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            + +
            +
            +
            + + +
            +
              + $toolbar as $button_id ) { + if ( strpos( $button_id, 'separator' ) !== false || in_array( $button_id, array( 'moveforward', 'movebackward', 'absolute' ) ) ) { + continue; + } + + if ( isset( $all_buttons_classic[ $button_id ] ) ) { + $name = $all_buttons_classic[ $button_id ]; + unset( $all_buttons_classic[ $button_id ] ); + } else { + continue; + } + + ?> +
            • + +
              +
              + + + +
              +
              + +
              + + + +
              + +
            • + +
            + +
            + +

            + +
            +

            +
            +
              + $name ) { + if ( strpos( $button_id, 'separator' ) !== false ) { + continue; + } + + ?> +
            • + +
              +
              + + + +
              +
              + +
              + + + +
              + +
            • + +
            +
            +
            +
            + +
            +

            + +
            + check_user_setting( 'merge_toolbars' ) ) echo ' checked'; ?> /> + +

            +
            + +
            + check_user_setting('advlist') ) echo ' checked'; ?> /> + +

            + +

            +
            + +
            + check_user_setting('contextmenu') ) echo ' checked'; ?> /> + +

            +
            + +
            + check_user_setting('advlink') ) echo ' checked'; ?> /> + +

            +
            + +
            + check_user_setting( 'fontsize_formats' ) ) echo ' checked="checked"'; ?> /> + +

            fontsize_formats ); ?>

            +
            +
            + +
            +

            +
            + check_admin_setting( 'classic_paragraph_block' ) ) echo ' checked'; ?> /> + +

            + + + + +

            +

            + + +

            +
            + +
            + check_admin_setting( 'hybrid_mode' ) ) echo ' checked'; ?> /> + +

            + + +

            +
            + +
            + + check_admin_setting( 'replace_block_editor' ) ) echo ' checked'; ?> /> + +

            + + +

            +

            + ', '' ); + + ?> +

            + +
            +
            + check_admin_setting( 'no_autop' ) ) echo ' checked'; ?> /> + +

            + + + + +

            +
            + has_editor_style(); + $disabled = ' disabled'; + + if ( $has_editor_style === false ) { + add_editor_style(); + $has_editor_style = $this->has_editor_style(); + } + + if ( $has_editor_style ) { + $disabled = ''; + } + + ?> +
            + check_admin_setting( 'importcss' ) ) echo ' checked'; echo $disabled; ?> /> + +

            + +

            + +

            + + +
            + +

            +
            +
            +

            +
            + check_admin_setting( 'table_resize_bars' ) ) echo ' checked'; ?> /> + +

            + + + +

            +

            + + +

            +

            + + +

            +
            +
            + check_admin_setting( 'table_default_attributes' ) ) echo ' checked'; ?> /> + +

            + +

            +
            +
            + check_admin_setting( 'table_grid' ) ) echo ' checked'; ?> /> + +

            + +

            +
            +
            + check_admin_setting( 'table_tab_navigation' ) ) echo ' checked'; ?> /> + +

            + +

            +
            +
            + check_admin_setting( 'table_advtab' ) ) echo ' checked'; ?> /> + +

            + +

            +

            + + +

            +
            +
            +
            + +
            +

            +
            +

            +

            + + +

            +

            + +   + +

            +
            +
            +

            +

            + check_admin_setting( 'enable_edit_post_screen' ) ) echo ' checked'; ?> /> + +

            +

            + check_admin_setting( 'enable_rest_of_wpadmin' ) ) echo ' checked'; ?> /> + +

            +

            + check_admin_setting( 'enable_on_front_end' ) ) echo ' checked'; ?> /> + +

            +
            +
            + +

            + + +

            + +
            + +

            + + + +

            +
            + +
            + +
            +
            diff --git a/html/wp-content/plugins/tinymce-advanced/tinymce-advanced.php b/html/wp-content/plugins/tinymce-advanced/tinymce-advanced.php new file mode 100644 index 0000000..8f7638b --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/tinymce-advanced.php @@ -0,0 +1,1181 @@ + 'menubar,advlist,menubar_block,merge_toolbars', + 'plugins' => 'anchor,code,insertdatetime,nonbreaking,print,searchreplace,table,visualblocks,visualchars,advlist,wptadv', + 'toolbar_1' => 'formatselect,bold,italic,blockquote,bullist,numlist,alignleft,aligncenter,alignright,link,unlink,undo,redo', + 'toolbar_2' => 'fontselect,fontsizeselect,outdent,indent,pastetext,removeformat,charmap,wp_more,forecolor,table,wp_help', + 'toolbar_3' => '', + 'toolbar_4' => '', + + 'toolbar_classic_block' => 'formatselect,bold,italic,blockquote,bullist,numlist,alignleft,aligncenter,alignright,' . + 'link,forecolor,backcolor,table,wp_help', + ); + } + + private function get_default_admin_settings() { + return array( + 'options' => 'classic_paragraph_block,table_resize_bars,table_grid,table_tab_navigation,table_advtab', + ); + } + + private function get_all_plugins() { + return array( + 'advlist', + 'anchor', + 'code', + 'contextmenu', + 'emoticons', + 'importcss', + 'insertdatetime', + 'link', + 'nonbreaking', + 'print', + 'searchreplace', + 'table', + 'visualblocks', + 'visualchars', + 'wptadv', + ); + } + + // Options are only "boolean"", array element exists or not. + private function get_all_user_options() { + return array( + 'advlist', + 'advlink', + 'contextmenu', + 'menubar', + 'menubar_block', + 'fontsize_formats', + 'merge_toolbars', + 'disable_richtext_buttons', + ); + } + + private function get_all_admin_options() { + return array( + 'importcss', + 'no_autop', + 'hybrid_mode', + 'classic_paragraph_block', + 'replace_block_editor', + 'table_resize_bars', + 'table_default_attributes', + 'table_grid', + 'table_tab_navigation', + 'table_advtab', + ); + } + + private function get_editor_locations() { + return array( + 'edit_post_screen', + 'rest_of_wpadmin', + 'on_front_end', + ); + } + + public function __construct() { + if ( is_admin() ) { + add_action( 'admin_menu', array( $this, 'add_menu' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) ); + add_filter( 'plugin_action_links', array( $this, 'add_settings_link' ), 10, 2 ); + add_action( 'before_wp_tiny_mce', array( $this, 'show_version_warning' ) ); + + add_action( 'admin_init', array( $this, 'import_export_settings_file' ) ); + add_action( 'plugins_loaded', array( $this, 'update_settings' ) ); + } + + add_filter( 'wp_editor_settings', array( $this, 'disable_for_editor' ), 10, 2 ); + + add_filter( 'mce_buttons', array( $this, 'mce_buttons_1' ), 999, 2 ); + add_filter( 'mce_buttons_2', array( $this, 'mce_buttons_2' ), 999, 2 ); + add_filter( 'mce_buttons_3', array( $this, 'mce_buttons_3' ), 999, 2 ); + add_filter( 'mce_buttons_4', array( $this, 'mce_buttons_4' ), 999, 2 ); + + add_filter( 'tiny_mce_before_init', array( $this, 'mce_options' ), 10, 2 ); + add_filter( 'mce_external_plugins', array( $this, 'mce_external_plugins' ), 999 ); + add_filter( 'tiny_mce_plugins', array( $this, 'tiny_mce_plugins' ), 999 ); + + add_action( 'enqueue_block_editor_assets', array( $this, 'block_editor_assets' ), 20 ); + add_action( 'init', array( $this, 'block_editor_init' ) ); + add_filter( 'wp_insert_post_data', array( $this, 'filter_post_content' ), 1 ); + + add_filter( 'excerpt_allowed_blocks', array( $this, 'excerpt_add_allowed_blocks' ) ); + } + + public function disable_for_editor( $settings, $editor_id ) { + static $editor_style_added = false; + + if ( empty( $this->admin_settings ) ) { + $this->load_settings(); + } + + $this->disabled_for_editor = false; + $this->editor_id = $editor_id; + + if ( ! empty( $this->admin_settings['disabled_editors'] ) ) { + $disabled_editors = explode( ',', $this->admin_settings['disabled_editors'] ); + $current_screen = isset( $GLOBALS['current_screen'] ) ? $GLOBALS['current_screen'] : new stdClass; + + if ( is_admin() ) { + if ( $editor_id === 'content' && ( $current_screen->id === 'post' || $current_screen->id === 'page' ) ) { + if ( in_array( 'edit_post_screen', $disabled_editors, true ) ) { + $this->disabled_for_editor = true; + } + } elseif ( in_array( 'rest_of_wpadmin', $disabled_editors, true ) ) { + $this->disabled_for_editor = true; + } + } elseif ( in_array( 'on_front_end', $disabled_editors, true ) ) { + $this->disabled_for_editor = true; + } + } + + if ( ! $this->disabled_for_editor && ! $editor_style_added ) { + if ( $this->check_admin_setting( 'importcss' ) && $this->has_editor_style() === false ) { + add_editor_style(); + } + + $editor_style_added = true; + } + + return $settings; + } + + private function is_disabled() { + return $this->disabled_for_editor; + } + + private function has_editor_style() { + if ( ! current_theme_supports( 'editor-style' ) ) { + return false; + } + + $editor_stylesheets = get_editor_stylesheets(); + + if ( is_array( $editor_stylesheets ) ) { + foreach ( $editor_stylesheets as $url ) { + if ( strpos( $url, 'editor-style.css' ) !== false ) { + return $url; + } + } + } + + return ''; + } + + public function load_textdomain() { + load_plugin_textdomain( 'tinymce-advanced', false, 'tinymce-advanced/langs' ); + } + + public function enqueue_scripts( $page ) { + if ( 'settings_page_tinymce-advanced' === $page ) { + $plugin_url = plugins_url( 'plugin-assets', __FILE__ ); + + wp_enqueue_style( 'tadv-css', $plugin_url . '/tadv.css', array( 'editor-buttons' ), $this->plugin_version ); + wp_enqueue_script( 'tadv-js', $plugin_url . '/tadv.js', array( 'jquery-ui-sortable' ), $this->plugin_version, true ); + wp_enqueue_style( 'tadv-mce-skin', includes_url( 'js/tinymce/skins/lightgray/skin.min.css' ), array(), $this->plugin_version ); + + add_action( 'admin_footer', array( $this, 'load_mce_translation' ) ); + } + } + + public function load_mce_translation() { + if ( ! class_exists( '_WP_Editors' ) ) { + require( ABSPATH . WPINC . '/class-wp-editor.php' ); + } + + ?> + + admin_settings ) ) { + $this->admin_settings = get_option( 'tadv_admin_settings', false ); + } + + if ( empty( $this->user_settings ) ) { + $this->user_settings = get_option( 'tadv_settings', false ); + } + + // load defaults if the options don't exist... + if ( $this->admin_settings === false ) { + $this->admin_settings = $this->get_default_admin_settings(); + } + + $this->admin_options = ! empty( $this->admin_settings['options'] ) ? explode( ',', $this->admin_settings['options'] ) : array(); + + $default_user_settings = $this->get_default_user_settings(); + + if ( $this->user_settings === false ) { + $this->user_settings = $default_user_settings; + } + + if ( empty( $this->user_settings['toolbar_1'] ) ) { + $this->user_settings['toolbar_1'] = $default_user_settings['toolbar_1']; + } + + if ( empty( $this->user_settings['toolbar_classic_block'] ) ) { + $this->user_settings['toolbar_classic_block'] = $default_user_settings['toolbar_classic_block']; + } + + $this->options = ! empty( $this->user_settings['options'] ) ? explode( ',', $this->user_settings['options'] ) : array(); + $this->plugins = ! empty( $this->user_settings['plugins'] ) ? explode( ',', $this->user_settings['plugins'] ) : array(); + $this->toolbar_1 = ! empty( $this->user_settings['toolbar_1'] ) ? explode( ',', $this->user_settings['toolbar_1'] ) : array(); + $this->toolbar_2 = ! empty( $this->user_settings['toolbar_2'] ) ? explode( ',', $this->user_settings['toolbar_2'] ) : array(); + $this->toolbar_3 = ! empty( $this->user_settings['toolbar_3'] ) ? explode( ',', $this->user_settings['toolbar_3'] ) : array(); + $this->toolbar_4 = ! empty( $this->user_settings['toolbar_4'] ) ? explode( ',', $this->user_settings['toolbar_4'] ) : array(); + + $this->toolbar_classic_block = ! empty( $this->user_settings['toolbar_classic_block'] ) ? explode( ',', $this->user_settings['toolbar_classic_block'] ) : array(); + + $this->used_buttons = array_merge( $this->toolbar_1, $this->toolbar_2, $this->toolbar_3, $this->toolbar_4, $this->toolbar_classic_block ); + $this->get_all_buttons(); + + // Force refresh after activation. + if ( ! empty( $GLOBALS['tinymce_version'] ) && strpos( $GLOBALS['tinymce_version'], '-tadv-' ) === false ) { + $GLOBALS['tinymce_version'] .= '-tadv-' . $this->plugin_version; + } + } + + public function show_version_warning() { + if ( is_admin() && current_user_can( 'update_plugins' ) && get_current_screen()->base === 'post' ) { + $this->warn_if_unsupported(); + } + } + + public function warn_if_unsupported() { + if ( ! $this->check_minimum_supported_version() ) { + $wp_version = ! empty( $GLOBALS['wp_version'] ) ? $GLOBALS['wp_version'] : '(undefined)'; + + ?> +

            + required_wp_version, + esc_html( $wp_version ) + ); + + echo '
            '; + + printf( + __( 'Please upgrade your WordPress installation or download an older version of the plugin.', 'tinymce-advanced' ), + 'https://wordpress.org/plugins/tinymce-advanced/advanced/#download-previous-link' + ); + + ?> +

            + required_wp_version, '>=' ) ); + } + + public function update_settings() { + $version = (int) get_option( 'tadv_version', 0 ); + + if ( $version >= $this->plugin_version ) { + return; + } + + if ( $version < 4000 ) { + // First install or upgrade to TinyMCE 4.0 + $this->user_settings = $this->get_default_user_settings(); + $this->admin_settings = $this->get_default_admin_settings(); + + update_option( 'tadv_settings', $this->user_settings ); + update_option( 'tadv_admin_settings', $this->admin_settings ); + update_option( 'tadv_version', $this->plugin_version ); + + // Clean out old options + delete_option('tadv_options'); + delete_option('tadv_toolbars'); + delete_option('tadv_plugins'); + delete_option('tadv_btns1'); + delete_option('tadv_btns2'); + delete_option('tadv_btns3'); + delete_option('tadv_btns4'); + delete_option('tadv_allbtns'); + + return; + } + + $admin_settings = get_option( 'tadv_admin_settings', false ); + $user_settings = get_option( 'tadv_settings', false ); + $user_defaults = $this->get_default_user_settings(); + + if ( $version < 5000 ) { + // Update for WP 5.0 + $admin_5000 = ! empty( $admin_settings['options'] ) ? $admin_settings['options'] : ''; + $user_5000 = ! empty( $user_settings['options'] ) ? $user_settings['options'] : ''; + + if ( empty( $admin_5000 ) ) { + $admin_5000 = 'hybrid_mode,classic_paragraph_block'; + } elseif ( strpos( $admin_5000, 'no_hybrid_mode' ) !== false ) { + $admin_5000 = str_replace( 'no_hybrid_mode', 'classic_paragraph_block', $admin_5000 ); + } else { + $admin_5000 .= ',hybrid_mode,classic_paragraph_block'; + } + + if ( empty( $user_5000 ) ) { + $user_5000 = 'menubar_block,merge_toolbars'; + } elseif ( strpos( $user_5000, 'no_merge_toolbars' ) !== false ) { + $user_5000 = str_replace( 'no_merge_toolbars', 'menubar_block', $user_5000 ); + } else { + $user_5000 .= ',menubar_block,merge_toolbars'; + } + + $admin_settings['options'] = $admin_5000; + $user_settings['options'] = $user_5000; + } + + if ( $version < 5200 ) { + // Update for 5.2, table options + if ( empty( $admin_settings ) || ! is_array( $admin_settings ) ) { + $admin_settings = array( + 'options' => 'table_resize_bars,table_grid,table_tab_navigation,table_advtab', + ); + } elseif ( empty( $admin_settings['options'] ) || ! is_string( $admin_settings['options'] ) ) { + $admin_settings['options'] = 'table_resize_bars,table_grid,table_tab_navigation,table_advtab'; + } else { + $admin_settings['options'] .= ',table_resize_bars,table_grid,table_tab_navigation,table_advtab'; + } + } + + update_option( 'tadv_admin_settings', $admin_settings ); + update_option( 'tadv_settings', $user_settings ); + + // Current version + update_option( 'tadv_version', $this->plugin_version ); + } + + public function get_all_buttons() { + if ( ! empty( $this->all_buttons ) ) { + return $this->all_buttons; + } + + $buttons = array( + // Core + 'bold' => 'Bold', + 'italic' => 'Italic', + 'underline' => 'Underline', + 'strikethrough' => 'Strikethrough', + 'alignleft' => 'Align left', + 'aligncenter' => 'Align center', + 'alignright' => 'Align right', + 'alignjustify' => 'Justify', + 'styleselect' => 'Formats', + 'formatselect' => 'Paragraph', + 'fontselect' => 'Font Family', + 'fontsizeselect' => 'Font Sizes', + 'cut' => 'Cut', + 'copy' => 'Copy', + 'paste' => 'Paste', + 'bullist' => 'Bulleted list', + 'numlist' => 'Numbered list', + 'outdent' => 'Decrease indent', + 'indent' => 'Increase indent', + 'blockquote' => 'Blockquote', + 'undo' => 'Undo', + 'redo' => 'Redo', + 'removeformat' => 'Clear formatting', + 'subscript' => 'Subscript', + 'superscript' => 'Superscript', + + // From plugins + 'hr' => 'Horizontal line', + 'link' => 'Insert/edit link', + 'unlink' => 'Remove link', + 'image' => 'Insert/edit image', + 'charmap' => 'Special character', + 'pastetext' => 'Paste as text', + 'print' => 'Print', + 'anchor' => 'Anchor', + 'searchreplace' => 'Find and replace', + 'visualblocks' => 'Show blocks', + 'visualchars' => 'Show invisible characters', + 'code' => 'Source code', + 'wp_code' => 'Code', + 'fullscreen' => 'Fullscreen', + 'insertdatetime' => 'Insert date/time', + 'media' => 'Insert/edit video', + 'nonbreaking' => 'Nonbreaking space', + 'table' => 'Table', + 'ltr' => 'Left to right', + 'rtl' => 'Right to left', + 'emoticons' => 'Emoticons', + 'forecolor' => 'Text color', + 'backcolor' => 'Background color', + + // WP + 'wp_adv' => 'Toolbar Toggle', + 'wp_help' => 'Keyboard Shortcuts', + 'wp_more' => 'Read more...', + 'wp_page' => 'Page break', + + 'tadv_mark' => 'Mark', + ); + + // add/remove allowed buttons + $buttons = apply_filters( 'tadv_allowed_buttons', $buttons ); + + $this->all_buttons = $buttons; + $this->buttons_filter = array_keys( $buttons ); + return $buttons; + } + + public function get_plugins( $plugins = array() ) { + + if ( ! is_array( $this->used_buttons ) ) { + $this->load_settings(); + } + + if ( in_array( 'anchor', $this->used_buttons, true ) ) + $plugins[] = 'anchor'; + + if ( in_array( 'visualchars', $this->used_buttons, true ) ) + $plugins[] = 'visualchars'; + + if ( in_array( 'visualblocks', $this->used_buttons, true ) ) + $plugins[] = 'visualblocks'; + + if ( in_array( 'nonbreaking', $this->used_buttons, true ) ) + $plugins[] = 'nonbreaking'; + + if ( in_array( 'emoticons', $this->used_buttons, true ) ) + $plugins[] = 'emoticons'; + + if ( in_array( 'insertdatetime', $this->used_buttons, true ) ) + $plugins[] = 'insertdatetime'; + + if ( in_array( 'table', $this->used_buttons, true ) ) + $plugins[] = 'table'; + + if ( in_array( 'print', $this->used_buttons, true ) ) + $plugins[] = 'print'; + + if ( in_array( 'searchreplace', $this->used_buttons, true ) ) + $plugins[] = 'searchreplace'; + + if ( in_array( 'code', $this->used_buttons, true ) ) + $plugins[] = 'code'; + + // From options + if ( $this->check_user_setting( 'advlist' ) ) + $plugins[] = 'advlist'; + + if ( $this->check_user_setting( 'advlink' ) ) + $plugins[] = 'link'; + + if ( $this->check_admin_setting( 'importcss' ) ) + $plugins[] = 'importcss'; + + if ( $this->check_user_setting( 'contextmenu' ) ) + $plugins[] = 'contextmenu'; + + // add/remove used plugins + $plugins = apply_filters( 'tadv_used_plugins', $plugins, $this->used_buttons ); + + return array_unique( $plugins ); + } + + private function check_user_setting( $setting ) { + if ( ! is_array( $this->options ) ) { + $this->load_settings(); + } + + // Back-compat for 'fontsize_formats' + if ( $setting === 'fontsize_formats' && $this->check_admin_setting( 'fontsize_formats' ) ) { + return true; + } + + return in_array( $setting, $this->options, true ); + } + + private function check_admin_setting( $setting ) { + if ( ! is_array( $this->admin_options ) ) { + $this->load_settings(); + } + + if ( strpos( $setting, 'enable_' ) === 0 ) { + $disabled_editors = ! empty( $this->admin_settings['disabled_editors'] ) ? explode( ',', $this->admin_settings['disabled_editors'] ) : array(); + return ! in_array( str_replace( 'enable_', '', $setting ), $disabled_editors ); + } + + return in_array( $setting, $this->admin_options, true ); + } + + public function mce_buttons_1( $original, $editor_id ) { + if ( $this->is_disabled() ) { + return $original; + } + + if ( ! is_array( $this->options ) ) { + $this->load_settings(); + } + + if ( $editor_id === 'classic-block' ) { + $buttons_1 = $this->toolbar_classic_block; + } else { + $buttons_1 = $this->toolbar_1; + } + + if ( is_array( $original ) && ! empty( $original ) ) { + $original = array_diff( $original, $this->buttons_filter ); + $buttons_1 = array_merge( $buttons_1, $original ); + } + + return $buttons_1; + } + + public function mce_buttons_2( $original, $editor_id ) { + if ( $this->is_disabled() ) { + return $original; + } + + if ( ! is_array( $this->options ) ) { + $this->load_settings(); + } + + if ( $editor_id === 'classic-block' ) { + $buttons_2 = array(); + } else { + $buttons_2 = $this->toolbar_2; + } + + if ( is_array( $original ) && ! empty( $original ) ) { + $original = array_diff( $original, $this->buttons_filter ); + $buttons_2 = array_merge( $buttons_2, $original ); + } + + return $buttons_2; + } + + public function mce_buttons_3( $original, $editor_id ) { + if ( $this->is_disabled() ) { + return $original; + } + + if ( ! is_array( $this->options ) ) { + $this->load_settings(); + } + + if ( $editor_id === 'classic-block' ) { + $buttons_3 = array(); + } else { + $buttons_3 = $this->toolbar_3; + } + + if ( is_array( $original ) && ! empty( $original ) ) { + $original = array_diff( $original, $this->buttons_filter ); + $buttons_3 = array_merge( $buttons_3, $original ); + } + + return $buttons_3; + } + + public function mce_buttons_4( $original, $editor_id ) { + if ( $this->is_disabled() ) { + return $original; + } + + if ( ! is_array( $this->options ) ) { + $this->load_settings(); + } + + if ( $editor_id === 'classic-block' ) { + $buttons_4 = array(); + } else { + $buttons_4 = $this->toolbar_4; + } + + if ( is_array( $original ) && ! empty( $original ) ) { + $original = array_diff( $original, $this->buttons_filter ); + $buttons_4 = array_merge( $buttons_4, $original ); + } + + return $buttons_4; + } + + public function mce_options( $init, $editor_id = '' ) { + if ( $this->is_disabled() ) { + return $init; + } + + $init['image_advtab'] = true; + $init['rel_list'] = '[{text: "None", value: ""}, {text: "Nofollow", value: "nofollow noreferrer"}]'; + // Prevent user errors. + $init['removed_menuitems'] = 'newdocument'; + + if ( $this->check_admin_setting( 'no_autop' ) ) { + $init['wpautop'] = false; + $init['indent'] = true; + $init['tadv_noautop'] = true; + } + + if ( $editor_id === 'classic-block' ) { + if ( $this->check_user_setting( 'menubar_block' ) ) { + $init['menubar'] = true; + } + + if ( + $this->check_user_setting( 'merge_toolbars' ) && + ! empty( $init['toolbar1'] ) && + is_string( $init['toolbar1'] ) + ) { + if ( ! empty( $init['toolbar2'] ) && is_string( $init['toolbar2'] ) ) { + $init['toolbar1'] = $init['toolbar1'] . ',' . $init['toolbar2']; + $init['toolbar2'] = ''; + } + if ( ! empty( $init['toolbar3'] ) && is_string( $init['toolbar3'] ) ) { + $init['toolbar1'] = $init['toolbar1'] . ',' . $init['toolbar3']; + $init['toolbar3'] = ''; + } + if ( ! empty( $init['toolbar4'] ) && is_string( $init['toolbar4'] ) ) { + $init['toolbar1'] = $init['toolbar1'] . ',' . $init['toolbar4']; + $init['toolbar4'] = ''; + } + } + } else { + if ( $this->check_user_setting( 'menubar' ) ) { + $init['menubar'] = true; + } + } + + if ( ! in_array( 'wp_adv', $this->toolbar_1, true ) ) { + $init['wordpress_adv_hidden'] = false; + } + + if ( $this->check_admin_setting( 'importcss' ) ) { + $init['importcss_file_filter'] = 'editor-style.css'; + } + + if ( $this->check_user_setting( 'fontsize_formats' ) ) { + $init['fontsize_formats'] = $this->fontsize_formats; + } + + if ( in_array( 'table', $this->plugins, true ) ) { + $init['table_toolbar'] = false; + + // Prefer percentage values + $init['table_responsive_width'] = true; + + if ( ! $this->check_admin_setting( 'table_resize_bars' ) ) { + $init['table_resize_bars'] = false; + $init['object_resizing'] = 'img'; + } + + if ( ! $this->check_admin_setting( 'table_default_attributes' ) ) { + $init['table_default_attributes'] = '{}'; + } + + if ( ! $this->check_admin_setting( 'table_grid' ) ) { + $init['table_grid'] = false; + } + + if ( ! $this->check_admin_setting( 'table_tab_navigation' ) ) { + $init['table_tab_navigation'] = false; + } + + if ( ! $this->check_admin_setting( 'table_advtab' ) ) { + $init['table_advtab'] = false; + $init['table_cell_advtab'] = false; + $init['table_row_advtab'] = false; + $init['table_appearance_options'] = false; + } + } + + return $init; + } + + public function block_editor_assets() { + $plugin_url = plugins_url( 'block-editor', __FILE__ ); + + if ( ! is_array( $this->admin_options ) ) { + $this->load_settings(); + } + + if ( $this->check_admin_setting( 'hybrid_mode' ) || $this->check_admin_setting( 'classic_paragraph_block' ) ) { + $strings = array(); + $dependencies = array( 'wp-element', 'wp-components', 'wp-i18n', 'wp-keycodes', 'wp-blocks', 'wp-edit-post', 'wp-hooks', 'lodash' ); + wp_enqueue_script( 'tadv-classic-paragraph', $plugin_url . '/classic-paragraph.js', $dependencies, $this->plugin_version ); + + if ( $this->check_admin_setting( 'classic_paragraph_block' ) ) { + $strings = array( + 'classicParagraphTitle' => __( 'Classic Paragraph', 'tinymce-advanced' ), + 'classicParagraph' => 'yes', + 'description' => __( 'For use instead of the Paragraph Block. Supports transforming to and from multiple Paragraph blocks, Image, Table, List, Quote, Custom HTML, and most other blocks.', 'tinymce-advanced' ), + ); + + wp_enqueue_style( 'tadv-classic-paragraph-styles', $plugin_url . '/classic-paragraph.css', array(), $this->plugin_version ); + } + + if ( $this->check_admin_setting( 'hybrid_mode' ) ) { + $strings['hybridMode'] = 'yes'; + } + + wp_localize_script( 'tadv-classic-paragraph', 'tadvBlockRegister', $strings ); + } + + // Block editor toolbars + if ( ! $this->check_user_setting( 'disable_richtext_buttons' ) ) { + $dependencies = array( 'wp-element', 'wp-components', 'wp-i18n', 'wp-editor', 'wp-rich-text' ); + wp_enqueue_script( 'tadv-block-buttons', $plugin_url . '/richtext-buttons.js', $dependencies, $this->plugin_version ); + + $strings = array( + 'strRemoveFormatting' => __( 'Clear formatting', 'tinymce-advanced' ), + 'strMark' => __( 'Mark', 'tinymce-advanced' ), + ); + + wp_localize_script( 'tadv-block-buttons', 'tadvBlockButtons', $strings ); + + wp_enqueue_style( 'tadv-block-buttons-styles', $plugin_url . '/richtext-buttons.css', array(), $this->plugin_version ); + } + + wp_enqueue_style( 'tadv-block-editor-styles', $plugin_url . '/tma-block-editor.css', array(), $this->plugin_version ); + } + + public function block_editor_init() { + if ( $this->check_admin_setting( 'replace_block_editor' ) && ! class_exists( 'Classic_Editor' ) ) { + add_filter( 'use_block_editor_for_post_type', '__return_false', 1000 ); + } + } + + public function filter_post_content( $data ) { + $content = $data['post_content']; + // Fix for the fix to keep

            tags inside the classic block :-( + // $data is slashed... + if ( strpos( $content, '

            ' ) !== false ) { + $content = str_replace( '

            ', '

            ', $content ); + } + + $data['post_content'] = $content; + return $data; + } + + // Excerpts can be generated from classic paragraph blocks + public function excerpt_add_allowed_blocks( $allowed_blocks ) { + // Make sure a plugin doesn't pass the wrong type here... + $allowed_blocks = (array) $allowed_blocks; + $allowed_blocks[] = 'tadv/classic-paragraph'; + return $allowed_blocks; + } + + public function mce_external_plugins( $mce_plugins ) { + if ( ! is_array( $this->options ) ) { + $this->load_settings(); + } + + if ( $this->is_disabled() ) { + return $mce_plugins; + } + + if ( ! is_array( $this->plugins ) ) { + $this->plugins = array(); + } + + $this->plugins[] = 'wptadv'; + + if ( $this->check_user_setting( 'menubar' ) || $this->check_user_setting( 'menubar_block' ) ) { + $this->plugins = array_merge( $this->plugins, $this->required_menubar_plugins ); + } + + $this->plugins = array_intersect( $this->plugins, $this->get_all_plugins() ); + + $plugin_url = plugins_url( 'mce/', __FILE__ ); + $mce_plugins = (array) $mce_plugins; + $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; + + foreach ( $this->plugins as $plugin ) { + $mce_plugins["$plugin"] = $plugin_url . $plugin . "/plugin{$suffix}.js"; + } + + return $mce_plugins; + } + + public function tiny_mce_plugins( $plugins ) { + if ( $this->is_disabled() ) { + return $plugins; + } + + if ( in_array( 'image', $this->used_buttons, true ) && ! in_array( 'image', $plugins, true ) ) { + $plugins[] = 'image'; + } + + if ( ( in_array( 'rtl', $this->used_buttons, true ) || in_array( 'ltr', $this->used_buttons, true ) ) && + ! in_array( 'directionality', (array) $plugins, true ) ) { + + $plugins[] = 'directionality'; + } + + return $plugins; + } + + private function parse_buttons( $toolbar_id = false, $buttons = false ) { + if ( $toolbar_id && ! $buttons && ! empty( $_POST[$toolbar_id] ) ) + $buttons = $_POST[$toolbar_id]; + + if ( is_array( $buttons ) ) { + $_buttons = array_map( array( @$this, 'filter_name' ), $buttons ); + return implode( ',', array_filter( $_buttons ) ); + } + + return ''; + } + + private function filter_name( $str ) { + if ( empty( $str ) || ! is_string( $str ) ) + return ''; + // Button names + return preg_replace( '/[^a-z0-9_]/i', '', $str ); + } + + private function sanitize_settings( $settings ) { + $_settings = array(); + + if ( ! is_array( $settings ) ) { + return $_settings; + } + + foreach( $settings as $name => $value ) { + $name = preg_replace( '/[^a-z0-9_]+/', '', $name ); + + if ( strpos( $name, 'toolbar_' ) === 0 ) { + $_settings[$name] = $this->parse_buttons( false, explode( ',', $value ) ); + } else if ( 'options' === $name || 'plugins' === $name || 'disabled_plugins' === $name ) { + $_settings[$name] = preg_replace( '/[^a-z0-9_,]+/', '', $value ); + } + } + + return $_settings; + } + + /** + * Validare array of settings against a whitelist. + * + * @param array $settings The settings. + * @param array $checklist The whitelist. + * @return string The validated settings CSV. + */ + private function validate_settings( $settings, $checklist ) { + if ( empty( $settings ) ) { + return ''; + } elseif ( is_string( $settings ) ) { + $settings = explode( ',', $settings ); + } elseif ( ! is_array( $settings ) ) { + return ''; + } + + $_settings = array(); + + foreach ( $settings as $value ) { + if ( in_array( $value, $checklist, true ) ) { + $_settings[] = $value; + } + } + + return implode( ',', $_settings ); + } + + private function save_settings( $all_settings = null ) { + $settings = $user_settings = array(); + $default_settings = $this->get_default_user_settings(); + + if ( empty( $this->buttons_filter ) ) { + $this->get_all_buttons(); + } + + if ( ! empty( $all_settings['settings'] ) ) { + $user_settings = $all_settings['settings']; + } + + for ( $i = 1; $i < 6; $i++ ) { + $toolbar_name = ( $i < 5 ) ? 'toolbar_' . $i : 'toolbar_classic_block'; + + if ( ! empty( $user_settings[ $toolbar_name ] ) ) { + $toolbar = explode( ',', $user_settings[ $toolbar_name ] ); + } elseif ( ! empty( $_POST[ $toolbar_name ] ) && is_array( $_POST[ $toolbar_name ] ) ) { + $toolbar = $_POST[ $toolbar_name ]; + } else { + $toolbar = array(); + } + + if ( $i > 1 && in_array( 'wp_adv', $toolbar, true ) ) { + $toolbar = array_diff( $toolbar, array( 'wp_adv' ) ); + } + + $settings[ $toolbar_name ] = $this->validate_settings( $toolbar, $this->buttons_filter ); + } + + if ( ! empty( $user_settings['options'] ) ) { + $options = explode( ',', $user_settings['options'] ); + } elseif ( ! empty( $_POST['options'] ) && is_array( $_POST['options'] ) ) { + $options = $_POST['options']; + + if ( ! empty( $_POST['richtext_buttons'] ) && $_POST['richtext_buttons'] === 'no' ) { + $options[] = 'disable_richtext_buttons'; + } + } else { + $options = array(); + } + + $settings['options'] = $this->validate_settings( $options, $this->get_all_user_options() ); + + if ( ! empty( $user_settings['plugins'] ) ) { + $plugins = explode( ',', $user_settings['plugins'] ); + } else { + $plugins = array(); + } + + if ( ! empty( $settings['options']['menubar'] ) || ! empty( $settings['options']['menubar_block'] ) ) { + $plugins = array_merge( $plugins, $this->required_menubar_plugins ); + } + + // Merge the submitted plugins with plugins needed for the buttons. + $this->user_settings = $settings; + $this->load_settings(); + $plugins = $this->get_plugins( $plugins ); + + $settings['plugins'] = $this->validate_settings( $plugins, $this->get_all_plugins() ); + + $this->user_settings = $settings; + $this->load_settings(); + + // Save the new settings. + update_option( 'tadv_settings', $settings ); + + if ( ! is_multisite() || current_user_can( 'manage_sites' ) ) { + $this->save_admin_settings( $all_settings ); + } + } + + private function save_admin_settings( $all_settings = null ) { + $admin_settings = $save_admin_settings = array(); + + if ( ! empty( $all_settings['admin_settings'] ) ) { + $admin_settings = $all_settings['admin_settings']; + } + + if ( ! empty( $admin_settings ) ) { + if ( ! empty( $admin_settings['options'] ) ) { + $save_admin_settings['options'] = $this->validate_settings( $admin_settings['options'], $this->get_all_admin_options() ); + } else { + $save_admin_settings['options'] = ''; + } + + $disabled_editors = array_intersect( $this->get_editor_locations(), explode( ',', $admin_settings['disabled_editors'] ) ); + } elseif ( isset( $_POST['tadv-save'] ) ) { + if ( ! empty( $_POST['admin_options'] ) && is_array( $_POST['admin_options'] ) ) { + $save_admin_settings['options'] = $this->validate_settings( $_POST['admin_options'], $this->get_all_admin_options() ); + } + + if ( ! empty( $_POST['tadv_enable_at'] ) && is_array( $_POST['tadv_enable_at'] ) ) { + $tadv_enable_at = $_POST['tadv_enable_at']; + } else { + $tadv_enable_at = array(); + } + + $disabled_editors = array_diff( $this->get_editor_locations(), $tadv_enable_at ); + } else { + return; + } + + $save_admin_settings['disabled_editors'] = implode( ',', $disabled_editors ); + + $this->admin_settings = $save_admin_settings; + update_option( 'tadv_admin_settings', $save_admin_settings ); + } + + private function import_from_file() { + if ( empty( $_FILES['tadv-import']['name'] ) ) { + return 1; + } + + $file_type = wp_check_filetype( $_FILES['tadv-import']['name'], array( 'json' => 'application/json' ) ); + + if ( $file_type['ext'] !== 'json' ) { + return 1; + } + + $settings = @file_get_contents( $_FILES['tadv-import']['tmp_name'] ); + + if ( empty( $settings ) ) { + return 2; + } + + $settings = json_decode( $settings, true ); + + if ( ! is_array( $settings ) ) { + return 3; + } + + $this->save_settings( $settings ); + return 0; + } + + public function import_export_settings_file() { + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + + if ( + isset( $_POST['tadv-import-file'] ) && + isset( $_POST['tadv-import-settings-nonce'] ) && + wp_verify_nonce( $_POST['tadv-import-settings-nonce'], 'tadv-import-settings' ) + ) { + $err = $this->import_from_file(); + $url = admin_url( 'options-general.php?page=tinymce-advanced' ); + $url = add_query_arg( 'tadv-import-file-complete', $err, $url ); + + wp_safe_redirect( $url ); + exit; + } elseif ( + isset( $_POST['tadv-export-settings'] ) && + isset( $_POST['tadv-export-settings-nonce'] ) && + wp_verify_nonce( $_POST['tadv-export-settings-nonce'], 'tadv-export-settings' ) + ) { + $this->load_settings(); + $output = array( 'settings' => $this->user_settings ); + + // TODO: only admin || SA + $output['admin_settings'] = $this->admin_settings; + + $sitename = get_bloginfo( 'name' ); + + if ( mb_strlen( $sitename ) > 100 ) { + $sitename = mb_substr( $sitename, 0, 100 ); + } + + $sitename = preg_replace( '/[ \.-]+/', '-', $sitename ); + + $date = date( 'Y-m-d' ); + $filename = sanitize_file_name( $sitename . '-TMA-settings-' . $date . '.json' ); + + nocache_headers(); + header( 'Content-Type: application/json; charset=utf-8' ); + header( "Content-Disposition: attachment; filename=$filename" ); + + echo wp_json_encode( $output ); + exit; + } + } + + public function settings_page() { + if ( ! defined( 'TADV_ADMIN_PAGE' ) ) { + define( 'TADV_ADMIN_PAGE', true ); + } + + include_once( plugin_dir_path( __FILE__ ) . 'tadv_admin.php' ); + } + + public function add_menu() { + $page_title = __( 'Advanced Editor Tools', 'tinymce-advanced' ); + $menu_item_label = __( 'Advanced Editor Tools', 'tinymce-advanced' ); + add_options_page( $page_title, $menu_item_label, 'manage_options', 'tinymce-advanced', array( $this, 'settings_page' ) ); + } + + /** + * Add a link to the settings page + */ + public function add_settings_link( $links, $file ) { + if ( + strrpos( $file, '/tinymce-advanced.php' ) === ( strlen( $file ) - 21 ) && + current_user_can( 'manage_options' ) + ) { + $settings_link = sprintf( '%s', admin_url( 'options-general.php?page=tinymce-advanced' ), __( 'Settings', 'tinymce-advanced' ) ); + $links = (array) $links; + $links['tma_settings_link'] = $settings_link; + } + + return $links; + } +} + +new Advanced_Editor_Tools; +endif; diff --git a/html/wp-content/plugins/tinymce-advanced/uninstall.php b/html/wp-content/plugins/tinymce-advanced/uninstall.php new file mode 100644 index 0000000..cdeb26e --- /dev/null +++ b/html/wp-content/plugins/tinymce-advanced/uninstall.php @@ -0,0 +1,28 @@ +Writing page. +* When activating the plugin for the first time, all post types are set to have the ability to disable the wpautop filter. This can be changed on the Settings->Writing page. +* Adding an uninstall hook to remove all traces of the plugin. + +## 1.0 ## +* Hello world! diff --git a/html/wp-content/plugins/toggle-wpautop/FAQ.md b/html/wp-content/plugins/toggle-wpautop/FAQ.md new file mode 100644 index 0000000..afadeba --- /dev/null +++ b/html/wp-content/plugins/toggle-wpautop/FAQ.md @@ -0,0 +1,10 @@ +# Frequently Asked Questions # + +## Can I disable wpautop completely with this plugin? ## + +Right now, no. wpautop is a great filter, and in most cases you should not need it disabled globally. However, if there is enough demand for this feature we can add it. + +## Can I set wpautop to default to "off" for new posts. + +Yes. +## diff --git a/html/wp-content/plugins/toggle-wpautop/LICENSE b/html/wp-content/plugins/toggle-wpautop/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/html/wp-content/plugins/toggle-wpautop/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/html/wp-content/plugins/toggle-wpautop/README.md b/html/wp-content/plugins/toggle-wpautop/README.md new file mode 100644 index 0000000..f4ada7f --- /dev/null +++ b/html/wp-content/plugins/toggle-wpautop/README.md @@ -0,0 +1,35 @@ +![Toggle wpautop](https://github.com/linchpin/toggle-wpautop/blob/master/.wordpress-org/banner-1544x500.png?raw=true) + +![Build Status](https://github.com/linchpin/toggle-wpautop/workflows/Deploy%20to%20WordPress.org/badge.svg) ![Maintainability](https://codeclimate.com/github/linchpin/toggle-wpautop/maintainability) + +# Toggle wpautop # + +Easily disable the default wpautop filter on a post by post basis. + + + +## Description ## + +**Note: This plugin does not support the block editor but should continue to work without issue when using it with custom post types and the [Classic Editor Plugin](https://wordpress.org/plugins/classic-editor/).** + +Before WordPress displays a post's content, the content gets passed through multiple filters to ensure that it safely appears how you enter it within the editor. + +One of these filters is [wpautop](http://codex.wordpress.org/Function_Reference/wpautop "wpautop"), which replaces double line breaks with `

            ` tags, and single line breaks with `
            ` tags. However, this filter sometimes causes issues when you are inputting a lot of HTML markup in the post editor. + +This plugin displays a checkbox in the publish meta box of the post edit screen that disables the [wpautop](http://codex.wordpress.org/Function_Reference/wpautop "wpautop") filter for that post. + +Also adds a 'wpautop', or 'no-wpautop' class to the post_class filter to help with CSS styling. + +## Installation ## + +1. Upload the plugin folder to the `/wp-content/plugins/` directory +2. Activate the plugin through the 'Plugins' menu in WordPress +3. Proceed to the Settings->Writing and select which post types should have the option to disable the wpautop filter. + + +## Screenshots ## + +1. The disable wpautop checkbox on post edit screens. +2. Settings->Writing page with plugin settings. + +![Linchpin](https://github.com/linchpin/brand-assets/blob/master/github-opensource-banner.png?raw=true) diff --git a/html/wp-content/plugins/toggle-wpautop/package.json b/html/wp-content/plugins/toggle-wpautop/package.json new file mode 100644 index 0000000..5c8c3a0 --- /dev/null +++ b/html/wp-content/plugins/toggle-wpautop/package.json @@ -0,0 +1,66 @@ +{ + "name": "toggle-wpautop", + "version": "1.3.0", + "description": "Easily disable the default WordPress wpautop filter on a post by post basis.", + "main": "gulpfile.babel.js", + "scripts": { + "start": "gulp", + "build": "gulp build:release --production --release", + "gulp readme": "gulp readme", + "gulp release": "gulp build:release --production --release=2.2.0" + }, + "author": "Linchpin ", + "license": "GPL", + "dependencies": { + "save-dev": "^0.0.1-security" + }, + "devDependencies": { + "@babel/core": "7.7.7", + "@babel/preset-env": "7.7.7", + "@babel/register": "7.7.7", + "autoprefixer": "9.7.3", + "babel-loader": "8.0.6", + "gulp": "4.0.2", + "gulp-babel": "8.0.0", + "gulp-bump": "3.1.3", + "gulp-cli": "2.2.0", + "gulp-concat": "2.6.1", + "gulp-extname": "0.2.2", + "gulp-if": "3.0.0", + "gulp-load-plugins": "1.6.0", + "gulp-readme-to-markdown": "0.2.1", + "gulp-replace": "^1.0.0", + "gulp-sourcemaps": "2.6.5", + "gulp-footer": "^2.0.2", + "gulp-header": "^2.0.9", + "gulp-uglify": "3.0.2", + "js-yaml": "3.13.1", + "rimraf": "2.7.1", + "through2": "^3.0.1", + "vinyl-named": "1.1.0", + "webpack": "4.41.3", + "webpack-stream": "5.2.1", + "yargs": "12.0.5" + }, + "resolutions": { + "lodash.template": "^4.5.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/linchpin/toggle-wpautop.git" + }, + "bugs": { + "url": "https://github.com/linchpin/toggle-wpautop/issues", + "email": "sayhi@linchpin.com" + }, + "engines": { + "node": ">= 10.13.0" + }, + "private": true, + "browserslist": [ + "last 1 version", + "> 1%", + "maintained node versions", + "not dead" + ] +} diff --git a/html/wp-content/plugins/toggle-wpautop/readme.txt b/html/wp-content/plugins/toggle-wpautop/readme.txt new file mode 100644 index 0000000..1f4812c --- /dev/null +++ b/html/wp-content/plugins/toggle-wpautop/readme.txt @@ -0,0 +1,93 @@ +=== Toggle wpautop === +Contributors: linchpin_agency, aware, desrosj +Tags: wpautop, formatting, post content, excerpt, editor, custom post types, filters, add_filter +Requires at least: 3.0 +Tested up to: 5.7 +Stable tag: 1.3.0 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +Easily disable the default wpautop filter on a post by post basis. + +![Linchpin](https://github.com/linchpin/brand-assets/blob/master/github-opensource-banner.png) + + +== Description == + +**Note: This plugin does not support the block editor but should continue to work without issue when using it with custom post types and the [Classic Editor Plugin](https://wordpress.org/plugins/classic-editor/).** + +Before WordPress displays a post's content, the content gets passed through multiple filters to ensure that it safely appears how you enter it within the editor. + +One of these filters is [wpautop](http://codex.wordpress.org/Function_Reference/wpautop "wpautop"), which replaces double line breaks with `

            ` tags, and single line breaks with `
            ` tags. However, this filter sometimes causes issues when you are inputting a lot of HTML markup in the post editor. + +This plugin displays a checkbox in the publish meta box of the post edit screen that disables the [wpautop](http://codex.wordpress.org/Function_Reference/wpautop "wpautop") filter for that post. + +Also adds a 'wpautop', or 'no-wpautop' class to the post_class filter to help with CSS styling. + +== Installation == + +1. Upload the plugin folder to the `/wp-content/plugins/` directory +2. Activate the plugin through the 'Plugins' menu in WordPress +3. Proceed to the Settings->Writing and select which post types should have the option to disable the wpautop filter. + +== Frequently Asked Questions == + += Can I disable wpautop completely with this plugin? = + +Right now, no. wpautop is a great filter, and in most cases you should not need it disabled globally. However, if there is enough demand for this feature we can add it. + += Can I set wpautop to default to "off" for new posts. + +Yes. + +== Screenshots == + +1. The disable wpautop checkbox on post edit screens. +2. Settings->Writing page with plugin settings. + +== Changelog == + += 1.3.0 = +* Fixed minor sanitization of within the admin +* Fixed minor WPCS and PHPCS notices +* Updated plugin branding for .org +* Updated readme to link to the Classic Editor Plugin +* Updated deployment process to make releases easier + += 1.2.5 = +* Fixing an issue where http://translate.wordpress.org did not detect the stable version correctly. + += 1.2.4 = +* A few additional steps to make the plugin accessible to http://translate.wordpress.org. + += 1.2.3 = +* Move translations to http://translate.wordpress.org. + += 1.2.2 = +* Fixing PHP syntax error. + += 1.2.1 = +* Added ability for i18n using grunt-wp-i18n +* Added english default .pot +* Added minor security hardening so the class file would exit if called directly +* Updated code formatting to be more inline with WordPress coding standards +* Updated some method descriptions +* Updated plugin description to be more... descriptive. + += 1.2.0 = +* Add a setting to disable wpautop automatically on new posts. +* Add filter (lp_wpautop_show_private_pt) for enabling the plugin on private post types. + += 1.1.2 = +* Fixing bug that was preventing other settings on the writing page from saving. + += 1.1.1 = +* Fixing bug where users upgrading from 1.0 would not receive the defaults for settings that were introduced in 1.1. + += 1.1 = +* Adding the ability to choose which post types have the option to disable the wpautop filter on the Settings->Writing page. +* When activating the plugin for the first time, all post types are set to have the ability to disable the wpautop filter. This can be changed on the Settings->Writing page. +* Adding an uninstall hook to remove all traces of the plugin. + += 1.0 = +* Hello world! diff --git a/html/wp-content/plugins/toggle-wpautop/toggle-wpautop.php b/html/wp-content/plugins/toggle-wpautop/toggle-wpautop.php new file mode 100644 index 0000000..1165e00 --- /dev/null +++ b/html/wp-content/plugins/toggle-wpautop/toggle-wpautop.php @@ -0,0 +1,354 @@ +public ) { + continue; + } + + $default_post_types[] = $post_type; + } + + if ( ! empty( $default_post_types ) ) { + add_option( 'lp_toggle_wpautop_settings', $default_post_types ); + } + } + + /** + * Load the plugin text domain. + */ + public function plugins_loaded() { + load_plugin_textdomain( 'toggle-wpautop', false, basename( dirname( __FILE__ ) ) . '/languages/' ); + } + + /** + * Add our settings fields to the writing page + * + * @access public + * @return void + */ + public function admin_init() { + register_setting( 'writing', 'lp_toggle_wpautop_settings', array( $this, 'sanitize_settings' ) ); + register_setting( 'writing', 'lp_toggle_wpautop_auto' ); + + // Add a section for the plugin's settings on the writing page. + add_settings_section( 'lp_toggle_wpautop_settings_section', __( 'Toggle wpautop', 'toggle-wpautop' ), array( $this, 'settings_section_text' ), 'writing' ); + + // For each post type add a settings field, excluding revisions and nav menu items. + if ( $post_types = get_post_types() ) { // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.Found, Squiz.PHP.DisallowMultipleAssignments.Found + + add_settings_field( 'lp_toggle_wpautop_auto', esc_html__( 'Auto Enable', 'toggle-wpautop' ), array( $this, 'toggle_wpautop_auto_field' ), 'writing', 'lp_toggle_wpautop_settings_section' ); + + $show_private_post_types = apply_filters( 'lp_wpautop_show_private_pt', false ); + + foreach ( $post_types as $post_type ) { + $post_type_object = get_post_type_object( $post_type ); + + if ( in_array( $post_type, array( 'revision', 'nav_menu_item', 'attachment' ), true ) || ( ! $show_private_post_types && ! $post_type_object->public ) ) { + continue; + } + + add_settings_field( + 'lp_toggle_wpautop_post_types' . $post_type, + $post_type_object->labels->name, + array( $this, 'toggle_wpautop_field' ), + 'writing', + 'lp_toggle_wpautop_settings_section', + array( + 'slug' => $post_type_object->name, + 'name' => $post_type_object->labels->name, + ) + ); + } + } + } + + /** + * Display our settings section + * + * @access public + * @return void + */ + public function settings_section_text() { + ?> +

            + +

            + + /> + + + /> + action ) && 'add' === $screen->action && get_option( 'lp_toggle_wpautop_auto', 0 ) ) { + $checked = true; + } else { + $checked = get_post_meta( $post->ID, '_lp_disable_wpautop', true ); + } + + ?> +
            + : /> ? +
            + ID, '_lp_disable_wpautop', true ) ) { + remove_filter( 'the_content', 'wpautop' ); + remove_filter( 'the_excerpt', 'wpautop' ); + } else { + if ( ! has_filter( 'the_content', 'wpautop' ) ) { + add_filter( 'the_content', 'wpautop' ); + } + + if ( ! has_filter( 'the_excerpt', 'wpautop' ) ) { + add_filter( 'the_excerpt', 'wpautop' ); + } + } + } + + /** + * After we run our loop, everything should be set back to normal + * + * @access public + * @return void + */ + public function loop_end() { + if ( ! has_filter( 'the_content', 'wpautop' ) ) { + add_filter( 'the_content', 'wpautop' ); + } + + if ( ! has_filter( 'the_excerpt', 'wpautop' ) ) { + add_filter( 'the_excerpt', 'wpautop' ); + } + } + + /** + * Add a class to posts noting whether they were passed through the wpautop filter + * + * @param mixed $classes Array of Post Classes. + * @param mixed $class Current Class. + * @param int $post_id Post ID. + * + * @return array + */ + public function post_class( $classes, $class, $post_id ) { + if ( get_post_meta( $post_id, '_lp_disable_wpautop', true ) ) { + $classes[] = 'no-wpautop'; + } else { + $classes[] = 'wpautop'; + } + + return $classes; + } + } +} + +$lp_toggle_wpautop = new LP_Toggle_wpautop(); + +/** + * Delete everything created by the plugin + * + * @access public + * @return void + */ +function toggle_wpautop_uninstall() { + // Delete post meta entries. + delete_post_meta_by_key( '_lp_disable_wpautop' ); + + // Delete settings. + delete_option( 'lp_toggle_wpautop_settings' ); +} + +register_uninstall_hook( __FILE__, 'toggle_wpautop_uninstall' ); diff --git a/html/wp-content/plugins/wordpress-seo/admin/admin-settings-changed-listener.php b/html/wp-content/plugins/wordpress-seo/admin/admin-settings-changed-listener.php new file mode 100644 index 0000000..712c544 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/admin-settings-changed-listener.php @@ -0,0 +1,89 @@ +helpers->current_page->is_yoast_seo_page() ) { + return; + } + + // Variable name is the same as the global that is set by get_settings_errors. + $wp_settings_errors = get_settings_errors(); + + foreach ( $wp_settings_errors as $key => $wp_settings_error ) { + if ( ! $this->is_settings_updated_notification( $wp_settings_error ) ) { + continue; + } + + self::$settings_saved = true; + unset( $wp_settings_errors[ $key ] ); + // phpcs:ignore WordPress.WP.GlobalVariablesOverride -- Overwrite the global with the list excluding the Changed saved message. + $GLOBALS['wp_settings_errors'] = $wp_settings_errors; + break; + } + } + + /** + * Checks whether the settings notification is a settings_updated notification. + * + * @param array $wp_settings_error The settings object. + * + * @return bool Whether this is a settings updated settings notification. + */ + public function is_settings_updated_notification( $wp_settings_error ) { + return ! empty( $wp_settings_error['code'] ) && $wp_settings_error['code'] === 'settings_updated'; + } + + /** + * Get whether the settings have successfully been saved + * + * @return bool Whether the settings have successfully been saved. + */ + public function have_settings_been_saved() { + return self::$settings_saved; + } + + /** + * Renders a success message if the Yoast SEO settings have been saved. + * + * @return void + */ + public function show_success_message() { + if ( $this->have_settings_been_saved() ) { + echo '

            ', + esc_html__( 'Settings saved.', 'wordpress-seo' ), + '

            '; + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/ajax.php b/html/wp-content/plugins/wordpress-seo/admin/ajax.php new file mode 100644 index 0000000..c9ac45d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/ajax.php @@ -0,0 +1,411 @@ + 'success', + 'post_id' => $post_id, + "new_{$return_key}" => $sanitized_new_meta_value, + "original_{$return_key}" => $orig_meta_value, + ]; + + $the_post = get_post( $post_id ); + if ( empty( $the_post ) ) { + + $upsert_results['status'] = 'failure'; + $upsert_results['results'] = __( 'Post doesn\'t exist.', 'wordpress-seo' ); + + return $upsert_results; + } + + $post_type_object = get_post_type_object( $the_post->post_type ); + if ( ! $post_type_object ) { + + $upsert_results['status'] = 'failure'; + $upsert_results['results'] = sprintf( + /* translators: %s expands to post type. */ + __( 'Post has an invalid Content Type: %s.', 'wordpress-seo' ), + $the_post->post_type, + ); + + return $upsert_results; + } + + if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) { + + $upsert_results['status'] = 'failure'; + $upsert_results['results'] = sprintf( + /* translators: %s expands to post type name. */ + __( 'You can\'t edit %s.', 'wordpress-seo' ), + $post_type_object->label, + ); + + return $upsert_results; + } + + if ( ! current_user_can( $post_type_object->cap->edit_others_posts ) && (int) $the_post->post_author !== get_current_user_id() ) { + + $upsert_results['status'] = 'failure'; + $upsert_results['results'] = sprintf( + /* translators: %s expands to the name of a post type (plural). */ + __( 'You can\'t edit %s that aren\'t yours.', 'wordpress-seo' ), + $post_type_object->label, + ); + + return $upsert_results; + } + + if ( $sanitized_new_meta_value === $orig_meta_value && $sanitized_new_meta_value !== $new_meta_value ) { + $upsert_results['status'] = 'failure'; + $upsert_results['results'] = __( 'You have used HTML in your value which is not allowed.', 'wordpress-seo' ); + + return $upsert_results; + } + + $res = update_post_meta( $post_id, $meta_key, $sanitized_new_meta_value ); + + $upsert_results['status'] = ( $res !== false ) ? 'success' : 'failure'; + $upsert_results['results'] = $res; + + return $upsert_results; +} + +/** + * Save all titles sent from the Bulk Editor. + * + * @return void + */ +function wpseo_save_all_titles() { + wpseo_save_all( 'title' ); +} + +add_action( 'wp_ajax_wpseo_save_all_titles', 'wpseo_save_all_titles' ); + +/** + * Save all description sent from the Bulk Editor. + * + * @return void + */ +function wpseo_save_all_descriptions() { + wpseo_save_all( 'metadesc' ); +} + +add_action( 'wp_ajax_wpseo_save_all_descriptions', 'wpseo_save_all_descriptions' ); + +/** + * Utility function to save values. + * + * @param string $what Type of item so save. + * + * @return void + */ +function wpseo_save_all( $what ) { + check_ajax_referer( 'wpseo-bulk-editor' ); + + $results = []; + if ( ! isset( $_POST['items'], $_POST['existingItems'] ) ) { + wpseo_ajax_json_echo_die( $results ); + } + + $new_values = array_map( [ 'WPSEO_Utils', 'sanitize_text_field' ], wp_unslash( (array) $_POST['items'] ) ); + $original_values = array_map( [ 'WPSEO_Utils', 'sanitize_text_field' ], wp_unslash( (array) $_POST['existingItems'] ) ); + + foreach ( $new_values as $post_id => $new_value ) { + $original_value = $original_values[ $post_id ]; + $results[] = wpseo_upsert_new( $what, $post_id, $new_value, $original_value ); + } + + wpseo_ajax_json_echo_die( $results ); +} + +/** + * Insert a new value. + * + * @param string $what Item type (such as title). + * @param int $post_id Post ID. + * @param string $new_value New value to record. + * @param string $original Original value. + * + * @return string + */ +function wpseo_upsert_new( $what, $post_id, $new_value, $original ) { + $meta_key = WPSEO_Meta::$meta_prefix . $what; + + return wpseo_upsert_meta( $post_id, $new_value, $original, $meta_key, $what ); +} + +/** + * Retrieves the post ids where the keyword is used before as well as the types of those posts. + * + * @return void + */ +function ajax_get_keyword_usage_and_post_types() { + check_ajax_referer( 'wpseo-keyword-usage-and-post-types', 'nonce' ); + + if ( ! isset( $_POST['post_id'], $_POST['keyword'] ) || ! is_string( $_POST['keyword'] ) ) { + exit( '-1' ); + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We are casting to an integer. + $post_id = (int) wp_unslash( $_POST['post_id'] ); + + if ( $post_id === 0 || ! current_user_can( 'edit_post', $post_id ) ) { + exit( '-1' ); + } + + $keyword = sanitize_text_field( wp_unslash( $_POST['keyword'] ) ); + + $post_ids = WPSEO_Meta::keyword_usage( $keyword, $post_id ); + + $return_object = [ + 'keyword_usage' => $post_ids, + 'post_types' => WPSEO_Meta::post_types_for_ids( $post_ids ), + ]; + + wp_die( + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe. + WPSEO_Utils::format_json_encode( $return_object ), + ); +} + +add_action( 'wp_ajax_get_focus_keyword_usage_and_post_types', 'ajax_get_keyword_usage_and_post_types' ); + +/** + * Retrieves the keyword for the keyword doubles of the termpages. + * + * @return void + */ +function ajax_get_term_keyword_usage() { + check_ajax_referer( 'wpseo-keyword-usage', 'nonce' ); + + if ( ! isset( $_POST['post_id'], $_POST['keyword'], $_POST['taxonomy'] ) || ! is_string( $_POST['keyword'] ) || ! is_string( $_POST['taxonomy'] ) ) { + wp_die( -1 ); + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are casting the unsafe input to an integer. + $post_id = (int) wp_unslash( $_POST['post_id'] ); + + if ( $post_id === 0 ) { + wp_die( -1 ); + } + + $keyword = sanitize_text_field( wp_unslash( $_POST['keyword'] ) ); + $taxonomy_name = sanitize_text_field( wp_unslash( $_POST['taxonomy'] ) ); + + $taxonomy = get_taxonomy( $taxonomy_name ); + + if ( ! $taxonomy ) { + wp_die( 0 ); + } + + if ( ! current_user_can( $taxonomy->cap->edit_terms ) ) { + wp_die( -1 ); + } + + $usage = WPSEO_Taxonomy_Meta::get_keyword_usage( $keyword, $post_id, $taxonomy_name ); + + // Normalize the result so it is the same as the post keyword usage AJAX request. + $usage = $usage[ $keyword ]; + + wp_die( + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe. + WPSEO_Utils::format_json_encode( $usage ), + ); +} + +add_action( 'wp_ajax_get_term_keyword_usage', 'ajax_get_term_keyword_usage' ); + +/** + * Registers hooks for all AJAX integrations. + * + * @return void + */ +function wpseo_register_ajax_integrations() { + $integrations = [ new Yoast_Network_Admin() ]; + + foreach ( $integrations as $integration ) { + $integration->register_ajax_hooks(); + } +} + +wpseo_register_ajax_integrations(); + +new WPSEO_Shortcode_Filter(); + +new WPSEO_Taxonomy_Columns(); + +/* ********************* DEPRECATED FUNCTIONS ********************* */ + +/** + * Retrieves the keyword for the keyword doubles. + * + * @return void + */ +function ajax_get_keyword_usage() { + _deprecated_function( __METHOD__, 'WPSEO 20.4' ); + check_ajax_referer( 'wpseo-keyword-usage', 'nonce' ); + + if ( ! isset( $_POST['post_id'], $_POST['keyword'] ) || ! is_string( $_POST['keyword'] ) ) { + exit( '-1' ); + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We are casting to an integer. + $post_id = (int) wp_unslash( $_POST['post_id'] ); + + if ( $post_id === 0 || ! current_user_can( 'edit_post', $post_id ) ) { + exit( '-1' ); + } + + $keyword = sanitize_text_field( wp_unslash( $_POST['keyword'] ) ); + + wp_die( + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe. + WPSEO_Utils::format_json_encode( WPSEO_Meta::keyword_usage( $keyword, $post_id ) ), + ); +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/ajax/class-shortcode-filter.php b/html/wp-content/plugins/wordpress-seo/admin/ajax/class-shortcode-filter.php new file mode 100644 index 0000000..c9f5f3d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/ajax/class-shortcode-filter.php @@ -0,0 +1,54 @@ + $shortcode, + 'output' => do_shortcode( $shortcode ), + ]; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: WPSEO_Utils::format_json_encode is considered safe. + wp_die( WPSEO_Utils::format_json_encode( $parsed_shortcodes ) ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-dismissable-notice.php b/html/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-dismissable-notice.php new file mode 100644 index 0000000..c847ba6 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-dismissable-notice.php @@ -0,0 +1,95 @@ +notice_name = $notice_name; + $this->notice_type = $notice_type; + + add_action( 'wp_ajax_wpseo_dismiss_' . $notice_name, [ $this, 'dismiss_notice' ] ); + } + + /** + * Handles the dismiss notice request. + * + * @return void + */ + public function dismiss_notice() { + check_ajax_referer( 'wpseo-dismiss-' . $this->notice_name ); + + $this->save_dismissed(); + + wp_die( 'true' ); + } + + /** + * Storing the dismissed value in the database. The target location is based on the set notification type. + * + * @return void + */ + private function save_dismissed() { + if ( $this->notice_type === self::FOR_SITE ) { + update_option( 'wpseo_dismiss_' . $this->notice_name, 1 ); + + return; + } + + if ( $this->notice_type === self::FOR_NETWORK ) { + update_site_option( 'wpseo_dismiss_' . $this->notice_name, 1 ); + + return; + } + + update_user_meta( get_current_user_id(), 'wpseo_dismiss_' . $this->notice_name, 1 ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-plugin-conflict-ajax.php b/html/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-plugin-conflict-ajax.php new file mode 100644 index 0000000..9778c5e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/ajax/class-yoast-plugin-conflict-ajax.php @@ -0,0 +1,130 @@ + sanitize_text_field( $conflict_data['section'] ), + 'plugins' => sanitize_text_field( $conflict_data['plugins'] ), + ]; + + $this->dismissed_conflicts = $this->get_dismissed_conflicts( $conflict_data['section'] ); + + $this->compare_plugins( $conflict_data['plugins'] ); + + $this->save_dismissed_conflicts( $conflict_data['section'] ); + + wp_die( 'true' ); + } + + /** + * Getting the user option from the database. + * + * @return bool|array + */ + private function get_dismissed_option() { + return get_user_meta( get_current_user_id(), $this->option_name, true ); + } + + /** + * Getting the dismissed conflicts from the database + * + * @param string $plugin_section Type of conflict group (such as Open Graph or sitemap). + * + * @return array + */ + private function get_dismissed_conflicts( $plugin_section ) { + $dismissed_conflicts = $this->get_dismissed_option(); + + if ( is_array( $dismissed_conflicts ) && array_key_exists( $plugin_section, $dismissed_conflicts ) ) { + return $dismissed_conflicts[ $plugin_section ]; + } + + return []; + } + + /** + * Storing the conflicting plugins as an user option in the database. + * + * @param string $plugin_section Plugin conflict type (such as Open Graph or sitemap). + * + * @return void + */ + private function save_dismissed_conflicts( $plugin_section ) { + $dismissed_conflicts = $this->get_dismissed_option(); + + $dismissed_conflicts[ $plugin_section ] = $this->dismissed_conflicts; + + update_user_meta( get_current_user_id(), $this->option_name, $dismissed_conflicts ); + } + + /** + * Loop through the plugins to compare them with the already stored dismissed plugin conflicts. + * + * @param array $posted_plugins Plugin set to check. + * + * @return void + */ + public function compare_plugins( array $posted_plugins ) { + foreach ( $posted_plugins as $posted_plugin ) { + $this->compare_plugin( $posted_plugin ); + } + } + + /** + * Check if plugin is already dismissed, if not store it in the array that will be saved later. + * + * @param string $posted_plugin Plugin to check against dismissed conflicts. + * + * @return void + */ + private function compare_plugin( $posted_plugin ) { + if ( ! in_array( $posted_plugin, $this->dismissed_conflicts, true ) ) { + $this->dismissed_conflicts[] = $posted_plugin; + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-abstract-capability-manager.php b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-abstract-capability-manager.php new file mode 100644 index 0000000..8f290d8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-abstract-capability-manager.php @@ -0,0 +1,91 @@ +capabilities[ $capability ] ) ) { + $this->capabilities[ $capability ] = $roles; + + return; + } + + // Combine configurations. + $this->capabilities[ $capability ] = array_merge( $roles, $this->capabilities[ $capability ] ); + + // Remove doubles. + $this->capabilities[ $capability ] = array_unique( $this->capabilities[ $capability ] ); + } + + /** + * Returns the list of registered capabilitities. + * + * @return string[] Registered capabilities. + */ + public function get_capabilities() { + return array_keys( $this->capabilities ); + } + + /** + * Returns a list of WP_Role roles. + * + * The string array of role names are converted to actual WP_Role objects. + * These are needed to be able to use the API on them. + * + * @param array $roles Roles to retrieve the objects for. + * + * @return WP_Role[] List of WP_Role objects. + */ + protected function get_wp_roles( array $roles ) { + $wp_roles = array_map( 'get_role', $roles ); + + return array_filter( $wp_roles ); + } + + /** + * Filter capability roles. + * + * @param string $capability Capability to filter roles for. + * @param array $roles List of roles which can be filtered. + * + * @return array Filtered list of roles for the capability. + */ + protected function filter_roles( $capability, array $roles ) { + /** + * Filter: Allow changing roles that a capability is added to. + * + * @param array $roles The default roles to be filtered. + */ + $filtered = apply_filters( $capability . '_roles', $roles ); + + // Make sure we have the expected type. + if ( ! is_array( $filtered ) ) { + return []; + } + + return $filtered; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-factory.php b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-factory.php new file mode 100644 index 0000000..e265bee --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-factory.php @@ -0,0 +1,35 @@ +manager = $manager; + } + + /** + * Registers the hooks. + * + * @return void + */ + public function register_hooks() { + add_filter( 'members_get_capabilities', [ $this, 'get_capabilities' ] ); + add_action( 'members_register_cap_groups', [ $this, 'action_members_register_cap_group' ] ); + + add_filter( 'ure_capabilities_groups_tree', [ $this, 'filter_ure_capabilities_groups_tree' ] ); + add_filter( 'ure_custom_capability_groups', [ $this, 'filter_ure_custom_capability_groups' ], 10, 2 ); + } + + /** + * Get the Yoast SEO capabilities. + * Optionally append them to an existing array. + * + * @param array $caps Optional existing capability list. + * @return array + */ + public function get_capabilities( array $caps = [] ) { + if ( ! did_action( 'wpseo_register_capabilities' ) ) { + do_action( 'wpseo_register_capabilities' ); + } + + return array_merge( $caps, $this->manager->get_capabilities() ); + } + + /** + * Add capabilities to its own group in the Members plugin. + * + * @see members_register_cap_group() + * + * @return void + */ + public function action_members_register_cap_group() { + if ( ! function_exists( 'members_register_cap_group' ) ) { + return; + } + + // Register the yoast group. + $args = [ + 'label' => esc_html__( 'Yoast SEO', 'wordpress-seo' ), + 'caps' => $this->get_capabilities(), + 'icon' => 'dashicons-admin-plugins', + 'diff_added' => true, + ]; + members_register_cap_group( 'wordpress-seo', $args ); + } + + /** + * Adds Yoast SEO capability group in the User Role Editor plugin. + * + * @see URE_Capabilities_Groups_Manager::get_groups_tree() + * + * @param array $groups Current groups. + * + * @return array Filtered list of capabilty groups. + */ + public function filter_ure_capabilities_groups_tree( $groups = [] ) { + $groups = (array) $groups; + + $groups['wordpress-seo'] = [ + 'caption' => 'Yoast SEO', + 'parent' => 'custom', + 'level' => 3, + ]; + + return $groups; + } + + /** + * Adds capabilities to the Yoast SEO group in the User Role Editor plugin. + * + * @see URE_Capabilities_Groups_Manager::get_cap_groups() + * + * @param array $groups Current capability groups. + * @param string $cap_id Capability identifier. + * + * @return array List of filtered groups. + */ + public function filter_ure_custom_capability_groups( $groups = [], $cap_id = '' ) { + if ( in_array( $cap_id, $this->get_capabilities(), true ) ) { + $groups = (array) $groups; + $groups[] = 'wordpress-seo'; + } + + return $groups; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-vip.php b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-vip.php new file mode 100644 index 0000000..4f56e8e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-vip.php @@ -0,0 +1,73 @@ +capabilities as $capability => $roles ) { + $role_capabilities = $this->get_role_capabilities( $role_capabilities, $capability, $roles ); + } + + foreach ( $role_capabilities as $role => $capabilities ) { + wpcom_vip_add_role_caps( $role, $capabilities ); + } + } + + /** + * Removes the registered capabilities from the system + * + * @return void + */ + public function remove() { + // Remove from any role it has been added to. + $roles = wp_roles()->get_names(); + $roles = array_keys( $roles ); + + $role_capabilities = []; + foreach ( array_keys( $this->capabilities ) as $capability ) { + // Allow filtering of roles. + $role_capabilities = $this->get_role_capabilities( $role_capabilities, $capability, $roles ); + } + + foreach ( $role_capabilities as $role => $capabilities ) { + wpcom_vip_remove_role_caps( $role, $capabilities ); + } + } + + /** + * Returns the roles which the capability is registered on. + * + * @param array $role_capabilities List of all roles with their capabilities. + * @param string $capability Capability to filter roles for. + * @param array $roles List of default roles. + * + * @return array List of capabilities. + */ + protected function get_role_capabilities( $role_capabilities, $capability, $roles ) { + // Allow filtering of roles. + $filtered_roles = $this->filter_roles( $capability, $roles ); + + foreach ( $filtered_roles as $role ) { + if ( ! isset( $add_role_caps[ $role ] ) ) { + $role_capabilities[ $role ] = []; + } + + $role_capabilities[ $role ][] = $capability; + } + + return $role_capabilities; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-wp.php b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-wp.php new file mode 100644 index 0000000..1830956 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager-wp.php @@ -0,0 +1,51 @@ +capabilities as $capability => $roles ) { + $filtered_roles = $this->filter_roles( $capability, $roles ); + + $wp_roles = $this->get_wp_roles( $filtered_roles ); + foreach ( $wp_roles as $wp_role ) { + $wp_role->add_cap( $capability ); + } + } + } + + /** + * Unregisters the capabilities from the system. + * + * @return void + */ + public function remove() { + // Remove from any roles it has been added to. + $roles = wp_roles()->get_names(); + $roles = array_keys( $roles ); + + foreach ( $this->capabilities as $capability => $_roles ) { + $registered_roles = array_unique( array_merge( $roles, $this->capabilities[ $capability ] ) ); + + // Allow filtering of roles. + $filtered_roles = $this->filter_roles( $capability, $registered_roles ); + + $wp_roles = $this->get_wp_roles( $filtered_roles ); + foreach ( $wp_roles as $wp_role ) { + $wp_role->remove_cap( $capability ); + } + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager.php b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager.php new file mode 100644 index 0000000..b755d6d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-capability-manager.php @@ -0,0 +1,44 @@ + $applicable_roles ] ); + } + + /** + * Retrieves the roles that have the specified capability. + * + * @param string $capability The name of the capability. + * + * @return array The names of the roles that have the capability. + */ + public static function get_applicable_roles( $capability ) { + $roles = wp_roles(); + $role_names = $roles->get_names(); + + $applicable_roles = []; + foreach ( array_keys( $role_names ) as $role_name ) { + $role = $roles->get_role( $role_name ); + + if ( ! $role ) { + continue; + } + + // Add role if it has the capability. + if ( array_key_exists( $capability, $role->capabilities ) && $role->capabilities[ $capability ] === true ) { + $applicable_roles[] = $role_name; + } + } + + return $applicable_roles; + } + + /** + * Checks if the current user has at least one of the supplied capabilities. + * + * @param array $capabilities Capabilities to check against. + * + * @return bool True if the user has at least one capability. + */ + protected static function has_any( array $capabilities ) { + foreach ( $capabilities as $capability ) { + if ( self::has( $capability ) ) { + return true; + } + } + + return false; + } + + /** + * Checks if the user has a certain capability. + * + * @param string $capability Capability to check against. + * + * @return bool True if the user has the capability. + */ + protected static function has( $capability ) { + return current_user_can( $capability ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-register-capabilities.php b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-register-capabilities.php new file mode 100644 index 0000000..04aee8c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/capabilities/class-register-capabilities.php @@ -0,0 +1,115 @@ +register( 'wpseo_bulk_edit', [ 'editor', 'wpseo_editor', 'wpseo_manager' ] ); + $manager->register( 'wpseo_edit_advanced_metadata', [ 'editor', 'wpseo_editor', 'wpseo_manager' ] ); + + $manager->register( 'wpseo_manage_options', [ 'administrator', 'wpseo_manager' ] ); + $manager->register( 'view_site_health_checks', [ 'wpseo_manager' ] ); + } + + /** + * Revokes the 'wpseo_manage_options' capability from administrator users if it should + * only be granted to network administrators. + * + * @param array $allcaps An array of all the user's capabilities. + * @param array $caps Actual capabilities being checked. + * @param array $args Optional parameters passed to has_cap(), typically object ID. + * @param WP_User $user The user object. + * + * @return array Possibly modified array of the user's capabilities. + */ + public function filter_user_has_wpseo_manage_options_cap( $allcaps, $caps, $args, $user ) { + + // We only need to do something if 'wpseo_manage_options' is being checked. + if ( ! in_array( 'wpseo_manage_options', $caps, true ) ) { + return $allcaps; + } + + // If the user does not have 'wpseo_manage_options' anyway, we don't need to revoke access. + if ( empty( $allcaps['wpseo_manage_options'] ) ) { + return $allcaps; + } + + // If the user does not have 'delete_users', they are not an administrator. + if ( empty( $allcaps['delete_users'] ) ) { + return $allcaps; + } + + $options = WPSEO_Options::get_instance(); + + if ( $options->get( 'access' ) === 'superadmin' && ! is_super_admin( $user->ID ) ) { + unset( $allcaps['wpseo_manage_options'] ); + } + + return $allcaps; + } + + /** + * Maybe add manage_privacy_options capability for wpseo_manager user role. + * + * @param string[] $caps Primitive capabilities required of the user. + * @param string[] $cap Capability being checked. + * + * @return string[] Filtered primitive capabilities required of the user. + */ + public function map_meta_cap_for_seo_manager( $caps, $cap ) { + $user = wp_get_current_user(); + + // No multisite support. + if ( is_multisite() ) { + return $caps; + } + + if ( ! is_array( $user->roles ) ) { + return $caps; + } + + // User must be of role wpseo_manager. + if ( ! in_array( 'wpseo_manager', $user->roles, true ) ) { + return $caps; + } + + // Remove manage_options cap requirement if requested cap is manage_privacy_options. + if ( $cap === 'manage_privacy_options' ) { + return array_diff( $caps, [ 'manage_options' ] ); + } + + return $caps; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-analysis-worker-location.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-analysis-worker-location.php new file mode 100644 index 0000000..478f0a8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-analysis-worker-location.php @@ -0,0 +1,75 @@ +flatten_version( WPSEO_VERSION ); + } + + $analysis_worker = $name . '-' . $flat_version . '.js'; + + $this->asset_location = WPSEO_Admin_Asset_Manager::create_default_location(); + $this->asset = new WPSEO_Admin_Asset( + [ + 'name' => $name, + 'src' => $analysis_worker, + ], + ); + } + + /** + * Retrieves the analysis worker asset. + * + * @return WPSEO_Admin_Asset The analysis worker asset. + */ + public function get_asset() { + return $this->asset; + } + + /** + * Determines the URL of the asset on the dev server. + * + * @param WPSEO_Admin_Asset $asset The asset to determine the URL for. + * @param string $type The type of asset. Usually JS or CSS. + * + * @return string The URL of the asset. + */ + public function get_url( WPSEO_Admin_Asset $asset, $type ) { + $scheme = wp_parse_url( $asset->get_src(), PHP_URL_SCHEME ); + if ( in_array( $scheme, [ 'http', 'https' ], true ) ) { + return $asset->get_src(); + } + + return $this->asset_location->get_url( $asset, $type ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-dev-server-location.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-dev-server-location.php new file mode 100644 index 0000000..ac3018a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-dev-server-location.php @@ -0,0 +1,69 @@ +url = $url; + } + + /** + * Determines the URL of the asset on the dev server. + * + * @param WPSEO_Admin_Asset $asset The asset to determine the URL for. + * @param string $type The type of asset. Usually JS or CSS. + * + * @return string The URL of the asset. + */ + public function get_url( WPSEO_Admin_Asset $asset, $type ) { + if ( $type === WPSEO_Admin_Asset::TYPE_CSS ) { + return $this->get_default_url( $asset, $type ); + } + + $path = sprintf( 'js/dist/%s%s.js', $asset->get_src(), $asset->get_suffix() ); + + return trailingslashit( $this->url ) . $path; + } + + /** + * Determines the URL of the asset not using the dev server. + * + * @param WPSEO_Admin_Asset $asset The asset to determine the URL for. + * @param string $type The type of asset. + * + * @return string The URL of the asset file. + */ + public function get_default_url( WPSEO_Admin_Asset $asset, $type ) { + $default_location = new WPSEO_Admin_Asset_SEO_Location( WPSEO_FILE ); + + return $default_location->get_url( $asset, $type ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-location.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-location.php new file mode 100644 index 0000000..7d1c8c3 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-location.php @@ -0,0 +1,22 @@ +asset_location = $asset_location; + $this->prefix = $prefix; + } + + /** + * Enqueues scripts. + * + * @param string $script The name of the script to enqueue. + * + * @return void + */ + public function enqueue_script( $script ) { + wp_enqueue_script( $this->prefix . $script ); + } + + /** + * Enqueues styles. + * + * @param string $style The name of the style to enqueue. + * + * @return void + */ + public function enqueue_style( $style ) { + wp_enqueue_style( $this->prefix . $style ); + } + + /** + * Enqueues the appropriate language for the user. + * + * @return void + */ + public function enqueue_user_language_script() { + $this->enqueue_script( 'language-' . YoastSEO()->helpers->language->get_researcher_language() ); + } + + /** + * Registers scripts based on it's parameters. + * + * @param WPSEO_Admin_Asset $script The script to register. + * + * @return void + */ + public function register_script( WPSEO_Admin_Asset $script ) { + $url = $script->get_src() ? $this->get_url( $script, WPSEO_Admin_Asset::TYPE_JS ) : false; + $args = [ + 'in_footer' => $script->is_in_footer(), + ]; + + if ( $script->get_strategy() !== '' ) { + $args['strategy'] = $script->get_strategy(); + } + + wp_register_script( + $this->prefix . $script->get_name(), + $url, + $script->get_deps(), + $script->get_version(), + $args, + ); + + if ( in_array( 'wp-i18n', $script->get_deps(), true ) ) { + wp_set_script_translations( $this->prefix . $script->get_name(), 'wordpress-seo' ); + } + } + + /** + * Registers styles based on it's parameters. + * + * @param WPSEO_Admin_Asset $style The style to register. + * + * @return void + */ + public function register_style( WPSEO_Admin_Asset $style ) { + wp_register_style( + $this->prefix . $style->get_name(), + $this->get_url( $style, WPSEO_Admin_Asset::TYPE_CSS ), + $style->get_deps(), + $style->get_version(), + $style->get_media(), + ); + } + + /** + * Calls the functions that register scripts and styles with the scripts and styles to be registered as arguments. + * + * @return void + */ + public function register_assets() { + $this->register_scripts( $this->scripts_to_be_registered() ); + $this->register_styles( $this->styles_to_be_registered() ); + } + + /** + * Registers all the scripts passed to it. + * + * @param array $scripts The scripts passed to it. + * + * @return void + */ + public function register_scripts( $scripts ) { + foreach ( $scripts as $script ) { + $script = new WPSEO_Admin_Asset( $script ); + $this->register_script( $script ); + } + } + + /** + * Registers all the styles it receives. + * + * @param array $styles Styles that need to be registered. + * + * @return void + */ + public function register_styles( $styles ) { + foreach ( $styles as $style ) { + $style = new WPSEO_Admin_Asset( $style ); + $this->register_style( $style ); + } + } + + /** + * Localizes the script. + * + * @param string $handle The script handle. + * @param string $object_name The object name. + * @param array $data The l10n data. + * + * @return void + */ + public function localize_script( $handle, $object_name, $data ) { + wp_localize_script( $this->prefix . $handle, $object_name, $data ); + } + + /** + * Adds an inline script. + * + * @param string $handle The script handle. + * @param string $data The l10n data. + * @param string $position Optional. Whether to add the inline script before the handle or after. + * + * @return void + */ + public function add_inline_script( $handle, $data, $position = 'after' ) { + wp_add_inline_script( $this->prefix . $handle, $data, $position ); + } + + /** + * A list of styles that shouldn't be registered but are needed in other locations in the plugin. + * + * @return array + */ + public function special_styles() { + $flat_version = $this->flatten_version( WPSEO_VERSION ); + $asset_args = [ + 'name' => 'inside-editor', + 'src' => 'inside-editor-' . $flat_version, + ]; + + return [ 'inside-editor' => new WPSEO_Admin_Asset( $asset_args ) ]; + } + + /** + * Flattens a version number for use in a filename. + * + * @param string $version The original version number. + * + * @return string The flattened version number. + */ + public function flatten_version( $version ) { + $parts = explode( '.', $version ); + + if ( count( $parts ) === 2 && preg_match( '/^\d+$/', $parts[1] ) === 1 ) { + $parts[] = '0'; + } + + return implode( '', $parts ); + } + + /** + * Creates a default location object for use in the admin asset manager. + * + * @return WPSEO_Admin_Asset_Location The location to use in the asset manager. + */ + public static function create_default_location() { + if ( defined( 'YOAST_SEO_DEV_SERVER' ) && YOAST_SEO_DEV_SERVER ) { + $url = defined( 'YOAST_SEO_DEV_SERVER_URL' ) ? YOAST_SEO_DEV_SERVER_URL : WPSEO_Admin_Asset_Dev_Server_Location::DEFAULT_URL; + + return new WPSEO_Admin_Asset_Dev_Server_Location( $url ); + } + + return new WPSEO_Admin_Asset_SEO_Location( WPSEO_FILE, false ); + } + + /** + * Checks if the given script is enqueued. + * + * @param string $script The script to check. + * + * @return bool True when the script is enqueued. + */ + public function is_script_enqueued( $script ) { + return wp_script_is( $this->prefix . $script ); + } + + /** + * Gets the list of Elementor dependencies. + * + * @return array The array of elementor dependencies. + */ + protected function get_elementor_dependencies() { + $dependencies = [ + 'backbone-marionette', + 'elementor-common-modules', + self::PREFIX . 'api-client', + self::PREFIX . 'externals-components', + self::PREFIX . 'externals-contexts', + self::PREFIX . 'externals-redux', + ]; + // Conditionally add Elementor v2 dependency if available. + if ( wp_script_is( 'elementor-v2-editor-app-bar', 'registered' ) ) { + $dependencies[] = 'elementor-v2-editor-app-bar'; + } + return $dependencies; + } + + /** + * Returns the scripts that need to be registered. + * + * @todo Data format is not self-documenting. Needs explanation inline. R. + * + * @return array The scripts that need to be registered. + */ + protected function scripts_to_be_registered() { + $header_scripts = [ + 'admin-global', + 'block-editor', + 'classic-editor', + 'post-edit', + 'help-scout-beacon', + 'redirect-old-features-tab', + ]; + $elementor_dependencies = $this->get_elementor_dependencies(); + $additional_dependencies = [ + 'analysis-worker' => [ self::PREFIX . 'analysis-package' ], + 'api-client' => [ 'wp-api' ], + 'crawl-settings' => [ 'jquery' ], + 'dashboard-widget' => [ self::PREFIX . 'api-client' ], + 'wincher-dashboard-widget' => [ self::PREFIX . 'api-client' ], + 'editor-modules' => [ 'jquery' ], + 'elementor' => $elementor_dependencies, + 'indexation' => [ + 'jquery-ui-core', + 'jquery-ui-progressbar', + ], + 'first-time-configuration' => [ + self::PREFIX . 'api-client', + self::PREFIX . 'externals-components', + self::PREFIX . 'externals-contexts', + self::PREFIX . 'externals-redux', + ], + 'integrations-page' => [ + self::PREFIX . 'api-client', + self::PREFIX . 'externals-components', + self::PREFIX . 'externals-contexts', + self::PREFIX . 'externals-redux', + ], + 'post-edit' => [ + self::PREFIX . 'api-client', + self::PREFIX . 'block-editor', + self::PREFIX . 'externals-components', + self::PREFIX . 'externals-contexts', + self::PREFIX . 'externals-redux', + ], + 'reindex-links' => [ + 'jquery-ui-core', + 'jquery-ui-progressbar', + ], + 'settings' => [ + 'jquery-ui-core', + 'jquery-ui-progressbar', + self::PREFIX . 'api-client', + self::PREFIX . 'externals-components', + self::PREFIX . 'externals-contexts', + self::PREFIX . 'externals-redux', + ], + 'term-edit' => [ + self::PREFIX . 'api-client', + self::PREFIX . 'classic-editor', + self::PREFIX . 'externals-components', + self::PREFIX . 'externals-contexts', + self::PREFIX . 'externals-redux', + ], + 'general-page' => [ + self::PREFIX . 'api-client', + ], + ]; + + $plugin_scripts = $this->load_generated_asset_file( + [ + 'asset_file' => __DIR__ . '/../src/generated/assets/plugin.php', + 'ext_length' => 3, + 'additional_deps' => $additional_dependencies, + 'header_scripts' => $header_scripts, + ], + ); + $external_scripts = $this->load_generated_asset_file( + [ + 'asset_file' => __DIR__ . '/../src/generated/assets/externals.php', + 'ext_length' => 3, + 'suffix' => '-package', + 'base_dir' => 'externals/', + 'additional_deps' => $additional_dependencies, + 'header_scripts' => $header_scripts, + ], + ); + $language_scripts = $this->load_generated_asset_file( + [ + 'asset_file' => __DIR__ . '/../src/generated/assets/languages.php', + 'ext_length' => 3, + 'suffix' => '-language', + 'base_dir' => 'languages/', + 'additional_deps' => $additional_dependencies, + 'header_scripts' => $header_scripts, + ], + ); + $renamed_scripts = $this->load_renamed_scripts(); + + $scripts = array_merge( + $plugin_scripts, + $external_scripts, + $language_scripts, + $renamed_scripts, + ); + + $scripts['installation-success'] = [ + 'name' => 'installation-success', + 'src' => 'installation-success.js', + 'deps' => [ + 'wp-a11y', + 'wp-dom-ready', + 'wp-components', + 'wp-element', + 'wp-i18n', + self::PREFIX . 'components-new-package', + self::PREFIX . 'externals-components', + ], + 'version' => $scripts['installation-success']['version'], + ]; + + $scripts['post-edit-classic'] = [ + 'name' => 'post-edit-classic', + 'src' => $scripts['post-edit']['src'], + 'deps' => array_map( + static function ( $dep ) { + if ( $dep === self::PREFIX . 'block-editor' ) { + return self::PREFIX . 'classic-editor'; + } + return $dep; + }, + $scripts['post-edit']['deps'], + ), + 'in_footer' => ! in_array( 'post-edit-classic', $header_scripts, true ), + 'version' => $scripts['post-edit']['version'], + ]; + + $scripts['workouts'] = [ + 'name' => 'workouts', + 'src' => 'workouts.js', + 'deps' => [ + 'clipboard', + 'lodash', + 'wp-api-fetch', + 'wp-a11y', + 'wp-components', + 'wp-compose', + 'wp-data', + 'wp-dom-ready', + 'wp-element', + 'wp-i18n', + self::PREFIX . 'externals-components', + self::PREFIX . 'externals-contexts', + self::PREFIX . 'externals-redux', + self::PREFIX . 'analysis', + self::PREFIX . 'components-new-package', + ], + 'version' => $scripts['workouts']['version'], + ]; + + // Add the current language to every script that requires the analysis package. + foreach ( $scripts as $name => $script ) { + if ( substr( $name, -8 ) === 'language' ) { + continue; + } + if ( in_array( self::PREFIX . 'analysis-package', $script['deps'], true ) ) { + $scripts[ $name ]['deps'][] = self::PREFIX . YoastSEO()->helpers->language->get_researcher_language() . '-language'; + } + } + + return $scripts; + } + + /** + * Loads a generated asset file. + * + * @param array $args { + * The arguments. + * + * @type string $asset_file The asset file to load. + * @type int $ext_length The length of the extension, including suffix, of the filename. + * @type string $suffix Optional. The suffix of the asset name. + * @type array $additional_deps Optional. The additional dependencies assets may have. + * @type string $base_dir Optional. The base directory of the asset. + * @type string[] $header_scripts Optional. The script names that should be in the header. + * } + * + * @return array { + * The scripts to be registered. + * + * @type string $name The name of the asset. + * @type string $src The src of the asset. + * @type string[] $deps The dependenies of the asset. + * @type bool $in_footer Whether or not the asset should be in the footer. + * } + */ + protected function load_generated_asset_file( $args ) { + $args = wp_parse_args( + $args, + [ + 'suffix' => '', + 'additional_deps' => [], + 'base_dir' => '', + 'header_scripts' => [], + ], + ); + $scripts = []; + $assets = require $args['asset_file']; + foreach ( $assets as $file => $data ) { + $name = substr( $file, 0, -$args['ext_length'] ); + $name = strtolower( preg_replace( '/([A-Z])/', '-$1', $name ) ); + $name .= $args['suffix']; + + $deps = $data['dependencies']; + if ( isset( $args['additional_deps'][ $name ] ) ) { + $deps = array_merge( $deps, $args['additional_deps'][ $name ] ); + } + + $scripts[ $name ] = [ + 'name' => $name, + 'src' => $args['base_dir'] . $file, + 'deps' => $deps, + 'in_footer' => ! in_array( $name, $args['header_scripts'], true ), + 'version' => $data['version'], + ]; + } + + return $scripts; + } + + /** + * Loads the scripts that should be renamed for BC. + * + * @return array { + * The scripts to be registered. + * + * @type string $name The name of the asset. + * @type string $src The src of the asset. + * @type string[] $deps The dependenies of the asset. + * @type bool $in_footer Whether or not the asset should be in the footer. + * } + */ + protected function load_renamed_scripts() { + $scripts = []; + $renamed_scripts = [ + 'admin-global-script' => 'admin-global', + 'analysis' => 'analysis-package', + 'analysis-report' => 'analysis-report-package', + 'api' => 'api-client', + 'commons' => 'commons-package', + 'edit-page' => 'edit-page-script', + 'draft-js' => 'draft-js-package', + 'feature-flag' => 'feature-flag-package', + 'helpers' => 'helpers-package', + 'jed' => 'jed-package', + 'chart.js' => 'chart.js-package', + 'network-admin-script' => 'network-admin', + 'redux' => 'redux-package', + 'replacement-variable-editor' => 'replacement-variable-editor-package', + 'search-metadata-previews' => 'search-metadata-previews-package', + 'social-metadata-forms' => 'social-metadata-forms-package', + 'styled-components' => 'styled-components-package', + 'style-guide' => 'style-guide-package', + 'yoast-components' => 'components-new-package', + ]; + + foreach ( $renamed_scripts as $original => $replacement ) { + $scripts[] = [ + 'name' => $original, + 'src' => false, + 'deps' => [ self::PREFIX . $replacement ], + ]; + } + + return $scripts; + } + + /** + * Returns the styles that need to be registered. + * + * @todo Data format is not self-documenting. Needs explanation inline. R. + * + * @return array Styles that need to be registered. + */ + protected function styles_to_be_registered() { + $flat_version = $this->flatten_version( WPSEO_VERSION ); + + return [ + [ + 'name' => 'admin-css', + 'src' => 'yst_plugin_tools-' . $flat_version, + 'deps' => [ self::PREFIX . 'toggle-switch' ], + ], + [ + 'name' => 'toggle-switch', + 'src' => 'toggle-switch-' . $flat_version, + ], + [ + 'name' => 'dismissible', + 'src' => 'wpseo-dismissible-' . $flat_version, + ], + [ + 'name' => 'notifications', + 'src' => 'notifications-' . $flat_version, + ], + [ + 'name' => 'alert', + 'src' => 'alerts-' . $flat_version, + ], + [ + 'name' => 'edit-page', + 'src' => 'edit-page-' . $flat_version, + ], + [ + 'name' => 'featured-image', + 'src' => 'featured-image-' . $flat_version, + ], + [ + 'name' => 'metabox-css', + 'src' => 'metabox-' . $flat_version, + 'deps' => [ + self::PREFIX . 'admin-css', + self::PREFIX . 'tailwind', + 'wp-components', + ], + ], + [ + 'name' => 'block-editor', + 'src' => 'block-editor-' . $flat_version, + ], + [ + 'name' => 'ai-generator', + 'src' => 'ai-generator-' . $flat_version, + 'deps' => [ + self::PREFIX . 'ai-frontend', + self::PREFIX . 'tailwind', + self::PREFIX . 'introductions', + ], + ], + [ + 'name' => 'ai-fix-assessments', + 'src' => 'ai-fix-assessments-' . $flat_version, + ], + [ + 'name' => 'ai-frontend', + 'src' => 'ai-frontend-' . $flat_version, + ], + [ + 'name' => 'introductions', + 'src' => 'introductions-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'wp-dashboard', + 'src' => 'dashboard-' . $flat_version, + ], + [ + 'name' => 'scoring', + 'src' => 'yst_seo_score-' . $flat_version, + ], + [ + 'name' => 'adminbar', + 'src' => 'adminbar-' . $flat_version, + 'deps' => [ + 'admin-bar', + ], + ], + [ + 'name' => 'primary-category', + 'src' => 'metabox-primary-category-' . $flat_version, + ], + [ + 'name' => 'admin-global', + 'src' => 'admin-global-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'filter-explanation', + 'src' => 'filter-explanation-' . $flat_version, + ], + [ + 'name' => 'monorepo', + 'src' => 'monorepo-' . $flat_version, + ], + [ + 'name' => 'structured-data-blocks', + 'src' => 'structured-data-blocks-' . $flat_version, + 'deps' => [ + 'dashicons', + 'forms', + 'wp-edit-blocks', + ], + ], + [ + 'name' => 'elementor', + 'src' => 'elementor-' . $flat_version, + ], + [ + 'name' => 'tailwind', + 'src' => 'tailwind-' . $flat_version, + // Note: The RTL suffix is not added here. + // Tailwind and our UI library provide styling that should be standalone compatible with RTL. + // To make it easier we should use the logical properties and values when possible. + // If there are exceptions, we can use the Tailwind modifier, e.g. `rtl:yst-space-x-reverse`. + 'rtl' => false, + ], + [ + 'name' => 'new-settings', + 'src' => 'new-settings-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'redirects', + 'src' => 'redirects-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'black-friday-banner', + 'src' => 'black-friday-banner-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'academy', + 'src' => 'academy-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'general-page', + 'src' => 'general-page-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'installation-success', + 'src' => 'installation-success-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'support', + 'src' => 'support-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'workouts', + 'src' => 'workouts-' . $flat_version, + 'deps' => [ + self::PREFIX . 'monorepo', + ], + ], + [ + 'name' => 'first-time-configuration', + 'src' => 'first-time-configuration-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + [ + 'name' => 'inside-editor', + 'src' => 'inside-editor-' . $flat_version, + ], + [ + 'name' => 'plans', + 'src' => 'plans-' . $flat_version, + 'deps' => [ self::PREFIX . 'tailwind' ], + ], + ]; + } + + /** + * Determines the URL of the asset. + * + * @param WPSEO_Admin_Asset $asset The asset to determine the URL for. + * @param string $type The type of asset. Usually JS or CSS. + * + * @return string The URL of the asset. + */ + protected function get_url( WPSEO_Admin_Asset $asset, $type ) { + $scheme = wp_parse_url( $asset->get_src(), PHP_URL_SCHEME ); + if ( in_array( $scheme, [ 'http', 'https' ], true ) ) { + return $asset->get_src(); + } + + return $this->asset_location->get_url( $asset, $type ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-seo-location.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-seo-location.php new file mode 100644 index 0000000..6774ebd --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-asset-seo-location.php @@ -0,0 +1,86 @@ +plugin_file = $plugin_file; + $this->add_suffix = $add_suffix; + } + + /** + * Determines the URL of the asset on the dev server. + * + * @param WPSEO_Admin_Asset $asset The asset to determine the URL for. + * @param string $type The type of asset. Usually JS or CSS. + * + * @return string The URL of the asset. + */ + public function get_url( WPSEO_Admin_Asset $asset, $type ) { + $path = $this->get_path( $asset, $type ); + if ( empty( $path ) ) { + return ''; + } + + return plugins_url( $path, $this->plugin_file ); + } + + /** + * Determines the path relative to the plugin folder of an asset. + * + * @param WPSEO_Admin_Asset $asset The asset to determine the path for. + * @param string $type The type of asset. + * + * @return string The path to the asset file. + */ + protected function get_path( WPSEO_Admin_Asset $asset, $type ) { + $relative_path = ''; + $rtl_suffix = ''; + + switch ( $type ) { + case WPSEO_Admin_Asset::TYPE_JS: + $relative_path = 'js/dist/' . $asset->get_src(); + if ( $this->add_suffix ) { + $relative_path .= $asset->get_suffix() . '.js'; + } + break; + + case WPSEO_Admin_Asset::TYPE_CSS: + // Path and suffix for RTL stylesheets. + if ( is_rtl() && $asset->has_rtl() ) { + $rtl_suffix = '-rtl'; + } + $relative_path = 'css/dist/' . $asset->get_src() . $rtl_suffix . $asset->get_suffix() . '.css'; + break; + } + + return $relative_path; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-editor-specific-replace-vars.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-editor-specific-replace-vars.php new file mode 100644 index 0000000..ffbddfa --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-editor-specific-replace-vars.php @@ -0,0 +1,227 @@ + [ 'id', 'pt_single', 'pt_plural', 'parent_title' ], + 'post' => [ 'id', 'term404', 'pt_single', 'pt_plural' ], + // Custom post type. + 'custom_post_type' => [ 'id', 'term404', 'pt_single', 'pt_plural', 'parent_title' ], + // Settings - archive pages. + 'custom-post-type_archive' => [ 'pt_single', 'pt_plural' ], + + // Taxonomies. + 'category' => [ 'term_title', 'term_description', 'category_description', 'parent_title', 'term_hierarchy' ], + 'post_tag' => [ 'term_title', 'term_description', 'tag_description' ], + 'post_format' => [ 'term_title' ], + // Custom taxonomy. + 'term-in-custom-taxonomy' => [ 'term_title', 'term_description', 'category_description', 'parent_title', 'term_hierarchy' ], + + // Settings - special pages. + 'search' => [ 'searchphrase' ], + ]; + + /** + * WPSEO_Admin_Editor_Specific_Replace_Vars constructor. + */ + public function __construct() { + $this->add_for_page_types( + [ 'page', 'post', 'custom_post_type' ], + WPSEO_Custom_Fields::get_custom_fields(), + ); + + $this->add_for_page_types( + [ 'post', 'term-in-custom-taxonomy' ], + WPSEO_Custom_Taxonomies::get_custom_taxonomies(), + ); + } + + /** + * Retrieves the editor specific replacement variables. + * + * @return array The editor specific replacement variables. + */ + public function get() { + /** + * Filter: Adds the possibility to add extra editor specific replacement variables. + * + * @param array $replacement_variables Array of editor specific replace vars. + */ + $replacement_variables = apply_filters( + 'wpseo_editor_specific_replace_vars', + $this->replacement_variables, + ); + + if ( ! is_array( $replacement_variables ) ) { + $replacement_variables = $this->replacement_variables; + } + + return array_filter( $replacement_variables, 'is_array' ); + } + + /** + * Retrieves the generic replacement variable names. + * + * Which are the replacement variables without the editor specific ones. + * + * @param array $replacement_variables Possibly generic replacement variables. + * + * @return array The generic replacement variable names. + */ + public function get_generic( $replacement_variables ) { + $shared_variables = array_diff( + $this->extract_names( $replacement_variables ), + $this->get_unique_replacement_variables(), + ); + + return array_values( $shared_variables ); + } + + /** + * Determines the page type of the current term. + * + * @param string $taxonomy The taxonomy name. + * + * @return string The page type. + */ + public function determine_for_term( $taxonomy ) { + $replacement_variables = $this->get(); + if ( array_key_exists( $taxonomy, $replacement_variables ) ) { + return $taxonomy; + } + + return 'term-in-custom-taxonomy'; + } + + /** + * Determines the page type of the current post. + * + * @param WP_Post $post A WordPress post instance. + * + * @return string The page type. + */ + public function determine_for_post( $post ) { + if ( $post instanceof WP_Post === false ) { + return 'post'; + } + + $replacement_variables = $this->get(); + if ( array_key_exists( $post->post_type, $replacement_variables ) ) { + return $post->post_type; + } + + return 'custom_post_type'; + } + + /** + * Determines the page type for a post type. + * + * @param string $post_type The name of the post_type. + * @param string $fallback The page type to fall back to. + * + * @return string The page type. + */ + public function determine_for_post_type( $post_type, $fallback = 'custom_post_type' ) { + if ( ! $this->has_for_page_type( $post_type ) ) { + return $fallback; + } + + return $post_type; + } + + /** + * Determines the page type for an archive page. + * + * @param string $name The name of the archive. + * @param string $fallback The page type to fall back to. + * + * @return string The page type. + */ + public function determine_for_archive( $name, $fallback = 'custom-post-type_archive' ) { + $page_type = $name . '_archive'; + + if ( ! $this->has_for_page_type( $page_type ) ) { + return $fallback; + } + + return $page_type; + } + + /** + * Adds the replavement variables for the given page types. + * + * @param array $page_types Page types to add variables for. + * @param array $replacement_variables_to_add The variables to add. + * + * @return void + */ + protected function add_for_page_types( array $page_types, array $replacement_variables_to_add ) { + if ( empty( $replacement_variables_to_add ) ) { + return; + } + + $replacement_variables_to_add = array_fill_keys( $page_types, $replacement_variables_to_add ); + $replacement_variables = $this->replacement_variables; + + $this->replacement_variables = array_merge_recursive( $replacement_variables, $replacement_variables_to_add ); + } + + /** + * Extracts the names from the given replacements variables. + * + * @param array $replacement_variables Replacement variables to extract the name from. + * + * @return array Extracted names. + */ + protected function extract_names( $replacement_variables ) { + $extracted_names = []; + + foreach ( $replacement_variables as $replacement_variable ) { + if ( empty( $replacement_variable['name'] ) ) { + continue; + } + + $extracted_names[] = $replacement_variable['name']; + } + + return $extracted_names; + } + + /** + * Returns whether the given page type has editor specific replace vars. + * + * @param string $page_type The page type to check. + * + * @return bool True if there are associated editor specific replace vars. + */ + protected function has_for_page_type( $page_type ) { + $replacement_variables = $this->get(); + + return ( ! empty( $replacement_variables[ $page_type ] ) && is_array( $replacement_variables[ $page_type ] ) ); + } + + /** + * Merges all editor specific replacement variables into one array and removes duplicates. + * + * @return array The list of unique editor specific replacement variables. + */ + protected function get_unique_replacement_variables() { + $merged_replacement_variables = call_user_func_array( 'array_merge', array_values( $this->get() ) ); + + return array_unique( $merged_replacement_variables ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-gutenberg-compatibility-notification.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-gutenberg-compatibility-notification.php new file mode 100644 index 0000000..718569a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-gutenberg-compatibility-notification.php @@ -0,0 +1,105 @@ +compatibility_checker = new WPSEO_Gutenberg_Compatibility(); + $this->notification_center = Yoast_Notification_Center::get(); + } + + /** + * Registers all hooks to WordPress. + * + * @return void + */ + public function register_hooks() { + add_action( 'admin_init', [ $this, 'manage_notification' ] ); + } + + /** + * Manages if the notification should be shown or removed. + * + * @return void + */ + public function manage_notification() { + /** + * Filter: 'yoast_display_gutenberg_compat_notification' - Allows developer to disable the Gutenberg compatibility + * notification. + * + * @param bool $display_notification + */ + $display_notification = apply_filters( 'yoast_display_gutenberg_compat_notification', true ); + + if ( + ! $this->compatibility_checker->is_installed() + || $this->compatibility_checker->is_fully_compatible() + || ! $display_notification + ) { + $this->notification_center->remove_notification_by_id( $this->notification_id ); + + return; + } + + $this->add_notification(); + } + + /** + * Adds the notification to the notificaton center. + * + * @return void + */ + protected function add_notification() { + $level = $this->compatibility_checker->is_below_minimum() ? Yoast_Notification::ERROR : Yoast_Notification::WARNING; + + $message = sprintf( + /* translators: %1$s expands to Yoast SEO, %2$s expands to the installed version, %3$s expands to Gutenberg */ + __( '%1$s detected you are using version %2$s of %3$s, please update to the latest version to prevent compatibility issues.', 'wordpress-seo' ), + 'Yoast SEO', + $this->compatibility_checker->get_installed_version(), + 'Gutenberg', + ); + + $notification = new Yoast_Notification( + $message, + [ + 'id' => $this->notification_id, + 'type' => $level, + 'priority' => 1, + ], + ); + + $this->notification_center->add_notification( $notification ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-help-panel.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-help-panel.php new file mode 100644 index 0000000..5fbb4b0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-help-panel.php @@ -0,0 +1,104 @@ +id = $id; + $this->help_button_text = $help_button_text; + $this->help_content = $help_content; + $this->wrapper = $wrapper; + } + + /** + * Returns the html for the Help Button. + * + * @return string + */ + public function get_button_html() { + + if ( ! $this->id || ! $this->help_button_text || ! $this->help_content ) { + return ''; + } + + return sprintf( + ' ', + esc_attr( $this->id ), + $this->help_button_text, + ); + } + + /** + * Returns the html for the Help Panel. + * + * @return string + */ + public function get_panel_html() { + + if ( ! $this->id || ! $this->help_button_text || ! $this->help_content ) { + return ''; + } + + $wrapper_start = ''; + $wrapper_end = ''; + + if ( $this->wrapper === 'has-wrapper' ) { + $wrapper_start = '
            '; + $wrapper_end = '
            '; + } + + return sprintf( + '%1$s

            %3$s

            %4$s', + $wrapper_start, + esc_attr( $this->id ), + $this->help_content, + $wrapper_end, + ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-init.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-init.php new file mode 100644 index 0000000..0856250 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-init.php @@ -0,0 +1,379 @@ +pagenow = $GLOBALS['pagenow']; + + $this->asset_manager = new WPSEO_Admin_Asset_Manager(); + + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_dismissible' ] ); + add_action( 'admin_init', [ $this, 'unsupported_php_notice' ], 15 ); + add_action( 'admin_init', [ $this, 'remove_translations_notification' ], 15 ); + add_action( 'admin_init', [ $this->asset_manager, 'register_assets' ] ); + add_action( 'admin_init', [ $this, 'show_hook_deprecation_warnings' ] ); + add_action( 'admin_init', [ 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ] ); + add_action( 'admin_notices', [ $this, 'permalink_settings_notice' ] ); + add_action( 'post_submitbox_misc_actions', [ $this, 'add_publish_box_section' ] ); + + $this->load_meta_boxes(); + $this->load_taxonomy_class(); + $this->load_admin_page_class(); + $this->load_admin_user_class(); + $this->load_xml_sitemaps_admin(); + $this->load_plugin_suggestions(); + } + + /** + * Enqueue our styling for dismissible yoast notifications. + * + * @return void + */ + public function enqueue_dismissible() { + $this->asset_manager->enqueue_style( 'dismissible' ); + } + + /** + * Removes any notification for incomplete translations. + * + * @return void + */ + public function remove_translations_notification() { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->remove_notification_by_id( 'i18nModuleTranslationAssistance' ); + } + + /** + * Creates an unsupported PHP version notification in the notification center. + * + * @return void + */ + public function unsupported_php_notice() { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->remove_notification_by_id( 'wpseo-dismiss-unsupported-php' ); + } + + /** + * Gets the latest released major WordPress version from the WordPress stable-check api. + * + * @return float|int The latest released major WordPress version. 0 when the stable-check API doesn't respond. + */ + private function get_latest_major_wordpress_version() { + $core_updates = get_core_updates( [ 'dismissed' => true ] ); + + if ( $core_updates === false ) { + return 0; + } + + $wp_version_latest = get_bloginfo( 'version' ); + foreach ( $core_updates as $update ) { + if ( $update->response === 'upgrade' && version_compare( $update->version, $wp_version_latest, '>' ) ) { + $wp_version_latest = $update->version; + } + } + + // Strip the patch version and convert to a float. + return (float) $wp_version_latest; + } + + /** + * Helper to verify if the user is currently visiting one of our admin pages. + * + * @return bool + */ + private function on_wpseo_admin_page() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( ! isset( $_GET['page'] ) || ! is_string( $_GET['page'] ) ) { + return false; + } + + if ( $this->pagenow !== 'admin.php' ) { + return false; + } + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $current_page = sanitize_text_field( wp_unslash( $_GET['page'] ) ); + return strpos( $current_page, 'wpseo' ) === 0; + } + + /** + * Whether we should load the meta box classes. + * + * @return bool true if we should load the meta box classes, false otherwise. + */ + private function should_load_meta_boxes() { + /** + * Filter: 'wpseo_always_register_metaboxes_on_admin' - Allow developers to change whether + * the WPSEO metaboxes are only registered on the typical pages (lean loading) or always + * registered when in admin. + * + * @param bool $register_metaboxes Whether to always register the metaboxes or not. Defaults to false. + */ + if ( apply_filters( 'wpseo_always_register_metaboxes_on_admin', false ) ) { + return true; + } + + // If we are in a post editor. + if ( WPSEO_Metabox::is_post_overview( $this->pagenow ) || WPSEO_Metabox::is_post_edit( $this->pagenow ) ) { + return true; + } + + // If we are doing an inline save. + if ( check_ajax_referer( 'inlineeditnonce', '_inline_edit', false ) && isset( $_POST['action'] ) && sanitize_text_field( wp_unslash( $_POST['action'] ) ) === 'inline-save' ) { + return true; + } + + return false; + } + + /** + * Determine whether we should load the meta box class and if so, load it. + * + * @return void + */ + private function load_meta_boxes() { + if ( $this->should_load_meta_boxes() ) { + $GLOBALS['wpseo_metabox'] = new WPSEO_Metabox(); + $GLOBALS['wpseo_meta_columns'] = new WPSEO_Meta_Columns(); + } + } + + /** + * Determine if we should load our taxonomy edit class and if so, load it. + * + * @return void + */ + private function load_taxonomy_class() { + if ( + WPSEO_Taxonomy::is_term_edit( $this->pagenow ) + || WPSEO_Taxonomy::is_term_overview( $this->pagenow ) + ) { + new WPSEO_Taxonomy(); + } + } + + /** + * Determine if we should load our admin pages class and if so, load it. + * + * Loads admin page class for all admin pages starting with `wpseo_`. + * + * @return void + */ + private function load_admin_user_class() { + if ( in_array( $this->pagenow, [ 'user-edit.php', 'profile.php' ], true ) + && current_user_can( 'edit_users' ) + ) { + new WPSEO_Admin_User_Profile(); + } + } + + /** + * Determine if we should load our admin pages class and if so, load it. + * + * Loads admin page class for all admin pages starting with `wpseo_`. + * + * @return void + */ + private function load_admin_page_class() { + + if ( $this->on_wpseo_admin_page() ) { + // For backwards compatabilty, this still needs a global, for now... + $GLOBALS['wpseo_admin_pages'] = new WPSEO_Admin_Pages(); + + $page = null; + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $page = sanitize_text_field( wp_unslash( $_GET['page'] ) ); + } + + // Only renders Yoast SEO Premium upsells when the page is a Yoast SEO page. + if ( $page !== null && WPSEO_Utils::is_yoast_seo_free_page( $page ) ) { + $this->register_premium_upsell_admin_block(); + } + } + } + + /** + * Loads the plugin suggestions. + * + * @return void + */ + private function load_plugin_suggestions() { + $suggestions = new WPSEO_Suggested_Plugins( new WPSEO_Plugin_Availability(), Yoast_Notification_Center::get() ); + $suggestions->register_hooks(); + } + + /** + * Registers the Premium Upsell Admin Block. + * + * @return void + */ + private function register_premium_upsell_admin_block() { + if ( ! YoastSEO()->helpers->product->is_premium() ) { + $upsell_block = new WPSEO_Premium_Upsell_Admin_Block( 'wpseo_admin_promo_footer' ); + $upsell_block->register_hooks(); + } + } + + /** + * See if we should start our XML Sitemaps Admin class. + * + * @return void + */ + private function load_xml_sitemaps_admin() { + if ( WPSEO_Options::get( 'enable_xml_sitemap', false, [ 'wpseo' ] ) ) { + new WPSEO_Sitemaps_Admin(); + } + } + + /** + * Shows deprecation warnings to the user if a plugin has registered a filter we have deprecated. + * + * @return void + */ + public function show_hook_deprecation_warnings() { + global $wp_filter; + + if ( wp_doing_ajax() ) { + return; + } + + // WordPress hooks that have been deprecated since a Yoast SEO version. + $deprecated_filters = [ + 'wpseo_genesis_force_adjacent_rel_home' => [ + 'version' => '9.4', + 'alternative' => null, + ], + 'wpseo_opengraph' => [ + 'version' => '14.0', + 'alternative' => null, + ], + 'wpseo_twitter' => [ + 'version' => '14.0', + 'alternative' => null, + ], + 'wpseo_twitter_taxonomy_image' => [ + 'version' => '14.0', + 'alternative' => null, + ], + 'wpseo_twitter_metatag_key' => [ + 'version' => '14.0', + 'alternative' => null, + ], + 'wp_seo_get_bc_ancestors' => [ + 'version' => '14.0', + 'alternative' => 'wpseo_breadcrumb_links', + ], + 'validate_facebook_app_id_api_response_code' => [ + 'version' => '15.5', + 'alternative' => null, + ], + 'validate_facebook_app_id_api_response_body' => [ + 'version' => '15.5', + 'alternative' => null, + ], + ]; + + // Determine which filters have been registered. + $deprecated_notices = array_intersect( + array_keys( $deprecated_filters ), + array_keys( $wp_filter ), + ); + + // Show notice for each deprecated filter or action that has been registered. + foreach ( $deprecated_notices as $deprecated_filter ) { + $deprecation_info = $deprecated_filters[ $deprecated_filter ]; + // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Only uses the hardcoded values from above. + _deprecated_hook( + $deprecated_filter, + 'WPSEO ' . $deprecation_info['version'], + $deprecation_info['alternative'], + ); + // phpcs:enable + } + } + + /** + * Check if the permalink uses %postname%. + * + * @return bool + */ + private function has_postname_in_permalink() { + return ( strpos( get_option( 'permalink_structure' ), '%postname%' ) !== false ); + } + + /** + * Shows a notice on the permalink settings page. + * + * @return void + */ + public function permalink_settings_notice() { + global $pagenow; + + if ( $pagenow === 'options-permalink.php' ) { + printf( + '

            %1$s
            %2$s
            %4$s

            ', + esc_html__( 'WARNING:', 'wordpress-seo' ), + sprintf( + /* translators: %1$s and %2$s expand to items to emphasize the word in the middle. */ + esc_html__( 'Changing your permalinks settings can seriously impact your search engine visibility. It should almost %1$s never %2$s be done on a live website.', 'wordpress-seo' ), + '', + '', + ), + esc_url( WPSEO_Shortlinker::get( 'https://yoa.st/why-permalinks/' ) ), + // The link's content. + esc_html__( 'Learn about why permalinks are important for SEO.', 'wordpress-seo' ), + ); + } + } + + /** + * Adds a custom Yoast section within the Classic Editor publish box. + * + * @param WP_Post $post The current post object. + * + * @return void + */ + public function add_publish_box_section( $post ) { + if ( in_array( $this->pagenow, [ 'post.php', 'post-new.php' ], true ) ) { + ?> +
            + [ 'sitename', 'title', 'sep', 'primary_category' ], + 'post' => [ 'sitename', 'title', 'sep', 'primary_category' ], + // Homepage. + 'homepage' => [ 'sitename', 'sitedesc', 'sep' ], + // Custom post type. + 'custom_post_type' => [ 'sitename', 'title', 'sep' ], + + // Taxonomies. + 'category' => [ 'sitename', 'term_title', 'sep', 'term_hierarchy' ], + 'post_tag' => [ 'sitename', 'term_title', 'sep' ], + 'post_format' => [ 'sitename', 'term_title', 'sep', 'page' ], + + // Custom taxonomy. + 'term-in-custom-taxonomy' => [ 'sitename', 'term_title', 'sep', 'term_hierarchy' ], + + // Settings - archive pages. + 'author_archive' => [ 'sitename', 'title', 'sep', 'page' ], + 'date_archive' => [ 'sitename', 'sep', 'date', 'page' ], + 'custom-post-type_archive' => [ 'sitename', 'title', 'sep', 'page' ], + + // Settings - special pages. + 'search' => [ 'sitename', 'searchphrase', 'sep', 'page' ], + '404' => [ 'sitename', 'sep' ], + ]; + + /** + * Determines the page type of the current term. + * + * @param string $taxonomy The taxonomy name. + * + * @return string The page type. + */ + public function determine_for_term( $taxonomy ) { + $recommended_replace_vars = $this->get_recommended_replacevars(); + if ( array_key_exists( $taxonomy, $recommended_replace_vars ) ) { + return $taxonomy; + } + + return 'term-in-custom-taxonomy'; + } + + /** + * Determines the page type of the current post. + * + * @param WP_Post $post A WordPress post instance. + * + * @return string The page type. + */ + public function determine_for_post( $post ) { + if ( $post instanceof WP_Post === false ) { + return 'post'; + } + + if ( $post->post_type === 'page' && $this->is_homepage( $post ) ) { + return 'homepage'; + } + + $recommended_replace_vars = $this->get_recommended_replacevars(); + if ( array_key_exists( $post->post_type, $recommended_replace_vars ) ) { + return $post->post_type; + } + + return 'custom_post_type'; + } + + /** + * Determines the page type for a post type. + * + * @param string $post_type The name of the post_type. + * @param string $fallback The page type to fall back to. + * + * @return string The page type. + */ + public function determine_for_post_type( $post_type, $fallback = 'custom_post_type' ) { + $page_type = $post_type; + $recommended_replace_vars = $this->get_recommended_replacevars(); + $has_recommended_replacevars = $this->has_recommended_replace_vars( $recommended_replace_vars, $page_type ); + + if ( ! $has_recommended_replacevars ) { + return $fallback; + } + + return $page_type; + } + + /** + * Determines the page type for an archive page. + * + * @param string $name The name of the archive. + * @param string $fallback The page type to fall back to. + * + * @return string The page type. + */ + public function determine_for_archive( $name, $fallback = 'custom-post-type_archive' ) { + $page_type = $name . '_archive'; + $recommended_replace_vars = $this->get_recommended_replacevars(); + $has_recommended_replacevars = $this->has_recommended_replace_vars( $recommended_replace_vars, $page_type ); + + if ( ! $has_recommended_replacevars ) { + return $fallback; + } + + return $page_type; + } + + /** + * Retrieves the recommended replacement variables for the given page type. + * + * @param string $page_type The page type. + * + * @return array The recommended replacement variables. + */ + public function get_recommended_replacevars_for( $page_type ) { + $recommended_replace_vars = $this->get_recommended_replacevars(); + $has_recommended_replace_vars = $this->has_recommended_replace_vars( $recommended_replace_vars, $page_type ); + + if ( ! $has_recommended_replace_vars ) { + return []; + } + + return $recommended_replace_vars[ $page_type ]; + } + + /** + * Retrieves the recommended replacement variables. + * + * @return array The recommended replacement variables. + */ + public function get_recommended_replacevars() { + /** + * Filter: Adds the possibility to add extra recommended replacement variables. + * + * @param array $additional_replace_vars Empty array to add the replacevars to. + */ + $recommended_replace_vars = apply_filters( 'wpseo_recommended_replace_vars', $this->recommended_replace_vars ); + + if ( ! is_array( $recommended_replace_vars ) ) { + return $this->recommended_replace_vars; + } + + return $recommended_replace_vars; + } + + /** + * Returns whether the given page type has recommended replace vars. + * + * @param array $recommended_replace_vars The recommended replace vars + * to check in. + * @param string $page_type The page type to check. + * + * @return bool True if there are associated recommended replace vars. + */ + private function has_recommended_replace_vars( $recommended_replace_vars, $page_type ) { + if ( ! isset( $recommended_replace_vars[ $page_type ] ) ) { + return false; + } + + if ( ! is_array( $recommended_replace_vars[ $page_type ] ) ) { + return false; + } + + return true; + } + + /** + * Determines whether or not a post is the homepage. + * + * @param WP_Post $post The WordPress global post object. + * + * @return bool True if the given post is the homepage. + */ + private function is_homepage( $post ) { + if ( $post instanceof WP_Post === false ) { + return false; + } + + /* + * The page on front returns a string with normal WordPress interaction, while the post ID is an int. + * This way we make sure we always compare strings. + */ + $post_id = (int) $post->ID; + $page_on_front = (int) get_option( 'page_on_front' ); + + return get_option( 'show_on_front' ) === 'page' && $page_on_front === $post_id; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin-user-profile.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin-user-profile.php new file mode 100644 index 0000000..5a2e0d1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin-user-profile.php @@ -0,0 +1,73 @@ +%s', + $install_url, + $plugin['title'], + ); + } + + /** + * Gets a visually hidden accessible message for links that open in a new browser tab. + * + * @return string The visually hidden accessible message. + */ + public static function get_new_tab_message() { + return sprintf( + '%s', + /* translators: Hidden accessibility text. */ + esc_html__( '(Opens in a new browser tab)', 'wordpress-seo' ), + ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-admin.php b/html/wp-content/plugins/wordpress-seo/admin/class-admin.php new file mode 100644 index 0000000..825960e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-admin.php @@ -0,0 +1,385 @@ +register_hooks(); + + if ( is_multisite() ) { + WPSEO_Options::maybe_set_multisite_defaults( false ); + } + + add_action( 'created_category', [ $this, 'schedule_rewrite_flush' ] ); + add_action( 'edited_category', [ $this, 'schedule_rewrite_flush' ] ); + add_action( 'delete_category', [ $this, 'schedule_rewrite_flush' ] ); + + add_filter( 'wpseo_accessible_post_types', [ 'WPSEO_Post_Type', 'filter_attachment_post_type' ] ); + + add_filter( 'plugin_action_links_' . WPSEO_BASENAME, [ $this, 'add_action_link' ], 10, 2 ); + add_filter( 'network_admin_plugin_action_links_' . WPSEO_BASENAME, [ $this, 'add_action_link' ], 10, 2 ); + + add_action( 'admin_enqueue_scripts', [ $this, 'config_page_scripts' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_global_style' ] ); + + add_action( 'after_switch_theme', [ $this, 'switch_theme' ] ); + add_action( 'switch_theme', [ $this, 'switch_theme' ] ); + + add_filter( 'set-screen-option', [ $this, 'save_bulk_edit_options' ], 10, 3 ); + + add_action( 'admin_init', [ 'WPSEO_Plugin_Conflict', 'hook_check_for_plugin_conflicts' ], 10, 1 ); + + add_action( 'admin_init', [ $this, 'map_manage_options_cap' ] ); + + WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'wpseo' ); + WPSEO_Sitemaps_Cache::register_clear_on_option_update( 'home' ); + + $this->initialize_cornerstone_content(); + + if ( WPSEO_Utils::is_plugin_network_active() ) { + $integrations[] = new Yoast_Network_Admin(); + } + + $this->admin_features = [ + 'dashboard_widget' => new Yoast_Dashboard_Widget(), + 'wincher_dashboard_widget' => new Wincher_Dashboard_Widget(), + ]; + + if ( WPSEO_Metabox::is_post_overview( $pagenow ) || WPSEO_Metabox::is_post_edit( $pagenow ) ) { + $this->admin_features['primary_category'] = new WPSEO_Primary_Term_Admin(); + } + + $integrations[] = new WPSEO_Yoast_Columns(); + $integrations[] = new WPSEO_Statistic_Integration(); + $integrations[] = new WPSEO_Capability_Manager_Integration( WPSEO_Capability_Manager_Factory::get() ); + $integrations[] = new WPSEO_Admin_Gutenberg_Compatibility_Notification(); + $integrations[] = new WPSEO_Expose_Shortlinks(); + $integrations[] = new WPSEO_MyYoast_Proxy(); + $integrations[] = new WPSEO_Schema_Person_Upgrade_Notification(); + $integrations[] = new WPSEO_Tracking( 'https://tracking.yoast.com/stats', ( WEEK_IN_SECONDS * 2 ) ); + $integrations[] = new WPSEO_Admin_Settings_Changed_Listener(); + + $integrations = array_merge( + $integrations, + $this->get_admin_features(), + $this->initialize_cornerstone_content(), + ); + + foreach ( $integrations as $integration ) { + $integration->register_hooks(); + } + } + + /** + * Schedules a rewrite flush to happen at shutdown. + * + * @return void + */ + public function schedule_rewrite_flush() { + if ( WPSEO_Options::get( 'stripcategorybase' ) !== true ) { + return; + } + + // Bail if this is a multisite installation and the site has been switched. + if ( is_multisite() && ms_is_switched() ) { + return; + } + + add_action( 'shutdown', 'flush_rewrite_rules' ); + } + + /** + * Returns all the classes for the admin features. + * + * @return array + */ + public function get_admin_features() { + return $this->admin_features; + } + + /** + * Register assets needed on admin pages. + * + * @deprecated 25.5 + * @codeCoverageIgnore + * + * @return void + */ + public function enqueue_assets() { + _deprecated_function( __METHOD__, 'Yoast SEO 25.5' ); + } + + /** + * Returns the manage_options capability. + * + * @return string The capability to use. + */ + public function get_manage_options_cap() { + /** + * Filter: 'wpseo_manage_options_capability' - Allow changing the capability users need to view the settings pages. + * + * @param string $capability The capability. + */ + return apply_filters( 'wpseo_manage_options_capability', 'wpseo_manage_options' ); + } + + /** + * Maps the manage_options cap on saving an options page to wpseo_manage_options. + * + * @return void + */ + public function map_manage_options_cap() { + // phpcs:ignore WordPress.Security -- The variable is only used in strpos and thus safe to not unslash or sanitize. + $option_page = ! empty( $_POST['option_page'] ) ? $_POST['option_page'] : ''; + + if ( strpos( $option_page, 'yoast_wpseo' ) === 0 || strpos( $option_page, Settings_Integration::PAGE ) === 0 ) { + add_filter( 'option_page_capability_' . $option_page, [ $this, 'get_manage_options_cap' ] ); + } + } + + /** + * Adds the ability to choose how many posts are displayed per page + * on the bulk edit pages. + * + * @return void + */ + public function bulk_edit_options() { + $option = 'per_page'; + $args = [ + 'label' => __( 'Posts', 'wordpress-seo' ), + 'default' => 10, + 'option' => 'wpseo_posts_per_page', + ]; + add_screen_option( $option, $args ); + } + + /** + * Saves the posts per page limit for bulk edit pages. + * + * @param int $status Status value to pass through. + * @param string $option Option name. + * @param int $value Count value to check. + * + * @return int + */ + public function save_bulk_edit_options( $status, $option, $value ) { + if ( $option && ( $value > 0 && $value < 1000 ) === 'wpseo_posts_per_page' ) { + return $value; + } + + return $status; + } + + /** + * Adds links to Premium Support and FAQ under the plugin in the plugin overview page. + * + * @param array $links Array of links for the plugins, adapted when the current plugin is found. + * @param string $file The filename for the current plugin, which the filter loops through. + * + * @return array + */ + public function add_action_link( $links, $file ) { + $first_time_configuration_notice_helper = YoastSEO()->helpers->first_time_configuration_notice; + + if ( $file === WPSEO_BASENAME && WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ) { + if ( is_network_admin() ) { + $settings_url = network_admin_url( 'admin.php?page=' . self::PAGE_IDENTIFIER ); + } + else { + $settings_url = admin_url( 'admin.php?page=' . self::PAGE_IDENTIFIER ); + } + $settings_link = '' . __( 'Settings', 'wordpress-seo' ) . ''; + array_unshift( $links, $settings_link ); + } + + // Add link to docs. + $faq_link = '' . __( 'FAQ', 'wordpress-seo' ) . ''; + array_unshift( $links, $faq_link ); + + if ( $first_time_configuration_notice_helper->first_time_configuration_not_finished() && ! is_network_admin() ) { + $configuration_title = ( ! $first_time_configuration_notice_helper->should_show_alternate_message() ) ? 'first-time configuration' : 'SEO configuration'; + /* translators: CTA to finish the first time configuration. %s: Either first-time SEO configuration or SEO configuration. */ + $message = sprintf( __( 'Finish your %s', 'wordpress-seo' ), $configuration_title ); + $ftc_page = 'admin.php?page=wpseo_dashboard#/first-time-configuration'; + $ftc_link = '' . $message . ''; + array_unshift( $links, $ftc_link ); + } + + $addon_manager = new WPSEO_Addon_Manager(); + if ( YoastSEO()->helpers->product->is_premium() ) { + + // Remove Free 'deactivate' link if Premium is active as well. We don't want users to deactivate Free when Premium is active. + unset( $links['deactivate'] ); + $no_deactivation_explanation = '' . sprintf( + /* translators: %s expands to Yoast SEO Premium. */ + __( 'Required by %s', 'wordpress-seo' ), + 'Yoast SEO Premium', + ) . ''; + + array_unshift( $links, $no_deactivation_explanation ); + + if ( $addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ) ) { + return $links; + } + + // Add link to where premium can be activated. + $activation_link = '' . __( 'Activate your subscription', 'wordpress-seo' ) . ''; + array_unshift( $links, $activation_link ); + + return $links; + } + + // Add link to premium landing page. + $premium_link = '' . __( 'Get Premium', 'wordpress-seo' ) . ''; + array_unshift( $links, $premium_link ); + + return $links; + } + + /** + * Enqueues the (tiny) global JS needed for the plugin. + * + * @return void + */ + public function config_page_scripts() { + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_script( 'admin-global' ); + $asset_manager->localize_script( 'admin-global', 'wpseoAdminGlobalL10n', $this->localize_admin_global_script() ); + } + + /** + * Enqueues the (tiny) global stylesheet needed for the plugin. + * + * @return void + */ + public function enqueue_global_style() { + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_style( 'admin-global' ); + } + + /** + * Filter the $contactmethods array and add a set of social profiles. + * + * These are used with the Facebook author, rel="author" and Twitter cards implementation. + * + * @deprecated 22.6 + * @codeCoverageIgnore + * + * @param array $contactmethods Currently set contactmethods. + * + * @return array Contactmethods with added contactmethods. + */ + public function update_contactmethods( $contactmethods ) { + _deprecated_function( __METHOD__, 'Yoast SEO 22.6' ); + + $contactmethods['facebook'] = __( 'Facebook profile URL', 'wordpress-seo' ); + $contactmethods['instagram'] = __( 'Instagram profile URL', 'wordpress-seo' ); + $contactmethods['linkedin'] = __( 'LinkedIn profile URL', 'wordpress-seo' ); + $contactmethods['myspace'] = __( 'MySpace profile URL', 'wordpress-seo' ); + $contactmethods['pinterest'] = __( 'Pinterest profile URL', 'wordpress-seo' ); + $contactmethods['soundcloud'] = __( 'SoundCloud profile URL', 'wordpress-seo' ); + $contactmethods['tumblr'] = __( 'Tumblr profile URL', 'wordpress-seo' ); + $contactmethods['twitter'] = __( 'X username (without @)', 'wordpress-seo' ); + $contactmethods['youtube'] = __( 'YouTube profile URL', 'wordpress-seo' ); + $contactmethods['wikipedia'] = __( 'Wikipedia page about you', 'wordpress-seo' ) . '
            ' . __( '(if one exists)', 'wordpress-seo' ) . ''; + + return $contactmethods; + } + + /** + * Log the updated timestamp for user profiles when theme is changed. + * + * @return void + */ + public function switch_theme() { + + $users = get_users( [ 'capability' => [ 'edit_posts' ] ] ); + + if ( is_array( $users ) && $users !== [] ) { + foreach ( $users as $user ) { + update_user_meta( $user->ID, '_yoast_wpseo_profile_updated', time() ); + } + } + } + + /** + * Localization for the dismiss urls. + * + * @return array + */ + private function localize_admin_global_script() { + return array_merge( + [ + 'isRtl' => is_rtl(), + 'variable_warning' => sprintf( + /* translators: %1$s: '%%term_title%%' variable used in titles and meta's template that's not compatible with the given template, %2$s: expands to 'HelpScout beacon' */ + __( 'Warning: the variable %1$s cannot be used in this template. See the %2$s for more info.', 'wordpress-seo' ), + '%s', + 'HelpScout beacon', + ), + /* translators: %s: expends to Yoast SEO */ + 'help_video_iframe_title' => sprintf( __( '%s video tutorial', 'wordpress-seo' ), 'Yoast SEO' ), + 'scrollable_table_hint' => __( 'Scroll to see the table content.', 'wordpress-seo' ), + 'wincher_is_logged_in' => WPSEO_Options::get( 'wincher_integration_active', true ) ? YoastSEO()->helpers->wincher->login_status() : false, + ], + YoastSEO()->helpers->wincher->get_admin_global_links(), + ); + } + + /** + * Whether we are on the admin dashboard page. + * + * @return bool + */ + protected function on_dashboard_page() { + return $GLOBALS['pagenow'] === 'index.php'; + } + + /** + * Loads the cornerstone filter. + * + * @return WPSEO_WordPress_Integration[] The integrations to initialize. + */ + protected function initialize_cornerstone_content() { + if ( ! WPSEO_Options::get( 'enable_cornerstone_content' ) ) { + return []; + } + + return [ + 'cornerstone_filter' => new WPSEO_Cornerstone_Filter(), + ]; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-asset.php b/html/wp-content/plugins/wordpress-seo/admin/class-asset.php new file mode 100644 index 0000000..dbb1c31 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-asset.php @@ -0,0 +1,273 @@ + [], + 'in_footer' => true, + 'rtl' => true, + 'media' => 'all', + 'version' => '', + 'suffix' => '', + 'strategy' => '', + ]; + + /** + * Constructs an instance of the WPSEO_Admin_Asset class. + * + * @param array $args The arguments for this asset. + * + * @throws InvalidArgumentException Throws when no name or src has been provided. + */ + public function __construct( array $args ) { + if ( ! isset( $args['name'] ) ) { + throw new InvalidArgumentException( 'name is a required argument' ); + } + + if ( ! isset( $args['src'] ) ) { + throw new InvalidArgumentException( 'src is a required argument' ); + } + + $args = array_merge( $this->defaults, $args ); + + $this->name = $args['name']; + $this->src = $args['src']; + $this->deps = $args['deps']; + $this->version = $args['version']; + $this->media = $args['media']; + $this->in_footer = $args['in_footer']; + $this->strategy = $args['strategy']; + $this->rtl = $args['rtl']; + $this->suffix = $args['suffix']; + } + + /** + * Returns the asset identifier. + * + * @return string + */ + public function get_name() { + return $this->name; + } + + /** + * Returns the path to the asset. + * + * @return string + */ + public function get_src() { + return $this->src; + } + + /** + * Returns the asset dependencies. + * + * @return array|string + */ + public function get_deps() { + return $this->deps; + } + + /** + * Returns the asset version. + * + * @return string|null + */ + public function get_version() { + if ( ! empty( $this->version ) ) { + return $this->version; + } + + return null; + } + + /** + * Returns the media type for CSS assets. + * + * @return string + */ + public function get_media() { + return $this->media; + } + + /** + * Returns whether a script asset should be loaded in the footer of the page. + * + * @return bool + */ + public function is_in_footer() { + return $this->in_footer; + } + + /** + * Returns the script asset's async/defer loading strategy. + * + * @return string + */ + public function get_strategy() { + return $this->strategy; + } + + /** + * Returns whether this CSS has a RTL counterpart. + * + * @return bool + */ + public function has_rtl() { + return $this->rtl; + } + + /** + * Returns the file suffix. + * + * @return string + */ + public function get_suffix() { + return $this->suffix; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-bulk-description-editor-list-table.php b/html/wp-content/plugins/wordpress-seo/admin/class-bulk-description-editor-list-table.php new file mode 100644 index 0000000..0138415 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-bulk-description-editor-list-table.php @@ -0,0 +1,80 @@ + 'wpseo_bulk_description', + 'plural' => 'wpseo_bulk_descriptions', + 'ajax' => true, + ]; + + /** + * The field in the database where meta field is saved. + * + * @var string + */ + protected $target_db_field = 'metadesc'; + + /** + * The columns shown on the table. + * + * @return array + */ + public function get_columns() { + $columns = [ + 'col_existing_yoast_seo_metadesc' => __( 'Existing Yoast Meta Description', 'wordpress-seo' ), + 'col_new_yoast_seo_metadesc' => __( 'New Yoast Meta Description', 'wordpress-seo' ), + ]; + + return $this->merge_columns( $columns ); + } + + /** + * Parse the metadescription. + * + * @param string $column_name Column name. + * @param object $record Data object. + * @param string $attributes HTML attributes. + * + * @return string + */ + protected function parse_page_specific_column( $column_name, $record, $attributes ) { + switch ( $column_name ) { + case 'col_new_yoast_seo_metadesc': + return sprintf( + '', + esc_attr( 'wpseo-new-metadesc-' . $record->ID ), + esc_attr( $record->ID ), + ); + + case 'col_existing_yoast_seo_metadesc': + // @todo Inconsistent return/echo behavior R. + // I traced the escaping of the attributes to WPSEO_Bulk_List_Table::column_attributes. Alexander. + // The output of WPSEO_Bulk_List_Table::parse_meta_data_field is properly escaped. + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $this->parse_meta_data_field( $record->ID, $attributes ); + break; + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-bulk-editor-list-table.php b/html/wp-content/plugins/wordpress-seo/admin/class-bulk-editor-list-table.php new file mode 100644 index 0000000..aa155c6 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-bulk-editor-list-table.php @@ -0,0 +1,1049 @@ +page_type) there will be constructed an url part, for subpages and + * navigation. + * + * @var string + */ + protected $page_url; + + /** + * The settings which will be used in the __construct. + * + * @var array + */ + protected $settings; + + /** + * Holds the pagination config. + * + * @var array + */ + protected $pagination = []; + + /** + * Holds the sanitized data from the user input. + * + * @var array + */ + protected $input_fields = []; + + /** + * The field in the database where meta field is saved. + * + * Should be set in the child class. + * + * @var string + */ + protected $target_db_field = ''; + + /** + * Class constructor. + * + * @param array $args The arguments. + */ + public function __construct( $args = [] ) { + parent::__construct( $this->settings ); + + $args = wp_parse_args( + $args, + [ + 'nonce' => '', + 'input_fields' => [], + ], + ); + + $this->input_fields = $args['input_fields']; + if ( isset( $_SERVER['REQUEST_URI'] ) ) { + $this->request_url = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ); + } + + $this->current_page = ( ! empty( $this->input_fields['paged'] ) ) ? $this->input_fields['paged'] : 1; + $this->current_filter = ( ! empty( $this->input_fields['post_type_filter'] ) ) ? $this->input_fields['post_type_filter'] : 1; + $this->current_status = ( ! empty( $this->input_fields['post_status'] ) ) ? $this->input_fields['post_status'] : 1; + $this->current_order = [ + 'order' => ( ! empty( $this->input_fields['order'] ) ) ? $this->input_fields['order'] : 'asc', + 'orderby' => ( ! empty( $this->input_fields['orderby'] ) ) ? $this->input_fields['orderby'] : 'post_title', + ]; + + $this->nonce = $args['nonce']; + $this->page_url = "&nonce={$this->nonce}&type={$this->page_type}#top#{$this->page_type}"; + + $this->populate_editable_post_types(); + } + + /** + * Prepares the data and renders the page. + * + * @return void + */ + public function show_page() { + $this->prepare_page_navigation(); + $this->prepare_items(); + + $this->views(); + $this->display(); + } + + /** + * Used in the constructor to build a reference list of post types the current user can edit. + * + * @return void + */ + protected function populate_editable_post_types() { + $post_types = get_post_types( + [ + 'public' => true, + 'exclude_from_search' => false, + ], + 'object', + ); + + $this->all_posts = []; + $this->own_posts = []; + + if ( is_array( $post_types ) && $post_types !== [] ) { + foreach ( $post_types as $post_type ) { + if ( ! current_user_can( $post_type->cap->edit_posts ) ) { + continue; + } + + if ( current_user_can( $post_type->cap->edit_others_posts ) ) { + $this->all_posts[] = esc_sql( $post_type->name ); + } + else { + $this->own_posts[] = esc_sql( $post_type->name ); + } + } + } + } + + /** + * Will show the navigation for the table like page navigation and page filter. + * + * @param string $which Table nav location (such as top). + * + * @return void + */ + public function display_tablenav( $which ) { + // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $post_status = isset( $_GET['post_status'] ) && is_string( $_GET['post_status'] ) ? sanitize_text_field( wp_unslash( $_GET['post_status'] ) ) : ''; + $order_by = isset( $_GET['orderby'] ) && is_string( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : ''; + $order = isset( $_GET['order'] ) && is_string( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : ''; + $post_type_filter = isset( $_GET['post_type_filter'] ) && is_string( $_GET['post_type_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type_filter'] ) ) : ''; + // phpcs:enable WordPress.Security.NonceVerification.Recommended; + ?> +
            + + +
            + + + + + + + + + + + + + extra_tablenav( $which ); + $this->pagination( $which ); + ?> + +
            + +
            + +
            + + prepare(), + * passing the current user_id in as the first parameter. + */ + public function get_base_subquery() { + global $wpdb; + + $all_posts_string = "'" . implode( "', '", $this->all_posts ) . "'"; + $own_posts_string = "'" . implode( "', '", $this->own_posts ) . "'"; + + $post_author = esc_sql( (int) get_current_user_id() ); + + $subquery = "( + SELECT * + FROM {$wpdb->posts} + WHERE post_type IN ({$all_posts_string}) + UNION ALL + SELECT * + FROM {$wpdb->posts} + WHERE post_type IN ({$own_posts_string}) AND post_author = {$post_author} + ) sub_base"; + + return $subquery; + } + + /** + * Gets the views. + * + * @return array The views. + */ + public function get_views() { + global $wpdb; + + $status_links = []; + + $states = get_post_stati( [ 'show_in_admin_all_list' => true ] ); + $subquery = $this->get_base_subquery(); + + $total_posts = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(ID) FROM {$subquery} + WHERE post_status IN (" + . implode( ', ', array_fill( 0, count( $states ), '%s' ) ) + . ')', + $states, + ), + ); + + $post_status = isset( $_GET['post_status'] ) && is_string( $_GET['post_status'] ) ? sanitize_text_field( wp_unslash( $_GET['post_status'] ) ) : ''; + $current_link_attributes = empty( $post_status ) ? ' class="current" aria-current="page"' : ''; + $localized_text = sprintf( + /* translators: %s expands to the number of posts in localized format. */ + _nx( 'All (%s)', 'All (%s)', $total_posts, 'posts', 'wordpress-seo' ), + number_format_i18n( $total_posts ), + ); + + $status_links['all'] = '' . $localized_text . ''; + + $post_stati = get_post_stati( [ 'show_in_admin_all_list' => true ], 'objects' ); + if ( is_array( $post_stati ) && $post_stati !== [] ) { + foreach ( $post_stati as $status ) { + + $status_name = esc_sql( $status->name ); + + $total = (int) $wpdb->get_var( + $wpdb->prepare( + " + SELECT COUNT(ID) FROM {$subquery} + WHERE post_status = %s + ", + $status_name, + ), + ); + + if ( $total === 0 ) { + continue; + } + + $current_link_attributes = ''; + if ( $status_name === $post_status ) { + $current_link_attributes = ' class="current" aria-current="page"'; + } + + $status_links[ $status_name ] = '' . sprintf( translate_nooped_plural( $status->label_count, $total ), number_format_i18n( $total ) ) . ''; + } + } + unset( $post_stati, $status, $status_name, $total, $current_link_attributes ); + + $trashed_posts = $wpdb->get_var( + "SELECT COUNT(ID) FROM {$subquery} + WHERE post_status IN ('trash') + ", + ); + + $current_link_attributes = ''; + if ( $post_status === 'trash' ) { + $current_link_attributes = 'class="current" aria-current="page"'; + } + + $localized_text = sprintf( + /* translators: %s expands to the number of trashed posts in localized format. */ + _nx( 'Trash (%s)', 'Trash (%s)', $trashed_posts, 'posts', 'wordpress-seo' ), + number_format_i18n( $trashed_posts ), + ); + + $status_links['trash'] = '' . $localized_text . ''; + + return $status_links; + } + + /** + * Outputs extra table navigation. + * + * @param string $which Table nav location (such as top). + * + * @return void + */ + public function extra_tablenav( $which ) { + + if ( $which === 'top' ) { + $post_types = get_post_types( + [ + 'public' => true, + 'exclude_from_search' => false, + ], + ); + + $instance_type = esc_attr( $this->page_type ); + + if ( is_array( $post_types ) && $post_types !== [] ) { + global $wpdb; + + echo '
            '; + + $post_types = esc_sql( $post_types ); + $post_types = "'" . implode( "', '", $post_types ) . "'"; + + $states = get_post_stati( [ 'show_in_admin_all_list' => true ] ); + $states['trash'] = 'trash'; + + $subquery = $this->get_base_subquery(); + + $post_types = $wpdb->get_results( + $wpdb->prepare( + "SELECT DISTINCT post_type FROM {$subquery} + WHERE post_status IN (" + . implode( ', ', array_fill( 0, count( $states ), '%s' ) ) + . ') ORDER BY post_type ASC', + $states, + ), + ); + + $post_type_filter = isset( $_GET['post_type_filter'] ) && is_string( $_GET['post_type_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type_filter'] ) ) : ''; + $selected = ( ! empty( $post_type_filter ) ) ? $post_type_filter : '-1'; + + $options = ''; + + if ( is_array( $post_types ) && $post_types !== [] ) { + foreach ( $post_types as $post_type ) { + $obj = get_post_type_object( $post_type->post_type ); + $options .= sprintf( + '', + esc_html( $obj->labels->name ), + esc_attr( $post_type->post_type ), + selected( $selected, $post_type->post_type, false ), + ); + } + } + + printf( + '', + esc_attr( 'post-type-filter-' . $instance_type ), + /* translators: Hidden accessibility text. */ + esc_html__( 'Filter by content type', 'wordpress-seo' ), + ); + printf( + '', + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $options is properly escaped above. + $options, + esc_attr( 'post-type-filter-' . $instance_type ), + ); + + submit_button( esc_html__( 'Filter', 'wordpress-seo' ), 'button', false, false, [ 'id' => 'post-query-submit' ] ); + echo '
            '; + } + } + } + + /** + * Gets a list of sortable columns. + * + * The format is: 'internal-name' => array( 'orderby', bool ). + * + * @return array + */ + public function get_sortable_columns() { + return [ + 'col_page_title' => [ 'post_title', true ], + 'col_post_type' => [ 'post_type', false ], + 'col_post_date' => [ 'post_date', false ], + ]; + } + + /** + * Sets the correct pagenumber and pageurl for the navigation. + * + * @return void + */ + public function prepare_page_navigation() { + + $request_url = $this->request_url . $this->page_url; + + $current_page = $this->current_page; + $current_filter = $this->current_filter; + $current_status = $this->current_status; + $current_order = $this->current_order; + + /* + * If current type doesn't compare with objects page_type, then we have to unset + * some vars in the requested url (which will be used for internal table urls). + */ + if ( isset( $this->input_fields['type'] ) && $this->input_fields['type'] !== $this->page_type ) { + $request_url = remove_query_arg( 'paged', $request_url ); // Page will be set with value 1 below. + $request_url = remove_query_arg( 'post_type_filter', $request_url ); + $request_url = remove_query_arg( 'post_status', $request_url ); + $request_url = remove_query_arg( 'orderby', $request_url ); + $request_url = remove_query_arg( 'order', $request_url ); + $request_url = add_query_arg( 'pages', 1, $request_url ); + + $current_page = 1; + $current_filter = '-1'; + $current_status = ''; + $current_order = [ + 'orderby' => 'post_title', + 'order' => 'asc', + ]; + } + + $_SERVER['REQUEST_URI'] = $request_url; + + $_GET['paged'] = $current_page; + $_REQUEST['paged'] = $current_page; + $_REQUEST['post_type_filter'] = $current_filter; + $_GET['post_type_filter'] = $current_filter; + $_GET['post_status'] = $current_status; + $_GET['orderby'] = $current_order['orderby']; + $_GET['order'] = $current_order['order']; + } + + /** + * Preparing the requested pagerows and setting the needed variables. + * + * @return void + */ + public function prepare_items() { + + $post_type_clause = $this->get_post_type_clause(); + $all_states = $this->get_all_states(); + $subquery = $this->get_base_subquery(); + + // Setting the column headers. + $this->set_column_headers(); + + // Count the total number of needed items and setting pagination given $total_items. + $total_items = $this->count_items( $subquery, $all_states, $post_type_clause ); + $this->set_pagination( $total_items ); + + // Getting items given $query. + $query = $this->parse_item_query( $subquery, $all_states, $post_type_clause ); + $this->get_items( $query ); + + // Get the metadata for the current items ($this->items). + $this->get_meta_data(); + } + + /** + * Getting the columns for first row. + * + * @return array + */ + public function get_columns() { + return $this->merge_columns(); + } + + /** + * Setting the column headers. + * + * @return void + */ + protected function set_column_headers() { + $columns = $this->get_columns(); + $hidden = []; + $sortable = $this->get_sortable_columns(); + $this->_column_headers = [ $columns, $hidden, $sortable ]; + } + + /** + * Counting total items. + * + * @param string $subquery SQL FROM part. + * @param string $all_states SQL IN part. + * @param string $post_type_clause SQL post type part. + * + * @return mixed + */ + protected function count_items( $subquery, $all_states, $post_type_clause ) { + global $wpdb; + + return (int) $wpdb->get_var( + "SELECT COUNT(ID) FROM {$subquery} + WHERE post_status IN ({$all_states}) + {$post_type_clause} + ", + ); + } + + /** + * Getting the post_type_clause filter. + * + * @return string + */ + protected function get_post_type_clause() { + // Filter Block. + $post_type_clause = ''; + $post_type_filter = isset( $_GET['post_type_filter'] ) && is_string( $_GET['post_type_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type_filter'] ) ) : ''; + + if ( ! empty( $post_type_filter ) && get_post_type_object( $post_type_filter ) ) { + $post_types = esc_sql( $post_type_filter ); + $post_type_clause = "AND post_type IN ('{$post_types}')"; + } + + return $post_type_clause; + } + + /** + * Setting the pagination. + * + * Total items is the number of all visible items. + * + * @param int $total_items Total items counts. + * + * @return void + */ + protected function set_pagination( $total_items ) { + // Calculate items per page. + $per_page = $this->get_items_per_page( 'wpseo_posts_per_page', 10 ); + $paged = isset( $_GET['paged'] ) && is_string( $_GET['paged'] ) ? esc_sql( sanitize_text_field( wp_unslash( $_GET['paged'] ) ) ) : ''; + + if ( empty( $paged ) || ! is_numeric( $paged ) ) { + $paged = 1; + } + else { + $paged = (int) $paged; + } + + if ( $paged <= 0 ) { + $paged = 1; + } + + $this->set_pagination_args( + [ + 'total_items' => $total_items, + 'total_pages' => ceil( $total_items / $per_page ), + 'per_page' => $per_page, + ], + ); + + $this->pagination = [ + 'per_page' => $per_page, + 'offset' => ( ( $paged - 1 ) * $per_page ), + ]; + } + + /** + * Parse the query to get items from database. + * + * Based on given parameters there will be parse a query which will get all the pages/posts and other post_types + * from the database. + * + * @param string $subquery SQL FROM part. + * @param string $all_states SQL IN part. + * @param string $post_type_clause SQL post type part. + * + * @return string + */ + protected function parse_item_query( $subquery, $all_states, $post_type_clause ) { + // Order By block. + $orderby = isset( $_GET['orderby'] ) && is_string( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : ''; + + $orderby = ! empty( $orderby ) ? esc_sql( $orderby ) : 'post_title'; + $orderby = $this->sanitize_orderby( $orderby ); + + // Order clause. + $order = isset( $_GET['order'] ) && is_string( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : ''; + $order = ! empty( $order ) ? esc_sql( strtoupper( $order ) ) : 'ASC'; + $order = $this->sanitize_order( $order ); + + // Get all needed results. + $query = " + SELECT ID, post_title, post_type, post_status, post_modified, post_date + FROM {$subquery} + WHERE post_status IN ({$all_states}) $post_type_clause + ORDER BY {$orderby} {$order} + LIMIT %d,%d + "; + + return $query; + } + + /** + * Heavily restricts the possible columns by which a user can order the table + * in the bulk editor, thereby preventing a possible CSRF vulnerability. + * + * @param string $orderby The column by which we want to order. + * + * @return string + */ + protected function sanitize_orderby( $orderby ) { + $valid_column_names = [ + 'post_title', + 'post_type', + 'post_date', + ]; + + if ( in_array( $orderby, $valid_column_names, true ) ) { + return $orderby; + } + + return 'post_title'; + } + + /** + * Makes sure the order clause is always ASC or DESC for the bulk editor table, + * thereby preventing a possible CSRF vulnerability. + * + * @param string $order Whether we want to sort ascending or descending. + * + * @return string SQL order string (ASC, DESC). + */ + protected function sanitize_order( $order ) { + if ( in_array( strtoupper( $order ), [ 'ASC', 'DESC' ], true ) ) { + return $order; + } + + return 'ASC'; + } + + /** + * Getting all the items. + * + * @param string $query SQL query to use. + * + * @return void + */ + protected function get_items( $query ) { + global $wpdb; + + $this->items = $wpdb->get_results( + $wpdb->prepare( + $query, + $this->pagination['offset'], + $this->pagination['per_page'], + ), + ); + } + + /** + * Getting all the states. + * + * @return string + */ + protected function get_all_states() { + global $wpdb; + + $states = get_post_stati( [ 'show_in_admin_all_list' => true ] ); + $states['trash'] = 'trash'; + + if ( ! empty( $this->input_fields['post_status'] ) ) { + $requested_state = $this->input_fields['post_status']; + if ( in_array( $requested_state, $states, true ) ) { + $states = [ $requested_state ]; + } + + if ( $requested_state !== 'trash' ) { + unset( $states['trash'] ); + } + } + + return $wpdb->prepare( + implode( ', ', array_fill( 0, count( $states ), '%s' ) ), + $states, + ); + } + + /** + * Based on $this->items and the defined columns, the table rows will be displayed. + * + * @return void + */ + public function display_rows() { + + $records = $this->items; + + list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); + + if ( ( is_array( $records ) && $records !== [] ) && ( is_array( $columns ) && $columns !== [] ) ) { + + foreach ( $records as $record ) { + + echo ''; + + foreach ( $columns as $column_name => $column_display_name ) { + + $classes = ''; + if ( $primary === $column_name ) { + $classes .= ' has-row-actions column-primary'; + } + + $attributes = $this->column_attributes( $column_name, $hidden, $classes, $column_display_name ); + + $column_value = $this->parse_column( $column_name, $record ); + + if ( method_exists( $this, 'parse_page_specific_column' ) && empty( $column_value ) ) { + $column_value = $this->parse_page_specific_column( $column_name, $record, $attributes ); + } + + if ( ! empty( $column_value ) ) { + printf( '%1$s', $column_value, $attributes ); + } + } + + echo ''; + } + } + } + + /** + * Getting the attributes for each table cell. + * + * @param string $column_name Column name string. + * @param array $hidden Set of hidden columns. + * @param string $classes Additional CSS classes. + * @param string $column_display_name Column display name string. + * + * @return string + */ + protected function column_attributes( $column_name, $hidden, $classes, $column_display_name ) { + + $attributes = ''; + $class = [ $column_name, "column-$column_name$classes" ]; + + if ( in_array( $column_name, $hidden, true ) ) { + $class[] = 'hidden'; + } + + if ( ! empty( $class ) ) { + $attributes = 'class="' . esc_attr( implode( ' ', $class ) ) . '"'; + } + + $attributes .= ' data-colname="' . esc_attr( $column_display_name ) . '"'; + + return $attributes; + } + + /** + * Parsing the title. + * + * @param WP_Post $rec Post object. + * + * @return string + */ + protected function parse_page_title_column( $rec ) { + + $title = empty( $rec->post_title ) ? __( '(no title)', 'wordpress-seo' ) : $rec->post_title; + + $return = sprintf( '%1$s', stripslashes( wp_strip_all_tags( $title ) ) ); + + $post_type_object = get_post_type_object( $rec->post_type ); + $can_edit_post = current_user_can( $post_type_object->cap->edit_post, $rec->ID ); + + $actions = []; + + if ( $can_edit_post && $rec->post_status !== 'trash' ) { + $actions['edit'] = sprintf( + '%s', + esc_url( get_edit_post_link( $rec->ID, true ) ), + /* translators: Hidden accessibility text; %s: post title. */ + esc_attr( sprintf( __( 'Edit “%s”', 'wordpress-seo' ), $title ) ), + __( 'Edit', 'wordpress-seo' ), + ); + } + + if ( $post_type_object->public ) { + if ( in_array( $rec->post_status, [ 'pending', 'draft', 'future' ], true ) ) { + if ( $can_edit_post ) { + $actions['view'] = sprintf( + '%s', + esc_url( add_query_arg( 'preview', 'true', get_permalink( $rec->ID ) ) ), + /* translators: Hidden accessibility text; %s: post title. */ + esc_attr( sprintf( __( 'Preview “%s”', 'wordpress-seo' ), $title ) ), + __( 'Preview', 'wordpress-seo' ), + ); + } + } + elseif ( $rec->post_status !== 'trash' ) { + $actions['view'] = sprintf( + '%s', + esc_url( get_permalink( $rec->ID ) ), + /* translators: Hidden accessibility text; %s: post title. */ + esc_attr( sprintf( __( 'View “%s”', 'wordpress-seo' ), $title ) ), + __( 'View', 'wordpress-seo' ), + ); + } + } + + $return .= $this->row_actions( $actions ); + + return $return; + } + + /** + * Parsing the column based on the $column_name. + * + * @param string $column_name Column name. + * @param WP_Post $rec Post object. + * + * @return string + */ + protected function parse_column( $column_name, $rec ) { + + static $date_format; + + if ( ! isset( $date_format ) ) { + $date_format = get_option( 'date_format' ); + } + + switch ( $column_name ) { + case 'col_page_title': + $column_value = $this->parse_page_title_column( $rec ); + break; + + case 'col_page_slug': + $permalink = get_permalink( $rec->ID ); + $display_slug = str_replace( get_bloginfo( 'url' ), '', $permalink ); + $column_value = sprintf( '%1$s', stripslashes( rawurldecode( $display_slug ) ), esc_url( $permalink ) ); + break; + + case 'col_post_type': + $post_type = get_post_type_object( $rec->post_type ); + $column_value = $post_type->labels->singular_name; + break; + + case 'col_post_status': + $post_status = get_post_status_object( $rec->post_status ); + $column_value = $post_status->label; + break; + + case 'col_post_date': + $column_value = date_i18n( $date_format, strtotime( $rec->post_date ) ); + break; + + case 'col_row_action': + $column_value = sprintf( + '%2$s %3$s', + $rec->ID, + esc_html__( 'Save', 'wordpress-seo' ), + esc_html__( 'Save all', 'wordpress-seo' ), + ); + break; + } + + if ( ! empty( $column_value ) ) { + return $column_value; + } + } + + /** + * Parse the field where the existing meta-data value is displayed. + * + * @param int $record_id Record ID. + * @param string $attributes HTML attributes. + * @param bool|array $values Optional values data array. + * + * @return string + */ + protected function parse_meta_data_field( $record_id, $attributes, $values = false ) { + + // Fill meta data if exists in $this->meta_data. + $meta_data = ( ! empty( $this->meta_data[ $record_id ] ) ) ? $this->meta_data[ $record_id ] : []; + $meta_key = WPSEO_Meta::$meta_prefix . $this->target_db_field; + $meta_value = ( ! empty( $meta_data[ $meta_key ] ) ) ? $meta_data[ $meta_key ] : ''; + + if ( ! empty( $values ) ) { + $meta_value = $values[ $meta_value ]; + } + + $id = "wpseo-existing-$this->target_db_field-$record_id"; + + // $attributes correctly escaped, verified by Alexander. See WPSEO_Bulk_Description_List_Table::parse_page_specific_column. + return sprintf( '%1$s', esc_html( $meta_value ), $attributes, esc_attr( $id ) ); + } + + /** + * Method for setting the meta data, which belongs to the records that will be shown on the current page. + * + * This method will loop through the current items ($this->items) for getting the post_id. With this data + * ($needed_ids) the method will query the meta-data table for getting the title. + * + * @return void + */ + protected function get_meta_data() { + + $post_ids = $this->get_post_ids(); + $meta_data = $this->get_meta_data_result( $post_ids ); + + $this->parse_meta_data( $meta_data ); + + // Little housekeeping. + unset( $post_ids, $meta_data ); + } + + /** + * Getting all post_ids from to $this->items. + * + * @return array + */ + protected function get_post_ids() { + $post_ids = []; + foreach ( $this->items as $item ) { + $post_ids[] = $item->ID; + } + + return $post_ids; + } + + /** + * Getting the meta_data from database. + * + * @param array $post_ids Post IDs for SQL IN part. + * + * @return mixed + */ + protected function get_meta_data_result( array $post_ids ) { + global $wpdb; + + $where = $wpdb->prepare( + 'post_id IN (' . implode( ', ', array_fill( 0, count( $post_ids ), '%d' ) ) . ')', + $post_ids, + ); + + $where .= $wpdb->prepare( ' AND meta_key = %s', WPSEO_Meta::$meta_prefix . $this->target_db_field ); + + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- They are prepared on the lines above. + return $wpdb->get_results( "SELECT * FROM {$wpdb->postmeta} WHERE {$where}" ); + } + + /** + * Setting $this->meta_data. + * + * @param array $meta_data Meta data set. + * + * @return void + */ + protected function parse_meta_data( $meta_data ) { + + foreach ( $meta_data as $row ) { + $this->meta_data[ $row->post_id ][ $row->meta_key ] = $row->meta_value; + } + } + + /** + * This method will merge general array with given parameter $columns. + * + * @param array $columns Optional columns set. + * + * @return array + */ + protected function merge_columns( $columns = [] ) { + $columns = array_merge( + [ + 'col_page_title' => __( 'WP Page Title', 'wordpress-seo' ), + 'col_post_type' => __( 'Content Type', 'wordpress-seo' ), + 'col_post_status' => __( 'Post Status', 'wordpress-seo' ), + 'col_post_date' => __( 'Publication date', 'wordpress-seo' ), + 'col_page_slug' => __( 'Page URL/Slug', 'wordpress-seo' ), + ], + $columns, + ); + + $columns['col_row_action'] = __( 'Action', 'wordpress-seo' ); + + return $columns; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-bulk-title-editor-list-table.php b/html/wp-content/plugins/wordpress-seo/admin/class-bulk-title-editor-list-table.php new file mode 100644 index 0000000..a523e26 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-bulk-title-editor-list-table.php @@ -0,0 +1,89 @@ + 'wpseo_bulk_title', + 'plural' => 'wpseo_bulk_titles', + 'ajax' => true, + ]; + + /** + * The field in the database where meta field is saved. + * + * @var string + */ + protected $target_db_field = 'title'; + + /** + * The columns shown on the table. + * + * @return array + */ + public function get_columns() { + + $columns = [ + /* translators: %1$s expands to Yoast SEO */ + 'col_existing_yoast_seo_title' => sprintf( __( 'Existing %1$s Title', 'wordpress-seo' ), 'Yoast SEO' ), + /* translators: %1$s expands to Yoast SEO */ + 'col_new_yoast_seo_title' => sprintf( __( 'New %1$s Title', 'wordpress-seo' ), 'Yoast SEO' ), + ]; + + return $this->merge_columns( $columns ); + } + + /** + * Parse the title columns. + * + * @param string $column_name Column name. + * @param object $record Data object. + * @param string $attributes HTML attributes. + * + * @return string + */ + protected function parse_page_specific_column( $column_name, $record, $attributes ) { + + // Fill meta data if exists in $this->meta_data. + $meta_data = ( ! empty( $this->meta_data[ $record->ID ] ) ) ? $this->meta_data[ $record->ID ] : []; + + switch ( $column_name ) { + case 'col_existing_yoast_seo_title': + // @todo Inconsistent return/echo behavior R. + // I traced the escaping of the attributes to WPSEO_Bulk_List_Table::column_attributes. + // The output of WPSEO_Bulk_List_Table::parse_meta_data_field is properly escaped. + // phpcs:ignore WordPress.Security.EscapeOutput + echo $this->parse_meta_data_field( $record->ID, $attributes ); + break; + + case 'col_new_yoast_seo_title': + return sprintf( + '', + 'wpseo-new-title-' . $record->ID, + $record->ID, + ); + } + + unset( $meta_data ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-collector.php b/html/wp-content/plugins/wordpress-seo/admin/class-collector.php new file mode 100644 index 0000000..908536e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-collector.php @@ -0,0 +1,54 @@ +collections[] = $collection; + } + + /** + * Collects the data from the collection objects. + * + * @return array The collected data. + */ + public function collect() { + $data = []; + + foreach ( $this->collections as $collection ) { + $data = array_merge( $data, $collection->get() ); + } + + return $data; + } + + /** + * Returns the collected data as a JSON encoded string. + * + * @return string|false The encode string. + */ + public function get_as_json() { + return WPSEO_Utils::format_json_encode( $this->collect() ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-config.php b/html/wp-content/plugins/wordpress-seo/admin/class-config.php new file mode 100644 index 0000000..bef7e30 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-config.php @@ -0,0 +1,161 @@ +asset_manager = new WPSEO_Admin_Asset_Manager(); + } + + /** + * Make sure the needed scripts are loaded for admin pages. + * + * @return void + */ + public function init() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $page = isset( $_GET['page'] ) && is_string( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; + + // Don't load the scripts for the following pages. + $page_exceptions = in_array( + $page, + [ + Settings_Integration::PAGE, + Academy_Integration::PAGE, + Support_Integration::PAGE, + Plans_Page_Integration::PAGE, + Redirects_Page_Integration::PAGE, + ], + true, + ); + $new_dashboard_page = ( $page === General_Page_Integration::PAGE && ! is_network_admin() ); + if ( $page_exceptions || $new_dashboard_page ) { + // Bail, this is managed in the applicable integration. + return; + } + add_action( 'admin_enqueue_scripts', [ $this, 'config_page_scripts' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'config_page_styles' ] ); + } + + /** + * Loads the required styles for the config page. + * + * @return void + */ + public function config_page_styles() { + wp_enqueue_style( 'dashboard' ); + wp_enqueue_style( 'thickbox' ); + wp_enqueue_style( 'global' ); + wp_enqueue_style( 'wp-admin' ); + $this->asset_manager->enqueue_style( 'admin-css' ); + $this->asset_manager->enqueue_style( 'monorepo' ); + } + + /** + * Loads the required scripts for the config page. + * + * @return void + */ + public function config_page_scripts() { + $this->asset_manager->enqueue_script( 'settings' ); + wp_enqueue_script( 'dashboard' ); + wp_enqueue_script( 'thickbox' ); + + $alert_dismissal_action = YoastSEO()->classes->get( Alert_Dismissal_Action::class ); + $dismissed_alerts = $alert_dismissal_action->all_dismissed(); + + $script_data = [ + 'dismissedAlerts' => $dismissed_alerts, + 'isRtl' => is_rtl(), + 'isPremium' => YoastSEO()->helpers->product->is_premium(), + 'currentPromotions' => YoastSEO()->classes->get( Promotion_Manager::class ) + ->get_current_promotions(), + 'webinarIntroFirstTimeConfigUrl' => $this->get_webinar_shortlink(), + 'linkParams' => WPSEO_Shortlinker::get_query_params(), + 'pluginUrl' => plugins_url( '', WPSEO_FILE ), + ]; + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $page = isset( $_GET['page'] ) && is_string( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; + + if ( in_array( $page, [ WPSEO_Admin::PAGE_IDENTIFIER, 'wpseo_workouts' ], true ) ) { + wp_enqueue_media(); + + $script_data['userEditUrl'] = add_query_arg( 'user_id', '{user_id}', admin_url( 'user-edit.php' ) ); + } + + if ( $page === 'wpseo_tools' ) { + $this->enqueue_tools_scripts(); + } + + $this->asset_manager->localize_script( 'settings', 'wpseoScriptData', $script_data ); + } + + /** + * Enqueues and handles all the tool dependencies. + * + * @return void + */ + private function enqueue_tools_scripts() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $tool = isset( $_GET['tool'] ) && is_string( $_GET['tool'] ) ? sanitize_text_field( wp_unslash( $_GET['tool'] ) ) : ''; + + if ( empty( $tool ) ) { + $this->asset_manager->enqueue_script( 'yoast-seo' ); + } + + if ( $tool === 'bulk-editor' ) { + $this->asset_manager->enqueue_script( 'bulk-editor' ); + } + } + + /** + * Returns the appropriate shortlink for the Webinar. + * + * @return string The shortlink for the Webinar. + */ + private function get_webinar_shortlink() { + if ( YoastSEO()->helpers->product->is_premium() ) { + return WPSEO_Shortlinker::get( 'https://yoa.st/webinar-intro-first-time-config-premium' ); + } + + return WPSEO_Shortlinker::get( 'https://yoa.st/webinar-intro-first-time-config' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-database-proxy.php b/html/wp-content/plugins/wordpress-seo/admin/class-database-proxy.php new file mode 100644 index 0000000..063f584 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-database-proxy.php @@ -0,0 +1,309 @@ +table_name = $table_name; + $this->suppress_errors = (bool) $suppress_errors; + $this->is_multisite_table = (bool) $is_multisite_table; + $this->database = $database; + + // If the table prefix was provided, strip it as it's handled automatically. + $table_prefix = $this->get_table_prefix(); + if ( ! empty( $table_prefix ) && strpos( $this->table_name, $table_prefix ) === 0 ) { + $this->table_prefix = substr( $this->table_name, strlen( $table_prefix ) ); + } + + if ( ! $this->is_table_registered() ) { + $this->register_table(); + } + } + + /** + * Inserts data into the database. + * + * @param array $data Data to insert. + * @param array|string|null $format Formats for the data. + * + * @return int|false Total amount of inserted rows or false on error. + */ + public function insert( array $data, $format = null ) { + $this->pre_execution(); + + $result = $this->database->insert( $this->get_table_name(), $data, $format ); + + $this->post_execution(); + + return $result; + } + + /** + * Updates data in the database. + * + * @param array $data Data to update on the table. + * @param array $where Where condition as key => value array. + * @param array|string|null $format Optional. Data prepare format. + * @param array|string|null $where_format Optional. Where prepare format. + * + * @return int|false False when the update request is invalid, int on number of rows changed. + */ + public function update( array $data, array $where, $format = null, $where_format = null ) { + $this->pre_execution(); + + $result = $this->database->update( $this->get_table_name(), $data, $where, $format, $where_format ); + + $this->post_execution(); + + return $result; + } + + /** + * Upserts data in the database. + * + * Performs an insert into and if key is duplicate it will update the existing record. + * + * @param array $data Data to update on the table. + * @param array|null $where Unused. Where condition as key => value array. + * @param array|string|null $format Optional. Data prepare format. + * @param array|string|null $where_format Optional. Where prepare format. + * + * @return int|false False when the upsert request is invalid, int on number of rows changed. + */ + public function upsert( array $data, ?array $where = null, $format = null, $where_format = null ) { + if ( $where_format !== null ) { + _deprecated_argument( __METHOD__, '7.7.0', 'The where_format argument is deprecated' ); + } + + $this->pre_execution(); + + $update = []; + $keys = []; + $columns = array_keys( $data ); + foreach ( $columns as $column ) { + $keys[] = '`' . $column . '`'; + $update[] = sprintf( '`%1$s` = VALUES(`%1$s`)', $column ); + } + + $query = sprintf( + 'INSERT INTO `%1$s` (%2$s) VALUES ( %3$s ) ON DUPLICATE KEY UPDATE %4$s', + $this->get_table_name(), + implode( ', ', $keys ), + implode( ', ', array_fill( 0, count( $data ), '%s' ) ), + implode( ', ', $update ), + ); + + $result = $this->database->query( + $this->database->prepare( + $query, + array_values( $data ), + ), + ); + + $this->post_execution(); + + return $result; + } + + /** + * Deletes a record from the database. + * + * @param array $where Where clauses for the query. + * @param array|string|null $format Formats for the data. + * + * @return int|false + */ + public function delete( array $where, $format = null ) { + $this->pre_execution(); + + $result = $this->database->delete( $this->get_table_name(), $where, $format ); + + $this->post_execution(); + + return $result; + } + + /** + * Executes the given query and returns the results. + * + * @param string $query The query to execute. + * + * @return array|object|null The resultset + */ + public function get_results( $query ) { + $this->pre_execution(); + + $results = $this->database->get_results( $query ); + + $this->post_execution(); + + return $results; + } + + /** + * Creates a table to the database. + * + * @param array $columns The columns to create. + * @param array $indexes The indexes to use. + * + * @return bool True when creation is successful. + */ + public function create_table( array $columns, array $indexes = [] ) { + $create_table = sprintf( + 'CREATE TABLE IF NOT EXISTS %1$s ( %2$s ) %3$s', + $this->get_table_name(), + implode( ',', array_merge( $columns, $indexes ) ), + $this->database->get_charset_collate(), + ); + + $this->pre_execution(); + + $is_created = (bool) $this->database->query( $create_table ); + + $this->post_execution(); + + return $is_created; + } + + /** + * Checks if there is an error. + * + * @return bool Returns true when there is an error. + */ + public function has_error() { + return ( $this->database->last_error !== '' ); + } + + /** + * Executed before a query will be ran. + * + * @return void + */ + protected function pre_execution() { + if ( $this->suppress_errors ) { + $this->last_suppressed_state = $this->database->suppress_errors(); + } + } + + /** + * Executed after a query has been ran. + * + * @return void + */ + protected function post_execution() { + if ( $this->suppress_errors ) { + $this->database->suppress_errors( $this->last_suppressed_state ); + } + } + + /** + * Returns the full table name. + * + * @return string Full table name including prefix. + */ + public function get_table_name() { + return $this->get_table_prefix() . $this->table_name; + } + + /** + * Returns the prefix to use for the table. + * + * @return string The table prefix depending on the database context. + */ + protected function get_table_prefix() { + if ( $this->is_multisite_table ) { + return $this->database->base_prefix; + } + + return $this->database->get_blog_prefix(); + } + + /** + * Registers the table with WordPress. + * + * @return void + */ + protected function register_table() { + $table_name = $this->table_name; + $full_table_name = $this->get_table_name(); + + $this->database->$table_name = $full_table_name; + + if ( $this->is_multisite_table ) { + $this->database->ms_global_tables[] = $table_name; + return; + } + + $this->database->tables[] = $table_name; + } + + /** + * Checks if the table has been registered with WordPress. + * + * @return bool True if the table is registered, false otherwise. + */ + protected function is_table_registered() { + if ( $this->is_multisite_table ) { + return in_array( $this->table_name, $this->database->ms_global_tables, true ); + } + + return in_array( $this->table_name, $this->database->tables, true ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-export.php b/html/wp-content/plugins/wordpress-seo/admin/class-export.php new file mode 100644 index 0000000..a9fee85 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-export.php @@ -0,0 +1,164 @@ +export_settings(); + $this->output(); + } + + /** + * Outputs the export. + * + * @return void + */ + public function output() { + if ( ! WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ) { + esc_html_e( 'You do not have the required rights to export settings.', 'wordpress-seo' ); + return; + } + + echo '

            '; + printf( + /* translators: %1$s expands to Import settings */ + esc_html__( + 'Copy all these settings to another site\'s %1$s tab and click "%1$s" there.', + 'wordpress-seo', + ), + esc_html__( + 'Import settings', + 'wordpress-seo', + ), + ); + echo '

            '; + /* translators: %1$s expands to Yoast SEO */ + echo '
            '; + echo ''; + } + + /** + * Exports the current site's WP SEO settings. + * + * @return void + */ + private function export_settings() { + $this->export_header(); + + foreach ( WPSEO_Options::get_option_names() as $opt_group ) { + $this->write_opt_group( $opt_group ); + } + } + + /** + * Writes the header of the export. + * + * @return void + */ + private function export_header() { + $header = sprintf( + /* translators: %1$s expands to Yoast SEO, %2$s expands to Yoast.com */ + esc_html__( 'These are settings for the %1$s plugin by %2$s', 'wordpress-seo' ), + 'Yoast SEO', + 'Yoast.com', + ); + $this->write_line( '; ' . $header ); + } + + /** + * Writes a line to the export. + * + * @param string $line Line string. + * @param bool $newline_first Boolean flag whether to prepend with new line. + * + * @return void + */ + private function write_line( $line, $newline_first = false ) { + if ( $newline_first ) { + $this->export .= PHP_EOL; + } + $this->export .= $line . PHP_EOL; + } + + /** + * Writes an entire option group to the export. + * + * @param string $opt_group Option group name. + * + * @return void + */ + private function write_opt_group( $opt_group ) { + + $this->write_line( '[' . $opt_group . ']', true ); + + $options = get_option( $opt_group ); + + if ( ! is_array( $options ) ) { + return; + } + + foreach ( $options as $key => $elem ) { + if ( is_array( $elem ) ) { + $count = count( $elem ); + for ( $i = 0; $i < $count; $i++ ) { + $elem_check = ( $elem[ $i ] ?? null ); + $this->write_setting( $key . '[]', $elem_check ); + } + } + else { + $this->write_setting( $key, $elem ); + } + } + } + + /** + * Writes a settings line to the export. + * + * @param string $key Key string. + * @param string $val Value string. + * + * @return void + */ + private function write_setting( $key, $val ) { + if ( is_string( $val ) ) { + $val = '"' . $val . '"'; + } + $this->write_line( $key . ' = ' . $val ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-expose-shortlinks.php b/html/wp-content/plugins/wordpress-seo/admin/class-expose-shortlinks.php new file mode 100644 index 0000000..0da0095 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-expose-shortlinks.php @@ -0,0 +1,129 @@ + 'https://yoa.st/allow-search-engines', + 'shortlinks.advanced.follow_links' => 'https://yoa.st/follow-links', + 'shortlinks.advanced.meta_robots' => 'https://yoa.st/meta-robots-advanced', + 'shortlinks.advanced.breadcrumbs_title' => 'https://yoa.st/breadcrumbs-title', + 'shortlinks.metabox.schema.explanation' => 'https://yoa.st/400', + 'shortlinks.metabox.schema.page_type' => 'https://yoa.st/402', + 'shortlinks.sidebar.schema.explanation' => 'https://yoa.st/401', + 'shortlinks.sidebar.schema.page_type' => 'https://yoa.st/403', + 'shortlinks.focus_keyword_info' => 'https://yoa.st/focus-keyword', + 'shortlinks.nofollow_sponsored' => 'https://yoa.st/nofollow-sponsored', + 'shortlinks.snippet_preview_info' => 'https://yoa.st/snippet-preview', + 'shortlinks.cornerstone_content_info' => 'https://yoa.st/1i9', + 'shortlinks.upsell.social_preview.social' => 'https://yoa.st/social-preview-facebook', + 'shortlinks.upsell.social_preview.x' => 'https://yoa.st/social-preview-twitter', + 'shortlinks.upsell.sidebar.news' => 'https://yoa.st/get-news-sidebar', + 'shortlinks.upsell.sidebar.premium_seo_analysis_button' => 'https://yoa.st/premium-seo-analysis-sidebar', + 'shortlinks.upsell.sidebar.additional_link' => 'https://yoa.st/textlink-keywords-sidebar', + 'shortlinks.upsell.sidebar.additional_button' => 'https://yoa.st/add-keywords-sidebar', + 'shortlinks.upsell.sidebar.word_complexity' => 'https://yoa.st/word-complexity-sidebar', + 'shortlinks.upsell.sidebar.internal_linking_suggestions' => 'https://yoa.st/internal-linking-suggestions-sidebar', + 'shortlinks.upsell.sidebar.highlighting_seo_analysis' => 'https://yoa.st/highlighting-seo-analysis', + 'shortlinks.upsell.sidebar.highlighting_readability_analysis' => 'https://yoa.st/highlighting-readability-analysis', + 'shortlinks.upsell.sidebar.highlighting_inclusive_analysis' => 'https://yoa.st/highlighting-inclusive-analysis', + 'shortlinks.upsell.sidebar.content_blocks' => 'https://yoa.st/content-blocks-sidebar', + 'shortlinks.upsell.metabox.news' => 'https://yoa.st/get-news-metabox', + 'shortlinks.upsell.metabox.go_premium' => 'https://yoa.st/pe-premium-page', + 'shortlinks.upsell.metabox.premium_seo_analysis_button' => 'https://yoa.st/premium-seo-analysis-metabox', + 'shortlinks.upsell.metabox.additional_link' => 'https://yoa.st/textlink-keywords-metabox', + 'shortlinks.upsell.metabox.additional_button' => 'https://yoa.st/add-keywords-metabox', + 'shortlinks.upsell.metabox.word_complexity' => 'https://yoa.st/word-complexity-metabox', + 'shortlinks.upsell.metabox.internal_linking_suggestions' => 'https://yoa.st/internal-linking-suggestions-metabox', + 'shortlinks.upsell.metabox.content_blocks' => 'https://yoa.st/content-blocks-metabox', + 'shortlinks.upsell.gsc.create_redirect_button' => 'https://yoa.st/redirects', + 'shortlinks.readability_analysis_info' => 'https://yoa.st/readability-analysis', + 'shortlinks.inclusive_language_analysis_info' => 'https://yoa.st/inclusive-language-analysis', + 'shortlinks.activate_premium_info' => 'https://yoa.st/activate-subscription', + 'shortlinks.wincher.seo_performance' => 'https://yoa.st/wincher-integration', + 'shortlinks-insights-estimated_reading_time' => 'https://yoa.st/4fd', + 'shortlinks-insights-flesch_reading_ease' => 'https://yoa.st/34r', + 'shortlinks-insights-flesch_reading_ease_sidebar' => 'https://yoa.st/4mf', + 'shortlinks-insights-flesch_reading_ease_metabox' => 'https://yoa.st/4mg', + 'shortlinks-insights-flesch_reading_ease_article' => 'https://yoa.st/34s', + 'shortlinks-insights-keyword_research_link' => 'https://yoa.st/keyword-research-metabox', + 'shortlinks-insights-upsell-sidebar-prominent_words' => 'https://yoa.st/prominent-words-upsell-sidebar', + 'shortlinks-insights-upsell-metabox-prominent_words' => 'https://yoa.st/prominent-words-upsell-metabox', + 'shortlinks-insights-upsell-elementor-prominent_words' => 'https://yoa.st/prominent-words-upsell-elementor', + 'shortlinks-insights-word_count' => 'https://yoa.st/word-count', + 'shortlinks-insights-upsell-sidebar-text_formality' => 'https://yoa.st/formality-upsell-sidebar', + 'shortlinks-insights-upsell-metabox-text_formality' => 'https://yoa.st/formality-upsell-metabox', + 'shortlinks-insights-upsell-elementor-text_formality' => 'https://yoa.st/formality-upsell-elementor', + 'shortlinks-insights-text_formality_info_free' => 'https://yoa.st/formality-free', + 'shortlinks-insights-text_formality_info_premium' => 'https://yoa.st/formality', + ]; + + /** + * Registers all hooks to WordPress. + * + * @return void + */ + public function register_hooks() { + add_filter( 'wpseo_admin_l10n', [ $this, 'expose_shortlinks' ] ); + } + + /** + * Adds shortlinks to the passed array. + * + * @param array $input The array to add shortlinks to. + * + * @return array The passed array with the additional shortlinks. + */ + public function expose_shortlinks( $input ) { + foreach ( $this->get_shortlinks() as $key => $shortlink ) { + $input[ $key ] = WPSEO_Shortlinker::get( $shortlink ); + } + + $input['default_query_params'] = WPSEO_Shortlinker::get_query_params(); + + return $input; + } + + /** + * Retrieves the shortlinks. + * + * @return array The shortlinks. + */ + private function get_shortlinks() { + if ( ! $this->is_term_edit() ) { + return $this->shortlinks; + } + + $shortlinks = $this->shortlinks; + + $shortlinks['shortlinks.upsell.metabox.additional_link'] = 'https://yoa.st/textlink-keywords-metabox-term'; + $shortlinks['shortlinks.upsell.metabox.additional_button'] = 'https://yoa.st/add-keywords-metabox-term'; + $shortlinks['shortlinks.upsell.metabox.word_complexity'] = 'https://yoa.st/word-complexity-metabox-term'; + $shortlinks['shortlinks.upsell.metabox.internal_linking_suggestions'] = 'https://yoa.st/internal-linking-suggestions-metabox-term'; + + return $shortlinks; + } + + /** + * Checks if the current page is a term edit page. + * + * @return bool True when page is term edit. + */ + private function is_term_edit() { + global $pagenow; + + return WPSEO_Taxonomy::is_term_edit( $pagenow ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-gutenberg-compatibility.php b/html/wp-content/plugins/wordpress-seo/admin/class-gutenberg-compatibility.php new file mode 100644 index 0000000..56957df --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-gutenberg-compatibility.php @@ -0,0 +1,107 @@ +current_version = $this->detect_installed_gutenberg_version(); + } + + /** + * Determines whether or not Gutenberg is installed. + * + * @return bool Whether or not Gutenberg is installed. + */ + public function is_installed() { + return $this->current_version !== ''; + } + + /** + * Determines whether or not the currently installed version of Gutenberg is below the minimum supported version. + * + * @return bool True if the currently installed version is below the minimum supported version. False otherwise. + */ + public function is_below_minimum() { + return version_compare( $this->current_version, $this->get_minimum_supported_version(), '<' ); + } + + /** + * Gets the currently installed version. + * + * @return string The currently installed version. + */ + public function get_installed_version() { + return $this->current_version; + } + + /** + * Determines whether or not the currently installed version of Gutenberg is the latest, fully compatible version. + * + * @return bool Whether or not the currently installed version is fully compatible. + */ + public function is_fully_compatible() { + return version_compare( $this->current_version, $this->get_latest_release(), '>=' ); + } + + /** + * Gets the latest released version of Gutenberg. + * + * @return string The latest release. + */ + protected function get_latest_release() { + return self::CURRENT_RELEASE; + } + + /** + * Gets the minimum supported version of Gutenberg. + * + * @return string The minumum supported release. + */ + protected function get_minimum_supported_version() { + return self::MINIMUM_SUPPORTED; + } + + /** + * Detects the currently installed Gutenberg version. + * + * @return string The currently installed Gutenberg version. Empty if the version couldn't be detected. + */ + protected function detect_installed_gutenberg_version() { + if ( defined( 'GUTENBERG_VERSION' ) ) { + return GUTENBERG_VERSION; + } + + return ''; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-meta-columns.php b/html/wp-content/plugins/wordpress-seo/admin/class-meta-columns.php new file mode 100644 index 0000000..14ffecf --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-meta-columns.php @@ -0,0 +1,912 @@ +analysis_seo = new WPSEO_Metabox_Analysis_SEO(); + $this->analysis_readability = new WPSEO_Metabox_Analysis_Readability(); + $this->admin_columns_cache = YoastSEO()->classes->get( Admin_Columns_Cache_Integration::class ); + $this->score_icon_helper = YoastSEO()->helpers->score_icon; + $this->admin_asset_manager = YoastSEO()->classes->get( WPSEO_Admin_Asset_Manager::class ); + } + + /** + * Sets up up the hooks. + * + * @return void + */ + public function setup_hooks() { + $this->set_post_type_hooks(); + + if ( $this->analysis_seo->is_enabled() ) { + add_action( 'restrict_manage_posts', [ $this, 'posts_filter_dropdown' ] ); + } + + if ( $this->analysis_readability->is_enabled() ) { + add_action( 'restrict_manage_posts', [ $this, 'posts_filter_dropdown_readability' ] ); + } + + add_filter( 'request', [ $this, 'column_sort_orderby' ] ); + add_filter( 'default_hidden_columns', [ $this, 'column_hidden' ], 10, 1 ); + } + + /** + * Adds the column headings for the SEO plugin for edit posts / pages overview. + * + * @param array $columns Already existing columns. + * + * @return array Array containing the column headings. + */ + public function column_heading( $columns ) { + if ( $this->display_metabox() === false ) { + return $columns; + } + + $this->admin_asset_manager->enqueue_script( 'edit-page' ); + $this->admin_asset_manager->enqueue_style( 'edit-page' ); + + $added_columns = []; + + if ( $this->analysis_seo->is_enabled() ) { + $added_columns['wpseo-score'] = '' + . __( 'SEO score', 'wordpress-seo' ) + . ''; + } + + if ( $this->analysis_readability->is_enabled() ) { + $added_columns['wpseo-score-readability'] = '' + . __( 'Readability score', 'wordpress-seo' ) + . ''; + } + + $added_columns['wpseo-title'] = __( 'SEO Title', 'wordpress-seo' ); + $added_columns['wpseo-metadesc'] = __( 'Meta Desc.', 'wordpress-seo' ); + + if ( $this->analysis_seo->is_enabled() ) { + $added_columns['wpseo-focuskw'] = __( 'Keyphrase', 'wordpress-seo' ); + } + + return array_merge( $columns, $added_columns ); + } + + /** + * Displays the column content for the given column. + * + * @param string $column_name Column to display the content for. + * @param int $post_id Post to display the column content for. + * + * @return void + */ + public function column_content( $column_name, $post_id ) { + if ( $this->display_metabox() === false ) { + return; + } + + switch ( $column_name ) { + case 'wpseo-score': + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in render_score_indicator() method. + echo $this->parse_column_score( $post_id ); + + return; + + case 'wpseo-score-readability': + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in render_score_indicator() method. + echo $this->parse_column_score_readability( $post_id ); + + return; + + case 'wpseo-title': + $meta = $this->get_meta( $post_id ); + if ( $meta ) { + echo esc_html( $meta->title ); + } + + return; + + case 'wpseo-metadesc': + $metadesc_val = ''; + $meta = $this->get_meta( $post_id ); + if ( $meta ) { + $metadesc_val = $meta->meta_description; + } + if ( $metadesc_val === '' ) { + echo '', + /* translators: Hidden accessibility text. */ + esc_html__( 'Meta description not set.', 'wordpress-seo' ), + ''; + + return; + } + + echo esc_html( $metadesc_val ); + + return; + + case 'wpseo-focuskw': + $focuskw_val = WPSEO_Meta::get_value( 'focuskw', $post_id ); + + if ( $focuskw_val === '' ) { + echo '', + /* translators: Hidden accessibility text. */ + esc_html__( 'Focus keyphrase not set.', 'wordpress-seo' ), + ''; + + return; + } + + echo esc_html( $focuskw_val ); + + return; + } + } + + /** + * Indicates which of the SEO columns are sortable. + * + * @param array $columns Appended with their orderby variable. + * + * @return array Array containing the sortable columns. + */ + public function column_sort( $columns ) { + if ( $this->display_metabox() === false ) { + return $columns; + } + + $columns['wpseo-metadesc'] = 'wpseo-metadesc'; + + if ( $this->analysis_seo->is_enabled() ) { + $columns['wpseo-focuskw'] = 'wpseo-focuskw'; + $columns['wpseo-score'] = 'wpseo-score'; + } + + if ( $this->analysis_readability->is_enabled() ) { + $columns['wpseo-score-readability'] = 'wpseo-score-readability'; + } + + return $columns; + } + + /** + * Hides the SEO title, meta description and focus keyword columns if the user hasn't chosen which columns to hide. + * + * @param array $hidden The hidden columns. + * + * @return array Array containing the columns to hide. + */ + public function column_hidden( $hidden ) { + if ( ! is_array( $hidden ) ) { + $hidden = []; + } + + array_push( $hidden, 'wpseo-title', 'wpseo-metadesc' ); + + if ( $this->analysis_seo->is_enabled() ) { + $hidden[] = 'wpseo-focuskw'; + } + + return $hidden; + } + + /** + * Adds a dropdown that allows filtering on the posts SEO Quality. + * + * @return void + */ + public function posts_filter_dropdown() { + if ( ! $this->can_display_filter() ) { + return; + } + + $ranks = WPSEO_Rank::get_all_ranks(); + + /* translators: Hidden accessibility text. */ + echo ''; + echo ''; + } + + /** + * Adds a dropdown that allows filtering on the posts Readability Quality. + * + * @return void + */ + public function posts_filter_dropdown_readability() { + if ( ! $this->can_display_filter() ) { + return; + } + + $ranks = WPSEO_Rank::get_all_readability_ranks(); + + /* translators: Hidden accessibility text. */ + echo ''; + echo ''; + } + + /** + * Generates an '; + } + + /** + * Returns the meta object for a given post ID. + * + * @param int $post_id The post ID. + * + * @return Meta The meta object. + */ + protected function get_meta( $post_id ) { + $indexable = $this->admin_columns_cache->get_indexable( $post_id ); + + return YoastSEO()->meta->for_indexable( $indexable, 'Post_Type' ); + } + + /** + * Determines the SEO score filter to be later used in the meta query, based on the passed SEO filter. + * + * @param string $seo_filter The SEO filter to use to determine what further filter to apply. + * + * @return array The SEO score filter. + */ + protected function determine_seo_filters( $seo_filter ) { + if ( $seo_filter === WPSEO_Rank::NO_FOCUS ) { + return $this->create_no_focus_keyword_filter(); + } + + if ( $seo_filter === WPSEO_Rank::NO_INDEX ) { + return $this->create_no_index_filter(); + } + + $rank = new WPSEO_Rank( $seo_filter ); + + return $this->create_seo_score_filter( $rank->get_starting_score(), $rank->get_end_score() ); + } + + /** + * Determines the Readability score filter to the meta query, based on the passed Readability filter. + * + * @param string $readability_filter The Readability filter to use to determine what further filter to apply. + * + * @return array The Readability score filter. + */ + protected function determine_readability_filters( $readability_filter ) { + if ( $readability_filter === WPSEO_Rank::NO_FOCUS ) { + return $this->create_no_readability_scores_filter(); + } + if ( $readability_filter === WPSEO_Rank::BAD ) { + return $this->create_bad_readability_scores_filter(); + } + $rank = new WPSEO_Rank( $readability_filter ); + + return $this->create_readability_score_filter( $rank->get_starting_score(), $rank->get_end_score() ); + } + + /** + * Creates a keyword filter for the meta query, based on the passed Keyword filter. + * + * @param string $keyword_filter The keyword filter to use. + * + * @return array The keyword filter. + */ + protected function get_keyword_filter( $keyword_filter ) { + return [ + 'post_type' => get_query_var( 'post_type', 'post' ), + 'key' => WPSEO_Meta::$meta_prefix . 'focuskw', + 'value' => sanitize_text_field( $keyword_filter ), + ]; + } + + /** + * Determines whether the passed filter is considered to be valid. + * + * @param mixed $filter The filter to check against. + * + * @return bool Whether the filter is considered valid. + */ + protected function is_valid_filter( $filter ) { + return ! empty( $filter ) && is_string( $filter ); + } + + /** + * Collects the filters and merges them into a single array. + * + * @return array Array containing all the applicable filters. + */ + protected function collect_filters() { + $active_filters = []; + + $seo_filter = $this->get_current_seo_filter(); + $readability_filter = $this->get_current_readability_filter(); + $current_keyword_filter = $this->get_current_keyword_filter(); + + if ( $this->is_valid_filter( $seo_filter ) ) { + $active_filters = array_merge( + $active_filters, + $this->determine_seo_filters( $seo_filter ), + ); + } + + if ( $this->is_valid_filter( $readability_filter ) ) { + $active_filters = array_merge( + $active_filters, + $this->determine_readability_filters( $readability_filter ), + ); + } + + if ( $this->is_valid_filter( $current_keyword_filter ) ) { + /** + * Adapt the meta query used to filter the post overview on keyphrase. + * + * @internal + * + * @param array $keyphrase The keyphrase used in the filter. + * @param array $keyword_filter The current keyword filter. + */ + $keyphrase_filter = apply_filters( + 'wpseo_change_keyphrase_filter_in_request', + $this->get_keyword_filter( $current_keyword_filter ), + $current_keyword_filter, + ); + + if ( is_array( $keyphrase_filter ) ) { + $active_filters = array_merge( + $active_filters, + [ $keyphrase_filter ], + ); + } + } + + /** + * Adapt the active applicable filters on the posts overview. + * + * @internal + * + * @param array $active_filters The current applicable filters. + */ + return apply_filters( 'wpseo_change_applicable_filters', $active_filters ); + } + + /** + * Modify the query based on the filters that are being passed. + * + * @param array $vars Query variables that need to be modified based on the filters. + * + * @return array Array containing the meta query to use for filtering the posts overview. + */ + public function column_sort_orderby( $vars ) { + $collected_filters = $this->collect_filters(); + + $order_by_column = $vars['orderby']; + if ( isset( $order_by_column ) ) { + // Based on the selected column, create a meta query. + $order_by = $this->filter_order_by( $order_by_column ); + + /** + * Adapt the order by part of the query on the posts overview. + * + * @internal + * + * @param array $order_by The current order by. + * @param string $order_by_column The current order by column. + */ + $order_by = apply_filters( 'wpseo_change_order_by', $order_by, $order_by_column ); + + $vars = array_merge( $vars, $order_by ); + } + + return $this->build_filter_query( $vars, $collected_filters ); + } + + /** + * Retrieves the meta robots query values to be used within the meta query. + * + * @return array Array containing the query parameters regarding meta robots. + */ + protected function get_meta_robots_query_values() { + return [ + 'relation' => 'OR', + [ + 'key' => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', + 'compare' => 'NOT EXISTS', + ], + [ + 'key' => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', + 'value' => '1', + 'compare' => '!=', + ], + ]; + } + + /** + * Determines the score filters to be used. If more than one is passed, it created an AND statement for the query. + * + * @param array $score_filters Array containing the score filters. + * + * @return array Array containing the score filters that need to be applied to the meta query. + */ + protected function determine_score_filters( $score_filters ) { + if ( count( $score_filters ) > 1 ) { + return array_merge( [ 'relation' => 'AND' ], $score_filters ); + } + + return $score_filters; + } + + /** + * Retrieves the post type from the $_GET variable. + * + * @return string|null The sanitized current post type or null when the variable is not set in $_GET. + */ + public function get_current_post_type() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['post_type'] ) && is_string( $_GET['post_type'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET['post_type'] ) ); + } + return null; + } + + /** + * Retrieves the SEO filter from the $_GET variable. + * + * @return string|null The sanitized seo filter or null when the variable is not set in $_GET. + */ + public function get_current_seo_filter() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['seo_filter'] ) && is_string( $_GET['seo_filter'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET['seo_filter'] ) ); + } + return null; + } + + /** + * Retrieves the Readability filter from the $_GET variable. + * + * @return string|null The sanitized readability filter or null when the variable is not set in $_GET. + */ + public function get_current_readability_filter() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['readability_filter'] ) && is_string( $_GET['readability_filter'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET['readability_filter'] ) ); + } + return null; + } + + /** + * Retrieves the keyword filter from the $_GET variable. + * + * @return string|null The sanitized seo keyword filter or null when the variable is not set in $_GET. + */ + public function get_current_keyword_filter() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['seo_kw_filter'] ) && is_string( $_GET['seo_kw_filter'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET['seo_kw_filter'] ) ); + } + return null; + } + + /** + * Uses the vars to create a complete filter query that can later be executed to filter out posts. + * + * @param array $vars Array containing the variables that will be used in the meta query. + * @param array $filters Array containing the filters that we need to apply in the meta query. + * + * @return array Array containing the complete filter query. + */ + protected function build_filter_query( $vars, $filters ) { + // If no filters were applied, just return everything. + if ( count( $filters ) === 0 ) { + return $vars; + } + + $result = [ 'meta_query' => [] ]; + $result['meta_query'] = array_merge( $result['meta_query'], [ $this->determine_score_filters( $filters ) ] ); + + $current_seo_filter = $this->get_current_seo_filter(); + + // This only applies for the SEO score filter because it can because the SEO score can be altered by the no-index option. + if ( $this->is_valid_filter( $current_seo_filter ) && ! in_array( $current_seo_filter, [ WPSEO_Rank::NO_INDEX ], true ) ) { + $result['meta_query'] = array_merge( $result['meta_query'], [ $this->get_meta_robots_query_values() ] ); + } + + return array_merge( $vars, $result ); + } + + /** + * Creates a Readability score filter. + * + * @param number $low The lower boundary of the score. + * @param number $high The higher boundary of the score. + * + * @return array> The Readability Score filter. + */ + protected function create_readability_score_filter( $low, $high ) { + return [ + [ + 'key' => WPSEO_Meta::$meta_prefix . 'content_score', + 'value' => [ $low, $high ], + 'type' => 'numeric', + 'compare' => 'BETWEEN', + ], + ]; + } + + /** + * Creates an SEO score filter. + * + * @param number $low The lower boundary of the score. + * @param number $high The higher boundary of the score. + * + * @return array> The SEO score filter. + */ + protected function create_seo_score_filter( $low, $high ) { + return [ + [ + 'key' => WPSEO_Meta::$meta_prefix . 'linkdex', + 'value' => [ $low, $high ], + 'type' => 'numeric', + 'compare' => 'BETWEEN', + ], + ]; + } + + /** + * Creates a filter to retrieve posts that were set to no-index. + * + * @return array> Array containin the no-index filter. + */ + protected function create_no_index_filter() { + return [ + [ + 'key' => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', + 'value' => '1', + 'compare' => '=', + ], + ]; + } + + /** + * Creates a filter to retrieve posts that have no keyword set. + * + * @return array> Array containing the no focus keyword filter. + */ + protected function create_no_focus_keyword_filter() { + return [ + [ + 'key' => WPSEO_Meta::$meta_prefix . 'linkdex', + 'value' => 'needs-a-value-anyway', + 'compare' => 'NOT EXISTS', + ], + ]; + } + + /** + * Creates a filter to retrieve posts that have not been analyzed for readability yet. + * + * @return array> Array containing the no readability filter. + */ + protected function create_no_readability_scores_filter() { + // We check the existence of the Estimated Reading Time, because readability scores of posts that haven't been manually saved while Yoast SEO is active, don't exist, which is also the case for posts with not enough content. + // Meanwhile, the ERT is a solid indicator of whether a post has ever been saved (aka, analyzed), so we're using that. + $rank = new WPSEO_Rank( WPSEO_Rank::BAD ); + return [ + [ + 'key' => WPSEO_Meta::$meta_prefix . 'estimated-reading-time-minutes', + 'value' => 'needs-a-value-anyway', + 'compare' => 'NOT EXISTS', + ], + [ + 'relation' => 'OR', + [ + 'key' => WPSEO_Meta::$meta_prefix . 'content_score', + 'value' => $rank->get_starting_score(), + 'type' => 'numeric', + 'compare' => '<', + ], + [ + 'key' => WPSEO_Meta::$meta_prefix . 'content_score', + 'value' => 'needs-a-value-anyway', + 'compare' => 'NOT EXISTS', + ], + ], + ]; + } + + /** + * Creates a filter to retrieve posts that have bad readability scores, including those that have not enough content to have one. + * + * @return array> Array containing the bad readability filter. + */ + protected function create_bad_readability_scores_filter() { + $rank = new WPSEO_Rank( WPSEO_Rank::BAD ); + return [ + 'relation' => 'OR', + [ + 'key' => WPSEO_Meta::$meta_prefix . 'content_score', + 'value' => [ $rank->get_starting_score(), $rank->get_end_score() ], + 'type' => 'numeric', + 'compare' => 'BETWEEN', + ], + [ + [ + 'key' => WPSEO_Meta::$meta_prefix . 'content_score', + 'value' => 'needs-a-value-anyway', + 'compare' => 'NOT EXISTS', + ], + [ + 'key' => WPSEO_Meta::$meta_prefix . 'estimated-reading-time-minutes', + 'compare' => 'EXISTS', + ], + ], + ]; + } + + /** + * Determines whether a particular post_id is of an indexable post type. + * + * @param string $post_id The post ID to check. + * + * @return bool Whether or not it is indexable. + */ + protected function is_indexable( $post_id ) { + if ( ! empty( $post_id ) && ! $this->uses_default_indexing( $post_id ) ) { + return WPSEO_Meta::get_value( 'meta-robots-noindex', $post_id ) === '2'; + } + + $post = get_post( $post_id ); + + if ( is_object( $post ) ) { + // If the option is false, this means we want to index it. + return WPSEO_Options::get( 'noindex-' . $post->post_type, false ) === false; + } + + return true; + } + + /** + * Determines whether the given post ID uses the default indexing settings. + * + * @param int $post_id The post ID to check. + * + * @return bool Whether or not the default indexing is being used for the post. + */ + protected function uses_default_indexing( $post_id ) { + return WPSEO_Meta::get_value( 'meta-robots-noindex', $post_id ) === '0'; + } + + /** + * Returns filters when $order_by is matched in the if-statement. + * + * @param string $order_by The ID of the column by which to order the posts. + * + * @return array Array containing the order filters. + */ + private function filter_order_by( $order_by ) { + switch ( $order_by ) { + case 'wpseo-metadesc': + return [ + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting. + 'meta_key' => WPSEO_Meta::$meta_prefix . 'metadesc', + 'orderby' => 'meta_value', + ]; + + case 'wpseo-focuskw': + return [ + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting. + 'meta_key' => WPSEO_Meta::$meta_prefix . 'focuskw', + 'orderby' => 'meta_value', + ]; + + case 'wpseo-score': + return [ + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting. + 'meta_key' => WPSEO_Meta::$meta_prefix . 'linkdex', + 'orderby' => 'meta_value_num', + ]; + + case 'wpseo-score-readability': + return [ + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: Only used when user requests sorting. + 'meta_key' => WPSEO_Meta::$meta_prefix . 'content_score', + 'orderby' => 'meta_value_num', + ]; + } + + return []; + } + + /** + * Parses the score column. + * + * @param int $post_id The ID of the post for which to show the score. + * + * @return string The HTML for the SEO score indicator. + */ + private function parse_column_score( $post_id ) { + $meta = $this->get_meta( $post_id ); + + if ( $meta ) { + return $this->score_icon_helper->for_seo( $meta->indexable, '', __( 'Post is set to noindex.', 'wordpress-seo' ) ); + } + } + + /** + * Parsing the readability score column. + * + * @param int $post_id The ID of the post for which to show the readability score. + * + * @return string The HTML for the readability score indicator. + */ + private function parse_column_score_readability( $post_id ) { + $meta = $this->get_meta( $post_id ); + if ( $meta ) { + return $this->score_icon_helper->for_readability( $meta->indexable->readability_score ); + } + } + + /** + * Sets up the hooks for the post_types. + * + * @return void + */ + private function set_post_type_hooks() { + $post_types = WPSEO_Post_Type::get_accessible_post_types(); + + if ( ! is_array( $post_types ) || $post_types === [] ) { + return; + } + + foreach ( $post_types as $post_type ) { + if ( $this->display_metabox( $post_type ) === false ) { + continue; + } + + add_filter( 'manage_' . $post_type . '_posts_columns', [ $this, 'column_heading' ], 10, 1 ); + add_action( 'manage_' . $post_type . '_posts_custom_column', [ $this, 'column_content' ], 10, 2 ); + add_action( 'manage_edit-' . $post_type . '_sortable_columns', [ $this, 'column_sort' ], 10, 2 ); + } + + unset( $post_type ); + } + + /** + * Wraps the WPSEO_Metabox check to determine whether the metabox should be displayed either by + * choice of the admin or because the post type is not a public post type. + * + * @since 7.0 + * + * @param string|null $post_type Optional. The post type to test, defaults to the current post post_type. + * + * @return bool Whether or not the meta box (and associated columns etc) should be hidden. + */ + private function display_metabox( $post_type = null ) { + $current_post_type = $this->get_current_post_type(); + + if ( ! isset( $post_type ) && ! empty( $current_post_type ) ) { + $post_type = $current_post_type; + } + + return WPSEO_Utils::is_metabox_active( $post_type, 'post_type' ); + } + + /** + * Determines whether or not filter dropdowns should be displayed. + * + * @return bool Whether or the current page can display the filter drop downs. + */ + public function can_display_filter() { + if ( $GLOBALS['pagenow'] === 'upload.php' ) { + return false; + } + + if ( $this->display_metabox() === false ) { + return false; + } + + $screen = get_current_screen(); + if ( $screen === null ) { + return false; + } + + return WPSEO_Post_Type::is_post_type_accessible( $screen->post_type ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-my-yoast-proxy.php b/html/wp-content/plugins/wordpress-seo/admin/class-my-yoast-proxy.php new file mode 100644 index 0000000..0b708dc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-my-yoast-proxy.php @@ -0,0 +1,218 @@ +is_proxy_page() ) { + return; + } + + // Register the page for the proxy. + add_action( 'admin_menu', [ $this, 'add_proxy_page' ] ); + add_action( 'admin_init', [ $this, 'handle_proxy_page' ] ); + } + + /** + * Registers the proxy page. It does not actually add a link to the dashboard. + * + * @codeCoverageIgnore + * + * @return void + */ + public function add_proxy_page() { + add_dashboard_page( '', '', 'read', self::PAGE_IDENTIFIER, '' ); + } + + /** + * Renders the requested proxy page and exits to prevent the WordPress UI from loading. + * + * @codeCoverageIgnore + * + * @return void + */ + public function handle_proxy_page() { + $this->render_proxy_page(); + + // Prevent the WordPress UI from loading. + exit(); + } + + /** + * Renders the requested proxy page. + * + * This is separated from the exits to be able to test it. + * + * @return void + */ + public function render_proxy_page() { + $proxy_options = $this->determine_proxy_options(); + if ( $proxy_options === [] ) { + // Do not accept any other file than implemented. + $this->set_header( 'HTTP/1.0 501 Requested file not implemented' ); + return; + } + + // Set the headers before serving the remote file. + $this->set_header( 'Content-Type: ' . $proxy_options['content_type'] ); + $this->set_header( 'Cache-Control: max-age=' . self::CACHE_CONTROL_MAX_AGE ); + + try { + echo $this->get_remote_url_body( $proxy_options['url'] ); + } catch ( Exception $e ) { + /* + * Reset the file headers because the loading failed. + * + * Note: Due to supporting PHP 5.2 `header_remove` can not be used here. + * Overwrite the headers instead. + */ + $this->set_header( 'Content-Type: text/plain' ); + $this->set_header( 'Cache-Control: max-age=0' ); + + $this->set_header( 'HTTP/1.0 500 ' . $e->getMessage() ); + } + } + + /** + * Tries to load the given url via `wp_remote_get`. + * + * @codeCoverageIgnore + * + * @param string $url The url to load. + * + * @return string The body of the response. + * + * @throws Exception When `wp_remote_get` returned an error. + * @throws Exception When the response code is not 200. + */ + protected function get_remote_url_body( $url ) { + $response = wp_remote_get( $url ); + + if ( $response instanceof WP_Error ) { + throw new Exception( 'Unable to retrieve file from MyYoast' ); + } + + if ( wp_remote_retrieve_response_code( $response ) !== 200 ) { + throw new Exception( 'Received unexpected response from MyYoast' ); + } + + return wp_remote_retrieve_body( $response ); + } + + /** + * Determines the proxy options based on the file and plugin version arguments. + * + * When the file is known it returns an array like this: + * + * $array = array( + * 'content_type' => 'the content type' + * 'url' => 'the url, possibly with the plugin version' + * ) + * + * + * @return array Empty for an unknown file. See format above for known files. + */ + protected function determine_proxy_options() { + if ( $this->get_proxy_file() === 'research-webworker' ) { + return [ + 'content_type' => 'text/javascript; charset=UTF-8', + 'url' => 'https://my.yoast.com/api/downloads/file/analysis-worker?plugin_version=' . $this->get_plugin_version(), + ]; + } + + return []; + } + + /** + * Checks if the current page is the MyYoast proxy page. + * + * @codeCoverageIgnore + * + * @return bool True when the page request parameter equals the proxy page. + */ + protected function is_proxy_page() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $page = isset( $_GET['page'] ) && is_string( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; + return $page === self::PAGE_IDENTIFIER; + } + + /** + * Returns the proxy file from the HTTP request parameters. + * + * @codeCoverageIgnore + * + * @return string The sanitized file request parameter or an empty string if it does not exist. + */ + protected function get_proxy_file() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['file'] ) && is_string( $_GET['file'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET['file'] ) ); + } + return ''; + } + + /** + * Returns the plugin version from the HTTP request parameters. + * + * @codeCoverageIgnore + * + * @return string The sanitized plugin_version request parameter or an empty string if it does not exist. + */ + protected function get_plugin_version() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['plugin_version'] ) && is_string( $_GET['plugin_version'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $plugin_version = sanitize_text_field( wp_unslash( $_GET['plugin_version'] ) ); + // Replace slashes to secure against requiring a file from another path. + return str_replace( [ '/', '\\' ], '_', $plugin_version ); + } + return ''; + } + + /** + * Sets the HTTP header. + * + * This is a tiny helper function to enable better testing. + * + * @codeCoverageIgnore + * + * @param string $header The header to set. + * + * @return void + */ + protected function set_header( $header ) { + header( $header ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-option-tab.php b/html/wp-content/plugins/wordpress-seo/admin/class-option-tab.php new file mode 100644 index 0000000..4a23125 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-option-tab.php @@ -0,0 +1,112 @@ +name = sanitize_title( $name ); + $this->label = $label; + $this->arguments = $arguments; + } + + /** + * Gets the name. + * + * @return string The name. + */ + public function get_name() { + return $this->name; + } + + /** + * Gets the label. + * + * @return string The label. + */ + public function get_label() { + return $this->label; + } + + /** + * Retrieves whether the tab needs a save button. + * + * @return bool True whether the tabs needs a save button. + */ + public function has_save_button() { + return (bool) $this->get_argument( 'save_button', true ); + } + + /** + * Retrieves whether the tab hosts beta functionalities. + * + * @return bool True whether the tab hosts beta functionalities. + */ + public function is_beta() { + return (bool) $this->get_argument( 'beta', false ); + } + + /** + * Retrieves whether the tab hosts premium functionalities. + * + * @return bool True whether the tab hosts premium functionalities. + */ + public function is_premium() { + return (bool) $this->get_argument( 'premium', false ); + } + + /** + * Gets the option group. + * + * @return string The option group. + */ + public function get_opt_group() { + return $this->get_argument( 'opt_group' ); + } + + /** + * Retrieves the variable from the supplied arguments. + * + * @param string $variable Variable to retrieve. + * @param string|mixed $default_value Default to use when variable not found. + * + * @return mixed|string The retrieved variable. + */ + protected function get_argument( $variable, $default_value = '' ) { + return array_key_exists( $variable, $this->arguments ) ? $this->arguments[ $variable ] : $default_value; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-option-tabs-formatter.php b/html/wp-content/plugins/wordpress-seo/admin/class-option-tabs-formatter.php new file mode 100644 index 0000000..b59f678 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-option-tabs-formatter.php @@ -0,0 +1,93 @@ +get_base() . '/' . $tab->get_name() . '.php'; + } + + /** + * Outputs the option tabs. + * + * @param WPSEO_Option_Tabs $option_tabs Option Tabs to get tabs from. + * + * @return void + */ + public function run( WPSEO_Option_Tabs $option_tabs ) { + + echo ''; + + foreach ( $option_tabs->get_tabs() as $tab ) { + $identifier = $tab->get_name(); + + $class = 'wpseotab ' . ( $tab->has_save_button() ? 'save' : 'nosave' ); + printf( '
            ', esc_attr( $identifier ), esc_attr( $class ) ); + + $tab_filter_name = sprintf( '%s_%s', $option_tabs->get_base(), $tab->get_name() ); + + /** + * Allows to override the content that is display on the specific option tab. + * + * @internal For internal Yoast SEO use only. + * + * @param string|null $tab_contents The content that should be displayed for this tab. Leave empty for default behaviour. + * @param WPSEO_Option_Tabs $option_tabs The registered option tabs. + * @param WPSEO_Option_Tab $tab The tab that is being displayed. + */ + $option_tab_content = apply_filters( 'wpseo_option_tab-' . $tab_filter_name, null, $option_tabs, $tab ); + if ( ! empty( $option_tab_content ) ) { + echo wp_kses_post( $option_tab_content ); + } + + if ( empty( $option_tab_content ) ) { + // Output the settings view for all tabs. + $tab_view = $this->get_tab_view( $option_tabs, $tab ); + + if ( is_file( $tab_view ) ) { + $yform = Yoast_Form::get_instance(); + require $tab_view; + } + } + + echo '
            '; + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-option-tabs.php b/html/wp-content/plugins/wordpress-seo/admin/class-option-tabs.php new file mode 100644 index 0000000..fb0c451 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-option-tabs.php @@ -0,0 +1,124 @@ +base = sanitize_title( $base ); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $tab = isset( $_GET['tab'] ) && is_string( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : ''; + $this->active_tab = empty( $tab ) ? $active_tab : $tab; + } + + /** + * Get the base. + * + * @return string + */ + public function get_base() { + return $this->base; + } + + /** + * Add a tab. + * + * @param WPSEO_Option_Tab $tab Tab to add. + * + * @return $this + */ + public function add_tab( WPSEO_Option_Tab $tab ) { + $this->tabs[] = $tab; + + return $this; + } + + /** + * Get active tab. + * + * @return WPSEO_Option_Tab|null Get the active tab. + */ + public function get_active_tab() { + if ( empty( $this->active_tab ) ) { + return null; + } + + $active_tabs = array_filter( $this->tabs, [ $this, 'is_active_tab' ] ); + if ( ! empty( $active_tabs ) ) { + $active_tabs = array_values( $active_tabs ); + if ( count( $active_tabs ) === 1 ) { + return $active_tabs[0]; + } + } + + return null; + } + + /** + * Is the tab the active tab. + * + * @param WPSEO_Option_Tab $tab Tab to check for active tab. + * + * @return bool + */ + public function is_active_tab( WPSEO_Option_Tab $tab ) { + return ( $tab->get_name() === $this->active_tab ); + } + + /** + * Get all tabs. + * + * @return WPSEO_Option_Tab[] + */ + public function get_tabs() { + return $this->tabs; + } + + /** + * Display the tabs. + * + * @param Yoast_Form $yform Yoast Form needed in the views. + * + * @return void + */ + public function display( Yoast_Form $yform ) { + $formatter = new WPSEO_Option_Tabs_Formatter(); + $formatter->run( $this, $yform ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-paper-presenter.php b/html/wp-content/plugins/wordpress-seo/admin/class-paper-presenter.php new file mode 100644 index 0000000..99550e4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-paper-presenter.php @@ -0,0 +1,141 @@ + null, + 'paper_id_prefix' => 'wpseo-', + 'collapsible' => false, + 'collapsible_header_class' => '', + 'expanded' => false, + 'help_text' => '', + 'title_after' => '', + 'class' => '', + 'content' => '', + 'view_data' => [], + ]; + + $this->settings = wp_parse_args( $settings, $defaults ); + $this->title = $title; + $this->view_file = $view_file; + } + + /** + * Renders the collapsible paper and returns it as a string. + * + * @return string The rendered paper. + */ + public function get_output() { + $view_variables = $this->get_view_variables(); + + extract( $view_variables, EXTR_SKIP ); + + $content = $this->settings['content']; + + if ( $this->view_file !== null ) { + ob_start(); + require $this->view_file; + $content = ob_get_clean(); + } + + ob_start(); + require WPSEO_PATH . 'admin/views/paper-collapsible.php'; + $rendered_output = ob_get_clean(); + + return $rendered_output; + } + + /** + * Retrieves the view variables. + * + * @return array The view variables. + */ + private function get_view_variables() { + if ( $this->settings['help_text'] instanceof WPSEO_Admin_Help_Panel === false ) { + $this->settings['help_text'] = new WPSEO_Admin_Help_Panel( '', '', '' ); + } + + $view_variables = [ + 'class' => $this->settings['class'], + 'collapsible' => $this->settings['collapsible'], + 'collapsible_config' => $this->collapsible_config(), + 'collapsible_header_class' => $this->settings['collapsible_header_class'], + 'title_after' => $this->settings['title_after'], + 'help_text' => $this->settings['help_text'], + 'view_file' => $this->view_file, + 'title' => $this->title, + 'paper_id' => $this->settings['paper_id'], + 'paper_id_prefix' => $this->settings['paper_id_prefix'], + 'yform' => Yoast_Form::get_instance(), + ]; + + return array_merge( $this->settings['view_data'], $view_variables ); + } + + /** + * Retrieves the collapsible config based on the settings. + * + * @return array The config. + */ + protected function collapsible_config() { + if ( empty( $this->settings['collapsible'] ) ) { + return [ + 'toggle_icon' => '', + 'class' => '', + 'expanded' => '', + ]; + } + + if ( ! empty( $this->settings['expanded'] ) ) { + return [ + 'toggle_icon' => 'dashicons-arrow-up-alt2', + 'class' => 'toggleable-container', + 'expanded' => 'true', + ]; + } + + return [ + 'toggle_icon' => 'dashicons-arrow-down-alt2', + 'class' => 'toggleable-container toggleable-container-hidden', + 'expanded' => 'false', + ]; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-plugin-availability.php b/html/wp-content/plugins/wordpress-seo/admin/class-plugin-availability.php new file mode 100644 index 0000000..9a553f4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-plugin-availability.php @@ -0,0 +1,357 @@ +register_yoast_plugins(); + $this->register_yoast_plugins_status(); + } + + /** + * Registers all the available Yoast SEO plugins. + * + * @return void + */ + protected function register_yoast_plugins() { + $this->plugins = [ + 'yoast-seo-premium' => [ + 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/1y7' ), + 'title' => 'Yoast SEO Premium', + 'description' => sprintf( + /* translators: %1$s expands to Yoast SEO */ + __( 'The premium version of %1$s with more features & support.', 'wordpress-seo' ), + 'Yoast SEO', + ), + 'installed' => false, + 'slug' => 'wordpress-seo-premium/wp-seo-premium.php', + 'version_sync' => true, + 'premium' => true, + ], + + 'video-seo-for-wordpress-seo-by-yoast' => [ + 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/1y8' ), + 'title' => 'Video SEO', + 'description' => __( 'Optimize your videos to show them off in search results and get more clicks!', 'wordpress-seo' ), + 'installed' => false, + 'slug' => 'wpseo-video/video-seo.php', + 'version_sync' => true, + 'premium' => true, + ], + + 'yoast-news-seo' => [ + 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/1y9' ), + 'title' => 'News SEO', + 'description' => __( 'Are you in Google News? Increase your traffic from Google News by optimizing for it!', 'wordpress-seo' ), + 'installed' => false, + 'slug' => 'wpseo-news/wpseo-news.php', + 'version_sync' => true, + 'premium' => true, + ], + + 'local-seo-for-yoast-seo' => [ + 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/1ya' ), + 'title' => 'Local SEO', + 'description' => __( 'Rank better locally and in Google Maps, without breaking a sweat!', 'wordpress-seo' ), + 'installed' => false, + 'slug' => 'wordpress-seo-local/local-seo.php', + 'version_sync' => true, + 'premium' => true, + ], + + 'yoast-woocommerce-seo' => [ + 'url' => WPSEO_Shortlinker::get( 'https://yoa.st/1o0' ), + 'title' => 'Yoast WooCommerce SEO', + 'description' => sprintf( + /* translators: %1$s expands to Yoast SEO */ + __( 'Seamlessly integrate WooCommerce with %1$s and get extra features!', 'wordpress-seo' ), + 'Yoast SEO', + ), + '_dependencies' => [ + 'WooCommerce' => [ + 'slug' => 'woocommerce/woocommerce.php', // Kept for backwards compatibility, in case external code uses get_dependencies(). Deprecated in 22.4. + 'conditional' => new WooCommerce_Conditional(), + ], + ], + 'installed' => false, + 'slug' => 'wpseo-woocommerce/wpseo-woocommerce.php', + 'version_sync' => true, + 'premium' => true, + ], + ]; + } + + /** + * Sets certain plugin properties based on WordPress' status. + * + * @return void + */ + protected function register_yoast_plugins_status() { + + foreach ( $this->plugins as $name => $plugin ) { + + $plugin_slug = $plugin['slug']; + $plugin_path = WP_PLUGIN_DIR . '/' . $plugin_slug; + + if ( file_exists( $plugin_path ) ) { + $plugin_data = get_plugin_data( $plugin_path, false, false ); + $this->plugins[ $name ]['installed'] = true; + $this->plugins[ $name ]['version'] = $plugin_data['Version']; + $this->plugins[ $name ]['active'] = is_plugin_active( $plugin_slug ); + } + } + } + + /** + * Checks if there are dependencies available for the plugin. + * + * @param array $plugin The information available about the plugin. + * + * @return bool Whether there is a dependency present. + */ + public function has_dependencies( $plugin ) { + return ( isset( $plugin['_dependencies'] ) && ! empty( $plugin['_dependencies'] ) ); + } + + /** + * Gets the dependencies for the plugin. + * + * @param array $plugin The information available about the plugin. + * + * @return array Array containing all the dependencies associated with the plugin. + */ + public function get_dependencies( $plugin ) { + if ( ! $this->has_dependencies( $plugin ) ) { + return []; + } + + return $plugin['_dependencies']; + } + + /** + * Checks if all dependencies are satisfied. + * + * @param array $plugin The information available about the plugin. + * + * @return bool Whether or not the dependencies are satisfied. + */ + public function dependencies_are_satisfied( $plugin ) { + if ( ! $this->has_dependencies( $plugin ) ) { + return true; + } + + $dependencies = $this->get_dependencies( $plugin ); + $active_dependencies = array_filter( $dependencies, [ $this, 'is_dependency_active' ] ); + + return count( $active_dependencies ) === count( $dependencies ); + } + + /** + * Checks whether or not one of the plugins is properly installed and usable. + * + * @param array $plugin The information available about the plugin. + * + * @return bool Whether or not the plugin is properly installed. + */ + public function is_installed( $plugin ) { + if ( empty( $plugin ) ) { + return false; + } + + return $this->is_available( $plugin ); + } + + /** + * Checks for the availability of the plugin. + * + * @param array $plugin The information available about the plugin. + * + * @return bool Whether or not the plugin is available. + */ + public function is_available( $plugin ) { + return isset( $plugin['installed'] ) && $plugin['installed'] === true; + } + + /** + * Checks whether a dependency is active. + * + * @param array $dependency The information about the dependency to look for. + * + * @return bool Whether or not the dependency is active. + */ + public function is_dependency_active( $dependency ) { + return $dependency['conditional']->is_met(); + } + + /** + * Gets an array of plugins that have defined dependencies. + * + * @return array Array of the plugins that have dependencies. + */ + public function get_plugins_with_dependencies() { + return array_filter( $this->plugins, [ $this, 'has_dependencies' ] ); + } + + /** + * Determines whether or not a plugin is active. + * + * @deprecated 23.4 + * @codeCoverageIgnore + * + * @param string $plugin The plugin slug to check. + * + * @return bool Whether or not the plugin is active. + */ + public function is_active( $plugin ) { + _deprecated_function( __METHOD__, 'Yoast SEO 23.4', 'is_plugin_active' ); + + return is_plugin_active( $plugin ); + } + + /** + * Gets all the possibly available plugins. + * + * @deprecated 23.4 + * @codeCoverageIgnore + * + * @return array Array containing the information about the plugins. + */ + public function get_plugins() { + _deprecated_function( __METHOD__, 'Yoast SEO 23.4', 'WPSEO_Addon_Manager::get_addon_filenames' ); + + return $this->plugins; + } + + /** + * Gets a specific plugin. Returns an empty array if it cannot be found. + * + * @deprecated 23.4 + * @codeCoverageIgnore + * + * @param string $plugin The plugin to search for. + * + * @return array The plugin properties. + */ + public function get_plugin( $plugin ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- needed for BC reasons + _deprecated_function( __METHOD__, 'Yoast SEO 23.4', 'WPSEO_Addon_Manager::get_plugin_file' ); + if ( ! isset( $this->plugins[ $plugin ] ) ) { + return []; + } + + return $this->plugins[ $plugin ]; + } + + /** + * Gets the version of the plugin. + * + * @deprecated 23.4 + * @codeCoverageIgnore + * + * @param array $plugin The information available about the plugin. + * + * @return string The version associated with the plugin. + */ + public function get_version( $plugin ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- needed for BC reasons + _deprecated_function( __METHOD__, 'Yoast SEO 23.4', 'WPSEO_Addon_Manager::get_installed_addons_versions' ); + if ( ! isset( $plugin['version'] ) ) { + return ''; + } + + return $plugin['version']; + } + + /** + * Checks whether a dependency is available. + * + * @deprecated 22.4 + * @codeCoverageIgnore + * + * @param array $dependency The information about the dependency to look for. + * + * @return bool Whether or not the dependency is available. + */ + public function is_dependency_available( $dependency ) { + _deprecated_function( __METHOD__, 'Yoast SEO 22.4' ); + + return isset( get_plugins()[ $dependency['slug'] ] ); + } + + /** + * Gets the names of the dependencies. + * + * @deprecated 23.4 + * @codeCoverageIgnore + * + * @param array $plugin The plugin to get the dependency names from. + * + * @return array Array containing the names of the associated dependencies. + */ + public function get_dependency_names( $plugin ) { // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- needed for BC reasons + _deprecated_function( __METHOD__, 'Yoast SEO 23.4' ); + if ( ! $this->has_dependencies( $plugin ) ) { + return []; + } + + return array_keys( $plugin['_dependencies'] ); + } + + /** + * Determines whether or not a plugin is a Premium product. + * + * @deprecated 23.4 + * @codeCoverageIgnore + * + * @param array $plugin The plugin to check. + * + * @return bool Whether or not the plugin is a Premium product. + */ + public function is_premium( $plugin ) { + _deprecated_function( __METHOD__, 'Yoast SEO 23.4' ); + + return isset( $plugin['premium'] ) && $plugin['premium'] === true; + } + + /** + * Gets all installed plugins. + * + * @deprecated 23.4 + * @codeCoverageIgnore + * + * @return array The installed plugins. + */ + public function get_installed_plugins() { + + _deprecated_function( __METHOD__, 'Yoast SEO 23.4', 'WPSEO_Addon_Manager::get_installed_addons_versions' ); + $installed = []; + + foreach ( $this->plugins as $plugin_key => $plugin ) { + if ( $this->is_installed( $plugin ) ) { + $installed[ $plugin_key ] = $plugin; + } + } + + return $installed; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-plugin-conflict.php b/html/wp-content/plugins/wordpress-seo/admin/class-plugin-conflict.php new file mode 100644 index 0000000..a90e8ac --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-plugin-conflict.php @@ -0,0 +1,94 @@ +> + */ + protected $plugins = [ + // The plugin which are writing OG metadata. + 'open_graph' => Conflicting_Plugins::OPEN_GRAPH_PLUGINS, + 'xml_sitemaps' => Conflicting_Plugins::XML_SITEMAPS_PLUGINS, + 'cloaking' => Conflicting_Plugins::CLOAKING_PLUGINS, + 'seo' => Conflicting_Plugins::SEO_PLUGINS, + ]; + + /** + * Overrides instance to set with this class as class. + * + * @param string $class_name Optional class name. + * + * @return Yoast_Plugin_Conflict + */ + public static function get_instance( $class_name = self::class ) { + return parent::get_instance( $class_name ); + } + + /** + * After activating any plugin, this method will be executed by a hook. + * + * If the activated plugin is conflicting with ours a notice will be shown. + * + * @param string|bool $plugin Optional plugin basename to check. + * + * @return void + */ + public static function hook_check_for_plugin_conflicts( $plugin = false ) { + // The instance of the plugin. + $instance = self::get_instance(); + + // Only add the plugin as an active plugin if $plugin isn't false. + if ( $plugin && is_string( $plugin ) ) { + $instance->add_active_plugin( $instance->find_plugin_category( $plugin ), $plugin ); + } + + $plugin_sections = []; + + // Only check for open graph problems when they are enabled. + if ( WPSEO_Options::get( 'opengraph' ) ) { + /* translators: %1$s expands to Yoast SEO, %2$s: 'Facebook' plugin name of possibly conflicting plugin with regard to creating OpenGraph output. */ + $plugin_sections['open_graph'] = __( 'Both %1$s and %2$s create Open Graph output, which might make Facebook, X, LinkedIn and other social networks use the wrong texts and images when your pages are being shared.', 'wordpress-seo' ) + . '

            ' + . '' + /* translators: %1$s expands to Yoast SEO. */ + . sprintf( __( 'Configure %1$s\'s Open Graph settings', 'wordpress-seo' ), 'Yoast SEO' ) + . ''; + } + + // Only check for XML conflicts if sitemaps are enabled. + if ( WPSEO_Options::get( 'enable_xml_sitemap' ) ) { + /* translators: %1$s expands to Yoast SEO, %2$s: 'Google XML Sitemaps' plugin name of possibly conflicting plugin with regard to the creation of sitemaps. */ + $plugin_sections['xml_sitemaps'] = __( 'Both %1$s and %2$s can create XML sitemaps. Having two XML sitemaps is not beneficial for search engines and might slow down your site.', 'wordpress-seo' ) + . '

            ' + . '' + /* translators: %1$s expands to Yoast SEO. */ + . sprintf( __( 'Toggle %1$s\'s XML Sitemap', 'wordpress-seo' ), 'Yoast SEO' ) + . ''; + } + + /* translators: %2$s expands to 'RS Head Cleaner' plugin name of possibly conflicting plugin with regard to differentiating output between search engines and normal users. */ + $plugin_sections['cloaking'] = __( 'The plugin %2$s changes your site\'s output and in doing that differentiates between search engines and normal users, a process that\'s called cloaking. We highly recommend that you disable it.', 'wordpress-seo' ); + + /* translators: %1$s expands to Yoast SEO, %2$s: 'SEO' plugin name of possibly conflicting plugin with regard to the creation of duplicate SEO meta. */ + $plugin_sections['seo'] = __( 'Both %1$s and %2$s manage the SEO of your site. Running two SEO plugins at the same time is detrimental.', 'wordpress-seo' ); + + $instance->check_plugin_conflicts( $plugin_sections ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-premium-popup.php b/html/wp-content/plugins/wordpress-seo/admin/class-premium-popup.php new file mode 100644 index 0000000..3582029 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-premium-popup.php @@ -0,0 +1,105 @@ +identifier = $identifier; + $this->heading_level = $heading_level; + $this->title = $title; + $this->content = $content; + $this->url = $url; + } + + /** + * Returns the premium popup as an HTML string. + * + * @param bool $popup Show this message as a popup show it straight away. + * + * @return string + */ + public function get_premium_message( $popup = true ) { + // Don't show in Premium. + if ( defined( 'WPSEO_PREMIUM_FILE' ) ) { + return ''; + } + + $assets_uri = trailingslashit( plugin_dir_url( WPSEO_FILE ) ); + + /* translators: %s expands to Yoast SEO Premium */ + $cta_text = esc_html( sprintf( __( 'Get %s', 'wordpress-seo' ), 'Yoast SEO Premium' ) ); + /* translators: Hidden accessibility text. */ + $new_tab_message = '' . esc_html__( '(Opens in a new browser tab)', 'wordpress-seo' ) . ''; + $caret_icon = ''; + $classes = ''; + if ( $popup ) { + $classes = ' hidden'; + } + $micro_copy = __( '1 year free support and updates included!', 'wordpress-seo' ); + + $popup = << + Yoast SEO + <{$this->heading_level} id="wpseo-contact-support-popup-title" class="wpseo-premium-popup-title">{$this->title}heading_level}> + {$this->content} + + {$cta_text} {$new_tab_message} {$caret_icon} +
            + {$micro_copy} + +EO_POPUP; + + return $popup; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-premium-upsell-admin-block.php b/html/wp-content/plugins/wordpress-seo/admin/class-premium-upsell-admin-block.php new file mode 100644 index 0000000..af364e4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-premium-upsell-admin-block.php @@ -0,0 +1,224 @@ +hook = $hook; + } + + /** + * Registers WordPress hooks. + * + * @return void + */ + public function register_hooks() { + add_action( $this->hook, [ $this, 'render' ] ); + } + + /** + * Renders the upsell block. + * + * @return void + */ + public function render() { + + $is_woocommerce_active = ( new WooCommerce_Conditional() )->is_met(); + $url = ( $is_woocommerce_active ) ? WPSEO_Shortlinker::get( 'https://yoa.st/admin-footer-upsell-woocommerce' ) : WPSEO_Shortlinker::get( 'https://yoa.st/17h' ); + + [ $header_text, $header_icon ] = $this->get_header( $is_woocommerce_active ); + + $arguments = $this->get_arguments( $is_woocommerce_active ); + + $now_including = [ 'Local SEO', 'News SEO', 'Video SEO', __( 'Google Docs add-on (1 seat)', 'wordpress-seo' ) ]; + if ( $is_woocommerce_active ) { + array_unshift( $now_including, 'Yoast SEO Premium' ); + } + + $header_class = ( $is_woocommerce_active ) ? 'woo-header' : ''; + $arguments_html = implode( '', array_map( [ $this, 'get_argument_html' ], $arguments ) ); + $badge_class = ( $is_woocommerce_active ) ? 'woo-badge' : ''; + + $class = $this->get_html_class(); + + /* translators: %s expands to Yoast SEO Premium */ + $button_text = $this->get_button_text( $is_woocommerce_active ); + /* translators: Hidden accessibility text. */ + $button_text .= '' . esc_html__( '(Opens in a new browser tab)', 'wordpress-seo' ) . '' + . ''; + + $upgrade_button = sprintf( + '%3$s', + esc_attr( 'wpseo-' . $this->identifier . '-popup-button' ), + esc_url( $url ), + $button_text, + ); + + echo '
            '; + + if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-promotion' ) ) { + $bf_label = esc_html__( 'BLACK FRIDAY', 'wordpress-seo' ); + $sale_label = esc_html__( '30% OFF', 'wordpress-seo' ); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Already escaped above. + echo "
            $sale_label $bf_label
            "; + } + + echo '
            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in get_header() method. + echo '

            ' . $header_text . $header_icon . '

            '; + + echo '
            '; + echo '' . esc_html__( 'Now includes:', 'wordpress-seo' ) . ''; + echo '
            '; + foreach ( $now_including as $value ) { + echo '' . esc_html( $value ) . ''; + } + echo '
            '; + echo '
            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in $this->get_argument_html() method. + echo '
              ' . $arguments_html . '
            '; + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Correctly escaped in $upgrade_button and $button_text above. + echo '

            ' . $upgrade_button . '

            '; + echo '
            '; + + echo '
            '; + } + + /** + * Formats the argument to a HTML list item. + * + * @param string $argument The argument to format. + * + * @return string Formatted argument in HTML. + */ + protected function get_argument_html( $argument ) { + $assets_uri = trailingslashit( plugin_dir_url( WPSEO_FILE ) ); + $class = $this->get_html_class(); + + return sprintf( + '
          • %3$s
          • ', + esc_url( $assets_uri . 'packages/js/images/icon-check-circle-green.svg' ), + esc_attr( $class . '--argument' ), + $argument, + ); + } + + /** + * Returns the HTML base class to use. + * + * @return string The HTML base class. + */ + protected function get_html_class() { + return 'yoast_' . $this->identifier; + } + + /** + * Returns the arguments based on whether WooCommerce is active. + * + * @param bool $is_woocommerce_active Whether WooCommerce is active. + * + * @return array The arguments list. + */ + private function get_arguments( bool $is_woocommerce_active ) { + $arguments = [ + esc_html__( 'Generate SEO optimized metadata in seconds with AI', 'wordpress-seo' ), + esc_html__( 'Make your articles visible, be seen in Google News', 'wordpress-seo' ), + esc_html__( 'Built to get found by search, AI, and real users', 'wordpress-seo' ), + esc_html__( 'Easy Local SEO. Show up in Google Maps results', 'wordpress-seo' ), + esc_html__( 'Internal links and redirect management, easy', 'wordpress-seo' ), + esc_html__( 'Access to friendly help when you need it, day or night', 'wordpress-seo' ), + ]; + + if ( $is_woocommerce_active ) { + $arguments[1] = esc_html__( 'Boost visibility for your products, from 10 or 10,000+', 'wordpress-seo' ); + } + + return $arguments; + } + + /** + * Returns the header text and icon based on whether WooCommerce is active. + * + * @param bool $is_woocommerce_active Whether WooCommerce is active. + * + * @return array The header text and icon. + */ + private function get_header( bool $is_woocommerce_active ) { + $assets_uri = trailingslashit( plugin_dir_url( WPSEO_FILE ) ); + if ( $is_woocommerce_active ) { + $header_text = sprintf( + /* translators: %s expands to Yoast WooCommerce SEO */ + esc_html__( 'Upgrade to %s', 'wordpress-seo' ), + 'Yoast WooCommerce SEO', + ); + $header_icon = sprintf( + '', + esc_url( $assets_uri . 'packages/js/images/icon-trolley.svg' ), + ); + } + else { + $header_text = sprintf( + /* translators: %s expands to Yoast SEO Premium*/ + esc_html__( 'Upgrade to %s', 'wordpress-seo' ), + 'Yoast SEO Premium', + ); + + $header_icon = sprintf( + '', + esc_url( $assets_uri . 'packages/js/images/icon-crown.svg' ), + ); + } + return [ $header_text, $header_icon ]; + } + + /** + * Returns the button text based on whether WooCommerce is active. + * + * @param bool $is_woocommerce_active Whether WooCommerce is active. + * + * @return string The button text. + */ + private function get_button_text( bool $is_woocommerce_active ): string { + if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-promotion' ) ) { + return esc_html__( 'Get 30% off now!', 'wordpress-seo' ); + } + else { + // phpcs:disable Squiz.ControlStructures.InlineIfDeclaration.NotSingleLine -- needed to add translators comments. + return $is_woocommerce_active + /* translators: %s expands to Yoast WooCommerce SEO */ + ? sprintf( esc_html__( 'Explore %s now!', 'wordpress-seo' ), 'Yoast WooCommerce SEO' ) + /* translators: %s expands to Yoast SEO Premium */ + : sprintf( esc_html__( 'Explore %s now!', 'wordpress-seo' ), 'Yoast SEO Premium' ); + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-primary-term-admin.php b/html/wp-content/plugins/wordpress-seo/admin/class-primary-term-admin.php new file mode 100644 index 0000000..a368551 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-primary-term-admin.php @@ -0,0 +1,272 @@ +get_primary_term_taxonomies(); + + foreach ( $taxonomies as $taxonomy ) { + $content .= $this->primary_term_field( $taxonomy->name ); + $content .= wp_nonce_field( 'save-primary-term', WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy->name . '_nonce', false, false ); + } + return $content; + } + + /** + * Generates the HTML for a hidden field for a primary taxonomy. + * + * @param string $taxonomy_name The taxonomy's slug. + * + * @return string The HTML for a hidden primary taxonomy field. + */ + protected function primary_term_field( $taxonomy_name ) { + return sprintf( + '', + esc_attr( $this->generate_field_id( $taxonomy_name ) ), + esc_attr( $this->generate_field_name( $taxonomy_name ) ), + esc_attr( $this->get_primary_term( $taxonomy_name ) ), + ); + } + + /** + * Generates an id for a primary taxonomy's hidden field. + * + * @param string $taxonomy_name The taxonomy's slug. + * + * @return string The field id. + */ + protected function generate_field_id( $taxonomy_name ) { + return 'yoast-wpseo-primary-' . $taxonomy_name; + } + + /** + * Generates a name for a primary taxonomy's hidden field. + * + * @param string $taxonomy_name The taxonomy's slug. + * + * @return string The field id. + */ + protected function generate_field_name( $taxonomy_name ) { + return WPSEO_Meta::$form_prefix . 'primary_' . $taxonomy_name . '_term'; + } + + /** + * Adds primary term templates. + * + * @return void + */ + public function wp_footer() { + $taxonomies = $this->get_primary_term_taxonomies(); + + if ( ! empty( $taxonomies ) ) { + $this->include_js_templates(); + } + } + + /** + * Enqueues all the assets needed for the primary term interface. + * + * @return void + */ + public function enqueue_assets() { + global $pagenow; + + if ( ! WPSEO_Metabox::is_post_edit( $pagenow ) ) { + return; + } + + $taxonomies = $this->get_primary_term_taxonomies(); + + // Only enqueue if there are taxonomies that need a primary term. + if ( empty( $taxonomies ) ) { + return; + } + + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_style( 'primary-category' ); + + $mapped_taxonomies = $this->get_mapped_taxonomies_for_js( $taxonomies ); + + $data = [ + 'taxonomies' => $mapped_taxonomies, + ]; + + $asset_manager->localize_script( 'post-edit', 'wpseoPrimaryCategoryL10n', $data ); + $asset_manager->localize_script( 'post-edit-classic', 'wpseoPrimaryCategoryL10n', $data ); + } + + /** + * Gets the id of the primary term. + * + * @param string $taxonomy_name Taxonomy name for the term. + * + * @return int primary term id + */ + protected function get_primary_term( $taxonomy_name ) { + $primary_term = new WPSEO_Primary_Term( $taxonomy_name, $this->get_current_id() ); + + return $primary_term->get_primary_term(); + } + + /** + * Returns all the taxonomies for which the primary term selection is enabled. + * + * @param int|null $post_id Default current post ID. + * @return array + */ + protected function get_primary_term_taxonomies( $post_id = null ) { + $post_id ??= $this->get_current_id(); + + $taxonomies = wp_cache_get( 'primary_term_taxonomies_' . $post_id, 'wpseo' ); + if ( $taxonomies !== false ) { + return $taxonomies; + } + + $taxonomies = $this->generate_primary_term_taxonomies( $post_id ); + + wp_cache_set( 'primary_term_taxonomies_' . $post_id, $taxonomies, 'wpseo' ); + + return $taxonomies; + } + + /** + * Includes templates file. + * + * @return void + */ + protected function include_js_templates() { + include_once WPSEO_PATH . 'admin/views/js-templates-primary-term.php'; + } + + /** + * Generates the primary term taxonomies. + * + * @param int $post_id ID of the post. + * + * @return array + */ + protected function generate_primary_term_taxonomies( $post_id ) { + $post_type = get_post_type( $post_id ); + $all_taxonomies = get_object_taxonomies( $post_type, 'objects' ); + $all_taxonomies = array_filter( $all_taxonomies, [ $this, 'filter_hierarchical_taxonomies' ] ); + + /** + * Filters which taxonomies for which the user can choose the primary term. + * + * @param array $taxonomies An array of taxonomy objects that are primary_term enabled. + * @param string $post_type The post type for which to filter the taxonomies. + * @param array $all_taxonomies All taxonomies for this post types, even ones that don't have primary term + * enabled. + */ + $taxonomies = (array) apply_filters( 'wpseo_primary_term_taxonomies', $all_taxonomies, $post_type, $all_taxonomies ); + + return $taxonomies; + } + + /** + * Creates a map of taxonomies for localization. + * + * @param array $taxonomies The taxononmies that should be mapped. + * + * @return array The mapped taxonomies. + */ + protected function get_mapped_taxonomies_for_js( $taxonomies ) { + return array_map( [ $this, 'map_taxonomies_for_js' ], $taxonomies ); + } + + /** + * Returns an array suitable for use in the javascript. + * + * @param stdClass $taxonomy The taxonomy to map. + * + * @return array The mapped taxonomy. + */ + private function map_taxonomies_for_js( $taxonomy ) { + $primary_term = $this->get_primary_term( $taxonomy->name ); + + if ( empty( $primary_term ) ) { + $primary_term = ''; + } + + $terms = get_terms( + [ + 'taxonomy' => $taxonomy->name, + 'update_term_meta_cache' => false, + 'fields' => 'id=>name', + ], + ); + + $mapped_terms_for_js = []; + foreach ( $terms as $id => $name ) { + $mapped_terms_for_js[] = [ + 'id' => $id, + 'name' => $name, + ]; + } + + return [ + 'title' => $taxonomy->labels->singular_name, + 'name' => $taxonomy->name, + 'primary' => $primary_term, + 'singularLabel' => $taxonomy->labels->singular_name, + 'fieldId' => $this->generate_field_id( $taxonomy->name ), + 'restBase' => ( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name, + 'terms' => $mapped_terms_for_js, + ]; + } + + /** + * Returns whether or not a taxonomy is hierarchical. + * + * @param stdClass $taxonomy Taxonomy object. + * + * @return bool + */ + private function filter_hierarchical_taxonomies( $taxonomy ) { + return (bool) $taxonomy->hierarchical; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-product-upsell-notice.php b/html/wp-content/plugins/wordpress-seo/admin/class-product-upsell-notice.php new file mode 100644 index 0000000..bd16e6e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-product-upsell-notice.php @@ -0,0 +1,231 @@ +options = $this->get_options(); + } + + /** + * Checks if the notice should be added or removed. + * + * @return void + */ + public function initialize() { + $this->remove_notification(); + } + + /** + * Sets the upgrade notice. + * + * @return void + */ + public function set_upgrade_notice() { + + if ( $this->has_first_activated_on() ) { + return; + } + + $this->set_first_activated_on(); + $this->add_notification(); + } + + /** + * Listener for the upsell notice. + * + * @return void + */ + public function dismiss_notice_listener() { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are validating a nonce here. + if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'dismiss-5star-upsell' ) ) { + return; + } + + $dismiss_upsell = isset( $_GET['yoast_dismiss'] ) && is_string( $_GET['yoast_dismiss'] ) ? sanitize_text_field( wp_unslash( $_GET['yoast_dismiss'] ) ) : ''; + + if ( $dismiss_upsell !== 'upsell' ) { + return; + } + + $this->dismiss_notice(); + + if ( wp_safe_redirect( admin_url( 'admin.php?page=wpseo_dashboard' ) ) ) { + exit(); + } + } + + /** + * When the notice should be shown. + * + * @return bool + */ + protected function should_add_notification() { + return ( $this->options['first_activated_on'] < strtotime( '-2weeks' ) ); + } + + /** + * Checks if the options has a first activated on date value. + * + * @return bool + */ + protected function has_first_activated_on() { + return $this->options['first_activated_on'] !== false; + } + + /** + * Sets the first activated on. + * + * @return void + */ + protected function set_first_activated_on() { + $this->options['first_activated_on'] = strtotime( '-2weeks' ); + + $this->save_options(); + } + + /** + * Adds a notification to the notification center. + * + * @return void + */ + protected function add_notification() { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->add_notification( $this->get_notification() ); + } + + /** + * Removes a notification to the notification center. + * + * @return void + */ + protected function remove_notification() { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->remove_notification( $this->get_notification() ); + } + + /** + * Returns a premium upsell section if using the free plugin. + * + * @return string + */ + protected function get_premium_upsell_section() { + if ( ! YoastSEO()->helpers->product->is_premium() ) { + return sprintf( + /* translators: %1$s expands anchor to premium plugin page, %2$s expands to */ + __( 'By the way, did you know we also have a %1$sPremium plugin%2$s? It offers advanced features, like a redirect manager and support for multiple keyphrases. It also comes with 24/7 personal support.', 'wordpress-seo' ), + "", + '', + ); + } + + return ''; + } + + /** + * Gets the notification value. + * + * @return Yoast_Notification + */ + protected function get_notification() { + $message = sprintf( + /* translators: %1$s expands to Yoast SEO, %2$s is a link start tag to the plugin page on WordPress.org, %3$s is the link closing tag. */ + __( 'We\'ve noticed you\'ve been using %1$s for some time now; we hope you love it! We\'d be thrilled if you could %2$sgive us a 5 stars rating on WordPress.org%3$s!', 'wordpress-seo' ), + 'Yoast SEO', + '', + '', + ) . "\n\n"; + + $message .= sprintf( + /* translators: %1$s is a link start tag to the bugreport guidelines on the Yoast help center, %2$s is the link closing tag. */ + __( 'If you are experiencing issues, %1$splease file a bug report%2$s and we\'ll do our best to help you out.', 'wordpress-seo' ), + '', + '', + ) . "\n\n"; + + $message .= $this->get_premium_upsell_section() . "\n\n"; + + $message .= '' . __( 'Please don\'t show me this notification anymore', 'wordpress-seo' ) . ''; + + $notification = new Yoast_Notification( + $message, + [ + 'type' => Yoast_Notification::WARNING, + 'id' => 'wpseo-upsell-notice', + 'capabilities' => 'wpseo_manage_options', + 'priority' => 0.8, + ], + ); + + return $notification; + } + + /** + * Dismisses the notice. + * + * @return bool + */ + protected function is_notice_dismissed() { + return get_user_meta( get_current_user_id(), self::USER_META_DISMISSED, true ) === '1'; + } + + /** + * Dismisses the notice. + * + * @return void + */ + protected function dismiss_notice() { + update_user_meta( get_current_user_id(), self::USER_META_DISMISSED, true ); + } + + /** + * Returns the set options. + * + * @return mixed + */ + protected function get_options() { + return get_option( self::OPTION_NAME ); + } + + /** + * Saves the options to the database. + * + * @return void + */ + protected function save_options() { + update_option( self::OPTION_NAME, $this->options ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-remote-request.php b/html/wp-content/plugins/wordpress-seo/admin/class-remote-request.php new file mode 100644 index 0000000..e54757a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-remote-request.php @@ -0,0 +1,158 @@ + false, + 'timeout' => 2, + ]; + + /** + * Holds the response error. + * + * @var WP_Error|null + */ + protected $response_error; + + /** + * Holds the response body. + * + * @var mixed + */ + protected $response_body; + + /** + * Sets the endpoint and arguments. + * + * @param string $endpoint The endpoint to send the request to. + * @param array $args The arguments to use in this request. + */ + public function __construct( $endpoint, array $args = [] ) { + $this->endpoint = $endpoint; + $this->args = wp_parse_args( $this->args, $args ); + } + + /** + * Sets the request body. + * + * @param mixed $body The body to set. + * + * @return void + */ + public function set_body( $body ) { + $this->args['body'] = $body; + } + + /** + * Sends the data to the given endpoint. + * + * @param string $method The type of request to send. + * + * @return bool True when sending data has been successful. + */ + public function send( $method = self::METHOD_POST ) { + switch ( $method ) { + case self::METHOD_POST: + $response = $this->post(); + break; + case self::METHOD_GET: + $response = $this->get(); + break; + default: + /* translators: %1$s expands to the request method */ + $response = new WP_Error( 1, sprintf( __( 'Request method %1$s is not valid.', 'wordpress-seo' ), $method ) ); + break; + } + + return $this->process_response( $response ); + } + + /** + * Returns the value of the response error. + * + * @return WP_Error|null The response error. + */ + public function get_response_error() { + return $this->response_error; + } + + /** + * Returns the response body. + * + * @return mixed The response body. + */ + public function get_response_body() { + return $this->response_body; + } + + /** + * Processes the given response. + * + * @param mixed $response The response to process. + * + * @return bool True when response is valid. + */ + protected function process_response( $response ) { + if ( $response instanceof WP_Error ) { + $this->response_error = $response; + + return false; + } + + $this->response_body = wp_remote_retrieve_body( $response ); + + return ( wp_remote_retrieve_response_code( $response ) === 200 ); + } + + /** + * Performs a post request to the specified endpoint with set arguments. + * + * @return WP_Error|array The response or WP_Error on failure. + */ + protected function post() { + return wp_remote_post( $this->endpoint, $this->args ); + } + + /** + * Performs a post request to the specified endpoint with set arguments. + * + * @return WP_Error|array The response or WP_Error on failure. + */ + protected function get() { + return wp_remote_get( $this->endpoint, $this->args ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-schema-person-upgrade-notification.php b/html/wp-content/plugins/wordpress-seo/admin/class-schema-person-upgrade-notification.php new file mode 100644 index 0000000..2bf0167 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-schema-person-upgrade-notification.php @@ -0,0 +1,83 @@ +add_notification(); + return; + } + + $this->remove_notification(); + } + + /** + * Adds a notification to the notification center. + * + * @return void + */ + protected function add_notification() { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->add_notification( $this->get_notification() ); + } + + /** + * Removes a notification to the notification center. + * + * @return void + */ + protected function remove_notification() { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->remove_notification( $this->get_notification() ); + } + + /** + * Gets the notification object. + * + * @return Yoast_Notification + */ + protected function get_notification() { + $message = sprintf( + /* translators: %1$s is a link start tag to the Search Appearance settings, %2$s is the link closing tag. */ + __( 'You have previously set your site to represent a person. We’ve improved our functionality around Schema and the Knowledge Graph, so you should go in and %1$scomplete those settings%2$s.', 'wordpress-seo' ), + '', + '', + ); + + $notification = new Yoast_Notification( + $message, + [ + 'type' => Yoast_Notification::WARNING, + 'id' => 'wpseo-schema-person-upgrade', + 'capabilities' => 'wpseo_manage_options', + 'priority' => 0.8, + ], + ); + + return $notification; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-suggested-plugins.php b/html/wp-content/plugins/wordpress-seo/admin/class-suggested-plugins.php new file mode 100644 index 0000000..708eac8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-suggested-plugins.php @@ -0,0 +1,140 @@ +availability_checker = $availability_checker; + $this->notification_center = $notification_center; + } + + /** + * Registers all hooks to WordPress. + * + * @return void + */ + public function register_hooks() { + add_action( 'admin_init', [ $this->availability_checker, 'register' ] ); + add_action( 'admin_init', [ $this, 'add_notifications' ] ); + } + + /** + * Adds notifications (when necessary). + * + * @return void + */ + public function add_notifications() { + $checker = $this->availability_checker; + + // Get all Yoast plugins that have dependencies. + $plugins = $checker->get_plugins_with_dependencies(); + + foreach ( $plugins as $plugin_name => $plugin ) { + $notification_id = 'wpseo-suggested-plugin-' . $plugin_name; + + if ( ! $checker->dependencies_are_satisfied( $plugin ) ) { + $this->notification_center->remove_notification_by_id( $notification_id ); + + continue; + } + + if ( ! $checker->is_installed( $plugin ) ) { + $notification = $this->get_yoast_seo_suggested_plugins_notification( $notification_id, $plugin ); + $this->notification_center->add_notification( $notification ); + + continue; + } + + $this->notification_center->remove_notification_by_id( $notification_id ); + } + } + + /** + * Build Yoast SEO suggested plugins notification. + * + * @param string $notification_id The id of the notification to be created. + * @param array> $plugin The plugin to retrieve the data from. + * + * @return Yoast_Notification The notification containing the suggested plugin. + */ + protected function get_yoast_seo_suggested_plugins_notification( $notification_id, $plugin ) { + $message = $this->create_install_suggested_plugin_message( $plugin ); + + return new Yoast_Notification( + $message, + [ + 'id' => $notification_id, + 'type' => Yoast_Notification::WARNING, + 'capabilities' => [ 'install_plugins' ], + ], + ); + } + + /** + * Creates a message to suggest the installation of a particular plugin. + * + * @param array $suggested_plugin The suggested plugin. + * + * @return string The install suggested plugin message. + */ + protected function create_install_suggested_plugin_message( $suggested_plugin ) { + /* translators: %1$s expands to an opening strong tag, %2$s expands to the dependency name, %3$s expands to a closing strong tag, %4$s expands to an opening anchor tag, %5$s expands to a closing anchor tag. */ + $message = __( 'It looks like you aren\'t using our %1$s%2$s addon%3$s. %4$sUpgrade today%5$s to unlock more tools and SEO features to make your products stand out in search results.', 'wordpress-seo' ); + $install_link = WPSEO_Admin_Utils::get_install_link( $suggested_plugin ); + + return sprintf( + $message, + '', + $install_link, + '', + $this->create_more_information_link( $suggested_plugin['url'], $suggested_plugin['title'] ), + '', + ); + } + + /** + * Creates a more information link that directs the user to WordPress.org Plugin repository. + * + * @param string $url The URL to the plugin's page. + * @param string $name The name of the plugin. + * + * @return string The more information link. + */ + protected function create_more_information_link( $url, $name ) { + return sprintf( + '', + $url, + /* translators: Hidden accessibility text; %1$s expands to the dependency name */ + sprintf( __( 'More information about %1$s', 'wordpress-seo' ), $name ), + ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-wincher-dashboard-widget.php b/html/wp-content/plugins/wordpress-seo/admin/class-wincher-dashboard-widget.php new file mode 100644 index 0000000..90faf1d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-wincher-dashboard-widget.php @@ -0,0 +1,136 @@ +asset_manager = new WPSEO_Admin_Asset_Manager(); + } + + /** + * Register WordPress hooks. + * + * @return void + */ + public function register_hooks() { + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_wincher_dashboard_assets' ] ); + add_action( 'admin_init', [ $this, 'queue_wincher_dashboard_widget' ] ); + } + + /** + * Adds the Wincher dashboard widget if it should be shown. + * + * @return void + */ + public function queue_wincher_dashboard_widget() { + if ( $this->show_widget() ) { + add_action( 'wp_dashboard_setup', [ $this, 'add_wincher_dashboard_widget' ] ); + } + } + + /** + * Adds the Wincher dashboard widget to WordPress. + * + * @return void + */ + public function add_wincher_dashboard_widget() { + add_filter( 'postbox_classes_dashboard_wpseo-wincher-dashboard-overview', [ $this, 'wpseo_wincher_dashboard_overview_class' ] ); + wp_add_dashboard_widget( + 'wpseo-wincher-dashboard-overview', + /* translators: %1$s expands to Yoast SEO, %2$s to Wincher */ + sprintf( __( '%1$s / %2$s: Top Keyphrases', 'wordpress-seo' ), 'Yoast SEO', 'Wincher' ), + [ $this, 'display_wincher_dashboard_widget' ], + ); + } + + /** + * Adds CSS classes to the dashboard widget. + * + * @param array $classes An array of postbox CSS classes. + * + * @return array + */ + public function wpseo_wincher_dashboard_overview_class( $classes ) { + $classes[] = 'yoast wpseo-wincherdashboard-overview'; + return $classes; + } + + /** + * Displays the Wincher dashboard widget. + * + * @return void + */ + public function display_wincher_dashboard_widget() { + echo '
            '; + } + + /** + * Enqueues assets for the dashboard if the current page is the dashboard. + * + * @return void + */ + public function enqueue_wincher_dashboard_assets() { + if ( ! $this->is_dashboard_screen() ) { + return; + } + + $this->asset_manager->localize_script( 'wincher-dashboard-widget', 'wpseoWincherDashboardWidgetL10n', $this->localize_wincher_dashboard_script() ); + $this->asset_manager->enqueue_script( 'wincher-dashboard-widget' ); + $this->asset_manager->enqueue_style( 'wp-dashboard' ); + $this->asset_manager->enqueue_style( 'monorepo' ); + } + + /** + * Translates strings used in the Wincher dashboard widget. + * + * @return array The translated strings. + */ + public function localize_wincher_dashboard_script() { + + return [ + 'wincher_is_logged_in' => YoastSEO()->helpers->wincher->login_status(), + 'wincher_website_id' => WPSEO_Options::get( 'wincher_website_id', '' ), + ]; + } + + /** + * Checks if the current screen is the dashboard screen. + * + * @return bool Whether or not this is the dashboard screen. + */ + private function is_dashboard_screen() { + $current_screen = get_current_screen(); + + return ( $current_screen instanceof WP_Screen && $current_screen->id === 'dashboard' ); + } + + /** + * Returns true when the Wincher dashboard widget should be shown. + * + * @return bool + */ + private function show_widget() { + $analysis_seo = new WPSEO_Metabox_Analysis_SEO(); + $user_can_edit = $analysis_seo->is_enabled() && current_user_can( 'edit_posts' ); + $is_wincher_active = YoastSEO()->helpers->wincher->is_active(); + + return $user_can_edit && $is_wincher_active; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-columns.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-columns.php new file mode 100644 index 0000000..bf17dcc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-columns.php @@ -0,0 +1,117 @@ +display_links(); + $meta_columns_present = $this->display_meta_columns(); + if ( ! ( $link_columns_present || $meta_columns_present ) ) { + return; + } + + $help_tab_content = sprintf( + /* translators: %1$s: Yoast SEO */ + __( '%1$s adds several columns to this page.', 'wordpress-seo' ), + 'Yoast SEO', + ); + + if ( $meta_columns_present ) { + $help_tab_content .= ' ' . sprintf( + /* translators: %1$s: Link to article about content analysis, %2$s: Anchor closing */ + __( 'We\'ve written an article about %1$show to use the SEO score and Readability score%2$s.', 'wordpress-seo' ), + '
            ', + '', + ); + } + + if ( $link_columns_present ) { + $help_tab_content .= ' ' . sprintf( + /* translators: %1$s: Link to article about text links, %2$s: Anchor closing tag, %3$s: Emphasis open tag, %4$s: Emphasis close tag */ + __( 'The links columns show the number of articles on this site linking %3$sto%4$s this article and the number of URLs linked %3$sfrom%4$s this article. Learn more about %1$show to use these features to improve your internal linking%2$s, which greatly enhances your SEO.', 'wordpress-seo' ), + '', + '', + '', + '', + ); + } + + $screen = get_current_screen(); + $screen->add_help_tab( + [ + /* translators: %s expands to Yoast */ + 'title' => sprintf( __( '%s Columns', 'wordpress-seo' ), 'Yoast' ), + 'id' => 'yst-columns', + 'content' => '

            ' . $help_tab_content . '

            ', + 'priority' => 15, + ], + ); + } + + /** + * Retrieves the post type from the $_GET variable. + * + * @return string The current post type. + */ + private function get_current_post_type() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['post_type'] ) && is_string( $_GET['post_type'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET['post_type'] ) ); + } + return ''; + } + + /** + * Whether we are showing link columns on this overview page. + * This depends on the post being accessible or not. + * + * @return bool Whether the linking columns are shown + */ + private function display_links() { + $current_post_type = $this->get_current_post_type(); + + if ( empty( $current_post_type ) ) { + return false; + } + + return WPSEO_Post_Type::is_post_type_accessible( $current_post_type ); + } + + /** + * Wraps the WPSEO_Metabox check to determine whether the metabox should be displayed either by + * choice of the admin or because the post type is not a public post type. + * + * @return bool Whether the meta box (and associated columns etc) should be hidden. + */ + private function display_meta_columns() { + $current_post_type = $this->get_current_post_type(); + + if ( empty( $current_post_type ) ) { + return false; + } + + return WPSEO_Utils::is_metabox_active( $current_post_type, 'post_type' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-dashboard-widget.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-dashboard-widget.php new file mode 100644 index 0000000..dfbcb50 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-dashboard-widget.php @@ -0,0 +1,158 @@ +statistics = $statistics; + $this->asset_manager = new WPSEO_Admin_Asset_Manager(); + } + + /** + * Register WordPress hooks. + * + * @return void + */ + public function register_hooks() { + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_dashboard_assets' ] ); + add_action( 'admin_init', [ $this, 'queue_dashboard_widget' ] ); + } + + /** + * Adds the dashboard widget if it should be shown. + * + * @return void + */ + public function queue_dashboard_widget() { + if ( $this->show_widget() ) { + add_action( 'wp_dashboard_setup', [ $this, 'add_dashboard_widget' ] ); + } + } + + /** + * Adds dashboard widget to WordPress. + * + * @return void + */ + public function add_dashboard_widget() { + add_filter( 'postbox_classes_dashboard_wpseo-dashboard-overview', [ $this, 'wpseo_dashboard_overview_class' ] ); + wp_add_dashboard_widget( + 'wpseo-dashboard-overview', + /* translators: %s is the plugin name */ + sprintf( __( '%s Posts Overview', 'wordpress-seo' ), 'Yoast SEO' ), + [ $this, 'display_dashboard_widget' ], + ); + } + + /** + * Adds CSS classes to the dashboard widget. + * + * @param array $classes An array of postbox CSS classes. + * + * @return array + */ + public function wpseo_dashboard_overview_class( $classes ) { + $classes[] = 'yoast wpseo-dashboard-overview'; + return $classes; + } + + /** + * Displays the dashboard widget. + * + * @return void + */ + public function display_dashboard_widget() { + echo '
            '; + } + + /** + * Enqueues assets for the dashboard if the current page is the dashboard. + * + * @return void + */ + public function enqueue_dashboard_assets() { + if ( ! $this->is_dashboard_screen() ) { + return; + } + + $this->asset_manager->localize_script( 'dashboard-widget', 'wpseoDashboardWidgetL10n', $this->localize_dashboard_script() ); + $this->asset_manager->enqueue_script( 'dashboard-widget' ); + $this->asset_manager->enqueue_style( 'wp-dashboard' ); + $this->asset_manager->enqueue_style( 'monorepo' ); + } + + /** + * Translates strings used in the dashboard widget. + * + * @return array The translated strings. + */ + public function localize_dashboard_script() { + return [ + 'feed_header' => sprintf( + /* translators: %1$s resolves to Yoast.com */ + __( 'Latest blog posts on %1$s', 'wordpress-seo' ), + 'Yoast.com', + ), + 'feed_footer' => __( 'Read more like this on our SEO blog', 'wordpress-seo' ), + 'wp_version' => substr( $GLOBALS['wp_version'], 0, 3 ) . '-' . ( is_plugin_active( 'classic-editor/classic-editor.php' ) ? '1' : '0' ), + 'php_version' => PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION, + ]; + } + + /** + * Checks if the current screen is the dashboard screen. + * + * @return bool Whether or not this is the dashboard screen. + */ + private function is_dashboard_screen() { + $current_screen = get_current_screen(); + + return ( $current_screen instanceof WP_Screen && $current_screen->id === 'dashboard' ); + } + + /** + * Returns true when the dashboard widget should be shown. + * + * @return bool + */ + private function show_widget() { + $analysis_seo = new WPSEO_Metabox_Analysis_SEO(); + + return $analysis_seo->is_enabled() && current_user_can( 'edit_posts' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-form.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-form.php new file mode 100644 index 0000000..1bf22c6 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-form.php @@ -0,0 +1,1103 @@ + +
            + +

            +
            +
            +
            + meets_requirements() ) { + $action_url = network_admin_url( 'settings.php' ); + $hidden_fields_cb = [ $network_admin, 'settings_fields' ]; + } + else { + $action_url = admin_url( 'options.php' ); + $hidden_fields_cb = 'settings_fields'; + } + + echo '
            '; + call_user_func( $hidden_fields_cb, $option_long_name ); + } + $this->set_option( $option ); + } + + /** + * Set the option used in output for form elements. + * + * @since 2.0 + * + * @param string $option_name Option key. + * + * @return void + */ + public function set_option( $option_name ) { + $this->option_name = $option_name; + + $this->option_instance = WPSEO_Options::get_option_instance( $option_name ); + if ( ! $this->option_instance ) { + $this->option_instance = null; + } + } + + /** + * Generates the footer for admin pages. + * + * @since 2.0 + * + * @param bool $submit Whether or not a submit button and form end tag should be shown. + * @param bool $show_sidebar Whether or not to show the banner sidebar - used by premium plugins to disable it. + * + * @return void + */ + public function admin_footer( $submit = true, $show_sidebar = true ) { + if ( $submit ) { + $settings_changed_listener = new WPSEO_Admin_Settings_Changed_Listener(); + echo '
            '; + + echo '
            '; + submit_button( __( 'Save changes', 'wordpress-seo' ) ); + $settings_changed_listener->show_success_message(); + echo '
            '; + + echo ''; + + echo '
            '; + + echo ' +
            '; + } + + /** + * Apply general admin_footer hooks. + */ + do_action( 'wpseo_admin_footer', $this ); + + /** + * Run possibly set actions to add for example an i18n box. + */ + do_action( 'wpseo_admin_promo_footer' ); + + echo ' +
            '; + + if ( $show_sidebar ) { + $this->admin_sidebar(); + } + + echo '
            '; + + do_action( 'wpseo_admin_below_content', $this ); + + echo ' +
            '; + } + + /** + * Generates the sidebar for admin pages. + * + * @since 2.0 + * + * @return void + */ + public function admin_sidebar() { + // No banners in Premium. + $addon_manager = new WPSEO_Addon_Manager(); + if ( YoastSEO()->helpers->product->is_premium() && $addon_manager->has_valid_subscription( WPSEO_Addon_Manager::PREMIUM_SLUG ) ) { + return; + } + + $sidebar_presenter = new Sidebar_Presenter(); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in presenter. + echo $sidebar_presenter->present(); + } + + /** + * Output a label element. + * + * @since 2.0 + * + * @param string $text Label text string, which can contain escaped html. + * @param array $attr HTML attributes set. + * + * @return void + */ + public function label( $text, $attr ) { + $defaults = [ + 'class' => 'checkbox', + 'close' => true, + 'for' => '', + 'aria_label' => '', + ]; + + $attr = wp_parse_args( $attr, $defaults ); + $aria_label = ''; + if ( $attr['aria_label'] !== '' ) { + $aria_label = ' aria-label="' . esc_attr( $attr['aria_label'] ) . '"'; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. Specifically, the $text variable can contain escaped html. + echo "'; + } + } + + /** + * Output a legend element. + * + * @since 3.4 + * + * @param string $text Legend text string. + * @param array $attr HTML attributes set. + * + * @return void + */ + public function legend( $text, $attr ) { + $defaults = [ + 'id' => '', + 'class' => '', + ]; + $attr = wp_parse_args( $attr, $defaults ); + + $id = ( $attr['id'] === '' ) ? '' : ' id="' . esc_attr( $attr['id'] ) . '"'; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + echo '' . $text . ''; + } + + /** + * Create a Checkbox input field. + * + * @since 2.0 + * + * @param string $variable The variable within the option to create the checkbox for. + * @param string $label The label to show for the variable. + * @param bool $label_left Whether the label should be left (true) or right (false). + * @param array $attr Extra attributes to add to the checkbox. + * + * @return void + */ + public function checkbox( $variable, $label, $label_left = false, $attr = [] ) { + $val = $this->get_field_value( $variable, false ); + + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + if ( $val === true ) { + $val = 'on'; + } + + $class = ''; + if ( $label_left !== false ) { + $this->label( $label_left, [ 'for' => $variable ] ); + } + else { + $class = 'double'; + } + + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $disabled_attribute output is hardcoded and all other output is properly escaped. + echo ''; + + if ( ! empty( $label ) ) { + $this->label( $label, [ 'for' => $variable ] ); + } + + echo '
            '; + } + + /** + * Creates a Checkbox input field list. + * + * @since 12.8 + * + * @param string $variable The variables within the option to create the checkbox list for. + * @param string $labels The labels to show for the variable. + * @param array $attr Extra attributes to add to the checkbox list. + * + * @return void + */ + public function checkbox_list( $variable, $labels, $attr = [] ) { + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + $values = $this->get_field_value( $variable, [] ); + + foreach ( $labels as $name => $label ) { + printf( + '', + esc_attr( $variable . '-' . $name ), + esc_attr( $this->option_name . '[' . $variable . '][' . $name . ']' ), + checked( ! empty( $values[ $name ] ), true, false ), + esc_attr( $name ), + disabled( ( isset( $attr['disabled'] ) && $attr['disabled'] ), true, false ), + ); + + printf( + '', + esc_attr( $variable . '-' . $name ), // #1 + esc_html( $label ), + ); + echo '
            '; + } + } + + /** + * Create a light switch input field using a single checkbox. + * + * @since 3.1 + * + * @param string $variable The variable within the option to create the checkbox for. + * @param string $label The visual label text for the toggle. + * @param array $buttons Array of two visual labels for the buttons (defaults Disabled/Enabled). + * @param bool $reverse Reverse order of buttons (default true). + * @param string $help Inline Help that will be printed out before the toggle. + * @param bool $strong Whether the visual label is displayed in strong text. Default is false. + * Starting from Yoast SEO 16.5, the visual label is forced to bold via CSS. + * @param array $attr Extra attributes to add to the light switch. + * + * @return void + */ + public function light_switch( $variable, $label, $buttons = [], $reverse = true, $help = '', $strong = false, $attr = [] ) { + $val = $this->get_field_value( $variable, false ); + + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + if ( $val === true ) { + $val = 'on'; + } + + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + $output = new Light_Switch_Presenter( + $variable, + $label, + $buttons, + $this->option_name . '[' . $variable . ']', + $val, + $reverse, + $help, + $strong, + $disabled_attribute, + ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: All output is properly escaped or hardcoded in the presenter. + echo $output; + } + + /** + * Create a Text input field. + * + * @since 2.0 + * @since 2.1 Introduced the `$attr` parameter. + * + * @param string $variable The variable within the option to create the text input field for. + * @param string $label The label to show for the variable. + * @param array|string $attr Extra attributes to add to the input field. Can be class, disabled, autocomplete. + * + * @return void + */ + public function textinput( $variable, $label, $attr = [] ) { + $type = 'text'; + if ( ! is_array( $attr ) ) { + $attr = [ + 'class' => $attr, + 'disabled' => false, + ]; + } + + $defaults = [ + 'placeholder' => '', + 'class' => '', + ]; + $attr = wp_parse_args( $attr, $defaults ); + $val = $this->get_field_value( $variable, '' ); + if ( isset( $attr['type'] ) && $attr['type'] === 'url' ) { + $val = urldecode( $val ); + $type = 'url'; + } + $attributes = isset( $attr['autocomplete'] ) ? ' autocomplete="' . esc_attr( $attr['autocomplete'] ) . '"' : ''; + + $this->label( + $label, + [ + 'for' => $variable, + 'class' => 'textinput', + ], + ); + + $aria_attributes = Yoast_Input_Validation::get_the_aria_invalid_attribute( $variable ); + + $aria_attributes .= Yoast_Input_Validation::get_the_aria_describedby_attribute( $variable ); + + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $disabled_attribute output is hardcoded and all other output is properly escaped. + echo '', '
            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in getter. + echo Yoast_Input_Validation::get_the_error_description( $variable ); + } + + /** + * Create a Number input field. + * + * @param string $variable The variable within the option to create the text input field for. + * @param string $label The label to show for the variable. + * @param array|string $attr Extra attributes to add to the input field. Can be class, disabled, autocomplete. + * + * @return void + */ + public function number( $variable, $label, $attr = [] ) { + $type = 'number'; + $defaults = [ + 'placeholder' => '', + 'class' => 'number', + 'disabled' => false, + 'min' => 0, + 'max' => 100, + ]; + $attr = wp_parse_args( $attr, $defaults ); + $val = $this->get_field_value( $variable, 0 ); + + $this->label( + $label, + [ + 'for' => $variable, + 'class' => 'textinput ' . $attr['class'], + ], + ); + + $aria_attributes = Yoast_Input_Validation::get_the_aria_invalid_attribute( $variable ); + $aria_attributes .= Yoast_Input_Validation::get_the_aria_describedby_attribute( $variable ); + + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $disabled_attribute output is hardcoded and all other output is properly escaped. + echo '', '
            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in getter. + echo Yoast_Input_Validation::get_the_error_description( $variable ); + } + + /** + * Creates a text input field with with the ability to add content after the label. + * + * @param string $variable The variable within the option to create the text input field for. + * @param string $label The label to show for the variable. + * @param array $attr Extra attributes to add to the input field. + * + * @return void + */ + public function textinput_extra_content( $variable, $label, $attr = [] ) { + $type = 'text'; + + $defaults = [ + 'class' => 'yoast-field-group__inputfield', + 'disabled' => false, + ]; + + $attr = wp_parse_args( $attr, $defaults ); + $val = $this->get_field_value( $variable, '' ); + + if ( isset( $attr['type'] ) && $attr['type'] === 'url' ) { + $val = urldecode( $val ); + $type = 'url'; + } + + echo '
            '; + $this->label( + $label, + [ + 'for' => $variable, + 'class' => $attr['class'] . '--label', + ], + ); + + if ( isset( $attr['extra_content'] ) ) { + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: may contain HTML that should not be escaped. + echo $attr['extra_content']; + } + echo '
            '; + + $aria_attributes = Yoast_Input_Validation::get_the_aria_invalid_attribute( $variable ); + $aria_attributes .= Yoast_Input_Validation::get_the_aria_describedby_attribute( $variable ); + + // phpcs:disable WordPress.Security.EscapeOutput -- Reason: output is properly escaped or hardcoded. + printf( + '', + $type, + esc_attr( $this->option_name . '[' . $variable . ']' ), + esc_attr( $variable ), + esc_attr( $attr['class'] ), + isset( $attr['placeholder'] ) ? ' placeholder="' . esc_attr( $attr['placeholder'] ) . '"' : '', + isset( $attr['autocomplete'] ) ? ' autocomplete="' . esc_attr( $attr['autocomplete'] ) . '"' : '', + $aria_attributes, + esc_attr( $val ), + $this->get_disabled_attribute( $variable, $attr ), + ); + // phpcs:enable + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: output is properly escaped. + echo Yoast_Input_Validation::get_the_error_description( $variable ); + } + + /** + * Create a textarea. + * + * @since 2.0 + * + * @param string $variable The variable within the option to create the textarea for. + * @param string $label The label to show for the variable. + * @param string|array $attr The CSS class or an array of attributes to assign to the textarea. + * + * @return void + */ + public function textarea( $variable, $label, $attr = [] ) { + if ( ! is_array( $attr ) ) { + $attr = [ + 'class' => $attr, + ]; + } + + $defaults = [ + 'cols' => '', + 'rows' => '', + 'class' => '', + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + $val = $this->get_field_value( $variable, '' ); + + $this->label( + $label, + [ + 'for' => $variable, + 'class' => 'textinput', + ], + ); + + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $disabled_attribute output is hardcoded and all other output is properly escaped. + echo '
            '; + } + + /** + * Create a hidden input field. + * + * @since 2.0 + * + * @param string $variable The variable within the option to create the hidden input for. + * @param string $id The ID of the element. + * @param mixed $val Optional. The value to set in the input field. Otherwise the value from the options will be used. + * + * @return void + */ + public function hidden( $variable, $id = '', $val = null ) { + $val ??= $this->get_field_value( $variable, '' ); + + if ( is_bool( $val ) ) { + $val = ( $val === true ) ? 'true' : 'false'; + } + + if ( $id === '' ) { + $id = 'hidden_' . $variable; + } + + echo ''; + } + + /** + * Create a Select Box. + * + * @since 2.0 + * + * @param string $variable The variable within the option to create the select for. + * @param string $label The label to show for the variable. + * @param array $select_options The select options to choose from. + * @param string $styled The select style. Use 'styled' to get a styled select. Default 'unstyled'. + * @param bool $show_label Whether or not to show the label, if not, it will be applied as an aria-label. + * @param array $attr Extra attributes to add to the select. + * @param string $help Optional. Inline Help HTML that will be printed after the label. Default is empty. + * + * @return void + */ + public function select( $variable, $label, array $select_options, $styled = 'unstyled', $show_label = true, $attr = [], $help = '' ) { + if ( empty( $select_options ) ) { + return; + } + + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + if ( $show_label ) { + $this->label( + $label, + [ + 'for' => $variable, + 'class' => 'select', + ], + ); + echo $help; // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: The help contains HTML. + } + + $select_name = esc_attr( $this->option_name ) . '[' . esc_attr( $variable ) . ']'; + $active_option = $this->get_field_value( $variable, '' ); + $wrapper_start_tag = ''; + $wrapper_end_tag = ''; + + $select = new Yoast_Input_Select( $variable, $select_name, $select_options, $active_option ); + $select->add_attribute( 'class', 'select' ); + + if ( $this->is_control_disabled( $variable ) + || ( isset( $attr['disabled'] ) && $attr['disabled'] ) ) { + $select->add_attribute( 'disabled', 'disabled' ); + } + + if ( ! $show_label ) { + $select->add_attribute( 'aria-label', $label ); + } + + if ( $styled === 'styled' ) { + $wrapper_start_tag = ''; + $wrapper_end_tag = ''; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + echo $wrapper_start_tag; + $select->output_html(); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + echo $wrapper_end_tag; + echo '
            '; + } + + /** + * Create a File upload field. + * + * @since 2.0 + * + * @param string $variable The variable within the option to create the file upload field for. + * @param string $label The label to show for the variable. + * @param array $attr Extra attributes to add to the file upload input. + * + * @return void + */ + public function file_upload( $variable, $label, $attr = [] ) { + $val = $this->get_field_value( $variable, '' ); + if ( is_array( $val ) ) { + $val = $val['url']; + } + + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + $var_esc = esc_attr( $variable ); + $this->label( + $label, + [ + 'for' => $variable, + 'class' => 'select', + ], + ); + + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $disabled_attribute output is hardcoded and all other output is properly escaped. + echo ''; + + // Need to save separate array items in hidden inputs, because empty file inputs type will be deleted by settings API. + if ( ! empty( $val ) ) { + $this->hidden( 'file', $this->option_name . '_file' ); + $this->hidden( 'url', $this->option_name . '_url' ); + $this->hidden( 'type', $this->option_name . '_type' ); + } + echo '
            '; + } + + /** + * Media input. + * + * @since 2.0 + * @deprecated 23.5 + * @codeCoverageIgnore + * + * @param string $variable Option name. + * @param string $label Label message. + * @param array $attr Extra attributes to add to the media input and buttons. + * + * @return void + */ + public function media_input( $variable, $label, $attr = [] ) { + + _deprecated_function( __METHOD__, 'Yoast SEO 23.5' ); + + $val = $this->get_field_value( $variable, '' ); + $id_value = $this->get_field_value( $variable . '_id', '' ); + + $var_esc = esc_attr( $variable ); + + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + $this->label( + $label, + [ + 'for' => 'wpseo_' . $variable, + 'class' => 'select', + ], + ); + + $id_field_id = 'wpseo_' . $var_esc . '_id'; + + echo ''; + echo ' '; + echo ''; + echo ''; + echo '
            '; + } + + /** + * Create a Radio input field. + * + * @since 2.0 + * + * @param string $variable The variable within the option to create the radio button for. + * @param array $values The radio options to choose from. + * @param string $legend Optional. The legend to show for the field set, if any. + * @param array $legend_attr Optional. The attributes for the legend, if any. + * @param array $attr Extra attributes to add to the radio button. + * + * @return void + */ + public function radio( $variable, $values, $legend = '', $legend_attr = [], $attr = [] ) { + if ( ! is_array( $values ) || $values === [] ) { + return; + } + $val = $this->get_field_value( $variable, false ); + + $var_esc = esc_attr( $variable ); + + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + echo '
            '; + + if ( is_string( $legend ) && $legend !== '' ) { + + $legend_defaults = [ + 'id' => '', + 'class' => 'radiogroup', + ]; + + $legend_attr = wp_parse_args( $legend_attr, $legend_defaults ); + + $this->legend( $legend, $legend_attr ); + } + + foreach ( $values as $key => $value ) { + $label = $value; + $aria_label = ''; + + if ( is_array( $value ) ) { + $label = ( $value['label'] ?? '' ); + $aria_label = ( $value['aria_label'] ?? '' ); + } + + $key_esc = esc_attr( $key ); + + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $disabled_attribute output is hardcoded and all other output is properly escaped. + echo ''; + $this->label( + $label, + [ + 'for' => $var_esc . '-' . $key_esc, + 'class' => 'radio', + 'aria_label' => $aria_label, + ], + ); + } + echo '
            '; + } + + /** + * Create a toggle switch input field using two radio buttons. + * + * @since 3.1 + * + * @param string $variable The variable within the option to create the radio buttons for. + * @param array $values Associative array of on/off keys and their values to be used as + * the label elements text for the radio buttons. Optionally, each + * value can be an array of visible label text and screen reader text. + * @param string $label The visual label for the radio buttons group, used as the fieldset legend. + * @param string $help Inline Help that will be printed out before the visible toggles text. + * @param array $attr Extra attributes to add to the toggle switch. + * + * @return void + */ + public function toggle_switch( $variable, $values, $label, $help = '', $attr = [] ) { + if ( ! is_array( $values ) || $values === [] ) { + return; + } + + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + if ( isset( $attr['preserve_disabled_value'] ) && $attr['preserve_disabled_value'] ) { + $this->hidden( $variable ); + $variable .= '_disabled'; + } + + $val = $this->get_field_value( $variable, false ); + if ( $val === true ) { + $val = 'on'; + } + if ( $val === false ) { + $val = 'off'; + } + + $help_class = ! empty( $help ) ? ' switch-container__has-help' : ''; + + $has_premium_upsell = ( isset( $attr['show_premium_upsell'] ) && $attr['show_premium_upsell'] && isset( $attr['premium_upsell_url'] ) && ! empty( $attr['premium_upsell_url'] ) ); + $upsell_class = ( $has_premium_upsell ) ? ' premium-upsell' : ''; + + $var_esc = esc_attr( $variable ); + + printf( '
            ', esc_attr( 'switch-container' . $help_class . $upsell_class ) ); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + echo '
            ', $label, '', $help; + + // Show disabled note if attribute does not exists or does exist and is set to true. + if ( ! isset( $attr['show_disabled_note'] ) || ( $attr['show_disabled_note'] === true ) ) { + if ( isset( $attr['note_when_disabled'] ) ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + echo $this->get_disabled_note( $variable, $attr['note_when_disabled'] ); + } + else { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + echo $this->get_disabled_note( $variable ); + } + } + + echo '
            '; + + foreach ( $values as $key => $value ) { + $screen_reader_text_html = ''; + + if ( is_array( $value ) ) { + $screen_reader_text = $value['screen_reader_text']; + $screen_reader_text_html = ' ' . esc_html( $screen_reader_text ) . ''; + $value = $value['text']; + } + + $key_esc = esc_attr( $key ); + $for = $var_esc . '-' . $key_esc; + $disabled_attribute = $this->get_disabled_attribute( $variable, $attr ); + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: $disabled_attribute output is hardcoded and all other output is properly escaped. + echo '', + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped before. + ''; + } + + $upsell_button = ''; + if ( $has_premium_upsell ) { + $upsell_button = '' + . esc_html__( 'Unlock with Premium!', 'wordpress-seo' ) + /* translators: Hidden accessibility text. */ + . '' . esc_html__( '(Opens in a new browser tab)', 'wordpress-seo' ) . '' + . ''; + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- All variable output is escaped above. + echo '
            ' . $upsell_button . '
            ' . PHP_EOL . PHP_EOL; + } + + /** + * Creates a toggle switch to define whether an indexable should be indexed or not. + * + * @param string $variable The variable within the option to create the radio buttons for. + * @param string $label The visual label for the radio buttons group, used as the fieldset legend. + * @param string $help Inline Help that will be printed out before the visible toggles text. + * @param array $attr Extra attributes to add to the index switch. + * + * @return void + */ + public function index_switch( $variable, $label, $help = '', $attr = [] ) { + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + $index_switch_values = [ + 'off' => __( 'On', 'wordpress-seo' ), + 'on' => __( 'Off', 'wordpress-seo' ), + ]; + + $is_disabled = ( isset( $attr['disabled'] ) && $attr['disabled'] ); + + $this->toggle_switch( + $variable, + $index_switch_values, + sprintf( + /* translators: %s expands to an indexable object's name, like a post type or taxonomy */ + esc_html__( 'Show %s in search results?', 'wordpress-seo' ), + $label, + ), + $help, + [ 'disabled' => $is_disabled ], + ); + } + + /** + * Creates a toggle switch to show hide certain options. + * + * @param string $variable The variable within the option to create the radio buttons for. + * @param string $label The visual label for the radio buttons group, used as the fieldset legend. + * @param bool $inverse_keys Whether or not the option keys need to be inverted to support older functions. + * @param string $help Inline Help that will be printed out before the visible toggles text. + * @param array $attr Extra attributes to add to the show-hide switch. + * + * @return void + */ + public function show_hide_switch( $variable, $label, $inverse_keys = false, $help = '', $attr = [] ) { + $defaults = [ + 'disabled' => false, + ]; + $attr = wp_parse_args( $attr, $defaults ); + + $on_key = ( $inverse_keys ) ? 'off' : 'on'; + $off_key = ( $inverse_keys ) ? 'on' : 'off'; + + $show_hide_switch = [ + $on_key => __( 'On', 'wordpress-seo' ), + $off_key => __( 'Off', 'wordpress-seo' ), + ]; + + $is_disabled = ( isset( $attr['disabled'] ) && $attr['disabled'] ); + + $this->toggle_switch( + $variable, + $show_hide_switch, + $label, + $help, + [ 'disabled' => $is_disabled ], + ); + } + + /** + * Retrieves the value for the form field. + * + * @param string $field_name The field name to retrieve the value for. + * @param string|null $default_value The default value, when field has no value. + * + * @return mixed|null The retrieved value. + */ + protected function get_field_value( $field_name, $default_value = null ) { + // On multisite subsites, the Usage tracking feature should always be set to Off. + if ( $this->is_tracking_on_subsite( $field_name ) ) { + return false; + } + + return WPSEO_Options::get( $field_name, $default_value ); + } + + /** + * Checks whether a given control should be disabled. + * + * @param string $variable The variable within the option to check whether its control should be disabled. + * + * @return bool True if control should be disabled, false otherwise. + */ + protected function is_control_disabled( $variable ) { + if ( $this->option_instance === null ) { + return false; + } + + // Disable the Usage tracking feature for multisite subsites. + if ( $this->is_tracking_on_subsite( $variable ) ) { + return true; + } + + return $this->option_instance->is_disabled( $variable ); + } + + /** + * Gets the explanation note to print if a given control is disabled. + * + * @param string $variable The variable within the option to print a disabled note for. + * @param string $custom_note An optional custom note to print instead. + * + * @return string Explanation note HTML string, or empty string if no note necessary. + */ + protected function get_disabled_note( $variable, $custom_note = '' ) { + if ( $custom_note === '' && ! $this->is_control_disabled( $variable ) ) { + return ''; + } + $disabled_message = esc_html__( 'This feature has been disabled by the network admin.', 'wordpress-seo' ); + + // The explanation to show when disabling the Usage tracking feature for multisite subsites. + if ( $this->is_tracking_on_subsite( $variable ) ) { + $disabled_message = esc_html__( 'This feature has been disabled since subsites never send tracking data.', 'wordpress-seo' ); + } + + if ( $custom_note ) { + $disabled_message = esc_html( $custom_note ); + } + + return '

            ' . $disabled_message . '

            '; + } + + /** + * Determines whether we are dealing with the Usage tracking feature on a multisite subsite. + * This feature requires specific behavior for the toggle switch. + * + * @param string $feature_setting The feature setting. + * + * @return bool True if we are dealing with the Usage tracking feature on a multisite subsite. + */ + protected function is_tracking_on_subsite( $feature_setting ) { + return ( $feature_setting === 'tracking' && ! is_network_admin() && ! is_main_site() ); + } + + /** + * Returns the disabled attribute HTML. + * + * @param string $variable The variable within the option of the related form element. + * @param array $attr Extra attributes added to the form element. + * + * @return string The disabled attribute HTML. + */ + protected function get_disabled_attribute( $variable, $attr ) { + if ( $this->is_control_disabled( $variable ) || ( isset( $attr['disabled'] ) && $attr['disabled'] ) ) { + return ' disabled'; + } + + return ''; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-input-validation.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-input-validation.php new file mode 100644 index 0000000..ad1c261 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-input-validation.php @@ -0,0 +1,252 @@ + + */ + private static $error_descriptions = []; + + /** + * Check whether an option group is a Yoast SEO setting. + * + * The normal pattern is 'yoast' . $option_name . 'options'. + * + * @since 12.0 + * + * @param string $group_name The option group name. + * + * @return bool Whether or not it's an Yoast SEO option group. + */ + public static function is_yoast_option_group_name( $group_name ) { + return ( strpos( $group_name, 'yoast' ) !== false ); + } + + /** + * Adds an error message to the document title when submitting a settings + * form and errors are returned. + * + * Uses the WordPress `admin_title` filter in the WPSEO_Option subclasses. + * + * @since 12.0 + * + * @param string $admin_title The page title, with extra context added. + * + * @return string The modified or original admin title. + */ + public static function add_yoast_admin_document_title_errors( $admin_title ) { + $errors = get_settings_errors(); + $error_count = 0; + + foreach ( $errors as $error ) { + // For now, filter the admin title only in the Yoast SEO settings pages. + if ( self::is_yoast_option_group_name( $error['setting'] ) && $error['code'] !== 'settings_updated' ) { + ++$error_count; + } + } + + if ( $error_count > 0 ) { + return sprintf( + /* translators: %1$s: amount of errors, %2$s: the admin page title */ + _n( 'The form contains %1$s error. %2$s', 'The form contains %1$s errors. %2$s', $error_count, 'wordpress-seo' ), + number_format_i18n( $error_count ), + $admin_title, + ); + } + + return $admin_title; + } + + /** + * Checks whether a specific form input field was submitted with an invalid value. + * + * @since 12.1 + * + * @param string $error_code Must be the same slug-name used for the field variable and for `add_settings_error()`. + * + * @return bool Whether or not the submitted input field contained an invalid value. + */ + public static function yoast_form_control_has_error( $error_code ) { + $errors = get_settings_errors(); + + foreach ( $errors as $error ) { + if ( $error['code'] === $error_code ) { + return true; + } + } + + return false; + } + + /** + * Sets the error descriptions. + * + * @since 12.1 + * @deprecated 23.3 + * @codeCoverageIgnore + * + * @param array $descriptions An associative array of error descriptions. + * For each entry, the key must be the setting variable. + * + * @return void + */ + public static function set_error_descriptions( $descriptions = [] ) { // @phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Needed for BC. + _deprecated_function( __METHOD__, 'Yoast SEO 23.3' ); + } + + /** + * Gets all the error descriptions. + * + * @since 12.1 + * @deprecated 23.3 + * @codeCoverageIgnore + * + * @return array An associative array of error descriptions. + */ + public static function get_error_descriptions() { + _deprecated_function( __METHOD__, 'Yoast SEO 23.3' ); + return []; + } + + /** + * Gets a specific error description. + * + * @since 12.1 + * + * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. + * + * @return string|null The error description. + */ + public static function get_error_description( $error_code ) { + if ( ! isset( self::$error_descriptions[ $error_code ] ) ) { + return null; + } + + return self::$error_descriptions[ $error_code ]; + } + + /** + * Gets the aria-invalid HTML attribute based on the submitted invalid value. + * + * @since 12.1 + * + * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. + * + * @return string The aria-invalid HTML attribute or empty string. + */ + public static function get_the_aria_invalid_attribute( $error_code ) { + if ( self::yoast_form_control_has_error( $error_code ) ) { + return ' aria-invalid="true"'; + } + + return ''; + } + + /** + * Gets the aria-describedby HTML attribute based on the submitted invalid value. + * + * @since 12.1 + * + * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. + * + * @return string The aria-describedby HTML attribute or empty string. + */ + public static function get_the_aria_describedby_attribute( $error_code ) { + if ( self::yoast_form_control_has_error( $error_code ) && self::get_error_description( $error_code ) ) { + return ' aria-describedby="' . esc_attr( $error_code ) . '-error-description"'; + } + + return ''; + } + + /** + * Gets the error description wrapped in a HTML paragraph. + * + * @since 12.1 + * + * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. + * + * @return string The error description HTML or empty string. + */ + public static function get_the_error_description( $error_code ) { + $error_description = self::get_error_description( $error_code ); + + if ( self::yoast_form_control_has_error( $error_code ) && $error_description ) { + return '

            ' . $error_description . '

            '; + } + + return ''; + } + + /** + * Adds the submitted invalid value to the WordPress `$wp_settings_errors` global. + * + * @since 12.1 + * + * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. + * @param string $dirty_value The submitted invalid value. + * + * @return void + */ + public static function add_dirty_value_to_settings_errors( $error_code, $dirty_value ) { + global $wp_settings_errors; + + if ( ! is_array( $wp_settings_errors ) ) { + return; + } + + foreach ( $wp_settings_errors as $index => $error ) { + if ( $error['code'] === $error_code ) { + // phpcs:ignore WordPress.WP.GlobalVariablesOverride -- This is a deliberate action. + $wp_settings_errors[ $index ]['yoast_dirty_value'] = $dirty_value; + } + } + } + + /** + * Gets an invalid submitted value. + * + * @since 12.1 + * @deprecated 23.3 + * @codeCoverageIgnore + * + * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. + * + * @return string The submitted invalid input field value. + */ + public static function get_dirty_value( $error_code ) { // @phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Needed for BC. + _deprecated_function( __METHOD__, 'Yoast SEO 23.3' ); + return ''; + } + + /** + * Gets a specific invalid value message. + * + * @since 12.1 + * @deprecated 23.3 + * @codeCoverageIgnore + * + * @param string $error_code Code of the error set via `add_settings_error()`, normally the variable name. + * + * @return string The error invalid value message or empty string. + */ + public static function get_dirty_value_message( $error_code ) { // @phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable, Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Needed for BC. + _deprecated_function( __METHOD__, 'Yoast SEO 23.3' ); + + return ''; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-network-admin.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-network-admin.php new file mode 100644 index 0000000..cc41698 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-network-admin.php @@ -0,0 +1,334 @@ + $site_label pairs. + */ + public function get_site_choices( $include_empty = false, $show_title = false ) { + $choices = []; + + if ( $include_empty ) { + $choices['-'] = __( 'None', 'wordpress-seo' ); + } + + $criteria = [ + 'deleted' => 0, + 'network_id' => get_current_network_id(), + ]; + $sites = get_sites( $criteria ); + + foreach ( $sites as $site ) { + $site_name = $site->domain . $site->path; + if ( $show_title ) { + $site_name = $site->blogname . ' (' . $site->domain . $site->path . ')'; + } + $choices[ $site->blog_id ] = $site->blog_id . ': ' . $site_name; + + $site_states = $this->get_site_states( $site ); + if ( ! empty( $site_states ) ) { + $choices[ $site->blog_id ] .= ' [' . implode( ', ', $site_states ) . ']'; + } + } + + return $choices; + } + + /** + * Gets the states of a site. + * + * @param WP_Site $site Site object. + * + * @return array Array of $state_slug => $state_label pairs. + */ + public function get_site_states( $site ) { + $available_states = [ + 'public' => __( 'public', 'wordpress-seo' ), + 'archived' => __( 'archived', 'wordpress-seo' ), + 'mature' => __( 'mature', 'wordpress-seo' ), + 'spam' => __( 'spam', 'wordpress-seo' ), + 'deleted' => __( 'deleted', 'wordpress-seo' ), + ]; + + $site_states = []; + foreach ( $available_states as $state_slug => $state_label ) { + if ( $site->$state_slug === '1' ) { + $site_states[ $state_slug ] = $state_label; + } + } + + return $site_states; + } + + /** + * Handles a request to update plugin network options. + * + * This method works similar to how option updates are handled in `wp-admin/options.php` and + * `wp-admin/network/settings.php`. + * + * @return void + */ + public function handle_update_options_request() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification will happen in verify_request below. + if ( ! isset( $_POST['network_option_group'] ) || ! is_string( $_POST['network_option_group'] ) ) { + return; + } + + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce verification will happen in verify_request below. + $option_group = sanitize_text_field( wp_unslash( $_POST['network_option_group'] ) ); + + if ( empty( $option_group ) ) { + return; + } + + $this->verify_request( "{$option_group}-network-options" ); + + $whitelist_options = Yoast_Network_Settings_API::get()->get_whitelist_options( $option_group ); + + if ( empty( $whitelist_options ) ) { + add_settings_error( $option_group, 'settings_updated', __( 'You are not allowed to modify unregistered network settings.', 'wordpress-seo' ), 'error' ); + + $this->terminate_request(); + return; + } + + // phpcs:disable WordPress.Security.NonceVerification -- Nonce verified via `verify_request()` above. + foreach ( $whitelist_options as $option_name ) { + $value = null; + if ( isset( $_POST[ $option_name ] ) ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: Adding sanitize_text_field around this will break the saving of settings because it expects a string: https://github.com/Yoast/wordpress-seo/issues/12440. + $value = wp_unslash( $_POST[ $option_name ] ); + } + + WPSEO_Options::update_site_option( $option_name, $value ); + } + // phpcs:enable WordPress.Security.NonceVerification + + $settings_errors = get_settings_errors(); + if ( empty( $settings_errors ) ) { + add_settings_error( $option_group, 'settings_updated', __( 'Settings Updated.', 'wordpress-seo' ), 'updated' ); + } + + $this->terminate_request(); + } + + /** + * Handles a request to restore a site's default settings. + * + * @return void + */ + public function handle_restore_site_request() { + $this->verify_request( 'wpseo-network-restore', 'restore_site_nonce' ); + + $option_group = 'wpseo_ms'; + + // phpcs:ignore WordPress.Security.NonceVerification -- Nonce verified via `verify_request()` above. + $site_id = ! empty( $_POST[ $option_group ]['site_id'] ) ? (int) $_POST[ $option_group ]['site_id'] : 0; + if ( ! $site_id ) { + add_settings_error( $option_group, 'settings_updated', __( 'No site has been selected to restore.', 'wordpress-seo' ), 'error' ); + + $this->terminate_request(); + return; + } + + $site = get_site( $site_id ); + if ( ! $site ) { + /* translators: %s expands to the ID of a site within a multisite network. */ + add_settings_error( $option_group, 'settings_updated', sprintf( __( 'Site with ID %d not found.', 'wordpress-seo' ), $site_id ), 'error' ); + } + else { + WPSEO_Options::reset_ms_blog( $site_id ); + + /* translators: %s expands to the name of a site within a multisite network. */ + add_settings_error( $option_group, 'settings_updated', sprintf( __( '%s restored to default SEO settings.', 'wordpress-seo' ), esc_html( $site->blogname ) ), 'updated' ); + } + + $this->terminate_request(); + } + + /** + * Outputs nonce, action and option group fields for a network settings page in the plugin. + * + * @param string $option_group Option group name for the current page. + * + * @return void + */ + public function settings_fields( $option_group ) { + ?> + + + enqueue_script( 'network-admin' ); + + $translations = [ + /* translators: %s: success message */ + 'success_prefix' => __( 'Success: %s', 'wordpress-seo' ), + /* translators: %s: error message */ + 'error_prefix' => __( 'Error: %s', 'wordpress-seo' ), + ]; + $asset_manager->localize_script( + 'network-admin', + 'wpseoNetworkAdminGlobalL10n', + $translations, + ); + } + + /** + * Hooks in the necessary actions and filters. + * + * @return void + */ + public function register_hooks() { + + if ( ! $this->meets_requirements() ) { + return; + } + + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] ); + + add_action( 'admin_action_' . self::UPDATE_OPTIONS_ACTION, [ $this, 'handle_update_options_request' ] ); + add_action( 'admin_action_' . self::RESTORE_SITE_ACTION, [ $this, 'handle_restore_site_request' ] ); + } + + /** + * Hooks in the necessary AJAX actions. + * + * @return void + */ + public function register_ajax_hooks() { + add_action( 'wp_ajax_' . self::UPDATE_OPTIONS_ACTION, [ $this, 'handle_update_options_request' ] ); + add_action( 'wp_ajax_' . self::RESTORE_SITE_ACTION, [ $this, 'handle_restore_site_request' ] ); + } + + /** + * Checks whether the requirements to use this class are met. + * + * @return bool True if requirements are met, false otherwise. + */ + public function meets_requirements() { + return is_multisite() && is_network_admin(); + } + + /** + * Verifies that the current request is valid. + * + * @param string $action Nonce action. + * @param string $query_arg Optional. Nonce query argument. Default '_wpnonce'. + * + * @return void + */ + public function verify_request( $action, $query_arg = '_wpnonce' ) { + $has_access = current_user_can( 'wpseo_manage_network_options' ); + + if ( wp_doing_ajax() ) { + check_ajax_referer( $action, $query_arg ); + + if ( ! $has_access ) { + wp_die( -1, 403 ); + } + return; + } + + check_admin_referer( $action, $query_arg ); + + if ( ! $has_access ) { + wp_die( esc_html__( 'You are not allowed to perform this action.', 'wordpress-seo' ) ); + } + } + + /** + * Terminates the current request by either redirecting back or sending an AJAX response. + * + * @return void + */ + public function terminate_request() { + if ( wp_doing_ajax() ) { + $settings_errors = get_settings_errors(); + + if ( ! empty( $settings_errors ) && $settings_errors[0]['type'] === 'updated' ) { + wp_send_json_success( $settings_errors, 200 ); + } + + wp_send_json_error( $settings_errors, 400 ); + } + + $this->persist_settings_errors(); + $this->redirect_back( [ 'settings-updated' => 'true' ] ); + } + + /** + * Persists settings errors. + * + * Settings errors are stored in a transient for 30 seconds so that this transient + * can be retrieved on the next page load. + * + * @return void + */ + protected function persist_settings_errors() { + /* + * A regular transient is used here, since it is automatically cleared right after the redirect. + * A network transient would be cleaner, but would require a lot of copied code from core for + * just a minor adjustment when displaying settings errors. + */ + set_transient( 'settings_errors', get_settings_errors(), 30 ); + } + + /** + * Redirects back to the referer URL, with optional query arguments. + * + * @param array $query_args Optional. Query arguments to add to the redirect URL. Default none. + * + * @return void + */ + protected function redirect_back( $query_args = [] ) { + $sendback = wp_get_referer(); + + if ( ! empty( $query_args ) ) { + $sendback = add_query_arg( $query_args, $sendback ); + } + + wp_safe_redirect( $sendback ); + exit(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-network-settings-api.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-network-settings-api.php new file mode 100644 index 0000000..05c0d7e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-network-settings-api.php @@ -0,0 +1,162 @@ + $option_group, + 'sanitize_callback' => null, + ]; + $args = wp_parse_args( $args, $defaults ); + + if ( ! isset( $this->whitelist_options[ $option_group ] ) ) { + $this->whitelist_options[ $option_group ] = []; + } + + $this->whitelist_options[ $option_group ][] = $option_name; + + if ( ! empty( $args['sanitize_callback'] ) ) { + add_filter( "sanitize_option_{$option_name}", [ $this, 'filter_sanitize_option' ], 10, 2 ); + } + + if ( array_key_exists( 'default', $args ) ) { + add_filter( "default_site_option_{$option_name}", [ $this, 'filter_default_option' ], 10, 2 ); + } + + $this->registered_settings[ $option_name ] = $args; + } + + /** + * Gets the registered settings and their data. + * + * @return array Array of $option_name => $data pairs. + */ + public function get_registered_settings() { + return $this->registered_settings; + } + + /** + * Gets the whitelisted options for a given option group. + * + * @param string $option_group Option group. + * + * @return array List of option names, or empty array if unknown option group. + */ + public function get_whitelist_options( $option_group ) { + if ( ! isset( $this->whitelist_options[ $option_group ] ) ) { + return []; + } + + return $this->whitelist_options[ $option_group ]; + } + + /** + * Filters sanitization for a network option value. + * + * This method is added as a filter to `sanitize_option_{$option}` for network options that are + * registered with a sanitize callback. + * + * @param string $value The sanitized option value. + * @param string $option The option name. + * + * @return string The filtered sanitized option value. + */ + public function filter_sanitize_option( $value, $option ) { + + if ( empty( $this->registered_settings[ $option ] ) ) { + return $value; + } + + return call_user_func( $this->registered_settings[ $option ]['sanitize_callback'], $value ); + } + + /** + * Filters the default value for a network option. + * + * This function is added as a filter to `default_site_option_{$option}` for network options that + * are registered with a default. + * + * @param mixed $default_value Existing default value to return. + * @param string $option The option name. + * + * @return mixed The filtered default value. + */ + public function filter_default_option( $default_value, $option ) { + + // If a default value was manually passed to the function, allow it to override. + if ( $default_value !== false ) { + return $default_value; + } + + if ( empty( $this->registered_settings[ $option ] ) ) { + return $default_value; + } + + return $this->registered_settings[ $option ]['default']; + } + + /** + * Checks whether the requirements to use this class are met. + * + * @return bool True if requirements are met, false otherwise. + */ + public function meets_requirements() { + return is_multisite(); + } + + /** + * Gets the singleton instance of this class. + * + * @return Yoast_Network_Settings_API The singleton instance. + */ + public static function get() { + + self::$instance ??= new self(); + + return self::$instance; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notification-center.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notification-center.php new file mode 100644 index 0000000..974abcc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notification-center.php @@ -0,0 +1,958 @@ +get_notification_by_id( $notification_id ); + if ( ( $notification instanceof Yoast_Notification ) === false ) { + + // Permit legacy. + $options = [ + 'id' => $notification_id, + 'dismissal_key' => $notification_id, + ]; + $notification = new Yoast_Notification( '', $options ); + } + + if ( self::maybe_dismiss_notification( $notification ) ) { + exit( '1' ); + } + + exit( '-1' ); + } + + /** + * Check if the user has dismissed a notification. + * + * @param Yoast_Notification $notification The notification to check for dismissal. + * @param int|null $user_id User ID to check on. + * + * @return bool + */ + public static function is_notification_dismissed( Yoast_Notification $notification, $user_id = null ) { + + $user_id = self::get_user_id( $user_id ); + $dismissal_key = $notification->get_dismissal_key(); + + // This checks both the site-specific user option and the meta value. + $current_value = get_user_option( $dismissal_key, $user_id ); + + // Migrate old user meta to user option on-the-fly. + if ( ! empty( $current_value ) + && metadata_exists( 'user', $user_id, $dismissal_key ) + && update_user_option( $user_id, $dismissal_key, $current_value ) ) { + delete_user_meta( $user_id, $dismissal_key ); + } + + return ! empty( $current_value ); + } + + /** + * Checks if the notification is being dismissed. + * + * @param Yoast_Notification $notification Notification to check dismissal of. + * @param string $meta_value Value to set the meta value to if dismissed. + * + * @return bool True if dismissed. + */ + public static function maybe_dismiss_notification( Yoast_Notification $notification, $meta_value = 'seen' ) { + + // Only persistent notifications are dismissible. + if ( ! $notification->is_persistent() ) { + return false; + } + + // If notification is already dismissed, we're done. + if ( self::is_notification_dismissed( $notification ) ) { + return true; + } + + $dismissal_key = $notification->get_dismissal_key(); + $notification_id = $notification->get_id(); + + $is_dismissing = ( $dismissal_key === self::get_user_input( 'notification' ) ); + if ( ! $is_dismissing ) { + $is_dismissing = ( $notification_id === self::get_user_input( 'notification' ) ); + } + + // Fallback to ?dismissal_key=1&nonce=bla when JavaScript fails. + if ( ! $is_dismissing ) { + $is_dismissing = ( self::get_user_input( $dismissal_key ) === '1' ); + } + + if ( ! $is_dismissing ) { + return false; + } + + $user_nonce = self::get_user_input( 'nonce' ); + if ( wp_verify_nonce( $user_nonce, $notification_id ) === false ) { + return false; + } + + return self::dismiss_notification( $notification, $meta_value ); + } + + /** + * Dismisses a notification. + * + * @param Yoast_Notification $notification Notification to dismiss. + * @param string $meta_value Value to save in the dismissal. + * + * @return bool True if dismissed, false otherwise. + */ + public static function dismiss_notification( Yoast_Notification $notification, $meta_value = 'seen' ) { + // Dismiss notification. + return update_user_option( get_current_user_id(), $notification->get_dismissal_key(), $meta_value ) !== false; + } + + /** + * Restores a notification. + * + * @param Yoast_Notification $notification Notification to restore. + * + * @return bool True if restored, false otherwise. + */ + public static function restore_notification( Yoast_Notification $notification ) { + + $user_id = get_current_user_id(); + $dismissal_key = $notification->get_dismissal_key(); + + // Restore notification. + $restored = delete_user_option( $user_id, $dismissal_key ); + + // Delete unprefixed user meta too for backward-compatibility. + if ( metadata_exists( 'user', $user_id, $dismissal_key ) ) { + $restored = delete_user_meta( $user_id, $dismissal_key ) && $restored; + } + + return $restored; + } + + /** + * Clear dismissal information for the specified Notification. + * + * When a cause is resolved, the next time it is present we want to show + * the message again. + * + * @param string|Yoast_Notification $notification Notification to clear the dismissal of. + * + * @return bool + */ + public function clear_dismissal( $notification ) { + + global $wpdb; + + if ( $notification instanceof Yoast_Notification ) { + $dismissal_key = $notification->get_dismissal_key(); + } + + if ( is_string( $notification ) ) { + $dismissal_key = $notification; + } + + if ( empty( $dismissal_key ) ) { + return false; + } + + // Remove notification dismissal for all users. + $deleted = delete_metadata( 'user', 0, $wpdb->get_blog_prefix() . $dismissal_key, '', true ); + + // Delete unprefixed user meta too for backward-compatibility. + $deleted = delete_metadata( 'user', 0, $dismissal_key, '', true ) || $deleted; + + return $deleted; + } + + /** + * Retrieves notifications from the storage and merges in previous notification changes. + * + * The current user in WordPress is not loaded shortly before the 'init' hook, but the plugin + * sometimes needs to add or remove notifications before that. In such cases, the transactions + * are not actually executed, but added to a queue. That queue is then handled in this method, + * after notifications for the current user have been set up. + * + * @return void + */ + public function setup_current_notifications() { + $this->retrieve_notifications_from_storage( get_current_user_id() ); + + foreach ( $this->queued_transactions as $transaction ) { + list( $callback, $args ) = $transaction; + + call_user_func_array( $callback, $args ); + } + + $this->queued_transactions = []; + } + + /** + * Add notification to the cookie. + * + * @param Yoast_Notification $notification Notification object instance. + * + * @return void + */ + public function add_notification( Yoast_Notification $notification ) { + + $callback = [ $this, __FUNCTION__ ]; + $args = func_get_args(); + if ( $this->queue_transaction( $callback, $args ) ) { + return; + } + + // Don't add if the user can't see it. + if ( ! $notification->display_for_current_user() ) { + return; + } + + $notification_id = $notification->get_id(); + $user_id = $notification->get_user_id(); + + // Empty notifications are always added. + if ( $notification_id !== '' ) { + + // If notification ID exists in notifications, don't add again. + $present_notification = $this->get_notification_by_id( $notification_id, $user_id ); + if ( $present_notification !== null ) { + $this->remove_notification( $present_notification, false ); + } + + if ( $present_notification === null ) { + $this->new[] = $notification_id; + } + } + + // Add to list. + $this->notifications[ $user_id ][] = $notification; + + $this->notifications_need_storage = true; + } + + /** + * Get the notification by ID and user ID. + * + * @param string $notification_id The ID of the notification to search for. + * @param int|null $user_id The ID of the user. + * + * @return Yoast_Notification|null + */ + public function get_notification_by_id( $notification_id, $user_id = null ) { + $user_id = self::get_user_id( $user_id ); + + $notifications = $this->get_notifications_for_user( $user_id ); + + foreach ( $notifications as $notification ) { + if ( $notification_id === $notification->get_id() ) { + return $notification; + } + } + + return null; + } + + /** + * Display the notifications. + * + * @param bool $echo_as_json True when notifications should be printed directly. + * + * @return void + */ + public function display_notifications( $echo_as_json = false ) { + + // Never display notifications for network admin. + if ( is_network_admin() ) { + return; + } + + $sorted_notifications = $this->get_sorted_notifications(); + $notifications = array_filter( $sorted_notifications, [ $this, 'is_notification_persistent' ] ); + + if ( empty( $notifications ) ) { + return; + } + + array_walk( $notifications, [ $this, 'remove_notification' ] ); + + $notifications = array_unique( $notifications ); + if ( $echo_as_json ) { + $notification_json = []; + + foreach ( $notifications as $notification ) { + $notification_json[] = $notification->render(); + } + + // phpcs:ignore WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe. + echo WPSEO_Utils::format_json_encode( $notification_json ); + + return; + } + + foreach ( $notifications as $notification ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: Temporarily disabled, see: https://github.com/Yoast/wordpress-seo-premium/issues/2510 and https://github.com/Yoast/wordpress-seo-premium/issues/2511. + echo $notification; + } + } + + /** + * Remove notification after it has been displayed. + * + * @param Yoast_Notification $notification Notification to remove. + * @param bool $resolve Resolve as fixed. + * + * @return void + */ + public function remove_notification( Yoast_Notification $notification, $resolve = true ) { + + $callback = [ $this, __FUNCTION__ ]; + $args = func_get_args(); + if ( $this->queue_transaction( $callback, $args ) ) { + return; + } + + $index = false; + + // ID of the user to show the notification for, defaults to current user id. + $user_id = $notification->get_user_id(); + $notifications = $this->get_notifications_for_user( $user_id ); + + // Match persistent Notifications by ID, non persistent by item in the array. + if ( $notification->is_persistent() ) { + foreach ( $notifications as $current_index => $present_notification ) { + if ( $present_notification->get_id() === $notification->get_id() ) { + $index = $current_index; + break; + } + } + } + else { + $index = array_search( $notification, $notifications, true ); + } + + if ( $index === false ) { + return; + } + + if ( $notification->is_persistent() && $resolve ) { + ++$this->resolved; + $this->clear_dismissal( $notification ); + } + + unset( $notifications[ $index ] ); + $this->notifications[ $user_id ] = array_values( $notifications ); + + $this->notifications_need_storage = true; + } + + /** + * Removes a notification by its ID. + * + * @param string $notification_id The notification id. + * @param bool $resolve Resolve as fixed. + * + * @return void + */ + public function remove_notification_by_id( $notification_id, $resolve = true ) { + $notification = $this->get_notification_by_id( $notification_id ); + + if ( $notification === null ) { + return; + } + + $this->remove_notification( $notification, $resolve ); + $this->notifications_need_storage = true; + } + + /** + * Get the notification count. + * + * @param bool $dismissed Count dismissed notifications. + * + * @return int Number of notifications + */ + public function get_notification_count( $dismissed = false ) { + + $notifications = $this->get_notifications_for_user( get_current_user_id() ); + $notifications = array_filter( $notifications, [ $this, 'filter_persistent_notifications' ] ); + + if ( ! $dismissed ) { + $notifications = array_filter( $notifications, [ $this, 'filter_dismissed_notifications' ] ); + } + + return count( $notifications ); + } + + /** + * Get the number of notifications resolved this execution. + * + * These notifications have been resolved and should be counted when active again. + * + * @return int + */ + public function get_resolved_notification_count() { + + return $this->resolved; + } + + /** + * Return the notifications sorted on type and priority. + * + * @return Yoast_Notification[] Sorted Notifications + */ + public function get_sorted_notifications() { + $notifications = $this->get_notifications_for_user( get_current_user_id() ); + if ( empty( $notifications ) ) { + return []; + } + + // Sort by severity, error first. + usort( $notifications, [ $this, 'sort_notifications' ] ); + + return $notifications; + } + + /** + * AJAX display notifications. + * + * @return void + */ + public function ajax_get_notifications() { + $echo = false; + // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form data. + if ( isset( $_POST['version'] ) && is_string( $_POST['version'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are only comparing the variable in a condition. + $echo = wp_unslash( $_POST['version'] ) === '2'; + } + + // Display the notices. + $this->display_notifications( $echo ); + + // AJAX die. + exit(); + } + + /** + * Remove storage when the plugin is deactivated. + * + * @return void + */ + public function deactivate_hook() { + + $this->clear_notifications(); + } + + /** + * Returns the given user ID if it exists. + * Otherwise, this function returns the ID of the current user. + * + * @param int $user_id The user ID to check. + * + * @return int The user ID to use. + */ + private static function get_user_id( $user_id ) { + if ( $user_id ) { + return $user_id; + } + return get_current_user_id(); + } + + /** + * Splits the notifications on user ID. + * + * In other terms, it returns an associative array, + * mapping user ID to a list of notifications for this user. + * + * @param Yoast_Notification[] $notifications The notifications to split. + * + * @return array The notifications, split on user ID. + */ + private function split_on_user_id( $notifications ) { + $split_notifications = []; + foreach ( $notifications as $notification ) { + $split_notifications[ $notification->get_user_id() ][] = $notification; + } + return $split_notifications; + } + + /** + * Save persistent notifications to storage. + * + * We need to be able to retrieve these so they can be dismissed at any time during the execution. + * + * @since 3.2 + * + * @return void + */ + public function update_storage() { + /** + * Plugins might exit on the plugins_loaded hook. + * This prevents the pluggable.php file from loading, as it's loaded after the plugins_loaded hook. + * As we need functions defined in pluggable.php, make sure it's loaded. + */ + require_once ABSPATH . WPINC . '/pluggable.php'; + + $notifications = $this->notifications; + + /** + * One array of Yoast_Notifications, merged from multiple arrays. + * + * @var Yoast_Notification[] $merged_notifications + */ + $merged_notifications = []; + if ( ! empty( $notifications ) ) { + $merged_notifications = array_merge( ...$notifications ); + } + + /** + * Filter: 'yoast_notifications_before_storage' - Allows developer to filter notifications before saving them. + * + * @param Yoast_Notification[] $notifications + */ + $filtered_merged_notifications = apply_filters( 'yoast_notifications_before_storage', $merged_notifications ); + + // The notifications were filtered and therefore need to be stored. + if ( $merged_notifications !== $filtered_merged_notifications ) { + $merged_notifications = $filtered_merged_notifications; + $this->notifications_need_storage = true; + } + + $notifications = $this->split_on_user_id( $merged_notifications ); + + // No notifications to store, clear storage if it was previously present. + if ( empty( $notifications ) ) { + $this->remove_storage(); + + return; + } + + // Only store notifications if changes are made. + if ( $this->notifications_need_storage ) { + array_walk( $notifications, [ $this, 'store_notifications_for_user' ] ); + } + } + + /** + * Stores the notifications to its respective user's storage. + * + * @param Yoast_Notification[] $notifications The notifications to store. + * @param int $user_id The ID of the user for which to store the notifications. + * + * @return void + */ + private function store_notifications_for_user( $notifications, $user_id ) { + $notifications_as_arrays = array_map( [ $this, 'notification_to_array' ], $notifications ); + update_user_option( $user_id, self::STORAGE_KEY, $notifications_as_arrays ); + } + + /** + * Provide a way to verify present notifications. + * + * @return Yoast_Notification[] Registered notifications. + */ + public function get_notifications() { + if ( ! $this->notifications ) { + return []; + } + return array_merge( ...$this->notifications ); + } + + /** + * Returns the notifications for the given user. + * + * @param int $user_id The id of the user to check. + * + * @return Yoast_Notification[] The notifications for the user with the given ID. + */ + public function get_notifications_for_user( $user_id ) { + if ( array_key_exists( $user_id, $this->notifications ) ) { + return $this->notifications[ $user_id ]; + } + return []; + } + + /** + * Get newly added notifications. + * + * @return array + */ + public function get_new_notifications() { + + return array_map( [ $this, 'get_notification_by_id' ], $this->new ); + } + + /** + * Get information from the User input. + * + * Note that this function does not handle nonce verification. + * + * @param string $key Key to retrieve. + * + * @return string non-sanitized value of key if set, an empty string otherwise. + */ + private static function get_user_input( $key ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Missing -- Reason: We are not processing form information and only using this variable in a comparison. + $request_method = isset( $_SERVER['REQUEST_METHOD'] ) && is_string( $_SERVER['REQUEST_METHOD'] ) ? strtoupper( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) : ''; + // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: This function does not sanitize variables. + // phpcs:disable WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing -- Reason: This function does not verify a nonce. + if ( $request_method === 'POST' ) { + if ( isset( $_POST[ $key ] ) && is_string( $_POST[ $key ] ) ) { + return wp_unslash( $_POST[ $key ] ); + } + } + elseif ( isset( $_GET[ $key ] ) && is_string( $_GET[ $key ] ) ) { + return wp_unslash( $_GET[ $key ] ); + } + // phpcs:enable WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + return ''; + } + + /** + * Retrieve the notifications from storage and fill the relevant property. + * + * @param int $user_id The ID of the user to retrieve notifications for. + * + * @return void + */ + private function retrieve_notifications_from_storage( $user_id ) { + if ( $this->notifications_retrieved ) { + return; + } + + $this->notifications_retrieved = true; + + $stored_notifications = get_user_option( self::STORAGE_KEY, $user_id ); + + // Check if notifications are stored. + if ( empty( $stored_notifications ) ) { + return; + } + + if ( is_array( $stored_notifications ) ) { + $notifications = array_map( [ $this, 'array_to_notification' ], $stored_notifications ); + + // Apply array_values to ensure we get a 0-indexed array. + $notifications = array_values( array_filter( $notifications, [ $this, 'filter_notification_current_user' ] ) ); + + $this->notifications[ $user_id ] = $notifications; + } + } + + /** + * Sort on type then priority. + * + * @param Yoast_Notification $a Compare with B. + * @param Yoast_Notification $b Compare with A. + * + * @return int 1, 0 or -1 for sorting offset. + */ + private function sort_notifications( Yoast_Notification $a, Yoast_Notification $b ) { + + $a_type = $a->get_type(); + $b_type = $b->get_type(); + + if ( $a_type === $b_type ) { + return WPSEO_Utils::calc( $b->get_priority(), 'compare', $a->get_priority() ); + } + + if ( $a_type === 'error' ) { + return -1; + } + + if ( $b_type === 'error' ) { + return 1; + } + + return 0; + } + + /** + * Clear local stored notifications. + * + * @return void + */ + private function clear_notifications() { + + $this->notifications = []; + $this->notifications_retrieved = false; + } + + /** + * Filter out non-persistent notifications. + * + * @since 3.2 + * + * @param Yoast_Notification $notification Notification to test for persistent. + * + * @return bool + */ + private function filter_persistent_notifications( Yoast_Notification $notification ) { + + return $notification->is_persistent(); + } + + /** + * Filter out dismissed notifications. + * + * @param Yoast_Notification $notification Notification to check. + * + * @return bool + */ + private function filter_dismissed_notifications( Yoast_Notification $notification ) { + + return ! self::maybe_dismiss_notification( $notification ); + } + + /** + * Convert Notification to array representation. + * + * @since 3.2 + * + * @param Yoast_Notification $notification Notification to convert. + * + * @return array + */ + private function notification_to_array( Yoast_Notification $notification ) { + + $notification_data = $notification->to_array(); + + if ( isset( $notification_data['nonce'] ) ) { + unset( $notification_data['nonce'] ); + } + + return $notification_data; + } + + /** + * Convert stored array to Notification. + * + * @param array $notification_data Array to convert to Notification. + * + * @return Yoast_Notification + */ + private function array_to_notification( $notification_data ) { + + if ( isset( $notification_data['options']['nonce'] ) ) { + unset( $notification_data['options']['nonce'] ); + } + + if ( isset( $notification_data['message'] ) + && is_subclass_of( $notification_data['message'], Abstract_Presenter::class, false ) + ) { + $notification_data['message'] = $notification_data['message']->present(); + } + + if ( isset( $notification_data['options']['user'] ) ) { + $notification_data['options']['user_id'] = $notification_data['options']['user']->ID; + unset( $notification_data['options']['user'] ); + + $this->notifications_need_storage = true; + } + + return new Yoast_Notification( + $notification_data['message'], + $notification_data['options'], + ); + } + + /** + * Filter notifications that should not be displayed for the current user. + * + * @param Yoast_Notification $notification Notification to test. + * + * @return bool + */ + private function filter_notification_current_user( Yoast_Notification $notification ) { + return $notification->display_for_current_user(); + } + + /** + * Checks if given notification is persistent. + * + * @param Yoast_Notification $notification The notification to check. + * + * @return bool True when notification is not persistent. + */ + private function is_notification_persistent( Yoast_Notification $notification ) { + return ! $notification->is_persistent(); + } + + /** + * Queues a notification transaction for later execution if notifications are not yet set up. + * + * @param callable $callback Callback that performs the transaction. + * @param array $args Arguments to pass to the callback. + * + * @return bool True if transaction was queued, false if it can be performed immediately. + */ + private function queue_transaction( $callback, $args ) { + if ( $this->notifications_retrieved ) { + return false; + } + + $this->add_transaction_to_queue( $callback, $args ); + + return true; + } + + /** + * Adds a notification transaction to the queue for later execution. + * + * @param callable $callback Callback that performs the transaction. + * @param array $args Arguments to pass to the callback. + * + * @return void + */ + private function add_transaction_to_queue( $callback, $args ) { + $this->queued_transactions[] = [ $callback, $args ]; + } + + /** + * Removes all notifications from storage. + * + * @return bool True when notifications got removed. + */ + protected function remove_storage() { + if ( ! $this->has_stored_notifications() ) { + return false; + } + + delete_user_option( get_current_user_id(), self::STORAGE_KEY ); + return true; + } + + /** + * Checks if there are stored notifications. + * + * @return bool True when there are stored notifications. + */ + protected function has_stored_notifications() { + $stored_notifications = $this->get_stored_notifications(); + + return ! empty( $stored_notifications ); + } + + /** + * Retrieves the stored notifications. + * + * @codeCoverageIgnore + * + * @return array|false Array with notifications or false when not set. + */ + protected function get_stored_notifications() { + return get_user_option( self::STORAGE_KEY, get_current_user_id() ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notification.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notification.php new file mode 100644 index 0000000..f33adea --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notification.php @@ -0,0 +1,446 @@ + self::UPDATED, + 'id' => '', + 'user_id' => null, + 'nonce' => null, + 'priority' => 0.5, + 'data_json' => [], + 'dismissal_key' => null, + 'capabilities' => [], + 'capability_check' => self::MATCH_ALL, + 'yoast_branding' => false, + 'resolve_nonce' => '', + ]; + + /** + * The message for the notification. + * + * @var string + */ + private $message; + + /** + * Notification class constructor. + * + * @param string $message Message string. + * @param array $options Set of options. + */ + public function __construct( $message, $options = [] ) { + $this->message = $message; + $this->options = $this->normalize_options( $options ); + } + + /** + * Retrieve notification ID string. + * + * @return string + */ + public function get_id() { + return $this->options['id']; + } + + /** + * Retrieve the user to show the notification for. + * + * @deprecated 21.6 + * @codeCoverageIgnore + * + * @return WP_User|null The user to show this notification for. + */ + public function get_user() { + _deprecated_function( __METHOD__, 'Yoast SEO 21.6' ); + return null; + } + + /** + * Retrieve the id of the user to show the notification for. + * + * Returns the id of the current user if not user has been sent. + * + * @return int The user id + */ + public function get_user_id() { + return ( $this->options['user_id'] ?? get_current_user_id() ); + } + + /** + * Retrieve nonce identifier. + * + * @return string|null Nonce for this Notification. + */ + public function get_nonce() { + if ( $this->options['id'] && empty( $this->options['nonce'] ) ) { + $this->options['nonce'] = wp_create_nonce( $this->options['id'] ); + } + + return $this->options['nonce']; + } + + /** + * Make sure the nonce is up to date. + * + * @return void + */ + public function refresh_nonce() { + if ( $this->options['id'] ) { + $this->options['nonce'] = wp_create_nonce( $this->options['id'] ); + } + } + + /** + * Get the type of the notification. + * + * @return string + */ + public function get_type() { + return $this->options['type']; + } + + /** + * Priority of the notification. + * + * Relative to the type. + * + * @return float Returns the priority between 0 and 1. + */ + public function get_priority() { + return $this->options['priority']; + } + + /** + * Get the nonce to resolve the alert. + * + * @return string + */ + public function get_resolve_nonce() { + return $this->options['resolve_nonce']; + } + + /** + * Get the User Meta key to check for dismissal of notification. + * + * @return string User Meta Option key that registers dismissal. + */ + public function get_dismissal_key() { + if ( empty( $this->options['dismissal_key'] ) ) { + return $this->options['id']; + } + + return $this->options['dismissal_key']; + } + + /** + * Is this Notification persistent. + * + * @return bool True if persistent, False if fire and forget. + */ + public function is_persistent() { + $id = $this->get_id(); + + return ! empty( $id ); + } + + /** + * Check if the notification is relevant for the current user. + * + * @return bool True if a user needs to see this notification, false if not. + */ + public function display_for_current_user() { + // If the notification is for the current page only, always show. + if ( ! $this->is_persistent() ) { + return true; + } + + // If the current user doesn't match capabilities. + return $this->match_capabilities(); + } + + /** + * Does the current user match required capabilities. + * + * @return bool + */ + public function match_capabilities() { + // Super Admin can do anything. + if ( is_multisite() && is_super_admin( $this->options['user_id'] ) ) { + return true; + } + + /** + * Filter capabilities that enable the displaying of this notification. + * + * @param array $capabilities The capabilities that must be present for this notification. + * @param Yoast_Notification $notification The notification object. + * + * @return array Array of capabilities or empty for no restrictions. + * + * @since 3.2 + */ + $capabilities = apply_filters( 'wpseo_notification_capabilities', $this->options['capabilities'], $this ); + + // Should be an array. + if ( ! is_array( $capabilities ) ) { + $capabilities = (array) $capabilities; + } + + /** + * Filter capability check to enable all or any capabilities. + * + * @param string $capability_check The type of check that will be used to determine if an capability is present. + * @param Yoast_Notification $notification The notification object. + * + * @return string self::MATCH_ALL or self::MATCH_ANY. + * + * @since 3.2 + */ + $capability_check = apply_filters( 'wpseo_notification_capability_check', $this->options['capability_check'], $this ); + + if ( ! in_array( $capability_check, [ self::MATCH_ALL, self::MATCH_ANY ], true ) ) { + $capability_check = self::MATCH_ALL; + } + + if ( ! empty( $capabilities ) ) { + + $has_capabilities = array_filter( $capabilities, [ $this, 'has_capability' ] ); + + switch ( $capability_check ) { + case self::MATCH_ALL: + return $has_capabilities === $capabilities; + case self::MATCH_ANY: + return ! empty( $has_capabilities ); + } + } + + return true; + } + + /** + * Array filter function to find matched capabilities. + * + * @param string $capability Capability to test. + * + * @return bool + */ + private function has_capability( $capability ) { + $user_id = $this->options['user_id']; + if ( ! is_numeric( $user_id ) ) { + return false; + } + $user = get_user_by( 'id', $user_id ); + if ( ! $user ) { + return false; + } + + return $user->has_cap( $capability ); + } + + /** + * Return the object properties as an array. + * + * @return array + */ + public function to_array() { + return [ + 'message' => $this->message, + 'options' => $this->options, + ]; + } + + /** + * Adds string (view) behaviour to the notification. + * + * @return string + */ + public function __toString() { + return $this->render(); + } + + /** + * Renders the notification as a string. + * + * @return string The rendered notification. + */ + public function render() { + $attributes = []; + + // Default notification classes. + $classes = [ + 'yoast-notification', + ]; + + // Maintain WordPress visualisation of notifications when they are not persistent. + if ( ! $this->is_persistent() ) { + $classes[] = 'notice'; + $classes[] = $this->get_type(); + } + + if ( ! empty( $classes ) ) { + $attributes['class'] = implode( ' ', $classes ); + } + + // Combined attribute key and value into a string. + array_walk( $attributes, [ $this, 'parse_attributes' ] ); + + $message = null; + if ( $this->options['yoast_branding'] ) { + $message = $this->wrap_yoast_seo_icon( $this->message ); + } + + $message ??= wpautop( $this->message ); + + // Build the output DIV. + return '
            ' . $message . '
            ' . PHP_EOL; + } + + /** + * Get the message for the notification. + * + * @return string The message. + */ + public function get_message() { + return wpautop( $this->message ); + } + + /** + * Wraps the message with a Yoast SEO icon. + * + * @param string $message The message to wrap. + * + * @return string The wrapped message. + */ + private function wrap_yoast_seo_icon( $message ) { + $out = sprintf( + '', + esc_url( plugin_dir_url( WPSEO_FILE ) . 'packages/js/images/Yoast_SEO_Icon.svg' ), + 60, + 60, + ); + $out .= '
            '; + $out .= $message; + $out .= '
            '; + + return $out; + } + + /** + * Get the JSON if provided. + * + * @return string|false + */ + public function get_json() { + if ( empty( $this->options['data_json'] ) ) { + return ''; + } + + return WPSEO_Utils::format_json_encode( $this->options['data_json'] ); + } + + /** + * Make sure we only have values that we can work with. + * + * @param array $options Options to normalize. + * + * @return array + */ + private function normalize_options( $options ) { + $options = wp_parse_args( $options, $this->defaults ); + + // Should not exceed 0 or 1. + $options['priority'] = min( 1, max( 0, $options['priority'] ) ); + + // Set default capabilities when not supplied. + if ( empty( $options['capabilities'] ) || $options['capabilities'] === [] ) { + $options['capabilities'] = [ 'wpseo_manage_options' ]; + } + + // Set to the id of the current user if not supplied. + $options['user_id'] ??= get_current_user_id(); + + return $options; + } + + /** + * Format HTML element attributes. + * + * @param string $value Attribute value. + * @param string $key Attribute name. + * + * @return void + */ + private function parse_attributes( &$value, $key ) { + $value = sprintf( '%s="%s"', sanitize_key( $key ), esc_attr( $value ) ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notifications.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notifications.php new file mode 100644 index 0000000..87c41a8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-notifications.php @@ -0,0 +1,319 @@ +add_hooks(); + } + + /** + * Add hooks + * + * @return void + */ + private function add_hooks() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $page = sanitize_text_field( wp_unslash( $_GET['page'] ) ); + if ( $page === self::ADMIN_PAGE ) { + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] ); + } + } + + // Needed for adminbar and Notifications page. + add_action( 'admin_init', [ self::class, 'collect_notifications' ], 99 ); + + // Add AJAX hooks. + add_action( 'wp_ajax_yoast_dismiss_notification', [ $this, 'ajax_dismiss_notification' ] ); + add_action( 'wp_ajax_yoast_restore_notification', [ $this, 'ajax_restore_notification' ] ); + } + + /** + * Enqueue assets. + * + * @return void + */ + public function enqueue_assets() { + $asset_manager = new WPSEO_Admin_Asset_Manager(); + + $asset_manager->enqueue_style( 'notifications' ); + } + + /** + * Handle ajax request to dismiss a notification. + * + * @return void + */ + public function ajax_dismiss_notification() { + + $notification = $this->get_notification_from_ajax_request(); + if ( $notification ) { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->maybe_dismiss_notification( $notification ); + + $this->output_ajax_response( $notification->get_type() ); + } + + wp_die(); + } + + /** + * Handle ajax request to restore a notification. + * + * @return void + */ + public function ajax_restore_notification() { + + $notification = $this->get_notification_from_ajax_request(); + if ( $notification ) { + $notification_center = Yoast_Notification_Center::get(); + $notification_center->restore_notification( $notification ); + + $this->output_ajax_response( $notification->get_type() ); + } + + wp_die(); + } + + /** + * Create AJAX response data. + * + * @param string $type Notification type. + * + * @return void + */ + private function output_ajax_response( $type ) { + + $html = $this->get_view_html( $type ); + // phpcs:disable WordPress.Security.EscapeOutput -- Reason: WPSEO_Utils::format_json_encode is safe. + echo WPSEO_Utils::format_json_encode( + [ + 'html' => $html, + 'total' => self::get_active_notification_count(), + ], + ); + // phpcs:enable -- Reason: WPSEO_Utils::format_json_encode is safe. + } + + /** + * Get the HTML to return in the AJAX request. + * + * @param string $type Notification type. + * + * @return bool|string + */ + private function get_view_html( $type ) { + + switch ( $type ) { + case 'error': + $view = 'errors'; + break; + + case 'warning': + default: + $view = 'warnings'; + break; + } + + // Re-collect notifications. + self::collect_notifications(); + + /** + * Stops PHPStorm from nagging about this variable being unused. The variable is used in the view. + * + * @noinspection PhpUnusedLocalVariableInspection + */ + $notifications_data = self::get_template_variables(); + + ob_start(); + include WPSEO_PATH . 'admin/views/partial-notifications-' . $view . '.php'; + $html = ob_get_clean(); + + return $html; + } + + /** + * Extract the Yoast Notification from the AJAX request. + * + * This function does not handle nonce verification. + * + * @return Yoast_Notification|null A Yoast_Notification on success, null on failure. + */ + private function get_notification_from_ajax_request() { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: This function does not handle nonce verification. + if ( ! isset( $_POST['notification'] ) || ! is_string( $_POST['notification'] ) ) { + return null; + } + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: This function does not handle nonce verification. + $notification_id = sanitize_text_field( wp_unslash( $_POST['notification'] ) ); + + if ( empty( $notification_id ) ) { + return null; + } + $notification_center = Yoast_Notification_Center::get(); + return $notification_center->get_notification_by_id( $notification_id ); + } + + /** + * Collect the notifications and group them together. + * + * @return void + */ + public static function collect_notifications() { + + $notification_center = Yoast_Notification_Center::get(); + + $notifications = $notification_center->get_sorted_notifications(); + self::$notification_count = count( $notifications ); + + self::$errors = array_filter( $notifications, [ self::class, 'filter_error_notifications' ] ); + self::$dismissed_errors = array_filter( self::$errors, [ self::class, 'filter_dismissed_notifications' ] ); + self::$active_errors = array_diff( self::$errors, self::$dismissed_errors ); + + self::$warnings = array_filter( $notifications, [ self::class, 'filter_warning_notifications' ] ); + self::$dismissed_warnings = array_filter( self::$warnings, [ self::class, 'filter_dismissed_notifications' ] ); + self::$active_warnings = array_diff( self::$warnings, self::$dismissed_warnings ); + } + + /** + * Get the variables needed in the views. + * + * @return array + */ + public static function get_template_variables() { + + return [ + 'metrics' => [ + 'total' => self::$notification_count, + 'active' => self::get_active_notification_count(), + 'errors' => count( self::$errors ), + 'warnings' => count( self::$warnings ), + ], + 'errors' => [ + 'dismissed' => self::$dismissed_errors, + 'active' => self::$active_errors, + ], + 'warnings' => [ + 'dismissed' => self::$dismissed_warnings, + 'active' => self::$active_warnings, + ], + ]; + } + + /** + * Get the number of active notifications. + * + * @return int + */ + public static function get_active_notification_count() { + + return ( count( self::$active_errors ) + count( self::$active_warnings ) ); + } + + /** + * Filter out any non-errors. + * + * @param Yoast_Notification $notification Notification to test. + * + * @return bool + */ + private static function filter_error_notifications( Yoast_Notification $notification ) { + + return $notification->get_type() === 'error'; + } + + /** + * Filter out any non-warnings. + * + * @param Yoast_Notification $notification Notification to test. + * + * @return bool + */ + private static function filter_warning_notifications( Yoast_Notification $notification ) { + + return $notification->get_type() !== 'error'; + } + + /** + * Filter out any dismissed notifications. + * + * @param Yoast_Notification $notification Notification to test. + * + * @return bool + */ + private static function filter_dismissed_notifications( Yoast_Notification $notification ) { + + return Yoast_Notification_Center::is_notification_dismissed( $notification ); + } +} + +class_alias( Yoast_Notifications::class, 'Yoast_Alerts' ); diff --git a/html/wp-content/plugins/wordpress-seo/admin/class-yoast-plugin-conflict.php b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-plugin-conflict.php new file mode 100644 index 0000000..48ab13f --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/class-yoast-plugin-conflict.php @@ -0,0 +1,340 @@ +plugins the active plugins will be stored in this + * property. + * + * @var array + */ + protected $active_conflicting_plugins = []; + + /** + * Property for holding instance of itself. + * + * @var Yoast_Plugin_Conflict + */ + protected static $instance; + + /** + * For the use of singleton pattern. Create instance of itself and return this instance. + * + * @param string $class_name Give the classname to initialize. If classname is + * false (empty) it will use it's own __CLASS__. + * + * @return Yoast_Plugin_Conflict + */ + public static function get_instance( $class_name = '' ) { + + if ( self::$instance === null ) { + if ( ! is_string( $class_name ) || $class_name === '' ) { + $class_name = self::class; + } + + self::$instance = new $class_name(); + } + + return self::$instance; + } + + /** + * Setting instance, all active plugins and search for active plugins. + * + * Protected constructor to prevent creating a new instance of the + * *Singleton* via the `new` operator from outside this class. + */ + protected function __construct() { + // Set active plugins. + $this->all_active_plugins = get_option( 'active_plugins' ); + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['action'] ) && is_string( $_GET['action'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information and only comparing the variable in a condition. + $action = wp_unslash( $_GET['action'] ); + if ( $action === 'deactivate' ) { + $this->remove_deactivated_plugin(); + } + } + + // Search for active plugins. + $this->search_active_plugins(); + } + + /** + * Check if there are conflicting plugins for given $plugin_section. + * + * @param string $plugin_section Type of plugin conflict (such as Open Graph or sitemap). + * + * @return bool + */ + public function check_for_conflicts( $plugin_section ) { + + static $sections_checked; + + // Return early if there are no active conflicting plugins at all. + if ( empty( $this->active_conflicting_plugins ) ) { + return false; + } + + $sections_checked ??= []; + + if ( ! in_array( $plugin_section, $sections_checked, true ) ) { + $sections_checked[] = $plugin_section; + return ( ! empty( $this->active_conflicting_plugins[ $plugin_section ] ) ); + } + + return false; + } + + /** + * Checks for given $plugin_sections for conflicts. + * + * @param array $plugin_sections Set of sections. + * + * @return void + */ + public function check_plugin_conflicts( $plugin_sections ) { + foreach ( $plugin_sections as $plugin_section => $readable_plugin_section ) { + // Check for conflicting plugins and show error if there are conflicts. + if ( $this->check_for_conflicts( $plugin_section ) ) { + $this->set_error( $plugin_section, $readable_plugin_section ); + } + } + + // List of all active sections. + $sections = array_keys( $plugin_sections ); + // List of all sections. + $all_plugin_sections = array_keys( $this->plugins ); + + /* + * Get all sections that are inactive. + * These plugins need to be cleared. + * + * This happens when Sitemaps or OpenGraph implementations toggle active/disabled. + */ + $inactive_sections = array_diff( $all_plugin_sections, $sections ); + if ( ! empty( $inactive_sections ) ) { + foreach ( $inactive_sections as $section ) { + array_walk( $this->plugins[ $section ], [ $this, 'clear_error' ] ); + } + } + + // For active sections clear errors for inactive plugins. + foreach ( $sections as $section ) { + // By default, clear errors for all plugins of the section. + $inactive_plugins = $this->plugins[ $section ]; + + // If there are active plugins, filter them from being cleared. + if ( isset( $this->active_conflicting_plugins[ $section ] ) ) { + $inactive_plugins = array_diff( $this->plugins[ $section ], $this->active_conflicting_plugins[ $section ] ); + } + + array_walk( $inactive_plugins, [ $this, 'clear_error' ] ); + } + } + + /** + * Setting an error on the screen. + * + * @param string $plugin_section Type of conflict group (such as Open Graph or sitemap). + * @param string $readable_plugin_section This is the value for the translation. + * + * @return void + */ + protected function set_error( $plugin_section, $readable_plugin_section ) { + + $notification_center = Yoast_Notification_Center::get(); + + foreach ( $this->active_conflicting_plugins[ $plugin_section ] as $plugin_file ) { + + $plugin_name = $this->get_plugin_name( $plugin_file ); + + $error_message = ''; + /* translators: %1$s: 'Facebook & Open Graph' plugin name(s) of possibly conflicting plugin(s), %2$s to Yoast SEO */ + $error_message .= '

            ' . sprintf( __( 'The %1$s plugin might cause issues when used in conjunction with %2$s.', 'wordpress-seo' ), '' . $plugin_name . '', 'Yoast SEO' ) . '

            '; + $error_message .= '

            ' . sprintf( $readable_plugin_section, 'Yoast SEO', $plugin_name ) . '

            '; + + /* translators: %s: 'Facebook' plugin name of possibly conflicting plugin */ + $error_message .= '' . sprintf( __( 'Deactivate %s', 'wordpress-seo' ), $this->get_plugin_name( $plugin_file ) ) . ' '; + + $identifier = $this->get_notification_identifier( $plugin_file ); + + // Add the message to the notifications center. + $notification_center->add_notification( + new Yoast_Notification( + $error_message, + [ + 'type' => Yoast_Notification::ERROR, + 'id' => 'wpseo-conflict-' . $identifier, + ], + ), + ); + } + } + + /** + * Clear the notification for a plugin. + * + * @param string $plugin_file Clear the optional notification for this plugin. + * + * @return void + */ + public function clear_error( $plugin_file ) { + $identifier = $this->get_notification_identifier( $plugin_file ); + + $notification_center = Yoast_Notification_Center::get(); + $notification_center->remove_notification_by_id( 'wpseo-conflict-' . $identifier ); + } + + /** + * Loop through the $this->plugins to check if one of the plugins is active. + * + * This method will store the active plugins in $this->active_plugins. + * + * @return void + */ + protected function search_active_plugins() { + foreach ( $this->plugins as $plugin_section => $plugins ) { + $this->check_plugins_active( $plugins, $plugin_section ); + } + } + + /** + * Loop through plugins and check if each plugin is active. + * + * @param array $plugins Set of plugins. + * @param string $plugin_section Type of conflict group (such as Open Graph or sitemap). + * + * @return void + */ + protected function check_plugins_active( $plugins, $plugin_section ) { + foreach ( $plugins as $plugin ) { + if ( $this->check_plugin_is_active( $plugin ) ) { + $this->add_active_plugin( $plugin_section, $plugin ); + } + } + } + + /** + * Check if given plugin exists in array with all_active_plugins. + * + * @param string $plugin Plugin basename string. + * + * @return bool + */ + protected function check_plugin_is_active( $plugin ) { + return in_array( $plugin, $this->all_active_plugins, true ); + } + + /** + * Add plugin to the list of active plugins. + * + * This method will check first if key $plugin_section exists, if not it will create an empty array + * If $plugin itself doesn't exist it will be added. + * + * @param string $plugin_section Type of conflict group (such as Open Graph or sitemap). + * @param string $plugin Plugin basename string. + * + * @return void + */ + protected function add_active_plugin( $plugin_section, $plugin ) { + if ( ! array_key_exists( $plugin_section, $this->active_conflicting_plugins ) ) { + $this->active_conflicting_plugins[ $plugin_section ] = []; + } + + if ( ! in_array( $plugin, $this->active_conflicting_plugins[ $plugin_section ], true ) ) { + $this->active_conflicting_plugins[ $plugin_section ][] = $plugin; + } + } + + /** + * Search in $this->plugins for the given $plugin. + * + * If there is a result it will return the plugin category. + * + * @param string $plugin Plugin basename string. + * + * @return int|string + */ + protected function find_plugin_category( $plugin ) { + foreach ( $this->plugins as $plugin_section => $plugins ) { + if ( in_array( $plugin, $plugins, true ) ) { + return $plugin_section; + } + } + } + + /** + * Get plugin name from file. + * + * @param string $plugin Plugin path relative to plugins directory. + * + * @return string|bool Plugin name or false when no name is set. + */ + protected function get_plugin_name( $plugin ) { + $plugin_details = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + + if ( $plugin_details['Name'] !== '' ) { + return $plugin_details['Name']; + } + + return false; + } + + /** + * When being in the deactivation process the currently deactivated plugin has to be removed. + * + * @return void + */ + private function remove_deactivated_plugin() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: On the deactivation screen the nonce is already checked by WordPress itself. + if ( ! isset( $_GET['plugin'] ) || ! is_string( $_GET['plugin'] ) ) { + return; + } + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: On the deactivation screen the nonce is already checked by WordPress itself. + $deactivated_plugin = sanitize_text_field( wp_unslash( $_GET['plugin'] ) ); + $key_to_remove = array_search( $deactivated_plugin, $this->all_active_plugins, true ); + + if ( $key_to_remove !== false ) { + unset( $this->all_active_plugins[ $key_to_remove ] ); + } + } + + /** + * Get the identifier from the plugin file. + * + * @param string $plugin_file Plugin file to get Identifier from. + * + * @return string + */ + private function get_notification_identifier( $plugin_file ) { + return md5( $plugin_file ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint-file-size.php b/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint-file-size.php new file mode 100644 index 0000000..9f2bec0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint-file-size.php @@ -0,0 +1,85 @@ +service = $service; + } + + /** + * Registers the routes for the endpoints. + * + * @return void + */ + public function register() { + $route_args = [ + 'methods' => 'GET', + 'args' => [ + 'url' => [ + 'required' => true, + 'type' => 'string', + 'description' => 'The url to retrieve', + ], + ], + 'callback' => [ + $this->service, + 'get', + ], + 'permission_callback' => [ + $this, + 'can_retrieve_data', + ], + ]; + register_rest_route( self::REST_NAMESPACE, self::ENDPOINT_SINGULAR, $route_args ); + } + + /** + * Determines whether or not data can be retrieved for the registered endpoints. + * + * @return bool Whether or not data can be retrieved. + */ + public function can_retrieve_data() { + return current_user_can( self::CAPABILITY_RETRIEVE ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint-statistics.php b/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint-statistics.php new file mode 100644 index 0000000..392d1c1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint-statistics.php @@ -0,0 +1,73 @@ +service = $service; + } + + /** + * Registers the REST routes that are available on the endpoint. + * + * @return void + */ + public function register() { + // Register fetch config. + $route_args = [ + 'methods' => 'GET', + 'callback' => [ $this->service, 'get_statistics' ], + 'permission_callback' => [ $this, 'can_retrieve_data' ], + ]; + register_rest_route( self::REST_NAMESPACE, self::ENDPOINT_RETRIEVE, $route_args ); + } + + /** + * Determines whether or not data can be retrieved for the registered endpoints. + * + * @return bool Whether or not data can be retrieved. + */ + public function can_retrieve_data() { + return current_user_can( self::CAPABILITY_RETRIEVE ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint.php b/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint.php new file mode 100644 index 0000000..abbc9d0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/endpoints/class-endpoint.php @@ -0,0 +1,26 @@ +is_filter_active() ) { + add_action( 'restrict_manage_posts', [ $this, 'render_hidden_input' ] ); + } + + if ( $this->is_filter_active() ) { + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_explanation_assets' ] ); + } + } + + /** + * Adds the filter links to the view_edit screens to give the user a filter link. + * + * @return void + */ + public function add_filter_links() { + foreach ( $this->get_post_types() as $post_type ) { + add_filter( 'views_edit-' . $post_type, [ $this, 'add_filter_link' ] ); + } + } + + /** + * Enqueues the necessary assets to display a filter explanation. + * + * @return void + */ + public function enqueue_explanation_assets() { + $explanation = $this->get_explanation(); + + if ( $explanation === null ) { + return; + } + + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_script( 'filter-explanation' ); + $asset_manager->enqueue_style( 'filter-explanation' ); + $asset_manager->localize_script( + 'filter-explanation', + 'yoastFilterExplanation', + [ 'text' => $explanation ], + ); + } + + /** + * Adds a filter link to the views. + * + * @param array $views Array with the views. + * + * @return array Array of views including the added view. + */ + public function add_filter_link( $views ) { + $views[ 'yoast_' . $this->get_query_val() ] = sprintf( + '%3$s (%4$s)', + esc_url( $this->get_filter_url() ), + ( $this->is_filter_active() ) ? ' class="current" aria-current="page"' : '', + $this->get_label(), + $this->get_post_total(), + ); + + return $views; + } + + /** + * Returns a text explaining this filter. Null if no explanation is necessary. + * + * @return string|null The explanation or null. + */ + protected function get_explanation() { + return null; + } + + /** + * Renders a hidden input to preserve this filter's state when using sub-filters. + * + * @return void + */ + public function render_hidden_input() { + echo ''; + } + + /** + * Returns an url to edit.php with post_type and this filter as the query arguments. + * + * @return string The url to activate this filter. + */ + protected function get_filter_url() { + $query_args = [ + self::FILTER_QUERY_ARG => $this->get_query_val(), + 'post_type' => $this->get_current_post_type(), + ]; + + return add_query_arg( $query_args, 'edit.php' ); + } + + /** + * Returns true when the filter is active. + * + * @return bool Whether the filter is active. + */ + protected function is_filter_active() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET[ self::FILTER_QUERY_ARG ] ) && is_string( $_GET[ self::FILTER_QUERY_ARG ] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET[ self::FILTER_QUERY_ARG ] ) ) === $this->get_query_val(); + } + return false; + } + + /** + * Returns the current post type. + * + * @return string The current post type. + */ + protected function get_current_post_type() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['post_type'] ) && is_string( $_GET['post_type'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $post_type = sanitize_text_field( wp_unslash( $_GET['post_type'] ) ); + if ( ! empty( $post_type ) ) { + return $post_type; + } + } + return 'post'; + } + + /** + * Returns the post types to which this filter should be added. + * + * @return array The post types to which this filter should be added. + */ + protected function get_post_types() { + return WPSEO_Post_Type::get_accessible_post_types(); + } + + /** + * Checks if the post type is supported. + * + * @param string $post_type Post type to check against. + * + * @return bool True when it is supported. + */ + protected function is_supported_post_type( $post_type ) { + return in_array( $post_type, $this->get_post_types(), true ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/filters/class-cornerstone-filter.php b/html/wp-content/plugins/wordpress-seo/admin/filters/class-cornerstone-filter.php new file mode 100644 index 0000000..f57b658 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/filters/class-cornerstone-filter.php @@ -0,0 +1,150 @@ +is_filter_active() ) { + global $wpdb; + + $where .= $wpdb->prepare( + " AND {$wpdb->posts}.ID IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = '1' ) ", + WPSEO_Meta::$meta_prefix . self::META_NAME, + ); + } + + return $where; + } + + /** + * Filters the post types that have the metabox disabled. + * + * @param array $post_types The post types to filter. + * + * @return array The filtered post types. + */ + public function filter_metabox_disabled( $post_types ) { + $filtered_post_types = []; + foreach ( $post_types as $post_type_key => $post_type ) { + if ( ! WPSEO_Post_Type::has_metabox_enabled( $post_type_key ) ) { + continue; + } + + $filtered_post_types[ $post_type_key ] = $post_type; + } + + return $filtered_post_types; + } + + /** + * Returns the label for this filter. + * + * @return string The label for this filter. + */ + protected function get_label() { + return __( 'Cornerstone content', 'wordpress-seo' ); + } + + /** + * Returns a text explaining this filter. + * + * @return string|null The explanation. + */ + protected function get_explanation() { + $post_type_object = get_post_type_object( $this->get_current_post_type() ); + + if ( $post_type_object === null ) { + return null; + } + + return sprintf( + /* translators: %1$s expands to the posttype label, %2$s expands anchor to blog post about cornerstone content, %3$s expands to */ + __( 'Mark the most important %1$s as \'cornerstone content\' to improve your site structure. %2$sLearn more about cornerstone content%3$s.', 'wordpress-seo' ), + strtolower( $post_type_object->labels->name ), + '', + '', + ); + } + + /** + * Returns the total amount of articles marked as cornerstone content. + * + * @return int + */ + protected function get_post_total() { + global $wpdb; + + return (int) $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT( 1 ) + FROM {$wpdb->postmeta} + WHERE post_id IN( SELECT ID FROM {$wpdb->posts} WHERE post_type = %s ) AND + meta_key = %s AND meta_value = '1' + ", + $this->get_current_post_type(), + WPSEO_Meta::$meta_prefix . self::META_NAME, + ), + ); + } + + /** + * Returns the post types to which this filter should be added. + * + * @return array The post types to which this filter should be added. + */ + protected function get_post_types() { + /** + * Filter: 'wpseo_cornerstone_post_types' - Filters post types to exclude the cornerstone feature for. + * + * @param array $post_types The accessible post types to filter. + */ + $post_types = apply_filters( 'wpseo_cornerstone_post_types', parent::get_post_types() ); + if ( ! is_array( $post_types ) ) { + return []; + } + + return $post_types; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/formatter/class-metabox-formatter.php b/html/wp-content/plugins/wordpress-seo/admin/formatter/class-metabox-formatter.php new file mode 100644 index 0000000..0a765c2 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/formatter/class-metabox-formatter.php @@ -0,0 +1,81 @@ +formatter = $formatter; + } + + /** + * Returns the values. + * + * @return array|bool|int> + */ + public function get_values() { + $defaults = $this->get_defaults(); + $values = $this->formatter->get_values(); + + return ( $values + $defaults ); + } + + /** + * Returns array with all the values always needed by a scraper object. + * + * @return array|bool|int> Default settings for the metabox. + */ + private function get_defaults() { + $schema_types = new Schema_Types(); + + $defaults = [ + 'author_name' => get_the_author_meta( 'display_name' ), + 'keyword_usage' => [], + 'title_template' => '', + 'metadesc_template' => '', + 'schema' => [ + 'displayFooter' => WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ), + 'pageTypeOptions' => $schema_types->get_page_type_options(), + 'articleTypeOptions' => $schema_types->get_article_type_options(), + ], + 'twitterCardType' => 'summary_large_image', + /** + * Filter to determine if the markers should be enabled or not. + * + * @param bool $showMarkers Should the markers being enabled. Default = true. + */ + 'show_markers' => apply_filters( 'wpseo_enable_assessment_markers', true ), + ]; + + $integration_information_repo = YoastSEO()->classes->get( Integration_Information_Repository::class ); + + $enabled_integrations = $integration_information_repo->get_integration_information(); + $defaults = array_merge( $defaults, $enabled_integrations ); + $enabled_features_repo = YoastSEO()->classes->get( Enabled_Analysis_Features_Repository::class ); + + $enabled_features = $enabled_features_repo->get_enabled_features()->parse_to_legacy_array(); + return array_merge( $defaults, $enabled_features ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/formatter/class-post-metabox-formatter.php b/html/wp-content/plugins/wordpress-seo/admin/formatter/class-post-metabox-formatter.php new file mode 100644 index 0000000..909876d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/formatter/class-post-metabox-formatter.php @@ -0,0 +1,95 @@ +post = $post; + $this->permalink = $structure; + } + + /** + * Determines whether the social templates should be used. + * + * @deprecated 23.1 + * @codeCoverageIgnore + * + * @return void + */ + public function use_social_templates() { + _deprecated_function( __METHOD__, 'Yoast SEO 23.1' ); + } + + /** + * Returns the translated values. + * + * @return array + */ + public function get_values() { + + $values = [ + 'metaDescriptionDate' => '', + ]; + + if ( $this->post instanceof WP_Post ) { + + /** @var Post_Seo_Information_Repository $repo */ + $repo = YoastSEO()->classes->get( Post_Seo_Information_Repository::class ); + $repo->set_post( $this->post ); + + $values_to_set = [ + 'isInsightsEnabled' => $this->is_insights_enabled(), + ]; + + $values = ( $values_to_set + $values ); + $values = ( $repo->get_seo_data() + $values ); + } + + /** + * Filter: 'wpseo_post_edit_values' - Allows changing the values Yoast SEO uses inside the post editor. + * + * @param array $values The key-value map Yoast SEO uses inside the post editor. + * @param WP_Post $post The post opened in the editor. + */ + return apply_filters( 'wpseo_post_edit_values', $values, $this->post ); + } + + /** + * Determines whether the insights feature is enabled for this post. + * + * @return bool + */ + protected function is_insights_enabled() { + return WPSEO_Options::get( 'enable_metabox_insights', false ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/formatter/class-term-metabox-formatter.php b/html/wp-content/plugins/wordpress-seo/admin/formatter/class-term-metabox-formatter.php new file mode 100644 index 0000000..29218d3 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/formatter/class-term-metabox-formatter.php @@ -0,0 +1,98 @@ +taxonomy = $taxonomy; + $this->term = $term; + + $this->use_social_templates = $this->use_social_templates(); + } + + /** + * Determines whether the social templates should be used. + * + * @return bool Whether the social templates should be used. + */ + public function use_social_templates() { + return WPSEO_Options::get( 'opengraph', false ) === true; + } + + /** + * Returns the translated values. + * + * @return array + */ + public function get_values() { + $values = []; + + // Todo: a column needs to be added on the termpages to add a filter for the keyword, so this can be used in the focus keyphrase doubles. + if ( is_object( $this->term ) && property_exists( $this->term, 'taxonomy' ) ) { + $values = [ + 'taxonomy' => $this->term->taxonomy, + 'semrushIntegrationActive' => 0, + 'wincherIntegrationActive' => 0, + 'isInsightsEnabled' => $this->is_insights_enabled(), + ]; + + $repo = YoastSEO()->classes->get( Term_Seo_Information_Repository::class ); + $repo->set_term( $this->term ); + $values = ( $repo->get_seo_data() + $values ); + } + + return $values; + } + + /** + * Determines whether the insights feature is enabled for this taxonomy. + * + * @return bool + */ + protected function is_insights_enabled() { + return WPSEO_Options::get( 'enable_metabox_insights', false ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/formatter/interface-metabox-formatter.php b/html/wp-content/plugins/wordpress-seo/admin/formatter/interface-metabox-formatter.php new file mode 100644 index 0000000..8c22048 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/formatter/interface-metabox-formatter.php @@ -0,0 +1,19 @@ +admin_header( false, 'wpseo-gsc', false, 'yoast_wpseo_gsc_options' ); + +// GSC Error notification. +$gsc_url = 'https://search.google.com/search-console/index'; +$gsc_post_url = 'https://yoa.st/google-search-console-deprecated'; +$gsc_style_alert = ' + display: flex; + align-items: baseline; + position: relative; + padding: 16px; + border: 1px solid rgba(0, 0, 0, 0.2); + font-size: 14px; + font-weight: 400; + line-height: 1.5; + margin: 16px 0; + color: #450c11; + background: #f8d7da; +'; +$gsc_style_alert_icon = 'display: block; margin-right: 8px;'; +$gsc_style_alert_content = 'max-width: 600px;'; +$gsc_style_alert_link = 'color: #004973;'; +$gsc_notification = sprintf( + /* Translators: %1$s: expands to opening anchor tag, %2$s expands to closing anchor tag. */ + __( 'Google has discontinued its Crawl Errors API. Therefore, any possible crawl errors you might have cannot be displayed here anymore. %1$sRead our statement on this for further information%2$s.', 'wordpress-seo' ), + '', + WPSEO_Admin_Utils::get_new_tab_message() . '', +); +$gsc_notification .= '

            '; +$gsc_notification .= sprintf( + /* Translators: %1$s: expands to opening anchor tag, %2$s expands to closing anchor tag. */ + __( 'To view your current crawl errors, %1$splease visit Google Search Console%2$s.', 'wordpress-seo' ), + '', + WPSEO_Admin_Utils::get_new_tab_message() . '', +); +?> +
            + + + + +
            +'; +printf( + /* Translators: %s: expands to Yoast SEO Premium */ + esc_html__( 'Creating redirects is a %s feature', 'wordpress-seo' ), + 'Yoast SEO Premium', +); +echo ''; +echo '

            '; +printf( + /* Translators: %1$s: expands to 'Yoast SEO Premium', %2$s: links to Yoast SEO Premium plugin page. */ + esc_html__( 'To be able to create a redirect and fix this issue, you need %1$s. You can buy the plugin, including one year of support and updates, on %2$s.', 'wordpress-seo' ), + 'Yoast SEO Premium', + 'yoast.com', +); +echo '

            '; +echo ''; diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/class-import-detector.php b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-detector.php new file mode 100644 index 0000000..48d31cc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-detector.php @@ -0,0 +1,36 @@ +status->status ) { + $this->needs_import[ $importer_class ] = $importer->get_plugin_name(); + } + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/class-import-plugin.php b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-plugin.php new file mode 100644 index 0000000..d71fff8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-plugin.php @@ -0,0 +1,63 @@ +importer = $importer; + + switch ( $action ) { + case 'cleanup': + $this->status = $this->importer->run_cleanup(); + break; + case 'import': + $this->status = $this->importer->run_import(); + break; + case 'detect': + default: + $this->status = $this->importer->run_detect(); + } + + $this->status->set_msg( $this->complete_msg( $this->status->get_msg() ) ); + } + + /** + * Convenience function to replace %s with plugin name in import message. + * + * @param string $msg Message string. + * + * @return string Returns message with plugin name instead of replacement variables. + */ + protected function complete_msg( $msg ) { + return sprintf( $msg, $this->importer->get_plugin_name() ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/class-import-settings.php b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-settings.php new file mode 100644 index 0000000..3bec4c8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-settings.php @@ -0,0 +1,127 @@ +status = new WPSEO_Import_Status( 'import', false ); + } + + /** + * Imports the data submitted by the user. + * + * @return void + */ + public function import() { + check_admin_referer( self::NONCE_ACTION ); + + if ( ! WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ) { + return; + } + + if ( ! isset( $_POST['settings_import'] ) || ! is_string( $_POST['settings_import'] ) ) { + return; + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: The raw content will be parsed afterwards. + $content = wp_unslash( $_POST['settings_import'] ); + + if ( empty( $content ) ) { + return; + } + + $this->parse_options( $content ); + } + + /** + * Parse the options. + * + * @param string $raw_options The content to parse. + * + * @return void + */ + protected function parse_options( $raw_options ) { + $options = parse_ini_string( $raw_options, true, INI_SCANNER_RAW ); + + if ( is_array( $options ) && $options !== [] ) { + $this->import_options( $options ); + + return; + } + + $this->status->set_msg( __( 'Settings could not be imported:', 'wordpress-seo' ) . ' ' . __( 'No settings found.', 'wordpress-seo' ) ); + } + + /** + * Parse the option group and import it. + * + * @param string $name Name string. + * @param array $option_group Option group data. + * @param array $options Options data. + * + * @return void + */ + protected function parse_option_group( $name, $option_group, $options ) { + // Make sure that the imported options are cleaned/converted on import. + $option_instance = WPSEO_Options::get_option_instance( $name ); + if ( is_object( $option_instance ) && method_exists( $option_instance, 'import' ) ) { + $option_instance->import( $option_group, $this->old_wpseo_version, $options ); + } + } + + /** + * Imports the options if found. + * + * @param array $options The options parsed from the provided settings. + * + * @return void + */ + protected function import_options( $options ) { + if ( isset( $options['wpseo']['version'] ) && $options['wpseo']['version'] !== '' ) { + $this->old_wpseo_version = $options['wpseo']['version']; + } + + foreach ( $options as $name => $option_group ) { + $this->parse_option_group( $name, $option_group, $options ); + } + + $this->status->set_msg( __( 'Settings successfully imported.', 'wordpress-seo' ) ); + $this->status->set_status( true ); + + // Reset the cached option values. + WPSEO_Options::clear_cache(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/class-import-status.php b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-status.php new file mode 100644 index 0000000..c105d4a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/class-import-status.php @@ -0,0 +1,131 @@ +action = $action; + $this->status = $status; + $this->msg = $msg; + } + + /** + * Get the import message. + * + * @return string Message about current status. + */ + public function get_msg() { + if ( $this->msg !== '' ) { + return $this->msg; + } + + if ( $this->status === false ) { + /* translators: %s is replaced with the name of the plugin we're trying to find data from. */ + return __( '%s data not found.', 'wordpress-seo' ); + } + + return $this->get_default_success_message(); + } + + /** + * Get the import action. + * + * @return string Import action type. + */ + public function get_action() { + return $this->action; + } + + /** + * Set the import action, set status to false. + * + * @param string $action The type of action to set as import action. + * + * @return void + */ + public function set_action( $action ) { + $this->action = $action; + $this->status = false; + } + + /** + * Sets the importer status message. + * + * @param string $msg The message to set. + * + * @return void + */ + public function set_msg( $msg ) { + $this->msg = $msg; + } + + /** + * Sets the importer status. + * + * @param bool $status The status to set. + * + * @return WPSEO_Import_Status The current object. + */ + public function set_status( $status ) { + $this->status = (bool) $status; + + return $this; + } + + /** + * Returns a success message depending on the action. + * + * @return string Returns a success message for the current action. + */ + private function get_default_success_message() { + switch ( $this->action ) { + case 'import': + /* translators: %s is replaced with the name of the plugin we're importing data from. */ + return __( '%s data successfully imported.', 'wordpress-seo' ); + case 'cleanup': + /* translators: %s is replaced with the name of the plugin we're removing data from. */ + return __( '%s data successfully removed.', 'wordpress-seo' ); + case 'detect': + default: + /* translators: %s is replaced with the name of the plugin we've found data from. */ + return __( '%s data found.', 'wordpress-seo' ); + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-abstract-plugin-importer.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-abstract-plugin-importer.php new file mode 100644 index 0000000..03b1b65 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-abstract-plugin-importer.php @@ -0,0 +1,329 @@ +plugin_name; + } + + /** + * Imports the settings and post meta data from another SEO plugin. + * + * @return WPSEO_Import_Status Import status object. + */ + public function run_import() { + $this->status = new WPSEO_Import_Status( 'import', false ); + + if ( ! $this->detect() ) { + return $this->status; + } + + $this->status->set_status( $this->import() ); + + // Flush the entire cache, as we no longer know what's valid and what's not. + wp_cache_flush(); + + return $this->status; + } + + /** + * Handles post meta data to import. + * + * @return bool Import success status. + */ + protected function import() { + return $this->meta_keys_clone( $this->clone_keys ); + } + + /** + * Removes the plugin data from the database. + * + * @return WPSEO_Import_Status Import status object. + */ + public function run_cleanup() { + $this->status = new WPSEO_Import_Status( 'cleanup', false ); + + if ( ! $this->detect() ) { + return $this->status; + } + + return $this->status->set_status( $this->cleanup() ); + } + + /** + * Removes the plugin data from the database. + * + * @return bool Cleanup status. + */ + protected function cleanup() { + global $wpdb; + if ( empty( $this->meta_key ) ) { + return true; + } + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE %s", + $this->meta_key, + ), + ); + $result = $wpdb->__get( 'result' ); + if ( ! $result ) { + $this->cleanup_error_msg(); + } + + return $result; + } + + /** + * Sets the status message for when a cleanup has gone bad. + * + * @return void + */ + protected function cleanup_error_msg() { + /* translators: %s is replaced with the plugin's name. */ + $this->status->set_msg( sprintf( __( 'Cleanup of %s data failed.', 'wordpress-seo' ), $this->plugin_name ) ); + } + + /** + * Detects whether an import for this plugin is needed. + * + * @return WPSEO_Import_Status Import status object. + */ + public function run_detect() { + $this->status = new WPSEO_Import_Status( 'detect', false ); + + if ( ! $this->detect() ) { + return $this->status; + } + + return $this->status->set_status( true ); + } + + /** + * Detects whether there is post meta data to import. + * + * @return bool Boolean indicating whether there is something to import. + */ + protected function detect() { + global $wpdb; + + $meta_keys = wp_list_pluck( $this->clone_keys, 'old_key' ); + $result = $wpdb->get_var( + $wpdb->prepare( + "SELECT COUNT(*) AS `count` + FROM {$wpdb->postmeta} + WHERE meta_key IN ( " . implode( ', ', array_fill( 0, count( $meta_keys ), '%s' ) ) . ' )', + $meta_keys, + ), + ); + + if ( $result === '0' ) { + return false; + } + + return true; + } + + /** + * Helper function to clone meta keys and (optionally) change their values in bulk. + * + * @param string $old_key The existing meta key. + * @param string $new_key The new meta key. + * @param array $replace_values An array, keys old value, values new values. + * + * @return bool Clone status. + */ + protected function meta_key_clone( $old_key, $new_key, $replace_values = [] ) { + global $wpdb; + + // First we create a temp table with all the values for meta_key. + $result = $wpdb->query( + $wpdb->prepare( + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- This is intentional + temporary. + "CREATE TEMPORARY TABLE tmp_meta_table SELECT * FROM {$wpdb->postmeta} WHERE meta_key = %s", + $old_key, + ), + ); + if ( $result === false ) { + $this->set_missing_db_rights_status(); + return false; + } + + // Delete all the values in our temp table for posts that already have data for $new_key. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM tmp_meta_table WHERE post_id IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s )", + WPSEO_Meta::$meta_prefix . $new_key, + ), + ); + + /* + * We set meta_id to NULL so on re-insert into the postmeta table, MYSQL can set + * new meta_id's and we don't get duplicates. + */ + $wpdb->query( 'UPDATE tmp_meta_table SET meta_id = NULL' ); + + // Now we rename the meta_key. + $wpdb->query( + $wpdb->prepare( + 'UPDATE tmp_meta_table SET meta_key = %s', + WPSEO_Meta::$meta_prefix . $new_key, + ), + ); + + $this->meta_key_clone_replace( $replace_values ); + + // With everything done, we insert all our newly cloned lines into the postmeta table. + $wpdb->query( "INSERT INTO {$wpdb->postmeta} SELECT * FROM tmp_meta_table" ); + + // Now we drop our temporary table. + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange -- This is intentional + a temporary table. + $wpdb->query( 'DROP TEMPORARY TABLE IF EXISTS tmp_meta_table' ); + + return true; + } + + /** + * Clones multiple meta keys. + * + * @param array $clone_keys The keys to clone. + * + * @return bool Success status. + */ + protected function meta_keys_clone( $clone_keys ) { + foreach ( $clone_keys as $clone_key ) { + $result = $this->meta_key_clone( $clone_key['old_key'], $clone_key['new_key'], ( $clone_key['convert'] ?? [] ) ); + if ( ! $result ) { + return false; + } + } + return true; + } + + /** + * Sets the import status to false and returns a message about why it failed. + * + * @return void + */ + protected function set_missing_db_rights_status() { + $this->status->set_status( false ); + /* translators: %s is replaced with Yoast SEO. */ + $this->status->set_msg( sprintf( __( 'The %s importer functionality uses temporary database tables. It seems your WordPress install does not have the capability to do this, please consult your hosting provider.', 'wordpress-seo' ), 'Yoast SEO' ) ); + } + + /** + * Helper function to search for a key in an array and maybe save it as a meta field. + * + * @param string $plugin_key The key in the $data array to check. + * @param string $yoast_key The identifier we use in our meta settings. + * @param array $data The array of data for this post to sift through. + * @param int $post_id The post ID. + * + * @return void + */ + protected function import_meta_helper( $plugin_key, $yoast_key, $data, $post_id ) { + if ( ! empty( $data[ $plugin_key ] ) ) { + $this->maybe_save_post_meta( $yoast_key, $data[ $plugin_key ], $post_id ); + } + } + + /** + * Saves a post meta value if it doesn't already exist. + * + * @param string $new_key The key to save. + * @param mixed $value The value to set the key to. + * @param int $post_id The Post to save the meta for. + * + * @return void + */ + protected function maybe_save_post_meta( $new_key, $value, $post_id ) { + // Big. Fat. Sigh. Mostly used for _yst_is_cornerstone, but might be useful for other hidden meta's. + $key = WPSEO_Meta::$meta_prefix . $new_key; + $wpseo_meta = true; + if ( substr( $new_key, 0, 1 ) === '_' ) { + $key = $new_key; + $wpseo_meta = false; + } + + $existing_value = get_post_meta( $post_id, $key, true ); + if ( empty( $existing_value ) ) { + if ( $wpseo_meta ) { + WPSEO_Meta::set_value( $new_key, $value, $post_id ); + return; + } + update_post_meta( $post_id, $new_key, $value ); + } + } + + /** + * Replaces values in our temporary table according to our settings. + * + * @param array $replace_values Key value pair of values to replace with other values. + * + * @return void + */ + protected function meta_key_clone_replace( $replace_values ) { + global $wpdb; + + // Now we replace values if needed. + if ( is_array( $replace_values ) && $replace_values !== [] ) { + foreach ( $replace_values as $old_value => $new_value ) { + $wpdb->query( + $wpdb->prepare( + 'UPDATE tmp_meta_table SET meta_value = %s WHERE meta_value = %s', + $new_value, + $old_value, + ), + ); + } + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-aioseo-v4.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-aioseo-v4.php new file mode 100644 index 0000000..5aa7658 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-aioseo-v4.php @@ -0,0 +1,241 @@ + '_aioseo_title', + 'new_key' => 'title', + ], + [ + 'old_key' => '_aioseo_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_aioseo_og_title', + 'new_key' => 'opengraph-title', + ], + [ + 'old_key' => '_aioseo_og_description', + 'new_key' => 'opengraph-description', + ], + [ + 'old_key' => '_aioseo_twitter_title', + 'new_key' => 'twitter-title', + ], + [ + 'old_key' => '_aioseo_twitter_description', + 'new_key' => 'twitter-description', + ], + ]; + + /** + * Mapping between the AiOSEO replace vars and the Yoast replace vars. + * + * @see https://yoast.com/help/list-available-snippet-variables-yoast-seo/ + * + * @var array + */ + protected $replace_vars = [ + // They key is the AiOSEO replace var, the value is the Yoast replace var (see class-wpseo-replace-vars). + '#author_first_name' => '%%author_first_name%%', + '#author_last_name' => '%%author_last_name%%', + '#author_name' => '%%name%%', + '#categories' => '%%category%%', + '#current_date' => '%%currentdate%%', + '#current_day' => '%%currentday%%', + '#current_month' => '%%currentmonth%%', + '#current_year' => '%%currentyear%%', + '#permalink' => '%%permalink%%', + '#post_content' => '%%post_content%%', + '#post_date' => '%%date%%', + '#post_day' => '%%post_day%%', + '#post_month' => '%%post_month%%', + '#post_title' => '%%title%%', + '#post_year' => '%%post_year%%', + '#post_excerpt_only' => '%%excerpt_only%%', + '#post_excerpt' => '%%excerpt%%', + '#separator_sa' => '%%sep%%', + '#site_title' => '%%sitename%%', + '#tagline' => '%%sitedesc%%', + '#taxonomy_title' => '%%category_title%%', + ]; + + /** + * Replaces the AiOSEO variables in our temporary table with Yoast variables (replace vars). + * + * @param array $replace_values Key value pair of values to replace with other values. This is only used in the base class but not here. + * That is because this class doesn't have any `convert` keys in `$clone_keys`. + * For that reason, we're overwriting the base class' `meta_key_clone_replace()` function without executing that base functionality. + * + * @return void + */ + protected function meta_key_clone_replace( $replace_values ) { + global $wpdb; + + // At this point we're already looping through all the $clone_keys (this happens in meta_keys_clone() in the abstract class). + // Now, we'll also loop through the replace_vars array, which holds the mappings between the AiOSEO variables and the Yoast variables. + // We'll replace all the AiOSEO variables in the temporary table with their Yoast equivalents. + foreach ( $this->replace_vars as $aioseo_variable => $yoast_variable ) { + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: We need this query and this is done at many other places as well, for example class-import-rankmath. + $wpdb->query( + $wpdb->prepare( + 'UPDATE tmp_meta_table SET meta_value = REPLACE( meta_value, %s, %s )', + $aioseo_variable, + $yoast_variable, + ), + ); + } + + // The AiOSEO custom fields take the form of `#custom_field-myfield`. + // These should be mapped to %%cf_myfield%%. + $meta_values_with_custom_fields = $this->get_meta_values_with_custom_field_or_taxonomy( $wpdb, 'custom_field' ); + $unique_custom_fields = $this->get_unique_custom_fields_or_taxonomies( $meta_values_with_custom_fields, 'custom_field' ); + $this->replace_custom_field_or_taxonomy_replace_vars( $unique_custom_fields, $wpdb, 'custom_field', 'cf' ); + + // Map `#tax_name-{tax-slug}` to `%%ct_{tax-slug}%%``. + $meta_values_with_custom_taxonomies = $this->get_meta_values_with_custom_field_or_taxonomy( $wpdb, 'tax_name' ); + $unique_custom_taxonomies = $this->get_unique_custom_fields_or_taxonomies( $meta_values_with_custom_taxonomies, 'tax_name' ); + $this->replace_custom_field_or_taxonomy_replace_vars( $unique_custom_taxonomies, $wpdb, 'tax_name', 'ct' ); + } + + /** + * Filters out all unique custom fields/taxonomies/etc. used in an AiOSEO replace var. + * + * @param string[] $meta_values An array of all the meta values that + * contain one or more AIOSEO custom field replace vars + * (in the form `#custom_field-xyz`). + * @param string $aioseo_prefix The AiOSEO prefix to use + * (e.g. `custom-field` for custom fields or `tax_name` for custom taxonomies). + * + * @return string[] An array of all the unique custom fields/taxonomies/etc. used in the replace vars. + * E.g. `xyz` in the above example. + */ + protected function get_unique_custom_fields_or_taxonomies( $meta_values, $aioseo_prefix ) { + $unique_custom_fields_or_taxonomies = []; + + foreach ( $meta_values as $meta_value ) { + // Find all custom field replace vars, store them in `$matches`. + preg_match_all( + "/#$aioseo_prefix-([\w-]+)/", + $meta_value, + $matches, + ); + + /* + * `$matches[1]` contain the captured matches of the + * first capturing group (the `([\w-]+)` in the regex above). + */ + $custom_fields_or_taxonomies = $matches[1]; + + foreach ( $custom_fields_or_taxonomies as $custom_field_or_taxonomy ) { + $unique_custom_fields_or_taxonomies[ trim( $custom_field_or_taxonomy ) ] = 1; + } + } + + return array_keys( $unique_custom_fields_or_taxonomies ); + } + + /** + * Replaces every AIOSEO custom field/taxonomy/etc. replace var with the Yoast version. + * + * E.g. `#custom_field-xyz` becomes `%%cf_xyz%%`. + * + * @param string[] $unique_custom_fields_or_taxonomies An array of unique custom fields to replace the replace vars of. + * @param wpdb $wpdb The WordPress database object. + * @param string $aioseo_prefix The AiOSEO prefix to use + * (e.g. `custom-field` for custom fields or `tax_name` for custom taxonomies). + * @param string $yoast_prefix The Yoast prefix to use (e.g. `cf` for custom fields). + * + * @return void + */ + protected function replace_custom_field_or_taxonomy_replace_vars( $unique_custom_fields_or_taxonomies, $wpdb, $aioseo_prefix, $yoast_prefix ) { + foreach ( $unique_custom_fields_or_taxonomies as $unique_custom_field_or_taxonomy ) { + $aioseo_variable = "#{$aioseo_prefix}-{$unique_custom_field_or_taxonomy}"; + $yoast_variable = "%%{$yoast_prefix}_{$unique_custom_field_or_taxonomy}%%"; + + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching + $wpdb->query( + $wpdb->prepare( + 'UPDATE tmp_meta_table SET meta_value = REPLACE( meta_value, %s, %s )', + $aioseo_variable, + $yoast_variable, + ), + ); + } + } + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching + + /** + * Retrieve all the meta values from the temporary meta table that contain + * at least one AiOSEO custom field replace var. + * + * @param wpdb $wpdb The WordPress database object. + * @param string $aioseo_prefix The AiOSEO prefix to use + * (e.g. `custom-field` for custom fields or `tax_name` for custom taxonomies). + * + * @return string[] All meta values that contain at least one AioSEO custom field replace var. + */ + protected function get_meta_values_with_custom_field_or_taxonomy( $wpdb, $aioseo_prefix ) { + return $wpdb->get_col( + $wpdb->prepare( + 'SELECT meta_value FROM tmp_meta_table WHERE meta_value LIKE %s', + "%#$aioseo_prefix-%", + ), + ); + } + + // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching + + /** + * Detects whether there is AIOSEO data to import by looking whether the AIOSEO data have been cleaned up. + * + * @return bool Boolean indicating whether there is something to import. + */ + protected function detect() { + $aioseo_cleanup_action = YoastSEO()->classes->get( Aioseo_Cleanup_Action::class ); + return ( $aioseo_cleanup_action->get_total_unindexed() > 0 ); + } + + /** + * Import AIOSEO post data from their custom indexable table. Not currently used. + * + * @return void + */ + protected function import() { + // This is overriden from the import.js and never run. + $aioseo_posts_import_action = YoastSEO()->classes->get( Aioseo_Posts_Importing_Action::class ); + $aioseo_posts_import_action->index(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-aioseo.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-aioseo.php new file mode 100644 index 0000000..cf7ab49 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-aioseo.php @@ -0,0 +1,110 @@ + 'opengraph-title', + 'aioseop_opengraph_settings_desc' => 'opengraph-description', + 'aioseop_opengraph_settings_customimg' => 'opengraph-image', + 'aioseop_opengraph_settings_customimg_twitter' => 'twitter-image', + ]; + + /** + * Array of meta keys to detect and import. + * + * @var array + */ + protected $clone_keys = [ + [ + 'old_key' => '_aioseop_title', + 'new_key' => 'title', + ], + [ + 'old_key' => '_aioseop_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_aioseop_noindex', + 'new_key' => 'meta-robots-noindex', + 'convert' => [ 'on' => 1 ], + ], + [ + 'old_key' => '_aioseop_nofollow', + 'new_key' => 'meta-robots-nofollow', + 'convert' => [ 'on' => 1 ], + ], + ]; + + /** + * Import All In One SEO meta values. + * + * @return bool Import success status. + */ + protected function import() { + $status = parent::import(); + if ( $status ) { + $this->import_opengraph(); + } + return $status; + } + + /** + * Imports the OpenGraph and Twitter settings for all posts. + * + * @return bool + */ + protected function import_opengraph() { + $query_posts = new WP_Query( 'post_type=any&meta_key=_aioseop_opengraph_settings&order=ASC&fields=ids&nopaging=true' ); + + if ( ! empty( $query_posts->posts ) ) { + foreach ( array_values( $query_posts->posts ) as $post_id ) { + $this->import_post_opengraph( $post_id ); + } + } + + return true; + } + + /** + * Imports the OpenGraph and Twitter settings for a single post. + * + * @param int $post_id Post ID. + * + * @return void + */ + private function import_post_opengraph( $post_id ) { + $meta = get_post_meta( $post_id, '_aioseop_opengraph_settings', true ); + $meta = maybe_unserialize( $meta ); + + foreach ( $this->import_keys as $old_key => $new_key ) { + $this->maybe_save_post_meta( $new_key, $meta[ $old_key ], $post_id ); + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-greg-high-performance-seo.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-greg-high-performance-seo.php new file mode 100644 index 0000000..8925421 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-greg-high-performance-seo.php @@ -0,0 +1,42 @@ + '_ghpseo_alternative_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_ghpseo_secondary_title', + 'new_key' => 'title', + ], + ]; +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-headspace.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-headspace.php new file mode 100644 index 0000000..3a43d16 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-headspace.php @@ -0,0 +1,54 @@ + '_headspace_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_headspace_page_title', + 'new_key' => 'title', + ], + [ + 'old_key' => '_headspace_noindex', + 'new_key' => 'meta-robots-noindex', + 'convert' => [ 'on' => 1 ], + ], + [ + 'old_key' => '_headspace_nofollow', + 'new_key' => 'meta-robots-nofollow', + 'convert' => [ 'on' => 1 ], + ], + ]; +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-jetpack.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-jetpack.php new file mode 100644 index 0000000..5f57d81 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-jetpack.php @@ -0,0 +1,40 @@ + 'advanced_seo_description', + 'new_key' => 'metadesc', + ], + ]; +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-platinum-seo-pack.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-platinum-seo-pack.php new file mode 100644 index 0000000..8240fe8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-platinum-seo-pack.php @@ -0,0 +1,138 @@ + 'description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => 'title', + 'new_key' => 'title', + ], + ]; + + /** + * Runs the import of post meta keys stored by Platinum SEO Pack. + * + * @return bool + */ + protected function import() { + $return = parent::import(); + if ( $return ) { + $this->import_robots_meta(); + } + + return $return; + } + + /** + * Cleans up all the meta values Platinum SEO pack creates. + * + * @return bool + */ + protected function cleanup() { + $this->meta_key = 'title'; + parent::cleanup(); + + $this->meta_key = 'description'; + parent::cleanup(); + + $this->meta_key = 'metarobots'; + parent::cleanup(); + + return true; + } + + /** + * Finds all the robotsmeta fields to import and deals with them. + * + * There are four potential values that Platinum SEO stores: + * - index,folllow + * - index,nofollow + * - noindex,follow + * - noindex,nofollow + * + * We only have to deal with the latter 3, the first is our default. + * + * @return void + */ + protected function import_robots_meta() { + $this->import_by_meta_robots( 'index,nofollow', [ 'nofollow' ] ); + $this->import_by_meta_robots( 'noindex,follow', [ 'noindex' ] ); + $this->import_by_meta_robots( 'noindex,nofollow', [ 'noindex', 'nofollow' ] ); + } + + /** + * Imports the values for all index, nofollow posts. + * + * @param string $value The meta robots value to find posts for. + * @param array $metas The meta field(s) to save. + * + * @return void + */ + protected function import_by_meta_robots( $value, $metas ) { + $posts = $this->find_posts_by_robots_meta( $value ); + if ( ! $posts ) { + return; + } + + foreach ( $posts as $post_id ) { + foreach ( $metas as $meta ) { + $this->maybe_save_post_meta( 'meta-robots-' . $meta, 1, $post_id ); + } + } + } + + /** + * Finds posts by a given meta robots value. + * + * @param string $meta_value Robots meta value. + * + * @return array|bool Array of Post IDs on success, false on failure. + */ + protected function find_posts_by_robots_meta( $meta_value ) { + $posts = get_posts( + [ + 'post_type' => 'any', + 'meta_key' => 'robotsmeta', + 'meta_value' => $meta_value, + 'order' => 'ASC', + 'fields' => 'ids', + 'nopaging' => true, + ], + ); + if ( empty( $posts ) ) { + return false; + } + return $posts; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-premium-seo-pack.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-premium-seo-pack.php new file mode 100644 index 0000000..bd93b91 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-premium-seo-pack.php @@ -0,0 +1,39 @@ +table_name = $wpdb->prefix . 'psp'; + $this->meta_key = ''; + } + + /** + * Returns the query to return an identifier for the posts to import. + * + * @return string + */ + protected function retrieve_posts_query() { + return "SELECT URL AS identifier FROM {$this->table_name} WHERE blog_id = %d"; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-rankmath.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-rankmath.php new file mode 100644 index 0000000..68e7c0c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-rankmath.php @@ -0,0 +1,179 @@ + 'rank_math_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => 'rank_math_title', + 'new_key' => 'title', + ], + [ + 'old_key' => 'rank_math_canonical_url', + 'new_key' => 'canonical', + ], + [ + 'old_key' => 'rank_math_primary_category', + 'new_key' => 'primary_category', + ], + [ + 'old_key' => 'rank_math_facebook_title', + 'new_key' => 'opengraph-title', + ], + [ + 'old_key' => 'rank_math_facebook_description', + 'new_key' => 'opengraph-description', + ], + [ + 'old_key' => 'rank_math_facebook_image', + 'new_key' => 'opengraph-image', + ], + [ + 'old_key' => 'rank_math_facebook_image_id', + 'new_key' => 'opengraph-image-id', + ], + [ + 'old_key' => 'rank_math_twitter_title', + 'new_key' => 'twitter-title', + ], + [ + 'old_key' => 'rank_math_twitter_description', + 'new_key' => 'twitter-description', + ], + [ + 'old_key' => 'rank_math_twitter_image', + 'new_key' => 'twitter-image', + ], + [ + 'old_key' => 'rank_math_twitter_image_id', + 'new_key' => 'twitter-image-id', + ], + [ + 'old_key' => 'rank_math_focus_keyword', + 'new_key' => 'focuskw', + ], + ]; + + /** + * Handles post meta data to import. + * + * @return bool Import success status. + */ + protected function import() { + global $wpdb; + // Replace % with %% as their variables are the same except for that. + $wpdb->query( "UPDATE $wpdb->postmeta SET meta_value = REPLACE( meta_value, '%', '%%' ) WHERE meta_key IN ( 'rank_math_description', 'rank_math_title' )" ); + + $this->import_meta_robots(); + $return = $this->meta_keys_clone( $this->clone_keys ); + + // Return %% to % so our import is non-destructive. + $wpdb->query( "UPDATE $wpdb->postmeta SET meta_value = REPLACE( meta_value, '%%', '%' ) WHERE meta_key IN ( 'rank_math_description', 'rank_math_title' )" ); + + if ( $return ) { + $this->import_settings(); + } + + return $return; + } + + /** + * RankMath stores robots meta quite differently, so we have to parse it out. + * + * @return void + */ + private function import_meta_robots() { + global $wpdb; + $post_metas = $wpdb->get_results( "SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = 'rank_math_robots'" ); + foreach ( $post_metas as $post_meta ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- Reason: We can't control the form in which Rankmath sends the data. + $robots_values = unserialize( $post_meta->meta_value ); + foreach ( [ 'noindex', 'nofollow' ] as $directive ) { + $directive_key = array_search( $directive, $robots_values, true ); + if ( $directive_key !== false ) { + update_post_meta( $post_meta->post_id, '_yoast_wpseo_meta-robots-' . $directive, 1 ); + unset( $robots_values[ $directive_key ] ); + } + } + if ( count( $robots_values ) > 0 ) { + $value = implode( ',', $robots_values ); + update_post_meta( $post_meta->post_id, '_yoast_wpseo_meta-robots-adv', $value ); + } + } + } + + /** + * Imports some of the RankMath settings. + * + * @return void + */ + private function import_settings() { + $settings = [ + 'title_separator' => 'separator', + 'homepage_title' => 'title-home-wpseo', + 'homepage_description' => 'metadesc-home-wpseo', + 'author_archive_title' => 'title-author-wpseo', + 'date_archive_title' => 'title-archive-wpseo', + 'search_title' => 'title-search-wpseo', + '404_title' => 'title-404-wpseo', + 'pt_post_title' => 'title-post', + 'pt_page_title' => 'title-page', + ]; + $options = get_option( 'rank-math-options-titles' ); + + foreach ( $settings as $import_setting_key => $setting_key ) { + if ( ! empty( $options[ $import_setting_key ] ) ) { + $value = $options[ $import_setting_key ]; + // Make sure replace vars work. + $value = str_replace( '%', '%%', $value ); + WPSEO_Options::set( $setting_key, $value ); + } + } + } + + /** + * Removes the plugin data from the database. + * + * @return bool Cleanup status. + */ + protected function cleanup() { + $return = parent::cleanup(); + if ( $return ) { + global $wpdb; + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE 'rank-math-%'" ); + $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '%rank_math%'" ); + } + + return $return; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-seo-framework.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-seo-framework.php new file mode 100644 index 0000000..8a8ac9e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-seo-framework.php @@ -0,0 +1,94 @@ + '_genesis_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_genesis_title', + 'new_key' => 'title', + ], + [ + 'old_key' => '_genesis_noindex', + 'new_key' => 'meta-robots-noindex', + ], + [ + 'old_key' => '_genesis_nofollow', + 'new_key' => 'meta-robots-nofollow', + ], + [ + 'old_key' => '_genesis_canonical_uri', + 'new_key' => 'canonical', + ], + [ + 'old_key' => '_open_graph_title', + 'new_key' => 'opengraph-title', + ], + [ + 'old_key' => '_open_graph_description', + 'new_key' => 'opengraph-description', + ], + [ + 'old_key' => '_social_image_url', + 'new_key' => 'opengraph-image', + ], + [ + 'old_key' => '_twitter_title', + 'new_key' => 'twitter-title', + ], + [ + 'old_key' => '_twitter_description', + 'new_key' => 'twitter-description', + ], + ]; + + /** + * Removes all the metadata set by the SEO Framework plugin. + * + * @return bool + */ + protected function cleanup() { + $set1 = parent::cleanup(); + + $this->meta_key = '_social_image_%'; + $set2 = parent::cleanup(); + + $this->meta_key = '_twitter_%'; + $set3 = parent::cleanup(); + + $this->meta_key = '_open_graph_%'; + $set4 = parent::cleanup(); + + return ( $set1 || $set2 || $set3 || $set4 ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-seopressor.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-seopressor.php new file mode 100644 index 0000000..4009c79 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-seopressor.php @@ -0,0 +1,175 @@ + '_seop_settings', + ], + ]; + + /** + * Imports the post meta values to Yoast SEO. + * + * @return bool Import success status. + */ + protected function import() { + // Query for all the posts that have an _seop_settings meta set. + $query_posts = new WP_Query( 'post_type=any&meta_key=_seop_settings&order=ASC&fields=ids&nopaging=true' ); + foreach ( $query_posts->posts as $post_id ) { + $this->import_post_focus_keywords( $post_id ); + $this->import_seopressor_post_settings( $post_id ); + } + + return true; + } + + /** + * Removes all the post meta fields SEOpressor creates. + * + * @return bool Cleanup status. + */ + protected function cleanup() { + global $wpdb; + + // If we get to replace the data, let's do some proper cleanup. + return $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE '_seop_%'" ); + } + + /** + * Imports the data. SEOpressor stores most of the data in one post array, this loops over it. + * + * @param int $post_id Post ID. + * + * @return void + */ + private function import_seopressor_post_settings( $post_id ) { + $settings = get_post_meta( $post_id, '_seop_settings', true ); + + foreach ( + [ + 'fb_description' => 'opengraph-description', + 'fb_title' => 'opengraph-title', + 'fb_type' => 'og_type', + 'fb_img' => 'opengraph-image', + 'meta_title' => 'title', + 'meta_description' => 'metadesc', + 'meta_canonical' => 'canonical', + 'tw_description' => 'twitter-description', + 'tw_title' => 'twitter-title', + 'tw_image' => 'twitter-image', + ] as $seopressor_key => $yoast_key ) { + $this->import_meta_helper( $seopressor_key, $yoast_key, $settings, $post_id ); + } + + if ( isset( $settings['meta_rules'] ) ) { + $this->import_post_robots( $settings['meta_rules'], $post_id ); + } + } + + /** + * Imports the focus keywords, and stores them for later use. + * + * @param int $post_id Post ID. + * + * @return void + */ + private function import_post_focus_keywords( $post_id ) { + // Import the focus keyword. + $focuskw = trim( get_post_meta( $post_id, '_seop_kw_1', true ) ); + $this->maybe_save_post_meta( 'focuskw', $focuskw, $post_id ); + + // Import additional focus keywords for use in premium. + $focuskw2 = trim( get_post_meta( $post_id, '_seop_kw_2', true ) ); + $focuskw3 = trim( get_post_meta( $post_id, '_seop_kw_3', true ) ); + + $focus_keywords = []; + if ( ! empty( $focuskw2 ) ) { + $focus_keywords[] = $focuskw2; + } + if ( ! empty( $focuskw3 ) ) { + $focus_keywords[] = $focuskw3; + } + + if ( $focus_keywords !== [] ) { + $this->maybe_save_post_meta( 'focuskeywords', WPSEO_Utils::format_json_encode( $focus_keywords ), $post_id ); + } + } + + /** + * Retrieves the SEOpressor robot value and map this to Yoast SEO values. + * + * @param string $meta_rules The meta rules taken from the SEOpressor settings array. + * @param int $post_id The post id of the current post. + * + * @return void + */ + private function import_post_robots( $meta_rules, $post_id ) { + $seopressor_robots = explode( '#|#|#', $meta_rules ); + $robot_value = $this->get_robot_value( $seopressor_robots ); + + // Saving the new meta values for Yoast SEO. + $this->maybe_save_post_meta( 'meta-robots-noindex', $robot_value['index'], $post_id ); + $this->maybe_save_post_meta( 'meta-robots-nofollow', $robot_value['follow'], $post_id ); + $this->maybe_save_post_meta( 'meta-robots-adv', $robot_value['advanced'], $post_id ); + } + + /** + * Gets the robot config by given SEOpressor robots value. + * + * @param array $seopressor_robots The value in SEOpressor that needs to be converted to the Yoast format. + * + * @return array The robots values in Yoast format. + */ + private function get_robot_value( $seopressor_robots ) { + $return = [ + 'index' => 2, + 'follow' => 0, + 'advanced' => '', + ]; + + if ( in_array( 'noindex', $seopressor_robots, true ) ) { + $return['index'] = 1; + } + if ( in_array( 'nofollow', $seopressor_robots, true ) ) { + $return['follow'] = 1; + } + foreach ( [ 'noarchive', 'nosnippet', 'noimageindex' ] as $needle ) { + if ( in_array( $needle, $seopressor_robots, true ) ) { + $return['advanced'] .= $needle . ','; + } + } + $return['advanced'] = rtrim( $return['advanced'], ',' ); + + return $return; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-smartcrawl.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-smartcrawl.php new file mode 100644 index 0000000..507120c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-smartcrawl.php @@ -0,0 +1,151 @@ + '_wds_metadesc', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_wds_title', + 'new_key' => 'title', + ], + [ + 'old_key' => '_wds_canonical', + 'new_key' => 'canonical', + ], + [ + 'old_key' => '_wds_focus-keywords', + 'new_key' => 'focuskw', + ], + [ + 'old_key' => '_wds_meta-robots-noindex', + 'new_key' => 'meta-robots-noindex', + ], + [ + 'old_key' => '_wds_meta-robots-nofollow', + 'new_key' => 'meta-robots-nofollow', + ], + ]; + + /** + * Used for importing Twitter and Facebook meta's. + * + * @var array + */ + protected $social_keys = []; + + /** + * Handles post meta data to import. + * + * @return bool Import success status. + */ + protected function import() { + $return = parent::import(); + if ( $return ) { + $this->import_opengraph(); + $this->import_twitter(); + } + + return $return; + } + + /** + * Imports the OpenGraph meta keys saved by Smartcrawl. + * + * @return bool Import status. + */ + protected function import_opengraph() { + $this->social_keys = [ + 'title' => 'opengraph-title', + 'description' => 'opengraph-description', + 'images' => 'opengraph-image', + ]; + return $this->post_find_import( '_wds_opengraph' ); + } + + /** + * Imports the Twitter meta keys saved by Smartcrawl. + * + * @return bool Import status. + */ + protected function import_twitter() { + $this->social_keys = [ + 'title' => 'twitter-title', + 'description' => 'twitter-description', + ]; + return $this->post_find_import( '_wds_twitter' ); + } + + /** + * Imports a post's serialized post meta values. + * + * @param int $post_id Post ID. + * @param string $key The meta key to import. + * + * @return void + */ + protected function import_serialized_post_meta( $post_id, $key ) { + $data = get_post_meta( $post_id, $key, true ); + $data = maybe_unserialize( $data ); + foreach ( $this->social_keys as $key => $meta_key ) { + if ( ! isset( $data[ $key ] ) ) { + return; + } + $value = $data[ $key ]; + if ( is_array( $value ) ) { + $value = $value[0]; + } + $this->maybe_save_post_meta( $meta_key, $value, $post_id ); + } + } + + /** + * Finds all the posts with a certain meta key and imports its values. + * + * @param string $key The meta key to search for. + * + * @return bool Import status. + */ + protected function post_find_import( $key ) { + $query_posts = new WP_Query( 'post_type=any&meta_key=' . $key . '&order=ASC&fields=ids&nopaging=true' ); + + if ( empty( $query_posts->posts ) ) { + return false; + } + + foreach ( array_values( $query_posts->posts ) as $post_id ) { + $this->import_serialized_post_meta( $post_id, $key ); + } + + return true; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-squirrly.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-squirrly.php new file mode 100644 index 0000000..903eacc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-squirrly.php @@ -0,0 +1,224 @@ + 'meta-robots-noindex', + 'nofollow' => 'meta-robots-nofollow', + 'title' => 'title', + 'description' => 'metadesc', + 'canonical' => 'canonical', + 'cornerstone' => '_yst_is_cornerstone', + 'tw_media' => 'twitter-image', + 'tw_title' => 'twitter-title', + 'tw_description' => 'twitter-description', + 'og_title' => 'opengraph-title', + 'og_description' => 'opengraph-description', + 'og_media' => 'opengraph-image', + 'focuskw' => 'focuskw', + ]; + + /** + * WPSEO_Import_Squirrly constructor. + */ + public function __construct() { + parent::__construct(); + + global $wpdb; + $this->table_name = $wpdb->prefix . 'qss'; + } + + /** + * Imports the post meta values to Yoast SEO. + * + * @return bool Import success status. + */ + protected function import() { + $results = $this->retrieve_posts(); + foreach ( $results as $post ) { + $return = $this->import_post_values( $post->identifier ); + if ( ! $return ) { + return false; + } + } + + return true; + } + + /** + * Retrieve the posts from the Squirrly Database. + * + * @return array Array of post IDs from the DB. + */ + protected function retrieve_posts() { + global $wpdb; + return $wpdb->get_results( + $wpdb->prepare( + $this->retrieve_posts_query(), + get_current_blog_id(), + ), + ); + } + + /** + * Returns the query to return an identifier for the posts to import. + * + * @return string Query to get post ID's from the DB. + */ + protected function retrieve_posts_query() { + return "SELECT post_id AS identifier FROM {$this->table_name} WHERE blog_id = %d"; + } + + /** + * Removes the DB table and the post meta field Squirrly creates. + * + * @return bool Cleanup status. + */ + protected function cleanup() { + global $wpdb; + + // If we can clean, let's clean. + $wpdb->query( "DROP TABLE {$this->table_name}" ); + + // This removes the post meta field for the focus keyword from the DB. + parent::cleanup(); + + // If we can still see the table, something went wrong. + if ( $this->detect() ) { + $this->cleanup_error_msg(); + return false; + } + + return true; + } + + /** + * Detects whether there is post meta data to import. + * + * @return bool Boolean indicating whether there is something to import. + */ + protected function detect() { + global $wpdb; + + $result = $wpdb->get_var( "SHOW TABLES LIKE '{$this->table_name}'" ); + if ( is_wp_error( $result ) || $result === null ) { + return false; + } + + return true; + } + + /** + * Imports the data of a post out of Squirrly's DB table. + * + * @param mixed $post_identifier Post identifier, can be ID or string. + * + * @return bool Import status. + */ + private function import_post_values( $post_identifier ) { + $data = $this->retrieve_post_data( $post_identifier ); + if ( ! $data ) { + return false; + } + + if ( ! is_numeric( $post_identifier ) ) { + $post_id = url_to_postid( $post_identifier ); + } + + if ( is_numeric( $post_identifier ) ) { + $post_id = (int) $post_identifier; + $data['focuskw'] = $this->maybe_add_focus_kw( $post_identifier ); + } + + foreach ( $this->seo_field_keys as $squirrly_key => $yoast_key ) { + $this->import_meta_helper( $squirrly_key, $yoast_key, $data, $post_id ); + } + return true; + } + + /** + * Retrieves the Squirrly SEO data for a post from the DB. + * + * @param int $post_identifier Post ID. + * + * @return array|bool Array of data or false. + */ + private function retrieve_post_data( $post_identifier ) { + global $wpdb; + + if ( is_numeric( $post_identifier ) ) { + $post_identifier = (int) $post_identifier; + $query_where = 'post_id = %d'; + } + if ( ! is_numeric( $post_identifier ) ) { + $query_where = 'URL = %s'; + } + + $replacements = [ + get_current_blog_id(), + $post_identifier, + ]; + + $data = $wpdb->get_var( + $wpdb->prepare( + "SELECT seo FROM {$this->table_name} WHERE blog_id = %d AND " . $query_where, + $replacements, + ), + ); + if ( ! $data || is_wp_error( $data ) ) { + return false; + } + $data = maybe_unserialize( $data ); + return $data; + } + + /** + * Squirrly stores the focus keyword in post meta. + * + * @param int $post_id Post ID. + * + * @return string The focus keyword. + */ + private function maybe_add_focus_kw( $post_id ) { + $focuskw = get_post_meta( $post_id, '_sq_post_keyword', true ); + if ( $focuskw ) { + $focuskw = json_decode( $focuskw ); + return $focuskw->keyword; + } + return ''; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-ultimate-seo.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-ultimate-seo.php new file mode 100644 index 0000000..a511365 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-ultimate-seo.php @@ -0,0 +1,64 @@ + '_su_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_su_title', + 'new_key' => 'title', + ], + [ + 'old_key' => '_su_og_title', + 'new_key' => 'opengraph-title', + ], + [ + 'old_key' => '_su_og_description', + 'new_key' => 'opengraph-description', + ], + [ + 'old_key' => '_su_og_image', + 'new_key' => 'opengraph-image', + ], + [ + 'old_key' => '_su_meta_robots_noindex', + 'new_key' => 'meta-robots-noindex', + 'convert' => [ 'on' => 1 ], + ], + [ + 'old_key' => '_su_meta_robots_nofollow', + 'new_key' => 'meta-robots-nofollow', + 'convert' => [ 'on' => 1 ], + ], + ]; +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-woothemes-seo.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-woothemes-seo.php new file mode 100644 index 0000000..8de3713 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-woothemes-seo.php @@ -0,0 +1,138 @@ + 'seo_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => 'seo_title', + 'new_key' => 'title', + ], + [ + 'old_key' => 'seo_noindex', + 'new_key' => 'meta-robots-noindex', + ], + [ + 'old_key' => 'seo_follow', + 'new_key' => 'meta-robots-nofollow', + ], + ]; + + /** + * Holds the meta fields we can delete after import. + * + * @var array + */ + protected $cleanup_metas = [ + 'seo_follow', + 'seo_noindex', + 'seo_title', + 'seo_description', + 'seo_keywords', + ]; + + /** + * Holds the options we can delete after import. + * + * @var array + */ + protected $cleanup_options = [ + 'seo_woo_archive_layout', + 'seo_woo_single_layout', + 'seo_woo_page_layout', + 'seo_woo_wp_title', + 'seo_woo_meta_single_desc', + 'seo_woo_meta_single_key', + 'seo_woo_home_layout', + ]; + + /** + * Cleans up the WooThemes SEO settings. + * + * @return bool Cleanup status. + */ + protected function cleanup() { + $result = $this->cleanup_meta(); + if ( $result ) { + $this->cleanup_options(); + } + return $result; + } + + /** + * Removes the Woo Options from the database. + * + * @return void + */ + private function cleanup_options() { + foreach ( $this->cleanup_options as $option ) { + delete_option( $option ); + } + } + + /** + * Removes the post meta fields from the database. + * + * @return bool Cleanup status. + */ + private function cleanup_meta() { + foreach ( $this->cleanup_metas as $key ) { + $result = $this->cleanup_meta_key( $key ); + if ( ! $result ) { + return false; + } + } + return true; + } + + /** + * Removes a single meta field from the postmeta table in the database. + * + * @param string $key The meta_key to delete. + * + * @return bool Cleanup status. + */ + private function cleanup_meta_key( $key ) { + global $wpdb; + + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->postmeta} WHERE meta_key = %s", + $key, + ), + ); + return $wpdb->__get( 'result' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-wp-meta-seo.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-wp-meta-seo.php new file mode 100644 index 0000000..e6a55ef --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-wp-meta-seo.php @@ -0,0 +1,82 @@ + '_metaseo_metadesc', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_metaseo_metatitle', + 'new_key' => 'title', + ], + [ + 'old_key' => '_metaseo_metaopengraph-title', + 'new_key' => 'opengraph-title', + ], + [ + 'old_key' => '_metaseo_metaopengraph-desc', + 'new_key' => 'opengraph-description', + ], + [ + 'old_key' => '_metaseo_metaopengraph-image', + 'new_key' => 'opengraph-image', + ], + [ + 'old_key' => '_metaseo_metatwitter-title', + 'new_key' => 'twitter-title', + ], + [ + 'old_key' => '_metaseo_metatwitter-desc', + 'new_key' => 'twitter-description', + ], + [ + 'old_key' => '_metaseo_metatwitter-image', + 'new_key' => 'twitter-image', + ], + [ + 'old_key' => '_metaseo_metaindex', + 'new_key' => 'meta-robots-noindex', + 'convert' => [ + 'index' => 0, + 'noindex' => 1, + ], + ], + [ + 'old_key' => '_metaseo_metafollow', + 'new_key' => 'meta-robots-nofollow', + 'convert' => [ + 'follow' => 0, + 'nofollow' => 1, + ], + ], + ]; +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-wpseo.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-wpseo.php new file mode 100644 index 0000000..d34676b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-import-wpseo.php @@ -0,0 +1,310 @@ + '_wpseo_edit_description', + 'new_key' => 'metadesc', + ], + [ + 'old_key' => '_wpseo_edit_title', + 'new_key' => 'title', + ], + [ + 'old_key' => '_wpseo_edit_canonical', + 'new_key' => 'canonical', + ], + [ + 'old_key' => '_wpseo_edit_og_title', + 'new_key' => 'opengraph-title', + ], + [ + 'old_key' => '_wpseo_edit_og_description', + 'new_key' => 'opengraph-description', + ], + [ + 'old_key' => '_wpseo_edit_og_image', + 'new_key' => 'opengraph-image', + ], + [ + 'old_key' => '_wpseo_edit_twittercard_title', + 'new_key' => 'twitter-title', + ], + [ + 'old_key' => '_wpseo_edit_twittercard_description', + 'new_key' => 'twitter-description', + ], + [ + 'old_key' => '_wpseo_edit_twittercard_image', + 'new_key' => 'twitter-image', + ], + ]; + + /** + * The values 1 - 6 are the configured values from wpSEO. This array will map the values of wpSEO to our values. + * + * There are some double array like 1-6 and 3-4. The reason is they only set the index value. The follow value is + * the default we use in the cases there isn't a follow value present. + * + * @var array + */ + private $robot_values = [ + // In wpSEO: index, follow. + 1 => [ + 'index' => 2, + 'follow' => 0, + ], + // In wpSEO: index, nofollow. + 2 => [ + 'index' => 2, + 'follow' => 1, + ], + // In wpSEO: noindex. + 3 => [ + 'index' => 1, + 'follow' => 0, + ], + // In wpSEO: noindex, follow. + 4 => [ + 'index' => 1, + 'follow' => 0, + ], + // In wpSEO: noindex, nofollow. + 5 => [ + 'index' => 1, + 'follow' => 1, + ], + // In wpSEO: index. + 6 => [ + 'index' => 2, + 'follow' => 0, + ], + ]; + + /** + * Imports wpSEO settings. + * + * @return bool Import success status. + */ + protected function import() { + $status = parent::import(); + if ( $status ) { + $this->import_post_robots(); + $this->import_taxonomy_metas(); + } + + return $status; + } + + /** + * Removes wpseo.de post meta's. + * + * @return bool Cleanup status. + */ + protected function cleanup() { + $this->cleanup_term_meta(); + $result = $this->cleanup_post_meta(); + return $result; + } + + /** + * Detects whether there is post meta data to import. + * + * @return bool Boolean indicating whether there is something to import. + */ + protected function detect() { + if ( parent::detect() ) { + return true; + } + + global $wpdb; + $count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->options} WHERE option_name LIKE 'wpseo_category_%'" ); + if ( $count !== '0' ) { + return true; + } + + return false; + } + + /** + * Imports the robot values from WPSEO plugin. These have to be converted to the Yoast format. + * + * @return void + */ + private function import_post_robots() { + $query_posts = new WP_Query( 'post_type=any&meta_key=_wpseo_edit_robots&order=ASC&fields=ids&nopaging=true' ); + + if ( ! empty( $query_posts->posts ) ) { + foreach ( array_values( $query_posts->posts ) as $post_id ) { + $this->import_post_robot( $post_id ); + } + } + } + + /** + * Gets the wpSEO robot value and map this to Yoast SEO values. + * + * @param int $post_id The post id of the current post. + * + * @return void + */ + private function import_post_robot( $post_id ) { + $wpseo_robots = get_post_meta( $post_id, '_wpseo_edit_robots', true ); + $robot_value = $this->get_robot_value( $wpseo_robots ); + + // Saving the new meta values for Yoast SEO. + $this->maybe_save_post_meta( 'meta-robots-noindex', $robot_value['index'], $post_id ); + $this->maybe_save_post_meta( 'meta-robots-nofollow', $robot_value['follow'], $post_id ); + } + + /** + * Imports the taxonomy metas from wpSEO. + * + * @return void + */ + private function import_taxonomy_metas() { + $terms = get_terms( + [ + 'taxonomy' => get_taxonomies(), + 'hide_empty' => false, + ], + ); + $tax_meta = get_option( 'wpseo_taxonomy_meta' ); + + foreach ( $terms as $term ) { + $this->import_taxonomy_description( $tax_meta, $term->taxonomy, $term->term_id ); + $this->import_taxonomy_robots( $tax_meta, $term->taxonomy, $term->term_id ); + } + + update_option( 'wpseo_taxonomy_meta', $tax_meta ); + } + + /** + * Imports the meta description to Yoast SEO. + * + * @param array $tax_meta The array with the current metadata. + * @param string $taxonomy String with the name of the taxonomy. + * @param string $term_id The ID of the current term. + * + * @return void + */ + private function import_taxonomy_description( &$tax_meta, $taxonomy, $term_id ) { + $description = get_option( 'wpseo_' . $taxonomy . '_' . $term_id, false ); + if ( $description !== false ) { + // Import description. + $tax_meta[ $taxonomy ][ $term_id ]['wpseo_desc'] = $description; + } + } + + /** + * Imports the robot value to Yoast SEO. + * + * @param array $tax_meta The array with the current metadata. + * @param string $taxonomy String with the name of the taxonomy. + * @param string $term_id The ID of the current term. + * + * @return void + */ + private function import_taxonomy_robots( &$tax_meta, $taxonomy, $term_id ) { + $wpseo_robots = get_option( 'wpseo_' . $taxonomy . '_' . $term_id . '_robots', false ); + if ( $wpseo_robots === false ) { + return; + } + // The value 1, 2 and 6 are the index values in wpSEO. + $new_robot_value = 'noindex'; + + if ( in_array( (int) $wpseo_robots, [ 1, 2, 6 ], true ) ) { + $new_robot_value = 'index'; + } + + $tax_meta[ $taxonomy ][ $term_id ]['wpseo_noindex'] = $new_robot_value; + } + + /** + * Deletes the wpSEO taxonomy meta data. + * + * @param string $taxonomy String with the name of the taxonomy. + * @param string $term_id The ID of the current term. + * + * @return void + */ + private function delete_taxonomy_metas( $taxonomy, $term_id ) { + delete_option( 'wpseo_' . $taxonomy . '_' . $term_id ); + delete_option( 'wpseo_' . $taxonomy . '_' . $term_id . '_robots' ); + } + + /** + * Gets the robot config by given wpSEO robots value. + * + * @param string $wpseo_robots The value in wpSEO that needs to be converted to the Yoast format. + * + * @return string The correct robot value. + */ + private function get_robot_value( $wpseo_robots ) { + if ( array_key_exists( $wpseo_robots, $this->robot_values ) ) { + return $this->robot_values[ $wpseo_robots ]; + } + + return $this->robot_values[1]; + } + + /** + * Deletes wpSEO postmeta from the database. + * + * @return bool Cleanup status. + */ + private function cleanup_post_meta() { + global $wpdb; + + // If we get to replace the data, let's do some proper cleanup. + return $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE '_wpseo_edit_%'" ); + } + + /** + * Cleans up the wpSEO term meta. + * + * @return void + */ + private function cleanup_term_meta() { + $terms = get_terms( + [ + 'taxonomy' => get_taxonomies(), + 'hide_empty' => false, + ], + ); + + foreach ( $terms as $term ) { + $this->delete_taxonomy_metas( $term->taxonomy, $term->term_id ); + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-importers.php b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-importers.php new file mode 100644 index 0000000..d2336ec --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/import/plugins/class-importers.php @@ -0,0 +1,47 @@ +get_manage_capability(); + $page_identifier = $this->get_page_identifier(); + $admin_page_callback = $this->get_admin_page_callback(); + + // Get all submenu pages. + $submenu_pages = $this->get_submenu_pages(); + + foreach ( $submenu_pages as $submenu_page ) { + if ( WPSEO_Capability_Utils::current_user_can( $submenu_page[3] ) ) { + $manage_capability = $submenu_page[3]; + $page_identifier = $submenu_page[4]; + $admin_page_callback = $submenu_page[5]; + break; + } + } + + foreach ( $submenu_pages as $index => $submenu_page ) { + $submenu_pages[ $index ][0] = $page_identifier; + } + + /* + * The current user has the capability to control anything. + * This means that all submenus and dashboard can be shown. + */ + global $admin_page_hooks; + + add_menu_page( + 'Yoast SEO: ' . __( 'Dashboard', 'wordpress-seo' ), + 'Yoast SEO ' . $this->get_notification_counter(), + $manage_capability, + $page_identifier, + $admin_page_callback, + $this->get_icon_svg(), + 99, + ); + + // Wipe notification bits from hooks. + // phpcs:ignore WordPress.WP.GlobalVariablesOverride -- This is a deliberate action. + $admin_page_hooks[ $page_identifier ] = 'seo'; + + // Add submenu items to the main menu if possible. + $this->register_submenu_pages( $submenu_pages ); + } + + /** + * Returns the list of registered submenu pages. + * + * @return array List of registered submenu pages. + */ + public function get_submenu_pages() { + global $wpseo_admin; + + $search_console_callback = null; + + // Account for when the available submenu pages are requested from outside the admin. + if ( isset( $wpseo_admin ) ) { + $google_search_console = new WPSEO_GSC(); + $search_console_callback = [ $google_search_console, 'display' ]; + } + + // Submenu pages. + $submenu_pages = [ + $this->get_submenu_page( + __( 'Search Console', 'wordpress-seo' ), + 'wpseo_search_console', + $search_console_callback, + ), + $this->get_submenu_page( __( 'Tools', 'wordpress-seo' ), 'wpseo_tools' ), + ]; + + /** + * Filter: 'wpseo_submenu_pages' - Collects all submenus that need to be shown. + * + * @param array $submenu_pages List with all submenu pages. + */ + return (array) apply_filters( 'wpseo_submenu_pages', $submenu_pages ); + } + + /** + * Returns the notification count in HTML format. + * + * @return string The notification count in HTML format. + */ + protected function get_notification_counter() { + $notification_center = Yoast_Notification_Center::get(); + $notification_count = $notification_center->get_notification_count(); + + // Add main page. + /* translators: Hidden accessibility text; %s: number of notifications. */ + $notifications = sprintf( _n( '%s notification', '%s notifications', $notification_count, 'wordpress-seo' ), number_format_i18n( $notification_count ) ); + + return sprintf( '%2$s', $notification_count, $notifications ); + } + + /** + * Returns the capability that is required to manage all options. + * + * @return string Capability to check against. + */ + protected function get_manage_capability() { + return 'wpseo_manage_options'; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/menu/class-base-menu.php b/html/wp-content/plugins/wordpress-seo/admin/menu/class-base-menu.php new file mode 100644 index 0000000..524ce4b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/menu/class-base-menu.php @@ -0,0 +1,283 @@ +menu = $menu; + } + + /** + * Returns the list of registered submenu pages. + * + * @return array List of registered submenu pages. + */ + abstract public function get_submenu_pages(); + + /** + * Creates a submenu formatted array. + * + * @param string $page_title Page title to use. + * @param string $page_slug Page slug to use. + * @param callable|null $callback Optional. Callback which handles the page request. + * @param callable[]|null $hook Optional. Hook to trigger when the page is registered. + * + * @return array Formatted submenu. + */ + protected function get_submenu_page( $page_title, $page_slug, $callback = null, $hook = null ) { + $callback ??= $this->get_admin_page_callback(); + + return [ + $this->get_page_identifier(), + '', + $page_title, + $this->get_manage_capability(), + $page_slug, + $callback, + $hook, + ]; + } + + /** + * Registers submenu pages as menu pages. + * + * This method should only be used if the user does not have the required capabilities + * to access the parent menu page. + * + * @param array $submenu_pages List of submenu pages to register. + * + * @return void + */ + protected function register_menu_pages( $submenu_pages ) { + if ( ! is_array( $submenu_pages ) || empty( $submenu_pages ) ) { + return; + } + + // Loop through submenu pages and add them. + array_walk( $submenu_pages, [ $this, 'register_menu_page' ] ); + } + + /** + * Registers submenu pages. + * + * @param array $submenu_pages List of submenu pages to register. + * + * @return void + */ + protected function register_submenu_pages( $submenu_pages ) { + if ( ! is_array( $submenu_pages ) || empty( $submenu_pages ) ) { + return; + } + + // Loop through submenu pages and add them. + array_walk( $submenu_pages, [ $this, 'register_submenu_page' ] ); + } + + /** + * Registers a submenu page as a menu page. + * + * This method should only be used if the user does not have the required capabilities + * to access the parent menu page. + * + * @param array $submenu_page { + * Submenu page definition. + * + * @type string $0 Parent menu page slug. + * @type string $1 Page title, currently unused. + * @type string $2 Title to display in the menu. + * @type string $3 Required capability to access the page. + * @type string $4 Page slug. + * @type callable $5 Callback to run when the page is rendered. + * @type array $6 Optional. List of callbacks to run when the page is loaded. + * } + * + * @return void + */ + protected function register_menu_page( $submenu_page ) { + + // If the submenu page requires the general manage capability, it must be added as an actual submenu page. + if ( $submenu_page[3] === $this->get_manage_capability() ) { + return; + } + + $page_title = 'Yoast SEO: ' . $submenu_page[2]; + + // Register submenu page as menu page. + $hook_suffix = add_menu_page( + $page_title, + $submenu_page[2], + $submenu_page[3], + $submenu_page[4], + $submenu_page[5], + $this->get_icon_svg(), + 99, + ); + + // If necessary, add hooks for the submenu page. + if ( isset( $submenu_page[6] ) && ( is_array( $submenu_page[6] ) ) ) { + $this->add_page_hooks( $hook_suffix, $submenu_page[6] ); + } + } + + /** + * Registers a submenu page. + * + * This method will override the capability of the page to automatically use the + * general manage capability. Use the `register_menu_page()` method if the submenu + * page should actually use a different capability. + * + * @param array $submenu_page { + * Submenu page definition. + * + * @type string $0 Parent menu page slug. + * @type string $1 Page title, currently unused. + * @type string $2 Title to display in the menu. + * @type string $3 Required capability to access the page. + * @type string $4 Page slug. + * @type callable $5 Callback to run when the page is rendered. + * @type array $6 Optional. List of callbacks to run when the page is loaded. + * } + * + * @return void + */ + protected function register_submenu_page( $submenu_page ) { + $page_title = $submenu_page[2]; + + /* + * Handle the Google Search Console special case by passing a fake parent + * page slug. This way, the sub-page is stil registered and can be accessed + * directly. Its menu item won't be displayed. + */ + if ( $submenu_page[4] === 'wpseo_search_console' ) { + // Set the parent page slug to a non-existing one. + $submenu_page[0] = 'wpseo_fake_menu_parent_page_slug'; + } + + $page_title .= ' - Yoast SEO'; + + // Register submenu page. + $hook_suffix = add_submenu_page( + $submenu_page[0], + $page_title, + $submenu_page[2], + $submenu_page[3], + $submenu_page[4], + $submenu_page[5], + ); + + // If necessary, add hooks for the submenu page. + if ( isset( $submenu_page[6] ) && ( is_array( $submenu_page[6] ) ) ) { + $this->add_page_hooks( $hook_suffix, $submenu_page[6] ); + } + } + + /** + * Adds hook callbacks for a given admin page hook suffix. + * + * @param string $hook_suffix Admin page hook suffix, as returned by `add_menu_page()` + * or `add_submenu_page()`. + * @param array $callbacks Callbacks to add. + * + * @return void + */ + protected function add_page_hooks( $hook_suffix, array $callbacks ) { + foreach ( $callbacks as $callback ) { + add_action( 'load-' . $hook_suffix, $callback ); + } + } + + /** + * Gets the main admin page identifier. + * + * @return string Admin page identifier. + */ + protected function get_page_identifier() { + return $this->menu->get_page_identifier(); + } + + /** + * Checks whether the current user has capabilities to manage all options. + * + * @return bool True if capabilities are sufficient, false otherwise. + */ + protected function check_manage_capability() { + return WPSEO_Capability_Utils::current_user_can( $this->get_manage_capability() ); + } + + /** + * Returns the capability that is required to manage all options. + * + * @return string Capability to check against. + */ + abstract protected function get_manage_capability(); + + /** + * Returns the page handler callback. + * + * @return array Callback page handler. + */ + protected function get_admin_page_callback() { + return [ $this->menu, 'load_page' ]; + } + + /** + * Returns the page title to use for the licenses page. + * + * @deprecated 25.5 + * @codeCoverageIgnore + * + * @return string The title for the license page. + */ + protected function get_license_page_title() { + static $title = null; + + _deprecated_function( __METHOD__, 'Yoast SEO 25.5' ); + + $title ??= __( 'Upgrades', 'wordpress-seo' ); + + if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-promotion' ) && ! YoastSEO()->helpers->product->is_premium() ) { + $title = __( 'Upgrades', 'wordpress-seo' ) . '' . __( '30% OFF', 'wordpress-seo' ) . ''; + } + + return $title; + } + + /** + * Returns a base64 URL for the svg for use in the menu. + * + * @param bool $base64 Whether or not to return base64'd output. + * + * @return string SVG icon. + */ + public function get_icon_svg( $base64 = true ) { + $svg = ''; + + if ( $base64 ) { + //phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- This encoding is intended. + return 'data:image/svg+xml;base64,' . base64_encode( $svg ); + } + + return $svg; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/menu/class-menu.php b/html/wp-content/plugins/wordpress-seo/admin/menu/class-menu.php new file mode 100644 index 0000000..56b98f7 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/menu/class-menu.php @@ -0,0 +1,91 @@ +register_hooks(); + + if ( WPSEO_Utils::is_plugin_network_active() ) { + $network_admin_menu = new WPSEO_Network_Admin_Menu( $this ); + $network_admin_menu->register_hooks(); + } + + $capability_normalizer = new WPSEO_Submenu_Capability_Normalize(); + $capability_normalizer->register_hooks(); + } + + /** + * Returns the main menu page identifier. + * + * @return string Page identifier to use. + */ + public function get_page_identifier() { + return self::PAGE_IDENTIFIER; + } + + /** + * Loads the requested admin settings page. + * + * @return void + */ + public function load_page() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $page = sanitize_text_field( wp_unslash( $_GET['page'] ) ); + $this->show_page( $page ); + } + } + + /** + * Shows an admin settings page. + * + * @param string $page Page to display. + * + * @return void + */ + protected function show_page( $page ) { + switch ( $page ) { + case 'wpseo_tools': + require_once WPSEO_PATH . 'admin/pages/tools.php'; + break; + + case 'wpseo_files': + require_once WPSEO_PATH . 'admin/views/tool-file-editor.php'; + break; + + default: + break; + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/menu/class-network-admin-menu.php b/html/wp-content/plugins/wordpress-seo/admin/menu/class-network-admin-menu.php new file mode 100644 index 0000000..71890d9 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/menu/class-network-admin-menu.php @@ -0,0 +1,102 @@ +check_manage_capability() ) { + return; + } + + add_menu_page( + __( 'Network Settings', 'wordpress-seo' ) . ' - Yoast SEO', + 'Yoast SEO', + $this->get_manage_capability(), + $this->get_page_identifier(), + [ $this, 'network_config_page' ], + $this->get_icon_svg(), + ); + + $submenu_pages = $this->get_submenu_pages(); + $this->register_submenu_pages( $submenu_pages ); + } + + /** + * Returns the list of registered submenu pages. + * + * @return array List of registered submenu pages. + */ + public function get_submenu_pages() { + + // Submenu pages. + $submenu_pages = [ + $this->get_submenu_page( + __( 'General', 'wordpress-seo' ), + $this->get_page_identifier(), + [ $this, 'network_config_page' ], + ), + ]; + + if ( WPSEO_Utils::allow_system_file_edit() === true ) { + $submenu_pages[] = $this->get_submenu_page( __( 'Edit Files', 'wordpress-seo' ), 'wpseo_files' ); + } + + /** + * Filter: 'wpseo_network_submenu_pages' - Collects all network submenus that need to be shown. + * + * @internal For internal Yoast SEO use only. + * + * @param array $submenu_pages List with all submenu pages. + */ + return (array) apply_filters( 'wpseo_network_submenu_pages', $submenu_pages ); + } + + /** + * Loads the form for the network configuration page. + * + * @return void + */ + public function network_config_page() { + require_once WPSEO_PATH . 'admin/pages/network.php'; + } + + /** + * Checks whether the current user has capabilities to manage all options. + * + * @return bool True if capabilities are sufficient, false otherwise. + */ + protected function check_manage_capability() { + return current_user_can( $this->get_manage_capability() ); + } + + /** + * Returns the capability that is required to manage all options. + * + * @return string Capability to check against. + */ + protected function get_manage_capability() { + return 'wpseo_manage_network_options'; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/menu/class-replacevar-editor.php b/html/wp-content/plugins/wordpress-seo/admin/menu/class-replacevar-editor.php new file mode 100644 index 0000000..fe69d28 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/menu/class-replacevar-editor.php @@ -0,0 +1,159 @@ + true, + 'label_title' => '', + 'label_description' => '', + 'description_placeholder' => '', + 'has_new_badge' => false, + 'is_disabled' => false, + 'has_premium_badge' => false, + ], + ); + + $this->validate_arguments( $arguments ); + + $this->yform = $yform; + $this->arguments = [ + 'title' => (string) $arguments['title'], + 'description' => (string) $arguments['description'], + 'page_type_recommended' => (string) $arguments['page_type_recommended'], + 'page_type_specific' => (string) $arguments['page_type_specific'], + 'paper_style' => (bool) $arguments['paper_style'], + 'label_title' => (string) $arguments['label_title'], + 'label_description' => (string) $arguments['label_description'], + 'description_placeholder' => (string) $arguments['description_placeholder'], + 'has_new_badge' => (bool) $arguments['has_new_badge'], + 'is_disabled' => (bool) $arguments['is_disabled'], + 'has_premium_badge' => (bool) $arguments['has_premium_badge'], + ]; + } + + /** + * Renders a div for the react application to mount to, and hidden inputs where + * the app should store it's value so they will be properly saved when the form + * is submitted. + * + * @return void + */ + public function render() { + $this->yform->hidden( $this->arguments['title'], $this->arguments['title'] ); + $this->yform->hidden( $this->arguments['description'], $this->arguments['description'] ); + + printf( + '
            ', + esc_attr( $this->arguments['title'] ), + esc_attr( $this->arguments['description'] ), + esc_attr( $this->arguments['page_type_recommended'] ), + esc_attr( $this->arguments['page_type_specific'] ), + esc_attr( $this->arguments['paper_style'] ), + esc_attr( $this->arguments['label_title'] ), + esc_attr( $this->arguments['label_description'] ), + esc_attr( $this->arguments['description_placeholder'] ), + esc_attr( $this->arguments['has_new_badge'] ), + esc_attr( $this->arguments['is_disabled'] ), + esc_attr( $this->arguments['has_premium_badge'] ), + ); + } + + /** + * Validates the replacement variable editor arguments. + * + * @param array $arguments The arguments to validate. + * + * @return void + * + * @throws InvalidArgumentException Thrown when not all required arguments are present. + */ + protected function validate_arguments( array $arguments ) { + $required_arguments = [ + 'title', + 'description', + 'page_type_recommended', + 'page_type_specific', + 'paper_style', + ]; + + foreach ( $required_arguments as $field_name ) { + if ( ! array_key_exists( $field_name, $arguments ) ) { + throw new InvalidArgumentException( + sprintf( + /* translators: %1$s expands to the missing field name. */ + __( 'Not all required fields are given. Missing field %1$s', 'wordpress-seo' ), + $field_name, + ), + ); + } + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/menu/class-replacevar-field.php b/html/wp-content/plugins/wordpress-seo/admin/menu/class-replacevar-field.php new file mode 100644 index 0000000..b201a0e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/menu/class-replacevar-field.php @@ -0,0 +1,88 @@ +yform = $yform; + $this->field_id = $field_id; + $this->label = $label; + $this->page_type_recommended = $page_type_recommended; + $this->page_type_specific = $page_type_specific; + } + + /** + * Renders a div for the react application to mount to, and hidden inputs where + * the app should store it's value so they will be properly saved when the form + * is submitted. + * + * @return void + */ + public function render() { + $this->yform->hidden( $this->field_id, $this->field_id ); + + printf( + '
            ', + esc_attr( $this->field_id ), + esc_attr( $this->label ), + esc_attr( $this->page_type_recommended ), + esc_attr( $this->page_type_specific ), + ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/menu/class-submenu-capability-normalize.php b/html/wp-content/plugins/wordpress-seo/admin/menu/class-submenu-capability-normalize.php new file mode 100644 index 0000000..6e35718 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/menu/class-submenu-capability-normalize.php @@ -0,0 +1,41 @@ + $submenu_page ) { + if ( $submenu_page[3] === 'manage_options' ) { + $submenu_pages[ $index ][3] = 'wpseo_manage_options'; + } + } + + return $submenu_pages; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-abstract-sectioned-metabox-tab.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-abstract-sectioned-metabox-tab.php new file mode 100644 index 0000000..732486e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-abstract-sectioned-metabox-tab.php @@ -0,0 +1,97 @@ + '', + 'link_class' => '', + 'link_aria_label' => '', + ]; + + $options = array_merge( $default_options, $options ); + + $this->name = $name; + + $this->link_content = $link_content; + $this->link_title = $options['link_title']; + $this->link_class = $options['link_class']; + $this->link_aria_label = $options['link_aria_label']; + } + + /** + * Outputs the section link if any section has been added. + * + * @return void + */ + public function display_link() { + if ( $this->has_sections() ) { + printf( + '
          • %5$s
          • ', + esc_attr( $this->name ), + esc_attr( $this->link_class ), + ( $this->link_title !== '' ) ? ' title="' . esc_attr( $this->link_title ) . '"' : '', + ( $this->link_aria_label !== '' ) ? ' aria-label="' . esc_attr( $this->link_aria_label ) . '"' : '', + $this->link_content, + ); + } + } + + /** + * Checks whether the tab has any sections. + * + * @return bool Whether the tab has any sections + */ + abstract protected function has_sections(); +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-inclusive-language.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-inclusive-language.php new file mode 100644 index 0000000..1fe2a1f --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-inclusive-language.php @@ -0,0 +1,58 @@ +is_globally_enabled() && $this->is_user_enabled() && $this->is_current_version_supported() + && YoastSEO()->helpers->language->has_inclusive_language_support( WPSEO_Language_Utils::get_language( get_locale() ) ); + } + + /** + * Whether or not this analysis is enabled by the user. + * + * @return bool Whether or not this analysis is enabled by the user. + */ + public function is_user_enabled() { + return ! get_the_author_meta( 'wpseo_inclusive_language_analysis_disable', get_current_user_id() ); + } + + /** + * Whether or not this analysis is enabled globally. + * + * @return bool Whether or not this analysis is enabled globally. + */ + public function is_globally_enabled() { + return WPSEO_Options::get( 'inclusive_language_analysis_active', false ); + } + + /** + * Whether the inclusive language analysis should be loaded in Free. + * + * It should always be loaded when Premium is not active. If Premium is active, it depends on the version. Some Premium + * versions also have inclusive language code (when it was still a Premium only feature) which would result in rendering + * the analysis twice. In those cases, the analysis should be only loaded from the Premium side. + * + * @return bool Whether or not the inclusive language analysis should be loaded. + */ + private function is_current_version_supported() { + $is_premium = YoastSEO()->helpers->product->is_premium(); + $premium_version = YoastSEO()->helpers->product->get_premium_version(); + + return ! $is_premium + || version_compare( $premium_version, '19.6-RC0', '>=' ) + || version_compare( $premium_version, '19.2', '==' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-readability.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-readability.php new file mode 100644 index 0000000..65345c4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-readability.php @@ -0,0 +1,39 @@ +is_globally_enabled() && $this->is_user_enabled(); + } + + /** + * Whether or not this analysis is enabled by the user. + * + * @return bool Whether or not this analysis is enabled by the user. + */ + public function is_user_enabled() { + return ! get_the_author_meta( 'wpseo_content_analysis_disable', get_current_user_id() ); + } + + /** + * Whether or not this analysis is enabled globally. + * + * @return bool Whether or not this analysis is enabled globally. + */ + public function is_globally_enabled() { + return WPSEO_Options::get( 'content_analysis_active', true ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-seo.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-seo.php new file mode 100644 index 0000000..8225def --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-analysis-seo.php @@ -0,0 +1,39 @@ +is_globally_enabled() && $this->is_user_enabled(); + } + + /** + * Whether or not this analysis is enabled by the user. + * + * @return bool Whether or not this analysis is enabled by the user. + */ + public function is_user_enabled() { + return ! get_the_author_meta( 'wpseo_keyword_analysis_disable', get_current_user_id() ); + } + + /** + * Whether or not this analysis is enabled globally. + * + * @return bool Whether or not this analysis is enabled globally. + */ + public function is_globally_enabled() { + return WPSEO_Options::get( 'keyword_analysis_active', true ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-collapsible.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-collapsible.php new file mode 100644 index 0000000..2e7502b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-collapsible.php @@ -0,0 +1,84 @@ +name = $name; + $this->content = $content; + $this->link_content = $link_content; + } + + /** + * Returns the html for the tab link. + * + * @return string + */ + public function link() { + return $this->link_content; + } + + /** + * Returns the html for the tab content. + * + * @return string + */ + public function content() { + $collapsible_paper = new WPSEO_Paper_Presenter( + $this->link(), + null, + [ + 'content' => $this->content, + 'collapsible' => true, + 'class' => 'metabox wpseo-form wpseo-collapsible-container', + 'paper_id' => 'collapsible-' . $this->name, + ], + ); + + return $collapsible_paper->get_output(); + } + + /** + * Returns the collapsible's unique identifier. + * + * @return string + */ + public function get_name() { + return $this->name; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-collapsibles-section.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-collapsibles-section.php new file mode 100644 index 0000000..14e8638 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-collapsibles-section.php @@ -0,0 +1,65 @@ +collapsibles = $collapsibles; + } + + /** + * Outputs the section content if any tab has been added. + * + * @return void + */ + public function display_content() { + if ( $this->has_sections() ) { + printf( '
            ', esc_attr( 'wpseo-meta-section-' . $this->name ) ); + echo '
            '; + + add_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_forms' ] ); + add_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_a11y' ] ); + foreach ( $this->collapsibles as $collapsible ) { + echo wp_kses_post( $collapsible->content() ); + } + remove_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_forms' ] ); + remove_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_a11y' ] ); + + echo '
            '; + } + } + + /** + * Checks whether the tab has any sections. + * + * @return bool Whether the tab has any sections + */ + protected function has_sections() { + return ! empty( $this->collapsibles ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-editor.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-editor.php new file mode 100644 index 0000000..4d68917 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-editor.php @@ -0,0 +1,85 @@ +special_styles(); + $inside_editor = $styles['inside-editor']; + + $asset_location = new WPSEO_Admin_Asset_SEO_Location( WPSEO_FILE ); + $url = $asset_location->get_url( $inside_editor, WPSEO_Admin_Asset::TYPE_CSS ); + + if ( $css_files === '' ) { + $css_files = $url; + } + else { + $css_files .= ',' . $url; + } + + return $css_files; + } + + /** + * Enqueues the CSS to use in the TinyMCE editor. + * + * @return void + */ + public function add_editor_styles() { + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_style( 'inside-editor' ); + } + + /** + * Adds a custom element to the tinyMCE editor that we need for marking the content. + * + * @param array $tinymce_config The tinyMCE config as configured by WordPress. + * + * @return array The new tinyMCE config with our added custom elements. + */ + public function add_custom_element( $tinymce_config ) { + if ( ! empty( $tinymce_config['custom_elements'] ) ) { + $custom_elements = $tinymce_config['custom_elements']; + + $custom_elements .= ',~yoastmark'; + } + else { + $custom_elements = '~yoastmark'; + } + + $tinymce_config['custom_elements'] = $custom_elements; + + return $tinymce_config; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-form-tab.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-form-tab.php new file mode 100644 index 0000000..395dbc4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-form-tab.php @@ -0,0 +1,135 @@ + '', + 'link_class' => '', + 'link_title' => '', + 'link_aria_label' => '', + 'single' => false, + ]; + + $options = array_merge( $default_options, $options ); + + $this->name = $name; + $this->content = $content; + $this->link_content = $link_content; + $this->tab_class = $options['tab_class']; + $this->link_class = $options['link_class']; + $this->link_title = $options['link_title']; + $this->link_aria_label = $options['link_aria_label']; + $this->single = $options['single']; + } + + /** + * Returns the html for the tab link. + * + * @return string + */ + public function link() { + + $html = '
          • %6$s
          • '; + + if ( $this->single ) { + $html = '
          • %6$s
          • '; + } + + return sprintf( + $html, + esc_attr( $this->name ), + ( $this->tab_class !== '' ) ? ' ' . esc_attr( $this->tab_class ) : '', + ( $this->link_class !== '' ) ? ' ' . esc_attr( $this->link_class ) : '', + ( $this->link_title !== '' ) ? ' title="' . esc_attr( $this->link_title ) . '"' : '', + ( $this->link_aria_label !== '' ) ? ' aria-label="' . esc_attr( $this->link_aria_label ) . '"' : '', + $this->link_content, + ); + } + + /** + * Returns the html for the tab content. + * + * @return string + */ + public function content() { + return sprintf( + '
            %3$s
            ', + esc_attr( 'wpseo_' . $this->name ), + esc_attr( $this->name ), + $this->content, + ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-null-tab.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-null-tab.php new file mode 100644 index 0000000..1e31fd2 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-null-tab.php @@ -0,0 +1,30 @@ +name = $name; + $this->content = $content; + $default_options = [ + 'link_class' => '', + 'link_aria_label' => '', + 'content_class' => 'wpseo-form', + ]; + $options = wp_parse_args( $options, $default_options ); + $this->link_content = $link_content; + $this->link_class = $options['link_class']; + $this->link_aria_label = $options['link_aria_label']; + $this->content_class = $options['content_class']; + } + + /** + * Outputs the section link. + * + * @return void + */ + public function display_link() { + printf( + '
          • %4$s
          • ', + esc_attr( $this->name ), + esc_attr( $this->link_class ), + ( $this->link_aria_label !== '' ) ? ' aria-label="' . esc_attr( $this->link_aria_label ) . '"' : '', + $this->link_content, + ); + } + + /** + * Outputs the section content. + * + * @return void + */ + public function display_content() { + $html = sprintf( + '
            ', + esc_attr( $this->name ), + esc_attr( $this->content_class ), + ); + $html .= $this->content; + $html .= '
            '; + echo $html; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-inclusive-language.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-inclusive-language.php new file mode 100644 index 0000000..291cd46 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-inclusive-language.php @@ -0,0 +1,46 @@ + +
            %2$s
            ', + esc_attr( $this->name ), + esc_html__( 'Inclusive language', 'wordpress-seo' ), + ); + } + + /** + * Outputs the section content. + * + * @return void + */ + public function display_content() { + printf( + '
            ', + esc_attr( $this->name ), + ); + echo '
            ', '
            '; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-react.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-react.php new file mode 100644 index 0000000..9e83a8d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-react.php @@ -0,0 +1,118 @@ +name = $name; + $this->content = $content; + + $default_options = [ + 'link_class' => '', + 'link_aria_label' => '', + 'html_after' => '', + ]; + + $options = wp_parse_args( $options, $default_options ); + + $this->link_content = $link_content; + $this->link_class = $options['link_class']; + $this->link_aria_label = $options['link_aria_label']; + $this->html_after = $options['html_after']; + } + + /** + * Outputs the section link. + * + * @return void + */ + public function display_link() { + printf( + '
          • %4$s
          • ', + esc_attr( $this->name ), + esc_attr( $this->link_class ), + ( $this->link_aria_label !== '' ) ? ' aria-label="' . esc_attr( $this->link_aria_label ) . '"' : '', + wp_kses_post( $this->link_content ), + ); + } + + /** + * Outputs the section content. + * + * @return void + */ + public function display_content() { + add_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_forms' ] ); + add_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_a11y' ] ); + + printf( + '
            ', + esc_attr( $this->name ), + ); + echo wp_kses_post( $this->content ); + echo '
            '; + echo wp_kses_post( $this->html_after ); + echo '
            '; + + remove_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_forms' ] ); + remove_filter( 'wp_kses_allowed_html', [ 'WPSEO_Utils', 'extend_kses_post_with_a11y' ] ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-readability.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-readability.php new file mode 100644 index 0000000..0d1b672 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox-section-readability.php @@ -0,0 +1,46 @@ + +
            %2$s
            ', + esc_attr( $this->name ), + esc_html__( 'Readability', 'wordpress-seo' ), + ); + } + + /** + * Outputs the section content. + * + * @return void + */ + public function display_content() { + printf( + '
            ', + esc_attr( $this->name ), + ); + echo '
            ', '
            '; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox.php new file mode 100644 index 0000000..a671adc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/class-metabox.php @@ -0,0 +1,1178 @@ +is_internet_explorer() ) { + add_action( 'add_meta_boxes', [ $this, 'internet_explorer_metabox' ] ); + + return; + } + + add_action( 'add_meta_boxes', [ $this, 'add_meta_box' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] ); + add_action( 'wp_insert_post', [ $this, 'save_postdata' ] ); + add_action( 'edit_attachment', [ $this, 'save_postdata' ] ); + add_action( 'add_attachment', [ $this, 'save_postdata' ] ); + + $this->social_is_enabled = WPSEO_Options::get( 'opengraph', false, [ 'wpseo_social' ] ) || WPSEO_Options::get( 'twitter', false, [ 'wpseo_social' ] ); + $this->is_advanced_metadata_enabled = WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta', null, [ 'wpseo' ] ) === false; + + $this->seo_analysis = new WPSEO_Metabox_Analysis_SEO(); + $this->readability_analysis = new WPSEO_Metabox_Analysis_Readability(); + $this->inclusive_language_analysis = new WPSEO_Metabox_Analysis_Inclusive_Language(); + } + + /** + * Checks whether the request comes from an IE 11 browser. + * + * @return bool Whether the request comes from an IE 11 browser. + */ + public static function is_internet_explorer() { + if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) { + return false; + } + + $user_agent = sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ); + + if ( stripos( $user_agent, 'Trident/7.0' ) === false ) { + return false; + } + + return true; + } + + /** + * Adds an alternative metabox for internet explorer users. + * + * @return void + */ + public function internet_explorer_metabox() { + $post_types = WPSEO_Post_Type::get_accessible_post_types(); + $post_types = array_filter( $post_types, [ $this, 'display_metabox' ] ); + + if ( ! is_array( $post_types ) || $post_types === [] ) { + return; + } + + $product_title = $this->get_product_title(); + + foreach ( $post_types as $post_type ) { + add_filter( "postbox_classes_{$post_type}_wpseo_meta", [ $this, 'wpseo_metabox_class' ] ); + + add_meta_box( + 'wpseo_meta', + $product_title, + [ $this, 'render_internet_explorer_notice' ], + $post_type, + 'normal', + apply_filters( 'wpseo_metabox_prio', 'high' ), + [ '__block_editor_compatible_meta_box' => true ], + ); + } + } + + /** + * Renders the content for the internet explorer metabox. + * + * @return void + */ + public function render_internet_explorer_notice() { + $content = sprintf( + /* translators: 1: Link start tag to the Firefox website, 2: Link start tag to the Chrome website, 3: Link start tag to the Edge website, 4: Link closing tag. */ + esc_html__( 'The browser you are currently using is unfortunately rather dated. Since we strive to give you the best experience possible, we no longer support this browser. Instead, please use %1$sFirefox%4$s, %2$sChrome%4$s or %3$sMicrosoft Edge%4$s.', 'wordpress-seo' ), + '', + '', + '', + '', + ); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above. + echo new Alert_Presenter( $content ); + } + + /** + * Translates text strings for use in the meta box. + * + * IMPORTANT: if you want to add a new string (option) somewhere, make sure you add that array key to + * the main meta box definition array in the class WPSEO_Meta() as well!!!! + * + * @deprecated 23.5 + * @codeCoverageIgnore + * + * @return void + */ + public static function translate_meta_boxes() { + _deprecated_function( __METHOD__, 'Yoast SEO 23.5' ); + + WPSEO_Meta::$meta_fields['general']['title']['title'] = __( 'SEO title', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['general']['metadesc']['title'] = __( 'Meta description', 'wordpress-seo' ); + + /* translators: %s expands to the post type name. */ + WPSEO_Meta::$meta_fields['advanced']['meta-robots-noindex']['title'] = __( 'Allow search engines to show this %s in search results?', 'wordpress-seo' ); + if ( (string) get_option( 'blog_public' ) === '0' ) { + WPSEO_Meta::$meta_fields['advanced']['meta-robots-noindex']['description'] = '' . __( 'Warning: even though you can set the meta robots setting here, the entire site is set to noindex in the sitewide privacy settings, so these settings won\'t have an effect.', 'wordpress-seo' ) . ''; + } + /* translators: %1$s expands to Yes or No, %2$s expands to the post type name.*/ + WPSEO_Meta::$meta_fields['advanced']['meta-robots-noindex']['options']['0'] = __( 'Default for %2$s, currently: %1$s', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-noindex']['options']['2'] = __( 'Yes', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-noindex']['options']['1'] = __( 'No', 'wordpress-seo' ); + + /* translators: %1$s expands to the post type name.*/ + WPSEO_Meta::$meta_fields['advanced']['meta-robots-nofollow']['title'] = __( 'Should search engines follow links on this %1$s?', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-nofollow']['options']['0'] = __( 'Yes', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-nofollow']['options']['1'] = __( 'No', 'wordpress-seo' ); + + WPSEO_Meta::$meta_fields['advanced']['meta-robots-adv']['title'] = __( 'Meta robots advanced', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-adv']['description'] = __( 'If you want to apply advanced meta robots settings for this page, please define them in the following field.', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-adv']['options']['noimageindex'] = __( 'No Image Index', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-adv']['options']['noarchive'] = __( 'No Archive', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['meta-robots-adv']['options']['nosnippet'] = __( 'No Snippet', 'wordpress-seo' ); + + WPSEO_Meta::$meta_fields['advanced']['bctitle']['title'] = __( 'Breadcrumbs Title', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['bctitle']['description'] = __( 'Title to use for this page in breadcrumb paths', 'wordpress-seo' ); + + WPSEO_Meta::$meta_fields['advanced']['canonical']['title'] = __( 'Canonical URL', 'wordpress-seo' ); + + WPSEO_Meta::$meta_fields['advanced']['canonical']['description'] = sprintf( + /* translators: 1: link open tag; 2: link close tag. */ + __( 'The canonical URL that this page should point to. Leave empty to default to permalink. %1$sCross domain canonical%2$s supported too.', 'wordpress-seo' ), + '', + WPSEO_Admin_Utils::get_new_tab_message() . '', + ); + + WPSEO_Meta::$meta_fields['advanced']['redirect']['title'] = __( '301 Redirect', 'wordpress-seo' ); + WPSEO_Meta::$meta_fields['advanced']['redirect']['description'] = __( 'The URL that this page should redirect to.', 'wordpress-seo' ); + + do_action_deprecated( 'wpseo_tab_translate', [], 'Yoast SEO 23.5', '', 'WPSEO_Metabox::translate_meta_boxes is deprecated.' ); + } + + /** + * Determines whether the metabox should be shown for the passed identifier. + * + * By default the check is done for post types, but can also be used for taxonomies. + * + * @param string|null $identifier The identifier to check. + * @param string $type The type of object to check. Defaults to post_type. + * + * @return bool Whether or not the metabox should be displayed. + */ + public function display_metabox( $identifier = null, $type = 'post_type' ) { + return WPSEO_Utils::is_metabox_active( $identifier, $type ); + } + + /** + * Adds the Yoast SEO meta box to the edit boxes in the edit post, page, + * attachment, and custom post types pages. + * + * @return void + */ + public function add_meta_box() { + $post_types = WPSEO_Post_Type::get_accessible_post_types(); + $post_types = array_filter( $post_types, [ $this, 'display_metabox' ] ); + + if ( ! is_array( $post_types ) || $post_types === [] ) { + return; + } + + $product_title = $this->get_product_title(); + + foreach ( $post_types as $post_type ) { + add_filter( "postbox_classes_{$post_type}_wpseo_meta", [ $this, 'wpseo_metabox_class' ] ); + + add_meta_box( + 'wpseo_meta', + $product_title, + [ $this, 'meta_box' ], + $post_type, + 'normal', + apply_filters( 'wpseo_metabox_prio', 'high' ), + [ '__block_editor_compatible_meta_box' => true ], + ); + } + } + + /** + * Adds CSS classes to the meta box. + * + * @param string[] $classes An array of postbox CSS classes. + * + * @return string[] List of classes that will be applied to the editbox container. + */ + public function wpseo_metabox_class( $classes ) { + $classes[] = 'yoast wpseo-metabox'; + + return $classes; + } + + /** + * Passes variables to js for use with the post-scraper. + * + * @return array|bool|int> + */ + public function get_metabox_script_data() { + $permalink = $this->get_permalink(); + + $post_formatter = new WPSEO_Metabox_Formatter( + new WPSEO_Post_Metabox_Formatter( $this->get_metabox_post(), [], $permalink ), + ); + + $values = $post_formatter->get_values(); + /** This filter is documented in admin/filters/class-cornerstone-filter.php. */ + $post_types = apply_filters( 'wpseo_cornerstone_post_types', WPSEO_Post_Type::get_accessible_post_types() ); + if ( $values['cornerstoneActive'] && ! in_array( $this->get_metabox_post()->post_type, $post_types, true ) ) { + $values['cornerstoneActive'] = false; + } + + if ( $values['semrushIntegrationActive'] && $this->post->post_type === 'attachment' ) { + $values['semrushIntegrationActive'] = 0; + } + + if ( $values['wincherIntegrationActive'] && $this->post->post_type === 'attachment' ) { + $values['wincherIntegrationActive'] = 0; + } + + return $values; + } + + /** + * Determines whether or not the current post type has registered taxonomies. + * + * @return bool Whether the current post type has taxonomies. + */ + private function current_post_type_has_taxonomies() { + $post_taxonomies = get_object_taxonomies( get_post_type() ); + + return ! empty( $post_taxonomies ); + } + + /** + * Determines the scope based on the post type. + * This can be used by the replacevar plugin to determine if a replacement needs to be executed. + * + * @return string String describing the current scope. + */ + private function determine_scope() { + if ( $this->get_metabox_post()->post_type === 'page' ) { + return 'page'; + } + + return 'post'; + } + + /** + * Outputs the meta box. + * + * @return void + */ + public function meta_box() { + $this->render_hidden_fields(); + $this->render_tabs(); + } + + /** + * Renders the metabox hidden fields. + * + * @return void + */ + protected function render_hidden_fields() { + wp_nonce_field( 'yoast_free_metabox', 'yoast_free_metabox_nonce' ); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in class. + echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'general' ); + + if ( $this->is_advanced_metadata_enabled ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in class. + echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'advanced' ); + } + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in class. + echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'schema', $this->get_metabox_post()->post_type ); + + if ( $this->social_is_enabled ) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped in class. + echo new Meta_Fields_Presenter( $this->get_metabox_post(), 'social' ); + } + + /** + * Filter: 'wpseo_content_meta_section_content' - Allow filtering the metabox content before outputting. + * + * @param string $post_content The metabox content string. + */ + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output should be escaped in the filter. + echo apply_filters( 'wpseo_content_meta_section_content', '' ); + } + + /** + * Renders the metabox tabs. + * + * @return void + */ + protected function render_tabs() { + echo '
            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: $this->get_product_title() returns a hard-coded string. + printf( '
              ', $this->get_product_title() ); + + $tabs = $this->get_tabs(); + + foreach ( $tabs as $tab ) { + if ( $tab->name === 'premium' ) { + continue; + } + + $tab->display_link(); + } + + echo '
            '; + + foreach ( $tabs as $tab ) { + $tab->display_content(); + } + + echo '
            '; + } + + /** + * Returns the relevant metabox tabs for the current view. + * + * @return WPSEO_Metabox_Section[] + */ + private function get_tabs() { + $tabs = []; + + $label = __( 'SEO', 'wordpress-seo' ); + if ( $this->seo_analysis->is_enabled() ) { + $label = '' . $label; + } + $tabs[] = new WPSEO_Metabox_Section_React( 'content', $label ); + + if ( $this->readability_analysis->is_enabled() ) { + $tabs[] = new WPSEO_Metabox_Section_Readability(); + } + + if ( $this->inclusive_language_analysis->is_enabled() ) { + $tabs[] = new WPSEO_Metabox_Section_Inclusive_Language(); + } + + if ( $this->is_advanced_metadata_enabled ) { + $tabs[] = new WPSEO_Metabox_Section_React( + 'schema', + '' . __( 'Schema', 'wordpress-seo' ), + '', + ); + } + + if ( $this->social_is_enabled ) { + $tabs[] = new WPSEO_Metabox_Section_React( + 'social', + '' . __( 'Social', 'wordpress-seo' ), + '', + [ + 'html_after' => '
            ', + ], + ); + } + + $tabs = array_merge( $tabs, $this->get_additional_tabs() ); + + return $tabs; + } + + /** + * Returns the metabox tabs that have been added by other plugins. + * + * @return WPSEO_Metabox_Section_Additional[] + */ + protected function get_additional_tabs() { + $tabs = []; + + /** + * Private filter: 'yoast_free_additional_metabox_sections'. + * + * Meant for internal use only. Allows adding additional tabs to the Yoast SEO metabox. + * + * @since 11.9 + * + * @param array[] $tabs { + * An array of arrays with tab specifications. + * + * @type array $tab { + * A tab specification. + * + * @type string $name The name of the tab. Used in the HTML IDs, href and aria properties. + * @type string $link_content The content of the tab link. + * @type string $content The content of the tab. + * @type array $options { + * Optional. Extra options. + * + * @type string $link_class Optional. The class for the tab link. + * @type string $link_aria_label Optional. The aria label of the tab link. + * } + * } + * } + */ + $requested_tabs = apply_filters( 'yoast_free_additional_metabox_sections', [] ); + + foreach ( $requested_tabs as $tab ) { + if ( is_array( $tab ) && array_key_exists( 'name', $tab ) && array_key_exists( 'link_content', $tab ) && array_key_exists( 'content', $tab ) ) { + $options = array_key_exists( 'options', $tab ) ? $tab['options'] : []; + $tabs[] = new WPSEO_Metabox_Section_Additional( + $tab['name'], + $tab['link_content'], + $tab['content'], + $options, + ); + } + } + + return $tabs; + } + + /** + * Adds a line in the meta box. + * + * @deprecated 23.5 + * @codeCoverageIgnore + * + * @param string[] $meta_field_def Contains the vars based on which output is generated. + * @param string $key Internal key (without prefix). + * + * @return string + */ + public function do_meta_box( $meta_field_def, $key = '' ) { + _deprecated_function( __METHOD__, 'Yoast SEO 23.5' ); + + $content = ''; + $esc_form_key = esc_attr( WPSEO_Meta::$form_prefix . $key ); + $meta_value = WPSEO_Meta::get_value( $key, $this->get_metabox_post()->ID ); + + $class = ''; + if ( isset( $meta_field_def['class'] ) && $meta_field_def['class'] !== '' ) { + $class = ' ' . $meta_field_def['class']; + } + + $placeholder = ''; + if ( isset( $meta_field_def['placeholder'] ) && $meta_field_def['placeholder'] !== '' ) { + $placeholder = $meta_field_def['placeholder']; + } + + $aria_describedby = ''; + $description = ''; + if ( isset( $meta_field_def['description'] ) ) { + $aria_describedby = ' aria-describedby="' . $esc_form_key . '-desc"'; + $description = '

            ' . $meta_field_def['description'] . '

            '; + } + + // Add a hide_on_pages option that returns nothing when the field is rendered on a page. + if ( isset( $meta_field_def['hide_on_pages'] ) && $meta_field_def['hide_on_pages'] && get_post_type() === 'page' ) { + return ''; + } + + switch ( $meta_field_def['type'] ) { + case 'text': + $ac = ''; + if ( isset( $meta_field_def['autocomplete'] ) && $meta_field_def['autocomplete'] === false ) { + $ac = 'autocomplete="off" '; + } + if ( $placeholder !== '' ) { + $placeholder = ' placeholder="' . esc_attr( $placeholder ) . '"'; + } + $content .= ''; + break; + + case 'url': + if ( $placeholder !== '' ) { + $placeholder = ' placeholder="' . esc_attr( $placeholder ) . '"'; + } + $content .= ''; + break; + + case 'textarea': + $rows = 3; + if ( isset( $meta_field_def['rows'] ) && $meta_field_def['rows'] > 0 ) { + $rows = $meta_field_def['rows']; + } + $content .= ''; + break; + + case 'hidden': + $default = ''; + if ( isset( $meta_field_def['default'] ) ) { + $default = sprintf( ' data-default="%s"', esc_attr( $meta_field_def['default'] ) ); + } + $content .= '' . "\n"; + break; + case 'select': + if ( isset( $meta_field_def['options'] ) && is_array( $meta_field_def['options'] ) && $meta_field_def['options'] !== [] ) { + $content .= ''; + } + break; + + case 'multiselect': + if ( isset( $meta_field_def['options'] ) && is_array( $meta_field_def['options'] ) && $meta_field_def['options'] !== [] ) { + + // Set $meta_value as $selected_arr. + $selected_arr = $meta_value; + + // If the multiselect field is 'meta-robots-adv' we should explode on ,. + if ( $key === 'meta-robots-adv' ) { + $selected_arr = explode( ',', $meta_value ); + } + + if ( ! is_array( $selected_arr ) ) { + $selected_arr = (array) $selected_arr; + } + + $options_count = count( $meta_field_def['options'] ); + + $content .= ''; + unset( $val, $option, $selected, $selected_arr, $options_count ); + } + break; + + case 'checkbox': + $checked = checked( $meta_value, 'on', false ); + $expl = ( isset( $meta_field_def['expl'] ) ) ? esc_html( $meta_field_def['expl'] ) : ''; + $content .= ' '; + unset( $checked, $expl ); + break; + + case 'radio': + if ( isset( $meta_field_def['options'] ) && is_array( $meta_field_def['options'] ) && $meta_field_def['options'] !== [] ) { + foreach ( $meta_field_def['options'] as $val => $option ) { + $checked = checked( $meta_value, $val, false ); + $content .= ' '; + } + unset( $val, $option, $checked ); + } + break; + } + + $html = ''; + if ( $content === '' ) { + $content = apply_filters_deprecated( 'wpseo_do_meta_box_field_' . $key, [ $content, $meta_value, $esc_form_key, $meta_field_def, $key ], 'Yoast SEO 23.5', '', 'do_meta_box is deprecated' ); + } + + if ( $content !== '' ) { + + $title = esc_html( $meta_field_def['title'] ); + + // By default, use the field title as a label element. + $label = ''; + + // Set the inline help and help panel, if any. + $help_button = ''; + $help_panel = ''; + if ( isset( $meta_field_def['help'] ) && $meta_field_def['help'] !== '' ) { + $help = new WPSEO_Admin_Help_Panel( $key, $meta_field_def['help-button'], $meta_field_def['help'] ); + $help_button = $help->get_button_html(); + $help_panel = $help->get_panel_html(); + } + + // If it's a set of radio buttons, output proper fieldset and legend. + if ( $meta_field_def['type'] === 'radio' ) { + return '
            ' . $title . '' . $help_button . $help_panel . $content . $description . '
            '; + } + + // If it's a single checkbox, ignore the title. + if ( $meta_field_def['type'] === 'checkbox' ) { + $label = ''; + } + + // Other meta box content or form fields. + if ( $meta_field_def['type'] === 'hidden' ) { + $html = $content; + } + else { + $html = $label . $description . $help_button . $help_panel . $content; + } + } + + return $html; + } + + /** + * Saves the WP SEO metadata for posts. + * + * {@internal $_POST parameters are validated via sanitize_post_meta().}} + * + * @param int $post_id Post ID. + * + * @return bool|void Boolean false if invalid save post request. + */ + public function save_postdata( $post_id ) { + // Bail if this is a multisite installation and the site has been switched. + if ( is_multisite() && ms_is_switched() ) { + return false; + } + + if ( $post_id === null ) { + return false; + } + + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in wp_verify_none. + if ( ! isset( $_POST['yoast_free_metabox_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['yoast_free_metabox_nonce'] ), 'yoast_free_metabox' ) ) { + return false; + } + + if ( wp_is_post_revision( $post_id ) ) { + $post_id = wp_is_post_revision( $post_id ); + } + + /** + * Determine we're not accidentally updating a different post. + * We can't use filter_input here as the ID isn't available at this point, other than in the $_POST data. + */ + if ( ! isset( $_POST['ID'] ) || $post_id !== (int) $_POST['ID'] ) { + return false; + } + + clean_post_cache( $post_id ); + $post = get_post( $post_id ); + + if ( ! is_object( $post ) ) { + // Non-existent post. + return false; + } + + do_action( 'wpseo_save_compare_data', $post ); + + $social_fields = []; + if ( $this->social_is_enabled ) { + $social_fields = WPSEO_Meta::get_meta_field_defs( 'social' ); + } + + $meta_boxes = apply_filters( 'wpseo_save_metaboxes', [] ); + $meta_boxes = array_merge( + $meta_boxes, + WPSEO_Meta::get_meta_field_defs( 'general', $post->post_type ), + WPSEO_Meta::get_meta_field_defs( 'advanced' ), + $social_fields, + WPSEO_Meta::get_meta_field_defs( 'schema', $post->post_type ), + ); + + foreach ( $meta_boxes as $key => $meta_box ) { + + // If analysis is disabled remove that analysis score value from the DB. + if ( $this->is_meta_value_disabled( $key ) ) { + WPSEO_Meta::delete( $key, $post_id ); + continue; + } + + $data = null; + $field_name = WPSEO_Meta::$form_prefix . $key; + + if ( $meta_box['type'] === 'checkbox' ) { + $data = isset( $_POST[ $field_name ] ) ? 'on' : 'off'; + } + else { + if ( isset( $_POST[ $field_name ] ) ) { + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- We're preparing to do just that. + $data = wp_unslash( $_POST[ $field_name ] ); + + // For multi-select. + if ( is_array( $data ) ) { + $data = array_map( [ 'WPSEO_Utils', 'sanitize_text_field' ], $data ); + } + + if ( is_string( $data ) ) { + $data = ( $key !== 'canonical' ) ? WPSEO_Utils::sanitize_text_field( $data ) : WPSEO_Utils::sanitize_url( $data ); + } + } + + // Reset options when no entry is present with multiselect - only applies to `meta-robots-adv` currently. + if ( ! isset( $_POST[ $field_name ] ) && ( $meta_box['type'] === 'multiselect' ) ) { + $data = []; + } + } + + if ( $data !== null ) { + WPSEO_Meta::set_value( $key, $data, $post_id ); + } + } + + do_action( 'wpseo_saved_postdata' ); + } + + /** + * Determines if the given meta value key is disabled. + * + * @param string $key The key of the meta value. + * + * @return bool Whether the given meta value key is disabled. + */ + public function is_meta_value_disabled( $key ) { + if ( $key === 'linkdex' && ! $this->seo_analysis->is_enabled() ) { + return true; + } + + if ( $key === 'content_score' && ! $this->readability_analysis->is_enabled() ) { + return true; + } + + if ( $key === 'inclusive_language_score' && ! $this->inclusive_language_analysis->is_enabled() ) { + return true; + } + + return false; + } + + /** + * Enqueues all the needed JS and CSS. + * + * @todo [JRF => whomever] Create css/metabox-mp6.css file and add it to the below allowed colors array when done. + * + * @return void + */ + public function enqueue() { + global $pagenow; + + if ( $this->readability_analysis->is_enabled() ) { + $this->editor = new WPSEO_Metabox_Editor(); + $this->editor->register_hooks(); + } + + $asset_manager = new WPSEO_Admin_Asset_Manager(); + + if ( self::is_post_overview( $pagenow ) ) { + return; + } + + /* Filter 'wpseo_always_register_metaboxes_on_admin' documented in wpseo-main.php */ + if ( ( self::is_post_edit( $pagenow ) === false && apply_filters( 'wpseo_always_register_metaboxes_on_admin', false ) === false ) || $this->display_metabox() === false ) { + return; + } + + $post_id = get_queried_object_id(); + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( empty( $post_id ) && isset( $_GET['post'] ) && is_string( $_GET['post'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + $post_id = sanitize_text_field( wp_unslash( $_GET['post'] ) ); + } + + if ( $post_id !== 0 ) { + // Enqueue files needed for upload functionality. + wp_enqueue_media( [ 'post' => $post_id ] ); + } + + $asset_manager->enqueue_style( 'metabox-css' ); + if ( $this->readability_analysis->is_enabled() ) { + $asset_manager->enqueue_style( 'scoring' ); + } + $asset_manager->enqueue_style( 'monorepo' ); + $asset_manager->enqueue_style( 'ai-generator' ); + $asset_manager->enqueue_style( 'ai-fix-assessments' ); + + $is_block_editor = WP_Screen::get()->is_block_editor(); + $post_edit_handle = 'post-edit'; + if ( ! $is_block_editor ) { + $post_edit_handle = 'post-edit-classic'; + } + $asset_manager->enqueue_script( $post_edit_handle ); + $asset_manager->enqueue_style( 'admin-css' ); + + /** + * Removes the emoji script as it is incompatible with both React and any + * contenteditable fields. + */ + remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); + + $asset_manager->localize_script( $post_edit_handle, 'wpseoAdminL10n', WPSEO_Utils::get_admin_l10n() ); + + $plugins_script_data = [ + 'replaceVars' => [ + 'replace_vars' => $this->get_replace_vars(), + 'hidden_replace_vars' => $this->get_hidden_replace_vars(), + 'recommended_replace_vars' => $this->get_recommended_replace_vars(), + 'scope' => $this->determine_scope(), + 'has_taxonomies' => $this->current_post_type_has_taxonomies(), + ], + 'shortcodes' => [ + 'wpseo_shortcode_tags' => $this->get_valid_shortcode_tags(), + 'wpseo_filter_shortcodes_nonce' => wp_create_nonce( 'wpseo-filter-shortcodes' ), + ], + ]; + + $worker_script_data = [ + 'url' => YoastSEO()->helpers->asset->get_asset_url( 'yoast-seo-analysis-worker' ), + 'dependencies' => YoastSEO()->helpers->asset->get_dependency_urls_by_handle( 'yoast-seo-analysis-worker' ), + 'keywords_assessment_url' => YoastSEO()->helpers->asset->get_asset_url( 'yoast-seo-used-keywords-assessment' ), + 'log_level' => WPSEO_Utils::get_analysis_worker_log_level(), + ]; + + $page_on_front = (int) get_option( 'page_on_front' ); + $homepage_is_page = get_option( 'show_on_front' ) === 'page'; + $is_front_page = $homepage_is_page && $page_on_front === (int) $post_id; + + $script_data = [ + 'metabox' => $this->get_metabox_script_data(), + 'isPost' => true, + 'isBlockEditor' => $is_block_editor, + 'postId' => $post_id, + 'postStatus' => get_post_status( $post_id ), + 'postType' => get_post_type( $post_id ), + 'isPage' => get_post_type( $post_id ) === 'page', + 'usedKeywordsNonce' => wp_create_nonce( 'wpseo-keyword-usage-and-post-types' ), + 'analysis' => [ + 'plugins' => $plugins_script_data, + 'worker' => $worker_script_data, + ], + 'isFrontPage' => $is_front_page, + ]; + + /** + * The website information repository. + * + * @var Website_Information_Repository $repo + */ + $repo = YoastSEO()->classes->get( Website_Information_Repository::class ); + $site_information = $repo->get_post_site_information(); + $site_information->set_permalink( $this->get_permalink() ); + $script_data = array_merge_recursive( $site_information->get_legacy_site_information(), $script_data ); + + if ( ! $is_block_editor && post_type_supports( get_post_type(), 'thumbnail' ) ) { + $asset_manager->enqueue_style( 'featured-image' ); + } + + $asset_manager->localize_script( $post_edit_handle, 'wpseoScriptData', $script_data ); + } + + /** + * Returns post in metabox context. + * + * @return WP_Post|array + */ + protected function get_metabox_post() { + if ( $this->post !== null ) { + return $this->post; + } + + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['post'] ) && is_string( $_GET['post'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, Sanitization happens in the validate_int function. + $post_id = (int) WPSEO_Utils::validate_int( wp_unslash( $_GET['post'] ) ); + + $this->post = get_post( $post_id ); + + return $this->post; + } + + if ( isset( $GLOBALS['post'] ) ) { + $this->post = $GLOBALS['post']; + + return $this->post; + } + + return []; + } + + /** + * Returns an array with shortcode tags for all registered shortcodes. + * + * @return string[] + */ + private function get_valid_shortcode_tags() { + $shortcode_tags = []; + + foreach ( $GLOBALS['shortcode_tags'] as $tag => $description ) { + $shortcode_tags[] = $tag; + } + + return $shortcode_tags; + } + + /** + * Prepares the replace vars for localization. + * + * @return string[] Replace vars. + */ + private function get_replace_vars() { + $cached_replacement_vars = []; + + $vars_to_cache = [ + 'date', + 'id', + 'sitename', + 'sitedesc', + 'sep', + 'page', + 'currentdate', + 'currentyear', + 'currentmonth', + 'currentday', + 'post_year', + 'post_month', + 'post_day', + 'name', + 'author_first_name', + 'author_last_name', + 'permalink', + 'post_content', + 'category_title', + 'tag', + 'category', + ]; + + foreach ( $vars_to_cache as $var ) { + $cached_replacement_vars[ $var ] = wpseo_replace_vars( '%%' . $var . '%%', $this->get_metabox_post() ); + } + + // Merge custom replace variables with the WordPress ones. + return array_merge( $cached_replacement_vars, $this->get_custom_replace_vars( $this->get_metabox_post() ) ); + } + + /** + * Returns the list of replace vars that should be hidden inside the editor. + * + * @return string[] The hidden replace vars. + */ + protected function get_hidden_replace_vars() { + return ( new WPSEO_Replace_Vars() )->get_hidden_replace_vars(); + } + + /** + * Prepares the recommended replace vars for localization. + * + * @return array Recommended replacement variables. + */ + private function get_recommended_replace_vars() { + $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars(); + + // What is recommended depends on the current context. + $post_type = $recommended_replace_vars->determine_for_post( $this->get_metabox_post() ); + + return $recommended_replace_vars->get_recommended_replacevars_for( $post_type ); + } + + /** + * Gets the custom replace variables for custom taxonomies and fields. + * + * @param WP_Post $post The post to check for custom taxonomies and fields. + * + * @return array Array containing all the replacement variables. + */ + private function get_custom_replace_vars( $post ) { + return [ + 'custom_fields' => $this->get_custom_fields_replace_vars( $post ), + 'custom_taxonomies' => $this->get_custom_taxonomies_replace_vars( $post ), + ]; + } + + /** + * Gets the custom replace variables for custom taxonomies. + * + * @param WP_Post $post The post to check for custom taxonomies. + * + * @return array Array containing all the replacement variables. + */ + private function get_custom_taxonomies_replace_vars( $post ) { + $taxonomies = get_object_taxonomies( $post, 'objects' ); + $custom_replace_vars = []; + + foreach ( $taxonomies as $taxonomy_name => $taxonomy ) { + + if ( is_string( $taxonomy ) ) { // If attachment, see https://core.trac.wordpress.org/ticket/37368 . + $taxonomy_name = $taxonomy; + $taxonomy = get_taxonomy( $taxonomy_name ); + } + + if ( $taxonomy->_builtin && $taxonomy->public ) { + continue; + } + + $custom_replace_vars[ $taxonomy_name ] = [ + 'name' => $taxonomy->name, + 'description' => $taxonomy->description, + ]; + } + + return $custom_replace_vars; + } + + /** + * Gets the custom replace variables for custom fields. + * + * @param WP_Post $post The post to check for custom fields. + * + * @return array Array containing all the replacement variables. + */ + private function get_custom_fields_replace_vars( $post ) { + $custom_replace_vars = []; + + // If no post object is passed, return the empty custom_replace_vars array. + if ( ! is_object( $post ) ) { + return $custom_replace_vars; + } + + $custom_fields = get_post_custom( $post->ID ); + + // If $custom_fields is an empty string or generally not an array, return early. + if ( ! is_array( $custom_fields ) ) { + return $custom_replace_vars; + } + + $meta = YoastSEO()->meta->for_post( $post->ID ); + + if ( ! $meta ) { + return $custom_replace_vars; + } + + // Simply concatenate all fields containing replace vars so we can handle them all with a single regex find. + $replace_vars_fields = implode( + ' ', + [ + $meta->presentation->title, + $meta->presentation->meta_description, + ], + ); + + preg_match_all( '/%%cf_([A-Za-z0-9_]+)%%/', $replace_vars_fields, $matches ); + $fields_to_include = $matches[1]; + foreach ( $custom_fields as $custom_field_name => $custom_field ) { + // Skip private custom fields. + if ( substr( $custom_field_name, 0, 1 ) === '_' ) { + continue; + } + + // Skip custom fields that are not used, new ones will be fetched dynamically. + if ( ! in_array( $custom_field_name, $fields_to_include, true ) ) { + continue; + } + + // Skip custom field values that are serialized. + if ( is_serialized( $custom_field[0] ) ) { + continue; + } + + $custom_replace_vars[ $custom_field_name ] = $custom_field[0]; + } + + return $custom_replace_vars; + } + + /** + * Checks if the page is the post overview page. + * + * @param string $page The page to check for the post overview page. + * + * @return bool Whether or not the given page is the post overview page. + */ + public static function is_post_overview( $page ) { + return $page === 'edit.php'; + } + + /** + * Checks if the page is the post edit page. + * + * @param string $page The page to check for the post edit page. + * + * @return bool Whether or not the given page is the post edit page. + */ + public static function is_post_edit( $page ) { + return $page === 'post.php' + || $page === 'post-new.php'; + } + + /** + * Retrieves the product title. + * + * @return string The product title. + */ + protected function get_product_title() { + return YoastSEO()->helpers->product->get_product_name(); + } + + /** + * Gets the permalink. + * + * @return string + */ + protected function get_permalink() { + $permalink = ''; + + if ( is_object( $this->get_metabox_post() ) ) { + $permalink = get_sample_permalink( $this->get_metabox_post()->ID ); + $permalink = $permalink[0]; + } + + return $permalink; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/metabox/interface-metabox-analysis.php b/html/wp-content/plugins/wordpress-seo/admin/metabox/interface-metabox-analysis.php new file mode 100644 index 0000000..756ca97 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/metabox/interface-metabox-analysis.php @@ -0,0 +1,33 @@ +get_listener_value() !== $this->notification_identifier ) { + return; + } + + $this->dismiss(); + } + + /** + * Adds the notification if applicable, otherwise removes it. + * + * @param Yoast_Notification_Center $notification_center The notification center object. + * + * @return void + */ + public function handle( Yoast_Notification_Center $notification_center ) { + if ( $this->is_applicable() ) { + $notification = $this->get_notification(); + $notification_center->add_notification( $notification ); + + return; + } + + $notification_center->remove_notification_by_id( 'wpseo-' . $this->notification_identifier ); + } + + /** + * Listens to an argument in the request URL and triggers an action. + * + * @return void + */ + protected function dismiss() { + $this->set_dismissal_state(); + $this->redirect_to_dashboard(); + } + + /** + * Checks if a notice is applicable. + * + * @return bool Whether a notice should be shown or not. + */ + protected function is_applicable() { + return $this->is_notice_dismissed() === false; + } + + /** + * Checks whether the notification has been dismissed. + * + * @codeCoverageIgnore + * + * @return bool True when notification is dismissed. + */ + protected function is_notice_dismissed() { + return get_user_meta( get_current_user_id(), 'wpseo-remove-' . $this->notification_identifier, true ) === '1'; + } + + /** + * Retrieves the value where listener is listening for. + * + * @codeCoverageIgnore + * + * @return string|null The listener value or null if not set. + */ + protected function get_listener_value() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: Normally we would need to check for a nonce here but this class is not used anymore. + if ( isset( $_GET['yoast_dismiss'] ) && is_string( $_GET['yoast_dismiss'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: Normally we would need to check for a nonce here but this class is not used anymore. + return sanitize_text_field( wp_unslash( $_GET['yoast_dismiss'] ) ); + } + return null; + } + + /** + * Dismisses the notification. + * + * @codeCoverageIgnore + * + * @return void + */ + protected function set_dismissal_state() { + update_user_meta( get_current_user_id(), 'wpseo-remove-' . $this->notification_identifier, true ); + } + + /** + * Redirects the user back to the dashboard. + * + * @codeCoverageIgnore + * + * @return void + */ + protected function redirect_to_dashboard() { + wp_safe_redirect( admin_url( 'admin.php?page=wpseo_dashboard' ) ); + exit(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/notifiers/interface-notification-handler.php b/html/wp-content/plugins/wordpress-seo/admin/notifiers/interface-notification-handler.php new file mode 100644 index 0000000..f798a58 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/notifiers/interface-notification-handler.php @@ -0,0 +1,21 @@ +admin_header( true, 'wpseo_ms' ); + +$network_tabs = new WPSEO_Option_Tabs( 'network' ); +$network_tabs->add_tab( new WPSEO_Option_Tab( 'general', __( 'General', 'wordpress-seo' ) ) ); +$network_tabs->add_tab( new WPSEO_Option_Tab( 'features', __( 'Features', 'wordpress-seo' ) ) ); +$network_tabs->add_tab( new WPSEO_Option_Tab( 'integrations', __( 'Integrations', 'wordpress-seo' ) ) ); + +$network_tabs->add_tab( + new WPSEO_Option_Tab( + 'crawl-settings', + __( 'Crawl settings', 'wordpress-seo' ), + [ + 'save_button' => true, + ], + ), +); +$network_tabs->add_tab( new WPSEO_Option_Tab( 'restore-site', __( 'Restore Site', 'wordpress-seo' ), [ 'save_button' => false ] ) ); +$network_tabs->display( $yform ); + +$yform->admin_footer(); diff --git a/html/wp-content/plugins/wordpress-seo/admin/pages/redirects.php b/html/wp-content/plugins/wordpress-seo/admin/pages/redirects.php new file mode 100644 index 0000000..52acbc3 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/pages/redirects.php @@ -0,0 +1,15 @@ +admin_header( false ); + +if ( $tool_page === '' ) { + + $tools = []; + + $tools['import-export'] = [ + 'title' => __( 'Import and Export', 'wordpress-seo' ), + 'desc' => __( 'Import settings from other SEO plugins and export your settings for re-use on (another) site.', 'wordpress-seo' ), + ]; + + if ( WPSEO_Utils::allow_system_file_edit() === true && ! is_multisite() ) { + $tools['file-editor'] = [ + 'title' => __( 'File editor', 'wordpress-seo' ), + 'desc' => __( 'This tool allows you to quickly change important files for your SEO, like your robots.txt and, if you have one, your .htaccess file.', 'wordpress-seo' ), + ]; + } + + $tools['bulk-editor'] = [ + 'title' => __( 'Bulk editor', 'wordpress-seo' ), + 'desc' => __( 'This tool allows you to quickly change titles and descriptions of your posts and pages without having to go into the editor for each page.', 'wordpress-seo' ), + ]; + + echo '

            '; + printf( + /* translators: %1$s expands to Yoast SEO */ + esc_html__( '%1$s comes with some very powerful built-in tools:', 'wordpress-seo' ), + 'Yoast SEO', + ); + echo '

            '; + + echo '
              '; + + $admin_url = admin_url( 'admin.php?page=wpseo_tools' ); + + foreach ( $tools as $slug => $tool ) { + $href = ( ! empty( $tool['href'] ) ) ? $admin_url . $tool['href'] : add_query_arg( [ 'tool' => $slug ], $admin_url ); + $attr = ( ! empty( $tool['attr'] ) ) ? $tool['attr'] : ''; + + echo '
            • '; + echo '', esc_html( $tool['title'] ), '
              '; + echo esc_html( $tool['desc'] ); + echo '
            • '; + } + + /** + * WARNING: This hook is intended for internal use only. + * Don't use it in your code as it will be removed shortly. + */ + do_action( 'wpseo_tools_overview_list_items_internal' ); + + echo '
            '; +} +else { + echo '', esc_html__( '« Back to Tools page', 'wordpress-seo' ), ''; + + $tool_pages = [ 'bulk-editor', 'import-export' ]; + + if ( WPSEO_Utils::allow_system_file_edit() === true && ! is_multisite() ) { + $tool_pages[] = 'file-editor'; + } + + if ( in_array( $tool_page, $tool_pages, true ) ) { + require_once WPSEO_PATH . 'admin/views/tool-' . $tool_page . '.php'; + } +} + +$yform->admin_footer( false ); diff --git a/html/wp-content/plugins/wordpress-seo/admin/roles/class-abstract-role-manager.php b/html/wp-content/plugins/wordpress-seo/admin/roles/class-abstract-role-manager.php new file mode 100644 index 0000000..39edad4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/roles/class-abstract-role-manager.php @@ -0,0 +1,149 @@ +roles[ $role ] = (object) [ + 'display_name' => $display_name, + 'template' => $template, + ]; + } + + /** + * Returns the list of registered roles. + * + * @return string[] List or registered roles. + */ + public function get_roles() { + return array_keys( $this->roles ); + } + + /** + * Adds the registered roles. + * + * @return void + */ + public function add() { + foreach ( $this->roles as $role => $data ) { + $capabilities = $this->get_capabilities( $data->template ); + $capabilities = $this->filter_existing_capabilties( $role, $capabilities ); + + $this->add_role( $role, $data->display_name, $capabilities ); + } + } + + /** + * Removes the registered roles. + * + * @return void + */ + public function remove() { + $roles = array_keys( $this->roles ); + array_map( [ $this, 'remove_role' ], $roles ); + } + + /** + * Returns the capabilities for the specified role. + * + * @param string $role Role to fetch capabilities from. + * + * @return array List of capabilities. + */ + protected function get_capabilities( $role ) { + if ( ! is_string( $role ) || empty( $role ) ) { + return []; + } + + $wp_role = get_role( $role ); + if ( ! $wp_role ) { + return []; + } + + return $wp_role->capabilities; + } + + /** + * Returns true if the capability exists on the role. + * + * @param WP_Role $role Role to check capability against. + * @param string $capability Capability to check. + * + * @return bool True if the capability is defined for the role. + */ + protected function capability_exists( WP_Role $role, $capability ) { + return ! array_key_exists( $capability, $role->capabilities ); + } + + /** + * Filters out capabilities that are already set for the role. + * + * This makes sure we don't override configurations that have been previously set. + * + * @param string $role The role to check against. + * @param array $capabilities The capabilities that should be set. + * + * @return array Capabilties that can be safely set. + */ + protected function filter_existing_capabilties( $role, array $capabilities ) { + if ( $capabilities === [] ) { + return $capabilities; + } + + $wp_role = get_role( $role ); + if ( ! $wp_role ) { + return $capabilities; + } + + foreach ( $capabilities as $capability => $grant ) { + if ( $this->capability_exists( $wp_role, $capability ) ) { + unset( $capabilities[ $capability ] ); + } + } + + return $capabilities; + } + + /** + * Adds a role to the system. + * + * @param string $role Role to add. + * @param string $display_name Name to display for the role. + * @param array $capabilities Capabilities to add to the role. + * + * @return void + */ + abstract protected function add_role( $role, $display_name, array $capabilities = [] ); + + /** + * Removes a role from the system. + * + * @param string $role Role to remove. + * + * @return void + */ + abstract protected function remove_role( $role ); +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/roles/class-register-roles.php b/html/wp-content/plugins/wordpress-seo/admin/roles/class-register-roles.php new file mode 100644 index 0000000..9636237 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/roles/class-register-roles.php @@ -0,0 +1,33 @@ +register( 'wpseo_manager', 'SEO Manager', 'editor' ); + $role_manager->register( 'wpseo_editor', 'SEO Editor', 'editor' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/roles/class-role-manager-factory.php b/html/wp-content/plugins/wordpress-seo/admin/roles/class-role-manager-factory.php new file mode 100644 index 0000000..bbe8cff --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/roles/class-role-manager-factory.php @@ -0,0 +1,25 @@ + $grant ) { + $wp_role->add_cap( $capability, $grant ); + } + + return; + } + + add_role( $role, $display_name, $capabilities ); + } + + /** + * Removes a role from the system. + * + * @param string $role Role to remove. + * + * @return void + */ + protected function remove_role( $role ) { + remove_role( $role ); + } + + /** + * Formats the capabilities to the required format. + * + * @param array $capabilities Capabilities to format. + * @param bool $enabled Whether these capabilities should be enabled or not. + * + * @return array Formatted capabilities. + */ + protected function format_capabilities( array $capabilities, $enabled = true ) { + // Flip keys and values. + $capabilities = array_flip( $capabilities ); + + // Set all values to $enabled. + return array_fill_keys( array_keys( $capabilities ), $enabled ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/roles/class-role-manager.php b/html/wp-content/plugins/wordpress-seo/admin/roles/class-role-manager.php new file mode 100644 index 0000000..7f9d82b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/roles/class-role-manager.php @@ -0,0 +1,44 @@ +get_file_url( $request ); + + return new WP_REST_Response( + [ + 'type' => 'success', + 'size_in_bytes' => $this->get_file_size( $file_url ), + ], + 200, + ); + } catch ( WPSEO_File_Size_Exception $exception ) { + return new WP_REST_Response( + [ + 'type' => 'failure', + 'response' => $exception->getMessage(), + ], + 404, + ); + } + } + + /** + * Retrieves the file url. + * + * @param WP_REST_Request $request The request to retrieve file url from. + * + * @return string The file url. + * @throws WPSEO_File_Size_Exception The file is hosted externally. + */ + protected function get_file_url( WP_REST_Request $request ) { + $file_url = rawurldecode( $request->get_param( 'url' ) ); + + if ( ! $this->is_externally_hosted( $file_url ) ) { + return $file_url; + } + + throw WPSEO_File_Size_Exception::externally_hosted( $file_url ); + } + + /** + * Checks if the file is hosted externally. + * + * @param string $file_url The file url. + * + * @return bool True if it is hosted externally. + */ + protected function is_externally_hosted( $file_url ) { + return wp_parse_url( home_url(), PHP_URL_HOST ) !== wp_parse_url( $file_url, PHP_URL_HOST ); + } + + /** + * Returns the file size. + * + * @param string $file_url The file url to get the size for. + * + * @return int The file size. + * @throws WPSEO_File_Size_Exception Retrieval of file size went wrong for unknown reasons. + */ + protected function get_file_size( $file_url ) { + $file_config = wp_upload_dir(); + $file_url = str_replace( $file_config['baseurl'], '', $file_url ); + $file_size = $this->calculate_file_size( $file_url ); + + if ( ! $file_size ) { + throw WPSEO_File_Size_Exception::unknown_error( $file_url ); + } + + return $file_size; + } + + /** + * Calculates the file size using the Utils class. + * + * @param string $file_url The file to retrieve the size for. + * + * @return int|bool The file size or False if it could not be retrieved. + */ + protected function calculate_file_size( $file_url ) { + return WPSEO_Image_Utils::get_file_size( + [ + 'path' => $file_url, + ], + ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/statistics/class-statistics-integration.php b/html/wp-content/plugins/wordpress-seo/admin/statistics/class-statistics-integration.php new file mode 100644 index 0000000..756f314 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/statistics/class-statistics-integration.php @@ -0,0 +1,36 @@ +statistics = $statistics; + } + + /** + * Fetches statistics by REST request. + * + * @return WP_REST_Response The response object. + */ + public function get_statistics() { + // Switch to the user locale with fallback to the site locale. + switch_to_locale( get_user_locale() ); + + $this->labels = $this->labels(); + $statistics = $this->statistic_items(); + + $data = [ + 'header' => $this->get_header_from_statistics( $statistics ), + 'seo_scores' => $statistics['scores'], + ]; + + return new WP_REST_Response( $data ); + } + + /** + * Gets a header summarizing the given statistics results. + * + * @param array $statistics The statistics results. + * + * @return string The header summing up the statistics results. + */ + private function get_header_from_statistics( array $statistics ) { + // Personal interpretation to allow release, should be looked at later. + if ( $statistics['division'] === false ) { + return __( 'You don\'t have any published posts, your SEO scores will appear here once you make your first post!', 'wordpress-seo' ); + } + + if ( $statistics['division']['good'] > 0.66 ) { + return __( 'Hey, your SEO is doing pretty well! Check out the stats:', 'wordpress-seo' ); + } + + return __( 'Below are your published posts\' SEO scores. Now is as good a time as any to start improving some of your posts!', 'wordpress-seo' ); + } + + /** + * An array representing items to be added to the At a Glance dashboard widget. + * + * @return array The statistics for the current user. + */ + private function statistic_items() { + $transient = $this->get_transient(); + $user_id = get_current_user_id(); + + if ( isset( $transient[ $user_id ] ) ) { + return $transient[ $user_id ]; + } + + return $this->set_statistic_items_for_user( $transient, $user_id ); + } + + /** + * Gets the statistics transient value. Returns array if transient wasn't set. + * + * @return array|mixed Returns the transient or an empty array if the transient doesn't exist. + */ + private function get_transient() { + $transient = get_transient( self::CACHE_TRANSIENT_KEY ); + + if ( $transient === false ) { + return []; + } + + return $transient; + } + + /** + * Set the statistics transient cache for a specific user. + * + * @param array $transient The current stored transient with the cached data. + * @param int $user The user's ID to assign the retrieved values to. + * + * @return array The statistics transient for the user. + */ + private function set_statistic_items_for_user( $transient, $user ) { + $scores = $this->get_seo_scores_with_post_count(); + $division = $this->get_seo_score_division( $scores ); + + $transient[ $user ] = [ + // Use array_values because array_filter may return non-zero indexed arrays. + 'scores' => array_values( array_filter( $scores, [ $this, 'filter_items' ] ) ), + 'division' => $division, + ]; + + set_transient( self::CACHE_TRANSIENT_KEY, $transient, DAY_IN_SECONDS ); + + return $transient[ $user ]; + } + + /** + * Gets the division of SEO scores. + * + * @param array $scores The SEO scores. + * + * @return array|bool The division of SEO scores, false if there are no posts. + */ + private function get_seo_score_division( array $scores ) { + $total = 0; + $division = []; + + foreach ( $scores as $score ) { + $total += $score['count']; + } + + if ( $total === 0 ) { + return false; + } + + foreach ( $scores as $score ) { + $division[ $score['seo_rank'] ] = ( $score['count'] / $total ); + } + + return $division; + } + + /** + * Get all SEO ranks and data associated with them. + * + * @return array An array of SEO scores and associated data. + */ + private function get_seo_scores_with_post_count() { + $ranks = WPSEO_Rank::get_all_ranks(); + + return array_map( [ $this, 'map_rank_to_widget' ], $ranks ); + } + + /** + * Converts a rank to data usable in the dashboard widget. + * + * @param WPSEO_Rank $rank The rank to map. + * + * @return array The mapped rank. + */ + private function map_rank_to_widget( WPSEO_Rank $rank ) { + return [ + 'seo_rank' => $rank->get_rank(), + 'label' => $this->get_label_for_rank( $rank ), + 'count' => $this->statistics->get_post_count( $rank ), + 'link' => $this->get_link_for_rank( $rank ), + ]; + } + + /** + * Returns a dashboard widget label to use for a certain rank. + * + * @param WPSEO_Rank $rank The rank to return a label for. + * + * @return string The label for the rank. + */ + private function get_label_for_rank( WPSEO_Rank $rank ) { + return $this->labels[ $rank->get_rank() ]; + } + + /** + * Determines the labels for the various scoring ranks that are known within Yoast SEO. + * + * @return array Array containing the translatable labels. + */ + private function labels() { + return [ + WPSEO_Rank::NO_FOCUS => sprintf( + /* translators: %1$s expands to an opening strong tag, %2$s expands to a closing strong tag */ + __( 'Posts %1$swithout%2$s a focus keyphrase', 'wordpress-seo' ), + '', + '', + ), + WPSEO_Rank::BAD => sprintf( + /* translators: %s expands to the score */ + __( 'Posts with the SEO score: %s', 'wordpress-seo' ), + '' . __( 'Needs improvement', 'wordpress-seo' ) . '', + ), + WPSEO_Rank::OK => sprintf( + /* translators: %s expands to the score */ + __( 'Posts with the SEO score: %s', 'wordpress-seo' ), + '' . __( 'OK', 'wordpress-seo' ) . '', + ), + WPSEO_Rank::GOOD => sprintf( + /* translators: %s expands to the score */ + __( 'Posts with the SEO score: %s', 'wordpress-seo' ), + '' . __( 'Good', 'wordpress-seo' ) . '', + ), + WPSEO_Rank::NO_INDEX => __( 'Posts that should not show up in search results', 'wordpress-seo' ), + ]; + } + + /** + * Filter items if they have a count of zero. + * + * @param array $item The item to potentially filter out. + * + * @return bool Whether or not the count is zero. + */ + private function filter_items( $item ) { + return $item['count'] !== 0; + } + + /** + * Returns a link for the overview of posts of a certain rank. + * + * @param WPSEO_Rank $rank The rank to return a link for. + * + * @return string The link that shows an overview of posts with that rank. + */ + private function get_link_for_rank( WPSEO_Rank $rank ) { + if ( current_user_can( 'edit_others_posts' ) === false ) { + return esc_url( admin_url( 'edit.php?post_status=publish&post_type=post&seo_filter=' . $rank->get_rank() . '&author=' . get_current_user_id() ) ); + } + + return esc_url( admin_url( 'edit.php?post_status=publish&post_type=post&seo_filter=' . $rank->get_rank() ) ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-columns.php b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-columns.php new file mode 100644 index 0000000..fda2f19 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-columns.php @@ -0,0 +1,231 @@ +taxonomy = $this->get_taxonomy(); + + if ( ! empty( $this->taxonomy ) ) { + add_filter( 'manage_edit-' . $this->taxonomy . '_columns', [ $this, 'add_columns' ] ); + add_filter( 'manage_' . $this->taxonomy . '_custom_column', [ $this, 'parse_column' ], 10, 3 ); + } + + $this->analysis_seo = new WPSEO_Metabox_Analysis_SEO(); + $this->analysis_readability = new WPSEO_Metabox_Analysis_Readability(); + $this->indexable_repository = YoastSEO()->classes->get( Indexable_Repository::class ); + $this->score_icon_helper = YoastSEO()->helpers->score_icon; + } + + /** + * Adds an SEO score column to the terms table, right after the description column. + * + * @param array $columns Current set columns. + * + * @return array + */ + public function add_columns( array $columns ) { + if ( $this->display_metabox( $this->taxonomy ) === false ) { + return $columns; + } + + $new_columns = []; + + foreach ( $columns as $column_name => $column_value ) { + $new_columns[ $column_name ] = $column_value; + + if ( $column_name === 'description' && $this->analysis_seo->is_enabled() ) { + $new_columns['wpseo-score'] = '' + . __( 'SEO score', 'wordpress-seo' ) . ''; + } + + if ( $column_name === 'description' && $this->analysis_readability->is_enabled() ) { + $new_columns['wpseo-score-readability'] = '' + . __( 'Readability score', 'wordpress-seo' ) . ''; + } + } + + return $new_columns; + } + + /** + * Parses the column. + * + * @param string $content The current content of the column. + * @param string $column_name The name of the column. + * @param int $term_id ID of requested taxonomy. + * + * @return string + */ + public function parse_column( $content, $column_name, $term_id ) { + + switch ( $column_name ) { + case 'wpseo-score': + return $this->get_score_value( $term_id ); + + case 'wpseo-score-readability': + return $this->get_score_readability_value( $term_id ); + } + + return $content; + } + + /** + * Retrieves the taxonomy from the $_GET or $_POST variable. + * + * @return string|null The current taxonomy or null when it is not set. + */ + public function get_current_taxonomy() { + // phpcs:disable WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( ! empty( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' ) { + if ( isset( $_POST['taxonomy'] ) && is_string( $_POST['taxonomy'] ) ) { + return sanitize_text_field( wp_unslash( $_POST['taxonomy'] ) ); + } + } + elseif ( isset( $_GET['taxonomy'] ) && is_string( $_GET['taxonomy'] ) ) { + return sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ); + } + // phpcs:enable WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended + return null; + } + + /** + * Returns the posted/get taxonomy value if it is set. + * + * @return string|null + */ + private function get_taxonomy() { + // phpcs:disable WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( wp_doing_ajax() ) { + if ( isset( $_POST['taxonomy'] ) && is_string( $_POST['taxonomy'] ) ) { + return sanitize_text_field( wp_unslash( $_POST['taxonomy'] ) ); + } + } + elseif ( isset( $_GET['taxonomy'] ) && is_string( $_GET['taxonomy'] ) ) { + return sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ); + } + // phpcs:enable WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended + return null; + } + + /** + * Parses the value for the score column. + * + * @param int $term_id ID of requested term. + * + * @return string + */ + private function get_score_value( $term_id ) { + $indexable = $this->indexable_repository->find_by_id_and_type( (int) $term_id, 'term' ); + + return $this->score_icon_helper->for_seo( $indexable, '', __( 'Term is set to noindex.', 'wordpress-seo' ) ); + } + + /** + * Parses the value for the readability score column. + * + * @param int $term_id ID of the requested term. + * + * @return string The HTML for the readability score indicator. + */ + private function get_score_readability_value( $term_id ) { + $score = (int) WPSEO_Taxonomy_Meta::get_term_meta( $term_id, $this->taxonomy, 'content_score' ); + + return $this->score_icon_helper->for_readability( $score ); + } + + /** + * Check if the taxonomy is indexable. + * + * @param mixed $term The current term. + * + * @return bool Whether the term is indexable. + */ + private function is_indexable( $term ) { + // When the no_index value is not empty and not default, check if its value is index. + $no_index = WPSEO_Taxonomy_Meta::get_term_meta( $term->term_id, $this->taxonomy, 'noindex' ); + + // Check if the default for taxonomy is empty (this will be index). + if ( ! empty( $no_index ) && $no_index !== 'default' ) { + return ( $no_index === 'index' ); + } + + if ( is_object( $term ) ) { + $no_index_key = 'noindex-tax-' . $term->taxonomy; + + // If the option is false, this means we want to index it. + return WPSEO_Options::get( $no_index_key, false ) === false; + } + + return true; + } + + /** + * Wraps the WPSEO_Metabox check to determine whether the metabox should be displayed either by + * choice of the admin or because the taxonomy is not public. + * + * @since 7.0 + * + * @param string|null $taxonomy Optional. The taxonomy to test, defaults to the current taxonomy. + * + * @return bool Whether the meta box (and associated columns etc) should be hidden. + */ + private function display_metabox( $taxonomy = null ) { + $current_taxonomy = $this->get_current_taxonomy(); + + if ( ! isset( $taxonomy ) && ! empty( $current_taxonomy ) ) { + $taxonomy = $current_taxonomy; + } + + return WPSEO_Utils::is_metabox_active( $taxonomy, 'taxonomy' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-fields-presenter.php b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-fields-presenter.php new file mode 100644 index 0000000..a32b853 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-fields-presenter.php @@ -0,0 +1,197 @@ +tax_meta = WPSEO_Taxonomy_Meta::get_term_meta( (int) $term->term_id, $term->taxonomy ); + } + + /** + * Displaying the form fields. + * + * @param array $fields Array with the fields that will be displayed. + * + * @return string + */ + public function html( array $fields ) { + $content = ''; + foreach ( $fields as $field_name => $field_configuration ) { + $content .= $this->form_row( 'wpseo_' . $field_name, $field_configuration ); + } + return $content; + } + + /** + * Create a row in the form table. + * + * @param string $field_name Variable the row controls. + * @param array $field_configuration Array with the field configuration. + * + * @return string + */ + private function form_row( $field_name, array $field_configuration ) { + $esc_field_name = esc_attr( $field_name ); + + $options = (array) $field_configuration['options']; + + if ( ! empty( $field_configuration['description'] ) ) { + $options['description'] = $field_configuration['description']; + } + + $label = $this->get_label( $field_configuration['label'], $esc_field_name ); + $field = $this->get_field( $field_configuration['type'], $esc_field_name, $this->get_field_value( $field_name ), $options ); + $help_content = ( $field_configuration['options']['help'] ?? '' ); + $help_button_text = ( $field_configuration['options']['help-button'] ?? '' ); + $help = new WPSEO_Admin_Help_Panel( $field_name, $help_button_text, $help_content ); + + return $this->parse_row( $label, $help, $field ); + } + + /** + * Generates the html for the given field config. + * + * @param string $field_type The fieldtype, e.g: text, checkbox, etc. + * @param string $field_name The name of the field. + * @param string $field_value The value of the field. + * @param array $options Array with additional options. + * + * @return string + */ + private function get_field( $field_type, $field_name, $field_value, array $options ) { + + $class = $this->get_class( $options ); + $field = ''; + $description = ''; + $aria_describedby = ''; + + if ( ! empty( $options['description'] ) ) { + $aria_describedby = ' aria-describedby="' . $field_name . '-desc"'; + $description = '

            ' . $options['description'] . '

            '; + } + + switch ( $field_type ) { + case 'div': + $field .= '
            '; + break; + case 'url': + $field .= ''; + break; + case 'text': + $field .= ''; + break; + case 'checkbox': + $field .= ''; + break; + case 'textarea': + $rows = 3; + if ( ! empty( $options['rows'] ) ) { + $rows = $options['rows']; + } + $field .= ''; + break; + case 'select': + if ( is_array( $options ) && $options !== [] ) { + $field .= ''; + } + break; + case 'hidden': + $field .= ''; + break; + } + + return $field . $description; + } + + /** + * Getting the value for given field_name. + * + * @param string $field_name The fieldname to get the value for. + * + * @return string + */ + private function get_field_value( $field_name ) { + if ( isset( $this->tax_meta[ $field_name ] ) && $this->tax_meta[ $field_name ] !== '' ) { + return $this->tax_meta[ $field_name ]; + } + + return ''; + } + + /** + * Getting the class attributes if $options contains a class key. + * + * @param array $options The array with field options. + * + * @return string + */ + private function get_class( array $options ) { + if ( ! empty( $options['class'] ) ) { + return ' class="' . esc_attr( $options['class'] ) . '"'; + } + + return ''; + } + + /** + * Getting the label HTML. + * + * @param string $label The label value. + * @param string $field_name The target field. + * + * @return string + */ + private function get_label( $label, $field_name ) { + if ( $label !== '' ) { + return ''; + } + + return ''; + } + + /** + * Returns the HTML for the row which contains label, help and the field. + * + * @param string $label The html for the label if there was a label set. + * @param WPSEO_Admin_Help_Panel $help The help panel to render in this row. + * @param string $field The html for the field. + * + * @return string + */ + private function parse_row( $label, WPSEO_Admin_Help_Panel $help, $field ) { + if ( $label !== '' || $help !== '' ) { + return $label . $help->get_button_html() . $help->get_panel_html() . $field; + } + + return $field; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-fields.php b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-fields.php new file mode 100644 index 0000000..d4801f2 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-fields.php @@ -0,0 +1,235 @@ +get_content_fields(); + break; + case 'settings': + $fields = $this->get_settings_fields(); + break; + case 'social': + $fields = $this->get_social_fields(); + break; + } + + return $this->filter_hidden_fields( $fields ); + } + + /** + * Returns array with the fields for the general tab. + * + * @return array + */ + protected function get_content_fields() { + $fields = [ + 'title' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'desc' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'linkdex' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'content_score' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'inclusive_language_score' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'focuskw' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'is_cornerstone' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + ]; + + /** + * Filter: 'wpseo_taxonomy_content_fields' - Adds the possibility to register additional content fields. + * + * @param array $additional_fields The additional fields. + */ + $additional_fields = apply_filters( 'wpseo_taxonomy_content_fields', [] ); + + return array_merge( $fields, $additional_fields ); + } + + /** + * Returns array with the fields for the settings tab. + * + * @return array + */ + protected function get_settings_fields() { + return [ + 'noindex' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'bctitle' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => ( WPSEO_Options::get( 'breadcrumbs-enable' ) !== true ), + ], + 'canonical' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + ]; + } + + /** + * Returning the fields for the social media tab. + * + * @return array + */ + protected function get_social_fields() { + $fields = []; + + if ( WPSEO_Options::get( 'opengraph', false ) === true ) { + $fields = [ + 'opengraph-title' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'opengraph-description' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'opengraph-image' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'opengraph-image-id' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + ]; + } + + if ( WPSEO_Options::get( 'twitter', false ) === true ) { + $fields = array_merge( + $fields, + [ + 'twitter-title' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'twitter-description' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'twitter-image' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + 'twitter-image-id' => [ + 'label' => '', + 'description' => '', + 'type' => 'hidden', + 'options' => '', + 'hide' => false, + ], + ], + ); + } + + return $fields; + } + + /** + * Filter the hidden fields. + * + * @param array $fields Array with the form fields that has will be filtered. + * + * @return array + */ + protected function filter_hidden_fields( array $fields ) { + foreach ( $fields as $field_name => $field_options ) { + if ( ! empty( $field_options['hide'] ) ) { + unset( $fields[ $field_name ] ); + } + } + + return $fields; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-metabox.php b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-metabox.php new file mode 100644 index 0000000..4a61551 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy-metabox.php @@ -0,0 +1,228 @@ +term = $term; + $this->taxonomy = $taxonomy; + $this->is_social_enabled = WPSEO_Options::get( 'opengraph', false ) || WPSEO_Options::get( 'twitter', false ); + + $this->seo_analysis = new WPSEO_Metabox_Analysis_SEO(); + $this->readability_analysis = new WPSEO_Metabox_Analysis_Readability(); + $this->inclusive_language_analysis = new WPSEO_Metabox_Analysis_Inclusive_Language(); + } + + /** + * Shows the Yoast SEO metabox for the term. + * + * @return void + */ + public function display() { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: $this->get_product_title() returns a hard-coded string. + printf( '

            %1$s

            ', $this->get_product_title() ); + + echo '
            '; + + $this->render_hidden_fields(); + $this->render_tabs(); + + echo '
            '; + echo '
            '; + } + + /** + * Renders the metabox hidden fields. + * + * @return void + */ + protected function render_hidden_fields() { + $fields_presenter = new WPSEO_Taxonomy_Fields_Presenter( $this->term ); + $field_definitions = new WPSEO_Taxonomy_Fields(); + + echo $fields_presenter->html( $field_definitions->get( 'content' ) ); + if ( WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || WPSEO_Options::get( 'disableadvanced_meta' ) === false ) { + echo $fields_presenter->html( $field_definitions->get( 'settings' ) ); + } + + if ( $this->is_social_enabled ) { + echo $fields_presenter->html( $field_definitions->get( 'social' ) ); + } + } + + /** + * Renders the metabox tabs. + * + * @return void + */ + protected function render_tabs() { + echo '
            '; + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: $this->get_product_title() returns a hard-coded string. + printf( '
              ', $this->get_product_title() ); + + $tabs = $this->get_tabs(); + + foreach ( $tabs as $tab ) { + $tab->display_link(); + } + + echo '
            '; + + foreach ( $tabs as $tab ) { + $tab->display_content(); + } + + echo '
            '; + } + + /** + * Returns the relevant metabox sections for the current view. + * + * @return WPSEO_Metabox_Section[] + */ + private function get_tabs() { + $tabs = []; + + $label = __( 'SEO', 'wordpress-seo' ); + if ( $this->seo_analysis->is_enabled() ) { + $label = '' . $label; + } + + $tabs[] = new WPSEO_Metabox_Section_React( 'content', $label ); + + if ( $this->readability_analysis->is_enabled() ) { + $tabs[] = new WPSEO_Metabox_Section_Readability(); + } + + if ( $this->inclusive_language_analysis->is_enabled() ) { + $tabs[] = new WPSEO_Metabox_Section_Inclusive_Language(); + } + + if ( $this->is_social_enabled ) { + $tabs[] = new WPSEO_Metabox_Section_React( + 'social', + '' . __( 'Social', 'wordpress-seo' ), + '', + [ + 'html_after' => '
            ', + ], + ); + } + + $tabs = array_merge( $tabs, $this->get_additional_tabs() ); + + return $tabs; + } + + /** + * Returns the metabox tabs that have been added by other plugins. + * + * @return WPSEO_Metabox_Section_Additional[] + */ + protected function get_additional_tabs() { + $tabs = []; + + /** + * Private filter: 'yoast_free_additional_taxonomy_metabox_sections'. + * + * Meant for internal use only. Allows adding additional tabs to the Yoast SEO metabox for taxonomies. + * + * @param array[] $tabs { + * An array of arrays with tab specifications. + * + * @type array $tab { + * A tab specification. + * + * @type string $name The name of the tab. Used in the HTML IDs, href and aria properties. + * @type string $link_content The content of the tab link. + * @type string $content The content of the tab. + * @type array $options { + * Optional. Extra options. + * + * @type string $link_class Optional. The class for the tab link. + * @type string $link_aria_label Optional. The aria label of the tab link. + * } + * } + * } + */ + $requested_tabs = apply_filters( 'yoast_free_additional_taxonomy_metabox_sections', [] ); + + foreach ( $requested_tabs as $tab ) { + if ( is_array( $tab ) && array_key_exists( 'name', $tab ) && array_key_exists( 'link_content', $tab ) && array_key_exists( 'content', $tab ) ) { + $options = array_key_exists( 'options', $tab ) ? $tab['options'] : []; + $tabs[] = new WPSEO_Metabox_Section_Additional( + $tab['name'], + $tab['link_content'], + $tab['content'], + $options, + ); + } + } + + return $tabs; + } + + /** + * Retrieves the product title. + * + * @return string The product title. + */ + protected function get_product_title() { + return YoastSEO()->helpers->product->get_product_name(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy.php b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy.php new file mode 100644 index 0000000..7579443 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/taxonomy/class-taxonomy.php @@ -0,0 +1,487 @@ +taxonomy = $this::get_taxonomy(); + + add_action( 'edit_term', [ $this, 'update_term' ], 99, 3 ); + add_action( 'init', [ $this, 'custom_category_descriptions_allow_html' ] ); + add_action( 'admin_init', [ $this, 'admin_init' ] ); + + if ( self::is_term_overview( $GLOBALS['pagenow'] ) ) { + new WPSEO_Taxonomy_Columns(); + } + $this->analysis_seo = new WPSEO_Metabox_Analysis_SEO(); + $this->analysis_readability = new WPSEO_Metabox_Analysis_Readability(); + $this->analysis_inclusive_language = new WPSEO_Metabox_Analysis_Inclusive_Language(); + } + + /** + * Add hooks late enough for taxonomy object to be available for checks. + * + * @return void + */ + public function admin_init() { + + $taxonomy = get_taxonomy( $this->taxonomy ); + + if ( empty( $taxonomy ) || empty( $taxonomy->public ) || ! $this->show_metabox() ) { + return; + } + + // Adds custom category description editor. Needs a hook that runs before the description field. + add_action( "{$this->taxonomy}_term_edit_form_top", [ $this, 'custom_category_description_editor' ] ); + + add_action( sanitize_text_field( $this->taxonomy ) . '_edit_form', [ $this, 'term_metabox' ], 90, 1 ); + add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] ); + } + + /** + * Show the SEO inputs for term. + * + * @param stdClass|WP_Term $term Term to show the edit boxes for. + * + * @return void + */ + public function term_metabox( $term ) { + if ( WPSEO_Metabox::is_internet_explorer() ) { + $this->show_internet_explorer_notice(); + return; + } + + $metabox = new WPSEO_Taxonomy_Metabox( $this->taxonomy, $term ); + $metabox->display(); + } + + /** + * Renders the content for the internet explorer metabox. + * + * @return void + */ + private function show_internet_explorer_notice() { + $product_title = YoastSEO()->helpers->product->get_product_name(); + + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: $product_title is hardcoded. + printf( '

            %1$s

            ', $product_title ); + echo '
            '; + + $content = sprintf( + /* translators: 1: Link start tag to the Firefox website, 2: Link start tag to the Chrome website, 3: Link start tag to the Edge website, 4: Link closing tag. */ + esc_html__( 'The browser you are currently using is unfortunately rather dated. Since we strive to give you the best experience possible, we no longer support this browser. Instead, please use %1$sFirefox%4$s, %2$sChrome%4$s or %3$sMicrosoft Edge%4$s.', 'wordpress-seo' ), + '', + '', + '', + '', + ); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output escaped above. + echo new Alert_Presenter( $content ); + + echo '
            '; + } + + /** + * Queue assets for taxonomy screens. + * + * @since 1.5.0 + * + * @return void + */ + public function admin_enqueue_scripts() { + + $pagenow = $GLOBALS['pagenow']; + + if ( ! ( self::is_term_edit( $pagenow ) || self::is_term_overview( $pagenow ) ) ) { + return; + } + + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_style( 'monorepo' ); + + $tag_id = $this::get_tag_id(); + + if ( + self::is_term_edit( $pagenow ) + && $tag_id !== null + ) { + wp_enqueue_media(); // Enqueue files needed for upload functionality. + + $asset_manager->enqueue_style( 'metabox-css' ); + if ( $this->analysis_readability->is_enabled() ) { + $asset_manager->enqueue_style( 'scoring' ); + } + $asset_manager->enqueue_style( 'ai-generator' ); + $asset_manager->enqueue_script( 'term-edit' ); + + /** + * Remove the emoji script as it is incompatible with both React and any + * contenteditable fields. + */ + remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); + + $asset_manager->localize_script( 'term-edit', 'wpseoAdminL10n', WPSEO_Utils::get_admin_l10n() ); + + $script_data = [ + 'analysis' => [ + 'plugins' => [ + 'replaceVars' => [ + 'replace_vars' => $this->get_replace_vars(), + 'recommended_replace_vars' => $this->get_recommended_replace_vars(), + 'scope' => $this->determine_scope(), + ], + 'shortcodes' => [ + 'wpseo_shortcode_tags' => $this->get_valid_shortcode_tags(), + 'wpseo_filter_shortcodes_nonce' => wp_create_nonce( 'wpseo-filter-shortcodes' ), + ], + ], + 'worker' => [ + 'url' => YoastSEO()->helpers->asset->get_asset_url( 'yoast-seo-analysis-worker' ), + 'dependencies' => YoastSEO()->helpers->asset->get_dependency_urls_by_handle( 'yoast-seo-analysis-worker' ), + 'keywords_assessment_url' => YoastSEO()->helpers->asset->get_asset_url( 'yoast-seo-used-keywords-assessment' ), + 'log_level' => WPSEO_Utils::get_analysis_worker_log_level(), + ], + ], + 'metabox' => $this->localize_term_scraper_script( $tag_id ), + 'isTerm' => true, + 'postId' => $tag_id, + 'postType' => $this->get_taxonomy(), + 'usedKeywordsNonce' => wp_create_nonce( 'wpseo-keyword-usage' ), + ]; + + /** + * The website information repository. + * + * @var Website_Information_Repository $repo + */ + $repo = YoastSEO()->classes->get( Website_Information_Repository::class ); + $term_information = $repo->get_term_site_information(); + $term_information->set_term( get_term_by( 'id', $tag_id, $this::get_taxonomy() ) ); + $script_data = array_merge_recursive( $term_information->get_legacy_site_information(), $script_data ); + + $asset_manager->localize_script( 'term-edit', 'wpseoScriptData', $script_data ); + } + + if ( self::is_term_overview( $pagenow ) ) { + $asset_manager->enqueue_script( 'edit-page' ); + $asset_manager->enqueue_style( 'edit-page' ); + } + } + + /** + * Update the taxonomy meta data on save. + * + * @param int $term_id ID of the term to save data for. + * @param int $tt_id The taxonomy_term_id for the term. + * @param string $taxonomy The taxonomy the term belongs to. + * + * @return void + */ + public function update_term( $term_id, $tt_id, $taxonomy ) { + // Bail if this is a multisite installation and the site has been switched. + if ( is_multisite() && ms_is_switched() ) { + return; + } + + /* Create post array with only our values. */ + $new_meta_data = []; + foreach ( WPSEO_Taxonomy_Meta::$defaults_per_term as $key => $default ) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reason: Nonce is already checked by WordPress before executing this action. + if ( isset( $_POST[ $key ] ) && is_string( $_POST[ $key ] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: $data is getting sanitized later. + $data = wp_unslash( $_POST[ $key ] ); + $new_meta_data[ $key ] = ( $key !== 'wpseo_canonical' ) ? WPSEO_Utils::sanitize_text_field( $data ) : WPSEO_Utils::sanitize_url( $data ); + } + + // If analysis is disabled remove that analysis score value from the DB. + if ( $this->is_meta_value_disabled( $key ) ) { + $new_meta_data[ $key ] = ''; + } + } + + // Saving the values. + WPSEO_Taxonomy_Meta::set_values( $term_id, $taxonomy, $new_meta_data ); + } + + /** + * Determines if the given meta value key is disabled. + * + * @param string $key The key of the meta value. + * @return bool Whether the given meta value key is disabled. + */ + public function is_meta_value_disabled( $key ) { + if ( $key === 'wpseo_linkdex' && ! $this->analysis_seo->is_enabled() ) { + return true; + } + + if ( $key === 'wpseo_content_score' && ! $this->analysis_readability->is_enabled() ) { + return true; + } + + if ( $key === 'wpseo_inclusive_language_score' && ! $this->analysis_inclusive_language->is_enabled() ) { + return true; + } + + return false; + } + + /** + * Allows post-kses-filtered HTML in term descriptions. + * + * @return void + */ + public function custom_category_descriptions_allow_html() { + remove_filter( 'term_description', 'wp_kses_data' ); + remove_filter( 'pre_term_description', 'wp_filter_kses' ); + add_filter( 'term_description', 'wp_kses_post' ); + add_filter( 'pre_term_description', 'wp_filter_post_kses' ); + } + + /** + * Output the WordPress editor. + * + * @return void + */ + public function custom_category_description_editor() { + wp_editor( '', 'description' ); + } + + /** + * Pass variables to js for use with the term-scraper. + * + * @param int $term_id The ID of the term to localize the script for. + * + * @return array + */ + public function localize_term_scraper_script( $term_id ) { + $term = get_term_by( 'id', $term_id, $this::get_taxonomy() ); + $taxonomy = get_taxonomy( $term->taxonomy ); + + $term_formatter = new WPSEO_Metabox_Formatter( + new WPSEO_Term_Metabox_Formatter( $taxonomy, $term ), + ); + + return $term_formatter->get_values(); + } + + /** + * Pass some variables to js for replacing variables. + * + * @return array + */ + public function localize_replace_vars_script() { + return [ + 'replace_vars' => $this->get_replace_vars(), + 'recommended_replace_vars' => $this->get_recommended_replace_vars(), + 'scope' => $this->determine_scope(), + ]; + } + + /** + * Determines the scope based on the current taxonomy. + * This can be used by the replacevar plugin to determine if a replacement needs to be executed. + * + * @return string String decribing the current scope. + */ + private function determine_scope() { + $taxonomy = $this::get_taxonomy(); + + if ( $taxonomy === 'category' ) { + return 'category'; + } + + if ( $taxonomy === 'post_tag' ) { + return 'tag'; + } + + return 'term'; + } + + /** + * Determines if a given page is the term overview page. + * + * @param string $page The string to check for the term overview page. + * + * @return bool + */ + public static function is_term_overview( $page ) { + return $page === 'edit-tags.php'; + } + + /** + * Determines if a given page is the term edit page. + * + * @param string $page The string to check for the term edit page. + * + * @return bool + */ + public static function is_term_edit( $page ) { + return $page === 'term.php'; + } + + /** + * Function to get the labels for the current taxonomy. + * + * @return object|null Labels for the current taxonomy or null if the taxonomy is not set. + */ + public static function get_labels() { + $term = self::get_taxonomy(); + if ( $term !== '' ) { + $taxonomy = get_taxonomy( $term ); + return $taxonomy->labels; + } + return null; + } + + /** + * Retrieves a template. + * Check if metabox for current taxonomy should be displayed. + * + * @return bool + */ + private function show_metabox() { + $option_key = 'display-metabox-tax-' . $this->taxonomy; + + return WPSEO_Options::get( $option_key ); + } + + /** + * Getting the taxonomy from the URL. + * + * @return string + */ + private static function get_taxonomy() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['taxonomy'] ) && is_string( $_GET['taxonomy'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + return sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ); + } + return ''; + } + + /** + * Get the current tag ID from the GET parameters. + * + * @return int|null the tag ID if it exists, null otherwise. + */ + private static function get_tag_id() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['tag_ID'] ) && is_string( $_GET['tag_ID'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, We are casting to an integer. + $tag_id = (int) wp_unslash( $_GET['tag_ID'] ); + if ( $tag_id > 0 ) { + return $tag_id; + } + } + return null; + } + + /** + * Prepares the replace vars for localization. + * + * @return array The replacement variables. + */ + private function get_replace_vars() { + $term_id = $this::get_tag_id(); + $term = get_term_by( 'id', $term_id, $this::get_taxonomy() ); + + $cached_replacement_vars = []; + + $vars_to_cache = [ + 'date', + 'id', + 'sitename', + 'sitedesc', + 'sep', + 'page', + 'term_title', + 'term_description', + 'term_hierarchy', + 'category_description', + 'tag_description', + 'searchphrase', + 'currentyear', + ]; + + foreach ( $vars_to_cache as $var ) { + $cached_replacement_vars[ $var ] = wpseo_replace_vars( '%%' . $var . '%%', $term ); + } + + return $cached_replacement_vars; + } + + /** + * Prepares the recommended replace vars for localization. + * + * @return array The recommended replacement variables. + */ + private function get_recommended_replace_vars() { + $recommended_replace_vars = new WPSEO_Admin_Recommended_Replace_Vars(); + $taxonomy = $this::get_taxonomy(); + + if ( $taxonomy === '' ) { + return []; + } + + // What is recommended depends on the current context. + $page_type = $recommended_replace_vars->determine_for_term( $taxonomy ); + + return $recommended_replace_vars->get_recommended_replacevars_for( $page_type ); + } + + /** + * Returns an array with shortcode tags for all registered shortcodes. + * + * @return array Array with shortcode tags. + */ + private function get_valid_shortcode_tags() { + $shortcode_tags = []; + + foreach ( $GLOBALS['shortcode_tags'] as $tag => $description ) { + $shortcode_tags[] = $tag; + } + + return $shortcode_tags; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-addon-data.php b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-addon-data.php new file mode 100644 index 0000000..0cbc27c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-addon-data.php @@ -0,0 +1,126 @@ +is_installed( WPSEO_Addon_Manager::LOCAL_SLUG ) ) { + $addon_settings = $this->get_local_addon_settings( $addon_settings, 'wpseo_local', WPSEO_Addon_Manager::LOCAL_SLUG, $this->local_include_list ); + } + + if ( $addon_manager->is_installed( WPSEO_Addon_Manager::WOOCOMMERCE_SLUG ) ) { + $addon_settings = $this->get_addon_settings( $addon_settings, 'wpseo_woo', WPSEO_Addon_Manager::WOOCOMMERCE_SLUG, $this->woo_include_list ); + } + + if ( $addon_manager->is_installed( WPSEO_Addon_Manager::NEWS_SLUG ) ) { + $addon_settings = $this->get_addon_settings( $addon_settings, 'wpseo_news', WPSEO_Addon_Manager::NEWS_SLUG, $this->news_include_list ); + } + + if ( $addon_manager->is_installed( WPSEO_Addon_Manager::VIDEO_SLUG ) ) { + $addon_settings = $this->get_addon_settings( $addon_settings, 'wpseo_video', WPSEO_Addon_Manager::VIDEO_SLUG, $this->video_include_list ); + } + + return $addon_settings; + } + + /** + * Gets the tracked options from the addon + * + * @param array $addon_settings The current list of addon settings. + * @param string $source_name The option key of the addon. + * @param string $slug The addon slug. + * @param array $option_include_list All the options to be included in tracking. + * + * @return array + */ + public function get_addon_settings( array $addon_settings, $source_name, $slug, $option_include_list ) { + $source_options = get_option( $source_name, [] ); + if ( ! is_array( $source_options ) || empty( $source_options ) ) { + return $addon_settings; + } + $addon_settings[ $slug ] = array_intersect_key( $source_options, array_flip( $option_include_list ) ); + + return $addon_settings; + } + + /** + * Filter business_type in local addon settings. + * + * Remove the business_type setting when 'multiple_locations_shared_business_info' setting is turned off. + * + * @param array $addon_settings The current list of addon settings. + * @param string $source_name The option key of the addon. + * @param string $slug The addon slug. + * @param array $option_include_list All the options to be included in tracking. + * + * @return array + */ + public function get_local_addon_settings( array $addon_settings, $source_name, $slug, $option_include_list ) { + $source_options = get_option( $source_name, [] ); + if ( ! is_array( $source_options ) || empty( $source_options ) ) { + return $addon_settings; + } + $addon_settings[ $slug ] = array_intersect_key( $source_options, array_flip( $option_include_list ) ); + + if ( array_key_exists( 'use_multiple_locations', $source_options ) && array_key_exists( 'business_type', $addon_settings[ $slug ] ) && $source_options['use_multiple_locations'] === 'on' && $source_options['multiple_locations_shared_business_info'] === 'off' ) { + $addon_settings[ $slug ]['business_type'] = 'multiple_locations'; + } + + if ( ! ( new WooCommerce_Conditional() )->is_met() ) { + unset( $addon_settings[ $slug ]['woocommerce_local_pickup_setting'] ); + } + + return $addon_settings; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-default-data.php b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-default-data.php new file mode 100644 index 0000000..498e7d0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-default-data.php @@ -0,0 +1,60 @@ + get_option( 'blogname' ), + '@timestamp' => (int) gmdate( 'Uv' ), + 'wpVersion' => $this->get_wordpress_version(), + 'homeURL' => home_url(), + 'adminURL' => admin_url(), + 'isMultisite' => is_multisite(), + 'siteLanguage' => get_bloginfo( 'language' ), + 'gmt_offset' => get_option( 'gmt_offset' ), + 'timezoneString' => get_option( 'timezone_string' ), + 'migrationStatus' => get_option( 'yoast_migrations_free' ), + 'countPosts' => $this->get_post_count( 'post' ), + 'countPages' => $this->get_post_count( 'page' ), + ]; + } + + /** + * Returns the number of posts of a certain type. + * + * @param string $post_type The post type return the count for. + * + * @return int The count for this post type. + */ + protected function get_post_count( $post_type ) { + $count = wp_count_posts( $post_type ); + if ( isset( $count->publish ) ) { + return $count->publish; + } + return 0; + } + + /** + * Returns the WordPress version. + * + * @return string The version. + */ + protected function get_wordpress_version() { + global $wp_version; + + return $wp_version; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-plugin-data.php b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-plugin-data.php new file mode 100644 index 0000000..2c585e1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-plugin-data.php @@ -0,0 +1,90 @@ + $this->get_plugin_data(), + ]; + } + + /** + * Returns all plugins. + * + * @return array The formatted plugins. + */ + protected function get_plugin_data() { + + if ( ! function_exists( 'get_plugin_data' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + $plugins = wp_get_active_and_valid_plugins(); + + $plugins = array_map( 'get_plugin_data', $plugins ); + $this->set_auto_update_plugin_list(); + $plugins = array_map( [ $this, 'format_plugin' ], $plugins ); + + $plugin_data = []; + foreach ( $plugins as $plugin ) { + $plugin_key = sanitize_title( $plugin['name'] ); + $plugin_data[ $plugin_key ] = $plugin; + } + + return $plugin_data; + } + + /** + * Sets all auto updating plugin data so it can be used in the tracking list. + * + * @return void + */ + public function set_auto_update_plugin_list() { + + $auto_update_plugins = []; + $auto_update_plugin_files = get_option( 'auto_update_plugins' ); + if ( $auto_update_plugin_files ) { + foreach ( $auto_update_plugin_files as $auto_update_plugin ) { + $data = get_plugin_data( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $auto_update_plugin ); + $auto_update_plugins[ $data['Name'] ] = $data; + } + } + + $this->auto_update_plugin_list = $auto_update_plugins; + } + + /** + * Formats the plugin array. + * + * @param array $plugin The plugin details. + * + * @return array The formatted array. + */ + protected function format_plugin( array $plugin ) { + + return [ + 'name' => $plugin['Name'], + 'version' => $plugin['Version'], + 'auto_updating' => array_key_exists( $plugin['Name'], $this->auto_update_plugin_list ), + ]; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-server-data.php b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-server-data.php new file mode 100644 index 0000000..220753f --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-server-data.php @@ -0,0 +1,85 @@ + $this->get_server_data(), + ]; + } + + /** + * Returns the values with server details. + * + * @return array Array with the value. + */ + protected function get_server_data() { + $server_data = []; + + // Validate if the server address is a valid IP-address. + $ipaddress = isset( $_SERVER['SERVER_ADDR'] ) ? filter_var( wp_unslash( $_SERVER['SERVER_ADDR'] ), FILTER_VALIDATE_IP ) : ''; + if ( $ipaddress ) { + $server_data['ip'] = $ipaddress; + $server_data['Hostname'] = gethostbyaddr( $ipaddress ); + } + + $server_data['os'] = function_exists( 'php_uname' ) ? php_uname() : PHP_OS; + $server_data['PhpVersion'] = PHP_VERSION; + $server_data['CurlVersion'] = $this->get_curl_info(); + $server_data['PhpExtensions'] = $this->get_php_extensions(); + + return $server_data; + } + + /** + * Returns details about the curl version. + * + * @return array|null The curl info. Or null when curl isn't available.. + */ + protected function get_curl_info() { + if ( ! function_exists( 'curl_version' ) ) { + return null; + } + + $curl = curl_version(); + + $ssl_support = true; + if ( ! $curl['features'] && CURL_VERSION_SSL ) { + $ssl_support = false; + } + + return [ + 'version' => $curl['version'], + 'sslSupport' => $ssl_support, + ]; + } + + /** + * Returns a list with php extensions. + * + * @return array Returns the state of the php extensions. + */ + protected function get_php_extensions() { + return [ + 'imagick' => extension_loaded( 'imagick' ), + 'filter' => extension_loaded( 'filter' ), + 'bcmath' => extension_loaded( 'bcmath' ), + 'pcre' => extension_loaded( 'pcre' ), + 'xml' => extension_loaded( 'xml' ), + 'pdo_mysql' => extension_loaded( 'pdo_mysql' ), + ]; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-settings-data.php b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-settings-data.php new file mode 100644 index 0000000..5339343 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-settings-data.php @@ -0,0 +1,295 @@ +include_list = apply_filters( 'wpseo_tracking_settings_include_list', $this->include_list ); + + // Always include the tracking only option keys. + $this->include_list = array_merge( $this->include_list, YoastSEO()->helpers->options->get_tracking_only_options() ); + + $options = WPSEO_Options::get_all(); + // Returns the settings of which the keys intersect with the values of the include list. + $options = array_intersect_key( $options, array_flip( $this->include_list ) ); + + return [ + 'settings' => $this->anonymize_settings( $options ), + ]; + } + + /** + * Anonimizes the WPSEO_Options array by replacing all $anonymous_settings values to 'used'. + * + * @param array $settings The settings. + * + * @return array The anonymized settings. + */ + private function anonymize_settings( $settings ) { + foreach ( $this->anonymous_settings as $setting ) { + if ( ! empty( $settings[ $setting ] ) ) { + $settings[ $setting ] = 'used'; + } + } + + return $settings; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-theme-data.php b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-theme-data.php new file mode 100644 index 0000000..e222595 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking-theme-data.php @@ -0,0 +1,51 @@ + [ + 'name' => $theme->get( 'Name' ), + 'url' => $theme->get( 'ThemeURI' ), + 'version' => $theme->get( 'Version' ), + 'author' => [ + 'name' => $theme->get( 'Author' ), + 'url' => $theme->get( 'AuthorURI' ), + ], + 'parentTheme' => $this->get_parent_theme( $theme ), + 'blockTemplateSupport' => current_theme_supports( 'block-templates' ), + 'isBlockTheme' => function_exists( 'wp_is_block_theme' ) && wp_is_block_theme(), + ], + ]; + } + + /** + * Returns the name of the parent theme. + * + * @param WP_Theme $theme The theme object. + * + * @return string|null The name of the parent theme or null. + */ + private function get_parent_theme( WP_Theme $theme ) { + if ( is_child_theme() ) { + return $theme->get( 'Template' ); + } + + return null; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking.php b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking.php new file mode 100644 index 0000000..a7154c2 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/tracking/class-tracking.php @@ -0,0 +1,240 @@ +tracking_enabled() ) { + return; + } + + $this->endpoint = $endpoint; + $this->threshold = $threshold; + $this->current_time = time(); + } + + /** + * Registers all hooks to WordPress. + * + * @return void + */ + public function register_hooks() { + if ( ! $this->tracking_enabled() ) { + return; + } + + // Send tracking data on `admin_init`. + add_action( 'admin_init', [ $this, 'send' ], 1 ); + + // Add an action hook that will be triggered at the specified time by `wp_schedule_single_event()`. + add_action( 'wpseo_send_tracking_data_after_core_update', [ $this, 'send' ] ); + // Call `wp_schedule_single_event()` after a WordPress core update. + add_action( 'upgrader_process_complete', [ $this, 'schedule_tracking_data_sending' ], 10, 2 ); + } + + /** + * Schedules a new sending of the tracking data after a WordPress core update. + * + * @param bool|WP_Upgrader $upgrader Optional. WP_Upgrader instance or false. + * Depending on context, it might be a Theme_Upgrader, + * Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader. + * instance. Default false. + * @param array $data Array of update data. + * + * @return void + */ + public function schedule_tracking_data_sending( $upgrader = false, $data = [] ) { + // Return if it's not a WordPress core update. + if ( ! $upgrader || ! isset( $data['type'] ) || $data['type'] !== 'core' ) { + return; + } + + /* + * To uniquely identify the scheduled cron event, `wp_next_scheduled()` + * needs to receive the same arguments as those used when originally + * scheduling the event otherwise it will always return false. + */ + if ( ! wp_next_scheduled( 'wpseo_send_tracking_data_after_core_update', [ true ] ) ) { + /* + * Schedule sending of data tracking 6 hours after a WordPress core + * update. Pass a `true` parameter for the callback `$force` argument. + */ + wp_schedule_single_event( ( time() + ( HOUR_IN_SECONDS * 6 ) ), 'wpseo_send_tracking_data_after_core_update', [ true ] ); + } + } + + /** + * Sends the tracking data. + * + * @param bool $force Whether to send the tracking data ignoring the two + * weeks time threshold. Default false. + * + * @return void + */ + public function send( $force = false ) { + if ( ! $this->should_send_tracking( $force ) ) { + return; + } + + // Set a 'content-type' header of 'application/json'. + $tracking_request_args = [ + 'headers' => [ + 'content-type:' => 'application/json', + ], + ]; + + $collector = $this->get_collector(); + + $request = new WPSEO_Remote_Request( $this->endpoint, $tracking_request_args ); + $request->set_body( $collector->get_as_json() ); + $request->send(); + + update_option( $this->option_name, $this->current_time, 'yes' ); + } + + /** + * Determines whether to send the tracking data. + * + * Returns false if tracking is disabled or the current page is one of the + * admin plugins pages. Returns true when there's no tracking data stored or + * the data was sent more than two weeks ago. The two weeks interval is set + * when instantiating the class. + * + * @param bool $ignore_time_treshhold Whether to send the tracking data ignoring + * the two weeks time treshhold. Default false. + * + * @return bool True when tracking data should be sent. + */ + protected function should_send_tracking( $ignore_time_treshhold = false ) { + global $pagenow; + + // Only send tracking on the main site of a multi-site instance. This returns true on non-multisite installs. + if ( is_network_admin() || ! is_main_site() ) { + return false; + } + + // Because we don't want to possibly block plugin actions with our routines. + if ( in_array( $pagenow, [ 'plugins.php', 'plugin-install.php', 'plugin-editor.php' ], true ) ) { + return false; + } + + $last_time = get_option( $this->option_name ); + + // When tracking data haven't been sent yet or when sending data is forced. + if ( ! $last_time || $ignore_time_treshhold ) { + return true; + } + + return $this->exceeds_treshhold( $this->current_time - $last_time ); + } + + /** + * Checks if the given amount of seconds exceeds the set threshold. + * + * @param int $seconds The amount of seconds to check. + * + * @return bool True when seconds is bigger than threshold. + */ + protected function exceeds_treshhold( $seconds ) { + return ( $seconds > $this->threshold ); + } + + /** + * Returns the collector for collecting the data. + * + * @return WPSEO_Collector The instance of the collector. + */ + public function get_collector() { + $collector = new WPSEO_Collector(); + $collector->add_collection( new WPSEO_Tracking_Default_Data() ); + $collector->add_collection( new WPSEO_Tracking_Server_Data() ); + $collector->add_collection( new WPSEO_Tracking_Theme_Data() ); + $collector->add_collection( new WPSEO_Tracking_Plugin_Data() ); + $collector->add_collection( new WPSEO_Tracking_Settings_Data() ); + $collector->add_collection( new WPSEO_Tracking_Addon_Data() ); + $collector->add_collection( YoastSEO()->classes->get( Missing_Indexables_Collector::class ) ); + $collector->add_collection( YoastSEO()->classes->get( To_Be_Cleaned_Indexables_Collector::class ) ); + + return $collector; + } + + /** + * See if we should run tracking at all. + * + * @return bool True when we can track, false when we can't. + */ + private function tracking_enabled() { + // Check if we're allowing tracking. + $tracking = WPSEO_Options::get( 'tracking' ); + + if ( $tracking === false ) { + return false; + } + + // Save this state. + if ( $tracking === null ) { + /** + * Filter: 'wpseo_enable_tracking' - Enables the data tracking of Yoast SEO Premium and add-ons. + * + * @param string|false $is_enabled The enabled state. Default is false. + */ + $tracking = apply_filters( 'wpseo_enable_tracking', false ); + + WPSEO_Options::set( 'tracking', $tracking ); + } + + if ( $tracking === false ) { + return false; + } + + if ( ! YoastSEO()->helpers->environment->is_production_mode() ) { + return false; + } + + return true; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-feature-toggle.php b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-feature-toggle.php new file mode 100644 index 0000000..9dd62ab --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-feature-toggle.php @@ -0,0 +1,206 @@ + $value ) { + if ( property_exists( $this, $key ) ) { + $this->$key = $value; + } + } + } + + /** + * Magic isset-er. + * + * @param string $key Key to check whether a value for it is set. + * + * @return bool True if set, false otherwise. + */ + public function __isset( $key ) { + return isset( $this->$key ); + } + + /** + * Magic getter. + * + * @param string $key Key to get the value for. + * + * @return mixed Value for the key, or null if not set. + */ + public function __get( $key ) { + if ( isset( $this->$key ) ) { + return $this->$key; + } + + return null; + } + + /** + * Checks whether the feature for this toggle is enabled. + * + * @return bool True if the feature is enabled, false otherwise. + */ + public function is_enabled() { + return (bool) WPSEO_Options::get( $this->setting ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-feature-toggles.php b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-feature-toggles.php new file mode 100644 index 0000000..7785510 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-feature-toggles.php @@ -0,0 +1,281 @@ +toggles ??= $this->load_toggles(); + + return $this->toggles; + } + + /** + * Loads the available feature toggles. + * + * Also ensures that the toggles are all Yoast_Feature_Toggle instances and sorted by their order value. + * + * @return array List of sorted Yoast_Feature_Toggle instances. + */ + protected function load_toggles() { + $xml_sitemap_extra = false; + if ( WPSEO_Options::get( 'enable_xml_sitemap' ) ) { + $xml_sitemap_extra = '' . esc_html__( 'See the XML sitemap.', 'wordpress-seo' ) . ''; + } + + $feature_toggles = [ + (object) [ + 'name' => __( 'SEO analysis', 'wordpress-seo' ), + 'setting' => 'keyword_analysis_active', + 'label' => __( 'The SEO analysis offers suggestions to improve the SEO of your text.', 'wordpress-seo' ), + 'read_more_label' => __( 'Learn how the SEO analysis can help you rank.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/2ak', + 'order' => 10, + ], + (object) [ + 'name' => __( 'Readability analysis', 'wordpress-seo' ), + 'setting' => 'content_analysis_active', + 'label' => __( 'The readability analysis offers suggestions to improve the structure and style of your text.', 'wordpress-seo' ), + 'read_more_label' => __( 'Discover why readability is important for SEO.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/2ao', + 'order' => 20, + ], + (object) [ + 'name' => __( 'Inclusive language analysis', 'wordpress-seo' ), + 'supported_languages' => Language_Helper::$languages_with_inclusive_language_support, + 'setting' => 'inclusive_language_analysis_active', + 'label' => __( 'The inclusive language analysis offers suggestions to write more inclusive copy.', 'wordpress-seo' ), + 'read_more_label' => __( 'Discover why inclusive language is important for SEO.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/inclusive-language-features-free', + 'order' => 25, + ], + (object) [ + 'name' => __( 'Cornerstone content', 'wordpress-seo' ), + 'setting' => 'enable_cornerstone_content', + 'label' => __( 'The cornerstone content feature lets you to mark and filter cornerstone content on your website.', 'wordpress-seo' ), + 'read_more_label' => __( 'Find out how cornerstone content can help you improve your site structure.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/dashboard-help-cornerstone', + 'order' => 30, + ], + (object) [ + 'name' => __( 'Text link counter', 'wordpress-seo' ), + 'setting' => 'enable_text_link_counter', + 'label' => __( 'The text link counter helps you improve your site structure.', 'wordpress-seo' ), + 'read_more_label' => __( 'Find out how the text link counter can enhance your SEO.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/2aj', + 'order' => 40, + ], + (object) [ + 'name' => __( 'Insights', 'wordpress-seo' ), + 'setting' => 'enable_metabox_insights', + 'label' => __( 'Find relevant data about your content right in the Insights section in the Yoast SEO metabox. You’ll see what words you use most often and if they’re a match with your keywords! ', 'wordpress-seo' ), + 'read_more_label' => __( 'Find out how Insights can help you improve your content.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/4ew', + 'premium_url' => 'https://yoa.st/2ai', + 'order' => 41, + ], + (object) [ + 'name' => __( 'Link suggestions', 'wordpress-seo' ), + 'premium' => true, + 'setting' => 'enable_link_suggestions', + 'label' => __( 'Get relevant internal linking suggestions — while you’re writing! The link suggestions metabox shows a list of posts on your blog with similar content that might be interesting to link to. ', 'wordpress-seo' ), + 'read_more_label' => __( 'Read more about how internal linking can improve your site structure.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/4ev', + 'premium_url' => 'https://yoa.st/17g', + 'premium_upsell_url' => 'https://yoa.st/get-link-suggestions', + 'order' => 42, + ], + (object) [ + 'name' => __( 'XML sitemaps', 'wordpress-seo' ), + 'setting' => 'enable_xml_sitemap', + /* translators: %s: Yoast SEO */ + 'label' => sprintf( __( 'Enable the XML sitemaps that %s generates.', 'wordpress-seo' ), 'Yoast SEO' ), + 'read_more_label' => __( 'Read why XML Sitemaps are important for your site.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/2a-', + 'extra' => $xml_sitemap_extra, + 'after' => $this->sitemaps_toggle_after(), + 'order' => 60, + ], + (object) [ + 'name' => __( 'Admin bar menu', 'wordpress-seo' ), + 'setting' => 'enable_admin_bar_menu', + /* translators: 1: Yoast SEO */ + 'label' => sprintf( __( 'The %1$s admin bar menu contains useful links to third-party tools for analyzing pages and makes it easy to see if you have new notifications.', 'wordpress-seo' ), 'Yoast SEO' ), + 'order' => 80, + ], + (object) [ + 'name' => __( 'Security: no advanced or schema settings for authors', 'wordpress-seo' ), + 'setting' => 'disableadvanced_meta', + 'label' => sprintf( + /* translators: 1: Yoast SEO, 2: translated version of "Off" */ + __( 'The advanced section of the %1$s meta box allows a user to remove posts from the search results or change the canonical. The settings in the schema tab allows a user to change schema meta data for a post. These are things you might not want any author to do. That\'s why, by default, only editors and administrators can do this. Setting to "%2$s" allows all users to change these settings.', 'wordpress-seo' ), + 'Yoast SEO', + __( 'Off', 'wordpress-seo' ), + ), + 'order' => 90, + ], + (object) [ + 'name' => __( 'Usage tracking', 'wordpress-seo' ), + 'label' => __( 'Usage tracking', 'wordpress-seo' ), + 'setting' => 'tracking', + 'read_more_label' => sprintf( + /* translators: 1: Yoast SEO */ + __( 'Allow us to track some data about your site to improve our plugin.', 'wordpress-seo' ), + 'Yoast SEO', + ), + 'read_more_url' => 'https://yoa.st/usage-tracking-2', + 'order' => 95, + ], + (object) [ + 'name' => __( 'REST API: Head endpoint', 'wordpress-seo' ), + 'setting' => 'enable_headless_rest_endpoints', + 'label' => sprintf( + /* translators: 1: Yoast SEO */ + __( 'This %1$s REST API endpoint gives you all the metadata you need for a specific URL. This will make it very easy for headless WordPress sites to use %1$s for all their SEO meta output.', 'wordpress-seo' ), + 'Yoast SEO', + ), + 'order' => 100, + ], + (object) [ + 'name' => __( 'Enhanced Slack sharing', 'wordpress-seo' ), + 'setting' => 'enable_enhanced_slack_sharing', + 'label' => __( 'This adds an author byline and reading time estimate to the article’s snippet when shared on Slack.', 'wordpress-seo' ), + 'read_more_label' => __( 'Find out how a rich snippet can improve visibility and click-through-rate.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/help-slack-share', + 'order' => 105, + ], + (object) [ + 'name' => __( 'IndexNow', 'wordpress-seo' ), + 'premium' => true, + 'setting' => 'enable_index_now', + 'label' => __( 'Automatically ping search engines like Bing and Yandex whenever you publish, update or delete a post.', 'wordpress-seo' ), + 'read_more_label' => __( 'Find out how IndexNow can help your site.', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/index-now-read-more', + 'premium_url' => 'https://yoa.st/index-now-feature', + 'premium_upsell_url' => 'https://yoa.st/get-indexnow', + 'order' => 110, + ], + (object) [ + 'name' => __( 'AI title & description generator', 'wordpress-seo' ), + 'premium' => true, + 'setting' => 'enable_ai_generator', + 'label' => __( 'Use the power of Yoast AI to automatically generate compelling titles and descriptions for your posts and pages.', 'wordpress-seo' ), + 'read_more_label' => __( 'Learn more', 'wordpress-seo' ), + 'read_more_url' => 'https://yoa.st/ai-generator-read-more', + 'premium_url' => 'https://yoa.st/ai-generator-feature', + 'premium_upsell_url' => 'https://yoa.st/get-ai-generator', + 'order' => 115, + ], + ]; + + /** + * Filter to add feature toggles from add-ons. + * + * @param array $feature_toggles Array with feature toggle objects where each object + * should have a `name`, `setting` and `label` property. + */ + $feature_toggles = apply_filters( 'wpseo_feature_toggles', $feature_toggles ); + + $feature_toggles = array_map( [ $this, 'ensure_toggle' ], $feature_toggles ); + usort( $feature_toggles, [ $this, 'sort_toggles_callback' ] ); + + return $feature_toggles; + } + + /** + * Returns html for a warning that core sitemaps are enabled when yoast seo sitemaps are disabled. + * + * @return string HTML string for the warning. + */ + protected function sitemaps_toggle_after() { + $out = ''; + + return $out; + } + + /** + * Ensures that the passed value is a Yoast_Feature_Toggle. + * + * @param Yoast_Feature_Toggle|object|array $toggle_data Feature toggle instance, or raw object or array + * containing feature toggle data. + * + * @return Yoast_Feature_Toggle Feature toggle instance based on $toggle_data. + */ + protected function ensure_toggle( $toggle_data ) { + if ( $toggle_data instanceof Yoast_Feature_Toggle ) { + return $toggle_data; + } + + if ( is_object( $toggle_data ) ) { + $toggle_data = get_object_vars( $toggle_data ); + } + + return new Yoast_Feature_Toggle( $toggle_data ); + } + + /** + * Callback for sorting feature toggles by their order. + * + * {@internal Once the minimum PHP version goes up to PHP 7.0, the logic in the function + * can be replaced with the spaceship operator `<=>`.} + * + * @param Yoast_Feature_Toggle $feature_a Feature A. + * @param Yoast_Feature_Toggle $feature_b Feature B. + * + * @return int An integer less than, equal to, or greater than zero indicating respectively + * that feature A is considered to be less than, equal to, or greater than feature B. + */ + protected function sort_toggles_callback( Yoast_Feature_Toggle $feature_a, Yoast_Feature_Toggle $feature_b ) { + return ( $feature_a->order - $feature_b->order ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-input-select.php b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-input-select.php new file mode 100644 index 0000000..1f2a173 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-input-select.php @@ -0,0 +1,146 @@ +select_id = $select_id; + $this->select_name = $select_name; + $this->select_options = $select_options; + $this->selected_option = $selected_option; + } + + /** + * Print the rendered view. + * + * @return void + */ + public function output_html() { + // Extract it, because we want each value accessible via a variable instead of accessing it as an array. + extract( $this->get_select_values() ); + + require WPSEO_PATH . 'admin/views/form/select.php'; + } + + /** + * Return the rendered view. + * + * @return string + */ + public function get_html() { + ob_start(); + + $this->output_html(); + + $rendered_output = ob_get_contents(); + ob_end_clean(); + + return $rendered_output; + } + + /** + * Add an attribute to the attributes property. + * + * @param string $attribute The name of the attribute to add. + * @param string $value The value of the attribute. + * + * @return void + */ + public function add_attribute( $attribute, $value ) { + $this->select_attributes[ $attribute ] = $value; + } + + /** + * Return the set fields for the select. + * + * @return array + */ + private function get_select_values() { + return [ + 'id' => $this->select_id, + 'name' => $this->select_name, + 'attributes' => $this->get_attributes(), + 'options' => $this->select_options, + 'selected' => $this->selected_option, + ]; + } + + /** + * Return the attribute string, when there are attributes set. + * + * @return string + */ + private function get_attributes() { + $attributes = $this->select_attributes; + + if ( ! empty( $attributes ) ) { + array_walk( $attributes, [ $this, 'parse_attribute' ] ); + + return implode( ' ', $attributes ) . ' '; + } + + return ''; + } + + /** + * Get an attribute from the attributes. + * + * @param string $value The value of the attribute. + * @param string $attribute The attribute to look for. + * + * @return void + */ + private function parse_attribute( &$value, $attribute ) { + $value = sprintf( '%s="%s"', sanitize_key( $attribute ), esc_attr( $value ) ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-integration-toggles.php b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-integration-toggles.php new file mode 100644 index 0000000..20bdb22 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/class-yoast-integration-toggles.php @@ -0,0 +1,135 @@ +toggles ??= $this->load_toggles(); + + return $this->toggles; + } + + /** + * Loads the available integration toggles. + * + * Also ensures that the toggles are all Yoast_Feature_Toggle instances and sorted by their order value. + * + * @return array List of sorted Yoast_Feature_Toggle instances. + */ + protected function load_toggles() { + $integration_toggles = [ + (object) [ + /* translators: %s: 'Semrush' */ + 'name' => sprintf( __( '%s integration', 'wordpress-seo' ), 'Semrush' ), + 'setting' => 'semrush_integration_active', + 'label' => sprintf( + /* translators: %s: 'Semrush' */ + __( 'The %s integration offers suggestions and insights for keywords related to the entered focus keyphrase.', 'wordpress-seo' ), + 'Semrush', + ), + 'order' => 10, + ], + (object) [ + /* translators: %s: Algolia. */ + 'name' => sprintf( esc_html__( '%s integration', 'wordpress-seo' ), 'Algolia' ), + 'premium' => true, + 'setting' => 'algolia_integration_active', + 'label' => __( 'Improve the quality of your site search! Automatically helps your users find your cornerstone and most important content in your internal search results. It also removes noindexed posts & pages from your site’s search results.', 'wordpress-seo' ), + /* translators: %s: Algolia. */ + 'read_more_label' => sprintf( __( 'Find out more about our %s integration.', 'wordpress-seo' ), 'Algolia' ), + 'read_more_url' => 'https://yoa.st/4eu', + 'premium_url' => 'https://yoa.st/4ex', + 'premium_upsell_url' => 'https://yoa.st/get-algolia-integration', + 'order' => 25, + ], + ]; + + /** + * Filter to add integration toggles from add-ons. + * + * @param array $integration_toggles Array with integration toggle objects where each object + * should have a `name`, `setting` and `label` property. + */ + $integration_toggles = apply_filters( 'wpseo_integration_toggles', $integration_toggles ); + + $integration_toggles = array_map( [ $this, 'ensure_toggle' ], $integration_toggles ); + usort( $integration_toggles, [ $this, 'sort_toggles_callback' ] ); + + return $integration_toggles; + } + + /** + * Ensures that the passed value is a Yoast_Feature_Toggle. + * + * @param Yoast_Feature_Toggle|object|array $toggle_data Feature toggle instance, or raw object or array + * containing integration toggle data. + * @return Yoast_Feature_Toggle Feature toggle instance based on $toggle_data. + */ + protected function ensure_toggle( $toggle_data ) { + if ( $toggle_data instanceof Yoast_Feature_Toggle ) { + return $toggle_data; + } + + if ( is_object( $toggle_data ) ) { + $toggle_data = get_object_vars( $toggle_data ); + } + + return new Yoast_Feature_Toggle( $toggle_data ); + } + + /** + * Callback for sorting integration toggles by their order. + * + * {@internal Once the minimum PHP version goes up to PHP 7.0, the logic in the function + * can be replaced with the spaceship operator `<=>`.} + * + * @param Yoast_Feature_Toggle $feature_a Feature A. + * @param Yoast_Feature_Toggle $feature_b Feature B. + * + * @return int An integer less than, equal to, or greater than zero indicating respectively + * that feature A is considered to be less than, equal to, or greater than feature B. + */ + protected function sort_toggles_callback( Yoast_Feature_Toggle $feature_a, Yoast_Feature_Toggle $feature_b ) { + return ( $feature_a->order - $feature_b->order ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/form/select.php b/html/wp-content/plugins/wordpress-seo/admin/views/form/select.php new file mode 100644 index 0000000..8f3a846 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/form/select.php @@ -0,0 +1,26 @@ + + + diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/interface-yoast-form-element.php b/html/wp-content/plugins/wordpress-seo/admin/views/interface-yoast-form-element.php new file mode 100644 index 0000000..24a8ccb --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/interface-yoast-form-element.php @@ -0,0 +1,19 @@ + + + + + diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/paper-collapsible.php b/html/wp-content/plugins/wordpress-seo/admin/views/paper-collapsible.php new file mode 100644 index 0000000..ae2e4ec --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/paper-collapsible.php @@ -0,0 +1,79 @@ + +
            > + + %4$s%5$s ', + esc_attr( 'collapsible-header ' . $collapsible_header_class ), + // phpcs:ignore WordPress.Security.EscapeOutput -- $button_id_attr is escaped above. + $button_id_attr, + esc_attr( $collapsible_config['expanded'] ), + // phpcs:ignore WordPress.Security.EscapeOutput -- $help_text is an instance of WPSEO_Admin_Help_Panel, which escapes it's own output. + $help_text->get_button_html(), + esc_html( $title ) . wp_kses_post( $title_after ), + wp_kses_post( $collapsible_config['toggle_icon'] ), + ); + } + else { + echo '

            ', + esc_html( $title ), + wp_kses_post( $title_after ), + // phpcs:ignore WordPress.Security.EscapeOutput -- $help_text is an instance of WPSEO_Admin_Help_Panel, which escapes it's own output. + $help_text->get_button_html(), + '

            '; + } + } + ?> + get_panel_html(); + + $container_id_attr = ''; + if ( ! empty( $paper_id ) ) { + $container_id_attr = sprintf( ' id="%s"', esc_attr( $paper_id_prefix . $paper_id . '-container' ) ); + } + + printf( + '%3$s
            ', + // phpcs:ignore WordPress.Security.EscapeOutput -- $container_id_attr is escaped above. + $container_id_attr, + esc_attr( 'paper-container ' . $collapsible_config['class'] ), + $content, + ); + ?> + + diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/partial-notifications-errors.php b/html/wp-content/plugins/wordpress-seo/admin/views/partial-notifications-errors.php new file mode 100644 index 0000000..ee9c92d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/partial-notifications-errors.php @@ -0,0 +1,29 @@ +%1$s', + /* translators: Hidden accessibility text. */ + esc_html__( 'Hide this item.', 'wordpress-seo' ), + ); + break; + + case 'dismissed': + $button = sprintf( + '', + /* translators: Hidden accessibility text. */ + esc_html__( 'Show this item.', 'wordpress-seo' ), + ); + break; + } + + $notifications .= sprintf( + '
            %4$s%5$s
            ', + esc_attr( $notification->get_id() ), + esc_attr( $notification->get_nonce() ), + esc_attr( $notification->get_json() ), + // This needs to be fixed in https://github.com/Yoast/wordpress-seo-premium/issues/2548. + $notification, + // Note: $button is properly escaped above. + $button, + ); + } + + return $notifications; + } +} + +$wpseo_i18n_summary = $yoast_seo_i18n_issues; +if ( ! $yoast_seo_active ) { + $yoast_seo_dashicon = 'yes'; + $wpseo_i18n_summary = $yoast_seo_i18n_no_issues; +} + +?> +

            + + () +

            + +
            + + +

            + +
            + +
            + + esc_attr( $yoast_seo_type . '-dismissed' ), + 'paper_id_prefix' => 'yoast-', + 'class' => 'yoast-notifications-dismissed', + 'content' => _yoast_display_notifications( $yoast_seo_dismissed, 'dismissed' ), + 'collapsible' => true, + 'collapsible_header_class' => 'yoast-notification', + ], + ); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Reason: get_output() output is properly escaped. + echo $dismissed_paper->get_output(); + } + ?> + + + +

            + + +
            diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/partial-notifications-warnings.php b/html/wp-content/plugins/wordpress-seo/admin/views/partial-notifications-warnings.php new file mode 100644 index 0000000..f5dfc28 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/partial-notifications-warnings.php @@ -0,0 +1,29 @@ + +
            diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/dashboard.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/dashboard.php new file mode 100644 index 0000000..b419e78 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/dashboard.php @@ -0,0 +1,44 @@ + + +
            +
            + +
            + +
            + +
            + +
            + +
            +
            + +
            +

            +

            + +

            +
            diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/first-time-configuration.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/first-time-configuration.php new file mode 100644 index 0000000..f15c4bb --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/first-time-configuration.php @@ -0,0 +1,14 @@ +'; diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/site-analysis.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/site-analysis.php new file mode 100644 index 0000000..b45c40e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/dashboard/site-analysis.php @@ -0,0 +1,20 @@ +get_all(); + +?> +

            +
            + '; + printf( + /* translators: %1$s opens the link to the Yoast.com article about Crawl settings, %2$s closes the link, */ + esc_html__( '%1$sLearn more about crawl settings.%2$s', 'wordpress-seo' ), + '', + '', + ); + echo '

            '; + + /** + * Fires when displaying the crawl cleanup network tab. + * + * @param Yoast_Form $yform The yoast form object. + */ + do_action( 'wpseo_settings_tab_crawl_cleanup_network', $yform ); + ?> +
            +hidden( 'show_onboarding_notice', 'wpseo_show_onboarding_notice' ); diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/features.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/features.php new file mode 100644 index 0000000..5c0cec5 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/features.php @@ -0,0 +1,115 @@ +get_all(); + +?> +

            +
            + helpers->product->is_premium(); + $premium_version = YoastSEO()->helpers->product->get_premium_version(); + + if ( $feature->premium && $feature->premium_version ) { + $not_supported_in_current_premium_version = $is_premium && version_compare( $premium_version, $feature->premium_version, '<' ); + + if ( $not_supported_in_current_premium_version ) { + continue; + } + } + + $help_text = esc_html( $feature->label ); + if ( ! empty( $feature->extra ) ) { + $help_text .= ' ' . $feature->extra; + } + if ( ! empty( $feature->read_more_label ) ) { + $url = $feature->read_more_url; + if ( ! empty( $feature->premium ) && $feature->premium === true ) { + $url = $feature->premium_url; + } + $help_text .= sprintf( + '%2$s', + esc_url( WPSEO_Shortlinker::get( $url ) ), + esc_html( $feature->read_more_label ), + ); + } + + $feature_help = new WPSEO_Admin_Help_Panel( + WPSEO_Option::ALLOW_KEY_PREFIX . $feature->setting, + /* translators: Hidden accessibility text; %s expands to a feature's name. */ + sprintf( esc_html__( 'Help on: %s', 'wordpress-seo' ), esc_html( $feature->name ) ), + $help_text, + ); + + $name = $feature->name; + if ( ! empty( $feature->premium ) && $feature->premium === true ) { + $name .= ' ' . new Premium_Badge_Presenter( $feature->name ); + } + + if ( ! empty( $feature->in_beta ) && $feature->in_beta === true ) { + $name .= ' ' . new Beta_Badge_Presenter( $feature->name ); + } + + $disabled = false; + $show_premium_upsell = false; + $premium_upsell_url = ''; + $note_when_disabled = ''; + + if ( $feature->premium === true && YoastSEO()->helpers->product->is_premium() === false ) { + $disabled = true; + $show_premium_upsell = true; + $premium_upsell_url = WPSEO_Shortlinker::get( $feature->premium_upsell_url ); + } + + $preserve_disabled_value = false; + if ( $disabled ) { + $preserve_disabled_value = true; + } + + $yform->toggle_switch( + WPSEO_Option::ALLOW_KEY_PREFIX . $feature->setting, + [ + 'on' => __( 'Allow Control', 'wordpress-seo' ), + 'off' => __( 'Disable', 'wordpress-seo' ), + ], + $name, + $feature_help->get_button_html() . $feature_help->get_panel_html(), + [ + 'disabled' => $disabled, + 'preserve_disabled_value' => $preserve_disabled_value, + 'show_premium_upsell' => $show_premium_upsell, + 'premium_upsell_url' => $premium_upsell_url, + 'note_when_disabled' => $note_when_disabled, + ], + ); + } + ?> +
            +hidden( 'show_onboarding_notice', 'wpseo_show_onboarding_notice' ); diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/general.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/general.php new file mode 100644 index 0000000..f212f9a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/general.php @@ -0,0 +1,56 @@ +'; + +/* + * {@internal Important: Make sure the options added to the array here are in line with the + * options set in the WPSEO_Option_MS::$allowed_access_options property.}} + */ +$yform->select( + 'access', + /* translators: %1$s expands to Yoast SEO */ + sprintf( __( 'Who should have access to the %1$s settings', 'wordpress-seo' ), 'Yoast SEO' ), + [ + 'admin' => __( 'Site Admins (default)', 'wordpress-seo' ), + 'superadmin' => __( 'Super Admins only', 'wordpress-seo' ), + ], +); + +if ( get_blog_count() <= 100 ) { + $network_admin = new Yoast_Network_Admin(); + + $yform->select( + 'defaultblog', + __( 'New sites in the network inherit their SEO settings from this site', 'wordpress-seo' ), + $network_admin->get_site_choices( true, true ), + ); + echo '

            ' . esc_html__( 'Choose the site whose settings you want to use as default for all sites that are added to your network. If you choose \'None\', the normal plugin defaults will be used.', 'wordpress-seo' ) . '

            '; +} +else { + $yform->textinput( 'defaultblog', __( 'New sites in the network inherit their SEO settings from this site', 'wordpress-seo' ) ); + echo '

            '; + printf( + /* translators: 1: link open tag; 2: link close tag. */ + esc_html__( 'Enter the %1$sSite ID%2$s for the site whose settings you want to use as default for all sites that are added to your network. Leave empty for none (i.e. the normal plugin defaults will be used).', 'wordpress-seo' ), + '', + '', + ); + echo '

            '; +} + +echo '

            ' . esc_html__( 'Take note:', 'wordpress-seo' ) . ' ' . esc_html__( 'Privacy sensitive (FB admins and such), theme specific (title rewrite) and a few very site specific settings will not be imported to new sites.', 'wordpress-seo' ) . '

            '; + +echo ''; diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/integrations.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/integrations.php new file mode 100644 index 0000000..e100055 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/integrations.php @@ -0,0 +1,103 @@ +get_all(); + +?> +

            +
            + label ); + + if ( ! empty( $integration->extra ) ) { + $help_text .= ' ' . $integration->extra; + } + + if ( ! empty( $integration->read_more_label ) ) { + $help_text .= ' '; + $help_text .= sprintf( + '%2$s', + esc_url( WPSEO_Shortlinker::get( $integration->read_more_url ) ), + esc_html( $integration->read_more_label ), + ); + } + + $feature_help = new WPSEO_Admin_Help_Panel( + WPSEO_Option::ALLOW_KEY_PREFIX . $integration->setting, + /* translators: Hidden accessibility text; %s expands to an integration's name. */ + sprintf( esc_html__( 'Help on: %s', 'wordpress-seo' ), esc_html( $integration->name ) ), + $help_text, + ); + + $name = $integration->name; + if ( ! empty( $integration->premium ) && $integration->premium === true ) { + $name .= ' ' . new Premium_Badge_Presenter( $integration->name ); + } + + if ( ! empty( $integration->new ) && $integration->new === true ) { + $name .= ' ' . new Badge_Presenter( $integration->name ); + } + + $disabled = $integration->disabled; + $show_premium_upsell = false; + $premium_upsell_url = ''; + + if ( $integration->premium === true && YoastSEO()->helpers->product->is_premium() === false ) { + $disabled = true; + $show_premium_upsell = true; + $premium_upsell_url = WPSEO_Shortlinker::get( $integration->premium_upsell_url ); + } + + $preserve_disabled_value = false; + if ( $disabled ) { + $preserve_disabled_value = true; + } + + $yform->toggle_switch( + WPSEO_Option::ALLOW_KEY_PREFIX . $integration->setting, + [ + 'on' => __( 'Allow Control', 'wordpress-seo' ), + 'off' => __( 'Disable', 'wordpress-seo' ), + ], + $name, + $feature_help->get_button_html() . $feature_help->get_panel_html(), + [ + 'disabled' => $disabled, + 'preserve_disabled_value' => $preserve_disabled_value, + 'show_premium_upsell' => $show_premium_upsell, + 'premium_upsell_url' => $premium_upsell_url, + ], + ); + + do_action( 'Yoast\WP\SEO\admin_network_integration_after', $integration ); + } + ?> +
            +hidden( 'show_onboarding_notice', 'wpseo_show_onboarding_notice' ); diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/restore-site.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/restore-site.php new file mode 100644 index 0000000..4484f4f --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/network/restore-site.php @@ -0,0 +1,32 @@ +' . esc_html__( 'Using this form you can reset a site to the default SEO settings.', 'wordpress-seo' ) . '

            '; + +if ( get_blog_count() <= 100 ) { + $network_admin = new Yoast_Network_Admin(); + + $yform->select( + 'site_id', + __( 'Site ID', 'wordpress-seo' ), + $network_admin->get_site_choices( false, true ), + ); +} +else { + $yform->textinput( 'site_id', __( 'Site ID', 'wordpress-seo' ) ); +} + +wp_nonce_field( 'wpseo-network-restore', 'restore_site_nonce', false ); +echo ''; diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/import-seo.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/import-seo.php new file mode 100644 index 0000000..69abf0d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/import-seo.php @@ -0,0 +1,128 @@ +detect(); +if ( count( $import_check->needs_import ) === 0 ) { + echo '

            ', esc_html__( 'Import from other SEO plugins', 'wordpress-seo' ), '

            '; + echo '

            '; + printf( + /* translators: %s expands to Yoast SEO */ + esc_html__( '%s did not detect any plugin data from plugins it can import from.', 'wordpress-seo' ), + 'Yoast SEO', + ); + echo '

            '; + + return; +} + +/** + * Creates a select box given a name and plugins array. + * + * @param string $name Name field for the select field. + * @param array $plugins An array of plugins and classes. + * + * @return void + */ +function wpseo_import_external_select( $name, $plugins ) { + esc_html_e( 'Plugin: ', 'wordpress-seo' ); + echo ''; +} + +?> +

            +

            + +

            + +
            +

            +

            + +

            +
            + +
            +

            +

            + +

            +
            + needs_import ); + ?> + + +
            +
            + +
            +

            +

            + +

            +
            + +
            +

            +

            + ', + '', + ); + ?> +

            +
            + +
            +

            +

            + +

            +
            + needs_import ); + ?> + +
            +
            diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/wpseo-export.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/wpseo-export.php new file mode 100644 index 0000000..3946dda --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/wpseo-export.php @@ -0,0 +1,39 @@ +export(); + return; +} + +$wpseo_export_phrase = sprintf( + /* translators: %1$s expands to Yoast SEO */ + __( 'Export your %1$s settings here, to copy them on another site.', 'wordpress-seo' ), + 'Yoast SEO', +); +?> + +

            +
            + + + +
            diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/wpseo-import.php b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/wpseo-import.php new file mode 100644 index 0000000..35fafc8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tabs/tool/wpseo-import.php @@ -0,0 +1,46 @@ + +

            + +

            + +
            + +
            +
            + +
            diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tool-bulk-editor.php b/html/wp-content/plugins/wordpress-seo/admin/views/tool-bulk-editor.php new file mode 100644 index 0000000..dab5a83 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tool-bulk-editor.php @@ -0,0 +1,120 @@ + $yoast_free_input_fields, + 'nonce' => wp_create_nonce( 'bulk-editor-table' ), +]; + +$wpseo_bulk_titles_table = new WPSEO_Bulk_Title_Editor_List_Table( $yoast_bulk_editor_arguments ); +$wpseo_bulk_description_table = new WPSEO_Bulk_Description_List_Table( $yoast_bulk_editor_arguments ); + +$yoast_free_screen_reader_content = [ + 'heading_views' => __( 'Filter posts list', 'wordpress-seo' ), + 'heading_pagination' => __( 'Posts list navigation', 'wordpress-seo' ), + 'heading_list' => __( 'Posts list', 'wordpress-seo' ), +]; +get_current_screen()->set_screen_reader_content( $yoast_free_screen_reader_content ); + +if ( ! empty( $_REQUEST['_wp_http_referer'] ) && isset( $_SERVER['REQUEST_URI'] ) ) { + $request_uri = sanitize_file_name( wp_unslash( $_SERVER['REQUEST_URI'] ) ); + + wp_redirect( + remove_query_arg( + [ '_wp_http_referer', '_wpnonce' ], + $request_uri, + ), + ); + exit(); +} + +/** + * Renders a bulk editor tab. + * + * @param WPSEO_Bulk_List_Table $table The table to render. + * @param string $id The id for the tab. + * + * @return void + */ +function wpseo_get_rendered_tab( $table, $id ) { + ?> +
            + show_page(); + ?> +
            + + + +

            + +
            + + + +
            + + +
            +
            diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tool-file-editor.php b/html/wp-content/plugins/wordpress-seo/admin/views/tool-file-editor.php new file mode 100644 index 0000000..dcfaf9c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tool-file-editor.php @@ -0,0 +1,244 @@ +admin_header( false, 'wpseo_ms' ); +} +else { + $action_url = admin_url( 'admin.php?page=wpseo_tools&tool=file-editor' ); +} + +if ( isset( $msg ) && ! empty( $msg ) ) { + echo '

            ', esc_html( $msg ), '

            '; +} + +// N.B.: "robots.txt" is a fixed file name and should not be translatable. +echo '

            robots.txt

            '; + +if ( ! file_exists( $robots_file ) ) { + if ( is_writable( $home_path ) ) { + echo '
            '; + wp_nonce_field( 'wpseo_create_robots', '_wpnonce', true, true ); + echo '

            '; + printf( + /* translators: %s expands to robots.txt. */ + esc_html__( 'You don\'t have a %s file, create one here:', 'wordpress-seo' ), + 'robots.txt', + ); + echo '

            '; + + printf( + '', + sprintf( + /* translators: %s expands to robots.txt. */ + esc_attr__( 'Create %s file', 'wordpress-seo' ), + 'robots.txt', + ), + ); + echo '
            '; + } + else { + echo '

            '; + printf( + /* translators: %s expands to robots.txt. */ + esc_html__( 'If you had a %s file and it was editable, you could edit it from here.', 'wordpress-seo' ), + 'robots.txt', + ); + echo '

            '; + } +} +else { + $f = fopen( $robots_file, 'r' ); + + $content = ''; + if ( filesize( $robots_file ) > 0 ) { + $content = fread( $f, filesize( $robots_file ) ); + } + + if ( ! is_writable( $robots_file ) ) { + echo '

            '; + printf( + /* translators: %s expands to robots.txt. */ + esc_html__( 'If your %s were writable, you could edit it from here.', 'wordpress-seo' ), + 'robots.txt', + ); + echo '

            '; + echo '
            '; + } + else { + echo '
            '; + wp_nonce_field( 'wpseo-robotstxt', '_wpnonce', true, true ); + echo ''; + echo '
            '; + printf( + '
            ', + sprintf( + /* translators: %s expands to robots.txt. */ + esc_attr__( 'Save changes to %s', 'wordpress-seo' ), + 'robots.txt', + ), + ); + echo '
            '; + } +} +if ( ! WPSEO_Utils::is_nginx() ) { + + echo '

            '; + printf( + /* translators: %s expands to ".htaccess". */ + esc_html__( '%s file', 'wordpress-seo' ), + '.htaccess', + ); + echo '

            '; + + if ( file_exists( $ht_access_file ) ) { + $f = fopen( $ht_access_file, 'r' ); + + $contentht = ''; + if ( filesize( $ht_access_file ) > 0 ) { + $contentht = fread( $f, filesize( $ht_access_file ) ); + } + + if ( ! is_writable( $ht_access_file ) ) { + echo '

            '; + printf( + /* translators: %s expands to ".htaccess". */ + esc_html__( 'If your %s were writable, you could edit it from here.', 'wordpress-seo' ), + '.htaccess', + ); + echo '

            '; + echo '
            '; + } + else { + echo '
            '; + wp_nonce_field( 'wpseo-htaccess', '_wpnonce', true, true ); + echo ''; + echo '
            '; + printf( + '
            ', + sprintf( + /* translators: %s expands to ".htaccess". */ + esc_attr__( 'Save changes to %s', 'wordpress-seo' ), + '.htaccess', + ), + ); + echo '
            '; + } + } + else { + echo '

            '; + printf( + /* translators: %s expands to ".htaccess". */ + esc_html__( 'If you had a %s file and it was editable, you could edit it from here.', 'wordpress-seo' ), + '.htaccess', + ); + echo '

            '; + } +} + +if ( is_multisite() ) { + $yform->admin_footer( false ); +} diff --git a/html/wp-content/plugins/wordpress-seo/admin/views/tool-import-export.php b/html/wp-content/plugins/wordpress-seo/admin/views/tool-import-export.php new file mode 100644 index 0000000..4ee8a3b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/views/tool-import-export.php @@ -0,0 +1,123 @@ +import(); +} + +/** + * Allow custom import actions. + * + * @param WPSEO_Import_Status $yoast_seo_import Contains info about the handled import. + */ +$yoast_seo_import = apply_filters( 'wpseo_handle_import', $yoast_seo_import ); + +if ( $yoast_seo_import ) { + + $yoast_seo_message = ''; + if ( $yoast_seo_import->status instanceof WPSEO_Import_Status ) { + $yoast_seo_message = $yoast_seo_import->status->get_msg(); + } + + /** + * Allow customization of import/export message. + * + * @param string $yoast_seo_msg The message. + */ + $yoast_seo_msg = apply_filters( 'wpseo_import_message', $yoast_seo_message ); + + if ( ! empty( $yoast_seo_msg ) ) { + $yoast_seo_status = 'error'; + if ( $yoast_seo_import->status->status ) { + $yoast_seo_status = 'updated'; + } + + $yoast_seo_class = 'message ' . $yoast_seo_status; + + echo '

            ', esc_html( $yoast_seo_msg ), '

            '; + } +} + +$yoast_seo_tabs = [ + 'wpseo-import' => [ + 'label' => __( 'Import settings', 'wordpress-seo' ), + ], + 'wpseo-export' => [ + 'label' => __( 'Export settings', 'wordpress-seo' ), + ], + 'import-seo' => [ + 'label' => __( 'Import from other SEO plugins', 'wordpress-seo' ), + ], +]; + +?> +

            + + + + $tab ) { + printf( '
            ', esc_attr( $identifier ) ); + require_once WPSEO_PATH . 'admin/views/tabs/tool/' . $identifier . '.php'; + echo '
            '; +} + +/** + * Allow adding a custom import tab. + */ +do_action( 'wpseo_import_tab_content' ); diff --git a/html/wp-content/plugins/wordpress-seo/admin/watchers/class-slug-change-watcher.php b/html/wp-content/plugins/wordpress-seo/admin/watchers/class-slug-change-watcher.php new file mode 100644 index 0000000..1c4718e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/admin/watchers/class-slug-change-watcher.php @@ -0,0 +1,254 @@ +helpers->product->is_premium() ) { + return; + } + + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] ); + + // Detect a post trash. + add_action( 'wp_trash_post', [ $this, 'detect_post_trash' ] ); + + // Detect a post delete. + add_action( 'before_delete_post', [ $this, 'detect_post_delete' ] ); + + // Detects deletion of a term. + add_action( 'delete_term_taxonomy', [ $this, 'detect_term_delete' ] ); + } + + /** + * Enqueues the quick edit handler. + * + * @return void + */ + public function enqueue_assets() { + global $pagenow; + + if ( ! in_array( $pagenow, [ 'edit.php', 'edit-tags.php' ], true ) ) { + return; + } + + $asset_manager = new WPSEO_Admin_Asset_Manager(); + $asset_manager->enqueue_script( 'quick-edit-handler' ); + } + + /** + * Shows a message when a post is about to get trashed. + * + * @param int $post_id The current post ID. + * + * @return void + */ + public function detect_post_trash( $post_id ) { + if ( ! $this->is_post_viewable( $post_id ) ) { + return; + } + + $post_label = $this->get_post_type_label( get_post_type( $post_id ) ); + + /* translators: %1$s expands to the translated name of the post type. */ + $first_sentence = sprintf( __( 'You just trashed a %1$s.', 'wordpress-seo' ), $post_label ); + $second_sentence = __( 'Search engines and other websites can still send traffic to your trashed content.', 'wordpress-seo' ); + $message = $this->get_message( $first_sentence, $second_sentence ); + + $this->add_notification( $message ); + } + + /** + * Shows a message when a post is about to get trashed. + * + * @param int $post_id The current post ID. + * + * @return void + */ + public function detect_post_delete( $post_id ) { + if ( ! $this->is_post_viewable( $post_id ) ) { + return; + } + + $post_label = $this->get_post_type_label( get_post_type( $post_id ) ); + + /* translators: %1$s expands to the translated name of the post type. */ + $first_sentence = sprintf( __( 'You just deleted a %1$s.', 'wordpress-seo' ), $post_label ); + $second_sentence = __( 'Search engines and other websites can still send traffic to your deleted content.', 'wordpress-seo' ); + $message = $this->get_message( $first_sentence, $second_sentence ); + + $this->add_notification( $message ); + } + + /** + * Shows a message when a term is about to get deleted. + * + * @param int $term_taxonomy_id The term taxonomy ID that will be deleted. + * + * @return void + */ + public function detect_term_delete( $term_taxonomy_id ) { + if ( ! $this->is_term_viewable( $term_taxonomy_id ) ) { + return; + } + + $term = get_term_by( 'term_taxonomy_id', (int) $term_taxonomy_id ); + $term_label = $this->get_taxonomy_label_for_term( $term->term_id ); + + /* translators: %1$s expands to the translated name of the term. */ + $first_sentence = sprintf( __( 'You just deleted a %1$s.', 'wordpress-seo' ), $term_label ); + $second_sentence = __( 'Search engines and other websites can still send traffic to your deleted content.', 'wordpress-seo' ); + $message = $this->get_message( $first_sentence, $second_sentence ); + + $this->add_notification( $message ); + } + + /** + * Checks if the post is viewable. + * + * @param string $post_id The post id to check. + * + * @return bool Whether the post is viewable or not. + */ + protected function is_post_viewable( $post_id ) { + $post_type = get_post_type( $post_id ); + if ( ! WPSEO_Post_Type::is_post_type_accessible( $post_type ) ) { + return false; + } + + $post_status = get_post_status( $post_id ); + if ( ! $this->check_visible_post_status( $post_status ) ) { + return false; + } + + return true; + } + + /** + * Checks if the term is viewable. + * + * @param int $term_taxonomy_id The term taxonomy ID to check. + * + * @return bool Whether the term is viewable or not. + */ + protected function is_term_viewable( $term_taxonomy_id ) { + $term = get_term_by( 'term_taxonomy_id', (int) $term_taxonomy_id ); + + if ( ! $term || is_wp_error( $term ) ) { + return false; + } + + $taxonomy = get_taxonomy( $term->taxonomy ); + if ( ! $taxonomy ) { + return false; + } + + return $taxonomy->publicly_queryable || $taxonomy->public; + } + + /** + * Gets the taxonomy label to use for a term. + * + * @param int $term_id The term ID. + * + * @return string The taxonomy's singular label. + */ + protected function get_taxonomy_label_for_term( $term_id ) { + $term = get_term( $term_id ); + $taxonomy = get_taxonomy( $term->taxonomy ); + + return $taxonomy->labels->singular_name; + } + + /** + * Retrieves the singular post type label. + * + * @param string $post_type Post type to retrieve label from. + * + * @return string The singular post type name. + */ + protected function get_post_type_label( $post_type ) { + $post_type_object = get_post_type_object( $post_type ); + + // If the post type of this post wasn't registered default back to post. + $post_type_object ??= get_post_type_object( 'post' ); + + return $post_type_object->labels->singular_name; + } + + /** + * Checks whether the given post status is visible or not. + * + * @param string $post_status The post status to check. + * + * @return bool Whether or not the post is visible. + */ + protected function check_visible_post_status( $post_status ) { + $visible_post_statuses = [ + 'publish', + 'static', + 'private', + ]; + + return in_array( $post_status, $visible_post_statuses, true ); + } + + /** + * Returns the message around changed URLs. + * + * @param string $first_sentence The first sentence of the notification. + * @param string $second_sentence The second sentence of the notification. + * + * @return string The full notification. + */ + protected function get_message( $first_sentence, $second_sentence ) { + return '

            ' . __( 'Make sure you don\'t miss out on traffic!', 'wordpress-seo' ) . '

            ' + . '

            ' + . $first_sentence + . ' ' . $second_sentence + . ' ' . __( 'You should create a redirect to ensure your visitors do not get a 404 error when they click on the no longer working URL.', 'wordpress-seo' ) + /* translators: %s expands to Yoast SEO Premium */ + . ' ' . sprintf( __( 'With %s, you can easily create such redirects.', 'wordpress-seo' ), 'Yoast SEO Premium' ) + . '

            ' + . '

            ' + /* translators: %s expands to Yoast SEO Premium */ + . sprintf( __( 'Get %s', 'wordpress-seo' ), 'Yoast SEO Premium' ) + /* translators: Hidden accessibility text. */ + . '' . __( '(Opens in a new browser tab)', 'wordpress-seo' ) . '' + . '' + . '

            '; + } + + /** + * Adds a notification to be shown on the next page request since posts are updated in an ajax request. + * + * @param string $message The message to add to the notification. + * + * @return void + */ + protected function add_notification( $message ) { + $notification = new Yoast_Notification( + $message, + [ + 'type' => 'notice-warning is-dismissible', + 'yoast_branding' => true, + ], + ); + + $notification_center = Yoast_Notification_Center::get(); + $notification_center->add_notification( $notification ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/blocks/dynamic-blocks/breadcrumbs/block.json b/html/wp-content/plugins/wordpress-seo/blocks/dynamic-blocks/breadcrumbs/block.json new file mode 100644 index 0000000..33ecb48 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/blocks/dynamic-blocks/breadcrumbs/block.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "version": "22.8", + "name": "yoast-seo/breadcrumbs", + "title": "Yoast Breadcrumbs", + "description": "Adds the Yoast SEO breadcrumbs to your template or content.", + "category": "yoast-internal-linking-blocks", + "icon": "admin-links", + "keywords": [ + "SEO", + "breadcrumbs", + "internal linking", + "site structure" + ], + "textdomain": "wordpress-seo", + "attributes": { + "className": { + "type": "string" + } + }, + "example": { + "attributes": {} + } +} diff --git a/html/wp-content/plugins/wordpress-seo/blocks/structured-data-blocks/faq/block.json b/html/wp-content/plugins/wordpress-seo/blocks/structured-data-blocks/faq/block.json new file mode 100644 index 0000000..f4c9959 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/blocks/structured-data-blocks/faq/block.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "version": "22.7", + "name": "yoast/faq-block", + "title": "Yoast FAQ", + "description": "List your Frequently Asked Questions in an SEO-friendly way.", + "category": "yoast-structured-data-blocks", + "icon": "editor-ul", + "keywords": [ + "FAQ", + "Frequently Asked Questions", + "Schema", + "SEO", + "Structured Data" + ], + "textdomain": "wordpress-seo", + "attributes": { + "questions": { + "type": "array" + }, + "additionalListCssClasses": { + "type": "string" + } + }, + "example": { + "attributes": { + "questions": [ + { + "id": "faq-question-1", + "question": "", + "answer": "", + "images": [] + }, + { + "id": "faq-question-2", + "question": "", + "answer": "", + "images": [] + } + ] + } + }, + "editorScript": "yoast-seo-faq-block", + "editorStyle": "yoast-seo-structured-data-blocks" +} diff --git a/html/wp-content/plugins/wordpress-seo/blocks/structured-data-blocks/how-to/block.json b/html/wp-content/plugins/wordpress-seo/blocks/structured-data-blocks/how-to/block.json new file mode 100644 index 0000000..d61d412 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/blocks/structured-data-blocks/how-to/block.json @@ -0,0 +1,78 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 3, + "version": "22.7", + "name": "yoast/how-to-block", + "title": "Yoast How-to", + "description": "Create a How-to guide in an SEO-friendly way. You can only use one How-to block per post.", + "category": "yoast-structured-data-blocks", + "icon": "editor-ol", + "keywords": [ + "How-to", + "How to", + "Schema", + "SEO", + "Structured Data" + ], + "supports": { + "multiple": false + }, + "textdomain": "wordpress-seo", + "attributes": { + "hasDuration": { + "type": "boolean" + }, + "days": { + "type": "string" + }, + "hours": { + "type": "string" + }, + "minutes": { + "type": "string" + }, + "description": { + "type": "string", + "source": "html", + "selector": ".schema-how-to-description" + }, + "jsonDescription": { + "type": "string" + }, + "steps": { + "type": "array" + }, + "additionalListCssClasses": { + "type": "string" + }, + "unorderedList": { + "type": "boolean" + }, + "durationText": { + "type": "string" + }, + "defaultDurationText": { + "type": "string" + } + }, + "example": { + "attributes": { + "steps": [ + { + "id": "how-to-step-example-1", + "name": "", + "text": "", + "images": [] + }, + { + "id": "how-to-step-example-2", + "name": "", + "text": "", + "images": [] + } + ] + } + }, + "editorScript": "yoast-seo-how-to-block", + "editorStyle": "yoast-seo-structured-data-blocks" +} diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/academy-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/academy-2711-rtl.css new file mode 100644 index 0000000..adad0ba --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/academy-2711-rtl.css @@ -0,0 +1 @@ +.seo_page_wpseo_page_academy{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}.seo_page_wpseo_page_academy #wpcontent{padding-right:0!important}.seo_page_wpseo_page_academy #wpfooter{padding-left:1rem}@media (min-width:768px){.seo_page_wpseo_page_academy #wpfooter{padding-right:17rem;padding-left:2rem}}@media screen and (max-width:782px){.seo_page_wpseo_page_academy .wp-responsive-open #wpbody{left:-190px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/academy-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/academy-2711.css new file mode 100644 index 0000000..d511571 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/academy-2711.css @@ -0,0 +1 @@ +.seo_page_wpseo_page_academy{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}.seo_page_wpseo_page_academy #wpcontent{padding-left:0!important}.seo_page_wpseo_page_academy #wpfooter{padding-right:1rem}@media (min-width:768px){.seo_page_wpseo_page_academy #wpfooter{padding-left:17rem;padding-right:2rem}}@media screen and (max-width:782px){.seo_page_wpseo_page_academy .wp-responsive-open #wpbody{right:-190px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/admin-global-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/admin-global-2711-rtl.css new file mode 100644 index 0000000..52ec0d2 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/admin-global-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.yoast-tooltip{position:relative}button.yoast-tooltip{overflow:visible}.yoast-tooltip:after{background:#000c;border-radius:3px;color:#fff;display:none;font:normal normal 11px/1.45454545 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;letter-spacing:normal;opacity:0;padding:6px 8px 5px;position:absolute;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;white-space:pre;z-index:1000000;word-wrap:break-word;content:attr(aria-label);pointer-events:none;-webkit-font-smoothing:subpixel-antialiased}.yoast-tooltip-alt:after{content:attr(data-label)}.yoast-tooltip:before{border:5px solid #0000;color:#000c;content:"\00a0";display:none;height:0;opacity:0;pointer-events:none;position:absolute;width:0;z-index:1000001}@keyframes yoast-tooltip-appear{0%{opacity:0}to{opacity:1}}.yoast-tooltip:active:after,.yoast-tooltip:active:before,.yoast-tooltip:focus:after,.yoast-tooltip:focus:before,.yoast-tooltip:hover:after,.yoast-tooltip:hover:before{animation-duration:.1s;animation-fill-mode:forwards;animation-name:yoast-tooltip-appear;animation-timing-function:ease-in;display:inline-block;text-decoration:none}.yoast-tooltip-no-delay:active:after,.yoast-tooltip-no-delay:active:before,.yoast-tooltip-no-delay:focus:after,.yoast-tooltip-no-delay:focus:before,.yoast-tooltip-no-delay:hover:after,.yoast-tooltip-no-delay:hover:before{animation:none;opacity:1}.yoast-tooltip-multiline:active:after,.yoast-tooltip-multiline:focus:after,.yoast-tooltip-multiline:hover:after{display:table-cell}.yoast-tooltip-s:after,.yoast-tooltip-se:after,.yoast-tooltip-sw:after{margin-top:5px;left:50%;top:100%}.yoast-tooltip-s:before,.yoast-tooltip-se:before,.yoast-tooltip-sw:before{border-bottom-color:#000c;bottom:-5px;margin-left:-5px;left:50%;top:auto}.yoast-tooltip-se:after{right:50%;margin-right:-15px;left:auto}.yoast-tooltip-sw:after{margin-left:-15px}.yoast-tooltip-n:after,.yoast-tooltip-ne:after,.yoast-tooltip-nw:after{bottom:100%;margin-bottom:5px;left:50%}.yoast-tooltip-n:before,.yoast-tooltip-ne:before,.yoast-tooltip-nw:before{border-top-color:#000c;bottom:auto;margin-left:-5px;left:50%;top:-5px}.yoast-tooltip-ne:after{right:50%;margin-right:-15px;left:auto}.yoast-tooltip-nw:after{margin-left:-15px}.yoast-tooltip-n:after,.yoast-tooltip-s:after{transform:translateX(-50%)}.yoast-tooltip-w:after{bottom:50%;margin-left:5px;left:100%;transform:translateY(50%)}.yoast-tooltip-w:before{border-right-color:#000c;bottom:50%;right:-5px;margin-top:-5px;top:50%}.yoast-tooltip-e:after{bottom:50%;right:100%;margin-right:5px;transform:translateY(50%)}.yoast-tooltip-e:before{border-left-color:#000c;bottom:50%;margin-top:-5px;left:-5px;top:50%}.yoast-tooltip-multiline:after{width:210px}@supports (width:max-content){.yoast-tooltip-multiline:after{width:max-content}}.yoast-tooltip-multiline:after{border-collapse:initial;max-width:210px;white-space:pre-line;word-wrap:normal;word-break:break-word}.yoast-tooltip-multiline.yoast-tooltip-n:after,.yoast-tooltip-multiline.yoast-tooltip-s:after{right:50%;left:auto;transform:translateX(50%)}.yoast-tooltip-multiline.yoast-tooltip-e:after,.yoast-tooltip-multiline.yoast-tooltip-w:after{left:100%}@media screen and (min-width:0\0){.yoast-tooltip-multiline:after{width:210px}}.yoast-tooltip-sticky:after,.yoast-tooltip-sticky:before{display:inline-block}.yoast-tooltip-sticky.yoast-tooltip-multiline:after{display:table-cell}@media only screen and (min-device-pixel-ratio:2),only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.yoast-tooltip-w:after{margin-left:4.5px}}.yoast-tooltip.yoast-tooltip-hidden:after,.yoast-tooltip.yoast-tooltip-hidden:before{display:none}.rtl .yst-icon-rtl{--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.wpseo-premium-indicator{display:inline-block;height:1px;width:1px}#adminmenu .wpseo-premium-indicator{color:inherit;margin:-2px 2px -3px 0}.wpseo-premium-indicator svg{display:none;height:100%;width:auto}.yoast-measure{max-width:600px}.yoast-measure.padded{max-width:632px}#TB_window .wpseo_content_wrapper p{font-size:14px;font-style:normal}#TB_window .wpseo_content_wrapper label{font-size:14px;font-weight:600;margin:0 0 0 10px}.wpseo-premium-popup-title{font-size:1.3em!important;font-weight:600!important;margin:1em 0!important;padding:0!important}.wpseo-premium-popup-icon{margin:10px}.edit-tags-php .column-description img{height:auto;max-width:100%}.yoast-label-strong{font-weight:600}.yoast-video-container-max-width{max-width:560px}.yoast-video-container{height:0;overflow:hidden;padding-bottom:56.25%;position:relative}.yoast-video-container iframe{height:100%;right:0;position:absolute;top:0;width:100%}.yoast-settings{margin-bottom:2em;padding-right:220px}.yoast-settings h2{margin-bottom:0;margin-right:-220px}.yoast-settings label{color:#23282d;display:inline-block;font-size:14px;font-weight:600;line-height:1.3;margin-right:-220px;margin-left:6px;padding-left:10px;padding-top:4px;vertical-align:top;width:200px}.yoast .yoast-settings__checkbox,.yoast .yoast-settings__radio,.yoast-settings fieldset,.yoast-settings input[type=text],.yoast-settings label,.yoast-settings select,.yoast-settings textarea{margin-bottom:.5em;margin-top:2em}.yoast-settings__textarea--medium{max-width:600px;width:100%}.yoast .yoast-settings__checkbox,.yoast .yoast-settings__radio{position:relative;top:1px;vertical-align:top}.yoast-settings__group--checkbox,.yoast-settings__group--radio{padding-top:1em}.yoast-settings__group--checkbox .yoast-settings__checkbox,.yoast-settings__group--radio .yoast-settings__radio{margin:0 0 10px 4px}.yoast-settings__checkbox+label,.yoast-settings__radio+label{margin-right:0;margin-left:0;max-width:calc(100% - 25px);padding:0;width:auto}.yoast-settings__group--checkbox .yoast-settings__checkbox+label,.yoast-settings__group--radio .yoast-settings__radio+label{font-weight:400;margin-bottom:10px;margin-top:0}.yoast-settings legend{color:#23282d;font-size:14px;font-weight:600}.yoast-settings .description{font-size:14px;margin-top:0}td .wpseo-score-icon{background:#888;border-radius:50%;display:inline-block;height:12px;line-height:16px;margin-right:5px;margin-top:3px;width:12px}.fixed th.column-wpseo-linked,.fixed th.column-wpseo-links,.fixed th.column-wpseo-score,.fixed th.column-wpseo-score-readability{padding:0;width:3em}.fixed th.column-wpseo-score-readability.sortable,.fixed th.column-wpseo-score-readability.sorted,.fixed th.column-wpseo-score.sortable,.fixed th.column-wpseo-score.sorted{width:3.5em}th.column-wpseo-linked a,th.column-wpseo-links a,th.column-wpseo-score .yoast-tooltip,th.column-wpseo-score-readability .yoast-tooltip{display:inline-block;overflow:visible;padding:8px 0;vertical-align:middle}th.column-wpseo-score .yoast-tooltip,th.column-wpseo-score-readability .yoast-tooltip{padding:8px 11px}th.column-wpseo-score-readability.sortable .yoast-tooltip,th.column-wpseo-score-readability.sorted .yoast-tooltip,th.column-wpseo-score.sortable .yoast-tooltip,th.column-wpseo-score.sorted .yoast-tooltip{padding-left:0}.column-wpseo-links .yoast-tooltip-multiline:after{max-width:160px}.column-wpseo-linked .yoast-tooltip-multiline:after{max-width:170px}.yoast-column-header-has-tooltip{position:relative}.manage-column .yoast-column-header-has-tooltip:before{color:#444;content:"";display:inline-block;height:20px;padding:0;text-decoration:none!important;vertical-align:top;width:20px}.manage-column .yoast-linked-to:before{background:#0000 url(../../images/link-out-icon.svg) no-repeat 100% 0;background-size:20px}.manage-column .yoast-linked-from:before{background:#0000 url(../../images/link-in-icon.svg) no-repeat 100% 0;background-size:20px}.manage-column .yoast-column-seo-score:before{background:#0000 url(../../images/Yoast_SEO_negative_icon.svg) no-repeat 100% 0;background-size:20px}.manage-column .yoast-column-readability:before{background:#0000 url(../../images/readability-icon.svg) no-repeat 100% 0;background-size:20px}td.column-wpseo-linked,td.column-wpseo-links{word-wrap:normal}@media screen and (max-width:782px){.yoast-settings{padding-right:0}.yoast-settings h2{margin-right:0}.yoast-settings label{margin-right:0;margin-left:0;padding:0;width:auto}.yoast .yoast-settings__radio,.yoast-settings__radio+label{margin-bottom:1em}.yoast-settings__checkbox+label,.yoast-settings__radio+label{max-width:calc(100% - 35px);padding-top:8px}.yoast-settings__group--checkbox .yoast-settings__checkbox+label,.yoast-settings__group--radio .yoast-settings__radio+label{padding-top:4px}.yoast-settings input[type=text],.yoast-settings select,.yoast-settings textarea{box-sizing:border-box;display:block;line-height:1.5;margin-bottom:0;margin-top:0;max-width:none;padding:7px 10px;width:100%}.screen-reader-text.wpseo-score-text{clip-path:none;height:auto;margin:0;position:static!important;width:auto}}.react-tabs__tab-panel{margin:0 auto;max-width:900px}.react-tabs__tab-panel li{max-width:none!important}.contact-premium-support{text-align:center}.contact-premium-support__content{font-size:.9375rem;line-height:1.4;margin:0 auto 1.5em}.contact-premium-support__content:nth-child(2){max-width:610px}.contact-premium-support__content:nth-child(3){max-width:560px}.contact-premium-support .contact-premium-support__button{margin-bottom:48px}.wpseo-premium-description{margin-top:.5em}.wpseo-premium-advantages-list{list-style:disc;padding-right:1.5em}.yoast_help.yoast-help-button,.yoast_help.yoast-help-link{background:#0000;border:0;box-shadow:none;color:#72777c;cursor:pointer;height:20px;margin:0;outline:none;padding:0;position:relative;vertical-align:top;width:20px}.yoast-section .yoast_help.yoast-help-button{float:left}.help-button-inline .yoast_help.yoast-help-button{margin-top:-4px}.yoast-section .yoast_help.yoast-help-button{margin-top:-44px}.wpseo-admin-page .yoast_help.yoast-help-button{margin-left:6px}.yoast_help .yoast-help-icon:before{content:"\f223";right:0;padding:4px;position:absolute;top:0}.yoast_help.yoast-help-button:focus,.yoast_help.yoast-help-button:hover,.yoast_help.yoast-help-link:hover{color:#0073aa}.assessment-results__mark:focus,.yoast_help.yoast-help-button:focus .yoast-help-icon:before,.yoast_help.yoast-help-link:focus .yoast-help-icon:before{border-radius:100%;box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc}.yoast-help-panel{clear:both;display:none;font-weight:400;max-width:30em!important;padding:0 0 1em;white-space:normal}.wpseo-admin-page .yoast-help-panel{max-width:600px!important}.copy-home-meta-description{margin-top:1em}.copy-home-meta-description .yoast-help-panel{max-width:400px!important}.yoast-modal_is-open{overflow:hidden}.yoast-notification .yoast-seo-icon{float:right;margin:20px 10px}.yoast-notification .yoast-seo-icon-wrap{margin:0 85px 0 0}.yoast-button-upsell{align-items:center;background-color:#fec228;border-radius:4px;box-shadow:inset 0 -4px 0 #0003;box-sizing:border-box;color:#000;display:inline-flex;filter:drop-shadow(0 2px 4px rgba(0,0,0,.2));font-family:Arial,sans-serif;font-size:16px;justify-content:center;line-height:1.5;min-height:48px;padding:8px 1em;text-decoration:none}.yoast-button-upsell:active,.yoast-button-upsell:focus,.yoast-button-upsell:hover{background-color:#f2ae01;color:#000}.yoast-button-upsell:focus{box-shadow:inset 0 -4px 0 #0003,0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc}.yoast-button-upsell:active{box-shadow:none;filter:none;transform:translateY(1px)}.yoast-button-upsell#wpseo-premium-button{color:#000}.yoast-button-upsell__caret{background:#0000 var(--yoast-svg-icon-caret-right) center no-repeat;flex-shrink:0;height:16px;margin:0 6px 0 -2px;width:8px}.rtl .yoast-button-upsell__caret{background-image:var(--yoast-svg-icon-caret-left)}body.folded .wpseo-admin-submit-fixed{right:36px}@media screen and (max-width:782px){body.folded .wpseo-admin-submit-fixed{right:0}}.wpseo-admin-submit{align-items:baseline;display:flex;justify-content:flex-start;margin:0;padding:16px 0;z-index:5}.wpseo-admin-submit.wpseo-admin-submit-fixed{background-color:#fff;bottom:0;box-shadow:0 1px 8px 1px #00000080;padding:16px;position:fixed;width:600px}@media screen and (max-width:782px){.wpseo-admin-submit.wpseo-admin-submit-fixed{right:0;width:782px}}.wpseo-admin-submit p.submit{margin:0;padding:0}.wpseo-admin-submit p.wpseo-message{color:#008a00;margin:0 0 0 16px;padding:0}.yoast-site-health__signature{color:#707070;display:flex;font-size:12px;line-height:20px;margin-top:2em}.yoast-site-health__inline-button.fetch-status,.yoast-site-health__signature-icon{margin-left:8px}#wpadminbar .yoast-badge,.yoast-badge{border-radius:8px;display:inline-block;font-weight:600;line-height:1.6;padding:0 8px}.yoast-badge{font-size:10px;min-height:16px}.yoast-badge--sale{background-color:#a4286a;border-radius:999px!important;color:#fff;font-size:12px!important;margin-top:-24px;position:absolute;left:30px;transform:rotate(-14deg)}@media (max-width:1024px){.yoast-badge--sale{display:inline-block;position:unset;vertical-align:top}}.yoast-badge__is-link:focus,.yoast-badge__is-link:hover{background-color:#004973;box-shadow:none;color:#fff;outline:none}#wpadminbar .yoast-badge,.wp-submenu .yoast-badge{font-size:9px;min-height:14px}.yoast-new-badge{background-color:#cce5ff;color:#004973}.yoast-premium-badge{background-color:#fff3cd;color:#674e00}.yoast-beta-badge{background-color:#cce5ff;color:#004973}.yoast-badge__is-link{text-decoration:none}.switch-container .yoast-badge{vertical-align:-1em}.switch-container legend .yoast-badge{vertical-align:0}.yoast_help+.yoast-badge{vertical-align:bottom}.wp-submenu .yoast-brand-insights-gradient-border{background:linear-gradient(-97.38deg,#cd82ab,#a5b4fc);padding:1px}.wp-submenu .yoast-brand-insights-content,.wp-submenu .yoast-brand-insights-gradient-border{border-radius:.375rem;display:inline-flex;position:relative;width:100%}.wp-submenu .yoast-brand-insights-content{align-items:center;background:var(--yoast-adminbar-submenu-bg,#2c3338);font-size:.75rem;font-weight:500;gap:.25rem;justify-content:center;padding:.375rem .625rem .375rem .5rem;white-space:nowrap}.yst-external-link-icon{background-color:currentColor;display:inline-block;height:.875rem;margin-bottom:.125rem;mask-image:var(--yoast-svg-icon-external-link);-webkit-mask-image:var(--yoast-svg-icon-external-link);mask-size:100% 100%;-webkit-mask-size:100% 100%;vertical-align:middle;width:.875rem}.yoast #crawl-settings fieldset[id$=_disabled],.yoast #crawl-settings p.disabled,.yoast label[for=clean_permalinks_extra_variables_free],.yoast label[for=search_character_limit_free],.yoast p.yoast-extra-variables-label-free{opacity:.5}.yoast #crawl-settings fieldset[id$=_disabled] .switch-toggle.switch-yoast-seo input:disabled~a{background:#a4286a;border:1px solid #b5b5b5}.yoast label[for^=search_character_limit]{font-weight:600;margin-bottom:10px!important;padding-right:2px;width:320px!important}.yoast input[id^=search_character_limit]{width:70px!important}.yoast label[for^=clean_permalinks_extra_variables]{font-weight:600;padding-right:2px;width:240px!important}.yoast input[id^=clean_permalinks_extra_variables]{width:358px!important}.yoast .yoast-crawl-single-setting{margin-top:18px}.yoast p[class*=yoast-extra-variables-label]{padding-right:243px!important}@media screen and (max-width:782px){.yoast p[class*=yoast-extra-variables-label]{margin-top:-20px!important;padding-right:0!important}}.yoast .yoast-crawl-settings-help{font-style:italic}.notice-yoast{background:#fff;border:1px solid #c3c4c7;border-right:4px solid var(--yoast-color-primary);box-shadow:0 1px 1px #0000000a;margin:20px 0 15px;padding:1px 12px}#black-friday-2023-product-editor-checklist .notice-yoast__container{padding:0 5px}.notice-yoast.is-dismissible{padding-left:38px;position:relative}.notice-yoast__container{padding:10px 0 5px}.notice-yoast__container,.notice-yoast__header{align-items:center;display:flex;flex-direction:row}.notice-yoast__header{box-sizing:border-box;justify-content:flex-start;margin-bottom:8px;padding:0;width:100%}.notice-yoast__header .notice-yoast__header-heading{line-height:1.2;margin:0;padding:0}.notice-yoast__header h2.notice-yoast__header-heading{color:var(--yoast-color-primary);font-size:14px;font-weight:600;line-height:1;margin:0}.notice-yoast__header .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:14px;margin-left:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:14px}.notice-yoast__content{display:flex;padding:0}.notice-yoast .notice-yoast__container>svg{height:60px;line-height:1;margin-right:10px;width:auto}.notice-yoast img{height:60px;line-height:1;margin-bottom:5px;margin-right:16px;width:auto}.notice-yoast p{font-size:13px;font-weight:400;line-height:19px;max-width:600px}.notice-yoast .yoast-button--small{min-height:unset}.notice-yoast .notice-dismiss{background:none;border:none;color:#787c82;cursor:pointer;margin:0;padding:9px;position:absolute;left:1px;top:0}.notice-yoast .notice-dismiss:before{background:none;color:#787c82;content:"\f153";display:block;font:normal 16px/20px dashicons;speak:never;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.notice-yoast .notice-dismiss:hover:before{color:#d63638}.yoast-notice-migrated-header{margin-top:10px}.privacy-settings .notice-yoast{margin:0 20px}.yoast .yoast-crawl-settings-explanation-free,.yoast .yoast-crawl-settings-help-free{opacity:.5}.yoast h3.yoast-crawl-settings,.yoast h3.yoast-crawl-settings-free{margin:2em 0 .5em}.yoast .yoast-crawl-settings-disabled,.yoast h3.yoast-crawl-settings-free{opacity:.5}.yoast .indexables-indexing-error p{margin-bottom:13px}.yoast .indexables-indexing-error strong{font-weight:500}.yoast .indexables-indexing-error summary{font-weight:700}.yoast-dashicons-notice{color:#dba617}#black-friday-promotion-sidebar.notice-yoast{background:#fff;border-color:#fcd34d;border-radius:8px;border-width:2px;margin:20px 0 15px;padding:1px 12px}#black-friday-promotion-sidebar .notice-yoast__header{margin-bottom:2px;padding-left:20px}#black-friday-promotion-metabox.notice-yoast{background:#fff;border-color:#fcd34d;border-radius:8px;border-width:2px;margin:20px}#black-friday-promotion-metabox h2.notice-yoast__header-heading{padding:0}#black-friday-promotion-metabox .notice-yoast__container{padding-bottom:0}#black-friday-promotion-metabox .notice-yoast__container p{display:inline}#black-friday-promotion-metabox .notice-yoast__header{margin-bottom:8px}#black-friday-promotion-metabox .notice-yoast__header a{font-weight:400;margin-right:13px}.yoast-bf-sale-badge{display:block;right:12px;position:absolute;top:-10px}.yoast-bf-sale-badge,.yoast-menu-bf-sale-badge{background-color:#1f2937;border-radius:8px;color:#fcd34d;font-size:10px;font-weight:600;line-height:normal;padding:2px 8px}.yoast-menu-bf-sale-badge{border:1px solid #fcd34d;margin-right:5px;text-wrap:nowrap}.yoast-update-plugin-bf-sale-badge{background-color:#000;border-radius:16px;color:#fcd34d;display:inline-block;font-size:10px;font-weight:600;height:13px;line-height:normal;margin:auto 8px;padding:2px 8px}#wpseo-new-badge-upgrade{align-items:center;border-radius:18px;display:inline-flex;height:1rem;justify-content:center;margin:.125rem .5rem;white-space:nowrap;width:2.375rem;--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:600;--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity,1))}@media (min-width:768px){.wpseo_table_page .tablenav.bottom{margin-bottom:40px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/admin-global-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/admin-global-2711.css new file mode 100644 index 0000000..74f25c6 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/admin-global-2711.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.yoast-tooltip{position:relative}button.yoast-tooltip{overflow:visible}.yoast-tooltip:after{background:#000c;border-radius:3px;color:#fff;display:none;font:normal normal 11px/1.45454545 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;letter-spacing:normal;opacity:0;padding:6px 8px 5px;position:absolute;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;white-space:pre;z-index:1000000;word-wrap:break-word;content:attr(aria-label);pointer-events:none;-webkit-font-smoothing:subpixel-antialiased}.yoast-tooltip-alt:after{content:attr(data-label)}.yoast-tooltip:before{border:5px solid #0000;color:#000c;content:"\00a0";display:none;height:0;opacity:0;pointer-events:none;position:absolute;width:0;z-index:1000001}@keyframes yoast-tooltip-appear{0%{opacity:0}to{opacity:1}}.yoast-tooltip:active:after,.yoast-tooltip:active:before,.yoast-tooltip:focus:after,.yoast-tooltip:focus:before,.yoast-tooltip:hover:after,.yoast-tooltip:hover:before{animation-duration:.1s;animation-fill-mode:forwards;animation-name:yoast-tooltip-appear;animation-timing-function:ease-in;display:inline-block;text-decoration:none}.yoast-tooltip-no-delay:active:after,.yoast-tooltip-no-delay:active:before,.yoast-tooltip-no-delay:focus:after,.yoast-tooltip-no-delay:focus:before,.yoast-tooltip-no-delay:hover:after,.yoast-tooltip-no-delay:hover:before{animation:none;opacity:1}.yoast-tooltip-multiline:active:after,.yoast-tooltip-multiline:focus:after,.yoast-tooltip-multiline:hover:after{display:table-cell}.yoast-tooltip-s:after,.yoast-tooltip-se:after,.yoast-tooltip-sw:after{margin-top:5px;right:50%;top:100%}.yoast-tooltip-s:before,.yoast-tooltip-se:before,.yoast-tooltip-sw:before{border-bottom-color:#000c;bottom:-5px;margin-right:-5px;right:50%;top:auto}.yoast-tooltip-se:after{left:50%;margin-left:-15px;right:auto}.yoast-tooltip-sw:after{margin-right:-15px}.yoast-tooltip-n:after,.yoast-tooltip-ne:after,.yoast-tooltip-nw:after{bottom:100%;margin-bottom:5px;right:50%}.yoast-tooltip-n:before,.yoast-tooltip-ne:before,.yoast-tooltip-nw:before{border-top-color:#000c;bottom:auto;margin-right:-5px;right:50%;top:-5px}.yoast-tooltip-ne:after{left:50%;margin-left:-15px;right:auto}.yoast-tooltip-nw:after{margin-right:-15px}.yoast-tooltip-n:after,.yoast-tooltip-s:after{transform:translateX(50%)}.yoast-tooltip-w:after{bottom:50%;margin-right:5px;right:100%;transform:translateY(50%)}.yoast-tooltip-w:before{border-left-color:#000c;bottom:50%;left:-5px;margin-top:-5px;top:50%}.yoast-tooltip-e:after{bottom:50%;left:100%;margin-left:5px;transform:translateY(50%)}.yoast-tooltip-e:before{border-right-color:#000c;bottom:50%;margin-top:-5px;right:-5px;top:50%}.yoast-tooltip-multiline:after{width:210px}@supports (width:max-content){.yoast-tooltip-multiline:after{width:max-content}}.yoast-tooltip-multiline:after{border-collapse:initial;max-width:210px;white-space:pre-line;word-wrap:normal;word-break:break-word}.yoast-tooltip-multiline.yoast-tooltip-n:after,.yoast-tooltip-multiline.yoast-tooltip-s:after{left:50%;right:auto;transform:translateX(-50%)}.yoast-tooltip-multiline.yoast-tooltip-e:after,.yoast-tooltip-multiline.yoast-tooltip-w:after{right:100%}@media screen and (min-width:0\0){.yoast-tooltip-multiline:after{width:210px}}.yoast-tooltip-sticky:after,.yoast-tooltip-sticky:before{display:inline-block}.yoast-tooltip-sticky.yoast-tooltip-multiline:after{display:table-cell}@media only screen and (min-device-pixel-ratio:2),only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.yoast-tooltip-w:after{margin-right:4.5px}}.yoast-tooltip.yoast-tooltip-hidden:after,.yoast-tooltip.yoast-tooltip-hidden:before{display:none}.rtl .yst-icon-rtl{--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.wpseo-premium-indicator{display:inline-block;height:1px;width:1px}#adminmenu .wpseo-premium-indicator{color:inherit;margin:-2px 0 -3px 2px}.wpseo-premium-indicator svg{display:none;height:100%;width:auto}.yoast-measure{max-width:600px}.yoast-measure.padded{max-width:632px}#TB_window .wpseo_content_wrapper p{font-size:14px;font-style:normal}#TB_window .wpseo_content_wrapper label{font-size:14px;font-weight:600;margin:0 10px 0 0}.wpseo-premium-popup-title{font-size:1.3em!important;font-weight:600!important;margin:1em 0!important;padding:0!important}.wpseo-premium-popup-icon{margin:10px}.edit-tags-php .column-description img{height:auto;max-width:100%}.yoast-label-strong{font-weight:600}.yoast-video-container-max-width{max-width:560px}.yoast-video-container{height:0;overflow:hidden;padding-bottom:56.25%;position:relative}.yoast-video-container iframe{height:100%;left:0;position:absolute;top:0;width:100%}.yoast-settings{margin-bottom:2em;padding-left:220px}.yoast-settings h2{margin-bottom:0;margin-left:-220px}.yoast-settings label{color:#23282d;display:inline-block;font-size:14px;font-weight:600;line-height:1.3;margin-left:-220px;margin-right:6px;padding-right:10px;padding-top:4px;vertical-align:top;width:200px}.yoast .yoast-settings__checkbox,.yoast .yoast-settings__radio,.yoast-settings fieldset,.yoast-settings input[type=text],.yoast-settings label,.yoast-settings select,.yoast-settings textarea{margin-bottom:.5em;margin-top:2em}.yoast-settings__textarea--medium{max-width:600px;width:100%}.yoast .yoast-settings__checkbox,.yoast .yoast-settings__radio{position:relative;top:1px;vertical-align:top}.yoast-settings__group--checkbox,.yoast-settings__group--radio{padding-top:1em}.yoast-settings__group--checkbox .yoast-settings__checkbox,.yoast-settings__group--radio .yoast-settings__radio{margin:0 4px 10px 0}.yoast-settings__checkbox+label,.yoast-settings__radio+label{margin-left:0;margin-right:0;max-width:calc(100% - 25px);padding:0;width:auto}.yoast-settings__group--checkbox .yoast-settings__checkbox+label,.yoast-settings__group--radio .yoast-settings__radio+label{font-weight:400;margin-bottom:10px;margin-top:0}.yoast-settings legend{color:#23282d;font-size:14px;font-weight:600}.yoast-settings .description{font-size:14px;margin-top:0}td .wpseo-score-icon{background:#888;border-radius:50%;display:inline-block;height:12px;line-height:16px;margin-left:5px;margin-top:3px;width:12px}.fixed th.column-wpseo-linked,.fixed th.column-wpseo-links,.fixed th.column-wpseo-score,.fixed th.column-wpseo-score-readability{padding:0;width:3em}.fixed th.column-wpseo-score-readability.sortable,.fixed th.column-wpseo-score-readability.sorted,.fixed th.column-wpseo-score.sortable,.fixed th.column-wpseo-score.sorted{width:3.5em}th.column-wpseo-linked a,th.column-wpseo-links a,th.column-wpseo-score .yoast-tooltip,th.column-wpseo-score-readability .yoast-tooltip{display:inline-block;overflow:visible;padding:8px 0;vertical-align:middle}th.column-wpseo-score .yoast-tooltip,th.column-wpseo-score-readability .yoast-tooltip{padding:8px 11px}th.column-wpseo-score-readability.sortable .yoast-tooltip,th.column-wpseo-score-readability.sorted .yoast-tooltip,th.column-wpseo-score.sortable .yoast-tooltip,th.column-wpseo-score.sorted .yoast-tooltip{padding-right:0}.column-wpseo-links .yoast-tooltip-multiline:after{max-width:160px}.column-wpseo-linked .yoast-tooltip-multiline:after{max-width:170px}.yoast-column-header-has-tooltip{position:relative}.manage-column .yoast-column-header-has-tooltip:before{color:#444;content:"";display:inline-block;height:20px;padding:0;text-decoration:none!important;vertical-align:top;width:20px}.manage-column .yoast-linked-to:before{background:#0000 url(../../images/link-out-icon.svg) no-repeat 0 0;background-size:20px}.manage-column .yoast-linked-from:before{background:#0000 url(../../images/link-in-icon.svg) no-repeat 0 0;background-size:20px}.manage-column .yoast-column-seo-score:before{background:#0000 url(../../images/Yoast_SEO_negative_icon.svg) no-repeat 0 0;background-size:20px}.manage-column .yoast-column-readability:before{background:#0000 url(../../images/readability-icon.svg) no-repeat 0 0;background-size:20px}td.column-wpseo-linked,td.column-wpseo-links{word-wrap:normal}@media screen and (max-width:782px){.yoast-settings{padding-left:0}.yoast-settings h2{margin-left:0}.yoast-settings label{margin-left:0;margin-right:0;padding:0;width:auto}.yoast .yoast-settings__radio,.yoast-settings__radio+label{margin-bottom:1em}.yoast-settings__checkbox+label,.yoast-settings__radio+label{max-width:calc(100% - 35px);padding-top:8px}.yoast-settings__group--checkbox .yoast-settings__checkbox+label,.yoast-settings__group--radio .yoast-settings__radio+label{padding-top:4px}.yoast-settings input[type=text],.yoast-settings select,.yoast-settings textarea{box-sizing:border-box;display:block;line-height:1.5;margin-bottom:0;margin-top:0;max-width:none;padding:7px 10px;width:100%}.screen-reader-text.wpseo-score-text{clip-path:none;height:auto;margin:0;position:static!important;width:auto}}.react-tabs__tab-panel{margin:0 auto;max-width:900px}.react-tabs__tab-panel li{max-width:none!important}.contact-premium-support{text-align:center}.contact-premium-support__content{font-size:.9375rem;line-height:1.4;margin:0 auto 1.5em}.contact-premium-support__content:nth-child(2){max-width:610px}.contact-premium-support__content:nth-child(3){max-width:560px}.contact-premium-support .contact-premium-support__button{margin-bottom:48px}.wpseo-premium-description{margin-top:.5em}.wpseo-premium-advantages-list{list-style:disc;padding-left:1.5em}.yoast_help.yoast-help-button,.yoast_help.yoast-help-link{background:#0000;border:0;box-shadow:none;color:#72777c;cursor:pointer;height:20px;margin:0;outline:none;padding:0;position:relative;vertical-align:top;width:20px}.yoast-section .yoast_help.yoast-help-button{float:right}.help-button-inline .yoast_help.yoast-help-button{margin-top:-4px}.yoast-section .yoast_help.yoast-help-button{margin-top:-44px}.wpseo-admin-page .yoast_help.yoast-help-button{margin-right:6px}.yoast_help .yoast-help-icon:before{content:"\f223";left:0;padding:4px;position:absolute;top:0}.yoast_help.yoast-help-button:focus,.yoast_help.yoast-help-button:hover,.yoast_help.yoast-help-link:hover{color:#0073aa}.assessment-results__mark:focus,.yoast_help.yoast-help-button:focus .yoast-help-icon:before,.yoast_help.yoast-help-link:focus .yoast-help-icon:before{border-radius:100%;box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc}.yoast-help-panel{clear:both;display:none;font-weight:400;max-width:30em!important;padding:0 0 1em;white-space:normal}.wpseo-admin-page .yoast-help-panel{max-width:600px!important}.copy-home-meta-description{margin-top:1em}.copy-home-meta-description .yoast-help-panel{max-width:400px!important}.yoast-modal_is-open{overflow:hidden}.yoast-notification .yoast-seo-icon{float:left;margin:20px 10px}.yoast-notification .yoast-seo-icon-wrap{margin:0 0 0 85px}.yoast-button-upsell{align-items:center;background-color:#fec228;border-radius:4px;box-shadow:inset 0 -4px 0 #0003;box-sizing:border-box;color:#000;display:inline-flex;filter:drop-shadow(0 2px 4px rgba(0,0,0,.2));font-family:Arial,sans-serif;font-size:16px;justify-content:center;line-height:1.5;min-height:48px;padding:8px 1em;text-decoration:none}.yoast-button-upsell:active,.yoast-button-upsell:focus,.yoast-button-upsell:hover{background-color:#f2ae01;color:#000}.yoast-button-upsell:focus{box-shadow:inset 0 -4px 0 #0003,0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc}.yoast-button-upsell:active{box-shadow:none;filter:none;transform:translateY(1px)}.yoast-button-upsell#wpseo-premium-button{color:#000}.yoast-button-upsell__caret{background:#0000 var(--yoast-svg-icon-caret-right) center no-repeat;flex-shrink:0;height:16px;margin:0 -2px 0 6px;width:8px}.rtl .yoast-button-upsell__caret{background-image:var(--yoast-svg-icon-caret-left)}body.folded .wpseo-admin-submit-fixed{left:36px}@media screen and (max-width:782px){body.folded .wpseo-admin-submit-fixed{left:0}}.wpseo-admin-submit{align-items:baseline;display:flex;justify-content:flex-start;margin:0;padding:16px 0;z-index:5}.wpseo-admin-submit.wpseo-admin-submit-fixed{background-color:#fff;bottom:0;box-shadow:0 1px 8px 1px #00000080;padding:16px;position:fixed;width:600px}@media screen and (max-width:782px){.wpseo-admin-submit.wpseo-admin-submit-fixed{left:0;width:782px}}.wpseo-admin-submit p.submit{margin:0;padding:0}.wpseo-admin-submit p.wpseo-message{color:#008a00;margin:0 16px 0 0;padding:0}.yoast-site-health__signature{color:#707070;display:flex;font-size:12px;line-height:20px;margin-top:2em}.yoast-site-health__inline-button.fetch-status,.yoast-site-health__signature-icon{margin-right:8px}#wpadminbar .yoast-badge,.yoast-badge{border-radius:8px;display:inline-block;font-weight:600;line-height:1.6;padding:0 8px}.yoast-badge{font-size:10px;min-height:16px}.yoast-badge--sale{background-color:#a4286a;border-radius:999px!important;color:#fff;font-size:12px!important;margin-top:-24px;position:absolute;right:30px;transform:rotate(14deg)}@media (max-width:1024px){.yoast-badge--sale{display:inline-block;position:unset;vertical-align:top}}.yoast-badge__is-link:focus,.yoast-badge__is-link:hover{background-color:#004973;box-shadow:none;color:#fff;outline:none}#wpadminbar .yoast-badge,.wp-submenu .yoast-badge{font-size:9px;min-height:14px}.yoast-new-badge{background-color:#cce5ff;color:#004973}.yoast-premium-badge{background-color:#fff3cd;color:#674e00}.yoast-beta-badge{background-color:#cce5ff;color:#004973}.yoast-badge__is-link{text-decoration:none}.switch-container .yoast-badge{vertical-align:-1em}.switch-container legend .yoast-badge{vertical-align:0}.yoast_help+.yoast-badge{vertical-align:bottom}.wp-submenu .yoast-brand-insights-gradient-border{background:linear-gradient(97.38deg,#cd82ab,#a5b4fc);padding:1px}.wp-submenu .yoast-brand-insights-content,.wp-submenu .yoast-brand-insights-gradient-border{border-radius:.375rem;display:inline-flex;position:relative;width:100%}.wp-submenu .yoast-brand-insights-content{align-items:center;background:var(--yoast-adminbar-submenu-bg,#2c3338);font-size:.75rem;font-weight:500;gap:.25rem;justify-content:center;padding:.375rem .5rem .375rem .625rem;white-space:nowrap}.yst-external-link-icon{background-color:currentColor;display:inline-block;height:.875rem;margin-bottom:.125rem;mask-image:var(--yoast-svg-icon-external-link);-webkit-mask-image:var(--yoast-svg-icon-external-link);mask-size:100% 100%;-webkit-mask-size:100% 100%;vertical-align:middle;width:.875rem}.yoast #crawl-settings fieldset[id$=_disabled],.yoast #crawl-settings p.disabled,.yoast label[for=clean_permalinks_extra_variables_free],.yoast label[for=search_character_limit_free],.yoast p.yoast-extra-variables-label-free{opacity:.5}.yoast #crawl-settings fieldset[id$=_disabled] .switch-toggle.switch-yoast-seo input:disabled~a{background:#a4286a;border:1px solid #b5b5b5}.yoast label[for^=search_character_limit]{font-weight:600;margin-bottom:10px!important;padding-left:2px;width:320px!important}.yoast input[id^=search_character_limit]{width:70px!important}.yoast label[for^=clean_permalinks_extra_variables]{font-weight:600;padding-left:2px;width:240px!important}.yoast input[id^=clean_permalinks_extra_variables]{width:358px!important}.yoast .yoast-crawl-single-setting{margin-top:18px}.yoast p[class*=yoast-extra-variables-label]{padding-left:243px!important}@media screen and (max-width:782px){.yoast p[class*=yoast-extra-variables-label]{margin-top:-20px!important;padding-left:0!important}}.yoast .yoast-crawl-settings-help{font-style:italic}.notice-yoast{background:#fff;border:1px solid #c3c4c7;border-left:4px solid var(--yoast-color-primary);box-shadow:0 1px 1px #0000000a;margin:20px 0 15px;padding:1px 12px}#black-friday-2023-product-editor-checklist .notice-yoast__container{padding:0 5px}.notice-yoast.is-dismissible{padding-right:38px;position:relative}.notice-yoast__container{padding:10px 0 5px}.notice-yoast__container,.notice-yoast__header{align-items:center;display:flex;flex-direction:row}.notice-yoast__header{box-sizing:border-box;justify-content:flex-start;margin-bottom:8px;padding:0;width:100%}.notice-yoast__header .notice-yoast__header-heading{line-height:1.2;margin:0;padding:0}.notice-yoast__header h2.notice-yoast__header-heading{color:var(--yoast-color-primary);font-size:14px;font-weight:600;line-height:1;margin:0}.notice-yoast__header .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:14px;margin-right:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:14px}.notice-yoast__content{display:flex;padding:0}.notice-yoast .notice-yoast__container>svg{height:60px;line-height:1;margin-left:10px;width:auto}.notice-yoast img{height:60px;line-height:1;margin-bottom:5px;margin-left:16px;width:auto}.notice-yoast p{font-size:13px;font-weight:400;line-height:19px;max-width:600px}.notice-yoast .yoast-button--small{min-height:unset}.notice-yoast .notice-dismiss{background:none;border:none;color:#787c82;cursor:pointer;margin:0;padding:9px;position:absolute;right:1px;top:0}.notice-yoast .notice-dismiss:before{background:none;color:#787c82;content:"\f153";display:block;font:normal 16px/20px dashicons;speak:never;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.notice-yoast .notice-dismiss:hover:before{color:#d63638}.yoast-notice-migrated-header{margin-top:10px}.privacy-settings .notice-yoast{margin:0 20px}.yoast .yoast-crawl-settings-explanation-free,.yoast .yoast-crawl-settings-help-free{opacity:.5}.yoast h3.yoast-crawl-settings,.yoast h3.yoast-crawl-settings-free{margin:2em 0 .5em}.yoast .yoast-crawl-settings-disabled,.yoast h3.yoast-crawl-settings-free{opacity:.5}.yoast .indexables-indexing-error p{margin-bottom:13px}.yoast .indexables-indexing-error strong{font-weight:500}.yoast .indexables-indexing-error summary{font-weight:700}.yoast-dashicons-notice{color:#dba617}#black-friday-promotion-sidebar.notice-yoast{background:#fff;border-color:#fcd34d;border-radius:8px;border-width:2px;margin:20px 0 15px;padding:1px 12px}#black-friday-promotion-sidebar .notice-yoast__header{margin-bottom:2px;padding-right:20px}#black-friday-promotion-metabox.notice-yoast{background:#fff;border-color:#fcd34d;border-radius:8px;border-width:2px;margin:20px}#black-friday-promotion-metabox h2.notice-yoast__header-heading{padding:0}#black-friday-promotion-metabox .notice-yoast__container{padding-bottom:0}#black-friday-promotion-metabox .notice-yoast__container p{display:inline}#black-friday-promotion-metabox .notice-yoast__header{margin-bottom:8px}#black-friday-promotion-metabox .notice-yoast__header a{font-weight:400;margin-left:13px}.yoast-bf-sale-badge{display:block;left:12px;position:absolute;top:-10px}.yoast-bf-sale-badge,.yoast-menu-bf-sale-badge{background-color:#1f2937;border-radius:8px;color:#fcd34d;font-size:10px;font-weight:600;line-height:normal;padding:2px 8px}.yoast-menu-bf-sale-badge{border:1px solid #fcd34d;margin-left:5px;text-wrap:nowrap}.yoast-update-plugin-bf-sale-badge{background-color:#000;border-radius:16px;color:#fcd34d;display:inline-block;font-size:10px;font-weight:600;height:13px;line-height:normal;margin:auto 8px;padding:2px 8px}#wpseo-new-badge-upgrade{align-items:center;border-radius:18px;display:inline-flex;height:1rem;justify-content:center;margin:.125rem .5rem;white-space:nowrap;width:2.375rem;--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:600;--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity,1))}@media (min-width:768px){.wpseo_table_page .tablenav.bottom{margin-bottom:40px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/adminbar-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/adminbar-2711-rtl.css new file mode 100644 index 0000000..a1c7053 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/adminbar-2711-rtl.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 3px 0 10px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe}:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}#wp-admin-bar-wpseo-menu .wpseo-score-icon{margin:10px 4px 0 0!important}#wp-admin-bar-wpseo-menu .wpseo-score-icon.adminbar-sub-menu-score{margin:11px 4px 0 0!important}#wp-admin-bar-wpseo-menu-default .ab-item{line-height:2.46153846!important}#wp-admin-bar-wpseo-menu .ab-submenu{margin-bottom:5px}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium span{background:#1f2937;border:1px solid #fcd34d;border-radius:14px;color:#fcd34d;font-size:12px;font-weight:600;padding:1px 4px}#wpadminbar .yoast-menu-bf-sale-badge{background-color:#1f2937;border:1px solid #fcd34d;border-radius:8px;color:#fcd34d;font-size:10px;font-weight:600;line-height:normal;margin-right:5px;padding:2px 8px;text-wrap:nowrap}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu .wpseo-focus-keyword{display:inline-block!important;max-width:100px!important;overflow:hidden;text-overflow:ellipsis!important;vertical-align:bottom;white-space:nowrap}#wpadminbar .yoast-badge{border-radius:8px;display:inline-block;font-weight:600;line-height:1.6;margin-right:4px;padding:0 8px}#wpadminbar .yoast-beta-badge{background-color:#cce5ff;color:#004973}#wpadminbar .yoast-premium-badge{background-color:#fff3cd;color:#674e00}#wpadminbar .yoast-issue-added,#wpadminbar .yoast-issue-added:hover{background-color:#a4286a;border-radius:10px 0 10px 10px;box-shadow:-1px 1px 1px 1px grey;color:#fff;right:0;padding:2px 12px;position:absolute;top:32px;white-space:nowrap}#wpadminbar .yoast-issue-added{display:none}#wpadminbar .yoast-issue-counter{background-color:#d63638;border-radius:9px;color:#fff;display:inline;padding:1px 6px 1px 7px!important}#wpadminbar .yoast-logo.svg{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJmaWxsOiM4Mjg3OGMiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBkPSJNMjAzLjYgMzk1YzYuOC0xNy40IDYuOC0zNi42IDAtNTRsLTc5LjQtMjA0aDcwLjlsNDcuNyAxNDkuNCA3NC44LTIwNy42SDExNi40Yy00MS44IDAtNzYgMzQuMi03NiA3NlYzNTdjMCA0MS44IDM0LjIgNzYgNzYgNzZIMTczYzE2LTguOSAyNC42LTIyLjcgMzAuNi0zOE00NzEuNiAxNTQuOGMwLTQxLjgtMzQuMi03Ni03Ni03NmgtM0wyODUuNyAzNjVjLTkuNiAyNi43LTE5LjQgNDkuMy0zMC4zIDY4aDIxNi4yeiIvPjxwYXRoIGQ9Im0zMzggMS4zLTkzLjMgMjU5LjEtNDIuMS0xMzEuOWgtODkuMWw4My44IDIxNS4yYzYgMTUuNSA2IDMyLjUgMCA0OC03LjQgMTktMTkgMzcuMy01MyA0MS45bC03LjIgMXY3Nmg4LjNjODEuNyAwIDExOC45LTU3LjIgMTQ5LjYtMTQyLjlMNDMxLjYgMS4zek0yNzkuNCAzNjJjLTMyLjkgOTItNjcuNiAxMjguNy0xMjUuNyAxMzEuOHYtNDVjMzcuNS03LjUgNTEuMy0zMSA1OS4xLTUxLjEgNy41LTE5LjMgNy41LTQwLjcgMC02MGwtNzUtMTkyLjdoNTIuOGw1My4zIDE2Ni44IDEwNS45LTI5NGg1OC4xeiIvPjwvc3ZnPg==");background-position:100% 6px;background-repeat:no-repeat;background-size:20px;float:right;height:30px;width:26px}#wpadminbar .wpseo-no-adminbar-notifications{display:none}@media screen and (max-width:782px){#wp-admin-bar-wpseo-menu .wpseo-score-icon{margin:16px 2px 0 10px!important}#wpadminbar #wp-admin-bar-wpseo-menu{display:block;position:static}#wpadminbar .yoast-logo.svg{background-position:50% 8px;background-size:30px;height:46px;width:52px}#wpadminbar .yoast-logo+.yoast-issue-counter{margin-right:-5px;margin-left:10px}#wpadminbar .ab-sub-wrapper .yoast-issue-counter{position:relative;top:-5px;vertical-align:text-top}#wpadminbar .yoast-issue-added,#wpadminbar .yoast-issue-added:hover{line-height:1.8;top:46px;white-space:normal}#wp-admin-bar-wpseo-menu.menupop .ab-sub-wrapper #wp-admin-bar-wpseo-kwresearch,#wp-admin-bar-wpseo-menu.menupop .ab-sub-wrapper #wp-admin-bar-wpseo-settings{display:none}}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item{align-items:center;border-color:#0000;border-radius:.375rem;cursor:pointer;display:inline-flex;height:1rem;justify-content:center;margin-right:.75rem;margin-left:.75rem;margin-top:.5rem;--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:500;line-height:1rem;padding:.375rem .625rem;text-align:center;-webkit-text-decoration-line:none;text-decoration-line:none;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-color:#0000}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:visited{color:#78350f}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:hover{--tw-bg-opacity:1;background-color:rgb(251 191 36/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:hover:visited{color:#78350f}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:focus{--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1));outline-color:#fbbf24;outline-offset:2px;outline-style:solid;outline-width:2px}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium{display:flex}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item a{--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-upgrade-sidebar{display:none}#wpadminbar #wp-admin-bar-wpseo_brand_insights,#wpadminbar #wp-admin-bar-wpseo_brand_insights_premium{display:flex}#wpadminbar #wp-admin-bar-wpseo_brand_insights .ab-item,#wpadminbar #wp-admin-bar-wpseo_brand_insights_premium .ab-item{padding:.625rem .75rem .5rem}@media (min-width:768px){#wpadminbar #wp-admin-bar-wpseo_brand_insights .ab-item,#wpadminbar #wp-admin-bar-wpseo_brand_insights_premium .ab-item{width:100%}}#wpadminbar .yoast-brand-insights-gradient-border{background:linear-gradient(-97.38deg,#cd82ab,#a5b4fc);border-radius:.375rem;display:flex;padding:1px;position:relative}#wpadminbar .yoast-brand-insights-content{align-items:center;border-radius:.375rem;display:flex;font-size:.75rem;font-weight:500;gap:.25rem;justify-content:center;padding-right:1.1rem;padding-left:1.1rem;position:relative;white-space:nowrap;width:100%}@media (min-width:1024px){#wpadminbar .yoast-brand-insights-content{padding-right:1rem;padding-left:1rem}}#wpadminbar .yoast-brand-insights-content{background:var(--yoast-adminbar-submenu-bg,#2c3338)}#wpadminbar .yst-external-link-icon{background-color:currentColor;display:inline-block;height:.875rem;margin-bottom:.125rem;mask-image:var(--yoast-svg-icon-external-link);-webkit-mask-image:var(--yoast-svg-icon-external-link);mask-size:100% 100%;-webkit-mask-size:100% 100%;vertical-align:middle;width:.875rem}#wpseo-new-badge-upgrade{align-items:center;border-radius:18px;display:inline-flex;height:1rem;justify-content:center;margin:.125rem .5rem;white-space:nowrap;width:2.375rem;--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:600;--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity,1))} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/adminbar-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/adminbar-2711.css new file mode 100644 index 0000000..8546ab5 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/adminbar-2711.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 10px 0 3px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe}:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}#wp-admin-bar-wpseo-menu .wpseo-score-icon{margin:10px 0 0 4px!important}#wp-admin-bar-wpseo-menu .wpseo-score-icon.adminbar-sub-menu-score{margin:11px 0 0 4px!important}#wp-admin-bar-wpseo-menu-default .ab-item{line-height:2.46153846!important}#wp-admin-bar-wpseo-menu .ab-submenu{margin-bottom:5px}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium span{background:#1f2937;border:1px solid #fcd34d;border-radius:14px;color:#fcd34d;font-size:12px;font-weight:600;padding:1px 4px}#wpadminbar .yoast-menu-bf-sale-badge{background-color:#1f2937;border:1px solid #fcd34d;border-radius:8px;color:#fcd34d;font-size:10px;font-weight:600;line-height:normal;margin-left:5px;padding:2px 8px;text-wrap:nowrap}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu .wpseo-focus-keyword{display:inline-block!important;max-width:100px!important;overflow:hidden;text-overflow:ellipsis!important;vertical-align:bottom;white-space:nowrap}#wpadminbar .yoast-badge{border-radius:8px;display:inline-block;font-weight:600;line-height:1.6;margin-left:4px;padding:0 8px}#wpadminbar .yoast-beta-badge{background-color:#cce5ff;color:#004973}#wpadminbar .yoast-premium-badge{background-color:#fff3cd;color:#674e00}#wpadminbar .yoast-issue-added,#wpadminbar .yoast-issue-added:hover{background-color:#a4286a;border-radius:0 10px 10px 10px;box-shadow:1px 1px 1px 1px grey;color:#fff;left:0;padding:2px 12px;position:absolute;top:32px;white-space:nowrap}#wpadminbar .yoast-issue-added{display:none}#wpadminbar .yoast-issue-counter{background-color:#d63638;border-radius:9px;color:#fff;display:inline;padding:1px 7px 1px 6px!important}#wpadminbar .yoast-logo.svg{background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIHN0eWxlPSJmaWxsOiM4Mjg3OGMiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBkPSJNMjAzLjYgMzk1YzYuOC0xNy40IDYuOC0zNi42IDAtNTRsLTc5LjQtMjA0aDcwLjlsNDcuNyAxNDkuNCA3NC44LTIwNy42SDExNi40Yy00MS44IDAtNzYgMzQuMi03NiA3NlYzNTdjMCA0MS44IDM0LjIgNzYgNzYgNzZIMTczYzE2LTguOSAyNC42LTIyLjcgMzAuNi0zOE00NzEuNiAxNTQuOGMwLTQxLjgtMzQuMi03Ni03Ni03NmgtM0wyODUuNyAzNjVjLTkuNiAyNi43LTE5LjQgNDkuMy0zMC4zIDY4aDIxNi4yeiIvPjxwYXRoIGQ9Im0zMzggMS4zLTkzLjMgMjU5LjEtNDIuMS0xMzEuOWgtODkuMWw4My44IDIxNS4yYzYgMTUuNSA2IDMyLjUgMCA0OC03LjQgMTktMTkgMzcuMy01MyA0MS45bC03LjIgMXY3Nmg4LjNjODEuNyAwIDExOC45LTU3LjIgMTQ5LjYtMTQyLjlMNDMxLjYgMS4zek0yNzkuNCAzNjJjLTMyLjkgOTItNjcuNiAxMjguNy0xMjUuNyAxMzEuOHYtNDVjMzcuNS03LjUgNTEuMy0zMSA1OS4xLTUxLjEgNy41LTE5LjMgNy41LTQwLjcgMC02MGwtNzUtMTkyLjdoNTIuOGw1My4zIDE2Ni44IDEwNS45LTI5NGg1OC4xeiIvPjwvc3ZnPg==");background-position:0 6px;background-repeat:no-repeat;background-size:20px;float:left;height:30px;width:26px}#wpadminbar .wpseo-no-adminbar-notifications{display:none}@media screen and (max-width:782px){#wp-admin-bar-wpseo-menu .wpseo-score-icon{margin:16px 10px 0 2px!important}#wpadminbar #wp-admin-bar-wpseo-menu{display:block;position:static}#wpadminbar .yoast-logo.svg{background-position:50% 8px;background-size:30px;height:46px;width:52px}#wpadminbar .yoast-logo+.yoast-issue-counter{margin-left:-5px;margin-right:10px}#wpadminbar .ab-sub-wrapper .yoast-issue-counter{position:relative;top:-5px;vertical-align:text-top}#wpadminbar .yoast-issue-added,#wpadminbar .yoast-issue-added:hover{line-height:1.8;top:46px;white-space:normal}#wp-admin-bar-wpseo-menu.menupop .ab-sub-wrapper #wp-admin-bar-wpseo-kwresearch,#wp-admin-bar-wpseo-menu.menupop .ab-sub-wrapper #wp-admin-bar-wpseo-settings{display:none}}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item{align-items:center;border-color:#0000;border-radius:.375rem;cursor:pointer;display:inline-flex;height:1rem;justify-content:center;margin-left:.75rem;margin-right:.75rem;margin-top:.5rem;--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:500;line-height:1rem;padding:.375rem .625rem;text-align:center;-webkit-text-decoration-line:none;text-decoration-line:none;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-color:#0000}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:visited{color:#78350f}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:hover{--tw-bg-opacity:1;background-color:rgb(251 191 36/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:hover:visited{color:#78350f}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item:focus{--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1));outline-color:#fbbf24;outline-offset:2px;outline-style:solid;outline-width:2px}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium{display:flex}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-get-premium .ab-empty-item a{--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}#wpadminbar .quicklinks #wp-admin-bar-wpseo-menu #wp-admin-bar-wpseo-menu-default li#wp-admin-bar-wpseo-upgrade-sidebar{display:none}#wpadminbar #wp-admin-bar-wpseo_brand_insights,#wpadminbar #wp-admin-bar-wpseo_brand_insights_premium{display:flex}#wpadminbar #wp-admin-bar-wpseo_brand_insights .ab-item,#wpadminbar #wp-admin-bar-wpseo_brand_insights_premium .ab-item{padding:.625rem .75rem .5rem}@media (min-width:768px){#wpadminbar #wp-admin-bar-wpseo_brand_insights .ab-item,#wpadminbar #wp-admin-bar-wpseo_brand_insights_premium .ab-item{width:100%}}#wpadminbar .yoast-brand-insights-gradient-border{background:linear-gradient(97.38deg,#cd82ab,#a5b4fc);border-radius:.375rem;display:flex;padding:1px;position:relative}#wpadminbar .yoast-brand-insights-content{align-items:center;border-radius:.375rem;display:flex;font-size:.75rem;font-weight:500;gap:.25rem;justify-content:center;padding-left:1.1rem;padding-right:1.1rem;position:relative;white-space:nowrap;width:100%}@media (min-width:1024px){#wpadminbar .yoast-brand-insights-content{padding-left:1rem;padding-right:1rem}}#wpadminbar .yoast-brand-insights-content{background:var(--yoast-adminbar-submenu-bg,#2c3338)}#wpadminbar .yst-external-link-icon{background-color:currentColor;display:inline-block;height:.875rem;margin-bottom:.125rem;mask-image:var(--yoast-svg-icon-external-link);-webkit-mask-image:var(--yoast-svg-icon-external-link);mask-size:100% 100%;-webkit-mask-size:100% 100%;vertical-align:middle;width:.875rem}#wpseo-new-badge-upgrade{align-items:center;border-radius:18px;display:inline-flex;height:1rem;justify-content:center;margin:.125rem .5rem;white-space:nowrap;width:2.375rem;--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:600;--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity,1))} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/ai-fix-assessments-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/ai-fix-assessments-2711-rtl.css new file mode 100644 index 0000000..6520677 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/ai-fix-assessments-2711-rtl.css @@ -0,0 +1 @@ +.yst-fixes-button__lock-icon{background-color:#fde68a;border-radius:50%;height:14px;padding:1px 2px;position:absolute;left:-6px;top:-6px;width:14px}.ai-button:disabled{pointer-events:auto} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/ai-fix-assessments-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/ai-fix-assessments-2711.css new file mode 100644 index 0000000..066f8eb --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/ai-fix-assessments-2711.css @@ -0,0 +1 @@ +.yst-fixes-button__lock-icon{background-color:#fde68a;border-radius:50%;height:14px;padding:1px 2px;position:absolute;right:-6px;top:-6px;width:14px}.ai-button:disabled{pointer-events:auto} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/ai-frontend-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/ai-frontend-2711-rtl.css new file mode 100644 index 0000000..6aca9d9 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/ai-frontend-2711-rtl.css @@ -0,0 +1 @@ +.yst-root *,.yst-root :after,.yst-root :before{border:0 solid #e5e7eb;box-sizing:border-box}.yst-root :after,.yst-root :before{--tw-content:""}.yst-root{-webkit-text-size-adjust:100%;margin:0;tab-size:4}.yst-root hr{border-top-width:1px;color:inherit;height:0}.yst-root abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.yst-root h1,.yst-root h2,.yst-root h3,.yst-root h4,.yst-root h5,.yst-root h6{font-size:inherit;font-weight:inherit}.yst-root a{color:inherit;text-decoration:inherit}.yst-root b,.yst-root strong{font-weight:bolder}.yst-root code,.yst-root kbd,.yst-root pre,.yst-root samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}.yst-root small{font-size:80%}.yst-root sub,.yst-root sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}.yst-root sub{bottom:-.25em}.yst-root sup{top:-.5em}.yst-root table{border-collapse:collapse;border-color:inherit;text-indent:0}.yst-root button,.yst-root input,.yst-root optgroup,.yst-root select,.yst-root textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}.yst-root button,.yst-root select{text-transform:none}.yst-root [type=button],.yst-root [type=reset],.yst-root [type=submit],.yst-root button{-webkit-appearance:button;background-color:initial;background-image:none}.yst-root progress{vertical-align:initial}.yst-root ::-webkit-inner-spin-button,.yst-root ::-webkit-outer-spin-button{height:auto}.yst-root [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.yst-root ::-webkit-search-decoration{-webkit-appearance:none}.yst-root ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.yst-root summary{display:list-item}.yst-root blockquote,.yst-root dd,.yst-root dl,.yst-root figure,.yst-root h1,.yst-root h2,.yst-root h3,.yst-root h4,.yst-root h5,.yst-root h6,.yst-root hr,.yst-root p,.yst-root pre{margin:0}.yst-root fieldset{margin:0;padding:0}.yst-root legend{padding:0}.yst-root menu,.yst-root ol,.yst-root ul{list-style:none;margin:0;padding:0}.yst-root textarea{resize:vertical}.yst-root input::placeholder,.yst-root textarea::placeholder{color:#6b7280;opacity:1}.yst-root [role=button],.yst-root button{cursor:pointer}.yst-root :disabled{cursor:default}.yst-root audio,.yst-root canvas,.yst-root embed,.yst-root iframe,.yst-root img,.yst-root object,.yst-root svg,.yst-root video{display:block;vertical-align:middle}.yst-root img,.yst-root video{height:auto;max-width:100%}.yst-root [type=date],.yst-root [type=datetime-local],.yst-root [type=email],.yst-root [type=month],.yst-root [type=number],.yst-root [type=password],.yst-root [type=search],.yst-root [type=tel],.yst-root [type=text],.yst-root [type=time],.yst-root [type=url],.yst-root [type=week]{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root [type=date]:focus,.yst-root [type=datetime-local]:focus,.yst-root [type=email]:focus,.yst-root [type=month]:focus,.yst-root [type=number]:focus,.yst-root [type=password]:focus,.yst-root [type=search]:focus,.yst-root [type=tel]:focus,.yst-root [type=text]:focus,.yst-root [type=time]:focus,.yst-root [type=url]:focus,.yst-root [type=week]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=date]::placeholder,.yst-root [type=datetime-local]::placeholder,.yst-root [type=email]::placeholder,.yst-root [type=month]::placeholder,.yst-root [type=number]::placeholder,.yst-root [type=password]::placeholder,.yst-root [type=search]::placeholder,.yst-root [type=tel]::placeholder,.yst-root [type=text]::placeholder,.yst-root [type=time]::placeholder,.yst-root [type=url]::placeholder,.yst-root [type=week]::placeholder{color:#6b7280;opacity:1}.yst-root [type=date]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=datetime-local]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=email]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=month]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=number]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=password]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=search]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=tel]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=text]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=time]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=url]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=week]::-webkit-datetime-edit-fields-wrapper{padding:0}.yst-root [type=date]::-webkit-date-and-time-value,.yst-root [type=datetime-local]::-webkit-date-and-time-value,.yst-root [type=email]::-webkit-date-and-time-value,.yst-root [type=month]::-webkit-date-and-time-value,.yst-root [type=number]::-webkit-date-and-time-value,.yst-root [type=password]::-webkit-date-and-time-value,.yst-root [type=search]::-webkit-date-and-time-value,.yst-root [type=tel]::-webkit-date-and-time-value,.yst-root [type=text]::-webkit-date-and-time-value,.yst-root [type=time]::-webkit-date-and-time-value,.yst-root [type=url]::-webkit-date-and-time-value,.yst-root [type=week]::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}.yst-root [type=date]::-webkit-datetime-edit,.yst-root [type=datetime-local]::-webkit-datetime-edit,.yst-root [type=email]::-webkit-datetime-edit,.yst-root [type=month]::-webkit-datetime-edit,.yst-root [type=number]::-webkit-datetime-edit,.yst-root [type=password]::-webkit-datetime-edit,.yst-root [type=search]::-webkit-datetime-edit,.yst-root [type=tel]::-webkit-datetime-edit,.yst-root [type=text]::-webkit-datetime-edit,.yst-root [type=time]::-webkit-datetime-edit,.yst-root [type=url]::-webkit-datetime-edit,.yst-root [type=week]::-webkit-datetime-edit{display:inline-flex}.yst-root [type=date]::-webkit-datetime-edit,.yst-root [type=date]::-webkit-datetime-edit-day-field,.yst-root [type=date]::-webkit-datetime-edit-hour-field,.yst-root [type=date]::-webkit-datetime-edit-meridiem-field,.yst-root [type=date]::-webkit-datetime-edit-millisecond-field,.yst-root [type=date]::-webkit-datetime-edit-minute-field,.yst-root [type=date]::-webkit-datetime-edit-month-field,.yst-root [type=date]::-webkit-datetime-edit-second-field,.yst-root [type=date]::-webkit-datetime-edit-year-field,.yst-root [type=datetime-local]::-webkit-datetime-edit,.yst-root [type=datetime-local]::-webkit-datetime-edit-day-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-hour-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-meridiem-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-millisecond-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-minute-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-month-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-second-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-year-field,.yst-root [type=email]::-webkit-datetime-edit,.yst-root [type=email]::-webkit-datetime-edit-day-field,.yst-root [type=email]::-webkit-datetime-edit-hour-field,.yst-root [type=email]::-webkit-datetime-edit-meridiem-field,.yst-root [type=email]::-webkit-datetime-edit-millisecond-field,.yst-root [type=email]::-webkit-datetime-edit-minute-field,.yst-root [type=email]::-webkit-datetime-edit-month-field,.yst-root [type=email]::-webkit-datetime-edit-second-field,.yst-root [type=email]::-webkit-datetime-edit-year-field,.yst-root [type=month]::-webkit-datetime-edit,.yst-root [type=month]::-webkit-datetime-edit-day-field,.yst-root [type=month]::-webkit-datetime-edit-hour-field,.yst-root [type=month]::-webkit-datetime-edit-meridiem-field,.yst-root [type=month]::-webkit-datetime-edit-millisecond-field,.yst-root [type=month]::-webkit-datetime-edit-minute-field,.yst-root [type=month]::-webkit-datetime-edit-month-field,.yst-root [type=month]::-webkit-datetime-edit-second-field,.yst-root [type=month]::-webkit-datetime-edit-year-field,.yst-root [type=number]::-webkit-datetime-edit,.yst-root [type=number]::-webkit-datetime-edit-day-field,.yst-root [type=number]::-webkit-datetime-edit-hour-field,.yst-root [type=number]::-webkit-datetime-edit-meridiem-field,.yst-root [type=number]::-webkit-datetime-edit-millisecond-field,.yst-root [type=number]::-webkit-datetime-edit-minute-field,.yst-root [type=number]::-webkit-datetime-edit-month-field,.yst-root [type=number]::-webkit-datetime-edit-second-field,.yst-root [type=number]::-webkit-datetime-edit-year-field,.yst-root [type=password]::-webkit-datetime-edit,.yst-root [type=password]::-webkit-datetime-edit-day-field,.yst-root [type=password]::-webkit-datetime-edit-hour-field,.yst-root [type=password]::-webkit-datetime-edit-meridiem-field,.yst-root [type=password]::-webkit-datetime-edit-millisecond-field,.yst-root [type=password]::-webkit-datetime-edit-minute-field,.yst-root [type=password]::-webkit-datetime-edit-month-field,.yst-root [type=password]::-webkit-datetime-edit-second-field,.yst-root [type=password]::-webkit-datetime-edit-year-field,.yst-root [type=search]::-webkit-datetime-edit,.yst-root [type=search]::-webkit-datetime-edit-day-field,.yst-root [type=search]::-webkit-datetime-edit-hour-field,.yst-root [type=search]::-webkit-datetime-edit-meridiem-field,.yst-root [type=search]::-webkit-datetime-edit-millisecond-field,.yst-root [type=search]::-webkit-datetime-edit-minute-field,.yst-root [type=search]::-webkit-datetime-edit-month-field,.yst-root [type=search]::-webkit-datetime-edit-second-field,.yst-root [type=search]::-webkit-datetime-edit-year-field,.yst-root [type=tel]::-webkit-datetime-edit,.yst-root [type=tel]::-webkit-datetime-edit-day-field,.yst-root [type=tel]::-webkit-datetime-edit-hour-field,.yst-root [type=tel]::-webkit-datetime-edit-meridiem-field,.yst-root [type=tel]::-webkit-datetime-edit-millisecond-field,.yst-root [type=tel]::-webkit-datetime-edit-minute-field,.yst-root [type=tel]::-webkit-datetime-edit-month-field,.yst-root [type=tel]::-webkit-datetime-edit-second-field,.yst-root [type=tel]::-webkit-datetime-edit-year-field,.yst-root [type=text]::-webkit-datetime-edit,.yst-root [type=text]::-webkit-datetime-edit-day-field,.yst-root [type=text]::-webkit-datetime-edit-hour-field,.yst-root [type=text]::-webkit-datetime-edit-meridiem-field,.yst-root [type=text]::-webkit-datetime-edit-millisecond-field,.yst-root [type=text]::-webkit-datetime-edit-minute-field,.yst-root [type=text]::-webkit-datetime-edit-month-field,.yst-root [type=text]::-webkit-datetime-edit-second-field,.yst-root [type=text]::-webkit-datetime-edit-year-field,.yst-root [type=time]::-webkit-datetime-edit,.yst-root [type=time]::-webkit-datetime-edit-day-field,.yst-root [type=time]::-webkit-datetime-edit-hour-field,.yst-root [type=time]::-webkit-datetime-edit-meridiem-field,.yst-root [type=time]::-webkit-datetime-edit-millisecond-field,.yst-root [type=time]::-webkit-datetime-edit-minute-field,.yst-root [type=time]::-webkit-datetime-edit-month-field,.yst-root [type=time]::-webkit-datetime-edit-second-field,.yst-root [type=time]::-webkit-datetime-edit-year-field,.yst-root [type=url]::-webkit-datetime-edit,.yst-root [type=url]::-webkit-datetime-edit-day-field,.yst-root [type=url]::-webkit-datetime-edit-hour-field,.yst-root [type=url]::-webkit-datetime-edit-meridiem-field,.yst-root [type=url]::-webkit-datetime-edit-millisecond-field,.yst-root [type=url]::-webkit-datetime-edit-minute-field,.yst-root [type=url]::-webkit-datetime-edit-month-field,.yst-root [type=url]::-webkit-datetime-edit-second-field,.yst-root [type=url]::-webkit-datetime-edit-year-field,.yst-root [type=week]::-webkit-datetime-edit,.yst-root [type=week]::-webkit-datetime-edit-day-field,.yst-root [type=week]::-webkit-datetime-edit-hour-field,.yst-root [type=week]::-webkit-datetime-edit-meridiem-field,.yst-root [type=week]::-webkit-datetime-edit-millisecond-field,.yst-root [type=week]::-webkit-datetime-edit-minute-field,.yst-root [type=week]::-webkit-datetime-edit-month-field,.yst-root [type=week]::-webkit-datetime-edit-second-field,.yst-root [type=week]::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}.yst-root textarea{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root textarea:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root textarea::placeholder{color:#6b7280;opacity:1}.yst-root select{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root select:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:left .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-left:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}.yst-root select:where([size]:not([size="1"])){background-image:none;background-position:100% 0;background-repeat:unset;background-size:initial;padding-left:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}.yst-root select[multiple]{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root select[multiple]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=checkbox]{appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000;border-radius:0}.yst-root [type=checkbox]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=checkbox]:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}@media (forced-colors:active){.yst-root [type=checkbox]:checked{appearance:auto}}.yst-root [type=checkbox]:checked:focus,.yst-root [type=checkbox]:checked:hover,.yst-root [type=checkbox]:indeterminate{background-color:currentColor;border-color:#0000}.yst-root [type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}@media (forced-colors:active){.yst-root [type=checkbox]:indeterminate{appearance:auto}}.yst-root [type=checkbox]:indeterminate:focus,.yst-root [type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}.yst-root [type=radio]{appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000;border-radius:100%}.yst-root [type=radio]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=radio]:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}@media (forced-colors:active){.yst-root [type=radio]:checked{appearance:auto}}.yst-root [type=radio]:checked:focus,.yst-root [type=radio]:checked:hover{background-color:currentColor;border-color:#0000}.yst-root{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:.8125rem;font-weight:400;line-height:1.5;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.yst-root a{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity));-webkit-text-decoration-line:underline;text-decoration-line:underline}.yst-root a:visited{color:#a61e69}.yst-root a:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity))}.yst-root a:hover:visited{color:#b94986}.yst-root a:focus{border-radius:.125rem;--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity));outline-color:#4f46e5;outline-offset:1px;outline-style:solid}.yst-root [type=date]::placeholder,.yst-root [type=datetime-local]::placeholder,.yst-root [type=email]::placeholder,.yst-root [type=month]::placeholder,.yst-root [type=number]::placeholder,.yst-root [type=password]::placeholder,.yst-root [type=search]::placeholder,.yst-root [type=tel]::placeholder,.yst-root [type=text]::placeholder,.yst-root [type=time]::placeholder,.yst-root [type=url]::placeholder,.yst-root [type=week]::placeholder,.yst-root textarea::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}.yst-root svg path{stroke-width:inherit}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.yst-root .yst-alert{border-radius:.375rem;display:flex;gap:.75rem;padding:1rem}.yst-root .yst-alert--info{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity))}.yst-root .yst-alert--info .yst-alert__message{--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity))}.yst-root .yst-alert--warning{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity))}.yst-root .yst-alert--warning .yst-alert__message{--tw-text-opacity:1;color:rgb(146 64 14/var(--tw-text-opacity))}.yst-root .yst-alert--success{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity))}.yst-root .yst-alert--success .yst-alert__message{--tw-text-opacity:1;color:rgb(22 101 52/var(--tw-text-opacity))}.yst-root .yst-alert--error{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.yst-root .yst-alert--error .yst-alert__message{--tw-text-opacity:1;color:rgb(153 27 27/var(--tw-text-opacity))}.yst-root .yst-alert__icon{flex-grow:0;flex-shrink:0;height:1.25rem;width:1.25rem}.yst-root .yst-autocomplete{position:relative}.yst-root .yst-autocomplete--error .yst-autocomplete__button{--tw-border-opacity:1;border-color:rgb(252 165 165/var(--tw-border-opacity))}.yst-root .yst-autocomplete--error .yst-autocomplete__button:focus{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-opacity:1;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity))}.yst-root .yst-autocomplete--error .yst-autocomplete__input::placeholder{--tw-placeholder-opacity:1;color:rgb(252 165 165/var(--tw-placeholder-opacity))}.yst-root .yst-autocomplete--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-autocomplete--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-autocomplete__button{align-items:center;border-radius:.375rem;border-width:0;display:flex;height:100%;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding-right:.75rem;padding-left:.75rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-autocomplete__button:focus-within{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-autocomplete__button-icon{height:1.25rem;pointer-events:none;position:absolute;left:.625rem;top:.6875rem;width:1.25rem;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-autocomplete__input{border-width:0;font-size:.8125rem;padding:.5rem 0 .5rem 2.5rem;width:100%;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-autocomplete__input:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-autocomplete__options{border-radius:.375rem;margin-top:.25rem;max-height:15rem;overflow:auto;position:absolute;width:100%;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity));--tw-ring-opacity:0.05}.yst-root .yst-autocomplete__options:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-autocomplete__option{align-items:center;cursor:default;display:flex;justify-content:space-between;padding:.5rem .75rem;position:relative;-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.yst-root .yst-autocomplete__option--active{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-autocomplete__option--selected{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-select__option-label{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yst-root .yst-autocomplete__option-check{flex-shrink:0;height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-badge{align-items:center;border-radius:9999px;display:inline-flex;white-space:nowrap;--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity));font-size:.75rem;font-weight:500;line-height:1.25;padding:.125rem .5rem;vertical-align:middle;--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity))}.yst-root .yst-badge--info{--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(30 58 138/var(--tw-text-opacity))}.yst-root .yst-badge--upsell{--tw-bg-opacity:1;background-color:rgb(253 230 138/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity))}.yst-root .yst-badge--plain{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.yst-root .yst-badge--small{font-size:.675rem}.yst-root .yst-badge--large{font-size:1rem;padding-right:.75rem;padding-left:.75rem}.yst-root .yst-button{align-items:center;border-radius:.375rem;cursor:pointer;display:inline-flex;font-size:.8125rem;font-weight:500;justify-content:center;line-height:1.25rem;padding:.5rem .75rem;text-align:center;-webkit-text-decoration-line:none;text-decoration-line:none;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-color:#0000}.yst-root .yst-button:focus{outline-color:#a61e69;outline-offset:2px;outline-style:solid;outline-width:2px}.yst-root a.yst-button:focus{border-radius:.375rem}.yst-root .yst-button--primary{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));--tw-ring-color:#0000}.yst-root .yst-button--primary:visited{color:#fff}.yst-root .yst-button--primary:hover{--tw-bg-opacity:1;background-color:rgb(143 15 87/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-button--primary:hover:visited{color:#fff}.yst-root .yst-button--primary:focus{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));outline-color:#8f0f57}.yst-root .yst-button--secondary{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-button--secondary:visited{color:#1e293b}.yst-root .yst-button--secondary:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-button--secondary:hover:visited{color:#1e293b}.yst-root .yst-button--secondary:focus{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));outline-color:#8f0f57}.yst-root .yst-button--tertiary{background-color:initial;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-button--tertiary:visited{color:#83084e}.yst-root .yst-button--tertiary:hover{--tw-text-opacity:1;color:rgb(131 8 78/var(--tw-text-opacity))}.yst-root .yst-button--tertiary:hover:visited{color:#83084e}.yst-root .yst-button--tertiary:focus{--tw-text-opacity:1;color:rgb(131 8 78/var(--tw-text-opacity));outline-color:#8f0f57}.yst-root .yst-button--error{border-color:#0000;--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-button--error:visited{color:#fff}.yst-root .yst-button--error:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-button--error:hover:visited{color:#fff}.yst-root .yst-button--error:focus{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));outline-color:#dc2626}.yst-root .yst-button--upsell{border-color:#0000;--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity))}.yst-root .yst-button--upsell:visited{color:#78350f}.yst-root .yst-button--upsell:hover{--tw-bg-opacity:1;background-color:rgb(251 191 36/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity))}.yst-root .yst-button--upsell:hover:visited{color:#78350f}.yst-root .yst-button--upsell:focus{--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity));outline-color:#fbbf24}.yst-root .yst-button--large{font-size:.875rem;line-height:1.5rem;padding:.5rem .75rem}.yst-root .yst-button--extra-large{font-size:1rem;line-height:1.5rem;padding:.625rem .875rem}.yst-root .yst-button--small{font-size:.75rem;line-height:1rem;padding:.375rem .625rem}.yst-root .yst-button--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-button--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-checkbox{align-items:center;display:flex}.yst-root .yst-checkbox--disabled .yst-checkbox__input,.yst-root .yst-checkbox--disabled .yst-checkbox__label{cursor:not-allowed;opacity:.5}.yst-root .yst-checkbox__input{border-radius:.25rem;height:1rem;width:1rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-checkbox__input:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-checkbox__label{margin-right:.75rem}.yst-root .yst-code{border-radius:.25rem;display:inline-block;margin:0;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));font-size:.75rem;line-height:1.25;padding:.25rem;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.yst-root .yst-code--block{display:block;margin-bottom:.5rem;margin-top:.5rem;max-width:100%;overflow-x:auto;padding:.25rem .5rem;white-space:nowrap}.yst-root .yst-file-input{border-radius:.375rem;border-style:dashed;border-width:2px;width:100%;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1.25rem 1.5rem 1.5rem;text-align:center;transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-file-input.yst-is-drag-over{--tw-border-opacity:1;border-color:rgb(205 130 171/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(250 243 247/var(--tw-bg-opacity))}.yst-root .yst-file-input.yst-is-drag-over .yst-file-input__content{pointer-events:none}.yst-root .yst-file-input.yst-is-drag-over .yst-file-input__icon{--tw-translate-y:-0.5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-text-opacity:1;color:rgb(185 73 134/var(--tw-text-opacity))}.yst-root .yst-file-input.yst-is-disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-file-input.yst-is-disabled .yst-file-input__select-label{cursor:not-allowed}.yst-root .yst-file-input__content{align-items:center;display:inline-flex;flex-direction:column;max-width:20rem}.yst-root .yst-file-input__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-file-input__content{text-align:center}.yst-root .yst-file-input__icon{height:3rem;margin-right:auto;margin-left:auto;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:3rem;stroke-width:1;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity));transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-file-input__icon>path{stroke-width:1}.yst-root .yst-file-input__input{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.yst-root .yst-file-input__input:focus+.yst-file-input__select-label{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-file-input__labels{display:inline-block;font-weight:400;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-file-input__select-label{border-radius:.375rem;font-weight:500}[dir=rtl] .yst-root .yst-file-input__labels{flex-direction:row-reverse}.yst-root .yst-label{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-link{cursor:pointer;--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity));-webkit-text-decoration-line:underline;text-decoration-line:underline}.yst-root .yst-link:visited{color:#a61e69}.yst-root .yst-link:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity))}.yst-root .yst-link:hover:visited{color:#b94986}.yst-root .yst-link:focus{border-radius:.125rem;--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(79 70 229/var(--tw-ring-opacity));--tw-ring-offset-width:1px;--tw-ring-offset-color:#0000}.yst-root .yst-link--primary{--tw-text-opacity:1;color:rgb(154 22 96/var(--tw-text-opacity))}.yst-root .yst-link--primary:focus,.yst-root .yst-link--primary:hover{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-link--primary:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(154 22 96/var(--tw-ring-opacity))}.yst-root .yst-link--error{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.yst-root .yst-link--error:focus,.yst-root .yst-link--error:hover{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.yst-root .yst-link--error:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(220 38 38/var(--tw-ring-opacity))}.yst-root .yst-paper{border-radius:.5rem;display:flex;flex-direction:column;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-paper__header{border-bottom-width:1px;padding:2rem}.yst-root .yst-paper__content{flex-grow:1;padding:2rem}.yst-root .yst-progress-bar{border-radius:9999px;display:block;overflow:hidden;width:100%;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-progress-bar__progress{border-radius:9999px;display:block;height:.375rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));transition-duration:.2s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:linear}.yst-root .yst-radio{align-items:center;display:flex}.yst-root .yst-radio--disabled .yst-radio__check,.yst-root .yst-radio--disabled .yst-radio__input,.yst-root .yst-radio--disabled .yst-radio__label{cursor:not-allowed;opacity:.5}.yst-root .yst-radio--disabled .yst-radio__check:focus,.yst-root .yst-radio--disabled .yst-radio__input:focus,.yst-root .yst-radio--disabled .yst-radio__label:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-radio--inline-block{display:inline-flex}.yst-root .yst-radio--inline-block .yst-radio__input{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.yst-root .yst-radio--inline-block .yst-radio__input:checked+.yst-radio__content .yst-radio__label{border-color:#0000;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-radio--inline-block .yst-radio__input:checked+.yst-radio__content .yst-radio__check{visibility:visible}.yst-root .yst-radio--inline-block .yst-radio__input:focus+.yst-radio__content .yst-radio__label{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-radio--inline-block .yst-radio__input:checked:focus+.yst-radio__content .yst-radio__label{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-offset-width:1px}.yst-root .yst-radio--inline-block .yst-radio__content{position:relative}.yst-root .yst-radio--inline-block .yst-radio__label{align-items:center;border-radius:.5rem;border-width:1px;cursor:pointer;display:flex;height:3.5rem;justify-content:center;margin-right:0;width:3.5rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:1rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-radio--inline-block .yst-radio__label:hover{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity))}.yst-root .yst-radio--inline-block .yst-radio__label:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-radio--inline-block .yst-radio__check{height:1.25rem;position:absolute;left:.125rem;top:.125rem;visibility:hidden;width:1.25rem;--tw-text-opacity:1;color:rgb(154 22 96/var(--tw-text-opacity))}.yst-root .yst-radio__input{height:1rem;width:1rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-radio__input:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-radio__label{margin-right:.75rem}.yst-root .yst-select{position:relative}.yst-root .yst-select--disabled .yst-select__button,.yst-root .yst-select--disabled .yst-select__label{cursor:not-allowed;opacity:.5}.yst-root .yst-select__button{align-items:center;border-radius:.375rem;cursor:default;display:flex;justify-content:space-between;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));line-height:1.5rem;padding:.5rem .75rem;text-align:right;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-select__button,.yst-root .yst-select__button:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-select__button:focus{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-select__button-icon{height:1.25rem;pointer-events:none;position:absolute;left:.625rem;top:.625rem;width:1.25rem;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-select__options{border-radius:.375rem;margin-top:.25rem;max-height:15rem;overflow:auto;position:absolute;width:100%;z-index:10;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity));--tw-ring-opacity:0.05}.yst-root .yst-select__options:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-select__option{align-items:center;cursor:default;display:flex;justify-content:space-between;padding:.5rem .75rem;position:relative;-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.yst-root .yst-select__option--active{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-select__option--selected{--tw-bg-opacity:1;background-color:rgb(154 22 96/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-select__button-label,.yst-root .yst-select__option-label{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yst-root .yst-select__option-check{flex-shrink:0;height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-skeleton-loader{border-radius:.25rem;display:block;height:auto;overflow:hidden;position:relative;width:-moz-fit-content;width:fit-content;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-skeleton-loader:after{animation:wave 2.5s linear .5s infinite;background:linear-gradient(-90deg,#0000,#00000012,#0000);content:"";inset:0;position:absolute;--tw-translate-x:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes wave{0%{transform:translateX(100%)}50%,to{transform:translateX(-100%)}}.yst-root .yst-tag-input{align-items:center;border-radius:.375rem;display:flex;flex-wrap:wrap;gap:.375rem;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;line-height:1.5rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-tag-input::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}.yst-root .yst-tag-input{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-tag-input,.yst-root .yst-tag-input:focus-within{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-tag-input--disabled:focus-within{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__tag{cursor:not-allowed}.yst-root .yst-tag-input--disabled .yst-tag-input__tag:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__tag:focus,.yst-root .yst-tag-input--disabled .yst-tag-input__tag:focus-visible{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag{cursor:not-allowed}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__input{cursor:not-allowed}.yst-root .yst-tag-input__tag{cursor:pointer;gap:.125rem;min-height:20px;padding-inline-end:.125rem}.yst-root .yst-tag-input__tag:hover{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input__tag:focus,.yst-root .yst-tag-input__tag:focus-visible{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input__remove-tag{align-items:center;border-radius:9999px;display:inline-flex;flex-shrink:0;height:1rem;justify-content:center;width:1rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-tag-input__remove-tag:hover{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.yst-root .yst-tag-input__remove-tag:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input__input{border-style:none;display:inline-flex;flex:1 1 0%;font-size:.8125rem;margin:0;padding:0}.yst-root .yst-tag-input__input:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input{border-radius:.375rem;border-width:0;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-text-input,.yst-root .yst-text-input:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-text-input--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-text-input--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input--read-only{cursor:default;--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.yst-root .yst-text-input--read-only,.yst-root .yst-textarea{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-textarea{border-radius:.375rem;border-width:0;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-textarea,.yst-root .yst-textarea:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-textarea:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-textarea--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-textarea--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-title{font-weight:500;line-height:1.25;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.yst-root .yst-title--1{font-size:1.5rem}.yst-root .yst-title--2{font-size:1.125rem}.yst-root .yst-title--3{font-size:.875rem}.yst-root .yst-title--4{font-size:1rem}.yst-root .yst-title--5{font-size:.8125rem}.yst-root .yst-toggle{border-color:#0000;border-radius:9999px;border-width:2px;cursor:pointer;display:inline-flex;flex-shrink:0;height:1.5rem;position:relative;width:2.75rem;--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity));transition-duration:.2s;transition-property:color,background-color,border-color,fill,stroke,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-toggle:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-toggle--checked{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity))}.yst-root .yst-toggle--checked .yst-toggle__handle{--tw-translate-x:1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-toggle--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-toggle--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-toggle__handle{display:flex;height:1.25rem;pointer-events:none;position:relative;width:1.25rem;--tw-translate-x:0px;align-items:center;border-radius:9999px;justify-content:center;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);transition-duration:.2s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-toggle__icon{flex-grow:0;flex-shrink:0;height:.625rem;width:.625rem;stroke:currentColor;stroke-width:2;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));transition-duration:.1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-toggle__icon--check{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-toggle__icon--x{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}[dir=rtl] .yst-root .yst-toggle--checked .yst-toggle__handle{--tw-translate-x:-1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip{border-radius:.5rem;display:inline-block;max-width:24rem;position:absolute;white-space:normal;width:max-content;z-index:10;--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity));font-size:.75rem;padding:.5rem .625rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-tooltip--top{right:50%;margin-top:-.75rem;top:0;--tw-translate-x:-50%;--tw-translate-y:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top:before{position:absolute;--tw-translate-x:-50%;--tw-translate-y:0px;border-bottom-color:#0000;border-right-color:#0000;border-left-color:#0000;border-width:8px;--tw-border-opacity:1;border-top-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip--bottom,.yst-root .yst-tooltip--top:before{right:50%;top:100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--bottom{margin-top:.75rem;--tw-translate-x:-50%;--tw-translate-y:-0px}.yst-root .yst-tooltip--bottom:before{bottom:100%;right:50%;position:absolute;--tw-translate-x:-50%;border-right-color:#0000;border-left-color:#0000;border-top-color:#0000;border-width:8px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-bottom-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip--right{right:100%;margin-right:.75rem;--tw-translate-x:-0px}.yst-root .yst-tooltip--right,.yst-root .yst-tooltip--right:before{top:50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--right:before{border-bottom-color:#0000;border-right-color:#0000;border-top-color:#0000;border-width:8px;position:absolute;left:100%;--tw-border-opacity:1;border-left-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip--left{margin-left:.75rem;left:100%}.yst-root .yst-tooltip--left,.yst-root .yst-tooltip--left:before{top:50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--left:before{border-bottom-color:#0000;border-left-color:#0000;border-top-color:#0000;border-width:8px;right:100%;position:absolute;--tw-border-opacity:1;border-right-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-validation-icon{pointer-events:none}.yst-root .yst-validation-icon--success{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.yst-root .yst-validation-icon--info{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity))}.yst-root .yst-validation-icon--warning{--tw-text-opacity:1;color:rgb(245 158 11/var(--tw-text-opacity))}.yst-root .yst-validation-icon--error{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.yst-root .yst-validation-input{position:relative}.yst-root .yst-validation-input--success .yst-validation-input__input{padding-left:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(134 239 172/var(--tw-ring-opacity))}.yst-root .yst-validation-input--success .yst-validation-input__input:focus,.yst-root .yst-validation-input--success .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(34 197 94/var(--tw-ring-opacity))}.yst-root .yst-validation-input--info .yst-validation-input__input{padding-left:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(147 197 253/var(--tw-ring-opacity))}.yst-root .yst-validation-input--info .yst-validation-input__input:focus,.yst-root .yst-validation-input--info .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity))}.yst-root .yst-validation-input--warning .yst-validation-input__input{padding-left:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(252 211 77/var(--tw-ring-opacity))}.yst-root .yst-validation-input--warning .yst-validation-input__input:focus,.yst-root .yst-validation-input--warning .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(245 158 11/var(--tw-ring-opacity))}.yst-root .yst-validation-input--error .yst-validation-input__input{padding-left:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(252 165 165/var(--tw-ring-opacity))}.yst-root .yst-validation-input--error .yst-validation-input__input:focus,.yst-root .yst-validation-input--error .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity))}.yst-root .yst-validation-input__input:focus,.yst-root .yst-validation-input__input:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-validation-input__icon{height:1.25rem;position:absolute;left:.625rem;top:.6875rem;width:1.25rem}.yst-root .yst-validation-message a{color:inherit;font-weight:500}.yst-root .yst-validation-message a:visited:hover{color:inherit}.yst-root .yst-validation-message a:focus{--tw-ring-color:currentColor}.yst-root .yst-validation-message--success{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity))}.yst-root .yst-validation-message--info{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.yst-root .yst-validation-message--warning{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity))}.yst-root .yst-validation-message--error{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.yst-root .yst-autocomplete-field__description,.yst-root .yst-autocomplete-field__validation{margin-top:.5rem}.yst-root .yst-card{display:flex;flex-direction:column;position:relative}.yst-root .yst-card>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-card{border-radius:.5rem;border-width:1px;overflow:hidden;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1.5rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-card__header{align-items:center;display:flex;height:6rem;justify-content:center;margin-right:-1.5rem;margin-left:-1.5rem;margin-top:-1.5rem;position:relative;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity));padding:1.5rem}.yst-root .yst-card__content{flex-grow:1}.yst-root .yst-card__footer{border-top-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));padding-top:1.5rem}.yst-root .yst-checkbox-group--disabled .yst-checkbox-group__description,.yst-root .yst-checkbox-group--disabled .yst-checkbox-group__label{cursor:not-allowed;opacity:.5}.yst-root .yst-checkbox-group__label{margin-bottom:.5rem}.yst-root .yst-checkbox-group__options{display:flex;flex-direction:column;gap:.75rem}.yst-root .yst-checkbox-group__description{margin-bottom:1rem;margin-top:-.5rem}.yst-root .yst-feature-upsell{position:relative}.yst-root .yst-feature-upsell--default{--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.yst-root .yst-feature-upsell--card{padding:1.5rem}.yst-root .yst-file-import>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-file-import__feedback{border-radius:.375rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1rem;--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-file-import__feedback-header{align-items:flex-start;display:flex}.yst-root .yst-file-import__feedback-header>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-left:calc(1rem*var(--tw-space-x-reverse))}.yst-root .yst-file-import__feedback-figure{align-items:center;border-radius:9999px;display:flex;height:2rem;justify-content:center;width:2rem;--tw-bg-opacity:1;background-color:rgb(243 229 237/var(--tw-bg-opacity))}.yst-root .yst-file-import__feedback-figure>svg{height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-file-import__feedback-title{display:block;font-weight:500;margin-bottom:.125rem;overflow-wrap:break-word;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-file-import__feedback-description{display:block;font-size:.75rem;font-weight:500}.yst-root .yst-file-import__abort-button{align-items:center;border-radius:9999px;display:inline-flex;flex-shrink:0;height:1.25rem;justify-content:center;width:1.25rem;--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.yst-root .yst-file-import__abort-button:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.yst-root .yst-file-import__abort-button:focus{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));outline:2px solid #0000;outline-offset:2px}.yst-root .yst-file-import__abort-button>svg{height:.75rem;width:.75rem}.yst-root .yst-file-import__abort-button>svg>path{stroke-width:3}.yst-root .yst-modal{inset:0;padding:1rem;position:fixed;z-index:10}@media (min-width:640px){.yst-root .yst-modal{padding:2rem}}@media (min-width:768px){.yst-root .yst-modal{padding:5rem}}.yst-root .yst-modal__layout{display:flex;min-height:100%}.yst-root .yst-modal--center .yst-modal__layout{align-items:center;justify-content:center}.yst-root .yst-modal--top-center .yst-modal__layout{align-items:flex-start;justify-content:center}.yst-root .yst-modal__overlay{background-color:rgb(100 116 139/var(--tw-bg-opacity));inset:0;position:fixed;--tw-bg-opacity:0.75;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-modal__panel{border-radius:.5rem;max-width:48rem;overflow:hidden;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1.5rem;--tw-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-modal__close{display:block;position:absolute;left:1rem;top:1rem}.yst-root .yst-modal__close-button{border-radius:.375rem;position:relative;z-index:10;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-modal__close-button:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.yst-root .yst-modal__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-modal__container{display:flex;flex-direction:column;max-height:calc(100vh - 2rem)}@media (min-width:640px){.yst-root .yst-modal__container{max-height:calc(100vh - 4rem)}}@media (min-width:768px){.yst-root .yst-modal__container{max-height:calc(100vh - 10rem)}}.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 5rem)}@media (min-width:640px){.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 7rem)}}@media (min-width:768px){.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 13rem)}}.yst-root .yst-modal__container-footer,.yst-root .yst-modal__container-header{flex-shrink:0}.yst-root .yst-modal__container-content{overflow:auto}.yst-root .yst-modal__panel .yst-modal__container-content{margin-right:-1.5rem;margin-left:-1.5rem;padding-right:1.5rem;padding-left:1.5rem}.yst-root .yst-notifications{display:flex;flex-direction:column;max-height:calc(100vh - 4rem);max-width:calc(100vw - 4rem);pointer-events:none;position:fixed;width:100%;z-index:20}.yst-root .yst-notifications>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-notifications--bottom-center{align-items:center;bottom:2rem}.yst-root .yst-notifications--bottom-left{bottom:2rem;right:2rem}.yst-root .yst-notifications--top-center{align-items:center;top:2rem}.yst-root .yst-notification{border-radius:.5rem;max-width:100%;overflow-y:auto;pointer-events:auto;width:20rem;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity));--tw-ring-opacity:0.05}.yst-root .yst-notification--large{width:24rem}.yst-root .yst-notification__icon{height:1.25rem;width:1.25rem}.yst-root .yst-pagination{display:inline-flex;isolation:isolate}.yst-root .yst-pagination>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(-1px*(1 - var(--tw-space-x-reverse)));margin-left:calc(-1px*var(--tw-space-x-reverse))}.yst-root .yst-pagination{border-radius:.375rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-pagination-display__text{font-weight:400;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(226 232 240/var(--tw-ring-opacity))}.yst-root .yst-pagination-display__current-text{font-weight:600;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.yst-root .yst-pagination-display__truncated{align-self:center;font-size:.8125rem;font-weight:600;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(226 232 240/var(--tw-ring-opacity))}.yst-root .yst-pagination-display__truncated,.yst-root .yst-pagination__button{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);display:inline-flex}.yst-root .yst-pagination__button{align-items:center;padding:.5rem;position:relative;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-pagination__button:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.yst-root .yst-pagination__button:focus{outline-color:#a61e69;outline-offset:0;z-index:20}.yst-root .yst-pagination__button--active{z-index:10;--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));font-size:.8125rem;font-weight:600;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-pagination__button--active:hover{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity))}.yst-root .yst-pagination__button--active:focus{z-index:20}.yst-root .yst-pagination__button--active:focus-visible{border-radius:.125rem;outline-color:#a61e69;outline-offset:2px;outline-style:solid;outline-width:2px}.yst-root .yst-pagination__button--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-pagination__button--disabled:hover{background-color:initial}.yst-root .yst-pagination__button--disabled:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-radio-group--inline-block .yst-radio-group__options{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}.yst-root .yst-radio-group--disabled .yst-radio-group__description,.yst-root .yst-radio-group--disabled .yst-radio-group__label{opacity:.5}.yst-root .yst-radio-group--disabled .yst-radio-group__label{cursor:not-allowed}.yst-root .yst-radio-group__label{margin-bottom:.5rem}.yst-root .yst-radio-group__options{display:flex;flex-direction:column;gap:.5rem}.yst-root .yst-radio-group__description{margin-bottom:1rem;margin-top:-.5rem}.yst-root .yst-select-field--disabled .yst-select-field__description,.yst-root .yst-select-field--disabled .yst-select-field__label{cursor:not-allowed;opacity:.5}.yst-root .yst-select-field__options{display:flex;flex-direction:column;gap:.75rem}.yst-root .yst-select-field__description,.yst-root .yst-select-field__validation{margin-top:.5rem}.yst-root .yst-mobile-navigation__top{position:sticky;top:0;width:100%;z-index:50}.yst-root .yst-mobile-navigation__dialog{display:flex;inset:0;position:fixed;z-index:50}.yst-root .yst-tag-field--disabled .yst-tag-field__description,.yst-root .yst-tag-field--disabled .yst-tag-field__label{cursor:not-allowed;opacity:.5}.yst-root .yst-tag-field__description,.yst-root .yst-tag-field__validation{margin-top:.5rem}.yst-root .yst-text-field--disabled .yst-text-field__description,.yst-root .yst-text-field--disabled .yst-text-field__label{opacity:.5}.yst-root .yst-text-field--disabled .yst-text-field__label{cursor:not-allowed}.yst-root .yst-text-field--read-only .yst-text-field__label{cursor:default}.yst-root .yst-text-field__description,.yst-root .yst-text-field__validation{margin-top:.5rem}.yst-root .yst-textarea-field--disabled .yst-textarea-field__description,.yst-root .yst-textarea-field--disabled .yst-textarea-field__label{opacity:.5}.yst-root .yst-textarea-field--disabled .yst-textarea-field__label{cursor:not-allowed}.yst-root .yst-text-field--read-only .yst-textarea-field__label{cursor:default}.yst-root .yst-textarea-field__description,.yst-root .yst-textarea-field__validation{margin-top:.5rem}.yst-root .yst-toggle-field{display:flex;flex-direction:column;gap:.25rem}.yst-root .yst-toggle-field--disabled .yst-toggle-field__description,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label-wrapper{opacity:.5}.yst-root .yst-toggle-field--disabled .yst-toggle-field__description,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label-wrapper{cursor:not-allowed}.yst-root .yst-toggle-field__header{align-items:center;display:flex;flex-direction:row;gap:1.5rem;justify-content:space-between}.yst-root .yst-toggle-field__label-wrapper{align-items:center;display:flex;gap:.25rem}.yst-root .yst-toggle-field__description{margin-left:4.25rem}.yst-sr-only{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;border-width:0!important;white-space:nowrap!important}.yst-pointer-events-none{pointer-events:none!important}.yst-invisible{visibility:hidden!important}.yst-fixed{position:fixed!important}.yst-absolute{position:absolute!important}.yst-relative{position:relative!important}.yst-inset-0{inset:0!important}.yst-right-0{left:0!important}.yst-top-0{top:0!important}.yst-z-10{z-index:10!important}.yst-z-30{z-index:30!important}.yst-z-40{z-index:40!important}.yst-m-0{margin:0!important}.yst-mx-auto{margin-right:auto!important;margin-left:auto!important}.yst--ml-1{margin-right:-.25rem!important}.yst--mr-14{margin-left:-3.5rem!important}.yst-mb-2{margin-bottom:.5rem!important}.yst-mb-px{margin-bottom:1px!important}.yst-ml-4{margin-right:1rem!important}.yst-ml-8{margin-right:2rem!important}.yst-mr-2{margin-left:.5rem!important}.yst-mr-4{margin-left:1rem!important}.yst-mt-1{margin-top:.25rem!important}.yst-mt-1\.5{margin-top:.375rem!important}.yst-mt-2{margin-top:.5rem!important}.yst-mt-3{margin-top:.75rem!important}.yst-mt-6{margin-top:1.5rem!important}.yst-block{display:block!important}.yst-flex{display:flex!important}.yst-inline-flex{display:inline-flex!important}.yst-hidden{display:none!important}.yst-h-0{height:0!important}.yst-h-12{height:3rem!important}.yst-h-16{height:4rem!important}.yst-h-3{height:.75rem!important}.yst-h-4{height:1rem!important}.yst-h-5{height:1.25rem!important}.yst-h-6{height:1.5rem!important}.yst-h-7{height:1.75rem!important}.yst-h-8{height:2rem!important}.yst-h-full{height:100%!important}.yst-w-0{width:0!important}.yst-w-12{width:3rem!important}.yst-w-2{width:.5rem!important}.yst-w-3{width:.75rem!important}.yst-w-4{width:1rem!important}.yst-w-5{width:1.25rem!important}.yst-w-6{width:1.5rem!important}.yst-w-8{width:2rem!important}.yst-w-full{width:100%!important}.yst-min-w-full{min-width:100%!important}.yst-max-w-none{max-width:none!important}.yst-max-w-xs{max-width:20rem!important}.yst-flex-1{flex:1 1 0%!important}.yst-flex-shrink-0,.yst-shrink-0{flex-shrink:0!important}.yst--translate-y-full{--tw-translate-y:-100%!important}.yst--translate-y-full,.yst-translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-translate-y-0{--tw-translate-y:0px!important}.yst-translate-y-4{--tw-translate-y:1rem!important}.yst-translate-y-4,.yst-translate-y-full{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-translate-y-full{--tw-translate-y:100%!important}.yst-scale-100{--tw-scale-x:1!important;--tw-scale-y:1!important}.yst-scale-100,.yst-scale-95{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-scale-95{--tw-scale-x:.95!important;--tw-scale-y:.95!important}.yst-transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}@keyframes yst-spin{to{transform:rotate(-1turn)}}.yst-animate-spin{animation:yst-spin 1s linear infinite!important}.yst-cursor-wait{cursor:wait!important}.yst-list-disc{list-style-type:disc!important}.yst-flex-col{flex-direction:column!important}.yst-flex-wrap{flex-wrap:wrap!important}.yst-items-start{align-items:flex-start!important}.yst-items-center{align-items:center!important}.yst-justify-center{justify-content:center!important}.yst-justify-between{justify-content:space-between!important}.yst-gap-2{gap:.5rem!important}.yst-gap-3{gap:.75rem!important}.yst-space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(.25rem*var(--tw-space-y-reverse))!important;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))!important}.yst-space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(2rem*var(--tw-space-y-reverse))!important;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))!important}.yst-divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0!important;border-bottom-width:calc(1px*var(--tw-divide-y-reverse))!important;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))!important}.yst-divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1!important;border-color:rgb(229 231 235/var(--tw-divide-opacity))!important}.yst-divide-slate-300>:not([hidden])~:not([hidden]){--tw-divide-opacity:1!important;border-color:rgb(203 213 225/var(--tw-divide-opacity))!important}.yst-overflow-hidden{overflow:hidden!important}.yst-overflow-y-auto{overflow-y:auto!important}.yst-rounded-full{border-radius:9999px!important}.yst-rounded-lg{border-radius:.5rem!important}.yst-rounded-md{border-radius:.375rem!important}.yst-rounded-l-md{border-bottom-right-radius:.375rem!important;border-top-right-radius:.375rem!important}.yst-rounded-r-md{border-bottom-left-radius:.375rem!important;border-top-left-radius:.375rem!important}.yst-border-b{border-bottom-width:1px!important}.yst-border-r{border-left-width:1px!important}.yst-border-slate-200{--tw-border-opacity:1!important;border-color:rgb(226 232 240/var(--tw-border-opacity))!important}.yst-border-r-slate-200{--tw-border-opacity:1!important;border-left-color:rgb(226 232 240/var(--tw-border-opacity))!important}.yst-bg-red-100{--tw-bg-opacity:1!important;background-color:rgb(254 226 226/var(--tw-bg-opacity))!important}.yst-bg-slate-100{--tw-bg-opacity:1!important;background-color:rgb(241 245 249/var(--tw-bg-opacity))!important}.yst-bg-slate-200{--tw-bg-opacity:1!important;background-color:rgb(226 232 240/var(--tw-bg-opacity))!important}.yst-bg-slate-50{--tw-bg-opacity:1!important;background-color:rgb(248 250 252/var(--tw-bg-opacity))!important}.yst-bg-slate-600{--tw-bg-opacity:1!important;background-color:rgb(71 85 105/var(--tw-bg-opacity))!important}.yst-bg-white{--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity))!important}.yst-bg-opacity-75{--tw-bg-opacity:0.75!important}.yst-stroke-3{stroke-width:3px!important}.yst-p-1{padding:.25rem!important}.yst-px-2{padding-right:.5rem!important;padding-left:.5rem!important}.yst-px-3{padding-right:.75rem!important;padding-left:.75rem!important}.yst-px-4{padding-right:1rem!important;padding-left:1rem!important}.yst-py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.yst-py-4{padding-bottom:1rem!important;padding-top:1rem!important}.yst-py-6{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.yst-pb-1{padding-bottom:.25rem!important}.yst-pb-4{padding-bottom:1rem!important}.yst-pt-1{padding-top:.25rem!important}.yst-text-left{text-align:right!important}.yst-text-center{text-align:center!important}.yst-text-sm{font-size:.8125rem!important}.yst-font-medium{font-weight:500!important}.yst-font-normal{font-weight:400!important}.yst-font-semibold{font-weight:600!important}.yst-leading-4{line-height:1rem!important}.yst-text-gray-500{--tw-text-opacity:1!important;color:rgb(107 114 128/var(--tw-text-opacity))!important}.yst-text-primary-500{--tw-text-opacity:1!important;color:rgb(166 30 105/var(--tw-text-opacity))!important}.yst-text-red-600{--tw-text-opacity:1!important;color:rgb(220 38 38/var(--tw-text-opacity))!important}.yst-text-slate-400{--tw-text-opacity:1!important;color:rgb(148 163 184/var(--tw-text-opacity))!important}.yst-text-slate-500{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity))!important}.yst-text-slate-600{--tw-text-opacity:1!important;color:rgb(71 85 105/var(--tw-text-opacity))!important}.yst-text-slate-800{--tw-text-opacity:1!important;color:rgb(30 41 59/var(--tw-text-opacity))!important}.yst-text-slate-900{--tw-text-opacity:1!important;color:rgb(15 23 42/var(--tw-text-opacity))!important}.yst-text-white{--tw-text-opacity:1!important;color:rgb(255 255 255/var(--tw-text-opacity))!important}.yst-no-underline{-webkit-text-decoration-line:none!important;text-decoration-line:none!important}.yst-opacity-0{opacity:0!important}.yst-opacity-100{opacity:1!important}.yst-opacity-25{opacity:.25!important}.yst-opacity-75{opacity:.75!important}.yst-shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a!important;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)!important}.yst-shadow,.yst-shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.yst-shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a!important;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)!important}.yst-shadow-amber-700\/30{--tw-shadow-color:#b453094d!important;--tw-shadow:var(--tw-shadow-colored)!important}.yst-ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.yst-ring-black{--tw-ring-opacity:1!important;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))!important}.yst-ring-opacity-5{--tw-ring-opacity:0.05!important}.yst-grayscale{--tw-grayscale:grayscale(100%)!important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.yst-transition{transition-duration:.15s!important;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-transition-opacity{transition-duration:.15s!important;transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-delay-200{transition-delay:.2s!important}.yst-duration-100{transition-duration:.1s!important}.yst-duration-1000{transition-duration:1s!important}.yst-duration-150{transition-duration:.15s!important}.yst-duration-200{transition-duration:.2s!important}.yst-duration-300{transition-duration:.3s!important}.yst-duration-75{transition-duration:75ms!important}.yst-ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)!important}.yst-ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)!important}.odd\:yst-bg-white:nth-child(odd){--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity))!important}.even\:yst-bg-slate-50:nth-child(2n),.hover\:yst-bg-slate-50:hover{--tw-bg-opacity:1!important;background-color:rgb(248 250 252/var(--tw-bg-opacity))!important}.hover\:yst-text-slate-500:hover{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity))!important}.hover\:yst-text-slate-900:hover{--tw-text-opacity:1!important;color:rgb(15 23 42/var(--tw-text-opacity))!important}.focus\:yst-outline-none:focus{outline:2px solid #0000!important;outline-offset:2px!important}.focus\:yst-ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important}.focus\:yst-ring-1:focus,.focus\:yst-ring-2:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.focus\:yst-ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important}.focus\:yst-ring-inset:focus{--tw-ring-inset:inset!important}.focus\:yst-ring-primary-500:focus{--tw-ring-opacity:1!important;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))!important}.focus\:yst-ring-offset-1:focus{--tw-ring-offset-width:1px!important}.focus\:yst-ring-offset-2:focus{--tw-ring-offset-width:2px!important}.focus\:yst-ring-offset-transparent:focus{--tw-ring-offset-color:#0000!important}.yst-group:hover .group-hover\:yst-text-slate-500{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity))!important}@media (min-width:640px){.sm\:yst-mx-0{margin-right:0!important;margin-left:0!important}.sm\:yst-ml-4{margin-right:1rem!important}.sm\:yst-mt-0{margin-top:0!important}.sm\:yst-flex{display:flex!important}.sm\:yst-h-10{height:2.5rem!important}.sm\:yst-w-10{width:2.5rem!important}.sm\:yst-translate-y-0{--tw-translate-y:0px!important}.sm\:yst-scale-100,.sm\:yst-translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.sm\:yst-scale-100{--tw-scale-x:1!important;--tw-scale-y:1!important}.sm\:yst-scale-95{--tw-scale-x:.95!important;--tw-scale-y:.95!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}}.rtl\:yst-rotate-180:where([dir=rtl],[dir=rtl] *){--tw-rotate:180deg!important;tw-rotate:180deg!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.sm\:yst-flex-row-reverse{flex-direction:row-reverse!important}.sm\:yst-items-start{align-items:flex-start!important}.sm\:yst-text-left{text-align:right!important}.yst-root :-moz-focusring{outline:auto}.yst-root :-moz-ui-invalid{box-shadow:none}.yst-root input::-moz-placeholder,.yst-root textarea::-moz-placeholder{color:#6b7280;opacity:1}.yst-root [type=date]::-moz-placeholder,.yst-root [type=datetime-local]::-moz-placeholder,.yst-root [type=email]::-moz-placeholder,.yst-root [type=month]::-moz-placeholder,.yst-root [type=number]::-moz-placeholder,.yst-root [type=password]::-moz-placeholder,.yst-root [type=search]::-moz-placeholder,.yst-root [type=tel]::-moz-placeholder,.yst-root [type=text]::-moz-placeholder,.yst-root [type=time]::-moz-placeholder,.yst-root [type=url]::-moz-placeholder,.yst-root [type=week]::-moz-placeholder{color:#6b7280;opacity:1}.yst-root textarea::-moz-placeholder{color:#6b7280;opacity:1}.yst-root [type=date]::-moz-placeholder,.yst-root [type=datetime-local]::-moz-placeholder,.yst-root [type=email]::-moz-placeholder,.yst-root [type=month]::-moz-placeholder,.yst-root [type=number]::-moz-placeholder,.yst-root [type=password]::-moz-placeholder,.yst-root [type=search]::-moz-placeholder,.yst-root [type=tel]::-moz-placeholder,.yst-root [type=text]::-moz-placeholder,.yst-root [type=time]::-moz-placeholder,.yst-root [type=url]::-moz-placeholder,.yst-root [type=week]::-moz-placeholder,.yst-root textarea::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}.yst-root .yst-autocomplete--error .yst-autocomplete__input::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(252 165 165/var(--tw-placeholder-opacity))}.yst-root .yst-tag-input::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}[class=yst-root] .styles-module__paginationTitleSkeleton--ePjfS{height:13px;width:131px}[class=yst-root] div.styles-module__modal--quowq{z-index:1050}.styles-module__generatorContainer--jWKDs{border-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));width:696px}.styles-module__logo--gDbXB{background-color:var(--yoast-color-primary);display:inline-block;height:1.25rem;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:1.25rem}.styles-module__modalTitle--LTCoD{align-items:center;display:flex;font-size:18px;font-weight:500;letter-spacing:.5px;line-height:27px;margin:24px}.styles-module__modalTitle--LTCoD>*{margin-left:8px}[class=yst-root] div.styles-module__modalContainer--DyT0w{max-width:696px;overflow:visible;padding:0!important;position:sticky;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}[class=yst-root] div.styles-module__modalContainer--DyT0w div.styles-module__modalContent--uxbqo{margin:0;padding-right:0;padding-left:0;position:relative}[class=yst-root] div.styles-module__modalContainer--DyT0w div.styles-module__modalContent--uxbqo .styles-module__fadeOut--O2ZCu:before{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));content:"";display:block;height:24px;margin-top:-24px;mask-image:linear-gradient(180deg,#0000,#000);position:sticky;top:calc(100% - 24px);width:100%}[class=yst-root] div.styles-module__modalContainer--DyT0w h1{--tw-border-opacity:1;border-bottom-width:1px;border-color:rgb(229 231 235/var(--tw-border-opacity))}.styles-module__floatingCounter--KzR9L{position:absolute;left:48px;top:-10px}.styles-module__learnMore--mrUIw{margin-right:-4px}.styles-module__learnMore--mrUIw svg{height:1rem;width:1rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}[class=yst-root] .styles-module__buttonArea--I6ND0{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:0 0 .5rem .5rem;border-width:1px 0 0;display:flex;justify-content:flex-end;padding:24px;width:100%}[class=yst-root] .styles-module__buttonArea--I6ND0>button{margin-right:.75rem}[class=yst-root] .styles-module__buttonArea--I6ND0>button svg{height:16px;margin-left:8px;width:16px}.styles-module__aiGenerator--Q4G7H{width:100%}.styles-module__aiGenerator--Q4G7H .styles-module__errorBanner--Aynek{margin:0 24px 16px;padding:0}.styles-module__aiGenerator--Q4G7H .styles-module__errorBanner--Aynek.styles-module__fullError--eTOfR{margin:16px}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='768' height='174' fill='none'%3E%3Cg clip-path='url(%23a)'%3E%3Cpath fill='%23fff' d='M0 0h768v174H0z'/%3E%3Cg filter='url(%23b)' opacity='.15'%3E%3Cellipse cx='384' cy='87' fill='url(%23c)' rx='304' ry='43'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3ClinearGradient id='c' x1='80' x2='453.361' y1='44' y2='386.089' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23A61E69'/%3E%3Cstop offset='1' stop-color='%236366F1'/%3E%3C/linearGradient%3E%3CclipPath id='a'%3E%3Cpath fill='%23fff' d='M0 0h768v174H0z'/%3E%3C/clipPath%3E%3Cfilter id='b' width='736' height='214' x='16' y='-20' color-interpolation-filters='sRGB' filterUnits='userSpaceOnUse'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeBlend in='SourceGraphic' in2='BackgroundImageFix' result='shape'/%3E%3CfeGaussianBlur result='effect1_foregroundBlur_862_1019' stdDeviation='32'/%3E%3C/filter%3E%3C/defs%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:auto;display:flex;justify-items:center;max-width:100%}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h.styles-module__social--I2bZ1{margin-bottom:1em}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q{background:#0000;margin:8px auto;max-width:100%;padding:0}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl{margin:0 24px;width:calc(100% - 48px)}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:last-child{margin:.5rem 0 0}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:last-child>div{align-items:center;display:flex;justify-content:center}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:first-child{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:8px;box-shadow:0 1px 6px #20212447;margin:inherit;padding:1rem}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:first-child>div{align-items:inherit;display:inherit;justify-content:inherit}.styles-module__social--I2bZ1 .styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q{width:100%}.styles-module__social--I2bZ1 .styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q>div{margin:1em auto}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q>section>div{background:#fff}.styles-module__aiGenerator--Q4G7H .styles-module__titleProgress--BlLuI{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity));padding:16px 24px}.styles-module__aiGenerator--Q4G7H .styles-module__mainTitle--hcBkm{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity));display:flex;justify-content:space-between;padding:24px 24px 16px}.styles-module__aiGenerator--Q4G7H .styles-module__mainTitle--hcBkm .styles-module__mainTitleSkeleton--CSk1Z{height:13px;width:98px}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy{margin:.5em 0}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__good--Ueni9>div{background-color:#7ad03a}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__good--Ueni9.styles-module__altColors--o1t8E>div{background-color:#4ade80}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__ok--RvqJ4>div{background-color:#ee7c1b}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__bad--_XMc7>div{background-color:#dc3232}.styles-module__skeletonPreview--QYdU8{background:#fff;border-radius:.5rem;margin:auto;padding:16px;width:400px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T{display:flex;margin-bottom:21px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__firstColumn--dorvx>span{border-radius:28px;height:28px;margin-left:12px;width:28px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__secondColumn--m5oLy>span{border-radius:4px;height:13px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__secondColumn--m5oLy>span:first-child{margin-bottom:3px;width:123px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__secondColumn--m5oLy>span:nth-child(2){width:276px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span{border-radius:4px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span:first-child{height:20px;margin-bottom:16px;width:368px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span:nth-child(2){height:13px;margin-bottom:8px;width:368px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span:nth-child(3){height:13px;width:221px}.styles-module__mockedSelector--_0Gy5{display:flex;items-align:center}.styles-module__mockedSelector--_0Gy5 .styles-module__emptyCircle--nibrZ{border-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:16px;height:16px;margin-left:8px;width:16px}.styles-module__mockedSelector--_0Gy5>span:nth-child(2){height:13px;margin-left:16px;width:82px}.styles-module__mockedSelector--_0Gy5>span:nth-child(4){height:13px;width:92px}form.styles-module__suggestionList--CVXuA{min-width:320px;width:100%}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;padding:1rem .75rem;--tw-text-opacity:1;align-items:center;border-width:0 1px 1px;color:rgb(71 85 105/var(--tw-text-opacity));display:flex}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB:first-of-type{border-top-right-radius:.5rem;border-top-left-radius:.5rem;border-top-width:1px}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB:last-of-type{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem;--tw-divide-y-reverse:1px}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB.styles-module__selectedOption--hcd4O{--tw-border-opacity:1;border-color:rgb(143 15 87/var(--tw-border-opacity));--tw-text-opacity:1;border-top-width:1px;color:rgb(15 23 42/var(--tw-text-opacity));margin-top:-1px}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB.styles-module__selectedOption--hcd4O:first-of-type{margin-top:0}form.styles-module__suggestionList--CVXuA .styles-module__innerOption--jmXHJ{align-items:center;display:flex}form.styles-module__suggestionList--CVXuA .styles-module__optionLabel--kZshU{flex:1 1 auto}form.styles-module__suggestionList--CVXuA .styles-module__loadingMock--Mr6WN{align-items:center;display:flex;height:1.5em;justify-content:space-between;width:100%}form.styles-module__suggestionList--CVXuA .styles-module__loadingMock--Mr6WN .styles-module__labelMock--NITYK{flex:1 0 auto;height:.75rem;margin-right:16px}form.styles-module__suggestionList--CVXuA .styles-module__pagination--FYqPO{display:flex;justify-content:flex-end;margin-top:1em;width:100%}:root{--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E")}.styles-module__gradientBorder--FrZBT,.styles-module__gradientBorderButton--gGjJv>button,[class=yst-root] span.styles-module__gradientBorder--FrZBT{position:absolute;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-gradient-from:#faf3f7 var(--tw-gradient-from-position);--tw-gradient-to:#faf3f700 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to);--tw-gradient-to:#eef2ff var(--tw-gradient-to-position);--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);border-image:linear-gradient(to bottom right,#cd82ab,#a5b4fc) 1;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);display:flex;justify-content:flex-start;position:relative;z-index:0;text-wrap:wrap;flex-direction:row;overflow:hidden}.styles-module__gradientBorder--FrZBT>svg,.styles-module__gradientBorderButton--gGjJv>button>svg,[class=yst-root] span.styles-module__gradientBorder--FrZBT>svg{margin-left:8px}.styles-module__gradientBorder--FrZBT:before,.styles-module__gradientBorderButton--gGjJv>button:before,[class=yst-root] span.styles-module__gradientBorder--FrZBT:before{background:linear-gradient(to bottom left,#cd82ab,#a5b4fc);border-radius:inherit;bottom:0;content:"";right:0;mask:linear-gradient(#fff,#fff) content-box,linear-gradient(#fff,#fff) border-box;mask-composite:exclude;padding:1px;position:absolute;left:0;top:0;z-index:-1}[class=yst-root] .styles-module__notificationWithToast--IBfwe>div{background-image:linear-gradient(to bottom left,var(--tw-gradient-stops));border-radius:.5rem;display:inline-block;max-width:24rem}[class=yst-root] .styles-module__notificationWithToast--IBfwe>span{inset-inline-start:265px;position:absolute;top:.25rem;z-index:10}[class=yst-root] .styles-module__notificationWithToast--IBfwe>div>div{overflow-y:visible;padding:1rem}[class=yst-root] .styles-module__notificationWithToast--IBfwe>div>div:first-child{padding-bottom:0}.styles-module__header--mjkFl{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;align-items:baseline;color:rgb(15 23 42/var(--tw-text-opacity));display:flex;justify-content:space-between;padding:0 24px}.styles-module__header--mjkFl button svg{margin-left:8px}.styles-module__suggestions--sUYxk{font-size:.8125rem;padding:8px 24px 40px}.styles-module__suggestions--sUYxk .styles-module__suggestionsNote--P23gI{font-size:.75rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-size:11px;margin-top:.5rem}#radio-group-typeSelector>div{flex-direction:row;gap:1.5rem}[class=yst-root] span.styles-module__badge--rMVjT{height:18px;position:absolute;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-gradient-from:#faf3f7 var(--tw-gradient-from-position);--tw-gradient-to:#faf3f700 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to);--tw-gradient-to:#eef2ff var(--tw-gradient-to-position);--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);border-image:linear-gradient(to bottom right,#cd82ab,#a5b4fc) 1;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);position:relative;z-index:0}[class=yst-root] span.styles-module__badge--rMVjT:before{background:linear-gradient(to bottom left,#cd82ab,#a5b4fc);border-radius:inherit;bottom:0;content:"";right:0;mask:linear-gradient(#fff,#fff) content-box,linear-gradient(#fff,#fff) border-box;mask-composite:exclude;padding:1px;position:absolute;left:0;top:0;z-index:-1}.styles-module__icon--y4uAf{margin-left:.25rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));width:11px;fill:linear-gradient(90deg,#3f87a6,#ebf8e1,#f69d3c)}.styles-module__data--C2k4_{font-weight:600;margin-left:.25rem;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>div{background-image:linear-gradient(to bottom left,var(--tw-gradient-stops));border-radius:.5rem;display:inline-block;max-width:24rem}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>span{inset-inline-start:265px;position:absolute;top:.25rem;z-index:10}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>div>div{overflow-y:visible;padding:1rem}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>div>div:first-child{padding-bottom:0}[class=yst-root] .styles-module__buttonGroup--BqLdI{display:flex;flex-direction:row-reverse;gap:.25rem;margin-left:-2.25rem;margin-top:.75rem}[class=yst-root] .styles-module__logo--JhJ6O{background-color:var(--yoast-color-primary);display:inline-block;height:1rem;margin-top:.125rem;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:1rem}[class=yst-root] div.styles-module__skeletonWrapperTop--TovVH{display:flex;gap:.25rem;justify-content:space-between}[class=yst-root] span.styles-module__skeleton--u4mld{height:18px;width:18px}[class=yst-root] div.styles-module__skeletonLoaderWrapper--HI7Rm{flex-grow:1}[class=yst-root] span.styles-module__skeletonLoader1--acDyN{height:1rem;width:100%}[class=yst-root] span.styles-module__skeletonLoader2--f4AbH{height:1rem;margin-top:.25rem;width:100%}[class=yst-root] span.styles-module__skeletonLoader3--pI6W5{height:1rem;margin-top:.125rem;width:100%}[class=yst-root] span.styles-module__skeletonLoader4--l4uCY{height:1rem;margin-top:.125rem;width:8rem}[class=yst-root] div.styles-module__skeletonWrapperBottom--HMog6{align-items:center;display:flex;gap:.25rem;justify-content:flex-end;margin-right:-.75rem;margin-top:1rem}[class=yst-root] span.styles-module__skeletonLoaderButtons--HkdNq{height:1.75rem;width:4rem}[class=yst-root] .styles-module__toastContentWrapper--e321x{display:flex;justify-content:flex-end}[class=yst-root] .styles-module__toastContentWrapper--e321x div:last-child{display:inline-block!important}[class=yst-root] .styles-module__toastContentContainer--UNMow{margin-right:.75rem;margin-left:1rem}[class=yst-root] .styles-module__toastContentContainerHeader--L5Dw3{align-items:center;display:flex;gap:.5rem;margin-bottom:.25rem}[class=yst-root] .styles-module__toastContentLink--cZjl1{align-items:center;display:inline-flex;font-size:.75rem;font-weight:500;gap:.25rem;margin-top:.5rem}[class=yst-root] .styles-module__toastContentArrow--xnqYS{height:1rem;width:1rem}[class=yst-root] .styles-module__toastContentArrow--xnqYS:where([dir=rtl],[dir=rtl] *){--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}[class=yst-root] .styles-module__toastContentButtonsWrapper--YHI5c{display:flex;gap:.75rem;justify-content:flex-end;margin-right:-.75rem;margin-top:.5rem}[class=yst-root] .styles-module__toastContentApplyButton--SlRYX{padding-right:.5rem;padding-left:.5rem}[class=yst-root] .styles-module__toastContentApplyButton--SlRYX .styles-module__buttonIcon--v49u_{height:1rem;width:1rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}[class=yst-root] .styles-module__toastContentApplyButton--SlRYX .styles-module__buttonText--ec2s0{margin-right:.25rem;margin-left:.25rem}[class=yst-root] div.styles-module__modal--CWdoh{z-index:1050}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43{border-radius:1.5rem;display:inline-block;max-width:512px;overflow:hidden;padding:0;position:relative;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));text-align:right;vertical-align:bottom;--tw-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}@media (min-width:640px){[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43{margin:2rem 1rem;vertical-align:middle}}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43 [class=yst-modal__close] button{background-color:initial}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43 [class=yst-modal__close] button svg{height:1.5rem;width:1.5rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__bigModal--xut4N{max-width:48rem}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__bigModal--xut4N .styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt .styles-module__main--KD5ki{margin-top:2rem}.styles-module__badge--anxyN{position:absolute;left:16px;top:-12px}.styles-module__consentModal--A_0w0,.styles-module__introModal--rMyze{align-items:center;display:flex;flex-direction:column;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));max-width:512px;padding:2.5rem 2.5rem 1rem}.styles-module__consentModal--A_0w0 .styles-module__top--Jckd_,.styles-module__introModal--rMyze .styles-module__top--Jckd_{height:340px;inset:0;position:absolute;--tw-bg-opacity:0.25;background-image:linear-gradient(to bottom,var(--tw-gradient-stops));--tw-gradient-from:#a61e6940 var(--tw-gradient-from-position);--tw-gradient-to:#a61e6900 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to);--tw-gradient-to:#ffffff40 var(--tw-gradient-to-position)}.styles-module__consentModal--A_0w0 .styles-module__content--s8aPG,.styles-module__introModal--rMyze .styles-module__content--s8aPG{align-items:center;display:flex;flex-direction:column;justify-content:center;position:relative;text-align:center}.styles-module__consentModal--A_0w0 .styles-module__image--EZwCo,.styles-module__introModal--rMyze .styles-module__image--EZwCo{aspect-ratio:16/9;border-radius:.5rem;overflow:hidden;width:100%;--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.styles-module__consentModal--A_0w0 .styles-module__title--upMch,.styles-module__introModal--rMyze .styles-module__title--upMch{font-size:1.125rem;font-weight:500;margin-top:1.5rem;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.styles-module__consentModal--A_0w0 .styles-module__checkbox--BNgin,.styles-module__introModal--rMyze .styles-module__checkbox--BNgin{align-items:flex-start;border-top-width:1px;font-size:.75rem;margin-top:1.25rem;padding-top:1rem;text-align:right;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.styles-module__consentModal--A_0w0 .styles-module__checkbox--BNgin label,.styles-module__introModal--rMyze .styles-module__checkbox--BNgin label{font-size:.75rem;font-weight:400;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.styles-module__consentModal--A_0w0 .styles-module__buttons--Synlt,.styles-module__introModal--rMyze .styles-module__buttons--Synlt{display:flex;flex-direction:column;gap:.75rem;margin-top:1.5rem;width:100%}.styles-module__consentModal--A_0w0 .styles-module__learnMoreLink--ZdsMp,.styles-module__introModal--rMyze .styles-module__learnMoreLink--ZdsMp{font-weight:500;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity));-webkit-text-decoration-line:none;text-decoration-line:none}.styles-module__introModal--rMyze{max-width:48rem;padding:2.5rem}.styles-module__introModal--rMyze .styles-module__separator--uFWrD{margin-top:1.5rem;width:100%;--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__mainVideo--jjRHv{overflow:visible;position:relative;width:100%}.styles-module__introModal--rMyze .styles-module__mainVideo--jjRHv .styles-module__video--QfVLI{aspect-ratio:16/9;border-radius:.5rem;overflow:hidden;width:100%;--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.styles-module__introModal--rMyze .styles-module__mainVideo--jjRHv .styles-module__video--QfVLI>*{max-width:100%}.styles-module__introModal--rMyze .styles-module__learnMoreLink--ZdsMp{align-items:center;display:inline-flex;font-weight:500;gap:.25rem;-webkit-text-decoration-line:none;text-decoration-line:none}.styles-module__introModal--rMyze .styles-module__titleSection--uRoF8{align-items:center;display:flex;font-size:.75rem;font-weight:500;margin-top:1.5rem;max-width:600px}.styles-module__introModal--rMyze .styles-module__titleSection--uRoF8 .styles-module__byline--eXZ9f{text-transform:uppercase;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity));letter-spacing:.8px;margin-right:8px}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV{margin-right:.375rem;margin-left:.375rem;margin-top:1rem;max-width:600px;text-align:center}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentHeader--b2brO{font-size:1.125rem;font-weight:500;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentText--dnFSm{font-size:.8125rem;margin-top:.5rem;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentText--dnFSm .styles-module__contentIcon--aE3SN{height:1rem;width:1rem}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentText--dnFSm .styles-module__contentIcon--aE3SN:where([dir=rtl],[dir=rtl] *){--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.styles-module__introModal--rMyze .styles-module__interactionSection--htDGA{align-items:flex-start;display:flex;margin-top:1rem}.styles-module__introModal--rMyze .styles-module__interactionSection--htDGA .styles-module__consentCheck--adf26:before{--tw-content:none;content:var(--tw-content)}.styles-module__introModal--rMyze .styles-module__interactionSection--htDGA .styles-module__consentLabel--JOn4k{font-size:.8125rem;font-weight:400;margin-right:.75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt{display:flex;margin-top:1rem;width:100%}.styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt .styles-module__main--KD5ki{flex-grow:1}.styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt .styles-module__close--nBst_{margin-top:1rem}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd{align-items:flex-start;display:flex}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd{align-items:flex-start;display:flex}}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__warningIconContainer--NcQlL{align-items:center;border-radius:9999px;display:flex;flex-shrink:0;height:3rem;justify-content:center;margin-right:auto;margin-left:auto;width:3rem;--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__warningIconContainer--NcQlL{height:2.5rem;margin-right:0;margin-left:0;width:2.5rem}}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__icon--ap2v5{height:1.5rem;width:1.5rem;--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__prompt--KATqc{margin-top:.75rem;text-align:center}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__prompt--KATqc{margin-right:1rem;margin-top:0;text-align:right}}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__prompt--KATqc .styles-module__content--s8aPG{font-size:.8125rem;margin-top:.5rem;padding-bottom:1rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.styles-module__warningPrompt--FUbHc .styles-module__buttonSection--fA_Lt{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:.5rem}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__buttonSection--fA_Lt{flex-direction:row-reverse}}.styles-module__logo--cl0TH{background-color:var(--yoast-color-primary);display:inline-block;height:1.25rem;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:1.25rem}.styles-module__errorModalHeader--_cNpd{align-items:center;display:flex;gap:.5rem;justify-content:flex-start}.styles-module__errorModalContentWrapper--c24iV{display:flex;flex-direction:column;margin-top:1.5rem}.styles-module__errorModalContentWrapper--c24iV>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.styles-module__errorModalLogo--X11B0{height:1.25rem;width:1.25rem}.styles-module__errorModalTitle--vms_Y{font-size:1.125rem;margin-inline-end:.375rem;margin-inline-start:.75rem;margin-right:.75rem;margin-left:.375rem}.styles-module__questionMarkCircle--rbmIj{height:1rem;width:1rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.styles-module__aiErrorModalLink--WHw0z{margin-left:.5rem;-webkit-text-decoration-line:none;text-decoration-line:none}.styles-module__errorModalButtonsWrapper--zknbB{display:flex;margin-bottom:.25rem;margin-top:1.5rem;place-content:end}.styles-module__errorModalButtonsWrapper--zknbB>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-right:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-left:calc(.75rem*var(--tw-space-x-reverse))}.styles-module__errorModalButtonsWrapper--zknbB:where([dir=rtl],[dir=rtl] *)>:not([hidden])~:not([hidden]){--tw-space-x-reverse:1}@media (max-height:840px){[class=yst-root] div.styles-module__modal--CWdoh{height:100%;overflow:scroll;padding:0;position:fixed;text-align:center}[class=yst-root] div.styles-module__modal--CWdoh div[class=yst-modal__layout]{display:block;position:relative}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/ai-frontend-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/ai-frontend-2711.css new file mode 100644 index 0000000..a717644 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/ai-frontend-2711.css @@ -0,0 +1 @@ +.yst-root *,.yst-root :after,.yst-root :before{border:0 solid #e5e7eb;box-sizing:border-box}.yst-root :after,.yst-root :before{--tw-content:""}.yst-root{-webkit-text-size-adjust:100%;margin:0;tab-size:4}.yst-root hr{border-top-width:1px;color:inherit;height:0}.yst-root abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.yst-root h1,.yst-root h2,.yst-root h3,.yst-root h4,.yst-root h5,.yst-root h6{font-size:inherit;font-weight:inherit}.yst-root a{color:inherit;text-decoration:inherit}.yst-root b,.yst-root strong{font-weight:bolder}.yst-root code,.yst-root kbd,.yst-root pre,.yst-root samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}.yst-root small{font-size:80%}.yst-root sub,.yst-root sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}.yst-root sub{bottom:-.25em}.yst-root sup{top:-.5em}.yst-root table{border-collapse:collapse;border-color:inherit;text-indent:0}.yst-root button,.yst-root input,.yst-root optgroup,.yst-root select,.yst-root textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}.yst-root button,.yst-root select{text-transform:none}.yst-root [type=button],.yst-root [type=reset],.yst-root [type=submit],.yst-root button{-webkit-appearance:button;background-color:initial;background-image:none}.yst-root progress{vertical-align:initial}.yst-root ::-webkit-inner-spin-button,.yst-root ::-webkit-outer-spin-button{height:auto}.yst-root [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.yst-root ::-webkit-search-decoration{-webkit-appearance:none}.yst-root ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.yst-root summary{display:list-item}.yst-root blockquote,.yst-root dd,.yst-root dl,.yst-root figure,.yst-root h1,.yst-root h2,.yst-root h3,.yst-root h4,.yst-root h5,.yst-root h6,.yst-root hr,.yst-root p,.yst-root pre{margin:0}.yst-root fieldset{margin:0;padding:0}.yst-root legend{padding:0}.yst-root menu,.yst-root ol,.yst-root ul{list-style:none;margin:0;padding:0}.yst-root textarea{resize:vertical}.yst-root input::placeholder,.yst-root textarea::placeholder{color:#6b7280;opacity:1}.yst-root [role=button],.yst-root button{cursor:pointer}.yst-root :disabled{cursor:default}.yst-root audio,.yst-root canvas,.yst-root embed,.yst-root iframe,.yst-root img,.yst-root object,.yst-root svg,.yst-root video{display:block;vertical-align:middle}.yst-root img,.yst-root video{height:auto;max-width:100%}.yst-root [type=date],.yst-root [type=datetime-local],.yst-root [type=email],.yst-root [type=month],.yst-root [type=number],.yst-root [type=password],.yst-root [type=search],.yst-root [type=tel],.yst-root [type=text],.yst-root [type=time],.yst-root [type=url],.yst-root [type=week]{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root [type=date]:focus,.yst-root [type=datetime-local]:focus,.yst-root [type=email]:focus,.yst-root [type=month]:focus,.yst-root [type=number]:focus,.yst-root [type=password]:focus,.yst-root [type=search]:focus,.yst-root [type=tel]:focus,.yst-root [type=text]:focus,.yst-root [type=time]:focus,.yst-root [type=url]:focus,.yst-root [type=week]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=date]::placeholder,.yst-root [type=datetime-local]::placeholder,.yst-root [type=email]::placeholder,.yst-root [type=month]::placeholder,.yst-root [type=number]::placeholder,.yst-root [type=password]::placeholder,.yst-root [type=search]::placeholder,.yst-root [type=tel]::placeholder,.yst-root [type=text]::placeholder,.yst-root [type=time]::placeholder,.yst-root [type=url]::placeholder,.yst-root [type=week]::placeholder{color:#6b7280;opacity:1}.yst-root [type=date]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=datetime-local]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=email]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=month]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=number]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=password]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=search]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=tel]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=text]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=time]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=url]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=week]::-webkit-datetime-edit-fields-wrapper{padding:0}.yst-root [type=date]::-webkit-date-and-time-value,.yst-root [type=datetime-local]::-webkit-date-and-time-value,.yst-root [type=email]::-webkit-date-and-time-value,.yst-root [type=month]::-webkit-date-and-time-value,.yst-root [type=number]::-webkit-date-and-time-value,.yst-root [type=password]::-webkit-date-and-time-value,.yst-root [type=search]::-webkit-date-and-time-value,.yst-root [type=tel]::-webkit-date-and-time-value,.yst-root [type=text]::-webkit-date-and-time-value,.yst-root [type=time]::-webkit-date-and-time-value,.yst-root [type=url]::-webkit-date-and-time-value,.yst-root [type=week]::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}.yst-root [type=date]::-webkit-datetime-edit,.yst-root [type=datetime-local]::-webkit-datetime-edit,.yst-root [type=email]::-webkit-datetime-edit,.yst-root [type=month]::-webkit-datetime-edit,.yst-root [type=number]::-webkit-datetime-edit,.yst-root [type=password]::-webkit-datetime-edit,.yst-root [type=search]::-webkit-datetime-edit,.yst-root [type=tel]::-webkit-datetime-edit,.yst-root [type=text]::-webkit-datetime-edit,.yst-root [type=time]::-webkit-datetime-edit,.yst-root [type=url]::-webkit-datetime-edit,.yst-root [type=week]::-webkit-datetime-edit{display:inline-flex}.yst-root [type=date]::-webkit-datetime-edit,.yst-root [type=date]::-webkit-datetime-edit-day-field,.yst-root [type=date]::-webkit-datetime-edit-hour-field,.yst-root [type=date]::-webkit-datetime-edit-meridiem-field,.yst-root [type=date]::-webkit-datetime-edit-millisecond-field,.yst-root [type=date]::-webkit-datetime-edit-minute-field,.yst-root [type=date]::-webkit-datetime-edit-month-field,.yst-root [type=date]::-webkit-datetime-edit-second-field,.yst-root [type=date]::-webkit-datetime-edit-year-field,.yst-root [type=datetime-local]::-webkit-datetime-edit,.yst-root [type=datetime-local]::-webkit-datetime-edit-day-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-hour-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-meridiem-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-millisecond-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-minute-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-month-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-second-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-year-field,.yst-root [type=email]::-webkit-datetime-edit,.yst-root [type=email]::-webkit-datetime-edit-day-field,.yst-root [type=email]::-webkit-datetime-edit-hour-field,.yst-root [type=email]::-webkit-datetime-edit-meridiem-field,.yst-root [type=email]::-webkit-datetime-edit-millisecond-field,.yst-root [type=email]::-webkit-datetime-edit-minute-field,.yst-root [type=email]::-webkit-datetime-edit-month-field,.yst-root [type=email]::-webkit-datetime-edit-second-field,.yst-root [type=email]::-webkit-datetime-edit-year-field,.yst-root [type=month]::-webkit-datetime-edit,.yst-root [type=month]::-webkit-datetime-edit-day-field,.yst-root [type=month]::-webkit-datetime-edit-hour-field,.yst-root [type=month]::-webkit-datetime-edit-meridiem-field,.yst-root [type=month]::-webkit-datetime-edit-millisecond-field,.yst-root [type=month]::-webkit-datetime-edit-minute-field,.yst-root [type=month]::-webkit-datetime-edit-month-field,.yst-root [type=month]::-webkit-datetime-edit-second-field,.yst-root [type=month]::-webkit-datetime-edit-year-field,.yst-root [type=number]::-webkit-datetime-edit,.yst-root [type=number]::-webkit-datetime-edit-day-field,.yst-root [type=number]::-webkit-datetime-edit-hour-field,.yst-root [type=number]::-webkit-datetime-edit-meridiem-field,.yst-root [type=number]::-webkit-datetime-edit-millisecond-field,.yst-root [type=number]::-webkit-datetime-edit-minute-field,.yst-root [type=number]::-webkit-datetime-edit-month-field,.yst-root [type=number]::-webkit-datetime-edit-second-field,.yst-root [type=number]::-webkit-datetime-edit-year-field,.yst-root [type=password]::-webkit-datetime-edit,.yst-root [type=password]::-webkit-datetime-edit-day-field,.yst-root [type=password]::-webkit-datetime-edit-hour-field,.yst-root [type=password]::-webkit-datetime-edit-meridiem-field,.yst-root [type=password]::-webkit-datetime-edit-millisecond-field,.yst-root [type=password]::-webkit-datetime-edit-minute-field,.yst-root [type=password]::-webkit-datetime-edit-month-field,.yst-root [type=password]::-webkit-datetime-edit-second-field,.yst-root [type=password]::-webkit-datetime-edit-year-field,.yst-root [type=search]::-webkit-datetime-edit,.yst-root [type=search]::-webkit-datetime-edit-day-field,.yst-root [type=search]::-webkit-datetime-edit-hour-field,.yst-root [type=search]::-webkit-datetime-edit-meridiem-field,.yst-root [type=search]::-webkit-datetime-edit-millisecond-field,.yst-root [type=search]::-webkit-datetime-edit-minute-field,.yst-root [type=search]::-webkit-datetime-edit-month-field,.yst-root [type=search]::-webkit-datetime-edit-second-field,.yst-root [type=search]::-webkit-datetime-edit-year-field,.yst-root [type=tel]::-webkit-datetime-edit,.yst-root [type=tel]::-webkit-datetime-edit-day-field,.yst-root [type=tel]::-webkit-datetime-edit-hour-field,.yst-root [type=tel]::-webkit-datetime-edit-meridiem-field,.yst-root [type=tel]::-webkit-datetime-edit-millisecond-field,.yst-root [type=tel]::-webkit-datetime-edit-minute-field,.yst-root [type=tel]::-webkit-datetime-edit-month-field,.yst-root [type=tel]::-webkit-datetime-edit-second-field,.yst-root [type=tel]::-webkit-datetime-edit-year-field,.yst-root [type=text]::-webkit-datetime-edit,.yst-root [type=text]::-webkit-datetime-edit-day-field,.yst-root [type=text]::-webkit-datetime-edit-hour-field,.yst-root [type=text]::-webkit-datetime-edit-meridiem-field,.yst-root [type=text]::-webkit-datetime-edit-millisecond-field,.yst-root [type=text]::-webkit-datetime-edit-minute-field,.yst-root [type=text]::-webkit-datetime-edit-month-field,.yst-root [type=text]::-webkit-datetime-edit-second-field,.yst-root [type=text]::-webkit-datetime-edit-year-field,.yst-root [type=time]::-webkit-datetime-edit,.yst-root [type=time]::-webkit-datetime-edit-day-field,.yst-root [type=time]::-webkit-datetime-edit-hour-field,.yst-root [type=time]::-webkit-datetime-edit-meridiem-field,.yst-root [type=time]::-webkit-datetime-edit-millisecond-field,.yst-root [type=time]::-webkit-datetime-edit-minute-field,.yst-root [type=time]::-webkit-datetime-edit-month-field,.yst-root [type=time]::-webkit-datetime-edit-second-field,.yst-root [type=time]::-webkit-datetime-edit-year-field,.yst-root [type=url]::-webkit-datetime-edit,.yst-root [type=url]::-webkit-datetime-edit-day-field,.yst-root [type=url]::-webkit-datetime-edit-hour-field,.yst-root [type=url]::-webkit-datetime-edit-meridiem-field,.yst-root [type=url]::-webkit-datetime-edit-millisecond-field,.yst-root [type=url]::-webkit-datetime-edit-minute-field,.yst-root [type=url]::-webkit-datetime-edit-month-field,.yst-root [type=url]::-webkit-datetime-edit-second-field,.yst-root [type=url]::-webkit-datetime-edit-year-field,.yst-root [type=week]::-webkit-datetime-edit,.yst-root [type=week]::-webkit-datetime-edit-day-field,.yst-root [type=week]::-webkit-datetime-edit-hour-field,.yst-root [type=week]::-webkit-datetime-edit-meridiem-field,.yst-root [type=week]::-webkit-datetime-edit-millisecond-field,.yst-root [type=week]::-webkit-datetime-edit-minute-field,.yst-root [type=week]::-webkit-datetime-edit-month-field,.yst-root [type=week]::-webkit-datetime-edit-second-field,.yst-root [type=week]::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}.yst-root textarea{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root textarea:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root textarea::placeholder{color:#6b7280;opacity:1}.yst-root select{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root select:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}.yst-root select:where([size]:not([size="1"])){background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}.yst-root select[multiple]{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root select[multiple]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=checkbox]{appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000;border-radius:0}.yst-root [type=checkbox]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=checkbox]:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}@media (forced-colors:active){.yst-root [type=checkbox]:checked{appearance:auto}}.yst-root [type=checkbox]:checked:focus,.yst-root [type=checkbox]:checked:hover,.yst-root [type=checkbox]:indeterminate{background-color:currentColor;border-color:#0000}.yst-root [type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}@media (forced-colors:active){.yst-root [type=checkbox]:indeterminate{appearance:auto}}.yst-root [type=checkbox]:indeterminate:focus,.yst-root [type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}.yst-root [type=radio]{appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000;border-radius:100%}.yst-root [type=radio]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=radio]:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}@media (forced-colors:active){.yst-root [type=radio]:checked{appearance:auto}}.yst-root [type=radio]:checked:focus,.yst-root [type=radio]:checked:hover{background-color:currentColor;border-color:#0000}.yst-root{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:.8125rem;font-weight:400;line-height:1.5;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.yst-root a{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity));-webkit-text-decoration-line:underline;text-decoration-line:underline}.yst-root a:visited{color:#a61e69}.yst-root a:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity))}.yst-root a:hover:visited{color:#b94986}.yst-root a:focus{border-radius:.125rem;--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity));outline-color:#4f46e5;outline-offset:1px;outline-style:solid}.yst-root [type=date]::placeholder,.yst-root [type=datetime-local]::placeholder,.yst-root [type=email]::placeholder,.yst-root [type=month]::placeholder,.yst-root [type=number]::placeholder,.yst-root [type=password]::placeholder,.yst-root [type=search]::placeholder,.yst-root [type=tel]::placeholder,.yst-root [type=text]::placeholder,.yst-root [type=time]::placeholder,.yst-root [type=url]::placeholder,.yst-root [type=week]::placeholder,.yst-root textarea::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}.yst-root svg path{stroke-width:inherit}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.yst-root .yst-alert{border-radius:.375rem;display:flex;gap:.75rem;padding:1rem}.yst-root .yst-alert--info{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity))}.yst-root .yst-alert--info .yst-alert__message{--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity))}.yst-root .yst-alert--warning{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity))}.yst-root .yst-alert--warning .yst-alert__message{--tw-text-opacity:1;color:rgb(146 64 14/var(--tw-text-opacity))}.yst-root .yst-alert--success{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity))}.yst-root .yst-alert--success .yst-alert__message{--tw-text-opacity:1;color:rgb(22 101 52/var(--tw-text-opacity))}.yst-root .yst-alert--error{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.yst-root .yst-alert--error .yst-alert__message{--tw-text-opacity:1;color:rgb(153 27 27/var(--tw-text-opacity))}.yst-root .yst-alert__icon{flex-grow:0;flex-shrink:0;height:1.25rem;width:1.25rem}.yst-root .yst-autocomplete{position:relative}.yst-root .yst-autocomplete--error .yst-autocomplete__button{--tw-border-opacity:1;border-color:rgb(252 165 165/var(--tw-border-opacity))}.yst-root .yst-autocomplete--error .yst-autocomplete__button:focus{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-opacity:1;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity))}.yst-root .yst-autocomplete--error .yst-autocomplete__input::placeholder{--tw-placeholder-opacity:1;color:rgb(252 165 165/var(--tw-placeholder-opacity))}.yst-root .yst-autocomplete--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-autocomplete--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-autocomplete__button{align-items:center;border-radius:.375rem;border-width:0;display:flex;height:100%;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding-left:.75rem;padding-right:.75rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-autocomplete__button:focus-within{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-autocomplete__button-icon{height:1.25rem;pointer-events:none;position:absolute;right:.625rem;top:.6875rem;width:1.25rem;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-autocomplete__input{border-width:0;font-size:.8125rem;padding:.5rem 2.5rem .5rem 0;width:100%;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-autocomplete__input:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-autocomplete__options{border-radius:.375rem;margin-top:.25rem;max-height:15rem;overflow:auto;position:absolute;width:100%;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity));--tw-ring-opacity:0.05}.yst-root .yst-autocomplete__options:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-autocomplete__option{align-items:center;cursor:default;display:flex;justify-content:space-between;padding:.5rem .75rem;position:relative;-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.yst-root .yst-autocomplete__option--active{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-autocomplete__option--selected{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-select__option-label{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yst-root .yst-autocomplete__option-check{flex-shrink:0;height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-badge{align-items:center;border-radius:9999px;display:inline-flex;white-space:nowrap;--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity));font-size:.75rem;font-weight:500;line-height:1.25;padding:.125rem .5rem;vertical-align:middle;--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity))}.yst-root .yst-badge--info{--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(30 58 138/var(--tw-text-opacity))}.yst-root .yst-badge--upsell{--tw-bg-opacity:1;background-color:rgb(253 230 138/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity))}.yst-root .yst-badge--plain{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.yst-root .yst-badge--small{font-size:.675rem}.yst-root .yst-badge--large{font-size:1rem;padding-left:.75rem;padding-right:.75rem}.yst-root .yst-button{align-items:center;border-radius:.375rem;cursor:pointer;display:inline-flex;font-size:.8125rem;font-weight:500;justify-content:center;line-height:1.25rem;padding:.5rem .75rem;text-align:center;-webkit-text-decoration-line:none;text-decoration-line:none;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-color:#0000}.yst-root .yst-button:focus{outline-color:#a61e69;outline-offset:2px;outline-style:solid;outline-width:2px}.yst-root a.yst-button:focus{border-radius:.375rem}.yst-root .yst-button--primary{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));--tw-ring-color:#0000}.yst-root .yst-button--primary:visited{color:#fff}.yst-root .yst-button--primary:hover{--tw-bg-opacity:1;background-color:rgb(143 15 87/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-button--primary:hover:visited{color:#fff}.yst-root .yst-button--primary:focus{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));outline-color:#8f0f57}.yst-root .yst-button--secondary{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-button--secondary:visited{color:#1e293b}.yst-root .yst-button--secondary:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-button--secondary:hover:visited{color:#1e293b}.yst-root .yst-button--secondary:focus{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));outline-color:#8f0f57}.yst-root .yst-button--tertiary{background-color:initial;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-button--tertiary:visited{color:#83084e}.yst-root .yst-button--tertiary:hover{--tw-text-opacity:1;color:rgb(131 8 78/var(--tw-text-opacity))}.yst-root .yst-button--tertiary:hover:visited{color:#83084e}.yst-root .yst-button--tertiary:focus{--tw-text-opacity:1;color:rgb(131 8 78/var(--tw-text-opacity));outline-color:#8f0f57}.yst-root .yst-button--error{border-color:#0000;--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-button--error:visited{color:#fff}.yst-root .yst-button--error:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-button--error:hover:visited{color:#fff}.yst-root .yst-button--error:focus{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));outline-color:#dc2626}.yst-root .yst-button--upsell{border-color:#0000;--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity))}.yst-root .yst-button--upsell:visited{color:#78350f}.yst-root .yst-button--upsell:hover{--tw-bg-opacity:1;background-color:rgb(251 191 36/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity))}.yst-root .yst-button--upsell:hover:visited{color:#78350f}.yst-root .yst-button--upsell:focus{--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity));outline-color:#fbbf24}.yst-root .yst-button--large{font-size:.875rem;line-height:1.5rem;padding:.5rem .75rem}.yst-root .yst-button--extra-large{font-size:1rem;line-height:1.5rem;padding:.625rem .875rem}.yst-root .yst-button--small{font-size:.75rem;line-height:1rem;padding:.375rem .625rem}.yst-root .yst-button--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-button--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-checkbox{align-items:center;display:flex}.yst-root .yst-checkbox--disabled .yst-checkbox__input,.yst-root .yst-checkbox--disabled .yst-checkbox__label{cursor:not-allowed;opacity:.5}.yst-root .yst-checkbox__input{border-radius:.25rem;height:1rem;width:1rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-checkbox__input:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-checkbox__label{margin-left:.75rem}.yst-root .yst-code{border-radius:.25rem;display:inline-block;margin:0;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));font-size:.75rem;line-height:1.25;padding:.25rem;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.yst-root .yst-code--block{display:block;margin-bottom:.5rem;margin-top:.5rem;max-width:100%;overflow-x:auto;padding:.25rem .5rem;white-space:nowrap}.yst-root .yst-file-input{border-radius:.375rem;border-style:dashed;border-width:2px;width:100%;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1.25rem 1.5rem 1.5rem;text-align:center;transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-file-input.yst-is-drag-over{--tw-border-opacity:1;border-color:rgb(205 130 171/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(250 243 247/var(--tw-bg-opacity))}.yst-root .yst-file-input.yst-is-drag-over .yst-file-input__content{pointer-events:none}.yst-root .yst-file-input.yst-is-drag-over .yst-file-input__icon{--tw-translate-y:-0.5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-text-opacity:1;color:rgb(185 73 134/var(--tw-text-opacity))}.yst-root .yst-file-input.yst-is-disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-file-input.yst-is-disabled .yst-file-input__select-label{cursor:not-allowed}.yst-root .yst-file-input__content{align-items:center;display:inline-flex;flex-direction:column;max-width:20rem}.yst-root .yst-file-input__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-file-input__content{text-align:center}.yst-root .yst-file-input__icon{height:3rem;margin-left:auto;margin-right:auto;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:3rem;stroke-width:1;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity));transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-file-input__icon>path{stroke-width:1}.yst-root .yst-file-input__input{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.yst-root .yst-file-input__input:focus+.yst-file-input__select-label{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-file-input__labels{display:inline-block;font-weight:400;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-file-input__select-label{border-radius:.375rem;font-weight:500}[dir=rtl] .yst-root .yst-file-input__labels{flex-direction:row-reverse}.yst-root .yst-label{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-link{cursor:pointer;--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity));-webkit-text-decoration-line:underline;text-decoration-line:underline}.yst-root .yst-link:visited{color:#a61e69}.yst-root .yst-link:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity))}.yst-root .yst-link:hover:visited{color:#b94986}.yst-root .yst-link:focus{border-radius:.125rem;--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(79 70 229/var(--tw-ring-opacity));--tw-ring-offset-width:1px;--tw-ring-offset-color:#0000}.yst-root .yst-link--primary{--tw-text-opacity:1;color:rgb(154 22 96/var(--tw-text-opacity))}.yst-root .yst-link--primary:focus,.yst-root .yst-link--primary:hover{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-link--primary:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(154 22 96/var(--tw-ring-opacity))}.yst-root .yst-link--error{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.yst-root .yst-link--error:focus,.yst-root .yst-link--error:hover{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.yst-root .yst-link--error:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(220 38 38/var(--tw-ring-opacity))}.yst-root .yst-paper{border-radius:.5rem;display:flex;flex-direction:column;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-paper__header{border-bottom-width:1px;padding:2rem}.yst-root .yst-paper__content{flex-grow:1;padding:2rem}.yst-root .yst-progress-bar{border-radius:9999px;display:block;overflow:hidden;width:100%;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-progress-bar__progress{border-radius:9999px;display:block;height:.375rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));transition-duration:.2s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:linear}.yst-root .yst-radio{align-items:center;display:flex}.yst-root .yst-radio--disabled .yst-radio__check,.yst-root .yst-radio--disabled .yst-radio__input,.yst-root .yst-radio--disabled .yst-radio__label{cursor:not-allowed;opacity:.5}.yst-root .yst-radio--disabled .yst-radio__check:focus,.yst-root .yst-radio--disabled .yst-radio__input:focus,.yst-root .yst-radio--disabled .yst-radio__label:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-radio--inline-block{display:inline-flex}.yst-root .yst-radio--inline-block .yst-radio__input{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.yst-root .yst-radio--inline-block .yst-radio__input:checked+.yst-radio__content .yst-radio__label{border-color:#0000;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-radio--inline-block .yst-radio__input:checked+.yst-radio__content .yst-radio__check{visibility:visible}.yst-root .yst-radio--inline-block .yst-radio__input:focus+.yst-radio__content .yst-radio__label{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-radio--inline-block .yst-radio__input:checked:focus+.yst-radio__content .yst-radio__label{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-offset-width:1px}.yst-root .yst-radio--inline-block .yst-radio__content{position:relative}.yst-root .yst-radio--inline-block .yst-radio__label{align-items:center;border-radius:.5rem;border-width:1px;cursor:pointer;display:flex;height:3.5rem;justify-content:center;margin-left:0;width:3.5rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:1rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-radio--inline-block .yst-radio__label:hover{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity))}.yst-root .yst-radio--inline-block .yst-radio__label:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-radio--inline-block .yst-radio__check{height:1.25rem;position:absolute;right:.125rem;top:.125rem;visibility:hidden;width:1.25rem;--tw-text-opacity:1;color:rgb(154 22 96/var(--tw-text-opacity))}.yst-root .yst-radio__input{height:1rem;width:1rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-radio__input:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-radio__label{margin-left:.75rem}.yst-root .yst-select{position:relative}.yst-root .yst-select--disabled .yst-select__button,.yst-root .yst-select--disabled .yst-select__label{cursor:not-allowed;opacity:.5}.yst-root .yst-select__button{align-items:center;border-radius:.375rem;cursor:default;display:flex;justify-content:space-between;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));line-height:1.5rem;padding:.5rem .75rem;text-align:left;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-select__button,.yst-root .yst-select__button:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-select__button:focus{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-select__button-icon{height:1.25rem;pointer-events:none;position:absolute;right:.625rem;top:.625rem;width:1.25rem;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-select__options{border-radius:.375rem;margin-top:.25rem;max-height:15rem;overflow:auto;position:absolute;width:100%;z-index:10;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity));--tw-ring-opacity:0.05}.yst-root .yst-select__options:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-select__option{align-items:center;cursor:default;display:flex;justify-content:space-between;padding:.5rem .75rem;position:relative;-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.yst-root .yst-select__option--active{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-select__option--selected{--tw-bg-opacity:1;background-color:rgb(154 22 96/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-select__button-label,.yst-root .yst-select__option-label{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yst-root .yst-select__option-check{flex-shrink:0;height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-skeleton-loader{border-radius:.25rem;display:block;height:auto;overflow:hidden;position:relative;width:-moz-fit-content;width:fit-content;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.yst-root .yst-skeleton-loader:after{animation:wave 2.5s linear .5s infinite;background:linear-gradient(90deg,#0000,#00000012,#0000);content:"";inset:0;position:absolute;--tw-translate-x:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes wave{0%{transform:translateX(-100%)}50%,to{transform:translateX(100%)}}.yst-root .yst-tag-input{align-items:center;border-radius:.375rem;display:flex;flex-wrap:wrap;gap:.375rem;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;line-height:1.5rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-tag-input::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}.yst-root .yst-tag-input{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-tag-input,.yst-root .yst-tag-input:focus-within{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-tag-input--disabled:focus-within{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__tag{cursor:not-allowed}.yst-root .yst-tag-input--disabled .yst-tag-input__tag:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__tag:focus,.yst-root .yst-tag-input--disabled .yst-tag-input__tag:focus-visible{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag{cursor:not-allowed}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__input{cursor:not-allowed}.yst-root .yst-tag-input__tag{cursor:pointer;gap:.125rem;min-height:20px;padding-inline-end:.125rem}.yst-root .yst-tag-input__tag:hover{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input__tag:focus,.yst-root .yst-tag-input__tag:focus-visible{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input__remove-tag{align-items:center;border-radius:9999px;display:inline-flex;flex-shrink:0;height:1rem;justify-content:center;width:1rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-tag-input__remove-tag:hover{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.yst-root .yst-tag-input__remove-tag:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-tag-input__input{border-style:none;display:inline-flex;flex:1 1 0%;font-size:.8125rem;margin:0;padding:0}.yst-root .yst-tag-input__input:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input{border-radius:.375rem;border-width:0;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-text-input,.yst-root .yst-text-input:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-text-input--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-text-input--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input--read-only{cursor:default;--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.yst-root .yst-text-input--read-only,.yst-root .yst-textarea{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-textarea{border-radius:.375rem;border-width:0;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-textarea,.yst-root .yst-textarea:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-textarea:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))}.yst-root .yst-textarea--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-textarea--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-title{font-weight:500;line-height:1.25;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.yst-root .yst-title--1{font-size:1.5rem}.yst-root .yst-title--2{font-size:1.125rem}.yst-root .yst-title--3{font-size:.875rem}.yst-root .yst-title--4{font-size:1rem}.yst-root .yst-title--5{font-size:.8125rem}.yst-root .yst-toggle{border-color:#0000;border-radius:9999px;border-width:2px;cursor:pointer;display:inline-flex;flex-shrink:0;height:1.5rem;position:relative;width:2.75rem;--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity));transition-duration:.2s;transition-property:color,background-color,border-color,fill,stroke,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-toggle:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-toggle--checked{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity))}.yst-root .yst-toggle--checked .yst-toggle__handle{--tw-translate-x:1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-toggle--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-toggle--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-toggle__handle{display:flex;height:1.25rem;pointer-events:none;position:relative;width:1.25rem;--tw-translate-x:0px;align-items:center;border-radius:9999px;justify-content:center;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);transition-duration:.2s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-toggle__icon{flex-grow:0;flex-shrink:0;height:.625rem;width:.625rem;stroke:currentColor;stroke-width:2;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));transition-duration:.1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-toggle__icon--check{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-toggle__icon--x{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}[dir=rtl] .yst-root .yst-toggle--checked .yst-toggle__handle{--tw-translate-x:-1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip{border-radius:.5rem;display:inline-block;max-width:24rem;position:absolute;white-space:normal;width:max-content;z-index:10;--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity));font-size:.75rem;padding:.5rem .625rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.yst-root .yst-tooltip--top{left:50%;margin-top:-.75rem;top:0;--tw-translate-x:-50%;--tw-translate-y:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top:before{position:absolute;--tw-translate-x:-50%;--tw-translate-y:0px;border-bottom-color:#0000;border-left-color:#0000;border-right-color:#0000;border-width:8px;--tw-border-opacity:1;border-top-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip--bottom,.yst-root .yst-tooltip--top:before{left:50%;top:100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--bottom{margin-top:.75rem;--tw-translate-x:-50%;--tw-translate-y:-0px}.yst-root .yst-tooltip--bottom:before{bottom:100%;left:50%;position:absolute;--tw-translate-x:-50%;border-left-color:#0000;border-right-color:#0000;border-top-color:#0000;border-width:8px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-bottom-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip--right{left:100%;margin-left:.75rem;--tw-translate-x:-0px}.yst-root .yst-tooltip--right,.yst-root .yst-tooltip--right:before{top:50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--right:before{border-bottom-color:#0000;border-left-color:#0000;border-top-color:#0000;border-width:8px;position:absolute;right:100%;--tw-border-opacity:1;border-right-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip--left{margin-right:.75rem;right:100%}.yst-root .yst-tooltip--left,.yst-root .yst-tooltip--left:before{top:50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--left:before{border-bottom-color:#0000;border-right-color:#0000;border-top-color:#0000;border-width:8px;left:100%;position:absolute;--tw-border-opacity:1;border-left-color:rgb(31 41 55/var(--tw-border-opacity));--tw-content:"";content:var(--tw-content)}.yst-root .yst-validation-icon{pointer-events:none}.yst-root .yst-validation-icon--success{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity))}.yst-root .yst-validation-icon--info{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity))}.yst-root .yst-validation-icon--warning{--tw-text-opacity:1;color:rgb(245 158 11/var(--tw-text-opacity))}.yst-root .yst-validation-icon--error{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.yst-root .yst-validation-input{position:relative}.yst-root .yst-validation-input--success .yst-validation-input__input{padding-right:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(134 239 172/var(--tw-ring-opacity))}.yst-root .yst-validation-input--success .yst-validation-input__input:focus,.yst-root .yst-validation-input--success .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(34 197 94/var(--tw-ring-opacity))}.yst-root .yst-validation-input--info .yst-validation-input__input{padding-right:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(147 197 253/var(--tw-ring-opacity))}.yst-root .yst-validation-input--info .yst-validation-input__input:focus,.yst-root .yst-validation-input--info .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity))}.yst-root .yst-validation-input--warning .yst-validation-input__input{padding-right:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(252 211 77/var(--tw-ring-opacity))}.yst-root .yst-validation-input--warning .yst-validation-input__input:focus,.yst-root .yst-validation-input--warning .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(245 158 11/var(--tw-ring-opacity))}.yst-root .yst-validation-input--error .yst-validation-input__input{padding-right:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(252 165 165/var(--tw-ring-opacity))}.yst-root .yst-validation-input--error .yst-validation-input__input:focus,.yst-root .yst-validation-input--error .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity))}.yst-root .yst-validation-input__input:focus,.yst-root .yst-validation-input__input:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-validation-input__icon{height:1.25rem;position:absolute;right:.625rem;top:.6875rem;width:1.25rem}.yst-root .yst-validation-message a{color:inherit;font-weight:500}.yst-root .yst-validation-message a:visited:hover{color:inherit}.yst-root .yst-validation-message a:focus{--tw-ring-color:currentColor}.yst-root .yst-validation-message--success{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity))}.yst-root .yst-validation-message--info{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.yst-root .yst-validation-message--warning{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity))}.yst-root .yst-validation-message--error{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.yst-root .yst-autocomplete-field__description,.yst-root .yst-autocomplete-field__validation{margin-top:.5rem}.yst-root .yst-card{display:flex;flex-direction:column;position:relative}.yst-root .yst-card>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-card{border-radius:.5rem;border-width:1px;overflow:hidden;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1.5rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-card__header{align-items:center;display:flex;height:6rem;justify-content:center;margin-left:-1.5rem;margin-right:-1.5rem;margin-top:-1.5rem;position:relative;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity));padding:1.5rem}.yst-root .yst-card__content{flex-grow:1}.yst-root .yst-card__footer{border-top-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));padding-top:1.5rem}.yst-root .yst-checkbox-group--disabled .yst-checkbox-group__description,.yst-root .yst-checkbox-group--disabled .yst-checkbox-group__label{cursor:not-allowed;opacity:.5}.yst-root .yst-checkbox-group__label{margin-bottom:.5rem}.yst-root .yst-checkbox-group__options{display:flex;flex-direction:column;gap:.75rem}.yst-root .yst-checkbox-group__description{margin-bottom:1rem;margin-top:-.5rem}.yst-root .yst-feature-upsell{position:relative}.yst-root .yst-feature-upsell--default{--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.yst-root .yst-feature-upsell--card{padding:1.5rem}.yst-root .yst-file-import>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-file-import__feedback{border-radius:.375rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1rem;--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-file-import__feedback-header{align-items:flex-start;display:flex}.yst-root .yst-file-import__feedback-header>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.yst-root .yst-file-import__feedback-figure{align-items:center;border-radius:9999px;display:flex;height:2rem;justify-content:center;width:2rem;--tw-bg-opacity:1;background-color:rgb(243 229 237/var(--tw-bg-opacity))}.yst-root .yst-file-import__feedback-figure>svg{height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity))}.yst-root .yst-file-import__feedback-title{display:block;font-weight:500;margin-bottom:.125rem;overflow-wrap:break-word;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.yst-root .yst-file-import__feedback-description{display:block;font-size:.75rem;font-weight:500}.yst-root .yst-file-import__abort-button{align-items:center;border-radius:9999px;display:inline-flex;flex-shrink:0;height:1.25rem;justify-content:center;width:1.25rem;--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.yst-root .yst-file-import__abort-button:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.yst-root .yst-file-import__abort-button:focus{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));outline:2px solid #0000;outline-offset:2px}.yst-root .yst-file-import__abort-button>svg{height:.75rem;width:.75rem}.yst-root .yst-file-import__abort-button>svg>path{stroke-width:3}.yst-root .yst-modal{inset:0;padding:1rem;position:fixed;z-index:10}@media (min-width:640px){.yst-root .yst-modal{padding:2rem}}@media (min-width:768px){.yst-root .yst-modal{padding:5rem}}.yst-root .yst-modal__layout{display:flex;min-height:100%}.yst-root .yst-modal--center .yst-modal__layout{align-items:center;justify-content:center}.yst-root .yst-modal--top-center .yst-modal__layout{align-items:flex-start;justify-content:center}.yst-root .yst-modal__overlay{background-color:rgb(100 116 139/var(--tw-bg-opacity));inset:0;position:fixed;--tw-bg-opacity:0.75;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-modal__panel{border-radius:.5rem;max-width:48rem;overflow:hidden;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1.5rem;--tw-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-modal__close{display:block;position:absolute;right:1rem;top:1rem}.yst-root .yst-modal__close-button{border-radius:.375rem;position:relative;z-index:10;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.yst-root .yst-modal__close-button:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.yst-root .yst-modal__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity));--tw-ring-offset-width:2px}.yst-root .yst-modal__container{display:flex;flex-direction:column;max-height:calc(100vh - 2rem)}@media (min-width:640px){.yst-root .yst-modal__container{max-height:calc(100vh - 4rem)}}@media (min-width:768px){.yst-root .yst-modal__container{max-height:calc(100vh - 10rem)}}.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 5rem)}@media (min-width:640px){.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 7rem)}}@media (min-width:768px){.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 13rem)}}.yst-root .yst-modal__container-footer,.yst-root .yst-modal__container-header{flex-shrink:0}.yst-root .yst-modal__container-content{overflow:auto}.yst-root .yst-modal__panel .yst-modal__container-content{margin-left:-1.5rem;margin-right:-1.5rem;padding-left:1.5rem;padding-right:1.5rem}.yst-root .yst-notifications{display:flex;flex-direction:column;max-height:calc(100vh - 4rem);max-width:calc(100vw - 4rem);pointer-events:none;position:fixed;width:100%;z-index:20}.yst-root .yst-notifications>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-notifications--bottom-center{align-items:center;bottom:2rem}.yst-root .yst-notifications--bottom-left{bottom:2rem;left:2rem}.yst-root .yst-notifications--top-center{align-items:center;top:2rem}.yst-root .yst-notification{border-radius:.5rem;max-width:100%;overflow-y:auto;pointer-events:auto;width:20rem;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));padding:1rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity));--tw-ring-opacity:0.05}.yst-root .yst-notification--large{width:24rem}.yst-root .yst-notification__icon{height:1.25rem;width:1.25rem}.yst-root .yst-pagination{display:inline-flex;isolation:isolate}.yst-root .yst-pagination>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(-1px*(1 - var(--tw-space-x-reverse)));margin-right:calc(-1px*var(--tw-space-x-reverse))}.yst-root .yst-pagination{border-radius:.375rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-pagination-display__text{font-weight:400;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(226 232 240/var(--tw-ring-opacity))}.yst-root .yst-pagination-display__current-text{font-weight:600;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.yst-root .yst-pagination-display__truncated{align-self:center;font-size:.8125rem;font-weight:600;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(226 232 240/var(--tw-ring-opacity))}.yst-root .yst-pagination-display__truncated,.yst-root .yst-pagination__button{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);display:inline-flex}.yst-root .yst-pagination__button{align-items:center;padding:.5rem;position:relative;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity))}.yst-root .yst-pagination__button:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.yst-root .yst-pagination__button:focus{outline-color:#a61e69;outline-offset:0;z-index:20}.yst-root .yst-pagination__button--active{z-index:10;--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity));font-size:.8125rem;font-weight:600;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-pagination__button--active:hover{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity))}.yst-root .yst-pagination__button--active:focus{z-index:20}.yst-root .yst-pagination__button--active:focus-visible{border-radius:.125rem;outline-color:#a61e69;outline-offset:2px;outline-style:solid;outline-width:2px}.yst-root .yst-pagination__button--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-pagination__button--disabled:hover{background-color:initial}.yst-root .yst-pagination__button--disabled:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-radio-group--inline-block .yst-radio-group__options{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}.yst-root .yst-radio-group--disabled .yst-radio-group__description,.yst-root .yst-radio-group--disabled .yst-radio-group__label{opacity:.5}.yst-root .yst-radio-group--disabled .yst-radio-group__label{cursor:not-allowed}.yst-root .yst-radio-group__label{margin-bottom:.5rem}.yst-root .yst-radio-group__options{display:flex;flex-direction:column;gap:.5rem}.yst-root .yst-radio-group__description{margin-bottom:1rem;margin-top:-.5rem}.yst-root .yst-select-field--disabled .yst-select-field__description,.yst-root .yst-select-field--disabled .yst-select-field__label{cursor:not-allowed;opacity:.5}.yst-root .yst-select-field__options{display:flex;flex-direction:column;gap:.75rem}.yst-root .yst-select-field__description,.yst-root .yst-select-field__validation{margin-top:.5rem}.yst-root .yst-mobile-navigation__top{position:sticky;top:0;width:100%;z-index:50}.yst-root .yst-mobile-navigation__dialog{display:flex;inset:0;position:fixed;z-index:50}.yst-root .yst-tag-field--disabled .yst-tag-field__description,.yst-root .yst-tag-field--disabled .yst-tag-field__label{cursor:not-allowed;opacity:.5}.yst-root .yst-tag-field__description,.yst-root .yst-tag-field__validation{margin-top:.5rem}.yst-root .yst-text-field--disabled .yst-text-field__description,.yst-root .yst-text-field--disabled .yst-text-field__label{opacity:.5}.yst-root .yst-text-field--disabled .yst-text-field__label{cursor:not-allowed}.yst-root .yst-text-field--read-only .yst-text-field__label{cursor:default}.yst-root .yst-text-field__description,.yst-root .yst-text-field__validation{margin-top:.5rem}.yst-root .yst-textarea-field--disabled .yst-textarea-field__description,.yst-root .yst-textarea-field--disabled .yst-textarea-field__label{opacity:.5}.yst-root .yst-textarea-field--disabled .yst-textarea-field__label{cursor:not-allowed}.yst-root .yst-text-field--read-only .yst-textarea-field__label{cursor:default}.yst-root .yst-textarea-field__description,.yst-root .yst-textarea-field__validation{margin-top:.5rem}.yst-root .yst-toggle-field{display:flex;flex-direction:column;gap:.25rem}.yst-root .yst-toggle-field--disabled .yst-toggle-field__description,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label-wrapper{opacity:.5}.yst-root .yst-toggle-field--disabled .yst-toggle-field__description,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label-wrapper{cursor:not-allowed}.yst-root .yst-toggle-field__header{align-items:center;display:flex;flex-direction:row;gap:1.5rem;justify-content:space-between}.yst-root .yst-toggle-field__label-wrapper{align-items:center;display:flex;gap:.25rem}.yst-root .yst-toggle-field__description{margin-right:4.25rem}.yst-sr-only{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;border-width:0!important;white-space:nowrap!important}.yst-pointer-events-none{pointer-events:none!important}.yst-invisible{visibility:hidden!important}.yst-fixed{position:fixed!important}.yst-absolute{position:absolute!important}.yst-relative{position:relative!important}.yst-inset-0{inset:0!important}.yst-right-0{right:0!important}.yst-top-0{top:0!important}.yst-z-10{z-index:10!important}.yst-z-30{z-index:30!important}.yst-z-40{z-index:40!important}.yst-m-0{margin:0!important}.yst-mx-auto{margin-left:auto!important;margin-right:auto!important}.yst--ml-1{margin-left:-.25rem!important}.yst--mr-14{margin-right:-3.5rem!important}.yst-mb-2{margin-bottom:.5rem!important}.yst-mb-px{margin-bottom:1px!important}.yst-ml-4{margin-left:1rem!important}.yst-ml-8{margin-left:2rem!important}.yst-mr-2{margin-right:.5rem!important}.yst-mr-4{margin-right:1rem!important}.yst-mt-1{margin-top:.25rem!important}.yst-mt-1\.5{margin-top:.375rem!important}.yst-mt-2{margin-top:.5rem!important}.yst-mt-3{margin-top:.75rem!important}.yst-mt-6{margin-top:1.5rem!important}.yst-block{display:block!important}.yst-flex{display:flex!important}.yst-inline-flex{display:inline-flex!important}.yst-hidden{display:none!important}.yst-h-0{height:0!important}.yst-h-12{height:3rem!important}.yst-h-16{height:4rem!important}.yst-h-3{height:.75rem!important}.yst-h-4{height:1rem!important}.yst-h-5{height:1.25rem!important}.yst-h-6{height:1.5rem!important}.yst-h-7{height:1.75rem!important}.yst-h-8{height:2rem!important}.yst-h-full{height:100%!important}.yst-w-0{width:0!important}.yst-w-12{width:3rem!important}.yst-w-2{width:.5rem!important}.yst-w-3{width:.75rem!important}.yst-w-4{width:1rem!important}.yst-w-5{width:1.25rem!important}.yst-w-6{width:1.5rem!important}.yst-w-8{width:2rem!important}.yst-w-full{width:100%!important}.yst-min-w-full{min-width:100%!important}.yst-max-w-none{max-width:none!important}.yst-max-w-xs{max-width:20rem!important}.yst-flex-1{flex:1 1 0%!important}.yst-flex-shrink-0,.yst-shrink-0{flex-shrink:0!important}.yst--translate-y-full{--tw-translate-y:-100%!important}.yst--translate-y-full,.yst-translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-translate-y-0{--tw-translate-y:0px!important}.yst-translate-y-4{--tw-translate-y:1rem!important}.yst-translate-y-4,.yst-translate-y-full{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-translate-y-full{--tw-translate-y:100%!important}.yst-scale-100{--tw-scale-x:1!important;--tw-scale-y:1!important}.yst-scale-100,.yst-scale-95{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-scale-95{--tw-scale-x:.95!important;--tw-scale-y:.95!important}.yst-transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}@keyframes yst-spin{to{transform:rotate(1turn)}}.yst-animate-spin{animation:yst-spin 1s linear infinite!important}.yst-cursor-wait{cursor:wait!important}.yst-list-disc{list-style-type:disc!important}.yst-flex-col{flex-direction:column!important}.yst-flex-wrap{flex-wrap:wrap!important}.yst-items-start{align-items:flex-start!important}.yst-items-center{align-items:center!important}.yst-justify-center{justify-content:center!important}.yst-justify-between{justify-content:space-between!important}.yst-gap-2{gap:.5rem!important}.yst-gap-3{gap:.75rem!important}.yst-space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(.25rem*var(--tw-space-y-reverse))!important;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))!important}.yst-space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(2rem*var(--tw-space-y-reverse))!important;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))!important}.yst-divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0!important;border-bottom-width:calc(1px*var(--tw-divide-y-reverse))!important;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))!important}.yst-divide-gray-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1!important;border-color:rgb(229 231 235/var(--tw-divide-opacity))!important}.yst-divide-slate-300>:not([hidden])~:not([hidden]){--tw-divide-opacity:1!important;border-color:rgb(203 213 225/var(--tw-divide-opacity))!important}.yst-overflow-hidden{overflow:hidden!important}.yst-overflow-y-auto{overflow-y:auto!important}.yst-rounded-full{border-radius:9999px!important}.yst-rounded-lg{border-radius:.5rem!important}.yst-rounded-md{border-radius:.375rem!important}.yst-rounded-l-md{border-bottom-left-radius:.375rem!important;border-top-left-radius:.375rem!important}.yst-rounded-r-md{border-bottom-right-radius:.375rem!important;border-top-right-radius:.375rem!important}.yst-border-b{border-bottom-width:1px!important}.yst-border-r{border-right-width:1px!important}.yst-border-slate-200{--tw-border-opacity:1!important;border-color:rgb(226 232 240/var(--tw-border-opacity))!important}.yst-border-r-slate-200{--tw-border-opacity:1!important;border-right-color:rgb(226 232 240/var(--tw-border-opacity))!important}.yst-bg-red-100{--tw-bg-opacity:1!important;background-color:rgb(254 226 226/var(--tw-bg-opacity))!important}.yst-bg-slate-100{--tw-bg-opacity:1!important;background-color:rgb(241 245 249/var(--tw-bg-opacity))!important}.yst-bg-slate-200{--tw-bg-opacity:1!important;background-color:rgb(226 232 240/var(--tw-bg-opacity))!important}.yst-bg-slate-50{--tw-bg-opacity:1!important;background-color:rgb(248 250 252/var(--tw-bg-opacity))!important}.yst-bg-slate-600{--tw-bg-opacity:1!important;background-color:rgb(71 85 105/var(--tw-bg-opacity))!important}.yst-bg-white{--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity))!important}.yst-bg-opacity-75{--tw-bg-opacity:0.75!important}.yst-stroke-3{stroke-width:3px!important}.yst-p-1{padding:.25rem!important}.yst-px-2{padding-left:.5rem!important;padding-right:.5rem!important}.yst-px-3{padding-left:.75rem!important;padding-right:.75rem!important}.yst-px-4{padding-left:1rem!important;padding-right:1rem!important}.yst-py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.yst-py-4{padding-bottom:1rem!important;padding-top:1rem!important}.yst-py-6{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.yst-pb-1{padding-bottom:.25rem!important}.yst-pb-4{padding-bottom:1rem!important}.yst-pt-1{padding-top:.25rem!important}.yst-text-left{text-align:left!important}.yst-text-center{text-align:center!important}.yst-text-sm{font-size:.8125rem!important}.yst-font-medium{font-weight:500!important}.yst-font-normal{font-weight:400!important}.yst-font-semibold{font-weight:600!important}.yst-leading-4{line-height:1rem!important}.yst-text-gray-500{--tw-text-opacity:1!important;color:rgb(107 114 128/var(--tw-text-opacity))!important}.yst-text-primary-500{--tw-text-opacity:1!important;color:rgb(166 30 105/var(--tw-text-opacity))!important}.yst-text-red-600{--tw-text-opacity:1!important;color:rgb(220 38 38/var(--tw-text-opacity))!important}.yst-text-slate-400{--tw-text-opacity:1!important;color:rgb(148 163 184/var(--tw-text-opacity))!important}.yst-text-slate-500{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity))!important}.yst-text-slate-600{--tw-text-opacity:1!important;color:rgb(71 85 105/var(--tw-text-opacity))!important}.yst-text-slate-800{--tw-text-opacity:1!important;color:rgb(30 41 59/var(--tw-text-opacity))!important}.yst-text-slate-900{--tw-text-opacity:1!important;color:rgb(15 23 42/var(--tw-text-opacity))!important}.yst-text-white{--tw-text-opacity:1!important;color:rgb(255 255 255/var(--tw-text-opacity))!important}.yst-no-underline{-webkit-text-decoration-line:none!important;text-decoration-line:none!important}.yst-opacity-0{opacity:0!important}.yst-opacity-100{opacity:1!important}.yst-opacity-25{opacity:.25!important}.yst-opacity-75{opacity:.75!important}.yst-shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a!important;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)!important}.yst-shadow,.yst-shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.yst-shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a!important;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)!important}.yst-shadow-amber-700\/30{--tw-shadow-color:#b453094d!important;--tw-shadow:var(--tw-shadow-colored)!important}.yst-ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.yst-ring-black{--tw-ring-opacity:1!important;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))!important}.yst-ring-opacity-5{--tw-ring-opacity:0.05!important}.yst-grayscale{--tw-grayscale:grayscale(100%)!important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.yst-transition{transition-duration:.15s!important;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-transition-opacity{transition-duration:.15s!important;transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-delay-200{transition-delay:.2s!important}.yst-duration-100{transition-duration:.1s!important}.yst-duration-1000{transition-duration:1s!important}.yst-duration-150{transition-duration:.15s!important}.yst-duration-200{transition-duration:.2s!important}.yst-duration-300{transition-duration:.3s!important}.yst-duration-75{transition-duration:75ms!important}.yst-ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)!important}.yst-ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)!important}.odd\:yst-bg-white:nth-child(odd){--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity))!important}.even\:yst-bg-slate-50:nth-child(2n),.hover\:yst-bg-slate-50:hover{--tw-bg-opacity:1!important;background-color:rgb(248 250 252/var(--tw-bg-opacity))!important}.hover\:yst-text-slate-500:hover{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity))!important}.hover\:yst-text-slate-900:hover{--tw-text-opacity:1!important;color:rgb(15 23 42/var(--tw-text-opacity))!important}.focus\:yst-outline-none:focus{outline:2px solid #0000!important;outline-offset:2px!important}.focus\:yst-ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important}.focus\:yst-ring-1:focus,.focus\:yst-ring-2:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.focus\:yst-ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important}.focus\:yst-ring-inset:focus{--tw-ring-inset:inset!important}.focus\:yst-ring-primary-500:focus{--tw-ring-opacity:1!important;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity))!important}.focus\:yst-ring-offset-1:focus{--tw-ring-offset-width:1px!important}.focus\:yst-ring-offset-2:focus{--tw-ring-offset-width:2px!important}.focus\:yst-ring-offset-transparent:focus{--tw-ring-offset-color:#0000!important}.yst-group:hover .group-hover\:yst-text-slate-500{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity))!important}@media (min-width:640px){.sm\:yst-mx-0{margin-left:0!important;margin-right:0!important}.sm\:yst-ml-4{margin-left:1rem!important}.sm\:yst-mt-0{margin-top:0!important}.sm\:yst-flex{display:flex!important}.sm\:yst-h-10{height:2.5rem!important}.sm\:yst-w-10{width:2.5rem!important}.sm\:yst-translate-y-0{--tw-translate-y:0px!important}.sm\:yst-scale-100,.sm\:yst-translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.sm\:yst-scale-100{--tw-scale-x:1!important;--tw-scale-y:1!important}.sm\:yst-scale-95{--tw-scale-x:.95!important;--tw-scale-y:.95!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}}.rtl\:yst-rotate-180:where([dir=rtl],[dir=rtl] *){--tw-rotate:180deg!important;tw-rotate:180deg!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.sm\:yst-flex-row-reverse{flex-direction:row-reverse!important}.sm\:yst-items-start{align-items:flex-start!important}.sm\:yst-text-left{text-align:left!important}.yst-root :-moz-focusring{outline:auto}.yst-root :-moz-ui-invalid{box-shadow:none}.yst-root input::-moz-placeholder,.yst-root textarea::-moz-placeholder{color:#6b7280;opacity:1}.yst-root [type=date]::-moz-placeholder,.yst-root [type=datetime-local]::-moz-placeholder,.yst-root [type=email]::-moz-placeholder,.yst-root [type=month]::-moz-placeholder,.yst-root [type=number]::-moz-placeholder,.yst-root [type=password]::-moz-placeholder,.yst-root [type=search]::-moz-placeholder,.yst-root [type=tel]::-moz-placeholder,.yst-root [type=text]::-moz-placeholder,.yst-root [type=time]::-moz-placeholder,.yst-root [type=url]::-moz-placeholder,.yst-root [type=week]::-moz-placeholder{color:#6b7280;opacity:1}.yst-root textarea::-moz-placeholder{color:#6b7280;opacity:1}.yst-root [type=date]::-moz-placeholder,.yst-root [type=datetime-local]::-moz-placeholder,.yst-root [type=email]::-moz-placeholder,.yst-root [type=month]::-moz-placeholder,.yst-root [type=number]::-moz-placeholder,.yst-root [type=password]::-moz-placeholder,.yst-root [type=search]::-moz-placeholder,.yst-root [type=tel]::-moz-placeholder,.yst-root [type=text]::-moz-placeholder,.yst-root [type=time]::-moz-placeholder,.yst-root [type=url]::-moz-placeholder,.yst-root [type=week]::-moz-placeholder,.yst-root textarea::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}.yst-root .yst-autocomplete--error .yst-autocomplete__input::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(252 165 165/var(--tw-placeholder-opacity))}.yst-root .yst-tag-input::-moz-placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity))}[class=yst-root] .styles-module__paginationTitleSkeleton--ePjfS{height:13px;width:131px}[class=yst-root] div.styles-module__modal--quowq{z-index:1050}.styles-module__generatorContainer--jWKDs{border-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));width:696px}.styles-module__logo--gDbXB{background-color:var(--yoast-color-primary);display:inline-block;height:1.25rem;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:1.25rem}.styles-module__modalTitle--LTCoD{align-items:center;display:flex;font-size:18px;font-weight:500;letter-spacing:.5px;line-height:27px;margin:24px}.styles-module__modalTitle--LTCoD>*{margin-right:8px}[class=yst-root] div.styles-module__modalContainer--DyT0w{max-width:696px;overflow:visible;padding:0!important;position:sticky;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}[class=yst-root] div.styles-module__modalContainer--DyT0w div.styles-module__modalContent--uxbqo{margin:0;padding-left:0;padding-right:0;position:relative}[class=yst-root] div.styles-module__modalContainer--DyT0w div.styles-module__modalContent--uxbqo .styles-module__fadeOut--O2ZCu:before{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));content:"";display:block;height:24px;margin-top:-24px;mask-image:linear-gradient(180deg,#0000,#000);position:sticky;top:calc(100% - 24px);width:100%}[class=yst-root] div.styles-module__modalContainer--DyT0w h1{--tw-border-opacity:1;border-bottom-width:1px;border-color:rgb(229 231 235/var(--tw-border-opacity))}.styles-module__floatingCounter--KzR9L{position:absolute;right:48px;top:-10px}.styles-module__learnMore--mrUIw{margin-left:-4px}.styles-module__learnMore--mrUIw svg{height:1rem;width:1rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}[class=yst-root] .styles-module__buttonArea--I6ND0{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:0 0 .5rem .5rem;border-width:1px 0 0;display:flex;justify-content:flex-end;padding:24px;width:100%}[class=yst-root] .styles-module__buttonArea--I6ND0>button{margin-left:.75rem}[class=yst-root] .styles-module__buttonArea--I6ND0>button svg{height:16px;margin-right:8px;width:16px}.styles-module__aiGenerator--Q4G7H{width:100%}.styles-module__aiGenerator--Q4G7H .styles-module__errorBanner--Aynek{margin:0 24px 16px;padding:0}.styles-module__aiGenerator--Q4G7H .styles-module__errorBanner--Aynek.styles-module__fullError--eTOfR{margin:16px}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='768' height='174' fill='none'%3E%3Cg clip-path='url(%23a)'%3E%3Cpath fill='%23fff' d='M0 0h768v174H0z'/%3E%3Cg filter='url(%23b)' opacity='.15'%3E%3Cellipse cx='384' cy='87' fill='url(%23c)' rx='304' ry='43'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3ClinearGradient id='c' x1='80' x2='453.361' y1='44' y2='386.089' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23A61E69'/%3E%3Cstop offset='1' stop-color='%236366F1'/%3E%3C/linearGradient%3E%3CclipPath id='a'%3E%3Cpath fill='%23fff' d='M0 0h768v174H0z'/%3E%3C/clipPath%3E%3Cfilter id='b' width='736' height='214' x='16' y='-20' color-interpolation-filters='sRGB' filterUnits='userSpaceOnUse'%3E%3CfeFlood flood-opacity='0' result='BackgroundImageFix'/%3E%3CfeBlend in='SourceGraphic' in2='BackgroundImageFix' result='shape'/%3E%3CfeGaussianBlur result='effect1_foregroundBlur_862_1019' stdDeviation='32'/%3E%3C/filter%3E%3C/defs%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:auto;display:flex;justify-items:center;max-width:100%}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h.styles-module__social--I2bZ1{margin-bottom:1em}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q{background:#0000;margin:8px auto;max-width:100%;padding:0}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl{margin:0 24px;width:calc(100% - 48px)}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:last-child{margin:.5rem 0 0}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:last-child>div{align-items:center;display:flex;justify-content:center}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:first-child{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:8px;box-shadow:0 1px 6px #20212447;margin:inherit;padding:1rem}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q .styles-module__desktopPreview--KClpl section>div:first-child>div{align-items:inherit;display:inherit;justify-content:inherit}.styles-module__social--I2bZ1 .styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q{width:100%}.styles-module__social--I2bZ1 .styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q>div{margin:1em auto}.styles-module__aiGenerator--Q4G7H .styles-module__previewSection--dQI7h .styles-module__preview--AMJ8q>section>div{background:#fff}.styles-module__aiGenerator--Q4G7H .styles-module__titleProgress--BlLuI{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity));padding:16px 24px}.styles-module__aiGenerator--Q4G7H .styles-module__mainTitle--hcBkm{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity));display:flex;justify-content:space-between;padding:24px 24px 16px}.styles-module__aiGenerator--Q4G7H .styles-module__mainTitle--hcBkm .styles-module__mainTitleSkeleton--CSk1Z{height:13px;width:98px}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy{margin:.5em 0}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__good--Ueni9>div{background-color:#7ad03a}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__good--Ueni9.styles-module__altColors--o1t8E>div{background-color:#4ade80}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__ok--RvqJ4>div{background-color:#ee7c1b}.styles-module__aiGenerator--Q4G7H .styles-module__progressBar--y7Coy.styles-module__bad--_XMc7>div{background-color:#dc3232}.styles-module__skeletonPreview--QYdU8{background:#fff;border-radius:.5rem;margin:auto;padding:16px;width:400px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T{display:flex;margin-bottom:21px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__firstColumn--dorvx>span{border-radius:28px;height:28px;margin-right:12px;width:28px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__secondColumn--m5oLy>span{border-radius:4px;height:13px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__secondColumn--m5oLy>span:first-child{margin-bottom:3px;width:123px}.styles-module__skeletonPreview--QYdU8 .styles-module__header--vHY_T .styles-module__secondColumn--m5oLy>span:nth-child(2){width:276px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span{border-radius:4px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span:first-child{height:20px;margin-bottom:16px;width:368px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span:nth-child(2){height:13px;margin-bottom:8px;width:368px}.styles-module__skeletonPreview--QYdU8 .styles-module__content--cEMcn>span:nth-child(3){height:13px;width:221px}.styles-module__mockedSelector--_0Gy5{display:flex;items-align:center}.styles-module__mockedSelector--_0Gy5 .styles-module__emptyCircle--nibrZ{border-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));border-radius:16px;height:16px;margin-right:8px;width:16px}.styles-module__mockedSelector--_0Gy5>span:nth-child(2){height:13px;margin-right:16px;width:82px}.styles-module__mockedSelector--_0Gy5>span:nth-child(4){height:13px;width:92px}form.styles-module__suggestionList--CVXuA{min-width:320px;width:100%}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));font-size:.8125rem;padding:1rem .75rem;--tw-text-opacity:1;align-items:center;border-width:0 1px 1px;color:rgb(71 85 105/var(--tw-text-opacity));display:flex}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB:first-of-type{border-top-left-radius:.5rem;border-top-right-radius:.5rem;border-top-width:1px}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB:last-of-type{border-bottom-left-radius:.5rem;border-bottom-right-radius:.5rem;--tw-divide-y-reverse:1px}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB.styles-module__selectedOption--hcd4O{--tw-border-opacity:1;border-color:rgb(143 15 87/var(--tw-border-opacity));--tw-text-opacity:1;border-top-width:1px;color:rgb(15 23 42/var(--tw-text-opacity));margin-top:-1px}form.styles-module__suggestionList--CVXuA .styles-module__row--ioJoB.styles-module__selectedOption--hcd4O:first-of-type{margin-top:0}form.styles-module__suggestionList--CVXuA .styles-module__innerOption--jmXHJ{align-items:center;display:flex}form.styles-module__suggestionList--CVXuA .styles-module__optionLabel--kZshU{flex:1 1 auto}form.styles-module__suggestionList--CVXuA .styles-module__loadingMock--Mr6WN{align-items:center;display:flex;height:1.5em;justify-content:space-between;width:100%}form.styles-module__suggestionList--CVXuA .styles-module__loadingMock--Mr6WN .styles-module__labelMock--NITYK{flex:1 0 auto;height:.75rem;margin-left:16px}form.styles-module__suggestionList--CVXuA .styles-module__pagination--FYqPO{display:flex;justify-content:flex-end;margin-top:1em;width:100%}:root{--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E")}.styles-module__gradientBorder--FrZBT,.styles-module__gradientBorderButton--gGjJv>button,[class=yst-root] span.styles-module__gradientBorder--FrZBT{position:absolute;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-gradient-from:#faf3f7 var(--tw-gradient-from-position);--tw-gradient-to:#faf3f700 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to);--tw-gradient-to:#eef2ff var(--tw-gradient-to-position);--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);border-image:linear-gradient(to bottom right,#cd82ab,#a5b4fc) 1;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);display:flex;justify-content:flex-start;position:relative;z-index:0;text-wrap:wrap;flex-direction:row;overflow:hidden}.styles-module__gradientBorder--FrZBT>svg,.styles-module__gradientBorderButton--gGjJv>button>svg,[class=yst-root] span.styles-module__gradientBorder--FrZBT>svg{margin-right:8px}.styles-module__gradientBorder--FrZBT:before,.styles-module__gradientBorderButton--gGjJv>button:before,[class=yst-root] span.styles-module__gradientBorder--FrZBT:before{background:linear-gradient(to bottom right,#cd82ab,#a5b4fc);border-radius:inherit;bottom:0;content:"";left:0;mask:linear-gradient(#fff,#fff) content-box,linear-gradient(#fff,#fff) border-box;mask-composite:exclude;padding:1px;position:absolute;right:0;top:0;z-index:-1}[class=yst-root] .styles-module__notificationWithToast--IBfwe>div{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops));border-radius:.5rem;display:inline-block;max-width:24rem}[class=yst-root] .styles-module__notificationWithToast--IBfwe>span{inset-inline-start:265px;position:absolute;top:.25rem;z-index:10}[class=yst-root] .styles-module__notificationWithToast--IBfwe>div>div{overflow-y:visible;padding:1rem}[class=yst-root] .styles-module__notificationWithToast--IBfwe>div>div:first-child{padding-bottom:0}.styles-module__header--mjkFl{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;align-items:baseline;color:rgb(15 23 42/var(--tw-text-opacity));display:flex;justify-content:space-between;padding:0 24px}.styles-module__header--mjkFl button svg{margin-right:8px}.styles-module__suggestions--sUYxk{font-size:.8125rem;padding:8px 24px 40px}.styles-module__suggestions--sUYxk .styles-module__suggestionsNote--P23gI{font-size:.75rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity));font-size:11px;margin-top:.5rem}#radio-group-typeSelector>div{flex-direction:row;gap:1.5rem}[class=yst-root] span.styles-module__badge--rMVjT{height:18px;position:absolute;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));--tw-gradient-from:#faf3f7 var(--tw-gradient-from-position);--tw-gradient-to:#faf3f700 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to);--tw-gradient-to:#eef2ff var(--tw-gradient-to-position);--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);border-image:linear-gradient(to bottom right,#cd82ab,#a5b4fc) 1;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);position:relative;z-index:0}[class=yst-root] span.styles-module__badge--rMVjT:before{background:linear-gradient(to bottom right,#cd82ab,#a5b4fc);border-radius:inherit;bottom:0;content:"";left:0;mask:linear-gradient(#fff,#fff) content-box,linear-gradient(#fff,#fff) border-box;mask-composite:exclude;padding:1px;position:absolute;right:0;top:0;z-index:-1}.styles-module__icon--y4uAf{margin-right:.25rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity));width:11px;fill:linear-gradient(90deg,#3f87a6,#ebf8e1,#f69d3c)}.styles-module__data--C2k4_{font-weight:600;margin-right:.25rem;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>div{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops));border-radius:.5rem;display:inline-block;max-width:24rem}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>span{inset-inline-start:265px;position:absolute;top:.25rem;z-index:10}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>div>div{overflow-y:visible;padding:1rem}[class=yst-root] .styles-module__toastWithUsageCounter--q44P2>div>div:first-child{padding-bottom:0}[class=yst-root] .styles-module__buttonGroup--BqLdI{display:flex;flex-direction:row-reverse;gap:.25rem;margin-right:-2.25rem;margin-top:.75rem}[class=yst-root] .styles-module__logo--JhJ6O{background-color:var(--yoast-color-primary);display:inline-block;height:1rem;margin-top:.125rem;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:1rem}[class=yst-root] div.styles-module__skeletonWrapperTop--TovVH{display:flex;gap:.25rem;justify-content:space-between}[class=yst-root] span.styles-module__skeleton--u4mld{height:18px;width:18px}[class=yst-root] div.styles-module__skeletonLoaderWrapper--HI7Rm{flex-grow:1}[class=yst-root] span.styles-module__skeletonLoader1--acDyN{height:1rem;width:100%}[class=yst-root] span.styles-module__skeletonLoader2--f4AbH{height:1rem;margin-top:.25rem;width:100%}[class=yst-root] span.styles-module__skeletonLoader3--pI6W5{height:1rem;margin-top:.125rem;width:100%}[class=yst-root] span.styles-module__skeletonLoader4--l4uCY{height:1rem;margin-top:.125rem;width:8rem}[class=yst-root] div.styles-module__skeletonWrapperBottom--HMog6{align-items:center;display:flex;gap:.25rem;justify-content:flex-end;margin-left:-.75rem;margin-top:1rem}[class=yst-root] span.styles-module__skeletonLoaderButtons--HkdNq{height:1.75rem;width:4rem}[class=yst-root] .styles-module__toastContentWrapper--e321x{display:flex;justify-content:flex-end}[class=yst-root] .styles-module__toastContentWrapper--e321x div:last-child{display:inline-block!important}[class=yst-root] .styles-module__toastContentContainer--UNMow{margin-left:.75rem;margin-right:1rem}[class=yst-root] .styles-module__toastContentContainerHeader--L5Dw3{align-items:center;display:flex;gap:.5rem;margin-bottom:.25rem}[class=yst-root] .styles-module__toastContentLink--cZjl1{align-items:center;display:inline-flex;font-size:.75rem;font-weight:500;gap:.25rem;margin-top:.5rem}[class=yst-root] .styles-module__toastContentArrow--xnqYS{height:1rem;width:1rem}[class=yst-root] .styles-module__toastContentArrow--xnqYS:where([dir=rtl],[dir=rtl] *){--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}[class=yst-root] .styles-module__toastContentButtonsWrapper--YHI5c{display:flex;gap:.75rem;justify-content:flex-end;margin-left:-.75rem;margin-top:.5rem}[class=yst-root] .styles-module__toastContentApplyButton--SlRYX{padding-left:.5rem;padding-right:.5rem}[class=yst-root] .styles-module__toastContentApplyButton--SlRYX .styles-module__buttonIcon--v49u_{height:1rem;width:1rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}[class=yst-root] .styles-module__toastContentApplyButton--SlRYX .styles-module__buttonText--ec2s0{margin-left:.25rem;margin-right:.25rem}[class=yst-root] div.styles-module__modal--CWdoh{z-index:1050}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43{border-radius:1.5rem;display:inline-block;max-width:512px;overflow:hidden;padding:0;position:relative;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));text-align:left;vertical-align:bottom;--tw-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}@media (min-width:640px){[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43{margin:2rem 1rem;vertical-align:middle}}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43 [class=yst-modal__close] button{background-color:initial}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__modalContainer--RcX43 [class=yst-modal__close] button svg{height:1.5rem;width:1.5rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__bigModal--xut4N{max-width:48rem}[class=yst-root] div.styles-module__modal--CWdoh .styles-module__bigModal--xut4N .styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt .styles-module__main--KD5ki{margin-top:2rem}.styles-module__badge--anxyN{position:absolute;right:16px;top:-12px}.styles-module__consentModal--A_0w0,.styles-module__introModal--rMyze{align-items:center;display:flex;flex-direction:column;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity));max-width:512px;padding:2.5rem 2.5rem 1rem}.styles-module__consentModal--A_0w0 .styles-module__top--Jckd_,.styles-module__introModal--rMyze .styles-module__top--Jckd_{height:340px;inset:0;position:absolute;--tw-bg-opacity:0.25;background-image:linear-gradient(to bottom,var(--tw-gradient-stops));--tw-gradient-from:#a61e6940 var(--tw-gradient-from-position);--tw-gradient-to:#a61e6900 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to);--tw-gradient-to:#ffffff40 var(--tw-gradient-to-position)}.styles-module__consentModal--A_0w0 .styles-module__content--s8aPG,.styles-module__introModal--rMyze .styles-module__content--s8aPG{align-items:center;display:flex;flex-direction:column;justify-content:center;position:relative;text-align:center}.styles-module__consentModal--A_0w0 .styles-module__image--EZwCo,.styles-module__introModal--rMyze .styles-module__image--EZwCo{aspect-ratio:16/9;border-radius:.5rem;overflow:hidden;width:100%;--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.styles-module__consentModal--A_0w0 .styles-module__title--upMch,.styles-module__introModal--rMyze .styles-module__title--upMch{font-size:1.125rem;font-weight:500;margin-top:1.5rem;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.styles-module__consentModal--A_0w0 .styles-module__checkbox--BNgin,.styles-module__introModal--rMyze .styles-module__checkbox--BNgin{align-items:flex-start;border-top-width:1px;font-size:.75rem;margin-top:1.25rem;padding-top:1rem;text-align:left;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.styles-module__consentModal--A_0w0 .styles-module__checkbox--BNgin label,.styles-module__introModal--rMyze .styles-module__checkbox--BNgin label{font-size:.75rem;font-weight:400;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.styles-module__consentModal--A_0w0 .styles-module__buttons--Synlt,.styles-module__introModal--rMyze .styles-module__buttons--Synlt{display:flex;flex-direction:column;gap:.75rem;margin-top:1.5rem;width:100%}.styles-module__consentModal--A_0w0 .styles-module__learnMoreLink--ZdsMp,.styles-module__introModal--rMyze .styles-module__learnMoreLink--ZdsMp{font-weight:500;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity));-webkit-text-decoration-line:none;text-decoration-line:none}.styles-module__introModal--rMyze{max-width:48rem;padding:2.5rem}.styles-module__introModal--rMyze .styles-module__separator--uFWrD{margin-top:1.5rem;width:100%;--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__mainVideo--jjRHv{overflow:visible;position:relative;width:100%}.styles-module__introModal--rMyze .styles-module__mainVideo--jjRHv .styles-module__video--QfVLI{aspect-ratio:16/9;border-radius:.5rem;overflow:hidden;width:100%;--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.styles-module__introModal--rMyze .styles-module__mainVideo--jjRHv .styles-module__video--QfVLI>*{max-width:100%}.styles-module__introModal--rMyze .styles-module__learnMoreLink--ZdsMp{align-items:center;display:inline-flex;font-weight:500;gap:.25rem;-webkit-text-decoration-line:none;text-decoration-line:none}.styles-module__introModal--rMyze .styles-module__titleSection--uRoF8{align-items:center;display:flex;font-size:.75rem;font-weight:500;margin-top:1.5rem;max-width:600px}.styles-module__introModal--rMyze .styles-module__titleSection--uRoF8 .styles-module__byline--eXZ9f{text-transform:uppercase;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity));letter-spacing:.8px;margin-left:8px}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV{margin-left:.375rem;margin-right:.375rem;margin-top:1rem;max-width:600px;text-align:center}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentHeader--b2brO{font-size:1.125rem;font-weight:500;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentText--dnFSm{font-size:.8125rem;margin-top:.5rem;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentText--dnFSm .styles-module__contentIcon--aE3SN{height:1rem;width:1rem}.styles-module__introModal--rMyze .styles-module__mainContentSection--DEAYV .styles-module__mainContentText--dnFSm .styles-module__contentIcon--aE3SN:where([dir=rtl],[dir=rtl] *){--tw-rotate:180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.styles-module__introModal--rMyze .styles-module__interactionSection--htDGA{align-items:flex-start;display:flex;margin-top:1rem}.styles-module__introModal--rMyze .styles-module__interactionSection--htDGA .styles-module__consentCheck--adf26:before{--tw-content:none;content:var(--tw-content)}.styles-module__introModal--rMyze .styles-module__interactionSection--htDGA .styles-module__consentLabel--JOn4k{font-size:.8125rem;font-weight:400;margin-left:.75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity))}.styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt{display:flex;margin-top:1rem;width:100%}.styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt .styles-module__main--KD5ki{flex-grow:1}.styles-module__introModal--rMyze .styles-module__buttonSection--fA_Lt .styles-module__close--nBst_{margin-top:1rem}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd{align-items:flex-start;display:flex}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd{align-items:flex-start;display:flex}}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__warningIconContainer--NcQlL{align-items:center;border-radius:9999px;display:flex;flex-shrink:0;height:3rem;justify-content:center;margin-left:auto;margin-right:auto;width:3rem;--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__warningIconContainer--NcQlL{height:2.5rem;margin-left:0;margin-right:0;width:2.5rem}}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__icon--ap2v5{height:1.5rem;width:1.5rem;--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__prompt--KATqc{margin-top:.75rem;text-align:center}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__prompt--KATqc{margin-left:1rem;margin-top:0;text-align:left}}.styles-module__warningPrompt--FUbHc .styles-module__body--c3lMd .styles-module__prompt--KATqc .styles-module__content--s8aPG{font-size:.8125rem;margin-top:.5rem;padding-bottom:1rem;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.styles-module__warningPrompt--FUbHc .styles-module__buttonSection--fA_Lt{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:.5rem}@media (min-width:640px){.styles-module__warningPrompt--FUbHc .styles-module__buttonSection--fA_Lt{flex-direction:row-reverse}}.styles-module__logo--cl0TH{background-color:var(--yoast-color-primary);display:inline-block;height:1.25rem;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:1.25rem}.styles-module__errorModalHeader--_cNpd{align-items:center;display:flex;gap:.5rem;justify-content:flex-start}.styles-module__errorModalContentWrapper--c24iV{display:flex;flex-direction:column;margin-top:1.5rem}.styles-module__errorModalContentWrapper--c24iV>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.styles-module__errorModalLogo--X11B0{height:1.25rem;width:1.25rem}.styles-module__errorModalTitle--vms_Y{font-size:1.125rem;margin-inline-end:.375rem;margin-inline-start:.75rem;margin-left:.75rem;margin-right:.375rem}.styles-module__questionMarkCircle--rbmIj{height:1rem;width:1rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.styles-module__aiErrorModalLink--WHw0z{margin-right:.5rem;-webkit-text-decoration-line:none;text-decoration-line:none}.styles-module__errorModalButtonsWrapper--zknbB{display:flex;margin-bottom:.25rem;margin-top:1.5rem;place-content:end}.styles-module__errorModalButtonsWrapper--zknbB>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.75rem*var(--tw-space-x-reverse))}.styles-module__errorModalButtonsWrapper--zknbB:where([dir=rtl],[dir=rtl] *)>:not([hidden])~:not([hidden]){--tw-space-x-reverse:1}@media (max-height:840px){[class=yst-root] div.styles-module__modal--CWdoh{height:100%;overflow:scroll;padding:0;position:fixed;text-align:center}[class=yst-root] div.styles-module__modal--CWdoh div[class=yst-modal__layout]{display:block;position:relative}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/ai-generator-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/ai-generator-2711-rtl.css new file mode 100644 index 0000000..5db1e53 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/ai-generator-2711-rtl.css @@ -0,0 +1 @@ +.yst-root .yst-logo-icon{background-color:var(--yoast-color-primary);display:inline-block;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%}.yst-root .yst-ai-mode .yst-radio-group__options{flex-direction:row;gap:1.5rem}.yst-root .yst-length-progress-bar.yst-score-good .yst-progress-bar__progress{background-color:#7ad03a}.yst-root .yst-length-progress-bar.yst-score-ok .yst-progress-bar__progress{background-color:#ee7c1b}.yst-root .yst-length-progress-bar.yst-score-bad .yst-progress-bar__progress{background-color:#dc3232}.yst-root .yst-suggestions-radio-group .yst-radio-group__options{gap:0}.yst-root .yst-suggestions-radio-group .yst-radio-group__options>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(-1px*var(--tw-space-y-reverse));margin-top:calc(-1px*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-introduction-modal .yst-modal__close-button{background-color:initial;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.yst-root .yst-introduction-modal .yst-modal__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-width:0px}.yst-root .yst-ai-modal .yst-modal__panel{overflow:visible}.yst-root .yst-revoke-button .yst-animate-spin{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.yst-root #facebookPreview,.yst-root #twitterPreview,.yst-root #yoast-snippet-preview-container{margin-right:auto;margin-left:auto;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.yst-root #yoast-snippet-preview-container{border-bottom:1px hidden #fff;border-radius:8px;box-shadow:0 1px 6px #20212447}.yst-root .yst-ai-generator-preview-section{margin-right:-1.5rem;margin-left:-1.5rem;padding:.5rem;position:relative}.yst-root .yst-ai-generator-preview-section:before{background-image:linear-gradient(-97.38deg,#a61e69,#6366f1);border-radius:9999px;content:"";filter:blur(32px);height:72%;right:10%;opacity:.15;position:absolute;top:2.25rem;width:80%;z-index:-1}.yst-root .yst-ai-generator-preview-section.mobile:before{right:13%;width:74%}.yst-root .yoast-snippet-preview-container__wrapper{background-color:initial}.yst-root .desktop #yoast-snippet-preview-container{padding:12px 16px}.yst-root .desktop.yst-user-agent__mobile .yoast-snippet-preview-section{padding:0}.yst-root .desktop.yst-user-agent__mobile .yoast-snippet-preview-container__wrapper{position:relative}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container{--yst-padding-bottom:12px}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container:has(+div){--yst-padding-bottom:calc(2rem + 22px)}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container{background-color:initial;border-bottom:none;border-radius:0;box-shadow:none;display:grid;padding-bottom:var(--yst-padding-bottom);padding-right:.5rem;padding-left:.5rem;padding-top:.5rem}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container>div:first-child{margin-right:auto;margin-left:auto;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));border-bottom:1px hidden #fff;border-radius:8px;box-shadow:0 1px 6px #20212447;padding:12px 16px;width:inherit}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container+div{align-items:center;bottom:0;display:flex;height:calc(2rem + 22px);justify-content:center;right:.5rem;margin:0;pointer-events:none;position:absolute;left:.5rem}.yst-root .yst-border-gradient{border-image:linear-gradient(to bottom right,#cd82ab,#a5b4fc) 1;position:relative;z-index:0}.yst-root .yst-border-gradient:before{background:linear-gradient(to bottom left,#cd82ab,#a5b4fc);border-radius:inherit;bottom:0;content:"";right:0;mask:linear-gradient(#fff,#fff) content-box,linear-gradient(#fff,#fff) border-box;mask-composite:exclude;padding:1px;position:absolute;left:0;top:0;z-index:-1}.yst-root svg.yst-ai-counter-badge__sparkles-icon path{stroke-width:1.3!important}.yst-root .yst-ai-counter-badge__skeleton{border-radius:9999px!important} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/ai-generator-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/ai-generator-2711.css new file mode 100644 index 0000000..5ec2c2e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/ai-generator-2711.css @@ -0,0 +1 @@ +.yst-root .yst-logo-icon{background-color:var(--yoast-color-primary);display:inline-block;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%}.yst-root .yst-ai-mode .yst-radio-group__options{flex-direction:row;gap:1.5rem}.yst-root .yst-length-progress-bar.yst-score-good .yst-progress-bar__progress{background-color:#7ad03a}.yst-root .yst-length-progress-bar.yst-score-ok .yst-progress-bar__progress{background-color:#ee7c1b}.yst-root .yst-length-progress-bar.yst-score-bad .yst-progress-bar__progress{background-color:#dc3232}.yst-root .yst-suggestions-radio-group .yst-radio-group__options{gap:0}.yst-root .yst-suggestions-radio-group .yst-radio-group__options>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(-1px*var(--tw-space-y-reverse));margin-top:calc(-1px*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-introduction-modal .yst-modal__close-button{background-color:initial;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.yst-root .yst-introduction-modal .yst-modal__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-width:0px}.yst-root .yst-ai-modal .yst-modal__panel{overflow:visible}.yst-root .yst-revoke-button .yst-animate-spin{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.yst-root #facebookPreview,.yst-root #twitterPreview,.yst-root #yoast-snippet-preview-container{margin-left:auto;margin-right:auto;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.yst-root #yoast-snippet-preview-container{border-bottom:1px hidden #fff;border-radius:8px;box-shadow:0 1px 6px #20212447}.yst-root .yst-ai-generator-preview-section{margin-left:-1.5rem;margin-right:-1.5rem;padding:.5rem;position:relative}.yst-root .yst-ai-generator-preview-section:before{background-image:linear-gradient(97.38deg,#a61e69,#6366f1);border-radius:9999px;content:"";filter:blur(32px);height:72%;left:10%;opacity:.15;position:absolute;top:2.25rem;width:80%;z-index:-1}.yst-root .yst-ai-generator-preview-section.mobile:before{left:13%;width:74%}.yst-root .yoast-snippet-preview-container__wrapper{background-color:initial}.yst-root .desktop #yoast-snippet-preview-container{padding:12px 16px}.yst-root .desktop.yst-user-agent__mobile .yoast-snippet-preview-section{padding:0}.yst-root .desktop.yst-user-agent__mobile .yoast-snippet-preview-container__wrapper{position:relative}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container{--yst-padding-bottom:12px}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container:has(+div){--yst-padding-bottom:calc(2rem + 22px)}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container{background-color:initial;border-bottom:none;border-radius:0;box-shadow:none;display:grid;padding-bottom:var(--yst-padding-bottom);padding-left:.5rem;padding-right:.5rem;padding-top:.5rem}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container>div:first-child{margin-left:auto;margin-right:auto;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));border-bottom:1px hidden #fff;border-radius:8px;box-shadow:0 1px 6px #20212447;padding:12px 16px;width:inherit}.yst-root .desktop.yst-user-agent__mobile #yoast-snippet-preview-container+div{align-items:center;bottom:0;display:flex;height:calc(2rem + 22px);justify-content:center;left:.5rem;margin:0;pointer-events:none;position:absolute;right:.5rem}.yst-root .yst-border-gradient{border-image:linear-gradient(to bottom right,#cd82ab,#a5b4fc) 1;position:relative;z-index:0}.yst-root .yst-border-gradient:before{background:linear-gradient(to bottom right,#cd82ab,#a5b4fc);border-radius:inherit;bottom:0;content:"";left:0;mask:linear-gradient(#fff,#fff) content-box,linear-gradient(#fff,#fff) border-box;mask-composite:exclude;padding:1px;position:absolute;right:0;top:0;z-index:-1}.yst-root svg.yst-ai-counter-badge__sparkles-icon path{stroke-width:1.3!important}.yst-root .yst-ai-counter-badge__skeleton{border-radius:9999px!important} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/alerts-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/alerts-2711-rtl.css new file mode 100644 index 0000000..273a5d8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/alerts-2711-rtl.css @@ -0,0 +1 @@ +.yoast-alert{align-items:flex-start;border:1px solid #0003;display:flex;font-size:13px;line-height:1.5;margin:16px 0;padding:16px}.yoast-alert--error{background:#f9dcdc;color:#8f1919}.yoast-alert--info{background:#cce5ff;color:#00468f}.yoast-alert--success{background:#e2f2cc;color:#395315}.yoast-alert--warning{background:#fff3cd;color:#674e00}.yoast-alert__icon.yoast-alert__icon{display:block;height:16px;margin-left:8px;margin-top:.1rem;max-width:none;width:16px}.yoast-alert a{color:#004973} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/alerts-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/alerts-2711.css new file mode 100644 index 0000000..275d7f7 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/alerts-2711.css @@ -0,0 +1 @@ +.yoast-alert{align-items:flex-start;border:1px solid #0003;display:flex;font-size:13px;line-height:1.5;margin:16px 0;padding:16px}.yoast-alert--error{background:#f9dcdc;color:#8f1919}.yoast-alert--info{background:#cce5ff;color:#00468f}.yoast-alert--success{background:#e2f2cc;color:#395315}.yoast-alert--warning{background:#fff3cd;color:#674e00}.yoast-alert__icon.yoast-alert__icon{display:block;height:16px;margin-right:8px;margin-top:.1rem;max-width:none;width:16px}.yoast-alert a{color:#004973} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/black-friday-banner-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/black-friday-banner-2711-rtl.css new file mode 100644 index 0000000..a7ac509 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/black-friday-banner-2711-rtl.css @@ -0,0 +1 @@ +.sidebar__sale_banner_container .sidebar__sale_banner{box-shadow:0 -1px 4px 0 #fcd34d,0 1px 4px 0 #fcd34d,0 -1px 0 0 #fcd34d,0 1px 0 0 #fcd34d;color:#fcd34d;letter-spacing:.5px;line-height:30px;margin-bottom:10px;margin-right:-30px;margin-top:2.5rem;width:calc(100% + 60px);--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1));font-size:1.125rem;font-weight:700;padding:.25rem 0;text-align:center}.sidebar__sale_banner_container .sidebar__sale_banner .banner_text{display:inline-block;margin:0 35px}.sidebar__sale_banner_container{margin-bottom:-25px;margin-right:-24px;margin-top:-25px;overflow:hidden;padding-bottom:10px;width:calc(100% + 48px)} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/black-friday-banner-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/black-friday-banner-2711.css new file mode 100644 index 0000000..00d4e8c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/black-friday-banner-2711.css @@ -0,0 +1 @@ +.sidebar__sale_banner_container .sidebar__sale_banner{box-shadow:0 -1px 4px 0 #fcd34d,0 1px 4px 0 #fcd34d,0 -1px 0 0 #fcd34d,0 1px 0 0 #fcd34d;color:#fcd34d;letter-spacing:.5px;line-height:30px;margin-bottom:10px;margin-left:-30px;margin-top:2.5rem;width:calc(100% + 60px);--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1));font-size:1.125rem;font-weight:700;padding:.25rem 0;text-align:center}.sidebar__sale_banner_container .sidebar__sale_banner .banner_text{display:inline-block;margin:0 35px}.sidebar__sale_banner_container{margin-bottom:-25px;margin-left:-24px;margin-top:-25px;overflow:hidden;padding-bottom:10px;width:calc(100% + 48px)} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/block-editor-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/block-editor-2711-rtl.css new file mode 100644 index 0000000..050e2ac --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/block-editor-2711-rtl.css @@ -0,0 +1 @@ +.editor-styles-wrapper mark.annotation-text-yoast{background-color:#e1bee7} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/block-editor-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/block-editor-2711.css new file mode 100644 index 0000000..050e2ac --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/block-editor-2711.css @@ -0,0 +1 @@ +.editor-styles-wrapper mark.annotation-text-yoast{background-color:#e1bee7} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/dashboard-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/dashboard-2711-rtl.css new file mode 100644 index 0000000..51f5b70 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/dashboard-2711-rtl.css @@ -0,0 +1 @@ +#yoast-seo-dashboard-widget h3{font-weight:700}#yoast-seo-dashboard-widget .assessments,#yoast-seo-dashboard-widget .score-assessments{padding-right:0}#yoast-seo-dashboard-widget .wordpress-feed{border-top:1px solid #eee;margin:16px -12px 0;padding:12px 12px 0}#yoast-seo-dashboard-widget .wordpress-feed .wordpress-feed__post{margin-top:12px}#yoast-seo-dashboard-widget .wordpress-feed .wordpress-feed__footer{border-top:1px solid #eee;margin:0 -12px;padding:4px 12px 0}#yoast-seo-dashboard-widget:empty:before,#yoast-seo-wincher-dashboard-widget:empty:before{animation:rotate 2s linear infinite;background-image:url(../../packages/js/images/Yoast_SEO_Icon.svg);content:"";display:block;height:40px;margin:25px auto;width:40px}@keyframes rotate{0%{transform:perspective(120px) rotateX(0deg) rotateY(0deg);-webkit-transform:perspective(120px) rotateX(0deg) rotateY(0deg)}to{transform:perspective(120px) rotateX(0deg) rotateY(-1turn);-webkit-transform:perspective(120px) rotateX(0deg) rotateY(-1turn)}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/dashboard-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/dashboard-2711.css new file mode 100644 index 0000000..c9a8212 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/dashboard-2711.css @@ -0,0 +1 @@ +#yoast-seo-dashboard-widget h3{font-weight:700}#yoast-seo-dashboard-widget .assessments,#yoast-seo-dashboard-widget .score-assessments{padding-left:0}#yoast-seo-dashboard-widget .wordpress-feed{border-top:1px solid #eee;margin:16px -12px 0;padding:12px 12px 0}#yoast-seo-dashboard-widget .wordpress-feed .wordpress-feed__post{margin-top:12px}#yoast-seo-dashboard-widget .wordpress-feed .wordpress-feed__footer{border-top:1px solid #eee;margin:0 -12px;padding:4px 12px 0}#yoast-seo-dashboard-widget:empty:before,#yoast-seo-wincher-dashboard-widget:empty:before{animation:rotate 2s linear infinite;background-image:url(../../packages/js/images/Yoast_SEO_Icon.svg);content:"";display:block;height:40px;margin:25px auto;width:40px}@keyframes rotate{0%{transform:perspective(120px) rotateX(0deg) rotateY(0deg);-webkit-transform:perspective(120px) rotateX(0deg) rotateY(0deg)}to{transform:perspective(120px) rotateX(0deg) rotateY(1turn);-webkit-transform:perspective(120px) rotateX(0deg) rotateY(1turn)}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/edit-page-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/edit-page-2711-rtl.css new file mode 100644 index 0000000..85c0742 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/edit-page-2711-rtl.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 3px 0 10px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe}@media screen and (max-width:782px){.wpseo-score-icon{margin-right:0!important;margin-left:0}.wpseo-score-icon .wpseo-score-text{display:none}.wpseo-cornerstone svg{margin-right:-4px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/edit-page-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/edit-page-2711.css new file mode 100644 index 0000000..763029b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/edit-page-2711.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 10px 0 3px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe}@media screen and (max-width:782px){.wpseo-score-icon{margin-left:0!important;margin-right:0}.wpseo-score-icon .wpseo-score-text{display:none}.wpseo-cornerstone svg{margin-left:-4px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/elementor-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/elementor-2711-rtl.css new file mode 100644 index 0000000..e46819a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/elementor-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-elementor-color-paragraph:#555d66}.yoast,.yoast h2,.yoast h3{font-family:var(--yoast-font-family)!important}.yoast h2{color:var(--yoast-color-dark);font-size:1.3em;font-weight:var(--yoast-font-weight-bold);margin-bottom:1em}.yoast input,.yoast input:focus,.yoast label,.yoast select:focus,.yoast select:not(:focus){background-color:#0000;border-color:var(--yoast-color-secondary-darker);color:var(--yoast-color-font-default)}.yoast label{color:var(--yoast-color-label)}.yoast input[disabled]{background-color:var(--yoast-color-inactive-grey-light)}.yoast.components-panel__body .yoast-title{font-weight:500}.yoast-field-group__title b{font-weight:var(--yoast-font-weight-bold)}.yoast h3 span>span{font-weight:400}.elementor-tab-control-yoast-seo-tab span:before,.yoast-element-menu-icon:before,.yoast-panel-icon:before{background-color:currentColor;content:" ";height:16px;margin:0 auto;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:16px}.yoast-element-menu-icon,.yoast-panel-icon{display:inline-flex}.yoast-element-menu-icon:before,.yoast-panel-icon:before{height:19px;width:19px}.yoast-elementor-panel__fills{background-color:var(--yoast-color-white);color:var(--yoast-color-dark);-webkit-font-smoothing:subpixel-antialiased}#yoast-seo-elementor-panel{height:100%;overflow-y:auto;padding:20px}.yoast-elementor-panel__content{background-color:var(--yoast-color-white);height:calc(100vh - 200px);overflow-y:auto}.yoast-elementor-panel{display:flex;flex-direction:column;height:100%}.yoast li,.yoast p,.yoast small{line-height:1.5;margin-bottom:6px}.yoast p,.yoast small,.yoast ul[role=list] li{color:var(--yoast-elementor-color-paragraph)}.button-link,.yoast a,.yoast a p,.yoast-elementor-panel__fills p a{color:var(--yoast-color-link);text-decoration:underline}.yoast a.dashicons{color:var(--yoast-color-inactive-text);height:24px;vertical-align:text-bottom;width:24px}.button-link{background:none;border:none;cursor:pointer;font-size:1em;line-height:1.5}.yoast .yoast-button-upsell,.yoast-elementor-panel__fills .UpsellLinkButton{color:var(--yoast-color-label);line-height:1.4em;text-decoration:none}.yoast-elementor-panel__fills h3>button{background:none;border:none;box-shadow:none}.yoast-gutenberg-modal .yoast-notice-container>hr{border-top-color:#ddd;border-top-style:solid}.yoast-gutenberg-modal input[type=radio]{-webkit-appearance:none;-moz-appearance:none;border:var(--yoast-border-default);border-radius:50%;box-shadow:inset 0 2px 4px #0000001a;cursor:pointer;height:18px;margin:0 0 0 8px;overflow:hidden;padding:2px;position:relative;transition:all .15s ease-out 0s;vertical-align:text-bottom;width:18px}.yoast-gutenberg-modal input[type=radio]:checked{background-color:inherit;border-color:var(--yoast-color-primary)}.yoast-gutenberg-modal input[type=radio]:checked:after{background:var(--yoast-color-primary);border-radius:50%;content:"";display:block;height:10px;right:3px;position:absolute;top:3px;width:10px}.yoast-post-settings-modal .yoast-notice-container{bottom:auto}.yoast-gutenberg-modal .components-popover.components-tooltip{right:unset!important;position:relative;left:40px;top:15px!important}.yoast div:focus,div.yoast:focus{outline:0}.yoast .button-link:focus,.yoast a:focus{box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc;color:#124964;outline:1px solid #0000}.yoast a.dashicons:focus{color:#1e8cbe}.yoast input[type=radio]:checked:focus{border-color:#fff;box-shadow:var(--yoast-color-focus)}.yoast .yoast-button-upsell:focus{box-shadow:inset 0 -4px 0 #0003,0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc;color:#000}.yoast-elementor-introduction{background-color:#fff;box-shadow:var(--yoast-shadow-default);padding:20px;position:absolute!important;text-align:right;z-index:1}#yoast-introduction{border-radius:3px;right:41px!important;top:5px!important}#yoast-introduction-editor-v2{border:1px solid #000;border-radius:8px}.yoast-elementor-introduction:before{border:solid #0000;content:"";position:absolute}#yoast-introduction:before{border-bottom-color:#fff;border-width:7px 5px;right:-12px;top:8px;transform:rotate(90deg)}#yoast-introduction-editor-v2:before{border-bottom-color:#000;border-width:10px 8px;right:var(--yoast-elementor-introduction-arrow,28%);top:-20px}.yoast-elementor-introduction>div{color:var(--yoast-color-default)}.yoast-elementor-introduction>.dialog-header{font-weight:var(--yoast-font-weight-bold);line-height:1.3}.yoast-elementor-introduction>.dialog-message{margin-top:.5em}.yoast-elementor-introduction>.dialog-buttons-wrapper{display:flex;justify-content:flex-end;margin-top:12px}#yoast-introduction .dialog-button,#yoast-introduction-editor-v2 .dialog-button{background-color:var(--yoast-color-primary);font-size:12px;padding:7px 17px}@media(hover:hover){.button-link:hover,.yoast a:hover,.yoast a:hover p,.yoast-elementor-panel__fills p a:hover{color:var(--yoast-color-primary-darker)}.yoast a.dashicons:hover{color:var(--yoast-color-link)}.yoast .yoast-button-upsell:hover,.yoast-elementor-panel__fills .UpsellLinkButton:hover{color:var(--yoast-color-label)}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/elementor-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/elementor-2711.css new file mode 100644 index 0000000..7ed61f3 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/elementor-2711.css @@ -0,0 +1 @@ +:root{--yoast-elementor-color-paragraph:#555d66}.yoast,.yoast h2,.yoast h3{font-family:var(--yoast-font-family)!important}.yoast h2{color:var(--yoast-color-dark);font-size:1.3em;font-weight:var(--yoast-font-weight-bold);margin-bottom:1em}.yoast input,.yoast input:focus,.yoast label,.yoast select:focus,.yoast select:not(:focus){background-color:#0000;border-color:var(--yoast-color-secondary-darker);color:var(--yoast-color-font-default)}.yoast label{color:var(--yoast-color-label)}.yoast input[disabled]{background-color:var(--yoast-color-inactive-grey-light)}.yoast.components-panel__body .yoast-title{font-weight:500}.yoast-field-group__title b{font-weight:var(--yoast-font-weight-bold)}.yoast h3 span>span{font-weight:400}.elementor-tab-control-yoast-seo-tab span:before,.yoast-element-menu-icon:before,.yoast-panel-icon:before{background-color:currentColor;content:" ";height:16px;margin:0 auto;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:16px}.yoast-element-menu-icon,.yoast-panel-icon{display:inline-flex}.yoast-element-menu-icon:before,.yoast-panel-icon:before{height:19px;width:19px}.yoast-elementor-panel__fills{background-color:var(--yoast-color-white);color:var(--yoast-color-dark);-webkit-font-smoothing:subpixel-antialiased}#yoast-seo-elementor-panel{height:100%;overflow-y:auto;padding:20px}.yoast-elementor-panel__content{background-color:var(--yoast-color-white);height:calc(100vh - 200px);overflow-y:auto}.yoast-elementor-panel{display:flex;flex-direction:column;height:100%}.yoast li,.yoast p,.yoast small{line-height:1.5;margin-bottom:6px}.yoast p,.yoast small,.yoast ul[role=list] li{color:var(--yoast-elementor-color-paragraph)}.button-link,.yoast a,.yoast a p,.yoast-elementor-panel__fills p a{color:var(--yoast-color-link);text-decoration:underline}.yoast a.dashicons{color:var(--yoast-color-inactive-text);height:24px;vertical-align:text-bottom;width:24px}.button-link{background:none;border:none;cursor:pointer;font-size:1em;line-height:1.5}.yoast .yoast-button-upsell,.yoast-elementor-panel__fills .UpsellLinkButton{color:var(--yoast-color-label);line-height:1.4em;text-decoration:none}.yoast-elementor-panel__fills h3>button{background:none;border:none;box-shadow:none}.yoast-gutenberg-modal .yoast-notice-container>hr{border-top-color:#ddd;border-top-style:solid}.yoast-gutenberg-modal input[type=radio]{-webkit-appearance:none;-moz-appearance:none;border:var(--yoast-border-default);border-radius:50%;box-shadow:inset 0 2px 4px #0000001a;cursor:pointer;height:18px;margin:0 8px 0 0;overflow:hidden;padding:2px;position:relative;transition:all .15s ease-out 0s;vertical-align:text-bottom;width:18px}.yoast-gutenberg-modal input[type=radio]:checked{background-color:inherit;border-color:var(--yoast-color-primary)}.yoast-gutenberg-modal input[type=radio]:checked:after{background:var(--yoast-color-primary);border-radius:50%;content:"";display:block;height:10px;left:3px;position:absolute;top:3px;width:10px}.yoast-post-settings-modal .yoast-notice-container{bottom:auto}.yoast-gutenberg-modal .components-popover.components-tooltip{left:unset!important;position:relative;right:40px;top:15px!important}.yoast div:focus,div.yoast:focus{outline:0}.yoast .button-link:focus,.yoast a:focus{box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc;color:#124964;outline:1px solid #0000}.yoast a.dashicons:focus{color:#1e8cbe}.yoast input[type=radio]:checked:focus{border-color:#fff;box-shadow:var(--yoast-color-focus)}.yoast .yoast-button-upsell:focus{box-shadow:inset 0 -4px 0 #0003,0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc;color:#000}.yoast-elementor-introduction{background-color:#fff;box-shadow:var(--yoast-shadow-default);padding:20px;position:absolute!important;text-align:left;z-index:1}#yoast-introduction{border-radius:3px;left:41px!important;top:5px!important}#yoast-introduction-editor-v2{border:1px solid #000;border-radius:8px}.yoast-elementor-introduction:before{border:solid #0000;content:"";position:absolute}#yoast-introduction:before{border-bottom-color:#fff;border-width:7px 5px;left:-12px;top:8px;transform:rotate(-90deg)}#yoast-introduction-editor-v2:before{border-bottom-color:#000;border-width:10px 8px;left:var(--yoast-elementor-introduction-arrow,28%);top:-20px}.yoast-elementor-introduction>div{color:var(--yoast-color-default)}.yoast-elementor-introduction>.dialog-header{font-weight:var(--yoast-font-weight-bold);line-height:1.3}.yoast-elementor-introduction>.dialog-message{margin-top:.5em}.yoast-elementor-introduction>.dialog-buttons-wrapper{display:flex;justify-content:flex-end;margin-top:12px}#yoast-introduction .dialog-button,#yoast-introduction-editor-v2 .dialog-button{background-color:var(--yoast-color-primary);font-size:12px;padding:7px 17px}@media(hover:hover){.button-link:hover,.yoast a:hover,.yoast a:hover p,.yoast-elementor-panel__fills p a:hover{color:var(--yoast-color-primary-darker)}.yoast a.dashicons:hover{color:var(--yoast-color-link)}.yoast .yoast-button-upsell:hover,.yoast-elementor-panel__fills .UpsellLinkButton:hover{color:var(--yoast-color-label)}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/featured-image-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/featured-image-2711-rtl.css new file mode 100644 index 0000000..336c610 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/featured-image-2711-rtl.css @@ -0,0 +1 @@ +#yst_opengraph_image_warning{margin-top:0}.yoast-opengraph-image-notice #set-post-thumbnail>img{box-shadow:0 0 0 2px #fff,0 0 0 5px #dc3232} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/featured-image-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/featured-image-2711.css new file mode 100644 index 0000000..336c610 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/featured-image-2711.css @@ -0,0 +1 @@ +#yst_opengraph_image_warning{margin-top:0}.yoast-opengraph-image-notice #set-post-thumbnail>img{box-shadow:0 0 0 2px #fff,0 0 0 5px #dc3232} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/filter-explanation-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/filter-explanation-2711-rtl.css new file mode 100644 index 0000000..bd1b36e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/filter-explanation-2711-rtl.css @@ -0,0 +1 @@ +#posts-filter .wpseo-filter-explanation{clear:both;margin:10px 1px 5px} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/filter-explanation-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/filter-explanation-2711.css new file mode 100644 index 0000000..bd1b36e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/filter-explanation-2711.css @@ -0,0 +1 @@ +#posts-filter .wpseo-filter-explanation{clear:both;margin:10px 1px 5px} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/first-time-configuration-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/first-time-configuration-2711-rtl.css new file mode 100644 index 0000000..ef83130 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/first-time-configuration-2711-rtl.css @@ -0,0 +1 @@ +#yoast-configuration .yst-input{border-radius:.375rem!important;border-width:1px!important;--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))!important;font-size:.8125rem!important;padding:.5rem .75rem!important;--tw-shadow:0 1px 2px 0 #0000000d!important;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}#yoast-configuration .yst-radio{align-items:center!important;display:flex!important}#yoast-configuration .yst-radio__input{appearance:none!important;border-radius:9999px!important;border-width:1px!important;height:1rem!important;margin:0!important;width:1rem!important;--tw-border-opacity:1!important;border-color:rgb(209 213 219/var(--tw-border-opacity,1))!important;--tw-text-opacity:1!important;color:rgb(166 30 105/var(--tw-text-opacity,1))!important;--tw-shadow:0 0 #0000!important;--tw-shadow-colored:0 0 #0000!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important;transition-property:none!important}#yoast-configuration .yst-radio__input:before{content:var(--tw-content)!important;display:none!important}#yoast-configuration .yst-radio__input:checked{border-width:5px!important;--tw-border-opacity:1!important;border-color:rgb(166 30 105/var(--tw-border-opacity,1))!important}#yoast-configuration .yst-radio__input:focus{outline:2px solid #0000!important;outline-offset:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important;--tw-ring-opacity:1!important;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))!important;--tw-ring-offset-width:2px!important;--tw-ring-offset-color:#fff!important}#yoast-configuration .yst-radio__label{font-weight:500!important;margin-right:.75rem!important;--tw-text-opacity:1!important;color:rgb(30 41 59/var(--tw-text-opacity,1))!important}#yoast-configuration .yst-radio-group__label{margin-bottom:.25rem!important}#yoast-configuration .yst-radio-group__options{display:flex!important;flex-direction:column!important;gap:.5rem!important}#yoast-configuration .yst-radio-group__description{margin-bottom:1rem!important}#yoast-configuration .yst-checkbox__input:before{--tw-content:none!important;content:var(--tw-content)!important} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/first-time-configuration-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/first-time-configuration-2711.css new file mode 100644 index 0000000..83ed2ab --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/first-time-configuration-2711.css @@ -0,0 +1 @@ +#yoast-configuration .yst-input{border-radius:.375rem!important;border-width:1px!important;--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))!important;font-size:.8125rem!important;padding:.5rem .75rem!important;--tw-shadow:0 1px 2px 0 #0000000d!important;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}#yoast-configuration .yst-radio{align-items:center!important;display:flex!important}#yoast-configuration .yst-radio__input{appearance:none!important;border-radius:9999px!important;border-width:1px!important;height:1rem!important;margin:0!important;width:1rem!important;--tw-border-opacity:1!important;border-color:rgb(209 213 219/var(--tw-border-opacity,1))!important;--tw-text-opacity:1!important;color:rgb(166 30 105/var(--tw-text-opacity,1))!important;--tw-shadow:0 0 #0000!important;--tw-shadow-colored:0 0 #0000!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important;transition-property:none!important}#yoast-configuration .yst-radio__input:before{content:var(--tw-content)!important;display:none!important}#yoast-configuration .yst-radio__input:checked{border-width:5px!important;--tw-border-opacity:1!important;border-color:rgb(166 30 105/var(--tw-border-opacity,1))!important}#yoast-configuration .yst-radio__input:focus{outline:2px solid #0000!important;outline-offset:2px!important;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important;--tw-ring-opacity:1!important;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))!important;--tw-ring-offset-width:2px!important;--tw-ring-offset-color:#fff!important}#yoast-configuration .yst-radio__label{font-weight:500!important;margin-left:.75rem!important;--tw-text-opacity:1!important;color:rgb(30 41 59/var(--tw-text-opacity,1))!important}#yoast-configuration .yst-radio-group__label{margin-bottom:.25rem!important}#yoast-configuration .yst-radio-group__options{display:flex!important;flex-direction:column!important;gap:.5rem!important}#yoast-configuration .yst-radio-group__description{margin-bottom:1rem!important}#yoast-configuration .yst-checkbox__input:before{--tw-content:none!important;content:var(--tw-content)!important} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/general-page-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/general-page-2711-rtl.css new file mode 100644 index 0000000..b232d73 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/general-page-2711-rtl.css @@ -0,0 +1 @@ +body.toplevel_page_wpseo_dashboard .notice,body.toplevel_page_wpseo_dashboard .yoast-migrated-notice{display:none}body.toplevel_page_wpseo_dashboard .yoast-general-page-notices:last-child{margin-bottom:2rem}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice,body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard{background:#fff;border-radius:.375rem;border-width:1px;padding:.75rem;--tw-border-opacity:1;border-color:rgb(224 179 204/var(--tw-border-opacity,1));--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:17px;margin-left:12px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-dismiss{position:relative;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-dismiss:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-dismiss:before,body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-yoast img{display:none}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice a{font-weight:500}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard{margin-bottom:.8rem;margin-top:0}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-dismiss:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%2394A3B8' stroke-width='2' class='yst-h-5 yst-w-5' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M6 18 18 6M6 6l12 12'/%3E%3C/svg%3E");content:""}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-dismiss:hover:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%2364748b' stroke-width='2' class='yst-h-5 yst-w-5' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M6 18 18 6M6 6l12 12'/%3E%3C/svg%3E");content:""}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard p{padding-right:1.8rem}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .yoast-icon{height:17px;margin-left:12px;width:17px}body.toplevel_page_wpseo_dashboard .yoast-notice-migrated-header{color:#1e293b;font-size:.8125rem;font-weight:500;line-height:19px}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard a{font-weight:500}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-yoast__container{padding:0}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-dismiss{padding:.75rem}body.toplevel_page_wpseo_dashboard .notice-yoast__header{margin-bottom:.25rem}body.toplevel_page_wpseo_dashboard{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}body.toplevel_page_wpseo_dashboard #wpcontent{padding-right:0!important}body.toplevel_page_wpseo_dashboard #wpfooter{padding-left:1rem}@media (min-width:768px){body.toplevel_page_wpseo_dashboard #wpfooter{padding-right:17rem;padding-left:2rem}}@media screen and (max-width:782px){body.toplevel_page_wpseo_dashboard .wp-responsive-open #wpbody{left:-190px}}body.toplevel_page_wpseo_dashboard #modal-search .yst-modal__close{margin-top:-.25rem}@media (min-width:783px) and (max-width:962px){body.toplevel_page_wpseo_dashboard.sticky-menu .yst-root .yst-notifications--bottom-left{right:calc(160px + 2rem)}}@media (min-width:783px) and (max-width:963px){body.toplevel_page_wpseo_dashboard.sticky-menu.auto-fold .yst-root .yst-notifications--bottom-left,body.toplevel_page_wpseo_dashboard.sticky-menu.folded .yst-root .yst-notifications--bottom-left{right:calc(32px + 2rem)}}@media (min-width:962px){body.toplevel_page_wpseo_dashboard.sticky-menu.folded .yst-root .yst-notifications--bottom-left{right:calc(32px + 2rem)}}@media (max-width:783px){body.toplevel_page_wpseo_dashboard:not(.sticky-menu) .wp-responsive-open .yst-root .yst-notifications--bottom-left{right:calc(190px + 2rem)}}@media (min-width:601px) and (max-width:768px){body.toplevel_page_wpseo_dashboard .yst-root .yst-mobile-navigation__top{top:46px}}@media (min-width:783px){body.toplevel_page_wpseo_dashboard .yst-root .yst-mobile-navigation__top{display:none}}body.toplevel_page_wpseo_dashboard .yst-root .yst-mobile-navigation__dialog{z-index:99999}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button{align-items:center;border-radius:.375rem;border-width:1px;cursor:pointer;display:inline-flex;font-size:.8125rem;font-weight:500;line-height:1.25rem;padding:.5rem .75rem;text-align:center;-webkit-text-decoration-line:none;text-decoration-line:none;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button:disabled{cursor:not-allowed;opacity:.5;pointer-events:none}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button{font-size:.75rem;line-height:1rem;margin-bottom:unset;margin-top:.75rem;min-height:unset;padding:.375rem .625rem;vertical-align:unset;white-space:normal}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link{cursor:pointer;--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1));-webkit-text-decoration-line:underline;text-decoration-line:underline}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:visited{color:#a61e69}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:hover:visited{color:#b94986}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:focus{border-radius:.125rem;--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(79 70 229/var(--tw-ring-opacity,1));--tw-ring-offset-width:1px;--tw-ring-offset-color:#0000}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .ul-disc{list-style-type:disc;margin-right:.75rem;margin-top:.375rem;padding-right:.75rem}body.toplevel_page_wpseo_dashboard.rtl .yst-root .yst-replacevar .emoji-select-popover{right:0;left:auto} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/general-page-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/general-page-2711.css new file mode 100644 index 0000000..b0c983c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/general-page-2711.css @@ -0,0 +1 @@ +body.toplevel_page_wpseo_dashboard .notice,body.toplevel_page_wpseo_dashboard .yoast-migrated-notice{display:none}body.toplevel_page_wpseo_dashboard .yoast-general-page-notices:last-child{margin-bottom:2rem}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice,body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard{background:#fff;border-radius:.375rem;border-width:1px;padding:.75rem;--tw-border-opacity:1;border-color:rgb(224 179 204/var(--tw-border-opacity,1));--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:17px;margin-right:12px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-dismiss{position:relative;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-dismiss:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-dismiss:before,body.toplevel_page_wpseo_dashboard .yoast-general-page-notice .notice-yoast img{display:none}body.toplevel_page_wpseo_dashboard .yoast-general-page-notice a{font-weight:500}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard{margin-bottom:.8rem;margin-top:0}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-dismiss:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%2394A3B8' stroke-width='2' class='yst-h-5 yst-w-5' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M6 18 18 6M6 6l12 12'/%3E%3C/svg%3E");content:""}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-dismiss:hover:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%2364748b' stroke-width='2' class='yst-h-5 yst-w-5' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M6 18 18 6M6 6l12 12'/%3E%3C/svg%3E");content:""}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard p{padding-left:1.8rem}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .yoast-icon{height:17px;margin-right:12px;width:17px}body.toplevel_page_wpseo_dashboard .yoast-notice-migrated-header{color:#1e293b;font-size:.8125rem;font-weight:500;line-height:19px}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard a{font-weight:500}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-yoast__container{padding:0}body.toplevel_page_wpseo_dashboard .yoast-webinar-dashboard .notice-dismiss{padding:.75rem}body.toplevel_page_wpseo_dashboard .notice-yoast__header{margin-bottom:.25rem}body.toplevel_page_wpseo_dashboard{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}body.toplevel_page_wpseo_dashboard #wpcontent{padding-left:0!important}body.toplevel_page_wpseo_dashboard #wpfooter{padding-right:1rem}@media (min-width:768px){body.toplevel_page_wpseo_dashboard #wpfooter{padding-left:17rem;padding-right:2rem}}@media screen and (max-width:782px){body.toplevel_page_wpseo_dashboard .wp-responsive-open #wpbody{right:-190px}}body.toplevel_page_wpseo_dashboard #modal-search .yst-modal__close{margin-top:-.25rem}@media (min-width:783px) and (max-width:962px){body.toplevel_page_wpseo_dashboard.sticky-menu .yst-root .yst-notifications--bottom-left{left:calc(160px + 2rem)}}@media (min-width:783px) and (max-width:963px){body.toplevel_page_wpseo_dashboard.sticky-menu.auto-fold .yst-root .yst-notifications--bottom-left,body.toplevel_page_wpseo_dashboard.sticky-menu.folded .yst-root .yst-notifications--bottom-left{left:calc(32px + 2rem)}}@media (min-width:962px){body.toplevel_page_wpseo_dashboard.sticky-menu.folded .yst-root .yst-notifications--bottom-left{left:calc(32px + 2rem)}}@media (max-width:783px){body.toplevel_page_wpseo_dashboard:not(.sticky-menu) .wp-responsive-open .yst-root .yst-notifications--bottom-left{left:calc(190px + 2rem)}}@media (min-width:601px) and (max-width:768px){body.toplevel_page_wpseo_dashboard .yst-root .yst-mobile-navigation__top{top:46px}}@media (min-width:783px){body.toplevel_page_wpseo_dashboard .yst-root .yst-mobile-navigation__top{display:none}}body.toplevel_page_wpseo_dashboard .yst-root .yst-mobile-navigation__dialog{z-index:99999}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button{align-items:center;border-radius:.375rem;border-width:1px;cursor:pointer;display:inline-flex;font-size:.8125rem;font-weight:500;line-height:1.25rem;padding:.5rem .75rem;text-align:center;-webkit-text-decoration-line:none;text-decoration-line:none;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button:disabled{cursor:not-allowed;opacity:.5;pointer-events:none}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button{font-size:.75rem;line-height:1rem;margin-bottom:unset;margin-top:.75rem;min-height:unset;padding:.375rem .625rem;vertical-align:unset;white-space:normal}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link{cursor:pointer;--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1));-webkit-text-decoration-line:underline;text-decoration-line:underline}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:visited{color:#a61e69}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1))}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:hover:visited{color:#b94986}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .button-link:focus{border-radius:.125rem;--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(79 70 229/var(--tw-ring-opacity,1));--tw-ring-offset-width:1px;--tw-ring-offset-color:#0000}body.toplevel_page_wpseo_dashboard .yst-root .yst-paper .ul-disc{list-style-type:disc;margin-left:.75rem;margin-top:.375rem;padding-left:.75rem}body.toplevel_page_wpseo_dashboard.rtl .yst-root .yst-replacevar .emoji-select-popover{left:0;right:auto} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/icons-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/icons-2711-rtl.css new file mode 100644 index 0000000..1b63d67 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/icons-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/icons-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/icons-2711.css new file mode 100644 index 0000000..1b63d67 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/icons-2711.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/inside-editor-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/inside-editor-2711-rtl.css new file mode 100644 index 0000000..c7e4aab --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/inside-editor-2711-rtl.css @@ -0,0 +1 @@ +.yoast-text-mark{background-color:#e1bee7}.yoast-text-mark__highlight{background-color:#4a148c;color:#fff} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/inside-editor-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/inside-editor-2711.css new file mode 100644 index 0000000..c7e4aab --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/inside-editor-2711.css @@ -0,0 +1 @@ +.yoast-text-mark{background-color:#e1bee7}.yoast-text-mark__highlight{background-color:#4a148c;color:#fff} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/installation-success-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/installation-success-2711-rtl.css new file mode 100644 index 0000000..80ef920 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/installation-success-2711-rtl.css @@ -0,0 +1 @@ +body.admin_page_wpseo_installation_successful_free{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/installation-success-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/installation-success-2711.css new file mode 100644 index 0000000..80ef920 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/installation-success-2711.css @@ -0,0 +1 @@ +body.admin_page_wpseo_installation_successful_free{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/introductions-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/introductions-2711-rtl.css new file mode 100644 index 0000000..2bca4e0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/introductions-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,');--yoast-color-default:#404040;--yoast-color-default-darker:#303030;--yoast-color-primary:#a4286a;--yoast-color-secondary:#f7f7f7;--yoast-color-white:#fff;--yoast-color-green:#6ea029;--yoast-color-primary-darker:#7b1e50;--yoast-color-primary-lighter:#f5d6e6;--yoast-color-secondary-darker:#d9d9d9;--yoast-color-button-upsell:#fec228;--yoast-color-button-upsell-hover:#f2ae01;--yoast-color-dark:#303030;--yoast-color-sale:#fec228;--yoast-color-sale-darker:#feb601;--yoast-color-border:#0003;--yoast-color-label:#303030;--yoast-color-label-help:#707070;--yoast-color-active:#6ea029;--yoast-color-inactive:#dc3232;--yoast-color-inactive-text:#707070;--yoast-color-inactive-grey:#9e9e9e;--yoast-color-inactive-grey-light:#f1f1f1;--yoast-color-active-light:#b6cf94;--yoast-transition-default:all 150ms ease-out;--yoast-color-link:#006dac;--yoast-color-border--default:#0003;--yoast-color-focus:0 0 0 2px #007fff,0 0 0 5px #bfdfff}.yst-root .yst-introduction-modal .yst-modal__close-button{background-color:initial;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.yst-root .yst-introduction-modal .yst-modal__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-width:0px}.yst-root .yst-introduction-gradient{background:linear-gradient(-180deg,#a61e6940 10%,#fff0 80%)}.yst-root .yst-delayed-introduction-gradient{background:linear-gradient(-180deg,#e0b3cc40 25%,#fff0 75%)}.yst-root .yst-woo-introduction-gradient{background:linear-gradient(-180deg,#0075b340 10%,#fff0 80%)}.yst-root .yst-introduction-modal-uppercase{letter-spacing:.8px;text-transform:uppercase;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-logo-icon{background-color:var(--yoast-color-primary);height:17px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px}.yst-root .yst-cart-icon{background-color:#0075b3;height:16px;mask-image:var(--yoast-svg-icon-cart);-webkit-mask-image:var(--yoast-svg-icon-cart);mask-size:100% 100%;-webkit-mask-size:100% 100%;transform:scaleX(-1);-webkit-transform:scaleX(-1);width:16px}.yst-root .yst-ai-insights-icon{background-image:linear-gradient(-97deg,#a61e69,#6366f1)!important;height:17px;mask-image:var(--yoast-svg-icon-yoast-insight-sparkle);-webkit-mask-image:var(--yoast-svg-icon-yoast-insight-sparkle);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/introductions-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/introductions-2711.css new file mode 100644 index 0000000..7a7697d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/introductions-2711.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,');--yoast-color-default:#404040;--yoast-color-default-darker:#303030;--yoast-color-primary:#a4286a;--yoast-color-secondary:#f7f7f7;--yoast-color-white:#fff;--yoast-color-green:#6ea029;--yoast-color-primary-darker:#7b1e50;--yoast-color-primary-lighter:#f5d6e6;--yoast-color-secondary-darker:#d9d9d9;--yoast-color-button-upsell:#fec228;--yoast-color-button-upsell-hover:#f2ae01;--yoast-color-dark:#303030;--yoast-color-sale:#fec228;--yoast-color-sale-darker:#feb601;--yoast-color-border:#0003;--yoast-color-label:#303030;--yoast-color-label-help:#707070;--yoast-color-active:#6ea029;--yoast-color-inactive:#dc3232;--yoast-color-inactive-text:#707070;--yoast-color-inactive-grey:#9e9e9e;--yoast-color-inactive-grey-light:#f1f1f1;--yoast-color-active-light:#b6cf94;--yoast-transition-default:all 150ms ease-out;--yoast-color-link:#006dac;--yoast-color-border--default:#0003;--yoast-color-focus:0 0 0 2px #007fff,0 0 0 5px #bfdfff}.yst-root .yst-introduction-modal .yst-modal__close-button{background-color:initial;--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.yst-root .yst-introduction-modal .yst-modal__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-width:0px}.yst-root .yst-introduction-gradient{background:linear-gradient(180deg,#a61e6940 10%,#fff0 80%)}.yst-root .yst-delayed-introduction-gradient{background:linear-gradient(180deg,#e0b3cc40 25%,#fff0 75%)}.yst-root .yst-woo-introduction-gradient{background:linear-gradient(180deg,#0075b340 10%,#fff0 80%)}.yst-root .yst-introduction-modal-uppercase{letter-spacing:.8px;text-transform:uppercase;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-logo-icon{background-color:var(--yoast-color-primary);height:17px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px}.yst-root .yst-cart-icon{background-color:#0075b3;height:16px;mask-image:var(--yoast-svg-icon-cart);-webkit-mask-image:var(--yoast-svg-icon-cart);mask-size:100% 100%;-webkit-mask-size:100% 100%;transform:scaleX(-1);-webkit-transform:scaleX(-1);width:16px}.yst-root .yst-ai-insights-icon{background-image:linear-gradient(97deg,#a61e69,#6366f1)!important;height:17px;mask-image:var(--yoast-svg-icon-yoast-insight-sparkle);-webkit-mask-image:var(--yoast-svg-icon-yoast-insight-sparkle);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/metabox-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-2711-rtl.css new file mode 100644 index 0000000..338da70 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.yoast-modal__screen-overlay{animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards;background-color:#a4286a99;bottom:0;right:0;position:fixed;left:0;top:0;z-index:100000}.yoast-modal{background:#fff;bottom:48px;display:flex;flex-direction:column;height:calc(100% - 96px);right:calc(50% - 440px);max-width:880px;overflow:hidden;position:fixed;top:48px;width:100%}.yoast-gutenberg-modal .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:20px;margin-left:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:20px}.yoast-tabs .yoast-modal__content{display:grid;grid-template-areas:"heading heading" "menu content" "menu footer";grid-template-columns:280px 1fr;grid-template-rows:72px 1fr 88px}.yoast-modal__heading{align-items:center;background:var(--yoast-color-white);border-bottom:var(--yoast-border-default);box-sizing:border-box;display:flex;grid-area:heading;min-height:72px;padding:0 24px}.yoast-modal__heading .yoast-close{position:absolute;left:16px}.yoast-gutenberg-modal__box.components-modal__frame{box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}@media (min-width:600px){.yoast-gutenberg-modal__box.components-modal__frame{border-radius:8px;max-height:calc(100% - 48px)}}.yoast-gutenberg-modal__no-padding .components-modal__content{padding:0}.yoast-gutenberg-modal .components-modal__header-heading,.yoast-modal__heading h1{color:var(--yoast-color-primary);font-size:20px;font-weight:400;line-height:1.2;margin:0}.yoast-gutenberg-modal .components-modal__content .components-modal__header{border-bottom:1px solid #e2e8f0!important}.yoast-gutenberg-modal .components-modal__icon-container{display:inline-flex}.yoast-gutenberg-modal .components-modal__icon-container svg,.yoast-modal__heading-icon{fill:var(--yoast-color-primary);flex-shrink:0;height:20px;margin-left:16px;width:19px}.yoast-modal__menu{border-left:var(--yoast-border-default);grid-area:menu;overflow-y:auto}.yoast-modal__menu ul{list-style:none;margin:0;padding:0}.yoast-modal__menu li{border-bottom:var(--yoast-border-default);color:var(--yoast-color-default);cursor:pointer;display:block;font-size:16px;padding:12px 16px 11px;text-decoration:none}.yoast-modal__menu li:hover{background-color:#edd4e1}.yoast-modal__menu li.yoast-tabs__tab--selected{background-color:var(--yoast-color-primary);border-bottom:var(--yoast-border-default);color:#fff}.yoast-modal__content,.yoast-modal__section{display:flex;flex-direction:column;flex-grow:1;grid-area:content;overflow-y:auto;position:relative}.yoast-modal__section *{max-width:600px}.yoast-modal__section-header{background:var(--yoast-color-white);padding:24px 24px 0;position:sticky;top:0;z-index:10}.yoast-modal__section .yoast-h2{border-bottom:var(--yoast-border-default);padding-bottom:24px}.yoast-modal__footer{align-items:center;align-self:flex-end;background:var(--yoast-color-white);border-top:var(--yoast-border-default);bottom:0;box-sizing:border-box;display:flex;grid-area:footer;justify-content:flex-end;margin:0 24px;min-height:88px;padding:0;position:sticky;width:calc(100% - 48px);z-index:10}.yoast-modal__settings-saved{align-items:center;display:inline-flex;margin-left:16px;position:relative}.yoast-modal__settings-saved:before{background:var(--yoast-checkmark--green) no-repeat center;content:"";display:inline-block;height:13px;margin-left:8px;width:14px}.yoast-modal__footer .yoast-button{display:block}.yoast-modal__section-content{flex-grow:1;padding:24px}@media screen and (max-width:880px){.yoast-modal{bottom:0;height:auto;right:0;left:0;top:0}}@media screen and (max-width:782px){.yoast-modal{overflow-y:initial}.yoast-modal.yoast-modal-collapsible{padding-bottom:72px}.yoast-tabs .yoast-modal__content{grid-template-rows:48px 1fr 72px}.yoast-modal__heading{min-height:48px;padding:0 16px;position:fixed;top:0;width:100%;z-index:11}.yoast-modal__heading h1{font-size:var(--yoast-font-size-default)}.yoast-close svg{width:10px}.yoast-modal__heading-icon{height:15px;margin-left:8px}.yoast .yoast-close{left:3px}.yoast-modal__heading .yoast-h2{font-size:var(--yoast-font-size-default)}.yoast-modal__section{flex-grow:0;overflow:initial}.yoast-modal__section-content{margin:0 16px;padding:24px 0}.yoast-modal__section:first-of-type{margin-top:48px}.yoast-modal__section:last-of-type{margin-bottom:72px}.yoast-modal__section-header{margin:0;padding:0;position:sticky;top:48px}.yoast-modal__section-open .yoast-modal__section-header{margin-right:16px;margin-left:16px;padding-right:0;padding-left:0}.yoast-modal__section-open{border-bottom:var(--yoast-border-default)}.yoast-modal__footer{margin:0;min-height:72px;padding:0 16px;position:fixed;width:100%;z-index:11}.yoast-modal-collapsible .yoast-modal__footer{min-height:72px}.yoast-modal-collapsible .yoast-modal__section-content{border-bottom:var(--yoast-border-default);margin:0;padding:24px 16px}.yoast-collapsible__hidden{display:none}.yoast-collapsible__trigger{background:#fff;border:none;border-bottom:var(--yoast-border-default);color:var(--yoast-color-primary);cursor:pointer;font-size:var(--yoast-font-size-default);justify-content:space-between;padding:16px;text-align:right;width:100%}.yoast-collapsible__trigger[aria-expanded=true] .yoast-collapsible__icon{transform:rotate(-180deg)}.yoast-collapsible__trigger[aria-expanded=true]{margin:0 16px;padding:16px 0;width:calc(100% - 32px)}.yoast-collapsible__icon{background-color:var(--yoast-color-white);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23404040' viewBox='0 0 12 8'%3E%3Cpath d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.5 0 1.4z'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:10px auto;border:none;display:block;float:left;height:19px;width:19px}.yoast-collapsible-block{margin-top:48px;width:100%}.yoast-collapsible-block+.yoast-collapsible-block{margin-top:0}}.yoast-post-settings-modal{height:100%;max-height:calc(100% - 96px);max-width:calc(100% - 96px);overflow:hidden;width:880px}.yoast-modal-content{padding:16px}@media (min-width:782px){.yoast-modal-content--columns{display:grid;grid-template-columns:1fr 1fr;grid-gap:24px}}.yoast-post-settings-modal__button-container{border-bottom:1px solid #0003;display:flex;flex-direction:column;padding:16px}.yoast-post-settings-modal .components-modal__content{display:flex;flex-direction:column;padding:0}.yoast-post-settings-modal .components-modal__header{border-bottom:var(--yoast-border-default);flex-shrink:0;margin:0}.yoast-post-settings-modal .yoast-notice-container{bottom:0;right:0;margin-top:auto;position:sticky;width:100%;z-index:1}.yoast-post-settings-modal .components-modal__content>div.components-modal__children-container,.yoast-post-settings-modal .components-modal__content>div:not([class]):not([class=""]){display:flex;flex-direction:column;overflow:hidden}.yoast-post-settings-modal .yoast-notice-container>hr{margin-bottom:0;margin-top:-1px}.yoast-post-settings-modal .yoast-content-container{flex-grow:1;overflow-y:auto}.yoast-post-settings-modal .yoast-button-container{display:flex;flex-direction:row;justify-content:flex-end;margin:0;padding:24px}.yoast-post-settings-modal .yoast-button-container p{align-self:center;color:var(--yoast-color-label-help);padding-left:24px}.yoast-post-settings-modal .yoast-button-container button{align-self:center;flex-shrink:0;max-height:45px}@media only screen and (max-width:600px){.yoast-post-settings-modal{max-height:100%;max-width:100%}.yoast-post-settings-modal .yoast-button-container{justify-content:space-between;padding:16px}.yoast-post-settings-modal .yoast-button-container p{padding-left:0}}.yoast-related-keyphrases-modal,.yoast-wincher-seo-performance-modal{max-width:712px}.yoast-wincher-seo-performance-modal__content{padding:25px 32px 32px}#yoast-get-related-keyphrases-metabox,#yoast-get-related-keyphrases-sidebar{margin-top:8px}.yoast-gutenberg-modal .yoast-related-keyphrases-modal__content{min-height:66vh;position:relative}.yoast-related-keyphrases-modal__chart{display:block}.m6zwb4v,.m6zwb4v:visited{background:#e6f3ff;border-radius:2px;color:#575f67;cursor:pointer;display:inline-block;padding-right:2px;padding-left:2px;-webkit-text-decoration:none;text-decoration:none}.m6zwb4v:focus,.m6zwb4v:hover{background:#edf5fd;color:#677584;outline:0}.m6zwb4v:active{background:#455261;color:#222}.mnw6qvm{background:#fff;border:1px solid #eee;border-radius:2px;box-shadow:0 4px 30px 0 #dcdcdc;box-sizing:border-box;cursor:pointer;display:flex;flex-direction:column;max-width:440px;min-width:220px;padding-bottom:8px;padding-top:8px;position:absolute;transform:scale(0);z-index:2}.m1ymsnxd{opacity:0;transition:opacity .25s cubic-bezier(.3,1.2,.2,1)}.m126ak5t{opacity:1}.mtiwdxc{padding:7px 10px 3px;transition:background-color .4s cubic-bezier(.27,1.27,.48,.56)}.mtiwdxc:active{background-color:#cce7ff}.myz2dw1{background-color:#e6f3ff;padding:7px 10px 3px;transition:background-color .4s cubic-bezier(.27,1.27,.48,.56)}.myz2dw1:active{background-color:#cce7ff}.mpqdcgq{font-size:.9em;margin-bottom:.2em;margin-right:8px;max-width:368px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.m1mfvffo,.mpqdcgq{display:inline-block}.m1mfvffo{border-radius:12px;height:24px;width:24px}.DraftEditor-editorContainer,.DraftEditor-root,.public-DraftEditor-content{height:inherit;text-align:initial}.public-DraftEditor-content[contenteditable=true]{-webkit-user-modify:read-write-plaintext-only}.DraftEditor-root{position:relative}.DraftEditor-editorContainer{background-color:#fff0;border-left:.1px solid #0000;position:relative;z-index:1}.public-DraftEditor-block{position:relative}.DraftEditor-alignLeft .public-DraftStyleDefault-block{text-align:left}.DraftEditor-alignLeft .public-DraftEditorPlaceholder-root{left:0;text-align:left}.DraftEditor-alignCenter .public-DraftStyleDefault-block{text-align:center}.DraftEditor-alignCenter .public-DraftEditorPlaceholder-root{margin:0 auto;text-align:center;width:100%}.DraftEditor-alignRight .public-DraftStyleDefault-block{text-align:right}.DraftEditor-alignRight .public-DraftEditorPlaceholder-root{right:0;text-align:right}.public-DraftEditorPlaceholder-root{color:#9197a3;position:absolute;width:100%;z-index:1}.public-DraftEditorPlaceholder-hasFocus{color:#bdc1c9}.DraftEditorPlaceholder-hidden{display:none}.public-DraftStyleDefault-block{position:relative;white-space:pre-wrap}.public-DraftStyleDefault-ltr{direction:ltr;text-align:left}.public-DraftStyleDefault-rtl{direction:rtl;text-align:right}.public-DraftStyleDefault-listLTR{direction:ltr}.public-DraftStyleDefault-listRTL{direction:rtl}.public-DraftStyleDefault-ol,.public-DraftStyleDefault-ul{margin:16px 0;padding:0}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-listLTR{margin-left:1.5em}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-listRTL{margin-right:1.5em}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-listLTR{margin-left:3em}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-listRTL{margin-right:3em}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-listLTR{margin-left:4.5em}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-listRTL{margin-right:4.5em}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-listLTR{margin-left:6em}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-listRTL{margin-right:6em}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-listLTR{margin-left:7.5em}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-listRTL{margin-right:7.5em}.public-DraftStyleDefault-unorderedListItem{list-style-type:square;position:relative}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth0{list-style-type:disc}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth1{list-style-type:circle}.public-DraftStyleDefault-orderedListItem{list-style-type:none;position:relative}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-listLTR:before{left:-36px;position:absolute;text-align:right;width:30px}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-listRTL:before{position:absolute;right:-36px;text-align:left;width:30px}.public-DraftStyleDefault-orderedListItem:before{content:counter(ol0) ". ";counter-increment:ol0}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth1:before{content:counter(ol1,lower-alpha) ". ";counter-increment:ol1}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth2:before{content:counter(ol2,lower-roman) ". ";counter-increment:ol2}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth3:before{content:counter(ol3) ". ";counter-increment:ol3}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth4:before{content:counter(ol4,lower-alpha) ". ";counter-increment:ol4}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-reset{counter-reset:ol0}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-reset{counter-reset:ol1}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-reset{counter-reset:ol2}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-reset{counter-reset:ol3}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-reset{counter-reset:ol4}#wpseo_meta{box-sizing:border-box}#wpseo_meta *,#wpseo_meta :after,#wpseo_meta :before{box-sizing:inherit}.DraftEditor-root [data-block]{margin:0}#edittag>#wp-description-wrap{display:none}#wp-description-wrap .wp-editor-area{border:0}.term-description-wrap td>textarea#description{min-height:530px}.wpseo-meta-section,.wpseo-meta-section-react{border:1px solid #0003;display:none;height:auto;max-width:600px;min-height:100%;vertical-align:top;width:100%}.wpseo-meta-section-react.active,.wpseo-meta-section.active{background:#fff;position:relative;z-index:12}.wpseo-meta-section.active{display:inline-block}.wpseo-meta-section-react.active{display:block;margin-bottom:10px}.wpseo-meta-section-content{padding:16px}.wpseo-metabox-content{max-width:800px;padding-top:16px}.edit-post-meta-boxes-area__container .wpseo-metabox .postbox-header{border-bottom:1px solid #ddd}.edit-post-meta-boxes-area__container .wpseo-metabox .inside{background-color:#f1f5f9}.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-metabox-content{max-width:none;padding:32px 8px 8px}.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-meta-section,.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-metabox-menu{margin:0 auto}.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-meta-section.active{display:block}.wpseo-metabox-menu{max-width:600px;padding:0}.wpseo-metabox-menu ul{align-items:flex-end;display:flex;flex-wrap:wrap;flex-flow:wrap-reverse;margin:0 0 0 1px;padding:0 16px 0 0}.wpseo-metabox-menu ul li:first-child{z-index:10}.wpseo-metabox-menu ul li:nth-child(2){z-index:9}.wpseo-metabox-menu ul li:nth-child(3){z-index:8}.wpseo-metabox-menu ul li:nth-child(4){z-index:7}.wpseo-metabox-menu ul li:nth-child(5){z-index:6}.wpseo-metabox-menu ul li:nth-child(6){z-index:5}.wpseo-metabox-menu ul li{background-color:#f8f8f8;box-shadow:0 0 4px 0 #0000001a;height:32px;margin-bottom:-1px;margin-right:-1px;position:relative;text-align:center}.wpseo-metabox-menu ul li a{align-items:center;border:1px solid #0003;border-bottom:2px #0000;color:#0073aa;display:flex}.wpseo-metabox-menu ul li a:focus{box-shadow:inherit}.wpseo-metabox-menu ul li .yst-traffic-light{height:20px;margin-right:4px;margin-left:10px;width:auto}.wpseo-metabox-menu ul li span.dashicons{margin-left:8px}.wpseo-metabox-menu ul li span.wpseo-buy-premium{color:#a4286a}.wpseo-metabox-menu ul li span.wpseo-buy-premium:hover{color:#832055}.wpseo-metabox-menu ul li.active{background-color:#fff;border-bottom:2px #0000;box-shadow:none;height:36px;margin-top:-4px;z-index:13}.wpseo-metabox-menu ul li.active a{color:#444;height:36px}.wpseo-metabox-menu ul li.active span.wpseo-buy-premium{border-color:#a4286a;color:#a4286a}.wpseo-metabox-menu ul li.active span.wpseo-buy-premium:hover{border-color:#832055;color:#832055}.wpseo-metabox-menu a{height:32px;padding:0 8px;text-decoration:none}.wpseotab{background-color:#fdfdfd;border:1px solid #ddd;display:none;padding:16px}.wpseotab .wpseo-cornerstone-checkbox{margin-left:.5em}.wpseotab.content{padding:20px 15px}.wpseotab.active{display:block}.wpseo-metabox-sidebar .dashicons{font-size:30px;height:30px;width:30px}#wpseo_meta .inside{margin:0}#wpseo_meta .inside:after{clear:both;content:"";display:table}#wpseo_meta .postbox .inside .wpseotab{font-size:13px!important}.wpseo-form input,.wpseo-form label,.wpseo-form p.error-message,.wpseo-form textarea{max-width:600px}.wpseo-form fieldset{padding-top:5px}.wpseo-form legend{font-weight:600}.wpseo-form label{display:block;font-weight:600}.wpseo-form input[type=checkbox]+label,.wpseo-form input[type=radio]+label{display:inline-block;font-weight:400}.wpseo-form fieldset,.wpseo-form label{margin-bottom:.5em;margin-top:2em}.wpseo-form input[type=checkbox],.wpseo-form input[type=checkbox]+label{font-size:1em;margin-bottom:0;margin-top:2em}.wpseo-form fieldset:first-child,.wpseo-form input[type=checkbox]:first-child,.wpseo-form input[type=checkbox]:first-child+label,.wpseo-form label:first-child{margin-top:10px}.wpseo-form input[type=radio]{margin-top:0}.wpseo-form input[type=radio]+label{margin:0 0 0 1em}.wpseo-form p.error-message{margin:.5em 0}.wpseo-form select[multiple]{margin-top:0}.yoast-metabox__description{margin:.5em 0;max-width:600px}.good,.warn,.wrong{font-weight:600}.good{color:green}.warn{color:maroon}.wrong{color:#dc3232}#current_seo_title span{background-color:#ffffe0;padding:2px 5px}#focuskwresults ul{margin:0}#focuskwresults li,#focuskwresults p{font-size:13px}#focuskwresults li{list-style-type:disc;margin:0 20px 0 0}.wpseo_hidden{display:none}.wpseo_msg{background-color:#ffffe0;border:1px solid #e6db55;margin:5px 0 10px;padding:0 5px}.snippet-editor__button.snippet-editor__edit-button:focus{background-color:#fafafa;border-color:#5b9dd9;box-shadow:0 0 3px #0073aacc;color:#23282d;outline:none}.wpseo-admin-page .subsubsub li{display:inline;max-width:none}.yoast-seo-help-container{float:right;max-width:none;width:100%}.yoast-seo-help-container .yoast-help-panel{margin:.5em 0!important}.wpseo_content_wrapper p.search-box{margin:10px 0 5px}#wpseotab .ui-widget-content .ui-state-hover{background:#f1f1f1;border:1px solid #dfdfdf;color:#333}.term-php .wpseo-taxonomy-metabox-postbox>h2{border-bottom:1px solid #eee;font-size:14px;line-height:1.4;margin:0;padding:8px 12px}#TB_window #TB_ajaxContent p{margin:5px 0 0;padding:5px 0 0}#TB_window #TB_ajaxContent ul{margin:5px 0 10px}#TB_window #TB_ajaxContent li{list-style:none;margin:5px 0 0}#TB_window #TB_ajaxContent li:before{content:"+";font-weight:700;margin:0 0 0 10px}.yoast-section__heading-icon-list{background-image:var(--yoast-svg-icon-list)}.yoast-section__heading-icon-key{background-image:var(--yoast-svg-icon-key)}.yoast-section__heading-icon-edit{background-image:var(--yoast-svg-icon-edit)}.yoast-tooltip.yoast-tooltip-hidden:after,.yoast-tooltip.yoast-tooltip-hidden:before{display:none}.screen-reader-text.wpseo-generic-tab-textual-score,.screen-reader-text.wpseo-keyword-tab-textual-score{display:block}.yoast-notice-go-premium{background:#f1f1f1;border-right-color:#a4286a;margin:0}.emoji-select-button{border-radius:.375rem!important;min-height:28px!important;padding:6px!important;width:28px!important;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}@media screen and (max-width:782px){.wpseo-metabox-buy-premium .wpseo-buy-premium{display:inline-block;height:20px;margin-left:5px;padding:0;width:20px}.yoast-help-panel{max-width:none!important}#wpseo-crawl-issues-table-form .subsubsub{float:none;max-width:calc(100vw - 20px)}#wpseo-crawl-issues-table-form .yoast-help-button{margin-top:3px}.wpseotab select[multiple]{height:auto!important}}@media screen and (max-width:600px){.wpseotab.content{padding:16px 0}}.wpseo-score-icon-container{align-items:center;display:flex;height:20px;justify-content:center;margin-left:8px;width:20px}.yoast-seo-sidebar-panel .yoast-analysis-check{display:flex}.yoast-seo-sidebar-panel .yoast-analysis-check svg{margin-left:5px;margin-top:6px}.yoast-seo-sidebar-panel .yoast-analysis-check span{line-height:1.5;margin-top:3px}.yoast-seo-sidebar-panel div{line-height:2}.yoast-seo-sidebar-panel div svg{vertical-align:middle}ul.yoast-seo-social-share-buttons li{display:inline-block;margin-left:24px}ul.yoast-seo-social-share-buttons li .x-share svg{height:30px;width:30px;fill:#000}ul.yoast-seo-social-share-buttons svg{height:32px;margin-bottom:8px;width:32px}ul.yoast-seo-social-share-buttons a{align-items:center;display:flex;flex-direction:column}.yoast-field-group.yoast-wincher-post-publish{margin-bottom:10px}.edit-post-pinned-plugins button.components-button:not(.is-compact)[aria-label="Yoast SEO Premium"]>svg,.edit-post-pinned-plugins button.components-button:not(.is-compact)[aria-label="Yoast SEO"]>svg,div.interface-pinned-items button.components-button:not(.is-compact)[aria-label="Yoast SEO Premium"]>svg,div.interface-pinned-items button.components-button:not(.is-compact)[aria-label="Yoast SEO"]>svg{height:28px;max-height:28px;max-width:28px;width:28px}div.interface-pinned-items button.components-button.is-pressed[aria-label="Yoast SEO Premium"]>svg path,div.interface-pinned-items button.components-button.is-pressed[aria-label="Yoast SEO"]>svg path{fill:#fff}.wpseo-schema-icon{align-items:center;background-image:var(--yoast-svg-icon-schema);background-size:cover;display:flex;height:16px;justify-content:center;margin-left:8px;width:16px}.wpseo-metabox-menu ul li.active a .wpseo-schema-icon{background-image:var(--yoast-svg-icon-schema-active)}.yoast-icon-span svg{margin-left:8px;fill:inherit}.yoast.components-panel__body{border-top:0}.components-button>.yoast-title-container{flex-grow:1;line-height:normal;overflow-x:hidden}.yoast-title-container>.yoast-subtitle,.yoast-title-container>.yoast-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yoast-title-container>.yoast-subtitle{font-size:.8125rem;font-weight:300;margin-top:2px}.yoast.components-panel__body .yoast-chevron{background-color:#1e1e1e;display:inline-block;height:24px;mask-image:var(--yoast-svg-icon-chevron-down);mask-size:100% 100%;width:24px}.yoast.components-panel__body.is-opened .yoast-chevron{mask-image:var(--yoast-svg-icon-chevron-up)}.yoast .components-panel__body-toggle{padding-left:16px}.yoast .components-form-token-field__remove-token.components-button,.yoast .components-form-token-field__token-text{background-color:var(--yoast-color-primary);color:var(--yoast-color-white)}.yoast .yoast-insights{color:#404040}.yoast .yoast-insights .yoast-field-group__title>b{color:var(--yoast-color-primary);font-size:16px;font-weight:var(--yoast-font-weight-default);line-height:1.2em}.yoast .yoast-insights-card__score{color:var(--yoast-color-primary);margin-block:0}.yoast .yoast-insights-card__description{line-height:1.4em}.yoast .yoast-prominent-words p,.yoast .yoast-prominent-words ul,.yoast .yoast-text-formality p{margin-block:1.2em}.yoast #wpseo-metabox-root .yoast-prominent-words{border-bottom:1px solid #0000001a;margin-bottom:24px;padding-bottom:24px}.yoast .yoast-insights .yoast-data-model--upsell li{color:#bbb}.yoast .yoast-insights .yoast-data-model--upsell li:after{background:#fdf4f8}.yoast-add-block-button{align-items:center;background-color:#fff;border:1px solid #cbd5e1;border-radius:6px;box-shadow:0 1px 2px 0 #0000000d;box-sizing:border-box;cursor:pointer;display:flex;flex-direction:row;height:28px;justify-content:center;padding:6px;width:28px}.yoast-add-block-button--clicked{background-color:var(--yoast-color-primary)}.yoast-add-block-button:focus:not(.yoast-add-block-button--clicked),.yoast-add-block-button:hover:not(.yoast-add-block-button--clicked){background-color:#f8fafc}.yoast-add-block-button__icon{height:16px;width:16px}.yoast-add-block-button__icon--clicked{stroke:#fff} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/metabox-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-2711.css new file mode 100644 index 0000000..e5c2812 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-2711.css @@ -0,0 +1,3 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.yoast-modal__screen-overlay{animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards;background-color:#a4286a99;bottom:0;left:0;position:fixed;right:0;top:0;z-index:100000}.yoast-modal{background:#fff;bottom:48px;display:flex;flex-direction:column;height:calc(100% - 96px);left:calc(50% - 440px);max-width:880px;overflow:hidden;position:fixed;top:48px;width:100%}.yoast-gutenberg-modal .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:20px;margin-right:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:20px}.yoast-tabs .yoast-modal__content{display:grid;grid-template-areas:"heading heading" "menu content" "menu footer";grid-template-columns:280px 1fr;grid-template-rows:72px 1fr 88px}.yoast-modal__heading{align-items:center;background:var(--yoast-color-white);border-bottom:var(--yoast-border-default);box-sizing:border-box;display:flex;grid-area:heading;min-height:72px;padding:0 24px}.yoast-modal__heading .yoast-close{position:absolute;right:16px}.yoast-gutenberg-modal__box.components-modal__frame{box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}@media (min-width:600px){.yoast-gutenberg-modal__box.components-modal__frame{border-radius:8px;max-height:calc(100% - 48px)}}.yoast-gutenberg-modal__no-padding .components-modal__content{padding:0}.yoast-gutenberg-modal .components-modal__header-heading,.yoast-modal__heading h1{color:var(--yoast-color-primary);font-size:20px;font-weight:400;line-height:1.2;margin:0}.yoast-gutenberg-modal .components-modal__content .components-modal__header{border-bottom:1px solid #e2e8f0!important}.yoast-gutenberg-modal .components-modal__icon-container{display:inline-flex}.yoast-gutenberg-modal .components-modal__icon-container svg,.yoast-modal__heading-icon{fill:var(--yoast-color-primary);flex-shrink:0;height:20px;margin-right:16px;width:19px}.yoast-modal__menu{border-right:var(--yoast-border-default);grid-area:menu;overflow-y:auto}.yoast-modal__menu ul{list-style:none;margin:0;padding:0}.yoast-modal__menu li{border-bottom:var(--yoast-border-default);color:var(--yoast-color-default);cursor:pointer;display:block;font-size:16px;padding:12px 16px 11px;text-decoration:none}.yoast-modal__menu li:hover{background-color:#edd4e1}.yoast-modal__menu li.yoast-tabs__tab--selected{background-color:var(--yoast-color-primary);border-bottom:var(--yoast-border-default);color:#fff}.yoast-modal__content,.yoast-modal__section{display:flex;flex-direction:column;flex-grow:1;grid-area:content;overflow-y:auto;position:relative}.yoast-modal__section *{max-width:600px}.yoast-modal__section-header{background:var(--yoast-color-white);padding:24px 24px 0;position:sticky;top:0;z-index:10}.yoast-modal__section .yoast-h2{border-bottom:var(--yoast-border-default);padding-bottom:24px}.yoast-modal__footer{align-items:center;align-self:flex-end;background:var(--yoast-color-white);border-top:var(--yoast-border-default);bottom:0;box-sizing:border-box;display:flex;grid-area:footer;justify-content:flex-end;margin:0 24px;min-height:88px;padding:0;position:sticky;width:calc(100% - 48px);z-index:10}.yoast-modal__settings-saved{align-items:center;display:inline-flex;margin-right:16px;position:relative}.yoast-modal__settings-saved:before{background:var(--yoast-checkmark--green) no-repeat center;content:"";display:inline-block;height:13px;margin-right:8px;width:14px}.yoast-modal__footer .yoast-button{display:block}.yoast-modal__section-content{flex-grow:1;padding:24px}@media screen and (max-width:880px){.yoast-modal{bottom:0;height:auto;left:0;right:0;top:0}}@media screen and (max-width:782px){.yoast-modal{overflow-y:initial}.yoast-modal.yoast-modal-collapsible{padding-bottom:72px}.yoast-tabs .yoast-modal__content{grid-template-rows:48px 1fr 72px}.yoast-modal__heading{min-height:48px;padding:0 16px;position:fixed;top:0;width:100%;z-index:11}.yoast-modal__heading h1{font-size:var(--yoast-font-size-default)}.yoast-close svg{width:10px}.yoast-modal__heading-icon{height:15px;margin-right:8px}.yoast .yoast-close{right:3px}.yoast-modal__heading .yoast-h2{font-size:var(--yoast-font-size-default)}.yoast-modal__section{flex-grow:0;overflow:initial}.yoast-modal__section-content{margin:0 16px;padding:24px 0}.yoast-modal__section:first-of-type{margin-top:48px}.yoast-modal__section:last-of-type{margin-bottom:72px}.yoast-modal__section-header{margin:0;padding:0;position:sticky;top:48px}.yoast-modal__section-open .yoast-modal__section-header{margin-left:16px;margin-right:16px;padding-left:0;padding-right:0}.yoast-modal__section-open{border-bottom:var(--yoast-border-default)}.yoast-modal__footer{margin:0;min-height:72px;padding:0 16px;position:fixed;width:100%;z-index:11}.yoast-modal-collapsible .yoast-modal__footer{min-height:72px}.yoast-modal-collapsible .yoast-modal__section-content{border-bottom:var(--yoast-border-default);margin:0;padding:24px 16px}.yoast-collapsible__hidden{display:none}.yoast-collapsible__trigger{background:#fff;border:none;border-bottom:var(--yoast-border-default);color:var(--yoast-color-primary);cursor:pointer;font-size:var(--yoast-font-size-default);justify-content:space-between;padding:16px;text-align:left;width:100%}.yoast-collapsible__trigger[aria-expanded=true] .yoast-collapsible__icon{transform:rotate(180deg)}.yoast-collapsible__trigger[aria-expanded=true]{margin:0 16px;padding:16px 0;width:calc(100% - 32px)}.yoast-collapsible__icon{background-color:var(--yoast-color-white);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23404040' viewBox='0 0 12 8'%3E%3Cpath d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.5 0 1.4z'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:10px auto;border:none;display:block;float:right;height:19px;width:19px}.yoast-collapsible-block{margin-top:48px;width:100%}.yoast-collapsible-block+.yoast-collapsible-block{margin-top:0}}.yoast-post-settings-modal{height:100%;max-height:calc(100% - 96px);max-width:calc(100% - 96px);overflow:hidden;width:880px}.yoast-modal-content{padding:16px}@media (min-width:782px){.yoast-modal-content--columns{display:grid;grid-template-columns:1fr 1fr;grid-gap:24px}}.yoast-post-settings-modal__button-container{border-bottom:1px solid #0003;display:flex;flex-direction:column;padding:16px}.yoast-post-settings-modal .components-modal__content{display:flex;flex-direction:column;padding:0}.yoast-post-settings-modal .components-modal__header{border-bottom:var(--yoast-border-default);flex-shrink:0;margin:0}.yoast-post-settings-modal .yoast-notice-container{bottom:0;left:0;margin-top:auto;position:sticky;width:100%;z-index:1}.yoast-post-settings-modal .components-modal__content>div.components-modal__children-container,.yoast-post-settings-modal .components-modal__content>div:not([class]):not([class=""]){display:flex;flex-direction:column;overflow:hidden}.yoast-post-settings-modal .yoast-notice-container>hr{margin-bottom:0;margin-top:-1px}.yoast-post-settings-modal .yoast-content-container{flex-grow:1;overflow-y:auto}.yoast-post-settings-modal .yoast-button-container{display:flex;flex-direction:row;justify-content:flex-end;margin:0;padding:24px}.yoast-post-settings-modal .yoast-button-container p{align-self:center;color:var(--yoast-color-label-help);padding-right:24px}.yoast-post-settings-modal .yoast-button-container button{align-self:center;flex-shrink:0;max-height:45px}@media only screen and (max-width:600px){.yoast-post-settings-modal{max-height:100%;max-width:100%}.yoast-post-settings-modal .yoast-button-container{justify-content:space-between;padding:16px}.yoast-post-settings-modal .yoast-button-container p{padding-right:0}}.yoast-related-keyphrases-modal,.yoast-wincher-seo-performance-modal{max-width:712px}.yoast-wincher-seo-performance-modal__content{padding:25px 32px 32px}#yoast-get-related-keyphrases-metabox,#yoast-get-related-keyphrases-sidebar{margin-top:8px}.yoast-gutenberg-modal .yoast-related-keyphrases-modal__content{min-height:66vh;position:relative}.yoast-related-keyphrases-modal__chart{display:block}.m6zwb4v,.m6zwb4v:visited{background:#e6f3ff;border-radius:2px;color:#575f67;cursor:pointer;display:inline-block;padding-left:2px;padding-right:2px;-webkit-text-decoration:none;text-decoration:none}.m6zwb4v:focus,.m6zwb4v:hover{background:#edf5fd;color:#677584;outline:0}.m6zwb4v:active{background:#455261;color:#222}.mnw6qvm{background:#fff;border:1px solid #eee;border-radius:2px;box-shadow:0 4px 30px 0 #dcdcdc;box-sizing:border-box;cursor:pointer;display:flex;flex-direction:column;max-width:440px;min-width:220px;padding-bottom:8px;padding-top:8px;position:absolute;transform:scale(0);z-index:2}.m1ymsnxd{opacity:0;transition:opacity .25s cubic-bezier(.3,1.2,.2,1)}.m126ak5t{opacity:1}.mtiwdxc{padding:7px 10px 3px;transition:background-color .4s cubic-bezier(.27,1.27,.48,.56)}.mtiwdxc:active{background-color:#cce7ff}.myz2dw1{background-color:#e6f3ff;padding:7px 10px 3px;transition:background-color .4s cubic-bezier(.27,1.27,.48,.56)}.myz2dw1:active{background-color:#cce7ff}.mpqdcgq{font-size:.9em;margin-bottom:.2em;margin-left:8px;max-width:368px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.m1mfvffo,.mpqdcgq{display:inline-block}.m1mfvffo{border-radius:12px;height:24px;width:24px} +/*!rtl:begin:ignore*/.DraftEditor-editorContainer,.DraftEditor-root,.public-DraftEditor-content{height:inherit;text-align:initial}.public-DraftEditor-content[contenteditable=true]{-webkit-user-modify:read-write-plaintext-only}.DraftEditor-root{position:relative}.DraftEditor-editorContainer{background-color:#fff0;border-left:.1px solid #0000;position:relative;z-index:1}.public-DraftEditor-block{position:relative}.DraftEditor-alignLeft .public-DraftStyleDefault-block{text-align:left}.DraftEditor-alignLeft .public-DraftEditorPlaceholder-root{left:0;text-align:left}.DraftEditor-alignCenter .public-DraftStyleDefault-block{text-align:center}.DraftEditor-alignCenter .public-DraftEditorPlaceholder-root{margin:0 auto;text-align:center;width:100%}.DraftEditor-alignRight .public-DraftStyleDefault-block{text-align:right}.DraftEditor-alignRight .public-DraftEditorPlaceholder-root{right:0;text-align:right}.public-DraftEditorPlaceholder-root{color:#9197a3;position:absolute;width:100%;z-index:1}.public-DraftEditorPlaceholder-hasFocus{color:#bdc1c9}.DraftEditorPlaceholder-hidden{display:none}.public-DraftStyleDefault-block{position:relative;white-space:pre-wrap}.public-DraftStyleDefault-ltr{direction:ltr;text-align:left}.public-DraftStyleDefault-rtl{direction:rtl;text-align:right}.public-DraftStyleDefault-listLTR{direction:ltr}.public-DraftStyleDefault-listRTL{direction:rtl}.public-DraftStyleDefault-ol,.public-DraftStyleDefault-ul{margin:16px 0;padding:0}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-listLTR{margin-left:1.5em}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-listRTL{margin-right:1.5em}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-listLTR{margin-left:3em}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-listRTL{margin-right:3em}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-listLTR{margin-left:4.5em}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-listRTL{margin-right:4.5em}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-listLTR{margin-left:6em}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-listRTL{margin-right:6em}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-listLTR{margin-left:7.5em}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-listRTL{margin-right:7.5em}.public-DraftStyleDefault-unorderedListItem{list-style-type:square;position:relative}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth0{list-style-type:disc}.public-DraftStyleDefault-unorderedListItem.public-DraftStyleDefault-depth1{list-style-type:circle}.public-DraftStyleDefault-orderedListItem{list-style-type:none;position:relative}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-listLTR:before{left:-36px;position:absolute;text-align:right;width:30px}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-listRTL:before{position:absolute;right:-36px;text-align:left;width:30px}.public-DraftStyleDefault-orderedListItem:before{content:counter(ol0) ". ";counter-increment:ol0}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth1:before{content:counter(ol1,lower-alpha) ". ";counter-increment:ol1}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth2:before{content:counter(ol2,lower-roman) ". ";counter-increment:ol2}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth3:before{content:counter(ol3) ". ";counter-increment:ol3}.public-DraftStyleDefault-orderedListItem.public-DraftStyleDefault-depth4:before{content:counter(ol4,lower-alpha) ". ";counter-increment:ol4}.public-DraftStyleDefault-depth0.public-DraftStyleDefault-reset{counter-reset:ol0}.public-DraftStyleDefault-depth1.public-DraftStyleDefault-reset{counter-reset:ol1}.public-DraftStyleDefault-depth2.public-DraftStyleDefault-reset{counter-reset:ol2}.public-DraftStyleDefault-depth3.public-DraftStyleDefault-reset{counter-reset:ol3}.public-DraftStyleDefault-depth4.public-DraftStyleDefault-reset{counter-reset:ol4} +/*!rtl:end:ignore*/#wpseo_meta{box-sizing:border-box}#wpseo_meta *,#wpseo_meta :after,#wpseo_meta :before{box-sizing:inherit}.DraftEditor-root [data-block]{margin:0}#edittag>#wp-description-wrap{display:none}#wp-description-wrap .wp-editor-area{border:0}.term-description-wrap td>textarea#description{min-height:530px}.wpseo-meta-section,.wpseo-meta-section-react{border:1px solid #0003;display:none;height:auto;max-width:600px;min-height:100%;vertical-align:top;width:100%}.wpseo-meta-section-react.active,.wpseo-meta-section.active{background:#fff;position:relative;z-index:12}.wpseo-meta-section.active{display:inline-block}.wpseo-meta-section-react.active{display:block;margin-bottom:10px}.wpseo-meta-section-content{padding:16px}.wpseo-metabox-content{max-width:800px;padding-top:16px}.edit-post-meta-boxes-area__container .wpseo-metabox .postbox-header{border-bottom:1px solid #ddd}.edit-post-meta-boxes-area__container .wpseo-metabox .inside{background-color:#f1f5f9}.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-metabox-content{max-width:none;padding:32px 8px 8px}.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-meta-section,.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-metabox-menu{margin:0 auto}.edit-post-meta-boxes-area__container .wpseo-metabox .wpseo-meta-section.active{display:block}.wpseo-metabox-menu{max-width:600px;padding:0}.wpseo-metabox-menu ul{align-items:flex-end;display:flex;flex-wrap:wrap;flex-flow:wrap-reverse;margin:0 1px 0 0;padding:0 0 0 16px}.wpseo-metabox-menu ul li:first-child{z-index:10}.wpseo-metabox-menu ul li:nth-child(2){z-index:9}.wpseo-metabox-menu ul li:nth-child(3){z-index:8}.wpseo-metabox-menu ul li:nth-child(4){z-index:7}.wpseo-metabox-menu ul li:nth-child(5){z-index:6}.wpseo-metabox-menu ul li:nth-child(6){z-index:5}.wpseo-metabox-menu ul li{background-color:#f8f8f8;box-shadow:0 0 4px 0 #0000001a;height:32px;margin-bottom:-1px;margin-left:-1px;position:relative;text-align:center}.wpseo-metabox-menu ul li a{align-items:center;border:1px solid #0003;border-bottom:2px #0000;color:#0073aa;display:flex}.wpseo-metabox-menu ul li a:focus{box-shadow:inherit}.wpseo-metabox-menu ul li .yst-traffic-light{height:20px;margin-left:4px;margin-right:10px;width:auto}.wpseo-metabox-menu ul li span.dashicons{margin-right:8px}.wpseo-metabox-menu ul li span.wpseo-buy-premium{color:#a4286a}.wpseo-metabox-menu ul li span.wpseo-buy-premium:hover{color:#832055}.wpseo-metabox-menu ul li.active{background-color:#fff;border-bottom:2px #0000;box-shadow:none;height:36px;margin-top:-4px;z-index:13}.wpseo-metabox-menu ul li.active a{color:#444;height:36px}.wpseo-metabox-menu ul li.active span.wpseo-buy-premium{border-color:#a4286a;color:#a4286a}.wpseo-metabox-menu ul li.active span.wpseo-buy-premium:hover{border-color:#832055;color:#832055}.wpseo-metabox-menu a{height:32px;padding:0 8px;text-decoration:none}.wpseotab{background-color:#fdfdfd;border:1px solid #ddd;display:none;padding:16px}.wpseotab .wpseo-cornerstone-checkbox{margin-right:.5em}.wpseotab.content{padding:20px 15px}.wpseotab.active{display:block}.wpseo-metabox-sidebar .dashicons{font-size:30px;height:30px;width:30px}#wpseo_meta .inside{margin:0}#wpseo_meta .inside:after{clear:both;content:"";display:table}#wpseo_meta .postbox .inside .wpseotab{font-size:13px!important}.wpseo-form input,.wpseo-form label,.wpseo-form p.error-message,.wpseo-form textarea{max-width:600px}.wpseo-form fieldset{padding-top:5px}.wpseo-form legend{font-weight:600}.wpseo-form label{display:block;font-weight:600}.wpseo-form input[type=checkbox]+label,.wpseo-form input[type=radio]+label{display:inline-block;font-weight:400}.wpseo-form fieldset,.wpseo-form label{margin-bottom:.5em;margin-top:2em}.wpseo-form input[type=checkbox],.wpseo-form input[type=checkbox]+label{font-size:1em;margin-bottom:0;margin-top:2em}.wpseo-form fieldset:first-child,.wpseo-form input[type=checkbox]:first-child,.wpseo-form input[type=checkbox]:first-child+label,.wpseo-form label:first-child{margin-top:10px}.wpseo-form input[type=radio]{margin-top:0}.wpseo-form input[type=radio]+label{margin:0 1em 0 0}.wpseo-form p.error-message{margin:.5em 0}.wpseo-form select[multiple]{margin-top:0}.yoast-metabox__description{margin:.5em 0;max-width:600px}.good,.warn,.wrong{font-weight:600}.good{color:green}.warn{color:maroon}.wrong{color:#dc3232}#current_seo_title span{background-color:#ffffe0;padding:2px 5px}#focuskwresults ul{margin:0}#focuskwresults li,#focuskwresults p{font-size:13px}#focuskwresults li{list-style-type:disc;margin:0 0 0 20px}.wpseo_hidden{display:none}.wpseo_msg{background-color:#ffffe0;border:1px solid #e6db55;margin:5px 0 10px;padding:0 5px}.snippet-editor__button.snippet-editor__edit-button:focus{background-color:#fafafa;border-color:#5b9dd9;box-shadow:0 0 3px #0073aacc;color:#23282d;outline:none}.wpseo-admin-page .subsubsub li{display:inline;max-width:none}.yoast-seo-help-container{float:left;max-width:none;width:100%}.yoast-seo-help-container .yoast-help-panel{margin:.5em 0!important}.wpseo_content_wrapper p.search-box{margin:10px 0 5px}#wpseotab .ui-widget-content .ui-state-hover{background:#f1f1f1;border:1px solid #dfdfdf;color:#333}.term-php .wpseo-taxonomy-metabox-postbox>h2{border-bottom:1px solid #eee;font-size:14px;line-height:1.4;margin:0;padding:8px 12px}#TB_window #TB_ajaxContent p{margin:5px 0 0;padding:5px 0 0}#TB_window #TB_ajaxContent ul{margin:5px 0 10px}#TB_window #TB_ajaxContent li{list-style:none;margin:5px 0 0}#TB_window #TB_ajaxContent li:before{content:"+";font-weight:700;margin:0 10px 0 0}.yoast-section__heading-icon-list{background-image:var(--yoast-svg-icon-list)}.yoast-section__heading-icon-key{background-image:var(--yoast-svg-icon-key)}.yoast-section__heading-icon-edit{background-image:var(--yoast-svg-icon-edit)}.yoast-tooltip.yoast-tooltip-hidden:after,.yoast-tooltip.yoast-tooltip-hidden:before{display:none}.screen-reader-text.wpseo-generic-tab-textual-score,.screen-reader-text.wpseo-keyword-tab-textual-score{display:block}.yoast-notice-go-premium{background:#f1f1f1;border-left-color:#a4286a;margin:0}.emoji-select-button{border-radius:.375rem!important;min-height:28px!important;padding:6px!important;width:28px!important;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}@media screen and (max-width:782px){.wpseo-metabox-buy-premium .wpseo-buy-premium{display:inline-block;height:20px;margin-right:5px;padding:0;width:20px}.yoast-help-panel{max-width:none!important}#wpseo-crawl-issues-table-form .subsubsub{float:none;max-width:calc(100vw - 20px)}#wpseo-crawl-issues-table-form .yoast-help-button{margin-top:3px}.wpseotab select[multiple]{height:auto!important}}@media screen and (max-width:600px){.wpseotab.content{padding:16px 0}}.wpseo-score-icon-container{align-items:center;display:flex;height:20px;justify-content:center;margin-right:8px;width:20px}.yoast-seo-sidebar-panel .yoast-analysis-check{display:flex}.yoast-seo-sidebar-panel .yoast-analysis-check svg{margin-right:5px;margin-top:6px}.yoast-seo-sidebar-panel .yoast-analysis-check span{line-height:1.5;margin-top:3px}.yoast-seo-sidebar-panel div{line-height:2}.yoast-seo-sidebar-panel div svg{vertical-align:middle}ul.yoast-seo-social-share-buttons li{display:inline-block;margin-right:24px}ul.yoast-seo-social-share-buttons li .x-share svg{height:30px;width:30px;fill:#000}ul.yoast-seo-social-share-buttons svg{height:32px;margin-bottom:8px;width:32px}ul.yoast-seo-social-share-buttons a{align-items:center;display:flex;flex-direction:column}.yoast-field-group.yoast-wincher-post-publish{margin-bottom:10px}.edit-post-pinned-plugins button.components-button:not(.is-compact)[aria-label="Yoast SEO Premium"]>svg,.edit-post-pinned-plugins button.components-button:not(.is-compact)[aria-label="Yoast SEO"]>svg,div.interface-pinned-items button.components-button:not(.is-compact)[aria-label="Yoast SEO Premium"]>svg,div.interface-pinned-items button.components-button:not(.is-compact)[aria-label="Yoast SEO"]>svg{height:28px;max-height:28px;max-width:28px;width:28px}div.interface-pinned-items button.components-button.is-pressed[aria-label="Yoast SEO Premium"]>svg path,div.interface-pinned-items button.components-button.is-pressed[aria-label="Yoast SEO"]>svg path{fill:#fff}.wpseo-schema-icon{align-items:center;background-image:var(--yoast-svg-icon-schema);background-size:cover;display:flex;height:16px;justify-content:center;margin-right:8px;width:16px}.wpseo-metabox-menu ul li.active a .wpseo-schema-icon{background-image:var(--yoast-svg-icon-schema-active)}.yoast-icon-span svg{margin-right:8px;fill:inherit}.yoast.components-panel__body{border-top:0}.components-button>.yoast-title-container{flex-grow:1;line-height:normal;overflow-x:hidden}.yoast-title-container>.yoast-subtitle,.yoast-title-container>.yoast-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yoast-title-container>.yoast-subtitle{font-size:.8125rem;font-weight:300;margin-top:2px}.yoast.components-panel__body .yoast-chevron{background-color:#1e1e1e;display:inline-block;height:24px;mask-image:var(--yoast-svg-icon-chevron-down);mask-size:100% 100%;width:24px}.yoast.components-panel__body.is-opened .yoast-chevron{mask-image:var(--yoast-svg-icon-chevron-up)}.yoast .components-panel__body-toggle{padding-right:16px}.yoast .components-form-token-field__remove-token.components-button,.yoast .components-form-token-field__token-text{background-color:var(--yoast-color-primary);color:var(--yoast-color-white)}.yoast .yoast-insights{color:#404040}.yoast .yoast-insights .yoast-field-group__title>b{color:var(--yoast-color-primary);font-size:16px;font-weight:var(--yoast-font-weight-default);line-height:1.2em}.yoast .yoast-insights-card__score{color:var(--yoast-color-primary);margin-block:0}.yoast .yoast-insights-card__description{line-height:1.4em}.yoast .yoast-prominent-words p,.yoast .yoast-prominent-words ul,.yoast .yoast-text-formality p{margin-block:1.2em}.yoast #wpseo-metabox-root .yoast-prominent-words{border-bottom:1px solid #0000001a;margin-bottom:24px;padding-bottom:24px}.yoast .yoast-insights .yoast-data-model--upsell li{color:#bbb}.yoast .yoast-insights .yoast-data-model--upsell li:after{background:#fdf4f8}.yoast-add-block-button{align-items:center;background-color:#fff;border:1px solid #cbd5e1;border-radius:6px;box-shadow:0 1px 2px 0 #0000000d;box-sizing:border-box;cursor:pointer;display:flex;flex-direction:row;height:28px;justify-content:center;padding:6px;width:28px}.yoast-add-block-button--clicked{background-color:var(--yoast-color-primary)}.yoast-add-block-button:focus:not(.yoast-add-block-button--clicked),.yoast-add-block-button:hover:not(.yoast-add-block-button--clicked){background-color:#f8fafc}.yoast-add-block-button__icon{height:16px;width:16px}.yoast-add-block-button__icon--clicked{stroke:#fff} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/metabox-primary-category-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-primary-category-2711-rtl.css new file mode 100644 index 0000000..6070b13 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-primary-category-2711-rtl.css @@ -0,0 +1 @@ +.wpseo-is-primary-term,.wpseo-primary-term>label{font-weight:600}.wpseo-non-primary-term>.wpseo-is-primary-term,.wpseo-primary-term>.wpseo-make-primary-term,.wpseo-term-unchecked>.wpseo-is-primary-term,.wpseo-term-unchecked>.wpseo-make-primary-term{display:none}.wpseo-is-primary-term,.wpseo-make-primary-term{float:left}.wpseo-non-primary-term:after,.wpseo-non-primary-term:before,.wpseo-primary-term:after,.wpseo-primary-term:before{content:"";display:table}.wpseo-non-primary-term:after,.wpseo-primary-term:after{clear:both}.wpseo-make-primary-term{background:none;border:none;color:#0073aa;cursor:pointer;margin:4px 0 0;padding:0;text-decoration:underline}.wpseo-make-primary-term:hover{color:#00a0d2} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/metabox-primary-category-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-primary-category-2711.css new file mode 100644 index 0000000..32b768c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/metabox-primary-category-2711.css @@ -0,0 +1 @@ +.wpseo-is-primary-term,.wpseo-primary-term>label{font-weight:600}.wpseo-non-primary-term>.wpseo-is-primary-term,.wpseo-primary-term>.wpseo-make-primary-term,.wpseo-term-unchecked>.wpseo-is-primary-term,.wpseo-term-unchecked>.wpseo-make-primary-term{display:none}.wpseo-is-primary-term,.wpseo-make-primary-term{float:right}.wpseo-non-primary-term:after,.wpseo-non-primary-term:before,.wpseo-primary-term:after,.wpseo-primary-term:before{content:"";display:table}.wpseo-non-primary-term:after,.wpseo-primary-term:after{clear:both}.wpseo-make-primary-term{background:none;border:none;color:#0073aa;cursor:pointer;margin:4px 0 0;padding:0;text-decoration:underline}.wpseo-make-primary-term:hover{color:#00a0d2} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/modal-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/modal-2711-rtl.css new file mode 100644 index 0000000..c18d360 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/modal-2711-rtl.css @@ -0,0 +1 @@ +.yoast-modal__screen-overlay{animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards;background-color:#a4286a99;bottom:0;right:0;position:fixed;left:0;top:0;z-index:100000}.yoast-modal{background:#fff;bottom:48px;display:flex;flex-direction:column;height:calc(100% - 96px);right:calc(50% - 440px);max-width:880px;overflow:hidden;position:fixed;top:48px;width:100%}.yoast-gutenberg-modal .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:20px;margin-left:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:20px}.yoast-tabs .yoast-modal__content{display:grid;grid-template-areas:"heading heading" "menu content" "menu footer";grid-template-columns:280px 1fr;grid-template-rows:72px 1fr 88px}.yoast-modal__heading{align-items:center;background:var(--yoast-color-white);border-bottom:var(--yoast-border-default);box-sizing:border-box;display:flex;grid-area:heading;min-height:72px;padding:0 24px}.yoast-modal__heading .yoast-close{position:absolute;left:16px}.yoast-gutenberg-modal__box.components-modal__frame{box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}@media (min-width:600px){.yoast-gutenberg-modal__box.components-modal__frame{border-radius:8px;max-height:calc(100% - 48px)}}.yoast-gutenberg-modal__no-padding .components-modal__content{padding:0}.yoast-gutenberg-modal .components-modal__header-heading,.yoast-modal__heading h1{color:var(--yoast-color-primary);font-size:20px;font-weight:400;line-height:1.2;margin:0}.yoast-gutenberg-modal .components-modal__content .components-modal__header{border-bottom:1px solid #e2e8f0!important}.yoast-gutenberg-modal .components-modal__icon-container{display:inline-flex}.yoast-gutenberg-modal .components-modal__icon-container svg,.yoast-modal__heading-icon{fill:var(--yoast-color-primary);flex-shrink:0;height:20px;margin-left:16px;width:19px}.yoast-modal__menu{border-left:var(--yoast-border-default);grid-area:menu;overflow-y:auto}.yoast-modal__menu ul{list-style:none;margin:0;padding:0}.yoast-modal__menu li{border-bottom:var(--yoast-border-default);color:var(--yoast-color-default);cursor:pointer;display:block;font-size:16px;padding:12px 16px 11px;text-decoration:none}.yoast-modal__menu li:hover{background-color:#edd4e1}.yoast-modal__menu li.yoast-tabs__tab--selected{background-color:var(--yoast-color-primary);border-bottom:var(--yoast-border-default);color:#fff}.yoast-modal__content,.yoast-modal__section{display:flex;flex-direction:column;flex-grow:1;grid-area:content;overflow-y:auto;position:relative}.yoast-modal__section *{max-width:600px}.yoast-modal__section-header{background:var(--yoast-color-white);padding:24px 24px 0;position:sticky;top:0;z-index:10}.yoast-modal__section .yoast-h2{border-bottom:var(--yoast-border-default);padding-bottom:24px}.yoast-modal__footer{align-items:center;align-self:flex-end;background:var(--yoast-color-white);border-top:var(--yoast-border-default);bottom:0;box-sizing:border-box;display:flex;grid-area:footer;justify-content:flex-end;margin:0 24px;min-height:88px;padding:0;position:sticky;width:calc(100% - 48px);z-index:10}.yoast-modal__settings-saved{align-items:center;display:inline-flex;margin-left:16px;position:relative}.yoast-modal__settings-saved:before{background:var(--yoast-checkmark--green) no-repeat center;content:"";display:inline-block;height:13px;margin-left:8px;width:14px}.yoast-modal__footer .yoast-button{display:block}.yoast-modal__section-content{flex-grow:1;padding:24px}@media screen and (max-width:880px){.yoast-modal{bottom:0;height:auto;right:0;left:0;top:0}}@media screen and (max-width:782px){.yoast-modal{overflow-y:initial}.yoast-modal.yoast-modal-collapsible{padding-bottom:72px}.yoast-tabs .yoast-modal__content{grid-template-rows:48px 1fr 72px}.yoast-modal__heading{min-height:48px;padding:0 16px;position:fixed;top:0;width:100%;z-index:11}.yoast-modal__heading h1{font-size:var(--yoast-font-size-default)}.yoast-close svg{width:10px}.yoast-modal__heading-icon{height:15px;margin-left:8px}.yoast .yoast-close{left:3px}.yoast-modal__heading .yoast-h2{font-size:var(--yoast-font-size-default)}.yoast-modal__section{flex-grow:0;overflow:initial}.yoast-modal__section-content{margin:0 16px;padding:24px 0}.yoast-modal__section:first-of-type{margin-top:48px}.yoast-modal__section:last-of-type{margin-bottom:72px}.yoast-modal__section-header{margin:0;padding:0;position:sticky;top:48px}.yoast-modal__section-open .yoast-modal__section-header{margin-right:16px;margin-left:16px;padding-right:0;padding-left:0}.yoast-modal__section-open{border-bottom:var(--yoast-border-default)}.yoast-modal__footer{margin:0;min-height:72px;padding:0 16px;position:fixed;width:100%;z-index:11}.yoast-modal-collapsible .yoast-modal__footer{min-height:72px}.yoast-modal-collapsible .yoast-modal__section-content{border-bottom:var(--yoast-border-default);margin:0;padding:24px 16px}.yoast-collapsible__hidden{display:none}.yoast-collapsible__trigger{background:#fff;border:none;border-bottom:var(--yoast-border-default);color:var(--yoast-color-primary);cursor:pointer;font-size:var(--yoast-font-size-default);justify-content:space-between;padding:16px;text-align:right;width:100%}.yoast-collapsible__trigger[aria-expanded=true] .yoast-collapsible__icon{transform:rotate(-180deg)}.yoast-collapsible__trigger[aria-expanded=true]{margin:0 16px;padding:16px 0;width:calc(100% - 32px)}.yoast-collapsible__icon{background-color:var(--yoast-color-white);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23404040' viewBox='0 0 12 8'%3E%3Cpath d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.5 0 1.4z'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:10px auto;border:none;display:block;float:left;height:19px;width:19px}.yoast-collapsible-block{margin-top:48px;width:100%}.yoast-collapsible-block+.yoast-collapsible-block{margin-top:0}}.yoast-post-settings-modal{height:100%;max-height:calc(100% - 96px);max-width:calc(100% - 96px);overflow:hidden;width:880px}.yoast-modal-content{padding:16px}@media (min-width:782px){.yoast-modal-content--columns{display:grid;grid-template-columns:1fr 1fr;grid-gap:24px}}.yoast-post-settings-modal__button-container{border-bottom:1px solid #0003;display:flex;flex-direction:column;padding:16px}.yoast-post-settings-modal .components-modal__content{display:flex;flex-direction:column;padding:0}.yoast-post-settings-modal .components-modal__header{border-bottom:var(--yoast-border-default);flex-shrink:0;margin:0}.yoast-post-settings-modal .yoast-notice-container{bottom:0;right:0;margin-top:auto;position:sticky;width:100%;z-index:1}.yoast-post-settings-modal .components-modal__content>div.components-modal__children-container,.yoast-post-settings-modal .components-modal__content>div:not([class]):not([class=""]){display:flex;flex-direction:column;overflow:hidden}.yoast-post-settings-modal .yoast-notice-container>hr{margin-bottom:0;margin-top:-1px}.yoast-post-settings-modal .yoast-content-container{flex-grow:1;overflow-y:auto}.yoast-post-settings-modal .yoast-button-container{display:flex;flex-direction:row;justify-content:flex-end;margin:0;padding:24px}.yoast-post-settings-modal .yoast-button-container p{align-self:center;color:var(--yoast-color-label-help);padding-left:24px}.yoast-post-settings-modal .yoast-button-container button{align-self:center;flex-shrink:0;max-height:45px}@media only screen and (max-width:600px){.yoast-post-settings-modal{max-height:100%;max-width:100%}.yoast-post-settings-modal .yoast-button-container{justify-content:space-between;padding:16px}.yoast-post-settings-modal .yoast-button-container p{padding-left:0}}.yoast-related-keyphrases-modal,.yoast-wincher-seo-performance-modal{max-width:712px}.yoast-wincher-seo-performance-modal__content{padding:25px 32px 32px}#yoast-get-related-keyphrases-metabox,#yoast-get-related-keyphrases-sidebar{margin-top:8px}.yoast-gutenberg-modal .yoast-related-keyphrases-modal__content{min-height:66vh;position:relative}.yoast-related-keyphrases-modal__chart{display:block} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/modal-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/modal-2711.css new file mode 100644 index 0000000..063768d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/modal-2711.css @@ -0,0 +1 @@ +.yoast-modal__screen-overlay{animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards;background-color:#a4286a99;bottom:0;left:0;position:fixed;right:0;top:0;z-index:100000}.yoast-modal{background:#fff;bottom:48px;display:flex;flex-direction:column;height:calc(100% - 96px);left:calc(50% - 440px);max-width:880px;overflow:hidden;position:fixed;top:48px;width:100%}.yoast-gutenberg-modal .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:20px;margin-right:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:20px}.yoast-tabs .yoast-modal__content{display:grid;grid-template-areas:"heading heading" "menu content" "menu footer";grid-template-columns:280px 1fr;grid-template-rows:72px 1fr 88px}.yoast-modal__heading{align-items:center;background:var(--yoast-color-white);border-bottom:var(--yoast-border-default);box-sizing:border-box;display:flex;grid-area:heading;min-height:72px;padding:0 24px}.yoast-modal__heading .yoast-close{position:absolute;right:16px}.yoast-gutenberg-modal__box.components-modal__frame{box-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a}@media (min-width:600px){.yoast-gutenberg-modal__box.components-modal__frame{border-radius:8px;max-height:calc(100% - 48px)}}.yoast-gutenberg-modal__no-padding .components-modal__content{padding:0}.yoast-gutenberg-modal .components-modal__header-heading,.yoast-modal__heading h1{color:var(--yoast-color-primary);font-size:20px;font-weight:400;line-height:1.2;margin:0}.yoast-gutenberg-modal .components-modal__content .components-modal__header{border-bottom:1px solid #e2e8f0!important}.yoast-gutenberg-modal .components-modal__icon-container{display:inline-flex}.yoast-gutenberg-modal .components-modal__icon-container svg,.yoast-modal__heading-icon{fill:var(--yoast-color-primary);flex-shrink:0;height:20px;margin-right:16px;width:19px}.yoast-modal__menu{border-right:var(--yoast-border-default);grid-area:menu;overflow-y:auto}.yoast-modal__menu ul{list-style:none;margin:0;padding:0}.yoast-modal__menu li{border-bottom:var(--yoast-border-default);color:var(--yoast-color-default);cursor:pointer;display:block;font-size:16px;padding:12px 16px 11px;text-decoration:none}.yoast-modal__menu li:hover{background-color:#edd4e1}.yoast-modal__menu li.yoast-tabs__tab--selected{background-color:var(--yoast-color-primary);border-bottom:var(--yoast-border-default);color:#fff}.yoast-modal__content,.yoast-modal__section{display:flex;flex-direction:column;flex-grow:1;grid-area:content;overflow-y:auto;position:relative}.yoast-modal__section *{max-width:600px}.yoast-modal__section-header{background:var(--yoast-color-white);padding:24px 24px 0;position:sticky;top:0;z-index:10}.yoast-modal__section .yoast-h2{border-bottom:var(--yoast-border-default);padding-bottom:24px}.yoast-modal__footer{align-items:center;align-self:flex-end;background:var(--yoast-color-white);border-top:var(--yoast-border-default);bottom:0;box-sizing:border-box;display:flex;grid-area:footer;justify-content:flex-end;margin:0 24px;min-height:88px;padding:0;position:sticky;width:calc(100% - 48px);z-index:10}.yoast-modal__settings-saved{align-items:center;display:inline-flex;margin-right:16px;position:relative}.yoast-modal__settings-saved:before{background:var(--yoast-checkmark--green) no-repeat center;content:"";display:inline-block;height:13px;margin-right:8px;width:14px}.yoast-modal__footer .yoast-button{display:block}.yoast-modal__section-content{flex-grow:1;padding:24px}@media screen and (max-width:880px){.yoast-modal{bottom:0;height:auto;left:0;right:0;top:0}}@media screen and (max-width:782px){.yoast-modal{overflow-y:initial}.yoast-modal.yoast-modal-collapsible{padding-bottom:72px}.yoast-tabs .yoast-modal__content{grid-template-rows:48px 1fr 72px}.yoast-modal__heading{min-height:48px;padding:0 16px;position:fixed;top:0;width:100%;z-index:11}.yoast-modal__heading h1{font-size:var(--yoast-font-size-default)}.yoast-close svg{width:10px}.yoast-modal__heading-icon{height:15px;margin-right:8px}.yoast .yoast-close{right:3px}.yoast-modal__heading .yoast-h2{font-size:var(--yoast-font-size-default)}.yoast-modal__section{flex-grow:0;overflow:initial}.yoast-modal__section-content{margin:0 16px;padding:24px 0}.yoast-modal__section:first-of-type{margin-top:48px}.yoast-modal__section:last-of-type{margin-bottom:72px}.yoast-modal__section-header{margin:0;padding:0;position:sticky;top:48px}.yoast-modal__section-open .yoast-modal__section-header{margin-left:16px;margin-right:16px;padding-left:0;padding-right:0}.yoast-modal__section-open{border-bottom:var(--yoast-border-default)}.yoast-modal__footer{margin:0;min-height:72px;padding:0 16px;position:fixed;width:100%;z-index:11}.yoast-modal-collapsible .yoast-modal__footer{min-height:72px}.yoast-modal-collapsible .yoast-modal__section-content{border-bottom:var(--yoast-border-default);margin:0;padding:24px 16px}.yoast-collapsible__hidden{display:none}.yoast-collapsible__trigger{background:#fff;border:none;border-bottom:var(--yoast-border-default);color:var(--yoast-color-primary);cursor:pointer;font-size:var(--yoast-font-size-default);justify-content:space-between;padding:16px;text-align:left;width:100%}.yoast-collapsible__trigger[aria-expanded=true] .yoast-collapsible__icon{transform:rotate(180deg)}.yoast-collapsible__trigger[aria-expanded=true]{margin:0 16px;padding:16px 0;width:calc(100% - 32px)}.yoast-collapsible__icon{background-color:var(--yoast-color-white);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23404040' viewBox='0 0 12 8'%3E%3Cpath d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.5 0 1.4z'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:10px auto;border:none;display:block;float:right;height:19px;width:19px}.yoast-collapsible-block{margin-top:48px;width:100%}.yoast-collapsible-block+.yoast-collapsible-block{margin-top:0}}.yoast-post-settings-modal{height:100%;max-height:calc(100% - 96px);max-width:calc(100% - 96px);overflow:hidden;width:880px}.yoast-modal-content{padding:16px}@media (min-width:782px){.yoast-modal-content--columns{display:grid;grid-template-columns:1fr 1fr;grid-gap:24px}}.yoast-post-settings-modal__button-container{border-bottom:1px solid #0003;display:flex;flex-direction:column;padding:16px}.yoast-post-settings-modal .components-modal__content{display:flex;flex-direction:column;padding:0}.yoast-post-settings-modal .components-modal__header{border-bottom:var(--yoast-border-default);flex-shrink:0;margin:0}.yoast-post-settings-modal .yoast-notice-container{bottom:0;left:0;margin-top:auto;position:sticky;width:100%;z-index:1}.yoast-post-settings-modal .components-modal__content>div.components-modal__children-container,.yoast-post-settings-modal .components-modal__content>div:not([class]):not([class=""]){display:flex;flex-direction:column;overflow:hidden}.yoast-post-settings-modal .yoast-notice-container>hr{margin-bottom:0;margin-top:-1px}.yoast-post-settings-modal .yoast-content-container{flex-grow:1;overflow-y:auto}.yoast-post-settings-modal .yoast-button-container{display:flex;flex-direction:row;justify-content:flex-end;margin:0;padding:24px}.yoast-post-settings-modal .yoast-button-container p{align-self:center;color:var(--yoast-color-label-help);padding-right:24px}.yoast-post-settings-modal .yoast-button-container button{align-self:center;flex-shrink:0;max-height:45px}@media only screen and (max-width:600px){.yoast-post-settings-modal{max-height:100%;max-width:100%}.yoast-post-settings-modal .yoast-button-container{justify-content:space-between;padding:16px}.yoast-post-settings-modal .yoast-button-container p{padding-right:0}}.yoast-related-keyphrases-modal,.yoast-wincher-seo-performance-modal{max-width:712px}.yoast-wincher-seo-performance-modal__content{padding:25px 32px 32px}#yoast-get-related-keyphrases-metabox,#yoast-get-related-keyphrases-sidebar{margin-top:8px}.yoast-gutenberg-modal .yoast-related-keyphrases-modal__content{min-height:66vh;position:relative}.yoast-related-keyphrases-modal__chart{display:block} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/monorepo-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/monorepo-2711-rtl.css new file mode 100644 index 0000000..3e0c224 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/monorepo-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-border-default:1px solid #0003;--yoast-color-default:#404040;--yoast-color-default-darker:#303030;--yoast-color-primary:#a4286a;--yoast-color-secondary:#f7f7f7;--yoast-color-white:#fff;--yoast-color-green:#6ea029;--yoast-color-primary-darker:#7b1e50;--yoast-color-primary-lighter:#f5d6e6;--yoast-color-secondary-darker:#d9d9d9;--yoast-color-button-upsell:#fec228;--yoast-color-button-upsell-hover:#f2ae01;--yoast-color-dark:#303030;--yoast-color-sale:#fec228;--yoast-color-sale-darker:#feb601;--yoast-color-border:#0003;--yoast-color-label:#303030;--yoast-color-label-help:#707070;--yoast-color-active:#6ea029;--yoast-color-inactive:#dc3232;--yoast-color-inactive-text:#707070;--yoast-color-inactive-grey:#9e9e9e;--yoast-color-inactive-grey-light:#f1f1f1;--yoast-color-active-light:#b6cf94;--yoast-transition-default:all 150ms ease-out;--yoast-color-link:#006dac;--yoast-color-border--default:#0003;--yoast-color-focus:0 0 0 2px #007fff,0 0 0 5px #bfdfff;--yoast-svg-icon-chevron-down:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-chevron-up:url('data:image/svg+xml;charset=utf-8,');--yoast-checkmark--white:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23FFF' viewBox='0 0 512 512'%3E%3Cpath d='m173.898 439.404-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001'/%3E%3C/svg%3E");--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-edit:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url('data:image/svg+xml;charset=utf-8,');--yoast-checkmark--green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%236EA029' viewBox='0 0 512 512'%3E%3Cpath d='m173.898 439.404-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001'/%3E%3C/svg%3E");--yoast-exclamation-mark:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23DC3232' viewBox='0 0 512 512'%3E%3Cpath d='M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248m-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46m-43.673-165.346 7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654'/%3E%3C/svg%3E");--yoast-svg-icon-schema:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24m181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24m-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24M0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24m386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24m0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24M181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24'/%3E%3C/svg%3E");--yoast-svg-icon-schema-active:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512' aria-hidden='true'%3E%3Cpath fill='D4444' d='M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24m181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24m-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24M0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24m386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24m0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24M181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24'/%3E%3C/svg%3E");--yoast-svg-icon-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23707070' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m4 16 4.586-4.586a2 2 0 0 1 2.828 0L16 16m-2-2 1.586-1.586a2 2 0 0 1 2.828 0L20 14m-6-6h.01M6 20h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2'/%3E%3C/svg%3E");--yoast-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--yoast-font-size-default:14px;--yoast-font-weight-default:400;--yoast-font-weight-bold:600;--yoast-color-font-default:#404040;--yoast-shadow-default:0px 3px 6px #00000026}.yoast-h1,.yoast-h2,.yoast-h3{color:var(--yoast-color-primary);font-weight:400;line-height:1.2;margin:0}.yoast-h1 a,.yoast-h2 a,.yoast-h3 a{color:var(--yoast-color-primary);text-decoration:none}.yoast-h1{font-size:24px}.yoast-h2{font-size:20px}.yoast-h3{font-size:16px}.yoast-paragraph{font-size:var(--yoast-font-size-default);margin-top:0}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);margin:-1px;padding:0;word-wrap:normal!important}.screen-reader-text,.visually-hidden{height:1px;overflow:hidden;position:absolute;width:1px}.visually-hidden{clip:rect(1px,1px,1px,1px);white-space:nowrap;word-wrap:normal}@media (max-width:782px){.yoast-show-on-mobile{display:initial!important}}@media (min-width:782px){.yoast-hide-on-desktop{display:none}}.yoast-field-group__title-separator{display:flex;flex-wrap:wrap}.yoast-field-group__title-separator label{align-items:center;border:var(--yoast-border-default);box-sizing:border-box;cursor:pointer;display:flex;flex-direction:column;height:42px;justify-content:center;margin:0 0 6px 6px;width:42px}.yoast-field-group__title-separator input[type=radio]:checked+label{border:3px solid var(--yoast-color-primary)}.yoast .yoast-button{align-items:center;border:1px solid #0003;border-radius:4px;box-shadow:inset 0 -2px 0 #0000001a;cursor:pointer;display:inline-flex;font-size:14px;justify-content:center;line-height:1.2;padding:10px 12px 12px;position:relative;text-decoration:none;transition:background-color .15s ease-out 0s}.yoast .yoast-button:focus,.yoast-close:focus,.yoast-hide:focus,.yoast-remove:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast .yoast-button::-moz-focus-inner,.yoast-close::-moz-focus-inner,.yoast-hide::-moz-focus-inner,.yoast-remove::-moz-focus-inner{border:0}.yoast .yoast-button:not(:disabled):active{box-shadow:none;top:2px}.yoast .yoast-button:disabled{cursor:default;opacity:.5}.yoast .yoast-button--primary{background-color:var(--yoast-color-primary)}.yoast .yoast-button--primary,.yoast .yoast-button--primary:visited{border:1px solid #0003;color:var(--yoast-color-white)}.yoast .yoast-button--primary:active,.yoast .yoast-button--primary:not(:disabled):hover{background-color:var(--yoast-color-primary-darker);border:1px solid #0003;color:var(--yoast-color-white)}.yoast .yoast-button--primary:focus{background-color:var(--yoast-color-primary);color:var(--yoast-color-white)}.yoast .yoast-button--secondary{background-color:var(--yoast-color-secondary);box-shadow:inset 0 -2px 0 #0000001a;color:var(--yoast-color-dark)}.yoast .yoast-button--secondary:visited{color:var(--yoast-color-dark)}.yoast .yoast-button--secondary:active,.yoast .yoast-button--secondary:not(:disabled):hover{background-color:var(--yoast-color-secondary-darker);border:1px solid #0003;color:var(--yoast-color-dark)}.yoast .yoast-button--buy{background-color:var(--yoast-color-sale)}.yoast .yoast-button--buy,.yoast .yoast-button--buy:visited{color:var(--yoast-color-dark)}.yoast .yoast-button--buy:active,.yoast .yoast-button--buy:not(:disabled):hover{background-color:var(--yoast-color-sale-darker);color:var(--yoast-color-dark)}.yoast .yoast-button--buy__caret{height:16px;margin:0 6px 0 -2px;mask-image:var(--yoast-svg-icon-caret-right);width:6px}.yoast .yoast-button--buy__caret,.yoast .yoast-button--edit{background-color:currentColor;display:inline-block;flex-shrink:0}.yoast .yoast-button--edit{height:18px;margin-left:8px;mask-image:var(--yoast-svg-icon-edit);width:20.25px}html[dir=rtl] .yoast .yoast-button--edit{margin-right:8px;margin-left:0}html[dir=rtl] .yoast .yoast-button--buy{flex-direction:row-reverse}.yoast .yoast-button--small{font-size:13px;padding:5px 8px 8px}.yoast .yoast-button--small .yoast-button--buy__caret{height:10px;width:4px}.yoast-hide,.yoast-remove{background-color:initial;border:none;color:#dc3232;cursor:pointer;font-size:14px;padding:0;text-decoration:underline}.yoast-hide{color:var(--yoast-color-link)}.yoast-field-group__upload .yoast-button{margin-left:24px}.yoast-close{align-items:center;background:none;border:none;box-shadow:none;cursor:pointer;display:flex;height:44px;justify-content:center;padding:0;width:44px}.yoast-close svg{fill:var(--yoast-color-default);width:14px}@media screen and (max-width:782px){.yoast-close svg{width:10px}}.yoast-field-group__checkbox{align-items:center;display:flex}.yoast-field-group__checkbox:not(.yoast-field-group__checkbox--horizontal)+.yoast-field-group__checkbox{margin-top:4px}.yoast-field-group__checkbox label{cursor:pointer}.yoast-field-group__checkbox input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;border:var(--yoast-border-default);border-radius:2px;box-shadow:inset 0 2px 4px #0000001a;cursor:pointer;height:18px;margin:2px 0 0 8px;overflow:hidden;padding:2px;position:relative;transition:background-color .15s ease-out 0s;width:18px}.yoast-field-group__checkbox input[type=checkbox]:checked:focus,.yoast-field-group__checkbox input[type=checkbox]:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast label+input[type=checkbox]{margin-right:16px}.yoast-field-group__checkbox input[type=checkbox]:checked{background:var(--yoast-checkmark--white) var(--yoast-color-primary) no-repeat center /13px;border:1px solid var(--yoast-color-primary);box-shadow:none}.yoast-field-group__checkbox input[type=checkbox]:checked:before{content:""}.yoast-field-group{border:none;margin:0 0 24px;padding:0;position:relative}.yoast-field-group__title{align-items:center;color:var(--yoast-color-label);display:flex;font-size:var(--yoast-font-size-default);font-weight:var(--yoast-font-weight-bold);line-height:1.5;margin:0 0 8px;padding:0}.yoast-field-group__title.yoast-field-group__title--light{font-weight:var(--yoast-font-weight-default)}.yoast-field-group .field-group-description{margin:0 0 1em}.yoast-field-group__inline{align-items:center;display:flex}.yoast-field-group__inline .yoast-field-group__inputfield{margin-left:8px}.yoast-field-group__inline .yoast-button{flex-shrink:0}.yoast-field-group .components-form-token-field__label{display:none}@media screen and (max-width:782px){.yoast-field-group__inline{display:block}.yoast-field-group__inline .yoast-field-group__inputfield{margin-bottom:8px;margin-left:0}}.yoast-help{margin-right:4px}.yoast-help__icon svg{height:12px;width:12px;fill:var(--yoast-color-inactive-text);transition:var(--yoast-transition-default)}.yoast-help:focus svg,.yoast-help:hover svg{fill:var(--yoast-color-link)}.yoast-data-model{list-style:none;padding:0}.yoast-data-model li{font-weight:var(--yoast-font-weight-bold);line-height:1.4;padding:0 8px;position:relative;z-index:2}.yoast-data-model span{float:left;font-weight:var(--yoast-font-weight-default)}.yoast-data-model li+li{margin-top:9px}.yoast-data-model li:after{background:#f5d6e6;content:"";height:20px;right:0;position:absolute;width:var(--yoast-width);z-index:-1}.yoast-image-select__preview{align-items:center;background-color:initial;border:1px solid #0003;display:flex;justify-content:center;max-height:200px;max-width:100%;min-height:165px;overflow:hidden;padding:0;width:300px}.yoast-image-select__preview--no-preview{background:var(--yoast-color-inactive-grey-light) var(--yoast-svg-icon-image) no-repeat center center /64px 64px}.yoast-image-select__preview.yoast-image-select__preview-has-warnings{margin-bottom:16px}.yoast-image-select__preview .yoast-image-select__preview--image{height:100%;max-width:100%;object-fit:contain}.yoast-image-select .yoast-field-group__inputfield{margin-bottom:1em}.yoast-image-select .yoast-button{margin-left:1.5em}.yoast-image-select{margin-bottom:1.7em;margin-top:1.7em}.yoast-image-select .yoast-image-select-buttons button{margin-top:1em}#organization-image-select .yoast-image-select{margin-top:0}:root{--yoast-color-placeholder:#707070}.yoast .yoast-field-group__inputfield,.yoast .yoast-field-group__textarea{background:var(--yoast-color-white);border:var(--yoast-border-default);border-radius:0;box-shadow:inset 0 2px 4px #0000001a;box-sizing:border-box;font-size:var(--yoast-font-size-default);padding:8px;width:100%}.yoast .yoast-field-group__inputfield:focus,.yoast .yoast-field-group__textarea:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast-field-group__upload .yoast-field-group__inputfield{margin-bottom:8px}.yoast-field-group__inputfield{height:40px}.yoast-field-group__textarea{min-height:200px}.yoast input+.description,.yoast-field-group .description+.yoast-field-group__inputfield,.yoast-field-group .description+input,.yoast-field-group__inputfield+.description{margin-bottom:24px;margin-top:8px}.yoast .yoast-field-group__inputfield:disabled,.yoast .yoast-field-group__inputfield:read-only,.yoast .yoast-field-group__inputfield[aria-disabled=true]{background:var(--yoast-color-inactive-grey-light)}.yoast .duration-inputs__wrapper{display:flex;flex-direction:row}.yoast .duration-inputs__input-wrapper{display:flex;flex-direction:column}.yoast .duration-inputs__input{margin:0 0 0 8px;width:4em}::placeholder{color:var(--yoast-color-placeholder);opacity:1}.yoast-insights-row:not(:last-of-type){border-bottom:1px solid #0000001a;margin-bottom:24px;padding-bottom:24px}.yoast-insights-row--columns{display:grid;grid-template-columns:1fr 1fr;grid-gap:24px}@media(min-width:782px){.yoast-modal-content .yoast-insights-row{border-bottom:1px solid #0000001a;margin-bottom:24px;padding-bottom:24px}}.yoast-insights-card__content{display:flex}.yoast-insights-card__score{flex-shrink:0;font-size:16px;margin-left:2em}.yoast-insights-card__amount{display:block;font-size:3.5em;line-height:1}.yoast-field-group__radiobutton{align-items:center;display:flex}.yoast-field-group__radiobutton--vertical:not(:last-of-type){margin-bottom:8px}.yoast-field-group__radiobutton label{cursor:pointer;margin-left:16px}.yoast-field-group__radiobutton input[type=radio]{-webkit-appearance:none;-moz-appearance:none;border:var(--yoast-border-default);border-radius:50%;box-shadow:inset 0 2px 4px #0000001a;cursor:pointer;height:18px;margin:0 0 0 8px;overflow:hidden;padding:2px;position:relative;transition:border-color .15s ease-out 0s;width:18px}.yoast-field-group__radiobutton input[type=radio]:checked:focus,.yoast-field-group__radiobutton input[type=radio]:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast-field-group__radiobutton input[type=radio]:checked{background-color:inherit;border-color:var(--yoast-color-primary)}.yoast-field-group__radiobutton input[type=radio]:checked:before{content:none}.yoast-field-group__radiobutton input[type=radio]:after{background-color:initial;border-radius:50%;content:"";display:block;height:10px;right:3px;position:absolute;top:3px;transition:background-color .15s ease-out 0s;width:10px}.yoast-field-group__radiobutton input[type=radio]:checked:after{background-color:var(--yoast-color-primary)}.yoast-field-group__select{align-items:center;cursor:pointer;display:flex}.yoast-select__indicator-separator{display:none}.yoast-select-container{background-color:#fff;border:var(--yoast-border-default);border-radius:0;box-shadow:inset 0 2px 4px #0000001a;display:block;min-height:2.85em;padding:0;position:relative;width:100%}.yoast-select-container .yoast-select__control--is-focused{box-shadow:var(--yoast-color-focus);outline:none}.yoast-select-container .yoast-select__indicator>svg{color:#212121}.yoast-select-container .yoast-select__menu{margin:0;z-index:2}.yoast-select-container .yoast-select__multi-value__label{align-items:center;box-sizing:border-box;color:inherit;display:flex;font-size:14px;padding:0}.yoast-select-container .yoast-select__multi-value{background-color:var(--yoast-color-primary);border:0;border-radius:12px;color:var(--yoast-color-white);display:flex;flex-direction:row-reverse;font-weight:500;line-height:1.5;margin-bottom:3px;margin-left:8px;margin-top:3px;padding:1px 10px 2px}.yoast-select-container .yoast-select__menu-list{padding:0}.yoast-select-container .yoast-select__multi-value__remove{align-items:center;border-radius:2px;box-sizing:border-box;display:flex;padding:2px 0 0;-webkit-box-align:center;margin-left:6px}.yoast-select-container .yoast-select__multi-value__remove:hover{background-color:inherit;color:var(--yoast-color-white);cursor:pointer}.yoast-select-container .yoast-select__control{background-color:initial;border:none;border-radius:0}.yoast-select-container .yoast-select__option{box-sizing:border-box;color:inherit;cursor:default;display:block;padding:8px 12px;-webkit-user-select:none;user-select:none;width:100%}.yoast-select-container .yoast-select__option--is-focused{background-color:var(--yoast-color-primary-lighter);color:var(--yoast-color-font-default)}.yoast-select-container .yoast-select__option.yoast-select__option--is-selected{background-color:var(--yoast-color-primary);color:var(--yoast-color-white)}.yoast-select-container input[type=text]:focus{box-shadow:none}.yoast-field-group select,.yoast-field-group__select select{-webkit-appearance:none;-moz-appearance:none;background-color:#fff;background-image:url('data:image/svg+xml;charset=utf-8,');background-position:left 15px center;background-repeat:no-repeat;background-size:13px auto;border:var(--yoast-border-default);border-radius:0;box-shadow:inset 0 2px 4px #0000001a;display:block;font-size:var(--yoast-font-size-default);max-width:300px;min-height:2.85em;padding:5px 8px;position:relative;width:100%}.yoast-field-group .yoast-select__value-container{padding:0 8px!important}.yoast-field-group select:focus,.yoast-field-group__select select:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast-field-group select,.yoast-field-group__select select{line-height:1.9;padding-left:40px}.yoast-field-group select.yoast-select--inline{display:inline-block}.yoast-field-group--inline{display:inline-block;margin-left:8px;max-width:300px;width:100%}.yoast-star-rating{display:inline-block;height:12px;width:65px}.yoast-star-rating span{background-repeat:repeat-x;background-size:13px 12px;height:100%;width:100%}.yoast-star-rating__placeholder{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAmCAQAAAAYCMGrAAAA+klEQVR4AcWV4cbtMBBFF0MIVUopoVSrhDDv/3gf/RFRpzdNOty1HiBO99mzeYWgCMZMKCPGrCgrxiSUhCkDeukxJKCXAUMiehkxw6FZhxEzmp0x4kCzByYISqlYdal0supS6WrVpdLEK0YSamJiJOPY0c/uOG4s6CcXfuKJaJcRzyNCQJsNiF1sRTR1hP11NNJ8RCrONOPRf+r7J+TZgQ5CNfMOYvW/2YxDqzqA/57+gVY9eiakrnyZEGXDsaE3p/4JScwPX3rtnZATDxnPWT7X16XAHaH8HWNrlxJD9TyGti5tCM84zpZe+RxNjeX9tZqLaGoMxN/P/wHP5Vw+8ZxnEQAAAABJRU5ErkJggg==);display:inline-block;overflow:hidden;position:relative}.yoast-star-rating__fill{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAmBAMAAABALxQTAAAAFVBMVEVMaXH4twP4twP4twP4twP4twP4twP7w8S/AAAAB3RSTlMAFv5uPpvQloUsTQAAAMFJREFUeAGE0TEOgzAMQFEXoDNiYC6/wFxxAsTADDkB5f6HqNRENXUi8TYiRfnY8lNXkjBOkuBWSeAhsYJOYiW9xO4MEqshkTbCSyIH7GLdgFasHHgmwkikZQD6OROZRG4Hxju8o/TNhbNhCqkOxaZDVKdxNnq/EjUS/A2o0PuXpyVeb9bjDWY9QSWXDQfBbtbjtWY9bM4sqfx+5yYt8wNcAFEzrGGkk5668KsFrKewPtQ3aFqh8WOnYZ+lIBQkgykAWk8rlAqcHfQAAAAASUVORK5CYII=);display:block}.yoast-table{border:var(--yoast-border-default);border-bottom:0;border-spacing:0;color:var(--yoast-color-default);font-size:var(--yoast-font-size-default);line-height:1.2;width:100%}.yoast-table tbody tr:nth-child(odd){background-color:#f9f9f9}.yoast-table th{color:var(--yoast-color-dark);font-weight:var(--yoast-font-weight-bold);text-align:right;white-space:nowrap}.yoast-table td,.yoast-table th{border-bottom:var(--yoast-border-default);padding:18px 12px}.yoast-table td:first-child,.yoast-table th:first-child{padding-right:16px}.yoast-table td:last-child,.yoast-table th:last-child{padding-left:16px}td.yoast-table__button,td.yoast-table__image{padding:10px 18px 9px}.yoast-table.yoast-table--nobreak td,td.yoast-table--nobreak,tr.yoast-table--nobreak td{white-space:nowrap}th.yoast-table--primary{width:100%}td.yoast-table--nopadding{padding:0 12px}.yoast-badge{border-radius:8px;display:inline-block;font-size:10px;font-weight:600;line-height:1.6;min-height:16px;padding:0 8px}.yoast-badge__in-label{margin-right:8px;vertical-align:text-top}.yoast-new-badge{background-color:#cce5ff;color:#004973}.yoast-premium-badge{background-color:#fff3cd;color:#674e00}.yoast-beta-badge{background-color:#cce5ff;color:#004973;margin:0 0 0 2px}.yoast-feature{margin-left:150px;max-width:600px}.yoast-toggle__item{border-bottom:1px solid var(--yoast-color-border);display:flex;justify-content:space-between;margin-bottom:16px;padding-bottom:16px}.yoast-toggle__item-disabled{position:relative}.yoast-toggle__item-disabled .yoast-button.yoast-button--buy{right:100%;margin-right:32px;position:absolute;white-space:nowrap}.yoast-toggle__item-disabled .yoast-toggle,.yoast-toggle__item-disabled .yoast-toggle__item-title{opacity:.5}.yoast-toggle__item-title{align-items:center;display:flex;font-weight:700}input[type=checkbox].yoast-toggle__checkbox{-webkit-appearance:none;-moz-appearance:none;background-color:initial;border:0;box-shadow:none;height:23px;margin-right:8px;overflow:hidden;position:absolute;width:34px;z-index:1}input[type=checkbox].yoast-toggle__checkbox:checked:before{content:none}.yoast-toggle__switch{background-color:var(--yoast-color-inactive-grey);border-radius:8px;display:inline-block;height:14px;margin-right:8px;margin-left:8px;position:relative;width:34px}.yoast-toggle__checkbox:focus~.yoast-toggle__switch:before{box-shadow:var(--yoast-color-focus)}.yoast-toggle__switch:before{background-color:var(--yoast-color-inactive-grey-light);border:.5px solid #0000001a;border-radius:50%;box-shadow:0 1px 2px 0 #0006;box-sizing:border-box;content:"";height:20px;right:0;position:absolute;top:-3px;width:20px}.yoast-toggle,.yoast-toggle--inverse{align-items:center;display:grid;grid-template:1fr/repeat(3,auto);position:relative}.yoast-toggle--inverse>*,.yoast-toggle>*{grid-row:1}.yoast-toggle--inactive,.yoast-toggle--inverse .yoast-toggle--active{grid-column:1}.yoast-toggle__checkbox,.yoast-toggle__switch{grid-column:2}.yoast-toggle--active,.yoast-toggle--inverse .yoast-toggle--inactive{grid-column:3}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle__switch,.yoast-toggle--inverse .yoast-toggle__checkbox:not(:checked)~.yoast-toggle__switch{background-color:var(--yoast-color-active-light)}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle__switch:before,.yoast-toggle--inverse .yoast-toggle__checkbox:not(:checked)~.yoast-toggle__switch:before{background-color:var(--yoast-color-active);right:auto;left:0}.yoast-toggle--inverse .yoast-toggle__checkbox:checked~.yoast-toggle__switch:before{right:0;left:auto}.yoast-toggle .yoast-toggle__checkbox~.yoast-toggle--inactive,.yoast-toggle--inverse .yoast-toggle__checkbox~.yoast-toggle--inactive{color:var(--yoast-color-default-darker)}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle--inactive,.yoast-toggle .yoast-toggle__checkbox~.yoast-toggle--active,.yoast-toggle--inverse .yoast-toggle__checkbox:checked~.yoast-toggle--inactive,.yoast-toggle--inverse .yoast-toggle__checkbox~.yoast-toggle--active{color:var(--yoast-color-inactive-text)}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle--active,.yoast-toggle--inverse .yoast-toggle__checkbox:checked~.yoast-toggle--active{color:var(--yoast-color-default-darker)}@media(max-width:400px){.yoast-feature{margin-left:0}.yoast-toggle__item-disabled{flex-wrap:wrap}.yoast-toggle__item-disabled .yoast-button.yoast-button--buy{margin-right:0;margin-top:8px;position:static}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/monorepo-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/monorepo-2711.css new file mode 100644 index 0000000..8369d4a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/monorepo-2711.css @@ -0,0 +1 @@ +:root{--yoast-border-default:1px solid #0003;--yoast-color-default:#404040;--yoast-color-default-darker:#303030;--yoast-color-primary:#a4286a;--yoast-color-secondary:#f7f7f7;--yoast-color-white:#fff;--yoast-color-green:#6ea029;--yoast-color-primary-darker:#7b1e50;--yoast-color-primary-lighter:#f5d6e6;--yoast-color-secondary-darker:#d9d9d9;--yoast-color-button-upsell:#fec228;--yoast-color-button-upsell-hover:#f2ae01;--yoast-color-dark:#303030;--yoast-color-sale:#fec228;--yoast-color-sale-darker:#feb601;--yoast-color-border:#0003;--yoast-color-label:#303030;--yoast-color-label-help:#707070;--yoast-color-active:#6ea029;--yoast-color-inactive:#dc3232;--yoast-color-inactive-text:#707070;--yoast-color-inactive-grey:#9e9e9e;--yoast-color-inactive-grey-light:#f1f1f1;--yoast-color-active-light:#b6cf94;--yoast-transition-default:all 150ms ease-out;--yoast-color-link:#006dac;--yoast-color-border--default:#0003;--yoast-color-focus:0 0 0 2px #007fff,0 0 0 5px #bfdfff;--yoast-svg-icon-chevron-down:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-chevron-up:url('data:image/svg+xml;charset=utf-8,');--yoast-checkmark--white:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23FFF' viewBox='0 0 512 512'%3E%3Cpath d='m173.898 439.404-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001'/%3E%3C/svg%3E");--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-edit:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url('data:image/svg+xml;charset=utf-8,');--yoast-checkmark--green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%236EA029' viewBox='0 0 512 512'%3E%3Cpath d='m173.898 439.404-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001'/%3E%3C/svg%3E");--yoast-exclamation-mark:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23DC3232' viewBox='0 0 512 512'%3E%3Cpath d='M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248m-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46m-43.673-165.346 7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654'/%3E%3C/svg%3E");--yoast-svg-icon-schema:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24m181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24m-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24M0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24m386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24m0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24M181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24'/%3E%3C/svg%3E");--yoast-svg-icon-schema-active:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='512' height='512' aria-hidden='true'%3E%3Cpath fill='D4444' d='M149.333 56v80c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V56c0-13.255 10.745-24 24-24h101.333c13.255 0 24 10.745 24 24m181.334 240v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m32-240v80c0 13.255 10.745 24 24 24H488c13.255 0 24-10.745 24-24V56c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24m-32 80V56c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.256 0 24.001-10.745 24.001-24m-205.334 56H24c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24M0 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H24c-13.255 0-24 10.745-24 24m386.667-56H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24m0 160H488c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H386.667c-13.255 0-24 10.745-24 24v80c0 13.255 10.745 24 24 24M181.333 376v80c0 13.255 10.745 24 24 24h101.333c13.255 0 24-10.745 24-24v-80c0-13.255-10.745-24-24-24H205.333c-13.255 0-24 10.745-24 24'/%3E%3C/svg%3E");--yoast-svg-icon-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='%23707070' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m4 16 4.586-4.586a2 2 0 0 1 2.828 0L16 16m-2-2 1.586-1.586a2 2 0 0 1 2.828 0L20 14m-6-6h.01M6 20h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2'/%3E%3C/svg%3E");--yoast-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;--yoast-font-size-default:14px;--yoast-font-weight-default:400;--yoast-font-weight-bold:600;--yoast-color-font-default:#404040;--yoast-shadow-default:0px 3px 6px #00000026}.yoast-h1,.yoast-h2,.yoast-h3{color:var(--yoast-color-primary);font-weight:400;line-height:1.2;margin:0}.yoast-h1 a,.yoast-h2 a,.yoast-h3 a{color:var(--yoast-color-primary);text-decoration:none}.yoast-h1{font-size:24px}.yoast-h2{font-size:20px}.yoast-h3{font-size:16px}.yoast-paragraph{font-size:var(--yoast-font-size-default);margin-top:0}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);margin:-1px;padding:0;word-wrap:normal!important}.screen-reader-text,.visually-hidden{height:1px;overflow:hidden;position:absolute;width:1px}.visually-hidden{clip:rect(1px,1px,1px,1px);white-space:nowrap;word-wrap:normal}@media (max-width:782px){.yoast-show-on-mobile{display:initial!important}}@media (min-width:782px){.yoast-hide-on-desktop{display:none}}.yoast-field-group__title-separator{display:flex;flex-wrap:wrap}.yoast-field-group__title-separator label{align-items:center;border:var(--yoast-border-default);box-sizing:border-box;cursor:pointer;display:flex;flex-direction:column;height:42px;justify-content:center;margin:0 6px 6px 0;width:42px}.yoast-field-group__title-separator input[type=radio]:checked+label{border:3px solid var(--yoast-color-primary)}.yoast .yoast-button{align-items:center;border:1px solid #0003;border-radius:4px;box-shadow:inset 0 -2px 0 #0000001a;cursor:pointer;display:inline-flex;font-size:14px;justify-content:center;line-height:1.2;padding:10px 12px 12px;position:relative;text-decoration:none;transition:background-color .15s ease-out 0s}.yoast .yoast-button:focus,.yoast-close:focus,.yoast-hide:focus,.yoast-remove:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast .yoast-button::-moz-focus-inner,.yoast-close::-moz-focus-inner,.yoast-hide::-moz-focus-inner,.yoast-remove::-moz-focus-inner{border:0}.yoast .yoast-button:not(:disabled):active{box-shadow:none;top:2px}.yoast .yoast-button:disabled{cursor:default;opacity:.5}.yoast .yoast-button--primary{background-color:var(--yoast-color-primary)}.yoast .yoast-button--primary,.yoast .yoast-button--primary:visited{border:1px solid #0003;color:var(--yoast-color-white)}.yoast .yoast-button--primary:active,.yoast .yoast-button--primary:not(:disabled):hover{background-color:var(--yoast-color-primary-darker);border:1px solid #0003;color:var(--yoast-color-white)}.yoast .yoast-button--primary:focus{background-color:var(--yoast-color-primary);color:var(--yoast-color-white)}.yoast .yoast-button--secondary{background-color:var(--yoast-color-secondary);box-shadow:inset 0 -2px 0 #0000001a;color:var(--yoast-color-dark)}.yoast .yoast-button--secondary:visited{color:var(--yoast-color-dark)}.yoast .yoast-button--secondary:active,.yoast .yoast-button--secondary:not(:disabled):hover{background-color:var(--yoast-color-secondary-darker);border:1px solid #0003;color:var(--yoast-color-dark)}.yoast .yoast-button--buy{background-color:var(--yoast-color-sale)}.yoast .yoast-button--buy,.yoast .yoast-button--buy:visited{color:var(--yoast-color-dark)}.yoast .yoast-button--buy:active,.yoast .yoast-button--buy:not(:disabled):hover{background-color:var(--yoast-color-sale-darker);color:var(--yoast-color-dark)}.yoast .yoast-button--buy__caret{height:16px;margin:0 -2px 0 6px;mask-image:var(--yoast-svg-icon-caret-right);width:6px}.yoast .yoast-button--buy__caret,.yoast .yoast-button--edit{background-color:currentColor;display:inline-block;flex-shrink:0}.yoast .yoast-button--edit{height:18px;margin-right:8px;mask-image:var(--yoast-svg-icon-edit);width:20.25px}html[dir=rtl] .yoast .yoast-button--edit{margin-left:8px;margin-right:0}html[dir=rtl] .yoast .yoast-button--buy{flex-direction:row-reverse}.yoast .yoast-button--small{font-size:13px;padding:5px 8px 8px}.yoast .yoast-button--small .yoast-button--buy__caret{height:10px;width:4px}.yoast-hide,.yoast-remove{background-color:initial;border:none;color:#dc3232;cursor:pointer;font-size:14px;padding:0;text-decoration:underline}.yoast-hide{color:var(--yoast-color-link)}.yoast-field-group__upload .yoast-button{margin-right:24px}.yoast-close{align-items:center;background:none;border:none;box-shadow:none;cursor:pointer;display:flex;height:44px;justify-content:center;padding:0;width:44px}.yoast-close svg{fill:var(--yoast-color-default);width:14px}@media screen and (max-width:782px){.yoast-close svg{width:10px}}.yoast-field-group__checkbox{align-items:center;display:flex}.yoast-field-group__checkbox:not(.yoast-field-group__checkbox--horizontal)+.yoast-field-group__checkbox{margin-top:4px}.yoast-field-group__checkbox label{cursor:pointer}.yoast-field-group__checkbox input[type=checkbox]{-webkit-appearance:none;-moz-appearance:none;border:var(--yoast-border-default);border-radius:2px;box-shadow:inset 0 2px 4px #0000001a;cursor:pointer;height:18px;margin:2px 8px 0 0;overflow:hidden;padding:2px;position:relative;transition:background-color .15s ease-out 0s;width:18px}.yoast-field-group__checkbox input[type=checkbox]:checked:focus,.yoast-field-group__checkbox input[type=checkbox]:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast label+input[type=checkbox]{margin-left:16px}.yoast-field-group__checkbox input[type=checkbox]:checked{background:var(--yoast-checkmark--white) var(--yoast-color-primary) no-repeat center /13px;border:1px solid var(--yoast-color-primary);box-shadow:none}.yoast-field-group__checkbox input[type=checkbox]:checked:before{content:""}.yoast-field-group{border:none;margin:0 0 24px;padding:0;position:relative}.yoast-field-group__title{align-items:center;color:var(--yoast-color-label);display:flex;font-size:var(--yoast-font-size-default);font-weight:var(--yoast-font-weight-bold);line-height:1.5;margin:0 0 8px;padding:0}.yoast-field-group__title.yoast-field-group__title--light{font-weight:var(--yoast-font-weight-default)}.yoast-field-group .field-group-description{margin:0 0 1em}.yoast-field-group__inline{align-items:center;display:flex}.yoast-field-group__inline .yoast-field-group__inputfield{margin-right:8px}.yoast-field-group__inline .yoast-button{flex-shrink:0}.yoast-field-group .components-form-token-field__label{display:none}@media screen and (max-width:782px){.yoast-field-group__inline{display:block}.yoast-field-group__inline .yoast-field-group__inputfield{margin-bottom:8px;margin-right:0}}.yoast-help{margin-left:4px}.yoast-help__icon svg{height:12px;width:12px;fill:var(--yoast-color-inactive-text);transition:var(--yoast-transition-default)}.yoast-help:focus svg,.yoast-help:hover svg{fill:var(--yoast-color-link)}.yoast-data-model{list-style:none;padding:0}.yoast-data-model li{font-weight:var(--yoast-font-weight-bold);line-height:1.4;padding:0 8px;position:relative;z-index:2}.yoast-data-model span{float:right;font-weight:var(--yoast-font-weight-default)}.yoast-data-model li+li{margin-top:9px}.yoast-data-model li:after{background:#f5d6e6;content:"";height:20px;left:0;position:absolute;width:var(--yoast-width);z-index:-1}.yoast-image-select__preview{align-items:center;background-color:initial;border:1px solid #0003;display:flex;justify-content:center;max-height:200px;max-width:100%;min-height:165px;overflow:hidden;padding:0;width:300px}.yoast-image-select__preview--no-preview{background:var(--yoast-color-inactive-grey-light) var(--yoast-svg-icon-image) no-repeat center center /64px 64px}.yoast-image-select__preview.yoast-image-select__preview-has-warnings{margin-bottom:16px}.yoast-image-select__preview .yoast-image-select__preview--image{height:100%;max-width:100%;object-fit:contain}.yoast-image-select .yoast-field-group__inputfield{margin-bottom:1em}.yoast-image-select .yoast-button{margin-right:1.5em}.yoast-image-select{margin-bottom:1.7em;margin-top:1.7em}.yoast-image-select .yoast-image-select-buttons button{margin-top:1em}#organization-image-select .yoast-image-select{margin-top:0}:root{--yoast-color-placeholder:#707070}.yoast .yoast-field-group__inputfield,.yoast .yoast-field-group__textarea{background:var(--yoast-color-white);border:var(--yoast-border-default);border-radius:0;box-shadow:inset 0 2px 4px #0000001a;box-sizing:border-box;font-size:var(--yoast-font-size-default);padding:8px;width:100%}.yoast .yoast-field-group__inputfield:focus,.yoast .yoast-field-group__textarea:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast-field-group__upload .yoast-field-group__inputfield{margin-bottom:8px}.yoast-field-group__inputfield{height:40px}.yoast-field-group__textarea{min-height:200px}.yoast input+.description,.yoast-field-group .description+.yoast-field-group__inputfield,.yoast-field-group .description+input,.yoast-field-group__inputfield+.description{margin-bottom:24px;margin-top:8px}.yoast .yoast-field-group__inputfield:disabled,.yoast .yoast-field-group__inputfield:read-only,.yoast .yoast-field-group__inputfield[aria-disabled=true]{background:var(--yoast-color-inactive-grey-light)}.yoast .duration-inputs__wrapper{display:flex;flex-direction:row}.yoast .duration-inputs__input-wrapper{display:flex;flex-direction:column}.yoast .duration-inputs__input{margin:0 8px 0 0;width:4em}::placeholder{color:var(--yoast-color-placeholder);opacity:1}.yoast-insights-row:not(:last-of-type){border-bottom:1px solid #0000001a;margin-bottom:24px;padding-bottom:24px}.yoast-insights-row--columns{display:grid;grid-template-columns:1fr 1fr;grid-gap:24px}@media(min-width:782px){.yoast-modal-content .yoast-insights-row{border-bottom:1px solid #0000001a;margin-bottom:24px;padding-bottom:24px}}.yoast-insights-card__content{display:flex}.yoast-insights-card__score{flex-shrink:0;font-size:16px;margin-right:2em}.yoast-insights-card__amount{display:block;font-size:3.5em;line-height:1}.yoast-field-group__radiobutton{align-items:center;display:flex}.yoast-field-group__radiobutton--vertical:not(:last-of-type){margin-bottom:8px}.yoast-field-group__radiobutton label{cursor:pointer;margin-right:16px}.yoast-field-group__radiobutton input[type=radio]{-webkit-appearance:none;-moz-appearance:none;border:var(--yoast-border-default);border-radius:50%;box-shadow:inset 0 2px 4px #0000001a;cursor:pointer;height:18px;margin:0 8px 0 0;overflow:hidden;padding:2px;position:relative;transition:border-color .15s ease-out 0s;width:18px}.yoast-field-group__radiobutton input[type=radio]:checked:focus,.yoast-field-group__radiobutton input[type=radio]:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast-field-group__radiobutton input[type=radio]:checked{background-color:inherit;border-color:var(--yoast-color-primary)}.yoast-field-group__radiobutton input[type=radio]:checked:before{content:none}.yoast-field-group__radiobutton input[type=radio]:after{background-color:initial;border-radius:50%;content:"";display:block;height:10px;left:3px;position:absolute;top:3px;transition:background-color .15s ease-out 0s;width:10px}.yoast-field-group__radiobutton input[type=radio]:checked:after{background-color:var(--yoast-color-primary)}.yoast-field-group__select{align-items:center;cursor:pointer;display:flex}.yoast-select__indicator-separator{display:none}.yoast-select-container{background-color:#fff;border:var(--yoast-border-default);border-radius:0;box-shadow:inset 0 2px 4px #0000001a;display:block;min-height:2.85em;padding:0;position:relative;width:100%}.yoast-select-container .yoast-select__control--is-focused{box-shadow:var(--yoast-color-focus);outline:none}.yoast-select-container .yoast-select__indicator>svg{color:#212121}.yoast-select-container .yoast-select__menu{margin:0;z-index:2}.yoast-select-container .yoast-select__multi-value__label{align-items:center;box-sizing:border-box;color:inherit;display:flex;font-size:14px;padding:0}.yoast-select-container .yoast-select__multi-value{background-color:var(--yoast-color-primary);border:0;border-radius:12px;color:var(--yoast-color-white);display:flex;flex-direction:row-reverse;font-weight:500;line-height:1.5;margin-bottom:3px;margin-right:8px;margin-top:3px;padding:1px 10px 2px}.yoast-select-container .yoast-select__menu-list{padding:0}.yoast-select-container .yoast-select__multi-value__remove{align-items:center;border-radius:2px;box-sizing:border-box;display:flex;padding:2px 0 0;-webkit-box-align:center;margin-right:6px}.yoast-select-container .yoast-select__multi-value__remove:hover{background-color:inherit;color:var(--yoast-color-white);cursor:pointer}.yoast-select-container .yoast-select__control{background-color:initial;border:none;border-radius:0}.yoast-select-container .yoast-select__option{box-sizing:border-box;color:inherit;cursor:default;display:block;padding:8px 12px;-webkit-user-select:none;user-select:none;width:100%}.yoast-select-container .yoast-select__option--is-focused{background-color:var(--yoast-color-primary-lighter);color:var(--yoast-color-font-default)}.yoast-select-container .yoast-select__option.yoast-select__option--is-selected{background-color:var(--yoast-color-primary);color:var(--yoast-color-white)}.yoast-select-container input[type=text]:focus{box-shadow:none}.yoast-field-group select,.yoast-field-group__select select{-webkit-appearance:none;-moz-appearance:none;background-color:#fff;background-image:url('data:image/svg+xml;charset=utf-8,');background-position:right 15px center;background-repeat:no-repeat;background-size:13px auto;border:var(--yoast-border-default);border-radius:0;box-shadow:inset 0 2px 4px #0000001a;display:block;font-size:var(--yoast-font-size-default);max-width:300px;min-height:2.85em;padding:5px 8px;position:relative;width:100%}.yoast-field-group .yoast-select__value-container{padding:0 8px!important}.yoast-field-group select:focus,.yoast-field-group__select select:focus{box-shadow:var(--yoast-color-focus);outline:none}.yoast-field-group select,.yoast-field-group__select select{line-height:1.9;padding-right:40px}.yoast-field-group select.yoast-select--inline{display:inline-block}.yoast-field-group--inline{display:inline-block;margin-right:8px;max-width:300px;width:100%}.yoast-star-rating{display:inline-block;height:12px;width:65px}.yoast-star-rating span{background-repeat:repeat-x;background-size:13px 12px;height:100%;width:100%}.yoast-star-rating__placeholder{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAmCAQAAAAYCMGrAAAA+klEQVR4AcWV4cbtMBBFF0MIVUopoVSrhDDv/3gf/RFRpzdNOty1HiBO99mzeYWgCMZMKCPGrCgrxiSUhCkDeukxJKCXAUMiehkxw6FZhxEzmp0x4kCzByYISqlYdal0supS6WrVpdLEK0YSamJiJOPY0c/uOG4s6CcXfuKJaJcRzyNCQJsNiF1sRTR1hP11NNJ8RCrONOPRf+r7J+TZgQ5CNfMOYvW/2YxDqzqA/57+gVY9eiakrnyZEGXDsaE3p/4JScwPX3rtnZATDxnPWT7X16XAHaH8HWNrlxJD9TyGti5tCM84zpZe+RxNjeX9tZqLaGoMxN/P/wHP5Vw+8ZxnEQAAAABJRU5ErkJggg==);display:inline-block;overflow:hidden;position:relative}.yoast-star-rating__fill{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACoAAAAmBAMAAABALxQTAAAAFVBMVEVMaXH4twP4twP4twP4twP4twP4twP7w8S/AAAAB3RSTlMAFv5uPpvQloUsTQAAAMFJREFUeAGE0TEOgzAMQFEXoDNiYC6/wFxxAsTADDkB5f6HqNRENXUi8TYiRfnY8lNXkjBOkuBWSeAhsYJOYiW9xO4MEqshkTbCSyIH7GLdgFasHHgmwkikZQD6OROZRG4Hxju8o/TNhbNhCqkOxaZDVKdxNnq/EjUS/A2o0PuXpyVeb9bjDWY9QSWXDQfBbtbjtWY9bM4sqfx+5yYt8wNcAFEzrGGkk5668KsFrKewPtQ3aFqh8WOnYZ+lIBQkgykAWk8rlAqcHfQAAAAASUVORK5CYII=);display:block}.yoast-table{border:var(--yoast-border-default);border-bottom:0;border-spacing:0;color:var(--yoast-color-default);font-size:var(--yoast-font-size-default);line-height:1.2;width:100%}.yoast-table tbody tr:nth-child(odd){background-color:#f9f9f9}.yoast-table th{color:var(--yoast-color-dark);font-weight:var(--yoast-font-weight-bold);text-align:left;white-space:nowrap}.yoast-table td,.yoast-table th{border-bottom:var(--yoast-border-default);padding:18px 12px}.yoast-table td:first-child,.yoast-table th:first-child{padding-left:16px}.yoast-table td:last-child,.yoast-table th:last-child{padding-right:16px}td.yoast-table__button,td.yoast-table__image{padding:10px 18px 9px}.yoast-table.yoast-table--nobreak td,td.yoast-table--nobreak,tr.yoast-table--nobreak td{white-space:nowrap}th.yoast-table--primary{width:100%}td.yoast-table--nopadding{padding:0 12px}.yoast-badge{border-radius:8px;display:inline-block;font-size:10px;font-weight:600;line-height:1.6;min-height:16px;padding:0 8px}.yoast-badge__in-label{margin-left:8px;vertical-align:text-top}.yoast-new-badge{background-color:#cce5ff;color:#004973}.yoast-premium-badge{background-color:#fff3cd;color:#674e00}.yoast-beta-badge{background-color:#cce5ff;color:#004973;margin:0 2px 0 0}.yoast-feature{margin-right:150px;max-width:600px}.yoast-toggle__item{border-bottom:1px solid var(--yoast-color-border);display:flex;justify-content:space-between;margin-bottom:16px;padding-bottom:16px}.yoast-toggle__item-disabled{position:relative}.yoast-toggle__item-disabled .yoast-button.yoast-button--buy{left:100%;margin-left:32px;position:absolute;white-space:nowrap}.yoast-toggle__item-disabled .yoast-toggle,.yoast-toggle__item-disabled .yoast-toggle__item-title{opacity:.5}.yoast-toggle__item-title{align-items:center;display:flex;font-weight:700}input[type=checkbox].yoast-toggle__checkbox{-webkit-appearance:none;-moz-appearance:none;background-color:initial;border:0;box-shadow:none;height:23px;margin-left:8px;overflow:hidden;position:absolute;width:34px;z-index:1}input[type=checkbox].yoast-toggle__checkbox:checked:before{content:none}.yoast-toggle__switch{background-color:var(--yoast-color-inactive-grey);border-radius:8px;display:inline-block;height:14px;margin-left:8px;margin-right:8px;position:relative;width:34px}.yoast-toggle__checkbox:focus~.yoast-toggle__switch:before{box-shadow:var(--yoast-color-focus)}.yoast-toggle__switch:before{background-color:var(--yoast-color-inactive-grey-light);border:.5px solid #0000001a;border-radius:50%;box-shadow:0 1px 2px 0 #0006;box-sizing:border-box;content:"";height:20px;left:0;position:absolute;top:-3px;width:20px}.yoast-toggle,.yoast-toggle--inverse{align-items:center;display:grid;grid-template:1fr/repeat(3,auto);position:relative}.yoast-toggle--inverse>*,.yoast-toggle>*{grid-row:1}.yoast-toggle--inactive,.yoast-toggle--inverse .yoast-toggle--active{grid-column:1}.yoast-toggle__checkbox,.yoast-toggle__switch{grid-column:2}.yoast-toggle--active,.yoast-toggle--inverse .yoast-toggle--inactive{grid-column:3}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle__switch,.yoast-toggle--inverse .yoast-toggle__checkbox:not(:checked)~.yoast-toggle__switch{background-color:var(--yoast-color-active-light)}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle__switch:before,.yoast-toggle--inverse .yoast-toggle__checkbox:not(:checked)~.yoast-toggle__switch:before{background-color:var(--yoast-color-active);left:auto;right:0}.yoast-toggle--inverse .yoast-toggle__checkbox:checked~.yoast-toggle__switch:before{left:0;right:auto}.yoast-toggle .yoast-toggle__checkbox~.yoast-toggle--inactive,.yoast-toggle--inverse .yoast-toggle__checkbox~.yoast-toggle--inactive{color:var(--yoast-color-default-darker)}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle--inactive,.yoast-toggle .yoast-toggle__checkbox~.yoast-toggle--active,.yoast-toggle--inverse .yoast-toggle__checkbox:checked~.yoast-toggle--inactive,.yoast-toggle--inverse .yoast-toggle__checkbox~.yoast-toggle--active{color:var(--yoast-color-inactive-text)}.yoast-toggle .yoast-toggle__checkbox:checked~.yoast-toggle--active,.yoast-toggle--inverse .yoast-toggle__checkbox:checked~.yoast-toggle--active{color:var(--yoast-color-default-darker)}@media(max-width:400px){.yoast-feature{margin-right:0}.yoast-toggle__item-disabled{flex-wrap:wrap}.yoast-toggle__item-disabled .yoast-button.yoast-button--buy{margin-left:0;margin-top:8px;position:static}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/new-settings-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/new-settings-2711-rtl.css new file mode 100644 index 0000000..aa567da --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/new-settings-2711-rtl.css @@ -0,0 +1 @@ +body.seo_page_wpseo_page_settings{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}body.seo_page_wpseo_page_settings #wpcontent{padding-right:0!important}body.seo_page_wpseo_page_settings #wpfooter{padding-left:1rem}@media (min-width:768px){body.seo_page_wpseo_page_settings #wpfooter{padding-right:17rem;padding-left:2rem}}@media screen and (max-width:782px){body.seo_page_wpseo_page_settings .wp-responsive-open #wpbody{left:-190px}}body.seo_page_wpseo_page_settings #modal-search .yst-modal__close{margin-top:-.25rem}@media (min-width:783px) and (max-width:962px){body.seo_page_wpseo_page_settings.sticky-menu .yst-root .yst-notifications--bottom-left{right:calc(160px + 2rem)}}@media (min-width:783px) and (max-width:963px){body.seo_page_wpseo_page_settings.sticky-menu.auto-fold .yst-root .yst-notifications--bottom-left,body.seo_page_wpseo_page_settings.sticky-menu.folded .yst-root .yst-notifications--bottom-left{right:calc(32px + 2rem)}}@media (min-width:962px){body.seo_page_wpseo_page_settings.sticky-menu.folded .yst-root .yst-notifications--bottom-left{right:calc(32px + 2rem)}}@media (max-width:783px){body.seo_page_wpseo_page_settings:not(.sticky-menu) .wp-responsive-open .yst-root .yst-notifications--bottom-left{right:calc(190px + 2rem)}}body.seo_page_wpseo_page_settings .yst-root .yst-notifications{max-height:calc(100% - 4rem - 32px)}@media (max-width:782px){body.seo_page_wpseo_page_settings .yst-root .yst-notifications{max-height:calc(100% - 4rem - 48px)}}body.seo_page_wpseo_page_settings .yst-root .yst-notifications--bottom-left{z-index:9991}@media (min-width:783px){body.seo_page_wpseo_page_settings .yst-root .yst-notifications--bottom-left{right:calc(160px + 2rem)}}@media (min-width:601px) and (max-width:768px){body.seo_page_wpseo_page_settings .yst-root .yst-mobile-navigation__top{top:46px}}@media (min-width:783px){body.seo_page_wpseo_page_settings .yst-root .yst-mobile-navigation__top{display:none}}body.seo_page_wpseo_page_settings .yst-root .yst-mobile-navigation__dialog{z-index:99999}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar{position:relative}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar .emoji-select-popover{right:0;left:auto;z-index:20}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .emoji-select-button,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__editor,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__label{opacity:.5}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .emoji-select-button,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__button-insert,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__editor,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__label{cursor:not-allowed}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .emoji-select-button{pointer-events:none}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__label{display:flex;font-size:.8125rem;font-weight:500;margin-bottom:.5rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__buttons{display:inline-flex;gap:.375rem;margin-bottom:.5rem}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__buttons .emoji-select-button{height:28px!important;min-height:28px!important;padding:6px!important;width:28px!important}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__buttons .emoji-select-button svg{height:16px!important;width:16px!important}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor{border-radius:.375rem;border-width:1px;width:100%;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));font-size:.8125rem;line-height:1.5rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor:focus-within{border-color:rgb(166 30 105/var(--tw-border-opacity,1));--tw-border-opacity:0;outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden]{border-radius:.375rem;width:14rem;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding-bottom:.25rem;padding-top:.25rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden]:focus{outline:2px solid #0000;outline-offset:2px}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden] div>div{cursor:pointer;display:block;font-size:.8125rem;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));-webkit-text-decoration-line:none;text-decoration-line:none}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden] div>div:hover,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden] div>div[aria-selected]{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--description .yst-replacevar__editor{min-height:5rem}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__mention{border-radius:9999px;display:inline-block;margin-right:.125rem;margin-left:.125rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:500;line-height:1.25;padding:.125rem .5rem;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-popover-backdrop-highlight-button button{z-index:99}body.seo_page_wpseo_page_settings.rtl .yst-root .yst-replacevar .emoji-select-popover{right:0;left:auto} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/new-settings-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/new-settings-2711.css new file mode 100644 index 0000000..f4a4a9b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/new-settings-2711.css @@ -0,0 +1 @@ +body.seo_page_wpseo_page_settings{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}body.seo_page_wpseo_page_settings #wpcontent{padding-left:0!important}body.seo_page_wpseo_page_settings #wpfooter{padding-right:1rem}@media (min-width:768px){body.seo_page_wpseo_page_settings #wpfooter{padding-left:17rem;padding-right:2rem}}@media screen and (max-width:782px){body.seo_page_wpseo_page_settings .wp-responsive-open #wpbody{right:-190px}}body.seo_page_wpseo_page_settings #modal-search .yst-modal__close{margin-top:-.25rem}@media (min-width:783px) and (max-width:962px){body.seo_page_wpseo_page_settings.sticky-menu .yst-root .yst-notifications--bottom-left{left:calc(160px + 2rem)}}@media (min-width:783px) and (max-width:963px){body.seo_page_wpseo_page_settings.sticky-menu.auto-fold .yst-root .yst-notifications--bottom-left,body.seo_page_wpseo_page_settings.sticky-menu.folded .yst-root .yst-notifications--bottom-left{left:calc(32px + 2rem)}}@media (min-width:962px){body.seo_page_wpseo_page_settings.sticky-menu.folded .yst-root .yst-notifications--bottom-left{left:calc(32px + 2rem)}}@media (max-width:783px){body.seo_page_wpseo_page_settings:not(.sticky-menu) .wp-responsive-open .yst-root .yst-notifications--bottom-left{left:calc(190px + 2rem)}}body.seo_page_wpseo_page_settings .yst-root .yst-notifications{max-height:calc(100% - 4rem - 32px)}@media (max-width:782px){body.seo_page_wpseo_page_settings .yst-root .yst-notifications{max-height:calc(100% - 4rem - 48px)}}body.seo_page_wpseo_page_settings .yst-root .yst-notifications--bottom-left{z-index:9991}@media (min-width:783px){body.seo_page_wpseo_page_settings .yst-root .yst-notifications--bottom-left{left:calc(160px + 2rem)}}@media (min-width:601px) and (max-width:768px){body.seo_page_wpseo_page_settings .yst-root .yst-mobile-navigation__top{top:46px}}@media (min-width:783px){body.seo_page_wpseo_page_settings .yst-root .yst-mobile-navigation__top{display:none}}body.seo_page_wpseo_page_settings .yst-root .yst-mobile-navigation__dialog{z-index:99999}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar{position:relative}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar .emoji-select-popover{left:0;right:auto;z-index:20}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .emoji-select-button,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__editor,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__label{opacity:.5}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .emoji-select-button,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__button-insert,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__editor,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .yst-replacevar__label{cursor:not-allowed}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--disabled .emoji-select-button{pointer-events:none}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__label{display:flex;font-size:.8125rem;font-weight:500;margin-bottom:.5rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__buttons{display:inline-flex;gap:.375rem;margin-bottom:.5rem}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__buttons .emoji-select-button{height:28px!important;min-height:28px!important;padding:6px!important;width:28px!important}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__buttons .emoji-select-button svg{height:16px!important;width:16px!important}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor{border-radius:.375rem;border-width:1px;width:100%;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));font-size:.8125rem;line-height:1.5rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor:focus-within{border-color:rgb(166 30 105/var(--tw-border-opacity,1));--tw-border-opacity:0;outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden]{border-radius:.375rem;width:14rem;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding-bottom:.25rem;padding-top:.25rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden]:focus{outline:2px solid #0000;outline-offset:2px}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden] div>div{cursor:pointer;display:block;font-size:.8125rem;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));-webkit-text-decoration-line:none;text-decoration-line:none}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden] div>div:hover,body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__editor [data-popper-reference-hidden] div>div[aria-selected]{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar--description .yst-replacevar__editor{min-height:5rem}body.seo_page_wpseo_page_settings .yst-root .yst-replacevar__mention{border-radius:9999px;display:inline-block;margin-left:.125rem;margin-right:.125rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));font-size:.75rem;font-weight:500;line-height:1.25;padding:.125rem .5rem;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}body.seo_page_wpseo_page_settings .yst-popover-backdrop-highlight-button button{z-index:99}body.seo_page_wpseo_page_settings.rtl .yst-root .yst-replacevar .emoji-select-popover{left:0;right:auto} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/notifications-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/notifications-2711-rtl.css new file mode 100644 index 0000000..b1352a4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/notifications-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.screen-reader-text{position:absolute!important;clip:rect(1px,1px,1px,1px);border:0;clip-path:inset(50%);height:1px;overflow:hidden;padding:0;width:1px;word-wrap:normal!important}.yoast-notification{background:#fff;border-right:4px solid #fff;box-shadow:0 1px 2px #0003;padding:0 12px}.yoast-container{background-color:#fdfdfd;border:1px solid #e5e5e5;box-shadow:0 1px 1px #0000000a;margin:20px 0 1px;max-width:1280px;padding:20px 20px 0;position:relative}.yoast-notifications>h2:first-child{font-size:23px;font-weight:400;line-height:29px;margin:0;padding:9px 0 4px}.yoast-notifications .yoast-container h3{background-color:#fdfdfd;border-bottom:1px solid #ccc;font-size:1.4em;margin:-20px -20px 0;padding:1em}.yoast-container .container{max-width:980px}.yoast-container .yoast-notification-holder{display:flex;position:relative}.dismiss .dashicons,.restore .dashicons{font-size:20px;height:20px;width:20px}.yoast-bottom-spacing{margin-bottom:20px}.yoast-notifications .button.dismiss,.yoast-notifications .button.restore{background:#0000;border:none;border-radius:0;box-shadow:none;cursor:pointer;height:100%;line-height:inherit;outline:none;padding:0;position:absolute;left:0;width:52px}.yoast-notifications .button.dismiss:focus,.yoast-notifications .button.dismiss:hover,.yoast-notifications .button.restore:focus,.yoast-notifications .button.restore:hover{background:#0000}.yoast-notifications .button.dismiss:focus:before,.yoast-notifications .button.restore:focus:before{border-radius:50%;box-shadow:0 0 0 1px #007cba;content:"";display:block;height:32px;right:50%;outline:2px solid #0000;position:absolute;top:50%;transform:translate(50%,-50%);width:32px}.yoast-container .separator{border-top:1px solid #ddd;margin-bottom:1em;margin-top:1em}.yoast-container .dashicons-yes{color:#77b227}.yoast-container-disabled{background-color:#e8e8e8b3;border-radius:4px;bottom:0;display:table-cell;right:0;position:absolute;left:0;top:0}.yoast-no-issues{color:#666;padding:1em 16px 1em 1em}.yoast-muted-title{font-style:italic;font-weight:600;overflow:hidden}.yoast-muted-title:after{border-top:1px solid #ddd;content:"";display:inline-block;height:.5em;margin-right:10px;margin-left:-100%;vertical-align:bottom;width:100%}.yoast-notifications-active .yoast-notification,.yoast-notifications-dismissed .yoast-notification{flex:1;padding-left:52px}.yoast-notifications-active .yoast-notification-holder{margin-bottom:20px}.yoast-notifications-dismissed.paper.tab-block{margin:20px 0}.yoast-notifications-dismissed.paper.tab-block .paper-container.toggleable-container{padding:0}.yoast-notifications-dismissed.paper.tab-block .paper-container.toggleable-container .yoast-notification-holder:nth-child(odd){background-color:#f7f7f7}.yoast-notifications-dismissed.paper.tab-block .paper-container.toggleable-container .yoast-notification-holder:nth-child(odd) .yoast-notification{background-color:initial}.yoast-notifications-dismissed .yoast-svg-icon-eye{background:#0000 var(--yoast-svg-icon-eye) no-repeat 100% 0;background-size:20px}#yoast-errors-header .dashicons{color:#dc3232}#yoast-errors-active .yoast-notification{border-right-color:#dc3232}#yoast-errors-dismissed .yoast-notification{border-right-color:#d93f69}#yoast-warnings-header .dashicons{color:#5d237a}#yoast-warnings-active .yoast-notification{border-right-color:#5d237a}#yoast-warnings-dismissed .yoast-notification{border-right-color:#0075b3} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/notifications-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/notifications-2711.css new file mode 100644 index 0000000..5218e0a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/notifications-2711.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.screen-reader-text{position:absolute!important;clip:rect(1px,1px,1px,1px);border:0;clip-path:inset(50%);height:1px;overflow:hidden;padding:0;width:1px;word-wrap:normal!important}.yoast-notification{background:#fff;border-left:4px solid #fff;box-shadow:0 1px 2px #0003;padding:0 12px}.yoast-container{background-color:#fdfdfd;border:1px solid #e5e5e5;box-shadow:0 1px 1px #0000000a;margin:20px 0 1px;max-width:1280px;padding:20px 20px 0;position:relative}.yoast-notifications>h2:first-child{font-size:23px;font-weight:400;line-height:29px;margin:0;padding:9px 0 4px}.yoast-notifications .yoast-container h3{background-color:#fdfdfd;border-bottom:1px solid #ccc;font-size:1.4em;margin:-20px -20px 0;padding:1em}.yoast-container .container{max-width:980px}.yoast-container .yoast-notification-holder{display:flex;position:relative}.dismiss .dashicons,.restore .dashicons{font-size:20px;height:20px;width:20px}.yoast-bottom-spacing{margin-bottom:20px}.yoast-notifications .button.dismiss,.yoast-notifications .button.restore{background:#0000;border:none;border-radius:0;box-shadow:none;cursor:pointer;height:100%;line-height:inherit;outline:none;padding:0;position:absolute;right:0;width:52px}.yoast-notifications .button.dismiss:focus,.yoast-notifications .button.dismiss:hover,.yoast-notifications .button.restore:focus,.yoast-notifications .button.restore:hover{background:#0000}.yoast-notifications .button.dismiss:focus:before,.yoast-notifications .button.restore:focus:before{border-radius:50%;box-shadow:0 0 0 1px #007cba;content:"";display:block;height:32px;left:50%;outline:2px solid #0000;position:absolute;top:50%;transform:translate(-50%,-50%);width:32px}.yoast-container .separator{border-top:1px solid #ddd;margin-bottom:1em;margin-top:1em}.yoast-container .dashicons-yes{color:#77b227}.yoast-container-disabled{background-color:#e8e8e8b3;border-radius:4px;bottom:0;display:table-cell;left:0;position:absolute;right:0;top:0}.yoast-no-issues{color:#666;padding:1em 1em 1em 16px}.yoast-muted-title{font-style:italic;font-weight:600;overflow:hidden}.yoast-muted-title:after{border-top:1px solid #ddd;content:"";display:inline-block;height:.5em;margin-left:10px;margin-right:-100%;vertical-align:bottom;width:100%}.yoast-notifications-active .yoast-notification,.yoast-notifications-dismissed .yoast-notification{flex:1;padding-right:52px}.yoast-notifications-active .yoast-notification-holder{margin-bottom:20px}.yoast-notifications-dismissed.paper.tab-block{margin:20px 0}.yoast-notifications-dismissed.paper.tab-block .paper-container.toggleable-container{padding:0}.yoast-notifications-dismissed.paper.tab-block .paper-container.toggleable-container .yoast-notification-holder:nth-child(odd){background-color:#f7f7f7}.yoast-notifications-dismissed.paper.tab-block .paper-container.toggleable-container .yoast-notification-holder:nth-child(odd) .yoast-notification{background-color:initial}.yoast-notifications-dismissed .yoast-svg-icon-eye{background:#0000 var(--yoast-svg-icon-eye) no-repeat 0 0;background-size:20px}#yoast-errors-header .dashicons{color:#dc3232}#yoast-errors-active .yoast-notification{border-left-color:#dc3232}#yoast-errors-dismissed .yoast-notification{border-left-color:#d93f69}#yoast-warnings-header .dashicons{color:#5d237a}#yoast-warnings-active .yoast-notification{border-left-color:#5d237a}#yoast-warnings-dismissed .yoast-notification{border-left-color:#0075b3} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/plans-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/plans-2711-rtl.css new file mode 100644 index 0000000..f177c8d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/plans-2711-rtl.css @@ -0,0 +1 @@ +.seo_page_wpseo_licenses,.yoast-seo_page_wpseo_licenses{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}.seo_page_wpseo_licenses #wpcontent,.yoast-seo_page_wpseo_licenses #wpcontent{padding-right:0!important} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/plans-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/plans-2711.css new file mode 100644 index 0000000..101d9d7 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/plans-2711.css @@ -0,0 +1 @@ +.seo_page_wpseo_licenses,.yoast-seo_page_wpseo_licenses{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}.seo_page_wpseo_licenses #wpcontent,.yoast-seo_page_wpseo_licenses #wpcontent{padding-left:0!important} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/redirects-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/redirects-2711-rtl.css new file mode 100644 index 0000000..172924b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/redirects-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,');--yoast-color-default:#404040;--yoast-color-default-darker:#303030;--yoast-color-primary:#a4286a;--yoast-color-secondary:#f7f7f7;--yoast-color-white:#fff;--yoast-color-green:#6ea029;--yoast-color-primary-darker:#7b1e50;--yoast-color-primary-lighter:#f5d6e6;--yoast-color-secondary-darker:#d9d9d9;--yoast-color-button-upsell:#fec228;--yoast-color-button-upsell-hover:#f2ae01;--yoast-color-dark:#303030;--yoast-color-sale:#fec228;--yoast-color-sale-darker:#feb601;--yoast-color-border:#0003;--yoast-color-label:#303030;--yoast-color-label-help:#707070;--yoast-color-active:#6ea029;--yoast-color-inactive:#dc3232;--yoast-color-inactive-text:#707070;--yoast-color-inactive-grey:#9e9e9e;--yoast-color-inactive-grey-light:#f1f1f1;--yoast-color-active-light:#b6cf94;--yoast-transition-default:all 150ms ease-out;--yoast-color-link:#006dac;--yoast-color-border--default:#0003;--yoast-color-focus:0 0 0 2px #007fff,0 0 0 5px #bfdfff}body.seo_page_wpseo_redirects{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}body.seo_page_wpseo_redirects #wpcontent{padding-right:0!important}body.seo_page_wpseo_redirects #wpfooter{padding-left:1rem}@media (min-width:768px){body.seo_page_wpseo_redirects #wpfooter{padding-right:17rem;padding-left:2rem}}@media screen and (max-width:782px){body.seo_page_wpseo_redirects .wp-responsive-open #wpbody{left:-190px}}body.seo_page_wpseo_redirects #modal-search .yst-modal__close{margin-top:-.25rem}@media (min-width:783px) and (max-width:962px){body.seo_page_wpseo_redirects.sticky-menu .yst-root .yst-notifications--bottom-left{right:calc(160px + 2rem)}}@media (min-width:783px) and (max-width:963px){body.seo_page_wpseo_redirects.sticky-menu.auto-fold .yst-root .yst-notifications--bottom-left,body.seo_page_wpseo_redirects.sticky-menu.folded .yst-root .yst-notifications--bottom-left{right:calc(32px + 2rem)}}@media (min-width:962px){body.seo_page_wpseo_redirects.sticky-menu.folded .yst-root .yst-notifications--bottom-left{right:calc(32px + 2rem)}}@media (max-width:783px){body.seo_page_wpseo_redirects:not(.sticky-menu) .wp-responsive-open .yst-root .yst-notifications--bottom-left{right:calc(190px + 2rem)}}@media (min-width:783px){body.seo_page_wpseo_redirects .yst-root .yst-notifications--bottom-left{right:calc(160px + 2rem)}}@media (min-width:601px) and (max-width:768px){body.seo_page_wpseo_redirects .yst-root .yst-mobile-navigation__top{top:46px}}@media (min-width:783px){body.seo_page_wpseo_redirects .yst-root .yst-mobile-navigation__top{display:none}}body.seo_page_wpseo_redirects .yst-root .yst-mobile-navigation__dialog{z-index:99999}body.seo_page_wpseo_redirects .yst-root .yst-paper{margin-bottom:unset;min-height:unset;vertical-align:unset;white-space:normal}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-header{font-weight:500;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-cell{padding-bottom:1.25rem;padding-top:1.25rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-cell .yst-checkbox__label{margin-inline-start:2.25rem}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-checkbox__label{margin-inline-start:1.5rem}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-cell:first-child,body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-header:first-child{padding-inline-start:.75rem}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-dropdown-menu__item--button{justify-content:flex-start;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-dropdown-menu__item--button:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-dropdown-menu__list{z-index:1100!important}body.seo_page_wpseo_redirects .yst-modal__panel{max-width:32rem}body.seo_page_wpseo_redirects .yst-logo-icon{background-color:var(--yoast-color-primary);height:17px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px}body.seo_page_wpseo_redirects .yst-modal-uppercase{letter-spacing:.8px;text-transform:uppercase;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects.rtl .yst-root .yst-replacevar .emoji-select-popover{right:0;left:auto}body.seo_page_wpseo_redirects #screen-meta-links{display:none} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/redirects-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/redirects-2711.css new file mode 100644 index 0000000..5739251 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/redirects-2711.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,');--yoast-color-default:#404040;--yoast-color-default-darker:#303030;--yoast-color-primary:#a4286a;--yoast-color-secondary:#f7f7f7;--yoast-color-white:#fff;--yoast-color-green:#6ea029;--yoast-color-primary-darker:#7b1e50;--yoast-color-primary-lighter:#f5d6e6;--yoast-color-secondary-darker:#d9d9d9;--yoast-color-button-upsell:#fec228;--yoast-color-button-upsell-hover:#f2ae01;--yoast-color-dark:#303030;--yoast-color-sale:#fec228;--yoast-color-sale-darker:#feb601;--yoast-color-border:#0003;--yoast-color-label:#303030;--yoast-color-label-help:#707070;--yoast-color-active:#6ea029;--yoast-color-inactive:#dc3232;--yoast-color-inactive-text:#707070;--yoast-color-inactive-grey:#9e9e9e;--yoast-color-inactive-grey-light:#f1f1f1;--yoast-color-active-light:#b6cf94;--yoast-transition-default:all 150ms ease-out;--yoast-color-link:#006dac;--yoast-color-border--default:#0003;--yoast-color-focus:0 0 0 2px #007fff,0 0 0 5px #bfdfff}body.seo_page_wpseo_redirects{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}body.seo_page_wpseo_redirects #wpcontent{padding-left:0!important}body.seo_page_wpseo_redirects #wpfooter{padding-right:1rem}@media (min-width:768px){body.seo_page_wpseo_redirects #wpfooter{padding-left:17rem;padding-right:2rem}}@media screen and (max-width:782px){body.seo_page_wpseo_redirects .wp-responsive-open #wpbody{right:-190px}}body.seo_page_wpseo_redirects #modal-search .yst-modal__close{margin-top:-.25rem}@media (min-width:783px) and (max-width:962px){body.seo_page_wpseo_redirects.sticky-menu .yst-root .yst-notifications--bottom-left{left:calc(160px + 2rem)}}@media (min-width:783px) and (max-width:963px){body.seo_page_wpseo_redirects.sticky-menu.auto-fold .yst-root .yst-notifications--bottom-left,body.seo_page_wpseo_redirects.sticky-menu.folded .yst-root .yst-notifications--bottom-left{left:calc(32px + 2rem)}}@media (min-width:962px){body.seo_page_wpseo_redirects.sticky-menu.folded .yst-root .yst-notifications--bottom-left{left:calc(32px + 2rem)}}@media (max-width:783px){body.seo_page_wpseo_redirects:not(.sticky-menu) .wp-responsive-open .yst-root .yst-notifications--bottom-left{left:calc(190px + 2rem)}}@media (min-width:783px){body.seo_page_wpseo_redirects .yst-root .yst-notifications--bottom-left{left:calc(160px + 2rem)}}@media (min-width:601px) and (max-width:768px){body.seo_page_wpseo_redirects .yst-root .yst-mobile-navigation__top{top:46px}}@media (min-width:783px){body.seo_page_wpseo_redirects .yst-root .yst-mobile-navigation__top{display:none}}body.seo_page_wpseo_redirects .yst-root .yst-mobile-navigation__dialog{z-index:99999}body.seo_page_wpseo_redirects .yst-root .yst-paper{margin-bottom:unset;min-height:unset;vertical-align:unset;white-space:normal}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-header{font-weight:500;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-cell{padding-bottom:1.25rem;padding-top:1.25rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-cell .yst-checkbox__label{margin-inline-start:2.25rem}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-checkbox__label{margin-inline-start:1.5rem}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-cell:first-child,body.seo_page_wpseo_redirects .yst-table--minimal table .yst-table-header:first-child{padding-inline-start:.75rem}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-dropdown-menu__item--button{justify-content:flex-start;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-dropdown-menu__item--button:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects .yst-table--minimal table .yst-dropdown-menu__list{z-index:1100!important}body.seo_page_wpseo_redirects .yst-modal__panel{max-width:32rem}body.seo_page_wpseo_redirects .yst-logo-icon{background-color:var(--yoast-color-primary);height:17px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:17px}body.seo_page_wpseo_redirects .yst-modal-uppercase{letter-spacing:.8px;text-transform:uppercase;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}body.seo_page_wpseo_redirects.rtl .yst-root .yst-replacevar .emoji-select-popover{left:0;right:auto}body.seo_page_wpseo_redirects #screen-meta-links{display:none} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/score_icon-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/score_icon-2711-rtl.css new file mode 100644 index 0000000..23fa8c6 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/score_icon-2711-rtl.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 3px 0 10px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/score_icon-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/score_icon-2711.css new file mode 100644 index 0000000..b6193ee --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/score_icon-2711.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 10px 0 3px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/structured-data-blocks-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/structured-data-blocks-2711-rtl.css new file mode 100644 index 0000000..a5c8cd0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/structured-data-blocks-2711-rtl.css @@ -0,0 +1 @@ +.schema-faq-section,.schema-how-to-step{border:1px solid #9197a240;list-style-type:none;margin:4px 0;padding:8px 32px 8px 4px;position:relative}.schema-faq-buttons,.schema-how-to-buttons{display:flex;justify-content:center}.schema-faq-buttons button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover,.schema-how-to-buttons button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{box-shadow:none;color:#007cba}.schema-faq-section-mover,.schema-how-to-step-mover{display:inline-block}.schema-faq-section-mover .editor-block-mover__control,.schema-how-to-step-mover .editor-block-mover__control{display:inline-flex;height:36px;width:36px}.schema-faq-question,.schema-how-to-step-name{font-weight:600}.schema-faq .schema-faq-answer,.schema-faq .schema-faq-question,.schema-how-to .schema-how-to-description,.schema-how-to .schema-how-to-step-name,.schema-how-to .schema-how-to-step-text,.schema-how-to .schema-how-to-steps{line-height:inherit;margin:0}.schema-how-to .schema-how-to-steps{padding-top:0}.schema-faq-section-button-container,.schema-how-to-step-button-container{display:inline-flex;text-align:left}.schema-faq-section-button-container button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover,.schema-how-to-step-button-container button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{box-shadow:none;color:#007cba}.schema-faq-section-controls-container,.schema-how-to-step-controls-container{margin-right:-28px;text-align:left}.schema-faq-section-controls-container .dashicons-arrow-up-alt2,.schema-how-to-step-controls-container .dashicons-arrow-up-alt2{position:relative;top:-1px}.faq-section-add-media .dashicon,.how-to-step-add-media .dashicon,.schema-faq-add-question .dashicon,.schema-how-to-add-step .dashicon,.schema-how-to-duration-button .dashicon{margin-left:4px}.schema-how-to{padding-top:4px}.schema-how-to-step-number{right:4px;position:absolute;text-align:left;width:24px}.schema-how-to-duration{border:0;margin:0;padding:0}.schema-how-to-duration-flex-container{align-items:center;display:flex}.schema-how-to-duration-time-input{align-items:center;display:inline-flex;flex-wrap:nowrap}legend.schema-how-to-duration-legend{margin-left:4px}#schema-how-to-duration-days{margin-left:8px}.schema-how-to-duration .schema-how-to-duration-input[type=number]{-moz-appearance:textfield;margin:0 2px;padding:6px 4px;text-align:center;width:40px}.schema-how-to-duration .schema-how-to-duration-input[type=number]::-webkit-inner-spin-button,.schema-how-to-duration .schema-how-to-duration-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.schema-how-to-duration-button.components-icon-button{margin-right:-8px;vertical-align:top}.schema-how-to-duration-button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{box-shadow:none;color:#007cba}.schema-how-to-description{margin:8px 0}body.is-dark-theme .schema-faq-section-mover button.components-button,body.is-dark-theme .schema-how-to-step-mover button.components-button,body.is-dark-theme button.components-button.schema-faq-add-question,body.is-dark-theme button.components-button.schema-faq-section-button,body.is-dark-theme button.components-button.schema-how-to-add-step,body.is-dark-theme button.components-button.schema-how-to-duration-button,body.is-dark-theme button.components-button.schema-how-to-step-button{color:#e8eaed} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/structured-data-blocks-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/structured-data-blocks-2711.css new file mode 100644 index 0000000..23f0f86 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/structured-data-blocks-2711.css @@ -0,0 +1 @@ +.schema-faq-section,.schema-how-to-step{border:1px solid #9197a240;list-style-type:none;margin:4px 0;padding:8px 4px 8px 32px;position:relative}.schema-faq-buttons,.schema-how-to-buttons{display:flex;justify-content:center}.schema-faq-buttons button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover,.schema-how-to-buttons button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{box-shadow:none;color:#007cba}.schema-faq-section-mover,.schema-how-to-step-mover{display:inline-block}.schema-faq-section-mover .editor-block-mover__control,.schema-how-to-step-mover .editor-block-mover__control{display:inline-flex;height:36px;width:36px}.schema-faq-question,.schema-how-to-step-name{font-weight:600}.schema-faq .schema-faq-answer,.schema-faq .schema-faq-question,.schema-how-to .schema-how-to-description,.schema-how-to .schema-how-to-step-name,.schema-how-to .schema-how-to-step-text,.schema-how-to .schema-how-to-steps{line-height:inherit;margin:0}.schema-how-to .schema-how-to-steps{padding-top:0}.schema-faq-section-button-container,.schema-how-to-step-button-container{display:inline-flex;text-align:right}.schema-faq-section-button-container button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover,.schema-how-to-step-button-container button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{box-shadow:none;color:#007cba}.schema-faq-section-controls-container,.schema-how-to-step-controls-container{margin-left:-28px;text-align:right}.schema-faq-section-controls-container .dashicons-arrow-up-alt2,.schema-how-to-step-controls-container .dashicons-arrow-up-alt2{position:relative;top:-1px}.faq-section-add-media .dashicon,.how-to-step-add-media .dashicon,.schema-faq-add-question .dashicon,.schema-how-to-add-step .dashicon,.schema-how-to-duration-button .dashicon{margin-right:4px}.schema-how-to{padding-top:4px}.schema-how-to-step-number{left:4px;position:absolute;text-align:right;width:24px}.schema-how-to-duration{border:0;margin:0;padding:0}.schema-how-to-duration-flex-container{align-items:center;display:flex}.schema-how-to-duration-time-input{align-items:center;display:inline-flex;flex-wrap:nowrap}legend.schema-how-to-duration-legend{margin-right:4px}#schema-how-to-duration-days{margin-right:8px}.schema-how-to-duration .schema-how-to-duration-input[type=number]{-moz-appearance:textfield;margin:0 2px;padding:6px 4px;text-align:center;width:40px}.schema-how-to-duration .schema-how-to-duration-input[type=number]::-webkit-inner-spin-button,.schema-how-to-duration .schema-how-to-duration-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.schema-how-to-duration-button.components-icon-button{margin-left:-8px;vertical-align:top}.schema-how-to-duration-button.components-icon-button:not(:disabled):not([aria-disabled=true]):not(.is-default):hover{box-shadow:none;color:#007cba}.schema-how-to-description{margin:8px 0}body.is-dark-theme .schema-faq-section-mover button.components-button,body.is-dark-theme .schema-how-to-step-mover button.components-button,body.is-dark-theme button.components-button.schema-faq-add-question,body.is-dark-theme button.components-button.schema-faq-section-button,body.is-dark-theme button.components-button.schema-how-to-add-step,body.is-dark-theme button.components-button.schema-how-to-duration-button,body.is-dark-theme button.components-button.schema-how-to-step-button{color:#e8eaed} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/support-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/support-2711-rtl.css new file mode 100644 index 0000000..837a542 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/support-2711-rtl.css @@ -0,0 +1 @@ +.seo_page_wpseo_page_support{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}.seo_page_wpseo_page_support #wpcontent{padding-right:0!important}.seo_page_wpseo_page_support #wpfooter{padding-left:1rem}@media (min-width:768px){.seo_page_wpseo_page_support #wpfooter{padding-right:17rem;padding-left:2rem}}@media screen and (max-width:782px){.seo_page_wpseo_page_support .wp-responsive-open #wpbody{left:-190px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/support-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/support-2711.css new file mode 100644 index 0000000..1325708 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/support-2711.css @@ -0,0 +1 @@ +.seo_page_wpseo_page_support{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));z-index:-1}.seo_page_wpseo_page_support #wpcontent{padding-left:0!important}.seo_page_wpseo_page_support #wpfooter{padding-right:1rem}@media (min-width:768px){.seo_page_wpseo_page_support #wpfooter{padding-left:17rem;padding-right:2rem}}@media screen and (max-width:782px){.seo_page_wpseo_page_support .wp-responsive-open #wpbody{right:-190px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/tailwind-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/tailwind-2711.css new file mode 100644 index 0000000..74be1b8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/tailwind-2711.css @@ -0,0 +1 @@ +*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }:root{--yst-ai-color-purple-300:#a5b4fc;--yst-ai-color-pink-300:#cd82ab}.yst-root *,.yst-root :after,.yst-root :before{border:0 solid #e5e7eb;box-sizing:border-box}.yst-root :after,.yst-root :before{--tw-content:""}.yst-root,.yst-root :host{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;tab-size:4;-webkit-tap-highlight-color:transparent}.yst-root{margin:0}.yst-root hr{border-top-width:1px;color:inherit;height:0}.yst-root abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.yst-root h1,.yst-root h2,.yst-root h3,.yst-root h4,.yst-root h5,.yst-root h6{font-size:inherit;font-weight:inherit}.yst-root a{color:inherit;text-decoration:inherit}.yst-root b,.yst-root strong{font-weight:bolder}.yst-root code,.yst-root kbd,.yst-root pre,.yst-root samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}.yst-root small{font-size:80%}.yst-root sub,.yst-root sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}.yst-root sub{bottom:-.25em}.yst-root sup{top:-.5em}.yst-root table{border-collapse:collapse;border-color:inherit;text-indent:0}.yst-root button,.yst-root input,.yst-root optgroup,.yst-root select,.yst-root textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}.yst-root button,.yst-root select{text-transform:none}.yst-root button,.yst-root input:where([type=button]),.yst-root input:where([type=reset]),.yst-root input:where([type=submit]){-webkit-appearance:button;background-color:initial;background-image:none}.yst-root :-moz-focusring{outline:auto}.yst-root :-moz-ui-invalid{box-shadow:none}.yst-root progress{vertical-align:initial}.yst-root ::-webkit-inner-spin-button,.yst-root ::-webkit-outer-spin-button{height:auto}.yst-root [type=search]{-webkit-appearance:textfield;outline-offset:-2px}.yst-root ::-webkit-search-decoration{-webkit-appearance:none}.yst-root ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.yst-root summary{display:list-item}.yst-root blockquote,.yst-root dd,.yst-root dl,.yst-root figure,.yst-root h1,.yst-root h2,.yst-root h3,.yst-root h4,.yst-root h5,.yst-root h6,.yst-root hr,.yst-root p,.yst-root pre{margin:0}.yst-root fieldset{margin:0;padding:0}.yst-root legend{padding:0}.yst-root menu,.yst-root ol,.yst-root ul{list-style:none;margin:0;padding:0}.yst-root dialog{padding:0}.yst-root textarea{resize:vertical}.yst-root input::placeholder,.yst-root textarea::placeholder{color:#9ca3af;opacity:1}.yst-root [role=button],.yst-root button{cursor:pointer}.yst-root :disabled{cursor:default}.yst-root audio,.yst-root canvas,.yst-root embed,.yst-root iframe,.yst-root img,.yst-root object,.yst-root svg,.yst-root video{display:block;vertical-align:middle}.yst-root img,.yst-root video{height:auto;max-width:100%}.yst-root [hidden]:where(:not([hidden=until-found])){display:none}.yst-root [type=date],.yst-root [type=datetime-local],.yst-root [type=email],.yst-root [type=month],.yst-root [type=number],.yst-root [type=password],.yst-root [type=search],.yst-root [type=tel],.yst-root [type=text],.yst-root [type=time],.yst-root [type=url],.yst-root [type=week]{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root [type=date]:focus,.yst-root [type=datetime-local]:focus,.yst-root [type=email]:focus,.yst-root [type=month]:focus,.yst-root [type=number]:focus,.yst-root [type=password]:focus,.yst-root [type=search]:focus,.yst-root [type=tel]:focus,.yst-root [type=text]:focus,.yst-root [type=time]:focus,.yst-root [type=url]:focus,.yst-root [type=week]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=date]::placeholder,.yst-root [type=datetime-local]::placeholder,.yst-root [type=email]::placeholder,.yst-root [type=month]::placeholder,.yst-root [type=number]::placeholder,.yst-root [type=password]::placeholder,.yst-root [type=search]::placeholder,.yst-root [type=tel]::placeholder,.yst-root [type=text]::placeholder,.yst-root [type=time]::placeholder,.yst-root [type=url]::placeholder,.yst-root [type=week]::placeholder{color:#6b7280;opacity:1}.yst-root [type=date]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=datetime-local]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=email]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=month]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=number]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=password]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=search]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=tel]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=text]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=time]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=url]::-webkit-datetime-edit-fields-wrapper,.yst-root [type=week]::-webkit-datetime-edit-fields-wrapper{padding:0}.yst-root [type=date]::-webkit-date-and-time-value,.yst-root [type=datetime-local]::-webkit-date-and-time-value,.yst-root [type=email]::-webkit-date-and-time-value,.yst-root [type=month]::-webkit-date-and-time-value,.yst-root [type=number]::-webkit-date-and-time-value,.yst-root [type=password]::-webkit-date-and-time-value,.yst-root [type=search]::-webkit-date-and-time-value,.yst-root [type=tel]::-webkit-date-and-time-value,.yst-root [type=text]::-webkit-date-and-time-value,.yst-root [type=time]::-webkit-date-and-time-value,.yst-root [type=url]::-webkit-date-and-time-value,.yst-root [type=week]::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}.yst-root [type=date]::-webkit-datetime-edit,.yst-root [type=datetime-local]::-webkit-datetime-edit,.yst-root [type=email]::-webkit-datetime-edit,.yst-root [type=month]::-webkit-datetime-edit,.yst-root [type=number]::-webkit-datetime-edit,.yst-root [type=password]::-webkit-datetime-edit,.yst-root [type=search]::-webkit-datetime-edit,.yst-root [type=tel]::-webkit-datetime-edit,.yst-root [type=text]::-webkit-datetime-edit,.yst-root [type=time]::-webkit-datetime-edit,.yst-root [type=url]::-webkit-datetime-edit,.yst-root [type=week]::-webkit-datetime-edit{display:inline-flex}.yst-root [type=date]::-webkit-datetime-edit,.yst-root [type=date]::-webkit-datetime-edit-day-field,.yst-root [type=date]::-webkit-datetime-edit-hour-field,.yst-root [type=date]::-webkit-datetime-edit-meridiem-field,.yst-root [type=date]::-webkit-datetime-edit-millisecond-field,.yst-root [type=date]::-webkit-datetime-edit-minute-field,.yst-root [type=date]::-webkit-datetime-edit-month-field,.yst-root [type=date]::-webkit-datetime-edit-second-field,.yst-root [type=date]::-webkit-datetime-edit-year-field,.yst-root [type=datetime-local]::-webkit-datetime-edit,.yst-root [type=datetime-local]::-webkit-datetime-edit-day-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-hour-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-meridiem-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-millisecond-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-minute-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-month-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-second-field,.yst-root [type=datetime-local]::-webkit-datetime-edit-year-field,.yst-root [type=email]::-webkit-datetime-edit,.yst-root [type=email]::-webkit-datetime-edit-day-field,.yst-root [type=email]::-webkit-datetime-edit-hour-field,.yst-root [type=email]::-webkit-datetime-edit-meridiem-field,.yst-root [type=email]::-webkit-datetime-edit-millisecond-field,.yst-root [type=email]::-webkit-datetime-edit-minute-field,.yst-root [type=email]::-webkit-datetime-edit-month-field,.yst-root [type=email]::-webkit-datetime-edit-second-field,.yst-root [type=email]::-webkit-datetime-edit-year-field,.yst-root [type=month]::-webkit-datetime-edit,.yst-root [type=month]::-webkit-datetime-edit-day-field,.yst-root [type=month]::-webkit-datetime-edit-hour-field,.yst-root [type=month]::-webkit-datetime-edit-meridiem-field,.yst-root [type=month]::-webkit-datetime-edit-millisecond-field,.yst-root [type=month]::-webkit-datetime-edit-minute-field,.yst-root [type=month]::-webkit-datetime-edit-month-field,.yst-root [type=month]::-webkit-datetime-edit-second-field,.yst-root [type=month]::-webkit-datetime-edit-year-field,.yst-root [type=number]::-webkit-datetime-edit,.yst-root [type=number]::-webkit-datetime-edit-day-field,.yst-root [type=number]::-webkit-datetime-edit-hour-field,.yst-root [type=number]::-webkit-datetime-edit-meridiem-field,.yst-root [type=number]::-webkit-datetime-edit-millisecond-field,.yst-root [type=number]::-webkit-datetime-edit-minute-field,.yst-root [type=number]::-webkit-datetime-edit-month-field,.yst-root [type=number]::-webkit-datetime-edit-second-field,.yst-root [type=number]::-webkit-datetime-edit-year-field,.yst-root [type=password]::-webkit-datetime-edit,.yst-root [type=password]::-webkit-datetime-edit-day-field,.yst-root [type=password]::-webkit-datetime-edit-hour-field,.yst-root [type=password]::-webkit-datetime-edit-meridiem-field,.yst-root [type=password]::-webkit-datetime-edit-millisecond-field,.yst-root [type=password]::-webkit-datetime-edit-minute-field,.yst-root [type=password]::-webkit-datetime-edit-month-field,.yst-root [type=password]::-webkit-datetime-edit-second-field,.yst-root [type=password]::-webkit-datetime-edit-year-field,.yst-root [type=search]::-webkit-datetime-edit,.yst-root [type=search]::-webkit-datetime-edit-day-field,.yst-root [type=search]::-webkit-datetime-edit-hour-field,.yst-root [type=search]::-webkit-datetime-edit-meridiem-field,.yst-root [type=search]::-webkit-datetime-edit-millisecond-field,.yst-root [type=search]::-webkit-datetime-edit-minute-field,.yst-root [type=search]::-webkit-datetime-edit-month-field,.yst-root [type=search]::-webkit-datetime-edit-second-field,.yst-root [type=search]::-webkit-datetime-edit-year-field,.yst-root [type=tel]::-webkit-datetime-edit,.yst-root [type=tel]::-webkit-datetime-edit-day-field,.yst-root [type=tel]::-webkit-datetime-edit-hour-field,.yst-root [type=tel]::-webkit-datetime-edit-meridiem-field,.yst-root [type=tel]::-webkit-datetime-edit-millisecond-field,.yst-root [type=tel]::-webkit-datetime-edit-minute-field,.yst-root [type=tel]::-webkit-datetime-edit-month-field,.yst-root [type=tel]::-webkit-datetime-edit-second-field,.yst-root [type=tel]::-webkit-datetime-edit-year-field,.yst-root [type=text]::-webkit-datetime-edit,.yst-root [type=text]::-webkit-datetime-edit-day-field,.yst-root [type=text]::-webkit-datetime-edit-hour-field,.yst-root [type=text]::-webkit-datetime-edit-meridiem-field,.yst-root [type=text]::-webkit-datetime-edit-millisecond-field,.yst-root [type=text]::-webkit-datetime-edit-minute-field,.yst-root [type=text]::-webkit-datetime-edit-month-field,.yst-root [type=text]::-webkit-datetime-edit-second-field,.yst-root [type=text]::-webkit-datetime-edit-year-field,.yst-root [type=time]::-webkit-datetime-edit,.yst-root [type=time]::-webkit-datetime-edit-day-field,.yst-root [type=time]::-webkit-datetime-edit-hour-field,.yst-root [type=time]::-webkit-datetime-edit-meridiem-field,.yst-root [type=time]::-webkit-datetime-edit-millisecond-field,.yst-root [type=time]::-webkit-datetime-edit-minute-field,.yst-root [type=time]::-webkit-datetime-edit-month-field,.yst-root [type=time]::-webkit-datetime-edit-second-field,.yst-root [type=time]::-webkit-datetime-edit-year-field,.yst-root [type=url]::-webkit-datetime-edit,.yst-root [type=url]::-webkit-datetime-edit-day-field,.yst-root [type=url]::-webkit-datetime-edit-hour-field,.yst-root [type=url]::-webkit-datetime-edit-meridiem-field,.yst-root [type=url]::-webkit-datetime-edit-millisecond-field,.yst-root [type=url]::-webkit-datetime-edit-minute-field,.yst-root [type=url]::-webkit-datetime-edit-month-field,.yst-root [type=url]::-webkit-datetime-edit-second-field,.yst-root [type=url]::-webkit-datetime-edit-year-field,.yst-root [type=week]::-webkit-datetime-edit,.yst-root [type=week]::-webkit-datetime-edit-day-field,.yst-root [type=week]::-webkit-datetime-edit-hour-field,.yst-root [type=week]::-webkit-datetime-edit-meridiem-field,.yst-root [type=week]::-webkit-datetime-edit-millisecond-field,.yst-root [type=week]::-webkit-datetime-edit-minute-field,.yst-root [type=week]::-webkit-datetime-edit-month-field,.yst-root [type=week]::-webkit-datetime-edit-second-field,.yst-root [type=week]::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}.yst-root textarea{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root textarea:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root textarea::placeholder{color:#6b7280;opacity:1}.yst-root select{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root select:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}.yst-root select:where([size]:not([size="1"])){background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}.yst-root select[multiple]{appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}.yst-root select[multiple]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=checkbox]{appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000;border-radius:0}.yst-root [type=checkbox]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=checkbox]:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}@media (forced-colors:active) {.yst-root [type=checkbox]:checked{appearance:auto}}.yst-root [type=checkbox]:checked:focus,.yst-root [type=checkbox]:checked:hover,.yst-root [type=checkbox]:indeterminate{background-color:currentColor;border-color:#0000}.yst-root [type=checkbox]:indeterminate{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%}@media (forced-colors:active) {.yst-root [type=checkbox]:indeterminate{appearance:auto}}.yst-root [type=checkbox]:indeterminate:focus,.yst-root [type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:#0000}.yst-root [type=radio]{appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000;border-radius:100%}.yst-root [type=radio]:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.yst-root [type=radio]:checked{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:#0000}@media (forced-colors:active) {.yst-root [type=radio]:checked{appearance:auto}}.yst-root [type=radio]:checked:focus,.yst-root [type=radio]:checked:hover{background-color:currentColor;border-color:#0000}.yst-root{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:.8125rem;font-weight:400;line-height:1.5;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.yst-root a{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1));-webkit-text-decoration-line:underline;text-decoration-line:underline}.yst-root a:visited{color:#a61e69}.yst-root a:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1))}.yst-root a:hover:visited{color:#b94986}.yst-root a:focus{border-radius:.125rem;--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1));outline-color:#4f46e5;outline-offset:1px;outline-style:solid}.yst-root [type=date]::placeholder,.yst-root [type=datetime-local]::placeholder,.yst-root [type=email]::placeholder,.yst-root [type=month]::placeholder,.yst-root [type=number]::placeholder,.yst-root [type=password]::placeholder,.yst-root [type=search]::placeholder,.yst-root [type=tel]::placeholder,.yst-root [type=text]::placeholder,.yst-root [type=time]::placeholder,.yst-root [type=url]::placeholder,.yst-root [type=week]::placeholder,.yst-root textarea::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity,1))}.yst-root svg path{stroke-width:inherit}.yst-root .yst-radio__input,.yst-root a:focus{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-radio__input{transition-property:none}.yst-root .yst-radio__input:checked:before{content:var(--tw-content);display:none}.yst-root .yst-modal{z-index:101000!important}.yst-root dd,.yst-root li{margin-bottom:0}.yst-root input[type=date],.yst-root input[type=datetime-local],.yst-root input[type=datetime],.yst-root input[type=email],.yst-root input[type=month],.yst-root input[type=number],.yst-root input[type=password],.yst-root input[type=search],.yst-root input[type=tel],.yst-root input[type=text],.yst-root input[type=time],.yst-root input[type=url],.yst-root input[type=week]{min-height:0}.yst-root input[type=checkbox]{min-height:0;min-width:0;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-property:none}.yst-root input[type=checkbox]:before{--tw-content:none;content:var(--tw-content)}.yst-root .yst-alert{border-radius:.375rem;display:flex;gap:.75rem;padding:1rem}.yst-root .yst-alert--info{--tw-bg-opacity:1;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))}.yst-root .yst-alert--info .yst-alert__message{--tw-text-opacity:1;color:rgb(30 64 175/var(--tw-text-opacity,1))}.yst-root .yst-alert--warning{--tw-bg-opacity:1;background-color:rgb(254 243 199/var(--tw-bg-opacity,1))}.yst-root .yst-alert--warning .yst-alert__message{--tw-text-opacity:1;color:rgb(146 64 14/var(--tw-text-opacity,1))}.yst-root .yst-alert--success{--tw-bg-opacity:1;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))}.yst-root .yst-alert--success .yst-alert__message{--tw-text-opacity:1;color:rgb(22 101 52/var(--tw-text-opacity,1))}.yst-root .yst-alert--error{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))}.yst-root .yst-alert--error .yst-alert__message{--tw-text-opacity:1;color:rgb(153 27 27/var(--tw-text-opacity,1))}.yst-root .yst-alert__icon{flex-grow:0;flex-shrink:0;height:1.25rem;width:1.25rem}.yst-root .yst-autocomplete{position:relative}.yst-root .yst-autocomplete--error .yst-autocomplete__button{--tw-border-opacity:1;border-color:rgb(252 165 165/var(--tw-border-opacity,1))}.yst-root .yst-autocomplete--error .yst-autocomplete__button:focus{--tw-border-opacity:1;border-color:rgb(239 68 68/var(--tw-border-opacity,1));outline:2px solid #0000;outline-offset:2px;--tw-ring-opacity:1;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity,1))}.yst-root .yst-autocomplete--error .yst-autocomplete__input::placeholder{--tw-placeholder-opacity:1;color:rgb(252 165 165/var(--tw-placeholder-opacity,1))}.yst-root .yst-autocomplete--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-autocomplete--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-autocomplete--disabled .yst-autocomplete__input{cursor:not-allowed}.yst-root .yst-autocomplete--disabled .yst-autocomplete__input:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-autocomplete--disabled .yst-autocomplete__button{cursor:not-allowed}.yst-root .yst-autocomplete--disabled .yst-autocomplete__button:focus-within{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1));outline:2px solid #0000;outline-offset:2px;--tw-ring-opacity:1;--tw-ring-color:rgb(226 232 240/var(--tw-ring-opacity,1))}.yst-root .yst-autocomplete__button{align-items:center;border-radius:.375rem;border-width:0;display:flex;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding-left:.75rem;padding-right:.75rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-autocomplete__button:focus-within{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity,1));outline:2px solid #0000;outline-offset:2px;--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-autocomplete__action-container{align-items:center;column-gap:.5rem;display:flex;padding-inline-start:.75rem}.yst-root .yst-button.yst-autocomplete__clear-action{padding-left:0;padding-right:0}.yst-root .yst-autocomplete__action-icon{flex-shrink:0;height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-autocomplete__action-separator{height:1.75rem;margin-inline-start:.125rem;width:.125rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.yst-root .yst-autocomplete__input{border-width:0;font-size:.8125rem;padding:.5rem 0;width:100%;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-autocomplete__input:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-autocomplete__options{border-radius:.375rem;margin-top:.25rem;max-height:15rem;overflow:auto;position:absolute;width:100%;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));font-size:.8125rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.yst-root .yst-autocomplete__options:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-autocomplete__option{align-items:center;cursor:default;display:flex;justify-content:space-between;padding:.5rem .75rem;position:relative;-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.yst-root .yst-autocomplete__option--active{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.yst-root .yst-autocomplete__option--selected{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-select__option-label{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yst-root .yst-autocomplete__option-check{flex-shrink:0;height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-badge{align-items:center;border-radius:9999px;display:inline-flex;font-size:.75rem;font-weight:500;line-height:1.25;padding:.125rem .5rem;vertical-align:middle;white-space:nowrap}.yst-root .yst-badge--info{background-color:rgb(191 219 254/var(--tw-bg-opacity,1));border-color:rgb(96 165 250/var(--tw-border-opacity,1));color:rgb(30 58 138/var(--tw-text-opacity,1))}.yst-root .yst-badge--info,.yst-root .yst-badge--upsell{--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1}.yst-root .yst-badge--upsell{background-color:rgb(253 230 138/var(--tw-bg-opacity,1));border-color:rgb(251 191 36/var(--tw-border-opacity,1));color:rgb(120 53 15/var(--tw-text-opacity,1))}.yst-root .yst-badge--plain{background-color:rgb(226 232 240/var(--tw-bg-opacity,1));border-color:rgb(148 163 184/var(--tw-border-opacity,1));color:rgb(15 23 42/var(--tw-text-opacity,1))}.yst-root .yst-badge--plain,.yst-root .yst-badge--success{--tw-border-opacity:1;--tw-bg-opacity:1;--tw-text-opacity:1}.yst-root .yst-badge--success{background-color:rgb(187 247 208/var(--tw-bg-opacity,1));border-color:rgb(74 222 128/var(--tw-border-opacity,1));color:rgb(20 83 45/var(--tw-text-opacity,1))}.yst-root .yst-badge--error{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(254 202 202/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(127 29 29/var(--tw-text-opacity,1))}.yst-root .yst-badge--ai{background-image:linear-gradient(97.38deg,#a61e69,#6366f1);font-weight:600;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-badge--small{font-size:.675rem}.yst-root .yst-badge--large{font-size:1rem;padding-left:.75rem;padding-right:.75rem}.yst-root .yst-button{align-items:center;border-radius:.375rem;cursor:pointer;display:inline-flex;font-size:.8125rem;font-weight:500;justify-content:center;line-height:1.25rem;padding:.5rem .75rem;text-align:center;-webkit-text-decoration-line:none;text-decoration-line:none;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-color:#0000}.yst-root .yst-button:focus{outline-color:#a61e69;outline-offset:2px;outline-style:solid;outline-width:2px}.yst-root a.yst-button:focus{border-radius:.375rem}.yst-root .yst-button--primary{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));--tw-ring-color:#0000}.yst-root .yst-button--primary:visited{color:#fff}.yst-root .yst-button--primary:hover{--tw-bg-opacity:1;background-color:rgb(143 15 87/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-button--primary:hover:visited{color:#fff}.yst-root .yst-button--primary:focus{outline-color:#8f0f57}.yst-root .yst-button--ai-primary,.yst-root .yst-button--primary:focus{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-button--ai-primary{background-image:linear-gradient(97.38deg,#a61e69,#6366f1);border-image:none;gap:.375rem;padding-inline-start:.5rem}.yst-root .yst-button--ai-primary:focus{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-button--ai-primary:hover{background-image:linear-gradient(97.38deg,#8f0f57,#4338ca)}.yst-root .yst-button--ai-primary>svg>path{stroke:#fff}.yst-root .yst-button--ai-secondary{background-color:initial;gap:.375rem;padding-inline-start:.5rem;position:relative;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-button--ai-secondary:hover{background-image:linear-gradient(97.38deg,#faf3f7,#eef2ff)}.yst-root .yst-button--ai-secondary:focus{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-button--ai-secondary{border-image:linear-gradient(to bottom right,var(--yst-ai-color-pink-300),var(--yst-ai-color-purple-300)) 1}.yst-root .yst-button--ai-secondary:before{background-image:linear-gradient(to bottom right,#cd82ab,#a5b4fc);border-radius:inherit;content:"";inset:0;mask:linear-gradient(#fff,#fff) content-box,linear-gradient(#fff,#fff) border-box;mask-composite:exclude;padding:1px;position:absolute}.yst-root .yst-button--ai-secondary:after{border-radius:.375rem;content:"";inset:1px;position:absolute;z-index:-1}.yst-root .yst-button--ai-secondary:after,.yst-root .yst-button--secondary{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.yst-root .yst-button--secondary{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-button--secondary:visited{color:#1e293b}.yst-root .yst-button--secondary:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-button--secondary:hover:visited{color:#1e293b}.yst-root .yst-button--secondary:focus{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));outline-color:#8f0f57}.yst-root .yst-button--tertiary{background-color:initial;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-button--tertiary:visited{color:#83084e}.yst-root .yst-button--tertiary:hover{--tw-text-opacity:1;color:rgb(131 8 78/var(--tw-text-opacity,1))}.yst-root .yst-button--tertiary:hover:visited{color:#83084e}.yst-root .yst-button--tertiary:focus{--tw-text-opacity:1;color:rgb(131 8 78/var(--tw-text-opacity,1));outline:2px solid #0000;outline-offset:2px}.yst-root .yst-button--tertiary:focus-visible{outline-color:#8f0f57;outline-style:solid}.yst-root .yst-button--error{border-color:#0000;--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-button--error:visited{color:#fff}.yst-root .yst-button--error:hover{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-button--error:hover:visited{color:#fff}.yst-root .yst-button--error:focus{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));outline-color:#dc2626}.yst-root .yst-button--upsell{border-color:#0000;--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}.yst-root .yst-button--upsell:visited{color:#78350f}.yst-root .yst-button--upsell:hover{--tw-bg-opacity:1;background-color:rgb(251 191 36/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}.yst-root .yst-button--upsell:hover:visited{color:#78350f}.yst-root .yst-button--upsell:focus{--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1));outline-color:#fbbf24}.yst-root .yst-button--large{font-size:.875rem;line-height:1.5rem;padding:.5rem .75rem}.yst-root .yst-button--extra-large{font-size:1rem;line-height:1.5rem;padding:.625rem .875rem}.yst-root .yst-button--small{font-size:.75rem;line-height:1rem;padding:.375rem .625rem}.yst-root .yst-button--small .yst-button--sparkles-icon{height:1rem}.yst-root .yst-button--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-button--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-button--loading{margin-inline-end:.5rem;margin-inline-start:-.25rem}.yst-root .yst-checkbox{align-items:center;display:flex}.yst-root .yst-checkbox--disabled .yst-checkbox__input,.yst-root .yst-checkbox--disabled .yst-checkbox__label{cursor:not-allowed;opacity:.5}.yst-root .yst-checkbox__input{border-radius:.25rem;height:1rem;width:1rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1))}.yst-root .yst-checkbox__input:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-checkbox__label{margin-inline-start:.75rem}.yst-root .yst-code{border-radius:.25rem;display:inline-block;margin:0;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));font-size:.75rem;line-height:1.25;padding:.25rem;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.yst-root .yst-code--block{display:block;margin-bottom:.5rem;margin-top:.5rem;max-width:100%;overflow-x:auto;padding:.25rem .5rem;white-space:nowrap}.yst-root .yst-file-input{border-radius:.375rem;border-style:dashed;border-width:2px;width:100%;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding:1.25rem 1.5rem 1.5rem;text-align:center;transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-file-input.yst-is-drag-over{--tw-border-opacity:1;border-color:rgb(205 130 171/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(250 243 247/var(--tw-bg-opacity,1))}.yst-root .yst-file-input.yst-is-drag-over .yst-file-input__content{pointer-events:none}.yst-root .yst-file-input.yst-is-drag-over .yst-file-input__icon{--tw-translate-y:-0.5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-text-opacity:1;color:rgb(185 73 134/var(--tw-text-opacity,1))}.yst-root .yst-file-input.yst-is-disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-file-input.yst-is-disabled .yst-file-input__select-label{cursor:not-allowed}.yst-root .yst-file-input__content{align-items:center;display:inline-flex;flex-direction:column;max-width:20rem}.yst-root .yst-file-input__content>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-file-input__content{text-align:center}.yst-root .yst-file-input__icon{height:3rem;margin-left:auto;margin-right:auto;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:3rem;stroke-width:1;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1));transition-duration:.3s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-file-input__icon>path{stroke-width:1}.yst-root .yst-file-input__input{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.yst-root .yst-file-input__input:focus+.yst-file-input__select-label{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-file-input__labels{display:inline-flex;font-weight:400;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-file-input__select-label{border-radius:.375rem;font-weight:500}.yst-root .yst-label{font-size:.8125rem;font-weight:500;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-link{cursor:pointer;--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity,1));-webkit-text-decoration-line:underline;text-decoration-line:underline}.yst-root .yst-link:visited{color:#a61e69}.yst-root .yst-link:hover{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1))}.yst-root .yst-link:hover:visited{color:#b94986}.yst-root .yst-link:focus{--tw-text-opacity:1;color:rgb(99 102 241/var(--tw-text-opacity,1));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color)}.yst-root .yst-link:focus,.yst-root .yst-link:focus-visible{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-link:focus-visible{border-radius:.125rem;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(79 70 229/var(--tw-ring-opacity,1));--tw-ring-offset-width:1px;--tw-ring-offset-color:#0000}.yst-root .yst-link--primary{--tw-text-opacity:1;color:rgb(154 22 96/var(--tw-text-opacity,1))}.yst-root .yst-link--primary:focus,.yst-root .yst-link--primary:hover{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1))}.yst-root .yst-link--primary:focus-visible{--tw-ring-opacity:1;--tw-ring-color:rgb(154 22 96/var(--tw-ring-opacity,1))}.yst-root .yst-link--error{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.yst-root .yst-link--error:focus,.yst-root .yst-link--error:hover{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.yst-root .yst-link--error:focus-visible{--tw-ring-opacity:1;--tw-ring-color:rgb(220 38 38/var(--tw-ring-opacity,1))}.yst-root .yst-paper{border-radius:.5rem;display:flex;flex-direction:column;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-paper__header{border-bottom-width:1px;padding:2rem}.yst-root .yst-paper__content{flex-grow:1;padding:2rem}.yst-root .yst-progress-bar{border-radius:9999px;display:block;overflow:hidden;width:100%;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.yst-root .yst-progress-bar__progress{border-radius:9999px;display:block;height:.375rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1));transition-duration:.2s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:linear}.yst-root .yst-radio{align-items:center;display:flex}.yst-root .yst-radio--disabled .yst-radio__check,.yst-root .yst-radio--disabled .yst-radio__input,.yst-root .yst-radio--disabled .yst-radio__label{cursor:not-allowed;opacity:.5}.yst-root .yst-radio--disabled .yst-radio__check:focus,.yst-root .yst-radio--disabled .yst-radio__input:focus,.yst-root .yst-radio--disabled .yst-radio__label:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-radio--inline-block{display:inline-flex}.yst-root .yst-radio--inline-block .yst-radio__input{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0,0,0,0);border-width:0;white-space:nowrap}.yst-root .yst-radio--inline-block .yst-radio__input:checked+.yst-radio__content .yst-radio__label{border-color:#0000;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-radio--inline-block .yst-radio__input:checked+.yst-radio__content .yst-radio__check{visibility:visible}.yst-root .yst-radio--inline-block .yst-radio__input:focus+.yst-radio__content .yst-radio__label{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-radio--inline-block .yst-radio__input:checked:focus+.yst-radio__content .yst-radio__label{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-offset-width:1px}.yst-root .yst-radio--inline-block .yst-radio__content{position:relative}.yst-root .yst-radio--inline-block .yst-radio__label{align-items:center;border-radius:.5rem;border-width:1px;cursor:pointer;display:flex;height:3.5rem;justify-content:center;margin-inline-start:0;width:3.5rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));font-size:1rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-radio--inline-block .yst-radio__label:hover{--tw-border-opacity:1;border-color:rgb(148 163 184/var(--tw-border-opacity,1))}.yst-root .yst-radio--inline-block .yst-radio__label:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-radio--inline-block .yst-radio__check{height:1.25rem;inset-inline-end:.125rem;position:absolute;top:.125rem;visibility:hidden;width:1.25rem;--tw-text-opacity:1;color:rgb(154 22 96/var(--tw-text-opacity,1))}.yst-root .yst-radio__input{height:1rem;width:1rem;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1))}.yst-root .yst-radio__input:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-radio__label{margin-inline-start:.75rem}.yst-root .yst-select{position:relative}.yst-root .yst-select--disabled .yst-select__button,.yst-root .yst-select--disabled .yst-select__label{cursor:not-allowed;opacity:.5}.yst-root .yst-select__button{align-items:center;border-radius:.375rem;cursor:default;display:flex;justify-content:space-between;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));line-height:1.5rem;padding:.5rem .75rem;text-align:start;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-select__button:focus{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity,1));outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-select__button-icon{height:1.25rem;inset-inline-end:.625rem;pointer-events:none;position:absolute;top:.625rem;width:1.25rem;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-select__options{border-radius:.375rem;margin-top:.25rem;max-height:15rem;overflow:auto;position:absolute;width:100%;z-index:10;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));font-size:.8125rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.yst-root .yst-select__options:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-select__option{align-items:center;cursor:default;display:flex;justify-content:space-between;padding:.5rem .75rem;position:relative;-webkit-user-select:none;user-select:none;--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity,1))}.yst-root .yst-select__option--active{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.yst-root .yst-select__option--selected{--tw-bg-opacity:1;background-color:rgb(154 22 96/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-select__button-label,.yst-root .yst-select__option-label{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.yst-root .yst-select__option-check{flex-shrink:0;height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-skeleton-loader{border-radius:.25rem;display:block;height:auto;overflow:hidden;position:relative;width:-moz-fit-content;width:fit-content;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))}.yst-root .yst-skeleton-loader:after{animation:wave 2.5s linear .5s infinite;background:linear-gradient(90deg,#0000,#00000012,#0000);content:"";inset:0;position:absolute;--tw-translate-x:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes wave{0%{transform:translateX(-100%)}50%,to{transform:translateX(100%)}}.yst-root .yst-table-wrapper table{min-width:100%}.yst-root .yst-table-wrapper table .yst-table-header{font-size:.8125rem;font-weight:600;padding:1rem .75rem;text-align:start;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.yst-root .yst-table-wrapper table .yst-table-cell{font-size:.8125rem;padding:1rem .75rem;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.yst-root .yst-table--default{border-radius:.5rem;--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.yst-root .yst-table--default table>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));--tw-divide-opacity:1;border-color:rgb(203 213 225/var(--tw-divide-opacity,1))}.yst-root .yst-table--default table thead .yst-table-header{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))}.yst-root .yst-table--default table thead .yst-table-header:first-child{border-start-start-radius:.5rem}.yst-root .yst-table--default table thead .yst-table-header:last-child{border-start-end-radius:.5rem}.yst-root .yst-table--default table tbody>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity,1))}.yst-root .yst-table--default table .yst-table-row:last-of-type .yst-table-cell{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.yst-root .yst-table--default table .yst-table-row:last-of-type .yst-table-cell:first-child{border-end-start-radius:.5rem}.yst-root .yst-table--default table .yst-table-row:last-of-type .yst-table-cell:last-child{border-end-end-radius:.5rem}.yst-root .yst-table--minimal table>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));--tw-divide-opacity:1;border-color:rgb(203 213 225/var(--tw-divide-opacity,1))}.yst-root .yst-table--minimal table .yst-table-header{padding-bottom:.5rem;padding-top:.5rem;vertical-align:bottom}.yst-root .yst-table--minimal table .yst-table-cell{padding-bottom:.5rem;padding-top:.5rem}.yst-root .yst-table--minimal table .yst-table-cell:first-child{padding-inline-start:0}.yst-root .yst-table--minimal table .yst-table-cell:last-child{padding-inline-end:0}.yst-root .yst-table--minimal table .yst-table-header:first-child{padding-inline-start:0}.yst-root .yst-table--minimal table .yst-table-header:last-child{padding-inline-end:0}.yst-root .yst-table--minimal table tbody>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0;border-bottom-width:calc(1px*var(--tw-divide-y-reverse));border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)));--tw-divide-opacity:1;border-color:rgb(229 231 235/var(--tw-divide-opacity,1))}.yst-root .yst-table--minimal table tbody,.yst-root .yst-tag-input{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))}.yst-root .yst-tag-input{align-items:center;border-radius:.375rem;display:flex;flex-wrap:wrap;font-size:.8125rem;gap:.375rem;line-height:1.5rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-tag-input::placeholder{--tw-placeholder-opacity:1;color:rgb(100 116 139/var(--tw-placeholder-opacity,1))}.yst-root .yst-tag-input{--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-tag-input,.yst-root .yst-tag-input:focus-within{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-tag-input--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-tag-input--disabled:focus-within{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__tag{cursor:not-allowed}.yst-root .yst-tag-input--disabled .yst-tag-input__tag:hover{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__tag:focus,.yst-root .yst-tag-input--disabled .yst-tag-input__tag:focus-visible{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag{cursor:not-allowed}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-tag-input--disabled .yst-tag-input__remove-tag:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-tag-input--disabled .yst-tag-input__input{cursor:not-allowed}.yst-root .yst-tag-input__tag{cursor:pointer;gap:.125rem;min-height:1.25rem;padding-inline-end:.125rem}.yst-root .yst-tag-input__tag:hover{--tw-border-opacity:1;border-color:rgb(166 30 105/var(--tw-border-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-tag-input__tag:focus,.yst-root .yst-tag-input__tag:focus-visible{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-tag-input__remove-tag{align-items:center;border-radius:9999px;display:inline-flex;flex-shrink:0;height:1rem;justify-content:center;width:1rem;--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-tag-input__remove-tag:hover{--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-tag-input__remove-tag:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-tag-input__input{border-style:none;display:inline-flex;flex:1 1 0%;font-size:.8125rem;margin:0;padding:0}.yst-root .yst-tag-input__input:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input{border-radius:.375rem;border-width:0;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));font-size:.8125rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-text-input,.yst-root .yst-text-input:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-text-input--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-text-input--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-text-input--read-only{cursor:default;--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1));--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000}.yst-root .yst-text-input--read-only,.yst-root .yst-textarea{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-textarea{border-radius:.375rem;border-width:0;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));font-size:.8125rem;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-textarea,.yst-root .yst-textarea:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-textarea:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-textarea--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-textarea--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-title{font-weight:500;line-height:1.25;--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.yst-root .yst-title--1{font-size:1.5rem}.yst-root .yst-title--2{font-size:1.125rem}.yst-root .yst-title--3{font-size:.875rem}.yst-root .yst-title--4{font-size:1rem}.yst-root .yst-title--5{font-size:.8125rem}.yst-root .yst-toast{border-radius:.5rem;max-width:100%;overflow-y:auto;pointer-events:auto;width:20rem;z-index:20;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding:1rem;--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1));--tw-ring-opacity:0.05}.yst-root .yst-toast--large{width:24rem}.yst-root .yst-toggle{border-color:#0000;border-radius:9999px;border-width:2px;cursor:pointer;display:inline-flex;flex-shrink:0;height:1.5rem;position:relative;width:2.75rem;--tw-bg-opacity:1;background-color:rgb(203 213 225/var(--tw-bg-opacity,1));transition-duration:.2s;transition-property:color,background-color,border-color,fill,stroke,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-toggle:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-toggle--checked{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1))}.yst-root .yst-toggle--checked .yst-toggle__handle{--tw-translate-x:1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-toggle--checked .yst-toggle__handle:where([dir=rtl],[dir=rtl] *){--tw-translate-x:-1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-toggle--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-toggle--disabled:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-toggle__handle{display:flex;height:1.25rem;pointer-events:none;position:relative;width:1.25rem;--tw-translate-x:0px;align-items:center;border-radius:9999px;justify-content:center;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);transition-duration:.2s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-toggle__icon{flex-grow:0;flex-shrink:0;height:.625rem;width:.625rem;stroke:currentColor;stroke-width:2;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));transition-duration:.1s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-toggle__icon--check{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1))}.yst-root .yst-toggle__icon--x{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-tooltip{border-radius:.5rem;max-width:24rem;position:absolute;white-space:normal;width:max-content;z-index:10;--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1));font-size:.75rem;padding:.5rem .625rem;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.yst-root .yst-tooltip:before{border-color:#0000;border-width:8px;position:absolute;--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip.yst-tooltip--light{border-width:1px;--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.yst-root .yst-tooltip.yst-tooltip--light:after{border-color:#0000;border-width:8px;position:absolute;--tw-content:"";content:var(--tw-content)}.yst-root .yst-tooltip--top{margin-top:-.75rem;top:0;--tw-translate-x:-50%;--tw-translate-y:-100%}.yst-root .yst-tooltip--top,.yst-root .yst-tooltip--top:before{inset-inline-start:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top:before{top:100%;--tw-translate-x:-50%;--tw-translate-y:0px;content:var(--tw-content);--tw-border-opacity:1;border-top-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top:where([dir=rtl],[dir=rtl] *){--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-top-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top.yst-tooltip--light:after{inset-inline-start:50%;top:99%;--tw-translate-x:-50%;--tw-translate-y:0px;content:var(--tw-content);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-top-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top.yst-tooltip--light:where([dir=rtl],[dir=rtl] *):after{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top-left{inset-inline-end:0;margin-top:-.75rem;top:0;--tw-translate-y:-100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top-left:before{inset-inline-end:.75rem;top:100%;--tw-translate-y:0px;content:var(--tw-content);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-top-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top-left.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-top-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top-left.yst-tooltip--light:after{inset-inline-end:.75rem;top:99%;--tw-translate-y:0px;content:var(--tw-content);--tw-border-opacity:1;border-top-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top-left.yst-tooltip--light:after,.yst-root .yst-tooltip--top-right{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--top-right{inset-inline-start:0;margin-top:-.75rem;top:0;--tw-translate-y:-100%}.yst-root .yst-tooltip--top-right:before{inset-inline-start:.75rem;top:100%;--tw-translate-y:0px;content:var(--tw-content);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-top-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top-right.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-top-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--top-right.yst-tooltip--light:after{inset-inline-start:.75rem;top:99%;--tw-translate-y:0px;content:var(--tw-content);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-top-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom{margin-top:.75rem;top:100%;--tw-translate-x:-50%;--tw-translate-y:-0px}.yst-root .yst-tooltip--bottom,.yst-root .yst-tooltip--bottom:before{inset-inline-start:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--bottom:before{bottom:100%;--tw-translate-x:-50%;border-width:8px;content:var(--tw-content);--tw-border-opacity:1;border-bottom-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom:where([dir=rtl],[dir=rtl] *){--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--bottom:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--bottom.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-bottom-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom.yst-tooltip--light:after{bottom:96%;inset-inline-start:50%;--tw-translate-x:-50%;content:var(--tw-content);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-bottom-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom.yst-tooltip--light:where([dir=rtl],[dir=rtl] *):after{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--bottom-left{inset-inline-end:0;margin-top:.75rem;top:100%}.yst-root .yst-tooltip--bottom-left:before{border-width:8px;bottom:100%;content:var(--tw-content);inset-inline-end:.75rem;--tw-border-opacity:1;border-bottom-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom-left.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-bottom-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom-left.yst-tooltip--light:after{bottom:96%;content:var(--tw-content);inset-inline-end:.75rem;--tw-border-opacity:1;border-bottom-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom-right{inset-inline-start:0;margin-top:.75rem;top:100%}.yst-root .yst-tooltip--bottom-right:before{border-width:8px;bottom:100%;content:var(--tw-content);inset-inline-start:.75rem;--tw-border-opacity:1;border-bottom-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom-right.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-bottom-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--bottom-right.yst-tooltip--light:after{bottom:96%;content:var(--tw-content);inset-inline-start:.75rem;--tw-border-opacity:1;border-bottom-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--right{inset-inline-start:100%;margin-inline-start:.75rem;--tw-translate-x:-0px}.yst-root .yst-tooltip--right,.yst-root .yst-tooltip--right:before{top:50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--right:before{content:var(--tw-content);inset-inline-end:100%;--tw-border-opacity:1;border-inline-end-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--right.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-inline-end-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--right.yst-tooltip--light:after{inset-inline-end:99%;--tw-translate-y:-50%;content:var(--tw-content);--tw-border-opacity:1;border-inline-end-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--left,.yst-root .yst-tooltip--right.yst-tooltip--light:after{top:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-tooltip--left{inset-inline-end:100%;margin-inline-end:.75rem;--tw-translate-y:-50%}.yst-root .yst-tooltip--left:before{inset-inline-start:100%;top:50%;--tw-translate-y:-50%;content:var(--tw-content);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-inline-start-color:rgb(31 41 55/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--left.yst-tooltip--light:before{content:var(--tw-content);--tw-border-opacity:1;border-inline-start-color:rgb(226 232 240/var(--tw-border-opacity,1))}.yst-root .yst-tooltip--left.yst-tooltip--light:after{inset-inline-start:99%;top:50%;--tw-translate-y:-50%;content:var(--tw-content);transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-border-opacity:1;border-inline-start-color:rgb(255 255 255/var(--tw-border-opacity,1))}.yst-root .yst-validation-icon{pointer-events:none}.yst-root .yst-validation-icon--success{--tw-text-opacity:1;color:rgb(34 197 94/var(--tw-text-opacity,1))}.yst-root .yst-validation-icon--info{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity,1))}.yst-root .yst-validation-icon--warning{--tw-text-opacity:1;color:rgb(245 158 11/var(--tw-text-opacity,1))}.yst-root .yst-validation-icon--error{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.yst-root .yst-validation-input{position:relative}.yst-root .yst-validation-input--success .yst-validation-input__input{padding-inline-end:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(134 239 172/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input--success .yst-validation-input__input:focus,.yst-root .yst-validation-input--success .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(34 197 94/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input--info .yst-validation-input__input{padding-inline-end:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(147 197 253/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input--info .yst-validation-input__input:focus,.yst-root .yst-validation-input--info .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input--warning .yst-validation-input__input{padding-inline-end:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(252 211 77/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input--warning .yst-validation-input__input:focus,.yst-root .yst-validation-input--warning .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(245 158 11/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input--error .yst-validation-input__input{padding-inline-end:2.5rem;--tw-ring-opacity:1;--tw-ring-color:rgb(252 165 165/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input--error .yst-validation-input__input:focus,.yst-root .yst-validation-input--error .yst-validation-input__input:focus-within{--tw-ring-opacity:1;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity,1))}.yst-root .yst-validation-input__input:focus,.yst-root .yst-validation-input__input:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-validation-input__icon{height:1.25rem;inset-inline-end:.625rem;position:absolute;top:.625rem;width:1.25rem}.yst-root .yst-validation-message a{color:inherit;font-weight:500}.yst-root .yst-validation-message a:visited:hover{color:inherit}.yst-root .yst-validation-message a:focus{--tw-ring-color:currentColor}.yst-root .yst-validation-message--success{--tw-text-opacity:1;color:rgb(22 163 74/var(--tw-text-opacity,1))}.yst-root .yst-validation-message--info{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.yst-root .yst-validation-message--warning{--tw-text-opacity:1;color:rgb(217 119 6/var(--tw-text-opacity,1))}.yst-root .yst-validation-message--error{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity,1))}.yst-root .yst-autocomplete-field--disabled .yst-autocomplete-field__description,.yst-root .yst-autocomplete-field--disabled .yst-autocomplete-field__label{opacity:.5}.yst-root .yst-autocomplete-field--disabled .yst-autocomplete-field__label{cursor:not-allowed}.yst-root .yst-autocomplete-field__description,.yst-root .yst-autocomplete-field__validation{margin-top:.5rem}.yst-root .yst-card{display:flex;flex-direction:column;position:relative}.yst-root .yst-card>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse));margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-card{border-radius:.5rem;border-width:1px;overflow:hidden;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding:1.5rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow);transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-card__header{align-items:center;display:flex;height:6rem;justify-content:center;margin-left:-1.5rem;margin-right:-1.5rem;margin-top:-1.5rem;position:relative;--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity,1));padding:1.5rem}.yst-root .yst-card__content{flex-grow:1}.yst-root .yst-card__footer{border-top-width:1px;--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity,1));padding-top:1.5rem}.yst-root .yst-checkbox-group--disabled .yst-checkbox-group__description,.yst-root .yst-checkbox-group--disabled .yst-checkbox-group__label{cursor:not-allowed;opacity:.5}.yst-root .yst-checkbox-group__label{margin-bottom:.5rem}.yst-root .yst-checkbox-group__options{display:flex;flex-direction:column;gap:.75rem}.yst-root .yst-checkbox-group__description{margin-bottom:1rem;margin-top:-.5rem}.yst-root .yst-dropdown-menu__icon-trigger{border-radius:9999px;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-dropdown-menu__icon-trigger:focus{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1));outline-color:#a61e69;outline-offset:2px;outline-style:solid;outline-width:2px}.yst-root .yst-dropdown-menu__item--button{align-items:center;border-radius:0;outline:2px solid #0000;outline-offset:2px;width:100%;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-dropdown-menu__item--button:focus,.yst-root .yst-dropdown-menu__item--button:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))}.yst-root .yst-dropdown-menu__item--button:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-dropdown-menu__list{border-radius:.375rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-dropdown-menu__list:focus-visible{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-feature-upsell{position:relative}.yst-root .yst-feature-upsell--default{--tw-grayscale:grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.yst-root .yst-feature-upsell--card{padding:1.5rem}.yst-root .yst-file-import>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(2rem*var(--tw-space-y-reverse));margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-file-import__feedback{border-radius:.375rem;border-width:1px;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1));--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding:1rem;--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-file-import__feedback-header{align-items:flex-start;display:flex}.yst-root .yst-file-import__feedback-header>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(1rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(1rem*var(--tw-space-x-reverse))}.yst-root .yst-file-import__feedback-header:where([dir=rtl],[dir=rtl] *)>:not([hidden])~:not([hidden]){--tw-space-x-reverse:1}.yst-root .yst-file-import__feedback-figure{align-items:center;border-radius:9999px;display:flex;height:2rem;justify-content:center;width:2rem;--tw-bg-opacity:1;background-color:rgb(243 229 237/var(--tw-bg-opacity,1))}.yst-root .yst-file-import__feedback-figure>svg{height:1.25rem;width:1.25rem;--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1))}.yst-root .yst-file-import__feedback-title{display:block;font-weight:500;margin-bottom:.125rem;overflow-wrap:break-word;--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-file-import__feedback-description{display:block;font-size:.75rem;font-weight:500}.yst-root .yst-file-import__abort-button{align-items:center;border-radius:9999px;display:inline-flex;flex-shrink:0;height:1.25rem;justify-content:center;width:1.25rem;--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-file-import__abort-button:hover{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.yst-root .yst-file-import__abort-button:focus{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));outline:2px solid #0000;outline-offset:2px}.yst-root .yst-file-import__abort-button>svg{height:.75rem;width:.75rem}.yst-root .yst-file-import__abort-button>svg>path{stroke-width:3}.yst-root .yst-image-select-preview{align-items:center;border-radius:.375rem;border-width:1px;display:flex;justify-content:center;overflow:hidden;--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity,1))}.yst-root .yst-image-select-preview:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-image-select-preview-icon{height:3rem;margin-left:auto;margin-right:auto;width:3rem;stroke-width:1;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-image-select-preview-image{min-height:100%;min-width:100%;object-fit:cover;object-position:center;transition-duration:.2s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-image-select-preview-image--loading{opacity:.7;--tw-blur:blur(4px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.yst-root .yst-modal{inset:0;padding:1rem;position:fixed;z-index:10}@media (min-width:640px){.yst-root .yst-modal{padding:2rem}}@media (min-width:768px){.yst-root .yst-modal{padding:5rem}}.yst-root .yst-modal__layout{display:flex;min-height:100%}.yst-root .yst-modal--center .yst-modal__layout{align-items:center;justify-content:center}.yst-root .yst-modal--top-center .yst-modal__layout{align-items:flex-start;justify-content:center}.yst-root .yst-modal__overlay{background-color:rgb(100 116 139/var(--tw-bg-opacity,1));inset:0;position:fixed;--tw-bg-opacity:0.75;transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.yst-root .yst-modal__panel{border-radius:.5rem;max-width:36rem;overflow:hidden;position:relative;width:100%;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding:1.5rem;--tw-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-modal__close{display:block;inset-inline-end:1rem;position:absolute;top:1rem}.yst-root .yst-modal__close-button{border-radius:.375rem;position:relative;z-index:10;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-modal__close-button:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-modal__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-modal__container{display:flex;flex-direction:column;max-height:calc(100vh - 2rem)}@media (min-width:640px){.yst-root .yst-modal__container{max-height:calc(100vh - 4rem)}}@media (min-width:768px){.yst-root .yst-modal__container{max-height:calc(100vh - 10rem)}}.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 5rem)}@media (min-width:640px){.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 7rem)}}@media (min-width:768px){.yst-root .yst-modal__panel .yst-modal__container{max-height:calc(100vh - 13rem)}}.yst-root .yst-modal__container-footer,.yst-root .yst-modal__container-header{flex-shrink:0}.yst-root .yst-modal__container-content{overflow:auto}.yst-root .yst-modal__panel .yst-modal__container-content{margin-left:-1.5rem;margin-right:-1.5rem;padding-left:1.5rem;padding-right:1.5rem}.yst-root .yst-notifications{display:flex;flex-direction:column;max-height:calc(100vh - 4rem);max-width:calc(100vw - 4rem);pointer-events:none;position:fixed;width:100%;z-index:20}.yst-root .yst-notifications>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1rem*var(--tw-space-y-reverse));margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-notifications--bottom-center{align-items:center;bottom:2rem}.yst-root .yst-notifications--bottom-left{bottom:2rem;inset-inline-start:2rem}.yst-root .yst-notifications--top-center{align-items:center;top:2rem}.yst-root .yst-notification--large{width:24rem}.yst-root .yst-notification__icon{height:1.25rem;width:1.25rem}.yst-root .yst-pagination{direction:ltr;display:inline-flex;isolation:isolate}.yst-root .yst-pagination>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(-1px*(1 - var(--tw-space-x-reverse)));margin-right:calc(-1px*var(--tw-space-x-reverse))}.yst-root .yst-pagination{border-radius:.375rem;--tw-shadow:0 1px 2px 0 #0000000d;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-pagination-display__text{font-weight:400;padding:.5rem .75rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(226 232 240/var(--tw-ring-opacity,1))}.yst-root .yst-pagination-display__current-text{font-weight:600;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1))}.yst-root .yst-pagination-display__truncated{align-self:center;font-size:.8125rem;font-weight:600;padding:.5rem 1rem;--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(226 232 240/var(--tw-ring-opacity,1))}.yst-root .yst-pagination-display__truncated,.yst-root .yst-pagination__button{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);display:inline-flex}.yst-root .yst-pagination__button{align-items:center;padding:.5rem;position:relative;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);--tw-ring-inset:inset;--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-pagination__button:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))}.yst-root .yst-pagination__button:focus{outline-color:#a61e69;outline-offset:0;z-index:20}.yst-root .yst-pagination__button--active{z-index:10;--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1));font-size:.8125rem;font-weight:600;--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.yst-root .yst-pagination__button--active:hover{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1))}.yst-root .yst-pagination__button--active:focus{z-index:20}.yst-root .yst-pagination__button--active:focus-visible{border-radius:.125rem;outline-color:#a61e69;outline-offset:2px;outline-style:solid;outline-width:2px}.yst-root .yst-pagination__button--disabled{cursor:not-allowed;opacity:.5}.yst-root .yst-pagination__button--disabled:hover{background-color:initial}.yst-root .yst-pagination__button--disabled:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-popover__backdrop{background-color:rgb(100 116 139/var(--tw-bg-opacity,1));inset:0;position:fixed;z-index:20;--tw-bg-opacity:0.75}.yst-root .yst-popover__close{display:block;inset-inline-end:1rem;position:absolute;top:1rem}.yst-root .yst-popover__close-button{border-radius:.375rem;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-popover__close-button:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-popover__close-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-popover__title{--tw-text-opacity:1;color:rgb(30 41 59/var(--tw-text-opacity,1))}.yst-root .yst-popover__title:where([dir=rtl],[dir=rtl] *){text-align:right}.yst-root .yst-popover__content{overflow:hidden}.yst-root .yst-popover__content:where([dir=rtl],[dir=rtl] *){text-align:right}.yst-root .yst-popover{border-radius:.5rem;border-width:1px;max-width:20rem;pointer-events:auto;position:absolute;white-space:normal;width:max-content;z-index:30;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));padding:1rem;--tw-shadow:0 25px 50px -12px #00000040;--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-popover:before{content:var(--tw-content);position:absolute}@media (min-width:640px){.yst-root .yst-popover{max-width:24rem}}.yst-root .yst-popover--no-arrow{inset-inline-start:50%;--tw-translate-x:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--no-arrow:where([dir=rtl],[dir=rtl] *){--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--right{inset-inline-start:100%;--tw-translate-x:1.25rem;--tw-translate-y:-50%;--tw-shadow:-25px 0 50px -12px #1e293b40;--tw-shadow-colored:-25px 0 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-popover--right,.yst-root .yst-popover--right:before{top:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--right:before{display:block;inset-inline-end:100%;--tw-translate-y:-50%;--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--right:where([dir=rtl],[dir=rtl] *){--tw-translate-x:-1.25rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--right:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);inset-inline-end:0;inset-inline-start:-100%;--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--right:before{border:14px solid #0000;border-right-color:#fff}[dir=rtl] .yst-root .yst-popover--right:before{border-left:14px solid #fff;border-right:14px solid #0000}.yst-root .yst-popover--top{inset-inline-end:50%;top:-1.25rem;--tw-translate-y:-100%;--tw-translate-x:50%}.yst-root .yst-popover--top,.yst-root .yst-popover--top:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--top:before{inset-inline-start:50%;top:100%;--tw-translate-x:-50%;--tw-translate-y:0px;--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--top:where([dir=rtl],[dir=rtl] *){--tw-translate-x:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--top:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--top:before{border-left:14px solid #0000;border-right:14px solid #0000;border-top:14px solid #fff}.yst-root .yst-popover--top-left{inset-inline-end:0;top:-1.25rem;--tw-translate-y:-100%;--tw-translate-x:0px}.yst-root .yst-popover--top-left,.yst-root .yst-popover--top-left:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--top-left:before{inset-inline-end:.5rem;top:100%;--tw-translate-x:-50%;--tw-translate-y:0px;border-color:#0000;--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--top-left:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--top-left:before{border-left:14px solid #0000;border-right:14px solid #0000;border-top:14px solid #fff}.yst-root .yst-popover--top-right{inset-inline-start:0;top:-1.25rem;--tw-translate-y:-100%}.yst-root .yst-popover--top-right,.yst-root .yst-popover--top-right:before{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--top-right:before{inset-inline-start:2rem;top:100%;--tw-translate-x:-50%;--tw-translate-y:0px;border-color:#0000;--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--top-right:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--top-right:before{border-left:14px solid #0000;border-right:14px solid #0000;border-top:14px solid #fff}.yst-root .yst-popover--left{inset-inline-end:100%;inset-inline-start:-1.25rem;--tw-translate-x:-100%;--tw-translate-y:-50%;--tw-shadow:25px 0 50px -12px #1e293b40;--tw-shadow-colored:25px 0 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-popover--left,.yst-root .yst-popover--left:before{top:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--left:before{inset-inline-start:100%;--tw-translate-y:-50%;--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--left:where([dir=rtl],[dir=rtl] *){inset-inline-end:-100%;--tw-translate-x:100%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--left:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);inset-inline-end:-100%;inset-inline-start:0;--tw-translate-x:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--left:before{border:14px solid #0000;border-left-color:#fff}[dir=rtl] .yst-root .yst-popover--left:before{border-left:14px solid #0000;border-right:14px solid #fff}.yst-root .yst-popover--bottom{top:3.5rem;--tw-translate-x:-50%;--tw-shadow:0 -25px 50px -12px #1e293b40;--tw-shadow-colored:0 -25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-popover--bottom,.yst-root .yst-popover--bottom:before{inset-inline-start:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--bottom:before{bottom:100%;--tw-translate-x:-50%;--tw-translate-y:0px;--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--bottom:where([dir=rtl],[dir=rtl] *){--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--bottom:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--bottom:before{border-bottom:14px solid #fff;border-left:14px solid #0000;border-right:14px solid #0000}.yst-root .yst-popover--bottom-left{inset-inline-end:0;top:3.5rem;--tw-shadow:0 -25px 50px -12px #1e293b40;--tw-shadow-colored:0 -25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-popover--bottom-left:before{bottom:100%;inset-inline-end:0;--tw-translate-x:-50%;--tw-translate-y:0px;border-color:#0000;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--bottom-left:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--bottom-left:before{border-bottom:14px solid #fff;border-left:14px solid #0000;border-right:14px solid #0000}.yst-root .yst-popover--bottom-right{inset-inline-start:0;top:3.5rem;--tw-shadow:0 -25px 50px -12px #1e293b40;--tw-shadow-colored:0 -25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.yst-root .yst-popover--bottom-right:before{bottom:100%;inset-inline-start:2rem;--tw-translate-x:-50%;--tw-translate-y:0px;border-color:#0000;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-content:"";content:var(--tw-content)}.yst-root .yst-popover--bottom-right:where([dir=rtl],[dir=rtl] *):before{content:var(--tw-content);--tw-translate-x:50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-popover--bottom-right:before{border-bottom:14px solid #fff;border-left:14px solid #0000;border-right:14px solid #0000}.yst-root .yst-radio-group--inline-block .yst-radio-group__options{display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem}.yst-root .yst-radio-group--disabled .yst-radio-group__description,.yst-root .yst-radio-group--disabled .yst-radio-group__label{opacity:.5}.yst-root .yst-radio-group--disabled .yst-radio-group__label{cursor:not-allowed}.yst-root .yst-radio-group__label{margin-bottom:.5rem}.yst-root .yst-radio-group__options{display:flex;flex-direction:column;gap:.5rem}.yst-root .yst-radio-group__description{margin-bottom:1rem;margin-top:-.5rem}.yst-root .yst-select-field--disabled .yst-select-field__description,.yst-root .yst-select-field--disabled .yst-select-field__label{cursor:not-allowed;opacity:.5}.yst-root .yst-select-field__options{display:flex;flex-direction:column;gap:.75rem}.yst-root .yst-select-field__description,.yst-root .yst-select-field__validation{margin-top:.5rem}.yst-root .yst-mobile-navigation__top{position:sticky;top:0;width:100%;z-index:50}.yst-root .yst-mobile-navigation__dialog{display:flex;inset:0;position:fixed;z-index:50}.yst-root .yst-mobile-navigation__dialog,.yst-root .yst-sidebar-navigation__sidebar{--yst-menu-text-color:#1e293b}.yst-root .yst-sidebar-navigation__list>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.125rem*var(--tw-space-y-reverse));margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-sidebar-navigation__list--indented{margin-inline-start:2rem;--yst-menu-text-color:#475569}.yst-root .yst-sidebar-navigation__item--active.yst-sidebar-navigation__collapsible-button,.yst-root .yst-sidebar-navigation__item--active.yst-sidebar-navigation__link{--tw-bg-opacity:1!important;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))!important;--tw-text-opacity:1!important;color:rgb(15 23 42/var(--tw-text-opacity,1))!important}.yst-root .yst-sidebar-navigation__item--active .yst-sidebar-navigation__icon{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-sidebar-navigation__item{list-style-type:none}.yst-root .yst-sidebar-navigation__item>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.125rem*var(--tw-space-y-reverse));margin-top:calc(.125rem*(1 - var(--tw-space-y-reverse)))}.yst-root .yst-sidebar-navigation__item:first-child{margin-top:.125rem}.yst-root .yst-sidebar-navigation__collapsible~.yst-sidebar-navigation__collapsible{margin-top:.25rem}.yst-root .yst-sidebar-navigation__collapsible-button{align-items:center;border-radius:.375rem;color:var(--yst-menu-text-color);column-gap:.75rem;cursor:pointer;display:flex;font-size:.8125rem;font-weight:500;justify-content:center;padding:.5rem .75rem;-webkit-text-decoration-line:none;text-decoration-line:none;width:100%}.yst-root .yst-sidebar-navigation__collapsible-button:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.yst-root .yst-sidebar-navigation__collapsible-button:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))}.yst-root .yst-sidebar-navigation__link{align-items:center;border-radius:.375rem;color:var(--yst-menu-text-color);display:flex;font-size:.8125rem;font-weight:500;padding:.5rem .75rem;-webkit-text-decoration-line:none;text-decoration-line:none}.yst-root .yst-sidebar-navigation__link:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.yst-root .yst-sidebar-navigation__link:focus{outline:2px solid #0000;outline-offset:2px;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:1px;--tw-ring-offset-color:#0000}.yst-root a.yst-sidebar-navigation__link:visited{color:var(--yst-menu-text-color)}.yst-root a.yst-sidebar-navigation__link:hover:visited{color:#0f172a}.yst-root a.yst-sidebar-navigation__link:focus{border-radius:.375rem;color:var(--yst-menu-text-color)}.yst-root .yst-sidebar-navigation__icon{flex-shrink:0;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-group:hover .yst-root .yst-sidebar-navigation__icon{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity,1))}.yst-root .yst-stepper{align-items:center;display:flex;justify-content:space-between;position:relative}.yst-root .yst-stepper .yst-progress-bar__progress{transition-duration:.5s}.yst-root .yst-step{align-items:center;display:flex;flex-direction:column}.yst-root .yst-step__circle{border-radius:9999px;height:1.5rem;position:relative;width:1.5rem;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(203 213 225/var(--tw-ring-opacity,1))}.yst-root .yst-step__icon{left:50%;position:absolute;top:50%;--tw-translate-x:-50%;--tw-translate-y:-50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.yst-root .yst-step--active{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1))}.yst-root .yst-step--active .yst-step__circle{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));transition-delay:.5s;transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,1,1)}.yst-root .yst-step--active .yst-step__icon{transition-duration:.15s;transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(.4,0,1,1)}.yst-root .yst-step--complete{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity,1))}.yst-root .yst-step--complete .yst-step__circle{--tw-bg-opacity:1;background-color:rgb(166 30 105/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1));--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));transition-delay:0s;transition-property:none}.yst-root .yst-tag-field--disabled .yst-tag-field__description,.yst-root .yst-tag-field--disabled .yst-tag-field__label{opacity:.5}.yst-root .yst-tag-field--disabled .yst-tag-field__label{cursor:not-allowed}.yst-root .yst-tag-field__description,.yst-root .yst-tag-field__validation{margin-top:.5rem}.yst-root .yst-text-field--disabled .yst-text-field__description,.yst-root .yst-text-field--disabled .yst-text-field__label{opacity:.5}.yst-root .yst-text-field--disabled .yst-text-field__label{cursor:not-allowed}.yst-root .yst-text-field--read-only .yst-text-field__label{cursor:default}.yst-root .yst-text-field__description,.yst-root .yst-text-field__validation{margin-top:.5rem}.yst-root .yst-textarea-field--disabled .yst-textarea-field__description,.yst-root .yst-textarea-field--disabled .yst-textarea-field__label{opacity:.5}.yst-root .yst-textarea-field--disabled .yst-textarea-field__label{cursor:not-allowed}.yst-root .yst-text-field--read-only .yst-textarea-field__label{cursor:default}.yst-root .yst-textarea-field__description,.yst-root .yst-textarea-field__validation{margin-top:.5rem}.yst-root .yst-toggle-field{display:flex;flex-direction:column;gap:.25rem}.yst-root .yst-toggle-field--disabled .yst-toggle-field__description,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label-wrapper{opacity:.5}.yst-root .yst-toggle-field--disabled .yst-toggle-field__label,.yst-root .yst-toggle-field--disabled .yst-toggle-field__label-wrapper{cursor:not-allowed}.yst-root .yst-toggle-field__header{align-items:center;display:flex;flex-direction:row;gap:1.5rem;justify-content:space-between}.yst-root .yst-toggle-field__label-wrapper{align-items:center;display:flex;gap:.25rem}.yst-root .yst-toggle-field__description{margin-inline-end:4.25rem}.yst-root .yst-tooltip-container{position:relative}.yst-root .yst-tooltip-trigger{border-radius:.375rem;cursor:pointer}.yst-root .yst-tooltip-trigger:focus{outline:2px solid #0000;outline-offset:2px}.yst-root .yst-tooltip-trigger:focus-visible{border-color:rgb(166 30 105/var(--tw-border-opacity,1));--tw-border-opacity:0;--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity,1));--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000);--tw-ring-opacity:1;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1));--tw-ring-offset-width:2px}.yst-root .yst-difficulty--very-easy{--tw-bg-opacity:1;background-color:rgb(110 231 183/var(--tw-bg-opacity,1))}.yst-root .yst-difficulty--easy{--tw-bg-opacity:1;background-color:rgb(5 150 105/var(--tw-bg-opacity,1))}.yst-root .yst-difficulty--possible{--tw-bg-opacity:1;background-color:rgb(251 191 36/var(--tw-bg-opacity,1))}.yst-root .yst-difficulty--difficult{--tw-bg-opacity:1;background-color:rgb(251 146 60/var(--tw-bg-opacity,1))}.yst-root .yst-difficulty--hard{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity,1))}.yst-root .yst-difficulty--very-hard{--tw-bg-opacity:1;background-color:rgb(185 28 28/var(--tw-bg-opacity,1))}.yst-root .yst-intent-badge{align-items:center;border-radius:.125rem;display:flex;font-size:.8125rem;font-weight:600;height:1.25rem;justify-content:center;position:relative;text-transform:uppercase;width:1.25rem}.yst-root .yst-intent-badge.yst-intent-badge--i{--tw-bg-opacity:1;background-color:rgb(191 219 254/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(30 58 138/var(--tw-text-opacity,1))}.yst-root .yst-intent-badge.yst-intent-badge--n{--tw-bg-opacity:1;background-color:rgb(221 214 254/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(76 29 149/var(--tw-text-opacity,1))}.yst-root .yst-intent-badge.yst-intent-badge--c{--tw-bg-opacity:1;background-color:rgb(253 230 138/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}.yst-root .yst-intent-badge.yst-intent-badge--t{--tw-bg-opacity:1;background-color:rgb(187 247 208/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(20 83 45/var(--tw-text-opacity,1))}.yst-root .yst-table-button{gap:.5rem}.yst-root .yst-table-button.yst-button--secondary .yst-button-icon{height:.75rem;width:.75rem;--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity,1))}.yst-root .yst-table-button.yst-button--tertiary{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.yst-root .yst-table-button.yst-button--tertiary:hover{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity,1))}.yst-root .yst-table-button.yst-button--tertiary .yst-button-icon{height:.875rem;width:.875rem}.yst-root .yst-success-message{align-items:center;display:flex;font-size:.75rem;gap:.25rem;justify-content:center;line-height:1.25rem;padding:.25rem .75rem;--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity,1));transition-duration:.3s;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-timing-function:cubic-bezier(0,0,.2,1)}.yst-root .yst-success-message .yst-success-icon{height:1rem;width:1rem}.yst-root .yst-success-message.yst-success-message-add .yst-success-icon{--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity,1))}.yst-root .yst-success-message.yst-success-message-remove .yst-success-icon{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity,1))}.yst-root .yst-modal-footer-link{align-items:center;display:flex;flex-direction:row;gap:.25rem}.yst-root .yst-modal-footer-link .yst-link-icon{height:.75rem;width:.75rem}.yst-root .yst-related-keyphrase-modal-content{max-height:60vh;min-height:350px;overflow-y:auto;padding:1.5rem}.yst-sr-only{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;border-width:0!important;white-space:nowrap!important}.yst-pointer-events-none{pointer-events:none!important}.yst-invisible{visibility:hidden!important}.yst-fixed{position:fixed!important}.yst-absolute{position:absolute!important}.yst-relative{position:relative!important}.yst-sticky{position:sticky!important}.yst-inset-0{inset:0!important}.yst-inset-5{inset:1.25rem!important}.yst-inset-x-0{left:0!important;right:0!important}.yst-inset-y-0{bottom:0!important;top:0!important}.yst--bottom-6{bottom:-1.5rem!important}.yst--end-\[6\.5px\]{inset-inline-end:-6.5px!important}.yst--left-3{left:-.75rem!important}.yst--top-2{top:-.5rem!important}.yst--top-\[6\.5px\]{top:-6.5px!important}.yst-bottom-0{bottom:0!important}.yst-bottom-12{bottom:3rem!important}.yst-end-0{inset-inline-end:0!important}.yst-end-12{inset-inline-end:3rem!important}.yst-end-2{inset-inline-end:.5rem!important}.yst-end-4{inset-inline-end:1rem!important}.yst-left-1\/2{left:50%!important}.yst-right-0{right:0!important}.yst-start-4{inset-inline-start:1rem!important}.yst-start-48{inset-inline-start:12rem!important}.yst-top-0{top:0!important}.yst-top-1\/2{top:50%!important}.yst-top-16{top:4rem!important}.yst-top-2{top:.5rem!important}.yst-top-3{top:.75rem!important}.yst-top-3\.5{top:.875rem!important}.yst-top-4{top:1rem!important}.yst-top-8{top:2rem!important}.yst-top-\[-11px\]{top:-11px!important}.yst-z-10{z-index:10!important}.yst-z-20{z-index:20!important}.yst-z-30{z-index:30!important}.yst-z-40{z-index:40!important}.yst-z-\[1000\]{z-index:1000!important}.yst-order-last{order:9999!important}.yst-col-span-1{grid-column:span 1/span 1!important}.yst-col-span-4{grid-column:span 4/span 4!important}.yst-float-end{float:inline-end!important}.yst--m-6{margin:-1.5rem!important}.yst-m-0{margin:0!important}.yst-m-8{margin:2rem!important}.yst-m-auto{margin:auto!important}.yst--mx-1{margin-left:-.25rem!important;margin-right:-.25rem!important}.yst--mx-6{margin-left:-1.5rem!important;margin-right:-1.5rem!important}.yst-mx-0{margin-left:0!important;margin-right:0!important}.yst-mx-1\.5{margin-left:.375rem!important;margin-right:.375rem!important}.yst-mx-10{margin-left:2.5rem!important;margin-right:2.5rem!important}.yst-mx-4{margin-left:1rem!important;margin-right:1rem!important}.yst-mx-\[calc\(50\%-50vw\)\]{margin-left:calc(50% - 50vw)!important;margin-right:calc(50% - 50vw)!important}.yst-mx-auto{margin-left:auto!important;margin-right:auto!important}.yst-my-0{margin-bottom:0!important;margin-top:0!important}.yst-my-0\.5{margin-bottom:.125rem!important;margin-top:.125rem!important}.yst-my-12{margin-bottom:3rem!important;margin-top:3rem!important}.yst-my-16{margin-bottom:4rem!important;margin-top:4rem!important}.yst-my-2{margin-bottom:.5rem!important;margin-top:.5rem!important}.yst-my-3{margin-bottom:.75rem!important;margin-top:.75rem!important}.yst-my-4{margin-bottom:1rem!important;margin-top:1rem!important}.yst-my-6{margin-bottom:1.5rem!important;margin-top:1.5rem!important}.yst-my-8{margin-bottom:2rem!important;margin-top:2rem!important}.yst-my-auto{margin-bottom:auto!important;margin-top:auto!important}.yst--me-1{margin-inline-end:-.25rem!important}.yst--me-14{margin-inline-end:-3.5rem!important}.yst--me-2{margin-inline-end:-.5rem!important}.yst--me-8{margin-inline-end:-2rem!important}.yst--ms-1{margin-inline-start:-.25rem!important}.yst--ms-2{margin-inline-start:-.5rem!important}.yst--ms-3{margin-inline-start:-.75rem!important}.yst--ms-px{margin-inline-start:-1px!important}.yst--mt-0\.5{margin-top:-.125rem!important}.yst--mt-10{margin-top:-2.5rem!important}.yst--mt-2{margin-top:-.5rem!important}.yst--mt-6{margin-top:-1.5rem!important}.yst-mb-0{margin-bottom:0!important}.yst-mb-1{margin-bottom:.25rem!important}.yst-mb-2{margin-bottom:.5rem!important}.yst-mb-3{margin-bottom:.75rem!important}.yst-mb-4{margin-bottom:1rem!important}.yst-mb-5{margin-bottom:1.25rem!important}.yst-mb-6{margin-bottom:1.5rem!important}.yst-mb-8{margin-bottom:2rem!important}.yst-mb-\[-25px\]{margin-bottom:-25px!important}.yst-mb-\[1px\],.yst-mb-px{margin-bottom:1px!important}.yst-me-1{margin-inline-end:.25rem!important}.yst-me-1\.5{margin-inline-end:.375rem!important}.yst-me-2{margin-inline-end:.5rem!important}.yst-me-3{margin-inline-end:.75rem!important}.yst-me-5{margin-inline-end:1.25rem!important}.yst-me-6{margin-inline-end:1.5rem!important}.yst-me-8{margin-inline-end:2rem!important}.yst-me-\[calc\(2\.5rem-1px\)\]{margin-inline-end:calc(2.5rem - 1px)!important}.yst-ml-1\.5{margin-left:.375rem!important}.yst-ml-2{margin-left:.5rem!important}.yst-mr-1{margin-right:.25rem!important}.yst-mr-2{margin-right:.5rem!important}.yst-mr-5{margin-right:1.25rem!important}.yst-ms-0\.5{margin-inline-start:.125rem!important}.yst-ms-1{margin-inline-start:.25rem!important}.yst-ms-1\.5{margin-inline-start:.375rem!important}.yst-ms-12{margin-inline-start:3rem!important}.yst-ms-2{margin-inline-start:.5rem!important}.yst-ms-3{margin-inline-start:.75rem!important}.yst-ms-4{margin-inline-start:1rem!important}.yst-ms-8{margin-inline-start:2rem!important}.yst-ms-auto{margin-inline-start:auto!important}.yst-mt-0{margin-top:0!important}.yst-mt-1{margin-top:.25rem!important}.yst-mt-1\.5{margin-top:.375rem!important}.yst-mt-10{margin-top:2.5rem!important}.yst-mt-12{margin-top:3rem!important}.yst-mt-2{margin-top:.5rem!important}.yst-mt-2\.5{margin-top:.625rem!important}.yst-mt-3{margin-top:.75rem!important}.yst-mt-4{margin-top:1rem!important}.yst-mt-5{margin-top:1.25rem!important}.yst-mt-6{margin-top:1.5rem!important}.yst-mt-7{margin-top:1.75rem!important}.yst-mt-8{margin-top:2rem!important}.yst-mt-\[-2\.6rem\]{margin-top:-2.6rem!important}.yst-mt-\[18px\]{margin-top:18px!important}.yst-mt-\[27\.5px\]{margin-top:27.5px!important}.yst-mt-\[3px\]{margin-top:3px!important}.yst-mt-auto{margin-top:auto!important}.yst-block{display:block!important}.yst-inline-block{display:inline-block!important}.yst-inline{display:inline!important}.yst-flex{display:flex!important}.yst-inline-flex{display:inline-flex!important}.yst-table-cell{display:table-cell!important}.yst-table-row{display:table-row!important}.yst-grid{display:grid!important}.yst-list-item{display:list-item!important}.yst-hidden{display:none!important}.yst-aspect-\[21\/5\]{aspect-ratio:21/5!important}.yst-aspect-square{aspect-ratio:1/1!important}.yst-aspect-video{aspect-ratio:16/9!important}.yst-h-0{height:0!important}.yst-h-0\.5{height:.125rem!important}.yst-h-1\.5{height:.375rem!important}.yst-h-10{height:2.5rem!important}.yst-h-11{height:2.75rem!important}.yst-h-12{height:3rem!important}.yst-h-14{height:3.5rem!important}.yst-h-16{height:4rem!important}.yst-h-2{height:.5rem!important}.yst-h-2\.5{height:.625rem!important}.yst-h-20{height:5rem!important}.yst-h-24{height:6rem!important}.yst-h-3{height:.75rem!important}.yst-h-4{height:1rem!important}.yst-h-4\/5{height:80%!important}.yst-h-48{height:12rem!important}.yst-h-5{height:1.25rem!important}.yst-h-52{height:13rem!important}.yst-h-6{height:1.5rem!important}.yst-h-60{height:15rem!important}.yst-h-7{height:1.75rem!important}.yst-h-8{height:2rem!important}.yst-h-9{height:2.25rem!important}.yst-h-96{height:24rem!important}.yst-h-\[17px\]{height:17px!important}.yst-h-\[18px\]{height:18px!important}.yst-h-\[19\.5px\]{height:19.5px!important}.yst-h-\[265px\]{height:265px!important}.yst-h-\[273px\]{height:273px!important}.yst-h-\[40px\]{height:40px!important}.yst-h-\[42px\]{height:42px!important}.yst-h-auto{height:auto!important}.yst-h-fit{height:-moz-fit-content!important;height:fit-content!important}.yst-h-full{height:100%!important}.yst-max-h-32{max-height:8rem!important}.yst-max-h-60{max-height:15rem!important}.yst-max-h-\[370px\]{max-height:370px!important}.yst-max-h-\[calc\(90vh-10rem\)\]{max-height:calc(90vh - 10rem)!important}.yst-min-h-20{min-height:5rem!important}.yst-min-h-\[24px\]{min-height:24px!important}.yst-min-h-\[84vh\]{min-height:84vh!important}.yst-min-h-full{min-height:100%!important}.yst-w-0{width:0!important}.yst-w-0\.5{width:.125rem!important}.yst-w-1\/3{width:33.333333%!important}.yst-w-10{width:2.5rem!important}.yst-w-10\/12{width:83.333333%!important}.yst-w-11{width:2.75rem!important}.yst-w-11\/12{width:91.666667%!important}.yst-w-12{width:3rem!important}.yst-w-14{width:3.5rem!important}.yst-w-16{width:4rem!important}.yst-w-2{width:.5rem!important}.yst-w-2\.5{width:.625rem!important}.yst-w-20{width:5rem!important}.yst-w-3{width:.75rem!important}.yst-w-3\/4{width:75%!important}.yst-w-3\/5{width:60%!important}.yst-w-32{width:8rem!important}.yst-w-36{width:9rem!important}.yst-w-4{width:1rem!important}.yst-w-40{width:10rem!important}.yst-w-44{width:11rem!important}.yst-w-48{width:12rem!important}.yst-w-5{width:1.25rem!important}.yst-w-52{width:13rem!important}.yst-w-56{width:14rem!important}.yst-w-6{width:1.5rem!important}.yst-w-7{width:1.75rem!important}.yst-w-7\/12{width:58.333333%!important}.yst-w-8{width:2rem!important}.yst-w-8\/12{width:66.666667%!important}.yst-w-9{width:2.25rem!important}.yst-w-9\/12{width:75%!important}.yst-w-96{width:24rem!important}.yst-w-\[140px\]{width:140px!important}.yst-w-\[17px\]{width:17px!important}.yst-w-\[184px\]{width:184px!important}.yst-w-\[19\.5px\]{width:19.5px!important}.yst-w-\[350px\]{width:350px!important}.yst-w-\[42px\]{width:42px!important}.yst-w-\[507px\]{width:507px!important}.yst-w-\[527px\]{width:527px!important}.yst-w-\[88px\]{width:88px!important}.yst-w-\[calc\(11\.5rem\+3px\)\]{width:calc(11.5rem + 3px)!important}.yst-w-auto{width:auto!important}.yst-w-full{width:100%!important}.yst-w-min{width:min-content!important}.yst-min-w-0{min-width:0!important}.yst-min-w-28{min-width:7rem!important}.yst-min-w-\[16rem\]{min-width:16rem!important}.yst-min-w-full{min-width:100%!important}.yst-max-w-2xl{max-width:42rem!important}.yst-max-w-36{max-width:9rem!important}.yst-max-w-3xl{max-width:48rem!important}.yst-max-w-44{max-width:11rem!important}.yst-max-w-48{max-width:12rem!important}.yst-max-w-4xl{max-width:56rem!important}.yst-max-w-5xl{max-width:64rem!important}.yst-max-w-64{max-width:16rem!important}.yst-max-w-6xl{max-width:72rem!important}.yst-max-w-80{max-width:20rem!important}.yst-max-w-\[13\.5rem\]{max-width:13.5rem!important}.yst-max-w-\[252px\]{max-width:252px!important}.yst-max-w-\[300px\]{max-width:300px!important}.yst-max-w-\[400px\]{max-width:400px!important}.yst-max-w-\[432px\]{max-width:432px!important}.yst-max-w-\[500px\]{max-width:500px!important}.yst-max-w-\[600px\]{max-width:600px!important}.yst-max-w-\[715px\]{max-width:715px!important}.yst-max-w-full{max-width:100%!important}.yst-max-w-lg{max-width:32rem!important}.yst-max-w-md{max-width:28rem!important}.yst-max-w-none{max-width:none!important}.yst-max-w-page{max-width:2048px!important}.yst-max-w-screen-sm{max-width:640px!important}.yst-max-w-sm{max-width:24rem!important}.yst-max-w-xl{max-width:36rem!important}.yst-max-w-xs{max-width:20rem!important}.yst-flex-1{flex:1 1 0%!important}.yst-flex-none{flex:none!important}.yst-flex-shrink-0,.yst-shrink-0{flex-shrink:0!important}.yst-flex-grow,.yst-grow{flex-grow:1!important}.yst-table-fixed{table-layout:fixed!important}.yst-origin-top{transform-origin:top!important}.yst--translate-x-1\/2{--tw-translate-x:-50%!important}.yst--translate-x-1\/2,.yst--translate-y-1\/2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst--translate-y-1\/2{--tw-translate-y:-50%!important}.yst--translate-y-full{--tw-translate-y:-100%!important}.yst--translate-y-full,.yst-translate-x-2{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-translate-x-2{--tw-translate-x:0.5rem!important}.yst-translate-y-0{--tw-translate-y:0px!important}.yst-translate-y-0,.yst-translate-y-4{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-translate-y-4{--tw-translate-y:1rem!important}.yst-translate-y-full{--tw-translate-y:100%!important}.yst-rotate-180,.yst-translate-y-full{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-rotate-180{--tw-rotate:180deg!important}.yst-scale-100{--tw-scale-x:1!important;--tw-scale-y:1!important}.yst-scale-100,.yst-scale-95{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-scale-95{--tw-scale-x:.95!important;--tw-scale-y:.95!important}.yst-scale-x-\[-1\]{--tw-scale-x:-1!important}.yst-scale-x-\[-1\],.yst-scale-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-scale-y-0{--tw-scale-y:0!important}.yst-transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}@keyframes yst-spin{to{transform:rotate(1turn)}}.yst-animate-spin{animation:yst-spin 1s linear infinite!important}.yst-cursor-default{cursor:default!important}.yst-cursor-help{cursor:help!important}.yst-cursor-not-allowed{cursor:not-allowed!important}.yst-cursor-pointer{cursor:pointer!important}.yst-cursor-wait{cursor:wait!important}.yst-select-none{-webkit-user-select:none!important;user-select:none!important}.yst-scroll-pb-2{scroll-padding-bottom:.5rem!important}.yst-scroll-pt-11{scroll-padding-top:2.75rem!important}.yst-list-outside{list-style-position:outside!important}.yst-list-disc{list-style-type:disc!important}.yst-list-none{list-style-type:none!important}.yst-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))!important}.yst-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))!important}.yst-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))!important}.yst-grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))!important}.yst-flex-row{flex-direction:row!important}.yst-flex-col{flex-direction:column!important}.yst-flex-wrap{flex-wrap:wrap!important}.yst-place-content-end{place-content:end!important}.yst-content-between{align-content:space-between!important}.yst-items-start{align-items:flex-start!important}.yst-items-end{align-items:flex-end!important}.yst-items-center{align-items:center!important}.yst-justify-start{justify-content:flex-start!important}.yst-justify-end{justify-content:flex-end!important}.yst-justify-center{justify-content:center!important}.yst-justify-between{justify-content:space-between!important}.yst-gap-0\.5{gap:.125rem!important}.yst-gap-1{gap:.25rem!important}.yst-gap-1\.5{gap:.375rem!important}.yst-gap-12{gap:3rem!important}.yst-gap-2{gap:.5rem!important}.yst-gap-3{gap:.75rem!important}.yst-gap-4{gap:1rem!important}.yst-gap-6{gap:1.5rem!important}.yst-gap-8{gap:2rem!important}.yst-gap-px{gap:1px!important}.yst-gap-x-2{column-gap:.5rem!important}.yst-gap-x-3{column-gap:.75rem!important}.yst-gap-x-4{column-gap:1rem!important}.yst-gap-x-5{column-gap:1.25rem!important}.yst-gap-x-6{column-gap:1.5rem!important}.yst-gap-y-1{row-gap:.25rem!important}.yst-gap-y-2{row-gap:.5rem!important}.yst-gap-y-4{row-gap:1rem!important}.yst-gap-y-6{row-gap:1.5rem!important}.yst--space-y-\[1px\]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(-1px*var(--tw-space-y-reverse))!important;margin-top:calc(-1px*(1 - var(--tw-space-y-reverse)))!important}.yst-space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0!important;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))!important;margin-right:calc(.5rem*var(--tw-space-x-reverse))!important}.yst-space-x-3>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0!important;margin-left:calc(.75rem*(1 - var(--tw-space-x-reverse)))!important;margin-right:calc(.75rem*var(--tw-space-x-reverse))!important}.yst-space-x-8>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0!important;margin-left:calc(2rem*(1 - var(--tw-space-x-reverse)))!important;margin-right:calc(2rem*var(--tw-space-x-reverse))!important}.yst-space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(.25rem*var(--tw-space-y-reverse))!important;margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))!important}.yst-space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(.5rem*var(--tw-space-y-reverse))!important;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))!important}.yst-space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(.75rem*var(--tw-space-y-reverse))!important;margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))!important}.yst-space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(1rem*var(--tw-space-y-reverse))!important;margin-top:calc(1rem*(1 - var(--tw-space-y-reverse)))!important}.yst-space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(1.5rem*var(--tw-space-y-reverse))!important;margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)))!important}.yst-space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0!important;margin-bottom:calc(2rem*var(--tw-space-y-reverse))!important;margin-top:calc(2rem*(1 - var(--tw-space-y-reverse)))!important}.yst-divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse:0!important;border-bottom-width:calc(1px*var(--tw-divide-y-reverse))!important;border-top-width:calc(1px*(1 - var(--tw-divide-y-reverse)))!important}.yst-divide-slate-200>:not([hidden])~:not([hidden]){--tw-divide-opacity:1!important;border-color:rgb(226 232 240/var(--tw-divide-opacity,1))!important}.yst-self-start{align-self:flex-start!important}.yst-self-end{align-self:flex-end!important}.yst-self-center{align-self:center!important}.yst-overflow-auto{overflow:auto!important}.yst-overflow-hidden{overflow:hidden!important}.yst-overflow-y-auto{overflow-y:auto!important}.yst-overflow-x-hidden{overflow-x:hidden!important}.yst-overflow-x-scroll{overflow-x:scroll!important}.yst-truncate{overflow:hidden!important;white-space:nowrap!important}.yst-overflow-ellipsis,.yst-text-ellipsis,.yst-truncate{text-overflow:ellipsis!important}.yst-whitespace-nowrap{white-space:nowrap!important}.yst-whitespace-pre-line{white-space:pre-line!important}.yst-break-all{word-break:break-all!important}.yst-rounded{border-radius:.25rem!important}.yst-rounded-2xl{border-radius:1rem!important}.yst-rounded-3xl{border-radius:1.5rem!important}.yst-rounded-full{border-radius:9999px!important}.yst-rounded-lg{border-radius:.5rem!important}.yst-rounded-md{border-radius:.375rem!important}.yst-rounded-none{border-radius:0!important}.yst-rounded-b-lg{border-bottom-left-radius:.5rem!important;border-bottom-right-radius:.5rem!important}.yst-rounded-b-none{border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.yst-rounded-e-md{border-end-end-radius:.375rem!important;border-start-end-radius:.375rem!important}.yst-rounded-r-md{border-bottom-right-radius:.375rem!important;border-top-right-radius:.375rem!important}.yst-rounded-s-md{border-end-start-radius:.375rem!important;border-start-start-radius:.375rem!important}.yst-rounded-t-2xl{border-top-left-radius:1rem!important;border-top-right-radius:1rem!important}.yst-rounded-t-\[14px\]{border-top-left-radius:14px!important;border-top-right-radius:14px!important}.yst-rounded-t-lg{border-top-left-radius:.5rem!important;border-top-right-radius:.5rem!important}.yst-border{border-width:1px!important}.yst-border-0{border-width:0!important}.yst-border-2{border-width:2px!important}.yst-border-x-0{border-left-width:0!important;border-right-width:0!important}.yst-border-y{border-top-width:1px!important}.yst-border-b,.yst-border-y{border-bottom-width:1px!important}.yst-border-l{border-left-width:1px!important}.yst-border-r{border-right-width:1px!important}.yst-border-t{border-top-width:1px!important}.yst-border-solid{border-style:solid!important}.yst-border-dashed{border-style:dashed!important}.yst-border-none{border-style:none!important}.yst-border-amber-300{--tw-border-opacity:1!important;border-color:rgb(252 211 77/var(--tw-border-opacity,1))!important}.yst-border-black{--tw-border-opacity:1!important;border-color:rgb(0 0 0/var(--tw-border-opacity,1))!important}.yst-border-emerald-600{--tw-border-opacity:1!important;border-color:rgb(5 150 105/var(--tw-border-opacity,1))!important}.yst-border-green-400{--tw-border-opacity:1!important;border-color:rgb(74 222 128/var(--tw-border-opacity,1))!important}.yst-border-primary-200{--tw-border-opacity:1!important;border-color:rgb(224 179 204/var(--tw-border-opacity,1))!important}.yst-border-primary-300{--tw-border-opacity:1!important;border-color:rgb(205 130 171/var(--tw-border-opacity,1))!important}.yst-border-primary-500{--tw-border-opacity:1!important;border-color:rgb(166 30 105/var(--tw-border-opacity,1))!important}.yst-border-red-300{--tw-border-opacity:1!important;border-color:rgb(252 165 165/var(--tw-border-opacity,1))!important}.yst-border-red-400{--tw-border-opacity:1!important;border-color:rgb(248 113 113/var(--tw-border-opacity,1))!important}.yst-border-red-500{--tw-border-opacity:1!important;border-color:rgb(239 68 68/var(--tw-border-opacity,1))!important}.yst-border-slate-100{--tw-border-opacity:1!important;border-color:rgb(241 245 249/var(--tw-border-opacity,1))!important}.yst-border-slate-200{--tw-border-opacity:1!important;border-color:rgb(226 232 240/var(--tw-border-opacity,1))!important}.yst-border-slate-300{--tw-border-opacity:1!important;border-color:rgb(203 213 225/var(--tw-border-opacity,1))!important}.yst-border-transparent{border-color:#0000!important}.yst-border-woo-light{--tw-border-opacity:1!important;border-color:rgb(0 117 179/var(--tw-border-opacity,1))!important}.yst-border-b-slate-200{--tw-border-opacity:1!important;border-bottom-color:rgb(226 232 240/var(--tw-border-opacity,1))!important}.yst-border-t-\[rgb\(0\,0\,0\,0\.2\)\]{border-top-color:#0003!important}.yst-border-t-slate-200{--tw-border-opacity:1!important;border-top-color:rgb(226 232 240/var(--tw-border-opacity,1))!important}.yst-border-opacity-30{--tw-border-opacity:0.3!important}.yst-border-opacity-50{--tw-border-opacity:0.5!important}.yst-bg-amber-200{--tw-bg-opacity:1!important;background-color:rgb(253 230 138/var(--tw-bg-opacity,1))!important}.yst-bg-amber-300{--tw-bg-opacity:1!important;background-color:rgb(252 211 77/var(--tw-bg-opacity,1))!important}.yst-bg-analysis-bad{--tw-bg-opacity:1!important;background-color:rgb(220 50 50/var(--tw-bg-opacity,1))!important}.yst-bg-analysis-good{--tw-bg-opacity:1!important;background-color:rgb(122 208 58/var(--tw-bg-opacity,1))!important}.yst-bg-analysis-na{--tw-bg-opacity:1!important;background-color:rgb(203 213 225/var(--tw-bg-opacity,1))!important}.yst-bg-analysis-ok{--tw-bg-opacity:1!important;background-color:rgb(238 124 27/var(--tw-bg-opacity,1))!important}.yst-bg-black{--tw-bg-opacity:1!important;background-color:rgb(0 0 0/var(--tw-bg-opacity,1))!important}.yst-bg-blue-100{--tw-bg-opacity:1!important;background-color:rgb(219 234 254/var(--tw-bg-opacity,1))!important}.yst-bg-gray-400{--tw-bg-opacity:1!important;background-color:rgb(156 163 175/var(--tw-bg-opacity,1))!important}.yst-bg-green-100{--tw-bg-opacity:1!important;background-color:rgb(220 252 231/var(--tw-bg-opacity,1))!important}.yst-bg-green-200{--tw-bg-opacity:1!important;background-color:rgb(187 247 208/var(--tw-bg-opacity,1))!important}.yst-bg-green-500{--tw-bg-opacity:1!important;background-color:rgb(34 197 94/var(--tw-bg-opacity,1))!important}.yst-bg-primary-200{--tw-bg-opacity:1!important;background-color:rgb(224 179 204/var(--tw-bg-opacity,1))!important}.yst-bg-primary-500{--tw-bg-opacity:1!important;background-color:rgb(166 30 105/var(--tw-bg-opacity,1))!important}.yst-bg-primary-600{--tw-bg-opacity:1!important;background-color:rgb(154 22 96/var(--tw-bg-opacity,1))!important}.yst-bg-red-100{--tw-bg-opacity:1!important;background-color:rgb(254 226 226/var(--tw-bg-opacity,1))!important}.yst-bg-slate-100{--tw-bg-opacity:1!important;background-color:rgb(241 245 249/var(--tw-bg-opacity,1))!important}.yst-bg-slate-200{--tw-bg-opacity:1!important;background-color:rgb(226 232 240/var(--tw-bg-opacity,1))!important}.yst-bg-slate-300{--tw-bg-opacity:1!important;background-color:rgb(203 213 225/var(--tw-bg-opacity,1))!important}.yst-bg-slate-400{--tw-bg-opacity:1!important;background-color:rgb(148 163 184/var(--tw-bg-opacity,1))!important}.yst-bg-slate-50{--tw-bg-opacity:1!important;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))!important}.yst-bg-slate-600{--tw-bg-opacity:1!important;background-color:rgb(71 85 105/var(--tw-bg-opacity,1))!important}.yst-bg-transparent{background-color:initial!important}.yst-bg-white{--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))!important}.yst-bg-woo-light{--tw-bg-opacity:1!important;background-color:rgb(0 117 179/var(--tw-bg-opacity,1))!important}.yst-bg-yellow-100{--tw-bg-opacity:1!important;background-color:rgb(254 249 195/var(--tw-bg-opacity,1))!important}.yst-bg-opacity-0{--tw-bg-opacity:0!important}.yst-bg-opacity-100{--tw-bg-opacity:1!important}.yst-bg-opacity-15{--tw-bg-opacity:0.15!important}.yst-bg-opacity-75{--tw-bg-opacity:0.75!important}.yst-bg-ai-500{background-image:linear-gradient(97.38deg,#a61e69,#6366f1)!important}.yst-bg-gradient-content-optimization{background-image:linear-gradient(to bottom right,#ef9d48 7%,#4338ca 74%)!important}.yst-bg-gradient-site-structure{background-image:linear-gradient(133deg,#54bbbb 7%,#2f3f85 74%)!important}.yst-bg-gradient-social-sharing{background-image:linear-gradient(133deg,#760b65 22%,#f590e4 94%)!important}.yst-bg-gradient-technical-seo{background-image:linear-gradient(133deg,#760b65 22%,#ef9d48 94%)!important}.yst-bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))!important}.yst-bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))!important}.yst-bg-gradient-tools{background-image:linear-gradient(133deg,#0e1e65 19%,#399b9b 94%)!important}.yst-from-primary-500\/25{--tw-gradient-from:#a61e6940 var(--tw-gradient-from-position)!important;--tw-gradient-to:#a61e6900 var(--tw-gradient-to-position)!important;--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)!important}.yst-from-slate-50{--tw-gradient-from:#f8fafc var(--tw-gradient-from-position)!important;--tw-gradient-to:#f8fafc00 var(--tw-gradient-to-position)!important;--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)!important}.yst-to-\[80\%\]{--tw-gradient-to-position:80%!important}.yst-fill-blue-500{fill:#3b82f6!important}.yst-fill-primary-500{fill:#a61e69!important}.yst-fill-red-500{fill:#ef4444!important}.yst-fill-sky-200{fill:#bae6fd!important}.yst-stroke-blue-500{stroke:#3b82f6!important}.yst-stroke-green-700{stroke:#15803d!important}.yst-stroke-slate-400{stroke:#94a3b8!important}.yst-stroke-1{stroke-width:1!important}.yst-stroke-3{stroke-width:3px!important}.yst-object-contain{object-fit:contain!important}.yst-object-cover{object-fit:cover!important}.yst-object-center{object-position:center!important}.yst-p-0{padding:0!important}.yst-p-0\.5{padding:.125rem!important}.yst-p-1{padding:.25rem!important}.yst-p-1\.5{padding:.375rem!important}.yst-p-2{padding:.5rem!important}.yst-p-2\.5{padding:.625rem!important}.yst-p-3{padding:.75rem!important}.yst-p-4{padding:1rem!important}.yst-p-6{padding:1.5rem!important}.yst-p-7{padding:1.75rem!important}.yst-p-8{padding:2rem!important}.yst-px-0{padding-left:0!important;padding-right:0!important}.yst-px-0\.5{padding-left:.125rem!important;padding-right:.125rem!important}.yst-px-1\.5{padding-left:.375rem!important;padding-right:.375rem!important}.yst-px-10{padding-left:2.5rem!important;padding-right:2.5rem!important}.yst-px-11{padding-left:2.75rem!important;padding-right:2.75rem!important}.yst-px-12{padding-left:3rem!important;padding-right:3rem!important}.yst-px-2{padding-left:.5rem!important;padding-right:.5rem!important}.yst-px-2\.5{padding-left:.625rem!important;padding-right:.625rem!important}.yst-px-3{padding-left:.75rem!important;padding-right:.75rem!important}.yst-px-4{padding-left:1rem!important;padding-right:1rem!important}.yst-px-6{padding-left:1.5rem!important;padding-right:1.5rem!important}.yst-px-8{padding-left:2rem!important;padding-right:2rem!important}.yst-px-\[3px\]{padding-left:3px!important;padding-right:3px!important}.yst-py-0{padding-bottom:0!important;padding-top:0!important}.yst-py-1{padding-bottom:.25rem!important;padding-top:.25rem!important}.yst-py-1\.5{padding-bottom:.375rem!important;padding-top:.375rem!important}.yst-py-10{padding-bottom:2.5rem!important;padding-top:2.5rem!important}.yst-py-12{padding-bottom:3rem!important;padding-top:3rem!important}.yst-py-2{padding-bottom:.5rem!important;padding-top:.5rem!important}.yst-py-3{padding-bottom:.75rem!important;padding-top:.75rem!important}.yst-py-3\.5{padding-bottom:.875rem!important;padding-top:.875rem!important}.yst-py-4{padding-bottom:1rem!important;padding-top:1rem!important}.yst-py-6{padding-bottom:1.5rem!important;padding-top:1.5rem!important}.yst-py-\[2px\]{padding-bottom:2px!important;padding-top:2px!important}.yst-py-\[3px\]{padding-bottom:3px!important;padding-top:3px!important}.yst-pb-1{padding-bottom:.25rem!important}.yst-pb-10{padding-bottom:2.5rem!important}.yst-pb-2{padding-bottom:.5rem!important}.yst-pb-4{padding-bottom:1rem!important}.yst-pb-6{padding-bottom:1.5rem!important}.yst-pb-8{padding-bottom:2rem!important}.yst-pe-0{padding-inline-end:0!important}.yst-pe-10{padding-inline-end:2.5rem!important}.yst-pe-2{padding-inline-end:.5rem!important}.yst-pe-4{padding-inline-end:1rem!important}.yst-pe-5{padding-inline-end:1.25rem!important}.yst-pe-9{padding-inline-end:2.25rem!important}.yst-pl-2{padding-left:.5rem!important}.yst-pr-3{padding-right:.75rem!important}.yst-ps-0{padding-inline-start:0!important}.yst-ps-2{padding-inline-start:.5rem!important}.yst-ps-3{padding-inline-start:.75rem!important}.yst-ps-6{padding-inline-start:1.5rem!important}.yst-ps-\[29px\]{padding-inline-start:29px!important}.yst-pt-1{padding-top:.25rem!important}.yst-pt-10{padding-top:2.5rem!important}.yst-pt-2{padding-top:.5rem!important}.yst-pt-3{padding-top:.75rem!important}.yst-pt-4{padding-top:1rem!important}.yst-pt-6{padding-top:1.5rem!important}.yst-pt-\[47\.25\%\]{padding-top:47.25%!important}.yst-pt-\[56\.25\%\]{padding-top:56.25%!important}.yst-text-left{text-align:left!important}.yst-text-center{text-align:center!important}.yst-text-right{text-align:right!important}.yst-text-start{text-align:start!important}.yst-text-end{text-align:end!important}.yst-align-middle{vertical-align:middle!important}.yst-font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.yst-font-wp{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif!important}.yst-text-2xl{font-size:1.5rem!important}.yst-text-4xl{font-size:2.25rem!important}.yst-text-\[10px\]{font-size:10px!important}.yst-text-\[16px\]{font-size:16px!important}.yst-text-base{font-size:1rem!important}.yst-text-lg{font-size:1.125rem!important}.yst-text-sm{font-size:.8125rem!important}.yst-text-tiny{font-size:.875rem!important}.yst-text-xl{font-size:1.25rem!important}.yst-text-xs{font-size:.75rem!important}.yst-text-xxs{font-size:.675rem!important}.yst-font-\[650\]{font-weight:650!important}.yst-font-bold{font-weight:700!important}.yst-font-extrabold{font-weight:800!important}.yst-font-medium{font-weight:500!important}.yst-font-normal{font-weight:400!important}.yst-font-semibold{font-weight:600!important}.yst-uppercase{text-transform:uppercase!important}.yst-capitalize{text-transform:capitalize!important}.yst-italic{font-style:italic!important}.yst-leading-10{line-height:2.5rem!important}.yst-leading-4{line-height:1rem!important}.yst-leading-5{line-height:1.25rem!important}.yst-leading-6{line-height:1.5rem!important}.yst-leading-7{line-height:1.75rem!important}.yst-leading-8{line-height:2rem!important}.yst-leading-\[0\]{line-height:0!important}.yst-leading-\[normal\]{line-height:normal!important}.yst-leading-none{line-height:1!important}.yst-leading-normal{line-height:1.5!important}.yst-leading-tight{line-height:1.25!important}.yst-tracking-tight{letter-spacing:-.025em!important}.yst-tracking-wide{letter-spacing:.025em!important}.yst-text-\[\#006499\]{--tw-text-opacity:1!important;color:rgb(0 100 153/var(--tw-text-opacity,1))!important}.yst-text-\[\#111827\]{--tw-text-opacity:1!important;color:rgb(17 24 39/var(--tw-text-opacity,1))!important}.yst-text-\[\#555\]{--tw-text-opacity:1!important;color:rgb(85 85 85/var(--tw-text-opacity,1))!important}.yst-text-amber-300{--tw-text-opacity:1!important;color:rgb(252 211 77/var(--tw-text-opacity,1))!important}.yst-text-amber-500{--tw-text-opacity:1!important;color:rgb(245 158 11/var(--tw-text-opacity,1))!important}.yst-text-amber-900{--tw-text-opacity:1!important;color:rgb(120 53 15/var(--tw-text-opacity,1))!important}.yst-text-black{--tw-text-opacity:1!important;color:rgb(0 0 0/var(--tw-text-opacity,1))!important}.yst-text-blue-500{--tw-text-opacity:1!important;color:rgb(59 130 246/var(--tw-text-opacity,1))!important}.yst-text-blue-800{--tw-text-opacity:1!important;color:rgb(30 64 175/var(--tw-text-opacity,1))!important}.yst-text-emerald-600{--tw-text-opacity:1!important;color:rgb(5 150 105/var(--tw-text-opacity,1))!important}.yst-text-gray-200{--tw-text-opacity:1!important;color:rgb(229 231 235/var(--tw-text-opacity,1))!important}.yst-text-gray-500{--tw-text-opacity:1!important;color:rgb(107 114 128/var(--tw-text-opacity,1))!important}.yst-text-green-400{--tw-text-opacity:1!important;color:rgb(74 222 128/var(--tw-text-opacity,1))!important}.yst-text-green-500{--tw-text-opacity:1!important;color:rgb(34 197 94/var(--tw-text-opacity,1))!important}.yst-text-green-600{--tw-text-opacity:1!important;color:rgb(22 163 74/var(--tw-text-opacity,1))!important}.yst-text-green-800{--tw-text-opacity:1!important;color:rgb(22 101 52/var(--tw-text-opacity,1))!important}.yst-text-indigo-600{--tw-text-opacity:1!important;color:rgb(79 70 229/var(--tw-text-opacity,1))!important}.yst-text-neutral-700{--tw-text-opacity:1!important;color:rgb(64 64 64/var(--tw-text-opacity,1))!important}.yst-text-primary-300{--tw-text-opacity:1!important;color:rgb(205 130 171/var(--tw-text-opacity,1))!important}.yst-text-primary-500{--tw-text-opacity:1!important;color:rgb(166 30 105/var(--tw-text-opacity,1))!important}.yst-text-red-500{--tw-text-opacity:1!important;color:rgb(239 68 68/var(--tw-text-opacity,1))!important}.yst-text-red-600{--tw-text-opacity:1!important;color:rgb(220 38 38/var(--tw-text-opacity,1))!important}.yst-text-red-800{--tw-text-opacity:1!important;color:rgb(153 27 27/var(--tw-text-opacity,1))!important}.yst-text-red-900{--tw-text-opacity:1!important;color:rgb(127 29 29/var(--tw-text-opacity,1))!important}.yst-text-slate-200{--tw-text-opacity:1!important;color:rgb(226 232 240/var(--tw-text-opacity,1))!important}.yst-text-slate-400{--tw-text-opacity:1!important;color:rgb(148 163 184/var(--tw-text-opacity,1))!important}.yst-text-slate-500{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity,1))!important}.yst-text-slate-600{--tw-text-opacity:1!important;color:rgb(71 85 105/var(--tw-text-opacity,1))!important}.yst-text-slate-700{--tw-text-opacity:1!important;color:rgb(51 65 85/var(--tw-text-opacity,1))!important}.yst-text-slate-800{--tw-text-opacity:1!important;color:rgb(30 41 59/var(--tw-text-opacity,1))!important}.yst-text-slate-900{--tw-text-opacity:1!important;color:rgb(15 23 42/var(--tw-text-opacity,1))!important}.yst-text-white{--tw-text-opacity:1!important;color:rgb(255 255 255/var(--tw-text-opacity,1))!important}.yst-text-woo-light{--tw-text-opacity:1!important;color:rgb(0 117 179/var(--tw-text-opacity,1))!important}.yst-text-yellow-500{--tw-text-opacity:1!important;color:rgb(234 179 8/var(--tw-text-opacity,1))!important}.yst-text-yellow-800{--tw-text-opacity:1!important;color:rgb(133 77 14/var(--tw-text-opacity,1))!important}.yst-text-yellow-900{--tw-text-opacity:1!important;color:rgb(113 63 18/var(--tw-text-opacity,1))!important}.yst-underline{-webkit-text-decoration-line:underline!important;text-decoration-line:underline!important}.yst-no-underline{-webkit-text-decoration-line:none!important;text-decoration-line:none!important}.yst-decoration-dotted{-webkit-text-decoration-style:dotted!important;text-decoration-style:dotted!important}.yst-underline-offset-4{text-underline-offset:4px!important}.yst-subpixel-antialiased{-webkit-font-smoothing:auto!important;-moz-osx-font-smoothing:auto!important}.yst-placeholder-slate-500::placeholder{--tw-placeholder-opacity:1!important;color:rgb(100 116 139/var(--tw-placeholder-opacity,1))!important}.yst-opacity-0{opacity:0!important}.yst-opacity-100{opacity:1!important}.yst-opacity-25{opacity:.25!important}.yst-opacity-50{opacity:.5!important}.yst-opacity-75{opacity:.75!important}.yst-shadow{--tw-shadow:0 1px 3px 0 #0000001a,0 1px 2px -1px #0000001a!important;--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)!important}.yst-shadow,.yst-shadow-2xl{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.yst-shadow-2xl{--tw-shadow:0 25px 50px -12px #00000040!important;--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color)!important}.yst-shadow-lg{--tw-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a!important;--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)!important}.yst-shadow-lg,.yst-shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.yst-shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a!important;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)!important}.yst-shadow-none{--tw-shadow:0 0 #0000!important;--tw-shadow-colored:0 0 #0000!important}.yst-shadow-none,.yst-shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.yst-shadow-sm{--tw-shadow:0 1px 2px 0 #0000000d!important;--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)!important}.yst-shadow-xl{--tw-shadow:0 20px 25px -5px #0000001a,0 8px 10px -6px #0000001a!important;--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color)!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.yst-shadow-amber-700\/30{--tw-shadow-color:#b453094d!important;--tw-shadow:var(--tw-shadow-colored)!important}.yst-outline-none{outline:2px solid #0000!important;outline-offset:2px!important}.yst-ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.yst-ring-black{--tw-ring-opacity:1!important;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity,1))!important}.yst-ring-gray-200{--tw-ring-opacity:1!important;--tw-ring-color:rgb(229 231 235/var(--tw-ring-opacity,1))!important}.yst-ring-opacity-5{--tw-ring-opacity:0.05!important}.yst-ring-offset-2{--tw-ring-offset-width:2px!important}.yst-ring-offset-primary-500{--tw-ring-offset-color:#a61e69!important}.yst-drop-shadow-md{--tw-drop-shadow:drop-shadow(0 4px 3px #00000012) drop-shadow(0 2px 2px #0000000f)!important}.yst-drop-shadow-md,.yst-drop-shadow-none{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.yst-drop-shadow-none{--tw-drop-shadow:drop-shadow(0 0 #0000)!important}.yst-grayscale{--tw-grayscale:grayscale(100%)!important}.yst-filter,.yst-grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.yst-transition{transition-duration:.15s!important;transition-property:color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-text-decoration-color!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-transition-\[width\]{transition-duration:.15s!important;transition-property:width!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-transition-all{transition-duration:.15s!important;transition-property:all!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-transition-colors{transition-duration:.15s!important;transition-property:color,background-color,border-color,fill,stroke,-webkit-text-decoration-color!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke!important;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,-webkit-text-decoration-color!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-transition-opacity{transition-duration:.15s!important;transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-transition-transform{transition-duration:.15s!important;transition-property:transform!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-delay-100{transition-delay:.1s!important}.yst-delay-200{transition-delay:.2s!important}.yst-delay-500{transition-delay:.5s!important}.yst-delay-\[900ms\]{transition-delay:.9s!important}.yst-duration-100{transition-duration:.1s!important}.yst-duration-1000{transition-duration:1s!important}.yst-duration-150{transition-duration:.15s!important}.yst-duration-200{transition-duration:.2s!important}.yst-duration-300{transition-duration:.3s!important}.yst-duration-500{transition-duration:.5s!important}.yst-duration-75{transition-duration:75ms!important}.yst-ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)!important}.yst-ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.yst-ease-linear{transition-timing-function:linear!important}.yst-ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)!important}.yst-\@container{container-type:inline-size!important}.marker\:yst-mr-0 ::marker{margin-right:0!important}.marker\:yst-mr-0::marker{margin-right:0!important}.first\:yst-rounded-t-md:first-child{border-top-left-radius:.375rem!important;border-top-right-radius:.375rem!important}.first\:yst-pt-0:first-child{padding-top:0!important}.last\:yst-me-0:last-child{margin-inline-end:0!important}.last\:yst-rounded-b-md:last-child{border-bottom-left-radius:.375rem!important;border-bottom-right-radius:.375rem!important}.last\:yst-border-0:last-child{border-width:0!important}.last\:yst-border-b-0:last-child{border-bottom-width:0!important}.last\:yst-pb-0:last-child{padding-bottom:0!important}.focus-within\:yst-border-primary-500:focus-within{--tw-border-opacity:1!important;border-color:rgb(166 30 105/var(--tw-border-opacity,1))!important}.focus-within\:yst-outline-none:focus-within{outline:2px solid #0000!important;outline-offset:2px!important}.focus-within\:yst-ring-1:focus-within{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.focus-within\:yst-ring-primary-500:focus-within{--tw-ring-opacity:1!important;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))!important}.hover\:yst-bg-\[\#f0f0f0\]:hover{--tw-bg-opacity:1!important;background-color:rgb(240 240 240/var(--tw-bg-opacity,1))!important}.hover\:yst-bg-gray-50:hover{--tw-bg-opacity:1!important;background-color:rgb(249 250 251/var(--tw-bg-opacity,1))!important}.hover\:yst-bg-primary-600:hover{--tw-bg-opacity:1!important;background-color:rgb(154 22 96/var(--tw-bg-opacity,1))!important}.hover\:yst-bg-white:hover{--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))!important}.hover\:yst-text-primary-500:hover{--tw-text-opacity:1!important;color:rgb(166 30 105/var(--tw-text-opacity,1))!important}.hover\:yst-text-slate-500:hover{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity,1))!important}.hover\:yst-text-slate-600:hover{--tw-text-opacity:1!important;color:rgb(71 85 105/var(--tw-text-opacity,1))!important}.hover\:yst-text-slate-800:hover{--tw-text-opacity:1!important;color:rgb(30 41 59/var(--tw-text-opacity,1))!important}.hover\:yst-text-slate-900:hover{--tw-text-opacity:1!important;color:rgb(15 23 42/var(--tw-text-opacity,1))!important}.hover\:yst-text-white:hover{--tw-text-opacity:1!important;color:rgb(255 255 255/var(--tw-text-opacity,1))!important}.focus\:yst-border-emerald-600:focus{--tw-border-opacity:1!important;border-color:rgb(5 150 105/var(--tw-border-opacity,1))!important}.focus\:yst-border-primary-500:focus{--tw-border-opacity:1!important;border-color:rgb(166 30 105/var(--tw-border-opacity,1))!important}.focus\:yst-border-red-500:focus{--tw-border-opacity:1!important;border-color:rgb(239 68 68/var(--tw-border-opacity,1))!important}.focus\:yst-bg-primary-600:focus{--tw-bg-opacity:1!important;background-color:rgb(154 22 96/var(--tw-bg-opacity,1))!important}.focus\:yst-text-primary-500:focus{--tw-text-opacity:1!important;color:rgb(166 30 105/var(--tw-text-opacity,1))!important}.focus\:yst-text-white:focus{--tw-text-opacity:1!important;color:rgb(255 255 255/var(--tw-text-opacity,1))!important}.focus\:yst-shadow-\[0_0_3px_rgba\(8\2c 74\2c 103\2c 0\.8\)\]:focus{--tw-shadow:0 0 3px #084a67cc!important;--tw-shadow-colored:0 0 3px var(--tw-shadow-color)!important;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.focus\:yst-outline-none:focus{outline:2px solid #0000!important;outline-offset:2px!important}.focus\:yst-outline:focus{outline-style:solid!important}.focus\:yst-outline-\[1px\]:focus{outline-width:1px!important}.focus\:-yst-outline-offset-1:focus{outline-offset:-1px!important}.focus\:yst-outline-\[color\:\#0066cd\]:focus{outline-color:#0066cd!important}.focus\:yst-ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important}.focus\:yst-ring-1:focus,.focus\:yst-ring-2:focus{box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)!important}.focus\:yst-ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)!important;--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color)!important}.focus\:yst-ring-inset:focus{--tw-ring-inset:inset!important}.focus\:yst-ring-emerald-600:focus{--tw-ring-opacity:1!important;--tw-ring-color:rgb(5 150 105/var(--tw-ring-opacity,1))!important}.focus\:yst-ring-primary-500:focus{--tw-ring-opacity:1!important;--tw-ring-color:rgb(166 30 105/var(--tw-ring-opacity,1))!important}.focus\:yst-ring-red-500:focus{--tw-ring-opacity:1!important;--tw-ring-color:rgb(239 68 68/var(--tw-ring-opacity,1))!important}.focus\:yst-ring-white:focus{--tw-ring-opacity:1!important;--tw-ring-color:rgb(255 255 255/var(--tw-ring-opacity,1))!important}.focus\:yst-ring-offset-0:focus{--tw-ring-offset-width:0px!important}.focus\:yst-ring-offset-2:focus{--tw-ring-offset-width:2px!important}.focus\:yst-ring-offset-primary-500:focus{--tw-ring-offset-color:#a61e69!important}.focus-visible\:yst-outline-none:focus-visible{outline:2px solid #0000!important;outline-offset:2px!important}.yst-group:first-child .group-first\:yst-pt-0{padding-top:0!important}.yst-group:last-child .group-last\:yst-mb-0{margin-bottom:0!important}.yst-group:last-child .group-last\:yst-border-none{border-style:none!important}.yst-group:last-child .group-last\:last\:yst-pb-0:last-child,.yst-group:last-child .group-last\:yst-pb-0{padding-bottom:0!important}.yst-group:hover .group-hover\:yst-translate-x-2{--tw-translate-x:0.5rem!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.yst-group:hover .group-hover\:yst-bg-primary-200{--tw-bg-opacity:1!important;background-color:rgb(224 179 204/var(--tw-bg-opacity,1))!important}.yst-group:hover .group-hover\:yst-bg-primary-500{--tw-bg-opacity:1!important;background-color:rgb(166 30 105/var(--tw-bg-opacity,1))!important}.yst-group:hover .group-hover\:yst-bg-slate-50{--tw-bg-opacity:1!important;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))!important}.yst-group:hover .group-hover\:yst-text-primary-800{--tw-text-opacity:1!important;color:rgb(131 8 78/var(--tw-text-opacity,1))!important}.yst-group:hover .group-hover\:yst-text-slate-500{--tw-text-opacity:1!important;color:rgb(100 116 139/var(--tw-text-opacity,1))!important}.yst-group:hover .group-hover\:yst-text-slate-800{--tw-text-opacity:1!important;color:rgb(30 41 59/var(--tw-text-opacity,1))!important}.yst-group:hover .group-hover\:yst-text-white{--tw-text-opacity:1!important;color:rgb(255 255 255/var(--tw-text-opacity,1))!important}.yst-group:hover .group-hover\:yst-underline{-webkit-text-decoration-line:underline!important;text-decoration-line:underline!important}@container (min-width: 28rem){.\@md\:yst-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))!important}.\@md\:yst-flex-row{flex-direction:row!important}}@container (min-width: 32rem){.\@lg\:yst-col-span-2{grid-column:span 2/span 2!important}.\@lg\:yst-pb-0{padding-bottom:0!important}.\@lg\:yst-pb-4{padding-bottom:1rem!important}.\@lg\:yst-pe-0{padding-inline-end:0!important}.\@lg\:yst-pe-4{padding-inline-end:1rem!important}.\@lg\:yst-ps-0{padding-inline-start:0!important}.\@lg\:yst-ps-4{padding-inline-start:1rem!important}.\@lg\:yst-pt-0{padding-top:0!important}.\@lg\:yst-pt-4{padding-top:1rem!important}}@container (min-width: 48rem){.\@3xl\:yst-col-span-1{grid-column:span 1/span 1!important}.\@3xl\:yst-col-span-2{grid-column:span 2/span 2!important}.\@3xl\:yst-min-w-0{min-width:0!important}.\@3xl\:yst-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))!important}.\@3xl\:yst-pb-0{padding-bottom:0!important}.\@3xl\:yst-pe-4{padding-inline-end:1rem!important}.\@3xl\:yst-ps-4{padding-inline-start:1rem!important}.\@3xl\:yst-pt-0{padding-top:0!important}.\@3xl\:first\:yst-ps-0:first-child{padding-inline-start:0!important}.\@3xl\:last\:yst-pe-0:last-child{padding-inline-end:0!important}}@media (max-width:784px){.max-\[784px\]\:yst-max-w-full{max-width:100%!important}}@media not all and (min-width:640px){.max-sm\:yst-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))!important}}@media (min-width:640px){.sm\:yst-end-16{inset-inline-end:4rem!important}.sm\:yst-mx-0{margin-left:0!important;margin-right:0!important}.sm\:yst-mb-0{margin-bottom:0!important}.sm\:yst-ml-3{margin-left:.75rem!important}.sm\:yst-ms-4{margin-inline-start:1rem!important}.sm\:yst-mt-0{margin-top:0!important}.sm\:yst-inline-block{display:inline-block!important}.sm\:yst-inline{display:inline!important}.sm\:yst-flex{display:flex!important}.sm\:yst-hidden{display:none!important}.sm\:yst-h-10{height:2.5rem!important}.sm\:yst-w-10{width:2.5rem!important}.sm\:yst-w-96{width:24rem!important}.sm\:yst-w-auto{width:auto!important}.sm\:yst-max-w-sm{max-width:24rem!important}.sm\:yst-shrink-0{flex-shrink:0!important}.sm\:yst-translate-y-0{--tw-translate-y:0px!important}.sm\:yst-scale-100,.sm\:yst-translate-y-0{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.sm\:yst-scale-100{--tw-scale-x:1!important;--tw-scale-y:1!important}.sm\:yst-scale-95{--tw-scale-x:.95!important;--tw-scale-y:.95!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.sm\:yst-columns-2{column-count:2!important}.sm\:yst-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))!important}.sm\:yst-flex-row{flex-direction:row!important}.sm\:yst-flex-row-reverse{flex-direction:row-reverse!important}.sm\:yst-items-start{align-items:flex-start!important}.sm\:yst-justify-end{justify-content:flex-end!important}.sm\:yst-space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0!important;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)))!important;margin-right:calc(.5rem*var(--tw-space-x-reverse))!important}.sm\:yst-px-0{padding-left:0!important;padding-right:0!important}.sm\:yst-text-left{text-align:left!important}.sm\:yst-text-start{text-align:start!important}.sm\:yst-text-sm{font-size:.8125rem!important}}@media (min-width:768px){.md\:yst-absolute{position:absolute!important}.md\:yst-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))!important}}@media (min-width:783px){.min-\[783px\]\:yst-block{display:block!important}.min-\[783px\]\:yst-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))!important}.min-\[783px\]\:yst-p-8{padding:2rem!important}}@media (min-width:1024px){.lg\:yst-col-span-2{grid-column:span 2/span 2!important}.lg\:yst-mt-0{margin-top:0!important}.lg\:yst-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))!important}.lg\:yst-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))!important}.lg\:yst-grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))!important}.lg\:yst-flex-row{flex-direction:row!important}.lg\:yst-gap-12{gap:3rem!important}.lg\:yst-py-\[155px\]{padding-bottom:155px!important;padding-top:155px!important}.lg\:yst-pt-0\.5{padding-top:.125rem!important}}@media (min-width:1280px){.xl\:yst-fixed{position:fixed!important}.xl\:yst-end-8{inset-inline-end:2rem!important}.xl\:yst-col-span-2{grid-column:span 2/span 2!important}.xl\:yst-mb-0{margin-bottom:0!important}.xl\:yst-mt-0{margin-top:0!important}.xl\:yst-w-\[16rem\]{width:16rem!important}.xl\:yst-max-w-3xl{max-width:48rem!important}.xl\:yst-max-w-\[16rem\]{max-width:16rem!important}.xl\:yst-max-w-\[256px\]{max-width:256px!important}.xl\:yst-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))!important}.xl\:yst-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))!important}.xl\:yst-grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))!important}.xl\:yst-flex-row{flex-direction:row!important}.xl\:yst-gap-12{gap:3rem!important}.xl\:yst-pe-\[17\.5rem\]{padding-inline-end:17.5rem!important}}@media (min-width:1536px){.\32xl\:yst-col-span-2{grid-column:span 2/span 2!important}.\32xl\:yst-mt-0{margin-top:0!important}.\32xl\:yst-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))!important}.\32xl\:yst-gap-12{gap:3rem!important}}.rtl\:yst-mr-2:where([dir=rtl],[dir=rtl] *){margin-right:.5rem!important}.rtl\:yst-rotate-180:where([dir=rtl],[dir=rtl] *){--tw-rotate:180deg!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.rtl\:yst-rotate-\[270deg\]:where([dir=rtl],[dir=rtl] *){--tw-rotate:270deg!important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.rtl\:yst-space-x-reverse:where([dir=rtl],[dir=rtl] *)>:not([hidden])~:not([hidden]){--tw-space-x-reverse:1!important}@media (min-width:640px){.sm\:rtl\:yst-space-x-reverse:where([dir=rtl],[dir=rtl] *)>:not([hidden])~:not([hidden]){--tw-space-x-reverse:1!important}}.\[\&\>\*\]\:odd\:yst-bg-white:nth-child(odd)>*{--tw-bg-opacity:1!important;background-color:rgb(255 255 255/var(--tw-bg-opacity,1))!important}.\[\&\>\*\]\:even\:yst-bg-slate-50:nth-child(2n)>*{--tw-bg-opacity:1!important;background-color:rgb(248 250 252/var(--tw-bg-opacity,1))!important} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/toggle-switch-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/toggle-switch-2711-rtl.css new file mode 100644 index 0000000..24fb5bb --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/toggle-switch-2711-rtl.css @@ -0,0 +1 @@ +.switch-light span span,.switch-toggle a{display:none}@media only screen{.switch-light,.switch-toggle{display:block;padding:0!important;position:relative}.switch-light:after,.switch-toggle:after{clear:both;content:"";display:table}.switch-light *,.switch-light :after,.switch-light :before,.switch-toggle *,.switch-toggle :after,.switch-toggle :before{box-sizing:border-box}.switch-light a,.switch-toggle a{display:block;transition:all .2s ease-out}.switch-light label,.switch-light-visual-label,.switch-light>span,.switch-toggle label,.switch-toggle>span{line-height:2;vertical-align:middle}.switch-light input{opacity:0;position:absolute;z-index:3}.switch-light input[type=checkbox].disabled,.switch-light input[type=checkbox].disabled:checked:before,.switch-light input[type=checkbox]:disabled,.switch-light input[type=checkbox]:disabled:checked:before{opacity:0}.switch-light input:checked~span a{left:0}.switch-light strong{font-weight:inherit}.switch-light>span{min-height:2em;padding:0;position:relative;text-align:right}.switch-light span span{display:block;float:right;position:relative;text-align:center;-webkit-user-select:none;user-select:none;width:50%;z-index:2}.switch-light a{display:block;height:100%;padding:0;position:absolute;left:50%;top:0;width:50%;z-index:1}.switch-toggle input{right:0;opacity:0;position:absolute}.switch-toggle input[type=radio].disabled,.switch-toggle input[type=radio].disabled:checked:before,.switch-toggle input[type=radio]:disabled,.switch-toggle input[type=radio]:disabled:checked:before{opacity:0}.switch-toggle input+label{float:right;margin:0;padding:0 .5em;text-align:center}.switch-toggle input:checked+label{position:relative;z-index:2}.switch-toggle a{height:100%;right:0;padding:0;position:absolute;top:0;width:10px;z-index:1}.switch-toggle .yoast-button-upsell{right:20px;position:relative}.switch-toggle label:nth-child(2):nth-last-child(4),.switch-toggle label:nth-child(2):nth-last-child(4)~a,.switch-toggle label:nth-child(2):nth-last-child(4)~label{width:50%}.switch-toggle label:nth-child(2):nth-last-child(4)~input:checked:nth-child(3)+label~a{right:50%}.switch-toggle label:nth-child(2):nth-last-child(6),.switch-toggle label:nth-child(2):nth-last-child(6)~a,.switch-toggle label:nth-child(2):nth-last-child(6)~label{width:33.33%}.switch-toggle label:nth-child(2):nth-last-child(6)~input:checked:nth-child(3)+label~a{right:33.33%}.switch-toggle label:nth-child(2):nth-last-child(6)~input:checked:nth-child(5)+label~a{right:66.66%}.switch-toggle label:nth-child(2):nth-last-child(8),.switch-toggle label:nth-child(2):nth-last-child(8)~a,.switch-toggle label:nth-child(2):nth-last-child(8)~label{width:25%}.switch-toggle label:nth-child(2):nth-last-child(8)~input:checked:nth-child(3)+label~a{right:25%}.switch-toggle label:nth-child(2):nth-last-child(8)~input:checked:nth-child(5)+label~a{right:50%}.switch-toggle label:nth-child(2):nth-last-child(8)~input:checked:nth-child(7)+label~a{right:75%}.switch-toggle label:nth-child(2):nth-last-child(10),.switch-toggle label:nth-child(2):nth-last-child(10)~a,.switch-toggle label:nth-child(2):nth-last-child(10)~label{width:20%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(3)+label~a{right:20%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(5)+label~a{right:40%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(7)+label~a{right:60%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(9)+label~a{right:80%}.switch-toggle label:nth-child(2):nth-last-child(12),.switch-toggle label:nth-child(2):nth-last-child(12)~a,.switch-toggle label:nth-child(2):nth-last-child(12)~label{width:16.6%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(3)+label~a{right:16.6%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(5)+label~a{right:33.2%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(7)+label~a{right:49.8%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(9)+label~a{right:66.4%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(11)+label~a{right:83%}.switch-candy a{box-shadow:0 1px 1px #0003,inset 0 1px 1px #ffffff73}}@media only screen and (-webkit-max-device-pixel-ratio:2) and (max-device-width:80em){.switch-light,.switch-toggle{-webkit-animation:webkitSiblingBugfix 1s infinite}}.fieldset-switch-toggle{width:400px}.fieldset-switch-toggle label{float:none}.fieldset-switch-toggle .yoast-button-upsell{background-color:green;height:16px;overflow:hidden;width:20px}@media only screen{.fieldset-switch-toggle legend{box-sizing:border-box;float:right;font-weight:600;line-height:2;margin:8px 0;min-width:200px;padding-left:16px;vertical-align:middle}.fieldset-switch-toggle .disabled-note{clear:both}.switch-container__has-help .switch-light-visual-label,.switch-container__has-help legend{float:right;min-width:0;padding-left:0}.switch-container__has-help .yoast_help.yoast-help-button{margin:8px 2px 0 0}.switch-light.switch-yoast-seo>span,.switch-toggle.switch-yoast-seo{background-color:#dcdcdc;border:1px solid #ccc;border-radius:.5em;box-shadow:inset 0 2px 4px #00000026;width:250px}.switch-light.switch-yoast-seo,.switch-toggle.switch-yoast-seo{clear:both;float:right}.switch-light.switch-yoast-seo>span{display:inline-block;overflow:visible}.switch-light.switch-yoast-seo a,.switch-toggle.switch-yoast-seo a{background:#a4286a;border:1px solid #b5b5b5;border-radius:.5em}.switch-light.switch-yoast-seo input.disabled+span a,.switch-light.switch-yoast-seo input.disabled:checked+span a,.switch-light.switch-yoast-seo input:disabled+span a,.switch-light.switch-yoast-seo input:disabled:checked+span a,.switch-toggle.switch-yoast-seo input.disabled+a,.switch-toggle.switch-yoast-seo input.disabled~a,.switch-toggle.switch-yoast-seo input:disabled+a,.switch-toggle.switch-yoast-seo input:disabled~a{background:#9b9b9b;border:0}.switch-light.switch-yoast-seo input:focus+label,.switch-light.switch-yoast-seo input:focus~span a,.switch-toggle.switch-yoast-seo input:focus+label,.switch-toggle.switch-yoast-seo input:focus~span a{outline:none}.switch-light.switch-yoast-seo input:focus~span a,.switch-toggle.switch-yoast-seo input:focus~a{border-color:#5b9dd9!important;box-shadow:0 0 2px #0073aacc!important}.switch-light.switch-yoast-seo input:checked~span a,.switch-toggle.switch-yoast-seo input:checked~span a{background:#a4286a;border:1px solid #b5b5b5}.switch-light.switch-yoast-seo input:checked~span span:first-child,.switch-light.switch-yoast-seo span span,.switch-toggle.switch-yoast-seo label{color:#333;font-weight:inherit;text-shadow:none}.switch-candy.switch-yoast-seo input:checked+label,.switch-candy.switch-yoast-seo input:checked~span span:nth-child(2),.switch-candy.switch-yoast-seo input~span span:first-child{color:#fff;text-shadow:none}.switch-candy.switch-yoast-seo input+label:after{content:"";display:block;height:100%;right:0;position:absolute;top:0;width:100%;z-index:3}.switch-candy.switch-yoast-seo input:checked+label:after{content:none}.switch-light.switch-yoast-seo-reverse input:checked~span a{right:0}.switch-light.switch-yoast-seo-reverse a{right:50%}.switch-light.switch-yoast-seo-reverse span span{float:left}.switch-toggle.switch-yoast-seo label,label.switch-light.switch-yoast-seo{cursor:pointer;margin-right:0}.switch-light.switch-yoast-seo input.disabled+span,.switch-light.switch-yoast-seo input:disabled+span,.switch-toggle.switch-yoast-seo input.disabled+label,.switch-toggle.switch-yoast-seo input:disabled+label{cursor:not-allowed}.switch-yoast-seo .switch-yoast-seo-jaws-a11y{display:block;height:1px;margin-bottom:-1px;overflow:hidden}.switch-light.switch-yoast-seo label code,.switch-toggle.switch-yoast-seo label code{background-color:inherit;vertical-align:top}.switch-light-visual-label{display:block;font-weight:600;line-height:2;margin:8px 0}.switch-light-visual-label__strong{font-weight:600}.switch-container{clear:both;margin:0 0 .8em}.switch-container.premium-upsell .clear{display:none}.switch-container.premium-upsell{align-items:end;clear:both;display:grid;grid-template-columns:280px 1fr;margin:0 0 .8em}.switch-container.premium-upsell .yoast-help-panel{width:520px}@media screen and (max-width:600px){.switch-container.premium-upsell{clear:both;display:grid;grid-template-columns:1fr;margin:0 0 .8em}.switch-container.premium-upsell .yoast-help-panel{width:unset}}.switch-container.premium-upsell .yoast-button{clear:both;margin-top:8px;width:-moz-fit-content;width:fit-content}.switch-container+.switch-container{margin-top:8px}.switch-container+p{margin:0 0 16px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/toggle-switch-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/toggle-switch-2711.css new file mode 100644 index 0000000..c215461 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/toggle-switch-2711.css @@ -0,0 +1 @@ +.switch-light span span,.switch-toggle a{display:none}@media only screen{.switch-light,.switch-toggle{display:block;padding:0!important;position:relative}.switch-light:after,.switch-toggle:after{clear:both;content:"";display:table}.switch-light *,.switch-light :after,.switch-light :before,.switch-toggle *,.switch-toggle :after,.switch-toggle :before{box-sizing:border-box}.switch-light a,.switch-toggle a{display:block;transition:all .2s ease-out}.switch-light label,.switch-light-visual-label,.switch-light>span,.switch-toggle label,.switch-toggle>span{line-height:2;vertical-align:middle}.switch-light input{opacity:0;position:absolute;z-index:3}.switch-light input[type=checkbox].disabled,.switch-light input[type=checkbox].disabled:checked:before,.switch-light input[type=checkbox]:disabled,.switch-light input[type=checkbox]:disabled:checked:before{opacity:0}.switch-light input:checked~span a{right:0}.switch-light strong{font-weight:inherit}.switch-light>span{min-height:2em;padding:0;position:relative;text-align:left}.switch-light span span{display:block;float:left;position:relative;text-align:center;-webkit-user-select:none;user-select:none;width:50%;z-index:2}.switch-light a{display:block;height:100%;padding:0;position:absolute;right:50%;top:0;width:50%;z-index:1}.switch-toggle input{left:0;opacity:0;position:absolute}.switch-toggle input[type=radio].disabled,.switch-toggle input[type=radio].disabled:checked:before,.switch-toggle input[type=radio]:disabled,.switch-toggle input[type=radio]:disabled:checked:before{opacity:0}.switch-toggle input+label{float:left;margin:0;padding:0 .5em;text-align:center}.switch-toggle input:checked+label{position:relative;z-index:2}.switch-toggle a{height:100%;left:0;padding:0;position:absolute;top:0;width:10px;z-index:1}.switch-toggle .yoast-button-upsell{left:20px;position:relative}.switch-toggle label:nth-child(2):nth-last-child(4),.switch-toggle label:nth-child(2):nth-last-child(4)~a,.switch-toggle label:nth-child(2):nth-last-child(4)~label{width:50%}.switch-toggle label:nth-child(2):nth-last-child(4)~input:checked:nth-child(3)+label~a{left:50%}.switch-toggle label:nth-child(2):nth-last-child(6),.switch-toggle label:nth-child(2):nth-last-child(6)~a,.switch-toggle label:nth-child(2):nth-last-child(6)~label{width:33.33%}.switch-toggle label:nth-child(2):nth-last-child(6)~input:checked:nth-child(3)+label~a{left:33.33%}.switch-toggle label:nth-child(2):nth-last-child(6)~input:checked:nth-child(5)+label~a{left:66.66%}.switch-toggle label:nth-child(2):nth-last-child(8),.switch-toggle label:nth-child(2):nth-last-child(8)~a,.switch-toggle label:nth-child(2):nth-last-child(8)~label{width:25%}.switch-toggle label:nth-child(2):nth-last-child(8)~input:checked:nth-child(3)+label~a{left:25%}.switch-toggle label:nth-child(2):nth-last-child(8)~input:checked:nth-child(5)+label~a{left:50%}.switch-toggle label:nth-child(2):nth-last-child(8)~input:checked:nth-child(7)+label~a{left:75%}.switch-toggle label:nth-child(2):nth-last-child(10),.switch-toggle label:nth-child(2):nth-last-child(10)~a,.switch-toggle label:nth-child(2):nth-last-child(10)~label{width:20%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(3)+label~a{left:20%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(5)+label~a{left:40%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(7)+label~a{left:60%}.switch-toggle label:nth-child(2):nth-last-child(10)~input:checked:nth-child(9)+label~a{left:80%}.switch-toggle label:nth-child(2):nth-last-child(12),.switch-toggle label:nth-child(2):nth-last-child(12)~a,.switch-toggle label:nth-child(2):nth-last-child(12)~label{width:16.6%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(3)+label~a{left:16.6%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(5)+label~a{left:33.2%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(7)+label~a{left:49.8%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(9)+label~a{left:66.4%}.switch-toggle label:nth-child(2):nth-last-child(12)~input:checked:nth-child(11)+label~a{left:83%}.switch-candy a{box-shadow:0 1px 1px #0003,inset 0 1px 1px #ffffff73}}@media only screen and (-webkit-max-device-pixel-ratio:2) and (max-device-width:80em){.switch-light,.switch-toggle{-webkit-animation:webkitSiblingBugfix 1s infinite}}.fieldset-switch-toggle{width:400px}.fieldset-switch-toggle label{float:none}.fieldset-switch-toggle .yoast-button-upsell{background-color:green;height:16px;overflow:hidden;width:20px}@media only screen{.fieldset-switch-toggle legend{box-sizing:border-box;float:left;font-weight:600;line-height:2;margin:8px 0;min-width:200px;padding-right:16px;vertical-align:middle}.fieldset-switch-toggle .disabled-note{clear:both}.switch-container__has-help .switch-light-visual-label,.switch-container__has-help legend{float:left;min-width:0;padding-right:0}.switch-container__has-help .yoast_help.yoast-help-button{margin:8px 0 0 2px}.switch-light.switch-yoast-seo>span,.switch-toggle.switch-yoast-seo{background-color:#dcdcdc;border:1px solid #ccc;border-radius:.5em;box-shadow:inset 0 2px 4px #00000026;width:250px}.switch-light.switch-yoast-seo,.switch-toggle.switch-yoast-seo{clear:both;float:left}.switch-light.switch-yoast-seo>span{display:inline-block;overflow:visible}.switch-light.switch-yoast-seo a,.switch-toggle.switch-yoast-seo a{background:#a4286a;border:1px solid #b5b5b5;border-radius:.5em}.switch-light.switch-yoast-seo input.disabled+span a,.switch-light.switch-yoast-seo input.disabled:checked+span a,.switch-light.switch-yoast-seo input:disabled+span a,.switch-light.switch-yoast-seo input:disabled:checked+span a,.switch-toggle.switch-yoast-seo input.disabled+a,.switch-toggle.switch-yoast-seo input.disabled~a,.switch-toggle.switch-yoast-seo input:disabled+a,.switch-toggle.switch-yoast-seo input:disabled~a{background:#9b9b9b;border:0}.switch-light.switch-yoast-seo input:focus+label,.switch-light.switch-yoast-seo input:focus~span a,.switch-toggle.switch-yoast-seo input:focus+label,.switch-toggle.switch-yoast-seo input:focus~span a{outline:none}.switch-light.switch-yoast-seo input:focus~span a,.switch-toggle.switch-yoast-seo input:focus~a{border-color:#5b9dd9!important;box-shadow:0 0 2px #0073aacc!important}.switch-light.switch-yoast-seo input:checked~span a,.switch-toggle.switch-yoast-seo input:checked~span a{background:#a4286a;border:1px solid #b5b5b5}.switch-light.switch-yoast-seo input:checked~span span:first-child,.switch-light.switch-yoast-seo span span,.switch-toggle.switch-yoast-seo label{color:#333;font-weight:inherit;text-shadow:none}.switch-candy.switch-yoast-seo input:checked+label,.switch-candy.switch-yoast-seo input:checked~span span:nth-child(2),.switch-candy.switch-yoast-seo input~span span:first-child{color:#fff;text-shadow:none}.switch-candy.switch-yoast-seo input+label:after{content:"";display:block;height:100%;left:0;position:absolute;top:0;width:100%;z-index:3}.switch-candy.switch-yoast-seo input:checked+label:after{content:none}.switch-light.switch-yoast-seo-reverse input:checked~span a{left:0}.switch-light.switch-yoast-seo-reverse a{left:50%}.switch-light.switch-yoast-seo-reverse span span{float:right}.switch-toggle.switch-yoast-seo label,label.switch-light.switch-yoast-seo{cursor:pointer;margin-left:0}.switch-light.switch-yoast-seo input.disabled+span,.switch-light.switch-yoast-seo input:disabled+span,.switch-toggle.switch-yoast-seo input.disabled+label,.switch-toggle.switch-yoast-seo input:disabled+label{cursor:not-allowed}.switch-yoast-seo .switch-yoast-seo-jaws-a11y{display:block;height:1px;margin-bottom:-1px;overflow:hidden}.switch-light.switch-yoast-seo label code,.switch-toggle.switch-yoast-seo label code{background-color:inherit;vertical-align:top}.switch-light-visual-label{display:block;font-weight:600;line-height:2;margin:8px 0}.switch-light-visual-label__strong{font-weight:600}.switch-container{clear:both;margin:0 0 .8em}.switch-container.premium-upsell .clear{display:none}.switch-container.premium-upsell{align-items:end;clear:both;display:grid;grid-template-columns:280px 1fr;margin:0 0 .8em}.switch-container.premium-upsell .yoast-help-panel{width:520px}@media screen and (max-width:600px){.switch-container.premium-upsell{clear:both;display:grid;grid-template-columns:1fr;margin:0 0 .8em}.switch-container.premium-upsell .yoast-help-panel{width:unset}}.switch-container.premium-upsell .yoast-button{clear:both;margin-top:8px;width:-moz-fit-content;width:fit-content}.switch-container+.switch-container{margin-top:8px}.switch-container+p{margin:0 0 16px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/tooltips-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/tooltips-2711-rtl.css new file mode 100644 index 0000000..e439bdb --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/tooltips-2711-rtl.css @@ -0,0 +1 @@ +.yoast-tooltip{position:relative}button.yoast-tooltip{overflow:visible}.yoast-tooltip:after{background:#000c;border-radius:3px;color:#fff;display:none;font:normal normal 11px/1.45454545 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;letter-spacing:normal;opacity:0;padding:6px 8px 5px;position:absolute;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;white-space:pre;z-index:1000000;word-wrap:break-word;content:attr(aria-label);pointer-events:none;-webkit-font-smoothing:subpixel-antialiased}.yoast-tooltip-alt:after{content:attr(data-label)}.yoast-tooltip:before{border:5px solid #0000;color:#000c;content:"\00a0";display:none;height:0;opacity:0;pointer-events:none;position:absolute;width:0;z-index:1000001}@keyframes yoast-tooltip-appear{0%{opacity:0}to{opacity:1}}.yoast-tooltip:active:after,.yoast-tooltip:active:before,.yoast-tooltip:focus:after,.yoast-tooltip:focus:before,.yoast-tooltip:hover:after,.yoast-tooltip:hover:before{animation-duration:.1s;animation-fill-mode:forwards;animation-name:yoast-tooltip-appear;animation-timing-function:ease-in;display:inline-block;text-decoration:none}.yoast-tooltip-no-delay:active:after,.yoast-tooltip-no-delay:active:before,.yoast-tooltip-no-delay:focus:after,.yoast-tooltip-no-delay:focus:before,.yoast-tooltip-no-delay:hover:after,.yoast-tooltip-no-delay:hover:before{animation:none;opacity:1}.yoast-tooltip-multiline:active:after,.yoast-tooltip-multiline:focus:after,.yoast-tooltip-multiline:hover:after{display:table-cell}.yoast-tooltip-s:after,.yoast-tooltip-se:after,.yoast-tooltip-sw:after{margin-top:5px;left:50%;top:100%}.yoast-tooltip-s:before,.yoast-tooltip-se:before,.yoast-tooltip-sw:before{border-bottom-color:#000c;bottom:-5px;margin-left:-5px;left:50%;top:auto}.yoast-tooltip-se:after{right:50%;margin-right:-15px;left:auto}.yoast-tooltip-sw:after{margin-left:-15px}.yoast-tooltip-n:after,.yoast-tooltip-ne:after,.yoast-tooltip-nw:after{bottom:100%;margin-bottom:5px;left:50%}.yoast-tooltip-n:before,.yoast-tooltip-ne:before,.yoast-tooltip-nw:before{border-top-color:#000c;bottom:auto;margin-left:-5px;left:50%;top:-5px}.yoast-tooltip-ne:after{right:50%;margin-right:-15px;left:auto}.yoast-tooltip-nw:after{margin-left:-15px}.yoast-tooltip-n:after,.yoast-tooltip-s:after{transform:translateX(-50%)}.yoast-tooltip-w:after{bottom:50%;margin-left:5px;left:100%;transform:translateY(50%)}.yoast-tooltip-w:before{border-right-color:#000c;bottom:50%;right:-5px;margin-top:-5px;top:50%}.yoast-tooltip-e:after{bottom:50%;right:100%;margin-right:5px;transform:translateY(50%)}.yoast-tooltip-e:before{border-left-color:#000c;bottom:50%;margin-top:-5px;left:-5px;top:50%}.yoast-tooltip-multiline:after{width:210px}@supports (width:max-content){.yoast-tooltip-multiline:after{width:max-content}}.yoast-tooltip-multiline:after{border-collapse:initial;max-width:210px;white-space:pre-line;word-wrap:normal;word-break:break-word}.yoast-tooltip-multiline.yoast-tooltip-n:after,.yoast-tooltip-multiline.yoast-tooltip-s:after{right:50%;left:auto;transform:translateX(50%)}.yoast-tooltip-multiline.yoast-tooltip-e:after,.yoast-tooltip-multiline.yoast-tooltip-w:after{left:100%}@media screen and (min-width:0\0){.yoast-tooltip-multiline:after{width:210px}}.yoast-tooltip-sticky:after,.yoast-tooltip-sticky:before{display:inline-block}.yoast-tooltip-sticky.yoast-tooltip-multiline:after{display:table-cell}@media only screen and (min-device-pixel-ratio:2),only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.yoast-tooltip-w:after{margin-left:4.5px}}.yoast-tooltip.yoast-tooltip-hidden:after,.yoast-tooltip.yoast-tooltip-hidden:before{display:none} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/tooltips-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/tooltips-2711.css new file mode 100644 index 0000000..9f8b827 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/tooltips-2711.css @@ -0,0 +1 @@ +.yoast-tooltip{position:relative}button.yoast-tooltip{overflow:visible}.yoast-tooltip:after{background:#000c;border-radius:3px;color:#fff;display:none;font:normal normal 11px/1.45454545 Helvetica,arial,nimbussansl,liberationsans,freesans,clean,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;letter-spacing:normal;opacity:0;padding:6px 8px 5px;position:absolute;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;white-space:pre;z-index:1000000;word-wrap:break-word;content:attr(aria-label);pointer-events:none;-webkit-font-smoothing:subpixel-antialiased}.yoast-tooltip-alt:after{content:attr(data-label)}.yoast-tooltip:before{border:5px solid #0000;color:#000c;content:"\00a0";display:none;height:0;opacity:0;pointer-events:none;position:absolute;width:0;z-index:1000001}@keyframes yoast-tooltip-appear{0%{opacity:0}to{opacity:1}}.yoast-tooltip:active:after,.yoast-tooltip:active:before,.yoast-tooltip:focus:after,.yoast-tooltip:focus:before,.yoast-tooltip:hover:after,.yoast-tooltip:hover:before{animation-duration:.1s;animation-fill-mode:forwards;animation-name:yoast-tooltip-appear;animation-timing-function:ease-in;display:inline-block;text-decoration:none}.yoast-tooltip-no-delay:active:after,.yoast-tooltip-no-delay:active:before,.yoast-tooltip-no-delay:focus:after,.yoast-tooltip-no-delay:focus:before,.yoast-tooltip-no-delay:hover:after,.yoast-tooltip-no-delay:hover:before{animation:none;opacity:1}.yoast-tooltip-multiline:active:after,.yoast-tooltip-multiline:focus:after,.yoast-tooltip-multiline:hover:after{display:table-cell}.yoast-tooltip-s:after,.yoast-tooltip-se:after,.yoast-tooltip-sw:after{margin-top:5px;right:50%;top:100%}.yoast-tooltip-s:before,.yoast-tooltip-se:before,.yoast-tooltip-sw:before{border-bottom-color:#000c;bottom:-5px;margin-right:-5px;right:50%;top:auto}.yoast-tooltip-se:after{left:50%;margin-left:-15px;right:auto}.yoast-tooltip-sw:after{margin-right:-15px}.yoast-tooltip-n:after,.yoast-tooltip-ne:after,.yoast-tooltip-nw:after{bottom:100%;margin-bottom:5px;right:50%}.yoast-tooltip-n:before,.yoast-tooltip-ne:before,.yoast-tooltip-nw:before{border-top-color:#000c;bottom:auto;margin-right:-5px;right:50%;top:-5px}.yoast-tooltip-ne:after{left:50%;margin-left:-15px;right:auto}.yoast-tooltip-nw:after{margin-right:-15px}.yoast-tooltip-n:after,.yoast-tooltip-s:after{transform:translateX(50%)}.yoast-tooltip-w:after{bottom:50%;margin-right:5px;right:100%;transform:translateY(50%)}.yoast-tooltip-w:before{border-left-color:#000c;bottom:50%;left:-5px;margin-top:-5px;top:50%}.yoast-tooltip-e:after{bottom:50%;left:100%;margin-left:5px;transform:translateY(50%)}.yoast-tooltip-e:before{border-right-color:#000c;bottom:50%;margin-top:-5px;right:-5px;top:50%}.yoast-tooltip-multiline:after{width:210px}@supports (width:max-content){.yoast-tooltip-multiline:after{width:max-content}}.yoast-tooltip-multiline:after{border-collapse:initial;max-width:210px;white-space:pre-line;word-wrap:normal;word-break:break-word}.yoast-tooltip-multiline.yoast-tooltip-n:after,.yoast-tooltip-multiline.yoast-tooltip-s:after{left:50%;right:auto;transform:translateX(-50%)}.yoast-tooltip-multiline.yoast-tooltip-e:after,.yoast-tooltip-multiline.yoast-tooltip-w:after{right:100%}@media screen and (min-width:0\0){.yoast-tooltip-multiline:after{width:210px}}.yoast-tooltip-sticky:after,.yoast-tooltip-sticky:before{display:inline-block}.yoast-tooltip-sticky.yoast-tooltip-multiline:after{display:table-cell}@media only screen and (min-device-pixel-ratio:2),only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.yoast-tooltip-w:after{margin-right:4.5px}}.yoast-tooltip.yoast-tooltip-hidden:after,.yoast-tooltip.yoast-tooltip-hidden:before{display:none} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/workouts-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/workouts-2711-rtl.css new file mode 100644 index 0000000..9a76491 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/workouts-2711-rtl.css @@ -0,0 +1 @@ +#wpseo-workouts-container-free h1,#wpseo-workouts-container-free h3{color:#a4286a;font-weight:500}#wpseo-workouts-container-free h3{font-size:18px;line-height:24px}.card.card-small h3{min-height:48px}#wpseo-workouts-container-free h2{font-size:12px;text-transform:uppercase}#wpseo-workouts-container-free #workouts-page-description{font-size:16px;max-width:600px}.workflow tr.cornerstone{font-weight:700}#wpseo-workouts-container-free hr{margin-bottom:24px;margin-top:8px}#wpseo-workouts-container-free progress{margin:16px 0 8px}#wpseo-workouts-container-free div.card{border-color:#0003;border-radius:8px;border-width:1px;box-shadow:0 1px 3px 0 #0000001a,0 1px 2px 0 #0000000f;max-width:720px;padding:24px;width:100%}#wpseo-workouts-container-free div.card>h2{margin:0}#wpseo-workouts-container-free div.card.card-small{display:flex;flex-direction:column;max-width:320px}#wpseo-workouts-container-free div.card.card-small svg{height:146px;width:204px}#wpseo-workouts-container-free div.card.card-small svg *{height:100%;width:100%}#wpseo-workouts-container-free div.card.card-small>span{margin-top:auto}#wpseo-workouts-container-free table button{margin:2px}.workflow{counter-reset:line-number;list-style:none;margin-right:48px}.workflow li li{counter-increment:none;line-height:19px;margin-bottom:8px}.workflow li.step{counter-increment:line-number;padding-bottom:16px;position:relative}.workflow .yoast-button.yoast-button--finished{opacity:.5}.workflow .finish-button-section .finish-button-saved{color:#6ea029;grid-column-end:3;grid-column-start:3;margin-right:10px;position:relative}.workflow .finish-button-section .finish-button-saved:before{background:var(--yoast-svg-icon-check);background-size:18px 13px;content:"";height:13px;right:-18px;position:absolute;top:2px;width:18px}.workflow li.step>.yoast-button.orphaned-summary{display:initial;margin:0}.yoast .yoast-button--arrow-down{display:inline-block;flex-shrink:0;height:16px;margin:0 6px 0 -2px;width:16px}.workflow>li.step:before{background:#a4286a;bottom:-20px;content:"";right:-33px;position:absolute;top:0;width:2px}.workflow .extra-list-content{position:relative}.workflow>li.step:last-of-type:before{display:none}.workflow>li.step:after{background:#fff;border:2px solid #a4286a;border-radius:100%;color:#a4286a;content:counter(line-number);display:block;height:28px;right:-48px;line-height:28px;position:absolute;text-align:center;top:-8px;width:28px}.workflow li.step.finished:after{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m5 13 4 4L19 7'/%3E%3C/svg%3E") #a4286a;background-position:50%;background-repeat:no-repeat;background-size:20px 20px;content:""}.workflow li.step.finished.faded p,.workflow li.step.finished.faded table{opacity:.5}.workflow li.step img{max-width:100%}.workflow li.step img.workflow__image{max-height:100px;max-width:100px}.workflow li.step.yoast-fadeout:before{background:linear-gradient(-180deg,#a4286a,#fff 75%);display:block}.workflow li.step #react-select-2-input{box-shadow:none!important}.workflows__index{display:flex;flex-wrap:wrap;gap:16px}.workflows__index .yoast-button{width:100%}table.yoast_help.yoast_link_suggestions thead td{padding:16px 8px}table.yoast_help.yoast_link_suggestions td{vertical-align:middle}table.yoast_help th.divider{text-align:center}.workflow table.yoast_help td{vertical-align:middle}.workflow table.yoast_help.yoast_link_suggestions td div{display:inline-block}.workflow table.yoast_help.yoast_link_suggestions td strong{display:inline-block;margin-left:8px}.components-modal__header{height:72px;padding:0 24px}.components-modal__header .components-modal__header-heading{color:#a4286a;font-size:20px;font-weight:400;line-height:1.2;margin:0}.components-modal__header .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:20px;margin-left:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:20px}.components-modal__content{padding:0 24px 24px}.components-modal__content input[type=text]{max-width:400px;width:100%}.components-modal__frame.yoast__workout{max-width:720px}.yoast__redirect-suggestions{line-height:2}.components-modal__screen-overlay{animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards;background-color:#00000059;bottom:0;right:0;position:fixed;left:0;top:0;z-index:100000}@media (prefers-reduced-motion:reduce){.components-modal__screen-overlay{animation-delay:0s;animation-duration:1ms}}.components-modal__frame{background:#fff;border-radius:2px;bottom:0;box-shadow:0 10px 10px #00000040;box-sizing:border-box;right:0;margin:0;overflow:auto;position:absolute;left:0;top:0}@media (min-width:600px){.components-modal__frame{animation:components-modal__appear-animation .1s ease-out;animation-fill-mode:forwards;bottom:auto;right:50%;max-height:90%;max-width:calc(100% - 32px);min-width:360px;left:auto;top:50%;transform:translate(50%,-50%)}}@media (min-width:600px) and (prefers-reduced-motion:reduce){.components-modal__frame{animation-delay:0s;animation-duration:1ms}}@keyframes components-modal__appear-animation{0%{margin-top:32px}to{margin-top:0}}.components-modal__header{align-items:center;background:#fff;border-bottom:1px solid #ddd;box-sizing:border-box;display:flex;flex-direction:row;height:60px;justify-content:space-between;margin:0 -32px 24px;padding:0 32px;position:relative;position:sticky;top:0;z-index:10}@supports (-ms-ime-align:auto){.components-modal__header{position:fixed;width:100%}}.components-modal__header .components-modal__header-heading{font-size:1rem;font-weight:600}.components-modal__header h1{line-height:1;margin:0}.components-modal__header .components-button{right:8px;position:relative}.components-modal__header-heading-container{align-items:center;display:flex;flex-direction:row;flex-grow:1;justify-content:left}.components-modal__header-icon-container{display:inline-block}.components-modal__header-icon-container svg{max-height:36px;max-width:36px;padding:8px}.components-modal__content{box-sizing:border-box;height:100%;padding:0 32px 24px}@supports (-ms-ime-align:auto){.components-modal__content{padding-top:60px}}.workflow li.step h4{font-size:14px;font-weight:600;margin:24px 0 0}.workflow .yoast-social-profiles-input-fields{margin:10px 0 20px}.workflow .tracking-radiobuttons{line-height:19px;margin:0 0 20px}.workflow .yoast-tracking{list-style-position:inside;list-style-type:disc;padding:inherit}.yoast-list--usp{margin-bottom:16px;padding-right:24px}.yoast-list--usp li{margin-bottom:16px;position:relative}.yoast-list--usp li:before{background:var(--yoast-svg-icon-check);background-size:18px 13px;content:"";height:13px;right:-24px;position:absolute;top:3px;width:18px}.workout-card-content-flex{display:flex}.card.card-small .yoast-button-upsell{box-shadow:inset 0 -2px 0 #0003;filter:none;font-family:inherit;min-height:40px}.card.card-small button{box-shadow:inset 0 -2px 0 #0000004d;filter:none;min-height:40px}.card.card-small button.yoast-button--secondary{box-shadow:inset 0 -2px 0 #0000001a}.workout-card-content-flex ul{margin-left:8px}.workout-card-content-flex img{max-width:120px}.workout-card-upsell-button{opacity:1}#wpseo-workouts-container-free div.card.card-small.card-disabled{background-color:#ffffff80}#wpseo-workouts-container-free div.card.card-small.card-disabled .workout-card-content-flex,#wpseo-workouts-container-free div.card.card-small.card-disabled .workout-card-progress,#wpseo-workouts-container-free div.card.card-small.card-disabled h2,#wpseo-workouts-container-free div.card.card-small.card-disabled h3{opacity:.5}.workflow__grid{display:grid;gap:8px;grid-template-columns:auto 100px}.workflow__grid>div:last-of-type{display:flex;flex-wrap:wrap;justify-content:flex-end}@media screen and (max-width:768px){#wpseo-workouts-container-free #workouts-page-description{max-width:320px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/workouts-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/workouts-2711.css new file mode 100644 index 0000000..a00c8d1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/workouts-2711.css @@ -0,0 +1 @@ +#wpseo-workouts-container-free h1,#wpseo-workouts-container-free h3{color:#a4286a;font-weight:500}#wpseo-workouts-container-free h3{font-size:18px;line-height:24px}.card.card-small h3{min-height:48px}#wpseo-workouts-container-free h2{font-size:12px;text-transform:uppercase}#wpseo-workouts-container-free #workouts-page-description{font-size:16px;max-width:600px}.workflow tr.cornerstone{font-weight:700}#wpseo-workouts-container-free hr{margin-bottom:24px;margin-top:8px}#wpseo-workouts-container-free progress{margin:16px 0 8px}#wpseo-workouts-container-free div.card{border-color:#0003;border-radius:8px;border-width:1px;box-shadow:0 1px 3px 0 #0000001a,0 1px 2px 0 #0000000f;max-width:720px;padding:24px;width:100%}#wpseo-workouts-container-free div.card>h2{margin:0}#wpseo-workouts-container-free div.card.card-small{display:flex;flex-direction:column;max-width:320px}#wpseo-workouts-container-free div.card.card-small svg{height:146px;width:204px}#wpseo-workouts-container-free div.card.card-small svg *{height:100%;width:100%}#wpseo-workouts-container-free div.card.card-small>span{margin-top:auto}#wpseo-workouts-container-free table button{margin:2px}.workflow{counter-reset:line-number;list-style:none;margin-left:48px}.workflow li li{counter-increment:none;line-height:19px;margin-bottom:8px}.workflow li.step{counter-increment:line-number;padding-bottom:16px;position:relative}.workflow .yoast-button.yoast-button--finished{opacity:.5}.workflow .finish-button-section .finish-button-saved{color:#6ea029;grid-column-end:3;grid-column-start:3;margin-left:10px;position:relative}.workflow .finish-button-section .finish-button-saved:before{background:var(--yoast-svg-icon-check);background-size:18px 13px;content:"";height:13px;left:-18px;position:absolute;top:2px;width:18px}.workflow li.step>.yoast-button.orphaned-summary{display:initial;margin:0}.yoast .yoast-button--arrow-down{display:inline-block;flex-shrink:0;height:16px;margin:0 -2px 0 6px;width:16px}.workflow>li.step:before{background:#a4286a;bottom:-20px;content:"";left:-33px;position:absolute;top:0;width:2px}.workflow .extra-list-content{position:relative}.workflow>li.step:last-of-type:before{display:none}.workflow>li.step:after{background:#fff;border:2px solid #a4286a;border-radius:100%;color:#a4286a;content:counter(line-number);display:block;height:28px;left:-48px;line-height:28px;position:absolute;text-align:center;top:-8px;width:28px}.workflow li.step.finished:after{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' aria-hidden='true'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m5 13 4 4L19 7'/%3E%3C/svg%3E") #a4286a;background-position:50%;background-repeat:no-repeat;background-size:20px 20px;content:""}.workflow li.step.finished.faded p,.workflow li.step.finished.faded table{opacity:.5}.workflow li.step img{max-width:100%}.workflow li.step img.workflow__image{max-height:100px;max-width:100px}.workflow li.step.yoast-fadeout:before{background:linear-gradient(180deg,#a4286a,#fff 75%);display:block}.workflow li.step #react-select-2-input{box-shadow:none!important}.workflows__index{display:flex;flex-wrap:wrap;gap:16px}.workflows__index .yoast-button{width:100%}table.yoast_help.yoast_link_suggestions thead td{padding:16px 8px}table.yoast_help.yoast_link_suggestions td{vertical-align:middle}table.yoast_help th.divider{text-align:center}.workflow table.yoast_help td{vertical-align:middle}.workflow table.yoast_help.yoast_link_suggestions td div{display:inline-block}.workflow table.yoast_help.yoast_link_suggestions td strong{display:inline-block;margin-right:8px}.components-modal__header{height:72px;padding:0 24px}.components-modal__header .components-modal__header-heading{color:#a4286a;font-size:20px;font-weight:400;line-height:1.2;margin:0}.components-modal__header .yoast-icon{background-color:var(--yoast-color-primary);display:inline-block;height:20px;margin-right:8px;mask-image:var(--yoast-svg-icon-yoast);-webkit-mask-image:var(--yoast-svg-icon-yoast);mask-size:100% 100%;-webkit-mask-size:100% 100%;width:20px}.components-modal__content{padding:0 24px 24px}.components-modal__content input[type=text]{max-width:400px;width:100%}.components-modal__frame.yoast__workout{max-width:720px}.yoast__redirect-suggestions{line-height:2}.components-modal__screen-overlay{animation:edit-post__fade-in-animation .2s ease-out 0s;animation-fill-mode:forwards;background-color:#00000059;bottom:0;left:0;position:fixed;right:0;top:0;z-index:100000}@media (prefers-reduced-motion:reduce){.components-modal__screen-overlay{animation-delay:0s;animation-duration:1ms}}.components-modal__frame{background:#fff;border-radius:2px;bottom:0;box-shadow:0 10px 10px #00000040;box-sizing:border-box;left:0;margin:0;overflow:auto;position:absolute;right:0;top:0}@media (min-width:600px){.components-modal__frame{animation:components-modal__appear-animation .1s ease-out;animation-fill-mode:forwards;bottom:auto;left:50%;max-height:90%;max-width:calc(100% - 32px);min-width:360px;right:auto;top:50%;transform:translate(-50%,-50%)}}@media (min-width:600px) and (prefers-reduced-motion:reduce){.components-modal__frame{animation-delay:0s;animation-duration:1ms}}@keyframes components-modal__appear-animation{0%{margin-top:32px}to{margin-top:0}}.components-modal__header{align-items:center;background:#fff;border-bottom:1px solid #ddd;box-sizing:border-box;display:flex;flex-direction:row;height:60px;justify-content:space-between;margin:0 -32px 24px;padding:0 32px;position:relative;position:sticky;top:0;z-index:10}@supports (-ms-ime-align:auto){.components-modal__header{position:fixed;width:100%}}.components-modal__header .components-modal__header-heading{font-size:1rem;font-weight:600}.components-modal__header h1{line-height:1;margin:0}.components-modal__header .components-button{left:8px;position:relative}.components-modal__header-heading-container{align-items:center;display:flex;flex-direction:row;flex-grow:1;justify-content:left}.components-modal__header-icon-container{display:inline-block}.components-modal__header-icon-container svg{max-height:36px;max-width:36px;padding:8px}.components-modal__content{box-sizing:border-box;height:100%;padding:0 32px 24px}@supports (-ms-ime-align:auto){.components-modal__content{padding-top:60px}}.workflow li.step h4{font-size:14px;font-weight:600;margin:24px 0 0}.workflow .yoast-social-profiles-input-fields{margin:10px 0 20px}.workflow .tracking-radiobuttons{line-height:19px;margin:0 0 20px}.workflow .yoast-tracking{list-style-position:inside;list-style-type:disc;padding:inherit}.yoast-list--usp{margin-bottom:16px;padding-left:24px}.yoast-list--usp li{margin-bottom:16px;position:relative}.yoast-list--usp li:before{background:var(--yoast-svg-icon-check);background-size:18px 13px;content:"";height:13px;left:-24px;position:absolute;top:3px;width:18px}.workout-card-content-flex{display:flex}.card.card-small .yoast-button-upsell{box-shadow:inset 0 -2px 0 #0003;filter:none;font-family:inherit;min-height:40px}.card.card-small button{box-shadow:inset 0 -2px 0 #0000004d;filter:none;min-height:40px}.card.card-small button.yoast-button--secondary{box-shadow:inset 0 -2px 0 #0000001a}.workout-card-content-flex ul{margin-right:8px}.workout-card-content-flex img{max-width:120px}.workout-card-upsell-button{opacity:1}#wpseo-workouts-container-free div.card.card-small.card-disabled{background-color:#ffffff80}#wpseo-workouts-container-free div.card.card-small.card-disabled .workout-card-content-flex,#wpseo-workouts-container-free div.card.card-small.card-disabled .workout-card-progress,#wpseo-workouts-container-free div.card.card-small.card-disabled h2,#wpseo-workouts-container-free div.card.card-small.card-disabled h3{opacity:.5}.workflow__grid{display:grid;gap:8px;grid-template-columns:auto 100px}.workflow__grid>div:last-of-type{display:flex;flex-wrap:wrap;justify-content:flex-end}@media screen and (max-width:768px){#wpseo-workouts-container-free #workouts-page-description{max-width:320px}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/wpseo-dismissible-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/wpseo-dismissible-2711-rtl.css new file mode 100644 index 0000000..564d97e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/wpseo-dismissible-2711-rtl.css @@ -0,0 +1 @@ +.yoast-notice-dismiss:before{background:none;color:#b4b9be;content:"\f153";display:block!important;font:normal 16px/1 dashicons;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased!important;speak:none}.yoast-notice-dismiss{background:none;border:none;color:#b4b9be;cursor:pointer;margin:0;padding:9px;position:absolute;left:1px;top:0}.yoast-notice-dismiss:before{right:0;line-height:20px;position:relative;top:0}.yoast-notice-dismiss:active:before,.yoast-notice-dismiss:focus:before,.yoast-notice-dismiss:hover:before{color:#c00}.yoast-notice-dismiss:focus{box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc;color:#c00;outline:none}.yoast-notice.is-dismissible{position:relative}.yoast-notice-dismiss{text-decoration:none} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/wpseo-dismissible-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/wpseo-dismissible-2711.css new file mode 100644 index 0000000..8c07616 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/wpseo-dismissible-2711.css @@ -0,0 +1 @@ +.yoast-notice-dismiss:before{background:none;color:#b4b9be;content:"\f153";display:block!important;font:normal 16px/1 dashicons;height:20px;text-align:center;width:20px;-webkit-font-smoothing:antialiased!important;speak:none}.yoast-notice-dismiss{background:none;border:none;color:#b4b9be;cursor:pointer;margin:0;padding:9px;position:absolute;right:1px;top:0}.yoast-notice-dismiss:before{left:0;line-height:20px;position:relative;top:0}.yoast-notice-dismiss:active:before,.yoast-notice-dismiss:focus:before,.yoast-notice-dismiss:hover:before{color:#c00}.yoast-notice-dismiss:focus{box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px #1e8cbecc;color:#c00;outline:none}.yoast-notice.is-dismissible{position:relative}.yoast-notice-dismiss{text-decoration:none} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/yst_plugin_tools-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/yst_plugin_tools-2711-rtl.css new file mode 100644 index 0000000..ebc4706 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/yst_plugin_tools-2711-rtl.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.wpseo_content_wrapper{display:table;table-layout:fixed;width:100%}.wpseo_content_cell{display:table-cell;height:500px;margin:0;padding:0;vertical-align:top}#wpseo_content_top{width:100%}tr.yst_row{margin:5px 0 0;padding:5px 0 0}#sidebar-container{padding-right:20px;width:256px}tr.yst_row.even{background-color:#f6f6f6}.wpseo_content_wrapper label.select,.wpseo_content_wrapper label.textinput{float:right;margin:5px 0;width:200px;word-wrap:break-word}.wpseo_content_wrapper label.select.error,.wpseo_content_wrapper label.textinput.error{color:#dc3232;font-weight:700}.wpseo_content_wrapper .yoast-inline-label{display:inline-block;float:none;margin:0 0 8px}.wpseo_content_wrapper input.textinput,.wpseo_content_wrapper select,.wpseo_content_wrapper textarea{width:400px}.wpseo_content_wrapper input.number{width:100px}.wpseo_content_wrapper input.large-text,.wpseo_content_wrapper textarea.large-text{width:99%}.wpseo_content_wrapper .select2-container,.wpseo_content_wrapper input.textinput,.wpseo_content_wrapper select.select,.wpseo_content_wrapper textarea.textinput{margin:0 0 15px}.wpseo_content_wrapper input.textinput[aria-invalid=true]{background:#f9dcdc url(../../images/error-icon.svg) no-repeat calc(100% - (100% - 6px));background-size:12px;border:1px solid #dc3232;color:#000;padding-left:24px}.wpseo_content_wrapper input.textinput[aria-invalid=true][aria-describedby]{margin-bottom:.5rem}.wpseo_content_wrapper .yoast-input-validation__error-description{color:#8f1919;margin:0 0 1rem;padding-right:200px;width:400px}.wpseo_content_wrapper input.checkbox,.wpseo_content_wrapper input.checkbox.double,.wpseo_content_wrapper input.radio{margin:6px 0 6px 10px}.wpseo_content_wrapper .textinput.metadesc{height:50px}.wpseo_content_wrapper textarea.import{height:100px;width:500px}.wpseo_content_wrapper p.desc{margin:6px 0 10px;padding:0 25px 8px 0}.wpseo_content_wrapper div.desc.label,.wpseo_content_wrapper p.desc.label{margin:0 0 20px;padding:0 200px 10px 0}.wpseo_content_wrapper h4{clear:both;margin:1.2em 0 .5em}.wpseo_content_wrapper .postbox{margin:10px 0 0 10px}.wpseo_content_wrapper .postbox form{line-height:150%}.wpseo_content_wrapper .text{width:250px}.wpseo_content_wrapper .correct{background-color:green;color:#fff;padding:5px}.wpseo_content_wrapper .wrong{background-color:#dc3232;color:#fff;padding:5px}.wpseo_content_wrapper .wrong code{color:#000;padding:3px 8px}.wpseo_content_wrapper .button.fixit{float:left;margin:0 5px}.wpseo_content_wrapper .button.checkit{float:left;margin:0 5px;padding:5px 8px}.wpseo_content_wrapper .disabled-note{color:#888;margin:0 0 8px}.wpseo_content_wrapper #separator{margin:1em 0 0}.wpseo_content_wrapper #separator input.radio{height:1px;right:-9999em;position:absolute;width:1px}.wpseo_content_wrapper #separator input.radio+label{border:1px solid #ccc;cursor:pointer;float:right;font-family:Arial,Helvetica,sans-serif!important;font-size:18px!important;line-height:24px;margin:.5em 0 0 5px!important;padding:9px 6px;text-align:center;width:30px!important}.wpseo_content_wrapper #separator input.radio:checked+label{background-color:#fff;border:3px solid #a4286a;padding:7px 4px}.wpseo_content_wrapper #separator input.radio:focus+label{outline:2px solid #5b9dd9}.wpseo_content_wrapper .svg-container{text-align:center}.wpseo_content_wrapper .svg-container .dashicons{font-size:100px;height:100px;width:200px}.wpseo_content_wrapper .paper.tab-block button.toggleable-container-trigger{font-size:1.0625rem;padding:16px;width:100%}.wpseo_content_wrapper .paper.tab-block button.toggleable-container-trigger:focus{box-shadow:0 0 3px #084a67cc;outline:1px solid #0066cd;outline-offset:-1px}.wpseo_content_wrapper .paper.tab-block button.toggleable-container-trigger:active{box-shadow:none}.wpseo_content_wrapper .paper.tab-block h2.collapsible-header{margin:0!important;padding:0!important}.wpseo_content_wrapper .paper.tab-block.metabox button.toggleable-container-trigger{color:#555}.wpseo_content_wrapper .paper.tab-block.metabox.wpseotab{border:0;padding:0}.wpseo_content_wrapper .paper.tab-block .paper-container{padding:16px}.wpseo_content_wrapper .paper.tab-block.has-paper-container-no-top-padding .paper-container{padding-top:0}.wpseo_content_wrapper .paper.tab-block .paper-container:first-child{margin-top:0}.wpseo_content_wrapper .paper.tab-block .paper-title{padding:16px}.wpseo_content_wrapper .paper.tab-block .paper-title h2{margin:0}.wpseo_content_wrapper .paper.tab-block .tab-block:first-child{margin-top:0}.wpseo_content_wrapper .wpseo-collapsible-container{background-color:#fff;border-bottom:1px solid #e2e4e7;border-top:1px solid #e2e4e7;margin-top:-1px}.wpseo_content_wrapper .toggleable-container-trigger{background:none;border:0;cursor:pointer;padding:0;text-align:right;width:100%}.wpseo_content_wrapper .toggleable-container-icon{float:left;height:20px;position:relative;width:20px}.wpseo_content_wrapper .toggleable-container-trigger .toggleable-container-icon:after{content:"";display:block;right:-4px;padding:14px;position:absolute;top:-4px}.wpseo_content_wrapper .toggleable-container-hidden{display:none}.wpseo_content_wrapper h3{font-size:1.15em;margin:1em 0 .5em}.wpseo_content_wrapper h3.h2{font-size:1.3em}.wpseo_content_wrapper li,.wpseo_content_wrapper p{max-width:600px}.wpseo_content_wrapper .notice p,.yoast .search-box,.yoast-container .container,.yoast-notification p{max-width:none}table.wpseo th{text-align:right}#wpseo-tabs+.notice{margin-top:1.5em}.wpseo-variable-warning-element{border:1px solid #c62d2d!important}.wpseo-variable-warning{clear:both;color:#c62d2d;margin:5px 0 0;padding:5px}.wpseo-variable-warning code{color:#b02828}.wpseo-variable-warning a{color:#c62d2d}.wpseo_content_wrapper h1.wpseo-redirect-url-title{font-size:1.3em;margin:1em 0 .5em}table.yoast_help{border-collapse:collapse;width:100%}table.yoast_help,table.yoast_help td,table.yoast_help th{border:1px solid #ddd;color:#444}table.yoast_help td,table.yoast_help th{padding:5px 10px;text-align:right;vertical-align:top}table.yoast_help tr{background-color:#f1f1f1}table.yoast_help tr:nth-child(2n){background-color:#fbfbfe}table.yoast_help tr:hover{background-color:#ddd}table.yoast_help thead tr,table.yoast_help thead tr:hover{background-color:#fff}table.yoast_help .yoast-variable-name{font-weight:600;white-space:nowrap}table.yoast_help .yoast-variable-desc{min-width:300px}.yoast-notice-blocking-files code{color:#000;line-height:2}.yoast-notice-blocking-files .button{margin:.5em 0}.wpseo_content_wrapper .yoast-blocking-files-error p{max-width:none}.wpseotab{display:none}.wpseotab.active{display:block}.wpseotab p.expl{margin-right:6px}.wpseotab .tab-block{display:block;margin:30px 0}.wpseotab p.expl strong{font-size:115%}#wpseo-debug-info{background-color:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px #0000000a;clear:both;margin:20px 0 0;padding:20px 20px 0}#wpseo-debug-info h2{cursor:auto;margin:0}#wpseo-debug-info .wpseo-debug-heading{font-size:1em}#wpseo-debug-info .wpseo-debug{color:#c00;display:inline-block;padding-right:20px}input.wpseo-new-title,textarea.wpseo-new-metadesc{max-width:100%;width:100%}body.toplevel_page_wpseo_dashboard .wp-badge{background:#0000 url(../../packages/js/images/Yoast_SEO_Icon.svg) no-repeat 50% 10px;background-size:140px 140px;box-shadow:none}#wpseo_progressbar{border:1px solid #006691;height:25px}#wpseo_progressbar .ui-progressbar-value{background:#006691;height:25px}.wpseo-progressbar-wrapper{display:inline;width:100%}.wpseo-progressbar{border:1px solid #006691;display:block;height:25px;width:100%}.wpseo-progressbar .ui-progressbar-value{background:#006691;height:25px}.yoast-sidebar__title{border-bottom:1px solid #a4286a;box-sizing:border-box;color:#a4286a;line-height:19px;margin:5px 0;padding:10px 0;text-align:right;width:100%}.yoast-sidebar__product{background:#fff;border:1px solid #cd82ab;border-radius:8px;box-shadow:0 3px 6px #00000026;color:#475569;margin-top:34px;padding:24px}.yoast-sidebar__product.woocommerce{border-color:#0075b380}.yoast-sidebar__product h2{color:#a61e69;font-size:20px;font-weight:600}.yoast-sidebar__product.woocommerce h2{color:#0075b3}.yoast-sidebar__product p.info-header{color:#1e293b;font-weight:500;margin-top:12px}.yoast-sidebar__product p{font-weight:400;margin-top:4px}.yoast-sidebar__product ul.yoast-features-list{display:flex;flex-direction:column;gap:8px;list-style-image:none;margin-inline-start:0}.yoast-sidebar__product ul.yoast-features-list li{margin-bottom:0;padding-right:26px;position:relative}.yoast-sidebar__product ul.yoast-features-list li:before{background:var(--yoast-svg-icon-check-circle-green) no-repeat;background-size:19.5px 19.5px;content:"";height:18px;right:0;position:absolute;top:0;width:18px}.yoast-get-premium-title{font-weight:600;line-height:27px;margin-bottom:12px;margin-top:0}.yoast-get-premium-title span{white-space:nowrap}.yoast-sidebar__product .product-image{margin:-50px auto 16px;max-height:64px;max-width:64px;position:relative;z-index:2}.yoast-sidebar__product .product-image img{overflow:hidden}.yoast-sidebar__product p{margin-bottom:12px;margin-top:0}.yoast-sidebar__product .yoast-price-micro-copy{color:#64748b;font-size:12px;font-style:italic;font-weight:400;line-height:20px;margin-bottom:8px;text-align:center}.yoast-sidebar__product .yoast-button-upsell{--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}.yoast-sidebar__product .yoast-upsell-hr{border-color:#e2e8f0;border-top:1px;margin-bottom:16px;margin-top:16px}.yoast-sidebar__product ul.yoast-guarantees-list{color:#1e293b;font-size:12px;font-weight:500;list-style:none;margin:0;padding-bottom:0;text-align:center}.yoast-sidebar__product ul.yoast-guarantees-list li{margin:0}.yoast-sidebar__product .plugin-buy-button .yoast-button-upsell{box-shadow:none;filter:none;font-size:13px;font-weight:500;min-height:36px;padding-bottom:4px;padding-top:4px;width:100%}#wpseo-premium_upsell-popup-button{box-shadow:none;filter:none;padding-bottom:0;padding-top:0;width:100%;--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}@media (min-width:640px){#wpseo-premium_upsell-popup-button{max-width:384px}}.yoast-sidebar__product .review-container{margin-top:16px}.yoast-sidebar__product .review-container a{color:#fff;text-decoration:none}.yoast-sidebar__product .review-container a .claim{color:#fff;display:block;margin-bottom:12px}.yoast-sidebar__product .review-container .title{color:#fff;font-weight:500;margin-bottom:8px}.yoast-sidebar__product .review-container .title:hover{text-decoration:underline}.yoast-sidebar__product .review-container .rating{display:flex;gap:5px}.yoast-sidebar__product .review-container .rating img{max-height:22px;max-width:22px}.yoast-sidebar__product .review-container .rating .rating-text{font-weight:600}.yoast-sidebar__product .sidebar__sale_banner_container{margin-right:-24px;margin-top:-40px;overflow-x:hidden;overflow-y:initial;width:calc(100% + 48px)}.yoast-sidebar__product .sidebar__sale_banner_container .sidebar__sale_banner{box-shadow:0 -1px 4px 0 #fcd34d,0 1px 4px 0 #fcd34d,0 -1px 0 0 #fcd34d,0 1px 0 0 #fcd34d;color:#fcd34d;letter-spacing:.5px;line-height:30px;margin-bottom:10px;margin-right:-30px;margin-top:2.5rem;width:calc(100% + 60px);--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1));font-size:1.125rem;font-weight:700;padding:.25rem 0;text-align:center}.yoast-sidebar__product .sidebar__sale_banner_container .sidebar__sale_banner .banner_text{display:inline-block;margin:0 35px}.yoast-sidebar__product .sidebar__sale_text{border-top:1px solid #fff;font-style:italic;text-align:center}.yoast-sidebar__product .sidebar__sale_text p{font-size:12.5px;margin:12.5px 0}.yoast-sidebar__section{background-color:#fff;border-radius:8px;box-shadow:0 3px 6px #00000026;color:#404040;margin:10px 0 20px;padding:16px}.yoast-sidebar__section h2{color:#a4286a;margin-top:0}.yoast-sidebar__section a{color:#0085ba}.yoast-sidebar__section ul{position:relative}.yoast-sidebar__section li{list-style:none;margin-right:20px}.yoast-sidebar__section li:before{content:"+";font-weight:700;right:0;position:absolute}.yoast-sidebar__section div{margin:10px 0 20px;position:relative}.yoast-sidebar__section div img{float:left;height:70px;margin:0 10px 0 0;width:70px}.yoast-sidebar__section div img.alignleft{float:right;margin:0 0 0 10px}.yoast-sidebar__section div p{float:right;margin:0;width:100%}.yoast_premium_upsell{background-color:#fff;border-radius:8px;box-shadow:0 3px 6px #00000026;margin-top:2em;max-width:896px;overflow:hidden}.yoast_premium_upsell--container{padding:24px}.black-friday-container{background-color:#1f2937;border-bottom:2px solid #fcd34d;display:flex;padding:8px 16px}.black-friday-container span{--tw-text-opacity:1;color:rgb(252 211 77/var(--tw-text-opacity,1));font-size:1.2rem;font-weight:500}.yoast_premium_upsell--header{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1));font-size:1.5em;font-weight:600;line-height:25px;margin:0}.yoast_premium_upsell--header.woo-header{--tw-text-opacity:1;color:rgb(0 117 179/var(--tw-text-opacity,1))}.yoast_premium_upsell--subheader{color:#1e293b;display:block;font-size:1em;font-weight:500;line-height:1.5;margin-top:8px}.yoast_premium_upsell--badge{background-color:#a61e6926;color:#9a1660;margin-left:8px}.yoast_premium_upsell--badge.woo-badge{background-color:#0075b326;color:#006499}.yoast_premium_upsell--motivation{color:#475569;column-gap:1.5rem;display:grid;grid-template-columns:repeat(1,minmax(0,1fr));line-height:1em;list-style-type:none;margin-bottom:0;margin-top:16px}@media (min-width:640px){.yoast_premium_upsell--motivation{grid-template-columns:repeat(2,minmax(0,1fr))}}.yoast_premium_upsell--motivation li{display:flex;flex:0 0 50%}.yoast_premium_upsell--argument{padding-right:10px}@media screen and (max-width:480px){.yoast_premium_upsell--motivation{display:block}}.yoast-variable-desc{min-width:300px}.yoast-table-scrollable,.yoast-table-scrollable td,.yoast-table-scrollable th{box-sizing:border-box}.yoast-table-scrollable__container.yoast-has-scroll{overflow:hidden;position:relative}.yoast-table-scrollable__container.yoast-has-scroll:after{border-radius:0 10px 10px 0/0 50% 50% 0;box-shadow:5px 0 10px #00000040;content:"";height:calc(100% - 16px);right:100%;position:absolute;top:0;width:50px}.yoast-table-scrollable__container.yoast-has-scroll .yoast-table-scrollable__inner{overflow-x:scroll;padding-bottom:16px}.yoast-table-scrollable__hintwrapper{display:none}.yoast-table-scrollable__hintwrapper.yoast-has-scroll{display:block;margin:1em 0;text-align:center}.yoast-has-scroll .yoast-table-scrollable__hint{display:inline-block}.yoast-has-scroll .yoast-table-scrollable__hint:before{content:"\21c4";display:inline-block;font-size:20px;line-height:inherit;margin-left:10px;vertical-align:text-top}.yoast-styled-select{align-items:center;display:inline-flex;margin-bottom:1em;position:relative}.yoast-styled-select:after,.yoast-styled-select:before{bottom:0;content:"";pointer-events:none;position:absolute;top:0}.yoast-styled-select:before{left:0;width:28px}.yoast-styled-select:after{border-top:4px solid #0000;border-color:#555 #0000 #0000;border-style:solid;border-width:5px 4px 0;height:0;margin:auto;left:6px;width:0;z-index:1}.yoast-styled-select select{appearance:none;background:#0000;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;color:#32373c;height:28px;line-height:1;margin:0;max-width:100%;padding:4px 8px 4px 32px}.yoast-styled-select select.error{border-color:#dc3232;border-width:2px}.wpseo_content_wrapper .yoast-styled-select select.select{margin:0}.yoast-styled-select select:focus{border-color:#5b9dd9}.yoast-styled-select select:-moz-focusring{color:#0000;text-shadow:0 0 0 #32373c}.yoast-styled-select select[disabled]{opacity:.75}.yoast-styled-select select::-ms-expand{display:none}@media screen and (max-width:1024px){.wpseo_content_cell,.wpseo_content_wrapper{display:block;height:auto}#wpseo_content_top{width:auto}#sidebar-container{display:flex;gap:.7rem;padding:0;width:auto}.yoast-sidebar__product .sidebar__sale_banner_container{overflow-y:hidden}#sidebar-container .yoast-sidebar__section{margin-top:5rem}.yoast-sidebar__product-list{border-bottom:1px solid #ddd;display:flex}.yoast-sidebar__product-list div p{word-wrap:break-word;width:calc(100% - 50px)}.yoast-sidebar__product-list .yoast-sidebar__section{border-bottom:none}.yoast-sidebar__product-list .yoast-sidebar__section:first-child{margin-left:40px}}@media screen and (max-width:782px){.wpseo_content_wrapper label.select,.wpseo_content_wrapper label.textinput{display:inline-block;float:none;width:auto}.wpseo_content_wrapper input.textinput,.wpseo_content_wrapper textarea,.wpseo_content_wrapper textarea.textinput{display:block;width:100%}.wpseo_content_wrapper .select2-container,.wpseo_content_wrapper select,.wpseo_content_wrapper select.select{display:block;margin:0 0 5px;max-width:100%}.wpseo_content_wrapper div.desc.label,.wpseo_content_wrapper p.desc.label{padding-right:0}.wpseo_content_wrapper .textinput[aria-invalid=true][aria-describedby]+br{display:none}.wpseo_content_wrapper .yoast-input-validation__error-description{padding-right:0;width:auto}}@media screen and (max-width:600px){.yoast-sidebar__product-list{border-bottom:none;display:block}.yoast-sidebar__product-list .yoast-sidebar__section{border-bottom:1px solid #ddd}.yoast-sidebar__product-list .yoast-sidebar__section p{word-wrap:break-word;padding-right:50px;width:calc(100% - 50px)}}@media screen and (max-width:500px){.yoast-sidebar__product .sidebar__sale_banner_container .sidebar__sale_banner{transform:rotate(4deg)}#sidebar-container{display:block}#sidebar-container .yoast-sidebar__section{margin-top:20px}body.toplevel_page_wpseo_dashboard .wp-badge{background-color:#a4286a;background-size:100px 100px;box-shadow:0 1px 3px #0003;padding-top:80px}}.wpseo-checkmark-ok-icon{background:var(--yoast-svg-icon-check-ok) no-repeat;background-size:18px;float:right;height:18px;margin-left:5px;vertical-align:top;width:18px}.yoast-settings-section:not(:last-child){margin-bottom:40px}.yoast-settings-section .yoast-field-group__title .yoast_help.yoast-help-link{margin:-6px 2px 0 0}#yoast-og-default-image-select .yoast-field-group__title{display:none}.yoast-settings-section.yoast-settings-section-disabled{border:1px solid #ccc;padding:16px;position:relative}.yoast-settings-section.yoast-settings-section-disabled>*{opacity:.5}.yoast-settings-section.yoast-settings-section-disabled .yoast-settings-section-upsell{align-items:center;bottom:0;display:flex;justify-content:center;right:0;opacity:1;position:absolute;left:0;top:0}@keyframes yoast-spin{0%{transform:rotate(0deg)}to{transform:rotate(-1turn)}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/yst_plugin_tools-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/yst_plugin_tools-2711.css new file mode 100644 index 0000000..d9ff31a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/yst_plugin_tools-2711.css @@ -0,0 +1 @@ +:root{--yoast-svg-icon-info:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23A4286A' d='M1152 1376v-160q0-14-9-23t-23-9h-96V672q0-14-9-23t-23-9H672q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23m-128-896V320q0-14-9-23t-23-9H800q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23m640 416q0 209-103 385.5T1281.5 1561 896 1664t-385.5-103T231 1281.5 128 896t103-385.5T510.5 231 896 128t385.5 103T1561 510.5 1664 896'/%3E%3C/svg%3E");--yoast-svg-icon-check:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 1792 1792'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%2377B227' d='M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68'/%3E%3C/svg%3E");--yoast-svg-icon-check-circle-green:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%2322c55e' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12m13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094z' clip-rule='evenodd'/%3E%3C/svg%3E");--yoast-svg-icon-caret-right:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662'/%3E%3C/svg%3E");--yoast-svg-icon-caret-left:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true' viewBox='0 0 192 512'%3E%3Cpath fill='%23555' d='M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142'/%3E%3C/svg%3E");--yoast-svg-icon-eye:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5T896 1280t-316.5-131.5T448 832q0-121 61-225-229 117-381 353 133 205 333.5 326.5T896 1408t434.5-121.5T1664 960M944 576q0-20-14-34t-34-14q-125 0-214.5 89.5T592 832q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34m848 384q0 34-20 69-140 230-376.5 368.5T896 1536t-499.5-139T20 1029Q0 994 0 960t20-69q140-229 376.5-368T896 384t499.5 139T1772 891q20 35 20 69'/%3E%3C/svg%3E");--yoast-svg-icon-list:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M384 1408q0 80-56 136t-136 56-136-56-56-136 56-136 136-56 136 56 56 136m0-512q0 80-56 136t-136 56-136-56T0 896t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 1504v-192q0-13 9.5-22.5t22.5-9.5h1216q13 0 22.5 9.5t9.5 22.5M384 384q0 80-56 136t-136 56-136-56T0 384t56-136 136-56 136 56 56 136m1408 416v192q0 13-9.5 22.5t-22.5 9.5H544q-13 0-22.5-9.5T512 992V800q0-13 9.5-22.5T544 768h1216q13 0 22.5 9.5t9.5 22.5m0-512v192q0 13-9.5 22.5T1760 512H544q-13 0-22.5-9.5T512 480V288q0-13 9.5-22.5T544 256h1216q13 0 22.5 9.5t9.5 22.5'/%3E%3C/svg%3E");--yoast-svg-icon-key:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='M832 512q0-80-56-136t-136-56-136 56-56 136q0 42 19 83-41-19-83-19-80 0-136 56t-56 136 56 136 136 56 136-56 56-136q0-42-19-83 41 19 83 19 80 0 136-56t56-136m851 704q0 17-49 66t-66 49q-9 0-28.5-16t-36.5-33-38.5-40-24.5-26l-96 96 220 220q28 28 28 68 0 42-39 81t-81 39q-40 0-68-28l-671-671q-176 131-365 131-163 0-265.5-102.5T0 784q0-160 95-313t248-248 313-95q163 0 265.5 102.5T1024 496q0 189-131 365l355 355 96-96q-3-3-26-24.5t-40-38.5-33-36.5-16-28.5q0-17 49-66t66-49q13 0 23 10 6 6 46 44.5t82 79.5 86.5 86 73 78 28.5 41'/%3E%3C/svg%3E");--yoast-svg-icon-edit:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23555' d='m491 1536 91-91-235-235-91 91v107h128v128zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17m-54-192 416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91'/%3E%3C/svg%3E");--yoast-svg-icon-lock:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-yoast:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23999' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-good:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%237ad03a' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-ok:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23ee7c1b' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-bad:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%23dc3232' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-noindex:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1792' height='1792' aria-hidden='true'%3E%3Cpath fill='%231e8cbe' d='M403 218h691l-26 72H403q-110 0-188.5 79T136 558v771q0 95 60.5 169.5T350 1592q23 5 98 5v72h-45q-140 0-239.5-100T64 1329V558q0-140 99.5-240T403 218M1254 0h247l-482 1294q-23 61-40.5 103.5t-45 98-54 93.5-64.5 78.5-79.5 65-95.5 41-116 18.5v-195q163-26 220-182 20-52 20-105 0-54-20-106L459 471h228l187 585zm474 558v1111H933q37-55 45-73h678V558q0-85-49.5-155T1477 304l25-67q101 34 163.5 123.5T1728 558'/%3E%3C/svg%3E");--yoast-svg-icon-yoast-insight-sparkle:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-cart:url('data:image/svg+xml;charset=utf-8,');--yoast-svg-icon-external-link:url('data:image/svg+xml;charset=utf-8,')}.wpseo_content_wrapper{display:table;table-layout:fixed;width:100%}.wpseo_content_cell{display:table-cell;height:500px;margin:0;padding:0;vertical-align:top}#wpseo_content_top{width:100%}tr.yst_row{margin:5px 0 0;padding:5px 0 0}#sidebar-container{padding-left:20px;width:256px}tr.yst_row.even{background-color:#f6f6f6}.wpseo_content_wrapper label.select,.wpseo_content_wrapper label.textinput{float:left;margin:5px 0;width:200px;word-wrap:break-word}.wpseo_content_wrapper label.select.error,.wpseo_content_wrapper label.textinput.error{color:#dc3232;font-weight:700}.wpseo_content_wrapper .yoast-inline-label{display:inline-block;float:none;margin:0 0 8px}.wpseo_content_wrapper input.textinput,.wpseo_content_wrapper select,.wpseo_content_wrapper textarea{width:400px}.wpseo_content_wrapper input.number{width:100px}.wpseo_content_wrapper input.large-text,.wpseo_content_wrapper textarea.large-text{width:99%}.wpseo_content_wrapper .select2-container,.wpseo_content_wrapper input.textinput,.wpseo_content_wrapper select.select,.wpseo_content_wrapper textarea.textinput{margin:0 0 15px}.wpseo_content_wrapper input.textinput[aria-invalid=true]{background:#f9dcdc url(../../images/error-icon.svg) no-repeat calc(100% - 6px);background-size:12px;border:1px solid #dc3232;color:#000;padding-right:24px}.wpseo_content_wrapper input.textinput[aria-invalid=true][aria-describedby]{margin-bottom:.5rem}.wpseo_content_wrapper .yoast-input-validation__error-description{color:#8f1919;margin:0 0 1rem;padding-left:200px;width:400px}.wpseo_content_wrapper input.checkbox,.wpseo_content_wrapper input.checkbox.double,.wpseo_content_wrapper input.radio{margin:6px 10px 6px 0}.wpseo_content_wrapper .textinput.metadesc{height:50px}.wpseo_content_wrapper textarea.import{height:100px;width:500px}.wpseo_content_wrapper p.desc{margin:6px 0 10px;padding:0 0 8px 25px}.wpseo_content_wrapper div.desc.label,.wpseo_content_wrapper p.desc.label{margin:0 0 20px;padding:0 0 10px 200px}.wpseo_content_wrapper h4{clear:both;margin:1.2em 0 .5em}.wpseo_content_wrapper .postbox{margin:10px 10px 0 0}.wpseo_content_wrapper .postbox form{line-height:150%}.wpseo_content_wrapper .text{width:250px}.wpseo_content_wrapper .correct{background-color:green;color:#fff;padding:5px}.wpseo_content_wrapper .wrong{background-color:#dc3232;color:#fff;padding:5px}.wpseo_content_wrapper .wrong code{color:#000;padding:3px 8px}.wpseo_content_wrapper .button.fixit{float:right;margin:0 5px}.wpseo_content_wrapper .button.checkit{float:right;margin:0 5px;padding:5px 8px}.wpseo_content_wrapper .disabled-note{color:#888;margin:0 0 8px}.wpseo_content_wrapper #separator{margin:1em 0 0}.wpseo_content_wrapper #separator input.radio{height:1px;left:-9999em;position:absolute;width:1px}.wpseo_content_wrapper #separator input.radio+label{border:1px solid #ccc;cursor:pointer;float:left;font-family:Arial,Helvetica,sans-serif!important;font-size:18px!important;line-height:24px;margin:.5em 5px 0 0!important;padding:9px 6px;text-align:center;width:30px!important}.wpseo_content_wrapper #separator input.radio:checked+label{background-color:#fff;border:3px solid #a4286a;padding:7px 4px}.wpseo_content_wrapper #separator input.radio:focus+label{outline:2px solid #5b9dd9}.wpseo_content_wrapper .svg-container{text-align:center}.wpseo_content_wrapper .svg-container .dashicons{font-size:100px;height:100px;width:200px}.wpseo_content_wrapper .paper.tab-block button.toggleable-container-trigger{font-size:1.0625rem;padding:16px;width:100%}.wpseo_content_wrapper .paper.tab-block button.toggleable-container-trigger:focus{box-shadow:0 0 3px #084a67cc;outline:1px solid #0066cd;outline-offset:-1px}.wpseo_content_wrapper .paper.tab-block button.toggleable-container-trigger:active{box-shadow:none}.wpseo_content_wrapper .paper.tab-block h2.collapsible-header{margin:0!important;padding:0!important}.wpseo_content_wrapper .paper.tab-block.metabox button.toggleable-container-trigger{color:#555}.wpseo_content_wrapper .paper.tab-block.metabox.wpseotab{border:0;padding:0}.wpseo_content_wrapper .paper.tab-block .paper-container{padding:16px}.wpseo_content_wrapper .paper.tab-block.has-paper-container-no-top-padding .paper-container{padding-top:0}.wpseo_content_wrapper .paper.tab-block .paper-container:first-child{margin-top:0}.wpseo_content_wrapper .paper.tab-block .paper-title{padding:16px}.wpseo_content_wrapper .paper.tab-block .paper-title h2{margin:0}.wpseo_content_wrapper .paper.tab-block .tab-block:first-child{margin-top:0}.wpseo_content_wrapper .wpseo-collapsible-container{background-color:#fff;border-bottom:1px solid #e2e4e7;border-top:1px solid #e2e4e7;margin-top:-1px}.wpseo_content_wrapper .toggleable-container-trigger{background:none;border:0;cursor:pointer;padding:0;text-align:left;width:100%}.wpseo_content_wrapper .toggleable-container-icon{float:right;height:20px;position:relative;width:20px}.wpseo_content_wrapper .toggleable-container-trigger .toggleable-container-icon:after{content:"";display:block;left:-4px;padding:14px;position:absolute;top:-4px}.wpseo_content_wrapper .toggleable-container-hidden{display:none}.wpseo_content_wrapper h3{font-size:1.15em;margin:1em 0 .5em}.wpseo_content_wrapper h3.h2{font-size:1.3em}.wpseo_content_wrapper li,.wpseo_content_wrapper p{max-width:600px}.wpseo_content_wrapper .notice p,.yoast .search-box,.yoast-container .container,.yoast-notification p{max-width:none}table.wpseo th{text-align:left}#wpseo-tabs+.notice{margin-top:1.5em}.wpseo-variable-warning-element{border:1px solid #c62d2d!important}.wpseo-variable-warning{clear:both;color:#c62d2d;margin:5px 0 0;padding:5px}.wpseo-variable-warning code{color:#b02828}.wpseo-variable-warning a{color:#c62d2d}.wpseo_content_wrapper h1.wpseo-redirect-url-title{font-size:1.3em;margin:1em 0 .5em}table.yoast_help{border-collapse:collapse;width:100%}table.yoast_help,table.yoast_help td,table.yoast_help th{border:1px solid #ddd;color:#444}table.yoast_help td,table.yoast_help th{padding:5px 10px;text-align:left;vertical-align:top}table.yoast_help tr{background-color:#f1f1f1}table.yoast_help tr:nth-child(2n){background-color:#fbfbfe}table.yoast_help tr:hover{background-color:#ddd}table.yoast_help thead tr,table.yoast_help thead tr:hover{background-color:#fff}table.yoast_help .yoast-variable-name{font-weight:600;white-space:nowrap}table.yoast_help .yoast-variable-desc{min-width:300px}.yoast-notice-blocking-files code{color:#000;line-height:2}.yoast-notice-blocking-files .button{margin:.5em 0}.wpseo_content_wrapper .yoast-blocking-files-error p{max-width:none}.wpseotab{display:none}.wpseotab.active{display:block}.wpseotab p.expl{margin-left:6px}.wpseotab .tab-block{display:block;margin:30px 0}.wpseotab p.expl strong{font-size:115%}#wpseo-debug-info{background-color:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px #0000000a;clear:both;margin:20px 0 0;padding:20px 20px 0}#wpseo-debug-info h2{cursor:auto;margin:0}#wpseo-debug-info .wpseo-debug-heading{font-size:1em}#wpseo-debug-info .wpseo-debug{color:#c00;display:inline-block;padding-left:20px}input.wpseo-new-title,textarea.wpseo-new-metadesc{max-width:100%;width:100%}body.toplevel_page_wpseo_dashboard .wp-badge{background:#0000 url(../../packages/js/images/Yoast_SEO_Icon.svg) no-repeat 50% 10px;background-size:140px 140px;box-shadow:none}#wpseo_progressbar{border:1px solid #006691;height:25px}#wpseo_progressbar .ui-progressbar-value{background:#006691;height:25px}.wpseo-progressbar-wrapper{display:inline;width:100%}.wpseo-progressbar{border:1px solid #006691;display:block;height:25px;width:100%}.wpseo-progressbar .ui-progressbar-value{background:#006691;height:25px}.yoast-sidebar__title{border-bottom:1px solid #a4286a;box-sizing:border-box;color:#a4286a;line-height:19px;margin:5px 0;padding:10px 0;text-align:left;width:100%}.yoast-sidebar__product{background:#fff;border:1px solid #cd82ab;border-radius:8px;box-shadow:0 3px 6px #00000026;color:#475569;margin-top:34px;padding:24px}.yoast-sidebar__product.woocommerce{border-color:#0075b380}.yoast-sidebar__product h2{color:#a61e69;font-size:20px;font-weight:600}.yoast-sidebar__product.woocommerce h2{color:#0075b3}.yoast-sidebar__product p.info-header{color:#1e293b;font-weight:500;margin-top:12px}.yoast-sidebar__product p{font-weight:400;margin-top:4px}.yoast-sidebar__product ul.yoast-features-list{display:flex;flex-direction:column;gap:8px;list-style-image:none;margin-inline-start:0}.yoast-sidebar__product ul.yoast-features-list li{margin-bottom:0;padding-left:26px;position:relative}.yoast-sidebar__product ul.yoast-features-list li:before{background:var(--yoast-svg-icon-check-circle-green) no-repeat;background-size:19.5px 19.5px;content:"";height:18px;left:0;position:absolute;top:0;width:18px}.yoast-get-premium-title{font-weight:600;line-height:27px;margin-bottom:12px;margin-top:0}.yoast-get-premium-title span{white-space:nowrap}.yoast-sidebar__product .product-image{margin:-50px auto 16px;max-height:64px;max-width:64px;position:relative;z-index:2}.yoast-sidebar__product .product-image img{overflow:hidden}.yoast-sidebar__product p{margin-bottom:12px;margin-top:0}.yoast-sidebar__product .yoast-price-micro-copy{color:#64748b;font-size:12px;font-style:italic;font-weight:400;line-height:20px;margin-bottom:8px;text-align:center}.yoast-sidebar__product .yoast-button-upsell{--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}.yoast-sidebar__product .yoast-upsell-hr{border-color:#e2e8f0;border-top:1px;margin-bottom:16px;margin-top:16px}.yoast-sidebar__product ul.yoast-guarantees-list{color:#1e293b;font-size:12px;font-weight:500;list-style:none;margin:0;padding-bottom:0;text-align:center}.yoast-sidebar__product ul.yoast-guarantees-list li{margin:0}.yoast-sidebar__product .plugin-buy-button .yoast-button-upsell{box-shadow:none;filter:none;font-size:13px;font-weight:500;min-height:36px;padding-bottom:4px;padding-top:4px;width:100%}#wpseo-premium_upsell-popup-button{box-shadow:none;filter:none;padding-bottom:0;padding-top:0;width:100%;--tw-bg-opacity:1;background-color:rgb(252 211 77/var(--tw-bg-opacity,1));--tw-text-opacity:1;color:rgb(120 53 15/var(--tw-text-opacity,1))}@media (min-width:640px){#wpseo-premium_upsell-popup-button{max-width:384px}}.yoast-sidebar__product .review-container{margin-top:16px}.yoast-sidebar__product .review-container a{color:#fff;text-decoration:none}.yoast-sidebar__product .review-container a .claim{color:#fff;display:block;margin-bottom:12px}.yoast-sidebar__product .review-container .title{color:#fff;font-weight:500;margin-bottom:8px}.yoast-sidebar__product .review-container .title:hover{text-decoration:underline}.yoast-sidebar__product .review-container .rating{display:flex;gap:5px}.yoast-sidebar__product .review-container .rating img{max-height:22px;max-width:22px}.yoast-sidebar__product .review-container .rating .rating-text{font-weight:600}.yoast-sidebar__product .sidebar__sale_banner_container{margin-left:-24px;margin-top:-40px;overflow-x:hidden;overflow-y:initial;width:calc(100% + 48px)}.yoast-sidebar__product .sidebar__sale_banner_container .sidebar__sale_banner{box-shadow:0 -1px 4px 0 #fcd34d,0 1px 4px 0 #fcd34d,0 -1px 0 0 #fcd34d,0 1px 0 0 #fcd34d;color:#fcd34d;letter-spacing:.5px;line-height:30px;margin-bottom:10px;margin-left:-30px;margin-top:2.5rem;width:calc(100% + 60px);--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity,1));font-size:1.125rem;font-weight:700;padding:.25rem 0;text-align:center}.yoast-sidebar__product .sidebar__sale_banner_container .sidebar__sale_banner .banner_text{display:inline-block;margin:0 35px}.yoast-sidebar__product .sidebar__sale_text{border-top:1px solid #fff;font-style:italic;text-align:center}.yoast-sidebar__product .sidebar__sale_text p{font-size:12.5px;margin:12.5px 0}.yoast-sidebar__section{background-color:#fff;border-radius:8px;box-shadow:0 3px 6px #00000026;color:#404040;margin:10px 0 20px;padding:16px}.yoast-sidebar__section h2{color:#a4286a;margin-top:0}.yoast-sidebar__section a{color:#0085ba}.yoast-sidebar__section ul{position:relative}.yoast-sidebar__section li{list-style:none;margin-left:20px}.yoast-sidebar__section li:before{content:"+";font-weight:700;left:0;position:absolute}.yoast-sidebar__section div{margin:10px 0 20px;position:relative}.yoast-sidebar__section div img{float:right;height:70px;margin:0 0 0 10px;width:70px}.yoast-sidebar__section div img.alignleft{float:left;margin:0 10px 0 0}.yoast-sidebar__section div p{float:left;margin:0;width:100%}.yoast_premium_upsell{background-color:#fff;border-radius:8px;box-shadow:0 3px 6px #00000026;margin-top:2em;max-width:896px;overflow:hidden}.yoast_premium_upsell--container{padding:24px}.black-friday-container{background-color:#1f2937;border-bottom:2px solid #fcd34d;display:flex;padding:8px 16px}.black-friday-container span{--tw-text-opacity:1;color:rgb(252 211 77/var(--tw-text-opacity,1));font-size:1.2rem;font-weight:500}.yoast_premium_upsell--header{--tw-text-opacity:1;color:rgb(166 30 105/var(--tw-text-opacity,1));font-size:1.5em;font-weight:600;line-height:25px;margin:0}.yoast_premium_upsell--header.woo-header{--tw-text-opacity:1;color:rgb(0 117 179/var(--tw-text-opacity,1))}.yoast_premium_upsell--subheader{color:#1e293b;display:block;font-size:1em;font-weight:500;line-height:1.5;margin-top:8px}.yoast_premium_upsell--badge{background-color:#a61e6926;color:#9a1660;margin-right:8px}.yoast_premium_upsell--badge.woo-badge{background-color:#0075b326;color:#006499}.yoast_premium_upsell--motivation{color:#475569;column-gap:1.5rem;display:grid;grid-template-columns:repeat(1,minmax(0,1fr));line-height:1em;list-style-type:none;margin-bottom:0;margin-top:16px}@media (min-width:640px){.yoast_premium_upsell--motivation{grid-template-columns:repeat(2,minmax(0,1fr))}}.yoast_premium_upsell--motivation li{display:flex;flex:0 0 50%}.yoast_premium_upsell--argument{padding-left:10px}@media screen and (max-width:480px){.yoast_premium_upsell--motivation{display:block}}.yoast-variable-desc{min-width:300px}.yoast-table-scrollable,.yoast-table-scrollable td,.yoast-table-scrollable th{box-sizing:border-box}.yoast-table-scrollable__container.yoast-has-scroll{overflow:hidden;position:relative}.yoast-table-scrollable__container.yoast-has-scroll:after{border-radius:10px 0 0 10px/50% 0 0 50%;box-shadow:-5px 0 10px #00000040;content:"";height:calc(100% - 16px);left:100%;position:absolute;top:0;width:50px}.yoast-table-scrollable__container.yoast-has-scroll .yoast-table-scrollable__inner{overflow-x:scroll;padding-bottom:16px}.yoast-table-scrollable__hintwrapper{display:none}.yoast-table-scrollable__hintwrapper.yoast-has-scroll{display:block;margin:1em 0;text-align:center}.yoast-has-scroll .yoast-table-scrollable__hint{display:inline-block}.yoast-has-scroll .yoast-table-scrollable__hint:before{content:"\21c4";display:inline-block;font-size:20px;line-height:inherit;margin-right:10px;vertical-align:text-top}.yoast-styled-select{align-items:center;display:inline-flex;margin-bottom:1em;position:relative}.yoast-styled-select:after,.yoast-styled-select:before{bottom:0;content:"";pointer-events:none;position:absolute;top:0}.yoast-styled-select:before{right:0;width:28px}.yoast-styled-select:after{border-top:4px solid #0000;border-color:#555 #0000 #0000;border-style:solid;border-width:5px 4px 0;height:0;margin:auto;right:6px;width:0;z-index:1}.yoast-styled-select select{appearance:none;background:#0000;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;color:#32373c;height:28px;line-height:1;margin:0;max-width:100%;padding:4px 32px 4px 8px}.yoast-styled-select select.error{border-color:#dc3232;border-width:2px}.wpseo_content_wrapper .yoast-styled-select select.select{margin:0}.yoast-styled-select select:focus{border-color:#5b9dd9}.yoast-styled-select select:-moz-focusring{color:#0000;text-shadow:0 0 0 #32373c}.yoast-styled-select select[disabled]{opacity:.75}.yoast-styled-select select::-ms-expand{display:none}@media screen and (max-width:1024px){.wpseo_content_cell,.wpseo_content_wrapper{display:block;height:auto}#wpseo_content_top{width:auto}#sidebar-container{display:flex;gap:.7rem;padding:0;width:auto}.yoast-sidebar__product .sidebar__sale_banner_container{overflow-y:hidden}#sidebar-container .yoast-sidebar__section{margin-top:5rem}.yoast-sidebar__product-list{border-bottom:1px solid #ddd;display:flex}.yoast-sidebar__product-list div p{word-wrap:break-word;width:calc(100% - 50px)}.yoast-sidebar__product-list .yoast-sidebar__section{border-bottom:none}.yoast-sidebar__product-list .yoast-sidebar__section:first-child{margin-right:40px}}@media screen and (max-width:782px){.wpseo_content_wrapper label.select,.wpseo_content_wrapper label.textinput{display:inline-block;float:none;width:auto}.wpseo_content_wrapper input.textinput,.wpseo_content_wrapper textarea,.wpseo_content_wrapper textarea.textinput{display:block;width:100%}.wpseo_content_wrapper .select2-container,.wpseo_content_wrapper select,.wpseo_content_wrapper select.select{display:block;margin:0 0 5px;max-width:100%}.wpseo_content_wrapper div.desc.label,.wpseo_content_wrapper p.desc.label{padding-left:0}.wpseo_content_wrapper .textinput[aria-invalid=true][aria-describedby]+br{display:none}.wpseo_content_wrapper .yoast-input-validation__error-description{padding-left:0;width:auto}}@media screen and (max-width:600px){.yoast-sidebar__product-list{border-bottom:none;display:block}.yoast-sidebar__product-list .yoast-sidebar__section{border-bottom:1px solid #ddd}.yoast-sidebar__product-list .yoast-sidebar__section p{word-wrap:break-word;padding-left:50px;width:calc(100% - 50px)}}@media screen and (max-width:500px){.yoast-sidebar__product .sidebar__sale_banner_container .sidebar__sale_banner{transform:rotate(-4deg)}#sidebar-container{display:block}#sidebar-container .yoast-sidebar__section{margin-top:20px}body.toplevel_page_wpseo_dashboard .wp-badge{background-color:#a4286a;background-size:100px 100px;box-shadow:0 1px 3px #0003;padding-top:80px}}.wpseo-checkmark-ok-icon{background:var(--yoast-svg-icon-check-ok) no-repeat;background-size:18px;float:left;height:18px;margin-right:5px;vertical-align:top;width:18px}.yoast-settings-section:not(:last-child){margin-bottom:40px}.yoast-settings-section .yoast-field-group__title .yoast_help.yoast-help-link{margin:-6px 0 0 2px}#yoast-og-default-image-select .yoast-field-group__title{display:none}.yoast-settings-section.yoast-settings-section-disabled{border:1px solid #ccc;padding:16px;position:relative}.yoast-settings-section.yoast-settings-section-disabled>*{opacity:.5}.yoast-settings-section.yoast-settings-section-disabled .yoast-settings-section-upsell{align-items:center;bottom:0;display:flex;justify-content:center;left:0;opacity:1;position:absolute;right:0;top:0}@keyframes yoast-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/yst_seo_score-2711-rtl.css b/html/wp-content/plugins/wordpress-seo/css/dist/yst_seo_score-2711-rtl.css new file mode 100644 index 0000000..d4343af --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/yst_seo_score-2711-rtl.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 3px 0 10px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe}.yst-traffic-light{height:30px;margin:0 5px 0 0;width:19px}.yst-traffic-light .traffic-light-color{display:none}.yst-traffic-light.bad .traffic-light-red,.yst-traffic-light.good .traffic-light-green,.yst-traffic-light.init .traffic-light-init,.yst-traffic-light.na .traffic-light-empty,.yst-traffic-light.ok .traffic-light-orange{display:inline}.yoast-seo-score .yoast-logo.svg{background:var(--yoast-svg-icon-yoast) no-repeat;background-size:18px;flex-shrink:0;float:right;height:18px;margin-left:7px;width:18px}.yoast-seo-score .yoast-logo.svg.good{background-image:var(--yoast-svg-icon-yoast-good)}.yoast-seo-score .yoast-logo.svg.ok{background-image:var(--yoast-svg-icon-yoast-ok)}.yoast-seo-score .yoast-logo.svg.bad{background-image:var(--yoast-svg-icon-yoast-bad)}.yoast-seo-score .yoast-logo.svg.na,.yoast-seo-score .yoast-logo.svg.noindex{background-image:var(--yoast-svg-icon-yoast)} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/dist/yst_seo_score-2711.css b/html/wp-content/plugins/wordpress-seo/css/dist/yst_seo_score-2711.css new file mode 100644 index 0000000..b381fa0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/dist/yst_seo_score-2711.css @@ -0,0 +1 @@ +.wpseo-score-icon{background:#888;border-radius:50%!important;display:inline-block!important;height:12px!important;margin:3px 10px 0 3px;vertical-align:top;width:12px!important}.wpseo-score-icon.good{background-color:#7ad03a}.wpseo-score-icon.ok{background-color:#ee7c1b}.wpseo-score-icon.bad{background-color:#dc3232}.wpseo-score-icon.na{background-color:#888}.wpseo-score-icon.noindex{background-color:#1e8cbe}.yst-traffic-light{height:30px;margin:0 0 0 5px;width:19px}.yst-traffic-light .traffic-light-color{display:none}.yst-traffic-light.bad .traffic-light-red,.yst-traffic-light.good .traffic-light-green,.yst-traffic-light.init .traffic-light-init,.yst-traffic-light.na .traffic-light-empty,.yst-traffic-light.ok .traffic-light-orange{display:inline}.yoast-seo-score .yoast-logo.svg{background:var(--yoast-svg-icon-yoast) no-repeat;background-size:18px;flex-shrink:0;float:left;height:18px;margin-right:7px;width:18px}.yoast-seo-score .yoast-logo.svg.good{background-image:var(--yoast-svg-icon-yoast-good)}.yoast-seo-score .yoast-logo.svg.ok{background-image:var(--yoast-svg-icon-yoast-ok)}.yoast-seo-score .yoast-logo.svg.bad{background-image:var(--yoast-svg-icon-yoast-bad)}.yoast-seo-score .yoast-logo.svg.na,.yoast-seo-score .yoast-logo.svg.noindex{background-image:var(--yoast-svg-icon-yoast)} \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/css/main-sitemap.xsl b/html/wp-content/plugins/wordpress-seo/css/main-sitemap.xsl new file mode 100644 index 0000000..b6e0ad1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/css/main-sitemap.xsl @@ -0,0 +1,145 @@ + + + + + + + XML Sitemap + + + + +
            +

            XML Sitemap

            +

            + Generated by Yoast SEO, this is an XML Sitemap, meant for consumption by search engines.
            + You can find more information about XML sitemaps on sitemaps.org. +

            + +

            + This XML Sitemap Index file contains sitemaps. +

            + + + + + + + + + + + + + + + + + + +
            SitemapLast Modified
            + + + +
            +
            + +

            + This XML Sitemap contains URLs. +

            + + + + + + + + + + + + + + + + + + + +
            URLImagesLast Mod.
            + + + + + + + + + + +
            +
            +
            + + +
            +
            diff --git a/html/wp-content/plugins/wordpress-seo/images/Yoast_SEO_negative_icon.svg b/html/wp-content/plugins/wordpress-seo/images/Yoast_SEO_negative_icon.svg new file mode 100644 index 0000000..ad6a6b3 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/Yoast_SEO_negative_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/ai_for_seo_icon_my_yoast.png b/html/wp-content/plugins/wordpress-seo/images/academy/ai_for_seo_icon_my_yoast.png new file mode 100644 index 0000000..4e27c6e Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/ai_for_seo_icon_my_yoast.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/all_around_seo.png b/html/wp-content/plugins/wordpress-seo/images/academy/all_around_seo.png new file mode 100644 index 0000000..c63aa72 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/all_around_seo.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/block_editor.png b/html/wp-content/plugins/wordpress-seo/images/academy/block_editor.png new file mode 100644 index 0000000..bb47a94 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/block_editor.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/copywriting.png b/html/wp-content/plugins/wordpress-seo/images/academy/copywriting.png new file mode 100644 index 0000000..50812e7 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/copywriting.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/crawlability.png b/html/wp-content/plugins/wordpress-seo/images/academy/crawlability.png new file mode 100644 index 0000000..ab7c573 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/crawlability.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/ecommerce.png b/html/wp-content/plugins/wordpress-seo/images/academy/ecommerce.png new file mode 100644 index 0000000..26af331 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/ecommerce.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/hosting_and_server.png b/html/wp-content/plugins/wordpress-seo/images/academy/hosting_and_server.png new file mode 100644 index 0000000..4aabc12 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/hosting_and_server.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/keyword_research.png b/html/wp-content/plugins/wordpress-seo/images/academy/keyword_research.png new file mode 100644 index 0000000..75d5d45 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/keyword_research.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/local.png b/html/wp-content/plugins/wordpress-seo/images/academy/local.png new file mode 100644 index 0000000..6916755 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/local.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/multilingual.png b/html/wp-content/plugins/wordpress-seo/images/academy/multilingual.png new file mode 100644 index 0000000..cc30e09 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/multilingual.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/seo_for_beginners.png b/html/wp-content/plugins/wordpress-seo/images/academy/seo_for_beginners.png new file mode 100644 index 0000000..4c932b2 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/seo_for_beginners.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/seo_for_wp.png b/html/wp-content/plugins/wordpress-seo/images/academy/seo_for_wp.png new file mode 100644 index 0000000..363417e Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/seo_for_wp.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/site_structure.png b/html/wp-content/plugins/wordpress-seo/images/academy/site_structure.png new file mode 100644 index 0000000..ff0b747 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/site_structure.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/structured_data_for_beginners.png b/html/wp-content/plugins/wordpress-seo/images/academy/structured_data_for_beginners.png new file mode 100644 index 0000000..100db7f Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/structured_data_for_beginners.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/understanding_structured_data.png b/html/wp-content/plugins/wordpress-seo/images/academy/understanding_structured_data.png new file mode 100644 index 0000000..efad745 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/understanding_structured_data.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/academy/wp_for_beginners.png b/html/wp-content/plugins/wordpress-seo/images/academy/wp_for_beginners.png new file mode 100644 index 0000000..d677b4d Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/academy/wp_for_beginners.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/acf-logo.png b/html/wp-content/plugins/wordpress-seo/images/acf-logo.png new file mode 100644 index 0000000..829a702 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/acf-logo.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/ai-brand-insights-pre-launch.png b/html/wp-content/plugins/wordpress-seo/images/ai-brand-insights-pre-launch.png new file mode 100644 index 0000000..efef728 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/ai-brand-insights-pre-launch.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/ai-consent.png b/html/wp-content/plugins/wordpress-seo/images/ai-consent.png new file mode 100644 index 0000000..6843e92 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/ai-consent.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/ai-fix-assessments-thumbnail.png b/html/wp-content/plugins/wordpress-seo/images/ai-fix-assessments-thumbnail.png new file mode 100644 index 0000000..bb7a4ac Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/ai-fix-assessments-thumbnail.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/ai-generator-preview.png b/html/wp-content/plugins/wordpress-seo/images/ai-generator-preview.png new file mode 100644 index 0000000..73ba341 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/ai-generator-preview.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/alert-error-icon.svg b/html/wp-content/plugins/wordpress-seo/images/alert-error-icon.svg new file mode 100644 index 0000000..80fa062 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/alert-error-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/alert-info-icon.svg b/html/wp-content/plugins/wordpress-seo/images/alert-info-icon.svg new file mode 100644 index 0000000..332d7af --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/alert-info-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/alert-success-icon.svg b/html/wp-content/plugins/wordpress-seo/images/alert-success-icon.svg new file mode 100644 index 0000000..30519e5 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/alert-success-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/alert-warning-icon.svg b/html/wp-content/plugins/wordpress-seo/images/alert-warning-icon.svg new file mode 100644 index 0000000..f52df86 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/alert-warning-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/black-friday-2025.gif b/html/wp-content/plugins/wordpress-seo/images/black-friday-2025.gif new file mode 100644 index 0000000..96b1aa1 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/black-friday-2025.gif differ diff --git a/html/wp-content/plugins/wordpress-seo/images/error-icon.svg b/html/wp-content/plugins/wordpress-seo/images/error-icon.svg new file mode 100644 index 0000000..43e859d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/error-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-admin-bar.svg b/html/wp-content/plugins/wordpress-seo/images/icon-admin-bar.svg new file mode 100644 index 0000000..204e4f9 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-admin-bar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-cornerstone-content.svg b/html/wp-content/plugins/wordpress-seo/images/icon-cornerstone-content.svg new file mode 100644 index 0000000..22e3b0a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-cornerstone-content.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-inclusive-language-analysis.svg b/html/wp-content/plugins/wordpress-seo/images/icon-inclusive-language-analysis.svg new file mode 100644 index 0000000..94deb97 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-inclusive-language-analysis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-index-now.svg b/html/wp-content/plugins/wordpress-seo/images/icon-index-now.svg new file mode 100644 index 0000000..1d1bf1a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-index-now.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-insights.svg b/html/wp-content/plugins/wordpress-seo/images/icon-insights.svg new file mode 100644 index 0000000..3259371 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-insights.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-internal-linking-suggestions.svg b/html/wp-content/plugins/wordpress-seo/images/icon-internal-linking-suggestions.svg new file mode 100644 index 0000000..7f69010 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-internal-linking-suggestions.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-llms-txt.svg b/html/wp-content/plugins/wordpress-seo/images/icon-llms-txt.svg new file mode 100644 index 0000000..fd730d7 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-llms-txt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-open-graph.svg b/html/wp-content/plugins/wordpress-seo/images/icon-open-graph.svg new file mode 100644 index 0000000..89fc2bd --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-open-graph.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-readability-analysis.svg b/html/wp-content/plugins/wordpress-seo/images/icon-readability-analysis.svg new file mode 100644 index 0000000..c274c4b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-readability-analysis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-redirect-manager.svg b/html/wp-content/plugins/wordpress-seo/images/icon-redirect-manager.svg new file mode 100644 index 0000000..d34262d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-redirect-manager.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-rest-api-endpoint.svg b/html/wp-content/plugins/wordpress-seo/images/icon-rest-api-endpoint.svg new file mode 100644 index 0000000..e9176df --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-rest-api-endpoint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-schema-aggregation-endpoint.svg b/html/wp-content/plugins/wordpress-seo/images/icon-schema-aggregation-endpoint.svg new file mode 100644 index 0000000..c9295e1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-schema-aggregation-endpoint.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-schema-framework.svg b/html/wp-content/plugins/wordpress-seo/images/icon-schema-framework.svg new file mode 100644 index 0000000..0a821cc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-schema-framework.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-seo-analysis.svg b/html/wp-content/plugins/wordpress-seo/images/icon-seo-analysis.svg new file mode 100644 index 0000000..2496a0f --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-seo-analysis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-slack-sharing.svg b/html/wp-content/plugins/wordpress-seo/images/icon-slack-sharing.svg new file mode 100644 index 0000000..472d921 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-slack-sharing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-sparkles.svg b/html/wp-content/plugins/wordpress-seo/images/icon-sparkles.svg new file mode 100644 index 0000000..d8363c0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-sparkles.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-task-list.svg b/html/wp-content/plugins/wordpress-seo/images/icon-task-list.svg new file mode 100644 index 0000000..7bec18b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-task-list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-text-link-counter.svg b/html/wp-content/plugins/wordpress-seo/images/icon-text-link-counter.svg new file mode 100644 index 0000000..501aaf9 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-text-link-counter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-x-card-data.svg b/html/wp-content/plugins/wordpress-seo/images/icon-x-card-data.svg new file mode 100644 index 0000000..565c259 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-x-card-data.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/icon-xml-sitemaps.svg b/html/wp-content/plugins/wordpress-seo/images/icon-xml-sitemaps.svg new file mode 100644 index 0000000..0f161ea --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/icon-xml-sitemaps.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/index.php b/html/wp-content/plugins/wordpress-seo/images/index.php new file mode 100644 index 0000000..e94d9a4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/index.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/link-in-icon.svg b/html/wp-content/plugins/wordpress-seo/images/link-in-icon.svg new file mode 100644 index 0000000..c374855 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/link-in-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/link-out-icon.svg b/html/wp-content/plugins/wordpress-seo/images/link-out-icon.svg new file mode 100644 index 0000000..202082b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/link-out-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/local_plugin_assistant.svg b/html/wp-content/plugins/wordpress-seo/images/local_plugin_assistant.svg new file mode 100644 index 0000000..44e3264 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/local_plugin_assistant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_man_1_optim.svg b/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_man_1_optim.svg new file mode 100644 index 0000000..187e6c4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_man_1_optim.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_woman_1_optim.svg b/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_woman_1_optim.svg new file mode 100644 index 0000000..4d5a248 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_woman_1_optim.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_woman_2_optim.svg b/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_woman_2_optim.svg new file mode 100644 index 0000000..801c69a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/mirrored_fit_bubble_woman_2_optim.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/new-to-configuration-notice.svg b/html/wp-content/plugins/wordpress-seo/images/new-to-configuration-notice.svg new file mode 100644 index 0000000..2343c57 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/new-to-configuration-notice.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/news_plugin_assistant.svg b/html/wp-content/plugins/wordpress-seo/images/news_plugin_assistant.svg new file mode 100644 index 0000000..f178f9c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/news_plugin_assistant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/plugin_subscription.svg b/html/wp-content/plugins/wordpress-seo/images/plugin_subscription.svg new file mode 100644 index 0000000..a3c077b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/plugin_subscription.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/question-mark.png b/html/wp-content/plugins/wordpress-seo/images/question-mark.png new file mode 100644 index 0000000..f847220 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/question-mark.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/readability-icon.svg b/html/wp-content/plugins/wordpress-seo/images/readability-icon.svg new file mode 100644 index 0000000..439f52f --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/readability-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/redirect-manager-thumbnail.png b/html/wp-content/plugins/wordpress-seo/images/redirect-manager-thumbnail.png new file mode 100644 index 0000000..a6ba390 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/redirect-manager-thumbnail.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/schema-aggregator-thumbnail.png b/html/wp-content/plugins/wordpress-seo/images/schema-aggregator-thumbnail.png new file mode 100644 index 0000000..4faeb14 Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/schema-aggregator-thumbnail.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/stale-cornerstone-content-in-yoast-seo.png b/html/wp-content/plugins/wordpress-seo/images/stale-cornerstone-content-in-yoast-seo.png new file mode 100644 index 0000000..581509a Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/stale-cornerstone-content-in-yoast-seo.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/succes_marieke_bubble_optm.svg b/html/wp-content/plugins/wordpress-seo/images/succes_marieke_bubble_optm.svg new file mode 100644 index 0000000..cfb3682 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/succes_marieke_bubble_optm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/support-team.svg b/html/wp-content/plugins/wordpress-seo/images/support-team.svg new file mode 100644 index 0000000..27e2678 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/support-team.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/support/github.png b/html/wp-content/plugins/wordpress-seo/images/support/github.png new file mode 100644 index 0000000..fc38adf Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/support/github.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/support/help_center.png b/html/wp-content/plugins/wordpress-seo/images/support/help_center.png new file mode 100644 index 0000000..43429ad Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/support/help_center.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/support/support_forums.png b/html/wp-content/plugins/wordpress-seo/images/support/support_forums.png new file mode 100644 index 0000000..b4fd6af Binary files /dev/null and b/html/wp-content/plugins/wordpress-seo/images/support/support_forums.png differ diff --git a/html/wp-content/plugins/wordpress-seo/images/video_plugin_assistant.svg b/html/wp-content/plugins/wordpress-seo/images/video_plugin_assistant.svg new file mode 100644 index 0000000..403d0fd --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/video_plugin_assistant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/images/woo_plugin_assistant.svg b/html/wp-content/plugins/wordpress-seo/images/woo_plugin_assistant.svg new file mode 100644 index 0000000..7d00c05 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/images/woo_plugin_assistant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-addon-manager.php b/html/wp-content/plugins/wordpress-seo/inc/class-addon-manager.php new file mode 100644 index 0000000..a9c687e --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-addon-manager.php @@ -0,0 +1,890 @@ + + */ + protected static $addons = [ + 'wp-seo-premium.php' => self::PREMIUM_SLUG, + 'wpseo-news.php' => self::NEWS_SLUG, + 'video-seo.php' => self::VIDEO_SLUG, + 'wpseo-woocommerce.php' => self::WOOCOMMERCE_SLUG, + 'local-seo.php' => self::LOCAL_SLUG, + ]; + + /** + * The addon data for the shortlinks. + * + * @var array> + */ + private $addon_details = [ + self::PREMIUM_SLUG => [ + 'name' => 'Yoast SEO Premium', + 'short_link_activation' => 'https://yoa.st/13j', + 'short_link_renewal' => 'https://yoa.st/4ey', + ], + self::NEWS_SLUG => [ + 'name' => 'Yoast News SEO', + 'short_link_activation' => 'https://yoa.st/4xq', + 'short_link_renewal' => 'https://yoa.st/4xv', + ], + self::WOOCOMMERCE_SLUG => [ + 'name' => 'Yoast WooCommerce SEO', + 'short_link_activation' => 'https://yoa.st/4xs', + 'short_link_renewal' => 'https://yoa.st/4xx', + ], + self::VIDEO_SLUG => [ + 'name' => 'Yoast Video SEO', + 'short_link_activation' => 'https://yoa.st/4xr', + 'short_link_renewal' => 'https://yoa.st/4xw', + ], + self::LOCAL_SLUG => [ + 'name' => 'Yoast Local SEO', + 'short_link_activation' => 'https://yoa.st/4xp', + 'short_link_renewal' => 'https://yoa.st/4xu', + ], + ]; + + /** + * Holds the site information data. + * + * @var stdClass + */ + private $site_information; + + /** + * Hooks into WordPress. + * + * @codeCoverageIgnore + * + * @return void + */ + public function register_hooks() { + add_action( 'admin_init', [ $this, 'validate_addons' ], 15 ); + add_filter( 'pre_set_site_transient_update_plugins', [ $this, 'check_for_updates' ] ); + add_filter( 'plugins_api', [ $this, 'get_plugin_information' ], 10, 3 ); + add_action( 'plugins_loaded', [ $this, 'register_expired_messages' ], 10 ); + } + + /** + * Registers "expired subscription" warnings to the update messages of our addons. + * + * @return void + */ + public function register_expired_messages() { + foreach ( array_keys( $this->get_installed_addons() ) as $plugin_file ) { + add_action( 'in_plugin_update_message-' . $plugin_file, [ $this, 'expired_subscription_warning' ], 10, 2 ); + } + } + + /** + * Gets the subscriptions for current site. + * + * @return stdClass The subscriptions. + */ + public function get_subscriptions() { + return $this->get_site_information()->subscriptions; + } + + /** + * Provides a list of addon filenames. + * + * @return string[] List of addon filenames with their slugs. + */ + public function get_addon_filenames() { + return self::$addons; + } + + /** + * Finds the plugin file. + * + * @param string $plugin_slug The plugin slug to search. + * + * @return bool|string Plugin file when installed, False when plugin isn't installed. + */ + public function get_plugin_file( $plugin_slug ) { + $plugins = $this->get_plugins(); + $plugin_files = array_keys( $plugins ); + $target_plugin_file = array_search( $plugin_slug, $this->get_addon_filenames(), true ); + + if ( ! $target_plugin_file ) { + return false; + } + + foreach ( $plugin_files as $plugin_file ) { + if ( strpos( $plugin_file, $target_plugin_file ) !== false ) { + return $plugin_file; + } + } + + return false; + } + + /** + * Retrieves the subscription for the given slug. + * + * @param string $slug The plugin slug to retrieve. + * + * @return stdClass|false Subscription data when found, false when not found. + */ + public function get_subscription( $slug ) { + foreach ( $this->get_subscriptions() as $subscription ) { + if ( $subscription->product->slug === $slug ) { + return $subscription; + } + } + + return false; + } + + /** + * Retrieves a list of (subscription) slugs by the active addons. + * + * @return array The slugs. + */ + public function get_subscriptions_for_active_addons() { + $active_addons = array_keys( $this->get_active_addons() ); + $subscription_slugs = array_map( [ $this, 'get_slug_by_plugin_file' ], $active_addons ); + $subscriptions = []; + foreach ( $subscription_slugs as $subscription_slug ) { + $subscriptions[ $subscription_slug ] = $this->get_subscription( $subscription_slug ); + } + + return $subscriptions; + } + + /** + * Retrieves a list of versions for each addon. + * + * @return array The addon versions. + */ + public function get_installed_addons_versions() { + $addon_versions = []; + foreach ( $this->get_installed_addons() as $plugin_file => $installed_addon ) { + $addon_versions[ $this->get_slug_by_plugin_file( $plugin_file ) ] = $installed_addon['Version']; + } + + return $addon_versions; + } + + /** + * Retrieves the plugin information from the subscriptions. + * + * @param stdClass|false $data The result object. Default false. + * @param string $action The type of information being requested from the Plugin Installation API. + * @param stdClass $args Plugin API arguments. + * + * @return object Extended plugin data. + */ + public function get_plugin_information( $data, $action, $args ) { + if ( $action !== 'plugin_information' ) { + return $data; + } + + if ( ! isset( $args->slug ) ) { + return $data; + } + + $subscription = $this->get_subscription( $args->slug ); + if ( ! $subscription ) { + return $data; + } + + $data = $this->convert_subscription_to_plugin( $subscription, null, true ); + + if ( $this->has_subscription_expired( $subscription ) ) { + unset( $data->package, $data->download_link ); + } + + return $data; + } + + /** + * Retrieves information from MyYoast about which addons are connected to the current site. + * + * @return stdClass The list of addons activated for this site. + */ + public function get_myyoast_site_information() { + $this->site_information ??= $this->get_site_information_transient(); + + if ( $this->site_information ) { + return $this->site_information; + } + + $this->site_information = $this->request_current_sites(); + if ( $this->site_information ) { + $this->site_information = $this->map_site_information( $this->site_information ); + + $this->set_site_information_transient( $this->site_information ); + + return $this->site_information; + } + + return $this->get_site_information_default(); + } + + /** + * Checks if the subscription for the given slug is valid. + * + * @param string $slug The plugin slug to retrieve. + * + * @return bool True when the subscription is valid. + */ + public function has_valid_subscription( $slug ) { + $subscription = $this->get_subscription( $slug ); + + // An non-existing subscription is never valid. + if ( ! $subscription ) { + return false; + } + + return ! $this->has_subscription_expired( $subscription ); + } + + /** + * Checks if there are addon updates. + * + * @param stdClass $data The current data for update_plugins. + * + * @return stdClass Extended data for update_plugins. + */ + public function check_for_updates( $data ) { + global $wp_version; + + if ( empty( $data ) ) { + return $data; + } + + // We have to figure out if we're safe to upgrade the add-ons, based on what the latest Yoast Free requirements for the WP version is. + $yoast_free_data = $this->extract_yoast_data( $data ); + + foreach ( $this->get_installed_addons() as $plugin_file => $installed_plugin ) { + $subscription_slug = $this->get_slug_by_plugin_file( $plugin_file ); + $subscription = $this->get_subscription( $subscription_slug ); + + if ( ! $subscription ) { + continue; + } + + $plugin_data = $this->convert_subscription_to_plugin( $subscription, $yoast_free_data, false, $plugin_file ); + + // Let's assume for now that it will get added in the 'no_update' key that we'll return to the WP API. + $is_no_update = true; + + // If the add-on's version is the latest, we have to do no further checks. + if ( version_compare( $installed_plugin['Version'], $plugin_data->new_version, '<' ) ) { + // If we haven't retrieved the Yoast Free requirements for the WP version yet, do nothing. The next run will probably get us that information. + if ( $plugin_data->requires === null ) { + continue; + } + + if ( version_compare( $plugin_data->requires, $wp_version, '<=' ) ) { + // The add-on has an available update *and* the Yoast Free requirements for the WP version are also met, so go ahead and show the upgrade info to the user. + $is_no_update = false; + $data->response[ $plugin_file ] = $plugin_data; + + if ( $this->has_subscription_expired( $subscription ) ) { + unset( $data->response[ $plugin_file ]->package, $data->response[ $plugin_file ]->download_link ); + } + } + } + + if ( $is_no_update ) { + // Still convert subscription when no updates is available. + $data->no_update[ $plugin_file ] = $plugin_data; + + if ( $this->has_subscription_expired( $subscription ) ) { + unset( $data->no_update[ $plugin_file ]->package, $data->no_update[ $plugin_file ]->download_link ); + } + } + } + + return $data; + } + + /** + * Extracts Yoast SEO Free's data from the wp.org API response. + * + * @param object $data The wp.org API response. + * + * @return object Yoast Free's data from wp.org. + */ + protected function extract_yoast_data( $data ) { + if ( isset( $data->response[ WPSEO_BASENAME ] ) ) { + return $data->response[ WPSEO_BASENAME ]; + } + + if ( isset( $data->no_update[ WPSEO_BASENAME ] ) ) { + return $data->no_update[ WPSEO_BASENAME ]; + } + + return (object) []; + } + + /** + * If the plugin is lacking an active subscription, throw a warning. + * + * @param array $plugin_data The data for the plugin in this row. + * + * @return void + */ + public function expired_subscription_warning( $plugin_data ) { + $subscription = $this->get_subscription( $plugin_data['slug'] ); + if ( $subscription && $this->has_subscription_expired( $subscription ) ) { + $addon_link = ( isset( $this->addon_details[ $plugin_data['slug'] ] ) ) ? $this->addon_details[ $plugin_data['slug'] ]['short_link_renewal'] : $this->addon_details[ self::PREMIUM_SLUG ]['short_link_renewal']; + + $sale_copy = ''; + if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-promotion' ) ) { + $sale_copy = sprintf( + /* translators: %1$s and %2$s are a opening and closing tag. */ + esc_html__( '%1$s30%% OFF - Black Friday %2$s', 'wordpress-seo' ), + '', + '', + ); + } + echo '

            '; + echo ' ' + . sprintf( + /* translators: %1$s is the plugin name, %2$s and %3$s are a link. */ + esc_html__( 'Your %1$s plugin cannot be updated as your subscription has expired. %2$sRenew your product subscription%3$s to restore updates and full feature access.', 'wordpress-seo' ), + esc_html( $plugin_data['name'] ), + '', + '', + ) + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output is escaped above. + . $sale_copy + . ''; + } + } + + /** + * Checks if there are any installed addons. + * + * @return bool True when there are installed Yoast addons. + */ + public function has_installed_addons() { + $installed_addons = $this->get_installed_addons(); + + return ! empty( $installed_addons ); + } + + /** + * Checks if the plugin is installed and activated in WordPress. + * + * @param string $slug The class' slug. + * + * @return bool True when installed and activated. + */ + public function is_installed( $slug ) { + $slug_to_class_map = [ + static::PREMIUM_SLUG => 'WPSEO_Premium', + static::NEWS_SLUG => 'WPSEO_News', + static::WOOCOMMERCE_SLUG => 'Yoast_WooCommerce_SEO', + static::VIDEO_SLUG => 'WPSEO_Video_Sitemap', + static::LOCAL_SLUG => 'WPSEO_Local_Core', + ]; + + if ( ! isset( $slug_to_class_map[ $slug ] ) ) { + return false; + } + + return class_exists( $slug_to_class_map[ $slug ] ); + } + + /** + * Validates the addons and show a notice for the ones that are invalid. + * + * @return void + */ + public function validate_addons() { + $notification_center = Yoast_Notification_Center::get(); + + if ( $notification_center === null ) { + return; + } + + foreach ( $this->addon_details as $slug => $addon_info ) { + $notification = $this->create_notification( $addon_info['name'], $addon_info['short_link_activation'] ); + + // Add a notification when the installed plugin isn't activated in My Yoast. + if ( $this->is_installed( $slug ) && ! $this->has_valid_subscription( $slug ) ) { + $notification_center->add_notification( $notification ); + + continue; + } + + $notification_center->remove_notification( $notification ); + } + } + + /** + * Checks if the user has any active addons. + * + * @return bool Whether there are active addons. + */ + public function has_active_addons() { + $active_addons = $this->get_active_addons(); + + return ! empty( $active_addons ); + } + + /** + * Removes the site information transients. + * + * @codeCoverageIgnore + * + * @return void + */ + public function remove_site_information_transients() { + delete_transient( self::SITE_INFORMATION_TRANSIENT ); + delete_transient( self::SITE_INFORMATION_TRANSIENT_QUICK ); + } + + /** + * Creates an instance of Yoast_Notification. + * + * @param string $product_name The product to create the notification for. + * @param string $short_link The short link for the addon notification. + * + * @return Yoast_Notification The created notification. + */ + protected function create_notification( $product_name, $short_link ) { + $notification_options = [ + 'type' => Yoast_Notification::ERROR, + 'id' => 'wpseo-dismiss-' . sanitize_title_with_dashes( $product_name, null, 'save' ), + 'capabilities' => 'wpseo_manage_options', + ]; + + return new Yoast_Notification( + sprintf( + /* translators: %1$s expands to a strong tag, %2$s expands to the product name, %3$s expands to a closing strong tag, %4$s expands to an a tag. %5$s expands to MyYoast, %6$s expands to a closing a tag, %7$s expands to the product name */ + __( '%1$s %2$s isn\'t working as expected %3$s and you are not receiving updates or support! Make sure to %4$s activate your product subscription in %5$s%6$s to unlock all the features of %7$s.', 'wordpress-seo' ), + '', + $product_name, + '', + '', + 'MyYoast', + '', + $product_name, + ), + $notification_options, + ); + } + + /** + * Checks whether a plugin expiry date has been passed. + * + * @param stdClass $subscription Plugin subscription. + * + * @return bool Has the plugin expired. + */ + protected function has_subscription_expired( $subscription ) { + return ( strtotime( $subscription->expiry_date ) - time() ) < 0; + } + + /** + * Converts a subscription to plugin based format. + * + * @param stdClass $subscription The subscription to convert. + * @param stdClass|null $yoast_free_data The Yoast Free's data. + * @param bool $plugin_info Whether we're in the plugin information modal. + * @param string $plugin_file The plugin filename. + * + * @return stdClass The converted subscription. + */ + protected function convert_subscription_to_plugin( $subscription, $yoast_free_data = null, $plugin_info = false, $plugin_file = '' ) { + $changelog = ''; + if ( isset( $subscription->product->changelog ) ) { + // We need to replace h2's and h3's with h4's because the styling expects that. + $changelog = str_replace( 'product->changelog ) ); + $changelog = str_replace( ' ( $plugin_info ) ? YOAST_SEO_WP_REQUIRED : null, + ]; + + return (object) [ + 'new_version' => ( $subscription->product->version ?? '' ), + 'name' => $subscription->product->name, + 'slug' => $subscription->product->slug, + 'plugin' => $plugin_file, + 'url' => $subscription->product->store_url, + 'last_update' => $subscription->product->last_updated, + 'homepage' => $subscription->product->store_url, + 'download_link' => $subscription->product->download, + 'package' => $subscription->product->download, + 'sections' => [ + 'changelog' => $changelog, + 'support' => $this->get_support_section(), + ], + 'icons' => [ + '2x' => $this->get_icon( $subscription->product->slug ), + ], + 'update_supported' => true, + 'banners' => $this->get_banners( $subscription->product->slug ), + // If we have extracted Yoast Free's data before, use that. If not, resort to the defaults. + 'tested' => YOAST_SEO_WP_TESTED, + 'requires' => ( $yoast_free_data->requires ?? $defaults['requires'] ), + 'requires_php' => YOAST_SEO_PHP_REQUIRED, + ]; + } + + /** + * Returns the plugin's icon URL. + * + * @param string $slug The plugin slug. + * + * @return string The icon URL for this plugin. + */ + protected function get_icon( $slug ) { + switch ( $slug ) { + case self::LOCAL_SLUG: + return 'https://yoa.st/local-seo-icon'; + case self::NEWS_SLUG: + return 'https://yoa.st/news-seo-icon'; + case self::PREMIUM_SLUG: + return 'https://yoa.st/yoast-seo-icon'; + case self::VIDEO_SLUG: + return 'https://yoa.st/video-seo-icon'; + case self::WOOCOMMERCE_SLUG: + return 'https://yoa.st/woo-seo-icon'; + } + } + + /** + * Return an array of plugin banner URLs. + * + * @param string $slug The plugin slug. + * + * @return string[] + */ + protected function get_banners( $slug ) { + switch ( $slug ) { + case self::LOCAL_SLUG: + return [ + 'high' => 'https://yoa.st/yoast-seo-banner-local', + 'low' => 'https://yoa.st/yoast-seo-banner-low-local', + ]; + case self::NEWS_SLUG: + return [ + 'high' => 'https://yoa.st/yoast-seo-banner-news', + 'low' => 'https://yoa.st/yoast-seo-banner-low-news', + ]; + case self::PREMIUM_SLUG: + return [ + 'high' => 'https://yoa.st/yoast-seo-banner-premium', + 'low' => 'https://yoa.st/yoast-seo-banner-low-premium', + ]; + case self::VIDEO_SLUG: + return [ + 'high' => 'https://yoa.st/yoast-seo-banner-video', + 'low' => 'https://yoa.st/yoast-seo-banner-low-video', + ]; + case self::WOOCOMMERCE_SLUG: + return [ + 'high' => 'https://yoa.st/yoast-seo-banner-woo', + 'low' => 'https://yoa.st/yoast-seo-banner-low-woo', + ]; + } + } + + /** + * Checks if the given plugin_file belongs to a Yoast addon. + * + * @param string $plugin_file Path to the plugin. + * + * @return bool True when plugin file is for a Yoast addon. + */ + protected function is_yoast_addon( $plugin_file ) { + return $this->get_slug_by_plugin_file( $plugin_file ) !== ''; + } + + /** + * Retrieves the addon slug by given plugin file path. + * + * @param string $plugin_file The file path to the plugin. + * + * @return string The slug when found or empty string when not. + */ + protected function get_slug_by_plugin_file( $plugin_file ) { + $addons = self::$addons; + + // Yoast SEO Free isn't an addon, but we needed it in Premium to fetch translations. + if ( YoastSEO()->helpers->product->is_premium() ) { + $addons['wp-seo.php'] = self::FREE_SLUG; + } + + foreach ( $addons as $addon => $addon_slug ) { + if ( strpos( $plugin_file, $addon ) !== false ) { + return $addon_slug; + } + } + + return ''; + } + + /** + * Retrieves the installed Yoast addons. + * + * @return array The installed plugins. + */ + protected function get_installed_addons() { + return array_filter( $this->get_plugins(), [ $this, 'is_yoast_addon' ], ARRAY_FILTER_USE_KEY ); + } + + /** + * Retrieves a list of active addons. + * + * @return array The active addons. + */ + protected function get_active_addons() { + return array_filter( $this->get_installed_addons(), [ $this, 'is_plugin_active' ], ARRAY_FILTER_USE_KEY ); + } + + /** + * Retrieves the current sites from the API. + * + * @codeCoverageIgnore + * + * @return bool|stdClass Object when request is successful. False if not. + */ + protected function request_current_sites() { + $api_request = new WPSEO_MyYoast_Api_Request( 'sites/current' ); + if ( $api_request->fire() ) { + return $api_request->get_response(); + } + + return $this->get_site_information_default(); + } + + /** + * Retrieves the transient value with the site information. + * + * @codeCoverageIgnore + * + * @return stdClass|false The transient value. + */ + protected function get_site_information_transient() { + global $pagenow; + + // Force re-check on license & dashboard pages. + $current_page = null; + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reason: We are not processing form information. + if ( isset( $_GET['page'] ) && is_string( $_GET['page'] ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Reason: We are not processing form information, We are only strictly comparing and thus no need to sanitize. + $current_page = wp_unslash( $_GET['page'] ); + } + + // Check whether the licenses are valid or whether we need to show notifications. + $quick = ( $current_page === Plans_Page_Integration::PAGE || $current_page === General_Page_Integration::PAGE ); + + // Also do a fresh request on Plugins & Core Update pages. + $quick = $quick || $pagenow === 'plugins.php'; + $quick = $quick || $pagenow === 'update-core.php'; + + if ( $quick ) { + return get_transient( self::SITE_INFORMATION_TRANSIENT_QUICK ); + } + + return get_transient( self::SITE_INFORMATION_TRANSIENT ); + } + + /** + * Sets the site information transient. + * + * @codeCoverageIgnore + * + * @param stdClass $site_information The site information to save. + * + * @return void + */ + protected function set_site_information_transient( $site_information ) { + set_transient( self::SITE_INFORMATION_TRANSIENT, $site_information, DAY_IN_SECONDS ); + set_transient( self::SITE_INFORMATION_TRANSIENT_QUICK, $site_information, 60 ); + } + + /** + * Retrieves all installed WordPress plugins. + * + * @codeCoverageIgnore + * + * @return array The plugins. + */ + protected function get_plugins() { + if ( ! function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + return get_plugins(); + } + + /** + * Checks if the given plugin file belongs to an active plugin. + * + * @codeCoverageIgnore + * + * @param string $plugin_file The file path to the plugin. + * + * @return bool True when plugin is active. + */ + protected function is_plugin_active( $plugin_file ) { + return is_plugin_active( $plugin_file ); + } + + /** + * Returns an object with no subscriptions. + * + * @codeCoverageIgnore + * + * @return stdClass Site information. + */ + protected function get_site_information_default() { + return (object) [ + 'url' => WPSEO_Utils::get_home_url(), + 'subscriptions' => [], + ]; + } + + /** + * Maps the plugin API response. + * + * @param object $site_information Site information as received from the API. + * + * @return stdClass Mapped site information. + */ + protected function map_site_information( $site_information ) { + return (object) [ + 'url' => $site_information->url, + 'subscriptions' => array_map( [ $this, 'map_subscription' ], $site_information->subscriptions ), + ]; + } + + /** + * Maps a plugin subscription. + * + * @param object $subscription Subscription information as received from the API. + * + * @return stdClass Mapped subscription. + */ + protected function map_subscription( $subscription ) { + // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- Not our properties. + return (object) [ + 'renewal_url' => $subscription->renewalUrl, + 'expiry_date' => $subscription->expiryDate, + 'product' => (object) [ + 'version' => $subscription->product->version, + 'name' => $subscription->product->name, + 'slug' => $subscription->product->slug, + 'last_updated' => $subscription->product->lastUpdated, + 'store_url' => $subscription->product->storeUrl, + // Ternary operator is necessary because download can be undefined. + 'download' => ( $subscription->product->download ?? null ), + 'changelog' => $subscription->product->changelog, + ], + ]; + // phpcs:enable + } + + /** + * Retrieves the site information. + * + * @return stdClass The site information. + */ + private function get_site_information() { + if ( ! $this->has_installed_addons() ) { + return $this->get_site_information_default(); + } + + return $this->get_myyoast_site_information(); + } + + /** + * Retrieves the contents for the support section. + * + * @return string The support section content. + */ + protected function get_support_section() { + return '

            ' . __( 'Need support?', 'wordpress-seo' ) . '

            ' + . '

            ' + /* translators: 1: expands to that refers to the help page, 2: closing tag. */ + . sprintf( __( 'You can probably find an answer to your question in our %1$shelp center%2$s.', 'wordpress-seo' ), '', '' ) + . ' ' + /* translators: %s expands to a mailto support link. */ + . sprintf( __( 'If you still need support and have an active subscription for this product, please email %s.', 'wordpress-seo' ), 'support@yoast.com' ) + . '

            '; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-my-yoast-api-request.php b/html/wp-content/plugins/wordpress-seo/inc/class-my-yoast-api-request.php new file mode 100644 index 0000000..17a993f --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-my-yoast-api-request.php @@ -0,0 +1,224 @@ + 'GET', + 'timeout' => 5, + 'headers' => [ + 'Accept-Encoding' => '*', + 'Expect' => '', + ], + ]; + + /** + * Contains the fetched response. + * + * @var stdClass + */ + protected $response; + + /** + * Contains the error message when request went wrong. + * + * @var string + */ + protected $error_message = ''; + + /** + * Constructor. + * + * @codeCoverageIgnore + * + * @param string $url The request url. + * @param array $args The request arguments. + */ + public function __construct( $url, array $args = [] ) { + $this->url = 'https://my.yoast.com/api/' . $url; + $this->args = wp_parse_args( $args, $this->args ); + } + + /** + * Fires the request. + * + * @return bool True when request is successful. + */ + public function fire() { + try { + $response = $this->do_request( $this->url, $this->args ); + $response = $this->decode_response( $response ); + $this->response = $this->validate_response( $response ); + return true; + } catch ( WPSEO_MyYoast_Bad_Request_Exception $bad_request_exception ) { + $this->error_message = $bad_request_exception->getMessage(); + + return false; + } + } + + /** + * Retrieves the error message. + * + * @return string The set error message. + */ + public function get_error_message() { + return $this->error_message; + } + + /** + * Retrieves the response. + * + * @return stdClass The response object. + */ + public function get_response() { + return $this->response; + } + + /** + * Performs the request using WordPress internals. + * + * @codeCoverageIgnore + * + * @param string $url The request URL. + * @param array $request_arguments The request arguments. + * + * @return string The retrieved body. + * @throws WPSEO_MyYoast_Bad_Request_Exception When request is invalid. + */ + protected function do_request( $url, $request_arguments ) { + $request_arguments = $this->enrich_request_arguments( $request_arguments ); + $response = wp_remote_request( $url, $request_arguments ); + + if ( is_wp_error( $response ) ) { + throw new WPSEO_MyYoast_Bad_Request_Exception( $response->get_error_message() ); + } + + $response_code = wp_remote_retrieve_response_code( $response ); + $response_message = wp_remote_retrieve_response_message( $response ); + + // Do nothing, response code is okay. + if ( $response_code === 200 ) { + return wp_remote_retrieve_body( $response ); + } + + throw new WPSEO_MyYoast_Bad_Request_Exception( esc_html( $response_message ), (int) $response_code ); + } + + /** + * Decodes the JSON encoded response. + * + * @param string $response The response to decode. + * + * @return stdClass The json decoded response. + * @throws WPSEO_MyYoast_Invalid_JSON_Exception When decoded string is not a JSON object. + */ + protected function decode_response( $response ) { + $response = json_decode( $response ); + + if ( ! is_object( $response ) ) { + throw new WPSEO_MyYoast_Invalid_JSON_Exception( + esc_html__( 'No JSON object was returned.', 'wordpress-seo' ), + ); + } + + return $response; + } + + /** + * Validates that all the needed fields are in de decoded response. + * + * @param stdClass $response The response to validate. + * + * @return stdClass The json decoded response. + * @throws WPSEO_MyYoast_Invalid_JSON_Exception When not all needed fields are found. + */ + private function validate_response( $response ) { + if ( isset( $response->url, $response->subscriptions ) && is_array( $response->subscriptions ) ) { + return $response; + } + + throw new WPSEO_MyYoast_Invalid_JSON_Exception( + esc_html__( 'Not all needed fields are present.', 'wordpress-seo' ), + ); + } + + /** + * Checks if MyYoast tokens are allowed and adds the token to the request body. + * + * When tokens are disallowed it will add the url to the request body. + * + * @param array $request_arguments The arguments to enrich. + * + * @return array The enriched arguments. + */ + protected function enrich_request_arguments( array $request_arguments ) { + $request_arguments = wp_parse_args( $request_arguments, [ 'headers' => [] ] ); + $addon_version_headers = $this->get_installed_addon_versions(); + + foreach ( $addon_version_headers as $addon => $version ) { + $request_arguments['headers'][ $addon . '-version' ] = $version; + } + + $request_body = $this->get_request_body(); + if ( $request_body !== [] ) { + $request_arguments['body'] = $request_body; + } + + return $request_arguments; + } + + /** + * Retrieves the request body based on URL or access token support. + * + * @codeCoverageIgnore + * + * @return array The request body. + */ + public function get_request_body() { + return [ 'url' => WPSEO_Utils::get_home_url() ]; + } + + /** + * Wraps the get current user id function. + * + * @codeCoverageIgnore + * + * @return int The user id. + */ + protected function get_current_user_id() { + return get_current_user_id(); + } + + /** + * Retrieves the installed addons as http headers. + * + * @codeCoverageIgnore + * + * @return array The installed addon versions. + */ + protected function get_installed_addon_versions() { + $addon_manager = new WPSEO_Addon_Manager(); + + return $addon_manager->get_installed_addons_versions(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-post-type.php b/html/wp-content/plugins/wordpress-seo/inc/class-post-type.php new file mode 100644 index 0000000..944e1f6 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-post-type.php @@ -0,0 +1,133 @@ +helpers->post_type->get_accessible_post_types(); + } + + /** + * Returns whether the passed post type is considered accessible. + * + * @param string $post_type The post type to check. + * + * @return bool Whether or not the post type is considered accessible. + */ + public static function is_post_type_accessible( $post_type ) { + return in_array( $post_type, self::get_accessible_post_types(), true ); + } + + /** + * Checks if the request post type is public and indexable. + * + * @param string $post_type_name The name of the post type to lookup. + * + * @return bool True when post type is set to index. + */ + public static function is_post_type_indexable( $post_type_name ) { + return YoastSEO()->helpers->post_type->is_indexable( $post_type_name ); + } + + /** + * Filters the attachment post type from an array with post_types. + * + * @param array $post_types The array to filter the attachment post type from. + * + * @return array The filtered array. + */ + public static function filter_attachment_post_type( array $post_types ) { + if ( WPSEO_Options::get( 'disable-attachment' ) === true ) { + unset( $post_types['attachment'] ); + } + + return $post_types; + } + + /** + * Checks if the post type is enabled in the REST API. + * + * @param string $post_type The post type to check. + * + * @return bool Whether or not the post type is available in the REST API. + */ + public static function is_rest_enabled( $post_type ) { + $post_type_object = get_post_type_object( $post_type ); + + if ( $post_type_object === null ) { + return false; + } + + return $post_type_object->show_in_rest === true; + } + + /** + * Checks if the current post type has an archive. + * + * Context: The has_archive value can be a string or a boolean. In most case it will be a boolean, + * but it can be defined as a string. When it is a string the archive_slug will be overwritten to + * define another endpoint. + * + * @param WP_Post_Type $post_type The post type object. + * + * @return bool True whether the post type has an archive. + */ + public static function has_archive( $post_type ) { + return YoastSEO()->helpers->post_type->has_archive( $post_type ); + } + + /** + * Checks if the Yoast Metabox has been enabled for the post type. + * + * @param string $post_type The post type name. + * + * @return bool True whether the metabox is enabled. + */ + public static function has_metabox_enabled( $post_type ) { + return WPSEO_Options::get( 'display-metabox-pt-' . $post_type, false ); + } + + /* ********************* DEPRECATED METHODS ********************* */ + + /** + * Removes the notification related to the post types which have been made public. + * + * @deprecated 20.10 + * @codeCoverageIgnore + * + * @return void + */ + public static function remove_post_types_made_public_notification() { + _deprecated_function( __METHOD__, 'Yoast SEO 20.10', 'Content_Type_Visibility_Dismiss_Notifications::dismiss_notifications' ); + $notification_center = Yoast_Notification_Center::get(); + $notification_center->remove_notification_by_id( 'post-types-made-public' ); + } + + /** + * Removes the notification related to the taxonomies which have been made public. + * + * @deprecated 20.10 + * @codeCoverageIgnore + * + * @return void + */ + public static function remove_taxonomies_made_public_notification() { + _deprecated_function( __METHOD__, 'Yoast SEO 20.10', 'Content_Type_Visibility_Dismiss_Notifications::dismiss_notifications' ); + $notification_center = Yoast_Notification_Center::get(); + $notification_center->remove_notification_by_id( 'taxonomies-made-public' ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-rewrite.php b/html/wp-content/plugins/wordpress-seo/inc/class-rewrite.php new file mode 100644 index 0000000..89827ce --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-rewrite.php @@ -0,0 +1,256 @@ + $query_vars Main query vars to filter. + * + * @return array The query vars. + */ + public function query_vars( $query_vars ) { + if ( WPSEO_Options::get( 'stripcategorybase' ) === true ) { + $query_vars[] = 'wpseo_category_redirect'; + } + + return $query_vars; + } + + /** + * Checks whether the redirect needs to be created. + * + * @param array $query_vars Query vars to check for existence of redirect var. + * + * @return array The query vars. + */ + public function request( $query_vars ) { + if ( WPSEO_Options::get( 'stripcategorybase' ) !== true ) { + return $query_vars; + } + + if ( ! isset( $query_vars['wpseo_category_redirect'] ) ) { + return $query_vars; + } + + $this->redirect( $query_vars['wpseo_category_redirect'] ); + return []; + } + + /** + * Wrapper for the category_rewrite_rules() below, so we can add the $rules param in a BC way. + * + * @param array $rules Rewrite rules generated for the current permastruct, keyed by their regex pattern. + * + * @return array The category rewrite rules. + */ + public function category_rewrite_rules_wrapper( $rules ) { + if ( WPSEO_Options::get( 'stripcategorybase' ) !== true ) { + return $rules; + } + + return $this->category_rewrite_rules(); + } + + /** + * This function taken and only slightly adapted from WP No Category Base plugin by Saurabh Gupta. + * + * @return array The category rewrite rules. + */ + public function category_rewrite_rules() { + global $wp_rewrite; + + $category_rewrite = []; + + $taxonomy = get_taxonomy( 'category' ); + $permalink_structure = get_option( 'permalink_structure' ); + + $blog_prefix = ''; + if ( strpos( $permalink_structure, '/blog/' ) === 0 ) { + if ( ( is_multisite() && ! is_subdomain_install() ) || is_main_site() || is_main_network() ) { + $blog_prefix = 'blog/'; + } + } + + $categories = get_categories( [ 'hide_empty' => false ] ); + if ( is_array( $categories ) && $categories !== [] ) { + foreach ( $categories as $category ) { + $category_nicename = $category->slug; + if ( $category->parent === $category->cat_ID ) { + // Recursive recursion. + $category->parent = 0; + } + elseif ( $taxonomy->rewrite['hierarchical'] !== false && $category->parent !== 0 ) { + $parents = get_category_parents( $category->parent, false, '/', true ); + if ( ! is_wp_error( $parents ) ) { + $category_nicename = $parents . $category_nicename; + } + unset( $parents ); + } + + $category_rewrite = $this->add_category_rewrites( $category_rewrite, $category_nicename, $blog_prefix, $wp_rewrite->pagination_base ); + + // Adds rules for the uppercase encoded URIs. + $category_nicename_filtered = $this->convert_encoded_to_upper( $category_nicename ); + + if ( $category_nicename_filtered !== $category_nicename ) { + $category_rewrite = $this->add_category_rewrites( $category_rewrite, $category_nicename_filtered, $blog_prefix, $wp_rewrite->pagination_base ); + } + } + unset( $categories, $category, $category_nicename, $category_nicename_filtered ); + } + + // Redirect support from Old Category Base. + $old_base = $wp_rewrite->get_category_permastruct(); + $old_base = str_replace( '%category%', '(.+)', $old_base ); + $old_base = trim( $old_base, '/' ); + $category_rewrite[ $old_base . '$' ] = 'index.php?wpseo_category_redirect=$matches[1]'; + + return $category_rewrite; + } + + /** + * Adds required category rewrites rules. + * + * @param array $rewrites The current set of rules. + * @param string $category_name Category nicename. + * @param string $blog_prefix Multisite blog prefix. + * @param string $pagination_base WP_Query pagination base. + * + * @return array The added set of rules. + */ + protected function add_category_rewrites( $rewrites, $category_name, $blog_prefix, $pagination_base ) { + $rewrite_name = $blog_prefix . '(' . $category_name . ')'; + + global $wp_rewrite; + $feed_regex = '(' . implode( '|', $wp_rewrite->feeds ) . ')'; + + $rewrites[ $rewrite_name . '/(?:feed/)?' . $feed_regex . '/?$' ] = 'index.php?category_name=$matches[1]&feed=$matches[2]'; + $rewrites[ $rewrite_name . '/' . $pagination_base . '/?([0-9]{1,})/?$' ] = 'index.php?category_name=$matches[1]&paged=$matches[2]'; + $rewrites[ $rewrite_name . '/?$' ] = 'index.php?category_name=$matches[1]'; + + return $rewrites; + } + + /** + * Walks through category nicename and convert encoded parts + * into uppercase using $this->encode_to_upper(). + * + * @param string $name The encoded category URI string. + * + * @return string The convered URI string. + */ + protected function convert_encoded_to_upper( $name ) { + // Checks if name has any encoding in it. + if ( strpos( $name, '%' ) === false ) { + return $name; + } + + $names = explode( '/', $name ); + $names = array_map( [ $this, 'encode_to_upper' ], $names ); + + return implode( '/', $names ); + } + + /** + * Converts the encoded URI string to uppercase. + * + * @param string $encoded The encoded string. + * + * @return string The uppercased string. + */ + public function encode_to_upper( $encoded ) { + if ( strpos( $encoded, '%' ) === false ) { + return $encoded; + } + + return strtoupper( $encoded ); + } + + /** + * Redirect the "old" category URL to the new one. + * + * @codeCoverageIgnore + * + * @param string $category_redirect The category page to redirect to. + * @return void + */ + protected function redirect( $category_redirect ) { + $catlink = trailingslashit( get_option( 'home' ) ) . user_trailingslashit( $category_redirect, 'category' ); + + wp_safe_redirect( $catlink, 301, 'Yoast SEO' ); + exit(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-upgrade-history.php b/html/wp-content/plugins/wordpress-seo/inc/class-upgrade-history.php new file mode 100644 index 0000000..da4b1e0 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-upgrade-history.php @@ -0,0 +1,136 @@ +option_name = $option_name; + } + } + + /** + * Retrieves the content of the history items currently stored. + * + * @return array> The contents of the history option. + */ + public function get() { + $data = get_option( $this->get_option_name(), [] ); + if ( ! is_array( $data ) ) { + return []; + } + + return $data; + } + + /** + * Adds a new history entry in the storage. + * + * @param string $old_version The version we are upgrading from. + * @param string $new_version The version we are upgrading to. + * @param array $option_names The options that need to be stored. + * + * @return void + */ + public function add( $old_version, $new_version, array $option_names ) { + $option_data = []; + if ( $option_names !== [] ) { + $option_data = $this->get_options_data( $option_names ); + } + + // Retrieve current history. + $data = $this->get(); + + // Add new entry. + $data[ time() ] = [ + 'options' => $option_data, + 'old_version' => $old_version, + 'new_version' => $new_version, + ]; + + // Store the data. + $this->set( $data ); + } + + /** + * Retrieves the data for the specified option names from the database. + * + * @param array $option_names The option names to retrieve. + * + * @return array> The retrieved data. + */ + protected function get_options_data( array $option_names ) { + $wpdb = $this->get_wpdb(); + + $results = $wpdb->get_results( + $wpdb->prepare( + ' + SELECT %i, %i FROM ' . $wpdb->options . ' WHERE + %i IN ( ' . implode( ',', array_fill( 0, count( $option_names ), '%s' ) ) . ' ) + ', + array_merge( [ 'option_value', 'option_name', 'option_name' ], $option_names ), + ), + ARRAY_A, + ); + + $data = []; + foreach ( $results as $result ) { + $data[ $result['option_name'] ] = maybe_unserialize( $result['option_value'] ); + } + + return $data; + } + + /** + * Stores the new history state. + * + * @param array> $data The data to store. + * + * @return void + */ + protected function set( array $data ) { + // This should not be autoloaded! + update_option( $this->get_option_name(), $data, false ); + } + + /** + * Retrieves the WPDB object. + * + * @return wpdb The WPDB object to use. + */ + protected function get_wpdb() { + global $wpdb; + + return $wpdb; + } + + /** + * Retrieves the option name to store the history in. + * + * @return string The option name to store the history in. + */ + protected function get_option_name() { + return $this->option_name; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-upgrade.php b/html/wp-content/plugins/wordpress-seo/inc/class-upgrade.php new file mode 100644 index 0000000..45f1ee2 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-upgrade.php @@ -0,0 +1,1871 @@ +taxonomy_helper = YoastSEO()->helpers->taxonomy; + + $version = WPSEO_Options::get( 'version' ); + + WPSEO_Options::maybe_set_multisite_defaults( false ); + + $routines = [ + '1.5.0' => 'upgrade_15', + '2.0' => 'upgrade_20', + '2.1' => 'upgrade_21', + '2.2' => 'upgrade_22', + '2.3' => 'upgrade_23', + '3.0' => 'upgrade_30', + '3.3' => 'upgrade_33', + '3.6' => 'upgrade_36', + '4.0' => 'upgrade_40', + '4.4' => 'upgrade_44', + '4.7' => 'upgrade_47', + '4.9' => 'upgrade_49', + '5.0' => 'upgrade_50', + '5.5' => 'upgrade_55', + '6.3' => 'upgrade_63', + '7.0-RC0' => 'upgrade_70', + '7.1-RC0' => 'upgrade_71', + '7.3-RC0' => 'upgrade_73', + '7.4-RC0' => 'upgrade_74', + '7.5.3' => 'upgrade_753', + '7.7-RC0' => 'upgrade_77', + '7.7.2-RC0' => 'upgrade_772', + '9.0-RC0' => 'upgrade_90', + '10.0-RC0' => 'upgrade_100', + '11.1-RC0' => 'upgrade_111', + // Reset notifications because we removed the AMP Glue plugin notification. + '12.1-RC0' => 'clean_all_notifications', + '12.3-RC0' => 'upgrade_123', + '12.4-RC0' => 'upgrade_124', + '12.8-RC0' => 'upgrade_128', + '13.2-RC0' => 'upgrade_132', + '14.0.3-RC0' => 'upgrade_1403', + '14.1-RC0' => 'upgrade_141', + '14.2-RC0' => 'upgrade_142', + '14.5-RC0' => 'upgrade_145', + '14.9-RC0' => 'upgrade_149', + '15.1-RC0' => 'upgrade_151', + '15.3-RC0' => 'upgrade_153', + '15.5-RC0' => 'upgrade_155', + '15.7-RC0' => 'upgrade_157', + '15.9.1-RC0' => 'upgrade_1591', + '16.2-RC0' => 'upgrade_162', + '16.5-RC0' => 'upgrade_165', + '17.2-RC0' => 'upgrade_172', + '17.7.1-RC0' => 'upgrade_1771', + '17.9-RC0' => 'upgrade_179', + '18.3-RC3' => 'upgrade_183', + '18.6-RC0' => 'upgrade_186', + '18.9-RC0' => 'upgrade_189', + '19.1-RC0' => 'upgrade_191', + '19.3-RC0' => 'upgrade_193', + '19.6-RC0' => 'upgrade_196', + '19.11-RC0' => 'upgrade_1911', + '20.2-RC0' => 'upgrade_202', + '20.5-RC0' => 'upgrade_205', + '20.7-RC0' => 'upgrade_207', + '20.8-RC0' => 'upgrade_208', + '22.6-RC0' => 'upgrade_226', + ]; + + array_walk( $routines, [ $this, 'run_upgrade_routine' ], $version ); + if ( version_compare( $version, '12.5-RC0', '<' ) ) { + /* + * We have to run this by hook, because otherwise: + * - the theme support check isn't available. + * - the notification center notifications are not filled yet. + */ + add_action( 'init', [ $this, 'upgrade_125' ] ); + } + + /** + * Filter: 'wpseo_run_upgrade' - Runs the upgrade hook which are dependent on Yoast SEO. + * + * @param string $version The current version of Yoast SEO + */ + do_action( 'wpseo_run_upgrade', $version ); + + $this->finish_up( $version ); + } + + /** + * Runs the upgrade routine. + * + * @param string $routine The method to call. + * @param string $version The new version. + * @param string $current_version The current set version. + * + * @return void + */ + protected function run_upgrade_routine( $routine, $version, $current_version ) { + if ( version_compare( $current_version, $version, '<' ) ) { + $this->$routine( $current_version ); + } + } + + /** + * Adds a new upgrade history entry. + * + * @param string $current_version The old version from which we are upgrading. + * @param string $new_version The version we are upgrading to. + * + * @return void + */ + protected function add_upgrade_history( $current_version, $new_version ) { + $upgrade_history = new WPSEO_Upgrade_History(); + $upgrade_history->add( $current_version, $new_version, array_keys( WPSEO_Options::$options ) ); + } + + /** + * Runs the needed cleanup after an update, setting the DB version to latest version, flushing caches etc. + * + * @param string|null $previous_version The previous version. + * + * @return void + */ + protected function finish_up( $previous_version = null ) { + if ( $previous_version ) { + WPSEO_Options::set( 'previous_version', $previous_version, 'wpseo' ); + // Store timestamp when plugin is updated from a previous version. + WPSEO_Options::set( 'last_updated_on', time(), 'wpseo' ); + } + WPSEO_Options::set( 'version', WPSEO_VERSION, 'wpseo' ); + + // Just flush rewrites, always, to at least make them work after an upgrade. + add_action( 'shutdown', 'flush_rewrite_rules' ); + + // Flush the sitemap cache. + WPSEO_Sitemaps_Cache::clear(); + + // Make sure all our options always exist - issue #1245. + WPSEO_Options::ensure_options_exist(); + } + + /** + * Run the Yoast SEO 1.5 upgrade routine. + * + * @param string $version Current plugin version. + * + * @return void + */ + private function upgrade_15( $version ) { + // Clean up options and meta. + WPSEO_Options::clean_up( null, $version ); + WPSEO_Meta::clean_up(); + } + + /** + * Moves options that moved position in WPSEO 2.0. + * + * @return void + */ + private function upgrade_20() { + /** + * Clean up stray wpseo_ms options from the options table, option should only exist in the sitemeta table. + * This could have been caused in many version of Yoast SEO, so deleting it for everything below 2.0. + */ + delete_option( 'wpseo_ms' ); + + $wpseo = $this->get_option_from_database( 'wpseo' ); + $this->save_option_setting( $wpseo, 'pinterestverify' ); + + // Re-save option to trigger sanitization. + $this->cleanup_option_data( 'wpseo' ); + } + + /** + * Detects if taxonomy terms were split and updates the corresponding taxonomy meta's accordingly. + * + * @return void + */ + private function upgrade_21() { + $taxonomies = get_option( 'wpseo_taxonomy_meta', [] ); + + if ( ! empty( $taxonomies ) ) { + foreach ( $taxonomies as $taxonomy => $tax_metas ) { + foreach ( $tax_metas as $term_id => $tax_meta ) { + if ( function_exists( 'wp_get_split_term' ) ) { + $new_term_id = wp_get_split_term( $term_id, $taxonomy ); + if ( $new_term_id !== false ) { + $taxonomies[ $taxonomy ][ $new_term_id ] = $taxonomies[ $taxonomy ][ $term_id ]; + unset( $taxonomies[ $taxonomy ][ $term_id ] ); + } + } + } + } + + update_option( 'wpseo_taxonomy_meta', $taxonomies ); + } + } + + /** + * Performs upgrade functions to Yoast SEO 2.2. + * + * @return void + */ + private function upgrade_22() { + // Unschedule our tracking. + wp_clear_scheduled_hook( 'yoast_tracking' ); + + $this->cleanup_option_data( 'wpseo' ); + } + + /** + * Schedules upgrade function to Yoast SEO 2.3. + * + * @return void + */ + private function upgrade_23() { + add_action( 'wp', [ $this, 'upgrade_23_query' ], 90 ); + add_action( 'admin_head', [ $this, 'upgrade_23_query' ], 90 ); + } + + /** + * Performs upgrade query to Yoast SEO 2.3. + * + * @return void + */ + public function upgrade_23_query() { + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Reason: executed only during the upgrade routine. + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Reason: executed only during the upgrade routine. + $wp_query = new WP_Query( 'post_type=any&meta_key=_yoast_wpseo_sitemap-include&meta_value=never&order=ASC' ); + + if ( ! empty( $wp_query->posts ) ) { + $options = get_option( 'wpseo_xml' ); + + $excluded_posts = []; + if ( $options['excluded-posts'] !== '' ) { + $excluded_posts = explode( ',', $options['excluded-posts'] ); + } + + foreach ( $wp_query->posts as $post ) { + if ( ! in_array( (string) $post->ID, $excluded_posts, true ) ) { + $excluded_posts[] = $post->ID; + } + } + + // Updates the meta value. + $options['excluded-posts'] = implode( ',', $excluded_posts ); + + // Update the option. + update_option( 'wpseo_xml', $options ); + } + + // Remove the meta fields. + delete_post_meta_by_key( '_yoast_wpseo_sitemap-include' ); + } + + /** + * Performs upgrade functions to Yoast SEO 3.0. + * + * @return void + */ + private function upgrade_30() { + // Remove the meta fields for sitemap prio. + delete_post_meta_by_key( '_yoast_wpseo_sitemap-prio' ); + } + + /** + * Performs upgrade functions to Yoast SEO 3.3. + * + * @return void + */ + private function upgrade_33() { + // Notification dismissals have been moved to User Meta instead of global option. + delete_option( Yoast_Notification_Center::STORAGE_KEY ); + } + + /** + * Performs upgrade functions to Yoast SEO 3.6. + * + * @return void + */ + protected function upgrade_36() { + global $wpdb; + + // Between 3.2 and 3.4 the sitemap options were saved with autoloading enabled. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + 'DELETE FROM %i WHERE %i LIKE %s AND autoload IN ("on", "yes")', + [ $wpdb->options, 'option_name', 'wpseo_sitemap_%' ], + ), + ); + } + + /** + * Removes the about notice when its still in the database. + * + * @return void + */ + private function upgrade_40() { + $center = Yoast_Notification_Center::get(); + $center->remove_notification_by_id( 'wpseo-dismiss-about' ); + } + + /** + * Moves the content-analysis-active and keyword-analysis-acive options from wpseo-titles to wpseo. + * + * @return void + */ + private function upgrade_44() { + $wpseo_titles = $this->get_option_from_database( 'wpseo_titles' ); + + $this->save_option_setting( $wpseo_titles, 'content-analysis-active', 'content_analysis_active' ); + $this->save_option_setting( $wpseo_titles, 'keyword-analysis-active', 'keyword_analysis_active' ); + + // Remove irrelevant content from the option. + $this->cleanup_option_data( 'wpseo_titles' ); + } + + /** + * Renames the meta name for the cornerstone content. It was a public meta field and it has to be private. + * + * @return void + */ + private function upgrade_47() { + global $wpdb; + + // The meta key has to be private, so prefix it. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + 'UPDATE ' . $wpdb->postmeta . ' SET meta_key = %s WHERE meta_key = "yst_is_cornerstone"', + WPSEO_Cornerstone_Filter::META_NAME, + ), + ); + } + + /** + * Removes the 'wpseo-dismiss-about' notice for every user that still has it. + * + * @return void + */ + protected function upgrade_49() { + global $wpdb; + + /* + * Using a filter to remove the notification for the current logged in user. The notification center is + * initializing the notifications before the upgrade routine has been executedd and is saving the stored + * notifications on shutdown. This causes the returning notification. By adding this filter the shutdown + * routine on the notification center will remove the notification. + */ + add_filter( 'yoast_notifications_before_storage', [ $this, 'remove_about_notice' ] ); + + $meta_key = $wpdb->get_blog_prefix() . Yoast_Notification_Center::STORAGE_KEY; + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $usermetas = $wpdb->get_results( + $wpdb->prepare( + ' + SELECT %i, %i + FROM %i + WHERE %i = %s AND %i LIKE %s + ', + [ + 'user_id', + 'meta_value', + $wpdb->usermeta, + 'meta_key', + $meta_key, + 'meta_value', + '%wpseo-dismiss-about%', + ], + ), + ARRAY_A, + ); + + if ( empty( $usermetas ) ) { + return; + } + + foreach ( $usermetas as $usermeta ) { + $notifications = maybe_unserialize( $usermeta['meta_value'] ); + + foreach ( $notifications as $notification_key => $notification ) { + if ( ! empty( $notification['options']['id'] ) && $notification['options']['id'] === 'wpseo-dismiss-about' ) { + unset( $notifications[ $notification_key ] ); + } + } + + update_user_option( $usermeta['user_id'], Yoast_Notification_Center::STORAGE_KEY, array_values( $notifications ) ); + } + } + + /** + * Removes the wpseo-dismiss-about notice from a list of notifications. + * + * @param Yoast_Notification[] $notifications The notifications to filter. + * + * @return Yoast_Notification[] The filtered list of notifications. Excluding the wpseo-dismiss-about notification. + */ + public function remove_about_notice( $notifications ) { + foreach ( $notifications as $notification_key => $notification ) { + if ( $notification->get_id() === 'wpseo-dismiss-about' ) { + unset( $notifications[ $notification_key ] ); + } + } + + return $notifications; + } + + /** + * Adds the yoast_seo_links table to the database. + * + * @return void + */ + protected function upgrade_50() { + global $wpdb; + + // Deletes the post meta value, which might created in the RC. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i + WHERE %i = '_yst_content_links_processed'", + [ $wpdb->postmeta, 'meta_key' ], + ), + ); + } + + /** + * Register new capabilities and roles. + * + * @return void + */ + private function upgrade_55() { + // Register roles. + do_action( 'wpseo_register_roles' ); + WPSEO_Role_Manager_Factory::get()->add(); + + // Register capabilities. + do_action( 'wpseo_register_capabilities' ); + WPSEO_Capability_Manager_Factory::get()->add(); + } + + /** + * Removes some no longer used options for noindexing subpages and for meta keywords and its associated templates. + * + * @return void + */ + private function upgrade_63() { + $this->cleanup_option_data( 'wpseo_titles' ); + } + + /** + * Perform the 7.0 upgrade, moves settings around, deletes several options. + * + * @return void + */ + private function upgrade_70() { + + $wpseo_permalinks = $this->get_option_from_database( 'wpseo_permalinks' ); + $wpseo_xml = $this->get_option_from_database( 'wpseo_xml' ); + $wpseo_rss = $this->get_option_from_database( 'wpseo_rss' ); + $wpseo = $this->get_option_from_database( 'wpseo' ); + $wpseo_internallinks = $this->get_option_from_database( 'wpseo_internallinks' ); + + // Move some permalink settings, then delete the option. + $this->save_option_setting( $wpseo_permalinks, 'redirectattachment', 'disable-attachment' ); + $this->save_option_setting( $wpseo_permalinks, 'stripcategorybase' ); + + // Move one XML sitemap setting, then delete the option. + $this->save_option_setting( $wpseo_xml, 'enablexmlsitemap', 'enable_xml_sitemap' ); + + // Move the RSS settings to the search appearance settings, then delete the RSS option. + $this->save_option_setting( $wpseo_rss, 'rssbefore' ); + $this->save_option_setting( $wpseo_rss, 'rssafter' ); + + $this->save_option_setting( $wpseo, 'company_logo' ); + $this->save_option_setting( $wpseo, 'company_name' ); + $this->save_option_setting( $wpseo, 'company_or_person' ); + $this->save_option_setting( $wpseo, 'person_name' ); + + // Remove the website name and altername name as we no longer need them. + $this->cleanup_option_data( 'wpseo' ); + + // All the breadcrumbs settings have moved to the search appearance settings. + foreach ( array_keys( $wpseo_internallinks ) as $key ) { + $this->save_option_setting( $wpseo_internallinks, $key ); + } + + // Convert hidden metabox options to display metabox options. + $title_options = get_option( 'wpseo_titles' ); + + foreach ( $title_options as $key => $value ) { + if ( strpos( $key, 'hideeditbox-tax-' ) === 0 ) { + $taxonomy = substr( $key, strlen( 'hideeditbox-tax-' ) ); + WPSEO_Options::set( 'display-metabox-tax-' . $taxonomy, ! $value ); + continue; + } + + if ( strpos( $key, 'hideeditbox-' ) === 0 ) { + $post_type = substr( $key, strlen( 'hideeditbox-' ) ); + WPSEO_Options::set( 'display-metabox-pt-' . $post_type, ! $value ); + continue; + } + } + + // Cleanup removed options. + delete_option( 'wpseo_xml' ); + delete_option( 'wpseo_permalinks' ); + delete_option( 'wpseo_rss' ); + delete_option( 'wpseo_internallinks' ); + + // Remove possibly present plugin conflict notice for plugin that was removed from the list of conflicting plugins. + $yoast_plugin_conflict = WPSEO_Plugin_Conflict::get_instance(); + $yoast_plugin_conflict->clear_error( 'header-footer/plugin.php' ); + + // Moves the user meta for excluding from the XML sitemap to a noindex. + global $wpdb; + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( "UPDATE $wpdb->usermeta SET meta_key = 'wpseo_noindex_author' WHERE meta_key = 'wpseo_excludeauthorsitemap'" ); + } + + /** + * Perform the 7.1 upgrade. + * + * @return void + */ + private function upgrade_71() { + $this->cleanup_option_data( 'wpseo_social' ); + + // Move the breadcrumbs setting and invert it. + $title_options = $this->get_option_from_database( 'wpseo_titles' ); + + if ( array_key_exists( 'breadcrumbs-blog-remove', $title_options ) ) { + WPSEO_Options::set( 'breadcrumbs-display-blog-page', ! $title_options['breadcrumbs-blog-remove'] ); + + $this->cleanup_option_data( 'wpseo_titles' ); + } + } + + /** + * Perform the 7.3 upgrade. + * + * @return void + */ + private function upgrade_73() { + global $wpdb; + // We've moved the cornerstone checkbox to our proper namespace. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '_yoast_wpseo_is_cornerstone' WHERE meta_key = '_yst_is_cornerstone'" ); + + // Remove the previous Whip dismissed message, as this is a new one regarding PHP 5.2. + delete_option( 'whip_dismiss_timestamp' ); + } + + /** + * Performs the 7.4 upgrade. + * + * @return void + */ + protected function upgrade_74() { + $this->remove_sitemap_validators(); + } + + /** + * Performs the 7.5.3 upgrade. + * + * When upgrading purging media is potentially relevant. + * + * @return void + */ + private function upgrade_753() { + // Only when attachments are not disabled. + if ( WPSEO_Options::get( 'disable-attachment' ) === true ) { + return; + } + + // Only when attachments are not no-indexed. + if ( WPSEO_Options::get( 'noindex-attachment' ) === true ) { + return; + } + + // Set purging relevancy. + WPSEO_Options::set( 'is-media-purge-relevant', true ); + } + + /** + * Performs the 7.7 upgrade. + * + * @return void + */ + private function upgrade_77() { + // Remove all OpenGraph content image cache. + $this->delete_post_meta( '_yoast_wpseo_post_image_cache' ); + } + + /** + * Performs the 7.7.2 upgrade. + * + * @return void + */ + private function upgrade_772() { + if ( YoastSEO()->helpers->woocommerce->is_active() ) { + $this->migrate_woocommerce_archive_setting_to_shop_page(); + } + } + + /** + * Performs the 9.0 upgrade. + * + * @return void + */ + protected function upgrade_90() { + global $wpdb; + + // Invalidate all sitemap cache transients. + WPSEO_Sitemaps_Cache_Validator::cleanup_database(); + + // Removes all scheduled tasks for hitting the sitemap index. + wp_clear_scheduled_hook( 'wpseo_hit_sitemap_index' ); + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + 'DELETE FROM %i + WHERE %i LIKE %s', + [ $wpdb->options, 'option_name', 'wpseo_sitemap_%' ], + ), + ); + } + + /** + * Performs the 10.0 upgrade. + * + * @return void + */ + private function upgrade_100() { + // Removes recalibration notifications. + $this->clean_all_notifications(); + + // Removes recalibration options. + WPSEO_Options::clean_up( 'wpseo' ); + delete_option( 'wpseo_recalibration_beta_mailinglist_subscription' ); + } + + /** + * Performs the 11.1 upgrade. + * + * @return void + */ + private function upgrade_111() { + // Set company_or_person to company when it's an invalid value. + $company_or_person = WPSEO_Options::get( 'company_or_person', '' ); + + if ( ! in_array( $company_or_person, [ 'company', 'person' ], true ) ) { + WPSEO_Options::set( 'company_or_person', 'company' ); + } + } + + /** + * Performs the 12.3 upgrade. + * + * Removes the about notice when its still in the database. + * + * @return void + */ + private function upgrade_123() { + $plugins = [ + 'yoast-seo-premium', + 'video-seo-for-wordpress-seo-by-yoast', + 'yoast-news-seo', + 'local-seo-for-yoast-seo', + 'yoast-woocommerce-seo', + 'yoast-acf-analysis', + ]; + + $center = Yoast_Notification_Center::get(); + foreach ( $plugins as $plugin ) { + $center->remove_notification_by_id( 'wpseo-outdated-yoast-seo-plugin-' . $plugin ); + } + } + + /** + * Performs the 12.4 upgrade. + * + * Removes the Google plus defaults from the database. + * + * @return void + */ + private function upgrade_124() { + $this->cleanup_option_data( 'wpseo_social' ); + } + + /** + * Performs the 12.5 upgrade. + * + * @return void + */ + public function upgrade_125() { + // Disables the force rewrite title when the theme supports it through WordPress. + if ( WPSEO_Options::get( 'forcerewritetitle', false ) && current_theme_supports( 'title-tag' ) ) { + WPSEO_Options::set( 'forcerewritetitle', false ); + } + + global $wpdb; + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + 'DELETE FROM %i + WHERE %i = %s', + [ $wpdb->usermeta, 'meta_key', 'wp_yoast_promo_hide_premium_upsell_admin_block' ], + ), + ); + + // Removes the WordPress update notification, because it is no longer necessary when WordPress 5.3 is released. + $center = Yoast_Notification_Center::get(); + $center->remove_notification_by_id( 'wpseo-dismiss-wordpress-upgrade' ); + } + + /** + * Performs the 12.8 upgrade. + * + * @return void + */ + private function upgrade_128() { + // Re-save wpseo to make sure bf_banner_2019_dismissed key is gone. + $this->cleanup_option_data( 'wpseo' ); + + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-page_comments-notice' ); + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-wordpress-upgrade' ); + } + + /** + * Performs the 13.2 upgrade. + * + * @return void + */ + private function upgrade_132() { + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-tagline-notice' ); + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-permalink-notice' ); + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-onpageorg' ); + + // Transfers the onpage option value to the ryte option. + $ryte_option = get_option( 'wpseo_ryte' ); + $onpage_option = get_option( 'wpseo_onpage' ); + if ( ! $ryte_option && $onpage_option ) { + update_option( 'wpseo_ryte', $onpage_option ); + delete_option( 'wpseo_onpage' ); + } + + // Changes onpage_indexability to ryte_indexability. + $wpseo_option = get_option( 'wpseo' ); + if ( isset( $wpseo_option['onpage_indexability'] ) && ! isset( $wpseo_option['ryte_indexability'] ) ) { + $wpseo_option['ryte_indexability'] = $wpseo_option['onpage_indexability']; + unset( $wpseo_option['onpage_indexability'] ); + update_option( 'wpseo', $wpseo_option ); + } + + if ( wp_next_scheduled( 'wpseo_ryte_fetch' ) ) { + wp_clear_scheduled_hook( 'wpseo_ryte_fetch' ); + } + + /* + * Re-register capabilities to add the new `view_site_health_checks` + * capability to the SEO Manager role. + */ + do_action( 'wpseo_register_capabilities' ); + WPSEO_Capability_Manager_Factory::get()->add(); + } + + /** + * Perform the 14.0.3 upgrade. + * + * @return void + */ + private function upgrade_1403() { + WPSEO_Options::set( 'ignore_indexation_warning', false ); + } + + /** + * Performs the 14.1 upgrade. + * + * @return void + */ + private function upgrade_141() { + /* + * These notifications are retrieved from storage on the `init` hook with + * priority 1. We need to remove them after they're retrieved. + */ + add_action( 'init', [ $this, 'remove_notifications_for_141' ] ); + add_action( 'init', [ $this, 'clean_up_private_taxonomies_for_141' ] ); + + $this->reset_permalinks_of_attachments_for_141(); + } + + /** + * Performs the 14.2 upgrade. + * + * Removes the yoast-acf-analysis notice when it's still in the database. + * + * @return void + */ + private function upgrade_142() { + add_action( 'init', [ $this, 'remove_acf_notification_for_142' ] ); + } + + /** + * Performs the 14.5 upgrade. + * + * @return void + */ + private function upgrade_145() { + add_action( 'init', [ $this, 'set_indexation_completed_option_for_145' ] ); + } + + /** + * Performs the 14.9 upgrade. + * + * @return void + */ + private function upgrade_149() { + $version = get_option( 'wpseo_license_server_version', 2 ); + WPSEO_Options::set( 'license_server_version', $version ); + delete_option( 'wpseo_license_server_version' ); + } + + /** + * Performs the 15.1 upgrade. + * + * @return void + */ + private function upgrade_151() { + $this->set_home_url_for_151(); + $this->move_indexables_indexation_reason_for_151(); + + add_action( 'init', [ $this, 'set_permalink_structure_option_for_151' ] ); + add_action( 'init', [ $this, 'store_custom_taxonomy_slugs_for_151' ] ); + } + + /** + * Performs the 15.3 upgrade. + * + * @return void + */ + private function upgrade_153() { + WPSEO_Options::set( 'category_base_url', get_option( 'category_base' ) ); + WPSEO_Options::set( 'tag_base_url', get_option( 'tag_base' ) ); + + // Rename a couple of options. + $indexation_started_value = WPSEO_Options::get( 'indexation_started' ); + WPSEO_Options::set( 'indexing_started', $indexation_started_value ); + + $indexables_indexing_completed_value = WPSEO_Options::get( 'indexables_indexation_completed' ); + WPSEO_Options::set( 'indexables_indexing_completed', $indexables_indexing_completed_value ); + } + + /** + * Performs the 15.5 upgrade. + * + * @return void + */ + private function upgrade_155() { + // Unset the fbadminapp value in the wpseo_social option. + $wpseo_social_option = get_option( 'wpseo_social' ); + + if ( isset( $wpseo_social_option['fbadminapp'] ) ) { + unset( $wpseo_social_option['fbadminapp'] ); + update_option( 'wpseo_social', $wpseo_social_option ); + } + } + + /** + * Performs the 15.7 upgrade. + * + * @return void + */ + private function upgrade_157() { + add_action( 'init', [ $this, 'remove_plugin_updated_notification_for_157' ] ); + } + + /** + * Performs the 15.9.1 upgrade routine. + * + * @return void + */ + private function upgrade_1591() { + $enabled_auto_updates = get_option( 'auto_update_plugins' ); + $addon_update_watcher = YoastSEO()->classes->get( Addon_Update_Watcher::class ); + $addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', [], $enabled_auto_updates ); + } + + /** + * Performs the 16.2 upgrade routine. + * + * @return void + */ + private function upgrade_162() { + $enabled_auto_updates = get_site_option( 'auto_update_plugins' ); + $addon_update_watcher = YoastSEO()->classes->get( Addon_Update_Watcher::class ); + $addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', $enabled_auto_updates, [] ); + } + + /** + * Performs the 16.5 upgrade. + * + * @return void + */ + private function upgrade_165() { + add_action( 'init', [ $this, 'copy_og_settings_from_social_to_titles' ], 99 ); + + // Run after the WPSEO_Options::enrich_defaults method which has priority 99. + add_action( 'init', [ $this, 'reset_og_settings_to_default_values' ], 100 ); + } + + /** + * Performs the 17.2 upgrade. Cleans out any unnecessary indexables. See $cleanup_integration->get_cleanup_tasks() + * to see what will be cleaned out. + * + * @return void + */ + private function upgrade_172() { + wp_unschedule_hook( 'wpseo_cleanup_orphaned_indexables' ); + wp_unschedule_hook( 'wpseo_cleanup_indexables' ); + + if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) { + wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK ); + } + } + + /** + * Performs the 17.7.1 upgrade routine. + * + * @return void + */ + private function upgrade_1771() { + $enabled_auto_updates = get_site_option( 'auto_update_plugins' ); + $addon_update_watcher = YoastSEO()->classes->get( Addon_Update_Watcher::class ); + $addon_update_watcher->toggle_auto_updates_for_add_ons( 'auto_update_plugins', $enabled_auto_updates, [] ); + } + + /** + * Performs the 17.9 upgrade routine. + * + * @return void + */ + private function upgrade_179() { + WPSEO_Options::set( 'wincher_integration_active', true ); + } + + /** + * Performs the 18.3 upgrade routine. + * + * @return void + */ + private function upgrade_183() { + $this->delete_post_meta( 'yoast-structured-data-blocks-images-cache' ); + } + + /** + * Performs the 18.6 upgrade routine. + * + * @return void + */ + private function upgrade_186() { + if ( is_multisite() ) { + WPSEO_Options::set( 'allow_wincher_integration_active', false ); + } + } + + /** + * Performs the 18.9 upgrade routine. + * + * @return void + */ + private function upgrade_189() { + // Make old users not get the Installation Success page after upgrading. + WPSEO_Options::set( 'should_redirect_after_install_free', false ); + // We're adding a hardcoded time here, so that in the future we can be able to identify whether the user did see the Installation Success page or not. + // If they did, they wouldn't have this hardcoded value in that option, but rather (roughly) the timestamp of the moment they saw it. + WPSEO_Options::set( 'activation_redirect_timestamp_free', 1_652_258_756 ); + + // Transfer the Social URLs. + $other = []; + $other[] = WPSEO_Options::get( 'instagram_url' ); + $other[] = WPSEO_Options::get( 'linkedin_url' ); + $other[] = WPSEO_Options::get( 'myspace_url' ); + $other[] = WPSEO_Options::get( 'pinterest_url' ); + $other[] = WPSEO_Options::get( 'youtube_url' ); + $other[] = WPSEO_Options::get( 'wikipedia_url' ); + + WPSEO_Options::set( 'other_social_urls', array_values( array_unique( array_filter( $other ) ) ) ); + + // Transfer the progress of the old Configuration Workout. + $workout_data = WPSEO_Options::get( 'workouts_data' ); + $old_conf_progress = ( $workout_data['configuration']['finishedSteps'] ?? [] ); + + if ( in_array( 'optimizeSeoData', $old_conf_progress, true ) && in_array( 'siteRepresentation', $old_conf_progress, true ) ) { + // If completed ‘SEO optimization’ and ‘Site representation’ step, we assume the workout was completed. + $configuration_finished_steps = [ + 'siteRepresentation', + 'socialProfiles', + 'personalPreferences', + ]; + WPSEO_Options::set( 'configuration_finished_steps', $configuration_finished_steps ); + } + } + + /** + * Performs the 19.1 upgrade routine. + * + * @return void + */ + private function upgrade_191() { + if ( is_multisite() ) { + WPSEO_Options::set( 'allow_remove_feed_post_comments', true ); + } + } + + /** + * Performs the 19.3 upgrade routine. + * + * @return void + */ + private function upgrade_193() { + if ( empty( get_option( 'wpseo_premium', [] ) ) ) { + WPSEO_Options::set( 'enable_index_now', true ); + WPSEO_Options::set( 'enable_link_suggestions', true ); + } + } + + /** + * Performs the 19.6 upgrade routine. + * + * @return void + */ + private function upgrade_196() { + WPSEO_Options::set( 'ryte_indexability', false ); + WPSEO_Options::set( 'allow_ryte_indexability', false ); + wp_clear_scheduled_hook( 'wpseo_ryte_fetch' ); + } + + /** + * Performs the 19.11 upgrade routine. + * + * @return void + */ + private function upgrade_1911() { + add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_post_types' ] ); + add_action( 'shutdown', [ $this, 'remove_indexable_rows_for_non_public_taxonomies' ] ); + $this->deduplicate_unindexed_indexable_rows(); + $this->remove_indexable_rows_for_disabled_authors_archive(); + if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) { + wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK ); + } + } + + /** + * Performs the 20.2 upgrade routine. + * + * @return void + */ + private function upgrade_202() { + if ( WPSEO_Options::get( 'disable-attachment', true ) ) { + $attachment_cleanup_helper = YoastSEO()->helpers->attachment_cleanup; + + $attachment_cleanup_helper->remove_attachment_indexables( true ); + $attachment_cleanup_helper->clean_attachment_links_from_target_indexable_ids( true ); + } + + $this->clean_unindexed_indexable_rows_with_no_object_id(); + + if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) { + // This schedules the cleanup routine cron again, since in combination of premium cleans up the prominent words table. We also want to cleanup possible orphaned hierarchies from the above cleanups. + wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK ); + } + } + + /** + * Performs the 20.5 upgrade routine. + * + * @return void + */ + private function upgrade_205() { + if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) { + wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK ); + } + } + + /** + * Performs the 20.7 upgrade routine. + * Removes the metadata related to the settings page introduction modal for all the users. + * Also, schedules another cleanup scheduled action. + * + * @return void + */ + private function upgrade_207() { + add_action( 'shutdown', [ $this, 'delete_user_introduction_meta' ] ); + } + + /** + * Performs the 20.8 upgrade routine. + * Schedules another cleanup scheduled action. + * + * @return void + */ + private function upgrade_208() { + if ( ! wp_next_scheduled( Cleanup_Integration::START_HOOK ) ) { + wp_schedule_single_event( ( time() + ( MINUTE_IN_SECONDS * 5 ) ), Cleanup_Integration::START_HOOK ); + } + } + + /** + * Performs the 22.6 upgrade routine. + * Schedules another cleanup scheduled action, but starting from the last cleanup action we just added (if there + * aren't any running cleanups already). + * + * @return void + */ + private function upgrade_226() { + if ( get_option( Cleanup_Integration::CURRENT_TASK_OPTION ) === false ) { + $cleanup_integration = YoastSEO()->classes->get( Cleanup_Integration::class ); + $cleanup_integration->start_cron_job( 'clean_selected_empty_usermeta', DAY_IN_SECONDS ); + } + } + + /** + * Sets the home_url option for the 15.1 upgrade routine. + * + * @return void + */ + protected function set_home_url_for_151() { + $home_url = WPSEO_Options::get( 'home_url' ); + + if ( empty( $home_url ) ) { + WPSEO_Options::set( 'home_url', get_home_url() ); + } + } + + /** + * Moves the `indexables_indexation_reason` option to the + * renamed `indexing_reason` option. + * + * @return void + */ + protected function move_indexables_indexation_reason_for_151() { + $reason = WPSEO_Options::get( 'indexables_indexation_reason', '' ); + WPSEO_Options::set( 'indexing_reason', $reason ); + } + + /** + * Checks if the indexable indexation is completed. + * If so, sets the `indexables_indexation_completed` option to `true`, + * else to `false`. + * + * @return void + */ + public function set_indexation_completed_option_for_145() { + WPSEO_Options::set( 'indexables_indexation_completed', YoastSEO()->helpers->indexing->get_limited_filtered_unindexed_count( 1 ) === 0 ); + } + + /** + * Cleans up the private taxonomies from the indexables table for the upgrade routine to 14.1. + * + * @return void + */ + public function clean_up_private_taxonomies_for_141() { + global $wpdb; + + // If migrations haven't been completed successfully the following may give false errors. So suppress them. + $show_errors = $wpdb->show_errors; + $wpdb->show_errors = false; + + // Clean up indexables of private taxonomies. + $private_taxonomies = get_taxonomies( [ 'public' => false ], 'names' ); + + if ( empty( $private_taxonomies ) ) { + return; + } + + $replacements = array_merge( + [ + Model::get_table_name( 'Indexable' ), + 'object_type', + 'object_sub_type', + ], + $private_taxonomies, + ); + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i + WHERE %i = 'term' + AND %i IN (" + . implode( ', ', array_fill( 0, count( $private_taxonomies ), '%s' ) ) + . ')', + $replacements, + ), + ); + + $wpdb->show_errors = $show_errors; + } + + /** + * Resets the permalinks of attachments to `null` in the indexable table for the upgrade routine to 14.1. + * + * @return void + */ + private function reset_permalinks_of_attachments_for_141() { + global $wpdb; + + // If migrations haven't been completed succesfully the following may give false errors. So suppress them. + $show_errors = $wpdb->show_errors; + $wpdb->show_errors = false; + + // Reset the permalinks of the attachments in the indexable table. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "UPDATE %i SET %i = NULL WHERE %i = 'post' AND %i = 'attachment'", + [ Model::get_table_name( 'Indexable' ), 'permalink', 'object_type', 'object_sub_type' ], + ), + ); + + $wpdb->show_errors = $show_errors; + } + + /** + * Removes notifications from the Notification center for the 14.1 upgrade. + * + * @return void + */ + public function remove_notifications_for_141() { + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-recalculate' ); + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-dismiss-blog-public-notice' ); + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-links-table-not-accessible' ); + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-post-type-archive-notification' ); + } + + /** + * Removes the wpseo-suggested-plugin-yoast-acf-analysis notification from the Notification center for the 14.2 + * upgrade. + * + * @return void + */ + public function remove_acf_notification_for_142() { + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-suggested-plugin-yoast-acf-analysis' ); + } + + /** + * Removes the wpseo-plugin-updated notification from the Notification center for the 15.7 upgrade. + * + * @return void + */ + public function remove_plugin_updated_notification_for_157() { + Yoast_Notification_Center::get()->remove_notification_by_id( 'wpseo-plugin-updated' ); + } + + /** + * Removes all notifications saved in the database under 'wp_yoast_notifications'. + * + * @return void + */ + private function clean_all_notifications() { + global $wpdb; + delete_metadata( 'user', 0, $wpdb->get_blog_prefix() . Yoast_Notification_Center::STORAGE_KEY, '', true ); + } + + /** + * Removes the post meta fields for a given meta key. + * + * @param string $meta_key The meta key. + * + * @return void + */ + private function delete_post_meta( $meta_key ) { + global $wpdb; + $deleted = $wpdb->delete( $wpdb->postmeta, [ 'meta_key' => $meta_key ], [ '%s' ] ); + + if ( $deleted ) { + wp_cache_set( 'last_changed', microtime(), 'posts' ); + } + } + + /** + * Removes all sitemap validators. + * + * This should be executed on every upgrade routine until we have removed the sitemap caching in the database. + * + * @return void + */ + private function remove_sitemap_validators() { + global $wpdb; + + // Remove all sitemap validators. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + 'DELETE FROM %i WHERE %i LIKE %s', + [ $wpdb->options, 'option_name', 'wpseo_sitemap%validator%' ], + ), + ); + } + + /** + * Retrieves the option value directly from the database. + * + * @param string $option_name Option to retrieve. + * + * @return int|string|bool|float|array The content of the option if exists, otherwise an + * empty array. + */ + protected function get_option_from_database( $option_name ) { + global $wpdb; + + // Load option directly from the database, to avoid filtering and sanitization. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $results = $wpdb->get_results( + $wpdb->prepare( + 'SELECT %i FROM %i WHERE %i = %s', + [ 'option_value', $wpdb->options, 'option_name', $option_name ], + ), + ARRAY_A, + ); + + if ( ! empty( $results ) ) { + return maybe_unserialize( $results[0]['option_value'] ); + } + + return []; + } + + /** + * Cleans the option to make sure only relevant settings are there. + * + * @param string $option_name Option name save. + * + * @return void + */ + protected function cleanup_option_data( $option_name ) { + $data = get_option( $option_name, [] ); + if ( ! is_array( $data ) || $data === [] ) { + return; + } + + /* + * Clean up the option by re-saving it. + * + * The option framework will remove any settings that are not configured + * for this option, removing any migrated settings. + */ + update_option( $option_name, $data ); + } + + /** + * Saves an option setting to where it should be stored. + * + * @param int|string|bool|float|array $source_data The option containing the value to be + * migrated. + * @param string $source_setting Name of the key in the "from" option. + * @param string|null $target_setting Name of the key in the "to" option. + * + * @return void + */ + protected function save_option_setting( $source_data, $source_setting, $target_setting = null ) { + $target_setting ??= $source_setting; + + if ( isset( $source_data[ $source_setting ] ) ) { + WPSEO_Options::set( $target_setting, $source_data[ $source_setting ] ); + } + } + + /** + * Migrates WooCommerce archive settings to the WooCommerce Shop page meta-data settings. + * + * If no Shop page is defined, nothing will be migrated. + * + * @return void + */ + private function migrate_woocommerce_archive_setting_to_shop_page() { + $shop_page_id = wc_get_page_id( 'shop' ); + + if ( $shop_page_id === -1 ) { + return; + } + + $title = WPSEO_Meta::get_value( 'title', $shop_page_id ); + + if ( empty( $title ) ) { + $option_title = WPSEO_Options::get( 'title-ptarchive-product' ); + + WPSEO_Meta::set_value( + 'title', + $option_title, + $shop_page_id, + ); + + WPSEO_Options::set( 'title-ptarchive-product', '' ); + } + + $meta_description = WPSEO_Meta::get_value( 'metadesc', $shop_page_id ); + + if ( empty( $meta_description ) ) { + $option_metadesc = WPSEO_Options::get( 'metadesc-ptarchive-product' ); + + WPSEO_Meta::set_value( + 'metadesc', + $option_metadesc, + $shop_page_id, + ); + + WPSEO_Options::set( 'metadesc-ptarchive-product', '' ); + } + + $bc_title = WPSEO_Meta::get_value( 'bctitle', $shop_page_id ); + + if ( empty( $bc_title ) ) { + $option_bctitle = WPSEO_Options::get( 'bctitle-ptarchive-product' ); + + WPSEO_Meta::set_value( + 'bctitle', + $option_bctitle, + $shop_page_id, + ); + + WPSEO_Options::set( 'bctitle-ptarchive-product', '' ); + } + + $noindex = WPSEO_Meta::get_value( 'meta-robots-noindex', $shop_page_id ); + + if ( $noindex === '0' ) { + $option_noindex = WPSEO_Options::get( 'noindex-ptarchive-product' ); + + WPSEO_Meta::set_value( + 'meta-robots-noindex', + $option_noindex, + $shop_page_id, + ); + + WPSEO_Options::set( 'noindex-ptarchive-product', false ); + } + } + + /** + * Stores the initial `permalink_structure` option. + * + * @return void + */ + public function set_permalink_structure_option_for_151() { + WPSEO_Options::set( 'permalink_structure', get_option( 'permalink_structure' ) ); + } + + /** + * Stores the initial slugs of custom taxonomies. + * + * @return void + */ + public function store_custom_taxonomy_slugs_for_151() { + $taxonomies = $this->taxonomy_helper->get_custom_taxonomies(); + + $custom_taxonomies = []; + + foreach ( $taxonomies as $taxonomy ) { + $slug = $this->taxonomy_helper->get_taxonomy_slug( $taxonomy ); + + $custom_taxonomies[ $taxonomy ] = $slug; + } + + WPSEO_Options::set( 'custom_taxonomy_slugs', $custom_taxonomies ); + } + + /** + * Copies the frontpage social settings to the titles options. + * + * @return void + */ + public function copy_og_settings_from_social_to_titles() { + $wpseo_social = get_option( 'wpseo_social' ); + $wpseo_titles = get_option( 'wpseo_titles' ); + + $copied_options = []; + // Reset to the correct default value. + $copied_options['open_graph_frontpage_title'] = '%%sitename%%'; + + $options = [ + 'og_frontpage_title' => 'open_graph_frontpage_title', + 'og_frontpage_desc' => 'open_graph_frontpage_desc', + 'og_frontpage_image' => 'open_graph_frontpage_image', + 'og_frontpage_image_id' => 'open_graph_frontpage_image_id', + ]; + + foreach ( $options as $social_option => $titles_option ) { + if ( ! empty( $wpseo_social[ $social_option ] ) ) { + $copied_options[ $titles_option ] = $wpseo_social[ $social_option ]; + } + } + + $wpseo_titles = array_merge( $wpseo_titles, $copied_options ); + + update_option( 'wpseo_titles', $wpseo_titles ); + } + + /** + * Reset the social options with the correct default values. + * + * @return void + */ + public function reset_og_settings_to_default_values() { + $wpseo_titles = get_option( 'wpseo_titles' ); + $updated_options = []; + + $updated_options['social-title-author-wpseo'] = '%%name%%'; + $updated_options['social-title-archive-wpseo'] = '%%date%%'; + + /* translators: %s expands to the name of a post type (plural). */ + $post_type_archive_default = sprintf( __( '%s Archive', 'wordpress-seo' ), '%%pt_plural%%' ); + + /* translators: %s expands to the variable used for term title. */ + $term_archive_default = sprintf( __( '%s Archives', 'wordpress-seo' ), '%%term_title%%' ); + + $post_type_objects = get_post_types( [ 'public' => true ], 'objects' ); + + if ( $post_type_objects ) { + foreach ( $post_type_objects as $pt ) { + // Post types. + if ( isset( $wpseo_titles[ 'social-title-' . $pt->name ] ) ) { + $updated_options[ 'social-title-' . $pt->name ] = '%%title%%'; + } + // Post type archives. + if ( isset( $wpseo_titles[ 'social-title-ptarchive-' . $pt->name ] ) ) { + $updated_options[ 'social-title-ptarchive-' . $pt->name ] = $post_type_archive_default; + } + } + } + + $taxonomy_objects = get_taxonomies( [ 'public' => true ], 'object' ); + + if ( $taxonomy_objects ) { + foreach ( $taxonomy_objects as $tax ) { + if ( isset( $wpseo_titles[ 'social-title-tax-' . $tax->name ] ) ) { + $updated_options[ 'social-title-tax-' . $tax->name ] = $term_archive_default; + } + } + } + + $wpseo_titles = array_merge( $wpseo_titles, $updated_options ); + + update_option( 'wpseo_titles', $wpseo_titles ); + } + + /** + * Removes all indexables for posts that are not publicly viewable. + * This method should be called after init, because post_types can still be registered. + * + * @return void + */ + public function remove_indexable_rows_for_non_public_post_types() { + global $wpdb; + + // If migrations haven't been completed successfully the following may give false errors. So suppress them. + $show_errors = $wpdb->show_errors; + $wpdb->show_errors = false; + + $indexable_table = Model::get_table_name( 'Indexable' ); + + $included_post_types = YoastSEO()->helpers->post_type->get_indexable_post_types(); + + if ( empty( $included_post_types ) ) { + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i + WHERE %i = 'post' + AND %i IS NOT NULL", + [ $indexable_table, 'object_type', 'object_sub_type' ], + ), + ); + } + else { + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i + WHERE %i = 'post' + AND %i IS NOT NULL + AND %i NOT IN ( " . implode( ', ', array_fill( 0, count( $included_post_types ), '%s' ) ) . ' )', + array_merge( + [ + $indexable_table, + 'object_type', + 'object_sub_type', + 'object_sub_type', + ], + $included_post_types, + ), + ), + ); + } + + $wpdb->show_errors = $show_errors; + } + + /** + * Removes all indexables for terms that are not publicly viewable. + * This method should be called after init, because taxonomies can still be registered. + * + * @return void + */ + public function remove_indexable_rows_for_non_public_taxonomies() { + global $wpdb; + + // If migrations haven't been completed successfully the following may give false errors. So suppress them. + $show_errors = $wpdb->show_errors; + $wpdb->show_errors = false; + + $indexable_table = Model::get_table_name( 'Indexable' ); + + $included_taxonomies = YoastSEO()->helpers->taxonomy->get_indexable_taxonomies(); + + if ( empty( $included_taxonomies ) ) { + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i + WHERE %i = 'term' + AND %i IS NOT NULL", + [ $indexable_table, 'object_type', 'object_sub_type' ], + ), + ); + } + else { + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i + WHERE %i = 'term' + AND %i IS NOT NULL + AND %i NOT IN ( " . implode( ', ', array_fill( 0, count( $included_taxonomies ), '%s' ) ) . ' )', + array_merge( + [ + $indexable_table, + 'object_type', + 'object_sub_type', + 'object_sub_type', + ], + $included_taxonomies, + ), + ), + ); + } + + $wpdb->show_errors = $show_errors; + } + + /** + * De-duplicates indexables that have more than one "unindexed" rows for the same object. Keeps the newest + * indexable. + * + * @return void + */ + protected function deduplicate_unindexed_indexable_rows() { + global $wpdb; + + // If migrations haven't been completed successfully the following may give false errors. So suppress them. + $show_errors = $wpdb->show_errors; + $wpdb->show_errors = false; + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $duplicates = $wpdb->get_results( + $wpdb->prepare( + " + SELECT + MAX(id) as newest_id, + object_id, + object_type + FROM + %i + WHERE + post_status = 'unindexed' + AND object_type IN ( 'term', 'post', 'user' ) + GROUP BY + object_id, + object_type + HAVING + count(*) > 1", + [ Model::get_table_name( 'Indexable' ) ], + ), + ARRAY_A, + ); + + if ( empty( $duplicates ) ) { + $wpdb->show_errors = $show_errors; + + return; + } + + // Users, terms and posts may share the same object_id. So delete them in separate, more performant, queries. + $delete_queries = [ + $this->get_indexable_deduplication_query_for_type( 'post', $duplicates, $wpdb ), + $this->get_indexable_deduplication_query_for_type( 'term', $duplicates, $wpdb ), + $this->get_indexable_deduplication_query_for_type( 'user', $duplicates, $wpdb ), + ]; + + foreach ( $delete_queries as $delete_query ) { + if ( ! empty( $delete_query ) ) { + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Reason: Is it prepared already. + $wpdb->query( $delete_query ); + // phpcs:enable + } + } + + $wpdb->show_errors = $show_errors; + } + + /** + * Cleans up "unindexed" indexable rows when appropriate, aka when there's no object ID even though it should. + * + * @return void + */ + protected function clean_unindexed_indexable_rows_with_no_object_id() { + global $wpdb; + + // If migrations haven't been completed successfully the following may give false errors. So suppress them. + $show_errors = $wpdb->show_errors; + $wpdb->show_errors = false; + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i + WHERE %i = 'unindexed' + AND %i NOT IN ( 'home-page', 'date-archive', 'post-type-archive', 'system-page' ) + AND %i IS NULL", + [ Model::get_table_name( 'Indexable' ), 'post_status', 'object_type', 'object_id' ], + ), + ); + + $wpdb->show_errors = $show_errors; + } + + /** + * Removes all user indexable rows when the author archive is disabled. + * + * @return void + */ + protected function remove_indexable_rows_for_disabled_authors_archive() { + global $wpdb; + + if ( ! YoastSEO()->helpers->author_archive->are_disabled() ) { + return; + } + + // If migrations haven't been completed successfully the following may give false errors. So suppress them. + $show_errors = $wpdb->show_errors; + $wpdb->show_errors = false; + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + $wpdb->query( + $wpdb->prepare( + "DELETE FROM %i WHERE %i = 'user'", + [ Model::get_table_name( 'Indexable' ), 'object_type' ], + ), + ); + + $wpdb->show_errors = $show_errors; + } + + /** + * Creates a query for de-duplicating indexables for a particular type. + * + * @param string $object_type The object type to deduplicate. + * @param string|array> $duplicates The result of the duplicate query. + * @param wpdb $wpdb The wpdb object. + * + * @return string The query that removes all but one duplicate for each object of the object type. + */ + protected function get_indexable_deduplication_query_for_type( $object_type, $duplicates, $wpdb ) { + $filtered_duplicates = array_filter( + $duplicates, + static function ( $duplicate ) use ( $object_type ) { + return $duplicate['object_type'] === $object_type; + }, + ); + + if ( empty( $filtered_duplicates ) ) { + return ''; + } + + $object_ids = wp_list_pluck( $filtered_duplicates, 'object_id' ); + $newest_indexable_ids = wp_list_pluck( $filtered_duplicates, 'newest_id' ); + + $replacements = array_merge( + [ + Model::get_table_name( 'Indexable' ), + 'object_id', + ], + array_values( $object_ids ), + array_values( $newest_indexable_ids ), + ); + $replacements[] = $object_type; + + // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery -- Reason: Most performant way. + return $wpdb->prepare( + 'DELETE FROM + %i + WHERE + %i IN ( ' . implode( ', ', array_fill( 0, count( $filtered_duplicates ), '%d' ) ) . ' ) + AND id NOT IN ( ' . implode( ', ', array_fill( 0, count( $filtered_duplicates ), '%d' ) ) . ' ) + AND object_type = %s', + $replacements, + ); + } + + /** + * Removes the settings' introduction modal data for users. + * + * @return void + */ + public function delete_user_introduction_meta() { + delete_metadata( 'user', 0, '_yoast_settings_introduction', '', true ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-admin-bar-menu.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-admin-bar-menu.php new file mode 100644 index 0000000..c96068d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-admin-bar-menu.php @@ -0,0 +1,978 @@ +classes->get( Indexable_Repository::class ); + } + if ( ! $score_icon_helper ) { + $score_icon_helper = YoastSEO()->helpers->score_icon; + } + if ( ! $product_helper ) { + $product_helper = YoastSEO()->helpers->product; + } + if ( ! $shortlinker ) { + $shortlinker = new WPSEO_Shortlinker(); + } + + $this->product_helper = $product_helper; + $this->asset_manager = $asset_manager; + $this->indexable_repository = $indexable_repository; + $this->score_icon_helper = $score_icon_helper; + $this->shortlinker = $shortlinker; + } + + /** + * Gets whether SEO score is enabled, with cache applied. + * + * @return bool True if SEO score is enabled, false otherwise. + */ + protected function get_is_seo_enabled() { + $this->is_seo_enabled ??= ( new WPSEO_Metabox_Analysis_SEO() )->is_enabled(); + + return $this->is_seo_enabled; + } + + /** + * Gets whether readability is enabled, with cache applied. + * + * @return bool True if readability is enabled, false otherwise. + */ + protected function get_is_readability_enabled() { + $this->is_readability_enabled ??= ( new WPSEO_Metabox_Analysis_Readability() )->is_enabled(); + + return $this->is_readability_enabled; + } + + /** + * Returns the indexable for the current WordPress page, with cache applied. + * + * @return bool|Indexable The indexable, false if none could be found. + */ + protected function get_current_indexable() { + $this->current_indexable ??= $this->indexable_repository->for_current_page(); + + return $this->current_indexable; + } + + /** + * Adds the admin bar menu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + public function add_menu( WP_Admin_Bar $wp_admin_bar ) { + // On block editor pages, the admin bar only shows on mobile, where having this menu icon is not very helpful. + if ( is_admin() ) { + $screen = get_current_screen(); + if ( isset( $screen ) && $screen->is_block_editor() ) { + return; + } + } + + // If the current user can't write posts, this is all of no use, so let's not output an admin menu. + if ( ! current_user_can( 'edit_posts' ) ) { + return; + } + + $this->add_root_menu( $wp_admin_bar ); + + /** + * Adds a submenu item in the top of the adminbar. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * @param string $menu_identifier The menu identifier. + */ + do_action( 'wpseo_add_adminbar_submenu', $wp_admin_bar, self::MENU_IDENTIFIER ); + + if ( ! is_admin() ) { + + if ( is_singular() || is_tag() || is_tax() || is_category() ) { + $is_seo_enabled = $this->get_is_seo_enabled(); + $is_readability_enabled = $this->get_is_readability_enabled(); + + $indexable = $this->get_current_indexable(); + + if ( $is_seo_enabled ) { + $focus_keyword = ( ! is_a( $indexable, 'Yoast\WP\SEO\Models\Indexable' ) || $indexable->primary_focus_keyword === null ) ? __( 'not set', 'wordpress-seo' ) : $indexable->primary_focus_keyword; + + $wp_admin_bar->add_menu( + [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-seo-focus-keyword', + 'title' => __( 'Focus keyphrase: ', 'wordpress-seo' ) . '' . $focus_keyword . '', + 'meta' => [ 'tabindex' => '0' ], + ], + ); + $wp_admin_bar->add_menu( + [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-seo-score', + 'title' => __( 'SEO score', 'wordpress-seo' ) . ': ' . $this->score_icon_helper->for_seo( $indexable, 'adminbar-sub-menu-score' ) + ->present(), + 'meta' => [ 'tabindex' => '0' ], + ], + ); + } + + if ( $is_readability_enabled ) { + $wp_admin_bar->add_menu( + [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-readability-score', + 'title' => __( 'Readability', 'wordpress-seo' ) . ': ' . $this->score_icon_helper->for_readability( $indexable->readability_score, 'adminbar-sub-menu-score' ) + ->present(), + 'meta' => [ 'tabindex' => '0' ], + ], + ); + } + + if ( ! $this->product_helper->is_premium() ) { + $wp_admin_bar->add_menu( + [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-frontend-inspector', + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-frontend-inspector' ), + 'title' => __( 'Front-end SEO inspector', 'wordpress-seo' ) . new Premium_Badge_Presenter( 'wpseo-frontend-inspector-badge' ), + 'meta' => [ + 'tabindex' => '0', + 'target' => '_blank', + ], + ], + ); + } + } + $this->add_analysis_submenu( $wp_admin_bar ); + $this->add_seo_tools_submenu( $wp_admin_bar ); + $this->add_how_to_submenu( $wp_admin_bar ); + $this->add_get_help_submenu( $wp_admin_bar ); + } + + if ( ! is_admin() || is_blog_admin() ) { + $this->add_settings_submenu( $wp_admin_bar ); + } + elseif ( is_network_admin() ) { + $this->add_network_settings_submenu( $wp_admin_bar ); + } + + $this->add_premium_link( $wp_admin_bar ); + $this->add_brand_insights_link( $wp_admin_bar ); + } + + /** + * Enqueues admin bar assets. + * + * @return void + */ + public function enqueue_assets() { + if ( ! is_admin_bar_showing() ) { + return; + } + + // If the current user can't write posts, this is all of no use, so let's not output an admin menu. + if ( ! current_user_can( 'edit_posts' ) ) { + return; + } + + $this->asset_manager->register_assets(); + $this->asset_manager->enqueue_style( 'adminbar' ); + } + + /** + * Registers the hooks. + * + * @return void + */ + public function register_hooks() { + if ( ! $this->meets_requirements() ) { + return; + } + + add_action( 'admin_bar_menu', [ $this, 'add_menu' ], 95 ); + + add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_assets' ] ); + add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] ); + } + + /** + * Checks whether the requirements to use this class are met. + * + * @return bool True if requirements are met, false otherwise. + */ + public function meets_requirements() { + if ( is_network_admin() ) { + return WPSEO_Utils::is_plugin_network_active(); + } + + if ( WPSEO_Options::get( 'enable_admin_bar_menu' ) !== true ) { + return false; + } + + return ! is_admin() || is_blog_admin(); + } + + /** + * Adds the admin bar root menu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_root_menu( WP_Admin_Bar $wp_admin_bar ) { + $title = $this->get_title(); + + $score = ''; + $settings_url = ''; + $counter = ''; + $notification_popup = ''; + $notification_count = 0; + + $post = $this->get_singular_post(); + if ( $post ) { + $score = $this->get_post_score( $post ); + } + + $term = $this->get_singular_term(); + if ( $term ) { + $score = $this->get_term_score( $term ); + } + + $can_manage_options = $this->can_manage_options(); + + if ( $can_manage_options ) { + $settings_url = $this->get_settings_page_url(); + } + + if ( empty( $score ) && ! is_network_admin() && $can_manage_options ) { + $notification_center = Yoast_Notification_Center::get(); + $notification_count = $notification_center->get_notification_count(); + + $counter = $this->get_notification_counter( $notification_count ); + $notification_popup = $this->get_notification_popup(); + } + + $admin_bar_menu_args = [ + 'id' => self::MENU_IDENTIFIER, + 'title' => $title . $score . $counter . $notification_popup, + 'href' => $settings_url, + 'meta' => [ 'tabindex' => ! empty( $settings_url ) ? false : '0' ], + ]; + $wp_admin_bar->add_menu( $admin_bar_menu_args ); + + if ( $notification_count > 0 ) { + $admin_bar_menu_args = [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-notifications', + 'title' => __( 'Notifications', 'wordpress-seo' ) . $counter, + 'href' => empty( $settings_url ) ? '' : $settings_url . '#/alert-center', + 'meta' => [ 'tabindex' => ! empty( $settings_url ) ? false : '0' ], + ]; + $wp_admin_bar->add_menu( $admin_bar_menu_args ); + } + } + + /** + * Adds the admin bar analysis submenu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_analysis_submenu( WP_Admin_Bar $wp_admin_bar ) { + try { + $url = YoastSEO()->meta->for_current_page()->canonical; + } catch ( Exception $e ) { + // This is not the type of error we can handle here. + return; + } + + if ( ! $url ) { + return; + } + + $menu_args = [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => self::ANALYSIS_SUBMENU_IDENTIFIER, + 'title' => __( 'Analyze this page', 'wordpress-seo' ), + 'meta' => [ 'tabindex' => '0' ], + ]; + $wp_admin_bar->add_menu( $menu_args ); + + $encoded_url = rawurlencode( $url ); + $submenu_items = [ + [ + 'id' => 'wpseo-inlinks', + 'title' => __( 'Check links to this URL', 'wordpress-seo' ), + 'href' => 'https://search.google.com/search-console/links/drilldown?resource_id=' . rawurlencode( get_option( 'siteurl' ) ) . '&type=EXTERNAL&target=' . $encoded_url . '&domain=', + ], + [ + 'id' => 'wpseo-structureddata', + 'title' => __( 'Google Rich Results Test', 'wordpress-seo' ), + 'href' => 'https://search.google.com/test/rich-results?url=' . $encoded_url, + ], + [ + 'id' => 'wpseo-facebookdebug', + 'title' => __( 'Facebook Debugger', 'wordpress-seo' ), + 'href' => '//developers.facebook.com/tools/debug/?q=' . $encoded_url, + ], + [ + 'id' => 'wpseo-pagespeed', + 'title' => __( 'Google Page Speed Test', 'wordpress-seo' ), + 'href' => '//developers.google.com/speed/pagespeed/insights/?url=' . $encoded_url, + ], + ]; + + $this->add_submenu_items( $submenu_items, $wp_admin_bar, self::ANALYSIS_SUBMENU_IDENTIFIER ); + } + + /** + * Adds the admin bar tools submenu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_seo_tools_submenu( WP_Admin_Bar $wp_admin_bar ) { + $menu_args = [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-sub-tools', + 'title' => __( 'SEO Tools', 'wordpress-seo' ), + 'meta' => [ 'tabindex' => '0' ], + ]; + $wp_admin_bar->add_menu( $menu_args ); + + $submenu_items = [ + [ + 'id' => 'wpseo-semrush', + 'title' => 'Semrush', + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-semrush' ), + ], + [ + 'id' => 'wpseo-wincher', + 'title' => 'Wincher', + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-wincher' ), + ], + [ + 'id' => 'wpseo-google-trends', + 'title' => 'Google trends', + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-gtrends' ), + ], + ]; + + $this->add_submenu_items( $submenu_items, $wp_admin_bar, 'wpseo-sub-tools' ); + } + + /** + * Adds the admin bar How To submenu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_how_to_submenu( WP_Admin_Bar $wp_admin_bar ) { + $menu_args = [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-sub-howto', + 'title' => __( 'How to', 'wordpress-seo' ), + 'meta' => [ 'tabindex' => '0' ], + ]; + $wp_admin_bar->add_menu( $menu_args ); + + $submenu_items = [ + [ + 'id' => 'wpseo-learn-seo', + 'title' => __( 'Learn more SEO', 'wordpress-seo' ), + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-learn-more-seo' ), + ], + [ + 'id' => 'wpseo-improve-blogpost', + 'title' => __( 'Improve your blog post', 'wordpress-seo' ), + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-improve-blog-post' ), + ], + [ + 'id' => 'wpseo-write-better-content', + 'title' => __( 'Write better content', 'wordpress-seo' ), + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-write-better' ), + ], + ]; + + $this->add_submenu_items( $submenu_items, $wp_admin_bar, 'wpseo-sub-howto' ); + } + + /** + * Adds the admin bar How To submenu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_get_help_submenu( WP_Admin_Bar $wp_admin_bar ) { + $menu_args = [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-sub-get-help', + 'title' => __( 'Help', 'wordpress-seo' ), + 'meta' => [ 'tabindex' => '0' ], + ]; + + if ( current_user_can( Support_Integration::CAPABILITY ) ) { + $menu_args['href'] = admin_url( 'admin.php?page=' . Support_Integration::PAGE ); + $wp_admin_bar->add_menu( $menu_args ); + + return; + } + $wp_admin_bar->add_menu( $menu_args ); + + $submenu_items = [ + [ + 'id' => 'wpseo-yoast-help', + 'title' => __( 'Yoast.com help section', 'wordpress-seo' ), + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-yoast-help' ), + ], + [ + 'id' => 'wpseo-premium-support', + 'title' => __( 'Yoast Premium support', 'wordpress-seo' ), + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-premium-support' ), + ], + [ + 'id' => 'wpseo-wp-support-forums', + 'title' => __( 'WordPress.org support forums', 'wordpress-seo' ), + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-wp-support-forums' ), + ], + [ + 'id' => 'wpseo-learn-seo-2', + 'title' => __( 'Learn more SEO', 'wordpress-seo' ), + 'href' => $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-learn-more-seo-help' ), + ], + ]; + + $this->add_submenu_items( $submenu_items, $wp_admin_bar, 'wpseo-sub-get-help' ); + } + + /** + * Adds the admin bar How To submenu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_premium_link( WP_Admin_Bar $wp_admin_bar ) { + // Don't show the Upgrade button if Yoast SEO WooCommerce addon is active. + $addon_manager = new WPSEO_Addon_Manager(); + if ( $addon_manager->is_installed( WPSEO_Addon_Manager::WOOCOMMERCE_SLUG ) ) { + return; + } + + $has_woocommerce = ( new Woocommerce_Conditional() )->is_met(); + + // Don't show the Upgrade button if Premium is active without the WooCommerce plugin. + if ( $this->product_helper->is_premium() && ! $has_woocommerce ) { + return; + } + + $link = $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-get-premium' ); + + if ( $has_woocommerce ) { + $link = $this->shortlinker->build_shortlink( 'https://yoa.st/admin-bar-get-premium-woocommerce' ); + } + + $button_label = esc_html__( 'Upgrade', 'wordpress-seo' ); + + if ( YoastSEO()->classes->get( Promotion_Manager::class )->is( 'black-friday-promotion' ) ) { + $button_label = esc_html__( '30% off - BF Sale', 'wordpress-seo' ); + } + $wp_admin_bar->add_menu( + [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => 'wpseo-get-premium', + // Circumvent an issue in the WP admin bar API in order to pass `data` attributes. See https://core.trac.wordpress.org/ticket/38636. + 'title' => sprintf( + '%2$s', + esc_url( $link ), + $button_label, + ), + 'meta' => [ + 'tabindex' => '0', + ], + ], + ); + } + + /** + * Adds the Brand Insights link to the admin bar. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_brand_insights_link( WP_Admin_Bar $wp_admin_bar ) { + $page = $this->product_helper->is_premium() ? 'wpseo_brand_insights_premium' : 'wpseo_brand_insights'; + + $button_content = 'AI Brand Insights'; + + $menu_title = '' + . '' + . $button_content + . Brand_Insights_Page::EXTERNAL_LINK_ICON + . ''; + + $wp_admin_bar->add_menu( + [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => $page, + 'title' => $menu_title, + 'href' => admin_url( 'admin.php?page=' . $page ), + 'meta' => [ + 'tabindex' => '0', + 'target' => '_blank', + ], + ], + ); + } + + /** + * Adds the admin bar settings submenu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_settings_submenu( WP_Admin_Bar $wp_admin_bar ) { + if ( ! $this->can_manage_options() ) { + return; + } + + $admin_menu = new WPSEO_Admin_Menu( new WPSEO_Menu() ); + $submenu_pages = $admin_menu->get_submenu_pages(); + + $menu_args = [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => self::SETTINGS_SUBMENU_IDENTIFIER, + 'title' => __( 'SEO Settings', 'wordpress-seo' ), + 'meta' => [ 'tabindex' => '0' ], + ]; + $wp_admin_bar->add_menu( $menu_args ); + + foreach ( $submenu_pages as $submenu_page ) { + if ( ! current_user_can( $submenu_page[3] ) ) { + continue; + } + + // Don't add the Google Search Console menu item. + if ( $submenu_page[4] === 'wpseo_search_console' ) { + continue; + } + + // Don't add the Brand Insights menu items (they're now in the main menu). + if ( $submenu_page[4] === 'wpseo_brand_insights' || $submenu_page[4] === 'wpseo_brand_insights_premium' ) { + continue; + } + + $id = 'wpseo-' . str_replace( '_', '-', str_replace( 'wpseo_', '', $submenu_page[4] ) ); + if ( $id === 'wpseo-dashboard' ) { + $id = 'wpseo-general'; + } + + $menu_args = [ + 'parent' => self::SETTINGS_SUBMENU_IDENTIFIER, + 'id' => $id, + 'title' => $submenu_page[2], + 'href' => admin_url( 'admin.php?page=' . rawurlencode( $submenu_page[4] ) ), + ]; + $wp_admin_bar->add_menu( $menu_args ); + } + } + + /** + * Adds the admin bar network settings submenu. + * + * @param WP_Admin_Bar $wp_admin_bar Admin bar instance to add the menu to. + * + * @return void + */ + protected function add_network_settings_submenu( WP_Admin_Bar $wp_admin_bar ) { + if ( ! $this->can_manage_options() ) { + return; + } + + $network_admin_menu = new WPSEO_Network_Admin_Menu( new WPSEO_Menu() ); + $submenu_pages = $network_admin_menu->get_submenu_pages(); + + $menu_args = [ + 'parent' => self::MENU_IDENTIFIER, + 'id' => self::NETWORK_SETTINGS_SUBMENU_IDENTIFIER, + 'title' => __( 'SEO Settings', 'wordpress-seo' ), + 'meta' => [ 'tabindex' => '0' ], + ]; + $wp_admin_bar->add_menu( $menu_args ); + + foreach ( $submenu_pages as $submenu_page ) { + if ( ! current_user_can( $submenu_page[3] ) ) { + continue; + } + + $id = 'wpseo-' . str_replace( '_', '-', str_replace( 'wpseo_', '', $submenu_page[4] ) ); + if ( $id === 'wpseo-dashboard' ) { + $id = 'wpseo-general'; + } + + $menu_args = [ + 'parent' => self::NETWORK_SETTINGS_SUBMENU_IDENTIFIER, + 'id' => $id, + 'title' => $submenu_page[2], + 'href' => network_admin_url( 'admin.php?page=' . rawurlencode( $submenu_page[4] ) ), + ]; + $wp_admin_bar->add_menu( $menu_args ); + } + } + + /** + * Gets the menu title markup. + * + * @return string Admin bar title markup. + */ + protected function get_title() { + return ''; + } + + /** + * Gets the current post if in a singular post context. + * + * @global string $pagenow Current page identifier. + * @global WP_Post|null $post Current post object, or null if none available. + * + * @return WP_Post|null Post object, or null if not in singular context. + */ + protected function get_singular_post() { + global $pagenow, $post; + + if ( ! is_singular() && ( ! is_blog_admin() || ! WPSEO_Metabox::is_post_edit( $pagenow ) ) ) { + return null; + } + + if ( ! isset( $post ) || ! is_object( $post ) || ! $post instanceof WP_Post ) { + return null; + } + + return $post; + } + + /** + * Gets the focus keyword for a given post. + * + * @param WP_Post $post Post object to get its focus keyword. + * + * @return string Focus keyword, or empty string if none available. + */ + protected function get_post_focus_keyword( $post ) { + if ( ! is_object( $post ) || ! property_exists( $post, 'ID' ) ) { + return ''; + } + + /** + * Filter: 'wpseo_use_page_analysis' Determines if the analysis should be enabled. + * + * @param bool $enabled Determines if the analysis should be enabled. + */ + if ( apply_filters( 'wpseo_use_page_analysis', true ) !== true ) { + return ''; + } + + return WPSEO_Meta::get_value( 'focuskw', $post->ID ); + } + + /** + * Gets the score for a given post. + * + * @param WP_Post $post Post object to get its score. + * + * @return string Score markup, or empty string if none available. + */ + protected function get_post_score( $post ) { + if ( ! is_object( $post ) || ! property_exists( $post, 'ID' ) ) { + return ''; + } + + if ( apply_filters( 'wpseo_use_page_analysis', true ) !== true ) { + return ''; + } + + return $this->get_score_icon(); + } + + /** + * Gets the current term if in a singular term context. + * + * @global string $pagenow Current page identifier. + * @global WP_Query $wp_query Current query object. + * @global WP_Term|null $tag Current term object, or null if none available. + * + * @return WP_Term|null Term object, or null if not in singular context. + */ + protected function get_singular_term() { + global $pagenow, $wp_query, $tag; + + if ( is_category() || is_tag() || is_tax() ) { + return $wp_query->get_queried_object(); + } + + if ( WPSEO_Taxonomy::is_term_edit( $pagenow ) && ! WPSEO_Taxonomy::is_term_overview( $pagenow ) && isset( $tag ) && is_object( $tag ) && ! is_wp_error( $tag ) ) { + return get_term( $tag->term_id ); + } + + return null; + } + + /** + * Gets the score for a given term. + * + * @param WP_Term $term Term object to get its score. + * + * @return string Score markup, or empty string if none available. + */ + protected function get_term_score( $term ) { + if ( ! is_object( $term ) || ! property_exists( $term, 'term_id' ) || ! property_exists( $term, 'taxonomy' ) ) { + return ''; + } + + return $this->get_score_icon(); + } + + /** + * Create the score icon. + * + * @return string The score icon, or empty string. + */ + protected function get_score_icon() { + $is_seo_enabled = $this->get_is_seo_enabled(); + $is_readability_enabled = $this->get_is_readability_enabled(); + + $indexable = $this->get_current_indexable(); + + if ( $is_seo_enabled ) { + return $this->score_icon_helper->for_seo( $indexable, 'adminbar-seo-score' )->present(); + } + + if ( $is_readability_enabled ) { + return $this->score_icon_helper->for_readability( $indexable->readability_score, 'adminbar-seo-score' ) + ->present(); + } + + return ''; + } + + /** + * Gets the URL to the main admin settings page. + * + * @return string Admin settings page URL. + */ + protected function get_settings_page_url() { + return self_admin_url( 'admin.php?page=' . WPSEO_Admin::PAGE_IDENTIFIER ); + } + + /** + * Gets the notification counter if in a valid context. + * + * @param int $notification_count Number of notifications. + * + * @return string Notification counter markup, or empty string if not available. + */ + protected function get_notification_counter( $notification_count ) { + /* translators: Hidden accessibility text; %s: number of notifications. */ + $counter_screen_reader_text = sprintf( _n( '%s notification', '%s notifications', $notification_count, 'wordpress-seo' ), number_format_i18n( $notification_count ) ); + + return sprintf( + '
            %s
            ', + ( $notification_count ) ? '' : ' wpseo-no-adminbar-notifications', + $notification_count, + $counter_screen_reader_text, + ); + } + + /** + * Gets the notification popup if in a valid context. + * + * @return string Notification popup markup, or empty string if not available. + */ + protected function get_notification_popup() { + $notification_center = Yoast_Notification_Center::get(); + $new_notifications = $notification_center->get_new_notifications(); + $new_notifications_count = count( $new_notifications ); + + if ( ! $new_notifications_count ) { + return ''; + } + + $notification = sprintf( + _n( + 'There is a new notification.', + 'There are new notifications.', + $new_notifications_count, + 'wordpress-seo', + ), + $new_notifications_count, + ); + + return '
            ' . $notification . '
            '; + } + + /** + * Checks whether the current user can manage options in the current context. + * + * @return bool True if capabilities are sufficient, false otherwise. + */ + protected function can_manage_options() { + return ( is_network_admin() && current_user_can( 'wpseo_manage_network_options' ) ) + || ( ! is_network_admin() && WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ); + } + + /** + * Add submenu items to a menu item. + * + * @param array $submenu_items Submenu items array. + * @param WP_Admin_Bar $wp_admin_bar Admin bar object. + * @param string $parent_id Parent menu item ID. + * + * @return void + */ + protected function add_submenu_items( array $submenu_items, WP_Admin_Bar $wp_admin_bar, $parent_id ) { + foreach ( $submenu_items as $menu_item ) { + $menu_args = [ + 'parent' => $parent_id, + 'id' => $menu_item['id'], + 'title' => $menu_item['title'], + 'href' => $menu_item['href'], + 'meta' => [ 'target' => '_blank' ], + ]; + $wp_admin_bar->add_menu( $menu_args ); + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-content-images.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-content-images.php new file mode 100644 index 0000000..9e23a91 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-content-images.php @@ -0,0 +1,110 @@ +get_images_from_content( $this->get_post_content( $post_id, $post ) ); + } + + /** + * Grabs the images from the content. + * + * @param string $content The post content string. + * + * @return array An array of image URLs. + */ + public function get_images_from_content( $content ) { + if ( ! is_string( $content ) ) { + return []; + } + + $content_images = $this->get_img_tags_from_content( $content ); + + $images = array_map( [ $this, 'get_img_tag_source' ], $content_images ); + $images = array_filter( $images ); + $images = array_unique( $images ); + $images = array_values( $images ); // Reset the array keys. + return $images; + } + + /** + * Gets the image tags from a given content string. + * + * @param string $content The content to search for image tags. + * + * @return array An array of `` tags. + */ + private function get_img_tags_from_content( $content ) { + if ( strpos( $content, ']+>`', $content, $matches ); + if ( isset( $matches[0] ) ) { + return $matches[0]; + } + + return []; + } + + /** + * Retrieves the image URL from an image tag. + * + * @param string $image Image HTML element. + * + * @return string|bool The image URL on success, false on failure. + */ + private function get_img_tag_source( $image ) { + preg_match( '`src=(["\'])(.*?)\1`', $image, $matches ); + if ( isset( $matches[2] ) && filter_var( $matches[2], FILTER_VALIDATE_URL ) ) { + return $matches[2]; + } + return false; + } + + /** + * Retrieves the post content we want to work with. + * + * @param int $post_id The post ID. + * @param WP_Post|array|null $post The post. + * + * @return string The content of the supplied post. + */ + private function get_post_content( $post_id, $post ) { + $post ??= get_post( $post_id ); + + if ( $post === null ) { + return ''; + } + + /** + * Filter: 'wpseo_pre_analysis_post_content' - Allow filtering the content before analysis. + * + * @param string $post_content The Post content string. + * @param WP_Post $post The current post. + */ + $content = apply_filters( 'wpseo_pre_analysis_post_content', $post->post_content, $post ); + + if ( ! is_string( $content ) ) { + $content = ''; + } + + return $content; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-custom-fields.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-custom-fields.php new file mode 100644 index 0000000..0432aaa --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-custom-fields.php @@ -0,0 +1,75 @@ +postmeta + WHERE meta_key NOT BETWEEN '_' AND '_z' AND SUBSTRING(meta_key, 1, 1) != '_' + LIMIT %d"; + $fields = $wpdb->get_col( $wpdb->prepare( $sql, $limit ) ); + + /** + * Filters the custom fields that are auto-completed and replaced as replacement variables + * in the meta box and sidebar. + * + * @param string[] $fields The custom field names. + */ + $fields = apply_filters( 'wpseo_replacement_variables_custom_fields', $fields ); + + if ( is_array( $fields ) ) { + self::$custom_fields = array_map( [ 'WPSEO_Custom_Fields', 'add_custom_field_prefix' ], $fields ); + } + + return self::$custom_fields; + } + + /** + * Adds the cf_ prefix to a field. + * + * @param string $field The field to prefix. + * + * @return string The prefixed field. + */ + private static function add_custom_field_prefix( $field ) { + return 'cf_' . $field; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-custom-taxonomies.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-custom-taxonomies.php new file mode 100644 index 0000000..3d2f1ba --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-custom-taxonomies.php @@ -0,0 +1,72 @@ + true, + '_builtin' => false, + ]; + $custom_taxonomies = get_taxonomies( $args, 'names', 'and' ); + + if ( is_array( $custom_taxonomies ) ) { + foreach ( $custom_taxonomies as $custom_taxonomy ) { + array_push( + self::$custom_taxonomies, + self::add_custom_taxonomies_prefix( $custom_taxonomy ), + self::add_custom_taxonomies_description_prefix( $custom_taxonomy ), + ); + } + } + + return self::$custom_taxonomies; + } + + /** + * Adds the ct_ prefix to a taxonomy. + * + * @param string $taxonomy The taxonomy to prefix. + * + * @return string The prefixed taxonomy. + */ + private static function add_custom_taxonomies_prefix( $taxonomy ) { + return 'ct_' . $taxonomy; + } + + /** + * Adds the ct_desc_ prefix to a taxonomy. + * + * @param string $taxonomy The taxonomy to prefix. + * + * @return string The prefixed taxonomy. + */ + private static function add_custom_taxonomies_description_prefix( $taxonomy ) { + return 'ct_desc_' . $taxonomy; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-image-utils.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-image-utils.php new file mode 100644 index 0000000..dbb0b7d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-image-utils.php @@ -0,0 +1,533 @@ + $sizes The array of image sizes to loop through. + */ + return apply_filters( 'wpseo_image_sizes', [ 'full', 'large', 'medium_large' ] ); + } + + /** + * Grabs an image alt text. + * + * @param int $attachment_id The attachment ID. + * + * @return string The image alt text. + */ + public static function get_alt_tag( $attachment_id ) { + return (string) get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); + } + + /** + * Checks whether an img sizes up to the parameters. + * + * @param array $dimensions The image values. + * @param array $usable_dimensions The parameters to check against. + * + * @return bool True if the image has usable measurements, false if not. + */ + private static function has_usable_dimensions( $dimensions, $usable_dimensions ) { + foreach ( [ 'width', 'height' ] as $param ) { + $minimum = $usable_dimensions[ 'min_' . $param ]; + $maximum = $usable_dimensions[ 'max_' . $param ]; + + $current = $dimensions[ $param ]; + if ( ( $current < $minimum ) || ( $current > $maximum ) ) { + return false; + } + } + + return true; + } + + /** + * Gets the post's first usable content image. Null if none is available. + * + * @param int|null $post_id The post id. + * + * @return string|null The image URL. + */ + public static function get_first_usable_content_image_for_post( $post_id = null ) { + $post = get_post( $post_id ); + + // We know get_post() returns the post or null. + if ( ! $post ) { + return null; + } + + $image_finder = new WPSEO_Content_Images(); + $images = $image_finder->get_images( $post->ID, $post ); + + return self::get_first_image( $images ); + } + + /** + * Gets the term's first usable content image. Null if none is available. + * + * @param int $term_id The term id. + * + * @return string|null The image URL. + */ + public static function get_first_content_image_for_term( $term_id ) { + $term_description = term_description( $term_id ); + + // We know term_description() returns a string which may be empty. + if ( $term_description === '' ) { + return null; + } + + $image_finder = new WPSEO_Content_Images(); + $images = $image_finder->get_images_from_content( $term_description ); + + return self::get_first_image( $images ); + } + + /** + * Retrieves an attachment ID for an image uploaded in the settings. + * + * Due to self::get_attachment_by_url returning 0 instead of false. + * 0 is also a possibility when no ID is available. + * + * @param string $setting The setting the image is stored in. + * + * @return int|bool The attachment id, or false or 0 if no ID is available. + */ + public static function get_attachment_id_from_settings( $setting ) { + $image_id = WPSEO_Options::get( $setting . '_id', false ); + if ( $image_id ) { + return $image_id; + } + + $image = WPSEO_Options::get( $setting, false ); + if ( $image ) { + // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. + // This means an attachment always exists, so doing this is only needed once. + $image_id = self::get_attachment_by_url( $image ); + } + + // Only store a new ID if it is not 0, to prevent an update loop. + if ( $image_id ) { + WPSEO_Options::set( $setting . '_id', $image_id ); + } + + return $image_id; + } + + /** + * Retrieves the first possible image url from an array of images. + * + * @param array $images The array to extract image url from. + * + * @return string|null The extracted image url when found, null when not found. + */ + protected static function get_first_image( $images ) { + if ( ! is_array( $images ) ) { + return null; + } + + $images = array_filter( $images ); + if ( empty( $images ) ) { + return null; + } + + return reset( $images ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-installation.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-installation.php new file mode 100644 index 0000000..d4c8a05 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-installation.php @@ -0,0 +1,49 @@ +is_first_install(); + + if ( $is_first_install && WPSEO_Utils::is_api_available() ) { + add_action( 'wpseo_activate', [ $this, 'set_first_install_options' ] ); + } + } + + /** + * When the option doesn't exist, it should be a new install. + * + * @return bool + */ + private function is_first_install() { + return ( get_option( 'wpseo' ) === false ); + } + + /** + * Sets the options on first install for showing the installation notice and disabling of the settings pages. + * + * @return void + */ + public function set_first_install_options() { + $options = get_option( 'wpseo' ); + + $options['show_onboarding_notice'] = true; + $options['first_activated_on'] = time(); + $options['first_activated_by'] = get_current_user_id(); + + update_option( 'wpseo', $options ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-meta.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-meta.php new file mode 100644 index 0000000..61691cd --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-meta.php @@ -0,0 +1,1045 @@ + (string) field type. i.e. text / textarea / checkbox / + * radio / select / multiselect / upload etc. + * (recommended) 'default_value' => (string|array) default value for the field. + * IMPORTANT: + * - if the field has options, the default has to be the + * key of one of the options. + * - if the field is a text field, the default **has** to be + * an empty string as otherwise the user can't save + * an empty value/delete the meta value. + * - if the field is a checkbox, the only valid values + * are 'on' or 'off'. + * (semi-required) 'options' => (array) options for used with (multi-)select and radio + * fields, required if that's the field type. + * key = (string) value which will be saved to db. + * value = (string) text label for the option. + * (optional) 'autocomplete' => (bool) whether autocomplete is on for text fields, + * defaults to true. + * (optional) 'class' => (string) classname(s) to add to the actual tag. + * (optional) 'rows' => (int) number of rows for a textarea, defaults to 3. + * (optional) 'serialized' => (bool) whether the value is expected to be serialized, + * i.e. an array or object, defaults to false. + * Currently only used by add-on plugins. + */ + public static $meta_fields = [ + 'general' => [ + 'focuskw' => [ + 'type' => 'hidden', + 'title' => '', + ], + 'title' => [ + 'type' => 'hidden', + 'default_value' => '', + ], + 'metadesc' => [ + 'type' => 'hidden', + 'default_value' => '', + 'class' => 'metadesc', + 'rows' => 2, + ], + 'linkdex' => [ + 'type' => 'hidden', + 'default_value' => '0', + ], + 'content_score' => [ + 'type' => 'hidden', + 'default_value' => '0', + ], + 'inclusive_language_score' => [ + 'type' => 'hidden', + 'default_value' => '0', + ], + 'is_cornerstone' => [ + 'type' => 'hidden', + 'default_value' => 'false', + ], + ], + 'advanced' => [ + 'meta-robots-noindex' => [ + 'type' => 'hidden', + 'default_value' => '0', // = post-type default. + 'options' => [ + '0' => '', // Post type default. + '2' => '', // Index. + '1' => '', // No-index. + ], + ], + 'meta-robots-nofollow' => [ + 'type' => 'hidden', + 'default_value' => '0', // = follow. + 'options' => [ + '0' => '', // Follow. + '1' => '', // No-follow. + ], + ], + 'meta-robots-adv' => [ + 'type' => 'hidden', + 'default_value' => '', + 'options' => [ + 'noimageindex' => '', + 'noarchive' => '', + 'nosnippet' => '', + ], + ], + 'bctitle' => [ + 'type' => 'hidden', + 'default_value' => '', + ], + 'canonical' => [ + 'type' => 'hidden', + 'default_value' => '', + ], + 'redirect' => [ + 'type' => 'url', + 'default_value' => '', + ], + ], + 'social' => [], + 'schema' => [ + 'schema_page_type' => [ + 'type' => 'hidden', + 'options' => Schema_Types::PAGE_TYPES, + ], + 'schema_article_type' => [ + 'type' => 'hidden', + 'hide_on_pages' => true, + 'options' => Schema_Types::ARTICLE_TYPES, + ], + ], + /* Fields we should validate & save, but not show on any form. */ + 'non_form' => [ + 'linkdex' => [ + 'type' => null, + 'default_value' => '0', + ], + ], + ]; + + /** + * Helper property - reverse index of the definition array. + * + * Format: [full meta key including prefix] => array + * ['subset'] => (string) primary index + * ['key'] => (string) internal key + * + * @var array + */ + public static $fields_index = []; + + /** + * Helper property - array containing only the defaults in the format: + * [full meta key including prefix] => (string) default value + * + * @var array + */ + public static $defaults = []; + + /** + * Helper property to define the social network meta field definitions - networks. + * + * @var array + */ + private static $social_networks = [ + 'opengraph' => 'opengraph', + 'twitter' => 'twitter', + ]; + + /** + * Helper property to define the social network meta field definitions - fields and their type. + * + * @var array + */ + private static $social_fields = [ + 'title' => 'hidden', + 'description' => 'hidden', + 'image' => 'hidden', + 'image-id' => 'hidden', + ]; + + /** + * Register our actions and filters. + * + * @return void + */ + public static function init() { + foreach ( self::$social_networks as $option => $network ) { + if ( WPSEO_Options::get( $option, false, [ 'wpseo_social' ] ) === true ) { + foreach ( self::$social_fields as $box => $type ) { + self::$meta_fields['social'][ $network . '-' . $box ] = [ + 'type' => $type, + 'default_value' => '', + ]; + } + } + } + unset( $option, $network, $box, $type ); + + /** + * Allow add-on plugins to register their meta fields for management by this class. + * Calls to add_filter() must be made before plugins_loaded prio 14. + */ + $extra_fields = apply_filters( 'add_extra_wpseo_meta_fields', [] ); + if ( is_array( $extra_fields ) ) { + self::$meta_fields = self::array_merge_recursive_distinct( $extra_fields, self::$meta_fields ); + } + unset( $extra_fields ); + + foreach ( self::$meta_fields as $subset => $field_group ) { + foreach ( $field_group as $key => $field_def ) { + + register_meta( + 'post', + self::$meta_prefix . $key, + [ 'sanitize_callback' => [ self::class, 'sanitize_post_meta' ] ], + ); + + // Set the $fields_index property for efficiency. + self::$fields_index[ self::$meta_prefix . $key ] = [ + 'subset' => $subset, + 'key' => $key, + ]; + + // Set the $defaults property for efficiency. + if ( isset( $field_def['default_value'] ) ) { + self::$defaults[ self::$meta_prefix . $key ] = $field_def['default_value']; + } + else { + // Meta will always be a string, so let's make the meta meta default also a string. + self::$defaults[ self::$meta_prefix . $key ] = ''; + } + } + } + unset( $subset, $field_group, $key, $field_def ); + + self::filter_schema_article_types(); + + add_filter( 'update_post_metadata', [ self::class, 'remove_meta_if_default' ], 10, 5 ); + add_filter( 'add_post_metadata', [ self::class, 'dont_save_meta_if_default' ], 10, 4 ); + } + + /** + * Retrieve the meta box form field definitions for the given tab and post type. + * + * @param string $tab Tab for which to retrieve the field definitions. + * @param string $post_type Post type of the current post. + * + * @return array Array containing the meta box field definitions. + */ + public static function get_meta_field_defs( $tab, $post_type = 'post' ) { + if ( ! isset( self::$meta_fields[ $tab ] ) ) { + return []; + } + + $field_defs = self::$meta_fields[ $tab ]; + + switch ( $tab ) { + case 'non-form': + // Prevent non-form fields from being passed to forms. + $field_defs = []; + break; + + case 'advanced': + global $post; + + if ( ! WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) && WPSEO_Options::get( 'disableadvanced_meta' ) ) { + return []; + } + + $post_type = ''; + if ( isset( $post->post_type ) ) { + $post_type = $post->post_type; + } + elseif ( ! isset( $post->post_type ) && isset( $_GET['post_type'] ) ) { + $post_type = sanitize_text_field( $_GET['post_type'] ); + } + + if ( $post_type === '' ) { + return []; + } + + /* Don't show the breadcrumb title field if breadcrumbs aren't enabled. */ + if ( WPSEO_Options::get( 'breadcrumbs-enable', false ) !== true && ! current_theme_supports( 'yoast-seo-breadcrumbs' ) ) { + unset( $field_defs['bctitle'] ); + } + + if ( empty( $post->ID ) || ( ! empty( $post->ID ) && self::get_value( 'redirect', $post->ID ) === '' ) ) { + unset( $field_defs['redirect'] ); + } + break; + + case 'schema': + if ( ! WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) && WPSEO_Options::get( 'disableadvanced_meta' ) ) { + return []; + } + + $field_defs['schema_page_type']['default'] = WPSEO_Options::get( 'schema-page-type-' . $post_type ); + + $article_helper = new Article_Helper(); + if ( $article_helper->is_article_post_type( $post_type ) ) { + $default_schema_article_type = WPSEO_Options::get( 'schema-article-type-' . $post_type ); + + /** This filter is documented in inc/options/class-wpseo-option-titles.php */ + $allowed_article_types = apply_filters( 'wpseo_schema_article_types', Schema_Types::ARTICLE_TYPES ); + + if ( ! array_key_exists( $default_schema_article_type, $allowed_article_types ) ) { + $default_schema_article_type = WPSEO_Options::get_default( 'wpseo_titles', 'schema-article-type-' . $post_type ); + } + $field_defs['schema_article_type']['default'] = $default_schema_article_type; + } + else { + unset( $field_defs['schema_article_type'] ); + } + + break; + } + + /** + * Filter the WPSEO metabox form field definitions for a tab. + * {tab} can be 'general', 'advanced' or 'social'. + * + * @param array $field_defs Metabox form field definitions. + * @param string $post_type Post type of the post the metabox is for, defaults to 'post'. + * + * @return array + */ + return apply_filters( 'wpseo_metabox_entries_' . $tab, $field_defs, $post_type ); + } + + /** + * Validate the post meta values. + * + * @param mixed $meta_value The new value. + * @param string $meta_key The full meta key (including prefix). + * + * @return string Validated meta value. + */ + public static function sanitize_post_meta( $meta_value, $meta_key ) { + $field_def = self::$meta_fields[ self::$fields_index[ $meta_key ]['subset'] ][ self::$fields_index[ $meta_key ]['key'] ]; + $clean = self::$defaults[ $meta_key ]; + + switch ( true ) { + case ( $meta_key === self::$meta_prefix . 'linkdex' ): + $int = WPSEO_Utils::validate_int( $meta_value ); + if ( $int !== false && $int >= 0 ) { + $clean = (string) $int; // Convert to string to make sure default check works. + } + break; + + case ( $field_def['type'] === 'checkbox' ): + // Only allow value if it's one of the predefined options. + if ( in_array( $meta_value, [ 'on', 'off' ], true ) ) { + $clean = $meta_value; + } + break; + + case ( $field_def['type'] === 'select' || $field_def['type'] === 'radio' ): + // Only allow value if it's one of the predefined options. + if ( isset( $field_def['options'][ $meta_value ] ) ) { + $clean = $meta_value; + } + break; + + case ( $field_def['type'] === 'hidden' && $meta_key === self::$meta_prefix . 'meta-robots-adv' ): + $clean = self::validate_meta_robots_adv( $meta_value ); + break; + + case ( $field_def['type'] === 'url' || $meta_key === self::$meta_prefix . 'canonical' ): + // Validate as url(-part). + $url = WPSEO_Utils::sanitize_url( $meta_value ); + if ( $url !== '' ) { + $clean = $url; + } + break; + + case ( $field_def['type'] === 'upload' && in_array( $meta_key, [ self::$meta_prefix . 'opengraph-image', self::$meta_prefix . 'twitter-image' ], true ) ): + // Validate as url. + $url = WPSEO_Utils::sanitize_url( $meta_value, [ 'http', 'https', 'ftp', 'ftps' ] ); + if ( $url !== '' ) { + $clean = $url; + } + break; + + case ( $field_def['type'] === 'hidden' && $meta_key === self::$meta_prefix . 'is_cornerstone' ): + $clean = $meta_value; + + /* + * This used to be a checkbox, then became a hidden input. + * To make sure the value remains consistent, we cast 'true' to '1'. + */ + if ( $meta_value === 'true' ) { + $clean = '1'; + } + break; + + case ( $field_def['type'] === 'hidden' && isset( $field_def['options'] ) ): + // Only allow value if it's one of the predefined options. + if ( isset( $field_def['options'][ $meta_value ] ) ) { + $clean = $meta_value; + } + break; + + case ( $field_def['type'] === 'textarea' ): + if ( is_string( $meta_value ) ) { + // Remove line breaks and tabs. + // @todo [JRF => Yoast] Verify that line breaks and the likes aren't allowed/recommended in meta header fields. + $meta_value = str_replace( [ "\n", "\r", "\t", ' ' ], ' ', $meta_value ); + $clean = WPSEO_Utils::sanitize_text_field( trim( $meta_value ) ); + } + break; + + case ( $field_def['type'] === 'multiselect' ): + $clean = $meta_value; + break; + + case ( $field_def['type'] === 'text' ): + default: + if ( is_string( $meta_value ) ) { + $clean = WPSEO_Utils::sanitize_text_field( trim( $meta_value ) ); + } + + break; + } + + $clean = apply_filters( 'wpseo_sanitize_post_meta_' . $meta_key, $clean, $meta_value, $field_def, $meta_key ); + + return $clean; + } + + /** + * Validate a meta-robots-adv meta value. + * + * @todo [JRF => Yoast] Verify that this logic for the prioritisation is correct. + * + * @param array|string $meta_value The value to validate. + * + * @return string Clean value. + */ + public static function validate_meta_robots_adv( $meta_value ) { + $clean = self::$meta_fields['advanced']['meta-robots-adv']['default_value']; + $options = self::$meta_fields['advanced']['meta-robots-adv']['options']; + + if ( is_string( $meta_value ) ) { + $meta_value = explode( ',', $meta_value ); + } + + if ( is_array( $meta_value ) && $meta_value !== [] ) { + $meta_value = array_map( 'trim', $meta_value ); + + // Individual selected entries. + $cleaning = []; + foreach ( $meta_value as $value ) { + if ( isset( $options[ $value ] ) ) { + $cleaning[] = $value; + } + } + + if ( $cleaning !== [] ) { + $clean = implode( ',', $cleaning ); + } + unset( $cleaning, $value ); + } + + return $clean; + } + + /** + * Prevent saving of default values and remove potential old value from the database if replaced by a default. + * + * @param bool $check The current status to allow updating metadata for the given type. + * @param int $object_id ID of the current object for which the meta is being updated. + * @param string $meta_key The full meta key (including prefix). + * @param string $meta_value New meta value. + * @param string $prev_value The old meta value. + * + * @return bool|null True = stop saving, null = continue saving. + */ + public static function remove_meta_if_default( $check, $object_id, $meta_key, $meta_value, $prev_value = '' ) { + /* If it's one of our meta fields, check against default. */ + if ( isset( self::$fields_index[ $meta_key ] ) && self::meta_value_is_default( $meta_key, $meta_value ) === true ) { + if ( $prev_value !== '' ) { + delete_post_meta( $object_id, $meta_key, $prev_value ); + } + else { + delete_post_meta( $object_id, $meta_key ); + } + + return true; // Stop saving the value. + } + + return $check; // Go on with the normal execution (update) in meta.php. + } + + /** + * Prevent adding of default values to the database. + * + * @param bool $check The current status to allow adding metadata for the given type. + * @param int $object_id ID of the current object for which the meta is being added. + * @param string $meta_key The full meta key (including prefix). + * @param string $meta_value New meta value. + * + * @return bool|null True = stop saving, null = continue saving. + */ + public static function dont_save_meta_if_default( $check, $object_id, $meta_key, $meta_value ) { + /* If it's one of our meta fields, check against default. */ + if ( isset( self::$fields_index[ $meta_key ] ) && self::meta_value_is_default( $meta_key, $meta_value ) === true ) { + return true; // Stop saving the value. + } + + return $check; // Go on with the normal execution (add) in meta.php. + } + + /** + * Is the given meta value the same as the default value ? + * + * @param string $meta_key The full meta key (including prefix). + * @param mixed $meta_value The value to check. + * + * @return bool + */ + public static function meta_value_is_default( $meta_key, $meta_value ) { + return ( isset( self::$defaults[ $meta_key ] ) && $meta_value === self::$defaults[ $meta_key ] ); + } + + /** + * Get a custom post meta value. + * + * Returns the default value if the meta value has not been set. + * + * {@internal Unfortunately there isn't a filter available to hook into before returning + * the results for get_post_meta(), get_post_custom() and the likes. That + * would have been the preferred solution.}} + * + * @param string $key Internal key of the value to get (without prefix). + * @param int $postid Post ID of the post to get the value for. + * + * @return string All 'normal' values returned from get_post_meta() are strings. + * Objects and arrays are possible, but not used by this plugin + * and therefore discarted (except when the special 'serialized' field def + * value is set to true - only used by add-on plugins for now). + * Will return the default value if no value was found. + * Will return empty string if no default was found (not one of our keys) or + * if the post does not exist. + */ + public static function get_value( $key, $postid = 0 ) { + global $post; + + $postid = absint( $postid ); + if ( $postid === 0 ) { + if ( ( isset( $post ) && is_object( $post ) ) && ( isset( $post->post_status ) && $post->post_status !== 'auto-draft' ) ) { + $postid = $post->ID; + } + else { + return ''; + } + } + + $custom = get_post_custom( $postid ); // Array of strings or empty array. + $table_key = self::$meta_prefix . $key; + + // Populate the field_def using the field_index lookup array. + $field_def = []; + if ( isset( self::$fields_index[ $table_key ] ) ) { + $field_def = self::$meta_fields[ self::$fields_index[ $table_key ]['subset'] ][ self::$fields_index[ $table_key ]['key'] ]; + } + + // Check if we have a custom post meta entry. + if ( isset( $custom[ $table_key ][0] ) ) { + $unserialized = maybe_unserialize( $custom[ $table_key ][0] ); + + // Check if it is already unserialized. + if ( $custom[ $table_key ][0] === $unserialized ) { + return $custom[ $table_key ][0]; + } + + // Check whether we need to unserialize it. + if ( isset( $field_def['serialized'] ) && $field_def['serialized'] === true ) { + // Ok, serialize value expected/allowed. + return $unserialized; + } + } + + // Meta was either not found or found, but object/array while not allowed to be. + if ( isset( self::$defaults[ self::$meta_prefix . $key ] ) ) { + // Update the default value to the current post type. + switch ( $key ) { + case 'schema_page_type': + case 'schema_article_type': + return ''; + } + + return self::$defaults[ self::$meta_prefix . $key ]; + } + + /* + * Shouldn't ever happen, means not one of our keys as there will always be a default available + * for all our keys. + */ + return ''; + } + + /** + * Update a meta value for a post. + * + * @param string $key The internal key of the meta value to change (without prefix). + * @param mixed $meta_value The value to set the meta to. + * @param int $post_id The ID of the post to change the meta for. + * + * @return bool Whether the value was changed. + */ + public static function set_value( $key, $meta_value, $post_id ) { + /* + * Slash the data, because `update_metadata` will unslash it and we have already unslashed it. + * Related issue: https://github.com/Yoast/YoastSEO.js/issues/2158 + */ + $meta_value = wp_slash( $meta_value ); + + return update_post_meta( $post_id, self::$meta_prefix . $key, $meta_value ); + } + + /** + * Deletes a meta value for a post. + * + * @param string $key The internal key of the meta value to change (without prefix). + * @param int $post_id The ID of the post to delete the meta for. + * + * @return bool Whether the delete was successful or not. + */ + public static function delete( $key, $post_id ) { + return delete_post_meta( $post_id, self::$meta_prefix . $key ); + } + + /** + * Used for imports, this functions imports the value of $old_metakey into $new_metakey for those post + * where no WPSEO meta data has been set. + * Optionally deletes the $old_metakey values. + * + * @param string $old_metakey The old key of the meta value. + * @param string $new_metakey The new key, usually the WPSEO meta key (including prefix). + * @param bool $delete_old Whether to delete the old meta key/value-sets. + * + * @return void + */ + public static function replace_meta( $old_metakey, $new_metakey, $delete_old = false ) { + global $wpdb; + + /* + * Get only those rows where no wpseo meta values exist for the same post + * (with the exception of linkdex as that will be set independently of whether the post has been edited). + * + * {@internal Query is pretty well optimized this way.}} + */ + $query = $wpdb->prepare( + " + SELECT `a`.* + FROM {$wpdb->postmeta} AS a + WHERE `a`.`meta_key` = %s + AND NOT EXISTS ( + SELECT DISTINCT `post_id` , count( `meta_id` ) AS count + FROM {$wpdb->postmeta} AS b + WHERE `a`.`post_id` = `b`.`post_id` + AND `meta_key` LIKE %s + AND `meta_key` <> %s + GROUP BY `post_id` + ) + ;", + $old_metakey, + $wpdb->esc_like( self::$meta_prefix . '%' ), + self::$meta_prefix . 'linkdex', + ); + $oldies = $wpdb->get_results( $query ); + + if ( is_array( $oldies ) && $oldies !== [] ) { + foreach ( $oldies as $old ) { + update_post_meta( $old->post_id, $new_metakey, $old->meta_value ); + } + } + + // Delete old keys. + if ( $delete_old === true ) { + delete_post_meta_by_key( $old_metakey ); + } + } + + /** + * General clean-up of the saved meta values. + * - Remove potentially lingering old meta keys; + * - Remove all default and invalid values. + * + * @return void + */ + public static function clean_up() { + global $wpdb; + + /* + * Clean up '_yoast_wpseo_meta-robots'. + * + * Retrieve all '_yoast_wpseo_meta-robots' meta values and convert if no new values found. + * + * {@internal Query is pretty well optimized this way.}} + * + * @todo [JRF => Yoast] Find out all possible values which the old '_yoast_wpseo_meta-robots' could contain + * to convert the data correctly. + */ + $query = $wpdb->prepare( + " + SELECT `a`.* + FROM {$wpdb->postmeta} AS a + WHERE `a`.`meta_key` = %s + AND NOT EXISTS ( + SELECT DISTINCT `post_id` , count( `meta_id` ) AS count + FROM {$wpdb->postmeta} AS b + WHERE `a`.`post_id` = `b`.`post_id` + AND ( `meta_key` = %s + OR `meta_key` = %s ) + GROUP BY `post_id` + ) + ;", + self::$meta_prefix . 'meta-robots', + self::$meta_prefix . 'meta-robots-noindex', + self::$meta_prefix . 'meta-robots-nofollow', + ); + $oldies = $wpdb->get_results( $query ); + + if ( is_array( $oldies ) && $oldies !== [] ) { + foreach ( $oldies as $old ) { + $old_values = explode( ',', $old->meta_value ); + foreach ( $old_values as $value ) { + if ( $value === 'noindex' ) { + update_post_meta( $old->post_id, self::$meta_prefix . 'meta-robots-noindex', 1 ); + } + elseif ( $value === 'nofollow' ) { + update_post_meta( $old->post_id, self::$meta_prefix . 'meta-robots-nofollow', 1 ); + } + } + } + } + unset( $query, $oldies, $old, $old_values, $value ); + + // Delete old keys. + delete_post_meta_by_key( self::$meta_prefix . 'meta-robots' ); + + /* + * Remove all default values and (most) invalid option values. + * Invalid option values for the multiselect (meta-robots-adv) field will be dealt with seperately. + * + * {@internal Some of the defaults have changed in v1.5, but as the defaults will + * be removed and new defaults will now automatically be passed when no + * data found, this update is automatic (as long as we remove the old + * values which we do in the below routine).}} + * + * {@internal Unfortunately we can't use the normal delete_meta() with key/value combination + * as '' (empty string) values will be ignored and would result in all metas + * with that key being deleted, not just the empty fields. + * Still, the below implementation is largely based on the delete_meta() function.}} + */ + $query = []; + + foreach ( self::$meta_fields as $subset => $field_group ) { + foreach ( $field_group as $key => $field_def ) { + if ( ! isset( $field_def['default_value'] ) ) { + continue; + } + + if ( isset( $field_def['options'] ) && is_array( $field_def['options'] ) && $field_def['options'] !== [] ) { + $valid = $field_def['options']; + // Remove the default value from the valid options. + unset( $valid[ $field_def['default_value'] ] ); + $valid = array_keys( $valid ); + + $query[] = $wpdb->prepare( + "( meta_key = %s AND meta_value NOT IN ( '" . implode( "','", esc_sql( $valid ) ) . "' ) )", + self::$meta_prefix . $key, + ); + unset( $valid ); + } + elseif ( is_string( $field_def['default_value'] ) && $field_def['default_value'] !== '' ) { + $query[] = $wpdb->prepare( + '( meta_key = %s AND meta_value = %s )', + self::$meta_prefix . $key, + $field_def['default_value'], + ); + } + else { + $query[] = $wpdb->prepare( + "( meta_key = %s AND meta_value = '' )", + self::$meta_prefix . $key, + ); + } + } + } + unset( $subset, $field_group, $key, $field_def ); + + $query = "SELECT meta_id FROM {$wpdb->postmeta} WHERE " . implode( ' OR ', $query ) . ';'; + $meta_ids = $wpdb->get_col( $query ); + + if ( is_array( $meta_ids ) && $meta_ids !== [] ) { + // WP native action. + do_action( 'delete_post_meta', $meta_ids, null, null, null ); + + $query = "DELETE FROM {$wpdb->postmeta} WHERE meta_id IN( " . implode( ',', $meta_ids ) . ' )'; + $count = $wpdb->query( $query ); + + if ( $count ) { + foreach ( $meta_ids as $object_id ) { + wp_cache_delete( $object_id, 'post_meta' ); + } + + // WP native action. + do_action( 'deleted_post_meta', $meta_ids, null, null, null ); + } + } + unset( $query, $meta_ids, $count, $object_id ); + + /* + * Deal with the multiselect (meta-robots-adv) field. + * + * Removes invalid option combinations, such as 'none,noarchive'. + * + * Default values have already been removed, so we should have a small result set and + * (hopefully) even smaller set of invalid results. + */ + $query = $wpdb->prepare( + "SELECT meta_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s", + self::$meta_prefix . 'meta-robots-adv', + ); + $oldies = $wpdb->get_results( $query ); + + if ( is_array( $oldies ) && $oldies !== [] ) { + foreach ( $oldies as $old ) { + $clean = self::validate_meta_robots_adv( $old->meta_value ); + + if ( $clean !== $old->meta_value ) { + if ( $clean !== self::$meta_fields['advanced']['meta-robots-adv']['default_value'] ) { + update_metadata_by_mid( 'post', $old->meta_id, $clean ); + } + else { + delete_metadata_by_mid( 'post', $old->meta_id ); + } + } + } + } + unset( $query, $oldies, $old, $clean ); + + do_action( 'wpseo_meta_clean_up' ); + } + + /** + * Recursively merge a variable number of arrays, using the left array as base, + * giving priority to the right array. + * + * Difference with native array_merge_recursive(): + * array_merge_recursive converts values with duplicate keys to arrays rather than + * overwriting the value in the first array with the duplicate value in the second array. + * + * array_merge_recursive_distinct does not change the data types of the values in the arrays. + * Matching keys' values in the second array overwrite those in the first array, as is the + * case with array_merge. + * + * Freely based on information found on http://www.php.net/manual/en/function.array-merge-recursive.php + * + * {@internal Should be moved to a general utility class.}} + * + * @return array + */ + public static function array_merge_recursive_distinct() { + + $arrays = func_get_args(); + if ( count( $arrays ) < 2 ) { + if ( $arrays === [] ) { + return []; + } + else { + return $arrays[0]; + } + } + + $merged = array_shift( $arrays ); + + foreach ( $arrays as $array ) { + foreach ( $array as $key => $value ) { + if ( is_array( $value ) && ( isset( $merged[ $key ] ) && is_array( $merged[ $key ] ) ) ) { + $merged[ $key ] = self::array_merge_recursive_distinct( $merged[ $key ], $value ); + } + else { + $merged[ $key ] = $value; + } + } + unset( $key, $value ); + } + + return $merged; + } + + /** + * Counts the total of all the keywords being used for posts except the given one. + * + * @param string $keyword The keyword to be counted. + * @param int $post_id The id of the post to which the keyword belongs. + * + * @return array + */ + public static function keyword_usage( $keyword, $post_id ) { + + if ( empty( $keyword ) ) { + return []; + } + + /** + * The indexable repository. + * + * @var Indexable_Repository $repository + */ + $repository = YoastSEO()->classes->get( Indexable_Repository::class ); + + $post_ids = $repository->query() + ->select( 'object_id' ) + ->where( 'primary_focus_keyword', $keyword ) + ->where( 'object_type', 'post' ) + ->where_not_equal( 'object_id', $post_id ) + ->where_not_equal( 'post_status', 'trash' ) + ->limit( 2 ) // Limit to 2 results to save time and resources. + ->find_array(); + + // Get object_id from each subarray in $post_ids. + $post_ids = ( is_array( $post_ids ) ) ? array_column( $post_ids, 'object_id' ) : []; + + /* + * If Premium is installed, get the additional keywords as well. + * We only check for the additional keywords if we've not already found two. + * In that case there's no use for an additional query as we already know + * that the keyword has been used multiple times before. + */ + if ( count( $post_ids ) < 2 ) { + /** + * Allows enhancing the array of posts' that share their focus keywords with the post's focus keywords. + * + * @param array $post_ids The array of posts' ids that share their related keywords with the post. + * @param string $keyword The keyword to search for. + * @param int $post_id The id of the post the keyword is associated to. + */ + $post_ids = apply_filters( 'wpseo_posts_for_focus_keyword', $post_ids, $keyword, $post_id ); + } + + return $post_ids; + } + + /** + * Returns the post types for the given post ids. + * + * @param array $post_ids The post ids to get the post types for. + * + * @return array The post types. + */ + public static function post_types_for_ids( $post_ids ) { + // Check if post ids is not empty. + if ( ! empty( $post_ids ) ) { + /** + * The indexable repository. + * + * @var Indexable_Repository $repository + */ + $repository = YoastSEO()->classes->get( Indexable_Repository::class ); + + // Get the post subtypes for the posts that share the keyword. + $post_types = $repository->query() + ->select( 'object_sub_type' ) + ->where_in( 'object_id', $post_ids ) + ->find_array(); + + // Get object_sub_type from each subarray in $post_ids. + $post_types = array_column( $post_types, 'object_sub_type' ); + } + else { + $post_types = []; + } + + return $post_types; + } + + /** + * Filter the schema article types. + * + * @return void + */ + public static function filter_schema_article_types() { + /** This filter is documented in inc/options/class-wpseo-option-titles.php */ + self::$meta_fields['schema']['schema_article_type']['options'] = apply_filters( 'wpseo_schema_article_types', self::$meta_fields['schema']['schema_article_type']['options'] ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-primary-term.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-primary-term.php new file mode 100644 index 0000000..f5a5ccc --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-primary-term.php @@ -0,0 +1,86 @@ +taxonomy_name = $taxonomy_name; + $this->post_ID = $post_id; + } + + /** + * Returns the primary term ID. + * + * @return int|bool + */ + public function get_primary_term() { + $primary_term = get_post_meta( $this->post_ID, WPSEO_Meta::$meta_prefix . 'primary_' . $this->taxonomy_name, true ); + + if ( ! $primary_term ) { + return false; + } + + $terms = $this->get_terms(); + + if ( ! in_array( (int) $primary_term, wp_list_pluck( $terms, 'term_id' ), true ) ) { + $primary_term = false; + } + + $primary_term = (int) $primary_term; + return ( $primary_term ) ? ( $primary_term ) : false; + } + + /** + * Sets the new primary term ID. + * + * @param int $new_primary_term New primary term ID. + * + * @return void + */ + public function set_primary_term( $new_primary_term ) { + update_post_meta( $this->post_ID, WPSEO_Meta::$meta_prefix . 'primary_' . $this->taxonomy_name, $new_primary_term ); + } + + /** + * Get the terms for the current post ID. + * When $terms is not an array, set $terms to an array. + * + * @return array + */ + protected function get_terms() { + $terms = get_the_terms( $this->post_ID, $this->taxonomy_name ); + + if ( ! is_array( $terms ) ) { + $terms = []; + } + + return $terms; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-rank.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-rank.php new file mode 100644 index 0000000..8f0e514 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-rank.php @@ -0,0 +1,343 @@ + [ + 'start' => 0, + 'end' => 0, + ], + self::BAD => [ + 'start' => 1, + 'end' => 40, + ], + self::OK => [ + 'start' => 41, + 'end' => 70, + ], + self::GOOD => [ + 'start' => 71, + 'end' => 100, + ], + ]; + + /** + * The current rank. + * + * @var int + */ + protected $rank; + + /** + * WPSEO_Rank constructor. + * + * @param int $rank The actual rank. + */ + public function __construct( $rank ) { + if ( ! in_array( $rank, self::$ranks, true ) ) { + $rank = self::BAD; + } + + $this->rank = $rank; + } + + /** + * Returns the saved rank for this rank. + * + * @return string + */ + public function get_rank() { + return $this->rank; + } + + /** + * Returns a CSS class for this rank. + * + * @return string + */ + public function get_css_class() { + $labels = [ + self::NO_FOCUS => 'na', + self::NO_INDEX => 'noindex', + self::BAD => 'bad', + self::OK => 'ok', + self::GOOD => 'good', + ]; + + return $labels[ $this->rank ]; + } + + /** + * Returns a label for this rank. + * + * @return string + */ + public function get_label() { + $labels = [ + self::NO_FOCUS => __( 'Not available', 'wordpress-seo' ), + self::NO_INDEX => __( 'No index', 'wordpress-seo' ), + self::BAD => __( 'Needs improvement', 'wordpress-seo' ), + self::OK => __( 'OK', 'wordpress-seo' ), + self::GOOD => __( 'Good', 'wordpress-seo' ), + ]; + + return $labels[ $this->rank ]; + } + + /** + * Returns an inclusive language label for this rank. + * The only difference with get_label above is that we return "Potentially non-inclusive" for an OK rank. + * + * @return string + */ + public function get_inclusive_language_label() { + if ( $this->rank === self::OK ) { + return __( 'Potentially non-inclusive', 'wordpress-seo' ); + } + return $this->get_label(); + } + + /** + * Returns a label for use in a drop down. + * + * @return mixed + */ + public function get_drop_down_label() { + $labels = [ + self::NO_FOCUS => sprintf( + /* translators: %s expands to the SEO score */ + __( 'SEO: %s', 'wordpress-seo' ), + __( 'No Focus Keyphrase', 'wordpress-seo' ), + ), + self::BAD => sprintf( + /* translators: %s expands to the SEO score */ + __( 'SEO: %s', 'wordpress-seo' ), + __( 'Needs improvement', 'wordpress-seo' ), + ), + self::OK => sprintf( + /* translators: %s expands to the SEO score */ + __( 'SEO: %s', 'wordpress-seo' ), + __( 'OK', 'wordpress-seo' ), + ), + self::GOOD => sprintf( + /* translators: %s expands to the SEO score */ + __( 'SEO: %s', 'wordpress-seo' ), + __( 'Good', 'wordpress-seo' ), + ), + self::NO_INDEX => sprintf( + /* translators: %s expands to the SEO score */ + __( 'SEO: %s', 'wordpress-seo' ), + __( 'Post Noindexed', 'wordpress-seo' ), + ), + ]; + + return $labels[ $this->rank ]; + } + + /** + * Gets the drop down labels for the readability score. + * + * @return string The readability rank label. + */ + public function get_drop_down_readability_labels() { + $labels = [ + self::BAD => sprintf( + /* translators: %s expands to the readability score */ + __( 'Readability: %s', 'wordpress-seo' ), + __( 'Needs improvement', 'wordpress-seo' ), + ), + self::OK => sprintf( + /* translators: %s expands to the readability score */ + __( 'Readability: %s', 'wordpress-seo' ), + __( 'OK', 'wordpress-seo' ), + ), + self::GOOD => sprintf( + /* translators: %s expands to the readability score */ + __( 'Readability: %s', 'wordpress-seo' ), + __( 'Good', 'wordpress-seo' ), + ), + self::NO_FOCUS => sprintf( + /* translators: %s expands to the readability score */ + __( 'Readability: %s', 'wordpress-seo' ), + __( 'Not analyzed', 'wordpress-seo' ), + ), + ]; + + return $labels[ $this->rank ]; + } + + /** + * Gets the drop down labels for the inclusive language score. + * + * @return string The inclusive language rank label. + */ + public function get_drop_down_inclusive_language_labels() { + $labels = [ + self::BAD => sprintf( + /* translators: %s expands to the inclusive language score */ + __( 'Inclusive language: %s', 'wordpress-seo' ), + __( 'Needs improvement', 'wordpress-seo' ), + ), + self::OK => sprintf( + /* translators: %s expands to the inclusive language score */ + __( 'Inclusive language: %s', 'wordpress-seo' ), + __( 'Potentially non-inclusive', 'wordpress-seo' ), + ), + self::GOOD => sprintf( + /* translators: %s expands to the inclusive language score */ + __( 'Inclusive language: %s', 'wordpress-seo' ), + __( 'Good', 'wordpress-seo' ), + ), + ]; + + return $labels[ $this->rank ]; + } + + /** + * Get the starting score for this rank. + * + * @return int The start score. + */ + public function get_starting_score() { + // No index does not have a starting score. + if ( $this->rank === self::NO_INDEX ) { + return -1; + } + + return self::$ranges[ $this->rank ]['start']; + } + + /** + * Get the ending score for this rank. + * + * @return int The end score. + */ + public function get_end_score() { + // No index does not have an end score. + if ( $this->rank === self::NO_INDEX ) { + return -1; + } + + return self::$ranges[ $this->rank ]['end']; + } + + /** + * Returns a rank for a specific numeric score. + * + * @param int $score The score to determine a rank for. + * + * @return self + */ + public static function from_numeric_score( $score ) { + // Set up the default value. + $rank = new self( self::BAD ); + + foreach ( self::$ranges as $rank_index => $range ) { + if ( $range['start'] <= $score && $score <= $range['end'] ) { + $rank = new self( $rank_index ); + break; + } + } + + return $rank; + } + + /** + * Returns a list of all possible SEO Ranks. + * + * @return WPSEO_Rank[] + */ + public static function get_all_ranks() { + return array_map( [ 'WPSEO_Rank', 'create_rank' ], self::$ranks ); + } + + /** + * Returns a list of all possible Readability Ranks. + * + * @return WPSEO_Rank[] + */ + public static function get_all_readability_ranks() { + return array_map( [ 'WPSEO_Rank', 'create_rank' ], [ self::BAD, self::OK, self::GOOD, self::NO_FOCUS ] ); + } + + /** + * Returns a list of all possible Inclusive Language Ranks. + * + * @return WPSEO_Rank[] + */ + public static function get_all_inclusive_language_ranks() { + return array_map( [ 'WPSEO_Rank', 'create_rank' ], [ self::BAD, self::OK, self::GOOD ] ); + } + + /** + * Converts a numeric rank into a WPSEO_Rank object, for use in functional array_* functions. + * + * @param string $rank SEO Rank. + * + * @return WPSEO_Rank + */ + private static function create_rank( $rank ) { + return new self( $rank ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-replace-vars.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-replace-vars.php new file mode 100644 index 0000000..8f0f679 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-replace-vars.php @@ -0,0 +1,1646 @@ + '', + 'name' => '', + 'post_author' => '', + 'post_content' => '', + 'post_date' => '', + 'post_excerpt' => '', + 'post_modified' => '', + 'post_title' => '', + 'taxonomy' => '', + 'term_id' => '', + 'term404' => '', + ]; + + /** + * Current post/page/cpt information. + * + * @var stdClass + */ + protected $args; + + /** + * Help texts for use in WPSEO -> Search appearance tabs. + * + * @var array + */ + protected static $help_texts = []; + + /** + * Register of additional variable replacements registered by other plugins/themes. + * + * @var array + */ + protected static $external_replacements = []; + + /** + * Setup the help texts and external replacements as statics so they will be available to all instances. + * + * @return void + */ + public static function setup_statics_once() { + if ( self::$help_texts === [] ) { + self::set_basic_help_texts(); + self::set_advanced_help_texts(); + } + + if ( self::$external_replacements === [] ) { + /** + * Action: 'wpseo_register_extra_replacements' - Allows for registration of additional + * variables to replace. + */ + do_action( 'wpseo_register_extra_replacements' ); + } + } + + /** + * Register new replacement %%variables%%. + * For use by other plugins/themes to register extra variables. + * + * @see wpseo_register_var_replacement() for a usage example. + * + * @param string $var_to_replace The name of the variable to replace, i.e. '%%var%%'. + * Note: the surrounding %% are optional. + * @param mixed $replace_function Function or method to call to retrieve the replacement value for the variable. + * Uses the same format as add_filter/add_action function parameter and + * should *return* the replacement value. DON'T echo it. + * @param string $type Type of variable: 'basic' or 'advanced', defaults to 'advanced'. + * @param string $help_text Help text to be added to the help tab for this variable. + * + * @return bool Whether the replacement function was succesfully registered. + */ + public static function register_replacement( $var_to_replace, $replace_function, $type = 'advanced', $help_text = '' ) { + $success = false; + + if ( is_string( $var_to_replace ) && $var_to_replace !== '' ) { + $var_to_replace = self::remove_var_delimiter( $var_to_replace ); + + if ( preg_match( '`^[A-Z0-9_-]+$`i', $var_to_replace ) === false ) { + trigger_error( esc_html__( 'A replacement variable can only contain alphanumeric characters, an underscore or a dash. Try renaming your variable.', 'wordpress-seo' ), E_USER_WARNING ); + } + elseif ( strpos( $var_to_replace, 'cf_' ) === 0 || strpos( $var_to_replace, 'ct_' ) === 0 ) { + trigger_error( esc_html__( 'A replacement variable can not start with "%%cf_" or "%%ct_" as these are reserved for the WPSEO standard variable variables for custom fields and custom taxonomies. Try making your variable name unique.', 'wordpress-seo' ), E_USER_WARNING ); + } + elseif ( ! method_exists( self::class, 'retrieve_' . $var_to_replace ) ) { + if ( $var_to_replace !== '' && ! isset( self::$external_replacements[ $var_to_replace ] ) ) { + self::$external_replacements[ $var_to_replace ] = $replace_function; + $replacement_variable = new WPSEO_Replacement_Variable( $var_to_replace, $var_to_replace, $help_text ); + self::register_help_text( $type, $replacement_variable ); + $success = true; + } + else { + trigger_error( esc_html__( 'A replacement variable with the same name has already been registered. Try making your variable name unique.', 'wordpress-seo' ), E_USER_WARNING ); + } + } + else { + trigger_error( esc_html__( 'You cannot overrule a WPSEO standard variable replacement by registering a variable with the same name. Use the "wpseo_replacements" filter instead to adjust the replacement value.', 'wordpress-seo' ), E_USER_WARNING ); + } + } + + return $success; + } + + /** + * Replace `%%variable_placeholders%%` with their real value based on the current requested page/post/cpt/etc. + * + * @param string $text The string to replace the variables in. + * @param array $args The object some of the replacement values might come from, + * could be a post, taxonomy or term. + * @param array $omit Variables that should not be replaced by this function. + * + * @return string + */ + public function replace( $text, $args, $omit = [] ) { + + $text = wp_strip_all_tags( $text ); + + // Let's see if we can bail super early. + if ( strpos( $text, '%%' ) === false ) { + return YoastSEO()->helpers->string->standardize_whitespace( $text ); + } + + $args = (array) $args; + if ( isset( $args['post_content'] ) && ! empty( $args['post_content'] ) ) { + $args['post_content'] = YoastSEO()->helpers->string->strip_shortcode( $args['post_content'] ); + } + if ( isset( $args['post_excerpt'] ) && ! empty( $args['post_excerpt'] ) ) { + $args['post_excerpt'] = YoastSEO()->helpers->string->strip_shortcode( $args['post_excerpt'] ); + } + $this->args = (object) wp_parse_args( $args, $this->defaults ); + + // Clean $omit array. + if ( is_array( $omit ) && $omit !== [] ) { + $omit = array_map( [ self::class, 'remove_var_delimiter' ], $omit ); + } + + $replacements = []; + if ( preg_match_all( '`%%([^%]+(%%single)?)%%?`iu', $text, $matches ) ) { + $replacements = $this->set_up_replacements( $matches, $omit ); + } + + /** + * Filter: 'wpseo_replacements' - Allow customization of the replacements before they are applied. + * + * @param array $replacements The replacements. + * @param array $args The object some of the replacement values might come from, + * could be a post, taxonomy or term. + */ + $replacements = apply_filters( 'wpseo_replacements', $replacements, $this->args ); + + // Do the actual replacements. + if ( is_array( $replacements ) && $replacements !== [] ) { + $text = str_replace( + array_keys( $replacements ), + // Make sure to exclude replacement values that are arrays e.g. coming from a custom field serialized value. + array_filter( array_values( $replacements ), 'is_scalar' ), + $text, + ); + } + + /** + * Filter: 'wpseo_replacements_final' - Allow overruling of whether or not to remove placeholders + * which didn't yield a replacement. + * + * @example add_filter( 'wpseo_replacements_final', '__return_false' ); + * + * @param bool $final + */ + if ( apply_filters( 'wpseo_replacements_final', true ) === true && ( isset( $matches[1] ) && is_array( $matches[1] ) ) ) { + // Remove non-replaced variables. + $remove = array_diff( $matches[1], $omit ); // Make sure the $omit variables do not get removed. + $remove = array_map( [ self::class, 'add_var_delimiter' ], $remove ); + $text = str_replace( $remove, '', $text ); + } + + // Undouble separators which have nothing between them, i.e. where a non-replaced variable was removed. + if ( isset( $replacements['%%sep%%'] ) && ( is_string( $replacements['%%sep%%'] ) && $replacements['%%sep%%'] !== '' ) ) { + $q_sep = preg_quote( $replacements['%%sep%%'], '`' ); + $text = preg_replace( '`' . $q_sep . '(?:\s*' . $q_sep . ')*`u', $replacements['%%sep%%'], $text ); + } + + // Remove superfluous whitespace. + $text = YoastSEO()->helpers->string->standardize_whitespace( $text ); + + return $text; + } + + /** + * Register a new replacement variable if it has not been registered already. + * + * @param string $var_to_replace The name of the variable to replace, i.e. '%%var%%'. + * Note: the surrounding %% are optional. + * @param mixed $replace_function Function or method to call to retrieve the replacement value for the variable. + * Uses the same format as add_filter/add_action function parameter and + * should *return* the replacement value. DON'T echo it. + * @param string $type Type of variable: 'basic' or 'advanced', defaults to 'advanced'. + * @param string $help_text Help text to be added to the help tab for this variable. + * + * @return bool `true` if the replace var has been registered, `false` if not. + */ + public function safe_register_replacement( $var_to_replace, $replace_function, $type = 'advanced', $help_text = '' ) { + if ( ! $this->has_been_registered( $var_to_replace ) ) { + return self::register_replacement( $var_to_replace, $replace_function, $type, $help_text ); + } + return false; + } + + /** + * Checks whether the given replacement variable has already been registered or not. + * + * @param string $replacement_variable The replacement variable to check, including the variable delimiter (e.g. `%%var%%`). + * + * @return bool `true` if the replacement variable has already been registered. + */ + public function has_been_registered( $replacement_variable ) { + $replacement_variable = self::remove_var_delimiter( $replacement_variable ); + + return isset( self::$external_replacements[ $replacement_variable ] ); + } + + /** + * Returns the list of hidden replace vars. + * + * E.g. the replace vars that should work, but are not advertised. + * + * @return string[] The list of hidden replace vars. + */ + public function get_hidden_replace_vars() { + return [ + 'currentdate', + 'currentyear', + 'currentmonth', + 'currentday', + 'post_year', + 'post_month', + 'post_day', + 'author_first_name', + 'author_last_name', + 'permalink', + 'post_content', + 'category_title', + ]; + } + + /** + * Retrieve the replacements for the variables found. + * + * @param array $matches Variables found in the original string - regex result. + * @param array $omit Variables that should not be replaced by this function. + * + * @return array Retrieved replacements - this might be a smaller array as some variables + * may not yield a replacement in certain contexts. + */ + private function set_up_replacements( $matches, $omit ) { + + $replacements = []; + + // @todo Figure out a way to deal with external functions starting with cf_/ct_. + foreach ( $matches[1] as $k => $var ) { + + // Don't set up replacements which should be omitted. + if ( in_array( $var, $omit, true ) ) { + continue; + } + + // Deal with variable variable names first. + if ( strpos( $var, 'cf_' ) === 0 ) { + $replacement = $this->retrieve_cf_custom_field_name( $var ); + } + elseif ( strpos( $var, 'ct_desc_' ) === 0 ) { + $replacement = $this->retrieve_ct_desc_custom_tax_name( $var ); + } + elseif ( strpos( $var, 'ct_' ) === 0 ) { + $single = ( isset( $matches[2][ $k ] ) && $matches[2][ $k ] !== '' ); + $replacement = $this->retrieve_ct_custom_tax_name( $var, $single ); + } + // Deal with non-variable variable names. + elseif ( method_exists( $this, 'retrieve_' . $var ) ) { + $method_name = 'retrieve_' . $var; + $replacement = $this->$method_name(); + } + // Deal with externally defined variable names. + elseif ( isset( self::$external_replacements[ $var ] ) && is_callable( self::$external_replacements[ $var ] ) ) { + $replacement = call_user_func( self::$external_replacements[ $var ], $var, $this->args ); + } + + // Replacement retrievals can return null if no replacement can be determined, root those outs. + if ( isset( $replacement ) ) { + $var = self::add_var_delimiter( $var ); + $replacements[ $var ] = $replacement; + } + unset( $replacement, $single, $method_name ); + } + + return $replacements; + } + + /* *********************** BASIC VARIABLES ************************** */ + + /** + * Retrieve the post/cpt categories (comma separated) for use as replacement string. + * + * @return string|null + */ + private function retrieve_category() { + $replacement = null; + + if ( ! empty( $this->args->ID ) ) { + $cat = $this->get_terms( $this->args->ID, 'category' ); + if ( $cat !== '' ) { + return $cat; + } + } + + if ( isset( $this->args->cat_name ) && ! empty( $this->args->cat_name ) ) { + $replacement = $this->args->cat_name; + } + + return $replacement; + } + + /** + * Retrieve the category description for use as replacement string. + * + * @return string|null + */ + private function retrieve_category_description() { + return $this->retrieve_term_description(); + } + + /** + * Retrieve the date of the post/page/cpt for use as replacement string. + * + * @return string|null + */ + private function retrieve_date() { + $replacement = null; + + if ( $this->args->post_date !== '' ) { + // Returns a string. + $replacement = YoastSEO()->helpers->date->format_translated( $this->args->post_date, get_option( 'date_format' ) ); + } + elseif ( get_query_var( 'day' ) && get_query_var( 'day' ) !== '' ) { + // Returns a string. + $replacement = get_the_date(); + } + elseif ( single_month_title( ' ', false ) ) { + // Returns a string. + $replacement = single_month_title( ' ', false ); + } + elseif ( get_query_var( 'year' ) !== '' ) { + // Returns an integer, let's cast to string. + $replacement = (string) get_query_var( 'year' ); + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt excerpt for use as replacement string. + * The excerpt will be auto-generated if it does not exist. + * + * @return string|null + */ + private function retrieve_excerpt() { + $replacement = null; + $locale = get_locale(); + + // Japanese doesn't have a jp_JP variant in WP. + $limit = ( $locale === 'ja' ) ? 80 : 156; + + // The check `post_password_required` is because excerpt must be hidden for a post with a password. + if ( ! empty( $this->args->ID ) && ! post_password_required( $this->args->ID ) ) { + if ( $this->args->post_excerpt !== '' ) { + $replacement = wp_strip_all_tags( $this->args->post_excerpt ); + } + elseif ( $this->args->post_content !== '' ) { + $content = strip_shortcodes( $this->args->post_content ); + $content = wp_strip_all_tags( $content ); + + if ( mb_strlen( $content ) <= $limit ) { + return $content; + } + + $replacement = wp_html_excerpt( $content, $limit ); + + // Check if the description has space and trim the auto-generated string to a word boundary. + if ( strrpos( $replacement, ' ' ) ) { + $replacement = substr( $replacement, 0, strrpos( $replacement, ' ' ) ); + } + } + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt excerpt for use as replacement string (without auto-generation). + * + * @return string|null + */ + private function retrieve_excerpt_only() { + $replacement = null; + + // The check `post_password_required` is because excerpt must be hidden for a post with a password. + if ( ! empty( $this->args->ID ) && $this->args->post_excerpt !== '' && ! post_password_required( $this->args->ID ) ) { + $replacement = wp_strip_all_tags( $this->args->post_excerpt ); + } + + return $replacement; + } + + /** + * Retrieve the title of the parent page of the current page/cpt for use as replacement string. + * Only applicable for hierarchical post types. + * + * @todo Check: shouldn't this use $this->args as well ? + * + * @return string|null + */ + private function retrieve_parent_title() { + $replacement = null; + + if ( ! empty( $this->args->ID ) ) { + $parent_id = wp_get_post_parent_id( $this->args->ID ); + if ( $parent_id ) { + $replacement = get_the_title( $parent_id ); + } + } + + return $replacement; + } + + /** + * Retrieve the current search phrase for use as replacement string. + * + * @return string|null + */ + private function retrieve_searchphrase() { + $replacement = null; + + $search = get_query_var( 's' ); + if ( $search !== '' ) { + $replacement = esc_html( $search ); + } + + return $replacement; + } + + /** + * Retrieve the separator for use as replacement string. + * + * @return string Retrieves the title separator. + */ + private function retrieve_sep() { + return YoastSEO()->helpers->options->get_title_separator(); + } + + /** + * Retrieve the site's tag line / description for use as replacement string. + * + * The `$replacement` variable is static because it doesn't change depending + * on the context. See https://github.com/Yoast/wordpress-seo/pull/1172#issuecomment-46019482. + * + * @return string|null + */ + private function retrieve_sitedesc() { + static $replacement; + + if ( ! isset( $replacement ) ) { + $description = wp_strip_all_tags( get_bloginfo( 'description' ) ); + if ( $description !== '' ) { + $replacement = $description; + } + } + + return $replacement; + } + + /** + * Retrieve the site's name for use as replacement string. + * + * The `$replacement` variable is static because it doesn't change depending + * on the context. See https://github.com/Yoast/wordpress-seo/pull/1172#issuecomment-46019482. + * + * @return string|null + */ + private function retrieve_sitename() { + static $replacement; + + if ( ! isset( $replacement ) ) { + $sitename = YoastSEO()->helpers->site->get_site_name(); + if ( $sitename !== '' ) { + $replacement = $sitename; + } + } + + return $replacement; + } + + /** + * Retrieve the current tag/tags for use as replacement string. + * + * @return string|null + */ + private function retrieve_tag() { + $replacement = null; + + if ( ! empty( $this->args->ID ) ) { + $tags = $this->get_terms( $this->args->ID, 'post_tag' ); + if ( $tags !== '' ) { + $replacement = $tags; + } + } + + return $replacement; + } + + /** + * Retrieve the tag description for use as replacement string. + * + * @return string|null + */ + private function retrieve_tag_description() { + return $this->retrieve_term_description(); + } + + /** + * Retrieve the term description for use as replacement string. + * + * @return string|null + */ + private function retrieve_term_description() { + $replacement = null; + + if ( ! empty( $this->args->term_id ) && ! empty( $this->args->taxonomy ) ) { + $term_desc = get_term_field( 'description', $this->args->term_id, $this->args->taxonomy ); + if ( $term_desc !== '' ) { + $replacement = wp_strip_all_tags( $term_desc ); + } + } + + return $replacement; + } + + /** + * Retrieve the term name for use as replacement string. + * + * @return string|null + */ + private function retrieve_term_title() { + $replacement = null; + + if ( ! empty( $this->args->taxonomy ) && ! empty( $this->args->name ) ) { + $replacement = $this->args->name; + } + + return $replacement; + } + + /** + * Retrieve the title of the post/page/cpt for use as replacement string. + * + * @return string|null + */ + private function retrieve_title() { + $replacement = null; + + if ( is_string( $this->args->post_title ) && $this->args->post_title !== '' ) { + $replacement = $this->args->post_title; + } + + return $replacement; + } + + /** + * Retrieve primary category for use as replacement string. + * + * @return bool|int|null + */ + private function retrieve_primary_category() { + $primary_category = null; + + if ( ! empty( $this->args->ID ) ) { + $wpseo_primary_category = new WPSEO_Primary_Term( 'category', $this->args->ID ); + + $term_id = $wpseo_primary_category->get_primary_term(); + $term = get_term( $term_id ); + + if ( ! is_wp_error( $term ) && ! empty( $term ) ) { + $primary_category = $term->name; + } + } + + return $primary_category; + } + + /** + * Retrieve the string generated by get_the_archive_title(). + * + * @return string|null + */ + private function retrieve_archive_title() { + return get_the_archive_title(); + } + + /* *********************** ADVANCED VARIABLES ************************** */ + + /** + * Determine the page numbering of the current post/page/cpt. + * + * @param string $request Either 'nr'|'max' - whether to return the page number or the max number of pages. + * + * @return int|null + */ + private function determine_pagenumbering( $request = 'nr' ) { + global $wp_query, $post; + $max_num_pages = null; + $page_number = null; + + $max_num_pages = 1; + + if ( ! is_singular() ) { + $page_number = get_query_var( 'paged' ); + if ( $page_number === 0 || $page_number === '' ) { + $page_number = 1; + } + + if ( ! empty( $wp_query->max_num_pages ) ) { + $max_num_pages = $wp_query->max_num_pages; + } + } + else { + $page_number = get_query_var( 'page' ); + if ( $page_number === 0 || $page_number === '' ) { + $page_number = 1; + } + + if ( isset( $post->post_content ) ) { + $max_num_pages = ( substr_count( $post->post_content, '' ) + 1 ); + } + } + + $return = null; + + switch ( $request ) { + case 'nr': + $return = $page_number; + break; + case 'max': + $return = $max_num_pages; + break; + } + + return $return; + } + + /** + * Determine the post type names for the current post/page/cpt. + * + * @param string $request Either 'single'|'plural' - whether to return the single or plural form. + * + * @return string|null + */ + private function determine_pt_names( $request = 'single' ) { + global $wp_query; + $pt_single = null; + $pt_plural = null; + $post_type = ''; + + if ( isset( $wp_query->query_vars['post_type'] ) && ( ( is_string( $wp_query->query_vars['post_type'] ) && $wp_query->query_vars['post_type'] !== '' ) || ( is_array( $wp_query->query_vars['post_type'] ) && $wp_query->query_vars['post_type'] !== [] ) ) ) { + $post_type = $wp_query->query_vars['post_type']; + } + elseif ( isset( $this->args->post_type ) && ( is_string( $this->args->post_type ) && $this->args->post_type !== '' ) ) { + $post_type = $this->args->post_type; + } + else { + // Make it work in preview mode. + $post = $wp_query->get_queried_object(); + if ( $post instanceof WP_Post ) { + $post_type = $post->post_type; + } + } + + if ( is_array( $post_type ) ) { + $post_type = reset( $post_type ); + } + + if ( $post_type !== '' ) { + $pt = get_post_type_object( $post_type ); + $pt_single = $pt->name; + $pt_plural = $pt->name; + if ( isset( $pt->labels->singular_name ) ) { + $pt_single = $pt->labels->singular_name; + } + if ( isset( $pt->labels->name ) ) { + $pt_plural = $pt->labels->name; + } + } + + $return = null; + + switch ( $request ) { + case 'single': + $return = $pt_single; + break; + case 'plural': + $return = $pt_plural; + break; + } + + return $return; + } + + /** + * Retrieve the attachment caption for use as replacement string. + * + * @return string|null + */ + private function retrieve_caption() { + return $this->retrieve_excerpt_only(); + } + + /** + * Retrieve a post/page/cpt's custom field value for use as replacement string. + * + * @param string $var_to_replace The complete variable to replace which includes the name of + * the custom field which value is to be retrieved. + * + * @return string|null + */ + private function retrieve_cf_custom_field_name( $var_to_replace ) { + $replacement = null; + + if ( is_string( $var_to_replace ) && $var_to_replace !== '' ) { + $field = substr( $var_to_replace, 3 ); + if ( ! empty( $this->args->ID ) ) { + // Post meta can be arrays and in this case we need to exclude them. + $name = get_post_meta( $this->args->ID, $field, true ); + if ( $name !== '' && ! is_array( $name ) ) { + $replacement = sanitize_text_field( $name ); + } + } + elseif ( ! empty( $this->args->term_id ) ) { + $name = get_term_meta( $this->args->term_id, $field, true ); + if ( $name !== '' ) { + $replacement = sanitize_text_field( $name ); + } + } + } + + return $replacement; + } + + /** + * Retrieve a post/page/cpt's custom taxonomies for use as replacement string. + * + * @param string $var_to_replace The complete variable to replace which includes the name of + * the custom taxonomy which value(s) is to be retrieved. + * @param bool $single Whether to retrieve only the first or all values for the taxonomy. + * + * @return string|null + */ + private function retrieve_ct_custom_tax_name( $var_to_replace, $single = false ) { + $replacement = null; + + if ( ( is_string( $var_to_replace ) && $var_to_replace !== '' ) && ! empty( $this->args->ID ) ) { + $tax = substr( $var_to_replace, 3 ); + $name = $this->get_terms( $this->args->ID, $tax, $single ); + if ( $name !== '' ) { + $replacement = $name; + } + } + + return $replacement; + } + + /** + * Retrieve a post/page/cpt's custom taxonomies description for use as replacement string. + * + * @param string $var_to_replace The complete variable to replace which includes the name of + * the custom taxonomy which description is to be retrieved. + * + * @return string|null + */ + private function retrieve_ct_desc_custom_tax_name( $var_to_replace ) { + $replacement = null; + + if ( is_string( $var_to_replace ) && $var_to_replace !== '' ) { + $tax = substr( $var_to_replace, 8 ); + if ( ! empty( $this->args->ID ) ) { + $terms = get_the_terms( $this->args->ID, $tax ); + if ( is_array( $terms ) && $terms !== [] ) { + $term = current( $terms ); + $term_desc = get_term_field( 'description', $term->term_id, $tax ); + if ( $term_desc !== '' ) { + $replacement = wp_strip_all_tags( $term_desc ); + } + } + } + } + + return $replacement; + } + + /** + * Retrieve the current date for use as replacement string. + * + * The `$replacement` variable is static because it doesn't change depending + * on the context. See https://github.com/Yoast/wordpress-seo/pull/1172#issuecomment-46019482. + * + * @return string The formatted current date. + */ + private function retrieve_currentdate() { + static $replacement; + + if ( ! isset( $replacement ) ) { + $replacement = date_i18n( get_option( 'date_format' ) ); + } + + return $replacement; + } + + /** + * Retrieve the current day for use as replacement string. + * + * The `$replacement` variable is static because it doesn't change depending + * on the context. See https://github.com/Yoast/wordpress-seo/pull/1172#issuecomment-46019482. + * + * @return string The current day. + */ + private function retrieve_currentday() { + static $replacement; + + if ( ! isset( $replacement ) ) { + $replacement = date_i18n( 'j' ); + } + + return $replacement; + } + + /** + * Retrieve the current month for use as replacement string. + * + * The `$replacement` variable is static because it doesn't change depending + * on the context. See https://github.com/Yoast/wordpress-seo/pull/1172#issuecomment-46019482. + * + * @return string The current month. + */ + private function retrieve_currentmonth() { + static $replacement; + + if ( ! isset( $replacement ) ) { + $replacement = date_i18n( 'F' ); + } + + return $replacement; + } + + /** + * Retrieve the current time for use as replacement string. + * + * The `$replacement` variable is static because it doesn't change depending + * on the context. See https://github.com/Yoast/wordpress-seo/pull/1172#issuecomment-46019482. + * + * @return string The formatted current time. + */ + private function retrieve_currenttime() { + static $replacement; + + if ( ! isset( $replacement ) ) { + $replacement = date_i18n( get_option( 'time_format' ) ); + } + + return $replacement; + } + + /** + * Retrieve the current year for use as replacement string. + * + * The `$replacement` variable is static because it doesn't change depending + * on the context. See https://github.com/Yoast/wordpress-seo/pull/1172#issuecomment-46019482. + * + * @return string The current year. + */ + private function retrieve_currentyear() { + static $replacement; + + if ( ! isset( $replacement ) ) { + $replacement = date_i18n( 'Y' ); + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt's focus keyword for use as replacement string. + * + * @return string|null + */ + private function retrieve_focuskw() { + // Retrieve focuskw from a Post. + if ( ! empty( $this->args->ID ) ) { + $focus_kw = WPSEO_Meta::get_value( 'focuskw', $this->args->ID ); + if ( $focus_kw !== '' ) { + return $focus_kw; + } + + return null; + } + + // Retrieve focuskw from a Term. + if ( ! empty( $this->args->term_id ) ) { + $focus_kw = WPSEO_Taxonomy_Meta::get_term_meta( $this->args->term_id, $this->args->taxonomy, 'focuskw' ); + if ( $focus_kw !== '' ) { + return $focus_kw; + } + } + + return null; + } + + /** + * Retrieve the post/page/cpt ID for use as replacement string. + * + * @return string|null + */ + private function retrieve_id() { + $replacement = null; + + if ( ! empty( $this->args->ID ) ) { + // The post/page/cpt ID is an integer, let's cast to string. + $replacement = (string) $this->args->ID; + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt modified time for use as replacement string. + * + * @return string|null + */ + private function retrieve_modified() { + $replacement = null; + + if ( ! empty( $this->args->post_modified ) ) { + $replacement = YoastSEO()->helpers->date->format_translated( $this->args->post_modified, get_option( 'date_format' ) ); + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt author's "nice name" for use as replacement string. + * + * @return string|null + */ + private function retrieve_name() { + $replacement = null; + + $user_id = (int) $this->retrieve_userid(); + $name = get_the_author_meta( 'display_name', $user_id ); + if ( $name !== '' ) { + $replacement = $name; + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt author's users description for use as a replacement string. + * + * @return string|null + */ + private function retrieve_user_description() { + $replacement = null; + + $user_id = (int) $this->retrieve_userid(); + $description = get_the_author_meta( 'description', $user_id ); + if ( $description !== '' ) { + $replacement = $description; + } + + return $replacement; + } + + /** + * Retrieve the current page number with context (i.e. 'page 2 of 4') for use as replacement string. + * + * @return string + */ + private function retrieve_page() { + $replacement = null; + + $max = $this->determine_pagenumbering( 'max' ); + $nr = $this->determine_pagenumbering( 'nr' ); + $sep = $this->retrieve_sep(); + + if ( $max > 1 && $nr > 1 ) { + /* translators: 1: current page number, 2: total number of pages. */ + $replacement = sprintf( $sep . ' ' . __( 'Page %1$d of %2$d', 'wordpress-seo' ), $nr, $max ); + } + + return $replacement; + } + + /** + * Retrieve the current page number for use as replacement string. + * + * @return string|null + */ + private function retrieve_pagenumber() { + $replacement = null; + + $nr = $this->determine_pagenumbering( 'nr' ); + if ( isset( $nr ) && $nr > 0 ) { + $replacement = (string) $nr; + } + + return $replacement; + } + + /** + * Retrieve the current page total for use as replacement string. + * + * @return string|null + */ + private function retrieve_pagetotal() { + $replacement = null; + + $max = $this->determine_pagenumbering( 'max' ); + if ( isset( $max ) && $max > 0 ) { + $replacement = (string) $max; + } + + return $replacement; + } + + /** + * Retrieve the post type plural label for use as replacement string. + * + * @return string|null + */ + private function retrieve_pt_plural() { + $replacement = null; + + $name = $this->determine_pt_names( 'plural' ); + if ( isset( $name ) && $name !== '' ) { + $replacement = $name; + } + + return $replacement; + } + + /** + * Retrieve the post type single label for use as replacement string. + * + * @return string|null + */ + private function retrieve_pt_single() { + $replacement = null; + + $name = $this->determine_pt_names( 'single' ); + if ( isset( $name ) && $name !== '' ) { + $replacement = $name; + } + + return $replacement; + } + + /** + * Retrieve the slug which caused the 404 for use as replacement string. + * + * @return string|null + */ + private function retrieve_term404() { + $replacement = null; + + if ( $this->args->term404 !== '' ) { + $replacement = sanitize_text_field( str_replace( '-', ' ', $this->args->term404 ) ); + } + else { + $error_request = get_query_var( 'pagename' ); + if ( $error_request !== '' ) { + $replacement = sanitize_text_field( str_replace( '-', ' ', $error_request ) ); + } + else { + $error_request = get_query_var( 'name' ); + if ( $error_request !== '' ) { + $replacement = sanitize_text_field( str_replace( '-', ' ', $error_request ) ); + } + } + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt author's user id for use as replacement string. + * + * @return string + */ + private function retrieve_userid() { + // The user ID is an integer, let's cast to string. + $replacement = ! empty( $this->args->post_author ) ? (string) $this->args->post_author : (string) get_query_var( 'author' ); + + return $replacement; + } + + /** + * Retrieve the post/page/cpt's published year for use as replacement string. + * + * @return string|null + */ + private function retrieve_post_year() { + if ( empty( $this->args->ID ) ) { + return null; + } + + return get_the_date( 'Y', $this->args->ID ); + } + + /** + * Retrieve the post/page/cpt's published month for use as replacement string. + * + * @return string|null + */ + private function retrieve_post_month() { + if ( empty( $this->args->ID ) ) { + return null; + } + + return get_the_date( 'F', $this->args->ID ); + } + + /** + * Retrieve the post/page/cpt's published day for use as replacement string. + * + * @return string|null + */ + private function retrieve_post_day() { + if ( empty( $this->args->ID ) ) { + return null; + } + + return get_the_date( 'd', $this->args->ID ); + } + + /** + * Retrieve the post/page/cpt author's first name for use as replacement string. + * + * @return string|null + */ + private function retrieve_author_first_name() { + $replacement = null; + + $user_id = (int) $this->retrieve_userid(); + $name = get_the_author_meta( 'first_name', $user_id ); + if ( $name !== '' ) { + $replacement = $name; + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt author's last name for use as replacement string. + * + * @return string|null + */ + private function retrieve_author_last_name() { + $replacement = null; + + $user_id = (int) $this->retrieve_userid(); + $name = get_the_author_meta( 'last_name', $user_id ); + if ( $name !== '' ) { + $replacement = $name; + } + + return $replacement; + } + + /** + * Retrieve the post/page/cpt permalink for use as replacement string. + * + * @return string|null + */ + private function retrieve_permalink() { + if ( empty( $this->args->ID ) ) { + return null; + } + + return get_permalink( $this->args->ID ); + } + + /** + * Retrieve the post/page/cpt content for use as replacement string. + * + * @return string|null + */ + private function retrieve_post_content() { + $replacement = null; + + // The check `post_password_required` is because content must be hidden for a post with a password. + if ( ! empty( $this->args->ID ) && $this->args->post_content !== '' && ! post_password_required( $this->args->ID ) ) { + $content = strip_shortcodes( $this->args->post_content ); + $replacement = wp_strip_all_tags( $content ); + } + + return $replacement; + } + + /** + * Retrieve the current or first category title. To be used for import data from AIOSEO. + * The code derives from AIOSEO's way of dealing with that var, so we can ensure 100% seamless transition. + * + * @return string|null + */ + private function retrieve_category_title() { + if ( empty( $this->args ) || empty( $this->args->ID ) ) { + return null; + } + $post_id = $this->args->ID; + + $post = get_post( $post_id ); + $taxonomies = get_object_taxonomies( $post, 'objects' ); + + foreach ( $taxonomies as $taxonomy_slug => $taxonomy ) { + if ( ! $taxonomy->hierarchical ) { + continue; + } + $post_terms = get_the_terms( $post_id, $taxonomy_slug ); + if ( is_array( $post_terms ) && count( $post_terms ) > 0 ) { + // AiOSEO takes the name of whatever the first hierarchical taxonomy is. + $term = reset( $post_terms ); + if ( $term ) { + return $term->name; + } + } + } + + return null; + } + + /* *********************** HELP TEXT RELATED ************************** */ + + /** + * Set the help text for a user/plugin/theme defined extra variable. + * + * @param string $type Type of variable: 'basic' or 'advanced'. + * @param WPSEO_Replacement_Variable $replacement_variable The replacement variable to register. + * + * @return void + */ + private static function register_help_text( $type, WPSEO_Replacement_Variable $replacement_variable ) { + $identifier = $replacement_variable->get_variable(); + + if ( ( is_string( $type ) && in_array( $type, [ 'basic', 'advanced' ], true ) ) + && ( $identifier !== '' && ! isset( self::$help_texts[ $type ][ $identifier ] ) ) + ) { + self::$help_texts[ $type ][ $identifier ] = $replacement_variable; + } + } + + /** + * Generates a list of replacement variables based on the help texts. + * + * @return array List of replace vars. + */ + public function get_replacement_variables_with_labels() { + self::setup_statics_once(); + + $custom_variables = []; + foreach ( array_merge( WPSEO_Custom_Fields::get_custom_fields(), WPSEO_Custom_Taxonomies::get_custom_taxonomies() ) as $custom_variable ) { + $custom_variables[ $custom_variable ] = new WPSEO_Replacement_Variable( $custom_variable, $this->get_label( $custom_variable ), '' ); + } + + $replacement_variables = array_filter( + array_merge( self::$help_texts['basic'], self::$help_texts['advanced'] ), + [ $this, 'is_not_prefixed' ], + ARRAY_FILTER_USE_KEY, + ); + + $hidden = $this->get_hidden_replace_vars(); + + return array_values( + array_map( + static function ( WPSEO_Replacement_Variable $replacement_variable ) use ( $hidden ) { + $name = $replacement_variable->get_variable(); + + return [ + 'name' => $name, + 'value' => '', + 'label' => $replacement_variable->get_label(), + 'hidden' => in_array( $name, $hidden, true ), + ]; + }, + array_merge( $replacement_variables, $custom_variables ), + ), + ); + } + + /** + * Generates a list of replacement variables based on the help texts. + * + * @return array List of replace vars. + */ + public function get_replacement_variables_list() { + self::setup_statics_once(); + + $replacement_variables = array_merge( + $this->get_replacement_variables(), + WPSEO_Custom_Fields::get_custom_fields(), + WPSEO_Custom_Taxonomies::get_custom_taxonomies(), + ); + + return array_map( [ $this, 'format_replacement_variable' ], $replacement_variables ); + } + + /** + * Creates a merged associative array of both the basic and advanced help texts. + * + * @return array Array with the replacement variables. + */ + private function get_replacement_variables() { + $help_texts = array_merge( self::$help_texts['basic'], self::$help_texts['advanced'] ); + + return array_filter( array_keys( $help_texts ), [ $this, 'is_not_prefixed' ] ); + } + + /** + * Checks whether the replacement variable contains a `ct_` or `cf_` prefix, because they follow different logic. + * + * @param string $replacement_variable The replacement variable. + * + * @return bool True when the replacement variable is not prefixed. + */ + private function is_not_prefixed( $replacement_variable ) { + $prefixes = [ 'cf_', 'ct_' ]; + $prefix = $this->get_prefix( $replacement_variable ); + + return ! in_array( $prefix, $prefixes, true ); + } + + /** + * Strip the prefix from a replacement variable name. + * + * @param string $replacement_variable The replacement variable. + * + * @return string The replacement variable name without the prefix. + */ + private function strip_prefix( $replacement_variable ) { + return substr( $replacement_variable, 3 ); + } + + /** + * Gets the prefix from a replacement variable name. + * + * @param string $replacement_variable The replacement variable. + * + * @return string The prefix of the replacement variable. + */ + private function get_prefix( $replacement_variable ) { + return substr( $replacement_variable, 0, 3 ); + } + + /** + * Strips 'desc_' if present, and appends ' description' at the end. + * + * @param string $label The replacement variable. + * + * @return string The altered replacement variable name. + */ + private function handle_description( $label ) { + if ( strpos( $label, 'desc_' ) === 0 ) { + return substr( $label, 5 ) . ' description'; + } + + return $label; + } + + /** + * Creates a label for prefixed replacement variables that matches the format in the editors. + * + * @param string $replacement_variable The replacement variable. + * + * @return string The replacement variable label. + */ + private function get_label( $replacement_variable ) { + $prefix = $this->get_prefix( $replacement_variable ); + if ( $prefix === 'cf_' ) { + return $this->strip_prefix( $replacement_variable ) . ' (custom field)'; + } + + if ( $prefix === 'ct_' ) { + $label = $this->strip_prefix( $replacement_variable ); + $label = $this->handle_description( $label ); + return ucfirst( $label . ' (custom taxonomy)' ); + } + + if ( $prefix === 'pt_' ) { + if ( $replacement_variable === 'pt_single' ) { + return 'Post type (singular)'; + } + + return 'Post type (plural)'; + } + + return ''; + } + + /** + * Formats the replacement variables. + * + * @param string $replacement_variable The replacement variable to format. + * + * @return array The formatted replacement variable. + */ + private function format_replacement_variable( $replacement_variable ) { + return [ + 'name' => $replacement_variable, + 'value' => '', + 'label' => $this->get_label( $replacement_variable ), + ]; + } + + /** + * Set/translate the help texts for the WPSEO standard basic variables. + * + * @return void + */ + private static function set_basic_help_texts() { + /* translators: %s: wp_title() function. */ + $separator_description = __( 'The separator defined in your theme\'s %s tag.', 'wordpress-seo' ); + $separator_description = sprintf( + $separator_description, + // 'wp_title()' + 'wp_title()', + ); + + $replacement_variables = [ + new WPSEO_Replacement_Variable( 'date', __( 'Date', 'wordpress-seo' ), __( 'Replaced with the date of the post/page', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'title', __( 'Title', 'wordpress-seo' ), __( 'Replaced with the title of the post/page', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'parent_title', __( 'Parent title', 'wordpress-seo' ), __( 'Replaced with the title of the parent page of the current page', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'archive_title', __( 'Archive title', 'wordpress-seo' ), __( 'Replaced with the normal title for an archive generated by WordPress', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'sitename', __( 'Site title', 'wordpress-seo' ), __( 'The site\'s name', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'sitedesc', __( 'Tagline', 'wordpress-seo' ), __( 'The site\'s tagline', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'excerpt', __( 'Excerpt', 'wordpress-seo' ), __( 'Replaced with the post/page excerpt (or auto-generated if it does not exist)', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'excerpt_only', __( 'Excerpt only', 'wordpress-seo' ), __( 'Replaced with the post/page excerpt (without auto-generation)', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'tag', __( 'Tag', 'wordpress-seo' ), __( 'Replaced with the current tag/tags', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'category', __( 'Category', 'wordpress-seo' ), __( 'Replaced with the post categories (comma separated)', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'primary_category', __( 'Primary category', 'wordpress-seo' ), __( 'Replaced with the primary category of the post/page', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'category_description', __( 'Category description', 'wordpress-seo' ), __( 'Replaced with the category description', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'tag_description', __( 'Tag description', 'wordpress-seo' ), __( 'Replaced with the tag description', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'term_description', __( 'Term description', 'wordpress-seo' ), __( 'Replaced with the term description', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'term_title', __( 'Term title', 'wordpress-seo' ), __( 'Replaced with the term name', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'searchphrase', __( 'Search phrase', 'wordpress-seo' ), __( 'Replaced with the current search phrase', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'term_hierarchy', __( 'Term hierarchy', 'wordpress-seo' ), __( 'Replaced with the term ancestors hierarchy', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'sep', __( 'Separator', 'wordpress-seo' ), $separator_description ), + new WPSEO_Replacement_Variable( 'currentdate', __( 'Current date', 'wordpress-seo' ), __( 'Replaced with the current date', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'currentyear', __( 'Current year', 'wordpress-seo' ), __( 'Replaced with the current year', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'currentmonth', __( 'Current month', 'wordpress-seo' ), __( 'Replaced with the current month', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'currentday', __( 'Current day', 'wordpress-seo' ), __( 'Replaced with the current day', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'post_year', __( 'Post year', 'wordpress-seo' ), __( 'Replaced with the year the post was published', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'post_month', __( 'Post month', 'wordpress-seo' ), __( 'Replaced with the month the post was published', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'post_day', __( 'Post day', 'wordpress-seo' ), __( 'Replaced with the day the post was published', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'author_first_name', __( 'Author first name', 'wordpress-seo' ), __( 'Replaced with the first name of the author', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'author_last_name', __( 'Author last name', 'wordpress-seo' ), __( 'Replaced with the last name of the author', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'permalink', __( 'Permalink', 'wordpress-seo' ), __( 'Replaced with the permalink', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'post_content', __( 'Post Content', 'wordpress-seo' ), __( 'Replaced with the post content', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'category_title', __( 'Category Title', 'wordpress-seo' ), __( 'Current or first category title', 'wordpress-seo' ) ), + ]; + + foreach ( $replacement_variables as $replacement_variable ) { + self::register_help_text( 'basic', $replacement_variable ); + } + } + + /** + * Set/translate the help texts for the WPSEO standard advanced variables. + * + * @return void + */ + private static function set_advanced_help_texts() { + $replacement_variables = [ + new WPSEO_Replacement_Variable( 'pt_single', __( 'Post type (singular)', 'wordpress-seo' ), __( 'Replaced with the content type single label', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'pt_plural', __( 'Post type (plural)', 'wordpress-seo' ), __( 'Replaced with the content type plural label', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'modified', __( 'Modified', 'wordpress-seo' ), __( 'Replaced with the post/page modified time', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'id', __( 'ID', 'wordpress-seo' ), __( 'Replaced with the post/page ID', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'name', __( 'Name', 'wordpress-seo' ), __( 'Replaced with the post/page author\'s \'nicename\'', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'user_description', __( 'User description', 'wordpress-seo' ), __( 'Replaced with the post/page author\'s \'Biographical Info\'', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'page', __( 'Page', 'wordpress-seo' ), __( 'Replaced with the current page number with context (i.e. page 2 of 4)', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'pagetotal', __( 'Pagetotal', 'wordpress-seo' ), __( 'Replaced with the current page total', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'pagenumber', __( 'Pagenumber', 'wordpress-seo' ), __( 'Replaced with the current page number', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'caption', __( 'Caption', 'wordpress-seo' ), __( 'Attachment caption', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'focuskw', __( 'Focus keyword', 'wordpress-seo' ), __( 'Replaced with the posts focus keyphrase', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'term404', __( 'Term404', 'wordpress-seo' ), __( 'Replaced with the slug which caused the 404', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'cf_', ' ' . __( '(custom field)', 'wordpress-seo' ), __( 'Replaced with a posts custom field value', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'ct_', ' ' . __( '(custom taxonomy)', 'wordpress-seo' ), __( 'Replaced with a posts custom taxonomies, comma separated.', 'wordpress-seo' ) ), + new WPSEO_Replacement_Variable( 'ct_desc_', ' ' . __( 'description (custom taxonomy)', 'wordpress-seo' ), __( 'Replaced with a custom taxonomies description', 'wordpress-seo' ) ), + ]; + + foreach ( $replacement_variables as $replacement_variable ) { + self::register_help_text( 'advanced', $replacement_variable ); + } + } + + /* *********************** GENERAL HELPER METHODS ************************** */ + + /** + * Remove the '%%' delimiters from a variable string. + * + * @param string $text Variable string to be cleaned. + * + * @return string + */ + private static function remove_var_delimiter( $text ) { + return trim( $text, '%' ); + } + + /** + * Add the '%%' delimiters to a variable string. + * + * @param string $text Variable string to be delimited. + * + * @return string + */ + private static function add_var_delimiter( $text ) { + return '%%' . $text . '%%'; + } + + /** + * Retrieve a post's terms, comma delimited. + * + * @param int $id ID of the post to get the terms for. + * @param string $taxonomy The taxonomy to get the terms for this post from. + * @param bool $return_single If true, return the first term. + * + * @return string Either a single term or a comma delimited string of terms. + */ + public function get_terms( $id, $taxonomy, $return_single = false ) { + $output = ''; + + // If we're on a specific tag, category or taxonomy page, use that. + if ( ! empty( $this->args->term_id ) ) { + $output = $this->args->name; + } + elseif ( ! empty( $id ) && ! empty( $taxonomy ) ) { + $terms = get_the_terms( $id, $taxonomy ); + if ( is_array( $terms ) && $terms !== [] ) { + foreach ( $terms as $term ) { + if ( $return_single ) { + $output = $term->name; + break; + } + else { + $output .= $term->name . ', '; + } + } + $output = rtrim( trim( $output ), ',' ); + } + } + unset( $terms, $term ); + + /** + * Allows filtering of the terms list used to replace %%category%%, %%tag%% + * and %%ct_%% variables. + * + * @param string $output Comma-delimited string containing the terms. + * @param string $taxonomy The taxonomy of the terms. + */ + return apply_filters( 'wpseo_terms', $output, $taxonomy ); + } + + /** + * Gets a taxonomy term hierarchy including the term to get the parents for. + * + * @return string + */ + private function get_term_hierarchy() { + if ( ! is_taxonomy_hierarchical( $this->args->taxonomy ) ) { + return ''; + } + + $separator = ' ' . $this->retrieve_sep() . ' '; + + $args = [ + 'format' => 'name', + 'separator' => $separator, + 'link' => false, + 'inclusive' => true, + ]; + + return rtrim( + get_term_parents_list( $this->args->term_id, $this->args->taxonomy, $args ), + $separator, + ); + } + + /** + * Retrieves the term ancestors hierarchy. + * + * @return string|null The term ancestors hierarchy. + */ + private function retrieve_term_hierarchy() { + $replacement = null; + + if ( ! empty( $this->args->term_id ) && ! empty( $this->args->taxonomy ) ) { + $hierarchy = $this->get_term_hierarchy(); + + if ( $hierarchy !== '' ) { + $replacement = esc_html( $hierarchy ); + } + } + + return $replacement; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-replacement-variable.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-replacement-variable.php new file mode 100644 index 0000000..83dfc8c --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-replacement-variable.php @@ -0,0 +1,76 @@ +variable = $variable; + $this->label = $label; + $this->description = $description; + } + + /** + * Returns the variable to use. + * + * @return string + */ + public function get_variable() { + return $this->variable; + } + + /** + * Returns the label of the replacement variable. + * + * @return string + */ + public function get_label() { + return $this->label; + } + + /** + * Returns the description of the replacement variable. + * + * @return string + */ + public function get_description() { + return $this->description; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-shortlinker.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-shortlinker.php new file mode 100644 index 0000000..8c2fd0d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-shortlinker.php @@ -0,0 +1,54 @@ +helpers->short_link->build( $url ); + } + + /** + * Returns a version of the URL with a utm_content with the current version. + * + * @param string $url The URL to build upon. + * + * @return string The final URL. + */ + public static function get( $url ) { + return YoastSEO()->helpers->short_link->get( $url ); + } + + /** + * Echoes a version of the URL with a utm_content with the current version. + * + * @param string $url The URL to build upon. + * + * @return void + */ + public static function show( $url ) { + YoastSEO()->helpers->short_link->show( $url ); + } + + /** + * Gets the shortlink's query params. + * + * @return array The shortlink's query params. + */ + public static function get_query_params() { + return YoastSEO()->helpers->short_link->get_query_params(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-statistics.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-statistics.php new file mode 100644 index 0000000..687b8fa --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-statistics.php @@ -0,0 +1,62 @@ +get_rank() === WPSEO_Rank::NO_FOCUS ) { + $posts = [ + 'meta_query' => [ + 'relation' => 'OR', + [ + 'key' => WPSEO_Meta::$meta_prefix . 'focuskw', + 'value' => 'needs-a-value-anyway', + 'compare' => 'NOT EXISTS', + ], + ], + ]; + } + elseif ( $rank->get_rank() === WPSEO_Rank::NO_INDEX ) { + $posts = [ + 'meta_key' => WPSEO_Meta::$meta_prefix . 'meta-robots-noindex', + 'meta_value' => '1', + 'compare' => '=', + ]; + } + else { + $posts = [ + 'meta_key' => WPSEO_Meta::$meta_prefix . 'linkdex', + 'meta_value' => [ $rank->get_starting_score(), $rank->get_end_score() ], + 'meta_compare' => 'BETWEEN', + 'meta_type' => 'NUMERIC', + ]; + } + + $posts['fields'] = 'ids'; + $posts['post_status'] = 'publish'; + + if ( current_user_can( 'edit_others_posts' ) === false ) { + $posts['author'] = get_current_user_id(); + } + + $posts = new WP_Query( $posts ); + + return (int) $posts->found_posts; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-utils.php b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-utils.php new file mode 100644 index 0000000..914320d --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-wpseo-utils.php @@ -0,0 +1,1098 @@ +helpers->url->is_relative( $url ); + } + + /** + * Recursively trim whitespace round a string value or of string values within an array. + * Only trims strings to avoid typecasting a variable (to string). + * + * @since 1.8.0 + * + * @param mixed $value Value to trim or array of values to trim. + * + * @return mixed Trimmed value or array of trimmed values. + */ + public static function trim_recursive( $value ) { + if ( is_string( $value ) ) { + $value = trim( $value ); + } + elseif ( is_array( $value ) ) { + $value = array_map( [ self::class, 'trim_recursive' ], $value ); + } + + return $value; + } + + /** + * Emulate the WP native sanitize_text_field function in a %%variable%% safe way. + * + * Sanitize a string from user input or from the db. + * + * - Check for invalid UTF-8; + * - Convert single < characters to entity; + * - Strip all tags; + * - Remove line breaks, tabs and extra white space; + * - Strip octets - BUT DO NOT REMOVE (part of) VARIABLES WHICH WILL BE REPLACED. + * + * @link https://core.trac.wordpress.org/browser/trunk/src/wp-includes/formatting.php for the original. + * + * @since 1.8.0 + * + * @param string $value String value to sanitize. + * + * @return string + */ + public static function sanitize_text_field( $value ) { + $filtered = wp_check_invalid_utf8( $value ); + + if ( strpos( $filtered, '<' ) !== false ) { + $filtered = wp_pre_kses_less_than( $filtered ); + // This will strip extra whitespace for us. + $filtered = wp_strip_all_tags( $filtered, true ); + } + else { + $filtered = trim( preg_replace( '`[\r\n\t ]+`', ' ', $filtered ) ); + } + + $found = false; + while ( preg_match( '`[^%](%[a-f0-9]{2})`i', $filtered, $match ) ) { + $filtered = str_replace( $match[1], '', $filtered ); + $found = true; + } + unset( $match ); + + if ( $found ) { + // Strip out the whitespace that may now exist after removing the octets. + $filtered = trim( preg_replace( '` +`', ' ', $filtered ) ); + } + + /** + * Filter a sanitized text field string. + * + * @since WP 2.9.0 + * + * @param string $filtered The sanitized string. + * @param string $str The string prior to being sanitized. + */ + return apply_filters( 'sanitize_text_field', $filtered, $value ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Using WP native filter. + } + + /** + * Sanitize a url for saving to the database. + * Not to be confused with the old native WP function. + * + * @since 1.8.0 + * + * @param string $value String URL value to sanitize. + * @param array $allowed_protocols Optional set of allowed protocols. + * + * @return string + */ + public static function sanitize_url( $value, $allowed_protocols = [ 'http', 'https' ] ) { + + $url = ''; + $parts = wp_parse_url( $value ); + + if ( isset( $parts['scheme'], $parts['host'] ) ) { + $url = $parts['scheme'] . '://'; + + if ( isset( $parts['user'] ) ) { + $url .= rawurlencode( $parts['user'] ); + $url .= isset( $parts['pass'] ) ? ':' . rawurlencode( $parts['pass'] ) : ''; + $url .= '@'; + } + + $parts['host'] = preg_replace( + '`[^a-z0-9-.:\[\]\\x80-\\xff]`', + '', + strtolower( $parts['host'] ), + ); + + $url .= $parts['host'] . ( isset( $parts['port'] ) ? ':' . (int) $parts['port'] : '' ); + } + + if ( isset( $parts['path'] ) && strpos( $parts['path'], '/' ) === 0 ) { + $path = explode( '/', wp_strip_all_tags( $parts['path'] ) ); + $path = self::sanitize_encoded_text_field( $path ); + $url .= str_replace( '%40', '@', implode( '/', $path ) ); + } + + if ( ! $url ) { + return ''; + } + + if ( isset( $parts['query'] ) ) { + wp_parse_str( $parts['query'], $parsed_query ); + + $parsed_query = array_combine( + self::sanitize_encoded_text_field( array_keys( $parsed_query ) ), + self::sanitize_encoded_text_field( array_values( $parsed_query ) ), + ); + + $url = add_query_arg( $parsed_query, $url ); + } + + if ( isset( $parts['fragment'] ) ) { + $url .= '#' . self::sanitize_encoded_text_field( $parts['fragment'] ); + } + + if ( strpos( $url, '%' ) !== false ) { + $url = preg_replace_callback( + '`%[a-fA-F0-9]{2}`', + static function ( $octects ) { + return strtolower( $octects[0] ); + }, + $url, + ); + } + + return esc_url_raw( $url, $allowed_protocols ); + } + + /** + * Decode, sanitize and encode the array of strings or the string. + * + * @since 13.3 + * + * @param array|string $value The value to sanitize and encode. + * + * @return array|string The sanitized value. + */ + public static function sanitize_encoded_text_field( $value ) { + if ( is_array( $value ) ) { + return array_map( [ self::class, 'sanitize_encoded_text_field' ], $value ); + } + + return rawurlencode( sanitize_text_field( rawurldecode( $value ) ) ); + } + + /** + * Validate a value as boolean. + * + * @since 1.8.0 + * + * @param mixed $value Value to validate. + * + * @return bool + */ + public static function validate_bool( $value ) { + if ( ! isset( self::$has_filters ) ) { + self::$has_filters = extension_loaded( 'filter' ); + } + + if ( self::$has_filters ) { + return filter_var( $value, FILTER_VALIDATE_BOOLEAN ); + } + else { + return self::emulate_filter_bool( $value ); + } + } + + /** + * Cast a value to bool. + * + * @since 1.8.0 + * + * @param mixed $value Value to cast. + * + * @return bool + */ + public static function emulate_filter_bool( $value ) { + $true = [ + '1', + 'true', + 'True', + 'TRUE', + 'y', + 'Y', + 'yes', + 'Yes', + 'YES', + 'on', + 'On', + 'ON', + ]; + $false = [ + '0', + 'false', + 'False', + 'FALSE', + 'n', + 'N', + 'no', + 'No', + 'NO', + 'off', + 'Off', + 'OFF', + ]; + + if ( is_bool( $value ) ) { + return $value; + } + elseif ( is_int( $value ) && ( $value === 0 || $value === 1 ) ) { + return (bool) $value; + } + elseif ( ( is_float( $value ) && ! is_nan( $value ) ) && ( $value === (float) 0 || $value === (float) 1 ) ) { + return (bool) $value; + } + elseif ( is_string( $value ) ) { + $value = trim( $value ); + if ( in_array( $value, $true, true ) ) { + return true; + } + elseif ( in_array( $value, $false, true ) ) { + return false; + } + else { + return false; + } + } + + return false; + } + + /** + * Validate a value as integer. + * + * @since 1.8.0 + * + * @param mixed $value Value to validate. + * + * @return int|bool Int or false in case of failure to convert to int. + */ + public static function validate_int( $value ) { + if ( ! isset( self::$has_filters ) ) { + self::$has_filters = extension_loaded( 'filter' ); + } + + if ( self::$has_filters ) { + return filter_var( $value, FILTER_VALIDATE_INT ); + } + else { + return self::emulate_filter_int( $value ); + } + } + + /** + * Cast a value to integer. + * + * @since 1.8.0 + * + * @param mixed $value Value to cast. + * + * @return int|bool + */ + public static function emulate_filter_int( $value ) { + if ( is_int( $value ) ) { + return $value; + } + elseif ( is_float( $value ) ) { + // phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison. + if ( (int) $value == $value && ! is_nan( $value ) ) { + return (int) $value; + } + else { + return false; + } + } + elseif ( is_string( $value ) ) { + $value = trim( $value ); + if ( $value === '' ) { + return false; + } + elseif ( ctype_digit( $value ) ) { + return (int) $value; + } + elseif ( strpos( $value, '-' ) === 0 && ctype_digit( substr( $value, 1 ) ) ) { + return (int) $value; + } + else { + return false; + } + } + + return false; + } + + /** + * Clears the WP or W3TC cache depending on which is used. + * + * @since 1.8.0 + * + * @return void + */ + public static function clear_cache() { + if ( function_exists( 'w3tc_flush_posts' ) ) { + w3tc_flush_posts(); + } + elseif ( function_exists( 'wp_cache_clear_cache' ) ) { + wp_cache_clear_cache(); + } + } + + /** + * Clear rewrite rules. + * + * @since 1.8.0 + * + * @return void + */ + public static function clear_rewrites() { + update_option( 'rewrite_rules', '' ); + } + + /** + * Do simple reliable math calculations without the risk of wrong results. + * + * In the rare case that the bcmath extension would not be loaded, it will return the normal calculation results. + * + * @link http://floating-point-gui.de/ + * @link http://php.net/language.types.float.php See the big red warning. + * + * @since 1.5.0 + * @since 1.8.0 Moved from stand-alone function to this class. + * + * @param mixed $number1 Scalar (string/int/float/bool). + * @param string $action Calculation action to execute. Valid input: + * '+' or 'add' or 'addition', + * '-' or 'sub' or 'subtract', + * '*' or 'mul' or 'multiply', + * '/' or 'div' or 'divide', + * '%' or 'mod' or 'modulus' + * '=' or 'comp' or 'compare'. + * @param mixed $number2 Scalar (string/int/float/bool). + * @param bool $round Whether or not to round the result. Defaults to false. + * Will be disregarded for a compare operation. + * @param int $decimals Decimals for rounding operation. Defaults to 0. + * @param int $precision Calculation precision. Defaults to 10. + * + * @return mixed Calculation Result or false if either or the numbers isn't scalar or + * an invalid operation was passed. + * - For compare the result will always be an integer. + * - For all other operations, the result will either be an integer (preferred) + * or a float. + */ + public static function calc( $number1, $action, $number2, $round = false, $decimals = 0, $precision = 10 ) { + static $bc; + + if ( ! is_scalar( $number1 ) || ! is_scalar( $number2 ) ) { + return false; + } + + if ( ! isset( $bc ) ) { + $bc = extension_loaded( 'bcmath' ); + } + + if ( $bc ) { + $number1 = number_format( $number1, 10, '.', '' ); + $number2 = number_format( $number2, 10, '.', '' ); + } + + $result = null; + $compare = false; + + switch ( $action ) { + case '+': + case 'add': + case 'addition': + $result = ( $bc ) ? bcadd( $number1, $number2, $precision ) /* string */ : ( $number1 + $number2 ); + break; + + case '-': + case 'sub': + case 'subtract': + $result = ( $bc ) ? bcsub( $number1, $number2, $precision ) /* string */ : ( $number1 - $number2 ); + break; + + case '*': + case 'mul': + case 'multiply': + $result = ( $bc ) ? bcmul( $number1, $number2, $precision ) /* string */ : ( $number1 * $number2 ); + break; + + case '/': + case 'div': + case 'divide': + if ( $bc ) { + $result = bcdiv( $number1, $number2, $precision ); // String, or NULL if right_operand is 0. + } + elseif ( $number2 != 0 ) { // phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison. + $result = ( $number1 / $number2 ); + } + + if ( ! isset( $result ) ) { + $result = 0; + } + break; + + case '%': + case 'mod': + case 'modulus': + if ( $bc ) { + $result = bcmod( $number1, $number2 ); // String, or NULL if modulus is 0. + } + elseif ( $number2 != 0 ) { // phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison. + $result = ( $number1 % $number2 ); + } + + if ( ! isset( $result ) ) { + $result = 0; + } + break; + + case '=': + case 'comp': + case 'compare': + $compare = true; + if ( $bc ) { + $result = bccomp( $number1, $number2, $precision ); // Returns int 0, 1 or -1. + } + else { + // phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison. + $result = ( $number1 == $number2 ) ? 0 : ( ( $number1 > $number2 ) ? 1 : -1 ); + } + break; + } + + if ( isset( $result ) ) { + if ( $compare === false ) { + if ( $round === true ) { + $result = round( (float) $result, $decimals ); + if ( $decimals === 0 ) { + $result = (int) $result; + } + } + else { + // phpcs:ignore Universal.Operators.StrictComparisons -- Purposeful loose comparison. + $result = ( intval( $result ) == $result ) ? (int) $result : (float) $result; + } + } + + return $result; + } + + return false; + } + + /** + * Trim whitespace and NBSP (Non-breaking space) from string. + * + * @since 2.0.0 + * + * @param string $text String input to trim. + * + * @return string + */ + public static function trim_nbsp_from_string( $text ) { + $find = [ ' ', chr( 0xC2 ) . chr( 0xA0 ) ]; + $text = str_replace( $find, ' ', $text ); + $text = trim( $text ); + + return $text; + } + + /** + * Check if a string is a valid datetime. + * + * @since 2.0.0 + * + * @param string $datetime String input to check as valid input for DateTime class. + * + * @return bool + */ + public static function is_valid_datetime( $datetime ) { + return YoastSEO()->helpers->date->is_valid_datetime( $datetime ); + } + + /** + * Format the URL to be sure it is okay for using as a redirect url. + * + * This method will parse the URL and combine them in one string. + * + * @since 2.3.0 + * + * @param string $url URL string. + * + * @return mixed + */ + public static function format_url( $url ) { + $parsed_url = wp_parse_url( $url ); + + $formatted_url = ''; + if ( ! empty( $parsed_url['path'] ) ) { + $formatted_url = $parsed_url['path']; + } + + // Prepend a slash if first char != slash. + if ( stripos( $formatted_url, '/' ) !== 0 ) { + $formatted_url = '/' . $formatted_url; + } + + // Append 'query' string if it exists. + if ( ! empty( $parsed_url['query'] ) ) { + $formatted_url .= '?' . $parsed_url['query']; + } + + return apply_filters( 'wpseo_format_admin_url', $formatted_url ); + } + + /** + * Retrieves the sitename. + * + * @since 3.0.0 + * + * @return string + */ + public static function get_site_name() { + return YoastSEO()->helpers->site->get_site_name(); + } + + /** + * Check if the current opened page is a Yoast SEO page. + * + * @since 3.0.0 + * + * @return bool + */ + public static function is_yoast_seo_page() { + return YoastSEO()->helpers->current_page->is_yoast_seo_page(); + } + + /** + * Check if the current opened page belongs to Yoast SEO Free. + * + * @since 3.3.0 + * + * @param string $current_page The current page the user is on. + * + * @return bool + */ + public static function is_yoast_seo_free_page( $current_page ) { + $yoast_seo_free_pages = [ + 'wpseo_tools', + 'wpseo_search_console', + ]; + + return in_array( $current_page, $yoast_seo_free_pages, true ); + } + + /** + * Determine if Yoast SEO is in development mode? + * + * Inspired by JetPack (https://github.com/Automattic/jetpack/blob/master/class.jetpack.php#L1383-L1406). + * + * @since 3.0.0 + * + * @return bool + */ + public static function is_development_mode() { + $development_mode = false; + + if ( defined( 'YOAST_ENVIRONMENT' ) && YOAST_ENVIRONMENT === 'development' ) { + $development_mode = true; + } + elseif ( defined( 'WPSEO_DEBUG' ) ) { + $development_mode = WPSEO_DEBUG; + } + elseif ( site_url() && strpos( site_url(), '.' ) === false ) { + $development_mode = true; + } + + /** + * Filter the Yoast SEO development mode. + * + * @since 3.0 + * + * @param bool $development_mode Is Yoast SEOs development mode active. + */ + return apply_filters( 'yoast_seo_development_mode', $development_mode ); + } + + /** + * Retrieve home URL with proper trailing slash. + * + * @since 3.3.0 + * + * @param string $path Path relative to home URL. + * @param string|null $scheme Scheme to apply. + * + * @return string Home URL with optional path, appropriately slashed if not. + */ + public static function home_url( $path = '', $scheme = null ) { + return YoastSEO()->helpers->url->home( $path, $scheme ); + } + + /** + * Checks if the WP-REST-API is available. + * + * @since 3.6 + * @since 3.7 Introduced the $minimum_version parameter. + * + * @param string $minimum_version The minimum version the API should be. + * + * @return bool Returns true if the API is available. + */ + public static function is_api_available( $minimum_version = '2.0' ) { + return ( defined( 'REST_API_VERSION' ) + && version_compare( REST_API_VERSION, $minimum_version, '>=' ) ); + } + + /** + * Determine whether or not the metabox should be displayed for a post type. + * + * @param string|null $post_type Optional. The post type to check the visibility of the metabox for. + * + * @return bool Whether or not the metabox should be displayed. + */ + protected static function display_post_type_metabox( $post_type = null ) { + if ( ! isset( $post_type ) ) { + $post_type = get_post_type(); + } + + if ( ! isset( $post_type ) || ! WPSEO_Post_Type::is_post_type_accessible( $post_type ) ) { + return false; + } + + if ( $post_type === 'attachment' && WPSEO_Options::get( 'disable-attachment' ) ) { + return false; + } + + return apply_filters( 'wpseo_enable_editor_features_' . $post_type, WPSEO_Options::get( 'display-metabox-pt-' . $post_type ) ); + } + + /** + * Determine whether or not the metabox should be displayed for a taxonomy. + * + * @param string|null $taxonomy Optional. The post type to check the visibility of the metabox for. + * + * @return bool Whether or not the metabox should be displayed. + */ + protected static function display_taxonomy_metabox( $taxonomy = null ) { + if ( ! isset( $taxonomy ) || ! in_array( $taxonomy, get_taxonomies( [ 'public' => true ], 'names' ), true ) ) { + return false; + } + + return WPSEO_Options::get( 'display-metabox-tax-' . $taxonomy ); + } + + /** + * Determines whether the metabox is active for the given identifier and type. + * + * @param string $identifier The identifier to check for. + * @param string $type The type to check for. + * + * @return bool Whether or not the metabox is active. + */ + public static function is_metabox_active( $identifier, $type ) { + if ( $type === 'post_type' ) { + return self::display_post_type_metabox( $identifier ); + } + + if ( $type === 'taxonomy' ) { + return self::display_taxonomy_metabox( $identifier ); + } + + return false; + } + + /** + * Determines whether the plugin is active for the entire network. + * + * @return bool Whether the plugin is network-active. + */ + public static function is_plugin_network_active() { + return YoastSEO()->helpers->url->is_plugin_network_active(); + } + + /** + * Gets the type of the current post. + * + * @return string The post type, or an empty string. + */ + public static function get_post_type() { + $wp_screen = get_current_screen(); + + if ( $wp_screen !== null && ! empty( $wp_screen->post_type ) ) { + return $wp_screen->post_type; + } + return ''; + } + + /** + * Gets the type of the current page. + * + * @return string Returns 'post' if the current page is a post edit page. Taxonomy in other cases. + */ + public static function get_page_type() { + global $pagenow; + if ( WPSEO_Metabox::is_post_edit( $pagenow ) ) { + return 'post'; + } + + return 'taxonomy'; + } + + /** + * Getter for the Adminl10n array. Applies the wpseo_admin_l10n filter. + * + * @return array The Adminl10n array. + */ + public static function get_admin_l10n() { + $post_type = self::get_post_type(); + $page_type = self::get_page_type(); + + $label_object = false; + $no_index = false; + + if ( $page_type === 'post' ) { + $label_object = get_post_type_object( $post_type ); + $no_index = WPSEO_Options::get( 'noindex-' . $post_type, false ); + } + else { + $label_object = WPSEO_Taxonomy::get_labels(); + + $wp_screen = get_current_screen(); + + if ( $wp_screen !== null && ! empty( $wp_screen->taxonomy ) ) { + $taxonomy_slug = $wp_screen->taxonomy; + $no_index = WPSEO_Options::get( 'noindex-tax-' . $taxonomy_slug, false ); + } + } + + $wpseo_admin_l10n = [ + 'displayAdvancedTab' => WPSEO_Capability_Utils::current_user_can( 'wpseo_edit_advanced_metadata' ) || ! WPSEO_Options::get( 'disableadvanced_meta' ), + 'noIndex' => (bool) $no_index, + 'isPostType' => (bool) get_post_type(), + 'postType' => get_post_type(), + 'postTypeNamePlural' => ( $page_type === 'post' ) ? $label_object->label : $label_object->name, + 'postTypeNameSingular' => ( $page_type === 'post' ) ? $label_object->labels->singular_name : $label_object->singular_name, + 'isBreadcrumbsDisabled' => WPSEO_Options::get( 'breadcrumbs-enable', false ) !== true && ! current_theme_supports( 'yoast-seo-breadcrumbs' ), + 'isAiFeatureActive' => (bool) WPSEO_Options::get( 'enable_ai_generator' ), + ]; + + $additional_entries = apply_filters( 'wpseo_admin_l10n', [] ); + if ( is_array( $additional_entries ) ) { + $wpseo_admin_l10n = array_merge( $wpseo_admin_l10n, $additional_entries ); + } + + return $wpseo_admin_l10n; + } + + /** + * Retrieves the analysis worker log level. Defaults to errors only. + * + * Uses bool YOAST_SEO_DEBUG as flag to enable logging. Off equals ERROR. + * Uses string YOAST_SEO_DEBUG_ANALYSIS_WORKER as log level for the Analysis + * Worker. Defaults to INFO. + * Can be: TRACE, DEBUG, INFO, WARN or ERROR. + * + * @return string The log level to use. + */ + public static function get_analysis_worker_log_level() { + if ( defined( 'YOAST_SEO_DEBUG' ) && YOAST_SEO_DEBUG ) { + return defined( 'YOAST_SEO_DEBUG_ANALYSIS_WORKER' ) ? YOAST_SEO_DEBUG_ANALYSIS_WORKER : 'INFO'; + } + + return 'ERROR'; + } + + /** + * Returns the unfiltered home URL. + * + * In case WPML is installed, returns the original home_url and not the WPML version. + * In case of a multisite setup we return the network_home_url. + * + * @codeCoverageIgnore + * + * @return string The home url. + */ + public static function get_home_url() { + return YoastSEO()->helpers->url->network_safe_home_url(); + } + + /** + * Prepares data for outputting as JSON. + * + * @param array $data The data to format. + * + * @return string|false The prepared JSON string. + */ + public static function format_json_encode( $data ) { + $flags = ( JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); + + if ( self::is_development_mode() ) { + $flags = ( $flags | JSON_PRETTY_PRINT ); + + /** + * Filter the Yoast SEO development mode. + * + * @param array $data Allows filtering of the JSON data for debug purposes. + */ + $data = apply_filters( 'wpseo_debug_json_data', $data ); + } + + // phpcs:ignore Yoast.Yoast.JsonEncodeAlternative.FoundWithAdditionalParams -- This is the definition of format_json_encode. + return wp_json_encode( $data, $flags ); + } + + /** + * Extends the allowed post tags with accessibility-related attributes. + * + * @codeCoverageIgnore + * + * @param array $allowed_post_tags The allowed post tags. + * + * @return array The allowed tags including post tags, input tags and select tags. + */ + public static function extend_kses_post_with_a11y( $allowed_post_tags ) { + static $a11y_tags; + + if ( isset( $a11y_tags ) === false ) { + $a11y_tags = [ + 'button' => [ + 'aria-expanded' => true, + 'aria-controls' => true, + ], + 'div' => [ + 'tabindex' => true, + ], + // Below are attributes that are needed for backwards compatibility (WP < 5.1). + 'span' => [ + 'aria-hidden' => true, + ], + 'input' => [ + 'aria-describedby' => true, + ], + 'select' => [ + 'aria-describedby' => true, + ], + 'textarea' => [ + 'aria-describedby' => true, + ], + ]; + + // Add the global allowed attributes to each html element. + $a11y_tags = array_map( '_wp_add_global_attributes', $a11y_tags ); + } + + return array_merge_recursive( $allowed_post_tags, $a11y_tags ); + } + + /** + * Extends the allowed post tags with input, select and option tags. + * + * @codeCoverageIgnore + * + * @param array $allowed_post_tags The allowed post tags. + * + * @return array The allowed tags including post tags, input tags, select tags and option tags. + */ + public static function extend_kses_post_with_forms( $allowed_post_tags ) { + static $input_tags; + + if ( isset( $input_tags ) === false ) { + $input_tags = [ + 'input' => [ + 'accept' => true, + 'accesskey' => true, + 'align' => true, + 'alt' => true, + 'autocomplete' => true, + 'autofocus' => true, + 'checked' => true, + 'contenteditable' => true, + 'dirname' => true, + 'disabled' => true, + 'draggable' => true, + 'dropzone' => true, + 'form' => true, + 'formaction' => true, + 'formenctype' => true, + 'formmethod' => true, + 'formnovalidate' => true, + 'formtarget' => true, + 'height' => true, + 'hidden' => true, + 'lang' => true, + 'list' => true, + 'max' => true, + 'maxlength' => true, + 'min' => true, + 'multiple' => true, + 'name' => true, + 'pattern' => true, + 'placeholder' => true, + 'readonly' => true, + 'required' => true, + 'size' => true, + 'spellcheck' => true, + 'src' => true, + 'step' => true, + 'tabindex' => true, + 'translate' => true, + 'type' => true, + 'value' => true, + 'width' => true, + + /* + * Below are attributes that are needed for backwards compatibility (WP < 5.1). + * They are used for the social media image in the metabox. + * These can be removed once we move to the React versions of the social previews. + */ + 'data-target' => true, + 'data-target-id' => true, + ], + 'select' => [ + 'accesskey' => true, + 'autofocus' => true, + 'contenteditable' => true, + 'disabled' => true, + 'draggable' => true, + 'dropzone' => true, + 'form' => true, + 'hidden' => true, + 'lang' => true, + 'multiple' => true, + 'name' => true, + 'onblur' => true, + 'onchange' => true, + 'oncontextmenu' => true, + 'onfocus' => true, + 'oninput' => true, + 'oninvalid' => true, + 'onreset' => true, + 'onsearch' => true, + 'onselect' => true, + 'onsubmit' => true, + 'required' => true, + 'size' => true, + 'spellcheck' => true, + 'tabindex' => true, + 'translate' => true, + ], + 'option' => [ + 'class' => true, + 'disabled' => true, + 'id' => true, + 'label' => true, + 'selected' => true, + 'value' => true, + ], + ]; + + // Add the global allowed attributes to each html element. + $input_tags = array_map( '_wp_add_global_attributes', $input_tags ); + } + + return array_merge_recursive( $allowed_post_tags, $input_tags ); + } + + /** + * Gets an array of enabled features. + * + * @return string[] The array of enabled features. + */ + public static function retrieve_enabled_features() { + /** + * The feature flag integration. + * + * @var Feature_Flag_Integration $feature_flag_integration + */ + $feature_flag_integration = YoastSEO()->classes->get( Feature_Flag_Integration::class ); + return $feature_flag_integration->get_enabled_features(); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/class-yoast-dynamic-rewrites.php b/html/wp-content/plugins/wordpress-seo/inc/class-yoast-dynamic-rewrites.php new file mode 100644 index 0000000..eb02946 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/class-yoast-dynamic-rewrites.php @@ -0,0 +1,178 @@ +register_hooks(); + } + + return self::$instance; + } + + /** + * Constructor. + * + * Sets the WP_Rewrite instance to use. + * + * @param WP_Rewrite|null $rewrite Optional. WP_Rewrite instance to use. Default is the $wp_rewrite global. + * @throws RuntimeException Throws an exception if the $wp_rewrite global is not set. + */ + public function __construct( $rewrite = null ) { + if ( ! $rewrite ) { + if ( empty( $GLOBALS['wp_rewrite'] ) ) { + /* translators: 1: PHP class name, 2: PHP variable name */ + throw new RuntimeException( sprintf( __( 'The %1$s class must not be instantiated before the %2$s global is set.', 'wordpress-seo' ), self::class, '$wp_rewrite' ) ); + } + + $rewrite = $GLOBALS['wp_rewrite']; + } + + $this->wp_rewrite = $rewrite; + } + + /** + * Registers all necessary hooks with WordPress. + * + * @return void + */ + public function register_hooks() { + add_action( 'init', [ $this, 'trigger_dynamic_rewrite_rules_hook' ], 1 ); + add_filter( 'option_rewrite_rules', [ $this, 'filter_rewrite_rules_option' ] ); + add_filter( 'sanitize_option_rewrite_rules', [ $this, 'sanitize_rewrite_rules_option' ] ); + } + + /** + * Adds a dynamic rewrite rule that transforms a URL structure to a set of query vars. + * + * Rules registered with this method are applied dynamically and do not require the rewrite rules + * to be flushed in order to become active, which is a benefit over the regular WordPress core API. + * Note however that the dynamic application only works for rules that correspond to index.php. + * Non-WordPress rewrite rules still require flushing. + * + * Any value in the $after parameter that isn't 'bottom' will result in the rule + * being placed at the top of the rewrite rules. + * + * @param string $regex Regular expression to match request against. + * @param string|array $query The corresponding query vars for this rewrite rule. + * @param string $priority Optional. Priority of the new rule. Accepts 'top' + * or 'bottom'. Default 'bottom'. + * + * @return void + */ + public function add_rule( $regex, $query, $priority = 'bottom' ) { + if ( is_array( $query ) ) { + $query = add_query_arg( $query, 'index.php' ); + } + + $this->wp_rewrite->add_rule( $regex, $query, $priority ); + + // Do not further handle external rules. + if ( substr( $query, 0, strlen( $this->wp_rewrite->index . '?' ) ) !== $this->wp_rewrite->index . '?' ) { + return; + } + + if ( $priority === 'bottom' ) { + $this->extra_rules_bottom[ $regex ] = $query; + return; + } + + $this->extra_rules_top[ $regex ] = $query; + } + + /** + * Triggers the hook on which rewrite rules should be added. + * + * This allows for a more specific point in time from the generic `init` hook where this is + * otherwise handled. + * + * @return void + */ + public function trigger_dynamic_rewrite_rules_hook() { + + /** + * Fires when the plugin's dynamic rewrite rules should be added. + * + * @param self $dynamic_rewrites Dynamic rewrites handler instance. Use its `add_rule()` method + * to add dynamic rewrite rules. + */ + do_action( 'yoast_add_dynamic_rewrite_rules', $this ); + } + + /** + * Filters the rewrite rules option to dynamically add additional rewrite rules. + * + * @param array|string $rewrite_rules Array of rewrite rule $regex => $query pairs, or empty string + * if currently not set. + * + * @return array|string Filtered value of $rewrite_rules. + */ + public function filter_rewrite_rules_option( $rewrite_rules ) { + // Do not add extra rewrite rules if the rules need to be flushed. + if ( empty( $rewrite_rules ) ) { + return $rewrite_rules; + } + + return array_merge( $this->extra_rules_top, $rewrite_rules, $this->extra_rules_bottom ); + } + + /** + * Sanitizes the rewrite rules option prior to writing it to the database. + * + * This method ensures that the dynamic rewrite rules do not become part of the actual option. + * + * @param array|string $rewrite_rules Array pf rewrite rule $regex => $query pairs, or empty string + * in order to unset. + * + * @return array|string Filtered value of $rewrite_rules before writing the option. + */ + public function sanitize_rewrite_rules_option( $rewrite_rules ) { + if ( empty( $rewrite_rules ) ) { + return $rewrite_rules; + } + + return array_diff_key( $rewrite_rules, $this->extra_rules_top, $this->extra_rules_bottom ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/date-helper.php b/html/wp-content/plugins/wordpress-seo/inc/date-helper.php new file mode 100644 index 0000000..f6489a4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/date-helper.php @@ -0,0 +1,61 @@ +helpers->date->format( $date, $format ); + } + + /** + * Formats the given timestamp to the needed format. + * + * @param int $timestamp The timestamp to use for the formatting. + * @param string $format The format that the passed date should be in. + * + * @return string The formatted date. + */ + public function format_timestamp( $timestamp, $format = DATE_W3C ) { + return YoastSEO()->helpers->date->format_timestamp( $timestamp, $format ); + } + + /** + * Formats a given date in UTC TimeZone format and translate it to the set language. + * + * @param string $date String representing the date / time. + * @param string $format The format that the passed date should be in. + * + * @return string The formatted and translated date. + */ + public function format_translated( $date, $format = DATE_W3C ) { + return YoastSEO()->helpers->date->format_translated( $date, $format ); + } + + /** + * Check if a string is a valid datetime. + * + * @param string $datetime String input to check as valid input for DateTime class. + * + * @return bool True when datatime is valid. + */ + public function is_valid_datetime( $datetime ) { + return YoastSEO()->helpers->date->is_valid_datetime( $datetime ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/exceptions/class-myyoast-bad-request-exception.php b/html/wp-content/plugins/wordpress-seo/inc/exceptions/class-myyoast-bad-request-exception.php new file mode 100644 index 0000000..d9d9f9a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/exceptions/class-myyoast-bad-request-exception.php @@ -0,0 +1,13 @@ +get_defaults(); + * + * @var array> + */ + protected $defaults = [ + 'llms_txt_selection_mode' => 'auto', + 'about_us_page' => 0, + 'contact_page' => 0, + 'terms_page' => 0, + 'privacy_policy_page' => 0, + 'shop_page' => 0, + 'other_included_pages' => [], + ]; + + /** + * Get the singleton instance of this class. + * + * @return object + */ + public static function get_instance() { + if ( ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * All concrete classes must contain a validate_option() method which validates all + * values within the option. + * + * @param array $dirty New value for the option. + * @param array $clean Clean value for the option, normally the defaults. + * @param array $old Old value of the option. + * + * @return array The clean option with the saved value. + */ + protected function validate_option( $dirty, $clean, $old ) { + + foreach ( $clean as $key => $value ) { + switch ( $key ) { + case 'other_included_pages': + if ( isset( $dirty[ $key ] ) ) { + $items = $dirty[ $key ]; + if ( ! is_array( $items ) ) { + $items = json_decode( $dirty[ $key ], true ); + } + + if ( is_array( $items ) ) { + $items = array_slice( $items, 0, $this->get_other_included_pages_limit() ); + foreach ( $items as $item ) { + $validated_id = WPSEO_Utils::validate_int( $item ); + + if ( $validated_id === false || $validated_id === 0 ) { + continue; + } + + $clean[ $key ][] = $validated_id; + } + } + } + + break; + case 'about_us_page': + case 'contact_page': + case 'terms_page': + case 'privacy_policy_page': + case 'shop_page': + if ( isset( $dirty[ $key ] ) ) { + $int = WPSEO_Utils::validate_int( $dirty[ $key ] ); + if ( $int !== false && $int >= 0 ) { + $clean[ $key ] = $int; + } + } + elseif ( isset( $old[ $key ] ) ) { + $int = WPSEO_Utils::validate_int( $old[ $key ] ); + if ( $int !== false && $int >= 0 ) { + $clean[ $key ] = $int; + } + } + break; + case 'llms_txt_selection_mode': + if ( isset( $dirty[ $key ] ) && in_array( $dirty[ $key ], [ 'auto', 'manual' ], true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + break; + } + } + + return $clean; + } + + /** + * Gets the limit for the other included pages. + * + * @return int The limit for the other included pages. + */ + public function get_other_included_pages_limit() { + return self::OTHER_INCLUDED_PAGES_LIMIT; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-ms.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-ms.php new file mode 100644 index 0000000..b0b38e1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-ms.php @@ -0,0 +1,259 @@ +get_defaults(); + * + * @var array + */ + protected $defaults = []; + + /** + * Available options for the 'access' setting. Used for input validation. + * + * {@internal Important: Make sure the options added to the array here are in line + * with the keys for the options set for the select box in the + * admin/pages/network.php file.}} + * + * @var array + */ + public static $allowed_access_options = [ + 'admin', + 'superadmin', + ]; + + /** + * Get the singleton instance of this class. + * + * @return object + */ + public static function get_instance() { + if ( ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Only run parent constructor in multisite context. + */ + public function __construct() { + $allow_prefix = self::ALLOW_KEY_PREFIX; + $this->defaults = [ + 'access' => 'admin', + 'defaultblog' => '', // Numeric blog ID or empty. + "{$allow_prefix}disableadvanced_meta" => true, + "{$allow_prefix}ryte_indexability" => false, + "{$allow_prefix}content_analysis_active" => true, + "{$allow_prefix}keyword_analysis_active" => true, + "{$allow_prefix}inclusive_language_analysis_active" => true, + "{$allow_prefix}enable_admin_bar_menu" => true, + "{$allow_prefix}enable_cornerstone_content" => true, + "{$allow_prefix}enable_xml_sitemap" => true, + "{$allow_prefix}enable_text_link_counter" => true, + "{$allow_prefix}enable_headless_rest_endpoints" => true, + "{$allow_prefix}enable_metabox_insights" => true, + "{$allow_prefix}enable_link_suggestions" => true, + "{$allow_prefix}tracking" => true, + "{$allow_prefix}enable_enhanced_slack_sharing" => true, + "{$allow_prefix}semrush_integration_active" => true, + "{$allow_prefix}wincher_integration_active" => false, + "{$allow_prefix}remove_feed_global" => true, + "{$allow_prefix}remove_feed_global_comments" => true, + "{$allow_prefix}remove_feed_post_comments" => true, + "{$allow_prefix}enable_index_now" => true, + "{$allow_prefix}enable_ai_generator" => true, + "{$allow_prefix}remove_feed_authors" => true, + "{$allow_prefix}remove_feed_categories" => true, + "{$allow_prefix}remove_feed_tags" => true, + "{$allow_prefix}remove_feed_custom_taxonomies" => true, + "{$allow_prefix}remove_feed_post_types" => true, + "{$allow_prefix}remove_feed_search" => true, + "{$allow_prefix}remove_atom_rdf_feeds" => true, + "{$allow_prefix}remove_shortlinks" => true, + "{$allow_prefix}remove_rest_api_links" => true, + "{$allow_prefix}remove_rsd_wlw_links" => true, + "{$allow_prefix}remove_oembed_links" => true, + "{$allow_prefix}remove_generator" => true, + "{$allow_prefix}remove_emoji_scripts" => true, + "{$allow_prefix}remove_powered_by_header" => true, + "{$allow_prefix}remove_pingback_header" => true, + "{$allow_prefix}clean_campaign_tracking_urls" => true, + "{$allow_prefix}clean_permalinks" => true, + "{$allow_prefix}search_cleanup" => true, + "{$allow_prefix}search_cleanup_emoji" => true, + "{$allow_prefix}search_cleanup_patterns" => true, + "{$allow_prefix}redirect_search_pretty_urls" => true, + "{$allow_prefix}algolia_integration_active" => true, + ]; + + if ( is_multisite() ) { + parent::__construct(); + + add_filter( 'admin_title', [ 'Yoast_Input_Validation', 'add_yoast_admin_document_title_errors' ] ); + } + } + + /** + * Add filters to make sure that the option default is returned if the option is not set + * + * @return void + */ + public function add_default_filters() { + // Don't change, needs to check for false as could return prio 0 which would evaluate to false. + if ( has_filter( 'default_site_option_' . $this->option_name, [ $this, 'get_defaults' ] ) === false ) { + add_filter( 'default_site_option_' . $this->option_name, [ $this, 'get_defaults' ] ); + } + } + + /** + * Remove the default filters. + * Called from the validate() method to prevent failure to add new options. + * + * @return void + */ + public function remove_default_filters() { + remove_filter( 'default_site_option_' . $this->option_name, [ $this, 'get_defaults' ] ); + } + + /** + * Add filters to make sure that the option is merged with its defaults before being returned. + * + * @return void + */ + public function add_option_filters() { + // Don't change, needs to check for false as could return prio 0 which would evaluate to false. + if ( has_filter( 'site_option_' . $this->option_name, [ $this, 'get_option' ] ) === false ) { + add_filter( 'site_option_' . $this->option_name, [ $this, 'get_option' ] ); + } + } + + /** + * Remove the option filters. + * Called from the clean_up methods to make sure we retrieve the original old option. + * + * @return void + */ + public function remove_option_filters() { + remove_filter( 'site_option_' . $this->option_name, [ $this, 'get_option' ] ); + } + + /* *********** METHODS influencing add_uption(), update_option() and saving from admin pages *********** */ + + /** + * Validate the option. + * + * @param array $dirty New value for the option. + * @param array $clean Clean value for the option, normally the defaults. + * @param array $old Old value of the option. + * + * @return array Validated clean value for the option to be saved to the database. + */ + protected function validate_option( $dirty, $clean, $old ) { + + foreach ( $clean as $key => $value ) { + switch ( $key ) { + case 'access': + if ( isset( $dirty[ $key ] ) && in_array( $dirty[ $key ], self::$allowed_access_options, true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + elseif ( function_exists( 'add_settings_error' ) ) { + add_settings_error( + $this->group_name, // Slug title of the setting. + $key, // Suffix-ID for the error message box. + /* translators: %1$s expands to the option name and %2$sexpands to Yoast SEO */ + sprintf( __( '%1$s is not a valid choice for who should be allowed access to the %2$s settings. Value reset to the default.', 'wordpress-seo' ), esc_html( sanitize_text_field( $dirty[ $key ] ) ), 'Yoast SEO' ), // The error message. + 'error', // Message type. + ); + } + break; + + case 'defaultblog': + if ( isset( $dirty[ $key ] ) && ( $dirty[ $key ] !== '' && $dirty[ $key ] !== '-' ) ) { + $int = WPSEO_Utils::validate_int( $dirty[ $key ] ); + if ( $int !== false && $int > 0 ) { + // Check if a valid blog number has been received. + $exists = get_blog_details( $int, false ); + if ( $exists && $exists->deleted === '0' ) { + $clean[ $key ] = $int; + } + elseif ( function_exists( 'add_settings_error' ) ) { + add_settings_error( + $this->group_name, // Slug title of the setting. + $key, // Suffix-ID for the error message box. + esc_html__( 'The default blog setting must be the numeric blog id of the blog you want to use as default.', 'wordpress-seo' ) + . '
            ' + . sprintf( + /* translators: %s is the ID number of a blog. */ + esc_html__( 'This must be an existing blog. Blog %s does not exist or has been marked as deleted.', 'wordpress-seo' ), + '' . esc_html( sanitize_text_field( $dirty[ $key ] ) ) . '', + ), // The error message. + 'error', // Message type. + ); + } + unset( $exists ); + } + elseif ( function_exists( 'add_settings_error' ) ) { + add_settings_error( + $this->group_name, // Slug title of the setting. + $key, // Suffix-ID for the error message box. + esc_html__( 'The default blog setting must be the numeric blog id of the blog you want to use as default.', 'wordpress-seo' ) . '
            ' . esc_html__( 'No numeric value was received.', 'wordpress-seo' ), // The error message. + 'error', // Message type. + ); + } + unset( $int ); + } + break; + + default: + $clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : false ); + break; + } + } + + return $clean; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-social.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-social.php new file mode 100644 index 0000000..a2aaa69 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-social.php @@ -0,0 +1,322 @@ +get_defaults(); + * + * @var array + */ + protected $defaults = [ + // Form fields. + 'facebook_site' => '', // Text field. + 'instagram_url' => '', + 'linkedin_url' => '', + 'myspace_url' => '', + 'og_default_image' => '', // Text field. + 'og_default_image_id' => '', + 'og_frontpage_title' => '', // Text field. + 'og_frontpage_desc' => '', // Text field. + 'og_frontpage_image' => '', // Text field. + 'og_frontpage_image_id' => '', + 'opengraph' => true, + 'pinterest_url' => '', + 'pinterestverify' => '', + 'twitter' => true, + 'twitter_site' => '', // Text field. + 'twitter_card_type' => 'summary_large_image', + 'youtube_url' => '', + 'wikipedia_url' => '', + 'other_social_urls' => [], + 'mastodon_url' => '', + ]; + + /** + * Array of sub-options which should not be overloaded with multi-site defaults. + * + * @var array + */ + public $ms_exclude = [ + /* Privacy. */ + 'pinterestverify', + ]; + + /** + * Array of allowed twitter card types. + * + * While we only have the options summary and summary_large_image in the + * interface now, we might change that at some point. + * + * {@internal Uncomment any of these to allow them in validation *and* automatically + * add them as a choice in the options page.}} + * + * @var array + */ + public static $twitter_card_types = [ + 'summary_large_image' => '', + // 'summary' => '', + // 'photo' => '', + // 'gallery' => '', + // 'app' => '', + // 'player' => '', + // 'product' => '', + ]; + + /** + * Add the actions and filters for the option. + */ + protected function __construct() { + parent::__construct(); + + add_filter( 'admin_title', [ 'Yoast_Input_Validation', 'add_yoast_admin_document_title_errors' ] ); + } + + /** + * Get the singleton instance of this class. + * + * @return object + */ + public static function get_instance() { + if ( ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Translate/set strings used in the option defaults. + * + * @return void + */ + public function translate_defaults() { + self::$twitter_card_types['summary_large_image'] = 'Summary with large image'; + } + + /** + * Validate the option. + * + * @param array $dirty New value for the option. + * @param array $clean Clean value for the option, normally the defaults. + * @param array $old Old value of the option. + * + * @return array Validated clean value for the option to be saved to the database. + */ + protected function validate_option( $dirty, $clean, $old ) { + + foreach ( $clean as $key => $value ) { + switch ( $key ) { + /* Text fields. */ + case 'og_frontpage_desc': + case 'og_frontpage_title': + if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) { + $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $dirty[ $key ] ); + } + break; + + case 'og_default_image_id': + case 'og_frontpage_image_id': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = (int) $dirty[ $key ]; + + if ( $dirty[ $key ] === '' ) { + $clean[ $key ] = $dirty[ $key ]; + } + } + break; + + /* URL text fields - no ftp allowed. */ + case 'facebook_site': + case 'instagram_url': + case 'linkedin_url': + case 'myspace_url': + case 'pinterest_url': + case 'og_default_image': + case 'og_frontpage_image': + case 'youtube_url': + case 'wikipedia_url': + case 'mastodon_url': + $this->validate_url( $key, $dirty, $old, $clean ); + break; + + case 'pinterestverify': + $this->validate_verification_string( $key, $dirty, $old, $clean ); + break; + + /* Twitter user name. */ + case 'twitter_site': + if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) { + $twitter_id = $this->validate_twitter_id( $dirty[ $key ] ); + + if ( $twitter_id ) { + $clean[ $key ] = $twitter_id; + } + elseif ( isset( $old[ $key ] ) && $old[ $key ] !== '' ) { + $twitter_id = sanitize_text_field( ltrim( $old[ $key ], '@' ) ); + if ( preg_match( '`^[A-Za-z0-9_]{1,25}$`', $twitter_id ) ) { + $clean[ $key ] = $twitter_id; + } + } + unset( $twitter_id ); + + Yoast_Input_Validation::add_dirty_value_to_settings_errors( $key, $dirty[ $key ] ); + } + break; + + case 'twitter_card_type': + if ( isset( $dirty[ $key ], self::$twitter_card_types[ $dirty[ $key ] ] ) && $dirty[ $key ] !== '' ) { + $clean[ $key ] = $dirty[ $key ]; + } + break; + + /* Boolean fields. */ + case 'opengraph': + case 'twitter': + $clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : false ); + break; + + /* Array fields. */ + case 'other_social_urls': + if ( isset( $dirty[ $key ] ) ) { + $items = $dirty[ $key ]; + if ( ! is_array( $items ) ) { + $items = json_decode( $dirty[ $key ], true ); + } + + if ( is_array( $items ) ) { + foreach ( $items as $item_key => $item ) { + $validated_url = $this->validate_social_url( $item ); + + if ( $validated_url === false ) { + // Restore the previous URL values, if any. + $old_urls = ( isset( $old[ $key ] ) ) ? $old[ $key ] : []; + foreach ( $old_urls as $old_item_key => $old_url ) { + if ( $old_url !== '' ) { + $url = WPSEO_Utils::sanitize_url( $old_url ); + if ( $url !== '' ) { + $clean[ $key ][ $old_item_key ] = $url; + } + } + } + break; + } + + // The URL format is valid, let's sanitize it. + $url = WPSEO_Utils::sanitize_url( $validated_url ); + if ( $url !== '' ) { + $clean[ $key ][ $item_key ] = $url; + } + } + } + } + + break; + } + } + + return $clean; + } + + /** + * Validates a social URL. + * + * @param string $url The url to be validated. + * + * @return string|false The validated URL or false if the URL is not valid. + */ + public function validate_social_url( $url ) { + $validated_url = filter_var( WPSEO_Utils::sanitize_url( trim( $url ) ), FILTER_VALIDATE_URL ); + + return $validated_url; + } + + /** + * Validates a twitter id. + * + * @param string $twitter_id The twitter id to be validated. + * @param bool $strip_at_sign Whether or not to strip the `@` sign. + * + * @return string|false The validated twitter id or false if it is not valid. + */ + public function validate_twitter_id( $twitter_id, $strip_at_sign = true ) { + $twitter_id = ( $strip_at_sign ) ? sanitize_text_field( ltrim( $twitter_id, '@' ) ) : sanitize_text_field( $twitter_id ); + + /* + * From the Twitter documentation about twitter screen names: + * Typically a maximum of 15 characters long, but some historical accounts + * may exist with longer names. + * A username can only contain alphanumeric characters (letters A-Z, numbers 0-9) + * with the exception of underscores. + * + * @link https://support.twitter.com/articles/101299-why-can-t-i-register-certain-usernames + */ + if ( preg_match( '`^[A-Za-z0-9_]{1,25}$`', $twitter_id ) ) { + return $twitter_id; + } + + if ( preg_match( '`^http(?:s)?://(?:www\.)?(?:twitter|x)\.com/(?P[A-Za-z0-9_]{1,25})/?$`', $twitter_id, $matches ) ) { + return $matches['handle']; + } + + return false; + } + + /** + * Clean a given option value. + * + * @param array $option_value Old (not merged with defaults or filtered) option value to + * clean according to the rules for this option. + * @param string|null $current_version Optional. Version from which to upgrade, if not set, + * version specific upgrades will be disregarded. + * @param array|null $all_old_option_values Optional. Only used when importing old options to have + * access to the real old values, in contrast to the saved ones. + * + * @return array Cleaned option. + */ + protected function clean_option( $option_value, $current_version = null, $all_old_option_values = null ) { + + /* Move options from very old option to this one. */ + $old_option = null; + if ( isset( $all_old_option_values ) ) { + // Ok, we have an import. + if ( isset( $all_old_option_values['wpseo_indexation'] ) && is_array( $all_old_option_values['wpseo_indexation'] ) && $all_old_option_values['wpseo_indexation'] !== [] ) { + $old_option = $all_old_option_values['wpseo_indexation']; + } + } + else { + $old_option = get_option( 'wpseo_indexation' ); + } + + if ( is_array( $old_option ) && $old_option !== [] ) { + $move = [ + 'opengraph', + ]; + foreach ( $move as $key ) { + if ( isset( $old_option[ $key ] ) && ! isset( $option_value[ $key ] ) ) { + $option_value[ $key ] = $old_option[ $key ]; + } + } + unset( $move, $key ); + } + unset( $old_option ); + + return $option_value; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-titles.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-titles.php new file mode 100644 index 0000000..4b127c9 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-titles.php @@ -0,0 +1,1005 @@ +get_defaults(); + * + * {@internal Note: Some of the default values are added via the translate_defaults() method.}} + * + * @var string[] + */ + protected $defaults = [ + // Form fields. + 'forcerewritetitle' => false, + 'separator' => 'sc-dash', + 'title-home-wpseo' => '%%sitename%% %%page%% %%sep%% %%sitedesc%%', // Text field. + 'title-author-wpseo' => '', // Text field. + 'title-archive-wpseo' => '%%date%% %%page%% %%sep%% %%sitename%%', // Text field. + 'title-search-wpseo' => '', // Text field. + 'title-404-wpseo' => '', // Text field. + + 'social-title-author-wpseo' => '%%name%%', // Text field. + 'social-title-archive-wpseo' => '%%date%%', // Text field. + 'social-description-author-wpseo' => '', // Text area. + 'social-description-archive-wpseo' => '', // Text area. + 'social-image-url-author-wpseo' => '', // Hidden input field. + 'social-image-url-archive-wpseo' => '', // Hidden input field. + 'social-image-id-author-wpseo' => 0, // Hidden input field. + 'social-image-id-archive-wpseo' => 0, // Hidden input field. + + 'metadesc-home-wpseo' => '', // Text area. + 'metadesc-author-wpseo' => '', // Text area. + 'metadesc-archive-wpseo' => '', // Text area. + 'rssbefore' => '', // Text area. + 'rssafter' => '', // Text area. + + 'noindex-author-wpseo' => false, + 'noindex-author-noposts-wpseo' => true, + 'noindex-archive-wpseo' => true, + + 'disable-author' => false, + 'disable-date' => false, + 'disable-post_format' => false, + 'disable-attachment' => true, + + 'breadcrumbs-404crumb' => '', // Text field. + 'breadcrumbs-display-blog-page' => true, + 'breadcrumbs-boldlast' => false, + 'breadcrumbs-archiveprefix' => '', // Text field. + 'breadcrumbs-enable' => true, + 'breadcrumbs-home' => '', // Text field. + 'breadcrumbs-prefix' => '', // Text field. + 'breadcrumbs-searchprefix' => '', // Text field. + 'breadcrumbs-sep' => '»', // Text field. + + 'website_name' => '', + 'person_name' => '', + 'person_logo' => '', + 'person_logo_id' => 0, + 'alternate_website_name' => '', + 'company_logo' => '', + 'company_logo_id' => 0, + 'company_logo_meta' => false, + 'person_logo_meta' => false, + 'company_name' => '', + 'company_alternate_name' => '', + 'company_or_person' => 'company', + 'company_or_person_user_id' => false, + + 'stripcategorybase' => false, + + 'open_graph_frontpage_title' => '%%sitename%%', // Text field. + 'open_graph_frontpage_desc' => '', // Text field. + 'open_graph_frontpage_image' => '', // Text field. + 'open_graph_frontpage_image_id' => 0, + + 'publishing_principles_id' => 0, + 'ownership_funding_info_id' => 0, + 'actionable_feedback_policy_id' => 0, + 'corrections_policy_id' => 0, + 'ethics_policy_id' => 0, + 'diversity_policy_id' => 0, + 'diversity_staffing_report_id' => 0, + + 'org-description' => '', + 'org-email' => '', + 'org-phone' => '', + 'org-legal-name' => '', + 'org-founding-date' => '', + 'org-number-employees' => '', + + 'org-vat-id' => '', + 'org-tax-id' => '', + 'org-iso' => '', + 'org-duns' => '', + 'org-leicode' => '', + 'org-naics' => '', + + /* + * Uses enrich_defaults to add more along the lines of: + * - 'title-' . $pt->name => ''; // Text field. + * - 'metadesc-' . $pt->name => ''; // Text field. + * - 'noindex-' . $pt->name => false; + * - 'display-metabox-pt-' . $pt->name => false; + * + * - 'title-ptarchive-' . $pt->name => ''; // Text field. + * - 'metadesc-ptarchive-' . $pt->name => ''; // Text field. + * - 'bctitle-ptarchive-' . $pt->name => ''; // Text field. + * - 'noindex-ptarchive-' . $pt->name => false; + * + * - 'title-tax-' . $tax->name => '''; // Text field. + * - 'metadesc-tax-' . $tax->name => ''; // Text field. + * - 'noindex-tax-' . $tax->name => false; + * - 'display-metabox-tax-' . $tax->name => false; + * + * - 'schema-page-type-' . $pt->name => 'WebPage'; + * - 'schema-article-type-' . $pt->name => 'Article'; + */ + ]; + + /** + * Used for "caching" during pageload. + * + * @var string[]|null + */ + protected $enriched_defaults = null; + + /** + * Array of variable option name patterns for the option. + * + * @var string[] + */ + protected $variable_array_key_patterns = [ + 'title-', + 'metadesc-', + 'noindex-', + 'display-metabox-pt-', + 'bctitle-ptarchive-', + 'post_types-', + 'taxonomy-', + 'schema-page-type-', + 'schema-article-type-', + 'social-title-', + 'social-description-', + 'social-image-url-', + 'social-image-id-', + 'org-', + ]; + + /** + * Array of sub-options which should not be overloaded with multi-site defaults. + * + * @var string[] + */ + public $ms_exclude = [ + 'forcerewritetitle', + ]; + + /** + * Add the actions and filters for the option. + * + * @todo [JRF => testers] Check if the extra actions below would run into problems if an option + * is updated early on and if so, change the call to schedule these for a later action on add/update + * instead of running them straight away. + */ + protected function __construct() { + parent::__construct(); + add_action( 'update_option_' . $this->option_name, [ 'WPSEO_Utils', 'clear_cache' ] ); + add_action( 'init', [ $this, 'end_of_init' ], 999 ); + + add_action( 'registered_post_type', [ $this, 'invalidate_enrich_defaults_cache' ] ); + add_action( 'unregistered_post_type', [ $this, 'invalidate_enrich_defaults_cache' ] ); + add_action( 'registered_taxonomy', [ $this, 'invalidate_enrich_defaults_cache' ] ); + add_action( 'unregistered_taxonomy', [ $this, 'invalidate_enrich_defaults_cache' ] ); + + add_filter( 'admin_title', [ 'Yoast_Input_Validation', 'add_yoast_admin_document_title_errors' ] ); + } + + /** + * Make sure we can recognize the right action for the double cleaning. + * + * @return void + */ + public function end_of_init() { + do_action( 'wpseo_double_clean_titles' ); + } + + /** + * Get the singleton instance of this class. + * + * @return self + */ + public static function get_instance() { + if ( ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Get the available separator options. + * + * @return string[] + */ + public function get_separator_options() { + $separators = wp_list_pluck( self::get_separator_option_list(), 'option' ); + + /** + * Allow altering the array with separator options. + * + * @param array $separator_options Array with the separator options. + */ + $filtered_separators = apply_filters( 'wpseo_separator_options', $separators ); + + if ( is_array( $filtered_separators ) && $filtered_separators !== [] ) { + $separators = array_merge( $separators, $filtered_separators ); + } + + return $separators; + } + + /** + * Get the available separator options aria-labels. + * + * @return string[] Array with the separator options aria-labels. + */ + public function get_separator_options_for_display() { + $separators = $this->get_separator_options(); + $separator_list = self::get_separator_option_list(); + + $separator_options = []; + + foreach ( $separators as $key => $label ) { + $aria_label = ( $separator_list[ $key ]['label'] ?? '' ); + + $separator_options[ $key ] = [ + 'label' => $label, + 'aria_label' => $aria_label, + ]; + } + + return $separator_options; + } + + /** + * Translate strings used in the option defaults. + * + * @return void + */ + public function translate_defaults() { + /* translators: 1: Author name; 2: Site name. */ + $this->defaults['title-author-wpseo'] = sprintf( __( '%1$s, Author at %2$s', 'wordpress-seo' ), '%%name%%', '%%sitename%%' ) . ' %%page%% '; + /* translators: %s expands to the search phrase. */ + $this->defaults['title-search-wpseo'] = sprintf( __( 'You searched for %s', 'wordpress-seo' ), '%%searchphrase%%' ) . ' %%page%% %%sep%% %%sitename%%'; + $this->defaults['title-404-wpseo'] = __( 'Page not found', 'wordpress-seo' ) . ' %%sep%% %%sitename%%'; + /* translators: 1: link to post; 2: link to blog. */ + $this->defaults['rssafter'] = sprintf( __( 'The post %1$s appeared first on %2$s.', 'wordpress-seo' ), '%%POSTLINK%%', '%%BLOGLINK%%' ); + + $this->defaults['breadcrumbs-404crumb'] = __( 'Error 404: Page not found', 'wordpress-seo' ); + $this->defaults['breadcrumbs-archiveprefix'] = __( 'Archives for', 'wordpress-seo' ); + $this->defaults['breadcrumbs-home'] = __( 'Home', 'wordpress-seo' ); + $this->defaults['breadcrumbs-searchprefix'] = __( 'You searched for', 'wordpress-seo' ); + } + + /** + * Add dynamically created default options based on available post types and taxonomies. + * + * @return void + */ + public function enrich_defaults() { + $enriched_defaults = $this->enriched_defaults; + if ( $enriched_defaults !== null ) { + $this->defaults += $enriched_defaults; + return; + } + + $enriched_defaults = []; + + /* + * Retrieve all the relevant post type and taxonomy arrays. + * + * WPSEO_Post_Type::get_accessible_post_types() should *not* be used here. + * These are the defaults and can be prepared for any public post type. + */ + $post_type_objects = get_post_types( [ 'public' => true ], 'objects' ); + + if ( $post_type_objects ) { + /* translators: %s expands to the name of a post type (plural). */ + $archive = sprintf( __( '%s Archive', 'wordpress-seo' ), '%%pt_plural%%' ); + + foreach ( $post_type_objects as $pt ) { + $enriched_defaults[ 'title-' . $pt->name ] = '%%title%% %%page%% %%sep%% %%sitename%%'; // Text field. + $enriched_defaults[ 'metadesc-' . $pt->name ] = ''; // Text area. + $enriched_defaults[ 'noindex-' . $pt->name ] = false; + $enriched_defaults[ 'display-metabox-pt-' . $pt->name ] = true; + $enriched_defaults[ 'post_types-' . $pt->name . '-maintax' ] = 0; // Select box. + $enriched_defaults[ 'schema-page-type-' . $pt->name ] = 'WebPage'; + $enriched_defaults[ 'schema-article-type-' . $pt->name ] = ( $pt->name === 'post' ) ? 'Article' : 'None'; + + if ( $pt->name !== 'attachment' ) { + $enriched_defaults[ 'social-title-' . $pt->name ] = '%%title%%'; // Text field. + $enriched_defaults[ 'social-description-' . $pt->name ] = ''; // Text area. + $enriched_defaults[ 'social-image-url-' . $pt->name ] = ''; // Hidden input field. + $enriched_defaults[ 'social-image-id-' . $pt->name ] = 0; // Hidden input field. + } + + // Custom post types that have archives. + if ( ! $pt->_builtin && WPSEO_Post_Type::has_archive( $pt ) ) { + $enriched_defaults[ 'title-ptarchive-' . $pt->name ] = $archive . ' %%page%% %%sep%% %%sitename%%'; // Text field. + $enriched_defaults[ 'metadesc-ptarchive-' . $pt->name ] = ''; // Text area. + $enriched_defaults[ 'bctitle-ptarchive-' . $pt->name ] = ''; // Text field. + $enriched_defaults[ 'noindex-ptarchive-' . $pt->name ] = false; + $enriched_defaults[ 'social-title-ptarchive-' . $pt->name ] = $archive; // Text field. + $enriched_defaults[ 'social-description-ptarchive-' . $pt->name ] = ''; // Text area. + $enriched_defaults[ 'social-image-url-ptarchive-' . $pt->name ] = ''; // Hidden input field. + $enriched_defaults[ 'social-image-id-ptarchive-' . $pt->name ] = 0; // Hidden input field. + } + } + } + + $taxonomy_objects = get_taxonomies( [ 'public' => true ], 'object' ); + + if ( $taxonomy_objects ) { + /* translators: %s expands to the variable used for term title. */ + $archives = sprintf( __( '%s Archives', 'wordpress-seo' ), '%%term_title%%' ); + + foreach ( $taxonomy_objects as $tax ) { + $enriched_defaults[ 'title-tax-' . $tax->name ] = $archives . ' %%page%% %%sep%% %%sitename%%'; // Text field. + $enriched_defaults[ 'metadesc-tax-' . $tax->name ] = ''; // Text area. + $enriched_defaults[ 'display-metabox-tax-' . $tax->name ] = true; + + $enriched_defaults[ 'noindex-tax-' . $tax->name ] = ( $tax->name === 'post_format' ); + + $enriched_defaults[ 'social-title-tax-' . $tax->name ] = $archives; // Text field. + $enriched_defaults[ 'social-description-tax-' . $tax->name ] = ''; // Text area. + $enriched_defaults[ 'social-image-url-tax-' . $tax->name ] = ''; // Hidden input field. + $enriched_defaults[ 'social-image-id-tax-' . $tax->name ] = 0; // Hidden input field. + + $enriched_defaults[ 'taxonomy-' . $tax->name . '-ptparent' ] = 0; // Select box;. + } + } + + $this->enriched_defaults = $enriched_defaults; + $this->defaults += $enriched_defaults; + } + + /** + * Invalidates enrich_defaults() cache. + * + * Called from actions: + * - (un)registered_post_type + * - (un)registered_taxonomy + * + * @return void + */ + public function invalidate_enrich_defaults_cache() { + $this->enriched_defaults = null; + } + + /** + * Validate the option. + * + * @param string[] $dirty New value for the option. + * @param string[] $clean Clean value for the option, normally the defaults. + * @param string[] $old Old value of the option. + * + * @return string[] Validated clean value for the option to be saved to the database. + */ + protected function validate_option( $dirty, $clean, $old ) { + $allowed_post_types = $this->get_allowed_post_types(); + + foreach ( $clean as $key => $value ) { + $switch_key = $this->get_switch_key( $key ); + + switch ( $switch_key ) { + // Only ever set programmatically, so no reason for intense validation. + case 'company_logo_meta': + case 'person_logo_meta': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + break; + + /* Breadcrumbs text fields. */ + case 'breadcrumbs-404crumb': + case 'breadcrumbs-archiveprefix': + case 'breadcrumbs-home': + case 'breadcrumbs-prefix': + case 'breadcrumbs-searchprefix': + case 'breadcrumbs-sep': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = wp_kses_post( $dirty[ $key ] ); + } + break; + + /* + * Text fields. + */ + + /* + * Covers: + * 'title-home-wpseo', 'title-author-wpseo', 'title-archive-wpseo', // phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- This isn't commented out code. + * 'title-search-wpseo', 'title-404-wpseo' + * 'title-' . $pt->name + * 'title-ptarchive-' . $pt->name + * 'title-tax-' . $tax->name + * 'social-title-' . $pt->name + * 'social-title-ptarchive-' . $pt->name + * 'social-title-tax-' . $tax->name + * 'social-title-author-wpseo', 'social-title-archive-wpseo' + * 'open_graph_frontpage_title' + */ + case 'org-': + case 'website_name': + case 'alternate_website_name': + case 'title-': + case 'social-title-': + case 'open_graph_frontpage_title': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $dirty[ $key ] ); + } + break; + + case 'company_or_person': + if ( isset( $dirty[ $key ] ) ) { + if ( in_array( $dirty[ $key ], [ 'company', 'person' ], true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + else { + $defaults = $this->get_defaults(); + $clean[ $key ] = $defaults['company_or_person']; + } + } + break; + + /* + * Covers: + * 'company_logo', 'person_logo' // phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- This isn't commented out code. + */ + case 'company_logo': + case 'person_logo': + case 'open_graph_frontpage_image': + // When a logo changes, we need to ditch the caches we have for it. + unset( $clean[ $switch_key . '_id' ] ); + unset( $clean[ $switch_key . '_meta' ] ); + $this->validate_url( $key, $dirty, $old, $clean ); + break; + + /* + * Covers: + * 'social-image-url-' . $pt->name + * 'social-image-url-ptarchive-' . $pt->name + * 'social-image-url-tax-' . $tax->name + * 'social-image-url-author-wpseo', 'social-image-url-archive-wpseo' + */ + case 'social-image-url-': + $this->validate_url( $key, $dirty, $old, $clean ); + break; + + /* + * Covers: + * 'metadesc-home-wpseo', 'metadesc-author-wpseo', 'metadesc-archive-wpseo' + * 'metadesc-' . $pt->name + * 'metadesc-ptarchive-' . $pt->name + * 'metadesc-tax-' . $tax->name + * and also: + * 'bctitle-ptarchive-' . $pt->name + * 'social-description-' . $pt->name + * 'social-description-ptarchive-' . $pt->name + * 'social-description-tax-' . $tax->name + * 'social-description-author-wpseo', 'social-description-archive-wpseo' + * 'open_graph_frontpage_desc' + */ + case 'metadesc-': + case 'bctitle-ptarchive-': + case 'company_name': + case 'company_alternate_name': + case 'person_name': + case 'social-description-': + case 'open_graph_frontpage_desc': + if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) { + $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $dirty[ $key ] ); + } + break; + + /* + * Covers: 'rssbefore', 'rssafter' // phpcs:ignore Squiz.PHP.CommentedOutCode.Found -- This isn't commented out code. + */ + case 'rssbefore': + case 'rssafter': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = wp_kses_post( $dirty[ $key ] ); + } + break; + + /* 'post_types-' . $pt->name . '-maintax' fields. */ + case 'post_types-': + $post_type = str_replace( [ 'post_types-', '-maintax' ], '', $key ); + $taxonomies = get_object_taxonomies( $post_type, 'names' ); + + if ( isset( $dirty[ $key ] ) ) { + if ( $taxonomies !== [] && in_array( $dirty[ $key ], $taxonomies, true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + elseif ( (string) $dirty[ $key ] === '0' || (string) $dirty[ $key ] === '' ) { + $clean[ $key ] = 0; + } + elseif ( sanitize_title_with_dashes( $dirty[ $key ] ) === $dirty[ $key ] ) { + // Allow taxonomies which may not be registered yet. + $clean[ $key ] = $dirty[ $key ]; + } + else { + if ( isset( $old[ $key ] ) ) { + $clean[ $key ] = sanitize_title_with_dashes( $old[ $key ] ); + } + + /* + * @todo [JRF => whomever] Maybe change the untranslated $pt name in the + * error message to the nicely translated label ? + */ + add_settings_error( + $this->group_name, // Slug title of the setting. + $key, // Suffix-id for the error message box. + /* translators: %s expands to a post type. */ + sprintf( __( 'Please select a valid taxonomy for post type "%s"', 'wordpress-seo' ), $post_type ), // The error message. + 'error', // Message type. + ); + } + } + elseif ( isset( $old[ $key ] ) ) { + $clean[ $key ] = sanitize_title_with_dashes( $old[ $key ] ); + } + unset( $taxonomies, $post_type ); + break; + + /* 'taxonomy-' . $tax->name . '-ptparent' fields. */ + case 'taxonomy-': + if ( isset( $dirty[ $key ] ) ) { + if ( $allowed_post_types !== [] && in_array( $dirty[ $key ], $allowed_post_types, true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + elseif ( (string) $dirty[ $key ] === '0' || (string) $dirty[ $key ] === '' ) { + $clean[ $key ] = 0; + } + elseif ( sanitize_key( $dirty[ $key ] ) === $dirty[ $key ] ) { + // Allow taxonomies which may not be registered yet. + $clean[ $key ] = $dirty[ $key ]; + } + else { + if ( isset( $old[ $key ] ) ) { + $clean[ $key ] = sanitize_key( $old[ $key ] ); + } + + /* + * @todo [JRF =? whomever] Maybe change the untranslated $tax name in the + * error message to the nicely translated label ? + */ + $tax = str_replace( [ 'taxonomy-', '-ptparent' ], '', $key ); + add_settings_error( + $this->group_name, // Slug title of the setting. + '_' . $tax, // Suffix-ID for the error message box. + /* translators: %s expands to a taxonomy slug. */ + sprintf( __( 'Please select a valid post type for taxonomy "%s"', 'wordpress-seo' ), $tax ), // The error message. + 'error', // Message type. + ); + unset( $tax ); + } + } + elseif ( isset( $old[ $key ] ) ) { + $clean[ $key ] = sanitize_key( $old[ $key ] ); + } + break; + + /* + * Covers: + * 'company_or_person_user_id' + * 'company_logo_id', 'person_logo_id', 'open_graph_frontpage_image_id' + * 'social-image-id-' . $pt->name + * 'social-image-id-ptarchive-' . $pt->name + * 'social-image-id-tax-' . $tax->name + * 'social-image-id-author-wpseo', 'social-image-id-archive-wpseo' + */ + case 'company_or_person_user_id': + case 'company_logo_id': + case 'person_logo_id': + case 'social-image-id-': + case 'open_graph_frontpage_image_id': + case 'publishing_principles_id': + case 'ownership_funding_info_id': + case 'actionable_feedback_policy_id': + case 'corrections_policy_id': + case 'ethics_policy_id': + case 'diversity_policy_id': + case 'diversity_staffing_report_id': + if ( isset( $dirty[ $key ] ) ) { + $int = WPSEO_Utils::validate_int( $dirty[ $key ] ); + if ( $int !== false && $int >= 0 ) { + $clean[ $key ] = $int; + } + } + elseif ( isset( $old[ $key ] ) ) { + $int = WPSEO_Utils::validate_int( $old[ $key ] ); + if ( $int !== false && $int >= 0 ) { + $clean[ $key ] = $int; + } + } + break; + /* Separator field - Radio. */ + case 'separator': + if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) { + + // Get separator fields. + $separator_fields = $this->get_separator_options(); + + // Check if the given separator exists. + if ( isset( $separator_fields[ $dirty[ $key ] ] ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + } + break; + + case 'schema-page-type-': + if ( isset( $dirty[ $key ] ) && is_string( $dirty[ $key ] ) ) { + if ( array_key_exists( $dirty[ $key ], Schema_Types::PAGE_TYPES ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + else { + $defaults = $this->get_defaults(); + $post_type = str_replace( $switch_key, '', $key ); + $clean[ $key ] = $defaults[ $switch_key . $post_type ]; + } + } + break; + case 'schema-article-type-': + if ( isset( $dirty[ $key ] ) && is_string( $dirty[ $key ] ) ) { + /** + * Filter: 'wpseo_schema_article_types' - Allow developers to filter the available article types. + * + * Make sure when you filter this to also filter `wpseo_schema_article_types_labels`. + * + * @param array $schema_article_types The available schema article types. + */ + if ( array_key_exists( $dirty[ $key ], apply_filters( 'wpseo_schema_article_types', Schema_Types::ARTICLE_TYPES ) ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + else { + $defaults = $this->get_defaults(); + $post_type = str_replace( $switch_key, '', $key ); + $clean[ $key ] = $defaults[ $switch_key . $post_type ]; + } + } + break; + + /* + * Boolean fields. + */ + + /* + * Covers: + * 'noindex-author-wpseo', 'noindex-author-noposts-wpseo', 'noindex-archive-wpseo' + * 'noindex-' . $pt->name + * 'noindex-ptarchive-' . $pt->name + * 'noindex-tax-' . $tax->name + * 'forcerewritetitle': + * 'noodp': + * 'noydir': + * 'disable-author': + * 'disable-date': + * 'disable-post_format'; + * 'noindex-' + * 'display-metabox-pt-' + * 'display-metabox-pt-'. $pt->name + * 'display-metabox-tax-' + * 'display-metabox-tax-' . $tax->name + * 'breadcrumbs-display-blog-page' + * 'breadcrumbs-boldlast' + * 'breadcrumbs-enable' + * 'stripcategorybase' + */ + default: + $clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : false ); + break; + } + } + + return $clean; + } + + /** + * Retrieve a list of the allowed post types as breadcrumb parent for a taxonomy. + * Helper method for validation. + * + * {@internal Don't make static as new types may still be registered.}} + * + * @return string[] + */ + protected function get_allowed_post_types() { + $allowed_post_types = []; + + /* + * WPSEO_Post_Type::get_accessible_post_types() should *not* be used here. + */ + $post_types = get_post_types( [ 'public' => true ], 'objects' ); + + if ( get_option( 'show_on_front' ) === 'page' && get_option( 'page_for_posts' ) > 0 ) { + $allowed_post_types[] = 'post'; + } + + if ( is_array( $post_types ) && $post_types !== [] ) { + foreach ( $post_types as $type ) { + if ( WPSEO_Post_Type::has_archive( $type ) ) { + $allowed_post_types[] = $type->name; + } + } + } + + return $allowed_post_types; + } + + /** + * Clean a given option value. + * + * @param string[] $option_value Old (not merged with defaults or filtered) option value to clean according to the rules for this option. + * @param string[]|null $current_version Optional. Version from which to upgrade, if not set, version specific upgrades will be disregarded. + * @param string[]|null $all_old_option_values Optional. Only used when importing old options to have access to the real old values, in contrast to the saved ones. + * + * @return string[] Cleaned option. + */ + protected function clean_option( $option_value, $current_version = null, $all_old_option_values = null ) { + static $original = null; + + // Double-run this function to ensure renaming of the taxonomy options will work. + if ( ! isset( $original ) + && has_action( 'wpseo_double_clean_titles', [ $this, 'clean' ] ) === false + ) { + add_action( 'wpseo_double_clean_titles', [ $this, 'clean' ] ); + $original = $option_value; + } + + /* + * Move options from very old option to this one. + * + * {@internal Don't rename to the 'current' names straight away as that would prevent + * the rename/unset combi below from working.}} + * + * @todo [JRF] Maybe figure out a smarter way to deal with this. + */ + $old_option = null; + if ( isset( $all_old_option_values ) ) { + // Ok, we have an import. + if ( isset( $all_old_option_values['wpseo_indexation'] ) && is_array( $all_old_option_values['wpseo_indexation'] ) && $all_old_option_values['wpseo_indexation'] !== [] ) { + $old_option = $all_old_option_values['wpseo_indexation']; + } + } + else { + $old_option = get_option( 'wpseo_indexation' ); + } + if ( is_array( $old_option ) && $old_option !== [] ) { + $move = [ + 'noindexauthor' => 'noindex-author', + 'disableauthor' => 'disable-author', + 'noindexdate' => 'noindex-archive', + 'noindexcat' => 'noindex-category', + 'noindextag' => 'noindex-post_tag', + 'noindexpostformat' => 'noindex-post_format', + ]; + foreach ( $move as $old => $new ) { + if ( isset( $old_option[ $old ] ) && ! isset( $option_value[ $new ] ) ) { + $option_value[ $new ] = $old_option[ $old ]; + } + } + unset( $move, $old, $new ); + } + unset( $old_option ); + + // Fix wrongness created by buggy version 1.2.2. + if ( isset( $option_value['title-home'] ) && $option_value['title-home'] === '%%sitename%% - %%sitedesc%% - 12345' ) { + $option_value['title-home-wpseo'] = '%%sitename%% - %%sitedesc%%'; + } + + /* + * Renaming these options to avoid ever overwritting these if a (bloody stupid) user / + * programmer would use any of the following as a custom post type or custom taxonomy: + * 'home', 'author', 'archive', 'search', '404', 'subpages'. + * + * Similarly, renaming the tax options to avoid a custom post type and a taxonomy + * with the same name occupying the same option. + */ + $rename = [ + 'title-home' => 'title-home-wpseo', + 'title-author' => 'title-author-wpseo', + 'title-archive' => 'title-archive-wpseo', + 'title-search' => 'title-search-wpseo', + 'title-404' => 'title-404-wpseo', + 'metadesc-home' => 'metadesc-home-wpseo', + 'metadesc-author' => 'metadesc-author-wpseo', + 'metadesc-archive' => 'metadesc-archive-wpseo', + 'noindex-author' => 'noindex-author-wpseo', + 'noindex-archive' => 'noindex-archive-wpseo', + ]; + foreach ( $rename as $old => $new ) { + if ( isset( $option_value[ $old ] ) && ! isset( $option_value[ $new ] ) ) { + $option_value[ $new ] = $option_value[ $old ]; + unset( $option_value[ $old ] ); + } + } + unset( $rename, $old, $new ); + + /* + * {@internal This clean-up action can only be done effectively once the taxonomies + * and post_types have been registered, i.e. at the end of the init action.}} + */ + if ( ( isset( $original ) && current_filter() === 'wpseo_double_clean_titles' ) || did_action( 'wpseo_double_clean_titles' ) > 0 ) { + $rename = [ + 'title-' => 'title-tax-', + 'metadesc-' => 'metadesc-tax-', + 'noindex-' => 'noindex-tax-', + 'tax-hideeditbox-' => 'hideeditbox-tax-', + ]; + + $taxonomy_names = get_taxonomies( [ 'public' => true ], 'names' ); + $post_type_names = get_post_types( [ 'public' => true ], 'names' ); + $defaults = $this->get_defaults(); + if ( $taxonomy_names !== [] ) { + foreach ( $taxonomy_names as $tax ) { + foreach ( $rename as $old_prefix => $new_prefix ) { + if ( + ( isset( $original[ $old_prefix . $tax ] ) && ! isset( $original[ $new_prefix . $tax ] ) ) + && ( ! isset( $option_value[ $new_prefix . $tax ] ) + || ( isset( $option_value[ $new_prefix . $tax ] ) + && $option_value[ $new_prefix . $tax ] === $defaults[ $new_prefix . $tax ] ) ) + ) { + $option_value[ $new_prefix . $tax ] = $original[ $old_prefix . $tax ]; + + /* + * Check if there is a cpt with the same name as the tax, + * if so, we should make sure that the old setting hasn't been removed. + */ + if ( ! isset( $post_type_names[ $tax ] ) && isset( $option_value[ $old_prefix . $tax ] ) ) { + unset( $option_value[ $old_prefix . $tax ] ); + } + elseif ( isset( $post_type_names[ $tax ] ) && ! isset( $option_value[ $old_prefix . $tax ] ) ) { + $option_value[ $old_prefix . $tax ] = $original[ $old_prefix . $tax ]; + } + + if ( $old_prefix === 'tax-hideeditbox-' ) { + unset( $option_value[ $old_prefix . $tax ] ); + } + } + } + } + } + unset( $rename, $taxonomy_names, $post_type_names, $defaults, $tax, $old_prefix, $new_prefix ); + } + + return $option_value; + } + + /** + * Make sure that any set option values relating to post_types and/or taxonomies are retained, + * even when that post_type or taxonomy may not yet have been registered. + * + * {@internal Overrule the abstract class version of this to make sure one extra renamed + * variable key does not get removed. IMPORTANT: keep this method in line with + * the parent on which it is based!}} + * + * @param string[] $dirty Original option as retrieved from the database. + * @param string[] $clean Filtered option where any options which shouldn't be in our option + * have already been removed and any options which weren't set + * have been set to their defaults. + * + * @return string[] + */ + protected function retain_variable_keys( $dirty, $clean ) { + if ( ( is_array( $this->variable_array_key_patterns ) && $this->variable_array_key_patterns !== [] ) && ( is_array( $dirty ) && $dirty !== [] ) ) { + + // Add the extra pattern. + $patterns = $this->variable_array_key_patterns; + $patterns[] = 'tax-hideeditbox-'; + + /** + * Allow altering the array with variable array key patterns. + * + * @param array $patterns Array with the variable array key patterns. + */ + $patterns = apply_filters( 'wpseo_option_titles_variable_array_key_patterns', $patterns ); + + foreach ( $dirty as $key => $value ) { + + // Do nothing if already in filtered option array. + if ( isset( $clean[ $key ] ) ) { + continue; + } + + foreach ( $patterns as $pattern ) { + if ( strpos( $key, $pattern ) === 0 ) { + $clean[ $key ] = $value; + break; + } + } + } + } + + return $clean; + } + + /** + * Retrieves a list of separator options. + * + * @return string[] An array of the separator options. + */ + protected static function get_separator_option_list() { + $separators = [ + 'sc-dash' => [ + 'option' => '-', + 'label' => __( 'Dash', 'wordpress-seo' ), + ], + 'sc-ndash' => [ + 'option' => '–', + 'label' => __( 'En dash', 'wordpress-seo' ), + ], + 'sc-mdash' => [ + 'option' => '—', + 'label' => __( 'Em dash', 'wordpress-seo' ), + ], + 'sc-colon' => [ + 'option' => ':', + 'label' => __( 'Colon', 'wordpress-seo' ), + ], + 'sc-middot' => [ + 'option' => '·', + 'label' => __( 'Middle dot', 'wordpress-seo' ), + ], + 'sc-bull' => [ + 'option' => '•', + 'label' => __( 'Bullet', 'wordpress-seo' ), + ], + 'sc-star' => [ + 'option' => '*', + 'label' => __( 'Asterisk', 'wordpress-seo' ), + ], + 'sc-smstar' => [ + 'option' => '⋆', + 'label' => __( 'Low asterisk', 'wordpress-seo' ), + ], + 'sc-pipe' => [ + 'option' => '|', + 'label' => __( 'Vertical bar', 'wordpress-seo' ), + ], + 'sc-tilde' => [ + 'option' => '~', + 'label' => __( 'Small tilde', 'wordpress-seo' ), + ], + 'sc-laquo' => [ + 'option' => '«', + 'label' => __( 'Left angle quotation mark', 'wordpress-seo' ), + ], + 'sc-raquo' => [ + 'option' => '»', + 'label' => __( 'Right angle quotation mark', 'wordpress-seo' ), + ], + 'sc-lt' => [ + 'option' => '>', + 'label' => __( 'Less than sign', 'wordpress-seo' ), + ], + 'sc-gt' => [ + 'option' => '<', + 'label' => __( 'Greater than sign', 'wordpress-seo' ), + ], + ]; + + /** + * Allows altering the separator options array. + * + * @param array $separators Array with the separator options. + */ + $separator_list = apply_filters( 'wpseo_separator_option_list', $separators ); + + if ( ! is_array( $separator_list ) ) { + return $separators; + } + + return $separator_list; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-tracking-only.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-tracking-only.php new file mode 100644 index 0000000..83ff0a8 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-tracking-only.php @@ -0,0 +1,88 @@ +get_defaults(); + * + * @var array> + */ + protected $defaults = [ + 'task_list_first_opened_on' => '', + 'task_first_actioned_on' => '', + 'frontend_inspector_first_actioned_on' => '', + ]; + + /** + * Get the singleton instance of this class. + * + * @return object + */ + public static function get_instance() { + if ( ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * All concrete classes must contain a validate_option() method which validates all + * values within the option. + * + * @phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Needed because the function is called with the parameter $old. + * + * @param array $dirty New value for the option. + * @param array $clean Clean value for the option, normally the defaults. + * @param array $old Old value of the option. + * + * @return array The clean option with the saved value. + */ + protected function validate_option( $dirty, $clean, $old ) { + + foreach ( $clean as $key => $value ) { + switch ( $key ) { + case 'task_list_first_opened_on': + case 'task_first_actioned_on': + case 'frontend_inspector_first_actioned_on': + // These should be set only once and never changed again (unless completely reset to default). + + if ( isset( $dirty[ $key ] ) && $old[ $key ] === $this->get_defaults()[ $key ] ) { + // Allow setting it for the first time. + $clean[ $key ] = sanitize_text_field( $dirty[ $key ] ); + } + elseif ( isset( $dirty[ $key ] ) && $dirty[ $key ] === $this->get_defaults()[ $key ] ) { + // Allow resetting to default. + $clean[ $key ] = $dirty[ $key ]; + } + else { + // Otherwise keep old value. + $clean[ $key ] = $old[ $key ]; + } + + break; + } + } + + return $clean; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-wpseo.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-wpseo.php new file mode 100644 index 0000000..3a503cd --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option-wpseo.php @@ -0,0 +1,701 @@ +get_defaults();}} + * + * @var array + */ + protected $defaults = [ + // Non-form fields, set via (ajax) function. + 'tracking' => null, + 'toggled_tracking' => false, + 'license_server_version' => false, + 'ms_defaults_set' => false, + 'ignore_search_engines_discouraged_notice' => false, + 'indexing_first_time' => true, + 'indexing_started' => null, + 'indexing_reason' => '', + 'indexables_indexing_completed' => false, + 'index_now_key' => '', + // Non-form field, should only be set via validation routine. + 'version' => '', // Leave default as empty to ensure activation/upgrade works. + 'previous_version' => '', + // Form fields. + 'disableadvanced_meta' => true, + 'enable_headless_rest_endpoints' => true, + 'ryte_indexability' => false, + 'baiduverify' => '', // Text field. + 'googleverify' => '', // Text field. + 'msverify' => '', // Text field. + 'yandexverify' => '', + 'ahrefsverify' => '', + 'site_type' => '', // List of options. + 'has_multiple_authors' => '', + 'environment_type' => '', + 'content_analysis_active' => true, + 'keyword_analysis_active' => true, + 'inclusive_language_analysis_active' => false, + 'enable_admin_bar_menu' => true, + 'enable_cornerstone_content' => true, + 'enable_xml_sitemap' => true, + 'enable_text_link_counter' => true, + 'enable_index_now' => true, + 'enable_ai_generator' => true, + 'ai_enabled_pre_default' => false, + 'show_onboarding_notice' => false, + 'first_activated_on' => false, + 'myyoast-oauth' => [ + 'config' => [ + 'clientId' => null, + 'secret' => null, + ], + 'access_tokens' => [], + ], + 'semrush_integration_active' => true, + 'semrush_tokens' => [], + 'semrush_country_code' => 'us', + 'permalink_structure' => '', + 'home_url' => '', + 'dynamic_permalinks' => false, + 'category_base_url' => '', + 'tag_base_url' => '', + 'custom_taxonomy_slugs' => [], + 'enable_enhanced_slack_sharing' => true, + 'enable_metabox_insights' => true, + 'enable_link_suggestions' => true, + 'algolia_integration_active' => false, + 'import_cursors' => [], + 'workouts_data' => [ 'configuration' => [ 'finishedSteps' => [] ] ], + 'configuration_finished_steps' => [], + 'dismiss_configuration_workout_notice' => false, + 'dismiss_premium_deactivated_notice' => false, + 'importing_completed' => [], + 'wincher_integration_active' => true, + 'wincher_tokens' => [], + 'wincher_automatically_add_keyphrases' => false, + 'wincher_website_id' => '', + 'first_time_install' => false, + 'should_redirect_after_install_free' => false, + 'activation_redirect_timestamp_free' => 0, + 'remove_feed_global' => false, + 'remove_feed_global_comments' => false, + 'remove_feed_post_comments' => false, + 'remove_feed_authors' => false, + 'remove_feed_categories' => false, + 'remove_feed_tags' => false, + 'remove_feed_custom_taxonomies' => false, + 'remove_feed_post_types' => false, + 'remove_feed_search' => false, + 'remove_atom_rdf_feeds' => false, + 'remove_shortlinks' => false, + 'remove_rest_api_links' => false, + 'remove_rsd_wlw_links' => false, + 'remove_oembed_links' => false, + 'remove_generator' => false, + 'remove_emoji_scripts' => false, + 'remove_powered_by_header' => false, + 'remove_pingback_header' => false, + 'clean_campaign_tracking_urls' => false, + 'clean_permalinks' => false, + 'clean_permalinks_extra_variables' => '', + 'search_cleanup' => false, + 'search_cleanup_emoji' => false, + 'search_cleanup_patterns' => false, + 'search_character_limit' => 50, + 'deny_search_crawling' => false, + 'deny_wp_json_crawling' => false, + 'deny_adsbot_crawling' => false, + 'deny_ccbot_crawling' => false, + 'deny_google_extended_crawling' => false, + 'deny_gptbot_crawling' => false, + 'redirect_search_pretty_urls' => false, + 'least_readability_ignore_list' => [], + 'least_seo_score_ignore_list' => [], + 'most_linked_ignore_list' => [], + 'least_linked_ignore_list' => [], + 'indexables_page_reading_list' => [ false, false, false, false, false ], + 'indexables_overview_state' => 'dashboard-not-visited', + 'last_known_public_post_types' => [], + 'last_known_public_taxonomies' => [], + 'last_known_no_unindexed' => [], + 'new_post_types' => [], + 'new_taxonomies' => [], + 'show_new_content_type_notification' => false, + 'site_kit_configuration_permanently_dismissed' => false, + 'site_kit_connected' => false, + 'site_kit_tracking_setup_widget_loaded' => 'no', + 'site_kit_tracking_first_interaction_stage' => '', + 'site_kit_tracking_last_interaction_stage' => '', + 'site_kit_tracking_setup_widget_temporarily_dismissed' => 'no', + 'site_kit_tracking_setup_widget_permanently_dismissed' => 'no', + 'google_site_kit_feature_enabled' => false, // No longer used. + 'ai_free_sparks_started_on' => null, + 'enable_llms_txt' => false, + 'last_updated_on' => false, + 'default_seo_title' => [], + 'default_seo_meta_desc' => [], + 'first_activated_by' => 0, + 'enable_schema_aggregation_endpoint' => false, + 'schema_aggregation_endpoint_enabled_on' => null, + 'enable_task_list' => true, + 'enable_schema' => true, + ]; + + /** + * Sub-options which should not be overloaded with multi-site defaults. + * + * @var array + */ + public $ms_exclude = [ + 'ignore_search_engines_discouraged_notice', + /* Privacy. */ + 'baiduverify', + 'googleverify', + 'msverify', + 'yandexverify', + 'ahrefsverify', + ]; + + /** + * Possible values for the site_type option. + * + * @var array + */ + protected $site_types = [ + '', + 'blog', + 'shop', + 'news', + 'smallBusiness', + 'corporateOther', + 'personalOther', + ]; + + /** + * Possible environment types. + * + * @var array + */ + protected $environment_types = [ + '', + 'local', + 'production', + 'staging', + 'development', + ]; + + /** + * Possible has_multiple_authors options. + * + * @var array + */ + protected $has_multiple_authors_options = [ + '', + true, + false, + ]; + + /** + * Name for an option higher in the hierarchy to override setting access. + * + * @var string + */ + protected $override_option_name = 'wpseo_ms'; + + /** + * Add the actions and filters for the option. + * + * @todo [JRF => testers] Check if the extra actions below would run into problems if an option + * is updated early on and if so, change the call to schedule these for a later action on add/update + * instead of running them straight away. + */ + protected function __construct() { + parent::__construct(); + + /** + * Filter: 'wpseo_enable_tracking' - Enables the data tracking of Yoast SEO Premium. + * + * @param string|false $is_enabled The enabled state. Default is false. + */ + $this->defaults['tracking'] = apply_filters( 'wpseo_enable_tracking', false ); + + /* Clear the cache on update/add. */ + add_action( 'add_option_' . $this->option_name, [ 'WPSEO_Utils', 'clear_cache' ] ); + add_action( 'update_option_' . $this->option_name, [ 'WPSEO_Utils', 'clear_cache' ] ); + + add_filter( 'admin_title', [ 'Yoast_Input_Validation', 'add_yoast_admin_document_title_errors' ] ); + + /** + * Filter the `wpseo` option defaults. + * + * @param array $defaults Array the defaults for the `wpseo` option attributes. + */ + $this->defaults = apply_filters( 'wpseo_option_wpseo_defaults', $this->defaults ); + } + + /** + * Get the singleton instance of this class. + * + * @return object + */ + public static function get_instance() { + if ( ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Add filters to make sure that the option is merged with its defaults before being returned. + * + * @return void + */ + public function add_option_filters() { + parent::add_option_filters(); + + list( $hookname, $callback, $priority ) = $this->get_verify_features_option_filter_hook(); + + if ( has_filter( $hookname, $callback ) === false ) { + add_filter( $hookname, $callback, $priority ); + } + } + + /** + * Remove the option filters. + * Called from the clean_up methods to make sure we retrieve the original old option. + * + * @return void + */ + public function remove_option_filters() { + parent::remove_option_filters(); + + list( $hookname, $callback, $priority ) = $this->get_verify_features_option_filter_hook(); + + remove_filter( $hookname, $callback, $priority ); + } + + /** + * Add filters to make sure that the option default is returned if the option is not set. + * + * @return void + */ + public function add_default_filters() { + parent::add_default_filters(); + + list( $hookname, $callback, $priority ) = $this->get_verify_features_default_option_filter_hook(); + + if ( has_filter( $hookname, $callback ) === false ) { + add_filter( $hookname, $callback, $priority ); + } + } + + /** + * Remove the default filters. + * Called from the validate() method to prevent failure to add new options. + * + * @return void + */ + public function remove_default_filters() { + parent::remove_default_filters(); + + list( $hookname, $callback, $priority ) = $this->get_verify_features_default_option_filter_hook(); + + remove_filter( $hookname, $callback, $priority ); + } + + /** + * Validate the option. + * + * @param array $dirty New value for the option. + * @param array $clean Clean value for the option, normally the defaults. + * @param array $old Old value of the option. + * + * @return array Validated clean value for the option to be saved to the database. + */ + protected function validate_option( $dirty, $clean, $old ) { + + foreach ( $clean as $key => $value ) { + switch ( $key ) { + case 'version': + $clean[ $key ] = WPSEO_VERSION; + break; + case 'previous_version': + case 'semrush_country_code': + case 'license_server_version': + case 'home_url': + case 'index_now_key': + case 'wincher_website_id': + case 'clean_permalinks_extra_variables': + case 'indexables_overview_state': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + break; + case 'indexing_reason': + case 'site_kit_tracking_setup_widget_loaded': + case 'site_kit_tracking_first_interaction_stage': + case 'site_kit_tracking_last_interaction_stage': + case 'site_kit_tracking_setup_widget_temporarily_dismissed': + case 'site_kit_tracking_setup_widget_permanently_dismissed': + case 'ai_free_sparks_started_on': + case 'schema_aggregation_endpoint_enabled_on': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = sanitize_text_field( $dirty[ $key ] ); + } + break; + + /* Verification strings. */ + case 'baiduverify': + case 'googleverify': + case 'msverify': + case 'yandexverify': + case 'ahrefsverify': + $this->validate_verification_string( $key, $dirty, $old, $clean ); + break; + + /* + * Boolean dismiss warnings - not fields - may not be in form + * (and don't need to be either as long as the default is false). + */ + case 'ignore_search_engines_discouraged_notice': + case 'ms_defaults_set': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = WPSEO_Utils::validate_bool( $dirty[ $key ] ); + } + elseif ( isset( $old[ $key ] ) ) { + $clean[ $key ] = WPSEO_Utils::validate_bool( $old[ $key ] ); + } + break; + + case 'site_type': + $clean[ $key ] = $old[ $key ]; + if ( isset( $dirty[ $key ] ) && in_array( $dirty[ $key ], $this->site_types, true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + break; + + case 'environment_type': + $clean[ $key ] = $old[ $key ]; + if ( isset( $dirty[ $key ] ) && in_array( $dirty[ $key ], $this->environment_types, true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + break; + + case 'has_multiple_authors': + $clean[ $key ] = $old[ $key ]; + if ( isset( $dirty[ $key ] ) && in_array( $dirty[ $key ], $this->has_multiple_authors_options, true ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + + break; + + case 'first_activated_on': + case 'indexing_started': + case 'activation_redirect_timestamp_free': + case 'last_updated_on': + $clean[ $key ] = false; + if ( isset( $dirty[ $key ] ) ) { + if ( $dirty[ $key ] === false || WPSEO_Utils::validate_int( $dirty[ $key ] ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + } + break; + + case 'first_activated_by': + // A slight change from the other integer fields, as we want to allow '0' here, but don't want to have much impact elsewhere. + $clean[ $key ] = false; + if ( isset( $dirty[ $key ] ) ) { + if ( $dirty[ $key ] === false || WPSEO_Utils::validate_int( $dirty[ $key ] ) !== false ) { + $clean[ $key ] = $dirty[ $key ]; + } + } + break; + + case 'tracking': + $clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : null ); + break; + + case 'myyoast_oauth': + case 'semrush_tokens': + case 'custom_taxonomy_slugs': + case 'wincher_tokens': + case 'workouts_data': + case 'configuration_finished_steps': + case 'least_readability_ignore_list': + case 'least_seo_score_ignore_list': + case 'most_linked_ignore_list': + case 'least_linked_ignore_list': + case 'indexables_page_reading_list': + case 'last_known_public_post_types': + case 'last_known_public_taxonomies': + case 'new_post_types': + case 'new_taxonomies': + case 'default_seo_title': + case 'default_seo_meta_desc': + $clean[ $key ] = $old[ $key ]; + + if ( isset( $dirty[ $key ] ) ) { + $items = $dirty[ $key ]; + if ( ! is_array( $items ) ) { + $items = json_decode( $dirty[ $key ], true ); + } + + if ( is_array( $items ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + } + + break; + + case 'permalink_structure': + case 'category_base_url': + case 'tag_base_url': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = sanitize_option( $key, $dirty[ $key ] ); + } + break; + + case 'search_character_limit': + if ( isset( $dirty[ $key ] ) ) { + $clean[ $key ] = (int) $dirty[ $key ]; + } + break; + + case 'import_cursors': + case 'importing_completed': + if ( isset( $dirty[ $key ] ) && is_array( $dirty[ $key ] ) ) { + $clean[ $key ] = $dirty[ $key ]; + } + break; + + case 'last_known_no_unindexed': + $clean[ $key ] = $old[ $key ]; + + if ( isset( $dirty[ $key ] ) ) { + $items = $dirty[ $key ]; + + if ( is_array( $items ) ) { + foreach ( $items as $item_key => $item ) { + if ( ! is_string( $item_key ) || ! is_numeric( $item ) ) { + unset( $items[ $item_key ] ); + } + } + $clean[ $key ] = $items; + } + } + + break; + + /* + * Boolean (checkbox) fields. + * + * Covers: + * 'disableadvanced_meta' + * 'enable_headless_rest_endpoints' + * 'yoast_tracking' + * 'dynamic_permalinks' + * 'indexing_first_time' + * 'first_time_install' + * 'remove_feed_global' + * 'remove_feed_global_comments' + * 'remove_feed_post_comments' + * 'remove_feed_authors' + * 'remove_feed_categories' + * 'remove_feed_tags' + * 'remove_feed_custom_taxonomies' + * 'remove_feed_post_types' + * 'remove_feed_search' + * 'remove_atom_rdf_feeds' + * 'remove_shortlinks' + * 'remove_rest_api_links' + * 'remove_rsd_wlw_links' + * 'remove_oembed_links' + * 'remove_generator' + * 'remove_emoji_scripts' + * 'remove_powered_by_header' + * 'remove_pingback_header' + * 'clean_campaign_tracking_urls' + * 'clean_permalinks' + * 'clean_permalinks_extra_variables' + * 'search_cleanup' + * 'search_cleanup_emoji' + * 'search_cleanup_patterns' + * 'deny_wp_json_crawling' + * 'deny_adsbot_crawling' + * 'deny_ccbot_crawling' + * 'deny_google_extended_crawling' + * 'deny_gptbot_crawling' + * 'redirect_search_pretty_urls' + * 'should_redirect_after_install_free' + * 'show_new_content_type_notification' + * 'site_kit_configuration_permanently_dismissed', + * 'site_kit_connected', + * 'google_site_kit_feature_enabled', + * 'enable_llms_txt', + * 'enable_schema_aggregation_endpoint' + * 'enable_task_list', + * 'enable_schema', + * and most of the feature variables. + */ + default: + $clean[ $key ] = ( isset( $dirty[ $key ] ) ? WPSEO_Utils::validate_bool( $dirty[ $key ] ) : false ); + break; + } + } + + return $clean; + } + + /** + * Verifies that the feature variables are turned off if the network is configured so. + * + * @param mixed $options Value of the option to be returned. Typically an array. + * + * @return mixed Filtered $options value. + */ + public function verify_features_against_network( $options = [] ) { + if ( ! is_array( $options ) || empty( $options ) ) { + return $options; + } + + // For the feature variables, set their values to off in case they are disabled. + $feature_vars = [ + 'disableadvanced_meta' => false, + 'ryte_indexability' => false, + 'content_analysis_active' => false, + 'keyword_analysis_active' => false, + 'inclusive_language_analysis_active' => false, + 'enable_admin_bar_menu' => false, + 'enable_cornerstone_content' => false, + 'enable_xml_sitemap' => false, + 'enable_text_link_counter' => false, + 'enable_metabox_insights' => false, + 'enable_link_suggestions' => false, + 'enable_headless_rest_endpoints' => false, + 'tracking' => false, + 'enable_enhanced_slack_sharing' => false, + 'semrush_integration_active' => false, + 'wincher_integration_active' => false, + 'remove_feed_global' => false, + 'remove_feed_global_comments' => false, + 'remove_feed_post_comments' => false, + 'enable_index_now' => false, + 'enable_ai_generator' => false, + 'remove_feed_authors' => false, + 'remove_feed_categories' => false, + 'remove_feed_tags' => false, + 'remove_feed_custom_taxonomies' => false, + 'remove_feed_post_types' => false, + 'remove_feed_search' => false, + 'remove_atom_rdf_feeds' => false, + 'remove_shortlinks' => false, + 'remove_rest_api_links' => false, + 'remove_rsd_wlw_links' => false, + 'remove_oembed_links' => false, + 'remove_generator' => false, + 'remove_emoji_scripts' => false, + 'remove_powered_by_header' => false, + 'remove_pingback_header' => false, + 'clean_campaign_tracking_urls' => false, + 'clean_permalinks' => false, + 'search_cleanup' => false, + 'search_cleanup_emoji' => false, + 'search_cleanup_patterns' => false, + 'redirect_search_pretty_urls' => false, + 'algolia_integration_active' => false, + 'google_site_kit_feature_enabled' => false, + 'enable_llms_txt' => false, + 'enable_task_list' => false, + 'enable_schema_aggregation_endpoint' => false, + 'enable_schema' => false, + ]; + + // We can reuse this logic from the base class with the above defaults to parse with the correct feature values. + $options = $this->prevent_disabled_options_update( $options, $feature_vars ); + + return $options; + } + + /** + * Gets the filter hook name and callback for adjusting the retrieved option value + * against the network-allowed features. + * + * @return array Array where the first item is the hook name, the second is the hook callback, + * and the third is the hook priority. + */ + protected function get_verify_features_option_filter_hook() { + return [ + "option_{$this->option_name}", + [ $this, 'verify_features_against_network' ], + 11, + ]; + } + + /** + * Gets the filter hook name and callback for adjusting the default option value against the network-allowed features. + * + * @return array Array where the first item is the hook name, the second is the hook callback, + * and the third is the hook priority. + */ + protected function get_verify_features_default_option_filter_hook() { + return [ + "default_option_{$this->option_name}", + [ $this, 'verify_features_against_network' ], + 11, + ]; + } + + /** + * Clean a given option value. + * + * @param array $option_value Old (not merged with defaults or filtered) option value to + * clean according to the rules for this option. + * @param string|null $current_version Optional. Version from which to upgrade, if not set, + * version specific upgrades will be disregarded. + * @param array|null $all_old_option_values Optional. Only used when importing old options to have + * access to the real old values, in contrast to the saved ones. + * + * @return array Cleaned option. + */ + protected function clean_option( $option_value, $current_version = null, $all_old_option_values = null ) { + // Deal with value change from text string to boolean. + $value_change = [ + 'ignore_search_engines_discouraged_notice', + ]; + + $target_values = [ + 'ignore', + 'done', + ]; + + foreach ( $value_change as $key ) { + if ( isset( $option_value[ $key ] ) + && in_array( $option_value[ $key ], $target_values, true ) + ) { + $option_value[ $key ] = true; + } + } + + return $option_value; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option.php new file mode 100644 index 0000000..1299ba9 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-option.php @@ -0,0 +1,854 @@ + testers] Double check that validation will not cause errors when called + * from upgrade routine (some of the WP functions may not yet be available). + */ +abstract class WPSEO_Option { + + /** + * Prefix for override option keys that allow or disallow the option key of the same name. + * + * @var string + */ + public const ALLOW_KEY_PREFIX = 'allow_'; + + /** + * Option name - MUST be set in concrete class and set to public. + * + * @var string + */ + protected $option_name; + + /** + * Option group name for use in settings forms. + * + * Will be set automagically if not set in concrete class (i.e. + * if it conforms to the normal pattern 'yoast' . $option_name . 'options', + * only set in concrete class if it doesn't). + * + * @var string + */ + public $group_name; + + /** + * Whether to include the option in the return for WPSEO_Options::get_all(). + * + * Also determines which options are copied over for ms_(re)set_blog(). + * + * @var bool + */ + public $include_in_all = true; + + /** + * Whether this option is only for when the install is multisite. + * + * @var bool + */ + public $multisite_only = false; + + /** + * Array of defaults for the option - MUST be set in concrete class. + * + * Shouldn't be requested directly, use $this->get_defaults(); + * + * @var array + */ + protected $defaults; + + /** + * Array of variable option name patterns for the option - if any. + * + * Set this when the option contains array keys which vary based on post_type + * or taxonomy. + * + * @var array + */ + protected $variable_array_key_patterns; + + /** + * Array of sub-options which should not be overloaded with multi-site defaults. + * + * @var array + */ + public $ms_exclude = []; + + /** + * Name for an option higher in the hierarchy to override setting access. + * + * @var string + */ + protected $override_option_name; + + /** + * Instance of this class. + * + * @var WPSEO_Option + */ + protected static $instance; + + /* *********** INSTANTIATION METHODS *********** */ + + /** + * Add all the actions and filters for the option. + */ + protected function __construct() { + + /* Add filters which get applied to the get_options() results. */ + $this->add_default_filters(); // Return defaults if option not set. + $this->add_option_filters(); // Merge with defaults if option *is* set. + + if ( $this->multisite_only !== true ) { + /** + * The option validation routines remove the default filters to prevent failing + * to insert an option if it's new. Let's add them back afterwards. + */ + add_action( 'add_option', [ $this, 'add_default_filters_if_same_option' ] ); // Adding back after INSERT. + + add_action( 'update_option', [ $this, 'add_default_filters_if_same_option' ] ); + + add_filter( 'pre_update_option', [ $this, 'add_default_filters_if_not_changed' ], PHP_INT_MAX, 3 ); + + // Refills the cache when the option has been updated. + add_action( 'update_option_' . $this->option_name, [ 'WPSEO_Options', 'clear_cache' ], 10 ); + } + elseif ( is_multisite() ) { + /* + * The option validation routines remove the default filters to prevent failing + * to insert an option if it's new. Let's add them back afterwards. + * + * For site_options, this method is not foolproof as these actions are not fired + * on an insert/update failure. Please use the WPSEO_Options::update_site_option() method + * for updating site options to make sure the filters are in place. + */ + add_action( 'add_site_option_' . $this->option_name, [ $this, 'add_default_filters' ] ); + add_action( 'update_site_option_' . $this->option_name, [ $this, 'add_default_filters' ] ); + add_filter( 'pre_update_site_option_' . $this->option_name, [ $this, 'add_default_filters_if_not_changed' ], PHP_INT_MAX, 3 ); + + // Refills the cache when the option has been updated. + add_action( 'update_site_option_' . $this->option_name, [ 'WPSEO_Options', 'clear_cache' ], 1, 0 ); + } + + /* + * Make sure the option will always get validated, independently of register_setting() + * (only available on back-end). + */ + add_filter( 'sanitize_option_' . $this->option_name, [ $this, 'validate' ] ); + + /* Register our option for the admin pages */ + add_action( 'admin_init', [ $this, 'register_setting' ] ); + + /* Set option group name if not given */ + if ( ! isset( $this->group_name ) || $this->group_name === '' ) { + $this->group_name = 'yoast_' . $this->option_name . '_options'; + } + + /* Translate some defaults as early as possible - textdomain is loaded in init on priority 1. */ + if ( method_exists( $this, 'translate_defaults' ) ) { + add_action( 'init', [ $this, 'translate_defaults' ], 2 ); + } + + /** + * Enrich defaults once custom post types and taxonomies have been registered + * which is normally done on the init action. + * + * @todo [JRF/testers] Verify that none of the options which are only available after + * enrichment are used before the enriching. + */ + if ( method_exists( $this, 'enrich_defaults' ) ) { + add_action( 'init', [ $this, 'enrich_defaults' ], 99 ); + } + } + + /* + * All concrete classes *must* contain the get_instance method. + * + * {@internal Unfortunately I can't define it as an abstract as it also *has* to be static...}} + * + * ``` + * abstract protected static function get_instance(); + * ``` + * --------------- + * + * Concrete classes *may* contain a translate_defaults method. + * ``` + * abstract public function translate_defaults(); + * ``` + * --------------- + * + * Concrete classes *may* contain an enrich_defaults method to add additional defaults once + * all post_types and taxonomies have been registered. + * + * ``` + * abstract public function enrich_defaults(); + * ``` + */ + + /* *********** METHODS INFLUENCING get_option() *********** */ + + /** + * Add filters to make sure that the option default is returned if the option is not set. + * + * @return void + */ + public function add_default_filters() { + // Don't change, needs to check for false as could return prio 0 which would evaluate to false. + if ( has_filter( 'default_option_' . $this->option_name, [ $this, 'get_defaults' ] ) === false ) { + add_filter( 'default_option_' . $this->option_name, [ $this, 'get_defaults' ] ); + } + } + + /** + * Adds back the default filters that were removed during validation if the option was changed. + * Checks if this option was changed to prevent constantly checking if filters are present. + * + * @param string $option_name The option name. + * + * @return void + */ + public function add_default_filters_if_same_option( $option_name ) { + if ( $option_name === $this->option_name ) { + $this->add_default_filters(); + } + } + + /** + * Adds back the default filters that were removed during validation if the option was not changed. + * This is because in that case the latter actions are not called and thus the filters are never + * added back. + * + * @param mixed $value The current value. + * @param string $option_name The option name. + * @param mixed $old_value The old value. + * + * @return string The current value. + */ + public function add_default_filters_if_not_changed( $value, $option_name, $old_value ) { + if ( $option_name !== $this->option_name ) { + return $value; + } + + if ( $value === $old_value || maybe_serialize( $value ) === maybe_serialize( $old_value ) ) { + $this->add_default_filters(); + } + + return $value; + } + + /** + * Validate webmaster tools & Pinterest verification strings. + * + * @param string $key Key to check, by type of service. + * @param array $dirty Dirty data with the new values. + * @param array $old Old data. + * @param array $clean Clean data by reference, normally the default values. + * + * @return void + */ + public function validate_verification_string( $key, $dirty, $old, &$clean ) { + if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) { + $meta = $dirty[ $key ]; + if ( strpos( $meta, 'content=' ) ) { + // Make sure we only have the real key, not a complete meta tag. + preg_match( '`content=([\'"])?([^\'"> ]+)(?:\1|[ />])`', $meta, $match ); + if ( isset( $match[2] ) ) { + $meta = $match[2]; + } + unset( $match ); + } + + $meta = sanitize_text_field( $meta ); + if ( $meta !== '' ) { + $regex = '`^[A-Fa-f0-9_-]+$`'; + + switch ( $key ) { + case 'googleverify': + case 'ahrefsverify': + case 'baiduverify': + $regex = '`^[A-Za-z0-9_-]+$`'; + break; + + case 'msverify': + case 'pinterestverify': + case 'yandexverify': + break; + } + + if ( preg_match( $regex, $meta ) ) { + $clean[ $key ] = $meta; + } + else { + // Restore the previous value, if any. + if ( isset( $old[ $key ] ) && preg_match( $regex, $old[ $key ] ) ) { + $clean[ $key ] = $old[ $key ]; + } + + Yoast_Input_Validation::add_dirty_value_to_settings_errors( $key, $meta ); + } + } + } + } + + /** + * Validates an option as a valid URL. Prints out a WordPress settings error + * notice if the URL is invalid. + * + * @param string $key Key to check, by type of URL setting. + * @param array $dirty Dirty data with the new values. + * @param array $old Old data. + * @param array $clean Clean data by reference, normally the default values. + * + * @return void + */ + public function validate_url( $key, $dirty, $old, &$clean ) { + if ( isset( $dirty[ $key ] ) && $dirty[ $key ] !== '' ) { + + $submitted_url = trim( $dirty[ $key ] ); + $validated_url = filter_var( WPSEO_Utils::sanitize_url( $submitted_url ), FILTER_VALIDATE_URL ); + + if ( $validated_url === false ) { + // Restore the previous URL value, if any. + if ( isset( $old[ $key ] ) && $old[ $key ] !== '' ) { + $url = WPSEO_Utils::sanitize_url( $old[ $key ] ); + if ( $url !== '' ) { + $clean[ $key ] = $url; + } + } + + Yoast_Input_Validation::add_dirty_value_to_settings_errors( $key, $submitted_url ); + + return; + } + + // The URL format is valid, let's sanitize it. + $url = WPSEO_Utils::sanitize_url( $validated_url ); + + if ( $url !== '' ) { + $clean[ $key ] = $url; + } + } + } + + /** + * Remove the default filters. + * Called from the validate() method to prevent failure to add new options. + * + * @return void + */ + public function remove_default_filters() { + remove_filter( 'default_option_' . $this->option_name, [ $this, 'get_defaults' ] ); + } + + /** + * Get the enriched default value for an option. + * + * Checks if the concrete class contains an enrich_defaults() method and if so, runs it. + * + * {@internal The enrich_defaults method is used to set defaults for variable array keys + * in an option, such as array keys depending on post_types and/or taxonomies.}} + * + * @return array + */ + public function get_defaults() { + if ( method_exists( $this, 'translate_defaults' ) ) { + $this->translate_defaults(); + } + + if ( method_exists( $this, 'enrich_defaults' ) ) { + $this->enrich_defaults(); + } + + return apply_filters( 'wpseo_defaults', $this->defaults, $this->option_name ); + } + + /** + * Add filters to make sure that the option is merged with its defaults before being returned. + * + * @return void + */ + public function add_option_filters() { + // Don't change, needs to check for false as could return prio 0 which would evaluate to false. + if ( has_filter( 'option_' . $this->option_name, [ $this, 'get_option' ] ) === false ) { + add_filter( 'option_' . $this->option_name, [ $this, 'get_option' ] ); + } + } + + /** + * Remove the option filters. + * Called from the clean_up methods to make sure we retrieve the original old option. + * + * @return void + */ + public function remove_option_filters() { + remove_filter( 'option_' . $this->option_name, [ $this, 'get_option' ] ); + } + + /** + * Merge an option with its default values. + * + * This method should *not* be called directly!!! It is only meant to filter the get_option() results. + * + * @param mixed $options Option value. + * + * @return mixed Option merged with the defaults for that option. + */ + public function get_option( $options = null ) { + $filtered = $this->array_filter_merge( $options ); + + /* + * If the option contains variable option keys, make sure we don't remove those settings + * - even if the defaults are not complete yet. + * Unfortunately this means we also won't be removing the settings for post types or taxonomies + * which are no longer in the WP install, but rather that than the other way around. + */ + if ( isset( $this->variable_array_key_patterns ) ) { + $filtered = $this->retain_variable_keys( $options, $filtered ); + } + + return $filtered; + } + + /* *********** METHODS influencing add_option(), update_option() and saving from admin pages. *********** */ + + /** + * Register (whitelist) the option for the configuration pages. + * The validation callback is already registered separately on the sanitize_option hook, + * so no need to double register. + * + * @return void + */ + public function register_setting() { + if ( ! WPSEO_Capability_Utils::current_user_can( 'wpseo_manage_options' ) ) { + return; + } + + if ( $this->multisite_only === true ) { + $network_settings_api = Yoast_Network_Settings_API::get(); + if ( $network_settings_api->meets_requirements() ) { + $network_settings_api->register_setting( $this->group_name, $this->option_name ); + } + return; + } + + register_setting( $this->group_name, $this->option_name ); + } + + /** + * Validate the option. + * + * @param mixed $option_value The unvalidated new value for the option. + * + * @return array Validated new value for the option. + */ + public function validate( $option_value ) { + $clean = $this->get_defaults(); + + /* Return the defaults if the new value is empty. */ + if ( ! is_array( $option_value ) || $option_value === [] ) { + return $clean; + } + + $option_value = array_map( [ 'WPSEO_Utils', 'trim_recursive' ], $option_value ); + + $old = $this->get_original_option(); + if ( ! is_array( $old ) ) { + $old = []; + } + $old = array_merge( $clean, $old ); + + $clean = $this->validate_option( $option_value, $clean, $old ); + + // Prevent updates to variables that are disabled via the override option. + $clean = $this->prevent_disabled_options_update( $clean, $old ); + + /* Retain the values for variable array keys even when the post type/taxonomy is not yet registered. */ + if ( isset( $this->variable_array_key_patterns ) ) { + $clean = $this->retain_variable_keys( $option_value, $clean ); + } + + $this->remove_default_filters(); + + return $clean; + } + + /** + * Checks whether a specific option key is disabled. + * + * This is determined by whether an override option is available with a key that equals the given key prefixed + * with 'allow_'. + * + * @param string $key Option key. + * + * @return bool True if option key is disabled, false otherwise. + */ + public function is_disabled( $key ) { + $override_option = $this->get_override_option(); + if ( empty( $override_option ) ) { + return false; + } + + return isset( $override_option[ self::ALLOW_KEY_PREFIX . $key ] ) && ! $override_option[ self::ALLOW_KEY_PREFIX . $key ]; + } + + /** + * All concrete classes must contain a validate_option() method which validates all + * values within the option. + * + * @param array $dirty New value for the option. + * @param array $clean Clean value for the option, normally the defaults. + * @param array $old Old value of the option. + */ + abstract protected function validate_option( $dirty, $clean, $old ); + + /* *********** METHODS for ADDING/UPDATING/UPGRADING the option. *********** */ + + /** + * Retrieve the real old value (unmerged with defaults). + * + * @return array|bool The original option value (which can be false if the option doesn't exist). + */ + protected function get_original_option() { + $this->remove_default_filters(); + $this->remove_option_filters(); + + // Get (unvalidated) array, NOT merged with defaults. + if ( $this->multisite_only !== true ) { + $option_value = get_option( $this->option_name ); + } + else { + $option_value = get_site_option( $this->option_name ); + } + + $this->add_option_filters(); + $this->add_default_filters(); + + return $option_value; + } + + /** + * Add the option if it doesn't exist for some strange reason. + * + * @uses WPSEO_Option::get_original_option() + * + * @return void + */ + public function maybe_add_option() { + if ( $this->get_original_option() === false ) { + if ( $this->multisite_only !== true ) { + update_option( $this->option_name, $this->get_defaults() ); + } + else { + $this->update_site_option( $this->get_defaults() ); + } + } + } + + /** + * Update a site_option. + * + * {@internal This special method is only needed for multisite options, but very needed indeed there. + * The order in which certain functions and hooks are run is different between + * get_option() and get_site_option() which means in practice that the removing + * of the default filters would be done too late and the re-adding of the default + * filters might not be done at all. + * Aka: use the WPSEO_Options::update_site_option() method (which calls this method) + * for safely adding/updating multisite options.}} + * + * @param mixed $value The new value for the option. + * + * @return bool Whether the update was successful. + */ + public function update_site_option( $value ) { + if ( $this->multisite_only === true && is_multisite() ) { + $this->remove_default_filters(); + $result = update_site_option( $this->option_name, $value ); + $this->add_default_filters(); + + return $result; + } + else { + return false; + } + } + + /** + * Retrieve the real old value (unmerged with defaults), clean and re-save the option. + * + * @uses WPSEO_Option::get_original_option() + * @uses WPSEO_Option::import() + * + * @param string|null $current_version Optional. Version from which to upgrade, if not set, + * version-specific upgrades will be disregarded. + * + * @return void + */ + public function clean( $current_version = null ) { + $option_value = $this->get_original_option(); + $this->import( $option_value, $current_version ); + } + + /** + * Clean and re-save the option. + * + * @uses clean_option() method from concrete class if it exists. + * + * @todo [JRF/whomever] Figure out a way to show settings error during/after the upgrade - maybe + * something along the lines of: + * -> add them to a property in this class + * -> if that property isset at the end of the routine and add_settings_error function does not exist, + * save as transient (or update the transient if one already exists) + * -> next time an admin is in the WP back-end, show the errors and delete the transient or only delete it + * once the admin has dismissed the message (add ajax function) + * Important: all validation routines which add_settings_errors would need to be changed for this to work + * + * @param array $option_value Option value to be imported. + * @param string|null $current_version Optional. Version from which to upgrade, if not set, + * version-specific upgrades will be disregarded. + * @param array|null $all_old_option_values Optional. Only used when importing old options to + * have access to the real old values, in contrast to + * the saved ones. + * + * @return void + */ + public function import( $option_value, $current_version = null, $all_old_option_values = null ) { + if ( $option_value === false ) { + $option_value = $this->get_defaults(); + } + elseif ( is_array( $option_value ) && method_exists( $this, 'clean_option' ) ) { + $option_value = $this->clean_option( $option_value, $current_version, $all_old_option_values ); + } + + /* + * Save the cleaned value - validation will take care of cleaning out array keys which + * should no longer be there. + */ + if ( $this->multisite_only !== true ) { + update_option( $this->option_name, $option_value ); + } + else { + $this->update_site_option( $this->option_name, $option_value ); + } + } + + /** + * Returns the variable array key patterns for an options class. + * + * @return array + */ + public function get_patterns() { + return (array) $this->variable_array_key_patterns; + } + + /** + * Retrieves the option name. + * + * @return string The set option name. + */ + public function get_option_name() { + return $this->option_name; + } + + /* + * Concrete classes *may* contain a clean_option method which will clean out old/renamed + * values within the option. + * + * ``` + * abstract public function clean_option( $option_value, $current_version = null, $all_old_option_values = null ); + * ``` + */ + + /* *********** HELPER METHODS for internal use. *********** */ + + /** + * Helper method - Combines a fixed array of default values with an options array + * while filtering out any keys which are not in the defaults array. + * + * @todo [JRF] - shouldn't this be a straight array merge ? at the end of the day, the validation + * removes any invalid keys on save. + * + * @param array|null $options Optional. Current options. If not set, the option defaults + * for the $option_key will be returned. + * + * @return array Combined and filtered options array. + */ + protected function array_filter_merge( $options = null ) { + + $defaults = $this->get_defaults(); + + if ( ! isset( $options ) || $options === false || $options === [] ) { + return $defaults; + } + + $options = (array) $options; + + /* + $filtered = array(); + + if ( $defaults !== array() ) { + foreach ( $defaults as $key => $default_value ) { + // @todo should this walk through array subkeys ? + $filtered[ $key ] = ( isset( $options[ $key ] ) ? $options[ $key ] : $default_value ); + } + } + */ + $filtered = array_merge( $defaults, $options ); + + return $filtered; + } + + /** + * Sets updated values for variables that are disabled via the override option back to their previous values. + * + * @param array $updated Updated option value. + * @param array $old Old option value. + * + * @return array Updated option value, with all disabled variables set to their old values. + */ + protected function prevent_disabled_options_update( $updated, $old ) { + $override_option = $this->get_override_option(); + if ( empty( $override_option ) ) { + return $updated; + } + + /* + * This loop could as well call `is_disabled( $key )` for each iteration, + * however this would be worse performance-wise. + */ + foreach ( $old as $key => $value ) { + if ( isset( $override_option[ self::ALLOW_KEY_PREFIX . $key ] ) && ! $override_option[ self::ALLOW_KEY_PREFIX . $key ] ) { + $updated[ $key ] = $old[ $key ]; + } + } + + return $updated; + } + + /** + * Retrieves the value of the override option, if available. + * + * An override option contains values that may determine access to certain sub-variables + * of this option. + * + * Only regular options in multisite can have override options, which in that case + * would be network options. + * + * @return array Override option value, or empty array if unavailable. + */ + protected function get_override_option() { + if ( empty( $this->override_option_name ) || $this->multisite_only === true || ! is_multisite() ) { + return []; + } + + return get_site_option( $this->override_option_name, [] ); + } + + /** + * Make sure that any set option values relating to post_types and/or taxonomies are retained, + * even when that post_type or taxonomy may not yet have been registered. + * + * {@internal The wpseo_titles concrete class overrules this method. Make sure that any + * changes applied here, also get ported to that version.}} + * + * @param array $dirty Original option as retrieved from the database. + * @param array $clean Filtered option where any options which shouldn't be in our option + * have already been removed and any options which weren't set + * have been set to their defaults. + * + * @return array + */ + protected function retain_variable_keys( $dirty, $clean ) { + if ( ( is_array( $this->variable_array_key_patterns ) && $this->variable_array_key_patterns !== [] ) && ( is_array( $dirty ) && $dirty !== [] ) ) { + foreach ( $dirty as $key => $value ) { + + // Do nothing if already in filtered options. + if ( isset( $clean[ $key ] ) ) { + continue; + } + + foreach ( $this->variable_array_key_patterns as $pattern ) { + + if ( strpos( $key, $pattern ) === 0 ) { + $clean[ $key ] = $value; + break; + } + } + } + } + + return $clean; + } + + /** + * Check whether a given array key conforms to one of the variable array key patterns for this option. + * + * @used-by validate_option() methods for options with variable array keys. + * + * @param string $key Array key to check. + * + * @return string Pattern if it conforms, original array key if it doesn't or if the option + * does not have variable array keys. + */ + protected function get_switch_key( $key ) { + if ( ! isset( $this->variable_array_key_patterns ) || ( ! is_array( $this->variable_array_key_patterns ) || $this->variable_array_key_patterns === [] ) ) { + return $key; + } + + foreach ( $this->variable_array_key_patterns as $pattern ) { + if ( strpos( $key, $pattern ) === 0 ) { + return $pattern; + } + } + + return $key; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-options.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-options.php new file mode 100644 index 0000000..790a426 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-options.php @@ -0,0 +1,606 @@ + (string) name of concrete class for the option. + */ + public static $options = [ + 'wpseo' => 'WPSEO_Option_Wpseo', + 'wpseo_titles' => 'WPSEO_Option_Titles', + 'wpseo_social' => 'WPSEO_Option_Social', + 'wpseo_ms' => 'WPSEO_Option_MS', + 'wpseo_taxonomy_meta' => 'WPSEO_Taxonomy_Meta', + 'wpseo_llmstxt' => 'WPSEO_Option_Llmstxt', + 'wpseo_tracking_only' => 'WPSEO_Option_Tracking_Only', + ]; + + /** + * Array of instantiated option objects. + * + * @var array + */ + protected static $option_instances = []; + + /** + * Array with the option names. + * + * @var array + */ + protected static $option_names = []; + + /** + * Instance of this class. + * + * @var WPSEO_Options + */ + protected static $instance; + + /** + * Instantiate all the WPSEO option management classes. + */ + protected function __construct() { + $this->register_hooks(); + + foreach ( static::$options as $option_class ) { + static::register_option( call_user_func( [ $option_class, 'get_instance' ] ) ); + } + } + + /** + * Register our hooks. + * + * @return void + */ + public function register_hooks() { + add_action( 'registered_taxonomy', [ $this, 'clear_cache' ] ); + add_action( 'unregistered_taxonomy', [ $this, 'clear_cache' ] ); + add_action( 'registered_post_type', [ $this, 'clear_cache' ] ); + add_action( 'unregistered_post_type', [ $this, 'clear_cache' ] ); + } + + /** + * Get the singleton instance of this class. + * + * @return object + */ + public static function get_instance() { + if ( ! ( static::$instance instanceof self ) ) { + static::$instance = new self(); + } + + return static::$instance; + } + + /** + * Registers an option to the options list. + * + * @param WPSEO_Option $option_instance Instance of the option. + * + * @return void + */ + public static function register_option( WPSEO_Option $option_instance ) { + $option_name = $option_instance->get_option_name(); + + if ( $option_instance->multisite_only && ! static::is_multisite() ) { + unset( static::$options[ $option_name ], static::$option_names[ $option_name ] ); + + return; + } + + $is_already_registered = array_key_exists( $option_name, static::$options ); + if ( ! $is_already_registered ) { + static::$options[ $option_name ] = get_class( $option_instance ); + } + + if ( $option_instance->include_in_all === true ) { + static::$option_names[ $option_name ] = $option_name; + } + + static::$option_instances[ $option_name ] = $option_instance; + + if ( ! $is_already_registered ) { + static::clear_cache(); + } + } + + /** + * Get the group name of an option for use in the settings form. + * + * @param string $option_name The option for which you want to retrieve the option group name. + * + * @return string|bool + */ + public static function get_group_name( $option_name ) { + if ( isset( static::$option_instances[ $option_name ] ) ) { + return static::$option_instances[ $option_name ]->group_name; + } + + return false; + } + + /** + * Get a specific default value for an option. + * + * @param string $option_name The option for which you want to retrieve a default. + * @param string $key The key within the option who's default you want. + * + * @return mixed + */ + public static function get_default( $option_name, $key ) { + if ( isset( static::$option_instances[ $option_name ] ) ) { + $defaults = static::$option_instances[ $option_name ]->get_defaults(); + if ( isset( $defaults[ $key ] ) ) { + return $defaults[ $key ]; + } + } + + return null; + } + + /** + * Update a site_option. + * + * @param string $option_name The option name of the option to save. + * @param mixed $value The new value for the option. + * + * @return bool + */ + public static function update_site_option( $option_name, $value ) { + if ( is_multisite() && isset( static::$option_instances[ $option_name ] ) ) { + return static::$option_instances[ $option_name ]->update_site_option( $value ); + } + + return false; + } + + /** + * Get the instantiated option instance. + * + * @param string $option_name The option for which you want to retrieve the instance. + * + * @return object|bool + */ + public static function get_option_instance( $option_name ) { + if ( isset( static::$option_instances[ $option_name ] ) ) { + return static::$option_instances[ $option_name ]; + } + + return false; + } + + /** + * Retrieve an array of the options which should be included in get_all() and reset(). + * + * @return array Array of option names. + */ + public static function get_option_names() { + $option_names = array_values( static::$option_names ); + if ( $option_names === [] ) { + foreach ( static::$option_instances as $option_name => $option_object ) { + if ( $option_object->include_in_all === true ) { + $option_names[] = $option_name; + } + } + } + + /** + * Filter: wpseo_options - Allow developers to change the option name to include. + * + * @param array $option_names The option names to include in get_all and reset(). + */ + return apply_filters( 'wpseo_options', $option_names ); + } + + /** + * Retrieve all the options for the SEO plugin in one go. + * + * @param array $specific_options The option groups of the option you want to get. + * + * @return array Array combining the values of all the options. + */ + public static function get_all( $specific_options = [] ) { + $option_names = ( empty( $specific_options ) ) ? static::get_option_names() : $specific_options; + static::$option_values = static::get_options( $option_names ); + + return static::$option_values; + } + + /** + * Retrieve one or more options for the SEO plugin. + * + * @param array $option_names An array of option names of the options you want to get. + * + * @return array Array combining the values of the requested options. + */ + public static function get_options( array $option_names ) { + $options = []; + $option_names = array_filter( $option_names, 'is_string' ); + foreach ( $option_names as $option_name ) { + if ( isset( static::$option_instances[ $option_name ] ) ) { + $option = static::get_option( $option_name ); + + if ( $option !== null ) { + $options = array_merge( $options, $option ); + } + } + } + + return $options; + } + + /** + * Retrieve a single option for the SEO plugin. + * + * @param string $option_name The name of the option you want to get. + * + * @return array Array containing the requested option. + */ + public static function get_option( $option_name ) { + $option = null; + if ( is_string( $option_name ) && ! empty( $option_name ) ) { + if ( isset( static::$option_instances[ $option_name ] ) ) { + if ( static::$option_instances[ $option_name ]->multisite_only !== true ) { + $option = get_option( $option_name ); + } + else { + $option = get_site_option( $option_name ); + } + } + } + + return $option; + } + + /** + * Retrieve a single field from any option for the SEO plugin. Keys are always unique. + * + * @param string $key The key it should return. + * @param mixed $default_value The default value that should be returned if the key isn't set. + * @param array $option_groups The option groups to retrieve the option from. + * + * @return mixed Returns value if found, $default_value if not. + */ + public static function get( $key, $default_value = null, $option_groups = [] ) { + if ( ! isset( static::$option_values[ $key ] ) ) { + static::prime_cache( $option_groups ); + } + if ( isset( static::$option_values[ $key ] ) ) { + return static::$option_values[ $key ]; + } + + return $default_value; + } + + /** + * Resets the cache to null. + * + * @return void + */ + public static function clear_cache() { + static::$option_values = null; + } + + /** + * Primes our cache. + * + * @param array $option_groups The option groups to prime the cache with. + * + * @return void + */ + private static function prime_cache( $option_groups = [] ) { + static::$option_values = static::get_all( $option_groups ); + static::$option_values = static::add_ms_option( static::$option_values ); + } + + /** + * Retrieve a single field from an option for the SEO plugin. + * + * @param string $key The key to set. + * @param mixed $value The value to set. + * @param string $option_group The lookup table which represents the option_group where the key is stored. + * + * @return mixed|null Returns value if found, $default if not. + */ + public static function set( $key, $value, $option_group = '' ) { + $lookup_table = static::get_lookup_table( $option_group ); + + if ( isset( $lookup_table[ $key ] ) ) { + return static::save_option( $lookup_table[ $key ], $key, $value ); + } + + $patterns = static::get_pattern_table(); + foreach ( $patterns as $pattern => $option ) { + if ( strpos( $key, $pattern ) === 0 ) { + return static::save_option( $option, $key, $value ); + } + } + + static::$option_values[ $key ] = $value; + } + + /** + * Get an option only if it's been auto-loaded. + * + * @param string $option The option to retrieve. + * @param mixed $default_value A default value to return. + * + * @return mixed + */ + public static function get_autoloaded_option( $option, $default_value = false ) { + $value = wp_cache_get( $option, 'options' ); + if ( $value === false ) { + $passed_default = func_num_args() > 1; + + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Using WP native filter. + return apply_filters( "default_option_{$option}", $default_value, $option, $passed_default ); + } + + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Using WP native filter. + return apply_filters( "option_{$option}", maybe_unserialize( $value ), $option ); + } + + /** + * Run the clean up routine for one or all options. + * + * @param array|string|null $option_name Optional. the option you want to clean or an array of + * option names for the options you want to clean. + * If not set, all options will be cleaned. + * @param string|null $current_version Optional. Version from which to upgrade, if not set, + * version specific upgrades will be disregarded. + * + * @return void + */ + public static function clean_up( $option_name = null, $current_version = null ) { + if ( isset( $option_name ) && is_string( $option_name ) && $option_name !== '' ) { + if ( isset( static::$option_instances[ $option_name ] ) ) { + static::$option_instances[ $option_name ]->clean( $current_version ); + } + } + elseif ( isset( $option_name ) && is_array( $option_name ) && $option_name !== [] ) { + foreach ( $option_name as $option ) { + if ( isset( static::$option_instances[ $option ] ) ) { + static::$option_instances[ $option ]->clean( $current_version ); + } + } + unset( $option ); + } + else { + foreach ( static::$option_instances as $instance ) { + $instance->clean( $current_version ); + } + unset( $instance ); + + // If we've done a full clean-up, we can safely remove this really old option. + delete_option( 'wpseo_indexation' ); + } + } + + /** + * Check that all options exist in the database and add any which don't. + * + * @return void + */ + public static function ensure_options_exist() { + foreach ( static::$option_instances as $instance ) { + $instance->maybe_add_option(); + } + } + + /** + * Initialize some options on first install/activate/reset. + * + * @return void + */ + public static function initialize() { + /* Force WooThemes to use Yoast SEO data. */ + if ( function_exists( 'woo_version_init' ) ) { + update_option( 'seo_woo_use_third_party_data', 'true' ); + } + } + + /** + * Reset all options to their default values and rerun some tests. + * + * @return void + */ + public static function reset() { + if ( ! is_multisite() ) { + $option_names = static::get_option_names(); + if ( is_array( $option_names ) && $option_names !== [] ) { + foreach ( $option_names as $option_name ) { + delete_option( $option_name ); + update_option( $option_name, get_option( $option_name ) ); + } + } + unset( $option_names ); + } + else { + // Reset MS blog based on network default blog setting. + static::reset_ms_blog( get_current_blog_id() ); + } + + static::initialize(); + } + + /** + * Initialize default values for a new multisite blog. + * + * @param bool $force_init Whether to always do the initialization routine (title/desc test). + * + * @return void + */ + public static function maybe_set_multisite_defaults( $force_init = false ) { + $option = get_option( 'wpseo' ); + + if ( is_multisite() ) { + if ( $option['ms_defaults_set'] === false ) { + static::reset_ms_blog( get_current_blog_id() ); + static::initialize(); + } + elseif ( $force_init === true ) { + static::initialize(); + } + } + } + + /** + * Reset all options for a specific multisite blog to their default values based upon a + * specified default blog if one was chosen on the network page or the plugin defaults if it was not. + * + * @param int|string $blog_id Blog id of the blog for which to reset the options. + * + * @return void + */ + public static function reset_ms_blog( $blog_id ) { + if ( is_multisite() ) { + $options = get_site_option( 'wpseo_ms' ); + $option_names = static::get_option_names(); + + if ( is_array( $option_names ) && $option_names !== [] ) { + $base_blog_id = $blog_id; + if ( $options['defaultblog'] !== '' && $options['defaultblog'] !== 0 ) { + $base_blog_id = $options['defaultblog']; + } + + foreach ( $option_names as $option_name ) { + delete_blog_option( $blog_id, $option_name ); + + $new_option = get_blog_option( $base_blog_id, $option_name ); + + /* Remove sensitive, theme dependent and site dependent info. */ + if ( isset( static::$option_instances[ $option_name ] ) && static::$option_instances[ $option_name ]->ms_exclude !== [] ) { + foreach ( static::$option_instances[ $option_name ]->ms_exclude as $key ) { + unset( $new_option[ $key ] ); + } + } + + if ( $option_name === 'wpseo' ) { + $new_option['ms_defaults_set'] = true; + } + + update_blog_option( $blog_id, $option_name, $new_option ); + } + } + } + } + + /** + * Saves the option to the database. + * + * @param string $wpseo_options_group_name The name for the wpseo option group in the database. + * @param string $option_name The name for the option to set. + * @param mixed $option_value The value for the option. + * + * @return bool Returns true if the option is successfully saved in the database. + */ + public static function save_option( $wpseo_options_group_name, $option_name, $option_value ) { + $options = static::get_option( $wpseo_options_group_name ); + $options[ $option_name ] = $option_value; + + if ( isset( static::$option_instances[ $wpseo_options_group_name ] ) && static::$option_instances[ $wpseo_options_group_name ]->multisite_only === true ) { + static::update_site_option( $wpseo_options_group_name, $options ); + } + else { + update_option( $wpseo_options_group_name, $options ); + } + + // Check if everything got saved properly. + $saved_option = static::get_option( $wpseo_options_group_name ); + + // Clear our cache. + static::clear_cache(); + + return $saved_option[ $option_name ] === $options[ $option_name ]; + } + + /** + * Adds the multisite options to the option stack if relevant. + * + * @param array $option The currently present options settings. + * + * @return array Options possibly including multisite. + */ + protected static function add_ms_option( $option ) { + if ( ! is_multisite() ) { + return $option; + } + + $ms_option = static::get_option( 'wpseo_ms' ); + if ( $ms_option === null ) { + return $option; + } + + return array_merge( $option, $ms_option ); + } + + /** + * Checks if installation is multisite. + * + * @return bool True when is multisite. + */ + protected static function is_multisite() { + static $is_multisite; + + $is_multisite ??= is_multisite(); + + return $is_multisite; + } + + /** + * Retrieves a lookup table to find in which option_group a key is stored. + * + * @param string $option_group The option_group where the key is stored. + * + * @return array The lookup table. + */ + private static function get_lookup_table( $option_group = '' ) { + $lookup_table = []; + $option_groups = ( $option_group === '' ) ? static::$options : [ $option_group => static::$options[ $option_group ] ]; + + foreach ( array_keys( $option_groups ) as $option_name ) { + $full_option = static::get_option( $option_name ); + foreach ( $full_option as $key => $value ) { + $lookup_table[ $key ] = $option_name; + } + } + + return $lookup_table; + } + + /** + * Retrieves a lookup table to find in which option_group a key is stored. + * + * @return array The lookup table. + */ + private static function get_pattern_table() { + $pattern_table = []; + foreach ( static::$options as $option_name => $option_class ) { + $instance = call_user_func( [ $option_class, 'get_instance' ] ); + foreach ( $instance->get_patterns() as $key ) { + $pattern_table[ $key ] = $option_name; + } + } + + return $pattern_table; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-taxonomy-meta.php b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-taxonomy-meta.php new file mode 100644 index 0000000..636e1ac --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/options/class-wpseo-taxonomy-meta.php @@ -0,0 +1,566 @@ +get_defaults(); + * + * {@internal Important: in contrast to most defaults, the below array format is + * very bare. The real option is in the format [taxonomy_name][term_id][...] + * where [...] is any of the $defaults_per_term options shown below. + * This is of course taken into account in the below methods.}} + * + * @var array + */ + protected $defaults = []; + + /** + * Option name - same as $option_name property, but now also available to static methods. + * + * @var string + */ + public static $name; + + /** + * Array of defaults for individual taxonomy meta entries. + * + * @var array + */ + public static $defaults_per_term = [ + 'wpseo_title' => '', + 'wpseo_desc' => '', + 'wpseo_canonical' => '', + 'wpseo_bctitle' => '', + 'wpseo_noindex' => 'default', + 'wpseo_focuskw' => '', + 'wpseo_linkdex' => '', + 'wpseo_content_score' => '', + 'wpseo_inclusive_language_score' => '', + 'wpseo_focuskeywords' => '[]', + 'wpseo_keywordsynonyms' => '[]', + 'wpseo_is_cornerstone' => '0', + + // Social fields. + 'wpseo_opengraph-title' => '', + 'wpseo_opengraph-description' => '', + 'wpseo_opengraph-image' => '', + 'wpseo_opengraph-image-id' => '', + 'wpseo_twitter-title' => '', + 'wpseo_twitter-description' => '', + 'wpseo_twitter-image' => '', + 'wpseo_twitter-image-id' => '', + ]; + + /** + * Available index options. + * + * Used for form generation and input validation. + * + * {@internal Labels (translation) added on admin_init via WPSEO_Taxonomy::translate_meta_options().}} + * + * @var array + */ + public static $no_index_options = [ + 'default' => '', + 'index' => '', + 'noindex' => '', + ]; + + /** + * Add the actions and filters for the option. + * + * @todo [JRF => testers] Check if the extra actions below would run into problems if an option + * is updated early on and if so, change the call to schedule these for a later action on add/update + * instead of running them straight away. + */ + protected function __construct() { + parent::__construct(); + + self::$name = $this->option_name; + } + + /** + * Get the singleton instance of this class. + * + * @return object + */ + public static function get_instance() { + if ( ! ( self::$instance instanceof self ) ) { + self::$instance = new self(); + self::$name = self::$instance->option_name; + } + + return self::$instance; + } + + /** + * Add extra default options received from a filter. + * + * @return void + */ + public function enrich_defaults() { + $extra_defaults_per_term = apply_filters( 'wpseo_add_extra_taxmeta_term_defaults', [] ); + if ( is_array( $extra_defaults_per_term ) ) { + self::$defaults_per_term = array_merge( $extra_defaults_per_term, self::$defaults_per_term ); + } + } + + /** + * Validate the option. + * + * @param array $dirty New value for the option. + * @param array $clean Clean value for the option, normally the defaults. + * @param array $old Old value of the option. + * + * @return array Validated clean value for the option to be saved to the database. + */ + protected function validate_option( $dirty, $clean, $old ) { + /* + * Prevent complete validation (which can be expensive when there are lots of terms) + * if only one item has changed and has already been validated. + */ + if ( isset( $dirty['wpseo_already_validated'] ) && $dirty['wpseo_already_validated'] === true ) { + unset( $dirty['wpseo_already_validated'] ); + + return $dirty; + } + + foreach ( $dirty as $taxonomy => $terms ) { + /* Don't validate taxonomy - may not be registered yet and we don't want to remove valid ones. */ + if ( is_array( $terms ) && $terms !== [] ) { + foreach ( $terms as $term_id => $meta_data ) { + /* Only validate term if the taxonomy exists. */ + if ( taxonomy_exists( $taxonomy ) && get_term_by( 'id', $term_id, $taxonomy ) === false ) { + /* Is this term id a special case ? */ + if ( has_filter( 'wpseo_tax_meta_special_term_id_validation_' . $term_id ) !== false ) { + $clean[ $taxonomy ][ $term_id ] = apply_filters( 'wpseo_tax_meta_special_term_id_validation_' . $term_id, $meta_data, $taxonomy, $term_id ); + } + continue; + } + + if ( is_array( $meta_data ) && $meta_data !== [] ) { + /* Validate meta data. */ + $old_meta = self::get_term_meta( $term_id, $taxonomy ); + $meta_data = self::validate_term_meta_data( $meta_data, $old_meta ); + if ( $meta_data !== [] ) { + $clean[ $taxonomy ][ $term_id ] = $meta_data; + } + } + + // Deal with special cases (for when taxonomy doesn't exist yet). + if ( ! isset( $clean[ $taxonomy ][ $term_id ] ) && has_filter( 'wpseo_tax_meta_special_term_id_validation_' . $term_id ) !== false ) { + $clean[ $taxonomy ][ $term_id ] = apply_filters( 'wpseo_tax_meta_special_term_id_validation_' . $term_id, $meta_data, $taxonomy, $term_id ); + } + } + } + } + + return $clean; + } + + /** + * Validate the meta data for one individual term and removes default values (no need to save those). + * + * @param array $meta_data New values. + * @param array $old_meta The original values. + * + * @return array Validated and filtered value. + */ + public static function validate_term_meta_data( $meta_data, $old_meta ) { + + $clean = self::$defaults_per_term; + $meta_data = array_map( [ 'WPSEO_Utils', 'trim_recursive' ], $meta_data ); + + if ( ! is_array( $meta_data ) || $meta_data === [] ) { + return $clean; + } + + foreach ( $clean as $key => $value ) { + switch ( $key ) { + + case 'wpseo_noindex': + if ( isset( $meta_data[ $key ] ) ) { + if ( isset( self::$no_index_options[ $meta_data[ $key ] ] ) ) { + $clean[ $key ] = $meta_data[ $key ]; + } + } + elseif ( isset( $old_meta[ $key ] ) ) { + // Retain old value if field currently not in use. + $clean[ $key ] = $old_meta[ $key ]; + } + break; + + case 'wpseo_canonical': + if ( isset( $meta_data[ $key ] ) && $meta_data[ $key ] !== '' ) { + $url = WPSEO_Utils::sanitize_url( $meta_data[ $key ] ); + if ( $url !== '' ) { + $clean[ $key ] = $url; + } + unset( $url ); + } + break; + + case 'wpseo_bctitle': + if ( isset( $meta_data[ $key ] ) ) { + $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $meta_data[ $key ] ); + } + elseif ( isset( $old_meta[ $key ] ) ) { + // Retain old value if field currently not in use. + $clean[ $key ] = $old_meta[ $key ]; + } + break; + + case 'wpseo_keywordsynonyms': + if ( isset( $meta_data[ $key ] ) && is_string( $meta_data[ $key ] ) ) { + // The data is stringified JSON. Use `json_decode` and `json_encode` around the sanitation. + $input = json_decode( $meta_data[ $key ], true ); + $sanitized = array_map( [ 'WPSEO_Utils', 'sanitize_text_field' ], $input ); + $clean[ $key ] = WPSEO_Utils::format_json_encode( $sanitized ); + } + elseif ( isset( $old_meta[ $key ] ) ) { + // Retain old value if field currently not in use. + $clean[ $key ] = $old_meta[ $key ]; + } + break; + + case 'wpseo_focuskeywords': + if ( isset( $meta_data[ $key ] ) && is_string( $meta_data[ $key ] ) ) { + // The data is stringified JSON. Use `json_decode` and `json_encode` around the sanitation. + $input = json_decode( $meta_data[ $key ], true ); + + // This data has two known keys: `keyword` and `score`. + $sanitized = []; + foreach ( $input as $entry ) { + $sanitized[] = [ + 'keyword' => WPSEO_Utils::sanitize_text_field( $entry['keyword'] ), + 'score' => WPSEO_Utils::sanitize_text_field( $entry['score'] ), + ]; + } + + $clean[ $key ] = WPSEO_Utils::format_json_encode( $sanitized ); + } + elseif ( isset( $old_meta[ $key ] ) ) { + // Retain old value if field currently not in use. + $clean[ $key ] = $old_meta[ $key ]; + } + break; + + case 'wpseo_focuskw': + case 'wpseo_title': + case 'wpseo_desc': + case 'wpseo_linkdex': + default: + if ( isset( $meta_data[ $key ] ) && is_string( $meta_data[ $key ] ) ) { + $clean[ $key ] = WPSEO_Utils::sanitize_text_field( $meta_data[ $key ] ); + } + + if ( $key === 'wpseo_focuskw' ) { + $search = [ + '<', + '>', + '`', + '<', + '>', + '`', + ]; + + $clean[ $key ] = str_replace( $search, '', $clean[ $key ] ); + } + break; + } + + $clean[ $key ] = apply_filters( 'wpseo_sanitize_tax_meta_' . $key, $clean[ $key ], ( $meta_data[ $key ] ?? null ), ( $old_meta[ $key ] ?? null ) ); + } + + // Only save the non-default values. + return array_diff_assoc( $clean, self::$defaults_per_term ); + } + + /** + * Clean a given option value. + * - Convert old option values to new + * - Fixes strings which were escaped (should have been sanitized - escaping is for output) + * + * @param array $option_value Old (not merged with defaults or filtered) option value to + * clean according to the rules for this option. + * @param string|null $current_version Optional. Version from which to upgrade, if not set, + * version specific upgrades will be disregarded. + * @param array|null $all_old_option_values Optional. Only used when importing old options to have + * access to the real old values, in contrast to the saved ones. + * + * @return array Cleaned option. + */ + protected function clean_option( $option_value, $current_version = null, $all_old_option_values = null ) { + + /* Clean up old values and remove empty arrays. */ + if ( is_array( $option_value ) && $option_value !== [] ) { + + foreach ( $option_value as $taxonomy => $terms ) { + + if ( is_array( $terms ) && $terms !== [] ) { + + foreach ( $terms as $term_id => $meta_data ) { + if ( ! is_array( $meta_data ) || $meta_data === [] ) { + // Remove empty term arrays. + unset( $option_value[ $taxonomy ][ $term_id ] ); + } + else { + foreach ( $meta_data as $key => $value ) { + + switch ( $key ) { + case 'noindex': + if ( $value === 'on' ) { + // Convert 'on' to 'noindex'. + $option_value[ $taxonomy ][ $term_id ][ $key ] = 'noindex'; + } + break; + + case 'canonical': + case 'wpseo_bctitle': + case 'wpseo_title': + case 'wpseo_desc': + case 'wpseo_linkdex': + // @todo [JRF => whomever] Needs checking, I don't have example data [JRF]. + if ( $value !== '' ) { + // Fix incorrectly saved (encoded) canonical urls and texts. + $option_value[ $taxonomy ][ $term_id ][ $key ] = wp_specialchars_decode( stripslashes( $value ), ENT_QUOTES ); + } + break; + + default: + // @todo [JRF => whomever] Needs checking, I don't have example data [JRF]. + if ( $value !== '' ) { + // Fix incorrectly saved (escaped) text strings. + $option_value[ $taxonomy ][ $term_id ][ $key ] = wp_specialchars_decode( $value, ENT_QUOTES ); + } + break; + } + } + } + } + } + else { + // Remove empty taxonomy arrays. + unset( $option_value[ $taxonomy ] ); + } + } + } + + return $option_value; + } + + /** + * Retrieve a taxonomy term's meta value(s). + * + * @param mixed $term Term to get the meta value for + * either (string) term name, (int) term id or (object) term. + * @param string $taxonomy Name of the taxonomy to which the term is attached. + * @param string|null $meta Optional. Meta value to get (without prefix). + * + * @return mixed Value for the $meta if one is given, might be the default. + * If no meta is given, an array of all the meta data for the term. + * False if the term does not exist or the $meta provided is invalid. + */ + public static function get_term_meta( $term, $taxonomy, $meta = null ) { + /* Figure out the term id. */ + if ( is_int( $term ) ) { + $term = get_term_by( 'id', $term, $taxonomy ); + } + elseif ( is_string( $term ) ) { + $term = get_term_by( 'slug', $term, $taxonomy ); + } + + if ( is_object( $term ) && isset( $term->term_id ) ) { + $term_id = $term->term_id; + } + else { + return false; + } + + $tax_meta = self::get_term_tax_meta( $term_id, $taxonomy ); + + /* + * Either return the complete array or a single value from it or false if the value does not exist + * (shouldn't happen after merge with defaults, indicates typo in request). + */ + if ( ! isset( $meta ) ) { + return $tax_meta; + } + + if ( isset( $tax_meta[ 'wpseo_' . $meta ] ) ) { + return $tax_meta[ 'wpseo_' . $meta ]; + } + + return false; + } + + /** + * Get the current queried object and return the meta value. + * + * @param string $meta The meta field that is needed. + * + * @return mixed + */ + public static function get_meta_without_term( $meta ) { + $term = $GLOBALS['wp_query']->get_queried_object(); + if ( ! $term || empty( $term->taxonomy ) ) { + return false; + } + + return self::get_term_meta( $term, $term->taxonomy, $meta ); + } + + /** + * Saving the values for the given term_id. + * + * @param int $term_id ID of the term to save data for. + * @param string $taxonomy The taxonomy the term belongs to. + * @param array $meta_values The values that will be saved. + * + * @return void + */ + public static function set_values( $term_id, $taxonomy, array $meta_values ) { + /* Validate the post values */ + $old = self::get_term_meta( $term_id, $taxonomy ); + $clean = self::validate_term_meta_data( $meta_values, $old ); + + self::save_clean_values( $term_id, $taxonomy, $clean ); + } + + /** + * Setting a single value to the term meta. + * + * @param int $term_id ID of the term to save data for. + * @param string $taxonomy The taxonomy the term belongs to. + * @param string $meta_key The target meta key to store the value in. + * @param string $meta_value The value of the target meta key. + * + * @return void + */ + public static function set_value( $term_id, $taxonomy, $meta_key, $meta_value ) { + + if ( substr( strtolower( $meta_key ), 0, 6 ) !== 'wpseo_' ) { + $meta_key = 'wpseo_' . $meta_key; + } + + self::set_values( $term_id, $taxonomy, [ $meta_key => $meta_value ] ); + } + + /** + * Find the keyword usages in the metas for the taxonomies/terms. + * + * @param string $keyword The keyword to look for. + * @param string $current_term_id The current term id. + * @param string $current_taxonomy The current taxonomy name. + * + * @return array + */ + public static function get_keyword_usage( $keyword, $current_term_id, $current_taxonomy ) { + $tax_meta = self::get_tax_meta(); + + $found = []; + // @todo Check for terms of all taxonomies, not only the current taxonomy. + foreach ( $tax_meta as $taxonomy_name => $terms ) { + foreach ( $terms as $term_id => $meta_values ) { + $is_current = ( $current_taxonomy === $taxonomy_name && (string) $current_term_id === (string) $term_id ); + if ( ! $is_current && ! empty( $meta_values['wpseo_focuskw'] ) && $meta_values['wpseo_focuskw'] === $keyword ) { + $found[] = $term_id; + } + } + } + + return [ $keyword => $found ]; + } + + /** + * Saving the values for the given term_id. + * + * @param int $term_id ID of the term to save data for. + * @param string $taxonomy The taxonomy the term belongs to. + * @param array $clean Array with clean values. + * + * @return void + */ + private static function save_clean_values( $term_id, $taxonomy, array $clean ) { + $tax_meta = self::get_tax_meta(); + + /* Add/remove the result to/from the original option value. */ + if ( $clean !== [] ) { + $tax_meta[ $taxonomy ][ $term_id ] = $clean; + } + else { + unset( $tax_meta[ $taxonomy ][ $term_id ] ); + if ( isset( $tax_meta[ $taxonomy ] ) && $tax_meta[ $taxonomy ] === [] ) { + unset( $tax_meta[ $taxonomy ] ); + } + } + + // Prevent complete array validation. + $tax_meta['wpseo_already_validated'] = true; + + self::save_tax_meta( $tax_meta ); + } + + /** + * Getting the meta from the options. + * + * @return array|void + */ + private static function get_tax_meta() { + return get_option( self::$name ); + } + + /** + * Saving the tax meta values to the database. + * + * @param array $tax_meta Array with the meta values for taxonomy. + * + * @return void + */ + private static function save_tax_meta( $tax_meta ) { + update_option( self::$name, $tax_meta ); + } + + /** + * Getting the taxonomy meta for the given term_id and taxonomy. + * + * @param int $term_id The id of the term. + * @param string $taxonomy Name of the taxonomy to which the term is attached. + * + * @return array + */ + private static function get_term_tax_meta( $term_id, $taxonomy ) { + $tax_meta = self::get_tax_meta(); + + /* If we have data for the term, merge with defaults for complete array, otherwise set defaults. */ + if ( isset( $tax_meta[ $taxonomy ][ $term_id ] ) ) { + return array_merge( self::$defaults_per_term, $tax_meta[ $taxonomy ][ $term_id ] ); + } + + return self::$defaults_per_term; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-author-sitemap-provider.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-author-sitemap-provider.php new file mode 100644 index 0000000..343f97b --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-author-sitemap-provider.php @@ -0,0 +1,244 @@ +handles_type( 'author' ) ) { + return []; + } + + // @todo Consider doing this less often / when necessary. R. + $this->update_user_meta(); + + $has_exclude_filter = has_filter( 'wpseo_sitemap_exclude_author' ); + + $query_arguments = []; + + if ( ! $has_exclude_filter ) { // We only need full users if legacy filter(s) hooked to exclusion logic. R. + $query_arguments['fields'] = 'ID'; + } + + $users = $this->get_users( $query_arguments ); + + if ( $has_exclude_filter ) { + $users = $this->exclude_users( $users ); + $users = wp_list_pluck( $users, 'ID' ); + } + + if ( empty( $users ) ) { + return []; + } + + $index = []; + $user_pages = array_chunk( $users, $max_entries ); + + foreach ( $user_pages as $page_counter => $users_page ) { + + $current_page = ( $page_counter === 0 ) ? '' : ( $page_counter + 1 ); + + $user_id = array_shift( $users_page ); // Time descending, first user on page is most recently updated. + $user = get_user_by( 'id', $user_id ); + $index[] = [ + 'loc' => WPSEO_Sitemaps_Router::get_base_url( 'author-sitemap' . $current_page . '.xml' ), + 'lastmod' => ( $user->_yoast_wpseo_profile_updated ) ? YoastSEO()->helpers->date->format_timestamp( $user->_yoast_wpseo_profile_updated ) : null, + ]; + } + + return $index; + } + + /** + * Retrieve users, taking account of all necessary exclusions. + * + * @param array $arguments Arguments to add. + * + * @return array + */ + protected function get_users( $arguments = [] ) { + + global $wpdb; + + $defaults = [ + 'capability' => [ 'edit_posts' ], + 'meta_key' => '_yoast_wpseo_profile_updated', + 'orderby' => 'meta_value_num', + 'order' => 'DESC', + 'meta_query' => [ + 'relation' => 'AND', + [ + 'key' => $wpdb->get_blog_prefix() . 'user_level', + 'value' => '0', + 'compare' => '!=', + ], + [ + 'relation' => 'OR', + [ + 'key' => 'wpseo_noindex_author', + 'value' => 'on', + 'compare' => '!=', + ], + [ + 'key' => 'wpseo_noindex_author', + 'compare' => 'NOT EXISTS', + ], + ], + ], + ]; + + if ( WPSEO_Options::get( 'noindex-author-noposts-wpseo', true ) ) { + unset( $defaults['capability'] ); // Otherwise it cancels out next argument. + $defaults['has_published_posts'] = YoastSEO()->helpers->author_archive->get_author_archive_post_types(); + } + + return get_users( array_merge( $defaults, $arguments ) ); + } + + /** + * Get set of sitemap link data. + * + * @param string $type Sitemap type. + * @param int $max_entries Entries per sitemap. + * @param int $current_page Current page of the sitemap. + * + * @return array + * + * @throws OutOfBoundsException When an invalid page is requested. + */ + public function get_sitemap_links( $type, $max_entries, $current_page ) { + + $links = []; + + if ( ! $this->handles_type( 'author' ) ) { + return $links; + } + + $user_criteria = [ + 'offset' => ( ( $current_page - 1 ) * $max_entries ), + 'number' => $max_entries, + ]; + + $users = $this->get_users( $user_criteria ); + + // Throw an exception when there are no users in the sitemap. + if ( count( $users ) === 0 ) { + throw new OutOfBoundsException( 'Invalid sitemap page requested' ); + } + + $users = $this->exclude_users( $users ); + if ( empty( $users ) ) { + $users = []; + } + + $time = time(); + + foreach ( $users as $user ) { + + $author_link = get_author_posts_url( $user->ID ); + + if ( empty( $author_link ) ) { + continue; + } + + $mod = $time; + + if ( isset( $user->_yoast_wpseo_profile_updated ) ) { + $mod = $user->_yoast_wpseo_profile_updated; + } + + $url = [ + 'loc' => $author_link, + 'mod' => date( DATE_W3C, $mod ), + + // Deprecated, kept for backwards data compat. R. + 'chf' => 'daily', + 'pri' => 1, + ]; + + /** This filter is documented at inc/sitemaps/class-post-type-sitemap-provider.php */ + $url = apply_filters( 'wpseo_sitemap_entry', $url, 'user', $user ); + + if ( ! empty( $url ) ) { + $links[] = $url; + } + } + + return $links; + } + + /** + * Update any users that don't have last profile update timestamp. + * + * @return int Count of users updated. + */ + protected function update_user_meta() { + + $user_criteria = [ + 'capability' => [ 'edit_posts' ], + 'meta_query' => [ + [ + 'key' => '_yoast_wpseo_profile_updated', + 'compare' => 'NOT EXISTS', + ], + ], + ]; + + $users = get_users( $user_criteria ); + + $time = time(); + + foreach ( $users as $user ) { + update_user_meta( $user->ID, '_yoast_wpseo_profile_updated', $time ); + } + + return count( $users ); + } + + /** + * Wrap legacy filter to deduplicate calls. + * + * @param array $users Array of user objects to filter. + * + * @return array + */ + protected function exclude_users( $users ) { + + /** + * Filter the authors, included in XML sitemap. + * + * @param array $users Array of user objects to filter. + */ + return apply_filters( 'wpseo_sitemap_exclude_author', $users ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-post-type-sitemap-provider.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-post-type-sitemap-provider.php new file mode 100644 index 0000000..a621464 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-post-type-sitemap-provider.php @@ -0,0 +1,766 @@ +include_images = apply_filters( 'wpseo_xml_sitemap_include_images', true ); + } + + /** + * Get the Image Parser. + * + * @return WPSEO_Sitemap_Image_Parser + */ + protected function get_image_parser() { + if ( ! isset( self::$image_parser ) ) { + self::$image_parser = new WPSEO_Sitemap_Image_Parser(); + } + + return self::$image_parser; + } + + /** + * Gets the parsed home url. + * + * @return array The home url, as parsed by wp_parse_url. + */ + protected function get_parsed_home_url() { + if ( ! isset( self::$parsed_home_url ) ) { + self::$parsed_home_url = wp_parse_url( home_url() ); + } + + return self::$parsed_home_url; + } + + /** + * Check if provider supports given item type. + * + * @param string $type Type string to check for. + * + * @return bool + */ + public function handles_type( $type ) { + + return post_type_exists( $type ); + } + + /** + * Retrieves the sitemap links. + * + * @param int $max_entries Entries per sitemap. + * + * @return array + */ + public function get_index_links( $max_entries ) { + global $wpdb; + $post_types = WPSEO_Post_Type::get_accessible_post_types(); + $post_types = array_filter( $post_types, [ $this, 'is_valid_post_type' ] ); + $last_modified_times = WPSEO_Sitemaps::get_last_modified_gmt( $post_types, true ); + $index = []; + + foreach ( $post_types as $post_type ) { + + $total_count = $this->get_post_type_count( $post_type ); + + if ( $total_count === 0 ) { + continue; + } + + $max_pages = 1; + if ( $total_count > $max_entries ) { + $max_pages = (int) ceil( $total_count / $max_entries ); + } + + $all_dates = []; + + if ( $max_pages > 1 ) { + $all_dates = version_compare( $wpdb->db_version(), '8.0', '>=' ) ? $this->get_all_dates_using_with_clause( $post_type, $max_entries ) : $this->get_all_dates( $post_type, $max_entries ); + } + + for ( $page_counter = 0; $page_counter < $max_pages; $page_counter++ ) { + + $current_page = ( $page_counter === 0 ) ? '' : ( $page_counter + 1 ); + $date = false; + + if ( empty( $current_page ) || $current_page === $max_pages ) { + + if ( ! empty( $last_modified_times[ $post_type ] ) ) { + $date = $last_modified_times[ $post_type ]; + } + } + else { + $date = $all_dates[ $page_counter ]; + } + + $index[] = [ + 'loc' => WPSEO_Sitemaps_Router::get_base_url( $post_type . '-sitemap' . $current_page . '.xml' ), + 'lastmod' => $date, + ]; + } + } + + return $index; + } + + /** + * Get set of sitemap link data. + * + * @param string $type Sitemap type. + * @param int $max_entries Entries per sitemap. + * @param int $current_page Current page of the sitemap. + * + * @return array + * + * @throws OutOfBoundsException When an invalid page is requested. + */ + public function get_sitemap_links( $type, $max_entries, $current_page ) { + + $links = []; + $post_type = $type; + + if ( ! $this->is_valid_post_type( $post_type ) ) { + throw new OutOfBoundsException( 'Invalid sitemap page requested' ); + } + + $steps = min( 100, $max_entries ); + $offset = ( $current_page > 1 ) ? ( ( $current_page - 1 ) * $max_entries ) : 0; + $total = ( $offset + $max_entries ); + + $post_type_entries = $this->get_post_type_count( $post_type ); + + if ( $total > $post_type_entries ) { + $total = $post_type_entries; + } + + if ( $current_page === 1 ) { + $links = array_merge( $links, $this->get_first_links( $post_type ) ); + } + + // If total post type count is lower than the offset, an invalid page is requested. + if ( $post_type_entries < $offset ) { + throw new OutOfBoundsException( 'Invalid sitemap page requested' ); + } + + if ( $post_type_entries === 0 ) { + return $links; + } + + $posts_to_exclude = $this->get_excluded_posts( $type ); + + while ( $total > $offset ) { + + $posts = $this->get_posts( $post_type, $steps, $offset ); + + $offset += $steps; + + if ( empty( $posts ) ) { + continue; + } + + foreach ( $posts as $post ) { + + if ( in_array( $post->ID, $posts_to_exclude, true ) ) { + continue; + } + + if ( WPSEO_Meta::get_value( 'meta-robots-noindex', $post->ID ) === '1' ) { + continue; + } + + $url = $this->get_url( $post ); + + if ( ! isset( $url['loc'] ) ) { + continue; + } + + /** + * Filter URL entry before it gets added to the sitemap. + * + * @param array $url Array of URL parts. + * @param string $type URL type. + * @param object $post Data object for the URL. + */ + $url = apply_filters( 'wpseo_sitemap_entry', $url, 'post', $post ); + + if ( ! empty( $url ) ) { + $links[] = $url; + } + } + + unset( $post, $url ); + } + + return $links; + } + + /** + * Check for relevant post type before invalidation. + * + * @param int $post_id Post ID to possibly invalidate for. + * + * @return void + */ + public function save_post( $post_id ) { + + if ( $this->is_valid_post_type( get_post_type( $post_id ) ) ) { + WPSEO_Sitemaps_Cache::invalidate_post( $post_id ); + } + } + + /** + * Check if post type should be present in sitemaps. + * + * @param string $post_type Post type string to check for. + * + * @return bool + */ + public function is_valid_post_type( $post_type ) { + if ( ! WPSEO_Post_Type::is_post_type_accessible( $post_type ) || ! WPSEO_Post_Type::is_post_type_indexable( $post_type ) ) { + return false; + } + + /** + * Filter decision if post type is excluded from the XML sitemap. + * + * @param bool $exclude Default false. + * @param string $post_type Post type name. + */ + if ( apply_filters( 'wpseo_sitemap_exclude_post_type', false, $post_type ) ) { + return false; + } + + return true; + } + + /** + * Retrieves a list with the excluded post ids. + * + * @param string $post_type Post type. + * + * @return array Array with post ids to exclude. + */ + protected function get_excluded_posts( $post_type ) { + $excluded_posts_ids = []; + + $page_on_front_id = ( $post_type === 'page' ) ? (int) get_option( 'page_on_front' ) : 0; + if ( $page_on_front_id > 0 ) { + $excluded_posts_ids[] = $page_on_front_id; + } + + /** + * Filter: 'wpseo_exclude_from_sitemap_by_post_ids' - Allow extending and modifying the posts to exclude. + * + * @param array $posts_to_exclude The posts to exclude. + */ + $excluded_posts_ids = apply_filters( 'wpseo_exclude_from_sitemap_by_post_ids', $excluded_posts_ids ); + if ( ! is_array( $excluded_posts_ids ) ) { + $excluded_posts_ids = []; + } + + $excluded_posts_ids = array_map( 'intval', $excluded_posts_ids ); + + $page_for_posts_id = ( $post_type === 'page' ) ? (int) get_option( 'page_for_posts' ) : 0; + if ( $page_for_posts_id > 0 ) { + $excluded_posts_ids[] = $page_for_posts_id; + } + + return array_unique( $excluded_posts_ids ); + } + + /** + * Get count of posts for post type. + * + * @param string $post_type Post type to retrieve count for. + * + * @return int + */ + protected function get_post_type_count( $post_type ) { + + global $wpdb; + + /** + * Filter JOIN query part for type count of post type. + * + * @param string $join SQL part, defaults to empty string. + * @param string $post_type Post type name. + */ + $join_filter = apply_filters( 'wpseo_typecount_join', '', $post_type ); + + /** + * Filter WHERE query part for type count of post type. + * + * @param string $where SQL part, defaults to empty string. + * @param string $post_type Post type name. + */ + $where_filter = apply_filters( 'wpseo_typecount_where', '', $post_type ); + + $where = $this->get_sql_where_clause( $post_type ); + + $sql = " + SELECT COUNT({$wpdb->posts}.ID) + FROM {$wpdb->posts} + {$join_filter} + {$where} + {$where_filter} + "; + + return (int) $wpdb->get_var( $sql ); + } + + /** + * Produces set of links to prepend at start of first sitemap page. + * + * @param string $post_type Post type to produce links for. + * + * @return array + */ + protected function get_first_links( $post_type ) { + + $links = []; + $archive_url = false; + + if ( $post_type === 'page' ) { + + $page_on_front_id = (int) get_option( 'page_on_front' ); + if ( $page_on_front_id > 0 ) { + $front_page = $this->get_url( + get_post( $page_on_front_id ), + ); + } + + if ( empty( $front_page ) ) { + $front_page = [ + 'loc' => YoastSEO()->helpers->url->home(), + ]; + } + + // Deprecated, kept for backwards data compat. R. + $front_page['chf'] = 'daily'; + $front_page['pri'] = 1; + + $images = ( $front_page['images'] ?? [] ); + + /** + * Filter images to be included for the term in XML sitemap. + * + * @param array $images Array of image items. + * @return array $image_list Array of image items. + */ + $image_list = apply_filters( 'wpseo_sitemap_urlimages_front_page', $images ); + if ( is_array( $image_list ) ) { + $front_page['images'] = $image_list; + } + + $links[] = $front_page; + } + elseif ( $post_type !== 'page' ) { + /** + * Filter the URL Yoast SEO uses in the XML sitemap for this post type archive. + * + * @param string $archive_url The URL of this archive + * @param string $post_type The post type this archive is for. + */ + $archive_url = apply_filters( + 'wpseo_sitemap_post_type_archive_link', + $this->get_post_type_archive_link( $post_type ), + $post_type, + ); + } + + if ( $archive_url ) { + + $links[] = [ + 'loc' => $archive_url, + 'mod' => WPSEO_Sitemaps::get_last_modified_gmt( $post_type ), + + // Deprecated, kept for backwards data compat. R. + 'chf' => 'daily', + 'pri' => 1, + ]; + } + + /** + * Filters the first post type links. + * + * @param array $links The first post type links. + * @param string $post_type The post type this archive is for. + */ + return apply_filters( 'wpseo_sitemap_post_type_first_links', $links, $post_type ); + } + + /** + * Get URL for a post type archive. + * + * @since 5.3 + * + * @param string $post_type Post type. + * + * @return string|bool URL or false if it should be excluded. + */ + protected function get_post_type_archive_link( $post_type ) { + + $pt_archive_page_id = -1; + + if ( $post_type === 'post' ) { + + if ( get_option( 'show_on_front' ) === 'posts' ) { + return YoastSEO()->helpers->url->home(); + } + + $pt_archive_page_id = (int) get_option( 'page_for_posts' ); + + // Post archive should be excluded if posts page isn't set. + if ( $pt_archive_page_id <= 0 ) { + return false; + } + } + + if ( ! $this->is_post_type_archive_indexable( $post_type, $pt_archive_page_id ) ) { + return false; + } + + return get_post_type_archive_link( $post_type ); + } + + /** + * Determines whether a post type archive is indexable. + * + * @since 11.5 + * + * @param string $post_type Post type. + * @param int $archive_page_id The page id. + * + * @return bool True when post type archive is indexable. + */ + protected function is_post_type_archive_indexable( $post_type, $archive_page_id = -1 ) { + + if ( WPSEO_Options::get( 'noindex-ptarchive-' . $post_type, false ) ) { + return false; + } + + /** + * Filter the page which is dedicated to this post type archive. + * + * @since 9.3 + * + * @param string $archive_page_id The post_id of the page. + * @param string $post_type The post type this archive is for. + */ + $archive_page_id = (int) apply_filters( 'wpseo_sitemap_page_for_post_type_archive', $archive_page_id, $post_type ); + + if ( $archive_page_id > 0 && WPSEO_Meta::get_value( 'meta-robots-noindex', $archive_page_id ) === '1' ) { + return false; + } + + return true; + } + + /** + * Retrieve set of posts with optimized query routine. + * + * @param string $post_type Post type to retrieve. + * @param int $count Count of posts to retrieve. + * @param int $offset Starting offset. + * + * @return object[] + */ + protected function get_posts( $post_type, $count, $offset ) { + + global $wpdb; + + static $filters = []; + + if ( ! isset( $filters[ $post_type ] ) ) { + // Make sure you're wpdb->preparing everything you throw into this!! + $filters[ $post_type ] = [ + /** + * Filter JOIN query part for the post type. + * + * @param string $join SQL part, defaults to false. + * @param string $post_type Post type name. + */ + 'join' => apply_filters( 'wpseo_posts_join', false, $post_type ), + + /** + * Filter WHERE query part for the post type. + * + * @param string $where SQL part, defaults to false. + * @param string $post_type Post type name. + */ + 'where' => apply_filters( 'wpseo_posts_where', false, $post_type ), + ]; + } + + $join_filter = $filters[ $post_type ]['join']; + $where_filter = $filters[ $post_type ]['where']; + $where = $this->get_sql_where_clause( $post_type ); + + /* + * Optimized query per this thread: + * {@link http://wordpress.org/support/topic/plugin-wordpress-seo-by-yoast-performance-suggestion}. + * Also see {@link http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/}. + */ + $sql = " + SELECT l.ID, post_title, post_content, post_name, post_parent, post_author, post_status, post_modified_gmt, post_date, post_date_gmt + FROM ( + SELECT {$wpdb->posts}.ID + FROM {$wpdb->posts} + {$join_filter} + {$where} + {$where_filter} + ORDER BY {$wpdb->posts}.post_modified ASC LIMIT %d OFFSET %d + ) + o JOIN {$wpdb->posts} l ON l.ID = o.ID + "; + + $posts = $wpdb->get_results( $wpdb->prepare( $sql, $count, $offset ) ); + + $post_ids = []; + + foreach ( $posts as $post_index => $post ) { + $post->post_type = $post_type; + $sanitized_post = sanitize_post( $post, 'raw' ); + $posts[ $post_index ] = new WP_Post( $sanitized_post ); + + $post_ids[] = $sanitized_post->ID; + } + + update_meta_cache( 'post', $post_ids ); + + return $posts; + } + + /** + * Constructs an SQL where clause for a given post type. + * + * @param string $post_type Post type slug. + * + * @return string + */ + protected function get_sql_where_clause( $post_type ) { + + global $wpdb; + + $join = ''; + $post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) ); + $status_where = "{$wpdb->posts}.post_status IN ('" . implode( "','", $post_statuses ) . "')"; + + // Based on WP_Query->get_posts(). R. + if ( $post_type === 'attachment' ) { + $join = " LEFT JOIN {$wpdb->posts} AS p2 ON ({$wpdb->posts}.post_parent = p2.ID) "; + $parent_statuses = array_diff( $post_statuses, [ 'inherit' ] ); + $status_where = "p2.post_status IN ('" . implode( "','", $parent_statuses ) . "') AND p2.post_password = ''"; + } + + $where_clause = " + {$join} + WHERE {$status_where} + AND {$wpdb->posts}.post_type = %s + AND {$wpdb->posts}.post_password = '' + AND {$wpdb->posts}.post_date != '0000-00-00 00:00:00' + "; + + return $wpdb->prepare( $where_clause, $post_type ); + } + + /** + * Produce array of URL parts for given post object. + * + * @param object $post Post object to get URL parts for. + * + * @return array|bool + */ + protected function get_url( $post ) { + + $url = []; + + /** + * Filter the URL Yoast SEO uses in the XML sitemap. + * + * Note that only absolute local URLs are allowed as the check after this removes external URLs. + * + * @param string $url URL to use in the XML sitemap + * @param object $post Post object for the URL. + */ + $url['loc'] = apply_filters( 'wpseo_xml_sitemap_post_url', get_permalink( $post ), $post ); + $link_type = YoastSEO()->helpers->url->get_link_type( + wp_parse_url( $url['loc'] ), + $this->get_parsed_home_url(), + ); + + /* + * Do not include external URLs. + * + * {@link https://wordpress.org/plugins/page-links-to/} can rewrite permalinks to external URLs. + */ + if ( $link_type === SEO_Links::TYPE_EXTERNAL ) { + return false; + } + + $modified = max( $post->post_modified_gmt, $post->post_date_gmt ); + + if ( $modified !== '0000-00-00 00:00:00' ) { + $url['mod'] = $modified; + } + + $url['chf'] = 'daily'; // Deprecated, kept for backwards data compat. R. + + $canonical = WPSEO_Meta::get_value( 'canonical', $post->ID ); + + if ( $canonical !== '' && $canonical !== $url['loc'] ) { + /* + * Let's assume that if a canonical is set for this page and it's different from + * the URL of this post, that page is either already in the XML sitemap OR is on + * an external site, either way, we shouldn't include it here. + */ + return false; + } + unset( $canonical ); + + $url['pri'] = 1; // Deprecated, kept for backwards data compat. R. + + if ( $this->include_images ) { + $url['images'] = $this->get_image_parser()->get_images( $post ); + } + + return $url; + } + + /** + * Get all dates for a post type by using the WITH clause for performance. + * + * @param string $post_type Post type to retrieve dates for. + * @param int $max_entries Maximum number of entries to retrieve. + * + * @return array Array of dates. + */ + private function get_all_dates_using_with_clause( $post_type, $max_entries ) { + global $wpdb; + + $post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) ); + + $replacements = array_merge( + [ + 'ordering', + 'post_modified_gmt', + $wpdb->posts, + 'type_status_date', + 'post_status', + ], + $post_statuses, + [ + 'post_type', + $post_type, + 'post_modified_gmt', + 'post_modified_gmt', + 'ordering', + $max_entries, + ], + ); + + //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here. + //phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + return $wpdb->get_col( + //phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized. + $wpdb->prepare( + ' + WITH %i AS (SELECT ROW_NUMBER() OVER (ORDER BY %i) AS n, post_modified_gmt + FROM %i USE INDEX ( %i ) + WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ') + AND %i = %s + ORDER BY %i) + SELECT %i + FROM %i + WHERE MOD(n, %d) = 0; + ', + $replacements, + ), + ); + } + + /** + * Get all dates for a post type. + * + * @param string $post_type Post type to retrieve dates for. + * @param int $max_entries Maximum number of entries to retrieve. + * + * @return array Array of dates. + */ + private function get_all_dates( $post_type, $max_entries ) { + global $wpdb; + + $post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses( $post_type ) ); + $replacements = array_merge( + [ + 'post_modified_gmt', + $wpdb->posts, + 'type_status_date', + 'post_status', + ], + $post_statuses, + [ + 'post_type', + $post_type, + $max_entries, + 'post_modified_gmt', + ], + ); + + return $wpdb->get_col( + //phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized. + $wpdb->prepare( + ' + SELECT %i + FROM ( SELECT @rownum:=0 ) init + JOIN %i USE INDEX( %i ) + WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ') + AND %i = %s + AND ( @rownum:=@rownum+1 ) %% %d = 0 + ORDER BY %i ASC + ', + $replacements, + ), + ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemap-cache-data.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemap-cache-data.php new file mode 100644 index 0000000..495afa1 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemap-cache-data.php @@ -0,0 +1,200 @@ +sitemap = $sitemap; + + /* + * Empty sitemap is not usable. + */ + if ( ! empty( $sitemap ) ) { + $this->set_status( self::OK ); + } + else { + $this->set_status( self::ERROR ); + } + } + + /** + * Set the status of the sitemap, is it usable. + * + * @param bool|string $usable Is the sitemap usable or not. + * + * @return void + */ + public function set_status( $usable ) { + + if ( $usable === self::OK ) { + $this->status = self::OK; + + return; + } + + if ( $usable === self::ERROR ) { + $this->status = self::ERROR; + $this->sitemap = ''; + + return; + } + + $this->status = self::UNKNOWN; + } + + /** + * Is the sitemap usable. + * + * @return bool True if usable, False if bad or unknown. + */ + public function is_usable() { + + return $this->status === self::OK; + } + + /** + * Get the XML content of the sitemap. + * + * @return string The content of the sitemap. + */ + public function get_sitemap() { + + return $this->sitemap; + } + + /** + * Get the status of the sitemap. + * + * @return string Status of the sitemap, 'ok'/'error'/'unknown'. + */ + public function get_status() { + + return $this->status; + } + + /** + * String representation of object. + * + * {@internal This magic method is only "magic" as of PHP 7.4 in which the magic method was introduced.} + * + * @link https://www.php.net/language.oop5.magic#object.serialize + * @link https://wiki.php.net/rfc/custom_object_serialization + * + * @since 17.8.0 + * + * @return array The data to be serialized. + */ + public function __serialize() { // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__serializeFound + + $data = [ + 'status' => $this->status, + 'xml' => $this->sitemap, + ]; + + return $data; + } + + /** + * Constructs the object. + * + * {@internal This magic method is only "magic" as of PHP 7.4 in which the magic method was introduced.} + * + * @link https://www.php.net/language.oop5.magic#object.serialize + * @link https://wiki.php.net/rfc/custom_object_serialization + * + * @since 17.8.0 + * + * @param array $data The unserialized data to use to (re)construct the object. + * + * @return void + */ + public function __unserialize( $data ) { // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound + + $this->set_sitemap( $data['xml'] ); + $this->set_status( $data['status'] ); + } + + /** + * String representation of object. + * + * {@internal The magic methods take precedence over the Serializable interface. + * This means that in practice, this method will now only be called on PHP < 7.4. + * For PHP 7.4 and higher, the magic methods will be used instead.} + * + * {@internal The Serializable interface is being phased out, in favour of the magic methods. + * This method should be deprecated and removed and the class should no longer + * implement the `Serializable` interface. + * This change, however, can't be made until the minimum PHP version goes up to PHP 7.4 or higher.} + * + * @link http://php.net/manual/en/serializable.serialize.php + * @link https://wiki.php.net/rfc/phase_out_serializable + * + * @since 5.1.0 + * + * @return string The string representation of the object or null in C-format. + */ + public function serialize() { + + return serialize( $this->__serialize() ); + } + + /** + * Constructs the object. + * + * {@internal The magic methods take precedence over the Serializable interface. + * This means that in practice, this method will now only be called on PHP < 7.4. + * For PHP 7.4 and higher, the magic methods will be used instead.} + * + * {@internal The Serializable interface is being phased out, in favour of the magic methods. + * This method should be deprecated and removed and the class should no longer + * implement the `Serializable` interface. + * This change, however, can't be made until the minimum PHP version goes up to PHP 7.4 or higher.} + * + * @link http://php.net/manual/en/serializable.unserialize.php + * @link https://wiki.php.net/rfc/phase_out_serializable + * + * @since 5.1.0 + * + * @param string $data The string representation of the object in C or O-format. + * + * @return void + */ + public function unserialize( $data ) { + + $data = unserialize( $data ); + $this->__unserialize( $data ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemap-image-parser.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemap-image-parser.php new file mode 100644 index 0000000..1a88399 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemap-image-parser.php @@ -0,0 +1,509 @@ +home_url = home_url(); + $parsed_home = wp_parse_url( $this->home_url ); + + if ( ! empty( $parsed_home['host'] ) ) { + $this->host = str_replace( 'www.', '', $parsed_home['host'] ); + } + + if ( ! empty( $parsed_home['scheme'] ) ) { + $this->scheme = $parsed_home['scheme']; + } + + $this->charset = esc_attr( get_bloginfo( 'charset' ) ); + } + + /** + * Get set of image data sets for the given post. + * + * @param object $post Post object to get images for. + * + * @return array + */ + public function get_images( $post ) { + + $images = []; + + if ( ! is_object( $post ) ) { + return $images; + } + + $thumbnail_id = get_post_thumbnail_id( $post->ID ); + + if ( $thumbnail_id ) { + + $src = $this->get_absolute_url( $this->image_url( $thumbnail_id ) ); + $images[] = $this->get_image_item( $post, $src ); + } + + /** + * Filter: 'wpseo_sitemap_content_before_parse_html_images' - Filters the post content + * before it is parsed for images. + * + * @param string $content The raw/unprocessed post content. + */ + $content = apply_filters( 'wpseo_sitemap_content_before_parse_html_images', $post->post_content ); + + $unfiltered_images = $this->parse_html_images( $content ); + + foreach ( $unfiltered_images as $image ) { + $images[] = $this->get_image_item( $post, $image['src'] ); + } + + foreach ( $this->parse_galleries( $content, $post->ID ) as $attachment ) { + $src = $this->get_absolute_url( $this->image_url( $attachment->ID ) ); + $images[] = $this->get_image_item( $post, $src ); + } + + if ( $post->post_type === 'attachment' && wp_attachment_is_image( $post ) ) { + $src = $this->get_absolute_url( $this->image_url( $post->ID ) ); + $images[] = $this->get_image_item( $post, $src ); + } + + foreach ( $images as $key => $image ) { + + if ( empty( $image['src'] ) ) { + unset( $images[ $key ] ); + } + } + + /** + * Filter images to be included for the post in XML sitemap. + * + * @param array $images Array of image items. + * @param int $post_id ID of the post. + */ + $image_list = apply_filters( 'wpseo_sitemap_urlimages', $images, $post->ID ); + if ( isset( $image_list ) && is_array( $image_list ) ) { + $images = $image_list; + } + + return $images; + } + + /** + * Get the images in the term description. + * + * @param object $term Term to get images from description for. + * + * @return array + */ + public function get_term_images( $term ) { + + $images = $this->parse_html_images( $term->description ); + + foreach ( $this->parse_galleries( $term->description ) as $attachment ) { + + $images[] = [ + 'src' => $this->get_absolute_url( $this->image_url( $attachment->ID ) ), + ]; + } + + /** + * Filter images to be included for the term in XML sitemap. + * + * @param array $image_list Array of image items. + * @param int $term_id ID of the post. + */ + $image_list = apply_filters( 'wpseo_sitemap_urlimages_term', $images, $term->term_id ); + if ( isset( $image_list ) && is_array( $image_list ) ) { + $images = $image_list; + } + + return $images; + } + + /** + * Parse `` tags in content. + * + * @param string $content Content string to parse. + * + * @return array + */ + private function parse_html_images( $content ) { + + $images = []; + + if ( ! class_exists( 'DOMDocument' ) ) { + return $images; + } + + if ( empty( $content ) ) { + return $images; + } + + // Prevent DOMDocument from bubbling warnings about invalid HTML. + libxml_use_internal_errors( true ); + + $post_dom = new DOMDocument(); + $post_dom->loadHTML( 'charset . '">' . $content ); + + // Clear the errors, so they don't get kept in memory. + libxml_clear_errors(); + + /** + * Image attribute. + * + * @var DOMElement $img + */ + foreach ( $post_dom->getElementsByTagName( 'img' ) as $img ) { + + $src = $img->getAttribute( 'src' ); + + if ( empty( $src ) ) { + continue; + } + + $class = $img->getAttribute( 'class' ); + + if ( // This detects WP-inserted images, which we need to upsize. R. + ! empty( $class ) + && ( strpos( $class, 'size-full' ) === false ) + && preg_match( '|wp-image-(?P\d+)|', $class, $matches ) + && get_post_status( $matches['id'] ) + ) { + $query_params = wp_parse_url( $src, PHP_URL_QUERY ); + $src = $this->image_url( $matches['id'] ); + + if ( $query_params ) { + $src .= '?' . $query_params; + } + } + + $src = $this->get_absolute_url( $src ); + + if ( strpos( $src, $this->host ) === false ) { + continue; + } + + if ( $src !== esc_url( $src, null, 'attribute' ) ) { + continue; + } + + $images[] = [ + 'src' => $src, + ]; + } + + return $images; + } + + /** + * Parse gallery shortcodes in a given content. + * + * @param string $content Content string. + * @param int $post_id Optional. ID of post being parsed. + * + * @return array Set of attachment objects. + */ + protected function parse_galleries( $content, $post_id = 0 ) { + + $attachments = []; + $galleries = $this->get_content_galleries( $content ); + + foreach ( $galleries as $gallery ) { + + $id = $post_id; + + if ( ! empty( $gallery['id'] ) ) { + $id = (int) $gallery['id']; + } + + // Forked from core gallery_shortcode() to have exact same logic. R. + if ( ! empty( $gallery['ids'] ) ) { + $gallery['include'] = $gallery['ids']; + } + + $gallery_attachments = $this->get_gallery_attachments( $id, $gallery ); + + $attachments = array_merge( $attachments, $gallery_attachments ); + } + + return array_unique( $attachments, SORT_REGULAR ); + } + + /** + * Retrieves galleries from the passed content. + * + * Forked from core to skip executing shortcodes for performance. + * + * @param string $content Content to parse for shortcodes. + * + * @return array A list of arrays, each containing gallery data. + */ + protected function get_content_galleries( $content ) { + + $galleries = []; + + if ( ! preg_match_all( '/' . get_shortcode_regex( [ 'gallery' ] ) . '/s', $content, $matches, PREG_SET_ORDER ) ) { + return $galleries; + } + + foreach ( $matches as $shortcode ) { + + $attributes = shortcode_parse_atts( $shortcode[3] ); + + if ( $attributes === '' ) { // Valid shortcode without any attributes. R. + $attributes = []; + } + + $galleries[] = $attributes; + } + + return $galleries; + } + + /** + * Get image item array with filters applied. + * + * @param WP_Post $post Post object for the context. + * @param string $src Image URL. + * + * @return array + */ + protected function get_image_item( $post, $src ) { + + $image = []; + + /** + * Filter image URL to be included in XML sitemap for the post. + * + * @param string $src Image URL. + * @param object $post Post object. + */ + $image['src'] = apply_filters( 'wpseo_xml_sitemap_img_src', $src, $post ); + + /** + * Filter image data to be included in XML sitemap for the post. + * + * @param array $image { + * Array of image data. + * + * @type string $src Image URL. + * } + * + * @param object $post Post object. + */ + return apply_filters( 'wpseo_xml_sitemap_img', $image, $post ); + } + + /** + * Get attached image URL with filters applied. Adapted from core for speed. + * + * @param int $post_id ID of the post. + * + * @return string + */ + private function image_url( $post_id ) { + + static $uploads; + + if ( empty( $uploads ) ) { + $uploads = wp_upload_dir(); + } + + if ( $uploads['error'] !== false ) { + return ''; + } + + $file = get_post_meta( $post_id, '_wp_attached_file', true ); + + if ( empty( $file ) ) { + return ''; + } + + // Check that the upload base exists in the file location. + if ( strpos( $file, $uploads['basedir'] ) === 0 ) { + $src = str_replace( $uploads['basedir'], $uploads['baseurl'], $file ); + } + elseif ( strpos( $file, 'wp-content/uploads' ) !== false ) { + $src = $uploads['baseurl'] . substr( $file, ( strpos( $file, 'wp-content/uploads' ) + 18 ) ); + } + else { + // It's a newly uploaded file, therefore $file is relative to the baseurl. + $src = $uploads['baseurl'] . '/' . $file; + } + + return apply_filters( 'wp_get_attachment_url', $src, $post_id ); + } + + /** + * Make absolute URL for domain or protocol-relative one. + * + * @param string $src URL to process. + * + * @return string + */ + protected function get_absolute_url( $src ) { + + if ( empty( $src ) || ! is_string( $src ) ) { + return $src; + } + + if ( YoastSEO()->helpers->url->is_relative( $src ) === true ) { + + if ( $src[0] !== '/' ) { + return $src; + } + + // The URL is relative, we'll have to make it absolute. + return $this->home_url . $src; + } + + if ( strpos( $src, 'http' ) !== 0 ) { + // Protocol relative URL, we add the scheme as the standard requires a protocol. + return $this->scheme . ':' . $src; + } + + return $src; + } + + /** + * Returns the attachments for a gallery. + * + * @param int $id The post ID. + * @param array $gallery The gallery config. + * + * @return array The selected attachments. + */ + protected function get_gallery_attachments( $id, $gallery ) { + + // When there are attachments to include. + if ( ! empty( $gallery['include'] ) ) { + return $this->get_gallery_attachments_for_included( $gallery['include'] ); + } + + // When $id is empty, just return empty array. + if ( empty( $id ) ) { + return []; + } + + return $this->get_gallery_attachments_for_parent( $id, $gallery ); + } + + /** + * Returns the attachments for the given ID. + * + * @param int $id The post ID. + * @param array $gallery The gallery config. + * + * @return array The selected attachments. + */ + protected function get_gallery_attachments_for_parent( $id, $gallery ) { + $query = [ + 'posts_per_page' => -1, + 'post_parent' => $id, + ]; + + // When there are posts that should be excluded from result set. + if ( ! empty( $gallery['exclude'] ) ) { + $query['post__not_in'] = wp_parse_id_list( $gallery['exclude'] ); + } + + return $this->get_attachments( $query ); + } + + /** + * Returns an array with attachments for the post IDs that will be included. + * + * @param array $included_ids Array with IDs to include. + * + * @return array The found attachments. + */ + protected function get_gallery_attachments_for_included( $included_ids ) { + $ids_to_include = wp_parse_id_list( $included_ids ); + $attachments = $this->get_attachments( + [ + 'posts_per_page' => count( $ids_to_include ), + 'post__in' => $ids_to_include, + ], + ); + + $gallery_attachments = []; + foreach ( $attachments as $val ) { + $gallery_attachments[ $val->ID ] = $val; + } + + return $gallery_attachments; + } + + /** + * Returns the attachments. + * + * @param array $args Array with query args. + * + * @return array The found attachments. + */ + protected function get_attachments( $args ) { + $default_args = [ + 'post_status' => 'inherit', + 'post_type' => 'attachment', + 'post_mime_type' => 'image', + + // Defaults taken from function get_posts. + 'orderby' => 'date', + 'order' => 'DESC', + 'meta_key' => '', + 'meta_value' => '', + 'suppress_filters' => true, + 'ignore_sticky_posts' => true, + 'no_found_rows' => true, + ]; + + $args = wp_parse_args( $args, $default_args ); + + $get_attachments = new WP_Query(); + return $get_attachments->query( $args ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-admin.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-admin.php new file mode 100644 index 0000000..10b8fcd --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-admin.php @@ -0,0 +1,125 @@ +status_transition_bulk( $new_status, $old_status, $post ); + + return; + } + + $post_type = get_post_type( $post ); + + wp_cache_delete( 'lastpostmodified:gmt:' . $post_type, 'timeinfo' ); // #17455. + } + + /** + * Notify Google of the updated sitemap. + * + * @deprecated 22.0 + * @codeCoverageIgnore + * + * @return void + */ + public function ping_search_engines() { + _deprecated_function( __METHOD__, 'Yoast SEO 22.0' ); + } + + /** + * While bulk importing, just save unique post_types. + * + * When importing is done, if we have a post_type that is saved in the sitemap + * try to ping the search engines. + * + * @param string $new_status New post status. + * @param string $old_status Old post status. + * @param WP_Post $post Post object. + * + * @return void + */ + private function status_transition_bulk( $new_status, $old_status, $post ) { + $this->importing_post_types[] = get_post_type( $post ); + $this->importing_post_types = array_unique( $this->importing_post_types ); + } + + /** + * After import finished, walk through imported post_types and update info. + * + * @return void + */ + public function status_transition_bulk_finished() { + if ( ! defined( 'WP_IMPORTING' ) ) { + return; + } + + if ( empty( $this->importing_post_types ) ) { + return; + } + + $ping_search_engines = false; + + foreach ( $this->importing_post_types as $post_type ) { + wp_cache_delete( 'lastpostmodified:gmt:' . $post_type, 'timeinfo' ); // #17455. + + // Just have the cache deleted for nav_menu_item. + if ( $post_type === 'nav_menu_item' ) { + continue; + } + + if ( WPSEO_Options::get( 'noindex-' . $post_type, false ) === false ) { + $ping_search_engines = true; + } + } + + // Nothing to do. + if ( $ping_search_engines === false ) { + return; + } + + if ( WP_CACHE ) { + do_action( 'wpseo_hit_sitemap_index' ); + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-cache-validator.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-cache-validator.php new file mode 100644 index 0000000..49c2463 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-cache-validator.php @@ -0,0 +1,326 @@ + $max_length ) { + + if ( $max_length < 15 ) { + /* + * If this happens the most likely cause is a page number that is too high. + * + * So this would not happen unintentionally. + * Either by trying to cause a high server load, finding backdoors or misconfiguration. + */ + throw new OutOfRangeException( + __( + 'Trying to build the sitemap cache key, but the postfix and prefix combination leaves too little room to do this. You are probably requesting a page that is way out of the expected range.', + 'wordpress-seo', + ), + ); + } + + $half = ( $max_length / 2 ); + + $first_part = substr( $type, 0, ( ceil( $half ) - 1 ) ); + $last_part = substr( $type, ( 1 - floor( $half ) ) ); + + $type = $first_part . '..' . $last_part; + } + + return $type; + } + + /** + * Invalidate sitemap cache. + * + * @since 3.2 + * + * @param string|null $type The type to get the key for. Null for all caches. + * + * @return void + */ + public static function invalidate_storage( $type = null ) { + + // Global validator gets cleared when no type is provided. + $old_validator = null; + + // Get the current type validator. + if ( $type !== null ) { + $old_validator = self::get_validator( $type ); + } + + // Refresh validator. + self::create_validator( $type ); + + if ( ! wp_using_ext_object_cache() ) { + // Clean up current cache from the database. + self::cleanup_database( $type, $old_validator ); + } + + // External object cache pushes old and unretrieved items out by itself so we don't have to do anything for that. + } + + /** + * Cleanup invalidated database cache. + * + * @since 3.2 + * + * @param string|null $type The type of sitemap to clear cache for. + * @param string|null $validator The validator to clear cache of. + * + * @return void + */ + public static function cleanup_database( $type = null, $validator = null ) { + + global $wpdb; + + if ( $type === null ) { + // Clear all cache if no type is provided. + $like = sprintf( '%s%%', self::STORAGE_KEY_PREFIX ); + } + else { + // Clear type cache for all type keys. + $like = sprintf( '%1$s%2$s_%%', self::STORAGE_KEY_PREFIX, $type ); + } + + /* + * Add slashes to the LIKE "_" single character wildcard. + * + * We can't use `esc_like` here because we need the % in the query. + */ + $where = []; + $where[] = sprintf( "option_name LIKE '%s'", addcslashes( '_transient_' . $like, '_' ) ); + $where[] = sprintf( "option_name LIKE '%s'", addcslashes( '_transient_timeout_' . $like, '_' ) ); + + // Delete transients. + //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here. + //phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + $wpdb->query( + $wpdb->prepare( + //phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized. + 'DELETE FROM %i WHERE ' . implode( ' OR ', array_fill( 0, count( $where ), '%s' ) ), + array_merge( [ $wpdb->options ], $where ), + ), + ); + + wp_cache_delete( 'alloptions', 'options' ); + } + + /** + * Get the current cache validator. + * + * Without the type the global validator is returned. + * This can invalidate -all- keys in cache at once. + * + * With the type parameter the validator for that specific type can be invalidated. + * + * @since 3.2 + * + * @param string $type Provide a type for a specific type validator, empty for global validator. + * + * @return string|null The validator for the supplied type. + */ + public static function get_validator( $type = '' ) { + + $key = self::get_validator_key( $type ); + + $current = get_option( $key, null ); + if ( $current !== null ) { + return $current; + } + + if ( self::create_validator( $type ) ) { + return self::get_validator( $type ); + } + + return null; + } + + /** + * Get the cache validator option key for the specified type. + * + * @since 3.2 + * + * @param string $type Provide a type for a specific type validator, empty for global validator. + * + * @return string Validator to be used to generate the cache key. + */ + public static function get_validator_key( $type = '' ) { + + if ( empty( $type ) ) { + return self::VALIDATION_GLOBAL_KEY; + } + + return sprintf( self::VALIDATION_TYPE_KEY_FORMAT, $type ); + } + + /** + * Refresh the cache validator value. + * + * @since 3.2 + * + * @param string $type Provide a type for a specific type validator, empty for global validator. + * + * @return bool True if validator key has been saved as option. + */ + public static function create_validator( $type = '' ) { + + $key = self::get_validator_key( $type ); + + // Generate new validator. + $microtime = microtime(); + + // Remove space. + list( $milliseconds, $seconds ) = explode( ' ', $microtime ); + + // Transients are purged every 24h. + $seconds = ( $seconds % DAY_IN_SECONDS ); + $milliseconds = intval( substr( $milliseconds, 2, 3 ), 10 ); + + // Combine seconds and milliseconds and convert to integer. + $validator = intval( $seconds . '' . $milliseconds, 10 ); + + // Apply base 61 encoding. + $compressed = self::convert_base10_to_base61( $validator ); + + return update_option( $key, $compressed, false ); + } + + /** + * Encode to base61 format. + * + * This is base64 (numeric + alpha + alpha upper case) without the 0. + * + * @since 3.2 + * + * @param int $base10 The number that has to be converted to base 61. + * + * @return string Base 61 converted string. + * + * @throws InvalidArgumentException When the input is not an integer. + */ + public static function convert_base10_to_base61( $base10 ) { + + if ( ! is_int( $base10 ) ) { + throw new InvalidArgumentException( __( 'Expected an integer as input.', 'wordpress-seo' ) ); + } + + // Characters that will be used in the conversion. + $characters = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $length = strlen( $characters ); + + $remainder = $base10; + $output = ''; + + do { + // Building from right to left in the result. + $index = ( $remainder % $length ); + + // Prepend the character to the output. + $output = $characters[ $index ] . $output; + + // Determine the remainder after removing the applied number. + $remainder = floor( $remainder / $length ); + + // Keep doing it until we have no remainder left. + } while ( $remainder ); + + return $output; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-cache.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-cache.php new file mode 100644 index 0000000..a74e569 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-cache.php @@ -0,0 +1,359 @@ +is_enabled(); + } + + /** + * If cache is enabled. + * + * @since 3.2 + * + * @return bool + */ + public function is_enabled() { + + /** + * Filter if XML sitemap transient cache is enabled. + * + * @param bool $unsigned Enable cache or not, defaults to true. + */ + return apply_filters( 'wpseo_enable_xml_sitemap_transient_caching', false ); + } + + /** + * Retrieve the sitemap page from cache. + * + * @since 3.2 + * + * @param string $type Sitemap type. + * @param int $page Page number to retrieve. + * + * @return string|bool + */ + public function get_sitemap( $type, $page ) { + + $transient_key = WPSEO_Sitemaps_Cache_Validator::get_storage_key( $type, $page ); + if ( $transient_key === false ) { + return false; + } + + return get_transient( $transient_key ); + } + + /** + * Get the sitemap that is cached. + * + * @param string $type Sitemap type. + * @param int $page Page number to retrieve. + * + * @return WPSEO_Sitemap_Cache_Data|null Null on no cache found otherwise object containing sitemap and meta data. + */ + public function get_sitemap_data( $type, $page ) { + + $sitemap = $this->get_sitemap( $type, $page ); + + if ( empty( $sitemap ) ) { + return null; + } + + /* + * Unserialize Cache Data object as is_serialized() doesn't recognize classes in C format. + * This work-around should no longer be needed once the minimum PHP version has gone up to PHP 7.4, + * as the `WPSEO_Sitemap_Cache_Data` class uses O format serialization in PHP 7.4 and higher. + * + * @link https://wiki.php.net/rfc/custom_object_serialization + */ + if ( is_string( $sitemap ) && strpos( $sitemap, 'C:24:"WPSEO_Sitemap_Cache_Data"' ) === 0 ) { + // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize -- Can't be avoided due to how WP stores options. + $sitemap = unserialize( $sitemap ); + } + + // What we expect it to be if it is set. + if ( $sitemap instanceof WPSEO_Sitemap_Cache_Data_Interface ) { + return $sitemap; + } + + return null; + } + + /** + * Store the sitemap page from cache. + * + * @since 3.2 + * + * @param string $type Sitemap type. + * @param int $page Page number to store. + * @param string $sitemap Sitemap body to store. + * @param bool $usable Is this a valid sitemap or a cache of an invalid sitemap. + * + * @return bool + */ + public function store_sitemap( $type, $page, $sitemap, $usable = true ) { + + $transient_key = WPSEO_Sitemaps_Cache_Validator::get_storage_key( $type, $page ); + + if ( $transient_key === false ) { + return false; + } + + $status = ( $usable ) ? WPSEO_Sitemap_Cache_Data::OK : WPSEO_Sitemap_Cache_Data::ERROR; + + $sitemap_data = new WPSEO_Sitemap_Cache_Data(); + $sitemap_data->set_sitemap( $sitemap ); + $sitemap_data->set_status( $status ); + + return set_transient( $transient_key, $sitemap_data, DAY_IN_SECONDS ); + } + + /** + * Delete cache transients for index and specific type. + * + * Always deletes the main index sitemaps cache, as that's always invalidated by any other change. + * + * @since 1.5.4 + * @since 3.2 Changed from function wpseo_invalidate_sitemap_cache() to method in this class. + * + * @param string $type Sitemap type to invalidate. + * + * @return void + */ + public static function invalidate( $type ) { + + self::clear( [ $type ] ); + } + + /** + * Helper to invalidate in hooks where type is passed as second argument. + * + * @since 3.2 + * + * @param int $unused Unused term ID value. + * @param string $type Taxonomy to invalidate. + * + * @return void + */ + public static function invalidate_helper( $unused, $type ) { + + if ( + WPSEO_Options::get( 'noindex-' . $type ) === false + || WPSEO_Options::get( 'noindex-tax-' . $type ) === false + ) { + self::invalidate( $type ); + } + } + + /** + * Invalidate sitemap cache for authors. + * + * @param int $user_id User ID. + * + * @return bool True if the sitemap was properly invalidated. False otherwise. + */ + public static function invalidate_author( $user_id ) { + + $user = get_user_by( 'id', $user_id ); + + if ( $user === false ) { + return false; + } + + if ( current_action() === 'user_register' ) { + update_user_meta( $user_id, '_yoast_wpseo_profile_updated', time() ); + } + + if ( empty( $user->roles ) || in_array( 'subscriber', $user->roles, true ) ) { + return false; + } + + self::invalidate( 'author' ); + + return true; + } + + /** + * Invalidate sitemap cache for the post type of a post. + * + * Don't invalidate for revisions. + * + * @since 1.5.4 + * @since 3.2 Changed from function wpseo_invalidate_sitemap_cache_on_save_post() to method in this class. + * + * @param int $post_id Post ID to invalidate type for. + * + * @return void + */ + public static function invalidate_post( $post_id ) { + + if ( wp_is_post_revision( $post_id ) ) { + return; + } + + self::invalidate( get_post_type( $post_id ) ); + } + + /** + * Delete cache transients for given sitemaps types or all by default. + * + * @since 1.8.0 + * @since 3.2 Moved from WPSEO_Utils to this class. + * + * @param array $types Set of sitemap types to delete cache transients for. + * + * @return void + */ + public static function clear( $types = [] ) { + + if ( ! self::$is_enabled ) { + return; + } + + // No types provided, clear all. + if ( empty( $types ) ) { + self::$clear_all = true; + + return; + } + + // Always invalidate the index sitemap as well. + if ( ! in_array( WPSEO_Sitemaps::SITEMAP_INDEX_TYPE, $types, true ) ) { + array_unshift( $types, WPSEO_Sitemaps::SITEMAP_INDEX_TYPE ); + } + + foreach ( $types as $type ) { + if ( ! in_array( $type, self::$clear_types, true ) ) { + self::$clear_types[] = $type; + } + } + } + + /** + * Invalidate storage for cache types queued to clear. + * + * @return void + */ + public static function clear_queued() { + + if ( self::$clear_all ) { + + WPSEO_Sitemaps_Cache_Validator::invalidate_storage(); + self::$clear_all = false; + self::$clear_types = []; + + return; + } + + foreach ( self::$clear_types as $type ) { + WPSEO_Sitemaps_Cache_Validator::invalidate_storage( $type ); + } + + self::$clear_types = []; + } + + /** + * Adds a hook that when given option is updated, the cache is cleared. + * + * @since 3.2 + * + * @param string $option Option name. + * @param string $type Sitemap type. + * + * @return void + */ + public static function register_clear_on_option_update( $option, $type = '' ) { + + self::$cache_clear[ $option ] = $type; + } + + /** + * Clears the transient cache when a given option is updated, if that option has been registered before. + * + * @since 3.2 + * + * @param string $option The option name that's being updated. + * + * @return void + */ + public static function clear_on_option_update( $option ) { + + if ( array_key_exists( $option, self::$cache_clear ) ) { + + if ( empty( self::$cache_clear[ $option ] ) ) { + // Clear all caches. + self::clear(); + } + else { + // Clear specific provided type(s). + $types = (array) self::$cache_clear[ $option ]; + self::clear( $types ); + } + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-renderer.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-renderer.php new file mode 100644 index 0000000..729a510 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-renderer.php @@ -0,0 +1,355 @@ +get_xsl_url() ); + $this->stylesheet = ''; + $this->charset = get_bloginfo( 'charset' ); + $this->output_charset = $this->charset; + + if ( + $this->charset !== 'UTF-8' + && function_exists( 'mb_list_encodings' ) + && in_array( $this->charset, mb_list_encodings(), true ) + ) { + $this->output_charset = 'UTF-8'; + } + + $this->needs_conversion = $this->output_charset !== $this->charset; + } + + /** + * Builds the sitemap index. + * + * @param array $links Set of sitemaps index links. + * + * @return string + */ + public function get_index( $links ) { + + $xml = '' . "\n"; + + foreach ( $links as $link ) { + $xml .= $this->sitemap_index_url( $link ); + } + + /** + * Filter to append sitemaps to the index. + * + * @param string $index String to append to sitemaps index, defaults to empty. + */ + $xml .= apply_filters( 'wpseo_sitemap_index', '' ); + $xml .= ''; + + return $xml; + } + + /** + * Builds the sitemap. + * + * @param array $links Set of sitemap links. + * @param string $type Sitemap type. + * @param int $current_page Current sitemap page number. + * + * @return string + */ + public function get_sitemap( $links, $type, $current_page ) { + + $urlset = '' . "\n"; + + /** + * Filters the `urlset` for all sitemaps. + * + * @param string $urlset The output for the sitemap's `urlset`. + */ + $urlset = apply_filters( 'wpseo_sitemap_urlset', $urlset ); + + /** + * Filters the `urlset` for a sitemap by type. + * + * @param string $urlset The output for the sitemap's `urlset`. + */ + $xml = apply_filters( "wpseo_sitemap_{$type}_urlset", $urlset ); + + foreach ( $links as $url ) { + $xml .= $this->sitemap_url( $url ); + } + + /** + * Filter to add extra URLs to the XML sitemap by type. + * + * Only runs for the first page, not on all. + * + * @param string $content String content to add, defaults to empty. + */ + if ( $current_page === 1 ) { + $xml .= apply_filters( "wpseo_sitemap_{$type}_content", '' ); + } + + $xml .= ''; + + return $xml; + } + + /** + * Produce final XML output with debug information. + * + * @param string $sitemap Sitemap XML. + * + * @return string + */ + public function get_output( $sitemap ) { + + $output = 'output_charset ) . '"?>'; + + if ( $this->stylesheet ) { + /** + * Filter the stylesheet URL for the XML sitemap. + * + * @param string $stylesheet Stylesheet URL. + */ + $output .= apply_filters( 'wpseo_stylesheet_url', $this->stylesheet ) . "\n"; + } + + $output .= $sitemap; + $output .= "\n"; + + return $output; + } + + /** + * Get charset for the output. + * + * @return string + */ + public function get_output_charset() { + return $this->output_charset; + } + + /** + * Set a custom stylesheet for this sitemap. Set to empty to just remove the default stylesheet. + * + * @param string $stylesheet Full XML-stylesheet declaration. + * + * @return void + */ + public function set_stylesheet( $stylesheet ) { + $this->stylesheet = $stylesheet; + } + + /** + * Build the `` tag for a given URL. + * + * @param array $url Array of parts that make up this entry. + * + * @return string + */ + protected function sitemap_index_url( $url ) { + + $date = null; + + if ( ! empty( $url['lastmod'] ) ) { + $date = YoastSEO()->helpers->date->format( $url['lastmod'] ); + } + + $url['loc'] = htmlspecialchars( $url['loc'], ENT_COMPAT, $this->output_charset, false ); + + $output = "\t\n"; + $output .= "\t\t" . $url['loc'] . "\n"; + $output .= empty( $date ) ? '' : "\t\t" . htmlspecialchars( $date, ENT_COMPAT, $this->output_charset, false ) . "\n"; + $output .= "\t\n"; + + return $output; + } + + /** + * Build the `` tag for a given URL. + * + * Public access for backwards compatibility reasons. + * + * @param array $url Array of parts that make up this entry. + * + * @return string + */ + public function sitemap_url( $url ) { + + $date = null; + + if ( ! empty( $url['mod'] ) ) { + // Create a DateTime object date in the correct timezone. + $date = YoastSEO()->helpers->date->format( $url['mod'] ); + } + + $output = "\t\n"; + $output .= "\t\t" . $this->encode_and_escape( $url['loc'] ) . "\n"; + $output .= empty( $date ) ? '' : "\t\t" . htmlspecialchars( $date, ENT_COMPAT, $this->output_charset, false ) . "\n"; + + if ( empty( $url['images'] ) ) { + $url['images'] = []; + } + + foreach ( $url['images'] as $img ) { + + if ( empty( $img['src'] ) ) { + continue; + } + + $output .= "\t\t\n"; + $output .= "\t\t\t" . $this->encode_and_escape( $img['src'] ) . "\n"; + $output .= "\t\t\n"; + } + unset( $img ); + + $output .= "\t\n"; + + /** + * Filters the output for the sitemap URL tag. + * + * @param string $output The output for the sitemap url tag. + * @param array $url The sitemap URL array on which the output is based. + */ + return apply_filters( 'wpseo_sitemap_url', $output, $url ); + } + + /** + * Ensure the URL is encoded per RFC3986 and correctly escaped for use in an XML sitemap. + * + * This method works around a two quirks in esc_url(): + * 1. `esc_url()` leaves schema-relative URLs alone, while according to the sitemap specs, + * the URL must always begin with a protocol. + * 2. `esc_url()` escapes ampersands as `&` instead of the more common `&`. + * According to the specs, `&` should be used, and even though this shouldn't + * really make a difference in practice, to quote Jono: "I'd be nervous about & + * given how many weird and wonderful things eat sitemaps", so better safe than sorry. + * + * @link https://www.sitemaps.org/protocol.html#xmlTagDefinitions + * @link https://www.sitemaps.org/protocol.html#escaping + * @link https://developer.wordpress.org/reference/functions/esc_url/ + * + * @param string $url URL to encode and escape. + * + * @return string + */ + protected function encode_and_escape( $url ) { + $url = $this->encode_url_rfc3986( $url ); + $url = esc_url( $url ); + $url = str_replace( '&', '&', $url ); + $url = str_replace( ''', ''', $url ); + + if ( strpos( $url, '//' ) === 0 ) { + // Schema-relative URL for which esc_url() does not add a scheme. + $url = 'http:' . $url; + } + + return $url; + } + + /** + * Apply some best effort conversion to comply with RFC3986. + * + * @param string $url URL to encode. + * + * @return string + */ + protected function encode_url_rfc3986( $url ) { + + if ( filter_var( $url, FILTER_VALIDATE_URL ) ) { + return $url; + } + + $path = wp_parse_url( $url, PHP_URL_PATH ); + + if ( ! empty( $path ) && $path !== '/' ) { + $encoded_path = explode( '/', $path ); + + // First decode the path, to prevent double encoding. + $encoded_path = array_map( 'rawurldecode', $encoded_path ); + + $encoded_path = array_map( 'rawurlencode', $encoded_path ); + $encoded_path = implode( '/', $encoded_path ); + + $url = str_replace( $path, $encoded_path, $url ); + } + + $query = wp_parse_url( $url, PHP_URL_QUERY ); + + if ( ! empty( $query ) ) { + + parse_str( $query, $parsed_query ); + + $parsed_query = http_build_query( $parsed_query, '', '&', PHP_QUERY_RFC3986 ); + + $url = str_replace( $query, $parsed_query, $url ); + } + + return $url; + } + + /** + * Retrieves the XSL URL that should be used in the current environment + * + * When home_url and site_url are not the same, the home_url should be used. + * This is because the XSL needs to be served from the same domain, protocol and port + * as the XML file that is loading it. + * + * @return string The XSL URL that needs to be used. + */ + protected function get_xsl_url() { + if ( home_url() !== site_url() ) { + return apply_filters( 'wpseo_sitemap_public_url', home_url( 'main-sitemap.xsl' ) ); + } + + /* + * Fallback to circumvent a cross-domain security problem when the XLS file is + * loaded from a different (sub)domain. + */ + if ( strpos( plugins_url(), home_url() ) !== 0 ) { + return home_url( 'main-sitemap.xsl' ); + } + + return plugin_dir_url( WPSEO_FILE ) . 'css/main-sitemap.xsl'; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-router.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-router.php new file mode 100644 index 0000000..8b92314 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps-router.php @@ -0,0 +1,161 @@ +classes->get( Deactivating_Yoast_Seo_Conditional::class )->is_met() ) { + return; + } + + add_action( 'yoast_add_dynamic_rewrite_rules', [ $this, 'add_rewrite_rules' ] ); + add_filter( 'query_vars', [ $this, 'add_query_vars' ] ); + + add_filter( 'redirect_canonical', [ $this, 'redirect_canonical' ] ); + add_action( 'template_redirect', [ $this, 'template_redirect' ], 0 ); + } + + /** + * Adds rewrite routes for sitemaps. + * + * @param Yoast_Dynamic_Rewrites $dynamic_rewrites Dynamic rewrites handler instance. + * + * @return void + */ + public function add_rewrite_rules( $dynamic_rewrites ) { + $dynamic_rewrites->add_rule( 'sitemap_index\.xml$', 'index.php?sitemap=1', 'top' ); + $dynamic_rewrites->add_rule( '([^/]+?)-sitemap([0-9]+)?\.xml$', 'index.php?sitemap=$matches[1]&sitemap_n=$matches[2]', 'top' ); + $dynamic_rewrites->add_rule( '([a-z]+)?-?sitemap\.xsl$', 'index.php?yoast-sitemap-xsl=$matches[1]', 'top' ); + } + + /** + * Adds query variables for sitemaps. + * + * @param array $query_vars List of query variables to filter. + * + * @return array Filtered query variables. + */ + public function add_query_vars( $query_vars ) { + $query_vars[] = 'sitemap'; + $query_vars[] = 'sitemap_n'; + $query_vars[] = 'yoast-sitemap-xsl'; + + return $query_vars; + } + + /** + * Sets up rewrite rules. + * + * @deprecated 21.8 + * @codeCoverageIgnore + * + * @return void + */ + public function init() { + _deprecated_function( __METHOD__, 'Yoast SEO 21.8' ); + } + + /** + * Stop trailing slashes on sitemap.xml URLs. + * + * @param string $redirect The redirect URL currently determined. + * + * @return bool|string + */ + public function redirect_canonical( $redirect ) { + + if ( get_query_var( 'sitemap' ) || get_query_var( 'yoast-sitemap-xsl' ) ) { + return false; + } + + return $redirect; + } + + /** + * Redirects sitemap.xml to sitemap_index.xml. + * + * @return void + */ + public function template_redirect() { + if ( ! $this->needs_sitemap_index_redirect() ) { + return; + } + + YoastSEO()->helpers->redirect->do_safe_redirect( home_url( '/sitemap_index.xml' ), 301, 'Yoast SEO' ); + } + + /** + * Checks whether the current request needs to be redirected to sitemap_index.xml. + * + * @global WP_Query $wp_query Current query. + * + * @return bool True if redirect is needed, false otherwise. + */ + public function needs_sitemap_index_redirect() { + global $wp_query; + + $protocol = 'http://'; + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + if ( ! empty( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) === 'on' ) { + $protocol = 'https://'; + } + + $domain = ''; + if ( isset( $_SERVER['SERVER_NAME'] ) ) { + $domain = sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) ); + } + + $path = ''; + if ( isset( $_SERVER['REQUEST_URI'] ) ) { + $path = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ); + } + + // Due to different environment configurations, we need to check both SERVER_NAME and HTTP_HOST. + $check_urls = [ $protocol . $domain . $path ]; + if ( ! empty( $_SERVER['HTTP_HOST'] ) ) { + $check_urls[] = $protocol . sanitize_text_field( wp_unslash( $_SERVER['HTTP_HOST'] ) ) . $path; + } + + return $wp_query->is_404 && in_array( home_url( '/sitemap.xml' ), $check_urls, true ); + } + + /** + * Create base URL for the sitemap. + * + * @param string $page Page to append to the base URL. + * + * @return string base URL (incl page) + */ + public static function get_base_url( $page ) { + + global $wp_rewrite; + + $base = $wp_rewrite->using_index_permalinks() ? 'index.php/' : '/'; + + /** + * Filter the base URL of the sitemaps. + * + * @param string $base The string that should be added to home_url() to make the full base URL. + */ + $base = apply_filters( 'wpseo_sitemaps_base_url', $base ); + + /* + * Get the scheme from the configured home URL instead of letting WordPress + * determine the scheme based on the requested URI. + */ + return home_url( $base . $page, wp_parse_url( get_option( 'home' ), PHP_URL_SCHEME ) ); + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps.php new file mode 100644 index 0000000..c765325 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-sitemaps.php @@ -0,0 +1,674 @@ +router = new WPSEO_Sitemaps_Router(); + $this->renderer = new WPSEO_Sitemaps_Renderer(); + $this->cache = new WPSEO_Sitemaps_Cache(); + + if ( ! empty( $_SERVER['SERVER_PROTOCOL'] ) ) { + $this->http_protocol = sanitize_text_field( wp_unslash( $_SERVER['SERVER_PROTOCOL'] ) ); + } + } + + /** + * Initialize sitemap providers classes. + * + * @since 5.3 + * + * @return void + */ + public function init_sitemaps_providers() { + + $this->providers = [ + new WPSEO_Post_Type_Sitemap_Provider(), + new WPSEO_Taxonomy_Sitemap_Provider(), + new WPSEO_Author_Sitemap_Provider(), + ]; + + $external_providers = apply_filters( 'wpseo_sitemaps_providers', [] ); + + foreach ( $external_providers as $provider ) { + if ( is_object( $provider ) && $provider instanceof WPSEO_Sitemap_Provider ) { + $this->providers[] = $provider; + } + } + } + + /** + * Check the current request URI, if we can determine it's probably an XML sitemap, kill loading the widgets. + * + * @return void + */ + public function reduce_query_load() { + if ( ! isset( $_SERVER['REQUEST_URI'] ) ) { + return; + } + $request_uri = sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ); + $extension = substr( $request_uri, -4 ); + if ( stripos( $request_uri, 'sitemap' ) !== false && in_array( $extension, [ '.xml', '.xsl' ], true ) ) { + remove_all_actions( 'widgets_init' ); + } + } + + /** + * Register your own sitemap. Call this during 'init'. + * + * @param string $name The name of the sitemap. + * @param callback $building_function Function to build your sitemap. + * @param string $rewrite Optional. Regular expression to match your sitemap with. + * + * @return void + */ + public function register_sitemap( $name, $building_function, $rewrite = '' ) { + add_action( 'wpseo_do_sitemap_' . $name, $building_function ); + if ( $rewrite ) { + Yoast_Dynamic_Rewrites::instance()->add_rule( $rewrite, 'index.php?sitemap=' . $name, 'top' ); + } + } + + /** + * Register your own XSL file. Call this during 'init'. + * + * @since 1.4.23 + * + * @param string $name The name of the XSL file. + * @param callback $building_function Function to build your XSL file. + * @param string $rewrite Optional. Regular expression to match your sitemap with. + * + * @return void + */ + public function register_xsl( $name, $building_function, $rewrite = '' ) { + add_action( 'wpseo_xsl_' . $name, $building_function ); + if ( $rewrite ) { + Yoast_Dynamic_Rewrites::instance()->add_rule( $rewrite, 'index.php?yoast-sitemap-xsl=' . $name, 'top' ); + } + } + + /** + * Set the sitemap current page to allow creating partial sitemaps with WP-CLI + * in a one-off process. + * + * @param int $current_page The part that should be generated. + * + * @return void + */ + public function set_n( $current_page ) { + if ( is_scalar( $current_page ) && (int) $current_page > 0 ) { + $this->current_page = (int) $current_page; + } + } + + /** + * Set the sitemap content to display after you have generated it. + * + * @param string $sitemap The generated sitemap to output. + * + * @return void + */ + public function set_sitemap( $sitemap ) { + $this->sitemap = $sitemap; + } + + /** + * Set as true to make the request 404. Used stop the display of empty sitemaps or invalid requests. + * + * @param bool $is_bad Is this a bad request. True or false. + * + * @return void + */ + public function set_bad_sitemap( $is_bad ) { + $this->bad_sitemap = (bool) $is_bad; + } + + /** + * Prevent stupid plugins from running shutdown scripts when we're obviously not outputting HTML. + * + * @since 1.4.16 + * + * @return void + */ + public function sitemap_close() { + remove_all_actions( 'wp_footer' ); + exit(); + } + + /** + * Hijack requests for potential sitemaps and XSL files. + * + * @param WP_Query $query Main query instance. + * + * @return void + */ + public function redirect( $query ) { + + if ( ! $query->is_main_query() ) { + return; + } + + $yoast_sitemap_xsl = get_query_var( 'yoast-sitemap-xsl' ); + + if ( ! empty( $yoast_sitemap_xsl ) ) { + /* + * This is a method to provide the XSL via the home_url. + * Needed when the site_url and home_url are not the same. + * Loading the XSL needs to come from the same domain, protocol and port as the XML. + * + * Whenever home_url and site_url are the same, the file can be loaded directly. + */ + $this->xsl_output( $yoast_sitemap_xsl ); + $this->sitemap_close(); + + return; + } + + $type = get_query_var( 'sitemap' ); + + if ( empty( $type ) ) { + return; + } + + if ( get_query_var( 'sitemap_n' ) === '1' || get_query_var( 'sitemap_n' ) === '0' ) { + wp_safe_redirect( home_url( "/$type-sitemap.xml" ), 301, 'Yoast SEO' ); + exit(); + } + + $this->set_n( get_query_var( 'sitemap_n' ) ); + + if ( ! $this->get_sitemap_from_cache( $type, $this->current_page ) ) { + $this->build_sitemap( $type ); + } + + if ( $this->bad_sitemap ) { + $query->set_404(); + status_header( 404 ); + + return; + } + + $this->output(); + $this->sitemap_close(); + } + + /** + * Try to get the sitemap from cache. + * + * @param string $type Sitemap type. + * @param int $page_number The page number to retrieve. + * + * @return bool If the sitemap has been retrieved from cache. + */ + private function get_sitemap_from_cache( $type, $page_number ) { + + $this->transient = false; + + if ( $this->cache->is_enabled() !== true ) { + return false; + } + + /** + * Fires before the attempt to retrieve XML sitemap from the transient cache. + * + * @param WPSEO_Sitemaps $sitemaps Sitemaps object. + */ + do_action( 'wpseo_sitemap_stylesheet_cache_' . $type, $this ); + + $sitemap_cache_data = $this->cache->get_sitemap_data( $type, $page_number ); + + // No cache was found, refresh it because cache is enabled. + if ( empty( $sitemap_cache_data ) ) { + return $this->refresh_sitemap_cache( $type, $page_number ); + } + + // Cache object was found, parse information. + $this->transient = true; + + $this->sitemap = $sitemap_cache_data->get_sitemap(); + $this->bad_sitemap = ! $sitemap_cache_data->is_usable(); + + return true; + } + + /** + * Build and save sitemap to cache. + * + * @param string $type Sitemap type. + * @param int $page_number The page number to save to. + * + * @return bool + */ + private function refresh_sitemap_cache( $type, $page_number ) { + $this->set_n( $page_number ); + $this->build_sitemap( $type ); + + return $this->cache->store_sitemap( $type, $page_number, $this->sitemap, ! $this->bad_sitemap ); + } + + /** + * Attempts to build the requested sitemap. + * + * Sets $bad_sitemap if this isn't for the root sitemap, a post type or taxonomy. + * + * @param string $type The requested sitemap's identifier. + * + * @return void + */ + public function build_sitemap( $type ) { + + /** + * Filter the type of sitemap to build. + * + * @param string $type Sitemap type, determined by the request. + */ + $type = apply_filters( 'wpseo_build_sitemap_post_type', $type ); + + if ( $type === '1' ) { + $this->build_root_map(); + + return; + } + + $entries_per_page = $this->get_entries_per_page(); + + foreach ( $this->providers as $provider ) { + if ( ! $provider->handles_type( $type ) ) { + continue; + } + + try { + $links = $provider->get_sitemap_links( $type, $entries_per_page, $this->current_page ); + } catch ( OutOfBoundsException $exception ) { + $this->bad_sitemap = true; + + return; + } + + $this->sitemap = $this->renderer->get_sitemap( $links, $type, $this->current_page ); + + return; + } + + if ( has_action( 'wpseo_do_sitemap_' . $type ) ) { + /** + * Fires custom handler, if hooked to generate sitemap for the type. + */ + do_action( 'wpseo_do_sitemap_' . $type ); + + return; + } + + $this->bad_sitemap = true; + } + + /** + * Build the root sitemap (example.com/sitemap_index.xml) which lists sub-sitemaps for other content types. + * + * @return void + */ + public function build_root_map() { + + $links = []; + $entries_per_page = $this->get_entries_per_page(); + + foreach ( $this->providers as $provider ) { + $links = array_merge( $links, $provider->get_index_links( $entries_per_page ) ); + } + + /** + * Filter the sitemap links array before the index sitemap is built. + * + * @param array $links Array of sitemap links + */ + $links = apply_filters( 'wpseo_sitemap_index_links', $links ); + + if ( empty( $links ) ) { + $this->bad_sitemap = true; + $this->sitemap = ''; + + return; + } + + $this->sitemap = $this->renderer->get_index( $links ); + } + + /** + * Spits out the XSL for the XML sitemap. + * + * @since 1.4.13 + * + * @param string $type Type to output. + * + * @return void + */ + public function xsl_output( $type ) { + + if ( $type !== 'main' ) { + + /** + * Fires for the output of XSL for XML sitemaps, other than type "main". + */ + do_action( 'wpseo_xsl_' . $type ); + + return; + } + + header( $this->http_protocol . ' 200 OK', true, 200 ); + // Prevent the search engines from indexing the XML Sitemap. + header( 'X-Robots-Tag: noindex, follow', true ); + header( 'Content-Type: text/xml' ); + + // Make the browser cache this file properly. + $expires = YEAR_IN_SECONDS; + header( 'Pragma: public' ); + header( 'Cache-Control: max-age=' . $expires ); + header( 'Expires: ' . YoastSEO()->helpers->date->format_timestamp( ( time() + $expires ), 'D, d M Y H:i:s' ) . ' GMT' ); + + // Don't use WP_Filesystem() here because that's not initialized yet. See https://yoast.atlassian.net/browse/QAK-2043. + readfile( WPSEO_PATH . 'css/main-sitemap.xsl' ); + } + + /** + * Spit out the generated sitemap. + * + * @return void + */ + public function output() { + $this->send_headers(); + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaping sitemap as either xml or html results in empty document. + echo $this->renderer->get_output( $this->sitemap ); + } + + /** + * Makes a request to the sitemap index to cache it before the arrival of the search engines. + * + * @return void + */ + public function hit_sitemap_index() { + if ( ! $this->cache->is_enabled() ) { + return; + } + + wp_remote_get( WPSEO_Sitemaps_Router::get_base_url( 'sitemap_index.xml' ) ); + } + + /** + * Get the GMT modification date for the last modified post in the post type. + * + * @since 3.2 + * + * @param string|array $post_types Post type or array of types. + * @param bool $return_all Flag to return array of values. + * + * @return string|array|false + */ + public static function get_last_modified_gmt( $post_types, $return_all = false ) { + + global $wpdb; + + static $post_type_dates = null; + + if ( ! is_array( $post_types ) ) { + $post_types = [ $post_types ]; + } + + foreach ( $post_types as $post_type ) { + if ( ! isset( $post_type_dates[ $post_type ] ) ) { // If we hadn't seen post type before. R. + $post_type_dates = null; + break; + } + } + + if ( $post_type_dates === null ) { + + $post_type_dates = []; + $post_type_names = WPSEO_Post_Type::get_accessible_post_types(); + + if ( ! empty( $post_type_names ) ) { + $post_statuses = array_map( 'esc_sql', self::get_post_statuses() ); + $replacements = array_merge( + [ + 'post_type', + 'post_modified_gmt', + 'date', + $wpdb->posts, + 'post_status', + ], + $post_statuses, + [ 'post_type' ], + array_keys( $post_type_names ), + [ + 'post_type', + 'date', + ], + ); + + //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here. + //phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + $dates = $wpdb->get_results( + //phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized. + $wpdb->prepare( + ' + SELECT %i, MAX(%i) AS %i + FROM %i + WHERE %i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ') + AND %i IN (' . implode( ', ', array_fill( 0, count( $post_type_names ), '%s' ) ) . ') + GROUP BY %i + ORDER BY %i DESC + ', + $replacements, + ), + ); + + foreach ( $dates as $obj ) { + $post_type_dates[ $obj->post_type ] = $obj->date; + } + } + } + + $dates = array_intersect_key( $post_type_dates, array_flip( $post_types ) ); + + if ( count( $dates ) > 0 ) { + if ( $return_all ) { + return $dates; + } + + return max( $dates ); + } + + return false; + } + + /** + * Get the modification date for the last modified post in the post type. + * + * @param array $post_types Post types to get the last modification date for. + * + * @return string + */ + public function get_last_modified( $post_types ) { + return YoastSEO()->helpers->date->format( self::get_last_modified_gmt( $post_types ) ); + } + + /** + * Get the maximum number of entries per XML sitemap. + * + * @return int The maximum number of entries. + */ + protected function get_entries_per_page() { + /** + * Filter the maximum number of entries per XML sitemap. + * + * After changing the output of the filter, make sure that you disable and enable the + * sitemaps to make sure the value is picked up for the sitemap cache. + * + * @param int $entries The maximum number of entries per XML sitemap. + */ + $entries = (int) apply_filters( 'wpseo_sitemap_entries_per_page', 1000 ); + + return $entries; + } + + /** + * Get post statuses for post_type or the root sitemap. + * + * @since 10.2 + * + * @param string $type Provide a type for a post_type sitemap, SITEMAP_INDEX_TYPE for the root sitemap. + * + * @return array List of post statuses. + */ + public static function get_post_statuses( $type = self::SITEMAP_INDEX_TYPE ) { + /** + * Filter post status list for sitemap query for the post type. + * + * @param array $post_statuses Post status list, defaults to array( 'publish' ). + * @param string $type Post type or SITEMAP_INDEX_TYPE. + */ + $post_statuses = apply_filters( 'wpseo_sitemap_post_statuses', [ 'publish' ], $type ); + + if ( ! is_array( $post_statuses ) || empty( $post_statuses ) ) { + $post_statuses = [ 'publish' ]; + } + + if ( ( $type === self::SITEMAP_INDEX_TYPE || $type === 'attachment' ) + && ! in_array( 'inherit', $post_statuses, true ) + ) { + $post_statuses[] = 'inherit'; + } + + return $post_statuses; + } + + /** + * Sends all the required HTTP Headers. + * + * @return void + */ + private function send_headers() { + if ( headers_sent() ) { + return; + } + + $headers = [ + $this->http_protocol . ' 200 OK' => 200, + // Prevent the search engines from indexing the XML Sitemap. + 'X-Robots-Tag: noindex, follow' => '', + 'Content-Type: text/xml; charset=' . esc_attr( $this->renderer->get_output_charset() ) => '', + ]; + + /** + * Filter the HTTP headers we send before an XML sitemap. + * + * @param array $headers The HTTP headers we're going to send out. + */ + $headers = apply_filters( 'wpseo_sitemap_http_headers', $headers ); + + foreach ( $headers as $header => $status ) { + if ( is_numeric( $status ) ) { + header( $header, true, $status ); + continue; + } + header( $header, true ); + } + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-taxonomy-sitemap-provider.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-taxonomy-sitemap-provider.php new file mode 100644 index 0000000..064c808 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/class-taxonomy-sitemap-provider.php @@ -0,0 +1,351 @@ +include_images = apply_filters( 'wpseo_xml_sitemap_include_images', true ); + } + + /** + * Check if provider supports given item type. + * + * @param string $type Type string to check for. + * + * @return bool + */ + public function handles_type( $type ) { + + $taxonomy = get_taxonomy( $type ); + + if ( $taxonomy === false || ! $this->is_valid_taxonomy( $taxonomy->name ) || ! $taxonomy->public ) { + return false; + } + + return true; + } + + /** + * Retrieves the links for the sitemap. + * + * @param int $max_entries Entries per sitemap. + * + * @return array + */ + public function get_index_links( $max_entries ) { + + $taxonomies = get_taxonomies( [ 'public' => true ], 'objects' ); + + if ( empty( $taxonomies ) ) { + return []; + } + + $taxonomy_names = array_filter( array_keys( $taxonomies ), [ $this, 'is_valid_taxonomy' ] ); + $taxonomies = array_intersect_key( $taxonomies, array_flip( $taxonomy_names ) ); + + // Retrieve all the taxonomies and their terms so we can do a proper count on them. + + /** + * Filter the setting of excluding empty terms from the XML sitemap. + * + * @param bool $exclude Defaults to true. + * @param array $taxonomy_names Array of names for the taxonomies being processed. + */ + $hide_empty = apply_filters( 'wpseo_sitemap_exclude_empty_terms', true, $taxonomy_names ); + + $all_taxonomies = []; + + foreach ( $taxonomy_names as $taxonomy_name ) { + /** + * Filter the setting of excluding empty terms from the XML sitemap for a specific taxonomy. + * + * @param bool $exclude Defaults to the sitewide setting. + * @param string $taxonomy_name The name of the taxonomy being processed. + */ + $hide_empty_tax = apply_filters( 'wpseo_sitemap_exclude_empty_terms_taxonomy', $hide_empty, $taxonomy_name ); + + $term_args = [ + 'taxonomy' => $taxonomy_name, + 'hide_empty' => $hide_empty_tax, + 'fields' => 'ids', + ]; + $taxonomy_terms = get_terms( $term_args ); + + if ( count( $taxonomy_terms ) > 0 ) { + $all_taxonomies[ $taxonomy_name ] = $taxonomy_terms; + } + } + + $index = []; + + foreach ( $taxonomies as $tax_name => $tax ) { + + if ( ! isset( $all_taxonomies[ $tax_name ] ) ) { // No eligible terms found. + continue; + } + + $total_count = ( isset( $all_taxonomies[ $tax_name ] ) ) ? count( $all_taxonomies[ $tax_name ] ) : 1; + $max_pages = 1; + + if ( $total_count > $max_entries ) { + $max_pages = (int) ceil( $total_count / $max_entries ); + } + + $last_modified_gmt = WPSEO_Sitemaps::get_last_modified_gmt( $tax->object_type ); + + for ( $page_counter = 0; $page_counter < $max_pages; $page_counter++ ) { + + $current_page = ( $page_counter === 0 ) ? '' : ( $page_counter + 1 ); + + if ( ! is_array( $tax->object_type ) || count( $tax->object_type ) === 0 ) { + continue; + } + + $terms = array_splice( $all_taxonomies[ $tax_name ], 0, $max_entries ); + + if ( ! $terms ) { + continue; + } + + $args = [ + 'post_type' => $tax->object_type, + 'tax_query' => [ + [ + 'taxonomy' => $tax_name, + 'terms' => $terms, + ], + ], + 'orderby' => 'modified', + 'order' => 'DESC', + 'posts_per_page' => 1, + ]; + $query = new WP_Query( $args ); + + if ( $query->have_posts() ) { + $date = $query->posts[0]->post_modified_gmt; + } + else { + $date = $last_modified_gmt; + } + + $index[] = [ + 'loc' => WPSEO_Sitemaps_Router::get_base_url( $tax_name . '-sitemap' . $current_page . '.xml' ), + 'lastmod' => $date, + ]; + } + } + + return $index; + } + + /** + * Get set of sitemap link data. + * + * @param string $type Sitemap type. + * @param int $max_entries Entries per sitemap. + * @param int $current_page Current page of the sitemap. + * + * @return array + * + * @throws OutOfBoundsException When an invalid page is requested. + */ + public function get_sitemap_links( $type, $max_entries, $current_page ) { + global $wpdb; + + $links = []; + if ( ! $this->handles_type( $type ) ) { + return $links; + } + + $taxonomy = get_taxonomy( $type ); + + $steps = $max_entries; + $offset = ( $current_page > 1 ) ? ( ( $current_page - 1 ) * $max_entries ) : 0; + + /** This filter is documented in inc/sitemaps/class-taxonomy-sitemap-provider.php */ + $hide_empty = apply_filters( 'wpseo_sitemap_exclude_empty_terms', true, [ $taxonomy->name ] ); + /** This filter is documented in inc/sitemaps/class-taxonomy-sitemap-provider.php */ + $hide_empty_tax = apply_filters( 'wpseo_sitemap_exclude_empty_terms_taxonomy', $hide_empty, $taxonomy->name ); + $terms = get_terms( + [ + 'taxonomy' => $taxonomy->name, + 'hide_empty' => $hide_empty_tax, + 'update_term_meta_cache' => false, + 'offset' => $offset, + 'number' => $steps, + ], + ); + + // If there are no terms fetched for this range, we are on an invalid page. + if ( empty( $terms ) ) { + throw new OutOfBoundsException( 'Invalid sitemap page requested' ); + } + + $post_statuses = array_map( 'esc_sql', WPSEO_Sitemaps::get_post_statuses() ); + + $replacements = array_merge( + [ + 'post_modified_gmt', + $wpdb->posts, + $wpdb->term_relationships, + 'object_id', + 'ID', + $wpdb->term_taxonomy, + 'term_taxonomy_id', + 'term_taxonomy_id', + 'taxonomy', + 'term_id', + 'post_status', + ], + $post_statuses, + [ 'post_password' ], + ); + + /** + * Filter: 'wpseo_exclude_from_sitemap_by_term_ids' - Allow excluding terms by ID. + * + * @param array $terms_to_exclude The terms to exclude. + */ + $terms_to_exclude = apply_filters( 'wpseo_exclude_from_sitemap_by_term_ids', [] ); + + foreach ( $terms as $term ) { + + if ( in_array( $term->term_id, $terms_to_exclude, true ) ) { + continue; + } + + $url = []; + + $tax_noindex = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'noindex' ); + + if ( $tax_noindex === 'noindex' ) { + continue; + } + + $canonical = WPSEO_Taxonomy_Meta::get_term_meta( $term, $term->taxonomy, 'canonical' ); + $url['loc'] = get_term_link( $term, $term->taxonomy ); + + if ( is_string( $canonical ) && $canonical !== '' && $canonical !== $url['loc'] ) { + continue; + } + + $current_replacements = $replacements; + array_splice( $current_replacements, 9, 0, $term->taxonomy ); + array_splice( $current_replacements, 11, 0, $term->term_id ); + + //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to use a direct query here. + //phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching -- Reason: No relevant caches. + $url['mod'] = $wpdb->get_var( + //phpcs:disable WordPress.DB.PreparedSQLPlaceholders -- %i placeholder is still not recognized. + $wpdb->prepare( + ' + SELECT MAX(p.%i) AS lastmod + FROM %i AS p + INNER JOIN %i AS term_rel + ON term_rel.%i = p.%i + INNER JOIN %i AS term_tax + ON term_tax.%i = term_rel.%i + AND term_tax.%i = %s + AND term_tax.%i = %d + WHERE p.%i IN (' . implode( ', ', array_fill( 0, count( $post_statuses ), '%s' ) ) . ") + AND p.%i = '' + ", + $current_replacements, + ), + ); + + if ( $this->include_images ) { + $url['images'] = $this->get_image_parser()->get_term_images( $term ); + } + + // Deprecated, kept for backwards data compat. R. + $url['chf'] = 'daily'; + $url['pri'] = 1; + + /** This filter is documented at inc/sitemaps/class-post-type-sitemap-provider.php */ + $url = apply_filters( 'wpseo_sitemap_entry', $url, 'term', $term ); + + if ( ! empty( $url ) ) { + $links[] = $url; + } + } + + return $links; + } + + /** + * Check if taxonomy by name is valid to appear in sitemaps. + * + * @param string $taxonomy_name Taxonomy name to check. + * + * @return bool + */ + public function is_valid_taxonomy( $taxonomy_name ) { + + if ( WPSEO_Options::get( "noindex-tax-{$taxonomy_name}" ) === true ) { + return false; + } + + if ( in_array( $taxonomy_name, [ 'link_category', 'nav_menu', 'wp_pattern_category' ], true ) ) { + return false; + } + + if ( $taxonomy_name === 'post_format' && WPSEO_Options::get( 'disable-post_format', false ) ) { + return false; + } + + /** + * Filter to exclude the taxonomy from the XML sitemap. + * + * @param bool $exclude Defaults to false. + * @param string $taxonomy_name Name of the taxonomy to exclude.. + */ + if ( apply_filters( 'wpseo_sitemap_exclude_taxonomy', false, $taxonomy_name ) ) { + return false; + } + + return true; + } + + /** + * Get the Image Parser. + * + * @return WPSEO_Sitemap_Image_Parser + */ + protected function get_image_parser() { + if ( ! isset( self::$image_parser ) ) { + self::$image_parser = new WPSEO_Sitemap_Image_Parser(); + } + + return self::$image_parser; + } +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/sitemaps/interface-sitemap-cache-data.php b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/interface-sitemap-cache-data.php new file mode 100644 index 0000000..9cfdf0a --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/sitemaps/interface-sitemap-cache-data.php @@ -0,0 +1,72 @@ +ID ); + return $primary_term->get_primary_term(); + } +} + +if ( ! function_exists( 'yoast_get_primary_term' ) ) { + /** + * Get the primary term name. + * + * @param string $taxonomy Optional. The taxonomy to get the primary term for. Defaults to category. + * @param int|WP_Post|null $post Optional. Post to get the primary term for. + * + * @return string Name of the primary term. + */ + function yoast_get_primary_term( $taxonomy = 'category', $post = null ) { + $primary_term_id = yoast_get_primary_term_id( $taxonomy, $post ); + + $term = get_term( $primary_term_id ); + if ( ! is_wp_error( $term ) && ! empty( $term ) ) { + return $term->name; + } + + return ''; + } +} + +/** + * Replace `%%variable_placeholders%%` with their real value based on the current requested page/post/cpt. + * + * @param string $text The string to replace the variables in. + * @param object $args The object some of the replacement values might come from, + * could be a post, taxonomy or term. + * @param array $omit Variables that should not be replaced by this function. + * + * @return string + */ +function wpseo_replace_vars( $text, $args, $omit = [] ) { + $replacer = new WPSEO_Replace_Vars(); + + return $replacer->replace( $text, $args, $omit ); +} + +/** + * Register a new variable replacement. + * + * This function is for use by other plugins/themes to easily add their own additional variables to replace. + * This function should be called from a function on the 'wpseo_register_extra_replacements' action hook. + * The use of this function is preferred over the older 'wpseo_replacements' filter as a way to add new replacements. + * The 'wpseo_replacements' filter should still be used to adjust standard WPSEO replacement values. + * The function can not be used to replace standard WPSEO replacement value functions and will thrown a warning + * if you accidently try. + * To avoid conflicts with variables registered by WPSEO and other themes/plugins, try and make the + * name of your variable unique. Variable names also can not start with "%%cf_" or "%%ct_" as these are reserved + * for the standard WPSEO variable variables 'cf_', 'ct_' and + * 'ct_desc_'. + * The replacement function will be passed the undelimited name (i.e. stripped of the %%) of the variable + * to replace in case you need it. + * + * Example code: + * + * + * + * + * @since 1.5.4 + * + * @param string $replacevar_name The name of the variable to replace, i.e. '%%var%%'. + * Note: the surrounding %% are optional, name can only contain [A-Za-z0-9_-]. + * @param mixed $replace_function Function or method to call to retrieve the replacement value for the variable. + * Uses the same format as add_filter/add_action function parameter and + * should *return* the replacement value. DON'T echo it. + * @param string $type Type of variable: 'basic' or 'advanced', defaults to 'advanced'. + * @param string $help_text Help text to be added to the help tab for this variable. + * + * @return bool Whether the replacement function was successfully registered. + */ +function wpseo_register_var_replacement( $replacevar_name, $replace_function, $type = 'advanced', $help_text = '' ) { + return WPSEO_Replace_Vars::register_replacement( $replacevar_name, $replace_function, $type, $help_text ); +} + +/** + * WPML plugin support: Set titles for custom types / taxonomies as translatable. + * + * It adds new keys to a wpml-config.xml file for a custom post type title, metadesc, + * title-ptarchive and metadesc-ptarchive fields translation. + * Documentation: http://wpml.org/documentation/support/language-configuration-files/ + * + * @global $sitepress + * + * @param array $config WPML configuration data to filter. + * + * @return array + */ +function wpseo_wpml_config( $config ) { + global $sitepress; + + if ( ( is_array( $config ) && isset( $config['wpml-config']['admin-texts']['key'] ) ) && ( is_array( $config['wpml-config']['admin-texts']['key'] ) && $config['wpml-config']['admin-texts']['key'] !== [] ) ) { + $admin_texts = $config['wpml-config']['admin-texts']['key']; + foreach ( $admin_texts as $k => $val ) { + if ( $val['attr']['name'] === 'wpseo_titles' ) { + $translate_cp = array_keys( $sitepress->get_translatable_documents() ); + if ( is_array( $translate_cp ) && $translate_cp !== [] ) { + foreach ( $translate_cp as $post_type ) { + $admin_texts[ $k ]['key'][]['attr']['name'] = 'title-' . $post_type; + $admin_texts[ $k ]['key'][]['attr']['name'] = 'metadesc-' . $post_type; + $admin_texts[ $k ]['key'][]['attr']['name'] = 'title-ptarchive-' . $post_type; + $admin_texts[ $k ]['key'][]['attr']['name'] = 'metadesc-ptarchive-' . $post_type; + + $translate_tax = $sitepress->get_translatable_taxonomies( false, $post_type ); + if ( is_array( $translate_tax ) && $translate_tax !== [] ) { + foreach ( $translate_tax as $taxonomy ) { + $admin_texts[ $k ]['key'][]['attr']['name'] = 'title-tax-' . $taxonomy; + $admin_texts[ $k ]['key'][]['attr']['name'] = 'metadesc-tax-' . $taxonomy; + } + } + } + } + break; + } + } + $config['wpml-config']['admin-texts']['key'] = $admin_texts; + } + + return $config; +} + +add_filter( 'icl_wpml_config_array', 'wpseo_wpml_config' ); + +if ( ! function_exists( 'ctype_digit' ) ) { + /** + * Emulate PHP native ctype_digit() function for when the ctype extension would be disabled *sigh*. + * Only emulates the behaviour for when the input is a string, does not handle integer input as ascii value. + * + * @param string $text String input to validate. + * + * @return bool + */ + function ctype_digit( $text ) { + $return = false; + if ( ( is_string( $text ) && $text !== '' ) && preg_match( '`^\d+$`', $text ) === 1 ) { + $return = true; + } + + return $return; + } +} + +/** + * Makes sure the taxonomy meta is updated when a taxonomy term is split. + * + * @link https://make.wordpress.org/core/2015/02/16/taxonomy-term-splitting-in-4-2-a-developer-guide/ Article explaining the taxonomy term splitting in WP 4.2. + * + * @param string $old_term_id Old term id of the taxonomy term that was splitted. + * @param string $new_term_id New term id of the taxonomy term that was splitted. + * @param string $term_taxonomy_id Term taxonomy id for the taxonomy that was affected. + * @param string $taxonomy The taxonomy that the taxonomy term was splitted for. + * + * @return void + */ +function wpseo_split_shared_term( $old_term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { + $tax_meta = get_option( 'wpseo_taxonomy_meta', [] ); + + if ( ! empty( $tax_meta[ $taxonomy ][ $old_term_id ] ) ) { + $tax_meta[ $taxonomy ][ $new_term_id ] = $tax_meta[ $taxonomy ][ $old_term_id ]; + unset( $tax_meta[ $taxonomy ][ $old_term_id ] ); + update_option( 'wpseo_taxonomy_meta', $tax_meta ); + } +} + +add_action( 'split_shared_term', 'wpseo_split_shared_term', 10, 4 ); + +/** + * Get all WPSEO related capabilities. + * + * @since 8.3 + * @return array + */ +function wpseo_get_capabilities() { + if ( ! did_action( 'wpseo_register_capabilities' ) ) { + do_action( 'wpseo_register_capabilities' ); + } + return WPSEO_Capability_Manager_Factory::get()->get_capabilities(); +} diff --git a/html/wp-content/plugins/wordpress-seo/inc/wpseo-non-ajax-functions.php b/html/wp-content/plugins/wordpress-seo/inc/wpseo-non-ajax-functions.php new file mode 100644 index 0000000..3563be6 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/inc/wpseo-non-ajax-functions.php @@ -0,0 +1,57 @@ +register_hooks(); +} +add_action( 'wp_loaded', 'wpseo_initialize_admin_bar' ); + +/** + * Allows editing of the meta fields through weblog editors like Marsedit. + * + * @param array $required_capabilities Capabilities that must all be true to allow action. + * @param array $capabilities Array of capabilities to be checked, unused here. + * @param array $args List of arguments for the specific capabilities to be checked. + * + * @return array Filtered capabilities. + */ +function allow_custom_field_edits( $required_capabilities, $capabilities, $args ) { + if ( ! in_array( $args[0], [ 'edit_post_meta', 'add_post_meta' ], true ) ) { + return $required_capabilities; + } + + // If this is provided, it is the post ID. + if ( empty( $args[2] ) ) { + return $required_capabilities; + } + + // If this is provided, it is the custom field. + if ( empty( $args[3] ) ) { + return $required_capabilities; + } + + // If the meta key is part of the plugin, grant capabilities accordingly. + if ( strpos( $args[3], WPSEO_Meta::$meta_prefix ) === 0 && current_user_can( 'edit_post', $args[2] ) ) { + $required_capabilities[ $args[0] ] = true; + } + + return $required_capabilities; +} + +add_filter( 'user_has_cap', 'allow_custom_field_edits', 0, 3 ); diff --git a/html/wp-content/plugins/wordpress-seo/index.php b/html/wp-content/plugins/wordpress-seo/index.php new file mode 100644 index 0000000..e94d9a4 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/index.php @@ -0,0 +1,4 @@ +{"use strict";var e={n:t=>{var s=t&&t.__esModule?()=>t.default:()=>t;return e.d(s,{a:s}),s},d:(t,s)=>{for(var a in s)e.o(s,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:s[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.wp.components,s=window.wp.data,a=window.wp.domReady;var r=e.n(a);const i=window.wp.element,o=window.yoast.uiLibrary,n=window.lodash,d=window.wp.i18n,l=window.yoast.reduxJsToolkit,c="adminUrl",u=(0,l.createSlice)({name:c,initialState:"",reducers:{setAdminUrl:(e,{payload:t})=>t}}),y=(u.getInitialState,{selectAdminUrl:e=>(0,n.get)(e,c,"")});y.selectAdminLink=(0,l.createSelector)([y.selectAdminUrl,(e,t)=>t],((e,t="")=>{try{return new URL(t,e).href}catch(t){return e}})),u.actions,u.reducer,window.wp.apiFetch;const p="hasConsent",m=(0,l.createSlice)({name:p,initialState:{hasConsent:!1,endpoint:"yoast/v1/ai_generator/consent"},reducers:{giveAiGeneratorConsent:(e,{payload:t})=>{e.hasConsent=t},setAiGeneratorConsentEndpoint:(e,{payload:t})=>{e.endpoint=t}}}),g=(m.getInitialState,m.actions,m.reducer,window.wp.url),h="linkParams",w=(0,l.createSlice)({name:h,initialState:{},reducers:{setLinkParams:(e,{payload:t})=>t}}),f=w.getInitialState,k={selectLinkParam:(e,t,s={})=>(0,n.get)(e,`${h}.${t}`,s),selectLinkParams:e=>(0,n.get)(e,h,{})};k.selectLink=(0,l.createSelector)([k.selectLinkParams,(e,t)=>t,(e,t,s={})=>s],((e,t,s)=>(0,g.addQueryArgs)(t,{...e,...s})));const _=w.actions,v=w.reducer,S=(0,l.createSlice)({name:"notifications",initialState:{},reducers:{addNotification:{reducer:(e,{payload:t})=>{e[t.id]={id:t.id,variant:t.variant,size:t.size,title:t.title,description:t.description}},prepare:({id:e,variant:t="info",size:s="default",title:a,description:r})=>({payload:{id:e||(0,l.nanoid)(),variant:t,size:s,title:a||"",description:r}})},removeNotification:(e,{payload:t})=>(0,n.omit)(e,t)}}),b=(S.getInitialState,S.actions,S.reducer,"pluginUrl"),x=(0,l.createSlice)({name:b,initialState:"",reducers:{setPluginUrl:(e,{payload:t})=>t}}),L=(x.getInitialState,{selectPluginUrl:e=>(0,n.get)(e,b,"")});L.selectImageLink=(0,l.createSelector)([L.selectPluginUrl,(e,t,s="images")=>s,(e,t)=>t],((e,t,s)=>[(0,n.trimEnd)(e,"/"),(0,n.trim)(t,"/"),(0,n.trimStart)(s,"/")].join("/"))),x.actions,x.reducer;const E="wistiaEmbedPermission",A=(0,l.createSlice)({name:E,initialState:{value:!1,status:"idle",error:{}},reducers:{setWistiaEmbedPermissionValue:(e,{payload:t})=>{e.value=Boolean(t)}},extraReducers:e=>{e.addCase(`${E}/request`,(e=>{e.status="loading"})),e.addCase(`${E}/success`,((e,{payload:t})=>{e.status="success",e.value=Boolean(t&&t.value)})),e.addCase(`${E}/error`,((e,{payload:t})=>{e.status="error",e.value=Boolean(t&&t.value),e.error={code:(0,n.get)(t,"error.code",500),message:(0,n.get)(t,"error.message","Unknown")}}))}});var P;A.getInitialState,A.actions,A.reducer;const O=(0,l.createSlice)({name:"documentTitle",initialState:(0,n.defaultTo)(null===(P=document)||void 0===P?void 0:P.title,""),reducers:{setDocumentTitle:(e,{payload:t})=>t}}),j=(O.getInitialState,O.actions,O.reducer,window.React),I=j.forwardRef((function(e,t){return j.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),j.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 11V7a4 4 0 118 0m-4 8v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2z"}))})),Q=j.forwardRef((function(e,t){return j.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),j.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"}))})),T=j.forwardRef((function(e,t){return j.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 20 20",fill:"currentColor","aria-hidden":"true",ref:t},e),j.createElement("path",{fillRule:"evenodd",d:"M10.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L12.586 11H5a1 1 0 110-2h7.586l-2.293-2.293a1 1 0 010-1.414z",clipRule:"evenodd"}))})),$="@yoast/academy",M=(e,t=[],...a)=>(0,s.useSelect)((t=>{var s,r;return null===(s=(r=t($))[e])||void 0===s?void 0:s.call(r,...a)}),t),R=window.ReactJSXRuntime,U=(e,t)=>!(!(0,n.isEmpty)(e)&&!t)||Object.values(e).every((e=>!0===e)),C=(e,t)=>!(0,n.isEmpty)(e)&&(t||e.WOO||e.LOCAL),N=()=>{const e=M("selectLinkParams"),t=M("selectPreference",[],"pluginUrl",""),s=M("selectPreference",[],"isPremium",""),a=M("selectPreference",[],"isWooActive",""),r=M("selectPreference",[],"isLocalActive",""),n=M("selectUpsellSettingsAsProps"),l=(0,o.useSvgAria)(),c=(0,i.useMemo)((()=>[{id:"ai_for_seo",title:"AI for SEO",description:(0,d.__)("Join the Yoast team to learn how to harness the power of AI to revolutionize your SEO approach. Gain a competitive edge, future-proof your keyword strategies, and soar to the top of search rankings – all designed to empower busy small business owners.","wordpress-seo"),image:`${t}/images/academy/ai_for_seo_icon_my_yoast.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/ai-for-seo-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/ai-for-seo-unlock",e),dependencies:{PREMIUM:s},hasTrial:!0},{id:"seo_for_beginners",title:"SEO for beginners",description:(0,d.__)("In this free course, you'll get quick wins to make your site rank higher in Google, Bing, and Yahoo.","wordpress-seo"),image:`${t}/images/academy/seo_for_beginners.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-seo-beginners-start",e),dependencies:{},hasTrial:!0},{id:"seo_for_wp",title:"Yoast SEO for WordPress (block editor)",description:(0,d.sprintf)(/* translators: %1$s expands to Yoast SEO. */ +(0,d.__)("In this course, you'll learn about how to set up and use the %1$s for WordPress plugin so it makes SEO even easier. This course is meant for users of the block editor.","wordpress-seo"),"Yoast SEO"),image:`${t}/images/academy/seo_for_wp.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-seo-wordpress-block-editor-start",e),dependencies:{},hasTrial:!0},{id:"all_around_seo",title:"All-around SEO",description:(0,d.__)("In this course, you'll learn practical SEO skills on every key aspect of SEO, to make your site stand out.","wordpress-seo"),image:`${t}/images/academy/all_around_seo.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-all-around-seo-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-all-around-seo-unlock",e),dependencies:{PREMIUM:s},hasTrial:!0},{id:"wp_for_beginners",title:"WordPress for beginners",description:(0,d.__)("Do you want to set up your own WordPress site? This course will teach you the ins and outs of creating and maintaining a WordPress website!","wordpress-seo"),image:`${t}/images/academy/wp_for_beginners.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-wordpress-beginners-start",e),dependencies:{},hasTrial:!0},{id:"copywriting",title:"SEO copywriting",description:(0,d.__)("In this course, you'll learn how to write awesome copy that is optimized for ranking in search engines.","wordpress-seo"),image:`${t}/images/academy/copywriting.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-seo-copywriting-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-seo-copywriting-unlock",e),dependencies:{PREMIUM:s},hasTrial:!0},{id:"structured_data_for_beginners",title:"Structured data for beginners",description:(0,d.__)("Learn how to make your site stand out from the crowd by adding structured data!","wordpress-seo"),image:`${t}/images/academy/structured_data_for_beginners.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-structured-data-beginners-start",e),dependencies:{},hasTrial:!0},{id:"keyword_research",title:"Keyword research",description:(0,d.__)("Do you know the essential first step of good SEO? It's keyword research. In this training, you'll learn how to research and select the keywords that will guide searchers to your pages.","wordpress-seo"),image:`${t}/images/academy/keyword_research.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-keyword-research-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-keyword-research-unlock",e),dependencies:{PREMIUM:s},hasTrial:!0},{id:"block_editor",title:"Block editor training",description:(0,d.__)("Start creating block-tastic content with the new WordPress block editor! Learn all about the block editor and what you can do with it.","wordpress-seo"),image:`${t}/images/academy/block_editor.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-block-editor-start",e),dependencies:{},hasTrial:!0},{id:"site_structure",title:"Site structure",description:(0,d.__)("A clear site structure benefits your users and is of great importance for SEO. Still, most people seem to forget about this. Get ahead of your competition and learn how to improve your site structure!","wordpress-seo"),image:`${t}/images/academy/site_structure.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-site-structure-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-site-structure-unlock",e),dependencies:{PREMIUM:s},hasTrial:!0},{id:"local",title:"Local SEO",description:(0,d.__)("Do you own a local business? This course will teach you how to make sure your local audience can find you in the search results and on Google Maps!","wordpress-seo"),image:`${t}/images/academy/local.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-local-seo-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-local-seo-unlock",e),dependencies:{LOCAL:r},hasTrial:!0},{id:"ecommerce",title:"Ecommerce SEO",description:(0,d.__)("Learn how to optimize your online shop for your customers and for search engines!","wordpress-seo"),image:`${t}/images/academy/ecommerce.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-ecommerce-seo-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-ecommerce-seo-unlock",e),dependencies:{WOO:a},hasTrial:!0},{id:"understanding_structured_data",title:"Understanding structured data",description:(0,d.__)("Do you want to take a deep dive into structured data? In this course, you'll learn the theory related to structured data in detail.","wordpress-seo"),image:`${t}/images/academy/understanding_structured_data.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-understanding-structured-data-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-understanding-structured-data-unlock",e),dependencies:{PREMIUM:s},hasTrial:!1},{id:"multilingual",title:"International SEO",description:(0,d.__)("Are you selling in countries all over the world? In this course, you’ll learn all about setting up and managing a site that targets people in different languages and locales.","wordpress-seo"),image:`${t}/images/academy/multilingual.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-international-seo-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-international-seo-unlock",e),dependencies:{PREMIUM:s},hasTrial:!0},{id:"crawlability",title:"Technical SEO: Crawlability and indexability",description:(0,d.__)("You have to make it possible for search engines to find your site, so they can display it in the search results. We'll tell you all about how that works in this course!","wordpress-seo"),image:`${t}/images/academy/crawlability.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-technical-seo-crawlability-indexability-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-technical-seo-crawlability-indexability-unlock",e),dependencies:{PREMIUM:s},hasTrial:!0},{id:"hosting_and_server",title:"Technical SEO: Hosting and server configuration",description:(0,d.__)("Choosing the right type of hosting for your site is the basis of a solid Technical SEO strategy. Learn all about it in this course!","wordpress-seo"),image:`${t}/images/academy/hosting_and_server.png`,startLink:(0,g.addQueryArgs)("https://yoa.st/academy-technical-seo-hosting-server-configuration-start",e),upsellLink:(0,g.addQueryArgs)("https://yoa.st/academy-technical-seo-hosting-server-configuration-unlock",e),dependencies:{PREMIUM:s},hasTrial:!1}]),[e]);return(0,R.jsx)("div",{className:"yst-p-4 min-[783px]:yst-p-8 yst-mb-8 xl:yst-mb-0",children:(0,R.jsxs)(o.Paper,{as:"main",className:"yst-max-w-page",children:[(0,R.jsx)("header",{className:"yst-p-8 yst-border-b yst-border-slate-200",children:(0,R.jsxs)("div",{className:"yst-max-w-screen-sm",children:[(0,R.jsx)(o.Title,{children:(0,d.__)("Academy","wordpress-seo")}),(0,R.jsxs)("p",{className:"yst-text-tiny yst-mt-3",children:[s&&(0,d.sprintf)( +// translators: %s for Yoast SEO Premium. +(0,d.__)("Learn vital SEO skills that you can apply at once! Let us take you by the hand and give you practical SEO tips to help you outrank your competitors. Maximize your SEO game! Because your %s subscription gives you unlimited access to all courses.","wordpress-seo"),"Yoast SEO Premium"),!s&&(0,R.jsxs)(R.Fragment,{children:[(0,d.sprintf)( +// translators: %s for Yoast SEO. +(0,d.__)("Learn vital SEO skills that you can apply at once! Let us take you by the hand and give you practical SEO tips to help you outrank your competitors. %s comes with five free courses.","wordpress-seo"),"Yoast SEO")," ",(0,R.jsx)(o.Link,{href:(0,g.addQueryArgs)("https://yoa.st/academy-page-upsell/",e),target:"_blank",...n,children:(0,d.sprintf)( +// translators: %s for Yoast SEO Premium. +(0,d.__)("Maximize your SEO game by purchasing %s, which grants you unlimited access to all courses.","wordpress-seo"),"Yoast SEO Premium")})]})]})]})}),(0,R.jsx)("div",{className:"yst-h-full yst-p-8",children:(0,R.jsx)("div",{className:"yst-max-w-6xl yst-grid yst-gap-6 yst-grid-cols-1 sm:yst-grid-cols-2 min-[783px]:yst-grid-cols-1 lg:yst-grid-cols-2 xl:yst-grid-cols-4",children:c.map((e=>(0,R.jsxs)(o.Card,{children:[(0,R.jsxs)(o.Card.Header,{className:"yst-h-auto yst-p-0",children:[(0,R.jsx)("img",{className:"yst-w-full yst-transition yst-duration-200",src:e.image,alt:"",width:500,height:250,loading:"lazy",decoding:"async"}),C(e.dependencies,s)&&(0,R.jsx)("div",{className:"yst-absolute yst-top-2 yst-end-2 yst-flex yst-gap-1.5",children:(0,R.jsx)(o.Badge,{size:"small",variant:"upsell",children:(0,d.__)("Premium","wordpress-seo")})})]}),(0,R.jsxs)(o.Card.Content,{className:"yst-flex yst-flex-col yst-gap-3",children:[(0,R.jsx)(o.Title,{as:"h3",children:e.title}),e.description,!U(e.dependencies,s)&&(0,R.jsxs)(o.Link,{href:e.startLink,className:"yst-flex yst-items-center yst-mt-3 yst-no-underline yst-font-medium yst-text-primary-500",target:"_blank",children:[(0,d.__)("Start free trial lesson","wordpress-seo"),(0,R.jsx)("span",{className:"yst-sr-only",children:/* translators: Hidden accessibility text. */ +(0,d.__)("(Opens in a new browser tab)","wordpress-seo")}),(0,R.jsx)(T,{className:"yst-h-4 yst-w-4 yst-ms-1 yst-icon-rtl"})]})]}),(0,R.jsx)(o.Card.Footer,{children:(0,R.jsxs)(R.Fragment,{children:[!U(e.dependencies,s)&&(0,R.jsxs)(o.Button,{as:"a",id:`button-get-course-${e.id}`,className:"yst-gap-2 yst-w-full yst-px-2",variant:"upsell",href:null==e?void 0:e.upsellLink,target:"_blank",rel:"noopener",...n,children:[(0,R.jsx)(I,{className:"yst-w-5 yst-h-5 yst--ms-1 yst-shrink-0",...l}),(0,d.sprintf)(/* translators: %1$s expands to Premium. */ +(0,d.__)("Unlock with %1$s","wordpress-seo"),"Premium")]}),U(e.dependencies,s)&&(0,R.jsxs)(o.Button,{as:"a",id:`button-start-course-${e.id}`,className:"yst-gap-2 yst-w-full yst-px-2 yst-leading-5",variant:"primary",href:e.startLink,target:"_blank",rel:"noopener",children:[(0,d.__)("Start the course","wordpress-seo"),(0,R.jsx)(Q,{className:"yst--me-1 yst-ms-1 yst-h-5 yst-w-5 yst-text-white rtl:yst-rotate-[270deg]"})]})]})})]},`card-course-${e.id}`)))})})]})})},B=()=>({...(0,n.get)(window,"wpseoScriptData.preferences",{})}),z=(0,l.createSlice)({name:"preferences",initialState:B(),reducers:{}}),W={selectPreference:(e,t,s={})=>(0,n.get)(e,`preferences.${t}`,s),selectPreferences:e=>(0,n.get)(e,"preferences",{})};W.selectUpsellSettingsAsProps=(0,l.createSelector)([e=>W.selectPreference(e,"upsellSettings",{}),(e,t="premiumCtbId")=>t],((e,t)=>({"data-action":null==e?void 0:e.actionId,"data-ctb-id":null==e?void 0:e[t]})));const Y=z.actions,D=z.reducer;r()((()=>{const e=document.getElementById("yoast-seo-academy");if(!e)return;(({initialState:e={}}={})=>{(0,s.register)((({initialState:e})=>(0,s.createReduxStore)($,{actions:{..._,...Y},selectors:{...k,...W},initialState:(0,n.merge)({},{[h]:f(),preferences:B()},e),reducer:(0,s.combineReducers)({[h]:v,preferences:D})}))({initialState:e}))})({initialState:{[h]:(0,n.get)(window,"wpseoScriptData.linkParams",{})}}),(()=>{const e=document.getElementById("wpcontent"),t=document.getElementById("adminmenuwrap");e&&t&&(e.style.minHeight=`${t.offsetHeight}px`)})();const a=(0,s.select)($).selectPreference("isRtl",!1);(0,i.createRoot)(e).render((0,R.jsx)(o.Root,{context:{isRtl:a},children:(0,R.jsx)(t.SlotFillProvider,{children:(0,R.jsx)(N,{})})}))}))})(); \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/js/dist/addon-installation.js b/html/wp-content/plugins/wordpress-seo/js/dist/addon-installation.js new file mode 100644 index 0000000..f9fdd43 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/js/dist/addon-installation.js @@ -0,0 +1,7 @@ +(()=>{"use strict";var e={n:n=>{var s=n&&n.__esModule?()=>n.default:()=>n;return e.d(s,{a:s}),s},d:(n,s)=>{for(var t in s)e.o(s,t)&&!e.o(n,t)&&Object.defineProperty(n,t,{enumerable:!0,get:s[t]})},o:(e,n)=>Object.prototype.hasOwnProperty.call(e,n)};const n=window.wp.element,s=window.wp.i18n,t=window.yoast.componentsNew,o=window.yoast.propTypes;var a=e.n(o);const l=window.yoast.styledComponents;var i=e.n(l);const r=window.React;var d,c;function p(){return p=Object.assign?Object.assign.bind():function(e){for(var n=1;nr.createElement("svg",p({xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",viewBox:"0 0 425 456.27"},e),d||(d=r.createElement("path",{d:"M73 405.26a66.79 66.79 0 0 1-6.54-1.7 64.75 64.75 0 0 1-6.28-2.31c-1-.42-2-.89-3-1.37-1.49-.72-3-1.56-4.77-2.56-1.5-.88-2.71-1.64-3.83-2.39-.9-.61-1.8-1.26-2.68-1.92a70.154 70.154 0 0 1-5.08-4.19 69.21 69.21 0 0 1-8.4-9.17c-.92-1.2-1.68-2.25-2.35-3.24a70.747 70.747 0 0 1-3.44-5.64 68.29 68.29 0 0 1-8.29-32.55V142.13a68.26 68.26 0 0 1 8.29-32.55c1-1.92 2.21-3.82 3.44-5.64s2.55-3.58 4-5.27a69.26 69.26 0 0 1 14.49-13.25C50.37 84.19 52.27 83 54.2 82A67.59 67.59 0 0 1 73 75.09a68.75 68.75 0 0 1 13.75-1.39h169.66L263 55.39H86.75A86.84 86.84 0 0 0 0 142.13v196.09A86.84 86.84 0 0 0 86.75 425h11.32v-18.35H86.75A68.75 68.75 0 0 1 73 405.26zM368.55 60.85l-1.41-.53-6.41 17.18 1.41.53a68.06 68.06 0 0 1 8.66 4c1.93 1 3.82 2.2 5.65 3.43A69.19 69.19 0 0 1 391 98.67c1.4 1.68 2.72 3.46 3.95 5.27s2.39 3.72 3.44 5.64a68.29 68.29 0 0 1 8.29 32.55v264.52H233.55l-.44.76c-3.07 5.37-6.26 10.48-9.49 15.19L222 425h203V142.13a87.2 87.2 0 0 0-56.45-81.28z"})),c||(c=r.createElement("path",{stroke:"#000",strokeMiterlimit:10,strokeWidth:3.81,d:"M119.8 408.28v46c28.49-1.12 50.73-10.6 69.61-29.58 19.45-19.55 36.17-50 52.61-96L363.94 1.9H305l-98.25 272.89-48.86-153h-54l71.7 184.18a75.67 75.67 0 0 1 0 55.12c-7.3 18.68-20.25 40.66-55.79 47.19z"}))),u=window.wp.components,h=window.ReactJSXRuntime,m=({title:e="Yoast SEO",className:n="yoast yoast-gutenberg-modal",showYoastIcon:s=!0,children:t=null,additionalClassName:o="",...a})=>{const l=s?(0,h.jsx)("span",{className:"yoast-icon"}):null;return(0,h.jsx)(u.Modal,{title:e,className:`${n} ${o}`,icon:l,...a,children:t})};m.propTypes={title:a().string,className:a().string,showYoastIcon:a().bool,children:a().oneOfType([a().node,a().arrayOf(a().node)]),additionalClassName:a().string};const y=m,g=i().div` + display: flex; + justify-content: flex-end; + gap: 8px; +`,v=({nonce:e,addons:o=[]})=>{const[a,l]=(0,n.useState)(!0),i=(0,n.useCallback)((()=>{l(!1)}),[l]),r=(0,n.useCallback)((()=>{window.location.href="admin.php?page=wpseo_licenses&action=install&nonce="+e}),[e]),d=(0,n.useCallback)((()=>(0,h.jsx)(t.Button,{onClick:i,id:"close-addon-installation-dialog",children:(0,s.__)("Cancel","wordpress-seo")})),[i]),c=(0,s.sprintf)(/* translators: %s expands to Yoast */ +(0,s.__)("%s SEO installation","wordpress-seo"),"Yoast");let p,u=(0,s.__)("the following addons","wordpress-seo");return 1===o.length&&(u=o[0]),1!==o.length&&(p=(0,h.jsx)("ul",{className:"ul-disc",children:o.map(((e,n)=>(0,h.jsx)("li",{children:e},"addon-"+n)))})),a?(0,h.jsxs)(y,{title:c,onRequestClose:i,icon:(0,h.jsx)(w,{}),isDismissible:!1,children:[(0,h.jsx)("p",{children:(0,s.sprintf)(/* translators: %s expands to Yoast SEO Premium */ +(0,s.__)("Please confirm below that you would like to install %s on this site.","wordpress-seo"),u)}),p,(0,h.jsxs)(g,{children:[d(),(0,h.jsx)(t.Button,{onClick:r,id:"continue-addon-installation-dialog",className:"yoast-button--primary",children:(0,s.__)("Install and activate","wordpress-seo")})]})]}):null};v.propTypes={nonce:a().string.isRequired,addons:a().array};const f=v,x=document.createElement("div");x.setAttribute("id","wpseo-app-element"),document.getElementById("extensions").append(x),(0,n.createRoot)(x).render((0,h.jsx)(f,{nonce:wpseoAddonInstallationL10n.nonce,addons:wpseoAddonInstallationL10n.addons}))})(); \ No newline at end of file diff --git a/html/wp-content/plugins/wordpress-seo/js/dist/admin-global.js b/html/wp-content/plugins/wordpress-seo/js/dist/admin-global.js new file mode 100644 index 0000000..a6b9809 --- /dev/null +++ b/html/wp-content/plugins/wordpress-seo/js/dist/admin-global.js @@ -0,0 +1 @@ +(()=>{"use strict";var t={n:o=>{var e=o&&o.__esModule?()=>o.default:()=>o;return t.d(e,{a:e}),e},d:(o,e)=>{for(var a in e)t.o(e,a)&&!t.o(o,a)&&Object.defineProperty(o,a,{enumerable:!0,get:e[a]})},o:(t,o)=>Object.prototype.hasOwnProperty.call(t,o)};const o=window.jQuery;var e=t.n(o);const a={fresh:"#2c3338",light:"#fff",modern:"#1e1e1e",blue:"#4796b3",coffee:"#46403c",ectoplasm:"#413256",midnight:"#26292c",ocean:"#627c83",sunrise:"#be3631"},n="fresh";!function(t){function o(t,o,a){const n=new FormData,s={action:"wpseo_set_ignore",option:t,_wpnonce:a};for(const[t,o]of Object.entries(s))n.append(t,o);return fetch(ajaxurl,{method:"POST",body:n}).then((a=>(a&&(e()("#"+o).hide(),e()("#hidden_ignore_"+t).val("ignore")),a)))}function s(){t("#wp-admin-bar-root-default > li").off("mouseenter.yoastalertpopup mouseleave.yoastalertpopup"),t(".yoast-issue-added").fadeOut(200)}function i(o,e){if(t(".yoast-notification-holder").off("click",".restore").off("click",".dismiss"),void 0!==e.html){e.html&&(o.closest(".yoast-container").html(e.html),r());var a=t("#wp-admin-bar-wpseo-menu"),n=a.find(".yoast-issue-counter");n.length||(a.find("> a:first-child").append('
            '),n=a.find(".yoast-issue-counter")),n.html(e.total),0===e.total?n.hide():n.show(),t("#toplevel_page_wpseo_dashboard .update-plugins").removeClass().addClass("update-plugins count-"+e.total),t("#toplevel_page_wpseo_dashboard .plugin-count").html(e.total)}}function r(){var o=t(".yoast-notification-holder");o.on("click",".dismiss",(function(){var o=t(this),e=o.closest(".yoast-notification-holder");o.closest(".yoast-container").append('
            '),t.post(ajaxurl,{action:"yoast_dismiss_notification",notification:e.attr("id"),nonce:e.data("nonce"),data:o.data("json")||e.data("json")},i.bind(this,e),"json")})),o.on("click",".restore",(function(){var o=t(this),e=o.closest(".yoast-notification-holder");o.closest(".yoast-container").append('
            '),t.post(ajaxurl,{action:"yoast_restore_notification",notification:e.attr("id"),nonce:e.data("nonce"),data:e.data("json")},i.bind(this,e),"json")}))}function l(t){t.is(":hidden")||(t.outerWidth()>t.parent().outerWidth()?(t.data("scrollHint").addClass("yoast-has-scroll"),t.data("scrollContainer").addClass("yoast-has-scroll")):(t.data("scrollHint").removeClass("yoast-has-scroll"),t.data("scrollContainer").removeClass("yoast-has-scroll")))}function c(){window.wpseoScrollableTables=t(".yoast-table-scrollable"),window.wpseoScrollableTables.length&&window.wpseoScrollableTables.each((function(){var o=t(this);if(!o.data("scrollContainer")){var e=t("
            ",{class:"yoast-table-scrollable__hintwrapper",html:"
        `,Fd.children[0].getAttribute("foo")):(Fd.innerHTML=e,Fd.textContent)},isBuiltInComponent:e=>"Transition"===e||"transition"===e?Ld:"TransitionGroup"===e||"transition-group"===e?Id:void 0,getNamespace(e,t,n){let o=t?t.ns:n;if(t&&2===o)if("annotation-xml"===t.tag){if("svg"===e)return 1;t.props.some(e=>6===e.type&&"encoding"===e.name&&null!=e.value&&("text/html"===e.value.content||"application/xhtml+xml"===e.value.content))&&(o=0)}else/^m(?:[ions]|text)$/.test(t.tag)&&"mglyph"!==e&&"malignmark"!==e&&(o=0);else t&&1===o&&("foreignObject"!==t.tag&&"desc"!==t.tag&&"title"!==t.tag||(o=0));if(0===o){if("svg"===e)return 1;if("math"===e)return 2}return o}},jd=(e,t)=>{const n=G(e);return Yc(JSON.stringify(n),!1,t,3)};function Ud(e,t){return _u(e,t)}const Hd=s("passive,once,capture"),qd=s("stop,prevent,self,ctrl,shift,alt,meta,exact,middle"),zd=s("left,right"),Wd=s("onkeyup,onkeydown,onkeypress"),Kd=(e,t)=>bu(e)&&"onclick"===e.content.toLowerCase()?Yc(t,!0):4!==e.type?eu(["(",e,`) === "onClick" ? "${t}" : (`,e,")"]):e,Jd=(e,t)=>{1!==e.type||0!==e.tagType||"script"!==e.tag&&"style"!==e.tag||t.removeNode()},Zd=[e=>{1===e.type&&e.props.forEach((t,n)=>{6===t.type&&"style"===t.name&&t.value&&(e.props[n]={type:7,name:"bind",arg:Yc("style",!0,t.loc),exp:jd(t.value.content,t.loc),modifiers:[],loc:t.loc})})}],Gd={cloak:()=>({props:[]}),html:(e,t,n)=>{const{exp:o,loc:s}=e;return o||n.onError(Ud(53,s)),t.children.length&&(n.onError(Ud(54,s)),t.children.length=0),{props:[Qc(Yc("innerHTML",!0,s),o||Yc("",!0))]}},text:(e,t,n)=>{const{exp:o,loc:s}=e;return o||n.onError(Ud(55,s)),t.children.length&&(n.onError(Ud(56,s)),t.children.length=0),{props:[Qc(Yc("textContent",!0),o?Np(o,n)>0?o:tu(n.helperString(Vc),[o],s):Yc("",!0))]}},model:(e,t,n)=>{const o=yd(e,t,n);if(!o.props.length||1===t.tagType)return o;e.arg&&n.onError(Ud(58,e.arg.loc));const{tag:s}=t,r=n.isCustomElement(s);if("input"===s||"textarea"===s||"select"===s||r){let i=Ad,a=!1;if("input"===s||r){const o=Bu(t,"type");if(o){if(7===o.type)i=Od;else if(o.value)switch(o.value.content){case"radio":i=Td;break;case"checkbox":i=Vd;break;case"file":a=!0,n.onError(Ud(59,e.loc))}}else(function(e){return e.props.some(e=>!(7!==e.type||"bind"!==e.name||e.arg&&4===e.arg.type&&e.arg.isStatic))})(t)&&(i=Od)}else"select"===s&&(i=Bd);a||(o.needRuntime=n.helper(i))}else n.onError(Ud(57,e.loc));return o.props=o.props.filter(e=>!(4===e.key.type&&"modelValue"===e.key.content)),o},on:(e,t,n)=>pd(e,t,n,t=>{const{modifiers:o}=e;if(!o.length)return t;let{key:s,value:r}=t.props[0];const{keyModifiers:i,nonKeyModifiers:a,eventOptionModifiers:l}=((e,t,n)=>{const o=[],s=[],r=[];for(let i=0;i{const{exp:o,loc:s}=e;return o||n.onError(Ud(61,s)),{props:[],needRuntime:n.helper(Pd)}}},Xd=Object.create(null);function Qd(e,t){if(!b(e)){if(!e.nodeType)return a;e=e.innerHTML}const n=function(e,t){return e+JSON.stringify(t,(e,t)=>"function"==typeof t?t.toString():t)}(e,t),s=Xd[n];if(s)return s;if("#"===e[0]){const t=document.querySelector(e);e=t?t.innerHTML:""}const r=p({hoistStatic:!0,onError:void 0,onWarn:a},t);r.isCustomElement||"undefined"==typeof customElements||(r.isCustomElement=e=>!!customElements.get(e));const{code:i}=function(e,t={}){return Nd(e,p({},$d,t,{nodeTransforms:[Jd,...Zd,...t.nodeTransforms||[]],directiveTransforms:p({},Gd,t.directiveTransforms||{}),transformHoist:null}))}(e,r),l=new Function("Vue",i)(o);return l._rc=!0,Xd[n]=l}Qi(Qd)},806:(e,t,n)=>{"use strict";function o(e,t){return function(){return e.apply(t,arguments)}}const{toString:s}=Object.prototype,{getPrototypeOf:r}=Object,{iterator:i,toStringTag:a}=Symbol,l=(c=Object.create(null),e=>{const t=s.call(e);return c[t]||(c[t]=t.slice(8,-1).toLowerCase())});var c;const u=e=>(e=e.toLowerCase(),t=>l(t)===e),p=e=>t=>typeof t===e,{isArray:d}=Array,f=p("undefined");function h(e){return null!==e&&!f(e)&&null!==e.constructor&&!f(e.constructor)&&y(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const m=u("ArrayBuffer"),g=p("string"),y=p("function"),v=p("number"),_=e=>null!==e&&"object"==typeof e,b=e=>{if("object"!==l(e))return!1;const t=r(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||a in e||i in e)},S=u("Date"),w=u("File"),C=u("Blob"),E=u("FileList"),k=u("URLSearchParams"),[x,N,T,V]=["ReadableStream","Request","Response","Headers"].map(u);function A(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let o,s;if("object"!=typeof e&&(e=[e]),d(e))for(o=0,s=e.length;o0;)if(o=n[s],t===o.toLowerCase())return o;return null}const O="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:n.g,R=e=>!f(e)&&e!==O,D=(P="undefined"!=typeof Uint8Array&&r(Uint8Array),e=>P&&e instanceof P);var P;const L=u("HTMLFormElement"),I=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),M=u("RegExp"),F=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),o={};A(n,(n,s)=>{let r;!1!==(r=t(n,s,e))&&(o[s]=r||n)}),Object.defineProperties(e,o)},$=u("AsyncFunction"),j=(U="function"==typeof setImmediate,H=y(O.postMessage),U?setImmediate:H?(q=`axios@${Math.random()}`,z=[],O.addEventListener("message",({source:e,data:t})=>{e===O&&t===q&&z.length&&z.shift()()},!1),e=>{z.push(e),O.postMessage(q,"*")}):e=>setTimeout(e));var U,H,q,z;const W="undefined"!=typeof queueMicrotask?queueMicrotask.bind(O):"undefined"!=typeof process&&process.nextTick||j;var K={isArray:d,isArrayBuffer:m,isBuffer:h,isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||y(e.append)&&("formdata"===(t=l(e))||"object"===t&&y(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&m(e.buffer),t},isString:g,isNumber:v,isBoolean:e=>!0===e||!1===e,isObject:_,isPlainObject:b,isEmptyObject:e=>{if(!_(e)||h(e))return!1;try{return 0===Object.keys(e).length&&Object.getPrototypeOf(e)===Object.prototype}catch(e){return!1}},isReadableStream:x,isRequest:N,isResponse:T,isHeaders:V,isUndefined:f,isDate:S,isFile:w,isBlob:C,isRegExp:M,isFunction:y,isStream:e=>_(e)&&y(e.pipe),isURLSearchParams:k,isTypedArray:D,isFileList:E,forEach:A,merge:function e(){const{caseless:t,skipUndefined:n}=R(this)&&this||{},o={},s=(s,r)=>{const i=t&&B(o,r)||r;b(o[i])&&b(s)?o[i]=e(o[i],s):b(s)?o[i]=e({},s):d(s)?o[i]=s.slice():n&&f(s)||(o[i]=s)};for(let e=0,t=arguments.length;e(A(t,(t,s)=>{n&&y(t)?e[s]=o(t,n):e[s]=t},{allOwnKeys:s}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,o)=>{e.prototype=Object.create(t.prototype,o),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,o)=>{let s,i,a;const l={};if(t=t||{},null==e)return t;do{for(s=Object.getOwnPropertyNames(e),i=s.length;i-- >0;)a=s[i],o&&!o(a,e,t)||l[a]||(t[a]=e[a],l[a]=!0);e=!1!==n&&r(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:l,kindOfTest:u,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const o=e.indexOf(t,n);return-1!==o&&o===n},toArray:e=>{if(!e)return null;if(d(e))return e;let t=e.length;if(!v(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[i]).call(e);let o;for(;(o=n.next())&&!o.done;){const n=o.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const o=[];for(;null!==(n=e.exec(t));)o.push(n);return o},isHTMLForm:L,hasOwnProperty:I,hasOwnProp:I,reduceDescriptors:F,freezeMethods:e=>{F(e,(t,n)=>{if(y(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const o=e[n];y(o)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))})},toObjectSet:(e,t)=>{const n={},o=e=>{e.forEach(e=>{n[e]=!0})};return d(e)?o(e):o(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(e,t,n){return t.toUpperCase()+n}),noop:()=>{},toFiniteNumber:(e,t)=>null!=e&&Number.isFinite(e=+e)?e:t,findKey:B,global:O,isContextDefined:R,isSpecCompliantForm:function(e){return!!(e&&y(e.append)&&"FormData"===e[a]&&e[i])},toJSONObject:e=>{const t=new Array(10),n=(e,o)=>{if(_(e)){if(t.indexOf(e)>=0)return;if(h(e))return e;if(!("toJSON"in e)){t[o]=e;const s=d(e)?[]:{};return A(e,(e,t)=>{const r=n(e,o+1);!f(r)&&(s[t]=r)}),t[o]=void 0,s}}return e};return n(e,0)},isAsyncFn:$,isThenable:e=>e&&(_(e)||y(e))&&y(e.then)&&y(e.catch),setImmediate:j,asap:W,isIterable:e=>null!=e&&y(e[i])};function J(e,t,n,o,s){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),o&&(this.request=o),s&&(this.response=s,this.status=s.status?s.status:null)}K.inherits(J,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:K.toJSONObject(this.config),code:this.code,status:this.status}}});const Z=J.prototype,G={};function X(e){return K.isPlainObject(e)||K.isArray(e)}function Q(e){return K.endsWith(e,"[]")?e.slice(0,-2):e}function Y(e,t,n){return e?e.concat(t).map(function(e,t){return e=Q(e),!n&&t?"["+e+"]":e}).join(n?".":""):t}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{G[e]={value:e}}),Object.defineProperties(J,G),Object.defineProperty(Z,"isAxiosError",{value:!0}),J.from=(e,t,n,o,s,r)=>{const i=Object.create(Z);K.toFlatObject(e,i,function(e){return e!==Error.prototype},e=>"isAxiosError"!==e);const a=e&&e.message?e.message:"Error",l=null==t&&e?e.code:t;return J.call(i,a,l,n,o,s),e&&null==i.cause&&Object.defineProperty(i,"cause",{value:e,configurable:!0}),i.name=e&&e.name||"Error",r&&Object.assign(i,r),i};const ee=K.toFlatObject(K,{},null,function(e){return/^is[A-Z]/.test(e)});function te(e,t,n){if(!K.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;const o=(n=K.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(e,t){return!K.isUndefined(t[e])})).metaTokens,s=n.visitor||c,r=n.dots,i=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&K.isSpecCompliantForm(t);if(!K.isFunction(s))throw new TypeError("visitor must be a function");function l(e){if(null===e)return"";if(K.isDate(e))return e.toISOString();if(K.isBoolean(e))return e.toString();if(!a&&K.isBlob(e))throw new J("Blob is not supported. Use a Buffer instead.");return K.isArrayBuffer(e)||K.isTypedArray(e)?a&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function c(e,n,s){let a=e;if(e&&!s&&"object"==typeof e)if(K.endsWith(n,"{}"))n=o?n:n.slice(0,-2),e=JSON.stringify(e);else if(K.isArray(e)&&function(e){return K.isArray(e)&&!e.some(X)}(e)||(K.isFileList(e)||K.endsWith(n,"[]"))&&(a=K.toArray(e)))return n=Q(n),a.forEach(function(e,o){!K.isUndefined(e)&&null!==e&&t.append(!0===i?Y([n],o,r):null===i?n:n+"[]",l(e))}),!1;return!!X(e)||(t.append(Y(s,n,r),l(e)),!1)}const u=[],p=Object.assign(ee,{defaultVisitor:c,convertValue:l,isVisitable:X});if(!K.isObject(e))throw new TypeError("data must be an object");return function e(n,o){if(!K.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+o.join("."));u.push(n),K.forEach(n,function(n,r){!0===(!(K.isUndefined(n)||null===n)&&s.call(t,n,K.isString(r)?r.trim():r,o,p))&&e(n,o?o.concat(r):[r])}),u.pop()}}(e),t}function ne(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(e){return t[e]})}function oe(e,t){this._pairs=[],e&&te(e,this,t)}const se=oe.prototype;function re(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function ie(e,t,n){if(!t)return e;const o=n&&n.encode||re;K.isFunction(n)&&(n={serialize:n});const s=n&&n.serialize;let r;if(r=s?s(t,n):K.isURLSearchParams(t)?t.toString():new oe(t,n).toString(o),r){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+r}return e}se.append=function(e,t){this._pairs.push([e,t])},se.toString=function(e){const t=e?function(t){return e.call(this,t,ne)}:ne;return this._pairs.map(function(e){return t(e[0])+"="+t(e[1])},"").join("&")};var ae=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){K.forEach(this.handlers,function(t){null!==t&&e(t)})}},le={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},ce={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:oe,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]};const ue="undefined"!=typeof window&&"undefined"!=typeof document,pe="object"==typeof navigator&&navigator||void 0,de=ue&&(!pe||["ReactNative","NativeScript","NS"].indexOf(pe.product)<0),fe="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,he=ue&&window.location.href||"http://localhost";var me={...Object.freeze({__proto__:null,hasBrowserEnv:ue,hasStandardBrowserWebWorkerEnv:fe,hasStandardBrowserEnv:de,navigator:pe,origin:he}),...ce};function ge(e){function t(e,n,o,s){let r=e[s++];if("__proto__"===r)return!0;const i=Number.isFinite(+r),a=s>=e.length;return r=!r&&K.isArray(o)?o.length:r,a?(K.hasOwnProp(o,r)?o[r]=[o[r],n]:o[r]=n,!i):(o[r]&&K.isObject(o[r])||(o[r]=[]),t(e,n,o[r],s)&&K.isArray(o[r])&&(o[r]=function(e){const t={},n=Object.keys(e);let o;const s=n.length;let r;for(o=0;o{t(function(e){return K.matchAll(/\w+|\[(\w*)]/g,e).map(e=>"[]"===e[0]?"":e[1]||e[0])}(e),o,n,0)}),n}return null}const ye={transitional:le,adapter:["xhr","http","fetch"],transformRequest:[function(e,t){const n=t.getContentType()||"",o=n.indexOf("application/json")>-1,s=K.isObject(e);if(s&&K.isHTMLForm(e)&&(e=new FormData(e)),K.isFormData(e))return o?JSON.stringify(ge(e)):e;if(K.isArrayBuffer(e)||K.isBuffer(e)||K.isStream(e)||K.isFile(e)||K.isBlob(e)||K.isReadableStream(e))return e;if(K.isArrayBufferView(e))return e.buffer;if(K.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let r;if(s){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return te(e,new me.classes.URLSearchParams,{visitor:function(e,t,n,o){return me.isNode&&K.isBuffer(e)?(this.append(t,e.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)},...t})}(e,this.formSerializer).toString();if((r=K.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return te(r?{"files[]":e}:e,t&&new t,this.formSerializer)}}return s||o?(t.setContentType("application/json",!1),function(e){if(K.isString(e))try{return(0,JSON.parse)(e),K.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(0,JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||ye.transitional,n=t&&t.forcedJSONParsing,o="json"===this.responseType;if(K.isResponse(e)||K.isReadableStream(e))return e;if(e&&K.isString(e)&&(n&&!this.responseType||o)){const n=!(t&&t.silentJSONParsing)&&o;try{return JSON.parse(e,this.parseReviver)}catch(e){if(n){if("SyntaxError"===e.name)throw J.from(e,J.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:me.classes.FormData,Blob:me.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};K.forEach(["delete","get","head","post","put","patch"],e=>{ye.headers[e]={}});var ve=ye;const _e=K.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),be=Symbol("internals");function Se(e){return e&&String(e).trim().toLowerCase()}function we(e){return!1===e||null==e?e:K.isArray(e)?e.map(we):String(e)}function Ce(e,t,n,o,s){return K.isFunction(o)?o.call(this,t,n):(s&&(t=n),K.isString(t)?K.isString(o)?-1!==t.indexOf(o):K.isRegExp(o)?o.test(t):void 0:void 0)}class Ee{constructor(e){e&&this.set(e)}set(e,t,n){const o=this;function s(e,t,n){const s=Se(t);if(!s)throw new Error("header name must be a non-empty string");const r=K.findKey(o,s);(!r||void 0===o[r]||!0===n||void 0===n&&!1!==o[r])&&(o[r||t]=we(e))}const r=(e,t)=>K.forEach(e,(e,n)=>s(e,n,t));if(K.isPlainObject(e)||e instanceof this.constructor)r(e,t);else if(K.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))r((e=>{const t={};let n,o,s;return e&&e.split("\n").forEach(function(e){s=e.indexOf(":"),n=e.substring(0,s).trim().toLowerCase(),o=e.substring(s+1).trim(),!n||t[n]&&_e[n]||("set-cookie"===n?t[n]?t[n].push(o):t[n]=[o]:t[n]=t[n]?t[n]+", "+o:o)}),t})(e),t);else if(K.isObject(e)&&K.isIterable(e)){let n,o,s={};for(const t of e){if(!K.isArray(t))throw TypeError("Object iterator must return a key-value pair");s[o=t[0]]=(n=s[o])?K.isArray(n)?[...n,t[1]]:[n,t[1]]:t[1]}r(s,t)}else null!=e&&s(t,e,n);return this}get(e,t){if(e=Se(e)){const n=K.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let o;for(;o=n.exec(e);)t[o[1]]=o[2];return t}(e);if(K.isFunction(t))return t.call(this,e,n);if(K.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=Se(e)){const n=K.findKey(this,e);return!(!n||void 0===this[n]||t&&!Ce(0,this[n],n,t))}return!1}delete(e,t){const n=this;let o=!1;function s(e){if(e=Se(e)){const s=K.findKey(n,e);!s||t&&!Ce(0,n[s],s,t)||(delete n[s],o=!0)}}return K.isArray(e)?e.forEach(s):s(e),o}clear(e){const t=Object.keys(this);let n=t.length,o=!1;for(;n--;){const s=t[n];e&&!Ce(0,this[s],s,e,!0)||(delete this[s],o=!0)}return o}normalize(e){const t=this,n={};return K.forEach(this,(o,s)=>{const r=K.findKey(n,s);if(r)return t[r]=we(o),void delete t[s];const i=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,t,n)=>t.toUpperCase()+n)}(s):String(s).trim();i!==s&&delete t[s],t[i]=we(o),n[i]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return K.forEach(this,(n,o)=>{null!=n&&!1!==n&&(t[o]=e&&K.isArray(n)?n.join(", "):n)}),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,t])=>e+": "+t).join("\n")}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach(e=>n.set(e)),n}static accessor(e){const t=(this[be]=this[be]={accessors:{}}).accessors,n=this.prototype;function o(e){const o=Se(e);t[o]||(function(e,t){const n=K.toCamelCase(" "+t);["get","set","has"].forEach(o=>{Object.defineProperty(e,o+n,{value:function(e,n,s){return this[o].call(this,t,e,n,s)},configurable:!0})})}(n,e),t[o]=!0)}return K.isArray(e)?e.forEach(o):o(e),this}}Ee.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),K.reduceDescriptors(Ee.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}}),K.freezeMethods(Ee);var ke=Ee;function xe(e,t){const n=this||ve,o=t||n,s=ke.from(o.headers);let r=o.data;return K.forEach(e,function(e){r=e.call(n,r,s.normalize(),t?t.status:void 0)}),s.normalize(),r}function Ne(e){return!(!e||!e.__CANCEL__)}function Te(e,t,n){J.call(this,null==e?"canceled":e,J.ERR_CANCELED,t,n),this.name="CanceledError"}function Ve(e,t,n){const o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(new J("Request failed with status code "+n.status,[J.ERR_BAD_REQUEST,J.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}K.inherits(Te,J,{__CANCEL__:!0});const Ae=(e,t,n=3)=>{let o=0;const s=function(e,t){e=e||10;const n=new Array(e),o=new Array(e);let s,r=0,i=0;return t=void 0!==t?t:1e3,function(a){const l=Date.now(),c=o[i];s||(s=l),n[r]=a,o[r]=l;let u=i,p=0;for(;u!==r;)p+=n[u++],u%=e;if(r=(r+1)%e,r===i&&(i=(i+1)%e),l-s{l=r,i=null,a&&(clearTimeout(a),a=null),(n=>{const r=n.loaded,i=n.lengthComputable?n.total:void 0,a=r-o,l=s(a);o=r,e({loaded:r,total:i,progress:i?r/i:void 0,bytes:a,rate:l||void 0,estimated:l&&i&&r<=i?(i-r)/l:void 0,event:n,lengthComputable:null!=i,[t?"download":"upload"]:!0})})(...n)};return[(...e)=>{const t=Date.now(),n=t-l;n>=c?u(e,t):(i=e,a||(a=setTimeout(()=>{a=null,u(i)},c-n)))},()=>i&&u(i)]}(0,n)},Be=(e,t)=>{const n=null!=e;return[o=>t[0]({lengthComputable:n,total:e,loaded:o}),t[1]]},Oe=e=>(...t)=>K.asap(()=>e(...t));var Re=me.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,me.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(me.origin),me.navigator&&/(msie|trident)/i.test(me.navigator.userAgent)):()=>!0,De=me.hasStandardBrowserEnv?{write(e,t,n,o,s,r,i){if("undefined"==typeof document)return;const a=[`${e}=${encodeURIComponent(t)}`];K.isNumber(n)&&a.push(`expires=${new Date(n).toUTCString()}`),K.isString(o)&&a.push(`path=${o}`),K.isString(s)&&a.push(`domain=${s}`),!0===r&&a.push("secure"),K.isString(i)&&a.push(`SameSite=${i}`),document.cookie=a.join("; ")},read(e){if("undefined"==typeof document)return null;const t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):null},remove(e){this.write(e,"",Date.now()-864e5,"/")}}:{write(){},read:()=>null,remove(){}};function Pe(e,t,n){let o=!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t);return e&&(o||0==n)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}const Le=e=>e instanceof ke?{...e}:e;function Ie(e,t){t=t||{};const n={};function o(e,t,n,o){return K.isPlainObject(e)&&K.isPlainObject(t)?K.merge.call({caseless:o},e,t):K.isPlainObject(t)?K.merge({},t):K.isArray(t)?t.slice():t}function s(e,t,n,s){return K.isUndefined(t)?K.isUndefined(e)?void 0:o(void 0,e,0,s):o(e,t,0,s)}function r(e,t){if(!K.isUndefined(t))return o(void 0,t)}function i(e,t){return K.isUndefined(t)?K.isUndefined(e)?void 0:o(void 0,e):o(void 0,t)}function a(n,s,r){return r in t?o(n,s):r in e?o(void 0,n):void 0}const l={url:r,method:r,data:r,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(e,t,n)=>s(Le(e),Le(t),0,!0)};return K.forEach(Object.keys({...e,...t}),function(o){const r=l[o]||s,i=r(e[o],t[o],o);K.isUndefined(i)&&r!==a||(n[o]=i)}),n}var Me=e=>{const t=Ie({},e);let{data:n,withXSRFToken:o,xsrfHeaderName:s,xsrfCookieName:r,headers:i,auth:a}=t;if(t.headers=i=ke.from(i),t.url=ie(Pe(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),a&&i.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),K.isFormData(n))if(me.hasStandardBrowserEnv||me.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if(K.isFunction(n.getHeaders)){const e=n.getHeaders(),t=["content-type","content-length"];Object.entries(e).forEach(([e,n])=>{t.includes(e.toLowerCase())&&i.set(e,n)})}if(me.hasStandardBrowserEnv&&(o&&K.isFunction(o)&&(o=o(t)),o||!1!==o&&Re(t.url))){const e=s&&r&&De.read(r);e&&i.set(s,e)}return t},Fe="undefined"!=typeof XMLHttpRequest&&function(e){return new Promise(function(t,n){const o=Me(e);let s=o.data;const r=ke.from(o.headers).normalize();let i,a,l,c,u,{responseType:p,onUploadProgress:d,onDownloadProgress:f}=o;function h(){c&&c(),u&&u(),o.cancelToken&&o.cancelToken.unsubscribe(i),o.signal&&o.signal.removeEventListener("abort",i)}let m=new XMLHttpRequest;function g(){if(!m)return;const o=ke.from("getAllResponseHeaders"in m&&m.getAllResponseHeaders());Ve(function(e){t(e),h()},function(e){n(e),h()},{data:p&&"text"!==p&&"json"!==p?m.response:m.responseText,status:m.status,statusText:m.statusText,headers:o,config:e,request:m}),m=null}m.open(o.method.toUpperCase(),o.url,!0),m.timeout=o.timeout,"onloadend"in m?m.onloadend=g:m.onreadystatechange=function(){m&&4===m.readyState&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))&&setTimeout(g)},m.onabort=function(){m&&(n(new J("Request aborted",J.ECONNABORTED,e,m)),m=null)},m.onerror=function(t){const o=new J(t&&t.message?t.message:"Network Error",J.ERR_NETWORK,e,m);o.event=t||null,n(o),m=null},m.ontimeout=function(){let t=o.timeout?"timeout of "+o.timeout+"ms exceeded":"timeout exceeded";const s=o.transitional||le;o.timeoutErrorMessage&&(t=o.timeoutErrorMessage),n(new J(t,s.clarifyTimeoutError?J.ETIMEDOUT:J.ECONNABORTED,e,m)),m=null},void 0===s&&r.setContentType(null),"setRequestHeader"in m&&K.forEach(r.toJSON(),function(e,t){m.setRequestHeader(t,e)}),K.isUndefined(o.withCredentials)||(m.withCredentials=!!o.withCredentials),p&&"json"!==p&&(m.responseType=o.responseType),f&&([l,u]=Ae(f,!0),m.addEventListener("progress",l)),d&&m.upload&&([a,c]=Ae(d),m.upload.addEventListener("progress",a),m.upload.addEventListener("loadend",c)),(o.cancelToken||o.signal)&&(i=t=>{m&&(n(!t||t.type?new Te(null,e,m):t),m.abort(),m=null)},o.cancelToken&&o.cancelToken.subscribe(i),o.signal&&(o.signal.aborted?i():o.signal.addEventListener("abort",i)));const y=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(o.url);y&&-1===me.protocols.indexOf(y)?n(new J("Unsupported protocol "+y+":",J.ERR_BAD_REQUEST,e)):m.send(s||null)})},$e=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let n,o=new AbortController;const s=function(e){if(!n){n=!0,i();const t=e instanceof Error?e:this.reason;o.abort(t instanceof J?t:new Te(t instanceof Error?t.message:t))}};let r=t&&setTimeout(()=>{r=null,s(new J(`timeout ${t} of ms exceeded`,J.ETIMEDOUT))},t);const i=()=>{e&&(r&&clearTimeout(r),r=null,e.forEach(e=>{e.unsubscribe?e.unsubscribe(s):e.removeEventListener("abort",s)}),e=null)};e.forEach(e=>e.addEventListener("abort",s));const{signal:a}=o;return a.unsubscribe=()=>K.asap(i),a}};const je=function*(e,t){let n=e.byteLength;if(!t||n{const s=async function*(e,t){for await(const n of async function*(e){if(e[Symbol.asyncIterator])return void(yield*e);const t=e.getReader();try{for(;;){const{done:e,value:n}=await t.read();if(e)break;yield n}}finally{await t.cancel()}}(e))yield*je(n,t)}(e,t);let r,i=0,a=e=>{r||(r=!0,o&&o(e))};return new ReadableStream({async pull(e){try{const{done:t,value:o}=await s.next();if(t)return a(),void e.close();let r=o.byteLength;if(n){let e=i+=r;n(e)}e.enqueue(new Uint8Array(o))}catch(e){throw a(e),e}},cancel:e=>(a(e),s.return())},{highWaterMark:2})},{isFunction:He}=K,qe=(({Request:e,Response:t})=>({Request:e,Response:t}))(K.global),{ReadableStream:ze,TextEncoder:We}=K.global,Ke=(e,...t)=>{try{return!!e(...t)}catch(e){return!1}},Je=e=>{e=K.merge.call({skipUndefined:!0},qe,e);const{fetch:t,Request:n,Response:o}=e,s=t?He(t):"function"==typeof fetch,r=He(n),i=He(o);if(!s)return!1;const a=s&&He(ze),l=s&&("function"==typeof We?(c=new We,e=>c.encode(e)):async e=>new Uint8Array(await new n(e).arrayBuffer()));var c;const u=r&&a&&Ke(()=>{let e=!1;const t=new n(me.origin,{body:new ze,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t}),p=i&&a&&Ke(()=>K.isReadableStream(new o("").body)),d={stream:p&&(e=>e.body)};s&&["text","arrayBuffer","blob","formData","stream"].forEach(e=>{!d[e]&&(d[e]=(t,n)=>{let o=t&&t[e];if(o)return o.call(t);throw new J(`Response type '${e}' is not supported`,J.ERR_NOT_SUPPORT,n)})});return async e=>{let{url:s,method:i,data:a,signal:c,cancelToken:f,timeout:h,onDownloadProgress:m,onUploadProgress:g,responseType:y,headers:v,withCredentials:_="same-origin",fetchOptions:b}=Me(e),S=t||fetch;y=y?(y+"").toLowerCase():"text";let w=$e([c,f&&f.toAbortSignal()],h),C=null;const E=w&&w.unsubscribe&&(()=>{w.unsubscribe()});let k;try{if(g&&u&&"get"!==i&&"head"!==i&&0!==(k=await(async(e,t)=>{const o=K.toFiniteNumber(e.getContentLength());return null==o?(async e=>{if(null==e)return 0;if(K.isBlob(e))return e.size;if(K.isSpecCompliantForm(e)){const t=new n(me.origin,{method:"POST",body:e});return(await t.arrayBuffer()).byteLength}return K.isArrayBufferView(e)||K.isArrayBuffer(e)?e.byteLength:(K.isURLSearchParams(e)&&(e+=""),K.isString(e)?(await l(e)).byteLength:void 0)})(t):o})(v,a))){let e,t=new n(s,{method:"POST",body:a,duplex:"half"});if(K.isFormData(a)&&(e=t.headers.get("content-type"))&&v.setContentType(e),t.body){const[e,n]=Be(k,Ae(Oe(g)));a=Ue(t.body,65536,e,n)}}K.isString(_)||(_=_?"include":"omit");const t=r&&"credentials"in n.prototype,c={...b,signal:w,method:i.toUpperCase(),headers:v.normalize().toJSON(),body:a,duplex:"half",credentials:t?_:void 0};C=r&&new n(s,c);let f=await(r?S(C,b):S(s,c));const h=p&&("stream"===y||"response"===y);if(p&&(m||h&&E)){const e={};["status","statusText","headers"].forEach(t=>{e[t]=f[t]});const t=K.toFiniteNumber(f.headers.get("content-length")),[n,s]=m&&Be(t,Ae(Oe(m),!0))||[];f=new o(Ue(f.body,65536,n,()=>{s&&s(),E&&E()}),e)}y=y||"text";let x=await d[K.findKey(d,y)||"text"](f,e);return!h&&E&&E(),await new Promise((t,n)=>{Ve(t,n,{data:x,headers:ke.from(f.headers),status:f.status,statusText:f.statusText,config:e,request:C})})}catch(t){if(E&&E(),t&&"TypeError"===t.name&&/Load failed|fetch/i.test(t.message))throw Object.assign(new J("Network Error",J.ERR_NETWORK,e,C),{cause:t.cause||t});throw J.from(t,t&&t.code,e,C)}}},Ze=new Map,Ge=e=>{let t=e&&e.env||{};const{fetch:n,Request:o,Response:s}=t,r=[o,s,n];let i,a,l=r.length,c=Ze;for(;l--;)i=r[l],a=c.get(i),void 0===a&&c.set(i,a=l?new Map:Je(t)),c=a;return a};Ge();const Xe={http:null,xhr:Fe,fetch:{get:Ge}};K.forEach(Xe,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}});const Qe=e=>`- ${e}`,Ye=e=>K.isFunction(e)||null===e||!1===e;var et=function(e,t){e=K.isArray(e)?e:[e];const{length:n}=e;let o,s;const r={};for(let i=0;i`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build"));throw new J("There is no suitable adapter to dispatch the request "+(n?e.length>1?"since :\n"+e.map(Qe).join("\n"):" "+Qe(e[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return s};function tt(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Te(null,e)}function nt(e){return tt(e),e.headers=ke.from(e.headers),e.data=xe.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),et(e.adapter||ve.adapter,e)(e).then(function(t){return tt(e),t.data=xe.call(e,e.transformResponse,t),t.headers=ke.from(t.headers),t},function(t){return Ne(t)||(tt(e),t&&t.response&&(t.response.data=xe.call(e,e.transformResponse,t.response),t.response.headers=ke.from(t.response.headers))),Promise.reject(t)})}const ot="1.13.1",st={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{st[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}});const rt={};st.transitional=function(e,t,n){function o(e,t){return"[Axios v"+ot+"] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,s,r)=>{if(!1===e)throw new J(o(s," has been removed"+(t?" in "+t:"")),J.ERR_DEPRECATED);return t&&!rt[s]&&(rt[s]=!0,console.warn(o(s," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,s,r)}},st.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};var it={assertOptions:function(e,t,n){if("object"!=typeof e)throw new J("options must be an object",J.ERR_BAD_OPTION_VALUE);const o=Object.keys(e);let s=o.length;for(;s-- >0;){const r=o[s],i=t[r];if(i){const t=e[r],n=void 0===t||i(t,r,e);if(!0!==n)throw new J("option "+r+" must be "+n,J.ERR_BAD_OPTION_VALUE);continue}if(!0!==n)throw new J("Unknown option "+r,J.ERR_BAD_OPTION)}},validators:st};const at=it.validators;class lt{constructor(e){this.defaults=e||{},this.interceptors={request:new ae,response:new ae}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=new Error;const n=t.stack?t.stack.replace(/^.+\n/,""):"";try{e.stack?n&&!String(e.stack).endsWith(n.replace(/^.+\n.+\n/,""))&&(e.stack+="\n"+n):e.stack=n}catch(e){}}throw e}}_request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=Ie(this.defaults,t);const{transitional:n,paramsSerializer:o,headers:s}=t;void 0!==n&&it.assertOptions(n,{silentJSONParsing:at.transitional(at.boolean),forcedJSONParsing:at.transitional(at.boolean),clarifyTimeoutError:at.transitional(at.boolean)},!1),null!=o&&(K.isFunction(o)?t.paramsSerializer={serialize:o}:it.assertOptions(o,{encode:at.function,serialize:at.function},!0)),void 0!==t.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),it.assertOptions(t,{baseUrl:at.spelling("baseURL"),withXsrfToken:at.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let r=s&&K.merge(s.common,s[t.method]);s&&K.forEach(["delete","get","head","post","put","patch","common"],e=>{delete s[e]}),t.headers=ke.concat(r,s);const i=[];let a=!0;this.interceptors.request.forEach(function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(a=a&&e.synchronous,i.unshift(e.fulfilled,e.rejected))});const l=[];let c;this.interceptors.response.forEach(function(e){l.push(e.fulfilled,e.rejected)});let u,p=0;if(!a){const e=[nt.bind(this),void 0];for(e.unshift(...i),e.push(...l),u=e.length,c=Promise.resolve(t);p{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t;const o=new Promise(e=>{n.subscribe(e),t=e}).then(e);return o.cancel=function(){n.unsubscribe(t)},o},e(function(e,o,s){n.reason||(n.reason=new Te(e,o,s),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}toAbortSignal(){const e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let e;return{token:new ut(function(t){e=t}),cancel:e}}}var pt=ut;const dt={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(dt).forEach(([e,t])=>{dt[t]=e});var ft=dt;const ht=function e(t){const n=new ct(t),s=o(ct.prototype.request,n);return K.extend(s,ct.prototype,n,{allOwnKeys:!0}),K.extend(s,n,null,{allOwnKeys:!0}),s.create=function(n){return e(Ie(t,n))},s}(ve);ht.Axios=ct,ht.CanceledError=Te,ht.CancelToken=pt,ht.isCancel=Ne,ht.VERSION=ot,ht.toFormData=te,ht.AxiosError=J,ht.Cancel=ht.CanceledError,ht.all=function(e){return Promise.all(e)},ht.spread=function(e){return function(t){return e.apply(null,t)}},ht.isAxiosError=function(e){return K.isObject(e)&&!0===e.isAxiosError},ht.mergeConfig=Ie,ht.AxiosHeaders=ke,ht.formToJSON=e=>ge(K.isHTMLForm(e)?new FormData(e):e),ht.getAdapter=et,ht.HttpStatusCode=ft,ht.default=ht,e.exports=ht}},t={};function n(o){var s=t[o];if(void 0!==s)return s.exports;var r=t[o]={exports:{}};return e[o](r,r.exports,n),r.exports}n.d=(e,t)=>{for(var o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},window.postSmtpDashboard=function(){try{window.Vue=n(425),window.axios=n(806),window.axios=window.axios.create({baseURL:postSmtpNewDashboard.json_url,headers:{"X-WP-Nonce":postSmtpNewDashboard.nonce,"Content-Type":"application/json"}}),n(229)}catch(e){}},window.postSmtpEmailLogs=function(){var e=window.location.href;if("failed"===(e=new URLSearchParams(e)).get("status")){let e=setInterval(function(){let t=document.querySelectorAll('button[data-status="failed"]');t.length&&(t[0].click(),clearInterval(e))},100)}},"toplevel_page_postman"===postSmtpNewDashboard.page_hook?window.postSmtpDashboard():"post-smtp_page_postman_email_log"===postSmtpNewDashboard.page_hook&&window.postSmtpEmailLogs()})(); +//# sourceMappingURL=app.js.map \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js.LICENSE.txt b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js.LICENSE.txt new file mode 100644 index 0000000..a503c35 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js.LICENSE.txt @@ -0,0 +1,19 @@ +/*! Axios v1.13.1 Copyright (c) 2025 Matt Zabriskie and contributors */ + +/** +* @vue/runtime-core v3.5.22 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/ + +/** +* @vue/runtime-dom v3.5.22 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/ + +/** +* @vue/shared v3.5.22 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/ diff --git a/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js.map b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js.map new file mode 100644 index 0000000..2af4bf6 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Dashboard/assets/js/app.js.map @@ -0,0 +1 @@ +{"version":3,"file":"js/app.js","mappings":";8DACMA,MAAM,sB,GAILA,MAAM,4B,GAELA,MAAM,gC,GASNA,MAAM,0BAiBd,GACCC,KAAM,qBAENC,MAAO,CACNC,mBAA6B,CAC5BC,KAAMC,QACNC,SAAS,GAEVC,YAA6B,CAC5BH,KAAMC,QACNC,SAAS,GAEVE,sBAA6B,CAC5BJ,KAAMC,QACNC,SAAS,GAEVG,mBAA6B,CAC5BL,KAAMC,QACNC,SAAS,GAEVI,4BAA6B,CAC5BN,KAAMC,QACNC,SAAS,GAGVK,WAAY,CACXP,KAAMQ,OACNN,QAAS,YAGVO,cAAe,CACXT,KAAMC,QACNC,SAAS,GAGbQ,sBAAuB,CACtBV,KAAMC,QACNC,SAAS,IAIXS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,a,aCrExB,MAEA,GAFiC,OAAgB,EAAQ,CAAC,CAAC,S,gMDN1DC,EAAAA,EAAAA,oBA4BM,MA5BNC,EA4BM,EA1BLC,EAAAA,EAAAA,aAAqCC,IAErCC,EAAAA,EAAAA,oBAsBM,MAtBNC,EAsBM,EApBLD,EAAAA,EAAAA,oBAQM,MARNE,EAQM,EAPLJ,EAAAA,EAAAA,aAMuBK,EAAA,CALrB,uBAAsBC,EAAAzB,mBACtB,wBAAuByB,EAAAnB,mBACvB,gBAAemB,EAAArB,YACf,wBAAuBqB,EAAAjB,WACf,mBAAkBiB,EAAAf,e,uHAG7BW,EAAAA,EAAAA,oBASM,MATNK,EASM,EARLP,EAAAA,EAAAA,aAOqBQ,EAAA,CANnB,uBAAsBF,EAAAzB,mBACtB,gBAAeyB,EAAArB,YACf,2BAA0BqB,EAAApB,sBAC1B,wBAAuBoB,EAAAnB,mBACvB,kCAAiCmB,EAAAlB,4BACjC,2BAA0BkB,EAAAd,uB,yKChB4C,CAAC,YAAY,qB,GCNnFd,MAAM,UA0BZ,GACCC,KAAM,iBAENc,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,YAGvBY,SAAU,CACTC,SAAAA,GACC,OAAOC,KAAKf,QAAQA,QAAQD,eAAiB,wBAC9C,GAGDiB,QAAS,CACRC,aAAAA,CAAeC,GACd,OAAOH,KAAKhB,eAAiB,iBAAmBmB,CACjD,ICnCF,GAFiC,OAAgB,EAAQ,CAAC,CAAC,S,8IDN1DhB,EAAAA,EAAAA,oBAsBM,MAtBNC,EAsBM,EApBLG,EAAAA,EAAAA,oBAIM,aAHLF,EAAAA,EAAAA,aAEiBe,EAAA,CADfC,IAAKC,EAAAP,WAAS,mBAGjBR,EAAAA,EAAAA,oBAaM,aAZLF,EAAAA,EAAAA,aAWsBkB,EAAA,CAVpBC,QAAO,C,MAAyBF,EAAAJ,cAAa,Y,qBAAqEI,EAAAJ,cAAa,gB,8CCHxD,CAAC,YAAY,qB,gBCFzF,GACClC,KAAM,cACNC,MAAO,CACNoC,IAAK,CACJlC,KAAMQ,OACN8B,UAAU,GAEXC,MAAO,CACNvC,KAAMwC,OACNtC,QAASA,KAAA,CAAS,IAEnBuC,UAAW,CACVzC,KAAMC,QACNC,SAAS,IAIXS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,YAGvBe,QAAS,CACRY,QAAOA,CAAEC,EAAWC,IACZpC,OAAQoC,GAASC,MAAOF,GAGhCG,YAAWA,CAAEC,EAAQC,KAC6B,IAA1CxC,OAAQwC,GAAWC,QAASF,IAIrCpB,SAAU,CACTuB,MAAAA,GACC,OAAKrB,KAAKiB,YAAa,WAAYjB,KAAKK,MAClCL,KAAKY,UACCZ,KAAKa,QAAS,WAAYb,KAAKK,KAC7B,GAAM,iBAGbL,KAAKK,GACb,ICvCF,GAFiC,OAAgB,EAAQ,CAAC,CAAC,S,+CDJzDlB,EAAAA,EAAAA,oBAA8D,OAAxDkB,IAAKC,EAAAe,OAASC,IAAG,aAAiB3B,EAAAU,IAAMK,OAAKa,EAAAA,EAAAA,gBAAE5B,EAAAe,Q,kBEAjD3C,MAAM,Y,cAqDZ,GACCC,KAAM,mBAENC,MAAO,CACNuC,QAAS,CACRrC,KAAMqD,MACNnD,QAASA,IAAM,KAIjBS,KAAQC,IAAC,CACRC,eAAiBD,EAAGE,QAAQD,eAC5BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAKE,SAClCC,SAAiB,EACjBC,cAAiB,EAEjBC,qBAAsB,KAGvBC,MAAO,CACP,EAEAjC,SAAU,CACTkC,uBAAAA,GAQC,MAAO,CACNC,QAPIjC,KAAK6B,aACC,QAEA,OAMZ,EACAK,kBAAAA,GAQC,MAAO,CACND,QAPIjC,KAAK4B,QACC,QAEA,OAMZ,GAGD3B,QAAS,CACRkC,QAAAA,CAAUC,EAAGC,GACZD,EAAEE,iBAGG,YAAcD,EAAOE,SACzBvC,KAAK6B,cAAe,EACpB7B,KAAK4B,SAAiB5B,KAAK4B,SAGvB,SAAWS,EAAOE,SACtBvC,KAAK4B,SAAe,EACpB5B,KAAK6B,cAAiB7B,KAAK6B,aAE7B,EAEAW,sBAAAA,GACCC,MAAMC,IAAK,mBACTC,KAAMC,IACN5C,KAAK8B,qBAAuBc,EAAS9D,KAAK+D,KAC1C7C,KAAK8B,qBAAuBnB,OAAOmC,OAAQ9C,KAAK8B,uBAEnD,GAGDiB,OAAAA,GACC/C,KAAKwC,yBAELQ,SAASC,KAAKC,iBAAkB,QAAWd,IACnCA,EAAEe,OAAOC,QAAS,eACxBpD,KAAK4B,SAAe,EACpB5B,KAAK6B,cAAe,IAGvB,GCjID,GAFiC,OAAgB,EAAQ,CAAC,CAAC,S,0MDN1D1C,EAAAA,EAAAA,oBAgDM,MAhDNC,EAgDM,EA9CLG,EAAAA,EAAAA,oBAIM,c,oBAHLJ,EAAAA,EAAAA,oBAESkE,EAAAA,SAAA,MAAAC,EAAAA,EAAAA,YAF6E3D,EAAAa,QAAV6B,K,kBAA5ElD,EAAAA,EAAAA,oBAES,UAFAoE,QAAOnB,GAAK9B,EAAA6B,SAAUC,EAAGC,GAAUtE,MAAM,oB,EACjDsB,EAAAA,EAAAA,aAA8Fe,EAAA,CAA9E,eAAcoD,EAAA1B,qBAAqB2B,OAASpD,IAAKgC,EAAOqB,M,8CAI1ErE,EAAAA,EAAAA,aAkC2BsE,EAAA,CAjCzBjD,OAAKa,EAAAA,EAAAA,gBAAEjB,EAAA4B,oBACP0B,MAAK,C,OAAwBJ,EAAA/B,KAAI,G,wBAA4C+B,EAAAtE,UAAS,gD,OAA8EsE,EAAA/B,KAAI,G,yBAA6C+B,EAAAtE,UAAS,0C,OAAwEsE,EAAA/B,KAAI,G,wBAA4C+B,EAAAtE,UAAS,gD,OAA8EsE,EAAA/B,KAAI,G,wBAA4C+B,EAAAtE,UAAS,gD,OAA8EsE,EAAA/B,KAAI,G,yBAA6C+B,EAAAtE,UAAS,yD,OAAuFsE,EAAA/B,KAAI,G,qBAAyC+B,EAAAtE,UAAS,iD,2BAkC7vBG,EAAAA,EAAAA,aAG8BwE,EAAA,CAF5BnD,OAAKa,EAAAA,EAAAA,gBAAEjB,EAAA0B,yBACP8B,cAAeN,EAAA1B,sB,sCCxCyD,CAAC,YAAY,qB,GCNnF/D,MAAM,mC,GACLA,MAAM,2B,WAUb,GACCC,KAAM,uBAENC,MAAO,CACN2F,MAAO,CACNzF,KAAMqD,MACNnD,QAASA,IAAM,KAIjBS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,aCfxB,GAFiC,OAAgB,EAAQ,CAAC,CAAC,S,+FDN1DC,EAAAA,EAAAA,oBAOM,MAPNC,EAOM,G,oBANLD,EAAAA,EAAAA,oBAKMkE,EAAAA,SAAA,MAAAC,EAAAA,EAAAA,YAL8C3D,EAAAiE,MAARG,K,kBAA5C5E,EAAAA,EAAAA,oBAKM,MALNK,EAKM,EAJLD,EAAAA,EAAAA,oBAGI,KAHAyE,KAAMD,EAAKE,IAAKlG,MAAM,oB,EACzBsB,EAAAA,EAAAA,aAAwLe,EAAA,CAAxK8D,SAAQ,kBAAsBH,EAAKL,KAAMhD,MAAA,8CAAgDL,IAAKmD,EAAAxE,eAAiB,iBAAmB+E,EAAKL,KAAO,Q,iDAA0B,KACxLS,EAAAA,EAAAA,iBAAGJ,EAAKK,OAAK,I,mBCE2D,CAAC,YAAY,qB,GCNnFrG,MAAM,sC,wCAaHA,MAAM,0C,GACLA,MAAM,sB,GACLA,MAAM,qB,GACNA,MAAM,gC,GAQPA,MAAM,kC,GAGL2C,MAAA,uBAA0B3C,MAAM,4C,2BAqBnCA,MAAM,0C,GACLA,MAAM,qB,GAENA,MAAM,gC,GAQPA,MAAM,kCAed,GACCC,KAAM,6BAENC,MAAO,CACN6F,cAAe,CACd3F,KAAMqD,MACNnD,QAASA,IAAM,KAIjBS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAKI,eAGnC5B,QAAS,CACRoE,gBAAAA,CAAkBjC,EAAGP,EAAcoC,GAClC7B,EAAEE,iBAEFG,MAAM6B,KAAM,oBAAqB,CAChCC,GAAI1C,EAAa0C,KAEhB5B,KAAMC,IACNf,EAAa2C,QAAS,EACtBC,OAAOC,SAASV,KAAOC,GAE1B,EAEAU,kBAAAA,CAAoBvC,EAAGP,GACtBO,EAAEE,iBAEGT,EAAa2C,QACjB/B,MAAM6B,KAAM,uBAAwB,CACnCC,GAAI1C,EAAa0C,KAEhB5B,KAAMC,IACN,MAAMgC,EAAQ5E,KAAK8D,cAAc1C,QAASS,GAErC+C,GAAS,GACb5E,KAAK8D,cAAce,OAAQD,EAAO,IAIvC,GAGD7B,OAAAA,GACA,GClHD,GAFiC,OAAgB,EAAQ,CAAC,CAAC,S,+FDN1D5D,EAAAA,EAAAA,oBAsEM,MAtENC,EAsEM,CAnEEO,EAAAmE,cAAcL,S,oBADrBtE,EAAAA,EAAAA,oBA2CMkE,EAAAA,SAAA,CAAAyB,IAAA,IAAAxB,EAAAA,EAAAA,YAzCkB3D,EAAAmE,cAAhBjC,K,kBAFR1C,EAAAA,EAAAA,oBA2CM,OAxCLpB,MAAM,iCACL,oBAAmB8D,EAAa2C,Q,EAEjCjF,EAAAA,EAAAA,oBA2BI,KA1BHyE,KAAK,IACJT,QAASnB,GAAO9B,EAAA+D,iBAAkBjC,EAAGP,EAAc2B,EAAAtE,UAAY,yCAChEwB,MAAA,4B,EAEAnB,EAAAA,EAAAA,oBAqBM,MArBNK,EAqBM,EApBLL,EAAAA,EAAAA,oBAiBM,MAjBNwF,EAiBM,EAhBLxF,EAAAA,EAAAA,oBAUM,MAVNyF,EAUM,EATLzF,EAAAA,EAAAA,oBAOK,KAPL0F,EAOK,C,aANJ1F,EAAAA,EAAAA,oBAIO,QAJDmB,MAAA,+CAA+C,EACpDnB,EAAAA,EAAAA,oBAEM,OAFD2F,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,EACjE/F,EAAAA,EAAAA,oBAAq1B,QAA/0BgG,EAAE,6zBAA6zBF,KAAK,gB,0BAEr0B,KACPlB,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAK2C,OAAK,MAEd7E,EAAAA,EAAAA,oBAAwE,IAAxEiG,GAAwErB,EAAAA,EAAAA,iBAA3BtC,EAAa4D,SAAO,MAGlElG,EAAAA,EAAAA,oBAEM,MAFNmG,GAEMvB,EAAAA,EAAAA,iBADFtC,EAAa8D,eAAa,G,aAE/BpG,EAAAA,EAAAA,oBAA4B,OAAvBxB,MAAM,YAAU,e,KAShB8D,EAAa2C,S,kBAFpBrF,EAAAA,EAAAA,oBAOI,K,MANHpB,MAAM,qCAELwF,QAASnB,GAAO9B,EAAAqE,mBAAoBvC,EAAGP,GACxCnB,MAAA,0F,EAEArB,EAAAA,EAAAA,aAA+Ee,EAAA,CAA/DC,IAAKmD,EAAAxE,eAAiB,yB,6FAIxCG,EAAAA,EAAAA,oBAqBM,MAAAyG,EAAA,EApBLrG,EAAAA,EAAAA,oBAmBM,MAnBNsG,EAmBM,EAlBLtG,EAAAA,EAAAA,oBAWM,MAXNuG,EAWM,EATLvG,EAAAA,EAAAA,oBAOK,KAPLwG,EAOK,C,aANFxG,EAAAA,EAAAA,oBAIO,QAJDmB,MAAA,+CAA+C,EACpDnB,EAAAA,EAAAA,oBAEM,OAFD2F,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,EACjE/F,EAAAA,EAAAA,oBAAq1B,QAA/0BgG,EAAE,6zBAA6zBF,KAAK,gB,0BAEr0B,KACTlB,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAK2C,OAAK,MAEd7E,EAAAA,EAAAA,oBAAoE,IAApEyG,GAAoE7B,EAAAA,EAAAA,iBAAvBX,EAAA/B,KAAKwE,aAAW,K,aAG9D1G,EAAAA,EAAAA,oBAA4B,OAAvBxB,MAAM,YAAU,U,aAErBwB,EAAAA,EAAAA,oBAEM,OAFDxB,MAAM,4BAA0B,EACpCwB,EAAAA,EAAAA,oBAA8D,QAAxDxB,MAAM,+C,aC3D2D,CAAC,YAAY,qB,GCHlFA,MAAM,e,GACPA,MAAM,cAAcoF,OAAO,SAASa,KAAK,wG,GAQxCjG,MAAM,e,GACPA,MAAM,eAAeoF,OAAO,SAASa,KAAK,oC,GAkBzCjG,MAAM,0B,GAGNA,MAAM,2B,GAEmCA,MAAM,gB,iDAMd2C,MAAA,0DAA4D3C,MAAM,gC,IAanGA,MAAM,4BAqBb,IACCC,KAAM,kBAENC,MAAO,CACNK,YAAa,CACZH,KAAMC,QACNC,SAAS,GAEVH,mBAAoB,CACnBC,KAAMC,QACNC,SAAS,GAGVE,sBAAuB,CACtBJ,KAAMC,QACNC,SAAS,GAGVG,mBAAoB,CACnBL,KAAMC,QACNC,SAAS,GAGVI,4BAA6B,CAC5BN,KAAMC,QACNC,SAAS,GAGVQ,sBAAuB,CACtBV,KAAMC,QACNC,SAAS,IAIXS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAKyE,QAClCC,gBAAiB,CAChB,CACC/B,MAAO1C,qBAAqBD,KAAKyE,QAAQC,gBAAgB,GACzDzC,KAAM,YACNO,IAAKlF,EAAGE,QAAQC,UAAY,2BAC5BkH,OAAO,EACPjD,QAAQ,EACRkD,MAAM,GAEP,CACCjC,MAAO1C,qBAAqBD,KAAKyE,QAAQC,gBAAgB,GACzDlC,IAAK,iDACLP,KAAM,kCACN0C,OAAO,EACPjD,OAAQ,SACRkD,MAAM,GAEP,CACCjC,MAAO1C,qBAAqBD,KAAKyE,QAAQC,gBAAgB,GACzDzC,KAAM,oBACNO,IAAKlF,EAAGE,QAAQC,UAAY,+BAC5BkH,OAAO,EACPjD,QAAQ,EACRkD,MAAM,GAEP,CACCjC,MAAO1C,qBAAqBD,KAAKyE,QAAQC,gBAAgB,GACzDzC,KAAM,mBACNO,IAAKlF,EAAGE,QAAQC,UAAY,0BAC5BkH,OAAO,EACPjD,QAAQ,EACRkD,MAAM,GAEP,CACCjC,MAAO1C,qBAAqBD,KAAKyE,QAAQC,gBAAgB,GACzDzC,KAAM,iBACNO,IAAKlF,EAAGE,QAAQC,UAAY,4BAC5BkH,OAAO,EACPjD,QAAQ,EACRkD,MAAM,GAEP,CACCjC,MAAO1C,qBAAqBD,KAAKyE,QAAQC,gBAAgB,GACzDzC,KAAM,YACNO,IAAKlF,EAAGE,QAAQC,UAAY,+BAC5BkH,OAAO,EACPjD,QAAQ,EACRkD,MAAM,OCzJV,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,mODN3DlH,EAAAA,EAAAA,oBAsEM,aArELmH,EAAAA,EAAAA,oBAAA,6DACyB3G,EAAArB,a,uDAAzBiI,EAAAA,EAAAA,aAMmBC,EAAA,C,MANmBzI,MAAM,iB,uBAC3C,IAIM,EAJNwB,EAAAA,EAAAA,oBAIM,MAJNH,EAIM,EAHLG,EAAAA,EAAAA,oBAEI,IAFJC,EAEI,EADLH,EAAAA,EAAAA,aAAqGe,EAAA,CAAtFrC,MAAM,kBAAmBsC,IAAKmD,EAAAxE,eAAiB,qC,8BAK/DsH,EAAAA,EAAAA,oBAAA,iFACwB3G,EAAAd,wB,kBAAxB0H,EAAAA,EAAAA,aAMmBC,EAAA,C,MAN4BzI,MAAM,kB,uBACpD,IAIM,EAJNwB,EAAAA,EAAAA,oBAIM,MAJNE,EAIM,EAHLF,EAAAA,EAAAA,oBAEI,IAFJK,EAEI,EADHP,EAAAA,EAAAA,aAAsGe,EAAA,CAAvFrC,MAAM,mBAAoBsC,IAAKmD,EAAAxE,eAAiB,qC,kEAKlEsH,EAAAA,EAAAA,oBAAA,qDAEO3G,EAAArB,aAAeqB,EAAAzB,qB,kBADtBqI,EAAAA,EAAAA,aAOEE,EAAA,C,MALD1I,MAAM,QACL,gBAAe4B,EAAArB,YACf,2BAA0BqB,EAAApB,sBAC1B,wBAAuBoB,EAAAnB,mBACvB,kCAAiCmB,EAAAlB,6B,qJAGnC6H,EAAAA,EAAAA,oBAAA,2CACAjH,EAAAA,EAAAA,aAkBmBmH,EAAA,CAlBDzI,MAAM,mBAAiB,C,sBACxC,IAEM,EAFNwB,EAAAA,EAAAA,oBAEM,MAFNwF,GAEMZ,EAAAA,EAAAA,iBADFX,EAAA/B,KAAKiF,sBAAoB,IAE7BnH,EAAAA,EAAAA,oBAaM,MAbNyF,EAaM,EAZLzF,EAAAA,EAAAA,oBAWK,a,oBAVJJ,EAAAA,EAAAA,oBASKkE,EAAAA,SAAA,MAAAC,EAAAA,EAAAA,YATsBE,EAAA2C,gBAAhBQ,K,kBAAXxH,EAAAA,EAAAA,oBASK,KATL8F,EASK,CARO0B,EAAaN,O,kBAAxBlH,EAAAA,EAAAA,oBAOM,MAAAqG,EAAA,CANQmB,EAAaP,O,uDAA1BjH,EAAAA,EAAAA,oBAA+G,Q,MAA9EuB,MAAA,wCAA6C3C,OAAK6I,EAAAA,EAAAA,gBAAED,EAAajD,O,SACvFiD,EAAaP,Q,kBAAxBjH,EAAAA,EAAAA,oBAA+I,O,MAAhHuB,MAAA,+CAAkDL,IAAKmD,EAAAxE,eAAiB,iBAAmB2H,EAAajD,M,gDACvInE,EAAAA,EAAAA,oBAGI,KAHA4D,OAAQwD,EAAaxD,OAASa,KAAM2C,EAAa1C,K,6CACjD0C,EAAavC,OAAQ,IACxB,GAAYuC,EAAaxD,S,kBAAzBhE,EAAAA,EAAAA,oBAAyI,OAAzIyG,K,uGAQNU,EAAAA,EAAAA,oBAAA,4CACAjH,EAAAA,EAAAA,aAiBmBmH,EAAA,CAjBDzI,MAAM,oBAAkB,C,sBACzC,IAEM,EAFNwB,EAAAA,EAAAA,oBAEM,aADLF,EAAAA,EAAAA,aAA8Ee,EAAA,CAA9DC,IAAKmD,EAAAxE,eAAiB,sC,mBAEvCO,EAAAA,EAAAA,oBAIM,MAJNsG,GAIM,EAHLtG,EAAAA,EAAAA,oBAEI,UAAA4E,EAAAA,EAAAA,iBADAX,EAAA/B,KAAKoF,YAAYZ,aAAW,MAGjC1G,EAAAA,EAAAA,oBAOM,aANLF,EAAAA,EAAAA,aAKmByH,EAAA,CAJlB9C,KAAK,wHACL7F,KAAK,a,uBAEL,IAA6B,E,2CAA1BqF,EAAA/B,KAAKoF,YAAYxE,QAAM,K,oBC3D8C,CAAC,YAAY,qB,ICNnFtE,MAAM,kBAMZ,IACCC,KAAM,iBAENc,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,aCHxB,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+CDN1DC,EAAAA,EAAAA,oBAEM,MAFNC,GAEM,EADL2H,EAAAA,EAAAA,YAAavD,EAAAwD,OAAA,kBAAAC,GAAA,I,GCK6D,CAAC,YAAY,qB,ICClFlJ,MAAM,iB,IAMNA,MAAM,wB,IAKLA,MAAM,e,IAUNA,MAAM,kB,IAOPA,MAAM,yB,IAQLA,MAAM,kB,IACPiG,KAAK,4G,IAWHjG,MAAM,+B,IAOPA,MAAM,sC,IAOLA,MAAM,+B,IACPiG,KAAK,oHAUb,IACChG,KAAM,cAENC,MAAO,CACNK,YAAwB,CACvBH,KAAMC,QACNC,SAAS,GAEVE,sBAAwB,CACvBJ,KAAMC,QACNC,SAAS,GAEVG,mBAAqB,CACpBL,KAAMC,QACNC,SAAS,GAEVI,4BAA8B,CAC7BN,KAAMC,QACNC,SAAS,IAIXS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAKyF,OCjGpC,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,4IDN1D/H,EAAAA,EAAAA,oBA2EM,YAxEGQ,EAAApB,sBAsBKoB,EAAAnB,mBA0BAmB,EAAAlB,6B,uDADb8H,EAAAA,EAAAA,aAuBmBC,EAAA,C,MArBlBzI,MAAM,gC,uBAEN,IAkBM,EAlBNwB,EAAAA,EAAAA,oBAkBM,aAjBLA,EAAAA,EAAAA,oBAMM,MANNiG,GAMM,EALLjG,EAAAA,EAAAA,oBAIK,Y,2CAHDiE,EAAA/B,KAAK0F,UAAU/C,OAAQ,IAC1B,G,aAAA7E,EAAAA,EAAAA,oBAAI,qBACJA,EAAAA,EAAAA,oBAAoC,UAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAK0F,UAAUC,UAAQ,QAG/B7H,EAAAA,EAAAA,oBAMK,KANLmG,GAMK,EALJnG,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAK0F,UAAUE,KAAK,IAAD,IAC1B9H,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAK0F,UAAUE,KAAK,IAAD,IAC1B9H,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAK0F,UAAUE,KAAK,IAAD,IAC1B9H,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAK0F,UAAUE,KAAK,IAAD,IAC1B9H,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAK0F,UAAUE,KAAK,IAAD,MAE3B9H,EAAAA,EAAAA,oBAEM,MAFN+H,GAEM,EADL/H,EAAAA,EAAAA,oBAAwJ,IAAxJqG,IAAwJzB,EAAAA,EAAAA,iBAA1BX,EAAA/B,KAAK0F,UAAUI,MAAI,S,2BA9CpJhB,EAAAA,EAAAA,aAwBmBC,EAAA,C,MAtBlBzI,MAAM,6B,uBAEN,IAKM,EALNwB,EAAAA,EAAAA,oBAKM,MALNK,GAKM,EAJLL,EAAAA,EAAAA,oBAGK,Y,2CAFDiE,EAAA/B,KAAK+F,OAAOpD,OAAQ,IACvB,IAAA7E,EAAAA,EAAAA,oBAAuC,aAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAK+F,OAAOJ,UAAQ,QAI/B7H,EAAAA,EAAAA,oBAMK,KANLwF,GAMK,EALJxF,EAAAA,EAAAA,oBAAkC,WAAA4E,EAAAA,EAAAA,iBAA3BX,EAAA/B,KAAK+F,OAAOH,KAAK,IAAD,IACvB9H,EAAAA,EAAAA,oBAAkC,WAAA4E,EAAAA,EAAAA,iBAA3BX,EAAA/B,KAAK+F,OAAOH,KAAK,IAAD,IACvB9H,EAAAA,EAAAA,oBAAkC,WAAA4E,EAAAA,EAAAA,iBAA3BX,EAAA/B,KAAK+F,OAAOH,KAAK,IAAD,IACvB9H,EAAAA,EAAAA,oBAAkC,WAAA4E,EAAAA,EAAAA,iBAA3BX,EAAA/B,KAAK+F,OAAOH,KAAK,IAAD,IACvB9H,EAAAA,EAAAA,oBAAkC,WAAA4E,EAAAA,EAAAA,iBAA3BX,EAAA/B,KAAK+F,OAAOH,KAAK,IAAD,MAGxB9H,EAAAA,EAAAA,oBAIM,MAJNyF,GAIM,EAHLzF,EAAAA,EAAAA,oBAEI,IAFJ0F,IAEId,EAAAA,EAAAA,iBADAX,EAAA/B,KAAK+F,OAAOD,MAAI,O,2BA3CtBhB,EAAAA,EAAAA,aAoBmBC,EAAA,C,MAlBlBzI,MAAM,kB,uBAGN,IAIK,EAJLwB,EAAAA,EAAAA,oBAIK,KAJLH,GAIK,E,2CAHDoE,EAAA/B,KAAKgG,UAAUrD,OAAQ,IAC1B,G,aAAA7E,EAAAA,EAAAA,oBAAI,qBACJA,EAAAA,EAAAA,oBAA8C,eAAA4E,EAAAA,EAAAA,iBAAnCX,EAAA/B,KAAKgG,UAAUL,UAAQ,MAGnC7H,EAAAA,EAAAA,oBAIK,KAJLC,GAIK,EAHJD,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAKgG,UAAUJ,KAAK,IAAD,IAC1B9H,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAKgG,UAAUJ,KAAK,IAAD,IAC1B9H,EAAAA,EAAAA,oBAAqC,WAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAKgG,UAAUJ,KAAK,IAAD,MAE3B9H,EAAAA,EAAAA,oBAGM,MAHNE,GAGM,EAFLJ,EAAAA,EAAAA,aAAuFe,EAAA,CAAxErC,MAAM,aAAcsC,IAAKmD,EAAAxE,eAAiB,4B,iBACzDK,EAAAA,EAAAA,aAAkGe,EAAA,CAAnFrC,MAAM,oBAAqBsC,IAAKmD,EAAAxE,eAAiB,gC,+BCdQ,CAAC,YAAY,qB,qBCEzF,IACChB,KAAM,iBAENC,MAAO,CACNE,KAAM,CACLA,KAAMQ,OACNN,QAASA,IAAM,WAGhB2F,KAAM,CACL7F,KAAMQ,OACNN,QAASA,IAAM,KAGhB8E,OAAQ,CACPhF,KAAMQ,OACNN,QAASA,IAAM,UAIjBS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,YAGvBY,SAAU,CACT/B,QACC,MAAO,WAAWiC,KAAK7B,MACxB,IC5BF,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+CDN1DgB,EAAAA,EAAAA,oBAIM,aAHLI,EAAAA,EAAAA,oBAEI,KAFAyE,KAAMrE,EAAAqE,KAAOjG,OAAK6I,EAAAA,EAAAA,gBAAEtG,EAAAvC,OAAQoF,OAAQxD,EAAAwD,Q,EACvC4D,EAAAA,EAAAA,YAAavD,EAAAwD,OAAA,kBAAAC,GAAA,I,WCI4D,CAAC,YAAY,qB,ICLlFlJ,MAAM,oC,gBAaJ2C,MAAA,yBAA6BwE,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8BA2CnG,IACCtH,KAAM,oBAENC,MAAO,CACNC,mBAAoB,CACnBC,KAAMC,QACNC,SAAS,GAEVG,mBAAqB,CACpBL,KAAMC,QACNC,SAAS,GAEVC,YAAa,CACZH,KAAMC,QACNC,SAAS,GAEVqJ,mBAAoB,CACnBvJ,KAAMQ,OACNN,QAAS,YAGRO,cAAe,CACbT,KAAMC,QACNC,SAAS,IAIdS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACtByI,OAAQ,OACLlG,KAAMC,qBAAqBD,KAAKmG,YAGpC3H,QAAS,CACR4H,6BAAAA,CAA+BF,GAC9B3H,KAAK2H,OAASA,CACf,ICtFF,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+VDN1DxI,EAAAA,EAAAA,oBAqDM,aApDLI,EAAAA,EAAAA,oBAiBM,MAjBNH,GAiBM,EAhBLC,EAAAA,EAAAA,aAI2ByI,EAAA,CAHrBC,oBAAqBzH,EAAAuH,8BAC1BnH,MAAA,eACC,uBAAsBf,EAAAzB,oB,uDAOjByB,EAAAzB,oBAAsByB,EAAAnB,qB,kBAJ7BW,EAAAA,EAAAA,oBASwB,K,MARvBuB,MAAA,gBACA3C,MAAM,mBACLiG,KAAMR,EAAAtE,UAAY,sC,qBAGnBC,EAAAA,EAAAA,oBAEM,MAFNM,GAEM,IAAAuI,EAAA,KAAAA,EAAA,KADLzI,EAAAA,EAAAA,oBAA83B,QAAx3B,YAAU,UAAU,YAAU,UAAUgG,EAAE,8zBAA8zBF,KAAK,W,oCAC92B,KACNlB,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAKwG,UAAQ,I,6CAKTtI,EAAAzB,oB,uDAFTqI,EAAAA,EAAAA,aAKqB2B,EAAA,C,MAJpBnK,MAAM,QAEF,mBAAkB4B,EAAAf,cACrB,uBAAsBe,EAAAzB,oB,sDAGxBmB,EAAAA,EAAAA,aAK6B8I,EAAA,CAJ3BR,OAAQnE,EAAAmE,OACT5J,MAAM,QACL,uBAAsB4B,EAAAzB,mBACtB,gBAAeyB,EAAArB,a,0DAKVqB,EAAAzB,qB,kBAFPqI,EAAAA,EAAAA,aAKqB2B,EAAA,C,MAJpBnK,MAAM,QAEL,uBAAsB4B,EAAAzB,mBACnB,mBAAkByB,EAAAf,e,0FAGvBS,EAAAA,EAAAA,aAG0B+I,EAAA,CAFzBrK,MAAM,QACL,uBAAsB4B,EAAAzB,oB,iCAIfyB,EAAArB,a,uDADTiI,EAAAA,EAAAA,aAI0B8B,EAAA,C,MAFzBtK,MAAM,QACL,wBAAuB4B,EAAA+H,oB,oCAGzBrI,EAAAA,EAAAA,aAAiDiJ,EAAA,CAAhCvK,MAAM,W,GC9CmD,CAAC,YAAY,qBCEzF,IACCE,MAAO,CACNC,mBAAoB,CACnBC,KAAMC,QACNC,SAAS,IAIXL,KAAM,uBAENc,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAK8G,OAGnCtI,QAAS,CACRuI,wBAAAA,CAA0BpG,EAAGuF,GAC5BvF,EAAEE,iBAEcU,SAASyF,iBAAkB,kBAEnCC,QAASrG,IAChBA,EAAOsG,UAAUC,OAAQ,YAG1BxG,EAAEe,OAAOwF,UAAUE,IAAK,UAExB7I,KAAK8I,MAAO,sBAAuBnB,EACpC,GAGD7H,SAAU,CACTiJ,0BAAAA,GACC,IAAIC,EAAU,CACb,SAAW,GAQZ,OALOhJ,KAAK9B,qBACX8K,EAAkB,UAAI,GAIhBA,CACR,IC5CF,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+CDN1D7J,EAAAA,EAAAA,oBAIM,OAJApB,OAAK6I,EAAAA,EAAAA,gBAAEtG,EAAAyI,6B,EACZxJ,EAAAA,EAAAA,oBAA0G,UAAjGgE,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAAkI,yBAA0BpG,EAAG,UAAWrE,MAAM,kB,qBAAoByF,EAAA/B,KAAK,IAAD,IAC3FlC,EAAAA,EAAAA,oBAA+G,UAAtGgE,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAAkI,yBAA0BpG,EAAG,SAAUrE,MAAM,yB,qBAA0ByF,EAAA/B,KAAK,IAAD,IAChGlC,EAAAA,EAAAA,oBAAuG,UAA9FgE,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAAkI,yBAA0BpG,EAAG,QAASrE,MAAM,kB,qBAAmByF,EAAA/B,KAAK,IAAD,I,KCGd,CAAC,YAAY,qB,ICNnF1D,MAAM,kB,gCAuBNA,MAAM,6B,UAKNA,MAAM,6B,gCA8BNA,MAAM,6B,UAKNA,MAAM,6B,gCA8BNA,MAAM,6B,UAKNA,MAAM,6B,IAiBH2C,MAAA,wBAA4B3C,MAAM,sB,IAWpCoF,OAAO,SAASa,KAAK,iG,IACjBjG,MAAM,e,gCAgCXA,MAAM,6B,UAKNA,MAAM,6BAWZ,IACCC,KAAM,yBAENC,MAAO,CACN0J,OAAQ,CACPxJ,KAAMQ,OACNN,QAASA,IAAM,SAGhBH,mBAAoB,CACnBC,KAAMC,QACNC,SAAS,GAGVC,YAAa,CACZH,KAAMC,QACNC,SAAS,IAIXS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UAEtB+J,YAAa,IACbC,cAAe,IACfC,aAAc,IACd/E,MAAO,GAEPgF,aAAc,IAEZ3H,KAAMC,qBAAqBD,KAAK4H,QAGnCtH,MAAO,CACN4F,MAAAA,CAAQ2B,GACPtJ,KAAKuJ,cAAeD,EACrB,GAGDrJ,QAAS,CACRuJ,QAAAA,CAAU7B,GACT,OAASA,GACR,IAAK,MACJ,OAAO3H,KAAKyB,KAAK8G,KAAK,GAEvB,IAAK,OACJ,OAAOvI,KAAKyB,KAAK8G,KAAK,GAEvB,IAAK,QACJ,OAAOvI,KAAKyB,KAAK8G,KAAK,GAEzB,EAEAgB,aAAAA,CAAe5B,GACdlF,MAAMC,IAAK,cAAe,CACzB+G,OAAQ,CACP9B,OAAQA,KAGRhF,KAAMC,SAC6B,IAAvBA,EAAS9D,KAAK4K,QACzB1J,KAAKiJ,YAAcrG,EAAS9D,KAAK4K,MAAMC,MACvC3J,KAAKkJ,cAAgBtG,EAAS9D,KAAK4K,MAAME,QACzC5J,KAAKmJ,aAAevG,EAAS9D,KAAK4K,MAAMG,QAIpC7J,KAAK1B,cACT0B,KAAKoJ,aAAexG,EAAS9D,KAAK4K,MAAMlF,QAAU,GAGnDxE,KAAKoE,MAAQpE,KAAKwJ,SAAU7B,IAE/B,EAEAmC,aAAAA,GACCrF,OAAOsF,KAAM,gGAAiG,SAC/G,GAIDhH,OAAAA,GACC/C,KAAKuJ,cAAevJ,KAAK2H,OAC1B,GC3PD,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,0IDN1DxI,EAAAA,EAAAA,oBA2KM,MA3KNC,GA2KM,EAzKLC,EAAAA,EAAAA,aA+BiB2K,EAAA,CA9BhB7L,KAAK,MACJ,SAAQwB,EAAArB,YACTP,MAAM,sB,CAGW2L,OAAKO,EAAAA,EAAAA,SAHL,IAGlB,CACatK,EAAAzB,qB,kBAAXiB,EAAAA,EAAAA,oBAEM,MAAAK,IAAA2E,EAAAA,EAAAA,iBADFX,EAAAyF,aAAW,M,kBAGf9J,EAAAA,EAAAA,oBAEM,MAAAM,GAFM,UAKIyK,SAAOD,EAAAA,EAAAA,SACvB,IAYM,EAZN1K,EAAAA,EAAAA,oBAYM,a,2CAXFiE,EAAA/B,KAAKkI,OAAQ,IAChB,G,aAAApK,EAAAA,EAAAA,oBAAI,oBAGGI,EAAAzB,qB,kBAFPiB,EAAAA,EAAAA,oBAGmB,OAHnBS,IAGmBuE,EAAAA,EAAAA,iBAAfX,EAAAY,OAAK,M,kBAETjF,EAAAA,EAAAA,oBAGS,OAHT4F,GAGC,U,oBAKJ1F,EAAAA,EAAAA,aAiCiB2K,EAAA,CAhChB7L,KAAK,UACJ,SAAQwB,EAAArB,YACTP,MAAM,sB,CAGW2L,OAAKO,EAAAA,EAAAA,SAXN,IAMf,CAOOtK,EAAAzB,qB,kBADPiB,EAAAA,EAAAA,oBAIM,MAAA6F,IAAAb,EAAAA,EAAAA,iBADFX,EAAA0F,eAAa,M,kBAGjB/J,EAAAA,EAAAA,oBAEQ,MAAA8F,GAAP,QAGeiF,SAAOD,EAAAA,EAAAA,SACvB,IAYM,EAZN1K,EAAAA,EAAAA,oBAYM,a,2CAXFiE,EAAA/B,KAAKmI,SAAU,IAClB,G,aAAArK,EAAAA,EAAAA,oBAAI,oBAGGI,EAAAzB,qB,kBAFPiB,EAAAA,EAAAA,oBAGmB,OAHnBqG,IAGmBrB,EAAAA,EAAAA,iBAAfX,EAAAY,OAAK,M,kBAETjF,EAAAA,EAAAA,oBAGS,OAHTuG,GAGC,U,oBAKJrG,EAAAA,EAAAA,aAiCiB2K,EAAA,CAhChB7L,KAAK,SACJ,SAAQwB,EAAArB,YACTP,MAAM,sB,CAGW2L,OAAKO,EAAAA,EAAAA,SAPtB,IAKK,CAIGtK,EAAAzB,qB,kBADPiB,EAAAA,EAAAA,oBAIM,MAAAmI,IAAAnD,EAAAA,EAAAA,iBADFX,EAAA2F,cAAY,M,kBAGhBhK,EAAAA,EAAAA,oBAEQ,MAAAyG,GAAP,QAGesE,SAAOD,EAAAA,EAAAA,SACvB,IAYM,EAZN1K,EAAAA,EAAAA,oBAYM,a,2CAXFiE,EAAA/B,KAAKoI,QAAS,IACjB,G,aAAAtK,EAAAA,EAAAA,oBAAI,oBAGGI,EAAAzB,qB,kBAFPiB,EAAAA,EAAAA,oBAGmB,OAHnB0G,IAGmB1B,EAAAA,EAAAA,iBAAfX,EAAAY,OAAK,M,kBAETjF,EAAAA,EAAAA,oBAGS,OAHT2G,GAGC,U,oBAKJQ,EAAAA,EAAAA,oBAAA,oBAGS3G,EAAArB,a,uDAFTiI,EAAAA,EAAAA,aA0BiByD,EAAA,C,MAzBhB7L,KAAK,cAELJ,MAAM,oBACLwF,QAAOjD,EAAAwJ,cACRpJ,MAAA,oB,CAGiBgJ,OAAKO,EAAAA,EAAAA,SACrB,IAEM,EAFN1K,EAAAA,EAAAA,oBAEM,MAFNwG,IAEM5B,EAAAA,EAAAA,iBADFX,EAAA/B,KAAK0I,UAAU/F,OAAK,KAIR8F,SAAOD,EAAAA,EAAAA,SACvB,IAIiB,EAJjB5K,EAAAA,EAAAA,aAIiBe,EAAA,CAHhBM,MAAA,8CACCL,IAAKmD,EAAAxE,eAAiB,6BACvBsC,IAAI,U,iBAEL/B,EAAAA,EAAAA,oBAII,IAJJyG,GAII,EAHHzG,EAAAA,EAAAA,oBAEO,OAFP6K,IAEOjG,EAAAA,EAAAA,iBADHX,EAAA/B,KAAK0I,UAAU/C,UAAQ,O,sBAK9Bd,EAAAA,EAAAA,oBAAA,eAKO3G,EAAArB,c,kBAHPiI,EAAAA,EAAAA,aAkCiByD,EAAA,C,MAjChB7L,KAAK,cACJ,SAAQwB,EAAArB,YAETP,MAAM,sB,CAGW2L,OAAKO,EAAAA,EAAAA,SAAA,KAEdtK,EAAAzB,qB,kBADPiB,EAAAA,EAAAA,oBAIM,MAAAkL,IAAAlG,EAAAA,EAAAA,iBADFX,EAAA4F,cAAY,M,kBAGhBjK,EAAAA,EAAAA,oBAEQ,MAAAmL,GAAP,QAGeJ,SAAOD,EAAAA,EAAAA,SACvB,IAYM,EAZN1K,EAAAA,EAAAA,oBAYM,a,2CAXFiE,EAAA/B,KAAK+C,QAAS,IACjB,G,aAAAjF,EAAAA,EAAAA,oBAAI,oBAGGI,EAAAzB,qB,kBAFPiB,EAAAA,EAAAA,oBAGmB,OAHnBoL,IAGmBpG,EAAAA,EAAAA,iBAAfX,EAAAY,OAAK,M,kBAETjF,EAAAA,EAAAA,oBAGS,OAHTqL,GAGC,U,4DChKsE,CAAC,YAAY,qB,kBCLlFzM,MAAM,kC,IACLA,MAAM,4BAA4B2C,MAAA,yB,IAKjC3C,MAAM,mB,IAKPA,MAAM,qBAUd,IACCC,KAAM,eAENC,MAAO,CACNE,KAAM,CACLA,KAAMQ,OACN8B,UAAU,GAGXgK,MAAO,CACNtM,KAAMC,QACNC,SAAS,IAIXS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,YAGvBY,SAAU,CACTkJ,OAAAA,GACC,MAAO,CACN,kBAAkB,EAClB,qBAAoC,QAAdhJ,KAAK7B,KAC3B,yBAAwC,YAAd6B,KAAK7B,KAC/B,wBAAuC,WAAd6B,KAAK7B,KAC9B,6BAA4C,gBAAd6B,KAAK7B,KAEnC,qBAAsB6B,KAAKyK,MAE7B,IC7CF,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+CDN1DtL,EAAAA,EAAAA,oBAkBM,OAlBApB,OAAK6I,EAAAA,EAAAA,gBAAEtG,EAAA0I,SAAU,SAAQrJ,EAAA8K,O,EAC9BlL,EAAAA,EAAAA,oBAgBM,MAhBNC,GAgBM,EAfLD,EAAAA,EAAAA,oBAEM,MAFNE,GAEM,EADLsH,EAAAA,EAAAA,YAA0BvD,EAAAwD,OAAA,gBAAAC,GAAA,MAE3B1H,EAAAA,EAAAA,oBAWM,aAVLA,EAAAA,EAAAA,oBAIM,OAJDxB,MAAM,0BAA2B2C,OAAKa,EAAAA,EAAAA,gBAAA,mCAA0C5B,EAAAxB,KAAO,MAAQ,UAAX,M,EACxFoB,EAAAA,EAAAA,oBAEK,KAFLK,GAEK,EADJmH,EAAAA,EAAAA,YAA0BvD,EAAAwD,OAAA,gBAAAC,GAAA,M,IAG5B1H,EAAAA,EAAAA,oBAIM,aAHLA,EAAAA,EAAAA,oBAEI,IAFJwF,GAEI,EADHgC,EAAAA,EAAAA,YAA4BvD,EAAAwD,OAAA,kBAAAC,GAAA,Y,SCP0C,CAAC,YAAY,qB,gBCQ9EvG,MAAA,yBAA6BwE,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,gBAoB1F5E,MAAA,yBAA6BwE,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,gBAqBpF5E,MAAA,yBAA6BwE,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8BAY3G,IACCtH,KAAM,oBAENC,MAAO,CACNC,mBAAoB,CACnBC,KAAMC,QACNC,SAAS,GAEVG,mBAAoB,CACnBL,KAAMC,QACNC,SAAS,GAERO,cAAe,CACbT,KAAMC,QACNC,SAAS,IAIdS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAKiJ,UAGnC5K,SAAU,CACT6K,mBAAAA,GACC,MAAO,GAAG3K,KAAKd,mCAChB,EAEA0L,UAAAA,GACC,MAAO,GAAG5K,KAAKd,6CAChB,GAEA6D,OAAAA,GACE8H,QAAQC,IAAK9K,KAAKpB,cACpB,GC9FF,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,kGDN1DO,EAAAA,EAAAA,oBA+DM,aA5DIQ,EAAAzB,qBAAsByB,EAAAnB,oBAA0BmB,EAAAf,e,uDAFzD2H,EAAAA,EAAAA,aAiBmBwE,EAAA,C,MAhBlB5M,KAAK,W,CAGYiG,OAAK6F,EAAAA,EAAAA,SACrB,IAA0B,E,2CAAvBzG,EAAA/B,KAAKuJ,WAAWC,MAAI,KAIP5I,QAAM4H,EAAAA,EAAAA,SACtB,IAKI,EALJ1K,EAAAA,EAAAA,oBAKI,KALAyE,KAAM1D,EAAAqK,oBAAqB5M,MAAM,oB,6CACjCyF,EAAA/B,KAAKuJ,WAAW3I,QAAS,IAC5B,IAAA9C,EAAAA,EAAAA,oBAEI,Y,kBADHJ,EAAAA,EAAAA,oBAA0hC,MAA1hCK,GAA0hC,IAAAwI,EAAA,KAAAA,EAAA,KAA95BzI,EAAAA,EAAAA,oBAAsxB,KAAnxB,YAAU,uBAAqB,EAACA,EAAAA,EAAAA,oBAA+uB,QAAzuBgG,EAAE,ytBAAytBF,KAAK,Y,IAAa9F,EAAAA,EAAAA,oBAAkI,cAA5HA,EAAAA,EAAAA,oBAAqH,YAA3GgF,GAAG,iBAAe,EAAChF,EAAAA,EAAAA,oBAA6E,QAAvE2F,MAAM,KAAKC,OAAO,KAAKE,KAAK,QAAQ6F,UAAU,8B,0BAQp+BvL,EAAAzB,oBAAwByB,EAAAnB,oBAAwBmB,EAAAf,e,uDAFzD2H,EAAAA,EAAAA,aAoBmBwE,EAAA,C,MAnBlB5M,KAAK,W,CAIYiG,OAAK6F,EAAAA,EAAAA,SACrB,IAA6B,E,2CAA1BzG,EAAA/B,KAAK0J,cAAcF,MAAI,KAIV5I,QAAM4H,EAAAA,EAAAA,SACtB,IAOI,EAPJ1K,EAAAA,EAAAA,oBAOI,KAPAyE,KAAM1D,EAAAsK,WAAY7M,MAAM,oB,6CACxByF,EAAA/B,KAAK0J,cAAc9I,QAAS,IAC/B,IAAA9C,EAAAA,EAAAA,oBAII,Y,kBAHHJ,EAAAA,EAAAA,oBAEM,MAFNS,GAEM,IAAAoI,EAAA,KAAAA,EAAA,KADLzI,EAAAA,EAAAA,oBAAkuB,QAA5tBgG,EAAE,0sBAA0sBF,KAAK,W,gCAShtB1F,EAAAf,gB,kBAFV2H,EAAAA,EAAAA,aAmBmBwE,EAAA,C,MAlBf5M,KAAK,W,CAGUiG,OAAK6F,EAAAA,EAAAA,SACpB,IAAyB,E,2CAAtBzG,EAAA/B,KAAK2J,UAAUH,MAAI,KAIP5I,QAAM4H,EAAAA,EAAAA,SACrB,IAOI,EAPJ1K,EAAAA,EAAAA,oBAOI,KAPAyE,KAAM1D,EAAAsK,WAAY7M,MAAM,oB,6CACvByF,EAAA/B,KAAK2J,UAAU/I,QAAS,IAC3B,IAAA9C,EAAAA,EAAAA,oBAII,Y,kBAHFJ,EAAAA,EAAAA,oBAEM,MAFN6F,GAEM,IAAAgD,EAAA,KAAAA,EAAA,KADJzI,EAAAA,EAAAA,oBAAkuB,QAA5tBgG,EAAE,0sBAA0sBF,KAAK,W,wEClDzpB,CAAC,YAAY,qB,ICNnFtH,MAAM,4B,IAGLA,MAAM,4B,IAEPA,MAAM,yB,UAED2C,MAAA,yBAAuDwE,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,UAIpH5E,MAAA,yBAAuDwE,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8BAoB/H,IACCtH,KAAM,iBAENC,MAAO,CACNE,KAAM,CACLA,KAAMQ,OACN8B,UAAU,IAIZ3B,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,YAGvBY,SAAU,CACTkJ,OAAAA,GACC,MAAO,CACN,oBAAoB,EACpB,2BAA0C,YAAdhJ,KAAK7B,KACjC,yBAAwC,UAAd6B,KAAK7B,KAC/B,2BAA0C,YAAd6B,KAAK7B,KAEnC,IC9CF,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+CDN1DgB,EAAAA,EAAAA,oBA2BM,MA3BNC,GA2BM,EA1BLG,EAAAA,EAAAA,oBAyBM,OAzBAxB,OAAK6I,EAAAA,EAAAA,gBAAEtG,EAAA0I,U,EACZzJ,EAAAA,EAAAA,oBAoBM,aAnBLA,EAAAA,EAAAA,oBAkBI,IAlBJC,GAkBI,EAjBHD,EAAAA,EAAAA,oBAWO,OAXPE,GAWO,C,YARgDE,EAAAxB,O,kBAAtDgB,EAAAA,EAAAA,oBAEM,MAFNS,GAEM,IAAAoI,EAAA,KAAAA,EAAA,KADLzI,EAAAA,EAAAA,oBAAqR,QAA/QgG,EAAE,6PAA6PF,KAAK,W,8DAGrN1F,EAAAxB,O,kBAAtDgB,EAAAA,EAAAA,oBAEM,MAFN4F,GAEM,IAAAiD,EAAA,KAAAA,EAAA,KADLzI,EAAAA,EAAAA,oBAAmL,QAA7KgG,EAAE,2JAA2JF,KAAK,W,qDAK1K9F,EAAAA,EAAAA,oBAES,gBADRwH,EAAAA,EAAAA,YAA0BvD,EAAAwD,OAAA,gBAAAC,GAAA,MAE3BF,EAAAA,EAAAA,YAA4BvD,EAAAwD,OAAA,kBAAAC,GAAA,QAG9B1H,EAAAA,EAAAA,oBAEM,aADLwH,EAAAA,EAAAA,YAA2BvD,EAAAwD,OAAA,iBAAAC,GAAA,M,OClB6C,CAAC,YAAY,qB,ICNnFlJ,MAAM,0B,IAELA,MAAM,yB,IACLA,MAAM,c,IAGNA,MAAM,e,gBAKPA,MAAM,uB,eAKJ2C,MAAA,qC,IACAA,MAAA,wC,IACAA,MAAA,wC,IACAA,MAAA,qC,IAUE3C,MAAM,4B,UAC6BA,MAAM,sC,UACL2C,MAAA,+CAAmD3C,MAAM,oB,UAC3DA,MAAM,qC,UAc/CA,MAAM,wB,IAwBDA,MAAM,0B,UAIsBA,MAAM,yB,YAU3C,IACCC,KAAM,sBAENC,MAAO,CACNC,mBAAoB,CACnBC,KAAMC,QACNC,SAAS,IAIXS,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAKoB,KAElCA,KAAM,KAGPd,MAAO,CAAC,EAERjC,SAAU,CACTuL,2BAAAA,GACC,OAAOrL,KAAK6C,KAAKY,MAClB,EAEA6H,YAAAA,GACC,MAAO,GAAGtL,KAAKd,kCAChB,EAEA0L,UAAAA,GACC,MAAO,GAAG5K,KAAKd,6CAChB,GAGDe,QAAS,CAERsL,QAAAA,GACC9I,MAAMC,IAAK,YACTC,KAAMC,IACN5C,KAAK6C,KAAOD,EAAS9D,KAAK+D,MAE7B,EAEA2I,aAAAA,GACCxL,KAAKuL,UACN,EAEAE,sBAAuBC,IASf,CACNzJ,QAPIyJ,EAAKC,cACC,QAEA,UASb5I,OAAAA,GAEC/C,KAAKuL,WAELvI,SAASC,KAAKC,iBAAkB,QAAW0I,IACnCA,EAAMzI,OAAOC,QAAS,wBAC5BpD,KAAK6C,KAAK6F,QAAWoC,IACpBA,EAAIa,eAAgB,KAKxB,GCtJD,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,2GDN1DxM,EAAAA,EAAAA,oBAgFM,MAhFNC,GAgFM,EA9ELG,EAAAA,EAAAA,oBAOM,MAPNC,GAOM,EANLD,EAAAA,EAAAA,oBAEM,MAFNE,GAEM,EADLF,EAAAA,EAAAA,oBAAyB,WAAA4E,EAAAA,EAAAA,iBAAlBX,EAAA/B,KAAK2C,OAAK,MAElB7E,EAAAA,EAAAA,oBAEM,MAFNK,GAEM,EADLL,EAAAA,EAAAA,oBAA6C,KAAzCyE,KAAM1D,EAAAgL,eAAYnH,EAAAA,EAAAA,iBAAKX,EAAA/B,KAAKY,QAAM,EAAA0C,SAIxCxF,EAAAA,EAAAA,oBAoEM,MApENyF,GAoEM,CAlEQ1E,EAAA+K,8B,kBAAblM,EAAAA,EAAAA,oBA8BQ,QAAA8F,GAAA,EA7BP1F,EAAAA,EAAAA,oBAOQ,eANRA,EAAAA,EAAAA,oBAKK,YAJJA,EAAAA,EAAAA,oBAAqE,KAArEiG,IAAqErB,EAAAA,EAAAA,iBAAvBX,EAAA/B,KAAKoK,QAAQ,IAAD,IAC1DtM,EAAAA,EAAAA,oBAAwE,KAAxEmG,IAAwEvB,EAAAA,EAAAA,iBAAvBX,EAAA/B,KAAKoK,QAAQ,IAAD,IAC7DtM,EAAAA,EAAAA,oBAAwE,KAAxE+H,IAAwEnD,EAAAA,EAAAA,iBAAvBX,EAAA/B,KAAKoK,QAAQ,IAAD,IAC7DtM,EAAAA,EAAAA,oBAAqE,KAArEqG,IAAqEzB,EAAAA,EAAAA,iBAAvBX,EAAA/B,KAAKoK,QAAQ,IAAD,QAI3DtM,EAAAA,EAAAA,oBAmBQ,gB,oBAlBPJ,EAAAA,EAAAA,oBAiBIkE,EAAAA,SAAA,MAAAC,EAAAA,EAAAA,YAjBeE,EAAAX,KAAR6I,K,kBAAXvM,EAAAA,EAAAA,oBAiBI,MAjBsB2F,IAAK4G,EAAKnH,I,EACpChF,EAAAA,EAAAA,oBAA2B,WAAA4E,EAAAA,EAAAA,iBAApBuH,EAAKjG,SAAO,IACnBlG,EAAAA,EAAAA,oBAA2B,WAAA4E,EAAAA,EAAAA,iBAApBuH,EAAKI,SAAO,IACnBvM,EAAAA,EAAAA,oBAAiC,WAAA4E,EAAAA,EAAAA,iBAA1BuH,EAAK/F,eAAa,IACzBpG,EAAAA,EAAAA,oBAYK,YAXJA,EAAAA,EAAAA,oBAUM,MAVNsG,GAUM,C,YATqB6F,EAAKK,S,kBAA/B5M,EAAAA,EAAAA,oBAA2G,OAA3G2G,IAA2G3B,EAAAA,EAAAA,iBAAtBX,EAAA/B,KAAKmI,SAAO,K,gDACtE8B,EAAKK,S,kBAAhC5M,EAAAA,EAAAA,oBAAmI,OAAnI4G,GAAoH,c,8CAC3F2F,EAAKK,S,kBAA9B5M,EAAAA,EAAAA,oBAAwG,OAAxG6G,IAAwG7B,EAAAA,EAAAA,iBAArBX,EAAA/B,KAAKoI,QAAM,K,oCAE9FxK,EAAAA,EAAAA,aAI6B2M,EAAA,CAHvBC,iBAAiB3L,EAAAkL,cACrBE,KAAMA,EACN,aAAYA,EAAKnH,I,wFAQvBpF,EAAAA,EAAAA,oBAgCM,MAhCNiL,GAgCM,C,+oDAPL7K,EAAAA,EAAAA,oBAGM,MAHN8K,GAGM,EAFL9K,EAAAA,EAAAA,oBAAgC,WAAA4E,EAAAA,EAAAA,iBAAzBX,EAAA/B,KAAKyK,OAAO9H,OAAK,IACxB7E,EAAAA,EAAAA,oBAAoC,UAAA4E,EAAAA,EAAAA,iBAA9BX,EAAA/B,KAAKyK,OAAOjG,aAAW,KAEjBtG,EAAAzB,oB,uDAAbiB,EAAAA,EAAAA,oBAEM,MAFNmL,GAEM,EADL/K,EAAAA,EAAAA,oBAAkD,KAA9CyE,KAAM1D,EAAAsK,aAAUzG,EAAAA,EAAAA,iBAAKX,EAAA/B,KAAK0J,eAAa,EAAAZ,a,GCrE4B,CAAC,YAAY,qB,ICJjFxM,MAAM,kB,IAaNA,MAAM,kB,IAUNA,MAAM,kB,UAoB0BA,MAAM,kB,UAYvCA,MAAM,2B,IACLA,MAAM,6B,UAIkB2C,MAAA,sJ,qCActB3C,MAAM,sB,+GA0DNA,MAAM,wB,IAELA,MAAM,c,IACHoO,IAAI,S,IAERpO,MAAM,cAAc2C,MAAA,0BAsB9B,IACC1C,KAAM,wBAENC,MAAO,CACNyN,KAAM,CACLvN,KAAMwC,OACNF,UAAU,GAEX2L,UAAW,CACVjO,KAAMQ,OACN8B,UAAU,IAIZ3B,KAAQC,IAAC,CACRC,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACpBuC,KAAMC,qBAAqBD,KAAK4K,cAElCC,YAAY,EACZC,YAAY,EACZC,WAAW,EACXC,iBAAiB,EACjBC,cAAc,EACdC,mBAAoB,aAEpBC,iBAAiB,EAEjBC,eAAgB,CACfC,KAAM,GACNC,GAAI,GACJC,KAAM,GACNvH,QAAS,GACTwH,aAAc,GACdC,YAAa,IAGdpB,QAAS,GAETqB,kBAAkB,IAGnBpL,MAAO,CACNuK,UAAAA,CAAYc,GACJA,IACNpN,KAAKuM,YAAmB,EACxBvM,KAAKwM,WAAmB,EACxBxM,KAAKyM,iBAAmB,EACxBzM,KAAK0M,cAAmB,EACxB1M,KAAKmN,kBAAmB,EAExBnN,KAAK2M,mBAAqB,aAE1B3M,KAAK6M,eAAeC,KAAe,GACnC9M,KAAK6M,eAAeE,GAAe,GACnC/M,KAAK6M,eAAeG,KAAe,GACnChN,KAAK6M,eAAepH,QAAe,GACnCzF,KAAK6M,eAAeI,aAAe,GACnCjN,KAAK6M,eAAeK,YAAe,GAEnClN,KAAK8I,MAAO,iBAAkB9I,KAAK0L,MAErC,GAKD5L,SAAU,CACTuN,aAAAA,GASC,MAAO,CACNpL,QAPIjC,KAAKsM,WACC,QAEA,OAMZ,EAEAgB,kBAAAA,GACC,MAAO,CACNrL,QAASjC,KAAKmN,iBAAmB,QAAU,OAE7C,GAGDlN,QAAS,CACRsN,WAAAA,CAAYnL,EAAGoL,GACdpL,EAAEE,iBAEFtC,KAAKyN,UAAW,KACfzN,KAAKsM,YAAa,EAEb,iBAAmBkB,EACnB,eAAiBA,GACpBxN,KAAKyN,UAAU,KACdzN,KAAK0N,WAAWF,KAIlBxN,KAAK8L,QAAU9L,KAAK0L,KAAKI,QAE1B9L,KAAKwN,IAAS,IAEb7K,KAAM,OAGT,EAEAgL,YAAAA,CAAcvL,GACbA,EAAEE,iBAEFtC,KAAKsM,YAAa,CACnB,EAEAoB,UAAAA,CAAYF,GAEX,OADAxN,KAAK4M,iBAAkB,EAChBnK,MAAMC,IAAK,cAAe,CAChC+G,OAAQ,CACPlF,GAAIvE,KAAK0L,KAAKnH,GACdpG,KAAMqP,KAEJ7K,KAAMC,IAET,GADA5C,KAAK4M,iBAAkB,EAClB,oBAAsBY,EAC1BxN,KAAK2M,mBAAqB/J,EAAS9D,KAAK8O,QAAQjB,wBAC1C,GAAK,cAAgBa,EAAQ,CACnC,IAAII,EAAUhL,EAAS9D,KAAK8O,QAE5B5N,KAAK6M,eAAeC,KAAec,EAAQC,YAC3C7N,KAAK6M,eAAeE,GAAea,EAAQE,UAC3C9N,KAAK6M,eAAeG,KAAeY,EAAQG,KAC3C/N,KAAK6M,eAAepH,QAAemI,EAAQI,iBAC3ChO,KAAK6M,eAAeI,aAAeW,EAAQK,cAC3CjO,KAAK6M,eAAeK,YAAeU,EAAQM,OAE5C,CACAlO,KAAMwN,IAAU,GAElB,EAEAW,WAAAA,CAAa/L,GACZA,EAAEE,iBAEFG,MAAM6B,KAAM,eAAgB,CAC3BC,GAAIvE,KAAK0L,KAAKnH,GACduH,QAAS9L,KAAK8L,UAEbnJ,KAAMC,IACN5C,KAAKsM,YAAa,EAElBtM,KAAK8I,MAAO,kBAAmBlG,EAAS9D,KAAK8O,UAEhD,EAEAQ,cAAAA,CAAgB1C,GACf1L,KAAKmN,kBAAqBnN,KAAKmN,gBAChC,GAGDpK,OAAAA,GAECC,SAASC,KAAKC,iBAAkB,QAAW0I,IACnCA,EAAMzI,OAAOC,QAAS,4BAA8BpD,KAAKoM,aAC/DpM,KAAKmN,kBAAmB,IAG3B,GCnUD,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+CDN1DhO,EAAAA,EAAAA,oBA6JM,OA7JApB,OAAK6I,EAAAA,EAAAA,gBAAA,mDAAqDjH,EAAAyM,c,EAC/D7M,EAAAA,EAAAA,oBAsDM,OAtDDxB,MAAM,oCAAqC2C,OAAKa,EAAAA,EAAAA,gBAAEjB,EAAAgN,qB,EACtD/N,EAAAA,EAAAA,oBAYM,MAZNH,GAYM,EAXLG,EAAAA,EAAAA,oBAUI,KATFgE,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAAiN,YAAanL,EAAG,cAC7B4B,KAAK,K,cAELzE,EAAAA,EAAAA,oBAII,WAHHA,EAAAA,EAAAA,oBAEM,OAFD2F,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,EACjE/F,EAAAA,EAAAA,oBAA64B,QAAv4BgG,EAAE,q3BAAq3BF,KAAK,gB,0BAEh4B,KACJlB,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAKc,OAAO8L,MAAI,QAGrB9O,EAAAA,EAAAA,oBASM,MATNC,GASM,EARLD,EAAAA,EAAAA,oBAOI,KAPDyE,KAAK,IAAKT,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAAiN,YAAanL,EAAG,kB,cACxC7C,EAAAA,EAAAA,oBAII,WAHHA,EAAAA,EAAAA,oBAEM,OAFD2F,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,EACjE/F,EAAAA,EAAAA,oBAAgH,QAA1GgG,EAAE,wFAAwFF,KAAK,gB,0BAEnG,KACJlB,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAKc,OAAO+L,QAAM,QAGvB/O,EAAAA,EAAAA,oBAmBM,MAnBNE,GAmBM,EAlBLF,EAAAA,EAAAA,oBAiBI,KAhBFgE,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAAiN,YAAanL,EAAG,oBAC7B4B,KAAK,K,i4DAaD,KACJG,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAKc,OAAOgM,YAAU,O,WAGH5O,EAAA+L,KAAKK,S,kBAA7B5M,EAAAA,EAAAA,oBASM,MATNS,GASM,EARLL,EAAAA,EAAAA,oBAOI,KAPAgE,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAAiN,YAAanL,EAAG,eAAgB4B,KAAK,K,gBACpDzE,EAAAA,EAAAA,oBAII,WAHHA,EAAAA,EAAAA,oBAEM,OAFD2F,MAAM,KAAKC,OAAO,KAAKC,QAAQ,YAAYC,KAAK,OAAOC,MAAM,8B,EACjE/F,EAAAA,EAAAA,oBAAoK,QAA9JgG,EAAE,4IAA4IF,KAAK,gB,0BAEvJ,KACJlB,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAKc,OAAOqL,SAAO,S,uCAKkBpK,EAAA8I,a,kBAA3CnN,EAAAA,EAAAA,oBA4FM,MA5FN4F,GA4FM,EA3FLxF,EAAAA,EAAAA,oBA0FM,MA1FNyF,GA0FM,EAxFLzF,EAAAA,EAAAA,oBAA2E,KAAxExB,MAAM,yBAA0BwF,QAAKyE,EAAA,KAAAA,EAAA,OAAAwG,IAAElO,EAAAqN,cAAArN,EAAAqN,gBAAAa,IAAcxK,KAAK,KAAI,KAEtDR,EAAAoJ,kB,kBAAXzN,EAAAA,EAAAA,oBAEM,MAFN8F,GAEM,IAAA+C,EAAA,MAAAA,EAAA,MADLzI,EAAAA,EAAAA,oBAAqB,WAAhB,cAAU,S,mCAGLiE,EAAA+I,a,kBAAXpN,EAAAA,EAAAA,oBAEM,MAAAqG,IAAArB,EAAAA,EAAAA,iBADFxE,EAAA+L,KAAK+C,OAAK,K,mCAGPjL,EAAAiJ,kB,kBADPtN,EAAAA,EAAAA,oBAIM,MAAAuG,IAAAvB,EAAAA,EAAAA,iBADFX,EAAAmJ,oBAAkB,K,mCAEXnJ,EAAAgJ,Y,kBAAXrN,EAAAA,EAAAA,oBAyDM,MAAAmI,GAAA,EAvDL/H,EAAAA,EAAAA,oBAqDM,MArDNqG,GAqDM,EApDLrG,EAAAA,EAAAA,oBA2CQ,eA1CPA,EAAAA,EAAAA,oBAyCe,eAxCRA,EAAAA,EAAAA,oBAOK,YANHA,EAAAA,EAAAA,oBAIK,YAHHA,EAAAA,EAAAA,oBAES,eAAA4E,EAAAA,EAAAA,iBADJX,EAAA/B,KAAKoK,QAAQiB,MAAO,KACzB,MAEFvN,EAAAA,EAAAA,oBAAsC,MAAlCmP,UAAQlL,EAAAqJ,eAAeC,M,cAE7BvN,EAAAA,EAAAA,oBAOK,YANHA,EAAAA,EAAAA,oBAIK,YAHHA,EAAAA,EAAAA,oBAES,eAAA4E,EAAAA,EAAAA,iBADJX,EAAA/B,KAAKoK,QAAQkB,IAAK,KACvB,MAEFxN,EAAAA,EAAAA,oBAAoC,MAAhCmP,UAAQlL,EAAAqJ,eAAeE,I,cAE7BxN,EAAAA,EAAAA,oBAOK,YANHA,EAAAA,EAAAA,oBAIK,YAHHA,EAAAA,EAAAA,oBAES,eAAA4E,EAAAA,EAAAA,iBADJX,EAAA/B,KAAKoK,QAAQmB,MAAO,KACzB,MAEFzN,EAAAA,EAAAA,oBAAsC,MAAlCmP,UAAQlL,EAAAqJ,eAAeG,M,cAE7BzN,EAAAA,EAAAA,oBAOK,YANHA,EAAAA,EAAAA,oBAIK,YAHHA,EAAAA,EAAAA,oBAES,eAAA4E,EAAAA,EAAAA,iBADJX,EAAA/B,KAAKoK,QAAQpG,SAAU,KAC5B,MAEFlG,EAAAA,EAAAA,oBAAyC,MAArCmP,UAAQlL,EAAAqJ,eAAepH,S,cAE7BlG,EAAAA,EAAAA,oBAOK,YANHA,EAAAA,EAAAA,oBAIK,YAHHA,EAAAA,EAAAA,oBAES,eAAA4E,EAAAA,EAAAA,iBADJX,EAAA/B,KAAKoK,QAAQ8C,aAAc,KAChC,MAEFpP,EAAAA,EAAAA,oBAA8C,MAA1CmP,UAAQlL,EAAAqJ,eAAeI,c,gCAIrC1N,EAAAA,EAAAA,oBAAI,qBACJA,EAAAA,EAAAA,oBAMM,aALLA,EAAAA,EAAAA,oBAIU,UAHT2F,MAAM,OACNC,OAAO,QACN9E,IAAKmD,EAAAqJ,eAAeK,a,sDAOd1J,EAAAkJ,e,kBAAXvN,EAAAA,EAAAA,oBAaM,MAAAmL,GAAA,EAZL/K,EAAAA,EAAAA,oBAWM,MAXNgL,GAWM,EATLhL,EAAAA,EAAAA,oBAQM,MARNiL,GAQM,EAPLjL,EAAAA,EAAAA,oBAA8D,QAA9DqP,IAA8DzK,EAAAA,EAAAA,iBAAxCX,EAAA/B,KAAK0M,YAAYU,cAAY,I,qBACnDtP,EAAAA,EAAAA,oBAA8E,Y,qCAA3DiE,EAAAsI,QAAOgD,GAAE/Q,MAAM,iB,qBAAkB4B,EAAA+L,KAAKI,SAAO,M,cAA7CtI,EAAAsI,YACnBvM,EAAAA,EAAAA,oBAEI,IAFJwP,GAEI,EADHxP,EAAAA,EAAAA,oBAAmD,eAAA4E,EAAAA,EAAAA,iBAAxCX,EAAA/B,KAAK0M,YAAYlI,aAAW,MAGxC1G,EAAAA,EAAAA,oBAA8G,UAArGgE,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAA6N,YAAa/L,IAAKrE,MAAM,6B,qBAA8ByF,EAAA/B,KAAK0M,YAAY9L,QAAM,W,6EAQvG9C,EAAAA,EAAAA,oBAKM,OALAgE,QAAKyE,EAAA,KAAAA,EAAA,OAAQ1H,EAAA8N,eAAgBzO,EAAA+L,OAAQ3N,MAAM,sB,oBAEhDwB,EAAAA,EAAAA,oBAAuC,QAAjCxB,MAAM,qBAAmB,UAC/BwB,EAAAA,EAAAA,oBAAuC,QAAjCxB,MAAM,qBAAmB,UAC/BwB,EAAAA,EAAAA,oBAAuC,QAAjCxB,MAAM,qBAAmB,c,KCrJ0C,CAAC,YAAY,qB,ICJjFA,MAAM,U,UAcgBA,MAAM,Q,qBAMzBA,MAAM,oB,IAGNA,MAAM,iB,2BAebA,MAAM,UA+BV,IACCC,KAAM,sBAENC,MAAO,CACNyJ,mBAAoB,CACnBvJ,KAAMQ,OACNN,QAAS,aAIXS,KAAQC,IAAC,CACN0C,KAAMC,qBAAqBD,KAAKuN,YAClChQ,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACtB+P,QAASvN,qBAAqBwN,QAC9BC,WAAY,GACZC,SAAU,CACT,CACChL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,wBACLkP,eAAe,GAEhB,CACCjL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,yBACLkP,eAAe,GAEhB,CACCjL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,mBACLkP,eAAe,GAEhB,CACCjL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,mBACLkP,eAAe,GAGhB,CACCjL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,sBACLkP,eAAe,GAEhB,CACCjL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,mBACLkP,eAAe,GAEhB,CACCjL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,sBACLkP,eAAe,GAEhB,CACCjL,MAAO1C,qBAAqBD,KAAKuN,YAAY3H,KAAK,GAClDlH,IAAK,oBACLkP,eAAe,IAIjBC,YAAa,aAAevQ,EAAG2I,qBAGhCzH,QAAS,CACRsP,aAActE,GACNA,EAAKuE,QAAS,QAAS,QAG/BC,UAAAA,GACCzP,KAAKsP,aAAgBtP,KAAKsP,YAC1B,IAAII,EAAoB1P,KAAKsP,YAAc,WAAa,WAExD7M,MAAM6B,KAAM,uBAAwB,CACnCoL,kBAAmBA,IAElB/M,KAAMC,MAET,GAGD9C,SAAU,CACT6P,sBAAAA,GACC,MAAO,CACN,KAAQ3P,KAAKiP,QACb,gBAAgB,EAElB,GAGDlM,OAAAA,GACC/C,KAAKiP,QAAU,MAAQjP,KAAKiP,QAE5BjP,KAAKmP,WAAanP,KAAKiP,QAAU,yHAA2H,wGAC7J,GC5JD,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,4IDN1D9P,EAAAA,EAAAA,oBAmEM,OAnEApB,OAAK6I,EAAAA,EAAAA,gBAAEtG,EAAAqP,wBAAyBjP,OAAKa,EAAAA,EAAAA,gBAAIiC,EAAA8L,YAAW,qB,EACzD/P,EAAAA,EAAAA,oBAiEM,OAjEDxB,MAAM,YAAa2C,OAAKa,EAAAA,EAAAA,gBAAIiC,EAAA8L,YAAW,iB,EAC3C/P,EAAAA,EAAAA,oBAQM,MARNH,GAQM,EAPLG,EAAAA,EAAAA,oBAGK,YAFJF,EAAAA,EAAAA,aAAgJe,EAAA,CAAjIM,MAAA,iDAAkD3C,MAAM,iBAAkBsC,IAAKmD,EAAAxE,eAAiB,+B,sCAAiC,KAChJmF,EAAAA,EAAAA,iBAAGX,EAAA/B,KAAK2C,OAAK,MAEd7E,EAAAA,EAAAA,oBAEI,UAAA4E,EAAAA,EAAAA,iBADAX,EAAA/B,KAAKwE,aAAW,MAIrB5G,EAAAA,EAAAA,aAoBauQ,EAAAA,WAAA,CAnBZ5R,KAAK,OACL,qBAAmB,oB,uBAGpB,IAmCA,CApCcwF,EAAA8L,a,uDAAbnQ,EAAAA,EAAAA,oBAeM,MAfNK,GAeM,G,oBAbLL,EAAAA,EAAAA,oBAWMkE,EAAAA,SAAA,MAAAC,EAAAA,EAAAA,YAXuCE,EAAA4L,SAAXS,K,kBAAlC1Q,EAAAA,EAAAA,oBAWM,OAXDpB,MAAM,gBAA6C+G,IAAK+K,EAAQzL,O,CACzDyL,EAAQR,gB,kBAAnBlQ,EAAAA,EAAAA,oBAEM,MAAAM,GAAA,EADLJ,EAAAA,EAAAA,aAAwEe,EAAA,CAAxDC,IAAKmD,EAAAxE,eAAiB,iBAAmB6Q,EAAQ1P,K,uCAElEhB,EAAAA,EAAAA,oBAEM,MAFNS,GAEM,EADLP,EAAAA,EAAAA,aAAwEe,EAAA,CAAxDC,IAAKmD,EAAAxE,eAAiB,iBAAmB6Q,EAAQ1P,K,oBAElEZ,EAAAA,EAAAA,oBAGM,MAHNwF,GAGM,EAFLxF,EAAAA,EAAAA,oBACI,KADDmP,UAAQpO,EAAAiP,aAAcM,EAAQzL,Q,mCAQrC/E,EAAAA,EAAAA,aAgBauQ,EAAAA,WAAA,CAfZ5R,KAAK,OACL,qBAAmB,oB,uBAsBV,IAcM,CAjCPwF,EAAA8L,a,uDADRnQ,EAAAA,EAAAA,oBAWK,MAXL8F,GAWK,EAPL5F,EAAAA,EAAAA,aAMmByH,EAAA,CALlB3I,KAAK,UACJ6F,KAAMR,EAAA2L,WACPhM,OAAO,U,uBAEP,IAAiB,E,2CAAdK,EAAA/B,KAAKY,QAAS,MAClB,K,4BAMMmB,EAAA8L,c,kBAFPnQ,EAAAA,EAAAA,oBAMM,O,MALLpB,MAAM,wBAELwF,QAAKyE,EAAA,KAAAA,EAAA,OAAAwG,IAAElO,EAAAmP,YAAAnP,EAAAmP,cAAAjB,K,kBAERjP,EAAAA,EAAAA,oBAAyD,QAAnDxB,MAAM,uCAAqC,gB,kBAElDoB,EAAAA,EAAAA,oBAMM,O,MALLpB,MAAM,wBAELwF,QAAKyE,EAAA,KAAAA,EAAA,OAAAwG,IAAElO,EAAAmP,YAAAnP,EAAAmP,cAAAjB,K,kBAERjP,EAAAA,EAAAA,oBAAuD,QAAjDxB,MAAM,qCAAmC,e,SC1DyB,CAAC,YAAY,qB,ICNnFA,MAAM,iB,IACLA,MAAM,U,IACLA,MAAM,c,IAGNA,MAAM,e,IACPiG,KAAK,4G,qBAoBsBjG,MAAM,Q,IAC/BA,MAAM,WAgBf,IACCC,KAAM,gBAENc,KAAQC,IAAC,CACN0C,KAAMC,qBAAqBD,KAAKqO,cAClC9Q,eAAgBD,EAAGE,QAAQD,eAC3BE,UAAWH,EAAGE,QAAQC,UACtB4Q,cAAepO,qBAAqBD,KAAKqO,cAAcA,cACvDC,oBAAoB,IAGrB9P,QAAS,CACR+P,gBAAAA,CAAkB5N,GACjBA,EAAEE,iBACYU,SAASiN,cAAe,oBAChCtH,UAAUuH,OAAQ,YAExBlQ,KAAK+P,oBAAuB/P,KAAK+P,kBAClC,ICrDF,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,yGDN1D5Q,EAAAA,EAAAA,oBAuCM,MAvCNC,GAuCM,EAtCLG,EAAAA,EAAAA,oBAmBM,MAnBNC,GAmBM,EAlBLD,EAAAA,EAAAA,oBAEM,MAFNE,GAEM,EADLF,EAAAA,EAAAA,oBAAyB,WAAA4E,EAAAA,EAAAA,iBAAlBX,EAAA/B,KAAK2C,OAAK,MAElB7E,EAAAA,EAAAA,oBAcM,MAdNK,GAcM,EAbLL,EAAAA,EAAAA,oBAAyI,IAAzIwF,IAAyIZ,EAAAA,EAAAA,iBAAnBX,EAAA/B,KAAK0O,SAAO,IAElI5Q,EAAAA,EAAAA,oBAUI,KATHyE,KAAK,IACJT,QAAKyE,EAAA,KAAAA,EAAA,GAAE5F,GAAK9B,EAAA0P,iBAAkB5N,IAC/B1B,MAAA,oD,EAEAnB,EAAAA,EAAAA,oBAIC,OAHAxB,MAAM,2BACN2C,MAAA,uBACCL,IAAKmD,EAAAxE,eAAiB,8B,kBAM3BK,EAAAA,EAAAA,aAgBauQ,EAAAA,WAAA,CAfZ5R,KAAK,OACL,qBAAmB,oB,uBAGtB,IA0BC,CA3BawF,EAAAuM,qB,kBAAX5Q,EAAAA,EAAAA,oBAWM,MAXN8F,GAWM,EAVL1F,EAAAA,EAAAA,oBASM,MATNiG,GASM,G,oBARLrG,EAAAA,EAAAA,oBAO2BkE,EAAAA,SAAA,MAAAC,EAAAA,EAAAA,YANZE,EAAAsM,cAAPM,K,kBADR7J,EAAAA,EAAAA,aAO2B8J,EAAA,CANIvL,IAAKsL,EAAIhM,MACtCA,MAAOgM,EAAIhM,MACX,aAAYgM,EAAIE,MAChB,YAAWF,EAAIG,UACf,iBAAgB/M,EAAAxE,eAChB,YAAWwE,EAAAtE,W,qIC5B0D,CAAC,YAAY,qB,ICNnFnB,MAAM,iB,IAGNA,MAAM,qB,IAEHA,MAAM,Y,IACL2C,MAAA,6B,eAMAA,MAAA,iE,wBAiBV,IACC1C,KAAM,wBAENC,MAAO,CACNmG,MAAO,CACNjG,KAAMQ,OACN8B,UAAU,GAEX+P,UAAW,CACVrS,KAAMqD,MACNf,UAAU,GAEXgQ,SAAU,CACTtS,KAAMQ,OACN8B,UAAU,GAEXiQ,aAAc,CACbvS,KAAMQ,OACN8B,UAAU,GAEXkQ,SAAU,CACTxS,KAAMQ,OACN8B,UAAU,IAIZ3B,KAAQC,IAAC,CACRC,eAAgBD,EAAG2R,aACnBxR,UAAWH,EAAG4R,SACZlP,KAAMC,qBAAqBD,KAAKqO,iBClDpC,IAFiC,OAAgB,GAAQ,CAAC,CAAC,S,+CDN1D3Q,EAAAA,EAAAA,oBAyBM,MAzBNC,GAyBM,EAxBLG,EAAAA,EAAAA,oBAAoB,WAAA4E,EAAAA,EAAAA,iBAAbxE,EAAAyE,OAAK,IAEZ7E,EAAAA,EAAAA,oBAmBK,KAnBLC,GAmBK,G,oBAlBJL,EAAAA,EAAAA,oBAiBKkE,EAAAA,SAAA,MAAAC,EAAAA,EAAAA,YAjBc3D,EAAA6Q,UAARjJ,K,kBAAXpI,EAAAA,EAAAA,oBAiBK,MAjB0B2F,IAAKyC,EAAKnD,O,EACxC7E,EAAAA,EAAAA,oBAeM,MAfNE,GAeM,EAdLF,EAAAA,EAAAA,oBAKM,MALNK,GAKM,EAJLL,EAAAA,EAAAA,oBAGC,OAFCc,IAAKmD,EAAAxE,eAAiB,yBACvB0B,MAAA,+C,cAGFnB,EAAAA,EAAAA,oBAOM,MAPNyF,GAOM,EANLzF,EAAAA,EAAAA,oBAKI,KAJFyE,KAAMuD,EAAKvD,KACZtD,MAAA,6B,qBAEG6G,EAAKnD,OAAK,EAAAa,Y,SAOlB1F,EAAAA,EAAAA,oBAAkE,KAA/DxB,MAAM,mBAAoBiG,KAAMrE,EAAA8Q,W,qBAAajN,EAAA/B,KAAKmP,MAAO,KAAE,EAAApL,K,GClBY,CAAC,YAAY,qBCNzF,IAAI,IAAEqL,GAAG,GAAEC,GAAIrO,MAAKA,IAAKgC,QACrB,KAAEhD,IAASqP,IACX,UAAEC,IAAcF,GA0BpB,MAAMG,GAAiBD,GAAW,CAE9BE,MAAOA,KAAA,CACHjS,eAAgB0C,qBAAqB1C,eACrCE,UAAWwC,qBAAqBxC,YAGpCJ,KAAMA,KAAA,CAAU,GAEhBiD,MAAO,CAAC,EAERjC,SAAU,CAAC,EAEXG,QAAS,CAAC,EAEV8C,OAAAA,GACA,IAKJiO,GAAeE,IAAK,CAChBC,OAAAA,CAASC,EAAKC,GACVD,EAAIE,QAAS,OAAQD,EACzB,GACD5P,IAGHuP,GAAeO,UAAW,wBAAyBC,GACnDR,GAAeO,UAAW,mBAAoBE,GAC9CT,GAAeO,UAAW,gBAAiBG,GAC3CV,GAAeO,UAAW,qBAAsBI,GAChDX,GAAeO,UAAW,0BAA2BK,GACrDZ,GAAeO,UAAW,6BAA8BM,GACxDb,GAAeO,UAAW,oBAAqBO,IAC/Cd,GAAeO,UAAW,mBAAoBQ,IAC9Cf,GAAeO,UAAW,gBAAiBS,IAC3ChB,GAAeO,UAAW,mBAAoBU,IAC9CjB,GAAeO,UAAW,sBAAuBW,IACjDlB,GAAeO,UAAW,0BAA2BY,IACrDnB,GAAeO,UAAW,4BAA6Ba,IACvDpB,GAAeO,UAAW,iBAAkBc,IAC5CrB,GAAeO,UAAW,oBAAqBe,IAC/CtB,GAAeO,UAAW,mBAAoBgB,IAC9CvB,GAAeO,UAAW,yBAA0BiB,IACpDxB,GAAeO,UAAW,4BAA6BkB,IACvDzB,GAAeO,UAAW,yBAA0BmB,IACpD1B,GAAeO,UAAW,kBAAmBoB,IAC7C3B,GAAeO,UAAW,0BAA2BqB,IAGrD5B,GACK6B,MAAO,kBACZpO,OACKqO,gBAAkB9B,E,2BC/EvB+B,EAAQ,EAAU,CAACC,EAAK/U,KACpB,MAAMkF,EAAS6P,EAAIC,WAAaD,EAChC,IAAK,MAAOlO,EAAKsI,KAAQnP,EACrBkF,EAAO2B,GAAOsI,EAElB,OAAOjK,E,i4GCHX,SAAS,EAAQ+P,GACf,MAAMC,EAAsBxS,OAAOyS,OAAO,MAC1C,IAAK,MAAMtO,KAAOoO,EAAIlS,MAAM,KAAMmS,EAAIrO,GAAO,EAC7C,OAAQsI,GAAQA,KAAO+F,CACzB,C,40GAEA,MAAME,EAA4E,CAAC,EAC7EC,EAA4E,GAC5E,EAAO,OAEPC,EAAK,KAAM,EACXC,EAAQ1O,GAA8B,MAAtBA,EAAI2O,WAAW,IAAoC,MAAtB3O,EAAI2O,WAAW,KACjE3O,EAAI2O,WAAW,GAAK,KAAO3O,EAAI2O,WAAW,GAAK,IAC1CC,EAAmB5O,GAAQA,EAAI6O,WAAW,aAC1C,EAAShT,OAAOiT,OAChBhL,EAAS,CAACiL,EAAKC,KACnB,MAAMC,EAAIF,EAAIzS,QAAQ0S,GAClBC,GAAK,GACPF,EAAIhP,OAAOkP,EAAG,IAGZ,EAAiBpT,OAAOqT,UAAUC,eAClCC,EAAS,CAAC9G,EAAKtI,IAAQ,EAAeqP,KAAK/G,EAAKtI,GAChD,EAAUtD,MAAM4S,QAChBC,EAASjH,GAA8B,iBAAtBkH,EAAalH,GAC9BmH,EAASnH,GAA8B,iBAAtBkH,EAAalH,GAC9BoH,EAAUpH,GAA8B,kBAAtBkH,EAAalH,GAE/B,EAAcA,GAAuB,mBAARA,EAC7B,EAAYA,GAAuB,iBAARA,EAC3BqH,EAAYrH,GAAuB,iBAARA,EAC3B,EAAYA,GAAgB,OAARA,GAA+B,iBAARA,EAC3CsH,EAAatH,IACT,EAASA,IAAQ,EAAWA,KAAS,EAAWA,EAAIzK,OAAS,EAAWyK,EAAIuH,OAEhFC,EAAiBjU,OAAOqT,UAAUa,SAClCP,EAAgB9G,GAAUoH,EAAeT,KAAK3G,GAC9C,EAAaA,GACV8G,EAAa9G,GAAOsH,MAAM,GAAI,GAEjCC,EAAiB3H,GAA8B,oBAAtBkH,EAAalH,GACtC4H,EAAgBlQ,GAAQ,EAASA,IAAgB,QAARA,GAA4B,MAAXA,EAAI,IAAc,GAAKmQ,SAASnQ,EAAK,MAAQA,EACvGoQ,EAAiC,EAErC,uIAEI,EAAqC,EACzC,6EAEIC,EAAuBC,IAC3B,MAAMC,EAAwB1U,OAAOyS,OAAO,MAC5C,OAASF,GACKmC,EAAMnC,KACHmC,EAAMnC,GAAOkC,EAAGlC,KAG7BoC,EAAa,OACb,EAAWH,EACdjC,GACQA,EAAI1D,QAAQ8F,EAAaC,GAAMA,EAAET,MAAM,GAAGU,gBAG/CC,EAAc,aACdC,EAAYP,EACfjC,GAAQA,EAAI1D,QAAQiG,EAAa,OAAOE,eAErC,EAAaR,EAAqBjC,GAC/BA,EAAI0C,OAAO,GAAGJ,cAAgBtC,EAAI4B,MAAM,IAE3Ce,EAAeV,EAClBjC,GACWA,EAAM,KAAK,EAAWA,KAAS,IAIvC4C,EAAa,CAACtI,EAAOuI,KAAcpV,OAAOqV,GAAGxI,EAAOuI,GACpDE,EAAiB,CAACC,KAAQC,KAC9B,IAAK,IAAIpC,EAAI,EAAGA,EAAImC,EAAIzS,OAAQsQ,IAC9BmC,EAAInC,MAAMoC,IAGRC,EAAM,CAACC,EAAKvR,EAAK0I,EAAO8I,GAAW,KACvC3V,OAAO4V,eAAeF,EAAKvR,EAAK,CAC9B0R,cAAc,EACdC,YAAY,EACZH,WACA9I,WAGEkJ,EAAiBtJ,IACrB,MAAMuJ,EAAIC,WAAWxJ,GACrB,OAAOyJ,MAAMF,GAAKvJ,EAAMuJ,GAEpBG,EAAY1J,IAChB,MAAMuJ,EAAI,EAASvJ,GAAO2J,OAAO3J,GAAO4J,IACxC,OAAOH,MAAMF,GAAKvJ,EAAMuJ,GAE1B,IAAIM,EACJ,MAAMC,EAAgB,IACbD,IAAgBA,EAAoC,oBAAfE,WAA6BA,WAA6B,oBAATC,KAAuBA,KAAyB,oBAAX3S,OAAyBA,YAA2B,IAAX,EAAA4S,EAAyB,EAAAA,EAAS,CAAC,GAoG1MC,EAAoC,EADlB,yNA8CxB,SAAS,EAAe9J,GACtB,GAAI,EAAQA,GAAQ,CAClB,MAAM+J,EAAM,CAAC,EACb,IAAK,IAAIxD,EAAI,EAAGA,EAAIvG,EAAM/J,OAAQsQ,IAAK,CACrC,MAAMrI,EAAO8B,EAAMuG,GACbyD,EAAa,EAAS9L,GAAQ+L,EAAiB/L,GAAQ,EAAeA,GAC5E,GAAI8L,EACF,IAAK,MAAM1S,KAAO0S,EAChBD,EAAIzS,GAAO0S,EAAW1S,EAG5B,CACA,OAAOyS,CACT,CAAO,GAAI,EAAS/J,IAAU,EAASA,GACrC,OAAOA,CAEX,CACA,MAAMkK,EAAkB,gBAClBC,EAAsB,UACtBC,EAAiB,iBACvB,SAASH,EAAiBI,GACxB,MAAMC,EAAM,CAAC,EAOb,OANAD,EAAQrI,QAAQoI,EAAgB,IAAI5W,MAAM0W,GAAiBhP,QAASgD,IAClE,GAAIA,EAAM,CACR,MAAMqM,EAAMrM,EAAK1K,MAAM2W,GACvBI,EAAItU,OAAS,IAAMqU,EAAIC,EAAI,GAAGC,QAAUD,EAAI,GAAGC,OACjD,IAEKF,CACT,CAcA,SAAS,EAAetK,GACtB,IAAI+J,EAAM,GACV,GAAI,EAAS/J,GACX+J,EAAM/J,OACD,GAAI,EAAQA,GACjB,IAAK,IAAIuG,EAAI,EAAGA,EAAIvG,EAAM/J,OAAQsQ,IAAK,CACrC,MAAMyD,EAAa,EAAehK,EAAMuG,IACpCyD,IACFD,GAAOC,EAAa,IAExB,MACK,GAAI,EAAShK,GAClB,IAAK,MAAMxP,KAAQwP,EACbA,EAAMxP,KACRuZ,GAAOvZ,EAAO,KAIpB,OAAOuZ,EAAIS,MACb,CACA,SAASC,EAAeha,GACtB,IAAKA,EAAO,OAAO,KACnB,IAAMF,MAAOma,EAAK,MAAExX,GAAUzC,EAO9B,OANIia,IAAU,EAASA,KACrBja,EAAMF,MAAQ,EAAema,IAE3BxX,IACFzC,EAAMyC,MAAQ,EAAeA,IAExBzC,CACT,CAEA,MAIM,EAA4B,EAJhB,klBAKZ,GAA2B,EAJhB,qpBAKX,GAA8B,EAJlB,sVAKZka,GAA4B,EAJhB,wEAOZC,GAAuC,EADjB,+EAK5B,SAAS,GAAmB5K,GAC1B,QAASA,GAAmB,KAAVA,CACpB,CA+FA,SAAS6K,GAAWC,EAAGC,GACrB,GAAID,IAAMC,EAAG,OAAO,EACpB,IAAIC,EAAahE,EAAO8D,GACpBG,EAAajE,EAAO+D,GACxB,GAAIC,GAAcC,EAChB,SAAOD,IAAcC,IAAaH,EAAEI,YAAcH,EAAEG,UAItD,GAFAF,EAAa/D,EAAS6D,GACtBG,EAAahE,EAAS8D,GAClBC,GAAcC,EAChB,OAAOH,IAAMC,EAIf,GAFAC,EAAa,EAAQF,GACrBG,EAAa,EAAQF,GACjBC,GAAcC,EAChB,SAAOD,IAAcC,IAvBzB,SAA4BH,EAAGC,GAC7B,GAAID,EAAE7U,SAAW8U,EAAE9U,OAAQ,OAAO,EAClC,IAAIkV,GAAQ,EACZ,IAAK,IAAI5E,EAAI,EAAG4E,GAAS5E,EAAIuE,EAAE7U,OAAQsQ,IACrC4E,EAAQN,GAAWC,EAAEvE,GAAIwE,EAAExE,IAE7B,OAAO4E,CACT,CAgBsCC,CAAmBN,EAAGC,GAI1D,GAFAC,EAAa,EAASF,GACtBG,EAAa,EAASF,GAClBC,GAAcC,EAAY,CAC5B,IAAKD,IAAeC,EAClB,OAAO,EAIT,GAFmB9X,OAAOkY,KAAKP,GAAG7U,SACf9C,OAAOkY,KAAKN,GAAG9U,OAEhC,OAAO,EAET,IAAK,MAAMqB,KAAOwT,EAAG,CACnB,MAAMQ,EAAUR,EAAErE,eAAenP,GAC3BiU,EAAUR,EAAEtE,eAAenP,GACjC,GAAIgU,IAAYC,IAAYD,GAAWC,IAAYV,GAAWC,EAAExT,GAAMyT,EAAEzT,IACtE,OAAO,CAEX,CACF,CACA,OAAOnG,OAAO2Z,KAAO3Z,OAAO4Z,EAC9B,CACA,SAASS,GAAanF,EAAKzG,GACzB,OAAOyG,EAAIoF,UAAWvN,GAAS2M,GAAW3M,EAAM0B,GAClD,CAEA,MAAM,GAASA,MACHA,IAA4B,IAArBA,EAAe,WAE5B8L,GAAmB9L,GAChB,EAASA,GAAOA,EAAa,MAAPA,EAAc,GAAK,EAAQA,IAAQ,EAASA,KAASA,EAAIyH,WAAaD,IAAmB,EAAWxH,EAAIyH,WAAa,GAAMzH,GAAO8L,GAAgB9L,EAAII,OAAS2L,KAAKC,UAAUhM,EAAKiM,GAAU,GAAK1a,OAAOyO,GAElOiM,GAAW,CAACC,EAAMlM,IAClB,GAAMA,GACDiM,GAASC,EAAMlM,EAAII,OACjB6G,EAAMjH,GACR,CACL,CAAC,OAAOA,EAAImM,SAAU,IAAInM,EAAIoM,WAAWC,OACvC,CAACD,GAAU1U,EAAK4U,GAAO3F,KACrByF,EAAQG,GAAgB7U,EAAKiP,GAAK,OAAS2F,EACpCF,GAET,CAAC,IAGIjF,EAAMnH,GACR,CACL,CAAC,OAAOA,EAAImM,SAAU,IAAInM,EAAItK,UAAUqQ,IAAKyG,GAAMD,GAAgBC,KAE5DnF,EAASrH,GACXuM,GAAgBvM,IACd,EAASA,IAAS,EAAQA,IAAS2H,EAAc3H,GAGrDA,EAFEzO,OAAOyO,GAIZuM,GAAkB,CAACC,EAAG7F,EAAI,MAC9B,IAAI8F,EACJ,OAGEpF,EAASmF,GAAK,UAAkC,OAAvBC,EAAKD,EAAE3T,aAAuB4T,EAAK9F,KAAO6F,GAIvE,SAAS,GAAqBpM,GAC5B,OAAa,MAATA,EACK,UAEY,iBAAVA,EACQ,KAAVA,EAAe,IAAMA,GAET,iBAAVA,GAAuBuJ,OAAO+C,SAAStM,GAQ3C7O,OAAO6O,GAChB,CC1gBA,IAAIuM,GA8IAC,GA7IJ,MAAMC,GACJ,WAAAC,CAAYC,GAAW,GACrBna,KAAKma,SAAWA,EAIhBna,KAAKoa,SAAU,EAIfpa,KAAKqa,IAAM,EAIXra,KAAKsa,QAAU,GAIfta,KAAKua,SAAW,GAChBva,KAAKwa,WAAY,EACjBxa,KAAKya,OAASV,IACTI,GAAYJ,KACf/Z,KAAK4E,OAASmV,GAAkBW,SAAWX,GAAkBW,OAAS,KAAKC,KACzE3a,MACE,EAER,CACA,UAAI4a,GACF,OAAO5a,KAAKoa,OACd,CACA,KAAAS,GACE,GAAI7a,KAAKoa,QAAS,CAEhB,IAAIrG,EAAG+G,EACP,GAFA9a,KAAKwa,WAAY,EAEbxa,KAAK0a,OACP,IAAK3G,EAAI,EAAG+G,EAAI9a,KAAK0a,OAAOjX,OAAQsQ,EAAI+G,EAAG/G,IACzC/T,KAAK0a,OAAO3G,GAAG8G,QAGnB,IAAK9G,EAAI,EAAG+G,EAAI9a,KAAKsa,QAAQ7W,OAAQsQ,EAAI+G,EAAG/G,IAC1C/T,KAAKsa,QAAQvG,GAAG8G,OAEpB,CACF,CAIA,MAAAE,GACE,GAAI/a,KAAKoa,SACHpa,KAAKwa,UAAW,CAElB,IAAIzG,EAAG+G,EACP,GAFA9a,KAAKwa,WAAY,EAEbxa,KAAK0a,OACP,IAAK3G,EAAI,EAAG+G,EAAI9a,KAAK0a,OAAOjX,OAAQsQ,EAAI+G,EAAG/G,IACzC/T,KAAK0a,OAAO3G,GAAGgH,SAGnB,IAAKhH,EAAI,EAAG+G,EAAI9a,KAAKsa,QAAQ7W,OAAQsQ,EAAI+G,EAAG/G,IAC1C/T,KAAKsa,QAAQvG,GAAGgH,QAEpB,CAEJ,CACA,GAAAC,CAAI5F,GACF,GAAIpV,KAAKoa,QAAS,CAChB,MAAMa,EAAqBlB,GAC3B,IAEE,OADAA,GAAoB/Z,KACboV,GACT,CAAE,QACA2E,GAAoBkB,CACtB,CACF,CAGF,CAKA,EAAAC,GACqB,MAAblb,KAAKqa,MACTra,KAAKmb,UAAYpB,GACjBA,GAAoB/Z,KAExB,CAKA,GAAAob,GACMpb,KAAKqa,IAAM,GAAoB,MAAbra,KAAKqa,MACzBN,GAAoB/Z,KAAKmb,UACzBnb,KAAKmb,eAAY,EAErB,CACA,IAAAE,CAAKC,GACH,GAAItb,KAAKoa,QAAS,CAEhB,IAAIrG,EAAG+G,EACP,IAFA9a,KAAKoa,SAAU,EAEVrG,EAAI,EAAG+G,EAAI9a,KAAKsa,QAAQ7W,OAAQsQ,EAAI+G,EAAG/G,IAC1C/T,KAAKsa,QAAQvG,GAAGsH,OAGlB,IADArb,KAAKsa,QAAQ7W,OAAS,EACjBsQ,EAAI,EAAG+G,EAAI9a,KAAKua,SAAS9W,OAAQsQ,EAAI+G,EAAG/G,IAC3C/T,KAAKua,SAASxG,KAGhB,GADA/T,KAAKua,SAAS9W,OAAS,EACnBzD,KAAK0a,OAAQ,CACf,IAAK3G,EAAI,EAAG+G,EAAI9a,KAAK0a,OAAOjX,OAAQsQ,EAAI+G,EAAG/G,IACzC/T,KAAK0a,OAAO3G,GAAGsH,MAAK,GAEtBrb,KAAK0a,OAAOjX,OAAS,CACvB,CACA,IAAKzD,KAAKma,UAAYna,KAAKya,SAAWa,EAAY,CAChD,MAAMC,EAAOvb,KAAKya,OAAOC,OAAOc,MAC5BD,GAAQA,IAASvb,OACnBA,KAAKya,OAAOC,OAAO1a,KAAK4E,OAAS2W,EACjCA,EAAK3W,MAAQ5E,KAAK4E,MAEtB,CACA5E,KAAKya,YAAS,CAChB,CACF,EAEF,SAASgB,GAAYtB,GACnB,OAAO,IAAIF,GAAYE,EACzB,CACA,SAASuB,KACP,OAAO3B,EACT,CACA,SAAS4B,GAAevG,EAAIwG,GAAe,GACrC7B,IACFA,GAAkBQ,SAASI,KAAKvF,EAMpC,CAGA,MAkBMyG,GAAqC,IAAIC,QAC/C,MAAMC,GACJ,WAAA7B,CAAY9E,GACVpV,KAAKoV,GAAKA,EAIVpV,KAAKgc,UAAO,EAIZhc,KAAKic,cAAW,EAIhBjc,KAAKkc,MAAQ,EAIblc,KAAKmc,UAAO,EAIZnc,KAAKoc,aAAU,EACfpc,KAAKqc,eAAY,EACbtC,IAAqBA,GAAkBa,QACzCb,GAAkBO,QAAQK,KAAK3a,KAEnC,CACA,KAAA6a,GACE7a,KAAKkc,OAAS,EAChB,CACA,MAAAnB,GACmB,GAAb/a,KAAKkc,QACPlc,KAAKkc,QAAU,GACXL,GAAmBS,IAAItc,QACzB6b,GAAmBU,OAAOvc,MAC1BA,KAAKwc,WAGX,CAIA,MAAAC,GACmB,EAAbzc,KAAKkc,SAA4B,GAAblc,KAAKkc,QAGV,EAAblc,KAAKkc,OACTQ,GAAM1c,KAEV,CACA,GAAAgb,GACE,KAAmB,EAAbhb,KAAKkc,OACT,OAAOlc,KAAKoV,KAEdpV,KAAKkc,OAAS,EACdS,GAAc3c,MACd4c,GAAY5c,MACZ,MAAM6c,EAAa7C,GACb8C,EAAkBC,GACxB/C,GAAYha,KACZ+c,IAAc,EACd,IACE,OAAO/c,KAAKoV,IACd,CAAE,QAMA4H,GAAYhd,MACZga,GAAY6C,EACZE,GAAcD,EACd9c,KAAKkc,QAAU,CACjB,CACF,CACA,IAAAb,GACE,GAAiB,EAAbrb,KAAKkc,MAAW,CAClB,IAAK,IAAI3U,EAAOvH,KAAKgc,KAAMzU,EAAMA,EAAOA,EAAK0V,QAC3CC,GAAU3V,GAEZvH,KAAKgc,KAAOhc,KAAKic,cAAW,EAC5BU,GAAc3c,MACdA,KAAKmd,QAAUnd,KAAKmd,SACpBnd,KAAKkc,QAAU,CACjB,CACF,CACA,OAAAM,GACmB,GAAbxc,KAAKkc,MACPL,GAAmBhT,IAAI7I,MACdA,KAAKqc,UACdrc,KAAKqc,YAELrc,KAAKod,YAET,CAIA,UAAAA,GACMC,GAAQrd,OACVA,KAAKgb,KAET,CACA,SAAIsC,GACF,OAAOD,GAAQrd,KACjB,EAEF,IACIud,GACAC,GAFAC,GAAa,EAGjB,SAASf,GAAMgB,EAAKC,GAAa,GAE/B,GADAD,EAAIxB,OAAS,EACTyB,EAGF,OAFAD,EAAIvB,KAAOqB,QACXA,GAAkBE,GAGpBA,EAAIvB,KAAOoB,GACXA,GAAaG,CACf,CACA,SAASE,KACPH,IACF,CACA,SAASI,KACP,KAAMJ,GAAa,EACjB,OAEF,GAAID,GAAiB,CACnB,IAAIpb,EAAIob,GAER,IADAA,QAAkB,EACXpb,GAAG,CACR,MAAM+Z,EAAO/Z,EAAE+Z,KACf/Z,EAAE+Z,UAAO,EACT/Z,EAAE8Z,QAAU,EACZ9Z,EAAI+Z,CACN,CACF,CACA,IAAI1N,EACJ,KAAO8O,IAAY,CACjB,IAAInb,EAAImb,GAER,IADAA,QAAa,EACNnb,GAAG,CACR,MAAM+Z,EAAO/Z,EAAE+Z,KAGf,GAFA/Z,EAAE+Z,UAAO,EACT/Z,EAAE8Z,QAAU,EACE,EAAV9Z,EAAE8Z,MACJ,IAEE9Z,EAAEoa,SACJ,CAAE,MAAOsB,GACFrP,IAAOA,EAAQqP,EACtB,CAEF1b,EAAI+Z,CACN,CACF,CACA,GAAI1N,EAAO,MAAMA,CACnB,CACA,SAASmO,GAAYc,GACnB,IAAK,IAAInW,EAAOmW,EAAI1B,KAAMzU,EAAMA,EAAOA,EAAK0V,QAC1C1V,EAAKwW,SAAW,EAChBxW,EAAKyW,eAAiBzW,EAAK0W,IAAIC,WAC/B3W,EAAK0W,IAAIC,WAAa3W,CAE1B,CACA,SAASyV,GAAYU,GACnB,IAAIS,EACAC,EAAOV,EAAIzB,SACX1U,EAAO6W,EACX,KAAO7W,GAAM,CACX,MAAM8W,EAAO9W,EAAK+W,SACI,IAAlB/W,EAAKwW,SACHxW,IAAS6W,IAAMA,EAAOC,GAC1BnB,GAAU3V,GACVgX,GAAUhX,IAEV4W,EAAO5W,EAETA,EAAK0W,IAAIC,WAAa3W,EAAKyW,eAC3BzW,EAAKyW,oBAAiB,EACtBzW,EAAO8W,CACT,CACAX,EAAI1B,KAAOmC,EACXT,EAAIzB,SAAWmC,CACjB,CACA,SAASf,GAAQK,GACf,IAAK,IAAInW,EAAOmW,EAAI1B,KAAMzU,EAAMA,EAAOA,EAAK0V,QAC1C,GAAI1V,EAAK0W,IAAIF,UAAYxW,EAAKwW,SAAWxW,EAAK0W,IAAIne,WAAa0e,GAAgBjX,EAAK0W,IAAIne,WAAayH,EAAK0W,IAAIF,UAAYxW,EAAKwW,SAC7H,OAAO,EAGX,QAAIL,EAAIe,MAIV,CACA,SAASD,GAAgB1e,GACvB,GAAqB,EAAjBA,EAASoc,SAAgC,GAAjBpc,EAASoc,OACnC,OAGF,GADApc,EAASoc,QAAU,GACfpc,EAAS4e,gBAAkBA,GAC7B,OAGF,GADA5e,EAAS4e,cAAgBA,IACpB5e,EAAS6e,OAA0B,IAAjB7e,EAASoc,SAAiBpc,EAASkc,OAASlc,EAAS2e,SAAWpB,GAAQvd,IAC7F,OAEFA,EAASoc,OAAS,EAClB,MAAM+B,EAAMne,EAASme,IACfW,EAAU5E,GACV8C,EAAkBC,GACxB/C,GAAYla,EACZid,IAAc,EACd,IACEH,GAAY9c,GACZ,MAAM0N,EAAQ1N,EAASsV,GAAGtV,EAAS+e,SACf,IAAhBZ,EAAIF,SAAiBjI,EAAWtI,EAAO1N,EAAS+e,WAClD/e,EAASoc,OAAS,IAClBpc,EAAS+e,OAASrR,EAClByQ,EAAIF,UAER,CAAE,MAAOD,GAEP,MADAG,EAAIF,UACED,CACR,CAAE,QACA9D,GAAY4E,EACZ7B,GAAcD,EACdE,GAAYld,GACZA,EAASoc,QAAU,CACrB,CACF,CACA,SAASgB,GAAU3V,EAAMuX,GAAO,GAC9B,MAAM,IAAEb,EAAG,QAAEW,EAAO,QAAEG,GAAYxX,EAYlC,GAXIqX,IACFA,EAAQG,QAAUA,EAClBxX,EAAKqX,aAAU,GAEbG,IACFA,EAAQH,QAAUA,EAClBrX,EAAKwX,aAAU,GAKbd,EAAIe,OAASzX,IACf0W,EAAIe,KAAOJ,GACNA,GAAWX,EAAIne,UAAU,CAC5Bme,EAAIne,SAASoc,QAAU,EACvB,IAAK,IAAIpB,EAAImD,EAAIne,SAASkc,KAAMlB,EAAGA,EAAIA,EAAEmC,QACvCC,GAAUpC,GAAG,EAEjB,CAEGgE,KAAWb,EAAIgB,KAAMhB,EAAI9K,KAC5B8K,EAAI9K,IAAIoJ,OAAO0B,EAAInZ,IAEvB,CACA,SAASyZ,GAAUhX,GACjB,MAAM,QAAE+W,EAAO,QAAErB,GAAY1V,EACzB+W,IACFA,EAAQrB,QAAUA,EAClB1V,EAAK+W,aAAU,GAEbrB,IACFA,EAAQqB,QAAUA,EAClB/W,EAAK0V,aAAU,EAEnB,CACA,SAASiC,GAAO9J,EAAI/D,GACd+D,EAAG8J,kBAAkBnD,KACvB3G,EAAKA,EAAG8J,OAAO9J,IAEjB,MAAMhT,EAAI,IAAI2Z,GAAe3G,GACzB/D,GACF,EAAOjP,EAAGiP,GAEZ,IACEjP,EAAE4Y,KACJ,CAAE,MAAO8C,GAEP,MADA1b,EAAEiZ,OACIyC,CACR,CACA,MAAMqB,EAAS/c,EAAE4Y,IAAIoE,KAAKhd,GAE1B,OADA+c,EAAOD,OAAS9c,EACT+c,CACT,CACA,SAAS9D,GAAK8D,GACZA,EAAOD,OAAO7D,MAChB,CACA,IAAI0B,IAAc,EAClB,MAAMsC,GAAa,GACnB,SAAS,KACPA,GAAW1E,KAAKoC,IAChBA,IAAc,CAChB,CAKA,SAAS,KACP,MAAMxB,EAAO8D,GAAW7D,MACxBuB,QAAuB,IAATxB,GAAyBA,CACzC,CAUA,SAASoB,GAAcva,GACrB,MAAM,QAAEga,GAAYha,EAEpB,GADAA,EAAEga,aAAU,EACRA,EAAS,CACX,MAAMwC,EAAU5E,GAChBA,QAAY,EACZ,IACEoC,GACF,CAAE,QACApC,GAAY4E,CACd,CACF,CACF,CAEA,IAAIF,GAAgB,EACpB,MAAMY,GACJ,WAAApF,CAAYwD,EAAKO,GACfje,KAAK0d,IAAMA,EACX1d,KAAKie,IAAMA,EACXje,KAAK+d,QAAUE,EAAIF,QACnB/d,KAAKid,QAAUjd,KAAKse,QAAUte,KAAK+e,QAAU/e,KAAK4e,QAAU5e,KAAKge,oBAAiB,CACpF,EAEF,MAAMuB,GAEJ,WAAArF,CAAYpa,GACVE,KAAKF,SAAWA,EAChBE,KAAK+d,QAAU,EAIf/d,KAAKke,gBAAa,EAIlBle,KAAKgf,UAAO,EAIZhf,KAAKmT,SAAM,EACXnT,KAAK8E,SAAM,EAIX9E,KAAKif,GAAK,EAIVjf,KAAKwf,UAAW,CAIlB,CACA,KAAAC,CAAMC,GACJ,IAAK1F,KAAc+C,IAAe/C,KAAcha,KAAKF,SACnD,OAEF,IAAIyH,EAAOvH,KAAKke,WAChB,QAAa,IAAT3W,GAAmBA,EAAKmW,MAAQ1D,GAClCzS,EAAOvH,KAAKke,WAAa,IAAIoB,GAAKtF,GAAWha,MACxCga,GAAUgC,MAGbzU,EAAK+W,QAAUtE,GAAUiC,SACzBjC,GAAUiC,SAASgB,QAAU1V,EAC7ByS,GAAUiC,SAAW1U,GAJrByS,GAAUgC,KAAOhC,GAAUiC,SAAW1U,EAMxCoY,GAAOpY,QACF,IAAsB,IAAlBA,EAAKwW,UACdxW,EAAKwW,QAAU/d,KAAK+d,QAChBxW,EAAK0V,SAAS,CAChB,MAAMd,EAAO5U,EAAK0V,QAClBd,EAAKmC,QAAU/W,EAAK+W,QAChB/W,EAAK+W,UACP/W,EAAK+W,QAAQrB,QAAUd,GAEzB5U,EAAK+W,QAAUtE,GAAUiC,SACzB1U,EAAK0V,aAAU,EACfjD,GAAUiC,SAASgB,QAAU1V,EAC7ByS,GAAUiC,SAAW1U,EACjByS,GAAUgC,OAASzU,IACrByS,GAAUgC,KAAOG,EAErB,CAYF,OAAO5U,CACT,CACA,OAAAiV,CAAQkD,GACN1f,KAAK+d,UACLW,KACA1e,KAAKyc,OAAOiD,EACd,CACA,MAAAjD,CAAOiD,GACL9B,KACA,IAeE,IAAK,IAAIrW,EAAOvH,KAAKgf,KAAMzX,EAAMA,EAAOA,EAAKqX,QACvCrX,EAAKmW,IAAIjB,UAEXlV,EAAKmW,IAAIO,IAAIxB,QAGnB,CAAE,QACAoB,IACF,CACF,EAEF,SAAS8B,GAAOpY,GAEd,GADAA,EAAK0W,IAAIgB,KACY,EAAjB1X,EAAKmW,IAAIxB,MAAW,CACtB,MAAMpc,EAAWyH,EAAK0W,IAAIne,SAC1B,GAAIA,IAAayH,EAAK0W,IAAIe,KAAM,CAC9Blf,EAASoc,OAAS,GAClB,IAAK,IAAIpB,EAAIhb,EAASkc,KAAMlB,EAAGA,EAAIA,EAAEmC,QACnC0C,GAAO7E,EAEX,CACA,MAAM8E,EAAcrY,EAAK0W,IAAIe,KACzBY,IAAgBrY,IAClBA,EAAKqX,QAAUgB,EACXA,IAAaA,EAAYb,QAAUxX,IAKzCA,EAAK0W,IAAIe,KAAOzX,CAClB,CACF,CACA,MAAMsY,GAA4B,IAAIC,QAChCC,GAAcC,OAC6C,IAE3DC,GAAsBD,OACuC,IAE7DE,GAAoBF,OACsC,IAEhE,SAAS,GAAM7c,EAAQhF,EAAM2G,GAC3B,GAAIiY,IAAe/C,GAAW,CAC5B,IAAImG,EAAUN,GAAUnd,IAAIS,GACvBgd,GACHN,GAAUO,IAAIjd,EAAQgd,EAA0B,IAAIE,KAEtD,IAAIpC,EAAMkC,EAAQzd,IAAIoC,GACjBmZ,IACHkC,EAAQC,IAAItb,EAAKmZ,EAAM,IAAIsB,IAC3BtB,EAAI9K,IAAMgN,EACVlC,EAAInZ,IAAMA,GASVmZ,EAAIwB,OAER,CACF,CACA,SAASjD,GAAQrZ,EAAQhF,EAAM2G,EAAKwE,EAAUyM,EAAUuK,GACtD,MAAMH,EAAUN,GAAUnd,IAAIS,GAC9B,IAAKgd,EAEH,YADAzB,KAGF,MAAM1D,EAAOiD,IACPA,GAWAA,EAAIzB,WAKV,GADAoB,KACa,UAATzf,EACFgiB,EAAQzX,QAAQsS,OACX,CACL,MAAMuF,EAAgB,EAAQpd,GACxBqd,EAAeD,GAAiBvL,EAAalQ,GACnD,GAAIyb,GAAyB,WAARzb,EAAkB,CACrC,MAAM2b,EAAY1J,OAAOzN,GACzB6W,EAAQzX,QAAQ,CAACuV,EAAKyC,MACP,WAATA,GAAqBA,IAASR,KAAsBzL,EAASiM,IAASA,GAAQD,IAChFzF,EAAIiD,IAGV,MAOE,aANY,IAARnZ,GAAkBqb,EAAQ7D,SAAI,KAChCtB,EAAImF,EAAQzd,IAAIoC,IAEd0b,GACFxF,EAAImF,EAAQzd,IAAIwd,KAEV/hB,GACN,IAAK,MACEoiB,EAKMC,GACTxF,EAAImF,EAAQzd,IAAI,YALhBsY,EAAImF,EAAQzd,IAAIqd,KACZ1L,EAAMlR,IACR6X,EAAImF,EAAQzd,IAAIud,MAKpB,MACF,IAAK,SACEM,IACHvF,EAAImF,EAAQzd,IAAIqd,KACZ1L,EAAMlR,IACR6X,EAAImF,EAAQzd,IAAIud,MAGpB,MACF,IAAK,MACC5L,EAAMlR,IACR6X,EAAImF,EAAQzd,IAAIqd,KAK1B,CACAlC,IACF,CAMA,SAAS8C,GAAkBC,GACzB,MAAMC,EAAM,GAAMD,GAClB,OAAIC,IAAQD,EAAcC,GAC1B,GAAMA,EAAK,EAAWX,IACfY,GAAUF,GAASC,EAAMA,EAAI1N,IAAI4N,IAC1C,CACA,SAASC,GAAiBnN,GAExB,OADA,GAAMA,EAAM,GAAMA,GAAM,EAAWqM,IAC5BrM,CACT,CACA,MAAMoN,GAAwB,CAC5BC,UAAW,KACX,CAAClB,OAAOmB,YACN,OAAOA,GAASnhB,KAAMggB,OAAOmB,SAAUJ,GACzC,EACA,MAAAK,IAAU5S,GACR,OAAOmS,GAAkB3gB,MAAMohB,UAC1B5S,EAAK2E,IAAKkO,GAAM,EAAQA,GAAKV,GAAkBU,GAAKA,GAE3D,EACA,OAAA7H,GACE,OAAO2H,GAASnhB,KAAM,UAAYwN,IAChCA,EAAM,GAAKuT,GAAWvT,EAAM,IACrBA,GAEX,EACA,KAAA8T,CAAMlM,EAAImM,GACR,OAAOC,GAAMxhB,KAAM,QAASoV,EAAImM,OAAS,EAAQE,UACnD,EACA,MAAAC,CAAOtM,EAAImM,GACT,OAAOC,GAAMxhB,KAAM,SAAUoV,EAAImM,EAAU3H,GAAMA,EAAEzG,IAAI4N,IAAaU,UACtE,EACA,IAAAE,CAAKvM,EAAImM,GACP,OAAOC,GAAMxhB,KAAM,OAAQoV,EAAImM,EAASR,GAAYU,UACtD,EACA,SAAAxI,CAAU7D,EAAImM,GACZ,OAAOC,GAAMxhB,KAAM,YAAaoV,EAAImM,OAAS,EAAQE,UACvD,EACA,QAAAG,CAASxM,EAAImM,GACX,OAAOC,GAAMxhB,KAAM,WAAYoV,EAAImM,EAASR,GAAYU,UAC1D,EACA,aAAAI,CAAczM,EAAImM,GAChB,OAAOC,GAAMxhB,KAAM,gBAAiBoV,EAAImM,OAAS,EAAQE,UAC3D,EAEA,OAAA/Y,CAAQ0M,EAAImM,GACV,OAAOC,GAAMxhB,KAAM,UAAWoV,EAAImM,OAAS,EAAQE,UACrD,EACA,QAAAK,IAAYtT,GACV,OAAOuT,GAAY/hB,KAAM,WAAYwO,EACvC,EACA,OAAApN,IAAWoN,GACT,OAAOuT,GAAY/hB,KAAM,UAAWwO,EACtC,EACA,IAAAwT,CAAKC,GACH,OAAOtB,GAAkB3gB,MAAMgiB,KAAKC,EACtC,EAEA,WAAAC,IAAe1T,GACb,OAAOuT,GAAY/hB,KAAM,cAAewO,EAC1C,EACA,GAAA2E,CAAIiC,EAAImM,GACN,OAAOC,GAAMxhB,KAAM,MAAOoV,EAAImM,OAAS,EAAQE,UACjD,EACA,GAAAjG,GACE,OAAO2G,GAAWniB,KAAM,MAC1B,EACA,IAAA2a,IAAQnM,GACN,OAAO2T,GAAWniB,KAAM,OAAQwO,EAClC,EACA,MAAAiL,CAAOrE,KAAO5G,GACZ,OAAOiL,GAAOzZ,KAAM,SAAUoV,EAAI5G,EACpC,EACA,WAAA4T,CAAYhN,KAAO5G,GACjB,OAAOiL,GAAOzZ,KAAM,cAAeoV,EAAI5G,EACzC,EACA,KAAA6T,GACE,OAAOF,GAAWniB,KAAM,QAC1B,EAEA,IAAAsiB,CAAKlN,EAAImM,GACP,OAAOC,GAAMxhB,KAAM,OAAQoV,EAAImM,OAAS,EAAQE,UAClD,EACA,MAAA5c,IAAU2J,GACR,OAAO2T,GAAWniB,KAAM,SAAUwO,EACpC,EACA,UAAA+T,GACE,OAAO5B,GAAkB3gB,MAAMuiB,YACjC,EACA,QAAAC,CAASC,GACP,OAAO9B,GAAkB3gB,MAAMwiB,SAASC,EAC1C,EACA,SAAAC,IAAalU,GACX,OAAOmS,GAAkB3gB,MAAM0iB,aAAalU,EAC9C,EACA,OAAAmU,IAAWnU,GACT,OAAO2T,GAAWniB,KAAM,UAAWwO,EACrC,EACA,MAAA1L,GACE,OAAOqe,GAASnhB,KAAM,SAAU+gB,GAClC,GAEF,SAASI,GAAS/J,EAAMwL,EAAQC,GAC9B,MAAMhP,EAAMmN,GAAiB5J,GACvB0L,EAAOjP,EAAI+O,KAWjB,OAVI/O,IAAQuD,GAAS0J,GAAU1J,KAC7B0L,EAAKC,MAAQD,EAAK3G,KAClB2G,EAAK3G,KAAO,KACV,MAAM6G,EAASF,EAAKC,QAIpB,OAHKC,EAAOC,OACVD,EAAOxV,MAAQqV,EAAUG,EAAOxV,QAE3BwV,IAGJF,CACT,CACA,MAAMI,GAAa1hB,MAAMwS,UACzB,SAASwN,GAAMpK,EAAMwL,EAAQxN,EAAImM,EAAS4B,EAAc3U,GACtD,MAAMqF,EAAMmN,GAAiB5J,GACvBgM,EAAYvP,IAAQuD,IAAS0J,GAAU1J,GACvCiM,EAAWxP,EAAI+O,GACrB,GAAIS,IAAaH,GAAWN,GAAS,CACnC,MAAMU,EAAUD,EAAS7B,MAAMpK,EAAM5I,GACrC,OAAO4U,EAAYrC,GAAWuC,GAAWA,CAC3C,CACA,IAAIC,EAAYnO,EACZvB,IAAQuD,IACNgM,EACFG,EAAY,SAAS7X,EAAM9G,GACzB,OAAOwQ,EAAGjB,KAAKnU,KAAM+gB,GAAWrV,GAAO9G,EAAOwS,EAChD,EACShC,EAAG3R,OAAS,IACrB8f,EAAY,SAAS7X,EAAM9G,GACzB,OAAOwQ,EAAGjB,KAAKnU,KAAM0L,EAAM9G,EAAOwS,EACpC,IAGJ,MAAM4L,EAASK,EAASlP,KAAKN,EAAK0P,EAAWhC,GAC7C,OAAO6B,GAAaD,EAAeA,EAAaH,GAAUA,CAC5D,CACA,SAASvJ,GAAOrC,EAAMwL,EAAQxN,EAAI5G,GAChC,MAAMqF,EAAMmN,GAAiB5J,GAC7B,IAAImM,EAAYnO,EAYhB,OAXIvB,IAAQuD,IACL0J,GAAU1J,GAIJhC,EAAG3R,OAAS,IACrB8f,EAAY,SAASC,EAAK9X,EAAM9G,GAC9B,OAAOwQ,EAAGjB,KAAKnU,KAAMwjB,EAAK9X,EAAM9G,EAAOwS,EACzC,GANAmM,EAAY,SAASC,EAAK9X,EAAM9G,GAC9B,OAAOwQ,EAAGjB,KAAKnU,KAAMwjB,EAAKzC,GAAWrV,GAAO9G,EAAOwS,EACrD,GAOGvD,EAAI+O,GAAQW,KAAc/U,EACnC,CACA,SAASuT,GAAY3K,EAAMwL,EAAQpU,GACjC,MAAMqF,EAAM,GAAMuD,GAClB,GAAMvD,EAAK,EAAWqM,IACtB,MAAM3I,EAAM1D,EAAI+O,MAAWpU,GAC3B,OAAc,IAAT+I,IAAsB,IAARA,IAAkBkM,GAAQjV,EAAK,IAI3C+I,GAHL/I,EAAK,GAAK,GAAMA,EAAK,IACdqF,EAAI+O,MAAWpU,GAG1B,CACA,SAAS2T,GAAW/K,EAAMwL,EAAQpU,EAAO,IACvC,KACAoP,KACA,MAAMrG,EAAM,GAAMH,GAAMwL,GAAQpB,MAAMpK,EAAM5I,GAG5C,OAFAqP,KACA,KACOtG,CACT,CAEA,MAAMmM,GAAqC,EAAQ,+BAC7CC,GAAiB,IAAIC,IACTjjB,OAAOkjB,oBAAoB7D,QAAQ0B,OAAQ5c,GAAgB,cAARA,GAA+B,WAARA,GAAkBqO,IAAKrO,GAAQkb,OAAOlb,IAAM4c,OAAOjN,IAE/I,SAAS,GAAe3P,GACjB2P,EAAS3P,KAAMA,EAAMnG,OAAOmG,IACjC,MAAMuR,EAAM,GAAMrW,MAElB,OADA,GAAMqW,EAAK,EAAOvR,GACXuR,EAAIpC,eAAenP,EAC5B,CACA,MAAMgf,GACJ,WAAA5J,CAAY6J,GAAc,EAAOC,GAAa,GAC5ChkB,KAAK+jB,YAAcA,EACnB/jB,KAAKgkB,WAAaA,CACpB,CACA,GAAAthB,CAAIS,EAAQ2B,EAAKmf,GACf,GAAY,aAARnf,EAAoB,OAAO3B,EAAiB,SAChD,MAAM+gB,EAAclkB,KAAK+jB,YAAaI,EAAankB,KAAKgkB,WACxD,GAAY,mBAARlf,EACF,OAAQof,EACH,GAAY,mBAARpf,EACT,OAAOof,EACF,GAAY,kBAARpf,EACT,OAAOqf,EACF,GAAY,YAARrf,EACT,OAAImf,KAAcC,EAAcC,EAAaC,GAAqBC,GAAcF,EAAaG,GAAqBC,IAAa7hB,IAAIS,IAEnIxC,OAAO6jB,eAAerhB,KAAYxC,OAAO6jB,eAAeP,GAC/C9gB,OAET,EAEF,MAAMod,EAAgB,EAAQpd,GAC9B,IAAK+gB,EAAa,CAChB,IAAI9O,EACJ,GAAImL,IAAkBnL,EAAK6L,GAAsBnc,IAC/C,OAAOsQ,EAET,GAAY,mBAARtQ,EACF,OAAO,EAEX,CACA,MAAMyS,EAAMkN,QAAQ/hB,IAClBS,EACA2B,EAIA,GAAM3B,GAAUA,EAAS8gB,GAE3B,GAAIxP,EAAS3P,GAAO6e,GAAerH,IAAIxX,GAAO4e,GAAmB5e,GAC/D,OAAOyS,EAKT,GAHK2M,GACH,GAAM/gB,EAAQ,EAAO2B,GAEnBqf,EACF,OAAO5M,EAET,GAAI,GAAMA,GAAM,CACd,MAAM/J,EAAQ+S,GAAiBvL,EAAalQ,GAAOyS,EAAMA,EAAI/J,MAC7D,OAAO0W,GAAe,EAAS1W,GAASkX,GAASlX,GAASA,CAC5D,CACA,OAAI,EAAS+J,GACJ2M,EAAcQ,GAASnN,GAAOoN,GAASpN,GAEzCA,CACT,EAEF,MAAMqN,WAA+Bd,GACnC,WAAA5J,CAAYiK,GAAa,GACvBU,OAAM,EAAOV,EACf,CACA,GAAA/D,CAAIjd,EAAQ2B,EAAK0I,EAAOyW,GACtB,IAAIlO,EAAW5S,EAAO2B,GACtB,IAAK9E,KAAKgkB,WAAY,CACpB,MAAMc,EAAqBC,GAAWhP,GAKtC,GAJK+K,GAAUtT,IAAWuX,GAAWvX,KACnCuI,EAAW,GAAMA,GACjBvI,EAAQ,GAAMA,KAEX,EAAQrK,IAAW,GAAM4S,KAAc,GAAMvI,GAChD,OAAIsX,IASF/O,EAASvI,MAAQA,IAFV,CAMb,CACA,MAAMwX,EAAS,EAAQ7hB,IAAW6R,EAAalQ,GAAOiS,OAAOjS,GAAO3B,EAAOM,OAASyQ,EAAO/Q,EAAQ2B,GAC7Fke,EAASyB,QAAQrE,IACrBjd,EACA2B,EACA0I,EACA,GAAMrK,GAAUA,EAAS8gB,GAS3B,OAPI9gB,IAAW,GAAM8gB,KACde,EAEMlP,EAAWtI,EAAOuI,IAC3ByG,GAAQrZ,EAAQ,MAAO2B,EAAK0I,GAF5BgP,GAAQrZ,EAAQ,MAAO2B,EAAK0I,IAKzBwV,CACT,CACA,cAAAiC,CAAe9hB,EAAQ2B,GACrB,MAAMkgB,EAAS9Q,EAAO/Q,EAAQ2B,GAExBke,GADW7f,EAAO2B,GACT2f,QAAQQ,eAAe9hB,EAAQ2B,IAI9C,OAHIke,GAAUgC,GACZxI,GAAQrZ,EAAQ,SAAU2B,OAAK,GAE1Bke,CACT,CACA,GAAA1G,CAAInZ,EAAQ2B,GACV,MAAMke,EAASyB,QAAQnI,IAAInZ,EAAQ2B,GAInC,OAHK2P,EAAS3P,IAAS6e,GAAerH,IAAIxX,IACxC,GAAM3B,EAAQ,EAAO2B,GAEhBke,CACT,CACA,OAAAkC,CAAQ/hB,GAMN,OALA,GACEA,EACA,EACA,EAAQA,GAAU,SAAW4c,IAExB0E,QAAQS,QAAQ/hB,EACzB,EAEF,MAAMgiB,WAAgCrB,GACpC,WAAA5J,CAAYiK,GAAa,GACvBU,OAAM,EAAMV,EACd,CACA,GAAA/D,CAAIjd,EAAQ2B,GAOV,OAAO,CACT,CACA,cAAAmgB,CAAe9hB,EAAQ2B,GAOrB,OAAO,CACT,EAEF,MAAMsgB,GAAkC,IAAIR,GACtCS,GAAmC,IAAIF,GACvCG,GAA0C,IAAIV,IAAuB,GACrEW,GAA0C,IAAIJ,IAAwB,GAEtEK,GAAahY,GAAUA,EACvBiY,GAAY7L,GAAM6K,QAAQD,eAAe5K,GA+B/C,SAAS8L,GAAqBvnB,GAC5B,OAAO,YAAYqQ,GAQjB,MAAgB,WAATrQ,IAAqC,UAATA,OAAmB,EAAS6B,KACjE,CACF,CA4IA,SAAS2lB,GAA4BzB,EAAa0B,GAChD,MAAMC,EA5IR,SAAgCnB,EAAUkB,GACxC,MAAMC,EAAmB,CACvB,GAAAnjB,CAAIoC,GACF,MAAM3B,EAASnD,KAAc,QACvB8lB,EAAY,GAAM3iB,GAClB4iB,EAAS,GAAMjhB,GAChB4f,IACC5O,EAAWhR,EAAKihB,IAClB,GAAMD,EAAW,EAAOhhB,GAE1B,GAAMghB,EAAW,EAAOC,IAE1B,MAAM,IAAEzJ,GAAQmJ,GAASK,GACnBE,EAAOJ,EAAUJ,GAAYd,EAAWuB,GAAalF,GAC3D,OAAIzE,EAAInI,KAAK2R,EAAWhhB,GACfkhB,EAAK7iB,EAAOT,IAAIoC,IACdwX,EAAInI,KAAK2R,EAAWC,GACtBC,EAAK7iB,EAAOT,IAAIqjB,SACd5iB,IAAW2iB,GACpB3iB,EAAOT,IAAIoC,GAEf,EACA,QAAIyU,GACF,MAAMpW,EAASnD,KAAc,QAE7B,OADC0kB,GAAY,GAAM,GAAMvhB,GAAS,EAAW4c,IACtC5c,EAAOoW,IAChB,EACA,GAAA+C,CAAIxX,GACF,MAAM3B,EAASnD,KAAc,QACvB8lB,EAAY,GAAM3iB,GAClB4iB,EAAS,GAAMjhB,GAOrB,OANK4f,IACC5O,EAAWhR,EAAKihB,IAClB,GAAMD,EAAW,EAAOhhB,GAE1B,GAAMghB,EAAW,EAAOC,IAEnBjhB,IAAQihB,EAAS5iB,EAAOmZ,IAAIxX,GAAO3B,EAAOmZ,IAAIxX,IAAQ3B,EAAOmZ,IAAIyJ,EAC1E,EACA,OAAArd,CAAQwd,EAAU3E,GAChB,MAAM4E,EAAWnmB,KACXmD,EAASgjB,EAAkB,QAC3BL,EAAY,GAAM3iB,GAClB6iB,EAAOJ,EAAUJ,GAAYd,EAAWuB,GAAalF,GAE3D,OADC2D,GAAY,GAAMoB,EAAW,EAAW/F,IAClC5c,EAAOuF,QAAQ,CAAC8E,EAAO1I,IACrBohB,EAAS/R,KAAKoN,EAASyE,EAAKxY,GAAQwY,EAAKlhB,GAAMqhB,GAE1D,GAyFF,OAvFA,EACEN,EACAnB,EAAW,CACT7b,IAAK6c,GAAqB,OAC1BtF,IAAKsF,GAAqB,OAC1BnJ,OAAQmJ,GAAqB,UAC7BU,MAAOV,GAAqB,UAC1B,CACF,GAAA7c,CAAI2E,GACGoY,GAAY9E,GAAUtT,IAAWuX,GAAWvX,KAC/CA,EAAQ,GAAMA,IAEhB,MAAMrK,EAAS,GAAMnD,MAOrB,OANcylB,GAAStiB,GACFmZ,IAAInI,KAAKhR,EAAQqK,KAEpCrK,EAAO0F,IAAI2E,GACXgP,GAAQrZ,EAAQ,MAAOqK,EAAOA,IAEzBxN,IACT,EACA,GAAAogB,CAAItb,EAAK0I,GACFoY,GAAY9E,GAAUtT,IAAWuX,GAAWvX,KAC/CA,EAAQ,GAAMA,IAEhB,MAAMrK,EAAS,GAAMnD,OACf,IAAEsc,EAAG,IAAE5Z,GAAQ+iB,GAAStiB,GAC9B,IAAI6hB,EAAS1I,EAAInI,KAAKhR,EAAQ2B,GACzBkgB,IACHlgB,EAAM,GAAMA,GACZkgB,EAAS1I,EAAInI,KAAKhR,EAAQ2B,IAI5B,MAAMiR,EAAWrT,EAAIyR,KAAKhR,EAAQ2B,GAOlC,OANA3B,EAAOid,IAAItb,EAAK0I,GACXwX,EAEMlP,EAAWtI,EAAOuI,IAC3ByG,GAAQrZ,EAAQ,MAAO2B,EAAK0I,GAF5BgP,GAAQrZ,EAAQ,MAAO2B,EAAK0I,GAIvBxN,IACT,EACA,OAAO8E,GACL,MAAM3B,EAAS,GAAMnD,OACf,IAAEsc,EAAG,IAAE5Z,GAAQ+iB,GAAStiB,GAC9B,IAAI6hB,EAAS1I,EAAInI,KAAKhR,EAAQ2B,GACzBkgB,IACHlgB,EAAM,GAAMA,GACZkgB,EAAS1I,EAAInI,KAAKhR,EAAQ2B,IAIXpC,GAAMA,EAAIyR,KAAKhR,EAAQ2B,GAAxC,MACMke,EAAS7f,EAAOoZ,OAAOzX,GAI7B,OAHIkgB,GACFxI,GAAQrZ,EAAQ,SAAU2B,OAAK,GAE1Bke,CACT,EACA,KAAAoD,GACE,MAAMjjB,EAAS,GAAMnD,MACfqmB,EAA2B,IAAhBljB,EAAOoW,KAElByJ,EAAS7f,EAAOijB,QAUtB,OATIC,GACF7J,GACErZ,EACA,aACA,OACA,GAIG6f,CACT,IAGoB,CACtB,OACA,SACA,UACAhD,OAAOmB,UAEOzY,QAASka,IACvBiD,EAAiBjD,GAjLrB,SAA8BA,EAAQsB,EAAaC,GACjD,OAAO,YAAY3V,GACjB,MAAMrL,EAASnD,KAAc,QACvB8lB,EAAY,GAAM3iB,GAClBmjB,EAAcjS,EAAMyR,GACpBS,EAAoB,YAAX3D,GAAwBA,IAAW5C,OAAOmB,UAAYmF,EAC/DE,EAAuB,SAAX5D,GAAqB0D,EACjCG,EAAgBtjB,EAAOyf,MAAWpU,GAClCwX,EAAO7B,EAAaqB,GAAYtB,EAAc+B,GAAalF,GAMjE,OALCmD,GAAe,GACd4B,EACA,EACAU,EAAYvG,GAAsBF,IAE7B,CAEL,IAAA5D,GACE,MAAM,MAAE3O,EAAK,KAAEyV,GAASwD,EAActK,OACtC,OAAO8G,EAAO,CAAEzV,QAAOyV,QAAS,CAC9BzV,MAAO+Y,EAAS,CAACP,EAAKxY,EAAM,IAAKwY,EAAKxY,EAAM,KAAOwY,EAAKxY,GACxDyV,OAEJ,EAEA,CAACjD,OAAOmB,YACN,OAAOnhB,IACT,EAEJ,CACF,CAoJ+B0mB,CAAqB9D,EAAQ8B,EAAUkB,KAE7DC,CACT,CAE2Bc,CAAuBzC,EAAa0B,GAC7D,MAAO,CAACziB,EAAQ2B,EAAKmf,IACP,mBAARnf,GACMof,EACS,mBAARpf,EACFof,EACU,YAARpf,EACF3B,EAEFshB,QAAQ/hB,IACbwR,EAAO2R,EAAkB/gB,IAAQA,KAAO3B,EAAS0iB,EAAmB1iB,EACpE2B,EACAmf,EAGN,CACA,MAAM2C,GAA4B,CAChClkB,IAAqBijB,IAA4B,GAAO,IAEpDkB,GAA4B,CAChCnkB,IAAqBijB,IAA4B,GAAO,IAEpDmB,GAA6B,CACjCpkB,IAAqBijB,IAA4B,GAAM,IAEnDoB,GAAoC,CACxCrkB,IAAqBijB,IAA4B,GAAM,IAYnDpB,GAA8B,IAAIzE,QAClCwE,GAAqC,IAAIxE,QACzCuE,GAA8B,IAAIvE,QAClCsE,GAAqC,IAAItE,QAkB/C,SAAS6E,GAASxhB,GAChB,OAAI4hB,GAAW5hB,GACNA,EAEF6jB,GACL7jB,GACA,EACAiiB,GACAwB,GACArC,GAEJ,CACA,SAAS0C,GAAgB9jB,GACvB,OAAO6jB,GACL7jB,GACA,EACAmiB,GACAuB,GACAvC,GAEJ,CACA,SAASI,GAASvhB,GAChB,OAAO6jB,GACL7jB,GACA,EACAkiB,GACAyB,GACAzC,GAEJ,CACA,SAAS6C,GAAgB/jB,GACvB,OAAO6jB,GACL7jB,GACA,EACAoiB,GACAwB,GACA3C,GAEJ,CACA,SAAS4C,GAAqB7jB,EAAQ+gB,EAAaiD,EAAcC,EAAoBC,GACnF,IAAK,EAASlkB,GAQZ,OAAOA,EAET,GAAIA,EAAgB,WAAO+gB,IAAe/gB,EAAuB,gBAC/D,OAAOA,EAET,MAAMmkB,GAxDe9Z,EAwDYrK,GAvDV,WAAMxC,OAAO4mB,aAAa/Z,GAAS,EAf5D,SAAuBga,GACrB,OAAQA,GACN,IAAK,SACL,IAAK,QACH,OAAO,EACT,IAAK,MACL,IAAK,MACL,IAAK,UACL,IAAK,UACH,OAAO,EACT,QACE,OAAO,EAEb,CAE8EC,CAAc,EAAUja,IADtG,IAAuBA,EAyDrB,GAAmB,IAAf8Z,EACF,OAAOnkB,EAET,MAAMukB,EAAgBL,EAAS3kB,IAAIS,GACnC,GAAIukB,EACF,OAAOA,EAET,MAAMC,EAAQ,IAAIC,MAChBzkB,EACe,IAAfmkB,EAAoCF,EAAqBD,GAG3D,OADAE,EAASjH,IAAIjd,EAAQwkB,GACdA,CACT,CACA,SAASE,GAAWra,GAClB,OAAIuX,GAAWvX,GACNqa,GAAWra,EAAe,YAEzBA,IAASA,EAAsB,eAC3C,CACA,SAASuX,GAAWvX,GAClB,SAAUA,IAASA,EAAsB,eAC3C,CACA,SAASsT,GAAUtT,GACjB,SAAUA,IAASA,EAAqB,cAC1C,CACA,SAASiW,GAAQjW,GACf,QAAOA,KAAUA,EAAe,OAClC,CACA,SAAS,GAAM2Y,GACb,MAAMtF,EAAMsF,GAAYA,EAAkB,QAC1C,OAAOtF,EAAM,GAAMA,GAAOsF,CAC5B,CACA,SAAS2B,GAAQta,GAIf,OAHK0G,EAAO1G,EAAO,aAAe7M,OAAO4mB,aAAa/Z,IACpD4I,EAAI5I,EAAO,YAAY,GAElBA,CACT,CACA,MAAMuT,GAAcvT,GAAU,EAASA,GAASmX,GAASnX,GAASA,EAC5DyY,GAAczY,GAAU,EAASA,GAASkX,GAASlX,GAASA,EAElE,SAAS,GAAMua,GACb,QAAOA,IAAuB,IAAnBA,EAAa,SAC1B,CACA,SAASC,GAAIxa,GACX,OAAOya,GAAUza,GAAO,EAC1B,CACA,SAAS0a,GAAW1a,GAClB,OAAOya,GAAUza,GAAO,EAC1B,CACA,SAASya,GAAUE,EAAUvC,GAC3B,OAAI,GAAMuC,GACDA,EAEF,IAAIC,GAAQD,EAAUvC,EAC/B,CACA,MAAMwC,GACJ,WAAAlO,CAAY1M,EAAO2W,GACjBnkB,KAAKie,IAAM,IAAIsB,GACfvf,KAAgB,WAAI,EACpBA,KAAoB,eAAI,EACxBA,KAAKqoB,UAAYlE,EAAa3W,EAAQ,GAAMA,GAC5CxN,KAAK6e,OAASsF,EAAa3W,EAAQuT,GAAWvT,GAC9CxN,KAAoB,cAAImkB,CAC1B,CACA,SAAI3W,GAUF,OAFExN,KAAKie,IAAIwB,QAEJzf,KAAK6e,MACd,CACA,SAAIrR,CAAMlE,GACR,MAAMyM,EAAW/V,KAAKqoB,UAChBC,EAAiBtoB,KAAoB,eAAK8gB,GAAUxX,IAAayb,GAAWzb,GAClFA,EAAWgf,EAAiBhf,EAAW,GAAMA,GACzCwM,EAAWxM,EAAUyM,KACvB/V,KAAKqoB,UAAY/e,EACjBtJ,KAAK6e,OAASyJ,EAAiBhf,EAAWyX,GAAWzX,GAUnDtJ,KAAKie,IAAIzB,UAGf,EAEF,SAAS+L,GAAWC,GACdA,EAAKvK,KASLuK,EAAKvK,IAAIzB,SAGf,CACA,SAASiM,GAAMD,GACb,OAAO,GAAMA,GAAQA,EAAKhb,MAAQgb,CACpC,CACA,SAASE,GAAQC,GACf,OAAO,EAAWA,GAAUA,IAAWF,GAAME,EAC/C,CACA,MAAMC,GAAwB,CAC5BlmB,IAAK,CAACS,EAAQ2B,EAAKmf,IAAqB,YAARnf,EAAoB3B,EAASslB,GAAMhE,QAAQ/hB,IAAIS,EAAQ2B,EAAKmf,IAC5F7D,IAAK,CAACjd,EAAQ2B,EAAK0I,EAAOyW,KACxB,MAAMlO,EAAW5S,EAAO2B,GACxB,OAAI,GAAMiR,KAAc,GAAMvI,IAC5BuI,EAASvI,MAAQA,GACV,GAEAiX,QAAQrE,IAAIjd,EAAQ2B,EAAK0I,EAAOyW,KAI7C,SAAS4E,GAAUC,GACjB,OAAOjB,GAAWiB,GAAkBA,EAAiB,IAAIlB,MAAMkB,EAAgBF,GACjF,CACA,MAAMG,GACJ,WAAA7O,CAAY8O,GACVhpB,KAAgB,WAAI,EACpBA,KAAK6e,YAAS,EACd,MAAMZ,EAAMje,KAAKie,IAAM,IAAIsB,IACrB,IAAE7c,EAAG,IAAE0d,GAAQ4I,EAAQ/K,EAAIwB,MAAML,KAAKnB,GAAMA,EAAIzB,QAAQ4C,KAAKnB,IACnEje,KAAKipB,KAAOvmB,EACZ1C,KAAKkpB,KAAO9I,CACd,CACA,SAAI5S,GACF,OAAOxN,KAAK6e,OAAS7e,KAAKipB,MAC5B,CACA,SAAIzb,CAAM2b,GACRnpB,KAAKkpB,KAAKC,EACZ,EAEF,SAASC,GAAUJ,GACjB,OAAO,IAAID,GAAcC,EAC3B,CACA,SAASK,GAAOC,GAId,MAAMxR,EAAM,EAAQwR,GAAU,IAAI9nB,MAAM8nB,EAAO7lB,QAAU,CAAC,EAC1D,IAAK,MAAMqB,KAAOwkB,EAChBxR,EAAIhT,GAAOykB,GAAcD,EAAQxkB,GAEnC,OAAOgT,CACT,CACA,MAAM0R,GACJ,WAAAtP,CAAYuP,EAASnQ,EAAMoQ,GACzB1pB,KAAKypB,QAAUA,EACfzpB,KAAKsZ,KAAOA,EACZtZ,KAAK0pB,cAAgBA,EACrB1pB,KAAgB,WAAI,EACpBA,KAAK6e,YAAS,CAChB,CACA,SAAIrR,GACF,MAAMJ,EAAMpN,KAAKypB,QAAQzpB,KAAKsZ,MAC9B,OAAOtZ,KAAK6e,YAAiB,IAARzR,EAAiBpN,KAAK0pB,cAAgBtc,CAC7D,CACA,SAAII,CAAM2b,GACRnpB,KAAKypB,QAAQzpB,KAAKsZ,MAAQ6P,CAC5B,CACA,OAAIlL,GACF,OAtzBJ,SAA4BqL,EAAQxkB,GAClC,MAAM6kB,EAAS9J,GAAUnd,IAAI4mB,GAC7B,OAAOK,GAAUA,EAAOjnB,IAAIoC,EAC9B,CAmzBW8kB,CAAmB,GAAM5pB,KAAKypB,SAAUzpB,KAAKsZ,KACtD,EAEF,MAAMuQ,GACJ,WAAA3P,CAAY4P,GACV9pB,KAAK8pB,QAAUA,EACf9pB,KAAgB,WAAI,EACpBA,KAAqB,gBAAI,EACzBA,KAAK6e,YAAS,CAChB,CACA,SAAIrR,GACF,OAAOxN,KAAK6e,OAAS7e,KAAK8pB,SAC5B,EAEF,SAASC,GAAMpB,EAAQ7jB,EAAKklB,GAC1B,OAAI,GAAMrB,GACDA,EACE,EAAWA,GACb,IAAIkB,GAAclB,GAChB,EAASA,IAAWlH,UAAUhe,OAAS,EACzC8lB,GAAcZ,EAAQ7jB,EAAKklB,GAE3BhC,GAAIW,EAEf,CACA,SAASY,GAAcZ,EAAQ7jB,EAAKklB,GAClC,MAAM5c,EAAMub,EAAO7jB,GACnB,OAAO,GAAMsI,GAAOA,EAAM,IAAIoc,GAAcb,EAAQ7jB,EAAKklB,EAC3D,CAEA,MAAMC,GACJ,WAAA/P,CAAY9E,EAAI8U,EAAQvL,GACtB3e,KAAKoV,GAAKA,EACVpV,KAAKkqB,OAASA,EAIdlqB,KAAK6e,YAAS,EAId7e,KAAKie,IAAM,IAAIsB,GAAIvf,MAInBA,KAAKmqB,WAAY,EAMjBnqB,KAAKgc,UAAO,EAIZhc,KAAKic,cAAW,EAIhBjc,KAAKkc,MAAQ,GAIblc,KAAK0e,cAAgBA,GAAgB,EAIrC1e,KAAKmc,UAAO,EAEZnc,KAAKkf,OAASlf,KACdA,KAAqB,gBAAKkqB,EAC1BlqB,KAAK2e,MAAQA,CACf,CAIA,MAAAlC,GAEE,GADAzc,KAAKkc,OAAS,KACK,EAAblc,KAAKkc,OACXlC,KAAcha,MAEZ,OADA0c,GAAM1c,MAAM,IACL,CAEX,CACA,SAAIwN,GACF,MAAMjG,EAIDvH,KAAKie,IAAIwB,QAKd,OAJAjB,GAAgBxe,MACZuH,IACFA,EAAKwW,QAAU/d,KAAKie,IAAIF,SAEnB/d,KAAK6e,MACd,CACA,SAAIrR,CAAMlE,GACJtJ,KAAKkqB,QACPlqB,KAAKkqB,OAAO5gB,EAIhB,EAmBF,MAAM8gB,GAAe,CACnB,IAAO,MACP,IAAO,MACP,QAAW,WAEPC,GAAiB,CACrB,IAAO,MACP,IAAO,MACP,OAAU,SACV,MAAS,SAmBLC,GAAwB,CAAC,EACzBC,GAA6B,IAAIzK,QACvC,IAAI0K,GACJ,SAASC,KACP,OAAOD,EACT,CACA,SAASE,GAAiBC,EAAW/O,GAAe,EAAOgP,EAAQJ,IACjE,GAAII,EAAO,CACT,IAAIrQ,EAAWgQ,GAAW7nB,IAAIkoB,GACzBrQ,GAAUgQ,GAAWnK,IAAIwK,EAAOrQ,EAAW,IAChDA,EAASI,KAAKgQ,EAChB,CAKF,CA6JA,SAASE,GAASrd,EAAOsd,EAAQC,IAAUC,GACzC,GAAIF,GAAS,IAAM,EAAStd,IAAUA,EAAgB,SACpD,OAAOA,EAGT,KADAwd,EAAOA,GAAwB,IAAI3K,KACzB3d,IAAI8K,IAAU,IAAMsd,EAC5B,OAAOtd,EAIT,GAFAwd,EAAK5K,IAAI5S,EAAOsd,GAChBA,IACI,GAAMtd,GACRqd,GAASrd,EAAMA,MAAOsd,EAAOE,QACxB,GAAI,EAAQxd,GACjB,IAAK,IAAIuG,EAAI,EAAGA,EAAIvG,EAAM/J,OAAQsQ,IAChC8W,GAASrd,EAAMuG,GAAI+W,EAAOE,QAEvB,GAAIzW,EAAM/G,IAAU6G,EAAM7G,GAC/BA,EAAM9E,QAASkR,IACbiR,GAASjR,EAAGkR,EAAOE,UAEhB,GAAIjW,EAAcvH,GAAQ,CAC/B,IAAK,MAAM1I,KAAO0I,EAChBqd,GAASrd,EAAM1I,GAAMgmB,EAAOE,GAE9B,IAAK,MAAMlmB,KAAOnE,OAAOsqB,sBAAsBzd,GACzC7M,OAAOqT,UAAUkX,qBAAqB/W,KAAK3G,EAAO1I,IACpD+lB,GAASrd,EAAM1I,GAAMgmB,EAAOE,EAGlC,CACA,OAAOxd,CACT,CCn3DA,MAAM2d,GAAQ,GAgHd,SAASC,GAAahe,EAAKjP,GAS3B,CAEA,MAAMktB,GAAa,CACjB,eAAkB,EAClB,EAAK,iBACL,gBAAmB,EACnB,EAAK,kBACL,qBAAwB,EACxB,EAAK,uBACL,wBAA2B,EAC3B,EAAK,0BACL,WAAc,EACd,EAAK,aACL,eAAkB,EAClB,EAAK,iBACL,gBAAmB,EACnB,EAAK,kBACL,kBAAqB,GACrB,GAAM,oBACN,iBAAoB,GACpB,GAAM,mBACN,aAAgB,GAChB,GAAM,eACN,uBAA0B,GAC1B,GAAM,yBACN,UAAa,GACb,GAAM,YACN,iBAAoB,GACpB,GAAM,mBACN,oBAAuB,GACvB,GAAM,uBAmCR,SAASC,GAAsBlW,EAAImW,EAAUptB,EAAMqQ,GACjD,IACE,OAAOA,EAAO4G,KAAM5G,GAAQ4G,GAC9B,CAAE,MAAO0I,GACP0N,GAAY1N,EAAKyN,EAAUptB,EAC7B,CACF,CACA,SAASstB,GAA2BrW,EAAImW,EAAUptB,EAAMqQ,GACtD,GAAI,EAAW4G,GAAK,CAClB,MAAMmC,EAAM+T,GAAsBlW,EAAImW,EAAUptB,EAAMqQ,GAMtD,OALI+I,GAAO7C,EAAU6C,IACnBA,EAAI5C,MAAOmJ,IACT0N,GAAY1N,EAAKyN,EAAUptB,KAGxBoZ,CACT,CACA,GAAI,EAAQnC,GAAK,CACf,MAAMtS,EAAS,GACf,IAAK,IAAIiR,EAAI,EAAGA,EAAIqB,EAAG3R,OAAQsQ,IAC7BjR,EAAO6X,KAAK8Q,GAA2BrW,EAAGrB,GAAIwX,EAAUptB,EAAMqQ,IAEhE,OAAO1L,CACT,CAKF,CACA,SAAS0oB,GAAY1N,EAAKyN,EAAUptB,EAAMutB,GAAa,GAChCH,GAAWA,EAASI,MAAzC,MACM,aAAEC,EAAY,gCAAEC,GAAoCN,GAAYA,EAASO,WAAWC,QAAU1Y,EACpG,GAAIkY,EAAU,CACZ,IAAIS,EAAMT,EAAS9Q,OACnB,MAAMwR,EAAkBV,EAAS5D,MAC3BuE,EAAmF,8CAA8C/tB,IACvI,KAAO6tB,GAAK,CACV,MAAMG,EAAqBH,EAAII,GAC/B,GAAID,EACF,IAAK,IAAIpY,EAAI,EAAGA,EAAIoY,EAAmB1oB,OAAQsQ,IAC7C,IAA+D,IAA3DoY,EAAmBpY,GAAG+J,EAAKmO,EAAiBC,GAC9C,OAINF,EAAMA,EAAIvR,MACZ,CACA,GAAImR,EAQF,OAPA,KACAN,GAAsBM,EAAc,KAAM,GAAI,CAC5C9N,EACAmO,EACAC,SAEF,IAGJ,EAGF,SAAkBpO,EAAK3f,EAAMkuB,EAAcX,GAAa,EAAMY,GAAc,GAenE,GAAIA,EACT,MAAMxO,EAENjT,QAAQ4D,MAAMqP,EAElB,CAtBEyO,CAASzO,EAAK3f,EAAMkuB,EAAcX,EAAYG,EAChD,CAuBA,MAAMW,GAAQ,GACd,IAAIC,IAAc,EAClB,MAAMC,GAAsB,GAC5B,IAAIC,GAAqB,KACrBC,GAAiB,EACrB,MAAMC,GAAkCC,QAAQC,UAChD,IAAIC,GAAsB,KAE1B,SAASC,GAAS7X,GAChB,MAAM8X,EAAIF,IAAuBH,GACjC,OAAOzX,EAAK8X,EAAEvqB,KAAK3C,KAAOoV,EAAGgK,KAAKpf,MAAQoV,GAAM8X,CAClD,CAgBA,SAASC,GAASC,GAChB,KAAkB,EAAZA,EAAIlR,OAAY,CACpB,MAAMmR,EAAQC,GAAMF,GACdG,EAAUf,GAAMA,GAAM/oB,OAAS,IAChC8pB,KACS,EAAZH,EAAIlR,QAAcmR,GAASC,GAAMC,GACjCf,GAAM7R,KAAKyS,GAEXZ,GAAM3nB,OAvBZ,SAA4BN,GAC1B,IAAIipB,EAAQf,GAAa,EACrBgB,EAAMjB,GAAM/oB,OAChB,KAAO+pB,EAAQC,GAAK,CAClB,MAAMC,EAASF,EAAQC,IAAQ,EACzBE,EAAYnB,GAAMkB,GAClBE,EAAcN,GAAMK,GACtBC,EAAcrpB,GAAMqpB,IAAgBrpB,GAAwB,EAAlBopB,EAAUzR,MACtDsR,EAAQE,EAAS,EAEjBD,EAAMC,CAEV,CACA,OAAOF,CACT,CASmBK,CAAmBR,GAAQ,EAAGD,GAE7CA,EAAIlR,OAAS,EACb4R,IACF,CACF,CACA,SAASA,KACFd,KACHA,GAAsBH,GAAgBlqB,KAAKorB,IAE/C,CACA,SAASC,GAAiBC,GACnB,EAAQA,GAQXvB,GAAoB/R,QAAQsT,GAPxBtB,KAAiC,IAAXsB,EAAG1pB,GAC3BooB,GAAmB9nB,OAAO+nB,GAAiB,EAAG,EAAGqB,GAC3B,EAAXA,EAAG/R,QACdwQ,GAAoB/R,KAAKsT,GACzBA,EAAG/R,OAAS,GAKhB4R,IACF,CACA,SAASI,GAAiB3C,EAAUP,EAAMjX,EAAI0Y,GAAa,GAIzD,KAAO1Y,EAAIyY,GAAM/oB,OAAQsQ,IAAK,CAC5B,MAAMka,EAAKzB,GAAMzY,GACjB,GAAIka,GAAiB,EAAXA,EAAG/R,MAAW,CACtB,GAAIqP,GAAY0C,EAAG1pB,KAAOgnB,EAAS4C,IACjC,SAKF3B,GAAM3nB,OAAOkP,EAAG,GAChBA,IACe,EAAXka,EAAG/R,QACL+R,EAAG/R,QAAU,GAEf+R,IACiB,EAAXA,EAAG/R,QACP+R,EAAG/R,QAAU,EAEjB,CACF,CACF,CACA,SAASkS,GAAkBpD,GACzB,GAAI0B,GAAoBjpB,OAAQ,CAC9B,MAAM4qB,EAAU,IAAI,IAAIzK,IAAI8I,KAAsB4B,KAChD,CAAChW,EAAGC,IAAM+U,GAAMhV,GAAKgV,GAAM/U,IAG7B,GADAmU,GAAoBjpB,OAAS,EACzBkpB,GAEF,YADAA,GAAmBhS,QAAQ0T,GAO7B,IAJA1B,GAAqB0B,EAIhBzB,GAAiB,EAAGA,GAAiBD,GAAmBlpB,OAAQmpB,KAAkB,CACrF,MAAMqB,EAAKtB,GAAmBC,IAIf,EAAXqB,EAAG/R,QACL+R,EAAG/R,QAAU,GAEE,EAAX+R,EAAG/R,OAAY+R,IACrBA,EAAG/R,QAAU,CACf,CACAyQ,GAAqB,KACrBC,GAAiB,CACnB,CACF,CACA,MAAMU,GAASF,GAAkB,MAAVA,EAAI7oB,GAAyB,EAAZ6oB,EAAIlR,OAAa,EAAI6O,IAAWqC,EAAI7oB,GAC5E,SAASwpB,GAAU/C,GAKjB,IACE,IAAKyB,GAAa,EAAGA,GAAaD,GAAM/oB,OAAQgpB,KAAc,CAC5D,MAAMW,EAAMZ,GAAMC,KACdW,GAAqB,EAAZA,EAAIlR,QAIC,EAAZkR,EAAIlR,QACNkR,EAAIlR,QAAS,GAEfoP,GACE8B,EACAA,EAAIrZ,EACJqZ,EAAIrZ,EAAI,GAAK,IAEG,EAAZqZ,EAAIlR,QACRkR,EAAIlR,QAAS,GAGnB,CACF,CAAE,QACA,KAAOuQ,GAAaD,GAAM/oB,OAAQgpB,KAAc,CAC9C,MAAMW,EAAMZ,GAAMC,IACdW,IACFA,EAAIlR,QAAU,EAElB,CACAuQ,IAAc,EACdD,GAAM/oB,OAAS,EACf2qB,KACApB,GAAsB,MAClBR,GAAM/oB,QAAUipB,GAAoBjpB,SACtCsqB,GAAU/C,EAEd,CACF,CA8IA,IAAIuD,GACAC,GAAS,GACTC,IAAuB,EA2FvBC,GAA2B,KAC3BC,GAAiB,KACrB,SAASC,GAA4BrD,GACnC,MAAMlN,EAAOqQ,GAGb,OAFAA,GAA2BnD,EAC3BoD,GAAiBpD,GAAYA,EAASptB,KAAK0wB,WAAa,KACjDxQ,CACT,CACA,SAASyQ,GAAYvqB,GACnBoqB,GAAiBpqB,CACnB,CACA,SAASwqB,KACPJ,GAAiB,IACnB,CACA,MAAMK,GAAeC,GAAQC,GAC7B,SAASA,GAAQ9Z,EAAI+Z,EAAMT,GAA0BU,GACnD,IAAKD,EAAK,OAAO/Z,EACjB,GAAIA,EAAGia,GACL,OAAOja,EAET,MAAMka,EAAsB,IAAI9gB,KAC1B8gB,EAAoBC,IACtBC,IAAkB,GAEpB,MAAMC,EAAeb,GAA4BO,GACjD,IAAI5X,EACJ,IACEA,EAAMnC,KAAM5G,EACd,CAAE,QACAogB,GAA4Ba,GACxBH,EAAoBC,IACtBC,GAAiB,EAErB,CAIA,OAAOjY,GAKT,OAHA+X,EAAoBD,IAAK,EACzBC,EAAoBI,IAAK,EACzBJ,EAAoBC,IAAK,EAClBD,CACT,CAOA,SAASK,GAAehE,EAAOiE,GAC7B,GAAiC,OAA7BlB,GAEF,OAAO/C,EAET,MAAMJ,EAAWsE,GAA2BnB,IACtCoB,EAAWnE,EAAMoE,OAASpE,EAAMoE,KAAO,IAC7C,IAAK,IAAIhc,EAAI,EAAGA,EAAI6b,EAAWnsB,OAAQsQ,IAAK,CAC1C,IAAKic,EAAKxiB,EAAO2I,EAAK8Z,EAAY5c,GAAauc,EAAW7b,GACtDic,IACE,EAAWA,KACbA,EAAM,CACJjtB,QAASitB,EACTE,QAASF,IAGTA,EAAIG,MACNtF,GAASrd,GAEXsiB,EAASnV,KAAK,CACZqV,MACAzE,WACA/d,QACAuI,cAAU,EACVI,MACA8Z,cAGN,CACA,OAAOtE,CACT,CACA,SAASyE,GAAoBzE,EAAO0E,EAAW9E,EAAUvtB,GACvD,MAAM8xB,EAAWnE,EAAMoE,KACjBO,EAAcD,GAAaA,EAAUN,KAC3C,IAAK,IAAIhc,EAAI,EAAGA,EAAI+b,EAASrsB,OAAQsQ,IAAK,CACxC,MAAMwc,EAAUT,EAAS/b,GACrBuc,IACFC,EAAQxa,SAAWua,EAAYvc,GAAGvG,OAEpC,IAAIgjB,EAAOD,EAAQP,IAAIhyB,GACnBwyB,IACF,KACA/E,GAA2B+E,EAAMjF,EAAU,EAAG,CAC5CI,EAAM7X,GACNyc,EACA5E,EACA0E,IAEF,KAEJ,CACF,CAEA,MAAMI,GAAiBzQ,OAAO,QACxB0Q,GAAcvyB,GAASA,EAAKwyB,aAC5BC,GAAsB3yB,GAAUA,IAAUA,EAAM4yB,UAA+B,KAAnB5yB,EAAM4yB,UAClEC,GAAsB7yB,GAAUA,IAAUA,EAAM8yB,OAAyB,KAAhB9yB,EAAM8yB,OAC/DC,GAAe7tB,GAAiC,oBAAf8tB,YAA8B9tB,aAAkB8tB,WACjFC,GAAkB/tB,GAAoC,mBAAlBguB,eAAgChuB,aAAkBguB,cACtFC,GAAgB,CAACnzB,EAAOozB,KAC5B,MAAMC,EAAiBrzB,GAASA,EAAM8O,GACtC,OAAI,EAASukB,GACND,EAMYA,EAAOC,GAFf,KAcFA,GAGLC,GAAe,CACnBvzB,KAAM,WACN2yB,cAAc,EACd,OAAAa,CAAQC,EAAIC,EAAIC,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,EAAWC,GACtG,MACEC,GAAIC,EACJC,GAAIC,EACJC,IAAKC,EACLC,GAAG,OAAEC,EAAM,cAAEziB,EAAa,WAAE0iB,EAAU,cAAEC,IACtCV,EACErB,EAAWD,GAAmBc,EAAGzzB,OACvC,IAAI,UAAE40B,EAAS,SAAEC,EAAQ,gBAAEC,GAAoBrB,EAK/C,GAAU,MAAND,EAAY,CACd,MAAMuB,EAActB,EAAG5d,GAAmF6e,EAAW,IAC/GM,EAAavB,EAAGE,OAAqFe,EAAW,IACtHD,EAAOM,EAAarB,EAAWC,GAC/Bc,EAAOO,EAAYtB,EAAWC,GAC9B,MAAM/e,EAAQ,CAACqgB,EAAYC,KACT,GAAZN,GACFT,EACEU,EACAI,EACAC,EACAtB,EACAC,EACAC,EACAC,EACAC,IAIAmB,EAAgB,KACpB,MAAMjwB,EAASuuB,EAAGvuB,OAASiuB,GAAcM,EAAGzzB,MAAOgS,GAC7CojB,EAAeC,GAAcnwB,EAAQuuB,EAAIiB,EAAYD,GACvDvvB,IACgB,QAAd4uB,GAAuBf,GAAY7tB,GACrC4uB,EAAY,MACW,WAAdA,GAA0Bb,GAAe/tB,KAClD4uB,EAAY,UAEVF,GAAmBA,EAAgB0B,OACpC1B,EAAgB2B,GAAGC,mBAAqB5B,EAAgB2B,GAAGC,iBAAmC,IAAI7P,MAAQ/a,IAAI1F,GAE5G0tB,IACHhe,EAAM1P,EAAQkwB,GACdK,GAAchC,GAAI,MAUpBb,IACFhe,EAAM8e,EAAWsB,GACjBS,GAAchC,GAAI,IAEhBZ,GAAmBY,EAAGzzB,QACxByzB,EAAG5d,GAAG6f,aAAc,EACpBC,GAAsB,KACpBR,WACO1B,EAAG5d,GAAG6f,aACZ7B,IAEHsB,GAEJ,KAAO,CACL,GAAItC,GAAmBY,EAAGzzB,SAAgC,IAAtBwzB,EAAG3d,GAAG6f,YAexC,YAdAC,GAAsB,KACpBrC,GAAaC,QACXC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,IAEDJ,GAGLJ,EAAG5d,GAAK2d,EAAG3d,GACX4d,EAAGmC,YAAcpC,EAAGoC,YACpB,MAAMZ,EAAavB,EAAGE,OAASH,EAAGG,OAC5BzuB,EAASuuB,EAAGvuB,OAASsuB,EAAGtuB,OACxBkwB,EAAe3B,EAAG2B,aAAe5B,EAAG4B,aACpCS,EAAclD,GAAmBa,EAAGxzB,OACpC81B,EAAmBD,EAAcnC,EAAYxuB,EAC7C6wB,EAAgBF,EAAcb,EAAaI,EA8BjD,GA7BkB,QAAdtB,GAAuBf,GAAY7tB,GACrC4uB,EAAY,OACW,WAAdA,GAA0Bb,GAAe/tB,MAClD4uB,EAAY,UAEVgB,GACFP,EACEf,EAAGsB,gBACHA,EACAgB,EACAlC,EACAC,EACAC,EACAC,GAEFiC,GAAuBxC,EAAIC,GAAI,IACrBO,GACVK,EACEb,EACAC,EACAqC,EACAC,EACAnC,EACAC,EACAC,EACAC,GACA,GAGAnB,EACGiD,EASCpC,EAAGzzB,OAASwzB,EAAGxzB,OAASyzB,EAAGzzB,MAAM8O,KAAO0kB,EAAGxzB,MAAM8O,KACnD2kB,EAAGzzB,MAAM8O,GAAK0kB,EAAGxzB,MAAM8O,IATzBmnB,GACExC,EACAC,EACAsB,EACAf,EACA,QAQJ,IAAKR,EAAGzzB,OAASyzB,EAAGzzB,MAAM8O,OAAS0kB,EAAGxzB,OAASwzB,EAAGxzB,MAAM8O,IAAK,CAC3D,MAAMonB,EAAazC,EAAGvuB,OAASiuB,GAC7BM,EAAGzzB,MACHgS,GAEEkkB,GACFD,GACExC,EACAyC,EACA,KACAjC,EACA,EASN,MAAW4B,GACTI,GACExC,EACAvuB,EACAkwB,EACAnB,EACA,GAINwB,GAAchC,EAAIb,EACpB,CACF,EACA,MAAAjoB,CAAO+iB,EAAOkG,EAAiBC,GAAkBsC,GAAIC,EAAS5B,GAAK7pB,OAAQ0rB,IAAgBC,GACzF,MAAM,UACJ1B,EAAS,SACTC,EAAQ,OACRlB,EAAM,YACNiC,EAAW,aACXR,EAAY,OACZlwB,EAAM,MACNlF,GACE0tB,EAMJ,GALIxoB,IACFmxB,EAAWT,GACXS,EAAWjB,IAEbkB,GAAYD,EAAW1C,GACP,GAAZiB,EAAgB,CAClB,MAAM2B,EAAeD,IAAa3D,GAAmB3yB,GACrD,IAAK,IAAI8V,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACvBsgB,EACEI,EACA5C,EACAC,EACA0C,IACEC,EAAM1B,gBAEZ,CACF,CACF,EACA2B,KAAMR,GACNS,QA2BF,SAAyBC,EAAMjJ,EAAOkG,EAAiBC,EAAgBE,EAAcC,GACnFQ,GAAG,YAAEoC,EAAW,WAAEC,EAAU,cAAE7kB,EAAa,OAAEyiB,EAAM,WAAEC,IACpDoC,GACD,SAASC,EAAwBC,EAAOC,EAAQrB,EAAaR,GAC3D6B,EAAOtD,OAASmD,EACdF,EAAYI,GACZC,EACAJ,EAAWG,GACXpD,EACAC,EACAE,EACAC,GAEFiD,EAAOrB,YAAcA,EACrBqB,EAAO7B,aAAeA,CACxB,CACA,MAAMlwB,EAASwoB,EAAMxoB,OAASiuB,GAC5BzF,EAAM1tB,MACNgS,GAEI4gB,EAAWD,GAAmBjF,EAAM1tB,OAC1C,GAAIkF,EAAQ,CACV,MAAMgyB,EAAahyB,EAAOiyB,MAAQjyB,EAAOkyB,WACzC,GAAsB,GAAlB1J,EAAMkH,UACR,GAAIhC,EACFmE,EACEJ,EACAjJ,EACAwJ,EACAA,GAAcN,EAAYM,QAEvB,CACLxJ,EAAMiG,OAASiD,EAAYD,GAC3B,IAAIvB,EAAe8B,EACnB,KAAO9B,GAAc,CACnB,GAAIA,GAA0C,IAA1BA,EAAaiC,SAC/B,GAA0B,0BAAtBjC,EAAav0B,KACf6sB,EAAMkI,YAAcR,OACf,GAA0B,oBAAtBA,EAAav0B,KAA4B,CAClD6sB,EAAM0H,aAAeA,EACrBlwB,EAAOiyB,KAAOzJ,EAAM0H,cAAgBwB,EAAYlJ,EAAM0H,cACtD,KACF,CAEFA,EAAewB,EAAYxB,EAC7B,CACK1H,EAAM0H,cACTC,GAAcnwB,EAAQwoB,EAAOgH,EAAYD,GAE3CqC,EACEI,GAAcN,EAAYM,GAC1BxJ,EACAxoB,EACA0uB,EACAC,EACAE,EACAC,EAEJ,CAEFyB,GAAc/H,EAAOkF,EACvB,MAAWA,GACa,GAAlBlF,EAAMkH,WACRmC,EAAwBJ,EAAMjJ,EAAOiJ,EAAMC,EAAYD,IAG3D,OAAOjJ,EAAMiG,QAAUiD,EAAYlJ,EAAMiG,OAC3C,GA5FA,SAASsC,GAAavI,EAAOgG,EAAW4D,GAAgB9C,GAAG,OAAEC,GAAU8C,EAAGd,GAAQe,EAAW,GAC1E,IAAbA,GACF/C,EAAO/G,EAAM0H,aAAc1B,EAAW4D,GAExC,MAAM,GAAEzhB,EAAE,OAAE8d,EAAM,UAAEiB,EAAS,SAAEC,EAAQ,MAAE70B,GAAU0tB,EAC7C+J,EAAyB,IAAbD,EAIlB,GAHIC,GACFhD,EAAO5e,EAAI6d,EAAW4D,KAEnBG,GAAa9E,GAAmB3yB,KACnB,GAAZ40B,EACF,IAAK,IAAI9e,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IACnC2gB,EACE5B,EAAS/e,GACT4d,EACA4D,EACA,GAKJG,GACFhD,EAAOd,EAAQD,EAAW4D,EAE9B,CAqEA,MAAMI,GAAWpE,GACjB,SAASmC,GAAc/H,EAAOiK,GAC5B,MAAMzG,EAAMxD,EAAMwD,IAClB,GAAIA,GAAOA,EAAI0G,GAAI,CACjB,IAAIjB,EAAMhD,EAQV,IAPIgE,GACFhB,EAAOjJ,EAAM7X,GACb8d,EAASjG,EAAMiG,SAEfgD,EAAOjJ,EAAMkI,YACbjC,EAASjG,EAAM0H,cAEVuB,GAAQA,IAAShD,GACA,IAAlBgD,EAAKU,UAAgBV,EAAKkB,aAAa,eAAgB3G,EAAIhB,KAC/DyG,EAAOA,EAAKC,YAEd1F,EAAI0G,IACN,CACF,CACA,SAASvC,GAAcnwB,EAAQwoB,EAAOgH,EAAYD,GAChD,MAAMmB,EAAclI,EAAMkI,YAAclB,EAAW,IAC7CU,EAAe1H,EAAM0H,aAAeV,EAAW,IAMrD,OALAkB,EAAYpD,IAAkB4C,EAC1BlwB,IACFuvB,EAAOmB,EAAa1wB,GACpBuvB,EAAOW,EAAclwB,IAEhBkwB,CACT,CAEA,MAAM0C,GAAa/V,OAAO,YACpBgW,GAAahW,OAAO,YAC1B,SAASiW,KACP,MAAMC,EAAQ,CACZC,WAAW,EACXC,WAAW,EACXC,cAAc,EACdC,cAA+B,IAAIjW,KAQrC,OANAkW,GAAU,KACRL,EAAMC,WAAY,IAEpBK,GAAgB,KACdN,EAAMG,cAAe,IAEhBH,CACT,CACA,MAAMO,GAA0B,CAACC,SAAUl1B,OACrCm1B,GAAgC,CACpCC,KAAMj4B,OACNk4B,OAAQz4B,QACR04B,UAAW14B,QAEX24B,cAAeN,GACfO,QAASP,GACTQ,aAAcR,GACdS,iBAAkBT,GAElBU,cAAeV,GACfW,QAASX,GACTY,aAAcZ,GACda,iBAAkBb,GAElBc,eAAgBd,GAChBe,SAAUf,GACVgB,cAAehB,GACfiB,kBAAmBjB,IAEfkB,GAAuBpM,IAC3B,MAAMqM,EAAUrM,EAASqM,QACzB,OAAOA,EAAQrmB,UAAYomB,GAAoBC,EAAQrmB,WAAaqmB,GAsFtE,SAASC,GAAoB/E,GAC3B,IAAI2B,EAAQ3B,EAAS,GACrB,GAAIA,EAASrvB,OAAS,EAAG,CACvB,IAAIq0B,GAAW,EACf,IAAK,MAAMviB,KAAKud,EACd,GAAIvd,EAAEpX,OAAS45B,GAAS,CAOtBtD,EAAQlf,EACRuiB,GAAW,EACqC,KAClD,CAEJ,CACA,OAAOrD,CACT,CACA,MAAMuD,GAxGqB,CACzBh6B,KAAM,iBACNC,MAAO04B,GACP,KAAA1lB,CAAMhT,GAAO,MAAEg6B,IACb,MAAM1M,EAAW2M,KACXhC,EAAQD,KACd,MAAO,KACL,MAAMnD,EAAWmF,EAAM55B,SAAW85B,GAAyBF,EAAM55B,WAAW,GAC5E,IAAKy0B,IAAaA,EAASrvB,OACzB,OAEF,MAAMgxB,EAAQoD,GAAoB/E,GAC5BsF,EAAW,GAAMn6B,IACjB,KAAE24B,GAASwB,EAIjB,GAAIlC,EAAME,UACR,OAAOiC,GAAiB5D,GAE1B,MAAM6D,EAAaC,GAAgB9D,GACnC,IAAK6D,EACH,OAAOD,GAAiB5D,GAE1B,IAAI+D,EAAaC,GACfH,EACAF,EACAlC,EACA3K,EAECmN,GAAUF,EAAaE,GAEtBJ,EAAWn6B,OAAS45B,IACtBY,GAAmBL,EAAYE,GAEjC,IAAII,EAAgBrN,EAASqM,SAAWW,GAAgBhN,EAASqM,SACjE,GAAIgB,GAAiBA,EAAcz6B,OAAS45B,KAAYc,GAAgBD,EAAeN,IAAeX,GAAoBpM,GAAUptB,OAAS45B,GAAS,CACpJ,IAAIe,EAAeL,GACjBG,EACAR,EACAlC,EACA3K,GAGF,GADAoN,GAAmBC,EAAeE,GACrB,WAATlC,GAAqB0B,EAAWn6B,OAAS45B,GAU3C,OATA7B,EAAME,WAAY,EAClB0C,EAAaC,WAAa,KACxB7C,EAAME,WAAY,EACS,EAArB7K,EAAS6B,IAAIlR,OACjBqP,EAASyN,gBAEJF,EAAaC,WACpBH,OAAgB,GAEXP,GAAiB5D,GACN,WAATmC,GAAqB0B,EAAWn6B,OAAS45B,GAClDe,EAAaG,WAAa,CAACnlB,EAAIolB,EAAaC,KACfC,GACzBlD,EACA0C,GAEiBj6B,OAAOi6B,EAAc9zB,MAAQ8zB,EAChD9kB,EAAGiiB,IAAc,KACfmD,IACAplB,EAAGiiB,SAAc,SACVyC,EAAWW,aAClBP,OAAgB,GAElBJ,EAAWW,aAAe,KACxBA,WACOX,EAAWW,aAClBP,OAAgB,IAIpBA,OAAgB,CAEpB,MAAWA,IACTA,OAAgB,GAElB,OAAOnE,EAEX,GAuBF,SAAS2E,GAAuBlD,EAAOvK,GACrC,MAAM,cAAE2K,GAAkBJ,EAC1B,IAAImD,EAAqB/C,EAAc5zB,IAAIipB,EAAMxtB,MAKjD,OAJKk7B,IACHA,EAAqC14B,OAAOyS,OAAO,MACnDkjB,EAAclW,IAAIuL,EAAMxtB,KAAMk7B,IAEzBA,CACT,CACA,SAASZ,GAAuB9M,EAAO1tB,EAAOi4B,EAAO3K,EAAU+N,GAC7D,MAAM,OACJzC,EAAM,KACND,EAAI,UACJE,GAAY,EAAK,cACjBC,EAAa,QACbC,EAAO,aACPC,EAAY,iBACZC,EAAgB,cAChBC,EAAa,QACbC,EAAO,aACPC,EAAY,iBACZC,EAAgB,eAChBC,EAAc,SACdC,EAAQ,cACRC,EAAa,kBACbC,GACEz5B,EACE6G,EAAMnG,OAAOgtB,EAAM7mB,KACnBu0B,EAAqBD,GAAuBlD,EAAOvK,GACnD4N,EAAW,CAAC/I,EAAMhiB,KACtBgiB,GAAQ/E,GACN+E,EACAjF,EACA,EACA/c,IAGEgrB,EAAgB,CAAChJ,EAAMhiB,KAC3B,MAAMyU,EAAOzU,EAAK,GAClB+qB,EAAS/I,EAAMhiB,GACX,EAAQgiB,GACNA,EAAKlP,MAAOmY,GAAUA,EAAMh2B,QAAU,IAAIwf,IACrCuN,EAAK/sB,QAAU,GACxBwf,KAGEyV,EAAQ,CACZ9B,OACAE,YACA,WAAA4C,CAAY5lB,GACV,IAAI0c,EAAOuG,EACX,IAAKb,EAAMC,UAAW,CACpB,IAAIU,EAGF,OAFArG,EAAO+G,GAAkBR,CAI7B,CACIjjB,EAAGiiB,KACLjiB,EAAGiiB,KACD,GAIJ,MAAM4D,EAAeN,EAAmBv0B,GACpC60B,GAAgBd,GAAgBlN,EAAOgO,IAAiBA,EAAa7lB,GAAGiiB,KAC1E4D,EAAa7lB,GAAGiiB,MAElBwD,EAAS/I,EAAM,CAAC1c,GAClB,EACA,KAAA8lB,CAAM9lB,GACJ,IAAI0c,EAAOwG,EACP6C,EAAY5C,EACZ6C,EAAa5C,EACjB,IAAKhB,EAAMC,UAAW,CACpB,IAAIU,EAKF,OAJArG,EAAOgH,GAAYR,EACnB6C,EAAYpC,GAAiBR,EAC7B6C,EAAapC,GAAqBR,CAItC,CACA,IAAI6C,GAAS,EACb,MAAM9W,EAAOnP,EAAGkiB,IAAegE,IACzBD,IACJA,GAAS,EAEPR,EADES,EACOF,EAEAD,EAFY,CAAC/lB,IAIpB4kB,EAAMS,cACRT,EAAMS,eAERrlB,EAAGkiB,SAAc,IAEfxF,EACFgJ,EAAchJ,EAAM,CAAC1c,EAAImP,IAEzBA,GAEJ,EACA,KAAAgX,CAAMnmB,EAAIlL,GACR,MAAM8X,EAAO/hB,OAAOgtB,EAAM7mB,KAO1B,GANIgP,EAAGkiB,KACLliB,EAAGkiB,KACD,GAIAE,EAAMG,aACR,OAAOztB,IAET2wB,EAASpC,EAAe,CAACrjB,IACzB,IAAIimB,GAAS,EACb,MAAM9W,EAAOnP,EAAGiiB,IAAeiE,IACzBD,IACJA,GAAS,EACTnxB,IAEE2wB,EADES,EACO1C,EAEAD,EAFkB,CAACvjB,IAI9BA,EAAGiiB,SAAc,EACbsD,EAAmB3Y,KAAUiL,UACxB0N,EAAmB3Y,KAG9B2Y,EAAmB3Y,GAAQiL,EACvByL,EACFoC,EAAcpC,EAAS,CAACtjB,EAAImP,IAE5BA,GAEJ,EACA,KAAAiX,CAAMhF,GACJ,MAAMiF,EAAS1B,GACbvD,EACAj3B,EACAi4B,EACA3K,EACA+N,GAGF,OADIA,GAAWA,EAAUa,GAClBA,CACT,GAEF,OAAOzB,CACT,CACA,SAASL,GAAiB1M,GACxB,GAAIyO,GAAYzO,GAGd,OAFAA,EAAQ0O,GAAW1O,IACbmH,SAAW,KACVnH,CAEX,CACA,SAAS4M,GAAgB5M,GACvB,IAAKyO,GAAYzO,GACf,OAAI+E,GAAW/E,EAAMxtB,OAASwtB,EAAMmH,SAC3B+E,GAAoBlM,EAAMmH,UAE5BnH,EAET,GAAIA,EAAMpa,UACR,OAAOoa,EAAMpa,UAAUqmB,QAEzB,MAAM,UAAE/E,EAAS,SAAEC,GAAanH,EAChC,GAAImH,EAAU,CACZ,GAAgB,GAAZD,EACF,OAAOC,EAAS,GAElB,GAAgB,GAAZD,GAAkB,EAAWC,EAASz0B,SACxC,OAAOy0B,EAASz0B,SAEpB,CACF,CACA,SAASs6B,GAAmBhN,EAAO+M,GACX,EAAlB/M,EAAMkH,WAAiBlH,EAAMpa,WAC/Boa,EAAM2O,WAAa5B,EACnBC,GAAmBhN,EAAMpa,UAAUqmB,QAASc,IACjB,IAAlB/M,EAAMkH,WACflH,EAAM4O,UAAUD,WAAa5B,EAAMwB,MAAMvO,EAAM4O,WAC/C5O,EAAM6O,WAAWF,WAAa5B,EAAMwB,MAAMvO,EAAM6O,aAEhD7O,EAAM2O,WAAa5B,CAEvB,CACA,SAASP,GAAyBrF,EAAU2H,GAAc,EAAOC,GAC/D,IAAI5iB,EAAM,GACN6iB,EAAqB,EACzB,IAAK,IAAI5mB,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,IAAI0gB,EAAQ3B,EAAS/e,GACrB,MAAMjP,EAAmB,MAAb41B,EAAoBjG,EAAM3vB,IAAMnG,OAAO+7B,GAAa/7B,OAAoB,MAAb81B,EAAM3vB,IAAc2vB,EAAM3vB,IAAMiP,GACnG0gB,EAAMt2B,OAASy8B,IACK,IAAlBnG,EAAMoG,WAAiBF,IAC3B7iB,EAAMA,EAAIsJ,OACR+W,GAAyB1D,EAAM3B,SAAU2H,EAAa31B,MAE/C21B,GAAehG,EAAMt2B,OAAS45B,KACvCjgB,EAAI6C,KAAY,MAAP7V,EAAcu1B,GAAW5F,EAAO,CAAE3vB,QAAS2vB,EAExD,CACA,GAAIkG,EAAqB,EACvB,IAAK,IAAI5mB,EAAI,EAAGA,EAAI+D,EAAIrU,OAAQsQ,IAC9B+D,EAAI/D,GAAG8mB,WAAa,EAGxB,OAAO/iB,CACT,CAGA,SAASgjB,GAAgBzpB,EAAS0pB,GAChC,OAAO,EAAW1pB,GAGA,KAAO,EAAO,CAAErT,KAAMqT,EAAQrT,MAAQ+8B,EAAc,CAAE9pB,MAAOI,IAHlD,GAIzBA,CACN,CAEA,SAAS2pB,KACP,MAAMjnB,EAAImkB,KACV,OAAInkB,GACMA,EAAE+X,WAAWC,OAAOkP,UAAY,KAAO,IAAMlnB,EAAEmnB,IAAI,GAAKnnB,EAAEmnB,IAAI,KAMjE,EACT,CACA,SAASC,GAAkB5P,GACzBA,EAAS2P,IAAM,CAAC3P,EAAS2P,IAAI,GAAK3P,EAAS2P,IAAI,KAAO,IAAK,EAAG,EAChE,CAGA,SAASE,GAAet2B,GACtB,MAAMiP,EAAImkB,KACJnQ,EAAIG,GAAW,MACrB,GAAInU,EAAG,CACL,MAAMsnB,EAAOtnB,EAAEsnB,OAAShoB,EAAYU,EAAEsnB,KAAO,CAAC,EAAItnB,EAAEsnB,KAKlD16B,OAAO4V,eAAe8kB,EAAMv2B,EAAK,CAC/B2R,YAAY,EACZ/T,IAAK,IAAMqlB,EAAEva,MACb4S,IAAMhT,GAAQ2a,EAAEva,MAAQJ,GAG9B,CASA,OAJsE2a,CAKxE,CAEA,MAAMuT,GAAmC,IAAIxb,QAC7C,SAASyb,GAAOC,EAAQC,EAAW3J,EAAgBnG,EAAO+P,GAAY,GACpE,GAAI,EAAQF,GAUV,YATAA,EAAO9yB,QACL,CAACqf,EAAGhU,IAAMwnB,GACRxT,EACA0T,IAAc,EAAQA,GAAaA,EAAU1nB,GAAK0nB,GAClD3J,EACAnG,EACA+P,IAKN,GAAIC,GAAehQ,KAAW+P,EAI5B,YAHsB,IAAlB/P,EAAMkH,WAAmBlH,EAAMxtB,KAAKy9B,iBAAmBjQ,EAAMpa,UAAUqmB,QAAQrmB,WACjFgqB,GAAOC,EAAQC,EAAW3J,EAAgBnG,EAAMpa,UAAUqmB,UAI9D,MAAMiE,EAA6B,EAAlBlQ,EAAMkH,UAAgBhD,GAA2BlE,EAAMpa,WAAaoa,EAAM7X,GACrFtG,EAAQkuB,EAAY,KAAOG,GACzB9nB,EAAG6W,EAAO7C,EAAGC,GAAQwT,EAOvBM,EAASL,GAAaA,EAAU1T,EAChCsT,EAAOzQ,EAAMyQ,OAAShoB,EAAYuX,EAAMyQ,KAAO,CAAC,EAAIzQ,EAAMyQ,KAC1DU,EAAanR,EAAMmR,WACnBC,EAAgB,GAAMD,GACtBE,EAAiBF,IAAe1oB,EAAYE,EAAMzO,GAW/CoP,EAAO8nB,EAAel3B,GAK/B,GAAc,MAAVg3B,GAAkBA,IAAW9T,EAE/B,GADAkU,GAAwBT,GACpB,EAASK,GACXT,EAAKS,GAAU,KACXG,EAAeH,KACjBC,EAAWD,GAAU,WAElB,GAAI,GAAMA,GAAS,CAEtBA,EAAOtuB,MAAQ,KAEjB,MAAM2uB,EAAgBV,EAClBU,EAAcC,IAAGf,EAAKc,EAAcC,GAAK,KAC/C,CAEF,GAAI,EAAWpU,GACbsD,GAAsBtD,EAAK4C,EAAO,GAAI,CAACpd,EAAO6tB,QACzC,CACL,MAAMgB,EAAY,EAASrU,GACrBsU,EAAS,GAAMtU,GACrB,GAAIqU,GAAaC,EAAQ,CACvB,MAAMC,EAAQ,KACZ,GAAIf,EAAOgB,EAAG,CACZ,MAAMC,EAAWJ,EAAYJ,EAAejU,GAAO+T,EAAW/T,GAAOqT,EAAKrT,GAAqCA,EAAIxa,MACnH,GAAIkuB,EACF,EAAQe,IAAa7zB,EAAO6zB,EAAUZ,QAEtC,GAAK,EAAQY,GAaDA,EAAS3a,SAAS+Z,IAC5BY,EAAS9hB,KAAKkhB,QAbd,GAAIQ,EACFhB,EAAKrT,GAAO,CAAC6T,GACTI,EAAejU,KACjB+T,EAAW/T,GAAOqT,EAAKrT,QAEpB,CACL,MAAMmB,EAAS,CAAC0S,GAEd7T,EAAIxa,MAAQ2b,EAEVqS,EAAOY,IAAGf,EAAKG,EAAOY,GAAKjT,EACjC,CAKN,MAAWkT,GACThB,EAAKrT,GAAOxa,EACRyuB,EAAejU,KACjB+T,EAAW/T,GAAOxa,IAEX8uB,IAEPtU,EAAIxa,MAAQA,EAEVguB,EAAOY,IAAGf,EAAKG,EAAOY,GAAK5uB,KAKnC,GAAIA,EAAO,CACT,MAAM4f,EAAM,KACVmP,IACAjB,GAAiB/e,OAAOif,IAE1BpO,EAAI7oB,IAAM,EACV+2B,GAAiBlb,IAAIob,EAAQpO,GAC7BwG,GAAsBxG,EAAK0E,EAC7B,MACEoK,GAAwBV,GACxBe,GAEJ,CAGF,CACF,CACA,SAASL,GAAwBV,GAC/B,MAAMkB,EAAgBpB,GAAiB54B,IAAI84B,GACvCkB,IACFA,EAAcxgB,OAAS,EACvBof,GAAiB/e,OAAOif,GAE5B,CAEA,IAAImB,IAAyB,EAC7B,MAAMC,GAAmB,KACnBD,KAGJ9xB,QAAQ4D,MAAM,gDACdkuB,IAAyB,IAIrBE,GAAoBlL,IACxB,GAA2B,IAAvBA,EAAU2D,SACd,MAJqB,CAAC3D,GAAcA,EAAUmL,aAAahb,SAAS,QAAgC,kBAAtB6P,EAAUoL,QAIpFC,CAAerL,GAAmB,MAHd,CAACA,GAAcA,EAAUmL,aAAahb,SAAS,UAInEmb,CAAkBtL,GAAmB,cAAzC,GAGIuL,GAAatI,GAA2B,IAAlBA,EAAKU,SACjC,SAAS6H,GAAyBC,GAChC,MACEC,GAAIC,EACJpQ,EAAGqQ,EACH9K,GAAG,UACD+K,EAAS,WACT7K,EAAU,YACVkC,EAAW,WACXC,EAAU,OACVlsB,EAAM,OACN8pB,EAAM,cACNE,IAEAwK,EAeEK,EAAc,CAAC7I,EAAMjJ,EAAOkG,EAAiBC,EAAgBE,EAAcC,GAAY,KAC3FA,EAAYA,KAAetG,EAAMoH,gBACjC,MAAM2K,EAAkBR,GAAUtI,IAAuB,MAAdA,EAAK91B,KAC1C6+B,EAAa,IAAMC,EACvBhJ,EACAjJ,EACAkG,EACAC,EACAE,EACA0L,IAEI,KAAEv/B,EAAI,IAAE6pB,EAAG,UAAE6K,EAAS,UAAEgI,GAAclP,EAC5C,IAAIkS,EAAUjJ,EAAKU,SACnB3J,EAAM7X,GAAK8gB,GAKQ,IAAfiG,IACF5I,GAAY,EACZtG,EAAMoH,gBAAkB,MAE1B,IAAI+K,EAAW,KACf,OAAQ3/B,GACN,KAAK4/B,GACa,IAAZF,EACqB,KAAnBlS,EAAMmH,UACRJ,EAAO/G,EAAM7X,GAAK6e,EAAW,IAAKmC,EAAWF,GAAOA,GACpDkJ,EAAWlJ,GAEXkJ,EAAWH,KAGT/I,EAAK91B,OAAS6sB,EAAMmH,WAUtB8J,KACAhI,EAAK91B,KAAO6sB,EAAMmH,UAEpBgL,EAAWjJ,EAAYD,IAEzB,MACF,KAAKmD,GACCiG,EAAepJ,IACjBkJ,EAAWjJ,EAAYD,GACvBqJ,EACEtS,EAAM7X,GAAK8gB,EAAK1qB,QAAQmrB,WACxBT,EACA/C,IAGFiM,EADqB,IAAZD,GAAiBH,EACfC,IAEA9I,EAAYD,GAEzB,MACF,KAAKsJ,GAKH,GAJIR,IAEFG,GADAjJ,EAAOC,EAAYD,IACJU,UAED,IAAZuI,GAA6B,IAAZA,EAAe,CAClCC,EAAWlJ,EACX,MAAMuJ,GAAsBxS,EAAMmH,SAASrvB,OAC3C,IAAK,IAAIsQ,EAAI,EAAGA,EAAI4X,EAAMyS,YAAarqB,IACjCoqB,IACFxS,EAAMmH,UAAkC,IAAtBgL,EAASxI,SAAiBwI,EAASO,UAAYP,EAASh/B,MACxEiV,IAAM4X,EAAMyS,YAAc,IAC5BzS,EAAMiG,OAASkM,GAEjBA,EAAWjJ,EAAYiJ,GAEzB,OAAOJ,EAAkB7I,EAAYiJ,GAAYA,CACnD,CACEH,IAEF,MACF,KAAK/C,GAIDkD,EAHGJ,EAGQY,EACT1J,EACAjJ,EACAkG,EACAC,EACAE,EACAC,GARS0L,IAWb,MACF,QACE,GAAgB,EAAZ9K,EAIAiL,EAHe,IAAZD,GAAiBlS,EAAMxtB,KAAKwX,gBAAkBif,EAAKmI,QAAQpnB,eAAmBqoB,EAAepJ,GAGrF2J,EACT3J,EACAjJ,EACAkG,EACAC,EACAE,EACAC,GARS0L,SAWR,GAAgB,EAAZ9K,EAAe,CACxBlH,EAAMqG,aAAeA,EACrB,MAAML,EAAYmD,EAAWF,GAiB7B,GAfEkJ,EADEJ,EACSc,EAAoB5J,GACtBsI,GAAUtI,IAAuB,mBAAdA,EAAK91B,KACtB0/B,EAAoB5J,EAAMA,EAAK91B,KAAM,gBAErC+1B,EAAYD,GAEzB0I,EACE3R,EACAgG,EACA,KACAE,EACAC,EACA+K,GAAiBlL,GACjBM,GAEE0J,GAAehQ,KAAWA,EAAMxtB,KAAKy9B,gBAAiB,CACxD,IAAIhE,EACA8F,GACF9F,EAAU6G,GAAY7D,IACtBhD,EAAQhG,OAASkM,EAAWA,EAASY,gBAAkB/M,EAAUgN,WAEjE/G,EAA4B,IAAlBhD,EAAKU,SAAiBsJ,GAAgB,IAAMH,GAAY,OAEpE7G,EAAQ9jB,GAAK8gB,EACbjJ,EAAMpa,UAAUqmB,QAAUA,CAC5B,CACF,MAAuB,GAAZ/E,EAEPiL,EADc,IAAZD,EACSF,IAEAhS,EAAMxtB,KAAKw2B,QACpBC,EACAjJ,EACAkG,EACAC,EACAE,EACAC,EACAmL,EACArI,GAGiB,IAAZlC,IACTiL,EAAWnS,EAAMxtB,KAAKw2B,QACpBC,EACAjJ,EACAkG,EACAC,EACA+K,GAAiB/H,EAAWF,IAC5B5C,EACAC,EACAmL,EACAK,IASR,OAHW,MAAPzV,GACFuT,GAAOvT,EAAK,KAAM8J,EAAgBnG,GAE7BmS,GAEHS,EAAiB,CAACzqB,EAAI6X,EAAOkG,EAAiBC,EAAgBE,EAAcC,KAChFA,EAAYA,KAAetG,EAAMoH,gBACjC,MAAM,KAAE50B,EAAI,MAAEF,EAAK,UAAE48B,EAAS,UAAEhI,EAAS,KAAE9C,EAAI,WAAEuK,GAAe3O,EAC1DkT,EAAsB,UAAT1gC,GAA6B,WAATA,EACvC,GAAiD0gC,IAA6B,IAAfhE,EAAkB,CAC3E9K,GACFK,GAAoBzE,EAAO,KAAMkG,EAAiB,WAEpD,IA2FIiN,EA3FAC,GAA0B,EAC9B,GAAIf,EAAelqB,GAAK,CACtBirB,EAA0BC,GACxB,KAEA1E,IACGzI,GAAmBA,EAAgBlG,MAAM1tB,OAAS4zB,EAAgBlG,MAAM1tB,MAAM44B,OACnF,MAAM3sB,EAAU4J,EAAG5J,QAAQmrB,WAC3B,GAAI0J,EAAyB,CAC3B,MAAME,EAAM/0B,EAAQg1B,aAAa,SAC7BD,IAAK/0B,EAAQi1B,KAAOF,GACxB3E,EAAWZ,YAAYxvB,EACzB,CACA+zB,EAAY/zB,EAAS4J,EAAI+d,GACzBlG,EAAM7X,GAAKA,EAAK5J,CAClB,CACA,GAAgB,GAAZ2oB,KACF50B,IAAUA,EAAMyQ,YAAazQ,EAAMmhC,aAAe,CAClD,IAAIjjB,EAAO4Y,EACTjhB,EAAGuhB,WACH1J,EACA7X,EACA+d,EACAC,EACAE,EACAC,GAGF,KAAO9V,GAAM,CACNkjB,GAAkBvrB,EAAI,IAUzB8oB,KAEF,MAAM5Q,EAAM7P,EACZA,EAAOA,EAAK0Y,YACZjsB,EAAOojB,EACT,CACF,MAAO,GAAgB,EAAZ6G,EAAe,CACxB,IAAIyM,EAAa3T,EAAMmH,SACD,OAAlBwM,EAAW,IAA+B,QAAfxrB,EAAGipB,SAAoC,aAAfjpB,EAAGipB,UACxDuC,EAAaA,EAAWxqB,MAAM,IAE5BhB,EAAGsrB,cAAgBE,IAChBD,GAAkBvrB,EAAI,IAQzB8oB,KAEF9oB,EAAGsrB,YAAczT,EAAMmH,SAE3B,CACA,GAAI70B,EACF,GAA4F4gC,IAAe5M,GAAyB,GAAZ4I,EAAuB,CAC7I,MAAM0E,EAAkBzrB,EAAGipB,QAAQjb,SAAS,KAC5C,IAAK,MAAMhd,KAAO7G,GAMZ4gC,IAAe/5B,EAAI06B,SAAS,UAAoB,kBAAR16B,IAA4B0O,EAAK1O,KAASoQ,EAAepQ,IAC1F,MAAXA,EAAI,IAAcy6B,IAChB/B,EAAU1pB,EAAIhP,EAAK,KAAM7G,EAAM6G,QAAM,EAAQ+sB,EAGnD,MAAO,GAAI5zB,EAAMsF,QACfi6B,EACE1pB,EACA,UACA,KACA7V,EAAMsF,aACN,EACAsuB,QAEG,GAAgB,EAAZgJ,GAAiBhT,GAAW5pB,EAAMyC,OAC3C,IAAK,MAAMoE,KAAO7G,EAAMyC,MAAOzC,EAAMyC,MAAMoE,IAI3Cg6B,EAAa7gC,GAASA,EAAMwhC,qBAC9BC,GAAgBZ,EAAYjN,EAAiBlG,GAE3CoE,GACFK,GAAoBzE,EAAO,KAAMkG,EAAiB,iBAE/CiN,EAAa7gC,GAASA,EAAM0hC,iBAAmB5P,GAAQgP,IAC1Da,GAAwB,KACtBd,GAAcY,GAAgBZ,EAAYjN,EAAiBlG,GAC3DoT,GAA2BzE,EAAWV,MAAM9lB,GAC5Cic,GAAQK,GAAoBzE,EAAO,KAAMkG,EAAiB,YACzDC,EAEP,CACA,OAAOhe,EAAG+gB,aAENE,EAAkB,CAACH,EAAMiL,EAAalO,EAAWE,EAAiBC,EAAgBE,EAAcC,KACpGA,EAAYA,KAAe4N,EAAY9M,gBACvC,MAAMD,EAAW+M,EAAY/M,SACvBhY,EAAIgY,EAASrvB,OAEnB,IAAK,IAAIsQ,EAAI,EAAGA,EAAI+G,EAAG/G,IAAK,CAC1B,MAAM4X,EAAQsG,EAAYa,EAAS/e,GAAK+e,EAAS/e,GAAK+rB,GAAehN,EAAS/e,IACxEgsB,EAASpU,EAAMxtB,OAAS4/B,GAC1BnJ,GACEmL,IAAW9N,GACTle,EAAI,EAAI+G,GAAKglB,GAAehN,EAAS/e,EAAI,IAAI5V,OAAS4/B,KACxDrL,EACEC,EACEiC,EAAK91B,KAAKgW,MAAM6W,EAAMmH,SAASrvB,SAEjCkuB,EACAkD,EAAYD,IAEdA,EAAK91B,KAAO6sB,EAAMmH,UAGtB8B,EAAO6I,EACL7I,EACAjJ,EACAkG,EACAC,EACAE,EACAC,IAEO8N,IAAWpU,EAAMmH,SAC1BJ,EAAO/G,EAAM7X,GAAK6e,EAAW,IAAKhB,IAE7B0N,GAAkB1N,EAAW,IAUhCiL,KAEFW,EACE,KACA5R,EACAgG,EACA,KACAE,EACAC,EACA+K,GAAiBlL,GACjBK,GAGN,CACA,OAAO4C,GAEH0J,EAAkB,CAAC1J,EAAMjJ,EAAOkG,EAAiBC,EAAgBE,EAAcC,KACnF,MAAQD,aAAcgO,GAAyBrU,EAC3CqU,IACFhO,EAAeA,EAAeA,EAAa5Q,OAAO4e,GAAwBA,GAE5E,MAAMrO,EAAYmD,EAAWF,GACvBzY,EAAO4Y,EACXF,EAAYD,GACZjJ,EACAgG,EACAE,EACAC,EACAE,EACAC,GAEF,OAAI9V,GAAQ+gB,GAAU/gB,IAAuB,MAAdA,EAAKrd,KAC3B+1B,EAAYlJ,EAAMiG,OAASzV,IAElCygB,KACAlK,EAAO/G,EAAMiG,OAASgB,EAAc,KAAMjB,EAAWxV,GAC9CA,IAGLyhB,EAAiB,CAAChJ,EAAMjJ,EAAOkG,EAAiBC,EAAgBE,EAAciO,KAclF,GAbKZ,GAAkBzK,EAAKsL,cAAe,IAUzCtD,KAEFjR,EAAM7X,GAAK,KACPmsB,EAAY,CACd,MAAMxS,EAAM+Q,EAAoB5J,GAChC,OAAa,CACX,MAAMuL,EAAQtL,EAAYD,GAC1B,IAAIuL,GAASA,IAAU1S,EAGrB,MAFA7kB,EAAOu3B,EAIX,CACF,CACA,MAAMhkB,EAAO0Y,EAAYD,GACnBjD,EAAYmD,EAAWF,GAgB7B,OAfAhsB,EAAOgsB,GACP2I,EACE,KACA5R,EACAgG,EACAxV,EACA0V,EACAC,EACA+K,GAAiBlL,GACjBK,GAEEH,IACFA,EAAgBlG,MAAM7X,GAAK6X,EAAM7X,GACjCssB,GAAgBvO,EAAiBlG,EAAM7X,KAElCqI,GAEHqiB,EAAsB,CAAC5J,EAAM7qB,EAAO,IAAKs2B,EAAQ,OACrD,IAAIC,EAAQ,EACZ,KAAO1L,GAEL,IADAA,EAAOC,EAAYD,KACPsI,GAAUtI,KAChBA,EAAK91B,OAASiL,GAAMu2B,IACpB1L,EAAK91B,OAASuhC,GAAO,CACvB,GAAc,IAAVC,EACF,OAAOzL,EAAYD,GAEnB0L,GAEJ,CAGJ,OAAO1L,GAEHqJ,EAAc,CAACsC,EAASC,EAAS3O,KACrC,MAAM4O,EAAcD,EAAQ1L,WACxB2L,GACFA,EAAYC,aAAaH,EAASC,GAEpC,IAAI/lB,EAASoX,EACb,KAAOpX,GACDA,EAAOkR,MAAM7X,KAAO0sB,IACtB/lB,EAAOkR,MAAM7X,GAAK2G,EAAOmd,QAAQ9jB,GAAKysB,GAExC9lB,EAASA,EAAOA,QAGdujB,EAAkBpJ,GACG,IAAlBA,EAAKU,UAAmC,aAAjBV,EAAKmI,QAErC,MAAO,CAldS,CAACpR,EAAOgG,KACtB,IAAKA,EAAUgP,gBAOb,OAHApD,EAAM,KAAM5R,EAAOgG,GACnBvD,UACAuD,EAAUiP,OAASjV,GAGrB8R,EAAY9L,EAAU0D,WAAY1J,EAAO,KAAM,KAAM,MACrDyC,KACAuD,EAAUiP,OAASjV,GAscJ8R,EACnB,CA4HA,MAAMoD,GAAoB,sBACpBC,GAAqB,CACzB,EAAgB,OAChB,EAAoB,WACpB,EAAiB,QACjB,EAAiB,QACjB,EAAqB,aAEvB,SAASzB,GAAkBvrB,EAAIitB,GAC7B,GAAoB,IAAhBA,GAAgD,IAAhBA,EAClC,KAAOjtB,IAAOA,EAAGktB,aAAaH,KAC5B/sB,EAAKA,EAAGosB,cAGZ,MAAMe,EAAcntB,GAAMA,EAAGorB,aAAa2B,IAC1C,GAAmB,MAAfI,EACF,OAAO,EACF,GAAoB,KAAhBA,EACT,OAAO,EACF,CACL,MAAM55B,EAAO45B,EAAYjgC,MAAM,KAC/B,QAAoB,IAAhB+/B,IAAgC15B,EAAKya,SAAS,cAG3Cza,EAAKya,SAASgf,GAAmBC,GAC1C,CACF,CAEA,MAAMG,GAAsBhqB,IAAgBgqB,qBAAuB,CAAEjT,GAAOkT,WAAWlT,EAAI,IACrFmT,GAAqBlqB,IAAgBkqB,oBAAsB,CAAE78B,GAAO88B,aAAa98B,IACjF+8B,GAAgB,CAACC,EAAU,MAAS5M,IACxC,MAAMpwB,EAAK28B,GAAoBvM,EAAS,CAAE4M,YAC1C,MAAO,IAAMH,GAAmB78B,IAO5Bi9B,GAAoBC,GAAS,CAAC9M,EAASjsB,KAC3C,MAAMg5B,EAAK,IAAIC,qBAAsBnoB,IACnC,IAAK,MAAMpX,KAAKoX,EACd,GAAKpX,EAAEw/B,eAAP,CACAF,EAAGG,aACHlN,IACA,KAH+B,GAKhC8M,GAUH,OATA/4B,EAASoL,IACP,GAAMA,aAAcguB,QACpB,OAhBJ,SAAoChuB,GAClC,MAAM,IAAEiuB,EAAG,KAAEC,EAAI,OAAEC,EAAM,MAAEC,GAAUpuB,EAAGquB,yBAClC,YAAEC,EAAW,WAAEC,GAAe59B,OACpC,OAAQs9B,EAAM,GAAKA,EAAMK,GAAeH,EAAS,GAAKA,EAASG,KAAiBJ,EAAO,GAAKA,EAAOK,GAAcH,EAAQ,GAAKA,EAAQG,EACxI,CAYQC,CAA2BxuB,IAC7B6gB,IACA+M,EAAGG,cACI,QAETH,EAAGa,QAAQzuB,KAEN,IAAM4tB,EAAGG,cAEZW,GAAuBC,GAAW9N,IACtC,GAAI8N,EAAO,CACT,MAAMC,EAAMC,WAAWF,GACvB,IAAIC,EAAIE,QAIN,OADAF,EAAIx/B,iBAAiB,SAAUyxB,EAAS,CAAEkO,MAAM,IACzC,IAAMH,EAAII,oBAAoB,SAAUnO,GAH/CA,GAKJ,GAEIoO,GAAuB,CAACC,EAAe,KAAO,CAACrO,EAASjsB,KACxD,EAASs6B,KAAeA,EAAe,CAACA,IAC5C,IAAIC,GAAc,EAClB,MAAMC,EAAa9gC,IACZ6gC,IACHA,GAAc,EACdE,IACAxO,IACAvyB,EAAEe,OAAOigC,cAAc,IAAIhhC,EAAE8X,YAAY9X,EAAEjE,KAAMiE,MAG/C+gC,EAAW,KACfz6B,EAASoL,IACP,IAAK,MAAMC,KAAKivB,EACdlvB,EAAGgvB,oBAAoB/uB,EAAGmvB,MAShC,OALAx6B,EAASoL,IACP,IAAK,MAAMC,KAAKivB,EACdlvB,EAAG5Q,iBAAiB6Q,EAAGmvB,EAAW,CAAEL,MAAM,MAGvCM,GA0BHxH,GAAkB5nB,KAAQA,EAAE5V,KAAKklC,cAEvC,SAASC,GAAqB3a,GACxB,EAAWA,KACbA,EAAS,CAAE4a,OAAQ5a,IAErB,MAAM,OACJ4a,EAAM,iBACNC,EAAgB,eAChBC,EAAc,MACdC,EAAQ,IACR/O,QAASgP,EAAe,QACxBpC,EAAO,YAEPqC,GAAc,EACdC,QAASC,GACPnb,EACJ,IACIob,EADAC,EAAiB,KAEjBC,EAAU,EACd,MAKMC,EAAO,KACX,IAAIC,EACJ,OAAOH,IAAmBG,EAAcH,EAAiBT,IAAS5uB,MAAOmJ,IAEvE,GADAA,EAAMA,aAAesmB,MAAQtmB,EAAM,IAAIsmB,MAAMzlC,OAAOmf,IAChDgmB,EACF,OAAO,IAAIhX,QAAQ,CAACC,EAASsX,KAG3BP,EAAYhmB,EAFM,IAAMiP,GAV9BkX,IACAD,EAAiB,KACVE,MASgB,IAAMG,EAAOvmB,GACQmmB,EAAU,KAGlD,MAAMnmB,IAEPnb,KAAM2hC,GACHH,IAAgBH,GAAkBA,EAC7BA,GAOLM,IAASA,EAAKC,YAA2C,WAA7BD,EAAKtkB,OAAOwkB,gBAC1CF,EAAOA,EAAKjmC,SAKd0lC,EAAeO,EACRA,MAGX,OAAOxJ,GAAgB,CACrB98B,KAAM,wBACNqlC,cAAea,EACf,cAAAO,CAAe3wB,EAAIyX,EAAUoJ,GAC3B,IAAI+P,GAAU,GACbnZ,EAASoZ,KAAOpZ,EAASoZ,GAAK,KAAKhqB,KAAK,IAAM+pB,GAAU,GACzD,MAAME,EAAiB,KACjBF,GAQJ/P,KAEIuO,EAAYS,EAAkB,KAClC,MAAMR,EAAWQ,EACfiB,EACC3W,GArGX,SAAwB2G,EAAM3G,GAC5B,GAAIiP,GAAUtI,IAAuB,MAAdA,EAAK91B,KAAc,CACxC,IAAIgsB,EAAQ,EACR3O,EAAOyY,EAAKC,YAChB,KAAO1Y,GAAM,CACX,GAAsB,IAAlBA,EAAKmZ,UAEP,IAAe,IADArH,EAAG9R,GAEhB,WAEG,GAAI+gB,GAAU/gB,GACnB,GAAkB,MAAdA,EAAKrd,MACP,GAAgB,MAAVgsB,EAAa,UACI,MAAd3O,EAAKrd,MACdgsB,IAGJ3O,EAAOA,EAAK0Y,WACd,CACF,MACE5G,EAAG2G,EAEP,CA+EkBiQ,CAAe/wB,EAAIma,IAEzBkV,IACD5X,EAASuZ,MAAQvZ,EAASuZ,IAAM,KAAKnqB,KAAKwoB,IAE3CyB,EACAb,EACFb,IAEAgB,IAAOvhC,KAAK,KAAO4oB,EAASwZ,aAAe7B,IAE/C,EACA,mBAAItH,GACF,OAAOmI,CACT,EACA,KAAA9yB,GACE,MAAMsa,EAAWyZ,GAEjB,GADA7J,GAAkB5P,GACdwY,EACF,MAAO,IAAMkB,GAAgBlB,EAAcxY,GAE7C,MAAMsY,EAAW/lB,IACfkmB,EAAiB,KACjBxY,GACE1N,EACAyN,EACA,IACCkY,IAGL,GAAIG,GAAerY,EAAS2Z,UAAYC,GACtC,OAAOjB,IAAOvhC,KAAM2hC,GACX,IAAMW,GAAgBX,EAAM/Y,IAClC5W,MAAOmJ,IACR+lB,EAAQ/lB,GACD,IAAM2lB,EAAiBhF,GAAYgF,EAAgB,CACxDh1B,MAAOqP,IACJ,OAGT,MAAMsnB,EAASpd,IAAI,GACbvZ,EAAQuZ,KACRqd,EAAUrd,KAAM0b,GA0BtB,OAzBIA,GACFvC,WAAW,KACTkE,EAAQ73B,OAAQ,GACfk2B,GAEU,MAAXnC,GACFJ,WAAW,KACT,IAAKiE,EAAO53B,QAAUiB,EAAMjB,MAAO,CACjC,MAAMsQ,EAAM,IAAIsmB,MACd,mCAAmC7C,QAErCsC,EAAQ/lB,GACRrP,EAAMjB,MAAQsQ,CAChB,GACCyjB,GAEL2C,IAAOvhC,KAAK,KACVyiC,EAAO53B,OAAQ,EACX+d,EAAS9Q,QAAU2f,GAAY7O,EAAS9Q,OAAOkR,QACjDJ,EAAS9Q,OAAOue,WAEjBrkB,MAAOmJ,IACR+lB,EAAQ/lB,GACRrP,EAAMjB,MAAQsQ,IAET,IACDsnB,EAAO53B,OAASu2B,EACXkB,GAAgBlB,EAAcxY,GAC5B9c,EAAMjB,OAASi2B,EACjBhF,GAAYgF,EAAgB,CACjCh1B,MAAOA,EAAMjB,QAENg2B,IAAqB6B,EAAQ73B,MAC/BixB,GAAY+E,QADd,CAIX,GAEJ,CACA,SAASyB,GAAgBX,EAAM7pB,GAC7B,MAAQuN,IAAKQ,EAAI,MAAEvqB,EAAK,SAAE60B,EAAQ,GAAEU,GAAO/Y,EAAOkR,MAC5CA,EAAQ8S,GAAY6F,EAAMrmC,EAAO60B,GAIvC,OAHAnH,EAAM3D,IAAMQ,EACZmD,EAAM6H,GAAKA,SACJ/Y,EAAOkR,MAAM6H,GACb7H,CACT,CAEA,MAAMyO,GAAezO,GAAUA,EAAMxtB,KAAKmnC,cA+MpCC,GA9MgB,CACpBvnC,KAAM,YAINsnC,eAAe,EACfrnC,MAAO,CACLunC,QAAS,CAAC7mC,OAAQ8mC,OAAQjkC,OAC1BkkC,QAAS,CAAC/mC,OAAQ8mC,OAAQjkC,OAC1BmkC,IAAK,CAAChnC,OAAQoY,SAEhB,KAAA9F,CAAMhT,GAAO,MAAEg6B,IACb,MAAM1M,EAAW2M,KACX0N,EAAgBra,EAAS4D,IAC/B,IAAKyW,EAAcC,SACjB,MAAO,KACL,MAAM/S,EAAWmF,EAAM55B,SAAW45B,EAAM55B,UACxC,OAAOy0B,GAAgC,IAApBA,EAASrvB,OAAeqvB,EAAS,GAAKA,GAG7D,MAAMzd,EAAwB,IAAIgL,IAC5BxH,EAAuB,IAAI+K,IACjC,IAAIkiB,EAAU,KAId,MAAMhU,EAAiBvG,EAAS2Z,UAE9BW,UACE3Y,EAAGqQ,EACH/H,EAAGd,EACHN,GAAI2R,EACJtT,GAAG,cAAEuT,KAELJ,EACEK,EAAmBD,EAAc,OAmDvC,SAAS3R,EAAQ1I,GACfua,GAAeva,GACfoa,EAASpa,EAAOJ,EAAUuG,GAAgB,EAC5C,CACA,SAASqU,EAAWzkB,GAClBrM,EAAM3M,QAAQ,CAACijB,EAAO7mB,KACpB,MAAM9G,EAAOooC,GAAiBza,EAAMxtB,MAChCH,IAAS0jB,EAAO1jB,IAClBqoC,EAAgBvhC,IAGtB,CACA,SAASuhC,EAAgBvhC,GACvB,MAAMwhC,EAASjxB,EAAM3S,IAAIoC,IACrBwhC,GAAYR,GAAYjN,GAAgByN,EAAQR,GAEzCA,GACTI,GAAeJ,GAFfzR,EAAQiS,GAIVjxB,EAAMkH,OAAOzX,GACb+T,EAAK0D,OAAOzX,EACd,CAvEA8gC,EAAcW,SAAW,CAAC5a,EAAOgG,EAAWC,EAAQG,EAAWE,KAC7D,MAAMuU,EAAY7a,EAAMpa,UACxBmjB,EAAK/I,EAAOgG,EAAWC,EAAQ,EAAGE,GAClCyL,EACEiJ,EAAU7a,MACVA,EACAgG,EACAC,EACA4U,EACA1U,EACAC,EACApG,EAAMqG,aACNC,GAEF2B,GAAsB,KACpB4S,EAAUC,eAAgB,EACtBD,EAAUluB,GACZrC,EAAeuwB,EAAUluB,GAE3B,MAAMouB,EAAY/a,EAAM1tB,OAAS0tB,EAAM1tB,MAAM0hC,eACzC+G,GACFhH,GAAgBgH,EAAWF,EAAU/rB,OAAQkR,IAE9CmG,IAKL8T,EAAce,WAAchb,IAC1B,MAAM6a,EAAY7a,EAAMpa,UACxBq1B,GAAgBJ,EAAUhR,GAC1BoR,GAAgBJ,EAAUluB,GAC1Boc,EAAK/I,EAAOsa,EAAkB,KAAM,EAAGnU,GACvC8B,GAAsB,KAChB4S,EAAUK,IACZ5wB,EAAeuwB,EAAUK,IAE3B,MAAMH,EAAY/a,EAAM1tB,OAAS0tB,EAAM1tB,MAAM6oC,iBACzCJ,GACFhH,GAAgBgH,EAAWF,EAAU/rB,OAAQkR,GAE/C6a,EAAUC,eAAgB,GACzB3U,IA8BL,GACE,IAAM,CAAC7zB,EAAMunC,QAASvnC,EAAMynC,SAC5B,EAAEF,EAASE,MACTF,GAAWW,EAAYnoC,GAAS4kC,GAAQ4C,EAASxnC,IACjD0nC,GAAWS,EAAYnoC,IAAU4kC,GAAQ8C,EAAS1nC,KAGpD,CAAE+oC,MAAO,OAAQ5W,MAAM,IAEzB,IAAI6W,EAAkB,KACtB,MAAMC,EAAe,KACI,MAAnBD,IACEE,GAAW3b,EAASqM,QAAQz5B,MAC9By1B,GAAsB,KACpBve,EAAM+K,IAAI4mB,EAAiBG,GAAc5b,EAASqM,WACjDrM,EAASqM,QAAQsN,UAEpB7vB,EAAM+K,IAAI4mB,EAAiBG,GAAc5b,EAASqM,YAmBxD,OAfArB,GAAU0Q,GACVG,GAAUH,GACVzQ,GAAgB,KACdnhB,EAAM3M,QAAS49B,IACb,MAAM,QAAE1O,EAAO,SAAEsN,GAAa3Z,EACxBI,EAAQwb,GAAcvP,GAC5B,GAAI0O,EAAOnoC,OAASwtB,EAAMxtB,MAAQmoC,EAAOxhC,MAAQ6mB,EAAM7mB,IAAK,CAC1DohC,GAAeva,GACf,MAAMkb,EAAKlb,EAAMpa,UAAUs1B,GAE3B,YADAA,GAAMjT,GAAsBiT,EAAI3B,GAElC,CACA7Q,EAAQiS,OAGL,KAEL,GADAU,EAAkB,MACb/O,EAAM55B,QACT,OAAOynC,EAAU,KAEnB,MAAMhT,EAAWmF,EAAM55B,UACjBgpC,EAAWvU,EAAS,GAC1B,GAAIA,EAASrvB,OAAS,EAKpB,OADAqiC,EAAU,KACHhT,EACF,IAAKwU,GAAQD,MAAoC,EAArBA,EAASxU,WAAyC,IAArBwU,EAASxU,WAEvE,OADAiT,EAAU,KACHuB,EAET,IAAI1b,EAAQwb,GAAcE,GAC1B,GAAI1b,EAAMxtB,OAAS45B,GAEjB,OADA+N,EAAU,KACHna,EAET,MAAM2Y,EAAO3Y,EAAMxtB,KACbH,EAAOooC,GACXzK,GAAehQ,GAASA,EAAMxtB,KAAKy9B,iBAAmB,CAAC,EAAI0I,IAEvD,QAAEkB,EAAO,QAAEE,EAAO,IAAEC,GAAQ1nC,EAClC,GAAIunC,KAAaxnC,IAAS4kC,GAAQ4C,EAASxnC,KAAU0nC,GAAW1nC,GAAQ4kC,GAAQ8C,EAAS1nC,GAGvF,OAFA2tB,EAAMkH,YAAc,IACpBiT,EAAUna,EACH0b,EAET,MAAMviC,EAAmB,MAAb6mB,EAAM7mB,IAAcw/B,EAAO3Y,EAAM7mB,IACvCyiC,EAAclyB,EAAM3S,IAAIoC,GAyB9B,OAxBI6mB,EAAM7X,KACR6X,EAAQ0O,GAAW1O,GACM,IAArB0b,EAASxU,YACXwU,EAAS9M,UAAY5O,IAGzBqb,EAAkBliC,EACdyiC,GACF5b,EAAM7X,GAAKyzB,EAAYzzB,GACvB6X,EAAMpa,UAAYg2B,EAAYh2B,UAC1Boa,EAAM2O,YACR3B,GAAmBhN,EAAOA,EAAM2O,YAElC3O,EAAMkH,WAAa,IACnBha,EAAK0D,OAAOzX,GACZ+T,EAAKhQ,IAAI/D,KAET+T,EAAKhQ,IAAI/D,GACL6gC,GAAO9sB,EAAKU,KAAOtE,SAAS0wB,EAAK,KACnCU,EAAgBxtB,EAAK/V,SAASqZ,OAAO3O,QAGzCme,EAAMkH,WAAa,IACnBiT,EAAUna,EACHub,GAAWG,EAASlpC,MAAQkpC,EAAW1b,EAElD,GAGF,SAASiX,GAAQ4E,EAASxpC,GACxB,OAAI,EAAQwpC,GACHA,EAAQllB,KAAM4K,GAAM0V,GAAQ1V,EAAGlvB,IAC7B,EAASwpC,GACXA,EAAQxmC,MAAM,KAAK8gB,SAAS9jB,GFzsFS,oBAAtBsW,EE0sFJkzB,KAClBA,EAAQC,UAAY,EACbD,EAAQE,KAAK1pC,GAGxB,CACA,SAAS2pC,GAAYnX,EAAMrtB,GACzBykC,GAAsBpX,EAAM,IAAKrtB,EACnC,CACA,SAAS0kC,GAAcrX,EAAMrtB,GAC3BykC,GAAsBpX,EAAM,KAAMrtB,EACpC,CACA,SAASykC,GAAsBpX,EAAMryB,EAAMgF,EAAS6hC,IAClD,MAAM8C,EAActX,EAAKuX,QAAUvX,EAAKuX,MAAQ,KAC9C,IAAIjC,EAAU3iC,EACd,KAAO2iC,GAAS,CACd,GAAIA,EAAQW,cACV,OAEFX,EAAUA,EAAQrrB,MACpB,CACA,OAAO+V,MAGT,GADAwX,GAAW7pC,EAAM2pC,EAAa3kC,GAC1BA,EAAQ,CACV,IAAI2iC,EAAU3iC,EAAOsX,OACrB,KAAOqrB,GAAWA,EAAQrrB,QACpB2f,GAAY0L,EAAQrrB,OAAOkR,QAC7Bsc,GAAsBH,EAAa3pC,EAAMgF,EAAQ2iC,GAEnDA,EAAUA,EAAQrrB,MAEtB,CACF,CACA,SAASwtB,GAAsBzX,EAAMryB,EAAMgF,EAAQ+kC,GACjD,MAAMC,EAAWH,GACf7pC,EACAqyB,EACA0X,GACA,GAGFE,GAAY,KACVx/B,EAAOs/B,EAAc/pC,GAAOgqC,IAC3BhlC,EACL,CACA,SAAS+iC,GAAeva,GACtBA,EAAMkH,YAAc,IACpBlH,EAAMkH,YAAc,GACtB,CACA,SAASsU,GAAcxb,GACrB,OAAyB,IAAlBA,EAAMkH,UAAkBlH,EAAM4O,UAAY5O,CACnD,CAEA,SAASqc,GAAW7pC,EAAMqyB,EAAMrtB,EAAS6hC,GAAiBqD,GAAU,GAClE,GAAIllC,EAAQ,CACV,MAAMu1B,EAAQv1B,EAAOhF,KAAUgF,EAAOhF,GAAQ,IACxC2pC,EAActX,EAAK8X,QAAU9X,EAAK8X,MAAQ,IAAI95B,KAClD,KACA,MAAM+5B,EAAQC,GAAmBrlC,GAC3BoU,EAAMkU,GAA2B+E,EAAMrtB,EAAQhF,EAAMqQ,GAG3D,OAFA+5B,IACA,KACOhxB,IAOT,OALI8wB,EACF3P,EAAM/V,QAAQmlB,GAEdpP,EAAM/d,KAAKmtB,GAENA,CACT,CAMF,CACA,MAAMW,GAAcC,GAAc,CAAClY,EAAMrtB,EAAS6hC,MAC3CG,IAAuC,OAAduD,GAC5BV,GAAWU,EAAW,IAAIl6B,IAASgiB,KAAQhiB,GAAOrL,IAGhDwlC,GAAgBF,GAAW,MAC3BlS,GAAYkS,GAAW,KACvBG,GAAiBH,GACrB,MAEIrB,GAAYqB,GAAW,KACvBjS,GAAkBiS,GACtB,OAEIL,GAAcK,GAAW,MACzBI,GAAmBJ,GACvB,MAEIK,GAAoBL,GAAW,OAC/BM,GAAkBN,GAAW,OACnC,SAASO,GAAgBxY,EAAMrtB,EAAS6hC,IACtCgD,GAAW,KAAMxX,EAAMrtB,EACzB,CAEA,MAAM8lC,GAAa,aACbC,GAAa,aACnB,SAASC,GAAiBnrC,EAAMorC,GAC9B,OAAOC,GAAaJ,GAAYjrC,GAAM,EAAMorC,IAAuBprC,CACrE,CACA,MAAMsrC,GAAyBtpB,OAAO7T,IAAI,SAC1C,SAASo9B,GAAwBh4B,GAC/B,OAAI,EAASA,GACJ83B,GAAaJ,GAAY13B,GAAW,IAAUA,EAE9CA,GAAa+3B,EAExB,CACA,SAASE,GAAiBxrC,GACxB,OAAOqrC,GAAaH,GAAYlrC,EAClC,CACA,SAASqrC,GAAalrC,EAAMH,EAAMyrC,GAAc,EAAML,GAAqB,GACzE,MAAM7d,EAAWmD,IAA4BsW,GAC7C,GAAIzZ,EAAU,CACZ,MAAMme,EAAYne,EAASptB,KAC3B,GAAIA,IAAS8qC,GAAY,CACvB,MAAMU,EAAWvD,GACfsD,GACA,GAEF,GAAIC,IAAaA,IAAa3rC,GAAQ2rC,IAAa,EAAS3rC,IAAS2rC,IAAa,EAAW,EAAS3rC,KACpG,OAAO0rC,CAEX,CACA,MAAMnyB,EAGJwV,GAAQxB,EAASptB,IAASurC,EAAUvrC,GAAOH,IAC3C+uB,GAAQxB,EAASO,WAAW3tB,GAAOH,GAErC,OAAKuZ,GAAO6xB,EACHM,EAOFnyB,CACT,CAKF,CACA,SAASwV,GAAQ6c,EAAU5rC,GACzB,OAAO4rC,IAAaA,EAAS5rC,IAAS4rC,EAAS,EAAS5rC,KAAU4rC,EAAS,EAAW,EAAS5rC,KACjG,CAEA,SAAS6rC,GAAWlhB,EAAQmhB,EAAYz0B,EAAOzQ,GAC7C,IAAIkT,EACJ,MAAMwuB,EAASjxB,GAASA,EAAMzQ,GACxBmlC,EAAgB,EAAQphB,GAC9B,GAAIohB,GAAiB,EAASphB,GAAS,CAErC,IAAIvF,GAAY,EACZ4mB,GAAmB,EAFOD,GAAiBliB,GAAWc,KAIxDvF,GAAatC,GAAU6H,GACvBqhB,EAAmBjlB,GAAW4D,GAC9BA,EAAS3H,GAAiB2H,IAE5B7Q,EAAM,IAAItW,MAAMmnB,EAAOllB,QACvB,IAAK,IAAIsQ,EAAI,EAAG+G,EAAI6N,EAAOllB,OAAQsQ,EAAI+G,EAAG/G,IACxC+D,EAAI/D,GAAK+1B,EACP1mB,EAAY4mB,EAAmB/jB,GAAWlF,GAAW4H,EAAO5U,KAAOgN,GAAW4H,EAAO5U,IAAM4U,EAAO5U,GAClGA,OACA,EACAuyB,GAAUA,EAAOvyB,GAGvB,MAAO,GAAsB,iBAAX4U,EAAqB,CAIrC7Q,EAAM,IAAItW,MAAMmnB,GAChB,IAAK,IAAI5U,EAAI,EAAGA,EAAI4U,EAAQ5U,IAC1B+D,EAAI/D,GAAK+1B,EAAW/1B,EAAI,EAAGA,OAAG,EAAQuyB,GAAUA,EAAOvyB,GAE3D,MAAO,GAAI,EAAS4U,GAClB,GAAIA,EAAO3I,OAAOmB,UAChBrJ,EAAMtW,MAAMsL,KACV6b,EACA,CAACjd,EAAMqI,IAAM+1B,EAAWp+B,EAAMqI,OAAG,EAAQuyB,GAAUA,EAAOvyB,SAEvD,CACL,MAAM8E,EAAOlY,OAAOkY,KAAK8P,GACzB7Q,EAAM,IAAItW,MAAMqX,EAAKpV,QACrB,IAAK,IAAIsQ,EAAI,EAAG+G,EAAIjC,EAAKpV,OAAQsQ,EAAI+G,EAAG/G,IAAK,CAC3C,MAAMjP,EAAM+T,EAAK9E,GACjB+D,EAAI/D,GAAK+1B,EAAWnhB,EAAO7jB,GAAMA,EAAKiP,EAAGuyB,GAAUA,EAAOvyB,GAC5D,CACF,MAEA+D,EAAM,GAKR,OAHIzC,IACFA,EAAMzQ,GAASkT,GAEVA,CACT,CAEA,SAASmyB,GAAYhS,EAAOiS,GAC1B,IAAK,IAAIn2B,EAAI,EAAGA,EAAIm2B,EAAazmC,OAAQsQ,IAAK,CAC5C,MAAMo2B,EAAOD,EAAan2B,GAC1B,GAAI,EAAQo2B,GACV,IAAK,IAAIC,EAAI,EAAGA,EAAID,EAAK1mC,OAAQ2mC,IAC/BnS,EAAMkS,EAAKC,GAAGpsC,MAAQmsC,EAAKC,GAAGh1B,QAEvB+0B,IACTlS,EAAMkS,EAAKnsC,MAAQmsC,EAAKrlC,IAAM,IAAI0J,KAChC,MAAM+I,EAAM4yB,EAAK/0B,MAAM5G,GAEvB,OADI+I,IAAKA,EAAIzS,IAAMqlC,EAAKrlC,KACjByS,GACL4yB,EAAK/0B,GAEb,CACA,OAAO6iB,CACT,CAEA,SAASoS,GAAWpS,EAAOj6B,EAAMC,EAAQ,CAAC,EAAGiG,EAAUomC,GACrD,GAAI5b,GAAyB8E,IAAM9E,GAAyBjU,QAAUkhB,GAAejN,GAAyBjU,SAAWiU,GAAyBjU,OAAO+Y,GAAI,CAC3J,MAAM+W,EAAW5pC,OAAOkY,KAAK5a,GAAOwF,OAAS,EAE7C,MADa,YAATzF,IAAoBC,EAAMD,KAAOA,GAC9BwsC,KAAaC,GAClB7P,GACA,KACA,CAAC6D,GAAY,OAAQxgC,EAAOiG,GAAYA,MACxCqmC,GAAY,EAAI,GAEpB,CACA,IAAIJ,EAAOlS,EAAMj6B,GAObmsC,GAAQA,EAAKza,KACfya,EAAK5a,IAAK,GAEZib,KACA,MAAME,EAAmBP,GAAQQ,GAAiBR,EAAKlsC,IACjD2sC,EAAU3sC,EAAM6G,KAEtB4lC,GAAoBA,EAAiB5lC,IAC/B+lC,EAAWJ,GACf7P,GACA,CACE91B,KAAM8lC,IAAYn2B,EAASm2B,GAAWA,EAAU,IAAI5sC,OAClD0sC,GAAoBxmC,EAAW,MAAQ,KAE3CwmC,IAAqBxmC,EAAWA,IAAa,IAC7CwmC,GAAgC,IAAZzS,EAAM6S,EAAU,IAAM,GAQ5C,OANKR,GAAaO,EAASE,UACzBF,EAAS7Y,aAAe,CAAC6Y,EAASE,QAAU,OAE1CZ,GAAQA,EAAKza,KACfya,EAAK5a,IAAK,GAELsb,CACT,CACA,SAASF,GAAiBK,GACxB,OAAOA,EAAO1oB,KAAMmS,IACb6S,GAAQ7S,IACTA,EAAMt2B,OAAS45B,MACftD,EAAMt2B,OAASy8B,KAAa+P,GAAiBlW,EAAM3B,YAGpDkY,EAAS,IAChB,CAEA,SAASC,GAAW50B,EAAK60B,GACvB,MAAMpzB,EAAM,CAAC,EAKb,IAAK,MAAMhT,KAAOuR,EAChByB,EAAIozB,GAA2B,QAAQxD,KAAK5iC,GAAO,MAAMA,IAAQ+Q,EAAa/Q,IAAQuR,EAAIvR,GAE5F,OAAOgT,CACT,CAEA,MAAMqzB,GAAqBp3B,GACpBA,EACDq3B,GAAoBr3B,GAAW8b,GAA2B9b,GACvDo3B,GAAkBp3B,EAAE0G,QAFZ,KAIX4wB,GAGY,EAAuB1qC,OAAOyS,OAAO,MAAO,CAC1Dk4B,EAAIv3B,GAAMA,EACVw3B,IAAMx3B,GAAMA,EAAE4X,MAAM7X,GACpB03B,MAAQz3B,GAAMA,EAAEjV,KAChBa,OAASoU,GAA6EA,EAAE9V,MACxFwtC,OAAS13B,GAA6EA,EAAE23B,MACxF1kC,OAAS+M,GAA6EA,EAAEkkB,MACxF0T,MAAQ53B,GAA4EA,EAAEsnB,KACtFp8B,QAAU8U,GAAMo3B,GAAkBp3B,EAAE0G,QACpCmxB,MAAQ73B,GAAMo3B,GAAkBp3B,EAAE83B,MAClCC,MAAQ/3B,GAAMA,EAAEyf,GAChB1qB,MAAQiL,GAAMA,EAAEg4B,KAChBzrC,SAAWyT,GAA4Bi4B,GAAqBj4B,GAC5Dk4B,aAAel4B,GAAMA,EAAEyoB,IAAMzoB,EAAEyoB,EAAI,KACjCrP,GAASpZ,EAAEilB,UAEbvrB,UAAYsG,GAAMA,EAAE4C,IAAM5C,EAAE4C,EAAIsW,GAAS7N,KAAKrL,EAAE4T,QAChDukB,OAASn4B,GAA4Bo4B,GAAc/sB,KAAKrL,KAItDq4B,GAAkB,CAAClW,EAAOpxB,IAAQoxB,IAAU7iB,IAAc6iB,EAAMmW,iBAAmBn4B,EAAOgiB,EAAOpxB,GACjGwnC,GAA8B,CAClC,GAAA5pC,EAAMooC,EAAGvf,GAAYzmB,GACnB,GAAY,aAARA,EACF,OAAO,EAET,MAAM,IAAEqqB,EAAG,WAAE4M,EAAU,KAAEj9B,EAAI,MAAEb,EAAK,YAAEsuC,EAAW,KAAEpuC,EAAI,WAAE2tB,GAAeP,EAIxE,IAAIihB,EACJ,GAAe,MAAX1nC,EAAI,GAAY,CAClB,MAAM6R,EAAI41B,EAAYznC,GACtB,QAAU,IAAN6R,EACF,OAAQA,GACN,KAAK,EACH,OAAOolB,EAAWj3B,GACpB,KAAK,EACH,OAAOhG,EAAKgG,GACd,KAAK,EACH,OAAOqqB,EAAIrqB,GACb,KAAK,EACH,OAAO7G,EAAM6G,OAEZ,IAAIsnC,GAAgBrQ,EAAYj3B,GAErC,OADAynC,EAAYznC,GAAO,EACZi3B,EAAWj3B,GACb,GAAIhG,IAASuU,GAAaa,EAAOpV,EAAMgG,GAE5C,OADAynC,EAAYznC,GAAO,EACZhG,EAAKgG,GACP,IAGJ0nC,EAAkBjhB,EAASkhB,aAAa,KAAOv4B,EAAOs4B,EAAiB1nC,GAGxE,OADAynC,EAAYznC,GAAO,EACZ7G,EAAM6G,GACR,GAAIqqB,IAAQ9b,GAAaa,EAAOib,EAAKrqB,GAE1C,OADAynC,EAAYznC,GAAO,EACZqqB,EAAIrqB,GACsB4nC,KACjCH,EAAYznC,GAAO,EACrB,CACF,CACA,MAAM6nC,EAAetB,GAAoBvmC,GACzC,IAAI8nC,EAAWC,EACf,OAAIF,GACU,WAAR7nC,GACF,GAAMymB,EAASmgB,MAAO,EAAO,IAKxBiB,EAAaphB,KAGnBqhB,EAAYzuC,EAAK2uC,gBAAkBF,EAAYA,EAAU9nC,IAEnD8nC,EACEzd,IAAQ9b,GAAaa,EAAOib,EAAKrqB,IAC1CynC,EAAYznC,GAAO,EACZqqB,EAAIrqB,KAGX+nC,EAAmB/gB,EAAWC,OAAO8gB,iBAAkB34B,EAAO24B,EAAkB/nC,GAGvE+nC,EAAiB/nC,QALrB,EAsBT,EACA,GAAAsb,EAAM0qB,EAAGvf,GAAYzmB,EAAK0I,GACxB,MAAM,KAAE1O,EAAI,WAAEi9B,EAAU,IAAE5M,GAAQ5D,EAClC,OAAI6gB,GAAgBrQ,EAAYj3B,IAC9Bi3B,EAAWj3B,GAAO0I,GACX,GAIE1O,IAASuU,GAAaa,EAAOpV,EAAMgG,IAC5ChG,EAAKgG,GAAO0I,GACL,KACE0G,EAAOqX,EAASttB,MAAO6G,IAInB,MAAXA,EAAI,IAAcA,EAAIgQ,MAAM,KAAMyW,IAalC4D,EAAIrqB,GAAO0I,EAGR,GACT,EACA,GAAA8O,EACEwuB,GAAG,KAAEhsC,EAAI,WAAEi9B,EAAU,YAAEwQ,EAAW,IAAEpd,EAAG,WAAErD,EAAU,aAAE2gB,EAAY,KAAEtuC,IAClE2G,GACD,IAAI0nC,EAAiBO,EACrB,SAAUR,EAAYznC,IAAQhG,IAASuU,GAAwB,MAAXvO,EAAI,IAAcoP,EAAOpV,EAAMgG,IAAQsnC,GAAgBrQ,EAAYj3B,KAAS0nC,EAAkBC,EAAa,KAAOv4B,EAAOs4B,EAAiB1nC,IAAQoP,EAAOib,EAAKrqB,IAAQoP,EAAOm3B,GAAqBvmC,IAAQoP,EAAO4X,EAAWC,OAAO8gB,iBAAkB/nC,KAASioC,EAAa5uC,EAAK2uC,eAAiBC,EAAWjoC,GAClW,EACA,cAAAyR,CAAepT,EAAQ2B,EAAKkoC,GAM1B,OALsB,MAAlBA,EAAWtqC,IACbS,EAAO2nC,EAAEyB,YAAYznC,GAAO,EACnBoP,EAAO84B,EAAY,UAC5BhtC,KAAKogB,IAAIjd,EAAQ2B,EAAKkoC,EAAWx/B,MAAO,MAEnCiX,QAAQlO,eAAepT,EAAQ2B,EAAKkoC,EAC7C,GAUIC,GAA6D,EAAO,CAAC,EAAGX,GAA6B,CACzG,GAAA5pC,CAAIS,EAAQ2B,GACV,GAAIA,IAAQkb,OAAOktB,YAGnB,OAAOZ,GAA4B5pC,IAAIS,EAAQ2B,EAAK3B,EACtD,EACAmZ,IAAG,CAACwuB,EAAGhmC,IACkB,MAAXA,EAAI,KAAewS,EAAkBxS,KAuErD,SAASqoC,KAIP,OAAO,IACT,CACA,SAASC,KAIP,OAAO,IACT,CACA,SAASC,GAAaC,GAItB,CACA,SAASC,GAAcl8B,GAIvB,CACA,SAASm8B,KAIP,OAAO,IACT,CACA,SAASC,KAIT,CACA,SAASC,GAAazvC,EAAO0vC,GAI3B,OAAO,IACT,CACA,SAASC,KACP,OAAOC,KAAuB5V,KAChC,CACA,SAAS6V,KACP,OAAOD,KAAuBnC,KAChC,CACA,SAASmC,GAAWE,GAClB,MAAMh6B,EAAImkB,KAIV,OAAOnkB,EAAEi6B,eAAiBj6B,EAAEi6B,aAAeC,GAAmBl6B,GAChE,CACA,SAASm6B,GAAsBjwC,GAC7B,OAAO,EAAQA,GAASA,EAAMwb,OAC5B,CAACjC,EAAY0V,KAAO1V,EAAW0V,GAAK,KAAM1V,GAC1C,CAAC,GACCvZ,CACN,CACA,SAASkwC,GAActtB,EAAK8sB,GAC1B,MAAM1vC,EAAQiwC,GAAsBrtB,GACpC,IAAK,MAAM/b,KAAO6oC,EAAU,CAC1B,GAAI7oC,EAAI6O,WAAW,UAAW,SAC9B,IAAIy6B,EAAMnwC,EAAM6G,GACZspC,EACE,EAAQA,IAAQ,EAAWA,GAC7BA,EAAMnwC,EAAM6G,GAAO,CAAE3G,KAAMiwC,EAAK/vC,QAASsvC,EAAS7oC,IAElDspC,EAAI/vC,QAAUsvC,EAAS7oC,GAER,OAARspC,IACTA,EAAMnwC,EAAM6G,GAAO,CAAEzG,QAASsvC,EAAS7oC,KAIrCspC,GAAOT,EAAS,UAAU7oC,OAC5BspC,EAAIC,aAAc,EAEtB,CACA,OAAOpwC,CACT,CACA,SAASqwC,GAAYh2B,EAAGC,GACtB,OAAKD,GAAMC,EACP,EAAQD,IAAM,EAAQC,GAAWD,EAAE8I,OAAO7I,GACvC,EAAO,CAAC,EAAG21B,GAAsB51B,GAAI41B,GAAsB31B,IAF7CD,GAAKC,CAG5B,CACA,SAASg2B,GAAqBtwC,EAAOuwC,GACnC,MAAM12B,EAAM,CAAC,EACb,IAAK,MAAMhT,KAAO7G,EACXuwC,EAAa1sB,SAAShd,IACzBnE,OAAO4V,eAAeuB,EAAKhT,EAAK,CAC9B2R,YAAY,EACZ/T,IAAK,IAAMzE,EAAM6G,KAIvB,OAAOgT,CACT,CACA,SAAS22B,GAAiBC,GACxB,MAAMvf,EAAM+I,KAMZ,IAAIyW,EAAYD,IAQhB,OAPAE,KACIl6B,EAAUi6B,KACZA,EAAYA,EAAUh6B,MAAOvS,IAE3B,MADAomC,GAAmBrZ,GACb/sB,KAGH,CAACusC,EAAW,IAAMnG,GAAmBrZ,GAC9C,CAYA,IAAIud,IAAoB,EAuOxB,SAASnT,GAAS/I,EAAMjF,EAAUptB,GAChCstB,GACE,EAAQ+E,GAAQA,EAAKrd,IAAK07B,GAAMA,EAAEzvB,KAAKmM,EAAS5D,QAAU6I,EAAKpR,KAAKmM,EAAS5D,OAC7E4D,EACAptB,EAEJ,CACA,SAAS2wC,GAAcjuB,EAAKsO,EAAK4f,EAAYjqC,GAC3C,IAAIkqC,EAASlqC,EAAIgd,SAAS,KAAOmtB,GAAiBF,EAAYjqC,GAAO,IAAMiqC,EAAWjqC,GACtF,GAAI,EAAS+b,GAAM,CACjB,MAAMquB,EAAU/f,EAAItO,GAChB,EAAWquB,IAEX,GAAMF,EAAQE,EAKpB,MAAO,GAAI,EAAWruB,GAElB,GAAMmuB,EAAQnuB,EAAIzB,KAAK2vB,SAEpB,GAAI,EAASluB,GAClB,GAAI,EAAQA,GACVA,EAAInY,QAASqf,GAAM+mB,GAAc/mB,EAAGoH,EAAK4f,EAAYjqC,QAChD,CACL,MAAMoqC,EAAU,EAAWruB,EAAIquB,SAAWruB,EAAIquB,QAAQ9vB,KAAK2vB,GAAc5f,EAAItO,EAAIquB,SAC7E,EAAWA,IACb,GAAMF,EAAQE,EAASruB,EAI3B,CAIJ,CACA,SAASmrB,GAAqBzgB,GAC5B,MAAM4jB,EAAO5jB,EAASptB,MAChB,OAAEixC,EAAQC,QAASC,GAAmBH,GAE1CC,OAAQG,EACRC,aAAcn6B,EACd0W,QAAQ,sBAAE0jB,IACRlkB,EAASO,WACPwa,EAASjxB,EAAM3S,IAAIysC,GACzB,IAAIO,EAmBJ,OAlBIpJ,EACFoJ,EAAWpJ,EACDiJ,EAAa9rC,QAAW2rC,GAAWE,GAK7CI,EAAW,CAAC,EACRH,EAAa9rC,QACf8rC,EAAa7mC,QACV8sB,GAAMma,GAAaD,EAAUla,EAAGia,GAAuB,IAG5DE,GAAaD,EAAUP,EAAMM,IAT3BC,EAAWP,EAWX,EAASA,IACX95B,EAAM+K,IAAI+uB,EAAMO,GAEXA,CACT,CACA,SAASC,GAAa5iC,EAAID,EAAM8iC,EAAQC,GAAU,GAChD,MAAM,OAAET,EAAQC,QAASC,GAAmBxiC,EACxCwiC,GACFK,GAAa5iC,EAAIuiC,EAAgBM,GAAQ,GAEvCR,GACFA,EAAO1mC,QACJ8sB,GAAMma,GAAa5iC,EAAIyoB,EAAGoa,GAAQ,IAGvC,IAAK,MAAM9qC,KAAOgI,EAChB,GAAI+iC,GAAmB,WAAR/qC,OAIR,CACL,MAAMgrC,EAAQC,GAA0BjrC,IAAQ8qC,GAAUA,EAAO9qC,GACjEiI,EAAGjI,GAAOgrC,EAAQA,EAAM/iC,EAAGjI,GAAMgI,EAAKhI,IAAQgI,EAAKhI,EACrD,CAEF,OAAOiI,CACT,CACA,MAAMgjC,GAA4B,CAChCjxC,KAAMkxC,GACN/xC,MAAOgyC,GACPC,MAAOD,GAEPhwC,QAASkwC,GACTrwC,SAAUqwC,GAEVC,aAAcC,GACdC,QAASD,GACTE,YAAaF,GACbttC,QAASstC,GACTG,aAAcH,GACdngB,QAASmgB,GACTI,cAAeJ,GACfK,cAAeL,GACfM,UAAWN,GACXO,UAAWP,GACXQ,UAAWR,GACXS,YAAaT,GACbU,cAAeV,GACfW,eAAgBX,GAEhBY,WAAYd,GACZvgB,WAAYugB,GAEZpuC,MAoDF,SAA2BgL,EAAID,GAC7B,IAAKC,EAAI,OAAOD,EAChB,IAAKA,EAAM,OAAOC,EAClB,MAAMmkC,EAAS,EAAuBvwC,OAAOyS,OAAO,MAAOrG,GAC3D,IAAK,MAAMjI,KAAOgI,EAChBokC,EAAOpsC,GAAOurC,GAAatjC,EAAGjI,GAAMgI,EAAKhI,IAE3C,OAAOosC,CACT,EA1DE5/B,QAAS0+B,GACTmB,OAgBF,SAAqBpkC,EAAID,GACvB,OAAOqjC,GAAmBiB,GAAgBrkC,GAAKqkC,GAAgBtkC,GACjE,GAhBA,SAASkjC,GAAYjjC,EAAID,GACvB,OAAKA,EAGAC,EAGE,WACL,OAAO,EACL,EAAWA,GAAMA,EAAGoH,KAAKnU,KAAMA,MAAQ+M,EACvC,EAAWD,GAAQA,EAAKqH,KAAKnU,KAAMA,MAAQ8M,EAE/C,EAPSA,EAHAC,CAWX,CAIA,SAASqkC,GAAgBvwB,GACvB,GAAI,EAAQA,GAAM,CAChB,MAAMtJ,EAAM,CAAC,EACb,IAAK,IAAIxD,EAAI,EAAGA,EAAI8M,EAAIpd,OAAQsQ,IAC9BwD,EAAIsJ,EAAI9M,IAAM8M,EAAI9M,GAEpB,OAAOwD,CACT,CACA,OAAOsJ,CACT,CACA,SAASwvB,GAAatjC,EAAID,GACxB,OAAOC,EAAK,IAAI,IAAI6W,IAAI,GAAGxC,OAAOrU,EAAID,KAAUA,CAClD,CACA,SAASqjC,GAAmBpjC,EAAID,GAC9B,OAAOC,EAAK,EAAuBpM,OAAOyS,OAAO,MAAOrG,EAAID,GAAQA,CACtE,CACA,SAASmjC,GAAyBljC,EAAID,GACpC,OAAIC,EACE,EAAQA,IAAO,EAAQD,GAClB,IAAoB,IAAI8W,IAAI,IAAI7W,KAAOD,KAEzC,EACWnM,OAAOyS,OAAO,MAC9B86B,GAAsBnhC,GACtBmhC,GAA8B,MAARphC,EAAeA,EAAO,CAAC,IAGxCA,CAEX,CAWA,SAASukC,KACP,MAAO,CACLjgC,IAAK,KACL2a,OAAQ,CACNulB,YAAa/9B,EACbg+B,aAAa,EACb1E,iBAAkB,CAAC,EACnB4C,sBAAuB,CAAC,EACxB7jB,kBAAc,EACd4lB,iBAAa,EACbC,gBAAiB,CAAC,GAEpBrC,OAAQ,GACR6B,WAAY,CAAC,EACbrhB,WAAY,CAAC,EACb8hB,SAA0B/wC,OAAOyS,OAAO,MACxCo8B,aAA8B,IAAI1vB,QAClC6xB,WAA4B,IAAI7xB,QAChC8xB,WAA4B,IAAI9xB,QAEpC,CACA,IAAI+xB,GAAQ,EACZ,SAASC,GAAaC,EAAQpd,GAC5B,OAAO,SAAmBqd,EAAeC,EAAY,MAC9C,EAAWD,KACdA,EAAgB,EAAO,CAAC,EAAGA,IAEZ,MAAbC,GAAsB,EAASA,KAEjCA,EAAY,MAEd,MAAMC,EAAUb,KACVc,EAAmC,IAAIr2B,QACvCs2B,EAAmB,GACzB,IAAIjc,GAAY,EAChB,MAAM/kB,EAAM8gC,EAAQ9gC,IAAM,CACxBihC,KAAMR,KACNS,WAAYN,EACZO,OAAQN,EACRO,WAAY,KACZC,SAAUP,EACVQ,UAAW,KACX30B,WACA,UAAIgO,GACF,OAAOmmB,EAAQnmB,MACjB,EACA,UAAIA,CAAOnS,GAMX,EACA1I,IAAG,CAACyhC,KAAWthC,KACT8gC,EAAiB71B,IAAIq2B,KAEdA,GAAU,EAAWA,EAAOxhC,UACrCghC,EAAiBtpC,IAAI8pC,GACrBA,EAAOxhC,QAAQC,KAAQC,IACd,EAAWshC,KACpBR,EAAiBtpC,IAAI8pC,GACrBA,EAAOvhC,KAAQC,KAMVD,GAETwhC,MAAMA,IAEGV,EAAQ9C,OAAOttB,SAAS8wB,IAC3BV,EAAQ9C,OAAOz0B,KAAKi4B,GASjBxhC,GAETG,UAAS,CAACvT,EAAMuT,IAITA,GAML2gC,EAAQjB,WAAWjzC,GAAQuT,EACpBH,GANE8gC,EAAQjB,WAAWjzC,GAQ9B60C,UAAS,CAAC70C,EAAM60C,IAITA,GAMLX,EAAQtiB,WAAW5xB,GAAQ60C,EACpBzhC,GANE8gC,EAAQtiB,WAAW5xB,GAQ9B,KAAA6U,CAAMigC,EAAeC,EAAWhhB,GAC9B,IAAKoE,EAAW,CAOd,MAAMxK,EAAQva,EAAI4hC,UAAYvU,GAAYuT,EAAeC,GA0BzD,OAzBAtmB,EAAMG,WAAaomB,GACD,IAAdngB,EACFA,EAAY,OACW,IAAdA,IACTA,OAAY,GASVghB,GAAape,EACfA,EAAQhJ,EAAOmnB,GAEff,EAAOpmB,EAAOmnB,EAAe/gB,GAE/BoE,GAAY,EACZ/kB,EAAIohC,WAAaM,EACjBA,EAAcG,YAAc7hC,EAKrBye,GAA2BlE,EAAMpa,UAC1C,CAMF,EACA,SAAA2hC,CAAUvoB,GAMRynB,EAAiBz3B,KAAKgQ,EACxB,EACA,OAAA0J,GACM8B,IACF1K,GACE2mB,EACAhhC,EAAIshC,UACJ,IAEFX,EAAO,KAAM3gC,EAAIohC,mBAKVphC,EAAIohC,WAAWS,YAI1B,EACA3hC,QAAO,CAACxM,EAAK0I,KAYX0kC,EAAQR,SAAS5sC,GAAO0I,EACjB4D,GAET,cAAA+hC,CAAe/9B,GACb,MAAMg+B,EAAUC,GAChBA,GAAajiC,EACb,IACE,OAAOgE,GACT,CAAE,QACAi+B,GAAaD,CACf,CACF,GAEF,OAAOhiC,CACT,CACF,CACA,IAAIiiC,GAAa,KAEjB,SAAS/hC,GAAQxM,EAAK0I,GACpB,GAAKw3B,GAIE,CACL,IAAI0M,EAAW1M,GAAgB0M,SAC/B,MAAM4B,EAAiBtO,GAAgBvqB,QAAUuqB,GAAgBvqB,OAAOi3B,SACpE4B,IAAmB5B,IACrBA,EAAW1M,GAAgB0M,SAAW/wC,OAAOyS,OAAOkgC,IAEtD5B,EAAS5sC,GAAO0I,CAClB,CACF,CACA,SAAS2jC,GAAOrsC,EAAKklB,EAAcupB,GAAwB,GACzD,MAAMhoB,EAAW2M,KACjB,GAAI3M,GAAY8nB,GAAY,CAC1B,IAAI3B,EAAW2B,GAAaA,GAAWZ,SAASf,SAAWnmB,EAA8B,MAAnBA,EAAS9Q,QAAkB8Q,EAASiI,GAAKjI,EAASI,MAAMG,YAAcP,EAASI,MAAMG,WAAW4lB,SAAWnmB,EAAS9Q,OAAOi3B,cAAW,EAC5M,GAAIA,GAAY5sC,KAAO4sC,EACrB,OAAOA,EAAS5sC,GACX,GAAI2c,UAAUhe,OAAS,EAC5B,OAAO8vC,GAAyB,EAAWvpB,GAAgBA,EAAa7V,KAAKoX,GAAYA,EAAS5D,OAASqC,CAI/G,CAGF,CACA,SAASwpB,KACP,SAAUtb,OAAwBmb,GACpC,CAEA,MAAMI,GAAsB,CAAC,EACvBC,GAAuB,IAAM/yC,OAAOyS,OAAOqgC,IAC3CE,GAAoBt9B,GAAQ1V,OAAO6jB,eAAenO,KAASo9B,GA4HjE,SAASG,GAAaroB,EAAU6M,EAAUn6B,EAAOytC,GAC/C,MAAOr6B,EAASwiC,GAAgBtoB,EAASkhB,aACzC,IACIqH,EADAC,GAAkB,EAEtB,GAAI3b,EACF,IAAK,IAAItzB,KAAOszB,EAAU,CACxB,GAAIljB,EAAepQ,GACjB,SAEF,MAAM0I,EAAQ4qB,EAAStzB,GACvB,IAAIkvC,EACA3iC,GAAW6C,EAAO7C,EAAS2iC,EAAW,EAASlvC,IAC5C+uC,GAAiBA,EAAa/xB,SAASkyB,IAGzCF,IAAkBA,EAAgB,CAAC,IAAIE,GAAYxmC,EAFpDvP,EAAM+1C,GAAYxmC,EAIVymC,GAAe1oB,EAAS2oB,aAAcpvC,IAC1CA,KAAO4mC,GAAUl+B,IAAUk+B,EAAM5mC,KACrC4mC,EAAM5mC,GAAO0I,EACbumC,GAAkB,EAGxB,CAEF,GAAIF,EAAc,CAChB,MAAMM,EAAkB,GAAMl2C,GACxBm2C,EAAaN,GAAiBzgC,EACpC,IAAK,IAAIU,EAAI,EAAGA,EAAI8/B,EAAapwC,OAAQsQ,IAAK,CAC5C,MAAMjP,EAAM+uC,EAAa9/B,GACzB9V,EAAM6G,GAAOuvC,GACXhjC,EACA8iC,EACArvC,EACAsvC,EAAWtvC,GACXymB,GACCrX,EAAOkgC,EAAYtvC,GAExB,CACF,CACA,OAAOivC,CACT,CACA,SAASM,GAAiBhjC,EAASpT,EAAO6G,EAAK0I,EAAO+d,EAAU+oB,GAC9D,MAAMlG,EAAM/8B,EAAQvM,GACpB,GAAW,MAAPspC,EAAa,CACf,MAAMmG,EAAargC,EAAOk6B,EAAK,WAC/B,GAAImG,QAAwB,IAAV/mC,EAAkB,CAClC,MAAMwc,EAAeokB,EAAI/vC,QACzB,GAAI+vC,EAAIjwC,OAASu4B,WAAa0X,EAAIC,aAAe,EAAWrkB,GAAe,CACzE,MAAM,cAAEwqB,GAAkBjpB,EAC1B,GAAIzmB,KAAO0vC,EACThnC,EAAQgnC,EAAc1vC,OACjB,CACL,MAAMyjC,EAAQC,GAAmBjd,GACjC/d,EAAQgnC,EAAc1vC,GAAOklB,EAAa7V,KACxC,KACAlW,GAEFsqC,GACF,CACF,MACE/6B,EAAQwc,EAENuB,EAASiI,IACXjI,EAASiI,GAAGihB,SAAS3vC,EAAK0I,EAE9B,CACI4gC,EAAI,KACFkG,IAAaC,EACf/mC,GAAQ,GACC4gC,EAAI,IAAsC,KAAV5gC,GAAgBA,IAAUkI,EAAU5Q,KAC7E0I,GAAQ,GAGd,CACA,OAAOA,CACT,CACA,MAAMknC,GAAkC,IAAI50B,QAC5C,SAAS60B,GAAsBrQ,EAAMxY,EAAY+jB,GAAU,GACzD,MAAMx6B,EAA+Bw6B,EAAU6E,GAAkB5oB,EAAW6lB,WACtErL,EAASjxB,EAAM3S,IAAI4hC,GACzB,GAAIgC,EACF,OAAOA,EAET,MAAMzlB,EAAMyjB,EAAKrmC,MACXuZ,EAAa,CAAC,EACdq8B,EAAe,GACrB,IAAIe,GAAa,EACjB,IAA4B,EAAWtQ,GAAO,CAC5C,MAAMuQ,EAAeC,IACnBF,GAAa,EACb,MAAO32C,EAAO4a,GAAQ87B,GAAsBG,EAAMhpB,GAAY,GAC9D,EAAOtU,EAAYvZ,GACf4a,GAAMg7B,EAAal5B,QAAQ9B,KAE5Bg3B,GAAW/jB,EAAWsjB,OAAO3rC,QAChCqoB,EAAWsjB,OAAO1mC,QAAQmsC,GAExBvQ,EAAK+K,SACPwF,EAAYvQ,EAAK+K,SAEf/K,EAAK8K,QACP9K,EAAK8K,OAAO1mC,QAAQmsC,EAExB,CACA,IAAKh0B,IAAQ+zB,EAIX,OAHI,EAAStQ,IACXjvB,EAAM+K,IAAIkkB,EAAMhxB,GAEXA,EAET,GAAI,EAAQuN,GACV,IAAK,IAAI9M,EAAI,EAAGA,EAAI8M,EAAIpd,OAAQsQ,IAAK,CAInC,MAAMghC,EAAgB,EAASl0B,EAAI9M,IAC/BihC,GAAiBD,KACnBv9B,EAAWu9B,GAAiB1hC,EAEhC,MACK,GAAIwN,EAIT,IAAK,MAAM/b,KAAO+b,EAAK,CACrB,MAAMk0B,EAAgB,EAASjwC,GAC/B,GAAIkwC,GAAiBD,GAAgB,CACnC,MAAM3G,EAAMvtB,EAAI/b,GACVmwC,EAAOz9B,EAAWu9B,GAAiB,EAAQ3G,IAAQ,EAAWA,GAAO,CAAEjwC,KAAMiwC,GAAQ,EAAO,CAAC,EAAGA,GAChG8G,EAAWD,EAAK92C,KACtB,IAAIg3C,GAAa,EACbC,GAAiB,EACrB,GAAI,EAAQF,GACV,IAAK,IAAItwC,EAAQ,EAAGA,EAAQswC,EAASzxC,SAAUmB,EAAO,CACpD,MAAMzG,EAAO+2C,EAAStwC,GAChBywC,EAAW,EAAWl3C,IAASA,EAAKH,KAC1C,GAAiB,YAAbq3C,EAAwB,CAC1BF,GAAa,EACb,KACF,CAAwB,WAAbE,IACTD,GAAiB,EAErB,MAEAD,EAAa,EAAWD,IAA+B,YAAlBA,EAASl3C,KAEhDi3C,EAAK,GAAsBE,EAC3BF,EAAK,GAA0BG,GAC3BD,GAAcjhC,EAAO+gC,EAAM,aAC7BpB,EAAal5B,KAAKo6B,EAEtB,CACF,CAEF,MAAMx9B,EAAM,CAACC,EAAYq8B,GAIzB,OAHI,EAASvP,IACXjvB,EAAM+K,IAAIkkB,EAAM/sB,GAEXA,CACT,CACA,SAASy9B,GAAiBlwC,GACxB,MAAe,MAAXA,EAAI,KAAeoQ,EAAepQ,EAMxC,CAqHA,MAAMwwC,GAAiBxwC,GAAgB,MAARA,GAAuB,SAARA,GAA0B,YAARA,EAC1DywC,GAAsB/nC,GAAU,EAAQA,GAASA,EAAM2F,IAAI2sB,IAAkB,CAACA,GAAetyB,IAC7FgoC,GAAgB,CAAC1wC,EAAK2wC,EAAStmB,KACnC,GAAIsmB,EAAQpmB,GACV,OAAOomB,EAET,MAAMj+B,EAAa0X,GAAQ,IAAI1gB,IAMtB+mC,GAAmBE,KAAWjnC,IACpC2gB,GAEH,OADA3X,EAAWkY,IAAK,EACTlY,GAEHk+B,GAAuB,CAACC,EAAU1d,EAAO1M,KAC7C,MAAM4D,EAAMwmB,EAASnyC,KACrB,IAAK,MAAMsB,KAAO6wC,EAAU,CAC1B,GAAIL,GAAcxwC,GAAM,SACxB,MAAM0I,EAAQmoC,EAAS7wC,GACvB,GAAI,EAAW0I,GACbyqB,EAAMnzB,GAAO0wC,GAAc1wC,EAAK0I,EAAO2hB,QAClC,GAAa,MAAT3hB,EAAe,CAMxB,MAAMgK,EAAa+9B,GAAmB/nC,GACtCyqB,EAAMnzB,GAAO,IAAM0S,CACrB,CACF,GAEIo+B,GAAsB,CAACrqB,EAAUuH,KAMrC,MAAMtb,EAAa+9B,GAAmBziB,GACtCvH,EAAS0M,MAAM55B,QAAU,IAAMmZ,GAE3Bq+B,GAAc,CAAC5d,EAAOnF,EAAUb,KACpC,IAAK,MAAMntB,KAAOguB,GACZb,GAAcqjB,GAAcxwC,KAC9BmzB,EAAMnzB,GAAOguB,EAAShuB,KAItBgxC,GAAY,CAACvqB,EAAUuH,EAAUb,KACrC,MAAMgG,EAAQ1M,EAAS0M,MAAQyb,KAC/B,GAA+B,GAA3BnoB,EAASI,MAAMkH,UAAgB,CACjC,MAAM10B,EAAO20B,EAASgY,EAClB3sC,GACF03C,GAAY5d,EAAOnF,EAAUb,GACzBA,GACF7b,EAAI6hB,EAAO,IAAK95B,GAAM,IAGxBu3C,GAAqB5iB,EAAUmF,EAEnC,MAAWnF,GACT8iB,GAAoBrqB,EAAUuH,IAG5BijB,GAAc,CAACxqB,EAAUuH,EAAUb,KACvC,MAAM,MAAEtG,EAAK,MAAEsM,GAAU1M,EACzB,IAAIyqB,GAAoB,EACpBC,EAA2B5iC,EAC/B,GAAsB,GAAlBsY,EAAMkH,UAAgB,CACxB,MAAM10B,EAAO20B,EAASgY,EAClB3sC,EAIS8zB,GAAsB,IAAT9zB,EACtB63C,GAAoB,EAEpBH,GAAY5d,EAAOnF,EAAUb,IAG/B+jB,GAAqBljB,EAASojB,QAC9BR,GAAqB5iB,EAAUmF,IAEjCge,EAA2BnjB,CAC7B,MAAWA,IACT8iB,GAAoBrqB,EAAUuH,GAC9BmjB,EAA2B,CAAE53C,QAAS,IAExC,GAAI23C,EACF,IAAK,MAAMlxC,KAAOmzB,EACXqd,GAAcxwC,IAAyC,MAAjCmxC,EAAyBnxC,WAC3CmzB,EAAMnzB,IAoEf8uB,GAAwBgM,GAC9B,SAASuW,GAAe9kC,GACtB,OAAO+kC,GAAmB/kC,EAC5B,CACA,SAASglC,GAAwBhlC,GAC/B,OAAO+kC,GAAmB/kC,EAAS8rB,GACrC,CACA,SAASiZ,GAAmB/kC,EAASilC,GAIpBp/B,IACRq/B,SAAU,EAIjB,MACE7jB,OAAQ8jB,EACR5tC,OAAQ0rB,EACRkJ,UAAWiZ,EACXzQ,cAAe0Q,EACf/jB,WAAYgkB,EACZ/jB,cAAegkB,EACfC,QAASC,EACTC,eAAgBC,EAChBliB,WAAYmiB,EACZpiB,YAAaqiB,EACbC,WAAYC,EAAiB,EAC7BC,oBAAqBC,GACnBjmC,EACEksB,EAAQ,CAAC9L,EAAIC,EAAIC,EAAWC,EAAS,KAAMC,EAAkB,KAAMC,EAAiB,KAAMC,OAAY,EAAQC,EAAe,KAAMC,IAAmFP,EAAGqB,mBAC7N,GAAItB,IAAOC,EACT,OAEED,IAAOoH,GAAgBpH,EAAIC,KAC7BE,EAAS2lB,EAAgB9lB,GACzB4C,EAAQ5C,EAAII,EAAiBC,GAAgB,GAC7CL,EAAK,OAEe,IAAlBC,EAAGmJ,YACL5I,GAAY,EACZP,EAAGqB,gBAAkB,MAEvB,MAAM,KAAE50B,EAAI,IAAE6pB,EAAG,UAAE6K,GAAcnB,EACjC,OAAQvzB,GACN,KAAK4/B,GACHyZ,EAAY/lB,EAAIC,EAAIC,EAAWC,GAC/B,MACF,KAAKmG,GACH0f,EAAmBhmB,EAAIC,EAAIC,EAAWC,GACtC,MACF,KAAKsM,GACO,MAANzM,GACFimB,EAAgBhmB,EAAIC,EAAWC,EAAQG,GAIzC,MACF,KAAK6I,GACH+c,EACElmB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAEF,MACF,QACkB,EAAZY,EACF+kB,EACEnmB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAEmB,EAAZY,EACTglB,EACEpmB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,IAEmB,GAAZY,GAaY,IAAZA,IAZT10B,EAAKqzB,QACHC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAmBG,MAAPlK,GAAe6J,EACjB0J,GAAOvT,EAAKyJ,GAAMA,EAAGzJ,IAAK8J,EAAgBJ,GAAMD,GAAKC,GACrC,MAAP1J,GAAeyJ,GAAgB,MAAVA,EAAGzJ,KACjCuT,GAAO9J,EAAGzJ,IAAK,KAAM8J,EAAgBL,GAAI,IAGvC+lB,EAAc,CAAC/lB,EAAIC,EAAIC,EAAWC,KACtC,GAAU,MAANH,EACF+kB,EACE9kB,EAAG5d,GAAK6iC,EAAejlB,EAAGoB,UAC1BnB,EACAC,OAEG,CACL,MAAM9d,EAAK4d,EAAG5d,GAAK2d,EAAG3d,GAClB4d,EAAGoB,WAAarB,EAAGqB,UACrBgkB,EAAYhjC,EAAI4d,EAAGoB,SAEvB,GAEI2kB,EAAqB,CAAChmB,EAAIC,EAAIC,EAAWC,KACnC,MAANH,EACF+kB,EACE9kB,EAAG5d,GAAK8iC,EAAkBllB,EAAGoB,UAAY,IACzCnB,EACAC,GAGFF,EAAG5d,GAAK2d,EAAG3d,IAGT4jC,EAAkB,CAAChmB,EAAIC,EAAWC,EAAQG,MAC7CL,EAAG5d,GAAI4d,EAAGE,QAAU0lB,EACnB5lB,EAAGoB,SACHnB,EACAC,EACAG,EACAL,EAAG5d,GACH4d,EAAGE,SAoCDgmB,EAAiB,CAACnmB,EAAIC,EAAIC,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,KAC3F,QAAZP,EAAGvzB,KACL4zB,EAAY,MACS,SAAZL,EAAGvzB,OACZ4zB,EAAY,UAEJ,MAANN,EACFqmB,EACEpmB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAGF8lB,EACEtmB,EACAC,EACAG,EACAC,EACAC,EACAC,EACAC,IAIA6lB,EAAe,CAACnsB,EAAOgG,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,KACxG,IAAIne,EACA4yB,EACJ,MAAM,MAAEzoC,EAAK,UAAE40B,EAAS,WAAEyH,EAAU,KAAEvK,GAASpE,EAyB/C,GAxBA7X,EAAK6X,EAAM7X,GAAK4iC,EACd/qB,EAAMxtB,KACN4zB,EACA9zB,GAASA,EAAM+X,GACf/X,GAEc,EAAZ40B,EACFmkB,EAAmBljC,EAAI6X,EAAMmH,UACR,GAAZD,GACTT,EACEzG,EAAMmH,SACNhf,EACA,KACA+d,EACAC,EACAkmB,GAAyBrsB,EAAOoG,GAChCC,EACAC,GAGAlC,GACFK,GAAoBzE,EAAO,KAAMkG,EAAiB,WAEpDslB,EAAWrjC,EAAI6X,EAAOA,EAAMof,QAAS/Y,EAAcH,GAC/C5zB,EAAO,CACT,IAAK,MAAM6G,KAAO7G,EACJ,UAAR6G,GAAoBoQ,EAAepQ,IACrC2xC,EAAc3iC,EAAIhP,EAAK,KAAM7G,EAAM6G,GAAMitB,EAAWF,GAGpD,UAAW5zB,GACbw4C,EAAc3iC,EAAI,QAAS,KAAM7V,EAAMuP,MAAOukB,IAE5C2U,EAAYzoC,EAAMwhC,qBACpBC,GAAgBgH,EAAW7U,EAAiBlG,EAEhD,CAKIoE,GACFK,GAAoBzE,EAAO,KAAMkG,EAAiB,eAEpD,MAAMkN,EAA0BC,GAAelN,EAAgBwI,GAC3DyE,GACFzE,EAAWZ,YAAY5lB,GAEzB0iC,EAAW1iC,EAAI6d,EAAWC,KACrB8U,EAAYzoC,GAASA,EAAM0hC,iBAAmBZ,GAA2BhP,IAC5E6D,GAAsB,KACpB8S,GAAahH,GAAgBgH,EAAW7U,EAAiBlG,GACzDoT,GAA2BzE,EAAWV,MAAM9lB,GAC5Cic,GAAQK,GAAoBzE,EAAO,KAAMkG,EAAiB,YACzDC,IAGDqlB,EAAa,CAACrjC,EAAI6X,EAAOof,EAAS/Y,EAAcH,KAIpD,GAHIkZ,GACFqM,EAAetjC,EAAIi3B,GAEjB/Y,EACF,IAAK,IAAIje,EAAI,EAAGA,EAAIie,EAAavuB,OAAQsQ,IACvCqjC,EAAetjC,EAAIke,EAAaje,IAGpC,GAAI8d,EAAiB,CACnB,IAAI+F,EAAU/F,EAAgB+F,QAI9B,GAAIjM,IAAUiM,GAAWsP,GAAWtP,EAAQz5B,QAAUy5B,EAAQ2C,YAAc5O,GAASiM,EAAQ4C,aAAe7O,GAAQ,CAClH,MAAMkU,EAAchO,EAAgBlG,MACpCwrB,EACErjC,EACA+rB,EACAA,EAAYkL,QACZlL,EAAY7N,aACZH,EAAgBpX,OAEpB,CACF,GAEI2X,EAAgB,CAACU,EAAUnB,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,EAAWzE,EAAQ,KAC/H,IAAK,IAAIzZ,EAAIyZ,EAAOzZ,EAAI+e,EAASrvB,OAAQsQ,IAAK,CAC5C,MAAM0gB,EAAQ3B,EAAS/e,GAAKke,EAAYgmB,GAAenlB,EAAS/e,IAAM+rB,GAAehN,EAAS/e,IAC9FwpB,EACE,KACA9I,EACA9C,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAEJ,GAEI8lB,EAAe,CAACtmB,EAAIC,EAAIG,EAAiBC,EAAgBC,EAAWC,EAAcC,KACtF,MAAMne,EAAK4d,EAAG5d,GAAK2d,EAAG3d,GAItB,IAAI,UAAE+mB,EAAS,gBAAE9H,EAAe,KAAEhD,GAAS2B,EAC3CmJ,GAA4B,GAAfpJ,EAAGoJ,UAChB,MAAMqd,EAAWzmB,EAAGxzB,OAASoV,EACvB8kC,EAAWzmB,EAAGzzB,OAASoV,EAC7B,IAAIqzB,EA2CJ,GA1CA7U,GAAmBumB,GAAcvmB,GAAiB,IAC9C6U,EAAYyR,EAASE,sBACvB3Y,GAAgBgH,EAAW7U,EAAiBH,EAAID,GAE9C1B,GACFK,GAAoBsB,EAAID,EAAII,EAAiB,gBAE/CA,GAAmBumB,GAAcvmB,GAAiB,IAM9CqmB,EAASxpC,WAAmC,MAAtBypC,EAASzpC,WAAqBwpC,EAAS9Y,aAAuC,MAAxB+Y,EAAS/Y,cACvF4X,EAAmBljC,EAAI,IAErBif,EACFP,EACEf,EAAGsB,gBACHA,EACAjf,EACA+d,EACAC,EACAkmB,GAAyBtmB,EAAIK,GAC7BC,GAKQC,GACVK,EACEb,EACAC,EACA5d,EACA,KACA+d,EACAC,EACAkmB,GAAyBtmB,EAAIK,GAC7BC,GACA,GAGA6I,EAAY,EAAG,CACjB,GAAgB,GAAZA,EACFyd,EAAWxkC,EAAIokC,EAAUC,EAAUtmB,EAAiBE,QAUpD,GARgB,EAAZ8I,GACEqd,EAASn6C,QAAUo6C,EAASp6C,OAC9B04C,EAAc3iC,EAAI,QAAS,KAAMqkC,EAASp6C,MAAOg0B,GAGrC,EAAZ8I,GACF4b,EAAc3iC,EAAI,QAASokC,EAASx3C,MAAOy3C,EAASz3C,MAAOqxB,GAE7C,EAAZ8I,EAAe,CACjB,MAAM0d,EAAgB7mB,EAAG8mB,aACzB,IAAK,IAAIzkC,EAAI,EAAGA,EAAIwkC,EAAc90C,OAAQsQ,IAAK,CAC7C,MAAMjP,EAAMyzC,EAAcxkC,GACpBsK,EAAO65B,EAASpzC,GAChBqX,EAAOg8B,EAASrzC,GAClBqX,IAASkC,GAAgB,UAARvZ,GACnB2xC,EAAc3iC,EAAIhP,EAAKuZ,EAAMlC,EAAM4V,EAAWF,EAElD,CACF,CAEc,EAAZgJ,GACEpJ,EAAGqB,WAAapB,EAAGoB,UACrBkkB,EAAmBljC,EAAI4d,EAAGoB,SAGhC,MAAYb,GAAgC,MAAnBc,GACvBulB,EAAWxkC,EAAIokC,EAAUC,EAAUtmB,EAAiBE,KAEjD2U,EAAYyR,EAASM,iBAAmB1oB,IAC3C6D,GAAsB,KACpB8S,GAAahH,GAAgBgH,EAAW7U,EAAiBH,EAAID,GAC7D1B,GAAQK,GAAoBsB,EAAID,EAAII,EAAiB,YACpDC,IAGDU,EAAqB,CAACkmB,EAAaC,EAAaC,EAAmB/mB,EAAiBC,EAAgBC,EAAWC,KACnH,IAAK,IAAIje,EAAI,EAAGA,EAAI4kC,EAAYl1C,OAAQsQ,IAAK,CAC3C,MAAM8kC,EAAWH,EAAY3kC,GACvB+kC,EAAWH,EAAY5kC,GACvB4d,EAGJknB,EAAS/kC,KAER+kC,EAAS16C,OAASy8B,KAElB/B,GAAgBggB,EAAUC,IACN,IAArBD,EAAShmB,WAA8BokB,EAAe4B,EAAS/kC,IAAM,EAMvEypB,EACEsb,EACAC,EACAnnB,EACA,KACAE,EACAC,EACAC,EACAC,GACA,EAEJ,GAEIsmB,EAAa,CAACxkC,EAAIokC,EAAUC,EAAUtmB,EAAiBE,KAC3D,GAAImmB,IAAaC,EAAU,CACzB,GAAID,IAAa7kC,EACf,IAAK,MAAMvO,KAAOozC,EACXhjC,EAAepQ,IAAUA,KAAOqzC,GACnC1B,EACE3iC,EACAhP,EACAozC,EAASpzC,GACT,KACAitB,EACAF,GAKR,IAAK,MAAM/sB,KAAOqzC,EAAU,CAC1B,GAAIjjC,EAAepQ,GAAM,SACzB,MAAMqX,EAAOg8B,EAASrzC,GAChBuZ,EAAO65B,EAASpzC,GAClBqX,IAASkC,GAAgB,UAARvZ,GACnB2xC,EAAc3iC,EAAIhP,EAAKuZ,EAAMlC,EAAM4V,EAAWF,EAElD,CACI,UAAWsmB,GACb1B,EAAc3iC,EAAI,QAASokC,EAAS1qC,MAAO2qC,EAAS3qC,MAAOukB,EAE/D,GAEI4lB,EAAkB,CAAClmB,EAAIC,EAAIC,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,KAC5G,MAAM8mB,EAAsBrnB,EAAG5d,GAAK2d,EAAKA,EAAG3d,GAAK6iC,EAAe,IAC1DqC,EAAoBtnB,EAAGE,OAASH,EAAKA,EAAGG,OAAS+kB,EAAe,IACtE,IAAI,UAAE9b,EAAS,gBAAE9H,EAAiBf,aAAcgO,GAAyBtO,EAOrEsO,IACFhO,EAAeA,EAAeA,EAAa5Q,OAAO4e,GAAwBA,GAElE,MAANvO,GACF+kB,EAAWuC,EAAqBpnB,EAAWC,GAC3C4kB,EAAWwC,EAAmBrnB,EAAWC,GACzCQ,EAKEV,EAAGoB,UAAY,GACfnB,EACAqnB,EACAnnB,EACAC,EACAC,EACAC,EACAC,IAGE4I,EAAY,GAAiB,GAAZA,GAAkB9H,GAEvCtB,EAAGsB,iBACDP,EACEf,EAAGsB,gBACHA,EACApB,EACAE,EACAC,EACAC,EACAC,IASU,MAAVN,EAAG5sB,KAAe+sB,GAAmBH,IAAOG,EAAgB+F,UAE5D3D,GACExC,EACAC,GACA,IAKJY,EACEb,EACAC,EACAC,EACAqnB,EACAnnB,EACAC,EACAC,EACAC,EACAC,IAKF4lB,EAAmB,CAACpmB,EAAIC,EAAIC,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,KAC7GP,EAAGM,aAAeA,EACR,MAANP,EACiB,IAAfC,EAAGmB,UACLhB,EAAgB1C,IAAIoX,SAClB7U,EACAC,EACAC,EACAG,EACAE,GAGFqL,EACE5L,EACAC,EACAC,EACAC,EACAC,EACAC,EACAE,GAIJgnB,EAAgBxnB,EAAIC,EAAIO,IAGtBqL,EAAiB,CAAC4b,EAAcvnB,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWE,KACnG,MAAM1G,EAAY2tB,EAAa3nC,UAAY4nC,GACzCD,EACArnB,EACAC,GAsBF,GAbIsI,GAAY8e,KACd3tB,EAAS4D,IAAI0W,SAAW3T,GAMxBknB,GAAe7tB,GAAU,EAAO0G,GAM9B1G,EAAS8tB,UAEX,GADAvnB,GAAkBA,EAAewnB,YAAY/tB,EAAUguB,EAAmBtnB,IACrEinB,EAAaplC,GAAI,CACpB,MAAMkf,EAAczH,EAASqM,QAAU6G,GAAY1G,IACnD0f,EAAmB,KAAMzkB,EAAarB,EAAWC,GACjDsnB,EAAalmB,YAAcA,EAAYlf,EACzC,OAEAylC,EACEhuB,EACA2tB,EACAvnB,EACAC,EACAE,EACAC,EACAE,IAQAgnB,EAAkB,CAACxnB,EAAIC,EAAIO,KAC/B,MAAM1G,EAAWmG,EAAGngB,UAAYkgB,EAAGlgB,UACnC,GAu6CJ,SAA+B8e,EAAWmpB,EAAWvnB,GACnD,MAAQh0B,MAAOw7C,EAAW3mB,SAAU4mB,EAAY,UAAEnoC,GAAc8e,GACxDpyB,MAAO07C,EAAW7mB,SAAU8mB,EAAY,UAAE/e,GAAc2e,EAC1DtJ,EAAQ3+B,EAAU2iC,aAIxB,GAAIsF,EAAUzpB,MAAQypB,EAAUlf,WAC9B,OAAO,EAET,KAAIrI,GAAa4I,GAAa,GAmB5B,SAAI6e,IAAgBE,GACbA,GAAiBA,EAAa1D,UAIjCuD,IAAcE,IAGbF,GAGAE,GAGEE,GAAgBJ,EAAWE,EAAWzJ,KALlCyJ,GA3BX,GAAgB,KAAZ9e,EACF,OAAO,EAET,GAAgB,GAAZA,EACF,OAAK4e,EAGEI,GAAgBJ,EAAWE,EAAWzJ,KAFlCyJ,EAGN,GAAgB,EAAZ9e,EAAe,CACxB,MAAM2d,EAAegB,EAAUhB,aAC/B,IAAK,IAAIzkC,EAAI,EAAGA,EAAIykC,EAAa/0C,OAAQsQ,IAAK,CAC5C,MAAMjP,EAAM0zC,EAAazkC,GACzB,GAAI4lC,EAAU70C,KAAS20C,EAAU30C,KAASmvC,GAAe/D,EAAOprC,GAC9D,OAAO,CAEX,CACF,CAkBF,OAAO,CACT,CAr9CQg1C,CAAsBroB,EAAIC,EAAIO,GAAY,CAC5C,GAAI1G,EAAS8tB,WAAa9tB,EAASwuB,cAQjC,YAJAC,EAAyBzuB,EAAUmG,EAAIO,GAMvC1G,EAASpP,KAAOuV,EAChBnG,EAASyN,QAEb,MACEtH,EAAG5d,GAAK2d,EAAG3d,GACXyX,EAASI,MAAQ+F,GAGf6nB,EAAoB,CAAChuB,EAAU2tB,EAAcvnB,EAAWC,EAAQE,EAAgBC,EAAWE,KAC/F,MAAMgoB,EAAoB,KACxB,GAAK1uB,EAAS4K,UA4FP,CACL,IAAI,KAAEha,EAAI,GAAEwoB,EAAE,EAAEuV,EAAC,OAAEz/B,EAAM,MAAEkR,GAAUJ,EACrC,CACE,MAAM4uB,EAAuBC,GAA2B7uB,GACxD,GAAI4uB,EAUF,OATIh+B,IACFA,EAAKrI,GAAK6X,EAAM7X,GAChBkmC,EAAyBzuB,EAAUpP,EAAM8V,SAE3CkoB,EAAqBd,SAAS12C,KAAK,KAC5B4oB,EAASwZ,aACZkV,KAKR,CACA,IACIvT,EADA2T,EAAal+B,EAKjBi8B,GAAc7sB,GAAU,GACpBpP,GACFA,EAAKrI,GAAK6X,EAAM7X,GAChBkmC,EAAyBzuB,EAAUpP,EAAM8V,IAEzC9V,EAAOwP,EAELgZ,GACF1uB,EAAe0uB,IAEb+B,EAAYvqB,EAAKle,OAASke,EAAKle,MAAMo6C,sBACvC3Y,GAAgBgH,EAAWjsB,EAAQ0B,EAAMwP,GAE3CysB,GAAc7sB,GAAU,GAIxB,MAAM+uB,EAAWC,GAAoBhvB,GAI/BivB,EAAWjvB,EAASqM,QAC1BrM,EAASqM,QAAU0iB,EAInB/c,EACEid,EACAF,EAEArD,EAAeuD,EAAS1mC,IAExByjC,EAAgBiD,GAChBjvB,EACAuG,EACAC,GAKF5V,EAAKrI,GAAKwmC,EAASxmC,GACA,OAAfumC,GACFja,GAAgB7U,EAAU+uB,EAASxmC,IAEjComC,GACFtmB,GAAsBsmB,EAAGpoB,IAEvB4U,EAAYvqB,EAAKle,OAASke,EAAKle,MAAMw6C,iBACvC7kB,GACE,IAAM8L,GAAgBgH,EAAWjsB,EAAQ0B,EAAMwP,GAC/CmG,EASN,KA7KyB,CACvB,IAAI4U,EACJ,MAAM,GAAE5yB,EAAE,MAAE7V,GAAUi7C,GAChB,GAAEuB,EAAE,EAAEjlB,EAAC,OAAE/a,EAAM,KAAEoxB,EAAI,KAAE1tC,GAASotB,EAChCmvB,EAAsB/e,GAAeud,GAS3C,GARAd,GAAc7sB,GAAU,GACpBkvB,GACFxkC,EAAewkC,IAEZC,IAAwBhU,EAAYzoC,GAASA,EAAMwhC,qBACtDC,GAAgBgH,EAAWjsB,EAAQy+B,GAErCd,GAAc7sB,GAAU,GACpBzX,GAAM2pB,GAAa,CACrB,MAAMkd,EAAiB,KAIrBpvB,EAASqM,QAAU2iB,GAAoBhvB,GAOvCkS,GACE3pB,EACAyX,EAASqM,QACTrM,EACAuG,EACA,OAMA4oB,GAAuBv8C,EAAKsmC,eAC9BtmC,EAAKsmC,eACH3wB,EACAyX,EACAovB,GAGFA,GAEJ,KAAO,CACD9O,EAAKrY,KACmB,IAA5BqY,EAAKrY,GAAGonB,KAAKC,YACXhP,EAAKrY,GAAGsnB,kBAAkB38C,GAK5B,MAAMy5B,EAAUrM,EAASqM,QAAU2iB,GAAoBhvB,GAOvDgS,EACE,KACA3F,EACAjG,EACAC,EACArG,EACAuG,EACAC,GAKFmnB,EAAaplC,GAAK8jB,EAAQ9jB,EAC5B,CAIA,GAHI0hB,GACF5B,GAAsB4B,EAAG1D,IAEtB4oB,IAAwBhU,EAAYzoC,GAASA,EAAM0hC,gBAAiB,CACvE,MAAMob,EAAqB7B,EAC3BtlB,GACE,IAAM8L,GAAgBgH,EAAWjsB,EAAQsgC,GACzCjpB,EAEJ,EAC6B,IAAzBonB,EAAarmB,WAAmBpY,GAAUkhB,GAAelhB,EAAOkR,QAAmC,IAAzBlR,EAAOkR,MAAMkH,YACzFtH,EAASjT,GAAKsb,GAAsBrI,EAASjT,EAAGwZ,GAElDvG,EAAS4K,WAAY,EAIrB+iB,EAAevnB,EAAYC,EAAS,IACtC,GAmFFrG,EAASyvB,MAAM9/B,KACf,MAAMgE,EAASqM,EAASrM,OAAS,IAAInD,GAAek+B,GACpD1uB,EAASyvB,MAAM5/B,MACf,MAAM4d,EAASzN,EAASyN,OAAS9Z,EAAOlE,IAAIoE,KAAKF,GAC3CkO,EAAM7B,EAAS6B,IAAMlO,EAAO9B,WAAWgC,KAAKF,GAClDkO,EAAIrZ,EAAIwX,EACR6B,EAAI7oB,GAAKgnB,EAAS4C,IAClBjP,EAAO7C,UAAY,IAAM8Q,GAASC,GAClCgrB,GAAc7sB,GAAU,GAKxByN,KAEIghB,EAA2B,CAACzuB,EAAUiuB,EAAWvnB,KACrDunB,EAAUjoC,UAAYga,EACtB,MAAMkuB,EAAYluB,EAASI,MAAM1tB,MACjCstB,EAASI,MAAQ6tB,EACjBjuB,EAASpP,KAAO,KA52CpB,SAAqBoP,EAAU6M,EAAU6iB,EAAchpB,GACrD,MAAM,MACJh0B,EAAK,MACLytC,EACA/f,OAAO,UAAEkP,IACPtP,EACE4oB,EAAkB,GAAMl2C,IACvBoT,GAAWka,EAASkhB,aAC3B,IAAIsH,GAAkB,EACtB,KAI+E9hB,GAAa4I,EAAY,IAAoB,GAAZA,EAmCzG,CAIL,IAAIqgB,EAHAtH,GAAaroB,EAAU6M,EAAUn6B,EAAOytC,KAC1CqI,GAAkB,GAGpB,IAAK,MAAMjvC,KAAOqvC,EACX/b,IACJlkB,EAAOkkB,EAAUtzB,KAEhBo2C,EAAWxlC,EAAU5Q,MAAUA,GAAQoP,EAAOkkB,EAAU8iB,MACpD7pC,GACE4pC,QACmB,IAAtBA,EAAan2C,SACa,IAA3Bm2C,EAAaC,KACXj9C,EAAM6G,GAAOuvC,GACXhjC,EACA8iC,EACArvC,OACA,EACAymB,GACA,WAIGttB,EAAM6G,IAInB,GAAI4mC,IAAUyI,EACZ,IAAK,MAAMrvC,KAAO4mC,EACXtT,GAAalkB,EAAOkkB,EAAUtzB,YAC1B4mC,EAAM5mC,GACbivC,GAAkB,EAI1B,MArEE,GAAgB,EAAZlZ,EAAe,CACjB,MAAM0d,EAAgBhtB,EAASI,MAAM6sB,aACrC,IAAK,IAAIzkC,EAAI,EAAGA,EAAIwkC,EAAc90C,OAAQsQ,IAAK,CAC7C,IAAIjP,EAAMyzC,EAAcxkC,GACxB,GAAIkgC,GAAe1oB,EAAS2oB,aAAcpvC,GACxC,SAEF,MAAM0I,EAAQ4qB,EAAStzB,GACvB,GAAIuM,EACF,GAAI6C,EAAOw3B,EAAO5mC,GACZ0I,IAAUk+B,EAAM5mC,KAClB4mC,EAAM5mC,GAAO0I,EACbumC,GAAkB,OAEf,CACL,MAAMoH,EAAe,EAASr2C,GAC9B7G,EAAMk9C,GAAgB9G,GACpBhjC,EACA8iC,EACAgH,EACA3tC,EACA+d,GACA,EAEJ,MAEI/d,IAAUk+B,EAAM5mC,KAClB4mC,EAAM5mC,GAAO0I,EACbumC,GAAkB,EAGxB,CACF,CAsCEA,GACFv3B,GAAQ+O,EAASmgB,MAAO,MAAO,GAKnC,CAkxCI0P,CAAY7vB,EAAUiuB,EAAUv7C,MAAOw7C,EAAWxnB,GAClD8jB,GAAYxqB,EAAUiuB,EAAU1mB,SAAUb,GAC1C,KACA/D,GAAiB3C,GACjB,MAEI+G,EAAgB,CAACb,EAAIC,EAAIC,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,GAAY,KACtH,MAAMopB,EAAK5pB,GAAMA,EAAGqB,SACdwoB,EAAgB7pB,EAAKA,EAAGoB,UAAY,EACpC0oB,EAAK7pB,EAAGoB,UACR,UAAE+H,EAAS,UAAEhI,GAAcnB,EACjC,GAAImJ,EAAY,EAAG,CACjB,GAAgB,IAAZA,EAYF,YAXA2gB,EACEH,EACAE,EACA5pB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAGG,GAAgB,IAAZ4I,EAYT,YAXA4gB,EACEJ,EACAE,EACA5pB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAIN,CACgB,EAAZY,GACkB,GAAhByoB,GACFI,EAAgBL,EAAIxpB,EAAiBC,GAEnCypB,IAAOF,GACTrE,EAAmBrlB,EAAW4pB,IAGZ,GAAhBD,EACc,GAAZzoB,EACF2oB,EACEH,EACAE,EACA5pB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAGFypB,EAAgBL,EAAIxpB,EAAiBC,GAAgB,IAGnC,EAAhBwpB,GACFtE,EAAmBrlB,EAAW,IAEhB,GAAZkB,GACFT,EACEmpB,EACA5pB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,KAMJwpB,EAAuB,CAACJ,EAAIE,EAAI5pB,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,KAEjHspB,EAAKA,GAAMjoC,EACX,MAAMqoC,GAFNN,EAAKA,GAAM/nC,GAEU7P,OACfgd,EAAY86B,EAAG93C,OACfm4C,EAAeC,KAAKC,IAAIH,EAAWl7B,GACzC,IAAI1M,EACJ,IAAKA,EAAI,EAAGA,EAAI6nC,EAAc7nC,IAAK,CACjC,MAAMgoC,EAAYR,EAAGxnC,GAAKke,EAAYgmB,GAAesD,EAAGxnC,IAAM+rB,GAAeyb,EAAGxnC,IAChFwpB,EACE8d,EAAGtnC,GACHgoC,EACApqB,EACA,KACAE,EACAC,EACAC,EACAC,EACAC,EAEJ,CACI0pB,EAAYl7B,EACdi7B,EACEL,EACAxpB,EACAC,GACA,GACA,EACA8pB,GAGFxpB,EACEmpB,EACA5pB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACA2pB,IAIAJ,EAAqB,CAACH,EAAIE,EAAI5pB,EAAW4D,EAAc1D,EAAiBC,EAAgBC,EAAWC,EAAcC,KACrH,IAAIle,EAAI,EACR,MAAMioC,EAAKT,EAAG93C,OACd,IAAIw4C,EAAKZ,EAAG53C,OAAS,EACjBy4C,EAAKF,EAAK,EACd,KAAOjoC,GAAKkoC,GAAMloC,GAAKmoC,GAAI,CACzB,MAAMzqB,EAAK4pB,EAAGtnC,GACR2d,EAAK6pB,EAAGxnC,GAAKke,EAAYgmB,GAAesD,EAAGxnC,IAAM+rB,GAAeyb,EAAGxnC,IACzE,IAAI8kB,GAAgBpH,EAAIC,GAatB,MAZA6L,EACE9L,EACAC,EACAC,EACA,KACAE,EACAC,EACAC,EACAC,EACAC,GAKJle,GACF,CACA,KAAOA,GAAKkoC,GAAMloC,GAAKmoC,GAAI,CACzB,MAAMzqB,EAAK4pB,EAAGY,GACRvqB,EAAK6pB,EAAGW,GAAMjqB,EAAYgmB,GAAesD,EAAGW,IAAOpc,GAAeyb,EAAGW,IAC3E,IAAIrjB,GAAgBpH,EAAIC,GAatB,MAZA6L,EACE9L,EACAC,EACAC,EACA,KACAE,EACAC,EACAC,EACAC,EACAC,GAKJgqB,IACAC,GACF,CACA,GAAInoC,EAAIkoC,GACN,GAAIloC,GAAKmoC,EAAI,CACX,MAAMC,EAAUD,EAAK,EACftqB,EAASuqB,EAAUH,EAAKT,EAAGY,GAASroC,GAAKyhB,EAC/C,KAAOxhB,GAAKmoC,GACV3e,EACE,KACAge,EAAGxnC,GAAKke,EAAYgmB,GAAesD,EAAGxnC,IAAM+rB,GAAeyb,EAAGxnC,IAC9D4d,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAEFle,GAEJ,OACK,GAAIA,EAAImoC,EACb,KAAOnoC,GAAKkoC,GACV5nB,EAAQgnB,EAAGtnC,GAAI8d,EAAiBC,GAAgB,GAChD/d,QAEG,CACL,MAAMqoC,EAAKroC,EACLsoC,EAAKtoC,EACLuoC,EAAmC,IAAIj8B,IAC7C,IAAKtM,EAAIsoC,EAAItoC,GAAKmoC,EAAInoC,IAAK,CACzB,MAAMgoC,EAAYR,EAAGxnC,GAAKke,EAAYgmB,GAAesD,EAAGxnC,IAAM+rB,GAAeyb,EAAGxnC,IAC3D,MAAjBgoC,EAAUj3C,KAQZw3C,EAAiBl8B,IAAI27B,EAAUj3C,IAAKiP,EAExC,CACA,IAAIq2B,EACA1F,EAAU,EACd,MAAM6X,EAAcL,EAAKG,EAAK,EAC9B,IAAIG,GAAQ,EACRC,EAAmB,EACvB,MAAMC,EAAwB,IAAIl7C,MAAM+6C,GACxC,IAAKxoC,EAAI,EAAGA,EAAIwoC,EAAaxoC,IAAK2oC,EAAsB3oC,GAAK,EAC7D,IAAKA,EAAIqoC,EAAIroC,GAAKkoC,EAAIloC,IAAK,CACzB,MAAM4oC,EAAYtB,EAAGtnC,GACrB,GAAI2wB,GAAW6X,EAAa,CAC1BloB,EAAQsoB,EAAW9qB,EAAiBC,GAAgB,GACpD,QACF,CACA,IAAI8qB,EACJ,GAAqB,MAAjBD,EAAU73C,IACZ83C,EAAWN,EAAiB55C,IAAIi6C,EAAU73C,UAE1C,IAAKslC,EAAIiS,EAAIjS,GAAK8R,EAAI9R,IACpB,GAAsC,IAAlCsS,EAAsBtS,EAAIiS,IAAaxjB,GAAgB8jB,EAAWpB,EAAGnR,IAAK,CAC5EwS,EAAWxS,EACX,KACF,MAGa,IAAbwS,EACFvoB,EAAQsoB,EAAW9qB,EAAiBC,GAAgB,IAEpD4qB,EAAsBE,EAAWP,GAAMtoC,EAAI,EACvC6oC,GAAYH,EACdA,EAAmBG,EAEnBJ,GAAQ,EAEVjf,EACEof,EACApB,EAAGqB,GACHjrB,EACA,KACAE,EACAC,EACAC,EACAC,EACAC,GAEFyS,IAEJ,CACA,MAAMmY,EAA6BL,EAmWzC,SAAqB3oC,GACnB,MAAMqZ,EAAIrZ,EAAIiB,QACRkO,EAAS,CAAC,GAChB,IAAIjP,EAAGq2B,EAAG8P,EAAGtgC,EAAGrE,EAChB,MAAMunC,EAAMjpC,EAAIpQ,OAChB,IAAKsQ,EAAI,EAAGA,EAAI+oC,EAAK/oC,IAAK,CACxB,MAAMgpC,EAAOlpC,EAAIE,GACjB,GAAa,IAATgpC,EAAY,CAEd,GADA3S,EAAIpnB,EAAOA,EAAOvf,OAAS,GACvBoQ,EAAIu2B,GAAK2S,EAAM,CACjB7vB,EAAEnZ,GAAKq2B,EACPpnB,EAAOrI,KAAK5G,GACZ,QACF,CAGA,IAFAmmC,EAAI,EACJtgC,EAAIoJ,EAAOvf,OAAS,EACby2C,EAAItgC,GACTrE,EAAI2kC,EAAItgC,GAAK,EACT/F,EAAImP,EAAOzN,IAAMwnC,EACnB7C,EAAI3kC,EAAI,EAERqE,EAAIrE,EAGJwnC,EAAOlpC,EAAImP,EAAOk3B,MAChBA,EAAI,IACNhtB,EAAEnZ,GAAKiP,EAAOk3B,EAAI,IAEpBl3B,EAAOk3B,GAAKnmC,EAEhB,CACF,CAGA,IAFAmmC,EAAIl3B,EAAOvf,OACXmW,EAAIoJ,EAAOk3B,EAAI,GACRA,KAAM,GACXl3B,EAAOk3B,GAAKtgC,EACZA,EAAIsT,EAAEtT,GAER,OAAOoJ,CACT,CA1YiDg6B,CAAYN,GAAyBppC,EAEhF,IADA82B,EAAIyS,EAA2Bp5C,OAAS,EACnCsQ,EAAIwoC,EAAc,EAAGxoC,GAAK,EAAGA,IAAK,CACrC,MAAMkpC,EAAYZ,EAAKtoC,EACjBgoC,EAAYR,EAAG0B,GACfC,EAAc3B,EAAG0B,EAAY,GAC7BrrB,EAASqrB,EAAY,EAAIjB,EAE7BkB,EAAYppC,IAAMopC,EAAYlqB,YAC5BuC,EAC6B,IAA7BmnB,EAAsB3oC,GACxBwpB,EACE,KACAwe,EACApqB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAEOuqB,IACLpS,EAAI,GAAKr2B,IAAM8oC,EAA2BzS,GAC5C1V,EAAKqnB,EAAWpqB,EAAWC,EAAQ,GAEnCwY,IAGN,CACF,GAEI1V,EAAO,CAAC/I,EAAOgG,EAAWC,EAAQ6D,EAAU3D,EAAiB,QACjE,MAAM,GAAEhe,EAAE,KAAE3V,EAAI,WAAEm8B,EAAU,SAAExH,EAAQ,UAAED,GAAclH,EACtD,GAAgB,EAAZkH,EACF6B,EAAK/I,EAAMpa,UAAUqmB,QAASjG,EAAWC,EAAQ6D,QAGnD,GAAgB,IAAZ5C,EACFlH,EAAMuZ,SAASxQ,KAAK/C,EAAWC,EAAQ6D,QAGzC,GAAgB,GAAZ5C,EACF10B,EAAKu2B,KAAK/I,EAAOgG,EAAWC,EAAQM,QAGtC,GAAI/zB,IAASy8B,GAQb,GAAIz8B,IAAS+/B,GAKb,GADqC,IAAbzI,GAA8B,EAAZ5C,GAAiByH,EAEzD,GAAiB,IAAb7E,EACF6E,EAAWZ,YAAY5lB,GACvB0iC,EAAW1iC,EAAI6d,EAAWC,GAC1BgC,GAAsB,IAAM0G,EAAWV,MAAM9lB,GAAKge,OAC7C,CACL,MAAM,MAAEmI,EAAK,WAAEhB,EAAU,WAAEF,GAAeuB,EACpC6iB,EAAU,KACVxxB,EAAMwD,IAAI4V,YACZzQ,EAAWxgB,GAEX0iC,EAAW1iC,EAAI6d,EAAWC,IAGxBwrB,EAAe,KACftpC,EAAGupC,YACLvpC,EAAGiiB,KACD,GAIJkE,EAAMnmB,EAAI,KACRqpC,IACApkB,GAAcA,OAGdE,EACFA,EAAWnlB,EAAIqpC,EAASC,GAExBA,GAEJ,MAEA5G,EAAW1iC,EAAI6d,EAAWC,OA7/BP,GAAG9d,KAAI8d,UAAUD,EAAWkD,KACjD,IAAI1Y,EACJ,KAAOrI,GAAMA,IAAO8d,GAClBzV,EAAO+6B,EAAgBpjC,GACvB0iC,EAAW1iC,EAAI6d,EAAWkD,GAC1B/gB,EAAKqI,EAEPq6B,EAAW5kB,EAAQD,EAAWkD,IAi9B5ByoB,CAAe3xB,EAAOgG,EAAWC,OATnC,CACE4kB,EAAW1iC,EAAI6d,EAAWC,GAC1B,IAAK,IAAI7d,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IACnC2gB,EAAK5B,EAAS/e,GAAI4d,EAAWC,EAAQ6D,GAEvC+gB,EAAW7qB,EAAMiG,OAAQD,EAAWC,EAEtC,GA0CIyC,EAAU,CAAC1I,EAAOkG,EAAiBC,EAAgByC,GAAW,EAAOtC,GAAY,KACrF,MAAM,KACJ9zB,EAAI,MACJF,EAAK,IACL+pB,EAAG,SACH8K,EAAQ,gBACRC,EAAe,UACfF,EAAS,UACTgI,EAAS,KACT9K,EAAI,WACJwtB,GACE5xB,EAYJ,IAXmB,IAAfkP,IACF5I,GAAY,GAEH,MAAPjK,IACF,KACAuT,GAAOvT,EAAK,KAAM8J,EAAgBnG,GAAO,GACzC,MAEgB,MAAd4xB,IACF1rB,EAAgB2rB,YAAYD,QAAc,GAE5B,IAAZ1qB,EAEF,YADAhB,EAAgB1C,IAAIwX,WAAWhb,GAGjC,MAAM8xB,EAA+B,EAAZ5qB,GAAiB9C,EACpC2tB,GAAyB/hB,GAAehQ,GAC9C,IAAI+a,EAIJ,GAHIgX,IAA0BhX,EAAYzoC,GAASA,EAAM0/C,uBACvDje,GAAgBgH,EAAW7U,EAAiBlG,GAE9B,EAAZkH,EACF+qB,EAAiBjyB,EAAMpa,UAAWugB,EAAgByC,OAC7C,CACL,GAAgB,IAAZ1B,EAEF,YADAlH,EAAMuZ,SAAS7Q,QAAQvC,EAAgByC,GAGrCkpB,GACFrtB,GAAoBzE,EAAO,KAAMkG,EAAiB,iBAEpC,GAAZgB,EACFlH,EAAMxtB,KAAKyK,OACT+iB,EACAkG,EACAC,EACAI,EACAqC,GAEOxB,IAKVA,EAAgB8qB,UAChB1/C,IAASy8B,IAAYC,EAAY,GAAiB,GAAZA,GACrC6gB,EACE3oB,EACAlB,EACAC,GACA,GACA,IAEO3zB,IAASy8B,IAAwB,IAAZC,IAA4B5I,GAAyB,GAAZY,IACvE6oB,EAAgB5oB,EAAUjB,EAAiBC,GAEzCyC,GACF3rB,EAAO+iB,EAEX,EACI+xB,IAA0BhX,EAAYzoC,GAASA,EAAM6oC,mBAAqB2W,IAC5E7pB,GAAsB,KACpB8S,GAAahH,GAAgBgH,EAAW7U,EAAiBlG,GACzD8xB,GAAoBrtB,GAAoBzE,EAAO,KAAMkG,EAAiB,cACrEC,IAGDlpB,EAAU+iB,IACd,MAAM,KAAExtB,EAAI,GAAE2V,EAAE,OAAE8d,EAAM,WAAE0I,GAAe3O,EACzC,GAAIxtB,IAASy8B,GAYX,YAFEkjB,EAAehqC,EAAI8d,GAIvB,GAAIzzB,IAAS+/B,GAEX,WAxlCqB,GAAGpqB,KAAI8d,aAC9B,IAAIzV,EACJ,KAAOrI,GAAMA,IAAO8d,GAClBzV,EAAO+6B,EAAgBpjC,GACvBwgB,EAAWxgB,GACXA,EAAKqI,EAEPmY,EAAW1C,IAglCTmsB,CAAiBpyB,GAGnB,MAAMqyB,EAAgB,KACpB1pB,EAAWxgB,GACPwmB,IAAeA,EAAWxD,WAAawD,EAAWvB,YACpDuB,EAAWvB,cAGf,GAAsB,EAAlBpN,EAAMkH,WAAiByH,IAAeA,EAAWxD,UAAW,CAC9D,MAAM,MAAEmD,EAAK,WAAEhB,GAAeqB,EACxB8iB,EAAe,IAAMnjB,EAAMnmB,EAAIkqC,GACjC/kB,EACFA,EAAWtN,EAAM7X,GAAIkqC,EAAeZ,GAEpCA,GAEJ,MACEY,KAGEF,EAAiB,CAAC9xB,EAAKyB,KAC3B,IAAItR,EACJ,KAAO6P,IAAQyB,GACbtR,EAAO+6B,EAAgBlrB,GACvBsI,EAAWtI,GACXA,EAAM7P,EAERmY,EAAW7G,IAEPmwB,EAAmB,CAACryB,EAAUuG,EAAgByC,KAIlD,MAAM,IAAEuQ,EAAG,MAAEkW,EAAK,IAAE5tB,EAAG,QAAEwK,EAAO,GAAExD,EAAE,EAAEoB,EAAC,EAAEld,GAAMiT,EAC/Cqb,GAAgBpR,GAChBoR,GAAgBtuB,GACZwsB,GACF7uB,EAAe6uB,GAEjBkW,EAAM3/B,OACF+R,IACFA,EAAIlR,OAAS,EACbmY,EAAQuD,EAASrM,EAAUuG,EAAgByC,IAEzCH,GACFR,GAAsBQ,EAAItC,GAE5B8B,GAAsB,KACpBrI,EAASwZ,aAAc,GACtBjT,IAKC4pB,EAAkB,CAAC5oB,EAAUjB,EAAiBC,EAAgByC,GAAW,EAAOtC,GAAY,EAAOzE,EAAQ,KAC/G,IAAK,IAAIzZ,EAAIyZ,EAAOzZ,EAAI+e,EAASrvB,OAAQsQ,IACvCsgB,EAAQvB,EAAS/e,GAAI8d,EAAiBC,EAAgByC,EAAUtC,IAG9DslB,EAAmB5rB,IACvB,GAAsB,EAAlBA,EAAMkH,UACR,OAAO0kB,EAAgB5rB,EAAMpa,UAAUqmB,SAEzC,GAAsB,IAAlBjM,EAAMkH,UACR,OAAOlH,EAAMuZ,SAAS/oB,OAExB,MAAMrI,EAAKojC,EAAgBvrB,EAAMiG,QAAUjG,EAAM7X,IAC3CmqC,EAAcnqC,GAAMA,EAAG2c,IAC7B,OAAOwtB,EAAc/G,EAAgB+G,GAAenqC,GAEtD,IAAIoqC,GAAa,EACjB,MAAMnM,EAAS,CAACpmB,EAAOgG,EAAWI,KACnB,MAATpG,EACEgG,EAAUiP,QACZvM,EAAQ1C,EAAUiP,OAAQ,KAAM,MAAM,GAGxCrD,EACE5L,EAAUiP,QAAU,KACpBjV,EACAgG,EACA,KACA,KACA,KACAI,GAGJJ,EAAUiP,OAASjV,EACduyB,IACHA,GAAa,EACbhwB,KACAE,KACA8vB,GAAa,IAGXhsB,EAAY,CAChBhF,EAAGqQ,EACHnJ,GAAIC,EACJmB,EAAGd,EACH3M,EAAGnf,EACHy0B,GAAIC,EACJnL,GAAIC,EACJC,GAAIC,EACJC,IAAKC,EACL7b,EAAG4gC,EACH9kB,EAAGphB,GAEL,IAAIsjB,EACA8I,GAMJ,OALI6Y,KACD3hB,EAAS8I,IAAe6Y,EACvBpkB,IAGG,CACL6f,SACApd,UACA5jB,UAAW+gC,GAAaC,EAAQpd,GAEpC,CACA,SAASqjB,IAAyB,KAAE75C,EAAI,MAAEF,GAASkgD,GACjD,MAA4B,QAArBA,GAAuC,kBAAThgD,GAAiD,WAArBggD,GAA0C,mBAAThgD,GAA6BF,GAASA,EAAMmgD,UAAYngD,EAAMmgD,SAASt8B,SAAS,aAAU,EAASq8B,CACvM,CACA,SAAS/F,IAAc,OAAEl5B,EAAM,IAAEkO,GAAOixB,GAClCA,GACFn/B,EAAOhD,OAAS,GAChBkR,EAAIlR,OAAS,IAEbgD,EAAOhD,QAAU,GACjBkR,EAAIlR,QAAU,EAElB,CACA,SAAS8iB,GAAelN,EAAgBwI,GACtC,QAASxI,GAAkBA,IAAmBA,EAAewsB,gBAAkBhkB,IAAeA,EAAWxD,SAC3G,CACA,SAAS7C,GAAuBxC,EAAIC,EAAI9L,GAAU,GAChD,MAAM24B,EAAM9sB,EAAGqB,SACT0rB,EAAM9sB,EAAGoB,SACf,GAAI,EAAQyrB,IAAQ,EAAQC,GAC1B,IAAK,IAAIzqC,EAAI,EAAGA,EAAIwqC,EAAI96C,OAAQsQ,IAAK,CACnC,MAAMsnC,EAAKkD,EAAIxqC,GACf,IAAIwnC,EAAKiD,EAAIzqC,GACM,EAAfwnC,EAAG1oB,YAAkB0oB,EAAGxoB,mBACtBwoB,EAAG1gB,WAAa,GAAsB,KAAjB0gB,EAAG1gB,aAC1B0gB,EAAKiD,EAAIzqC,GAAKkkC,GAAeuG,EAAIzqC,IACjCwnC,EAAGznC,GAAKunC,EAAGvnC,IAER8R,IAA6B,IAAlB21B,EAAG1gB,WACjB5G,GAAuBonB,EAAIE,IAE3BA,EAAGp9C,OAAS4/B,KACE,IAAlBwd,EAAG1gB,YACD0gB,EAAGznC,GAAKunC,EAAGvnC,IAETynC,EAAGp9C,OAAS45B,IAAYwjB,EAAGznC,KAC7BynC,EAAGznC,GAAKunC,EAAGvnC,GAKf,CAEJ,CAyCA,SAASsmC,GAA2B7uB,GAClC,MAAMkzB,EAAelzB,EAASqM,QAAQrmB,UACtC,GAAIktC,EACF,OAAIA,EAAapF,WAAaoF,EAAa1E,cAClC0E,EAEArE,GAA2BqE,EAGxC,CACA,SAAS7X,GAAgBlO,GACvB,GAAIA,EACF,IAAK,IAAI3kB,EAAI,EAAGA,EAAI2kB,EAAMj1B,OAAQsQ,IAChC2kB,EAAM3kB,GAAGmI,OAAS,CAExB,CAEA,MAAMwiC,GAAgB1+B,OAAO7T,IAAI,SAC3BwyC,GAAgB,IAENxN,GAAOuN,IAUvB,SAASE,GAAY1/B,EAAQ7N,GAC3B,OAAOwtC,GAAQ3/B,EAAQ,KAAM7N,EAC/B,CACA,SAASytC,GAAgB5/B,EAAQ7N,GAC/B,OAAOwtC,GACL3/B,EACA,KACqF,CAAE6nB,MAAO,QAElG,CACA,SAASgY,GAAgB7/B,EAAQ7N,GAC/B,OAAOwtC,GACL3/B,EACA,KACqF,CAAE6nB,MAAO,QAElG,CACA,SAAS,GAAMpe,EAAQsF,EAAI5c,GAMzB,OAAOwtC,GAAQl2B,EAAQsF,EAAI5c,EAC7B,CACA,SAASwtC,GAAQl2B,EAAQsF,EAAI5c,EAAUgC,GACrC,MAAM,UAAE2rC,EAAS,KAAE7uB,EAAI,MAAE4W,EAAK,KAAElE,GAASxxB,EAkBnC4tC,EAAmB,EAAO,CAAC,EAAG5tC,GAE9B6tC,EAAkBjxB,GAAM+wB,IAAc/wB,GAAgB,SAAV8Y,EAClD,IAAIoY,EACJ,GAAIha,GACF,GAAc,SAAV4B,EAAkB,CACpB,MAAM5X,EAAMwvB,KACZQ,EAAahwB,EAAIiwB,mBAAqBjwB,EAAIiwB,iBAAmB,GAC/D,MAAO,IAAKF,EAAiB,CAC3B,MAAMG,EAAkB,OAKxB,OAHAA,EAAgBhkC,KAAO,EACvBgkC,EAAgBtkC,OAAS,EACzBskC,EAAgBxkC,MAAQ,EACjBwkC,CACT,CAEF,MAAM9zB,EAAWyZ,GACjBia,EAAiB9qC,KAAO,CAACiB,EAAIjX,EAAMqQ,IAASid,GAA2BrW,EAAImW,EAAUptB,EAAMqQ,GAC3F,IAAI8wC,GAAQ,EACE,SAAVvY,EACFkY,EAAiB5iC,UAAa+Q,IAC5BwG,GAAsBxG,EAAK7B,GAAYA,EAAS2Z,WAE/B,SAAV6B,IACTuY,GAAQ,EACRL,EAAiB5iC,UAAY,CAAC+Q,EAAKmyB,KAC7BA,EACFnyB,IAEAD,GAASC,KAIf6xB,EAAiBO,WAAcpyB,IACzBa,IACFb,EAAIlR,OAAS,GAEXojC,IACFlyB,EAAIlR,OAAS,EACTqP,IACF6B,EAAI7oB,GAAKgnB,EAAS4C,IAClBf,EAAIrZ,EAAIwX,KAId,MAAMk0B,EDj+IR,SAAe92B,EAAQsF,EAAI5c,EAAUgC,GACnC,MAAM,UAAE2rC,EAAS,KAAE7uB,EAAI,KAAE0S,EAAI,UAAExmB,EAAS,WAAEmjC,EAAU,KAAErrC,GAAS9C,EAQzDquC,EAAkBC,GAClBxvB,EAAawvB,EACb7+B,GAAU6+B,KAAqB,IAATxvB,GAA2B,IAATA,EACnCtF,GAAS80B,EAAS,GACpB90B,GAAS80B,GAElB,IAAIzgC,EACA8vB,EACA5yB,EACAwjC,EACAC,GAAe,EACfC,GAAgB,EA+CpB,GA9CI,GAAMn3B,IACRqmB,EAAS,IAAMrmB,EAAOnb,MACtBqyC,EAAe/+B,GAAU6H,IAChBd,GAAWc,IACpBqmB,EAAS,IAAM0Q,EAAe/2B,GAC9Bk3B,GAAe,GACN,EAAQl3B,IACjBm3B,GAAgB,EAChBD,EAAel3B,EAAOrG,KAAMy9B,GAAMl4B,GAAWk4B,IAAMj/B,GAAUi/B,IAC7D/Q,EAAS,IAAMrmB,EAAOxV,IAAK4sC,GACrB,GAAMA,GACDA,EAAEvyC,MACAqa,GAAWk4B,GACbL,EAAeK,GACb,EAAWA,GACb5rC,EAAOA,EAAK4rC,EAAG,GAAKA,SADtB,IAQP/Q,EAFO,EAAWrmB,GAChBsF,EACO9Z,EAAO,IAAMA,EAAKwU,EAAQ,GAAKA,EAE/B,KACP,GAAIvM,EAAS,CACX,KACA,IACEA,GACF,CAAE,QACA,IACF,CACF,CACA,MAAM4jC,EAAgBx1B,GACtBA,GAAgBtL,EAChB,IACE,OAAO/K,EAAOA,EAAKwU,EAAQ,EAAG,CAACi3B,IAAiBj3B,EAAOi3B,EACzD,CAAE,QACAp1B,GAAgBw1B,CAClB,GAIK,EAGP/xB,GAAMkC,EAAM,CACd,MAAM8vB,EAAajR,EACblkB,GAAiB,IAATqF,EAAgBpF,IAAWoF,EACzC6e,EAAS,IAAMnkB,GAASo1B,IAAcn1B,EACxC,CACA,MAAMkwB,EAAQt/B,KACR+jC,EAAc,KAClBvgC,EAAO7D,OACH2/B,GAASA,EAAMpgC,QACjBhS,EAAOoyC,EAAM1gC,QAAS4E,IAG1B,GAAI2jB,GAAQ5U,EAAI,CACd,MAAMiyB,EAAMjyB,EACZA,EAAK,IAAIzf,KACP0xC,KAAO1xC,GACPixC,IAEJ,CACA,IAAI1pC,EAAW+pC,EAAgB,IAAIt+C,MAAMmnB,EAAOllB,QAAQ4B,KAAKilB,IAAyBA,GACtF,MAAM8C,EAAO+yB,IACX,GAAqB,EAAfjhC,EAAOhD,QAAegD,EAAO5B,OAAU6iC,GAG7C,GAAIlyB,EAAI,CACN,MAAM3kB,EAAW4V,EAAOlE,MACxB,GAAImV,GAAQ0vB,IAAiBC,EAAgBx2C,EAASgZ,KAAK,CAAC1I,EAAG7F,IAAM+B,EAAW8D,EAAG7D,EAAShC,KAAO+B,EAAWxM,EAAUyM,IAAY,CAC9HqG,GACFA,IAEF,MAAMgkC,EAAiB51B,GACvBA,GAAgBtL,EAChB,IACE,MAAM1Q,EAAO,CACXlF,EAEAyM,IAAauU,QAAwB,EAASw1B,GAAiB/pC,EAAS,KAAOuU,GAAwB,GAAKvU,EAC5G6pC,GAEF7pC,EAAWzM,EACX6K,EAAOA,EAAK8Z,EAAI,EAAGzf,GAEjByf,KAAMzf,EAEV,CAAE,QACAgc,GAAgB41B,CAClB,CACF,CACF,MACElhC,EAAOlE,OAsCX,OAnCIwkC,GACFA,EAAWpyB,GAEblO,EAAS,IAAInD,GAAeizB,GAC5B9vB,EAAO7C,UAAYA,EAAY,IAAMA,EAAU+Q,GAAK,GAASA,EAC7DwyB,EAAgBxqC,GAAOsV,GAAiBtV,GAAI,EAAO8J,GACnD9C,EAAU8C,EAAO/B,OAAS,KACxB,MAAM5C,EAAWgQ,GAAW7nB,IAAIwc,GAChC,GAAI3E,EAAU,CACZ,GAAIpG,EACFA,EAAKoG,EAAU,QAEf,IAAK,MAAM8lC,KAAY9lC,EAAU8lC,IAEnC91B,GAAWhO,OAAO2C,EACpB,GAME+O,EACE+wB,EACF5xB,GAAI,GAEJrX,EAAWmJ,EAAOlE,MAEXqB,EACTA,EAAU+Q,EAAIhO,KAAK,MAAM,IAAO,GAEhCF,EAAOlE,MAETykC,EAAY5kC,MAAQqE,EAAOrE,MAAMuE,KAAKF,GACtCugC,EAAY1kC,OAASmE,EAAOnE,OAAOqE,KAAKF,GACxCugC,EAAYpkC,KAAOokC,EACZA,CACT,CCs0IsB19C,CAAQ4mB,EAAQsF,EAAIgxB,GAQxC,OAPI9Z,KACEga,EACFA,EAAWxkC,KAAK8kC,GACPP,GACTO,KAGGA,CACT,CACA,SAAStT,GAAcxjB,EAAQnb,EAAO6D,GACpC,MAAM09B,EAAa/uC,KAAK2nB,MAClBqnB,EAAS,EAASrmB,GAAUA,EAAO7G,SAAS,KAAOmtB,GAAiBF,EAAYpmB,GAAU,IAAMomB,EAAWpmB,GAAUA,EAAOvJ,KAAK2vB,EAAYA,GACnJ,IAAI9gB,EACA,EAAWzgB,GACbygB,EAAKzgB,GAELygB,EAAKzgB,EAAM0hC,QACX79B,EAAU7D,GAEZ,MAAM+6B,EAAQC,GAAmBxoC,MAC3BuX,EAAMsnC,GAAQ7P,EAAQ/gB,EAAG7O,KAAK2vB,GAAa19B,GAEjD,OADAk3B,IACOhxB,CACT,CACA,SAAS03B,GAAiB9f,EAAKmxB,GAC7B,MAAMC,EAAWD,EAAKt/C,MAAM,KAC5B,MAAO,KACL,IAAIgrB,EAAMmD,EACV,IAAK,IAAIpb,EAAI,EAAGA,EAAIwsC,EAAS98C,QAAUuoB,EAAKjY,IAC1CiY,EAAMA,EAAIu0B,EAASxsC,IAErB,OAAOiY,EAEX,CAEA,SAASw0B,GAASviD,EAAOD,EAAMqT,EAAUgC,GACvC,MAAMU,EAAImkB,KAKJuoB,EAAgB,EAASziD,GAKzB0iD,EAAiBhrC,EAAU1X,GAC3BiyB,EAAY0wB,GAAkB1iD,EAAOwiD,GACrClpC,EAAM6R,GAAU,CAAC3J,EAAOjD,KAC5B,IAAIokC,EAEAC,EADAC,EAAeztC,EASnB,OAPA0rC,GAAgB,KACd,MAAMgC,EAAY9iD,EAAMwiD,GACpB3qC,EAAW8qC,EAAYG,KACzBH,EAAaG,EACbvkC,OAGG,CACL9Z,IAAG,KACD+c,IACOpO,EAAQ3O,IAAM2O,EAAQ3O,IAAIk+C,GAAcA,GAEjD,GAAAxgC,CAAI5S,GACF,MAAMwzC,EAAe3vC,EAAQ+O,IAAM/O,EAAQ+O,IAAI5S,GAASA,EACxD,KAAKsI,EAAWkrC,EAAcJ,IAAiBE,IAAiBztC,GAAayC,EAAWtI,EAAOszC,IAC7F,OAEF,MAAM1oB,EAAWrkB,EAAE4X,MAAM1tB,MACnBm6B,IACLp6B,KAAQo6B,GAAYqoB,KAAiBroB,GAAYsoB,KAAkBtoB,KAAc,YAAYp6B,MAAUo6B,GAAY,YAAYqoB,MAAmBroB,GAAY,YAAYsoB,MAAoBtoB,KAC7LwoB,EAAapzC,EACbgP,KAEFzI,EAAEg4B,KAAK,UAAU/tC,IAAQgjD,GACrBlrC,EAAWtI,EAAOwzC,IAAiBlrC,EAAWtI,EAAOszC,KAAkBhrC,EAAWkrC,EAAcH,IAClGrkC,IAEFskC,EAAetzC,EACfqzC,EAAmBG,CACrB,KAeJ,OAZAzpC,EAAIyI,OAAOmB,UAAY,KACrB,IAAI8/B,EAAK,EACT,MAAO,CACL9kC,KAAI,IACE8kC,EAAK,EACA,CAAEzzC,MAAOyzC,IAAOhxB,GAAa5c,EAAYkE,EAAK0L,MAAM,GAEpD,CAAEA,MAAM,KAKhB1L,CACT,CACA,MAAMopC,GAAoB,CAAC1iD,EAAOijD,IACX,eAAdA,GAA4C,gBAAdA,EAA8BjjD,EAAMkjD,eAAiBljD,EAAM,GAAGijD,eAAyBjjD,EAAM,GAAG,EAASijD,gBAA0BjjD,EAAM,GAAGyX,EAAUwrC,eAG7L,SAASnV,GAAKxgB,EAAU3f,KAAUw1C,GAChC,GAAI71B,EAASwZ,YAAa,OAC1B,MAAM9mC,EAAQstB,EAASI,MAAM1tB,OAASoV,EA0BtC,IAAI7E,EAAO4yC,EACX,MAAM1tC,EAAkB9H,EAAM+H,WAAW,WACnCsc,EAAYvc,GAAmBitC,GAAkB1iD,EAAO2N,EAAMkJ,MAAM,IAyB1E,IAAIusC,EAxBApxB,IACEA,EAAUjY,OACZxJ,EAAO4yC,EAAQjuC,IAAKmF,GAAM,EAASA,GAAKA,EAAEN,OAASM,IAEjD2X,EAAUqxB,SACZ9yC,EAAO4yC,EAAQjuC,IAAIuD,KAoBvB,IAAIw4B,EAAUjxC,EAAMojD,EAAcxrC,EAAajK,KAC/C3N,EAAMojD,EAAcxrC,EAAa,EAASjK,MACrCsjC,GAAWx7B,IACdw7B,EAAUjxC,EAAMojD,EAAcxrC,EAAaH,EAAU9J,MAEnDsjC,GACFzjB,GACEyjB,EACA3jB,EACA,EACA/c,GAGJ,MAAM+yC,EAActjD,EAAMojD,EAAc,QACxC,GAAIE,EAAa,CACf,GAAKh2B,EAASi2B,SAEP,GAAIj2B,EAASi2B,QAAQH,GAC1B,YAFA91B,EAASi2B,QAAU,CAAC,EAItBj2B,EAASi2B,QAAQH,IAAe,EAChC51B,GACE81B,EACAh2B,EACA,EACA/c,EAEJ,CACF,CACA,MAAMizC,GAAkC,IAAI3hC,QAC5C,SAAS4hC,GAAsBpd,EAAMxY,EAAY+jB,GAAU,GACzD,MAAMx6B,EAA+Bw6B,EAAU4R,GAAkB31B,EAAW8lB,WACtEtL,EAASjxB,EAAM3S,IAAI4hC,GACzB,QAAe,IAAXgC,EACF,OAAOA,EAET,MAAMzlB,EAAMyjB,EAAK4L,MACjB,IAAI14B,EAAa,CAAC,EACdo9B,GAAa,EACjB,IAA4B,EAAWtQ,GAAO,CAC5C,MAAMqd,EAAe7M,IACnB,MAAM8M,EAAuBF,GAAsB5M,EAAMhpB,GAAY,GACjE81B,IACFhN,GAAa,EACb,EAAOp9B,EAAYoqC,MAGlB/R,GAAW/jB,EAAWsjB,OAAO3rC,QAChCqoB,EAAWsjB,OAAO1mC,QAAQi5C,GAExBrd,EAAK+K,SACPsS,EAAYrd,EAAK+K,SAEf/K,EAAK8K,QACP9K,EAAK8K,OAAO1mC,QAAQi5C,EAExB,CACA,OAAK9gC,GAAQ+zB,GAMT,EAAQ/zB,GACVA,EAAInY,QAAS5D,GAAQ0S,EAAW1S,GAAO,MAEvC,EAAO0S,EAAYqJ,GAEjB,EAASyjB,IACXjvB,EAAM+K,IAAIkkB,EAAM9sB,GAEXA,IAbD,EAAS8sB,IACXjvB,EAAM+K,IAAIkkB,EAAM,MAEX,KAWX,CACA,SAAS2P,GAAe5iC,EAASvM,GAC/B,SAAKuM,IAAYmC,EAAK1O,MAGtBA,EAAMA,EAAIgQ,MAAM,GAAGtF,QAAQ,QAAS,IAC7B0E,EAAO7C,EAASvM,EAAI,GAAG6Q,cAAgB7Q,EAAIgQ,MAAM,KAAOZ,EAAO7C,EAASqE,EAAU5Q,KAASoP,EAAO7C,EAASvM,GACpH,CAMA,SAASy1C,GAAoBhvB,GAC3B,MACEptB,KAAMurC,EAAS,MACf/d,EAAK,MACLhE,EAAK,UACLk6B,EACApV,cAAeA,GAAa,MAC5BxU,EAAK,MACLyT,EAAK,KACLK,EAAI,OACJgG,EAAM,YACNyL,EAAW,MACXv/C,EAAK,KACLa,EAAI,WACJi9B,EAAU,IACV5M,EAAG,aACH2yB,GACEv2B,EACElN,EAAOuQ,GAA4BrD,GACzC,IAAIvI,EACA++B,EAIJ,IACE,GAAsB,EAAlBp2B,EAAMkH,UAAe,CACvB,MAAMmvB,EAAaH,GAAal6B,EAC1Bs6B,EASDD,EACLh/B,EAAS8c,GACPiS,EAAO59B,KACL8tC,EACAD,EACAxE,EACqEv/C,EACrE89B,EACAj9B,EACAqwB,IAGJ4yB,EAAmBrW,CACrB,KAAO,CACL,MAAMwW,EAAUxY,EAIhB1mB,EAAS8c,GACPoiB,EAAQz+C,OAAS,EAAIy+C,EACkDjkD,EAQjE,CAAEytC,QAAOzT,QAAO8T,SAClBmW,EACmEjkD,EACrE,OAGJ8jD,EAAmBrY,EAAUzrC,MAAQytC,EAAQyW,GAAyBzW,EACxE,CACF,CAAE,MAAO5tB,GACPskC,GAAW3+C,OAAS,EACpB+nB,GAAY1N,EAAKyN,EAAU,GAC3BvI,EAASyb,GAAY1G,GACvB,CACA,IAAI8T,EAAO7oB,EAKX,GAAI++B,IAAqC,IAAjBD,EAAwB,CAC9C,MAAMjpC,EAAOlY,OAAOkY,KAAKkpC,IACnB,UAAElvB,GAAcgZ,EAClBhzB,EAAKpV,QACS,EAAZovB,IACE4Z,GAAgB5zB,EAAKyJ,KAAK5O,KAC5BquC,EAAmBM,GACjBN,EACAtV,IAGJZ,EAAOxR,GAAWwR,EAAMkW,GAAkB,GAAO,GA2BvD,CAwBA,OAvBIp2B,EAAMoE,OAMR8b,EAAOxR,GAAWwR,EAAM,MAAM,GAAO,GACrCA,EAAK9b,KAAO8b,EAAK9b,KAAO8b,EAAK9b,KAAK3O,OAAOuK,EAAMoE,MAAQpE,EAAMoE,MAE3DpE,EAAM2O,YAMR3B,GAAmBkT,EAAMlgB,EAAM2O,YAK/BtX,EAAS6oB,EAEXjd,GAA4BvQ,GACrB2E,CACT,CA6CA,MAAMm/B,GAA4BzW,IAChC,IAAIn0B,EACJ,IAAK,MAAMzS,KAAO4mC,GACJ,UAAR5mC,GAA2B,UAARA,GAAmB0O,EAAK1O,OAC5CyS,IAAQA,EAAM,CAAC,IAAIzS,GAAO4mC,EAAM5mC,IAGrC,OAAOyS,GAEH8qC,GAAuB,CAAC3W,EAAOztC,KACnC,MAAMsZ,EAAM,CAAC,EACb,IAAK,MAAMzS,KAAO4mC,EACXh4B,EAAgB5O,IAAUA,EAAIgQ,MAAM,KAAM7W,IAC7CsZ,EAAIzS,GAAO4mC,EAAM5mC,IAGrB,OAAOyS,GAoDT,SAASsiC,GAAgBJ,EAAWE,EAAWzF,GAC7C,MAAMoO,EAAW3hD,OAAOkY,KAAK8gC,GAC7B,GAAI2I,EAAS7+C,SAAW9C,OAAOkY,KAAK4gC,GAAWh2C,OAC7C,OAAO,EAET,IAAK,IAAIsQ,EAAI,EAAGA,EAAIuuC,EAAS7+C,OAAQsQ,IAAK,CACxC,MAAMjP,EAAMw9C,EAASvuC,GACrB,GAAI4lC,EAAU70C,KAAS20C,EAAU30C,KAASmvC,GAAeC,EAAcpvC,GACrE,OAAO,CAEX,CACA,OAAO,CACT,CACA,SAASs7B,IAAgB,MAAEzU,EAAK,OAAElR,GAAU3G,GAC1C,KAAO2G,GAAQ,CACb,MAAMoxB,EAAOpxB,EAAOmd,QAIpB,GAHIiU,EAAK3G,UAAY2G,EAAK3G,SAASqd,eAAiB52B,IAClDkgB,EAAK/3B,GAAK6X,EAAM7X,IAEd+3B,IAASlgB,EAIX,OAHCA,EAAQlR,EAAOkR,OAAO7X,GAAKA,EAC5B2G,EAASA,EAAOA,MAIpB,CACF,CAEA,MAAMysB,GAAc/oC,GAASA,EAAKqkD,aAClC,IAAIC,GAAa,EACjB,MA2CMC,GA3Ce,CACnB1kD,KAAM,WAKNwkD,cAAc,EACd,OAAAhxB,CAAQC,EAAIC,EAAIC,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,EAAWmL,GACtG,GAAU,MAAN3L,GA0CR,SAAuB9F,EAAOgG,EAAWC,EAAQC,EAAiBC,EAAgBC,EAAWC,EAAcC,EAAWmL,GACpH,MACElQ,EAAGqQ,EACH9K,GAAG,cAAEuT,IACH5I,EACEulB,EAAkB3c,EAAc,OAChCd,EAAWvZ,EAAMuZ,SAAW0d,GAChCj3B,EACAmG,EACAD,EACAF,EACAgxB,EACA/wB,EACAG,EACAC,EACAC,EACAmL,GAEFG,EACE,KACA2H,EAASoZ,cAAgB3yB,EAAM4O,UAC/BooB,EACA,KACA9wB,EACAqT,EACAnT,EACAC,GAEEkT,EAASlpB,KAAO,GAClB6mC,GAAal3B,EAAO,aACpBk3B,GAAal3B,EAAO,cACpB4R,EACE,KACA5R,EAAM6O,WACN7I,EACAC,EACAC,EACA,KAEAE,EACAC,GAEF8wB,GAAgB5d,EAAUvZ,EAAM6O,aAEhC0K,EAASnY,SAAQ,GAAO,EAE5B,CAvFMg2B,CACErxB,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAmL,OAEG,CACL,GAAItL,GAAkBA,EAAe9V,KAAO,IAAMyV,EAAGyT,SAAS8d,aAI5D,OAHAtxB,EAAGwT,SAAWzT,EAAGyT,SACjBxT,EAAGwT,SAASvZ,MAAQ+F,OACpBA,EAAG5d,GAAK2d,EAAG3d,KAyEnB,SAAuB2d,EAAIC,EAAIC,EAAWC,EAAQC,EAAiBE,EAAWC,EAAcC,GAAa/E,EAAGqQ,EAAOnJ,GAAIC,EAAS5B,GAAG,cAAEuT,KACnI,MAAMd,EAAWxT,EAAGwT,SAAWzT,EAAGyT,SAClCA,EAASvZ,MAAQ+F,EACjBA,EAAG5d,GAAK2d,EAAG3d,GACX,MAAMmvC,EAAYvxB,EAAG6I,UACf2oB,EAAcxxB,EAAG8I,YACjB,aAAE+nB,EAAY,cAAEjE,EAAa,aAAE0E,EAAY,YAAEG,GAAgBje,EACnE,GAAIoZ,EACFpZ,EAASoZ,cAAgB2E,EACrBpqB,GAAgBylB,EAAe2E,IACjC1lB,EACE+gB,EACA2E,EACA/d,EAASyd,gBACT,KACA9wB,EACAqT,EACAnT,EACAC,EACAC,GAEEiT,EAASlpB,MAAQ,EACnBkpB,EAASnY,UACAi2B,IACJG,IACH5lB,EACEglB,EACAW,EACAvxB,EACAC,EACAC,EACA,KAEAE,EACAC,EACAC,GAEF6wB,GAAgB5d,EAAUge,OAI9Bhe,EAASke,UAAYX,KACjBU,GACFje,EAASie,aAAc,EACvBje,EAASqd,aAAejE,GAExBjqB,EAAQiqB,EAAezsB,EAAiBqT,GAE1CA,EAASlpB,KAAO,EAChBkpB,EAAS5qB,QAAQ7W,OAAS,EAC1ByhC,EAASyd,gBAAkB3c,EAAc,OACrCgd,GACFzlB,EACE,KACA0lB,EACA/d,EAASyd,gBACT,KACA9wB,EACAqT,EACAnT,EACAC,EACAC,GAEEiT,EAASlpB,MAAQ,EACnBkpB,EAASnY,WAETwQ,EACEglB,EACAW,EACAvxB,EACAC,EACAC,EACA,KAEAE,EACAC,EACAC,GAEF6wB,GAAgB5d,EAAUge,KAEnBX,GAAgB1pB,GAAgB0pB,EAAcU,IACvD1lB,EACEglB,EACAU,EACAtxB,EACAC,EACAC,EACAqT,EACAnT,EACAC,EACAC,GAEFiT,EAASnY,SAAQ,KAEjBwQ,EACE,KACA0lB,EACA/d,EAASyd,gBACT,KACA9wB,EACAqT,EACAnT,EACAC,EACAC,GAEEiT,EAASlpB,MAAQ,GACnBkpB,EAASnY,iBAKf,GAAIw1B,GAAgB1pB,GAAgB0pB,EAAcU,GAChD1lB,EACEglB,EACAU,EACAtxB,EACAC,EACAC,EACAqT,EACAnT,EACAC,EACAC,GAEF6wB,GAAgB5d,EAAU+d,QAoB1B,GAlBAJ,GAAanxB,EAAI,aACjBwT,EAASoZ,cAAgB2E,EACC,IAAtBA,EAAUpwB,UACZqS,EAASke,UAAYH,EAAU1xC,UAAUkxC,WAEzCvd,EAASke,UAAYX,KAEvBllB,EACE,KACA0lB,EACA/d,EAASyd,gBACT,KACA9wB,EACAqT,EACAnT,EACAC,EACAC,GAEEiT,EAASlpB,MAAQ,EACnBkpB,EAASnY,cACJ,CACL,MAAM,QAAEwU,EAAO,UAAE6hB,GAAcle,EAC3B3D,EAAU,EACZJ,WAAW,KACL+D,EAASke,YAAcA,GACzBle,EAAShhC,SAASg/C,IAEnB3hB,GACkB,IAAZA,GACT2D,EAAShhC,SAASg/C,EAEtB,CAGN,CArOMG,CACE5xB,EACAC,EACAC,EACAC,EACAC,EACAE,EACAC,EACAC,EACAmL,EAEJ,CACF,EACAzI,QAycF,SAAyBC,EAAMjJ,EAAOkG,EAAiBC,EAAgBC,EAAWC,EAAcC,EAAWmL,EAAmBK,GAC5H,MAAMyH,EAAWvZ,EAAMuZ,SAAW0d,GAChCj3B,EACAmG,EACAD,EACA+C,EAAKE,WAEL9xB,SAASgjC,cAAc,OACvB,KACAjU,EACAC,EACAC,EACAmL,GACA,GAEIpa,EAASya,EACb7I,EACAsQ,EAASoZ,cAAgB3yB,EAAM4O,UAC/B1I,EACAqT,EACAlT,EACAC,GAKF,OAHsB,IAAlBiT,EAASlpB,MACXkpB,EAASnY,SAAQ,GAAO,GAEnB/J,CACT,EAneEsgC,UAoeF,SAAmC33B,GACjC,MAAM,UAAEkH,EAAS,SAAEC,GAAanH,EAC1B43B,EAA6B,GAAZ1wB,EACvBlH,EAAM4O,UAAYipB,GAChBD,EAAiBzwB,EAASz0B,QAAUy0B,GAEtCnH,EAAM6O,WAAa+oB,EAAiBC,GAAsB1wB,EAAS5uB,UAAYu6B,GAAY1G,GAC7F,GAxeA,SAAS8qB,GAAal3B,EAAO3tB,GAC3B,MAAMylD,EAAgB93B,EAAM1tB,OAAS0tB,EAAM1tB,MAAMD,GAC7C,EAAWylD,IACbA,GAEJ,CAiNA,SAASb,GAAuBj3B,EAAOmG,EAAgBD,EAAiBF,EAAWgxB,EAAiB/wB,EAAQG,EAAWC,EAAcC,EAAWmL,EAAmB+lB,GAAc,GAO/K,MACEj2B,EACAsI,EAAGd,EACHN,GAAIC,EACJ1d,EAAGwF,EACHsW,GAAG,WAAEqC,EAAU,OAAElsB,IACfw0B,EACJ,IAAIsmB,EACJ,MAAMC,EAyTR,SAA4Bh4B,GAC1B,MAAMiY,EAAcjY,EAAM1tB,OAAS0tB,EAAM1tB,MAAM2lC,YAC/C,OAAsB,MAAfA,IAAuC,IAAhBA,CAChC,CA5TwBggB,CAAmBj4B,GACrCg4B,GACE7xB,GAAkBA,EAAewsB,gBACnCoF,EAAmB5xB,EAAesxB,UAClCtxB,EAAe9V,QAGnB,MAAMulB,EAAU5V,EAAM1tB,MAAQ6Y,EAAS6U,EAAM1tB,MAAMsjC,cAAW,EAIxDsiB,EAAgBjyB,EAChBsT,EAAW,CACfvZ,QACAlR,OAAQqX,EACRD,kBACAE,YACAJ,YACAgxB,kBACA3mC,KAAM,EACNonC,UAAWX,KACXlhB,QAA4B,iBAAZA,EAAuBA,GAAW,EAClDghB,aAAc,KACdjE,cAAe,KACf0E,cAAeG,EACfA,cACApe,aAAa,EACbzqB,QAAS,GACT,OAAAyS,CAAQhS,GAAS,EAAO+oC,GAAO,GAa7B,MACEn4B,MAAOuJ,EAAM,aACbqtB,EAAY,cACZjE,EAAa,UACb8E,EAAS,QACT9oC,EACAuX,gBAAiBkyB,EACjBpyB,UAAWuB,GACTgS,EACJ,IAAI8e,GAAa,EACb9e,EAASie,YACXje,EAASie,aAAc,EACbpoC,IACVipC,EAAazB,GAAgBjE,EAAchkB,YAAgD,WAAlCgkB,EAAchkB,WAAW1D,KAC9EotB,IACFzB,EAAajoB,WAAWvB,WAAa,KAC/BqqB,IAAcle,EAASke,YACzB1uB,EACE4pB,EACAprB,EACAtB,IAAWiyB,EAAgB1nC,EAAKomC,GAAgB3wB,EAChD,GAEF5D,GAAiB1T,MAInBioC,IACEztB,EAAWytB,EAAazuC,MAAQof,IAClCtB,EAASzV,EAAKomC,IAEhBluB,EAAQkuB,EAAcwB,EAAkB7e,GAAU,IAE/C8e,GACHtvB,EAAK4pB,EAAeprB,EAAYtB,EAAQ,IAG5CkxB,GAAgB5d,EAAUoZ,GAC1BpZ,EAASoZ,cAAgB,KACzBpZ,EAAS8d,cAAe,EACxB,IAAIvoC,EAASyqB,EAASzqB,OAClBwpC,GAAwB,EAC5B,KAAOxpC,GAAQ,CACb,GAAIA,EAAO6jC,cAAe,CACxB7jC,EAAOH,QAAQK,QAAQL,GACvB2pC,GAAwB,EACxB,KACF,CACAxpC,EAASA,EAAOA,MAClB,CACKwpC,GAA0BD,GAC7Bh2B,GAAiB1T,GAEnB4qB,EAAS5qB,QAAU,GACfqpC,GACE7xB,GAAkBA,EAAewsB,eAAiBoF,IAAqB5xB,EAAesxB,YACxFtxB,EAAe9V,OACa,IAAxB8V,EAAe9V,MAAe8nC,GAChChyB,EAAe/E,WAIrB81B,GAAa3tB,EAAQ,YACvB,EACA,QAAAhxB,CAASggD,GACP,IAAKhf,EAASoZ,cACZ,OAEF,MAAQ3yB,MAAOuJ,EAAM,aAAEqtB,EAAc1wB,gBAAiBkyB,EAAkBpyB,UAAWuB,EAAYnB,UAAWoyB,GAAejf,EACzH2d,GAAa3tB,EAAQ,cACrB,MAAM/B,EAAUhX,EAAKomC,GACf6B,EAAgB,KACflf,EAAS8d,eAGdzlB,EACE,KACA2mB,EACAhxB,EACAC,EACA4wB,EACA,KAEAI,EACAnyB,EACAC,GAEF6wB,GAAgB5d,EAAUgf,KAEtBF,EAAaE,EAAc5pB,YAAgD,WAAlC4pB,EAAc5pB,WAAW1D,KACpEotB,IACFzB,EAAajoB,WAAWvB,WAAaqrB,GAEvClf,EAAS8d,cAAe,EACxB3uB,EACEkuB,EACAwB,EACA,MAEA,GAGGC,GACHI,GAEJ,EACA,IAAA1vB,CAAKxB,EAAYC,EAASh1B,GACxB+mC,EAASqd,cAAgB7tB,EAAKwQ,EAASqd,aAAcrvB,EAAYC,EAASh1B,GAC1E+mC,EAASvT,UAAYuB,CACvB,EACA/W,KAAI,IACK+oB,EAASqd,cAAgBpmC,EAAK+oB,EAASqd,cAEhD,WAAAjJ,CAAY/tB,EAAUguB,EAAmB8K,GACvC,MAAMC,IAAwBpf,EAASoZ,cACnCgG,GACFpf,EAASlpB,OAEX,MAAMuoC,EAAah5B,EAASI,MAAM7X,GAClCyX,EAAS8tB,SAAS1kC,MAAOmJ,IACvB0N,GAAY1N,EAAKyN,EAAU,KAC1B5oB,KAAM6hD,IACP,GAAIj5B,EAASwZ,aAAeG,EAASH,aAAeG,EAASke,YAAc73B,EAASk3B,WAClF,OAEFl3B,EAASwuB,eAAgB,EACzB,MAAQpuB,MAAOuJ,GAAW3J,EAI1Bk5B,GAAkBl5B,EAAUi5B,GAAkB,GAC1CD,IACFrvB,EAAOphB,GAAKywC,GAEd,MAAMvxB,GAAeuxB,GAAch5B,EAASqM,QAAQ9jB,GACpDylC,EACEhuB,EACA2J,EAIAJ,EAAWyvB,GAAch5B,EAASqM,QAAQ9jB,IAG1CywC,EAAa,KAAOpoC,EAAKoP,EAASqM,SAClCsN,EACAnT,EACAsyB,GAEErxB,GACFpqB,EAAOoqB,GAEToN,GAAgB7U,EAAU2J,EAAOphB,IAI7BwwC,GAA2C,MAAlBpf,EAASlpB,MACpCkpB,EAASnY,WAGf,EACA,OAAAsH,CAAQqwB,EAAiBnwB,GACvB2Q,EAASH,aAAc,EACnBG,EAASqd,cACXluB,EACE6Q,EAASqd,aACT1wB,EACA6yB,EACAnwB,GAGA2Q,EAASoZ,eACXjqB,EACE6Q,EAASoZ,cACTzsB,EACA6yB,EACAnwB,EAGN,GAEF,OAAO2Q,CACT,CAqCA,SAASse,GAAsBzD,GAC7B,IAAI4E,EACJ,GAAI,EAAW5E,GAAI,CACjB,MAAM6E,EAAaC,IAAsB9E,EAAErwB,GACvCk1B,IACF7E,EAAExwB,IAAK,EACPib,MAEFuV,EAAIA,IACA6E,IACF7E,EAAExwB,IAAK,EACPo1B,EAAQG,GACRC,KAEJ,CACA,GAAI,EAAQhF,GAAI,CACd,MAAMiF,EA5pBV,SAA0BlyB,GACxB,IAAImyB,EACJ,IAAK,IAAIlxC,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACvB,IAAIuzB,GAAQ7S,GAYV,OAXA,GAAIA,EAAMt2B,OAAS45B,IAA8B,SAAnBtD,EAAM3B,SAAqB,CACvD,GAAImyB,EACF,OAEAA,EAAaxwB,CAKjB,CAIJ,CACA,OAAOwwB,CACT,CAwoBwBC,CAAiBnF,GAIrCA,EAAIiF,CACN,CAKA,OAJAjF,EAAIjgB,GAAeigB,GACf4E,IAAU5E,EAAEhtB,kBACdgtB,EAAEhtB,gBAAkB4xB,EAAMjjC,OAAQnM,GAAMA,IAAMwqC,IAEzCA,CACT,CACA,SAASngB,GAAwBxqB,EAAI8vB,GAC/BA,GAAYA,EAASoZ,cACnB,EAAQlpC,GACV8vB,EAAS5qB,QAAQK,QAAQvF,GAEzB8vB,EAAS5qB,QAAQK,KAAKvF,GAGxB4Y,GAAiB5Y,EAErB,CACA,SAAS0tC,GAAgB5d,EAAUigB,GACjCjgB,EAASqd,aAAe4C,EACxB,MAAM,MAAEx5B,EAAK,gBAAEkG,GAAoBqT,EACnC,IAAIpxB,EAAKqxC,EAAOrxC,GAChB,MAAQA,GAAMqxC,EAAO5zC,WAEnBuC,GADAqxC,EAASA,EAAO5zC,UAAUqmB,SACd9jB,GAEd6X,EAAM7X,GAAKA,EACP+d,GAAmBA,EAAgB+F,UAAYjM,IACjDkG,EAAgBlG,MAAM7X,GAAKA,EAC3BssB,GAAgBvO,EAAiB/d,GAErC,CAMA,MAAM8mB,GAAW5a,OAAO7T,IAAI,SACtB4xB,GAAO/d,OAAO7T,IAAI,SAClB4rB,GAAU/X,OAAO7T,IAAI,SACrB+xB,GAASle,OAAO7T,IAAI,SACpBi2C,GAAa,GACnB,IAAI0C,GAAe,KACnB,SAASta,GAAU4a,GAAkB,GACnChD,GAAWznC,KAAKmqC,GAAeM,EAAkB,KAAO,GAC1D,CACA,SAASL,KACP3C,GAAW5mC,MACXspC,GAAe1C,GAAWA,GAAW3+C,OAAS,IAAM,IACtD,CACA,IAsDI4hD,GAtDAR,GAAqB,EACzB,SAASr1B,GAAiBhiB,EAAO83C,GAAU,GACzCT,IAAsBr3C,EAClBA,EAAQ,GAAKs3C,IAAgBQ,IAC/BR,GAAajH,SAAU,EAE3B,CACA,SAAS0H,GAAW55B,GAMlB,OALAA,EAAMoH,gBAAkB8xB,GAAqB,EAAIC,IAAgBxxC,EAAY,KAC7EyxC,KACIF,GAAqB,GAAKC,IAC5BA,GAAanqC,KAAKgR,GAEbA,CACT,CACA,SAAS65B,GAAmBrnD,EAAMF,EAAO60B,EAAU+H,EAAW2d,EAAc3lB,GAC1E,OAAO0yB,GACLE,GACEtnD,EACAF,EACA60B,EACA+H,EACA2d,EACA3lB,GACA,GAGN,CACA,SAAS4X,GAAYtsC,EAAMF,EAAO60B,EAAU+H,EAAW2d,GACrD,OAAO+M,GACL9mB,GACEtgC,EACAF,EACA60B,EACA+H,EACA2d,GACA,GAGN,CACA,SAASlR,GAAQ95B,GACf,QAAOA,IAA8B,IAAtBA,EAAMk4C,WACvB,CACA,SAAS7sB,GAAgBpH,EAAIC,GAS3B,OAAOD,EAAGtzB,OAASuzB,EAAGvzB,MAAQszB,EAAG3sB,MAAQ4sB,EAAG5sB,GAC9C,CAEA,SAAS6gD,GAAmBC,GAC1BP,GAAuBO,CACzB,CACA,MAKMC,GAAe,EAAG/gD,SAAiB,MAAPA,EAAcA,EAAM,KAChDghD,GAAe,EACnB99B,MACA+9B,UACAC,cAEmB,iBAARh+B,IACTA,EAAM,GAAKA,GAEC,MAAPA,EAAc,EAASA,IAAQ,GAAMA,IAAQ,EAAWA,GAAO,CAAEjU,EAAG2a,GAA0B3G,EAAGC,EAAKoU,EAAG2pB,EAASvpB,IAAKwpB,GAAYh+B,EAAM,MAElJ,SAASy9B,GAAgBtnD,EAAMF,EAAQ,KAAM60B,EAAW,KAAM+H,EAAY,EAAG2d,EAAe,KAAM3lB,GAAY10B,IAASy8B,GAAW,EAAI,GAAGqrB,GAAc,EAAOC,GAAgC,GAC5L,MAAMv6B,EAAQ,CACZ+5B,aAAa,EACblmC,UAAU,EACVrhB,OACAF,QACA6G,IAAK7G,GAAS4nD,GAAa5nD,GAC3B+pB,IAAK/pB,GAAS6nD,GAAa7nD,GAC3B8sC,QAASpc,GACTqD,aAAc,KACdc,WACAvhB,UAAW,KACX2zB,SAAU,KACV3K,UAAW,KACXC,WAAY,KACZzK,KAAM,KACNuK,WAAY,KACZxmB,GAAI,KACJ8d,OAAQ,KACRzuB,OAAQ,KACR0wB,YAAa,KACbR,aAAc,KACd+K,YAAa,EACbvL,YACAgI,YACA2d,eACAzlB,gBAAiB,KACjBjH,WAAY,KACZqD,IAAKT,IAwBP,OAtBIw3B,GACFC,GAAkBx6B,EAAOmH,GACT,IAAZD,GACF10B,EAAKmlD,UAAU33B,IAERmH,IACTnH,EAAMkH,WAAa,EAASC,GAAY,EAAI,IAK1C+xB,GAAqB,IACxBoB,GACDnB,KAICn5B,EAAMkP,UAAY,GAAiB,EAAZhI,IAEJ,KAApBlH,EAAMkP,WACJiqB,GAAanqC,KAAKgR,GAEbA,CACT,CACA,MAAM8S,GACN,SAAsBtgC,EAAMF,EAAQ,KAAM60B,EAAW,KAAM+H,EAAY,EAAG2d,EAAe,KAAMyN,GAAc,GAO3G,GANK9nD,GAAQA,IAASmrC,KAIpBnrC,EAAO45B,IAELuP,GAAQnpC,GAAO,CACjB,MAAMioD,EAAS/rB,GACbl8B,EACAF,GACA,GAcF,OAXI60B,GACFqzB,GAAkBC,EAAQtzB,GAExB+xB,GAAqB,IAAMoB,GAAenB,KACrB,EAAnBsB,EAAOvzB,UACTiyB,GAAaA,GAAa1jD,QAAQjD,IAASioD,EAE3CtB,GAAanqC,KAAKyrC,IAGtBA,EAAOvrB,WAAa,EACburB,CACT,CAIA,GAmoBwB54C,EAtoBHrP,EAuoBd,EAAWqP,IAAU,cAAeA,IAtoBzCrP,EAAOA,EAAK8U,WAEVhV,EAAO,CACTA,EAAQooD,GAAmBpoD,GAC3B,IAAMF,MAAOma,EAAK,MAAExX,GAAUzC,EAC1Bia,IAAU,EAASA,KACrBja,EAAMF,MAAQ,EAAema,IAE3B,EAASxX,KACP+iB,GAAQ/iB,KAAW,EAAQA,KAC7BA,EAAQ,EAAO,CAAC,EAAGA,IAErBzC,EAAMyC,MAAQ,EAAeA,GAEjC,CAunBF,IAA0B8M,EA5mBxB,OAAOi4C,GACLtnD,EACAF,EACA60B,EACA+H,EACA2d,EAfgB,EAASr6C,GAAQ,EAAI+oC,GAAW/oC,GAAQ,IAAMuyB,GAAWvyB,GAAQ,GAAK,EAASA,GAAQ,EAAI,EAAWA,GAAQ,EAAI,EAiBlI8nD,GACA,EAEJ,EACA,SAASI,GAAmBpoD,GAC1B,OAAKA,EACEwlB,GAAQxlB,IAAU01C,GAAiB11C,GAAS,EAAO,CAAC,EAAGA,GAASA,EADpD,IAErB,CACA,SAASo8B,GAAW1O,EAAO26B,EAAYC,GAAW,EAAOC,GAAkB,GACzE,MAAM,MAAEvoD,EAAK,IAAE+pB,EAAG,UAAE6S,EAAS,SAAE/H,EAAQ,WAAEwH,GAAe3O,EAClD86B,EAAcH,EAAaI,GAAWzoD,GAAS,CAAC,EAAGqoD,GAAcroD,EACjEmoD,EAAS,CACbV,aAAa,EACblmC,UAAU,EACVrhB,KAAMwtB,EAAMxtB,KACZF,MAAOwoD,EACP3hD,IAAK2hD,GAAeZ,GAAaY,GACjCz+B,IAAKs+B,GAAcA,EAAWt+B,IAI5Bu+B,GAAYv+B,EAAM,EAAQA,GAAOA,EAAI5G,OAAO0kC,GAAaQ,IAAe,CAACt+B,EAAK89B,GAAaQ,IAAeR,GAAaQ,GACrHt+B,EACJ+iB,QAASpf,EAAMof,QACf/Y,aAAcrG,EAAMqG,aACpBc,SAA8HA,EAC9H3vB,OAAQwoB,EAAMxoB,OACd0wB,YAAalI,EAAMkI,YACnBR,aAAc1H,EAAM0H,aACpB+K,YAAazS,EAAMyS,YACnBvL,UAAWlH,EAAMkH,UAKjBgI,UAAWyrB,GAAc36B,EAAMxtB,OAASy8B,IAA0B,IAAfC,EAAmB,GAAiB,GAAZA,EAAiBA,EAC5F2d,aAAc7sB,EAAM6sB,aACpBzlB,gBAAiBpH,EAAMoH,gBACvBjH,WAAYH,EAAMG,WAClBiE,KAAMpE,EAAMoE,KACZuK,aAKA/oB,UAAWoa,EAAMpa,UACjB2zB,SAAUvZ,EAAMuZ,SAChB3K,UAAW5O,EAAM4O,WAAaF,GAAW1O,EAAM4O,WAC/CC,WAAY7O,EAAM6O,YAAcH,GAAW1O,EAAM6O,YACjDxH,YAAarH,EAAMqH,YACnBlf,GAAI6X,EAAM7X,GACV8d,OAAQjG,EAAMiG,OACdzC,IAAKxD,EAAMwD,IACXqE,GAAI7H,EAAM6H,IAQZ,OANI8G,GAAcksB,GAChB7tB,GACEytB,EACA9rB,EAAWJ,MAAMksB,IAGdA,CACT,CAQA,SAASxnB,GAAgB3zB,EAAO,IAAK07C,EAAO,GAC1C,OAAOloB,GAAYV,GAAM,KAAM9yB,EAAM07C,EACvC,CACA,SAASC,GAAkB18C,EAAS28C,GAClC,MAAMl7B,EAAQ8S,GAAYP,GAAQ,KAAMh0B,GAExC,OADAyhB,EAAMyS,YAAcyoB,EACbl7B,CACT,CACA,SAASm7B,GAAmB77C,EAAO,GAAI87C,GAAU,GAC/C,OAAOA,GAAWvc,KAAaC,GAAY1S,GAAS,KAAM9sB,IAASwzB,GAAY1G,GAAS,KAAM9sB,EAChG,CACA,SAAS60B,GAAerL,GACtB,OAAa,MAATA,GAAkC,kBAAVA,EACnBgK,GAAY1G,IACV,EAAQtD,GACVgK,GACL7D,GACA,KAEAnG,EAAM3f,SAECwyB,GAAQ7S,GACVwjB,GAAexjB,GAEfgK,GAAYV,GAAM,KAAMp/B,OAAO81B,GAE1C,CACA,SAASwjB,GAAexjB,GACtB,OAAoB,OAAbA,EAAM3gB,KAAoC,IAArB2gB,EAAMoG,WAAoBpG,EAAMuyB,KAAOvyB,EAAQ4F,GAAW5F,EACxF,CACA,SAAS0xB,GAAkBx6B,EAAOmH,GAChC,IAAI30B,EAAO,EACX,MAAM,UAAE00B,GAAclH,EACtB,GAAgB,MAAZmH,EACFA,EAAW,UACN,GAAI,EAAQA,GACjB30B,EAAO,QACF,GAAwB,iBAAb20B,EAAuB,CACvC,GAAgB,GAAZD,EAAsB,CACxB,MAAMsX,EAAOrX,EAASz0B,QAMtB,YALI8rC,IACFA,EAAKza,KAAOya,EAAK5a,IAAK,GACtB42B,GAAkBx6B,EAAOwe,KACzBA,EAAKza,KAAOya,EAAK5a,IAAK,IAG1B,CAAO,CACLpxB,EAAO,GACP,MAAM8oD,EAAWn0B,EAASgY,EACrBmc,GAAatT,GAAiB7gB,GAEX,IAAbm0B,GAAkBv4B,KACc,IAArCA,GAAyBuJ,MAAM6S,EACjChY,EAASgY,EAAI,GAEbhY,EAASgY,EAAI,EACbnf,EAAMkP,WAAa,OANrB/H,EAAStvB,KAAOkrB,EASpB,CACF,MAAW,EAAWoE,IACpBA,EAAW,CAAEz0B,QAASy0B,EAAUtvB,KAAMkrB,IACtCvwB,EAAO,KAEP20B,EAAWn0B,OAAOm0B,GACF,GAAZD,GACF10B,EAAO,GACP20B,EAAW,CAAC8L,GAAgB9L,KAE5B30B,EAAO,GAGXwtB,EAAMmH,SAAWA,EACjBnH,EAAMkH,WAAa10B,CACrB,CACA,SAASuoD,MAAcl4C,GACrB,MAAMsJ,EAAM,CAAC,EACb,IAAK,IAAI/D,EAAI,EAAGA,EAAIvF,EAAK/K,OAAQsQ,IAAK,CACpC,MAAMmzC,EAAU14C,EAAKuF,GACrB,IAAK,MAAMjP,KAAOoiD,EAChB,GAAY,UAARpiD,EACEgT,EAAI/Z,QAAUmpD,EAAQnpD,QACxB+Z,EAAI/Z,MAAQ,EAAe,CAAC+Z,EAAI/Z,MAAOmpD,EAAQnpD,cAE5C,GAAY,UAAR+G,EACTgT,EAAIpX,MAAQ,EAAe,CAACoX,EAAIpX,MAAOwmD,EAAQxmD,aAC1C,GAAI8S,EAAK1O,GAAM,CACpB,MAAM23B,EAAW3kB,EAAIhT,GACfqiD,EAAWD,EAAQpiD,IACrBqiD,GAAY1qB,IAAa0qB,GAAc,EAAQ1qB,IAAaA,EAAS3a,SAASqlC,KAChFrvC,EAAIhT,GAAO23B,EAAW,GAAGrb,OAAOqb,EAAU0qB,GAAYA,EAE1D,KAAmB,KAARriD,IACTgT,EAAIhT,GAAOoiD,EAAQpiD,GAGzB,CACA,OAAOgT,CACT,CACA,SAAS4nB,GAAgBlP,EAAMjF,EAAUI,EAAO0E,EAAY,MAC1D5E,GAA2B+E,EAAMjF,EAAU,EAAG,CAC5CI,EACA0E,GAEJ,CAEA,MAAM+2B,GAAkB/V,KACxB,IAAIljB,GAAM,EACV,SAASgrB,GAAwBxtB,EAAOlR,EAAQyqB,GAC9C,MAAM/mC,EAAOwtB,EAAMxtB,KACb2tB,GAAcrR,EAASA,EAAOqR,WAAaH,EAAMG,aAAes7B,GAChE77B,EAAW,CACf4C,IAAKA,KACLxC,QACAxtB,OACAsc,SACAqR,aACA+f,KAAM,KAEN1vB,KAAM,KACNyb,QAAS,KAET1Y,OAAQ,KACR8Z,OAAQ,KAER5L,IAAK,KACL4tB,MAAO,IAAI/gC,IACT,GAGF83B,OAAQ,KACRpqB,MAAO,KACP2lB,QAAS,KACT+Z,YAAa,KACbxF,UAAW,KACXnQ,SAAUj3B,EAASA,EAAOi3B,SAAW/wC,OAAOyS,OAAO0Y,EAAW4lB,UAC9DxW,IAAKzgB,EAASA,EAAOygB,IAAM,CAAC,GAAI,EAAG,GACnCqR,YAAa,KACbiR,YAAa,GAEbvM,WAAY,KACZrhB,WAAY,KAEZ6c,aAAckI,GAAsBx2C,EAAM2tB,GAC1CooB,aAAcwN,GAAsBvjD,EAAM2tB,GAE1CigB,KAAM,KAENyV,QAAS,KAEThN,cAAenhC,EAEfyuC,aAAc3jD,EAAK2jD,aAEnB3yB,IAAK9b,EACLvU,KAAMuU,EACNpV,MAAOoV,EACPq4B,MAAOr4B,EACP4kB,MAAO5kB,EACPgoB,KAAMhoB,EACN0oB,WAAY1oB,EACZ26B,aAAc,KAEd9I,WACAud,WAAYvd,EAAWA,EAASke,UAAY,EAC5C/J,SAAU,KACVU,eAAe,EAGf5jB,WAAW,EACX4O,aAAa,EACb0B,eAAe,EACf6gB,GAAI,KACJ/xC,EAAG,KACHklC,GAAI,KACJjlB,EAAG,KACHmP,GAAI,KACJuV,EAAG,KACH9lB,GAAI,KACJ0Q,IAAK,KACL+B,GAAI,KACJvuB,EAAG,KACHivC,IAAK,KACLC,IAAK,KACLp7B,GAAI,KACJq7B,GAAI,MAYN,OAPEl8B,EAAS4D,IAAM,CAAE2b,EAAGvf,GAEtBA,EAASsgB,KAAOpxB,EAASA,EAAOoxB,KAAOtgB,EACvCA,EAASwgB,KAAOA,GAAK3sB,KAAK,KAAMmM,GAC5BI,EAAM6H,IACR7H,EAAM6H,GAAGjI,GAEJA,CACT,CACA,IAAIyZ,GAAkB,KACtB,MAAM9M,GAAqB,IAAM8M,IAAmBtW,GACpD,IAAIg5B,GACAC,GACJ,CACE,MAAMtwC,EAAIH,IACJ0wC,EAAuB,CAAC9iD,EAAKolB,KACjC,IAAI29B,EAGJ,OAFMA,EAAUxwC,EAAEvS,MAAO+iD,EAAUxwC,EAAEvS,GAAO,IAC5C+iD,EAAQltC,KAAKuP,GACLtQ,IACFiuC,EAAQpkD,OAAS,EAAGokD,EAAQn/C,QAAS0X,GAAQA,EAAIxG,IAChDiuC,EAAQ,GAAGjuC,KAGpB8tC,GAA6BE,EAC3B,2BACChuC,GAAMorB,GAAkBprB,GAE3B+tC,GAAqBC,EACnB,sBACChuC,GAAMurB,GAAwBvrB,EAEnC,CACA,MAAM4uB,GAAsBjd,IAC1B,MAAMlN,EAAO2mB,GAGb,OAFA0iB,GAA2Bn8B,GAC3BA,EAASyvB,MAAM9/B,KACR,KACLqQ,EAASyvB,MAAM5/B,MACfssC,GAA2BrpC,KAGzBuwB,GAAuB,KAC3B5J,IAAmBA,GAAgBgW,MAAM5/B,MACzCssC,GAA2B,OAU7B,SAAStc,GAAoB7f,GAC3B,OAAkC,EAA3BA,EAASI,MAAMkH,SACxB,CACA,IAgHIi1B,GACAC,GAjHA5iB,IAAwB,EAC5B,SAASiU,GAAe7tB,EAAU5M,GAAQ,EAAOsT,GAAY,GAC3DtT,GAASgpC,GAAmBhpC,GAC5B,MAAM,MAAE1gB,EAAK,SAAE60B,GAAavH,EAASI,MAC/Bq8B,EAAa5c,GAAoB7f,IAjwHzC,SAAmBA,EAAU6M,EAAU4vB,EAAYrpC,GAAQ,GACzD,MAAM1gB,EAAQ,CAAC,EACTytC,EAAQgI,KACdnoB,EAASipB,cAAgC7zC,OAAOyS,OAAO,MACvDwgC,GAAaroB,EAAU6M,EAAUn6B,EAAOytC,GACxC,IAAK,MAAM5mC,KAAOymB,EAASkhB,aAAa,GAChC3nC,KAAO7G,IACXA,EAAM6G,QAAO,GAMbkjD,EACFz8B,EAASttB,MAAQ0gB,EAAQ1gB,EAAQgpB,GAAgBhpB,GAE5CstB,EAASptB,KAAKF,MAGjBstB,EAASttB,MAAQA,EAFjBstB,EAASttB,MAAQytC,EAKrBngB,EAASmgB,MAAQA,CACnB,CA2uHEuc,CAAU18B,EAAUttB,EAAO+pD,EAAYrpC,GACvCm3B,GAAUvqB,EAAUuH,EAAUb,GAAatT,GAC3C,MAAMupC,EAAcF,EAItB,SAAgCz8B,EAAU5M,GAExC,MAAM+qB,EAAYne,EAASptB,KAuB3BotB,EAASghB,YAA8B5rC,OAAOyS,OAAO,MACrDmY,EAAS5D,MAAQ,IAAIC,MAAM2D,EAAS4D,IAAKmd,IAIzC,MAAM,MAAEr7B,GAAUy4B,EAClB,GAAIz4B,EAAO,CACT,KACA,MAAM+8B,EAAeziB,EAASyiB,aAAe/8B,EAAMxN,OAAS,EAAIwqC,GAAmB1iB,GAAY,KACzFgd,EAAQC,GAAmBjd,GAC3B28B,EAAc58B,GAClBra,EACAsa,EACA,EACA,CACgFA,EAASttB,MACvF+vC,IAGEma,EAAezzC,EAAUwzC,GAM/B,GALA,KACA3f,KACK4f,IAAgB58B,EAASk8B,IAAQ9rB,GAAepQ,IACnD4P,GAAkB5P,GAEhB48B,EAAc,CAEhB,GADAD,EAAYvlD,KAAKisC,GAAsBA,IACnCjwB,EACF,OAAOupC,EAAYvlD,KAAMylD,IACvB3D,GAAkBl5B,EAAU68B,EAAgBzpC,KAC3ChK,MAAOvS,IACRopB,GAAYppB,EAAGmpB,EAAU,KAG3BA,EAAS8tB,SAAW6O,CAQxB,MACEzD,GAAkBl5B,EAAU28B,EAAavpC,EAE7C,MACE0pC,GAAqB98B,EAAU5M,EAEnC,CA7EmC2pC,CAAuB/8B,EAAU5M,QAAS,EAE3E,OADAA,GAASgpC,IAAmB,GACrBO,CACT,CA2EA,SAASzD,GAAkBl5B,EAAU28B,EAAavpC,GAC5C,EAAWupC,GACT38B,EAASptB,KAAKoqD,kBAChBh9B,EAASi9B,UAAYN,EAErB38B,EAASwmB,OAASmW,EAEX,EAASA,KASlB38B,EAASwQ,WAAalT,GAAUq/B,IASlCG,GAAqB98B,EAAU5M,EACjC,CAGA,SAAS8pC,GAAwBC,GAC/BZ,GAAUY,EACVX,GAAoBh0C,IACdA,EAAEg+B,OAAO4W,MACX50C,EAAE8tC,UAAY,IAAIj6B,MAAM7T,EAAEob,IAAK8d,KAGrC,CACA,MAAM,GAAgB,KAAO6a,GAC7B,SAASO,GAAqB98B,EAAU5M,EAAOiqC,GAC7C,MAAMlf,EAAYne,EAASptB,KAC3B,IAAKotB,EAASwmB,OAAQ,CACpB,IAAKpzB,GAASmpC,KAAYpe,EAAUqI,OAAQ,CAC1C,MAAM8W,EAAWnf,EAAUmf,UAAmC7c,GAAqBzgB,GAAUs9B,SAC7F,GAAIA,EAAU,CAIZ,MAAM,gBAAEtpB,EAAe,gBAAEkS,GAAoBlmB,EAASO,WAAWC,QAC3D,WAAE+8B,EAAYrX,gBAAiBsX,GAA6Brf,EAC5Dsf,EAAuB,EAC3B,EACE,CACEzpB,kBACAupB,cAEFrX,GAEFsX,GAEFrf,EAAUqI,OAAS+V,GAAQe,EAAUG,EAIvC,CACF,CACAz9B,EAASwmB,OAASrI,EAAUqI,QAAU,EAClCgW,IACFA,GAAiBx8B,EAErB,CACiC,CAC/B,MAAMgd,EAAQC,GAAmBjd,GACjC,KACA,KAriJJ,SAAsBA,GACpB,MAAMla,EAAU26B,GAAqBzgB,GAC/BwjB,EAAaxjB,EAAS5D,MACtBwH,EAAM5D,EAAS4D,IACrBud,IAAoB,EAChBr7B,EAAQ++B,cACV7W,GAASloB,EAAQ++B,aAAc7kB,EAAU,MAE3C,MAEEzsB,KAAMmqD,EACNnpD,SAAUopD,EAAe,QACzBjpD,EACA8B,MAAOonD,EACP73C,QAAS83C,EACTjY,OAAQkY,EAAa,QAErB/Y,EAAO,YACPC,EAAW,QACXxtC,EAAO,aACPytC,EAAY,QACZtgB,EAAO,UACP2gB,EAAS,YACTC,EAAW,cACXL,EAAa,cACbC,EAAa,UACbC,EAAS,UACTC,EAAS,OACTmB,EAAM,cACNuX,EAAa,gBACbC,EAAe,cACfxY,EAAa,eACbC,EAAc,OAEdwY,EAAM,aACN1H,EAAY,WAEZ7Q,EAAU,WACVrhB,EAAU,QACV65B,GACEp4C,EAaJ,GAHIg4C,GAiJN,SAA2BA,EAAel6B,GACpC,EAAQk6B,KACVA,EAAgBjY,GAAgBiY,IAElC,IAAK,MAAMvkD,KAAOukD,EAAe,CAC/B,MAAMjb,EAAMib,EAAcvkD,GAC1B,IAAIqjC,EAGAA,EAFA,EAASiG,GACP,YAAaA,EACJ+C,GACT/C,EAAIthC,MAAQhI,EACZspC,EAAI/vC,SACJ,GAGS8yC,GAAO/C,EAAIthC,MAAQhI,GAGrBqsC,GAAO/C,GAEhB,GAAMjG,GACRxnC,OAAO4V,eAAe4Y,EAAKrqB,EAAK,CAC9B2R,YAAY,EACZD,cAAc,EACd9T,IAAK,IAAMylC,EAAS36B,MACpB4S,IAAMxG,GAAMuuB,EAAS36B,MAAQoM,IAG/BuV,EAAIrqB,GAAOqjC,CAKf,CACF,CAlLIuhB,CAAkBL,EAAel6B,GAE/BlvB,EACF,IAAK,MAAM6E,KAAO7E,EAAS,CACzB,MAAM0pD,EAAgB1pD,EAAQ6E,GAC1B,EAAW6kD,KASXx6B,EAAIrqB,GAAO6kD,EAAcvqC,KAAK2vB,GAUpC,CAEF,GAAIka,EAAa,CAMf,MAAMnqD,EAAOmqD,EAAY90C,KAAK46B,EAAYA,GAMrC,EAASjwC,KAGZysB,EAASzsB,KAAO6lB,GAAS7lB,GAe7B,CAEA,GADA4tC,IAAoB,EAChBwc,EACF,IAAK,MAAMpkD,KAAOokD,EAAiB,CACjC,MAAM9a,EAAM8a,EAAgBpkD,GACtBpC,EAAM,EAAW0rC,GAAOA,EAAIhvB,KAAK2vB,EAAYA,GAAc,EAAWX,EAAI1rC,KAAO0rC,EAAI1rC,IAAI0c,KAAK2vB,EAAYA,GAAc,EAIxH3uB,GAAO,EAAWguB,IAAQ,EAAWA,EAAIhuB,KAAOguB,EAAIhuB,IAAIhB,KAAK2vB,GAI/D,EACEx5B,EAAI,GAAS,CACjB7S,MACA0d,QAEFzf,OAAO4V,eAAe4Y,EAAKrqB,EAAK,CAC9B2R,YAAY,EACZD,cAAc,EACd9T,IAAK,IAAM6S,EAAE/H,MACb4S,IAAMxG,GAAMrE,EAAE/H,MAAQoM,GAK1B,CAEF,GAAIuvC,EACF,IAAK,MAAMrkD,KAAOqkD,EAChBra,GAAcqa,EAAarkD,GAAMqqB,EAAK4f,EAAYjqC,GAGtD,GAAIskD,EAAgB,CAClB,MAAM1X,EAAW,EAAW0X,GAAkBA,EAAej1C,KAAK46B,GAAcqa,EAChF3kC,QAAQS,QAAQwsB,GAAUhpC,QAAS5D,IACjCwM,GAAQxM,EAAK4sC,EAAS5sC,KAE1B,CAIA,SAAS8kD,EAAsBC,EAAUr5B,GACnC,EAAQA,GACVA,EAAK9nB,QAASohD,GAAUD,EAASC,EAAM1qC,KAAK2vB,KACnCve,GACTq5B,EAASr5B,EAAKpR,KAAK2vB,GAEvB,CAaA,GAtBIuB,GACF/W,GAAS+W,EAAS/kB,EAAU,KAS9Bq+B,EAAsBjhB,GAAe4H,GACrCqZ,EAAsBrzB,GAAWxzB,GACjC6mD,EAAsBhhB,GAAgB4H,GACtCoZ,EAAsBxiB,GAAWlX,GACjC05B,EAAsBjiB,GAAakJ,GACnC+Y,EAAsB/hB,GAAeiJ,GACrC8Y,EAAsB5gB,GAAiB+H,GACvC6Y,EAAsB7gB,GAAiBugB,GACvCM,EAAsB9gB,GAAmBygB,GACzCK,EAAsBpzB,GAAiBka,GACvCkZ,EAAsBxhB,GAAawI,GACnCgZ,EAAsB/gB,GAAkBmI,GACpC,EAAQwY,GACV,GAAIA,EAAO/lD,OAAQ,CACjB,MAAM6pC,EAAU/hB,EAAS+hB,UAAY/hB,EAAS+hB,QAAU,CAAC,GACzDkc,EAAO9gD,QAAS5D,IACdnE,OAAO4V,eAAe+2B,EAASxoC,EAAK,CAClCpC,IAAK,IAAMqsC,EAAWjqC,GACtBsb,IAAMhT,GAAQ2hC,EAAWjqC,GAAOsI,EAChCqJ,YAAY,KAGlB,MAAY8U,EAAS+hB,UACnB/hB,EAAS+hB,QAAU,CAAC,GAGpByE,GAAUxmB,EAASwmB,SAAW,IAChCxmB,EAASwmB,OAASA,GAEA,MAAhB+P,IACFv2B,EAASu2B,aAAeA,GAEtB7Q,IAAY1lB,EAAS0lB,WAAaA,GAClCrhB,IAAYrE,EAASqE,WAAaA,GAClCohB,GACF7V,GAAkB5P,EAEtB,CAo2IMw+B,CAAax+B,EACf,CAAE,QACA,KACAgd,GACF,CACF,CAUF,CACA,MAAMyhB,GAcF,CACFtnD,IAAG,CAACS,EAAQ2B,KACV,GAAM3B,EAAQ,EAAO,IACdA,EAAO2B,KAWlB,SAASmpC,GAAmB1iB,GAwCxB,MAAO,CACLmgB,MAAO,IAAI9jB,MAAM2D,EAASmgB,MAAOse,IACjC/xB,MAAO1M,EAAS0M,MAChB8T,KAAMxgB,EAASwgB,KACfyd,OA3CYlc,IAqBd/hB,EAAS+hB,QAAUA,GAAW,CAAC,GAyBnC,CACA,SAASzd,GAA2BtE,GAClC,OAAIA,EAAS+hB,QACJ/hB,EAAS87B,cAAgB97B,EAAS87B,YAAc,IAAIz/B,MAAMiB,GAAUf,GAAQyD,EAAS+hB,UAAW,CACrG5qC,IAAG,CAACS,EAAQ2B,IACNA,KAAO3B,EACFA,EAAO2B,GACLA,KAAOumC,GACTA,GAAoBvmC,GAAKymB,QAD3B,EAITjP,IAAG,CAACnZ,EAAQ2B,IACHA,KAAO3B,GAAU2B,KAAOumC,MAI5B9f,EAAS5D,KAEpB,CAGA,SAASye,GAAiBsD,EAAWugB,GAAkB,GACrD,OAAO,EAAWvgB,GAAaA,EAAUwgB,aAAexgB,EAAU1rC,KAAO0rC,EAAU1rC,MAAQisD,GAAmBvgB,EAAUygB,MAC1H,CA2BA,MAAM,GAAW,CAACC,EAAiBC,KACjC,MAAM90C,EDt7MR,SAAkB60C,EAAiBC,EAAc1rC,GAAQ,GACvD,IAAIqwB,EACA9kB,EAYJ,OAXI,EAAWkgC,GACbpb,EAASob,GAETpb,EAASob,EAAgB1nD,IACzBwnB,EAASkgC,EAAgBhqC,KAEd,IAAI6J,GAAgB+kB,EAAQ9kB,EAAQvL,EAMnD,CCu6MY7e,CAAWsqD,EAAiBC,EAAcllB,IAOpD,OAAO5vB,GAGT,SAASs5B,GAAE1wC,EAAMmsD,EAAiBx3B,GAChC,IACEtD,IAAkB,GAClB,MAAM1U,EAAI2G,UAAUhe,OACpB,OAAU,IAANqX,EACE,EAASwvC,KAAqB,EAAQA,GACpChjB,GAAQgjB,GACH7rB,GAAYtgC,EAAM,KAAM,CAACmsD,IAE3B7rB,GAAYtgC,EAAMmsD,GAElB7rB,GAAYtgC,EAAM,KAAMmsD,IAG7BxvC,EAAI,EACNgY,EAAWtxB,MAAMwS,UAAUc,MAAMX,KAAKsN,UAAW,GAClC,IAAN3G,GAAWwsB,GAAQxU,KAC5BA,EAAW,CAACA,IAEP2L,GAAYtgC,EAAMmsD,EAAiBx3B,GAE9C,CAAE,QACAtD,GAAiB,EACnB,CACF,CAEA,SAAS,KAkLT,CAEA,SAAS+6B,GAASvD,EAAMjV,EAAQ18B,EAAOzQ,GACrC,MAAM0hC,EAASjxB,EAAMzQ,GACrB,GAAI0hC,GAAUkkB,GAAWlkB,EAAQ0gB,GAC/B,OAAO1gB,EAET,MAAMxuB,EAAMi6B,IAGZ,OAFAj6B,EAAIkvC,KAAOA,EAAKlyC,QAChBgD,EAAIylC,WAAa34C,EACVyQ,EAAMzQ,GAASkT,CACxB,CACA,SAAS0yC,GAAWlkB,EAAQ0gB,GAC1B,MAAM3oC,EAAOioB,EAAO0gB,KACpB,GAAI3oC,EAAK5a,QAAUujD,EAAKvjD,OACtB,OAAO,EAET,IAAK,IAAIsQ,EAAI,EAAGA,EAAIsK,EAAK5a,OAAQsQ,IAC/B,GAAI+B,EAAWuI,EAAKtK,GAAIizC,EAAKjzC,IAC3B,OAAO,EAMX,OAHI8wC,GAAqB,GAAKC,IAC5BA,GAAanqC,KAAK2rB,IAEb,CACT,CAEA,MAAMvoB,GAAU,SACV,GAA4D,EAC5D0sC,GA3oQqB,CACzB,GAAQ,sBACR,GAAQ,oBACR,EAAO,eACP,GAAQ,mBACR,EAAO,eACP,GAAQ,oBACR,EAAO,UACP,IAAS,qBACT,GAAQ,iBACR,EAAO,iBACP,GAAQ,mBACR,GAAQ,qBACR,IAAS,qBACT,IAAS,uBACT,EAAK,iBACL,EAAK,kBACL,EAAK,iBACL,EAAK,mBACL,EAAK,2BACL,EAAK,uBACL,EAAK,0BACL,EAAK,aACL,EAAK,iBACL,EAAK,kBACL,GAAM,mBACN,GAAM,kBACN,GAAM,eACN,GAAM,yBACN,GAAM,kBACN,GAAM,mBACN,GAAM,gCA6mQFC,GAA+Dn8B,GAC/Do8B,GAxuPN,SAASC,EAAkBp6B,EAAMrtB,GAC/B,IAAI0W,EAAIgxC,EACRt8B,GAAaiC,EACTjC,IACFA,GAAWu8B,SAAU,EACrBt8B,GAAO9lB,QAAQ,EAAGkD,QAAO4C,UAAW+f,GAAWwd,KAAKngC,KAAU4C,IAC9DggB,GAAS,IAKS,oBAAX/pB,QACPA,OAAOsmD,eAE6D,OAAjEF,EAAgC,OAA1BhxC,EAAKpV,OAAOumD,gBAAqB,EAASnxC,EAAGoxC,gBAAqB,EAASJ,EAAG/oC,SAAS,YAEjF3e,EAAO+nD,6BAA+B/nD,EAAO+nD,8BAAgC,IACrFvwC,KAAMwwC,IACXP,EAAkBO,EAAShoD,KAE7Bg+B,WAAW,KACJ5S,KACHprB,EAAO+nD,6BAA+B,KACtCz8B,IAAuB,EACvBD,GAAS,KAEV,OAEHC,IAAuB,EACvBD,GAAS,GAEb,EAstPM48B,GAZY,CAChBjS,2BACAC,kBACAmB,uBACA3rB,+BACA0Y,QAASA,GACTxH,kBACAjQ,8BACA8a,oBACA0gB,mBA/yQF,SAA4B1/B,GAC1BR,GAAMxQ,KAAKgR,EACb,EA8yQE2/B,kBA7yQF,WACEngC,GAAM3P,KACR,GA8yQM+vC,GAAgB,KAChBC,GAAc,KACdC,GAAmB,KCvzQzB,IAAIC,GACJ,MAAMC,GAAuB,oBAAXlnD,QAA0BA,OAAOmnD,aACnD,GAAID,GACF,IACED,GAAyBC,GAAGE,aAAa,MAAO,CAC9CC,WAAa1+C,GAAQA,GAEzB,CAAE,MAAOhL,GAET,CAEF,MAAM2pD,GAAsBL,GAAUt+C,GAAQs+C,GAAOI,WAAW1+C,GAAQA,GAAQA,EAG1EgD,GAA0B,oBAAbpN,SAA2BA,SAAW,KACnDgpD,GAAoB57C,IAAuBA,GAAI41B,cAAc,YAC7DimB,GAAU,CACdv5B,OAAQ,CAAC+B,EAAOha,EAAQmX,KACtBnX,EAAOyxC,aAAaz3B,EAAO7C,GAAU,OAEvChpB,OAAS6rB,IACP,MAAMha,EAASga,EAAMK,WACjBra,GACFA,EAAO0xC,YAAY13B,IAGvBuR,cAAe,CAAComB,EAAKr6B,EAAW/b,EAAI/X,KAClC,MAAM6V,EAAmB,QAAdie,EAAsB3hB,GAAIi8C,gBAf3B,6BAekDD,GAAqB,WAAdr6B,EAAyB3hB,GAAIi8C,gBAdnF,qCAc6GD,GAAOp2C,EAAK5F,GAAI41B,cAAcomB,EAAK,CAAEp2C,OAAQ5F,GAAI41B,cAAcomB,GAIzL,MAHY,WAARA,GAAoBnuD,GAA2B,MAAlBA,EAAMquD,UACrCx4C,EAAGgiB,aAAa,WAAY73B,EAAMquD,UAE7Bx4C,GAET6e,WAAa1nB,GAASmF,GAAIm8C,eAAethD,GACzC2nB,cAAgB3nB,GAASmF,GAAIwiB,cAAc3nB,GAC3C4rC,QAAS,CAACjiB,EAAM3pB,KACd2pB,EAAK43B,UAAYvhD,GAEnB8rC,eAAgB,CAACjjC,EAAI7I,KACnB6I,EAAGsrB,YAAcn0B,GAEnB6pB,WAAaF,GAASA,EAAKE,WAC3BD,YAAcD,GAASA,EAAKC,YAC5B5kB,cAAgBw8C,GAAar8C,GAAIH,cAAcw8C,GAC/C,UAAAtV,CAAWrjC,EAAIvP,GACbuP,EAAGgiB,aAAavxB,EAAI,GACtB,EAKA,mBAAA8yC,CAAoBntC,EAASuQ,EAAQmX,EAAQG,EAAWvE,EAAOC,GAC7D,MAAMi/B,EAAS96B,EAASA,EAAO8M,gBAAkBjkB,EAAOkkB,UACxD,GAAInR,IAAUA,IAAUC,GAAOD,EAAMqH,aACnC,KACEpa,EAAOyxC,aAAa1+B,EAAMm/B,WAAU,GAAO/6B,GACvCpE,IAAUC,IAASD,EAAQA,EAAMqH,mBAElC,CACLm3B,GAAkBt9C,UAAYq9C,GACd,QAAdh6B,EAAsB,QAAQ7nB,UAAgC,WAAd6nB,EAAyB,SAAS7nB,WAAmBA,GAEvG,MAAM2+C,EAAWmD,GAAkB9hD,QACnC,GAAkB,QAAd6nB,GAAqC,WAAdA,EAAwB,CACjD,MAAM66B,EAAU/D,EAASxzB,WACzB,KAAOu3B,EAAQv3B,YACbwzB,EAASgE,YAAYD,EAAQv3B,YAE/BwzB,EAASsD,YAAYS,EACvB,CACAnyC,EAAOyxC,aAAarD,EAAUj3B,EAChC,CACA,MAAO,CAEL86B,EAASA,EAAO73B,YAAcpa,EAAO4a,WAErCzD,EAASA,EAAO8M,gBAAkBjkB,EAAOkkB,UAE7C,GAGImuB,GAAa,aACbC,GAAY,YACZC,GAAShtC,OAAO,QAChBitC,GAA+B,CACnCjvD,KAAMW,OACNR,KAAMQ,OACNuuD,IAAK,CACH/uD,KAAMC,QACNC,SAAS,GAEX8uD,SAAU,CAACxuD,OAAQoY,OAAQpW,QAC3BysD,eAAgBzuD,OAChB0uD,iBAAkB1uD,OAClB2uD,aAAc3uD,OACd4uD,gBAAiB5uD,OACjB6uD,kBAAmB7uD,OACnB8uD,cAAe9uD,OACf+uD,eAAgB/uD,OAChBgvD,iBAAkBhvD,OAClBivD,aAAcjvD,QAEVkvD,GAA4C,EAChD,CAAC,EACDl3B,GACAs2B,IAOIa,GALa,CAACC,IAClBA,EAAE7D,YAAc,aAChB6D,EAAE9vD,MAAQ4vD,GACHE,GAE0BC,CACjC,CAAC/vD,GAASg6B,WAAY4W,GAAE7W,GAAgBi2B,GAAuBhwD,GAAQg6B,IAEnE,GAAW,CAACzH,EAAMhiB,EAAO,MACzB,EAAQgiB,GACVA,EAAK9nB,QAASwlD,GAAOA,KAAM1/C,IAClBgiB,GACTA,KAAQhiB,IAGN2/C,GAAuB39B,KACpBA,IAAO,EAAQA,GAAQA,EAAKlO,KAAM4rC,GAAOA,EAAGzqD,OAAS,GAAK+sB,EAAK/sB,OAAS,GAEjF,SAASwqD,GAAuB71B,GAC9B,MAAMg2B,EAAY,CAAC,EACnB,IAAK,MAAMtpD,KAAOszB,EACVtzB,KAAOmoD,KACXmB,EAAUtpD,GAAOszB,EAAStzB,IAG9B,IAAqB,IAAjBszB,EAAS80B,IACX,OAAOkB,EAET,MAAM,KACJpwD,EAAO,IAAG,KACVG,EAAI,SACJgvD,EAAQ,eACRC,EAAiB,GAAGpvD,eAAiB,iBACrCqvD,EAAmB,GAAGrvD,iBAAmB,aACzCsvD,EAAe,GAAGtvD,aAAe,gBACjCuvD,EAAkBH,EAAc,kBAChCI,EAAoBH,EAAgB,cACpCI,EAAgBH,EAAY,eAC5BI,EAAiB,GAAG1vD,eAAiB,iBACrC2vD,EAAmB,GAAG3vD,iBAAmB,aACzC4vD,EAAe,GAAG5vD,cAChBo6B,EACEi2B,EA0FR,SAA2BlB,GACzB,GAAgB,MAAZA,EACF,OAAO,KACF,GAAI,EAASA,GAClB,MAAO,CAACmB,GAASnB,EAASvzB,OAAQ00B,GAASnB,EAASlzB,QAC/C,CACL,MAAMtjB,EAAI23C,GAASnB,GACnB,MAAO,CAACx2C,EAAGA,EACb,CACF,CAnGoB43C,CAAkBpB,GAC9BqB,EAAgBH,GAAaA,EAAU,GACvCI,EAAgBJ,GAAaA,EAAU,IACvC,cACJt3B,EAAa,QACbC,EAAO,iBACPE,EAAgB,QAChBE,EAAO,iBACPE,EAAgB,eAChBC,EAAiBR,EAAa,SAC9BS,EAAWR,EAAO,kBAClBU,EAAoBR,GAClBk3B,EACEM,EAAc,CAAC56C,EAAI66C,EAAU1rC,EAAM2rC,KACvC96C,EAAG+6C,gBAAkBD,EACrBE,GAAsBh7C,EAAI66C,EAAWlB,EAAgBH,GACrDwB,GAAsBh7C,EAAI66C,EAAWnB,EAAoBH,GACzDpqC,GAAQA,KAEJ8rC,EAAc,CAACj7C,EAAImP,KACvBnP,EAAGupC,YAAa,EAChByR,GAAsBh7C,EAAI45C,GAC1BoB,GAAsBh7C,EAAI85C,GAC1BkB,GAAsBh7C,EAAI65C,GAC1B1qC,GAAQA,KAEJ+rC,EAAiBL,GACd,CAAC76C,EAAImP,KACV,MAAMuN,EAAOm+B,EAAWn3B,EAAWR,EAC7BjK,EAAU,IAAM2hC,EAAY56C,EAAI66C,EAAU1rC,GAChD,GAASuN,EAAM,CAAC1c,EAAIiZ,IACpBkiC,GAAU,KACRH,GAAsBh7C,EAAI66C,EAAWpB,EAAkBH,GACvD8B,GAAmBp7C,EAAI66C,EAAWlB,EAAgBH,GAC7Ca,GAAoB39B,IACvB2+B,GAAmBr7C,EAAI3V,EAAMqwD,EAAezhC,MAKpD,OAAO,EAAOqhC,EAAW,CACvB,aAAAr3B,CAAcjjB,GACZ,GAASijB,EAAe,CAACjjB,IACzBo7C,GAAmBp7C,EAAIs5C,GACvB8B,GAAmBp7C,EAAIu5C,EACzB,EACA,cAAA91B,CAAezjB,GACb,GAASyjB,EAAgB,CAACzjB,IAC1Bo7C,GAAmBp7C,EAAIy5C,GACvB2B,GAAmBp7C,EAAI05C,EACzB,EACAx2B,QAASg4B,GAAc,GACvBx3B,SAAUw3B,GAAc,GACxB,OAAA53B,CAAQtjB,EAAImP,GACVnP,EAAGupC,YAAa,EAChB,MAAMtwB,EAAU,IAAMgiC,EAAYj7C,EAAImP,GACtCisC,GAAmBp7C,EAAI45C,GAClB55C,EAAG+6C,iBAINK,GAAmBp7C,EAAI65C,GACvByB,GAAYt7C,KAJZs7C,GAAYt7C,GACZo7C,GAAmBp7C,EAAI65C,IAKzBsB,GAAU,KACHn7C,EAAGupC,aAGRyR,GAAsBh7C,EAAI45C,GAC1BwB,GAAmBp7C,EAAI85C,GAClBO,GAAoB/2B,IACvB+3B,GAAmBr7C,EAAI3V,EAAMswD,EAAe1hC,MAGhD,GAASqK,EAAS,CAACtjB,EAAIiZ,GACzB,EACA,gBAAAmK,CAAiBpjB,GACf46C,EAAY56C,GAAI,OAAO,GAAQ,GAC/B,GAASojB,EAAkB,CAACpjB,GAC9B,EACA,iBAAA4jB,CAAkB5jB,GAChB46C,EAAY56C,GAAI,OAAM,GAAQ,GAC9B,GAAS4jB,EAAmB,CAAC5jB,GAC/B,EACA,gBAAAwjB,CAAiBxjB,GACfi7C,EAAYj7C,GACZ,GAASwjB,EAAkB,CAACxjB,GAC9B,GAEJ,CAWA,SAASw6C,GAASlhD,GAKhB,OAJY0J,EAAS1J,EAKvB,CACA,SAAS8hD,GAAmBp7C,EAAImrB,GAC9BA,EAAIj+B,MAAM,OAAO0H,QAAS6M,GAAMA,GAAKzB,EAAGnL,UAAUE,IAAI0M,KACrDzB,EAAGk5C,MAAYl5C,EAAGk5C,IAA0B,IAAIppC,MAAQ/a,IAAIo2B,EAC/D,CACA,SAAS6vB,GAAsBh7C,EAAImrB,GACjCA,EAAIj+B,MAAM,OAAO0H,QAAS6M,GAAMA,GAAKzB,EAAGnL,UAAUC,OAAO2M,IACzD,MAAM85C,EAAOv7C,EAAGk5C,IACZqC,IACFA,EAAK9yC,OAAO0iB,GACPowB,EAAK91C,OACRzF,EAAGk5C,SAAU,GAGnB,CACA,SAASiC,GAAUhhC,GACjBqhC,sBAAsB,KACpBA,sBAAsBrhC,IAE1B,CACA,IAAIshC,GAAQ,EACZ,SAASJ,GAAmBr7C,EAAI07C,EAAcC,EAAiB1iC,GAC7D,MAAMxoB,EAAKuP,EAAG47C,SAAWH,GACnBI,EAAoB,KACpBprD,IAAOuP,EAAG47C,QACZ3iC,KAGJ,GAAuB,MAAnB0iC,EACF,OAAOtuB,WAAWwuB,EAAmBF,GAEvC,MAAM,KAAEtxD,EAAI,QAAEojC,EAAO,UAAEquB,GAAcC,GAAkB/7C,EAAI07C,GAC3D,IAAKrxD,EACH,OAAO4uB,IAET,MAAM+iC,EAAW3xD,EAAO,MACxB,IAAI4xD,EAAQ,EACZ,MAAMtiC,EAAM,KACV3Z,EAAGgvB,oBAAoBgtB,EAAUE,GACjCL,KAEIK,EAAS5tD,IACTA,EAAEe,SAAW2Q,KAAQi8C,GAASH,GAChCniC,KAGJ0T,WAAW,KACL4uB,EAAQH,GACVniC,KAED8T,EAAU,GACbztB,EAAG5Q,iBAAiB4sD,EAAUE,EAChC,CACA,SAASH,GAAkB/7C,EAAI07C,GAC7B,MAAMS,EAASxrD,OAAOyrD,iBAAiBp8C,GACjCq8C,EAAsBrrD,IAASmrD,EAAOnrD,IAAQ,IAAI9D,MAAM,MACxDovD,EAAmBD,EAAmB,GAAGrD,WACzCuD,EAAsBF,EAAmB,GAAGrD,cAC5CwD,EAAoBC,GAAWH,EAAkBC,GACjDG,EAAkBL,EAAmB,GAAGpD,WACxC0D,EAAqBN,EAAmB,GAAGpD,cAC3C2D,EAAmBH,GAAWC,EAAiBC,GACrD,IAAItyD,EAAO,KACPojC,EAAU,EACVquB,EAAY,EAqBhB,OApBIJ,IAAiB1C,GACfwD,EAAoB,IACtBnyD,EAAO2uD,GACPvrB,EAAU+uB,EACVV,EAAYS,EAAoB5sD,QAEzB+rD,IAAiBzC,GACtB2D,EAAmB,IACrBvyD,EAAO4uD,GACPxrB,EAAUmvB,EACVd,EAAYa,EAAmBhtD,SAGjC89B,EAAUsa,KAAKlW,IAAI2qB,EAAmBI,GACtCvyD,EAAOojC,EAAU,EAAI+uB,EAAoBI,EAAmB5D,GAAaC,GAAY,KACrF6C,EAAYzxD,EAAOA,IAAS2uD,GAAauD,EAAoB5sD,OAASgtD,EAAmBhtD,OAAS,GAK7F,CACLtF,OACAojC,UACAquB,YACAe,aAPmBxyD,IAAS2uD,IAAc,6BAA6BplB,KACvEyoB,EAAmB,GAAGrD,cAAsBj4C,YAQhD,CACA,SAAS07C,GAAWK,EAAQvC,GAC1B,KAAOuC,EAAOntD,OAAS4qD,EAAU5qD,QAC/BmtD,EAASA,EAAOxvC,OAAOwvC,GAEzB,OAAO/U,KAAKlW,OAAO0oB,EAAUl7C,IAAI,CAAC5N,EAAGwO,IAAM88C,GAAKtrD,GAAKsrD,GAAKD,EAAO78C,KACnE,CACA,SAAS88C,GAAK9Q,GACZ,MAAU,SAANA,EAAqB,EACyB,IAA3ChpC,OAAOgpC,EAAEjrC,MAAM,GAAI,GAAGtF,QAAQ,IAAK,KAC5C,CACA,SAAS4/C,GAAYt7C,GAEnB,OADuBA,EAAKA,EAAGg9C,cAAgB9tD,UACzBC,KAAK8tD,YAC7B,CAgBA,MAAMC,GAAuBhxC,OAAO,QAC9BixC,GAAcjxC,OAAO,QACrBkxC,GAAQ,CAEZlzD,KAAM,OACN,WAAAuyC,CAAYz8B,GAAI,MAAEtG,IAAS,WAAE8sB,IAC3BxmB,EAAGk9C,IAA6C,SAArBl9C,EAAGpT,MAAMuB,QAAqB,GAAK6R,EAAGpT,MAAMuB,QACnEq4B,GAAc9sB,EAChB8sB,EAAWZ,YAAY5lB,GAEvBq9C,GAAWr9C,EAAItG,EAEnB,EACA,OAAAzK,CAAQ+Q,GAAI,MAAEtG,IAAS,WAAE8sB,IACnBA,GAAc9sB,GAChB8sB,EAAWV,MAAM9lB,EAErB,EACA,OAAAoc,CAAQpc,GAAI,MAAEtG,EAAK,SAAEuI,IAAY,WAAEukB,KAC5B9sB,IAAWuI,IACZukB,EACE9sB,GACF8sB,EAAWZ,YAAY5lB,GACvBq9C,GAAWr9C,GAAI,GACfwmB,EAAWV,MAAM9lB,IAEjBwmB,EAAWL,MAAMnmB,EAAI,KACnBq9C,GAAWr9C,GAAI,KAInBq9C,GAAWr9C,EAAItG,GAEnB,EACA,aAAAkjC,CAAc58B,GAAI,MAAEtG,IAClB2jD,GAAWr9C,EAAItG,EACjB,GAEF,SAAS2jD,GAAWr9C,EAAItG,GACtBsG,EAAGpT,MAAMuB,QAAUuL,EAAQsG,EAAGk9C,IAAwB,OACtDl9C,EAAGm9C,KAAgBzjD,CACrB,CASA,MAAM4jD,GAAepxC,OAAoE,IACzF,SAASqxC,GAAWriB,GAClB,MAAMzjB,EAAW2M,KACjB,IAAK3M,EAEH,OAEF,MAAM+lC,EAAkB/lC,EAASsK,GAAK,CAAC07B,EAAOviB,EAAOzjB,EAAS5D,UAC5DnmB,MAAMsL,KACJ9J,SAASyF,iBAAiB,kBAAkB8iB,EAAS4C,UACrDzlB,QAASksB,GAAS48B,GAAc58B,EAAM28B,KAKpCE,EAAU,KACd,MAAMF,EAAOviB,EAAOzjB,EAAS5D,OACzB4D,EAASiI,GACXg+B,GAAcjmC,EAASiI,GAAI+9B,GAE3BG,GAAenmC,EAASqM,QAAS25B,GAEnCD,EAAgBC,IAElB3oB,GAAe,KACb5a,GAAiByjC,KAEnBl7B,GAAU,KACR,GAAMk7B,EAAS,EAAM,CAAE1qB,MAAO,SAC9B,MAAMrF,EAAK,IAAIiwB,iBAAiBF,GAChC/vB,EAAGa,QAAQhX,EAASqM,QAAQ9jB,GAAGghB,WAAY,CAAE88B,WAAW,IACxDxpB,GAAY,IAAM1G,EAAGG,eAEzB,CACA,SAAS6vB,GAAe/lC,EAAO4lC,GAC7B,GAAsB,IAAlB5lC,EAAMkH,UAAiB,CACzB,MAAMqS,EAAWvZ,EAAMuZ,SACvBvZ,EAAQuZ,EAASqd,aACbrd,EAASoZ,gBAAkBpZ,EAASie,aACtCje,EAAS5qB,QAAQK,KAAK,KACpB+2C,GAAexsB,EAASqd,aAAcgP,IAG5C,CACA,KAAO5lC,EAAMpa,WACXoa,EAAQA,EAAMpa,UAAUqmB,QAE1B,GAAsB,EAAlBjM,EAAMkH,WAAiBlH,EAAM7X,GAC/B09C,GAAc7lC,EAAM7X,GAAIy9C,QACnB,GAAI5lC,EAAMxtB,OAASy8B,GACxBjP,EAAMmH,SAASpqB,QAAS6M,GAAMm8C,GAAen8C,EAAGg8C,SAC3C,GAAI5lC,EAAMxtB,OAAS+/B,GAAQ,CAChC,IAAI,GAAEpqB,EAAE,OAAE8d,GAAWjG,EACrB,KAAO7X,IACL09C,GAAc19C,EAAIy9C,GACdz9C,IAAO8d,IACX9d,EAAKA,EAAG+gB,WAEZ,CACF,CACA,SAAS28B,GAAc19C,EAAIy9C,GACzB,GAAoB,IAAhBz9C,EAAGwhB,SAAgB,CACrB,MAAM50B,EAAQoT,EAAGpT,MACjB,IAAImX,EAAU,GACd,IAAK,MAAM/S,KAAOysD,EAAM,CACtB,MAAM/jD,EAAQ,GAAqB+jD,EAAKzsD,IACxCpE,EAAMmxD,YAAY,KAAK/sD,IAAO0I,GAC9BqK,GAAW,KAAK/S,MAAQ0I,IAC1B,CACA9M,EAAM0wD,IAAgBv5C,CACxB,CACF,CAEA,MAAMi6C,GAAY,wBAkDZC,GAAc,iBACpB,SAASC,GAAStxD,EAAO1C,EAAMoP,GAC7B,GAAI,EAAQA,GACVA,EAAI1E,QAASkR,GAAMo4C,GAAStxD,EAAO1C,EAAM4b,SAUzC,GARW,MAAPxM,IAAaA,EAAM,IAQnBpP,EAAK2V,WAAW,MAClBjT,EAAMmxD,YAAY7zD,EAAMoP,OACnB,CACL,MAAM6kD,EAeZ,SAAoBvxD,EAAOwxD,GACzB,MAAM5rB,EAAS6rB,GAAYD,GAC3B,GAAI5rB,EACF,OAAOA,EAET,IAAItoC,EAAO,EAASk0D,GACpB,GAAa,WAATl0D,GAAqBA,KAAQ0C,EAC/B,OAAOyxD,GAAYD,GAAWl0D,EAEhCA,EAAO,EAAWA,GAClB,IAAK,IAAI+V,EAAI,EAAGA,EAAIq+C,GAAS3uD,OAAQsQ,IAAK,CACxC,MAAMk+C,EAAWG,GAASr+C,GAAK/V,EAC/B,GAAIi0D,KAAYvxD,EACd,OAAOyxD,GAAYD,GAAWD,CAElC,CACA,OAAOC,CACT,CAhCuBG,CAAW3xD,EAAO1C,GAC/B+zD,GAAYrqB,KAAKt6B,GACnB1M,EAAMmxD,YACJn8C,EAAUu8C,GACV7kD,EAAIoC,QAAQuiD,GAAa,IACzB,aAGFrxD,EAAMuxD,GAAY7kD,CAEtB,CAEJ,CACA,MAAMglD,GAAW,CAAC,SAAU,MAAO,MAC7BD,GAAc,CAAC,EAoBfG,GAAU,+BAChB,SAASC,GAAUz+C,EAAIhP,EAAK0I,EAAOglD,EAAOjnC,EAAUknC,EAAYr6C,GAAqBtT,IAC/E0tD,GAAS1tD,EAAI6O,WAAW,UACb,MAATnG,EACFsG,EAAG4+C,kBAAkBJ,GAASxtD,EAAIgQ,MAAM,EAAGhQ,EAAIrB,SAE/CqQ,EAAG6+C,eAAeL,GAASxtD,EAAK0I,GAGrB,MAATA,GAAiBilD,IAAc,GAAmBjlD,GACpDsG,EAAG8+C,gBAAgB9tD,GAEnBgP,EAAGgiB,aACDhxB,EACA2tD,EAAY,GAAKh+C,EAASjH,GAAS7O,OAAO6O,GAASA,EAI3D,CAEA,SAASqlD,GAAa/+C,EAAIhP,EAAK0I,EAAOqkB,EAAiBihC,GACrD,GAAY,cAARhuD,GAA+B,gBAARA,EAIzB,YAHa,MAAT0I,IACFsG,EAAGhP,GAAe,cAARA,EAAsBinD,GAAoBv+C,GAASA,IAIjE,MAAM4+C,EAAMt4C,EAAGipB,QACf,GAAY,UAARj4B,GAA2B,aAARsnD,IACtBA,EAAItqC,SAAS,KAAM,CAClB,MAAM/L,EAAmB,WAARq2C,EAAmBt4C,EAAGorB,aAAa,UAAY,GAAKprB,EAAGtG,MAClElE,EAAoB,MAATkE,EAGH,aAAZsG,EAAG3V,KAAsB,KAAO,GAC9BQ,OAAO6O,GAQX,OAPIuI,IAAazM,GAAc,WAAYwK,IACzCA,EAAGtG,MAAQlE,GAEA,MAATkE,GACFsG,EAAG8+C,gBAAgB9tD,QAErBgP,EAAG+K,OAASrR,EAEd,CACA,IAAIulD,GAAa,EACjB,GAAc,KAAVvlD,GAAyB,MAATA,EAAe,CACjC,MAAMrP,SAAc2V,EAAGhP,GACV,YAAT3G,EACFqP,EAAQ,GAAmBA,GACT,MAATA,GAA0B,WAATrP,GAC1BqP,EAAQ,GACRulD,GAAa,GACK,WAAT50D,IACTqP,EAAQ,EACRulD,GAAa,EAEjB,CACA,IACEj/C,EAAGhP,GAAO0I,CACZ,CAAE,MAAOpL,GAOT,CACA2wD,GAAcj/C,EAAG8+C,gBAAgBE,GAAYhuD,EAC/C,CAEA,SAAS5B,GAAiB4Q,EAAIlI,EAAOsjC,EAAS79B,GAC5CyC,EAAG5Q,iBAAiB0I,EAAOsjC,EAAS79B,EACtC,CAIA,MAAM2hD,GAAShzC,OAAO,QAoBtB,MAAMizC,GAAoB,4BAc1B,IAAIC,GAAY,EAChB,MAAMhmC,GAAoBJ,QAAQC,UAC5BomC,GAAS,IAAMD,KAAchmC,GAAEvqB,KAAK,IAAMuwD,GAAY,GAAIA,GAAYE,KAAKC,OA4C3EC,GAAcxuD,GAA8B,MAAtBA,EAAI2O,WAAW,IAAoC,MAAtB3O,EAAI2O,WAAW,IACxE3O,EAAI2O,WAAW,GAAK,IAAM3O,EAAI2O,WAAW,GAAK,IAgExC8/C,GAAU,CAAC,EAEjB,SAASC,GAAoBniD,EAAS0pB,EAAc04B,GAClD,IAAIC,EAAO54B,GAAgBzpB,EAAS0pB,GAChChmB,EAAc2+C,KAAOA,EAAO,EAAO,CAAC,EAAGA,EAAM34B,IACjD,MAAM44B,UAAyBC,GAC7B,WAAA15C,CAAY25C,GACVhvC,MAAM6uC,EAAMG,EAAcJ,EAC5B,EAGF,OADAE,EAAiBv9C,IAAMs9C,EAChBC,CACT,CACA,MAAMG,GAAyB,CAA6BziD,EAAS0pB,IAC5Cy4B,GAAoBniD,EAAS0pB,EAAcg5B,IAE9DC,GAAmC,oBAAhBjJ,YAA8BA,YAAc,QAErE,MAAM6I,WAAmBI,GACvB,WAAA95C,CAAY0gC,EAAMrI,EAAS,CAAC,EAAGkhB,EAAa1iD,IAC1C8T,QACA7kB,KAAK46C,KAAOA,EACZ56C,KAAKuyC,OAASA,EACdvyC,KAAKyzD,WAAaA,EAClBzzD,KAAKi0D,UAAW,EAIhBj0D,KAAK0yC,UAAY,KAIjB1yC,KAAKk0D,KAAO,KAIZl0D,KAAKm0D,OAASn0D,KAAK46C,KAAKwZ,MACxBp0D,KAAKq0D,YAAa,EAClBr0D,KAAKs0D,WAAY,EACjBt0D,KAAKu0D,aAAe,KACpBv0D,KAAKw0D,eAAiC,IAAI14C,QAC1C9b,KAAKy0D,IAAM,KACPz0D,KAAK66C,YAAc4Y,IAAe1iD,GACpC/Q,KAAK00D,MAAQ10D,KAAK66C,YAOM,IAApBD,EAAKC,YACP76C,KAAK20D,aACH,EAAO,CAAC,EAAG/Z,EAAKga,kBAAmB,CACjCh+B,KAAM,UAGV52B,KAAK00D,MAAQ10D,KAAK66C,YAElB76C,KAAK00D,MAAQ10D,IAGnB,CACA,iBAAA60D,GACE,IAAK70D,KAAK80D,YAAa,OAClB90D,KAAK66C,YAAe76C,KAAKs0D,WAC5Bt0D,KAAK+0D,cAEP/0D,KAAKq0D,YAAa,EAClB,IAAI55C,EAASza,KACb,KAAOya,EAASA,IAAWA,EAAOqa,YAAcra,EAAOu6C,OACrD,GAAIv6C,aAAkBm5C,GAAY,CAChC5zD,KAAKi1D,QAAUx6C,EACf,KACF,CAEGza,KAAK0yC,YACJ1yC,KAAKs0D,UACPt0D,KAAKk1D,OAAOl1D,KAAK46C,MAEbngC,GAAUA,EAAO06C,gBACnBn1D,KAAKm1D,gBAAkB16C,EAAO06C,gBAAgBxyD,KAAK,KACjD3C,KAAKm1D,qBAAkB,EACvBn1D,KAAKo1D,gBAGPp1D,KAAKo1D,cAIb,CACA,UAAAC,CAAW56C,EAASza,KAAKi1D,SACnBx6C,IACFza,KAAK0yC,UAAUj4B,OAASA,EAAOi4B,UAC/B1yC,KAAKs1D,sBAAsB76C,GAE/B,CACA,qBAAA66C,CAAsB76C,EAASza,KAAKi1D,SAC9Bx6C,GAAUza,KAAKk0D,MACjBvzD,OAAO40D,eACLv1D,KAAKk0D,KAAKzhB,SAASf,SACnBj3B,EAAOi4B,UAAUhB,SAGvB,CACA,oBAAA8jB,GACEx1D,KAAKq0D,YAAa,EAClBpnC,GAAS,KACFjtB,KAAKq0D,aACJr0D,KAAKy0D,MACPz0D,KAAKy0D,IAAI5yB,aACT7hC,KAAKy0D,IAAM,MAEbz0D,KAAKk0D,MAAQl0D,KAAKk0D,KAAK7/B,UACnBr0B,KAAK0yC,YAAW1yC,KAAK0yC,UAAUlf,QAAK,GACxCxzB,KAAKk0D,KAAOl0D,KAAK0yC,UAAY,KACzB1yC,KAAKyzB,mBACPzzB,KAAKyzB,iBAAiBrN,QACtBpmB,KAAKyzB,sBAAmB,KAIhC,CACA,iBAAAgiC,CAAkBC,GAChB,IAAK,MAAMlgC,KAAKkgC,EACd11D,KAAK21D,SAASngC,EAAEogC,cAEpB,CAIA,WAAAR,GACE,GAAIp1D,KAAKm1D,gBACP,OAEF,IAAK,IAAIphD,EAAI,EAAGA,EAAI/T,KAAK61D,WAAWpyD,OAAQsQ,IAC1C/T,KAAK21D,SAAS31D,KAAK61D,WAAW9hD,GAAG/V,MAEnCgC,KAAKy0D,IAAM,IAAI9C,iBAAiB3xD,KAAKy1D,kBAAkBr2C,KAAKpf,OAC5DA,KAAKy0D,IAAIlyB,QAAQviC,KAAM,CAAE61D,YAAY,IACrC,MAAM9oC,EAAU,CAAC3W,EAAK0/C,GAAU,KAC9B91D,KAAKs0D,WAAY,EACjBt0D,KAAKm1D,qBAAkB,EACvB,MAAM,MAAEl3D,EAAK,OAAEgyD,GAAW75C,EAC1B,IAAI2/C,EACJ,GAAI93D,IAAU,EAAQA,GACpB,IAAK,MAAM6G,KAAO7G,EAAO,CACvB,MAAMmwC,EAAMnwC,EAAM6G,IACdspC,IAAQr3B,QAAUq3B,GAAOA,EAAIjwC,OAAS4Y,UACpCjS,KAAO9E,KAAKuyC,SACdvyC,KAAKuyC,OAAOztC,GAAOgS,EAAS9W,KAAKuyC,OAAOztC,MAEzCixD,IAAgBA,EAA8Bp1D,OAAOyS,OAAO,QAAQ,EAAWtO,KAAQ,EAE5F,CAEF9E,KAAKu0D,aAAewB,EACpB/1D,KAAKg2D,cAAc5/C,GACfpW,KAAK66C,YACP76C,KAAKi2D,aAAahG,GAMpBjwD,KAAKk1D,OAAO9+C,IAER8/C,EAAWl2D,KAAK46C,KAAKvX,cACvB6yB,EACFl2D,KAAKm1D,gBAAkBe,IAAWvzD,KAAMyT,IACtCA,EAAI+/C,aAAen2D,KAAK46C,KAAKub,aAC7BppC,EAAQ/sB,KAAK46C,KAAOxkC,GAAK,KAG3B2W,EAAQ/sB,KAAK46C,KAEjB,CACA,MAAAsa,CAAO9+C,GAILpW,KAAKk0D,KAAOl0D,KAAKyzD,WAAWr9C,GAC5BpW,KAAKs1D,wBACDl/C,EAAI+/C,cACN//C,EAAI+/C,aAAan2D,KAAKk0D,MAExBl0D,KAAKk0D,KAAKlhB,SAAWhzC,KAAKX,eAC1BW,KAAKk0D,KAAKrhD,MAAM7S,KAAK00D,OACrB,MAAMpnB,EAAUttC,KAAK0yC,WAAa1yC,KAAK0yC,UAAUpF,QACjD,GAAKA,EACL,IAAK,MAAMxoC,KAAOwoC,EACXp5B,EAAOlU,KAAM8E,IAChBnE,OAAO4V,eAAevW,KAAM8E,EAAK,CAE/BpC,IAAK,IAAM+lB,GAAM6kB,EAAQxoC,KAMjC,CACA,aAAAkxD,CAAc5/C,GACZ,MAAM,MAAEnY,GAAUmY,EACZggD,EAAmB,EAAQn4D,GAASA,EAAQ0C,OAAOkY,KAAK5a,GAAS,CAAC,GACxE,IAAK,MAAM6G,KAAOnE,OAAOkY,KAAK7Y,MACb,MAAX8E,EAAI,IAAcsxD,EAAiBt0C,SAAShd,IAC9C9E,KAAKy0C,SAAS3vC,EAAK9E,KAAK8E,IAG5B,IAAK,MAAMA,KAAOsxD,EAAiBjjD,IAAI,GACrCxS,OAAO4V,eAAevW,KAAM8E,EAAK,CAC/B,GAAApC,GACE,OAAO1C,KAAKq2D,SAASvxD,EACvB,EACA,GAAAsb,CAAIhT,GACFpN,KAAKy0C,SAAS3vC,EAAKsI,GAAK,GAAM,EAChC,GAGN,CACA,QAAAuoD,CAAS7wD,GACP,GAAIA,EAAI6O,WAAW,WAAY,OAC/B,MAAM2I,EAAMtc,KAAKghC,aAAal8B,GAC9B,IAAI0I,EAAQ8O,EAAMtc,KAAKk/B,aAAap6B,GAAOyuD,GAC3C,MAAMvf,EAAW,EAAWlvC,GACxBwX,GAAOtc,KAAKu0D,cAAgBv0D,KAAKu0D,aAAavgB,KAChDxmC,EAAQsJ,EAAStJ,IAEnBxN,KAAKy0C,SAAST,EAAUxmC,GAAO,GAAO,EACxC,CAIA,QAAA6oD,CAASvxD,GACP,OAAO9E,KAAKuyC,OAAOztC,EACrB,CAIA,QAAA2vC,CAAS3vC,EAAKsI,EAAKkpD,GAAgB,EAAMC,GAAe,GACtD,GAAInpD,IAAQpN,KAAKuyC,OAAOztC,KAClBsI,IAAQmmD,UACHvzD,KAAKuyC,OAAOztC,IAEnB9E,KAAKuyC,OAAOztC,GAAOsI,EACP,QAARtI,GAAiB9E,KAAKk0D,OACxBl0D,KAAKk0D,KAAKlhB,SAASluC,IAAMsI,IAGzBmpD,GAAgBv2D,KAAK0yC,WACvB1yC,KAAKw2D,UAEHF,GAAe,CACjB,MAAM50B,EAAK1hC,KAAKy0D,IACZ/yB,IACF1hC,KAAKy1D,kBAAkB/zB,EAAG+0B,eAC1B/0B,EAAGG,eAEO,IAARz0B,EACFpN,KAAK81B,aAAapgB,EAAU5Q,GAAM,IACV,iBAARsI,GAAmC,iBAARA,EAC3CpN,KAAK81B,aAAapgB,EAAU5Q,GAAMsI,EAAM,IAC9BA,GACVpN,KAAK4yD,gBAAgBl9C,EAAU5Q,IAEjC48B,GAAMA,EAAGa,QAAQviC,KAAM,CAAE61D,YAAY,GACvC,CAEJ,CACA,OAAAW,GACE,MAAM7qC,EAAQ3rB,KAAKX,eACfW,KAAKk0D,OAAMvoC,EAAMG,WAAa9rB,KAAKk0D,KAAKzhB,UAC5CV,GAAOpmB,EAAO3rB,KAAK00D,MACrB,CACA,YAAAr1D,GACE,MAAM+uD,EAAY,CAAC,EACdpuD,KAAK66C,aACRuT,EAAUzuB,eAAiByuB,EAAU3V,eAAiBz4C,KAAK02D,aAAat3C,KAAKpf,OAE/E,MAAM2rB,EAAQ8S,GAAYz+B,KAAK46C,KAAM,EAAOwT,EAAWpuD,KAAKuyC,SAkC5D,OAjCKvyC,KAAK0yC,YACR/mB,EAAM6H,GAAMjI,IACVvrB,KAAK0yC,UAAYnnB,EACjBA,EAASiI,GAAKxzB,KACdurB,EAASgI,MAAO,EAYhB,MAAMojC,EAAW,CAAC/qD,EAAO4C,KACvBxO,KAAKojC,cACH,IAAIwzB,YACFhrD,EACAmJ,EAAcvG,EAAK,IAAM,EAAO,CAAEqoD,OAAQroD,GAAQA,EAAK,IAAM,CAAEqoD,OAAQroD,MAI7E+c,EAASwgB,KAAO,CAACngC,KAAU4C,KACzBmoD,EAAS/qD,EAAO4C,GACZkH,EAAU9J,KAAWA,GACvB+qD,EAASjhD,EAAU9J,GAAQ4C,IAG/BxO,KAAKq1D,eAGF1pC,CACT,CACA,YAAAsqC,CAAahG,EAAQrlC,GACnB,IAAKqlC,EAAQ,OACb,GAAIrlC,EAAO,CACT,GAAIA,IAAU5qB,KAAK46C,MAAQ56C,KAAKw0D,eAAel4C,IAAIsO,GACjD,OAEF5qB,KAAKw0D,eAAe3rD,IAAI+hB,EAC1B,CACA,MAAMwpC,EAAQp0D,KAAKm0D,OACnB,IAAK,IAAIpgD,EAAIk8C,EAAOxsD,OAAS,EAAGsQ,GAAK,EAAGA,IAAK,CAC3C,MAAMgsC,EAAI/8C,SAASgjC,cAAc,SAC7BouB,GAAOrU,EAAEjqB,aAAa,QAASs+B,GACnCrU,EAAE3gB,YAAc6wB,EAAOl8C,GACvB/T,KAAK66C,WAAWxS,QAAQ0X,EAe1B,CACF,CAIA,WAAAgV,GACE,MAAM98B,EAAQj4B,KAAK82D,OAAS,CAAC,EAC7B,IAAIngD,EACJ,KAAOA,EAAI3W,KAAKq1B,YAAY,CAC1B,MAAM0hC,EAA0B,IAAfpgD,EAAE2e,UAAkB3e,EAAEuoB,aAAa,SAAW,WAC9DjH,EAAM8+B,KAAc9+B,EAAM8+B,GAAY,KAAKp8C,KAAKhE,GACjD3W,KAAKmsD,YAAYx1C,EACnB,CACF,CAIA,YAAA+/C,GACE,MAAMM,EAAUh3D,KAAKi3D,YACflsB,EAAU/qC,KAAK0yC,UAAUv0C,KAAK0wB,UACpC,IAAK,IAAI9a,EAAI,EAAGA,EAAIijD,EAAQvzD,OAAQsQ,IAAK,CACvC,MAAM0e,EAAIukC,EAAQjjD,GACZgjD,EAAWtkC,EAAEyM,aAAa,SAAW,UACrCh1B,EAAUlK,KAAK82D,OAAOC,GACtBt8C,EAASgY,EAAEqC,WACjB,GAAI5qB,EACF,IAAK,MAAMyM,KAAKzM,EAAS,CACvB,GAAI6gC,GAA0B,IAAfp0B,EAAE2e,SAAgB,CAC/B,MAAM/wB,EAAKwmC,EAAU,KACfmsB,EAASl0D,SAASm0D,iBAAiBxgD,EAAG,GAE5C,IAAI8d,EACJ,IAFA9d,EAAEmf,aAAavxB,EAAI,IAEZkwB,EAAQyiC,EAAOp5B,YACpBrJ,EAAMqB,aAAavxB,EAAI,GAE3B,CACAkW,EAAOyxC,aAAav1C,EAAG8b,EACzB,MAEA,KAAOA,EAAE4C,YAAY5a,EAAOyxC,aAAaz5B,EAAE4C,WAAY5C,GAEzDhY,EAAO0xC,YAAY15B,EACrB,CACF,CAIA,SAAAwkC,GACE,MAAMG,EAAQ,CAACp3D,MAIf,OAHIA,KAAKyzB,kBACP2jC,EAAMz8C,QAAQ3a,KAAKyzB,kBAEd2jC,EAAM39C,OAAO,CAAClC,EAAKxD,KACxBwD,EAAIoD,QAAQnZ,MAAMsL,KAAKiH,EAAEtL,iBAAiB,UACnC8O,GACN,GACL,CAIA,iBAAAujC,CAAkBxW,GAChBtkC,KAAKi2D,aAAa3xB,EAAK2rB,OAAQ3rB,EACjC,CAIA,iBAAA+yB,CAAkB/yB,GAWlB,EAEF,SAASgzB,GAAQC,GACf,MAAMhsC,EAAW2M,KAEjB,OADW3M,GAAYA,EAASiI,IAczB,IACT,CACA,SAASgkC,KACP,MAAM1jD,EAA4EwjD,KAClF,OAAOxjD,GAAMA,EAAG+mC,UAClB,CAEA,SAAS4c,GAAaz5D,EAAO,UAC3B,CACE,MAAMutB,EAAW2M,KACjB,IAAK3M,EAEH,OAAOlY,EAET,MAAMqkD,EAAUnsC,EAASptB,KAAK2uC,aAC9B,IAAK4qB,EAEH,OAAOrkD,EAGT,OADYqkD,EAAQ15D,IAGXqV,CAGX,CACF,CAEA,MAAMskD,GAA8B,IAAI73C,QAClC83C,GAAiC,IAAI93C,QACrC+3C,GAAY73C,OAAO,WACnB,GAAaA,OAAO,YA8FpB83C,GA7FW,CAAC/J,WACTA,EAAE9vD,MAAM24B,KACRm3B,GAEmCgK,CAAS,CACnD/5D,KAAM,kBACNC,MAAuB,EAAO,CAAC,EAAG4vD,GAA2B,CAC3DzB,IAAKztD,OACLq5D,UAAWr5D,SAEb,KAAAsS,CAAMhT,GAAO,MAAEg6B,IACb,MAAM1M,EAAW2M,KACXhC,EAAQD,KACd,IAAIyjB,EACA5mB,EAqCJ,OApCAsU,GAAU,KACR,IAAKsS,EAAaj2C,OAChB,OAEF,MAAMu0D,EAAY/5D,EAAM+5D,WAAa,GAAG/5D,EAAMD,MAAQ,WACtD,IAkGN,SAAyB8V,EAAI+3B,EAAMmsB,GACjC,MAAM99B,EAAQpmB,EAAG64C,YACX0C,EAAOv7C,EAAGk5C,IACZqC,GACFA,EAAK3mD,QAASu2B,IACZA,EAAIj+B,MAAM,OAAO0H,QAAS6M,GAAMA,GAAK2kB,EAAMvxB,UAAUC,OAAO2M,MAGhEyiD,EAAUh3D,MAAM,OAAO0H,QAAS6M,GAAMA,GAAK2kB,EAAMvxB,UAAUE,IAAI0M,IAC/D2kB,EAAMx5B,MAAMuB,QAAU,OACtB,MAAM0vB,EAA8B,IAAlBka,EAAKvW,SAAiBuW,EAAOA,EAAK/W,WACpDnD,EAAUk7B,YAAY3yB,GACtB,MAAM,aAAEy2B,GAAiBd,GAAkB31B,GAE3C,OADAvI,EAAUw6B,YAAYjyB,GACfy2B,CACT,CAjHWsH,CACHve,EAAa,GAAG5lC,GAChByX,EAASI,MAAM7X,GACfkkD,GAGA,YADAte,EAAe,IAGjBA,EAAahxC,QAAQwvD,IACrBxe,EAAahxC,QAAQyvD,IACrB,MAAMC,EAAgB1e,EAAah4B,OAAO22C,IAC1CjJ,GAAY7jC,EAASI,MAAM7X,IAC3BskD,EAAc1vD,QAAS6M,IACrB,MAAMzB,EAAKyB,EAAEzB,GACPpT,EAAQoT,EAAGpT,MACjBwuD,GAAmBp7C,EAAIkkD,GACvBt3D,EAAMwK,UAAYxK,EAAM43D,gBAAkB53D,EAAM63D,mBAAqB,GACrE,MAAMtqC,EAAKna,EAAG+jD,IAAcz1D,IACtBA,GAAKA,EAAEe,SAAW2Q,GAGjB1R,IAAKA,EAAEo2D,aAAah5B,SAAS,eAChC1rB,EAAGgvB,oBAAoB,gBAAiB7U,GACxCna,EAAG+jD,IAAa,KAChB/I,GAAsBh7C,EAAIkkD,KAG9BlkD,EAAG5Q,iBAAiB,gBAAiB+qB,KAEvCyrB,EAAe,KAEV,KACL,MAAMthB,EAAW,GAAMn6B,GACjBw6D,EAAqBxK,GAAuB71B,GAClD,IAAIg0B,EAAMh0B,EAASg0B,KAAOxxB,GAE1B,GADA8e,EAAe,GACX5mB,EACF,IAAK,IAAI/e,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACnB0gB,EAAM3gB,IAAM2gB,EAAM3gB,cAAcguB,UAClC4X,EAAa/+B,KAAK8Z,GAClBkE,GACElE,EACAgE,GACEhE,EACAgkC,EACAviC,EACA3K,IAGJosC,GAAYv3C,IACVqU,EACAA,EAAM3gB,GAAGquB,yBAGf,CAEFrP,EAAWmF,EAAM55B,QAAU85B,GAAyBF,EAAM55B,WAAa,GACvE,IAAK,IAAI0V,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACN,MAAb0gB,EAAM3vB,KACR6zB,GACElE,EACAgE,GAAuBhE,EAAOgkC,EAAoBviC,EAAO3K,GAK/D,CACA,OAAOkT,GAAY2tB,EAAK,KAAMt5B,GAElC,IAGF,SAASolC,GAAe3iD,GACtB,MAAMzB,EAAKyB,EAAEzB,GACTA,EAAG+jD,KACL/jD,EAAG+jD,MAED/jD,EAAG,KACLA,EAAG,KAEP,CACA,SAASqkD,GAAe5iD,GACtBqiD,GAAex3C,IAAI7K,EAAGA,EAAEzB,GAAGquB,wBAC7B,CACA,SAASk2B,GAAiB9iD,GACxB,MAAMmjD,EAASf,GAAYj1D,IAAI6S,GACzBojD,EAASf,GAAel1D,IAAI6S,GAC5BqjD,EAAKF,EAAO12B,KAAO22B,EAAO32B,KAC1B62B,EAAKH,EAAO32B,IAAM42B,EAAO52B,IAC/B,GAAI62B,GAAMC,EAAI,CACZ,MAAM9Y,EAAIxqC,EAAEzB,GAAGpT,MAGf,OAFAq/C,EAAE70C,UAAY60C,EAAEuY,gBAAkB,aAAaM,OAAQC,OACvD9Y,EAAEwY,mBAAqB,KAChBhjD,CACT,CACF,CAkBA,MAAMujD,GAAoBntC,IACxB,MAAMvW,EAAKuW,EAAM1tB,MAAM,yBAA0B,EACjD,OAAO,EAAQmX,GAAO5H,GAAUyI,EAAeb,EAAI5H,GAAS4H,GAE9D,SAAS2jD,GAAmB32D,GAC1BA,EAAEe,OAAO61D,WAAY,CACvB,CACA,SAASC,GAAiB72D,GACxB,MAAMe,EAASf,EAAEe,OACbA,EAAO61D,YACT71D,EAAO61D,WAAY,EACnB71D,EAAOigC,cAAc,IAAI81B,MAAM,UAEnC,CACA,MAAMC,GAAYn5C,OAAO,WACnBo5C,GAAa,CACjB,OAAA9oB,CAAQx8B,GAAMmc,WAAW,KAAEopC,EAAI,KAAErhD,EAAI,OAAEspC,IAAY31B,GACjD7X,EAAGqlD,IAAaL,GAAiBntC,GACjC,MAAM2tC,EAAehY,GAAU31B,EAAM1tB,OAA8B,WAArB0tB,EAAM1tB,MAAME,KAC1D+E,GAAiB4Q,EAAIulD,EAAO,SAAW,QAAUj3D,IAC/C,GAAIA,EAAEe,OAAO61D,UAAW,OACxB,IAAIO,EAAWzlD,EAAGtG,MACdwK,IACFuhD,EAAWA,EAASvhD,QAElBshD,IACFC,EAAW7iD,EAAc6iD,IAE3BzlD,EAAGqlD,IAAWI,KAEZvhD,GACF9U,GAAiB4Q,EAAI,SAAU,KAC7BA,EAAGtG,MAAQsG,EAAGtG,MAAMwK,SAGnBqhD,IACHn2D,GAAiB4Q,EAAI,mBAAoBilD,IACzC71D,GAAiB4Q,EAAI,iBAAkBmlD,IACvC/1D,GAAiB4Q,EAAI,SAAUmlD,IAEnC,EAEA,OAAAl2D,CAAQ+Q,GAAI,MAAEtG,IACZsG,EAAGtG,MAAiB,MAATA,EAAgB,GAAKA,CAClC,EACA,YAAAgjC,CAAa18B,GAAI,MAAEtG,EAAK,SAAEuI,EAAUka,WAAW,KAAEopC,EAAI,KAAErhD,EAAI,OAAEspC,IAAY31B,GAEvE,GADA7X,EAAGqlD,IAAaL,GAAiBntC,GAC7B7X,EAAGklD,UAAW,OAClB,MACM1vD,EAAoB,MAATkE,EAAgB,GAAKA,EACtC,KAFiB8zC,GAAsB,WAAZxtC,EAAG3V,MAAuB,OAAOupC,KAAK5zB,EAAGtG,OAAmCsG,EAAGtG,MAA7BkJ,EAAc5C,EAAGtG,UAE9ElE,EAAhB,CAGA,GAAItG,SAASw2D,gBAAkB1lD,GAAkB,UAAZA,EAAG3V,KAAkB,CACxD,GAAIk7D,GAAQ7rD,IAAUuI,EACpB,OAEF,GAAIiC,GAAQlE,EAAGtG,MAAMwK,SAAW1O,EAC9B,MAEJ,CACAwK,EAAGtG,MAAQlE,CATX,CAUF,GAEImwD,GAAiB,CAErBtpC,MAAM,EACN,OAAAmgB,CAAQx8B,EAAIg3B,EAAGnf,GACb7X,EAAGqlD,IAAaL,GAAiBntC,GACjCzoB,GAAiB4Q,EAAI,SAAU,KAC7B,MAAM4lD,EAAa5lD,EAAG6lD,YAChBC,EAAeC,GAAS/lD,GACxBgmD,EAAUhmD,EAAGgmD,QACblmD,EAASE,EAAGqlD,IAClB,GAAI,EAAQO,GAAa,CACvB,MAAM90D,EAAQoU,GAAa0gD,EAAYE,GACjCG,GAAmB,IAAXn1D,EACd,GAAIk1D,IAAYC,EACdnmD,EAAO8lD,EAAWt4C,OAAOw4C,SACpB,IAAKE,GAAWC,EAAO,CAC5B,MAAMC,EAAW,IAAIN,GACrBM,EAASn1D,OAAOD,EAAO,GACvBgP,EAAOomD,EACT,CACF,MAAO,GAAIzlD,EAAMmlD,GAAa,CAC5B,MAAMtT,EAAS,IAAIxiC,IAAI81C,GACnBI,EACF1T,EAAOv9C,IAAI+wD,GAEXxT,EAAO7pC,OAAOq9C,GAEhBhmD,EAAOwyC,EACT,MACExyC,EAAOqmD,GAAiBnmD,EAAIgmD,KAGlC,EAEA/2D,QAASm3D,GACT,YAAA1pB,CAAa18B,EAAIyc,EAAS5E,GACxB7X,EAAGqlD,IAAaL,GAAiBntC,GACjCuuC,GAAWpmD,EAAIyc,EAAS5E,EAC1B,GAEF,SAASuuC,GAAWpmD,GAAI,MAAEtG,EAAK,SAAEuI,GAAY4V,GAE3C,IAAImuC,EACJ,GAFAhmD,EAAG6lD,YAAcnsD,EAEb,EAAQA,GACVssD,EAAU9gD,GAAaxL,EAAOme,EAAM1tB,MAAMuP,QAAU,OAC/C,GAAI+G,EAAM/G,GACfssD,EAAUtsD,EAAM8O,IAAIqP,EAAM1tB,MAAMuP,WAC3B,CACL,GAAIA,IAAUuI,EAAU,OACxB+jD,EAAUzhD,GAAW7K,EAAOysD,GAAiBnmD,GAAI,GACnD,CACIA,EAAGgmD,UAAYA,IACjBhmD,EAAGgmD,QAAUA,EAEjB,CACA,MAAMK,GAAc,CAClB,OAAA7pB,CAAQx8B,GAAI,MAAEtG,GAASme,GACrB7X,EAAGgmD,QAAUzhD,GAAW7K,EAAOme,EAAM1tB,MAAMuP,OAC3CsG,EAAGqlD,IAAaL,GAAiBntC,GACjCzoB,GAAiB4Q,EAAI,SAAU,KAC7BA,EAAGqlD,IAAWU,GAAS/lD,KAE3B,EACA,YAAA08B,CAAa18B,GAAI,MAAEtG,EAAK,SAAEuI,GAAY4V,GACpC7X,EAAGqlD,IAAaL,GAAiBntC,GAC7Bne,IAAUuI,IACZjC,EAAGgmD,QAAUzhD,GAAW7K,EAAOme,EAAM1tB,MAAMuP,OAE/C,GAEI4sD,GAAe,CAEnBjqC,MAAM,EACN,OAAAmgB,CAAQx8B,GAAI,MAAEtG,EAAOyiB,WAAW,OAAEqxB,IAAY31B,GAC5C,MAAM0uC,EAAa9lD,EAAM/G,GACzBtK,GAAiB4Q,EAAI,SAAU,KAC7B,MAAMwmD,EAAc94D,MAAMwS,UAAU0N,OAAOvN,KAAKL,EAAGzC,QAAUohB,GAAMA,EAAE8nC,UAAUpnD,IAC5Esf,GAAM6uB,EAAS5qC,EAAcmjD,GAASpnC,IAAMonC,GAASpnC,IAExD3e,EAAGqlD,IACDrlD,EAAGw4C,SAAW+N,EAAa,IAAIz2C,IAAI02C,GAAeA,EAAcA,EAAY,IAE9ExmD,EAAG0mD,YAAa,EAChBvtC,GAAS,KACPnZ,EAAG0mD,YAAa,MAGpB1mD,EAAGqlD,IAAaL,GAAiBntC,EACnC,EAGA,OAAA5oB,CAAQ+Q,GAAI,MAAEtG,IACZitD,GAAY3mD,EAAItG,EAClB,EACA,YAAAgjC,CAAa18B,EAAI4mD,EAAU/uC,GACzB7X,EAAGqlD,IAAaL,GAAiBntC,EACnC,EACA,OAAAuE,CAAQpc,GAAI,MAAEtG,IACPsG,EAAG0mD,YACNC,GAAY3mD,EAAItG,EAEpB,GAEF,SAASitD,GAAY3mD,EAAItG,GACvB,MAAMmtD,EAAa7mD,EAAGw4C,SAChBsO,EAAe,EAAQptD,GAC7B,IAAImtD,GAAeC,GAAiBrmD,EAAM/G,GAA1C,CAMA,IAAK,IAAIuG,EAAI,EAAG+G,EAAIhH,EAAGzC,QAAQ5N,OAAQsQ,EAAI+G,EAAG/G,IAAK,CACjD,MAAM8mD,EAAS/mD,EAAGzC,QAAQ0C,GACpB+mD,EAAcjB,GAASgB,GAC7B,GAAIF,EACF,GAAIC,EAAc,CAChB,MAAMG,SAAoBD,EAExBD,EAAON,SADU,WAAfQ,GAA0C,WAAfA,EACXvtD,EAAM8U,KAAM1I,GAAMjb,OAAOib,KAAOjb,OAAOm8D,IAEvC9hD,GAAaxL,EAAOstD,IAAgB,CAE1D,MACED,EAAON,SAAW/sD,EAAM8O,IAAIw+C,QAEzB,GAAIziD,GAAWwhD,GAASgB,GAASrtD,GAEtC,YADIsG,EAAGknD,gBAAkBjnD,IAAGD,EAAGknD,cAAgBjnD,GAGnD,CACK4mD,IAAoC,IAAtB7mD,EAAGknD,gBACpBlnD,EAAGknD,eAAiB,EArBtB,CAuBF,CACA,SAASnB,GAAS/lD,GAChB,MAAO,WAAYA,EAAKA,EAAG+K,OAAS/K,EAAGtG,KACzC,CACA,SAASysD,GAAiBnmD,EAAIgmD,GAC5B,MAAMh1D,EAAMg1D,EAAU,aAAe,cACrC,OAAOh1D,KAAOgP,EAAKA,EAAGhP,GAAOg1D,CAC/B,CACA,MAAMmB,GAAgB,CACpB,OAAA3qB,CAAQx8B,EAAIyc,EAAS5E,GACnBuvC,GAAcpnD,EAAIyc,EAAS5E,EAAO,KAAM,UAC1C,EACA,OAAA5oB,CAAQ+Q,EAAIyc,EAAS5E,GACnBuvC,GAAcpnD,EAAIyc,EAAS5E,EAAO,KAAM,UAC1C,EACA,YAAA6kB,CAAa18B,EAAIyc,EAAS5E,EAAO0E,GAC/B6qC,GAAcpnD,EAAIyc,EAAS5E,EAAO0E,EAAW,eAC/C,EACA,OAAAH,CAAQpc,EAAIyc,EAAS5E,EAAO0E,GAC1B6qC,GAAcpnD,EAAIyc,EAAS5E,EAAO0E,EAAW,UAC/C,GAEF,SAAS8qC,GAAoBp+B,EAAS5+B,GACpC,OAAQ4+B,GACN,IAAK,SACH,OAAOq9B,GACT,IAAK,WACH,OAAOhB,GACT,QACE,OAAQj7D,GACN,IAAK,WACH,OAAOs7D,GACT,IAAK,QACH,OAAOU,GACT,QACE,OAAOf,IAGjB,CACA,SAAS8B,GAAcpnD,EAAIyc,EAAS5E,EAAO0E,EAAWG,GACpD,MAIMpb,EAJa+lD,GACjBrnD,EAAGipB,QACHpR,EAAM1tB,OAAS0tB,EAAM1tB,MAAME,MAEPqyB,GACtBpb,GAAMA,EAAGtB,EAAIyc,EAAS5E,EAAO0E,EAC/B,CAoCA,MAAM+qC,GAAkB,CAAC,OAAQ,QAAS,MAAO,QAC3CC,GAAiB,CACrBhgD,KAAOjZ,GAAMA,EAAEk5D,kBACfC,QAAUn5D,GAAMA,EAAEE,iBAClB8U,KAAOhV,GAAMA,EAAEe,SAAWf,EAAEo5D,cAC5BC,KAAOr5D,IAAOA,EAAEs5D,QAChBr5C,MAAQjgB,IAAOA,EAAEu5D,SACjBr6D,IAAMc,IAAOA,EAAEw5D,OACfC,KAAOz5D,IAAOA,EAAE05D,QAChB95B,KAAO5/B,GAAM,WAAYA,GAAkB,IAAbA,EAAEC,OAChCqrB,OAAStrB,GAAM,WAAYA,GAAkB,IAAbA,EAAEC,OAClC6/B,MAAQ9/B,GAAM,WAAYA,GAAkB,IAAbA,EAAEC,OACjC05D,MAAO,CAAC35D,EAAG6tB,IAAcmrC,GAAgB94C,KAAMkT,GAAMpzB,EAAE,GAAGozB,UAAYvF,EAAUnO,SAAS0T,KAErFwmC,GAAgB,CAAC5mD,EAAI6a,KACzB,MAAM5a,EAAQD,EAAG6mD,YAAc7mD,EAAG6mD,UAAY,CAAC,GACzCC,EAAWjsC,EAAUjO,KAAK,KAChC,OAAO3M,EAAM6mD,KAAc7mD,EAAM6mD,GAAY,CAAEtwD,KAAU4C,KACvD,IAAK,IAAIuF,EAAI,EAAGA,EAAIkc,EAAUxsB,OAAQsQ,IAAK,CACzC,MAAMooD,EAAQd,GAAeprC,EAAUlc,IACvC,GAAIooD,GAASA,EAAMvwD,EAAOqkB,GAAY,MACxC,CACA,OAAO7a,EAAGxJ,KAAU4C,EACrB,IAEG4tD,GAAW,CACfC,IAAK,SACLC,MAAO,IACPC,GAAI,WACJv6B,KAAM,aACNE,MAAO,cACPs6B,KAAM,aACNjgD,OAAQ,aAEJkgD,GAAW,CAACrnD,EAAI6a,KACpB,MAAM5a,EAAQD,EAAGsnD,YAActnD,EAAGsnD,UAAY,CAAC,GACzCR,EAAWjsC,EAAUjO,KAAK,KAChC,OAAO3M,EAAM6mD,KAAc7mD,EAAM6mD,GAActwD,IAC7C,KAAM,QAASA,GACb,OAEF,MAAM+wD,EAAWjnD,EAAU9J,EAAM9G,KACjC,OAAImrB,EAAU3N,KACX8Z,GAAMA,IAAMugC,GAAYP,GAAShgC,KAAOugC,GAElCvnD,EAAGxJ,QAHZ,CAKD,IAGGgxD,GAAkC,EAAO,CAAEp/B,UAr+B/B,CAAC1pB,EAAIhP,EAAK+3D,EAAWC,EAAW/qC,EAAWF,KAC3D,MAAM2gC,EAAsB,QAAdzgC,EACF,UAARjtB,EA9YN,SAAoBgP,EAAItG,EAAOglD,GAC7B,MAAMuK,EAAoBjpD,EAAGk5C,IACzB+P,IACFvvD,GAASA,EAAQ,CAACA,KAAUuvD,GAAqB,IAAIA,IAAoB/6C,KAAK,MAEnE,MAATxU,EACFsG,EAAG8+C,gBAAgB,SACVJ,EACT1+C,EAAGgiB,aAAa,QAAStoB,GAEzBsG,EAAGkpD,UAAYxvD,CAEnB,CAmYIyvD,CAAWnpD,EAAIgpD,EAAWtK,GACT,UAAR1tD,EAtQb,SAAoBgP,EAAIuK,EAAMlC,GAC5B,MAAMzb,EAAQoT,EAAGpT,MACXw8D,EAAc,EAAS/gD,GAC7B,IAAIghD,GAAuB,EAC3B,GAAIhhD,IAAS+gD,EAAa,CACxB,GAAI7+C,EACF,GAAK,EAASA,GAOZ,IAAK,MAAM++C,KAAa/+C,EAAKrd,MAAM,KAAM,CACvC,MAAM8D,EAAMs4D,EAAUtoD,MAAM,EAAGsoD,EAAUh8D,QAAQ,MAAM4W,OACtC,MAAbmE,EAAKrX,IACPktD,GAAStxD,EAAOoE,EAAK,GAEzB,MAXA,IAAK,MAAMA,KAAOuZ,EACC,MAAblC,EAAKrX,IACPktD,GAAStxD,EAAOoE,EAAK,IAY7B,IAAK,MAAMA,KAAOqX,EACJ,YAARrX,IACFq4D,GAAuB,GAEzBnL,GAAStxD,EAAOoE,EAAKqX,EAAKrX,GAE9B,MACE,GAAIo4D,GACF,GAAI7+C,IAASlC,EAAM,CACjB,MAAMkhD,EAAa38D,EAAM0wD,IACrBiM,IACFlhD,GAAQ,IAAMkhD,GAEhB38D,EAAMmX,QAAUsE,EAChBghD,EAAuBrL,GAAUpqB,KAAKvrB,EACxC,OACSkC,GACTvK,EAAG8+C,gBAAgB,SAGnB5B,MAAwBl9C,IAC1BA,EAAGk9C,IAAwBmM,EAAuBz8D,EAAMuB,QAAU,GAC9D6R,EAAGm9C,MACLvwD,EAAMuB,QAAU,QAGtB,CAwNIq7D,CAAWxpD,EAAI+oD,EAAWC,GACjBtpD,EAAK1O,GACT4O,EAAgB5O,IAxFzB,SAAoBgP,EAAIo+C,EAAS2K,EAAWC,EAAWvxC,EAAW,MAChE,MAAMgyC,EAAWzpD,EAAGk/C,MAAYl/C,EAAGk/C,IAAU,CAAC,GACxCwK,EAAkBD,EAASrL,GACjC,GAAI4K,GAAaU,EACfA,EAAgBhwD,MAA6FsvD,MACxG,CACL,MAAO9+D,EAAMqT,GAcjB,SAAmBrT,GACjB,IAAIqT,EACJ,GAAI4hD,GAAkBvrB,KAAK1pC,GAAO,CAEhC,IAAIw3B,EACJ,IAFAnkB,EAAU,CAAC,EAEJmkB,EAAIx3B,EAAKsiC,MAAM2yB,KACpBj1D,EAAOA,EAAK8W,MAAM,EAAG9W,EAAKyF,OAAS+xB,EAAE,GAAG/xB,QACxC4N,EAAQmkB,EAAE,GAAG7f,gBAAiB,CAElC,CAEA,MAAO,CADmB,MAAZ3X,EAAK,GAAaA,EAAK8W,MAAM,GAAKY,EAAU1X,EAAK8W,MAAM,IACtDzD,EACjB,CA1B4BosD,CAAUvL,GAClC,GAAI4K,EAAW,CACb,MAAMY,EAAUH,EAASrL,GA4B/B,SAAuByL,EAAcpyC,GACnC,MAAMmyC,EAAWt7D,IACf,GAAKA,EAAEw7D,MAEA,GAAIx7D,EAAEw7D,MAAQF,EAAQG,SAC3B,YAFAz7D,EAAEw7D,KAAOxK,KAAKC,MAIhB5nC,GAqBJ,SAAuCrpB,EAAGoL,GACxC,GAAI,EAAQA,GAAQ,CAClB,MAAMswD,EAAe17D,EAAE27D,yBAKvB,OAJA37D,EAAE27D,yBAA2B,KAC3BD,EAAa3pD,KAAK/R,GAClBA,EAAE47D,UAAW,GAERxwD,EAAM2F,IACViC,GAAQ8mC,IAAQA,EAAG8hB,UAAY5oD,GAAMA,EAAG8mC,GAE7C,CACE,OAAO1uC,CAEX,CAjCMywD,CAA8B77D,EAAGs7D,EAAQlwD,OACzC+d,EACA,EACA,CAACnpB,KAKL,OAFAs7D,EAAQlwD,MAAQmwD,EAChBD,EAAQG,SAAW1K,KACZuK,CACT,CA7C0CQ,CACmDpB,EACrFvxC,GAEFroB,GAAiB4Q,EAAI9V,EAAM0/D,EAASrsD,EACtC,MAAWmsD,IAjBf,SAA6B1pD,EAAIlI,EAAOsjC,EAAS79B,GAC/CyC,EAAGgvB,oBAAoBl3B,EAAOsjC,EAAS79B,EACzC,CAgBMyxB,CAAoBhvB,EAAI9V,EAAMw/D,EAAiBnsD,GAC/CksD,EAASrL,QAAW,EAExB,CACF,CAuEMiM,CAAWrqD,EAAIhP,EAAK+3D,EAAWC,EAAWjrC,IAExB,MAAX/sB,EAAI,IAAcA,EAAMA,EAAIgQ,MAAM,GAAI,GAAmB,MAAXhQ,EAAI,IAAcA,EAAMA,EAAIgQ,MAAM,GAAI,GAmBjG,SAAyBhB,EAAIhP,EAAK0I,EAAOglD,GACvC,GAAIA,EACF,MAAY,cAAR1tD,GAA+B,gBAARA,MAGvBA,KAAOgP,GAAMw/C,GAAWxuD,IAAQ,EAAW0I,IAKjD,GAAY,eAAR1I,GAAgC,cAARA,GAA+B,cAARA,GAA+B,gBAARA,EACxE,OAAO,EAET,GAAY,SAARA,EACF,OAAO,EAET,GAAY,SAARA,GAAiC,UAAfgP,EAAGipB,QACvB,OAAO,EAET,GAAY,SAARj4B,GAAiC,aAAfgP,EAAGipB,QACvB,OAAO,EAET,GAAY,UAARj4B,GAA2B,WAARA,EAAkB,CACvC,MAAMsnD,EAAMt4C,EAAGipB,QACf,GAAY,QAARqvB,GAAyB,UAARA,GAA2B,WAARA,GAA4B,WAARA,EAC1D,OAAO,CAEX,CACA,QAAIkH,GAAWxuD,KAAQ,EAAS0I,KAGzB1I,KAAOgP,CAChB,CAnD0GsqD,CAAgBtqD,EAAIhP,EAAKg4D,EAAWtK,KAC1IK,GAAa/+C,EAAIhP,EAAKg4D,GACjBhpD,EAAGipB,QAAQjb,SAAS,MAAiB,UAARhd,GAA2B,YAARA,GAA6B,aAARA,GACxEytD,GAAUz+C,EAAIhP,EAAKg4D,EAAWtK,EAAO3gC,EAAyB,UAAR/sB,KAIxDgP,EAAGmgD,WAAa,QAAQvsB,KAAK5iC,IAAS,EAASg4D,IAInC,eAARh4D,EACFgP,EAAGuqD,WAAavB,EACC,gBAARh4D,IACTgP,EAAGwqD,YAAcxB,GAEnBvK,GAAUz+C,EAAIhP,EAAKg4D,EAAWtK,IAP9BK,GAAa/+C,EAAI,EAAWhP,GAAMg4D,EAAWjrC,EAAiB/sB,KAk9BJmnD,IAC9D,IAAIpmB,GACA04B,IAAmB,EACvB,SAASC,KACP,OAAO34B,KAAaA,GAAWsQ,GAAeymB,IAChD,CACA,SAAS6B,KAGP,OAFA54B,GAAW04B,GAAmB14B,GAAWwQ,GAAwBumB,IACjE2B,IAAmB,EACZ14B,EACT,CACA,MAAMkM,GAAS,IAAKvjC,KAClBgwD,KAAiBzsB,UAAUvjC,EAC5B,EACKmmB,GAAU,IAAKnmB,KACnBiwD,KAA0B9pC,WAAWnmB,EACtC,EACKuC,GAAY,IAAKvC,KACrB,MAAM4C,EAAMotD,KAAiBztD,aAAavC,IAKpC,MAAEqE,GAAUzB,EAkBlB,OAjBAA,EAAIyB,MAAS6rD,IACX,MAAM/sC,EAAYgtC,GAAmBD,GACrC,IAAK/sC,EAAW,OAChB,MAAMpgB,EAAYH,EAAIkhC,WACjB,EAAW/gC,IAAeA,EAAUwgC,QAAWxgC,EAAUs3C,WAC5Dt3C,EAAUs3C,SAAWl3B,EAAUjjB,WAEN,IAAvBijB,EAAU2D,WACZ3D,EAAUyN,YAAc,IAE1B,MAAMzX,EAAQ9U,EAAM8e,GAAW,EAAOitC,GAAqBjtC,IAK3D,OAJIA,aAAqBmQ,UACvBnQ,EAAUihC,gBAAgB,WAC1BjhC,EAAUmE,aAAa,aAAc,KAEhCnO,GAEFvW,CACR,EACK2iD,GAAe,IAAKvlD,KACxB,MAAM4C,EAAMqtD,KAA0B1tD,aAAavC,IAK7C,MAAEqE,GAAUzB,EAOlB,OANAA,EAAIyB,MAAS6rD,IACX,MAAM/sC,EAAYgtC,GAAmBD,GACrC,GAAI/sC,EACF,OAAO9e,EAAM8e,GAAW,EAAMitC,GAAqBjtC,KAGhDvgB,CACR,EACD,SAASwtD,GAAqBjtC,GAC5B,OAAIA,aAAqBV,WAChB,MAEoB,mBAAlBE,eAAgCQ,aAAqBR,cACvD,cADT,CAGF,CAoCA,SAASwtC,GAAmBhtC,GAC1B,OAAI,EAASA,GACC3uB,SAASiN,cAAc0hB,GAa9BA,CACT,CACA,IAAIktC,IAA0B,EAC9B,MAAMC,GAAuB,KACtBD,KACHA,IAA0B,EA7M5BzF,GAAW2F,YAAc,EAAGvxD,YAAY,CAAGA,UAC3C2sD,GAAY4E,YAAc,EAAGvxD,SAASme,KACpC,GAAIA,EAAM1tB,OAASoa,GAAWsT,EAAM1tB,MAAMuP,MAAOA,GAC/C,MAAO,CAAEssD,SAAS,IAGtBL,GAAesF,YAAc,EAAGvxD,SAASme,KACvC,GAAI,EAAQne,IACV,GAAIme,EAAM1tB,OAAS+a,GAAaxL,EAAOme,EAAM1tB,MAAMuP,QAAU,EAC3D,MAAO,CAAEssD,SAAS,QAEf,GAAIvlD,EAAM/G,IACf,GAAIme,EAAM1tB,OAASuP,EAAM8O,IAAIqP,EAAM1tB,MAAMuP,OACvC,MAAO,CAAEssD,SAAS,QAEf,GAAItsD,EACT,MAAO,CAAEssD,SAAS,IAGtBmB,GAAc8D,YAAc,CAACxuC,EAAS5E,KACpC,GAA0B,iBAAfA,EAAMxtB,KACf,OAEF,MAAM6gE,EAAa7D,GAEjBxvC,EAAMxtB,KAAKqX,cACXmW,EAAM1tB,OAAS0tB,EAAM1tB,MAAME,MAE7B,OAAI6gE,EAAWD,YACNC,EAAWD,YAAYxuC,EAAS5E,QADzC,GAhwCFulC,GAAM6N,YAAc,EAAGvxD,YACrB,IAAKA,EACH,MAAO,CAAE9M,MAAO,CAAEuB,QAAS,YCta3Bg9D,GAAWj/C,OAAgE,IAC3Ek/C,GAAWl/C,OAAgE,IAC3Em/C,GAAWn/C,OAAgE,IAC3Eo/C,GAAap/C,OAAiE,IAC9Eq/C,GAAkBr/C,OACyC,IAE3Ds/C,GAAat/C,OAAiE,IAC9Eu/C,GAAev/C,OAAmE,IAClFw/C,GAAuBx/C,OACwC,IAE/Dy/C,GAAez/C,OAAmE,IAClF0/C,GAAuB1/C,OACwC,IAE/D2/C,GAAiB3/C,OAC8C,IAE/D4/C,GAAc5/C,OAC8C,IAE5D6/C,GAAgB7/C,OAC8C,IAE9D8/C,GAAoB9/C,OACyC,IAE7D+/C,GAA4B//C,OACwC,IAEpEggD,GAAoBhgD,OACyC,IAE7DigD,GAAiBjgD,OACyC,IAE1DkgD,GAAkBlgD,OACyC,IAE3DmgD,GAAcngD,OAAkE,IAChFogD,GAAcpgD,OAAkE,IAChFqgD,GAAergD,OAAmE,IAClFsgD,GAAoBtgD,OACwC,IAE5DugD,GAAcvgD,OAAkE,IAChFwgD,GAAkBxgD,OACyC,IAE3DygD,GAAkBzgD,OACyC,IAE3D0gD,GAAkB1gD,OACyC,IAE3D2gD,GAAuB3gD,OACwC,IAE/D4gD,GAAc5gD,OAAkE,IAChF6gD,GAAW7gD,OAAgE,IAC3E8gD,GAAa9gD,OAAkE,IAC/E+gD,GAAiB/gD,OACwC,IAEzDghD,GAAqBhhD,OACwC,IAE7DihD,GAAgBjhD,OAAmE,IACnFkhD,GAAelhD,OAAkE,IACjFmhD,GAAWnhD,OAA+D,IAC1EohD,GAAQphD,OAA6D,IACrEqhD,GAASrhD,OAA6D,IACtEshD,GAAYthD,OAAgE,IAC5EuhD,GAAevhD,OAAkE,IACjFwhD,GAAgB,CACpB,CAACvC,IAAW,WACZ,CAACC,IAAW,WACZ,CAACC,IAAW,WACZ,CAACC,IAAa,YACd,CAACC,IAAkB,iBACnB,CAACC,IAAa,YACd,CAACC,IAAe,cAChB,CAACC,IAAuB,qBACxB,CAACC,IAAe,cAChB,CAACC,IAAuB,qBACxB,CAACC,IAAiB,qBAClB,CAACC,IAAc,kBACf,CAACC,IAAgB,oBACjB,CAACC,IAAoB,mBACrB,CAACC,IAA4B,0BAC7B,CAACC,IAAoB,mBACrB,CAACC,IAAiB,gBAClB,CAACC,IAAkB,iBACnB,CAACC,IAAc,aACf,CAACC,IAAc,aACf,CAACC,IAAe,cAChB,CAACC,IAAoB,kBACrB,CAACC,IAAc,aACf,CAACC,IAAkB,iBACnB,CAACC,IAAkB,iBACnB,CAACC,IAAkB,iBACnB,CAACC,IAAuB,qBACxB,CAACC,IAAc,aACf,CAACC,IAAW,WACZ,CAACC,IAAa,aACd,CAACC,IAAiB,eAClB,CAACC,IAAqB,mBACtB,CAACC,IAAgB,cACjB,CAACC,IAAe,aAChB,CAACC,IAAW,UACZ,CAACC,IAAQ,QACT,CAACC,IAAS,QACV,CAACC,IAAY,WACb,CAACC,IAAe,cA4FZE,GAAU,CACdj0C,MAAO,CAAEk0C,KAAM,EAAGC,OAAQ,EAAGC,OAAQ,GACrCn0C,IAAK,CAAEi0C,KAAM,EAAGC,OAAQ,EAAGC,OAAQ,GACnCj5C,OAAQ,IAkBV,SAASk5C,GAAgB3vB,EAASka,EAAKnuD,EAAO60B,EAAU+H,EAAW2d,EAAc5oB,EAAYkyC,GAAU,EAAO1c,GAAkB,EAAO2c,GAAc,EAAOC,EAAMP,IAYhK,OAXIvvB,IACE4vB,GACF5vB,EAAQ+vB,OAAO3C,IACfptB,EAAQ+vB,OAAOC,GAAoBhwB,EAAQiwB,MAAOJ,KAElD7vB,EAAQ+vB,OAAOG,GAAelwB,EAAQiwB,MAAOJ,IAE3CnyC,GACFsiB,EAAQ+vB,OAAO/B,KAGZ,CACL/hE,KAAM,GACNiuD,MACAnuD,QACA60B,WACA+H,YACA2d,eACA5oB,aACAkyC,UACA1c,kBACA2c,cACAC,MAEJ,CACA,SAASK,GAAsBC,EAAUN,EAAMP,IAC7C,MAAO,CACLtjE,KAAM,GACN6jE,MACAM,WAEJ,CACA,SAASC,GAAuBC,EAAYR,EAAMP,IAChD,MAAO,CACLtjE,KAAM,GACN6jE,MACAQ,aAEJ,CACA,SAASC,GAAqB39D,EAAK0I,GACjC,MAAO,CACLrP,KAAM,GACN6jE,IAAKP,GACL38D,IAAK,EAASA,GAAO49D,GAAuB59D,GAAK,GAAQA,EACzD0I,QAEJ,CACA,SAASk1D,GAAuBx4D,EAASy4D,GAAW,EAAOX,EAAMP,GAASmB,EAAY,GACpF,MAAO,CACLzkE,KAAM,EACN6jE,MACA93D,UACAy4D,WACAC,UAAWD,EAAW,EAAIC,EAE9B,CAQA,SAASC,GAAyB/vC,EAAUkvC,EAAMP,IAChD,MAAO,CACLtjE,KAAM,EACN6jE,MACAlvC,WAEJ,CACA,SAASgwC,GAAqBC,EAAQv0D,EAAO,GAAIwzD,EAAMP,IACrD,MAAO,CACLtjE,KAAM,GACN6jE,MACAe,SACAthD,UAAWjT,EAEf,CACA,SAASw0D,GAAyBv5D,EAAQw5D,OAAU,EAAQC,GAAU,EAAOC,GAAS,EAAOnB,EAAMP,IACjG,MAAO,CACLtjE,KAAM,GACNsL,SACAw5D,UACAC,UACAC,SACAnB,MAEJ,CACA,SAASoB,GAA4B17B,EAAM27B,EAAYC,EAAWJ,GAAU,GAC1E,MAAO,CACL/kE,KAAM,GACNupC,OACA27B,aACAC,YACAJ,UACAlB,IAAKP,GAET,CAyDA,SAASW,GAAemB,EAAKxB,GAC3B,OAAOwB,GAAOxB,EAActC,GAAeC,EAC7C,CACA,SAASwC,GAAoBqB,EAAKxB,GAChC,OAAOwB,GAAOxB,EAAcxC,GAAeC,EAC7C,CACA,SAASgE,GAAe5uC,GAAM,OAAEqtC,EAAM,aAAEwB,EAAY,MAAEtB,IAC/CvtC,EAAKktC,UACRltC,EAAKktC,SAAU,EACf2B,EAAarB,GAAeD,EAAOvtC,EAAKmtC,cACxCE,EAAO3C,IACP2C,EAAOC,GAAoBC,EAAOvtC,EAAKmtC,cAE3C,CAEA,MAAM2B,GAAwB,IAAIC,WAAW,CAAC,IAAK,MAC7CC,GAAyB,IAAID,WAAW,CAAC,IAAK,MACpD,SAASE,GAAetuD,GACtB,OAAOA,GAAK,IAAMA,GAAK,KAAOA,GAAK,IAAMA,GAAK,EAChD,CACA,SAASuuD,GAAavuD,GACpB,OAAa,KAANA,GAAkB,KAANA,GAAkB,IAANA,GAAiB,KAANA,GAAkB,KAANA,CACxD,CACA,SAASwuD,GAAkBxuD,GACzB,OAAa,KAANA,GAAkB,KAANA,GAAYuuD,GAAavuD,EAC9C,CACA,SAASyuD,GAAY9wD,GACnB,MAAM4E,EAAM,IAAI6rD,WAAWzwD,EAAIzP,QAC/B,IAAK,IAAIsQ,EAAI,EAAGA,EAAIb,EAAIzP,OAAQsQ,IAC9B+D,EAAI/D,GAAKb,EAAIO,WAAWM,GAE1B,OAAO+D,CACT,CACA,MAAMmsD,GAAY,CAChBC,MAAO,IAAIP,WAAW,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,KAE3CQ,SAAU,IAAIR,WAAW,CAAC,GAAI,GAAI,KAElCS,WAAY,IAAIT,WAAW,CAAC,GAAI,GAAI,KAEpCU,UAAW,IAAIV,WAAW,CAAC,GAAI,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,MAE3DW,SAAU,IAAIX,WAAW,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,MAEtDY,SAAU,IAAIZ,WAAW,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,MAEtDa,YAAa,IAAIb,WAAW,CAC1B,GACA,GACA,IACA,IACA,IACA,IACA,GACA,IACA,IACA,MAsyBJ,SAASc,GAAe3/D,GAAK,aAAE4/D,IAC7B,MAAMl3D,EAAQk3D,GAAgBA,EAAa5/D,GAC3C,MAAY,SAARA,EACK0I,GAAS,EAETA,CAEX,CACA,SAASm3D,GAAgB7/D,EAAKotC,GAC5B,MAAMtb,EAAO6tC,GAAe,OAAQvyB,GAC9B1kC,EAAQi3D,GAAe3/D,EAAKotC,GAClC,OAAgB,IAATtb,GAAuB,IAAVppB,GAA2B,IAAVA,CACvC,CACA,SAASo3D,GAAmB9/D,EAAKotC,EAAS8vB,KAAQxzD,GAKhD,OAJgBm2D,GAAgB7/D,EAAKotC,EAKvC,CAeA,SAAS2yB,GAAep2D,GACtB,MAAMA,CACR,CACA,SAASq2D,GAAcC,GAEvB,CACA,SAASC,GAAoBC,EAAMjD,EAAKkD,EAAUC,GAChD,MACM12D,EAAQ,IAAI22D,YAAYzmE,OADmG,+CAA+CsmE,MAIhL,OAFAx2D,EAAMw2D,KAAOA,EACbx2D,EAAMuzD,IAAMA,EACLvzD,CACT,CAoUA,MAAM42D,GAAen4C,GAAiB,IAAXA,EAAE/uB,MAAc+uB,EAAEy1C,SAC7C,SAAS2C,GAAgBlZ,GACvB,OAAQA,GACN,IAAK,WACL,IAAK,WACH,OAAO8S,GACT,IAAK,WACL,IAAK,WACH,OAAOC,GACT,IAAK,YACL,IAAK,aACH,OAAOC,GACT,IAAK,iBACL,IAAK,kBACH,OAAOC,GAEb,CACA,MAAMkG,GAAkB,4BAClBC,GAAsBxnE,IAAUunE,GAAgB79B,KAAK1pC,GACrDynE,GAAwB,wBACxBC,GAAmB,uBACnBC,GAAe,yBACfC,GAAgBC,GAAqB,IAAbA,EAAI1nE,KAAa0nE,EAAI37D,QAAU27D,EAAI7D,IAAIr5C,OAgE/Dm9C,GA/D6BD,IACjC,MAAMvlB,EAAOslB,GAAaC,GAAK7tD,OAAOxI,QAAQm2D,GAAe5lB,GAAMA,EAAE/nC,QACrE,IAAIke,EAAQ,EACR6vC,EAAa,GACbC,EAA0B,EAC1BC,EAAyB,EACzBC,EAAoB,KACxB,IAAK,IAAInyD,EAAI,EAAGA,EAAIusC,EAAK78C,OAAQsQ,IAAK,CACpC,MAAMoyD,EAAO7lB,EAAK1qC,OAAO7B,GACzB,OAAQmiB,GACN,KAAK,EACH,GAAa,MAATiwC,EACFJ,EAAWprD,KAAKub,GAChBA,EAAQ,EACR8vC,SACK,GAAa,MAATG,EACTJ,EAAWprD,KAAKub,GAChBA,EAAQ,EACR+vC,SACK,KAAY,IAANlyD,EAAU0xD,GAAwBC,IAAkBh+B,KAAKy+B,GACpE,OAAO,EAET,MACF,KAAK,EACU,MAATA,GAAyB,MAATA,GAAyB,MAATA,GAClCJ,EAAWprD,KAAKub,GAChBA,EAAQ,EACRgwC,EAAoBC,GACF,MAATA,EACTH,IACkB,MAATG,MACFH,IACL9vC,EAAQ6vC,EAAWvqD,QAGvB,MACF,KAAK,EACH,GAAa,MAAT2qD,GAAyB,MAATA,GAAyB,MAATA,EAClCJ,EAAWprD,KAAKub,GAChBA,EAAQ,EACRgwC,EAAoBC,OACf,GAAa,MAATA,EACTF,SACK,GAAa,MAATE,EAAc,CACvB,GAAIpyD,IAAMusC,EAAK78C,OAAS,EACtB,OAAO,IAEFwiE,IACL/vC,EAAQ6vC,EAAWvqD,MAEvB,CACA,MACF,KAAK,EACC2qD,IAASD,IACXhwC,EAAQ6vC,EAAWvqD,MACnB0qD,EAAoB,MAI5B,CACA,OAAQF,IAA4BC,GAIhCG,GAAU,uGAkChB,SAASC,GAAQzxC,EAAM52B,EAAMsoE,GAAa,GACxC,IAAK,IAAIvyD,EAAI,EAAGA,EAAI6gB,EAAK32B,MAAMwF,OAAQsQ,IAAK,CAC1C,MAAMmZ,EAAI0H,EAAK32B,MAAM8V,GACrB,GAAe,IAAXmZ,EAAE/uB,OAAemoE,GAAcp5C,EAAE24C,OAAS,EAAS7nE,GAAQkvB,EAAElvB,OAASA,EAAOA,EAAK0pC,KAAKxa,EAAElvB,OAC3F,OAAOkvB,CAEX,CACF,CACA,SAASq5C,GAAS3xC,EAAM52B,EAAMwoE,GAAc,EAAOF,GAAa,GAC9D,IAAK,IAAIvyD,EAAI,EAAGA,EAAI6gB,EAAK32B,MAAMwF,OAAQsQ,IAAK,CAC1C,MAAMmZ,EAAI0H,EAAK32B,MAAM8V,GACrB,GAAe,IAAXmZ,EAAE/uB,KAAY,CAChB,GAAIqoE,EAAa,SACjB,GAAIt5C,EAAElvB,OAASA,IAASkvB,EAAE1f,OAAS84D,GACjC,OAAOp5C,CAEX,MAAO,GAAe,SAAXA,EAAElvB,OAAoBkvB,EAAE24C,KAAOS,IAAeG,GAAcv5C,EAAE/W,IAAKnY,GAC5E,OAAOkvB,CAEX,CACF,CACA,SAASu5C,GAActwD,EAAKnY,GAC1B,SAAUmY,IAAOkvD,GAAYlvD,IAAQA,EAAIjM,UAAYlM,EACvD,CASA,SAAS0oE,GAAS9xC,GAChB,OAAqB,IAAdA,EAAKz2B,MAA4B,IAAdy2B,EAAKz2B,IACjC,CACA,SAASwoE,GAAOz5C,GACd,OAAkB,IAAXA,EAAE/uB,MAAyB,QAAX+uB,EAAElvB,IAC3B,CACA,SAAS4oE,GAAQ15C,GACf,OAAkB,IAAXA,EAAE/uB,MAAyB,SAAX+uB,EAAElvB,IAC3B,CACA,SAASggC,GAAepJ,GACtB,OAAqB,IAAdA,EAAKz2B,MAA+B,IAAjBy2B,EAAKiyC,OACjC,CACA,SAASC,GAAalyC,GACpB,OAAqB,IAAdA,EAAKz2B,MAA+B,IAAjBy2B,EAAKiyC,OACjC,CACA,MAAME,GAAiC,IAAInjD,IAAI,CAAC88C,GAAiBC,KACjE,SAASqG,GAAqB/oE,EAAOgpE,EAAW,IAC9C,GAAIhpE,IAAU,EAASA,IAAyB,KAAfA,EAAME,KAAa,CAClD,MAAM4kE,EAAS9kE,EAAM8kE,OACrB,IAAK,EAASA,IAAWgE,GAAezqD,IAAIymD,GAC1C,OAAOiE,GACL/oE,EAAMwjB,UAAU,GAChBwlD,EAAS7lD,OAAOnjB,GAGtB,CACA,MAAO,CAACA,EAAOgpE,EACjB,CACA,SAASC,GAAWtyC,EAAMqgB,EAAM/C,GAC9B,IAAIi1B,EAGAC,EAFAnpE,EAAsB,KAAd22B,EAAKz2B,KAAcy2B,EAAK32B,MAAQ22B,EAAKnT,UAAU,GACvDwlD,EAAW,GAEf,GAAIhpE,IAAU,EAASA,IAAyB,KAAfA,EAAME,KAAa,CAClD,MAAM2Z,EAAMkvD,GAAqB/oE,GACjCA,EAAQ6Z,EAAI,GACZmvD,EAAWnvD,EAAI,GACfsvD,EAAaH,EAASA,EAASxjE,OAAS,EAC1C,CACA,GAAa,MAATxF,GAAiB,EAASA,GAC5BkpE,EAAqB5E,GAAuB,CAACttB,SACxC,GAAmB,KAAfh3C,EAAME,KAAa,CAC5B,MAAMkpE,EAAQppE,EAAMwjB,UAAU,GACzB,EAAS4lD,IAAyB,KAAfA,EAAMlpE,KAKxBF,EAAM8kE,SAAWnC,GACnBuG,EAAqBrE,GAAqB5wB,EAAQ+vB,OAAO1B,IAAc,CACrEgC,GAAuB,CAACttB,IACxBh3C,IAGFA,EAAMwjB,UAAUkB,QAAQ4/C,GAAuB,CAACttB,KAV7CqyB,GAAQryB,EAAMoyB,IACjBA,EAAM7E,WAAW7/C,QAAQsyB,IAY5BkyB,IAAuBA,EAAqBlpE,EAC/C,MAA0B,KAAfA,EAAME,MACVmpE,GAAQryB,EAAMh3C,IACjBA,EAAMukE,WAAW7/C,QAAQsyB,GAE3BkyB,EAAqBlpE,IAErBkpE,EAAqBrE,GAAqB5wB,EAAQ+vB,OAAO1B,IAAc,CACrEgC,GAAuB,CAACttB,IACxBh3C,IAEEmpE,GAAcA,EAAWrE,SAAWpC,KACtCyG,EAAaH,EAASA,EAASxjE,OAAS,KAG1B,KAAdmxB,EAAKz2B,KACHipE,EACFA,EAAW3lD,UAAU,GAAK0lD,EAE1BvyC,EAAK32B,MAAQkpE,EAGXC,EACFA,EAAW3lD,UAAU,GAAK0lD,EAE1BvyC,EAAKnT,UAAU,GAAK0lD,CAG1B,CACA,SAASG,GAAQryB,EAAMh3C,GACrB,IAAI+kB,GAAS,EACb,GAAsB,IAAlBiyB,EAAKnwC,IAAI3G,KAAY,CACvB,MAAMopE,EAActyB,EAAKnwC,IAAIoF,QAC7B8Y,EAAS/kB,EAAMukE,WAAWlgD,KACvB4K,GAAqB,IAAfA,EAAEpoB,IAAI3G,MAAc+uB,EAAEpoB,IAAIoF,UAAYq9D,EAEjD,CACA,OAAOvkD,CACT,CACA,SAASwkD,GAAexpE,EAAMG,GAC5B,MAAO,IAAIA,KAAQH,EAAKwR,QAAQ,SAAU,CAACi4D,EAAaC,IAC/B,MAAhBD,EAAsB,IAAMzpE,EAAKyV,WAAWi0D,GAAc7yD,aAErE,CAiDA,MAAM8yD,GAAa,uCAEbC,GAAuB,CAC3BC,UAAW,OACXC,GAAI,EACJhf,WAAY,CAAC,KAAM,MACnBif,aAAc,IAAM,EACpB5vD,UAAW5E,EACXy0D,SAAUz0D,EACV00D,mBAAoB10D,EACpBgsB,gBAAiBhsB,EACjBswB,QAASghC,GACTqD,OAAQpD,GACRqD,UAAU,EACVC,mBAAmB,GAErB,IAAIC,GAAiBT,GACjBU,GAAc,KACdC,GAAe,GACfC,GAAiB,KACjBC,GAAc,KACdC,GAAmB,GACnBC,IAAyB,EACzBC,IAAuB,EACvBC,GAAQ,EACRC,IAAS,EACTC,GAAsB,KAC1B,MAAM,GAAQ,GACRC,GAAY,IA99ClB,MACE,WAAA9uD,CAAYiR,EAAO89C,GACjBjpE,KAAKmrB,MAAQA,EACbnrB,KAAKipE,IAAMA,EAEXjpE,KAAKk2B,MAAQ,EAEbl2B,KAAKwuB,OAAS,GAEdxuB,KAAKkpE,aAAe,EAEpBlpE,KAAK4E,MAAQ,EAEb5E,KAAKmpE,YAAc,EAEnBnpE,KAAKopE,UAAY,EAEjBppE,KAAKqpE,UAAW,EAEhBrpE,KAAKspE,OAAQ,EAEbtpE,KAAK8oE,QAAS,EAEd9oE,KAAKupE,SAAW,GAChBvpE,KAAK42B,KAAO,EACZ52B,KAAKwpE,cAAgB9F,GACrB1jE,KAAKypE,eAAiB7F,GACtB5jE,KAAK0pE,gBAAkB,EACvB1pE,KAAK2pE,qBAAkB,EACvB3pE,KAAK4pE,cAAgB,CACvB,CACA,aAAIC,GACF,OAAqB,IAAd7pE,KAAK42B,MAAoC,IAAtB52B,KAAKmrB,MAAM1nB,MACvC,CACA,KAAA8kC,GACEvoC,KAAKk2B,MAAQ,EACbl2B,KAAK42B,KAAO,EACZ52B,KAAKwuB,OAAS,GACdxuB,KAAKkpE,aAAe,EACpBlpE,KAAK4E,MAAQ,EACb5E,KAAKopE,UAAY,EACjBppE,KAAKqpE,UAAW,EAChBrpE,KAAK2pE,qBAAkB,EACvB3pE,KAAKupE,SAAS9lE,OAAS,EACvBzD,KAAKwpE,cAAgB9F,GACrB1jE,KAAKypE,eAAiB7F,EACxB,CAOA,MAAAkG,CAAOllE,GACL,IAAI88D,EAAO,EACPC,EAAS/8D,EAAQ,EACrB,IAAK,IAAImP,EAAI/T,KAAKupE,SAAS9lE,OAAS,EAAGsQ,GAAK,EAAGA,IAAK,CAClD,MAAMg2D,EAAe/pE,KAAKupE,SAASx1D,GACnC,GAAInP,EAAQmlE,EAAc,CACxBrI,EAAO3tD,EAAI,EACX4tD,EAAS/8D,EAAQmlE,EACjB,KACF,CACF,CACA,MAAO,CACLpI,SACAD,OACAE,OAAQh9D,EAEZ,CACA,IAAAolE,GACE,OAAOhqE,KAAKwuB,OAAO/a,WAAWzT,KAAK4E,MAAQ,EAC7C,CACA,SAAAqlE,CAAU10D,GACE,KAANA,GACEvV,KAAK4E,MAAQ5E,KAAKkpE,cACpBlpE,KAAKipE,IAAIiB,OAAOlqE,KAAKkpE,aAAclpE,KAAK4E,OAE1C5E,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,OACf5E,KAAK8oE,QAAUvzD,IAAMvV,KAAKwpE,cAAc,KAClDxpE,KAAKk2B,MAAQ,EACbl2B,KAAK0pE,eAAiB,EACtB1pE,KAAKmqE,uBAAuB50D,GAEhC,CACA,sBAAA40D,CAAuB50D,GACrB,GAAIA,IAAMvV,KAAKwpE,cAAcxpE,KAAK0pE,gBAChC,GAAI1pE,KAAK0pE,iBAAmB1pE,KAAKwpE,cAAc/lE,OAAS,EAAG,CACzD,MAAM+pB,EAAQxtB,KAAK4E,MAAQ,EAAI5E,KAAKwpE,cAAc/lE,OAC9C+pB,EAAQxtB,KAAKkpE,cACflpE,KAAKipE,IAAIiB,OAAOlqE,KAAKkpE,aAAc17C,GAErCxtB,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAe17C,CACtB,MACExtB,KAAK0pE,sBAEE1pE,KAAKqpE,UACdrpE,KAAKk2B,MAAQ,GACbl2B,KAAKoqE,cAAc70D,KAEnBvV,KAAKk2B,MAAQ,EACbl2B,KAAKiqE,UAAU10D,GAEnB,CACA,kBAAA80D,CAAmB90D,GACbA,IAAMvV,KAAKypE,eAAe,KAC5BzpE,KAAKk2B,MAAQ,EACbl2B,KAAK0pE,eAAiB,EACtB1pE,KAAKsqE,wBAAwB/0D,GAEjC,CACA,uBAAA+0D,CAAwB/0D,GAClBA,IAAMvV,KAAKypE,eAAezpE,KAAK0pE,gBAC7B1pE,KAAK0pE,iBAAmB1pE,KAAKypE,eAAehmE,OAAS,GACvDzD,KAAKipE,IAAIsB,gBAAgBvqE,KAAKkpE,aAAclpE,KAAK4E,MAAQ,GACrD5E,KAAKqpE,SACPrpE,KAAKk2B,MAAQ,GAEbl2B,KAAKk2B,MAAQ,EAEfl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GAEjC5E,KAAK0pE,kBAGP1pE,KAAKk2B,MAAQ,EACbl2B,KAAKqqE,mBAAmB90D,GAE5B,CACA,yBAAAi1D,CAA0Bj1D,GACxB,MAAMk1D,EAAQzqE,KAAK4pE,gBAAkB5pE,KAAK2pE,gBAAgBlmE,OAQ1D,GAPgBgnE,EAEd1G,GAAkBxuD,IAGb,GAAJA,KAAYvV,KAAK2pE,gBAAgB3pE,KAAK4pE,gBAIlC,IAAKa,EAEV,YADAzqE,KAAK4pE,qBAFL5pE,KAAKqpE,UAAW,EAKlBrpE,KAAK4pE,cAAgB,EACrB5pE,KAAKk2B,MAAQ,EACbl2B,KAAK0qE,eAAen1D,EACtB,CAEA,aAAA60D,CAAc70D,GACZ,GAAIvV,KAAK4pE,gBAAkB5pE,KAAK2pE,gBAAgBlmE,OAAQ,CACtD,GAAU,KAAN8R,GAAYuuD,GAAavuD,GAAI,CAC/B,MAAMo1D,EAAY3qE,KAAK4E,MAAQ5E,KAAK2pE,gBAAgBlmE,OACpD,GAAIzD,KAAKkpE,aAAeyB,EAAW,CACjC,MAAMC,EAAc5qE,KAAK4E,MACzB5E,KAAK4E,MAAQ+lE,EACb3qE,KAAKipE,IAAIiB,OAAOlqE,KAAKkpE,aAAcyB,GACnC3qE,KAAK4E,MAAQgmE,CACf,CAIA,OAHA5qE,KAAKkpE,aAAeyB,EAAY,EAChC3qE,KAAK6qE,sBAAsBt1D,QAC3BvV,KAAKqpE,UAAW,EAElB,CACArpE,KAAK4pE,cAAgB,CACvB,EACS,GAAJr0D,KAAYvV,KAAK2pE,gBAAgB3pE,KAAK4pE,eACzC5pE,KAAK4pE,eAAiB,EACU,IAAvB5pE,KAAK4pE,cACV5pE,KAAK2pE,kBAAoB1F,GAAUM,UAAYvkE,KAAK2pE,kBAAoB1F,GAAUO,cAAgBxkE,KAAK6pE,UACpG7pE,KAAK8oE,QAAUvzD,IAAMvV,KAAKwpE,cAAc,KAC3CxpE,KAAKk2B,MAAQ,EACbl2B,KAAK0pE,eAAiB,EACtB1pE,KAAKmqE,uBAAuB50D,IAErBvV,KAAK8qE,cAAc,MAC5B9qE,KAAK4pE,cAAgB,GAGvB5pE,KAAK4pE,cAAgB7yD,OAAa,KAANxB,EAEhC,CACA,kBAAAw1D,CAAmBx1D,GACbA,IAAM0uD,GAAUC,MAAMlkE,KAAK4pE,iBACvB5pE,KAAK4pE,gBAAkB3F,GAAUC,MAAMzgE,SAC3CzD,KAAKk2B,MAAQ,GACbl2B,KAAK2pE,gBAAkB1F,GAAUE,SACjCnkE,KAAK4pE,cAAgB,EACrB5pE,KAAKkpE,aAAelpE,KAAK4E,MAAQ,IAGnC5E,KAAK4pE,cAAgB,EACrB5pE,KAAKk2B,MAAQ,GACbl2B,KAAKgrE,mBAAmBz1D,GAE5B,CAOA,aAAAu1D,CAAcv1D,GACZ,OAASvV,KAAK4E,MAAQ5E,KAAKwuB,OAAO/qB,QAAQ,CACxC,MAAMwnE,EAAKjrE,KAAKwuB,OAAO/a,WAAWzT,KAAK4E,OAIvC,GAHW,KAAPqmE,GACFjrE,KAAKupE,SAAS5uD,KAAK3a,KAAK4E,OAEtBqmE,IAAO11D,EACT,OAAO,CAEX,CAEA,OADAvV,KAAK4E,MAAQ5E,KAAKwuB,OAAO/qB,OAAS,GAC3B,CACT,CASA,kBAAAynE,CAAmB31D,GACbA,IAAMvV,KAAK2pE,gBAAgB3pE,KAAK4pE,iBAC5B5pE,KAAK4pE,gBAAkB5pE,KAAK2pE,gBAAgBlmE,SAC5CzD,KAAK2pE,kBAAoB1F,GAAUE,SACrCnkE,KAAKipE,IAAIkC,QAAQnrE,KAAKkpE,aAAclpE,KAAK4E,MAAQ,GAEjD5E,KAAKipE,IAAImC,UAAUprE,KAAKkpE,aAAclpE,KAAK4E,MAAQ,GAErD5E,KAAK4pE,cAAgB,EACrB5pE,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EACjC5E,KAAKk2B,MAAQ,GAEiB,IAAvBl2B,KAAK4pE,cACV5pE,KAAK8qE,cAAc9qE,KAAK2pE,gBAAgB,MAC1C3pE,KAAK4pE,cAAgB,GAEdr0D,IAAMvV,KAAK2pE,gBAAgB3pE,KAAK4pE,cAAgB,KACzD5pE,KAAK4pE,cAAgB,EAEzB,CACA,YAAAyB,CAAaC,EAAU1J,GACrB5hE,KAAKurE,YAAYD,EAAU1J,GAC3B5hE,KAAKk2B,MAAQ,EACf,CACA,WAAAq1C,CAAYD,EAAU1J,GACpB5hE,KAAKqpE,UAAW,EAChBrpE,KAAK2pE,gBAAkB2B,EACvBtrE,KAAK4pE,cAAgBhI,CACvB,CACA,kBAAA4J,CAAmBj2D,GACP,KAANA,GACFvV,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GAClB,KAAN2Q,GACTvV,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GACxBi/D,GAAetuD,IACxBvV,KAAKkpE,aAAelpE,KAAK4E,MACP,IAAd5E,KAAK42B,KACP52B,KAAKk2B,MAAQ,EACJl2B,KAAK6pE,UACd7pE,KAAKk2B,MAAQ,GACHl2B,KAAKspE,MAOftpE,KAAKk2B,MAAQ,EALXl2B,KAAKk2B,MADG,MAAN3gB,EACW,GAEM,MAANA,EAAY,GAAK,GAKnB,KAANA,EACTvV,KAAKk2B,MAAQ,GAEbl2B,KAAKk2B,MAAQ,EACbl2B,KAAKiqE,UAAU10D,GAEnB,CACA,cAAAm1D,CAAen1D,GACTwuD,GAAkBxuD,IACpBvV,KAAKyrE,cAAcl2D,EAEvB,CACA,qBAAAm2D,CAAsBn2D,GACpB,GAAIwuD,GAAkBxuD,GAAI,CACxB,MAAM62C,EAAMpsD,KAAKwuB,OAAO1Z,MAAM9U,KAAKkpE,aAAclpE,KAAK4E,OAC1C,aAARwnD,GACFpsD,KAAKurE,YAAYvH,GAAY,KAAO5X,GAAM,GAE5CpsD,KAAKyrE,cAAcl2D,EACrB,CACF,CACA,aAAAk2D,CAAcl2D,GACZvV,KAAKipE,IAAI0C,cAAc3rE,KAAKkpE,aAAclpE,KAAK4E,OAC/C5E,KAAKkpE,cAAgB,EACrBlpE,KAAKk2B,MAAQ,GACbl2B,KAAK4rE,oBAAoBr2D,EAC3B,CACA,yBAAAs2D,CAA0Bt2D,GACpBuuD,GAAavuD,KAAqB,KAANA,GAI9BvV,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,IAEjC5E,KAAKk2B,MAAQ2tC,GAAetuD,GAAK,EAAI,GACrCvV,KAAKkpE,aAAelpE,KAAK4E,OAE7B,CACA,qBAAAimE,CAAsBt1D,IACV,KAANA,GAAYuuD,GAAavuD,MAC3BvV,KAAKipE,IAAI6C,WAAW9rE,KAAKkpE,aAAclpE,KAAK4E,OAC5C5E,KAAKkpE,cAAgB,EACrBlpE,KAAKk2B,MAAQ,GACbl2B,KAAK+rE,yBAAyBx2D,GAElC,CACA,wBAAAw2D,CAAyBx2D,GACb,KAANA,IACFvV,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EAErC,CACA,mBAAAgnE,CAAoBr2D,GACR,KAANA,GACFvV,KAAKipE,IAAI+C,aAAahsE,KAAK4E,OACvB5E,KAAKqpE,SACPrpE,KAAKk2B,MAAQ,GAEbl2B,KAAKk2B,MAAQ,EAEfl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GAClB,KAAN2Q,EACTvV,KAAKk2B,MAAQ,EAIE,KAAN3gB,GAA4B,KAAhBvV,KAAKgqE,QAC1BhqE,KAAKipE,IAAI+C,aAAahsE,KAAK4E,OAC3B5E,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,OACfk/D,GAAavuD,IAOvBvV,KAAKisE,gBAAgB12D,EAEzB,CACA,eAAA02D,CAAgB12D,GACJ,MAANA,GAA6B,KAAhBvV,KAAKgqE,QACpBhqE,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,OACV,KAAN2Q,GAAkB,KAANA,GAAkB,KAANA,GAAkB,KAANA,GAC7CvV,KAAKipE,IAAIiD,UAAUlsE,KAAK4E,MAAO5E,KAAK4E,MAAQ,GAC5C5E,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,IAEjC5E,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAE7B,CACA,qBAAAunE,CAAsB52D,GACV,KAANA,GACFvV,KAAKipE,IAAImD,iBAAiBpsE,KAAK4E,OAC/B5E,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EACjC5E,KAAKqpE,UAAW,GACNvF,GAAavuD,KACvBvV,KAAKk2B,MAAQ,GACbl2B,KAAK4rE,oBAAoBr2D,GAE7B,CACA,eAAA82D,CAAgB92D,IACJ,KAANA,GAAYwuD,GAAkBxuD,MAChCvV,KAAKipE,IAAIqD,aAAatsE,KAAKkpE,aAAclpE,KAAK4E,OAC9C5E,KAAKusE,kBAAkBh3D,GAO3B,CACA,cAAAi3D,CAAej3D,GACH,KAANA,GAAYwuD,GAAkBxuD,IAChCvV,KAAKipE,IAAIiD,UAAUlsE,KAAKkpE,aAAclpE,KAAK4E,OAC3C5E,KAAKusE,kBAAkBh3D,IACR,KAANA,GACTvV,KAAKipE,IAAIiD,UAAUlsE,KAAKkpE,aAAclpE,KAAK4E,OAC3C5E,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GAClB,KAAN2Q,IACTvV,KAAKipE,IAAIiD,UAAUlsE,KAAKkpE,aAAclpE,KAAK4E,OAC3C5E,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EAErC,CACA,aAAA6nE,CAAcl3D,GACF,KAANA,GAAYwuD,GAAkBxuD,IAChCvV,KAAKipE,IAAIyD,SAAS1sE,KAAKkpE,aAAclpE,KAAK4E,OAC1C5E,KAAKusE,kBAAkBh3D,IACR,KAANA,EACTvV,KAAKk2B,MAAQ,GACE,KAAN3gB,IACTvV,KAAKipE,IAAIyD,SAAS1sE,KAAKkpE,aAAclpE,KAAK4E,OAC1C5E,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EAErC,CACA,oBAAA+nE,CAAqBp3D,GACT,KAANA,EACFvV,KAAKk2B,MAAQ,IACE,KAAN3gB,GAAYwuD,GAAkBxuD,MACvCvV,KAAKipE,IAAIyD,SAAS1sE,KAAKkpE,aAAclpE,KAAK4E,MAAQ,GAClD5E,KAAKusE,kBAAkBh3D,GAQ3B,CACA,kBAAAq3D,CAAmBr3D,GACP,KAANA,GAAYwuD,GAAkBxuD,IAChCvV,KAAKipE,IAAI4D,cAAc7sE,KAAKkpE,aAAclpE,KAAK4E,OAC/C5E,KAAKusE,kBAAkBh3D,IACR,KAANA,IACTvV,KAAKipE,IAAI4D,cAAc7sE,KAAKkpE,aAAclpE,KAAK4E,OAC/C5E,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EAErC,CACA,iBAAA2nE,CAAkBh3D,GAChBvV,KAAKkpE,aAAelpE,KAAK4E,MACzB5E,KAAKk2B,MAAQ,GACbl2B,KAAKipE,IAAI6D,gBAAgB9sE,KAAK4E,OAC9B5E,KAAK+sE,mBAAmBx3D,EAC1B,CACA,kBAAAw3D,CAAmBx3D,GACP,KAANA,EACFvV,KAAKk2B,MAAQ,GACE,KAAN3gB,GAAkB,KAANA,GACrBvV,KAAKipE,IAAI+D,YAAY,EAAGhtE,KAAKkpE,cAC7BlpE,KAAKkpE,cAAgB,EACrBlpE,KAAKk2B,MAAQ,GACbl2B,KAAK4rE,oBAAoBr2D,IACfuuD,GAAavuD,KACvBvV,KAAKipE,IAAI+D,YAAY,EAAGhtE,KAAKkpE,cAC7BlpE,KAAKisE,gBAAgB12D,GAEzB,CACA,oBAAA03D,CAAqB13D,GACT,KAANA,GACFvV,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GAClB,KAAN2Q,GACTvV,KAAKk2B,MAAQ,GACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GACvBk/D,GAAavuD,KACvBvV,KAAKkpE,aAAelpE,KAAK4E,MACzB5E,KAAKk2B,MAAQ,GACbl2B,KAAKktE,yBAAyB33D,GAElC,CACA,iBAAA43D,CAAkB53D,EAAG63D,IACf73D,IAAM63D,GAASptE,KAAK8qE,cAAcsC,MACpCptE,KAAKipE,IAAIoE,aAAartE,KAAKkpE,aAAclpE,KAAK4E,OAC9C5E,KAAKkpE,cAAgB,EACrBlpE,KAAKipE,IAAI+D,YACG,KAAVI,EAAe,EAAI,EACnBptE,KAAK4E,MAAQ,GAEf5E,KAAKk2B,MAAQ,GAEjB,CACA,4BAAAo3C,CAA6B/3D,GAC3BvV,KAAKmtE,kBAAkB53D,EAAG,GAC5B,CACA,4BAAAg4D,CAA6Bh4D,GAC3BvV,KAAKmtE,kBAAkB53D,EAAG,GAC5B,CACA,wBAAA23D,CAAyB33D,GACnBuuD,GAAavuD,IAAY,KAANA,GACrBvV,KAAKipE,IAAIoE,aAAartE,KAAKkpE,aAAclpE,KAAK4E,OAC9C5E,KAAKkpE,cAAgB,EACrBlpE,KAAKipE,IAAI+D,YAAY,EAAGhtE,KAAK4E,OAC7B5E,KAAKk2B,MAAQ,GACbl2B,KAAK4rE,oBAAoBr2D,IAC0D,KAANA,GAAkB,KAANA,GAAkB,KAANA,GAAkB,KAANA,GACjHvV,KAAKipE,IAAIuE,MACP,GACAxtE,KAAK4E,MAGX,CACA,sBAAA6oE,CAAuBl4D,GACX,KAANA,GACFvV,KAAKk2B,MAAQ,GACbl2B,KAAK4pE,cAAgB,GAErB5pE,KAAKk2B,MAAc,KAAN3gB,EAAW,GAAK,EAEjC,CACA,kBAAAy1D,CAAmBz1D,IACP,KAANA,GAAYvV,KAAK8qE,cAAc,OACjC9qE,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EAErC,CACA,4BAAA8oE,CAA6Bn4D,IACjB,KAANA,GAAYvV,KAAK8qE,cAAc,OACjC9qE,KAAKipE,IAAI0E,wBAAwB3tE,KAAKkpE,aAAclpE,KAAK4E,OACzD5E,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EAErC,CACA,kBAAAgpE,CAAmBr4D,GACP,KAANA,GACFvV,KAAKk2B,MAAQ,GACbl2B,KAAK2pE,gBAAkB1F,GAAUG,WACjCpkE,KAAK4pE,cAAgB,EACrB5pE,KAAKkpE,aAAelpE,KAAK4E,MAAQ,GAEjC5E,KAAKk2B,MAAQ,EAEjB,CACA,qBAAA23C,CAAsBt4D,IACV,KAANA,GAAYvV,KAAK8qE,cAAc,OACjC9qE,KAAKipE,IAAImC,UAAUprE,KAAKkpE,aAAclpE,KAAK4E,OAC3C5E,KAAKk2B,MAAQ,EACbl2B,KAAKkpE,aAAelpE,KAAK4E,MAAQ,EAErC,CACA,mBAAAkpE,CAAoBv4D,GACdA,IAAM0uD,GAAUI,UAAU,GAC5BrkE,KAAKqrE,aAAapH,GAAUI,UAAW,GAC9B9uD,IAAM0uD,GAAUK,SAAS,GAClCtkE,KAAKqrE,aAAapH,GAAUK,SAAU,IAEtCtkE,KAAKk2B,MAAQ,EACbl2B,KAAK0qE,eAAen1D,GAExB,CACA,mBAAAw4D,CAAoBx4D,GACdA,IAAM0uD,GAAUM,SAAS,GAC3BvkE,KAAKqrE,aAAapH,GAAUM,SAAU,GAC7BhvD,IAAM0uD,GAAUO,YAAY,GACrCxkE,KAAKqrE,aAAapH,GAAUO,YAAa,IAEzCxkE,KAAKk2B,MAAQ,EACbl2B,KAAK0qE,eAAen1D,GAExB,CACA,WAAAy4D,GACA,CACA,aAAAC,GACA,CAMA,KAAAC,CAAMC,GAEJ,IADAnuE,KAAKwuB,OAAS2/C,EACPnuE,KAAK4E,MAAQ5E,KAAKwuB,OAAO/qB,QAAQ,CACtC,MAAM8R,EAAIvV,KAAKwuB,OAAO/a,WAAWzT,KAAK4E,OAItC,OAHU,KAAN2Q,GAA2B,KAAfvV,KAAKk2B,OACnBl2B,KAAKupE,SAAS5uD,KAAK3a,KAAK4E,OAElB5E,KAAKk2B,OACX,KAAK,EACHl2B,KAAKiqE,UAAU10D,GACf,MAEF,KAAK,EACHvV,KAAKmqE,uBAAuB50D,GAC5B,MAEF,KAAK,EACHvV,KAAKqqE,mBAAmB90D,GACxB,MAEF,KAAK,EACHvV,KAAKsqE,wBAAwB/0D,GAC7B,MAEF,KAAK,GACHvV,KAAKwqE,0BAA0Bj1D,GAC/B,MAEF,KAAK,GACHvV,KAAKoqE,cAAc70D,GACnB,MAEF,KAAK,GACHvV,KAAK+qE,mBAAmBx1D,GACxB,MAEF,KAAK,GACHvV,KAAKstE,6BAA6B/3D,GAClC,MAEF,KAAK,GACHvV,KAAKqsE,gBAAgB92D,GACrB,MAEF,KAAK,GACHvV,KAAKwsE,eAAej3D,GACpB,MAEF,KAAK,GACHvV,KAAKysE,cAAcl3D,GACnB,MAEF,KAAK,GACHvV,KAAK2sE,qBAAqBp3D,GAC1B,MAEF,KAAK,GACHvV,KAAK4sE,mBAAmBr3D,GACxB,MAEF,KAAK,GACHvV,KAAKkrE,mBAAmB31D,GACxB,MAEF,KAAK,GACHvV,KAAK6tE,sBAAsBt4D,GAC3B,MAEF,KAAK,GACHvV,KAAK4rE,oBAAoBr2D,GACzB,MAEF,KAAK,EACHvV,KAAK0qE,eAAen1D,GACpB,MAEF,KAAK,GACHvV,KAAK0rE,sBAAsBn2D,GAC3B,MAEF,KAAK,EACHvV,KAAK6qE,sBAAsBt1D,GAC3B,MAEF,KAAK,EACHvV,KAAKwrE,mBAAmBj2D,GACxB,MAEF,KAAK,GACHvV,KAAK+sE,mBAAmBx3D,GACxB,MAEF,KAAK,GACHvV,KAAKutE,6BAA6Bh4D,GAClC,MAEF,KAAK,GACHvV,KAAKitE,qBAAqB13D,GAC1B,MAEF,KAAK,EACHvV,KAAK6rE,0BAA0Bt2D,GAC/B,MAEF,KAAK,GACHvV,KAAK+rE,yBAAyBx2D,GAC9B,MAEF,KAAK,GACHvV,KAAK8tE,oBAAoBv4D,GACzB,MAEF,KAAK,GACHvV,KAAK+tE,oBAAoBx4D,GACzB,MAEF,KAAK,GACHvV,KAAKktE,yBAAyB33D,GAC9B,MAEF,KAAK,EACHvV,KAAKmsE,sBAAsB52D,GAC3B,MAEF,KAAK,GACHvV,KAAKgrE,mBAAmBz1D,GACxB,MAEF,KAAK,GACHvV,KAAKytE,uBAAuBl4D,GAC5B,MAEF,KAAK,GACHvV,KAAK4tE,mBAAmBr4D,GACxB,MAEF,KAAK,GACHvV,KAAK0tE,6BAA6Bn4D,GAClC,MAEF,KAAK,GACHvV,KAAKiuE,gBAITjuE,KAAK4E,OACP,CACA5E,KAAKoc,UACLpc,KAAKouE,QACP,CAIA,OAAAhyD,GACMpc,KAAKkpE,eAAiBlpE,KAAK4E,QACV,IAAf5E,KAAKk2B,OAA8B,KAAfl2B,KAAKk2B,OAAuC,IAAvBl2B,KAAK4pE,eAChD5pE,KAAKipE,IAAIiB,OAAOlqE,KAAKkpE,aAAclpE,KAAK4E,OACxC5E,KAAKkpE,aAAelpE,KAAK4E,OACD,KAAf5E,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,QACxDl2B,KAAKipE,IAAIoE,aAAartE,KAAKkpE,aAAclpE,KAAK4E,OAC9C5E,KAAKkpE,aAAelpE,KAAK4E,OAG/B,CACA,MAAAwpE,GACEpuE,KAAKquE,qBACLruE,KAAKipE,IAAIqF,OACX,CAEA,kBAAAD,GACE,MAAME,EAAWvuE,KAAKwuB,OAAO/qB,OACzBzD,KAAKkpE,cAAgBqF,IAGN,KAAfvuE,KAAKk2B,MACHl2B,KAAK2pE,kBAAoB1F,GAAUE,SACrCnkE,KAAKipE,IAAIkC,QAAQnrE,KAAKkpE,aAAcqF,GAEpCvuE,KAAKipE,IAAImC,UAAUprE,KAAKkpE,aAAcqF,GAEhB,IAAfvuE,KAAKk2B,OAA8B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,KAAfl2B,KAAKk2B,OAA+B,IAAfl2B,KAAKk2B,OACzQl2B,KAAKipE,IAAIiB,OAAOlqE,KAAKkpE,aAAcqF,GAEvC,CACA,aAAAC,CAAcC,EAAIC,GAClB,GA0uB8B,GAAO,CACrClB,MAAOmB,GACP,MAAAzE,CAAO18C,EAAOC,GACZmhD,GAAOC,GAASrhD,EAAOC,GAAMD,EAAOC,EACtC,EACA,YAAAqhD,CAAa3I,EAAM34C,EAAOC,GACxBmhD,GAAOzI,EAAM34C,EAAOC,EACtB,EACA,eAAA88C,CAAgB/8C,EAAOC,GACrB,GAAIq7C,GACF,OAAO8F,GAAOC,GAASrhD,EAAOC,GAAMD,EAAOC,GAE7C,IAAIshD,EAAavhD,EAAQw7C,GAAUQ,cAAc/lE,OAC7CurE,EAAWvhD,EAAMu7C,GAAUS,eAAehmE,OAC9C,KAAOqgE,GAAayE,GAAa90D,WAAWs7D,KAC1CA,IAEF,KAAOjL,GAAayE,GAAa90D,WAAWu7D,EAAW,KACrDA,IAEF,IAAInJ,EAAMgJ,GAASE,EAAYC,GAC3BnJ,EAAI/jD,SAAS,OAEb+jD,EAAMwC,GAAe4G,eAAepJ,GAAK,IAG7CqJ,GAAQ,CACN/wE,KAAM,EACN+L,QAASilE,GAAUtJ,GAAK,EAAOuJ,GAAOL,EAAYC,IAClDhN,IAAKoN,GAAO5hD,EAAOC,IAEvB,EACA,aAAAk+C,CAAcn+C,EAAOC,GACnB,MAAMzvB,EAAO6wE,GAASrhD,EAAOC,GAC7B+6C,GAAiB,CACfrqE,KAAM,EACNiuD,IAAKpuD,EACL8pE,GAAIO,GAAeN,aAAa/pE,EAAM,GAAM,GAAIqqE,GAAeP,IAC/DjB,QAAS,EAET5oE,MAAO,GACP60B,SAAU,GACVkvC,IAAKoN,GAAO5hD,EAAQ,EAAGC,GACvB4hD,iBAAa,EAEjB,EACA,YAAArD,CAAav+C,GACX6hD,GAAW7hD,EACb,EACA,UAAAq+C,CAAWt+C,EAAOC,GAChB,MAAMzvB,EAAO6wE,GAASrhD,EAAOC,GAC7B,IAAK46C,GAAelwD,UAAUna,GAAO,CACnC,IAAI+7D,GAAQ,EACZ,IAAK,IAAIhmD,EAAI,EAAGA,EAAI,GAAMtQ,OAAQsQ,IAEhC,GADU,GAAMA,GACVq4C,IAAIz2C,gBAAkB3X,EAAK2X,cAAe,CAC9CokD,GAAQ,EACJhmD,EAAI,GACN46D,GAAU,GAAI,GAAM,GAAG3M,IAAIx0C,MAAMo0C,QAEnC,IAAK,IAAIx3B,EAAI,EAAGA,GAAKr2B,EAAGq2B,IAEtBmlC,GADW,GAAMltD,QACFoL,EAAK2c,EAAIr2B,GAE1B,KACF,CAEGgmD,GACH4U,GAAU,GAAIa,GAAUhiD,EAAO,IAEnC,CACF,EACA,gBAAA4+C,CAAiB3+C,GACf,MAAMzvB,EAAOwqE,GAAepc,IAC5Boc,GAAeiH,eAAgB,EAC/BH,GAAW7hD,GACP,GAAM,IAAM,GAAM,GAAG2+B,MAAQpuD,GAC/BuxE,GAAW,GAAMltD,QAASoL,EAE9B,EACA,YAAA6+C,CAAa9+C,EAAOC,GAClBg7C,GAAc,CACZtqE,KAAM,EACNH,KAAM6wE,GAASrhD,EAAOC,GACtBiiD,QAASN,GAAO5hD,EAAOC,GACvBjgB,WAAO,EACPw0D,IAAKoN,GAAO5hD,GAEhB,EACA,SAAA0+C,CAAU1+C,EAAOC,GACf,MAAM5M,EAAMguD,GAASrhD,EAAOC,GACtBzvB,EAAe,MAAR6iB,GAAuB,MAARA,EAAc,OAAiB,MAARA,EAAc,KAAe,MAARA,EAAc,OAASA,EAAI/L,MAAM,GAIzG,GAHKg0D,IAAmB,KAAT9qE,GACb2wE,GAAU,GAAInhD,GAEZs7C,IAAmB,KAAT9qE,EACZyqE,GAAc,CACZtqE,KAAM,EACNH,KAAM6iB,EACN6uD,QAASN,GAAO5hD,EAAOC,GACvBjgB,WAAO,EACPw0D,IAAKoN,GAAO5hD,SAYd,GATAi7C,GAAc,CACZtqE,KAAM,EACNH,OACAk0D,QAASrxC,EACTglD,SAAK,EACL1vD,SAAK,EACL8Z,UAAmB,MAARpP,EAAc,CAAC6hD,GAAuB,SAAW,GAC5DV,IAAKoN,GAAO5hD,IAED,QAATxvB,EAAgB,CAClB8qE,GAASE,GAAUF,QAAS,EAC5BC,GAAsBP,GACtB,MAAMvqE,EAAQuqE,GAAevqE,MAC7B,IAAK,IAAI8V,EAAI,EAAGA,EAAI9V,EAAMwF,OAAQsQ,IACV,IAAlB9V,EAAM8V,GAAG5V,OACXF,EAAM8V,GAAK47D,GAAU1xE,EAAM8V,IAGjC,CAEJ,EACA,QAAA24D,CAASl/C,EAAOC,GACd,GAAID,IAAUC,EAAK,OACnB,MAAMtX,EAAM04D,GAASrhD,EAAOC,GAC5B,GAAIq7C,KAAWnC,GAAO8B,IACpBA,GAAYzqE,MAAQmY,EACpBy5D,GAAUnH,GAAYiH,QAASjiD,OAC1B,CACL,MAAMk1C,EAAsB,MAAXxsD,EAAI,GACrBsyD,GAAYtyD,IAAMg5D,GAChBxM,EAAWxsD,EAAMA,EAAIrB,MAAM,GAAI,GAC/B6tD,EACAyM,GAAO5hD,EAAOC,GACdk1C,EAAW,EAAI,EAEnB,CACF,EACA,aAAAkK,CAAcr/C,EAAOC,GACnB,MAAMoiD,EAAMhB,GAASrhD,EAAOC,GAC5B,GAAIq7C,KAAWnC,GAAO8B,IACpBA,GAAYzqE,MAAQ,IAAM6xE,EAC1BD,GAAUnH,GAAYiH,QAASjiD,QAC1B,GAAyB,SAArBg7C,GAAYzqE,KAAiB,CACtC,MAAMmY,EAAMsyD,GAAYtyD,IACpBA,IACFA,EAAIjM,SAAW,IAAM2lE,EACrBD,GAAUz5D,EAAI6rD,IAAKv0C,GAEvB,KAAO,CACL,MAAMo4C,EAAMnD,GAAuBmN,GAAK,EAAMT,GAAO5hD,EAAOC,IAC5Dg7C,GAAYx4C,UAAUtV,KAAKkrD,EAC7B,CACF,EACA,YAAAwH,CAAa7/C,EAAOC,GAClBi7C,IAAoBmG,GAASrhD,EAAOC,GAChCk7C,GAAwB,IAAGA,GAAwBn7C,GACvDo7C,GAAsBn7C,CACxB,EACA,cAAAqiD,CAAe3J,EAAM34C,EAAOC,GAC1Bi7C,IAAoBvC,EAChBwC,GAAwB,IAAGA,GAAwBn7C,GACvDo7C,GAAsBn7C,CACxB,EACA,eAAAq/C,CAAgBr/C,GACd,MAAMD,EAAQi7C,GAAYzG,IAAIx0C,MAAMo0C,OAC9B5jE,EAAO6wE,GAASrhD,EAAOC,GACJ,IAArBg7C,GAAYtqE,OACdsqE,GAAYvW,QAAUl0D,GAEpBwqE,GAAevqE,MAAMqkB,KACtB4K,IAAkB,IAAXA,EAAE/uB,KAAa+uB,EAAEglC,QAAUhlC,EAAElvB,QAAUA,IAE/C2wE,GAAU,EAAGnhD,EAEjB,EACA,WAAAw/C,CAAYI,EAAO3/C,GACjB,GAAI+6C,IAAkBC,GAAa,CAEjC,GADAmH,GAAUnH,GAAYzG,IAAKv0C,GACb,IAAV2/C,EAOF,GANI1E,GAAiB5mD,SAAS,OAC5B4mD,GAAmBL,GAAe4G,eAChCvG,IACA,IAGqB,IAArBD,GAAYtqE,KACW,UAArBsqE,GAAYzqE,OACd0qE,GAAmBqH,GAASrH,IAAkB1wD,QAElC,IAAVo1D,GAAgB1E,IAClBiG,GAAU,GAAIlhD,GAEhBg7C,GAAYj7D,MAAQ,CAClBrP,KAAM,EACN+L,QAASw+D,GACT1G,IAAe,IAAVoL,EAAcgC,GAAOzG,GAAuBC,IAAuBwG,GAAOzG,GAAwB,EAAGC,GAAsB,IAE9HI,GAAUa,WAAoC,aAAvBrB,GAAepc,KAA2C,SAArBqc,GAAYzqE,MAAmB0qE,IAAyC,SAArBA,IACjHM,GAAUuC,YAAYvH,GAAY,cAAe,OAE9C,CACL,IAAIgM,EAAe,EACnBvH,GAAY5C,IAAMsJ,GAChBzG,IACA,EACA0G,GAAOzG,GAAuBC,IAC9B,EACAoH,GAEuB,QAArBvH,GAAYzqE,OACdyqE,GAAYwH,eAiGxB,SAA4B9B,GAC1B,MAAMnM,EAAMmM,EAAMnM,IACZ6D,EAAMsI,EAAMjkE,QACZgmE,EAAUrK,EAAIvlC,MAAMqnC,IAC1B,IAAKuI,EAAS,OACd,MAAO,CAAEC,EAAKC,GAAOF,EACfG,EAAwB,CAACnmE,EAAS03D,EAAQ0O,GAAU,KACxD,MAAM9iD,EAAQw0C,EAAIx0C,MAAMo0C,OAASA,EAEjC,OAAOuN,GACLjlE,GACA,EACAklE,GAAO5hD,EAJGA,EAAQtjB,EAAQzG,QAK1B,EACA6sE,EAAU,EAAiB,IAGzBttD,EAAS,CACb2F,OAAQ0nD,EAAsBD,EAAIp4D,OAAQ6tD,EAAIzkE,QAAQgvE,EAAKD,EAAI1sE,SAC/D+J,WAAO,EACP1I,SAAK,EACLF,WAAO,EACP2rE,WAAW,GAEb,IAAIC,EAAeL,EAAIn4D,OAAOxI,QAAQihE,GAAe,IAAIz4D,OACzD,MAAM04D,EAAgBP,EAAI/uE,QAAQovE,GAC5BG,EAAgBH,EAAalwC,MAAMswC,IACzC,GAAID,EAAe,CACjBH,EAAeA,EAAahhE,QAAQohE,GAAe,IAAI54D,OACvD,MAAM64D,EAAaF,EAAc,GAAG34D,OACpC,IAAI84D,EAKJ,GAJID,IACFC,EAAYjL,EAAIzkE,QAAQyvE,EAAYH,EAAgBF,EAAa/sE,QACjEuf,EAAOle,IAAMurE,EAAsBQ,EAAYC,GAAW,IAExDH,EAAc,GAAI,CACpB,MAAMI,EAAeJ,EAAc,GAAG34D,OAClC+4D,IACF/tD,EAAOpe,MAAQyrE,EACbU,EACAlL,EAAIzkE,QACF2vE,EACA/tD,EAAOle,IAAMgsE,EAAYD,EAAWptE,OAASitE,EAAgBF,EAAa/sE,SAE5E,GAGN,CACF,CAIA,OAHI+sE,IACFxtD,EAAOxV,MAAQ6iE,EAAsBG,EAAcE,GAAe,IAE7D1tD,CACT,CAtJyCguD,CAAmBvI,GAAY5C,MAE9D,IAAIoL,GAAa,EACQ,SAArBxI,GAAYzqE,OAAoBizE,EAAYxI,GAAYx4C,UAAUhX,UACnE42D,GAAwB,SAAhBA,EAAI3lE,WACT,GAAK06D,GACT,uBACAyD,GACAI,GAAYzG,IACZyG,GAAYtyD,IAAI6rD,IAAIr5C,UAEpB8/C,GAAYzqE,KAAO,QACnByqE,GAAYx4C,UAAUprB,OAAOosE,EAAW,GAE5C,CAEuB,IAArBxI,GAAYtqE,MAAmC,QAArBsqE,GAAYzqE,MACxCwqE,GAAevqE,MAAM0c,KAAK8tD,GAE9B,CACAC,GAAmB,GACnBC,GAAwBC,IAAuB,CACjD,EACA,SAAAwC,CAAU59C,EAAOC,GACX46C,GAAeF,UACjB+G,GAAQ,CACN/wE,KAAM,EACN+L,QAAS2kE,GAASrhD,EAAOC,GACzBu0C,IAAKoN,GAAO5hD,EAAQ,EAAGC,EAAM,IAGnC,EACA,KAAA6gD,GACE,MAAM7gD,EAAM86C,GAAa9kE,OAyCzB,IAAK,IAAImB,EAAQ,EAAGA,EAAQ,GAAMnB,OAAQmB,IACxC2qE,GAAW,GAAM3qE,GAAQ6oB,EAAM,GAC/BkhD,GAAU,GAAI,GAAM/pE,GAAOo9D,IAAIx0C,MAAMo0C,OAEzC,EACA,OAAAuJ,CAAQ39C,EAAOC,GACO,IAAhB,GAAM,GAAGq6C,GACX8G,GAAOC,GAASrhD,EAAOC,GAAMD,EAAOC,GAEpCkhD,GAAU,EAAGnhD,EAAQ,EAEzB,EACA,uBAAAmgD,CAAwBngD,GAC+B,KAAhD,GAAM,GAAK,GAAM,GAAGs6C,GAAKO,GAAeP,KAC3C6G,GACE,GACAnhD,EAAQ,EAGd,IAEIojD,GAAgB,iCAChBH,GAAgB,WAuDtB,SAAS5B,GAASrhD,EAAOC,GACvB,OAAO86C,GAAazzD,MAAM0Y,EAAOC,EACnC,CACA,SAAS6hD,GAAW7hD,GACdu7C,GAAUa,YACZrB,GAAe0I,SAAW9B,GAAO3hD,EAAM,EAAGA,EAAM,IAElDyhD,GAAQ1G,IACR,MAAM,IAAEpc,EAAG,GAAE0b,GAAOU,GACT,IAAPV,GAAYO,GAAeL,SAAS5b,IACtCyc,KAEER,GAAelwD,UAAUi0C,GAC3BmjB,GAAW/G,GAAgB/6C,IAE3B,GAAM9K,QAAQ6lD,IACH,IAAPV,GAAmB,IAAPA,IACdkB,GAAUM,OAAQ,IAGtBd,GAAiB,IACnB,CACA,SAASoG,GAAO1kE,EAASsjB,EAAOC,GAC9B,CACE,MAAM2+B,EAAM,GAAM,IAAM,GAAM,GAAGA,IACrB,WAARA,GAA4B,UAARA,GAAmBliD,EAAQ4X,SAAS,OAC1D5X,EAAUm+D,GAAe4G,eAAe/kE,GAAS,GAErD,CACA,MAAMuQ,EAAS,GAAM,IAAM6tD,GACrB6I,EAAW12D,EAAOqY,SAASrY,EAAOqY,SAASrvB,OAAS,GACtD0tE,GAA8B,IAAlBA,EAAShzE,MACvBgzE,EAASjnE,SAAWA,EACpB0lE,GAAUuB,EAASnP,IAAKv0C,IAExBhT,EAAOqY,SAASnY,KAAK,CACnBxc,KAAM,EACN+L,UACA83D,IAAKoN,GAAO5hD,EAAOC,IAGzB,CACA,SAAS8hD,GAAWz7D,EAAI2Z,EAAK2jD,GAAY,GAErCxB,GAAU97D,EAAGkuD,IADXoP,EACgB5B,GAAU/hD,EAAK,IAuGrC,SAAmB7oB,GACjB,IAAImP,EAAInP,EACR,KAvGmC,KAuG5B2jE,GAAa90D,WAAWM,IAAYA,EAAIw0D,GAAa9kE,OAAS,GAAGsQ,IACxE,OAAOA,CACT,CAzGsBs9D,CAAU5jD,GAAW,GAErCu7C,GAAUa,YACR/1D,EAAGgf,SAASrvB,OACdqQ,EAAGo9D,SAASzjD,IAAM,EAAO,CAAC,EAAG3Z,EAAGgf,SAAShf,EAAGgf,SAASrvB,OAAS,GAAGu+D,IAAIv0C,KAErE3Z,EAAGo9D,SAASzjD,IAAM,EAAO,CAAC,EAAG3Z,EAAGo9D,SAAS1jD,OAE3C1Z,EAAGo9D,SAASvoD,OAASkmD,GACnB/6D,EAAGo9D,SAAS1jD,MAAMo0C,OAClB9tD,EAAGo9D,SAASzjD,IAAIm0C,SAGpB,MAAM,IAAExV,EAAG,GAAE0b,EAAE,SAAEh1C,GAAahf,EAa9B,GAZKg1D,KACS,SAAR1c,EACFt4C,EAAG+yD,QAAU,EACJyK,GAAmBx9D,GAC5BA,EAAG+yD,QAAU,EAwGnB,UAAqB,IAAEza,EAAG,MAAEnuD,IAC1B,GAAIoqE,GAAe9oC,gBAAgB6sB,GACjC,OAAO,EAET,GAAY,cAARA,IA4Be72C,EA5BoB62C,EAAI34C,WAAW,IA6B3C,IAAM8B,EAAI,IA7BwC+vD,GAAgBlZ,IAAQic,GAAekJ,oBAAsBlJ,GAAekJ,mBAAmBnlB,IAAQic,GAAe/2B,cAAgB+2B,GAAe/2B,YAAY8a,GAC5N,OAAO,EA2BX,IAAqB72C,EAzBnB,IAAK,IAAIxB,EAAI,EAAGA,EAAI9V,EAAMwF,OAAQsQ,IAAK,CACrC,MAAMmZ,EAAIjvB,EAAM8V,GAChB,GAAe,IAAXmZ,EAAE/uB,MACJ,GAAe,OAAX+uB,EAAElvB,MAAiBkvB,EAAE1f,MAAO,CAC9B,GAAI0f,EAAE1f,MAAMtD,QAAQyJ,WAAW,QAC7B,OAAO,EACF,GAAIixD,GACT,yBACAyD,GACAn7C,EAAE80C,KAEF,OAAO,CAEX,OACK,GACI,SAAX90C,EAAElvB,MAAmByoE,GAAcv5C,EAAE/W,IAAK,OAASyuD,GACjD,yBACAyD,GACAn7C,EAAE80C,KAEF,OAAO,CAEX,CACA,OAAO,CACT,CAtIeD,CAAYjuD,KACrBA,EAAG+yD,QAAU,IAGZmC,GAAUK,WACbv1D,EAAGgf,SAAW0+C,GAAmB1+C,IAExB,IAAPg1C,GAAYO,GAAeJ,mBAAmB7b,GAAM,CACtD,MAAMib,EAAQv0C,EAAS,GACnBu0C,GAAwB,IAAfA,EAAMlpE,OACjBkpE,EAAMn9D,QAAUm9D,EAAMn9D,QAAQsF,QAAQ,SAAU,IAEpD,CACW,IAAPs4D,GAAYO,GAAeL,SAAS5b,IACtCyc,KAEEE,KAAwBj1D,IAC1Bg1D,GAASE,GAAUF,QAAS,EAC5BC,GAAsB,MAEpBC,GAAUM,OAA0D,KAAhD,GAAM,GAAK,GAAM,GAAGxB,GAAKO,GAAeP,MAC9DkB,GAAUM,OAAQ,GAEpB,CACE,MAAMrrE,EAAQ6V,EAAG7V,MA0BjB,IAAK+qE,GAAUa,WAAalF,GAC1B,2BACA0D,KACc,aAAXv0D,EAAGs4C,MAAuBklB,GAAmBx9D,GAAK,CAMrD,MAAM2G,EAAS,GAAM,IAAM6tD,GACrB1jE,EAAQ6V,EAAOqY,SAAS1xB,QAAQ0S,GACtC2G,EAAOqY,SAASjuB,OAAOD,EAAO,KAAMkP,EAAGgf,SACzC,CACA,MAAM2+C,EAAqBxzE,EAAM0jB,KAC9BuL,GAAiB,IAAXA,EAAE/uB,MAAyB,oBAAX+uB,EAAElvB,MAEvByzE,GAAsB7M,GACxB,2BACAyD,GACAoJ,EAAmBzP,MAChBluD,EAAGgf,SAASrvB,SACfguE,EAAmBjkE,MAAQ,CACzBrP,KAAM,EACN+L,QAAS2kE,GACP/6D,EAAGgf,SAAS,GAAGkvC,IAAIx0C,MAAMo0C,OACzB9tD,EAAGgf,SAAShf,EAAGgf,SAASrvB,OAAS,GAAGu+D,IAAIv0C,IAAIm0C,QAE9CI,IAAKyP,EAAmBzP,KAG9B,CACF,CAMA,SAASwN,GAAU5qE,EAAO2Q,GACxB,IAAIxB,EAAInP,EACR,KAAO2jE,GAAa90D,WAAWM,KAAOwB,GAAKxB,GAAK,GAAGA,IACnD,OAAOA,CACT,CACA,MAAM29D,GAAqC,IAAI9tD,IAAI,CAAC,KAAM,OAAQ,UAAW,MAAO,SACpF,SAAS0tD,IAAmB,IAAEllB,EAAG,MAAEnuD,IACjC,GAAY,aAARmuD,EACF,IAAK,IAAIr4C,EAAI,EAAGA,EAAI9V,EAAMwF,OAAQsQ,IAChC,GAAsB,IAAlB9V,EAAM8V,GAAG5V,MAAcuzE,GAAmBp1D,IAAIre,EAAM8V,GAAG/V,MACzD,OAAO,EAIb,OAAO,CACT,CAoCA,MAAM2zE,GAAmB,QACzB,SAASH,GAAmBI,GAC1B,MAAMC,EAA+C,aAA9BxJ,GAAeyJ,WACtC,IAAIC,GAAoB,EACxB,IAAK,IAAIh+D,EAAI,EAAGA,EAAI69D,EAAMnuE,OAAQsQ,IAAK,CACrC,MAAM6gB,EAAOg9C,EAAM79D,GACnB,GAAkB,IAAd6gB,EAAKz2B,KACP,GAAK0qE,GAcHj0C,EAAK1qB,QAAU0qB,EAAK1qB,QAAQsF,QAAQmiE,GAAkB,WAbtD,GAAIK,GAAgBp9C,EAAK1qB,SAAU,CACjC,MAAMmU,EAAOuzD,EAAM79D,EAAI,IAAM69D,EAAM79D,EAAI,GAAG5V,KACpCge,EAAOy1D,EAAM79D,EAAI,IAAM69D,EAAM79D,EAAI,GAAG5V,MACrCkgB,IAASlC,GAAQ01D,IAA4B,IAATxzD,IAAwB,IAATlC,GAAuB,IAATA,IAAwB,IAATkC,IAAwB,IAATlC,GAAuB,IAATA,GAAc81D,GAAer9C,EAAK1qB,YAClJ6nE,GAAoB,EACpBH,EAAM79D,GAAK,MAEX6gB,EAAK1qB,QAAU,GAEnB,MAAW2nE,IACTj9C,EAAK1qB,QAAU6lE,GAASn7C,EAAK1qB,SAMrC,CACA,OAAO6nE,EAAoBH,EAAMlwD,OAAOtjB,SAAWwzE,CACrD,CACA,SAASI,GAAgB9+D,GACvB,IAAK,IAAIa,EAAI,EAAGA,EAAIb,EAAIzP,OAAQsQ,IAC9B,IAAK+vD,GAAa5wD,EAAIO,WAAWM,IAC/B,OAAO,EAGX,OAAO,CACT,CACA,SAASk+D,GAAe/+D,GACtB,IAAK,IAAIa,EAAI,EAAGA,EAAIb,EAAIzP,OAAQsQ,IAAK,CACnC,MAAMwB,EAAIrC,EAAIO,WAAWM,GACzB,GAAU,KAANwB,GAAkB,KAANA,EACd,OAAO,CAEX,CACA,OAAO,CACT,CACA,SAASw6D,GAAS78D,GAChB,IAAI4E,EAAM,GACNo6D,GAAuB,EAC3B,IAAK,IAAIn+D,EAAI,EAAGA,EAAIb,EAAIzP,OAAQsQ,IAC1B+vD,GAAa5wD,EAAIO,WAAWM,IACzBm+D,IACHp6D,GAAO,IACPo6D,GAAuB,IAGzBp6D,GAAO5E,EAAIa,GACXm+D,GAAuB,GAG3B,OAAOp6D,CACT,CACA,SAASo3D,GAAQt6C,IACd,GAAM,IAAM0zC,IAAax1C,SAASnY,KAAKia,EAC1C,CACA,SAASw6C,GAAO5hD,EAAOC,GACrB,MAAO,CACLD,MAAOw7C,GAAUc,OAAOt8C,GAExBC,IAAY,MAAPA,EAAcA,EAAMu7C,GAAUc,OAAOr8C,GAE1C9E,OAAe,MAAP8E,EAAcA,EAAMohD,GAASrhD,EAAOC,GAEhD,CAIA,SAASmiD,GAAU5N,EAAKv0C,GACtBu0C,EAAIv0C,IAAMu7C,GAAUc,OAAOr8C,GAC3Bu0C,EAAIr5C,OAASkmD,GAAS7M,EAAIx0C,MAAMo0C,OAAQn0C,EAC1C,CACA,SAASkiD,GAAU3/C,GACjB,MAAMmiD,EAAO,CACXh0E,KAAM,EACNH,KAAMgyB,EAAIkiC,QACVwd,QAASN,GACPp/C,EAAIgyC,IAAIx0C,MAAMo0C,OACd5xC,EAAIgyC,IAAIx0C,MAAMo0C,OAAS5xC,EAAIkiC,QAAQzuD,QAErC+J,WAAO,EACPw0D,IAAKhyC,EAAIgyC,KAEX,GAAIhyC,EAAI61C,IAAK,CACX,MAAM7D,EAAMhyC,EAAI61C,IAAI7D,IAChBA,EAAIv0C,IAAIm0C,OAAS5xC,EAAIgyC,IAAIv0C,IAAIm0C,SAC/BI,EAAIx0C,MAAMo0C,SACVI,EAAIx0C,MAAMm0C,SACVK,EAAIv0C,IAAIm0C,SACRI,EAAIv0C,IAAIk0C,UAEVwQ,EAAK3kE,MAAQ,CACXrP,KAAM,EACN+L,QAAS8lB,EAAI61C,IAAI37D,QACjB83D,MAEJ,CACA,OAAOmQ,CACT,CACA,SAAShD,GAAUjlE,EAASy4D,GAAW,EAAOX,EAAKY,EAAY,EAAGiF,EAAY,GAE5E,OADYnF,GAAuBx4D,EAASy4D,EAAUX,EAAKY,EAE7D,CACA,SAAS+L,GAAU1J,EAAMrgE,EAAOwtE,GAC9B/J,GAAexkC,QACbmhC,GAAoBC,EAAMmK,GAAOxqE,EAAOA,IAE5C,CA4CA,SAASytE,GAAYxmC,EAAMqG,GACzBogC,GACEzmC,OACA,EACAqG,IAGEqgC,GAAqB1mC,GAE3B,CACA,SAAS0mC,GAAqB1mC,GAC5B,MAAM/Y,EAAW+Y,EAAK/Y,SAASpR,OAAQL,GAAiB,IAAXA,EAAEljB,MAC/C,OAA2B,IAApB20B,EAASrvB,QAAqC,IAArBqvB,EAAS,GAAG30B,MAAe2oE,GAAah0C,EAAS,IAAoB,KAAdA,EAAS,EAClG,CACA,SAASw/C,GAAK19C,EAAMna,EAAQy3B,EAASsgC,GAAiB,EAAOC,GAAQ,GACnE,MAAM,SAAE3/C,GAAa8B,EACf89C,EAAU,GAChB,IAAK,IAAI3+D,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACvB,GAAmB,IAAf0gB,EAAMt2B,MAAgC,IAAlBs2B,EAAMoyC,QAAe,CAC3C,MAAM8L,EAAeH,EAAiB,EAAII,GAAgBn+C,EAAOyd,GACjE,GAAIygC,EAAe,GACjB,GAAIA,GAAgB,EAAG,CACrBl+C,EAAM46C,YAAYx0C,WAAa,EAC/B63C,EAAQ/3D,KAAK8Z,GACb,QACF,MACK,CACL,MAAM46C,EAAc56C,EAAM46C,YAC1B,GAAyB,KAArBA,EAAYlxE,KAAa,CAC3B,MAAMwoD,EAAO0oB,EAAYx0C,UACzB,SAAc,IAAT8rB,GAA4B,MAATA,GAAyB,IAATA,IAAeksB,GAA8Bp+C,EAAOyd,IAAY,EAAG,CACzG,MAAMj0C,EAAQ60E,GAAar+C,GACvBx2B,IACFoxE,EAAYpxE,MAAQi0C,EAAQ6gC,MAAM90E,GAEtC,CACIoxE,EAAY72B,eACd62B,EAAY72B,aAAetG,EAAQ6gC,MAAM1D,EAAY72B,cAEzD,CACF,CACF,MAAO,GAAmB,KAAf/jB,EAAMt2B,OACMq0E,EAAiB,EAAII,GAAgBn+C,EAAOyd,KAC7C,EAAG,CACU,KAA3Bzd,EAAM46C,YAAYlxE,MAAes2B,EAAM46C,YAAY5tD,UAAUhe,OAAS,GACxEgxB,EAAM46C,YAAY5tD,UAAU9G,KAC1B,MAGJ+3D,EAAQ/3D,KAAK8Z,GACb,QACF,CAEF,GAAmB,IAAfA,EAAMt2B,KAAY,CACpB,MAAM4jE,EAAgC,IAAlBttC,EAAMoyC,QACtB9E,GACF7vB,EAAQx3B,OAAOs4D,QAEjBV,GAAK79C,EAAOG,EAAMsd,GAAS,EAAOugC,GAC9B1Q,GACF7vB,EAAQx3B,OAAOs4D,OAEnB,MAAO,GAAmB,KAAfv+C,EAAMt2B,KACfm0E,GAAK79C,EAAOG,EAAMsd,EAAmC,IAA1Bzd,EAAM3B,SAASrvB,QAAc,QACnD,GAAmB,IAAfgxB,EAAMt2B,KACf,IAAK,IAAI8iD,EAAK,EAAGA,EAAKxsB,EAAMw+C,SAASxvE,OAAQw9C,IAC3CqxB,GACE79C,EAAMw+C,SAAShyB,GACfrsB,EACAsd,EACuC,IAAvCzd,EAAMw+C,SAAShyB,GAAInuB,SAASrvB,OAC5BgvE,EAIR,CACA,IAAIS,GAAgB,EACpB,GAAIR,EAAQjvE,SAAWqvB,EAASrvB,QAAwB,IAAdmxB,EAAKz2B,KAC7C,GAAqB,IAAjBy2B,EAAKiyC,SAAiBjyC,EAAKy6C,aAAyC,KAA1Bz6C,EAAKy6C,YAAYlxE,MAAe,EAAQy2B,EAAKy6C,YAAYv8C,UACrG8B,EAAKy6C,YAAYv8C,SAAWqgD,EAC1B9Q,GAAsBztC,EAAKy6C,YAAYv8C,WAEzCogD,GAAgB,OACX,GAAqB,IAAjBt+C,EAAKiyC,SAAiBjyC,EAAKy6C,aAAyC,KAA1Bz6C,EAAKy6C,YAAYlxE,MAAey2B,EAAKy6C,YAAYv8C,WAAa,EAAQ8B,EAAKy6C,YAAYv8C,WAAgD,KAAnC8B,EAAKy6C,YAAYv8C,SAAS30B,KAAa,CAC9L,MAAMgsC,EAAOipC,EAAYx+C,EAAKy6C,YAAa,WACvCllC,IACFA,EAAK84B,QAAUkQ,EACb9Q,GAAsBl4B,EAAK84B,UAE7BiQ,GAAgB,EAEpB,MAAO,GAAqB,IAAjBt+C,EAAKiyC,SAAiBpsD,GAA0B,IAAhBA,EAAOtc,MAAiC,IAAnBsc,EAAOosD,SAAiBpsD,EAAO40D,aAA2C,KAA5B50D,EAAO40D,YAAYlxE,MAAesc,EAAO40D,YAAYv8C,WAAa,EAAQrY,EAAO40D,YAAYv8C,WAAkD,KAArCrY,EAAO40D,YAAYv8C,SAAS30B,KAAa,CAC/P,MAAM44D,EAAWsP,GAAQzxC,EAAM,QAAQ,GACjCuV,EAAO4sB,GAAYA,EAAS5gD,KAAOi9D,EAAY34D,EAAO40D,YAAatY,EAAS5gD,KAC9Eg0B,IACFA,EAAK84B,QAAUkQ,EACb9Q,GAAsBl4B,EAAK84B,UAE7BiQ,GAAgB,EAEpB,CAEF,IAAKA,EACH,IAAK,MAAMz+C,KAASi+C,EAClBj+C,EAAM46C,YAAcn9B,EAAQ78B,MAAMof,EAAM46C,aAG5C,SAAS8D,EAAmB3lE,GAC1B,MAAMq4D,EAAM3zB,EAAQ78B,MAAM7H,GAE1B,OADAq4D,EAAIwN,iBAAkB,EACfxN,CACT,CACA,SAASuN,EAAYn+C,EAAOj3B,GAC1B,GAAIi3B,EAAMnC,WAAa,EAAQmC,EAAMnC,WAAqC,KAAxBmC,EAAMnC,SAAS30B,KAAa,CAC5E,MAAMgsC,EAAOlV,EAAMnC,SAAS0vC,WAAW7gD,KACpCuL,GAAMA,EAAEpoB,MAAQ9G,GAAQkvB,EAAEpoB,IAAIoF,UAAYlM,GAE7C,OAAOmsC,GAAQA,EAAK38B,KACtB,CACF,CACIklE,EAAQjvE,QAAUyuC,EAAQohC,gBAC5BphC,EAAQohC,eAAexgD,EAAUof,EAAStd,EAE9C,CACA,SAASg+C,GAAgBh+C,EAAMsd,GAC7B,MAAM,cAAEqhC,GAAkBrhC,EAC1B,OAAQtd,EAAKz2B,MACX,KAAK,EACH,GAAqB,IAAjBy2B,EAAKiyC,QACP,OAAO,EAET,MAAMvgC,EAASitC,EAAc7wE,IAAIkyB,GACjC,QAAe,IAAX0R,EACF,OAAOA,EAET,MAAM+oC,EAAcz6C,EAAKy6C,YACzB,GAAyB,KAArBA,EAAYlxE,KACd,OAAO,EAET,GAAIkxE,EAAYvN,SAAwB,QAAbltC,EAAKw3B,KAA8B,kBAAbx3B,EAAKw3B,KAAwC,SAAbx3B,EAAKw3B,IACpF,OAAO,EAET,QAA8B,IAA1BijB,EAAYx0C,UAAsB,CACpC,IAAI24C,EAAc,EAClB,MAAMC,EAAqBZ,GAA8Bj+C,EAAMsd,GAC/D,GAA2B,IAAvBuhC,EAEF,OADAF,EAAcnzD,IAAIwU,EAAM,GACjB,EAEL6+C,EAAqBD,IACvBA,EAAcC,GAEhB,IAAK,IAAI1/D,EAAI,EAAGA,EAAI6gB,EAAK9B,SAASrvB,OAAQsQ,IAAK,CAC7C,MAAM2/D,EAAYd,GAAgBh+C,EAAK9B,SAAS/e,GAAIm+B,GACpD,GAAkB,IAAdwhC,EAEF,OADAH,EAAcnzD,IAAIwU,EAAM,GACjB,EAEL8+C,EAAYF,IACdA,EAAcE,EAElB,CACA,GAAIF,EAAc,EAChB,IAAK,IAAIz/D,EAAI,EAAGA,EAAI6gB,EAAK32B,MAAMwF,OAAQsQ,IAAK,CAC1C,MAAMmZ,EAAI0H,EAAK32B,MAAM8V,GACrB,GAAe,IAAXmZ,EAAE/uB,MAAyB,SAAX+uB,EAAElvB,MAAmBkvB,EAAE24C,IAAK,CAC9C,MAAM8N,EAAUf,GAAgB1lD,EAAE24C,IAAK3zB,GACvC,GAAgB,IAAZyhC,EAEF,OADAJ,EAAcnzD,IAAIwU,EAAM,GACjB,EAEL++C,EAAUH,IACZA,EAAcG,EAElB,CACF,CAEF,GAAItE,EAAYvN,QAAS,CACvB,IAAK,IAAI/tD,EAAI,EAAGA,EAAI6gB,EAAK32B,MAAMwF,OAAQsQ,IAErC,GAAe,IADL6gB,EAAK32B,MAAM8V,GACf5V,KAEJ,OADAo1E,EAAcnzD,IAAIwU,EAAM,GACjB,EAGXsd,EAAQuxB,aAAanE,IACrBptB,EAAQuxB,aACNvB,GAAoBhwB,EAAQiwB,MAAOkN,EAAYtN,cAEjDsN,EAAYvN,SAAU,EACtB5vB,EAAQ+vB,OAAOG,GAAelwB,EAAQiwB,MAAOkN,EAAYtN,aAC3D,CAEA,OADAwR,EAAcnzD,IAAIwU,EAAM4+C,GACjBA,CACT,CAEE,OADAD,EAAcnzD,IAAIwU,EAAM,GACjB,EAEX,KAAK,EACL,KAAK,EACH,OAAO,EACT,KAAK,EACL,KAAK,GACL,KAAK,GAwBL,QAEE,OAAO,EAxBT,KAAK,EACL,KAAK,GACH,OAAOg+C,GAAgBh+C,EAAK1qB,QAASgoC,GACvC,KAAK,EACH,OAAOtd,EAAKguC,UACd,KAAK,EACH,IAAIgR,EAAa,EACjB,IAAK,IAAI7/D,EAAI,EAAGA,EAAI6gB,EAAK9B,SAASrvB,OAAQsQ,IAAK,CAC7C,MAAM0gB,EAAQG,EAAK9B,SAAS/e,GAC5B,GAAI,EAAS0gB,IAAUhgB,EAASggB,GAC9B,SAEF,MAAMi/C,EAAYd,GAAgBn+C,EAAOyd,GACzC,GAAkB,IAAdwhC,EACF,OAAO,EACEA,EAAYE,IACrBA,EAAaF,EAEjB,CACA,OAAOE,EACT,KAAK,GACH,OAAO,EAKb,CACA,MAAMC,GAAwC,IAAIjwD,IAAI,CACpD48C,GACAC,GACAC,GACAC,KAEF,SAASmT,GAA4BtmE,EAAO0kC,GAC1C,GAAmB,KAAf1kC,EAAMrP,OAAgB,EAASqP,EAAMu1D,SAAW8Q,GAAsBv3D,IAAI9O,EAAMu1D,QAAS,CAC3F,MAAM5sD,EAAM3I,EAAMiU,UAAU,GAC5B,GAAiB,IAAbtL,EAAIhY,KACN,OAAOy0E,GAAgBz8D,EAAK+7B,GACvB,GAAiB,KAAb/7B,EAAIhY,KACb,OAAO21E,GAA4B39D,EAAK+7B,EAE5C,CACA,OAAO,CACT,CACA,SAAS2gC,GAA8Bj+C,EAAMsd,GAC3C,IAAI0hC,EAAa,EACjB,MAAM31E,EAAQ60E,GAAal+C,GAC3B,GAAI32B,GAAwB,KAAfA,EAAME,KAAa,CAC9B,MAAM,WAAEqkE,GAAevkE,EACvB,IAAK,IAAI8V,EAAI,EAAGA,EAAIyuD,EAAW/+D,OAAQsQ,IAAK,CAC1C,MAAM,IAAEjP,EAAG,MAAE0I,GAAUg1D,EAAWzuD,GAC5BggE,EAAUnB,GAAgB9tE,EAAKotC,GACrC,GAAgB,IAAZ6hC,EACF,OAAOA,EAKT,IAAIC,EAQJ,GAXID,EAAUH,IACZA,EAAaG,GAIbC,EADiB,IAAfxmE,EAAMrP,KACIy0E,GAAgBplE,EAAO0kC,GACX,KAAf1kC,EAAMrP,KACH21E,GAA4BtmE,EAAO0kC,GAEnC,EAEI,IAAd8hC,EACF,OAAOA,EAELA,EAAYJ,IACdA,EAAaI,EAEjB,CACF,CACA,OAAOJ,CACT,CACA,SAASd,GAAal+C,GACpB,MAAMy6C,EAAcz6C,EAAKy6C,YACzB,GAAyB,KAArBA,EAAYlxE,KACd,OAAOkxE,EAAYpxE,KAEvB,CA8JA,SAASiN,GAAU2gC,EAAMx6B,GACvB,MAAM6gC,EA7JR,SAAgCrG,GAAM,SACpCooC,EAAW,GAAE,kBACb7L,GAAoB,EAAK,YACzB8L,GAAc,EAAK,IACnBC,GAAM,EAAK,cACXC,GAAgB,EAAK,eACrBC,EAAiB,GAAE,oBACnBC,EAAsB,CAAC,EAAC,eACxBhB,EAAiB,KAAI,mBACrB/B,EAAqB,EAAI,gBACzBhyC,EAAkB,EAAI,kBACtBg1C,EAAoB,GAAE,QACtBxpC,EAAU,KAAI,QACdypC,GAAU,EAAI,IACdjR,GAAM,EAAK,MACXpB,GAAQ,EAAK,WACbsS,EAAa,GAAE,gBACfC,EAAkBrhE,EAAS,OAC3BshE,GAAS,EAAK,KACdC,GAAO,EAAK,QACZ/wC,EAAUghC,GAAc,OACxBqD,EAASpD,GAAa,aACtBJ,IAEA,MAAMmQ,EAAYZ,EAASzkE,QAAQ,QAAS,IAAI8wB,MAAM,mBAChD4R,EAAU,CAEd+hC,WACAtqC,SAAUkrC,GAAa,EAAW,EAASA,EAAU,KACrDzM,oBACA8L,cACAC,MACAC,gBACAC,iBACAC,sBACAhB,iBACA/B,qBACAhyC,kBACAg1C,oBACAxpC,UACAypC,UACAjR,MACApB,QACAsS,aACAC,kBACAC,SACAC,OACA/wC,UACAqkC,SACAxD,eAEA74B,OACAipC,QAAyB,IAAIz0D,IAC7B4wB,WAA4B,IAAIrtB,IAChCgM,WAA4B,IAAIhM,IAChCmxD,OAAQ,GACRC,QAAS,GACT1uC,OAAQ,GACRitC,cAA+B,IAAIzzD,QACnCm1D,MAAO,EACPC,YAA6Bv0E,OAAOyS,OAAO,MAC3CsH,OAAQ,CACNy6D,KAAM,EACNnC,MAAO,EACPoC,KAAM,EACNC,MAAO,GAET56D,OAAQ,KACR66D,YAAa,KACbC,YAAa1pC,EACb2pC,WAAY,EACZlwB,SAAS,EAET,MAAA2c,CAAOjkE,GACL,MAAM0L,EAAQwoC,EAAQ4iC,QAAQpyE,IAAI1E,IAAS,EAE3C,OADAk0C,EAAQ4iC,QAAQ10D,IAAIpiB,EAAM0L,EAAQ,GAC3B1L,CACT,EACA,YAAAylE,CAAazlE,GACX,MAAM0L,EAAQwoC,EAAQ4iC,QAAQpyE,IAAI1E,GAClC,GAAI0L,EAAO,CACT,MAAM+rE,EAAe/rE,EAAQ,EACxB+rE,EAGHvjC,EAAQ4iC,QAAQ10D,IAAIpiB,EAAMy3E,GAF1BvjC,EAAQ4iC,QAAQv4D,OAAOve,EAI3B,CACF,EACA03E,aAAa13E,GACJ,IAAIwjE,GAActvB,EAAQ+vB,OAAOjkE,MAE1C,WAAAigC,CAAYrJ,GASVsd,EAAQz3B,OAAOqY,SAASof,EAAQsjC,YAActjC,EAAQqjC,YAAc3gD,CACtE,EACA,UAAA+gD,CAAW/gD,GAIT,MAAMvtB,EAAO6qC,EAAQz3B,OAAOqY,SACtB8iD,EAAehhD,EAAOvtB,EAAKjG,QAAQwzB,GAAQsd,EAAQqjC,YAAcrjC,EAAQsjC,YAAc,EAIxF5gD,GAAQA,IAASsd,EAAQqjC,YAIxBrjC,EAAQsjC,WAAaI,IACvB1jC,EAAQsjC,aACRtjC,EAAQ2jC,kBALV3jC,EAAQqjC,YAAc,KACtBrjC,EAAQ2jC,iBAOV3jC,EAAQz3B,OAAOqY,SAASjuB,OAAO+wE,EAAc,EAC/C,EACAC,cAAe,EACf,cAAAC,CAAejQ,GACf,EACA,iBAAAkQ,CAAkBlQ,GAClB,EACA,KAAAkN,CAAMlN,GACA,EAASA,KAAMA,EAAMnD,GAAuBmD,IAChD3zB,EAAQ6iC,OAAOp6D,KAAKkrD,GACpB,MAAMmQ,EAAatT,GACjB,YAAYxwB,EAAQ6iC,OAAOtxE,UAC3B,EACAoiE,EAAI7D,IACJ,GAGF,OADAgU,EAAWC,QAAUpQ,EACdmQ,CACT,EACA,KAAA3gE,CAAMwwD,EAAKv+B,GAAU,EAAOge,GAAU,GACpC,MAAM4wB,EAttFZ,SAA+BtxE,EAAO4I,EAAO2oE,GAAoB,EAAO7wB,GAAU,GAChF,MAAO,CACLnnD,KAAM,GACNyG,QACA4I,QACA2oE,oBACA7wB,UACA+tB,iBAAiB,EACjBrR,IAAKP,GAET,CA4sFuB2U,CACflkC,EAAQ5L,OAAO7iC,OACfoiE,EACAv+B,EACAge,GAGF,OADApT,EAAQ5L,OAAO3rB,KAAKu7D,GACbA,CACT,GAKF,OAFEhkC,EAAQuX,QAA0B,IAAI7lC,IAEjCsuB,CACT,CAEkBmkC,CAAuBxqC,EAAMx6B,GAC7CilE,GAAazqC,EAAMqG,GACf7gC,EAAQ6iE,aACV7B,GAAYxmC,EAAMqG,GAEf7gC,EAAQkyD,KAef,SAA2B13B,EAAMqG,GAC/B,MAAM,OAAE+vB,GAAW/vB,GACb,SAAEpf,GAAa+Y,EACrB,GAAwB,IAApB/Y,EAASrvB,OAAc,CACzB,MAAM8yE,EAAyBhE,GAAqB1mC,GACpD,GAAI0qC,GAA0BA,EAAuBlH,YAAa,CAChE,MAAMA,EAAckH,EAAuBlH,YAClB,KAArBA,EAAYlxE,MACdqlE,GAAe6L,EAAan9B,GAE9BrG,EAAKwjC,YAAcA,CACrB,MACExjC,EAAKwjC,YAAcv8C,EAAS,EAEhC,MAAO,GAAIA,EAASrvB,OAAS,EAAG,CAC9B,IAAIo3B,EAAY,GAIhBgR,EAAKwjC,YAAcxN,GACjB3vB,EACA+vB,EAAOhD,SACP,EACApzB,EAAK/Y,SACL+H,OACA,OACA,GACA,OACA,GACA,EAEJ,CACF,CA9CI27C,CAAkB3qC,EAAMqG,GAE1BrG,EAAKipC,QAA0B,IAAIlxD,IAAI,IAAIsuB,EAAQ4iC,QAAQj8D,SAC3DgzB,EAAKoF,WAAa,IAAIiB,EAAQjB,YAC9BpF,EAAKjc,WAAa,IAAIsiB,EAAQtiB,YAC9Bic,EAAKmpC,QAAU9iC,EAAQ8iC,QACvBnpC,EAAKkpC,OAAS7iC,EAAQ6iC,OACtBlpC,EAAKopC,MAAQ/iC,EAAQ+iC,MACrBppC,EAAKvF,OAAS4L,EAAQ5L,OACtBuF,EAAK4qC,aAAc,EAEjB5qC,EAAK4d,QAAU,IAAIvX,EAAQuX,QAE/B,CAiDA,SAAS6sB,GAAa1hD,EAAMsd,GAC1BA,EAAQqjC,YAAc3gD,EACtB,MAAM,eAAEy/C,GAAmBniC,EACrBwkC,EAAU,GAChB,IAAK,IAAIz1B,EAAK,EAAGA,EAAKozB,EAAe5wE,OAAQw9C,IAAM,CACjD,MAAM01B,EAAStC,EAAepzB,GAAIrsB,EAAMsd,GAQxC,GAPIykC,IACE,EAAQA,GACVD,EAAQ/7D,QAAQg8D,GAEhBD,EAAQ/7D,KAAKg8D,KAGZzkC,EAAQqjC,YACX,OAEA3gD,EAAOsd,EAAQqjC,WAEnB,CACA,OAAQ3gD,EAAKz2B,MACX,KAAK,EACE+zC,EAAQqxB,KACXrxB,EAAQ+vB,OAAOtC,IAEjB,MACF,KAAK,EACEztB,EAAQqxB,KACXrxB,EAAQ+vB,OAAO3B,IAEjB,MAEF,KAAK,EACH,IAAK,IAAIrf,EAAK,EAAGA,EAAKrsB,EAAKq+C,SAASxvE,OAAQw9C,IAC1Cq1B,GAAa1hD,EAAKq+C,SAAShyB,GAAK/O,GAElC,MACF,KAAK,GACL,KAAK,GACL,KAAK,EACL,KAAK,GAtDT,SAA0Bz3B,EAAQy3B,GAChC,IAAIn+B,EAAI,EACR,MAAM6iE,EAAc,KAClB7iE,KAEF,KAAOA,EAAI0G,EAAOqY,SAASrvB,OAAQsQ,IAAK,CACtC,MAAM0gB,EAAQha,EAAOqY,SAAS/e,GAC1B,EAAS0gB,KACbyd,EAAQojC,YAAcpjC,EAAQz3B,OAC9By3B,EAAQz3B,OAASA,EACjBy3B,EAAQsjC,WAAazhE,EACrBm+B,EAAQ2jC,cAAgBe,EACxBN,GAAa7hD,EAAOyd,GACtB,CACF,CAyCM2kC,CAAiBjiD,EAAMsd,GAG3BA,EAAQqjC,YAAc3gD,EACtB,IAAI7gB,EAAI2iE,EAAQjzE,OAChB,KAAOsQ,KACL2iE,EAAQ3iE,IAEZ,CACA,SAAS+iE,GAAmC94E,EAAMoX,GAChD,MAAMwtB,EAAU,EAAS5kC,GAAS2Y,GAAMA,IAAM3Y,EAAQ2Y,GAAM3Y,EAAK0pC,KAAK/wB,GACtE,MAAO,CAACie,EAAMsd,KACZ,GAAkB,IAAdtd,EAAKz2B,KAAY,CACnB,MAAM,MAAEF,GAAU22B,EAClB,GAAqB,IAAjBA,EAAKiyC,SAAiB5oE,EAAMqkB,KAAKskD,IACnC,OAEF,MAAM8P,EAAU,GAChB,IAAK,IAAI3iE,EAAI,EAAGA,EAAI9V,EAAMwF,OAAQsQ,IAAK,CACrC,MAAMkhC,EAAOh3C,EAAM8V,GACnB,GAAkB,IAAdkhC,EAAK92C,MAAcykC,EAAQqS,EAAKj3C,MAAO,CACzCC,EAAM4G,OAAOkP,EAAG,GAChBA,IACA,MAAM4iE,EAASvhE,EAAGwf,EAAMqgB,EAAM/C,GAC1BykC,GAAQD,EAAQ/7D,KAAKg8D,EAC3B,CACF,CACA,OAAOD,CACT,EAEJ,CAEA,MAAMK,GAAkB,gBAClBC,GAAej3B,GAAM,GAAGyhB,GAAczhB,QAAQyhB,GAAczhB,KAsLlE,SAASk3B,GAAUC,EAAQ/4E,GAAM,OAAE8jE,EAAM,KAAEtnD,EAAI,QAAEuoD,EAAO,KAAE0R,IACxD,MAAMuC,EAAWlV,EACN,WAAT9jE,EAAoB8hE,GAA0B,cAAT9hE,EAAuB2hE,GAAoBE,IAElF,IAAK,IAAIjsD,EAAI,EAAGA,EAAImjE,EAAOzzE,OAAQsQ,IAAK,CACtC,IAAIxP,EAAK2yE,EAAOnjE,GAChB,MAAMq1B,EAAqB7kC,EAAGi7B,SAAS,UACnC4J,IACF7kC,EAAKA,EAAGuQ,MAAM,GAAI,IAEpB6F,EACE,SAAS6sD,GAAejjE,EAAIpG,QAAWg5E,KAAYh+D,KAAKC,UAAU7U,KAAM6kC,EAAqB,SAAW,MAAMwrC,EAAO,IAAM,MAEzH7gE,EAAImjE,EAAOzzE,OAAS,GACtBy/D,GAEJ,CACF,CAqBA,SAASkU,GAAmBxF,EAAO1/B,GACjC,MAAMmlC,EAAazF,EAAMnuE,OAAS,IAAK,EACvCyuC,EAAQv3B,KAAK,KACb08D,GAAcnlC,EAAQolC,SACtBC,GAAY3F,EAAO1/B,EAASmlC,GAC5BA,GAAcnlC,EAAQslC,WACtBtlC,EAAQv3B,KAAK,IACf,CACA,SAAS48D,GAAY3F,EAAO1/B,EAASmlC,GAAa,EAAOI,GAAQ,GAC/D,MAAM,KAAE98D,EAAI,QAAEuoD,GAAYhxB,EAC1B,IAAK,IAAIn+B,EAAI,EAAGA,EAAI69D,EAAMnuE,OAAQsQ,IAAK,CACrC,MAAM6gB,EAAOg9C,EAAM79D,GACf,EAAS6gB,GACXja,EAAKia,GAAO,GACH,EAAQA,GACjBwiD,GAAmBxiD,EAAMsd,GAEzBwlC,GAAQ9iD,EAAMsd,GAEZn+B,EAAI69D,EAAMnuE,OAAS,IACjB4zE,GACFI,GAAS98D,EAAK,KACduoD,KAEAuU,GAAS98D,EAAK,MAGpB,CACF,CACA,SAAS+8D,GAAQ9iD,EAAMsd,GACrB,GAAI,EAAStd,GACXsd,EAAQv3B,KAAKia,GAAO,QAGtB,GAAIngB,EAASmgB,GACXsd,EAAQv3B,KAAKu3B,EAAQ+vB,OAAOrtC,SAG9B,OAAQA,EAAKz2B,MACX,KAAK,EACL,KAAK,EACL,KAAK,GAgBL,KAAK,GACHu5E,GAAQ9iD,EAAKy6C,YAAan9B,GAC1B,MAXF,KAAK,GAgET,SAAiBtd,EAAMsd,GACrBA,EAAQv3B,KAAKxB,KAAKC,UAAUwb,EAAK1qB,UAAW,EAAiB0qB,EAC/D,CAjEM+iD,CAAQ/iD,EAAMsd,GACd,MACF,KAAK,EACH0lC,GAAchjD,EAAMsd,GACpB,MACF,KAAK,GAqET,SAA0Btd,EAAMsd,GAC9B,MAAM,KAAEv3B,EAAI,OAAEsnD,EAAM,KAAE4V,GAAS3lC,EAC3B2lC,GAAMl9D,EAAKo8D,IACfp8D,EAAK,GAAGsnD,EAAO3B,QACfoX,GAAQ9iD,EAAK1qB,QAASgoC,GACtBv3B,EAAK,IACP,CA1EMm9D,CAAiBljD,EAAMsd,GACvB,MAIF,KAAK,EACH6lC,GAAsBnjD,EAAMsd,GAC5B,MACF,KAAK,GA0FT,SAAoBtd,EAAMsd,GACxB,MAAM,KAAEv3B,EAAI,OAAEsnD,EAAM,KAAE4V,GAAS3lC,EAC3B2lC,GACFl9D,EAAKo8D,IAEPp8D,EACE,GAAGsnD,EAAOtC,OAAmBxmD,KAAKC,UAAUwb,EAAK1qB,aAChD,EACD0qB,EAEJ,CAnGMojD,CAAWpjD,EAAMsd,GACjB,MACF,KAAK,IAkGT,SAAsBtd,EAAMsd,GAC1B,MAAM,KAAEv3B,EAAI,OAAEsnD,EAAM,KAAE4V,GAAS3lC,GACzB,IACJka,EAAG,MACHnuD,EAAK,SACL60B,EAAQ,UACR+H,EAAS,aACT2d,EAAY,WACZ5oB,EAAU,QACVkyC,EAAO,gBACP1c,EAAe,YACf2c,GACEntC,EACJ,IAAIqjD,EACAp9C,IASAo9C,EAAkBt5E,OAAOk8B,IAGzBjL,GACFjV,EAAKsnD,EAAO/B,IAAmB,KAE7B4B,GACFnnD,EAAK,IAAIsnD,EAAO3C,OAAela,EAAkB,OAAS,SAExDyyB,GACFl9D,EAAKo8D,IAGPp8D,EAAKsnD,EADcH,EAAUI,GAAoBhwB,EAAQiwB,MAAOJ,GAAeK,GAAelwB,EAAQiwB,MAAOJ,IACnF,KAAM,EAAcntC,GAC9C2iD,GAcF,SAAyB/oE,GACvB,IAAIuF,EAAIvF,EAAK/K,OACb,KAAOsQ,KACU,MAAXvF,EAAKuF,KAEX,OAAOvF,EAAKsG,MAAM,EAAGf,EAAI,GAAGZ,IAAKgD,GAAQA,GAAO,OAClD,CAnBI+hE,CAAgB,CAAC9rB,EAAKnuD,EAAO60B,EAAUmlD,EAAiBz/B,IACxDtG,GAEFv3B,EAAK,KACDmnD,GACFnnD,EAAK,KAEHiV,IACFjV,EAAK,MACL+8D,GAAQ9nD,EAAYsiB,GACpBv3B,EAAK,KAET,CAnJMw9D,CAAavjD,EAAMsd,GACnB,MACF,KAAK,IAyJT,SAA2Btd,EAAMsd,GAC/B,MAAM,KAAEv3B,EAAI,OAAEsnD,EAAM,KAAE4V,GAAS3lC,EACzB6wB,EAAS,EAASnuC,EAAKmuC,QAAUnuC,EAAKmuC,OAASd,EAAOrtC,EAAKmuC,QAC7D8U,GACFl9D,EAAKo8D,IAEPp8D,EAAKooD,EAAS,KAAM,EAAcnuC,GAClC2iD,GAAY3iD,EAAKnT,UAAWywB,GAC5Bv3B,EAAK,IACP,CAjKMy9D,CAAkBxjD,EAAMsd,GACxB,MACF,KAAK,IAgKT,SAA6Btd,EAAMsd,GACjC,MAAM,KAAEv3B,EAAI,OAAE28D,EAAM,SAAEE,EAAQ,QAAEtU,GAAYhxB,GACtC,WAAEswB,GAAe5tC,EACvB,IAAK4tC,EAAW/+D,OAEd,YADAkX,EAAK,MAAO,EAAcia,GAG5B,MAAMyiD,EAAa7U,EAAW/+D,OAAS,IAAK,EAC5CkX,EAAK08D,EAAa,IAAM,MACxBA,GAAcC,IACd,IAAK,IAAIvjE,EAAI,EAAGA,EAAIyuD,EAAW/+D,OAAQsQ,IAAK,CAC1C,MAAM,IAAEjP,EAAG,MAAE0I,GAAUg1D,EAAWzuD,GAClCskE,GAA2BvzE,EAAKotC,GAChCv3B,EAAK,MACL+8D,GAAQlqE,EAAO0kC,GACXn+B,EAAIyuD,EAAW/+D,OAAS,IAC1BkX,EAAK,KACLuoD,IAEJ,CACAmU,GAAcG,IACd78D,EAAK08D,EAAa,IAAM,KAC1B,CArLMiB,CAAoB1jD,EAAMsd,GAC1B,MACF,KAAK,IAoLT,SAA4Btd,EAAMsd,GAChCklC,GAAmBxiD,EAAK0tC,SAAUpwB,EACpC,CArLMqmC,CAAmB3jD,EAAMsd,GACzB,MACF,KAAK,IAoLT,SAA+Btd,EAAMsd,GACnC,MAAM,KAAEv3B,EAAI,OAAE28D,EAAM,SAAEE,GAAatlC,GAC7B,OAAEzoC,EAAM,QAAEw5D,EAAO,KAAEhgE,EAAI,QAAEigE,EAAO,OAAEC,GAAWvuC,EAC/CuuC,GACFxoD,EAAK,IAAI6mD,GAAcL,QAEzBxmD,EAAK,KAAM,EAAcia,GACrB,EAAQnrB,GACV8tE,GAAY9tE,EAAQyoC,GACXzoC,GACTiuE,GAAQjuE,EAAQyoC,GAElBv3B,EAAK,UACDuoD,GAAWjgE,KACb0X,EAAK,KACL28D,KAEErU,GACEC,GACFvoD,EAAK,WAEH,EAAQsoD,GACVmU,GAAmBnU,EAAS/wB,GAE5BwlC,GAAQzU,EAAS/wB,IAEVjvC,GACTy0E,GAAQz0E,EAAMivC,IAEZgxB,GAAWjgE,KACbu0E,IACA78D,EAAK,MAEHwoD,IACEvuC,EAAKxF,iBACPzU,EAAK,qBAEPA,EAAK,KAET,CA1NM69D,CAAsB5jD,EAAMsd,GAC5B,MACF,KAAK,IAyNT,SAAkCtd,EAAMsd,GACtC,MAAM,KAAExK,EAAI,WAAE27B,EAAU,UAAEC,EAAWJ,QAASuV,GAAgB7jD,GACxD,KAAEja,EAAI,OAAE28D,EAAM,SAAEE,EAAQ,QAAEtU,GAAYhxB,EAC5C,GAAkB,IAAdxK,EAAKvpC,KAAY,CACnB,MAAMu6E,GAAelT,GAAmB99B,EAAKx9B,SAC7CwuE,GAAe/9D,EAAK,KACpBi9D,GAAclwC,EAAMwK,GACpBwmC,GAAe/9D,EAAK,IACtB,MACEA,EAAK,KACL+8D,GAAQhwC,EAAMwK,GACdv3B,EAAK,KAEP89D,GAAenB,IACfplC,EAAQymC,cACRF,GAAe99D,EAAK,KACpBA,EAAK,MACL+8D,GAAQrU,EAAYnxB,GACpBA,EAAQymC,cACRF,GAAevV,IACfuV,GAAe99D,EAAK,KACpBA,EAAK,MACL,MAAMi+D,EAA8B,KAAnBtV,EAAUnlE,KACtBy6E,GACH1mC,EAAQymC,cAEVjB,GAAQpU,EAAWpxB,GACd0mC,GACH1mC,EAAQymC,cAEVF,GAAejB,GACb,EAGJ,CA1PMqB,CAAyBjkD,EAAMsd,GAC/B,MACF,KAAK,IAyPT,SAA4Btd,EAAMsd,GAChC,MAAM,KAAEv3B,EAAI,OAAEsnD,EAAM,OAAEqV,EAAM,SAAEE,EAAQ,QAAEtU,GAAYhxB,GAC9C,kBAAEikC,EAAiB,gBAAE9C,GAAoBz+C,EAC3Cy+C,GACF14D,EAAK,SAEPA,EAAK,UAAUia,EAAKhwB,eAChBuxE,IACFmB,IACA38D,EAAK,GAAGsnD,EAAOjB,UACXpsC,EAAK0wB,SAAS3qC,EAAK,UACvBA,EAAK,MACLuoD,IACAvoD,EAAK,MAEPA,EAAK,UAAUia,EAAKhwB,aACpB8yE,GAAQ9iD,EAAKpnB,MAAO0kC,GAChBikC,IACFx7D,EAAK,kBAAkBia,EAAKhwB,UAC5Bs+D,IACAvoD,EAAK,GAAGsnD,EAAOjB,WACfkC,IACAvoD,EAAK,UAAUia,EAAKhwB,UACpB4yE,KAEF78D,EAAK,KACD04D,GACF14D,EAAK,KAET,CArRMm+D,CAAmBlkD,EAAMsd,GACzB,MACF,KAAK,GACHqlC,GAAY3iD,EAAK3xB,KAAMivC,GAAS,GAAM,GAuB5C,CAIA,SAAS0lC,GAAchjD,EAAMsd,GAC3B,MAAM,QAAEhoC,EAAO,SAAEy4D,GAAa/tC,EAC9Bsd,EAAQv3B,KACNgoD,EAAWxpD,KAAKC,UAAUlP,GAAWA,GACpC,EACD0qB,EAEJ,CAQA,SAASmjD,GAAsBnjD,EAAMsd,GACnC,IAAK,IAAIn+B,EAAI,EAAGA,EAAI6gB,EAAK9B,SAASrvB,OAAQsQ,IAAK,CAC7C,MAAM0gB,EAAQG,EAAK9B,SAAS/e,GACxB,EAAS0gB,GACXyd,EAAQv3B,KAAK8Z,GAAQ,GAErBijD,GAAQjjD,EAAOyd,EAEnB,CACF,CACA,SAASmmC,GAA2BzjD,EAAMsd,GACxC,MAAM,KAAEv3B,GAASu3B,EACC,IAAdtd,EAAKz2B,MACPwc,EAAK,KACLo9D,GAAsBnjD,EAAMsd,GAC5Bv3B,EAAK,MACIia,EAAK+tC,SAEdhoD,EADa6qD,GAAmB5wC,EAAK1qB,SAAW0qB,EAAK1qB,QAAUiP,KAAKC,UAAUwb,EAAK1qB,UACvE,EAAc0qB,GAE1Bja,EAAK,IAAIia,EAAK1qB,YAAa,EAAiB0qB,EAEhD,CAoN4B,IAAI6Q,OAC9B,MAAQ,sMAAsMzkC,MAAM,KAAKghB,KAAK,WAAa,OA4E7O,MAAM+2D,GAAcjC,GAClB,wBACA,CAACliD,EAAM5E,EAAKkiB,IA8Bd,SAAmBtd,EAAM5E,EAAKkiB,EAAS8mC,GACrC,KAAiB,SAAbhpD,EAAIhyB,MAAqBgyB,EAAI61C,KAAQ71C,EAAI61C,IAAI37D,QAAQ8N,QAAS,CAChE,MAAMgqD,EAAMhyC,EAAI61C,IAAM71C,EAAI61C,IAAI7D,IAAMptC,EAAKotC,IACzC9vB,EAAQrO,QACNmhC,GAAoB,GAAIh1C,EAAIgyC,MAE9BhyC,EAAI61C,IAAMnD,GAAuB,QAAQ,EAAOV,EAClD,CAIA,GAAiB,OAAbhyC,EAAIhyB,KAAe,CACrB,MAAMmnD,EAAS8zB,GAAerkD,EAAM5E,GAC9BkpD,EAAS,CACb/6E,KAAM,EACN6jE,KAr2CYA,EAq2CEptC,EAAKotC,IAp2ChBoN,GAAOpN,EAAIx0C,MAAMo0C,OAAQI,EAAIv0C,IAAIm0C,SAq2CpCqR,SAAU,CAAC9tB,IAGb,GADAjT,EAAQjU,YAAYi7C,GAChBF,EACF,OAAOA,EAAeE,EAAQ/zB,GAAQ,EAE1C,KAAO,CACL,MAAMg0B,EAAWjnC,EAAQz3B,OAAOqY,SAEhC,IAAI/e,EAAIolE,EAAS/3E,QAAQwzB,GACzB,KAAO7gB,OAAQ,GAAG,CAChB,MAAMqlE,EAAUD,EAASplE,GACzB,GAAIqlE,GAA4B,IAAjBA,EAAQj7E,KACrB+zC,EAAQyjC,WAAWyD,OADrB,CAKA,IAAIA,GAA4B,IAAjBA,EAAQj7E,MAAei7E,EAAQlvE,QAAQ8N,OAAOvU,OAA7D,CAIA,GAAI21E,GAA4B,IAAjBA,EAAQj7E,KAAY,CACf,YAAb6xB,EAAIhyB,MAAmC,SAAbgyB,EAAIhyB,WAAgF,IAA5Do7E,EAAQnG,SAASmG,EAAQnG,SAASxvE,OAAS,GAAG41E,WACnGnnC,EAAQrO,QACNmhC,GAAoB,GAAIpwC,EAAKotC,MAGjC9vB,EAAQyjC,aACR,MAAMxwB,EAAS8zB,GAAerkD,EAAM5E,GAoBpCopD,EAAQnG,SAASt4D,KAAKwqC,GACtB,MAAMwxB,EAASqC,GAAkBA,EAAeI,EAASj0B,GAAQ,GACjEmxB,GAAanxB,EAAQjT,GACjBykC,GAAQA,IACZzkC,EAAQqjC,YAAc,IACxB,MACErjC,EAAQrO,QACNmhC,GAAoB,GAAIpwC,EAAKotC,MAGjC,KAtCA,CAFE9vB,EAAQyjC,WAAWyD,EAFrB,CA2CF,CACF,CAl6CF,IAAkBpX,CAm6ClB,CA1GWsX,CAAU1kD,EAAM5E,EAAKkiB,EAAS,CAACgnC,EAAQ/zB,EAAQo0B,KACpD,MAAMJ,EAAWjnC,EAAQz3B,OAAOqY,SAChC,IAAI/e,EAAIolE,EAAS/3E,QAAQ83E,GACrBp0E,EAAM,EACV,KAAOiP,MAAO,GAAG,CACf,MAAMqlE,EAAUD,EAASplE,GACrBqlE,GAA4B,IAAjBA,EAAQj7E,OACrB2G,GAAOs0E,EAAQnG,SAASxvE,OAE5B,CACA,MAAO,KACL,GAAI81E,EACFL,EAAO7J,YAAcmK,GACnBr0B,EACArgD,EACAotC,OAEG,CACL,MAAMunC,EAwLhB,SAA4B7kD,GAC1B,OACE,GAAkB,KAAdA,EAAKz2B,KAAa,CACpB,GAA4B,KAAxBy2B,EAAK0uC,UAAUnlE,KAGjB,OAAOy2B,EAFPA,EAAOA,EAAK0uC,SAIhB,MAAyB,KAAd1uC,EAAKz2B,OACdy2B,EAAOA,EAAKpnB,MAGlB,CApMkCksE,CAAmBR,EAAO7J,aAClDoK,EAAgBnW,UAAYkW,GAC1Br0B,EACArgD,EAAMo0E,EAAOjG,SAASxvE,OAAS,EAC/ByuC,EAEJ,MAmFR,SAAS+mC,GAAerkD,EAAM5E,GAC5B,MAAM2pD,EAAgC,IAAjB/kD,EAAKiyC,QAC1B,MAAO,CACL1oE,KAAM,GACN6jE,IAAKptC,EAAKotC,IACVqX,UAAwB,SAAbrpD,EAAIhyB,UAAkB,EAASgyB,EAAI61C,IAC9C/yC,SAAU6mD,IAAiBtT,GAAQzxC,EAAM,OAASA,EAAK9B,SAAW,CAAC8B,GACnEglD,QAASrT,GAAS3xC,EAAM,OACxB+kD,eAEJ,CACA,SAASH,GAA2Br0B,EAAQ00B,EAAU3nC,GACpD,OAAIiT,EAAOk0B,UACFjW,GACLje,EAAOk0B,UACPS,GAA0B30B,EAAQ00B,EAAU3nC,GAG5C4wB,GAAqB5wB,EAAQ+vB,OAAOtC,IAAiB,CACI,KACvD,UAIGma,GAA0B30B,EAAQ00B,EAAU3nC,EAEvD,CACA,SAAS4nC,GAA0B30B,EAAQ00B,EAAU3nC,GACnD,MAAM,OAAE+vB,GAAW/vB,EACb6nC,EAActX,GAClB,MACAC,GACE,GAAGmX,KACH,EACApY,GACA,KAGE,SAAE3uC,GAAaqyB,EACf9vB,EAAavC,EAAS,GAE5B,GADgD,IAApBA,EAASrvB,QAAoC,IAApB4xB,EAAWl3B,KACvC,CACvB,GAAwB,IAApB20B,EAASrvB,QAAoC,KAApB4xB,EAAWl3B,KAAa,CACnD,MAAM67E,EAAY3kD,EAAWg6C,YAE7B,OADAnI,GAAW8S,EAAWD,EAAa7nC,GAC5B8nC,CACT,CAAO,CACL,IAAIn/C,EAAY,GAIhB,OAAOgnC,GACL3vB,EACA+vB,EAAOhD,IACPsD,GAAuB,CAACwX,IACxBjnD,EACA+H,OACA,OACA,GACA,GACA,GACA,EACAsqB,EAAO6c,IAEX,CACF,CAAO,CACL,MAAMlqD,EAAMud,EAAWg6C,YACjB2K,EAzoEU,MADQplD,EA0oEa9c,GAzoE9B3Z,MAAey2B,EAAKmuC,SAAWzB,GAC/B1sC,EAAKnT,UAAU,GAAGwhD,QAElBruC,EA2oEP,OAJuB,KAAnBolD,EAAU77E,MACZqlE,GAAewW,EAAW9nC,GAE5Bg1B,GAAW8S,EAAWD,EAAa7nC,GAC5Bp6B,CACT,CAhpEF,IAA4B8c,CAipE5B,CAmCA,MAAMqlD,GAAenD,GACnB,MACA,CAACliD,EAAM5E,EAAKkiB,KACV,MAAM,OAAE+vB,EAAM,aAAEwB,GAAiBvxB,EACjC,OA+HJ,SAAoBtd,EAAM5E,EAAKkiB,EAAS8mC,GACtC,IAAKhpD,EAAI61C,IAIP,YAHA3zB,EAAQrO,QACNmhC,GAAoB,GAAIh1C,EAAIgyC,MAIhC,MAAMkY,EAAclqD,EAAIigD,eACxB,IAAKiK,EAIH,YAHAhoC,EAAQrO,QACNmhC,GAAoB,GAAIh1C,EAAIgyC,MAIhCmY,GAAuBD,GACvB,MAAM,eAAEpE,EAAc,kBAAEC,EAAiB,OAAEr7D,GAAWw3B,GAChD,OAAEvpB,EAAM,MAAEnb,EAAK,IAAE1I,EAAG,MAAEF,GAAUs1E,EAChCE,EAAU,CACdj8E,KAAM,GACN6jE,IAAKhyC,EAAIgyC,IACTr5C,SACA0xD,WAAY7sE,EACZ8sE,SAAUx1E,EACVy1E,iBAAkB31E,EAClBs1E,cACApnD,SAAUkL,GAAepJ,GAAQA,EAAK9B,SAAW,CAAC8B,IAEpDsd,EAAQjU,YAAYm8C,GACpB1/D,EAAOy6D,OACP,MAAMwB,EAASqC,GAAkBA,EAAeoB,GAChD,MAAO,KACL1/D,EAAOy6D,OACHwB,GAAQA,IAEhB,CAjKW6D,CAAW5lD,EAAM5E,EAAKkiB,EAAUkoC,IACrC,MAAMK,EAAY3X,GAAqBb,EAAO9B,IAAc,CAC1Dia,EAAQzxD,SAEJ+xD,EAAa18C,GAAepJ,GAC5BoyB,EAAOqf,GAAQzxC,EAAM,QACrB+lD,EAAUpU,GAAS3xC,EAAM,OAAO,GAAO,GAC7C+lD,GAAWA,EAAQx8E,KACnB,IAAIy8E,EAASD,IAA6B,IAAjBA,EAAQx8E,KAAaw8E,EAAQntE,MAAQk1D,GAAuBiY,EAAQntE,MAAMtD,SAAS,QAAQ,EAASywE,EAAQ9U,KACrI,MAAMkU,EAAcY,GAAWC,EAASnY,GAAqB,MAAOmY,GAAU,KACxEC,EAA2C,IAAxBT,EAAQzxD,OAAOxqB,MAAci8E,EAAQzxD,OAAOi6C,UAAY,EAC3EkY,EAAeD,EAAmB,GAAKF,EAAU,IAAM,IAc7D,OAbAP,EAAQ/K,YAAcxN,GACpB3vB,EACA+vB,EAAOhD,SACP,EACAwb,EACAK,OACA,OACA,GACA,GACCD,GACD,EACAjmD,EAAKotC,KAEA,KACL,IAAI+Y,EACJ,MAAM,SAAEjoD,GAAasnD,EAiBfY,EAA0C,IAApBloD,EAASrvB,QAAqC,IAArBqvB,EAAS,GAAG30B,KAC3D88E,EAAanU,GAAalyC,GAAQA,EAAO8lD,GAAuC,IAAzB9lD,EAAK9B,SAASrvB,QAAgBqjE,GAAalyC,EAAK9B,SAAS,IAAM8B,EAAK9B,SAAS,GAAK,KA4C/I,GA3CImoD,GACFF,EAAaE,EAAW5L,YACpBqL,GAAcX,GAChB7S,GAAW6T,EAAYhB,EAAa7nC,IAE7B8oC,EACTD,EAAalZ,GACX3vB,EACA+vB,EAAOhD,IACP8a,EAAcxX,GAAuB,CAACwX,SAAgB,EACtDnlD,EAAK9B,SACL,QACA,OACA,GACA,OACA,GACA,IAGFioD,EAAajoD,EAAS,GAAGu8C,YACrBqL,GAAcX,GAChB7S,GAAW6T,EAAYhB,EAAa7nC,GAElC6oC,EAAWjZ,WAAa+Y,IACtBE,EAAWjZ,SACb2B,EAAanE,IACbmE,EACEvB,GAAoBhwB,EAAQiwB,MAAO4Y,EAAWhZ,eAGhD0B,EACErB,GAAelwB,EAAQiwB,MAAO4Y,EAAWhZ,eAI/CgZ,EAAWjZ,SAAW+Y,EAClBE,EAAWjZ,SACbG,EAAO3C,IACP2C,EAAOC,GAAoBhwB,EAAQiwB,MAAO4Y,EAAWhZ,eAErDE,EAAOG,GAAelwB,EAAQiwB,MAAO4Y,EAAWhZ,eAGhD/a,EAAM,CACR,MAAMk0B,EAAOlY,GACXmY,GAAoBf,EAAQF,YAAa,CACvCxX,GAAuB,cAG3BwY,EAAKj4E,KA1zHN,CACL9E,KAAM,GACN8E,KAwzHuC,CAC/B4/D,GAAyB,CAAC,kBAAmB7b,EAAK6e,IAAK,MACvDhD,GAAyB,CACvB,iBACG+X,EAAS,CAAC,uBAAwBA,GAAU,GAC/C,OAAO1oC,EAAQwjC,aACbnU,wCAGJsB,GAAyB,CAAC,iBAAkBkY,IAC5CrY,GAAuB,sBACvBA,GAAuB,iBAl0H/BV,IAAKP,IAo0HCgZ,EAAUh5D,UAAU9G,KAClBugE,EACAxY,GAAuB,UACvBA,GAAuB/jE,OAAOuzC,EAAQ5L,OAAO7iC,UAE/CyuC,EAAQ5L,OAAO3rB,KAAK,KACtB,MACE8/D,EAAUh5D,UAAU9G,KAClBqoD,GACEmY,GAAoBf,EAAQF,aAC5Ba,GACA,SA2Cd,SAASZ,GAAuBn3D,EAAQkvB,GAClClvB,EAAOutD,YAyBXvtD,EAAOutD,WAAY,EACrB,CACA,SAAS4K,IAAoB,MAAE3tE,EAAK,IAAE1I,EAAG,MAAEF,GAASw2E,EAAW,IAC7D,OAEF,SAA0B5sE,GACxB,IAAIuF,EAAIvF,EAAK/K,OACb,KAAOsQ,MACDvF,EAAKuF,KAEX,OAAOvF,EAAKsG,MAAM,EAAGf,EAAI,GAAGZ,IAAI,CAACgD,EAAK8qC,IAAO9qC,GAAOusD,GAAuB,IAAI2Y,OAAOp6B,EAAK,IAAI,GACjG,CARSq6B,CAAiB,CAAC9tE,EAAO1I,EAAKF,KAAUw2E,GACjD,CASA,MAAMG,GAAkB7Y,GAAuB,aAAa,GACtD8Y,GAAkB,CAAC5mD,EAAMsd,KAC7B,GAAkB,IAAdtd,EAAKz2B,OAAgC,IAAjBy2B,EAAKiyC,SAAkC,IAAjBjyC,EAAKiyC,SAAgB,CACjE,MAAMmM,EAAQ3M,GAAQzxC,EAAM,QAC5B,GAAIo+C,EAGF,OAFAA,EAAMnN,IACN3zB,EAAQx3B,OAAOs4D,QACR,KACL9gC,EAAQx3B,OAAOs4D,QAGrB,GAqBIyI,GAAoB,CAACx9E,EAAOy9E,EAAU5oD,EAAUkvC,IAAQgB,GAC5D/kE,EACA60B,GACA,GACA,EACAA,EAASrvB,OAASqvB,EAAS,GAAGkvC,IAAMA,GAEtC,SAAS2Z,GAAW/mD,EAAMsd,EAAS0pC,EAAcH,IAC/CvpC,EAAQ+vB,OAAOd,IACf,MAAM,SAAEruC,EAAQ,IAAEkvC,GAAQptC,EACpBinD,EAAkB,GAClB3xC,EAAe,GACrB,IAAI4xC,EAAkB5pC,EAAQx3B,OAAOs4D,MAAQ,GAAK9gC,EAAQx3B,OAAOy6D,KAAO,EACxE,MAAM4G,EAAkB1V,GAAQzxC,EAAM,QAAQ,GAC9C,GAAImnD,EAAiB,CACnB,MAAM,IAAE5lE,EAAG,IAAE0vD,GAAQkW,EACjB5lE,IAAQkvD,GAAYlvD,KACtB2lE,GAAkB,GAEpBD,EAAgBlhE,KACd8nD,GACEtsD,GAAOusD,GAAuB,WAAW,GACzCkZ,EAAY/V,OAAK,EAAQ/yC,EAAUkvC,IAGzC,CACA,IAAIga,GAAmB,EACnBC,GAAsB,EAC1B,MAAMC,EAA0B,GAC1BC,EAAgC,IAAIv4D,IAC1C,IAAIw4D,EAAyB,EAC7B,IAAK,IAAIroE,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAMsoE,EAAcvpD,EAAS/e,GAC7B,IAAIuoE,EACJ,IAAKt+C,GAAeq+C,MAAkBC,EAAUjW,GAAQgW,EAAa,QAAQ,IAAQ,CAC1D,IAArBA,EAAYl+E,MACd+9E,EAAwBvhE,KAAK0hE,GAE/B,QACF,CACA,GAAIN,EAAiB,CACnB7pC,EAAQrO,QACNmhC,GAAoB,GAAIsX,EAAQta,MAElC,KACF,CACAga,GAAmB,EACnB,MAAQlpD,SAAUypD,EAAcva,IAAKwa,GAAYH,GAE/ClmE,IAAK4gD,EAAW2L,GAAuB,WAAW,GAClDmD,IAAK4W,EACLza,IAAK0a,GACHJ,EACJ,IAAIK,EACAtX,GAAYtO,GACd4lB,EAAiB5lB,EAAWA,EAAS7sD,QAAU,UAE/C4xE,GAAkB,EAEpB,MAAM3G,EAAO9O,GAAQgW,EAAa,OAC5BO,EAAehB,EAAYa,EAAWtH,EAAMoH,EAAcC,GAChE,IAAIK,EACAC,EACJ,GAAID,EAAMxW,GAAQgW,EAAa,MAC7BP,GAAkB,EAClB5xC,EAAavvB,KACXyoD,GACEyZ,EAAIhX,IACJkX,GAAiBhmB,EAAU6lB,EAAcR,KACzCb,UAGC,GAAIuB,EAAQzW,GACjBgW,EACA,kBACA,GAEC,CACD,IACIh+D,EADA+rB,EAAIr2B,EAER,KAAOq2B,MACL/rB,EAAOyU,EAASsX,GACE,IAAd/rB,EAAKlgB,OAAc6+E,GAAuB3+D,MAIhD,GAAIA,GAAQ2f,GAAe3f,IAASgoD,GAAQhoD,EAAM,kBAAmB,CACnE,IAAI4+D,EAAc/yC,EAAaA,EAAazmC,OAAS,GACrD,KAAsC,KAA/Bw5E,EAAY3Z,UAAUnlE,MAC3B8+E,EAAcA,EAAY3Z,UAE5B2Z,EAAY3Z,UAAYwZ,EAAMjX,IAAMzC,GAClC0Z,EAAMjX,IACNkX,GACEhmB,EACA6lB,EACAR,KAEFb,IACEwB,GAAiBhmB,EAAU6lB,EAAcR,IAC/C,MACElqC,EAAQrO,QACNmhC,GAAoB,GAAI8X,EAAM9a,KAGpC,MAAO,GAAImT,EAAM,CACf2G,GAAkB,EAClB,MAAM5B,EAAc/E,EAAKlF,eACrBiK,GACFC,GAAuBD,GACvBhwC,EAAavvB,KACXmoD,GAAqB5wB,EAAQ+vB,OAAO9B,IAAc,CAChD+Z,EAAYvxD,OACZq6C,GACEmY,GAAoBjB,GACpB6C,GAAiBhmB,EAAU6lB,IAC3B,OAKN1qC,EAAQrO,QACNmhC,GACE,GACAmQ,EAAKnT,KAIb,KAAO,CACL,GAAI2a,EAAgB,CAClB,GAAIR,EAAc7/D,IAAIqgE,GAAiB,CACrCzqC,EAAQrO,QACNmhC,GACE,GACA0X,IAGJ,QACF,CACAP,EAActzE,IAAI8zE,GACK,YAAnBA,IACFV,GAAsB,EAE1B,CACAJ,EAAgBlhE,KAAK8nD,GAAqB1L,EAAU6lB,GACtD,CACF,CACA,IAAKb,EAAiB,CACpB,MAAMmB,EAA2B,CAACj/E,EAAOk/E,KACvC,MAAM/nE,EAAKwmE,EAAY39E,OAAO,EAAQk/E,EAAWnb,GAIjD,OAHI9vB,EAAQwyB,eACVtvD,EAAGga,iBAAkB,GAEhBqzC,GAAqB,UAAWrtD,IAEpC4mE,EAEME,EAAwBz4E,QAGnCy4E,EAAwB55D,KAAM2S,GAAU+nD,GAAuB/nD,MACzDgnD,EACF/pC,EAAQrO,QACNmhC,GACE,GACAkX,EAAwB,GAAGla,MAI/B6Z,EAAgBlhE,KACduiE,OAAyB,EAAQhB,KAdrCL,EAAgBlhE,KAAKuiE,OAAyB,EAAQpqD,GAkB1D,CACA,MAAMm0B,EAAW60B,EAAkB,EAAIsB,GAAkBxoD,EAAK9B,UAAY,EAAI,EAC9E,IAAImF,EAAQsqC,GACVsZ,EAAgBz6D,OACdqhD,GACE,IAGAC,GACEzb,EAA8F,IAC9F,KAIN+a,GAQF,OANI93B,EAAazmC,SACfw0B,EAAQ6qC,GAAqB5wB,EAAQ+vB,OAAO5B,IAAe,CACzDpoC,EACAoqC,GAAsBn4B,MAGnB,CACLjS,QACA6jD,kBAEJ,CACA,SAASiB,GAAiB/+E,EAAMoX,EAAIxQ,GAClC,MAAM3G,EAAQ,CACZwkE,GAAqB,OAAQzkE,GAC7BykE,GAAqB,KAAMrtD,IAO7B,OALa,MAATxQ,GACF3G,EAAM0c,KACJ8nD,GAAqB,MAAOC,GAAuB/jE,OAAOiG,IAAQ,KAG/D29D,GAAuBtkE,EAChC,CACA,SAASm/E,GAAkBtqD,GACzB,IAAK,IAAI/e,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACvB,OAAQ0gB,EAAMt2B,MACZ,KAAK,EACH,GAAsB,IAAlBs2B,EAAMoyC,SAAiBuW,GAAkB3oD,EAAM3B,UACjD,OAAO,EAET,MACF,KAAK,EACH,GAAIsqD,GAAkB3oD,EAAMw+C,UAAW,OAAO,EAC9C,MACF,KAAK,GACL,KAAK,GACH,GAAImK,GAAkB3oD,EAAM3B,UAAW,OAAO,EAGpD,CACA,OAAO,CACT,CACA,SAASkqD,GAAuBpoD,GAC9B,OAAkB,IAAdA,EAAKz2B,MAA4B,KAAdy2B,EAAKz2B,OAEP,IAAdy2B,EAAKz2B,OAAey2B,EAAK1qB,QAAQ8N,OAASglE,GAAuBpoD,EAAK1qB,SAC/E,CAEA,MAAMmzE,GAAqC,IAAIv9D,QACzCw9D,GAAmB,CAAC1oD,EAAMsd,IACvB,WAEL,GAAoB,KADpBtd,EAAOsd,EAAQqjC,aACJp3E,MAAgC,IAAjBy2B,EAAKiyC,SAAkC,IAAjBjyC,EAAKiyC,QACnD,OAEF,MAAM,IAAEza,EAAG,MAAEnuD,GAAU22B,EACjBmtC,EAA+B,IAAjBntC,EAAKiyC,QACzB,IAAI0W,EAAWxb,EA4FnB,SAA8BntC,EAAMsd,EAASqxB,GAAM,GACjD,IAAI,IAAEnX,GAAQx3B,EACd,MAAM4oD,EAAoBC,GAAerxB,GACnCsxB,EAASnX,GACb3xC,EACA,MACA,GACA,GAGF,GAAI8oD,EACF,GAAIF,GAAqB7Y,GACvB,yBACAzyB,GACC,CACD,IAAI2zB,EASJ,GARoB,IAAhB6X,EAAOv/E,KACT0nE,EAAM6X,EAAOlwE,OAASk1D,GAAuBgb,EAAOlwE,MAAMtD,SAAS,IAEnE27D,EAAM6X,EAAO7X,IACRA,IACHA,EAAMnD,GAAuB,MAAM,EAAOgb,EAAOvnE,IAAI6rD,OAGrD6D,EACF,OAAO/C,GAAqB5wB,EAAQ+vB,OAAOlC,IAA4B,CACrE8F,GAGN,MAA2B,IAAhB6X,EAAOv/E,MAAcu/E,EAAOlwE,MAAMtD,QAAQyJ,WAAW,UAC9Dy4C,EAAMsxB,EAAOlwE,MAAMtD,QAAQ4K,MAAM,IAGrC,MAAM6oE,EAAUrY,GAAgBlZ,IAAQla,EAAQq/B,mBAAmBnlB,GACnE,OAAIuxB,GACGpa,GAAKrxB,EAAQ+vB,OAAO0b,GAClBA,IAETzrC,EAAQ+vB,OAAOnC,IACf5tB,EAAQjB,WAAWpoC,IAAIujD,GAChBob,GAAepb,EAAK,aAC7B,CArIiCwxB,CAAqBhpD,EAAMsd,GAAW,IAAIka,KACvE,MAAMyxB,EAAqB,EAASN,IAAaA,EAASxa,SAAWhD,GACrE,IAAI+d,EACAC,EAEAC,EACAC,EACAC,EAHArjD,EAAY,EAIZsjD,EAEFN,GAAsBN,IAAare,IAAYqe,IAAape,KAAa4C,IAIhE,QAAR3V,GAAyB,kBAARA,GAAmC,SAARA,GAE/C,GAAInuD,EAAMwF,OAAS,EAAG,CACpB,MAAM26E,EAAmBC,GACvBzpD,EACAsd,OACA,EACA6vB,EACA8b,GAEFC,EAAaM,EAAiBngF,MAC9B48B,EAAYujD,EAAiBvjD,UAC7BojD,EAAmBG,EAAiBH,iBACpC,MAAMruD,EAAawuD,EAAiBxuD,WACpCsuD,EAAkBtuD,GAAcA,EAAWnsB,OAAS4+D,GAClDzyC,EAAWzc,IAAK6c,GAocxB,SAA4BA,EAAKkiB,GAC/B,MAAMosC,EAAU,GACVC,EAAUlB,GAAmB36E,IAAIstB,GACnCuuD,EACFD,EAAQ3jE,KAAKu3B,EAAQwjC,aAAa6I,KAGhCrsC,EAAQ+vB,OAAOjC,IACf9tB,EAAQtiB,WAAW/mB,IAAImnB,EAAIhyB,MAC3BsgF,EAAQ3jE,KAAK6sD,GAAex3C,EAAIhyB,KAAM,eAG1C,MAAM,IAAEgkE,GAAQhyC,EAQhB,GAPIA,EAAI61C,KAAKyY,EAAQ3jE,KAAKqV,EAAI61C,KAC1B71C,EAAI7Z,MACD6Z,EAAI61C,KACPyY,EAAQ3jE,KAAK,UAEf2jE,EAAQ3jE,KAAKqV,EAAI7Z,MAEfxV,OAAOkY,KAAKmX,EAAIC,WAAWxsB,OAAQ,CAChCusB,EAAI7Z,MACF6Z,EAAI61C,KACPyY,EAAQ3jE,KAAK,UAEf2jE,EAAQ3jE,KAAK,WAEf,MAAM6jE,EAAiB9b,GAAuB,QAAQ,EAAOV,GAC7Dsc,EAAQ3jE,KACN4nD,GACEvyC,EAAIC,UAAU9c,IACXsrE,GAAahc,GAAqBgc,EAAUD,IAE/Cxc,GAGN,CACA,OAAOK,GAAsBic,EAAStuD,EAAIgyC,IAC5C,CA1egC0c,CAAmB1uD,EAAKkiB,UAC9C,EACAksC,EAAiBD,iBACnBA,GAAiB,EAErB,CACA,GAAIvpD,EAAK9B,SAASrvB,OAAS,EAiBzB,GAhBI85E,IAAane,KACf+e,GAAiB,EACjBtjD,GAAa,MAWYknC,GAC3Bwb,IAAare,IACbqe,IAAane,GACW,CACtB,MAAM,MAAEnnC,EAAK,gBAAE6jD,GAAoBH,GAAW/mD,EAAMsd,GACpD6rC,EAAgB9lD,EACZ6jD,IACFjhD,GAAa,KAEjB,MAAO,GAA6B,IAAzBjG,EAAK9B,SAASrvB,QAAgB85E,IAAare,GAAU,CAC9D,MAAMzqC,EAAQG,EAAK9B,SAAS,GACtB30B,EAAOs2B,EAAMt2B,KACbwgF,EAA+B,IAATxgF,GAAuB,IAATA,EACtCwgF,GAA2D,IAApC/L,GAAgBn+C,EAAOyd,KAChDrX,GAAa,GAGbkjD,EADEY,GAAgC,IAATxgF,EACTs2B,EAEAG,EAAK9B,QAEzB,MACEirD,EAAgBnpD,EAAK9B,SAGrBmrD,GAAoBA,EAAiBx6E,SACvCu6E,EA6bN,SAAmC//E,GACjC,IAAI2gF,EAAmB,IACvB,IAAK,IAAI7qE,EAAI,EAAG+G,EAAI7c,EAAMwF,OAAQsQ,EAAI+G,EAAG/G,IACvC6qE,GAAoBzlE,KAAKC,UAAUnb,EAAM8V,IACrCA,EAAI+G,EAAI,IAAG8jE,GAAoB,MAErC,OAAOA,EAAmB,GAC5B,CApc0BC,CAA0BZ,IAEhDrpD,EAAKy6C,YAAcxN,GACjB3vB,EACAqrC,EACAO,EACAC,EACc,IAAdljD,OAAkB,EAASA,EAC3BmjD,EACAE,IACEC,GACF,EACApc,EACAntC,EAAKotC,IAET,EA4CF,SAASqc,GAAWzpD,EAAMsd,EAASj0C,EAAQ22B,EAAK32B,MAAO8jE,EAAa8b,EAAoBta,GAAM,GAC5F,MAAM,IAAEnX,EAAK4V,IAAK8c,EAAU,SAAEhsD,GAAa8B,EAC3C,IAAI4tC,EAAa,GACjB,MAAMuc,EAAY,GACZC,EAAoB,GACpBC,EAAcnsD,EAASrvB,OAAS,EACtC,IAAI06E,GAAiB,EACjBtjD,EAAY,EACZqkD,GAAS,EACTC,GAAkB,EAClBC,GAAkB,EAClBC,GAA2B,EAC3BC,GAAiB,EACjBC,GAAe,EACnB,MAAMtB,EAAmB,GACnBuB,EAAgBrpE,IAChBqsD,EAAW/+D,SACbs7E,EAAUpkE,KACR4nD,GAAuBkd,GAAiBjd,GAAasc,IAEvDtc,EAAa,IAEXrsD,GAAK4oE,EAAUpkE,KAAKxE,IAEpBupE,EAAoB,KACpBxtC,EAAQx3B,OAAOy6D,KAAO,GACxB3S,EAAW7nD,KACT8nD,GACEC,GAAuB,WAAW,GAClCA,GAAuB,WAKzBid,EAAmB,EAAG76E,MAAK0I,YAC/B,GAAI63D,GAAYvgE,GAAM,CACpB,MAAM9G,EAAO8G,EAAIoF,QACX01E,EAAiBpsE,EAAKxV,GAc5B,IAbI4hF,GAAoB7d,IAAe8b,GAEhB,YAAvB7/E,EAAK2X,eACI,wBAAT3X,GACCkX,EAAelX,KACdqhF,GAA2B,GAEzBO,GAAkB1qE,EAAelX,KACnCuhF,GAAe,GAEbK,GAAiC,KAAfpyE,EAAMrP,OAC1BqP,EAAQA,EAAMiU,UAAU,IAEP,KAAfjU,EAAMrP,OAA+B,IAAfqP,EAAMrP,MAA6B,IAAfqP,EAAMrP,OAAey0E,GAAgBplE,EAAO0kC,GAAW,EACnG,OAEW,QAATl0C,EACFkhF,GAAS,EACS,UAATlhF,EACTmhF,GAAkB,EACA,UAATnhF,EACTohF,GAAkB,EACA,QAATphF,GAAmBigF,EAAiBn8D,SAAS9jB,IACtDigF,EAAiBtjE,KAAK3c,IAEpB+jE,GAAyB,UAAT/jE,GAA6B,UAATA,GAAsBigF,EAAiBn8D,SAAS9jB,IACtFigF,EAAiBtjE,KAAK3c,EAE1B,MACEshF,GAAiB,GAGrB,IAAK,IAAIvrE,EAAI,EAAGA,EAAI9V,EAAMwF,OAAQsQ,IAAK,CACrC,MAAMkhC,EAAOh3C,EAAM8V,GACnB,GAAkB,IAAdkhC,EAAK92C,KAAY,CACnB,MAAM,IAAE6jE,EAAG,KAAEhkE,EAAI,QAAE0xE,EAAO,MAAEliE,GAAUynC,EACtC,IAAI0tB,GAAW,EAKf,GAJa,QAAT3kE,IACFkhF,GAAS,EACTQ,KAEW,OAAT1hF,IAAkBy/E,GAAerxB,IAAQ5+C,GAASA,EAAMtD,QAAQyJ,WAAW,SAAWgxD,GACxF,yBACAzyB,IAEA,SAEFswB,EAAW7nD,KACT8nD,GACEC,GAAuB1kE,GAAM,EAAM0xE,GACnChN,GACEl1D,EAAQA,EAAMtD,QAAU,GACxBy4D,EACAn1D,EAAQA,EAAMw0D,IAAMA,IAI5B,KAAO,CACL,MAAM,KAAEhkE,EAAI,IAAEmY,EAAG,IAAE0vD,EAAG,IAAE7D,EAAG,UAAE/xC,GAAcglB,EACrC4qC,EAAmB,SAAT7hF,EACV8hF,EAAiB,OAAT9hF,EACd,GAAa,SAATA,EAAiB,CACd+jE,GACH7vB,EAAQrO,QACNmhC,GAAoB,GAAIhD,IAG5B,QACF,CACA,GAAa,SAAThkE,GAA4B,SAATA,EACrB,SAEF,GAAa,OAATA,GAAiB6hF,GAAWpZ,GAActwD,EAAK,QAAUsnE,GAAerxB,IAAQuY,GAClF,yBACAzyB,IAEA,SAEF,GAAI4tC,GAASvc,EACX,SAaF,IATEsc,GAAWpZ,GAActwD,EAAK,QAE9B2pE,GAASb,GAAexY,GAActwD,EAAK,wBAE3CgoE,GAAiB,GAEf0B,GAAWpZ,GAActwD,EAAK,QAChCupE,KAEGvpE,IAAQ0pE,GAAWC,GAAQ,CAE9B,GADAR,GAAiB,EACbzZ,EACF,GAAIga,EAAS,CAwBT,GAtBAL,IAsBI7a,GACF,+BACAzyB,GACC,CACD6sC,EAAUp8D,QAAQkjD,GAClB,QACF,CAEF6Z,IACAF,IACAT,EAAUpkE,KAAKkrD,EACjB,MACE2Z,EAAa,CACXrhF,KAAM,GACN6jE,MACAe,OAAQ7wB,EAAQ+vB,OAAOrB,IACvBn/C,UAAWsgD,EAAc,CAAC8D,GAAO,CAACA,EAAK,eAI3C3zB,EAAQrO,QACNmhC,GACE6a,EAAU,GAAK,GACf7d,IAIN,QACF,CACI6d,GAAW5vD,EAAU3N,KAAMutD,GAAwB,SAAhBA,EAAI3lE,WACzC2wB,GAAa,IAEf,MAAMklD,EAAqB7tC,EAAQoiC,oBAAoBt2E,GACvD,GAAI+hF,EAAoB,CACtB,MAAQ9hF,MAAO+hF,EAAM,YAAEC,GAAgBF,EAAmB9qC,EAAMrgB,EAAMsd,IACrEqxB,GAAOyc,EAAOt3E,QAAQi3E,GACnBG,GAAS3pE,IAAQkvD,GAAYlvD,GAC/BqpE,EAAajd,GAAuByd,EAAQlB,IAE5Ctc,EAAW7nD,QAAQqlE,GAEjBC,IACFjB,EAAkBrkE,KAAKs6B,GACnBxgC,EAASwrE,IACX5C,GAAmBj9D,IAAI60B,EAAMgrC,GAGnC,MAAY,EAAmBjiF,KAC7BghF,EAAkBrkE,KAAKs6B,GACnBgqC,IACFd,GAAiB,GAGvB,CACF,CACA,IAAI+B,EAqCJ,GApCInB,EAAUt7E,QACZ+7E,IAEEU,EADEnB,EAAUt7E,OAAS,EACHq/D,GAChB5wB,EAAQ+vB,OAAO1B,IACfwe,EACAD,GAGgBC,EAAU,IAErBvc,EAAW/+D,SACpBy8E,EAAkB3d,GAChBkd,GAAiBjd,GACjBsc,IAGAQ,EACFzkD,GAAa,IAETskD,IAAoBpd,IACtBlnC,GAAa,GAEXukD,IAAoBrd,IACtBlnC,GAAa,GAEXojD,EAAiBx6E,SACnBo3B,GAAa,GAEXwkD,IACFxkD,GAAa,KAGZsjD,GAAiC,IAAdtjD,GAAiC,KAAdA,KAAsBqkD,GAAUK,GAAgBP,EAAkBv7E,OAAS,KACpHo3B,GAAa,MAEVqX,EAAQiwB,OAAS+d,EACpB,OAAQA,EAAgB/hF,MACtB,KAAK,GACH,IAAIgiF,GAAiB,EACjBC,GAAiB,EACjBC,GAAgB,EACpB,IAAK,IAAItsE,EAAI,EAAGA,EAAImsE,EAAgB1d,WAAW/+D,OAAQsQ,IAAK,CAC1D,MAAMjP,EAAMo7E,EAAgB1d,WAAWzuD,GAAGjP,IACtCugE,GAAYvgE,GACM,UAAhBA,EAAIoF,QACNi2E,EAAgBpsE,EACS,UAAhBjP,EAAIoF,UACbk2E,EAAgBrsE,GAERjP,EAAIw7E,eACdD,GAAgB,EAEpB,CACA,MAAME,EAAYL,EAAgB1d,WAAW2d,GACvCK,EAAYN,EAAgB1d,WAAW4d,GACxCC,EAkBHH,EAAkBpd,GAChB5wB,EAAQ+vB,OAAOvB,IACf,CAACwf,KAnBCK,IAAclb,GAAYkb,EAAU/yE,SACtC+yE,EAAU/yE,MAAQs1D,GAChB5wB,EAAQ+vB,OAAOzB,IACf,CAAC+f,EAAU/yE,SAGXgzE,IAEHpB,GAA4C,IAAzBoB,EAAUhzE,MAAMrP,MAAoD,MAAtCqiF,EAAUhzE,MAAMtD,QAAQ8N,OAAO,IAExD,KAAzBwoE,EAAUhzE,MAAMrP,QACdqiF,EAAUhzE,MAAQs1D,GAChB5wB,EAAQ+vB,OAAOxB,IACf,CAAC+f,EAAUhzE,UASjB,MACF,KAAK,GACH,MACF,QACE0yE,EAAkBpd,GAChB5wB,EAAQ+vB,OAAOvB,IACf,CACEoC,GAAqB5wB,EAAQ+vB,OAAOtB,IAAuB,CACzDuf,MAOZ,MAAO,CACLjiF,MAAOiiF,EACPtwD,WAAYovD,EACZnkD,YACAojD,mBACAE,iBAEJ,CACA,SAASsB,GAAiBjd,GACxB,MAAMie,EAA6B,IAAIpgE,IACjCgO,EAAU,GAChB,IAAK,IAAIta,EAAI,EAAGA,EAAIyuD,EAAW/+D,OAAQsQ,IAAK,CAC1C,MAAMkhC,EAAOutB,EAAWzuD,GACxB,GAAsB,IAAlBkhC,EAAKnwC,IAAI3G,OAAe82C,EAAKnwC,IAAI69D,SAAU,CAC7Ct0C,EAAQ1T,KAAKs6B,GACb,QACF,CACA,MAAMj3C,EAAOi3C,EAAKnwC,IAAIoF,QAChBuyB,EAAWgkD,EAAW/9E,IAAI1E,GAC5By+B,GACW,UAATz+B,GAA6B,UAATA,GAAoBwV,EAAKxV,KAC/C,GAAay+B,EAAUwY,IAGzBwrC,EAAWrgE,IAAIpiB,EAAMi3C,GACrB5mB,EAAQ1T,KAAKs6B,GAEjB,CACA,OAAO5mB,CACT,CACA,SAAS,GAAaoO,EAAU0qB,GACF,KAAxB1qB,EAASjvB,MAAMrP,KACjBs+B,EAASjvB,MAAM80D,SAAS3nD,KAAKwsC,EAAS35C,OAEtCivB,EAASjvB,MAAQ60D,GACf,CAAC5lC,EAASjvB,MAAO25C,EAAS35C,OAC1BivB,EAASulC,IAGf,CAgDA,SAASyb,GAAerxB,GACtB,MAAe,cAARA,GAA+B,cAARA,CAChC,CAEA,MAAMs0B,GAAsB,CAAC9rD,EAAMsd,KACjC,GAAI40B,GAAalyC,GAAO,CACtB,MAAM,SAAE9B,EAAQ,IAAEkvC,GAAQptC,GACpB,SAAEmiC,EAAQ,UAAE0lB,GA4BtB,SAA2B7nD,EAAMsd,GAC/B,IACIuqC,EADA1lB,EAAW,YAEf,MAAM4pB,EAAe,GACrB,IAAK,IAAI5sE,EAAI,EAAGA,EAAI6gB,EAAK32B,MAAMwF,OAAQsQ,IAAK,CAC1C,MAAMmZ,EAAI0H,EAAK32B,MAAM8V,GACrB,GAAe,IAAXmZ,EAAE/uB,KACA+uB,EAAE1f,QACW,SAAX0f,EAAElvB,KACJ+4D,EAAW59C,KAAKC,UAAU8T,EAAE1f,MAAMtD,UAElCgjB,EAAElvB,KAAO,EAASkvB,EAAElvB,MACpB2iF,EAAahmE,KAAKuS,UAItB,GAAe,SAAXA,EAAElvB,MAAmByoE,GAAcv5C,EAAE/W,IAAK,SAC5C,GAAI+W,EAAE24C,IACJ9O,EAAW7pC,EAAE24C,SACR,GAAI34C,EAAE/W,KAAsB,IAAf+W,EAAE/W,IAAIhY,KAAY,CACpC,MAAMH,EAAO,EAASkvB,EAAE/W,IAAIjM,SAC5B6sD,EAAW7pC,EAAE24C,IAAMnD,GAAuB1kE,GAAM,EAAOkvB,EAAE/W,IAAI6rD,IAC/D,MAEe,SAAX90C,EAAElvB,MAAmBkvB,EAAE/W,KAAOkvD,GAAYn4C,EAAE/W,OAC9C+W,EAAE/W,IAAIjM,QAAU,EAASgjB,EAAE/W,IAAIjM,UAEjCy2E,EAAahmE,KAAKuS,EAGxB,CACA,GAAIyzD,EAAal9E,OAAS,EAAG,CAC3B,MAAM,MAAExF,EAAK,WAAE2xB,GAAeyuD,GAC5BzpD,EACAsd,EACAyuC,GACA,GACA,GAEFlE,EAAYx+E,EACR2xB,EAAWnsB,QACbyuC,EAAQrO,QACNmhC,GACE,GACAp1C,EAAW,GAAGoyC,KAItB,CACA,MAAO,CACLjL,WACA0lB,YAEJ,CAjFoCmE,CAAkBhsD,EAAMsd,GAClD2uC,EAAW,CACf3uC,EAAQk2B,kBAAoB,cAAgB,SAC5CrR,EACA,KACA,YACA,QAEF,IAAI+pB,EAAc,EACdrE,IACFoE,EAAS,GAAKpE,EACdqE,EAAc,GAEZhuD,EAASrvB,SACXo9E,EAAS,GAAK7d,GAAyB,GAAIlwC,GAAU,GAAO,EAAOkvC,GACnE8e,EAAc,GAEZ5uC,EAAQnH,UAAYmH,EAAQsiC,UAC9BsM,EAAc,GAEhBD,EAASh8E,OAAOi8E,GAChBlsD,EAAKy6C,YAAcvM,GACjB5wB,EAAQ+vB,OAAO7B,IACfygB,EACA7e,EAEJ,GAyDI+e,GAAc,CAAC/wD,EAAK4E,EAAMsd,EAAS8uC,KACvC,MAAM,IAAEhf,EAAG,UAAE/xC,EAAS,IAAE9Z,GAAQ6Z,EAIhC,IAAIixD,EACJ,GAJKjxD,EAAI61C,KAAQ51C,EAAUxsB,QACzByuC,EAAQrO,QAAQmhC,GAAoB,GAAIhD,IAGzB,IAAb7rD,EAAIhY,KACN,GAAIgY,EAAIwsD,SAAU,CAChB,IAAIzQ,EAAU/7C,EAAIjM,QAIdgoD,EAAQv+C,WAAW,UACrBu+C,EAAU,SAASA,EAAQp9C,MAAM,MAWnCmsE,EAAYve,GATyB,IAAjB9tC,EAAKiyC,SAAiB3U,EAAQv+C,WAAW,WAAa,QAAQ+zB,KAAKwqB,GAGrFr8C,EAAa,EAASq8C,IACpB,MAGIA,KAEwC,EAAM/7C,EAAI6rD,IAC5D,MACEif,EAAYpe,GAAyB,CACnC,GAAG3wB,EAAQwjC,aAAa3U,OACxB5qD,EACA,WAIJ8qE,EAAY9qE,EACZ8qE,EAAUnuD,SAASnQ,QAAQ,GAAGuvB,EAAQwjC,aAAa3U,QACnDkgB,EAAUnuD,SAASnY,KAAK,KAE1B,IAAIkrD,EAAM71C,EAAI61C,IACVA,IAAQA,EAAI37D,QAAQ8N,SACtB6tD,OAAM,GAER,IAAIqb,EAAchvC,EAAQkiC,gBAAkBvO,IAAQ3zB,EAAQoT,QAC5D,GAAIugB,EAAK,CACP,MAAMsb,EAAcrb,GAAmBD,GACjCub,IAAsBD,GA9/GF,CAACtb,GAAQO,GAAQ1+B,KAAKk+B,GAAaC,IA8/GlBwb,CAAexb,IACpDyb,EAAwBzb,EAAI37D,QAAQ4X,SAAS,MAS/Cs/D,GAAqBF,GAAeC,KACtCtb,EAAMhD,GAAyB,CAC7B,GAAGue,EAAoB,SAAW,kBAAuBE,EAAwB,IAAM,MACvFzb,EACAyb,EAAwB,IAAM,MAGpC,CACA,IAAIxpE,EAAM,CACR7Z,MAAO,CACLwkE,GACEwe,EACApb,GAAOnD,GAAuB,YAAY,EAAOV,MAWvD,OAPIgf,IACFlpE,EAAMkpE,EAAUlpE,IAEdopE,IACFppE,EAAI7Z,MAAM,GAAGuP,MAAQ0kC,EAAQ78B,MAAMyC,EAAI7Z,MAAM,GAAGuP,QAElDsK,EAAI7Z,MAAMyK,QAASwkB,GAAMA,EAAEpoB,IAAIw7E,cAAe,GACvCxoE,GAGHypE,GAAgB,CAACvxD,EAAKwxD,EAAOtvC,KACjC,MAAM,UAAEjiB,EAAS,IAAE+xC,GAAQhyC,EACrB7Z,EAAM6Z,EAAI7Z,IAChB,IAAI,IAAE0vD,GAAQ71C,EAgCd,OA/BI61C,GAAoB,IAAbA,EAAI1nE,OAAe0nE,EAAI37D,QAAQ8N,SAEtC6tD,OAAM,GAGO,IAAb1vD,EAAIhY,MACNgY,EAAI2c,SAASnQ,QAAQ,KACrBxM,EAAI2c,SAASnY,KAAK,YACRxE,EAAIwsD,WACdxsD,EAAIjM,QAAUiM,EAAIjM,QAAU,GAAGiM,EAAIjM,gBAAkB,MAEnD+lB,EAAU3N,KAAMutD,GAAwB,UAAhBA,EAAI3lE,WACb,IAAbiM,EAAIhY,KACFgY,EAAIwsD,SACNxsD,EAAIjM,QAAU,EAASiM,EAAIjM,SAE3BiM,EAAIjM,QAAU,GAAGgoC,EAAQwjC,aAAa7U,OAAa1qD,EAAIjM,YAGzDiM,EAAI2c,SAASnQ,QAAQ,GAAGuvB,EAAQwjC,aAAa7U,QAC7C1qD,EAAI2c,SAASnY,KAAK,OAGjBu3B,EAAQiwB,QACPlyC,EAAU3N,KAAMutD,GAAwB,SAAhBA,EAAI3lE,UAC9Bu3E,GAAatrE,EAAK,KAEhB8Z,EAAU3N,KAAMutD,GAAwB,SAAhBA,EAAI3lE,UAC9Bu3E,GAAatrE,EAAK,MAGf,CACLlY,MAAO,CAACwkE,GAAqBtsD,EAAK0vD,MAGhC4b,GAAe,CAACtrE,EAAKurE,KACR,IAAbvrE,EAAIhY,KACFgY,EAAIwsD,SACNxsD,EAAIjM,QAAUw3E,EAASvrE,EAAIjM,QAE3BiM,EAAIjM,QAAU,KAAKw3E,OAAYvrE,EAAIjM,cAGrCiM,EAAI2c,SAASnQ,QAAQ,IAAI++D,UACzBvrE,EAAI2c,SAASnY,KAAK,OAIhBgnE,GAAgB,CAAC/sD,EAAMsd,KAC3B,GAAkB,IAAdtd,EAAKz2B,MAA4B,IAAdy2B,EAAKz2B,MAA4B,KAAdy2B,EAAKz2B,MAA6B,KAAdy2B,EAAKz2B,KACjE,MAAO,KACL,MAAM20B,EAAW8B,EAAK9B,SACtB,IAAIiB,EACA6tD,GAAU,EACd,IAAK,IAAI7tE,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACvB,GAAI2yD,GAASjyC,GAAQ,CACnBmtD,GAAU,EACV,IAAK,IAAIx3C,EAAIr2B,EAAI,EAAGq2B,EAAItX,EAASrvB,OAAQ2mC,IAAK,CAC5C,MAAMjuB,EAAO2W,EAASsX,GACtB,IAAIs8B,GAASvqD,GAUN,CACL4X,OAAmB,EACnB,KACF,CAZOA,IACHA,EAAmBjB,EAAS/e,GAAK8uD,GAC/B,CAACpuC,GACDA,EAAMutC,MAGVjuC,EAAiBjB,SAASnY,KAAK,MAAOwB,GACtC2W,EAASjuB,OAAOulC,EAAG,GACnBA,GAKJ,CACF,CACF,CACA,GAAKw3C,IAIe,IAApB9uD,EAASrvB,QAA+B,IAAdmxB,EAAKz2B,OAA4B,IAAdy2B,EAAKz2B,MAA+B,IAAjBy2B,EAAKiyC,SAKpEjyC,EAAK32B,MAAM0jB,KACTuL,GAAiB,IAAXA,EAAE/uB,OAAe+zC,EAAQoiC,oBAAoBpnD,EAAElvB,QAIzC,aAAb42B,EAAKw3B,MAGP,IAAK,IAAIr4C,EAAI,EAAGA,EAAI+e,EAASrvB,OAAQsQ,IAAK,CACxC,MAAM0gB,EAAQ3B,EAAS/e,GACvB,GAAI2yD,GAASjyC,IAAyB,IAAfA,EAAMt2B,KAAY,CACvC,MAAM0jF,EAAW,GACE,IAAfptD,EAAMt2B,MAAgC,MAAlBs2B,EAAMvqB,SAC5B23E,EAASlnE,KAAK8Z,GAEXyd,EAAQqxB,KAA2C,IAApCqP,GAAgBn+C,EAAOyd,IACzC2vC,EAASlnE,KACP,KAGJmY,EAAS/e,GAAK,CACZ5V,KAAM,GACN+L,QAASuqB,EACTutC,IAAKvtC,EAAMutC,IACXqN,YAAavM,GACX5wB,EAAQ+vB,OAAOrC,IACfiiB,GAGN,CACF,IAKAC,GAAyB,IAAIhmE,QAC7BimE,GAAgB,CAACntD,EAAMsd,KAC3B,GAAkB,IAAdtd,EAAKz2B,MAAckoE,GAAQzxC,EAAM,QAAQ,GAAO,CAClD,GAAIktD,GAAOxlE,IAAIsY,IAASsd,EAAQoT,SAAWpT,EAAQiwB,MACjD,OAKF,OAHA2f,GAAOj5E,IAAI+rB,GACXsd,EAAQoT,SAAU,EAClBpT,EAAQ+vB,OAAOjB,IACR,KACL9uB,EAAQoT,SAAU,EAClB,MAAMt5B,EAAMkmB,EAAQqjC,YAChBvpD,EAAIqjD,cACNrjD,EAAIqjD,YAAcn9B,EAAQ78B,MACxB2W,EAAIqjD,aACJ,GACA,IAIR,GAGI2S,GAAiB,CAAChyD,EAAK4E,EAAMsd,KACjC,MAAM,IAAE2zB,EAAG,IAAE1vD,GAAQ6Z,EACrB,IAAK61C,EAIH,OAHA3zB,EAAQrO,QACNmhC,GAAoB,GAAIh1C,EAAIgyC,MAEvBigB,KAET,MAAMC,EAASrc,EAAI7D,IAAIr5C,OAAO3Q,OACxBmqE,EAAyB,IAAbtc,EAAI1nE,KAAa0nE,EAAI37D,QAAUg4E,EAC3CE,EAAclwC,EAAQwiC,gBAAgBwN,GAC5C,GAAoB,UAAhBE,GAA2C,kBAAhBA,EAE7B,OADAlwC,EAAQrO,QAAQmhC,GAAoB,GAAIa,EAAI7D,MACrCigB,KAET,IAAKE,EAAUnqE,SAAW8tD,GAAmBD,GAI3C,OAHA3zB,EAAQrO,QACNmhC,GAAoB,GAAIa,EAAI7D,MAEvBigB,KAET,MAAMI,EAAWlsE,GAAYusD,GAAuB,cAAc,GAC5Due,EAAY9qE,EAAMkvD,GAAYlvD,GAAO,YAAY,EAASA,EAAIjM,WAAa24D,GAAyB,CAAC,iBAAkB1sD,IAAQ,sBACrI,IAAImsE,EAGFA,EAAgBzf,GAAyB,EAF1B3wB,EAAQ0iC,KAAO,gBAAkB,UAG9C,SACA/O,EACA,gBAGJ,MAAM5nE,EAAQ,CAEZwkE,GAAqB4f,EAAUryD,EAAI61C,KAEnCpD,GAAqBwe,EAAWqB,IAElC,GAAItyD,EAAIC,UAAUxsB,QAA2B,IAAjBmxB,EAAKiyC,QAAe,CAC9C,MAAM52C,EAAYD,EAAIC,UAAU9c,IAAKqiB,GAAMA,EAAEtrB,SAASiJ,IAAKqiB,IAAOgwC,GAAmBhwC,GAAKA,EAAIrc,KAAKC,UAAUoc,IAAM,UAAUxT,KAAK,MAC5HugE,EAAepsE,EAAMkvD,GAAYlvD,GAAO,GAAGA,EAAIjM,mBAAqB24D,GAAyB,CAAC1sD,EAAK,mBAAqB,iBAC9HlY,EAAM0c,KACJ8nD,GACE8f,EACA7f,GACE,KAAKzyC,OACL,EACAD,EAAIgyC,IACJ,IAIR,CACA,OAAOigB,GAAqBhkF,IAE9B,SAASgkF,GAAqBhkF,EAAQ,IACpC,MAAO,CAAEA,QACX,CAEA,MAAMukF,GAAsB,gBACtBC,GAAkB,CAAC7tD,EAAMsd,KACxByyB,GAAgB,mBAAoBzyB,KAGvB,IAAdtd,EAAKz2B,KACPukF,GAAc9tD,EAAK1qB,QAASgoC,GACL,IAAdtd,EAAKz2B,MACdy2B,EAAK32B,MAAMyK,QAASusC,IACA,IAAdA,EAAK92C,MAA4B,QAAd82C,EAAKj3C,MAAkBi3C,EAAK4wB,KACjD6c,GAAcztC,EAAK4wB,IAAK3zB,OAKhC,SAASwwC,GAAc9tD,EAAMsd,GAC3B,GAAkB,IAAdtd,EAAKz2B,KACPwkF,GAAY/tD,EAAMsd,QAElB,IAAK,IAAIn+B,EAAI,EAAGA,EAAI6gB,EAAK9B,SAASrvB,OAAQsQ,IAAK,CAC7C,MAAM0gB,EAAQG,EAAK9B,SAAS/e,GACP,iBAAV0gB,IACQ,IAAfA,EAAMt2B,KACRwkF,GAAYluD,EAAOyd,GACK,IAAfzd,EAAMt2B,KACfukF,GAAc9tD,EAAMsd,GACI,IAAfzd,EAAMt2B,MACfukF,GAAcjuD,EAAMvqB,QAASgoC,GAEjC,CAEJ,CACA,SAASywC,GAAY/tD,EAAMsd,GACzB,MAAM2zB,EAAMjxC,EAAK1qB,QACjB,IAQIqL,EAAG8I,EAAMtK,EAAG6uE,EARZC,GAAW,EACXC,GAAW,EACXC,GAAmB,EACnBC,GAAU,EACVC,EAAQ,EACRC,EAAS,EACTC,EAAQ,EACRC,EAAkB,EACM35B,EAAU,GACtC,IAAK11C,EAAI,EAAGA,EAAI8xD,EAAIpiE,OAAQsQ,IAG1B,GAFAsK,EAAO9I,EACPA,EAAIswD,EAAIpyD,WAAWM,GACf8uE,EACQ,KAANttE,GAAqB,KAAT8I,IAAawkE,GAAW,QACnC,GAAIC,EACC,KAANvtE,GAAqB,KAAT8I,IAAaykE,GAAW,QACnC,GAAIC,EACC,KAANxtE,GAAqB,KAAT8I,IAAa0kE,GAAmB,QAC3C,GAAIC,EACC,KAANztE,GAAqB,KAAT8I,IAAa2kE,GAAU,QAClC,GAAU,MAANztE,GACe,MAA1BswD,EAAIpyD,WAAWM,EAAI,IAAwC,MAA1B8xD,EAAIpyD,WAAWM,EAAI,IAAekvE,GAAUC,GAAWC,EAOjF,CACL,OAAQ5tE,GACN,KAAK,GACHutE,GAAW,EACX,MAEF,KAAK,GACHD,GAAW,EACX,MAEF,KAAK,GACHE,GAAmB,EACnB,MAEF,KAAK,GACHI,IACA,MAEF,KAAK,GACHA,IACA,MAEF,KAAK,GACHD,IACA,MAEF,KAAK,GACHA,IACA,MAEF,KAAK,IACHD,IACA,MAEF,KAAK,IACHA,IAGJ,GAAU,KAAN1tE,EAAU,CACZ,IACI2X,EADAkd,EAAIr2B,EAAI,EAEZ,KAAOq2B,GAAK,IACVld,EAAI24C,EAAIjwD,OAAOw0B,GACL,MAANld,GAFSkd,KAIVld,GAAMs1D,GAAoB96C,KAAKxa,KAClC81D,GAAU,EAEd,CACF,WAvDqB,IAAfJ,GACFQ,EAAkBrvE,EAAI,EACtB6uE,EAAa/c,EAAI/wD,MAAM,EAAGf,GAAGiE,QAE7BqrE,IA0DN,SAASA,IACP55B,EAAQ9uC,KAAKkrD,EAAI/wD,MAAMsuE,EAAiBrvE,GAAGiE,QAC3CorE,EAAkBrvE,EAAI,CACxB,CACA,QATmB,IAAf6uE,EACFA,EAAa/c,EAAI/wD,MAAM,EAAGf,GAAGiE,OACA,IAApBorE,GACTC,IAME55B,EAAQhmD,OAAQ,CAMlB,IAAKsQ,EAAI,EAAGA,EAAI01C,EAAQhmD,OAAQsQ,IAC9B6uE,EAAaU,GAAWV,EAAYn5B,EAAQ11C,GAAIm+B,GAElDtd,EAAK1qB,QAAU04E,EACfhuD,EAAK2uD,SAAM,CACb,CACF,CACA,SAASD,GAAWzd,EAAKnkD,EAAQwwB,GAC/BA,EAAQ+vB,OAAOhC,IACf,MAAMlsD,EAAI2N,EAAOtgB,QAAQ,KACzB,GAAI2S,EAAI,EAEN,OADAm+B,EAAQuX,QAAQ5gD,IAAI6Y,GACb,GAAG8lD,GAAe9lD,EAAQ,aAAamkD,KACzC,CACL,MAAM7nE,EAAO0jB,EAAO5M,MAAM,EAAGf,GACvBvF,EAAOkT,EAAO5M,MAAMf,EAAI,GAE9B,OADAm+B,EAAQuX,QAAQ5gD,IAAI7K,GACb,GAAGwpE,GAAexpE,EAAM,aAAa6nE,IAAe,MAATr3D,EAAe,IAAMA,EAAOA,GAChF,CACF,CAEA,MAAMwc,GAAuB,IAAIlP,QAC3B0nE,GAAgB,CAAC5uD,EAAMsd,KAC3B,GAAkB,IAAdtd,EAAKz2B,KAAY,CACnB,MAAM6xB,EAAMq2C,GAAQzxC,EAAM,QAC1B,IAAK5E,GAAOhF,GAAK1O,IAAIsY,IAASsd,EAAQiwB,MACpC,OAGF,OADAn3C,GAAKniB,IAAI+rB,GACF,KACL,MAAMy6C,EAAcz6C,EAAKy6C,aAAen9B,EAAQqjC,YAAYlG,YACxDA,GAAoC,KAArBA,EAAYlxE,OACR,IAAjBy2B,EAAKiyC,SACPrD,GAAe6L,EAAan9B,GAE9Btd,EAAKy6C,YAAcvM,GAAqB5wB,EAAQ+vB,OAAOX,IAAY,CACjEtxC,EAAI61C,IACJ7C,QAAyB,EAAQqM,GACjC,SACA1wE,OAAOuzC,EAAQ5L,OAAO7iC,UAExByuC,EAAQ5L,OAAO3rB,KAAK,OAG1B,GAGI8oE,GAA0B,CAAC7uD,EAAMsd,KACrC,GAAkB,IAAdtd,EAAKz2B,KACP,IAAK,MAAM82C,KAAQrgB,EAAK32B,MACtB,GAAkB,IAAdg3C,EAAK92C,MAA4B,SAAd82C,EAAKj3C,OAAoBi3C,EAAK4wB,IAAK,CACxD,MAAM1vD,EAAM8+B,EAAK9+B,IACjB,GAAiB,IAAbA,EAAIhY,MAAegY,EAAIwsD,SAQpB,CACL,MAAM0f,EAAW,EAASlsE,EAAIjM,UAC1Bu7D,GAAsB/9B,KAAK26C,EAAS,KACxB,MAAhBA,EAAS,MACPptC,EAAK4wB,IAAMnD,GAAuB2f,GAAU,EAAOlsE,EAAI6rD,KAE3D,MAbE9vB,EAAQrO,QACNmhC,GACE,GACA7uD,EAAI6rD,MAGR/sB,EAAK4wB,IAAMnD,GAAuB,IAAI,EAAMvsD,EAAI6rD,IAQpD,GA2BN,SAAS0hB,GAAY/6D,EAAQtX,EAAU,CAAC,GACtC,MAAMwyB,EAAUxyB,EAAQwyB,SAAWghC,GAC7B8e,EAAgC,WAAjBtyE,EAAQulB,MAEO,IAA9BvlB,EAAQ+2D,kBACVvkC,EAAQmhC,GAAoB,KACnB2e,GACT9/C,EAAQmhC,GAAoB,KAI5B3zD,EAAQ+iE,eACVvwC,EAAQmhC,GAAoB,KAE1B3zD,EAAQ05B,UAAY44C,GACtB9/C,EAAQmhC,GAAoB,KAE9B,MAAM4e,EAAkB,EAAO,CAAC,EAAGvyE,EAAS,CAC1C+2D,mBARwB,IAUpBmb,EAAM,EAAS56D,GA7jGvB,SAAmBwlD,EAAO98D,GAIxB,GAZA23D,GAAUzgC,QACVigC,GAAiB,KACjBC,GAAc,KACdC,GAAmB,GACnBC,IAAyB,EACzBC,IAAuB,EACvB,GAAMnlE,OAAS,EAIf8kE,GAAe4F,EACf9F,GAAiB,EAAO,CAAC,EAAGT,IACxBv2D,EAAS,CACX,IAAIvM,EACJ,IAAKA,KAAOuM,EACU,MAAhBA,EAAQvM,KACVujE,GAAevjE,GAAOuM,EAAQvM,GAGpC,CAQAkkE,GAAUpyC,KAAoC,SAA7ByxC,GAAeR,UAAuB,EAAiC,QAA7BQ,GAAeR,UAAsB,EAAI,EACpGmB,GAAUM,MAA8B,IAAtBjB,GAAeP,IAAkC,IAAtBO,GAAeP,GAC5D,MAAMhf,EAAaz3C,GAAWA,EAAQy3C,WAClCA,IACFkgB,GAAUQ,cAAgBxF,GAAYlb,EAAW,IACjDkgB,GAAUS,eAAiBzF,GAAYlb,EAAW,KAEpD,MAAMjd,EAAOy8B,GAn5Ef,SAAoBx1C,EAAUnK,EAAS,IACrC,MAAO,CACLxqB,KAAM,EACNwqB,SACAmK,SA+4EoC,GA94EpCgiD,QAAyB,IAAIlxD,IAC7BqtB,WAAY,GACZrhB,WAAY,GACZmlD,OAAQ,GACRC,QAAS,GACT1uC,OAAQ,GACR2uC,MAAO,EACP5F,iBAAa,EACbrN,IAAKP,GAET,CAo4E6BoiB,CAAW,EAAI1V,GAK1C,OAJAnF,GAAUkF,MAAM3F,IAChB18B,EAAKm2B,IAAMoN,GAAO,EAAGjB,EAAM1qE,QAC3BooC,EAAK/Y,SAAW0+C,GAAmB3lC,EAAK/Y,UACxCw1C,GAAc,KACPz8B,CACT,CA6hGiC,CAAUljB,EAAQi7D,GAAmBj7D,GAC7D0rD,EAAgBC,GA1ChB,CACL,CACEmP,GACA1B,GACAhJ,GACAyK,GACAvJ,GACIwI,GAEJ/B,GACApD,GACA9B,GACAmG,IAEF,CACEzmE,GAAI6lE,GACJ3hE,KAAMmiE,GACNuC,MAAO9B,KA0CX,OAhBA92E,GACEq4E,EACA,EAAO,CAAC,EAAGK,EAAiB,CAC1BvP,eAAgB,IACXA,KACAhjE,EAAQgjE,gBAAkB,IAG/BC,oBAAqB,EACnB,CAAC,EACDA,EACAjjE,EAAQijE,qBAAuB,CAAC,MAh6ExC,SAAkBiP,EAAKlyE,EAAU,CAAC,GAChC,MAAM6gC,EA7DR,SAA8BqxC,GAAK,KACjC3sD,EAAO,WAAU,kBACjBwxC,EAA6B,WAATxxC,EAAiB,UACrCmtD,GAAY,EAAK,SACjB9P,EAAW,oBAAmB,QAC9BlpC,EAAU,KAAI,gBACdi5C,GAAkB,EAAK,kBACvBC,EAAoB,MAAK,kBACzBC,EAAoB,MAAK,qBACzBC,EAAuB,sBAAqB,IAC5C5gB,GAAM,EAAK,KACXqR,GAAO,EAAK,MACZzS,GAAQ,IAER,MAAMjwB,EAAU,CACdtb,OACAwxC,oBACA2b,YACA9P,WACAlpC,UACAi5C,kBACAC,oBACAC,oBACAC,uBACA5gB,MACAqR,OACAzS,QACAx5C,OAAQ46D,EAAI56D,OACZs8C,KAAM,GACNtD,OAAQ,EACRD,KAAM,EACNE,OAAQ,EACR+W,YAAa,EACbd,MAAM,EACN1kE,SAAK,EACL8uD,OAAOn9D,GACE,IAAI08D,GAAc18D,KAE3B,IAAA6V,CAAKsqD,EAAM8E,GAAe,EAAen1C,GACvCsd,EAAQ+yB,MAAQA,CAClB,EACA,MAAAqS,GACEpU,IAAUhxB,EAAQymC,YACpB,EACA,QAAAnB,CAAS4M,GAAiB,GACpBA,IACAlyC,EAAQymC,YAEVzV,IAAUhxB,EAAQymC,YAEtB,EACA,OAAAzV,GACEA,EAAQhxB,EAAQymC,YAClB,GAEF,SAASzV,EAAQvsD,GACfu7B,EAAQv3B,KAAK,KAAO,KAAK0gE,OAAO1kE,GAAI,EACtC,CACA,OAAOu7B,CACT,CAEkBmyC,CAAqBd,EAAKlyE,GACtCA,EAAQizE,kBAAkBjzE,EAAQizE,iBAAiBpyC,GACvD,MAAM,KACJtb,EAAI,KACJjc,EAAI,kBACJytD,EAAiB,OACjBkP,EAAM,SACNE,EAAQ,QACRtU,EAAO,QACPn4B,EAAO,IACPw4B,GACErxB,EACE4iC,EAAUtzE,MAAMsL,KAAKy2E,EAAIzO,SACzByP,EAAazP,EAAQrxE,OAAS,EAC9B+gF,GAAgBpc,GAA8B,WAATxxC,EAyC3C,GAgCF,SAA6B2sD,EAAKrxC,GAChC,MAAM,IACJqxB,EAAG,kBACH6E,EAAiB,KACjBztD,EAAI,QACJuoD,EAAO,kBACPghB,EAAiB,kBACjBD,EAAiB,qBACjBE,GACEjyC,EACEuyC,EAAaR,EACbnP,EAAUtzE,MAAMsL,KAAKy2E,EAAIzO,SAC3BA,EAAQrxE,OAAS,IAEjBkX,EAAK,gBAAgB8pE,OACvB,GACMlB,EAAIxO,OAAOtxE,SAQbkX,EAAK,WAPiB,CACpB8kD,GACAC,GACAC,GACAC,GACAC,IACAn+C,OAAQugD,GAAW6S,EAAQhzD,SAASmgD,IAAS9uD,IAAI6jE,IAAah1D,KAAK,oBAEzE,GA0BJ,SAAmB+yD,EAAQ7iC,GACzB,IAAK6iC,EAAOtxE,OACV,OAEFyuC,EAAQ2lC,MAAO,EACf,MAAM,KAAEl9D,EAAI,QAAEuoD,GAAYhxB,EAC1BgxB,IACA,IAAK,IAAInvD,EAAI,EAAGA,EAAIghE,EAAOtxE,OAAQsQ,IAAK,CACtC,MAAM8xD,EAAMkP,EAAOhhE,GACf8xD,IACFlrD,EAAK,kBAAkB5G,EAAI,QAC3B2jE,GAAQ7R,EAAK3zB,GACbgxB,IAEJ,CACAhxB,EAAQ2lC,MAAO,CACjB,CAtCE6M,CAAUnB,EAAIxO,OAAQ7iC,GACtBgxB,IACAvoD,EAAK,UACP,CAtGIgqE,CAAoBpB,EAFErxC,GAQtBv3B,EAAK,YAJc4oD,EAAM,YAAc,aAC5BA,EAAM,CAAC,OAAQ,QAAS,UAAW,UAAY,CAAC,OAAQ,WAC9CvhD,KAAK,YAI5Bs1D,IACIkN,IACF7pE,EAAK,iBACL28D,IACIiN,IACF5pE,EACE,WAAWm6D,EAAQ3hE,IAAI6jE,IAAah1D,KAAK,oBAExC,GAEHkhD,MAGAqgB,EAAItyC,WAAWxtC,SACjBwzE,GAAUsM,EAAItyC,WAAY,YAAaiB,IACnCqxC,EAAI3zD,WAAWnsB,QAAU8/E,EAAItO,MAAQ,IACvC/R,KAGAqgB,EAAI3zD,WAAWnsB,SACjBwzE,GAAUsM,EAAI3zD,WAAY,YAAasiB,GACnCqxC,EAAItO,MAAQ,GACd/R,KAGAqgB,EAAI95B,SAAW85B,EAAI95B,QAAQhmD,SAC7By/D,IACA+T,GAAUsM,EAAI95B,QAAS,SAAUvX,GACjCgxB,KAEEqgB,EAAItO,MAAQ,EAAG,CACjBt6D,EAAK,QACL,IAAK,IAAI5G,EAAI,EAAGA,EAAIwvE,EAAItO,MAAOlhE,IAC7B4G,EAAK,GAAG5G,EAAI,EAAI,KAAO,UAAUA,IAErC,CAoBA,OAnBIwvE,EAAItyC,WAAWxtC,QAAU8/E,EAAI3zD,WAAWnsB,QAAU8/E,EAAItO,SACxDt6D,EAAK,KACN,GACCuoD,KAEGK,GACH5oD,EAAK,WAEH4oE,EAAIlU,YACNqI,GAAQ6L,EAAIlU,YAAan9B,GAEzBv3B,EAAK,QAEH6pE,IACFhN,IACA78D,EAAK,MAEP68D,IACA78D,EAAK,KACE,CACL4oE,MACAte,KAAM/yB,EAAQ+yB,KACd2f,SAAU,GACVzxE,IAAK++B,EAAQ/+B,IAAM++B,EAAQ/+B,IAAI0xE,cAAW,EAE9C,CA80ESC,CAASvB,EAAKK,EACvB,CAEA,MC7pLMmB,GAAgB/kE,OAAmE,IACnFglE,GAAmBhlE,OACwC,IAE3DilE,GAAejlE,OAAkE,IACjFklE,GAAiBllE,OACwC,IAEzDmlE,GAAkBnlE,OACwC,IAE1DolE,GAAsBplE,OACwC,IAE9DqlE,GAAiBrlE,OACwC,IAEzDslE,GAAStlE,OAA6D,IACtE,GAAaA,OAAkE,IAC/EulE,GAAmBvlE,OACyC,ID+FlE,IAAgC80D,GChFhC,IAAI0Q,GDgF4B1Q,GC7FT,CACrB,CAACiQ,IAAgB,cACjB,CAACC,IAAmB,iBACpB,CAACC,IAAe,aAChB,CAACC,IAAiB,eAClB,CAACC,IAAkB,gBACnB,CAACC,IAAsB,gBACvB,CAACC,IAAiB,WAClB,CAACC,IAAS,QACV,CAAC,IAAa,aACd,CAACC,IAAmB,mBDoFpB5kF,OAAOsqB,sBAAsB6pD,IAASpsE,QAASq3C,IAC7CyhB,GAAczhB,GAAK+0B,GAAQ/0B,KCpE/B,MAAM0lC,GAAgB,CACpB5d,UAAW,OACX1vD,UAAS,GACTm5B,YAAc8a,GAAQ,EAAUA,IAAQ,GAASA,IAAQ,GAAYA,GACrE4b,SAAW5b,GAAgB,QAARA,EACnB6b,mBAAqB7b,GAAgB,QAARA,GAAyB,aAARA,EAC9C6iB,eAnBF,SAA2BpuD,EAAK6kE,GAAS,GAIvC,OAHKF,KACHA,GAAUxiF,SAASgjC,cAAc,QAE/B0/C,GACFF,GAAQ92E,UAAY,aAAamS,EAAIrR,QAAQ,KAAM,cAC5Cg2E,GAAQ1yD,SAAS,GAAGoM,aAAa,SAExCsmD,GAAQ92E,UAAYmS,EACb2kE,GAAQpmD,YAEnB,EASEmyC,mBAAqBnlB,GACP,eAARA,GAAgC,eAARA,EACnB,GACU,oBAARA,GAAqC,qBAARA,EAC/Bm5B,QADF,EAKT,YAAAxd,CAAa3b,EAAK3xC,EAAQkrE,GACxB,IAAI7d,EAAKrtD,EAASA,EAAOqtD,GAAK6d,EAC9B,GAAIlrE,GAAiB,IAAPqtD,EACZ,GAAmB,mBAAfrtD,EAAO2xC,IAA0B,CACnC,GAAY,QAARA,EACF,OAAO,EAEL3xC,EAAOxc,MAAMqkB,KACdhK,GAAiB,IAAXA,EAAEna,MAAyB,aAAXma,EAAEta,MAAkC,MAAXsa,EAAE9K,QAAsC,cAApB8K,EAAE9K,MAAMtD,SAA+C,0BAApBoO,EAAE9K,MAAMtD,YAE/G49D,EAAK,EAET,KAAW,qBAAqBpgC,KAAKjtB,EAAO2xC,MAAgB,WAARA,GAA4B,eAARA,IACtE0b,EAAK,QAEErtD,GAAiB,IAAPqtD,IACA,kBAAfrtD,EAAO2xC,KAA0C,SAAf3xC,EAAO2xC,KAAiC,UAAf3xC,EAAO2xC,MACpE0b,EAAK,IAGT,GAAW,IAAPA,EAAU,CACZ,GAAY,QAAR1b,EACF,OAAO,EAET,GAAY,SAARA,EACF,OAAO,CAEX,CACA,OAAO0b,CACT,GAmBI8d,GAAiB,CAAC/tE,EAASmqD,KAC/B,MAAMxqD,EAAaC,EAAiBI,GACpC,OAAO6qD,GACLvpD,KAAKC,UAAU5B,IACf,EACAwqD,EACA,IAIJ,SAAS6jB,GAAuB5gB,EAAMjD,GACpC,OAAOgD,GACLC,EACAjD,EAGJ,CACA,MA6KM8jB,GAAwC,EAAQ,wBAChDC,GAAmC,EAEvC,sDAEIC,GAAmC,EAAQ,cAC3CC,GAAkC,EAAQ,gCA0C1CC,GAAiB,CAACphF,EAAK8G,IACLy5D,GAAYvgE,IAAsC,YAA9BA,EAAIoF,QAAQyL,cAC/B+sD,GAAuB92D,GAAO,GAAqB,IAAb9G,EAAI3G,KAAa0kE,GAAyB,CACrG,IACA/9D,EACA,sBAAsB8G,SACtB9G,EACA,MACGA,EAgGDqhF,GAAuB,CAACvxD,EAAMsd,KAChB,IAAdtd,EAAKz2B,MAA+B,IAAjBy2B,EAAKiyC,SAA+B,WAAbjyC,EAAKw3B,KAAiC,UAAbx3B,EAAKw3B,KAO1Ela,EAAQyjC,cAmLNyQ,GAAoB,CAjiBFxxD,IACJ,IAAdA,EAAKz2B,MACPy2B,EAAK32B,MAAMyK,QAAQ,CAACwkB,EAAGnZ,KACN,IAAXmZ,EAAE/uB,MAAyB,UAAX+uB,EAAElvB,MAAoBkvB,EAAE1f,QAC1ConB,EAAK32B,MAAM8V,GAAK,CACd5V,KAAM,EACNH,KAAM,OACNmY,IAAKusD,GAAuB,SAAS,EAAMx1C,EAAE80C,KAC7C6D,IAAK+f,GAAe14D,EAAE1f,MAAMtD,QAASgjB,EAAE80C,KACvC/xC,UAAW,GACX+xC,IAAK90C,EAAE80C,UA2hBXqkB,GAAyB,CAC7BC,MDoiK6B,KAAM,CAAGroF,MAAO,KCniK7CsoF,KA9dqB,CAACv2D,EAAK4E,EAAMsd,KACjC,MAAM,IAAE2zB,EAAG,IAAE7D,GAAQhyC,EAYrB,OAXK61C,GACH3zB,EAAQrO,QACNgiD,GAAuB,GAAI7jB,IAG3BptC,EAAK9B,SAASrvB,SAChByuC,EAAQrO,QACNgiD,GAAuB,GAAI7jB,IAE7BptC,EAAK9B,SAASrvB,OAAS,GAElB,CACLxF,MAAO,CACLwkE,GACEC,GAAuB,aAAa,EAAMV,GAC1C6D,GAAOnD,GAAuB,IAAI,OA8cxCz3D,KAxcqB,CAAC+kB,EAAK4E,EAAMsd,KACjC,MAAM,IAAE2zB,EAAG,IAAE7D,GAAQhyC,EAYrB,OAXK61C,GACH3zB,EAAQrO,QACNgiD,GAAuB,GAAI7jB,IAG3BptC,EAAK9B,SAASrvB,SAChByuC,EAAQrO,QACNgiD,GAAuB,GAAI7jB,IAE7BptC,EAAK9B,SAASrvB,OAAS,GAElB,CACLxF,MAAO,CACLwkE,GACEC,GAAuB,eAAe,GACtCmD,EAAM+M,GAAgB/M,EAAK3zB,GAAW,EAAI2zB,EAAM/C,GAC9C5wB,EAAQwjC,aAAapV,IACrB,CAACuF,GACD7D,GACEU,GAAuB,IAAI,OAobrCohB,MA9aqB,CAAC9zD,EAAK4E,EAAMsd,KACjC,MAAMs0C,EAAaxE,GAAiBhyD,EAAK4E,EAAMsd,GAC/C,IAAKs0C,EAAWvoF,MAAMwF,QAA2B,IAAjBmxB,EAAKiyC,QACnC,OAAO2f,EAELx2D,EAAI7Z,KACN+7B,EAAQrO,QACNgiD,GACE,GACA71D,EAAI7Z,IAAI6rD,MAed,MAAM,IAAE5V,GAAQx3B,EACV2K,EAAkB2S,EAAQ3S,gBAAgB6sB,GAChD,GAAY,UAARA,GAA2B,aAARA,GAA8B,WAARA,GAAoB7sB,EAAiB,CAChF,IAAIknD,EAAiBxB,GACjByB,GAAgB,EACpB,GAAY,UAARt6B,GAAmB7sB,EAAiB,CACtC,MAAMphC,EAAOooE,GAAS3xC,EAAM,QAC5B,GAAIz2B,GACF,GAAkB,IAAdA,EAAKA,KACPsoF,EAAiBtB,QACZ,GAAIhnF,EAAKqP,MACd,OAAQrP,EAAKqP,MAAMtD,SACjB,IAAK,QACHu8E,EAAiB1B,GACjB,MACF,IAAK,WACH0B,EAAiBzB,GACjB,MACF,IAAK,OACH0B,GAAgB,EAChBx0C,EAAQrO,QACNgiD,GACE,GACA71D,EAAIgyC,YDo9CtB,SAA4BptC,GAC1B,OAAOA,EAAK32B,MAAMqkB,KACf4K,KAAiB,IAAXA,EAAE/uB,MAAyB,SAAX+uB,EAAElvB,MAAqBkvB,EAAE/W,KACjC,IAAf+W,EAAE/W,IAAIhY,MACL+uB,EAAE/W,IAAIwsD,UAGX,ECl9CiBgkB,CAAmB/xD,KAC5B6xD,EAAiBtB,GAIrB,KAAmB,WAAR/4B,IACTq6B,EAAiBvB,IAIdwB,IACHF,EAAWvG,YAAc/tC,EAAQ+vB,OAAOwkB,GAE5C,MACEv0C,EAAQrO,QACNgiD,GACE,GACA71D,EAAIgyC,MAOV,OAHAwkB,EAAWvoF,MAAQuoF,EAAWvoF,MAAMyjB,OACjCwL,KAAuB,IAAfA,EAAEpoB,IAAI3G,MAAgC,eAAlB+uB,EAAEpoB,IAAIoF,UAE9Bs8E,GAgWPtrE,GAnSkB,CAAC8U,EAAK4E,EAAMsd,IACvB6uC,GAAc/wD,EAAK4E,EAAMsd,EAAUs0C,IACxC,MAAM,UAAEv2D,GAAcD,EACtB,IAAKC,EAAUxsB,OAAQ,OAAO+iF,EAC9B,IAAI,IAAE1hF,EAAK0I,MAAOo5E,GAAeJ,EAAWvoF,MAAM,GAClD,MAAM,aAAE4oF,EAAY,gBAAEC,EAAe,qBAAEC,GAxDlB,EAACjiF,EAAKmrB,EAAWiiB,KACxC,MAAM20C,EAAe,GACfC,EAAkB,GAClBC,EAAuB,GAC7B,IAAK,IAAIhzE,EAAI,EAAGA,EAAIkc,EAAUxsB,OAAQsQ,IAAK,CACzC,MAAM0qE,EAAWxuD,EAAUlc,GAAG7J,QACb,WAAbu0E,GAAyB7Z,GAC3B,uBACA1yB,IAIS4zC,GAAsBrH,GAD/BsI,EAAqBpsE,KAAK8jE,GAItBuH,GAAiBvH,GACfpZ,GAAYvgE,GACVmhF,GAAgBnhF,EAAIoF,QAAQyL,eAC9BkxE,EAAalsE,KAAK8jE,GAElBqI,EAAgBnsE,KAAK8jE,IAGvBoI,EAAalsE,KAAK8jE,GAClBqI,EAAgBnsE,KAAK8jE,IAGnBsH,GAAiBtH,GACnBqI,EAAgBnsE,KAAK8jE,GAErBoI,EAAalsE,KAAK8jE,EAI1B,CACA,MAAO,CACLoI,eACAC,kBACAC,yBAkBgEC,CAAiBliF,EAAKmrB,EAAWiiB,EAASliB,EAAIgyC,KAoB9G,GAnBI8kB,EAAgBhlE,SAAS,WAC3Bhd,EAAMohF,GAAephF,EAAK,kBAExBgiF,EAAgBhlE,SAAS,YAC3Bhd,EAAMohF,GAAephF,EAAK,cAExBgiF,EAAgBrjF,SAClBmjF,EAAa9jB,GAAqB5wB,EAAQ+vB,OAAOmjB,IAAsB,CACrEwB,EACAztE,KAAKC,UAAU0tE,OAGfD,EAAapjF,QACf4hE,GAAYvgE,KAAQmhF,GAAgBnhF,EAAIoF,QAAQyL,iBAChDixE,EAAa9jB,GAAqB5wB,EAAQ+vB,OAAOojB,IAAiB,CAChEuB,EACAztE,KAAKC,UAAUytE,MAGfE,EAAqBtjF,OAAQ,CAC/B,MAAMwjF,EAAkBF,EAAqB5zE,IAAI,GAAY6O,KAAK,IAClEld,EAAMugE,GAAYvgE,GAAO49D,GAAuB,GAAG59D,EAAIoF,UAAU+8E,KAAmB,GAAQpkB,GAAyB,CAAC,IAAK/9D,EAAK,QAAQmiF,MAC1I,CACA,MAAO,CACLhpF,MAAO,CAACwkE,GAAqB39D,EAAK8hF,OAuQtCvgF,KAlQoB,CAAC2pB,EAAK4E,EAAMsd,KAChC,MAAM,IAAE2zB,EAAG,IAAE7D,GAAQhyC,EAMrB,OALK61C,GACH3zB,EAAQrO,QACNgiD,GAAuB,GAAI7jB,IAGxB,CACL/jE,MAAO,GACPgiF,YAAa/tC,EAAQ+vB,OAAOqjB,OCzY1B4B,GAA+BvmF,OAAOyS,OAAO,MACnD,SAAS+zE,GAAkBt+B,EAAUx3C,GACnC,IAAK,EAASw3C,GAAW,CACvB,IAAIA,EAASvzB,SAIX,OAAO,EAHPuzB,EAAWA,EAASn6C,SAKxB,CACA,MAAM5J,ENiFR,SAAqB6jB,EAAQtX,GAC3B,OAAOsX,EAASxP,KAAKC,UACnB/H,EACA,CAACy5B,EAAG19B,IAAuB,mBAARA,EAAqBA,EAAIyH,WAAazH,EAE7D,CMtFcg6E,CAAYv+B,EAAUx3C,GAC5Bi1B,EAAS4gD,GAAapiF,GAC5B,GAAIwhC,EACF,OAAOA,EAET,GAAoB,MAAhBuiB,EAAS,GAAY,CACvB,MAAM/0C,EAAK9Q,SAASiN,cAAc44C,GAIlCA,EAAW/0C,EAAKA,EAAGpF,UAAY,EACjC,CACA,MAAM+yB,EAAO,EACX,CACEyyC,aAAa,EACbrwC,aAA+D,EAC/DqkC,OAA8E,GAEhF72D,GAEGowB,EAAKlC,iBAA6C,oBAAnB8nD,iBAClC5lD,EAAKlC,gBAAmB6sB,KAAUi7B,eAAe3kF,IAAI0pD,IAEvD,MAAM,KAAE6Y,GDmmBV,SAAiB5kE,EAAKgR,EAAU,CAAC,GAC/B,OAAOqyE,GACLrjF,EACA,EAAO,CAAC,EAAGolF,GAAep0E,EAAS,CACjCgjE,eAAgB,CAId8R,MACGC,MACA/0E,EAAQgjE,gBAAkB,IAE/BC,oBAAqB,EACnB,CAAC,EACD+R,GACAh1E,EAAQijE,qBAAuB,CAAC,GAElChB,eAAgB,OAGtB,CCvnBmB,CAAQzqB,EAAUpnB,GAW7BsQ,EAAS,IAAIrb,SAAS,MAAOuuC,EAApB,CAA0B,GAEzC,OADAlzB,EAAO4W,KAAM,EACNu+B,GAAapiF,GAAOitC,CAC7B,CACA0W,GAAwB0+B,G,6BC1DxB,SAAS/nE,EAAKhK,EAAImM,GAChB,OAAO,WACL,OAAOnM,EAAGoM,MAAMD,EAASE,UAC3B,CACF,CAIA,MAAM,SAAC5M,GAAYlU,OAAOqT,WACpB,eAACwQ,GAAkB7jB,QACnB,SAACwgB,EAAQ,YAAEqjB,GAAexkB,OAE1BsnE,GAAUjyE,EAGb1U,OAAOyS,OAAO,MAHQm0E,IACrB,MAAMr0E,EAAM2B,EAASV,KAAKozE,GAC1B,OAAOlyE,EAAMnC,KAASmC,EAAMnC,GAAOA,EAAI4B,MAAM,GAAI,GAAGa,iBAFzC,IAACN,EAKhB,MAAMmyE,EAAcrpF,IAClBA,EAAOA,EAAKwX,cACJ4xE,GAAUD,EAAOC,KAAWppF,GAGhCspF,EAAatpF,GAAQopF,UAAgBA,IAAUppF,GAS/C,QAACiW,GAAW5S,MASZkmF,EAAcD,EAAW,aAS/B,SAASE,EAASv6E,GAChB,OAAe,OAARA,IAAiBs6E,EAAYt6E,IAA4B,OAApBA,EAAI8M,cAAyBwtE,EAAYt6E,EAAI8M,cACpF0tE,EAAax6E,EAAI8M,YAAYytE,WAAav6E,EAAI8M,YAAYytE,SAASv6E,EAC1E,CASA,MAAMy6E,EAAgBL,EAAW,eA2B3BM,EAAWL,EAAW,UAQtBG,EAAeH,EAAW,YAS1BM,EAAWN,EAAW,UAStBO,EAAYT,GAAoB,OAAVA,GAAmC,iBAAVA,EAiB/CxyE,EAAiB3H,IACrB,GAAoB,WAAhBk6E,EAAOl6E,GACT,OAAO,EAGT,MAAM4G,EAAYwQ,EAAepX,GACjC,QAAsB,OAAd4G,GAAsBA,IAAcrT,OAAOqT,WAAkD,OAArCrT,OAAO6jB,eAAexQ,IAA0BwwB,KAAep3B,GAAU+T,KAAY/T,IA+BjJoH,EAASgzE,EAAW,QASpBS,EAAST,EAAW,QASpBU,EAASV,EAAW,QASpBW,EAAaX,EAAW,YAsCxBY,EAAoBZ,EAAW,oBAE9Ba,EAAkBC,EAAWC,EAAYC,GAAa,CAAC,iBAAkB,UAAW,WAAY,WAAWr1E,IAAIq0E,GA2BtH,SAAS9+E,EAAQ2N,EAAKjB,GAAI,WAACqzE,GAAa,GAAS,CAAC,GAEhD,GAAIpyE,QACF,OAGF,IAAItC,EACA+G,EAQJ,GALmB,iBAARzE,IAETA,EAAM,CAACA,IAGLjC,EAAQiC,GAEV,IAAKtC,EAAI,EAAG+G,EAAIzE,EAAI5S,OAAQsQ,EAAI+G,EAAG/G,IACjCqB,EAAGjB,KAAK,KAAMkC,EAAItC,GAAIA,EAAGsC,OAEtB,CAEL,GAAIsxE,EAAStxE,GACX,OAIF,MAAMwC,EAAO4vE,EAAa9nF,OAAOkjB,oBAAoBxN,GAAO1V,OAAOkY,KAAKxC,GAClEymC,EAAMjkC,EAAKpV,OACjB,IAAIqB,EAEJ,IAAKiP,EAAI,EAAGA,EAAI+oC,EAAK/oC,IACnBjP,EAAM+T,EAAK9E,GACXqB,EAAGjB,KAAK,KAAMkC,EAAIvR,GAAMA,EAAKuR,EAEjC,CACF,CAEA,SAASqyE,EAAQryE,EAAKvR,GACpB,GAAI6iF,EAAStxE,GACX,OAAO,KAGTvR,EAAMA,EAAI6Q,cACV,MAAMkD,EAAOlY,OAAOkY,KAAKxC,GACzB,IACIiD,EADAvF,EAAI8E,EAAKpV,OAEb,KAAOsQ,KAAM,GAEX,GADAuF,EAAOT,EAAK9E,GACRjP,IAAQwU,EAAK3D,cACf,OAAO2D,EAGX,OAAO,IACT,CAEA,MAAMqvE,EAEsB,oBAAfxxE,WAAmCA,WACvB,oBAATC,KAAuBA,KAA0B,oBAAX3S,OAAyBA,OAAS,EAAA4S,EAGlFuxE,EAAoB12C,IAAaw1C,EAAYx1C,IAAYA,IAAYy2C,EAkLrEE,GAAgBC,EAKG,oBAAfnlB,YAA8Bn/C,EAAem/C,YAH9C4jB,GACEuB,GAAcvB,aAAiBuB,GAHrB,IAACA,EAetB,MAiCMC,EAAavB,EAAW,mBAWxBvzE,EAAiB,GAAGA,oBAAoB,CAACoC,EAAK4+B,IAAShhC,EAAeE,KAAKkC,EAAK4+B,GAA/D,CAAsEt0C,OAAOqT,WAS9Fg1E,EAAWxB,EAAW,UAEtByB,EAAoB,CAAC5yE,EAAK6yE,KAC9B,MAAMC,EAAcxoF,OAAOyoF,0BAA0B/yE,GAC/CgzE,EAAqB,CAAC,EAE5B3gF,EAAQygF,EAAa,CAACn8C,EAAYhvC,KAChC,IAAI8Z,GAC2C,KAA1CA,EAAMoxE,EAAQl8C,EAAYhvC,EAAMqY,MACnCgzE,EAAmBrrF,GAAQ8Z,GAAOk1B,KAItCrsC,OAAO2oF,iBAAiBjzE,EAAKgzE,IAuGzBE,EAAY/B,EAAW,iBAQvBgC,GAAkBC,EAkBE,mBAAjBC,aAlBsCC,EAmB7C/B,EAAae,EAAQiB,aAlBjBH,EACKC,aAGFC,GAAyBE,EAW7B,SAAShuC,KAAKiuC,WAXsBC,EAWV,GAV3BpB,EAAQzlF,iBAAiB,UAAW,EAAEylB,SAAQ7pB,WACxC6pB,IAAWggE,GAAW7pF,IAAS+qF,GACjCE,EAAUtmF,QAAUsmF,EAAU1nE,OAAV0nE,KAErB,GAEK97D,IACN87D,EAAUpvE,KAAKsT,GACf06D,EAAQiB,YAAYC,EAAO,OAEK57D,GAAOkT,WAAWlT,IAhBlC,IAAEw7D,EAAuBE,EAKbE,EAAOE,EAiBzC,MAAMC,EAAiC,oBAAnBC,eAClBA,eAAe7qE,KAAKupE,GAAgC,oBAAZn3D,SAA2BA,QAAQvE,UAAYu8D,EAQzF,IAAIU,EAAU,CACZ91E,UACAyzE,gBACAF,WACAwC,WApgBkB5C,IAClB,IAAI6C,EACJ,OAAO7C,IACgB,mBAAb8C,UAA2B9C,aAAiB8C,UAClDzC,EAAaL,EAAM+C,UACU,cAA1BF,EAAO9C,EAAOC,KAEL,WAAT6C,GAAqBxC,EAAaL,EAAM1yE,WAAkC,sBAArB0yE,EAAM1yE,cA8flE01E,kBAnpBF,SAA2Bn9E,GACzB,IAAI4V,EAMJ,OAJEA,EAD0B,oBAAhBwnE,aAAiCA,YAAkB,OACpDA,YAAYC,OAAOr9E,GAEnB,GAAUA,EAAU,QAAMy6E,EAAcz6E,EAAIohB,QAEhDxL,CACT,EA4oBE8kE,WACAC,WACAt1B,UAnmBgB80B,IAAmB,IAAVA,IAA4B,IAAVA,EAomB3CS,WACAjzE,gBACA21E,cA7kBqBt9E,IAErB,IAAK46E,EAAS56E,IAAQu6E,EAASv6E,GAC7B,OAAO,EAGT,IACE,OAAmC,IAA5BzM,OAAOkY,KAAKzL,GAAK3J,QAAgB9C,OAAO6jB,eAAepX,KAASzM,OAAOqT,SAChF,CAAE,MAAO5R,GAEP,OAAO,CACT,GAmkBAimF,mBACAC,YACAC,aACAC,YACAd,cACAlzE,SACAyzE,SACAC,SACAc,WACA2B,WAAY/C,EACZgD,SA/hBgBx9E,GAAQ46E,EAAS56E,IAAQw6E,EAAax6E,EAAIy9E,MAgiB1DzC,oBACAS,eACAV,aACAz/E,UACAoiF,MAxZF,SAASA,IACP,MAAM,SAACC,EAAQ,cAAEC,GAAiBpC,EAAiB5oF,OAASA,MAAQ,CAAC,EAC/DgjB,EAAS,CAAC,EACVioE,EAAc,CAAC79E,EAAKtI,KACxB,MAAMomF,EAAYH,GAAYrC,EAAQ1lE,EAAQle,IAAQA,EAClDiQ,EAAciO,EAAOkoE,KAAen2E,EAAc3H,GACpD4V,EAAOkoE,GAAaJ,EAAM9nE,EAAOkoE,GAAY99E,GACpC2H,EAAc3H,GACvB4V,EAAOkoE,GAAaJ,EAAM,CAAC,EAAG19E,GACrBgH,EAAQhH,GACjB4V,EAAOkoE,GAAa99E,EAAI0H,QACdk2E,GAAkBtD,EAAYt6E,KACxC4V,EAAOkoE,GAAa99E,IAIxB,IAAK,IAAI2G,EAAI,EAAG+G,EAAI2G,UAAUhe,OAAQsQ,EAAI+G,EAAG/G,IAC3C0N,UAAU1N,IAAMrL,EAAQ+Y,UAAU1N,GAAIk3E,GAExC,OAAOjoE,CACT,EAqYEmoE,OAzXa,CAAC7yE,EAAGC,EAAGgJ,GAAUknE,cAAa,CAAC,KAC5C//E,EAAQ6P,EAAG,CAACnL,EAAKtI,KACXyc,GAAWqmE,EAAax6E,GAC1BkL,EAAExT,GAAOsa,EAAKhS,EAAKmU,GAEnBjJ,EAAExT,GAAOsI,GAEV,CAACq7E,eACGnwE,GAkXPN,KA9fY9E,GAAQA,EAAI8E,KACxB9E,EAAI8E,OAAS9E,EAAI1D,QAAQ,qCAAsC,IA8f/D47E,SAzWgBlhF,IACc,QAA1BA,EAAQuJ,WAAW,KACrBvJ,EAAUA,EAAQ4K,MAAM,IAEnB5K,GAsWPmhF,SA1Ve,CAACnxE,EAAaoxE,EAAkBrtF,EAAOkrF,KACtDjvE,EAAYlG,UAAYrT,OAAOyS,OAAOk4E,EAAiBt3E,UAAWm1E,GAClEjvE,EAAYlG,UAAUkG,YAAcA,EACpCvZ,OAAO4V,eAAe2D,EAAa,QAAS,CAC1C1M,MAAO89E,EAAiBt3E,YAE1B/V,GAAS0C,OAAOiT,OAAOsG,EAAYlG,UAAW/V,IAqV9CstF,aAzUmB,CAACC,EAAWC,EAAS/pE,EAAQgqE,KAChD,IAAIztF,EACA8V,EACAkhC,EACJ,MAAM/D,EAAS,CAAC,EAIhB,GAFAu6C,EAAUA,GAAW,CAAC,EAEL,MAAbD,EAAmB,OAAOC,EAE9B,EAAG,CAGD,IAFAxtF,EAAQ0C,OAAOkjB,oBAAoB2nE,GACnCz3E,EAAI9V,EAAMwF,OACHsQ,KAAM,GACXkhC,EAAOh3C,EAAM8V,GACP23E,IAAcA,EAAWz2C,EAAMu2C,EAAWC,IAAcv6C,EAAO+D,KACnEw2C,EAAQx2C,GAAQu2C,EAAUv2C,GAC1B/D,EAAO+D,IAAQ,GAGnBu2C,GAAuB,IAAX9pE,GAAoB8C,EAAegnE,EACjD,OAASA,KAAe9pE,GAAUA,EAAO8pE,EAAWC,KAAaD,IAAc7qF,OAAOqT,WAEtF,OAAOy3E,GAmTPnE,SACAE,aACAhoD,SAzSe,CAACtsB,EAAKy4E,EAAcC,KACnC14E,EAAMvU,OAAOuU,SACIjM,IAAb2kF,GAA0BA,EAAW14E,EAAIzP,UAC3CmoF,EAAW14E,EAAIzP,QAEjBmoF,GAAYD,EAAaloF,OACzB,MAAMgkC,EAAYv0B,EAAI9R,QAAQuqF,EAAcC,GAC5C,OAAsB,IAAfnkD,GAAoBA,IAAcmkD,GAmSzCC,QAxRetE,IACf,IAAKA,EAAO,OAAO,KACnB,GAAInzE,EAAQmzE,GAAQ,OAAOA,EAC3B,IAAIxzE,EAAIwzE,EAAM9jF,OACd,IAAKskF,EAASh0E,GAAI,OAAO,KACzB,MAAMF,EAAM,IAAIrS,MAAMuS,GACtB,KAAOA,KAAM,GACXF,EAAIE,GAAKwzE,EAAMxzE,GAEjB,OAAOF,GAgRPi4E,aArPmB,CAACz1E,EAAKjB,KACzB,MAEM22E,GAFY11E,GAAOA,EAAI8K,IAEDhN,KAAKkC,GAEjC,IAAI2M,EAEJ,MAAQA,EAAS+oE,EAAU5vE,UAAY6G,EAAOC,MAAM,CAClD,MAAM+oE,EAAOhpE,EAAOxV,MACpB4H,EAAGjB,KAAKkC,EAAK21E,EAAK,GAAIA,EAAK,GAC7B,GA4OAC,SAjOe,CAACC,EAAQh5E,KACxB,IAAI0vB,EACJ,MAAM/uB,EAAM,GAEZ,KAAwC,QAAhC+uB,EAAUspD,EAAOC,KAAKj5E,KAC5BW,EAAI8G,KAAKioB,GAGX,OAAO/uB,GA0NPk1E,aACA90E,iBACAm4E,WAAYn4E,EACZg1E,oBACAoD,cAjLqBh2E,IACrB4yE,EAAkB5yE,EAAK,CAAC22B,EAAYhvC,KAElC,GAAI4pF,EAAavxE,KAA6D,IAArD,CAAC,YAAa,SAAU,UAAUjV,QAAQpD,GACjE,OAAO,EAGT,MAAMwP,EAAQ6I,EAAIrY,GAEb4pF,EAAap6E,KAElBw/B,EAAWv2B,YAAa,EAEpB,aAAcu2B,EAChBA,EAAW12B,UAAW,EAInB02B,EAAW5sB,MACd4sB,EAAW5sB,IAAM,KACf,MAAMgkB,MAAM,qCAAwCpmC,EAAO,WA8JjEsuF,YAxJkB,CAACC,EAAezrF,KAClC,MAAMuV,EAAM,CAAC,EAEPm2E,EAAU34E,IACdA,EAAInL,QAAQ8E,IACV6I,EAAI7I,IAAS,KAMjB,OAFA4G,EAAQm4E,GAAiBC,EAAOD,GAAiBC,EAAO7tF,OAAO4tF,GAAevrF,MAAMF,IAE7EuV,GA8IPo2E,YA1NkBv5E,GACXA,EAAIyC,cAAcnG,QAAQ,wBAC/B,SAAkBgmB,EAAGk3D,EAAIC,GACvB,OAAOD,EAAGl3E,cAAgBm3E,CAC5B,GAuNFC,KA5IW,OA6IXC,eA3IqB,CAACr/E,EAAOwc,IACb,MAATxc,GAAiBuJ,OAAO+C,SAAStM,GAASA,GAASA,EAAQwc,EA2IlE0+D,UACAoE,OAAQnE,EACRC,mBACAmE,oBAlIF,SAA6BxF,GAC3B,SAAUA,GAASK,EAAaL,EAAM+C,SAAkC,aAAvB/C,EAAM/iD,IAA+B+iD,EAAMpmE,GAC9F,EAiIE6rE,aA/HoB32E,IACpB,MAAM8U,EAAQ,IAAI3pB,MAAM,IAElByrF,EAAQ,CAACtkE,EAAQ5U,KAErB,GAAIi0E,EAASr/D,GAAS,CACpB,GAAIwC,EAAM/pB,QAAQunB,IAAW,EAC3B,OAIF,GAAIg/D,EAASh/D,GACX,OAAOA,EAGT,KAAK,WAAYA,GAAS,CACxBwC,EAAMpX,GAAK4U,EACX,MAAMxlB,EAASiR,EAAQuU,GAAU,GAAK,CAAC,EASvC,OAPAjgB,EAAQigB,EAAQ,CAACnb,EAAO1I,KACtB,MAAMooF,EAAeD,EAAMz/E,EAAOuG,EAAI,IACrC2zE,EAAYwF,KAAkB/pF,EAAO2B,GAAOooF,KAG/C/hE,EAAMpX,QAAK9M,EAEJ9D,CACT,CACF,CAEA,OAAOwlB,GAGT,OAAOskE,EAAM52E,EAAK,IA+FlBkzE,YACA4D,WA3FkB5F,GAClBA,IAAUS,EAAST,IAAUK,EAAaL,KAAWK,EAAaL,EAAM5kF,OAASilF,EAAaL,EAAM5yE,OA2FpG+0E,aAAcF,EACdQ,OACAoD,WA5DkB7F,GAAmB,MAATA,GAAiBK,EAAaL,EAAMpmE,KA0ElE,SAASksE,EAAWjb,EAASnN,EAAMl5C,EAAQuhE,EAAS1qF,GAClDwhC,MAAMjwB,KAAKnU,MAEPokC,MAAMmpD,kBACRnpD,MAAMmpD,kBAAkBvtF,KAAMA,KAAKka,aAEnCla,KAAKmrB,OAAQ,IAAKiZ,OAASjZ,MAG7BnrB,KAAKoyE,QAAUA,EACfpyE,KAAKhC,KAAO,aACZinE,IAASjlE,KAAKilE,KAAOA,GACrBl5C,IAAW/rB,KAAK+rB,OAASA,GACzBuhE,IAAYttF,KAAKstF,QAAUA,GACvB1qF,IACF5C,KAAK4C,SAAWA,EAChB5C,KAAK+L,OAASnJ,EAASmJ,OAASnJ,EAASmJ,OAAS,KAEtD,CAEAm+E,EAAQmB,SAASgC,EAAYjpD,MAAO,CAClCygD,OAAQ,WACN,MAAO,CAELzS,QAASpyE,KAAKoyE,QACdp0E,KAAMgC,KAAKhC,KAEXiI,YAAajG,KAAKiG,YAClBq7C,OAAQthD,KAAKshD,OAEbksC,SAAUxtF,KAAKwtF,SACfC,WAAYztF,KAAKytF,WACjBC,aAAc1tF,KAAK0tF,aACnBviE,MAAOnrB,KAAKmrB,MAEZY,OAAQm+D,EAAQ8C,aAAahtF,KAAK+rB,QAClCk5C,KAAMjlE,KAAKilE,KACXl5D,OAAQ/L,KAAK+L,OAEjB,IAGF,MAAM4hF,EAAcN,EAAWr5E,UACzBm1E,EAAc,CAAC,EA6DrB,SAASyE,EAAYrG,GACnB,OAAO2C,EAAQn1E,cAAcwyE,IAAU2C,EAAQ91E,QAAQmzE,EACzD,CASA,SAASsG,EAAe/oF,GACtB,OAAOolF,EAAQ1qD,SAAS16B,EAAK,MAAQA,EAAIgQ,MAAM,GAAI,GAAKhQ,CAC1D,CAWA,SAASgpF,EAAUxtC,EAAMx7C,EAAKipF,GAC5B,OAAKztC,EACEA,EAAKl/B,OAAOtc,GAAKqO,IAAI,SAAc02E,EAAO91E,GAG/C,OADA81E,EAAQgE,EAAehE,IACfkE,GAAQh6E,EAAI,IAAM81E,EAAQ,IAAMA,CAC1C,GAAG7nE,KAAK+rE,EAAO,IAAM,IALHjpF,CAMpB,CA1FA,CACE,uBACA,iBACA,eACA,YACA,cACA,4BACA,iBACA,mBACA,kBACA,eACA,kBACA,mBAEA4D,QAAQu8D,IACRkkB,EAAYlkB,GAAQ,CAACz3D,MAAOy3D,KAG9BtkE,OAAO2oF,iBAAiB+D,EAAYlE,GACpCxoF,OAAO4V,eAAeo3E,EAAa,eAAgB,CAACngF,OAAO,IAG3D6/E,EAAWvgF,KAAO,CAAC2B,EAAOw2D,EAAMl5C,EAAQuhE,EAAS1qF,EAAUorF,KACzD,MAAMC,EAAattF,OAAOyS,OAAOu6E,GAEjCzD,EAAQqB,aAAa98E,EAAOw/E,EAAY,SAAgB53E,GACtD,OAAOA,IAAQ+tB,MAAMpwB,SACvB,EAAGihC,GACe,iBAATA,GAGT,MAAM8vB,EAAMt2D,GAASA,EAAM2jE,QAAU3jE,EAAM2jE,QAAU,QAG/C8b,EAAkB,MAARjpB,GAAgBx2D,EAAQA,EAAMw2D,KAAOA,EAYrD,OAXAooB,EAAWl5E,KAAK85E,EAAYlpB,EAAKmpB,EAASniE,EAAQuhE,EAAS1qF,GAGvD6L,GAA6B,MAApBw/E,EAAWE,OACtBxtF,OAAO4V,eAAe03E,EAAY,QAAS,CAAEzgF,MAAOiB,EAAO+H,cAAc,IAG3Ey3E,EAAWjwF,KAAQyQ,GAASA,EAAMzQ,MAAS,QAE3CgwF,GAAertF,OAAOiT,OAAOq6E,EAAYD,GAElCC,GAyDT,MAAMG,GAAalE,EAAQqB,aAAarB,EAAS,CAAC,EAAG,KAAM,SAAgBj1C,GACzE,MAAO,WAAWvN,KAAKuN,EACzB,GAyBA,SAASo5C,GAAWh4E,EAAKi4E,EAAUj9E,GACjC,IAAK64E,EAAQlC,SAAS3xE,GACpB,MAAM,IAAIk4E,UAAU,4BAItBD,EAAWA,GAAY,IAAI,SAY3B,MAAME,GATNn9E,EAAU64E,EAAQqB,aAAal6E,EAAS,CACtCm9E,YAAY,EACZT,MAAM,EACNU,SAAS,IACR,EAAO,SAAiB5zB,EAAQlyC,GAEjC,OAAQuhE,EAAQxC,YAAY/+D,EAAOkyC,GACrC,IAE2B2zB,WAErBE,EAAUr9E,EAAQq9E,SAAWC,EAC7BZ,EAAO18E,EAAQ08E,KACfU,EAAUp9E,EAAQo9E,QAElBG,GADQv9E,EAAQw9E,MAAwB,oBAATA,MAAwBA,OACpC3E,EAAQ6C,oBAAoBuB,GAErD,IAAKpE,EAAQS,WAAW+D,GACtB,MAAM,IAAIH,UAAU,8BAGtB,SAASO,EAAathF,GACpB,GAAc,OAAVA,EAAgB,MAAO,GAE3B,GAAI08E,EAAQ11E,OAAOhH,GACjB,OAAOA,EAAMuhF,cAGf,GAAI7E,EAAQz3B,UAAUjlD,GACpB,OAAOA,EAAMqH,WAGf,IAAK+5E,GAAW1E,EAAQhC,OAAO16E,GAC7B,MAAM,IAAI6/E,EAAW,gDAGvB,OAAInD,EAAQrC,cAAcr6E,IAAU08E,EAAQrB,aAAar7E,GAChDohF,GAA2B,mBAATC,KAAsB,IAAIA,KAAK,CAACrhF,IAAUwhF,OAAOliF,KAAKU,GAG1EA,CACT,CAYA,SAASmhF,EAAenhF,EAAO1I,EAAKw7C,GAClC,IAAIzsC,EAAMrG,EAEV,GAAIA,IAAU8yC,GAAyB,iBAAV9yC,EAC3B,GAAI08E,EAAQ1qD,SAAS16B,EAAK,MAExBA,EAAM0pF,EAAa1pF,EAAMA,EAAIgQ,MAAM,GAAI,GAEvCtH,EAAQ2L,KAAKC,UAAU5L,QAClB,GACJ08E,EAAQ91E,QAAQ5G,IAvGzB,SAAqBqG,GACnB,OAAOq2E,EAAQ91E,QAAQP,KAASA,EAAIyO,KAAKsrE,EAC3C,CAqGmCqB,CAAYzhF,KACrC08E,EAAQ/B,WAAW36E,IAAU08E,EAAQ1qD,SAAS16B,EAAK,SAAW+O,EAAMq2E,EAAQ2B,QAAQr+E,IAYtF,OATA1I,EAAM+oF,EAAe/oF,GAErB+O,EAAInL,QAAQ,SAAcoL,EAAIlP,IAC1BslF,EAAQxC,YAAY5zE,IAAc,OAAPA,GAAgBw6E,EAAShE,QAExC,IAAZmE,EAAmBX,EAAU,CAAChpF,GAAMF,EAAOmpF,GAAqB,OAAZU,EAAmB3pF,EAAMA,EAAM,KACnFgqF,EAAah7E,GAEjB,IACO,EAIX,QAAI85E,EAAYpgF,KAIhB8gF,EAAShE,OAAOwD,EAAUxtC,EAAMx7C,EAAKipF,GAAOe,EAAathF,KAElD,EACT,CAEA,MAAM2d,EAAQ,GAER+jE,EAAiBvuF,OAAOiT,OAAOw6E,GAAY,CAC/CO,iBACAG,eACAlB,gBAyBF,IAAK1D,EAAQlC,SAAS3xE,GACpB,MAAM,IAAIk4E,UAAU,0BAKtB,OA5BA,SAASY,EAAM3hF,EAAO8yC,GACpB,IAAI4pC,EAAQxC,YAAYl6E,GAAxB,CAEA,IAA8B,IAA1B2d,EAAM/pB,QAAQoM,GAChB,MAAM42B,MAAM,kCAAoCkc,EAAKt+B,KAAK,MAG5DmJ,EAAMxQ,KAAKnN,GAEX08E,EAAQxhF,QAAQ8E,EAAO,SAAcsG,EAAIhP,IAKxB,OAJEolF,EAAQxC,YAAY5zE,IAAc,OAAPA,IAAgB46E,EAAQv6E,KAClEm6E,EAAUx6E,EAAIo2E,EAAQpC,SAAShjF,GAAOA,EAAIkT,OAASlT,EAAKw7C,EAAM4uC,KAI9DC,EAAMr7E,EAAIwsC,EAAOA,EAAKl/B,OAAOtc,GAAO,CAACA,GAEzC,GAEAqmB,EAAM3P,KAlBgC,CAmBxC,CAMA2zE,CAAM94E,GAECi4E,CACT,CAUA,SAASc,GAASl8E,GAChB,MAAMm8E,EAAU,CACd,IAAK,MACL,IAAK,MACL,IAAK,MACL,IAAK,MACL,IAAK,MACL,MAAO,IACP,MAAO,MAET,OAAOC,mBAAmBp8E,GAAK1D,QAAQ,mBAAoB,SAAkB8wB,GAC3E,OAAO+uD,EAAQ/uD,EACjB,EACF,CAUA,SAASivD,GAAqB9lF,EAAQ4H,GACpCrR,KAAKwvF,OAAS,GAEd/lF,GAAU4kF,GAAW5kF,EAAQzJ,KAAMqR,EACrC,CAEA,MAAM2C,GAAYu7E,GAAqBv7E,UAwBvC,SAASy7E,GAAOriF,GACd,OAAOkiF,mBAAmBliF,GACxBoC,QAAQ,QAAS,KACjBA,QAAQ,OAAQ,KAChBA,QAAQ,QAAS,KACjBA,QAAQ,OAAQ,IACpB,CAWA,SAASkgF,GAASzrF,EAAKwF,EAAQ4H,GAE7B,IAAK5H,EACH,OAAOxF,EAGT,MAAM0rF,EAAUt+E,GAAWA,EAAQo+E,QAAUA,GAEzCvF,EAAQS,WAAWt5E,KACrBA,EAAU,CACRu+E,UAAWv+E,IAIf,MAAMw+E,EAAcx+E,GAAWA,EAAQu+E,UAEvC,IAAIE,EAUJ,GAPEA,EADED,EACiBA,EAAYpmF,EAAQ4H,GAEpB64E,EAAQ9B,kBAAkB3+E,GAC3CA,EAAOoL,WACP,IAAI06E,GAAqB9lF,EAAQ4H,GAASwD,SAAS86E,GAGnDG,EAAkB,CACpB,MAAMC,EAAgB9rF,EAAI7C,QAAQ,MAEX,IAAnB2uF,IACF9rF,EAAMA,EAAI6Q,MAAM,EAAGi7E,IAErB9rF,KAA8B,IAAtBA,EAAI7C,QAAQ,KAAc,IAAM,KAAO0uF,CACjD,CAEA,OAAO7rF,CACT,CA3EA+P,GAAUs2E,OAAS,SAAgBtsF,EAAMwP,GACvCxN,KAAKwvF,OAAO70E,KAAK,CAAC3c,EAAMwP,GAC1B,EAEAwG,GAAUa,SAAW,SAAkBm7E,GACrC,MAAML,EAAUK,EAAU,SAASxiF,GACjC,OAAOwiF,EAAQ77E,KAAKnU,KAAMwN,EAAO4hF,GACnC,EAAIA,GAEJ,OAAOpvF,KAAKwvF,OAAOr8E,IAAI,SAAc64E,GACnC,OAAO2D,EAAQ3D,EAAK,IAAM,IAAM2D,EAAQ3D,EAAK,GAC/C,EAAG,IAAIhqE,KAAK,IACd,EAmIA,IAAIiuE,GAlEJ,MACE,WAAA/1E,GACEla,KAAKkwF,SAAW,EAClB,CAUA,GAAAh/E,CAAIi/E,EAAWC,EAAU/+E,GAOvB,OANArR,KAAKkwF,SAASv1E,KAAK,CACjBw1E,YACAC,WACAC,cAAah/E,GAAUA,EAAQg/E,YAC/BC,QAASj/E,EAAUA,EAAQi/E,QAAU,OAEhCtwF,KAAKkwF,SAASzsF,OAAS,CAChC,CASA,KAAA8sF,CAAMhsF,GACAvE,KAAKkwF,SAAS3rF,KAChBvE,KAAKkwF,SAAS3rF,GAAM,KAExB,CAOA,KAAA6hB,GACMpmB,KAAKkwF,WACPlwF,KAAKkwF,SAAW,GAEpB,CAYA,OAAAxnF,CAAQ0M,GACN80E,EAAQxhF,QAAQ1I,KAAKkwF,SAAU,SAAwBrhD,GAC3C,OAANA,GACFz5B,EAAGy5B,EAEP,EACF,GAKE2hD,GAAuB,CACzBC,mBAAmB,EACnBC,mBAAmB,EACnBC,qBAAqB,GASnBC,GAAa,CACfC,WAAW,EACX7nF,QAAS,CACP8nF,gBAT+C,oBAApBA,gBAAkCA,gBAAkBvB,GAU/ElF,SARiC,oBAAbA,SAA2BA,SAAW,KAS1DwE,KAPyB,oBAATA,KAAuBA,KAAO,MAShDkC,UAAW,CAAC,OAAQ,QAAS,OAAQ,OAAQ,MAAO,SAGtD,MAAMC,GAAkC,oBAAXvsF,QAA8C,oBAAbzB,SAExDiuF,GAAkC,iBAAdjmC,WAA0BA,gBAAa/jD,EAmB3DiqF,GAAwBF,MAC1BC,IAAc,CAAC,cAAe,eAAgB,MAAM7vF,QAAQ6vF,GAAWE,SAAW,GAWhFC,GAE2B,oBAAtBC,mBAEPj6E,gBAAgBi6E,mBACc,mBAAvBj6E,KAAKk6E,cAIVC,GAASP,IAAiBvsF,OAAOC,SAASV,MAAQ,mBAExD,IASIwtF,GAAW,IATU7wF,OAAO8wF,OAAO,CACrCvwE,UAAW,KACX8vE,cAAeA,GACfI,+BAAgCA,GAChCF,sBAAuBA,GACvBlmC,UAAWimC,GACXM,OAAQA,QAKLX,IA6DL,SAASc,GAAepD,GACtB,SAASqD,EAAUrxC,EAAM9yC,EAAOrK,EAAQyB,GACtC,IAAI5G,EAAOsiD,EAAK17C,KAEhB,GAAa,cAAT5G,EAAsB,OAAO,EAEjC,MAAM4zF,EAAe76E,OAAO+C,UAAU9b,GAChC6zF,EAASjtF,GAAS07C,EAAK78C,OAG7B,OAFAzF,GAAQA,GAAQksF,EAAQ91E,QAAQjR,GAAUA,EAAOM,OAASzF,EAEtD6zF,GACE3H,EAAQkC,WAAWjpF,EAAQnF,GAC7BmF,EAAOnF,GAAQ,CAACmF,EAAOnF,GAAOwP,GAE9BrK,EAAOnF,GAAQwP,GAGTokF,IAGLzuF,EAAOnF,IAAUksF,EAAQlC,SAAS7kF,EAAOnF,MAC5CmF,EAAOnF,GAAQ,IAGF2zF,EAAUrxC,EAAM9yC,EAAOrK,EAAOnF,GAAO4G,IAEtCslF,EAAQ91E,QAAQjR,EAAOnF,MACnCmF,EAAOnF,GA/Cb,SAAuB6V,GACrB,MAAMwC,EAAM,CAAC,EACPwC,EAAOlY,OAAOkY,KAAKhF,GACzB,IAAIE,EACJ,MAAM+oC,EAAMjkC,EAAKpV,OACjB,IAAIqB,EACJ,IAAKiP,EAAI,EAAGA,EAAI+oC,EAAK/oC,IACnBjP,EAAM+T,EAAK9E,GACXsC,EAAIvR,GAAO+O,EAAI/O,GAEjB,OAAOuR,CACT,CAoCqBy7E,CAAc3uF,EAAOnF,MAG9B4zF,EACV,CAEA,GAAI1H,EAAQC,WAAWmE,IAAapE,EAAQS,WAAW2D,EAAS90E,SAAU,CACxE,MAAMnD,EAAM,CAAC,EAMb,OAJA6zE,EAAQ4B,aAAawC,EAAU,CAACtwF,EAAMwP,KACpCmkF,EA1EN,SAAuB3zF,GAKrB,OAAOksF,EAAQ+B,SAAS,gBAAiBjuF,GAAMmV,IAAImtB,GAC7B,OAAbA,EAAM,GAAc,GAAKA,EAAM,IAAMA,EAAM,GAEtD,CAkEgByxD,CAAc/zF,GAAOwP,EAAO6I,EAAK,KAGtCA,CACT,CAEA,OAAO,IACT,CA2BA,MAAMs3B,GAAW,CAEfqkD,aAAcxB,GAEdyB,QAAS,CAAC,MAAO,OAAQ,SAEzBC,iBAAkB,CAAC,SAA0BpzF,EAAM+M,GACjD,MAAMsmF,EAActmF,EAAQumF,kBAAoB,GAC1CC,EAAqBF,EAAY/wF,QAAQ,qBAAuB,EAChEkxF,EAAkBpI,EAAQlC,SAASlpF,GAQzC,GANIwzF,GAAmBpI,EAAQnB,WAAWjqF,KACxCA,EAAO,IAAIurF,SAASvrF,IAGHorF,EAAQC,WAAWrrF,GAGpC,OAAOuzF,EAAqBl5E,KAAKC,UAAUs4E,GAAe5yF,IAASA,EAGrE,GAAIorF,EAAQrC,cAAc/oF,IACxBorF,EAAQvC,SAAS7oF,IACjBorF,EAAQU,SAAS9rF,IACjBorF,EAAQjC,OAAOnpF,IACforF,EAAQhC,OAAOppF,IACforF,EAAQ7B,iBAAiBvpF,GAEzB,OAAOA,EAET,GAAIorF,EAAQK,kBAAkBzrF,GAC5B,OAAOA,EAAK0vB,OAEd,GAAI07D,EAAQ9B,kBAAkBtpF,GAE5B,OADA+M,EAAQ0mF,eAAe,mDAAmD,GACnEzzF,EAAK+V,WAGd,IAAIszE,EAEJ,GAAImK,EAAiB,CACnB,GAAIH,EAAY/wF,QAAQ,sCAAwC,EAC9D,OA3KR,SAA0BtC,EAAMuS,GAC9B,OAAOg9E,GAAWvvF,EAAM,IAAI0yF,GAASxoF,QAAQ8nF,gBAAmB,CAC9DpC,QAAS,SAASlhF,EAAO1I,EAAKw7C,EAAMw0B,GAClC,OAAI0c,GAASgB,QAAUtI,EAAQvC,SAASn6E,IACtCxN,KAAKsqF,OAAOxlF,EAAK0I,EAAMqH,SAAS,YACzB,GAGFigE,EAAQ6Z,eAAentE,MAAMxhB,KAAMyhB,UAC5C,KACGpQ,GAEP,CA+JeohF,CAAiB3zF,EAAMkB,KAAK0yF,gBAAgB79E,WAGrD,IAAKszE,EAAa+B,EAAQ/B,WAAWrpF,KAAUqzF,EAAY/wF,QAAQ,wBAA0B,EAAG,CAC9F,MAAMuxF,EAAY3yF,KAAK4yF,KAAO5yF,KAAK4yF,IAAIvI,SAEvC,OAAOgE,GACLlG,EAAa,CAAC,UAAWrpF,GAAQA,EACjC6zF,GAAa,IAAIA,EACjB3yF,KAAK0yF,eAET,CACF,CAEA,OAAIJ,GAAmBD,GACrBxmF,EAAQ0mF,eAAe,oBAAoB,GAxEjD,SAAyBpqE,GACvB,GAAI+hE,EAAQpC,SAAS3/D,GACnB,IAEE,OADA,EAAWhP,KAAK+0D,OAAO/lD,GAChB+hE,EAAQlyE,KAAKmQ,EACtB,CAAE,MAAO/lB,GACP,GAAe,gBAAXA,EAAEpE,KACJ,MAAMoE,CAEV,CAGF,OAAO,EAAY+W,KAAKC,WAAW+O,EACrC,CA4Da0qE,CAAgB/zF,IAGlBA,CACT,GAEAg0F,kBAAmB,CAAC,SAA2Bh0F,GAC7C,MAAMkzF,EAAehyF,KAAKgyF,cAAgBrkD,GAASqkD,aAC7CtB,EAAoBsB,GAAgBA,EAAatB,kBACjDqC,EAAsC,SAAtB/yF,KAAKgzF,aAE3B,GAAI9I,EAAQ3B,WAAWzpF,IAASorF,EAAQ7B,iBAAiBvpF,GACvD,OAAOA,EAGT,GAAIA,GAAQorF,EAAQpC,SAAShpF,KAAW4xF,IAAsB1wF,KAAKgzF,cAAiBD,GAAgB,CAClG,MACME,IADoBjB,GAAgBA,EAAavB,oBACPsC,EAEhD,IACE,OAAO55E,KAAK+0D,MAAMpvE,EAAMkB,KAAKkzF,aAC/B,CAAE,MAAO9wF,GACP,GAAI6wF,EAAmB,CACrB,GAAe,gBAAX7wF,EAAEpE,KACJ,MAAMqvF,EAAWvgF,KAAK1K,EAAGirF,EAAW8F,iBAAkBnzF,KAAM,KAAMA,KAAK4C,UAEzE,MAAMR,CACR,CACF,CACF,CAEA,OAAOtD,CACT,GAMAyiC,QAAS,EAET6xD,eAAgB,aAChBC,eAAgB,eAEhBC,kBAAmB,EACnBC,eAAgB,EAEhBX,IAAK,CACHvI,SAAUmH,GAASxoF,QAAQqhF,SAC3BwE,KAAM2C,GAASxoF,QAAQ6lF,MAGzB2E,eAAgB,SAAwBznF,GACtC,OAAOA,GAAU,KAAOA,EAAS,GACnC,EAEAF,QAAS,CACP4nF,OAAQ,CACN,OAAU,oCACV,oBAAgBxsF,KAKtBijF,EAAQxhF,QAAQ,CAAC,SAAU,MAAO,OAAQ,OAAQ,MAAO,SAAWka,IAClE+qB,GAAS9hC,QAAQ+W,GAAU,CAAC,IAG9B,IAAI8wE,GAAa/lD,GAIjB,MAAMgmD,GAAoBzJ,EAAQoC,YAAY,CAC5C,MAAO,gBAAiB,iBAAkB,eAAgB,OAC1D,UAAW,OAAQ,OAAQ,oBAAqB,sBAChD,gBAAiB,WAAY,eAAgB,sBAC7C,UAAW,cAAe,eA8CtBsH,GAAa5zE,OAAO,aAE1B,SAAS6zE,GAAgBC,GACvB,OAAOA,GAAUn1F,OAAOm1F,GAAQ97E,OAAOrC,aACzC,CAEA,SAASo+E,GAAevmF,GACtB,OAAc,IAAVA,GAA4B,MAATA,EACdA,EAGF08E,EAAQ91E,QAAQ5G,GAASA,EAAM2F,IAAI4gF,IAAkBp1F,OAAO6O,EACrE,CAgBA,SAASwmF,GAAiB9hD,EAAS1kC,EAAOsmF,EAAQpyE,EAAQuyE,GACxD,OAAI/J,EAAQS,WAAWjpE,GACdA,EAAOvN,KAAKnU,KAAMwN,EAAOsmF,IAG9BG,IACFzmF,EAAQsmF,GAGL5J,EAAQpC,SAASt6E,GAElB08E,EAAQpC,SAASpmE,IACe,IAA3BlU,EAAMpM,QAAQsgB,GAGnBwoE,EAAQlB,SAAStnE,GACZA,EAAOgmB,KAAKl6B,QADrB,OANA,EASF,CAsBA,MAAM0mF,GACJ,WAAAh6E,CAAYrO,GACVA,GAAW7L,KAAKogB,IAAIvU,EACtB,CAEA,GAAAuU,CAAI0zE,EAAQK,EAAgBC,GAC1B,MAAMh9E,EAAOpX,KAEb,SAASq0F,EAAUx1E,EAAQy1E,EAASC,GAClC,MAAMC,EAAUX,GAAgBS,GAEhC,IAAKE,EACH,MAAM,IAAIpwD,MAAM,0CAGlB,MAAMt/B,EAAMolF,EAAQxB,QAAQtxE,EAAMo9E,KAE9B1vF,QAAqBmC,IAAdmQ,EAAKtS,KAAmC,IAAbyvF,QAAmCttF,IAAbstF,IAAwC,IAAdn9E,EAAKtS,MACzFsS,EAAKtS,GAAOwvF,GAAWP,GAAel1E,GAE1C,CAEA,MAAM41E,EAAa,CAAC5oF,EAAS0oF,IAC3BrK,EAAQxhF,QAAQmD,EAAS,CAACgT,EAAQy1E,IAAYD,EAAUx1E,EAAQy1E,EAASC,IAE3E,GAAIrK,EAAQn1E,cAAc++E,IAAWA,aAAkB9zF,KAAKka,YAC1Du6E,EAAWX,EAAQK,QACd,GAAGjK,EAAQpC,SAASgM,KAAYA,EAASA,EAAO97E,UArExB,iCAAiC0vB,KAqEqBosD,EArEZ97E,QAsEvEy8E,EA7HaC,KACjB,MAAMC,EAAS,CAAC,EAChB,IAAI7vF,EACAsI,EACA2G,EAsBJ,OApBA2gF,GAAcA,EAAW1zF,MAAM,MAAM0H,QAAQ,SAAgBg5D,GAC3D3tD,EAAI2tD,EAAKtgE,QAAQ,KACjB0D,EAAM48D,EAAKkzB,UAAU,EAAG7gF,GAAGiE,OAAOrC,cAClCvI,EAAMs0D,EAAKkzB,UAAU7gF,EAAI,GAAGiE,QAEvBlT,GAAQ6vF,EAAO7vF,IAAQ6uF,GAAkB7uF,KAIlC,eAARA,EACE6vF,EAAO7vF,GACT6vF,EAAO7vF,GAAK6V,KAAKvN,GAEjBunF,EAAO7vF,GAAO,CAACsI,GAGjBunF,EAAO7vF,GAAO6vF,EAAO7vF,GAAO6vF,EAAO7vF,GAAO,KAAOsI,EAAMA,EAE3D,GAEOunF,GAmGQE,CAAaf,GAASK,QAC5B,GAAIjK,EAAQlC,SAAS8L,IAAW5J,EAAQkD,WAAW0G,GAAS,CACjE,IAAcgB,EAAMhwF,EAAhBuR,EAAM,CAAC,EACX,IAAK,MAAM0+E,KAASjB,EAAQ,CAC1B,IAAK5J,EAAQ91E,QAAQ2gF,GACnB,MAAMxG,UAAU,gDAGlBl4E,EAAIvR,EAAMiwF,EAAM,KAAOD,EAAOz+E,EAAIvR,IAC/BolF,EAAQ91E,QAAQ0gF,GAAQ,IAAIA,EAAMC,EAAM,IAAM,CAACD,EAAMC,EAAM,IAAOA,EAAM,EAC7E,CAEAN,EAAWp+E,EAAK89E,EAClB,MACY,MAAVL,GAAkBO,EAAUF,EAAgBL,EAAQM,GAGtD,OAAOp0F,IACT,CAEA,GAAA0C,CAAIoxF,EAAQkB,GAGV,GAFAlB,EAASD,GAAgBC,GAEb,CACV,MAAMhvF,EAAMolF,EAAQxB,QAAQ1oF,KAAM8zF,GAElC,GAAIhvF,EAAK,CACP,MAAM0I,EAAQxN,KAAK8E,GAEnB,IAAKkwF,EACH,OAAOxnF,EAGT,IAAe,IAAXwnF,EACF,OApHV,SAAqB9hF,GACnB,MAAM+hF,EAASt0F,OAAOyS,OAAO,MACvB8hF,EAAW,mCACjB,IAAI50D,EAEJ,KAAQA,EAAQ40D,EAAS/I,KAAKj5E,IAC5B+hF,EAAO30D,EAAM,IAAMA,EAAM,GAG3B,OAAO20D,CACT,CA0GiBE,CAAY3nF,GAGrB,GAAI08E,EAAQS,WAAWqK,GACrB,OAAOA,EAAO7gF,KAAKnU,KAAMwN,EAAO1I,GAGlC,GAAIolF,EAAQlB,SAASgM,GACnB,OAAOA,EAAO7I,KAAK3+E,GAGrB,MAAM,IAAI+gF,UAAU,yCACtB,CACF,CACF,CAEA,GAAAjyE,CAAIw3E,EAAQsB,GAGV,GAFAtB,EAASD,GAAgBC,GAEb,CACV,MAAMhvF,EAAMolF,EAAQxB,QAAQ1oF,KAAM8zF,GAElC,SAAUhvF,QAAqBmC,IAAdjH,KAAK8E,IAAwBswF,IAAWpB,GAAiBh0F,EAAMA,KAAK8E,GAAMA,EAAKswF,GAClG,CAEA,OAAO,CACT,CAEA,OAAOtB,EAAQsB,GACb,MAAMh+E,EAAOpX,KACb,IAAIq1F,GAAU,EAEd,SAASC,EAAahB,GAGpB,GAFAA,EAAUT,GAAgBS,GAEb,CACX,MAAMxvF,EAAMolF,EAAQxB,QAAQtxE,EAAMk9E,IAE9BxvF,GAASswF,IAAWpB,GAAiB58E,EAAMA,EAAKtS,GAAMA,EAAKswF,YACtDh+E,EAAKtS,GAEZuwF,GAAU,EAEd,CACF,CAQA,OANInL,EAAQ91E,QAAQ0/E,GAClBA,EAAOprF,QAAQ4sF,GAEfA,EAAaxB,GAGRuB,CACT,CAEA,KAAAjvE,CAAMgvE,GACJ,MAAMv8E,EAAOlY,OAAOkY,KAAK7Y,MACzB,IAAI+T,EAAI8E,EAAKpV,OACT4xF,GAAU,EAEd,KAAOthF,KAAK,CACV,MAAMjP,EAAM+T,EAAK9E,GACbqhF,IAAWpB,GAAiBh0F,EAAMA,KAAK8E,GAAMA,EAAKswF,GAAS,YACtDp1F,KAAK8E,GACZuwF,GAAU,EAEd,CAEA,OAAOA,CACT,CAEA,SAAA/xC,CAAUiyC,GACR,MAAMn+E,EAAOpX,KACP6L,EAAU,CAAC,EAsBjB,OApBAq+E,EAAQxhF,QAAQ1I,KAAM,CAACwN,EAAOsmF,KAC5B,MAAMhvF,EAAMolF,EAAQxB,QAAQ78E,EAASioF,GAErC,GAAIhvF,EAGF,OAFAsS,EAAKtS,GAAOivF,GAAevmF,eACpB4J,EAAK08E,GAId,MAAMt8E,EAAa+9E,EAtKzB,SAAsBzB,GACpB,OAAOA,EAAO97E,OACXrC,cAAcnG,QAAQ,kBAAmB,CAACgmF,EAAGrvB,EAAMjzD,IAC3CizD,EAAK3wD,cAAgBtC,EAElC,CAiKkCuiF,CAAa3B,GAAUn1F,OAAOm1F,GAAQ97E,OAE9DR,IAAes8E,UACV18E,EAAK08E,GAGd18E,EAAKI,GAAcu8E,GAAevmF,GAElC3B,EAAQ2L,IAAc,IAGjBxX,IACT,CAEA,MAAAohB,IAAUs0E,GACR,OAAO11F,KAAKka,YAAYkH,OAAOphB,QAAS01F,EAC1C,CAEA,MAAA7Q,CAAO8Q,GACL,MAAMt/E,EAAM1V,OAAOyS,OAAO,MAM1B,OAJA82E,EAAQxhF,QAAQ1I,KAAM,CAACwN,EAAOsmF,KACnB,MAATtmF,IAA2B,IAAVA,IAAoB6I,EAAIy9E,GAAU6B,GAAazL,EAAQ91E,QAAQ5G,GAASA,EAAMwU,KAAK,MAAQxU,KAGvG6I,CACT,CAEA,CAAC2J,OAAOmB,YACN,OAAOxgB,OAAO6Y,QAAQxZ,KAAK6kF,UAAU7kE,OAAOmB,WAC9C,CAEA,QAAAtM,GACE,OAAOlU,OAAO6Y,QAAQxZ,KAAK6kF,UAAU1xE,IAAI,EAAE2gF,EAAQtmF,KAAWsmF,EAAS,KAAOtmF,GAAOwU,KAAK,KAC5F,CAEA,YAAA4zE,GACE,OAAO51F,KAAK0C,IAAI,eAAiB,EACnC,CAEA,IAAKsd,OAAOwkB,eACV,MAAO,cACT,CAEA,WAAO13B,CAAKy6E,GACV,OAAOA,aAAiBvnF,KAAOunF,EAAQ,IAAIvnF,KAAKunF,EAClD,CAEA,aAAOnmE,CAAOimD,KAAUquB,GACtB,MAAM51F,EAAW,IAAIE,KAAKqnE,GAI1B,OAFAquB,EAAQhtF,QAASvF,GAAWrD,EAASsgB,IAAIjd,IAElCrD,CACT,CAEA,eAAO+1F,CAAS/B,GACd,MAIMgC,GAJY91F,KAAK4zF,IAAe5zF,KAAK4zF,IAAc,CACvDkC,UAAW,CAAC,IAGcA,UACtB9hF,EAAYhU,KAAKgU,UAEvB,SAAS+hF,EAAezB,GACtB,MAAME,EAAUX,GAAgBS,GAE3BwB,EAAUtB,KAlOrB,SAAwBn+E,EAAKy9E,GAC3B,MAAMkC,EAAe9L,EAAQuC,YAAY,IAAMqH,GAE/C,CAAC,MAAO,MAAO,OAAOprF,QAAQutF,IAC5Bt1F,OAAO4V,eAAeF,EAAK4/E,EAAaD,EAAc,CACpDxoF,MAAO,SAAS0oF,EAAMC,EAAMC,GAC1B,OAAOp2F,KAAKi2F,GAAY9hF,KAAKnU,KAAM8zF,EAAQoC,EAAMC,EAAMC,EACzD,EACA5/E,cAAc,KAGpB,CAwNQ6/E,CAAeriF,EAAWsgF,GAC1BwB,EAAUtB,IAAW,EAEzB,CAIA,OAFAtK,EAAQ91E,QAAQ0/E,GAAUA,EAAOprF,QAAQqtF,GAAkBA,EAAejC,GAEnE9zF,IACT,EAGFk0F,GAAa2B,SAAS,CAAC,eAAgB,iBAAkB,SAAU,kBAAmB,aAAc,kBAGpG3L,EAAQjB,kBAAkBiL,GAAalgF,UAAW,EAAExG,SAAQ1I,KAC1D,IAAIwxF,EAASxxF,EAAI,GAAG0Q,cAAgB1Q,EAAIgQ,MAAM,GAC9C,MAAO,CACLpS,IAAK,IAAM8K,EACX,GAAA4S,CAAIm2E,GACFv2F,KAAKs2F,GAAUC,CACjB,KAIJrM,EAAQmC,cAAc6H,IAEtB,IAAIsC,GAAiBtC,GAUrB,SAASuC,GAAcvgF,EAAKtT,GAC1B,MAAMmpB,EAAS/rB,MAAQ0zF,GACjBxhD,EAAUtvC,GAAYmpB,EACtBlgB,EAAU2qF,GAAe1pF,KAAKolC,EAAQrmC,SAC5C,IAAI/M,EAAOozC,EAAQpzC,KAQnB,OANAorF,EAAQxhF,QAAQwN,EAAK,SAAmBd,GACtCtW,EAAOsW,EAAGjB,KAAK4X,EAAQjtB,EAAM+M,EAAQy3C,YAAa1gD,EAAWA,EAASmJ,YAAS9E,EACjF,GAEA4E,EAAQy3C,YAEDxkD,CACT,CAEA,SAAS43F,GAASlpF,GAChB,SAAUA,IAASA,EAAMmpF,WAC3B,CAWA,SAASC,GAAcxkB,EAASrmD,EAAQuhE,GAEtCD,EAAWl5E,KAAKnU,KAAiB,MAAXoyE,EAAkB,WAAaA,EAASib,EAAWwJ,aAAc9qE,EAAQuhE,GAC/FttF,KAAKhC,KAAO,eACd,CAeA,SAAS84F,GAAO/pE,EAASsX,EAAQzhC,GAC/B,MAAM4wF,EAAiB5wF,EAASmpB,OAAOynE,eAClC5wF,EAASmJ,QAAWynF,IAAkBA,EAAe5wF,EAASmJ,QAGjEs4B,EAAO,IAAIgpD,EACT,mCAAqCzqF,EAASmJ,OAC9C,CAACshF,EAAW0J,gBAAiB1J,EAAW8F,kBAAkBt3C,KAAKm7C,MAAMp0F,EAASmJ,OAAS,KAAO,GAC9FnJ,EAASmpB,OACTnpB,EAAS0qF,QACT1qF,IAPFmqB,EAAQnqB,EAUZ,CA1BAsnF,EAAQmB,SAASuL,GAAevJ,EAAY,CAC1CsJ,YAAY,IA+Hd,MAAMM,GAAuB,CAACC,EAAUC,EAAkBC,EAAO,KAC/D,IAAIC,EAAgB,EACpB,MAAMC,EA3FR,SAAqBC,EAAcz7C,GACjCy7C,EAAeA,GAAgB,GAC/B,MAAMC,EAAQ,IAAIh2F,MAAM+1F,GAClBE,EAAa,IAAIj2F,MAAM+1F,GAC7B,IAEIG,EAFAv5E,EAAO,EACPC,EAAO,EAKX,OAFA09B,OAAc70C,IAAR60C,EAAoBA,EAAM,IAEzB,SAAc67C,GACnB,MAAMtkC,EAAMD,KAAKC,MAEXukC,EAAYH,EAAWr5E,GAExBs5E,IACHA,EAAgBrkC,GAGlBmkC,EAAMr5E,GAAQw5E,EACdF,EAAWt5E,GAAQk1C,EAEnB,IAAIt/C,EAAIqK,EACJy5E,EAAa,EAEjB,KAAO9jF,IAAMoK,GACX05E,GAAcL,EAAMzjF,KACpBA,GAAQwjF,EASV,GANAp5E,GAAQA,EAAO,GAAKo5E,EAEhBp5E,IAASC,IACXA,GAAQA,EAAO,GAAKm5E,GAGlBlkC,EAAMqkC,EAAgB57C,EACxB,OAGF,MAAMg8C,EAASF,GAAavkC,EAAMukC,EAElC,OAAOE,EAASj8C,KAAKk8C,MAAmB,IAAbF,EAAoBC,QAAU7wF,CAC3D,CACF,CA+CuB+wF,CAAY,GAAI,KAErC,OAzCF,SAAkB5iF,EAAIgiF,GACpB,IAEIa,EACAC,EAHAC,EAAY,EACZC,EAAY,IAAOhB,EAIvB,MAAMiB,EAAS,CAAC7pF,EAAM6kD,EAAMD,KAAKC,SAC/B8kC,EAAY9kC,EACZ4kC,EAAW,KACPC,IACF72D,aAAa62D,GACbA,EAAQ,MA8BI91F,KACd,MAAMgjC,EAAShjC,EAAEgjC,OACXz7B,EAAQvH,EAAEk2F,iBAAmBl2F,EAAEuH,WAAQ1C,EACvCsxF,EAAgBnzD,EAASiyD,EACzBmB,EAAOlB,EAAaiB,GAG1BlB,EAAgBjyD,EAchB8xD,EAZa,CACX9xD,SACAz7B,QACA8uF,SAAU9uF,EAASy7B,EAASz7B,OAAS1C,EACrCuwF,MAAOe,EACPC,KAAMA,QAAcvxF,EACpByxF,UAAWF,GAAQ7uF,GAVLy7B,GAAUz7B,GAUeA,EAAQy7B,GAAUozD,OAAOvxF,EAChE2E,MAAOxJ,EACPk2F,iBAA2B,MAAT3uF,EAClB,CAACwtF,EAAmB,WAAa,WAAW,KA9C9C/hF,IAAM5G,IAqBR,MAAO,CAlBW,IAAIA,KACpB,MAAM6kD,EAAMD,KAAKC,MACXykC,EAASzkC,EAAM8kC,EAChBL,GAAUM,EACbC,EAAO7pF,EAAM6kD,IAEb4kC,EAAWzpF,EACN0pF,IACHA,EAAQ/2D,WAAW,KACjB+2D,EAAQ,KACRG,EAAOJ,IACNG,EAAYN,MAKP,IAAMG,GAAYI,EAAOJ,GAGzC,CAMSU,CAASv2F,EAsBbg1F,IAGCwB,GAAyB,CAACjvF,EAAOkvF,KACrC,MAAMP,EAA4B,MAAT3uF,EAEzB,MAAO,CAAEy7B,GAAWyzD,EAAU,GAAG,CAC/BP,mBACA3uF,QACAy7B,WACEyzD,EAAU,KAGVC,GAAkB1jF,GAAO,IAAI5G,IAAS07E,EAAQF,KAAK,IAAM50E,KAAM5G,IAErE,IAAIuqF,GAAkBvH,GAASN,sBAAwB,EAAEK,EAAQyH,IAAY/0F,IAC3EA,EAAM,IAAIg1F,IAAIh1F,EAAKutF,GAASD,QAG1BA,EAAO2H,WAAaj1F,EAAIi1F,UACxB3H,EAAOv8B,OAAS/wD,EAAI+wD,OACnBgkC,GAAUzH,EAAO4H,OAASl1F,EAAIk1F,OANoB,CASrD,IAAIF,IAAIzH,GAASD,QACjBC,GAASxmC,WAAa,kBAAkBtjB,KAAK8pD,GAASxmC,UAAUC,YAC9D,KAAM,EAENmuC,GAAU5H,GAASN,sBAGrB,CACE,KAAAmI,CAAMr7F,EAAMwP,EAAO8rF,EAASh5C,EAAMi5C,EAAQC,EAAQC,GAChD,GAAwB,oBAAbz2F,SAA0B,OAErC,MAAM02F,EAAS,CAAC,GAAG17F,KAAQsxF,mBAAmB9hF,MAE1C08E,EAAQnC,SAASuR,IACnBI,EAAO/+E,KAAK,WAAW,IAAIy4C,KAAKkmC,GAASK,iBAEvCzP,EAAQpC,SAASxnC,IACnBo5C,EAAO/+E,KAAK,QAAQ2lC,KAElB4pC,EAAQpC,SAASyR,IACnBG,EAAO/+E,KAAK,UAAU4+E,MAET,IAAXC,GACFE,EAAO/+E,KAAK,UAEVuvE,EAAQpC,SAAS2R,IACnBC,EAAO/+E,KAAK,YAAY8+E,KAG1Bz2F,SAAS02F,OAASA,EAAO13E,KAAK,KAChC,EAEA,IAAA43E,CAAK57F,GACH,GAAwB,oBAAbgF,SAA0B,OAAO,KAC5C,MAAMs9B,EAAQt9B,SAAS02F,OAAOp5D,MAAM,IAAImF,OAAO,WAAaznC,EAAO,aACnE,OAAOsiC,EAAQu5D,mBAAmBv5D,EAAM,IAAM,IAChD,EAEA,MAAA13B,CAAO5K,GACLgC,KAAKq5F,MAAMr7F,EAAM,GAAIo1D,KAAKC,MAAQ,MAAU,IAC9C,GAMF,CACE,KAAAgmC,GAAS,EACTO,KAAI,IACK,KAET,MAAAhxF,GAAU,GAyCd,SAASkxF,GAAcC,EAASC,EAAcC,GAC5C,IAAIC,GA5BG,8BAA8BxyD,KA4BFsyD,GACnC,OAAID,IAAYG,GAAsC,GAArBD,GAlBnC,SAAqBF,EAASI,GAC5B,OAAOA,EACHJ,EAAQvqF,QAAQ,SAAU,IAAM,IAAM2qF,EAAY3qF,QAAQ,OAAQ,IAClEuqF,CACN,CAeWK,CAAYL,EAASC,GAEvBA,CACT,CAEA,MAAMK,GAAmB9S,GAAUA,aAAiBiP,GAAiB,IAAKjP,GAAUA,EAWpF,SAAS+S,GAAYC,EAASC,GAE5BA,EAAUA,GAAW,CAAC,EACtB,MAAMzuE,EAAS,CAAC,EAEhB,SAAS0uE,EAAet3F,EAAQwlB,EAAQssB,EAAM81C,GAC5C,OAAIb,EAAQn1E,cAAc5R,IAAW+mF,EAAQn1E,cAAc4T,GAClDuhE,EAAQY,MAAM32E,KAAK,CAAC42E,YAAW5nF,EAAQwlB,GACrCuhE,EAAQn1E,cAAc4T,GACxBuhE,EAAQY,MAAM,CAAC,EAAGniE,GAChBuhE,EAAQ91E,QAAQuU,GAClBA,EAAO7T,QAET6T,CACT,CAGA,SAAS+xE,EAAoBpiF,EAAGC,EAAG08B,EAAM81C,GACvC,OAAKb,EAAQxC,YAAYnvE,GAEb2xE,EAAQxC,YAAYpvE,QAAzB,EACEmiF,OAAexzF,EAAWqR,EAAG28B,EAAM81C,GAFnC0P,EAAeniF,EAAGC,EAAG08B,EAAM81C,EAItC,CAGA,SAAS4P,EAAiBriF,EAAGC,GAC3B,IAAK2xE,EAAQxC,YAAYnvE,GACvB,OAAOkiF,OAAexzF,EAAWsR,EAErC,CAGA,SAASqiF,EAAiBtiF,EAAGC,GAC3B,OAAK2xE,EAAQxC,YAAYnvE,GAEb2xE,EAAQxC,YAAYpvE,QAAzB,EACEmiF,OAAexzF,EAAWqR,GAF1BmiF,OAAexzF,EAAWsR,EAIrC,CAGA,SAASsiF,EAAgBviF,EAAGC,EAAG08B,GAC7B,OAAIA,KAAQulD,EACHC,EAAeniF,EAAGC,GAChB08B,KAAQslD,EACVE,OAAexzF,EAAWqR,QAD5B,CAGT,CAEA,MAAMwiF,EAAW,CACf72F,IAAK02F,EACL/3E,OAAQ+3E,EACR77F,KAAM67F,EACNZ,QAASa,EACT1I,iBAAkB0I,EAClB9H,kBAAmB8H,EACnBG,iBAAkBH,EAClBr5D,QAASq5D,EACTI,eAAgBJ,EAChBK,gBAAiBL,EACjBM,cAAeN,EACf3I,QAAS2I,EACT5H,aAAc4H,EACdxH,eAAgBwH,EAChBvH,eAAgBuH,EAChBO,iBAAkBP,EAClBQ,mBAAoBR,EACpBS,WAAYT,EACZtH,iBAAkBsH,EAClBrH,cAAeqH,EACfU,eAAgBV,EAChBW,UAAWX,EACXY,UAAWZ,EACXa,WAAYb,EACZc,YAAad,EACbe,WAAYf,EACZgB,iBAAkBhB,EAClBpH,eAAgBqH,EAChBhvF,QAAS,CAACyM,EAAGC,EAAG08B,IAASylD,EAAoBL,GAAgB/hF,GAAI+hF,GAAgB9hF,GAAI08B,GAAM,IAS7F,OANAi1C,EAAQxhF,QAAQ/H,OAAOkY,KAAK,IAAI0hF,KAAYC,IAAW,SAA4BvlD,GACjF,MAAM61C,EAAQgQ,EAAS7lD,IAASylD,EAC1BmB,EAAc/Q,EAAMyP,EAAQtlD,GAAOulD,EAAQvlD,GAAOA,GACvDi1C,EAAQxC,YAAYmU,IAAgB/Q,IAAU+P,IAAqB9uE,EAAOkpB,GAAQ4mD,EACrF,GAEO9vE,CACT,CAEA,IAAI+vE,GAAiB/vE,IACnB,MAAMgwE,EAAYzB,GAAY,CAAC,EAAGvuE,GAElC,IAAI,KAAEjtB,EAAI,cAAEo8F,EAAa,eAAE7H,EAAc,eAAED,EAAc,QAAEvnF,EAAO,KAAEmwF,GAASD,EAa7E,GAXAA,EAAUlwF,QAAUA,EAAU2qF,GAAe1pF,KAAKjB,GAElDkwF,EAAU93F,IAAMyrF,GAASoK,GAAciC,EAAUhC,QAASgC,EAAU93F,IAAK83F,EAAU9B,mBAAoBluE,EAAOtiB,OAAQsiB,EAAOgvE,kBAGzHiB,GACFnwF,EAAQuU,IAAI,gBAAiB,SAC3B67E,MAAMD,EAAKE,UAAY,IAAM,KAAOF,EAAKG,SAAWC,SAAS9M,mBAAmB0M,EAAKG,WAAa,MAIlGjS,EAAQC,WAAWrrF,GACrB,GAAI0yF,GAASN,uBAAyBM,GAASJ,+BAC7CvlF,EAAQ0mF,oBAAetrF,QAClB,GAAIijF,EAAQS,WAAW7rF,EAAKu9F,YAAa,CAE9C,MAAMC,EAAcx9F,EAAKu9F,aAEnBE,EAAiB,CAAC,eAAgB,kBACxC57F,OAAO6Y,QAAQ8iF,GAAa5zF,QAAQ,EAAE5D,EAAKsI,MACrCmvF,EAAez6E,SAAShd,EAAI6Q,gBAC9B9J,EAAQuU,IAAItb,EAAKsI,IAGvB,CAOF,GAAIokF,GAASN,wBACXgK,GAAiBhR,EAAQS,WAAWuQ,KAAmBA,EAAgBA,EAAca,IAEjFb,IAAoC,IAAlBA,GAA2BnC,GAAgBgD,EAAU93F,MAAO,CAEhF,MAAMu4F,EAAYnJ,GAAkBD,GAAkBgG,GAAQQ,KAAKxG,GAE/DoJ,GACF3wF,EAAQuU,IAAIizE,EAAgBmJ,EAEhC,CAGF,OAAOT,GAKLU,GAFoD,oBAAnBC,gBAEK,SAAU3wE,GAClD,OAAO,IAAIe,QAAQ,SAA4BC,EAASsX,GACtD,MAAMs4D,EAAUb,GAAc/vE,GAC9B,IAAI6wE,EAAcD,EAAQ79F,KAC1B,MAAM+9F,EAAiBrG,GAAe1pF,KAAK6vF,EAAQ9wF,SAASy3C,YAC5D,IACIw5C,EACAC,EAAiBC,EACjBC,EAAaC,GAHb,aAAClK,EAAY,iBAAEmI,EAAgB,mBAAEC,GAAsBuB,EAK3D,SAAS15E,IACPg6E,GAAeA,IACfC,GAAiBA,IAEjBP,EAAQjB,aAAeiB,EAAQjB,YAAYyB,YAAYL,GAEvDH,EAAQS,QAAUT,EAAQS,OAAOt6D,oBAAoB,QAASg6D,EAChE,CAEA,IAAIxP,EAAU,IAAIoP,eAOlB,SAASW,IACP,IAAK/P,EACH,OAGF,MAAMgQ,EAAkB9G,GAAe1pF,KACrC,0BAA2BwgF,GAAWA,EAAQiQ,yBAahDzG,GAAO,SAAkBtpF,GACvBuf,EAAQvf,GACRyV,GACF,EAAG,SAAiBnF,GAClBumB,EAAOvmB,GACPmF,GACF,EAfiB,CACfnkB,KAHoBk0F,GAAiC,SAAjBA,GAA4C,SAAjBA,EACxC1F,EAAQ1qF,SAA/B0qF,EAAQkQ,aAGRzxF,OAAQuhF,EAAQvhF,OAChB0xF,WAAYnQ,EAAQmQ,WACpB5xF,QAASyxF,EACTvxE,SACAuhE,YAYFA,EAAU,IACZ,CAlCAA,EAAQvjF,KAAK4yF,EAAQ/5E,OAAOpN,cAAemnF,EAAQ14F,KAAK,GAGxDqpF,EAAQ/rD,QAAUo7D,EAAQp7D,QAiCtB,cAAe+rD,EAEjBA,EAAQ+P,UAAYA,EAGpB/P,EAAQoQ,mBAAqB,WACtBpQ,GAAkC,IAAvBA,EAAQqQ,aAQD,IAAnBrQ,EAAQvhF,QAAkBuhF,EAAQsQ,aAAwD,IAAzCtQ,EAAQsQ,YAAYx8F,QAAQ,WAKjF+/B,WAAWk8D,EACb,EAIF/P,EAAQuQ,QAAU,WACXvQ,IAILjpD,EAAO,IAAIgpD,EAAW,kBAAmBA,EAAWyQ,aAAc/xE,EAAQuhE,IAG1EA,EAAU,KACZ,EAGFA,EAAQyQ,QAAU,SAAqBnyF,GAIlC,MACMkS,EAAM,IAAIuvE,EADJzhF,GAASA,EAAMwmE,QAAUxmE,EAAMwmE,QAAU,gBACrBib,EAAW2Q,YAAajyE,EAAQuhE,GAEhExvE,EAAIlS,MAAQA,GAAS,KACrBy4B,EAAOvmB,GACPwvE,EAAU,IACb,EAGAA,EAAQ2Q,UAAY,WAClB,IAAIC,EAAsBvB,EAAQp7D,QAAU,cAAgBo7D,EAAQp7D,QAAU,cAAgB,mBAC9F,MAAMywD,EAAe2K,EAAQ3K,cAAgBxB,GACzCmM,EAAQuB,sBACVA,EAAsBvB,EAAQuB,qBAEhC75D,EAAO,IAAIgpD,EACT6Q,EACAlM,EAAarB,oBAAsBtD,EAAW8Q,UAAY9Q,EAAWyQ,aACrE/xE,EACAuhE,IAGFA,EAAU,IACZ,OAGgBrmF,IAAhB21F,GAA6BC,EAAetK,eAAe,MAGvD,qBAAsBjF,GACxBpD,EAAQxhF,QAAQm0F,EAAehY,SAAU,SAA0Bz3E,EAAKtI,GACtEwoF,EAAQ8Q,iBAAiBt5F,EAAKsI,EAChC,GAIG88E,EAAQxC,YAAYiV,EAAQ1B,mBAC/B3N,EAAQ2N,kBAAoB0B,EAAQ1B,iBAIlCjI,GAAiC,SAAjBA,IAClB1F,EAAQ0F,aAAe2J,EAAQ3J,cAI7BoI,KACA4B,EAAmBE,GAAiBjG,GAAqBmE,GAAoB,GAC/E9N,EAAQpqF,iBAAiB,WAAY85F,IAInC7B,GAAoB7N,EAAQ+Q,UAC5BtB,EAAiBE,GAAehG,GAAqBkE,GAEvD7N,EAAQ+Q,OAAOn7F,iBAAiB,WAAY65F,GAE5CzP,EAAQ+Q,OAAOn7F,iBAAiB,UAAW+5F,KAGzCN,EAAQjB,aAAeiB,EAAQS,UAGjCN,EAAawB,IACNhR,IAGLjpD,GAAQi6D,GAAUA,EAAOngG,KAAO,IAAIy4F,GAAc,KAAM7qE,EAAQuhE,GAAWgR,GAC3EhR,EAAQiR,QACRjR,EAAU,OAGZqP,EAAQjB,aAAeiB,EAAQjB,YAAY8C,UAAU1B,GACjDH,EAAQS,SACVT,EAAQS,OAAOqB,QAAU3B,IAAeH,EAAQS,OAAOl6F,iBAAiB,QAAS45F,KAIrF,MAAM5D,EArkBV,SAAuBj1F,GACrB,MAAMq8B,EAAQ,4BAA4B6rD,KAAKloF,GAC/C,OAAOq8B,GAASA,EAAM,IAAM,EAC9B,CAkkBqBo+D,CAAc/B,EAAQ14F,KAEnCi1F,IAAsD,IAA1C1H,GAAST,UAAU3vF,QAAQ83F,GACzC70D,EAAO,IAAIgpD,EAAW,wBAA0B6L,EAAW,IAAK7L,EAAW0J,gBAAiBhrE,IAM9FuhE,EAAQqR,KAAK/B,GAAe,KAC9B,EACF,EA6CIgC,GA3CmB,CAACC,EAASt9D,KAC/B,MAAM,OAAC99B,GAAWo7F,EAAUA,EAAUA,EAAQn9E,OAAOtjB,SAAW,GAEhE,GAAImjC,GAAW99B,EAAQ,CACrB,IAEIg7F,EAFAK,EAAa,IAAIC,gBAIrB,MAAMlB,EAAU,SAAUmB,GACxB,IAAKP,EAAS,CACZA,GAAU,EACVtB,IACA,MAAMr/E,EAAMkhF,aAAkB56D,MAAQ46D,EAASh/F,KAAKg/F,OACpDF,EAAWP,MAAMzgF,aAAeuvE,EAAavvE,EAAM,IAAI84E,GAAc94E,aAAesmB,MAAQtmB,EAAIs0D,QAAUt0D,GAC5G,CACF,EAEA,IAAIo6E,EAAQ32D,GAAWJ,WAAW,KAChC+2D,EAAQ,KACR2F,EAAQ,IAAIxQ,EAAW,WAAW9rD,mBAA0B8rD,EAAW8Q,aACtE58D,GAEH,MAAM47D,EAAc,KACd0B,IACF3G,GAAS72D,aAAa62D,GACtBA,EAAQ,KACR2G,EAAQn2F,QAAQ00F,IACdA,EAAOD,YAAcC,EAAOD,YAAYU,GAAWT,EAAOt6D,oBAAoB,QAAS+6D,KAEzFgB,EAAU,OAIdA,EAAQn2F,QAAS00F,GAAWA,EAAOl6F,iBAAiB,QAAS26F,IAE7D,MAAM,OAACT,GAAU0B,EAIjB,OAFA1B,EAAOD,YAAc,IAAMjT,EAAQF,KAAKmT,GAEjCC,CACT,GAKF,MAAM6B,GAAc,UAAWC,EAAOC,GACpC,IAAIriD,EAAMoiD,EAAME,WAEhB,IAAKD,GAAariD,EAAMqiD,EAEtB,kBADMD,GAIR,IACIzxE,EADA4xE,EAAM,EAGV,KAAOA,EAAMviD,GACXrvB,EAAM4xE,EAAMF,QACND,EAAMpqF,MAAMuqF,EAAK5xE,GACvB4xE,EAAM5xE,CAEV,EA4BM6xE,GAAc,CAACC,EAAQJ,EAAWK,EAAYC,KAClD,MAAMt+E,EA3BUu+E,gBAAiBC,EAAUR,GAC3C,UAAW,MAAMD,KAKAQ,gBAAiBH,GAClC,GAAIA,EAAOv/E,OAAO4/E,eAEhB,kBADOL,GAIT,MAAMM,EAASN,EAAOO,YACtB,IACE,OAAS,CACP,MAAM,KAAC78E,EAAI,MAAEzV,SAAeqyF,EAAOjG,OACnC,GAAI32E,EACF,YAEIzV,CACR,CACF,CAAE,cACMqyF,EAAOvB,QACf,CACF,CAvB4ByB,CAAWJ,SAC5BV,GAAYC,EAAOC,EAE9B,CAuBmBa,CAAUT,EAAQJ,GAEnC,IACIl8E,EADAu0E,EAAQ,EAERyI,EAAa79F,IACV6gB,IACHA,GAAO,EACPw8E,GAAYA,EAASr9F,KAIzB,OAAO,IAAI89F,eAAe,CACxB,UAAMC,CAAKrB,GACT,IACE,MAAM,KAAC77E,EAAI,MAAEzV,SAAe2T,EAAShF,OAErC,GAAI8G,EAGF,OAFDg9E,SACCnB,EAAWz+D,QAIb,IAAIyc,EAAMtvC,EAAM4xF,WAChB,GAAII,EAAY,CACd,IAAIY,EAAc5I,GAAS16C,EAC3B0iD,EAAWY,EACb,CACAtB,EAAWuB,QAAQ,IAAI18B,WAAWn2D,GACpC,CAAE,MAAOsQ,GAEP,MADAmiF,EAAUniF,GACJA,CACR,CACF,EACAwgF,OAAOU,IACLiB,EAAUjB,GACH79E,EAASm/E,WAEjB,CACDC,cAAe,MAMb,WAAC5V,IAAcT,EAEfsW,GAAiB,GAAGC,UAASC,eAAc,CAC/CD,UAASC,aADY,CAEnBxW,EAAQ4C,SAGVoT,eAAgBS,GAAgB,YAAEC,IAChC1W,EAAQ4C,OAGNplD,GAAO,CAACtyB,KAAO5G,KACnB,IACE,QAAS4G,KAAM5G,EACjB,CAAE,MAAOpM,GACP,OAAO,CACT,GAGI4mB,GAAW4pE,IACfA,EAAM1I,EAAQY,MAAM32E,KAAK,CACvB62E,eAAe,GACdwV,GAAgB5N,GAEnB,MAAOiO,MAAOC,EAAQ,QAAEL,EAAO,SAAEC,GAAY9N,EACvCmO,EAAmBD,EAAWnW,GAAWmW,GAA6B,mBAAVD,MAC5DG,EAAqBrW,GAAW8V,GAChCQ,EAAsBtW,GAAW+V,GAEvC,IAAKK,EACH,OAAO,EAGT,MAAMG,EAA4BH,GAAoBpW,GAAWgW,IAE3DQ,EAAaJ,IAA4C,mBAAhBH,IACzC5Q,EAA0C,IAAI4Q,GAAjC1tF,GAAQ88E,EAAQP,OAAOv8E,IACtCwsF,MAAOxsF,GAAQ,IAAIywD,iBAAiB,IAAI88B,EAAQvtF,GAAKkuF,gBADrD,IAAEpR,EAIN,MAAMqR,EAAwBL,GAAsBE,GAA6Bx5D,GAAK,KACpF,IAAI45D,GAAiB,EAErB,MAAMC,EAAiB,IAAId,EAAQjP,GAASD,OAAQ,CAClDtuF,KAAM,IAAI09F,GACV/9E,OAAQ,OACR,UAAI4+E,GAEF,OADAF,GAAiB,EACV,MACT,IACCz1F,QAAQyQ,IAAI,gBAEf,OAAOglF,IAAmBC,IAGtBE,EAAyBR,GAAuBC,GACpDx5D,GAAK,IAAMwiD,EAAQ7B,iBAAiB,IAAIqY,EAAS,IAAIz9F,OAEjDy+F,EAAY,CAChBnC,OAAQkC,GAA0B,CAAElqF,GAAQA,EAAItU,OAGlD89F,GACE,CAAC,OAAQ,cAAe,OAAQ,WAAY,UAAUr4F,QAAQvK,KAC3DujG,EAAUvjG,KAAUujG,EAAUvjG,GAAQ,CAACoZ,EAAKwU,KAC3C,IAAInJ,EAASrL,GAAOA,EAAIpZ,GAExB,GAAIykB,EACF,OAAOA,EAAOzO,KAAKoD,GAGrB,MAAM,IAAI81E,EAAW,kBAAkBlvF,sBAA0BkvF,EAAWsU,gBAAiB51E,OAyCnG,OAAO2zE,MAAO3zE,IACZ,IAAI,IACF9nB,EAAG,OACH2e,EAAM,KACN9jB,EAAI,OACJs+F,EAAM,YACN1B,EAAW,QACXn6D,EAAO,mBACP65D,EAAkB,iBAClBD,EAAgB,aAChBnI,EAAY,QACZnnF,EAAO,gBACPovF,EAAkB,cAAa,aAC/B2G,GACE9F,GAAc/vE,GAEd81E,EAASf,GAAYD,MAEzB7N,EAAeA,GAAgBA,EAAe,IAAIr9E,cAAgB,OAElE,IAAImsF,EAAiBlD,GAAiB,CAACxB,EAAQ1B,GAAeA,EAAYqG,iBAAkBxgE,GAExF+rD,EAAU,KAEd,MAAM6P,EAAc2E,GAAkBA,EAAe3E,aAAe,MAClE2E,EAAe3E,aAChB,GAED,IAAI6E,EAEJ,IACE,GACE7G,GAAoBkG,GAAoC,QAAXz+E,GAA+B,SAAXA,GACG,KAAnEo/E,OAvCmBtC,OAAO7zF,EAAS5I,KACxC,MAAMQ,EAASymF,EAAQ2C,eAAehhF,EAAQo2F,oBAE9C,OAAiB,MAAVx+F,EAjCai8F,OAAOz8F,IAC3B,GAAY,MAARA,EACF,OAAO,EAGT,GAAIinF,EAAQhC,OAAOjlF,GACjB,OAAOA,EAAKsW,KAGd,GAAI2wE,EAAQ6C,oBAAoB9pF,GAAO,CACrC,MAAMi/F,EAAW,IAAIzB,EAAQjP,GAASD,OAAQ,CAC5C3uE,OAAQ,OACR3f,SAEF,aAAci/F,EAASd,eAAehC,UACxC,CAEA,OAAIlV,EAAQK,kBAAkBtnF,IAASinF,EAAQrC,cAAc5kF,GACpDA,EAAKm8F,YAGVlV,EAAQ9B,kBAAkBnlF,KAC5BA,GAAc,IAGZinF,EAAQpC,SAAS7kF,UACLk+F,EAAWl+F,IAAOm8F,gBADlC,IAQwB+C,CAAcl/F,GAAQQ,GAoCZ2+F,CAAkBv2F,EAAS/M,IACzD,CACA,IAMIujG,EANAH,EAAW,IAAIzB,EAAQx8F,EAAK,CAC9B2e,OAAQ,OACR3f,KAAMnE,EACN0iG,OAAQ,SASV,GAJItX,EAAQC,WAAWrrF,KAAUujG,EAAoBH,EAASr2F,QAAQnJ,IAAI,kBACxEmJ,EAAQ0mF,eAAe8P,GAGrBH,EAASj/F,KAAM,CACjB,MAAOu8F,EAAYz4D,GAAS6xD,GAC1BoJ,EACA/K,GAAqB6B,GAAeqC,KAGtCr8F,EAAOwgG,GAAY4C,EAASj/F,KAvKX,MAuKqCu8F,EAAYz4D,EACpE,CACF,CAEKmjD,EAAQpC,SAASmT,KACpBA,EAAkBA,EAAkB,UAAY,QAKlD,MAAMqH,EAAyBtB,GAAsB,gBAAiBP,EAAQzsF,UAExE4vE,EAAkB,IACnBge,EACHxE,OAAQ0E,EACRl/E,OAAQA,EAAOpN,cACf3J,QAASA,EAAQy3C,YAAYuhC,SAC7B5hF,KAAMnE,EACN0iG,OAAQ,OACRe,YAAaD,EAAyBrH,OAAkBh0F,GAG1DqmF,EAAU0T,GAAsB,IAAIP,EAAQx8F,EAAK2/E,GAEjD,IAAIhhF,QAAkBo+F,EAAqBa,EAAOvU,EAASsU,GAAgBC,EAAO59F,EAAK2/E,IAEvF,MAAM4e,EAAmBf,IAA4C,WAAjBzO,GAA8C,aAAjBA,GAEjF,GAAIyO,IAA2BrG,GAAuBoH,GAAoBrF,GAAe,CACvF,MAAM9rF,EAAU,CAAC,EAEjB,CAAC,SAAU,aAAc,WAAW3I,QAAQusC,IAC1C5jC,EAAQ4jC,GAAQryC,EAASqyC,KAG3B,MAAMwtD,EAAwBvY,EAAQ2C,eAAejqF,EAASiJ,QAAQnJ,IAAI,oBAEnE88F,EAAYz4D,GAASq0D,GAAsBxC,GAChD6J,EACAxL,GAAqB6B,GAAesC,IAAqB,KACtD,GAELx4F,EAAW,IAAI89F,EACbpB,GAAY18F,EAASK,KAlNJ,MAkN8Bu8F,EAAY,KACzDz4D,GAASA,IACTo2D,GAAeA,MAEjB9rF,EAEJ,CAEA2hF,EAAeA,GAAgB,OAE/B,IAAI0P,QAAqBhB,EAAUxX,EAAQxB,QAAQgZ,EAAW1O,IAAiB,QAAQpwF,EAAUmpB,GAIjG,OAFCy2E,GAAoBrF,GAAeA,UAEvB,IAAIrwE,QAAQ,CAACC,EAASsX,KACjCyyD,GAAO/pE,EAASsX,EAAQ,CACtBvlC,KAAM4jG,EACN72F,QAAS2qF,GAAe1pF,KAAKlK,EAASiJ,SACtCE,OAAQnJ,EAASmJ,OACjB0xF,WAAY76F,EAAS66F,WACrB1xE,SACAuhE,aAGN,CAAE,MAAOxvE,GAGP,GAFAq/E,GAAeA,IAEXr/E,GAAoB,cAAbA,EAAI9f,MAAwB,qBAAqB0pC,KAAK5pB,EAAIs0D,SACnE,MAAMzxE,OAAOiT,OACX,IAAIy5E,EAAW,gBAAiBA,EAAW2Q,YAAajyE,EAAQuhE,GAChE,CACEa,MAAOrwE,EAAIqwE,OAASrwE,IAK1B,MAAMuvE,EAAWvgF,KAAKgR,EAAKA,GAAOA,EAAImnD,KAAMl5C,EAAQuhE,EACtD,IAIEqV,GAAY,IAAItiF,IAEhBuiF,GAAY72E,IAChB,IAAI6mE,EAAO7mE,GAAUA,EAAO6mE,KAAQ,CAAC,EACrC,MAAM,MAACiO,EAAK,QAAEJ,EAAO,SAAEC,GAAY9N,EAC7BiQ,EAAQ,CACZpC,EAASC,EAAUG,GAGrB,IACEiC,EAAM3/F,EADgB4Q,EAAd8uF,EAAMp/F,OACA0P,EAAMwvF,GAEtB,KAAO5uF,KACL+uF,EAAOD,EAAM9uF,GACb5Q,EAASgQ,EAAIzQ,IAAIogG,QAEN77F,IAAX9D,GAAwBgQ,EAAIiN,IAAI0iF,EAAM3/F,EAAU4Q,EAAI,IAAIsM,IAAQ2I,GAAQ4pE,IAExEz/E,EAAMhQ,EAGR,OAAOA,GAGTy/F,KAWA,MAAMG,GAAgB,CACpBC,KAtoEgB,KAuoEhBC,IAAKxG,GACLoE,MAAO,CACLn+F,IAAKkgG,KAKT1Y,EAAQxhF,QAAQq6F,GAAe,CAAC3tF,EAAI5H,KAClC,GAAI4H,EAAI,CACN,IACEzU,OAAO4V,eAAenB,EAAI,OAAQ,CAAE5H,SACtC,CAAE,MAAOpL,GAET,CACAzB,OAAO4V,eAAenB,EAAI,cAAe,CAAE5H,SAC7C,IASF,MAAM01F,GAAgBlE,GAAW,KAAKA,IAQhCmE,GAAoBlR,GAAY/H,EAAQS,WAAWsH,IAAwB,OAAZA,IAAgC,IAAZA,EAgEzF,IAAImR,GApDJ,SAAoBA,EAAUr3E,GAC5Bq3E,EAAWlZ,EAAQ91E,QAAQgvF,GAAYA,EAAW,CAACA,GAEnD,MAAM,OAAE3/F,GAAW2/F,EACnB,IAAIC,EACApR,EAEJ,MAAMqR,EAAkB,CAAC,EAEzB,IAAK,IAAIvvF,EAAI,EAAGA,EAAItQ,EAAQsQ,IAAK,CAE/B,IAAIxP,EAIJ,GALA8+F,EAAgBD,EAASrvF,GAGzBk+E,EAAUoR,GAELF,GAAiBE,KACpBpR,EAAU8Q,IAAex+F,EAAK5F,OAAO0kG,IAAgB1tF,oBAErC1O,IAAZgrF,GACF,MAAM,IAAI5E,EAAW,oBAAoB9oF,MAI7C,GAAI0tF,IAAY/H,EAAQS,WAAWsH,KAAaA,EAAUA,EAAQvvF,IAAIqpB,KACpE,MAGFu3E,EAAgB/+F,GAAM,IAAMwP,GAAKk+E,CACnC,CAEA,IAAKA,EAAS,CACZ,MAAMsR,EAAU5iG,OAAO6Y,QAAQ8pF,GAC5BnwF,IAAI,EAAE5O,EAAI2xB,KAAW,WAAW3xB,OACpB,IAAV2xB,EAAkB,sCAAwC,kCAO/D,MAAM,IAAIm3D,EACR,yDALM5pF,EACL8/F,EAAQ9/F,OAAS,EAAI,YAAc8/F,EAAQpwF,IAAI+vF,IAAclhF,KAAK,MAAQ,IAAMkhF,GAAaK,EAAQ,IACtG,2BAIA,kBAEJ,CAEA,OAAOtR,CACT,EA0BA,SAASuR,GAA6Bz3E,GAKpC,GAJIA,EAAO2vE,aACT3vE,EAAO2vE,YAAY+H,mBAGjB13E,EAAOqxE,QAAUrxE,EAAOqxE,OAAOqB,QACjC,MAAM,IAAI7H,GAAc,KAAM7qE,EAElC,CASA,SAAS23E,GAAgB33E,GAiBvB,OAhBAy3E,GAA6Bz3E,GAE7BA,EAAOlgB,QAAU2qF,GAAe1pF,KAAKif,EAAOlgB,SAG5CkgB,EAAOjtB,KAAO23F,GAActiF,KAC1B4X,EACAA,EAAOmmE,mBAGgD,IAArD,CAAC,OAAQ,MAAO,SAAS9wF,QAAQ2qB,EAAOnJ,SAC1CmJ,EAAOlgB,QAAQ0mF,eAAe,qCAAqC,GAGrD6Q,GAAoBr3E,EAAOkmE,SAAWyB,GAAWzB,QAASlmE,EAEnEkmE,CAAQlmE,GAAQppB,KAAK,SAA6BC,GAYvD,OAXA4gG,GAA6Bz3E,GAG7BnpB,EAAS9D,KAAO23F,GAActiF,KAC5B4X,EACAA,EAAO+mE,kBACPlwF,GAGFA,EAASiJ,QAAU2qF,GAAe1pF,KAAKlK,EAASiJ,SAEzCjJ,CACT,EAAG,SAA4Bo8F,GAe7B,OAdKtI,GAASsI,KACZwE,GAA6Bz3E,GAGzBizE,GAAUA,EAAOp8F,WACnBo8F,EAAOp8F,SAAS9D,KAAO23F,GAActiF,KACnC4X,EACAA,EAAO+mE,kBACPkM,EAAOp8F,UAETo8F,EAAOp8F,SAASiJ,QAAU2qF,GAAe1pF,KAAKkyF,EAAOp8F,SAASiJ,WAI3DihB,QAAQuX,OAAO26D,EACxB,EACF,CAEA,MAAM2E,GAAU,SAEVC,GAAe,CAAC,EAGtB,CAAC,SAAU,UAAW,SAAU,WAAY,SAAU,UAAUl7F,QAAQ,CAACvK,EAAM4V,KAC7E6vF,GAAazlG,GAAQ,SAAmBopF,GACtC,cAAcA,IAAUppF,GAAQ,KAAO4V,EAAI,EAAI,KAAO,KAAO5V,CAC/D,IAGF,MAAM0lG,GAAqB,CAAC,EAW5BD,GAAa5R,aAAe,SAAsB8R,EAAW/lF,EAASq0D,GACpE,SAAS2xB,EAAc31D,EAAK41D,GAC1B,MAAO,WAAaL,GAAU,0BAA6Bv1D,EAAM,IAAO41D,GAAQ5xB,EAAU,KAAOA,EAAU,GAC7G,CAGA,MAAO,CAAC5kE,EAAO4gC,EAAK3M,KAClB,IAAkB,IAAdqiE,EACF,MAAM,IAAIzW,EACR0W,EAAc31D,EAAK,qBAAuBrwB,EAAU,OAASA,EAAU,KACvEsvE,EAAW4W,gBAef,OAXIlmF,IAAY8lF,GAAmBz1D,KACjCy1D,GAAmBz1D,IAAO,EAE1BvjC,QAAQq5F,KACNH,EACE31D,EACA,+BAAiCrwB,EAAU,8CAK1C+lF,GAAYA,EAAUt2F,EAAO4gC,EAAK3M,GAE7C,EAEAmiE,GAAaO,SAAW,SAAkBC,GACxC,MAAO,CAAC52F,EAAO4gC,KAEbvjC,QAAQq5F,KAAK,GAAG91D,gCAAkCg2D,MAC3C,EAEX,EAmCA,IAAIN,GAAY,CACdO,cAxBF,SAAuBhzF,EAASizF,EAAQC,GACtC,GAAuB,iBAAZlzF,EACT,MAAM,IAAIg8E,EAAW,4BAA6BA,EAAWmX,sBAE/D,MAAM3rF,EAAOlY,OAAOkY,KAAKxH,GACzB,IAAI0C,EAAI8E,EAAKpV,OACb,KAAOsQ,KAAM,GAAG,CACd,MAAMq6B,EAAMv1B,EAAK9E,GACX+vF,EAAYQ,EAAOl2D,GACzB,GAAI01D,EAAW,CACb,MAAMt2F,EAAQ6D,EAAQ+8B,GAChBprB,OAAmB/b,IAAVuG,GAAuBs2F,EAAUt2F,EAAO4gC,EAAK/8B,GAC5D,IAAe,IAAX2R,EACF,MAAM,IAAIqqE,EAAW,UAAYj/C,EAAM,YAAcprB,EAAQqqE,EAAWmX,sBAE1E,QACF,CACA,IAAqB,IAAjBD,EACF,MAAM,IAAIlX,EAAW,kBAAoBj/C,EAAKi/C,EAAWoX,eAE7D,CACF,EAIEC,WAAYd,IAGd,MAAMc,GAAaZ,GAAUY,WAS7B,MAAMC,GACJ,WAAAzqF,CAAY0qF,GACV5kG,KAAK2tC,SAAWi3D,GAAkB,CAAC,EACnC5kG,KAAK6kG,aAAe,CAClBvX,QAAS,IAAI2C,GACbrtF,SAAU,IAAIqtF,GAElB,CAUA,aAAM3C,CAAQwX,EAAa/4E,GACzB,IACE,aAAa/rB,KAAKkiG,SAAS4C,EAAa/4E,EAC1C,CAAE,MAAOjO,GACP,GAAIA,aAAesmB,MAAO,CACxB,IAAI2gE,EAAQ,CAAC,EAEb3gE,MAAMmpD,kBAAoBnpD,MAAMmpD,kBAAkBwX,GAAUA,EAAQ,IAAI3gE,MAGxE,MAAMjZ,EAAQ45E,EAAM55E,MAAQ45E,EAAM55E,MAAM3b,QAAQ,QAAS,IAAM,GAC/D,IACOsO,EAAIqN,MAGEA,IAAUxsB,OAAOmf,EAAIqN,OAAOqU,SAASrU,EAAM3b,QAAQ,YAAa,OACzEsO,EAAIqN,OAAS,KAAOA,GAHpBrN,EAAIqN,MAAQA,CAKhB,CAAE,MAAO/oB,GAET,CACF,CAEA,MAAM0b,CACR,CACF,CAEA,QAAAokF,CAAS4C,EAAa/4E,GAGO,iBAAhB+4E,GACT/4E,EAASA,GAAU,CAAC,GACb9nB,IAAM6gG,EAEb/4E,EAAS+4E,GAAe,CAAC,EAG3B/4E,EAASuuE,GAAYt6F,KAAK2tC,SAAU5hB,GAEpC,MAAM,aAACimE,EAAY,iBAAE+I,EAAgB,QAAElvF,GAAWkgB,OAE7B9kB,IAAjB+qF,GACF8R,GAAUO,cAAcrS,EAAc,CACpCvB,kBAAmBiU,GAAW1S,aAAa0S,GAAWM,SACtDtU,kBAAmBgU,GAAW1S,aAAa0S,GAAWM,SACtDrU,oBAAqB+T,GAAW1S,aAAa0S,GAAWM,WACvD,GAGmB,MAApBjK,IACE7Q,EAAQS,WAAWoQ,GACrBhvE,EAAOgvE,iBAAmB,CACxBnL,UAAWmL,GAGb+I,GAAUO,cAActJ,EAAkB,CACxCtL,OAAQiV,GAAWO,SACnBrV,UAAW8U,GAAWO,WACrB,SAK0Bh+F,IAA7B8kB,EAAOkuE,yBAAgFhzF,IAApCjH,KAAK2tC,SAASssD,kBACnEluE,EAAOkuE,kBAAoBj6F,KAAK2tC,SAASssD,kBAEzCluE,EAAOkuE,mBAAoB,GAG7B6J,GAAUO,cAAct4E,EAAQ,CAC9Bm5E,QAASR,GAAWP,SAAS,WAC7BgB,cAAeT,GAAWP,SAAS,mBAClC,GAGHp4E,EAAOnJ,QAAUmJ,EAAOnJ,QAAU5iB,KAAK2tC,SAAS/qB,QAAU,OAAOjN,cAGjE,IAAIyvF,EAAiBv5F,GAAWq+E,EAAQY,MACtCj/E,EAAQ4nF,OACR5nF,EAAQkgB,EAAOnJ,SAGjB/W,GAAWq+E,EAAQxhF,QACjB,CAAC,SAAU,MAAO,OAAQ,OAAQ,MAAO,QAAS,UACjDka,WACQ/W,EAAQ+W,KAInBmJ,EAAOlgB,QAAU2qF,GAAep1E,OAAOgkF,EAAgBv5F,GAGvD,MAAMw5F,EAA0B,GAChC,IAAIC,GAAiC,EACrCtlG,KAAK6kG,aAAavX,QAAQ5kF,QAAQ,SAAoC68F,GACjC,mBAAxBA,EAAYjV,UAA0D,IAAhCiV,EAAYjV,QAAQvkE,KAIrEu5E,EAAiCA,GAAkCC,EAAYlV,YAE/EgV,EAAwB1iF,QAAQ4iF,EAAYpV,UAAWoV,EAAYnV,UACrE,GAEA,MAAMoV,EAA2B,GAKjC,IAAIC,EAJJzlG,KAAK6kG,aAAajiG,SAAS8F,QAAQ,SAAkC68F,GACnEC,EAAyB7qF,KAAK4qF,EAAYpV,UAAWoV,EAAYnV,SACnE,GAGA,IACItzC,EADA/oC,EAAI,EAGR,IAAKuxF,EAAgC,CACnC,MAAMI,EAAQ,CAAChC,GAAgBtkF,KAAKpf,WAAOiH,GAO3C,IANAy+F,EAAM/iF,WAAW0iF,GACjBK,EAAM/qF,QAAQ6qF,GACd1oD,EAAM4oD,EAAMjiG,OAEZgiG,EAAU34E,QAAQC,QAAQhB,GAEnBhY,EAAI+oC,GACT2oD,EAAUA,EAAQ9iG,KAAK+iG,EAAM3xF,KAAM2xF,EAAM3xF,MAG3C,OAAO0xF,CACT,CAEA3oD,EAAMuoD,EAAwB5hG,OAE9B,IAAIs4F,EAAYhwE,EAEhB,KAAOhY,EAAI+oC,GAAK,CACd,MAAM6oD,EAAcN,EAAwBtxF,KACtC6xF,EAAaP,EAAwBtxF,KAC3C,IACEgoF,EAAY4J,EAAY5J,EAC1B,CAAE,MAAOttF,GACPm3F,EAAWzxF,KAAKnU,KAAMyO,GACtB,KACF,CACF,CAEA,IACEg3F,EAAU/B,GAAgBvvF,KAAKnU,KAAM+7F,EACvC,CAAE,MAAOttF,GACP,OAAOqe,QAAQuX,OAAO51B,EACxB,CAKA,IAHAsF,EAAI,EACJ+oC,EAAM0oD,EAAyB/hG,OAExBsQ,EAAI+oC,GACT2oD,EAAUA,EAAQ9iG,KAAK6iG,EAAyBzxF,KAAMyxF,EAAyBzxF,MAGjF,OAAO0xF,CACT,CAEA,MAAAI,CAAO95E,GAGL,OAAO2jE,GADUoK,IADjB/tE,EAASuuE,GAAYt6F,KAAK2tC,SAAU5hB,IACEguE,QAAShuE,EAAO9nB,IAAK8nB,EAAOkuE,mBACxCluE,EAAOtiB,OAAQsiB,EAAOgvE,iBAClD,EAIF7Q,EAAQxhF,QAAQ,CAAC,SAAU,MAAO,OAAQ,WAAY,SAA6Bka,GAEjF+hF,GAAM3wF,UAAU4O,GAAU,SAAS3e,EAAK8nB,GACtC,OAAO/rB,KAAKstF,QAAQgN,GAAYvuE,GAAU,CAAC,EAAG,CAC5CnJ,SACA3e,MACAnF,MAAOitB,GAAU,CAAC,GAAGjtB,OAEzB,CACF,GAEAorF,EAAQxhF,QAAQ,CAAC,OAAQ,MAAO,SAAU,SAA+Bka,GAGvE,SAASkjF,EAAmBC,GAC1B,OAAO,SAAoB9hG,EAAKnF,EAAMitB,GACpC,OAAO/rB,KAAKstF,QAAQgN,GAAYvuE,GAAU,CAAC,EAAG,CAC5CnJ,SACA/W,QAASk6F,EAAS,CAChB,eAAgB,uBACd,CAAC,EACL9hG,MACAnF,SAEJ,CACF,CAEA6lG,GAAM3wF,UAAU4O,GAAUkjF,IAE1BnB,GAAM3wF,UAAU4O,EAAS,QAAUkjF,GAAmB,EACxD,GAEA,IAAIE,GAAUrB,GASd,MAAMsB,GACJ,WAAA/rF,CAAYgsF,GACV,GAAwB,mBAAbA,EACT,MAAM,IAAI3X,UAAU,gCAGtB,IAAI4X,EAEJnmG,KAAKylG,QAAU,IAAI34E,QAAQ,SAAyBC,GAClDo5E,EAAiBp5E,CACnB,GAEA,MAAM88D,EAAQ7pF,KAGdA,KAAKylG,QAAQ9iG,KAAK27F,IAChB,IAAKzU,EAAMuc,WAAY,OAEvB,IAAIryF,EAAI81E,EAAMuc,WAAW3iG,OAEzB,KAAOsQ,KAAM,GACX81E,EAAMuc,WAAWryF,GAAGuqF,GAEtBzU,EAAMuc,WAAa,OAIrBpmG,KAAKylG,QAAQ9iG,KAAO0jG,IAClB,IAAIC,EAEJ,MAAMb,EAAU,IAAI34E,QAAQC,IAC1B88D,EAAM2U,UAAUzxE,GAChBu5E,EAAWv5E,IACVpqB,KAAK0jG,GAMR,OAJAZ,EAAQnH,OAAS,WACfzU,EAAMsT,YAAYmJ,EACpB,EAEOb,GAGTS,EAAS,SAAgB9zB,EAASrmD,EAAQuhE,GACpCzD,EAAMmV,SAKVnV,EAAMmV,OAAS,IAAIpI,GAAcxkB,EAASrmD,EAAQuhE,GAClD6Y,EAAetc,EAAMmV,QACvB,EACF,CAKA,gBAAAyE,GACE,GAAIzjG,KAAKg/F,OACP,MAAMh/F,KAAKg/F,MAEf,CAMA,SAAAR,CAAUtH,GACJl3F,KAAKg/F,OACP9H,EAASl3F,KAAKg/F,QAIZh/F,KAAKomG,WACPpmG,KAAKomG,WAAWzrF,KAAKu8E,GAErBl3F,KAAKomG,WAAa,CAAClP,EAEvB,CAMA,WAAAiG,CAAYjG,GACV,IAAKl3F,KAAKomG,WACR,OAEF,MAAMxhG,EAAQ5E,KAAKomG,WAAWhlG,QAAQ81F,IACvB,IAAXtyF,GACF5E,KAAKomG,WAAWvhG,OAAOD,EAAO,EAElC,CAEA,aAAAm9F,GACE,MAAMjD,EAAa,IAAIC,gBAEjBR,EAASzgF,IACbghF,EAAWP,MAAMzgF,IAOnB,OAJA9d,KAAKw+F,UAAUD,GAEfO,EAAW1B,OAAOD,YAAc,IAAMn9F,KAAKm9F,YAAYoB,GAEhDO,EAAW1B,MACpB,CAMA,aAAOz0E,GACL,IAAI21E,EAIJ,MAAO,CACLzU,MAJY,IAAIoc,GAAY,SAAkB1wF,GAC9C+oF,EAAS/oF,CACX,GAGE+oF,SAEJ,EAGF,IAAIiI,GAAgBN,GAwCpB,MAAMO,GAAiB,CACrBC,SAAU,IACVC,mBAAoB,IACpBC,WAAY,IACZC,WAAY,IACZC,GAAI,IACJC,QAAS,IACTC,SAAU,IACVC,4BAA6B,IAC7BC,UAAW,IACXC,aAAc,IACdC,eAAgB,IAChBC,YAAa,IACbC,gBAAiB,IACjBC,OAAQ,IACRC,gBAAiB,IACjBC,iBAAkB,IAClBC,MAAO,IACPC,SAAU,IACVC,YAAa,IACbC,SAAU,IACVC,OAAQ,IACRC,kBAAmB,IACnBC,kBAAmB,IACnBC,WAAY,IACZC,aAAc,IACdC,gBAAiB,IACjBC,UAAW,IACXC,SAAU,IACVC,iBAAkB,IAClBC,cAAe,IACfC,4BAA6B,IAC7BC,eAAgB,IAChBC,SAAU,IACVC,KAAM,IACNC,eAAgB,IAChBC,mBAAoB,IACpBC,gBAAiB,IACjBC,WAAY,IACZC,qBAAsB,IACtBC,oBAAqB,IACrBC,kBAAmB,IACnBC,UAAW,IACXC,mBAAoB,IACpBC,oBAAqB,IACrBC,OAAQ,IACRC,iBAAkB,IAClBC,SAAU,IACVC,gBAAiB,IACjBC,qBAAsB,IACtBC,gBAAiB,IACjBC,4BAA6B,IAC7BC,2BAA4B,IAC5BC,oBAAqB,IACrBC,eAAgB,IAChBC,WAAY,IACZC,mBAAoB,IACpBC,eAAgB,IAChBC,wBAAyB,IACzBC,sBAAuB,IACvBC,oBAAqB,IACrBC,aAAc,IACdC,YAAa,IACbC,8BAA+B,IAC/BC,gBAAiB,IACjBC,mBAAoB,IACpBC,oBAAqB,IACrBC,gBAAiB,IACjBC,mBAAoB,IACpBC,sBAAuB,KAGzBlqG,OAAO6Y,QAAQgtF,IAAgB99F,QAAQ,EAAE5D,EAAK0I,MAC5Cg5F,GAAeh5F,GAAS1I,IAG1B,IAAIgmG,GAAmBtE,GA4BvB,MAAM/jG,GAnBN,SAASsoG,EAAeC,GACtB,MAAM94D,EAAU,IAAI8zD,GAAQgF,GACtBz/E,EAAWnM,EAAK4mF,GAAQhyF,UAAUs5E,QAASp7C,GAajD,OAVAg4C,EAAQiB,OAAO5/D,EAAUy6E,GAAQhyF,UAAWk+B,EAAS,CAACu2C,YAAY,IAGlEyB,EAAQiB,OAAO5/D,EAAU2mB,EAAS,KAAM,CAACu2C,YAAY,IAGrDl9D,EAASnY,OAAS,SAAgBwxF,GAChC,OAAOmG,EAAezQ,GAAY0Q,EAAepG,GACnD,EAEOr5E,CACT,CAGcw/E,CAAerX,IAG7BjxF,GAAMkiG,MAAQqB,GAGdvjG,GAAMm0F,cAAgBA,GACtBn0F,GAAMwjG,YAAcM,GACpB9jG,GAAMi0F,SAAWA,GACjBj0F,GAAMkhG,QAAUA,GAChBlhG,GAAM4rF,WAAaA,GAGnB5rF,GAAM4qF,WAAaA,EAGnB5qF,GAAMwoG,OAASxoG,GAAMm0F,cAGrBn0F,GAAMyoG,IAAM,SAAaC,GACvB,OAAOr+E,QAAQo+E,IAAIC,EACrB,EAEA1oG,GAAM2oG,OAhJN,SAAgBllF,GACd,OAAO,SAAcrS,GACnB,OAAOqS,EAAS1E,MAAM,KAAM3N,EAC9B,CACF,EA+IApR,GAAM4oG,aAtIN,SAAsBC,GACpB,OAAOphB,EAAQlC,SAASsjB,KAAsC,IAAzBA,EAAQD,YAC/C,EAuIA5oG,GAAM63F,YAAcA,GAEpB73F,GAAMyxF,aAAesC,GAErB/zF,GAAM8oG,WAAahkB,GAASmK,GAAexH,EAAQnB,WAAWxB,GAAS,IAAI8C,SAAS9C,GAASA,GAE7F9kF,GAAM+oG,WAAapI,GAEnB3gG,GAAM+jG,eAAiBsE,GAEvBroG,GAAMpE,QAAUoE,GAEhBgpG,EAAO14F,QAAUtQ,E,GCl0HbipG,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqB3kG,IAAjB4kG,EACH,OAAOA,EAAa94F,QAGrB,IAAI04F,EAASC,EAAyBE,GAAY,CAGjD74F,QAAS,CAAC,GAOX,OAHA+4F,EAAoBF,GAAUH,EAAQA,EAAO14F,QAAS44F,GAG/CF,EAAO14F,OACf,CCrBA44F,EAAoBpmG,EAAI,CAACwN,EAASg5F,KACjC,IAAI,IAAIjnG,KAAOinG,EACXJ,EAAoBl5E,EAAEs5E,EAAYjnG,KAAS6mG,EAAoBl5E,EAAE1f,EAASjO,IAC5EnE,OAAO4V,eAAexD,EAASjO,EAAK,CAAE2R,YAAY,EAAM/T,IAAKqpG,EAAWjnG,MCJ3E6mG,EAAoBt0F,EAAI,WACvB,GAA0B,iBAAfF,WAAyB,OAAOA,WAC3C,IACC,OAAOnX,MAAQ,IAAI02B,SAAS,cAAb,EAChB,CAAE,MAAOt0B,GACR,GAAsB,iBAAXqC,OAAqB,OAAOA,MACxC,CACA,CAPuB,GCAxBknG,EAAoBl5E,EAAI,CAACpc,EAAK4+B,IAAUt0C,OAAOqT,UAAUC,eAAeE,KAAKkC,EAAK4+B,GCClF02D,EAAoB5jF,EAAKhV,IACH,oBAAXiN,QAA0BA,OAAOwkB,aAC1C7jC,OAAO4V,eAAexD,EAASiN,OAAOwkB,YAAa,CAAEh3B,MAAO,WAE7D7M,OAAO4V,eAAexD,EAAS,aAAc,CAAEvF,OAAO,KCLvD/I,OAAOunG,kBAAoB,WACvB,IAEIvnG,OAAOoM,IAAMo7F,EAAQ,KACrBxnG,OAAOhC,MAAQwpG,EAAQ,KACvBxnG,OAAOhC,MAAQgC,OAAOhC,MAAM2Q,OAAO,CAC/B2mF,QAASr4F,qBAAqBwqG,SAC9BrgG,QAAS,CACL,aAAcnK,qBAAqB0yD,MACnC,eAAgB,sBAIxB63C,EAAQ,IACZ,CAAE,MAAO7pG,GAET,CACJ,EAEAqC,OAAO0nG,kBAAoB,WACvB,IAAIC,EAAuB3nG,OAAOC,SAASV,KAG3C,GAAK,YAFLooG,EAAuB,IAAItb,gBAAiBsb,IAEL1pG,IAAK,UAAa,CACrD,IAAI2pG,EAAcC,YAAa,WAE3B,IAAIx4F,EAAK9Q,SAASyF,iBAAkB,gCAC/BqL,EAAGrQ,SACJqQ,EAAG,GAAGy4F,QACNC,cAAeH,GAEvB,EAAG,IACP,CACJ,EAEK,0BAA4B3qG,qBAAqB+qG,UAClDhoG,OAAOunG,oBACC,qCAAuCtqG,qBAAqB+qG,WACpEhoG,OAAO0nG,mB","sources":["webpack://saa-new-dashboard/./src/components/post-smtp-app-wrapper.vue","webpack://saa-new-dashboard/./src/components/post-smtp-app-wrapper.vue?2883","webpack://saa-new-dashboard/./src/components/post-smtp-header.vue","webpack://saa-new-dashboard/./src/components/post-smtp-header.vue?1f2f","webpack://saa-new-dashboard/./src/components/post-smtp-img.vue","webpack://saa-new-dashboard/./src/components/post-smtp-img.vue?b894","webpack://saa-new-dashboard/./src/components/post-smtp-settings.vue","webpack://saa-new-dashboard/./src/components/post-smtp-settings.vue?387e","webpack://saa-new-dashboard/./src/components/post-smtp-settings-menu.vue","webpack://saa-new-dashboard/./src/components/post-smtp-settings-menu.vue?3b07","webpack://saa-new-dashboard/./src/components/post-smtp-notification-bar.vue","webpack://saa-new-dashboard/./src/components/post-smtp-notification-bar.vue?a74c","webpack://saa-new-dashboard/./src/components/post-smtp-sidebar.vue","webpack://saa-new-dashboard/./src/components/post-smtp-sidebar.vue?5ebd","webpack://saa-new-dashboard/./src/components/post-smtp-widget.vue","webpack://saa-new-dashboard/./src/components/post-smtp-widget.vue?63cf","webpack://saa-new-dashboard/./src/components/post-smtp-ads.vue","webpack://saa-new-dashboard/./src/components/post-smtp-ads.vue?c8fe","webpack://saa-new-dashboard/./src/components/post-smtp-button.vue","webpack://saa-new-dashboard/./src/components/post-smtp-button.vue?a978","webpack://saa-new-dashboard/./src/components/post-smtp-dashboard.vue","webpack://saa-new-dashboard/./src/components/post-smtp-dashboard.vue?3ca5","webpack://saa-new-dashboard/./src/components/post-smtp-days-selector.vue","webpack://saa-new-dashboard/./src/components/post-smtp-days-selector.vue?fd71","webpack://saa-new-dashboard/./src/components/post-smtp-cards-container.vue","webpack://saa-new-dashboard/./src/components/post-smtp-cards-container.vue?4c8f","webpack://saa-new-dashboard/./src/components/post-smtp-card.vue","webpack://saa-new-dashboard/./src/components/post-smtp-card.vue?cff1","webpack://saa-new-dashboard/./src/components/post-smtp-banners.vue","webpack://saa-new-dashboard/./src/components/post-smtp-banners.vue?8776","webpack://saa-new-dashboard/./src/components/post-smtp-notice.vue","webpack://saa-new-dashboard/./src/components/post-smtp-notice.vue?a44f","webpack://saa-new-dashboard/./src/components/post-smtp-logs-section.vue","webpack://saa-new-dashboard/./src/components/post-smtp-logs-section.vue?18bd","webpack://saa-new-dashboard/./src/components/post-smtp-log-action-menu.vue","webpack://saa-new-dashboard/./src/components/post-smtp-log-action-menu.vue?1202","webpack://saa-new-dashboard/./src/components/post-smtp-pro-features.vue","webpack://saa-new-dashboard/./src/components/post-smtp-pro-features.vue?fd59","webpack://saa-new-dashboard/./src/components/post-smtp-guide.vue","webpack://saa-new-dashboard/./src/components/post-smtp-guide.vue?4578","webpack://saa-new-dashboard/./src/components/post-smtp-documentation.vue","webpack://saa-new-dashboard/./src/components/post-smtp-documentation.vue?140e","webpack://saa-new-dashboard/./src/vue.js","webpack://saa-new-dashboard/./node_modules/vue-loader/dist/exportHelper.js","webpack://saa-new-dashboard/./node_modules/@vue/shared/dist/shared.esm-bundler.js","webpack://saa-new-dashboard/./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js","webpack://saa-new-dashboard/./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js","webpack://saa-new-dashboard/./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js","webpack://saa-new-dashboard/./node_modules/@vue/compiler-core/dist/compiler-core.esm-bundler.js","webpack://saa-new-dashboard/./node_modules/@vue/compiler-dom/dist/compiler-dom.esm-bundler.js","webpack://saa-new-dashboard/./node_modules/vue/dist/vue.esm-bundler.js","webpack://saa-new-dashboard/./node_modules/axios/dist/browser/axios.cjs","webpack://saa-new-dashboard/webpack/bootstrap","webpack://saa-new-dashboard/webpack/runtime/define property getters","webpack://saa-new-dashboard/webpack/runtime/global","webpack://saa-new-dashboard/webpack/runtime/hasOwnProperty shorthand","webpack://saa-new-dashboard/webpack/runtime/make namespace object","webpack://saa-new-dashboard/./src/app.js"],"sourcesContent":["\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-app-wrapper.vue?vue&type=template&id=3112b8ca&scoped=true\"\nimport script from \"./post-smtp-app-wrapper.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-app-wrapper.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-app-wrapper.vue?vue&type=style&index=0&id=3112b8ca&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-3112b8ca\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-header.vue?vue&type=template&id=65055dc1&scoped=true\"\nimport script from \"./post-smtp-header.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-header.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-header.vue?vue&type=style&index=0&id=65055dc1&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-65055dc1\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-img.vue?vue&type=template&id=4c6a7522\"\nimport script from \"./post-smtp-img.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-img.vue?vue&type=script&lang=js\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-settings.vue?vue&type=template&id=84d0a47e&scoped=true\"\nimport script from \"./post-smtp-settings.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-settings.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-settings.vue?vue&type=style&index=0&id=84d0a47e&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-84d0a47e\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-settings-menu.vue?vue&type=template&id=a06ecf4c&scoped=true\"\nimport script from \"./post-smtp-settings-menu.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-settings-menu.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-settings-menu.vue?vue&type=style&index=0&id=a06ecf4c&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-a06ecf4c\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-notification-bar.vue?vue&type=template&id=1d82fd54&scoped=true\"\nimport script from \"./post-smtp-notification-bar.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-notification-bar.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-notification-bar.vue?vue&type=style&index=0&id=1d82fd54&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-1d82fd54\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-sidebar.vue?vue&type=template&id=7b742791&scoped=true\"\nimport script from \"./post-smtp-sidebar.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-sidebar.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-sidebar.vue?vue&type=style&index=0&id=7b742791&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-7b742791\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-widget.vue?vue&type=template&id=61b1c642&scoped=true\"\nimport script from \"./post-smtp-widget.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-widget.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-widget.vue?vue&type=style&index=0&id=61b1c642&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-61b1c642\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-ads.vue?vue&type=template&id=2975379f&scoped=true\"\nimport script from \"./post-smtp-ads.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-ads.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-ads.vue?vue&type=style&index=0&id=2975379f&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-2975379f\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-button.vue?vue&type=template&id=e27b9696&scoped=true\"\nimport script from \"./post-smtp-button.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-button.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-button.vue?vue&type=style&index=0&id=e27b9696&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-e27b9696\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-dashboard.vue?vue&type=template&id=b8fab578&scoped=true\"\nimport script from \"./post-smtp-dashboard.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-dashboard.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-dashboard.vue?vue&type=style&index=0&id=b8fab578&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-b8fab578\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-days-selector.vue?vue&type=template&id=0ba96be9&scoped=true\"\nimport script from \"./post-smtp-days-selector.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-days-selector.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-days-selector.vue?vue&type=style&index=0&id=0ba96be9&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-0ba96be9\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-cards-container.vue?vue&type=template&id=2dc01e40&scoped=true\"\nimport script from \"./post-smtp-cards-container.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-cards-container.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-cards-container.vue?vue&type=style&index=0&id=2dc01e40&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-2dc01e40\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-card.vue?vue&type=template&id=3753d82c&scoped=true\"\nimport script from \"./post-smtp-card.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-card.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-card.vue?vue&type=style&index=0&id=3753d82c&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-3753d82c\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-banners.vue?vue&type=template&id=b0a24b2e&scoped=true\"\nimport script from \"./post-smtp-banners.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-banners.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-banners.vue?vue&type=style&index=0&id=b0a24b2e&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-b0a24b2e\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-notice.vue?vue&type=template&id=d473dc1c&scoped=true\"\nimport script from \"./post-smtp-notice.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-notice.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-notice.vue?vue&type=style&index=0&id=d473dc1c&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-d473dc1c\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-logs-section.vue?vue&type=template&id=82c3bb58&scoped=true\"\nimport script from \"./post-smtp-logs-section.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-logs-section.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-logs-section.vue?vue&type=style&index=0&id=82c3bb58&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-82c3bb58\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-log-action-menu.vue?vue&type=template&id=1121e3a1&scoped=true\"\nimport script from \"./post-smtp-log-action-menu.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-log-action-menu.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-log-action-menu.vue?vue&type=style&index=0&id=1121e3a1&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-1121e3a1\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-pro-features.vue?vue&type=template&id=670574d9&scoped=true\"\nimport script from \"./post-smtp-pro-features.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-pro-features.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-pro-features.vue?vue&type=style&index=0&id=670574d9&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-670574d9\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-guide.vue?vue&type=template&id=7fb6e671&scoped=true\"\nimport script from \"./post-smtp-guide.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-guide.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-guide.vue?vue&type=style&index=0&id=7fb6e671&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-7fb6e671\"]])\n\nexport default __exports__","\r\n\r\n\r\n\r\n","import { render } from \"./post-smtp-documentation.vue?vue&type=template&id=7ae3eba2&scoped=true\"\nimport script from \"./post-smtp-documentation.vue?vue&type=script&lang=js\"\nexport * from \"./post-smtp-documentation.vue?vue&type=script&lang=js\"\n\nimport \"./post-smtp-documentation.vue?vue&type=style&index=0&id=7ae3eba2&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-7ae3eba2\"]])\n\nexport default __exports__","// collecting all the components and creating the main app.\r\nlet { Vue, wp, axios } = window,\r\n { i18n } = wp,\r\n { createApp } = Vue;\r\n\r\n// Importing all components from the components folder\r\nimport PostSmtpAppWrapper from \"components/post-smtp-app-wrapper.vue\";\r\nimport PostSMTPHeader from \"components/post-smtp-header.vue\";\r\nimport PostSmtpImg from \"components/post-smtp-img.vue\";\r\nimport PostSmtpSettings from \"components/post-smtp-settings.vue\";\r\nimport PostSmtpSettingsMenu from \"components/post-smtp-settings-menu.vue\";\r\nimport PostSmtpNotificationBar from \"components/post-smtp-notification-bar.vue\";\r\nimport PostSmtpSidebar from \"components/post-smtp-sidebar.vue\";\r\nimport PostSmtpWidget from \"components/post-smtp-widget.vue\";\r\nimport PostSmtpAds from \"components/post-smtp-ads.vue\";\r\nimport PostSmtpButton from \"components/post-smtp-button.vue\";\r\nimport PostSmtpDashboard from \"components/post-smtp-dashboard.vue\";\r\nimport PostSmtpDaysSelector from \"components/post-smtp-days-selector.vue\";\r\nimport PostSmtpCardsContainer from \"components/post-smtp-cards-container.vue\";\r\nimport PostSmtpCard from \"components/post-smtp-card.vue\";\r\nimport PostSmtpBanners from \"components/post-smtp-banners.vue\";\r\nimport PostSmtpNotice from \"components/post-smtp-notice.vue\";\r\nimport PostSmtpLogsSection from \"components/post-smtp-logs-section.vue\";\r\nimport PostSmtpLogActionMenu from 'components/post-smtp-log-action-menu.vue'\r\nimport PostSmtpProFeatures from \"components/post-smtp-pro-features.vue\";\r\nimport PostSmtpGuide from \"components/post-smtp-guide.vue\";\r\nimport PostSmtpDocumentation from \"components/post-smtp-documentation.vue\";\r\n\r\n// Creating the main app\r\nconst post_smtp__app = createApp( {\r\n\r\n setup: () => ( {\r\n plugin_dir_url: postSmtpNewDashboard.plugin_dir_url,\r\n admin_url: postSmtpNewDashboard.admin_url,\r\n } ),\r\n\r\n data: () => ( {} ),\r\n\r\n watch: {},\r\n\r\n computed: {},\r\n\r\n methods: {},\r\n\r\n mounted() {\r\n },\r\n\r\n} );\r\n\r\n// registering plugins.\r\npost_smtp__app.use( {\r\n install( app, options ) {\r\n app.provide( 'i18n', options );\r\n }\r\n}, i18n );\r\n\r\n// Registering all components\r\npost_smtp__app.component( 'post-smtp-app-wrapper', PostSmtpAppWrapper );\r\npost_smtp__app.component( 'post-smtp-header', PostSMTPHeader );\r\npost_smtp__app.component( 'post-smtp-img', PostSmtpImg );\r\npost_smtp__app.component( 'post-smtp-settings', PostSmtpSettings );\r\npost_smtp__app.component( 'post-smtp-settings-menu', PostSmtpSettingsMenu );\r\npost_smtp__app.component( 'post-smtp-notification-bar', PostSmtpNotificationBar );\r\npost_smtp__app.component( 'post-smtp-sidebar', PostSmtpSidebar );\r\npost_smtp__app.component( 'post-smtp-widget', PostSmtpWidget );\r\npost_smtp__app.component( 'post-smtp-ads', PostSmtpAds );\r\npost_smtp__app.component( 'post-smtp-button', PostSmtpButton );\r\npost_smtp__app.component( 'post-smtp-dashboard', PostSmtpDashboard );\r\npost_smtp__app.component( 'post-smtp-days-selector', PostSmtpDaysSelector );\r\npost_smtp__app.component( 'post-smtp-cards-container', PostSmtpCardsContainer );\r\npost_smtp__app.component( 'post-smtp-card', PostSmtpCard );\r\npost_smtp__app.component( 'post-smtp-banners', PostSmtpBanners );\r\npost_smtp__app.component( 'post-smtp-notice', PostSmtpNotice );\r\npost_smtp__app.component( 'post-smtp-logs-section', PostSmtpLogsSection );\r\npost_smtp__app.component( 'post-smtp-log-action-menu', PostSmtpLogActionMenu );\r\npost_smtp__app.component( 'post-smtp-pro-features', PostSmtpProFeatures );\r\npost_smtp__app.component( 'post-smtp-guide', PostSmtpGuide );\r\npost_smtp__app.component( 'post-smtp-documentation', PostSmtpDocumentation );\r\n\r\n// Mounting the main app\r\npost_smtp__app\r\n .mount( '#post-smtp-app' );\r\nwindow\r\n .$post_smtp__app = post_smtp__app;","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// runtime helper for setting properties on components\n// in a tree-shakable way\nexports.default = (sfc, props) => {\n const target = sfc.__vccOpts || sfc;\n for (const [key, val] of props) {\n target[key] = val;\n }\n return target;\n};\n","/**\n* @vue/shared v3.5.22\n* (c) 2018-present Yuxi (Evan) You and Vue contributors\n* @license MIT\n**/\n// @__NO_SIDE_EFFECTS__\nfunction makeMap(str) {\n const map = /* @__PURE__ */ Object.create(null);\n for (const key of str.split(\",\")) map[key] = 1;\n return (val) => val in map;\n}\n\nconst EMPTY_OBJ = !!(process.env.NODE_ENV !== \"production\") ? Object.freeze({}) : {};\nconst EMPTY_ARR = !!(process.env.NODE_ENV !== \"production\") ? Object.freeze([]) : [];\nconst NOOP = () => {\n};\nconst NO = () => false;\nconst isOn = (key) => key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && // uppercase letter\n(key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97);\nconst isModelListener = (key) => key.startsWith(\"onUpdate:\");\nconst extend = Object.assign;\nconst remove = (arr, el) => {\n const i = arr.indexOf(el);\n if (i > -1) {\n arr.splice(i, 1);\n }\n};\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst hasOwn = (val, key) => hasOwnProperty.call(val, key);\nconst isArray = Array.isArray;\nconst isMap = (val) => toTypeString(val) === \"[object Map]\";\nconst isSet = (val) => toTypeString(val) === \"[object Set]\";\nconst isDate = (val) => toTypeString(val) === \"[object Date]\";\nconst isRegExp = (val) => toTypeString(val) === \"[object RegExp]\";\nconst isFunction = (val) => typeof val === \"function\";\nconst isString = (val) => typeof val === \"string\";\nconst isSymbol = (val) => typeof val === \"symbol\";\nconst isObject = (val) => val !== null && typeof val === \"object\";\nconst isPromise = (val) => {\n return (isObject(val) || isFunction(val)) && isFunction(val.then) && isFunction(val.catch);\n};\nconst objectToString = Object.prototype.toString;\nconst toTypeString = (value) => objectToString.call(value);\nconst toRawType = (value) => {\n return toTypeString(value).slice(8, -1);\n};\nconst isPlainObject = (val) => toTypeString(val) === \"[object Object]\";\nconst isIntegerKey = (key) => isString(key) && key !== \"NaN\" && key[0] !== \"-\" && \"\" + parseInt(key, 10) === key;\nconst isReservedProp = /* @__PURE__ */ makeMap(\n // the leading comma is intentional so empty string \"\" is also included\n \",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted\"\n);\nconst isBuiltInDirective = /* @__PURE__ */ makeMap(\n \"bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo\"\n);\nconst cacheStringFunction = (fn) => {\n const cache = /* @__PURE__ */ Object.create(null);\n return ((str) => {\n const hit = cache[str];\n return hit || (cache[str] = fn(str));\n });\n};\nconst camelizeRE = /-\\w/g;\nconst camelize = cacheStringFunction(\n (str) => {\n return str.replace(camelizeRE, (c) => c.slice(1).toUpperCase());\n }\n);\nconst hyphenateRE = /\\B([A-Z])/g;\nconst hyphenate = cacheStringFunction(\n (str) => str.replace(hyphenateRE, \"-$1\").toLowerCase()\n);\nconst capitalize = cacheStringFunction((str) => {\n return str.charAt(0).toUpperCase() + str.slice(1);\n});\nconst toHandlerKey = cacheStringFunction(\n (str) => {\n const s = str ? `on${capitalize(str)}` : ``;\n return s;\n }\n);\nconst hasChanged = (value, oldValue) => !Object.is(value, oldValue);\nconst invokeArrayFns = (fns, ...arg) => {\n for (let i = 0; i < fns.length; i++) {\n fns[i](...arg);\n }\n};\nconst def = (obj, key, value, writable = false) => {\n Object.defineProperty(obj, key, {\n configurable: true,\n enumerable: false,\n writable,\n value\n });\n};\nconst looseToNumber = (val) => {\n const n = parseFloat(val);\n return isNaN(n) ? val : n;\n};\nconst toNumber = (val) => {\n const n = isString(val) ? Number(val) : NaN;\n return isNaN(n) ? val : n;\n};\nlet _globalThis;\nconst getGlobalThis = () => {\n return _globalThis || (_globalThis = typeof globalThis !== \"undefined\" ? globalThis : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n};\nconst identRE = /^[_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*$/;\nfunction genPropsAccessExp(name) {\n return identRE.test(name) ? `__props.${name}` : `__props[${JSON.stringify(name)}]`;\n}\nfunction genCacheKey(source, options) {\n return source + JSON.stringify(\n options,\n (_, val) => typeof val === \"function\" ? val.toString() : val\n );\n}\n\nconst PatchFlags = {\n \"TEXT\": 1,\n \"1\": \"TEXT\",\n \"CLASS\": 2,\n \"2\": \"CLASS\",\n \"STYLE\": 4,\n \"4\": \"STYLE\",\n \"PROPS\": 8,\n \"8\": \"PROPS\",\n \"FULL_PROPS\": 16,\n \"16\": \"FULL_PROPS\",\n \"NEED_HYDRATION\": 32,\n \"32\": \"NEED_HYDRATION\",\n \"STABLE_FRAGMENT\": 64,\n \"64\": \"STABLE_FRAGMENT\",\n \"KEYED_FRAGMENT\": 128,\n \"128\": \"KEYED_FRAGMENT\",\n \"UNKEYED_FRAGMENT\": 256,\n \"256\": \"UNKEYED_FRAGMENT\",\n \"NEED_PATCH\": 512,\n \"512\": \"NEED_PATCH\",\n \"DYNAMIC_SLOTS\": 1024,\n \"1024\": \"DYNAMIC_SLOTS\",\n \"DEV_ROOT_FRAGMENT\": 2048,\n \"2048\": \"DEV_ROOT_FRAGMENT\",\n \"CACHED\": -1,\n \"-1\": \"CACHED\",\n \"BAIL\": -2,\n \"-2\": \"BAIL\"\n};\nconst PatchFlagNames = {\n [1]: `TEXT`,\n [2]: `CLASS`,\n [4]: `STYLE`,\n [8]: `PROPS`,\n [16]: `FULL_PROPS`,\n [32]: `NEED_HYDRATION`,\n [64]: `STABLE_FRAGMENT`,\n [128]: `KEYED_FRAGMENT`,\n [256]: `UNKEYED_FRAGMENT`,\n [512]: `NEED_PATCH`,\n [1024]: `DYNAMIC_SLOTS`,\n [2048]: `DEV_ROOT_FRAGMENT`,\n [-1]: `CACHED`,\n [-2]: `BAIL`\n};\n\nconst ShapeFlags = {\n \"ELEMENT\": 1,\n \"1\": \"ELEMENT\",\n \"FUNCTIONAL_COMPONENT\": 2,\n \"2\": \"FUNCTIONAL_COMPONENT\",\n \"STATEFUL_COMPONENT\": 4,\n \"4\": \"STATEFUL_COMPONENT\",\n \"TEXT_CHILDREN\": 8,\n \"8\": \"TEXT_CHILDREN\",\n \"ARRAY_CHILDREN\": 16,\n \"16\": \"ARRAY_CHILDREN\",\n \"SLOTS_CHILDREN\": 32,\n \"32\": \"SLOTS_CHILDREN\",\n \"TELEPORT\": 64,\n \"64\": \"TELEPORT\",\n \"SUSPENSE\": 128,\n \"128\": \"SUSPENSE\",\n \"COMPONENT_SHOULD_KEEP_ALIVE\": 256,\n \"256\": \"COMPONENT_SHOULD_KEEP_ALIVE\",\n \"COMPONENT_KEPT_ALIVE\": 512,\n \"512\": \"COMPONENT_KEPT_ALIVE\",\n \"COMPONENT\": 6,\n \"6\": \"COMPONENT\"\n};\n\nconst SlotFlags = {\n \"STABLE\": 1,\n \"1\": \"STABLE\",\n \"DYNAMIC\": 2,\n \"2\": \"DYNAMIC\",\n \"FORWARDED\": 3,\n \"3\": \"FORWARDED\"\n};\nconst slotFlagsText = {\n [1]: \"STABLE\",\n [2]: \"DYNAMIC\",\n [3]: \"FORWARDED\"\n};\n\nconst GLOBALS_ALLOWED = \"Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error,Symbol\";\nconst isGloballyAllowed = /* @__PURE__ */ makeMap(GLOBALS_ALLOWED);\nconst isGloballyWhitelisted = isGloballyAllowed;\n\nconst range = 2;\nfunction generateCodeFrame(source, start = 0, end = source.length) {\n start = Math.max(0, Math.min(start, source.length));\n end = Math.max(0, Math.min(end, source.length));\n if (start > end) return \"\";\n let lines = source.split(/(\\r?\\n)/);\n const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);\n lines = lines.filter((_, idx) => idx % 2 === 0);\n let count = 0;\n const res = [];\n for (let i = 0; i < lines.length; i++) {\n count += lines[i].length + (newlineSequences[i] && newlineSequences[i].length || 0);\n if (count >= start) {\n for (let j = i - range; j <= i + range || end > count; j++) {\n if (j < 0 || j >= lines.length) continue;\n const line = j + 1;\n res.push(\n `${line}${\" \".repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`\n );\n const lineLength = lines[j].length;\n const newLineSeqLength = newlineSequences[j] && newlineSequences[j].length || 0;\n if (j === i) {\n const pad = start - (count - (lineLength + newLineSeqLength));\n const length = Math.max(\n 1,\n end > count ? lineLength - pad : end - start\n );\n res.push(` | ` + \" \".repeat(pad) + \"^\".repeat(length));\n } else if (j > i) {\n if (end > count) {\n const length = Math.max(Math.min(end - count, lineLength), 1);\n res.push(` | ` + \"^\".repeat(length));\n }\n count += lineLength + newLineSeqLength;\n }\n }\n break;\n }\n }\n return res.join(\"\\n\");\n}\n\nfunction normalizeStyle(value) {\n if (isArray(value)) {\n const res = {};\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item);\n if (normalized) {\n for (const key in normalized) {\n res[key] = normalized[key];\n }\n }\n }\n return res;\n } else if (isString(value) || isObject(value)) {\n return value;\n }\n}\nconst listDelimiterRE = /;(?![^(]*\\))/g;\nconst propertyDelimiterRE = /:([^]+)/;\nconst styleCommentRE = /\\/\\*[^]*?\\*\\//g;\nfunction parseStringStyle(cssText) {\n const ret = {};\n cssText.replace(styleCommentRE, \"\").split(listDelimiterRE).forEach((item) => {\n if (item) {\n const tmp = item.split(propertyDelimiterRE);\n tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());\n }\n });\n return ret;\n}\nfunction stringifyStyle(styles) {\n if (!styles) return \"\";\n if (isString(styles)) return styles;\n let ret = \"\";\n for (const key in styles) {\n const value = styles[key];\n if (isString(value) || typeof value === \"number\") {\n const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key);\n ret += `${normalizedKey}:${value};`;\n }\n }\n return ret;\n}\nfunction normalizeClass(value) {\n let res = \"\";\n if (isString(value)) {\n res = value;\n } else if (isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const normalized = normalizeClass(value[i]);\n if (normalized) {\n res += normalized + \" \";\n }\n }\n } else if (isObject(value)) {\n for (const name in value) {\n if (value[name]) {\n res += name + \" \";\n }\n }\n }\n return res.trim();\n}\nfunction normalizeProps(props) {\n if (!props) return null;\n let { class: klass, style } = props;\n if (klass && !isString(klass)) {\n props.class = normalizeClass(klass);\n }\n if (style) {\n props.style = normalizeStyle(style);\n }\n return props;\n}\n\nconst HTML_TAGS = \"html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot\";\nconst SVG_TAGS = \"svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view\";\nconst MATH_TAGS = \"annotation,annotation-xml,maction,maligngroup,malignmark,math,menclose,merror,mfenced,mfrac,mfraction,mglyph,mi,mlabeledtr,mlongdiv,mmultiscripts,mn,mo,mover,mpadded,mphantom,mprescripts,mroot,mrow,ms,mscarries,mscarry,msgroup,msline,mspace,msqrt,msrow,mstack,mstyle,msub,msubsup,msup,mtable,mtd,mtext,mtr,munder,munderover,none,semantics\";\nconst VOID_TAGS = \"area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr\";\nconst isHTMLTag = /* @__PURE__ */ makeMap(HTML_TAGS);\nconst isSVGTag = /* @__PURE__ */ makeMap(SVG_TAGS);\nconst isMathMLTag = /* @__PURE__ */ makeMap(MATH_TAGS);\nconst isVoidTag = /* @__PURE__ */ makeMap(VOID_TAGS);\n\nconst specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;\nconst isSpecialBooleanAttr = /* @__PURE__ */ makeMap(specialBooleanAttrs);\nconst isBooleanAttr = /* @__PURE__ */ makeMap(\n specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`\n);\nfunction includeBooleanAttr(value) {\n return !!value || value === \"\";\n}\nconst unsafeAttrCharRE = /[>/=\"'\\u0009\\u000a\\u000c\\u0020]/;\nconst attrValidationCache = {};\nfunction isSSRSafeAttrName(name) {\n if (attrValidationCache.hasOwnProperty(name)) {\n return attrValidationCache[name];\n }\n const isUnsafe = unsafeAttrCharRE.test(name);\n if (isUnsafe) {\n console.error(`unsafe attribute name: ${name}`);\n }\n return attrValidationCache[name] = !isUnsafe;\n}\nconst propsToAttrMap = {\n acceptCharset: \"accept-charset\",\n className: \"class\",\n htmlFor: \"for\",\n httpEquiv: \"http-equiv\"\n};\nconst isKnownHtmlAttr = /* @__PURE__ */ makeMap(\n `accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,inert,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap`\n);\nconst isKnownSvgAttr = /* @__PURE__ */ makeMap(\n `xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,color-interpolation-filters,color-profile,color-rendering,contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,overflow,overline-position,overline-thickness,panose-1,paint-order,path,pathLength,patternContentUnits,patternTransform,patternUnits,ping,pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,specularConstant,specularExponent,speed,spreadMethod,startOffset,stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,string,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,text-decoration,text-rendering,textLength,to,transform,transform-origin,type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xmlns:xlink,xml:base,xml:lang,xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan`\n);\nconst isKnownMathMLAttr = /* @__PURE__ */ makeMap(\n `accent,accentunder,actiontype,align,alignmentscope,altimg,altimg-height,altimg-valign,altimg-width,alttext,bevelled,close,columnsalign,columnlines,columnspan,denomalign,depth,dir,display,displaystyle,encoding,equalcolumns,equalrows,fence,fontstyle,fontweight,form,frame,framespacing,groupalign,height,href,id,indentalign,indentalignfirst,indentalignlast,indentshift,indentshiftfirst,indentshiftlast,indextype,justify,largetop,largeop,lquote,lspace,mathbackground,mathcolor,mathsize,mathvariant,maxsize,minlabelspacing,mode,other,overflow,position,rowalign,rowlines,rowspan,rquote,rspace,scriptlevel,scriptminsize,scriptsizemultiplier,selection,separator,separators,shift,side,src,stackalign,stretchy,subscriptshift,superscriptshift,symmetric,voffset,width,widths,xlink:href,xlink:show,xlink:type,xmlns`\n);\nfunction isRenderableAttrValue(value) {\n if (value == null) {\n return false;\n }\n const type = typeof value;\n return type === \"string\" || type === \"number\" || type === \"boolean\";\n}\n\nconst escapeRE = /[\"'&<>]/;\nfunction escapeHtml(string) {\n const str = \"\" + string;\n const match = escapeRE.exec(str);\n if (!match) {\n return str;\n }\n let html = \"\";\n let escaped;\n let index;\n let lastIndex = 0;\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34:\n escaped = \""\";\n break;\n case 38:\n escaped = \"&\";\n break;\n case 39:\n escaped = \"'\";\n break;\n case 60:\n escaped = \"<\";\n break;\n case 62:\n escaped = \">\";\n break;\n default:\n continue;\n }\n if (lastIndex !== index) {\n html += str.slice(lastIndex, index);\n }\n lastIndex = index + 1;\n html += escaped;\n }\n return lastIndex !== index ? html + str.slice(lastIndex, index) : html;\n}\nconst commentStripRE = /^-?>||--!>|?@[\\\\\\]^`{|}~]/g;\nfunction getEscapedCssVarName(key, doubleEscape) {\n return key.replace(\n cssVarNameEscapeSymbolsRE,\n (s) => doubleEscape ? s === '\"' ? '\\\\\\\\\\\\\"' : `\\\\\\\\${s}` : `\\\\${s}`\n );\n}\n\nfunction looseCompareArrays(a, b) {\n if (a.length !== b.length) return false;\n let equal = true;\n for (let i = 0; equal && i < a.length; i++) {\n equal = looseEqual(a[i], b[i]);\n }\n return equal;\n}\nfunction looseEqual(a, b) {\n if (a === b) return true;\n let aValidType = isDate(a);\n let bValidType = isDate(b);\n if (aValidType || bValidType) {\n return aValidType && bValidType ? a.getTime() === b.getTime() : false;\n }\n aValidType = isSymbol(a);\n bValidType = isSymbol(b);\n if (aValidType || bValidType) {\n return a === b;\n }\n aValidType = isArray(a);\n bValidType = isArray(b);\n if (aValidType || bValidType) {\n return aValidType && bValidType ? looseCompareArrays(a, b) : false;\n }\n aValidType = isObject(a);\n bValidType = isObject(b);\n if (aValidType || bValidType) {\n if (!aValidType || !bValidType) {\n return false;\n }\n const aKeysCount = Object.keys(a).length;\n const bKeysCount = Object.keys(b).length;\n if (aKeysCount !== bKeysCount) {\n return false;\n }\n for (const key in a) {\n const aHasKey = a.hasOwnProperty(key);\n const bHasKey = b.hasOwnProperty(key);\n if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) {\n return false;\n }\n }\n }\n return String(a) === String(b);\n}\nfunction looseIndexOf(arr, val) {\n return arr.findIndex((item) => looseEqual(item, val));\n}\n\nconst isRef = (val) => {\n return !!(val && val[\"__v_isRef\"] === true);\n};\nconst toDisplayString = (val) => {\n return isString(val) ? val : val == null ? \"\" : isArray(val) || isObject(val) && (val.toString === objectToString || !isFunction(val.toString)) ? isRef(val) ? toDisplayString(val.value) : JSON.stringify(val, replacer, 2) : String(val);\n};\nconst replacer = (_key, val) => {\n if (isRef(val)) {\n return replacer(_key, val.value);\n } else if (isMap(val)) {\n return {\n [`Map(${val.size})`]: [...val.entries()].reduce(\n (entries, [key, val2], i) => {\n entries[stringifySymbol(key, i) + \" =>\"] = val2;\n return entries;\n },\n {}\n )\n };\n } else if (isSet(val)) {\n return {\n [`Set(${val.size})`]: [...val.values()].map((v) => stringifySymbol(v))\n };\n } else if (isSymbol(val)) {\n return stringifySymbol(val);\n } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {\n return String(val);\n }\n return val;\n};\nconst stringifySymbol = (v, i = \"\") => {\n var _a;\n return (\n // Symbol.description in es2019+ so we need to cast here to pass\n // the lib: es2016 check\n isSymbol(v) ? `Symbol(${(_a = v.description) != null ? _a : i})` : v\n );\n};\n\nfunction normalizeCssVarValue(value) {\n if (value == null) {\n return \"initial\";\n }\n if (typeof value === \"string\") {\n return value === \"\" ? \" \" : value;\n }\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n console.warn(\n \"[Vue warn] Invalid value used for CSS binding. Expected a string or a finite number but received:\",\n value\n );\n }\n }\n return String(value);\n}\n\nexport { EMPTY_ARR, EMPTY_OBJ, NO, NOOP, PatchFlagNames, PatchFlags, ShapeFlags, SlotFlags, camelize, capitalize, cssVarNameEscapeSymbolsRE, def, escapeHtml, escapeHtmlComment, extend, genCacheKey, genPropsAccessExp, generateCodeFrame, getEscapedCssVarName, getGlobalThis, hasChanged, hasOwn, hyphenate, includeBooleanAttr, invokeArrayFns, isArray, isBooleanAttr, isBuiltInDirective, isDate, isFunction, isGloballyAllowed, isGloballyWhitelisted, isHTMLTag, isIntegerKey, isKnownHtmlAttr, isKnownMathMLAttr, isKnownSvgAttr, isMap, isMathMLTag, isModelListener, isObject, isOn, isPlainObject, isPromise, isRegExp, isRenderableAttrValue, isReservedProp, isSSRSafeAttrName, isSVGTag, isSet, isSpecialBooleanAttr, isString, isSymbol, isVoidTag, looseEqual, looseIndexOf, looseToNumber, makeMap, normalizeClass, normalizeCssVarValue, normalizeProps, normalizeStyle, objectToString, parseStringStyle, propsToAttrMap, remove, slotFlagsText, stringifyStyle, toDisplayString, toHandlerKey, toNumber, toRawType, toTypeString };\n","/**\n* @vue/reactivity v3.5.22\n* (c) 2018-present Yuxi (Evan) You and Vue contributors\n* @license MIT\n**/\nimport { extend, hasChanged, isArray, isIntegerKey, isSymbol, isMap, hasOwn, makeMap, isObject, capitalize, toRawType, def, isFunction, EMPTY_OBJ, isSet, isPlainObject, remove, NOOP } from '@vue/shared';\n\nfunction warn(msg, ...args) {\n console.warn(`[Vue warn] ${msg}`, ...args);\n}\n\nlet activeEffectScope;\nclass EffectScope {\n constructor(detached = false) {\n this.detached = detached;\n /**\n * @internal\n */\n this._active = true;\n /**\n * @internal track `on` calls, allow `on` call multiple times\n */\n this._on = 0;\n /**\n * @internal\n */\n this.effects = [];\n /**\n * @internal\n */\n this.cleanups = [];\n this._isPaused = false;\n this.parent = activeEffectScope;\n if (!detached && activeEffectScope) {\n this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(\n this\n ) - 1;\n }\n }\n get active() {\n return this._active;\n }\n pause() {\n if (this._active) {\n this._isPaused = true;\n let i, l;\n if (this.scopes) {\n for (i = 0, l = this.scopes.length; i < l; i++) {\n this.scopes[i].pause();\n }\n }\n for (i = 0, l = this.effects.length; i < l; i++) {\n this.effects[i].pause();\n }\n }\n }\n /**\n * Resumes the effect scope, including all child scopes and effects.\n */\n resume() {\n if (this._active) {\n if (this._isPaused) {\n this._isPaused = false;\n let i, l;\n if (this.scopes) {\n for (i = 0, l = this.scopes.length; i < l; i++) {\n this.scopes[i].resume();\n }\n }\n for (i = 0, l = this.effects.length; i < l; i++) {\n this.effects[i].resume();\n }\n }\n }\n }\n run(fn) {\n if (this._active) {\n const currentEffectScope = activeEffectScope;\n try {\n activeEffectScope = this;\n return fn();\n } finally {\n activeEffectScope = currentEffectScope;\n }\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn(`cannot run an inactive effect scope.`);\n }\n }\n /**\n * This should only be called on non-detached scopes\n * @internal\n */\n on() {\n if (++this._on === 1) {\n this.prevScope = activeEffectScope;\n activeEffectScope = this;\n }\n }\n /**\n * This should only be called on non-detached scopes\n * @internal\n */\n off() {\n if (this._on > 0 && --this._on === 0) {\n activeEffectScope = this.prevScope;\n this.prevScope = void 0;\n }\n }\n stop(fromParent) {\n if (this._active) {\n this._active = false;\n let i, l;\n for (i = 0, l = this.effects.length; i < l; i++) {\n this.effects[i].stop();\n }\n this.effects.length = 0;\n for (i = 0, l = this.cleanups.length; i < l; i++) {\n this.cleanups[i]();\n }\n this.cleanups.length = 0;\n if (this.scopes) {\n for (i = 0, l = this.scopes.length; i < l; i++) {\n this.scopes[i].stop(true);\n }\n this.scopes.length = 0;\n }\n if (!this.detached && this.parent && !fromParent) {\n const last = this.parent.scopes.pop();\n if (last && last !== this) {\n this.parent.scopes[this.index] = last;\n last.index = this.index;\n }\n }\n this.parent = void 0;\n }\n }\n}\nfunction effectScope(detached) {\n return new EffectScope(detached);\n}\nfunction getCurrentScope() {\n return activeEffectScope;\n}\nfunction onScopeDispose(fn, failSilently = false) {\n if (activeEffectScope) {\n activeEffectScope.cleanups.push(fn);\n } else if (!!(process.env.NODE_ENV !== \"production\") && !failSilently) {\n warn(\n `onScopeDispose() is called when there is no active effect scope to be associated with.`\n );\n }\n}\n\nlet activeSub;\nconst EffectFlags = {\n \"ACTIVE\": 1,\n \"1\": \"ACTIVE\",\n \"RUNNING\": 2,\n \"2\": \"RUNNING\",\n \"TRACKING\": 4,\n \"4\": \"TRACKING\",\n \"NOTIFIED\": 8,\n \"8\": \"NOTIFIED\",\n \"DIRTY\": 16,\n \"16\": \"DIRTY\",\n \"ALLOW_RECURSE\": 32,\n \"32\": \"ALLOW_RECURSE\",\n \"PAUSED\": 64,\n \"64\": \"PAUSED\",\n \"EVALUATED\": 128,\n \"128\": \"EVALUATED\"\n};\nconst pausedQueueEffects = /* @__PURE__ */ new WeakSet();\nclass ReactiveEffect {\n constructor(fn) {\n this.fn = fn;\n /**\n * @internal\n */\n this.deps = void 0;\n /**\n * @internal\n */\n this.depsTail = void 0;\n /**\n * @internal\n */\n this.flags = 1 | 4;\n /**\n * @internal\n */\n this.next = void 0;\n /**\n * @internal\n */\n this.cleanup = void 0;\n this.scheduler = void 0;\n if (activeEffectScope && activeEffectScope.active) {\n activeEffectScope.effects.push(this);\n }\n }\n pause() {\n this.flags |= 64;\n }\n resume() {\n if (this.flags & 64) {\n this.flags &= -65;\n if (pausedQueueEffects.has(this)) {\n pausedQueueEffects.delete(this);\n this.trigger();\n }\n }\n }\n /**\n * @internal\n */\n notify() {\n if (this.flags & 2 && !(this.flags & 32)) {\n return;\n }\n if (!(this.flags & 8)) {\n batch(this);\n }\n }\n run() {\n if (!(this.flags & 1)) {\n return this.fn();\n }\n this.flags |= 2;\n cleanupEffect(this);\n prepareDeps(this);\n const prevEffect = activeSub;\n const prevShouldTrack = shouldTrack;\n activeSub = this;\n shouldTrack = true;\n try {\n return this.fn();\n } finally {\n if (!!(process.env.NODE_ENV !== \"production\") && activeSub !== this) {\n warn(\n \"Active effect was not restored correctly - this is likely a Vue internal bug.\"\n );\n }\n cleanupDeps(this);\n activeSub = prevEffect;\n shouldTrack = prevShouldTrack;\n this.flags &= -3;\n }\n }\n stop() {\n if (this.flags & 1) {\n for (let link = this.deps; link; link = link.nextDep) {\n removeSub(link);\n }\n this.deps = this.depsTail = void 0;\n cleanupEffect(this);\n this.onStop && this.onStop();\n this.flags &= -2;\n }\n }\n trigger() {\n if (this.flags & 64) {\n pausedQueueEffects.add(this);\n } else if (this.scheduler) {\n this.scheduler();\n } else {\n this.runIfDirty();\n }\n }\n /**\n * @internal\n */\n runIfDirty() {\n if (isDirty(this)) {\n this.run();\n }\n }\n get dirty() {\n return isDirty(this);\n }\n}\nlet batchDepth = 0;\nlet batchedSub;\nlet batchedComputed;\nfunction batch(sub, isComputed = false) {\n sub.flags |= 8;\n if (isComputed) {\n sub.next = batchedComputed;\n batchedComputed = sub;\n return;\n }\n sub.next = batchedSub;\n batchedSub = sub;\n}\nfunction startBatch() {\n batchDepth++;\n}\nfunction endBatch() {\n if (--batchDepth > 0) {\n return;\n }\n if (batchedComputed) {\n let e = batchedComputed;\n batchedComputed = void 0;\n while (e) {\n const next = e.next;\n e.next = void 0;\n e.flags &= -9;\n e = next;\n }\n }\n let error;\n while (batchedSub) {\n let e = batchedSub;\n batchedSub = void 0;\n while (e) {\n const next = e.next;\n e.next = void 0;\n e.flags &= -9;\n if (e.flags & 1) {\n try {\n ;\n e.trigger();\n } catch (err) {\n if (!error) error = err;\n }\n }\n e = next;\n }\n }\n if (error) throw error;\n}\nfunction prepareDeps(sub) {\n for (let link = sub.deps; link; link = link.nextDep) {\n link.version = -1;\n link.prevActiveLink = link.dep.activeLink;\n link.dep.activeLink = link;\n }\n}\nfunction cleanupDeps(sub) {\n let head;\n let tail = sub.depsTail;\n let link = tail;\n while (link) {\n const prev = link.prevDep;\n if (link.version === -1) {\n if (link === tail) tail = prev;\n removeSub(link);\n removeDep(link);\n } else {\n head = link;\n }\n link.dep.activeLink = link.prevActiveLink;\n link.prevActiveLink = void 0;\n link = prev;\n }\n sub.deps = head;\n sub.depsTail = tail;\n}\nfunction isDirty(sub) {\n for (let link = sub.deps; link; link = link.nextDep) {\n if (link.dep.version !== link.version || link.dep.computed && (refreshComputed(link.dep.computed) || link.dep.version !== link.version)) {\n return true;\n }\n }\n if (sub._dirty) {\n return true;\n }\n return false;\n}\nfunction refreshComputed(computed) {\n if (computed.flags & 4 && !(computed.flags & 16)) {\n return;\n }\n computed.flags &= -17;\n if (computed.globalVersion === globalVersion) {\n return;\n }\n computed.globalVersion = globalVersion;\n if (!computed.isSSR && computed.flags & 128 && (!computed.deps && !computed._dirty || !isDirty(computed))) {\n return;\n }\n computed.flags |= 2;\n const dep = computed.dep;\n const prevSub = activeSub;\n const prevShouldTrack = shouldTrack;\n activeSub = computed;\n shouldTrack = true;\n try {\n prepareDeps(computed);\n const value = computed.fn(computed._value);\n if (dep.version === 0 || hasChanged(value, computed._value)) {\n computed.flags |= 128;\n computed._value = value;\n dep.version++;\n }\n } catch (err) {\n dep.version++;\n throw err;\n } finally {\n activeSub = prevSub;\n shouldTrack = prevShouldTrack;\n cleanupDeps(computed);\n computed.flags &= -3;\n }\n}\nfunction removeSub(link, soft = false) {\n const { dep, prevSub, nextSub } = link;\n if (prevSub) {\n prevSub.nextSub = nextSub;\n link.prevSub = void 0;\n }\n if (nextSub) {\n nextSub.prevSub = prevSub;\n link.nextSub = void 0;\n }\n if (!!(process.env.NODE_ENV !== \"production\") && dep.subsHead === link) {\n dep.subsHead = nextSub;\n }\n if (dep.subs === link) {\n dep.subs = prevSub;\n if (!prevSub && dep.computed) {\n dep.computed.flags &= -5;\n for (let l = dep.computed.deps; l; l = l.nextDep) {\n removeSub(l, true);\n }\n }\n }\n if (!soft && !--dep.sc && dep.map) {\n dep.map.delete(dep.key);\n }\n}\nfunction removeDep(link) {\n const { prevDep, nextDep } = link;\n if (prevDep) {\n prevDep.nextDep = nextDep;\n link.prevDep = void 0;\n }\n if (nextDep) {\n nextDep.prevDep = prevDep;\n link.nextDep = void 0;\n }\n}\nfunction effect(fn, options) {\n if (fn.effect instanceof ReactiveEffect) {\n fn = fn.effect.fn;\n }\n const e = new ReactiveEffect(fn);\n if (options) {\n extend(e, options);\n }\n try {\n e.run();\n } catch (err) {\n e.stop();\n throw err;\n }\n const runner = e.run.bind(e);\n runner.effect = e;\n return runner;\n}\nfunction stop(runner) {\n runner.effect.stop();\n}\nlet shouldTrack = true;\nconst trackStack = [];\nfunction pauseTracking() {\n trackStack.push(shouldTrack);\n shouldTrack = false;\n}\nfunction enableTracking() {\n trackStack.push(shouldTrack);\n shouldTrack = true;\n}\nfunction resetTracking() {\n const last = trackStack.pop();\n shouldTrack = last === void 0 ? true : last;\n}\nfunction onEffectCleanup(fn, failSilently = false) {\n if (activeSub instanceof ReactiveEffect) {\n activeSub.cleanup = fn;\n } else if (!!(process.env.NODE_ENV !== \"production\") && !failSilently) {\n warn(\n `onEffectCleanup() was called when there was no active effect to associate with.`\n );\n }\n}\nfunction cleanupEffect(e) {\n const { cleanup } = e;\n e.cleanup = void 0;\n if (cleanup) {\n const prevSub = activeSub;\n activeSub = void 0;\n try {\n cleanup();\n } finally {\n activeSub = prevSub;\n }\n }\n}\n\nlet globalVersion = 0;\nclass Link {\n constructor(sub, dep) {\n this.sub = sub;\n this.dep = dep;\n this.version = dep.version;\n this.nextDep = this.prevDep = this.nextSub = this.prevSub = this.prevActiveLink = void 0;\n }\n}\nclass Dep {\n // TODO isolatedDeclarations \"__v_skip\"\n constructor(computed) {\n this.computed = computed;\n this.version = 0;\n /**\n * Link between this dep and the current active effect\n */\n this.activeLink = void 0;\n /**\n * Doubly linked list representing the subscribing effects (tail)\n */\n this.subs = void 0;\n /**\n * For object property deps cleanup\n */\n this.map = void 0;\n this.key = void 0;\n /**\n * Subscriber counter\n */\n this.sc = 0;\n /**\n * @internal\n */\n this.__v_skip = true;\n if (!!(process.env.NODE_ENV !== \"production\")) {\n this.subsHead = void 0;\n }\n }\n track(debugInfo) {\n if (!activeSub || !shouldTrack || activeSub === this.computed) {\n return;\n }\n let link = this.activeLink;\n if (link === void 0 || link.sub !== activeSub) {\n link = this.activeLink = new Link(activeSub, this);\n if (!activeSub.deps) {\n activeSub.deps = activeSub.depsTail = link;\n } else {\n link.prevDep = activeSub.depsTail;\n activeSub.depsTail.nextDep = link;\n activeSub.depsTail = link;\n }\n addSub(link);\n } else if (link.version === -1) {\n link.version = this.version;\n if (link.nextDep) {\n const next = link.nextDep;\n next.prevDep = link.prevDep;\n if (link.prevDep) {\n link.prevDep.nextDep = next;\n }\n link.prevDep = activeSub.depsTail;\n link.nextDep = void 0;\n activeSub.depsTail.nextDep = link;\n activeSub.depsTail = link;\n if (activeSub.deps === link) {\n activeSub.deps = next;\n }\n }\n }\n if (!!(process.env.NODE_ENV !== \"production\") && activeSub.onTrack) {\n activeSub.onTrack(\n extend(\n {\n effect: activeSub\n },\n debugInfo\n )\n );\n }\n return link;\n }\n trigger(debugInfo) {\n this.version++;\n globalVersion++;\n this.notify(debugInfo);\n }\n notify(debugInfo) {\n startBatch();\n try {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n for (let head = this.subsHead; head; head = head.nextSub) {\n if (head.sub.onTrigger && !(head.sub.flags & 8)) {\n head.sub.onTrigger(\n extend(\n {\n effect: head.sub\n },\n debugInfo\n )\n );\n }\n }\n }\n for (let link = this.subs; link; link = link.prevSub) {\n if (link.sub.notify()) {\n ;\n link.sub.dep.notify();\n }\n }\n } finally {\n endBatch();\n }\n }\n}\nfunction addSub(link) {\n link.dep.sc++;\n if (link.sub.flags & 4) {\n const computed = link.dep.computed;\n if (computed && !link.dep.subs) {\n computed.flags |= 4 | 16;\n for (let l = computed.deps; l; l = l.nextDep) {\n addSub(l);\n }\n }\n const currentTail = link.dep.subs;\n if (currentTail !== link) {\n link.prevSub = currentTail;\n if (currentTail) currentTail.nextSub = link;\n }\n if (!!(process.env.NODE_ENV !== \"production\") && link.dep.subsHead === void 0) {\n link.dep.subsHead = link;\n }\n link.dep.subs = link;\n }\n}\nconst targetMap = /* @__PURE__ */ new WeakMap();\nconst ITERATE_KEY = Symbol(\n !!(process.env.NODE_ENV !== \"production\") ? \"Object iterate\" : \"\"\n);\nconst MAP_KEY_ITERATE_KEY = Symbol(\n !!(process.env.NODE_ENV !== \"production\") ? \"Map keys iterate\" : \"\"\n);\nconst ARRAY_ITERATE_KEY = Symbol(\n !!(process.env.NODE_ENV !== \"production\") ? \"Array iterate\" : \"\"\n);\nfunction track(target, type, key) {\n if (shouldTrack && activeSub) {\n let depsMap = targetMap.get(target);\n if (!depsMap) {\n targetMap.set(target, depsMap = /* @__PURE__ */ new Map());\n }\n let dep = depsMap.get(key);\n if (!dep) {\n depsMap.set(key, dep = new Dep());\n dep.map = depsMap;\n dep.key = key;\n }\n if (!!(process.env.NODE_ENV !== \"production\")) {\n dep.track({\n target,\n type,\n key\n });\n } else {\n dep.track();\n }\n }\n}\nfunction trigger(target, type, key, newValue, oldValue, oldTarget) {\n const depsMap = targetMap.get(target);\n if (!depsMap) {\n globalVersion++;\n return;\n }\n const run = (dep) => {\n if (dep) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n dep.trigger({\n target,\n type,\n key,\n newValue,\n oldValue,\n oldTarget\n });\n } else {\n dep.trigger();\n }\n }\n };\n startBatch();\n if (type === \"clear\") {\n depsMap.forEach(run);\n } else {\n const targetIsArray = isArray(target);\n const isArrayIndex = targetIsArray && isIntegerKey(key);\n if (targetIsArray && key === \"length\") {\n const newLength = Number(newValue);\n depsMap.forEach((dep, key2) => {\n if (key2 === \"length\" || key2 === ARRAY_ITERATE_KEY || !isSymbol(key2) && key2 >= newLength) {\n run(dep);\n }\n });\n } else {\n if (key !== void 0 || depsMap.has(void 0)) {\n run(depsMap.get(key));\n }\n if (isArrayIndex) {\n run(depsMap.get(ARRAY_ITERATE_KEY));\n }\n switch (type) {\n case \"add\":\n if (!targetIsArray) {\n run(depsMap.get(ITERATE_KEY));\n if (isMap(target)) {\n run(depsMap.get(MAP_KEY_ITERATE_KEY));\n }\n } else if (isArrayIndex) {\n run(depsMap.get(\"length\"));\n }\n break;\n case \"delete\":\n if (!targetIsArray) {\n run(depsMap.get(ITERATE_KEY));\n if (isMap(target)) {\n run(depsMap.get(MAP_KEY_ITERATE_KEY));\n }\n }\n break;\n case \"set\":\n if (isMap(target)) {\n run(depsMap.get(ITERATE_KEY));\n }\n break;\n }\n }\n }\n endBatch();\n}\nfunction getDepFromReactive(object, key) {\n const depMap = targetMap.get(object);\n return depMap && depMap.get(key);\n}\n\nfunction reactiveReadArray(array) {\n const raw = toRaw(array);\n if (raw === array) return raw;\n track(raw, \"iterate\", ARRAY_ITERATE_KEY);\n return isShallow(array) ? raw : raw.map(toReactive);\n}\nfunction shallowReadArray(arr) {\n track(arr = toRaw(arr), \"iterate\", ARRAY_ITERATE_KEY);\n return arr;\n}\nconst arrayInstrumentations = {\n __proto__: null,\n [Symbol.iterator]() {\n return iterator(this, Symbol.iterator, toReactive);\n },\n concat(...args) {\n return reactiveReadArray(this).concat(\n ...args.map((x) => isArray(x) ? reactiveReadArray(x) : x)\n );\n },\n entries() {\n return iterator(this, \"entries\", (value) => {\n value[1] = toReactive(value[1]);\n return value;\n });\n },\n every(fn, thisArg) {\n return apply(this, \"every\", fn, thisArg, void 0, arguments);\n },\n filter(fn, thisArg) {\n return apply(this, \"filter\", fn, thisArg, (v) => v.map(toReactive), arguments);\n },\n find(fn, thisArg) {\n return apply(this, \"find\", fn, thisArg, toReactive, arguments);\n },\n findIndex(fn, thisArg) {\n return apply(this, \"findIndex\", fn, thisArg, void 0, arguments);\n },\n findLast(fn, thisArg) {\n return apply(this, \"findLast\", fn, thisArg, toReactive, arguments);\n },\n findLastIndex(fn, thisArg) {\n return apply(this, \"findLastIndex\", fn, thisArg, void 0, arguments);\n },\n // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement\n forEach(fn, thisArg) {\n return apply(this, \"forEach\", fn, thisArg, void 0, arguments);\n },\n includes(...args) {\n return searchProxy(this, \"includes\", args);\n },\n indexOf(...args) {\n return searchProxy(this, \"indexOf\", args);\n },\n join(separator) {\n return reactiveReadArray(this).join(separator);\n },\n // keys() iterator only reads `length`, no optimization required\n lastIndexOf(...args) {\n return searchProxy(this, \"lastIndexOf\", args);\n },\n map(fn, thisArg) {\n return apply(this, \"map\", fn, thisArg, void 0, arguments);\n },\n pop() {\n return noTracking(this, \"pop\");\n },\n push(...args) {\n return noTracking(this, \"push\", args);\n },\n reduce(fn, ...args) {\n return reduce(this, \"reduce\", fn, args);\n },\n reduceRight(fn, ...args) {\n return reduce(this, \"reduceRight\", fn, args);\n },\n shift() {\n return noTracking(this, \"shift\");\n },\n // slice could use ARRAY_ITERATE but also seems to beg for range tracking\n some(fn, thisArg) {\n return apply(this, \"some\", fn, thisArg, void 0, arguments);\n },\n splice(...args) {\n return noTracking(this, \"splice\", args);\n },\n toReversed() {\n return reactiveReadArray(this).toReversed();\n },\n toSorted(comparer) {\n return reactiveReadArray(this).toSorted(comparer);\n },\n toSpliced(...args) {\n return reactiveReadArray(this).toSpliced(...args);\n },\n unshift(...args) {\n return noTracking(this, \"unshift\", args);\n },\n values() {\n return iterator(this, \"values\", toReactive);\n }\n};\nfunction iterator(self, method, wrapValue) {\n const arr = shallowReadArray(self);\n const iter = arr[method]();\n if (arr !== self && !isShallow(self)) {\n iter._next = iter.next;\n iter.next = () => {\n const result = iter._next();\n if (!result.done) {\n result.value = wrapValue(result.value);\n }\n return result;\n };\n }\n return iter;\n}\nconst arrayProto = Array.prototype;\nfunction apply(self, method, fn, thisArg, wrappedRetFn, args) {\n const arr = shallowReadArray(self);\n const needsWrap = arr !== self && !isShallow(self);\n const methodFn = arr[method];\n if (methodFn !== arrayProto[method]) {\n const result2 = methodFn.apply(self, args);\n return needsWrap ? toReactive(result2) : result2;\n }\n let wrappedFn = fn;\n if (arr !== self) {\n if (needsWrap) {\n wrappedFn = function(item, index) {\n return fn.call(this, toReactive(item), index, self);\n };\n } else if (fn.length > 2) {\n wrappedFn = function(item, index) {\n return fn.call(this, item, index, self);\n };\n }\n }\n const result = methodFn.call(arr, wrappedFn, thisArg);\n return needsWrap && wrappedRetFn ? wrappedRetFn(result) : result;\n}\nfunction reduce(self, method, fn, args) {\n const arr = shallowReadArray(self);\n let wrappedFn = fn;\n if (arr !== self) {\n if (!isShallow(self)) {\n wrappedFn = function(acc, item, index) {\n return fn.call(this, acc, toReactive(item), index, self);\n };\n } else if (fn.length > 3) {\n wrappedFn = function(acc, item, index) {\n return fn.call(this, acc, item, index, self);\n };\n }\n }\n return arr[method](wrappedFn, ...args);\n}\nfunction searchProxy(self, method, args) {\n const arr = toRaw(self);\n track(arr, \"iterate\", ARRAY_ITERATE_KEY);\n const res = arr[method](...args);\n if ((res === -1 || res === false) && isProxy(args[0])) {\n args[0] = toRaw(args[0]);\n return arr[method](...args);\n }\n return res;\n}\nfunction noTracking(self, method, args = []) {\n pauseTracking();\n startBatch();\n const res = toRaw(self)[method].apply(self, args);\n endBatch();\n resetTracking();\n return res;\n}\n\nconst isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);\nconst builtInSymbols = new Set(\n /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== \"arguments\" && key !== \"caller\").map((key) => Symbol[key]).filter(isSymbol)\n);\nfunction hasOwnProperty(key) {\n if (!isSymbol(key)) key = String(key);\n const obj = toRaw(this);\n track(obj, \"has\", key);\n return obj.hasOwnProperty(key);\n}\nclass BaseReactiveHandler {\n constructor(_isReadonly = false, _isShallow = false) {\n this._isReadonly = _isReadonly;\n this._isShallow = _isShallow;\n }\n get(target, key, receiver) {\n if (key === \"__v_skip\") return target[\"__v_skip\"];\n const isReadonly2 = this._isReadonly, isShallow2 = this._isShallow;\n if (key === \"__v_isReactive\") {\n return !isReadonly2;\n } else if (key === \"__v_isReadonly\") {\n return isReadonly2;\n } else if (key === \"__v_isShallow\") {\n return isShallow2;\n } else if (key === \"__v_raw\") {\n if (receiver === (isReadonly2 ? isShallow2 ? shallowReadonlyMap : readonlyMap : isShallow2 ? shallowReactiveMap : reactiveMap).get(target) || // receiver is not the reactive proxy, but has the same prototype\n // this means the receiver is a user proxy of the reactive proxy\n Object.getPrototypeOf(target) === Object.getPrototypeOf(receiver)) {\n return target;\n }\n return;\n }\n const targetIsArray = isArray(target);\n if (!isReadonly2) {\n let fn;\n if (targetIsArray && (fn = arrayInstrumentations[key])) {\n return fn;\n }\n if (key === \"hasOwnProperty\") {\n return hasOwnProperty;\n }\n }\n const res = Reflect.get(\n target,\n key,\n // if this is a proxy wrapping a ref, return methods using the raw ref\n // as receiver so that we don't have to call `toRaw` on the ref in all\n // its class methods\n isRef(target) ? target : receiver\n );\n if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {\n return res;\n }\n if (!isReadonly2) {\n track(target, \"get\", key);\n }\n if (isShallow2) {\n return res;\n }\n if (isRef(res)) {\n const value = targetIsArray && isIntegerKey(key) ? res : res.value;\n return isReadonly2 && isObject(value) ? readonly(value) : value;\n }\n if (isObject(res)) {\n return isReadonly2 ? readonly(res) : reactive(res);\n }\n return res;\n }\n}\nclass MutableReactiveHandler extends BaseReactiveHandler {\n constructor(isShallow2 = false) {\n super(false, isShallow2);\n }\n set(target, key, value, receiver) {\n let oldValue = target[key];\n if (!this._isShallow) {\n const isOldValueReadonly = isReadonly(oldValue);\n if (!isShallow(value) && !isReadonly(value)) {\n oldValue = toRaw(oldValue);\n value = toRaw(value);\n }\n if (!isArray(target) && isRef(oldValue) && !isRef(value)) {\n if (isOldValueReadonly) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n warn(\n `Set operation on key \"${String(key)}\" failed: target is readonly.`,\n target[key]\n );\n }\n return true;\n } else {\n oldValue.value = value;\n return true;\n }\n }\n }\n const hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key);\n const result = Reflect.set(\n target,\n key,\n value,\n isRef(target) ? target : receiver\n );\n if (target === toRaw(receiver)) {\n if (!hadKey) {\n trigger(target, \"add\", key, value);\n } else if (hasChanged(value, oldValue)) {\n trigger(target, \"set\", key, value, oldValue);\n }\n }\n return result;\n }\n deleteProperty(target, key) {\n const hadKey = hasOwn(target, key);\n const oldValue = target[key];\n const result = Reflect.deleteProperty(target, key);\n if (result && hadKey) {\n trigger(target, \"delete\", key, void 0, oldValue);\n }\n return result;\n }\n has(target, key) {\n const result = Reflect.has(target, key);\n if (!isSymbol(key) || !builtInSymbols.has(key)) {\n track(target, \"has\", key);\n }\n return result;\n }\n ownKeys(target) {\n track(\n target,\n \"iterate\",\n isArray(target) ? \"length\" : ITERATE_KEY\n );\n return Reflect.ownKeys(target);\n }\n}\nclass ReadonlyReactiveHandler extends BaseReactiveHandler {\n constructor(isShallow2 = false) {\n super(true, isShallow2);\n }\n set(target, key) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n warn(\n `Set operation on key \"${String(key)}\" failed: target is readonly.`,\n target\n );\n }\n return true;\n }\n deleteProperty(target, key) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n warn(\n `Delete operation on key \"${String(key)}\" failed: target is readonly.`,\n target\n );\n }\n return true;\n }\n}\nconst mutableHandlers = /* @__PURE__ */ new MutableReactiveHandler();\nconst readonlyHandlers = /* @__PURE__ */ new ReadonlyReactiveHandler();\nconst shallowReactiveHandlers = /* @__PURE__ */ new MutableReactiveHandler(true);\nconst shallowReadonlyHandlers = /* @__PURE__ */ new ReadonlyReactiveHandler(true);\n\nconst toShallow = (value) => value;\nconst getProto = (v) => Reflect.getPrototypeOf(v);\nfunction createIterableMethod(method, isReadonly2, isShallow2) {\n return function(...args) {\n const target = this[\"__v_raw\"];\n const rawTarget = toRaw(target);\n const targetIsMap = isMap(rawTarget);\n const isPair = method === \"entries\" || method === Symbol.iterator && targetIsMap;\n const isKeyOnly = method === \"keys\" && targetIsMap;\n const innerIterator = target[method](...args);\n const wrap = isShallow2 ? toShallow : isReadonly2 ? toReadonly : toReactive;\n !isReadonly2 && track(\n rawTarget,\n \"iterate\",\n isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY\n );\n return {\n // iterator protocol\n next() {\n const { value, done } = innerIterator.next();\n return done ? { value, done } : {\n value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),\n done\n };\n },\n // iterable protocol\n [Symbol.iterator]() {\n return this;\n }\n };\n };\n}\nfunction createReadonlyMethod(type) {\n return function(...args) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n const key = args[0] ? `on key \"${args[0]}\" ` : ``;\n warn(\n `${capitalize(type)} operation ${key}failed: target is readonly.`,\n toRaw(this)\n );\n }\n return type === \"delete\" ? false : type === \"clear\" ? void 0 : this;\n };\n}\nfunction createInstrumentations(readonly, shallow) {\n const instrumentations = {\n get(key) {\n const target = this[\"__v_raw\"];\n const rawTarget = toRaw(target);\n const rawKey = toRaw(key);\n if (!readonly) {\n if (hasChanged(key, rawKey)) {\n track(rawTarget, \"get\", key);\n }\n track(rawTarget, \"get\", rawKey);\n }\n const { has } = getProto(rawTarget);\n const wrap = shallow ? toShallow : readonly ? toReadonly : toReactive;\n if (has.call(rawTarget, key)) {\n return wrap(target.get(key));\n } else if (has.call(rawTarget, rawKey)) {\n return wrap(target.get(rawKey));\n } else if (target !== rawTarget) {\n target.get(key);\n }\n },\n get size() {\n const target = this[\"__v_raw\"];\n !readonly && track(toRaw(target), \"iterate\", ITERATE_KEY);\n return target.size;\n },\n has(key) {\n const target = this[\"__v_raw\"];\n const rawTarget = toRaw(target);\n const rawKey = toRaw(key);\n if (!readonly) {\n if (hasChanged(key, rawKey)) {\n track(rawTarget, \"has\", key);\n }\n track(rawTarget, \"has\", rawKey);\n }\n return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey);\n },\n forEach(callback, thisArg) {\n const observed = this;\n const target = observed[\"__v_raw\"];\n const rawTarget = toRaw(target);\n const wrap = shallow ? toShallow : readonly ? toReadonly : toReactive;\n !readonly && track(rawTarget, \"iterate\", ITERATE_KEY);\n return target.forEach((value, key) => {\n return callback.call(thisArg, wrap(value), wrap(key), observed);\n });\n }\n };\n extend(\n instrumentations,\n readonly ? {\n add: createReadonlyMethod(\"add\"),\n set: createReadonlyMethod(\"set\"),\n delete: createReadonlyMethod(\"delete\"),\n clear: createReadonlyMethod(\"clear\")\n } : {\n add(value) {\n if (!shallow && !isShallow(value) && !isReadonly(value)) {\n value = toRaw(value);\n }\n const target = toRaw(this);\n const proto = getProto(target);\n const hadKey = proto.has.call(target, value);\n if (!hadKey) {\n target.add(value);\n trigger(target, \"add\", value, value);\n }\n return this;\n },\n set(key, value) {\n if (!shallow && !isShallow(value) && !isReadonly(value)) {\n value = toRaw(value);\n }\n const target = toRaw(this);\n const { has, get } = getProto(target);\n let hadKey = has.call(target, key);\n if (!hadKey) {\n key = toRaw(key);\n hadKey = has.call(target, key);\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n checkIdentityKeys(target, has, key);\n }\n const oldValue = get.call(target, key);\n target.set(key, value);\n if (!hadKey) {\n trigger(target, \"add\", key, value);\n } else if (hasChanged(value, oldValue)) {\n trigger(target, \"set\", key, value, oldValue);\n }\n return this;\n },\n delete(key) {\n const target = toRaw(this);\n const { has, get } = getProto(target);\n let hadKey = has.call(target, key);\n if (!hadKey) {\n key = toRaw(key);\n hadKey = has.call(target, key);\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n checkIdentityKeys(target, has, key);\n }\n const oldValue = get ? get.call(target, key) : void 0;\n const result = target.delete(key);\n if (hadKey) {\n trigger(target, \"delete\", key, void 0, oldValue);\n }\n return result;\n },\n clear() {\n const target = toRaw(this);\n const hadItems = target.size !== 0;\n const oldTarget = !!(process.env.NODE_ENV !== \"production\") ? isMap(target) ? new Map(target) : new Set(target) : void 0;\n const result = target.clear();\n if (hadItems) {\n trigger(\n target,\n \"clear\",\n void 0,\n void 0,\n oldTarget\n );\n }\n return result;\n }\n }\n );\n const iteratorMethods = [\n \"keys\",\n \"values\",\n \"entries\",\n Symbol.iterator\n ];\n iteratorMethods.forEach((method) => {\n instrumentations[method] = createIterableMethod(method, readonly, shallow);\n });\n return instrumentations;\n}\nfunction createInstrumentationGetter(isReadonly2, shallow) {\n const instrumentations = createInstrumentations(isReadonly2, shallow);\n return (target, key, receiver) => {\n if (key === \"__v_isReactive\") {\n return !isReadonly2;\n } else if (key === \"__v_isReadonly\") {\n return isReadonly2;\n } else if (key === \"__v_raw\") {\n return target;\n }\n return Reflect.get(\n hasOwn(instrumentations, key) && key in target ? instrumentations : target,\n key,\n receiver\n );\n };\n}\nconst mutableCollectionHandlers = {\n get: /* @__PURE__ */ createInstrumentationGetter(false, false)\n};\nconst shallowCollectionHandlers = {\n get: /* @__PURE__ */ createInstrumentationGetter(false, true)\n};\nconst readonlyCollectionHandlers = {\n get: /* @__PURE__ */ createInstrumentationGetter(true, false)\n};\nconst shallowReadonlyCollectionHandlers = {\n get: /* @__PURE__ */ createInstrumentationGetter(true, true)\n};\nfunction checkIdentityKeys(target, has, key) {\n const rawKey = toRaw(key);\n if (rawKey !== key && has.call(target, rawKey)) {\n const type = toRawType(target);\n warn(\n `Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`\n );\n }\n}\n\nconst reactiveMap = /* @__PURE__ */ new WeakMap();\nconst shallowReactiveMap = /* @__PURE__ */ new WeakMap();\nconst readonlyMap = /* @__PURE__ */ new WeakMap();\nconst shallowReadonlyMap = /* @__PURE__ */ new WeakMap();\nfunction targetTypeMap(rawType) {\n switch (rawType) {\n case \"Object\":\n case \"Array\":\n return 1 /* COMMON */;\n case \"Map\":\n case \"Set\":\n case \"WeakMap\":\n case \"WeakSet\":\n return 2 /* COLLECTION */;\n default:\n return 0 /* INVALID */;\n }\n}\nfunction getTargetType(value) {\n return value[\"__v_skip\"] || !Object.isExtensible(value) ? 0 /* INVALID */ : targetTypeMap(toRawType(value));\n}\nfunction reactive(target) {\n if (isReadonly(target)) {\n return target;\n }\n return createReactiveObject(\n target,\n false,\n mutableHandlers,\n mutableCollectionHandlers,\n reactiveMap\n );\n}\nfunction shallowReactive(target) {\n return createReactiveObject(\n target,\n false,\n shallowReactiveHandlers,\n shallowCollectionHandlers,\n shallowReactiveMap\n );\n}\nfunction readonly(target) {\n return createReactiveObject(\n target,\n true,\n readonlyHandlers,\n readonlyCollectionHandlers,\n readonlyMap\n );\n}\nfunction shallowReadonly(target) {\n return createReactiveObject(\n target,\n true,\n shallowReadonlyHandlers,\n shallowReadonlyCollectionHandlers,\n shallowReadonlyMap\n );\n}\nfunction createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) {\n if (!isObject(target)) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n warn(\n `value cannot be made ${isReadonly2 ? \"readonly\" : \"reactive\"}: ${String(\n target\n )}`\n );\n }\n return target;\n }\n if (target[\"__v_raw\"] && !(isReadonly2 && target[\"__v_isReactive\"])) {\n return target;\n }\n const targetType = getTargetType(target);\n if (targetType === 0 /* INVALID */) {\n return target;\n }\n const existingProxy = proxyMap.get(target);\n if (existingProxy) {\n return existingProxy;\n }\n const proxy = new Proxy(\n target,\n targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers\n );\n proxyMap.set(target, proxy);\n return proxy;\n}\nfunction isReactive(value) {\n if (isReadonly(value)) {\n return isReactive(value[\"__v_raw\"]);\n }\n return !!(value && value[\"__v_isReactive\"]);\n}\nfunction isReadonly(value) {\n return !!(value && value[\"__v_isReadonly\"]);\n}\nfunction isShallow(value) {\n return !!(value && value[\"__v_isShallow\"]);\n}\nfunction isProxy(value) {\n return value ? !!value[\"__v_raw\"] : false;\n}\nfunction toRaw(observed) {\n const raw = observed && observed[\"__v_raw\"];\n return raw ? toRaw(raw) : observed;\n}\nfunction markRaw(value) {\n if (!hasOwn(value, \"__v_skip\") && Object.isExtensible(value)) {\n def(value, \"__v_skip\", true);\n }\n return value;\n}\nconst toReactive = (value) => isObject(value) ? reactive(value) : value;\nconst toReadonly = (value) => isObject(value) ? readonly(value) : value;\n\nfunction isRef(r) {\n return r ? r[\"__v_isRef\"] === true : false;\n}\nfunction ref(value) {\n return createRef(value, false);\n}\nfunction shallowRef(value) {\n return createRef(value, true);\n}\nfunction createRef(rawValue, shallow) {\n if (isRef(rawValue)) {\n return rawValue;\n }\n return new RefImpl(rawValue, shallow);\n}\nclass RefImpl {\n constructor(value, isShallow2) {\n this.dep = new Dep();\n this[\"__v_isRef\"] = true;\n this[\"__v_isShallow\"] = false;\n this._rawValue = isShallow2 ? value : toRaw(value);\n this._value = isShallow2 ? value : toReactive(value);\n this[\"__v_isShallow\"] = isShallow2;\n }\n get value() {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n this.dep.track({\n target: this,\n type: \"get\",\n key: \"value\"\n });\n } else {\n this.dep.track();\n }\n return this._value;\n }\n set value(newValue) {\n const oldValue = this._rawValue;\n const useDirectValue = this[\"__v_isShallow\"] || isShallow(newValue) || isReadonly(newValue);\n newValue = useDirectValue ? newValue : toRaw(newValue);\n if (hasChanged(newValue, oldValue)) {\n this._rawValue = newValue;\n this._value = useDirectValue ? newValue : toReactive(newValue);\n if (!!(process.env.NODE_ENV !== \"production\")) {\n this.dep.trigger({\n target: this,\n type: \"set\",\n key: \"value\",\n newValue,\n oldValue\n });\n } else {\n this.dep.trigger();\n }\n }\n }\n}\nfunction triggerRef(ref2) {\n if (ref2.dep) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n ref2.dep.trigger({\n target: ref2,\n type: \"set\",\n key: \"value\",\n newValue: ref2._value\n });\n } else {\n ref2.dep.trigger();\n }\n }\n}\nfunction unref(ref2) {\n return isRef(ref2) ? ref2.value : ref2;\n}\nfunction toValue(source) {\n return isFunction(source) ? source() : unref(source);\n}\nconst shallowUnwrapHandlers = {\n get: (target, key, receiver) => key === \"__v_raw\" ? target : unref(Reflect.get(target, key, receiver)),\n set: (target, key, value, receiver) => {\n const oldValue = target[key];\n if (isRef(oldValue) && !isRef(value)) {\n oldValue.value = value;\n return true;\n } else {\n return Reflect.set(target, key, value, receiver);\n }\n }\n};\nfunction proxyRefs(objectWithRefs) {\n return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers);\n}\nclass CustomRefImpl {\n constructor(factory) {\n this[\"__v_isRef\"] = true;\n this._value = void 0;\n const dep = this.dep = new Dep();\n const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep));\n this._get = get;\n this._set = set;\n }\n get value() {\n return this._value = this._get();\n }\n set value(newVal) {\n this._set(newVal);\n }\n}\nfunction customRef(factory) {\n return new CustomRefImpl(factory);\n}\nfunction toRefs(object) {\n if (!!(process.env.NODE_ENV !== \"production\") && !isProxy(object)) {\n warn(`toRefs() expects a reactive object but received a plain one.`);\n }\n const ret = isArray(object) ? new Array(object.length) : {};\n for (const key in object) {\n ret[key] = propertyToRef(object, key);\n }\n return ret;\n}\nclass ObjectRefImpl {\n constructor(_object, _key, _defaultValue) {\n this._object = _object;\n this._key = _key;\n this._defaultValue = _defaultValue;\n this[\"__v_isRef\"] = true;\n this._value = void 0;\n }\n get value() {\n const val = this._object[this._key];\n return this._value = val === void 0 ? this._defaultValue : val;\n }\n set value(newVal) {\n this._object[this._key] = newVal;\n }\n get dep() {\n return getDepFromReactive(toRaw(this._object), this._key);\n }\n}\nclass GetterRefImpl {\n constructor(_getter) {\n this._getter = _getter;\n this[\"__v_isRef\"] = true;\n this[\"__v_isReadonly\"] = true;\n this._value = void 0;\n }\n get value() {\n return this._value = this._getter();\n }\n}\nfunction toRef(source, key, defaultValue) {\n if (isRef(source)) {\n return source;\n } else if (isFunction(source)) {\n return new GetterRefImpl(source);\n } else if (isObject(source) && arguments.length > 1) {\n return propertyToRef(source, key, defaultValue);\n } else {\n return ref(source);\n }\n}\nfunction propertyToRef(source, key, defaultValue) {\n const val = source[key];\n return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue);\n}\n\nclass ComputedRefImpl {\n constructor(fn, setter, isSSR) {\n this.fn = fn;\n this.setter = setter;\n /**\n * @internal\n */\n this._value = void 0;\n /**\n * @internal\n */\n this.dep = new Dep(this);\n /**\n * @internal\n */\n this.__v_isRef = true;\n // TODO isolatedDeclarations \"__v_isReadonly\"\n // A computed is also a subscriber that tracks other deps\n /**\n * @internal\n */\n this.deps = void 0;\n /**\n * @internal\n */\n this.depsTail = void 0;\n /**\n * @internal\n */\n this.flags = 16;\n /**\n * @internal\n */\n this.globalVersion = globalVersion - 1;\n /**\n * @internal\n */\n this.next = void 0;\n // for backwards compat\n this.effect = this;\n this[\"__v_isReadonly\"] = !setter;\n this.isSSR = isSSR;\n }\n /**\n * @internal\n */\n notify() {\n this.flags |= 16;\n if (!(this.flags & 8) && // avoid infinite self recursion\n activeSub !== this) {\n batch(this, true);\n return true;\n } else if (!!(process.env.NODE_ENV !== \"production\")) ;\n }\n get value() {\n const link = !!(process.env.NODE_ENV !== \"production\") ? this.dep.track({\n target: this,\n type: \"get\",\n key: \"value\"\n }) : this.dep.track();\n refreshComputed(this);\n if (link) {\n link.version = this.dep.version;\n }\n return this._value;\n }\n set value(newValue) {\n if (this.setter) {\n this.setter(newValue);\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn(\"Write operation failed: computed value is readonly\");\n }\n }\n}\nfunction computed(getterOrOptions, debugOptions, isSSR = false) {\n let getter;\n let setter;\n if (isFunction(getterOrOptions)) {\n getter = getterOrOptions;\n } else {\n getter = getterOrOptions.get;\n setter = getterOrOptions.set;\n }\n const cRef = new ComputedRefImpl(getter, setter, isSSR);\n if (!!(process.env.NODE_ENV !== \"production\") && debugOptions && !isSSR) {\n cRef.onTrack = debugOptions.onTrack;\n cRef.onTrigger = debugOptions.onTrigger;\n }\n return cRef;\n}\n\nconst TrackOpTypes = {\n \"GET\": \"get\",\n \"HAS\": \"has\",\n \"ITERATE\": \"iterate\"\n};\nconst TriggerOpTypes = {\n \"SET\": \"set\",\n \"ADD\": \"add\",\n \"DELETE\": \"delete\",\n \"CLEAR\": \"clear\"\n};\nconst ReactiveFlags = {\n \"SKIP\": \"__v_skip\",\n \"IS_REACTIVE\": \"__v_isReactive\",\n \"IS_READONLY\": \"__v_isReadonly\",\n \"IS_SHALLOW\": \"__v_isShallow\",\n \"RAW\": \"__v_raw\",\n \"IS_REF\": \"__v_isRef\"\n};\n\nconst WatchErrorCodes = {\n \"WATCH_GETTER\": 2,\n \"2\": \"WATCH_GETTER\",\n \"WATCH_CALLBACK\": 3,\n \"3\": \"WATCH_CALLBACK\",\n \"WATCH_CLEANUP\": 4,\n \"4\": \"WATCH_CLEANUP\"\n};\nconst INITIAL_WATCHER_VALUE = {};\nconst cleanupMap = /* @__PURE__ */ new WeakMap();\nlet activeWatcher = void 0;\nfunction getCurrentWatcher() {\n return activeWatcher;\n}\nfunction onWatcherCleanup(cleanupFn, failSilently = false, owner = activeWatcher) {\n if (owner) {\n let cleanups = cleanupMap.get(owner);\n if (!cleanups) cleanupMap.set(owner, cleanups = []);\n cleanups.push(cleanupFn);\n } else if (!!(process.env.NODE_ENV !== \"production\") && !failSilently) {\n warn(\n `onWatcherCleanup() was called when there was no active watcher to associate with.`\n );\n }\n}\nfunction watch(source, cb, options = EMPTY_OBJ) {\n const { immediate, deep, once, scheduler, augmentJob, call } = options;\n const warnInvalidSource = (s) => {\n (options.onWarn || warn)(\n `Invalid watch source: `,\n s,\n `A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.`\n );\n };\n const reactiveGetter = (source2) => {\n if (deep) return source2;\n if (isShallow(source2) || deep === false || deep === 0)\n return traverse(source2, 1);\n return traverse(source2);\n };\n let effect;\n let getter;\n let cleanup;\n let boundCleanup;\n let forceTrigger = false;\n let isMultiSource = false;\n if (isRef(source)) {\n getter = () => source.value;\n forceTrigger = isShallow(source);\n } else if (isReactive(source)) {\n getter = () => reactiveGetter(source);\n forceTrigger = true;\n } else if (isArray(source)) {\n isMultiSource = true;\n forceTrigger = source.some((s) => isReactive(s) || isShallow(s));\n getter = () => source.map((s) => {\n if (isRef(s)) {\n return s.value;\n } else if (isReactive(s)) {\n return reactiveGetter(s);\n } else if (isFunction(s)) {\n return call ? call(s, 2) : s();\n } else {\n !!(process.env.NODE_ENV !== \"production\") && warnInvalidSource(s);\n }\n });\n } else if (isFunction(source)) {\n if (cb) {\n getter = call ? () => call(source, 2) : source;\n } else {\n getter = () => {\n if (cleanup) {\n pauseTracking();\n try {\n cleanup();\n } finally {\n resetTracking();\n }\n }\n const currentEffect = activeWatcher;\n activeWatcher = effect;\n try {\n return call ? call(source, 3, [boundCleanup]) : source(boundCleanup);\n } finally {\n activeWatcher = currentEffect;\n }\n };\n }\n } else {\n getter = NOOP;\n !!(process.env.NODE_ENV !== \"production\") && warnInvalidSource(source);\n }\n if (cb && deep) {\n const baseGetter = getter;\n const depth = deep === true ? Infinity : deep;\n getter = () => traverse(baseGetter(), depth);\n }\n const scope = getCurrentScope();\n const watchHandle = () => {\n effect.stop();\n if (scope && scope.active) {\n remove(scope.effects, effect);\n }\n };\n if (once && cb) {\n const _cb = cb;\n cb = (...args) => {\n _cb(...args);\n watchHandle();\n };\n }\n let oldValue = isMultiSource ? new Array(source.length).fill(INITIAL_WATCHER_VALUE) : INITIAL_WATCHER_VALUE;\n const job = (immediateFirstRun) => {\n if (!(effect.flags & 1) || !effect.dirty && !immediateFirstRun) {\n return;\n }\n if (cb) {\n const newValue = effect.run();\n if (deep || forceTrigger || (isMultiSource ? newValue.some((v, i) => hasChanged(v, oldValue[i])) : hasChanged(newValue, oldValue))) {\n if (cleanup) {\n cleanup();\n }\n const currentWatcher = activeWatcher;\n activeWatcher = effect;\n try {\n const args = [\n newValue,\n // pass undefined as the old value when it's changed for the first time\n oldValue === INITIAL_WATCHER_VALUE ? void 0 : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE ? [] : oldValue,\n boundCleanup\n ];\n oldValue = newValue;\n call ? call(cb, 3, args) : (\n // @ts-expect-error\n cb(...args)\n );\n } finally {\n activeWatcher = currentWatcher;\n }\n }\n } else {\n effect.run();\n }\n };\n if (augmentJob) {\n augmentJob(job);\n }\n effect = new ReactiveEffect(getter);\n effect.scheduler = scheduler ? () => scheduler(job, false) : job;\n boundCleanup = (fn) => onWatcherCleanup(fn, false, effect);\n cleanup = effect.onStop = () => {\n const cleanups = cleanupMap.get(effect);\n if (cleanups) {\n if (call) {\n call(cleanups, 4);\n } else {\n for (const cleanup2 of cleanups) cleanup2();\n }\n cleanupMap.delete(effect);\n }\n };\n if (!!(process.env.NODE_ENV !== \"production\")) {\n effect.onTrack = options.onTrack;\n effect.onTrigger = options.onTrigger;\n }\n if (cb) {\n if (immediate) {\n job(true);\n } else {\n oldValue = effect.run();\n }\n } else if (scheduler) {\n scheduler(job.bind(null, true), true);\n } else {\n effect.run();\n }\n watchHandle.pause = effect.pause.bind(effect);\n watchHandle.resume = effect.resume.bind(effect);\n watchHandle.stop = watchHandle;\n return watchHandle;\n}\nfunction traverse(value, depth = Infinity, seen) {\n if (depth <= 0 || !isObject(value) || value[\"__v_skip\"]) {\n return value;\n }\n seen = seen || /* @__PURE__ */ new Map();\n if ((seen.get(value) || 0) >= depth) {\n return value;\n }\n seen.set(value, depth);\n depth--;\n if (isRef(value)) {\n traverse(value.value, depth, seen);\n } else if (isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n traverse(value[i], depth, seen);\n }\n } else if (isSet(value) || isMap(value)) {\n value.forEach((v) => {\n traverse(v, depth, seen);\n });\n } else if (isPlainObject(value)) {\n for (const key in value) {\n traverse(value[key], depth, seen);\n }\n for (const key of Object.getOwnPropertySymbols(value)) {\n if (Object.prototype.propertyIsEnumerable.call(value, key)) {\n traverse(value[key], depth, seen);\n }\n }\n }\n return value;\n}\n\nexport { ARRAY_ITERATE_KEY, EffectFlags, EffectScope, ITERATE_KEY, MAP_KEY_ITERATE_KEY, ReactiveEffect, ReactiveFlags, TrackOpTypes, TriggerOpTypes, WatchErrorCodes, computed, customRef, effect, effectScope, enableTracking, getCurrentScope, getCurrentWatcher, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, onEffectCleanup, onScopeDispose, onWatcherCleanup, pauseTracking, proxyRefs, reactive, reactiveReadArray, readonly, ref, resetTracking, shallowReactive, shallowReadArray, shallowReadonly, shallowRef, stop, toRaw, toReactive, toReadonly, toRef, toRefs, toValue, track, traverse, trigger, triggerRef, unref, watch };\n","/**\n* @vue/runtime-core v3.5.22\n* (c) 2018-present Yuxi (Evan) You and Vue contributors\n* @license MIT\n**/\nimport { pauseTracking, resetTracking, isRef, toRaw, traverse, shallowRef, readonly, isReactive, ref, isShallow, isReadonly, shallowReadArray, toReadonly, toReactive, shallowReadonly, track, reactive, shallowReactive, trigger, ReactiveEffect, watch as watch$1, customRef, isProxy, proxyRefs, markRaw, EffectScope, computed as computed$1 } from '@vue/reactivity';\nexport { EffectScope, ReactiveEffect, TrackOpTypes, TriggerOpTypes, customRef, effect, effectScope, getCurrentScope, getCurrentWatcher, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, onScopeDispose, onWatcherCleanup, proxyRefs, reactive, readonly, ref, shallowReactive, shallowReadonly, shallowRef, stop, toRaw, toRef, toRefs, toValue, triggerRef, unref } from '@vue/reactivity';\nimport { isString, isFunction, EMPTY_OBJ, isPromise, isArray, NOOP, getGlobalThis, extend, isBuiltInDirective, NO, hasOwn, remove, def, isOn, isReservedProp, normalizeClass, stringifyStyle, normalizeStyle, isKnownSvgAttr, isBooleanAttr, isKnownHtmlAttr, includeBooleanAttr, isRenderableAttrValue, normalizeCssVarValue, getEscapedCssVarName, isObject, isRegExp, invokeArrayFns, toHandlerKey, camelize, capitalize, isSymbol, isGloballyAllowed, EMPTY_ARR, hyphenate, makeMap, toRawType, hasChanged, looseToNumber, isModelListener, toNumber } from '@vue/shared';\nexport { camelize, capitalize, normalizeClass, normalizeProps, normalizeStyle, toDisplayString, toHandlerKey } from '@vue/shared';\n\nconst stack = [];\nfunction pushWarningContext(vnode) {\n stack.push(vnode);\n}\nfunction popWarningContext() {\n stack.pop();\n}\nlet isWarning = false;\nfunction warn$1(msg, ...args) {\n if (isWarning) return;\n isWarning = true;\n pauseTracking();\n const instance = stack.length ? stack[stack.length - 1].component : null;\n const appWarnHandler = instance && instance.appContext.config.warnHandler;\n const trace = getComponentTrace();\n if (appWarnHandler) {\n callWithErrorHandling(\n appWarnHandler,\n instance,\n 11,\n [\n // eslint-disable-next-line no-restricted-syntax\n msg + args.map((a) => {\n var _a, _b;\n return (_b = (_a = a.toString) == null ? void 0 : _a.call(a)) != null ? _b : JSON.stringify(a);\n }).join(\"\"),\n instance && instance.proxy,\n trace.map(\n ({ vnode }) => `at <${formatComponentName(instance, vnode.type)}>`\n ).join(\"\\n\"),\n trace\n ]\n );\n } else {\n const warnArgs = [`[Vue warn]: ${msg}`, ...args];\n if (trace.length && // avoid spamming console during tests\n true) {\n warnArgs.push(`\n`, ...formatTrace(trace));\n }\n console.warn(...warnArgs);\n }\n resetTracking();\n isWarning = false;\n}\nfunction getComponentTrace() {\n let currentVNode = stack[stack.length - 1];\n if (!currentVNode) {\n return [];\n }\n const normalizedStack = [];\n while (currentVNode) {\n const last = normalizedStack[0];\n if (last && last.vnode === currentVNode) {\n last.recurseCount++;\n } else {\n normalizedStack.push({\n vnode: currentVNode,\n recurseCount: 0\n });\n }\n const parentInstance = currentVNode.component && currentVNode.component.parent;\n currentVNode = parentInstance && parentInstance.vnode;\n }\n return normalizedStack;\n}\nfunction formatTrace(trace) {\n const logs = [];\n trace.forEach((entry, i) => {\n logs.push(...i === 0 ? [] : [`\n`], ...formatTraceEntry(entry));\n });\n return logs;\n}\nfunction formatTraceEntry({ vnode, recurseCount }) {\n const postfix = recurseCount > 0 ? `... (${recurseCount} recursive calls)` : ``;\n const isRoot = vnode.component ? vnode.component.parent == null : false;\n const open = ` at <${formatComponentName(\n vnode.component,\n vnode.type,\n isRoot\n )}`;\n const close = `>` + postfix;\n return vnode.props ? [open, ...formatProps(vnode.props), close] : [open + close];\n}\nfunction formatProps(props) {\n const res = [];\n const keys = Object.keys(props);\n keys.slice(0, 3).forEach((key) => {\n res.push(...formatProp(key, props[key]));\n });\n if (keys.length > 3) {\n res.push(` ...`);\n }\n return res;\n}\nfunction formatProp(key, value, raw) {\n if (isString(value)) {\n value = JSON.stringify(value);\n return raw ? value : [`${key}=${value}`];\n } else if (typeof value === \"number\" || typeof value === \"boolean\" || value == null) {\n return raw ? value : [`${key}=${value}`];\n } else if (isRef(value)) {\n value = formatProp(key, toRaw(value.value), true);\n return raw ? value : [`${key}=Ref<`, value, `>`];\n } else if (isFunction(value)) {\n return [`${key}=fn${value.name ? `<${value.name}>` : ``}`];\n } else {\n value = toRaw(value);\n return raw ? value : [`${key}=`, value];\n }\n}\nfunction assertNumber(val, type) {\n if (!!!(process.env.NODE_ENV !== \"production\")) return;\n if (val === void 0) {\n return;\n } else if (typeof val !== \"number\") {\n warn$1(`${type} is not a valid number - got ${JSON.stringify(val)}.`);\n } else if (isNaN(val)) {\n warn$1(`${type} is NaN - the duration expression might be incorrect.`);\n }\n}\n\nconst ErrorCodes = {\n \"SETUP_FUNCTION\": 0,\n \"0\": \"SETUP_FUNCTION\",\n \"RENDER_FUNCTION\": 1,\n \"1\": \"RENDER_FUNCTION\",\n \"NATIVE_EVENT_HANDLER\": 5,\n \"5\": \"NATIVE_EVENT_HANDLER\",\n \"COMPONENT_EVENT_HANDLER\": 6,\n \"6\": \"COMPONENT_EVENT_HANDLER\",\n \"VNODE_HOOK\": 7,\n \"7\": \"VNODE_HOOK\",\n \"DIRECTIVE_HOOK\": 8,\n \"8\": \"DIRECTIVE_HOOK\",\n \"TRANSITION_HOOK\": 9,\n \"9\": \"TRANSITION_HOOK\",\n \"APP_ERROR_HANDLER\": 10,\n \"10\": \"APP_ERROR_HANDLER\",\n \"APP_WARN_HANDLER\": 11,\n \"11\": \"APP_WARN_HANDLER\",\n \"FUNCTION_REF\": 12,\n \"12\": \"FUNCTION_REF\",\n \"ASYNC_COMPONENT_LOADER\": 13,\n \"13\": \"ASYNC_COMPONENT_LOADER\",\n \"SCHEDULER\": 14,\n \"14\": \"SCHEDULER\",\n \"COMPONENT_UPDATE\": 15,\n \"15\": \"COMPONENT_UPDATE\",\n \"APP_UNMOUNT_CLEANUP\": 16,\n \"16\": \"APP_UNMOUNT_CLEANUP\"\n};\nconst ErrorTypeStrings$1 = {\n [\"sp\"]: \"serverPrefetch hook\",\n [\"bc\"]: \"beforeCreate hook\",\n [\"c\"]: \"created hook\",\n [\"bm\"]: \"beforeMount hook\",\n [\"m\"]: \"mounted hook\",\n [\"bu\"]: \"beforeUpdate hook\",\n [\"u\"]: \"updated\",\n [\"bum\"]: \"beforeUnmount hook\",\n [\"um\"]: \"unmounted hook\",\n [\"a\"]: \"activated hook\",\n [\"da\"]: \"deactivated hook\",\n [\"ec\"]: \"errorCaptured hook\",\n [\"rtc\"]: \"renderTracked hook\",\n [\"rtg\"]: \"renderTriggered hook\",\n [0]: \"setup function\",\n [1]: \"render function\",\n [2]: \"watcher getter\",\n [3]: \"watcher callback\",\n [4]: \"watcher cleanup function\",\n [5]: \"native event handler\",\n [6]: \"component event handler\",\n [7]: \"vnode hook\",\n [8]: \"directive hook\",\n [9]: \"transition hook\",\n [10]: \"app errorHandler\",\n [11]: \"app warnHandler\",\n [12]: \"ref function\",\n [13]: \"async component loader\",\n [14]: \"scheduler flush\",\n [15]: \"component update\",\n [16]: \"app unmount cleanup function\"\n};\nfunction callWithErrorHandling(fn, instance, type, args) {\n try {\n return args ? fn(...args) : fn();\n } catch (err) {\n handleError(err, instance, type);\n }\n}\nfunction callWithAsyncErrorHandling(fn, instance, type, args) {\n if (isFunction(fn)) {\n const res = callWithErrorHandling(fn, instance, type, args);\n if (res && isPromise(res)) {\n res.catch((err) => {\n handleError(err, instance, type);\n });\n }\n return res;\n }\n if (isArray(fn)) {\n const values = [];\n for (let i = 0; i < fn.length; i++) {\n values.push(callWithAsyncErrorHandling(fn[i], instance, type, args));\n }\n return values;\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\n `Invalid value type passed to callWithAsyncErrorHandling(): ${typeof fn}`\n );\n }\n}\nfunction handleError(err, instance, type, throwInDev = true) {\n const contextVNode = instance ? instance.vnode : null;\n const { errorHandler, throwUnhandledErrorInProduction } = instance && instance.appContext.config || EMPTY_OBJ;\n if (instance) {\n let cur = instance.parent;\n const exposedInstance = instance.proxy;\n const errorInfo = !!(process.env.NODE_ENV !== \"production\") ? ErrorTypeStrings$1[type] : `https://vuejs.org/error-reference/#runtime-${type}`;\n while (cur) {\n const errorCapturedHooks = cur.ec;\n if (errorCapturedHooks) {\n for (let i = 0; i < errorCapturedHooks.length; i++) {\n if (errorCapturedHooks[i](err, exposedInstance, errorInfo) === false) {\n return;\n }\n }\n }\n cur = cur.parent;\n }\n if (errorHandler) {\n pauseTracking();\n callWithErrorHandling(errorHandler, null, 10, [\n err,\n exposedInstance,\n errorInfo\n ]);\n resetTracking();\n return;\n }\n }\n logError(err, type, contextVNode, throwInDev, throwUnhandledErrorInProduction);\n}\nfunction logError(err, type, contextVNode, throwInDev = true, throwInProd = false) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n const info = ErrorTypeStrings$1[type];\n if (contextVNode) {\n pushWarningContext(contextVNode);\n }\n warn$1(`Unhandled error${info ? ` during execution of ${info}` : ``}`);\n if (contextVNode) {\n popWarningContext();\n }\n if (throwInDev) {\n throw err;\n } else {\n console.error(err);\n }\n } else if (throwInProd) {\n throw err;\n } else {\n console.error(err);\n }\n}\n\nconst queue = [];\nlet flushIndex = -1;\nconst pendingPostFlushCbs = [];\nlet activePostFlushCbs = null;\nlet postFlushIndex = 0;\nconst resolvedPromise = /* @__PURE__ */ Promise.resolve();\nlet currentFlushPromise = null;\nconst RECURSION_LIMIT = 100;\nfunction nextTick(fn) {\n const p = currentFlushPromise || resolvedPromise;\n return fn ? p.then(this ? fn.bind(this) : fn) : p;\n}\nfunction findInsertionIndex(id) {\n let start = flushIndex + 1;\n let end = queue.length;\n while (start < end) {\n const middle = start + end >>> 1;\n const middleJob = queue[middle];\n const middleJobId = getId(middleJob);\n if (middleJobId < id || middleJobId === id && middleJob.flags & 2) {\n start = middle + 1;\n } else {\n end = middle;\n }\n }\n return start;\n}\nfunction queueJob(job) {\n if (!(job.flags & 1)) {\n const jobId = getId(job);\n const lastJob = queue[queue.length - 1];\n if (!lastJob || // fast path when the job id is larger than the tail\n !(job.flags & 2) && jobId >= getId(lastJob)) {\n queue.push(job);\n } else {\n queue.splice(findInsertionIndex(jobId), 0, job);\n }\n job.flags |= 1;\n queueFlush();\n }\n}\nfunction queueFlush() {\n if (!currentFlushPromise) {\n currentFlushPromise = resolvedPromise.then(flushJobs);\n }\n}\nfunction queuePostFlushCb(cb) {\n if (!isArray(cb)) {\n if (activePostFlushCbs && cb.id === -1) {\n activePostFlushCbs.splice(postFlushIndex + 1, 0, cb);\n } else if (!(cb.flags & 1)) {\n pendingPostFlushCbs.push(cb);\n cb.flags |= 1;\n }\n } else {\n pendingPostFlushCbs.push(...cb);\n }\n queueFlush();\n}\nfunction flushPreFlushCbs(instance, seen, i = flushIndex + 1) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n seen = seen || /* @__PURE__ */ new Map();\n }\n for (; i < queue.length; i++) {\n const cb = queue[i];\n if (cb && cb.flags & 2) {\n if (instance && cb.id !== instance.uid) {\n continue;\n }\n if (!!(process.env.NODE_ENV !== \"production\") && checkRecursiveUpdates(seen, cb)) {\n continue;\n }\n queue.splice(i, 1);\n i--;\n if (cb.flags & 4) {\n cb.flags &= -2;\n }\n cb();\n if (!(cb.flags & 4)) {\n cb.flags &= -2;\n }\n }\n }\n}\nfunction flushPostFlushCbs(seen) {\n if (pendingPostFlushCbs.length) {\n const deduped = [...new Set(pendingPostFlushCbs)].sort(\n (a, b) => getId(a) - getId(b)\n );\n pendingPostFlushCbs.length = 0;\n if (activePostFlushCbs) {\n activePostFlushCbs.push(...deduped);\n return;\n }\n activePostFlushCbs = deduped;\n if (!!(process.env.NODE_ENV !== \"production\")) {\n seen = seen || /* @__PURE__ */ new Map();\n }\n for (postFlushIndex = 0; postFlushIndex < activePostFlushCbs.length; postFlushIndex++) {\n const cb = activePostFlushCbs[postFlushIndex];\n if (!!(process.env.NODE_ENV !== \"production\") && checkRecursiveUpdates(seen, cb)) {\n continue;\n }\n if (cb.flags & 4) {\n cb.flags &= -2;\n }\n if (!(cb.flags & 8)) cb();\n cb.flags &= -2;\n }\n activePostFlushCbs = null;\n postFlushIndex = 0;\n }\n}\nconst getId = (job) => job.id == null ? job.flags & 2 ? -1 : Infinity : job.id;\nfunction flushJobs(seen) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n seen = seen || /* @__PURE__ */ new Map();\n }\n const check = !!(process.env.NODE_ENV !== \"production\") ? (job) => checkRecursiveUpdates(seen, job) : NOOP;\n try {\n for (flushIndex = 0; flushIndex < queue.length; flushIndex++) {\n const job = queue[flushIndex];\n if (job && !(job.flags & 8)) {\n if (!!(process.env.NODE_ENV !== \"production\") && check(job)) {\n continue;\n }\n if (job.flags & 4) {\n job.flags &= ~1;\n }\n callWithErrorHandling(\n job,\n job.i,\n job.i ? 15 : 14\n );\n if (!(job.flags & 4)) {\n job.flags &= ~1;\n }\n }\n }\n } finally {\n for (; flushIndex < queue.length; flushIndex++) {\n const job = queue[flushIndex];\n if (job) {\n job.flags &= -2;\n }\n }\n flushIndex = -1;\n queue.length = 0;\n flushPostFlushCbs(seen);\n currentFlushPromise = null;\n if (queue.length || pendingPostFlushCbs.length) {\n flushJobs(seen);\n }\n }\n}\nfunction checkRecursiveUpdates(seen, fn) {\n const count = seen.get(fn) || 0;\n if (count > RECURSION_LIMIT) {\n const instance = fn.i;\n const componentName = instance && getComponentName(instance.type);\n handleError(\n `Maximum recursive updates exceeded${componentName ? ` in component <${componentName}>` : ``}. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.`,\n null,\n 10\n );\n return true;\n }\n seen.set(fn, count + 1);\n return false;\n}\n\nlet isHmrUpdating = false;\nconst hmrDirtyComponents = /* @__PURE__ */ new Map();\nif (!!(process.env.NODE_ENV !== \"production\")) {\n getGlobalThis().__VUE_HMR_RUNTIME__ = {\n createRecord: tryWrap(createRecord),\n rerender: tryWrap(rerender),\n reload: tryWrap(reload)\n };\n}\nconst map = /* @__PURE__ */ new Map();\nfunction registerHMR(instance) {\n const id = instance.type.__hmrId;\n let record = map.get(id);\n if (!record) {\n createRecord(id, instance.type);\n record = map.get(id);\n }\n record.instances.add(instance);\n}\nfunction unregisterHMR(instance) {\n map.get(instance.type.__hmrId).instances.delete(instance);\n}\nfunction createRecord(id, initialDef) {\n if (map.has(id)) {\n return false;\n }\n map.set(id, {\n initialDef: normalizeClassComponent(initialDef),\n instances: /* @__PURE__ */ new Set()\n });\n return true;\n}\nfunction normalizeClassComponent(component) {\n return isClassComponent(component) ? component.__vccOpts : component;\n}\nfunction rerender(id, newRender) {\n const record = map.get(id);\n if (!record) {\n return;\n }\n record.initialDef.render = newRender;\n [...record.instances].forEach((instance) => {\n if (newRender) {\n instance.render = newRender;\n normalizeClassComponent(instance.type).render = newRender;\n }\n instance.renderCache = [];\n isHmrUpdating = true;\n if (!(instance.job.flags & 8)) {\n instance.update();\n }\n isHmrUpdating = false;\n });\n}\nfunction reload(id, newComp) {\n const record = map.get(id);\n if (!record) return;\n newComp = normalizeClassComponent(newComp);\n updateComponentDef(record.initialDef, newComp);\n const instances = [...record.instances];\n for (let i = 0; i < instances.length; i++) {\n const instance = instances[i];\n const oldComp = normalizeClassComponent(instance.type);\n let dirtyInstances = hmrDirtyComponents.get(oldComp);\n if (!dirtyInstances) {\n if (oldComp !== record.initialDef) {\n updateComponentDef(oldComp, newComp);\n }\n hmrDirtyComponents.set(oldComp, dirtyInstances = /* @__PURE__ */ new Set());\n }\n dirtyInstances.add(instance);\n instance.appContext.propsCache.delete(instance.type);\n instance.appContext.emitsCache.delete(instance.type);\n instance.appContext.optionsCache.delete(instance.type);\n if (instance.ceReload) {\n dirtyInstances.add(instance);\n instance.ceReload(newComp.styles);\n dirtyInstances.delete(instance);\n } else if (instance.parent) {\n queueJob(() => {\n if (!(instance.job.flags & 8)) {\n isHmrUpdating = true;\n instance.parent.update();\n isHmrUpdating = false;\n dirtyInstances.delete(instance);\n }\n });\n } else if (instance.appContext.reload) {\n instance.appContext.reload();\n } else if (typeof window !== \"undefined\") {\n window.location.reload();\n } else {\n console.warn(\n \"[HMR] Root or manually mounted instance modified. Full reload required.\"\n );\n }\n if (instance.root.ce && instance !== instance.root) {\n instance.root.ce._removeChildStyle(oldComp);\n }\n }\n queuePostFlushCb(() => {\n hmrDirtyComponents.clear();\n });\n}\nfunction updateComponentDef(oldComp, newComp) {\n extend(oldComp, newComp);\n for (const key in oldComp) {\n if (key !== \"__file\" && !(key in newComp)) {\n delete oldComp[key];\n }\n }\n}\nfunction tryWrap(fn) {\n return (id, arg) => {\n try {\n return fn(id, arg);\n } catch (e) {\n console.error(e);\n console.warn(\n `[HMR] Something went wrong during Vue component hot-reload. Full reload required.`\n );\n }\n };\n}\n\nlet devtools$1;\nlet buffer = [];\nlet devtoolsNotInstalled = false;\nfunction emit$1(event, ...args) {\n if (devtools$1) {\n devtools$1.emit(event, ...args);\n } else if (!devtoolsNotInstalled) {\n buffer.push({ event, args });\n }\n}\nfunction setDevtoolsHook$1(hook, target) {\n var _a, _b;\n devtools$1 = hook;\n if (devtools$1) {\n devtools$1.enabled = true;\n buffer.forEach(({ event, args }) => devtools$1.emit(event, ...args));\n buffer = [];\n } else if (\n // handle late devtools injection - only do this if we are in an actual\n // browser environment to avoid the timer handle stalling test runner exit\n // (#4815)\n typeof window !== \"undefined\" && // some envs mock window but not fully\n window.HTMLElement && // also exclude jsdom\n // eslint-disable-next-line no-restricted-syntax\n !((_b = (_a = window.navigator) == null ? void 0 : _a.userAgent) == null ? void 0 : _b.includes(\"jsdom\"))\n ) {\n const replay = target.__VUE_DEVTOOLS_HOOK_REPLAY__ = target.__VUE_DEVTOOLS_HOOK_REPLAY__ || [];\n replay.push((newHook) => {\n setDevtoolsHook$1(newHook, target);\n });\n setTimeout(() => {\n if (!devtools$1) {\n target.__VUE_DEVTOOLS_HOOK_REPLAY__ = null;\n devtoolsNotInstalled = true;\n buffer = [];\n }\n }, 3e3);\n } else {\n devtoolsNotInstalled = true;\n buffer = [];\n }\n}\nfunction devtoolsInitApp(app, version) {\n emit$1(\"app:init\" /* APP_INIT */, app, version, {\n Fragment,\n Text,\n Comment,\n Static\n });\n}\nfunction devtoolsUnmountApp(app) {\n emit$1(\"app:unmount\" /* APP_UNMOUNT */, app);\n}\nconst devtoolsComponentAdded = /* @__PURE__ */ createDevtoolsComponentHook(\"component:added\" /* COMPONENT_ADDED */);\nconst devtoolsComponentUpdated = /* @__PURE__ */ createDevtoolsComponentHook(\"component:updated\" /* COMPONENT_UPDATED */);\nconst _devtoolsComponentRemoved = /* @__PURE__ */ createDevtoolsComponentHook(\n \"component:removed\" /* COMPONENT_REMOVED */\n);\nconst devtoolsComponentRemoved = (component) => {\n if (devtools$1 && typeof devtools$1.cleanupBuffer === \"function\" && // remove the component if it wasn't buffered\n !devtools$1.cleanupBuffer(component)) {\n _devtoolsComponentRemoved(component);\n }\n};\n// @__NO_SIDE_EFFECTS__\nfunction createDevtoolsComponentHook(hook) {\n return (component) => {\n emit$1(\n hook,\n component.appContext.app,\n component.uid,\n component.parent ? component.parent.uid : void 0,\n component\n );\n };\n}\nconst devtoolsPerfStart = /* @__PURE__ */ createDevtoolsPerformanceHook(\"perf:start\" /* PERFORMANCE_START */);\nconst devtoolsPerfEnd = /* @__PURE__ */ createDevtoolsPerformanceHook(\"perf:end\" /* PERFORMANCE_END */);\nfunction createDevtoolsPerformanceHook(hook) {\n return (component, type, time) => {\n emit$1(hook, component.appContext.app, component.uid, component, type, time);\n };\n}\nfunction devtoolsComponentEmit(component, event, params) {\n emit$1(\n \"component:emit\" /* COMPONENT_EMIT */,\n component.appContext.app,\n component,\n event,\n params\n );\n}\n\nlet currentRenderingInstance = null;\nlet currentScopeId = null;\nfunction setCurrentRenderingInstance(instance) {\n const prev = currentRenderingInstance;\n currentRenderingInstance = instance;\n currentScopeId = instance && instance.type.__scopeId || null;\n return prev;\n}\nfunction pushScopeId(id) {\n currentScopeId = id;\n}\nfunction popScopeId() {\n currentScopeId = null;\n}\nconst withScopeId = (_id) => withCtx;\nfunction withCtx(fn, ctx = currentRenderingInstance, isNonScopedSlot) {\n if (!ctx) return fn;\n if (fn._n) {\n return fn;\n }\n const renderFnWithContext = (...args) => {\n if (renderFnWithContext._d) {\n setBlockTracking(-1);\n }\n const prevInstance = setCurrentRenderingInstance(ctx);\n let res;\n try {\n res = fn(...args);\n } finally {\n setCurrentRenderingInstance(prevInstance);\n if (renderFnWithContext._d) {\n setBlockTracking(1);\n }\n }\n if (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_DEVTOOLS__) {\n devtoolsComponentUpdated(ctx);\n }\n return res;\n };\n renderFnWithContext._n = true;\n renderFnWithContext._c = true;\n renderFnWithContext._d = true;\n return renderFnWithContext;\n}\n\nfunction validateDirectiveName(name) {\n if (isBuiltInDirective(name)) {\n warn$1(\"Do not use built-in directive ids as custom directive id: \" + name);\n }\n}\nfunction withDirectives(vnode, directives) {\n if (currentRenderingInstance === null) {\n !!(process.env.NODE_ENV !== \"production\") && warn$1(`withDirectives can only be used inside render functions.`);\n return vnode;\n }\n const instance = getComponentPublicInstance(currentRenderingInstance);\n const bindings = vnode.dirs || (vnode.dirs = []);\n for (let i = 0; i < directives.length; i++) {\n let [dir, value, arg, modifiers = EMPTY_OBJ] = directives[i];\n if (dir) {\n if (isFunction(dir)) {\n dir = {\n mounted: dir,\n updated: dir\n };\n }\n if (dir.deep) {\n traverse(value);\n }\n bindings.push({\n dir,\n instance,\n value,\n oldValue: void 0,\n arg,\n modifiers\n });\n }\n }\n return vnode;\n}\nfunction invokeDirectiveHook(vnode, prevVNode, instance, name) {\n const bindings = vnode.dirs;\n const oldBindings = prevVNode && prevVNode.dirs;\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i];\n if (oldBindings) {\n binding.oldValue = oldBindings[i].value;\n }\n let hook = binding.dir[name];\n if (hook) {\n pauseTracking();\n callWithAsyncErrorHandling(hook, instance, 8, [\n vnode.el,\n binding,\n vnode,\n prevVNode\n ]);\n resetTracking();\n }\n }\n}\n\nconst TeleportEndKey = Symbol(\"_vte\");\nconst isTeleport = (type) => type.__isTeleport;\nconst isTeleportDisabled = (props) => props && (props.disabled || props.disabled === \"\");\nconst isTeleportDeferred = (props) => props && (props.defer || props.defer === \"\");\nconst isTargetSVG = (target) => typeof SVGElement !== \"undefined\" && target instanceof SVGElement;\nconst isTargetMathML = (target) => typeof MathMLElement === \"function\" && target instanceof MathMLElement;\nconst resolveTarget = (props, select) => {\n const targetSelector = props && props.to;\n if (isString(targetSelector)) {\n if (!select) {\n !!(process.env.NODE_ENV !== \"production\") && warn$1(\n `Current renderer does not support string target for Teleports. (missing querySelector renderer option)`\n );\n return null;\n } else {\n const target = select(targetSelector);\n if (!!(process.env.NODE_ENV !== \"production\") && !target && !isTeleportDisabled(props)) {\n warn$1(\n `Failed to locate Teleport target with selector \"${targetSelector}\". Note the target element must exist before the component is mounted - i.e. the target cannot be rendered by the component itself, and ideally should be outside of the entire Vue component tree.`\n );\n }\n return target;\n }\n } else {\n if (!!(process.env.NODE_ENV !== \"production\") && !targetSelector && !isTeleportDisabled(props)) {\n warn$1(`Invalid Teleport target: ${targetSelector}`);\n }\n return targetSelector;\n }\n};\nconst TeleportImpl = {\n name: \"Teleport\",\n __isTeleport: true,\n process(n1, n2, container, anchor, parentComponent, parentSuspense, namespace, slotScopeIds, optimized, internals) {\n const {\n mc: mountChildren,\n pc: patchChildren,\n pbc: patchBlockChildren,\n o: { insert, querySelector, createText, createComment }\n } = internals;\n const disabled = isTeleportDisabled(n2.props);\n let { shapeFlag, children, dynamicChildren } = n2;\n if (!!(process.env.NODE_ENV !== \"production\") && isHmrUpdating) {\n optimized = false;\n dynamicChildren = null;\n }\n if (n1 == null) {\n const placeholder = n2.el = !!(process.env.NODE_ENV !== \"production\") ? createComment(\"teleport start\") : createText(\"\");\n const mainAnchor = n2.anchor = !!(process.env.NODE_ENV !== \"production\") ? createComment(\"teleport end\") : createText(\"\");\n insert(placeholder, container, anchor);\n insert(mainAnchor, container, anchor);\n const mount = (container2, anchor2) => {\n if (shapeFlag & 16) {\n mountChildren(\n children,\n container2,\n anchor2,\n parentComponent,\n parentSuspense,\n namespace,\n slotScopeIds,\n optimized\n );\n }\n };\n const mountToTarget = () => {\n const target = n2.target = resolveTarget(n2.props, querySelector);\n const targetAnchor = prepareAnchor(target, n2, createText, insert);\n if (target) {\n if (namespace !== \"svg\" && isTargetSVG(target)) {\n namespace = \"svg\";\n } else if (namespace !== \"mathml\" && isTargetMathML(target)) {\n namespace = \"mathml\";\n }\n if (parentComponent && parentComponent.isCE) {\n (parentComponent.ce._teleportTargets || (parentComponent.ce._teleportTargets = /* @__PURE__ */ new Set())).add(target);\n }\n if (!disabled) {\n mount(target, targetAnchor);\n updateCssVars(n2, false);\n }\n } else if (!!(process.env.NODE_ENV !== \"production\") && !disabled) {\n warn$1(\n \"Invalid Teleport target on mount:\",\n target,\n `(${typeof target})`\n );\n }\n };\n if (disabled) {\n mount(container, mainAnchor);\n updateCssVars(n2, true);\n }\n if (isTeleportDeferred(n2.props)) {\n n2.el.__isMounted = false;\n queuePostRenderEffect(() => {\n mountToTarget();\n delete n2.el.__isMounted;\n }, parentSuspense);\n } else {\n mountToTarget();\n }\n } else {\n if (isTeleportDeferred(n2.props) && n1.el.__isMounted === false) {\n queuePostRenderEffect(() => {\n TeleportImpl.process(\n n1,\n n2,\n container,\n anchor,\n parentComponent,\n parentSuspense,\n namespace,\n slotScopeIds,\n optimized,\n internals\n );\n }, parentSuspense);\n return;\n }\n n2.el = n1.el;\n n2.targetStart = n1.targetStart;\n const mainAnchor = n2.anchor = n1.anchor;\n const target = n2.target = n1.target;\n const targetAnchor = n2.targetAnchor = n1.targetAnchor;\n const wasDisabled = isTeleportDisabled(n1.props);\n const currentContainer = wasDisabled ? container : target;\n const currentAnchor = wasDisabled ? mainAnchor : targetAnchor;\n if (namespace === \"svg\" || isTargetSVG(target)) {\n namespace = \"svg\";\n } else if (namespace === \"mathml\" || isTargetMathML(target)) {\n namespace = \"mathml\";\n }\n if (dynamicChildren) {\n patchBlockChildren(\n n1.dynamicChildren,\n dynamicChildren,\n currentContainer,\n parentComponent,\n parentSuspense,\n namespace,\n slotScopeIds\n );\n traverseStaticChildren(n1, n2, !!!(process.env.NODE_ENV !== \"production\"));\n } else if (!optimized) {\n patchChildren(\n n1,\n n2,\n currentContainer,\n currentAnchor,\n parentComponent,\n parentSuspense,\n namespace,\n slotScopeIds,\n false\n );\n }\n if (disabled) {\n if (!wasDisabled) {\n moveTeleport(\n n2,\n container,\n mainAnchor,\n internals,\n 1\n );\n } else {\n if (n2.props && n1.props && n2.props.to !== n1.props.to) {\n n2.props.to = n1.props.to;\n }\n }\n } else {\n if ((n2.props && n2.props.to) !== (n1.props && n1.props.to)) {\n const nextTarget = n2.target = resolveTarget(\n n2.props,\n querySelector\n );\n if (nextTarget) {\n moveTeleport(\n n2,\n nextTarget,\n null,\n internals,\n 0\n );\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\n \"Invalid Teleport target on update:\",\n target,\n `(${typeof target})`\n );\n }\n } else if (wasDisabled) {\n moveTeleport(\n n2,\n target,\n targetAnchor,\n internals,\n 1\n );\n }\n }\n updateCssVars(n2, disabled);\n }\n },\n remove(vnode, parentComponent, parentSuspense, { um: unmount, o: { remove: hostRemove } }, doRemove) {\n const {\n shapeFlag,\n children,\n anchor,\n targetStart,\n targetAnchor,\n target,\n props\n } = vnode;\n if (target) {\n hostRemove(targetStart);\n hostRemove(targetAnchor);\n }\n doRemove && hostRemove(anchor);\n if (shapeFlag & 16) {\n const shouldRemove = doRemove || !isTeleportDisabled(props);\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n unmount(\n child,\n parentComponent,\n parentSuspense,\n shouldRemove,\n !!child.dynamicChildren\n );\n }\n }\n },\n move: moveTeleport,\n hydrate: hydrateTeleport\n};\nfunction moveTeleport(vnode, container, parentAnchor, { o: { insert }, m: move }, moveType = 2) {\n if (moveType === 0) {\n insert(vnode.targetAnchor, container, parentAnchor);\n }\n const { el, anchor, shapeFlag, children, props } = vnode;\n const isReorder = moveType === 2;\n if (isReorder) {\n insert(el, container, parentAnchor);\n }\n if (!isReorder || isTeleportDisabled(props)) {\n if (shapeFlag & 16) {\n for (let i = 0; i < children.length; i++) {\n move(\n children[i],\n container,\n parentAnchor,\n 2\n );\n }\n }\n }\n if (isReorder) {\n insert(anchor, container, parentAnchor);\n }\n}\nfunction hydrateTeleport(node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized, {\n o: { nextSibling, parentNode, querySelector, insert, createText }\n}, hydrateChildren) {\n function hydrateDisabledTeleport(node2, vnode2, targetStart, targetAnchor) {\n vnode2.anchor = hydrateChildren(\n nextSibling(node2),\n vnode2,\n parentNode(node2),\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized\n );\n vnode2.targetStart = targetStart;\n vnode2.targetAnchor = targetAnchor;\n }\n const target = vnode.target = resolveTarget(\n vnode.props,\n querySelector\n );\n const disabled = isTeleportDisabled(vnode.props);\n if (target) {\n const targetNode = target._lpa || target.firstChild;\n if (vnode.shapeFlag & 16) {\n if (disabled) {\n hydrateDisabledTeleport(\n node,\n vnode,\n targetNode,\n targetNode && nextSibling(targetNode)\n );\n } else {\n vnode.anchor = nextSibling(node);\n let targetAnchor = targetNode;\n while (targetAnchor) {\n if (targetAnchor && targetAnchor.nodeType === 8) {\n if (targetAnchor.data === \"teleport start anchor\") {\n vnode.targetStart = targetAnchor;\n } else if (targetAnchor.data === \"teleport anchor\") {\n vnode.targetAnchor = targetAnchor;\n target._lpa = vnode.targetAnchor && nextSibling(vnode.targetAnchor);\n break;\n }\n }\n targetAnchor = nextSibling(targetAnchor);\n }\n if (!vnode.targetAnchor) {\n prepareAnchor(target, vnode, createText, insert);\n }\n hydrateChildren(\n targetNode && nextSibling(targetNode),\n vnode,\n target,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized\n );\n }\n }\n updateCssVars(vnode, disabled);\n } else if (disabled) {\n if (vnode.shapeFlag & 16) {\n hydrateDisabledTeleport(node, vnode, node, nextSibling(node));\n }\n }\n return vnode.anchor && nextSibling(vnode.anchor);\n}\nconst Teleport = TeleportImpl;\nfunction updateCssVars(vnode, isDisabled) {\n const ctx = vnode.ctx;\n if (ctx && ctx.ut) {\n let node, anchor;\n if (isDisabled) {\n node = vnode.el;\n anchor = vnode.anchor;\n } else {\n node = vnode.targetStart;\n anchor = vnode.targetAnchor;\n }\n while (node && node !== anchor) {\n if (node.nodeType === 1) node.setAttribute(\"data-v-owner\", ctx.uid);\n node = node.nextSibling;\n }\n ctx.ut();\n }\n}\nfunction prepareAnchor(target, vnode, createText, insert) {\n const targetStart = vnode.targetStart = createText(\"\");\n const targetAnchor = vnode.targetAnchor = createText(\"\");\n targetStart[TeleportEndKey] = targetAnchor;\n if (target) {\n insert(targetStart, target);\n insert(targetAnchor, target);\n }\n return targetAnchor;\n}\n\nconst leaveCbKey = Symbol(\"_leaveCb\");\nconst enterCbKey = Symbol(\"_enterCb\");\nfunction useTransitionState() {\n const state = {\n isMounted: false,\n isLeaving: false,\n isUnmounting: false,\n leavingVNodes: /* @__PURE__ */ new Map()\n };\n onMounted(() => {\n state.isMounted = true;\n });\n onBeforeUnmount(() => {\n state.isUnmounting = true;\n });\n return state;\n}\nconst TransitionHookValidator = [Function, Array];\nconst BaseTransitionPropsValidators = {\n mode: String,\n appear: Boolean,\n persisted: Boolean,\n // enter\n onBeforeEnter: TransitionHookValidator,\n onEnter: TransitionHookValidator,\n onAfterEnter: TransitionHookValidator,\n onEnterCancelled: TransitionHookValidator,\n // leave\n onBeforeLeave: TransitionHookValidator,\n onLeave: TransitionHookValidator,\n onAfterLeave: TransitionHookValidator,\n onLeaveCancelled: TransitionHookValidator,\n // appear\n onBeforeAppear: TransitionHookValidator,\n onAppear: TransitionHookValidator,\n onAfterAppear: TransitionHookValidator,\n onAppearCancelled: TransitionHookValidator\n};\nconst recursiveGetSubtree = (instance) => {\n const subTree = instance.subTree;\n return subTree.component ? recursiveGetSubtree(subTree.component) : subTree;\n};\nconst BaseTransitionImpl = {\n name: `BaseTransition`,\n props: BaseTransitionPropsValidators,\n setup(props, { slots }) {\n const instance = getCurrentInstance();\n const state = useTransitionState();\n return () => {\n const children = slots.default && getTransitionRawChildren(slots.default(), true);\n if (!children || !children.length) {\n return;\n }\n const child = findNonCommentChild(children);\n const rawProps = toRaw(props);\n const { mode } = rawProps;\n if (!!(process.env.NODE_ENV !== \"production\") && mode && mode !== \"in-out\" && mode !== \"out-in\" && mode !== \"default\") {\n warn$1(`invalid mode: ${mode}`);\n }\n if (state.isLeaving) {\n return emptyPlaceholder(child);\n }\n const innerChild = getInnerChild$1(child);\n if (!innerChild) {\n return emptyPlaceholder(child);\n }\n let enterHooks = resolveTransitionHooks(\n innerChild,\n rawProps,\n state,\n instance,\n // #11061, ensure enterHooks is fresh after clone\n (hooks) => enterHooks = hooks\n );\n if (innerChild.type !== Comment) {\n setTransitionHooks(innerChild, enterHooks);\n }\n let oldInnerChild = instance.subTree && getInnerChild$1(instance.subTree);\n if (oldInnerChild && oldInnerChild.type !== Comment && !isSameVNodeType(oldInnerChild, innerChild) && recursiveGetSubtree(instance).type !== Comment) {\n let leavingHooks = resolveTransitionHooks(\n oldInnerChild,\n rawProps,\n state,\n instance\n );\n setTransitionHooks(oldInnerChild, leavingHooks);\n if (mode === \"out-in\" && innerChild.type !== Comment) {\n state.isLeaving = true;\n leavingHooks.afterLeave = () => {\n state.isLeaving = false;\n if (!(instance.job.flags & 8)) {\n instance.update();\n }\n delete leavingHooks.afterLeave;\n oldInnerChild = void 0;\n };\n return emptyPlaceholder(child);\n } else if (mode === \"in-out\" && innerChild.type !== Comment) {\n leavingHooks.delayLeave = (el, earlyRemove, delayedLeave) => {\n const leavingVNodesCache = getLeavingNodesForType(\n state,\n oldInnerChild\n );\n leavingVNodesCache[String(oldInnerChild.key)] = oldInnerChild;\n el[leaveCbKey] = () => {\n earlyRemove();\n el[leaveCbKey] = void 0;\n delete enterHooks.delayedLeave;\n oldInnerChild = void 0;\n };\n enterHooks.delayedLeave = () => {\n delayedLeave();\n delete enterHooks.delayedLeave;\n oldInnerChild = void 0;\n };\n };\n } else {\n oldInnerChild = void 0;\n }\n } else if (oldInnerChild) {\n oldInnerChild = void 0;\n }\n return child;\n };\n }\n};\nfunction findNonCommentChild(children) {\n let child = children[0];\n if (children.length > 1) {\n let hasFound = false;\n for (const c of children) {\n if (c.type !== Comment) {\n if (!!(process.env.NODE_ENV !== \"production\") && hasFound) {\n warn$1(\n \" can only be used on a single element or component. Use for lists.\"\n );\n break;\n }\n child = c;\n hasFound = true;\n if (!!!(process.env.NODE_ENV !== \"production\")) break;\n }\n }\n }\n return child;\n}\nconst BaseTransition = BaseTransitionImpl;\nfunction getLeavingNodesForType(state, vnode) {\n const { leavingVNodes } = state;\n let leavingVNodesCache = leavingVNodes.get(vnode.type);\n if (!leavingVNodesCache) {\n leavingVNodesCache = /* @__PURE__ */ Object.create(null);\n leavingVNodes.set(vnode.type, leavingVNodesCache);\n }\n return leavingVNodesCache;\n}\nfunction resolveTransitionHooks(vnode, props, state, instance, postClone) {\n const {\n appear,\n mode,\n persisted = false,\n onBeforeEnter,\n onEnter,\n onAfterEnter,\n onEnterCancelled,\n onBeforeLeave,\n onLeave,\n onAfterLeave,\n onLeaveCancelled,\n onBeforeAppear,\n onAppear,\n onAfterAppear,\n onAppearCancelled\n } = props;\n const key = String(vnode.key);\n const leavingVNodesCache = getLeavingNodesForType(state, vnode);\n const callHook = (hook, args) => {\n hook && callWithAsyncErrorHandling(\n hook,\n instance,\n 9,\n args\n );\n };\n const callAsyncHook = (hook, args) => {\n const done = args[1];\n callHook(hook, args);\n if (isArray(hook)) {\n if (hook.every((hook2) => hook2.length <= 1)) done();\n } else if (hook.length <= 1) {\n done();\n }\n };\n const hooks = {\n mode,\n persisted,\n beforeEnter(el) {\n let hook = onBeforeEnter;\n if (!state.isMounted) {\n if (appear) {\n hook = onBeforeAppear || onBeforeEnter;\n } else {\n return;\n }\n }\n if (el[leaveCbKey]) {\n el[leaveCbKey](\n true\n /* cancelled */\n );\n }\n const leavingVNode = leavingVNodesCache[key];\n if (leavingVNode && isSameVNodeType(vnode, leavingVNode) && leavingVNode.el[leaveCbKey]) {\n leavingVNode.el[leaveCbKey]();\n }\n callHook(hook, [el]);\n },\n enter(el) {\n let hook = onEnter;\n let afterHook = onAfterEnter;\n let cancelHook = onEnterCancelled;\n if (!state.isMounted) {\n if (appear) {\n hook = onAppear || onEnter;\n afterHook = onAfterAppear || onAfterEnter;\n cancelHook = onAppearCancelled || onEnterCancelled;\n } else {\n return;\n }\n }\n let called = false;\n const done = el[enterCbKey] = (cancelled) => {\n if (called) return;\n called = true;\n if (cancelled) {\n callHook(cancelHook, [el]);\n } else {\n callHook(afterHook, [el]);\n }\n if (hooks.delayedLeave) {\n hooks.delayedLeave();\n }\n el[enterCbKey] = void 0;\n };\n if (hook) {\n callAsyncHook(hook, [el, done]);\n } else {\n done();\n }\n },\n leave(el, remove) {\n const key2 = String(vnode.key);\n if (el[enterCbKey]) {\n el[enterCbKey](\n true\n /* cancelled */\n );\n }\n if (state.isUnmounting) {\n return remove();\n }\n callHook(onBeforeLeave, [el]);\n let called = false;\n const done = el[leaveCbKey] = (cancelled) => {\n if (called) return;\n called = true;\n remove();\n if (cancelled) {\n callHook(onLeaveCancelled, [el]);\n } else {\n callHook(onAfterLeave, [el]);\n }\n el[leaveCbKey] = void 0;\n if (leavingVNodesCache[key2] === vnode) {\n delete leavingVNodesCache[key2];\n }\n };\n leavingVNodesCache[key2] = vnode;\n if (onLeave) {\n callAsyncHook(onLeave, [el, done]);\n } else {\n done();\n }\n },\n clone(vnode2) {\n const hooks2 = resolveTransitionHooks(\n vnode2,\n props,\n state,\n instance,\n postClone\n );\n if (postClone) postClone(hooks2);\n return hooks2;\n }\n };\n return hooks;\n}\nfunction emptyPlaceholder(vnode) {\n if (isKeepAlive(vnode)) {\n vnode = cloneVNode(vnode);\n vnode.children = null;\n return vnode;\n }\n}\nfunction getInnerChild$1(vnode) {\n if (!isKeepAlive(vnode)) {\n if (isTeleport(vnode.type) && vnode.children) {\n return findNonCommentChild(vnode.children);\n }\n return vnode;\n }\n if (vnode.component) {\n return vnode.component.subTree;\n }\n const { shapeFlag, children } = vnode;\n if (children) {\n if (shapeFlag & 16) {\n return children[0];\n }\n if (shapeFlag & 32 && isFunction(children.default)) {\n return children.default();\n }\n }\n}\nfunction setTransitionHooks(vnode, hooks) {\n if (vnode.shapeFlag & 6 && vnode.component) {\n vnode.transition = hooks;\n setTransitionHooks(vnode.component.subTree, hooks);\n } else if (vnode.shapeFlag & 128) {\n vnode.ssContent.transition = hooks.clone(vnode.ssContent);\n vnode.ssFallback.transition = hooks.clone(vnode.ssFallback);\n } else {\n vnode.transition = hooks;\n }\n}\nfunction getTransitionRawChildren(children, keepComment = false, parentKey) {\n let ret = [];\n let keyedFragmentCount = 0;\n for (let i = 0; i < children.length; i++) {\n let child = children[i];\n const key = parentKey == null ? child.key : String(parentKey) + String(child.key != null ? child.key : i);\n if (child.type === Fragment) {\n if (child.patchFlag & 128) keyedFragmentCount++;\n ret = ret.concat(\n getTransitionRawChildren(child.children, keepComment, key)\n );\n } else if (keepComment || child.type !== Comment) {\n ret.push(key != null ? cloneVNode(child, { key }) : child);\n }\n }\n if (keyedFragmentCount > 1) {\n for (let i = 0; i < ret.length; i++) {\n ret[i].patchFlag = -2;\n }\n }\n return ret;\n}\n\n// @__NO_SIDE_EFFECTS__\nfunction defineComponent(options, extraOptions) {\n return isFunction(options) ? (\n // #8236: extend call and options.name access are considered side-effects\n // by Rollup, so we have to wrap it in a pure-annotated IIFE.\n /* @__PURE__ */ (() => extend({ name: options.name }, extraOptions, { setup: options }))()\n ) : options;\n}\n\nfunction useId() {\n const i = getCurrentInstance();\n if (i) {\n return (i.appContext.config.idPrefix || \"v\") + \"-\" + i.ids[0] + i.ids[1]++;\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\n `useId() is called when there is no active component instance to be associated with.`\n );\n }\n return \"\";\n}\nfunction markAsyncBoundary(instance) {\n instance.ids = [instance.ids[0] + instance.ids[2]++ + \"-\", 0, 0];\n}\n\nconst knownTemplateRefs = /* @__PURE__ */ new WeakSet();\nfunction useTemplateRef(key) {\n const i = getCurrentInstance();\n const r = shallowRef(null);\n if (i) {\n const refs = i.refs === EMPTY_OBJ ? i.refs = {} : i.refs;\n let desc;\n if (!!(process.env.NODE_ENV !== \"production\") && (desc = Object.getOwnPropertyDescriptor(refs, key)) && !desc.configurable) {\n warn$1(`useTemplateRef('${key}') already exists.`);\n } else {\n Object.defineProperty(refs, key, {\n enumerable: true,\n get: () => r.value,\n set: (val) => r.value = val\n });\n }\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\n `useTemplateRef() is called when there is no active component instance to be associated with.`\n );\n }\n const ret = !!(process.env.NODE_ENV !== \"production\") ? readonly(r) : r;\n if (!!(process.env.NODE_ENV !== \"production\")) {\n knownTemplateRefs.add(ret);\n }\n return ret;\n}\n\nconst pendingSetRefMap = /* @__PURE__ */ new WeakMap();\nfunction setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {\n if (isArray(rawRef)) {\n rawRef.forEach(\n (r, i) => setRef(\n r,\n oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef),\n parentSuspense,\n vnode,\n isUnmount\n )\n );\n return;\n }\n if (isAsyncWrapper(vnode) && !isUnmount) {\n if (vnode.shapeFlag & 512 && vnode.type.__asyncResolved && vnode.component.subTree.component) {\n setRef(rawRef, oldRawRef, parentSuspense, vnode.component.subTree);\n }\n return;\n }\n const refValue = vnode.shapeFlag & 4 ? getComponentPublicInstance(vnode.component) : vnode.el;\n const value = isUnmount ? null : refValue;\n const { i: owner, r: ref } = rawRef;\n if (!!(process.env.NODE_ENV !== \"production\") && !owner) {\n warn$1(\n `Missing ref owner context. ref cannot be used on hoisted vnodes. A vnode with ref must be created inside the render function.`\n );\n return;\n }\n const oldRef = oldRawRef && oldRawRef.r;\n const refs = owner.refs === EMPTY_OBJ ? owner.refs = {} : owner.refs;\n const setupState = owner.setupState;\n const rawSetupState = toRaw(setupState);\n const canSetSetupRef = setupState === EMPTY_OBJ ? NO : (key) => {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n if (hasOwn(rawSetupState, key) && !isRef(rawSetupState[key])) {\n warn$1(\n `Template ref \"${key}\" used on a non-ref value. It will not work in the production build.`\n );\n }\n if (knownTemplateRefs.has(rawSetupState[key])) {\n return false;\n }\n }\n return hasOwn(rawSetupState, key);\n };\n const canSetRef = (ref2) => {\n return !!!(process.env.NODE_ENV !== \"production\") || !knownTemplateRefs.has(ref2);\n };\n if (oldRef != null && oldRef !== ref) {\n invalidatePendingSetRef(oldRawRef);\n if (isString(oldRef)) {\n refs[oldRef] = null;\n if (canSetSetupRef(oldRef)) {\n setupState[oldRef] = null;\n }\n } else if (isRef(oldRef)) {\n if (canSetRef(oldRef)) {\n oldRef.value = null;\n }\n const oldRawRefAtom = oldRawRef;\n if (oldRawRefAtom.k) refs[oldRawRefAtom.k] = null;\n }\n }\n if (isFunction(ref)) {\n callWithErrorHandling(ref, owner, 12, [value, refs]);\n } else {\n const _isString = isString(ref);\n const _isRef = isRef(ref);\n if (_isString || _isRef) {\n const doSet = () => {\n if (rawRef.f) {\n const existing = _isString ? canSetSetupRef(ref) ? setupState[ref] : refs[ref] : canSetRef(ref) || !rawRef.k ? ref.value : refs[rawRef.k];\n if (isUnmount) {\n isArray(existing) && remove(existing, refValue);\n } else {\n if (!isArray(existing)) {\n if (_isString) {\n refs[ref] = [refValue];\n if (canSetSetupRef(ref)) {\n setupState[ref] = refs[ref];\n }\n } else {\n const newVal = [refValue];\n if (canSetRef(ref)) {\n ref.value = newVal;\n }\n if (rawRef.k) refs[rawRef.k] = newVal;\n }\n } else if (!existing.includes(refValue)) {\n existing.push(refValue);\n }\n }\n } else if (_isString) {\n refs[ref] = value;\n if (canSetSetupRef(ref)) {\n setupState[ref] = value;\n }\n } else if (_isRef) {\n if (canSetRef(ref)) {\n ref.value = value;\n }\n if (rawRef.k) refs[rawRef.k] = value;\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\"Invalid template ref type:\", ref, `(${typeof ref})`);\n }\n };\n if (value) {\n const job = () => {\n doSet();\n pendingSetRefMap.delete(rawRef);\n };\n job.id = -1;\n pendingSetRefMap.set(rawRef, job);\n queuePostRenderEffect(job, parentSuspense);\n } else {\n invalidatePendingSetRef(rawRef);\n doSet();\n }\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\"Invalid template ref type:\", ref, `(${typeof ref})`);\n }\n }\n}\nfunction invalidatePendingSetRef(rawRef) {\n const pendingSetRef = pendingSetRefMap.get(rawRef);\n if (pendingSetRef) {\n pendingSetRef.flags |= 8;\n pendingSetRefMap.delete(rawRef);\n }\n}\n\nlet hasLoggedMismatchError = false;\nconst logMismatchError = () => {\n if (hasLoggedMismatchError) {\n return;\n }\n console.error(\"Hydration completed but contains mismatches.\");\n hasLoggedMismatchError = true;\n};\nconst isSVGContainer = (container) => container.namespaceURI.includes(\"svg\") && container.tagName !== \"foreignObject\";\nconst isMathMLContainer = (container) => container.namespaceURI.includes(\"MathML\");\nconst getContainerType = (container) => {\n if (container.nodeType !== 1) return void 0;\n if (isSVGContainer(container)) return \"svg\";\n if (isMathMLContainer(container)) return \"mathml\";\n return void 0;\n};\nconst isComment = (node) => node.nodeType === 8;\nfunction createHydrationFunctions(rendererInternals) {\n const {\n mt: mountComponent,\n p: patch,\n o: {\n patchProp,\n createText,\n nextSibling,\n parentNode,\n remove,\n insert,\n createComment\n }\n } = rendererInternals;\n const hydrate = (vnode, container) => {\n if (!container.hasChildNodes()) {\n (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn$1(\n `Attempting to hydrate existing markup but container is empty. Performing full mount instead.`\n );\n patch(null, vnode, container);\n flushPostFlushCbs();\n container._vnode = vnode;\n return;\n }\n hydrateNode(container.firstChild, vnode, null, null, null);\n flushPostFlushCbs();\n container._vnode = vnode;\n };\n const hydrateNode = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized = false) => {\n optimized = optimized || !!vnode.dynamicChildren;\n const isFragmentStart = isComment(node) && node.data === \"[\";\n const onMismatch = () => handleMismatch(\n node,\n vnode,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n isFragmentStart\n );\n const { type, ref, shapeFlag, patchFlag } = vnode;\n let domType = node.nodeType;\n vnode.el = node;\n if (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_DEVTOOLS__) {\n def(node, \"__vnode\", vnode, true);\n def(node, \"__vueParentComponent\", parentComponent, true);\n }\n if (patchFlag === -2) {\n optimized = false;\n vnode.dynamicChildren = null;\n }\n let nextNode = null;\n switch (type) {\n case Text:\n if (domType !== 3) {\n if (vnode.children === \"\") {\n insert(vnode.el = createText(\"\"), parentNode(node), node);\n nextNode = node;\n } else {\n nextNode = onMismatch();\n }\n } else {\n if (node.data !== vnode.children) {\n (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn$1(\n `Hydration text mismatch in`,\n node.parentNode,\n `\n - rendered on server: ${JSON.stringify(\n node.data\n )}\n - expected on client: ${JSON.stringify(vnode.children)}`\n );\n logMismatchError();\n node.data = vnode.children;\n }\n nextNode = nextSibling(node);\n }\n break;\n case Comment:\n if (isTemplateNode(node)) {\n nextNode = nextSibling(node);\n replaceNode(\n vnode.el = node.content.firstChild,\n node,\n parentComponent\n );\n } else if (domType !== 8 || isFragmentStart) {\n nextNode = onMismatch();\n } else {\n nextNode = nextSibling(node);\n }\n break;\n case Static:\n if (isFragmentStart) {\n node = nextSibling(node);\n domType = node.nodeType;\n }\n if (domType === 1 || domType === 3) {\n nextNode = node;\n const needToAdoptContent = !vnode.children.length;\n for (let i = 0; i < vnode.staticCount; i++) {\n if (needToAdoptContent)\n vnode.children += nextNode.nodeType === 1 ? nextNode.outerHTML : nextNode.data;\n if (i === vnode.staticCount - 1) {\n vnode.anchor = nextNode;\n }\n nextNode = nextSibling(nextNode);\n }\n return isFragmentStart ? nextSibling(nextNode) : nextNode;\n } else {\n onMismatch();\n }\n break;\n case Fragment:\n if (!isFragmentStart) {\n nextNode = onMismatch();\n } else {\n nextNode = hydrateFragment(\n node,\n vnode,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized\n );\n }\n break;\n default:\n if (shapeFlag & 1) {\n if ((domType !== 1 || vnode.type.toLowerCase() !== node.tagName.toLowerCase()) && !isTemplateNode(node)) {\n nextNode = onMismatch();\n } else {\n nextNode = hydrateElement(\n node,\n vnode,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized\n );\n }\n } else if (shapeFlag & 6) {\n vnode.slotScopeIds = slotScopeIds;\n const container = parentNode(node);\n if (isFragmentStart) {\n nextNode = locateClosingAnchor(node);\n } else if (isComment(node) && node.data === \"teleport start\") {\n nextNode = locateClosingAnchor(node, node.data, \"teleport end\");\n } else {\n nextNode = nextSibling(node);\n }\n mountComponent(\n vnode,\n container,\n null,\n parentComponent,\n parentSuspense,\n getContainerType(container),\n optimized\n );\n if (isAsyncWrapper(vnode) && !vnode.type.__asyncResolved) {\n let subTree;\n if (isFragmentStart) {\n subTree = createVNode(Fragment);\n subTree.anchor = nextNode ? nextNode.previousSibling : container.lastChild;\n } else {\n subTree = node.nodeType === 3 ? createTextVNode(\"\") : createVNode(\"div\");\n }\n subTree.el = node;\n vnode.component.subTree = subTree;\n }\n } else if (shapeFlag & 64) {\n if (domType !== 8) {\n nextNode = onMismatch();\n } else {\n nextNode = vnode.type.hydrate(\n node,\n vnode,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized,\n rendererInternals,\n hydrateChildren\n );\n }\n } else if (shapeFlag & 128) {\n nextNode = vnode.type.hydrate(\n node,\n vnode,\n parentComponent,\n parentSuspense,\n getContainerType(parentNode(node)),\n slotScopeIds,\n optimized,\n rendererInternals,\n hydrateNode\n );\n } else if (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) {\n warn$1(\"Invalid HostVNode type:\", type, `(${typeof type})`);\n }\n }\n if (ref != null) {\n setRef(ref, null, parentSuspense, vnode);\n }\n return nextNode;\n };\n const hydrateElement = (el, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {\n optimized = optimized || !!vnode.dynamicChildren;\n const { type, props, patchFlag, shapeFlag, dirs, transition } = vnode;\n const forcePatch = type === \"input\" || type === \"option\";\n if (!!(process.env.NODE_ENV !== \"production\") || forcePatch || patchFlag !== -1) {\n if (dirs) {\n invokeDirectiveHook(vnode, null, parentComponent, \"created\");\n }\n let needCallTransitionHooks = false;\n if (isTemplateNode(el)) {\n needCallTransitionHooks = needTransition(\n null,\n // no need check parentSuspense in hydration\n transition\n ) && parentComponent && parentComponent.vnode.props && parentComponent.vnode.props.appear;\n const content = el.content.firstChild;\n if (needCallTransitionHooks) {\n const cls = content.getAttribute(\"class\");\n if (cls) content.$cls = cls;\n transition.beforeEnter(content);\n }\n replaceNode(content, el, parentComponent);\n vnode.el = el = content;\n }\n if (shapeFlag & 16 && // skip if element has innerHTML / textContent\n !(props && (props.innerHTML || props.textContent))) {\n let next = hydrateChildren(\n el.firstChild,\n vnode,\n el,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized\n );\n let hasWarned = false;\n while (next) {\n if (!isMismatchAllowed(el, 1 /* CHILDREN */)) {\n if ((!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && !hasWarned) {\n warn$1(\n `Hydration children mismatch on`,\n el,\n `\nServer rendered element contains more child nodes than client vdom.`\n );\n hasWarned = true;\n }\n logMismatchError();\n }\n const cur = next;\n next = next.nextSibling;\n remove(cur);\n }\n } else if (shapeFlag & 8) {\n let clientText = vnode.children;\n if (clientText[0] === \"\\n\" && (el.tagName === \"PRE\" || el.tagName === \"TEXTAREA\")) {\n clientText = clientText.slice(1);\n }\n if (el.textContent !== clientText) {\n if (!isMismatchAllowed(el, 0 /* TEXT */)) {\n (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn$1(\n `Hydration text content mismatch on`,\n el,\n `\n - rendered on server: ${el.textContent}\n - expected on client: ${vnode.children}`\n );\n logMismatchError();\n }\n el.textContent = vnode.children;\n }\n }\n if (props) {\n if (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ || forcePatch || !optimized || patchFlag & (16 | 32)) {\n const isCustomElement = el.tagName.includes(\"-\");\n for (const key in props) {\n if ((!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && // #11189 skip if this node has directives that have created hooks\n // as it could have mutated the DOM in any possible way\n !(dirs && dirs.some((d) => d.dir.created)) && propHasMismatch(el, key, props[key], vnode, parentComponent)) {\n logMismatchError();\n }\n if (forcePatch && (key.endsWith(\"value\") || key === \"indeterminate\") || isOn(key) && !isReservedProp(key) || // force hydrate v-bind with .prop modifiers\n key[0] === \".\" || isCustomElement) {\n patchProp(el, key, null, props[key], void 0, parentComponent);\n }\n }\n } else if (props.onClick) {\n patchProp(\n el,\n \"onClick\",\n null,\n props.onClick,\n void 0,\n parentComponent\n );\n } else if (patchFlag & 4 && isReactive(props.style)) {\n for (const key in props.style) props.style[key];\n }\n }\n let vnodeHooks;\n if (vnodeHooks = props && props.onVnodeBeforeMount) {\n invokeVNodeHook(vnodeHooks, parentComponent, vnode);\n }\n if (dirs) {\n invokeDirectiveHook(vnode, null, parentComponent, \"beforeMount\");\n }\n if ((vnodeHooks = props && props.onVnodeMounted) || dirs || needCallTransitionHooks) {\n queueEffectWithSuspense(() => {\n vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode);\n needCallTransitionHooks && transition.enter(el);\n dirs && invokeDirectiveHook(vnode, null, parentComponent, \"mounted\");\n }, parentSuspense);\n }\n }\n return el.nextSibling;\n };\n const hydrateChildren = (node, parentVNode, container, parentComponent, parentSuspense, slotScopeIds, optimized) => {\n optimized = optimized || !!parentVNode.dynamicChildren;\n const children = parentVNode.children;\n const l = children.length;\n let hasWarned = false;\n for (let i = 0; i < l; i++) {\n const vnode = optimized ? children[i] : children[i] = normalizeVNode(children[i]);\n const isText = vnode.type === Text;\n if (node) {\n if (isText && !optimized) {\n if (i + 1 < l && normalizeVNode(children[i + 1]).type === Text) {\n insert(\n createText(\n node.data.slice(vnode.children.length)\n ),\n container,\n nextSibling(node)\n );\n node.data = vnode.children;\n }\n }\n node = hydrateNode(\n node,\n vnode,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized\n );\n } else if (isText && !vnode.children) {\n insert(vnode.el = createText(\"\"), container);\n } else {\n if (!isMismatchAllowed(container, 1 /* CHILDREN */)) {\n if ((!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && !hasWarned) {\n warn$1(\n `Hydration children mismatch on`,\n container,\n `\nServer rendered element contains fewer child nodes than client vdom.`\n );\n hasWarned = true;\n }\n logMismatchError();\n }\n patch(\n null,\n vnode,\n container,\n null,\n parentComponent,\n parentSuspense,\n getContainerType(container),\n slotScopeIds\n );\n }\n }\n return node;\n };\n const hydrateFragment = (node, vnode, parentComponent, parentSuspense, slotScopeIds, optimized) => {\n const { slotScopeIds: fragmentSlotScopeIds } = vnode;\n if (fragmentSlotScopeIds) {\n slotScopeIds = slotScopeIds ? slotScopeIds.concat(fragmentSlotScopeIds) : fragmentSlotScopeIds;\n }\n const container = parentNode(node);\n const next = hydrateChildren(\n nextSibling(node),\n vnode,\n container,\n parentComponent,\n parentSuspense,\n slotScopeIds,\n optimized\n );\n if (next && isComment(next) && next.data === \"]\") {\n return nextSibling(vnode.anchor = next);\n } else {\n logMismatchError();\n insert(vnode.anchor = createComment(`]`), container, next);\n return next;\n }\n };\n const handleMismatch = (node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragment) => {\n if (!isMismatchAllowed(node.parentElement, 1 /* CHILDREN */)) {\n (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_HYDRATION_MISMATCH_DETAILS__) && warn$1(\n `Hydration node mismatch:\n- rendered on server:`,\n node,\n node.nodeType === 3 ? `(text)` : isComment(node) && node.data === \"[\" ? `(start of fragment)` : ``,\n `\n- expected on client:`,\n vnode.type\n );\n logMismatchError();\n }\n vnode.el = null;\n if (isFragment) {\n const end = locateClosingAnchor(node);\n while (true) {\n const next2 = nextSibling(node);\n if (next2 && next2 !== end) {\n remove(next2);\n } else {\n break;\n }\n }\n }\n const next = nextSibling(node);\n const container = parentNode(node);\n remove(node);\n patch(\n null,\n vnode,\n container,\n next,\n parentComponent,\n parentSuspense,\n getContainerType(container),\n slotScopeIds\n );\n if (parentComponent) {\n parentComponent.vnode.el = vnode.el;\n updateHOCHostEl(parentComponent, vnode.el);\n }\n return next;\n };\n const locateClosingAnchor = (node, open = \"[\", close = \"]\") => {\n let match = 0;\n while (node) {\n node = nextSibling(node);\n if (node && isComment(node)) {\n if (node.data === open) match++;\n if (node.data === close) {\n if (match === 0) {\n return nextSibling(node);\n } else {\n match--;\n }\n }\n }\n }\n return node;\n };\n const replaceNode = (newNode, oldNode, parentComponent) => {\n const parentNode2 = oldNode.parentNode;\n if (parentNode2) {\n parentNode2.replaceChild(newNode, oldNode);\n }\n let parent = parentComponent;\n while (parent) {\n if (parent.vnode.el === oldNode) {\n parent.vnode.el = parent.subTree.el = newNode;\n }\n parent = parent.parent;\n }\n };\n const isTemplateNode = (node) => {\n return node.nodeType === 1 && node.tagName === \"TEMPLATE\";\n };\n return [hydrate, hydrateNode];\n}\nfunction propHasMismatch(el, key, clientValue, vnode, instance) {\n let mismatchType;\n let mismatchKey;\n let actual;\n let expected;\n if (key === \"class\") {\n if (el.$cls) {\n actual = el.$cls;\n delete el.$cls;\n } else {\n actual = el.getAttribute(\"class\");\n }\n expected = normalizeClass(clientValue);\n if (!isSetEqual(toClassSet(actual || \"\"), toClassSet(expected))) {\n mismatchType = 2 /* CLASS */;\n mismatchKey = `class`;\n }\n } else if (key === \"style\") {\n actual = el.getAttribute(\"style\") || \"\";\n expected = isString(clientValue) ? clientValue : stringifyStyle(normalizeStyle(clientValue));\n const actualMap = toStyleMap(actual);\n const expectedMap = toStyleMap(expected);\n if (vnode.dirs) {\n for (const { dir, value } of vnode.dirs) {\n if (dir.name === \"show\" && !value) {\n expectedMap.set(\"display\", \"none\");\n }\n }\n }\n if (instance) {\n resolveCssVars(instance, vnode, expectedMap);\n }\n if (!isMapEqual(actualMap, expectedMap)) {\n mismatchType = 3 /* STYLE */;\n mismatchKey = \"style\";\n }\n } else if (el instanceof SVGElement && isKnownSvgAttr(key) || el instanceof HTMLElement && (isBooleanAttr(key) || isKnownHtmlAttr(key))) {\n if (isBooleanAttr(key)) {\n actual = el.hasAttribute(key);\n expected = includeBooleanAttr(clientValue);\n } else if (clientValue == null) {\n actual = el.hasAttribute(key);\n expected = false;\n } else {\n if (el.hasAttribute(key)) {\n actual = el.getAttribute(key);\n } else if (key === \"value\" && el.tagName === \"TEXTAREA\") {\n actual = el.value;\n } else {\n actual = false;\n }\n expected = isRenderableAttrValue(clientValue) ? String(clientValue) : false;\n }\n if (actual !== expected) {\n mismatchType = 4 /* ATTRIBUTE */;\n mismatchKey = key;\n }\n }\n if (mismatchType != null && !isMismatchAllowed(el, mismatchType)) {\n const format = (v) => v === false ? `(not rendered)` : `${mismatchKey}=\"${v}\"`;\n const preSegment = `Hydration ${MismatchTypeString[mismatchType]} mismatch on`;\n const postSegment = `\n - rendered on server: ${format(actual)}\n - expected on client: ${format(expected)}\n Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead.\n You should fix the source of the mismatch.`;\n {\n warn$1(preSegment, el, postSegment);\n }\n return true;\n }\n return false;\n}\nfunction toClassSet(str) {\n return new Set(str.trim().split(/\\s+/));\n}\nfunction isSetEqual(a, b) {\n if (a.size !== b.size) {\n return false;\n }\n for (const s of a) {\n if (!b.has(s)) {\n return false;\n }\n }\n return true;\n}\nfunction toStyleMap(str) {\n const styleMap = /* @__PURE__ */ new Map();\n for (const item of str.split(\";\")) {\n let [key, value] = item.split(\":\");\n key = key.trim();\n value = value && value.trim();\n if (key && value) {\n styleMap.set(key, value);\n }\n }\n return styleMap;\n}\nfunction isMapEqual(a, b) {\n if (a.size !== b.size) {\n return false;\n }\n for (const [key, value] of a) {\n if (value !== b.get(key)) {\n return false;\n }\n }\n return true;\n}\nfunction resolveCssVars(instance, vnode, expectedMap) {\n const root = instance.subTree;\n if (instance.getCssVars && (vnode === root || root && root.type === Fragment && root.children.includes(vnode))) {\n const cssVars = instance.getCssVars();\n for (const key in cssVars) {\n const value = normalizeCssVarValue(cssVars[key]);\n expectedMap.set(`--${getEscapedCssVarName(key, false)}`, value);\n }\n }\n if (vnode === root && instance.parent) {\n resolveCssVars(instance.parent, instance.vnode, expectedMap);\n }\n}\nconst allowMismatchAttr = \"data-allow-mismatch\";\nconst MismatchTypeString = {\n [0 /* TEXT */]: \"text\",\n [1 /* CHILDREN */]: \"children\",\n [2 /* CLASS */]: \"class\",\n [3 /* STYLE */]: \"style\",\n [4 /* ATTRIBUTE */]: \"attribute\"\n};\nfunction isMismatchAllowed(el, allowedType) {\n if (allowedType === 0 /* TEXT */ || allowedType === 1 /* CHILDREN */) {\n while (el && !el.hasAttribute(allowMismatchAttr)) {\n el = el.parentElement;\n }\n }\n const allowedAttr = el && el.getAttribute(allowMismatchAttr);\n if (allowedAttr == null) {\n return false;\n } else if (allowedAttr === \"\") {\n return true;\n } else {\n const list = allowedAttr.split(\",\");\n if (allowedType === 0 /* TEXT */ && list.includes(\"children\")) {\n return true;\n }\n return list.includes(MismatchTypeString[allowedType]);\n }\n}\n\nconst requestIdleCallback = getGlobalThis().requestIdleCallback || ((cb) => setTimeout(cb, 1));\nconst cancelIdleCallback = getGlobalThis().cancelIdleCallback || ((id) => clearTimeout(id));\nconst hydrateOnIdle = (timeout = 1e4) => (hydrate) => {\n const id = requestIdleCallback(hydrate, { timeout });\n return () => cancelIdleCallback(id);\n};\nfunction elementIsVisibleInViewport(el) {\n const { top, left, bottom, right } = el.getBoundingClientRect();\n const { innerHeight, innerWidth } = window;\n return (top > 0 && top < innerHeight || bottom > 0 && bottom < innerHeight) && (left > 0 && left < innerWidth || right > 0 && right < innerWidth);\n}\nconst hydrateOnVisible = (opts) => (hydrate, forEach) => {\n const ob = new IntersectionObserver((entries) => {\n for (const e of entries) {\n if (!e.isIntersecting) continue;\n ob.disconnect();\n hydrate();\n break;\n }\n }, opts);\n forEach((el) => {\n if (!(el instanceof Element)) return;\n if (elementIsVisibleInViewport(el)) {\n hydrate();\n ob.disconnect();\n return false;\n }\n ob.observe(el);\n });\n return () => ob.disconnect();\n};\nconst hydrateOnMediaQuery = (query) => (hydrate) => {\n if (query) {\n const mql = matchMedia(query);\n if (mql.matches) {\n hydrate();\n } else {\n mql.addEventListener(\"change\", hydrate, { once: true });\n return () => mql.removeEventListener(\"change\", hydrate);\n }\n }\n};\nconst hydrateOnInteraction = (interactions = []) => (hydrate, forEach) => {\n if (isString(interactions)) interactions = [interactions];\n let hasHydrated = false;\n const doHydrate = (e) => {\n if (!hasHydrated) {\n hasHydrated = true;\n teardown();\n hydrate();\n e.target.dispatchEvent(new e.constructor(e.type, e));\n }\n };\n const teardown = () => {\n forEach((el) => {\n for (const i of interactions) {\n el.removeEventListener(i, doHydrate);\n }\n });\n };\n forEach((el) => {\n for (const i of interactions) {\n el.addEventListener(i, doHydrate, { once: true });\n }\n });\n return teardown;\n};\nfunction forEachElement(node, cb) {\n if (isComment(node) && node.data === \"[\") {\n let depth = 1;\n let next = node.nextSibling;\n while (next) {\n if (next.nodeType === 1) {\n const result = cb(next);\n if (result === false) {\n break;\n }\n } else if (isComment(next)) {\n if (next.data === \"]\") {\n if (--depth === 0) break;\n } else if (next.data === \"[\") {\n depth++;\n }\n }\n next = next.nextSibling;\n }\n } else {\n cb(node);\n }\n}\n\nconst isAsyncWrapper = (i) => !!i.type.__asyncLoader;\n// @__NO_SIDE_EFFECTS__\nfunction defineAsyncComponent(source) {\n if (isFunction(source)) {\n source = { loader: source };\n }\n const {\n loader,\n loadingComponent,\n errorComponent,\n delay = 200,\n hydrate: hydrateStrategy,\n timeout,\n // undefined = never times out\n suspensible = true,\n onError: userOnError\n } = source;\n let pendingRequest = null;\n let resolvedComp;\n let retries = 0;\n const retry = () => {\n retries++;\n pendingRequest = null;\n return load();\n };\n const load = () => {\n let thisRequest;\n return pendingRequest || (thisRequest = pendingRequest = loader().catch((err) => {\n err = err instanceof Error ? err : new Error(String(err));\n if (userOnError) {\n return new Promise((resolve, reject) => {\n const userRetry = () => resolve(retry());\n const userFail = () => reject(err);\n userOnError(err, userRetry, userFail, retries + 1);\n });\n } else {\n throw err;\n }\n }).then((comp) => {\n if (thisRequest !== pendingRequest && pendingRequest) {\n return pendingRequest;\n }\n if (!!(process.env.NODE_ENV !== \"production\") && !comp) {\n warn$1(\n `Async component loader resolved to undefined. If you are using retry(), make sure to return its return value.`\n );\n }\n if (comp && (comp.__esModule || comp[Symbol.toStringTag] === \"Module\")) {\n comp = comp.default;\n }\n if (!!(process.env.NODE_ENV !== \"production\") && comp && !isObject(comp) && !isFunction(comp)) {\n throw new Error(`Invalid async component load result: ${comp}`);\n }\n resolvedComp = comp;\n return comp;\n }));\n };\n return defineComponent({\n name: \"AsyncComponentWrapper\",\n __asyncLoader: load,\n __asyncHydrate(el, instance, hydrate) {\n let patched = false;\n (instance.bu || (instance.bu = [])).push(() => patched = true);\n const performHydrate = () => {\n if (patched) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\n `Skipping lazy hydration for component '${getComponentName(resolvedComp) || resolvedComp.__file}': it was updated before lazy hydration performed.`\n );\n }\n return;\n }\n hydrate();\n };\n const doHydrate = hydrateStrategy ? () => {\n const teardown = hydrateStrategy(\n performHydrate,\n (cb) => forEachElement(el, cb)\n );\n if (teardown) {\n (instance.bum || (instance.bum = [])).push(teardown);\n }\n } : performHydrate;\n if (resolvedComp) {\n doHydrate();\n } else {\n load().then(() => !instance.isUnmounted && doHydrate());\n }\n },\n get __asyncResolved() {\n return resolvedComp;\n },\n setup() {\n const instance = currentInstance;\n markAsyncBoundary(instance);\n if (resolvedComp) {\n return () => createInnerComp(resolvedComp, instance);\n }\n const onError = (err) => {\n pendingRequest = null;\n handleError(\n err,\n instance,\n 13,\n !errorComponent\n );\n };\n if (suspensible && instance.suspense || isInSSRComponentSetup) {\n return load().then((comp) => {\n return () => createInnerComp(comp, instance);\n }).catch((err) => {\n onError(err);\n return () => errorComponent ? createVNode(errorComponent, {\n error: err\n }) : null;\n });\n }\n const loaded = ref(false);\n const error = ref();\n const delayed = ref(!!delay);\n if (delay) {\n setTimeout(() => {\n delayed.value = false;\n }, delay);\n }\n if (timeout != null) {\n setTimeout(() => {\n if (!loaded.value && !error.value) {\n const err = new Error(\n `Async component timed out after ${timeout}ms.`\n );\n onError(err);\n error.value = err;\n }\n }, timeout);\n }\n load().then(() => {\n loaded.value = true;\n if (instance.parent && isKeepAlive(instance.parent.vnode)) {\n instance.parent.update();\n }\n }).catch((err) => {\n onError(err);\n error.value = err;\n });\n return () => {\n if (loaded.value && resolvedComp) {\n return createInnerComp(resolvedComp, instance);\n } else if (error.value && errorComponent) {\n return createVNode(errorComponent, {\n error: error.value\n });\n } else if (loadingComponent && !delayed.value) {\n return createVNode(loadingComponent);\n }\n };\n }\n });\n}\nfunction createInnerComp(comp, parent) {\n const { ref: ref2, props, children, ce } = parent.vnode;\n const vnode = createVNode(comp, props, children);\n vnode.ref = ref2;\n vnode.ce = ce;\n delete parent.vnode.ce;\n return vnode;\n}\n\nconst isKeepAlive = (vnode) => vnode.type.__isKeepAlive;\nconst KeepAliveImpl = {\n name: `KeepAlive`,\n // Marker for special handling inside the renderer. We are not using a ===\n // check directly on KeepAlive in the renderer, because importing it directly\n // would prevent it from being tree-shaken.\n __isKeepAlive: true,\n props: {\n include: [String, RegExp, Array],\n exclude: [String, RegExp, Array],\n max: [String, Number]\n },\n setup(props, { slots }) {\n const instance = getCurrentInstance();\n const sharedContext = instance.ctx;\n if (!sharedContext.renderer) {\n return () => {\n const children = slots.default && slots.default();\n return children && children.length === 1 ? children[0] : children;\n };\n }\n const cache = /* @__PURE__ */ new Map();\n const keys = /* @__PURE__ */ new Set();\n let current = null;\n if (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_DEVTOOLS__) {\n instance.__v_cache = cache;\n }\n const parentSuspense = instance.suspense;\n const {\n renderer: {\n p: patch,\n m: move,\n um: _unmount,\n o: { createElement }\n }\n } = sharedContext;\n const storageContainer = createElement(\"div\");\n sharedContext.activate = (vnode, container, anchor, namespace, optimized) => {\n const instance2 = vnode.component;\n move(vnode, container, anchor, 0, parentSuspense);\n patch(\n instance2.vnode,\n vnode,\n container,\n anchor,\n instance2,\n parentSuspense,\n namespace,\n vnode.slotScopeIds,\n optimized\n );\n queuePostRenderEffect(() => {\n instance2.isDeactivated = false;\n if (instance2.a) {\n invokeArrayFns(instance2.a);\n }\n const vnodeHook = vnode.props && vnode.props.onVnodeMounted;\n if (vnodeHook) {\n invokeVNodeHook(vnodeHook, instance2.parent, vnode);\n }\n }, parentSuspense);\n if (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_DEVTOOLS__) {\n devtoolsComponentAdded(instance2);\n }\n };\n sharedContext.deactivate = (vnode) => {\n const instance2 = vnode.component;\n invalidateMount(instance2.m);\n invalidateMount(instance2.a);\n move(vnode, storageContainer, null, 1, parentSuspense);\n queuePostRenderEffect(() => {\n if (instance2.da) {\n invokeArrayFns(instance2.da);\n }\n const vnodeHook = vnode.props && vnode.props.onVnodeUnmounted;\n if (vnodeHook) {\n invokeVNodeHook(vnodeHook, instance2.parent, vnode);\n }\n instance2.isDeactivated = true;\n }, parentSuspense);\n if (!!(process.env.NODE_ENV !== \"production\") || __VUE_PROD_DEVTOOLS__) {\n devtoolsComponentAdded(instance2);\n }\n if (!!(process.env.NODE_ENV !== \"production\") && true) {\n instance2.__keepAliveStorageContainer = storageContainer;\n }\n };\n function unmount(vnode) {\n resetShapeFlag(vnode);\n _unmount(vnode, instance, parentSuspense, true);\n }\n function pruneCache(filter) {\n cache.forEach((vnode, key) => {\n const name = getComponentName(vnode.type);\n if (name && !filter(name)) {\n pruneCacheEntry(key);\n }\n });\n }\n function pruneCacheEntry(key) {\n const cached = cache.get(key);\n if (cached && (!current || !isSameVNodeType(cached, current))) {\n unmount(cached);\n } else if (current) {\n resetShapeFlag(current);\n }\n cache.delete(key);\n keys.delete(key);\n }\n watch(\n () => [props.include, props.exclude],\n ([include, exclude]) => {\n include && pruneCache((name) => matches(include, name));\n exclude && pruneCache((name) => !matches(exclude, name));\n },\n // prune post-render after `current` has been updated\n { flush: \"post\", deep: true }\n );\n let pendingCacheKey = null;\n const cacheSubtree = () => {\n if (pendingCacheKey != null) {\n if (isSuspense(instance.subTree.type)) {\n queuePostRenderEffect(() => {\n cache.set(pendingCacheKey, getInnerChild(instance.subTree));\n }, instance.subTree.suspense);\n } else {\n cache.set(pendingCacheKey, getInnerChild(instance.subTree));\n }\n }\n };\n onMounted(cacheSubtree);\n onUpdated(cacheSubtree);\n onBeforeUnmount(() => {\n cache.forEach((cached) => {\n const { subTree, suspense } = instance;\n const vnode = getInnerChild(subTree);\n if (cached.type === vnode.type && cached.key === vnode.key) {\n resetShapeFlag(vnode);\n const da = vnode.component.da;\n da && queuePostRenderEffect(da, suspense);\n return;\n }\n unmount(cached);\n });\n });\n return () => {\n pendingCacheKey = null;\n if (!slots.default) {\n return current = null;\n }\n const children = slots.default();\n const rawVNode = children[0];\n if (children.length > 1) {\n if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(`KeepAlive should contain exactly one component child.`);\n }\n current = null;\n return children;\n } else if (!isVNode(rawVNode) || !(rawVNode.shapeFlag & 4) && !(rawVNode.shapeFlag & 128)) {\n current = null;\n return rawVNode;\n }\n let vnode = getInnerChild(rawVNode);\n if (vnode.type === Comment) {\n current = null;\n return vnode;\n }\n const comp = vnode.type;\n const name = getComponentName(\n isAsyncWrapper(vnode) ? vnode.type.__asyncResolved || {} : comp\n );\n const { include, exclude, max } = props;\n if (include && (!name || !matches(include, name)) || exclude && name && matches(exclude, name)) {\n vnode.shapeFlag &= -257;\n current = vnode;\n return rawVNode;\n }\n const key = vnode.key == null ? comp : vnode.key;\n const cachedVNode = cache.get(key);\n if (vnode.el) {\n vnode = cloneVNode(vnode);\n if (rawVNode.shapeFlag & 128) {\n rawVNode.ssContent = vnode;\n }\n }\n pendingCacheKey = key;\n if (cachedVNode) {\n vnode.el = cachedVNode.el;\n vnode.component = cachedVNode.component;\n if (vnode.transition) {\n setTransitionHooks(vnode, vnode.transition);\n }\n vnode.shapeFlag |= 512;\n keys.delete(key);\n keys.add(key);\n } else {\n keys.add(key);\n if (max && keys.size > parseInt(max, 10)) {\n pruneCacheEntry(keys.values().next().value);\n }\n }\n vnode.shapeFlag |= 256;\n current = vnode;\n return isSuspense(rawVNode.type) ? rawVNode : vnode;\n };\n }\n};\nconst KeepAlive = KeepAliveImpl;\nfunction matches(pattern, name) {\n if (isArray(pattern)) {\n return pattern.some((p) => matches(p, name));\n } else if (isString(pattern)) {\n return pattern.split(\",\").includes(name);\n } else if (isRegExp(pattern)) {\n pattern.lastIndex = 0;\n return pattern.test(name);\n }\n return false;\n}\nfunction onActivated(hook, target) {\n registerKeepAliveHook(hook, \"a\", target);\n}\nfunction onDeactivated(hook, target) {\n registerKeepAliveHook(hook, \"da\", target);\n}\nfunction registerKeepAliveHook(hook, type, target = currentInstance) {\n const wrappedHook = hook.__wdc || (hook.__wdc = () => {\n let current = target;\n while (current) {\n if (current.isDeactivated) {\n return;\n }\n current = current.parent;\n }\n return hook();\n });\n injectHook(type, wrappedHook, target);\n if (target) {\n let current = target.parent;\n while (current && current.parent) {\n if (isKeepAlive(current.parent.vnode)) {\n injectToKeepAliveRoot(wrappedHook, type, target, current);\n }\n current = current.parent;\n }\n }\n}\nfunction injectToKeepAliveRoot(hook, type, target, keepAliveRoot) {\n const injected = injectHook(\n type,\n hook,\n keepAliveRoot,\n true\n /* prepend */\n );\n onUnmounted(() => {\n remove(keepAliveRoot[type], injected);\n }, target);\n}\nfunction resetShapeFlag(vnode) {\n vnode.shapeFlag &= -257;\n vnode.shapeFlag &= -513;\n}\nfunction getInnerChild(vnode) {\n return vnode.shapeFlag & 128 ? vnode.ssContent : vnode;\n}\n\nfunction injectHook(type, hook, target = currentInstance, prepend = false) {\n if (target) {\n const hooks = target[type] || (target[type] = []);\n const wrappedHook = hook.__weh || (hook.__weh = (...args) => {\n pauseTracking();\n const reset = setCurrentInstance(target);\n const res = callWithAsyncErrorHandling(hook, target, type, args);\n reset();\n resetTracking();\n return res;\n });\n if (prepend) {\n hooks.unshift(wrappedHook);\n } else {\n hooks.push(wrappedHook);\n }\n return wrappedHook;\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n const apiName = toHandlerKey(ErrorTypeStrings$1[type].replace(/ hook$/, \"\"));\n warn$1(\n `${apiName} is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup().` + (` If you are using async setup(), make sure to register lifecycle hooks before the first await statement.` )\n );\n }\n}\nconst createHook = (lifecycle) => (hook, target = currentInstance) => {\n if (!isInSSRComponentSetup || lifecycle === \"sp\") {\n injectHook(lifecycle, (...args) => hook(...args), target);\n }\n};\nconst onBeforeMount = createHook(\"bm\");\nconst onMounted = createHook(\"m\");\nconst onBeforeUpdate = createHook(\n \"bu\"\n);\nconst onUpdated = createHook(\"u\");\nconst onBeforeUnmount = createHook(\n \"bum\"\n);\nconst onUnmounted = createHook(\"um\");\nconst onServerPrefetch = createHook(\n \"sp\"\n);\nconst onRenderTriggered = createHook(\"rtg\");\nconst onRenderTracked = createHook(\"rtc\");\nfunction onErrorCaptured(hook, target = currentInstance) {\n injectHook(\"ec\", hook, target);\n}\n\nconst COMPONENTS = \"components\";\nconst DIRECTIVES = \"directives\";\nfunction resolveComponent(name, maybeSelfReference) {\n return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name;\n}\nconst NULL_DYNAMIC_COMPONENT = Symbol.for(\"v-ndc\");\nfunction resolveDynamicComponent(component) {\n if (isString(component)) {\n return resolveAsset(COMPONENTS, component, false) || component;\n } else {\n return component || NULL_DYNAMIC_COMPONENT;\n }\n}\nfunction resolveDirective(name) {\n return resolveAsset(DIRECTIVES, name);\n}\nfunction resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) {\n const instance = currentRenderingInstance || currentInstance;\n if (instance) {\n const Component = instance.type;\n if (type === COMPONENTS) {\n const selfName = getComponentName(\n Component,\n false\n );\n if (selfName && (selfName === name || selfName === camelize(name) || selfName === capitalize(camelize(name)))) {\n return Component;\n }\n }\n const res = (\n // local registration\n // check instance[type] first which is resolved for options API\n resolve(instance[type] || Component[type], name) || // global registration\n resolve(instance.appContext[type], name)\n );\n if (!res && maybeSelfReference) {\n return Component;\n }\n if (!!(process.env.NODE_ENV !== \"production\") && warnMissing && !res) {\n const extra = type === COMPONENTS ? `\nIf this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.` : ``;\n warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`);\n }\n return res;\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn$1(\n `resolve${capitalize(type.slice(0, -1))} can only be used in render() or setup().`\n );\n }\n}\nfunction resolve(registry, name) {\n return registry && (registry[name] || registry[camelize(name)] || registry[capitalize(camelize(name))]);\n}\n\nfunction renderList(source, renderItem, cache, index) {\n let ret;\n const cached = cache && cache[index];\n const sourceIsArray = isArray(source);\n if (sourceIsArray || isString(source)) {\n const sourceIsReactiveArray = sourceIsArray && isReactive(source);\n let needsWrap = false;\n let isReadonlySource = false;\n if (sourceIsReactiveArray) {\n needsWrap = !isShallow(source);\n isReadonlySource = isReadonly(source);\n source = shallowReadArray(source);\n }\n ret = new Array(source.length);\n for (let i = 0, l = source.length; i < l; i++) {\n ret[i] = renderItem(\n needsWrap ? isReadonlySource ? toReadonly(toReactive(source[i])) : toReactive(source[i]) : source[i],\n i,\n void 0,\n cached && cached[i]\n );\n }\n } else if (typeof source === \"number\") {\n if (!!(process.env.NODE_ENV !== \"production\") && !Number.isInteger(source)) {\n warn$1(`The v-for range expect an integer value but got ${source}.`);\n }\n ret = new Array(source);\n for (let i = 0; i < source; i++) {\n ret[i] = renderItem(i + 1, i, void 0, cached && cached[i]);\n }\n } else if (isObject(source)) {\n if (source[Symbol.iterator]) {\n ret = Array.from(\n source,\n (item, i) => renderItem(item, i, void 0, cached && cached[i])\n );\n } else {\n const keys = Object.keys(source);\n ret = new Array(keys.length);\n for (let i = 0, l = keys.length; i < l; i++) {\n const key = keys[i];\n ret[i] = renderItem(source[key], key, i, cached && cached[i]);\n }\n }\n } else {\n ret = [];\n }\n if (cache) {\n cache[index] = ret;\n }\n return ret;\n}\n\nfunction createSlots(slots, dynamicSlots) {\n for (let i = 0; i < dynamicSlots.length; i++) {\n const slot = dynamicSlots[i];\n if (isArray(slot)) {\n for (let j = 0; j < slot.length; j++) {\n slots[slot[j].name] = slot[j].fn;\n }\n } else if (slot) {\n slots[slot.name] = slot.key ? (...args) => {\n const res = slot.fn(...args);\n if (res) res.key = slot.key;\n return res;\n } : slot.fn;\n }\n }\n return slots;\n}\n\nfunction renderSlot(slots, name, props = {}, fallback, noSlotted) {\n if (currentRenderingInstance.ce || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.ce) {\n const hasProps = Object.keys(props).length > 0;\n if (name !== \"default\") props.name = name;\n return openBlock(), createBlock(\n Fragment,\n null,\n [createVNode(\"slot\", props, fallback && fallback())],\n hasProps ? -2 : 64\n );\n }\n let slot = slots[name];\n if (!!(process.env.NODE_ENV !== \"production\") && slot && slot.length > 1) {\n warn$1(\n `SSR-optimized slot function detected in a non-SSR-optimized render function. You need to mark this component with $dynamic-slots in the parent template.`\n );\n slot = () => [];\n }\n if (slot && slot._c) {\n slot._d = false;\n }\n openBlock();\n const validSlotContent = slot && ensureValidVNode(slot(props));\n const slotKey = props.key || // slot content array of a dynamic conditional slot may have a branch\n // key attached in the `createSlots` helper, respect that\n validSlotContent && validSlotContent.key;\n const rendered = createBlock(\n Fragment,\n {\n key: (slotKey && !isSymbol(slotKey) ? slotKey : `_${name}`) + // #7256 force differentiate fallback content from actual content\n (!validSlotContent && fallback ? \"_fb\" : \"\")\n },\n validSlotContent || (fallback ? fallback() : []),\n validSlotContent && slots._ === 1 ? 64 : -2\n );\n if (!noSlotted && rendered.scopeId) {\n rendered.slotScopeIds = [rendered.scopeId + \"-s\"];\n }\n if (slot && slot._c) {\n slot._d = true;\n }\n return rendered;\n}\nfunction ensureValidVNode(vnodes) {\n return vnodes.some((child) => {\n if (!isVNode(child)) return true;\n if (child.type === Comment) return false;\n if (child.type === Fragment && !ensureValidVNode(child.children))\n return false;\n return true;\n }) ? vnodes : null;\n}\n\nfunction toHandlers(obj, preserveCaseIfNecessary) {\n const ret = {};\n if (!!(process.env.NODE_ENV !== \"production\") && !isObject(obj)) {\n warn$1(`v-on with no argument expects an object value.`);\n return ret;\n }\n for (const key in obj) {\n ret[preserveCaseIfNecessary && /[A-Z]/.test(key) ? `on:${key}` : toHandlerKey(key)] = obj[key];\n }\n return ret;\n}\n\nconst getPublicInstance = (i) => {\n if (!i) return null;\n if (isStatefulComponent(i)) return getComponentPublicInstance(i);\n return getPublicInstance(i.parent);\n};\nconst publicPropertiesMap = (\n // Move PURE marker to new line to workaround compiler discarding it\n // due to type annotation\n /* @__PURE__ */ extend(/* @__PURE__ */ Object.create(null), {\n $: (i) => i,\n $el: (i) => i.vnode.el,\n $data: (i) => i.data,\n $props: (i) => !!(process.env.NODE_ENV !== \"production\") ? shallowReadonly(i.props) : i.props,\n $attrs: (i) => !!(process.env.NODE_ENV !== \"production\") ? shallowReadonly(i.attrs) : i.attrs,\n $slots: (i) => !!(process.env.NODE_ENV !== \"production\") ? shallowReadonly(i.slots) : i.slots,\n $refs: (i) => !!(process.env.NODE_ENV !== \"production\") ? shallowReadonly(i.refs) : i.refs,\n $parent: (i) => getPublicInstance(i.parent),\n $root: (i) => getPublicInstance(i.root),\n $host: (i) => i.ce,\n $emit: (i) => i.emit,\n $options: (i) => __VUE_OPTIONS_API__ ? resolveMergedOptions(i) : i.type,\n $forceUpdate: (i) => i.f || (i.f = () => {\n queueJob(i.update);\n }),\n $nextTick: (i) => i.n || (i.n = nextTick.bind(i.proxy)),\n $watch: (i) => __VUE_OPTIONS_API__ ? instanceWatch.bind(i) : NOOP\n })\n);\nconst isReservedPrefix = (key) => key === \"_\" || key === \"$\";\nconst hasSetupBinding = (state, key) => state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key);\nconst PublicInstanceProxyHandlers = {\n get({ _: instance }, key) {\n if (key === \"__v_skip\") {\n return true;\n }\n const { ctx, setupState, data, props, accessCache, type, appContext } = instance;\n if (!!(process.env.NODE_ENV !== \"production\") && key === \"__isVue\") {\n return true;\n }\n let normalizedProps;\n if (key[0] !== \"$\") {\n const n = accessCache[key];\n if (n !== void 0) {\n switch (n) {\n case 1 /* SETUP */:\n return setupState[key];\n case 2 /* DATA */:\n return data[key];\n case 4 /* CONTEXT */:\n return ctx[key];\n case 3 /* PROPS */:\n return props[key];\n }\n } else if (hasSetupBinding(setupState, key)) {\n accessCache[key] = 1 /* SETUP */;\n return setupState[key];\n } else if (data !== EMPTY_OBJ && hasOwn(data, key)) {\n accessCache[key] = 2 /* DATA */;\n return data[key];\n } else if (\n // only cache other properties when instance has declared (thus stable)\n // props\n (normalizedProps = instance.propsOptions[0]) && hasOwn(normalizedProps, key)\n ) {\n accessCache[key] = 3 /* PROPS */;\n return props[key];\n } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {\n accessCache[key] = 4 /* CONTEXT */;\n return ctx[key];\n } else if (!__VUE_OPTIONS_API__ || shouldCacheAccess) {\n accessCache[key] = 0 /* OTHER */;\n }\n }\n const publicGetter = publicPropertiesMap[key];\n let cssModule, globalProperties;\n if (publicGetter) {\n if (key === \"$attrs\") {\n track(instance.attrs, \"get\", \"\");\n !!(process.env.NODE_ENV !== \"production\") && markAttrsAccessed();\n } else if (!!(process.env.NODE_ENV !== \"production\") && key === \"$slots\") {\n track(instance, \"get\", key);\n }\n return publicGetter(instance);\n } else if (\n // css module (injected by vue-loader)\n (cssModule = type.__cssModules) && (cssModule = cssModule[key])\n ) {\n return cssModule;\n } else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {\n accessCache[key] = 4 /* CONTEXT */;\n return ctx[key];\n } else if (\n // global properties\n globalProperties = appContext.config.globalProperties, hasOwn(globalProperties, key)\n ) {\n {\n return globalProperties[key];\n }\n } else if (!!(process.env.NODE_ENV !== \"production\") && currentRenderingInstance && (!isString(key) || // #1091 avoid internal isRef/isVNode checks on component instance leading\n // to infinite warning loop\n key.indexOf(\"__v\") !== 0)) {\n if (data !== EMPTY_OBJ && isReservedPrefix(key[0]) && hasOwn(data, key)) {\n warn$1(\n `Property ${JSON.stringify(\n key\n )} must be accessed via $data because it starts with a reserved character (\"$\" or \"_\") and is not proxied on the render context.`\n );\n } else if (instance === currentRenderingInstance) {\n warn$1(\n `Property ${JSON.stringify(key)} was accessed during render but is not defined on instance.`\n );\n }\n }\n },\n set({ _: instance }, key, value) {\n const { data, setupState, ctx } = instance;\n if (hasSetupBinding(setupState, key)) {\n setupState[key] = value;\n return true;\n } else if (!!(process.env.NODE_ENV !== \"production\") && setupState.__isScriptSetup && hasOwn(setupState, key)) {\n warn$1(`Cannot mutate '); + } elseif ($format === 'js') { + static::writeOutput(static::generateScript()); + } + static::resetStatic(); + } + } + public function close() + { + self::resetStatic(); + } + public function reset() + { + self::resetStatic(); + } + /** + * Forget all logged records + */ + public static function resetStatic() + { + static::$records = array(); + } + /** + * Wrapper for register_shutdown_function to allow overriding + */ + protected function registerShutdownFunction() + { + if (\PHP_SAPI !== 'cli') { + \register_shutdown_function(array('PostSMTP\\Vendor\\Monolog\\Handler\\BrowserConsoleHandler', 'send')); + } + } + /** + * Wrapper for echo to allow overriding + * + * @param string $str + */ + protected static function writeOutput($str) + { + echo $str; + } + /** + * Checks the format of the response + * + * If Content-Type is set to application/javascript or text/javascript -> js + * If Content-Type is set to text/html, or is unset -> html + * If Content-Type is anything else -> unknown + * + * @return string One of 'js', 'html' or 'unknown' + */ + protected static function getResponseFormat() + { + // Check content type + foreach (\headers_list() as $header) { + if (\stripos($header, 'content-type:') === 0) { + // This handler only works with HTML and javascript outputs + // text/javascript is obsolete in favour of application/javascript, but still used + if (\stripos($header, 'application/javascript') !== \false || \stripos($header, 'text/javascript') !== \false) { + return 'js'; + } + if (\stripos($header, 'text/html') === \false) { + return 'unknown'; + } + break; + } + } + return 'html'; + } + private static function generateScript() + { + $script = array(); + foreach (static::$records as $record) { + $context = static::dump('Context', $record['context']); + $extra = static::dump('Extra', $record['extra']); + if (empty($context) && empty($extra)) { + $script[] = static::call_array('log', static::handleStyles($record['formatted'])); + } else { + $script = \array_merge($script, array(static::call_array('groupCollapsed', static::handleStyles($record['formatted']))), $context, $extra, array(static::call('groupEnd'))); + } + } + return "(function (c) {if (c && c.groupCollapsed) {\n" . \implode("\n", $script) . "\n}})(console);"; + } + private static function handleStyles($formatted) + { + $args = array(); + $format = '%c' . $formatted; + \preg_match_all('/\\[\\[(.*?)\\]\\]\\{([^}]*)\\}/s', $format, $matches, \PREG_OFFSET_CAPTURE | \PREG_SET_ORDER); + foreach (\array_reverse($matches) as $match) { + $args[] = '"font-weight: normal"'; + $args[] = static::quote(static::handleCustomStyles($match[2][0], $match[1][0])); + $pos = $match[0][1]; + $format = \substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . \substr($format, $pos + \strlen($match[0][0])); + } + $args[] = static::quote('font-weight: normal'); + $args[] = static::quote($format); + return \array_reverse($args); + } + private static function handleCustomStyles($style, $string) + { + static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey'); + static $labels = array(); + return \preg_replace_callback('/macro\\s*:(.*?)(?:;|$)/', function ($m) use($string, &$colors, &$labels) { + if (\trim($m[1]) === 'autolabel') { + // Format the string as a label with consistent auto assigned background color + if (!isset($labels[$string])) { + $labels[$string] = $colors[\count($labels) % \count($colors)]; + } + $color = $labels[$string]; + return "background-color: {$color}; color: white; border-radius: 3px; padding: 0 2px 0 2px"; + } + return $m[1]; + }, $style); + } + private static function dump($title, array $dict) + { + $script = array(); + $dict = \array_filter($dict); + if (empty($dict)) { + return $script; + } + $script[] = static::call('log', static::quote('%c%s'), static::quote('font-weight: bold'), static::quote($title)); + foreach ($dict as $key => $value) { + $value = \json_encode($value); + if (empty($value)) { + $value = static::quote(''); + } + $script[] = static::call('log', static::quote('%s: %o'), static::quote($key), $value); + } + return $script; + } + private static function quote($arg) + { + return '"' . \addcslashes($arg, "\"\n\\") . '"'; + } + private static function call() + { + $args = \func_get_args(); + $method = \array_shift($args); + return static::call_array($method, $args); + } + private static function call_array($method, array $args) + { + return 'c.' . $method . '(' . \implode(', ', $args) . ');'; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/BufferHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/BufferHandler.php new file mode 100644 index 0000000..b23d732 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/BufferHandler.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\ResettableInterface; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Buffers all records until closing the handler and then pass them as batch. + * + * This is useful for a MailHandler to send only one mail per request instead of + * sending one per log message. + * + * @author Christophe Coevoet + */ +class BufferHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractHandler +{ + protected $handler; + protected $bufferSize = 0; + protected $bufferLimit; + protected $flushOnOverflow; + protected $buffer = array(); + protected $initialized = \false; + /** + * @param HandlerInterface $handler Handler. + * @param int $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded + */ + public function __construct(\PostSMTP\Vendor\Monolog\Handler\HandlerInterface $handler, $bufferLimit = 0, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $flushOnOverflow = \false) + { + parent::__construct($level, $bubble); + $this->handler = $handler; + $this->bufferLimit = (int) $bufferLimit; + $this->flushOnOverflow = $flushOnOverflow; + } + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return \false; + } + if (!$this->initialized) { + // __destructor() doesn't get called on Fatal errors + \register_shutdown_function(array($this, 'close')); + $this->initialized = \true; + } + if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) { + if ($this->flushOnOverflow) { + $this->flush(); + } else { + \array_shift($this->buffer); + $this->bufferSize--; + } + } + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + } + $this->buffer[] = $record; + $this->bufferSize++; + return \false === $this->bubble; + } + public function flush() + { + if ($this->bufferSize === 0) { + return; + } + $this->handler->handleBatch($this->buffer); + $this->clear(); + } + public function __destruct() + { + // suppress the parent behavior since we already have register_shutdown_function() + // to call close(), and the reference contained there will prevent this from being + // GC'd until the end of the request + } + /** + * {@inheritdoc} + */ + public function close() + { + $this->flush(); + } + /** + * Clears the buffer without flushing any messages down to the wrapped handler. + */ + public function clear() + { + $this->bufferSize = 0; + $this->buffer = array(); + } + public function reset() + { + $this->flush(); + parent::reset(); + if ($this->handler instanceof \PostSMTP\Vendor\Monolog\ResettableInterface) { + $this->handler->reset(); + } + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + $this->handler->setFormatter($formatter); + return $this; + } + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->handler->getFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php new file mode 100644 index 0000000..50fc95c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\ChromePHPFormatter; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +/** + * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/) + * + * This also works out of the box with Firefox 43+ + * + * @author Christophe Coevoet + */ +class ChromePHPHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * Version of the extension + */ + const VERSION = '4.0'; + /** + * Header name + */ + const HEADER_NAME = 'X-ChromeLogger-Data'; + /** + * Regular expression to detect supported browsers (matches any Chrome, or Firefox 43+) + */ + const USER_AGENT_REGEX = '{\\b(?:Chrome/\\d+(?:\\.\\d+)*|HeadlessChrome|Firefox/(?:4[3-9]|[5-9]\\d|\\d{3,})(?:\\.\\d)*)\\b}'; + protected static $initialized = \false; + /** + * Tracks whether we sent too much data + * + * Chrome limits the headers to 4KB, so when we sent 3KB we stop sending + * + * @var bool + */ + protected static $overflowed = \false; + protected static $json = array('version' => self::VERSION, 'columns' => array('label', 'log', 'backtrace', 'type'), 'rows' => array()); + protected static $sendHeaders = \true; + /** + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + parent::__construct($level, $bubble); + if (!\function_exists('json_encode')) { + throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler'); + } + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + if (!empty($messages)) { + $messages = $this->getFormatter()->formatBatch($messages); + self::$json['rows'] = \array_merge(self::$json['rows'], $messages); + $this->send(); + } + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\ChromePHPFormatter(); + } + /** + * Creates & sends header for a record + * + * @see sendHeader() + * @see send() + * @param array $record + */ + protected function write(array $record) + { + self::$json['rows'][] = $record['formatted']; + $this->send(); + } + /** + * Sends the log header + * + * @see sendHeader() + */ + protected function send() + { + if (self::$overflowed || !self::$sendHeaders) { + return; + } + if (!self::$initialized) { + self::$initialized = \true; + self::$sendHeaders = $this->headersAccepted(); + if (!self::$sendHeaders) { + return; + } + self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : ''; + } + $json = \PostSMTP\Vendor\Monolog\Utils::jsonEncode(self::$json, null, \true); + $data = \base64_encode(\utf8_encode($json)); + if (\strlen($data) > 3 * 1024) { + self::$overflowed = \true; + $record = array('message' => 'Incomplete logs, chrome header size limit reached', 'context' => array(), 'level' => \PostSMTP\Vendor\Monolog\Logger::WARNING, 'level_name' => \PostSMTP\Vendor\Monolog\Logger::getLevelName(\PostSMTP\Vendor\Monolog\Logger::WARNING), 'channel' => 'monolog', 'datetime' => new \DateTime(), 'extra' => array()); + self::$json['rows'][\count(self::$json['rows']) - 1] = $this->getFormatter()->format($record); + $json = \PostSMTP\Vendor\Monolog\Utils::jsonEncode(self::$json, null, \true); + $data = \base64_encode(\utf8_encode($json)); + } + if (\trim($data) !== '') { + $this->sendHeader(self::HEADER_NAME, $data); + } + } + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!\headers_sent() && self::$sendHeaders) { + \header(\sprintf('%s: %s', $header, $content)); + } + } + /** + * Verifies if the headers are accepted by the current user agent + * + * @return bool + */ + protected function headersAccepted() + { + if (empty($_SERVER['HTTP_USER_AGENT'])) { + return \false; + } + return \preg_match(self::USER_AGENT_REGEX, $_SERVER['HTTP_USER_AGENT']); + } + /** + * BC getter for the sendHeaders property that has been made static + */ + public function __get($property) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property ' . $property); + } + return static::$sendHeaders; + } + /** + * BC setter for the sendHeaders property that has been made static + */ + public function __set($property, $value) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property ' . $property); + } + static::$sendHeaders = $value; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php new file mode 100644 index 0000000..0e60967 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\JsonFormatter; +use PostSMTP\Vendor\Monolog\Logger; +/** + * CouchDB handler + * + * @author Markus Bachmann + */ +class CouchDBHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + private $options; + public function __construct(array $options = array(), $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + $this->options = \array_merge(array('host' => 'localhost', 'port' => 5984, 'dbname' => 'logger', 'username' => null, 'password' => null), $options); + parent::__construct($level, $bubble); + } + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $basicAuth = null; + if ($this->options['username']) { + $basicAuth = \sprintf('%s:%s@', $this->options['username'], $this->options['password']); + } + $url = 'http://' . $basicAuth . $this->options['host'] . ':' . $this->options['port'] . '/' . $this->options['dbname']; + $context = \stream_context_create(array('http' => array('method' => 'POST', 'content' => $record['formatted'], 'ignore_errors' => \true, 'max_redirects' => 0, 'header' => 'Content-type: application/json'))); + if (\false === @\file_get_contents($url, null, $context)) { + throw new \RuntimeException(\sprintf('Could not connect to %s', $url)); + } + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\JsonFormatter(\PostSMTP\Vendor\Monolog\Formatter\JsonFormatter::BATCH_MODE_JSON, \false); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/CubeHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/CubeHandler.php new file mode 100644 index 0000000..c95ea1f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/CubeHandler.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +/** + * Logs to Cube. + * + * @link http://square.github.com/cube/ + * @author Wan Chen + */ +class CubeHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + private $udpConnection; + private $httpConnection; + private $scheme; + private $host; + private $port; + private $acceptedSchemes = array('http', 'udp'); + /** + * Create a Cube handler + * + * @throws \UnexpectedValueException when given url is not a valid url. + * A valid url must consist of three parts : protocol://host:port + * Only valid protocols used by Cube are http and udp + */ + public function __construct($url, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + $urlInfo = \parse_url($url); + if (!isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) { + throw new \UnexpectedValueException('URL "' . $url . '" is not valid'); + } + if (!\in_array($urlInfo['scheme'], $this->acceptedSchemes)) { + throw new \UnexpectedValueException('Invalid protocol (' . $urlInfo['scheme'] . ').' . ' Valid options are ' . \implode(', ', $this->acceptedSchemes)); + } + $this->scheme = $urlInfo['scheme']; + $this->host = $urlInfo['host']; + $this->port = $urlInfo['port']; + parent::__construct($level, $bubble); + } + /** + * Establish a connection to an UDP socket + * + * @throws \LogicException when unable to connect to the socket + * @throws MissingExtensionException when there is no socket extension + */ + protected function connectUdp() + { + if (!\extension_loaded('sockets')) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler'); + } + $this->udpConnection = \socket_create(\AF_INET, \SOCK_DGRAM, 0); + if (!$this->udpConnection) { + throw new \LogicException('Unable to create a socket'); + } + if (!\socket_connect($this->udpConnection, $this->host, $this->port)) { + throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port); + } + } + /** + * Establish a connection to a http server + * @throws \LogicException when no curl extension + */ + protected function connectHttp() + { + if (!\extension_loaded('curl')) { + throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler'); + } + $this->httpConnection = \curl_init('http://' . $this->host . ':' . $this->port . '/1.0/event/put'); + if (!$this->httpConnection) { + throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port); + } + \curl_setopt($this->httpConnection, \CURLOPT_CUSTOMREQUEST, "POST"); + \curl_setopt($this->httpConnection, \CURLOPT_RETURNTRANSFER, \true); + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $date = $record['datetime']; + $data = array('time' => $date->format('Y-m-d\\TH:i:s.uO')); + unset($record['datetime']); + if (isset($record['context']['type'])) { + $data['type'] = $record['context']['type']; + unset($record['context']['type']); + } else { + $data['type'] = $record['channel']; + } + $data['data'] = $record['context']; + $data['data']['level'] = $record['level']; + if ($this->scheme === 'http') { + $this->writeHttp(\PostSMTP\Vendor\Monolog\Utils::jsonEncode($data)); + } else { + $this->writeUdp(\PostSMTP\Vendor\Monolog\Utils::jsonEncode($data)); + } + } + private function writeUdp($data) + { + if (!$this->udpConnection) { + $this->connectUdp(); + } + \socket_send($this->udpConnection, $data, \strlen($data), 0); + } + private function writeHttp($data) + { + if (!$this->httpConnection) { + $this->connectHttp(); + } + \curl_setopt($this->httpConnection, \CURLOPT_POSTFIELDS, '[' . $data . ']'); + \curl_setopt($this->httpConnection, \CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . \strlen('[' . $data . ']'))); + \PostSMTP\Vendor\Monolog\Handler\Curl\Util::execute($this->httpConnection, 5, \false); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/Curl/Util.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/Curl/Util.php new file mode 100644 index 0000000..2d7e980 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/Curl/Util.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler\Curl; + +class Util +{ + private static $retriableErrorCodes = array(\CURLE_COULDNT_RESOLVE_HOST, \CURLE_COULDNT_CONNECT, \CURLE_HTTP_NOT_FOUND, \CURLE_READ_ERROR, \CURLE_OPERATION_TIMEOUTED, \CURLE_HTTP_POST_ERROR, \CURLE_SSL_CONNECT_ERROR); + /** + * Executes a CURL request with optional retries and exception on failure + * + * @param resource $ch curl handler + * @throws \RuntimeException + */ + public static function execute($ch, $retries = 5, $closeAfterDone = \true) + { + while ($retries--) { + if (\curl_exec($ch) === \false) { + $curlErrno = \curl_errno($ch); + if (\false === \in_array($curlErrno, self::$retriableErrorCodes, \true) || !$retries) { + $curlError = \curl_error($ch); + if ($closeAfterDone) { + \curl_close($ch); + } + throw new \RuntimeException(\sprintf('Curl error (code %s): %s', $curlErrno, $curlError)); + } + continue; + } + if ($closeAfterDone) { + \curl_close($ch); + } + break; + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php new file mode 100644 index 0000000..b9e3cb1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Simple handler wrapper that deduplicates log records across multiple requests + * + * It also includes the BufferHandler functionality and will buffer + * all messages until the end of the request or flush() is called. + * + * This works by storing all log records' messages above $deduplicationLevel + * to the file specified by $deduplicationStore. When further logs come in at the end of the + * request (or when flush() is called), all those above $deduplicationLevel are checked + * against the existing stored logs. If they match and the timestamps in the stored log is + * not older than $time seconds, the new log record is discarded. If no log record is new, the + * whole data set is discarded. + * + * This is mainly useful in combination with Mail handlers or things like Slack or HipChat handlers + * that send messages to people, to avoid spamming with the same message over and over in case of + * a major component failure like a database server being down which makes all requests fail in the + * same way. + * + * @author Jordi Boggiano + */ +class DeduplicationHandler extends \PostSMTP\Vendor\Monolog\Handler\BufferHandler +{ + /** + * @var string + */ + protected $deduplicationStore; + /** + * @var int + */ + protected $deduplicationLevel; + /** + * @var int + */ + protected $time; + /** + * @var bool + */ + private $gc = \false; + /** + * @param HandlerInterface $handler Handler. + * @param string $deduplicationStore The file/path where the deduplication log should be kept + * @param int $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes + * @param int $time The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\PostSMTP\Vendor\Monolog\Handler\HandlerInterface $handler, $deduplicationStore = null, $deduplicationLevel = \PostSMTP\Vendor\Monolog\Logger::ERROR, $time = 60, $bubble = \true) + { + parent::__construct($handler, 0, \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble, \false); + $this->deduplicationStore = $deduplicationStore === null ? \sys_get_temp_dir() . '/monolog-dedup-' . \substr(\md5(__FILE__), 0, 20) . '.log' : $deduplicationStore; + $this->deduplicationLevel = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($deduplicationLevel); + $this->time = $time; + } + public function flush() + { + if ($this->bufferSize === 0) { + return; + } + $passthru = null; + foreach ($this->buffer as $record) { + if ($record['level'] >= $this->deduplicationLevel) { + $passthru = $passthru || !$this->isDuplicate($record); + if ($passthru) { + $this->appendRecord($record); + } + } + } + // default of null is valid as well as if no record matches duplicationLevel we just pass through + if ($passthru === \true || $passthru === null) { + $this->handler->handleBatch($this->buffer); + } + $this->clear(); + if ($this->gc) { + $this->collectLogs(); + } + } + private function isDuplicate(array $record) + { + if (!\file_exists($this->deduplicationStore)) { + return \false; + } + $store = \file($this->deduplicationStore, \FILE_IGNORE_NEW_LINES | \FILE_SKIP_EMPTY_LINES); + if (!\is_array($store)) { + return \false; + } + $yesterday = \time() - 86400; + $timestampValidity = $record['datetime']->getTimestamp() - $this->time; + $expectedMessage = \preg_replace('{[\\r\\n].*}', '', $record['message']); + for ($i = \count($store) - 1; $i >= 0; $i--) { + list($timestamp, $level, $message) = \explode(':', $store[$i], 3); + if ($level === $record['level_name'] && $message === $expectedMessage && $timestamp > $timestampValidity) { + return \true; + } + if ($timestamp < $yesterday) { + $this->gc = \true; + } + } + return \false; + } + private function collectLogs() + { + if (!\file_exists($this->deduplicationStore)) { + return \false; + } + $handle = \fopen($this->deduplicationStore, 'rw+'); + \flock($handle, \LOCK_EX); + $validLogs = array(); + $timestampValidity = \time() - $this->time; + while (!\feof($handle)) { + $log = \fgets($handle); + if (\substr($log, 0, 10) >= $timestampValidity) { + $validLogs[] = $log; + } + } + \ftruncate($handle, 0); + \rewind($handle); + foreach ($validLogs as $log) { + \fwrite($handle, $log); + } + \flock($handle, \LOCK_UN); + \fclose($handle); + $this->gc = \false; + } + private function appendRecord(array $record) + { + \file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . \preg_replace('{[\\r\\n].*}', '', $record['message']) . "\n", \FILE_APPEND); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php new file mode 100644 index 0000000..86d77bf --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter; +use PostSMTP\Vendor\Doctrine\CouchDB\CouchDBClient; +/** + * CouchDB handler for Doctrine CouchDB ODM + * + * @author Markus Bachmann + */ +class DoctrineCouchDBHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + private $client; + public function __construct(\PostSMTP\Vendor\Doctrine\CouchDB\CouchDBClient $client, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + $this->client = $client; + parent::__construct($level, $bubble); + } + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $this->client->postDocument($record['formatted']); + } + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php new file mode 100644 index 0000000..9cbfc98 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Aws\Sdk; +use PostSMTP\Vendor\Aws\DynamoDb\DynamoDbClient; +use PostSMTP\Vendor\Aws\DynamoDb\Marshaler; +use PostSMTP\Vendor\Monolog\Formatter\ScalarFormatter; +use PostSMTP\Vendor\Monolog\Logger; +/** + * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/) + * + * @link https://github.com/aws/aws-sdk-php/ + * @author Andrew Lawson + */ +class DynamoDbHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + const DATE_FORMAT = 'Y-m-d\\TH:i:s.uO'; + /** + * @var DynamoDbClient + */ + protected $client; + /** + * @var string + */ + protected $table; + /** + * @var int + */ + protected $version; + /** + * @var Marshaler + */ + protected $marshaler; + /** + * @param DynamoDbClient $client + * @param string $table + * @param int $level + * @param bool $bubble + */ + public function __construct(\PostSMTP\Vendor\Aws\DynamoDb\DynamoDbClient $client, $table, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if (\defined('Aws\\Sdk::VERSION') && \version_compare(\PostSMTP\Vendor\Aws\Sdk::VERSION, '3.0', '>=')) { + $this->version = 3; + $this->marshaler = new \PostSMTP\Vendor\Aws\DynamoDb\Marshaler(); + } else { + $this->version = 2; + } + $this->client = $client; + $this->table = $table; + parent::__construct($level, $bubble); + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $filtered = $this->filterEmptyFields($record['formatted']); + if ($this->version === 3) { + $formatted = $this->marshaler->marshalItem($filtered); + } else { + /** @phpstan-ignore-next-line */ + $formatted = $this->client->formatAttributes($filtered); + } + $this->client->putItem(array('TableName' => $this->table, 'Item' => $formatted)); + } + /** + * @param array $record + * @return array + */ + protected function filterEmptyFields(array $record) + { + return \array_filter($record, function ($value) { + return !empty($value) || \false === $value || 0 === $value; + }); + } + /** + * {@inheritdoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\ScalarFormatter(self::DATE_FORMAT); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php new file mode 100644 index 0000000..7fb065c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +use PostSMTP\Vendor\Monolog\Formatter\ElasticaFormatter; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Elastica\Client; +use PostSMTP\Vendor\Elastica\Exception\ExceptionInterface; +/** + * Elastic Search handler + * + * Usage example: + * + * $client = new \Elastica\Client(); + * $options = array( + * 'index' => 'elastic_index_name', + * 'type' => 'elastic_doc_type', + * ); + * $handler = new ElasticSearchHandler($client, $options); + * $log = new Logger('application'); + * $log->pushHandler($handler); + * + * @author Jelle Vink + */ +class ElasticSearchHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * @var Client + */ + protected $client; + /** + * @var array Handler config options + */ + protected $options = array(); + /** + * @param Client $client Elastica Client object + * @param array $options Handler configuration + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\PostSMTP\Vendor\Elastica\Client $client, array $options = array(), $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + parent::__construct($level, $bubble); + $this->client = $client; + $this->options = \array_merge(array( + 'index' => 'monolog', + // Elastic index name + 'type' => 'record', + // Elastic document type + 'ignore_error' => \false, + ), $options); + } + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + $this->bulkSend(array($record['formatted'])); + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + if ($formatter instanceof \PostSMTP\Vendor\Monolog\Formatter\ElasticaFormatter) { + return parent::setFormatter($formatter); + } + throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter'); + } + /** + * Getter options + * @return array + */ + public function getOptions() + { + return $this->options; + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\ElasticaFormatter($this->options['index'], $this->options['type']); + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $documents = $this->getFormatter()->formatBatch($records); + $this->bulkSend($documents); + } + /** + * Use Elasticsearch bulk API to send list of documents + * @param array $documents + * @throws \RuntimeException + */ + protected function bulkSend(array $documents) + { + try { + $this->client->addDocuments($documents); + } catch (\PostSMTP\Vendor\Elastica\Exception\ExceptionInterface $e) { + if (!$this->options['ignore_error']) { + throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e); + } + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php new file mode 100644 index 0000000..841dfba --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +use PostSMTP\Vendor\Monolog\Logger; +/** + * Stores to PHP error_log() handler. + * + * @author Elan Ruusamäe + */ +class ErrorLogHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + const OPERATING_SYSTEM = 0; + const SAPI = 4; + protected $messageType; + protected $expandNewlines; + /** + * @param int $messageType Says where the error should go. + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries + */ + public function __construct($messageType = self::OPERATING_SYSTEM, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $expandNewlines = \false) + { + parent::__construct($level, $bubble); + if (\false === \in_array($messageType, self::getAvailableTypes())) { + $message = \sprintf('The given message type "%s" is not supported', \print_r($messageType, \true)); + throw new \InvalidArgumentException($message); + } + $this->messageType = $messageType; + $this->expandNewlines = $expandNewlines; + } + /** + * @return array With all available types + */ + public static function getAvailableTypes() + { + return array(self::OPERATING_SYSTEM, self::SAPI); + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%'); + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if ($this->expandNewlines) { + $lines = \preg_split('{[\\r\\n]+}', (string) $record['formatted']); + foreach ($lines as $line) { + \error_log($line, $this->messageType); + } + } else { + \error_log((string) $record['formatted'], $this->messageType); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FilterHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FilterHandler.php new file mode 100644 index 0000000..f539e6f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FilterHandler.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Simple handler wrapper that filters records based on a list of levels + * + * It can be configured with an exact list of levels to allow, or a min/max level. + * + * @author Hennadiy Verkh + * @author Jordi Boggiano + */ +class FilterHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractHandler +{ + /** + * Handler or factory callable($record, $this) + * + * @var callable|\Monolog\Handler\HandlerInterface + */ + protected $handler; + /** + * Minimum level for logs that are passed to handler + * + * @var int[] + */ + protected $acceptedLevels; + /** + * Whether the messages that are handled can bubble up the stack or not + * + * @var bool + */ + protected $bubble; + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $filterHandler). + * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided + * @param int $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($handler, $minLevelOrList = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $maxLevel = \PostSMTP\Vendor\Monolog\Logger::EMERGENCY, $bubble = \true) + { + $this->handler = $handler; + $this->bubble = $bubble; + $this->setAcceptedLevels($minLevelOrList, $maxLevel); + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface && !\is_callable($this->handler)) { + throw new \RuntimeException("The given handler (" . \json_encode($this->handler) . ") is not a callable nor a PostSMTP\\Vendor\\Monolog\\Handler\\HandlerInterface object"); + } + } + /** + * @return array + */ + public function getAcceptedLevels() + { + return \array_flip($this->acceptedLevels); + } + /** + * @param int|string|array $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided + * @param int|string $maxLevel Maximum level or level name to accept, only used if $minLevelOrList is not an array + */ + public function setAcceptedLevels($minLevelOrList = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $maxLevel = \PostSMTP\Vendor\Monolog\Logger::EMERGENCY) + { + if (\is_array($minLevelOrList)) { + $acceptedLevels = \array_map('PostSMTP\\Vendor\\Monolog\\Logger::toMonologLevel', $minLevelOrList); + } else { + $minLevelOrList = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($minLevelOrList); + $maxLevel = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($maxLevel); + $acceptedLevels = \array_values(\array_filter(\PostSMTP\Vendor\Monolog\Logger::getLevels(), function ($level) use($minLevelOrList, $maxLevel) { + return $level >= $minLevelOrList && $level <= $maxLevel; + })); + } + $this->acceptedLevels = \array_flip($acceptedLevels); + } + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return isset($this->acceptedLevels[$record['level']]); + } + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return \false; + } + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + } + $this->getHandler($record)->handle($record); + return \false === $this->bubble; + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $filtered = array(); + foreach ($records as $record) { + if ($this->isHandling($record)) { + $filtered[] = $record; + } + } + if (\count($filtered) > 0) { + $this->getHandler($filtered[\count($filtered) - 1])->handleBatch($filtered); + } + } + /** + * Return the nested handler + * + * If the handler was provided as a factory callable, this will trigger the handler's instantiation. + * + * @return HandlerInterface + */ + public function getHandler(array $record = null) + { + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface) { + $this->handler = \call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + return $this->handler; + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + $this->getHandler()->setFormatter($formatter); + return $this; + } + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->getHandler()->getFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php new file mode 100644 index 0000000..ab78f78 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler\FingersCrossed; + +/** + * Interface for activation strategies for the FingersCrossedHandler. + * + * @author Johannes M. Schmitt + */ +interface ActivationStrategyInterface +{ + /** + * Returns whether the given record activates the handler. + * + * @param array $record + * @return bool + */ + public function isHandlerActivated(array $record); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php new file mode 100644 index 0000000..7ab7810 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler\FingersCrossed; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Channel and Error level based monolog activation strategy. Allows to trigger activation + * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except + * for records of the 'sql' channel; those should trigger activation on level 'WARN'. + * + * Example: + * + * + * $activationStrategy = new ChannelLevelActivationStrategy( + * Logger::CRITICAL, + * array( + * 'request' => Logger::ALERT, + * 'sensitive' => Logger::ERROR, + * ) + * ); + * $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy); + * + * + * @author Mike Meessen + */ +class ChannelLevelActivationStrategy implements \PostSMTP\Vendor\Monolog\Handler\FingersCrossed\ActivationStrategyInterface +{ + private $defaultActionLevel; + private $channelToActionLevel; + /** + * @param int $defaultActionLevel The default action level to be used if the record's category doesn't match any + * @param array $channelToActionLevel An array that maps channel names to action levels. + */ + public function __construct($defaultActionLevel, $channelToActionLevel = array()) + { + $this->defaultActionLevel = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($defaultActionLevel); + $this->channelToActionLevel = \array_map('PostSMTP\\Vendor\\Monolog\\Logger::toMonologLevel', $channelToActionLevel); + } + public function isHandlerActivated(array $record) + { + if (isset($this->channelToActionLevel[$record['channel']])) { + return $record['level'] >= $this->channelToActionLevel[$record['channel']]; + } + return $record['level'] >= $this->defaultActionLevel; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php new file mode 100644 index 0000000..71488e5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler\FingersCrossed; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Error level based activation strategy. + * + * @author Johannes M. Schmitt + */ +class ErrorLevelActivationStrategy implements \PostSMTP\Vendor\Monolog\Handler\FingersCrossed\ActivationStrategyInterface +{ + private $actionLevel; + public function __construct($actionLevel) + { + $this->actionLevel = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($actionLevel); + } + public function isHandlerActivated(array $record) + { + return $record['level'] >= $this->actionLevel; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php new file mode 100644 index 0000000..1e8d03c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php @@ -0,0 +1,183 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; +use PostSMTP\Vendor\Monolog\Handler\FingersCrossed\ActivationStrategyInterface; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\ResettableInterface; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Buffers all records until a certain level is reached + * + * The advantage of this approach is that you don't get any clutter in your log files. + * Only requests which actually trigger an error (or whatever your actionLevel is) will be + * in the logs, but they will contain all records, not only those above the level threshold. + * + * You can find the various activation strategies in the + * Monolog\Handler\FingersCrossed\ namespace. + * + * @author Jordi Boggiano + */ +class FingersCrossedHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractHandler +{ + protected $handler; + protected $activationStrategy; + protected $buffering = \true; + protected $bufferSize; + protected $buffer = array(); + protected $stopBuffering; + protected $passthruLevel; + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $fingersCrossedHandler). + * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action + * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $stopBuffering Whether the handler should stop buffering after being triggered (default true) + * @param int $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered + */ + public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = \true, $stopBuffering = \true, $passthruLevel = null) + { + if (null === $activationStrategy) { + $activationStrategy = new \PostSMTP\Vendor\Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy(\PostSMTP\Vendor\Monolog\Logger::WARNING); + } + // convert simple int activationStrategy to an object + if (!$activationStrategy instanceof \PostSMTP\Vendor\Monolog\Handler\FingersCrossed\ActivationStrategyInterface) { + $activationStrategy = new \PostSMTP\Vendor\Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy($activationStrategy); + } + $this->handler = $handler; + $this->activationStrategy = $activationStrategy; + $this->bufferSize = $bufferSize; + $this->bubble = $bubble; + $this->stopBuffering = $stopBuffering; + if ($passthruLevel !== null) { + $this->passthruLevel = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($passthruLevel); + } + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface && !\is_callable($this->handler)) { + throw new \RuntimeException("The given handler (" . \json_encode($this->handler) . ") is not a callable nor a Monolog\\Handler\\HandlerInterface object"); + } + } + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return \true; + } + /** + * Manually activate this logger regardless of the activation strategy + */ + public function activate() + { + if ($this->stopBuffering) { + $this->buffering = \false; + } + $this->getHandler(\end($this->buffer) ?: null)->handleBatch($this->buffer); + $this->buffer = array(); + } + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + } + if ($this->buffering) { + $this->buffer[] = $record; + if ($this->bufferSize > 0 && \count($this->buffer) > $this->bufferSize) { + \array_shift($this->buffer); + } + if ($this->activationStrategy->isHandlerActivated($record)) { + $this->activate(); + } + } else { + $this->getHandler($record)->handle($record); + } + return \false === $this->bubble; + } + /** + * {@inheritdoc} + */ + public function close() + { + $this->flushBuffer(); + } + public function reset() + { + $this->flushBuffer(); + parent::reset(); + if ($this->getHandler() instanceof \PostSMTP\Vendor\Monolog\ResettableInterface) { + $this->getHandler()->reset(); + } + } + /** + * Clears the buffer without flushing any messages down to the wrapped handler. + * + * It also resets the handler to its initial buffering state. + */ + public function clear() + { + $this->buffer = array(); + $this->reset(); + } + /** + * Resets the state of the handler. Stops forwarding records to the wrapped handler. + */ + private function flushBuffer() + { + if (null !== $this->passthruLevel) { + $level = $this->passthruLevel; + $this->buffer = \array_filter($this->buffer, function ($record) use($level) { + return $record['level'] >= $level; + }); + if (\count($this->buffer) > 0) { + $this->getHandler(\end($this->buffer) ?: null)->handleBatch($this->buffer); + } + } + $this->buffer = array(); + $this->buffering = \true; + } + /** + * Return the nested handler + * + * If the handler was provided as a factory callable, this will trigger the handler's instantiation. + * + * @return HandlerInterface + */ + public function getHandler(array $record = null) + { + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface) { + $this->handler = \call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + return $this->handler; + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + $this->getHandler()->setFormatter($formatter); + return $this; + } + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->getHandler()->getFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php new file mode 100644 index 0000000..3ac51e8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\WildfireFormatter; +/** + * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. + * + * @author Eric Clemmons (@ericclemmons) + */ +class FirePHPHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * WildFire JSON header message format + */ + const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'; + /** + * FirePHP structure for parsing messages & their presentation + */ + const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'; + /** + * Must reference a "known" plugin, otherwise headers won't display in FirePHP + */ + const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3'; + /** + * Header prefix for Wildfire to recognize & parse headers + */ + const HEADER_PREFIX = 'X-Wf'; + /** + * Whether or not Wildfire vendor-specific headers have been generated & sent yet + */ + protected static $initialized = \false; + /** + * Shared static message index between potentially multiple handlers + * @var int + */ + protected static $messageIndex = 1; + protected static $sendHeaders = \true; + /** + * Base header creation function used by init headers & record headers + * + * @param array $meta Wildfire Plugin, Protocol & Structure Indexes + * @param string $message Log message + * @return array Complete header string ready for the client as key and message as value + */ + protected function createHeader(array $meta, $message) + { + $header = \sprintf('%s-%s', self::HEADER_PREFIX, \join('-', $meta)); + return array($header => $message); + } + /** + * Creates message header from record + * + * @see createHeader() + * @param array $record + * @return array + */ + protected function createRecordHeader(array $record) + { + // Wildfire is extensible to support multiple protocols & plugins in a single request, + // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake. + return $this->createHeader(array(1, 1, 1, self::$messageIndex++), $record['formatted']); + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\WildfireFormatter(); + } + /** + * Wildfire initialization headers to enable message parsing + * + * @see createHeader() + * @see sendHeader() + * @return array + */ + protected function getInitHeaders() + { + // Initial payload consists of required headers for Wildfire + return \array_merge($this->createHeader(array('Protocol', 1), self::PROTOCOL_URI), $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI), $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI)); + } + /** + * Send header string to the client + * + * @param string $header + * @param string $content + */ + protected function sendHeader($header, $content) + { + if (!\headers_sent() && self::$sendHeaders) { + \header(\sprintf('%s: %s', $header, $content)); + } + } + /** + * Creates & sends header for a record, ensuring init headers have been sent prior + * + * @see sendHeader() + * @see sendInitHeaders() + * @param array $record + */ + protected function write(array $record) + { + if (!self::$sendHeaders) { + return; + } + // WildFire-specific headers must be sent prior to any messages + if (!self::$initialized) { + self::$initialized = \true; + self::$sendHeaders = $this->headersAccepted(); + if (!self::$sendHeaders) { + return; + } + foreach ($this->getInitHeaders() as $header => $content) { + $this->sendHeader($header, $content); + } + } + $header = $this->createRecordHeader($record); + if (\trim(\current($header)) !== '') { + $this->sendHeader(\key($header), \current($header)); + } + } + /** + * Verifies if the headers are accepted by the current user agent + * + * @return bool + */ + protected function headersAccepted() + { + if (!empty($_SERVER['HTTP_USER_AGENT']) && \preg_match('{\\bFirePHP/\\d+\\.\\d+\\b}', $_SERVER['HTTP_USER_AGENT'])) { + return \true; + } + return isset($_SERVER['HTTP_X_FIREPHP_VERSION']); + } + /** + * BC getter for the sendHeaders property that has been made static + */ + public function __get($property) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property ' . $property); + } + return static::$sendHeaders; + } + /** + * BC setter for the sendHeaders property that has been made static + */ + public function __set($property, $value) + { + if ('sendHeaders' !== $property) { + throw new \InvalidArgumentException('Undefined property ' . $property); + } + static::$sendHeaders = $value; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php new file mode 100644 index 0000000..2560497 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +use PostSMTP\Vendor\Monolog\Logger; +/** + * Sends logs to Fleep.io using Webhook integrations + * + * You'll need a Fleep.io account to use this handler. + * + * @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation + * @author Ando Roots + */ +class FleepHookHandler extends \PostSMTP\Vendor\Monolog\Handler\SocketHandler +{ + const FLEEP_HOST = 'fleep.io'; + const FLEEP_HOOK_URI = '/hook/'; + /** + * @var string Webhook token (specifies the conversation where logs are sent) + */ + protected $token; + /** + * Construct a new Fleep.io Handler. + * + * For instructions on how to create a new web hook in your conversations + * see https://fleep.io/integrations/webhooks/ + * + * @param string $token Webhook token + * @param bool|int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @throws MissingExtensionException + */ + public function __construct($token, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if (!\extension_loaded('openssl')) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler'); + } + $this->token = $token; + $connectionString = 'ssl://' . self::FLEEP_HOST . ':443'; + parent::__construct($connectionString, $level, $bubble); + } + /** + * Returns the default formatter to use with this handler + * + * Overloaded to remove empty context and extra arrays from the end of the log message. + * + * @return LineFormatter + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter(null, null, \true, \true); + } + /** + * Handles a log record + * + * @param array $record + */ + public function write(array $record) + { + parent::write($record); + $this->closeSocket(); + } + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + return $this->buildHeader($content) . $content; + } + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST " . self::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n"; + $header .= "Host: " . self::FLEEP_HOST . "\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . \strlen($content) . "\r\n"; + $header .= "\r\n"; + return $header; + } + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = array('message' => $record['formatted']); + return \http_build_query($dataArray); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php new file mode 100644 index 0000000..90230ca --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +use PostSMTP\Vendor\Monolog\Formatter\FlowdockFormatter; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Sends notifications through the Flowdock push API + * + * This must be configured with a FlowdockFormatter instance via setFormatter() + * + * Notes: + * API token - Flowdock API token + * + * @author Dominik Liebler + * @see https://www.flowdock.com/api/push + */ +class FlowdockHandler extends \PostSMTP\Vendor\Monolog\Handler\SocketHandler +{ + /** + * @var string + */ + protected $apiToken; + /** + * @param string $apiToken + * @param bool|int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * + * @throws MissingExtensionException if OpenSSL is missing + */ + public function __construct($apiToken, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if (!\extension_loaded('openssl')) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler'); + } + parent::__construct('ssl://api.flowdock.com:443', $level, $bubble); + $this->apiToken = $apiToken; + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + if (!$formatter instanceof \PostSMTP\Vendor\Monolog\Formatter\FlowdockFormatter) { + throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\\Formatter\\FlowdockFormatter to function correctly'); + } + return parent::setFormatter($formatter); + } + /** + * Gets the default formatter. + * + * @return FormatterInterface + */ + protected function getDefaultFormatter() + { + throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\\Formatter\\FlowdockFormatter to function correctly'); + } + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + $this->closeSocket(); + } + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + return $this->buildHeader($content) . $content; + } + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + return \PostSMTP\Vendor\Monolog\Utils::jsonEncode($record['formatted']['flowdock']); + } + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n"; + $header .= "Host: api.flowdock.com\r\n"; + $header .= "Content-Type: application/json\r\n"; + $header .= "Content-Length: " . \strlen($content) . "\r\n"; + $header .= "\r\n"; + return $header; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php new file mode 100644 index 0000000..191d1cc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Interface to describe loggers that have a formatter + * + * This interface is present in monolog 1.x to ease forward compatibility. + * + * @author Jordi Boggiano + */ +interface FormattableHandlerInterface +{ + /** + * Sets the formatter. + * + * @param FormatterInterface $formatter + * @return HandlerInterface self + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) : \PostSMTP\Vendor\Monolog\Handler\HandlerInterface; + /** + * Gets the formatter. + * + * @return FormatterInterface + */ + public function getFormatter() : \PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php new file mode 100644 index 0000000..e336d82 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +/** + * Helper trait for implementing FormattableInterface + * + * This trait is present in monolog 1.x to ease forward compatibility. + * + * @author Jordi Boggiano + */ +trait FormattableHandlerTrait +{ + /** + * @var FormatterInterface + */ + protected $formatter; + /** + * {@inheritdoc} + * @suppress PhanTypeMismatchReturn + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) : \PostSMTP\Vendor\Monolog\Handler\HandlerInterface + { + $this->formatter = $formatter; + return $this; + } + /** + * {@inheritdoc} + */ + public function getFormatter() : \PostSMTP\Vendor\Monolog\Formatter\FormatterInterface + { + if (!$this->formatter) { + $this->formatter = $this->getDefaultFormatter(); + } + return $this->formatter; + } + /** + * Gets the default formatter. + * + * Overwrite this if the LineFormatter is not a good default for your handler. + */ + protected function getDefaultFormatter() : \PostSMTP\Vendor\Monolog\Formatter\FormatterInterface + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/GelfHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/GelfHandler.php new file mode 100644 index 0000000..0372b67 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/GelfHandler.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Gelf\IMessagePublisher; +use PostSMTP\Vendor\Gelf\PublisherInterface; +use PostSMTP\Vendor\Gelf\Publisher; +use InvalidArgumentException; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Formatter\GelfMessageFormatter; +/** + * Handler to send messages to a Graylog2 (http://www.graylog2.org) server + * + * @author Matt Lehner + * @author Benjamin Zikarsky + */ +class GelfHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * @var Publisher|PublisherInterface|IMessagePublisher the publisher object that sends the message to the server + */ + protected $publisher; + /** + * @param PublisherInterface|IMessagePublisher|Publisher $publisher a publisher object + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($publisher, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + parent::__construct($level, $bubble); + if (!$publisher instanceof \PostSMTP\Vendor\Gelf\Publisher && !$publisher instanceof \PostSMTP\Vendor\Gelf\IMessagePublisher && !$publisher instanceof \PostSMTP\Vendor\Gelf\PublisherInterface) { + throw new \InvalidArgumentException('Invalid publisher, expected a Gelf\\Publisher, Gelf\\IMessagePublisher or Gelf\\PublisherInterface instance'); + } + $this->publisher = $publisher; + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->publisher->publish($record['formatted']); + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\GelfMessageFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/GroupHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/GroupHandler.php new file mode 100644 index 0000000..f6c8f81 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/GroupHandler.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +use PostSMTP\Vendor\Monolog\ResettableInterface; +/** + * Forwards records to multiple handlers + * + * @author Lenar Lõhmus + */ +class GroupHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractHandler +{ + protected $handlers; + /** + * @param array $handlers Array of Handlers. + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(array $handlers, $bubble = \true) + { + foreach ($handlers as $handler) { + if (!$handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface) { + throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.'); + } + } + $this->handlers = $handlers; + $this->bubble = $bubble; + } + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + foreach ($this->handlers as $handler) { + if ($handler->isHandling($record)) { + return \true; + } + } + return \false; + } + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + } + foreach ($this->handlers as $handler) { + $handler->handle($record); + } + return \false === $this->bubble; + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + if ($this->processors) { + $processed = array(); + foreach ($records as $record) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + $processed[] = $record; + } + $records = $processed; + } + foreach ($this->handlers as $handler) { + $handler->handleBatch($records); + } + } + public function reset() + { + parent::reset(); + foreach ($this->handlers as $handler) { + if ($handler instanceof \PostSMTP\Vendor\Monolog\ResettableInterface) { + $handler->reset(); + } + } + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + foreach ($this->handlers as $handler) { + $handler->setFormatter($formatter); + } + return $this; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HandlerInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HandlerInterface.php new file mode 100644 index 0000000..5706f90 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HandlerInterface.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Interface that all Monolog Handlers must implement + * + * @author Jordi Boggiano + */ +interface HandlerInterface +{ + /** + * Checks whether the given record will be handled by this handler. + * + * This is mostly done for performance reasons, to avoid calling processors for nothing. + * + * Handlers should still check the record levels within handle(), returning false in isHandling() + * is no guarantee that handle() will not be called, and isHandling() might not be called + * for a given record. + * + * @param array $record Partial log record containing only a level key + * + * @return bool + */ + public function isHandling(array $record); + /** + * Handles a record. + * + * All records may be passed to this method, and the handler should discard + * those that it does not want to handle. + * + * The return value of this function controls the bubbling process of the handler stack. + * Unless the bubbling is interrupted (by returning true), the Logger class will keep on + * calling further handlers in the stack with a given log record. + * + * @param array $record The record to handle + * @return bool true means that this handler handled the record, and that bubbling is not permitted. + * false means the record was either not processed or that this handler allows bubbling. + */ + public function handle(array $record); + /** + * Handles a set of records at once. + * + * @param array $records The records to handle (an array of record arrays) + */ + public function handleBatch(array $records); + /** + * Adds a processor in the stack. + * + * @param callable $callback + * @return self + */ + public function pushProcessor($callback); + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + public function popProcessor(); + /** + * Sets the formatter. + * + * @param FormatterInterface $formatter + * @return self + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter); + /** + * Gets the formatter. + * + * @return FormatterInterface + */ + public function getFormatter(); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php new file mode 100644 index 0000000..82f35b7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\ResettableInterface; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * This simple wrapper class can be used to extend handlers functionality. + * + * Example: A custom filtering that can be applied to any handler. + * + * Inherit from this class and override handle() like this: + * + * public function handle(array $record) + * { + * if ($record meets certain conditions) { + * return false; + * } + * return $this->handler->handle($record); + * } + * + * @author Alexey Karapetov + */ +class HandlerWrapper implements \PostSMTP\Vendor\Monolog\Handler\HandlerInterface, \PostSMTP\Vendor\Monolog\ResettableInterface +{ + /** + * @var HandlerInterface + */ + protected $handler; + /** + * HandlerWrapper constructor. + * @param HandlerInterface $handler + */ + public function __construct(\PostSMTP\Vendor\Monolog\Handler\HandlerInterface $handler) + { + $this->handler = $handler; + } + /** + * {@inheritdoc} + */ + public function isHandling(array $record) + { + return $this->handler->isHandling($record); + } + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + return $this->handler->handle($record); + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + return $this->handler->handleBatch($records); + } + /** + * {@inheritdoc} + */ + public function pushProcessor($callback) + { + $this->handler->pushProcessor($callback); + return $this; + } + /** + * {@inheritdoc} + */ + public function popProcessor() + { + return $this->handler->popProcessor(); + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + $this->handler->setFormatter($formatter); + return $this; + } + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->handler->getFormatter(); + } + public function reset() + { + if ($this->handler instanceof \PostSMTP\Vendor\Monolog\ResettableInterface) { + return $this->handler->reset(); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HipChatHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HipChatHandler.php new file mode 100644 index 0000000..7dbf97b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/HipChatHandler.php @@ -0,0 +1,300 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Sends notifications through the hipchat api to a hipchat room + * + * Notes: + * API token - HipChat API token + * Room - HipChat Room Id or name, where messages are sent + * Name - Name used to send the message (from) + * notify - Should the message trigger a notification in the clients + * version - The API version to use (HipChatHandler::API_V1 | HipChatHandler::API_V2) + * + * @author Rafael Dohms + * @see https://www.hipchat.com/docs/api + */ +class HipChatHandler extends \PostSMTP\Vendor\Monolog\Handler\SocketHandler +{ + /** + * Use API version 1 + */ + const API_V1 = 'v1'; + /** + * Use API version v2 + */ + const API_V2 = 'v2'; + /** + * The maximum allowed length for the name used in the "from" field. + */ + const MAXIMUM_NAME_LENGTH = 15; + /** + * The maximum allowed length for the message. + */ + const MAXIMUM_MESSAGE_LENGTH = 9500; + /** + * @var string + */ + private $token; + /** + * @var string + */ + private $room; + /** + * @var string + */ + private $name; + /** + * @var bool + */ + private $notify; + /** + * @var string + */ + private $format; + /** + * @var string + */ + private $host; + /** + * @var string + */ + private $version; + /** + * @param string $token HipChat API Token + * @param string $room The room that should be alerted of the message (Id or Name) + * @param string $name Name used in the "from" field. + * @param bool $notify Trigger a notification in clients or not + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useSSL Whether to connect via SSL. + * @param string $format The format of the messages (default to text, can be set to html if you have html in the messages) + * @param string $host The HipChat server hostname. + * @param string $version The HipChat API version (default HipChatHandler::API_V1) + */ + public function __construct($token, $room, $name = 'Monolog', $notify = \false, $level = \PostSMTP\Vendor\Monolog\Logger::CRITICAL, $bubble = \true, $useSSL = \true, $format = 'text', $host = 'api.hipchat.com', $version = self::API_V1) + { + @\trigger_error('The Monolog\\Handler\\HipChatHandler class is deprecated. You should migrate to Slack and the SlackWebhookHandler / SlackbotHandler, see https://www.atlassian.com/partnerships/slack', \E_USER_DEPRECATED); + if ($version == self::API_V1 && !$this->validateStringLength($name, static::MAXIMUM_NAME_LENGTH)) { + throw new \InvalidArgumentException('The supplied name is too long. HipChat\'s v1 API supports names up to 15 UTF-8 characters.'); + } + $connectionString = $useSSL ? 'ssl://' . $host . ':443' : $host . ':80'; + parent::__construct($connectionString, $level, $bubble); + $this->token = $token; + $this->name = $name; + $this->notify = $notify; + $this->room = $room; + $this->format = $format; + $this->host = $host; + $this->version = $version; + } + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + return $this->buildHeader($content) . $content; + } + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = array('notify' => $this->version == self::API_V1 ? $this->notify ? 1 : 0 : ($this->notify ? 'true' : 'false'), 'message' => $record['formatted'], 'message_format' => $this->format, 'color' => $this->getAlertColor($record['level'])); + if (!$this->validateStringLength($dataArray['message'], static::MAXIMUM_MESSAGE_LENGTH)) { + if (\function_exists('mb_substr')) { + $dataArray['message'] = \mb_substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH) . ' [truncated]'; + } else { + $dataArray['message'] = \substr($dataArray['message'], 0, static::MAXIMUM_MESSAGE_LENGTH) . ' [truncated]'; + } + } + // if we are using the legacy API then we need to send some additional information + if ($this->version == self::API_V1) { + $dataArray['room_id'] = $this->room; + } + // append the sender name if it is set + // always append it if we use the v1 api (it is required in v1) + if ($this->version == self::API_V1 || $this->name !== null) { + $dataArray['from'] = (string) $this->name; + } + return \http_build_query($dataArray); + } + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + if ($this->version == self::API_V1) { + $header = "POST /v1/rooms/message?format=json&auth_token={$this->token} HTTP/1.1\r\n"; + } else { + // needed for rooms with special (spaces, etc) characters in the name + $room = \rawurlencode($this->room); + $header = "POST /v2/room/{$room}/notification?auth_token={$this->token} HTTP/1.1\r\n"; + } + $header .= "Host: {$this->host}\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . \strlen($content) . "\r\n"; + $header .= "\r\n"; + return $header; + } + /** + * Assigns a color to each level of log records. + * + * @param int $level + * @return string + */ + protected function getAlertColor($level) + { + switch (\true) { + case $level >= \PostSMTP\Vendor\Monolog\Logger::ERROR: + return 'red'; + case $level >= \PostSMTP\Vendor\Monolog\Logger::WARNING: + return 'yellow'; + case $level >= \PostSMTP\Vendor\Monolog\Logger::INFO: + return 'green'; + case $level == \PostSMTP\Vendor\Monolog\Logger::DEBUG: + return 'gray'; + default: + return 'yellow'; + } + } + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + $this->finalizeWrite(); + } + /** + * Finalizes the request by reading some bytes and then closing the socket + * + * If we do not read some but close the socket too early, hipchat sometimes + * drops the request entirely. + */ + protected function finalizeWrite() + { + $res = $this->getResource(); + if (\is_resource($res)) { + @\fread($res, 2048); + } + $this->closeSocket(); + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + if (\count($records) == 0) { + return \true; + } + $batchRecords = $this->combineRecords($records); + $handled = \false; + foreach ($batchRecords as $batchRecord) { + if ($this->isHandling($batchRecord)) { + $this->write($batchRecord); + $handled = \true; + } + } + if (!$handled) { + return \false; + } + return \false === $this->bubble; + } + /** + * Combines multiple records into one. Error level of the combined record + * will be the highest level from the given records. Datetime will be taken + * from the first record. + * + * @param array $records + * @return array + */ + private function combineRecords(array $records) + { + $batchRecord = null; + $batchRecords = array(); + $messages = array(); + $formattedMessages = array(); + $level = 0; + $levelName = null; + $datetime = null; + foreach ($records as $record) { + $record = $this->processRecord($record); + if ($record['level'] > $level) { + $level = $record['level']; + $levelName = $record['level_name']; + } + if (null === $datetime) { + $datetime = $record['datetime']; + } + $messages[] = $record['message']; + $messageStr = \implode(\PHP_EOL, $messages); + $formattedMessages[] = $this->getFormatter()->format($record); + $formattedMessageStr = \implode('', $formattedMessages); + $batchRecord = array('message' => $messageStr, 'formatted' => $formattedMessageStr, 'context' => array(), 'extra' => array()); + if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) { + // Pop the last message and implode the remaining messages + $lastMessage = \array_pop($messages); + $lastFormattedMessage = \array_pop($formattedMessages); + $batchRecord['message'] = \implode(\PHP_EOL, $messages); + $batchRecord['formatted'] = \implode('', $formattedMessages); + $batchRecords[] = $batchRecord; + $messages = array($lastMessage); + $formattedMessages = array($lastFormattedMessage); + $batchRecord = null; + } + } + if (null !== $batchRecord) { + $batchRecords[] = $batchRecord; + } + // Set the max level and datetime for all records + foreach ($batchRecords as &$batchRecord) { + $batchRecord = \array_merge($batchRecord, array('level' => $level, 'level_name' => $levelName, 'datetime' => $datetime)); + } + return $batchRecords; + } + /** + * Validates the length of a string. + * + * If the `mb_strlen()` function is available, it will use that, as HipChat + * allows UTF-8 characters. Otherwise, it will fall back to `strlen()`. + * + * Note that this might cause false failures in the specific case of using + * a valid name with less than 16 characters, but 16 or more bytes, on a + * system where `mb_strlen()` is unavailable. + * + * @param string $str + * @param int $length + * + * @return bool + */ + private function validateStringLength($str, $length) + { + if (\function_exists('mb_strlen')) { + return \mb_strlen($str) <= $length; + } + return \strlen($str) <= $length; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php new file mode 100644 index 0000000..fe6cfab --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +/** + * IFTTTHandler uses cURL to trigger IFTTT Maker actions + * + * Register a secret key and trigger/event name at https://ifttt.com/maker + * + * value1 will be the channel from monolog's Logger constructor, + * value2 will be the level name (ERROR, WARNING, ..) + * value3 will be the log record's message + * + * @author Nehal Patel + */ +class IFTTTHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + private $eventName; + private $secretKey; + /** + * @param string $eventName The name of the IFTTT Maker event that should be triggered + * @param string $secretKey A valid IFTTT secret key + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($eventName, $secretKey, $level = \PostSMTP\Vendor\Monolog\Logger::ERROR, $bubble = \true) + { + $this->eventName = $eventName; + $this->secretKey = $secretKey; + parent::__construct($level, $bubble); + } + /** + * {@inheritdoc} + */ + public function write(array $record) + { + $postData = array("value1" => $record["channel"], "value2" => $record["level_name"], "value3" => $record["message"]); + $postString = \PostSMTP\Vendor\Monolog\Utils::jsonEncode($postData); + $ch = \curl_init(); + \curl_setopt($ch, \CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey); + \curl_setopt($ch, \CURLOPT_POST, \true); + \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, \true); + \curl_setopt($ch, \CURLOPT_POSTFIELDS, $postString); + \curl_setopt($ch, \CURLOPT_HTTPHEADER, array("Content-Type: application/json")); + \PostSMTP\Vendor\Monolog\Handler\Curl\Util::execute($ch); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php new file mode 100644 index 0000000..2099dd6 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Inspired on LogEntriesHandler. + * + * @author Robert Kaufmann III + * @author Gabriel Machado + */ +class InsightOpsHandler extends \PostSMTP\Vendor\Monolog\Handler\SocketHandler +{ + /** + * @var string + */ + protected $logToken; + /** + * @param string $token Log token supplied by InsightOps + * @param string $region Region where InsightOps account is hosted. Could be 'us' or 'eu'. + * @param bool $useSSL Whether or not SSL encryption should be used + * @param int $level The minimum logging level to trigger this handler + * @param bool $bubble Whether or not messages that are handled should bubble up the stack. + * + * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing + */ + public function __construct($token, $region = 'us', $useSSL = \true, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if ($useSSL && !\extension_loaded('openssl')) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for InsightOpsHandler'); + } + $endpoint = $useSSL ? 'ssl://' . $region . '.data.logs.insight.rapid7.com:443' : $region . '.data.logs.insight.rapid7.com:80'; + parent::__construct($endpoint, $level, $bubble); + $this->logToken = $token; + } + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + return $this->logToken . ' ' . $record['formatted']; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php new file mode 100644 index 0000000..b919e6e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * @author Robert Kaufmann III + */ +class LogEntriesHandler extends \PostSMTP\Vendor\Monolog\Handler\SocketHandler +{ + /** + * @var string + */ + protected $logToken; + /** + * @param string $token Log token supplied by LogEntries + * @param bool $useSSL Whether or not SSL encryption should be used. + * @param int $level The minimum logging level to trigger this handler + * @param bool $bubble Whether or not messages that are handled should bubble up the stack. + * + * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing + */ + public function __construct($token, $useSSL = \true, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $host = 'data.logentries.com') + { + if ($useSSL && !\extension_loaded('openssl')) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler'); + } + $endpoint = $useSSL ? 'ssl://' . $host . ':443' : $host . ':80'; + parent::__construct($endpoint, $level, $bubble); + $this->logToken = $token; + } + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + return $this->logToken . ' ' . $record['formatted']; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/LogglyHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/LogglyHandler.php new file mode 100644 index 0000000..ca26265 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/LogglyHandler.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Formatter\LogglyFormatter; +/** + * Sends errors to Loggly. + * + * @author Przemek Sobstel + * @author Adam Pancutt + * @author Gregory Barchard + */ +class LogglyHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + const HOST = 'logs-01.loggly.com'; + const ENDPOINT_SINGLE = 'inputs'; + const ENDPOINT_BATCH = 'bulk'; + protected $token; + protected $tag = array(); + public function __construct($token, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if (!\extension_loaded('curl')) { + throw new \LogicException('The curl extension is needed to use the LogglyHandler'); + } + $this->token = $token; + parent::__construct($level, $bubble); + } + public function setTag($tag) + { + $tag = !empty($tag) ? $tag : array(); + $this->tag = \is_array($tag) ? $tag : array($tag); + } + public function addTag($tag) + { + if (!empty($tag)) { + $tag = \is_array($tag) ? $tag : array($tag); + $this->tag = \array_unique(\array_merge($this->tag, $tag)); + } + } + protected function write(array $record) + { + $this->send($record["formatted"], self::ENDPOINT_SINGLE); + } + public function handleBatch(array $records) + { + $level = $this->level; + $records = \array_filter($records, function ($record) use($level) { + return $record['level'] >= $level; + }); + if ($records) { + $this->send($this->getFormatter()->formatBatch($records), self::ENDPOINT_BATCH); + } + } + protected function send($data, $endpoint) + { + $url = \sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token); + $headers = array('Content-Type: application/json'); + if (!empty($this->tag)) { + $headers[] = 'X-LOGGLY-TAG: ' . \implode(',', $this->tag); + } + $ch = \curl_init(); + \curl_setopt($ch, \CURLOPT_URL, $url); + \curl_setopt($ch, \CURLOPT_POST, \true); + \curl_setopt($ch, \CURLOPT_POSTFIELDS, $data); + \curl_setopt($ch, \CURLOPT_HTTPHEADER, $headers); + \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, \true); + \PostSMTP\Vendor\Monolog\Handler\Curl\Util::execute($ch); + } + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\LogglyFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MailHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MailHandler.php new file mode 100644 index 0000000..797bac7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MailHandler.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +/** + * Base class for all mail handlers + * + * @author Gyula Sallai + */ +abstract class MailHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $messages = array(); + foreach ($records as $record) { + if ($record['level'] < $this->level) { + continue; + } + $messages[] = $this->processRecord($record); + } + if (!empty($messages)) { + $this->send((string) $this->getFormatter()->formatBatch($messages), $messages); + } + } + /** + * Send a mail with the given content + * + * @param string $content formatted email body to be sent + * @param array $records the array of log records that formed this content + */ + protected abstract function send($content, array $records); + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->send((string) $record['formatted'], array($record)); + } + protected function getHighestRecord(array $records) + { + $highestRecord = null; + foreach ($records as $record) { + if ($highestRecord === null || $highestRecord['level'] < $record['level']) { + $highestRecord = $record; + } + } + return $highestRecord; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MandrillHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MandrillHandler.php new file mode 100644 index 0000000..f4b8e8e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MandrillHandler.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * MandrillHandler uses cURL to send the emails to the Mandrill API + * + * @author Adam Nicholson + */ +class MandrillHandler extends \PostSMTP\Vendor\Monolog\Handler\MailHandler +{ + protected $message; + protected $apiKey; + /** + * @param string $apiKey A valid Mandrill API key + * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($apiKey, $message, $level = \PostSMTP\Vendor\Monolog\Logger::ERROR, $bubble = \true) + { + parent::__construct($level, $bubble); + if (!$message instanceof \PostSMTP\Vendor\Swift_Message && \is_callable($message)) { + $message = \call_user_func($message); + } + if (!$message instanceof \PostSMTP\Vendor\Swift_Message) { + throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it'); + } + $this->message = $message; + $this->apiKey = $apiKey; + } + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $message = clone $this->message; + $message->setBody($content); + if (\version_compare(\PostSMTP\Vendor\Swift::VERSION, '6.0.0', '>=')) { + $message->setDate(new \DateTimeImmutable()); + } else { + $message->setDate(\time()); + } + $ch = \curl_init(); + \curl_setopt($ch, \CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json'); + \curl_setopt($ch, \CURLOPT_POST, 1); + \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, 1); + \curl_setopt($ch, \CURLOPT_POSTFIELDS, \http_build_query(array('key' => $this->apiKey, 'raw_message' => (string) $message, 'async' => \false))); + \PostSMTP\Vendor\Monolog\Handler\Curl\Util::execute($ch); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php new file mode 100644 index 0000000..f5ea44f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +/** + * Exception can be thrown if an extension for an handler is missing + * + * @author Christian Bergau + */ +class MissingExtensionException extends \Exception +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php new file mode 100644 index 0000000..27dfa97 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter; +/** + * Logs to a MongoDB database. + * + * usage example: + * + * $log = new Logger('application'); + * $mongodb = new MongoDBHandler(new \Mongo("mongodb://localhost:27017"), "logs", "prod"); + * $log->pushHandler($mongodb); + * + * @author Thomas Tourlourat + */ +class MongoDBHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + protected $mongoCollection; + public function __construct($mongo, $database, $collection, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo || $mongo instanceof \PostSMTP\Vendor\MongoDB\Client)) { + throw new \InvalidArgumentException('MongoClient, Mongo or MongoDB\\Client instance required'); + } + $this->mongoCollection = $mongo->selectCollection($database, $collection); + parent::__construct($level, $bubble); + } + protected function write(array $record) + { + if ($this->mongoCollection instanceof \PostSMTP\Vendor\MongoDB\Collection) { + $this->mongoCollection->insertOne($record["formatted"]); + } else { + $this->mongoCollection->save($record["formatted"]); + } + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php new file mode 100644 index 0000000..13de1b4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php @@ -0,0 +1,161 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +/** + * NativeMailerHandler uses the mail() function to send the emails + * + * @author Christophe Coevoet + * @author Mark Garrett + */ +class NativeMailerHandler extends \PostSMTP\Vendor\Monolog\Handler\MailHandler +{ + /** + * The email addresses to which the message will be sent + * @var array + */ + protected $to; + /** + * The subject of the email + * @var string + */ + protected $subject; + /** + * Optional headers for the message + * @var array + */ + protected $headers = array(); + /** + * Optional parameters for the message + * @var array + */ + protected $parameters = array(); + /** + * The wordwrap length for the message + * @var int + */ + protected $maxColumnWidth; + /** + * The Content-type for the message + * @var string + */ + protected $contentType = 'text/plain'; + /** + * The encoding for the message + * @var string + */ + protected $encoding = 'utf-8'; + /** + * @param string|array $to The receiver of the mail + * @param string $subject The subject of the mail + * @param string $from The sender of the mail + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $maxColumnWidth The maximum column width that the message lines will have + */ + public function __construct($to, $subject, $from, $level = \PostSMTP\Vendor\Monolog\Logger::ERROR, $bubble = \true, $maxColumnWidth = 70) + { + parent::__construct($level, $bubble); + $this->to = \is_array($to) ? $to : array($to); + $this->subject = $subject; + $this->addHeader(\sprintf('From: %s', $from)); + $this->maxColumnWidth = $maxColumnWidth; + } + /** + * Add headers to the message + * + * @param string|array $headers Custom added headers + * @return self + */ + public function addHeader($headers) + { + foreach ((array) $headers as $header) { + if (\strpos($header, "\n") !== \false || \strpos($header, "\r") !== \false) { + throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons'); + } + $this->headers[] = $header; + } + return $this; + } + /** + * Add parameters to the message + * + * @param string|array $parameters Custom added parameters + * @return self + */ + public function addParameter($parameters) + { + $this->parameters = \array_merge($this->parameters, (array) $parameters); + return $this; + } + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $content = \wordwrap($content, $this->maxColumnWidth); + $headers = \ltrim(\implode("\r\n", $this->headers) . "\r\n", "\r\n"); + $headers .= 'Content-type: ' . $this->getContentType() . '; charset=' . $this->getEncoding() . "\r\n"; + if ($this->getContentType() == 'text/html' && \false === \strpos($headers, 'MIME-Version:')) { + $headers .= 'MIME-Version: 1.0' . "\r\n"; + } + $subject = $this->subject; + if ($records) { + $subjectFormatter = new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter($this->subject); + $subject = $subjectFormatter->format($this->getHighestRecord($records)); + } + $parameters = \implode(' ', $this->parameters); + foreach ($this->to as $to) { + \mail($to, $subject, $content, $headers, $parameters); + } + } + /** + * @return string $contentType + */ + public function getContentType() + { + return $this->contentType; + } + /** + * @return string $encoding + */ + public function getEncoding() + { + return $this->encoding; + } + /** + * @param string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML + * messages. + * @return self + */ + public function setContentType($contentType) + { + if (\strpos($contentType, "\n") !== \false || \strpos($contentType, "\r") !== \false) { + throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection'); + } + $this->contentType = $contentType; + return $this; + } + /** + * @param string $encoding + * @return self + */ + public function setEncoding($encoding) + { + if (\strpos($encoding, "\n") !== \false || \strpos($encoding, "\r") !== \false) { + throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection'); + } + $this->encoding = $encoding; + return $this; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php new file mode 100644 index 0000000..284be91 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php @@ -0,0 +1,179 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +use PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter; +/** + * Class to record a log on a NewRelic application. + * Enabling New Relic High Security mode may prevent capture of useful information. + * + * This handler requires a NormalizerFormatter to function and expects an array in $record['formatted'] + * + * @see https://docs.newrelic.com/docs/agents/php-agent + * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security + */ +class NewRelicHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * Name of the New Relic application that will receive logs from this handler. + * + * @var string + */ + protected $appName; + /** + * Name of the current transaction + * + * @var string + */ + protected $transactionName; + /** + * Some context and extra data is passed into the handler as arrays of values. Do we send them as is + * (useful if we are using the API), or explode them for display on the NewRelic RPM website? + * + * @var bool + */ + protected $explodeArrays; + /** + * {@inheritDoc} + * + * @param string $appName + * @param bool $explodeArrays + * @param string $transactionName + */ + public function __construct($level = \PostSMTP\Vendor\Monolog\Logger::ERROR, $bubble = \true, $appName = null, $explodeArrays = \false, $transactionName = null) + { + parent::__construct($level, $bubble); + $this->appName = $appName; + $this->explodeArrays = $explodeArrays; + $this->transactionName = $transactionName; + } + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + if (!$this->isNewRelicEnabled()) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler'); + } + if ($appName = $this->getAppName($record['context'])) { + $this->setNewRelicAppName($appName); + } + if ($transactionName = $this->getTransactionName($record['context'])) { + $this->setNewRelicTransactionName($transactionName); + unset($record['formatted']['context']['transaction_name']); + } + if (isset($record['context']['exception']) && ($record['context']['exception'] instanceof \Exception || \PHP_VERSION_ID >= 70000 && $record['context']['exception'] instanceof \Throwable)) { + \newrelic_notice_error($record['message'], $record['context']['exception']); + unset($record['formatted']['context']['exception']); + } else { + \newrelic_notice_error($record['message']); + } + if (isset($record['formatted']['context']) && \is_array($record['formatted']['context'])) { + foreach ($record['formatted']['context'] as $key => $parameter) { + if (\is_array($parameter) && $this->explodeArrays) { + foreach ($parameter as $paramKey => $paramValue) { + $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue); + } + } else { + $this->setNewRelicParameter('context_' . $key, $parameter); + } + } + } + if (isset($record['formatted']['extra']) && \is_array($record['formatted']['extra'])) { + foreach ($record['formatted']['extra'] as $key => $parameter) { + if (\is_array($parameter) && $this->explodeArrays) { + foreach ($parameter as $paramKey => $paramValue) { + $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue); + } + } else { + $this->setNewRelicParameter('extra_' . $key, $parameter); + } + } + } + } + /** + * Checks whether the NewRelic extension is enabled in the system. + * + * @return bool + */ + protected function isNewRelicEnabled() + { + return \extension_loaded('newrelic'); + } + /** + * Returns the appname where this log should be sent. Each log can override the default appname, set in this + * handler's constructor, by providing the appname in it's context. + * + * @param array $context + * @return null|string + */ + protected function getAppName(array $context) + { + if (isset($context['appname'])) { + return $context['appname']; + } + return $this->appName; + } + /** + * Returns the name of the current transaction. Each log can override the default transaction name, set in this + * handler's constructor, by providing the transaction_name in it's context + * + * @param array $context + * + * @return null|string + */ + protected function getTransactionName(array $context) + { + if (isset($context['transaction_name'])) { + return $context['transaction_name']; + } + return $this->transactionName; + } + /** + * Sets the NewRelic application that should receive this log. + * + * @param string $appName + */ + protected function setNewRelicAppName($appName) + { + \newrelic_set_appname($appName); + } + /** + * Overwrites the name of the current transaction + * + * @param string $transactionName + */ + protected function setNewRelicTransactionName($transactionName) + { + \newrelic_name_transaction($transactionName); + } + /** + * @param string $key + * @param mixed $value + */ + protected function setNewRelicParameter($key, $value) + { + if (null === $value || \is_scalar($value)) { + \newrelic_add_custom_parameter($key, $value); + } else { + \newrelic_add_custom_parameter($key, \PostSMTP\Vendor\Monolog\Utils::jsonEncode($value, null, \true)); + } + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NullHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NullHandler.php new file mode 100644 index 0000000..eeabc23 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/NullHandler.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Blackhole + * + * Any record it can handle will be thrown away. This can be used + * to put on top of an existing stack to override it temporarily. + * + * @author Jordi Boggiano + */ +class NullHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractHandler +{ + /** + * @param int $level The minimum logging level at which this handler will be triggered + */ + public function __construct($level = \PostSMTP\Vendor\Monolog\Logger::DEBUG) + { + parent::__construct($level, \false); + } + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($record['level'] < $this->level) { + return \false; + } + return \true; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php new file mode 100644 index 0000000..c28a13e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php @@ -0,0 +1,234 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use Exception; +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +use PostSMTP\Vendor\PhpConsole\Connector; +use PostSMTP\Vendor\PhpConsole\Handler; +use PostSMTP\Vendor\PhpConsole\Helper; +/** + * Monolog handler for Google Chrome extension "PHP Console" + * + * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely + * + * Usage: + * 1. Install Google Chrome extension https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef + * 2. See overview https://github.com/barbushin/php-console#overview + * 3. Install PHP Console library https://github.com/barbushin/php-console#installation + * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png) + * + * $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler())); + * \Monolog\ErrorHandler::register($logger); + * echo $undefinedVar; + * $logger->addDebug('SELECT * FROM users', array('db', 'time' => 0.012)); + * PC::debug($_SERVER); // PHP Console debugger for any type of vars + * + * @author Sergey Barbushin https://www.linkedin.com/in/barbushin + */ +class PHPConsoleHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + private $options = array( + 'enabled' => \true, + // bool Is PHP Console server enabled + 'classesPartialsTraceIgnore' => array('PostSMTP\\Vendor\\Monolog\\'), + // array Hide calls of classes started with... + 'debugTagsKeysInContext' => array(0, 'tag'), + // bool Is PHP Console server enabled + 'useOwnErrorsHandler' => \false, + // bool Enable errors handling + 'useOwnExceptionsHandler' => \false, + // bool Enable exceptions handling + 'sourcesBasePath' => null, + // string Base path of all project sources to strip in errors source paths + 'registerHelper' => \true, + // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s') + 'serverEncoding' => null, + // string|null Server internal encoding + 'headersLimit' => null, + // int|null Set headers size limit for your web-server + 'password' => null, + // string|null Protect PHP Console connection by password + 'enableSslOnlyMode' => \false, + // bool Force connection by SSL for clients with PHP Console installed + 'ipMasks' => array(), + // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1') + 'enableEvalListener' => \false, + // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required) + 'dumperDetectCallbacks' => \false, + // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings + 'dumperLevelLimit' => 5, + // int Maximum dumped vars array or object nested dump level + 'dumperItemsCountLimit' => 100, + // int Maximum dumped var same level array items or object properties number + 'dumperItemSizeLimit' => 5000, + // int Maximum length of any string or dumped array item + 'dumperDumpSizeLimit' => 500000, + // int Maximum approximate size of dumped vars result formatted in JSON + 'detectDumpTraceAndSource' => \false, + // bool Autodetect and append trace data to debug + 'dataStorage' => null, + ); + /** @var Connector */ + private $connector; + /** + * @param array $options See \Monolog\Handler\PHPConsoleHandler::$options for more details + * @param Connector|null $connector Instance of \PhpConsole\Connector class (optional) + * @param int $level + * @param bool $bubble + * @throws Exception + */ + public function __construct(array $options = array(), \PostSMTP\Vendor\PhpConsole\Connector $connector = null, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if (!\class_exists('PostSMTP\\Vendor\\PhpConsole\\Connector')) { + throw new \Exception('PHP Console library not found. See https://github.com/barbushin/php-console#installation'); + } + parent::__construct($level, $bubble); + $this->options = $this->initOptions($options); + $this->connector = $this->initConnector($connector); + } + private function initOptions(array $options) + { + $wrongOptions = \array_diff(\array_keys($options), \array_keys($this->options)); + if ($wrongOptions) { + throw new \Exception('Unknown options: ' . \implode(', ', $wrongOptions)); + } + return \array_replace($this->options, $options); + } + private function initConnector(\PostSMTP\Vendor\PhpConsole\Connector $connector = null) + { + if (!$connector) { + if ($this->options['dataStorage']) { + \PostSMTP\Vendor\PhpConsole\Connector::setPostponeStorage($this->options['dataStorage']); + } + $connector = \PostSMTP\Vendor\PhpConsole\Connector::getInstance(); + } + if ($this->options['registerHelper'] && !\PostSMTP\Vendor\PhpConsole\Helper::isRegistered()) { + \PostSMTP\Vendor\PhpConsole\Helper::register(); + } + if ($this->options['enabled'] && $connector->isActiveClient()) { + if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) { + $handler = \PostSMTP\Vendor\PhpConsole\Handler::getInstance(); + $handler->setHandleErrors($this->options['useOwnErrorsHandler']); + $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']); + $handler->start(); + } + if ($this->options['sourcesBasePath']) { + $connector->setSourcesBasePath($this->options['sourcesBasePath']); + } + if ($this->options['serverEncoding']) { + $connector->setServerEncoding($this->options['serverEncoding']); + } + if ($this->options['password']) { + $connector->setPassword($this->options['password']); + } + if ($this->options['enableSslOnlyMode']) { + $connector->enableSslOnlyMode(); + } + if ($this->options['ipMasks']) { + $connector->setAllowedIpMasks($this->options['ipMasks']); + } + if ($this->options['headersLimit']) { + $connector->setHeadersLimit($this->options['headersLimit']); + } + if ($this->options['detectDumpTraceAndSource']) { + $connector->getDebugDispatcher()->detectTraceAndSource = \true; + } + $dumper = $connector->getDumper(); + $dumper->levelLimit = $this->options['dumperLevelLimit']; + $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit']; + $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit']; + $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit']; + $dumper->detectCallbacks = $this->options['dumperDetectCallbacks']; + if ($this->options['enableEvalListener']) { + $connector->startEvalRequestsListener(); + } + } + return $connector; + } + public function getConnector() + { + return $this->connector; + } + public function getOptions() + { + return $this->options; + } + public function handle(array $record) + { + if ($this->options['enabled'] && $this->connector->isActiveClient()) { + return parent::handle($record); + } + return !$this->bubble; + } + /** + * Writes the record down to the log of the implementing handler + * + * @param array $record + * @return void + */ + protected function write(array $record) + { + if ($record['level'] < \PostSMTP\Vendor\Monolog\Logger::NOTICE) { + $this->handleDebugRecord($record); + } elseif (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) { + $this->handleExceptionRecord($record); + } else { + $this->handleErrorRecord($record); + } + } + private function handleDebugRecord(array $record) + { + $tags = $this->getRecordTags($record); + $message = $record['message']; + if ($record['context']) { + $message .= ' ' . \PostSMTP\Vendor\Monolog\Utils::jsonEncode($this->connector->getDumper()->dump(\array_filter($record['context'])), null, \true); + } + $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']); + } + private function handleExceptionRecord(array $record) + { + $this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']); + } + private function handleErrorRecord(array $record) + { + $context = $record['context']; + $this->connector->getErrorsDispatcher()->dispatchError(isset($context['code']) ? $context['code'] : null, isset($context['message']) ? $context['message'] : $record['message'], isset($context['file']) ? $context['file'] : null, isset($context['line']) ? $context['line'] : null, $this->options['classesPartialsTraceIgnore']); + } + private function getRecordTags(array &$record) + { + $tags = null; + if (!empty($record['context'])) { + $context =& $record['context']; + foreach ($this->options['debugTagsKeysInContext'] as $key) { + if (!empty($context[$key])) { + $tags = $context[$key]; + if ($key === 0) { + \array_shift($context); + } else { + unset($context[$key]); + } + break; + } + } + } + return $tags ?: \strtolower($record['level_name']); + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter('%message%'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php new file mode 100644 index 0000000..e827a5c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Processor\ProcessorInterface; +/** + * Interface to describe loggers that have processors + * + * This interface is present in monolog 1.x to ease forward compatibility. + * + * @author Jordi Boggiano + */ +interface ProcessableHandlerInterface +{ + /** + * Adds a processor in the stack. + * + * @param ProcessorInterface|callable $callback + * @return HandlerInterface self + */ + public function pushProcessor($callback) : \PostSMTP\Vendor\Monolog\Handler\HandlerInterface; + /** + * Removes the processor on top of the stack and returns it. + * + * @throws \LogicException In case the processor stack is empty + * @return callable + */ + public function popProcessor() : callable; +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php new file mode 100644 index 0000000..802008d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\ResettableInterface; +/** + * Helper trait for implementing ProcessableInterface + * + * This trait is present in monolog 1.x to ease forward compatibility. + * + * @author Jordi Boggiano + */ +trait ProcessableHandlerTrait +{ + /** + * @var callable[] + */ + protected $processors = []; + /** + * {@inheritdoc} + * @suppress PhanTypeMismatchReturn + */ + public function pushProcessor($callback) : \PostSMTP\Vendor\Monolog\Handler\HandlerInterface + { + \array_unshift($this->processors, $callback); + return $this; + } + /** + * {@inheritdoc} + */ + public function popProcessor() : callable + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + return \array_shift($this->processors); + } + /** + * Processes a record. + */ + protected function processRecord(array $record) : array + { + foreach ($this->processors as $processor) { + $record = $processor($record); + } + return $record; + } + protected function resetProcessors() : void + { + foreach ($this->processors as $processor) { + if ($processor instanceof \PostSMTP\Vendor\Monolog\ResettableInterface) { + $processor->reset(); + } + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PsrHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PsrHandler.php new file mode 100644 index 0000000..720f3a0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PsrHandler.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Psr\Log\LoggerInterface; +/** + * Proxies log messages to an existing PSR-3 compliant logger. + * + * @author Michael Moussa + */ +class PsrHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractHandler +{ + /** + * PSR-3 compliant logger + * + * @var LoggerInterface + */ + protected $logger; + /** + * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\PostSMTP\Vendor\Psr\Log\LoggerInterface $logger, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + parent::__construct($level, $bubble); + $this->logger = $logger; + } + /** + * {@inheritDoc} + */ + public function handle(array $record) + { + if (!$this->isHandling($record)) { + return \false; + } + $this->logger->log(\strtolower($record['level_name']), $record['message'], $record['context']); + return \false === $this->bubble; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PushoverHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PushoverHandler.php new file mode 100644 index 0000000..c66ffd0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/PushoverHandler.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Sends notifications through the pushover api to mobile phones + * + * @author Sebastian Göttschkes + * @see https://www.pushover.net/api + */ +class PushoverHandler extends \PostSMTP\Vendor\Monolog\Handler\SocketHandler +{ + private $token; + private $users; + private $title; + private $user; + private $retry; + private $expire; + private $highPriorityLevel; + private $emergencyLevel; + private $useFormattedMessage = \false; + /** + * All parameters that can be sent to Pushover + * @see https://pushover.net/api + * @var array + */ + private $parameterNames = array('token' => \true, 'user' => \true, 'message' => \true, 'device' => \true, 'title' => \true, 'url' => \true, 'url_title' => \true, 'priority' => \true, 'timestamp' => \true, 'sound' => \true, 'retry' => \true, 'expire' => \true, 'callback' => \true); + /** + * Sounds the api supports by default + * @see https://pushover.net/api#sounds + * @var array + */ + private $sounds = array('pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', 'persistent', 'echo', 'updown', 'none'); + /** + * @param string $token Pushover api token + * @param string|array $users Pushover user id or array of ids the message will be sent to + * @param string $title Title sent to the Pushover API + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useSSL Whether to connect via SSL. Required when pushing messages to users that are not + * the pushover.net app owner. OpenSSL is required for this option. + * @param int $highPriorityLevel The minimum logging level at which this handler will start + * sending "high priority" requests to the Pushover API + * @param int $emergencyLevel The minimum logging level at which this handler will start + * sending "emergency" requests to the Pushover API + * @param int $retry The retry parameter specifies how often (in seconds) the Pushover servers will send the same notification to the user. + * @param int $expire The expire parameter specifies how many seconds your notification will continue to be retried for (every retry seconds). + */ + public function __construct($token, $users, $title = null, $level = \PostSMTP\Vendor\Monolog\Logger::CRITICAL, $bubble = \true, $useSSL = \true, $highPriorityLevel = \PostSMTP\Vendor\Monolog\Logger::CRITICAL, $emergencyLevel = \PostSMTP\Vendor\Monolog\Logger::EMERGENCY, $retry = 30, $expire = 25200) + { + $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80'; + parent::__construct($connectionString, $level, $bubble); + $this->token = $token; + $this->users = (array) $users; + $this->title = $title ?: \gethostname(); + $this->highPriorityLevel = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($highPriorityLevel); + $this->emergencyLevel = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($emergencyLevel); + $this->retry = $retry; + $this->expire = $expire; + } + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + return $this->buildHeader($content) . $content; + } + private function buildContent($record) + { + // Pushover has a limit of 512 characters on title and message combined. + $maxMessageLength = 512 - \strlen($this->title); + $message = $this->useFormattedMessage ? $record['formatted'] : $record['message']; + $message = \substr($message, 0, $maxMessageLength); + $timestamp = $record['datetime']->getTimestamp(); + $dataArray = array('token' => $this->token, 'user' => $this->user, 'message' => $message, 'title' => $this->title, 'timestamp' => $timestamp); + if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) { + $dataArray['priority'] = 2; + $dataArray['retry'] = $this->retry; + $dataArray['expire'] = $this->expire; + } elseif (isset($record['level']) && $record['level'] >= $this->highPriorityLevel) { + $dataArray['priority'] = 1; + } + // First determine the available parameters + $context = \array_intersect_key($record['context'], $this->parameterNames); + $extra = \array_intersect_key($record['extra'], $this->parameterNames); + // Least important info should be merged with subsequent info + $dataArray = \array_merge($extra, $context, $dataArray); + // Only pass sounds that are supported by the API + if (isset($dataArray['sound']) && !\in_array($dataArray['sound'], $this->sounds)) { + unset($dataArray['sound']); + } + return \http_build_query($dataArray); + } + private function buildHeader($content) + { + $header = "POST /1/messages.json HTTP/1.1\r\n"; + $header .= "Host: api.pushover.net\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . \strlen($content) . "\r\n"; + $header .= "\r\n"; + return $header; + } + protected function write(array $record) + { + foreach ($this->users as $user) { + $this->user = $user; + parent::write($record); + $this->closeSocket(); + } + $this->user = null; + } + public function setHighPriorityLevel($value) + { + $this->highPriorityLevel = $value; + } + public function setEmergencyLevel($value) + { + $this->emergencyLevel = $value; + } + /** + * Use the formatted message? + * @param bool $value + */ + public function useFormattedMessage($value) + { + $this->useFormattedMessage = (bool) $value; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RavenHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RavenHandler.php new file mode 100644 index 0000000..34d30f1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RavenHandler.php @@ -0,0 +1,197 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Raven_Client; +/** + * Handler to send messages to a Sentry (https://github.com/getsentry/sentry) server + * using sentry-php (https://github.com/getsentry/sentry-php) + * + * @author Marc Abramowitz + */ +class RavenHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * Translates Monolog log levels to Raven log levels. + */ + protected $logLevels = array(\PostSMTP\Vendor\Monolog\Logger::DEBUG => \PostSMTP\Vendor\Raven_Client::DEBUG, \PostSMTP\Vendor\Monolog\Logger::INFO => \PostSMTP\Vendor\Raven_Client::INFO, \PostSMTP\Vendor\Monolog\Logger::NOTICE => \PostSMTP\Vendor\Raven_Client::INFO, \PostSMTP\Vendor\Monolog\Logger::WARNING => \PostSMTP\Vendor\Raven_Client::WARNING, \PostSMTP\Vendor\Monolog\Logger::ERROR => \PostSMTP\Vendor\Raven_Client::ERROR, \PostSMTP\Vendor\Monolog\Logger::CRITICAL => \PostSMTP\Vendor\Raven_Client::FATAL, \PostSMTP\Vendor\Monolog\Logger::ALERT => \PostSMTP\Vendor\Raven_Client::FATAL, \PostSMTP\Vendor\Monolog\Logger::EMERGENCY => \PostSMTP\Vendor\Raven_Client::FATAL); + /** + * @var string should represent the current version of the calling + * software. Can be any string (git commit, version number) + */ + protected $release; + /** + * @var Raven_Client the client object that sends the message to the server + */ + protected $ravenClient; + /** + * @var FormatterInterface The formatter to use for the logs generated via handleBatch() + */ + protected $batchFormatter; + /** + * @param Raven_Client $ravenClient + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\PostSMTP\Vendor\Raven_Client $ravenClient, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + @\trigger_error('The Monolog\\Handler\\RavenHandler class is deprecated. You should rather upgrade to the sentry/sentry 2.x and use Sentry\\Monolog\\Handler, see https://github.com/getsentry/sentry-php/blob/master/src/Monolog/Handler.php', \E_USER_DEPRECATED); + parent::__construct($level, $bubble); + $this->ravenClient = $ravenClient; + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + $level = $this->level; + // filter records based on their level + $records = \array_filter($records, function ($record) use($level) { + return $record['level'] >= $level; + }); + if (!$records) { + return; + } + // the record with the highest severity is the "main" one + $record = \array_reduce($records, function ($highest, $record) { + if (null === $highest || $record['level'] > $highest['level']) { + return $record; + } + return $highest; + }); + // the other ones are added as a context item + $logs = array(); + foreach ($records as $r) { + $logs[] = $this->processRecord($r); + } + if ($logs) { + $record['context']['logs'] = (string) $this->getBatchFormatter()->formatBatch($logs); + } + $this->handle($record); + } + /** + * Sets the formatter for the logs generated by handleBatch(). + * + * @param FormatterInterface $formatter + */ + public function setBatchFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + $this->batchFormatter = $formatter; + } + /** + * Gets the formatter for the logs generated by handleBatch(). + * + * @return FormatterInterface + */ + public function getBatchFormatter() + { + if (!$this->batchFormatter) { + $this->batchFormatter = $this->getDefaultBatchFormatter(); + } + return $this->batchFormatter; + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $previousUserContext = \false; + $options = array(); + $options['level'] = $this->logLevels[$record['level']]; + $options['tags'] = array(); + if (!empty($record['extra']['tags'])) { + $options['tags'] = \array_merge($options['tags'], $record['extra']['tags']); + unset($record['extra']['tags']); + } + if (!empty($record['context']['tags'])) { + $options['tags'] = \array_merge($options['tags'], $record['context']['tags']); + unset($record['context']['tags']); + } + if (!empty($record['context']['fingerprint'])) { + $options['fingerprint'] = $record['context']['fingerprint']; + unset($record['context']['fingerprint']); + } + if (!empty($record['context']['logger'])) { + $options['logger'] = $record['context']['logger']; + unset($record['context']['logger']); + } else { + $options['logger'] = $record['channel']; + } + foreach ($this->getExtraParameters() as $key) { + foreach (array('extra', 'context') as $source) { + if (!empty($record[$source][$key])) { + $options[$key] = $record[$source][$key]; + unset($record[$source][$key]); + } + } + } + if (!empty($record['context'])) { + $options['extra']['context'] = $record['context']; + if (!empty($record['context']['user'])) { + $previousUserContext = $this->ravenClient->context->user; + $this->ravenClient->user_context($record['context']['user']); + unset($options['extra']['context']['user']); + } + } + if (!empty($record['extra'])) { + $options['extra']['extra'] = $record['extra']; + } + if (!empty($this->release) && !isset($options['release'])) { + $options['release'] = $this->release; + } + if (isset($record['context']['exception']) && ($record['context']['exception'] instanceof \Exception || \PHP_VERSION_ID >= 70000 && $record['context']['exception'] instanceof \Throwable)) { + $options['message'] = $record['formatted']; + $this->ravenClient->captureException($record['context']['exception'], $options); + } else { + $this->ravenClient->captureMessage($record['formatted'], array(), $options); + } + if ($previousUserContext !== \false) { + $this->ravenClient->user_context($previousUserContext); + } + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter('[%channel%] %message%'); + } + /** + * Gets the default formatter for the logs generated by handleBatch(). + * + * @return FormatterInterface + */ + protected function getDefaultBatchFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter(); + } + /** + * Gets extra parameters supported by Raven that can be found in "extra" and "context" + * + * @return array + */ + protected function getExtraParameters() + { + return array('contexts', 'checksum', 'release', 'event_id'); + } + /** + * @param string $value + * @return self + */ + public function setRelease($value) + { + $this->release = $value; + return $this; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RedisHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RedisHandler.php new file mode 100644 index 0000000..d252fc3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RedisHandler.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +use PostSMTP\Vendor\Monolog\Logger; +/** + * Logs to a Redis key using rpush + * + * usage example: + * + * $log = new Logger('application'); + * $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod"); + * $log->pushHandler($redis); + * + * @author Thomas Tourlourat + */ +class RedisHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + private $redisClient; + private $redisKey; + protected $capSize; + /** + * @param \Predis\Client|\Redis $redis The redis instance + * @param string $key The key name to push records to + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|false $capSize Number of entries to limit list size to + */ + public function __construct($redis, $key, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $capSize = \false) + { + if (!($redis instanceof \PostSMTP\Vendor\Predis\Client || $redis instanceof \Redis)) { + throw new \InvalidArgumentException('Predis\\Client or Redis instance required'); + } + $this->redisClient = $redis; + $this->redisKey = $key; + $this->capSize = $capSize; + parent::__construct($level, $bubble); + } + /** + * {@inheritDoc} + */ + protected function write(array $record) + { + if ($this->capSize) { + $this->writeCapped($record); + } else { + $this->redisClient->rpush($this->redisKey, $record["formatted"]); + } + } + /** + * Write and cap the collection + * Writes the record to the redis list and caps its + * + * @param array $record associative record array + * @return void + */ + protected function writeCapped(array $record) + { + if ($this->redisClient instanceof \Redis) { + $mode = \defined('\\Redis::MULTI') ? \Redis::MULTI : 1; + $this->redisClient->multi($mode)->rpush($this->redisKey, $record["formatted"])->ltrim($this->redisKey, -$this->capSize, -1)->exec(); + } else { + $redisKey = $this->redisKey; + $capSize = $this->capSize; + $this->redisClient->transaction(function ($tx) use($record, $redisKey, $capSize) { + $tx->rpush($redisKey, $record["formatted"]); + $tx->ltrim($redisKey, -$capSize, -1); + }); + } + } + /** + * {@inheritDoc} + */ + protected function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RollbarHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RollbarHandler.php new file mode 100644 index 0000000..3c4b8ac --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RollbarHandler.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\RollbarNotifier; +use Exception; +use PostSMTP\Vendor\Monolog\Logger; +/** + * Sends errors to Rollbar + * + * If the context data contains a `payload` key, that is used as an array + * of payload options to RollbarNotifier's report_message/report_exception methods. + * + * Rollbar's context info will contain the context + extra keys from the log record + * merged, and then on top of that a few keys: + * + * - level (rollbar level name) + * - monolog_level (monolog level name, raw level, as rollbar only has 5 but monolog 8) + * - channel + * - datetime (unix timestamp) + * + * @author Paul Statezny + */ +class RollbarHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * Rollbar notifier + * + * @var RollbarNotifier + */ + protected $rollbarNotifier; + protected $levelMap = array(\PostSMTP\Vendor\Monolog\Logger::DEBUG => 'debug', \PostSMTP\Vendor\Monolog\Logger::INFO => 'info', \PostSMTP\Vendor\Monolog\Logger::NOTICE => 'info', \PostSMTP\Vendor\Monolog\Logger::WARNING => 'warning', \PostSMTP\Vendor\Monolog\Logger::ERROR => 'error', \PostSMTP\Vendor\Monolog\Logger::CRITICAL => 'critical', \PostSMTP\Vendor\Monolog\Logger::ALERT => 'critical', \PostSMTP\Vendor\Monolog\Logger::EMERGENCY => 'critical'); + /** + * Records whether any log records have been added since the last flush of the rollbar notifier + * + * @var bool + */ + private $hasRecords = \false; + protected $initialized = \false; + /** + * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\PostSMTP\Vendor\RollbarNotifier $rollbarNotifier, $level = \PostSMTP\Vendor\Monolog\Logger::ERROR, $bubble = \true) + { + $this->rollbarNotifier = $rollbarNotifier; + parent::__construct($level, $bubble); + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (!$this->initialized) { + // __destructor() doesn't get called on Fatal errors + \register_shutdown_function(array($this, 'close')); + $this->initialized = \true; + } + $context = $record['context']; + $payload = array(); + if (isset($context['payload'])) { + $payload = $context['payload']; + unset($context['payload']); + } + $context = \array_merge($context, $record['extra'], array('level' => $this->levelMap[$record['level']], 'monolog_level' => $record['level_name'], 'channel' => $record['channel'], 'datetime' => $record['datetime']->format('U'))); + if (isset($context['exception']) && $context['exception'] instanceof \Exception) { + $payload['level'] = $context['level']; + $exception = $context['exception']; + unset($context['exception']); + $this->rollbarNotifier->report_exception($exception, $context, $payload); + } else { + $this->rollbarNotifier->report_message($record['message'], $context['level'], $context, $payload); + } + $this->hasRecords = \true; + } + public function flush() + { + if ($this->hasRecords) { + $this->rollbarNotifier->flush(); + $this->hasRecords = \false; + } + } + /** + * {@inheritdoc} + */ + public function close() + { + $this->flush(); + } + /** + * {@inheritdoc} + */ + public function reset() + { + $this->flush(); + parent::reset(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php new file mode 100644 index 0000000..a3aa06a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +/** + * Stores logs to files that are rotated every day and a limited number of files are kept. + * + * This rotation is only intended to be used as a workaround. Using logrotate to + * handle the rotation is strongly encouraged when you can use it. + * + * @author Christophe Coevoet + * @author Jordi Boggiano + */ +class RotatingFileHandler extends \PostSMTP\Vendor\Monolog\Handler\StreamHandler +{ + const FILE_PER_DAY = 'Y-m-d'; + const FILE_PER_MONTH = 'Y-m'; + const FILE_PER_YEAR = 'Y'; + protected $filename; + protected $maxFiles; + protected $mustRotate; + protected $nextRotation; + protected $filenameFormat; + protected $dateFormat; + /** + * @param string $filename + * @param int $maxFiles The maximal amount of files to keep (0 means unlimited) + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) + * @param bool $useLocking Try to lock log file before doing any writes + */ + public function __construct($filename, $maxFiles = 0, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $filePermission = null, $useLocking = \false) + { + $this->filename = \PostSMTP\Vendor\Monolog\Utils::canonicalizePath($filename); + $this->maxFiles = (int) $maxFiles; + $this->nextRotation = new \DateTime('tomorrow'); + $this->filenameFormat = '{filename}-{date}'; + $this->dateFormat = 'Y-m-d'; + parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking); + } + /** + * {@inheritdoc} + */ + public function close() + { + parent::close(); + if (\true === $this->mustRotate) { + $this->rotate(); + } + } + /** + * {@inheritdoc} + */ + public function reset() + { + parent::reset(); + if (\true === $this->mustRotate) { + $this->rotate(); + } + } + public function setFilenameFormat($filenameFormat, $dateFormat) + { + if (!\preg_match('{^Y(([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) { + \trigger_error('Invalid date format - format must be one of ' . 'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") ' . 'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the ' . 'date formats using slashes, underscores and/or dots instead of dashes.', \E_USER_DEPRECATED); + } + if (\substr_count($filenameFormat, '{date}') === 0) { + \trigger_error('Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.', \E_USER_DEPRECATED); + } + $this->filenameFormat = $filenameFormat; + $this->dateFormat = $dateFormat; + $this->url = $this->getTimedFilename(); + $this->close(); + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + // on the first record written, if the log is new, we should rotate (once per day) + if (null === $this->mustRotate) { + $this->mustRotate = !\file_exists($this->url); + } + if ($this->nextRotation < $record['datetime']) { + $this->mustRotate = \true; + $this->close(); + } + parent::write($record); + } + /** + * Rotates the files. + */ + protected function rotate() + { + // update filename + $this->url = $this->getTimedFilename(); + $this->nextRotation = new \DateTime('tomorrow'); + // skip GC of old logs if files are unlimited + if (0 === $this->maxFiles) { + return; + } + $logFiles = \glob($this->getGlobPattern()); + if ($this->maxFiles >= \count($logFiles)) { + // no files to remove + return; + } + // Sorting the files by name to remove the older ones + \usort($logFiles, function ($a, $b) { + return \strcmp($b, $a); + }); + foreach (\array_slice($logFiles, $this->maxFiles) as $file) { + if (\is_writable($file)) { + // suppress errors here as unlink() might fail if two processes + // are cleaning up/rotating at the same time + \set_error_handler(function ($errno, $errstr, $errfile, $errline) { + }); + \unlink($file); + \restore_error_handler(); + } + } + $this->mustRotate = \false; + } + protected function getTimedFilename() + { + $fileInfo = \pathinfo($this->filename); + $timedFilename = \str_replace(array('{filename}', '{date}'), array($fileInfo['filename'], \date($this->dateFormat)), $fileInfo['dirname'] . '/' . $this->filenameFormat); + if (!empty($fileInfo['extension'])) { + $timedFilename .= '.' . $fileInfo['extension']; + } + return $timedFilename; + } + protected function getGlobPattern() + { + $fileInfo = \pathinfo($this->filename); + $glob = \str_replace(array('{filename}', '{date}'), array($fileInfo['filename'], '[0-9][0-9][0-9][0-9]*'), $fileInfo['dirname'] . '/' . $this->filenameFormat); + if (!empty($fileInfo['extension'])) { + $glob .= '.' . $fileInfo['extension']; + } + return $glob; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SamplingHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SamplingHandler.php new file mode 100644 index 0000000..6365f96 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SamplingHandler.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Sampling handler + * + * A sampled event stream can be useful for logging high frequency events in + * a production environment where you only need an idea of what is happening + * and are not concerned with capturing every occurrence. Since the decision to + * handle or not handle a particular event is determined randomly, the + * resulting sampled log is not guaranteed to contain 1/N of the events that + * occurred in the application, but based on the Law of large numbers, it will + * tend to be close to this ratio with a large number of attempts. + * + * @author Bryan Davis + * @author Kunal Mehta + */ +class SamplingHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractHandler +{ + /** + * @var callable|HandlerInterface $handler + */ + protected $handler; + /** + * @var int $factor + */ + protected $factor; + /** + * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $samplingHandler). + * @param int $factor Sample factor + */ + public function __construct($handler, $factor) + { + parent::__construct(); + $this->handler = $handler; + $this->factor = $factor; + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface && !\is_callable($this->handler)) { + throw new \RuntimeException("The given handler (" . \json_encode($this->handler) . ") is not a callable nor a Monolog\\Handler\\HandlerInterface object"); + } + } + public function isHandling(array $record) + { + return $this->getHandler($record)->isHandling($record); + } + public function handle(array $record) + { + if ($this->isHandling($record) && \mt_rand(1, $this->factor) === 1) { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + } + $this->getHandler($record)->handle($record); + } + return \false === $this->bubble; + } + /** + * Return the nested handler + * + * If the handler was provided as a factory callable, this will trigger the handler's instantiation. + * + * @return HandlerInterface + */ + public function getHandler(array $record = null) + { + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface) { + $this->handler = \call_user_func($this->handler, $record, $this); + if (!$this->handler instanceof \PostSMTP\Vendor\Monolog\Handler\HandlerInterface) { + throw new \RuntimeException("The factory callable should return a HandlerInterface"); + } + } + return $this->handler; + } + /** + * {@inheritdoc} + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + $this->getHandler()->setFormatter($formatter); + return $this; + } + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->getHandler()->getFormatter(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php new file mode 100644 index 0000000..00cbd8d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php @@ -0,0 +1,239 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler\Slack; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +use PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +/** + * Slack record utility helping to log to Slack webhooks or API. + * + * @author Greg Kedzierski + * @author Haralan Dobrev + * @see https://api.slack.com/incoming-webhooks + * @see https://api.slack.com/docs/message-attachments + */ +class SlackRecord +{ + const COLOR_DANGER = 'danger'; + const COLOR_WARNING = 'warning'; + const COLOR_GOOD = 'good'; + const COLOR_DEFAULT = '#e3e4e6'; + /** + * Slack channel (encoded ID or name) + * @var string|null + */ + private $channel; + /** + * Name of a bot + * @var string|null + */ + private $username; + /** + * User icon e.g. 'ghost', 'http://example.com/user.png' + * @var string + */ + private $userIcon; + /** + * Whether the message should be added to Slack as attachment (plain text otherwise) + * @var bool + */ + private $useAttachment; + /** + * Whether the the context/extra messages added to Slack as attachments are in a short style + * @var bool + */ + private $useShortAttachment; + /** + * Whether the attachment should include context and extra data + * @var bool + */ + private $includeContextAndExtra; + /** + * Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2'] + * @var array + */ + private $excludeFields; + /** + * @var FormatterInterface + */ + private $formatter; + /** + * @var NormalizerFormatter + */ + private $normalizerFormatter; + public function __construct($channel = null, $username = null, $useAttachment = \true, $userIcon = null, $useShortAttachment = \false, $includeContextAndExtra = \false, array $excludeFields = array(), \PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter = null) + { + $this->channel = $channel; + $this->username = $username; + $this->userIcon = \trim($userIcon, ':'); + $this->useAttachment = $useAttachment; + $this->useShortAttachment = $useShortAttachment; + $this->includeContextAndExtra = $includeContextAndExtra; + $this->excludeFields = $excludeFields; + $this->formatter = $formatter; + if ($this->includeContextAndExtra) { + $this->normalizerFormatter = new \PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter(); + } + } + public function getSlackData(array $record) + { + $dataArray = array(); + $record = $this->excludeFields($record); + if ($this->username) { + $dataArray['username'] = $this->username; + } + if ($this->channel) { + $dataArray['channel'] = $this->channel; + } + if ($this->formatter && !$this->useAttachment) { + $message = $this->formatter->format($record); + } else { + $message = $record['message']; + } + if ($this->useAttachment) { + $attachment = array('fallback' => $message, 'text' => $message, 'color' => $this->getAttachmentColor($record['level']), 'fields' => array(), 'mrkdwn_in' => array('fields'), 'ts' => $record['datetime']->getTimestamp()); + if ($this->useShortAttachment) { + $attachment['title'] = $record['level_name']; + } else { + $attachment['title'] = 'Message'; + $attachment['fields'][] = $this->generateAttachmentField('Level', $record['level_name']); + } + if ($this->includeContextAndExtra) { + foreach (array('extra', 'context') as $key) { + if (empty($record[$key])) { + continue; + } + if ($this->useShortAttachment) { + $attachment['fields'][] = $this->generateAttachmentField($key, $record[$key]); + } else { + // Add all extra fields as individual fields in attachment + $attachment['fields'] = \array_merge($attachment['fields'], $this->generateAttachmentFields($record[$key])); + } + } + } + $dataArray['attachments'] = array($attachment); + } else { + $dataArray['text'] = $message; + } + if ($this->userIcon) { + if (\filter_var($this->userIcon, \FILTER_VALIDATE_URL)) { + $dataArray['icon_url'] = $this->userIcon; + } else { + $dataArray['icon_emoji'] = ":{$this->userIcon}:"; + } + } + return $dataArray; + } + /** + * Returned a Slack message attachment color associated with + * provided level. + * + * @param int $level + * @return string + */ + public function getAttachmentColor($level) + { + switch (\true) { + case $level >= \PostSMTP\Vendor\Monolog\Logger::ERROR: + return self::COLOR_DANGER; + case $level >= \PostSMTP\Vendor\Monolog\Logger::WARNING: + return self::COLOR_WARNING; + case $level >= \PostSMTP\Vendor\Monolog\Logger::INFO: + return self::COLOR_GOOD; + default: + return self::COLOR_DEFAULT; + } + } + /** + * Stringifies an array of key/value pairs to be used in attachment fields + * + * @param array $fields + * + * @return string + */ + public function stringify($fields) + { + $normalized = $this->normalizerFormatter->format($fields); + $prettyPrintFlag = \defined('JSON_PRETTY_PRINT') ? \JSON_PRETTY_PRINT : 128; + $flags = 0; + if (\PHP_VERSION_ID >= 50400) { + $flags = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE; + } + $hasSecondDimension = \count(\array_filter($normalized, 'is_array')); + $hasNonNumericKeys = !\count(\array_filter(\array_keys($normalized), 'is_numeric')); + return $hasSecondDimension || $hasNonNumericKeys ? \PostSMTP\Vendor\Monolog\Utils::jsonEncode($normalized, $prettyPrintFlag | $flags) : \PostSMTP\Vendor\Monolog\Utils::jsonEncode($normalized, $flags); + } + /** + * Sets the formatter + * + * @param FormatterInterface $formatter + */ + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + $this->formatter = $formatter; + } + /** + * Generates attachment field + * + * @param string $title + * @param string|array $value + * + * @return array + */ + private function generateAttachmentField($title, $value) + { + $value = \is_array($value) ? \sprintf('```%s```', $this->stringify($value)) : $value; + return array('title' => \ucfirst($title), 'value' => $value, 'short' => \false); + } + /** + * Generates a collection of attachment fields from array + * + * @param array $data + * + * @return array + */ + private function generateAttachmentFields(array $data) + { + $fields = array(); + foreach ($this->normalizerFormatter->format($data) as $key => $value) { + $fields[] = $this->generateAttachmentField($key, $value); + } + return $fields; + } + /** + * Get a copy of record with fields excluded according to $this->excludeFields + * + * @param array $record + * + * @return array + */ + private function excludeFields(array $record) + { + foreach ($this->excludeFields as $field) { + $keys = \explode('.', $field); + $node =& $record; + $lastKey = \end($keys); + foreach ($keys as $key) { + if (!isset($node[$key])) { + break; + } + if ($lastKey === $key) { + unset($node[$key]); + break; + } + $node =& $node[$key]; + } + } + return $record; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackHandler.php new file mode 100644 index 0000000..c2d3a3a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackHandler.php @@ -0,0 +1,178 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +use PostSMTP\Vendor\Monolog\Handler\Slack\SlackRecord; +/** + * Sends notifications through Slack API + * + * @author Greg Kedzierski + * @see https://api.slack.com/ + */ +class SlackHandler extends \PostSMTP\Vendor\Monolog\Handler\SocketHandler +{ + /** + * Slack API token + * @var string + */ + private $token; + /** + * Instance of the SlackRecord util class preparing data for Slack API. + * @var SlackRecord + */ + private $slackRecord; + /** + * @param string $token Slack API token + * @param string $channel Slack channel (encoded ID or name) + * @param string|null $username Name of a bot + * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) + * @param string|null $iconEmoji The emoji name to use (or null) + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style + * @param bool $includeContextAndExtra Whether the attachment should include context and extra data + * @param array $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2'] + * @throws MissingExtensionException If no OpenSSL PHP extension configured + */ + public function __construct($token, $channel, $username = null, $useAttachment = \true, $iconEmoji = null, $level = \PostSMTP\Vendor\Monolog\Logger::CRITICAL, $bubble = \true, $useShortAttachment = \false, $includeContextAndExtra = \false, array $excludeFields = array()) + { + if (!\extension_loaded('openssl')) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler'); + } + parent::__construct('ssl://slack.com:443', $level, $bubble); + $this->slackRecord = new \PostSMTP\Vendor\Monolog\Handler\Slack\SlackRecord($channel, $username, $useAttachment, $iconEmoji, $useShortAttachment, $includeContextAndExtra, $excludeFields, $this->formatter); + $this->token = $token; + } + public function getSlackRecord() + { + return $this->slackRecord; + } + public function getToken() + { + return $this->token; + } + /** + * {@inheritdoc} + * + * @param array $record + * @return string + */ + protected function generateDataStream($record) + { + $content = $this->buildContent($record); + return $this->buildHeader($content) . $content; + } + /** + * Builds the body of API call + * + * @param array $record + * @return string + */ + private function buildContent($record) + { + $dataArray = $this->prepareContentData($record); + return \http_build_query($dataArray); + } + /** + * Prepares content data + * + * @param array $record + * @return array + */ + protected function prepareContentData($record) + { + $dataArray = $this->slackRecord->getSlackData($record); + $dataArray['token'] = $this->token; + if (!empty($dataArray['attachments'])) { + $dataArray['attachments'] = \PostSMTP\Vendor\Monolog\Utils::jsonEncode($dataArray['attachments']); + } + return $dataArray; + } + /** + * Builds the header of the API Call + * + * @param string $content + * @return string + */ + private function buildHeader($content) + { + $header = "POST /api/chat.postMessage HTTP/1.1\r\n"; + $header .= "Host: slack.com\r\n"; + $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; + $header .= "Content-Length: " . \strlen($content) . "\r\n"; + $header .= "\r\n"; + return $header; + } + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + parent::write($record); + $this->finalizeWrite(); + } + /** + * Finalizes the request by reading some bytes and then closing the socket + * + * If we do not read some but close the socket too early, slack sometimes + * drops the request entirely. + */ + protected function finalizeWrite() + { + $res = $this->getResource(); + if (\is_resource($res)) { + @\fread($res, 2048); + } + $this->closeSocket(); + } + /** + * Returned a Slack message attachment color associated with + * provided level. + * + * @param int $level + * @return string + * @deprecated Use underlying SlackRecord instead + */ + protected function getAttachmentColor($level) + { + \trigger_error('SlackHandler::getAttachmentColor() is deprecated. Use underlying SlackRecord instead.', \E_USER_DEPRECATED); + return $this->slackRecord->getAttachmentColor($level); + } + /** + * Stringifies an array of key/value pairs to be used in attachment fields + * + * @param array $fields + * @return string + * @deprecated Use underlying SlackRecord instead + */ + protected function stringify($fields) + { + \trigger_error('SlackHandler::stringify() is deprecated. Use underlying SlackRecord instead.', \E_USER_DEPRECATED); + return $this->slackRecord->stringify($fields); + } + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + parent::setFormatter($formatter); + $this->slackRecord->setFormatter($formatter); + return $this; + } + public function getFormatter() + { + $formatter = parent::getFormatter(); + $this->slackRecord->setFormatter($formatter); + return $formatter; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php new file mode 100644 index 0000000..e0f99d8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +use PostSMTP\Vendor\Monolog\Handler\Slack\SlackRecord; +/** + * Sends notifications through Slack Webhooks + * + * @author Haralan Dobrev + * @see https://api.slack.com/incoming-webhooks + */ +class SlackWebhookHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * Slack Webhook token + * @var string + */ + private $webhookUrl; + /** + * Instance of the SlackRecord util class preparing data for Slack API. + * @var SlackRecord + */ + private $slackRecord; + /** + * @param string $webhookUrl Slack Webhook URL + * @param string|null $channel Slack channel (encoded ID or name) + * @param string|null $username Name of a bot + * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) + * @param string|null $iconEmoji The emoji name to use (or null) + * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style + * @param bool $includeContextAndExtra Whether the attachment should include context and extra data + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param array $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2'] + */ + public function __construct($webhookUrl, $channel = null, $username = null, $useAttachment = \true, $iconEmoji = null, $useShortAttachment = \false, $includeContextAndExtra = \false, $level = \PostSMTP\Vendor\Monolog\Logger::CRITICAL, $bubble = \true, array $excludeFields = array()) + { + parent::__construct($level, $bubble); + $this->webhookUrl = $webhookUrl; + $this->slackRecord = new \PostSMTP\Vendor\Monolog\Handler\Slack\SlackRecord($channel, $username, $useAttachment, $iconEmoji, $useShortAttachment, $includeContextAndExtra, $excludeFields, $this->formatter); + } + public function getSlackRecord() + { + return $this->slackRecord; + } + public function getWebhookUrl() + { + return $this->webhookUrl; + } + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + $postData = $this->slackRecord->getSlackData($record); + $postString = \PostSMTP\Vendor\Monolog\Utils::jsonEncode($postData); + $ch = \curl_init(); + $options = array(\CURLOPT_URL => $this->webhookUrl, \CURLOPT_POST => \true, \CURLOPT_RETURNTRANSFER => \true, \CURLOPT_HTTPHEADER => array('Content-type: application/json'), \CURLOPT_POSTFIELDS => $postString); + if (\defined('CURLOPT_SAFE_UPLOAD')) { + $options[\CURLOPT_SAFE_UPLOAD] = \true; + } + \curl_setopt_array($ch, $options); + \PostSMTP\Vendor\Monolog\Handler\Curl\Util::execute($ch); + } + public function setFormatter(\PostSMTP\Vendor\Monolog\Formatter\FormatterInterface $formatter) + { + parent::setFormatter($formatter); + $this->slackRecord->setFormatter($formatter); + return $this; + } + public function getFormatter() + { + $formatter = parent::getFormatter(); + $this->slackRecord->setFormatter($formatter); + return $formatter; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackbotHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackbotHandler.php new file mode 100644 index 0000000..adb9dab --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SlackbotHandler.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Sends notifications through Slack's Slackbot + * + * @author Haralan Dobrev + * @see https://slack.com/apps/A0F81R8ET-slackbot + * @deprecated According to Slack the API used on this handler it is deprecated. + * Therefore this handler will be removed on 2.x + * Slack suggests to use webhooks instead. Please contact slack for more information. + */ +class SlackbotHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * The slug of the Slack team + * @var string + */ + private $slackTeam; + /** + * Slackbot token + * @var string + */ + private $token; + /** + * Slack channel name + * @var string + */ + private $channel; + /** + * @param string $slackTeam Slack team slug + * @param string $token Slackbot token + * @param string $channel Slack channel (encoded ID or name) + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($slackTeam, $token, $channel, $level = \PostSMTP\Vendor\Monolog\Logger::CRITICAL, $bubble = \true) + { + @\trigger_error('SlackbotHandler is deprecated and will be removed on 2.x', \E_USER_DEPRECATED); + parent::__construct($level, $bubble); + $this->slackTeam = $slackTeam; + $this->token = $token; + $this->channel = $channel; + } + /** + * {@inheritdoc} + * + * @param array $record + */ + protected function write(array $record) + { + $slackbotUrl = \sprintf('https://%s.slack.com/services/hooks/slackbot?token=%s&channel=%s', $this->slackTeam, $this->token, $this->channel); + $ch = \curl_init(); + \curl_setopt($ch, \CURLOPT_URL, $slackbotUrl); + \curl_setopt($ch, \CURLOPT_POST, \true); + \curl_setopt($ch, \CURLOPT_RETURNTRANSFER, \true); + \curl_setopt($ch, \CURLOPT_POSTFIELDS, $record['message']); + \PostSMTP\Vendor\Monolog\Handler\Curl\Util::execute($ch); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SocketHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SocketHandler.php new file mode 100644 index 0000000..df0ba17 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SocketHandler.php @@ -0,0 +1,344 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Stores to any socket - uses fsockopen() or pfsockopen(). + * + * @author Pablo de Leon Belloc + * @see http://php.net/manual/en/function.fsockopen.php + */ +class SocketHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + private $connectionString; + private $connectionTimeout; + private $resource; + private $timeout = 0; + private $writingTimeout = 10; + private $lastSentBytes = null; + private $chunkSize = null; + private $persistent = \false; + private $errno; + private $errstr; + private $lastWritingAt; + /** + * @param string $connectionString Socket connection string + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct($connectionString, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + parent::__construct($level, $bubble); + $this->connectionString = $connectionString; + $this->connectionTimeout = (float) \ini_get('default_socket_timeout'); + } + /** + * Connect (if necessary) and write to the socket + * + * @param array $record + * + * @throws \UnexpectedValueException + * @throws \RuntimeException + */ + protected function write(array $record) + { + $this->connectIfNotConnected(); + $data = $this->generateDataStream($record); + $this->writeToSocket($data); + } + /** + * We will not close a PersistentSocket instance so it can be reused in other requests. + */ + public function close() + { + if (!$this->isPersistent()) { + $this->closeSocket(); + } + } + /** + * Close socket, if open + */ + public function closeSocket() + { + if (\is_resource($this->resource)) { + \fclose($this->resource); + $this->resource = null; + } + } + /** + * Set socket connection to nbe persistent. It only has effect before the connection is initiated. + * + * @param bool $persistent + */ + public function setPersistent($persistent) + { + $this->persistent = (bool) $persistent; + } + /** + * Set connection timeout. Only has effect before we connect. + * + * @param float $seconds + * + * @see http://php.net/manual/en/function.fsockopen.php + */ + public function setConnectionTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->connectionTimeout = (float) $seconds; + } + /** + * Set write timeout. Only has effect before we connect. + * + * @param float $seconds + * + * @see http://php.net/manual/en/function.stream-set-timeout.php + */ + public function setTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->timeout = (float) $seconds; + } + /** + * Set writing timeout. Only has effect during connection in the writing cycle. + * + * @param float $seconds 0 for no timeout + */ + public function setWritingTimeout($seconds) + { + $this->validateTimeout($seconds); + $this->writingTimeout = (float) $seconds; + } + /** + * Set chunk size. Only has effect during connection in the writing cycle. + * + * @param float $bytes + */ + public function setChunkSize($bytes) + { + $this->chunkSize = $bytes; + } + /** + * Get current connection string + * + * @return string + */ + public function getConnectionString() + { + return $this->connectionString; + } + /** + * Get persistent setting + * + * @return bool + */ + public function isPersistent() + { + return $this->persistent; + } + /** + * Get current connection timeout setting + * + * @return float + */ + public function getConnectionTimeout() + { + return $this->connectionTimeout; + } + /** + * Get current in-transfer timeout + * + * @return float + */ + public function getTimeout() + { + return $this->timeout; + } + /** + * Get current local writing timeout + * + * @return float + */ + public function getWritingTimeout() + { + return $this->writingTimeout; + } + /** + * Get current chunk size + * + * @return float + */ + public function getChunkSize() + { + return $this->chunkSize; + } + /** + * Check to see if the socket is currently available. + * + * UDP might appear to be connected but might fail when writing. See http://php.net/fsockopen for details. + * + * @return bool + */ + public function isConnected() + { + return \is_resource($this->resource) && !\feof($this->resource); + // on TCP - other party can close connection. + } + /** + * Wrapper to allow mocking + */ + protected function pfsockopen() + { + return @\pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + /** + * Wrapper to allow mocking + */ + protected function fsockopen() + { + return @\fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); + } + /** + * Wrapper to allow mocking + * + * @see http://php.net/manual/en/function.stream-set-timeout.php + */ + protected function streamSetTimeout() + { + $seconds = \floor($this->timeout); + $microseconds = \round(($this->timeout - $seconds) * 1000000.0); + return \stream_set_timeout($this->resource, $seconds, $microseconds); + } + /** + * Wrapper to allow mocking + * + * @see http://php.net/manual/en/function.stream-set-chunk-size.php + */ + protected function streamSetChunkSize() + { + return \stream_set_chunk_size($this->resource, $this->chunkSize); + } + /** + * Wrapper to allow mocking + */ + protected function fwrite($data) + { + return @\fwrite($this->resource, $data); + } + /** + * Wrapper to allow mocking + */ + protected function streamGetMetadata() + { + return \stream_get_meta_data($this->resource); + } + private function validateTimeout($value) + { + $ok = \filter_var($value, \FILTER_VALIDATE_FLOAT); + if ($ok === \false || $value < 0) { + throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got {$value})"); + } + } + private function connectIfNotConnected() + { + if ($this->isConnected()) { + return; + } + $this->connect(); + } + protected function generateDataStream($record) + { + return (string) $record['formatted']; + } + /** + * @return resource|null + */ + protected function getResource() + { + return $this->resource; + } + private function connect() + { + $this->createSocketResource(); + $this->setSocketTimeout(); + $this->setStreamChunkSize(); + } + private function createSocketResource() + { + if ($this->isPersistent()) { + $resource = $this->pfsockopen(); + } else { + $resource = $this->fsockopen(); + } + if (!$resource) { + throw new \UnexpectedValueException("Failed connecting to {$this->connectionString} ({$this->errno}: {$this->errstr})"); + } + $this->resource = $resource; + } + private function setSocketTimeout() + { + if (!$this->streamSetTimeout()) { + throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()"); + } + } + private function setStreamChunkSize() + { + if ($this->chunkSize && !$this->streamSetChunkSize()) { + throw new \UnexpectedValueException("Failed setting chunk size with stream_set_chunk_size()"); + } + } + private function writeToSocket($data) + { + $length = \strlen($data); + $sent = 0; + $this->lastSentBytes = $sent; + while ($this->isConnected() && $sent < $length) { + if (0 == $sent) { + $chunk = $this->fwrite($data); + } else { + $chunk = $this->fwrite(\substr($data, $sent)); + } + if ($chunk === \false) { + throw new \RuntimeException("Could not write to socket"); + } + $sent += $chunk; + $socketInfo = $this->streamGetMetadata(); + if ($socketInfo['timed_out']) { + throw new \RuntimeException("Write timed-out"); + } + if ($this->writingIsTimedOut($sent)) { + throw new \RuntimeException("Write timed-out, no data sent for `{$this->writingTimeout}` seconds, probably we got disconnected (sent {$sent} of {$length})"); + } + } + if (!$this->isConnected() && $sent < $length) { + throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent {$sent} of {$length})"); + } + } + private function writingIsTimedOut($sent) + { + $writingTimeout = (int) \floor($this->writingTimeout); + if (0 === $writingTimeout) { + return \false; + } + if ($sent !== $this->lastSentBytes) { + $this->lastWritingAt = \time(); + $this->lastSentBytes = $sent; + return \false; + } else { + \usleep(100); + } + if (\time() - $this->lastWritingAt >= $writingTimeout) { + $this->closeSocket(); + return \true; + } + return \false; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/StreamHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/StreamHandler.php new file mode 100644 index 0000000..0812466 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/StreamHandler.php @@ -0,0 +1,172 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Utils; +/** + * Stores to any stream resource + * + * Can be used to store into php://stderr, remote and local files, etc. + * + * @author Jordi Boggiano + */ +class StreamHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** @private 512KB */ + const CHUNK_SIZE = 524288; + /** @var resource|null */ + protected $stream; + protected $url; + private $errorMessage; + protected $filePermission; + protected $useLocking; + private $dirCreated; + /** + * @param resource|string $stream + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) + * @param bool $useLocking Try to lock log file before doing any writes + * + * @throws \Exception If a missing directory is not buildable + * @throws \InvalidArgumentException If stream is not a resource or string + */ + public function __construct($stream, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $filePermission = null, $useLocking = \false) + { + parent::__construct($level, $bubble); + if (\is_resource($stream)) { + $this->stream = $stream; + $this->streamSetChunkSize(); + } elseif (\is_string($stream)) { + $this->url = \PostSMTP\Vendor\Monolog\Utils::canonicalizePath($stream); + } else { + throw new \InvalidArgumentException('A stream must either be a resource or a string.'); + } + $this->filePermission = $filePermission; + $this->useLocking = $useLocking; + } + /** + * {@inheritdoc} + */ + public function close() + { + if ($this->url && \is_resource($this->stream)) { + \fclose($this->stream); + } + $this->stream = null; + $this->dirCreated = null; + } + /** + * Return the currently active stream if it is open + * + * @return resource|null + */ + public function getStream() + { + return $this->stream; + } + /** + * Return the stream URL if it was configured with a URL and not an active resource + * + * @return string|null + */ + public function getUrl() + { + return $this->url; + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (!\is_resource($this->stream)) { + if (null === $this->url || '' === $this->url) { + throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); + } + $this->createDir(); + $this->errorMessage = null; + \set_error_handler(array($this, 'customErrorHandler')); + $this->stream = \fopen($this->url, 'a'); + if ($this->filePermission !== null) { + @\chmod($this->url, $this->filePermission); + } + \restore_error_handler(); + if (!\is_resource($this->stream)) { + $this->stream = null; + throw new \UnexpectedValueException(\sprintf('The stream or file "%s" could not be opened in append mode: ' . $this->errorMessage, $this->url)); + } + $this->streamSetChunkSize(); + } + if ($this->useLocking) { + // ignoring errors here, there's not much we can do about them + \flock($this->stream, \LOCK_EX); + } + $this->streamWrite($this->stream, $record); + if ($this->useLocking) { + \flock($this->stream, \LOCK_UN); + } + } + /** + * Write to stream + * @param resource $stream + * @param array $record + */ + protected function streamWrite($stream, array $record) + { + \fwrite($stream, (string) $record['formatted']); + } + protected function streamSetChunkSize() + { + if (\version_compare(\PHP_VERSION, '5.4.0', '>=')) { + return \stream_set_chunk_size($this->stream, self::CHUNK_SIZE); + } + return \false; + } + private function customErrorHandler($code, $msg) + { + $this->errorMessage = \preg_replace('{^(fopen|mkdir)\\(.*?\\): }', '', $msg); + } + /** + * @param string $stream + * + * @return null|string + */ + private function getDirFromStream($stream) + { + $pos = \strpos($stream, '://'); + if ($pos === \false) { + return \dirname($stream); + } + if ('file://' === \substr($stream, 0, 7)) { + return \dirname(\substr($stream, 7)); + } + return null; + } + private function createDir() + { + // Do not try to create dir if it has already been tried. + if ($this->dirCreated) { + return; + } + $dir = $this->getDirFromStream($this->url); + if (null !== $dir && !\is_dir($dir)) { + $this->errorMessage = null; + \set_error_handler(array($this, 'customErrorHandler')); + $status = \mkdir($dir, 0777, \true); + \restore_error_handler(); + if (\false === $status && !\is_dir($dir)) { + throw new \UnexpectedValueException(\sprintf('There is no existing directory at "%s" and its not buildable: ' . $this->errorMessage, $dir)); + } + } + $this->dirCreated = \true; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php new file mode 100644 index 0000000..a92ec97 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Formatter\FormatterInterface; +use PostSMTP\Vendor\Monolog\Formatter\LineFormatter; +use PostSMTP\Vendor\Swift; +/** + * SwiftMailerHandler uses Swift_Mailer to send the emails + * + * @author Gyula Sallai + */ +class SwiftMailerHandler extends \PostSMTP\Vendor\Monolog\Handler\MailHandler +{ + protected $mailer; + private $messageTemplate; + /** + * @param \Swift_Mailer $mailer The mailer to use + * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + */ + public function __construct(\PostSMTP\Vendor\Swift_Mailer $mailer, $message, $level = \PostSMTP\Vendor\Monolog\Logger::ERROR, $bubble = \true) + { + parent::__construct($level, $bubble); + $this->mailer = $mailer; + $this->messageTemplate = $message; + } + /** + * {@inheritdoc} + */ + protected function send($content, array $records) + { + $this->mailer->send($this->buildMessage($content, $records)); + } + /** + * Gets the formatter for the Swift_Message subject. + * + * @param string $format The format of the subject + * @return FormatterInterface + */ + protected function getSubjectFormatter($format) + { + return new \PostSMTP\Vendor\Monolog\Formatter\LineFormatter($format); + } + /** + * Creates instance of Swift_Message to be sent + * + * @param string $content formatted email body to be sent + * @param array $records Log records that formed the content + * @return \Swift_Message + */ + protected function buildMessage($content, array $records) + { + $message = null; + if ($this->messageTemplate instanceof \PostSMTP\Vendor\Swift_Message) { + $message = clone $this->messageTemplate; + $message->generateId(); + } elseif (\is_callable($this->messageTemplate)) { + $message = \call_user_func($this->messageTemplate, $content, $records); + } + if (!$message instanceof \PostSMTP\Vendor\Swift_Message) { + throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it'); + } + if ($records) { + $subjectFormatter = $this->getSubjectFormatter($message->getSubject()); + $message->setSubject($subjectFormatter->format($this->getHighestRecord($records))); + } + $message->setBody($content); + if (\version_compare(\PostSMTP\Vendor\Swift::VERSION, '6.0.0', '>=')) { + $message->setDate(new \DateTimeImmutable()); + } else { + $message->setDate(\time()); + } + return $message; + } + /** + * BC getter, to be removed in 2.0 + */ + public function __get($name) + { + if ($name === 'message') { + \trigger_error('SwiftMailerHandler->message is deprecated, use ->buildMessage() instead to retrieve the message', \E_USER_DEPRECATED); + return $this->buildMessage(null, array()); + } + throw new \InvalidArgumentException('Invalid property ' . $name); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogHandler.php new file mode 100644 index 0000000..7297ea2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogHandler.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Logs to syslog service. + * + * usage example: + * + * $log = new Logger('application'); + * $syslog = new SyslogHandler('myfacility', 'local6'); + * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%"); + * $syslog->setFormatter($formatter); + * $log->pushHandler($syslog); + * + * @author Sven Paulus + */ +class SyslogHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractSyslogHandler +{ + protected $ident; + protected $logopts; + /** + * @param string $ident + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID + */ + public function __construct($ident, $facility = \LOG_USER, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $logopts = \LOG_PID) + { + parent::__construct($facility, $level, $bubble); + $this->ident = $ident; + $this->logopts = $logopts; + } + /** + * {@inheritdoc} + */ + public function close() + { + \closelog(); + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + if (!\openlog($this->ident, $this->logopts, $this->facility)) { + throw new \LogicException('Can\'t open syslog for ident "' . $this->ident . '" and facility "' . $this->facility . '"'); + } + \syslog($this->logLevels[$record['level']], (string) $record['formatted']); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php new file mode 100644 index 0000000..0224f2d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler\SyslogUdp; + +class UdpSocket +{ + const DATAGRAM_MAX_LENGTH = 65023; + protected $ip; + protected $port; + protected $socket; + public function __construct($ip, $port = 514) + { + $this->ip = $ip; + $this->port = $port; + $this->socket = \socket_create(\AF_INET, \SOCK_DGRAM, \SOL_UDP); + } + public function write($line, $header = "") + { + $this->send($this->assembleMessage($line, $header)); + } + public function close() + { + if (\is_resource($this->socket)) { + \socket_close($this->socket); + $this->socket = null; + } + } + protected function send($chunk) + { + if (!\is_resource($this->socket)) { + throw new \LogicException('The UdpSocket to ' . $this->ip . ':' . $this->port . ' has been closed and can not be written to anymore'); + } + \socket_sendto($this->socket, $chunk, \strlen($chunk), $flags = 0, $this->ip, $this->port); + } + protected function assembleMessage($line, $header) + { + $chunkSize = self::DATAGRAM_MAX_LENGTH - \strlen($header); + return $header . \substr($line, 0, $chunkSize); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php new file mode 100644 index 0000000..0a5c434 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Logger; +use PostSMTP\Vendor\Monolog\Handler\SyslogUdp\UdpSocket; +/** + * A Handler for logging to a remote syslogd server. + * + * @author Jesper Skovgaard Nielsen + * @author Dominik Kukacka + */ +class SyslogUdpHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractSyslogHandler +{ + const RFC3164 = 0; + const RFC5424 = 1; + private $dateFormats = array(self::RFC3164 => 'M d H:i:s', self::RFC5424 => \DateTime::RFC3339); + protected $socket; + protected $ident; + protected $rfc; + /** + * @param string $host + * @param int $port + * @param mixed $facility + * @param int $level The minimum logging level at which this handler will be triggered + * @param bool $bubble Whether the messages that are handled can bubble up the stack or not + * @param string $ident Program name or tag for each log message. + * @param int $rfc RFC to format the message for. + */ + public function __construct($host, $port = 514, $facility = \LOG_USER, $level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true, $ident = 'php', $rfc = self::RFC5424) + { + parent::__construct($facility, $level, $bubble); + $this->ident = $ident; + $this->rfc = $rfc; + $this->socket = new \PostSMTP\Vendor\Monolog\Handler\SyslogUdp\UdpSocket($host, $port ?: 514); + } + protected function write(array $record) + { + $lines = $this->splitMessageIntoLines($record['formatted']); + $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]); + foreach ($lines as $line) { + $this->socket->write($line, $header); + } + } + public function close() + { + $this->socket->close(); + } + private function splitMessageIntoLines($message) + { + if (\is_array($message)) { + $message = \implode("\n", $message); + } + return \preg_split('/$\\R?^/m', $message, -1, \PREG_SPLIT_NO_EMPTY); + } + /** + * Make common syslog header (see rfc5424 or rfc3164) + */ + protected function makeCommonSyslogHeader($severity) + { + $priority = $severity + $this->facility; + if (!($pid = \getmypid())) { + $pid = '-'; + } + if (!($hostname = \gethostname())) { + $hostname = '-'; + } + $date = $this->getDateTime(); + if ($this->rfc === self::RFC3164) { + return "<{$priority}>" . $date . " " . $hostname . " " . $this->ident . "[" . $pid . "]: "; + } else { + return "<{$priority}>1 " . $date . " " . $hostname . " " . $this->ident . " " . $pid . " - - "; + } + } + protected function getDateTime() + { + return \date($this->dateFormats[$this->rfc]); + } + /** + * Inject your own socket, mainly used for testing + */ + public function setSocket($socket) + { + $this->socket = $socket; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/TestHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/TestHandler.php new file mode 100644 index 0000000..a1654e8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/TestHandler.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +/** + * Used for testing purposes. + * + * It records all records and gives you access to them for verification. + * + * @author Jordi Boggiano + * + * @method bool hasEmergency($record) + * @method bool hasAlert($record) + * @method bool hasCritical($record) + * @method bool hasError($record) + * @method bool hasWarning($record) + * @method bool hasNotice($record) + * @method bool hasInfo($record) + * @method bool hasDebug($record) + * + * @method bool hasEmergencyRecords() + * @method bool hasAlertRecords() + * @method bool hasCriticalRecords() + * @method bool hasErrorRecords() + * @method bool hasWarningRecords() + * @method bool hasNoticeRecords() + * @method bool hasInfoRecords() + * @method bool hasDebugRecords() + * + * @method bool hasEmergencyThatContains($message) + * @method bool hasAlertThatContains($message) + * @method bool hasCriticalThatContains($message) + * @method bool hasErrorThatContains($message) + * @method bool hasWarningThatContains($message) + * @method bool hasNoticeThatContains($message) + * @method bool hasInfoThatContains($message) + * @method bool hasDebugThatContains($message) + * + * @method bool hasEmergencyThatMatches($message) + * @method bool hasAlertThatMatches($message) + * @method bool hasCriticalThatMatches($message) + * @method bool hasErrorThatMatches($message) + * @method bool hasWarningThatMatches($message) + * @method bool hasNoticeThatMatches($message) + * @method bool hasInfoThatMatches($message) + * @method bool hasDebugThatMatches($message) + * + * @method bool hasEmergencyThatPasses($message) + * @method bool hasAlertThatPasses($message) + * @method bool hasCriticalThatPasses($message) + * @method bool hasErrorThatPasses($message) + * @method bool hasWarningThatPasses($message) + * @method bool hasNoticeThatPasses($message) + * @method bool hasInfoThatPasses($message) + * @method bool hasDebugThatPasses($message) + */ +class TestHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + protected $records = array(); + protected $recordsByLevel = array(); + private $skipReset = \false; + public function getRecords() + { + return $this->records; + } + public function clear() + { + $this->records = array(); + $this->recordsByLevel = array(); + } + public function reset() + { + if (!$this->skipReset) { + $this->clear(); + } + } + public function setSkipReset($skipReset) + { + $this->skipReset = $skipReset; + } + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + /** + * @param string|array $record Either a message string or an array containing message and optionally context keys that will be checked against all records + * @param int $level Logger::LEVEL constant value + */ + public function hasRecord($record, $level) + { + if (\is_string($record)) { + $record = array('message' => $record); + } + return $this->hasRecordThatPasses(function ($rec) use($record) { + if ($rec['message'] !== $record['message']) { + return \false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return \false; + } + return \true; + }, $level); + } + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use($message) { + return \strpos($rec['message'], $message) !== \false; + }, $level); + } + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use($regex) { + return \preg_match($regex, $rec['message']) > 0; + }, $level); + } + public function hasRecordThatPasses($predicate, $level) + { + if (!\is_callable($predicate)) { + throw new \InvalidArgumentException("Expected a callable for hasRecordThatSucceeds"); + } + if (!isset($this->recordsByLevel[$level])) { + return \false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (\call_user_func($predicate, $rec, $i)) { + return \true; + } + } + return \false; + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + public function __call($method, $args) + { + if (\preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = \constant('PostSMTP\\Vendor\\Monolog\\Logger::' . \strtoupper($matches[2])); + if (\method_exists($this, $genericMethod)) { + $args[] = $level; + return \call_user_func_array(array($this, $genericMethod), $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . \get_class($this) . '::' . $method . '()'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php new file mode 100644 index 0000000..8855c63 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +/** + * Forwards records to multiple handlers suppressing failures of each handler + * and continuing through to give every handler a chance to succeed. + * + * @author Craig D'Amelio + */ +class WhatFailureGroupHandler extends \PostSMTP\Vendor\Monolog\Handler\GroupHandler +{ + /** + * {@inheritdoc} + */ + public function handle(array $record) + { + if ($this->processors) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + } + foreach ($this->handlers as $handler) { + try { + $handler->handle($record); + } catch (\Exception $e) { + // What failure? + } catch (\Throwable $e) { + // What failure? + } + } + return \false === $this->bubble; + } + /** + * {@inheritdoc} + */ + public function handleBatch(array $records) + { + if ($this->processors) { + $processed = array(); + foreach ($records as $record) { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + $processed[] = $record; + } + $records = $processed; + } + foreach ($this->handlers as $handler) { + try { + $handler->handleBatch($records); + } catch (\Exception $e) { + // What failure? + } catch (\Throwable $e) { + // What failure? + } + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php new file mode 100644 index 0000000..58b37c8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Handler; + +use PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter; +use PostSMTP\Vendor\Monolog\Logger; +/** + * Handler sending logs to Zend Monitor + * + * @author Christian Bergau + * @author Jason Davis + */ +class ZendMonitorHandler extends \PostSMTP\Vendor\Monolog\Handler\AbstractProcessingHandler +{ + /** + * Monolog level / ZendMonitor Custom Event priority map + * + * @var array + */ + protected $levelMap = array(); + /** + * Construct + * + * @param int $level + * @param bool $bubble + * @throws MissingExtensionException + */ + public function __construct($level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, $bubble = \true) + { + if (!\function_exists('PostSMTP\\Vendor\\zend_monitor_custom_event')) { + throw new \PostSMTP\Vendor\Monolog\Handler\MissingExtensionException('You must have Zend Server installed with Zend Monitor enabled in order to use this handler'); + } + //zend monitor constants are not defined if zend monitor is not enabled. + $this->levelMap = array(\PostSMTP\Vendor\Monolog\Logger::DEBUG => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_INFO, \PostSMTP\Vendor\Monolog\Logger::INFO => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_INFO, \PostSMTP\Vendor\Monolog\Logger::NOTICE => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_INFO, \PostSMTP\Vendor\Monolog\Logger::WARNING => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_WARNING, \PostSMTP\Vendor\Monolog\Logger::ERROR => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR, \PostSMTP\Vendor\Monolog\Logger::CRITICAL => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR, \PostSMTP\Vendor\Monolog\Logger::ALERT => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR, \PostSMTP\Vendor\Monolog\Logger::EMERGENCY => \PostSMTP\Vendor\ZEND_MONITOR_EVENT_SEVERITY_ERROR); + parent::__construct($level, $bubble); + } + /** + * {@inheritdoc} + */ + protected function write(array $record) + { + $this->writeZendMonitorCustomEvent(\PostSMTP\Vendor\Monolog\Logger::getLevelName($record['level']), $record['message'], $record['formatted'], $this->levelMap[$record['level']]); + } + /** + * Write to Zend Monitor Events + * @param string $type Text displayed in "Class Name (custom)" field + * @param string $message Text displayed in "Error String" + * @param mixed $formatted Displayed in Custom Variables tab + * @param int $severity Set the event severity level (-1,0,1) + */ + protected function writeZendMonitorCustomEvent($type, $message, $formatted, $severity) + { + zend_monitor_custom_event($type, $message, $formatted, $severity); + } + /** + * {@inheritdoc} + */ + public function getDefaultFormatter() + { + return new \PostSMTP\Vendor\Monolog\Formatter\NormalizerFormatter(); + } + /** + * Get the level map + * + * @return array + */ + public function getLevelMap() + { + return $this->levelMap; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Logger.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Logger.php new file mode 100644 index 0000000..d644627 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Logger.php @@ -0,0 +1,692 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog; + +use PostSMTP\Vendor\Monolog\Handler\HandlerInterface; +use PostSMTP\Vendor\Monolog\Handler\StreamHandler; +use PostSMTP\Vendor\Psr\Log\LoggerInterface; +use PostSMTP\Vendor\Psr\Log\InvalidArgumentException; +use Exception; +/** + * Monolog log channel + * + * It contains a stack of Handlers and a stack of Processors, + * and uses them to store records that are added to it. + * + * @author Jordi Boggiano + */ +class Logger implements \PostSMTP\Vendor\Psr\Log\LoggerInterface, \PostSMTP\Vendor\Monolog\ResettableInterface +{ + /** + * Detailed debug information + */ + const DEBUG = 100; + /** + * Interesting events + * + * Examples: User logs in, SQL logs. + */ + const INFO = 200; + /** + * Uncommon events + */ + const NOTICE = 250; + /** + * Exceptional occurrences that are not errors + * + * Examples: Use of deprecated APIs, poor use of an API, + * undesirable things that are not necessarily wrong. + */ + const WARNING = 300; + /** + * Runtime errors + */ + const ERROR = 400; + /** + * Critical conditions + * + * Example: Application component unavailable, unexpected exception. + */ + const CRITICAL = 500; + /** + * Action must be taken immediately + * + * Example: Entire website down, database unavailable, etc. + * This should trigger the SMS alerts and wake you up. + */ + const ALERT = 550; + /** + * Urgent alert. + */ + const EMERGENCY = 600; + /** + * Monolog API version + * + * This is only bumped when API breaks are done and should + * follow the major version of the library + * + * @var int + */ + const API = 1; + /** + * Logging levels from syslog protocol defined in RFC 5424 + * + * @var array $levels Logging levels + */ + protected static $levels = array(self::DEBUG => 'DEBUG', self::INFO => 'INFO', self::NOTICE => 'NOTICE', self::WARNING => 'WARNING', self::ERROR => 'ERROR', self::CRITICAL => 'CRITICAL', self::ALERT => 'ALERT', self::EMERGENCY => 'EMERGENCY'); + /** + * @var \DateTimeZone + */ + protected static $timezone; + /** + * @var string + */ + protected $name; + /** + * The handler stack + * + * @var HandlerInterface[] + */ + protected $handlers; + /** + * Processors that will process all log records + * + * To process records of a single handler instead, add the processor on that specific handler + * + * @var callable[] + */ + protected $processors; + /** + * @var bool + */ + protected $microsecondTimestamps = \true; + /** + * @var callable + */ + protected $exceptionHandler; + /** + * @param string $name The logging channel + * @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc. + * @param callable[] $processors Optional array of processors + */ + public function __construct($name, array $handlers = array(), array $processors = array()) + { + $this->name = $name; + $this->setHandlers($handlers); + $this->processors = $processors; + } + /** + * @return string + */ + public function getName() + { + return $this->name; + } + /** + * Return a new cloned instance with the name changed + * + * @return static + */ + public function withName($name) + { + $new = clone $this; + $new->name = $name; + return $new; + } + /** + * Pushes a handler on to the stack. + * + * @param HandlerInterface $handler + * @return $this + */ + public function pushHandler(\PostSMTP\Vendor\Monolog\Handler\HandlerInterface $handler) + { + \array_unshift($this->handlers, $handler); + return $this; + } + /** + * Pops a handler from the stack + * + * @return HandlerInterface + */ + public function popHandler() + { + if (!$this->handlers) { + throw new \LogicException('You tried to pop from an empty handler stack.'); + } + return \array_shift($this->handlers); + } + /** + * Set handlers, replacing all existing ones. + * + * If a map is passed, keys will be ignored. + * + * @param HandlerInterface[] $handlers + * @return $this + */ + public function setHandlers(array $handlers) + { + $this->handlers = array(); + foreach (\array_reverse($handlers) as $handler) { + $this->pushHandler($handler); + } + return $this; + } + /** + * @return HandlerInterface[] + */ + public function getHandlers() + { + return $this->handlers; + } + /** + * Adds a processor on to the stack. + * + * @param callable $callback + * @return $this + */ + public function pushProcessor($callback) + { + if (!\is_callable($callback)) { + throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), ' . \var_export($callback, \true) . ' given'); + } + \array_unshift($this->processors, $callback); + return $this; + } + /** + * Removes the processor on top of the stack and returns it. + * + * @return callable + */ + public function popProcessor() + { + if (!$this->processors) { + throw new \LogicException('You tried to pop from an empty processor stack.'); + } + return \array_shift($this->processors); + } + /** + * @return callable[] + */ + public function getProcessors() + { + return $this->processors; + } + /** + * Control the use of microsecond resolution timestamps in the 'datetime' + * member of new records. + * + * Generating microsecond resolution timestamps by calling + * microtime(true), formatting the result via sprintf() and then parsing + * the resulting string via \DateTime::createFromFormat() can incur + * a measurable runtime overhead vs simple usage of DateTime to capture + * a second resolution timestamp in systems which generate a large number + * of log events. + * + * @param bool $micro True to use microtime() to create timestamps + */ + public function useMicrosecondTimestamps($micro) + { + $this->microsecondTimestamps = (bool) $micro; + } + /** + * Adds a log record. + * + * @param int $level The logging level + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addRecord($level, $message, array $context = array()) + { + if (!$this->handlers) { + $this->pushHandler(new \PostSMTP\Vendor\Monolog\Handler\StreamHandler('php://stderr', static::DEBUG)); + } + $levelName = static::getLevelName($level); + // check if any handler will handle this message so we can return early and save cycles + $handlerKey = null; + \reset($this->handlers); + while ($handler = \current($this->handlers)) { + if ($handler->isHandling(array('level' => $level))) { + $handlerKey = \key($this->handlers); + break; + } + \next($this->handlers); + } + if (null === $handlerKey) { + return \false; + } + if (!static::$timezone) { + static::$timezone = new \DateTimeZone(\date_default_timezone_get() ?: 'UTC'); + } + // php7.1+ always has microseconds enabled, so we do not need this hack + if ($this->microsecondTimestamps && \PHP_VERSION_ID < 70100) { + $ts = \DateTime::createFromFormat('U.u', \sprintf('%.6F', \microtime(\true)), static::$timezone); + } else { + $ts = new \DateTime('now', static::$timezone); + } + $ts->setTimezone(static::$timezone); + $record = array('message' => (string) $message, 'context' => $context, 'level' => $level, 'level_name' => $levelName, 'channel' => $this->name, 'datetime' => $ts, 'extra' => array()); + try { + foreach ($this->processors as $processor) { + $record = \call_user_func($processor, $record); + } + while ($handler = \current($this->handlers)) { + if (\true === $handler->handle($record)) { + break; + } + \next($this->handlers); + } + } catch (\Exception $e) { + $this->handleException($e, $record); + } + return \true; + } + /** + * Ends a log cycle and frees all resources used by handlers. + * + * Closing a Handler means flushing all buffers and freeing any open resources/handles. + * Handlers that have been closed should be able to accept log records again and re-open + * themselves on demand, but this may not always be possible depending on implementation. + * + * This is useful at the end of a request and will be called automatically on every handler + * when they get destructed. + */ + public function close() + { + foreach ($this->handlers as $handler) { + if (\method_exists($handler, 'close')) { + $handler->close(); + } + } + } + /** + * Ends a log cycle and resets all handlers and processors to their initial state. + * + * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal + * state, and getting it back to a state in which it can receive log records again. + * + * This is useful in case you want to avoid logs leaking between two requests or jobs when you + * have a long running process like a worker or an application server serving multiple requests + * in one process. + */ + public function reset() + { + foreach ($this->handlers as $handler) { + if ($handler instanceof \PostSMTP\Vendor\Monolog\ResettableInterface) { + $handler->reset(); + } + } + foreach ($this->processors as $processor) { + if ($processor instanceof \PostSMTP\Vendor\Monolog\ResettableInterface) { + $processor->reset(); + } + } + } + /** + * Adds a log record at the DEBUG level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addDebug($message, array $context = array()) + { + return $this->addRecord(static::DEBUG, $message, $context); + } + /** + * Adds a log record at the INFO level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addInfo($message, array $context = array()) + { + return $this->addRecord(static::INFO, $message, $context); + } + /** + * Adds a log record at the NOTICE level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addNotice($message, array $context = array()) + { + return $this->addRecord(static::NOTICE, $message, $context); + } + /** + * Adds a log record at the WARNING level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addWarning($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + /** + * Adds a log record at the ERROR level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addError($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + /** + * Adds a log record at the CRITICAL level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addCritical($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + /** + * Adds a log record at the ALERT level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addAlert($message, array $context = array()) + { + return $this->addRecord(static::ALERT, $message, $context); + } + /** + * Adds a log record at the EMERGENCY level. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function addEmergency($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + /** + * Gets all supported logging levels. + * + * @return array Assoc array with human-readable level names => level codes. + */ + public static function getLevels() + { + return \array_flip(static::$levels); + } + /** + * Gets the name of the logging level. + * + * @param int $level + * @return string + */ + public static function getLevelName($level) + { + if (!isset(static::$levels[$level])) { + throw new \PostSMTP\Vendor\Psr\Log\InvalidArgumentException('Level "' . $level . '" is not defined, use one of: ' . \implode(', ', \array_keys(static::$levels))); + } + return static::$levels[$level]; + } + /** + * Converts PSR-3 levels to Monolog ones if necessary + * + * @param string|int $level Level number (monolog) or name (PSR-3) + * @return int + */ + public static function toMonologLevel($level) + { + if (\is_string($level)) { + // Contains chars of all log levels and avoids using strtoupper() which may have + // strange results depending on locale (for example, "i" will become "İ") + $upper = \strtr($level, 'abcdefgilmnortuwy', 'ABCDEFGILMNORTUWY'); + if (\defined(__CLASS__ . '::' . $upper)) { + return \constant(__CLASS__ . '::' . $upper); + } + } + return $level; + } + /** + * Checks whether the Logger has a handler that listens on the given level + * + * @param int $level + * @return bool + */ + public function isHandling($level) + { + $record = array('level' => $level); + foreach ($this->handlers as $handler) { + if ($handler->isHandling($record)) { + return \true; + } + } + return \false; + } + /** + * Set a custom exception handler + * + * @param callable $callback + * @return $this + */ + public function setExceptionHandler($callback) + { + if (!\is_callable($callback)) { + throw new \InvalidArgumentException('Exception handler must be valid callable (callback or object with an __invoke method), ' . \var_export($callback, \true) . ' given'); + } + $this->exceptionHandler = $callback; + return $this; + } + /** + * @return callable + */ + public function getExceptionHandler() + { + return $this->exceptionHandler; + } + /** + * Delegates exception management to the custom exception handler, + * or throws the exception if no custom handler is set. + */ + protected function handleException(\Exception $e, array $record) + { + if (!$this->exceptionHandler) { + throw $e; + } + \call_user_func($this->exceptionHandler, $e, $record); + } + /** + * Adds a log record at an arbitrary level. + * + * This method allows for compatibility with common interfaces. + * + * @param mixed $level The log level + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function log($level, $message, array $context = array()) + { + $level = static::toMonologLevel($level); + return $this->addRecord($level, $message, $context); + } + /** + * Adds a log record at the DEBUG level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function debug($message, array $context = array()) + { + return $this->addRecord(static::DEBUG, $message, $context); + } + /** + * Adds a log record at the INFO level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function info($message, array $context = array()) + { + return $this->addRecord(static::INFO, $message, $context); + } + /** + * Adds a log record at the NOTICE level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function notice($message, array $context = array()) + { + return $this->addRecord(static::NOTICE, $message, $context); + } + /** + * Adds a log record at the WARNING level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function warn($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + /** + * Adds a log record at the WARNING level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function warning($message, array $context = array()) + { + return $this->addRecord(static::WARNING, $message, $context); + } + /** + * Adds a log record at the ERROR level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function err($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + /** + * Adds a log record at the ERROR level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function error($message, array $context = array()) + { + return $this->addRecord(static::ERROR, $message, $context); + } + /** + * Adds a log record at the CRITICAL level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function crit($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + /** + * Adds a log record at the CRITICAL level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function critical($message, array $context = array()) + { + return $this->addRecord(static::CRITICAL, $message, $context); + } + /** + * Adds a log record at the ALERT level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function alert($message, array $context = array()) + { + return $this->addRecord(static::ALERT, $message, $context); + } + /** + * Adds a log record at the EMERGENCY level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function emerg($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + /** + * Adds a log record at the EMERGENCY level. + * + * This method allows for compatibility with common interfaces. + * + * @param string $message The log message + * @param array $context The log context + * @return bool Whether the record has been processed + */ + public function emergency($message, array $context = array()) + { + return $this->addRecord(static::EMERGENCY, $message, $context); + } + /** + * Set the timezone to be used for the timestamp of log records. + * + * This is stored globally for all Logger instances + * + * @param \DateTimeZone $tz Timezone object + */ + public static function setTimezone(\DateTimeZone $tz) + { + self::$timezone = $tz; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/GitProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/GitProcessor.php new file mode 100644 index 0000000..efab8c4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/GitProcessor.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Injects Git branch and Git commit SHA in all records + * + * @author Nick Otter + * @author Jordi Boggiano + */ +class GitProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + private $level; + private static $cache; + public function __construct($level = \PostSMTP\Vendor\Monolog\Logger::DEBUG) + { + $this->level = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($level); + } + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // return if the level is not high enough + if ($record['level'] < $this->level) { + return $record; + } + $record['extra']['git'] = self::getGitInfo(); + return $record; + } + private static function getGitInfo() + { + if (self::$cache) { + return self::$cache; + } + $branches = `git branch -v --no-abbrev`; + if ($branches && \preg_match('{^\\* (.+?)\\s+([a-f0-9]{40})(?:\\s|$)}m', $branches, $matches)) { + return self::$cache = array('branch' => $matches[1], 'commit' => $matches[2]); + } + return self::$cache = array(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php new file mode 100644 index 0000000..b1cde1c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Injects line/file:class/function where the log message came from + * + * Warning: This only works if the handler processes the logs directly. + * If you put the processor on a handler that is behind a FingersCrossedHandler + * for example, the processor will only be called once the trigger level is reached, + * and all the log records will have the same file/line/.. data from the call that + * triggered the FingersCrossedHandler. + * + * @author Jordi Boggiano + */ +class IntrospectionProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + private $level; + private $skipClassesPartials; + private $skipStackFramesCount; + private $skipFunctions = array('call_user_func', 'call_user_func_array'); + public function __construct($level = \PostSMTP\Vendor\Monolog\Logger::DEBUG, array $skipClassesPartials = array(), $skipStackFramesCount = 0) + { + $this->level = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($level); + $this->skipClassesPartials = \array_merge(array('PostSMTP\\Vendor\\Monolog\\'), $skipClassesPartials); + $this->skipStackFramesCount = $skipStackFramesCount; + } + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // return if the level is not high enough + if ($record['level'] < $this->level) { + return $record; + } + /* + * http://php.net/manual/en/function.debug-backtrace.php + * As of 5.3.6, DEBUG_BACKTRACE_IGNORE_ARGS option was added. + * Any version less than 5.3.6 must use the DEBUG_BACKTRACE_IGNORE_ARGS constant value '2'. + */ + $trace = \debug_backtrace(\PHP_VERSION_ID < 50306 ? 2 : \DEBUG_BACKTRACE_IGNORE_ARGS); + // skip first since it's always the current method + \array_shift($trace); + // the call_user_func call is also skipped + \array_shift($trace); + $i = 0; + while ($this->isTraceClassOrSkippedFunction($trace, $i)) { + if (isset($trace[$i]['class'])) { + foreach ($this->skipClassesPartials as $part) { + if (\strpos($trace[$i]['class'], $part) !== \false) { + $i++; + continue 2; + } + } + } elseif (\in_array($trace[$i]['function'], $this->skipFunctions)) { + $i++; + continue; + } + break; + } + $i += $this->skipStackFramesCount; + // we should have the call source now + $record['extra'] = \array_merge($record['extra'], array('file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null, 'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null, 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null, 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null)); + return $record; + } + private function isTraceClassOrSkippedFunction(array $trace, $index) + { + if (!isset($trace[$index])) { + return \false; + } + return isset($trace[$index]['class']) || \in_array($trace[$index]['function'], $this->skipFunctions); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php new file mode 100644 index 0000000..c1e1e69 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +/** + * Injects memory_get_peak_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryPeakUsageProcessor extends \PostSMTP\Vendor\Monolog\Processor\MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = \memory_get_peak_usage($this->realUsage); + $formatted = $this->formatBytes($bytes); + $record['extra']['memory_peak_usage'] = $formatted; + return $record; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php new file mode 100644 index 0000000..260917a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +/** + * Some methods that are common for all memory processors + * + * @author Rob Jensen + */ +abstract class MemoryProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + /** + * @var bool If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported. + */ + protected $realUsage; + /** + * @var bool If true, then format memory size to human readable string (MB, KB, B depending on size) + */ + protected $useFormatting; + /** + * @param bool $realUsage Set this to true to get the real size of memory allocated from system. + * @param bool $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size) + */ + public function __construct($realUsage = \true, $useFormatting = \true) + { + $this->realUsage = (bool) $realUsage; + $this->useFormatting = (bool) $useFormatting; + } + /** + * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is + * + * @param int $bytes + * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as is + */ + protected function formatBytes($bytes) + { + $bytes = (int) $bytes; + if (!$this->useFormatting) { + return $bytes; + } + if ($bytes > 1024 * 1024) { + return \round($bytes / 1024 / 1024, 2) . ' MB'; + } elseif ($bytes > 1024) { + return \round($bytes / 1024, 2) . ' KB'; + } + return $bytes . ' B'; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php new file mode 100644 index 0000000..c00732a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +/** + * Injects memory_get_usage in all records + * + * @see Monolog\Processor\MemoryProcessor::__construct() for options + * @author Rob Jensen + */ +class MemoryUsageProcessor extends \PostSMTP\Vendor\Monolog\Processor\MemoryProcessor +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $bytes = \memory_get_usage($this->realUsage); + $formatted = $this->formatBytes($bytes); + $record['extra']['memory_usage'] = $formatted; + return $record; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php new file mode 100644 index 0000000..afe9acb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +use PostSMTP\Vendor\Monolog\Logger; +/** + * Injects Hg branch and Hg revision number in all records + * + * @author Jonathan A. Schweder + */ +class MercurialProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + private $level; + private static $cache; + public function __construct($level = \PostSMTP\Vendor\Monolog\Logger::DEBUG) + { + $this->level = \PostSMTP\Vendor\Monolog\Logger::toMonologLevel($level); + } + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // return if the level is not high enough + if ($record['level'] < $this->level) { + return $record; + } + $record['extra']['hg'] = self::getMercurialInfo(); + return $record; + } + private static function getMercurialInfo() + { + if (self::$cache) { + return self::$cache; + } + $result = \explode(' ', \trim(`hg id -nb`)); + if (\count($result) >= 3) { + return self::$cache = array('branch' => $result[1], 'revision' => $result[2]); + } + return self::$cache = array(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php new file mode 100644 index 0000000..1f0bbd8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +/** + * Adds value of getmypid into records + * + * @author Andreas Hörnicke + */ +class ProcessIdProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + $record['extra']['process_id'] = \getmypid(); + return $record; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php new file mode 100644 index 0000000..4a871df --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +/** + * An optional interface to allow labelling Monolog processors. + * + * @author Nicolas Grekas + */ +interface ProcessorInterface +{ + /** + * @return array The processed records + */ + public function __invoke(array $records); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php new file mode 100644 index 0000000..77ad18f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +use PostSMTP\Vendor\Monolog\Utils; +/** + * Processes a record's message according to PSR-3 rules + * + * It replaces {foo} with the value from $context['foo'] + * + * @author Jordi Boggiano + */ +class PsrLogMessageProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + const SIMPLE_DATE = "Y-m-d\\TH:i:s.uP"; + /** @var string|null */ + private $dateFormat; + /** @var bool */ + private $removeUsedContextFields; + /** + * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format + * @param bool $removeUsedContextFields If set to true the fields interpolated into message gets unset + */ + public function __construct($dateFormat = null, $removeUsedContextFields = \false) + { + $this->dateFormat = $dateFormat; + $this->removeUsedContextFields = $removeUsedContextFields; + } + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + if (\false === \strpos($record['message'], '{')) { + return $record; + } + $replacements = array(); + foreach ($record['context'] as $key => $val) { + $placeholder = '{' . $key . '}'; + if (\strpos($record['message'], $placeholder) === \false) { + continue; + } + if (\is_null($val) || \is_scalar($val) || \is_object($val) && \method_exists($val, "__toString")) { + $replacements[$placeholder] = $val; + } elseif ($val instanceof \DateTime) { + $replacements[$placeholder] = $val->format($this->dateFormat ?: static::SIMPLE_DATE); + } elseif (\is_object($val)) { + $replacements[$placeholder] = '[object ' . \PostSMTP\Vendor\Monolog\Utils::getClass($val) . ']'; + } elseif (\is_array($val)) { + $replacements[$placeholder] = 'array' . \PostSMTP\Vendor\Monolog\Utils::jsonEncode($val, null, \true); + } else { + $replacements[$placeholder] = '[' . \gettype($val) . ']'; + } + if ($this->removeUsedContextFields) { + unset($record['context'][$key]); + } + } + $record['message'] = \strtr($record['message'], $replacements); + return $record; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/TagProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/TagProcessor.php new file mode 100644 index 0000000..1e5d7ca --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/TagProcessor.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +/** + * Adds a tags array into record + * + * @author Martijn Riemers + */ +class TagProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + private $tags; + public function __construct(array $tags = array()) + { + $this->setTags($tags); + } + public function addTags(array $tags = array()) + { + $this->tags = \array_merge($this->tags, $tags); + } + public function setTags(array $tags = array()) + { + $this->tags = $tags; + } + public function __invoke(array $record) + { + $record['extra']['tags'] = $this->tags; + return $record; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/UidProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/UidProcessor.php new file mode 100644 index 0000000..d43598c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/UidProcessor.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +use PostSMTP\Vendor\Monolog\ResettableInterface; +/** + * Adds a unique identifier into records + * + * @author Simon Mönch + */ +class UidProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface, \PostSMTP\Vendor\Monolog\ResettableInterface +{ + private $uid; + public function __construct($length = 7) + { + if (!\is_int($length) || $length > 32 || $length < 1) { + throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32'); + } + $this->uid = $this->generateUid($length); + } + public function __invoke(array $record) + { + $record['extra']['uid'] = $this->uid; + return $record; + } + /** + * @return string + */ + public function getUid() + { + return $this->uid; + } + public function reset() + { + $this->uid = $this->generateUid(\strlen($this->uid)); + } + private function generateUid($length) + { + return \substr(\hash('md5', \uniqid('', \true)), 0, $length); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/WebProcessor.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/WebProcessor.php new file mode 100644 index 0000000..8f6efc4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Processor/WebProcessor.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog\Processor; + +/** + * Injects url/method and remote IP of the current web request in all records + * + * @author Jordi Boggiano + */ +class WebProcessor implements \PostSMTP\Vendor\Monolog\Processor\ProcessorInterface +{ + /** + * @var array|\ArrayAccess + */ + protected $serverData; + /** + * Default fields + * + * Array is structured as [key in record.extra => key in $serverData] + * + * @var array + */ + protected $extraFields = array('url' => 'REQUEST_URI', 'ip' => 'REMOTE_ADDR', 'http_method' => 'REQUEST_METHOD', 'server' => 'SERVER_NAME', 'referrer' => 'HTTP_REFERER'); + /** + * @param array|\ArrayAccess $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data + * @param array|null $extraFields Field names and the related key inside $serverData to be added. If not provided it defaults to: url, ip, http_method, server, referrer + */ + public function __construct($serverData = null, array $extraFields = null) + { + if (null === $serverData) { + $this->serverData =& $_SERVER; + } elseif (\is_array($serverData) || $serverData instanceof \ArrayAccess) { + $this->serverData = $serverData; + } else { + throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.'); + } + if (isset($this->serverData['UNIQUE_ID'])) { + $this->extraFields['unique_id'] = 'UNIQUE_ID'; + } + if (null !== $extraFields) { + if (isset($extraFields[0])) { + foreach (\array_keys($this->extraFields) as $fieldName) { + if (!\in_array($fieldName, $extraFields)) { + unset($this->extraFields[$fieldName]); + } + } + } else { + $this->extraFields = $extraFields; + } + } + } + /** + * @param array $record + * @return array + */ + public function __invoke(array $record) + { + // skip processing if for some reason request data + // is not present (CLI or wonky SAPIs) + if (!isset($this->serverData['REQUEST_URI'])) { + return $record; + } + $record['extra'] = $this->appendExtraFields($record['extra']); + return $record; + } + /** + * @param string $extraName + * @param string $serverName + * @return $this + */ + public function addExtraField($extraName, $serverName) + { + $this->extraFields[$extraName] = $serverName; + return $this; + } + /** + * @param array $extra + * @return array + */ + private function appendExtraFields(array $extra) + { + foreach ($this->extraFields as $extraName => $serverName) { + $extra[$extraName] = isset($this->serverData[$serverName]) ? $this->serverData[$serverName] : null; + } + return $extra; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Registry.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Registry.php new file mode 100644 index 0000000..c2f3223 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Registry.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog; + +use InvalidArgumentException; +/** + * Monolog log registry + * + * Allows to get `Logger` instances in the global scope + * via static method calls on this class. + * + * + * $application = new Monolog\Logger('application'); + * $api = new Monolog\Logger('api'); + * + * Monolog\Registry::addLogger($application); + * Monolog\Registry::addLogger($api); + * + * function testLogger() + * { + * Monolog\Registry::api()->addError('Sent to $api Logger instance'); + * Monolog\Registry::application()->addError('Sent to $application Logger instance'); + * } + * + * + * @author Tomas Tatarko + */ +class Registry +{ + /** + * List of all loggers in the registry (by named indexes) + * + * @var Logger[] + */ + private static $loggers = array(); + /** + * Adds new logging channel to the registry + * + * @param Logger $logger Instance of the logging channel + * @param string|null $name Name of the logging channel ($logger->getName() by default) + * @param bool $overwrite Overwrite instance in the registry if the given name already exists? + * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists + */ + public static function addLogger(\PostSMTP\Vendor\Monolog\Logger $logger, $name = null, $overwrite = \false) + { + $name = $name ?: $logger->getName(); + if (isset(self::$loggers[$name]) && !$overwrite) { + throw new \InvalidArgumentException('Logger with the given name already exists'); + } + self::$loggers[$name] = $logger; + } + /** + * Checks if such logging channel exists by name or instance + * + * @param string|Logger $logger Name or logger instance + */ + public static function hasLogger($logger) + { + if ($logger instanceof \PostSMTP\Vendor\Monolog\Logger) { + $index = \array_search($logger, self::$loggers, \true); + return \false !== $index; + } else { + return isset(self::$loggers[$logger]); + } + } + /** + * Removes instance from registry by name or instance + * + * @param string|Logger $logger Name or logger instance + */ + public static function removeLogger($logger) + { + if ($logger instanceof \PostSMTP\Vendor\Monolog\Logger) { + if (\false !== ($idx = \array_search($logger, self::$loggers, \true))) { + unset(self::$loggers[$idx]); + } + } else { + unset(self::$loggers[$logger]); + } + } + /** + * Clears the registry + */ + public static function clear() + { + self::$loggers = array(); + } + /** + * Gets Logger instance from the registry + * + * @param string $name Name of the requested Logger instance + * @throws \InvalidArgumentException If named Logger instance is not in the registry + * @return Logger Requested instance of Logger + */ + public static function getInstance($name) + { + if (!isset(self::$loggers[$name])) { + throw new \InvalidArgumentException(\sprintf('Requested "%s" logger instance is not in the registry', $name)); + } + return self::$loggers[$name]; + } + /** + * Gets Logger instance from the registry via static method call + * + * @param string $name Name of the requested Logger instance + * @param array $arguments Arguments passed to static method call + * @throws \InvalidArgumentException If named Logger instance is not in the registry + * @return Logger Requested instance of Logger + */ + public static function __callStatic($name, $arguments) + { + return self::getInstance($name); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/ResettableInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/ResettableInterface.php new file mode 100644 index 0000000..b6c037f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/ResettableInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog; + +/** + * Handler or Processor implementing this interface will be reset when Logger::reset() is called. + * + * Resetting ends a log cycle gets them back to their initial state. + * + * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal + * state, and getting it back to a state in which it can receive log records again. + * + * This is useful in case you want to avoid logs leaking between two requests or jobs when you + * have a long running process like a worker or an application server serving multiple requests + * in one process. + * + * @author Grégoire Pineau + */ +interface ResettableInterface +{ + public function reset(); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/SignalHandler.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/SignalHandler.php new file mode 100644 index 0000000..c4b3360 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/SignalHandler.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog; + +use PostSMTP\Vendor\Psr\Log\LoggerInterface; +use PostSMTP\Vendor\Psr\Log\LogLevel; +use ReflectionExtension; +/** + * Monolog POSIX signal handler + * + * @author Robert Gust-Bardon + */ +class SignalHandler +{ + private $logger; + private $previousSignalHandler = array(); + private $signalLevelMap = array(); + private $signalRestartSyscalls = array(); + public function __construct(\PostSMTP\Vendor\Psr\Log\LoggerInterface $logger) + { + $this->logger = $logger; + } + public function registerSignalHandler($signo, $level = \PostSMTP\Vendor\Psr\Log\LogLevel::CRITICAL, $callPrevious = \true, $restartSyscalls = \true, $async = \true) + { + if (!\extension_loaded('pcntl') || !\function_exists('pcntl_signal')) { + return $this; + } + if ($callPrevious) { + if (\function_exists('pcntl_signal_get_handler')) { + $handler = \pcntl_signal_get_handler($signo); + if ($handler === \false) { + return $this; + } + $this->previousSignalHandler[$signo] = $handler; + } else { + $this->previousSignalHandler[$signo] = \true; + } + } else { + unset($this->previousSignalHandler[$signo]); + } + $this->signalLevelMap[$signo] = $level; + $this->signalRestartSyscalls[$signo] = $restartSyscalls; + if (\function_exists('pcntl_async_signals') && $async !== null) { + \pcntl_async_signals($async); + } + \pcntl_signal($signo, array($this, 'handleSignal'), $restartSyscalls); + return $this; + } + public function handleSignal($signo, array $siginfo = null) + { + static $signals = array(); + if (!$signals && \extension_loaded('pcntl')) { + $pcntl = new \ReflectionExtension('pcntl'); + $constants = $pcntl->getConstants(); + if (!$constants) { + // HHVM 3.24.2 returns an empty array. + $constants = \get_defined_constants(\true); + $constants = $constants['Core']; + } + foreach ($constants as $name => $value) { + if (\substr($name, 0, 3) === 'SIG' && $name[3] !== '_' && \is_int($value)) { + $signals[$value] = $name; + } + } + unset($constants); + } + $level = isset($this->signalLevelMap[$signo]) ? $this->signalLevelMap[$signo] : \PostSMTP\Vendor\Psr\Log\LogLevel::CRITICAL; + $signal = isset($signals[$signo]) ? $signals[$signo] : $signo; + $context = isset($siginfo) ? $siginfo : array(); + $this->logger->log($level, \sprintf('Program received signal %s', $signal), $context); + if (!isset($this->previousSignalHandler[$signo])) { + return; + } + if ($this->previousSignalHandler[$signo] === \true || $this->previousSignalHandler[$signo] === \SIG_DFL) { + if (\extension_loaded('pcntl') && \function_exists('pcntl_signal') && \function_exists('pcntl_sigprocmask') && \function_exists('pcntl_signal_dispatch') && \extension_loaded('posix') && \function_exists('posix_getpid') && \function_exists('posix_kill')) { + $restartSyscalls = isset($this->signalRestartSyscalls[$signo]) ? $this->signalRestartSyscalls[$signo] : \true; + \pcntl_signal($signo, \SIG_DFL, $restartSyscalls); + \pcntl_sigprocmask(\SIG_UNBLOCK, array($signo), $oldset); + \posix_kill(\posix_getpid(), $signo); + \pcntl_signal_dispatch(); + \pcntl_sigprocmask(\SIG_SETMASK, $oldset); + \pcntl_signal($signo, array($this, 'handleSignal'), $restartSyscalls); + } + } elseif (\is_callable($this->previousSignalHandler[$signo])) { + if (\PHP_VERSION_ID >= 70100) { + $this->previousSignalHandler[$signo]($signo, $siginfo); + } else { + $this->previousSignalHandler[$signo]($signo); + } + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Utils.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Utils.php new file mode 100644 index 0000000..c681eaf --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/monolog/monolog/src/Monolog/Utils.php @@ -0,0 +1,162 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Monolog; + +class Utils +{ + /** + * @internal + */ + public static function getClass($object) + { + $class = \get_class($object); + return 'c' === $class[0] && 0 === \strpos($class, "class@anonymous\0") ? \get_parent_class($class) . '@anonymous' : $class; + } + /** + * Makes sure if a relative path is passed in it is turned into an absolute path + * + * @param string $streamUrl stream URL or path without protocol + * + * @return string + */ + public static function canonicalizePath($streamUrl) + { + $prefix = ''; + if ('file://' === \substr($streamUrl, 0, 7)) { + $streamUrl = \substr($streamUrl, 7); + $prefix = 'file://'; + } + // other type of stream, not supported + if (\false !== \strpos($streamUrl, '://')) { + return $streamUrl; + } + // already absolute + if (\substr($streamUrl, 0, 1) === '/' || \substr($streamUrl, 1, 1) === ':' || \substr($streamUrl, 0, 2) === '\\\\') { + return $prefix . $streamUrl; + } + $streamUrl = \getcwd() . '/' . $streamUrl; + return $prefix . $streamUrl; + } + /** + * Return the JSON representation of a value + * + * @param mixed $data + * @param int $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE + * @param bool $ignoreErrors whether to ignore encoding errors or to throw on error, when ignored and the encoding fails, "null" is returned which is valid json for null + * @throws \RuntimeException if encoding fails and errors are not ignored + * @return string + */ + public static function jsonEncode($data, $encodeFlags = null, $ignoreErrors = \false) + { + if (null === $encodeFlags && \version_compare(\PHP_VERSION, '5.4.0', '>=')) { + $encodeFlags = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE; + } + if ($ignoreErrors) { + $json = @\json_encode($data, $encodeFlags); + if (\false === $json) { + return 'null'; + } + return $json; + } + $json = \json_encode($data, $encodeFlags); + if (\false === $json) { + $json = self::handleJsonError(\json_last_error(), $data); + } + return $json; + } + /** + * Handle a json_encode failure. + * + * If the failure is due to invalid string encoding, try to clean the + * input and encode again. If the second encoding attempt fails, the + * inital error is not encoding related or the input can't be cleaned then + * raise a descriptive exception. + * + * @param int $code return code of json_last_error function + * @param mixed $data data that was meant to be encoded + * @param int $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE + * @throws \RuntimeException if failure can't be corrected + * @return string JSON encoded data after error correction + */ + public static function handleJsonError($code, $data, $encodeFlags = null) + { + if ($code !== \JSON_ERROR_UTF8) { + self::throwEncodeError($code, $data); + } + if (\is_string($data)) { + self::detectAndCleanUtf8($data); + } elseif (\is_array($data)) { + \array_walk_recursive($data, array('PostSMTP\\Vendor\\Monolog\\Utils', 'detectAndCleanUtf8')); + } else { + self::throwEncodeError($code, $data); + } + if (null === $encodeFlags && \version_compare(\PHP_VERSION, '5.4.0', '>=')) { + $encodeFlags = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE; + } + $json = \json_encode($data, $encodeFlags); + if ($json === \false) { + self::throwEncodeError(\json_last_error(), $data); + } + return $json; + } + /** + * Throws an exception according to a given code with a customized message + * + * @param int $code return code of json_last_error function + * @param mixed $data data that was meant to be encoded + * @throws \RuntimeException + */ + private static function throwEncodeError($code, $data) + { + switch ($code) { + case \JSON_ERROR_DEPTH: + $msg = 'Maximum stack depth exceeded'; + break; + case \JSON_ERROR_STATE_MISMATCH: + $msg = 'Underflow or the modes mismatch'; + break; + case \JSON_ERROR_CTRL_CHAR: + $msg = 'Unexpected control character found'; + break; + case \JSON_ERROR_UTF8: + $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded'; + break; + default: + $msg = 'Unknown error'; + } + throw new \RuntimeException('JSON encoding failed: ' . $msg . '. Encoding: ' . \var_export($data, \true)); + } + /** + * Detect invalid UTF-8 string characters and convert to valid UTF-8. + * + * Valid UTF-8 input will be left unmodified, but strings containing + * invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed + * original encoding of ISO-8859-15. This conversion may result in + * incorrect output if the actual encoding was not ISO-8859-15, but it + * will be clean UTF-8 output and will not rely on expensive and fragile + * detection algorithms. + * + * Function converts the input in place in the passed variable so that it + * can be used as a callback for array_walk_recursive. + * + * @param mixed $data Input to check and convert if needed, passed by ref + * @private + */ + public static function detectAndCleanUtf8(&$data) + { + if (\is_string($data) && !\preg_match('//u', $data)) { + $data = \preg_replace_callback('/[\\x80-\\xFF]+/', function ($m) { + return \utf8_encode($m[0]); + }, $data); + $data = \str_replace(array('¤', '¦', '¨', '´', '¸', '¼', '½', '¾'), array('€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'), $data); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/LICENSE.txt b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/LICENSE.txt new file mode 100644 index 0000000..91acaca --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/LICENSE.txt @@ -0,0 +1,48 @@ +The MIT License (MIT) + +Copyright (c) 2016 - 2022 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------ +This library was based on the work of Steve "Sc00bz" Thomas. +------------------------------------------------------------------------------ + +The MIT License (MIT) + +Copyright (c) 2014 Steve Thomas + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base32.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base32.php new file mode 100644 index 0000000..156b4d8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base32.php @@ -0,0 +1,404 @@ + 96 && $src < 123) $ret += $src - 97 + 1; // -64 + $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 96; + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (0x31 - $src & $src - 0x38) >> 8 & $src - 23; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src) : int + { + $ret = -1; + // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 + $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64; + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (0x31 - $src & $src - 0x38) >> 8 & $src - 23; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src) : string + { + $diff = 0x61; + // if ($src > 25) $ret -= 72; + $diff -= 25 - $src >> 8 & 73; + return \pack('C', $src + $diff); + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src) : string + { + $diff = 0x41; + // if ($src > 25) $ret -= 40; + $diff -= 25 - $src >> 8 & 41; + return \pack('C', $src + $diff); + } + /** + * @param string $encodedString + * @param bool $upper + * @return string + */ + public static function decodeNoPadding(string $encodedString, bool $upper = \false) : string + { + $srcLen = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7 && $j < $srcLen; ++$j) { + if ($encodedString[$srcLen - $j - 1] === '=') { + throw new \InvalidArgumentException("decodeNoPadding() doesn't tolerate padding"); + } + } + } + return static::doDecode($encodedString, $upper, \true); + } + /** + * Base32 decoding + * + * @param string $src + * @param bool $upper + * @param bool $strictPadding + * @return string + * + * @throws TypeError + * @psalm-suppress RedundantCondition + */ + protected static function doDecode(string $src, bool $upper = \false, bool $strictPadding = \false) : string + { + // We do this to reduce code duplication: + $method = $upper ? 'decode5BitsUpper' : 'decode5Bits'; + // Remove padding + $srcLen = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($src); + if ($srcLen === 0) { + return ''; + } + if ($strictPadding) { + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7; ++$j) { + if ($src[$srcLen - 1] === '=') { + $srcLen--; + } else { + break; + } + } + } + if (($srcLen & 7) === 1) { + throw new \RangeException('Incorrect padding'); + } + } else { + $src = \rtrim($src, '='); + $srcLen = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($src); + } + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 8 <= $srcLen; $i += 8) { + /** @var array $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($src, $i, 8)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + /** @var int $c7 */ + $c7 = static::$method($chunk[8]); + $dest .= \pack('CCCCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff, ($c4 << 7 | $c5 << 2 | $c6 >> 3) & 0xff, ($c6 << 5 | $c7) & 0xff); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($src, $i, $srcLen - $i)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + if ($i + 6 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + $dest .= \pack('CCCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff, ($c4 << 7 | $c5 << 2 | $c6 >> 3) & 0xff); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; + if ($strictPadding) { + $err |= $c6 << 5 & 0xff; + } + } elseif ($i + 5 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + $dest .= \pack('CCCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff, ($c4 << 7 | $c5 << 2) & 0xff); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; + } elseif ($i + 4 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + $dest .= \pack('CCC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff, ($c3 << 4 | $c4 >> 1) & 0xff); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; + if ($strictPadding) { + $err |= $c4 << 7 & 0xff; + } + } elseif ($i + 3 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + $dest .= \pack('CC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1 | $c3 >> 4) & 0xff); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + if ($strictPadding) { + $err |= $c3 << 4 & 0xff; + } + } elseif ($i + 2 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + $dest .= \pack('CC', ($c0 << 3 | $c1 >> 2) & 0xff, ($c1 << 6 | $c2 << 1) & 0xff); + $err |= ($c0 | $c1 | $c2) >> 8; + if ($strictPadding) { + $err |= $c2 << 6 & 0xff; + } + } elseif ($i + 1 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + $dest .= \pack('C', ($c0 << 3 | $c1 >> 2) & 0xff); + $err |= ($c0 | $c1) >> 8; + if ($strictPadding) { + $err |= $c1 << 6 & 0xff; + } + } else { + $dest .= \pack('C', $c0 << 3 & 0xff); + $err |= $c0 >> 8; + } + } + $check = $err === 0; + if (!$check) { + throw new \RangeException('Base32::doDecode() only expects characters in the correct base32 alphabet'); + } + return $dest; + } + /** + * Base32 Encoding + * + * @param string $src + * @param bool $upper + * @param bool $pad + * @return string + * @throws TypeError + */ + protected static function doEncode(string $src, bool $upper = \false, $pad = \true) : string + { + // We do this to reduce code duplication: + $method = $upper ? 'encode5BitsUpper' : 'encode5Bits'; + $dest = ''; + $srcLen = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($src); + // Main loop (no padding): + for ($i = 0; $i + 5 <= $srcLen; $i += 5) { + /** @var array $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($src, $i, 5)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $b4 = $chunk[5]; + $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method(($b1 << 4 | $b2 >> 4) & 31) . static::$method(($b2 << 1 | $b3 >> 7) & 31) . static::$method($b3 >> 2 & 31) . static::$method(($b3 << 3 | $b4 >> 5) & 31) . static::$method($b4 & 31); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 3 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method(($b1 << 4 | $b2 >> 4) & 31) . static::$method(($b2 << 1 | $b3 >> 7) & 31) . static::$method($b3 >> 2 & 31) . static::$method($b3 << 3 & 31); + if ($pad) { + $dest .= '='; + } + } elseif ($i + 2 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method(($b1 << 4 | $b2 >> 4) & 31) . static::$method($b2 << 1 & 31); + if ($pad) { + $dest .= '==='; + } + } elseif ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= static::$method($b0 >> 3 & 31) . static::$method(($b0 << 2 | $b1 >> 6) & 31) . static::$method($b1 >> 1 & 31) . static::$method($b1 << 4 & 31); + if ($pad) { + $dest .= '===='; + } + } else { + $dest .= static::$method($b0 >> 3 & 31) . static::$method($b0 << 2 & 31); + if ($pad) { + $dest .= '======'; + } + } + } + return $dest; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base32Hex.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base32Hex.php new file mode 100644 index 0000000..d4f9b6b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base32Hex.php @@ -0,0 +1,98 @@ + 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src - 47; + // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 + $ret += (0x60 - $src & $src - 0x77) >> 8 & $src - 86; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src) : int + { + $ret = -1; + // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src - 47; + // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 + $ret += (0x40 - $src & $src - 0x57) >> 8 & $src - 54; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src) : string + { + $src += 0x30; + // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 + $src += 0x39 - $src >> 8 & 39; + return \pack('C', $src); + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src) : string + { + $src += 0x30; + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += 0x39 - $src >> 8 & 7; + return \pack('C', $src); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64.php new file mode 100644 index 0000000..62e4486 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64.php @@ -0,0 +1,257 @@ + $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($src, $i, 3)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . static::encode6Bits(($b1 << 2 | $b2 >> 6) & 63) . static::encode6Bits($b2 & 63); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits(($b0 << 4 | $b1 >> 4) & 63) . static::encode6Bits($b1 << 2 & 63); + if ($pad) { + $dest .= '='; + } + } else { + $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits($b0 << 4 & 63); + if ($pad) { + $dest .= '=='; + } + } + } + return $dest; + } + /** + * decode from base64 into binary + * + * Base64 character set "./[A-Z][a-z][0-9]" + * + * @param string $encodedString + * @param bool $strictPadding + * @return string + * + * @throws RangeException + * @throws TypeError + * @psalm-suppress RedundantCondition + */ + public static function decode(string $encodedString, bool $strictPadding = \false) : string + { + // Remove padding + $srcLen = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + if ($strictPadding) { + if (($srcLen & 3) === 0) { + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + } + } + } + if (($srcLen & 3) === 1) { + throw new \RangeException('Incorrect padding'); + } + if ($encodedString[$srcLen - 1] === '=') { + throw new \RangeException('Incorrect padding'); + } + } else { + $encodedString = \rtrim($encodedString, '='); + $srcLen = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($encodedString); + } + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 4 <= $srcLen; $i += 4) { + /** @var array $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($encodedString, $i, 4)); + $c0 = static::decode6Bits($chunk[1]); + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $c3 = static::decode6Bits($chunk[4]); + $dest .= \pack('CCC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff, ($c2 << 6 | $c3) & 0xff); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeSubstr($encodedString, $i, $srcLen - $i)); + $c0 = static::decode6Bits($chunk[1]); + if ($i + 2 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $dest .= \pack('CC', ($c0 << 2 | $c1 >> 4) & 0xff, ($c1 << 4 | $c2 >> 2) & 0xff); + $err |= ($c0 | $c1 | $c2) >> 8; + if ($strictPadding) { + $err |= $c2 << 6 & 0xff; + } + } elseif ($i + 1 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $dest .= \pack('C', ($c0 << 2 | $c1 >> 4) & 0xff); + $err |= ($c0 | $c1) >> 8; + if ($strictPadding) { + $err |= $c1 << 4 & 0xff; + } + } elseif ($strictPadding) { + $err |= 1; + } + } + $check = $err === 0; + if (!$check) { + throw new \RangeException('Base64::decode() only expects characters in the correct base64 alphabet'); + } + return $dest; + } + /** + * @param string $encodedString + * @return string + */ + public static function decodeNoPadding(string $encodedString) : string + { + $srcLen = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + if (($srcLen & 3) === 0) { + if ($encodedString[$srcLen - 1] === '=') { + throw new \InvalidArgumentException("decodeNoPadding() doesn't tolerate padding"); + } + if (($srcLen & 3) > 1) { + if ($encodedString[$srcLen - 2] === '=') { + throw new \InvalidArgumentException("decodeNoPadding() doesn't tolerate padding"); + } + } + } + return static::decode($encodedString, \true); + } + /** + * Uses bitwise operators instead of table-lookups to turn 6-bit integers + * into 8-bit integers. + * + * Base64 character set: + * [A-Z] [a-z] [0-9] + / + * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f + * + * @param int $src + * @return int + */ + protected static function decode6Bits(int $src) : int + { + $ret = -1; + // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64; + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 70; + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 5; + // if ($src == 0x2b) $ret += 62 + 1; + $ret += (0x2a - $src & $src - 0x2c) >> 8 & 63; + // if ($src == 0x2f) ret += 63 + 1; + $ret += (0x2e - $src & $src - 0x30) >> 8 & 64; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src) : string + { + $diff = 0x41; + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += 25 - $src >> 8 & 6; + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= 51 - $src >> 8 & 75; + // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 + $diff -= 61 - $src >> 8 & 15; + // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 + $diff += 62 - $src >> 8 & 3; + return \pack('C', $src + $diff); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlash.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlash.php new file mode 100644 index 0000000..ecd331f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlash.php @@ -0,0 +1,78 @@ + 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 + $ret += (0x2d - $src & $src - 0x30) >> 8 & $src - 45; + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 + $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 62; + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 + $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 68; + // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 + $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 7; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src) : string + { + $src += 0x2e; + // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 + $src += 0x2f - $src >> 8 & 17; + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += 0x5a - $src >> 8 & 6; + // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 + $src -= 0x7a - $src >> 8 & 75; + return \pack('C', $src); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php new file mode 100644 index 0000000..2aa94ef --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php @@ -0,0 +1,74 @@ + 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 + $ret += (0x2d - $src & $src - 0x3a) >> 8 & $src - 45; + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 + $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 52; + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 + $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 58; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src) : string + { + $src += 0x2e; + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += 0x39 - $src >> 8 & 7; + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += 0x5a - $src >> 8 & 6; + return \pack('C', $src); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64UrlSafe.php new file mode 100644 index 0000000..0ae7631 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Base64UrlSafe.php @@ -0,0 +1,82 @@ + 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (0x40 - $src & $src - 0x5b) >> 8 & $src - 64; + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (0x60 - $src & $src - 0x7b) >> 8 & $src - 70; + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (0x2f - $src & $src - 0x3a) >> 8 & $src + 5; + // if ($src == 0x2c) $ret += 62 + 1; + $ret += (0x2c - $src & $src - 0x2e) >> 8 & 63; + // if ($src == 0x5f) ret += 63 + 1; + $ret += (0x5e - $src & $src - 0x60) >> 8 & 64; + return $ret; + } + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src) : string + { + $diff = 0x41; + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += 25 - $src >> 8 & 6; + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= 51 - $src >> 8 & 75; + // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 + $diff -= 61 - $src >> 8 & 13; + // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 + $diff += 62 - $src >> 8 & 49; + return \pack('C', $src + $diff); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Binary.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Binary.php new file mode 100644 index 0000000..b8d3767 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/Binary.php @@ -0,0 +1,85 @@ + $chunk */ + $chunk = \unpack('C', $binString[$i]); + $c = $chunk[1] & 0xf; + $b = $chunk[1] >> 4; + $hex .= \pack('CC', 87 + $b + ($b - 10 >> 8 & ~38), 87 + $c + ($c - 10 >> 8 & ~38)); + } + return $hex; + } + /** + * Convert a binary string into a hexadecimal string without cache-timing + * leaks, returning uppercase letters (as per RFC 4648) + * + * @param string $binString (raw binary) + * @return string + * @throws TypeError + */ + public static function encodeUpper(string $binString) : string + { + $hex = ''; + $len = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($binString); + for ($i = 0; $i < $len; ++$i) { + /** @var array $chunk */ + $chunk = \unpack('C', $binString[$i]); + $c = $chunk[1] & 0xf; + $b = $chunk[1] >> 4; + $hex .= \pack('CC', 55 + $b + ($b - 10 >> 8 & ~6), 55 + $c + ($c - 10 >> 8 & ~6)); + } + return $hex; + } + /** + * Convert a hexadecimal string into a binary string without cache-timing + * leaks + * + * @param string $encodedString + * @param bool $strictPadding + * @return string (raw binary) + * @throws RangeException + */ + public static function decode(string $encodedString, bool $strictPadding = \false) : string + { + $hex_pos = 0; + $bin = ''; + $c_acc = 0; + $hex_len = \PostSMTP\Vendor\ParagonIE\ConstantTime\Binary::safeStrlen($encodedString); + $state = 0; + if (($hex_len & 1) !== 0) { + if ($strictPadding) { + throw new \RangeException('Expected an even number of hexadecimal characters'); + } else { + $encodedString = '0' . $encodedString; + ++$hex_len; + } + } + /** @var array $chunk */ + $chunk = \unpack('C*', $encodedString); + while ($hex_pos < $hex_len) { + ++$hex_pos; + $c = $chunk[$hex_pos]; + $c_num = $c ^ 48; + $c_num0 = $c_num - 10 >> 8; + $c_alpha = ($c & ~32) - 55; + $c_alpha0 = ($c_alpha - 10 ^ $c_alpha - 16) >> 8; + if (($c_num0 | $c_alpha0) === 0) { + throw new \RangeException('Expected hexadecimal character'); + } + $c_val = $c_num0 & $c_num | $c_alpha & $c_alpha0; + if ($state === 0) { + $c_acc = $c_val * 16; + } else { + $bin .= \pack('C', $c_acc | $c_val); + } + $state ^= 1; + } + return $bin; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/RFC4648.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/RFC4648.php new file mode 100644 index 0000000..ff5ff21 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/paragonie/constant_time_encoding/src/RFC4648.php @@ -0,0 +1,176 @@ + "Zm9v" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64Encode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64::encode($str); + } + /** + * RFC 4648 Base64 decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64Decode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64::decode($str, \true); + } + /** + * RFC 4648 Base64 (URL Safe) encoding + * + * "foo" -> "Zm9v" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64UrlSafeEncode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64UrlSafe::encode($str); + } + /** + * RFC 4648 Base64 (URL Safe) decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64UrlSafeDecode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64UrlSafe::decode($str, \true); + } + /** + * RFC 4648 Base32 encoding + * + * "foo" -> "MZXW6===" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32Encode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base32::encodeUpper($str); + } + /** + * RFC 4648 Base32 encoding + * + * "MZXW6===" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32Decode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base32::decodeUpper($str, \true); + } + /** + * RFC 4648 Base32-Hex encoding + * + * "foo" -> "CPNMU===" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32HexEncode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base32::encodeUpper($str); + } + /** + * RFC 4648 Base32-Hex decoding + * + * "CPNMU===" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32HexDecode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Base32::decodeUpper($str, \true); + } + /** + * RFC 4648 Base16 decoding + * + * "foo" -> "666F6F" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base16Encode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Hex::encodeUpper($str); + } + /** + * RFC 4648 Base16 decoding + * + * "666F6F" -> "foo" + * + * @param string $str + * @return string + */ + public static function base16Decode(string $str) : string + { + return \PostSMTP\Vendor\ParagonIE\ConstantTime\Hex::decode($str, \true); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/LICENSE b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/LICENSE new file mode 100644 index 0000000..e7214eb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2011-2019 TerraFrost and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php new file mode 100644 index 0000000..2b91b37 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php @@ -0,0 +1,454 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Common\Functions; + +use PostSMTP\Vendor\ParagonIE\ConstantTime\Base64; +use PostSMTP\Vendor\ParagonIE\ConstantTime\Base64UrlSafe; +use PostSMTP\Vendor\ParagonIE\ConstantTime\Hex; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField; +/** + * Common String Functions + * + * @author Jim Wigginton + */ +abstract class Strings +{ + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + */ + public static function shift(&$string, $index = 1) + { + $substr = \substr($string, 0, $index); + $string = \substr($string, $index); + return $substr; + } + /** + * String Pop + * + * Inspired by array_pop + * + * @param string $string + * @param int $index + * @return string + */ + public static function pop(&$string, $index = 1) + { + $substr = \substr($string, -$index); + $string = \substr($string, 0, -$index); + return $substr; + } + /** + * Parse SSH2-style string + * + * Returns either an array or a boolean if $data is malformed. + * + * Valid characters for $format are as follows: + * + * C = byte + * b = boolean (true/false) + * N = uint32 + * Q = uint64 + * s = string + * i = mpint + * L = name-list + * + * uint64 is not supported. + * + * @param string $format + * @param string $data + * @return mixed + */ + public static function unpackSSH2($format, &$data) + { + $format = self::formatPack($format); + $result = []; + for ($i = 0; $i < \strlen($format); $i++) { + switch ($format[$i]) { + case 'C': + case 'b': + if (!\strlen($data)) { + throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); + } + break; + case 'N': + case 'i': + case 's': + case 'L': + if (\strlen($data) < 4) { + throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); + } + break; + case 'Q': + if (\strlen($data) < 8) { + throw new \LengthException('At least eight byte needs to be present for successful N / i / s / L decodes'); + } + break; + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + switch ($format[$i]) { + case 'C': + $result[] = \ord(self::shift($data)); + continue 2; + case 'b': + $result[] = \ord(self::shift($data)) != 0; + continue 2; + case 'N': + list(, $temp) = \unpack('N', self::shift($data, 4)); + $result[] = $temp; + continue 2; + case 'Q': + // pack() added support for Q in PHP 5.6.3 and PHP 5.6 is phpseclib 3's minimum version + // so in theory we could support this BUT, "64-bit format codes are not available for + // 32-bit versions" and phpseclib works on 32-bit installs. on 32-bit installs + // 64-bit floats can be used to get larger numbers then 32-bit signed ints would allow + // for. sure, you're not gonna get the full precision of 64-bit numbers but just because + // you need > 32-bit precision doesn't mean you need the full 64-bit precision + \extract(\unpack('Nupper/Nlower', self::shift($data, 8))); + $temp = $upper ? 4294967296 * $upper : 0; + $temp += $lower < 0 ? ($lower & 0x7ffffffff) + 0x80000000 : $lower; + // $temp = hexdec(bin2hex(self::shift($data, 8))); + $result[] = $temp; + continue 2; + } + list(, $length) = \unpack('N', self::shift($data, 4)); + if (\strlen($data) < $length) { + throw new \LengthException("{$length} bytes needed; " . \strlen($data) . ' bytes available'); + } + $temp = self::shift($data, $length); + switch ($format[$i]) { + case 'i': + $result[] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($temp, -256); + break; + case 's': + $result[] = $temp; + break; + case 'L': + $result[] = \explode(',', $temp); + } + } + return $result; + } + /** + * Create SSH2-style string + * + * @param string $format + * @param string|int|float|array|bool ...$elements + * @return string + */ + public static function packSSH2($format, ...$elements) + { + $format = self::formatPack($format); + if (\strlen($format) != \count($elements)) { + throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); + } + $result = ''; + for ($i = 0; $i < \strlen($format); $i++) { + $element = $elements[$i]; + switch ($format[$i]) { + case 'C': + if (!\is_int($element)) { + throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); + } + $result .= \pack('C', $element); + break; + case 'b': + if (!\is_bool($element)) { + throw new \InvalidArgumentException('A boolean parameter was expected.'); + } + $result .= $element ? "\1" : "\0"; + break; + case 'Q': + if (!\is_int($element) && !\is_float($element)) { + throw new \InvalidArgumentException('An integer was expected.'); + } + // 4294967296 == 1 << 32 + $result .= \pack('NN', $element / 4294967296, $element); + break; + case 'N': + if (\is_float($element)) { + $element = (int) $element; + } + if (!\is_int($element)) { + throw new \InvalidArgumentException('An integer was expected.'); + } + $result .= \pack('N', $element); + break; + case 's': + if (!self::is_stringable($element)) { + throw new \InvalidArgumentException('A string was expected.'); + } + $result .= \pack('Na*', \strlen($element), $element); + break; + case 'i': + if (!$element instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger && !$element instanceof \PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer) { + throw new \InvalidArgumentException('A phpseclib3\\Math\\BigInteger or phpseclib3\\Math\\Common\\FiniteField\\Integer object was expected.'); + } + $element = $element->toBytes(\true); + $result .= \pack('Na*', \strlen($element), $element); + break; + case 'L': + if (!\is_array($element)) { + throw new \InvalidArgumentException('An array was expected.'); + } + $element = \implode(',', $element); + $result .= \pack('Na*', \strlen($element), $element); + break; + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + } + return $result; + } + /** + * Expand a pack string + * + * Converts C5 to CCCCC, for example. + * + * @param string $format + * @return string + */ + private static function formatPack($format) + { + $parts = \preg_split('#(\\d+)#', $format, -1, \PREG_SPLIT_DELIM_CAPTURE); + $format = ''; + for ($i = 1; $i < \count($parts); $i += 2) { + $format .= \substr($parts[$i - 1], 0, -1) . \str_repeat(\substr($parts[$i - 1], -1), $parts[$i]); + } + $format .= $parts[$i - 1]; + return $format; + } + /** + * Convert binary data into bits + * + * bin2hex / hex2bin refer to base-256 encoded data as binary, whilst + * decbin / bindec refer to base-2 encoded data as binary. For the purposes + * of this function, bin refers to base-256 encoded data whilst bits refers + * to base-2 encoded data + * + * @param string $x + * @return string + */ + public static function bits2bin($x) + { + /* + // the pure-PHP approach is faster than the GMP approach + if (function_exists('gmp_export')) { + return strlen($x) ? gmp_export(gmp_init($x, 2)) : gmp_init(0); + } + */ + if (\preg_match('#[^01]#', $x)) { + throw new \RuntimeException('The only valid characters are 0 and 1'); + } + if (!\defined('PHP_INT_MIN')) { + \define('PHP_INT_MIN', ~\PHP_INT_MAX); + } + $length = \strlen($x); + if (!$length) { + return ''; + } + $block_size = \PHP_INT_SIZE << 3; + $pad = $block_size - $length % $block_size; + if ($pad != $block_size) { + $x = \str_repeat('0', $pad) . $x; + } + $parts = \str_split($x, $block_size); + $str = ''; + foreach ($parts as $part) { + $xor = $part[0] == '1' ? \PHP_INT_MIN : 0; + $part[0] = '0'; + $str .= \pack(\PHP_INT_SIZE == 4 ? 'N' : 'J', $xor ^ eval('return 0b' . $part . ';')); + } + return \ltrim($str, "\0"); + } + /** + * Convert bits to binary data + * + * @param string $x + * @return string + */ + public static function bin2bits($x, $trim = \true) + { + /* + // the pure-PHP approach is slower than the GMP approach BUT + // i want to the pure-PHP version to be easily unit tested as well + if (function_exists('gmp_import')) { + return gmp_strval(gmp_import($x), 2); + } + */ + $len = \strlen($x); + $mod = $len % \PHP_INT_SIZE; + if ($mod) { + $x = \str_pad($x, $len + \PHP_INT_SIZE - $mod, "\0", \STR_PAD_LEFT); + } + $bits = ''; + if (\PHP_INT_SIZE == 4) { + $digits = \unpack('N*', $x); + foreach ($digits as $digit) { + $bits .= \sprintf('%032b', $digit); + } + } else { + $digits = \unpack('J*', $x); + foreach ($digits as $digit) { + $bits .= \sprintf('%064b', $digit); + } + } + return $trim ? \ltrim($bits, '0') : $bits; + } + /** + * Switch Endianness Bit Order + * + * @param string $x + * @return string + */ + public static function switchEndianness($x) + { + $r = ''; + for ($i = \strlen($x) - 1; $i >= 0; $i--) { + $b = \ord($x[$i]); + if (\PHP_INT_SIZE === 8) { + // 3 operations + // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv + $r .= \chr(($b * 0x202020202 & 0x10884422010) % 1023); + } else { + // 7 operations + // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits + $p1 = $b * 0x802 & 0x22110; + $p2 = $b * 0x8020 & 0x88440; + $r .= \chr(($p1 | $p2) * 0x10101 >> 16); + } + } + return $r; + } + /** + * Increment the current string + * + * @param string $var + * @return string + */ + public static function increment_str(&$var) + { + if (\function_exists('sodium_increment')) { + $var = \strrev($var); + \sodium_increment($var); + $var = \strrev($var); + return $var; + } + for ($i = 4; $i <= \strlen($var); $i += 4) { + $temp = \substr($var, -$i, 4); + switch ($temp) { + case "����": + $var = \substr_replace($var, "\0\0\0\0", -$i, 4); + break; + case "���": + $var = \substr_replace($var, "�\0\0\0", -$i, 4); + return $var; + default: + $temp = \unpack('Nnum', $temp); + $var = \substr_replace($var, \pack('N', $temp['num'] + 1), -$i, 4); + return $var; + } + } + $remainder = \strlen($var) % 4; + if ($remainder == 0) { + return $var; + } + $temp = \unpack('Nnum', \str_pad(\substr($var, 0, $remainder), 4, "\0", \STR_PAD_LEFT)); + $temp = \substr(\pack('N', $temp['num'] + 1), -$remainder); + $var = \substr_replace($var, $temp, 0, $remainder); + return $var; + } + /** + * Find whether the type of a variable is string (or could be converted to one) + * + * @param mixed $var + * @return bool + * @psalm-assert-if-true string|\Stringable $var + */ + public static function is_stringable($var) + { + return \is_string($var) || \is_object($var) && \method_exists($var, '__toString'); + } + /** + * Constant Time Base64-decoding + * + * ParagoneIE\ConstantTime doesn't use libsodium if it's available so we'll do so + * ourselves. see https://github.com/paragonie/constant_time_encoding/issues/39 + * + * @param string $data + * @return string + */ + public static function base64_decode($data) + { + return \function_exists('sodium_base642bin') ? \sodium_base642bin($data, \SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING, '=') : \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64::decode($data); + } + /** + * Constant Time Base64-decoding (URL safe) + * + * @param string $data + * @return string + */ + public static function base64url_decode($data) + { + // return self::base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); + return \function_exists('sodium_base642bin') ? \sodium_base642bin($data, \SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING, '=') : \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64UrlSafe::decode($data); + } + /** + * Constant Time Base64-encoding + * + * @param string $data + * @return string + */ + public static function base64_encode($data) + { + return \function_exists('sodium_bin2base64') ? \sodium_bin2base64($data, \SODIUM_BASE64_VARIANT_ORIGINAL) : \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64::encode($data); + } + /** + * Constant Time Base64-encoding (URL safe) + * + * @param string $data + * @return string + */ + public static function base64url_encode($data) + { + // return str_replace(['+', '/'], ['-', '_'], self::base64_encode($data)); + return \function_exists('sodium_bin2base64') ? \sodium_bin2base64($data, \SODIUM_BASE64_VARIANT_URLSAFE) : \PostSMTP\Vendor\ParagonIE\ConstantTime\Base64UrlSafe::encode($data); + } + /** + * Constant Time Hex Decoder + * + * @param string $data + * @return string + */ + public static function hex2bin($data) + { + return \function_exists('sodium_hex2bin') ? \sodium_hex2bin($data) : \PostSMTP\Vendor\ParagonIE\ConstantTime\Hex::decode($data); + } + /** + * Constant Time Hex Encoder + * + * @param string $data + * @return string + */ + public static function bin2hex($data) + { + return \function_exists('sodium_bin2hex') ? \sodium_bin2hex($data) : \PostSMTP\Vendor\ParagonIE\ConstantTime\Hex::encode($data); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/AES.php new file mode 100644 index 0000000..5296d75 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/AES.php @@ -0,0 +1,112 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $aes->decrypt($aes->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt; + +/** + * Pure-PHP implementation of AES. + * + * @author Jim Wigginton + */ +class AES extends \PostSMTP\Vendor\phpseclib3\Crypt\Rijndael +{ + /** + * Dummy function + * + * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. + * + * @see \phpseclib3\Crypt\Rijndael::setBlockLength() + * @param int $length + * @throws \BadMethodCallException anytime it's called + */ + public function setBlockLength($length) + { + throw new \BadMethodCallException('The block length cannot be set for AES.'); + } + /** + * Sets the key length + * + * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length + * + * @see \phpseclib3\Crypt\Rijndael:setKeyLength() + * @param int $length + * @throws \LengthException if the key length isn't supported + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 192: + case 256: + break; + default: + throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); + } + parent::setKeyLength($length); + } + /** + * Sets the key. + * + * Rijndael supports five different key lengths, AES only supports three. + * + * @see \phpseclib3\Crypt\Rijndael:setKey() + * @see setKeyLength() + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (\strlen($key)) { + case 16: + case 24: + case 32: + break; + default: + throw new \LengthException('Key of size ' . \strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + parent::setKey($key); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php new file mode 100644 index 0000000..1a1177c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php @@ -0,0 +1,507 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common; + +use PostSMTP\Vendor\phpseclib3\Crypt\DSA; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA; +use PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Base Class for all asymmetric cipher classes + * + * @author Jim Wigginton + */ +abstract class AsymmetricKey +{ + /** + * Precomputed Zero + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $zero; + /** + * Precomputed One + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $one; + /** + * Format of the loaded key + * + * @var string + */ + protected $format; + /** + * Hash function + * + * @var \phpseclib3\Crypt\Hash + */ + protected $hash; + /** + * HMAC function + * + * @var \phpseclib3\Crypt\Hash + */ + private $hmac; + /** + * Supported plugins (lower case) + * + * @see self::initialize_static_variables() + * @var array + */ + private static $plugins = []; + /** + * Invisible plugins + * + * @see self::initialize_static_variables() + * @var array + */ + private static $invisiblePlugins = []; + /** + * Available Engines + * + * @var boolean[] + */ + protected static $engines = []; + /** + * Key Comment + * + * @var null|string + */ + private $comment; + /** + * @param string $type + * @return string + */ + public abstract function toString($type, array $options = []); + /** + * The constructor + */ + protected function __construct() + { + self::initialize_static_variables(); + $this->hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha256'); + $this->hmac = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha256'); + } + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$zero)) { + self::$zero = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(0); + self::$one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + self::loadPlugins('Keys'); + if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') { + self::loadPlugins('Signature'); + } + } + /** + * Load the key + * + * @param string $key + * @param string $password optional + * @return AsymmetricKey + */ + public static function load($key, $password = \false) + { + self::initialize_static_variables(); + $components = \false; + foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { + if (isset(self::$invisiblePlugins[static::ALGORITHM]) && \in_array($format, self::$invisiblePlugins[static::ALGORITHM])) { + continue; + } + try { + $components = $format::load($key, $password); + } catch (\Exception $e) { + $components = \false; + } + if ($components !== \false) { + break; + } + } + if ($components === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('Unable to read key'); + } + $components['format'] = $format; + $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; + $comment = isset($components['comment']) ? $components['comment'] : null; + $new = static::onLoad($components); + $new->format = $format; + $new->comment = $comment; + return $new instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey ? $new->withPassword($password) : $new; + } + /** + * Loads a private key + * + * @return PrivateKey + * @param string|array $key + * @param string $password optional + */ + public static function loadPrivateKey($key, $password = '') + { + $key = self::load($key, $password); + if (!$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + /** + * Loads a public key + * + * @return PublicKey + * @param string|array $key + */ + public static function loadPublicKey($key) + { + $key = self::load($key); + if (!$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PublicKey) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string|array $key + */ + public static function loadParameters($key) + { + $key = self::load($key); + if (!$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey && !$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PublicKey) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } + /** + * Load the key, assuming a specific format + * + * @param string $type + * @param string $key + * @param string $password optional + * @return static + */ + public static function loadFormat($type, $key, $password = \false) + { + self::initialize_static_variables(); + $components = \false; + $format = \strtolower($type); + if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) { + $format = self::$plugins[static::ALGORITHM]['Keys'][$format]; + $components = $format::load($key, $password); + } + if ($components === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('Unable to read key'); + } + $components['format'] = $format; + $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; + $new = static::onLoad($components); + $new->format = $format; + return $new instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey ? $new->withPassword($password) : $new; + } + /** + * Loads a private key + * + * @return PrivateKey + * @param string $type + * @param string $key + * @param string $password optional + */ + public static function loadPrivateKeyFormat($type, $key, $password = \false) + { + $key = self::loadFormat($type, $key, $password); + if (!$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + /** + * Loads a public key + * + * @return PublicKey + * @param string $type + * @param string $key + */ + public static function loadPublicKeyFormat($type, $key) + { + $key = self::loadFormat($type, $key); + if (!$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PublicKey) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string $type + * @param string|array $key + */ + public static function loadParametersFormat($type, $key) + { + $key = self::loadFormat($type, $key); + if (!$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey && !$key instanceof \PostSMTP\Vendor\phpseclib3\Crypt\Common\PublicKey) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } + /** + * Validate Plugin + * + * @param string $format + * @param string $type + * @param string $method optional + * @return mixed + */ + protected static function validatePlugin($format, $type, $method = null) + { + $type = \strtolower($type); + if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException("{$type} is not a supported format"); + } + $type = self::$plugins[static::ALGORITHM][$format][$type]; + if (isset($method) && !\method_exists($type, $method)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException("{$type} does not implement {$method}"); + } + return $type; + } + /** + * Load Plugins + * + * @param string $format + */ + private static function loadPlugins($format) + { + if (!isset(self::$plugins[static::ALGORITHM][$format])) { + self::$plugins[static::ALGORITHM][$format] = []; + foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $name = $file->getBasename('.php'); + if ($name[0] == '.') { + continue; + } + $type = 'PostSMTP\\Vendor\\phpseclib3\\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name; + $reflect = new \ReflectionClass($type); + if ($reflect->isTrait()) { + continue; + } + self::$plugins[static::ALGORITHM][$format][\strtolower($name)] = $type; + if ($reflect->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM][] = $type; + } + } + } + } + /** + * Returns a list of supported formats. + * + * @return array + */ + public static function getSupportedKeyFormats() + { + self::initialize_static_variables(); + return self::$plugins[static::ALGORITHM]['Keys']; + } + /** + * Add a fileformat plugin + * + * The plugin needs to either already be loaded or be auto-loadable. + * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin. + * + * @see self::load() + * @param string $fullname + * @return bool + */ + public static function addFileFormat($fullname) + { + self::initialize_static_variables(); + if (\class_exists($fullname)) { + $meta = new \ReflectionClass($fullname); + $shortname = $meta->getShortName(); + self::$plugins[static::ALGORITHM]['Keys'][\strtolower($shortname)] = $fullname; + if ($meta->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM] = \strtolower($name); + } + } + } + /** + * Returns the format of the loaded key. + * + * If the key that was loaded wasn't in a valid or if the key was auto-generated + * with RSA::createKey() then this will throw an exception. + * + * @see self::load() + * @return mixed + */ + public function getLoadedFormat() + { + if (empty($this->format)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); + } + $meta = new \ReflectionClass($this->format); + return $meta->getShortName(); + } + /** + * Returns the key's comment + * + * Not all key formats support comments. If you want to set a comment use toString() + * + * @return null|string + */ + public function getComment() + { + return $this->comment; + } + /** + * Tests engine validity + * + */ + public static function useBestEngine() + { + static::$engines = [ + 'PHP' => \true, + 'OpenSSL' => \extension_loaded('openssl'), + // this test can be satisfied by either of the following: + // http://php.net/manual/en/book.sodium.php + // https://github.com/paragonie/sodium_compat + 'libsodium' => \function_exists('sodium_crypto_sign_keypair'), + ]; + return static::$engines; + } + /** + * Flag to use internal engine only (useful for unit testing) + * + */ + public static function useInternalEngine() + { + static::$engines = ['PHP' => \true, 'OpenSSL' => \false, 'libsodium' => \false]; + } + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + return $this->toString('PKCS8'); + } + /** + * Determines which hashing function should be used + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + $new->hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash($hash); + $new->hmac = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash($hash); + return $new; + } + /** + * Returns the hash algorithm currently being used + * + */ + public function getHash() + { + return clone $this->hash; + } + /** + * Compute the pseudorandom k for signature generation, + * using the process specified for deterministic DSA. + * + * @param string $h1 + * @return string + */ + protected function computek($h1) + { + $v = \str_repeat("\1", \strlen($h1)); + $k = \str_repeat("\0", \strlen($h1)); + $x = $this->int2octets($this->x); + $h1 = $this->bits2octets($h1); + $this->hmac->setKey($k); + $k = $this->hmac->hash($v . "\0" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + $k = $this->hmac->hash($v . "\1" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + $qlen = $this->q->getLengthInBytes(); + while (\true) { + $t = ''; + while (\strlen($t) < $qlen) { + $v = $this->hmac->hash($v); + $t = $t . $v; + } + $k = $this->bits2int($t); + if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) { + break; + } + $k = $this->hmac->hash($v . "\0"); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + } + return $k; + } + /** + * Integer to Octet String + * + * @param \phpseclib3\Math\BigInteger $v + * @return string + */ + private function int2octets($v) + { + $out = $v->toBytes(); + $rolen = $this->q->getLengthInBytes(); + if (\strlen($out) < $rolen) { + return \str_pad($out, $rolen, "\0", \STR_PAD_LEFT); + } elseif (\strlen($out) > $rolen) { + return \substr($out, -$rolen); + } else { + return $out; + } + } + /** + * Bit String to Integer + * + * @param string $in + * @return \phpseclib3\Math\BigInteger + */ + protected function bits2int($in) + { + $v = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($in, 256); + $vlen = \strlen($in) << 3; + $qlen = $this->q->getLength(); + if ($vlen > $qlen) { + return $v->bitwise_rightShift($vlen - $qlen); + } + return $v; + } + /** + * Bit String to Octet String + * + * @param string $in + * @return string + */ + private function bits2octets($in) + { + $z1 = $this->bits2int($in); + $z2 = $z1->subtract($this->q); + return $z2->compare(self::$zero) < 0 ? $this->int2octets($z1) : $this->int2octets($z2); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php new file mode 100644 index 0000000..f2fe6d8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php @@ -0,0 +1,23 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common; + +/** + * Base Class for all block cipher classes + * + * @author Jim Wigginton + */ +abstract class BlockCipher extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\SymmetricKey +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php new file mode 100644 index 0000000..794de4e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php @@ -0,0 +1,62 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +/** + * JSON Web Key Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class JWK +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + $key = \preg_replace('#\\s#', '', $key); + // remove whitespace + if (\PHP_VERSION_ID >= 73000) { + $key = \json_decode($key, null, 512, \JSON_THROW_ON_ERROR); + } else { + $key = \json_decode($key); + if (!$key) { + throw new \RuntimeException('Unable to decode JSON'); + } + } + if (isset($key->kty)) { + return $key; + } + if (\count($key->keys) != 1) { + throw new \RuntimeException('Although the JWK key format supports multiple keys phpseclib does not'); + } + return $key->keys[0]; + } + /** + * Wrap a key appropriately + * + * @return string + */ + protected static function wrapKey(array $key, array $options) + { + return \json_encode(['keys' => [$key + $options]]); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..9a243c7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php @@ -0,0 +1,195 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\AES; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +/** + * OpenSSH Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH +{ + /** + * Default comment + * + * @var string + */ + protected static $comment = 'phpseclib-generated-key'; + /** + * Binary key flag + * + * @var bool + */ + protected static $binary = \false; + /** + * Sets the default comment + * + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = \str_replace(["\r", "\n"], '', $comment); + } + /** + * Break a public or private key down into its constituent components + * + * $type can be either ssh-dss or ssh-rsa + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + // key format is described here: + // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD + if (\strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== \false) { + $key = \preg_replace('#(?:^-.*?-[\\r\\n]*$)|\\s#ms', '', $key); + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode($key); + $magic = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, 15); + if ($magic != "openssh-key-v1\0") { + throw new \RuntimeException('Expected openssh-key-v1'); + } + list($ciphername, $kdfname, $kdfoptions, $numKeys) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('sssN', $key); + if ($numKeys != 1) { + // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys + // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass + // that to the appropriate key loading parser $numKey times or something + throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); + } + switch ($ciphername) { + case 'none': + break; + case 'aes256-ctr': + if ($kdfname != 'bcrypt') { + throw new \RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)'); + } + list($salt, $rounds) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('sN', $kdfoptions); + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\AES('ctr'); + //$crypto->setKeyLength(256); + //$crypto->disablePadding(); + $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); + break; + default: + throw new \RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used)'); + } + list($publicKey, $paddedKey) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ss', $key); + list($type) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('s', $publicKey); + if (isset($crypto)) { + $paddedKey = $crypto->decrypt($paddedKey); + } + list($checkint1, $checkint2) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('NN', $paddedKey); + // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. + if ($checkint1 != $checkint2) { + throw new \RuntimeException('The two checkints do not match'); + } + self::checkType($type); + return \compact('type', 'publicKey', 'paddedKey'); + } + $parts = \explode(' ', $key, 3); + if (!isset($parts[1])) { + $key = \base64_decode($parts[0]); + $comment = \false; + } else { + $asciiType = $parts[0]; + self::checkType($parts[0]); + $key = \base64_decode($parts[1]); + $comment = isset($parts[2]) ? $parts[2] : \false; + } + if ($key === \false) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + list($type) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('s', $key); + self::checkType($type); + if (isset($asciiType) && $asciiType != $type) { + throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); + } + if (\strlen($key) <= 4) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $publicKey = $key; + return \compact('type', 'publicKey', 'comment'); + } + /** + * Toggle between binary and printable keys + * + * Printable keys are what are generated by default. These are the ones that go in + * $HOME/.ssh/authorized_key. + * + * @param bool $enabled + */ + public static function setBinaryOutput($enabled) + { + self::$binary = $enabled; + } + /** + * Checks to see if the type is valid + * + * @param string $candidate + */ + private static function checkType($candidate) + { + if (!\in_array($candidate, static::$types)) { + throw new \RuntimeException("The key type ({$candidate}) is not equal to: " . \implode(',', static::$types)); + } + } + /** + * Wrap a private key appropriately + * + * @param string $publicKey + * @param string $privateKey + * @param string $password + * @param array $options + * @return string + */ + protected static function wrapPrivateKey($publicKey, $privateKey, $password, $options) + { + list(, $checkint) = \unpack('N', \PostSMTP\Vendor\phpseclib3\Crypt\Random::string(4)); + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $paddedKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('NN', $checkint, $checkint) . $privateKey . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $comment); + $usesEncryption = !empty($password) && \is_string($password); + /* + from http://tools.ietf.org/html/rfc4253#section-6 : + + Note that the length of the concatenation of 'packet_length', + 'padding_length', 'payload', and 'random padding' MUST be a multiple + of the cipher block size or 8, whichever is larger. + */ + $blockSize = $usesEncryption ? 16 : 8; + $paddingLength = ($blockSize - 1) * \strlen($paddedKey) % $blockSize; + for ($i = 1; $i <= $paddingLength; $i++) { + $paddedKey .= \chr($i); + } + if (!$usesEncryption) { + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey); + } else { + $rounds = isset($options['rounds']) ? $options['rounds'] : 16; + $salt = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string(16); + $kdfoptions = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('sN', $salt, $rounds); + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\AES('ctr'); + $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); + $paddedKey = $crypto->encrypt($paddedKey); + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('sssNss', 'aes256-ctr', 'bcrypt', $kdfoptions, 1, $publicKey, $paddedKey); + } + $key = "openssh-key-v1\0{$key}"; + return "-----BEGIN OPENSSH PRIVATE KEY-----\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 70, "\n") . "-----END OPENSSH PRIVATE KEY-----\n"; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php new file mode 100644 index 0000000..83abf82 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php @@ -0,0 +1,67 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys; + +/** + * PKCS1 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS +{ + /** + * Auto-detect the format + */ + const MODE_ANY = 0; + /** + * Require base64-encoded PEM's be supplied + */ + const MODE_PEM = 1; + /** + * Require raw DER's be supplied + */ + const MODE_DER = 2; + /**#@-*/ + /** + * Is the key a base-64 encoded PEM, DER or should it be auto-detected? + * + * @var int + */ + protected static $format = self::MODE_ANY; + /** + * Require base64-encoded PEM's be supplied + * + */ + public static function requirePEM() + { + self::$format = self::MODE_PEM; + } + /** + * Require raw DER's be supplied + * + */ + public static function requireDER() + { + self::$format = self::MODE_DER; + } + /** + * Accept any format and auto detect the format + * + * This is the default setting + * + */ + public static function requireAny() + { + self::$format = self::MODE_ANY; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..09f8753 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php @@ -0,0 +1,187 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\AES; +use PostSMTP\Vendor\phpseclib3\Crypt\DES; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Crypt\TripleDES; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +/** + * PKCS1 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS +{ + /** + * Default encryption algorithm + * + * @var string + */ + private static $defaultEncryptionAlgorithm = 'AES-128-CBC'; + /** + * Sets the default encryption algorithm + * + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + /** + * Returns the mode constant corresponding to the mode string + * + * @param string $mode + * @return int + * @throws \UnexpectedValueException if the block cipher mode is unsupported + */ + private static function getEncryptionMode($mode) + { + switch ($mode) { + case 'CBC': + case 'ECB': + case 'CFB': + case 'OFB': + case 'CTR': + return $mode; + } + throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); + } + /** + * Returns a cipher object corresponding to a string + * + * @param string $algo + * @return string + * @throws \UnexpectedValueException if the encryption algorithm is unsupported + */ + private static function getEncryptionObject($algo) + { + $modes = '(CBC|ECB|CFB|OFB|CTR)'; + switch (\true) { + case \preg_match("#^AES-(128|192|256)-{$modes}\$#", $algo, $matches): + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\AES(self::getEncryptionMode($matches[2])); + $cipher->setKeyLength($matches[1]); + return $cipher; + case \preg_match("#^DES-EDE3-{$modes}\$#", $algo, $matches): + return new \PostSMTP\Vendor\phpseclib3\Crypt\TripleDES(self::getEncryptionMode($matches[1])); + case \preg_match("#^DES-{$modes}\$#", $algo, $matches): + return new \PostSMTP\Vendor\phpseclib3\Crypt\DES(self::getEncryptionMode($matches[1])); + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException($algo . ' is not a supported algorithm'); + } + } + /** + * Generate a symmetric key for PKCS#1 keys + * + * @param string $password + * @param string $iv + * @param int $length + * @return string + */ + private static function generateSymmetricKey($password, $iv, $length) + { + $symkey = ''; + $iv = \substr($iv, 0, 8); + while (\strlen($symkey) < $length) { + $symkey .= \md5($symkey . $password . $iv, \true); + } + return \substr($symkey, 0, $length); + } + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password) + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is + "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to + protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding + two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: + + http://tools.ietf.org/html/rfc1421#section-4.6.1.1 + http://tools.ietf.org/html/rfc1421#section-4.6.1.3 + + DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. + DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation + function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's + own implementation. ie. the implementation *is* the standard and any bugs that may exist in that + implementation are part of the standard, as well. + + * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ + if (\preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { + $iv = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::hex2bin(\trim($matches[2])); + // remove the Proc-Type / DEK-Info sections as they're no longer needed + $key = \preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); + $ciphertext = \PostSMTP\Vendor\phpseclib3\File\ASN1::extractBER($key); + if ($ciphertext === \false) { + $ciphertext = $key; + } + $crypto = self::getEncryptionObject($matches[1]); + $crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3)); + $crypto->setIV($iv); + $key = $crypto->decrypt($ciphertext); + } else { + if (self::$format != self::MODE_DER) { + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::extractBER($key); + if ($decoded !== \false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + } + return $key; + } + /** + * Wrap a private key appropriately + * + * @param string $key + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $type, $password, array $options = []) + { + if (empty($password) || !\is_string($password)) { + return "-----BEGIN {$type} PRIVATE KEY-----\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . "-----END {$type} PRIVATE KEY-----"; + } + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + $cipher = self::getEncryptionObject($encryptionAlgorithm); + $iv = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string($cipher->getBlockLength() >> 3); + $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); + $cipher->setIV($iv); + $iv = \strtoupper(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($iv)); + return "-----BEGIN {$type} PRIVATE KEY-----\r\n" . "Proc-Type: 4,ENCRYPTED\r\n" . "DEK-Info: " . $encryptionAlgorithm . ",{$iv}\r\n" . "\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($cipher->encrypt($key)), 64) . "-----END {$type} PRIVATE KEY-----"; + } + /** + * Wrap a public key appropriately + * + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + return "-----BEGIN {$type} PUBLIC KEY-----\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . "-----END {$type} PUBLIC KEY-----"; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..f4bb4c9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php @@ -0,0 +1,587 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\AES; +use PostSMTP\Vendor\phpseclib3\Crypt\DES; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Crypt\RC2; +use PostSMTP\Vendor\phpseclib3\Crypt\RC4; +use PostSMTP\Vendor\phpseclib3\Crypt\TripleDES; +use PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +/** + * PKCS#8 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS +{ + /** + * Default encryption algorithm + * + * @var string + */ + private static $defaultEncryptionAlgorithm = 'id-PBES2'; + /** + * Default encryption scheme + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + */ + private static $defaultEncryptionScheme = 'aes128-CBC-PAD'; + /** + * Default PRF + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + */ + private static $defaultPRF = 'id-hmacWithSHA256'; + /** + * Default Iteration Count + * + * @var int + */ + private static $defaultIterationCount = 2048; + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = \false; + /** + * Sets the default encryption algorithm + * + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + /** + * Sets the default encryption algorithm for PBES2 + * + * @param string $algo + */ + public static function setEncryptionScheme($algo) + { + self::$defaultEncryptionScheme = $algo; + } + /** + * Sets the iteration count + * + * @param int $count + */ + public static function setIterationCount($count) + { + self::$defaultIterationCount = $count; + } + /** + * Sets the PRF for PBES2 + * + * @param string $algo + */ + public static function setPRF($algo) + { + self::$defaultPRF = $algo; + } + /** + * Returns a SymmetricKey object based on a PBES1 $algo + * + * @return \phpseclib3\Crypt\Common\SymmetricKey + * @param string $algo + */ + private static function getPBES1EncryptionObject($algo) + { + $algo = \preg_match('#^pbeWith(?:MD2|MD5|SHA1|SHA)And(.*?)-CBC$#', $algo, $matches) ? $matches[1] : \substr($algo, 13); + // strlen('pbeWithSHAAnd') == 13 + switch ($algo) { + case 'DES': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\DES('cbc'); + break; + case 'RC2': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\RC2('cbc'); + break; + case '3-KeyTripleDES': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\TripleDES('cbc'); + break; + case '2-KeyTripleDES': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\TripleDES('cbc'); + $cipher->setKeyLength(128); + break; + case '128BitRC2': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\RC2('cbc'); + $cipher->setKeyLength(128); + break; + case '40BitRC2': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\RC2('cbc'); + $cipher->setKeyLength(40); + break; + case '128BitRC4': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\RC4(); + $cipher->setKeyLength(128); + break; + case '40BitRC4': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\RC4(); + $cipher->setKeyLength(40); + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException("{$algo} is not a supported algorithm"); + } + return $cipher; + } + /** + * Returns a hash based on a PBES1 $algo + * + * @return string + * @param string $algo + */ + private static function getPBES1Hash($algo) + { + if (\preg_match('#^pbeWith(MD2|MD5|SHA1|SHA)And.*?-CBC$#', $algo, $matches)) { + return $matches[1] == 'SHA' ? 'sha1' : $matches[1]; + } + return 'sha1'; + } + /** + * Returns a KDF baesd on a PBES1 $algo + * + * @return string + * @param string $algo + */ + private static function getPBES1KDF($algo) + { + switch ($algo) { + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + return 'pbkdf1'; + } + return 'pkcs12'; + } + /** + * Returns a SymmetricKey object baesd on a PBES2 $algo + * + * @return SymmetricKey + * @param string $algo + */ + private static function getPBES2EncryptionObject($algo) + { + switch ($algo) { + case 'desCBC': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\TripleDES('cbc'); + break; + case 'des-EDE3-CBC': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\TripleDES('cbc'); + break; + case 'rc2CBC': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\RC2('cbc'); + // in theory this can be changed + $cipher->setKeyLength(128); + break; + case 'rc5-CBC-PAD': + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('rc5-CBC-PAD is not supported for PBES2 PKCS#8 keys'); + case 'aes128-CBC-PAD': + case 'aes192-CBC-PAD': + case 'aes256-CBC-PAD': + $cipher = new \PostSMTP\Vendor\phpseclib3\Crypt\AES('cbc'); + $cipher->setKeyLength(\substr($algo, 3, 3)); + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException("{$algo} is not supported"); + } + return $cipher; + } + /** + * Initialize static variables + * + */ + private static function initialize_static_variables() + { + if (!isset(static::$childOIDsLoaded)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException('This class should not be called directly'); + } + if (!static::$childOIDsLoaded) { + \PostSMTP\Vendor\phpseclib3\File\ASN1::loadOIDs(\is_array(static::OID_NAME) ? \array_combine(static::OID_NAME, static::OID_VALUE) : [static::OID_NAME => static::OID_VALUE]); + static::$childOIDsLoaded = \true; + } + if (!self::$oidsLoaded) { + // from https://tools.ietf.org/html/rfc2898 + \PostSMTP\Vendor\phpseclib3\File\ASN1::loadOIDs([ + // PBES1 encryption schemes + 'pbeWithMD2AndDES-CBC' => '1.2.840.113549.1.5.1', + 'pbeWithMD2AndRC2-CBC' => '1.2.840.113549.1.5.4', + 'pbeWithMD5AndDES-CBC' => '1.2.840.113549.1.5.3', + 'pbeWithMD5AndRC2-CBC' => '1.2.840.113549.1.5.6', + 'pbeWithSHA1AndDES-CBC' => '1.2.840.113549.1.5.10', + 'pbeWithSHA1AndRC2-CBC' => '1.2.840.113549.1.5.11', + // from PKCS#12: + // https://tools.ietf.org/html/rfc7292 + 'pbeWithSHAAnd128BitRC4' => '1.2.840.113549.1.12.1.1', + 'pbeWithSHAAnd40BitRC4' => '1.2.840.113549.1.12.1.2', + 'pbeWithSHAAnd3-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.3', + 'pbeWithSHAAnd2-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.4', + 'pbeWithSHAAnd128BitRC2-CBC' => '1.2.840.113549.1.12.1.5', + 'pbeWithSHAAnd40BitRC2-CBC' => '1.2.840.113549.1.12.1.6', + 'id-PBKDF2' => '1.2.840.113549.1.5.12', + 'id-PBES2' => '1.2.840.113549.1.5.13', + 'id-PBMAC1' => '1.2.840.113549.1.5.14', + // from PKCS#5 v2.1: + // http://www.rsa.com/rsalabs/pkcs/files/h11302-wp-pkcs5v2-1-password-based-cryptography-standard.pdf + 'id-hmacWithSHA1' => '1.2.840.113549.2.7', + 'id-hmacWithSHA224' => '1.2.840.113549.2.8', + 'id-hmacWithSHA256' => '1.2.840.113549.2.9', + 'id-hmacWithSHA384' => '1.2.840.113549.2.10', + 'id-hmacWithSHA512' => '1.2.840.113549.2.11', + 'id-hmacWithSHA512-224' => '1.2.840.113549.2.12', + 'id-hmacWithSHA512-256' => '1.2.840.113549.2.13', + 'desCBC' => '1.3.14.3.2.7', + 'des-EDE3-CBC' => '1.2.840.113549.3.7', + 'rc2CBC' => '1.2.840.113549.3.2', + 'rc5-CBC-PAD' => '1.2.840.113549.3.9', + 'aes128-CBC-PAD' => '2.16.840.1.101.3.4.1.2', + 'aes192-CBC-PAD' => '2.16.840.1.101.3.4.1.22', + 'aes256-CBC-PAD' => '2.16.840.1.101.3.4.1.42', + ]); + self::$oidsLoaded = \true; + } + } + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password = '') + { + $decoded = self::preParse($key); + $meta = []; + $decrypted = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\EncryptedPrivateKeyInfo::MAP); + if (\strlen($password) && \is_array($decrypted)) { + $algorithm = $decrypted['encryptionAlgorithm']['algorithm']; + switch ($algorithm) { + // PBES1 + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + case 'pbeWithSHAAnd3-KeyTripleDES-CBC': + case 'pbeWithSHAAnd2-KeyTripleDES-CBC': + case 'pbeWithSHAAnd128BitRC2-CBC': + case 'pbeWithSHAAnd40BitRC2-CBC': + case 'pbeWithSHAAnd128BitRC4': + case 'pbeWithSHAAnd40BitRC4': + $cipher = self::getPBES1EncryptionObject($algorithm); + $hash = self::getPBES1Hash($algorithm); + $kdf = self::getPBES1KDF($algorithm); + $meta['meta']['algorithm'] = $algorithm; + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + \extract(\PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($temp[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBEParameter::MAP)); + $iterationCount = (int) $iterationCount->toString(); + $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER 2'); + } + break; + case 'id-PBES2': + $meta['meta']['algorithm'] = $algorithm; + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($temp[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBES2params::MAP); + \extract($temp); + $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); + $meta['meta']['cipher'] = $encryptionScheme['algorithm']; + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($temp[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBES2params::MAP); + \extract($temp); + if (!$cipher instanceof \PostSMTP\Vendor\phpseclib3\Crypt\RC2) { + $cipher->setIV($encryptionScheme['parameters']['octetString']); + } else { + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($encryptionScheme['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + \extract(\PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($temp[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RC2CBCParameter::MAP)); + $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); + switch ($effectiveKeyLength) { + case 160: + $effectiveKeyLength = 40; + break; + case 120: + $effectiveKeyLength = 64; + break; + case 58: + $effectiveKeyLength = 128; + break; + } + $cipher->setIV($iv); + $cipher->setKeyLength($effectiveKeyLength); + } + $meta['meta']['keyDerivationFunc'] = $keyDerivationFunc['algorithm']; + switch ($keyDerivationFunc['algorithm']) { + case 'id-PBKDF2': + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($keyDerivationFunc['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $prf = ['algorithm' => 'id-hmacWithSHA1']; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($temp[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBKDF2params::MAP); + \extract($params); + $meta['meta']['prf'] = $prf['algorithm']; + $hash = \str_replace('-', '/', \substr($prf['algorithm'], 11)); + $params = [$password, 'pbkdf2', $hash, $salt, (int) $iterationCount->toString()]; + if (isset($keyLength)) { + $params[] = (int) $keyLength->toString(); + } + $cipher->setPassword(...$params); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER 3'); + } + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('Only PBKDF2 is supported for PBES2 PKCS#8 keys'); + } + break; + case 'id-PBMAC1': + //$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + //$value = ASN1::asn1map($temp[0], Maps\PBMAC1params::MAP); + // since i can't find any implementation that does PBMAC1 it is unsupported + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('Only PBES1 and PBES2 PKCS#8 keys are supported.'); + } + } + $private = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\OneAsymmetricKey::MAP); + if (\is_array($private)) { + if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof \PostSMTP\Vendor\phpseclib3\File\ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) { + $temp = $decoded[0]['content'][1]['content'][1]; + $private['privateKeyAlgorithm']['parameters'] = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element(\substr($key, $temp['start'], $temp['length'])); + } + if (\is_array(static::OID_NAME)) { + if (!\in_array($private['privateKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException($private['privateKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($private['privateKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $private['privateKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($private['publicKey'])) { + if ($private['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . \bin2hex($private['publicKey'][0])); + } + $private['publicKey'] = \substr($private['publicKey'], 1); + } + return $private + $meta; + } + // EncryptedPrivateKeyInfo and PublicKeyInfo have largely identical "signatures". the only difference + // is that the former has an octet string and the later has a bit string. the first byte of a bit + // string represents the number of bits in the last byte that are to be ignored but, currently, + // bit strings wanting a non-zero amount of bits trimmed are not supported + $public = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PublicKeyInfo::MAP); + if (\is_array($public)) { + if ($public['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . \bin2hex($public['publicKey'][0])); + } + if (\is_array(static::OID_NAME)) { + if (!\in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException($public['publicKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($public['publicKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $public['publicKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($public['publicKeyAlgorithm']['parameters']) && !$public['publicKeyAlgorithm']['parameters'] instanceof \PostSMTP\Vendor\phpseclib3\File\ASN1\Element && isset($decoded[0]['content'][0]['content'][1])) { + $temp = $decoded[0]['content'][0]['content'][1]; + $public['publicKeyAlgorithm']['parameters'] = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element(\substr($key, $temp['start'], $temp['length'])); + } + $public['publicKey'] = \substr($public['publicKey'], 1); + return $public; + } + throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); + } + /** + * Wrap a private key appropriately + * + * @param string $key + * @param string $attr + * @param mixed $params + * @param string $password + * @param string $oid optional + * @param string $publicKey optional + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $attr, $params, $password, $oid = null, $publicKey = '', array $options = []) + { + self::initialize_static_variables(); + $key = ['version' => 'v1', 'privateKeyAlgorithm' => ['algorithm' => \is_string(static::OID_NAME) ? static::OID_NAME : $oid], 'privateKey' => $key]; + if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { + $key['privateKeyAlgorithm']['parameters'] = $params; + } + if (!empty($attr)) { + $key['attributes'] = $attr; + } + if (!empty($publicKey)) { + $key['version'] = 'v2'; + $key['publicKey'] = $publicKey; + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\OneAsymmetricKey::MAP); + if (!empty($password) && \is_string($password)) { + $salt = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string(8); + $iterationCount = isset($options['iterationCount']) ? $options['iterationCount'] : self::$defaultIterationCount; + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + $encryptionScheme = isset($options['encryptionScheme']) ? $options['encryptionScheme'] : self::$defaultEncryptionScheme; + $prf = isset($options['PRF']) ? $options['PRF'] : self::$defaultPRF; + if ($encryptionAlgorithm == 'id-PBES2') { + $crypto = self::getPBES2EncryptionObject($encryptionScheme); + $hash = \str_replace('-', '/', \substr($prf, 11)); + $kdf = 'pbkdf2'; + $iv = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string($crypto->getBlockLength() >> 3); + $PBKDF2params = ['salt' => $salt, 'iterationCount' => $iterationCount, 'prf' => ['algorithm' => $prf, 'parameters' => null]]; + $PBKDF2params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($PBKDF2params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBKDF2params::MAP); + if (!$crypto instanceof \PostSMTP\Vendor\phpseclib3\Crypt\RC2) { + $params = ['octetString' => $iv]; + } else { + $params = ['rc2ParametersVersion' => 58, 'iv' => $iv]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RC2CBCParameter::MAP); + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($params); + } + $params = ['keyDerivationFunc' => ['algorithm' => 'id-PBKDF2', 'parameters' => new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($PBKDF2params)], 'encryptionScheme' => ['algorithm' => $encryptionScheme, 'parameters' => $params]]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBES2params::MAP); + $crypto->setIV($iv); + } else { + $crypto = self::getPBES1EncryptionObject($encryptionAlgorithm); + $hash = self::getPBES1Hash($encryptionAlgorithm); + $kdf = self::getPBES1KDF($encryptionAlgorithm); + $params = ['salt' => $salt, 'iterationCount' => $iterationCount]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBEParameter::MAP); + } + $crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $crypto->encrypt($key); + $key = ['encryptionAlgorithm' => ['algorithm' => $encryptionAlgorithm, 'parameters' => new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($params)], 'encryptedData' => $key]; + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\EncryptedPrivateKeyInfo::MAP); + return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . "-----END ENCRYPTED PRIVATE KEY-----"; + } + return "-----BEGIN PRIVATE KEY-----\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . "-----END PRIVATE KEY-----"; + } + /** + * Wrap a public key appropriately + * + * @param string $key + * @param mixed $params + * @param string $oid + * @return string + */ + protected static function wrapPublicKey($key, $params, $oid = null) + { + self::initialize_static_variables(); + $key = ['publicKeyAlgorithm' => ['algorithm' => \is_string(static::OID_NAME) ? static::OID_NAME : $oid], 'publicKey' => "\0" . $key]; + if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { + $key['publicKeyAlgorithm']['parameters'] = $params; + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PublicKeyInfo::MAP); + return "-----BEGIN PUBLIC KEY-----\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . "-----END PUBLIC KEY-----"; + } + /** + * Perform some preliminary parsing of the key + * + * @param string $key + * @return array + */ + private static function preParse(&$key) + { + self::initialize_static_variables(); + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (self::$format != self::MODE_DER) { + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::extractBER($key); + if ($decoded !== \false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + return $decoded; + } + /** + * Returns the encryption parameters used by the key + * + * @param string $key + * @return array + */ + public static function extractEncryptionAlgorithm($key) + { + $decoded = self::preParse($key); + $r = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\EncryptedPrivateKeyInfo::MAP); + if (!\is_array($r)) { + throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); + } + if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $r['encryptionAlgorithm']['parameters'] = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBES2params::MAP); + $kdf =& $r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; + switch ($kdf['algorithm']) { + case 'id-PBKDF2': + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($kdf['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $kdf['parameters'] = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\PBKDF2params::MAP); + } + } + return $r['encryptionAlgorithm']; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..f9d561a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php @@ -0,0 +1,324 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\AES; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException; +/** + * PuTTY Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY +{ + /** + * Default comment + * + * @var string + */ + private static $comment = 'phpseclib-generated-key'; + /** + * Default version + * + * @var int + */ + private static $version = 2; + /** + * Sets the default comment + * + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = \str_replace(["\r", "\n"], '', $comment); + } + /** + * Sets the default version + * + * @param int $version + */ + public static function setVersion($version) + { + if ($version != 2 && $version != 3) { + throw new \RuntimeException('Only supported versions are 2 and 3'); + } + self::$version = $version; + } + /** + * Generate a symmetric key for PuTTY v2 keys + * + * @param string $password + * @param int $length + * @return string + */ + private static function generateV2Key($password, $length) + { + $symkey = ''; + $sequence = 0; + while (\strlen($symkey) < $length) { + $temp = \pack('Na*', $sequence++, $password); + $symkey .= \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::hex2bin(\sha1($temp)); + } + return \substr($symkey, 0, $length); + } + /** + * Generate a symmetric key for PuTTY v3 keys + * + * @param string $password + * @param string $flavour + * @param int $memory + * @param int $passes + * @param string $salt + * @return array + */ + private static function generateV3Key($password, $flavour, $memory, $passes, $salt) + { + if (!\function_exists('sodium_crypto_pwhash')) { + throw new \RuntimeException('sodium_crypto_pwhash needs to exist for Argon2 password hasing'); + } + switch ($flavour) { + case 'Argon2i': + $flavour = \SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13; + break; + case 'Argon2id': + $flavour = \SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13; + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('Only Argon2i and Argon2id are supported'); + } + $length = 80; + // keylen + ivlen + mac_keylen + $temp = \sodium_crypto_pwhash($length, $password, $salt, $passes, $memory << 10, $flavour); + $symkey = \substr($temp, 0, 32); + $symiv = \substr($temp, 32, 16); + $hashkey = \substr($temp, -32); + return \compact('symkey', 'symiv', 'hashkey'); + } + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password) + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (\strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== \false) { + $lines = \preg_split('#[\\r\\n]+#', $key); + switch (\true) { + case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); + case $lines[\count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); + } + $lines = \array_splice($lines, 1, -1); + $lines = \array_map(function ($line) { + return \rtrim($line, "\r\n"); + }, $lines); + $data = $current = ''; + $values = []; + $in_value = \false; + foreach ($lines as $line) { + switch (\true) { + case \preg_match('#^(.*?): (.*)#', $line, $match): + $in_value = $line[\strlen($line) - 1] == '\\'; + $current = \strtolower($match[1]); + $values[$current] = $in_value ? \substr($match[2], 0, -1) : $match[2]; + break; + case $in_value: + $in_value = $line[\strlen($line) - 1] == '\\'; + $values[$current] .= $in_value ? \substr($line, 0, -1) : $line; + break; + default: + $data .= $line; + } + } + $components = \call_user_func([static::PUBLIC_HANDLER, 'load'], $data); + if ($components === \false) { + throw new \UnexpectedValueException('Unable to decode public key'); + } + $components += $values; + $components['comment'] = \str_replace(['\\\\', '\\"'], ['\\', '"'], $values['comment']); + return $components; + } + $components = []; + $key = \preg_split('#\\r\\n|\\r|\\n#', \trim($key)); + if (\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key[0], \strlen('PuTTY-User-Key-File-')) != 'PuTTY-User-Key-File-') { + return \false; + } + $version = (int) \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key[0], 3); + // should be either "2: " or "3: 0" prior to int casting + if ($version != 2 && $version != 3) { + throw new \RuntimeException('Only v2 and v3 PuTTY private keys are supported'); + } + $components['type'] = $type = \rtrim($key[0]); + if (!\in_array($type, static::$types)) { + $error = \count(static::$types) == 1 ? 'Only ' . static::$types[0] . ' keys are supported. ' : ''; + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException($error . 'This is an unsupported ' . $type . ' key'); + } + $encryption = \trim(\preg_replace('#Encryption: (.+)#', '$1', $key[1])); + $components['comment'] = \trim(\preg_replace('#Comment: (.+)#', '$1', $key[2])); + $publicLength = \trim(\preg_replace('#Public-Lines: (\\d+)#', '$1', $key[3])); + $public = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode(\implode('', \array_map('trim', \array_slice($key, 4, $publicLength)))); + $source = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); + \extract(\unpack('Nlength', \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($public, 4))); + $newtype = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($public, $length); + if ($newtype != $type) { + throw new \RuntimeException('The binary type does not match the human readable type field'); + } + $components['public'] = $public; + switch ($version) { + case 3: + $hashkey = ''; + break; + case 2: + $hashkey = 'putty-private-key-file-mac-key'; + } + $offset = $publicLength + 4; + switch ($encryption) { + case 'aes256-cbc': + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\AES('cbc'); + switch ($version) { + case 3: + $flavour = \trim(\preg_replace('#Key-Derivation: (.*)#', '$1', $key[$offset++])); + $memory = \trim(\preg_replace('#Argon2-Memory: (\\d+)#', '$1', $key[$offset++])); + $passes = \trim(\preg_replace('#Argon2-Passes: (\\d+)#', '$1', $key[$offset++])); + $parallelism = \trim(\preg_replace('#Argon2-Parallelism: (\\d+)#', '$1', $key[$offset++])); + $salt = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::hex2bin(\trim(\preg_replace('#Argon2-Salt: ([0-9a-f]+)#', '$1', $key[$offset++]))); + \extract(self::generateV3Key($password, $flavour, $memory, $passes, $salt)); + break; + case 2: + $symkey = self::generateV2Key($password, 32); + $symiv = \str_repeat("\0", $crypto->getBlockLength() >> 3); + $hashkey .= $password; + } + } + switch ($version) { + case 3: + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha256'); + $hash->setKey($hashkey); + break; + case 2: + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha1'); + $hash->setKey(\sha1($hashkey, \true)); + } + $privateLength = \trim(\preg_replace('#Private-Lines: (\\d+)#', '$1', $key[$offset++])); + $private = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode(\implode('', \array_map('trim', \array_slice($key, $offset, $privateLength)))); + if ($encryption != 'none') { + $crypto->setKey($symkey); + $crypto->setIV($symiv); + $crypto->disablePadding(); + $private = $crypto->decrypt($private); + } + $source .= \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $private); + $hmac = \trim(\preg_replace('#Private-MAC: (.+)#', '$1', $key[$offset + $privateLength])); + $hmac = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::hex2bin($hmac); + if (!\hash_equals($hash->hash($source), $hmac)) { + throw new \UnexpectedValueException('MAC validation error'); + } + $components['private'] = $private; + return $components; + } + /** + * Wrap a private key appropriately + * + * @param string $public + * @param string $private + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) + { + $encryption = !empty($password) || \is_string($password) ? 'aes256-cbc' : 'none'; + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $version = isset($options['version']) ? $options['version'] : self::$version; + $key = "PuTTY-User-Key-File-{$version}: {$type}\r\n"; + $key .= "Encryption: {$encryption}\r\n"; + $key .= "Comment: {$comment}\r\n"; + $public = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $type) . $public; + $source = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ssss', $type, $encryption, $comment, $public); + $public = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($public); + $key .= "Public-Lines: " . (\strlen($public) + 63 >> 6) . "\r\n"; + $key .= \chunk_split($public, 64); + if (empty($password) && !\is_string($password)) { + $source .= \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $private); + switch ($version) { + case 3: + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha256'); + $hash->setKey(''); + break; + case 2: + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha1'); + $hash->setKey(\sha1('putty-private-key-file-mac-key', \true)); + } + } else { + $private .= \PostSMTP\Vendor\phpseclib3\Crypt\Random::string(16 - (\strlen($private) & 15)); + $source .= \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $private); + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\AES('cbc'); + switch ($version) { + case 3: + $salt = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string(16); + $key .= "Key-Derivation: Argon2id\r\n"; + $key .= "Argon2-Memory: 8192\r\n"; + $key .= "Argon2-Passes: 13\r\n"; + $key .= "Argon2-Parallelism: 1\r\n"; + $key .= "Argon2-Salt: " . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($salt) . "\r\n"; + \extract(self::generateV3Key($password, 'Argon2id', 8192, 13, $salt)); + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha256'); + $hash->setKey($hashkey); + break; + case 2: + $symkey = self::generateV2Key($password, 32); + $symiv = \str_repeat("\0", $crypto->getBlockLength() >> 3); + $hashkey = 'putty-private-key-file-mac-key' . $password; + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha1'); + $hash->setKey(\sha1($hashkey, \true)); + } + $crypto->setKey($symkey); + $crypto->setIV($symiv); + $crypto->disablePadding(); + $private = $crypto->encrypt($private); + $mac = $hash->hash($source); + } + $private = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($private); + $key .= 'Private-Lines: ' . (\strlen($private) + 63 >> 6) . "\r\n"; + $key .= \chunk_split($private, 64); + $key .= 'Private-MAC: ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($hash->hash($source)) . "\r\n"; + return $key; + } + /** + * Wrap a public key appropriately + * + * This is basically the format described in RFC 4716 (https://tools.ietf.org/html/rfc4716) + * + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + $key = \pack('Na*a*', \strlen($type), $type, $key); + $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . 'Comment: "' . \str_replace(['\\', '"'], ['\\\\', '\\"'], self::$comment) . "\"\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . '---- END SSH2 PUBLIC KEY ----'; + return $key; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php new file mode 100644 index 0000000..0215dd5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php @@ -0,0 +1,53 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Signature; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Raw Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Loads a signature + * + * @param array $sig + * @return array|bool + */ + public static function load($sig) + { + switch (\true) { + case !\is_array($sig): + case !isset($sig['r']) || !isset($sig['s']): + case !$sig['r'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + case !$sig['s'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + return \false; + } + return ['r' => $sig['r'], 's' => $sig['s']]; + } + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $r, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $s) + { + return \compact('r', 's'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php new file mode 100644 index 0000000..33959c3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php @@ -0,0 +1,29 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common; + +/** + * PrivateKey interface + * + * @author Jim Wigginton + */ +interface PrivateKey +{ + public function sign($message); + //public function decrypt($ciphertext); + public function getPublicKey(); + public function toString($type, array $options = []); + /** + * @param string|false $password + * @return mixed + */ + public function withPassword($password = \false); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php new file mode 100644 index 0000000..31ccdac --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php @@ -0,0 +1,24 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common; + +/** + * PublicKey interface + * + * @author Jim Wigginton + */ +interface PublicKey +{ + public function verify($message, $signature); + //public function encrypt($plaintext); + public function toString($type, array $options = []); + public function getFingerprint($algorithm); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php new file mode 100644 index 0000000..fcfebb0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php @@ -0,0 +1,51 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common; + +/** + * Base Class for all stream cipher classes + * + * @author Jim Wigginton + */ +abstract class StreamCipher extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\SymmetricKey +{ + /** + * Block Length of the cipher + * + * Stream ciphers do not have a block size + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + */ + protected $block_size = 0; + /** + * Default Constructor. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @return \phpseclib3\Crypt\Common\StreamCipher + */ + public function __construct() + { + parent::__construct('stream'); + } + /** + * Stream ciphers not use an IV + * + * @return bool + */ + public function usesIV() + { + return \false; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php new file mode 100644 index 0000000..30fca3b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php @@ -0,0 +1,3085 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Blowfish; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Exception\BadDecryptionException; +use PostSMTP\Vendor\phpseclib3\Exception\BadModeException; +use PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException; +use PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\BinaryField; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField; +/** + * Base Class for all \phpseclib3\Crypt\* cipher classes + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +abstract class SymmetricKey +{ + /** + * Encrypt / decrypt using the Counter mode. + * + * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CTR = -1; + /** + * Encrypt / decrypt using the Electronic Code Book mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_ECB = 1; + /** + * Encrypt / decrypt using the Code Book Chaining mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CBC = 2; + /** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CFB = 3; + /** + * Encrypt / decrypt using the Cipher Feedback mode (8bit) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CFB8 = 7; + /** + * Encrypt / decrypt using the Output Feedback mode (8bit) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_OFB8 = 8; + /** + * Encrypt / decrypt using the Output Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_OFB = 4; + /** + * Encrypt / decrypt using Galois/Counter mode. + * + * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_GCM = 5; + /** + * Encrypt / decrypt using streaming mode. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_STREAM = 6; + /** + * Mode Map + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const MODE_MAP = ['ctr' => self::MODE_CTR, 'ecb' => self::MODE_ECB, 'cbc' => self::MODE_CBC, 'cfb' => self::MODE_CFB, 'cfb8' => self::MODE_CFB8, 'ofb' => self::MODE_OFB, 'ofb8' => self::MODE_OFB8, 'gcm' => self::MODE_GCM, 'stream' => self::MODE_STREAM]; + /** + * Base value for the internal implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_INTERNAL = 1; + /** + * Base value for the eval() implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_EVAL = 2; + /** + * Base value for the mcrypt implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_MCRYPT = 3; + /** + * Base value for the openssl implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL = 4; + /** + * Base value for the libsodium implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_LIBSODIUM = 5; + /** + * Base value for the openssl / gcm implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL_GCM = 6; + /** + * Engine Reverse Map + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() + */ + const ENGINE_MAP = [self::ENGINE_INTERNAL => 'PHP', self::ENGINE_EVAL => 'Eval', self::ENGINE_MCRYPT => 'mcrypt', self::ENGINE_OPENSSL => 'OpenSSL', self::ENGINE_LIBSODIUM => 'libsodium', self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)']; + /** + * The Encryption Mode + * + * @see self::__construct() + * @var int + */ + protected $mode; + /** + * The Block Length of the block cipher + * + * @var int + */ + protected $block_size = 16; + /** + * The Key + * + * @see self::setKey() + * @var string + */ + protected $key = \false; + /** + * HMAC Key + * + * @see self::setupGCM() + * @var ?string + */ + protected $hKey = \false; + /** + * The Initialization Vector + * + * @see self::setIV() + * @var string + */ + protected $iv = \false; + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::clearBuffers() + * @var string + */ + protected $encryptIV; + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::clearBuffers() + * @var string + */ + protected $decryptIV; + /** + * Continuous Buffer status + * + * @see self::enableContinuousBuffer() + * @var bool + */ + protected $continuousBuffer = \false; + /** + * Encryption buffer for CTR, OFB and CFB modes + * + * @see self::encrypt() + * @see self::clearBuffers() + * @var array + */ + protected $enbuffer; + /** + * Decryption buffer for CTR, OFB and CFB modes + * + * @see self::decrypt() + * @see self::clearBuffers() + * @var array + */ + protected $debuffer; + /** + * mcrypt resource for encryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::encrypt() + * @var resource + */ + private $enmcrypt; + /** + * mcrypt resource for decryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::decrypt() + * @var resource + */ + private $demcrypt; + /** + * Does the enmcrypt resource need to be (re)initialized? + * + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() + * @var bool + */ + private $enchanged = \true; + /** + * Does the demcrypt resource need to be (re)initialized? + * + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() + * @var bool + */ + private $dechanged = \true; + /** + * mcrypt resource for CFB mode + * + * mcrypt's CFB mode, in (and only in) buffered context, + * is broken, so phpseclib implements the CFB mode by it self, + * even when the mcrypt php extension is available. + * + * In order to do the CFB-mode work (fast) phpseclib + * use a separate ECB-mode mcrypt resource. + * + * @link http://phpseclib.sourceforge.net/cfb-demo.phps + * @see self::encrypt() + * @see self::decrypt() + * @see self::setupMcrypt() + * @var resource + */ + private $ecb; + /** + * Optimizing value while CFB-encrypting + * + * Only relevant if $continuousBuffer enabled + * and $engine == self::ENGINE_MCRYPT + * + * It's faster to re-init $enmcrypt if + * $buffer bytes > $cfb_init_len than + * using the $ecb resource furthermore. + * + * This value depends of the chosen cipher + * and the time it would be needed for it's + * initialization [by mcrypt_generic_init()] + * which, typically, depends on the complexity + * on its internaly Key-expanding algorithm. + * + * @see self::encrypt() + * @var int + */ + protected $cfb_init_len = 600; + /** + * Does internal cipher state need to be (re)initialized? + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + * @var bool + */ + protected $changed = \true; + /** + * Does Eval engie need to be (re)initialized? + * + * @see self::setup() + * @var bool + */ + protected $nonIVChanged = \true; + /** + * Padding status + * + * @see self::enablePadding() + * @var bool + */ + private $padding = \true; + /** + * Is the mode one that is paddable? + * + * @see self::__construct() + * @var bool + */ + private $paddable = \false; + /** + * Holds which crypt engine internaly should be use, + * which will be determined automatically on __construct() + * + * Currently available $engines are: + * - self::ENGINE_LIBSODIUM (very fast, php-extension: libsodium, extension_loaded('libsodium') required) + * - self::ENGINE_OPENSSL_GCM (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) + * - self::ENGINE_EVAL (medium, pure php-engine, no php-extension required) + * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) + * + * @see self::setEngine() + * @see self::encrypt() + * @see self::decrypt() + * @var int + */ + protected $engine; + /** + * Holds the preferred crypt engine + * + * @see self::setEngine() + * @see self::setPreferredEngine() + * @var int + */ + private $preferredEngine; + /** + * The mcrypt specific name of the cipher + * + * Only used if $engine == self::ENGINE_MCRYPT + * + * @link http://www.php.net/mcrypt_module_open + * @link http://www.php.net/mcrypt_list_algorithms + * @see self::setupMcrypt() + * @var string + */ + protected $cipher_name_mcrypt; + /** + * The openssl specific name of the cipher + * + * Only used if $engine == self::ENGINE_OPENSSL + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + */ + protected $cipher_name_openssl; + /** + * The openssl specific name of the cipher in ECB mode + * + * If OpenSSL does not support the mode we're trying to use (CTR) + * it can still be emulated with ECB mode. + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + */ + protected $cipher_name_openssl_ecb; + /** + * The default salt used by setPassword() + * + * @see self::setPassword() + * @var string + */ + private $password_default_salt = 'phpseclib/salt'; + /** + * The name of the performance-optimized callback function + * + * Used by encrypt() / decrypt() + * only if $engine == self::ENGINE_INTERNAL + * + * @see self::encrypt() + * @see self::decrypt() + * @see self::setupInlineCrypt() + * @var Callback + */ + protected $inline_crypt; + /** + * If OpenSSL can be used in ECB but not in CTR we can emulate CTR + * + * @see self::openssl_ctr_process() + * @var bool + */ + private $openssl_emulate_ctr = \false; + /** + * Don't truncate / null pad key + * + * @see self::clearBuffers() + * @var bool + */ + private $skip_key_adjustment = \false; + /** + * Has the key length explicitly been set or should it be derived from the key, itself? + * + * @see self::setKeyLength() + * @var bool + */ + protected $explicit_key_length = \false; + /** + * Hash subkey for GHASH + * + * @see self::setupGCM() + * @see self::ghash() + * @var BinaryField\Integer + */ + private $h; + /** + * Additional authenticated data + * + * @var string + */ + protected $aad = ''; + /** + * Authentication Tag produced after a round of encryption + * + * @var string + */ + protected $newtag = \false; + /** + * Authentication Tag to be verified during decryption + * + * @var string + */ + protected $oldtag = \false; + /** + * GCM Binary Field + * + * @see self::__construct() + * @see self::ghash() + * @var BinaryField + */ + private static $gcmField; + /** + * Poly1305 Prime Field + * + * @see self::enablePoly1305() + * @see self::poly1305() + * @var PrimeField + */ + private static $poly1305Field; + /** + * Flag for using regular vs "safe" intval + * + * @see self::initialize_static_variables() + * @var boolean + */ + protected static $use_reg_intval; + /** + * Poly1305 Key + * + * @see self::setPoly1305Key() + * @see self::poly1305() + * @var string + */ + protected $poly1305Key; + /** + * Poly1305 Flag + * + * @see self::setPoly1305Key() + * @see self::enablePoly1305() + * @var boolean + */ + protected $usePoly1305 = \false; + /** + * The Original Initialization Vector + * + * GCM uses the nonce to build the IV but we want to be able to distinguish between nonce-derived + * IV's and user-set IV's + * + * @see self::setIV() + * @var string + */ + private $origIV = \false; + /** + * Nonce + * + * Only used with GCM. We could re-use setIV() but nonce's can be of a different length and + * toggling between GCM and other modes could be more complicated if we re-used setIV() + * + * @see self::setNonce() + * @var string + */ + protected $nonce = \false; + /** + * Default Constructor. + * + * $mode could be: + * + * - ecb + * + * - cbc + * + * - ctr + * + * - cfb + * + * - cfb8 + * + * - ofb + * + * - ofb8 + * + * - gcm + * + * @param string $mode + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + $mode = \strtolower($mode); + // necessary because of 5.6 compatibility; we can't do isset(self::MODE_MAP[$mode]) in 5.6 + $map = self::MODE_MAP; + if (!isset($map[$mode])) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadModeException('No valid mode has been specified'); + } + $mode = self::MODE_MAP[$mode]; + // $mode dependent settings + switch ($mode) { + case self::MODE_ECB: + case self::MODE_CBC: + $this->paddable = \true; + break; + case self::MODE_CTR: + case self::MODE_CFB: + case self::MODE_CFB8: + case self::MODE_OFB: + case self::MODE_OFB8: + case self::MODE_STREAM: + $this->paddable = \false; + break; + case self::MODE_GCM: + if ($this->block_size != 16) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadModeException('GCM is only valid for block ciphers with a block size of 128 bits'); + } + if (!isset(self::$gcmField)) { + self::$gcmField = new \PostSMTP\Vendor\phpseclib3\Math\BinaryField(128, 7, 2, 1, 0); + } + $this->paddable = \false; + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadModeException('No valid mode has been specified'); + } + $this->mode = $mode; + static::initialize_static_variables(); + } + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$use_reg_intval)) { + switch (\true) { + // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster + case (\PHP_OS & "���") === 'WIN': + case (\php_uname('m') & "���") != 'ARM': + case \defined('PHP_INT_SIZE') && \PHP_INT_SIZE == 8: + self::$use_reg_intval = \true; + break; + case (\php_uname('m') & "���") == 'ARM': + switch (\true) { + /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors: + + https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd + + altho the changelogs make no mention of it, this bug was fixed with this commit: + + https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8 + + affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */ + case \PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID <= 70123: + case \PHP_VERSION_ID >= 70200 && \PHP_VERSION_ID <= 70211: + self::$use_reg_intval = \false; + break; + default: + self::$use_reg_intval = \true; + } + } + } + } + /** + * Sets the initialization vector. + * + * setIV() is not required when ecb or gcm modes are being used. + * + * {@internal Can be overwritten by a sub class, but does not have to be} + * + * @param string $iv + * @throws \LengthException if the IV length isn't equal to the block size + * @throws \BadMethodCallException if an IV is provided when one shouldn't be + */ + public function setIV($iv) + { + if ($this->mode == self::MODE_ECB) { + throw new \BadMethodCallException('This mode does not require an IV.'); + } + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Use setNonce instead'); + } + if (!$this->usesIV()) { + throw new \BadMethodCallException('This algorithm does not use an IV.'); + } + if (\strlen($iv) != $this->block_size) { + throw new \LengthException('Received initialization vector of size ' . \strlen($iv) . ', but size ' . $this->block_size . ' is required'); + } + $this->iv = $this->origIV = $iv; + $this->changed = \true; + } + /** + * Enables Poly1305 mode. + * + * Once enabled Poly1305 cannot be disabled. + * + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode + */ + public function enablePoly1305() + { + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + $this->usePoly1305 = \true; + } + /** + * Enables Poly1305 mode. + * + * Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key + * will be made. + * + * @param string $key optional + * @throws \LengthException if the key isn't long enough + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode + */ + public function setPoly1305Key($key = null) + { + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + if (!\is_string($key) || \strlen($key) != 32) { + throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); + } + if (!isset(self::$poly1305Field)) { + // 2^130-5 + self::$poly1305Field = new \PostSMTP\Vendor\phpseclib3\Math\PrimeField(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3fffffffffffffffffffffffffffffffb', 16)); + } + $this->poly1305Key = $key; + $this->usePoly1305 = \true; + } + /** + * Sets the nonce. + * + * setNonce() is only required when gcm is used + * + * @param string $nonce + * @throws \BadMethodCallException if an nonce is provided when one shouldn't be + */ + public function setNonce($nonce) + { + if ($this->mode != self::MODE_GCM) { + throw new \BadMethodCallException('Nonces are only used in GCM mode.'); + } + $this->nonce = $nonce; + $this->setEngine(); + } + /** + * Sets additional authenticated data + * + * setAAD() is only used by gcm or in poly1305 mode + * + * @param string $aad + * @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized + */ + public function setAAD($aad) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); + } + $this->aad = $aad; + } + /** + * Returns whether or not the algorithm uses an IV + * + * @return bool + */ + public function usesIV() + { + return $this->mode != self::MODE_GCM && $this->mode != self::MODE_ECB; + } + /** + * Returns whether or not the algorithm uses a nonce + * + * @return bool + */ + public function usesNonce() + { + return $this->mode == self::MODE_GCM; + } + /** + * Returns the current key length in bits + * + * @return int + */ + public function getKeyLength() + { + return $this->key_length << 3; + } + /** + * Returns the current block length in bits + * + * @return int + */ + public function getBlockLength() + { + return $this->block_size << 3; + } + /** + * Returns the current block length in bytes + * + * @return int + */ + public function getBlockLengthInBytes() + { + return $this->block_size; + } + /** + * Sets the key length. + * + * Keys with explicitly set lengths need to be treated accordingly + * + * @param int $length + */ + public function setKeyLength($length) + { + $this->explicit_key_length = $length >> 3; + if (\is_string($this->key) && \strlen($this->key) != $this->explicit_key_length) { + $this->key = \false; + throw new \PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException('Key has already been set and is not ' . $this->explicit_key_length . ' bytes long'); + } + } + /** + * Sets the key. + * + * The min/max length(s) of the key depends on the cipher which is used. + * If the key not fits the length(s) of the cipher it will paded with null bytes + * up to the closest valid key length. If the key is more than max length, + * we trim the excess bits. + * + * If the key is not explicitly set, it'll be assumed to be all null bytes. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @param string $key + */ + public function setKey($key) + { + if ($this->explicit_key_length !== \false && \strlen($key) != $this->explicit_key_length) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . \strlen($key) . ' bytes'); + } + $this->key = $key; + $this->key_length = \strlen($key); + $this->setEngine(); + } + /** + * Sets the password. + * + * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: + * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: + * $hash, $salt, $count, $dkLen + * + * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php + * {@link https://en.wikipedia.org/wiki/Bcrypt bcypt}: + * $salt, $rounds, $keylen + * + * This is a modified version of bcrypt used by OpenSSH. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see Crypt/Hash.php + * @param string $password + * @param string $method + * @param string[] ...$func_args + * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length + * @throws \RuntimeException if bcrypt is being used and a salt isn't provided + * @return bool + */ + public function setPassword($password, $method = 'pbkdf2', ...$func_args) + { + $key = ''; + $method = \strtolower($method); + switch ($method) { + case 'bcrypt': + if (!isset($func_args[2])) { + throw new \RuntimeException('A salt must be provided for bcrypt to work'); + } + $salt = $func_args[0]; + $rounds = isset($func_args[1]) ? $func_args[1] : 16; + $keylen = isset($func_args[2]) ? $func_args[2] : $this->key_length; + $key = \PostSMTP\Vendor\phpseclib3\Crypt\Blowfish::bcrypt_pbkdf($password, $salt, $keylen + $this->block_size, $rounds); + $this->setKey(\substr($key, 0, $keylen)); + $this->setIV(\substr($key, $keylen)); + return \true; + case 'pkcs12': + // from https://tools.ietf.org/html/rfc7292#appendix-B.2 + case 'pbkdf1': + case 'pbkdf2': + // Hash function + $hash = isset($func_args[0]) ? \strtolower($func_args[0]) : 'sha1'; + $hashObj = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash(); + $hashObj->setHash($hash); + // WPA and WPA2 use the SSID as the salt + $salt = isset($func_args[1]) ? $func_args[1] : $this->password_default_salt; + // RFC2898#section-4.2 uses 1,000 iterations by default + // WPA and WPA2 use 4,096. + $count = isset($func_args[2]) ? $func_args[2] : 1000; + // Keylength + if (isset($func_args[3])) { + if ($func_args[3] <= 0) { + throw new \LengthException('Derived key length cannot be longer 0 or less'); + } + $dkLen = $func_args[3]; + } else { + $key_length = $this->explicit_key_length !== \false ? $this->explicit_key_length : $this->key_length; + $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length; + } + switch (\true) { + case $method == 'pkcs12': + /* + In this specification, however, all passwords are created from + BMPStrings with a NULL terminator. This means that each character in + the original BMPString is encoded in 2 bytes in big-endian format + (most-significant byte first). There are no Unicode byte order + marks. The 2 bytes produced from the last character in the BMPString + are followed by 2 additional bytes with the value 0x00. + + -- https://tools.ietf.org/html/rfc7292#appendix-B.1 + */ + $password = "\0" . \chunk_split($password, 1, "\0") . "\0"; + /* + This standard specifies 3 different values for the ID byte mentioned + above: + + 1. If ID=1, then the pseudorandom bits being produced are to be used + as key material for performing encryption or decryption. + + 2. If ID=2, then the pseudorandom bits being produced are to be used + as an IV (Initial Value) for encryption or decryption. + + 3. If ID=3, then the pseudorandom bits being produced are to be used + as an integrity key for MACing. + */ + // Construct a string, D (the "diversifier"), by concatenating v/8 + // copies of ID. + $blockLength = $hashObj->getBlockLengthInBytes(); + $d1 = \str_repeat(\chr(1), $blockLength); + $d2 = \str_repeat(\chr(2), $blockLength); + $s = ''; + if (\strlen($salt)) { + while (\strlen($s) < $blockLength) { + $s .= $salt; + } + } + $s = \substr($s, 0, $blockLength); + $p = ''; + if (\strlen($password)) { + while (\strlen($p) < $blockLength) { + $p .= $password; + } + } + $p = \substr($p, 0, $blockLength); + $i = $s . $p; + $this->setKey(self::pkcs12helper($dkLen, $hashObj, $i, $d1, $count)); + if ($this->usesIV()) { + $this->setIV(self::pkcs12helper($this->block_size, $hashObj, $i, $d2, $count)); + } + return \true; + case $method == 'pbkdf1': + if ($dkLen > $hashObj->getLengthInBytes()) { + throw new \LengthException('Derived key length cannot be longer than the hash length'); + } + $t = $password . $salt; + for ($i = 0; $i < $count; ++$i) { + $t = $hashObj->hash($t); + } + $key = \substr($t, 0, $dkLen); + $this->setKey(\substr($key, 0, $dkLen >> 1)); + if ($this->usesIV()) { + $this->setIV(\substr($key, $dkLen >> 1)); + } + return \true; + case !\in_array($hash, \hash_algos()): + $i = 1; + $hashObj->setKey($password); + while (\strlen($key) < $dkLen) { + $f = $u = $hashObj->hash($salt . \pack('N', $i++)); + for ($j = 2; $j <= $count; ++$j) { + $u = $hashObj->hash($u); + $f ^= $u; + } + $key .= $f; + } + $key = \substr($key, 0, $dkLen); + break; + default: + $key = \hash_pbkdf2($hash, $password, $salt, $count, $dkLen, \true); + } + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException($method . ' is not a supported password hashing method'); + } + $this->setKey($key); + return \true; + } + /** + * PKCS#12 KDF Helper Function + * + * As discussed here: + * + * {@link https://tools.ietf.org/html/rfc7292#appendix-B} + * + * @see self::setPassword() + * @param int $n + * @param \phpseclib3\Crypt\Hash $hashObj + * @param string $i + * @param string $d + * @param int $count + * @return string $a + */ + private static function pkcs12helper($n, $hashObj, $i, $d, $count) + { + static $one; + if (!isset($one)) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + $blockLength = $hashObj->getBlockLength() >> 3; + $c = \ceil($n / $hashObj->getLengthInBytes()); + $a = ''; + for ($j = 1; $j <= $c; $j++) { + $ai = $d . $i; + for ($k = 0; $k < $count; $k++) { + $ai = $hashObj->hash($ai); + } + $b = ''; + while (\strlen($b) < $blockLength) { + $b .= $ai; + } + $b = \substr($b, 0, $blockLength); + $b = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($b, 256); + $newi = ''; + for ($k = 0; $k < \strlen($i); $k += $blockLength) { + $temp = \substr($i, $k, $blockLength); + $temp = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($temp, 256); + $temp->setPrecision($blockLength << 3); + $temp = $temp->add($b); + $temp = $temp->add($one); + $newi .= $temp->toBytes(\false); + } + $i = $newi; + $a .= $ai; + } + return \substr($a, 0, $n); + } + /** + * Encrypts a message. + * + * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher + * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's + * necessary are discussed in the following + * URL: + * + * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} + * + * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. + * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that + * length. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::decrypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + if ($this->paddable) { + $plaintext = $this->pad($plaintext); + } + $this->setup(); + if ($this->mode == self::MODE_GCM) { + $oldIV = $this->iv; + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $ciphertext = $cipher->encrypt($plaintext); + $s = $this->ghash(self::nullPad128($this->aad) . self::nullPad128($ciphertext) . self::len64($this->aad) . self::len64($ciphertext)); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $this->newtag = $cipher->encrypt($s); + return $ciphertext; + } + if (isset($this->poly1305Key)) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = \false; + $ciphertext = $cipher->encrypt($plaintext); + $this->newtag = $this->poly1305($ciphertext); + return $ciphertext; + } + if ($this->engine === self::ENGINE_OPENSSL) { + switch ($this->mode) { + case self::MODE_STREAM: + return \openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); + case self::MODE_ECB: + return \openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); + case self::MODE_CBC: + $result = \openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + $this->encryptIV = \substr($result, -$this->block_size); + } + return $result; + case self::MODE_CTR: + return $this->openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $ciphertext = ''; + if ($this->continuousBuffer) { + $iv =& $this->encryptIV; + $pos =& $this->enbuffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = \strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = \substr($iv, $orig_pos) ^ $plaintext; + $iv = \substr_replace($iv, $ciphertext, $orig_pos, $i); + $plaintext = \substr($plaintext, $i); + } + $overflow = $len % $this->block_size; + if ($overflow) { + $ciphertext .= \openssl_encrypt(\substr($plaintext, 0, -$overflow) . \str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $iv); + $iv = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::pop($ciphertext, $this->block_size); + $size = $len - $overflow; + $block = $iv ^ \substr($plaintext, -$overflow); + $iv = \substr_replace($iv, $block, 0, $overflow); + $ciphertext .= $block; + $pos = $overflow; + } elseif ($len) { + $ciphertext = \openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $iv); + $iv = \substr($ciphertext, -$this->block_size); + } + return $ciphertext; + case self::MODE_CFB8: + $ciphertext = \openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + if (($len = \strlen($ciphertext)) >= $this->block_size) { + $this->encryptIV = \substr($ciphertext, -$this->block_size); + } else { + $this->encryptIV = \substr($this->encryptIV, $len - $this->block_size) . \substr($ciphertext, -$len); + } + } + return $ciphertext; + case self::MODE_OFB8: + $ciphertext = ''; + $len = \strlen($plaintext); + $iv = $this->encryptIV; + for ($i = 0; $i < $len; ++$i) { + $xor = \openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); + $ciphertext .= $plaintext[$i] ^ $xor; + $iv = \substr($iv, 1) . $xor[0]; + } + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + break; + case self::MODE_OFB: + return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); + } + } + if ($this->engine === self::ENGINE_MCRYPT) { + \set_error_handler(function () { + }); + if ($this->enchanged) { + \mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); + $this->enchanged = \false; + } + // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's + // rewritten CFB implementation the above outputs the same thing twice. + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $block_size = $this->block_size; + $iv =& $this->encryptIV; + $pos =& $this->enbuffer['pos']; + $len = \strlen($plaintext); + $ciphertext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + $ciphertext = \substr($iv, $orig_pos) ^ $plaintext; + $iv = \substr_replace($iv, $ciphertext, $orig_pos, $i); + $this->enbuffer['enmcrypt_init'] = \true; + } + if ($len >= $block_size) { + if ($this->enbuffer['enmcrypt_init'] === \false || $len > $this->cfb_init_len) { + if ($this->enbuffer['enmcrypt_init'] === \true) { + \mcrypt_generic_init($this->enmcrypt, $this->key, $iv); + $this->enbuffer['enmcrypt_init'] = \false; + } + $ciphertext .= \mcrypt_generic($this->enmcrypt, \substr($plaintext, $i, $len - $len % $block_size)); + $iv = \substr($ciphertext, -$block_size); + $len %= $block_size; + } else { + while ($len >= $block_size) { + $iv = \mcrypt_generic($this->ecb, $iv) ^ \substr($plaintext, $i, $block_size); + $ciphertext .= $iv; + $len -= $block_size; + $i += $block_size; + } + } + } + if ($len) { + $iv = \mcrypt_generic($this->ecb, $iv); + $block = $iv ^ \substr($plaintext, -$len); + $iv = \substr_replace($iv, $block, 0, $len); + $ciphertext .= $block; + $pos = $len; + } + \restore_error_handler(); + return $ciphertext; + } + $ciphertext = \mcrypt_generic($this->enmcrypt, $plaintext); + if (!$this->continuousBuffer) { + \mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); + } + \restore_error_handler(); + return $ciphertext; + } + if ($this->engine === self::ENGINE_EVAL) { + $inline = $this->inline_crypt; + return $inline('encrypt', $plaintext); + } + $buffer =& $this->enbuffer; + $block_size = $this->block_size; + $ciphertext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $ciphertext .= $this->encryptBlock(\substr($plaintext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->encryptIV; + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $block = \substr($plaintext, $i, $block_size); + $block = $this->encryptBlock($block ^ $xor); + $xor = $block; + $ciphertext .= $block; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->encryptIV; + if (\strlen($buffer['ciphertext'])) { + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $block = \substr($plaintext, $i, $block_size); + if (\strlen($block) > \strlen($buffer['ciphertext'])) { + $buffer['ciphertext'] .= $this->encryptBlock($xor); + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($xor); + } + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext .= $block ^ $key; + } + } else { + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $block = \substr($plaintext, $i, $block_size); + $key = $this->encryptBlock($xor); + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($xor); + $ciphertext .= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = \strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = \substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + if ($this->continuousBuffer) { + $iv =& $this->encryptIV; + $pos =& $buffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = \strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = \substr($iv, $orig_pos) ^ $plaintext; + $iv = \substr_replace($iv, $ciphertext, $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->encryptBlock($iv) ^ \substr($plaintext, $i, $block_size); + $ciphertext .= $iv; + $len -= $block_size; + $i += $block_size; + } + if ($len) { + $iv = $this->encryptBlock($iv); + $block = $iv ^ \substr($plaintext, $i); + $iv = \substr_replace($iv, $block, 0, $len); + $ciphertext .= $block; + $pos = $len; + } + break; + case self::MODE_CFB8: + $ciphertext = ''; + $len = \strlen($plaintext); + $iv = $this->encryptIV; + for ($i = 0; $i < $len; ++$i) { + $ciphertext .= $c = $plaintext[$i] ^ $this->encryptBlock($iv); + $iv = \substr($iv, 1) . $c; + } + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->encryptIV = \substr($ciphertext, -$block_size); + } else { + $this->encryptIV = \substr($this->encryptIV, $len - $block_size) . \substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB8: + $ciphertext = ''; + $len = \strlen($plaintext); + $iv = $this->encryptIV; + for ($i = 0; $i < $len; ++$i) { + $xor = $this->encryptBlock($iv); + $ciphertext .= $plaintext[$i] ^ $xor; + $iv = \substr($iv, 1) . $xor[0]; + } + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + break; + case self::MODE_OFB: + $xor = $this->encryptIV; + if (\strlen($buffer['xor'])) { + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $block = \substr($plaintext, $i, $block_size); + if (\strlen($block) > \strlen($buffer['xor'])) { + $xor = $this->encryptBlock($xor); + $buffer['xor'] .= $xor; + } + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($buffer['xor'], $block_size); + $ciphertext .= $block ^ $key; + } + } else { + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $xor = $this->encryptBlock($xor); + $ciphertext .= \substr($plaintext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = \strlen($plaintext) % $block_size) { + $buffer['xor'] = \substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $ciphertext = $this->encryptBlock($plaintext); + break; + } + return $ciphertext; + } + /** + * Decrypts a message. + * + * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until + * it is. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::encrypt() + * @param string $ciphertext + * @return string $plaintext + * @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size + */ + public function decrypt($ciphertext) + { + if ($this->paddable && \strlen($ciphertext) % $this->block_size) { + throw new \LengthException('The ciphertext length (' . \strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); + } + $this->setup(); + if ($this->mode == self::MODE_GCM || isset($this->poly1305Key)) { + if ($this->oldtag === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException('Authentication Tag has not been set'); + } + if (isset($this->poly1305Key)) { + $newtag = $this->poly1305($ciphertext); + } else { + $oldIV = $this->iv; + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $plaintext = $cipher->decrypt($ciphertext); + $s = $this->ghash(self::nullPad128($this->aad) . self::nullPad128($ciphertext) . self::len64($this->aad) . self::len64($ciphertext)); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $newtag = $cipher->encrypt($s); + } + if ($this->oldtag != \substr($newtag, 0, \strlen($newtag))) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = \false; + $plaintext = $cipher->decrypt($ciphertext); + $this->oldtag = \false; + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = \false; + return $plaintext; + } + if ($this->engine === self::ENGINE_OPENSSL) { + switch ($this->mode) { + case self::MODE_STREAM: + $plaintext = \openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); + break; + case self::MODE_ECB: + $plaintext = \openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); + break; + case self::MODE_CBC: + $offset = $this->block_size; + $plaintext = \openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + $this->decryptIV = \substr($ciphertext, -$offset, $this->block_size); + } + break; + case self::MODE_CTR: + $plaintext = $this->openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $plaintext = ''; + if ($this->continuousBuffer) { + $iv =& $this->decryptIV; + $pos =& $this->debuffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = \strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize + $plaintext = \substr($iv, $orig_pos) ^ $ciphertext; + $iv = \substr_replace($iv, \substr($ciphertext, 0, $i), $orig_pos, $i); + $ciphertext = \substr($ciphertext, $i); + } + $overflow = $len % $this->block_size; + if ($overflow) { + $plaintext .= \openssl_decrypt(\substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $iv); + if ($len - $overflow) { + $iv = \substr($ciphertext, -$overflow - $this->block_size, -$overflow); + } + $iv = \openssl_encrypt(\str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $iv); + $plaintext .= $iv ^ \substr($ciphertext, -$overflow); + $iv = \substr_replace($iv, \substr($ciphertext, -$overflow), 0, $overflow); + $pos = $overflow; + } elseif ($len) { + $plaintext .= \openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $iv); + $iv = \substr($ciphertext, -$this->block_size); + } + break; + case self::MODE_CFB8: + $plaintext = \openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + if (($len = \strlen($ciphertext)) >= $this->block_size) { + $this->decryptIV = \substr($ciphertext, -$this->block_size); + } else { + $this->decryptIV = \substr($this->decryptIV, $len - $this->block_size) . \substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB8: + $plaintext = ''; + $len = \strlen($ciphertext); + $iv = $this->decryptIV; + for ($i = 0; $i < $len; ++$i) { + $xor = \openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); + $plaintext .= $ciphertext[$i] ^ $xor; + $iv = \substr($iv, 1) . $xor[0]; + } + if ($this->continuousBuffer) { + $this->decryptIV = $iv; + } + break; + case self::MODE_OFB: + $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); + } + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + if ($this->engine === self::ENGINE_MCRYPT) { + \set_error_handler(function () { + }); + $block_size = $this->block_size; + if ($this->dechanged) { + \mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); + $this->dechanged = \false; + } + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $iv =& $this->decryptIV; + $pos =& $this->debuffer['pos']; + $len = \strlen($ciphertext); + $plaintext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = \substr($iv, $orig_pos) ^ $ciphertext; + $iv = \substr_replace($iv, \substr($ciphertext, 0, $i), $orig_pos, $i); + } + if ($len >= $block_size) { + $cb = \substr($ciphertext, $i, $len - $len % $block_size); + $plaintext .= \mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; + $iv = \substr($cb, -$block_size); + $len %= $block_size; + } + if ($len) { + $iv = \mcrypt_generic($this->ecb, $iv); + $plaintext .= $iv ^ \substr($ciphertext, -$len); + $iv = \substr_replace($iv, \substr($ciphertext, -$len), 0, $len); + $pos = $len; + } + \restore_error_handler(); + return $plaintext; + } + $plaintext = \mdecrypt_generic($this->demcrypt, $ciphertext); + if (!$this->continuousBuffer) { + \mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); + } + \restore_error_handler(); + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + if ($this->engine === self::ENGINE_EVAL) { + $inline = $this->inline_crypt; + return $inline('decrypt', $ciphertext); + } + $block_size = $this->block_size; + $buffer =& $this->debuffer; + $plaintext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < \strlen($ciphertext); $i += $block_size) { + $plaintext .= $this->decryptBlock(\substr($ciphertext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->decryptIV; + for ($i = 0; $i < \strlen($ciphertext); $i += $block_size) { + $block = \substr($ciphertext, $i, $block_size); + $plaintext .= $this->decryptBlock($block) ^ $xor; + $xor = $block; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->decryptIV; + if (\strlen($buffer['ciphertext'])) { + for ($i = 0; $i < \strlen($ciphertext); $i += $block_size) { + $block = \substr($ciphertext, $i, $block_size); + if (\strlen($block) > \strlen($buffer['ciphertext'])) { + $buffer['ciphertext'] .= $this->encryptBlock($xor); + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($xor); + } + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($buffer['ciphertext'], $block_size); + $plaintext .= $block ^ $key; + } + } else { + for ($i = 0; $i < \strlen($ciphertext); $i += $block_size) { + $block = \substr($ciphertext, $i, $block_size); + $key = $this->encryptBlock($xor); + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($xor); + $plaintext .= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = \strlen($ciphertext) % $block_size) { + $buffer['ciphertext'] = \substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + if ($this->continuousBuffer) { + $iv =& $this->decryptIV; + $pos =& $buffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = \strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = \substr($iv, $orig_pos) ^ $ciphertext; + $iv = \substr_replace($iv, \substr($ciphertext, 0, $i), $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->encryptBlock($iv); + $cb = \substr($ciphertext, $i, $block_size); + $plaintext .= $iv ^ $cb; + $iv = $cb; + $len -= $block_size; + $i += $block_size; + } + if ($len) { + $iv = $this->encryptBlock($iv); + $plaintext .= $iv ^ \substr($ciphertext, $i); + $iv = \substr_replace($iv, \substr($ciphertext, $i), 0, $len); + $pos = $len; + } + break; + case self::MODE_CFB8: + $plaintext = ''; + $len = \strlen($ciphertext); + $iv = $this->decryptIV; + for ($i = 0; $i < $len; ++$i) { + $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); + $iv = \substr($iv, 1) . $ciphertext[$i]; + } + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->decryptIV = \substr($ciphertext, -$block_size); + } else { + $this->decryptIV = \substr($this->decryptIV, $len - $block_size) . \substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB8: + $plaintext = ''; + $len = \strlen($ciphertext); + $iv = $this->decryptIV; + for ($i = 0; $i < $len; ++$i) { + $xor = $this->encryptBlock($iv); + $plaintext .= $ciphertext[$i] ^ $xor; + $iv = \substr($iv, 1) . $xor[0]; + } + if ($this->continuousBuffer) { + $this->decryptIV = $iv; + } + break; + case self::MODE_OFB: + $xor = $this->decryptIV; + if (\strlen($buffer['xor'])) { + for ($i = 0; $i < \strlen($ciphertext); $i += $block_size) { + $block = \substr($ciphertext, $i, $block_size); + if (\strlen($block) > \strlen($buffer['xor'])) { + $xor = $this->encryptBlock($xor); + $buffer['xor'] .= $xor; + } + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($buffer['xor'], $block_size); + $plaintext .= $block ^ $key; + } + } else { + for ($i = 0; $i < \strlen($ciphertext); $i += $block_size) { + $xor = $this->encryptBlock($xor); + $plaintext .= \substr($ciphertext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = \strlen($ciphertext) % $block_size) { + $buffer['xor'] = \substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $plaintext = $this->decryptBlock($ciphertext); + break; + } + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + /** + * Get the authentication tag + * + * Only used in GCM or Poly1305 mode + * + * @see self::encrypt() + * @param int $length optional + * @return string + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function getTag($length = 16) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + if ($this->newtag === \false) { + throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); + } + // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it + // were 0 you might as well be doing CTR and less than 4 provides minimal security that could be trivially + // easily brute forced. + // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 + // for more info + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + return $length == 16 ? $this->newtag : \substr($this->newtag, 0, $length); + } + /** + * Sets the authentication tag + * + * Only used in GCM mode + * + * @see self::decrypt() + * @param string $tag + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function setTag($tag) + { + if ($this->usePoly1305 && !isset($this->poly1305Key) && \method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + $length = \strlen($tag); + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + $this->oldtag = $tag; + } + /** + * Get the IV + * + * mcrypt requires an IV even if ECB is used + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $iv + * @return string + */ + protected function getIV($iv) + { + return $this->mode == self::MODE_ECB ? \str_repeat("\0", $this->block_size) : $iv; + } + /** + * OpenSSL CTR Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for CTR is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this + * function will emulate CTR with ECB when necessary. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + */ + private function openssl_ctr_process($plaintext, &$encryptIV, &$buffer) + { + $ciphertext = ''; + $block_size = $this->block_size; + $key = $this->key; + if ($this->openssl_emulate_ctr) { + $xor = $encryptIV; + if (\strlen($buffer['ciphertext'])) { + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $block = \substr($plaintext, $i, $block_size); + if (\strlen($block) > \strlen($buffer['ciphertext'])) { + $buffer['ciphertext'] .= \openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); + } + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($xor); + $otp = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext .= $block ^ $otp; + } + } else { + for ($i = 0; $i < \strlen($plaintext); $i += $block_size) { + $block = \substr($plaintext, $i, $block_size); + $otp = \openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($xor); + $ciphertext .= $block ^ $otp; + } + } + if ($this->continuousBuffer) { + $encryptIV = $xor; + if ($start = \strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = \substr($key, $start) . $buffer['ciphertext']; + } + } + return $ciphertext; + } + if (\strlen($buffer['ciphertext'])) { + $ciphertext = $plaintext ^ \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($buffer['ciphertext'], \strlen($plaintext)); + $plaintext = \substr($plaintext, \strlen($ciphertext)); + if (!\strlen($plaintext)) { + return $ciphertext; + } + } + $overflow = \strlen($plaintext) % $block_size; + if ($overflow) { + $plaintext2 = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::pop($plaintext, $overflow); + // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 + $encrypted = \openssl_encrypt($plaintext . \str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $encryptIV); + $temp = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::pop($encrypted, $block_size); + $ciphertext .= $encrypted . ($plaintext2 ^ $temp); + if ($this->continuousBuffer) { + $buffer['ciphertext'] = \substr($temp, $overflow); + $encryptIV = $temp; + } + } elseif (!\strlen($buffer['ciphertext'])) { + $ciphertext .= \openssl_encrypt($plaintext . \str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $encryptIV); + $temp = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $temp; + } + } + if ($this->continuousBuffer) { + $encryptIV = \openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING); + if ($overflow) { + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::increment_str($encryptIV); + } + } + return $ciphertext; + } + /** + * OpenSSL OFB Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for OFB is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + */ + private function openssl_ofb_process($plaintext, &$encryptIV, &$buffer) + { + if (\strlen($buffer['xor'])) { + $ciphertext = $plaintext ^ $buffer['xor']; + $buffer['xor'] = \substr($buffer['xor'], \strlen($ciphertext)); + $plaintext = \substr($plaintext, \strlen($ciphertext)); + } else { + $ciphertext = ''; + } + $block_size = $this->block_size; + $len = \strlen($plaintext); + $key = $this->key; + $overflow = $len % $block_size; + if (\strlen($plaintext)) { + if ($overflow) { + $ciphertext .= \openssl_encrypt(\substr($plaintext, 0, -$overflow) . \str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $encryptIV); + $xor = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $xor; + } + $ciphertext .= \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($xor, $overflow) ^ \substr($plaintext, -$overflow); + if ($this->continuousBuffer) { + $buffer['xor'] = $xor; + } + } else { + $ciphertext = \openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, \OPENSSL_RAW_DATA | \OPENSSL_ZERO_PADDING, $encryptIV); + if ($this->continuousBuffer) { + $encryptIV = \substr($ciphertext, -$block_size) ^ \substr($plaintext, -$block_size); + } + } + } + return $ciphertext; + } + /** + * phpseclib <-> OpenSSL Mode Mapper + * + * May need to be overwritten by classes extending this one in some cases + * + * @return string + */ + protected function openssl_translate_mode() + { + switch ($this->mode) { + case self::MODE_ECB: + return 'ecb'; + case self::MODE_CBC: + return 'cbc'; + case self::MODE_CTR: + case self::MODE_GCM: + return 'ctr'; + case self::MODE_CFB: + return 'cfb'; + case self::MODE_CFB8: + return 'cfb8'; + case self::MODE_OFB: + return 'ofb'; + } + } + /** + * Pad "packets". + * + * Block ciphers working by encrypting between their specified [$this->]block_size at a time + * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to + * pad the input so that it is of the proper length. + * + * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, + * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping + * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is + * transmitted separately) + * + * @see self::disablePadding() + */ + public function enablePadding() + { + $this->padding = \true; + } + /** + * Do not pad packets. + * + * @see self::enablePadding() + */ + public function disablePadding() + { + $this->padding = \false; + } + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->encrypt(substr($plaintext, 16, 16)); + * + * + * echo $rijndael->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\*() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::disableContinuousBuffer() + */ + public function enableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('This mode does not run in continuous mode'); + } + $this->continuousBuffer = \true; + $this->setEngine(); + } + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::enableContinuousBuffer() + */ + public function disableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + if (!$this->continuousBuffer) { + return; + } + $this->continuousBuffer = \false; + $this->setEngine(); + } + /** + * Test for engine validity + * + * @see self::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_OPENSSL: + $this->openssl_emulate_ctr = \false; + $result = $this->cipher_name_openssl && \extension_loaded('openssl'); + if (!$result) { + return \false; + } + $methods = \openssl_get_cipher_methods(); + if (\in_array($this->cipher_name_openssl, $methods)) { + return \true; + } + // not all of openssl's symmetric cipher's support ctr. for those + // that don't we'll emulate it + switch ($this->mode) { + case self::MODE_CTR: + if (\in_array($this->cipher_name_openssl_ecb, $methods)) { + $this->openssl_emulate_ctr = \true; + return \true; + } + } + return \false; + case self::ENGINE_MCRYPT: + \set_error_handler(function () { + }); + $result = $this->cipher_name_mcrypt && \extension_loaded('mcrypt') && \in_array($this->cipher_name_mcrypt, \mcrypt_list_algorithms()); + \restore_error_handler(); + return $result; + case self::ENGINE_EVAL: + return \method_exists($this, 'setupInlineCrypt'); + case self::ENGINE_INTERNAL: + return \true; + } + return \false; + } + /** + * Test for engine validity + * + * @see self::__construct() + * @param string $engine + * @return bool + */ + public function isValidEngine($engine) + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = \array_map('strtolower', self::ENGINE_MAP); + $reverseMap = \array_flip($reverseMap); + } + $engine = \strtolower($engine); + if (!isset($reverseMap[$engine])) { + return \false; + } + return $this->isValidEngineHelper($reverseMap[$engine]); + } + /** + * Sets the preferred crypt engine + * + * Currently, $engine could be: + * + * - libsodium[very fast] + * + * - OpenSSL [very fast] + * + * - mcrypt [fast] + * + * - Eval [slow] + * + * - PHP [slowest] + * + * If the preferred crypt engine is not available the fastest available one will be used + * + * @see self::__construct() + * @param string $engine + */ + public function setPreferredEngine($engine) + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = \array_map('strtolower', self::ENGINE_MAP); + $reverseMap = \array_flip($reverseMap); + } + $engine = \is_string($engine) ? \strtolower($engine) : ''; + $this->preferredEngine = isset($reverseMap[$engine]) ? $reverseMap[$engine] : self::ENGINE_LIBSODIUM; + $this->setEngine(); + } + /** + * Returns the engine currently being utilized + * + * @see self::setEngine() + */ + public function getEngine() + { + return self::ENGINE_MAP[$this->engine]; + } + /** + * Sets the engine as appropriate + * + * @see self::__construct() + */ + protected function setEngine() + { + $this->engine = null; + $candidateEngines = [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM, self::ENGINE_OPENSSL, self::ENGINE_MCRYPT, self::ENGINE_EVAL]; + if (isset($this->preferredEngine)) { + $temp = [$this->preferredEngine]; + $candidateEngines = \array_merge($temp, \array_diff($candidateEngines, $temp)); + } + foreach ($candidateEngines as $engine) { + if ($this->isValidEngineHelper($engine)) { + $this->engine = $engine; + break; + } + } + if (!$this->engine) { + $this->engine = self::ENGINE_INTERNAL; + } + if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { + \set_error_handler(function () { + }); + // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, + // (re)open them with the module named in $this->cipher_name_mcrypt + \mcrypt_module_close($this->enmcrypt); + \mcrypt_module_close($this->demcrypt); + $this->enmcrypt = null; + $this->demcrypt = null; + if ($this->ecb) { + \mcrypt_module_close($this->ecb); + $this->ecb = null; + } + \restore_error_handler(); + } + $this->changed = $this->nonIVChanged = \true; + } + /** + * Encrypts a block + * + * Note: Must be extended by the child \phpseclib3\Crypt\* class + * + * @param string $in + * @return string + */ + protected abstract function encryptBlock($in); + /** + * Decrypts a block + * + * Note: Must be extended by the child \phpseclib3\Crypt\* class + * + * @param string $in + * @return string + */ + protected abstract function decryptBlock($in); + /** + * Setup the key (expansion) + * + * Only used if $engine == self::ENGINE_INTERNAL + * + * Note: Must extend by the child \phpseclib3\Crypt\* class + * + * @see self::setup() + */ + protected abstract function setupKey(); + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == self::ENGINE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * {@internal setup() is always called before en/decryption.} + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + $this->changed = \false; + if ($this->usePoly1305 && !isset($this->poly1305Key) && \method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => \true]; + //$this->newtag = $this->oldtag = false; + if ($this->usesNonce()) { + if ($this->nonce === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException('No nonce has been defined'); + } + if ($this->mode == self::MODE_GCM && !\in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + $this->setupGCM(); + } + } else { + $this->iv = $this->origIV; + } + if ($this->iv === \false && !\in_array($this->mode, [self::MODE_STREAM, self::MODE_ECB])) { + if ($this->mode != self::MODE_GCM || !\in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException('No IV has been defined'); + } + } + if ($this->key === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException('No key has been defined'); + } + $this->encryptIV = $this->decryptIV = $this->iv; + switch ($this->engine) { + case self::ENGINE_MCRYPT: + $this->enchanged = $this->dechanged = \true; + \set_error_handler(function () { + }); + if (!isset($this->enmcrypt)) { + static $mcrypt_modes = [self::MODE_CTR => 'ctr', self::MODE_ECB => \MCRYPT_MODE_ECB, self::MODE_CBC => \MCRYPT_MODE_CBC, self::MODE_CFB => 'ncfb', self::MODE_CFB8 => \MCRYPT_MODE_CFB, self::MODE_OFB => \MCRYPT_MODE_NOFB, self::MODE_OFB8 => \MCRYPT_MODE_OFB, self::MODE_STREAM => \MCRYPT_MODE_STREAM]; + $this->demcrypt = \mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = \mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() + // to workaround mcrypt's broken ncfb implementation in buffered mode + // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + if ($this->mode == self::MODE_CFB) { + $this->ecb = \mcrypt_module_open($this->cipher_name_mcrypt, '', \MCRYPT_MODE_ECB, ''); + } + } + // else should mcrypt_generic_deinit be called? + if ($this->mode == self::MODE_CFB) { + \mcrypt_generic_init($this->ecb, $this->key, \str_repeat("\0", $this->block_size)); + } + \restore_error_handler(); + break; + case self::ENGINE_INTERNAL: + $this->setupKey(); + break; + case self::ENGINE_EVAL: + if ($this->nonIVChanged) { + $this->setupKey(); + $this->setupInlineCrypt(); + } + } + $this->nonIVChanged = \false; + } + /** + * Pads a string + * + * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. + * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to + * chr($this->block_size - (strlen($text) % $this->block_size) + * + * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless + * and padding will, hence forth, be enabled. + * + * @see self::unpad() + * @param string $text + * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size + * @return string + */ + protected function pad($text) + { + $length = \strlen($text); + if (!$this->padding) { + if ($length % $this->block_size == 0) { + return $text; + } else { + throw new \LengthException("The plaintext's length ({$length}) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); + } + } + $pad = $this->block_size - $length % $this->block_size; + return \str_pad($text, $length + $pad, \chr($pad)); + } + /** + * Unpads a string. + * + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. + * + * @see self::pad() + * @param string $text + * @throws \LengthException if the ciphertext's length is not a multiple of the block size + * @return string + */ + protected function unpad($text) + { + if (!$this->padding) { + return $text; + } + $length = \ord($text[\strlen($text) - 1]); + if (!$length || $length > $this->block_size) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadDecryptionException("The ciphertext has an invalid padding length ({$length}) compared to the block size ({$this->block_size})"); + } + return \substr($text, 0, -$length); + } + /** + * Setup the performance-optimized function for de/encrypt() + * + * Stores the created (or existing) callback function-name + * in $this->inline_crypt + * + * Internally for phpseclib developers: + * + * _setupInlineCrypt() would be called only if: + * + * - $this->engine === self::ENGINE_EVAL + * + * - each time on _setup(), after(!) _setupKey() + * + * + * This ensures that _setupInlineCrypt() has always a + * full ready2go initializated internal cipher $engine state + * where, for example, the keys already expanded, + * keys/block_size calculated and such. + * + * It is, each time if called, the responsibility of _setupInlineCrypt(): + * + * - to set $this->inline_crypt to a valid and fully working callback function + * as a (faster) replacement for encrypt() / decrypt() + * + * - NOT to create unlimited callback functions (for memory reasons!) + * no matter how often _setupInlineCrypt() would be called. At some + * point of amount they must be generic re-useable. + * + * - the code of _setupInlineCrypt() it self, + * and the generated callback code, + * must be, in following order: + * - 100% safe + * - 100% compatible to encrypt()/decrypt() + * - using only php5+ features/lang-constructs/php-extensions if + * compatibility (down to php4) or fallback is provided + * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) + * - >= 10% faster than encrypt()/decrypt() [which is, by the way, + * the reason for the existence of _setupInlineCrypt() :-)] + * - memory-nice + * - short (as good as possible) + * + * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. + * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib3\Crypt\* class. + * - The following variable names are reserved: + * - $_* (all variable names prefixed with an underscore) + * - $self (object reference to it self. Do not use $this, but $self instead) + * - $in (the content of $in has to en/decrypt by the generated code) + * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only + * + * {@internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()} + * + * @see self::setup() + * @see self::createInlineCryptFunction() + * @see self::encrypt() + * @see self::decrypt() + */ + //protected function setupInlineCrypt(); + /** + * Creates the performance-optimized function for en/decrypt() + * + * Internally for phpseclib developers: + * + * _createInlineCryptFunction(): + * + * - merge the $cipher_code [setup'ed by _setupInlineCrypt()] + * with the current [$this->]mode of operation code + * + * - create the $inline function, which called by encrypt() / decrypt() + * as its replacement to speed up the en/decryption operations. + * + * - return the name of the created $inline callback function + * + * - used to speed up en/decryption + * + * + * + * The main reason why can speed up things [up to 50%] this way are: + * + * - using variables more effective then regular. + * (ie no use of expensive arrays but integers $k_0, $k_1 ... + * or even, for example, the pure $key[] values hardcoded) + * + * - avoiding 1000's of function calls of ie _encryptBlock() + * but inlining the crypt operations. + * in the mode of operation for() loop. + * + * - full loop unroll the (sometimes key-dependent) rounds + * avoiding this way ++$i counters and runtime-if's etc... + * + * The basic code architectur of the generated $inline en/decrypt() + * lambda function, in pseudo php, is: + * + * + * +----------------------------------------------------------------------------------------------+ + * | callback $inline = create_function: | + * | lambda_function_0001_crypt_ECB($action, $text) | + * | { | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_crypt']; // general init code. | + * | // ie: $sbox'es declarations used for | + * | // encrypt and decrypt'ing. | + * | | + * | switch ($action) { | + * | case 'encrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | + * | ie: specified $key or $box | + * | declarations for encrypt'ing. | + * | | + * | foreach ($ciphertext) { | + * | $in = $block_size of $ciphertext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for encryption. | + * | // $cipher_code['encrypt_block'] has to | + * | // encrypt the content of the $in variable | + * | | + * | $plaintext .= $in; | + * | } | + * | return $plaintext; | + * | | + * | case 'decrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_decrypt']; // decrypt sepcific init code | + * | ie: specified $key or $box | + * | declarations for decrypt'ing. | + * | foreach ($plaintext) { | + * | $in = $block_size of $plaintext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for decryption. | + * | // $cipher_code['decrypt_block'] has to | + * | // decrypt the content of the $in variable | + * | $ciphertext .= $in; | + * | } | + * | return $ciphertext; | + * | } | + * | } | + * +----------------------------------------------------------------------------------------------+ + * + * + * See also the \phpseclib3\Crypt\*::_setupInlineCrypt()'s for + * productive inline $cipher_code's how they works. + * + * Structure of: + * + * $cipher_code = [ + * 'init_crypt' => (string) '', // optional + * 'init_encrypt' => (string) '', // optional + * 'init_decrypt' => (string) '', // optional + * 'encrypt_block' => (string) '', // required + * 'decrypt_block' => (string) '' // required + * ]; + * + * + * @see self::setupInlineCrypt() + * @see self::encrypt() + * @see self::decrypt() + * @param array $cipher_code + * @return string (the name of the created callback function) + */ + protected function createInlineCryptFunction($cipher_code) + { + $block_size = $this->block_size; + // optional + $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : ''; + $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : ''; + $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : ''; + // required + $encrypt_block = $cipher_code['encrypt_block']; + $decrypt_block = $cipher_code['decrypt_block']; + // Generating mode of operation inline code, + // merged with the $cipher_code algorithm + // for encrypt- and decryption. + switch ($this->mode) { + case self::MODE_ECB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . '); + ' . $encrypt_block . ' + $_ciphertext.= $in; + } + + return $_ciphertext; + '; + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); + $_ciphertext_len = strlen($_text); + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . '); + ' . $decrypt_block . ' + $_plaintext.= $in; + } + + return $this->unpad($_plaintext); + '; + break; + case self::MODE_CTR: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + ' . $encrypt_block . ' + \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + $in = $_xor; + ' . $encrypt_block . ' + \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::increment_str($_xor); + $_key = $in; + $_ciphertext.= $_block ^ $_key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % ' . $block_size . ') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; + + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + ' . $encrypt_block . ' + \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + $in = $_xor; + ' . $encrypt_block . ' + \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::increment_str($_xor); + $_key = $in; + $_plaintext.= $_block ^ $_key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % ' . $block_size . ') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_plaintext; + '; + break; + case self::MODE_CFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_buffer = &$this->enbuffer; + + if ($this->continuousBuffer) { + $_iv = &$this->encryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $this->encryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = ' . $block_size . ' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); + } + while ($_len >= ' . $block_size . ') { + $in = $_iv; + ' . $encrypt_block . '; + $_iv = $in ^ substr($_text, $_i, ' . $block_size . '); + $_ciphertext.= $_iv; + $_len-= ' . $block_size . '; + $_i+= ' . $block_size . '; + } + if ($_len) { + $in = $_iv; + ' . $encrypt_block . ' + $_iv = $in; + $_block = $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, $_block, 0, $_len); + $_ciphertext.= $_block; + $_pos = $_len; + } + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_buffer = &$this->debuffer; + + if ($this->continuousBuffer) { + $_iv = &$this->decryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $this->decryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = ' . $block_size . ' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_plaintext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); + } + while ($_len >= ' . $block_size . ') { + $in = $_iv; + ' . $encrypt_block . ' + $_iv = $in; + $cb = substr($_text, $_i, ' . $block_size . '); + $_plaintext.= $_iv ^ $cb; + $_iv = $cb; + $_len-= ' . $block_size . '; + $_i+= ' . $block_size . '; + } + if ($_len) { + $in = $_iv; + ' . $encrypt_block . ' + $_iv = $in; + $_plaintext.= $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); + $_pos = $_len; + } + + return $_plaintext; + '; + break; + case self::MODE_CFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $this->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_ciphertext .= ($_c = $_text[$_i] ^ $in); + $_iv = substr($_iv, 1) . $_c; + } + + if ($this->continuousBuffer) { + if ($_len >= ' . $block_size . ') { + $this->encryptIV = substr($_ciphertext, -' . $block_size . '); + } else { + $this->encryptIV = substr($this->encryptIV, $_len - ' . $block_size . ') . substr($_ciphertext, -$_len); + } + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_plaintext .= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $_text[$_i]; + } + + if ($this->continuousBuffer) { + if ($_len >= ' . $block_size . ') { + $this->decryptIV = substr($_text, -' . $block_size . '); + } else { + $this->decryptIV = substr($this->decryptIV, $_len - ' . $block_size . ') . substr($_text, -$_len); + } + } + + return $_plaintext; + '; + break; + case self::MODE_OFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $this->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_ciphertext.= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $in[0]; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $_iv; + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_plaintext.= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $in[0]; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $_iv; + } + + return $_plaintext; + '; + break; + case self::MODE_OFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::shift($_buffer["xor"], ' . $block_size . '); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_ciphertext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; + } + $_key = $_xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % ' . $block_size . ') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = \\PostSMTP\\Vendor\\phpseclib3\\Common\\Functions\\Strings::shift($_buffer["xor"], ' . $block_size . '); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_plaintext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; + } + $_key = $_xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % ' . $block_size . ') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_plaintext; + '; + break; + case self::MODE_STREAM: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + ' . $encrypt_block . ' + return $_ciphertext; + '; + $decrypt = $init_decrypt . ' + $_plaintext = ""; + ' . $decrypt_block . ' + return $_plaintext; + '; + break; + // case self::MODE_CBC: + default: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + $in = $this->encryptIV; + + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . ') ^ $in; + ' . $encrypt_block . ' + $_ciphertext.= $in; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $in; + } + + return $_ciphertext; + '; + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); + $_ciphertext_len = strlen($_text); + + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = $_block = substr($_text, $_i, ' . $block_size . '); + ' . $decrypt_block . ' + $_plaintext.= $in ^ $_iv; + $_iv = $_block; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $_iv; + } + + return $this->unpad($_plaintext); + '; + break; + } + // Before discrediting this, please read the following: + // @see https://github.com/phpseclib/phpseclib/issues/1293 + // @see https://github.com/phpseclib/phpseclib/pull/1143 + eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};'); + return \Closure::bind($func, $this, static::class); + } + /** + * Convert float to int + * + * On ARM CPUs converting floats to ints doesn't always work + * + * @param string $x + * @return int + */ + protected static function safe_intval($x) + { + if (\is_int($x)) { + return $x; + } + if (self::$use_reg_intval) { + return \PHP_INT_SIZE == 4 && \PHP_VERSION_ID >= 80100 ? \intval($x) : $x; + } + return \fmod($x, 0x80000000) & 0x7fffffff | (\fmod(\floor($x / 0x80000000), 2) & 1) << 31; + } + /** + * eval()'able string for in-line float to int + * + * @return string + */ + protected static function safe_intval_inline() + { + if (self::$use_reg_intval) { + return \PHP_INT_SIZE == 4 && \PHP_VERSION_ID >= 80100 ? 'intval(%s)' : '%s'; + } + $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; + return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; + } + /** + * Sets up GCM parameters + * + * See steps 1-2 of https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=23 + * for more info + * + */ + private function setupGCM() + { + // don't keep on re-calculating $this->h + if (!$this->h || $this->hKey != $this->key) { + $cipher = new static('ecb'); + $cipher->setKey($this->key); + $cipher->disablePadding(); + $this->h = self::$gcmField->newInteger(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::switchEndianness($cipher->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"))); + $this->hKey = $this->key; + } + if (\strlen($this->nonce) == 12) { + $this->iv = $this->nonce . "\0\0\0\1"; + } else { + $this->iv = $this->ghash(self::nullPad128($this->nonce) . \str_repeat("\0", 8) . self::len64($this->nonce)); + } + } + /** + * Performs GHASH operation + * + * See https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=20 + * for more info + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $x + * @return string + */ + private function ghash($x) + { + $h = $this->h; + $y = ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"]; + $x = \str_split($x, 16); + $n = 0; + // the switchEndianness calls are necessary because the multiplication algorithm in BinaryField/Integer + // interprets strings as polynomials in big endian order whereas in GCM they're interpreted in little + // endian order per https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=19. + // big endian order is what binary field elliptic curves use per http://www.secg.org/sec1-v2.pdf#page=18. + // we could switchEndianness here instead of in the while loop but doing so in the while loop seems like it + // might be slightly more performant + //$x = Strings::switchEndianness($x); + foreach ($x as $xn) { + $xn = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::switchEndianness($xn); + $t = $y[$n] ^ $xn; + $temp = self::$gcmField->newInteger($t); + $y[++$n] = $temp->multiply($h)->toBytes(); + $y[$n] = \substr($y[$n], 1); + } + $y[$n] = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::switchEndianness($y[$n]); + return $y[$n]; + } + /** + * Returns the bit length of a string in a packed format + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @param string $str + * @return string + */ + private static function len64($str) + { + return "\0\0\0\0" . \pack('N', 8 * \strlen($str)); + } + /** + * NULL pads a string to be a multiple of 128 + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @param string $str + * @return string + */ + protected static function nullPad128($str) + { + $len = \strlen($str); + return $str . \str_repeat("\0", 16 * \ceil($len / 16) - $len); + } + /** + * Calculates Poly1305 MAC + * + * On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation + * it takes 1.2s. + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $text + * @return string + */ + protected function poly1305($text) + { + $s = $this->poly1305Key; + // strlen($this->poly1305Key) == 32 + $r = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($s, 16); + $r = \strrev($r); + $r &= "\17���\17���\17���\17���"; + $s = \strrev($s); + $r = self::$poly1305Field->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($r, 256)); + $s = self::$poly1305Field->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($s, 256)); + $a = self::$poly1305Field->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger()); + $blocks = \str_split($text, 16); + foreach ($blocks as $block) { + $n = \strrev($block . \chr(1)); + $n = self::$poly1305Field->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($n, 256)); + $a = $a->add($n); + $a = $a->multiply($r); + } + $r = $a->toBigInteger()->add($s->toBigInteger()); + $mask = "����������������"; + return \strrev($r->toBytes()) & $mask; + } + /** + * Return the mode + * + * You can do $obj instanceof AES or whatever to get the cipher but you can't do that to get the mode + * + * @return string + */ + public function getMode() + { + return \array_flip(self::MODE_MAP)[$this->mode]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php new file mode 100644 index 0000000..a6c4e9c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php @@ -0,0 +1,55 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Traits; + +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +/** + * Fingerprint Trait for Private Keys + * + * @author Jim Wigginton + */ +trait Fingerprint +{ + /** + * Returns the public key's fingerprint + * + * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is + * no public key currently loaded, false is returned. + * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) + * + * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned + * for invalid values. + * @return mixed + */ + public function getFingerprint($algorithm = 'md5') + { + $type = self::validatePlugin('Keys', 'OpenSSH', 'savePublicKey'); + if ($type === \false) { + return \false; + } + $key = $this->toString('OpenSSH', ['binary' => \true]); + if ($key === \false) { + return \false; + } + switch ($algorithm) { + case 'sha256': + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha256'); + $base = \base64_encode($hash->hash($key)); + return \substr($base, 0, \strlen($base) - 1); + case 'md5': + return \substr(\chunk_split(\md5($key), 2, ':'), 0, -1); + default: + return \false; + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php new file mode 100644 index 0000000..3e05110 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php @@ -0,0 +1,44 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\Common\Traits; + +/** + * Password Protected Trait for Private Keys + * + * @author Jim Wigginton + */ +trait PasswordProtected +{ + /** + * Password + * + * @var string|bool + */ + private $password = \false; + /** + * Sets the password + * + * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. + * Or rather, pass in $password such that empty($password) && !is_string($password) is true. + * + * @see self::createKey() + * @see self::load() + * @param string|bool $password + */ + public function withPassword($password = \false) + { + $new = clone $this; + $new->password = $password; + return $new; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..a3f7bf4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php @@ -0,0 +1,65 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DH\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * "PKCS1" Formatted DH Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $components = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DHParameter::MAP); + if (!\is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + return $components; + } + /** + * Convert EC parameters to the appropriate format + * + * @return string + */ + public static function saveParameters(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $prime, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $base, array $options = []) + { + $params = ['prime' => $prime, 'base' => $base]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DHParameter::MAP); + return "-----BEGIN DH PARAMETERS-----\r\n" . \chunk_split(\base64_encode($params), 64) . "-----END DH PARAMETERS-----\r\n"; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..e90392e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php @@ -0,0 +1,126 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DH\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PKCS#8 Formatted DH Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'dhKeyAgreement'; + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.3.1'; + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = \false; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + $isPublic = \strpos($key, 'PUBLIC') !== \false; + $key = parent::load($key, $password); + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + switch (\true) { + case !$isPublic && $type == 'publicKey': + throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); + case $isPublic && $type == 'privateKey': + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DHParameter::MAP); + if (!\is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key[$type]); + switch (\true) { + case !isset($decoded): + case !isset($decoded[0]['content']): + case !$decoded[0]['content'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components[$type] = $decoded[0]['content']; + return $components; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Math\BigInteger $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $prime, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $base, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $publicKey, $password = '', array $options = []) + { + $params = ['prime' => $prime, 'base' => $base]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DHParameter::MAP); + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($params); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($privateKey, ['type' => \PostSMTP\Vendor\phpseclib3\File\ASN1::TYPE_INTEGER]); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $prime, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $base, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $publicKey, array $options = []) + { + $params = ['prime' => $prime, 'base' => $base]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DHParameter::MAP); + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($params); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($publicKey, ['type' => \PostSMTP\Vendor\phpseclib3\File\ASN1::TYPE_INTEGER]); + return self::wrapPublicKey($key, $params); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php new file mode 100644 index 0000000..9061774 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php @@ -0,0 +1,33 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DH; + +use PostSMTP\Vendor\phpseclib3\Crypt\DH; +/** + * DH Parameters + * + * @author Jim Wigginton + */ +class Parameters extends \PostSMTP\Vendor\phpseclib3\Crypt\DH +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + return $type::saveParameters($this->prime, $this->base, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php new file mode 100644 index 0000000..487206c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php @@ -0,0 +1,64 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DH; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\DH; +/** + * DH Private Key + * + * @author Jim Wigginton + */ +class PrivateKey extends \PostSMTP\Vendor\phpseclib3\Crypt\DH +{ + use Common\Traits\PasswordProtected; + /** + * Private Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $privateKey; + /** + * Public Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicKey; + /** + * Returns the public key + * + * @return DH\PublicKey + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + $key = $type::savePublicKey($this->prime, $this->base, $this->publicKey); + return \PostSMTP\Vendor\phpseclib3\Crypt\DH::loadFormat('PKCS8', $key); + } + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + return $type::savePrivateKey($this->prime, $this->base, $this->privateKey, $this->publicKey, $this->password, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php new file mode 100644 index 0000000..eed0b0a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php @@ -0,0 +1,44 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DH; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\DH; +/** + * DH Public Key + * + * @author Jim Wigginton + */ +class PublicKey extends \PostSMTP\Vendor\phpseclib3\Crypt\DH +{ + use Common\Traits\Fingerprint; + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + return $type::savePublicKey($this->prime, $this->base, $this->publicKey, $options); + } + /** + * Returns the public key as a BigInteger + * + * @return \phpseclib3\Math\BigInteger + */ + public function toBigInteger() + { + return $this->publicKey; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..fae259f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,102 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * OpenSSH Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\OpenSSH +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-dss']; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + if (isset($parsed['paddedKey'])) { + list($type) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ({$type} vs {$parsed['type']})"); + } + list($p, $q, $g, $y, $x, $comment) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('i5s', $parsed['paddedKey']); + return \compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + list($p, $q, $g, $y) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('iiii', $parsed['publicKey']); + $comment = $parsed['comment']; + return \compact('p', 'q', 'g', 'y', 'comment'); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + // from : + // string "ssh-dss" + // mpint p + // mpint q + // mpint g + // mpint y + $DSAPublicKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y); + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $DSAPublicKey; + } + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $DSAPublicKey = 'ssh-dss ' . \base64_encode($DSAPublicKey) . ' ' . $comment; + return $DSAPublicKey; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $x, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => \true]); + $privateKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x); + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..949b4a9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php @@ -0,0 +1,115 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PKCS#1 Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAParams::MAP); + if (\is_array($key)) { + return $key; + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAPrivateKey::MAP); + if (\is_array($key)) { + return $key; + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAPublicKey::MAP); + if (\is_array($key)) { + return $key; + } + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + /** + * Convert DSA parameters to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @return string + */ + public static function saveParameters(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g) + { + $key = ['p' => $p, 'q' => $q, 'g' => $g]; + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAParams::MAP); + return "-----BEGIN DSA PARAMETERS-----\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . "-----END DSA PARAMETERS-----\r\n"; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $x, $password = '', array $options = []) + { + $key = ['version' => 0, 'p' => $p, 'q' => $q, 'g' => $g, 'y' => $y, 'x' => $x]; + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAPrivateKey::MAP); + return self::wrapPrivateKey($key, 'DSA', $password, $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($y, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAPublicKey::MAP); + return self::wrapPublicKey($key, 'DSA'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..dd33895 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php @@ -0,0 +1,136 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PKCS#8 Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'id-dsa'; + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.10040.4.1'; + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = \false; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + $isPublic = \strpos($key, 'PUBLIC') !== \false; + $key = parent::load($key, $password); + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + switch (\true) { + case !$isPublic && $type == 'publicKey': + throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); + case $isPublic && $type == 'privateKey': + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAParams::MAP); + if (!\is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key[$type]); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + $var = $type == 'privateKey' ? 'x' : 'y'; + $components[$var] = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAPublicKey::MAP); + if (!$components[$var] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + if (isset($key['meta'])) { + $components['meta'] = $key['meta']; + } + return $components; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $x, $password = '', array $options = []) + { + $params = ['p' => $p, 'q' => $q, 'g' => $g]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAParams::MAP); + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($params); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($x, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAPublicKey::MAP); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, array $options = []) + { + $params = ['p' => $p, 'q' => $q, 'g' => $g]; + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAParams::MAP); + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($params); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($y, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DSAPublicKey::MAP); + return self::wrapPublicKey($key, $params); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..f4f5e68 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php @@ -0,0 +1,98 @@ + 160 kinda useless, hence this handlers not supporting such keys. + * + * PHP version 5 + * + * @author Jim Wigginton + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PuTTY Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PuTTY +{ + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'PostSMTP\\Vendor\\phpseclib3\\Crypt\\DSA\\Formats\\Keys\\OpenSSH'; + /** + * Algorithm Identifier + * + * @var array + */ + protected static $types = ['ssh-dss']; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + \extract($components); + unset($components['public'], $components['private']); + list($p, $q, $g, $y) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('iiii', $public); + list($x) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('i', $private); + return \compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $x, $password = \false, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + $public = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('iiii', $p, $q, $g, $y); + $private = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('i', $x); + return self::wrapPrivateKey($public, $private, 'ssh-dsa', $password, $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + return self::wrapPublicKey(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dsa'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php new file mode 100644 index 0000000..91d66ba --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php @@ -0,0 +1,78 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Raw DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @param array $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . \gettype($key)); + } + switch (\true) { + case !isset($key['p']) || !isset($key['q']) || !isset($key['g']): + case !$key['p'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + case !$key['q'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + case !$key['g'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + case !isset($key['x']) && !isset($key['y']): + case isset($key['x']) && !$key['x'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + case isset($key['y']) && !$key['y'] instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; + return \array_intersect_key($key, $options); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $x, $password = '') + { + return \compact('p', 'q', 'g', 'y', 'x'); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + return \compact('p', 'q', 'g', 'y'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php new file mode 100644 index 0000000..da205ee --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php @@ -0,0 +1,123 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * XML Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (!\class_exists('DOMDocument')) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException('The dom extension is not setup correctly on this system'); + } + $use_errors = \libxml_use_internal_errors(\true); + $dom = new \DOMDocument(); + if (\substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + \libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='{$key}']"); + if (!$temp->length) { + continue; + } + $value = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'p': + // a prime modulus meeting the [DSS] requirements + // Parameters P, Q, and G can be public and common to a group of users. They might be known + // from application context. As such, they are optional but P and Q must either both appear + // or both be absent + $components['p'] = $value; + break; + case 'q': + // an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 + $components['q'] = $value; + break; + case 'g': + // an integer with certain properties with respect to P and Q + $components['g'] = $value; + break; + case 'y': + // G**X mod P (where X is part of the private key and not made public) + $components['y'] = $value; + // the remaining options do not do anything + case 'j': + // (P - 1) / Q + // Parameter J is available for inclusion solely for efficiency as it is calculatable from + // P and Q + case 'seed': + // a DSA prime generation seed + // Parameters seed and pgenCounter are used in the DSA prime number generation algorithm + // specified in [DSS]. As such, they are optional but must either both be present or both + // be absent + case 'pgencounter': + } + } + \libxml_use_internal_errors($use_errors); + if (!isset($components['y'])) { + throw new \UnexpectedValueException('Key is missing y component'); + } + switch (\true) { + case !isset($components['p']): + case !isset($components['q']): + case !isset($components['g']): + return ['y' => $components['y']]; + } + return $components; + } + /** + * Convert a public key to the appropriate format + * + * See https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $q, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $g, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + return "\r\n" . '

        ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($p->toBytes()) . "

        \r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($q->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($g->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($y->toBytes()) . "\r\n" . '
        '; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php new file mode 100644 index 0000000..1509f00 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php @@ -0,0 +1,57 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Signature; + +use PostSMTP\Vendor\phpseclib3\File\ASN1 as Encoder; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @param string $sig + * @return array|bool + */ + public static function load($sig) + { + if (!\is_string($sig)) { + return \false; + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($sig); + if (empty($decoded)) { + return \false; + } + $components = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DssSigValue::MAP); + return $components; + } + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $r, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $s) + { + return \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(\compact('r', 's'), \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DssSigValue::MAP); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php new file mode 100644 index 0000000..b99a39d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php @@ -0,0 +1,23 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Signature; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; +/** + * Raw DSA Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Signature\Raw +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php new file mode 100644 index 0000000..5c62331 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php @@ -0,0 +1,61 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Signature; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * SSH2 Signature Handler + * + * @author Jim Wigginton + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!\is_string($sig)) { + return \false; + } + $result = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ss', $sig); + if ($result === \false) { + return \false; + } + list($type, $blob) = $result; + if ($type != 'ssh-dss' || \strlen($blob) != 40) { + return \false; + } + return ['r' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\substr($blob, 0, 20), 256), 's' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\substr($blob, 20), 256)]; + } + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $r, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $s) + { + if ($r->getLength() > 160 || $s->getLength() > 160) { + return \false; + } + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ss', 'ssh-dss', \str_pad($r->toBytes(), 20, "\0", \STR_PAD_LEFT) . \str_pad($s->toBytes(), 20, "\0", \STR_PAD_LEFT)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php new file mode 100644 index 0000000..b2d7ae6 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php @@ -0,0 +1,33 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA; + +use PostSMTP\Vendor\phpseclib3\Crypt\DSA; +/** + * DSA Parameters + * + * @author Jim Wigginton + */ +class Parameters extends \PostSMTP\Vendor\phpseclib3\Crypt\DSA +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + return $type::saveParameters($this->p, $this->q, $this->g, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php new file mode 100644 index 0000000..bae7a9c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php @@ -0,0 +1,131 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\DSA; +use PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * DSA Private Key + * + * @author Jim Wigginton + */ +class PrivateKey extends \PostSMTP\Vendor\phpseclib3\Crypt\DSA implements \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + /** + * DSA secret exponent x + * + * @var \phpseclib3\Math\BigInteger + */ + protected $x; + /** + * Returns the public key + * + * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key + * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. + * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this + * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g + * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified + * by getting a DSA PKCS8 public key: + * + * "openssl dsa -in private.dsa -pubout -outform PEM" + * + * ie. just swap out rsa with dsa in the rsa command above. + * + * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA + * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature + * without the parameters and the PKCS1 DSA public key format does not include the parameters. + * + * @see self::getPrivateKey() + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); + return \PostSMTP\Vendor\phpseclib3\Crypt\DSA::loadFormat('PKCS8', $key)->withHash($this->hash->getHash())->withSignatureFormat($this->shortFormat); + } + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return mixed + */ + public function sign($message) + { + $format = $this->sigFormat; + if (self::$engines['OpenSSL'] && \in_array($this->hash->getHash(), \openssl_get_md_methods())) { + $signature = ''; + $result = \openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); + if ($result) { + if ($this->shortFormat == 'ASN1') { + return $signature; + } + \extract(\PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Signature\ASN1::load($signature)); + return $format::save($r, $s); + } + } + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + while (\true) { + $k = \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($this->q); + $temp = $h->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + if (!$s->equals(self::$zero)) { + break; + } + } + // the following is an RFC6979 compliant implementation of deterministic DSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + return $format::save($r, $s); + } + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php new file mode 100644 index 0000000..06b035e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php @@ -0,0 +1,74 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\DSA; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\DSA; +use PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; +/** + * DSA Public Key + * + * @author Jim Wigginton + */ +class PublicKey extends \PostSMTP\Vendor\phpseclib3\Crypt\DSA implements \PostSMTP\Vendor\phpseclib3\Crypt\Common\PublicKey +{ + use Common\Traits\Fingerprint; + /** + * Verify a signature + * + * @see self::verify() + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + $format = $this->sigFormat; + $params = $format::load($signature); + if ($params === \false || \count($params) != 2) { + return \false; + } + \extract($params); + if (self::$engines['OpenSSL'] && \in_array($this->hash->getHash(), \openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? \PostSMTP\Vendor\phpseclib3\Crypt\DSA\Formats\Signature\ASN1::save($r, $s) : $signature; + $result = \openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash()); + if ($result != -1) { + return (bool) $result; + } + } + $q_1 = $this->q->subtract(self::$one); + if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) { + return \false; + } + $w = $s->modInverse($this->q); + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + list(, $u1) = $h->multiply($w)->divide($this->q); + list(, $u2) = $r->multiply($w)->divide($this->q); + $v1 = $this->g->powMod($u1, $this->p); + $v2 = $this->y->powMod($u2, $this->p); + list(, $v) = $v1->multiply($v2)->divide($this->p); + list(, $v) = $v->divide($this->q); + return $v->equals($r); + } + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php new file mode 100644 index 0000000..4f104f9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php @@ -0,0 +1,192 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Base + * + * @author Jim Wigginton + */ +abstract class Base +{ + /** + * The Order + * + * @var BigInteger + */ + protected $order; + /** + * Finite Field Integer factory + * + * @var \phpseclib3\Math\FiniteField\Integer + */ + protected $factory; + /** + * Returns a random integer + * + * @return object + */ + public function randomInteger() + { + return $this->factory->randomInteger(); + } + /** + * Converts a BigInteger to a \phpseclib3\Math\FiniteField\Integer integer + * + * @return object + */ + public function convertInteger(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + return $this->factory->newInteger($x); + } + /** + * Returns the length, in bytes, of the modulo + * + * @return integer + */ + public function getLengthInBytes() + { + return $this->factory->getLengthInBytes(); + } + /** + * Returns the length, in bits, of the modulo + * + * @return integer + */ + public function getLength() + { + return $this->factory->getLength(); + } + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d) + { + $alreadyInternal = isset($p[2]); + $r = $alreadyInternal ? [[], $p] : [[], $this->convertToInternal($p)]; + $d = $d->toBits(); + for ($i = 0; $i < \strlen($d); $i++) { + $d_i = (int) $d[$i]; + $r[1 - $d_i] = $this->addPoint($r[0], $r[1]); + $r[$d_i] = $this->doublePoint($r[$d_i]); + } + return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]); + } + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + static $one; + if (!isset($one)) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + return \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomRange($one, $this->order->subtract($one)); + } + /** + * Performs range check + */ + public function rangeCheck(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + static $zero; + if (!isset($zero)) { + $zero = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(); + } + if (!isset($this->order)) { + throw new \RuntimeException('setOrder needs to be called before this method'); + } + if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) { + throw new \RangeException('x must be between 1 and the order of the curve'); + } + } + /** + * Sets the Order + */ + public function setOrder(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $order) + { + $this->order = $order; + } + /** + * Returns the Order + * + * @return \phpseclib3\Math\BigInteger + */ + public function getOrder() + { + return $this->order; + } + /** + * Use a custom defined modular reduction function + * + * @return object + */ + public function setReduction(callable $func) + { + $this->factory->setReduction($func); + } + /** + * Returns the affine point + * + * @return object[] + */ + public function convertToAffine(array $p) + { + return $p; + } + /** + * Converts an affine point to a jacobian coordinate + * + * @return object[] + */ + public function convertToInternal(array $p) + { + return $p; + } + /** + * Negates a point + * + * @return object[] + */ + public function negatePoint(array $p) + { + $temp = [$p[0], $p[1]->negate()]; + if (isset($p[2])) { + $temp[] = $p[2]; + } + return $temp; + } + /** + * Multiply and Add Points + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $p1 = $this->convertToInternal($points[0]); + $p2 = $this->convertToInternal($points[1]); + $p1 = $this->multiplyPoint($p1, $scalars[0]); + $p2 = $this->multiplyPoint($p2, $scalars[1]); + $r = $this->addPoint($p1, $p2); + return $this->convertToAffine($r); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php new file mode 100644 index 0000000..4bb8a77 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php @@ -0,0 +1,324 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\BinaryField; +use PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer as BinaryInteger; +/** + * Curves over y^2 + x*y = x^3 + a*x^2 + b + * + * @author Jim Wigginton + */ +class Binary extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base +{ + /** + * Binary Field Integer factory + * + * @var \phpseclib3\Math\BinaryField + */ + protected $factory; + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + /** + * Base Point + * + * @var object + */ + protected $p; + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + /** + * The Order + * + * @var BigInteger + */ + protected $order; + /** + * Sets the modulo + */ + public function setModulo(...$modulo) + { + $this->modulo = $modulo; + $this->factory = new \PostSMTP\Vendor\phpseclib3\Math\BinaryField(...$modulo); + $this->one = $this->factory->newInteger("\1"); + } + /** + * Set coefficients a and b + * + * @param string $a + * @param string $b + */ + public function setCoefficients($a, $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger(\pack('H*', $a)); + $this->b = $this->factory->newInteger(\pack('H*', $b)); + } + /** + * Set x and y coordinates for the base point + * + * @param string|BinaryInteger $x + * @param string|BinaryInteger $y + */ + public function setBasePoint($x, $y) + { + switch (\true) { + case !\is_string($x) && !$x instanceof \PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\\Integer'); + case !\is_string($y) && !$y instanceof \PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [\is_string($x) ? $this->factory->newInteger(\pack('H*', $x)) : $x, \is_string($y) ? $this->factory->newInteger(\pack('H*', $y)) : $y]; + } + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p) || !\count($q)) { + if (\count($q)) { + return $q; + } + if (\count($p)) { + return $p; + } + return []; + } + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + $o1 = $z1->multiply($z1); + $b = $x2->multiply($o1); + if ($z2->equals($this->one)) { + $d = $y2->multiply($o1)->multiply($z1); + $e = $x1->add($b); + $f = $y1->add($d); + $z3 = $e->multiply($z1); + $h = $f->multiply($x2)->add($z3->multiply($y2)); + $i = $f->add($z3); + $g = $z3->multiply($z3); + $p1 = $this->a->multiply($g); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($h)); + return [$x3, $y3, $z3]; + } + $o2 = $z2->multiply($z2); + $a = $x1->multiply($o2); + $c = $y1->multiply($o2)->multiply($z2); + $d = $y2->multiply($o1)->multiply($z1); + $e = $a->add($b); + $f = $c->add($d); + $g = $e->multiply($z1); + $h = $f->multiply($x2)->add($g->multiply($y2)); + $z3 = $g->multiply($z2); + $i = $f->add($z3); + $p1 = $this->a->multiply($z3->multiply($z3)); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h)); + return [$x3, $y3, $z3]; + } + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p)) { + return []; + } + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + list($x1, $y1, $z1) = $p; + $a = $x1->multiply($x1); + $b = $a->multiply($a); + if ($z1->equals($this->one)) { + $x3 = $b->add($this->b); + $z3 = clone $x1; + $p1 = $a->add($y1)->add($z3)->multiply($this->b); + $p2 = $a->add($y1)->multiply($b); + $y3 = $p1->add($p2); + return [$x3, $y3, $z3]; + } + $c = $z1->multiply($z1); + $d = $c->multiply($c); + $x3 = $b->add($this->b->multiply($d->multiply($d))); + $z3 = $x1->multiply($c); + $p1 = $b->multiply($z3); + $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3); + $y3 = $p1->add($p2); + return [$x3, $y3, $z3]; + } + /** + * Returns the X coordinate and the derived Y coordinate + * + * Not supported because it is covered by patents. + * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html , + * + * "Due to patent issues the compressed option is disabled by default for binary curves + * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at + * compile time." + * + * @return array + */ + public function derivePoint($m) + { + throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); + } + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $lhs = $lhs->add($x->multiply($y)); + $x2 = $x->multiply($x); + $x3 = $x2->multiply($x); + $rhs = $x3->add($this->a->multiply($x2))->add($this->b); + return $lhs->equals($rhs); + } + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [$x->multiply($z2), $y->multiply($z2)->multiply($z)]; + } + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + $p[2] = clone $this->one; + $p['fresh'] = \true; + return $p; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php new file mode 100644 index 0000000..7e8102b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php @@ -0,0 +1,273 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField; +/** + * Curves over y^2 = x^3 + b + * + * @author Jim Wigginton + */ +class KoblitzPrime extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + /** + * Basis + * + * @var list + */ + protected $basis; + /** + * Beta + * + * @var PrimeField\Integer + */ + protected $beta; + // don't overwrite setCoefficients() with one that only accepts one parameter so that + // one might be able to switch between KoblitzPrime and Prime more easily (for benchmarking + // purposes). + /** + * Multiply and Add Points + * + * Uses a efficiently computable endomorphism to achieve a slight speedup + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/short.js#L219 + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + static $zero, $one, $two; + if (!isset($two)) { + $two = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(2); + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + if (!isset($this->beta)) { + // get roots + $inv = $this->one->divide($this->two)->negate(); + $s = $this->three->negate()->squareRoot()->multiply($inv); + $betas = [$inv->add($s), $inv->subtract($s)]; + $this->beta = $betas[0]->compare($betas[1]) < 0 ? $betas[0] : $betas[1]; + //echo strtoupper($this->beta->toHex(true)) . "\n"; exit; + } + if (!isset($this->basis)) { + $factory = new \PostSMTP\Vendor\phpseclib3\Math\PrimeField($this->order); + $tempOne = $factory->newInteger($one); + $tempTwo = $factory->newInteger($two); + $tempThree = $factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(3)); + $inv = $tempOne->divide($tempTwo)->negate(); + $s = $tempThree->negate()->squareRoot()->multiply($inv); + $lambdas = [$inv->add($s), $inv->subtract($s)]; + $lhs = $this->multiplyPoint($this->p, $lambdas[0])[0]; + $rhs = $this->p[0]->multiply($this->beta); + $lambda = $lhs->equals($rhs) ? $lambdas[0] : $lambdas[1]; + $this->basis = static::extendedGCD($lambda->toBigInteger(), $this->order); + ///* + foreach ($this->basis as $basis) { + echo \strtoupper($basis['a']->toHex(\true)) . "\n"; + echo \strtoupper($basis['b']->toHex(\true)) . "\n\n"; + } + exit; + //*/ + } + $npoints = $nscalars = []; + for ($i = 0; $i < \count($points); $i++) { + $p = $points[$i]; + $k = $scalars[$i]->toBigInteger(); + // begin split + list($v1, $v2) = $this->basis; + $c1 = $v2['b']->multiply($k); + list($c1, $r) = $c1->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c1 = $c1->add($one); + } + $c2 = $v1['b']->negate()->multiply($k); + list($c2, $r) = $c2->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c2 = $c2->add($one); + } + $p1 = $c1->multiply($v1['a']); + $p2 = $c2->multiply($v2['a']); + $q1 = $c1->multiply($v1['b']); + $q2 = $c2->multiply($v2['b']); + $k1 = $k->subtract($p1)->subtract($p2); + $k2 = $q1->add($q2)->negate(); + // end split + $beta = [$p[0]->multiply($this->beta), $p[1], clone $this->one]; + if (isset($p['naf'])) { + $beta['naf'] = \array_map(function ($p) { + return [$p[0]->multiply($this->beta), $p[1], clone $this->one]; + }, $p['naf']); + $beta['nafwidth'] = $p['nafwidth']; + } + if ($k1->isNegative()) { + $k1 = $k1->negate(); + $p = $this->negatePoint($p); + } + if ($k2->isNegative()) { + $k2 = $k2->negate(); + $beta = $this->negatePoint($beta); + } + $pos = 2 * $i; + $npoints[$pos] = $p; + $nscalars[$pos] = $this->factory->newInteger($k1); + $pos++; + $npoints[$pos] = $beta; + $nscalars[$pos] = $this->factory->newInteger($k2); + } + return parent::multiplyAddPoints($npoints, $nscalars); + } + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0]); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + /** + * Doubles a jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x1, $y1, $z1) = $p; + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $b->multiply($b); + $d = $x1->add($b); + $d = $d->multiply($d)->subtract($a)->subtract($c)->multiply($this->two); + $e = $this->three->multiply($a); + $f = $e->multiply($e); + $x3 = $f->subtract($this->two->multiply($d)); + $y3 = $e->multiply($d->subtract($x3))->subtract($this->eight->multiply($c)); + $z3 = $this->two->multiply($y1)->multiply($z1); + return [$x3, $y3, $z3]; + } + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x1, $y1) = $p; + $xx = $x1->multiply($x1); + $yy = $y1->multiply($y1); + $yyyy = $yy->multiply($yy); + $s = $x1->add($yy); + $s = $s->multiply($s)->subtract($xx)->subtract($yyyy)->multiply($this->two); + $m = $this->three->multiply($xx); + $t = $m->multiply($m)->subtract($this->two->multiply($s)); + $x3 = $t; + $y3 = $s->subtract($t); + $y3 = $m->multiply($y3)->subtract($this->eight->multiply($yyyy)); + $z3 = $this->two->multiply($y1); + return [$x3, $y3, $z3]; + } + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($x)->multiply($x); + $rhs = $temp->add($this->b); + return $lhs->equals($rhs); + } + /** + * Calculates the parameters needed from the Euclidean algorithm as discussed at + * http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=148 + * + * @param BigInteger $u + * @param BigInteger $v + * @return BigInteger[] + */ + protected static function extendedGCD(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $u, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $v) + { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + $zero = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(); + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + $stop = $v->bitwise_rightShift($v->getLength() >> 1); + $a1 = clone $zero; + $b1 = clone $zero; + $a2 = clone $zero; + $b2 = clone $zero; + $postGreatestIndex = 0; + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + if ($v->compare($stop) > 0) { + $a0 = $v; + $b0 = $c; + } else { + $postGreatestIndex++; + } + if ($postGreatestIndex == 1) { + $a1 = $v; + $b1 = $c->negate(); + } + if ($postGreatestIndex == 2) { + $rhs = $a0->multiply($a0)->add($b0->multiply($b0)); + $lhs = $v->multiply($v)->add($b->multiply($b)); + if ($lhs->compare($rhs) <= 0) { + $a2 = $a0; + $b2 = $b0->negate(); + } else { + $a2 = $v; + $b2 = $c->negate(); + } + break; + } + } + return [['a' => $a1, 'b' => $b1], ['a' => $a2, 'b' => $b2]]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php new file mode 100644 index 0000000..3fdba68 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php @@ -0,0 +1,246 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer as PrimeInteger; +/** + * Curves over y^2 = x^3 + a*x + x + * + * @author Jim Wigginton + */ +class Montgomery extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeField + */ + protected $factory; + /** + * Cofficient for x + * + * @var object + */ + protected $a; + /** + * Constant used for point doubling + * + * @var object + */ + protected $a24; + /** + * The Number Zero + * + * @var object + */ + protected $zero; + /** + * The Number One + * + * @var object + */ + protected $one; + /** + * Base Point + * + * @var object + */ + protected $p; + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + /** + * The Order + * + * @var BigInteger + */ + protected $order; + /** + * Sets the modulo + */ + public function setModulo(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new \PostSMTP\Vendor\phpseclib3\Math\PrimeField($modulo); + $this->zero = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger()); + $this->one = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1)); + } + /** + * Set coefficients a + */ + public function setCoefficients(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $a) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $two = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(2)); + $four = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(4)); + $this->a24 = $this->a->subtract($two)->divide($four); + } + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (\true) { + case !$x instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger && !$x instanceof \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\\Integer'); + case !$y instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger && !$y instanceof \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [$x instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger ? $this->factory->newInteger($x) : $x, $y instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger ? $this->factory->newInteger($y) : $y]; + } + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + /** + * Doubles and adds a point on a curve + * + * See https://tools.ietf.org/html/draft-ietf-tls-curve25519-01#appendix-A.1.3 + * + * @return FiniteField[][] + */ + private function doubleAndAddPoint(array $p, array $q, \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer $x1) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p) || !\count($q)) { + return []; + } + if (!isset($p[1])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); + } + list($x2, $z2) = $p; + list($x3, $z3) = $q; + $a = $x2->add($z2); + $aa = $a->multiply($a); + $b = $x2->subtract($z2); + $bb = $b->multiply($b); + $e = $aa->subtract($bb); + $c = $x3->add($z3); + $d = $x3->subtract($z3); + $da = $d->multiply($a); + $cb = $c->multiply($b); + $temp = $da->add($cb); + $x5 = $temp->multiply($temp); + $temp = $da->subtract($cb); + $z5 = $x1->multiply($temp->multiply($temp)); + $x4 = $aa->multiply($bb); + $temp = static::class == \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519::class ? $bb : $aa; + $z4 = $e->multiply($temp->add($this->a24->multiply($e))); + return [[$x4, $z4], [$x5, $z5]]; + } + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d) + { + $p1 = [$this->one, $this->zero]; + $alreadyInternal = isset($x[1]); + $p2 = $this->convertToInternal($p); + $x = $p[0]; + $b = $d->toBits(); + $b = \str_pad($b, 256, '0', \STR_PAD_LEFT); + for ($i = 0; $i < \strlen($b); $i++) { + $b_i = (int) $b[$i]; + if ($b_i) { + list($p2, $p1) = $this->doubleAndAddPoint($p2, $p1, $x); + } else { + list($p1, $p2) = $this->doubleAndAddPoint($p1, $p2, $x); + } + } + return $alreadyInternal ? $p1 : $this->convertToAffine($p1); + } + /** + * Converts an affine point to an XZ coordinate + * + * From https://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html + * + * XZ coordinates represent x y as X Z satsfying the following equations: + * + * x=X/Z + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one]; + } + if (isset($p[1])) { + return $p; + } + $p[1] = clone $this->one; + return $p; + } + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[1])) { + return $p; + } + list($x, $z) = $p; + return [$x->divide($z)]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php new file mode 100644 index 0000000..cc62458 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php @@ -0,0 +1,695 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer as PrimeInteger; +/** + * Curves over y^2 = x^3 + a*x + b + * + * @author Jim Wigginton + */ +class Prime extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeFields + */ + protected $factory; + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + /** + * Base Point + * + * @var object + */ + protected $p; + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + /** + * The number three over the specified finite field + * + * @var object + */ + protected $three; + /** + * The number four over the specified finite field + * + * @var object + */ + protected $four; + /** + * The number eight over the specified finite field + * + * @var object + */ + protected $eight; + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + /** + * The Order + * + * @var BigInteger + */ + protected $order; + /** + * Sets the modulo + */ + public function setModulo(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new \PostSMTP\Vendor\phpseclib3\Math\PrimeField($modulo); + $this->two = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(2)); + $this->three = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(3)); + // used by jacobian coordinates + $this->one = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1)); + $this->four = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(4)); + $this->eight = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(8)); + } + /** + * Set coefficients a and b + */ + public function setCoefficients(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $a, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->b = $this->factory->newInteger($b); + } + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (\true) { + case !$x instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger && !$x instanceof \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\\Integer'); + case !$y instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger && !$y instanceof \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [$x instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger ? $this->factory->newInteger($x) : $x, $y instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger ? $this->factory->newInteger($y) : $y]; + } + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + /** + * Adds two "fresh" jacobian form on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedXY(array $p, array $q) + { + list($u1, $s1) = $p; + list($u2, $s2) = $q; + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply($v->subtract($x3))->subtract($s1->multiply($h3)); + return [$x3, $y3, $h]; + } + /** + * Adds one "fresh" jacobian form on the curve + * + * The second parameter should be the "fresh" one + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedX(array $p, array $q) + { + list($u1, $s1, $z1) = $p; + list($x2, $y2) = $q; + $z12 = $z1->multiply($z1); + $u2 = $x2->multiply($z12); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply($v->subtract($x3))->subtract($s1->multiply($h3)); + $z3 = $h->multiply($z1); + return [$x3, $y3, $z3]; + } + /** + * Adds two jacobian coordinates on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPoint(array $p, array $q) + { + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + $z12 = $z1->multiply($z1); + $z22 = $z2->multiply($z2); + $u1 = $x1->multiply($z22); + $u2 = $x2->multiply($z12); + $s1 = $y1->multiply($z22->multiply($z2)); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply($v->subtract($x3))->subtract($s1->multiply($h3)); + $z3 = $h->multiply($z1)->multiply($z2); + return [$x3, $y3, $z3]; + } + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p) || !\count($q)) { + if (\count($q)) { + return $q; + } + if (\count($p)) { + return $p; + } + return []; + } + // use jacobian coordinates + if (isset($p[2]) && isset($q[2])) { + if (isset($p['fresh']) && isset($q['fresh'])) { + return $this->jacobianAddPointMixedXY($p, $q); + } + if (isset($p['fresh'])) { + return $this->jacobianAddPointMixedX($q, $p); + } + if (isset($q['fresh'])) { + return $this->jacobianAddPointMixedX($p, $q); + } + return $this->jacobianAddPoint($p, $q); + } + if (isset($p[2]) || isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); + } + if ($p[0]->equals($q[0])) { + if (!$p[1]->equals($q[1])) { + return []; + } else { + // eg. doublePoint + list($numerator, $denominator) = $this->doublePointHelper($p); + } + } else { + $numerator = $q[1]->subtract($p[1]); + $denominator = $q[0]->subtract($p[0]); + } + $slope = $numerator->divide($denominator); + $x = $slope->multiply($slope)->subtract($p[0])->subtract($q[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + return [$x, $y]; + } + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0])->add($this->a); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + /** + * Doubles a jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x, $y, $z) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $z2 = $z->multiply($z); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m2 = $this->a->multiply($z2->multiply($z2)); + $m = $m1->add($m2); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract($this->eight->multiply($y2->multiply($y2))); + $z1 = $this->two->multiply($y)->multiply($z); + return [$x1, $y1, $z1]; + } + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m = $m1->add($this->a); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract($this->eight->multiply($y2->multiply($y2))); + $z1 = $this->two->multiply($y); + return [$x1, $y1, $z1]; + } + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p)) { + return []; + } + // use jacobian coordinates + if (isset($p[2])) { + if (isset($p['fresh'])) { + return $this->jacobianDoublePointMixed($p); + } + return $this->jacobianDoublePoint($p); + } + list($numerator, $denominator) = $this->doublePointHelper($p); + $slope = $numerator->divide($denominator); + $x = $slope->multiply($slope)->subtract($p[0])->subtract($p[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + return [$x, $y]; + } + /** + * Returns the X coordinate and the derived Y coordinate + * + * @return array + */ + public function derivePoint($m) + { + $y = \ord(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($m)); + $x = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($m, 256); + $xp = $this->convertInteger($x); + switch ($y) { + case 2: + $ypn = \false; + break; + case 3: + $ypn = \true; + break; + default: + throw new \RuntimeException('Coordinate not in recognized format'); + } + $temp = $xp->multiply($this->a); + $temp = $xp->multiply($xp)->multiply($xp)->add($temp); + $temp = $temp->add($this->b); + $b = $temp->squareRoot(); + if (!$b) { + throw new \RuntimeException('Unable to derive Y coordinate'); + } + $bn = $b->isOdd(); + $yp = $ypn == $bn ? $b : $b->negate(); + return [$xp, $yp]; + } + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($this->a); + $temp = $x->multiply($x)->multiply($x)->add($temp); + $rhs = $temp->add($this->b); + return $lhs->equals($rhs); + } + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + /** + * Multiply and Add Points + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L125 + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $length = \count($points); + foreach ($points as &$point) { + $point = $this->convertToInternal($point); + } + $wnd = [$this->getNAFPoints($points[0], 7)]; + $wndWidth = [isset($points[0]['nafwidth']) ? $points[0]['nafwidth'] : 7]; + for ($i = 1; $i < $length; $i++) { + $wnd[] = $this->getNAFPoints($points[$i], 1); + $wndWidth[] = isset($points[$i]['nafwidth']) ? $points[$i]['nafwidth'] : 1; + } + $naf = []; + // comb all window NAFs + $max = 0; + for ($i = $length - 1; $i >= 1; $i -= 2) { + $a = $i - 1; + $b = $i; + if ($wndWidth[$a] != 1 || $wndWidth[$b] != 1) { + $naf[$a] = $scalars[$a]->getNAF($wndWidth[$a]); + $naf[$b] = $scalars[$b]->getNAF($wndWidth[$b]); + $max = \max(\count($naf[$a]), \count($naf[$b]), $max); + continue; + } + $comb = [ + $points[$a], + // 1 + null, + // 3 + null, + // 5 + $points[$b], + ]; + $comb[1] = $this->addPoint($points[$a], $points[$b]); + $comb[2] = $this->addPoint($points[$a], $this->negatePoint($points[$b])); + $index = [ + -3, + /* -1 -1 */ + -1, + /* -1 0 */ + -5, + /* -1 1 */ + -7, + /* 0 -1 */ + 0, + /* 0 -1 */ + 7, + /* 0 1 */ + 5, + /* 1 -1 */ + 1, + /* 1 0 */ + 3, + ]; + $jsf = self::getJSFPoints($scalars[$a], $scalars[$b]); + $max = \max(\count($jsf[0]), $max); + if ($max > 0) { + $naf[$a] = \array_fill(0, $max, 0); + $naf[$b] = \array_fill(0, $max, 0); + } else { + $naf[$a] = []; + $naf[$b] = []; + } + for ($j = 0; $j < $max; $j++) { + $ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0; + $jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0; + $naf[$a][$j] = $index[3 * ($ja + 1) + $jb + 1]; + $naf[$b][$j] = 0; + $wnd[$a] = $comb; + } + } + $acc = []; + $temp = [0, 0, 0, 0]; + for ($i = $max; $i >= 0; $i--) { + $k = 0; + while ($i >= 0) { + $zero = \true; + for ($j = 0; $j < $length; $j++) { + $temp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0; + if ($temp[$j] != 0) { + $zero = \false; + } + } + if (!$zero) { + break; + } + $k++; + $i--; + } + if ($i >= 0) { + $k++; + } + while ($k--) { + $acc = $this->doublePoint($acc); + } + if ($i < 0) { + break; + } + for ($j = 0; $j < $length; $j++) { + $z = $temp[$j]; + $p = null; + if ($z == 0) { + continue; + } + $p = $z > 0 ? $wnd[$j][$z - 1 >> 1] : $this->negatePoint($wnd[$j][-$z - 1 >> 1]); + $acc = $this->addPoint($acc, $p); + } + } + return $this->convertToAffine($acc); + } + /** + * Precomputes NAF points + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L351 + * + * @return int[] + */ + private function getNAFPoints(array $point, $wnd) + { + if (isset($point['naf'])) { + return $point['naf']; + } + $res = [$point]; + $max = (1 << $wnd) - 1; + $dbl = $max == 1 ? null : $this->doublePoint($point); + for ($i = 1; $i < $max; $i++) { + $res[] = $this->addPoint($res[$i - 1], $dbl); + } + $point['naf'] = $res; + /* + $str = ''; + foreach ($res as $re) { + $re[0] = bin2hex($re[0]->toBytes()); + $re[1] = bin2hex($re[1]->toBytes()); + $str.= " ['$re[0]', '$re[1]'],\r\n"; + } + file_put_contents('temp.txt', $str); + exit; + */ + return $res; + } + /** + * Precomputes points in Joint Sparse Form + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/utils.js#L96 + * + * @return int[] + */ + private static function getJSFPoints(\PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer $k1, \PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer $k2) + { + static $three; + if (!isset($three)) { + $three = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(3); + } + $jsf = [[], []]; + $k1 = $k1->toBigInteger(); + $k2 = $k2->toBigInteger(); + $d1 = 0; + $d2 = 0; + while ($k1->compare(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(-$d1)) > 0 || $k2->compare(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(-$d2)) > 0) { + // first phase + $m14 = $k1->testBit(0) + 2 * $k1->testBit(1); + $m14 += $d1; + $m14 &= 3; + $m24 = $k2->testBit(0) + 2 * $k2->testBit(1); + $m24 += $d2; + $m24 &= 3; + if ($m14 == 3) { + $m14 = -1; + } + if ($m24 == 3) { + $m24 = -1; + } + $u1 = 0; + if ($m14 & 1) { + // if $m14 is odd + $m8 = $k1->testBit(0) + 2 * $k1->testBit(1) + 4 * $k1->testBit(2); + $m8 += $d1; + $m8 &= 7; + $u1 = ($m8 == 3 || $m8 == 5) && $m24 == 2 ? -$m14 : $m14; + } + $jsf[0][] = $u1; + $u2 = 0; + if ($m24 & 1) { + // if $m24 is odd + $m8 = $k2->testBit(0) + 2 * $k2->testBit(1) + 4 * $k2->testBit(2); + $m8 += $d2; + $m8 &= 7; + $u2 = ($m8 == 3 || $m8 == 5) && $m14 == 2 ? -$m24 : $m24; + } + $jsf[1][] = $u2; + // second phase + if (2 * $d1 == $u1 + 1) { + $d1 = 1 - $d1; + } + if (2 * $d2 == $u2 + 1) { + $d2 = 1 - $d2; + } + $k1 = $k1->bitwise_rightShift(1); + $k2 = $k2->bitwise_rightShift(1); + } + return $jsf; + } + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [$x->multiply($z2), $y->multiply($z2)->multiply($z)]; + } + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + $p[2] = clone $this->one; + $p['fresh'] = \true; + return $p; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php new file mode 100644 index 0000000..3dbe4b9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php @@ -0,0 +1,190 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer as PrimeInteger; +/** + * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 + * + * @author Jim Wigginton + */ +class TwistedEdwards extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base +{ + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + /** + * Cofficient for x^2 + * + * @var object + */ + protected $a; + /** + * Cofficient for x^2*y^2 + * + * @var object + */ + protected $d; + /** + * Base Point + * + * @var object[] + */ + protected $p; + /** + * The number zero over the specified finite field + * + * @var object + */ + protected $zero; + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + /** + * Sets the modulo + */ + public function setModulo(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new \PostSMTP\Vendor\phpseclib3\Math\PrimeField($modulo); + $this->zero = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(0)); + $this->one = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1)); + $this->two = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(2)); + } + /** + * Set coefficients a and b + */ + public function setCoefficients(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $a, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->d = $this->factory->newInteger($d); + } + /** + * Set x and y coordinates for the base point + */ + public function setBasePoint($x, $y) + { + switch (\true) { + case !$x instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger && !$x instanceof \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\\Integer'); + case !$y instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger && !$y instanceof \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer: + throw new \UnexpectedValueException('PostSMTP\\Vendor\\Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [$x instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger ? $this->factory->newInteger($x) : $x, $y instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger ? $this->factory->newInteger($y) : $y]; + } + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getD() + { + return $this->d; + } + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + return [$x->multiply($z), $y->multiply($z)]; + } + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $lhs = $this->a->multiply($x2)->add($y2); + $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); + return $lhs->equals($rhs); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php new file mode 100644 index 0000000..6d63187 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php @@ -0,0 +1,73 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class Curve25519 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery +{ + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->a24 = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('121666')); + $this->p = [$this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(9))]; + // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + /* + $this->setCoefficients( + new BigInteger('486662'), // a + ); + $this->setBasePoint( + new BigInteger(9), + new BigInteger('14781619447589544791020593568409986887264606134616475288964881837755586237401') + ); + */ + } + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + $d = $d->toBytes(); + $d &= "�" . \str_repeat("�", 30) . ""; + $d = \strrev($d); + $d |= "@"; + $d = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($d, -256); + return parent::multiplyPoint($p, $d); + } + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return \PostSMTP\Vendor\phpseclib3\Math\BigInteger::random(256); + } + /** + * Performs range check + */ + public function rangeCheck(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + if ($x->getLength() > 256 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 256 bytes in length'); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php new file mode 100644 index 0000000..cd1e37d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php @@ -0,0 +1,76 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class Curve448 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery +{ + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->a24 = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('39081')); + $this->p = [$this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(5))]; + // 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16)); + /* + $this->setCoefficients( + new BigInteger('156326'), // a + ); + $this->setBasePoint( + new BigInteger(5), + new BigInteger( + '355293926785568175264127502063783334808976399387714271831880898' . + '435169088786967410002932673765864550910142774147268105838985595290' . + '606362') + ); + */ + } + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + $d = $d->toBytes(); + $d[0] = $d[0] & "�"; + $d = \strrev($d); + $d |= "�"; + $d = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($d, 256); + return parent::multiplyPoint($p, $d); + } + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return \PostSMTP\Vendor\phpseclib3\Math\BigInteger::random(446); + } + /** + * Performs range check + */ + public function rangeCheck(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + if ($x->getLength() > 448 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 446 bytes in length'); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php new file mode 100644 index 0000000..5d0630f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php @@ -0,0 +1,295 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class Ed25519 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards +{ + const HASH = 'sha512'; + /* + Per https://tools.ietf.org/html/rfc8032#page-6 EdDSA has several parameters, one of which is b: + + 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b + bits, and EdDSA signatures have exactly 2*b bits. b is + recommended to be a multiple of 8, so public key and signature + lengths are an integral number of octets. + + SIZE corresponds to b + */ + const SIZE = 32; + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->setCoefficients( + // -1 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC', 16), + // a + // -121665/121666 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6666666666666666666666666666666666666666666666666666666666666658', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + // algorithm 14.47 from http://cacr.uwaterloo.ca/hac/about/chap14.pdf#page=16 + /* + $this->setReduction(function($x) { + $parts = $x->bitwise_split(255); + $className = $this->className; + + if (count($parts) > 2) { + list(, $r) = $x->divide($className::$modulo); + return $r; + } + + $zero = new BigInteger(); + $c = new BigInteger(19); + + switch (count($parts)) { + case 2: + list($qi, $ri) = $parts; + break; + case 1: + $qi = $zero; + list($ri) = $parts; + break; + case 0: + return $zero; + } + $r = $ri; + + while ($qi->compare($zero) > 0) { + $temp = $qi->multiply($c)->bitwise_split(255); + if (count($temp) == 2) { + list($qi, $ri) = $temp; + } else { + $qi = $zero; + list($ri) = $temp; + } + $r = $r->add($ri); + } + + while ($r->compare($className::$modulo) > 0) { + $r = $r->subtract($className::$modulo); + } + return $r; + }); + */ + } + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.1.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->add($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + /* we don't do $x2->squareRoot() because, quoting from + https://tools.ietf.org/html/rfc8032#section-5.1.1: + + "For point decoding or "decompression", square roots modulo p are + needed. They can be computed using the Tonelli-Shanks algorithm or + the special case for p = 5 (mod 8). To find a square root of a, + first compute the candidate root x = a^((p+3)/8) (mod p)." + */ + $exp = $this->getModulo()->add(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(3)); + $exp = $exp->bitwise_rightShift(3); + $x = $x2->pow($exp); + // If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a square root. + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + $temp = $this->getModulo()->subtract(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1)); + $temp = $temp->bitwise_rightShift(2); + $temp = $this->two->pow($temp); + $x = $x->multiply($temp); + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + return [$x, $y]; + } + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.1.5 + * + * Used by the various key handlers + * + * @param string $str + * @return array + */ + public function extractSecret($str) + { + if (\strlen($str) != 32) { + throw new \LengthException('Private Key should be 32-bytes long'); + } + // 1. Hash the 32-byte private key using SHA-512, storing the digest in + // a 64-octet large buffer, denoted h. Only the lower 32 bytes are + // used for generating the public key. + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha512'); + $h = $hash->hash($str); + $h = \substr($h, 0, 32); + // 2. Prune the buffer: The lowest three bits of the first octet are + // cleared, the highest bit of the last octet is cleared, and the + // second highest bit of the last octet is set. + $h[0] = $h[0] & \chr(0xf8); + $h = \strrev($h); + $h[0] = $h[0] & \chr(0x3f) | \chr(0x40); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($h, 256); + return ['dA' => $dA, 'secret' => $str]; + } + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = $y->toBytes(); + $y[0] = $y[0] & \chr(0x7f); + if ($x->isOdd()) { + $y[0] = $y[0] | \chr(0x80); + } + $y = \strrev($y); + return $y; + } + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(\PostSMTP\Vendor\phpseclib3\Crypt\Random::string(32))['dA']; + } + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.1.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one, clone $this->zero]; + } + if (isset($p[2])) { + return $p; + } + $p[2] = clone $this->one; + $p[3] = $p[0]->multiply($p[1]); + return $p; + } + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p)) { + return []; + } + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + // from https://tools.ietf.org/html/rfc8032#page-12 + list($x1, $y1, $z1, $t1) = $p; + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $this->two->multiply($z1)->multiply($z1); + $h = $a->add($b); + $temp = $x1->add($y1); + $e = $h->subtract($temp->multiply($temp)); + $g = $a->subtract($b); + $f = $c->add($g); + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + return [$x3, $y3, $z3, $t3]; + } + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p) || !\count($q)) { + if (\count($q)) { + return $q; + } + if (\count($p)) { + return $p; + } + return []; + } + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + // from https://tools.ietf.org/html/rfc8032#page-12 + list($x1, $y1, $z1, $t1) = $p; + list($x2, $y2, $z2, $t2) = $q; + $a = $y1->subtract($x1)->multiply($y2->subtract($x2)); + $b = $y1->add($x1)->multiply($y2->add($x2)); + $c = $t1->multiply($this->two)->multiply($this->d)->multiply($t2); + $d = $z1->multiply($this->two)->multiply($z2); + $e = $b->subtract($a); + $f = $d->subtract($c); + $g = $d->add($c); + $h = $b->add($a); + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + return [$x3, $y3, $z3, $t3]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php new file mode 100644 index 0000000..50e11f1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php @@ -0,0 +1,222 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class Ed448 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards +{ + const HASH = 'shake256-912'; + const SIZE = 57; + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1), + // -39081 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324' . 'A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E' . '05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16)); + } + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.2.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->subtract($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + $exp = $this->getModulo()->add(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1)); + $exp = $exp->bitwise_rightShift(2); + $x = $x2->pow($exp); + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + return [$x, $y]; + } + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.2.5 + * + * Used by the various key handlers + * + * @param string $str + * @return array + */ + public function extractSecret($str) + { + if (\strlen($str) != 57) { + throw new \LengthException('Private Key should be 57-bytes long'); + } + // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the + // digest in a 114-octet large buffer, denoted h. Only the lower 57 + // bytes are used for generating the public key. + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('shake256-912'); + $h = $hash->hash($str); + $h = \substr($h, 0, 57); + // 2. Prune the buffer: The two least significant bits of the first + // octet are cleared, all eight bits the last octet are cleared, and + // the highest bit of the second to last octet is set. + $h[0] = $h[0] & \chr(0xfc); + $h = \strrev($h); + $h[0] = "\0"; + $h[1] = $h[1] | \chr(0x80); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($h, 256); + return ['dA' => $dA, 'secret' => $str]; + $dA->secret = $str; + return $dA; + } + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = "\0" . $y->toBytes(); + if ($x->isOdd()) { + $y[0] = $y[0] | \chr(0x80); + } + $y = \strrev($y); + return $y; + } + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(\PostSMTP\Vendor\phpseclib3\Crypt\Random::string(57))['dA']; + } + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.2.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one]; + } + if (isset($p[2])) { + return $p; + } + $p[2] = clone $this->one; + return $p; + } + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p)) { + return []; + } + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + // from https://tools.ietf.org/html/rfc8032#page-18 + list($x1, $y1, $z1) = $p; + $b = $x1->add($y1); + $b = $b->multiply($b); + $c = $x1->multiply($x1); + $d = $y1->multiply($y1); + $e = $c->add($d); + $h = $z1->multiply($z1); + $j = $e->subtract($this->two->multiply($h)); + $x3 = $b->subtract($e)->multiply($j); + $y3 = $c->subtract($d)->multiply($e); + $z3 = $e->multiply($j); + return [$x3, $y3, $z3]; + } + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + if (!\count($p) || !\count($q)) { + if (\count($q)) { + return $q; + } + if (\count($p)) { + return $p; + } + return []; + } + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + // from https://tools.ietf.org/html/rfc8032#page-17 + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + $a = $z1->multiply($z2); + $b = $a->multiply($a); + $c = $x1->multiply($x2); + $d = $y1->multiply($y2); + $e = $this->d->multiply($c)->multiply($d); + $f = $b->subtract($e); + $g = $b->add($e); + $h = $x1->add($y1)->multiply($x2->add($y2)); + $x3 = $a->multiply($f)->multiply($h->subtract($c)->subtract($d)); + $y3 = $a->multiply($g)->multiply($d->subtract($c)); + $z3 = $f->multiply($g); + return [$x3, $y3, $z3]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php new file mode 100644 index 0000000..36dcc04 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP160r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('340E7BE2A280EB74E2BE61BADA745D97E8F7C300', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('1667CB477A1A8EC338F94741669C976316DA6321', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php new file mode 100644 index 0000000..6b07ed8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php @@ -0,0 +1,43 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP160t1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620C', 16), + // eg. -3 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('B199B13B9B34EFC1397E64BAEB05ACC265FF2378', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('ADD6718B7C7C1961F0991B842443772152C9E0AD', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php new file mode 100644 index 0000000..43f6fdd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP192r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php new file mode 100644 index 0000000..d324899 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP192t1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294', 16), + // eg. -3 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php new file mode 100644 index 0000000..1fe08c8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP224r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php new file mode 100644 index 0000000..da26298 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP224t1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC', 16), + // eg. -3 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php new file mode 100644 index 0000000..0cb8851 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP256r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php new file mode 100644 index 0000000..e8a7bd1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP256t1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374', 16), + // eg. -3 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php new file mode 100644 index 0000000..50bb785 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP320r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4' . '92F375A97D860EB4', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981' . '6F5EB4AC8FB1F1A6', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7' . '10AF8D0D39E20611', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7' . 'D35245D1692E8EE1', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . '82EC7EE8658E98691555B44C59311', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php new file mode 100644 index 0000000..8b6be70 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP320t1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28' . 'FCD412B1F1B32E24', 16), + // eg. -3 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE' . 'B5B4FEF422340353', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF' . '3357F624A21BED52', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B' . '1B9BC0455FB0D2C3', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . '82EC7EE8658E98691555B44C59311', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php new file mode 100644 index 0000000..88aa453 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP384r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . '1874700133107EC53', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503' . 'AD4EB04A8C7DD22CE2826', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DB' . 'C9943AB78696FA504C11', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D' . '646AAEF87B2E247D4AF1E', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E464621779' . '1811142820341263C5315', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . '03B883202E9046565', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php new file mode 100644 index 0000000..082c914 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP384t1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . '1874700133107EC53', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901' . 'D1A71874700133107EC50', 16), + // eg. -3 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B8' . '8805CED70355A33B471EE', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946' . 'A5F54D8D0AA2F418808CC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC' . '2B2912675BF5B9E582928', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . '03B883202E9046565', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php new file mode 100644 index 0000000..c949a60 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP512r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA82' . '53AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C' . '1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D' . '0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5' . 'F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php new file mode 100644 index 0000000..ab37163 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class brainpoolP512t1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16)); + $this->setCoefficients( + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0', 16), + // eg. -3 + new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA23049' . '76540F6450085F2DAE145C22553B465763689180EA2571867423E', 16) + ); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CD' . 'B3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEE' . 'F216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php new file mode 100644 index 0000000..7106bb0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistb233 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\sect233r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php new file mode 100644 index 0000000..a76a0a0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistb409 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\sect409r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php new file mode 100644 index 0000000..154e174 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistk163 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\sect163k1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php new file mode 100644 index 0000000..30c3e3a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistk233 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\sect233k1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php new file mode 100644 index 0000000..990c6e2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistk283 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\sect283k1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php new file mode 100644 index 0000000..52aa9a1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistk409 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\sect409k1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php new file mode 100644 index 0000000..50f37fb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistp192 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp192r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php new file mode 100644 index 0000000..3ef5309 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistp224 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp224r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php new file mode 100644 index 0000000..784fb37 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistp256 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp256r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php new file mode 100644 index 0000000..5a9b65c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistp384 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp384r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php new file mode 100644 index 0000000..5364d76 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistp521 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp521r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php new file mode 100644 index 0000000..e9caf1f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class nistt571 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\sect571k1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php new file mode 100644 index 0000000..872ca19 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class prime192v1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp192r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php new file mode 100644 index 0000000..da16e16 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class prime192v2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php new file mode 100644 index 0000000..51d9800 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class prime192v3 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php new file mode 100644 index 0000000..091ca8f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class prime239v1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php new file mode 100644 index 0000000..1c59dfb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class prime239v2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php new file mode 100644 index 0000000..0c3a1e5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class prime239v3 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php new file mode 100644 index 0000000..cd7e883 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php @@ -0,0 +1,17 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +final class prime256v1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp256r1 +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php new file mode 100644 index 0000000..3ffe4b5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp112r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('DB7C2ABF62E35E668076BEAD2088', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('659EF8BA043916EEDE8911702B22', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('09487239995A5EE76B55F9C2F098', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A89CE5AF8724C0A23E0E0FF77500', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('DB7C2ABF62E35E7628DFAC6561C5', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php new file mode 100644 index 0000000..ef60acb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php @@ -0,0 +1,27 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp112r2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + // same modulo as secp112r1 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6127C24C05F38A0AAAF65C0EF02C', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('51DEF1815DB5ED74FCC34C85D709', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('4BA30AB5E892B4E1649DD0928643', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('ADCD46F5882E3747DEF36E956E97', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('36DF0AAFD8B8D7597CA10520D04B', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php new file mode 100644 index 0000000..8b9df9d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp128r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('E87579C11079F43DD824993C2CEE5ED3', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('161FF7528B899B2D0C28607CA52C5B86', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('CF5AC8395BAFEB13C02DA292DDED7A83', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFE0000000075A30D1B9038A115', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php new file mode 100644 index 0000000..5bdacb3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php @@ -0,0 +1,27 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp128r2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + // same as secp128r1 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('D6031998D1B3BBFEBF59CC9BBFF9AEE1', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('5EEEFCA380D02919DC2C6558BB6D8A5D', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7B6AA5D85E572983E6FB32A7CDEBC140', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('27B6916A894D3AEE7106FE805FC34B44', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3FFFFFFF7FFFFFFFBE0024720613B5A3', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php new file mode 100644 index 0000000..efde249 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php @@ -0,0 +1,31 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp160k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime +{ + public function __construct() + { + // same as secp160r2 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0000000000000000000000000000000000000000', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0000000000000000000000000000000000000007', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3B4C382CE37AA192A4019E763036F4F5DD4D7EBB', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('938CF935318FDCED6BC28286531733C3F03C4FEE', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0100000000000000000001B8FA16DFAB9ACA16B6B3', 16)); + $this->basis = []; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0096341F1138933BC2F505', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FF6E9D0418C67BB8D5F562', -16)]; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01BDCB3A09AAAABEAFF4A8', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('04D12329FF0EF498EA67', -16)]; + $this->beta = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('645B7345A143464942CC46D7CF4D5D1E1E6CBB68', -16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php new file mode 100644 index 0000000..466a4cf --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp160r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('4A96B5688EF573284664698968C38BB913CBFC82', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('23A628553168947D59DCC912042351377AC5FB32', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0100000000000000000001F4C8F927AED3CA752257', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php new file mode 100644 index 0000000..1059b8d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php @@ -0,0 +1,27 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp160r2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + // same as secp160k1 + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('B4E134D3FB59EB8BAB57274904664D5AF50388BA', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('52DCB034293A117E1F4FF11B30F7199D3144CE6D', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0100000000000000000000351EE786A818F3A1A16B', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php new file mode 100644 index 0000000..2fe04ec --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp192k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('000000000000000000000000000000000000000000000000', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('000000000000000000000000000000000000000000000003', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D', 16)); + $this->basis = []; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('00B3FB3400DEC5C4ADCEB8655C', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8EE96418CCF4CFC7124FDA0F', -16)]; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01D90D03E8F096B9948B20F0A9', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('42E49819ABBA9474E1083F6B', -16)]; + $this->beta = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('447A96E6C647963E2F7809FEAAB46947F34B0AA3CA0BBA74', -16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php new file mode 100644 index 0000000..2eeb092 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php @@ -0,0 +1,68 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp192r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $modulo = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16); + $this->setModulo($modulo); + // algorithm 2.27 from http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=66 + /* in theory this should be faster than regular modular reductions save for one small issue. + to convert to / from base-2**8 with BCMath you have to call bcmul() and bcdiv() a lot. + to convert to / from base-2**8 with PHP64 you have to call base256_rshift() a lot. + in short, converting to / from base-2**8 is pretty expensive and that expense is + enough to offset whatever else might be gained by a simplified reduction algorithm. + now, if PHP supported unsigned integers things might be different. no bit-shifting + would be required for the PHP engine and it'd be a lot faster. but as is, BigInteger + uses base-2**31 or base-2**26 depending on whether or not the system is has a 32-bit + or a 64-bit OS. + */ + /* + $m_length = $this->getLengthInBytes(); + $this->setReduction(function($c) use ($m_length) { + $cBytes = $c->toBytes(); + $className = $this->className; + + if (strlen($cBytes) > 2 * $m_length) { + list(, $r) = $c->divide($className::$modulo); + return $r; + } + + $c = str_pad($cBytes, 48, "\0", STR_PAD_LEFT); + $c = array_reverse(str_split($c, 8)); + + $null = "\0\0\0\0\0\0\0\0"; + $s1 = new BigInteger($c[2] . $c[1] . $c[0], 256); + $s2 = new BigInteger($null . $c[3] . $c[3], 256); + $s3 = new BigInteger($c[4] . $c[4] . $null, 256); + $s4 = new BigInteger($c[5] . $c[5] . $c[5], 256); + + $r = $s1->add($s2)->add($s3)->add($s4); + while ($r->compare($className::$modulo) >= 0) { + $r = $r->subtract($className::$modulo); + } + + return $r; + }); + */ + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php new file mode 100644 index 0000000..6967f3b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php @@ -0,0 +1,30 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp224k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('00000000000000000000000000000000000000000000000000000000', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('00000000000000000000000000000000000000000000000000000005', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7', 16)); + $this->basis = []; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('00B8ADF1378A6EB73409FA6C9C637D', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('94730F82B358A3776A826298FA6F', -16)]; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01DCE8D2EC6184CAF0A972769FCC8B', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('4D2100BA3DC75AAB747CCF355DEC', -16)]; + $this->beta = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01F178FFA4B17C89E6F73AECE2AAD57AF4C0A748B63C830947B27E04', -16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php new file mode 100644 index 0000000..2c76a0d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp224r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php new file mode 100644 index 0000000..ae6cb2f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +//use phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +//class secp256k1 extends Prime +class secp256k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0000000000000000000000000000000000000000000000000000000000000000', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0000000000000000000000000000000000000000000000000000000000000007', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16)); + $this->basis = []; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FF1BBC8129FEF177D790AB8056F5401B3D', -16)]; + $this->basis[] = ['a' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('114CA50F7A8E2F3F657C1108D9D44CFD8', -16), 'b' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16)]; + $this->beta = $this->factory->newInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE', -16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php new file mode 100644 index 0000000..de0a0e0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp256r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php new file mode 100644 index 0000000..7f2bc5c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp384r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php new file mode 100644 index 0000000..5e529f2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class secp521r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime +{ + public function __construct() + { + $this->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFF', 16)); + $this->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFC', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF1' . '09E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B50' . '3F00', 16)); + $this->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D' . '3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5' . 'BD66', 16), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E' . '662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1' . '6650', 16)); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138' . '6409', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php new file mode 100644 index 0000000..5d346b3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect113r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients('003088250CA6E7C7FE649CE85820F7', '00E8BEE4D3E2260744188BE0E9C723'); + $this->setBasePoint('009D73616F35F4AB1407D73562C10F', '00A52830277958EE84D1315ED31886'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0100000000000000D9CCEC8A39E56F', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php new file mode 100644 index 0000000..b40cb63 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect113r2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients('00689918DBEC7E5A0DD6DFC0AA55C7', '0095E9A9EC9B297BD4BF36E059184F'); + $this->setBasePoint('01A57A6A7B26CA5EF52FCDB8164797', '00B3ADC94ED1FE674C06E695BABA1D'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('010000000000000108789B2496AF93', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php new file mode 100644 index 0000000..386707a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect131r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients('07A11B09A76B562144418FF3FF8C2570B8', '0217C05610884B63B9C6C7291678F9D341'); + $this->setBasePoint('0081BAF91FDF9833C40F9C181343638399', '078C6E7EA38C001F73C8134B1B4EF9E150'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0400000000000000023123953A9464B54D', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php new file mode 100644 index 0000000..8c3e151 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect131r2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients('03E5A88919D7CAFCBF415F07C2176573B2', '04B8266A46C55657AC734CE38F018F2192'); + $this->setBasePoint('0356DCD8F2F95031AD652D23951BB366A8', '0648F06D867940A5366D9E265DE9EB240F'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('0400000000000000016954A233049BA98F', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php new file mode 100644 index 0000000..d846514 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect163k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients('000000000000000000000000000000000000000001', '000000000000000000000000000000000000000001'); + $this->setBasePoint('02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8', '0289070FB05D38FF58321F2E800536D538CCDAA3D9'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('04000000000000000000020108A2E0CC0D99F8A5EF', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php new file mode 100644 index 0000000..a3fa402 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect163r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients('07B6882CAAEFA84F9554FF8428BD88E246D2782AE2', '0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9'); + $this->setBasePoint('0369979697AB43897789566789567F787A7876A654', '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php new file mode 100644 index 0000000..45b21d2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect163r2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients('000000000000000000000000000000000000000001', '020A601907B8C953CA1481EB10512F78744A3205FD'); + $this->setBasePoint('03F0EBA16286A2D57EA0991168D4994637E8343E36', '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('040000000000000000000292FE77E70C12A4234C33', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php new file mode 100644 index 0000000..f544516 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect193r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients('0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01', '00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814'); + $this->setBasePoint('01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1', '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01000000000000000000000000C7F34A778F443ACC920EBA49', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php new file mode 100644 index 0000000..c3cc7cd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect193r2 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients('0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B', '00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE'); + $this->setBasePoint('00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F', '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('010000000000000000000000015AAB561B005413CCD4EE99D5', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php new file mode 100644 index 0000000..1da0c6d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect233k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients('000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000001'); + $this->setBasePoint('017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126', '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php new file mode 100644 index 0000000..2db0347 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect233r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients('000000000000000000000000000000000000000000000000000000000001', '0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD'); + $this->setBasePoint('00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B', '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php new file mode 100644 index 0000000..fc3cf7c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect239k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(239, 158, 0); + $this->setCoefficients('000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000001'); + $this->setBasePoint('29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC', '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php new file mode 100644 index 0000000..ab5225d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect283k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients('000000000000000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000000000000000001'); + $this->setBasePoint('0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836', '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php new file mode 100644 index 0000000..2fc8b2e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect283r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients('000000000000000000000000000000000000000000000000000000000000000000000001', '027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5'); + $this->setBasePoint('05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053', '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php new file mode 100644 index 0000000..7f6099e --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect409k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'); + $this->setBasePoint('0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746', '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F' . '83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php new file mode 100644 index 0000000..cae255a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect409r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients('00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', '0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F'); + $this->setBasePoint('015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7', '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('010000000000000000000000000000000000000000000000000001E2' . 'AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php new file mode 100644 index 0000000..ec799d7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect571k1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients('000000000000000000000000000000000000000000000000000000000000000000000000' . '000000000000000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000000000000000000' . '000000000000000000000000000000000000000000000000000000000000000000000001'); + $this->setBasePoint('026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709584' . '93B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972', '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0' . 'AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('020000000000000000000000000000000000000000000000000000000000000000000000' . '131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php new file mode 100644 index 0000000..2d98923 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php @@ -0,0 +1,26 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +class sect571r1 extends \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients('000000000000000000000000000000000000000000000000000000000000000000000000' . '000000000000000000000000000000000000000000000000000000000000000000000001', '02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD' . '8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A'); + $this->setBasePoint('0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950' . 'F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19', '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43' . 'BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B'); + $this->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'E661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47', 16)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php new file mode 100644 index 0000000..06edfad --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php @@ -0,0 +1,489 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Generic EC Key Parsing Helper functions + * + * @author Jim Wigginton + */ +trait Common +{ + /** + * Curve OIDs + * + * @var array + */ + private static $curveOIDs = []; + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = \false; + /** + * Use Named Curves + * + * @var bool + */ + private static $useNamedCurves = \true; + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (empty(self::$curveOIDs)) { + // the sec* curves are from the standards for efficient cryptography group + // sect* curves are curves over binary finite fields + // secp* curves are curves over prime finite fields + // sec*r* curves are regular curves; sec*k* curves are koblitz curves + // brainpool*r* curves are regular prime finite field curves + // brainpool*t* curves are twisted versions of the brainpool*r* curves + self::$curveOIDs = [ + 'prime192v1' => '1.2.840.10045.3.1.1', + // J.5.1, example 1 (aka secp192r1) + 'prime192v2' => '1.2.840.10045.3.1.2', + // J.5.1, example 2 + 'prime192v3' => '1.2.840.10045.3.1.3', + // J.5.1, example 3 + 'prime239v1' => '1.2.840.10045.3.1.4', + // J.5.2, example 1 + 'prime239v2' => '1.2.840.10045.3.1.5', + // J.5.2, example 2 + 'prime239v3' => '1.2.840.10045.3.1.6', + // J.5.2, example 3 + 'prime256v1' => '1.2.840.10045.3.1.7', + // J.5.3, example 1 (aka secp256r1) + // https://tools.ietf.org/html/rfc5656#section-10 + 'nistp256' => '1.2.840.10045.3.1.7', + // aka secp256r1 + 'nistp384' => '1.3.132.0.34', + // aka secp384r1 + 'nistp521' => '1.3.132.0.35', + // aka secp521r1 + 'nistk163' => '1.3.132.0.1', + // aka sect163k1 + 'nistp192' => '1.2.840.10045.3.1.1', + // aka secp192r1 + 'nistp224' => '1.3.132.0.33', + // aka secp224r1 + 'nistk233' => '1.3.132.0.26', + // aka sect233k1 + 'nistb233' => '1.3.132.0.27', + // aka sect233r1 + 'nistk283' => '1.3.132.0.16', + // aka sect283k1 + 'nistk409' => '1.3.132.0.36', + // aka sect409k1 + 'nistb409' => '1.3.132.0.37', + // aka sect409r1 + 'nistt571' => '1.3.132.0.38', + // aka sect571k1 + // from https://tools.ietf.org/html/rfc5915 + 'secp192r1' => '1.2.840.10045.3.1.1', + // aka prime192v1 + 'sect163k1' => '1.3.132.0.1', + 'sect163r2' => '1.3.132.0.15', + 'secp224r1' => '1.3.132.0.33', + 'sect233k1' => '1.3.132.0.26', + 'sect233r1' => '1.3.132.0.27', + 'secp256r1' => '1.2.840.10045.3.1.7', + // aka prime256v1 + 'sect283k1' => '1.3.132.0.16', + 'sect283r1' => '1.3.132.0.17', + 'secp384r1' => '1.3.132.0.34', + 'sect409k1' => '1.3.132.0.36', + 'sect409r1' => '1.3.132.0.37', + 'secp521r1' => '1.3.132.0.35', + 'sect571k1' => '1.3.132.0.38', + 'sect571r1' => '1.3.132.0.39', + // from http://www.secg.org/SEC2-Ver-1.0.pdf + 'secp112r1' => '1.3.132.0.6', + 'secp112r2' => '1.3.132.0.7', + 'secp128r1' => '1.3.132.0.28', + 'secp128r2' => '1.3.132.0.29', + 'secp160k1' => '1.3.132.0.9', + 'secp160r1' => '1.3.132.0.8', + 'secp160r2' => '1.3.132.0.30', + 'secp192k1' => '1.3.132.0.31', + 'secp224k1' => '1.3.132.0.32', + 'secp256k1' => '1.3.132.0.10', + 'sect113r1' => '1.3.132.0.4', + 'sect113r2' => '1.3.132.0.5', + 'sect131r1' => '1.3.132.0.22', + 'sect131r2' => '1.3.132.0.23', + 'sect163r1' => '1.3.132.0.2', + 'sect193r1' => '1.3.132.0.24', + 'sect193r2' => '1.3.132.0.25', + 'sect239k1' => '1.3.132.0.3', + // from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf#page=36 + /* + 'c2pnb163v1' => '1.2.840.10045.3.0.1', // J.4.1, example 1 + 'c2pnb163v2' => '1.2.840.10045.3.0.2', // J.4.1, example 2 + 'c2pnb163v3' => '1.2.840.10045.3.0.3', // J.4.1, example 3 + 'c2pnb172w1' => '1.2.840.10045.3.0.4', // J.4.2, example 1 + 'c2tnb191v1' => '1.2.840.10045.3.0.5', // J.4.3, example 1 + 'c2tnb191v2' => '1.2.840.10045.3.0.6', // J.4.3, example 2 + 'c2tnb191v3' => '1.2.840.10045.3.0.7', // J.4.3, example 3 + 'c2onb191v4' => '1.2.840.10045.3.0.8', // J.4.3, example 4 + 'c2onb191v5' => '1.2.840.10045.3.0.9', // J.4.3, example 5 + 'c2pnb208w1' => '1.2.840.10045.3.0.10', // J.4.4, example 1 + 'c2tnb239v1' => '1.2.840.10045.3.0.11', // J.4.5, example 1 + 'c2tnb239v2' => '1.2.840.10045.3.0.12', // J.4.5, example 2 + 'c2tnb239v3' => '1.2.840.10045.3.0.13', // J.4.5, example 3 + 'c2onb239v4' => '1.2.840.10045.3.0.14', // J.4.5, example 4 + 'c2onb239v5' => '1.2.840.10045.3.0.15', // J.4.5, example 5 + 'c2pnb272w1' => '1.2.840.10045.3.0.16', // J.4.6, example 1 + 'c2pnb304w1' => '1.2.840.10045.3.0.17', // J.4.7, example 1 + 'c2tnb359v1' => '1.2.840.10045.3.0.18', // J.4.8, example 1 + 'c2pnb368w1' => '1.2.840.10045.3.0.19', // J.4.9, example 1 + 'c2tnb431r1' => '1.2.840.10045.3.0.20', // J.4.10, example 1 + */ + // http://www.ecc-brainpool.org/download/Domain-parameters.pdf + // https://tools.ietf.org/html/rfc5639 + 'brainpoolP160r1' => '1.3.36.3.3.2.8.1.1.1', + 'brainpoolP160t1' => '1.3.36.3.3.2.8.1.1.2', + 'brainpoolP192r1' => '1.3.36.3.3.2.8.1.1.3', + 'brainpoolP192t1' => '1.3.36.3.3.2.8.1.1.4', + 'brainpoolP224r1' => '1.3.36.3.3.2.8.1.1.5', + 'brainpoolP224t1' => '1.3.36.3.3.2.8.1.1.6', + 'brainpoolP256r1' => '1.3.36.3.3.2.8.1.1.7', + 'brainpoolP256t1' => '1.3.36.3.3.2.8.1.1.8', + 'brainpoolP320r1' => '1.3.36.3.3.2.8.1.1.9', + 'brainpoolP320t1' => '1.3.36.3.3.2.8.1.1.10', + 'brainpoolP384r1' => '1.3.36.3.3.2.8.1.1.11', + 'brainpoolP384t1' => '1.3.36.3.3.2.8.1.1.12', + 'brainpoolP512r1' => '1.3.36.3.3.2.8.1.1.13', + 'brainpoolP512t1' => '1.3.36.3.3.2.8.1.1.14', + ]; + \PostSMTP\Vendor\phpseclib3\File\ASN1::loadOIDs([ + 'prime-field' => '1.2.840.10045.1.1', + 'characteristic-two-field' => '1.2.840.10045.1.2', + 'characteristic-two-basis' => '1.2.840.10045.1.2.3', + // per http://www.secg.org/SEC1-Ver-1.0.pdf#page=84, gnBasis "not used here" + 'gnBasis' => '1.2.840.10045.1.2.3.1', + // NULL + 'tpBasis' => '1.2.840.10045.1.2.3.2', + // Trinomial + 'ppBasis' => '1.2.840.10045.1.2.3.3', + ] + self::$curveOIDs); + } + } + /** + * Explicitly set the curve + * + * If the key contains an implicit curve phpseclib needs the curve + * to be explicitly provided + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + */ + public static function setImplicitCurve(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve) + { + self::$implicitCurve = $curve; + } + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param array $params + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + protected static function loadCurveByParam(array $params) + { + if (\count($params) > 1) { + throw new \RuntimeException('No parameters are present'); + } + if (isset($params['namedCurve'])) { + $curve = '\\PostSMTP\\Vendor\\phpseclib3\\Crypt\\EC\\Curves\\' . $params['namedCurve']; + if (!\class_exists($curve)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Named Curve of ' . $params['namedCurve'] . ' is not supported'); + } + return new $curve(); + } + if (isset($params['implicitCurve'])) { + if (!isset(self::$implicitCurve)) { + throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); + } + return self::$implicitCurve; + } + if (isset($params['specifiedCurve'])) { + $data = $params['specifiedCurve']; + switch ($data['fieldID']['fieldType']) { + case 'prime-field': + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime(); + $curve->setModulo($data['fieldID']['parameters']); + $curve->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($data['curve']['a'], 256), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($data['curve']['b'], 256)); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + case 'characteristic-two-field': + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary(); + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($data['fieldID']['parameters']); + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($params[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\Characteristic_two::MAP); + $modulo = [(int) $params['m']->toString()]; + switch ($params['basis']) { + case 'tpBasis': + $modulo[] = (int) $params['parameters']->toString(); + break; + case 'ppBasis': + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($params['parameters']); + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($temp[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\Pentanomial::MAP); + $modulo[] = (int) $temp['k3']->toString(); + $modulo[] = (int) $temp['k2']->toString(); + $modulo[] = (int) $temp['k1']->toString(); + } + $modulo[] = 0; + $curve->setModulo(...$modulo); + $len = \ceil($modulo[0] / 8); + $curve->setCoefficients(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($data['curve']['a']), \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($data['curve']['b'])); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); + } + } + throw new \RuntimeException('No valid parameters are present'); + } + /** + * Extract points from a string + * + * Supports both compressed and uncompressed points + * + * @param string $str + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + public static function extractPoint($str, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve) + { + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + // first step of point deciding as discussed at the following URL's: + // https://tools.ietf.org/html/rfc8032#section-5.1.3 + // https://tools.ietf.org/html/rfc8032#section-5.2.3 + $y = $str; + $y = \strrev($y); + $sign = (bool) (\ord($y[0]) & 0x80); + $y[0] = $y[0] & \chr(0x7f); + $y = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($y, 256); + if ($y->compare($curve->getModulo()) >= 0) { + throw new \RuntimeException('The Y coordinate should not be >= the modulo'); + } + $point = $curve->recoverX($y, $sign); + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, + // currently, bit strings wanting a non-zero amount of bits trimmed are not supported + if (($val = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($str)) != "\0") { + throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($val)); + } + if ($str == "\0") { + return []; + } + $keylen = \strlen($str); + $order = $curve->getLengthInBytes(); + // point compression is being used + if ($keylen == $order + 1) { + return $curve->derivePoint($str); + } + // point compression is not being used + if ($keylen == 2 * $order + 1) { + \preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); + list(, $w, $x, $y) = $matches; + if ($w != "\4") { + throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($val)); + } + $point = [$curve->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($x, 256)), $curve->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($y, 256))]; + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); + } + /** + * Encode Parameters + * + * @todo Maybe at some point this could be moved to __toString() for each of the curves? + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param bool $returnArray optional + * @param array $options optional + * @return string|false + */ + private static function encodeParameters(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, $returnArray = \false, array $options = []) + { + $useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves; + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + if ($useNamedCurves) { + if (isset(self::$curveOIDs[$name])) { + if ($reflect->isFinal()) { + $reflect = $reflect->getParentClass(); + $name = $reflect->getShortName(); + } + return $returnArray ? ['namedCurve' => $name] : \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(['namedCurve' => $name], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + } + foreach (new \DirectoryIterator(__DIR__ . '/../../Curves/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $testName = $file->getBasename('.php'); + $class = 'PostSMTP\\Vendor\\phpseclib3\\Crypt\\EC\\Curves\\' . $testName; + $reflect = new \ReflectionClass($class); + if ($reflect->isFinal()) { + continue; + } + $candidate = new $class(); + switch ($name) { + case 'Prime': + if (!$candidate instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime) { + break; + } + if (!$candidate->getModulo()->equals($curve->getModulo())) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + return $returnArray ? ['namedCurve' => $testName] : \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(['namedCurve' => $testName], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + case 'Binary': + if (!$candidate instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary) { + break; + } + if ($candidate->getModulo() != $curve->getModulo()) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + return $returnArray ? ['namedCurve' => $testName] : \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(['namedCurve' => $testName], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + } + } + } + $order = $curve->getOrder(); + // we could try to calculate the order thusly: + // https://crypto.stackexchange.com/a/27914/4520 + // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm + if (!$order) { + throw new \RuntimeException('Specified Curves need the order to be specified'); + } + $point = $curve->getBasePoint(); + $x = $point[0]->toBytes(); + $y = $point[1]->toBytes(); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime) { + /* + * valid versions are: + * + * ecdpVer1: + * - neither the curve or the base point are generated verifiably randomly. + * ecdpVer2: + * - curve and base point are generated verifiably at random and curve.seed is present + * ecdpVer3: + * - base point is generated verifiably at random but curve is not. curve.seed is present + */ + // other (optional) parameters can be calculated using the methods discused at + // https://crypto.stackexchange.com/q/28947/4520 + $data = ['version' => 'ecdpVer1', 'fieldID' => ['fieldType' => 'prime-field', 'parameters' => $curve->getModulo()], 'curve' => ['a' => $curve->getA()->toBytes(), 'b' => $curve->getB()->toBytes()], 'base' => "\4" . $x . $y, 'order' => $order]; + return $returnArray ? ['specifiedCurve' => $data] : \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(['specifiedCurve' => $data], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + } + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Binary) { + $modulo = $curve->getModulo(); + $basis = \count($modulo); + $m = \array_shift($modulo); + \array_pop($modulo); + // the last parameter should always be 0 + //rsort($modulo); + switch ($basis) { + case 3: + $basis = 'tpBasis'; + $modulo = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($modulo[0]); + break; + case 5: + $basis = 'ppBasis'; + // these should be in strictly ascending order (hence the commented out rsort above) + $modulo = ['k1' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($modulo[2]), 'k2' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($modulo[1]), 'k3' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($modulo[0])]; + $modulo = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($modulo, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\Pentanomial::MAP); + $modulo = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($modulo); + } + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(['m' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($m), 'basis' => $basis, 'parameters' => $modulo], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\Characteristic_two::MAP); + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($params); + $a = \ltrim($curve->getA()->toBytes(), "\0"); + if (!\strlen($a)) { + $a = "\0"; + } + $b = \ltrim($curve->getB()->toBytes(), "\0"); + if (!\strlen($b)) { + $b = "\0"; + } + $data = ['version' => 'ecdpVer1', 'fieldID' => ['fieldType' => 'characteristic-two-field', 'parameters' => $params], 'curve' => ['a' => $a, 'b' => $b], 'base' => "\4" . $x . $y, 'order' => $order]; + return $returnArray ? ['specifiedCurve' => $data] : \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(['specifiedCurve' => $data], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + } + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Curve cannot be serialized'); + } + /** + * Use Specified Curve + * + * A specified curve has all the coefficients, the base points, etc, explicitely included. + * A specified curve is a more verbose way of representing a curve + */ + public static function useSpecifiedCurve() + { + self::$useNamedCurves = \false; + } + /** + * Use Named Curve + * + * A named curve does not include any parameters. It is up to the EC parameters to + * know what the coefficients, the base points, etc, are from the name of the curve. + * A named curve is a more concise way of representing a curve + */ + public static function useNamedCurve() + { + self::$useNamedCurves = \true; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php new file mode 100644 index 0000000..0c52257 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php @@ -0,0 +1,155 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp256k1; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp256r1; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp384r1; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp521r1; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * JWK Formatted EC Handler + * + * @author Jim Wigginton + */ +abstract class JWK extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\JWK +{ + use Common; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + switch ($key->kty) { + case 'EC': + switch ($key->crv) { + case 'P-256': + case 'P-384': + case 'P-521': + case 'secp256k1': + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Only P-256, P-384, P-521 and secp256k1 curves are accepted (' . $key->crv . ' provided)'); + } + break; + case 'OKP': + switch ($key->crv) { + case 'Ed25519': + case 'Ed448': + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Only Ed25519 and Ed448 curves are accepted (' . $key->crv . ' provided)'); + } + break; + default: + throw new \Exception('Only EC and OKP JWK keys are supported'); + } + $curve = '\\phpseclib3\\Crypt\\EC\\Curves\\' . \str_replace('P-', 'nistp', $key->crv); + $curve = new $curve(); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + $QA = self::extractPoint(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_decode($key->x), $curve); + if (!isset($key->d)) { + return \compact('curve', 'QA'); + } + $arr = $curve->extractSecret(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_decode($key->d)); + return \compact('curve', 'QA') + $arr; + } + $QA = [$curve->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_decode($key->x), 256)), $curve->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_decode($key->y), 256))]; + if (!$curve->verifyPoint($QA)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + if (!isset($key->d)) { + return \compact('curve', 'QA'); + } + $dA = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_decode($key->d), 256); + $curve->rangeCheck($dA); + return \compact('curve', 'dA', 'QA'); + } + /** + * Returns the alias that corresponds to a curve + * + * @return string + */ + private static function getAlias(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve) + { + switch (\true) { + case $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp256r1: + return 'P-256'; + case $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp384r1: + return 'P-384'; + case $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp521r1: + return 'P-521'; + case $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\secp256k1: + return 'secp256k1'; + } + $reflect = new \ReflectionClass($curve); + $curveName = $reflect->isFinal() ? $reflect->getParentClass()->getShortName() : $reflect->getShortName(); + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException("{$curveName} is not a supported curve"); + } + /** + * Return the array superstructure for an EC public key + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return array + */ + private static function savePublicKeyHelper(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey) + { + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + return ['kty' => 'OKP', 'crv' => $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519 ? 'Ed25519' : 'Ed448', 'x' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($curve->encodePoint($publicKey))]; + } + return ['kty' => 'EC', 'crv' => self::getAlias($curve), 'x' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($publicKey[0]->toBytes()), 'y' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($publicKey[1]->toBytes())]; + } + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, array $options = []) + { + $key = self::savePublicKeyHelper($curve, $publicKey); + return self::wrapKey($key, $options); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + $key = self::savePublicKeyHelper($curve, $publicKey); + $key['d'] = $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards ? $secret : $privateKey->toBytes(); + $key['d'] = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($key['d']); + return self::wrapKey($key, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php new file mode 100644 index 0000000..25f4dca --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php @@ -0,0 +1,93 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve448; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Montgomery Curve Private Key Handler + * + * @author Jim Wigginton + */ +abstract class MontgomeryPrivate +{ + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = \true; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (\strlen($key)) { + case 32: + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519(); + break; + case 56: + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve448(); + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + $components = ['curve' => $curve]; + $components['dA'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($key, 256); + $curve->rangeCheck($components['dA']); + // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + return $components; + } + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve, array $publicKey) + { + return \strrev($publicKey[0]->toBytes()); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve, array $publicKey, $secret = null, $password = '') + { + if (!empty($password) && \is_string($password)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); + } + return $privateKey->toBytes(); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php new file mode 100644 index 0000000..e9b378b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php @@ -0,0 +1,65 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve448; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Montgomery Public Key Handler + * + * @author Jim Wigginton + */ +abstract class MontgomeryPublic +{ + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = \true; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (\strlen($key)) { + case 32: + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519(); + break; + case 56: + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve448(); + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + $components = ['curve' => $curve]; + $components['QA'] = [$components['curve']->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev($key), 256))]; + return $components; + } + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve, array $publicKey) + { + return \strrev($publicKey[0]->toBytes()); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..0ef27c6 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php @@ -0,0 +1,163 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * OpenSSH Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\OpenSSH +{ + use Common; + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519']; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + if (isset($parsed['paddedKey'])) { + $paddedKey = $parsed['paddedKey']; + list($type) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('s', $paddedKey); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ({$type} vs {$parsed['type']})"); + } + if ($type == 'ssh-ed25519') { + list(, $key, $comment) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('sss', $paddedKey); + $key = \PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\libsodium::load($key); + $key['comment'] = $comment; + return $key; + } + list($curveName, $publicKey, $privateKey, $comment) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ssis', $paddedKey); + $curve = self::loadCurveByParam(['namedCurve' => $curveName]); + $curve->rangeCheck($privateKey); + return ['curve' => $curve, 'dA' => $privateKey, 'QA' => self::extractPoint("\0{$publicKey}", $curve), 'comment' => $comment]; + } + if ($parsed['type'] == 'ssh-ed25519') { + if (\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($parsed['publicKey'], 4) != "\0\0\0 ") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519(); + $qa = self::extractPoint($parsed['publicKey'], $curve); + } else { + list($curveName, $publicKey) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ss', $parsed['publicKey']); + $curveName = '\\PostSMTP\\Vendor\\phpseclib3\\Crypt\\EC\\Curves\\' . $curveName; + $curve = new $curveName(); + $qa = self::extractPoint("\0" . $publicKey, $curve); + } + return ['curve' => $curve, 'QA' => $qa, 'comment' => $parsed['comment']]; + } + /** + * Returns the alias that corresponds to a curve + * + * @return string + */ + private static function getAlias(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve) + { + self::initialize_static_variables(); + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + $oid = self::$curveOIDs[$name]; + $aliases = \array_filter(self::$curveOIDs, function ($v) use($oid) { + return $v == $oid; + }); + $aliases = \array_keys($aliases); + for ($i = 0; $i < \count($aliases); $i++) { + if (\in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) { + $alias = $aliases[$i]; + break; + } + } + if (!isset($alias)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports'); + } + return $alias; + } + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, array $options = []) + { + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519) { + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey)); + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + $key = 'ssh-ed25519 ' . \base64_encode($key) . ' ' . $comment; + return $key; + } + $alias = self::getAlias($curve); + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points); + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + $key = 'ecdsa-sha2-' . $alias . ' ' . \base64_encode($key) . ' ' . $comment; + return $key; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519) { + if (!isset($secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (\strlen($secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + $pubKey = $curve->encodePoint($publicKey); + $publicKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ss', 'ssh-ed25519', $pubKey); + $privateKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $secret . $pubKey); + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } + $alias = self::getAlias($curve); + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => \true]); + $privateKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey); + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..da1785b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php @@ -0,0 +1,154 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * "PKCS1" (RFC5915) Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 +{ + use Common; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (\strpos($key, 'BEGIN EC PARAMETERS') && \strpos($key, 'BEGIN EC PRIVATE KEY')) { + $components = []; + \preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches); + $decoded = parent::load($matches[0], $password); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($decoded); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $ecPrivate = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECPrivateKey::MAP); + if (!\is_array($ecPrivate)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + if (isset($ecPrivate['parameters'])) { + $components['curve'] = self::loadCurveByParam($ecPrivate['parameters']); + } + \preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches); + $decoded = parent::load($matches[0], ''); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($decoded); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $ecParams = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + if (!\is_array($ecParams)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + $ecParams = self::loadCurveByParam($ecParams); + // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes + // even if the modulo is the same + if (isset($components['curve']) && self::encodeParameters($ecParams, \false, []) != self::encodeParameters($components['curve'], \false, [])) { + throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); + } + if (!isset($components['curve'])) { + $components['curve'] = $ecParams; + } + $components['dA'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($ecPrivate['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); + $components['QA'] = isset($ecPrivate['publicKey']) ? self::extractPoint($ecPrivate['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + return $components; + } + $key = parent::load($key, $password); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + if (\is_array($key)) { + return ['curve' => self::loadCurveByParam($key)]; + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECPrivateKey::MAP); + if (!\is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + if (!isset($key['parameters'])) { + throw new \RuntimeException('Key cannot be loaded without parameters'); + } + $components = []; + $components['curve'] = self::loadCurveByParam($key['parameters']); + $components['dA'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($key['privateKey'], 256); + $components['QA'] = isset($ecPrivate['publicKey']) ? self::extractPoint($ecPrivate['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + return $components; + } + /** + * Convert EC parameters to the appropriate format + * + * @return string + */ + public static function saveParameters(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $options = []) + { + self::initialize_static_variables(); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards || $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + $key = self::encodeParameters($curve, \false, $options); + return "-----BEGIN EC PARAMETERS-----\r\n" . \chunk_split(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key), 64) . "-----END EC PARAMETERS-----\r\n"; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + self::initialize_static_variables(); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards || $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('TwistedEdwards Curves are not supported'); + } + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $key = ['version' => 'ecPrivkeyVer1', 'privateKey' => $privateKey->toBytes(), 'parameters' => new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element(self::encodeParameters($curve)), 'publicKey' => "\0" . $publicKey]; + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECPrivateKey::MAP); + return self::wrapPrivateKey($key, 'EC', $password, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..266f590 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php @@ -0,0 +1,197 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed448; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PKCS#8 Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 +{ + use Common; + /** + * OID Name + * + * @var array + */ + const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448']; + /** + * OID Value + * + * @var string + */ + const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113']; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + // initialize_static_variables() is defined in both the trait and the parent class + // when it's defined in two places it's the traits one that's called + // the parent one is needed, as well, but the parent one is called by other methods + // in the parent class as needed and in the context of the parent it's the parent + // one that's called + self::initialize_static_variables(); + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + $isPublic = \strpos($key, 'PUBLIC') !== \false; + $key = parent::load($key, $password); + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + switch (\true) { + case !$isPublic && $type == 'publicKey': + throw new \UnexpectedValueException('Human readable string claims non-public key but DER encoded string claims public key'); + case $isPublic && $type == 'privateKey': + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + switch ($key[$type . 'Algorithm']['algorithm']) { + case 'id-Ed25519': + case 'id-Ed448': + return self::loadEdDSA($key); + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECParameters::MAP); + if (!$params) { + throw new \RuntimeException('PostSMTP\\Vendor\\Unable to decode the parameters using Maps\\ECParameters'); + } + $components = []; + $components['curve'] = self::loadCurveByParam($params); + if ($isPublic) { + $components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']); + return $components; + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key['privateKey']); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECPrivateKey::MAP); + if (isset($key['parameters']) && $params != $key['parameters']) { + throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); + } + $components['dA'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($key['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); + $components['QA'] = isset($key['publicKey']) ? self::extractPoint($key['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + return $components; + } + /** + * Break a public or private EdDSA key down into its constituent components + * + * @return array + */ + private static function loadEdDSA(array $key) + { + $components = []; + if (isset($key['privateKey'])) { + $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519() : new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed448(); + // 0x04 == octet string + // 0x20 == length (32 bytes) + if (\substr($key['privateKey'], 0, 2) != "\4 ") { + throw new \RuntimeException('The first two bytes of the private key field should be 0x0420'); + } + $arr = $components['curve']->extractSecret(\substr($key['privateKey'], 2)); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } + if (isset($key['publicKey'])) { + if (!isset($components['curve'])) { + $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519() : new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed448(); + } + $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); + } + if (isset($key['privateKey']) && !isset($components['QA'])) { + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + } + return $components; + } + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Montgomery Curves are not supported'); + } + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + return self::wrapPublicKey($curve->encodePoint($publicKey), null, $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519 ? 'id-Ed25519' : 'id-Ed448'); + } + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element(self::encodeParameters($curve, \false, $options)); + $key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + return self::wrapPublicKey($key, $params, 'id-ecPublicKey'); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + self::initialize_static_variables(); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Montgomery Curves are not supported'); + } + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + return self::wrapPrivateKey("\4 " . $secret, [], null, $password, $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519 ? 'id-Ed25519' : 'id-Ed448'); + } + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $params = new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element(self::encodeParameters($curve, \false, $options)); + $key = [ + 'version' => 'ecPrivkeyVer1', + 'privateKey' => $privateKey->toBytes(), + //'parameters' => $params, + 'publicKey' => "\0" . $publicKey, + ]; + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\ECPrivateKey::MAP); + return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..a7cb675 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php @@ -0,0 +1,115 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PuTTY Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PuTTY +{ + use Common; + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'PostSMTP\\Vendor\\phpseclib3\\Crypt\\EC\\Formats\\Keys\\OpenSSH'; + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519']; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + $private = $components['private']; + $temp = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $components['type']) . $components['public']); + $components = \PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\OpenSSH::load($components['type'] . ' ' . $temp . ' ' . $components['comment']); + if ($components['curve'] instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + if (\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($private, 4) != "\0\0\0 ") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + $arr = $components['curve']->extractSecret($private); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } else { + list($components['dA']) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('i', $private); + $components['curve']->rangeCheck($components['dA']); + } + return $components; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, $secret = null, $password = \false, array $options = []) + { + self::initialize_static_variables(); + $public = \explode(' ', \PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\OpenSSH::savePublicKey($curve, $publicKey)); + $name = $public[0]; + $public = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode($public[1]); + list(, $length) = \unpack('N', \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($public, 4)); + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($public, $length); + // PuTTY pads private keys with a null byte per the following: + // https://github.com/github/putty/blob/a3d14d77f566a41fc61dfdc5c2e0e384c9e6ae8b/sshecc.c#L1926 + if (!$curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + $private = $privateKey->toBytes(); + if (!(\strlen($privateKey->toBits()) & 7)) { + $private = "\0{$private}"; + } + } + $private = $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards ? \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $secret) : \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('s', $private); + return self::wrapPrivateKey($public, $private, $name, $password, $options); + } + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField[] $publicKey + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey) + { + $public = \explode(' ', \PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\OpenSSH::savePublicKey($curve, $publicKey)); + $type = $public[0]; + $public = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode($public[1]); + list(, $length) = \unpack('N', \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($public, 4)); + \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($public, $length); + return self::wrapPublicKey($public, $type); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php new file mode 100644 index 0000000..382ba24 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php @@ -0,0 +1,373 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * XML Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + use Common; + /** + * Default namespace + * + * @var string + */ + private static $namespace; + /** + * Flag for using RFC4050 syntax + * + * @var bool + */ + private static $rfc4050 = \false; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (!\class_exists('DOMDocument')) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException('The dom extension is not setup correctly on this system'); + } + $use_errors = \libxml_use_internal_errors(\true); + $temp = self::isolateNamespace($key, 'http://www.w3.org/2009/xmldsig11#'); + if ($temp) { + $key = $temp; + } + $temp = self::isolateNamespace($key, 'http://www.w3.org/2001/04/xmldsig-more#'); + if ($temp) { + $key = $temp; + } + $dom = new \DOMDocument(); + if (\substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + \libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + \libxml_use_internal_errors($use_errors); + $curve = self::loadCurveByParam($xpath); + $pubkey = self::query($xpath, 'publickey', 'Public Key is not present'); + $QA = self::query($xpath, 'ecdsakeyvalue')->length ? self::extractPointRFC4050($xpath, $curve) : self::extractPoint("\0" . $pubkey, $curve); + \libxml_use_internal_errors($use_errors); + return \compact('curve', 'QA'); + } + /** + * Case-insensitive xpath query + * + * @param \DOMXPath $xpath + * @param string $name + * @param string $error optional + * @param bool $decode optional + * @return \DOMNodeList + */ + private static function query(\DOMXPath $xpath, $name, $error = null, $decode = \true) + { + $query = '/'; + $names = \explode('/', $name); + foreach ($names as $name) { + $query .= "/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='{$name}']"; + } + $result = $xpath->query($query); + if (!isset($error)) { + return $result; + } + if (!$result->length) { + throw new \RuntimeException($error); + } + return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; + } + /** + * Finds the first element in the relevant namespace, strips the namespacing and returns the XML for that element. + * + * @param string $xml + * @param string $ns + */ + private static function isolateNamespace($xml, $ns) + { + $dom = new \DOMDocument(); + if (!$dom->loadXML($xml)) { + return \false; + } + $xpath = new \DOMXPath($dom); + $nodes = $xpath->query("//*[namespace::*[.='{$ns}'] and not(../namespace::*[.='{$ns}'])]"); + if (!$nodes->length) { + return \false; + } + $node = $nodes->item(0); + $ns_name = $node->lookupPrefix($ns); + if ($ns_name) { + $node->removeAttributeNS($ns, $ns_name); + } + return $dom->saveXML($node); + } + /** + * Decodes the value + * + * @param string $value + */ + private static function decodeValue($value) + { + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode(\str_replace(["\r", "\n", ' ', "\t"], '', $value)); + } + /** + * Extract points from an XML document + * + * @param \DOMXPath $xpath + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + private static function extractPointRFC4050(\DOMXPath $xpath, \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve) + { + $x = self::query($xpath, 'publickey/x'); + $y = self::query($xpath, 'publickey/y'); + if (!$x->length || !$x->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / X coordinate not found'); + } + if (!$y->length || !$y->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / Y coordinate not found'); + } + $point = [$curve->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($x->item(0)->getAttribute('Value'))), $curve->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($y->item(0)->getAttribute('Value')))]; + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParam(\DOMXPath $xpath) + { + $namedCurve = self::query($xpath, 'namedcurve'); + if ($namedCurve->length == 1) { + $oid = $namedCurve->item(0)->getAttribute('URN'); + $oid = \preg_replace('#[^\\d.]#', '', $oid); + $name = \array_search($oid, self::$curveOIDs); + if ($name === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Curve with OID of ' . $oid . ' is not supported'); + } + $curve = '\\PostSMTP\\Vendor\\phpseclib3\\Crypt\\EC\\Curves\\' . $name; + if (!\class_exists($curve)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Named Curve of ' . $name . ' is not supported'); + } + return new $curve(); + } + $params = self::query($xpath, 'explicitparams'); + if ($params->length) { + return self::loadCurveByParamRFC4050($xpath); + } + $params = self::query($xpath, 'ecparameters'); + if (!$params->length) { + throw new \RuntimeException('No parameters are present'); + } + $fieldTypes = ['prime-field' => ['fieldid/prime/p'], 'gnb' => ['fieldid/gnb/m'], 'tnb' => ['fieldid/tnb/k'], 'pnb' => ['fieldid/pnb/k1', 'fieldid/pnb/k2', 'fieldid/pnb/k3'], 'unknown' => []]; + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = \preg_replace('#.*/#', '', $query); + ${$param} = self::decodeValue($result->item(0)->textContent); + } + break; + } + $a = self::query($xpath, 'curve/a', 'A coefficient is not present'); + $b = self::query($xpath, 'curve/b', 'B coefficient is not present'); + $base = self::query($xpath, 'base', 'Base point is not present'); + $order = self::query($xpath, 'order', 'Order is not present'); + switch ($type) { + case 'prime-field': + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime(); + $curve->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($p, 256)); + $curve->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($a, 256), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($b, 256)); + $point = self::extractPoint("\0" . $base, $curve); + $curve->setBasePoint(...$point); + $curve->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($order, 256)); + return $curve; + case 'gnb': + case 'tnb': + case 'pnb': + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParamRFC4050(\DOMXPath $xpath) + { + $fieldTypes = ['prime-field' => ['primefieldparamstype/p'], 'unknown' => []]; + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = \preg_replace('#.*/#', '', $query); + ${$param} = $result->item(0)->textContent; + } + break; + } + $a = self::query($xpath, 'curveparamstype/a', 'A coefficient is not present', \false); + $b = self::query($xpath, 'curveparamstype/b', 'B coefficient is not present', \false); + $x = self::query($xpath, 'basepointparams/basepoint/ecpointtype/x', 'Base Point X is not present', \false); + $y = self::query($xpath, 'basepointparams/basepoint/ecpointtype/y', 'Base Point Y is not present', \false); + $order = self::query($xpath, 'order', 'Order is not present', \false); + switch ($type) { + case 'prime-field': + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Prime(); + $p = \str_replace(["\r", "\n", ' ', "\t"], '', $p); + $curve->setModulo(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($p)); + $a = \str_replace(["\r", "\n", ' ', "\t"], '', $a); + $b = \str_replace(["\r", "\n", ' ', "\t"], '', $b); + $curve->setCoefficients(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($a), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($b)); + $x = \str_replace(["\r", "\n", ' ', "\t"], '', $x); + $y = \str_replace(["\r", "\n", ' ', "\t"], '', $y); + $curve->setBasePoint(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($x), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($y)); + $order = \str_replace(["\r", "\n", ' ', "\t"], '', $order); + $curve->setOrder(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($order)); + return $curve; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + /** + * Sets the namespace. dsig11 is the most common one. + * + * Set to null to unset. Used only for creating public keys. + * + * @param string $namespace + */ + public static function setNamespace($namespace) + { + self::$namespace = $namespace; + } + /** + * Uses the XML syntax specified in https://tools.ietf.org/html/rfc4050 + */ + public static function enableRFC4050Syntax() + { + self::$rfc4050 = \true; + } + /** + * Uses the XML syntax specified in https://www.w3.org/TR/xmldsig-core/#sec-ECParameters + */ + public static function disableRFC4050Syntax() + { + self::$rfc4050 = \false; + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards || $curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + if (empty(static::$namespace)) { + $pre = $post = ''; + } else { + $pre = static::$namespace . ':'; + $post = ':' . static::$namespace; + } + if (self::$rfc4050) { + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" . self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . '<' . $pre . 'PublicKey>' . "\r\n" . '<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" . '<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" . '' . "\r\n" . ''; + } + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" . self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . '<' . $pre . 'PublicKey>' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($publicKey) . '' . "\r\n" . ''; + } + /** + * Encode Parameters + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param string $pre + * @param array $options optional + * @return string|false + */ + private static function encodeXMLParameters(\PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Base $curve, $pre, array $options = []) + { + $result = self::encodeParameters($curve, \true, $options); + if (isset($result['namedCurve'])) { + $namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />'; + return self::$rfc4050 ? '' . \str_replace('URI', 'URN', $namedCurve) . '' : $namedCurve; + } + if (self::$rfc4050) { + $xml = '<' . $pre . 'ExplicitParams>' . "\r\n" . '<' . $pre . 'FieldParams>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml .= '<' . $pre . 'PrimeFieldParamsType>' . "\r\n" . '<' . $pre . 'P>' . $temp['fieldID']['parameters'] . '' . "\r\n" . '' . "\r\n"; + $a = $curve->getA(); + $b = $curve->getB(); + list($x, $y) = $curve->getBasePoint(); + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml .= '' . "\r\n" . '<' . $pre . 'CurveParamsType>' . "\r\n" . '<' . $pre . 'A>' . $a . '' . "\r\n" . '<' . $pre . 'B>' . $b . '' . "\r\n" . '' . "\r\n" . '<' . $pre . 'BasePointParams>' . "\r\n" . '<' . $pre . 'BasePoint>' . "\r\n" . '<' . $pre . 'ECPointType>' . "\r\n" . '<' . $pre . 'X>' . $x . '' . "\r\n" . '<' . $pre . 'Y>' . $y . '' . "\r\n" . '' . "\r\n" . '' . "\r\n" . '<' . $pre . 'Order>' . $curve->getOrder() . '' . "\r\n" . '' . "\r\n" . '' . "\r\n"; + return $xml; + } + if (isset($result['specifiedCurve'])) { + $xml = '<' . $pre . 'ECParameters>' . "\r\n" . '<' . $pre . 'FieldID>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml .= '<' . $pre . 'Prime>' . "\r\n" . '<' . $pre . 'P>' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($temp['fieldID']['parameters']->toBytes()) . '' . "\r\n" . '' . "\r\n"; + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml .= '' . "\r\n" . '<' . $pre . 'Curve>' . "\r\n" . '<' . $pre . 'A>' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($temp['curve']['a']) . '' . "\r\n" . '<' . $pre . 'B>' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($temp['curve']['b']) . '' . "\r\n" . '' . "\r\n" . '<' . $pre . 'Base>' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($temp['base']) . '' . "\r\n" . '<' . $pre . 'Order>' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($temp['order']) . '' . "\r\n" . ''; + return $xml; + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php new file mode 100644 index 0000000..81ceff7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php @@ -0,0 +1,106 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * libsodium Key Handler + * + * @author Jim Wigginton + */ +abstract class libsodium +{ + use Common; + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = \true; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (\strlen($key)) { + case 32: + $public = $key; + break; + case 64: + $private = \substr($key, 0, 32); + $public = \substr($key, -32); + break; + case 96: + $public = \substr($key, -32); + if (\substr($key, 32, 32) != $public) { + throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); + } + $private = \substr($key, 0, 32); + break; + default: + throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); + } + $curve = new \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519(); + $components = ['curve' => $curve]; + if (isset($private)) { + $arr = $curve->extractSecret($private); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } + $components['QA'] = isset($public) ? self::extractPoint($public, $curve) : $curve->multiplyPoint($curve->getBasePoint(), $components['dA']); + return $components; + } + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519 $curve, array $publicKey) + { + return $curve->encodePoint($publicKey); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $privateKey, \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519 $curve, array $publicKey, $secret = null, $password = '') + { + if (!isset($secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (\strlen($secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + if (!empty($password) && \is_string($password)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException('libsodium private keys do not support encryption'); + } + return $secret . $curve->encodePoint($publicKey); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php new file mode 100644 index 0000000..20d3bbc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php @@ -0,0 +1,57 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Signature; + +use PostSMTP\Vendor\phpseclib3\File\ASN1 as Encoder; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\EcdsaSigValue; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @param string $sig + * @return array + */ + public static function load($sig) + { + if (!\is_string($sig)) { + return \false; + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($sig); + if (empty($decoded)) { + return \false; + } + $components = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\EcdsaSigValue::MAP); + return $components; + } + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $r, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $s) + { + return \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER(\compact('r', 's'), \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\EcdsaSigValue::MAP); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php new file mode 100644 index 0000000..721a2d3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php @@ -0,0 +1,23 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Signature; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; +/** + * Raw DSA Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Signature\Raw +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php new file mode 100644 index 0000000..ce79013 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php @@ -0,0 +1,83 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Signature; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * SSH2 Signature Handler + * + * @author Jim Wigginton + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!\is_string($sig)) { + return \false; + } + $result = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ss', $sig); + if ($result === \false) { + return \false; + } + list($type, $blob) = $result; + switch ($type) { + // see https://tools.ietf.org/html/rfc5656#section-3.1.2 + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + break; + default: + return \false; + } + $result = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ii', $blob); + if ($result === \false) { + return \false; + } + return ['r' => $result[0], 's' => $result[1]]; + } + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @param string $curve + * @return string + */ + public static function save(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $r, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $s, $curve) + { + switch ($curve) { + case 'secp256r1': + $curve = 'nistp256'; + break; + case 'secp384r1': + $curve = 'nistp384'; + break; + case 'secp521r1': + $curve = 'nistp521'; + break; + default: + return \false; + } + $blob = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ii', $r, $s); + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php new file mode 100644 index 0000000..cf41544 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php @@ -0,0 +1,33 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC; + +use PostSMTP\Vendor\phpseclib3\Crypt\EC; +/** + * EC Parameters + * + * @author Jim Wigginton + */ +class Parameters extends \PostSMTP\Vendor\phpseclib3\Crypt\EC +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + return $type::saveParameters($this->curve, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php new file mode 100644 index 0000000..e3ade85 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php @@ -0,0 +1,226 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\EC; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedOperationException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * EC Private Key + * + * @author Jim Wigginton + */ +class PrivateKey extends \PostSMTP\Vendor\phpseclib3\Crypt\EC implements \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + /** + * Private Key dA + * + * sign() converts this to a BigInteger so one might wonder why this is a FiniteFieldInteger instead of + * a BigInteger. That's because a FiniteFieldInteger, when converted to a byte string, is null padded by + * a certain amount whereas a BigInteger isn't. + * + * @var object + */ + protected $dA; + /** + * @var string + */ + protected $secret; + /** + * Multiplies an encoded point by the private key + * + * Used by ECDH + * + * @param string $coordinates + * @return string + */ + public function multiply($coordinates) + { + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Curve25519 && self::$engines['libsodium']) { + return \sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates); + } + $point = [$this->curve->convertInteger(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev($coordinates), 256))]; + $point = $this->curve->multiplyPoint($point, $this->dA); + return \strrev($point[0]->toBytes(\true)); + } + if (!$this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + $coordinates = "\0{$coordinates}"; + } + $point = \PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\PKCS1::extractPoint($coordinates, $this->curve); + $point = $this->curve->multiplyPoint($point, $this->dA); + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + return $this->curve->encodePoint($point); + } + if (empty($point)) { + throw new \RuntimeException('The infinity point is invalid'); + } + return "\4" . $point[0]->toBytes(\true) . $point[1]->toBytes(\true); + } + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return mixed + */ + public function sign($message) + { + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + $dA = $this->dA; + $order = $this->curve->getOrder(); + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === \false) { + return \false; + } + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + $result = \sodium_crypto_sign_detached($message, $this->withPassword()->toString('libsodium')); + return $shortFormat == 'SSH2' ? \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ss', 'ssh-' . \strtolower($this->getCurve()), $result) : $result; + } + // contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not. + // quoting https://tools.ietf.org/html/rfc8032#section-8.5 , + // "The Ed25519ph and Ed448ph variants ... SHOULD NOT be used" + $A = $this->curve->encodePoint($this->QA); + $curve = $this->curve; + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash($curve::HASH); + $secret = \substr($hash->hash($this->secret), $curve::SIZE); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519) { + $dom = !isset($this->context) ? '' : 'SigEd25519 no Ed25519 collisions' . "\0" . \chr(\strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom = 'SigEd448' . "\0" . \chr(\strlen($context)) . $context; + } + // SHA-512(dom2(F, C) || prefix || PH(M)) + $r = $hash->hash($dom . $secret . $message); + $r = \strrev($r); + $r = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($r, 256); + list(, $r) = $r->divide($order); + $R = $curve->multiplyPoint($curve->getBasePoint(), $r); + $R = $curve->encodePoint($R); + $k = $hash->hash($dom . $R . $A . $message); + $k = \strrev($k); + $k = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($k, 256); + list(, $k) = $k->divide($order); + $S = $k->multiply($dA)->add($r); + list(, $S) = $S->divide($order); + $S = \str_pad(\strrev($S->toBytes()), $curve::SIZE, "\0"); + return $shortFormat == 'SSH2' ? \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ss', 'ssh-' . \strtolower($this->getCurve()), $R . $S) : $R . $S; + } + if (self::$engines['OpenSSL'] && \in_array($this->hash->getHash(), \openssl_get_md_methods())) { + $signature = ''; + // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long + // supported signing / verification + // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; + // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even + // has curve-specific optimizations + $result = \openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => \false]), $this->hash->getHash()); + if ($result) { + if ($shortFormat == 'ASN1') { + return $signature; + } + \extract(\PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Signature\ASN1::load($signature)); + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + } + $e = $this->hash->hash($message); + $e = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($e, 256); + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + while (\true) { + $k = \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomRange(self::$one, $order->subtract(self::$one)); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($order); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($order); + $temp = $z->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($order); + if (!$s->equals(self::$zero)) { + break; + } + } + // the following is an RFC6979 compliant implementation of deterministic ECDSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + // if this were actually being used it'd probably be better if this lived in load() and createKey() + $this->q = $this->curve->getOrder(); + $dA = $this->dA->toBigInteger(); + $this->x = $dA; + + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->secret, $this->password, $options); + } + /** + * Returns the public key + * + * @see self::getPrivateKey() + * @return mixed + */ + public function getPublicKey() + { + $format = 'PKCS8'; + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + $format = 'MontgomeryPublic'; + } + $type = self::validatePlugin('Keys', $format, 'savePublicKey'); + $key = $type::savePublicKey($this->curve, $this->QA); + $key = \PostSMTP\Vendor\phpseclib3\Crypt\EC::loadFormat($format, $key); + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + return $key; + } + $key = $key->withHash($this->hash->getHash())->withSignatureFormat($this->shortFormat); + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + $key = $key->withContext($this->context); + } + return $key; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php new file mode 100644 index 0000000..fc69757 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php @@ -0,0 +1,136 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\EC; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\EC; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedOperationException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * EC Public Key + * + * @author Jim Wigginton + */ +class PublicKey extends \PostSMTP\Vendor\phpseclib3\Crypt\EC implements \PostSMTP\Vendor\phpseclib3\Crypt\Common\PublicKey +{ + use Common\Traits\Fingerprint; + /** + * Verify a signature + * + * @see self::verify() + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\Montgomery) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === \false) { + return \false; + } + $order = $this->curve->getOrder(); + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards) { + if ($shortFormat == 'SSH2') { + list(, $signature) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ss', $signature); + } + if ($this->curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + return \sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium')); + } + $curve = $this->curve; + if (\strlen($signature) != 2 * $curve::SIZE) { + return \false; + } + $R = \substr($signature, 0, $curve::SIZE); + $S = \substr($signature, $curve::SIZE); + try { + $R = \PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Keys\PKCS1::extractPoint($R, $curve); + $R = $this->curve->convertToInternal($R); + } catch (\Exception $e) { + return \false; + } + $S = \strrev($S); + $S = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($S, 256); + if ($S->compare($order) >= 0) { + return \false; + } + $A = $curve->encodePoint($this->QA); + if ($curve instanceof \PostSMTP\Vendor\phpseclib3\Crypt\EC\Curves\Ed25519) { + $dom2 = !isset($this->context) ? '' : 'SigEd25519 no Ed25519 collisions' . "\0" . \chr(\strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom2 = 'SigEd448' . "\0" . \chr(\strlen($context)) . $context; + } + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash($curve::HASH); + $k = $hash->hash($dom2 . \substr($signature, 0, $curve::SIZE) . $A . $message); + $k = \strrev($k); + $k = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($k, 256); + list(, $k) = $k->divide($order); + $qa = $curve->convertToInternal($this->QA); + $lhs = $curve->multiplyPoint($curve->getBasePoint(), $S); + $rhs = $curve->multiplyPoint($qa, $k); + $rhs = $curve->addPoint($rhs, $R); + $rhs = $curve->convertToAffine($rhs); + return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]); + } + $params = $format::load($signature); + if ($params === \false || \count($params) != 2) { + return \false; + } + \extract($params); + if (self::$engines['OpenSSL'] && \in_array($this->hash->getHash(), \openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? \PostSMTP\Vendor\phpseclib3\Crypt\EC\Formats\Signature\ASN1::save($r, $s) : $signature; + $result = \openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => \false]), $this->hash->getHash()); + if ($result != -1) { + return (bool) $result; + } + } + $n_1 = $order->subtract(self::$one); + if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) { + return \false; + } + $e = $this->hash->hash($message); + $e = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($e, 256); + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + $w = $s->modInverse($order); + list(, $u1) = $z->multiply($w)->divide($order); + list(, $u2) = $r->multiply($w)->divide($order); + $u1 = $this->curve->convertInteger($u1); + $u2 = $this->curve->convertInteger($u2); + list($x1, $y1) = $this->curve->multiplyAddPoints([$this->curve->getBasePoint(), $this->QA], [$u1, $u2]); + $x1 = $x1->toBigInteger(); + list(, $x1) = $x1->divide($order); + return $x1->equals($r); + } + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + return $type::savePublicKey($this->curve, $this->QA, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA.php new file mode 100644 index 0000000..cb4ceb0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -0,0 +1,815 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $ciphertext = $public->encrypt($plaintext); + * + * echo $private->decrypt($ciphertext); + * ?> + * + * + * Here's an example of how to create signatures and verify signatures with this library: + * + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * One thing to consider when using this: so phpseclib uses PSS mode by default. + * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So + * should phpseclib save to the id-RSASSA-PSS format by default or the + * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better + * because SSH doesn't use PSS and idk how many SSH servers would be able to + * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS + * format is used by default (unless you change it up to use PKCS1 instead) + * + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common\AsymmetricKey; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA\PrivateKey; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA\PublicKey; +use PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Pure-PHP PKCS#1 compliant implementation of RSA. + * + * @author Jim Wigginton + */ +abstract class RSA extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'RSA'; + /** + * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} + * (OAEP) for encryption / decryption. + * + * Uses sha256 by default + * + * @see self::setHash() + * @see self::setMGFHash() + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_OAEP = 1; + /** + * Use PKCS#1 padding. + * + * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards + * compatibility with protocols (like SSH-1) written before OAEP's introduction. + * + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_PKCS1 = 2; + /** + * Do not use any padding + * + * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy + * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. + * + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_NONE = 4; + /** + * Use the Probabilistic Signature Scheme for signing + * + * Uses sha256 and 0 as the salt length + * + * @see self::setSaltLength() + * @see self::setMGFHash() + * @see self::setHash() + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_PSS = 16; + /** + * Use a relaxed version of PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_RELAXED_PKCS1 = 32; + /** + * Use PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_PKCS1 = 64; + /** + * Encryption padding mode + * + * @var int + */ + protected $encryptionPadding = self::ENCRYPTION_OAEP; + /** + * Signature padding mode + * + * @var int + */ + protected $signaturePadding = self::SIGNATURE_PSS; + /** + * Length of hash function output + * + * @var int + */ + protected $hLen; + /** + * Length of salt + * + * @var int + */ + protected $sLen; + /** + * Label + * + * @var string + */ + protected $label = ''; + /** + * Hash function for the Mask Generation Function + * + * @var \phpseclib3\Crypt\Hash + */ + protected $mgfHash; + /** + * Length of MGF hash function output + * + * @var int + */ + protected $mgfHLen; + /** + * Modulus (ie. n) + * + * @var \phpseclib3\Math\BigInteger + */ + protected $modulus; + /** + * Modulus length + * + * @var \phpseclib3\Math\BigInteger + */ + protected $k; + /** + * Exponent (ie. e or d) + * + * @var \phpseclib3\Math\BigInteger + */ + protected $exponent; + /** + * Default public exponent + * + * @var int + * @link http://en.wikipedia.org/wiki/65537_%28number%29 + */ + private static $defaultExponent = 65537; + /** + * Enable Blinding? + * + * @var bool + */ + protected static $enableBlinding = \true; + /** + * OpenSSL configuration file name. + * + * @see self::createKey() + * @var ?string + */ + protected static $configFile; + /** + * Smallest Prime + * + * Per , this number ought not result in primes smaller + * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime + * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if + * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is + * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's + * a chance neither gmp nor OpenSSL are installed) + * + * @var int + */ + private static $smallestPrime = 4096; + /** + * Public Exponent + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicExponent; + /** + * Sets the public exponent for key generation + * + * This will be 65537 unless changed. + * + * @param int $val + */ + public static function setExponent($val) + { + self::$defaultExponent = $val; + } + /** + * Sets the smallest prime number in bits. Used for key generation + * + * This will be 4096 unless changed. + * + * @param int $val + */ + public static function setSmallestPrime($val) + { + self::$smallestPrime = $val; + } + /** + * Sets the OpenSSL config file path + * + * Set to the empty string to use the default config file + * + * @param string $val + */ + public static function setOpenSSLConfigPath($val) + { + self::$configFile = $val; + } + /** + * Create a private key + * + * The public key can be extracted from the private key + * + * @return RSA\PrivateKey + * @param int $bits + */ + public static function createKey($bits = 2048) + { + self::initialize_static_variables(); + $regSize = $bits >> 1; + // divide by two to see how many bits P and Q would be + if ($regSize > self::$smallestPrime) { + $num_primes = \floor($bits / self::$smallestPrime); + $regSize = self::$smallestPrime; + } else { + $num_primes = 2; + } + if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum + if (self::$engines['OpenSSL']) { + $config = []; + if (self::$configFile) { + $config['config'] = self::$configFile; + } + $rsa = \openssl_pkey_new(['private_key_bits' => $bits] + $config); + \openssl_pkey_export($rsa, $privatekeystr, null, $config); + // clear the buffer of error strings stemming from a minimalistic openssl.cnf + while (\openssl_error_string() !== \false) { + } + return \PostSMTP\Vendor\phpseclib3\Crypt\RSA::load($privatekeystr); + } + } + static $e; + if (!isset($e)) { + $e = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(self::$defaultExponent); + } + $n = clone self::$one; + $exponents = $coefficients = $primes = []; + $lcm = ['top' => clone self::$one, 'bottom' => \false]; + do { + for ($i = 1; $i <= $num_primes; $i++) { + if ($i != $num_primes) { + $primes[$i] = \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomPrime($regSize); + } else { + \extract(\PostSMTP\Vendor\phpseclib3\Math\BigInteger::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + list($min) = $min->divide($n); + $min = $min->add(self::$one); + list($max) = $max->divide($n); + $primes[$i] = \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomRangePrime($min, $max); + } + // the first coefficient is calculated differently from the rest + // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1]) + if ($i > 2) { + $coefficients[$i] = $n->modInverse($primes[$i]); + } + $n = $n->multiply($primes[$i]); + $temp = $primes[$i]->subtract(self::$one); + // textbook RSA implementations use Euler's totient function instead of the least common multiple. + // see http://en.wikipedia.org/wiki/Euler%27s_totient_function + $lcm['top'] = $lcm['top']->multiply($temp); + $lcm['bottom'] = $lcm['bottom'] === \false ? $temp : $lcm['bottom']->gcd($temp); + } + list($temp) = $lcm['top']->divide($lcm['bottom']); + $gcd = $temp->gcd($e); + $i0 = 1; + } while (!$gcd->equals(self::$one)); + $coefficients[2] = $primes[2]->modInverse($primes[1]); + $d = $e->modInverse($temp); + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $e->modInverse($temp); + } + // from : + // RSAPrivateKey ::= SEQUENCE { + // version Version, + // modulus INTEGER, -- n + // publicExponent INTEGER, -- e + // privateExponent INTEGER, -- d + // prime1 INTEGER, -- p + // prime2 INTEGER, -- q + // exponent1 INTEGER, -- d mod (p-1) + // exponent2 INTEGER, -- d mod (q-1) + // coefficient INTEGER, -- (inverse of q) mod p + // otherPrimeInfos OtherPrimeInfos OPTIONAL + // } + $privatekey = new \PostSMTP\Vendor\phpseclib3\Crypt\RSA\PrivateKey(); + $privatekey->modulus = $n; + $privatekey->k = $bits >> 3; + $privatekey->publicExponent = $e; + $privatekey->exponent = $d; + $privatekey->primes = $primes; + $privatekey->exponents = $exponents; + $privatekey->coefficients = $coefficients; + /* + $publickey = new PublicKey; + $publickey->modulus = $n; + $publickey->k = $bits >> 3; + $publickey->exponent = $e; + $publickey->publicExponent = $e; + $publickey->isPublic = true; + */ + return $privatekey; + } + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + $key = $components['isPublicKey'] ? new \PostSMTP\Vendor\phpseclib3\Crypt\RSA\PublicKey() : new \PostSMTP\Vendor\phpseclib3\Crypt\RSA\PrivateKey(); + $key->modulus = $components['modulus']; + $key->publicExponent = $components['publicExponent']; + $key->k = $key->modulus->getLengthInBytes(); + if ($components['isPublicKey'] || !isset($components['privateExponent'])) { + $key->exponent = $key->publicExponent; + } else { + $key->privateExponent = $components['privateExponent']; + $key->exponent = $key->privateExponent; + $key->primes = $components['primes']; + $key->exponents = $components['exponents']; + $key->coefficients = $components['coefficients']; + } + if ($components['format'] == \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PSS::class) { + // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is + // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib + // uses PSS padding by default. it assumes the more secure method by default and altho it provides + // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent + // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that + // not only does it defaults to the most secure methods - it doesn't even let you choose less + // secure methods + //$key = $key->withPadding(self::SIGNATURE_PSS); + if (isset($components['hash'])) { + $key = $key->withHash($components['hash']); + } + if (isset($components['MGFHash'])) { + $key = $key->withMGFHash($components['MGFHash']); + } + if (isset($components['saltLength'])) { + $key = $key->withSaltLength($components['saltLength']); + } + } + return $key; + } + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$configFile)) { + self::$configFile = \dirname(__FILE__) . '/../openssl.cnf'; + } + parent::initialize_static_variables(); + } + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + parent::__construct(); + $this->hLen = $this->hash->getLengthInBytes(); + $this->mgfHash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash('sha256'); + $this->mgfHLen = $this->mgfHash->getLengthInBytes(); + } + /** + * Integer-to-Octet-String primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. + * + * @param bool|\phpseclib3\Math\BigInteger $x + * @param int $xLen + * @return bool|string + */ + protected function i2osp($x, $xLen) + { + if ($x === \false) { + return \false; + } + $x = $x->toBytes(); + if (\strlen($x) > $xLen) { + throw new \OutOfRangeException('Resultant string length out of range'); + } + return \str_pad($x, $xLen, \chr(0), \STR_PAD_LEFT); + } + /** + * Octet-String-to-Integer primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. + * + * @param string $x + * @return \phpseclib3\Math\BigInteger + */ + protected function os2ip($x) + { + return new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($x, 256); + } + /** + * EMSA-PKCS1-V1_5-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. + * + * @param string $m + * @param int $emLen + * @throws \LengthException if the intended encoded message length is too short + * @return string + */ + protected function emsa_pkcs1_v1_5_encode($m, $emLen) + { + $h = $this->hash->hash($m); + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hash->getHash()) { + case 'md2': + $t = "0 0\f\6\10*�H��\r\2\2\5\0\4\20"; + break; + case 'md5': + $t = "0 0\f\6\10*�H��\r\2\5\5\0\4\20"; + break; + case 'sha1': + $t = "0!0\t\6\5+\16\3\2\32\5\0\4\24"; + break; + case 'sha256': + $t = "010\r\6\t`�H\1e\3\4\2\1\5\0\4 "; + break; + case 'sha384': + $t = "0A0\r\6\t`�H\1e\3\4\2\2\5\0\0040"; + break; + case 'sha512': + $t = "0Q0\r\6\t`�H\1e\3\4\2\3\5\0\4@"; + break; + // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 + case 'sha224': + $t = "0-0\r\6\t`�H\1e\3\4\2\4\5\0\4\34"; + break; + case 'sha512/224': + $t = "0-0\r\6\t`�H\1e\3\4\2\5\5\0\4\34"; + break; + case 'sha512/256': + $t = "010\r\6\t`�H\1e\3\4\2\6\5\0\4 "; + } + $t .= $h; + $tLen = \strlen($t); + if ($emLen < $tLen + 11) { + throw new \LengthException('Intended encoded message length too short'); + } + $ps = \str_repeat(\chr(0xff), $emLen - $tLen - 3); + $em = "\0\1{$ps}\0{$t}"; + return $em; + } + /** + * EMSA-PKCS1-V1_5-ENCODE (without NULL) + * + * Quoting https://tools.ietf.org/html/rfc8017#page-65, + * + * "The parameters field associated with id-sha1, id-sha224, id-sha256, + * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should + * generally be omitted, but if present, it shall have a value of type + * NULL" + * + * @param string $m + * @param int $emLen + * @return string + */ + protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen) + { + $h = $this->hash->hash($m); + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hash->getHash()) { + case 'sha1': + $t = "0\0370\7\6\5+\16\3\2\32\4\24"; + break; + case 'sha256': + $t = "0/0\v\6\t`�H\1e\3\4\2\1\4 "; + break; + case 'sha384': + $t = "0?0\v\6\t`�H\1e\3\4\2\2\0040"; + break; + case 'sha512': + $t = "0O0\v\6\t`�H\1e\3\4\2\3\4@"; + break; + // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 + case 'sha224': + $t = "0+0\v\6\t`�H\1e\3\4\2\4\4\34"; + break; + case 'sha512/224': + $t = "0+0\v\6\t`�H\1e\3\4\2\5\4\34"; + break; + case 'sha512/256': + $t = "0/0\v\6\t`�H\1e\3\4\2\6\4 "; + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('md2 and md5 require NULLs'); + } + $t .= $h; + $tLen = \strlen($t); + if ($emLen < $tLen + 11) { + throw new \LengthException('Intended encoded message length too short'); + } + $ps = \str_repeat(\chr(0xff), $emLen - $tLen - 3); + $em = "\0\1{$ps}\0{$t}"; + return $em; + } + /** + * MGF1 + * + * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. + * + * @param string $mgfSeed + * @param int $maskLen + * @return string + */ + protected function mgf1($mgfSeed, $maskLen) + { + // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. + $t = ''; + $count = \ceil($maskLen / $this->mgfHLen); + for ($i = 0; $i < $count; $i++) { + $c = \pack('N', $i); + $t .= $this->mgfHash->hash($mgfSeed . $c); + } + return \substr($t, 0, $maskLen); + } + /** + * Returns the key size + * + * More specifically, this returns the size of the modulo in bits. + * + * @return int + */ + public function getLength() + { + return !isset($this->modulus) ? 0 : $this->modulus->getLength(); + } + /** + * Determines which hashing function should be used + * + * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and + * decryption. + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (\strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash($hash); + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'); + } + $new->hLen = $new->hash->getLengthInBytes(); + return $new; + } + /** + * Determines which hashing function should be used for the mask generation function + * + * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's + * best if Hash and MGFHash are set to the same thing this is not a requirement. + * + * @param string $hash + */ + public function withMGFHash($hash) + { + $new = clone $this; + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (\strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->mgfHash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash($hash); + break; + default: + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException('The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256'); + } + $new->mgfHLen = $new->mgfHash->getLengthInBytes(); + return $new; + } + /** + * Returns the MGF hash algorithm currently being used + * + */ + public function getMGFHash() + { + return clone $this->mgfHash; + } + /** + * Determines the salt length + * + * Used by RSA::PADDING_PSS + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: + * + * Typical salt lengths in octets are hLen (the length of the output + * of the hash function Hash) and 0. + * + * @param int $sLen + */ + public function withSaltLength($sLen) + { + $new = clone $this; + $new->sLen = $sLen; + return $new; + } + /** + * Returns the salt length currently being used + * + */ + public function getSaltLength() + { + return $this->sLen !== null ? $this->sLen : $this->hLen; + } + /** + * Determines the label + * + * Used by RSA::PADDING_OAEP + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: + * + * Both the encryption and the decryption operations of RSAES-OAEP take + * the value of a label L as input. In this version of PKCS #1, L is + * the empty string; other uses of the label are outside the scope of + * this document. + * + * @param string $label + */ + public function withLabel($label) + { + $new = clone $this; + $new->label = $label; + return $new; + } + /** + * Returns the label currently being used + * + */ + public function getLabel() + { + return $this->label; + } + /** + * Determines the padding modes + * + * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1); + * + * @param int $padding + */ + public function withPadding($padding) + { + $masks = [self::ENCRYPTION_OAEP, self::ENCRYPTION_PKCS1, self::ENCRYPTION_NONE]; + $numSelected = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $numSelected++; + } + } + if ($numSelected > 1) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); + } + $encryptionPadding = $selected; + $masks = [self::SIGNATURE_PSS, self::SIGNATURE_RELAXED_PKCS1, self::SIGNATURE_PKCS1]; + $numSelected = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $numSelected++; + } + } + if ($numSelected > 1) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); + } + $signaturePadding = $selected; + $new = clone $this; + $new->encryptionPadding = $encryptionPadding; + $new->signaturePadding = $signaturePadding; + return $new; + } + /** + * Returns the padding currently being used + * + */ + public function getPadding() + { + return $this->signaturePadding | $this->encryptionPadding; + } + /** + * Returns the current engine being used + * + * OpenSSL is only used in this class (and it's subclasses) for key generation + * Even then it depends on the parameters you're using. It's not used for + * multi-prime RSA nor is it used if the key length is outside of the range + * supported by OpenSSL + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @return string + */ + public function getEngine() + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ? 'OpenSSL' : 'PHP'; + } + /** + * Enable RSA Blinding + * + */ + public static function enableBlinding() + { + static::$enableBlinding = \true; + } + /** + * Disable RSA Blinding + * + */ + public static function disableBlinding() + { + static::$enableBlinding = \false; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php new file mode 100644 index 0000000..bce30b3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php @@ -0,0 +1,116 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * JWK Formatted RSA Handler + * + * @author Jim Wigginton + */ +abstract class JWK extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\JWK +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + if ($key->kty != 'RSA') { + throw new \RuntimeException('Only RSA JWK keys are supported'); + } + $count = $publicCount = 0; + $vars = ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi']; + foreach ($vars as $var) { + if (!isset($key->{$var}) || !\is_string($key->{$var})) { + continue; + } + $count++; + $value = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_decode($key->{$var}), 256); + switch ($var) { + case 'n': + $publicCount++; + $components['modulus'] = $value; + break; + case 'e': + $publicCount++; + $components['publicExponent'] = $value; + break; + case 'd': + $components['privateExponent'] = $value; + break; + case 'p': + $components['primes'][1] = $value; + break; + case 'q': + $components['primes'][2] = $value; + break; + case 'dp': + $components['exponents'][1] = $value; + break; + case 'dq': + $components['exponents'][2] = $value; + break; + case 'qi': + $components['coefficients'][2] = $value; + } + } + if ($count == \count($vars)) { + return $components + ['isPublicKey' => \false]; + } + if ($count == 2 && $publicCount == 2) { + return $components + ['isPublicKey' => \true]; + } + throw new \UnexpectedValueException('Key does not have an appropriate number of RSA parameters'); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (\count($primes) != 2) { + throw new \InvalidArgumentException('JWK does not support multi-prime RSA keys'); + } + $key = ['kty' => 'RSA', 'n' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($n->toBytes()), 'e' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($e->toBytes()), 'd' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($d->toBytes()), 'p' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($primes[1]->toBytes()), 'q' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($primes[2]->toBytes()), 'dp' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($exponents[1]->toBytes()), 'dq' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($exponents[2]->toBytes()), 'qi' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($coefficients[2]->toBytes())]; + return self::wrapKey($key, $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, array $options = []) + { + $key = ['kty' => 'RSA', 'n' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($n->toBytes()), 'e' => \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64url_encode($e->toBytes())]; + return self::wrapKey($key, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php new file mode 100644 index 0000000..aef8081 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php @@ -0,0 +1,207 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Microsoft BLOB Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class MSBLOB +{ + /** + * Public/Private Key Pair + * + */ + const PRIVATEKEYBLOB = 0x7; + /** + * Public Key + * + */ + const PUBLICKEYBLOB = 0x6; + /** + * Public Key + * + */ + const PUBLICKEYBLOBEX = 0xa; + /** + * RSA public key exchange algorithm + * + */ + const CALG_RSA_KEYX = 0xa400; + /** + * RSA public key exchange algorithm + * + */ + const CALG_RSA_SIGN = 0x2400; + /** + * Public Key + * + */ + const RSA1 = 0x31415352; + /** + * Private Key + * + */ + const RSA2 = 0x32415352; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + $key = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode($key); + if (!\is_string($key)) { + throw new \UnexpectedValueException('Base64 decoding produced an error'); + } + if (\strlen($key) < 20) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + // PUBLICKEYSTRUC publickeystruc + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx + \extract(\unpack('atype/aversion/vreserved/Valgo', \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, 8))); + /** + * @var string $type + * @var string $version + * @var integer $reserved + * @var integer $algo + */ + switch (\ord($type)) { + case self::PUBLICKEYBLOB: + case self::PUBLICKEYBLOBEX: + $publickey = \true; + break; + case self::PRIVATEKEYBLOB: + $publickey = \false; + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $components = ['isPublicKey' => $publickey]; + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx + switch ($algo) { + case self::CALG_RSA_KEYX: + case self::CALG_RSA_SIGN: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + // RSAPUBKEY rsapubkey + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx + // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit + \extract(\unpack('Vmagic/Vbitlen/a4pubexp', \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, 12))); + /** + * @var integer $magic + * @var integer $bitlen + * @var string $pubexp + */ + switch ($magic) { + case self::RSA2: + $components['isPublicKey'] = \false; + // fall-through + case self::RSA1: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $baseLength = $bitlen / 16; + if (\strlen($key) != 2 * $baseLength && \strlen($key) != 9 * $baseLength) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev($pubexp), 256); + // BYTE modulus[rsapubkey.bitlen/8] + $components['modulus'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, $bitlen / 8)), 256); + if ($publickey) { + return $components; + } + $components['isPublicKey'] = \false; + // BYTE prime1[rsapubkey.bitlen/16] + $components['primes'] = [1 => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE prime2[rsapubkey.bitlen/16] + $components['primes'][] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, $bitlen / 16)), 256); + // BYTE exponent1[rsapubkey.bitlen/16] + $components['exponents'] = [1 => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE exponent2[rsapubkey.bitlen/16] + $components['exponents'][] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, $bitlen / 16)), 256); + // BYTE coefficient[rsapubkey.bitlen/16] + $components['coefficients'] = [2 => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, $bitlen / 16)), 256)]; + if (isset($components['privateExponent'])) { + $components['publicExponent'] = $components['privateExponent']; + } + // BYTE privateExponent[rsapubkey.bitlen/8] + $components['privateExponent'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\strrev(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($key, $bitlen / 8)), 256); + return $components; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (\count($primes) != 2) { + throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); + } + if (!empty($password) && \is_string($password)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException('MSBLOB private keys do not support encryption'); + } + $n = \strrev($n->toBytes()); + $e = \str_pad(\strrev($e->toBytes()), 4, "\0"); + $key = \pack('aavV', \chr(self::PRIVATEKEYBLOB), \chr(2), 0, self::CALG_RSA_KEYX); + $key .= \pack('VVa*', self::RSA2, 8 * \strlen($n), $e); + $key .= $n; + $key .= \strrev($primes[1]->toBytes()); + $key .= \strrev($primes[2]->toBytes()); + $key .= \strrev($exponents[1]->toBytes()); + $key .= \strrev($exponents[2]->toBytes()); + $key .= \strrev($coefficients[2]->toBytes()); + $key .= \strrev($d->toBytes()); + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e) + { + $n = \strrev($n->toBytes()); + $e = \str_pad(\strrev($e->toBytes()), 4, "\0"); + $key = \pack('aavV', \chr(self::PUBLICKEYBLOB), \chr(2), 0, self::CALG_RSA_KEYX); + $key .= \pack('VVa*', self::RSA1, 8 * \strlen($n), $e); + $key .= $n; + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($key); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..37531d5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,101 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * OpenSSH Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\OpenSSH +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-rsa']; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + $parsed = parent::load($key, $password); + if (isset($parsed['paddedKey'])) { + list($type) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ({$type} vs {$parsed['type']})"); + } + $primes = $coefficients = []; + list($modulus, $publicExponent, $privateExponent, $coefficients[2], $primes[1], $primes[2], $comment, ) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('i6s', $parsed['paddedKey']); + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + $isPublicKey = \false; + return \compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + list($publicExponent, $modulus) = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ii', $parsed['publicKey']); + return ['isPublicKey' => \true, 'modulus' => $modulus, 'publicExponent' => $publicExponent, 'comment' => $parsed['comment']]; + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, array $options = []) + { + $RSAPublicKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('sii', 'ssh-rsa', $e, $n); + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $RSAPublicKey; + } + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $RSAPublicKey = 'ssh-rsa ' . \base64_encode($RSAPublicKey) . ' ' . $comment; + return $RSAPublicKey; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($n, $e, ['binary' => \true]); + $privateKey = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]); + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..d23d1c5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php @@ -0,0 +1,120 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PKCS#1 Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS1 +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (\strpos($key, 'PUBLIC') !== \false) { + $components = ['isPublicKey' => \true]; + } elseif (\strpos($key, 'PRIVATE') !== \false) { + $components = ['isPublicKey' => \false]; + } else { + $components = []; + } + $key = parent::load($key, $password); + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RSAPrivateKey::MAP); + if (\is_array($key)) { + $components += ['modulus' => $key['modulus'], 'publicExponent' => $key['publicExponent'], 'privateExponent' => $key['privateExponent'], 'primes' => [1 => $key['prime1'], $key['prime2']], 'exponents' => [1 => $key['exponent1'], $key['exponent2']], 'coefficients' => [2 => $key['coefficient']]]; + if ($key['version'] == 'multi') { + foreach ($key['otherPrimeInfos'] as $primeInfo) { + $components['primes'][] = $primeInfo['prime']; + $components['exponents'][] = $primeInfo['exponent']; + $components['coefficients'][] = $primeInfo['coefficient']; + } + } + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = \false; + } + return $components; + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RSAPublicKey::MAP); + if (!\is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = \true; + } + return $components + $key; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $num_primes = \count($primes); + $key = ['version' => $num_primes == 2 ? 'two-prime' : 'multi', 'modulus' => $n, 'publicExponent' => $e, 'privateExponent' => $d, 'prime1' => $primes[1], 'prime2' => $primes[2], 'exponent1' => $exponents[1], 'exponent2' => $exponents[2], 'coefficient' => $coefficients[2]]; + for ($i = 3; $i <= $num_primes; $i++) { + $key['otherPrimeInfos'][] = ['prime' => $primes[$i], 'exponent' => $exponents[$i], 'coefficient' => $coefficients[$i]]; + } + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RSAPrivateKey::MAP); + return self::wrapPrivateKey($key, 'RSA', $password, $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e) + { + $key = ['modulus' => $n, 'publicExponent' => $e]; + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($key, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RSAPublicKey::MAP); + return self::wrapPublicKey($key, 'RSA'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..32de41a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php @@ -0,0 +1,126 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PKCS#8 Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'rsaEncryption'; + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.1.1'; + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = \false; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (\strpos($key, 'PUBLIC') !== \false) { + $components = ['isPublicKey' => \true]; + } elseif (\strpos($key, 'PRIVATE') !== \false) { + $components = ['isPublicKey' => \false]; + } else { + $components = []; + } + $key = parent::load($key, $password); + if (isset($key['privateKey'])) { + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = \false; + } + $type = 'private'; + } else { + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = \true; + } + $type = 'public'; + } + $result = $components + \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS1::load($key[$type . 'Key']); + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + return $result; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $key = \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::extractBER($key); + return self::wrapPrivateKey($key, [], null, $password, null, '', $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, array $options = []) + { + $key = \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS1::savePublicKey($n, $e); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::extractBER($key); + return self::wrapPublicKey($key, null); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php new file mode 100644 index 0000000..93d7919 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php @@ -0,0 +1,193 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PKCS#8 Formatted RSA-PSS Key Handler + * + * @author Jim Wigginton + */ +abstract class PSS extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PKCS8 +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'id-RSASSA-PSS'; + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.1.10'; + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = \false; + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = \false; + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!self::$oidsLoaded) { + \PostSMTP\Vendor\phpseclib3\File\ASN1::loadOIDs(['md2' => '1.2.840.113549.2.2', 'md4' => '1.2.840.113549.2.4', 'md5' => '1.2.840.113549.2.5', 'id-sha1' => '1.3.14.3.2.26', 'id-sha256' => '2.16.840.1.101.3.4.2.1', 'id-sha384' => '2.16.840.1.101.3.4.2.2', 'id-sha512' => '2.16.840.1.101.3.4.2.3', 'id-sha224' => '2.16.840.1.101.3.4.2.4', 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', 'id-mgf1' => '1.2.840.113549.1.1.8']); + self::$oidsLoaded = \true; + } + } + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + $components = ['isPublicKey' => \strpos($key, 'PUBLIC') !== \false]; + $key = parent::load($key, $password); + $type = isset($key['privateKey']) ? 'private' : 'public'; + $result = $components + \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS1::load($key[$type . 'Key']); + if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); + if ($decoded === \false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RSASSA_PSS_params::MAP); + } else { + $params = []; + } + if (isset($params['maskGenAlgorithm']['parameters'])) { + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); + if ($decoded === \false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params['maskGenAlgorithm']['parameters'] = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\HashAlgorithm::MAP); + } else { + $params['maskGenAlgorithm'] = ['algorithm' => 'id-mgf1', 'parameters' => ['algorithm' => 'id-sha1']]; + } + if (!isset($params['hashAlgorithm']['algorithm'])) { + $params['hashAlgorithm']['algorithm'] = 'id-sha1'; + } + $result['hash'] = \str_replace('id-', '', $params['hashAlgorithm']['algorithm']); + $result['MGFHash'] = \str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']); + if (isset($params['saltLength'])) { + $result['saltLength'] = (int) $params['saltLength']->toString(); + } + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + return $result; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + self::initialize_static_variables(); + $key = \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, array $options = []) + { + self::initialize_static_variables(); + $key = \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS1::savePublicKey($n, $e); + $key = \PostSMTP\Vendor\phpseclib3\File\ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPublicKey($key, $params); + } + /** + * Encodes PSS parameters + * + * @param array $options + * @return string + */ + public static function savePSSParams(array $options) + { + /* + The trailerField field is an integer. It provides + compatibility with IEEE Std 1363a-2004 [P1363A]. The value + MUST be 1, which represents the trailer field with hexadecimal + value 0xBC. Other trailer fields, including the trailer field + composed of HashID concatenated with 0xCC that is specified in + IEEE Std 1363a, are not supported. Implementations that + perform signature generation MUST omit the trailerField field, + indicating that the default trailer field value was used. + Implementations that perform signature validation MUST + recognize both a present trailerField field with value 1 and an + absent trailerField field. + + source: https://tools.ietf.org/html/rfc4055#page-9 + */ + $params = ['trailerField' => new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1)]; + if (isset($options['hash'])) { + $params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash']; + } + if (isset($options['MGFHash'])) { + $temp = ['algorithm' => 'id-' . $options['MGFHash']]; + $temp = \PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($temp, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\HashAlgorithm::MAP); + $params['maskGenAlgorithm'] = ['algorithm' => 'id-mgf1', 'parameters' => new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element($temp)]; + } + if (isset($options['saltLength'])) { + $params['saltLength'] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($options['saltLength']); + } + return new \PostSMTP\Vendor\phpseclib3\File\ASN1\Element(\PostSMTP\Vendor\phpseclib3\File\ASN1::encodeDER($params, \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\RSASSA_PSS_params::MAP)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..9bf9688 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php @@ -0,0 +1,107 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * PuTTY Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\Formats\Keys\PuTTY +{ + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'PostSMTP\\Vendor\\phpseclib3\\Crypt\\RSA\\Formats\\Keys\\OpenSSH'; + /** + * Algorithm Identifier + * + * @var array + */ + protected static $types = ['ssh-rsa']; + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + \extract($components); + unset($components['public'], $components['private']); + $isPublicKey = \false; + $result = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('ii', $public); + if ($result === \false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + list($publicExponent, $modulus) = $result; + $result = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::unpackSSH2('iiii', $private); + if ($result === \false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $primes = $coefficients = []; + list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + return \compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (\count($primes) != 2) { + throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); + } + $public = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ii', $e, $n); + $private = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); + return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options); + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e) + { + return self::wrapPublicKey(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::packSSH2('ii', $e, $n), 'ssh-rsa'); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php new file mode 100644 index 0000000..560d140 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php @@ -0,0 +1,153 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . \gettype($key)); + } + $key = \array_change_key_case($key, \CASE_LOWER); + $components = ['isPublicKey' => \false]; + foreach (['e', 'exponent', 'publicexponent', 0, 'privateexponent', 'd'] as $index) { + if (isset($key[$index])) { + $components['publicExponent'] = $key[$index]; + break; + } + } + foreach (['n', 'modulo', 'modulus', 1] as $index) { + if (isset($key[$index])) { + $components['modulus'] = $key[$index]; + break; + } + } + if (!isset($components['publicExponent']) || !isset($components['modulus'])) { + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + if (isset($key['primes'])) { + $components['primes'] = $key['primes']; + } elseif (isset($key['p']) && isset($key['q'])) { + $indices = [['p', 'q'], ['prime1', 'prime2']]; + foreach ($indices as $index) { + list($i0, $i1) = $index; + if (isset($key[$i0]) && isset($key[$i1])) { + $components['primes'] = [1 => $key[$i0], $key[$i1]]; + } + } + } + if (isset($key['exponents'])) { + $components['exponents'] = $key['exponents']; + } else { + $indices = [['dp', 'dq'], ['exponent1', 'exponent2']]; + foreach ($indices as $index) { + list($i0, $i1) = $index; + if (isset($key[$i0]) && isset($key[$i1])) { + $components['exponents'] = [1 => $key[$i0], $key[$i1]]; + } + } + } + if (isset($key['coefficients'])) { + $components['coefficients'] = $key['coefficients']; + } else { + foreach (['inverseq', 'q\'', 'coefficient'] as $index) { + if (isset($key[$index])) { + $components['coefficients'] = [2 => $key[$index]]; + } + } + } + if (!isset($components['primes'])) { + $components['isPublicKey'] = \true; + return $components; + } + if (!isset($components['exponents'])) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + $temp = $components['primes'][1]->subtract($one); + $exponents = [1 => $components['publicExponent']->modInverse($temp)]; + $temp = $components['primes'][2]->subtract($one); + $exponents[] = $components['publicExponent']->modInverse($temp); + $components['exponents'] = $exponents; + } + if (!isset($components['coefficients'])) { + $components['coefficients'] = [2 => $components['primes'][2]->modInverse($components['primes'][1])]; + } + foreach (['privateexponent', 'd'] as $index) { + if (isset($key[$index])) { + $components['privateExponent'] = $key[$index]; + break; + } + } + return $components; + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return array + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (!empty($password) && \is_string($password)) { + throw new \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\UnsupportedFormatException('Raw private keys do not support encryption'); + } + return ['e' => clone $e, 'n' => clone $n, 'd' => clone $d, 'primes' => \array_map(function ($var) { + return clone $var; + }, $primes), 'exponents' => \array_map(function ($var) { + return clone $var; + }, $exponents), 'coefficients' => \array_map(function ($var) { + return clone $var; + }, $coefficients)]; + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return array + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e) + { + return ['e' => clone $e, 'n' => clone $n]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php new file mode 100644 index 0000000..324c5f3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php @@ -0,0 +1,140 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * XML Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . \gettype($key)); + } + if (!\class_exists('DOMDocument')) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException('The dom extension is not setup correctly on this system'); + } + $components = ['isPublicKey' => \false, 'primes' => [], 'exponents' => [], 'coefficients' => []]; + $use_errors = \libxml_use_internal_errors(\true); + $dom = new \DOMDocument(); + if (\substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + \libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='{$key}']"); + if (!$temp->length) { + continue; + } + $value = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'modulus': + $components['modulus'] = $value; + break; + case 'exponent': + $components['publicExponent'] = $value; + break; + case 'p': + $components['primes'][1] = $value; + break; + case 'q': + $components['primes'][2] = $value; + break; + case 'dp': + $components['exponents'][1] = $value; + break; + case 'dq': + $components['exponents'][2] = $value; + break; + case 'inverseq': + $components['coefficients'][2] = $value; + break; + case 'd': + $components['privateExponent'] = $value; + } + } + \libxml_use_internal_errors($use_errors); + foreach ($components as $key => $value) { + if (\is_array($value) && !\count($value)) { + unset($components[$key]); + } + } + if (isset($components['modulus']) && isset($components['publicExponent'])) { + if (\count($components) == 3) { + $components['isPublicKey'] = \true; + } + return $components; + } + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (\count($primes) != 2) { + throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); + } + if (!empty($password) && \is_string($password)) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException('XML private keys do not support encryption'); + } + return "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($n->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($e->toBytes()) . "\r\n" . '

        ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($primes[1]->toBytes()) . "

        \r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($primes[2]->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($exponents[1]->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($exponents[2]->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($coefficients[2]->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($d->toBytes()) . "\r\n" . '
        '; + } + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $e) + { + return "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($n->toBytes()) . "\r\n" . ' ' . \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::base64_encode($e->toBytes()) . "\r\n" . ''; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php new file mode 100644 index 0000000..e5e1cda --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php @@ -0,0 +1,441 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA; + +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +class PrivateKey extends \PostSMTP\Vendor\phpseclib3\Crypt\RSA implements \PostSMTP\Vendor\phpseclib3\Crypt\Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + /** + * Primes for Chinese Remainder Theorem (ie. p and q) + * + * @var array + */ + protected $primes; + /** + * Exponents for Chinese Remainder Theorem (ie. dP and dQ) + * + * @var array + */ + protected $exponents; + /** + * Coefficients for Chinese Remainder Theorem (ie. qInv) + * + * @var array + */ + protected $coefficients; + /** + * Private Exponent + * + * @var \phpseclib3\Math\BigInteger + */ + protected $privateExponent; + /** + * RSADP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. + * + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsadp(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $c) + { + if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Ciphertext representative out of range'); + } + return $this->exponentiate($c); + } + /** + * RSASP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. + * + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsasp1(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Signature representative out of range'); + } + return $this->exponentiate($m); + } + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + protected function exponentiate(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + switch (\true) { + case empty($this->primes): + case $this->primes[1]->equals(self::$zero): + case empty($this->coefficients): + case $this->coefficients[2]->equals(self::$zero): + case empty($this->exponents): + case $this->exponents[1]->equals(self::$zero): + return $x->modPow($this->exponent, $this->modulus); + } + $num_primes = \count($this->primes); + if (!static::$enableBlinding) { + $m_i = [1 => $x->modPow($this->exponents[1], $this->primes[1]), 2 => $x->modPow($this->exponents[2], $this->primes[2])]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); + $r = $r->multiply($this->primes[$i - 1]); + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + $m = $m->add($r->multiply($h)); + } + } else { + $smallest = $this->primes[1]; + for ($i = 2; $i <= $num_primes; $i++) { + if ($smallest->compare($this->primes[$i]) > 0) { + $smallest = $this->primes[$i]; + } + } + $r = \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomRange(self::$one, $smallest->subtract(self::$one)); + $m_i = [1 => $this->blind($x, $r, 1), 2 => $this->blind($x, $r, 2)]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $this->blind($x, $r, $i); + $r = $r->multiply($this->primes[$i - 1]); + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + $m = $m->add($r->multiply($h)); + } + } + return $m; + } + /** + * Performs RSA Blinding + * + * Protects against timing attacks by employing RSA Blinding. + * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) + * + * @param \phpseclib3\Math\BigInteger $x + * @param \phpseclib3\Math\BigInteger $r + * @param int $i + * @return \phpseclib3\Math\BigInteger + */ + private function blind(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $r, $i) + { + $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); + $x = $x->modPow($this->exponents[$i], $this->primes[$i]); + $r = $r->modInverse($this->primes[$i]); + $x = $x->multiply($r); + list(, $x) = $x->divide($this->primes[$i]); + return $x; + } + /** + * EMSA-PSS-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. + * + * @return string + * @param string $m + * @throws \RuntimeException on encoding error + * @param int $emBits + */ + private function emsa_pss_encode($m, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + $emLen = $emBits + 1 >> 3; + // ie. ceil($emBits / 8) + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + throw new \LengthException('RSA modulus too short'); + } + $salt = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string($sLen); + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h = $this->hash->hash($m2); + $ps = \str_repeat(\chr(0), $emLen - $sLen - $this->hLen - 2); + $db = $ps . \chr(1) . $salt; + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); + // ie. stlren($db) + $maskedDB = $db ^ $dbMask; + $maskedDB[0] = ~\chr(0xff << ($emBits & 7)) & $maskedDB[0]; + $em = $maskedDB . $h . \chr(0xbc); + return $em; + } + /** + * RSASSA-PSS-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. + * + * @param string $m + * @return bool|string + */ + private function rsassa_pss_sign($m) + { + // EMSA-PSS encoding + $em = $this->emsa_pss_encode($m, 8 * $this->k - 1); + // RSA signature + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + // Output the signature S + return $s; + } + /** + * RSASSA-PKCS1-V1_5-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. + * + * @param string $m + * @throws \LengthException if the RSA modulus is too short + * @return bool|string + */ + private function rsassa_pkcs1_v1_5_sign($m) + { + // EMSA-PKCS1-v1_5 encoding + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + } catch (\LengthException $e) { + throw new \LengthException('RSA modulus too short'); + } + // RSA signature + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + // Output the signature S + return $s; + } + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return string + */ + public function sign($message) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_PKCS1: + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_sign($message); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_sign($message); + } + } + /** + * RSAES-PKCS1-V1_5-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. + * + * @param string $c + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_decrypt($c) + { + // Length checking + if (\strlen($c) != $this->k) { + // or if k < 11 + throw new \LengthException('Ciphertext representative too long'); + } + // RSA decryption + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + // EME-PKCS1-v1_5 decoding + if (\ord($em[0]) != 0 || \ord($em[1]) > 2) { + throw new \RuntimeException('Decryption error'); + } + $ps = \substr($em, 2, \strpos($em, \chr(0), 2) - 2); + $m = \substr($em, \strlen($ps) + 3); + if (\strlen($ps) < 8) { + throw new \RuntimeException('Decryption error'); + } + // Output M + return $m; + } + /** + * RSAES-OAEP-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error + * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: + * + * Note. Care must be taken to ensure that an opponent cannot + * distinguish the different error conditions in Step 3.g, whether by + * error message or timing, or, more generally, learn partial + * information about the encoded message EM. Otherwise an opponent may + * be able to obtain useful information about the decryption of the + * ciphertext C, leading to a chosen-ciphertext attack such as the one + * observed by Manger [36]. + * + * @param string $c + * @return bool|string + */ + private function rsaes_oaep_decrypt($c) + { + // Length checking + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + if (\strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { + throw new \LengthException('Ciphertext representative too long'); + } + // RSA decryption + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + // EME-OAEP decoding + $lHash = $this->hash->hash($this->label); + $y = \ord($em[0]); + $maskedSeed = \substr($em, 1, $this->hLen); + $maskedDB = \substr($em, $this->hLen + 1); + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $seed = $maskedSeed ^ $seedMask; + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $lHash2 = \substr($db, 0, $this->hLen); + $m = \substr($db, $this->hLen); + $hashesMatch = \hash_equals($lHash, $lHash2); + $leadingZeros = 1; + $patternMatch = 0; + $offset = 0; + for ($i = 0; $i < \strlen($m); $i++) { + $patternMatch |= $leadingZeros & $m[$i] === "\1"; + $leadingZeros &= $m[$i] === "\0"; + $offset += $patternMatch ? 0 : 1; + } + // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation + // to protect against timing attacks + if (!$hashesMatch | !$patternMatch) { + throw new \RuntimeException('Decryption error'); + } + // Output the message M + return \substr($m, $offset + 1); + } + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (\strlen($m) > $this->k) { + throw new \LengthException('Ciphertext representative too long'); + } + $temp = $this->os2ip($m); + $temp = $this->rsadp($temp); + return $this->i2osp($temp, $this->k); + } + /** + * Decryption + * + * @see self::encrypt() + * @param string $ciphertext + * @return bool|string + */ + public function decrypt($ciphertext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($ciphertext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_decrypt($ciphertext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_decrypt($ciphertext); + } + } + /** + * Returns the public key + * + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + if (empty($this->modulus) || empty($this->publicExponent)) { + throw new \RuntimeException('Public key components not found'); + } + $key = $type::savePublicKey($this->modulus, $this->publicExponent); + return \PostSMTP\Vendor\phpseclib3\Crypt\RSA::loadFormat('PKCS8', $key)->withHash($this->hash->getHash())->withMGFHash($this->mgfHash->getHash())->withSaltLength($this->sLen)->withLabel($this->label)->withPadding($this->signaturePadding | $this->encryptionPadding); + } + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, empty($this->primes) ? 'savePublicKey' : 'savePrivateKey'); + if ($type == \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options += ['hash' => $this->hash->getHash(), 'MGFHash' => $this->mgfHash->getHash(), 'saltLength' => $this->getSaltLength()]; + } else { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + if (empty($this->primes)) { + return $type::savePublicKey($this->modulus, $this->exponent, $options); + } + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + /* + $key = $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + if ($key !== false || count($this->primes) == 2) { + return $key; + } + + $nSize = $this->getSize() >> 1; + + $primes = [1 => clone self::$one, clone self::$one]; + $i = 1; + foreach ($this->primes as $prime) { + $primes[$i] = $primes[$i]->multiply($prime); + if ($primes[$i]->getLength() >= $nSize) { + $i++; + } + } + + $exponents = []; + $coefficients = [2 => $primes[2]->modInverse($primes[1])]; + + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $this->modulus->modInverse($temp); + } + + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $primes, $exponents, $coefficients, $this->password, $options); + */ + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php new file mode 100644 index 0000000..b6d7e53 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php @@ -0,0 +1,439 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt\RSA; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common; +use PostSMTP\Vendor\phpseclib3\Crypt\Hash; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA; +use PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException; +use PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException; +use PostSMTP\Vendor\phpseclib3\File\ASN1; +use PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DigestInfo; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +class PublicKey extends \PostSMTP\Vendor\phpseclib3\Crypt\RSA implements \PostSMTP\Vendor\phpseclib3\Crypt\Common\PublicKey +{ + use Common\Traits\Fingerprint; + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + private function exponentiate(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + return $x->modPow($this->exponent, $this->modulus); + } + /** + * RSAVP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. + * + * @param \phpseclib3\Math\BigInteger $s + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsavp1($s) + { + if ($s->compare(self::$zero) < 0 || $s->compare($this->modulus) > 0) { + return \false; + } + return $this->exponentiate($s); + } + /** + * RSASSA-PKCS1-V1_5-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. + * + * @param string $m + * @param string $s + * @throws \LengthException if the RSA modulus is too short + * @return bool + */ + private function rsassa_pkcs1_v1_5_verify($m, $s) + { + // Length checking + if (\strlen($s) != $this->k) { + return \false; + } + // RSA verification + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === \false) { + return \false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === \false) { + return \false; + } + // EMSA-PKCS1-v1_5 encoding + $exception = \false; + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em2 = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + $r1 = \hash_equals($em, $em2); + } catch (\LengthException $e) { + $exception = \true; + } + try { + $em3 = $this->emsa_pkcs1_v1_5_encode_without_null($m, $this->k); + $r2 = \hash_equals($em, $em3); + } catch (\LengthException $e) { + $exception = \true; + } catch (\PostSMTP\Vendor\phpseclib3\Exception\UnsupportedAlgorithmException $e) { + $r2 = \false; + } + if ($exception) { + throw new \LengthException('RSA modulus too short'); + } + // Compare + return $r1 || $r2; + } + /** + * RSASSA-PKCS1-V1_5-VERIFY (relaxed matching) + * + * Per {@link http://tools.ietf.org/html/rfc3447#page-43 RFC3447#page-43} PKCS1 v1.5 + * specified the use BER encoding rather than DER encoding that PKCS1 v2.0 specified. + * This means that under rare conditions you can have a perfectly valid v1.5 signature + * that fails to validate with _rsassa_pkcs1_v1_5_verify(). PKCS1 v2.1 also recommends + * that if you're going to validate these types of signatures you "should indicate + * whether the underlying BER encoding is a DER encoding and hence whether the signature + * is valid with respect to the specification given in [PKCS1 v2.0+]". so if you do + * $rsa->getLastPadding() and get RSA::PADDING_RELAXED_PKCS1 back instead of + * RSA::PADDING_PKCS1... that means BER encoding was used. + * + * @param string $m + * @param string $s + * @return bool + */ + private function rsassa_pkcs1_v1_5_relaxed_verify($m, $s) + { + // Length checking + if (\strlen($s) != $this->k) { + return \false; + } + // RSA verification + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === \false) { + return \false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === \false) { + return \false; + } + if (\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($em, 2) != "\0\1") { + return \false; + } + $em = \ltrim($em, "�"); + if (\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($em) != "\0") { + return \false; + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::decodeBER($em); + if (!\is_array($decoded) || empty($decoded[0]) || \strlen($em) > $decoded[0]['length']) { + return \false; + } + static $oids; + if (!isset($oids)) { + $oids = [ + 'md2' => '1.2.840.113549.2.2', + 'md4' => '1.2.840.113549.2.4', + // from PKCS1 v1.5 + 'md5' => '1.2.840.113549.2.5', + 'id-sha1' => '1.3.14.3.2.26', + 'id-sha256' => '2.16.840.1.101.3.4.2.1', + 'id-sha384' => '2.16.840.1.101.3.4.2.2', + 'id-sha512' => '2.16.840.1.101.3.4.2.3', + // from PKCS1 v2.2 + 'id-sha224' => '2.16.840.1.101.3.4.2.4', + 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', + 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', + ]; + \PostSMTP\Vendor\phpseclib3\File\ASN1::loadOIDs($oids); + } + $decoded = \PostSMTP\Vendor\phpseclib3\File\ASN1::asn1map($decoded[0], \PostSMTP\Vendor\phpseclib3\File\ASN1\Maps\DigestInfo::MAP); + if (!isset($decoded) || $decoded === \false) { + return \false; + } + if (!isset($oids[$decoded['digestAlgorithm']['algorithm']])) { + return \false; + } + if (isset($decoded['digestAlgorithm']['parameters']) && $decoded['digestAlgorithm']['parameters'] !== ['null' => '']) { + return \false; + } + $hash = $decoded['digestAlgorithm']['algorithm']; + $hash = \substr($hash, 0, 3) == 'id-' ? \substr($hash, 3) : $hash; + $hash = new \PostSMTP\Vendor\phpseclib3\Crypt\Hash($hash); + $em = $hash->hash($m); + $em2 = $decoded['digest']; + return \hash_equals($em, $em2); + } + /** + * EMSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. + * + * @param string $m + * @param string $em + * @param int $emBits + * @return string + */ + private function emsa_pss_verify($m, $em, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + $emLen = $emBits + 7 >> 3; + // ie. ceil($emBits / 8); + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + return \false; + } + if ($em[\strlen($em) - 1] != \chr(0xbc)) { + return \false; + } + $maskedDB = \substr($em, 0, -$this->hLen - 1); + $h = \substr($em, -$this->hLen - 1, $this->hLen); + $temp = \chr(0xff << ($emBits & 7)); + if ((~$maskedDB[0] & $temp) != $temp) { + return \false; + } + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $db[0] = ~\chr(0xff << ($emBits & 7)) & $db[0]; + $temp = $emLen - $this->hLen - $sLen - 2; + if (\substr($db, 0, $temp) != \str_repeat(\chr(0), $temp) || \ord($db[$temp]) != 1) { + return \false; + } + $salt = \substr($db, $temp + 1); + // should be $sLen long + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h2 = $this->hash->hash($m2); + return \hash_equals($h, $h2); + } + /** + * RSASSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. + * + * @param string $m + * @param string $s + * @return bool|string + */ + private function rsassa_pss_verify($m, $s) + { + // Length checking + if (\strlen($s) != $this->k) { + return \false; + } + // RSA verification + $modBits = \strlen($this->modulus->toBits()); + $s2 = $this->os2ip($s); + $m2 = $this->rsavp1($s2); + $em = $this->i2osp($m2, $this->k); + if ($em === \false) { + return \false; + } + // EMSA-PSS verification + return $this->emsa_pss_verify($m, $em, $modBits - 1); + } + /** + * Verifies a signature + * + * @see self::sign() + * @param string $message + * @param string $signature + * @return bool + */ + public function verify($message, $signature) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature); + case self::SIGNATURE_PKCS1: + return $this->rsassa_pkcs1_v1_5_verify($message, $signature); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_verify($message, $signature); + } + } + /** + * RSAES-PKCS1-V1_5-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. + * + * @param string $m + * @param bool $pkcs15_compat optional + * @throws \LengthException if strlen($m) > $this->k - 11 + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_encrypt($m, $pkcs15_compat = \false) + { + $mLen = \strlen($m); + // Length checking + if ($mLen > $this->k - 11) { + throw new \LengthException('Message too long'); + } + // EME-PKCS1-v1_5 encoding + $psLen = $this->k - $mLen - 3; + $ps = ''; + while (\strlen($ps) != $psLen) { + $temp = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string($psLen - \strlen($ps)); + $temp = \str_replace("\0", '', $temp); + $ps .= $temp; + } + $type = 2; + $em = \chr(0) . \chr($type) . $ps . \chr(0) . $m; + // RSA encryption + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + // Output the ciphertext C + return $c; + } + /** + * RSAES-OAEP-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and + * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. + * + * @param string $m + * @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 + * @return string + */ + private function rsaes_oaep_encrypt($m) + { + $mLen = \strlen($m); + // Length checking + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + if ($mLen > $this->k - 2 * $this->hLen - 2) { + throw new \LengthException('Message too long'); + } + // EME-OAEP encoding + $lHash = $this->hash->hash($this->label); + $ps = \str_repeat(\chr(0), $this->k - $mLen - 2 * $this->hLen - 2); + $db = $lHash . $ps . \chr(1) . $m; + $seed = \PostSMTP\Vendor\phpseclib3\Crypt\Random::string($this->hLen); + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $maskedDB = $db ^ $dbMask; + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $maskedSeed = $seed ^ $seedMask; + $em = \chr(0) . $maskedSeed . $maskedDB; + // RSA encryption + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + // Output the ciphertext C + return $c; + } + /** + * RSAEP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. + * + * @param \phpseclib3\Math\BigInteger $m + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsaep($m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Message representative out of range'); + } + return $this->exponentiate($m); + } + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (\strlen($m) > $this->k) { + throw new \LengthException('Message too long'); + } + $temp = $this->os2ip($m); + $temp = $this->rsaep($temp); + return $this->i2osp($temp, $this->k); + } + /** + * Encryption + * + * Both self::PADDING_OAEP and self::PADDING_PKCS1 both place limits on how long $plaintext can be. + * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will + * be concatenated together. + * + * @see self::decrypt() + * @param string $plaintext + * @return bool|string + * @throws \LengthException if the RSA modulus is too short + */ + public function encrypt($plaintext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($plaintext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_encrypt($plaintext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_encrypt($plaintext); + } + } + /** + * Returns the public key + * + * The public key is only returned under two circumstances - if the private key had the public key embedded within it + * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this + * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. + * + * @param string $type + * @param array $options optional + * @return mixed + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + if ($type == \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options += ['hash' => $this->hash->getHash(), 'MGFHash' => $this->mgfHash->getHash(), 'saltLength' => $this->getSaltLength()]; + } else { + throw new \PostSMTP\Vendor\phpseclib3\Exception\UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + return $type::savePublicKey($this->modulus, $this->publicExponent, $options); + } + /** + * Converts a public key to a private key + * + * @return RSA + */ + public function asPrivateKey() + { + $new = new \PostSMTP\Vendor\phpseclib3\Crypt\RSA\PrivateKey(); + $new->exponent = $this->exponent; + $new->modulus = $this->modulus; + $new->k = $this->k; + $new->format = $this->format; + return $new->withHash($this->hash->getHash())->withMGFHash($this->mgfHash->getHash())->withSaltLength($this->sLen)->withLabel($this->label)->withPadding($this->signaturePadding | $this->encryptionPadding); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Random.php new file mode 100644 index 0000000..7f2a684 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Random.php @@ -0,0 +1,202 @@ + + * + * + * + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt; + +/** + * Pure-PHP Random Number Generator + * + * @author Jim Wigginton + */ +abstract class Random +{ + /** + * Generate a random string. + * + * Although microoptimizations are generally discouraged as they impair readability this function is ripe with + * microoptimizations because this function has the potential of being called a huge number of times. + * eg. for RSA key generation. + * + * @param int $length + * @throws \RuntimeException if a symmetric cipher is needed but not loaded + * @return string + */ + public static function string($length) + { + if (!$length) { + return ''; + } + try { + return \random_bytes($length); + } catch (\Exception $e) { + // random_compat will throw an Exception, which in PHP 5 does not implement Throwable + } catch (\Throwable $e) { + // If a sufficient source of randomness is unavailable, random_bytes() will throw an + // object that implements the Throwable interface (Exception, TypeError, Error). + // We don't actually need to do anything here. The string() method should just continue + // as normal. Note, however, that if we don't have a sufficient source of randomness for + // random_bytes(), most of the other calls here will fail too, so we'll end up using + // the PHP implementation. + } + // at this point we have no choice but to use a pure-PHP CSPRNG + // cascade entropy across multiple PHP instances by fixing the session and collecting all + // environmental variables, including the previous session data and the current session + // data. + // + // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively) + // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but + // PHP isn't low level to be able to use those as sources and on a web server there's not likely + // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use + // however, a ton of people visiting the website. obviously you don't want to base your seeding + // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled + // by the user and (2) this isn't just looking at the data sent by the current user - it's based + // on the data sent by all users. one user requests the page and a hash of their info is saved. + // another user visits the page and the serialization of their data is utilized along with the + // server environment stuff and a hash of the previous http request data (which itself utilizes + // a hash of the session data before that). certainly an attacker should be assumed to have + // full control over his own http requests. he, however, is not going to have control over + // everyone's http requests. + static $crypto = \false, $v; + if ($crypto === \false) { + // save old session data + $old_session_id = \session_id(); + $old_use_cookies = \ini_get('session.use_cookies'); + $old_session_cache_limiter = \session_cache_limiter(); + $_OLD_SESSION = isset($_SESSION) ? $_SESSION : \false; + if ($old_session_id != '') { + \session_write_close(); + } + \session_id(1); + \ini_set('session.use_cookies', 0); + \session_cache_limiter(''); + \session_start(); + $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . (isset($_POST) ? self::safe_serialize($_POST) : '') . (isset($_GET) ? self::safe_serialize($_GET) : '') . (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') . self::safe_serialize($GLOBALS) . self::safe_serialize($_SESSION) . self::safe_serialize($_OLD_SESSION); + $v = $seed = $_SESSION['seed'] = \sha1($v, \true); + if (!isset($_SESSION['count'])) { + $_SESSION['count'] = 0; + } + $_SESSION['count']++; + \session_write_close(); + // restore old session data + if ($old_session_id != '') { + \session_id($old_session_id); + \session_start(); + \ini_set('session.use_cookies', $old_use_cookies); + \session_cache_limiter($old_session_cache_limiter); + } else { + if ($_OLD_SESSION !== \false) { + $_SESSION = $_OLD_SESSION; + unset($_OLD_SESSION); + } else { + unset($_SESSION); + } + } + // in SSH2 a shared secret and an exchange hash are generated through the key exchange process. + // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C. + // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the + // original hash and the current hash. we'll be emulating that. for more info see the following URL: + // + // http://tools.ietf.org/html/rfc4253#section-7.2 + // + // see the is_string($crypto) part for an example of how to expand the keys + $key = \sha1($seed . 'A', \true); + $iv = \sha1($seed . 'C', \true); + // ciphers are used as per the nist.gov link below. also, see this link: + // + // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives + switch (\true) { + case \class_exists('PostSMTP\\Vendor\\phpseclib3\\Crypt\\AES'): + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\AES('ctr'); + break; + case \class_exists('PostSMTP\\Vendor\\phpseclib3\\Crypt\\Twofish'): + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\Twofish('ctr'); + break; + case \class_exists('PostSMTP\\Vendor\\phpseclib3\\Crypt\\Blowfish'): + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\Blowfish('ctr'); + break; + case \class_exists('PostSMTP\\Vendor\\phpseclib3\\Crypt\\TripleDES'): + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\TripleDES('ctr'); + break; + case \class_exists('PostSMTP\\Vendor\\phpseclib3\\Crypt\\DES'): + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\DES('ctr'); + break; + case \class_exists('PostSMTP\\Vendor\\phpseclib3\\Crypt\\RC4'): + $crypto = new \PostSMTP\Vendor\phpseclib3\Crypt\RC4(); + break; + default: + throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); + } + $crypto->setKey(\substr($key, 0, $crypto->getKeyLength() >> 3)); + $crypto->setIV(\substr($iv, 0, $crypto->getBlockLength() >> 3)); + $crypto->enableContinuousBuffer(); + } + //return $crypto->encrypt(str_repeat("\0", $length)); + // the following is based off of ANSI X9.31: + // + // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf + // + // OpenSSL uses that same standard for it's random numbers: + // + // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c + // (do a search for "ANS X9.31 A.2.4") + $result = ''; + while (\strlen($result) < $length) { + $i = $crypto->encrypt(\microtime()); + // strlen(microtime()) == 21 + $r = $crypto->encrypt($i ^ $v); + // strlen($v) == 20 + $v = $crypto->encrypt($r ^ $i); + // strlen($r) == 20 + $result .= $r; + } + return \substr($result, 0, $length); + } + /** + * Safely serialize variables + * + * If a class has a private __sleep() it'll emit a warning + * @return mixed + * @param mixed $arr + */ + private static function safe_serialize(&$arr) + { + if (\is_object($arr)) { + return ''; + } + if (!\is_array($arr)) { + return \serialize($arr); + } + // prevent circular array recursion + if (isset($arr['__phpseclib_marker'])) { + return ''; + } + $safearr = []; + $arr['__phpseclib_marker'] = \true; + foreach (\array_keys($arr) as $key) { + // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage + if ($key !== '__phpseclib_marker') { + $safearr[$key] = self::safe_serialize($arr[$key]); + } + } + unset($arr['__phpseclib_marker']); + return \serialize($safearr); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php new file mode 100644 index 0000000..1a117d2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php @@ -0,0 +1,1050 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rijndael->decrypt($rijndael->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Crypt; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Common\BlockCipher; +use PostSMTP\Vendor\phpseclib3\Exception\BadDecryptionException; +use PostSMTP\Vendor\phpseclib3\Exception\BadModeException; +use PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException; +use PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException; +/** + * Pure-PHP implementation of Rijndael. + * + * @author Jim Wigginton + */ +class Rijndael extends \PostSMTP\Vendor\phpseclib3\Crypt\Common\BlockCipher +{ + /** + * The mcrypt specific name of the cipher + * + * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. + * \phpseclib3\Crypt\Rijndael determines automatically whether mcrypt is useable + * or not for the current $block_size/$key_length. + * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::engine + * @see self::isValidEngine() + * @var string + */ + protected $cipher_name_mcrypt = 'rijndael-128'; + /** + * The Key Schedule + * + * @see self::setup() + * @var array + */ + private $w; + /** + * The Inverse Key Schedule + * + * @see self::setup() + * @var array + */ + private $dw; + /** + * The Block Length divided by 32 + * + * {@internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size + * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could + * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see self::setBlockLength() + * @var int + */ + private $Nb = 4; + /** + * The Key Length (in bytes) + * + * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see self::setKeyLength() + * @var int + */ + protected $key_length = 16; + /** + * The Key Length divided by 32 + * + * @see self::setKeyLength() + * @var int + * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 + */ + private $Nk = 4; + /** + * The Number of Rounds + * + * {@internal The max value is 14, the min value is 10.} + * + * @var int + */ + private $Nr; + /** + * Shift offsets + * + * @var array + */ + private $c; + /** + * Holds the last used key- and block_size information + * + * @var array + */ + private $kl; + /** + * Default Constructor. + * + * @param string $mode + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + if ($this->mode == self::MODE_STREAM) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + /** + * Sets the key length. + * + * Valid key lengths are 128, 160, 192, 224, and 256. + * + * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined + * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to + * 192/256 bits as, for example, mcrypt will do. + * + * That said, if you want be compatible with other Rijndael and AES implementations, + * you should not setKeyLength(160) or setKeyLength(224). + * + * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use + * the mcrypt php extension, even if available. + * This results then in slower encryption. + * + * @throws \LengthException if the key length is invalid + * @param int $length + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + $this->key_length = $length >> 3; + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); + } + parent::setKeyLength($length); + } + /** + * Sets the key. + * + * Rijndael supports five different key lengths + * + * @see setKeyLength() + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (\strlen($key)) { + case 16: + case 20: + case 24: + case 28: + case 32: + break; + default: + throw new \LengthException('Key of size ' . \strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); + } + parent::setKey($key); + } + /** + * Sets the block length + * + * Valid block lengths are 128, 160, 192, 224, and 256. + * + * @param int $length + */ + public function setBlockLength($length) + { + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); + } + $this->Nb = $length >> 5; + $this->block_size = $length >> 3; + $this->changed = $this->nonIVChanged = \true; + $this->setEngine(); + } + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_LIBSODIUM: + return \function_exists('sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available() && $this->mode == self::MODE_GCM && $this->key_length == 32 && $this->nonce && \strlen($this->nonce) == 12 && $this->block_size == 16; + case self::ENGINE_OPENSSL_GCM: + if (!\extension_loaded('openssl')) { + return \false; + } + $methods = \openssl_get_cipher_methods(); + return $this->mode == self::MODE_GCM && \version_compare(\PHP_VERSION, '7.1.0', '>=') && \in_array('aes-' . $this->getKeyLength() . '-gcm', $methods) && $this->block_size == 16; + case self::ENGINE_OPENSSL: + if ($this->block_size != 16) { + return \false; + } + $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; + $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->openssl_translate_mode(); + break; + case self::ENGINE_MCRYPT: + $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); + if ($this->key_length % 8) { + // is it a 160/224-bit key? + // mcrypt is not usable for them, only for 128/192/256-bit keys + return \false; + } + } + return parent::isValidEngineHelper($engine); + } + /** + * Encrypts a block + * + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + static $tables; + if (empty($tables)) { + $tables =& $this->getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + $state = []; + $words = \unpack('N*', $in); + $c = $this->c; + $w = $this->w; + $Nb = $this->Nb; + $Nr = $this->Nr; + // addRoundKey + $wc = $Nb - 1; + foreach ($words as $word) { + $state[] = $word ^ $w[++$wc]; + } + // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - + // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding + // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf. + // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization. + // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1], + // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. + // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf + $temp = []; + for ($round = 1; $round < $Nr; ++$round) { + $i = 0; + // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + while ($i < $Nb) { + $temp[$i] = $t0[$state[$i] >> 24 & 0xff] ^ $t1[$state[$j] >> 16 & 0xff] ^ $t2[$state[$k] >> 8 & 0xff] ^ $t3[$state[$l] & 0xff] ^ $w[++$wc]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + $state = $temp; + } + // subWord + for ($i = 0; $i < $Nb; ++$i) { + $state[$i] = $sbox[$state[$i] & 0xff] | $sbox[$state[$i] >> 8 & 0xff] << 8 | $sbox[$state[$i] >> 16 & 0xff] << 16 | $sbox[$state[$i] >> 24 & 0xff] << 24; + } + // shiftRows + addRoundKey + $i = 0; + // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + while ($i < $Nb) { + $temp[$i] = $state[$i] & \intval(0xff000000) ^ $state[$j] & 0xff0000 ^ $state[$k] & 0xff00 ^ $state[$l] & 0xff ^ $w[$i]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + return \pack('N*', ...$temp); + } + /** + * Decrypts a block + * + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + static $invtables; + if (empty($invtables)) { + $invtables =& $this->getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + $state = []; + $words = \unpack('N*', $in); + $c = $this->c; + $dw = $this->dw; + $Nb = $this->Nb; + $Nr = $this->Nr; + // addRoundKey + $wc = $Nb - 1; + foreach ($words as $word) { + $state[] = $word ^ $dw[++$wc]; + } + $temp = []; + for ($round = $Nr - 1; $round > 0; --$round) { + $i = 0; + // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + while ($i < $Nb) { + $temp[$i] = $dt0[$state[$i] >> 24 & 0xff] ^ $dt1[$state[$j] >> 16 & 0xff] ^ $dt2[$state[$k] >> 8 & 0xff] ^ $dt3[$state[$l] & 0xff] ^ $dw[++$wc]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + $state = $temp; + } + // invShiftRows + invSubWord + addRoundKey + $i = 0; + // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + while ($i < $Nb) { + $word = $state[$i] & \intval(0xff000000) | $state[$j] & 0xff0000 | $state[$k] & 0xff00 | $state[$l] & 0xff; + $temp[$i] = $dw[$i] ^ ($isbox[$word & 0xff] | $isbox[$word >> 8 & 0xff] << 8 | $isbox[$word >> 16 & 0xff] << 16 | $isbox[$word >> 24 & 0xff] << 24); + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + return \pack('N*', ...$temp); + } + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == self::ENGINE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * {@internal setup() is always called before en/decryption.} + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + parent::setup(); + if (\is_string($this->iv) && \strlen($this->iv) != $this->block_size) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InconsistentSetupException('The IV length (' . \strlen($this->iv) . ') does not match the block size (' . $this->block_size . ')'); + } + } + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + */ + protected function setupKey() + { + // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. + // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse + static $rcon; + if (!isset($rcon)) { + $rcon = [0, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000, 0x6c000000, 0xd8000000, 0xab000000, 0x4d000000, 0x9a000000, 0x2f000000, 0x5e000000, 0xbc000000, 0x63000000, 0xc6000000, 0x97000000, 0x35000000, 0x6a000000, 0xd4000000, 0xb3000000, 0x7d000000, 0xfa000000, 0xef000000, 0xc5000000, 0x91000000]; + $rcon = \array_map('intval', $rcon); + } + if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size]; + $this->Nk = $this->key_length >> 2; + // see Rijndael-ammended.pdf#page=44 + $this->Nr = \max($this->Nk, $this->Nb) + 6; + // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44, + // "Table 8: Shift offsets in Shiftrow for the alternative block lengths" + // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14, + // "Table 2: Shift offsets for different block lengths" + switch ($this->Nb) { + case 4: + case 5: + case 6: + $this->c = [0, 1, 2, 3]; + break; + case 7: + $this->c = [0, 1, 2, 4]; + break; + case 8: + $this->c = [0, 1, 3, 4]; + } + $w = \array_values(\unpack('N*words', $this->key)); + $length = $this->Nb * ($this->Nr + 1); + for ($i = $this->Nk; $i < $length; $i++) { + $temp = $w[$i - 1]; + if ($i % $this->Nk == 0) { + // according to , "the size of an integer is platform-dependent". + // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, + // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' + // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. + $temp = $temp << 8 & \intval(0xffffff00) | $temp >> 24 & 0xff; + // rotWord + $temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk]; + } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { + $temp = $this->subWord($temp); + } + $w[$i] = $w[$i - $this->Nk] ^ $temp; + } + // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns + // and generate the inverse key schedule. more specifically, + // according to (section 5.3.3), + // "The key expansion for the Inverse Cipher is defined as follows: + // 1. Apply the Key Expansion. + // 2. Apply InvMixColumn to all Round Keys except the first and the last one." + // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" + list($dt0, $dt1, $dt2, $dt3) = $this->getInvTables(); + $temp = $this->w = $this->dw = []; + for ($i = $row = $col = 0; $i < $length; $i++, $col++) { + if ($col == $this->Nb) { + if ($row == 0) { + $this->dw[0] = $this->w[0]; + } else { + // subWord + invMixColumn + invSubWord = invMixColumn + $j = 0; + while ($j < $this->Nb) { + $dw = $this->subWord($this->w[$row][$j]); + $temp[$j] = $dt0[$dw >> 24 & 0xff] ^ $dt1[$dw >> 16 & 0xff] ^ $dt2[$dw >> 8 & 0xff] ^ $dt3[$dw & 0xff]; + $j++; + } + $this->dw[$row] = $temp; + } + $col = 0; + $row++; + } + $this->w[$row][$col] = $w[$i]; + } + $this->dw[$row] = $this->w[$row]; + // Converting to 1-dim key arrays (both ascending) + $this->dw = \array_reverse($this->dw); + $w = \array_pop($this->w); + $dw = \array_pop($this->dw); + foreach ($this->w as $r => $wr) { + foreach ($wr as $c => $wc) { + $w[] = $wc; + $dw[] = $this->dw[$r][$c]; + } + } + $this->w = $w; + $this->dw = $dw; + } + /** + * Performs S-Box substitutions + * + * @return array + * @param int $word + */ + private function subWord($word) + { + static $sbox; + if (empty($sbox)) { + list(, , , , $sbox) = self::getTables(); + } + return $sbox[$word & 0xff] | $sbox[$word >> 8 & 0xff] << 8 | $sbox[$word >> 16 & 0xff] << 16 | $sbox[$word >> 24 & 0xff] << 24; + } + /** + * Provides the mixColumns and sboxes tables + * + * @see self::encryptBlock() + * @see self::setupInlineCrypt() + * @see self::subWord() + * @return array &$tables + */ + protected function &getTables() + { + static $tables; + if (empty($tables)) { + // according to (section 5.2.1), + // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so + // those are the names we'll use. + $t3 = \array_map('intval', [ + // with array_map('intval', ...) we ensure we have only int's and not + // some slower floats converted by php automatically on high values + 0x6363a5c6, + 0x7c7c84f8, + 0x777799ee, + 0x7b7b8df6, + 0xf2f20dff, + 0x6b6bbdd6, + 0x6f6fb1de, + 0xc5c55491, + 0x30305060, + 0x1010302, + 0x6767a9ce, + 0x2b2b7d56, + 0xfefe19e7, + 0xd7d762b5, + 0xababe64d, + 0x76769aec, + 0xcaca458f, + 0x82829d1f, + 0xc9c94089, + 0x7d7d87fa, + 0xfafa15ef, + 0x5959ebb2, + 0x4747c98e, + 0xf0f00bfb, + 0xadadec41, + 0xd4d467b3, + 0xa2a2fd5f, + 0xafafea45, + 0x9c9cbf23, + 0xa4a4f753, + 0x727296e4, + 0xc0c05b9b, + 0xb7b7c275, + 0xfdfd1ce1, + 0x9393ae3d, + 0x26266a4c, + 0x36365a6c, + 0x3f3f417e, + 0xf7f702f5, + 0xcccc4f83, + 0x34345c68, + 0xa5a5f451, + 0xe5e534d1, + 0xf1f108f9, + 0x717193e2, + 0xd8d873ab, + 0x31315362, + 0x15153f2a, + 0x4040c08, + 0xc7c75295, + 0x23236546, + 0xc3c35e9d, + 0x18182830, + 0x9696a137, + 0x5050f0a, + 0x9a9ab52f, + 0x707090e, + 0x12123624, + 0x80809b1b, + 0xe2e23ddf, + 0xebeb26cd, + 0x2727694e, + 0xb2b2cd7f, + 0x75759fea, + 0x9091b12, + 0x83839e1d, + 0x2c2c7458, + 0x1a1a2e34, + 0x1b1b2d36, + 0x6e6eb2dc, + 0x5a5aeeb4, + 0xa0a0fb5b, + 0x5252f6a4, + 0x3b3b4d76, + 0xd6d661b7, + 0xb3b3ce7d, + 0x29297b52, + 0xe3e33edd, + 0x2f2f715e, + 0x84849713, + 0x5353f5a6, + 0xd1d168b9, + 0x0, + 0xeded2cc1, + 0x20206040, + 0xfcfc1fe3, + 0xb1b1c879, + 0x5b5bedb6, + 0x6a6abed4, + 0xcbcb468d, + 0xbebed967, + 0x39394b72, + 0x4a4ade94, + 0x4c4cd498, + 0x5858e8b0, + 0xcfcf4a85, + 0xd0d06bbb, + 0xefef2ac5, + 0xaaaae54f, + 0xfbfb16ed, + 0x4343c586, + 0x4d4dd79a, + 0x33335566, + 0x85859411, + 0x4545cf8a, + 0xf9f910e9, + 0x2020604, + 0x7f7f81fe, + 0x5050f0a0, + 0x3c3c4478, + 0x9f9fba25, + 0xa8a8e34b, + 0x5151f3a2, + 0xa3a3fe5d, + 0x4040c080, + 0x8f8f8a05, + 0x9292ad3f, + 0x9d9dbc21, + 0x38384870, + 0xf5f504f1, + 0xbcbcdf63, + 0xb6b6c177, + 0xdada75af, + 0x21216342, + 0x10103020, + 0xffff1ae5, + 0xf3f30efd, + 0xd2d26dbf, + 0xcdcd4c81, + 0xc0c1418, + 0x13133526, + 0xecec2fc3, + 0x5f5fe1be, + 0x9797a235, + 0x4444cc88, + 0x1717392e, + 0xc4c45793, + 0xa7a7f255, + 0x7e7e82fc, + 0x3d3d477a, + 0x6464acc8, + 0x5d5de7ba, + 0x19192b32, + 0x737395e6, + 0x6060a0c0, + 0x81819819, + 0x4f4fd19e, + 0xdcdc7fa3, + 0x22226644, + 0x2a2a7e54, + 0x9090ab3b, + 0x8888830b, + 0x4646ca8c, + 0xeeee29c7, + 0xb8b8d36b, + 0x14143c28, + 0xdede79a7, + 0x5e5ee2bc, + 0xb0b1d16, + 0xdbdb76ad, + 0xe0e03bdb, + 0x32325664, + 0x3a3a4e74, + 0xa0a1e14, + 0x4949db92, + 0x6060a0c, + 0x24246c48, + 0x5c5ce4b8, + 0xc2c25d9f, + 0xd3d36ebd, + 0xacacef43, + 0x6262a6c4, + 0x9191a839, + 0x9595a431, + 0xe4e437d3, + 0x79798bf2, + 0xe7e732d5, + 0xc8c8438b, + 0x3737596e, + 0x6d6db7da, + 0x8d8d8c01, + 0xd5d564b1, + 0x4e4ed29c, + 0xa9a9e049, + 0x6c6cb4d8, + 0x5656faac, + 0xf4f407f3, + 0xeaea25cf, + 0x6565afca, + 0x7a7a8ef4, + 0xaeaee947, + 0x8081810, + 0xbabad56f, + 0x787888f0, + 0x25256f4a, + 0x2e2e725c, + 0x1c1c2438, + 0xa6a6f157, + 0xb4b4c773, + 0xc6c65197, + 0xe8e823cb, + 0xdddd7ca1, + 0x74749ce8, + 0x1f1f213e, + 0x4b4bdd96, + 0xbdbddc61, + 0x8b8b860d, + 0x8a8a850f, + 0x707090e0, + 0x3e3e427c, + 0xb5b5c471, + 0x6666aacc, + 0x4848d890, + 0x3030506, + 0xf6f601f7, + 0xe0e121c, + 0x6161a3c2, + 0x35355f6a, + 0x5757f9ae, + 0xb9b9d069, + 0x86869117, + 0xc1c15899, + 0x1d1d273a, + 0x9e9eb927, + 0xe1e138d9, + 0xf8f813eb, + 0x9898b32b, + 0x11113322, + 0x6969bbd2, + 0xd9d970a9, + 0x8e8e8907, + 0x9494a733, + 0x9b9bb62d, + 0x1e1e223c, + 0x87879215, + 0xe9e920c9, + 0xcece4987, + 0x5555ffaa, + 0x28287850, + 0xdfdf7aa5, + 0x8c8c8f03, + 0xa1a1f859, + 0x89898009, + 0xd0d171a, + 0xbfbfda65, + 0xe6e631d7, + 0x4242c684, + 0x6868b8d0, + 0x4141c382, + 0x9999b029, + 0x2d2d775a, + 0xf0f111e, + 0xb0b0cb7b, + 0x5454fca8, + 0xbbbbd66d, + 0x16163a2c, + ]); + foreach ($t3 as $t3i) { + $t0[] = $t3i << 24 & \intval(0xff000000) | $t3i >> 8 & 0xffffff; + $t1[] = $t3i << 16 & \intval(0xffff0000) | $t3i >> 16 & 0xffff; + $t2[] = $t3i << 8 & \intval(0xffffff00) | $t3i >> 24 & 0xff; + } + $tables = [ + // The Precomputed mixColumns tables t0 - t3 + $t0, + $t1, + $t2, + $t3, + // The SubByte S-Box + [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x1, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x4, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x5, 0x9a, 0x7, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x9, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x0, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x2, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0xc, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0xb, 0xdb, 0xe0, 0x32, 0x3a, 0xa, 0x49, 0x6, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x8, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x3, 0xf6, 0xe, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0xd, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0xf, 0xb0, 0x54, 0xbb, 0x16], + ]; + } + return $tables; + } + /** + * Provides the inverse mixColumns and inverse sboxes tables + * + * @see self::decryptBlock() + * @see self::setupInlineCrypt() + * @see self::setupKey() + * @return array &$tables + */ + protected function &getInvTables() + { + static $tables; + if (empty($tables)) { + $dt3 = \array_map('intval', [0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a, 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b, 0x30fa5520, 0x766df6ad, 0xcc769188, 0x24c25f5, 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5, 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d, 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b, 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95, 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e, 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27, 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d, 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562, 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x82b94f9, 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752, 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66, 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3, 0x2887f230, 0xbfa5b223, 0x36aba02, 0x16825ced, 0xcf1c2b8a, 0x79b492a7, 0x7f2f0f3, 0x69e2a14e, 0xdaf4cd65, 0x5bed506, 0x34621fd1, 0xa6fe8ac4, 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4, 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd, 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d, 0x548db591, 0xc45d0571, 0x6d46f04, 0x5015ff60, 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767, 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79, 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x0, 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c, 0xefffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736, 0xfd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24, 0xa67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b, 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c, 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12, 0x90d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814, 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3, 0x1269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b, 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8, 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084, 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7, 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077, 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247, 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22, 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698, 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f, 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254, 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582, 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf, 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb, 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883, 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef, 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629, 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035, 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533, 0x4984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17, 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4, 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46, 0x5eea049d, 0x8c355d01, 0x877473fa, 0xb412efb, 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d, 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb, 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a, 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73, 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678, 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2, 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0xd9541ff, 0xa8017139, 0xcb3de08, 0xb4e49cd8, 0x56c19064, 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0]); + foreach ($dt3 as $dt3i) { + $dt0[] = $dt3i << 24 & \intval(0xff000000) | $dt3i >> 8 & 0xffffff; + $dt1[] = $dt3i << 16 & \intval(0xffff0000) | $dt3i >> 16 & 0xffff; + $dt2[] = $dt3i << 8 & \intval(0xffffff00) | $dt3i >> 24 & 0xff; + } + $tables = [ + // The Precomputed inverse mixColumns tables dt0 - dt3 + $dt0, + $dt1, + $dt2, + $dt3, + // The inverse SubByte S-Box + [0x52, 0x9, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0xb, 0x42, 0xfa, 0xc3, 0x4e, 0x8, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x0, 0x8c, 0xbc, 0xd3, 0xa, 0xf7, 0xe4, 0x58, 0x5, 0xb8, 0xb3, 0x45, 0x6, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0xf, 0x2, 0xc1, 0xaf, 0xbd, 0x3, 0x1, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0xe, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x7, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0xd, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x4, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0xc, 0x7d], + ]; + } + return $tables; + } + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + */ + protected function setupInlineCrypt() + { + $w = $this->w; + $dw = $this->dw; + $init_encrypt = ''; + $init_decrypt = ''; + $Nr = $this->Nr; + $Nb = $this->Nb; + $c = $this->c; + // Generating encrypt code: + $init_encrypt .= ' + static $tables; + if (empty($tables)) { + $tables = &$this->getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + '; + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + // Preround: addRoundKey + $encrypt_block = '$in = unpack("N*", $in);' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $w[++$wc] . ";\n"; + } + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= '$' . $e . $i . ' = + $t0[($' . $s . $i . ' >> 24) & 0xff] ^ + $t1[($' . $s . ($i + $c[1]) % $Nb . ' >> 16) & 0xff] ^ + $t2[($' . $s . ($i + $c[2]) % $Nb . ' >> 8) & 0xff] ^ + $t3[ $' . $s . ($i + $c[3]) % $Nb . ' & 0xff] ^ + ' . $w[++$wc] . ";\n"; + } + } + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= '$' . $e . $i . ' = + $sbox[ $' . $e . $i . ' & 0xff] | + ($sbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | + ($sbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | + ($sbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; + } + $encrypt_block .= '$in = pack("N*"' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= ', + ($' . $e . $i . ' & ' . (int) 0xff000000 . ') ^ + ($' . $e . ($i + $c[1]) % $Nb . ' & 0x00FF0000 ) ^ + ($' . $e . ($i + $c[2]) % $Nb . ' & 0x0000FF00 ) ^ + ($' . $e . ($i + $c[3]) % $Nb . ' & 0x000000FF ) ^ + ' . $w[$i] . "\n"; + } + $encrypt_block .= ');'; + // Generating decrypt code: + $init_decrypt .= ' + static $invtables; + if (empty($invtables)) { + $invtables = &$this->getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + '; + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + // Preround: addRoundKey + $decrypt_block = '$in = unpack("N*", $in);' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $dw[++$wc] . ';' . "\n"; + } + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= '$' . $e . $i . ' = + $dt0[($' . $s . $i . ' >> 24) & 0xff] ^ + $dt1[($' . $s . ($Nb + $i - $c[1]) % $Nb . ' >> 16) & 0xff] ^ + $dt2[($' . $s . ($Nb + $i - $c[2]) % $Nb . ' >> 8) & 0xff] ^ + $dt3[ $' . $s . ($Nb + $i - $c[3]) % $Nb . ' & 0xff] ^ + ' . $dw[++$wc] . ";\n"; + } + } + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= '$' . $e . $i . ' = + $isbox[ $' . $e . $i . ' & 0xff] | + ($isbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | + ($isbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | + ($isbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; + } + $decrypt_block .= '$in = pack("N*"' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= ', + ($' . $e . $i . ' & ' . (int) 0xff000000 . ') ^ + ($' . $e . ($Nb + $i - $c[1]) % $Nb . ' & 0x00FF0000 ) ^ + ($' . $e . ($Nb + $i - $c[2]) % $Nb . ' & 0x0000FF00 ) ^ + ($' . $e . ($Nb + $i - $c[3]) % $Nb . ' & 0x000000FF ) ^ + ' . $dw[$i] . "\n"; + } + $decrypt_block .= ');'; + $this->inline_crypt = $this->createInlineCryptFunction(['init_crypt' => '', 'init_encrypt' => $init_encrypt, 'init_decrypt' => $init_decrypt, 'encrypt_block' => $encrypt_block, 'decrypt_block' => $decrypt_block]); + } + /** + * Encrypts a message. + * + * @see self::decrypt() + * @see parent::encrypt() + * @param string $plaintext + * @return string + */ + public function encrypt($plaintext) + { + $this->setup(); + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + $this->newtag = \sodium_crypto_aead_aes256gcm_encrypt($plaintext, $this->aad, $this->nonce, $this->key); + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::shift($this->newtag, \strlen($plaintext)); + case self::ENGINE_OPENSSL_GCM: + return \openssl_encrypt($plaintext, 'aes-' . $this->getKeyLength() . '-gcm', $this->key, \OPENSSL_RAW_DATA, $this->nonce, $this->newtag, $this->aad); + } + return parent::encrypt($plaintext); + } + /** + * Decrypts a message. + * + * @see self::encrypt() + * @see parent::decrypt() + * @param string $ciphertext + * @return string + */ + public function decrypt($ciphertext) + { + $this->setup(); + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + if ($this->oldtag === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException('Authentication Tag has not been set'); + } + if (\strlen($this->oldtag) != 16) { + break; + } + $plaintext = \sodium_crypto_aead_aes256gcm_decrypt($ciphertext . $this->oldtag, $this->aad, $this->nonce, $this->key); + if ($plaintext === \false) { + $this->oldtag = \false; + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadDecryptionException('Error decrypting ciphertext with libsodium'); + } + return $plaintext; + case self::ENGINE_OPENSSL_GCM: + if ($this->oldtag === \false) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\InsufficientSetupException('Authentication Tag has not been set'); + } + $plaintext = \openssl_decrypt($ciphertext, 'aes-' . $this->getKeyLength() . '-gcm', $this->key, \OPENSSL_RAW_DATA, $this->nonce, $this->oldtag, $this->aad); + if ($plaintext === \false) { + $this->oldtag = \false; + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadDecryptionException('Error decrypting ciphertext with OpenSSL'); + } + return $plaintext; + } + return parent::decrypt($ciphertext); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php new file mode 100644 index 0000000..969e8b4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * BadConfigurationException + * + * @author Jim Wigginton + */ +class BadConfigurationException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php new file mode 100644 index 0000000..b3d25f8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * BadDecryptionException + * + * @author Jim Wigginton + */ +class BadDecryptionException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php new file mode 100644 index 0000000..55b750c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * BadModeException + * + * @author Jim Wigginton + */ +class BadModeException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php new file mode 100644 index 0000000..71164f9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * ConnectionClosedException + * + * @author Jim Wigginton + */ +class ConnectionClosedException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php new file mode 100644 index 0000000..d8f4483 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * FileNotFoundException + * + * @author Jim Wigginton + */ +class FileNotFoundException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php new file mode 100644 index 0000000..a0f5522 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * InconsistentSetupException + * + * @author Jim Wigginton + */ +class InconsistentSetupException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php new file mode 100644 index 0000000..1b65915 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * InsufficientSetupException + * + * @author Jim Wigginton + */ +class InsufficientSetupException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php new file mode 100644 index 0000000..a13474c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * NoKeyLoadedException + * + * @author Jim Wigginton + */ +class NoKeyLoadedException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php new file mode 100644 index 0000000..2233e8a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * NoSupportedAlgorithmsException + * + * @author Jim Wigginton + */ +class NoSupportedAlgorithmsException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php new file mode 100644 index 0000000..bf16e71 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * UnableToConnectException + * + * @author Jim Wigginton + */ +class UnableToConnectException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php new file mode 100644 index 0000000..96ffaf0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * UnsupportedAlgorithmException + * + * @author Jim Wigginton + */ +class UnsupportedAlgorithmException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php new file mode 100644 index 0000000..30fe04d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * UnsupportedCurveException + * + * @author Jim Wigginton + */ +class UnsupportedCurveException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php new file mode 100644 index 0000000..4ffefae --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * UnsupportedFormatException + * + * @author Jim Wigginton + */ +class UnsupportedFormatException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php new file mode 100644 index 0000000..02aa378 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php @@ -0,0 +1,22 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ +namespace PostSMTP\Vendor\phpseclib3\Exception; + +/** + * UnsupportedOperationException + * + * @author Jim Wigginton + */ +class UnsupportedOperationException extends \RuntimeException +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger.php new file mode 100644 index 0000000..b6ff1ab --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -0,0 +1,802 @@ + + * add($b); + * + * echo $c->toString(); // outputs 5 + * ?> + * + * + * @author Jim Wigginton + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Math; + +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine; +/** + * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 + * numbers. + * + * @author Jim Wigginton + */ +class BigInteger implements \JsonSerializable +{ + /** + * Main Engine + * + * @var class-string + */ + private static $mainEngine; + /** + * Selected Engines + * + * @var list + */ + private static $engines; + /** + * The actual BigInteger object + * + * @var object + */ + private $value; + /** + * Mode independent value used for serialization. + * + * @see self::__sleep() + * @see self::__wakeup() + * @var string + */ + private $hex; + /** + * Precision (used only for serialization) + * + * @see self::__sleep() + * @see self::__wakeup() + * @var int + */ + private $precision; + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param string $main + * @param list $modexps optional + * @return void + */ + public static function setEngine($main, array $modexps = ['DefaultEngine']) + { + self::$engines = []; + $fqmain = 'PostSMTP\\Vendor\\phpseclib3\\Math\\BigInteger\\Engines\\' . $main; + if (!\class_exists($fqmain) || !\method_exists($fqmain, 'isValidEngine')) { + throw new \InvalidArgumentException("{$main} is not a valid engine"); + } + if (!$fqmain::isValidEngine()) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException("{$main} is not setup correctly on this system"); + } + /** @var class-string $fqmain */ + self::$mainEngine = $fqmain; + if (!\in_array('Default', $modexps)) { + $modexps[] = 'DefaultEngine'; + } + $found = \false; + foreach ($modexps as $modexp) { + try { + $fqmain::setModExpEngine($modexp); + $found = \true; + break; + } catch (\Exception $e) { + } + } + if (!$found) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException("No valid modular exponentiation engine found for {$main}"); + } + self::$engines = [$main, $modexp]; + } + /** + * Returns the engine type + * + * @return string[] + */ + public static function getEngine() + { + self::initialize_static_variables(); + return self::$engines; + } + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!isset(self::$mainEngine)) { + $engines = [['GMP'], ['PHP64', ['OpenSSL']], ['BCMath', ['OpenSSL']], ['PHP32', ['OpenSSL']]]; + foreach ($engines as $engine) { + try { + self::setEngine($engine[0], isset($engine[1]) ? $engine[1] : []); + break; + } catch (\Exception $e) { + } + } + } + } + /** + * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. + * + * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using + * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. + * + * @param string|int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set. + * @param int $base + */ + public function __construct($x = 0, $base = 10) + { + self::initialize_static_variables(); + if ($x instanceof self::$mainEngine) { + $this->value = clone $x; + } elseif ($x instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine) { + $this->value = new static("{$x}"); + $this->value->setPrecision($x->getPrecision()); + } else { + $this->value = new self::$mainEngine($x, $base); + } + } + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return $this->value->toString(); + } + /** + * __toString() magic method + */ + public function __toString() + { + return (string) $this->value; + } + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + */ + public function __debugInfo() + { + return $this->value->__debugInfo(); + } + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = \false) + { + return $this->value->toBytes($twos_compliment); + } + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = \false) + { + return $this->value->toHex($twos_compliment); + } + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = \false) + { + return $this->value->toBits($twos_compliment); + } + /** + * Adds two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + public function add(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + return new static($this->value->add($y->value)); + } + /** + * Subtracts two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + public function subtract(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + return new static($this->value->subtract($y->value)); + } + /** + * Multiplies two BigIntegers + * + * @param BigInteger $x + * @return BigInteger + */ + public function multiply(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + return new static($this->value->multiply($x->value)); + } + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * Here's an example: + * + * divide($b); + * + * echo $quotient->toString(); // outputs 0 + * echo "\r\n"; + * echo $remainder->toString(); // outputs 10 + * ?> + * + * + * @param BigInteger $y + * @return BigInteger[] + */ + public function divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + list($q, $r) = $this->value->divide($y->value); + return [new static($q), new static($r)]; + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BigInteger $n + * @return BigInteger + */ + public function modInverse(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n) + { + return new static($this->value->modInverse($n->value)); + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BigInteger $n + * @return BigInteger[] + */ + public function extendedGCD(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n) + { + \extract($this->value->extendedGCD($n->value)); + /** + * @var BigInteger $gcd + * @var BigInteger $x + * @var BigInteger $y + */ + return ['gcd' => new static($gcd), 'x' => new static($x), 'y' => new static($y)]; + } + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BigInteger $n + * @return BigInteger + */ + public function gcd(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n) + { + return new static($this->value->gcd($n->value)); + } + /** + * Absolute value. + * + * @return BigInteger + */ + public function abs() + { + return new static($this->value->abs()); + } + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + $this->value->setPrecision($bits); + } + /** + * Get Precision + * + * Returns the precision if it exists, false if it doesn't + * + * @return int|bool + */ + public function getPrecision() + { + return $this->value->getPrecision(); + } + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * __sleep() / __wakeup() have been around since PHP 4.0 + * + * \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1: + * https://wiki.php.net/rfc/phase_out_serializable + * + * __serialize() / __unserialize() were introduced in PHP 7.4: + * https://wiki.php.net/rfc/custom_object_serialization + * + * @return array + */ + public function __sleep() + { + $this->hex = $this->toHex(\true); + $vars = ['hex']; + if ($this->getPrecision() > 0) { + $vars[] = 'precision'; + } + return $vars; + } + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + */ + public function __wakeup() + { + $temp = new static($this->hex, -16); + $this->value = $temp->value; + if ($this->precision > 0) { + // recalculate $this->bitmask + $this->setPrecision($this->precision); + } + } + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $result = ['hex' => $this->toHex(\true)]; + if ($this->precision > 0) { + $result['precision'] = $this->getPrecision(); + } + return $result; + } + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function powMod(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $n) + { + return new static($this->value->powMod($e->value, $n->value)); + } + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function modPow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $n) + { + return new static($this->value->modPow($e->value, $n->value)); + } + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BigInteger $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $y) + { + return $this->value->compare($y->value); + } + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BigInteger $x + * @return bool + */ + public function equals(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + return $this->value->equals($x->value); + } + /** + * Logical Not + * + * @return BigInteger + */ + public function bitwise_not() + { + return new static($this->value->bitwise_not()); + } + /** + * Logical And + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_and(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + return new static($this->value->bitwise_and($x->value)); + } + /** + * Logical Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_or(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + return new static($this->value->bitwise_or($x->value)); + } + /** + * Logical Exclusive Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_xor(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + return new static($this->value->bitwise_xor($x->value)); + } + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightShift($shift) + { + return new static($this->value->bitwise_rightShift($shift)); + } + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftShift($shift) + { + return new static($this->value->bitwise_leftShift($shift)); + } + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftRotate($shift) + { + return new static($this->value->bitwise_leftRotate($shift)); + } + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightRotate($shift) + { + return new static($this->value->bitwise_rightRotate($shift)); + } + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return BigInteger[] + */ + public static function minMaxBits($bits) + { + self::initialize_static_variables(); + $class = self::$mainEngine; + \extract($class::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + return ['min' => new static($min), 'max' => new static($max)]; + } + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return $this->value->getLength(); + } + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return $this->value->getLengthInBytes(); + } + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function random($size) + { + self::initialize_static_variables(); + $class = self::$mainEngine; + return new static($class::random($size)); + } + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function randomPrime($size) + { + self::initialize_static_variables(); + $class = self::$mainEngine; + return new static($class::randomPrime($size)); + } + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BigInteger $min + * @param BigInteger $max + * @return false|BigInteger + */ + public static function randomRangePrime(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRangePrime($min->value, $max->value)); + } + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BigInteger $min + * @param BigInteger $max + * @return BigInteger + */ + public static function randomRange(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRange($min->value, $max->value)); + } + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = \false) + { + return $this->value->isPrime($t); + } + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n optional + * @return BigInteger + */ + public function root($n = 2) + { + return new static($this->value->root($n)); + } + /** + * Performs exponentiation. + * + * @param BigInteger $n + * @return BigInteger + */ + public function pow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $n) + { + return new static($this->value->pow($n->value)); + } + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function min(\PostSMTP\Vendor\phpseclib3\Math\BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = \array_map(function ($num) { + return $num->value; + }, $nums); + return new static($class::min(...$nums)); + } + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function max(\PostSMTP\Vendor\phpseclib3\Math\BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = \array_map(function ($num) { + return $num->value; + }, $nums); + return new static($class::max(...$nums)); + } + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BigInteger $min + * @param BigInteger $max + * @return bool + */ + public function between(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $max) + { + return $this->value->between($min->value, $max->value); + } + /** + * Clone + */ + public function __clone() + { + $this->value = clone $this->value; + } + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value->isOdd(); + } + /** + * Tests if a bit is set + * + * @param int $x + * @return bool + */ + public function testBit($x) + { + return $this->value->testBit($x); + } + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return $this->value->isNegative(); + } + /** + * Negate + * + * Given $k, returns -$k + * + * @return BigInteger + */ + public function negate() + { + return new static($this->value->negate()); + } + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param BigInteger $r + * @return int + */ + public static function scan1divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $r) + { + $class = self::$mainEngine; + return $class::scan1divide($r->value); + } + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $func = $this->value->createRecurringModuloFunction(); + return function (\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) use($func) { + return new static($func($x->value)); + }; + } + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return BigInteger[] + */ + public function bitwise_split($split) + { + return \array_map(function ($val) { + return new static($val); + }, $this->value->bitwise_split($split)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php new file mode 100644 index 0000000..40500e5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php @@ -0,0 +1,601 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +/** + * BCMath Engine. + * + * @author Jim Wigginton + */ +class BCMath extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = \false; + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'BCMath'; + /** + * Test for engine validity + * + * @return bool + * @see parent::__construct() + */ + public static function isValidEngine() + { + return \extension_loaded('bcmath'); + } + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException('BCMath is not setup correctly on this system'); + } + $this->value = '0'; + parent::__construct($x, $base); + } + /** + * Initialize a BCMath BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (\abs($base)) { + case 256: + // round $len to the nearest 4 + $len = \strlen($this->value) + 3 & 0xfffffffc; + $x = \str_pad($this->value, $len, \chr(0), \STR_PAD_LEFT); + $this->value = '0'; + for ($i = 0; $i < $len; $i += 4) { + $this->value = \bcmul($this->value, '4294967296', 0); + // 4294967296 == 2**32 + $this->value = \bcadd($this->value, 0x1000000 * \ord($x[$i]) + (\ord($x[$i + 1]) << 16 | \ord($x[$i + 2]) << 8 | \ord($x[$i + 3])), 0); + } + if ($this->is_negative) { + $this->value = '-' . $this->value; + } + break; + case 16: + $x = \strlen($this->value) & 1 ? '0' . $this->value : $this->value; + $temp = new self(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::hex2bin($x), 256); + $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; + $this->is_negative = \false; + break; + case 10: + // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different + // results then doing it on '-1' does (modInverse does $x[0]) + $this->value = $this->value === '-' ? '0' : (string) $this->value; + } + } + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if ($this->value === '0') { + return '0'; + } + return \ltrim($this->value, '0'); + } + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = \false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + $value = ''; + $current = $this->value; + if ($current[0] == '-') { + $current = \substr($current, 1); + } + while (\bccomp($current, '0', 0) > 0) { + $temp = \bcmod($current, '16777216'); + $value = \chr($temp >> 16) . \chr($temp >> 8) . \chr($temp) . $value; + $current = \bcdiv($current, '16777216', 0); + } + return $this->precision > 0 ? \substr(\str_pad($value, $this->precision >> 3, \chr(0), \STR_PAD_LEFT), -($this->precision >> 3)) : \ltrim($value, \chr(0)); + } + /** + * Adds two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function add(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $y) + { + $temp = new self(); + $temp->value = \bcadd($this->value, $y->value); + return $this->normalize($temp); + } + /** + * Subtracts two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function subtract(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $y) + { + $temp = new self(); + $temp->value = \bcsub($this->value, $y->value); + return $this->normalize($temp); + } + /** + * Multiplies two BigIntegers. + * + * @param BCMath $x + * @return BCMath + */ + public function multiply(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $x) + { + $temp = new self(); + $temp->value = \bcmul($this->value, $x->value); + return $this->normalize($temp); + } + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param BCMath $y + * @return array{static, static} + */ + public function divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $y) + { + $quotient = new self(); + $remainder = new self(); + $quotient->value = \bcdiv($this->value, $y->value, 0); + $remainder->value = \bcmod($this->value, $y->value); + if ($remainder->value[0] == '-') { + $remainder->value = \bcadd($remainder->value, $y->value[0] == '-' ? \substr($y->value, 1) : $y->value, 0); + } + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BCMath $n + * @return false|BCMath + */ + public function modInverse(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + return $this->modInverseHelper($n); + } + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param BCMath $n + * @return array{gcd: static, x: static, y: static} + */ + public function extendedGCD(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works + // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, + // the basic extended euclidean algorithim is what we're using. + $u = $this->value; + $v = $n->value; + $a = '1'; + $b = '0'; + $c = '0'; + $d = '1'; + while (\bccomp($v, '0', 0) != 0) { + $q = \bcdiv($u, $v, 0); + $temp = $u; + $u = $v; + $v = \bcsub($temp, \bcmul($v, $q, 0), 0); + $temp = $a; + $a = $c; + $c = \bcsub($temp, \bcmul($a, $q, 0), 0); + $temp = $b; + $b = $d; + $d = \bcsub($temp, \bcmul($b, $q, 0), 0); + } + return ['gcd' => $this->normalize(new static($u)), 'x' => $this->normalize(new static($a)), 'y' => $this->normalize(new static($b))]; + } + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BCMath $n + * @return BCMath + */ + public function gcd(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + \extract($this->extendedGCD($n)); + /** @var BCMath $gcd */ + return $gcd; + } + /** + * Absolute value. + * + * @return BCMath + */ + public function abs() + { + $temp = new static(); + $temp->value = \strlen($this->value) && $this->value[0] == '-' ? \substr($this->value, 1) : $this->value; + return $temp; + } + /** + * Logical And + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_and(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $x) + { + return $this->bitwiseAndHelper($x); + } + /** + * Logical Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_or(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + /** + * Logical Exclusive Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_xor(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return BCMath + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + $temp->value = \bcdiv($this->value, \bcpow('2', $shift, 0), 0); + return $this->normalize($temp); + } + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return BCMath + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + $temp->value = \bcmul($this->value, \bcpow('2', $shift, 0), 0); + return $this->normalize($temp); + } + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BCMath $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $y) + { + return \bccomp($this->value, $y->value, 0); + } + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BCMath $x + * @return bool + */ + public function equals(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $x) + { + return $this->value == $x->value; + } + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function modPow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + return $this->powModOuter($e, $n); + } + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function powMod(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + return $this->powModOuter($e, $n); + } + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected function powModInner(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + try { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param BCMath $result + * @return BCMath + */ + protected function normalize(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + if ($result->bitmask !== \false) { + $result->value = \bcmod($result->value, $result->bitmask->value); + } + return $result; + } + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BCMath $min + * @param BCMath $max + * @return false|BCMath + */ + public static function randomRangePrime(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $max) + { + return self::randomRangePrimeOuter($min, $max); + } + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BCMath $min + * @param BCMath $max + * @return BCMath + */ + public static function randomRange(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $max) + { + return self::randomRangeHelper($min, $max); + } + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + if (!$this->isOdd()) { + $this->value = \bcadd($this->value, '1'); + } + } + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value === '1') { + return \false; + } + if ($this->value === '2') { + return \true; + } + if ($this->value[\strlen($this->value) - 1] % 2 == 0) { + return \false; + } + $value = $this->value; + foreach (self::PRIMES as $prime) { + $r = \bcmod($this->value, $prime); + if ($r == '0') { + return $this->value == $prime; + } + } + return \true; + } + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param BCMath $r + * @return int + * @see self::isPrime() + */ + public static function scan1divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $r) + { + $r_value =& $r->value; + $s = 0; + // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one[static::class]) check earlier + while ($r_value[\strlen($r_value) - 1] % 2 == 0) { + $r_value = \bcdiv($r_value, '2', 0); + ++$s; + } + return $s; + } + /** + * Performs exponentiation. + * + * @param BCMath $n + * @return BCMath + */ + public function pow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + $temp = new self(); + $temp->value = \bcpow($this->value, $n->value); + return $this->normalize($temp); + } + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function min(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath ...$nums) + { + return self::minHelper($nums); + } + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function max(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath ...$nums) + { + return self::maxHelper($nums); + } + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BCMath $min + * @param BCMath $max + * @return bool + */ + public function between(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + /** + * Set Bitmask + * + * @param int $bits + * @return Engine + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + $temp = parent::setBitmask($bits); + return $temp->add(static::$one[static::class]); + } + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value[\strlen($this->value) - 1] % 2 == 1; + } + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + return \bccomp(\bcmod($this->value, \bcpow('2', $x + 1, 0)), \bcpow('2', $x, 0), 0) >= 0; + } + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return \strlen($this->value) && $this->value[0] == '-'; + } + /** + * Negate + * + * Given $k, returns -$k + * + * @return BCMath + */ + public function negate() + { + $temp = clone $this; + if (!\strlen($temp->value)) { + return $temp; + } + $temp->value = $temp->value[0] == '-' ? \substr($this->value, 1) : '-' . $this->value; + return $temp; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php new file mode 100644 index 0000000..f940053 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php @@ -0,0 +1,102 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath; +/** + * Sliding Window Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Base extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + /** + * Performs modular exponentiation. + * + * @param BCMath $x + * @param BCMath $e + * @param BCMath $n + * @param string $class + * @return BCMath + */ + protected static function powModHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = '1'; + return $x->normalize($temp); + } + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + /** + * Modular reduction preparation + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function prepareReduce($x, $n, $class) + { + return static::reduce($x, $n); + } + /** + * Modular multiply + * + * @param string $x + * @param string $y + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function multiplyReduce($x, $y, $n, $class) + { + return static::reduce(\bcmul($x, $y), $n); + } + /** + * Modular square + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function squareReduce($x, $n, $class) + { + return static::reduce(\bcmul($x, $x), $n); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php new file mode 100644 index 0000000..8b17e29 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php @@ -0,0 +1,37 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath; +/** + * Built-In BCMath Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class BuiltIn extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath +{ + /** + * Performs modular exponentiation. + * + * @param BCMath $x + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected static function powModHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $n) + { + $temp = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath(); + $temp->value = \bcpowmod($x->value, $e->value, $n->value); + return $x->normalize($temp); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php new file mode 100644 index 0000000..b78cd83 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php @@ -0,0 +1,23 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett; +/** + * PHP Default Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php new file mode 100644 index 0000000..4f2e864 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php @@ -0,0 +1,23 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\OpenSSL +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php new file mode 100644 index 0000000..6cc15ca --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php @@ -0,0 +1,157 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Base; +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Barrett extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Base +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param string $n + * @param string $m + * @return string + */ + protected static function reduce($n, $m) + { + static $cache = [self::VARIABLE => [], self::DATA => []]; + $m_length = \strlen($m); + if (\strlen($n) > 2 * $m_length) { + return \bcmod($n, $m); + } + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m); + } + // n = 2 * m.length + if (($key = \array_search($m, $cache[self::VARIABLE])) === \false) { + $key = \count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + $lhs = '1' . \str_repeat('0', $m_length + ($m_length >> 1)); + $u = \bcdiv($lhs, $m, 0); + $m1 = \bcsub($lhs, \bcmul($u, $m)); + $cache[self::DATA][] = [ + 'u' => $u, + // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1' => $m1, + ]; + } else { + \extract($cache[self::DATA][$key]); + } + $cutoff = $m_length + ($m_length >> 1); + $lsd = \substr($n, -$cutoff); + $msd = \substr($n, 0, -$cutoff); + $temp = \bcmul($msd, $m1); + // m.length + (m.length >> 1) + $n = \bcadd($lsd, $temp); + // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n, $m); + //} + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = \substr($n, 0, -$m_length + 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = \bcmul($temp, $u); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = \substr($temp, 0, -($m_length >> 1) - 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = \bcmul($temp, $m); + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + $result = \bcsub($n, $temp); + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $temp = '1' . \str_repeat('0', $m_length + 1); + $result = \bcadd($result, $temp); + } + while (\bccomp($result, $m) >= 0) { + $result = \bcsub($result, $m); + } + return $result; + } + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param string $x + * @param string $n + * @return string + */ + private static function regularBarrett($x, $n) + { + static $cache = [self::VARIABLE => [], self::DATA => []]; + $n_length = \strlen($n); + if (\strlen($x) > 2 * $n_length) { + return \bcmod($x, $n); + } + if (($key = \array_search($n, $cache[self::VARIABLE])) === \false) { + $key = \count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = '1' . \str_repeat('0', 2 * $n_length); + $cache[self::DATA][] = \bcdiv($lhs, $n, 0); + } + $temp = \substr($x, 0, -$n_length + 1); + $temp = \bcmul($temp, $cache[self::DATA][$key]); + $temp = \substr($temp, 0, -$n_length - 1); + $r1 = \substr($x, -$n_length - 1); + $r2 = \substr(\bcmul($temp, $n), -$n_length - 1); + $result = \bcsub($r1, $r2); + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $q = '1' . \str_repeat('0', $n_length + 1); + $result = \bcadd($result, $q); + } + while (\bccomp($result, $n) >= 0) { + $result = \bcsub($result, $n); + } + return $result; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php new file mode 100644 index 0000000..f743b92 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php @@ -0,0 +1,96 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Base; +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class EvalBarrett extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath\Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param string $n + * @param string $m + * @return string + */ + protected static function reduce($n, $m) + { + $inline = self::$custom_reduction; + return $inline($n); + } + /** + * Generate Custom Reduction + * + * @param BCMath $m + * @param string $class + * @return callable|void + */ + protected static function generateCustomReduction(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\BCMath $m, $class) + { + $m_length = \strlen($m); + if ($m_length < 5) { + $code = 'return bcmod($x, $n);'; + eval('$func = function ($n) { ' . $code . '};'); + self::$custom_reduction = $func; + return; + } + $lhs = '1' . \str_repeat('0', $m_length + ($m_length >> 1)); + $u = \bcdiv($lhs, $m, 0); + $m1 = \bcsub($lhs, \bcmul($u, $m)); + $cutoff = $m_length + ($m_length >> 1); + $m = "'{$m}'"; + $u = "'{$u}'"; + $m1 = "'{$m1}'"; + $code = ' + $lsd = substr($n, -' . $cutoff . '); + $msd = substr($n, 0, -' . $cutoff . '); + + $temp = bcmul($msd, ' . $m1 . '); + $n = bcadd($lsd, $temp); + + $temp = substr($n, 0, ' . (-$m_length + 1) . '); + $temp = bcmul($temp, ' . $u . '); + $temp = substr($temp, 0, ' . (-($m_length >> 1) - 1) . '); + $temp = bcmul($temp, ' . $m . '); + + $result = bcsub($n, $temp); + + if ($result[0] == \'-\') { + $temp = \'1' . \str_repeat('0', $m_length + 1) . '\'; + $result = bcadd($result, $temp); + } + + while (bccomp($result, ' . $m . ') >= 0) { + $result = bcsub($result, ' . $m . '); + } + + return $result;'; + eval('$func = function ($n) { ' . $code . '};'); + self::$custom_reduction = $func; + return $func; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php new file mode 100644 index 0000000..a40e7ae --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php @@ -0,0 +1,1142 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Crypt\Random; +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * Base Engine. + * + * @author Jim Wigginton + */ +abstract class Engine implements \JsonSerializable +{ + /* final protected */ + const PRIMES = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; + /** + * BigInteger(0) + * + * @var array, static> + */ + protected static $zero = []; + /** + * BigInteger(1) + * + * @var array, static> + */ + protected static $one = []; + /** + * BigInteger(2) + * + * @var array, static> + */ + protected static $two = []; + /** + * Modular Exponentiation Engine + * + * @var array, class-string> + */ + protected static $modexpEngine; + /** + * Engine Validity Flag + * + * @var array, bool> + */ + protected static $isValidEngine; + /** + * Holds the BigInteger's value + * + * @var \GMP|string|array|int + */ + protected $value; + /** + * Holds the BigInteger's sign + * + * @var bool + */ + protected $is_negative; + /** + * Precision + * + * @see static::setPrecision() + * @var int + */ + protected $precision = -1; + /** + * Precision Bitmask + * + * @see static::setPrecision() + * @var static|false + */ + protected $bitmask = \false; + /** + * Recurring Modulo Function + * + * @var callable + */ + protected $reduce; + /** + * Mode independent value used for serialization. + * + * @see self::__sleep() + * @see self::__wakeup() + * @var string + */ + protected $hex; + /** + * Default constructor + * + * @param int|numeric-string $x integer Base-10 number or base-$base number if $base set. + * @param int $base + */ + public function __construct($x = 0, $base = 10) + { + if (!\array_key_exists(static::class, static::$zero)) { + static::$zero[static::class] = null; + // Placeholder to prevent infinite loop. + static::$zero[static::class] = new static(0); + static::$one[static::class] = new static(1); + static::$two[static::class] = new static(2); + } + // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 + // '0' is the only value like this per http://php.net/empty + if (empty($x) && (\abs($base) != 256 || $x !== '0')) { + return; + } + switch ($base) { + case -256: + case 256: + if ($base == -256 && \ord($x[0]) & 0x80) { + $this->value = ~$x; + $this->is_negative = \true; + } else { + $this->value = $x; + $this->is_negative = \false; + } + $this->initialize($base); + if ($this->is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -16: + case 16: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = \true; + $x = \substr($x, 1); + } + $x = \preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x); + $is_negative = \false; + if ($base < 0 && \hexdec($x[0]) >= 8) { + $this->is_negative = $is_negative = \true; + $x = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex(~\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::hex2bin($x)); + } + $this->value = $x; + $this->initialize($base); + if ($is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -10: + case 10: + // (?value = \preg_replace('#(?value) || $this->value == '-') { + $this->value = '0'; + } + $this->initialize($base); + break; + case -2: + case 2: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = \true; + $x = \substr($x, 1); + } + $x = \preg_replace('#^([01]*).*#', '$1', $x); + $temp = new static(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bits2bin($x), 128 * $base); + // ie. either -16 or +16 + $this->value = $temp->value; + if ($temp->is_negative) { + $this->is_negative = \true; + } + break; + default: + } + } + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param class-string $engine + */ + public static function setModExpEngine($engine) + { + $fqengine = '\\PostSMTP\\Vendor\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; + if (!\class_exists($fqengine) || !\method_exists($fqengine, 'isValidEngine')) { + throw new \InvalidArgumentException("{$engine} is not a valid engine"); + } + if (!$fqengine::isValidEngine()) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException("{$engine} is not setup correctly on this system"); + } + static::$modexpEngine[static::class] = $fqengine; + } + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * @return string + */ + protected function toBytesHelper() + { + $comparison = $this->compare(new static()); + if ($comparison == 0) { + return $this->precision > 0 ? \str_repeat(\chr(0), $this->precision + 1 >> 3) : ''; + } + $temp = $comparison < 0 ? $this->add(new static(1)) : $this; + $bytes = $temp->toBytes(); + if (!\strlen($bytes)) { + // eg. if the number we're trying to convert is -1 + $bytes = \chr(0); + } + if (\ord($bytes[0]) & 0x80) { + $bytes = \chr(0) . $bytes; + } + return $comparison < 0 ? ~$bytes : $bytes; + } + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = \false) + { + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($this->toBytes($twos_compliment)); + } + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = \false) + { + $hex = $this->toBytes($twos_compliment); + $bits = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2bits($hex); + $result = $this->precision > 0 ? \substr($bits, -$this->precision) : \ltrim($bits, '0'); + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $result; + } + return $result; + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} + * + * @param Engine $n + * @return static|false + */ + protected function modInverseHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $n) + { + // $x mod -$n == $x mod $n. + $n = $n->abs(); + if ($this->compare(static::$zero[static::class]) < 0) { + $temp = $this->abs(); + $temp = $temp->modInverse($n); + return $this->normalize($n->subtract($temp)); + } + \extract($this->extendedGCD($n)); + /** + * @var Engine $gcd + * @var Engine $x + */ + if (!$gcd->equals(static::$one[static::class])) { + return \false; + } + $x = $x->compare(static::$zero[static::class]) < 0 ? $x->add($n) : $x; + return $this->compare(static::$zero[static::class]) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); + } + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * @return array + */ + public function __sleep() + { + $this->hex = $this->toHex(\true); + $vars = ['hex']; + if ($this->precision > 0) { + $vars[] = 'precision'; + } + return $vars; + } + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + * + * @return void + */ + public function __wakeup() + { + $temp = new static($this->hex, -16); + $this->value = $temp->value; + $this->is_negative = $temp->is_negative; + if ($this->precision > 0) { + // recalculate $this->bitmask + $this->setPrecision($this->precision); + } + } + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $result = ['hex' => $this->toHex(\true)]; + if ($this->precision > 0) { + $result['precision'] = $this->precision; + } + return $result; + } + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function __toString() + { + return $this->toString(); + } + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + * + * @return array + */ + public function __debugInfo() + { + $result = ['value' => '0x' . $this->toHex(\true), 'engine' => \basename(static::class)]; + return $this->precision > 0 ? $result + ['precision' => $this->precision] : $result; + } + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + if ($bits < 1) { + $this->precision = -1; + $this->bitmask = \false; + return; + } + $this->precision = $bits; + $this->bitmask = static::setBitmask($bits); + $temp = $this->normalize($this); + $this->value = $temp->value; + } + /** + * Get Precision + * + * Returns the precision if it exists, -1 if it doesn't + * + * @return int + */ + public function getPrecision() + { + return $this->precision; + } + /** + * Set Bitmask + * @return static + * @param int $bits + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + return new static(\chr((1 << ($bits & 0x7)) - 1) . \str_repeat(\chr(0xff), $bits >> 3), 256); + } + /** + * Logical Not + * + * @return Engine|string + */ + public function bitwise_not() + { + // calculuate "not" without regard to $this->precision + // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) + $temp = $this->toBytes(); + if ($temp == '') { + return $this->normalize(static::$zero[static::class]); + } + $pre_msb = \decbin(\ord($temp[0])); + $temp = ~$temp; + $msb = \decbin(\ord($temp[0])); + if (\strlen($msb) == 8) { + $msb = \substr($msb, \strpos($msb, '0')); + } + $temp[0] = \chr(\bindec($msb)); + // see if we need to add extra leading 1's + $current_bits = \strlen($pre_msb) + 8 * \strlen($temp) - 8; + $new_bits = $this->precision - $current_bits; + if ($new_bits <= 0) { + return $this->normalize(new static($temp, 256)); + } + // generate as many leading 1's as we need to. + $leading_ones = \chr((1 << ($new_bits & 0x7)) - 1) . \str_repeat(\chr(0xff), $new_bits >> 3); + self::base256_lshift($leading_ones, $current_bits); + $temp = \str_pad($temp, \strlen($leading_ones), \chr(0), \STR_PAD_LEFT); + return $this->normalize(new static($leading_ones | $temp, 256)); + } + /** + * Logical Left Shift + * + * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. + * + * @param string $x + * @param int $shift + * @return void + */ + protected static function base256_lshift(&$x, $shift) + { + if ($shift == 0) { + return; + } + $num_bytes = $shift >> 3; + // eg. floor($shift/8) + $shift &= 7; + // eg. $shift % 8 + $carry = 0; + for ($i = \strlen($x) - 1; $i >= 0; --$i) { + $temp = \ord($x[$i]) << $shift | $carry; + $x[$i] = \chr($temp); + $carry = $temp >> 8; + } + $carry = $carry != 0 ? \chr($carry) : ''; + $x = $carry . $x . \str_repeat(\chr(0), $num_bytes); + } + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return Engine + */ + public function bitwise_leftRotate($shift) + { + $bits = $this->toBytes(); + if ($this->precision > 0) { + $precision = $this->precision; + if (static::FAST_BITWISE) { + $mask = $this->bitmask->toBytes(); + } else { + $mask = $this->bitmask->subtract(new static(1)); + $mask = $mask->toBytes(); + } + } else { + $temp = \ord($bits[0]); + for ($i = 0; $temp >> $i; ++$i) { + } + $precision = 8 * \strlen($bits) - 8 + $i; + $mask = \chr((1 << ($precision & 0x7)) - 1) . \str_repeat(\chr(0xff), $precision >> 3); + } + if ($shift < 0) { + $shift += $precision; + } + $shift %= $precision; + if (!$shift) { + return clone $this; + } + $left = $this->bitwise_leftShift($shift); + $left = $left->bitwise_and(new static($mask, 256)); + $right = $this->bitwise_rightShift($precision - $shift); + $result = static::FAST_BITWISE ? $left->bitwise_or($right) : $left->add($right); + return $this->normalize($result); + } + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return Engine + */ + public function bitwise_rightRotate($shift) + { + return $this->bitwise_leftRotate(-$shift); + } + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return array{min: static, max: static} + */ + public static function minMaxBits($bits) + { + $bytes = $bits >> 3; + $min = \str_repeat(\chr(0), $bytes); + $max = \str_repeat(\chr(0xff), $bytes); + $msb = $bits & 7; + if ($msb) { + $min = \chr(1 << $msb - 1) . $min; + $max = \chr((1 << $msb) - 1) . $max; + } else { + $min[0] = \chr(0x80); + } + return ['min' => new static($min, 256), 'max' => new static($max, 256)]; + } + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return \strlen($this->toBits()); + } + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return \strlen($this->toBytes()); + } + /** + * Performs some pre-processing for powMod + * + * @param Engine $e + * @param Engine $n + * @return static|false + */ + protected function powModOuter(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $n) + { + $n = $this->bitmask !== \false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); + if ($e->compare(new static()) < 0) { + $e = $e->abs(); + $temp = $this->modInverse($n); + if ($temp === \false) { + return \false; + } + return $this->normalize($temp->powModInner($e, $n)); + } + return $this->powModInner($e, $n); + } + /** + * Sliding Window k-ary Modular Exponentiation + * + * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, + * however, this function performs a modular reduction after every multiplication and squaring operation. + * As such, this function has the same preconditions that the reductions being used do. + * + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T + */ + protected static function slidingWindow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $n, $class) + { + static $window_ranges = [7, 25, 81, 241, 673, 1793]; + // from BigInteger.java's oddModPow function + //static $window_ranges = [0, 7, 36, 140, 450, 1303, 3529]; // from MPM 7.3.1 + $e_bits = $e->toBits(); + $e_length = \strlen($e_bits); + // calculate the appropriate window size. + // $window_size == 3 if $window_ranges is between 25 and 81, for example. + for ($i = 0, $window_size = 1; $i < \count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { + } + $n_value = $n->value; + if (\method_exists(static::class, 'generateCustomReduction')) { + static::generateCustomReduction($n, $class); + } + // precompute $this^0 through $this^$window_size + $powers = []; + $powers[1] = static::prepareReduce($x->value, $n_value, $class); + $powers[2] = static::squareReduce($powers[1], $n_value, $class); + // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end + // in a 1. ie. it's supposed to be odd. + $temp = 1 << $window_size - 1; + for ($i = 1; $i < $temp; ++$i) { + $i2 = $i << 1; + $powers[$i2 + 1] = static::multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $class); + } + $result = new $class(1); + $result = static::prepareReduce($result->value, $n_value, $class); + for ($i = 0; $i < $e_length;) { + if (!$e_bits[$i]) { + $result = static::squareReduce($result, $n_value, $class); + ++$i; + } else { + for ($j = $window_size - 1; $j > 0; --$j) { + if (!empty($e_bits[$i + $j])) { + break; + } + } + // eg. the length of substr($e_bits, $i, $j + 1) + for ($k = 0; $k <= $j; ++$k) { + $result = static::squareReduce($result, $n_value, $class); + } + $result = static::multiplyReduce($result, $powers[\bindec(\substr($e_bits, $i, $j + 1))], $n_value, $class); + $i += $j + 1; + } + } + $temp = new $class(); + $temp->value = static::reduce($result, $n_value, $class); + return $temp; + } + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return Engine + */ + public static function random($size) + { + \extract(static::minMaxBits($size)); + /** + * @var BigInteger $min + * @var BigInteger $max + */ + return static::randomRange($min, $max); + } + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return Engine + */ + public static function randomPrime($size) + { + \extract(static::minMaxBits($size)); + /** + * @var static $min + * @var static $max + */ + return static::randomRangePrime($min, $max); + } + /** + * Performs some pre-processing for randomRangePrime + * + * @param Engine $min + * @param Engine $max + * @return static|false + */ + protected static function randomRangePrimeOuter(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $max) + { + $compare = $max->compare($min); + if (!$compare) { + return $min->isPrime() ? $min : \false; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + $x = static::randomRange($min, $max); + return static::randomRangePrimeInner($x, $min, $max); + } + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param Engine $min + * @param Engine $max + * @return Engine + */ + protected static function randomRangeHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $max) + { + $compare = $max->compare($min); + if (!$compare) { + return $min; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + if (!isset(static::$one[static::class])) { + static::$one[static::class] = new static(1); + } + $max = $max->subtract($min->subtract(static::$one[static::class])); + $size = \strlen(\ltrim($max->toBytes(), \chr(0))); + /* + doing $random % $max doesn't work because some numbers will be more likely to occur than others. + eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 + would produce 5 whereas the only value of random that could produce 139 would be 139. ie. + not all numbers would be equally likely. some would be more likely than others. + + creating a whole new random number until you find one that is within the range doesn't work + because, for sufficiently small ranges, the likelihood that you'd get a number within that range + would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability + would be pretty high that $random would be greater than $max. + + phpseclib works around this using the technique described here: + + http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string + */ + $random_max = new static(\chr(1) . \str_repeat("\0", $size), 256); + $random = new static(\PostSMTP\Vendor\phpseclib3\Crypt\Random::string($size), 256); + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + while ($random->compare($max_multiple) >= 0) { + $random = $random->subtract($max_multiple); + $random_max = $random_max->subtract($max_multiple); + $random = $random->bitwise_leftShift(8); + $random = $random->add(new static(\PostSMTP\Vendor\phpseclib3\Crypt\Random::string(1), 256)); + $random_max = $random_max->bitwise_leftShift(8); + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + } + list(, $random) = $random->divide($max); + return $random->add($min); + } + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return static|false + */ + protected static function randomRangePrimeInner(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $max) + { + if (!isset(static::$two[static::class])) { + static::$two[static::class] = new static('2'); + } + $x->make_odd(); + if ($x->compare($max) > 0) { + // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range + if ($min->equals($max)) { + return \false; + } + $x = clone $min; + $x->make_odd(); + } + $initial_x = clone $x; + while (\true) { + if ($x->isPrime()) { + return $x; + } + $x = $x->add(static::$two[static::class]); + if ($x->compare($max) > 0) { + $x = clone $min; + if ($x->equals(static::$two[static::class])) { + return $x; + } + $x->make_odd(); + } + if ($x->equals($initial_x)) { + return \false; + } + } + } + /** + * Sets the $t parameter for primality testing + * + * @return int + */ + protected function setupIsPrime() + { + $length = $this->getLengthInBytes(); + // see HAC 4.49 "Note (controlling the error probability)" + // @codingStandardsIgnoreStart + if ($length >= 163) { + $t = 2; + } else { + if ($length >= 106) { + $t = 3; + } else { + if ($length >= 81) { + $t = 4; + } else { + if ($length >= 68) { + $t = 5; + } else { + if ($length >= 56) { + $t = 6; + } else { + if ($length >= 50) { + $t = 7; + } else { + if ($length >= 43) { + $t = 8; + } else { + if ($length >= 37) { + $t = 9; + } else { + if ($length >= 31) { + $t = 12; + } else { + if ($length >= 25) { + $t = 15; + } else { + if ($length >= 18) { + $t = 18; + } else { + $t = 27; + } + } + } + } + } + } + } + } + } + } + } + // @codingStandardsIgnoreEnd + return $t; + } + /** + * Tests Primality + * + * Uses the {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24} for more info. + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + if (!$this->testSmallPrimes()) { + return \false; + } + $n = clone $this; + $n_1 = $n->subtract(static::$one[static::class]); + $n_2 = $n->subtract(static::$two[static::class]); + $r = clone $n_1; + $s = static::scan1divide($r); + for ($i = 0; $i < $t; ++$i) { + $a = static::randomRange(static::$two[static::class], $n_2); + $y = $a->modPow($r, $n); + if (!$y->equals(static::$one[static::class]) && !$y->equals($n_1)) { + for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { + $y = $y->modPow(static::$two[static::class], $n); + if ($y->equals(static::$one[static::class])) { + return \false; + } + } + if (!$y->equals($n_1)) { + return \false; + } + } + } + return \true; + } + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = \false) + { + if (!$t) { + $t = $this->setupIsPrime(); + } + return $this->testPrimality($t); + } + /** + * Performs a few preliminary checks on root + * + * @param int $n + * @return Engine + */ + protected function rootHelper($n) + { + if ($n < 1) { + return clone static::$zero[static::class]; + } + // we want positive exponents + if ($this->compare(static::$one[static::class]) < 0) { + return clone static::$zero[static::class]; + } + // we want positive numbers + if ($this->compare(static::$two[static::class]) < 0) { + return clone static::$one[static::class]; + } + // n-th root of 1 or 2 is 1 + return $this->rootInner($n); + } + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} + * + * @param int $n + * @return Engine + */ + protected function rootInner($n) + { + $n = new static($n); + // g is our guess number + $g = static::$two[static::class]; + // while (g^n < num) g=g*2 + while ($g->pow($n)->compare($this) < 0) { + $g = $g->multiply(static::$two[static::class]); + } + // if (g^n==num) num is a power of 2, we're lucky, end of job + // == 0 bccomp(bcpow($g, $n), $n->value)==0 + if ($g->pow($n)->equals($this) > 0) { + $root = $g; + return $this->normalize($root); + } + // if we're here num wasn't a power of 2 :( + $og = $g; + // og means original guess and here is our upper bound + $g = $g->divide(static::$two[static::class])[0]; + // g is set to be our lower bound + $step = $og->subtract($g)->divide(static::$two[static::class])[0]; + // step is the half of upper bound - lower bound + $g = $g->add($step); + // we start at lower bound + step , basically in the middle of our interval + // while step>1 + while ($step->compare(static::$one[static::class]) == 1) { + $guess = $g->pow($n); + $step = $step->divide(static::$two[static::class])[0]; + $comp = $guess->compare($this); + // compare our guess with real number + switch ($comp) { + case -1: + // if guess is lower we add the new step + $g = $g->add($step); + break; + case 1: + // if guess is higher we sub the new step + $g = $g->subtract($step); + break; + case 0: + // if guess is exactly the num we're done, we return the value + $root = $g; + break 2; + } + } + if ($comp == 1) { + $g = $g->subtract($step); + } + // whatever happened, g is the closest guess we can make so return it + $root = $g; + return $this->normalize($root); + } + /** + * Calculates the nth root of a biginteger. + * + * @param int $n + * @return Engine + */ + public function root($n = 2) + { + return $this->rootHelper($n); + } + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function minHelper(array $nums) + { + if (\count($nums) == 1) { + return $nums[0]; + } + $min = $nums[0]; + for ($i = 1; $i < \count($nums); $i++) { + $min = $min->compare($nums[$i]) > 0 ? $nums[$i] : $min; + } + return $min; + } + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function maxHelper(array $nums) + { + if (\count($nums) == 1) { + return $nums[0]; + } + $max = $nums[0]; + for ($i = 1; $i < \count($nums); $i++) { + $max = $max->compare($nums[$i]) < 0 ? $nums[$i] : $max; + } + return $max; + } + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $class = static::class; + $fqengine = !\method_exists(static::$modexpEngine[static::class], 'reduce') ? '\\PostSMTP\\Vendor\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : static::$modexpEngine[static::class]; + if (\method_exists($fqengine, 'generateCustomReduction')) { + $func = $fqengine::generateCustomReduction($this, static::class); + return eval('return function(' . static::class . ' $x) use ($func, $class) { + $r = new $class(); + $r->value = $func($x->value); + return $r; + };'); + } + $n = $this->value; + return eval('return function(' . static::class . ' $x) use ($n, $fqengine, $class) { + $r = new $class(); + $r->value = $fqengine::reduce($x->value, $n, $class); + return $r; + };'); + } + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * @param Engine $n + * @return array{gcd: Engine, x: Engine, y: Engine} + */ + protected function extendedGCDHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $n) + { + $u = clone $this; + $v = clone $n; + $one = new static(1); + $zero = new static(); + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + } + return ['gcd' => $u, 'x' => $a, 'y' => $b]; + } + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return Engine[] + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + $mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]); + $num = clone $this; + $vals = []; + while (!$num->equals(static::$zero[static::class])) { + $vals[] = $num->bitwise_and($mask); + $num = $num->bitwise_rightShift($split); + } + return \array_reverse($vals); + } + /** + * Logical And + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseAndHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x) + { + $left = $this->toBytes(\true); + $right = $x->toBytes(\true); + $length = \max(\strlen($left), \strlen($right)); + $left = \str_pad($left, $length, \chr(0), \STR_PAD_LEFT); + $right = \str_pad($right, $length, \chr(0), \STR_PAD_LEFT); + return $this->normalize(new static($left & $right, -256)); + } + /** + * Logical Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseOrHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x) + { + $left = $this->toBytes(\true); + $right = $x->toBytes(\true); + $length = \max(\strlen($left), \strlen($right)); + $left = \str_pad($left, $length, \chr(0), \STR_PAD_LEFT); + $right = \str_pad($right, $length, \chr(0), \STR_PAD_LEFT); + return $this->normalize(new static($left | $right, -256)); + } + /** + * Logical Exclusive Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseXorHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x) + { + $left = $this->toBytes(\true); + $right = $x->toBytes(\true); + $length = \max(\strlen($left), \strlen($right)); + $left = \str_pad($left, $length, \chr(0), \STR_PAD_LEFT); + $right = \str_pad($right, $length, \chr(0), \STR_PAD_LEFT); + return $this->normalize(new static($left ^ $right, -256)); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php new file mode 100644 index 0000000..e6af962 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php @@ -0,0 +1,612 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines; + +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +/** + * GMP Engine. + * + * @author Jim Wigginton + */ +class GMP extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = \true; + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'GMP'; + /** + * Test for engine validity + * + * @return bool + * @see parent::__construct() + */ + public static function isValidEngine() + { + return \extension_loaded('gmp'); + } + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException('GMP is not setup correctly on this system'); + } + if ($x instanceof \GMP) { + $this->value = $x; + return; + } + $this->value = \gmp_init(0); + parent::__construct($x, $base); + } + /** + * Initialize a GMP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (\abs($base)) { + case 256: + $this->value = \gmp_import($this->value); + if ($this->is_negative) { + $this->value = -$this->value; + } + break; + case 16: + $temp = $this->is_negative ? '-0x' . $this->value : '0x' . $this->value; + $this->value = \gmp_init($temp); + break; + case 10: + $this->value = \gmp_init(isset($this->value) ? $this->value : '0'); + } + } + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return (string) $this->value; + } + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = \false) + { + $hex = $this->toHex($twos_compliment); + $bits = \gmp_strval(\gmp_init($hex, 16), 2); + if ($this->precision > 0) { + $bits = \substr($bits, -$this->precision); + } + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $bits; + } + return $bits; + } + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = \false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + if (\gmp_cmp($this->value, \gmp_init(0)) == 0) { + return $this->precision > 0 ? \str_repeat(\chr(0), $this->precision + 1 >> 3) : ''; + } + $temp = \gmp_export($this->value); + return $this->precision > 0 ? \substr(\str_pad($temp, $this->precision >> 3, \chr(0), \STR_PAD_LEFT), -($this->precision >> 3)) : \ltrim($temp, \chr(0)); + } + /** + * Adds two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function add(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $y) + { + $temp = new self(); + $temp->value = $this->value + $y->value; + return $this->normalize($temp); + } + /** + * Subtracts two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function subtract(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $y) + { + $temp = new self(); + $temp->value = $this->value - $y->value; + return $this->normalize($temp); + } + /** + * Multiplies two BigIntegers. + * + * @param GMP $x + * @return GMP + */ + public function multiply(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $x) + { + $temp = new self(); + $temp->value = $this->value * $x->value; + return $this->normalize($temp); + } + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param GMP $y + * @return array{GMP, GMP} + */ + public function divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $y) + { + $quotient = new self(); + $remainder = new self(); + list($quotient->value, $remainder->value) = \gmp_div_qr($this->value, $y->value); + if (\gmp_sign($remainder->value) < 0) { + $remainder->value = $remainder->value + \gmp_abs($y->value); + } + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param GMP $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $y) + { + $r = \gmp_cmp($this->value, $y->value); + if ($r < -1) { + $r = -1; + } + if ($r > 1) { + $r = 1; + } + return $r; + } + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param GMP $x + * @return bool + */ + public function equals(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $x) + { + return $this->value == $x->value; + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param GMP $n + * @return false|GMP + */ + public function modInverse(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + $temp = new self(); + $temp->value = \gmp_invert($this->value, $n->value); + return $temp->value === \false ? \false : $this->normalize($temp); + } + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param GMP $n + * @return GMP[] + */ + public function extendedGCD(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + \extract(\gmp_gcdext($this->value, $n->value)); + return ['gcd' => $this->normalize(new self($g)), 'x' => $this->normalize(new self($s)), 'y' => $this->normalize(new self($t))]; + } + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param GMP $n + * @return GMP + */ + public function gcd(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + $r = \gmp_gcd($this->value, $n->value); + return $this->normalize(new self($r)); + } + /** + * Absolute value. + * + * @return GMP + */ + public function abs() + { + $temp = new self(); + $temp->value = \gmp_abs($this->value); + return $temp; + } + /** + * Logical And + * + * @param GMP $x + * @return GMP + */ + public function bitwise_and(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $x) + { + $temp = new self(); + $temp->value = $this->value & $x->value; + return $this->normalize($temp); + } + /** + * Logical Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_or(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $x) + { + $temp = new self(); + $temp->value = $this->value | $x->value; + return $this->normalize($temp); + } + /** + * Logical Exclusive Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_xor(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $x) + { + $temp = new self(); + $temp->value = $this->value ^ $x->value; + return $this->normalize($temp); + } + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return GMP + */ + public function bitwise_rightShift($shift) + { + // 0xFFFFFFFF >> 2 == -1 (on 32-bit systems) + // gmp_init('0xFFFFFFFF') >> 2 == gmp_init('0x3FFFFFFF') + $temp = new self(); + $temp->value = $this->value >> $shift; + return $this->normalize($temp); + } + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return GMP + */ + public function bitwise_leftShift($shift) + { + $temp = new self(); + $temp->value = $this->value << $shift; + return $this->normalize($temp); + } + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function modPow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + return $this->powModOuter($e, $n); + } + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function powMod(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + return $this->powModOuter($e, $n); + } + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected function powModInner(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n); + } + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param GMP $result + * @return GMP + */ + protected function normalize(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + if ($result->bitmask !== \false) { + $flip = $result->value < 0; + if ($flip) { + $result->value = -$result->value; + } + $result->value = $result->value & $result->bitmask->value; + if ($flip) { + $result->value = -$result->value; + } + } + return $result; + } + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return GMP + */ + protected static function randomRangePrimeInner(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $max) + { + $p = \gmp_nextprime($x->value); + if ($p <= $max->value) { + return new self($p); + } + if ($min->value != $x->value) { + $x = new self($x->value - 1); + } + return self::randomRangePrime($min, $x); + } + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param GMP $min + * @param GMP $max + * @return false|GMP + */ + public static function randomRangePrime(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $max) + { + return self::randomRangePrimeOuter($min, $max); + } + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param GMP $min + * @param GMP $max + * @return GMP + */ + public static function randomRange(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $max) + { + return self::randomRangeHelper($min, $max); + } + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + \gmp_setbit($this->value, 0); + } + /** + * Tests Primality + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + return \gmp_prob_prime($this->value, $t) != 0; + } + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n + * @return GMP + */ + protected function rootInner($n) + { + $root = new self(); + $root->value = \gmp_root($this->value, $n); + return $this->normalize($root); + } + /** + * Performs exponentiation. + * + * @param GMP $n + * @return GMP + */ + public function pow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + $temp = new self(); + $temp->value = $this->value ** $n->value; + return $this->normalize($temp); + } + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function min(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP ...$nums) + { + return self::minHelper($nums); + } + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function max(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP ...$nums) + { + return self::maxHelper($nums); + } + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param GMP $min + * @param GMP $max + * @return bool + */ + public function between(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $temp = $this->value; + return function (\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $x) use($temp) { + return new \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP($x->value % $temp); + }; + } + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param GMP $r + * @return int + */ + public static function scan1divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $r) + { + $s = \gmp_scan1($r->value, 0); + $r->value >>= $s; + return $s; + } + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return \gmp_testbit($this->value, 0); + } + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + return \gmp_testbit($this->value, $x); + } + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return \gmp_sign($this->value) == -1; + } + /** + * Negate + * + * Given $k, returns -$k + * + * @return GMP + */ + public function negate() + { + $temp = clone $this; + $temp->value = -$this->value; + return $temp; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php new file mode 100644 index 0000000..beb528d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php @@ -0,0 +1,37 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP; +/** + * GMP Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP +{ + /** + * Performs modular exponentiation. + * + * @param GMP $x + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected static function powModHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP $n) + { + $temp = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\GMP(); + $temp->value = \gmp_powm($x->value, $e->value, $n->value); + return $x->normalize($temp); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php new file mode 100644 index 0000000..f30e8f9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines; + +use PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return \extension_loaded('openssl') && static::class != __CLASS__; + } + /** + * Performs modular exponentiation. + * + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @return Engine + */ + public static function powModHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $n) + { + if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { + throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); + } + $key = \PostSMTP\Vendor\phpseclib3\Crypt\RSA\Formats\Keys\PKCS8::savePublicKey(new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($n), new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($e)); + $plaintext = \str_pad($x->toBytes(), $n->getLengthInBytes(), "\0", \STR_PAD_LEFT); + // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it + // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line" + // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what + // about odd numbers divisible by 3, by 5, etc? + if (!\openssl_public_encrypt($plaintext, $result, $key, \OPENSSL_NO_PADDING)) { + throw new \UnexpectedValueException(\openssl_error_string()); + } + $class = \get_class($x); + return new $class($result, 256); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php new file mode 100644 index 0000000..6d0c0d5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php @@ -0,0 +1,1086 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException; +/** + * Pure-PHP Engine. + * + * @author Jim Wigginton + */ +abstract class PHP extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine +{ + /**#@+ + * Array constants + * + * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and + * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. + * + */ + /** + * $result[self::VALUE] contains the value. + */ + const VALUE = 0; + /** + * $result[self::SIGN] contains the sign. + */ + const SIGN = 1; + /**#@-*/ + /** + * Karatsuba Cutoff + * + * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? + * + */ + const KARATSUBA_CUTOFF = 25; + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = \true; + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'PHP'; + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @return PHP + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = static::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new \PostSMTP\Vendor\phpseclib3\Exception\BadConfigurationException(static::class . ' is not setup correctly on this system'); + } + $this->value = []; + parent::__construct($x, $base); + } + /** + * Initialize a PHP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (\abs($base)) { + case 16: + $x = \strlen($this->value) & 1 ? '0' . $this->value : $this->value; + $temp = new static(\PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::hex2bin($x), 256); + $this->value = $temp->value; + break; + case 10: + $temp = new static(); + $multiplier = new static(); + $multiplier->value = [static::MAX10]; + $x = $this->value; + if ($x[0] == '-') { + $this->is_negative = \true; + $x = \substr($x, 1); + } + $x = \str_pad($x, \strlen($x) + (static::MAX10LEN - 1) * \strlen($x) % static::MAX10LEN, 0, \STR_PAD_LEFT); + while (\strlen($x)) { + $temp = $temp->multiply($multiplier); + $temp = $temp->add(new static($this->int2bytes(\substr($x, 0, static::MAX10LEN)), 256)); + $x = \substr($x, static::MAX10LEN); + } + $this->value = $temp->value; + } + } + /** + * Pads strings so that unpack may be used on them + * + * @param string $str + * @return string + */ + protected function pad($str) + { + $length = \strlen($str); + $pad = 4 - \strlen($str) % 4; + return \str_pad($str, $length + $pad, "\0", \STR_PAD_LEFT); + } + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if (!\count($this->value)) { + return '0'; + } + $temp = clone $this; + $temp->bitmask = \false; + $temp->is_negative = \false; + $divisor = new static(); + $divisor->value = [static::MAX10]; + $result = ''; + while (\count($temp->value)) { + list($temp, $mod) = $temp->divide($divisor); + $result = \str_pad(isset($mod->value[0]) ? $mod->value[0] : '', static::MAX10LEN, '0', \STR_PAD_LEFT) . $result; + } + $result = \ltrim($result, '0'); + if (empty($result)) { + $result = '0'; + } + if ($this->is_negative) { + $result = '-' . $result; + } + return $result; + } + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = \false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + if (!\count($this->value)) { + return $this->precision > 0 ? \str_repeat(\chr(0), $this->precision + 1 >> 3) : ''; + } + $result = $this->bitwise_small_split(8); + $result = \implode('', \array_map('chr', $result)); + return $this->precision > 0 ? \str_pad(\substr($result, -($this->precision + 7 >> 3)), $this->precision + 7 >> 3, \chr(0), \STR_PAD_LEFT) : $result; + } + /** + * Performs addition. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function addHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = \count($x_value); + $y_size = \count($y_value); + if ($x_size == 0) { + return [self::VALUE => $y_value, self::SIGN => $y_negative]; + } elseif ($y_size == 0) { + return [self::VALUE => $x_value, self::SIGN => $x_negative]; + } + // subtract, if appropriate + if ($x_negative != $y_negative) { + if ($x_value == $y_value) { + return [self::VALUE => [], self::SIGN => \false]; + } + $temp = self::subtractHelper($x_value, \false, $y_value, \false); + $temp[self::SIGN] = self::compareHelper($x_value, \false, $y_value, \false) > 0 ? $x_negative : $y_negative; + return $temp; + } + if ($x_size < $y_size) { + $size = $x_size; + $value = $y_value; + } else { + $size = $y_size; + $value = $x_value; + } + $value[\count($value)] = 0; + // just in case the carry adds an extra digit + $carry = 0; + for ($i = 0, $j = 1; $j < $size; $i += 2, $j += 2) { + //$sum = $x_value[$j] * static::BASE_FULL + $x_value[$i] + $y_value[$j] * static::BASE_FULL + $y_value[$i] + $carry; + $sum = ($x_value[$j] + $y_value[$j]) * static::BASE_FULL + $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::MAX_DIGIT2; + // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum - static::MAX_DIGIT2 : $sum; + $temp = static::BASE === 26 ? \intval($sum / 0x4000000) : $sum >> 31; + $value[$i] = (int) ($sum - static::BASE_FULL * $temp); + // eg. a faster alternative to fmod($sum, 0x4000000) + $value[$j] = $temp; + } + if ($j == $size) { + // ie. if $y_size is odd + $sum = $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::BASE_FULL; + $value[$i] = $carry ? $sum - static::BASE_FULL : $sum; + ++$i; + // ie. let $i = $j since we've just done $value[$i] + } + if ($carry) { + for (; $value[$i] == static::MAX_DIGIT; ++$i) { + $value[$i] = 0; + } + ++$value[$i]; + } + return [self::VALUE => self::trim($value), self::SIGN => $x_negative]; + } + /** + * Performs subtraction. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + public static function subtractHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = \count($x_value); + $y_size = \count($y_value); + if ($x_size == 0) { + return [self::VALUE => $y_value, self::SIGN => !$y_negative]; + } elseif ($y_size == 0) { + return [self::VALUE => $x_value, self::SIGN => $x_negative]; + } + // add, if appropriate (ie. -$x - +$y or +$x - -$y) + if ($x_negative != $y_negative) { + $temp = self::addHelper($x_value, \false, $y_value, \false); + $temp[self::SIGN] = $x_negative; + return $temp; + } + $diff = self::compareHelper($x_value, $x_negative, $y_value, $y_negative); + if (!$diff) { + return [self::VALUE => [], self::SIGN => \false]; + } + // switch $x and $y around, if appropriate. + if (!$x_negative && $diff < 0 || $x_negative && $diff > 0) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + $x_negative = !$x_negative; + $x_size = \count($x_value); + $y_size = \count($y_value); + } + // at this point, $x_value should be at least as big as - if not bigger than - $y_value + $carry = 0; + for ($i = 0, $j = 1; $j < $y_size; $i += 2, $j += 2) { + $sum = ($x_value[$j] - $y_value[$j]) * static::BASE_FULL + $x_value[$i] - $y_value[$i] - $carry; + $carry = $sum < 0; + // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum + static::MAX_DIGIT2 : $sum; + $temp = static::BASE === 26 ? \intval($sum / 0x4000000) : $sum >> 31; + $x_value[$i] = (int) ($sum - static::BASE_FULL * $temp); + $x_value[$j] = $temp; + } + if ($j == $y_size) { + // ie. if $y_size is odd + $sum = $x_value[$i] - $y_value[$i] - $carry; + $carry = $sum < 0; + $x_value[$i] = $carry ? $sum + static::BASE_FULL : $sum; + ++$i; + } + if ($carry) { + for (; !$x_value[$i]; ++$i) { + $x_value[$i] = static::MAX_DIGIT; + } + --$x_value[$i]; + } + return [self::VALUE => self::trim($x_value), self::SIGN => $x_negative]; + } + /** + * Performs multiplication. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function multiplyHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + //if ( $x_value == $y_value ) { + // return [ + // self::VALUE => self::square($x_value), + // self::SIGN => $x_sign != $y_value + // ]; + //} + $x_length = \count($x_value); + $y_length = \count($y_value); + if (!$x_length || !$y_length) { + // a 0 is being multiplied + return [self::VALUE => [], self::SIGN => \false]; + } + return [self::VALUE => \min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? self::trim(self::regularMultiply($x_value, $y_value)) : self::trim(self::karatsuba($x_value, $y_value)), self::SIGN => $x_negative != $y_negative]; + } + /** + * Performs Karatsuba multiplication on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + private static function karatsuba(array $x_value, array $y_value) + { + $m = \min(\count($x_value) >> 1, \count($y_value) >> 1); + if ($m < self::KARATSUBA_CUTOFF) { + return self::regularMultiply($x_value, $y_value); + } + $x1 = \array_slice($x_value, $m); + $x0 = \array_slice($x_value, 0, $m); + $y1 = \array_slice($y_value, $m); + $y0 = \array_slice($y_value, 0, $m); + $z2 = self::karatsuba($x1, $y1); + $z0 = self::karatsuba($x0, $y0); + $z1 = self::addHelper($x1, \false, $x0, \false); + $temp = self::addHelper($y1, \false, $y0, \false); + $z1 = self::karatsuba($z1[self::VALUE], $temp[self::VALUE]); + $temp = self::addHelper($z2, \false, $z0, \false); + $z1 = self::subtractHelper($z1, \false, $temp[self::VALUE], \false); + $z2 = \array_merge(\array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = \array_merge(\array_fill(0, $m, 0), $z1[self::VALUE]); + $xy = self::addHelper($z2, \false, $z1[self::VALUE], $z1[self::SIGN]); + $xy = self::addHelper($xy[self::VALUE], $xy[self::SIGN], $z0, \false); + return $xy[self::VALUE]; + } + /** + * Performs long multiplication on two BigIntegers + * + * Modeled after 'multiply' in MutableBigInteger.java. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + protected static function regularMultiply(array $x_value, array $y_value) + { + $x_length = \count($x_value); + $y_length = \count($y_value); + if (!$x_length || !$y_length) { + // a 0 is being multiplied + return []; + } + $product_value = self::array_repeat(0, $x_length + $y_length); + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + $carry = 0; + for ($j = 0; $j < $x_length; ++$j) { + // ie. $i = 0 + $temp = $x_value[$j] * $y_value[0] + $carry; + // $product_value[$k] == 0 + $carry = static::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31; + $product_value[$j] = (int) ($temp - static::BASE_FULL * $carry); + } + $product_value[$j] = $carry; + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = static::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31; + $product_value[$k] = (int) ($temp - static::BASE_FULL * $carry); + } + $product_value[$k] = $carry; + } + return $product_value; + } + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @return array{static, static} + * @internal This function is based off of + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. + */ + protected function divideHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $y) + { + if (\count($y->value) == 1) { + list($q, $r) = $this->divide_digit($this->value, $y->value[0]); + $quotient = new static(); + $remainder = new static(); + $quotient->value = $q; + $remainder->value = [$r]; + $quotient->is_negative = $this->is_negative != $y->is_negative; + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + $x = clone $this; + $y = clone $y; + $x_sign = $x->is_negative; + $y_sign = $y->is_negative; + $x->is_negative = $y->is_negative = \false; + $diff = $x->compare($y); + if (!$diff) { + $temp = new static(); + $temp->value = [1]; + $temp->is_negative = $x_sign != $y_sign; + return [$this->normalize($temp), $this->normalize(static::$zero[static::class])]; + } + if ($diff < 0) { + // if $x is negative, "add" $y. + if ($x_sign) { + $x = $y->subtract($x); + } + return [$this->normalize(static::$zero[static::class]), $this->normalize($x)]; + } + // normalize $x and $y as described in HAC 14.23 / 14.24 + $msb = $y->value[\count($y->value) - 1]; + for ($shift = 0; !($msb & static::MSB); ++$shift) { + $msb <<= 1; + } + $x->lshift($shift); + $y->lshift($shift); + $y_value =& $y->value; + $x_max = \count($x->value) - 1; + $y_max = \count($y->value) - 1; + $quotient = new static(); + $quotient_value =& $quotient->value; + $quotient_value = self::array_repeat(0, $x_max - $y_max + 1); + static $temp, $lhs, $rhs; + if (!isset($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + if (static::class != \get_class($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + $temp_value =& $temp->value; + $rhs_value =& $rhs->value; + // $temp = $y << ($x_max - $y_max-1) in base 2**26 + $temp_value = \array_merge(self::array_repeat(0, $x_max - $y_max), $y_value); + while ($x->compare($temp) >= 0) { + // calculate the "common residue" + ++$quotient_value[$x_max - $y_max]; + $x = $x->subtract($temp); + $x_max = \count($x->value) - 1; + } + for ($i = $x_max; $i >= $y_max + 1; --$i) { + $x_value =& $x->value; + $x_window = [isset($x_value[$i]) ? $x_value[$i] : 0, isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0]; + $y_window = [$y_value[$y_max], $y_max > 0 ? $y_value[$y_max - 1] : 0]; + $q_index = $i - $y_max - 1; + if ($x_window[0] == $y_window[0]) { + $quotient_value[$q_index] = static::MAX_DIGIT; + } else { + $quotient_value[$q_index] = self::safe_divide($x_window[0] * static::BASE_FULL + $x_window[1], $y_window[0]); + } + $temp_value = [$y_window[1], $y_window[0]]; + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + $rhs_value = [$x_window[2], $x_window[1], $x_window[0]]; + while ($lhs->compare($rhs) > 0) { + --$quotient_value[$q_index]; + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + } + $adjust = self::array_repeat(0, $q_index); + $temp_value = [$quotient_value[$q_index]]; + $temp = $temp->multiply($y); + $temp_value =& $temp->value; + if (\count($temp_value)) { + $temp_value = \array_merge($adjust, $temp_value); + } + $x = $x->subtract($temp); + if ($x->compare(static::$zero[static::class]) < 0) { + $temp_value = \array_merge($adjust, $y_value); + $x = $x->add($temp); + --$quotient_value[$q_index]; + } + $x_max = \count($x_value) - 1; + } + // unnormalize the remainder + $x->rshift($shift); + $quotient->is_negative = $x_sign != $y_sign; + // calculate the "common residue", if appropriate + if ($x_sign) { + $y->rshift($shift); + $x = $y->subtract($x); + } + return [$this->normalize($quotient), $this->normalize($x)]; + } + /** + * Divides a BigInteger by a regular integer + * + * abc / x = a00 / x + b0 / x + c / x + * + * @param array $dividend + * @param int $divisor + * @return array + */ + private static function divide_digit(array $dividend, $divisor) + { + $carry = 0; + $result = []; + for ($i = \count($dividend) - 1; $i >= 0; --$i) { + $temp = static::BASE_FULL * $carry + $dividend[$i]; + $result[$i] = self::safe_divide($temp, $divisor); + $carry = (int) ($temp - $divisor * $result[$i]); + } + return [$result, $carry]; + } + /** + * Single digit division + * + * Even if int64 is being used the division operator will return a float64 value + * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't + * have the precision of int64 this is a problem so, when int64 is being used, + * we'll guarantee that the dividend is divisible by first subtracting the remainder. + * + * @param int $x + * @param int $y + * @return int + */ + private static function safe_divide($x, $y) + { + if (static::BASE === 26) { + return (int) ($x / $y); + } + // static::BASE === 31 + /** @var int */ + return ($x - $x % $y) / $y; + } + /** + * Convert an array / boolean to a PHP BigInteger object + * + * @param array $arr + * @return static + */ + protected function convertToObj(array $arr) + { + $result = new static(); + $result->value = $arr[self::VALUE]; + $result->is_negative = $arr[self::SIGN]; + return $this->normalize($result); + } + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param PHP $result + * @return static + */ + protected function normalize(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + $value =& $result->value; + if (!\count($value)) { + $result->is_negative = \false; + return $result; + } + $value = static::trim($value); + if (!empty($result->bitmask->value)) { + $length = \min(\count($value), \count($result->bitmask->value)); + $value = \array_slice($value, 0, $length); + for ($i = 0; $i < $length; ++$i) { + $value[$i] = $value[$i] & $result->bitmask->value[$i]; + } + $value = static::trim($value); + } + return $result; + } + /** + * Compares two numbers. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return int + * @see static::compare() + */ + protected static function compareHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + if ($x_negative != $y_negative) { + return !$x_negative && $y_negative ? 1 : -1; + } + $result = $x_negative ? -1 : 1; + if (\count($x_value) != \count($y_value)) { + return \count($x_value) > \count($y_value) ? $result : -$result; + } + $size = \max(\count($x_value), \count($y_value)); + $x_value = \array_pad($x_value, $size, 0); + $y_value = \array_pad($y_value, $size, 0); + for ($i = \count($x_value) - 1; $i >= 0; --$i) { + if ($x_value[$i] != $y_value[$i]) { + return $x_value[$i] > $y_value[$i] ? $result : -$result; + } + } + return 0; + } + /** + * Absolute value. + * + * @return PHP + */ + public function abs() + { + $temp = new static(); + $temp->value = $this->value; + return $temp; + } + /** + * Trim + * + * Removes leading zeros + * + * @param list $value + * @return list + */ + protected static function trim(array $value) + { + for ($i = \count($value) - 1; $i >= 0; --$i) { + if ($value[$i]) { + break; + } + unset($value[$i]); + } + return $value; + } + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return PHP + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + // could just replace lshift with this, but then all lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->rshift($shift); + return $this->normalize($temp); + } + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return PHP + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->lshift($shift); + return $this->normalize($temp); + } + /** + * Converts 32-bit integers to bytes. + * + * @param int $x + * @return string + */ + private static function int2bytes($x) + { + return \ltrim(\pack('N', $x), \chr(0)); + } + /** + * Array Repeat + * + * @param int $input + * @param int $multiplier + * @return array + */ + protected static function array_repeat($input, $multiplier) + { + return $multiplier ? \array_fill(0, $multiplier, $input) : []; + } + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function lshift($shift) + { + if ($shift == 0) { + return; + } + $num_digits = (int) ($shift / static::BASE); + $shift %= static::BASE; + $shift = 1 << $shift; + $carry = 0; + for ($i = 0; $i < \count($this->value); ++$i) { + $temp = $this->value[$i] * $shift + $carry; + $carry = static::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31; + $this->value[$i] = (int) ($temp - $carry * static::BASE_FULL); + } + if ($carry) { + $this->value[\count($this->value)] = $carry; + } + while ($num_digits--) { + \array_unshift($this->value, 0); + } + } + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function rshift($shift) + { + if ($shift == 0) { + return; + } + $num_digits = (int) ($shift / static::BASE); + $shift %= static::BASE; + $carry_shift = static::BASE - $shift; + $carry_mask = (1 << $shift) - 1; + if ($num_digits) { + $this->value = \array_slice($this->value, $num_digits); + } + $carry = 0; + for ($i = \count($this->value) - 1; $i >= 0; --$i) { + $temp = $this->value[$i] >> $shift | $carry; + $carry = ($this->value[$i] & $carry_mask) << $carry_shift; + $this->value[$i] = $temp; + } + $this->value = static::trim($this->value); + } + /** + * Performs modular exponentiation. + * + * @param PHP $e + * @param PHP $n + * @return PHP + */ + protected function powModInner(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $n) + { + try { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + /** + * Performs squaring + * + * @param list $x + * @return list + */ + protected static function square(array $x) + { + return \count($x) < 2 * self::KARATSUBA_CUTOFF ? self::trim(self::baseSquare($x)) : self::trim(self::karatsubaSquare($x)); + } + /** + * Performs traditional squaring on two BigIntegers + * + * Squaring can be done faster than multiplying a number by itself can be. See + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. + * + * @param array $value + * @return array + */ + protected static function baseSquare(array $value) + { + if (empty($value)) { + return []; + } + $square_value = self::array_repeat(0, 2 * \count($value)); + for ($i = 0, $max_index = \count($value) - 1; $i <= $max_index; ++$i) { + $i2 = $i << 1; + $temp = $square_value[$i2] + $value[$i] * $value[$i]; + $carry = static::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31; + $square_value[$i2] = (int) ($temp - static::BASE_FULL * $carry); + // note how we start from $i+1 instead of 0 as we do in multiplication. + for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { + $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; + $carry = static::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31; + $square_value[$k] = (int) ($temp - static::BASE_FULL * $carry); + } + // the following line can yield values larger 2**15. at this point, PHP should switch + // over to floats. + $square_value[$i + $max_index + 1] = $carry; + } + return $square_value; + } + /** + * Performs Karatsuba "squaring" on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. + * + * @param array $value + * @return array + */ + protected static function karatsubaSquare(array $value) + { + $m = \count($value) >> 1; + if ($m < self::KARATSUBA_CUTOFF) { + return self::baseSquare($value); + } + $x1 = \array_slice($value, $m); + $x0 = \array_slice($value, 0, $m); + $z2 = self::karatsubaSquare($x1); + $z0 = self::karatsubaSquare($x0); + $z1 = self::addHelper($x1, \false, $x0, \false); + $z1 = self::karatsubaSquare($z1[self::VALUE]); + $temp = self::addHelper($z2, \false, $z0, \false); + $z1 = self::subtractHelper($z1, \false, $temp[self::VALUE], \false); + $z2 = \array_merge(\array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = \array_merge(\array_fill(0, $m, 0), $z1[self::VALUE]); + $xx = self::addHelper($z2, \false, $z1[self::VALUE], $z1[self::SIGN]); + $xx = self::addHelper($xx[self::VALUE], $xx[self::SIGN], $z0, \false); + return $xx[self::VALUE]; + } + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + $this->value[0] |= 1; + } + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value == [1]) { + return \false; + } + if ($this->value == [2]) { + return \true; + } + if (~$this->value[0] & 1) { + return \false; + } + $value = $this->value; + foreach (static::PRIMES as $prime) { + list(, $r) = self::divide_digit($value, $prime); + if (!$r) { + return \count($value) == 1 && $value[0] == $prime; + } + } + return \true; + } + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param PHP $r + * @return int + * @see self::isPrime() + */ + public static function scan1divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $r) + { + $r_value =& $r->value; + for ($i = 0, $r_length = \count($r_value); $i < $r_length; ++$i) { + $temp = ~$r_value[$i] & static::MAX_DIGIT; + for ($j = 1; $temp >> $j & 1; ++$j) { + } + if ($j <= static::BASE) { + break; + } + } + $s = static::BASE * $i + $j; + $r->rshift($s); + return $s; + } + /** + * Performs exponentiation. + * + * @param PHP $n + * @return PHP + */ + protected function powHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $n) + { + if ($n->compare(static::$zero[static::class]) == 0) { + return new static(1); + } + // n^0 = 1 + $temp = clone $this; + while (!$n->equals(static::$one[static::class])) { + $temp = $temp->multiply($this); + $n = $n->subtract(static::$one[static::class]); + } + return $temp; + } + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return (bool) ($this->value[0] & 1); + } + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + $digit = (int) \floor($x / static::BASE); + $bit = $x % static::BASE; + if (!isset($this->value[$digit])) { + return \false; + } + return (bool) ($this->value[$digit] & 1 << $bit); + } + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return $this->is_negative; + } + /** + * Negate + * + * Given $k, returns -$k + * + * @return static + */ + public function negate() + { + $temp = clone $this; + $temp->is_negative = !$temp->is_negative; + return $temp; + } + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return list + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + $width = (int) ($split / static::BASE); + if (!$width) { + $arr = $this->bitwise_small_split($split); + return \array_map(function ($digit) { + $temp = new static(); + $temp->value = $digit != 0 ? [$digit] : []; + return $temp; + }, $arr); + } + $vals = []; + $val = $this->value; + $i = $overflow = 0; + $len = \count($val); + while ($i < $len) { + $digit = []; + if (!$overflow) { + $digit = \array_slice($val, $i, $width); + $i += $width; + $overflow = $split % static::BASE; + if ($overflow) { + $mask = (1 << $overflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $mask; + } + } else { + $remaining = static::BASE - $overflow; + $tempsplit = $split - $remaining; + $tempwidth = (int) ($tempsplit / static::BASE + 1); + $digit = \array_slice($val, $i, $tempwidth); + $i += $tempwidth; + $tempoverflow = $tempsplit % static::BASE; + if ($tempoverflow) { + $tempmask = (1 << $tempoverflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $tempmask; + } + $newbits = 0; + for ($j = \count($digit) - 1; $j >= 0; $j--) { + $temp = $digit[$j] & $mask; + $digit[$j] = $digit[$j] >> $overflow | $newbits << $remaining; + $newbits = $temp; + } + $overflow = $tempoverflow; + $mask = $tempmask; + } + $temp = new static(); + $temp->value = static::trim($digit); + $vals[] = $temp; + } + return \array_reverse($vals); + } + /** + * Bitwise Split where $split < static::BASE + * + * @param int $split + * @return list + */ + private function bitwise_small_split($split) + { + $vals = []; + $val = $this->value; + $mask = (1 << $split) - 1; + $i = $overflow = 0; + $len = \count($val); + $val[] = 0; + $remaining = static::BASE; + while ($i != $len) { + $digit = $val[$i] & $mask; + $val[$i] >>= $split; + if (!$overflow) { + $remaining -= $split; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + if (!$remaining) { + $i++; + $remaining = static::BASE; + $overflow = 0; + } + } elseif (++$i != $len) { + $tempmask = (1 << $overflow) - 1; + $digit |= ($val[$i] & $tempmask) << $remaining; + $val[$i] >>= $overflow; + $remaining = static::BASE - $overflow; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + } + $vals[] = $digit; + } + while ($vals[\count($vals) - 1] == 0) { + unset($vals[\count($vals) - 1]); + } + return \array_reverse($vals); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php new file mode 100644 index 0000000..f73a18d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php @@ -0,0 +1,133 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; +/** + * PHP Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Base extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + /** + * Performs modular exponentiation. + * + * The most naive approach to modular exponentiation has very unreasonable requirements, and + * and although the approach involving repeated squaring does vastly better, it, too, is impractical + * for our purposes. The reason being that division - by far the most complicated and time-consuming + * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. + * + * Modular reductions resolve this issue. Although an individual modular reduction takes more time + * then an individual division, when performed in succession (with the same modulo), they're a lot faster. + * + * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, + * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the + * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because + * the product of two odd numbers is odd), but what about when RSA isn't used? + * + * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a + * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the + * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, + * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and + * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. + * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. + * + * @param PHP $x + * @param PHP $e + * @param PHP $n + * @param string $class + * @return PHP + */ + protected static function powModHelper(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = [1]; + return $x->normalize($temp); + } + if ($e->value == [1]) { + list(, $temp) = $x->divide($n); + return $x->normalize($temp); + } + if ($e->value == [2]) { + $temp = new $class(); + $temp->value = $class::square($x->value); + list(, $temp) = $temp->divide($n); + return $x->normalize($temp); + } + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + /** + * Modular reduction preparation + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return static::reduce($x, $n, $class); + } + /** + * Modular multiply + * + * @param array $x + * @param array $y + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function multiplyReduce(array $x, array $y, array $n, $class) + { + $temp = $class::multiplyHelper($x, \false, $y, \false); + return static::reduce($temp[self::VALUE], $n, $class); + } + /** + * Modular square + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function squareReduce(array $x, array $n, $class) + { + return static::reduce($class::square($x), $n, $class); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php new file mode 100644 index 0000000..480fc00 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php @@ -0,0 +1,23 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett; +/** + * PHP Default Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php new file mode 100644 index 0000000..883d996 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php @@ -0,0 +1,78 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo; +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Montgomery extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + /** + * Performs modular exponentiation. + * + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T + */ + protected static function slidingWindow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $x, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\Engine $n, $class) + { + // is the modulo odd? + if ($n->value[0] & 1) { + return parent::slidingWindow($x, $e, $n, $class); + } + // if it's not, it's even + // find the lowest set bit (eg. the max pow of 2 that divides $n) + for ($i = 0; $i < \count($n->value); ++$i) { + if ($n->value[$i]) { + $temp = \decbin($n->value[$i]); + $j = \strlen($temp) - \strrpos($temp, '1') - 1; + $j += $class::BASE * $i; + break; + } + } + // at this point, 2^$j * $n/(2^$j) == $n + $mod1 = clone $n; + $mod1->rshift($j); + $mod2 = new $class(); + $mod2->value = [1]; + $mod2->lshift($j); + $part1 = $mod1->value != [1] ? parent::slidingWindow($x, $e, $mod1, $class) : new $class(); + $part2 = \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo::slidingWindow($x, $e, $mod2, $class); + $y1 = $mod2->modInverse($mod1); + $y2 = $mod1->modInverse($mod2); + $result = $part1->multiply($mod2); + $result = $result->multiply($y1); + $temp = $part2->multiply($mod1); + $temp = $temp->multiply($y2); + $result = $result->add($temp); + list(, $result) = $result->divide($n); + return $result; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php new file mode 100644 index 0000000..97f2fbd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php @@ -0,0 +1,23 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\OpenSSL +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php new file mode 100644 index 0000000..dd73f6d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php @@ -0,0 +1,239 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base; +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Barrett extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base +{ + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param array $n + * @param array $m + * @param class-string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + static $cache = [self::VARIABLE => [], self::DATA => []]; + $m_length = \count($m); + // if (self::compareHelper($n, $static::square($m)) >= 0) { + if (\count($n) > 2 * $m_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $n; + $rhs->value = $m; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m, $class); + } + // n = 2 * m.length + if (($key = \array_search($m, $cache[self::VARIABLE])) === \false) { + $key = \count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + $lhs = new $class(); + $lhs_value =& $lhs->value; + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $m; + list($u, $m1) = $lhs->divide($rhs); + $u = $u->value; + $m1 = $m1->value; + $cache[self::DATA][] = [ + 'u' => $u, + // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1' => $m1, + ]; + } else { + \extract($cache[self::DATA][$key]); + } + $cutoff = $m_length + ($m_length >> 1); + $lsd = \array_slice($n, 0, $cutoff); + // m.length + (m.length >> 1) + $msd = \array_slice($n, $cutoff); + // m.length >> 1 + $lsd = self::trim($lsd); + $temp = $class::multiplyHelper($msd, \false, $m1, \false); + // m.length + (m.length >> 1) + $n = $class::addHelper($lsd, \false, $temp[self::VALUE], \false); + // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n[self::VALUE], $m, $class); + //} + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = \array_slice($n[self::VALUE], $m_length - 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = $class::multiplyHelper($temp, \false, $u, \false); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = \array_slice($temp[self::VALUE], ($m_length >> 1) + 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = $class::multiplyHelper($temp, \false, $m, \false); + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + $result = $class::subtractHelper($n[self::VALUE], \false, $temp[self::VALUE], \false); + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $m, \false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $m, \false); + } + return $result[self::VALUE]; + } + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + private static function regularBarrett(array $x, array $n, $class) + { + static $cache = [self::VARIABLE => [], self::DATA => []]; + $n_length = \count($n); + if (\count($x) > 2 * $n_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $x; + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + if (($key = \array_search($n, $cache[self::VARIABLE])) === \false) { + $key = \count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = new $class(); + $lhs_value =& $lhs->value; + $lhs_value = self::array_repeat(0, 2 * $n_length); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $n; + list($temp, ) = $lhs->divide($rhs); + // m.length + $cache[self::DATA][] = $temp->value; + } + // 2 * m.length - (m.length - 1) = m.length + 1 + $temp = \array_slice($x, $n_length - 1); + // (m.length + 1) + m.length = 2 * m.length + 1 + $temp = $class::multiplyHelper($temp, \false, $cache[self::DATA][$key], \false); + // (2 * m.length + 1) - (m.length - 1) = m.length + 2 + $temp = \array_slice($temp[self::VALUE], $n_length + 1); + // m.length + 1 + $result = \array_slice($x, 0, $n_length + 1); + // m.length + 1 + $temp = self::multiplyLower($temp, \false, $n, \false, $n_length + 1, $class); + // $temp == array_slice($class::regularMultiply($temp, false, $n, false)->value, 0, $n_length + 1) + if (self::compareHelper($result, \false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { + $corrector_value = self::array_repeat(0, $n_length + 1); + $corrector_value[\count($corrector_value)] = 1; + $result = $class::addHelper($result, \false, $corrector_value, \false); + $result = $result[self::VALUE]; + } + // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits + $result = $class::subtractHelper($result, \false, $temp[self::VALUE], $temp[self::SIGN]); + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $n, \false) > 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $n, \false); + } + return $result[self::VALUE]; + } + /** + * Performs long multiplication up to $stop digits + * + * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. + * + * @see self::regularBarrett() + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @param int $stop + * @param string $class + * @return array + */ + private static function multiplyLower(array $x_value, $x_negative, array $y_value, $y_negative, $stop, $class) + { + $x_length = \count($x_value); + $y_length = \count($y_value); + if (!$x_length || !$y_length) { + // a 0 is being multiplied + return [self::VALUE => [], self::SIGN => \false]; + } + if ($x_length < $y_length) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + $x_length = \count($x_value); + $y_length = \count($y_value); + } + $product_value = self::array_repeat(0, $x_length + $y_length); + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + $carry = 0; + for ($j = 0; $j < $x_length; ++$j) { + // ie. $i = 0, $k = $i + $temp = $x_value[$j] * $y_value[0] + $carry; + // $product_value[$k] == 0 + $carry = $class::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31; + $product_value[$j] = (int) ($temp - $class::BASE_FULL * $carry); + } + if ($j < $stop) { + $product_value[$j] = $carry; + } + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = $class::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31; + $product_value[$k] = (int) ($temp - $class::BASE_FULL * $carry); + } + if ($k < $stop) { + $product_value[$k] = $carry; + } + } + return [self::VALUE => self::trim($product_value), self::SIGN => $x_negative != $y_negative]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php new file mode 100644 index 0000000..a82c250 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base; +/** + * PHP Classic Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Classic extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base +{ + /** + * Regular Division + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php new file mode 100644 index 0000000..023aedb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php @@ -0,0 +1,412 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base; +/** + * PHP Dynamic Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class EvalBarrett extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param array $n + * @param array $m + * @param string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + $inline = self::$custom_reduction; + return $inline($n); + } + /** + * Generate Custom Reduction + * + * @param PHP $m + * @param string $class + * @return callable + */ + protected static function generateCustomReduction(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP $m, $class) + { + $m_length = \count($m->value); + if ($m_length < 5) { + $code = ' + $lhs = new ' . $class . '(); + $lhs->value = $x; + $rhs = new ' . $class . '(); + $rhs->value = [' . \implode(',', \array_map(self::class . '::float2string', $m->value)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + '; + eval('$func = function ($x) { ' . $code . '};'); + self::$custom_reduction = $func; + //self::$custom_reduction = \Closure::bind($func, $m, $class); + return $func; + } + $lhs = new $class(); + $lhs_value =& $lhs->value; + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + list($u, $m1) = $lhs->divide($m); + if ($class::BASE != 26) { + $u = $u->value; + } else { + $lhs_value = self::array_repeat(0, 2 * $m_length); + $lhs_value[] = 1; + $rhs = new $class(); + list($u) = $lhs->divide($m); + $u = $u->value; + } + $m = $m->value; + $m1 = $m1->value; + $cutoff = \count($m) + (\count($m) >> 1); + $code = ' + if (count($n) > ' . 2 * \count($m) . ') { + $lhs = new ' . $class . '(); + $rhs = new ' . $class . '(); + $lhs->value = $n; + $rhs->value = [' . \implode(',', \array_map('self::float2string', $m)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + $lsd = array_slice($n, 0, ' . $cutoff . '); + $msd = array_slice($n, ' . $cutoff . ');'; + $code .= self::generateInlineTrim('msd'); + $code .= self::generateInlineMultiply('msd', $m1, 'temp', $class); + $code .= self::generateInlineAdd('lsd', 'temp', 'n', $class); + $code .= '$temp = array_slice($n, ' . (\count($m) - 1) . ');'; + $code .= self::generateInlineMultiply('temp', $u, 'temp2', $class); + $code .= self::generateInlineTrim('temp2'); + $code .= $class::BASE == 26 ? '$temp = array_slice($temp2, ' . (\count($m) + 1) . ');' : '$temp = array_slice($temp2, ' . ((\count($m) >> 1) + 1) . ');'; + $code .= self::generateInlineMultiply('temp', $m, 'temp2', $class); + $code .= self::generateInlineTrim('temp2'); + /* + if ($class::BASE == 26) { + $code.= '$n = array_slice($n, 0, ' . (count($m) + 1) . '); + $temp2 = array_slice($temp2, 0, ' . (count($m) + 1) . ');'; + } + */ + $code .= self::generateInlineSubtract2('n', 'temp2', 'temp', $class); + $subcode = self::generateInlineSubtract1('temp', $m, 'temp2', $class); + $subcode .= '$temp = $temp2;'; + $code .= self::generateInlineCompare($m, 'temp', $subcode); + $code .= 'return $temp;'; + eval('$func = function ($n) { ' . $code . '};'); + self::$custom_reduction = $func; + return $func; + //self::$custom_reduction = \Closure::bind($func, $m, $class); + } + /** + * Inline Trim + * + * Removes leading zeros + * + * @param string $name + * @return string + */ + private static function generateInlineTrim($name) + { + return ' + for ($i = count($' . $name . ') - 1; $i >= 0; --$i) { + if ($' . $name . '[$i]) { + break; + } + unset($' . $name . '[$i]); + }'; + } + /** + * Inline Multiply (unknown, known) + * + * @param string $input + * @param array $arr + * @param string $output + * @param string $class + * @return string + */ + private static function generateInlineMultiply($input, array $arr, $output, $class) + { + if (!\count($arr)) { + return 'return [];'; + } + $regular = ' + $length = count($' . $input . '); + if (!$length) { + $' . $output . ' = []; + }else{ + $' . $output . ' = array_fill(0, $length + ' . \count($arr) . ', 0); + $carry = 0;'; + for ($i = 0; $i < \count($arr); $i++) { + $regular .= ' + $subtemp = $' . $input . '[0] * ' . $arr[$i]; + $regular .= $i ? ' + $carry;' : ';'; + $regular .= '$carry = '; + $regular .= $class::BASE === 26 ? 'intval($subtemp / 0x4000000);' : '$subtemp >> 31;'; + $regular .= '$' . $output . '[' . $i . '] = '; + if ($class::BASE === 26) { + $regular .= '(int) ('; + } + $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular .= $class::BASE === 26 ? ');' : ';'; + } + $regular .= '$' . $output . '[' . \count($arr) . '] = $carry;'; + $regular .= ' + for ($i = 1; $i < $length; ++$i) {'; + for ($j = 0; $j < \count($arr); $j++) { + $regular .= $j ? '$k++;' : '$k = $i;'; + $regular .= ' + $subtemp = $' . $output . '[$k] + $' . $input . '[$i] * ' . $arr[$j]; + $regular .= $j ? ' + $carry;' : ';'; + $regular .= '$carry = '; + $regular .= $class::BASE === 26 ? 'intval($subtemp / 0x4000000);' : '$subtemp >> 31;'; + $regular .= '$' . $output . '[$k] = '; + if ($class::BASE === 26) { + $regular .= '(int) ('; + } + $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular .= $class::BASE === 26 ? ');' : ';'; + } + $regular .= '$' . $output . '[++$k] = $carry; $carry = 0;'; + $regular .= '}}'; + //if (count($arr) < 2 * self::KARATSUBA_CUTOFF) { + //} + return $regular; + } + /** + * Inline Addition + * + * @param string $x + * @param string $y + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineAdd($x, $y, $result, $class) + { + $code = ' + $length = max(count($' . $x . '), count($' . $y . ')); + $' . $result . ' = array_pad($' . $x . ', $length + 1, 0); + $_' . $y . ' = array_pad($' . $y . ', $length, 0); + $carry = 0; + for ($i = 0, $j = 1; $j < $length; $i+=2, $j+=2) { + $sum = ($' . $result . '[$j] + $_' . $y . '[$j]) * ' . $class::BASE_FULL . ' + + $' . $result . '[$i] + $_' . $y . '[$i] + + $carry; + $carry = $sum >= ' . self::float2string($class::MAX_DIGIT2) . '; + $sum = $carry ? $sum - ' . self::float2string($class::MAX_DIGIT2) . ' : $sum;'; + $code .= $class::BASE === 26 ? '$upper = intval($sum / 0x4000000); $' . $result . '[$i] = (int) ($sum - ' . $class::BASE_FULL . ' * $upper);' : '$upper = $sum >> 31; $' . $result . '[$i] = $sum - ' . $class::BASE_FULL . ' * $upper;'; + $code .= ' + $' . $result . '[$j] = $upper; + } + if ($j == $length) { + $sum = $' . $result . '[$i] + $_' . $y . '[$i] + $carry; + $carry = $sum >= ' . self::float2string($class::BASE_FULL) . '; + $' . $result . '[$i] = $carry ? $sum - ' . self::float2string($class::BASE_FULL) . ' : $sum; + ++$i; + } + if ($carry) { + for (; $' . $result . '[$i] == ' . $class::MAX_DIGIT . '; ++$i) { + $' . $result . '[$i] = 0; + } + ++$' . $result . '[$i]; + }'; + $code .= self::generateInlineTrim($result); + return $code; + } + /** + * Inline Subtraction 2 + * + * For when $known is more digits than $unknown. This is the harder use case to optimize for. + * + * @param string $known + * @param string $unknown + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract2($known, $unknown, $result, $class) + { + $code = ' + $' . $result . ' = $' . $known . '; + $carry = 0; + $size = count($' . $unknown . '); + for ($i = 0, $j = 1; $j < $size; $i+= 2, $j+= 2) { + $sum = ($' . $known . '[$j] - $' . $unknown . '[$j]) * ' . $class::BASE_FULL . ' + $' . $known . '[$i] + - $' . $unknown . '[$i] + - $carry; + $carry = $sum < 0; + if ($carry) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code .= $class::BASE === 26 ? 'intval($sum / 0x4000000);' : '$sum >> 31;'; + $code .= '$' . $result . '[$i] = '; + if ($class::BASE === 26) { + $code .= '(int) ('; + } + $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code .= ')'; + } + $code .= '; + $' . $result . '[$j] = $subtemp; + } + if ($j == $size) { + $sum = $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; + $carry = $sum < 0; + $' . $result . '[$i] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i; + } + + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + $code .= self::generateInlineTrim($result); + return $code; + } + /** + * Inline Subtraction 1 + * + * For when $unknown is more digits than $known. This is the easier use case to optimize for. + * + * @param string $unknown + * @param array $known + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract1($unknown, array $known, $result, $class) + { + $code = '$' . $result . ' = $' . $unknown . ';'; + for ($i = 0, $j = 1; $j < \count($known); $i += 2, $j += 2) { + $code .= '$sum = $' . $unknown . '[' . $j . '] * ' . $class::BASE_FULL . ' + $' . $unknown . '[' . $i . '] - '; + $code .= self::float2string($known[$j] * $class::BASE_FULL + $known[$i]); + if ($i != 0) { + $code .= ' - $carry'; + } + $code .= '; + if ($carry = $sum < 0) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code .= $class::BASE === 26 ? 'intval($sum / 0x4000000);' : '$sum >> 31;'; + $code .= ' + $' . $result . '[' . $i . '] = '; + if ($class::BASE === 26) { + $code .= ' (int) ('; + } + $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code .= ')'; + } + $code .= '; + $' . $result . '[' . $j . '] = $subtemp;'; + } + $code .= '$i = ' . $i . ';'; + if ($j == \count($known)) { + $code .= ' + $sum = $' . $unknown . '[' . $i . '] - ' . $known[$i] . ' - $carry; + $carry = $sum < 0; + $' . $result . '[' . $i . '] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i;'; + } + $code .= ' + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + $code .= self::generateInlineTrim($result); + return $code; + } + /** + * Inline Comparison + * + * If $unknown >= $known then loop + * + * @param array $known + * @param string $unknown + * @param string $subcode + * @return string + */ + private static function generateInlineCompare(array $known, $unknown, $subcode) + { + $uniqid = \uniqid(); + $code = 'loop_' . $uniqid . ': + $clength = count($' . $unknown . '); + switch (true) { + case $clength < ' . \count($known) . ': + goto end_' . $uniqid . '; + case $clength > ' . \count($known) . ':'; + for ($i = \count($known) - 1; $i >= 0; $i--) { + $code .= ' + case $' . $unknown . '[' . $i . '] > ' . $known[$i] . ': + goto subcode_' . $uniqid . '; + case $' . $unknown . '[' . $i . '] < ' . $known[$i] . ': + goto end_' . $uniqid . ';'; + } + $code .= ' + default: + // do subcode + } + + subcode_' . $uniqid . ':' . $subcode . ' + goto loop_' . $uniqid . '; + + end_' . $uniqid . ':'; + return $code; + } + /** + * Convert a float to a string + * + * If you do echo floatval(pow(2, 52)) you'll get 4.6116860184274E+18. It /can/ be displayed without a loss of + * precision but displayed in this way there will be precision loss, hence the need for this method. + * + * @param int|float $num + * @return string + */ + private static function float2string($num) + { + if (!\is_float($num)) { + return (string) $num; + } + if ($num < 0) { + return '-' . self::float2string(\abs($num)); + } + $temp = ''; + while ($num) { + $temp = \fmod($num, 10) . $temp; + $num = \floor($num / 10); + } + return $temp; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php new file mode 100644 index 0000000..eb433d9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php @@ -0,0 +1,113 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Montgomery as Progenitor; +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Montgomery extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Montgomery +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = \array_merge(self::array_repeat(0, \count($n)), $x); + $rhs = new $class(); + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + static $cache = [self::VARIABLE => [], self::DATA => []]; + if (($key = \array_search($n, $cache[self::VARIABLE])) === \false) { + $key = \count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $x; + $cache[self::DATA][] = self::modInverse67108864($n, $class); + } + $k = \count($n); + $result = [self::VALUE => $x]; + for ($i = 0; $i < $k; ++$i) { + $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31); + $temp = $class::regularMultiply([$temp], $n); + $temp = \array_merge(self::array_repeat(0, $i), $temp); + $result = $class::addHelper($result[self::VALUE], \false, $temp, \false); + } + $result[self::VALUE] = \array_slice($result[self::VALUE], $k); + if (self::compareHelper($result, \false, $n, \false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], \false, $n, \false); + } + return $result[self::VALUE]; + } + /** + * Modular Inverse of a number mod 2**26 (eg. 67108864) + * + * Based off of the bnpInvDigit function implemented and justified in the following URL: + * + * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} + * + * The following URL provides more info: + * + * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} + * + * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For + * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields + * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't + * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that + * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the + * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to + * 40 bits, which only 64-bit floating points will support. + * + * Thanks to Pedro Gimeno Fortea for input! + * + * @param array $x + * @param string $class + * @return int + */ + protected static function modInverse67108864(array $x, $class) + { + $x = -$x[0]; + $result = $x & 0x3; + // x**-1 mod 2**2 + $result = $result * (2 - $x * $result) & 0xf; + // x**-1 mod 2**4 + $result = $result * (2 - ($x & 0xff) * $result) & 0xff; + // x**-1 mod 2**8 + $result = $result * (2 - ($x & 0xffff) * $result & 0xffff) & 0xffff; + // x**-1 mod 2**16 + $result = $class::BASE == 26 ? \fmod($result * (2 - \fmod($x * $result, $class::BASE_FULL)), $class::BASE_FULL) : $result * (2 - $x * $result % $class::BASE_FULL) % $class::BASE_FULL; + return $result & $class::MAX_DIGIT; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php new file mode 100644 index 0000000..daa7a33 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php @@ -0,0 +1,68 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP; +/** + * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication + * + * @author Jim Wigginton + */ +abstract class MontgomeryMult extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions\Montgomery +{ + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @see self::_prepMontgomery() + * @see self::_montgomery() + * @param array $x + * @param array $y + * @param array $m + * @param class-string $class + * @return array + */ + public static function multiplyReduce(array $x, array $y, array $m, $class) + { + // the following code, although not callable, can be run independently of the above code + // although the above code performed better in my benchmarks the following could might + // perform better under different circumstances. in lieu of deleting it it's just been + // made uncallable + static $cache = [self::VARIABLE => [], self::DATA => []]; + if (($key = \array_search($m, $cache[self::VARIABLE])) === \false) { + $key = \count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + $cache[self::DATA][] = self::modInverse67108864($m, $class); + } + $n = \max(\count($x), \count($y), \count($m)); + $x = \array_pad($x, $n, 0); + $y = \array_pad($y, $n, 0); + $m = \array_pad($m, $n, 0); + $a = [self::VALUE => self::array_repeat(0, $n + 1)]; + for ($i = 0; $i < $n; ++$i) { + $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31); + $temp = $temp * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? \intval($temp / 0x4000000) : $temp >> 31); + $temp = $class::addHelper($class::regularMultiply([$x[$i]], $y), \false, $class::regularMultiply([$temp], $m), \false); + $a = $class::addHelper($a[self::VALUE], \false, $temp[self::VALUE], \false); + $a[self::VALUE] = \array_slice($a[self::VALUE], 1); + } + if (self::compareHelper($a[self::VALUE], \false, $m, \false) >= 0) { + $a = $class::subtractHelper($a[self::VALUE], \false, $m, \false); + } + return $a[self::VALUE]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php new file mode 100644 index 0000000..0841f7f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php @@ -0,0 +1,54 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base; +/** + * PHP Power Of Two Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class PowerOfTwo extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP\Base +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return self::reduce($x, $n, $class); + } + /** + * Power Of Two Reduction + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + $temp = new $class(); + $temp->value = [1]; + $result = $lhs->bitwise_and($rhs->subtract($temp)); + return $result->value; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php new file mode 100644 index 0000000..831fca1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -0,0 +1,341 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines; + +/** + * Pure-PHP 32-bit Engine. + * + * Uses 64-bit floats if int size is 4 bits + * + * @author Jim Wigginton + */ +class PHP32 extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP +{ + // Constants used by PHP.php + const BASE = 26; + const BASE_FULL = 0x4000000; + const MAX_DIGIT = 0x3ffffff; + const MSB = 0x2000000; + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 10000000; + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 7; + const MAX_DIGIT2 = 4503599627370496; + /** + * Initialize a PHP32 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + $val = $this->value; + $this->value = []; + $vals =& $this->value; + $i = \strlen($val); + if (!$i) { + return; + } + while (\true) { + $i -= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = \substr($val, 0, 4 + $i); + $val = \str_pad($val, 4, "\0", \STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = \unpack('N', \substr($val, $i, 4)); + if ($digit < 0) { + $digit += 0xffffffff + 1; + } + $step = \count($vals) & 3; + if ($step) { + $digit = \floor($digit / \pow(2, 2 * $step)); + } + if ($step != 3) { + $digit &= static::MAX_DIGIT; + $i++; + } + $vals[] = $digit; + } + while (\end($vals) === 0) { + \array_pop($vals); + } + \reset($vals); + } + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return \PHP_INT_SIZE >= 4; + } + /** + * Adds two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function add(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + return $this->convertToObj($temp); + } + /** + * Subtracts two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function subtract(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + return $this->convertToObj($temp); + } + /** + * Multiplies two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function multiply(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + return $this->convertToObj($temp); + } + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP32 $y + * @return array{PHP32, PHP32} + */ + public function divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $y) + { + return $this->divideHelper($y); + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return false|PHP32 + */ + public function modInverse(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $n) + { + return $this->modInverseHelper($n); + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return PHP32[] + */ + public function extendedGCD(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $n) + { + return $this->extendedGCDHelper($n); + } + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP32 $n + * @return PHP32 + */ + public function gcd(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $n) + { + return $this->extendedGCD($n)['gcd']; + } + /** + * Logical And + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_and(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $x) + { + return $this->bitwiseAndHelper($x); + } + /** + * Logical Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_or(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $x) + { + return $this->bitwiseOrHelper($x); + } + /** + * Logical Exclusive Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_xor(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $x) + { + return $this->bitwiseXorHelper($x); + } + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP32 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $y) + { + return $this->compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP32 $x + * @return bool + */ + public function equals(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + /** + * Performs modular exponentiation. + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function modPow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $n) + { + return $this->powModOuter($e, $n); + } + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function powMod(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $n) + { + return $this->powModOuter($e, $n); + } + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP32 $min + * @param PHP32 $max + * @return false|PHP32 + */ + public static function randomRangePrime(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP32 $min + * @param PHP32 $max + * @return PHP32 + */ + public static function randomRange(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $max) + { + return self::randomRangeHelper($min, $max); + } + /** + * Performs exponentiation. + * + * @param PHP32 $n + * @return PHP32 + */ + public function pow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $n) + { + return $this->powHelper($n); + } + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function min(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 ...$nums) + { + return self::minHelper($nums); + } + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function max(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 ...$nums) + { + return self::maxHelper($nums); + } + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP32 $min + * @param PHP32 $max + * @return bool + */ + public function between(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP32 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php new file mode 100644 index 0000000..becd10f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php @@ -0,0 +1,342 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines; + +/** + * Pure-PHP 64-bit Engine. + * + * Uses 64-bit integers if int size is 8 bits + * + * @author Jim Wigginton + */ +class PHP64 extends \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP +{ + // Constants used by PHP.php + const BASE = 31; + const BASE_FULL = 0x80000000; + const MAX_DIGIT = 0x7fffffff; + const MSB = 0x40000000; + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 1000000000; + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 9; + const MAX_DIGIT2 = 4611686018427387904; + /** + * Initialize a PHP64 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + $val = $this->value; + $this->value = []; + $vals =& $this->value; + $i = \strlen($val); + if (!$i) { + return; + } + while (\true) { + $i -= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = \substr($val, 0, 4 + $i); + $val = \str_pad($val, 4, "\0", \STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = \unpack('N', \substr($val, $i, 4)); + $step = \count($vals) & 7; + if (!$step) { + $digit &= static::MAX_DIGIT; + $i++; + } else { + $shift = 8 - $step; + $digit >>= $shift; + $shift = 32 - $shift; + $digit &= (1 << $shift) - 1; + $temp = $i > 0 ? \ord($val[$i - 1]) : 0; + $digit |= $temp << $shift & 0x7f000000; + } + $vals[] = $digit; + } + while (\end($vals) === 0) { + \array_pop($vals); + } + \reset($vals); + } + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return \PHP_INT_SIZE >= 8; + } + /** + * Adds two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function add(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + return $this->convertToObj($temp); + } + /** + * Subtracts two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function subtract(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + return $this->convertToObj($temp); + } + /** + * Multiplies two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function multiply(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + return $this->convertToObj($temp); + } + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP64 $y + * @return array{PHP64, PHP64} + */ + public function divide(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $y) + { + return $this->divideHelper($y); + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return false|PHP64 + */ + public function modInverse(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $n) + { + return $this->modInverseHelper($n); + } + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return PHP64[] + */ + public function extendedGCD(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $n) + { + return $this->extendedGCDHelper($n); + } + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP64 $n + * @return PHP64 + */ + public function gcd(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $n) + { + return $this->extendedGCD($n)['gcd']; + } + /** + * Logical And + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_and(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $x) + { + return $this->bitwiseAndHelper($x); + } + /** + * Logical Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_or(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $x) + { + return $this->bitwiseOrHelper($x); + } + /** + * Logical Exclusive Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_xor(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $x) + { + return $this->bitwiseXorHelper($x); + } + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP64 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $y) + { + return parent::compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP64 $x + * @return bool + */ + public function equals(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + /** + * Performs modular exponentiation. + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64 + */ + public function modPow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $n) + { + return $this->powModOuter($e, $n); + } + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64|false + */ + public function powMod(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $e, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $n) + { + return $this->powModOuter($e, $n); + } + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP64 $min + * @param PHP64 $max + * @return false|PHP64 + */ + public static function randomRangePrime(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP64 $min + * @param PHP64 $max + * @return PHP64 + */ + public static function randomRange(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $max) + { + return self::randomRangeHelper($min, $max); + } + /** + * Performs exponentiation. + * + * @param PHP64 $n + * @return PHP64 + */ + public function pow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $n) + { + return $this->powHelper($n); + } + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function min(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 ...$nums) + { + return self::minHelper($nums); + } + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function max(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 ...$nums) + { + return self::maxHelper($nums); + } + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP64 $min + * @param PHP64 $max + * @return bool + */ + public function between(\PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $min, \PostSMTP\Vendor\phpseclib3\Math\BigInteger\Engines\PHP64 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BinaryField.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BinaryField.php new file mode 100644 index 0000000..3fad2b6 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BinaryField.php @@ -0,0 +1,174 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Math; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer; +use PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField; +/** + * Binary Finite Fields + * + * @author Jim Wigginton + */ +class BinaryField extends \PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + /** @var BigInteger */ + private $randomMax; + /** + * Default constructor + */ + public function __construct(...$indices) + { + $m = \array_shift($indices); + $val = \str_repeat('0', $m) . '1'; + foreach ($indices as $index) { + $val[$index] = '1'; + } + $modulo = static::base2ToBase256(\strrev($val)); + $mStart = 2 * $m - 2; + $t = \ceil($m / 8); + $finalMask = \chr((1 << $m % 8) - 1); + if ($finalMask == "\0") { + $finalMask = "�"; + } + $bitLen = $mStart + 1; + $pad = \ceil($bitLen / 8); + $h = $bitLen & 7; + $h = $h ? 8 - $h : 0; + $r = \rtrim(\substr($val, 0, -1), '0'); + $u = [static::base2ToBase256(\strrev($r))]; + for ($i = 1; $i < 8; $i++) { + $u[] = static::base2ToBase256(\strrev(\str_repeat('0', $i) . $r)); + } + // implements algorithm 2.40 (in section 2.3.5) in "Guide to Elliptic Curve Cryptography" + // with W = 8 + $reduce = function ($c) use($u, $mStart, $m, $t, $finalMask, $pad, $h) { + $c = \str_pad($c, $pad, "\0", \STR_PAD_LEFT); + for ($i = $mStart; $i >= $m;) { + $g = $h >> 3; + $mask = $h & 7; + $mask = $mask ? 1 << 7 - $mask : 0x80; + for (; $mask > 0; $mask >>= 1, $i--, $h++) { + if (\ord($c[$g]) & $mask) { + $temp = $i - $m; + $j = $temp >> 3; + $k = $temp & 7; + $t1 = $j ? \substr($c, 0, -$j) : $c; + $length = \strlen($t1); + if ($length) { + $t2 = \str_pad($u[$k], $length, "\0", \STR_PAD_LEFT); + $temp = $t1 ^ $t2; + $c = $j ? \substr_replace($c, $temp, 0, $length) : $temp; + } + } + } + } + $c = \substr($c, -$t); + if (\strlen($c) == $t) { + $c[0] = $c[0] & $finalMask; + } + return \ltrim($c, "\0"); + }; + $this->instanceID = self::$instanceCounter++; + \PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer::setModulo($this->instanceID, $modulo); + \PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer::setRecurringModuloFunction($this->instanceID, $reduce); + $this->randomMax = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($modulo, 2); + } + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @param string $num + * @return Integer + */ + public function newInteger($num) + { + return new \PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer($this->instanceID, $num instanceof \PostSMTP\Vendor\phpseclib3\Math\BigInteger ? $num->toBytes() : $num); + } + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return Integer + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + return new \PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer($this->instanceID, \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomRange($one, $this->randomMax)->toBytes()); + } + /** + * Returns the length of the modulo in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return \strlen(\PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer::getModulo($this->instanceID)); + } + /** + * Returns the length of the modulo in bits + * + * @return int + */ + public function getLength() + { + return \strlen(\PostSMTP\Vendor\phpseclib3\Math\BinaryField\Integer::getModulo($this->instanceID)) << 3; + } + /** + * Converts a base-2 string to a base-256 string + * + * @param string $x + * @param int|null $size + * @return string + */ + public static function base2ToBase256($x, $size = null) + { + $str = \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bits2bin($x); + $pad = \strlen($x) >> 3; + if (\strlen($x) & 3) { + $pad++; + } + $str = \str_pad($str, $pad, "\0", \STR_PAD_LEFT); + if (isset($size)) { + $str = \str_pad($str, $size, "\0", \STR_PAD_LEFT); + } + return $str; + } + /** + * Converts a base-256 string to a base-2 string + * + * @param string $x + * @return string + */ + public static function base256ToBase2($x) + { + if (\function_exists('gmp_import')) { + return \gmp_strval(\gmp_import($x), 2); + } + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2bits($x); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php new file mode 100644 index 0000000..4c48b1d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php @@ -0,0 +1,442 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Math\BinaryField; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\BinaryField; +use PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer as Base; +/** + * Binary Finite Fields + * + * @author Jim Wigginton + */ +class Integer extends \PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer +{ + /** + * Holds the BinaryField's value + * + * @var string + */ + protected $value; + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + /** + * Holds the PrimeField's modulo + * + * @var array + */ + protected static $modulo; + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var callable[] + */ + protected static $reduce; + /** + * Default constructor + */ + public function __construct($instanceID, $num = '') + { + $this->instanceID = $instanceID; + if (!\strlen($num)) { + $this->value = ''; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + /** + * Set the modulo for a given instance + * @param int $instanceID + * @param string $modulo + */ + public static function setModulo($instanceID, $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + /** + * Set the modulo for a given instance + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + } + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + */ + private static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two BinaryField\\Integer objects do not match'); + } + } + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + return $this->value == $x->value; + } + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + $a = $this->value; + $b = $x->value; + $length = \max(\strlen($a), \strlen($b)); + $a = \str_pad($a, $length, "\0", \STR_PAD_LEFT); + $b = \str_pad($b, $length, "\0", \STR_PAD_LEFT); + return \strcmp($a, $b); + } + /** + * Returns the degree of the polynomial + * + * @param string $x + * @return int + */ + private static function deg($x) + { + $x = \ltrim($x, "\0"); + $xbit = \decbin(\ord($x[0])); + $xlen = $xbit == '0' ? 0 : \strlen($xbit); + $len = \strlen($x); + if (!$len) { + return -1; + } + return 8 * \strlen($x) - 9 + $xlen; + } + /** + * Perform polynomial division + * + * @return string[] + * @link https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclidean_division + */ + private static function polynomialDivide($x, $y) + { + // in wikipedia's description of the algorithm, lc() is the leading coefficient. over a binary field that's + // always going to be 1. + $q = \chr(0); + $d = static::deg($y); + $r = $x; + while (($degr = static::deg($r)) >= $d) { + $s = '1' . \str_repeat('0', $degr - $d); + $s = \PostSMTP\Vendor\phpseclib3\Math\BinaryField::base2ToBase256($s); + $length = \max(\strlen($s), \strlen($q)); + $q = !isset($q) ? $s : \str_pad($q, $length, "\0", \STR_PAD_LEFT) ^ \str_pad($s, $length, "\0", \STR_PAD_LEFT); + $s = static::polynomialMultiply($s, $y); + $length = \max(\strlen($r), \strlen($s)); + $r = \str_pad($r, $length, "\0", \STR_PAD_LEFT) ^ \str_pad($s, $length, "\0", \STR_PAD_LEFT); + } + return [\ltrim($q, "\0"), \ltrim($r, "\0")]; + } + /** + * Perform polynomial multiplation in the traditional way + * + * @return string + * @link https://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplication + */ + private static function regularPolynomialMultiply($x, $y) + { + $precomputed = [\ltrim($x, "\0")]; + $x = \strrev(\PostSMTP\Vendor\phpseclib3\Math\BinaryField::base256ToBase2($x)); + $y = \strrev(\PostSMTP\Vendor\phpseclib3\Math\BinaryField::base256ToBase2($y)); + if (\strlen($x) == \strlen($y)) { + $length = \strlen($x); + } else { + $length = \max(\strlen($x), \strlen($y)); + $x = \str_pad($x, $length, '0'); + $y = \str_pad($y, $length, '0'); + } + $result = \str_repeat('0', 2 * $length - 1); + $result = \PostSMTP\Vendor\phpseclib3\Math\BinaryField::base2ToBase256($result); + $size = \strlen($result); + $x = \strrev($x); + // precompute left shift 1 through 7 + for ($i = 1; $i < 8; $i++) { + $precomputed[$i] = \PostSMTP\Vendor\phpseclib3\Math\BinaryField::base2ToBase256($x . \str_repeat('0', $i)); + } + for ($i = 0; $i < \strlen($y); $i++) { + if ($y[$i] == '1') { + $temp = $precomputed[$i & 7] . \str_repeat("\0", $i >> 3); + $result ^= \str_pad($temp, $size, "\0", \STR_PAD_LEFT); + } + } + return $result; + } + /** + * Perform polynomial multiplation + * + * Uses karatsuba multiplication to reduce x-bit multiplications to a series of 32-bit multiplications + * + * @return string + * @link https://en.wikipedia.org/wiki/Karatsuba_algorithm + */ + private static function polynomialMultiply($x, $y) + { + if (\strlen($x) == \strlen($y)) { + $length = \strlen($x); + } else { + $length = \max(\strlen($x), \strlen($y)); + $x = \str_pad($x, $length, "\0", \STR_PAD_LEFT); + $y = \str_pad($y, $length, "\0", \STR_PAD_LEFT); + } + switch (\true) { + case \PHP_INT_SIZE == 8 && $length <= 4: + return $length != 4 ? self::subMultiply(\str_pad($x, 4, "\0", \STR_PAD_LEFT), \str_pad($y, 4, "\0", \STR_PAD_LEFT)) : self::subMultiply($x, $y); + case \PHP_INT_SIZE == 4 || $length > 32: + return self::regularPolynomialMultiply($x, $y); + } + $m = $length >> 1; + $x1 = \substr($x, 0, -$m); + $x0 = \substr($x, -$m); + $y1 = \substr($y, 0, -$m); + $y0 = \substr($y, -$m); + $z2 = self::polynomialMultiply($x1, $y1); + $z0 = self::polynomialMultiply($x0, $y0); + $z1 = self::polynomialMultiply(self::subAdd2($x1, $x0), self::subAdd2($y1, $y0)); + $z1 = self::subAdd3($z1, $z2, $z0); + $xy = self::subAdd3($z2 . \str_repeat("\0", 2 * $m), $z1 . \str_repeat("\0", $m), $z0); + return \ltrim($xy, "\0"); + } + /** + * Perform polynomial multiplication on 2x 32-bit numbers, returning + * a 64-bit number + * + * @param string $x + * @param string $y + * @return string + * @link https://www.bearssl.org/constanttime.html#ghash-for-gcm + */ + private static function subMultiply($x, $y) + { + $x = \unpack('N', $x)[1]; + $y = \unpack('N', $y)[1]; + $x0 = $x & 0x11111111; + $x1 = $x & 0x22222222; + $x2 = $x & 0x44444444; + $x3 = $x & 0x88888888; + $y0 = $y & 0x11111111; + $y1 = $y & 0x22222222; + $y2 = $y & 0x44444444; + $y3 = $y & 0x88888888; + $z0 = $x0 * $y0 ^ $x1 * $y3 ^ $x2 * $y2 ^ $x3 * $y1; + $z1 = $x0 * $y1 ^ $x1 * $y0 ^ $x2 * $y3 ^ $x3 * $y2; + $z2 = $x0 * $y2 ^ $x1 * $y1 ^ $x2 * $y0 ^ $x3 * $y3; + $z3 = $x0 * $y3 ^ $x1 * $y2 ^ $x2 * $y1 ^ $x3 * $y0; + $z0 &= 0x1111111111111111; + $z1 &= 0x2222222222222222; + $z2 &= 0x4444444444444444; + $z3 &= -8608480567731124088; + // 0x8888888888888888 gets interpreted as a float + $z = $z0 | $z1 | $z2 | $z3; + return \pack('J', $z); + } + /** + * Adds two numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd2($x, $y) + { + $length = \max(\strlen($x), \strlen($y)); + $x = \str_pad($x, $length, "\0", \STR_PAD_LEFT); + $y = \str_pad($y, $length, "\0", \STR_PAD_LEFT); + return $x ^ $y; + } + /** + * Adds three numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd3($x, $y, $z) + { + $length = \max(\strlen($x), \strlen($y), \strlen($z)); + $x = \str_pad($x, $length, "\0", \STR_PAD_LEFT); + $y = \str_pad($y, $length, "\0", \STR_PAD_LEFT); + $z = \str_pad($z, $length, "\0", \STR_PAD_LEFT); + return $x ^ $y ^ $z; + } + /** + * Adds two BinaryFieldIntegers. + * + * @return static + */ + public function add(self $y) + { + static::checkInstance($this, $y); + $length = \strlen(static::$modulo[$this->instanceID]); + $x = \str_pad($this->value, $length, "\0", \STR_PAD_LEFT); + $y = \str_pad($y->value, $length, "\0", \STR_PAD_LEFT); + return new static($this->instanceID, $x ^ $y); + } + /** + * Subtracts two BinaryFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + return $this->add($x); + } + /** + * Multiplies two BinaryFieldIntegers. + * + * @return static + */ + public function multiply(self $y) + { + static::checkInstance($this, $y); + return new static($this->instanceID, static::polynomialMultiply($this->value, $y->value)); + } + /** + * Returns the modular inverse of a BinaryFieldInteger + * + * @return static + */ + public function modInverse() + { + $remainder0 = static::$modulo[$this->instanceID]; + $remainder1 = $this->value; + if ($remainder1 == '') { + return new static($this->instanceID); + } + $aux0 = "\0"; + $aux1 = "\1"; + while ($remainder1 != "\1") { + list($q, $r) = static::polynomialDivide($remainder0, $remainder1); + $remainder0 = $remainder1; + $remainder1 = $r; + // the auxiliary in row n is given by the sum of the auxiliary in + // row n-2 and the product of the quotient and the auxiliary in row + // n-1 + $temp = static::polynomialMultiply($aux1, $q); + $aux = \str_pad($aux0, \strlen($temp), "\0", \STR_PAD_LEFT) ^ \str_pad($temp, \strlen($aux0), "\0", \STR_PAD_LEFT); + $aux0 = $aux1; + $aux1 = $aux; + } + $temp = new static($this->instanceID); + $temp->value = \ltrim($aux1, "\0"); + return $temp; + } + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + $x = $x->modInverse(); + return $this->multiply($x); + } + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return object + */ + public function negate() + { + $x = \str_pad($this->value, \strlen(static::$modulo[$this->instanceID]), "\0", \STR_PAD_LEFT); + return new static($this->instanceID, $x ^ static::$modulo[$this->instanceID]); + } + /** + * Returns the modulo + * + * @return string + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + return \str_pad($this->value, \strlen(static::$modulo[$this->instanceID]), "\0", \STR_PAD_LEFT); + } + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($this->toBytes()); + } + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + //return str_pad(BinaryField::base256ToBase2($this->value), strlen(static::$modulo[$this->instanceID]), '0', STR_PAD_LEFT); + return \PostSMTP\Vendor\phpseclib3\Math\BinaryField::base256ToBase2($this->value); + } + /** + * Converts an Integer to a BigInteger + * + * @return string + */ + public function toBigInteger() + { + return new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($this->value, 256); + } + /** + * __toString() magic method + * + */ + public function __toString() + { + return (string) $this->toBigInteger(); + } + /** + * __debugInfo() magic method + * + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php new file mode 100644 index 0000000..c140ee9 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php @@ -0,0 +1,21 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Math\Common; + +/** + * Finite Fields + * + * @author Jim Wigginton + */ +abstract class FiniteField +{ +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php new file mode 100644 index 0000000..8874fc0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField; + +/** + * Finite Field Integer + * + * @author Jim Wigginton + */ +abstract class Integer implements \JsonSerializable +{ + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + * + * PHP Serialize isn't supported because unserializing would require the factory be + * serialized as well and that just sounds like too much + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ['hex' => $this->toHex(\true)]; + } + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public abstract function toHex(); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/PrimeField.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/PrimeField.php new file mode 100644 index 0000000..8048da4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/PrimeField.php @@ -0,0 +1,106 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ +namespace PostSMTP\Vendor\phpseclib3\Math; + +use PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField; +use PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer; +/** + * Prime Finite Fields + * + * @author Jim Wigginton + */ +class PrimeField extends \PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + /** + * Default constructor + */ + public function __construct(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $modulo) + { + //if (!$modulo->isPrime()) { + // throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); + //} + $this->instanceID = self::$instanceCounter++; + \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer::setModulo($this->instanceID, $modulo); + \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); + } + /** + * Use a custom defined modular reduction function + * + * @return void + */ + public function setReduction(\Closure $func) + { + $this->reduce = $func->bindTo($this, $this); + } + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @return Integer + */ + public function newInteger(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $num) + { + return new \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer($this->instanceID, $num); + } + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return Integer + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + } + return new \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer($this->instanceID, \PostSMTP\Vendor\phpseclib3\Math\BigInteger::randomRange($one, \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer::getModulo($this->instanceID))); + } + /** + * Returns the length of the modulo in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer::getModulo($this->instanceID)->getLengthInBytes(); + } + /** + * Returns the length of the modulo in bits + * + * @return int + */ + public function getLength() + { + return \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer::getModulo($this->instanceID)->getLength(); + } + /** + * Destructor + */ + public function __destruct() + { + \PostSMTP\Vendor\phpseclib3\Math\PrimeField\Integer::cleanupCache($this->instanceID); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php new file mode 100644 index 0000000..ccc52ca --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php @@ -0,0 +1,366 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ +namespace PostSMTP\Vendor\phpseclib3\Math\PrimeField; + +use PostSMTP\Vendor\phpseclib3\Common\Functions\Strings; +use PostSMTP\Vendor\phpseclib3\Math\BigInteger; +use PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer as Base; +/** + * Prime Finite Fields + * + * @author Jim Wigginton + */ +class Integer extends \PostSMTP\Vendor\phpseclib3\Math\Common\FiniteField\Integer +{ + /** + * Holds the PrimeField's value + * + * @var BigInteger + */ + protected $value; + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + /** + * Holds the PrimeField's modulo + * + * @var array + */ + protected static $modulo; + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var array + */ + protected static $reduce; + /** + * Zero + * + * @var BigInteger + */ + protected static $zero; + /** + * Default constructor + * + * @param int $instanceID + */ + public function __construct($instanceID, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $num = null) + { + $this->instanceID = $instanceID; + if (!isset($num)) { + $this->value = clone static::$zero[static::class]; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + /** + * Set the modulo for a given instance + * + * @param int $instanceID + * @return void + */ + public static function setModulo($instanceID, \PostSMTP\Vendor\phpseclib3\Math\BigInteger $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + /** + * Set the modulo for a given instance + * + * @param int $instanceID + * @return void + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + if (!isset(static::$zero[static::class])) { + static::$zero[static::class] = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(); + } + } + /** + * Delete the modulo for a given instance + */ + public static function cleanupCache($instanceID) + { + unset(static::$modulo[$instanceID]); + unset(static::$reduce[$instanceID]); + } + /** + * Returns the modulo + * + * @param int $instanceID + * @return BigInteger + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + * + * @return void + */ + public static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two PrimeField\\Integer objects do not match'); + } + } + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + return $this->value->equals($x->value); + } + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + return $this->value->compare($x->value); + } + /** + * Adds two PrimeFieldIntegers. + * + * @return static + */ + public function add(self $x) + { + static::checkInstance($this, $x); + $temp = new static($this->instanceID); + $temp->value = $this->value->add($x->value); + if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) { + $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]); + } + return $temp; + } + /** + * Subtracts two PrimeFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + static::checkInstance($this, $x); + $temp = new static($this->instanceID); + $temp->value = $this->value->subtract($x->value); + if ($temp->value->isNegative()) { + $temp->value = $temp->value->add(static::$modulo[$this->instanceID]); + } + return $temp; + } + /** + * Multiplies two PrimeFieldIntegers. + * + * @return static + */ + public function multiply(self $x) + { + static::checkInstance($this, $x); + return new static($this->instanceID, $this->value->multiply($x->value)); + } + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]); + return new static($this->instanceID, $this->value->multiply($denominator)); + } + /** + * Performs power operation on a PrimeFieldInteger. + * + * @return static + */ + public function pow(\PostSMTP\Vendor\phpseclib3\Math\BigInteger $x) + { + $temp = new static($this->instanceID); + $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]); + return $temp; + } + /** + * Calculates the square root + * + * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm + * @return static|false + */ + public function squareRoot() + { + static $one, $two; + if (!isset($one)) { + $one = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1); + $two = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(2); + } + $reduce = static::$reduce[$this->instanceID]; + $p_1 = static::$modulo[$this->instanceID]->subtract($one); + $q = clone $p_1; + $s = \PostSMTP\Vendor\phpseclib3\Math\BigInteger::scan1divide($q); + list($pow) = $p_1->divide($two); + for ($z = $one; !$z->equals(static::$modulo[$this->instanceID]); $z = $z->add($one)) { + $temp = $z->powMod($pow, static::$modulo[$this->instanceID]); + if ($temp->equals($p_1)) { + break; + } + } + $m = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger($s); + $c = $z->powMod($q, static::$modulo[$this->instanceID]); + $t = $this->value->powMod($q, static::$modulo[$this->instanceID]); + list($temp) = $q->add($one)->divide($two); + $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]); + while (!$t->equals($one)) { + $i = clone $one; + while (!$t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) { + $i = $i->add($one); + } + if ($i->compare($m) >= 0) { + return \false; + } + $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), static::$modulo[$this->instanceID]); + $m = $i; + $c = $reduce($b->multiply($b)); + $t = $reduce($t->multiply($c)); + $r = $reduce($r->multiply($b)); + } + return new static($this->instanceID, $r); + } + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value->isOdd(); + } + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return static + */ + public function negate() + { + return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value)); + } + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + $length = static::$modulo[$this->instanceID]->getLengthInBytes(); + return \str_pad($this->value->toBytes(), $length, "\0", \STR_PAD_LEFT); + } + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return \PostSMTP\Vendor\phpseclib3\Common\Functions\Strings::bin2hex($this->toBytes()); + } + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + // return $this->value->toBits(); + static $length; + if (!isset($length)) { + $length = static::$modulo[$this->instanceID]->getLength(); + } + return \str_pad($this->value->toBits(), $length, '0', \STR_PAD_LEFT); + } + /** + * Returns the w-ary non-adjacent form (wNAF) + * + * @param int $w optional + * @return array + */ + public function getNAF($w = 1) + { + $w++; + $mask = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger((1 << $w) - 1); + $sub = new \PostSMTP\Vendor\phpseclib3\Math\BigInteger(1 << $w); + //$sub = new BigInteger(1 << ($w - 1)); + $d = $this->toBigInteger(); + $d_i = []; + $i = 0; + while ($d->compare(static::$zero[static::class]) > 0) { + if ($d->isOdd()) { + // start mods + $bigInteger = $d->testBit($w - 1) ? $d->bitwise_and($mask)->subtract($sub) : $d->bitwise_and($mask); + // end mods + $d = $d->subtract($bigInteger); + $d_i[$i] = (int) $bigInteger->toString(); + } else { + $d_i[$i] = 0; + } + $shift = !$d->equals(static::$zero[static::class]) && $d->bitwise_and($mask)->equals(static::$zero[static::class]) ? $w : 1; + // $w or $w + 1? + $d = $d->bitwise_rightShift($shift); + while (--$shift > 0) { + $d_i[++$i] = 0; + } + $i++; + } + return $d_i; + } + /** + * Converts an Integer to a BigInteger + * + * @return BigInteger + */ + public function toBigInteger() + { + return clone $this->value; + } + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + return (string) $this->value; + } + /** + * __debugInfo() magic method + * + * @return array + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/bootstrap.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/bootstrap.php new file mode 100644 index 0000000..359bf4d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/phpseclib/phpseclib/phpseclib/bootstrap.php @@ -0,0 +1,20 @@ +getHeaders() as $name => $values) { + * echo $name . ": " . implode(", ", $values); + * } + * + * // Emit headers iteratively: + * foreach ($message->getHeaders() as $name => $values) { + * foreach ($values as $value) { + * header(sprintf('%s: %s', $name, $value), false); + * } + * } + * + * While header names are not case-sensitive, getHeaders() will preserve the + * exact case in which headers were originally specified. + * + * @return string[][] Returns an associative array of the message's headers. Each + * key MUST be a header name, and each value MUST be an array of strings + * for that header. + */ + public function getHeaders(); + /** + * Checks if a header exists by the given case-insensitive name. + * + * @param string $name Case-insensitive header field name. + * @return bool Returns true if any header names match the given header + * name using a case-insensitive string comparison. Returns false if + * no matching header name is found in the message. + */ + public function hasHeader(string $name); + /** + * Retrieves a message header value by the given case-insensitive name. + * + * This method returns an array of all the header values of the given + * case-insensitive header name. + * + * If the header does not appear in the message, this method MUST return an + * empty array. + * + * @param string $name Case-insensitive header field name. + * @return string[] An array of string values as provided for the given + * header. If the header does not appear in the message, this method MUST + * return an empty array. + */ + public function getHeader(string $name); + /** + * Retrieves a comma-separated string of the values for a single header. + * + * This method returns all of the header values of the given + * case-insensitive header name as a string concatenated together using + * a comma. + * + * NOTE: Not all header values may be appropriately represented using + * comma concatenation. For such headers, use getHeader() instead + * and supply your own delimiter when concatenating. + * + * If the header does not appear in the message, this method MUST return + * an empty string. + * + * @param string $name Case-insensitive header field name. + * @return string A string of values as provided for the given header + * concatenated together using a comma. If the header does not appear in + * the message, this method MUST return an empty string. + */ + public function getHeaderLine(string $name); + /** + * Return an instance with the provided value replacing the specified header. + * + * While header names are case-insensitive, the casing of the header will + * be preserved by this function, and returned from getHeaders(). + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * new and/or updated header and value. + * + * @param string $name Case-insensitive header field name. + * @param string|string[] $value Header value(s). + * @return static + * @throws \InvalidArgumentException for invalid header names or values. + */ + public function withHeader(string $name, $value); + /** + * Return an instance with the specified header appended with the given value. + * + * Existing values for the specified header will be maintained. The new + * value(s) will be appended to the existing list. If the header did not + * exist previously, it will be added. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * new header and/or value. + * + * @param string $name Case-insensitive header field name to add. + * @param string|string[] $value Header value(s). + * @return static + * @throws \InvalidArgumentException for invalid header names or values. + */ + public function withAddedHeader(string $name, $value); + /** + * Return an instance without the specified header. + * + * Header resolution MUST be done without case-sensitivity. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that removes + * the named header. + * + * @param string $name Case-insensitive header field name to remove. + * @return static + */ + public function withoutHeader(string $name); + /** + * Gets the body of the message. + * + * @return StreamInterface Returns the body as a stream. + */ + public function getBody(); + /** + * Return an instance with the specified message body. + * + * The body MUST be a StreamInterface object. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return a new instance that has the + * new body stream. + * + * @param StreamInterface $body Body. + * @return static + * @throws \InvalidArgumentException When the body is not valid. + */ + public function withBody(\PostSMTP\Vendor\Psr\Http\Message\StreamInterface $body); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/http-message/src/RequestInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/http-message/src/RequestInterface.php new file mode 100644 index 0000000..105518b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/http-message/src/RequestInterface.php @@ -0,0 +1,125 @@ +getQuery()` + * or from the `QUERY_STRING` server param. + * + * @return array + */ + public function getQueryParams(); + /** + * Return an instance with the specified query string arguments. + * + * These values SHOULD remain immutable over the course of the incoming + * request. They MAY be injected during instantiation, such as from PHP's + * $_GET superglobal, or MAY be derived from some other value such as the + * URI. In cases where the arguments are parsed from the URI, the data + * MUST be compatible with what PHP's parse_str() would return for + * purposes of how duplicate query parameters are handled, and how nested + * sets are handled. + * + * Setting query string arguments MUST NOT change the URI stored by the + * request, nor the values in the server params. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * updated query string arguments. + * + * @param array $query Array of query string arguments, typically from + * $_GET. + * @return static + */ + public function withQueryParams(array $query); + /** + * Retrieve normalized file upload data. + * + * This method returns upload metadata in a normalized tree, with each leaf + * an instance of Psr\Http\Message\UploadedFileInterface. + * + * These values MAY be prepared from $_FILES or the message body during + * instantiation, or MAY be injected via withUploadedFiles(). + * + * @return array An array tree of UploadedFileInterface instances; an empty + * array MUST be returned if no data is present. + */ + public function getUploadedFiles(); + /** + * Create a new instance with the specified uploaded files. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * updated body parameters. + * + * @param array $uploadedFiles An array tree of UploadedFileInterface instances. + * @return static + * @throws \InvalidArgumentException if an invalid structure is provided. + */ + public function withUploadedFiles(array $uploadedFiles); + /** + * Retrieve any parameters provided in the request body. + * + * If the request Content-Type is either application/x-www-form-urlencoded + * or multipart/form-data, and the request method is POST, this method MUST + * return the contents of $_POST. + * + * Otherwise, this method may return any results of deserializing + * the request body content; as parsing returns structured content, the + * potential types MUST be arrays or objects only. A null value indicates + * the absence of body content. + * + * @return null|array|object The deserialized body parameters, if any. + * These will typically be an array or object. + */ + public function getParsedBody(); + /** + * Return an instance with the specified body parameters. + * + * These MAY be injected during instantiation. + * + * If the request Content-Type is either application/x-www-form-urlencoded + * or multipart/form-data, and the request method is POST, use this method + * ONLY to inject the contents of $_POST. + * + * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of + * deserializing the request body content. Deserialization/parsing returns + * structured data, and, as such, this method ONLY accepts arrays or objects, + * or a null value if nothing was available to parse. + * + * As an example, if content negotiation determines that the request data + * is a JSON payload, this method could be used to create a request + * instance with the deserialized parameters. + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * updated body parameters. + * + * @param null|array|object $data The deserialized body data. This will + * typically be in an array or object. + * @return static + * @throws \InvalidArgumentException if an unsupported argument type is + * provided. + */ + public function withParsedBody($data); + /** + * Retrieve attributes derived from the request. + * + * The request "attributes" may be used to allow injection of any + * parameters derived from the request: e.g., the results of path + * match operations; the results of decrypting cookies; the results of + * deserializing non-form-encoded message bodies; etc. Attributes + * will be application and request specific, and CAN be mutable. + * + * @return array Attributes derived from the request. + */ + public function getAttributes(); + /** + * Retrieve a single derived request attribute. + * + * Retrieves a single derived request attribute as described in + * getAttributes(). If the attribute has not been previously set, returns + * the default value as provided. + * + * This method obviates the need for a hasAttribute() method, as it allows + * specifying a default value to return if the attribute is not found. + * + * @see getAttributes() + * @param string $name The attribute name. + * @param mixed $default Default value to return if the attribute does not exist. + * @return mixed + */ + public function getAttribute(string $name, $default = null); + /** + * Return an instance with the specified derived request attribute. + * + * This method allows setting a single derived request attribute as + * described in getAttributes(). + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that has the + * updated attribute. + * + * @see getAttributes() + * @param string $name The attribute name. + * @param mixed $value The value of the attribute. + * @return static + */ + public function withAttribute(string $name, $value); + /** + * Return an instance that removes the specified derived request attribute. + * + * This method allows removing a single derived request attribute as + * described in getAttributes(). + * + * This method MUST be implemented in such a way as to retain the + * immutability of the message, and MUST return an instance that removes + * the attribute. + * + * @see getAttributes() + * @param string $name The attribute name. + * @return static + */ + public function withoutAttribute(string $name); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/http-message/src/StreamInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/http-message/src/StreamInterface.php new file mode 100644 index 0000000..4b6f8d8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/http-message/src/StreamInterface.php @@ -0,0 +1,145 @@ + + * [user-info@]host[:port] + * + * + * If the port component is not set or is the standard port for the current + * scheme, it SHOULD NOT be included. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.2 + * @return string The URI authority, in "[user-info@]host[:port]" format. + */ + public function getAuthority(); + /** + * Retrieve the user information component of the URI. + * + * If no user information is present, this method MUST return an empty + * string. + * + * If a user is present in the URI, this will return that value; + * additionally, if the password is also present, it will be appended to the + * user value, with a colon (":") separating the values. + * + * The trailing "@" character is not part of the user information and MUST + * NOT be added. + * + * @return string The URI user information, in "username[:password]" format. + */ + public function getUserInfo(); + /** + * Retrieve the host component of the URI. + * + * If no host is present, this method MUST return an empty string. + * + * The value returned MUST be normalized to lowercase, per RFC 3986 + * Section 3.2.2. + * + * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 + * @return string The URI host. + */ + public function getHost(); + /** + * Retrieve the port component of the URI. + * + * If a port is present, and it is non-standard for the current scheme, + * this method MUST return it as an integer. If the port is the standard port + * used with the current scheme, this method SHOULD return null. + * + * If no port is present, and no scheme is present, this method MUST return + * a null value. + * + * If no port is present, but a scheme is present, this method MAY return + * the standard port for that scheme, but SHOULD return null. + * + * @return null|int The URI port. + */ + public function getPort(); + /** + * Retrieve the path component of the URI. + * + * The path can either be empty or absolute (starting with a slash) or + * rootless (not starting with a slash). Implementations MUST support all + * three syntaxes. + * + * Normally, the empty path "" and absolute path "/" are considered equal as + * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically + * do this normalization because in contexts with a trimmed base path, e.g. + * the front controller, this difference becomes significant. It's the task + * of the user to handle both "" and "/". + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986, Sections 2 and 3.3. + * + * As an example, if the value should include a slash ("/") not intended as + * delimiter between path segments, that value MUST be passed in encoded + * form (e.g., "%2F") to the instance. + * + * @see https://tools.ietf.org/html/rfc3986#section-2 + * @see https://tools.ietf.org/html/rfc3986#section-3.3 + * @return string The URI path. + */ + public function getPath(); + /** + * Retrieve the query string of the URI. + * + * If no query string is present, this method MUST return an empty string. + * + * The leading "?" character is not part of the query and MUST NOT be + * added. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986, Sections 2 and 3.4. + * + * As an example, if a value in a key/value pair of the query string should + * include an ampersand ("&") not intended as a delimiter between values, + * that value MUST be passed in encoded form (e.g., "%26") to the instance. + * + * @see https://tools.ietf.org/html/rfc3986#section-2 + * @see https://tools.ietf.org/html/rfc3986#section-3.4 + * @return string The URI query string. + */ + public function getQuery(); + /** + * Retrieve the fragment component of the URI. + * + * If no fragment is present, this method MUST return an empty string. + * + * The leading "#" character is not part of the fragment and MUST NOT be + * added. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986, Sections 2 and 3.5. + * + * @see https://tools.ietf.org/html/rfc3986#section-2 + * @see https://tools.ietf.org/html/rfc3986#section-3.5 + * @return string The URI fragment. + */ + public function getFragment(); + /** + * Return an instance with the specified scheme. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified scheme. + * + * Implementations MUST support the schemes "http" and "https" case + * insensitively, and MAY accommodate other schemes if required. + * + * An empty scheme is equivalent to removing the scheme. + * + * @param string $scheme The scheme to use with the new instance. + * @return static A new instance with the specified scheme. + * @throws \InvalidArgumentException for invalid or unsupported schemes. + */ + public function withScheme(string $scheme); + /** + * Return an instance with the specified user information. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified user information. + * + * Password is optional, but the user information MUST include the + * user; an empty string for the user is equivalent to removing user + * information. + * + * @param string $user The user name to use for authority. + * @param null|string $password The password associated with $user. + * @return static A new instance with the specified user information. + */ + public function withUserInfo(string $user, ?string $password = null); + /** + * Return an instance with the specified host. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified host. + * + * An empty host value is equivalent to removing the host. + * + * @param string $host The hostname to use with the new instance. + * @return static A new instance with the specified host. + * @throws \InvalidArgumentException for invalid hostnames. + */ + public function withHost(string $host); + /** + * Return an instance with the specified port. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified port. + * + * Implementations MUST raise an exception for ports outside the + * established TCP and UDP port ranges. + * + * A null value provided for the port is equivalent to removing the port + * information. + * + * @param null|int $port The port to use with the new instance; a null value + * removes the port information. + * @return static A new instance with the specified port. + * @throws \InvalidArgumentException for invalid ports. + */ + public function withPort(?int $port); + /** + * Return an instance with the specified path. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified path. + * + * The path can either be empty or absolute (starting with a slash) or + * rootless (not starting with a slash). Implementations MUST support all + * three syntaxes. + * + * If the path is intended to be domain-relative rather than path relative then + * it must begin with a slash ("/"). Paths not starting with a slash ("/") + * are assumed to be relative to some base path known to the application or + * consumer. + * + * Users can provide both encoded and decoded path characters. + * Implementations ensure the correct encoding as outlined in getPath(). + * + * @param string $path The path to use with the new instance. + * @return static A new instance with the specified path. + * @throws \InvalidArgumentException for invalid paths. + */ + public function withPath(string $path); + /** + * Return an instance with the specified query string. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified query string. + * + * Users can provide both encoded and decoded query characters. + * Implementations ensure the correct encoding as outlined in getQuery(). + * + * An empty query string value is equivalent to removing the query string. + * + * @param string $query The query string to use with the new instance. + * @return static A new instance with the specified query string. + * @throws \InvalidArgumentException for invalid query strings. + */ + public function withQuery(string $query); + /** + * Return an instance with the specified URI fragment. + * + * This method MUST retain the state of the current instance, and return + * an instance that contains the specified URI fragment. + * + * Users can provide both encoded and decoded fragment characters. + * Implementations ensure the correct encoding as outlined in getFragment(). + * + * An empty fragment value is equivalent to removing the fragment. + * + * @param string $fragment The fragment to use with the new instance. + * @return static A new instance with the specified fragment. + */ + public function withFragment(string $fragment); + /** + * Return the string representation as a URI reference. + * + * Depending on which components of the URI are present, the resulting + * string is either a full URI or relative reference according to RFC 3986, + * Section 4.1. The method concatenates the various components of the URI, + * using the appropriate delimiters: + * + * - If a scheme is present, it MUST be suffixed by ":". + * - If an authority is present, it MUST be prefixed by "//". + * - The path can be concatenated without delimiters. But there are two + * cases where the path has to be adjusted to make the URI reference + * valid as PHP does not allow to throw an exception in __toString(): + * - If the path is rootless and an authority is present, the path MUST + * be prefixed by "/". + * - If the path is starting with more than one "/" and no authority is + * present, the starting slashes MUST be reduced to one. + * - If a query is present, it MUST be prefixed by "?". + * - If a fragment is present, it MUST be prefixed by "#". + * + * @see http://tools.ietf.org/html/rfc3986#section-4.1 + * @return string + */ + public function __toString(); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/LICENSE b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/LICENSE new file mode 100644 index 0000000..474c952 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/AbstractLogger.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/AbstractLogger.php new file mode 100644 index 0000000..4bd153d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/AbstractLogger.php @@ -0,0 +1,121 @@ +log(\PostSMTP\Vendor\Psr\Log\LogLevel::EMERGENCY, $message, $context); + } + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::ALERT, $message, $context); + } + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::CRITICAL, $message, $context); + } + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::ERROR, $message, $context); + } + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::WARNING, $message, $context); + } + /** + * Normal but significant events. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::NOTICE, $message, $context); + } + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::INFO, $message, $context); + } + /** + * Detailed debug information. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::DEBUG, $message, $context); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/InvalidArgumentException.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 0000000..81eb44f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/LoggerInterface.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 0000000..de89fb7 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,117 @@ +log(\PostSMTP\Vendor\Psr\Log\LogLevel::EMERGENCY, $message, $context); + } + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::ALERT, $message, $context); + } + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::CRITICAL, $message, $context); + } + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::ERROR, $message, $context); + } + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::WARNING, $message, $context); + } + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::NOTICE, $message, $context); + } + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::INFO, $message, $context); + } + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(\PostSMTP\Vendor\Psr\Log\LogLevel::DEBUG, $message, $context); + } + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + public abstract function log($level, $message, array $context = array()); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/NullLogger.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 0000000..b324b34 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,30 @@ +logger) { }` + * blocks. + */ +class NullLogger extends \PostSMTP\Vendor\Psr\Log\AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/deprecation-contracts/LICENSE b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/deprecation-contracts/LICENSE new file mode 100644 index 0000000..406242f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/deprecation-contracts/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/deprecation-contracts/function.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/deprecation-contracts/function.php new file mode 100644 index 0000000..f48a372 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/deprecation-contracts/function.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +if (!\function_exists('PostSMTP\\Vendor\\trigger_deprecation')) { + /** + * Triggers a silenced deprecation notice. + * + * @param string $package The name of the Composer package that is triggering the deprecation + * @param string $version The version of the package that introduced the deprecation + * @param string $message The message of the deprecation + * @param mixed ...$args Values to insert in the message using printf() formatting + * + * @author Nicolas Grekas + */ + function trigger_deprecation(string $package, string $version, string $message, ...$args) : void + { + @\trigger_error(($package || $version ? "Since {$package} {$version}: " : '') . ($args ? \vsprintf($message, $args) : $message), \E_USER_DEPRECATED); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Idn.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Idn.php new file mode 100644 index 0000000..dd769eb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Idn.php @@ -0,0 +1,715 @@ + and Trevor Rowbotham + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn; + +use PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges; +use PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex; +/** + * @see https://www.unicode.org/reports/tr46/ + * + * @internal + */ +final class Idn +{ + public const ERROR_EMPTY_LABEL = 1; + public const ERROR_LABEL_TOO_LONG = 2; + public const ERROR_DOMAIN_NAME_TOO_LONG = 4; + public const ERROR_LEADING_HYPHEN = 8; + public const ERROR_TRAILING_HYPHEN = 0x10; + public const ERROR_HYPHEN_3_4 = 0x20; + public const ERROR_LEADING_COMBINING_MARK = 0x40; + public const ERROR_DISALLOWED = 0x80; + public const ERROR_PUNYCODE = 0x100; + public const ERROR_LABEL_HAS_DOT = 0x200; + public const ERROR_INVALID_ACE_LABEL = 0x400; + public const ERROR_BIDI = 0x800; + public const ERROR_CONTEXTJ = 0x1000; + public const ERROR_CONTEXTO_PUNCTUATION = 0x2000; + public const ERROR_CONTEXTO_DIGITS = 0x4000; + public const INTL_IDNA_VARIANT_2003 = 0; + public const INTL_IDNA_VARIANT_UTS46 = 1; + public const IDNA_DEFAULT = 0; + public const IDNA_ALLOW_UNASSIGNED = 1; + public const IDNA_USE_STD3_RULES = 2; + public const IDNA_CHECK_BIDI = 4; + public const IDNA_CHECK_CONTEXTJ = 8; + public const IDNA_NONTRANSITIONAL_TO_ASCII = 16; + public const IDNA_NONTRANSITIONAL_TO_UNICODE = 32; + public const MAX_DOMAIN_SIZE = 253; + public const MAX_LABEL_SIZE = 63; + public const BASE = 36; + public const TMIN = 1; + public const TMAX = 26; + public const SKEW = 38; + public const DAMP = 700; + public const INITIAL_BIAS = 72; + public const INITIAL_N = 128; + public const DELIMITER = '-'; + public const MAX_INT = 2147483647; + /** + * Contains the numeric value of a basic code point (for use in representing integers) in the + * range 0 to BASE-1, or -1 if b is does not represent a value. + * + * @var array + */ + private static $basicToDigit = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]; + /** + * @var array + */ + private static $virama; + /** + * @var array + */ + private static $mapped; + /** + * @var array + */ + private static $ignored; + /** + * @var array + */ + private static $deviation; + /** + * @var array + */ + private static $disallowed; + /** + * @var array + */ + private static $disallowed_STD3_mapped; + /** + * @var array + */ + private static $disallowed_STD3_valid; + /** + * @var bool + */ + private static $mappingTableLoaded = \false; + /** + * @see https://www.unicode.org/reports/tr46/#ToASCII + * + * @param string $domainName + * @param int $options + * @param int $variant + * @param array $idna_info + * + * @return string|false + */ + public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) + { + if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) { + @\trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); + } + $options = ['CheckHyphens' => \true, 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_ASCII), 'VerifyDnsLength' => \true]; + $info = new \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info(); + $labels = self::process((string) $domainName, $options, $info); + foreach ($labels as $i => $label) { + // Only convert labels to punycode that contain non-ASCII code points + if (1 === \preg_match('/[^\\x00-\\x7F]/', $label)) { + try { + $label = 'xn--' . self::punycodeEncode($label); + } catch (\Exception $e) { + $info->errors |= self::ERROR_PUNYCODE; + } + $labels[$i] = $label; + } + } + if ($options['VerifyDnsLength']) { + self::validateDomainAndLabelLength($labels, $info); + } + $idna_info = ['result' => \implode('.', $labels), 'isTransitionalDifferent' => $info->transitionalDifferent, 'errors' => $info->errors]; + return 0 === $info->errors ? $idna_info['result'] : \false; + } + /** + * @see https://www.unicode.org/reports/tr46/#ToUnicode + * + * @param string $domainName + * @param int $options + * @param int $variant + * @param array $idna_info + * + * @return string|false + */ + public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = []) + { + if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) { + @\trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED); + } + $info = new \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info(); + $labels = self::process((string) $domainName, ['CheckHyphens' => \true, 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_UNICODE)], $info); + $idna_info = ['result' => \implode('.', $labels), 'isTransitionalDifferent' => $info->transitionalDifferent, 'errors' => $info->errors]; + return 0 === $info->errors ? $idna_info['result'] : \false; + } + /** + * @param string $label + * + * @return bool + */ + private static function isValidContextJ(array $codePoints, $label) + { + if (!isset(self::$virama)) { + self::$virama = (require __DIR__ . \DIRECTORY_SEPARATOR . 'Resources' . \DIRECTORY_SEPARATOR . 'unidata' . \DIRECTORY_SEPARATOR . 'virama.php'); + } + $offset = 0; + foreach ($codePoints as $i => $codePoint) { + if (0x200c !== $codePoint && 0x200d !== $codePoint) { + continue; + } + if (!isset($codePoints[$i - 1])) { + return \false; + } + // If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True; + if (isset(self::$virama[$codePoints[$i - 1]])) { + continue; + } + // If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C(Joining_Type:T)*(Joining_Type:{R,D})) Then + // True; + // Generated RegExp = ([Joining_Type:{L,D}][Joining_Type:T]*\u200C[Joining_Type:T]*)[Joining_Type:{R,D}] + if (0x200c === $codePoint && 1 === \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::ZWNJ, $label, $matches, \PREG_OFFSET_CAPTURE, $offset)) { + $offset += \strlen($matches[1][0]); + continue; + } + return \false; + } + return \true; + } + /** + * @see https://www.unicode.org/reports/tr46/#ProcessingStepMap + * + * @param string $input + * @param array $options + * + * @return string + */ + private static function mapCodePoints($input, array $options, \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info $info) + { + $str = ''; + $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules']; + $transitional = $options['Transitional_Processing']; + foreach (self::utf8Decode($input) as $codePoint) { + $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules); + switch ($data['status']) { + case 'disallowed': + $info->errors |= self::ERROR_DISALLOWED; + // no break. + case 'valid': + $str .= \mb_chr($codePoint, 'utf-8'); + break; + case 'ignored': + // Do nothing. + break; + case 'mapped': + $str .= $data['mapping']; + break; + case 'deviation': + $info->transitionalDifferent = \true; + $str .= $transitional ? $data['mapping'] : \mb_chr($codePoint, 'utf-8'); + break; + } + } + return $str; + } + /** + * @see https://www.unicode.org/reports/tr46/#Processing + * + * @param string $domain + * @param array $options + * + * @return array + */ + private static function process($domain, array $options, \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info $info) + { + // If VerifyDnsLength is not set, we are doing ToUnicode otherwise we are doing ToASCII and + // we need to respect the VerifyDnsLength option. + $checkForEmptyLabels = !isset($options['VerifyDnsLength']) || $options['VerifyDnsLength']; + if ($checkForEmptyLabels && '' === $domain) { + $info->errors |= self::ERROR_EMPTY_LABEL; + return [$domain]; + } + // Step 1. Map each code point in the domain name string + $domain = self::mapCodePoints($domain, $options, $info); + // Step 2. Normalize the domain name string to Unicode Normalization Form C. + if (!\Normalizer::isNormalized($domain, \Normalizer::FORM_C)) { + $domain = \Normalizer::normalize($domain, \Normalizer::FORM_C); + } + // Step 3. Break the string into labels at U+002E (.) FULL STOP. + $labels = \explode('.', $domain); + $lastLabelIndex = \count($labels) - 1; + // Step 4. Convert and validate each label in the domain name string. + foreach ($labels as $i => $label) { + $validationOptions = $options; + if ('xn--' === \substr($label, 0, 4)) { + try { + $label = self::punycodeDecode(\substr($label, 4)); + } catch (\Exception $e) { + $info->errors |= self::ERROR_PUNYCODE; + continue; + } + $validationOptions['Transitional_Processing'] = \false; + $labels[$i] = $label; + } + self::validateLabel($label, $info, $validationOptions, $i > 0 && $i === $lastLabelIndex); + } + if ($info->bidiDomain && !$info->validBidiDomain) { + $info->errors |= self::ERROR_BIDI; + } + // Any input domain name string that does not record an error has been successfully + // processed according to this specification. Conversely, if an input domain_name string + // causes an error, then the processing of the input domain_name string fails. Determining + // what to do with error input is up to the caller, and not in the scope of this document. + return $labels; + } + /** + * @see https://tools.ietf.org/html/rfc5893#section-2 + * + * @param string $label + */ + private static function validateBidiLabel($label, \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info $info) + { + if (1 === \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::RTL_LABEL, $label)) { + $info->bidiDomain = \true; + // Step 1. The first character must be a character with Bidi property L, R, or AL. + // If it has the R or AL property, it is an RTL label + if (1 !== \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_1_RTL, $label)) { + $info->validBidiDomain = \false; + return; + } + // Step 2. In an RTL label, only characters with the Bidi properties R, AL, AN, EN, ES, + // CS, ET, ON, BN, or NSM are allowed. + if (1 === \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_2, $label)) { + $info->validBidiDomain = \false; + return; + } + // Step 3. In an RTL label, the end of the label must be a character with Bidi property + // R, AL, EN, or AN, followed by zero or more characters with Bidi property NSM. + if (1 !== \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_3, $label)) { + $info->validBidiDomain = \false; + return; + } + // Step 4. In an RTL label, if an EN is present, no AN may be present, and vice versa. + if (1 === \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_4_AN, $label) && 1 === \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_4_EN, $label)) { + $info->validBidiDomain = \false; + return; + } + return; + } + // We are a LTR label + // Step 1. The first character must be a character with Bidi property L, R, or AL. + // If it has the L property, it is an LTR label. + if (1 !== \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_1_LTR, $label)) { + $info->validBidiDomain = \false; + return; + } + // Step 5. In an LTR label, only characters with the Bidi properties L, EN, + // ES, CS, ET, ON, BN, or NSM are allowed. + if (1 === \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_5, $label)) { + $info->validBidiDomain = \false; + return; + } + // Step 6.In an LTR label, the end of the label must be a character with Bidi property L or + // EN, followed by zero or more characters with Bidi property NSM. + if (1 !== \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::BIDI_STEP_6, $label)) { + $info->validBidiDomain = \false; + return; + } + } + /** + * @param array $labels + */ + private static function validateDomainAndLabelLength(array $labels, \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info $info) + { + $maxDomainSize = self::MAX_DOMAIN_SIZE; + $length = \count($labels); + // Number of "." delimiters. + $domainLength = $length - 1; + // If the last label is empty and it is not the first label, then it is the root label. + // Increase the max size by 1, making it 254, to account for the root label's "." + // delimiter. This also means we don't need to check the last label's length for being too + // long. + if ($length > 1 && '' === $labels[$length - 1]) { + ++$maxDomainSize; + --$length; + } + for ($i = 0; $i < $length; ++$i) { + $bytes = \strlen($labels[$i]); + $domainLength += $bytes; + if ($bytes > self::MAX_LABEL_SIZE) { + $info->errors |= self::ERROR_LABEL_TOO_LONG; + } + } + if ($domainLength > $maxDomainSize) { + $info->errors |= self::ERROR_DOMAIN_NAME_TOO_LONG; + } + } + /** + * @see https://www.unicode.org/reports/tr46/#Validity_Criteria + * + * @param string $label + * @param array $options + * @param bool $canBeEmpty + */ + private static function validateLabel($label, \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info $info, array $options, $canBeEmpty) + { + if ('' === $label) { + if (!$canBeEmpty && (!isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'])) { + $info->errors |= self::ERROR_EMPTY_LABEL; + } + return; + } + // Step 1. The label must be in Unicode Normalization Form C. + if (!\Normalizer::isNormalized($label, \Normalizer::FORM_C)) { + $info->errors |= self::ERROR_INVALID_ACE_LABEL; + } + $codePoints = self::utf8Decode($label); + if ($options['CheckHyphens']) { + // Step 2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character + // in both the thrid and fourth positions. + if (isset($codePoints[2], $codePoints[3]) && 0x2d === $codePoints[2] && 0x2d === $codePoints[3]) { + $info->errors |= self::ERROR_HYPHEN_3_4; + } + // Step 3. If CheckHyphens, the label must neither begin nor end with a U+002D + // HYPHEN-MINUS character. + if ('-' === \substr($label, 0, 1)) { + $info->errors |= self::ERROR_LEADING_HYPHEN; + } + if ('-' === \substr($label, -1, 1)) { + $info->errors |= self::ERROR_TRAILING_HYPHEN; + } + } + // Step 4. The label must not contain a U+002E (.) FULL STOP. + if (\false !== \strpos($label, '.')) { + $info->errors |= self::ERROR_LABEL_HAS_DOT; + } + // Step 5. The label must not begin with a combining mark, that is: General_Category=Mark. + if (1 === \preg_match(\PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex::COMBINING_MARK, $label)) { + $info->errors |= self::ERROR_LEADING_COMBINING_MARK; + } + // Step 6. Each code point in the label must only have certain status values according to + // Section 5, IDNA Mapping Table: + $transitional = $options['Transitional_Processing']; + $useSTD3ASCIIRules = $options['UseSTD3ASCIIRules']; + foreach ($codePoints as $codePoint) { + $data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules); + $status = $data['status']; + if ('valid' === $status || !$transitional && 'deviation' === $status) { + continue; + } + $info->errors |= self::ERROR_DISALLOWED; + break; + } + // Step 7. If CheckJoiners, the label must satisify the ContextJ rules from Appendix A, in + // The Unicode Code Points and Internationalized Domain Names for Applications (IDNA) + // [IDNA2008]. + if ($options['CheckJoiners'] && !self::isValidContextJ($codePoints, $label)) { + $info->errors |= self::ERROR_CONTEXTJ; + } + // Step 8. If CheckBidi, and if the domain name is a Bidi domain name, then the label must + // satisfy all six of the numbered conditions in [IDNA2008] RFC 5893, Section 2. + if ($options['CheckBidi'] && (!$info->bidiDomain || $info->validBidiDomain)) { + self::validateBidiLabel($label, $info); + } + } + /** + * @see https://tools.ietf.org/html/rfc3492#section-6.2 + * + * @param string $input + * + * @return string + */ + private static function punycodeDecode($input) + { + $n = self::INITIAL_N; + $out = 0; + $i = 0; + $bias = self::INITIAL_BIAS; + $lastDelimIndex = \strrpos($input, self::DELIMITER); + $b = \false === $lastDelimIndex ? 0 : $lastDelimIndex; + $inputLength = \strlen($input); + $output = []; + $bytes = \array_map('ord', \str_split($input)); + for ($j = 0; $j < $b; ++$j) { + if ($bytes[$j] > 0x7f) { + throw new \Exception('Invalid input'); + } + $output[$out++] = $input[$j]; + } + if ($b > 0) { + ++$b; + } + for ($in = $b; $in < $inputLength; ++$out) { + $oldi = $i; + $w = 1; + for ($k = self::BASE;; $k += self::BASE) { + if ($in >= $inputLength) { + throw new \Exception('Invalid input'); + } + $digit = self::$basicToDigit[$bytes[$in++] & 0xff]; + if ($digit < 0) { + throw new \Exception('Invalid input'); + } + if ($digit > \intdiv(self::MAX_INT - $i, $w)) { + throw new \Exception('Integer overflow'); + } + $i += $digit * $w; + if ($k <= $bias) { + $t = self::TMIN; + } elseif ($k >= $bias + self::TMAX) { + $t = self::TMAX; + } else { + $t = $k - $bias; + } + if ($digit < $t) { + break; + } + $baseMinusT = self::BASE - $t; + if ($w > \intdiv(self::MAX_INT, $baseMinusT)) { + throw new \Exception('Integer overflow'); + } + $w *= $baseMinusT; + } + $outPlusOne = $out + 1; + $bias = self::adaptBias($i - $oldi, $outPlusOne, 0 === $oldi); + if (\intdiv($i, $outPlusOne) > self::MAX_INT - $n) { + throw new \Exception('Integer overflow'); + } + $n += \intdiv($i, $outPlusOne); + $i %= $outPlusOne; + \array_splice($output, $i++, 0, [\mb_chr($n, 'utf-8')]); + } + return \implode('', $output); + } + /** + * @see https://tools.ietf.org/html/rfc3492#section-6.3 + * + * @param string $input + * + * @return string + */ + private static function punycodeEncode($input) + { + $n = self::INITIAL_N; + $delta = 0; + $out = 0; + $bias = self::INITIAL_BIAS; + $inputLength = 0; + $output = ''; + $iter = self::utf8Decode($input); + foreach ($iter as $codePoint) { + ++$inputLength; + if ($codePoint < 0x80) { + $output .= \chr($codePoint); + ++$out; + } + } + $h = $out; + $b = $out; + if ($b > 0) { + $output .= self::DELIMITER; + ++$out; + } + while ($h < $inputLength) { + $m = self::MAX_INT; + foreach ($iter as $codePoint) { + if ($codePoint >= $n && $codePoint < $m) { + $m = $codePoint; + } + } + if ($m - $n > \intdiv(self::MAX_INT - $delta, $h + 1)) { + throw new \Exception('Integer overflow'); + } + $delta += ($m - $n) * ($h + 1); + $n = $m; + foreach ($iter as $codePoint) { + if ($codePoint < $n && 0 === ++$delta) { + throw new \Exception('Integer overflow'); + } + if ($codePoint === $n) { + $q = $delta; + for ($k = self::BASE;; $k += self::BASE) { + if ($k <= $bias) { + $t = self::TMIN; + } elseif ($k >= $bias + self::TMAX) { + $t = self::TMAX; + } else { + $t = $k - $bias; + } + if ($q < $t) { + break; + } + $qMinusT = $q - $t; + $baseMinusT = self::BASE - $t; + $output .= self::encodeDigit($t + $qMinusT % $baseMinusT, \false); + ++$out; + $q = \intdiv($qMinusT, $baseMinusT); + } + $output .= self::encodeDigit($q, \false); + ++$out; + $bias = self::adaptBias($delta, $h + 1, $h === $b); + $delta = 0; + ++$h; + } + } + ++$delta; + ++$n; + } + return $output; + } + /** + * @see https://tools.ietf.org/html/rfc3492#section-6.1 + * + * @param int $delta + * @param int $numPoints + * @param bool $firstTime + * + * @return int + */ + private static function adaptBias($delta, $numPoints, $firstTime) + { + // xxx >> 1 is a faster way of doing intdiv(xxx, 2) + $delta = $firstTime ? \intdiv($delta, self::DAMP) : $delta >> 1; + $delta += \intdiv($delta, $numPoints); + $k = 0; + while ($delta > (self::BASE - self::TMIN) * self::TMAX >> 1) { + $delta = \intdiv($delta, self::BASE - self::TMIN); + $k += self::BASE; + } + return $k + \intdiv((self::BASE - self::TMIN + 1) * $delta, $delta + self::SKEW); + } + /** + * @param int $d + * @param bool $flag + * + * @return string + */ + private static function encodeDigit($d, $flag) + { + return \chr($d + 22 + 75 * ($d < 26 ? 1 : 0) - (($flag ? 1 : 0) << 5)); + } + /** + * Takes a UTF-8 encoded string and converts it into a series of integer code points. Any + * invalid byte sequences will be replaced by a U+FFFD replacement code point. + * + * @see https://encoding.spec.whatwg.org/#utf-8-decoder + * + * @param string $input + * + * @return array + */ + private static function utf8Decode($input) + { + $bytesSeen = 0; + $bytesNeeded = 0; + $lowerBoundary = 0x80; + $upperBoundary = 0xbf; + $codePoint = 0; + $codePoints = []; + $length = \strlen($input); + for ($i = 0; $i < $length; ++$i) { + $byte = \ord($input[$i]); + if (0 === $bytesNeeded) { + if ($byte >= 0x0 && $byte <= 0x7f) { + $codePoints[] = $byte; + continue; + } + if ($byte >= 0xc2 && $byte <= 0xdf) { + $bytesNeeded = 1; + $codePoint = $byte & 0x1f; + } elseif ($byte >= 0xe0 && $byte <= 0xef) { + if (0xe0 === $byte) { + $lowerBoundary = 0xa0; + } elseif (0xed === $byte) { + $upperBoundary = 0x9f; + } + $bytesNeeded = 2; + $codePoint = $byte & 0xf; + } elseif ($byte >= 0xf0 && $byte <= 0xf4) { + if (0xf0 === $byte) { + $lowerBoundary = 0x90; + } elseif (0xf4 === $byte) { + $upperBoundary = 0x8f; + } + $bytesNeeded = 3; + $codePoint = $byte & 0x7; + } else { + $codePoints[] = 0xfffd; + } + continue; + } + if ($byte < $lowerBoundary || $byte > $upperBoundary) { + $codePoint = 0; + $bytesNeeded = 0; + $bytesSeen = 0; + $lowerBoundary = 0x80; + $upperBoundary = 0xbf; + --$i; + $codePoints[] = 0xfffd; + continue; + } + $lowerBoundary = 0x80; + $upperBoundary = 0xbf; + $codePoint = $codePoint << 6 | $byte & 0x3f; + if (++$bytesSeen !== $bytesNeeded) { + continue; + } + $codePoints[] = $codePoint; + $codePoint = 0; + $bytesNeeded = 0; + $bytesSeen = 0; + } + // String unexpectedly ended, so append a U+FFFD code point. + if (0 !== $bytesNeeded) { + $codePoints[] = 0xfffd; + } + return $codePoints; + } + /** + * @param int $codePoint + * @param bool $useSTD3ASCIIRules + * + * @return array{status: string, mapping?: string} + */ + private static function lookupCodePointStatus($codePoint, $useSTD3ASCIIRules) + { + if (!self::$mappingTableLoaded) { + self::$mappingTableLoaded = \true; + self::$mapped = (require __DIR__ . '/Resources/unidata/mapped.php'); + self::$ignored = (require __DIR__ . '/Resources/unidata/ignored.php'); + self::$deviation = (require __DIR__ . '/Resources/unidata/deviation.php'); + self::$disallowed = (require __DIR__ . '/Resources/unidata/disallowed.php'); + self::$disallowed_STD3_mapped = (require __DIR__ . '/Resources/unidata/disallowed_STD3_mapped.php'); + self::$disallowed_STD3_valid = (require __DIR__ . '/Resources/unidata/disallowed_STD3_valid.php'); + } + if (isset(self::$mapped[$codePoint])) { + return ['status' => 'mapped', 'mapping' => self::$mapped[$codePoint]]; + } + if (isset(self::$ignored[$codePoint])) { + return ['status' => 'ignored']; + } + if (isset(self::$deviation[$codePoint])) { + return ['status' => 'deviation', 'mapping' => self::$deviation[$codePoint]]; + } + if (isset(self::$disallowed[$codePoint]) || \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges::inRange($codePoint)) { + return ['status' => 'disallowed']; + } + $isDisallowedMapped = isset(self::$disallowed_STD3_mapped[$codePoint]); + if ($isDisallowedMapped || isset(self::$disallowed_STD3_valid[$codePoint])) { + $status = 'disallowed'; + if (!$useSTD3ASCIIRules) { + $status = $isDisallowedMapped ? 'mapped' : 'valid'; + } + if ($isDisallowedMapped) { + return ['status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]]; + } + return ['status' => $status]; + } + return ['status' => 'valid']; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Info.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Info.php new file mode 100644 index 0000000..2176a28 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Info.php @@ -0,0 +1,22 @@ + and Trevor Rowbotham + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn; + +/** + * @internal + */ +class Info +{ + public $bidiDomain = \false; + public $errors = 0; + public $validBidiDomain = \true; + public $transitionalDifferent = \false; +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/LICENSE b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/LICENSE new file mode 100644 index 0000000..fd0a062 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier and Trevor Rowbotham + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php new file mode 100644 index 0000000..27f0437 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php @@ -0,0 +1,294 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata; + +/** + * @internal + */ +final class DisallowedRanges +{ + /** + * @param int $codePoint + * + * @return bool + */ + public static function inRange($codePoint) + { + if ($codePoint >= 128 && $codePoint <= 159) { + return \true; + } + if ($codePoint >= 2155 && $codePoint <= 2207) { + return \true; + } + if ($codePoint >= 3676 && $codePoint <= 3712) { + return \true; + } + if ($codePoint >= 3808 && $codePoint <= 3839) { + return \true; + } + if ($codePoint >= 4059 && $codePoint <= 4095) { + return \true; + } + if ($codePoint >= 4256 && $codePoint <= 4293) { + return \true; + } + if ($codePoint >= 6849 && $codePoint <= 6911) { + return \true; + } + if ($codePoint >= 11859 && $codePoint <= 11903) { + return \true; + } + if ($codePoint >= 42955 && $codePoint <= 42996) { + return \true; + } + if ($codePoint >= 55296 && $codePoint <= 57343) { + return \true; + } + if ($codePoint >= 57344 && $codePoint <= 63743) { + return \true; + } + if ($codePoint >= 64218 && $codePoint <= 64255) { + return \true; + } + if ($codePoint >= 64976 && $codePoint <= 65007) { + return \true; + } + if ($codePoint >= 65630 && $codePoint <= 65663) { + return \true; + } + if ($codePoint >= 65953 && $codePoint <= 65999) { + return \true; + } + if ($codePoint >= 66046 && $codePoint <= 66175) { + return \true; + } + if ($codePoint >= 66518 && $codePoint <= 66559) { + return \true; + } + if ($codePoint >= 66928 && $codePoint <= 67071) { + return \true; + } + if ($codePoint >= 67432 && $codePoint <= 67583) { + return \true; + } + if ($codePoint >= 67760 && $codePoint <= 67807) { + return \true; + } + if ($codePoint >= 67904 && $codePoint <= 67967) { + return \true; + } + if ($codePoint >= 68256 && $codePoint <= 68287) { + return \true; + } + if ($codePoint >= 68528 && $codePoint <= 68607) { + return \true; + } + if ($codePoint >= 68681 && $codePoint <= 68735) { + return \true; + } + if ($codePoint >= 68922 && $codePoint <= 69215) { + return \true; + } + if ($codePoint >= 69298 && $codePoint <= 69375) { + return \true; + } + if ($codePoint >= 69466 && $codePoint <= 69551) { + return \true; + } + if ($codePoint >= 70207 && $codePoint <= 70271) { + return \true; + } + if ($codePoint >= 70517 && $codePoint <= 70655) { + return \true; + } + if ($codePoint >= 70874 && $codePoint <= 71039) { + return \true; + } + if ($codePoint >= 71134 && $codePoint <= 71167) { + return \true; + } + if ($codePoint >= 71370 && $codePoint <= 71423) { + return \true; + } + if ($codePoint >= 71488 && $codePoint <= 71679) { + return \true; + } + if ($codePoint >= 71740 && $codePoint <= 71839) { + return \true; + } + if ($codePoint >= 72026 && $codePoint <= 72095) { + return \true; + } + if ($codePoint >= 72441 && $codePoint <= 72703) { + return \true; + } + if ($codePoint >= 72887 && $codePoint <= 72959) { + return \true; + } + if ($codePoint >= 73130 && $codePoint <= 73439) { + return \true; + } + if ($codePoint >= 73465 && $codePoint <= 73647) { + return \true; + } + if ($codePoint >= 74650 && $codePoint <= 74751) { + return \true; + } + if ($codePoint >= 75076 && $codePoint <= 77823) { + return \true; + } + if ($codePoint >= 78905 && $codePoint <= 82943) { + return \true; + } + if ($codePoint >= 83527 && $codePoint <= 92159) { + return \true; + } + if ($codePoint >= 92784 && $codePoint <= 92879) { + return \true; + } + if ($codePoint >= 93072 && $codePoint <= 93759) { + return \true; + } + if ($codePoint >= 93851 && $codePoint <= 93951) { + return \true; + } + if ($codePoint >= 94112 && $codePoint <= 94175) { + return \true; + } + if ($codePoint >= 101590 && $codePoint <= 101631) { + return \true; + } + if ($codePoint >= 101641 && $codePoint <= 110591) { + return \true; + } + if ($codePoint >= 110879 && $codePoint <= 110927) { + return \true; + } + if ($codePoint >= 111356 && $codePoint <= 113663) { + return \true; + } + if ($codePoint >= 113828 && $codePoint <= 118783) { + return \true; + } + if ($codePoint >= 119366 && $codePoint <= 119519) { + return \true; + } + if ($codePoint >= 119673 && $codePoint <= 119807) { + return \true; + } + if ($codePoint >= 121520 && $codePoint <= 122879) { + return \true; + } + if ($codePoint >= 122923 && $codePoint <= 123135) { + return \true; + } + if ($codePoint >= 123216 && $codePoint <= 123583) { + return \true; + } + if ($codePoint >= 123648 && $codePoint <= 124927) { + return \true; + } + if ($codePoint >= 125143 && $codePoint <= 125183) { + return \true; + } + if ($codePoint >= 125280 && $codePoint <= 126064) { + return \true; + } + if ($codePoint >= 126133 && $codePoint <= 126208) { + return \true; + } + if ($codePoint >= 126270 && $codePoint <= 126463) { + return \true; + } + if ($codePoint >= 126652 && $codePoint <= 126703) { + return \true; + } + if ($codePoint >= 126706 && $codePoint <= 126975) { + return \true; + } + if ($codePoint >= 127406 && $codePoint <= 127461) { + return \true; + } + if ($codePoint >= 127590 && $codePoint <= 127743) { + return \true; + } + if ($codePoint >= 129202 && $codePoint <= 129279) { + return \true; + } + if ($codePoint >= 129751 && $codePoint <= 129791) { + return \true; + } + if ($codePoint >= 129995 && $codePoint <= 130031) { + return \true; + } + if ($codePoint >= 130042 && $codePoint <= 131069) { + return \true; + } + if ($codePoint >= 173790 && $codePoint <= 173823) { + return \true; + } + if ($codePoint >= 191457 && $codePoint <= 194559) { + return \true; + } + if ($codePoint >= 195102 && $codePoint <= 196605) { + return \true; + } + if ($codePoint >= 201547 && $codePoint <= 262141) { + return \true; + } + if ($codePoint >= 262144 && $codePoint <= 327677) { + return \true; + } + if ($codePoint >= 327680 && $codePoint <= 393213) { + return \true; + } + if ($codePoint >= 393216 && $codePoint <= 458749) { + return \true; + } + if ($codePoint >= 458752 && $codePoint <= 524285) { + return \true; + } + if ($codePoint >= 524288 && $codePoint <= 589821) { + return \true; + } + if ($codePoint >= 589824 && $codePoint <= 655357) { + return \true; + } + if ($codePoint >= 655360 && $codePoint <= 720893) { + return \true; + } + if ($codePoint >= 720896 && $codePoint <= 786429) { + return \true; + } + if ($codePoint >= 786432 && $codePoint <= 851965) { + return \true; + } + if ($codePoint >= 851968 && $codePoint <= 917501) { + return \true; + } + if ($codePoint >= 917536 && $codePoint <= 917631) { + return \true; + } + if ($codePoint >= 917632 && $codePoint <= 917759) { + return \true; + } + if ($codePoint >= 918000 && $codePoint <= 983037) { + return \true; + } + if ($codePoint >= 983040 && $codePoint <= 1048573) { + return \true; + } + if ($codePoint >= 1048576 && $codePoint <= 1114109) { + return \true; + } + return \false; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/Regex.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/Regex.php new file mode 100644 index 0000000..6f05d6c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/Regex.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Resources\unidata; + +/** + * @internal + */ +final class Regex +{ + const COMBINING_MARK = '/^[\\x{0300}-\\x{036F}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{0591}-\\x{05BD}\\x{05BF}\\x{05C1}-\\x{05C2}\\x{05C4}-\\x{05C5}\\x{05C7}\\x{0610}-\\x{061A}\\x{064B}-\\x{065F}\\x{0670}\\x{06D6}-\\x{06DC}\\x{06DF}-\\x{06E4}\\x{06E7}-\\x{06E8}\\x{06EA}-\\x{06ED}\\x{0711}\\x{0730}-\\x{074A}\\x{07A6}-\\x{07B0}\\x{07EB}-\\x{07F3}\\x{07FD}\\x{0816}-\\x{0819}\\x{081B}-\\x{0823}\\x{0825}-\\x{0827}\\x{0829}-\\x{082D}\\x{0859}-\\x{085B}\\x{08D3}-\\x{08E1}\\x{08E3}-\\x{0902}\\x{0903}\\x{093A}\\x{093B}\\x{093C}\\x{093E}-\\x{0940}\\x{0941}-\\x{0948}\\x{0949}-\\x{094C}\\x{094D}\\x{094E}-\\x{094F}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{0982}-\\x{0983}\\x{09BC}\\x{09BE}-\\x{09C0}\\x{09C1}-\\x{09C4}\\x{09C7}-\\x{09C8}\\x{09CB}-\\x{09CC}\\x{09CD}\\x{09D7}\\x{09E2}-\\x{09E3}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A03}\\x{0A3C}\\x{0A3E}-\\x{0A40}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0A83}\\x{0ABC}\\x{0ABE}-\\x{0AC0}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0AC9}\\x{0ACB}-\\x{0ACC}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B02}-\\x{0B03}\\x{0B3C}\\x{0B3E}\\x{0B3F}\\x{0B40}\\x{0B41}-\\x{0B44}\\x{0B47}-\\x{0B48}\\x{0B4B}-\\x{0B4C}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B57}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BBE}-\\x{0BBF}\\x{0BC0}\\x{0BC1}-\\x{0BC2}\\x{0BC6}-\\x{0BC8}\\x{0BCA}-\\x{0BCC}\\x{0BCD}\\x{0BD7}\\x{0C00}\\x{0C01}-\\x{0C03}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C41}-\\x{0C44}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C81}\\x{0C82}-\\x{0C83}\\x{0CBC}\\x{0CBE}\\x{0CBF}\\x{0CC0}-\\x{0CC4}\\x{0CC6}\\x{0CC7}-\\x{0CC8}\\x{0CCA}-\\x{0CCB}\\x{0CCC}-\\x{0CCD}\\x{0CD5}-\\x{0CD6}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D02}-\\x{0D03}\\x{0D3B}-\\x{0D3C}\\x{0D3E}-\\x{0D40}\\x{0D41}-\\x{0D44}\\x{0D46}-\\x{0D48}\\x{0D4A}-\\x{0D4C}\\x{0D4D}\\x{0D57}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0D82}-\\x{0D83}\\x{0DCA}\\x{0DCF}-\\x{0DD1}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0DD8}-\\x{0DDF}\\x{0DF2}-\\x{0DF3}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F3E}-\\x{0F3F}\\x{0F71}-\\x{0F7E}\\x{0F7F}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102B}-\\x{102C}\\x{102D}-\\x{1030}\\x{1031}\\x{1032}-\\x{1037}\\x{1038}\\x{1039}-\\x{103A}\\x{103B}-\\x{103C}\\x{103D}-\\x{103E}\\x{1056}-\\x{1057}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1062}-\\x{1064}\\x{1067}-\\x{106D}\\x{1071}-\\x{1074}\\x{1082}\\x{1083}-\\x{1084}\\x{1085}-\\x{1086}\\x{1087}-\\x{108C}\\x{108D}\\x{108F}\\x{109A}-\\x{109C}\\x{109D}\\x{135D}-\\x{135F}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B6}\\x{17B7}-\\x{17BD}\\x{17BE}-\\x{17C5}\\x{17C6}\\x{17C7}-\\x{17C8}\\x{17C9}-\\x{17D3}\\x{17DD}\\x{180B}-\\x{180D}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1923}-\\x{1926}\\x{1927}-\\x{1928}\\x{1929}-\\x{192B}\\x{1930}-\\x{1931}\\x{1932}\\x{1933}-\\x{1938}\\x{1939}-\\x{193B}\\x{1A17}-\\x{1A18}\\x{1A19}-\\x{1A1A}\\x{1A1B}\\x{1A55}\\x{1A56}\\x{1A57}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A61}\\x{1A62}\\x{1A63}-\\x{1A64}\\x{1A65}-\\x{1A6C}\\x{1A6D}-\\x{1A72}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B04}\\x{1B34}\\x{1B35}\\x{1B36}-\\x{1B3A}\\x{1B3B}\\x{1B3C}\\x{1B3D}-\\x{1B41}\\x{1B42}\\x{1B43}-\\x{1B44}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1B82}\\x{1BA1}\\x{1BA2}-\\x{1BA5}\\x{1BA6}-\\x{1BA7}\\x{1BA8}-\\x{1BA9}\\x{1BAA}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE7}\\x{1BE8}-\\x{1BE9}\\x{1BEA}-\\x{1BEC}\\x{1BED}\\x{1BEE}\\x{1BEF}-\\x{1BF1}\\x{1BF2}-\\x{1BF3}\\x{1C24}-\\x{1C2B}\\x{1C2C}-\\x{1C33}\\x{1C34}-\\x{1C35}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE1}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF7}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2CEF}-\\x{2CF1}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{302A}-\\x{302D}\\x{302E}-\\x{302F}\\x{3099}-\\x{309A}\\x{A66F}\\x{A670}-\\x{A672}\\x{A674}-\\x{A67D}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A802}\\x{A806}\\x{A80B}\\x{A823}-\\x{A824}\\x{A825}-\\x{A826}\\x{A827}\\x{A82C}\\x{A880}-\\x{A881}\\x{A8B4}-\\x{A8C3}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A952}-\\x{A953}\\x{A980}-\\x{A982}\\x{A983}\\x{A9B3}\\x{A9B4}-\\x{A9B5}\\x{A9B6}-\\x{A9B9}\\x{A9BA}-\\x{A9BB}\\x{A9BC}-\\x{A9BD}\\x{A9BE}-\\x{A9C0}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA2F}-\\x{AA30}\\x{AA31}-\\x{AA32}\\x{AA33}-\\x{AA34}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA4D}\\x{AA7B}\\x{AA7C}\\x{AA7D}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEB}\\x{AAEC}-\\x{AAED}\\x{AAEE}-\\x{AAEF}\\x{AAF5}\\x{AAF6}\\x{ABE3}-\\x{ABE4}\\x{ABE5}\\x{ABE6}-\\x{ABE7}\\x{ABE8}\\x{ABE9}-\\x{ABEA}\\x{ABEC}\\x{ABED}\\x{FB1E}\\x{FE00}-\\x{FE0F}\\x{FE20}-\\x{FE2F}\\x{101FD}\\x{102E0}\\x{10376}-\\x{1037A}\\x{10A01}-\\x{10A03}\\x{10A05}-\\x{10A06}\\x{10A0C}-\\x{10A0F}\\x{10A38}-\\x{10A3A}\\x{10A3F}\\x{10AE5}-\\x{10AE6}\\x{10D24}-\\x{10D27}\\x{10EAB}-\\x{10EAC}\\x{10F46}-\\x{10F50}\\x{11000}\\x{11001}\\x{11002}\\x{11038}-\\x{11046}\\x{1107F}-\\x{11081}\\x{11082}\\x{110B0}-\\x{110B2}\\x{110B3}-\\x{110B6}\\x{110B7}-\\x{110B8}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112C}\\x{1112D}-\\x{11134}\\x{11145}-\\x{11146}\\x{11173}\\x{11180}-\\x{11181}\\x{11182}\\x{111B3}-\\x{111B5}\\x{111B6}-\\x{111BE}\\x{111BF}-\\x{111C0}\\x{111C9}-\\x{111CC}\\x{111CE}\\x{111CF}\\x{1122C}-\\x{1122E}\\x{1122F}-\\x{11231}\\x{11232}-\\x{11233}\\x{11234}\\x{11235}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E0}-\\x{112E2}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{11302}-\\x{11303}\\x{1133B}-\\x{1133C}\\x{1133E}-\\x{1133F}\\x{11340}\\x{11341}-\\x{11344}\\x{11347}-\\x{11348}\\x{1134B}-\\x{1134D}\\x{11357}\\x{11362}-\\x{11363}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11435}-\\x{11437}\\x{11438}-\\x{1143F}\\x{11440}-\\x{11441}\\x{11442}-\\x{11444}\\x{11445}\\x{11446}\\x{1145E}\\x{114B0}-\\x{114B2}\\x{114B3}-\\x{114B8}\\x{114B9}\\x{114BA}\\x{114BB}-\\x{114BE}\\x{114BF}-\\x{114C0}\\x{114C1}\\x{114C2}-\\x{114C3}\\x{115AF}-\\x{115B1}\\x{115B2}-\\x{115B5}\\x{115B8}-\\x{115BB}\\x{115BC}-\\x{115BD}\\x{115BE}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11630}-\\x{11632}\\x{11633}-\\x{1163A}\\x{1163B}-\\x{1163C}\\x{1163D}\\x{1163E}\\x{1163F}-\\x{11640}\\x{116AB}\\x{116AC}\\x{116AD}\\x{116AE}-\\x{116AF}\\x{116B0}-\\x{116B5}\\x{116B6}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11720}-\\x{11721}\\x{11722}-\\x{11725}\\x{11726}\\x{11727}-\\x{1172B}\\x{1182C}-\\x{1182E}\\x{1182F}-\\x{11837}\\x{11838}\\x{11839}-\\x{1183A}\\x{11930}-\\x{11935}\\x{11937}-\\x{11938}\\x{1193B}-\\x{1193C}\\x{1193D}\\x{1193E}\\x{11940}\\x{11942}\\x{11943}\\x{119D1}-\\x{119D3}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119DC}-\\x{119DF}\\x{119E0}\\x{119E4}\\x{11A01}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A39}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A57}-\\x{11A58}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A97}\\x{11A98}-\\x{11A99}\\x{11C2F}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C3E}\\x{11C3F}\\x{11C92}-\\x{11CA7}\\x{11CA9}\\x{11CAA}-\\x{11CB0}\\x{11CB1}\\x{11CB2}-\\x{11CB3}\\x{11CB4}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D8A}-\\x{11D8E}\\x{11D90}-\\x{11D91}\\x{11D93}-\\x{11D94}\\x{11D95}\\x{11D96}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{11EF5}-\\x{11EF6}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F51}-\\x{16F87}\\x{16F8F}-\\x{16F92}\\x{16FE4}\\x{16FF0}-\\x{16FF1}\\x{1BC9D}-\\x{1BC9E}\\x{1D165}-\\x{1D166}\\x{1D167}-\\x{1D169}\\x{1D16D}-\\x{1D172}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D242}-\\x{1D244}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E8D0}-\\x{1E8D6}\\x{1E944}-\\x{1E94A}\\x{E0100}-\\x{E01EF}]/u'; + const RTL_LABEL = '/[\\x{0590}\\x{05BE}\\x{05C0}\\x{05C3}\\x{05C6}\\x{05C8}-\\x{05CF}\\x{05D0}-\\x{05EA}\\x{05EB}-\\x{05EE}\\x{05EF}-\\x{05F2}\\x{05F3}-\\x{05F4}\\x{05F5}-\\x{05FF}\\x{0600}-\\x{0605}\\x{0608}\\x{060B}\\x{060D}\\x{061B}\\x{061C}\\x{061D}\\x{061E}-\\x{061F}\\x{0620}-\\x{063F}\\x{0640}\\x{0641}-\\x{064A}\\x{0660}-\\x{0669}\\x{066B}-\\x{066C}\\x{066D}\\x{066E}-\\x{066F}\\x{0671}-\\x{06D3}\\x{06D4}\\x{06D5}\\x{06DD}\\x{06E5}-\\x{06E6}\\x{06EE}-\\x{06EF}\\x{06FA}-\\x{06FC}\\x{06FD}-\\x{06FE}\\x{06FF}\\x{0700}-\\x{070D}\\x{070E}\\x{070F}\\x{0710}\\x{0712}-\\x{072F}\\x{074B}-\\x{074C}\\x{074D}-\\x{07A5}\\x{07B1}\\x{07B2}-\\x{07BF}\\x{07C0}-\\x{07C9}\\x{07CA}-\\x{07EA}\\x{07F4}-\\x{07F5}\\x{07FA}\\x{07FB}-\\x{07FC}\\x{07FE}-\\x{07FF}\\x{0800}-\\x{0815}\\x{081A}\\x{0824}\\x{0828}\\x{082E}-\\x{082F}\\x{0830}-\\x{083E}\\x{083F}\\x{0840}-\\x{0858}\\x{085C}-\\x{085D}\\x{085E}\\x{085F}\\x{0860}-\\x{086A}\\x{086B}-\\x{086F}\\x{0870}-\\x{089F}\\x{08A0}-\\x{08B4}\\x{08B5}\\x{08B6}-\\x{08C7}\\x{08C8}-\\x{08D2}\\x{08E2}\\x{200F}\\x{FB1D}\\x{FB1F}-\\x{FB28}\\x{FB2A}-\\x{FB36}\\x{FB37}\\x{FB38}-\\x{FB3C}\\x{FB3D}\\x{FB3E}\\x{FB3F}\\x{FB40}-\\x{FB41}\\x{FB42}\\x{FB43}-\\x{FB44}\\x{FB45}\\x{FB46}-\\x{FB4F}\\x{FB50}-\\x{FBB1}\\x{FBB2}-\\x{FBC1}\\x{FBC2}-\\x{FBD2}\\x{FBD3}-\\x{FD3D}\\x{FD40}-\\x{FD4F}\\x{FD50}-\\x{FD8F}\\x{FD90}-\\x{FD91}\\x{FD92}-\\x{FDC7}\\x{FDC8}-\\x{FDCF}\\x{FDF0}-\\x{FDFB}\\x{FDFC}\\x{FDFE}-\\x{FDFF}\\x{FE70}-\\x{FE74}\\x{FE75}\\x{FE76}-\\x{FEFC}\\x{FEFD}-\\x{FEFE}\\x{10800}-\\x{10805}\\x{10806}-\\x{10807}\\x{10808}\\x{10809}\\x{1080A}-\\x{10835}\\x{10836}\\x{10837}-\\x{10838}\\x{10839}-\\x{1083B}\\x{1083C}\\x{1083D}-\\x{1083E}\\x{1083F}-\\x{10855}\\x{10856}\\x{10857}\\x{10858}-\\x{1085F}\\x{10860}-\\x{10876}\\x{10877}-\\x{10878}\\x{10879}-\\x{1087F}\\x{10880}-\\x{1089E}\\x{1089F}-\\x{108A6}\\x{108A7}-\\x{108AF}\\x{108B0}-\\x{108DF}\\x{108E0}-\\x{108F2}\\x{108F3}\\x{108F4}-\\x{108F5}\\x{108F6}-\\x{108FA}\\x{108FB}-\\x{108FF}\\x{10900}-\\x{10915}\\x{10916}-\\x{1091B}\\x{1091C}-\\x{1091E}\\x{10920}-\\x{10939}\\x{1093A}-\\x{1093E}\\x{1093F}\\x{10940}-\\x{1097F}\\x{10980}-\\x{109B7}\\x{109B8}-\\x{109BB}\\x{109BC}-\\x{109BD}\\x{109BE}-\\x{109BF}\\x{109C0}-\\x{109CF}\\x{109D0}-\\x{109D1}\\x{109D2}-\\x{109FF}\\x{10A00}\\x{10A04}\\x{10A07}-\\x{10A0B}\\x{10A10}-\\x{10A13}\\x{10A14}\\x{10A15}-\\x{10A17}\\x{10A18}\\x{10A19}-\\x{10A35}\\x{10A36}-\\x{10A37}\\x{10A3B}-\\x{10A3E}\\x{10A40}-\\x{10A48}\\x{10A49}-\\x{10A4F}\\x{10A50}-\\x{10A58}\\x{10A59}-\\x{10A5F}\\x{10A60}-\\x{10A7C}\\x{10A7D}-\\x{10A7E}\\x{10A7F}\\x{10A80}-\\x{10A9C}\\x{10A9D}-\\x{10A9F}\\x{10AA0}-\\x{10ABF}\\x{10AC0}-\\x{10AC7}\\x{10AC8}\\x{10AC9}-\\x{10AE4}\\x{10AE7}-\\x{10AEA}\\x{10AEB}-\\x{10AEF}\\x{10AF0}-\\x{10AF6}\\x{10AF7}-\\x{10AFF}\\x{10B00}-\\x{10B35}\\x{10B36}-\\x{10B38}\\x{10B40}-\\x{10B55}\\x{10B56}-\\x{10B57}\\x{10B58}-\\x{10B5F}\\x{10B60}-\\x{10B72}\\x{10B73}-\\x{10B77}\\x{10B78}-\\x{10B7F}\\x{10B80}-\\x{10B91}\\x{10B92}-\\x{10B98}\\x{10B99}-\\x{10B9C}\\x{10B9D}-\\x{10BA8}\\x{10BA9}-\\x{10BAF}\\x{10BB0}-\\x{10BFF}\\x{10C00}-\\x{10C48}\\x{10C49}-\\x{10C7F}\\x{10C80}-\\x{10CB2}\\x{10CB3}-\\x{10CBF}\\x{10CC0}-\\x{10CF2}\\x{10CF3}-\\x{10CF9}\\x{10CFA}-\\x{10CFF}\\x{10D00}-\\x{10D23}\\x{10D28}-\\x{10D2F}\\x{10D30}-\\x{10D39}\\x{10D3A}-\\x{10D3F}\\x{10D40}-\\x{10E5F}\\x{10E60}-\\x{10E7E}\\x{10E7F}\\x{10E80}-\\x{10EA9}\\x{10EAA}\\x{10EAD}\\x{10EAE}-\\x{10EAF}\\x{10EB0}-\\x{10EB1}\\x{10EB2}-\\x{10EFF}\\x{10F00}-\\x{10F1C}\\x{10F1D}-\\x{10F26}\\x{10F27}\\x{10F28}-\\x{10F2F}\\x{10F30}-\\x{10F45}\\x{10F51}-\\x{10F54}\\x{10F55}-\\x{10F59}\\x{10F5A}-\\x{10F6F}\\x{10F70}-\\x{10FAF}\\x{10FB0}-\\x{10FC4}\\x{10FC5}-\\x{10FCB}\\x{10FCC}-\\x{10FDF}\\x{10FE0}-\\x{10FF6}\\x{10FF7}-\\x{10FFF}\\x{1E800}-\\x{1E8C4}\\x{1E8C5}-\\x{1E8C6}\\x{1E8C7}-\\x{1E8CF}\\x{1E8D7}-\\x{1E8FF}\\x{1E900}-\\x{1E943}\\x{1E94B}\\x{1E94C}-\\x{1E94F}\\x{1E950}-\\x{1E959}\\x{1E95A}-\\x{1E95D}\\x{1E95E}-\\x{1E95F}\\x{1E960}-\\x{1EC6F}\\x{1EC70}\\x{1EC71}-\\x{1ECAB}\\x{1ECAC}\\x{1ECAD}-\\x{1ECAF}\\x{1ECB0}\\x{1ECB1}-\\x{1ECB4}\\x{1ECB5}-\\x{1ECBF}\\x{1ECC0}-\\x{1ECFF}\\x{1ED00}\\x{1ED01}-\\x{1ED2D}\\x{1ED2E}\\x{1ED2F}-\\x{1ED3D}\\x{1ED3E}-\\x{1ED4F}\\x{1ED50}-\\x{1EDFF}\\x{1EE00}-\\x{1EE03}\\x{1EE04}\\x{1EE05}-\\x{1EE1F}\\x{1EE20}\\x{1EE21}-\\x{1EE22}\\x{1EE23}\\x{1EE24}\\x{1EE25}-\\x{1EE26}\\x{1EE27}\\x{1EE28}\\x{1EE29}-\\x{1EE32}\\x{1EE33}\\x{1EE34}-\\x{1EE37}\\x{1EE38}\\x{1EE39}\\x{1EE3A}\\x{1EE3B}\\x{1EE3C}-\\x{1EE41}\\x{1EE42}\\x{1EE43}-\\x{1EE46}\\x{1EE47}\\x{1EE48}\\x{1EE49}\\x{1EE4A}\\x{1EE4B}\\x{1EE4C}\\x{1EE4D}-\\x{1EE4F}\\x{1EE50}\\x{1EE51}-\\x{1EE52}\\x{1EE53}\\x{1EE54}\\x{1EE55}-\\x{1EE56}\\x{1EE57}\\x{1EE58}\\x{1EE59}\\x{1EE5A}\\x{1EE5B}\\x{1EE5C}\\x{1EE5D}\\x{1EE5E}\\x{1EE5F}\\x{1EE60}\\x{1EE61}-\\x{1EE62}\\x{1EE63}\\x{1EE64}\\x{1EE65}-\\x{1EE66}\\x{1EE67}-\\x{1EE6A}\\x{1EE6B}\\x{1EE6C}-\\x{1EE72}\\x{1EE73}\\x{1EE74}-\\x{1EE77}\\x{1EE78}\\x{1EE79}-\\x{1EE7C}\\x{1EE7D}\\x{1EE7E}\\x{1EE7F}\\x{1EE80}-\\x{1EE89}\\x{1EE8A}\\x{1EE8B}-\\x{1EE9B}\\x{1EE9C}-\\x{1EEA0}\\x{1EEA1}-\\x{1EEA3}\\x{1EEA4}\\x{1EEA5}-\\x{1EEA9}\\x{1EEAA}\\x{1EEAB}-\\x{1EEBB}\\x{1EEBC}-\\x{1EEEF}\\x{1EEF2}-\\x{1EEFF}\\x{1EF00}-\\x{1EFFF}]/u'; + const BIDI_STEP_1_LTR = '/^[^\\x{0000}-\\x{0008}\\x{0009}\\x{000A}\\x{000B}\\x{000C}\\x{000D}\\x{000E}-\\x{001B}\\x{001C}-\\x{001E}\\x{001F}\\x{0020}\\x{0021}-\\x{0022}\\x{0023}\\x{0024}\\x{0025}\\x{0026}-\\x{0027}\\x{0028}\\x{0029}\\x{002A}\\x{002B}\\x{002C}\\x{002D}\\x{002E}-\\x{002F}\\x{0030}-\\x{0039}\\x{003A}\\x{003B}\\x{003C}-\\x{003E}\\x{003F}-\\x{0040}\\x{005B}\\x{005C}\\x{005D}\\x{005E}\\x{005F}\\x{0060}\\x{007B}\\x{007C}\\x{007D}\\x{007E}\\x{007F}-\\x{0084}\\x{0085}\\x{0086}-\\x{009F}\\x{00A0}\\x{00A1}\\x{00A2}-\\x{00A5}\\x{00A6}\\x{00A7}\\x{00A8}\\x{00A9}\\x{00AB}\\x{00AC}\\x{00AD}\\x{00AE}\\x{00AF}\\x{00B0}\\x{00B1}\\x{00B2}-\\x{00B3}\\x{00B4}\\x{00B6}-\\x{00B7}\\x{00B8}\\x{00B9}\\x{00BB}\\x{00BC}-\\x{00BE}\\x{00BF}\\x{00D7}\\x{00F7}\\x{02B9}-\\x{02BA}\\x{02C2}-\\x{02C5}\\x{02C6}-\\x{02CF}\\x{02D2}-\\x{02DF}\\x{02E5}-\\x{02EB}\\x{02EC}\\x{02ED}\\x{02EF}-\\x{02FF}\\x{0300}-\\x{036F}\\x{0374}\\x{0375}\\x{037E}\\x{0384}-\\x{0385}\\x{0387}\\x{03F6}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{058A}\\x{058D}-\\x{058E}\\x{058F}\\x{0590}\\x{0591}-\\x{05BD}\\x{05BE}\\x{05BF}\\x{05C0}\\x{05C1}-\\x{05C2}\\x{05C3}\\x{05C4}-\\x{05C5}\\x{05C6}\\x{05C7}\\x{05C8}-\\x{05CF}\\x{05D0}-\\x{05EA}\\x{05EB}-\\x{05EE}\\x{05EF}-\\x{05F2}\\x{05F3}-\\x{05F4}\\x{05F5}-\\x{05FF}\\x{0600}-\\x{0605}\\x{0606}-\\x{0607}\\x{0608}\\x{0609}-\\x{060A}\\x{060B}\\x{060C}\\x{060D}\\x{060E}-\\x{060F}\\x{0610}-\\x{061A}\\x{061B}\\x{061C}\\x{061D}\\x{061E}-\\x{061F}\\x{0620}-\\x{063F}\\x{0640}\\x{0641}-\\x{064A}\\x{064B}-\\x{065F}\\x{0660}-\\x{0669}\\x{066A}\\x{066B}-\\x{066C}\\x{066D}\\x{066E}-\\x{066F}\\x{0670}\\x{0671}-\\x{06D3}\\x{06D4}\\x{06D5}\\x{06D6}-\\x{06DC}\\x{06DD}\\x{06DE}\\x{06DF}-\\x{06E4}\\x{06E5}-\\x{06E6}\\x{06E7}-\\x{06E8}\\x{06E9}\\x{06EA}-\\x{06ED}\\x{06EE}-\\x{06EF}\\x{06F0}-\\x{06F9}\\x{06FA}-\\x{06FC}\\x{06FD}-\\x{06FE}\\x{06FF}\\x{0700}-\\x{070D}\\x{070E}\\x{070F}\\x{0710}\\x{0711}\\x{0712}-\\x{072F}\\x{0730}-\\x{074A}\\x{074B}-\\x{074C}\\x{074D}-\\x{07A5}\\x{07A6}-\\x{07B0}\\x{07B1}\\x{07B2}-\\x{07BF}\\x{07C0}-\\x{07C9}\\x{07CA}-\\x{07EA}\\x{07EB}-\\x{07F3}\\x{07F4}-\\x{07F5}\\x{07F6}\\x{07F7}-\\x{07F9}\\x{07FA}\\x{07FB}-\\x{07FC}\\x{07FD}\\x{07FE}-\\x{07FF}\\x{0800}-\\x{0815}\\x{0816}-\\x{0819}\\x{081A}\\x{081B}-\\x{0823}\\x{0824}\\x{0825}-\\x{0827}\\x{0828}\\x{0829}-\\x{082D}\\x{082E}-\\x{082F}\\x{0830}-\\x{083E}\\x{083F}\\x{0840}-\\x{0858}\\x{0859}-\\x{085B}\\x{085C}-\\x{085D}\\x{085E}\\x{085F}\\x{0860}-\\x{086A}\\x{086B}-\\x{086F}\\x{0870}-\\x{089F}\\x{08A0}-\\x{08B4}\\x{08B5}\\x{08B6}-\\x{08C7}\\x{08C8}-\\x{08D2}\\x{08D3}-\\x{08E1}\\x{08E2}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09F2}-\\x{09F3}\\x{09FB}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AF1}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0BF3}-\\x{0BF8}\\x{0BF9}\\x{0BFA}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C78}-\\x{0C7E}\\x{0C81}\\x{0CBC}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E3F}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F3A}\\x{0F3B}\\x{0F3C}\\x{0F3D}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{135D}-\\x{135F}\\x{1390}-\\x{1399}\\x{1400}\\x{1680}\\x{169B}\\x{169C}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17DB}\\x{17DD}\\x{17F0}-\\x{17F9}\\x{1800}-\\x{1805}\\x{1806}\\x{1807}-\\x{180A}\\x{180B}-\\x{180D}\\x{180E}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1940}\\x{1944}-\\x{1945}\\x{19DE}-\\x{19FF}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{1FBD}\\x{1FBF}-\\x{1FC1}\\x{1FCD}-\\x{1FCF}\\x{1FDD}-\\x{1FDF}\\x{1FED}-\\x{1FEF}\\x{1FFD}-\\x{1FFE}\\x{2000}-\\x{200A}\\x{200B}-\\x{200D}\\x{200F}\\x{2010}-\\x{2015}\\x{2016}-\\x{2017}\\x{2018}\\x{2019}\\x{201A}\\x{201B}-\\x{201C}\\x{201D}\\x{201E}\\x{201F}\\x{2020}-\\x{2027}\\x{2028}\\x{2029}\\x{202A}\\x{202B}\\x{202C}\\x{202D}\\x{202E}\\x{202F}\\x{2030}-\\x{2034}\\x{2035}-\\x{2038}\\x{2039}\\x{203A}\\x{203B}-\\x{203E}\\x{203F}-\\x{2040}\\x{2041}-\\x{2043}\\x{2044}\\x{2045}\\x{2046}\\x{2047}-\\x{2051}\\x{2052}\\x{2053}\\x{2054}\\x{2055}-\\x{205E}\\x{205F}\\x{2060}-\\x{2064}\\x{2065}\\x{2066}\\x{2067}\\x{2068}\\x{2069}\\x{206A}-\\x{206F}\\x{2070}\\x{2074}-\\x{2079}\\x{207A}-\\x{207B}\\x{207C}\\x{207D}\\x{207E}\\x{2080}-\\x{2089}\\x{208A}-\\x{208B}\\x{208C}\\x{208D}\\x{208E}\\x{20A0}-\\x{20BF}\\x{20C0}-\\x{20CF}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2100}-\\x{2101}\\x{2103}-\\x{2106}\\x{2108}-\\x{2109}\\x{2114}\\x{2116}-\\x{2117}\\x{2118}\\x{211E}-\\x{2123}\\x{2125}\\x{2127}\\x{2129}\\x{212E}\\x{213A}-\\x{213B}\\x{2140}-\\x{2144}\\x{214A}\\x{214B}\\x{214C}-\\x{214D}\\x{2150}-\\x{215F}\\x{2189}\\x{218A}-\\x{218B}\\x{2190}-\\x{2194}\\x{2195}-\\x{2199}\\x{219A}-\\x{219B}\\x{219C}-\\x{219F}\\x{21A0}\\x{21A1}-\\x{21A2}\\x{21A3}\\x{21A4}-\\x{21A5}\\x{21A6}\\x{21A7}-\\x{21AD}\\x{21AE}\\x{21AF}-\\x{21CD}\\x{21CE}-\\x{21CF}\\x{21D0}-\\x{21D1}\\x{21D2}\\x{21D3}\\x{21D4}\\x{21D5}-\\x{21F3}\\x{21F4}-\\x{2211}\\x{2212}\\x{2213}\\x{2214}-\\x{22FF}\\x{2300}-\\x{2307}\\x{2308}\\x{2309}\\x{230A}\\x{230B}\\x{230C}-\\x{231F}\\x{2320}-\\x{2321}\\x{2322}-\\x{2328}\\x{2329}\\x{232A}\\x{232B}-\\x{2335}\\x{237B}\\x{237C}\\x{237D}-\\x{2394}\\x{2396}-\\x{239A}\\x{239B}-\\x{23B3}\\x{23B4}-\\x{23DB}\\x{23DC}-\\x{23E1}\\x{23E2}-\\x{2426}\\x{2440}-\\x{244A}\\x{2460}-\\x{2487}\\x{2488}-\\x{249B}\\x{24EA}-\\x{24FF}\\x{2500}-\\x{25B6}\\x{25B7}\\x{25B8}-\\x{25C0}\\x{25C1}\\x{25C2}-\\x{25F7}\\x{25F8}-\\x{25FF}\\x{2600}-\\x{266E}\\x{266F}\\x{2670}-\\x{26AB}\\x{26AD}-\\x{2767}\\x{2768}\\x{2769}\\x{276A}\\x{276B}\\x{276C}\\x{276D}\\x{276E}\\x{276F}\\x{2770}\\x{2771}\\x{2772}\\x{2773}\\x{2774}\\x{2775}\\x{2776}-\\x{2793}\\x{2794}-\\x{27BF}\\x{27C0}-\\x{27C4}\\x{27C5}\\x{27C6}\\x{27C7}-\\x{27E5}\\x{27E6}\\x{27E7}\\x{27E8}\\x{27E9}\\x{27EA}\\x{27EB}\\x{27EC}\\x{27ED}\\x{27EE}\\x{27EF}\\x{27F0}-\\x{27FF}\\x{2900}-\\x{2982}\\x{2983}\\x{2984}\\x{2985}\\x{2986}\\x{2987}\\x{2988}\\x{2989}\\x{298A}\\x{298B}\\x{298C}\\x{298D}\\x{298E}\\x{298F}\\x{2990}\\x{2991}\\x{2992}\\x{2993}\\x{2994}\\x{2995}\\x{2996}\\x{2997}\\x{2998}\\x{2999}-\\x{29D7}\\x{29D8}\\x{29D9}\\x{29DA}\\x{29DB}\\x{29DC}-\\x{29FB}\\x{29FC}\\x{29FD}\\x{29FE}-\\x{2AFF}\\x{2B00}-\\x{2B2F}\\x{2B30}-\\x{2B44}\\x{2B45}-\\x{2B46}\\x{2B47}-\\x{2B4C}\\x{2B4D}-\\x{2B73}\\x{2B76}-\\x{2B95}\\x{2B97}-\\x{2BFF}\\x{2CE5}-\\x{2CEA}\\x{2CEF}-\\x{2CF1}\\x{2CF9}-\\x{2CFC}\\x{2CFD}\\x{2CFE}-\\x{2CFF}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{2E00}-\\x{2E01}\\x{2E02}\\x{2E03}\\x{2E04}\\x{2E05}\\x{2E06}-\\x{2E08}\\x{2E09}\\x{2E0A}\\x{2E0B}\\x{2E0C}\\x{2E0D}\\x{2E0E}-\\x{2E16}\\x{2E17}\\x{2E18}-\\x{2E19}\\x{2E1A}\\x{2E1B}\\x{2E1C}\\x{2E1D}\\x{2E1E}-\\x{2E1F}\\x{2E20}\\x{2E21}\\x{2E22}\\x{2E23}\\x{2E24}\\x{2E25}\\x{2E26}\\x{2E27}\\x{2E28}\\x{2E29}\\x{2E2A}-\\x{2E2E}\\x{2E2F}\\x{2E30}-\\x{2E39}\\x{2E3A}-\\x{2E3B}\\x{2E3C}-\\x{2E3F}\\x{2E40}\\x{2E41}\\x{2E42}\\x{2E43}-\\x{2E4F}\\x{2E50}-\\x{2E51}\\x{2E52}\\x{2E80}-\\x{2E99}\\x{2E9B}-\\x{2EF3}\\x{2F00}-\\x{2FD5}\\x{2FF0}-\\x{2FFB}\\x{3000}\\x{3001}-\\x{3003}\\x{3004}\\x{3008}\\x{3009}\\x{300A}\\x{300B}\\x{300C}\\x{300D}\\x{300E}\\x{300F}\\x{3010}\\x{3011}\\x{3012}-\\x{3013}\\x{3014}\\x{3015}\\x{3016}\\x{3017}\\x{3018}\\x{3019}\\x{301A}\\x{301B}\\x{301C}\\x{301D}\\x{301E}-\\x{301F}\\x{3020}\\x{302A}-\\x{302D}\\x{3030}\\x{3036}-\\x{3037}\\x{303D}\\x{303E}-\\x{303F}\\x{3099}-\\x{309A}\\x{309B}-\\x{309C}\\x{30A0}\\x{30FB}\\x{31C0}-\\x{31E3}\\x{321D}-\\x{321E}\\x{3250}\\x{3251}-\\x{325F}\\x{327C}-\\x{327E}\\x{32B1}-\\x{32BF}\\x{32CC}-\\x{32CF}\\x{3377}-\\x{337A}\\x{33DE}-\\x{33DF}\\x{33FF}\\x{4DC0}-\\x{4DFF}\\x{A490}-\\x{A4C6}\\x{A60D}-\\x{A60F}\\x{A66F}\\x{A670}-\\x{A672}\\x{A673}\\x{A674}-\\x{A67D}\\x{A67E}\\x{A67F}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A700}-\\x{A716}\\x{A717}-\\x{A71F}\\x{A720}-\\x{A721}\\x{A788}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A828}-\\x{A82B}\\x{A82C}\\x{A838}\\x{A839}\\x{A874}-\\x{A877}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}-\\x{A9BD}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEC}-\\x{AAED}\\x{AAF6}\\x{AB6A}-\\x{AB6B}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1D}\\x{FB1E}\\x{FB1F}-\\x{FB28}\\x{FB29}\\x{FB2A}-\\x{FB36}\\x{FB37}\\x{FB38}-\\x{FB3C}\\x{FB3D}\\x{FB3E}\\x{FB3F}\\x{FB40}-\\x{FB41}\\x{FB42}\\x{FB43}-\\x{FB44}\\x{FB45}\\x{FB46}-\\x{FB4F}\\x{FB50}-\\x{FBB1}\\x{FBB2}-\\x{FBC1}\\x{FBC2}-\\x{FBD2}\\x{FBD3}-\\x{FD3D}\\x{FD3E}\\x{FD3F}\\x{FD40}-\\x{FD4F}\\x{FD50}-\\x{FD8F}\\x{FD90}-\\x{FD91}\\x{FD92}-\\x{FDC7}\\x{FDC8}-\\x{FDCF}\\x{FDD0}-\\x{FDEF}\\x{FDF0}-\\x{FDFB}\\x{FDFC}\\x{FDFD}\\x{FDFE}-\\x{FDFF}\\x{FE00}-\\x{FE0F}\\x{FE10}-\\x{FE16}\\x{FE17}\\x{FE18}\\x{FE19}\\x{FE20}-\\x{FE2F}\\x{FE30}\\x{FE31}-\\x{FE32}\\x{FE33}-\\x{FE34}\\x{FE35}\\x{FE36}\\x{FE37}\\x{FE38}\\x{FE39}\\x{FE3A}\\x{FE3B}\\x{FE3C}\\x{FE3D}\\x{FE3E}\\x{FE3F}\\x{FE40}\\x{FE41}\\x{FE42}\\x{FE43}\\x{FE44}\\x{FE45}-\\x{FE46}\\x{FE47}\\x{FE48}\\x{FE49}-\\x{FE4C}\\x{FE4D}-\\x{FE4F}\\x{FE50}\\x{FE51}\\x{FE52}\\x{FE54}\\x{FE55}\\x{FE56}-\\x{FE57}\\x{FE58}\\x{FE59}\\x{FE5A}\\x{FE5B}\\x{FE5C}\\x{FE5D}\\x{FE5E}\\x{FE5F}\\x{FE60}-\\x{FE61}\\x{FE62}\\x{FE63}\\x{FE64}-\\x{FE66}\\x{FE68}\\x{FE69}\\x{FE6A}\\x{FE6B}\\x{FE70}-\\x{FE74}\\x{FE75}\\x{FE76}-\\x{FEFC}\\x{FEFD}-\\x{FEFE}\\x{FEFF}\\x{FF01}-\\x{FF02}\\x{FF03}\\x{FF04}\\x{FF05}\\x{FF06}-\\x{FF07}\\x{FF08}\\x{FF09}\\x{FF0A}\\x{FF0B}\\x{FF0C}\\x{FF0D}\\x{FF0E}-\\x{FF0F}\\x{FF10}-\\x{FF19}\\x{FF1A}\\x{FF1B}\\x{FF1C}-\\x{FF1E}\\x{FF1F}-\\x{FF20}\\x{FF3B}\\x{FF3C}\\x{FF3D}\\x{FF3E}\\x{FF3F}\\x{FF40}\\x{FF5B}\\x{FF5C}\\x{FF5D}\\x{FF5E}\\x{FF5F}\\x{FF60}\\x{FF61}\\x{FF62}\\x{FF63}\\x{FF64}-\\x{FF65}\\x{FFE0}-\\x{FFE1}\\x{FFE2}\\x{FFE3}\\x{FFE4}\\x{FFE5}-\\x{FFE6}\\x{FFE8}\\x{FFE9}-\\x{FFEC}\\x{FFED}-\\x{FFEE}\\x{FFF0}-\\x{FFF8}\\x{FFF9}-\\x{FFFB}\\x{FFFC}-\\x{FFFD}\\x{FFFE}-\\x{FFFF}\\x{10101}\\x{10140}-\\x{10174}\\x{10175}-\\x{10178}\\x{10179}-\\x{10189}\\x{1018A}-\\x{1018B}\\x{1018C}\\x{10190}-\\x{1019C}\\x{101A0}\\x{101FD}\\x{102E0}\\x{102E1}-\\x{102FB}\\x{10376}-\\x{1037A}\\x{10800}-\\x{10805}\\x{10806}-\\x{10807}\\x{10808}\\x{10809}\\x{1080A}-\\x{10835}\\x{10836}\\x{10837}-\\x{10838}\\x{10839}-\\x{1083B}\\x{1083C}\\x{1083D}-\\x{1083E}\\x{1083F}-\\x{10855}\\x{10856}\\x{10857}\\x{10858}-\\x{1085F}\\x{10860}-\\x{10876}\\x{10877}-\\x{10878}\\x{10879}-\\x{1087F}\\x{10880}-\\x{1089E}\\x{1089F}-\\x{108A6}\\x{108A7}-\\x{108AF}\\x{108B0}-\\x{108DF}\\x{108E0}-\\x{108F2}\\x{108F3}\\x{108F4}-\\x{108F5}\\x{108F6}-\\x{108FA}\\x{108FB}-\\x{108FF}\\x{10900}-\\x{10915}\\x{10916}-\\x{1091B}\\x{1091C}-\\x{1091E}\\x{1091F}\\x{10920}-\\x{10939}\\x{1093A}-\\x{1093E}\\x{1093F}\\x{10940}-\\x{1097F}\\x{10980}-\\x{109B7}\\x{109B8}-\\x{109BB}\\x{109BC}-\\x{109BD}\\x{109BE}-\\x{109BF}\\x{109C0}-\\x{109CF}\\x{109D0}-\\x{109D1}\\x{109D2}-\\x{109FF}\\x{10A00}\\x{10A01}-\\x{10A03}\\x{10A04}\\x{10A05}-\\x{10A06}\\x{10A07}-\\x{10A0B}\\x{10A0C}-\\x{10A0F}\\x{10A10}-\\x{10A13}\\x{10A14}\\x{10A15}-\\x{10A17}\\x{10A18}\\x{10A19}-\\x{10A35}\\x{10A36}-\\x{10A37}\\x{10A38}-\\x{10A3A}\\x{10A3B}-\\x{10A3E}\\x{10A3F}\\x{10A40}-\\x{10A48}\\x{10A49}-\\x{10A4F}\\x{10A50}-\\x{10A58}\\x{10A59}-\\x{10A5F}\\x{10A60}-\\x{10A7C}\\x{10A7D}-\\x{10A7E}\\x{10A7F}\\x{10A80}-\\x{10A9C}\\x{10A9D}-\\x{10A9F}\\x{10AA0}-\\x{10ABF}\\x{10AC0}-\\x{10AC7}\\x{10AC8}\\x{10AC9}-\\x{10AE4}\\x{10AE5}-\\x{10AE6}\\x{10AE7}-\\x{10AEA}\\x{10AEB}-\\x{10AEF}\\x{10AF0}-\\x{10AF6}\\x{10AF7}-\\x{10AFF}\\x{10B00}-\\x{10B35}\\x{10B36}-\\x{10B38}\\x{10B39}-\\x{10B3F}\\x{10B40}-\\x{10B55}\\x{10B56}-\\x{10B57}\\x{10B58}-\\x{10B5F}\\x{10B60}-\\x{10B72}\\x{10B73}-\\x{10B77}\\x{10B78}-\\x{10B7F}\\x{10B80}-\\x{10B91}\\x{10B92}-\\x{10B98}\\x{10B99}-\\x{10B9C}\\x{10B9D}-\\x{10BA8}\\x{10BA9}-\\x{10BAF}\\x{10BB0}-\\x{10BFF}\\x{10C00}-\\x{10C48}\\x{10C49}-\\x{10C7F}\\x{10C80}-\\x{10CB2}\\x{10CB3}-\\x{10CBF}\\x{10CC0}-\\x{10CF2}\\x{10CF3}-\\x{10CF9}\\x{10CFA}-\\x{10CFF}\\x{10D00}-\\x{10D23}\\x{10D24}-\\x{10D27}\\x{10D28}-\\x{10D2F}\\x{10D30}-\\x{10D39}\\x{10D3A}-\\x{10D3F}\\x{10D40}-\\x{10E5F}\\x{10E60}-\\x{10E7E}\\x{10E7F}\\x{10E80}-\\x{10EA9}\\x{10EAA}\\x{10EAB}-\\x{10EAC}\\x{10EAD}\\x{10EAE}-\\x{10EAF}\\x{10EB0}-\\x{10EB1}\\x{10EB2}-\\x{10EFF}\\x{10F00}-\\x{10F1C}\\x{10F1D}-\\x{10F26}\\x{10F27}\\x{10F28}-\\x{10F2F}\\x{10F30}-\\x{10F45}\\x{10F46}-\\x{10F50}\\x{10F51}-\\x{10F54}\\x{10F55}-\\x{10F59}\\x{10F5A}-\\x{10F6F}\\x{10F70}-\\x{10FAF}\\x{10FB0}-\\x{10FC4}\\x{10FC5}-\\x{10FCB}\\x{10FCC}-\\x{10FDF}\\x{10FE0}-\\x{10FF6}\\x{10FF7}-\\x{10FFF}\\x{11001}\\x{11038}-\\x{11046}\\x{11052}-\\x{11065}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{111CF}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{11660}-\\x{1166C}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{1193B}-\\x{1193C}\\x{1193E}\\x{11943}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119E0}\\x{11A01}-\\x{11A06}\\x{11A09}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{11FD5}-\\x{11FDC}\\x{11FDD}-\\x{11FE0}\\x{11FE1}-\\x{11FF1}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F8F}-\\x{16F92}\\x{16FE2}\\x{16FE4}\\x{1BC9D}-\\x{1BC9E}\\x{1BCA0}-\\x{1BCA3}\\x{1D167}-\\x{1D169}\\x{1D173}-\\x{1D17A}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D200}-\\x{1D241}\\x{1D242}-\\x{1D244}\\x{1D245}\\x{1D300}-\\x{1D356}\\x{1D6DB}\\x{1D715}\\x{1D74F}\\x{1D789}\\x{1D7C3}\\x{1D7CE}-\\x{1D7FF}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E2FF}\\x{1E800}-\\x{1E8C4}\\x{1E8C5}-\\x{1E8C6}\\x{1E8C7}-\\x{1E8CF}\\x{1E8D0}-\\x{1E8D6}\\x{1E8D7}-\\x{1E8FF}\\x{1E900}-\\x{1E943}\\x{1E944}-\\x{1E94A}\\x{1E94B}\\x{1E94C}-\\x{1E94F}\\x{1E950}-\\x{1E959}\\x{1E95A}-\\x{1E95D}\\x{1E95E}-\\x{1E95F}\\x{1E960}-\\x{1EC6F}\\x{1EC70}\\x{1EC71}-\\x{1ECAB}\\x{1ECAC}\\x{1ECAD}-\\x{1ECAF}\\x{1ECB0}\\x{1ECB1}-\\x{1ECB4}\\x{1ECB5}-\\x{1ECBF}\\x{1ECC0}-\\x{1ECFF}\\x{1ED00}\\x{1ED01}-\\x{1ED2D}\\x{1ED2E}\\x{1ED2F}-\\x{1ED3D}\\x{1ED3E}-\\x{1ED4F}\\x{1ED50}-\\x{1EDFF}\\x{1EE00}-\\x{1EE03}\\x{1EE04}\\x{1EE05}-\\x{1EE1F}\\x{1EE20}\\x{1EE21}-\\x{1EE22}\\x{1EE23}\\x{1EE24}\\x{1EE25}-\\x{1EE26}\\x{1EE27}\\x{1EE28}\\x{1EE29}-\\x{1EE32}\\x{1EE33}\\x{1EE34}-\\x{1EE37}\\x{1EE38}\\x{1EE39}\\x{1EE3A}\\x{1EE3B}\\x{1EE3C}-\\x{1EE41}\\x{1EE42}\\x{1EE43}-\\x{1EE46}\\x{1EE47}\\x{1EE48}\\x{1EE49}\\x{1EE4A}\\x{1EE4B}\\x{1EE4C}\\x{1EE4D}-\\x{1EE4F}\\x{1EE50}\\x{1EE51}-\\x{1EE52}\\x{1EE53}\\x{1EE54}\\x{1EE55}-\\x{1EE56}\\x{1EE57}\\x{1EE58}\\x{1EE59}\\x{1EE5A}\\x{1EE5B}\\x{1EE5C}\\x{1EE5D}\\x{1EE5E}\\x{1EE5F}\\x{1EE60}\\x{1EE61}-\\x{1EE62}\\x{1EE63}\\x{1EE64}\\x{1EE65}-\\x{1EE66}\\x{1EE67}-\\x{1EE6A}\\x{1EE6B}\\x{1EE6C}-\\x{1EE72}\\x{1EE73}\\x{1EE74}-\\x{1EE77}\\x{1EE78}\\x{1EE79}-\\x{1EE7C}\\x{1EE7D}\\x{1EE7E}\\x{1EE7F}\\x{1EE80}-\\x{1EE89}\\x{1EE8A}\\x{1EE8B}-\\x{1EE9B}\\x{1EE9C}-\\x{1EEA0}\\x{1EEA1}-\\x{1EEA3}\\x{1EEA4}\\x{1EEA5}-\\x{1EEA9}\\x{1EEAA}\\x{1EEAB}-\\x{1EEBB}\\x{1EEBC}-\\x{1EEEF}\\x{1EEF0}-\\x{1EEF1}\\x{1EEF2}-\\x{1EEFF}\\x{1EF00}-\\x{1EFFF}\\x{1F000}-\\x{1F02B}\\x{1F030}-\\x{1F093}\\x{1F0A0}-\\x{1F0AE}\\x{1F0B1}-\\x{1F0BF}\\x{1F0C1}-\\x{1F0CF}\\x{1F0D1}-\\x{1F0F5}\\x{1F100}-\\x{1F10A}\\x{1F10B}-\\x{1F10C}\\x{1F10D}-\\x{1F10F}\\x{1F12F}\\x{1F16A}-\\x{1F16F}\\x{1F1AD}\\x{1F260}-\\x{1F265}\\x{1F300}-\\x{1F3FA}\\x{1F3FB}-\\x{1F3FF}\\x{1F400}-\\x{1F6D7}\\x{1F6E0}-\\x{1F6EC}\\x{1F6F0}-\\x{1F6FC}\\x{1F700}-\\x{1F773}\\x{1F780}-\\x{1F7D8}\\x{1F7E0}-\\x{1F7EB}\\x{1F800}-\\x{1F80B}\\x{1F810}-\\x{1F847}\\x{1F850}-\\x{1F859}\\x{1F860}-\\x{1F887}\\x{1F890}-\\x{1F8AD}\\x{1F8B0}-\\x{1F8B1}\\x{1F900}-\\x{1F978}\\x{1F97A}-\\x{1F9CB}\\x{1F9CD}-\\x{1FA53}\\x{1FA60}-\\x{1FA6D}\\x{1FA70}-\\x{1FA74}\\x{1FA78}-\\x{1FA7A}\\x{1FA80}-\\x{1FA86}\\x{1FA90}-\\x{1FAA8}\\x{1FAB0}-\\x{1FAB6}\\x{1FAC0}-\\x{1FAC2}\\x{1FAD0}-\\x{1FAD6}\\x{1FB00}-\\x{1FB92}\\x{1FB94}-\\x{1FBCA}\\x{1FBF0}-\\x{1FBF9}\\x{1FFFE}-\\x{1FFFF}\\x{2FFFE}-\\x{2FFFF}\\x{3FFFE}-\\x{3FFFF}\\x{4FFFE}-\\x{4FFFF}\\x{5FFFE}-\\x{5FFFF}\\x{6FFFE}-\\x{6FFFF}\\x{7FFFE}-\\x{7FFFF}\\x{8FFFE}-\\x{8FFFF}\\x{9FFFE}-\\x{9FFFF}\\x{AFFFE}-\\x{AFFFF}\\x{BFFFE}-\\x{BFFFF}\\x{CFFFE}-\\x{CFFFF}\\x{DFFFE}-\\x{E0000}\\x{E0001}\\x{E0002}-\\x{E001F}\\x{E0020}-\\x{E007F}\\x{E0080}-\\x{E00FF}\\x{E0100}-\\x{E01EF}\\x{E01F0}-\\x{E0FFF}\\x{EFFFE}-\\x{EFFFF}\\x{FFFFE}-\\x{FFFFF}\\x{10FFFE}-\\x{10FFFF}]/u'; + const BIDI_STEP_1_RTL = '/^[\\x{0590}\\x{05BE}\\x{05C0}\\x{05C3}\\x{05C6}\\x{05C8}-\\x{05CF}\\x{05D0}-\\x{05EA}\\x{05EB}-\\x{05EE}\\x{05EF}-\\x{05F2}\\x{05F3}-\\x{05F4}\\x{05F5}-\\x{05FF}\\x{0608}\\x{060B}\\x{060D}\\x{061B}\\x{061C}\\x{061D}\\x{061E}-\\x{061F}\\x{0620}-\\x{063F}\\x{0640}\\x{0641}-\\x{064A}\\x{066D}\\x{066E}-\\x{066F}\\x{0671}-\\x{06D3}\\x{06D4}\\x{06D5}\\x{06E5}-\\x{06E6}\\x{06EE}-\\x{06EF}\\x{06FA}-\\x{06FC}\\x{06FD}-\\x{06FE}\\x{06FF}\\x{0700}-\\x{070D}\\x{070E}\\x{070F}\\x{0710}\\x{0712}-\\x{072F}\\x{074B}-\\x{074C}\\x{074D}-\\x{07A5}\\x{07B1}\\x{07B2}-\\x{07BF}\\x{07C0}-\\x{07C9}\\x{07CA}-\\x{07EA}\\x{07F4}-\\x{07F5}\\x{07FA}\\x{07FB}-\\x{07FC}\\x{07FE}-\\x{07FF}\\x{0800}-\\x{0815}\\x{081A}\\x{0824}\\x{0828}\\x{082E}-\\x{082F}\\x{0830}-\\x{083E}\\x{083F}\\x{0840}-\\x{0858}\\x{085C}-\\x{085D}\\x{085E}\\x{085F}\\x{0860}-\\x{086A}\\x{086B}-\\x{086F}\\x{0870}-\\x{089F}\\x{08A0}-\\x{08B4}\\x{08B5}\\x{08B6}-\\x{08C7}\\x{08C8}-\\x{08D2}\\x{200F}\\x{FB1D}\\x{FB1F}-\\x{FB28}\\x{FB2A}-\\x{FB36}\\x{FB37}\\x{FB38}-\\x{FB3C}\\x{FB3D}\\x{FB3E}\\x{FB3F}\\x{FB40}-\\x{FB41}\\x{FB42}\\x{FB43}-\\x{FB44}\\x{FB45}\\x{FB46}-\\x{FB4F}\\x{FB50}-\\x{FBB1}\\x{FBB2}-\\x{FBC1}\\x{FBC2}-\\x{FBD2}\\x{FBD3}-\\x{FD3D}\\x{FD40}-\\x{FD4F}\\x{FD50}-\\x{FD8F}\\x{FD90}-\\x{FD91}\\x{FD92}-\\x{FDC7}\\x{FDC8}-\\x{FDCF}\\x{FDF0}-\\x{FDFB}\\x{FDFC}\\x{FDFE}-\\x{FDFF}\\x{FE70}-\\x{FE74}\\x{FE75}\\x{FE76}-\\x{FEFC}\\x{FEFD}-\\x{FEFE}\\x{10800}-\\x{10805}\\x{10806}-\\x{10807}\\x{10808}\\x{10809}\\x{1080A}-\\x{10835}\\x{10836}\\x{10837}-\\x{10838}\\x{10839}-\\x{1083B}\\x{1083C}\\x{1083D}-\\x{1083E}\\x{1083F}-\\x{10855}\\x{10856}\\x{10857}\\x{10858}-\\x{1085F}\\x{10860}-\\x{10876}\\x{10877}-\\x{10878}\\x{10879}-\\x{1087F}\\x{10880}-\\x{1089E}\\x{1089F}-\\x{108A6}\\x{108A7}-\\x{108AF}\\x{108B0}-\\x{108DF}\\x{108E0}-\\x{108F2}\\x{108F3}\\x{108F4}-\\x{108F5}\\x{108F6}-\\x{108FA}\\x{108FB}-\\x{108FF}\\x{10900}-\\x{10915}\\x{10916}-\\x{1091B}\\x{1091C}-\\x{1091E}\\x{10920}-\\x{10939}\\x{1093A}-\\x{1093E}\\x{1093F}\\x{10940}-\\x{1097F}\\x{10980}-\\x{109B7}\\x{109B8}-\\x{109BB}\\x{109BC}-\\x{109BD}\\x{109BE}-\\x{109BF}\\x{109C0}-\\x{109CF}\\x{109D0}-\\x{109D1}\\x{109D2}-\\x{109FF}\\x{10A00}\\x{10A04}\\x{10A07}-\\x{10A0B}\\x{10A10}-\\x{10A13}\\x{10A14}\\x{10A15}-\\x{10A17}\\x{10A18}\\x{10A19}-\\x{10A35}\\x{10A36}-\\x{10A37}\\x{10A3B}-\\x{10A3E}\\x{10A40}-\\x{10A48}\\x{10A49}-\\x{10A4F}\\x{10A50}-\\x{10A58}\\x{10A59}-\\x{10A5F}\\x{10A60}-\\x{10A7C}\\x{10A7D}-\\x{10A7E}\\x{10A7F}\\x{10A80}-\\x{10A9C}\\x{10A9D}-\\x{10A9F}\\x{10AA0}-\\x{10ABF}\\x{10AC0}-\\x{10AC7}\\x{10AC8}\\x{10AC9}-\\x{10AE4}\\x{10AE7}-\\x{10AEA}\\x{10AEB}-\\x{10AEF}\\x{10AF0}-\\x{10AF6}\\x{10AF7}-\\x{10AFF}\\x{10B00}-\\x{10B35}\\x{10B36}-\\x{10B38}\\x{10B40}-\\x{10B55}\\x{10B56}-\\x{10B57}\\x{10B58}-\\x{10B5F}\\x{10B60}-\\x{10B72}\\x{10B73}-\\x{10B77}\\x{10B78}-\\x{10B7F}\\x{10B80}-\\x{10B91}\\x{10B92}-\\x{10B98}\\x{10B99}-\\x{10B9C}\\x{10B9D}-\\x{10BA8}\\x{10BA9}-\\x{10BAF}\\x{10BB0}-\\x{10BFF}\\x{10C00}-\\x{10C48}\\x{10C49}-\\x{10C7F}\\x{10C80}-\\x{10CB2}\\x{10CB3}-\\x{10CBF}\\x{10CC0}-\\x{10CF2}\\x{10CF3}-\\x{10CF9}\\x{10CFA}-\\x{10CFF}\\x{10D00}-\\x{10D23}\\x{10D28}-\\x{10D2F}\\x{10D3A}-\\x{10D3F}\\x{10D40}-\\x{10E5F}\\x{10E7F}\\x{10E80}-\\x{10EA9}\\x{10EAA}\\x{10EAD}\\x{10EAE}-\\x{10EAF}\\x{10EB0}-\\x{10EB1}\\x{10EB2}-\\x{10EFF}\\x{10F00}-\\x{10F1C}\\x{10F1D}-\\x{10F26}\\x{10F27}\\x{10F28}-\\x{10F2F}\\x{10F30}-\\x{10F45}\\x{10F51}-\\x{10F54}\\x{10F55}-\\x{10F59}\\x{10F5A}-\\x{10F6F}\\x{10F70}-\\x{10FAF}\\x{10FB0}-\\x{10FC4}\\x{10FC5}-\\x{10FCB}\\x{10FCC}-\\x{10FDF}\\x{10FE0}-\\x{10FF6}\\x{10FF7}-\\x{10FFF}\\x{1E800}-\\x{1E8C4}\\x{1E8C5}-\\x{1E8C6}\\x{1E8C7}-\\x{1E8CF}\\x{1E8D7}-\\x{1E8FF}\\x{1E900}-\\x{1E943}\\x{1E94B}\\x{1E94C}-\\x{1E94F}\\x{1E950}-\\x{1E959}\\x{1E95A}-\\x{1E95D}\\x{1E95E}-\\x{1E95F}\\x{1E960}-\\x{1EC6F}\\x{1EC70}\\x{1EC71}-\\x{1ECAB}\\x{1ECAC}\\x{1ECAD}-\\x{1ECAF}\\x{1ECB0}\\x{1ECB1}-\\x{1ECB4}\\x{1ECB5}-\\x{1ECBF}\\x{1ECC0}-\\x{1ECFF}\\x{1ED00}\\x{1ED01}-\\x{1ED2D}\\x{1ED2E}\\x{1ED2F}-\\x{1ED3D}\\x{1ED3E}-\\x{1ED4F}\\x{1ED50}-\\x{1EDFF}\\x{1EE00}-\\x{1EE03}\\x{1EE04}\\x{1EE05}-\\x{1EE1F}\\x{1EE20}\\x{1EE21}-\\x{1EE22}\\x{1EE23}\\x{1EE24}\\x{1EE25}-\\x{1EE26}\\x{1EE27}\\x{1EE28}\\x{1EE29}-\\x{1EE32}\\x{1EE33}\\x{1EE34}-\\x{1EE37}\\x{1EE38}\\x{1EE39}\\x{1EE3A}\\x{1EE3B}\\x{1EE3C}-\\x{1EE41}\\x{1EE42}\\x{1EE43}-\\x{1EE46}\\x{1EE47}\\x{1EE48}\\x{1EE49}\\x{1EE4A}\\x{1EE4B}\\x{1EE4C}\\x{1EE4D}-\\x{1EE4F}\\x{1EE50}\\x{1EE51}-\\x{1EE52}\\x{1EE53}\\x{1EE54}\\x{1EE55}-\\x{1EE56}\\x{1EE57}\\x{1EE58}\\x{1EE59}\\x{1EE5A}\\x{1EE5B}\\x{1EE5C}\\x{1EE5D}\\x{1EE5E}\\x{1EE5F}\\x{1EE60}\\x{1EE61}-\\x{1EE62}\\x{1EE63}\\x{1EE64}\\x{1EE65}-\\x{1EE66}\\x{1EE67}-\\x{1EE6A}\\x{1EE6B}\\x{1EE6C}-\\x{1EE72}\\x{1EE73}\\x{1EE74}-\\x{1EE77}\\x{1EE78}\\x{1EE79}-\\x{1EE7C}\\x{1EE7D}\\x{1EE7E}\\x{1EE7F}\\x{1EE80}-\\x{1EE89}\\x{1EE8A}\\x{1EE8B}-\\x{1EE9B}\\x{1EE9C}-\\x{1EEA0}\\x{1EEA1}-\\x{1EEA3}\\x{1EEA4}\\x{1EEA5}-\\x{1EEA9}\\x{1EEAA}\\x{1EEAB}-\\x{1EEBB}\\x{1EEBC}-\\x{1EEEF}\\x{1EEF2}-\\x{1EEFF}\\x{1EF00}-\\x{1EFFF}]/u'; + const BIDI_STEP_2 = '/[^\\x{0000}-\\x{0008}\\x{000E}-\\x{001B}\\x{0021}-\\x{0022}\\x{0023}\\x{0024}\\x{0025}\\x{0026}-\\x{0027}\\x{0028}\\x{0029}\\x{002A}\\x{002B}\\x{002C}\\x{002D}\\x{002E}-\\x{002F}\\x{0030}-\\x{0039}\\x{003A}\\x{003B}\\x{003C}-\\x{003E}\\x{003F}-\\x{0040}\\x{005B}\\x{005C}\\x{005D}\\x{005E}\\x{005F}\\x{0060}\\x{007B}\\x{007C}\\x{007D}\\x{007E}\\x{007F}-\\x{0084}\\x{0086}-\\x{009F}\\x{00A0}\\x{00A1}\\x{00A2}-\\x{00A5}\\x{00A6}\\x{00A7}\\x{00A8}\\x{00A9}\\x{00AB}\\x{00AC}\\x{00AD}\\x{00AE}\\x{00AF}\\x{00B0}\\x{00B1}\\x{00B2}-\\x{00B3}\\x{00B4}\\x{00B6}-\\x{00B7}\\x{00B8}\\x{00B9}\\x{00BB}\\x{00BC}-\\x{00BE}\\x{00BF}\\x{00D7}\\x{00F7}\\x{02B9}-\\x{02BA}\\x{02C2}-\\x{02C5}\\x{02C6}-\\x{02CF}\\x{02D2}-\\x{02DF}\\x{02E5}-\\x{02EB}\\x{02EC}\\x{02ED}\\x{02EF}-\\x{02FF}\\x{0300}-\\x{036F}\\x{0374}\\x{0375}\\x{037E}\\x{0384}-\\x{0385}\\x{0387}\\x{03F6}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{058A}\\x{058D}-\\x{058E}\\x{058F}\\x{0590}\\x{0591}-\\x{05BD}\\x{05BE}\\x{05BF}\\x{05C0}\\x{05C1}-\\x{05C2}\\x{05C3}\\x{05C4}-\\x{05C5}\\x{05C6}\\x{05C7}\\x{05C8}-\\x{05CF}\\x{05D0}-\\x{05EA}\\x{05EB}-\\x{05EE}\\x{05EF}-\\x{05F2}\\x{05F3}-\\x{05F4}\\x{05F5}-\\x{05FF}\\x{0600}-\\x{0605}\\x{0606}-\\x{0607}\\x{0608}\\x{0609}-\\x{060A}\\x{060B}\\x{060C}\\x{060D}\\x{060E}-\\x{060F}\\x{0610}-\\x{061A}\\x{061B}\\x{061C}\\x{061D}\\x{061E}-\\x{061F}\\x{0620}-\\x{063F}\\x{0640}\\x{0641}-\\x{064A}\\x{064B}-\\x{065F}\\x{0660}-\\x{0669}\\x{066A}\\x{066B}-\\x{066C}\\x{066D}\\x{066E}-\\x{066F}\\x{0670}\\x{0671}-\\x{06D3}\\x{06D4}\\x{06D5}\\x{06D6}-\\x{06DC}\\x{06DD}\\x{06DE}\\x{06DF}-\\x{06E4}\\x{06E5}-\\x{06E6}\\x{06E7}-\\x{06E8}\\x{06E9}\\x{06EA}-\\x{06ED}\\x{06EE}-\\x{06EF}\\x{06F0}-\\x{06F9}\\x{06FA}-\\x{06FC}\\x{06FD}-\\x{06FE}\\x{06FF}\\x{0700}-\\x{070D}\\x{070E}\\x{070F}\\x{0710}\\x{0711}\\x{0712}-\\x{072F}\\x{0730}-\\x{074A}\\x{074B}-\\x{074C}\\x{074D}-\\x{07A5}\\x{07A6}-\\x{07B0}\\x{07B1}\\x{07B2}-\\x{07BF}\\x{07C0}-\\x{07C9}\\x{07CA}-\\x{07EA}\\x{07EB}-\\x{07F3}\\x{07F4}-\\x{07F5}\\x{07F6}\\x{07F7}-\\x{07F9}\\x{07FA}\\x{07FB}-\\x{07FC}\\x{07FD}\\x{07FE}-\\x{07FF}\\x{0800}-\\x{0815}\\x{0816}-\\x{0819}\\x{081A}\\x{081B}-\\x{0823}\\x{0824}\\x{0825}-\\x{0827}\\x{0828}\\x{0829}-\\x{082D}\\x{082E}-\\x{082F}\\x{0830}-\\x{083E}\\x{083F}\\x{0840}-\\x{0858}\\x{0859}-\\x{085B}\\x{085C}-\\x{085D}\\x{085E}\\x{085F}\\x{0860}-\\x{086A}\\x{086B}-\\x{086F}\\x{0870}-\\x{089F}\\x{08A0}-\\x{08B4}\\x{08B5}\\x{08B6}-\\x{08C7}\\x{08C8}-\\x{08D2}\\x{08D3}-\\x{08E1}\\x{08E2}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09F2}-\\x{09F3}\\x{09FB}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AF1}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0BF3}-\\x{0BF8}\\x{0BF9}\\x{0BFA}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C78}-\\x{0C7E}\\x{0C81}\\x{0CBC}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E3F}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F3A}\\x{0F3B}\\x{0F3C}\\x{0F3D}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{135D}-\\x{135F}\\x{1390}-\\x{1399}\\x{1400}\\x{169B}\\x{169C}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17DB}\\x{17DD}\\x{17F0}-\\x{17F9}\\x{1800}-\\x{1805}\\x{1806}\\x{1807}-\\x{180A}\\x{180B}-\\x{180D}\\x{180E}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1940}\\x{1944}-\\x{1945}\\x{19DE}-\\x{19FF}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{1FBD}\\x{1FBF}-\\x{1FC1}\\x{1FCD}-\\x{1FCF}\\x{1FDD}-\\x{1FDF}\\x{1FED}-\\x{1FEF}\\x{1FFD}-\\x{1FFE}\\x{200B}-\\x{200D}\\x{200F}\\x{2010}-\\x{2015}\\x{2016}-\\x{2017}\\x{2018}\\x{2019}\\x{201A}\\x{201B}-\\x{201C}\\x{201D}\\x{201E}\\x{201F}\\x{2020}-\\x{2027}\\x{202F}\\x{2030}-\\x{2034}\\x{2035}-\\x{2038}\\x{2039}\\x{203A}\\x{203B}-\\x{203E}\\x{203F}-\\x{2040}\\x{2041}-\\x{2043}\\x{2044}\\x{2045}\\x{2046}\\x{2047}-\\x{2051}\\x{2052}\\x{2053}\\x{2054}\\x{2055}-\\x{205E}\\x{2060}-\\x{2064}\\x{2065}\\x{206A}-\\x{206F}\\x{2070}\\x{2074}-\\x{2079}\\x{207A}-\\x{207B}\\x{207C}\\x{207D}\\x{207E}\\x{2080}-\\x{2089}\\x{208A}-\\x{208B}\\x{208C}\\x{208D}\\x{208E}\\x{20A0}-\\x{20BF}\\x{20C0}-\\x{20CF}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2100}-\\x{2101}\\x{2103}-\\x{2106}\\x{2108}-\\x{2109}\\x{2114}\\x{2116}-\\x{2117}\\x{2118}\\x{211E}-\\x{2123}\\x{2125}\\x{2127}\\x{2129}\\x{212E}\\x{213A}-\\x{213B}\\x{2140}-\\x{2144}\\x{214A}\\x{214B}\\x{214C}-\\x{214D}\\x{2150}-\\x{215F}\\x{2189}\\x{218A}-\\x{218B}\\x{2190}-\\x{2194}\\x{2195}-\\x{2199}\\x{219A}-\\x{219B}\\x{219C}-\\x{219F}\\x{21A0}\\x{21A1}-\\x{21A2}\\x{21A3}\\x{21A4}-\\x{21A5}\\x{21A6}\\x{21A7}-\\x{21AD}\\x{21AE}\\x{21AF}-\\x{21CD}\\x{21CE}-\\x{21CF}\\x{21D0}-\\x{21D1}\\x{21D2}\\x{21D3}\\x{21D4}\\x{21D5}-\\x{21F3}\\x{21F4}-\\x{2211}\\x{2212}\\x{2213}\\x{2214}-\\x{22FF}\\x{2300}-\\x{2307}\\x{2308}\\x{2309}\\x{230A}\\x{230B}\\x{230C}-\\x{231F}\\x{2320}-\\x{2321}\\x{2322}-\\x{2328}\\x{2329}\\x{232A}\\x{232B}-\\x{2335}\\x{237B}\\x{237C}\\x{237D}-\\x{2394}\\x{2396}-\\x{239A}\\x{239B}-\\x{23B3}\\x{23B4}-\\x{23DB}\\x{23DC}-\\x{23E1}\\x{23E2}-\\x{2426}\\x{2440}-\\x{244A}\\x{2460}-\\x{2487}\\x{2488}-\\x{249B}\\x{24EA}-\\x{24FF}\\x{2500}-\\x{25B6}\\x{25B7}\\x{25B8}-\\x{25C0}\\x{25C1}\\x{25C2}-\\x{25F7}\\x{25F8}-\\x{25FF}\\x{2600}-\\x{266E}\\x{266F}\\x{2670}-\\x{26AB}\\x{26AD}-\\x{2767}\\x{2768}\\x{2769}\\x{276A}\\x{276B}\\x{276C}\\x{276D}\\x{276E}\\x{276F}\\x{2770}\\x{2771}\\x{2772}\\x{2773}\\x{2774}\\x{2775}\\x{2776}-\\x{2793}\\x{2794}-\\x{27BF}\\x{27C0}-\\x{27C4}\\x{27C5}\\x{27C6}\\x{27C7}-\\x{27E5}\\x{27E6}\\x{27E7}\\x{27E8}\\x{27E9}\\x{27EA}\\x{27EB}\\x{27EC}\\x{27ED}\\x{27EE}\\x{27EF}\\x{27F0}-\\x{27FF}\\x{2900}-\\x{2982}\\x{2983}\\x{2984}\\x{2985}\\x{2986}\\x{2987}\\x{2988}\\x{2989}\\x{298A}\\x{298B}\\x{298C}\\x{298D}\\x{298E}\\x{298F}\\x{2990}\\x{2991}\\x{2992}\\x{2993}\\x{2994}\\x{2995}\\x{2996}\\x{2997}\\x{2998}\\x{2999}-\\x{29D7}\\x{29D8}\\x{29D9}\\x{29DA}\\x{29DB}\\x{29DC}-\\x{29FB}\\x{29FC}\\x{29FD}\\x{29FE}-\\x{2AFF}\\x{2B00}-\\x{2B2F}\\x{2B30}-\\x{2B44}\\x{2B45}-\\x{2B46}\\x{2B47}-\\x{2B4C}\\x{2B4D}-\\x{2B73}\\x{2B76}-\\x{2B95}\\x{2B97}-\\x{2BFF}\\x{2CE5}-\\x{2CEA}\\x{2CEF}-\\x{2CF1}\\x{2CF9}-\\x{2CFC}\\x{2CFD}\\x{2CFE}-\\x{2CFF}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{2E00}-\\x{2E01}\\x{2E02}\\x{2E03}\\x{2E04}\\x{2E05}\\x{2E06}-\\x{2E08}\\x{2E09}\\x{2E0A}\\x{2E0B}\\x{2E0C}\\x{2E0D}\\x{2E0E}-\\x{2E16}\\x{2E17}\\x{2E18}-\\x{2E19}\\x{2E1A}\\x{2E1B}\\x{2E1C}\\x{2E1D}\\x{2E1E}-\\x{2E1F}\\x{2E20}\\x{2E21}\\x{2E22}\\x{2E23}\\x{2E24}\\x{2E25}\\x{2E26}\\x{2E27}\\x{2E28}\\x{2E29}\\x{2E2A}-\\x{2E2E}\\x{2E2F}\\x{2E30}-\\x{2E39}\\x{2E3A}-\\x{2E3B}\\x{2E3C}-\\x{2E3F}\\x{2E40}\\x{2E41}\\x{2E42}\\x{2E43}-\\x{2E4F}\\x{2E50}-\\x{2E51}\\x{2E52}\\x{2E80}-\\x{2E99}\\x{2E9B}-\\x{2EF3}\\x{2F00}-\\x{2FD5}\\x{2FF0}-\\x{2FFB}\\x{3001}-\\x{3003}\\x{3004}\\x{3008}\\x{3009}\\x{300A}\\x{300B}\\x{300C}\\x{300D}\\x{300E}\\x{300F}\\x{3010}\\x{3011}\\x{3012}-\\x{3013}\\x{3014}\\x{3015}\\x{3016}\\x{3017}\\x{3018}\\x{3019}\\x{301A}\\x{301B}\\x{301C}\\x{301D}\\x{301E}-\\x{301F}\\x{3020}\\x{302A}-\\x{302D}\\x{3030}\\x{3036}-\\x{3037}\\x{303D}\\x{303E}-\\x{303F}\\x{3099}-\\x{309A}\\x{309B}-\\x{309C}\\x{30A0}\\x{30FB}\\x{31C0}-\\x{31E3}\\x{321D}-\\x{321E}\\x{3250}\\x{3251}-\\x{325F}\\x{327C}-\\x{327E}\\x{32B1}-\\x{32BF}\\x{32CC}-\\x{32CF}\\x{3377}-\\x{337A}\\x{33DE}-\\x{33DF}\\x{33FF}\\x{4DC0}-\\x{4DFF}\\x{A490}-\\x{A4C6}\\x{A60D}-\\x{A60F}\\x{A66F}\\x{A670}-\\x{A672}\\x{A673}\\x{A674}-\\x{A67D}\\x{A67E}\\x{A67F}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A700}-\\x{A716}\\x{A717}-\\x{A71F}\\x{A720}-\\x{A721}\\x{A788}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A828}-\\x{A82B}\\x{A82C}\\x{A838}\\x{A839}\\x{A874}-\\x{A877}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}-\\x{A9BD}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEC}-\\x{AAED}\\x{AAF6}\\x{AB6A}-\\x{AB6B}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1D}\\x{FB1E}\\x{FB1F}-\\x{FB28}\\x{FB29}\\x{FB2A}-\\x{FB36}\\x{FB37}\\x{FB38}-\\x{FB3C}\\x{FB3D}\\x{FB3E}\\x{FB3F}\\x{FB40}-\\x{FB41}\\x{FB42}\\x{FB43}-\\x{FB44}\\x{FB45}\\x{FB46}-\\x{FB4F}\\x{FB50}-\\x{FBB1}\\x{FBB2}-\\x{FBC1}\\x{FBC2}-\\x{FBD2}\\x{FBD3}-\\x{FD3D}\\x{FD3E}\\x{FD3F}\\x{FD40}-\\x{FD4F}\\x{FD50}-\\x{FD8F}\\x{FD90}-\\x{FD91}\\x{FD92}-\\x{FDC7}\\x{FDC8}-\\x{FDCF}\\x{FDD0}-\\x{FDEF}\\x{FDF0}-\\x{FDFB}\\x{FDFC}\\x{FDFD}\\x{FDFE}-\\x{FDFF}\\x{FE00}-\\x{FE0F}\\x{FE10}-\\x{FE16}\\x{FE17}\\x{FE18}\\x{FE19}\\x{FE20}-\\x{FE2F}\\x{FE30}\\x{FE31}-\\x{FE32}\\x{FE33}-\\x{FE34}\\x{FE35}\\x{FE36}\\x{FE37}\\x{FE38}\\x{FE39}\\x{FE3A}\\x{FE3B}\\x{FE3C}\\x{FE3D}\\x{FE3E}\\x{FE3F}\\x{FE40}\\x{FE41}\\x{FE42}\\x{FE43}\\x{FE44}\\x{FE45}-\\x{FE46}\\x{FE47}\\x{FE48}\\x{FE49}-\\x{FE4C}\\x{FE4D}-\\x{FE4F}\\x{FE50}\\x{FE51}\\x{FE52}\\x{FE54}\\x{FE55}\\x{FE56}-\\x{FE57}\\x{FE58}\\x{FE59}\\x{FE5A}\\x{FE5B}\\x{FE5C}\\x{FE5D}\\x{FE5E}\\x{FE5F}\\x{FE60}-\\x{FE61}\\x{FE62}\\x{FE63}\\x{FE64}-\\x{FE66}\\x{FE68}\\x{FE69}\\x{FE6A}\\x{FE6B}\\x{FE70}-\\x{FE74}\\x{FE75}\\x{FE76}-\\x{FEFC}\\x{FEFD}-\\x{FEFE}\\x{FEFF}\\x{FF01}-\\x{FF02}\\x{FF03}\\x{FF04}\\x{FF05}\\x{FF06}-\\x{FF07}\\x{FF08}\\x{FF09}\\x{FF0A}\\x{FF0B}\\x{FF0C}\\x{FF0D}\\x{FF0E}-\\x{FF0F}\\x{FF10}-\\x{FF19}\\x{FF1A}\\x{FF1B}\\x{FF1C}-\\x{FF1E}\\x{FF1F}-\\x{FF20}\\x{FF3B}\\x{FF3C}\\x{FF3D}\\x{FF3E}\\x{FF3F}\\x{FF40}\\x{FF5B}\\x{FF5C}\\x{FF5D}\\x{FF5E}\\x{FF5F}\\x{FF60}\\x{FF61}\\x{FF62}\\x{FF63}\\x{FF64}-\\x{FF65}\\x{FFE0}-\\x{FFE1}\\x{FFE2}\\x{FFE3}\\x{FFE4}\\x{FFE5}-\\x{FFE6}\\x{FFE8}\\x{FFE9}-\\x{FFEC}\\x{FFED}-\\x{FFEE}\\x{FFF0}-\\x{FFF8}\\x{FFF9}-\\x{FFFB}\\x{FFFC}-\\x{FFFD}\\x{FFFE}-\\x{FFFF}\\x{10101}\\x{10140}-\\x{10174}\\x{10175}-\\x{10178}\\x{10179}-\\x{10189}\\x{1018A}-\\x{1018B}\\x{1018C}\\x{10190}-\\x{1019C}\\x{101A0}\\x{101FD}\\x{102E0}\\x{102E1}-\\x{102FB}\\x{10376}-\\x{1037A}\\x{10800}-\\x{10805}\\x{10806}-\\x{10807}\\x{10808}\\x{10809}\\x{1080A}-\\x{10835}\\x{10836}\\x{10837}-\\x{10838}\\x{10839}-\\x{1083B}\\x{1083C}\\x{1083D}-\\x{1083E}\\x{1083F}-\\x{10855}\\x{10856}\\x{10857}\\x{10858}-\\x{1085F}\\x{10860}-\\x{10876}\\x{10877}-\\x{10878}\\x{10879}-\\x{1087F}\\x{10880}-\\x{1089E}\\x{1089F}-\\x{108A6}\\x{108A7}-\\x{108AF}\\x{108B0}-\\x{108DF}\\x{108E0}-\\x{108F2}\\x{108F3}\\x{108F4}-\\x{108F5}\\x{108F6}-\\x{108FA}\\x{108FB}-\\x{108FF}\\x{10900}-\\x{10915}\\x{10916}-\\x{1091B}\\x{1091C}-\\x{1091E}\\x{1091F}\\x{10920}-\\x{10939}\\x{1093A}-\\x{1093E}\\x{1093F}\\x{10940}-\\x{1097F}\\x{10980}-\\x{109B7}\\x{109B8}-\\x{109BB}\\x{109BC}-\\x{109BD}\\x{109BE}-\\x{109BF}\\x{109C0}-\\x{109CF}\\x{109D0}-\\x{109D1}\\x{109D2}-\\x{109FF}\\x{10A00}\\x{10A01}-\\x{10A03}\\x{10A04}\\x{10A05}-\\x{10A06}\\x{10A07}-\\x{10A0B}\\x{10A0C}-\\x{10A0F}\\x{10A10}-\\x{10A13}\\x{10A14}\\x{10A15}-\\x{10A17}\\x{10A18}\\x{10A19}-\\x{10A35}\\x{10A36}-\\x{10A37}\\x{10A38}-\\x{10A3A}\\x{10A3B}-\\x{10A3E}\\x{10A3F}\\x{10A40}-\\x{10A48}\\x{10A49}-\\x{10A4F}\\x{10A50}-\\x{10A58}\\x{10A59}-\\x{10A5F}\\x{10A60}-\\x{10A7C}\\x{10A7D}-\\x{10A7E}\\x{10A7F}\\x{10A80}-\\x{10A9C}\\x{10A9D}-\\x{10A9F}\\x{10AA0}-\\x{10ABF}\\x{10AC0}-\\x{10AC7}\\x{10AC8}\\x{10AC9}-\\x{10AE4}\\x{10AE5}-\\x{10AE6}\\x{10AE7}-\\x{10AEA}\\x{10AEB}-\\x{10AEF}\\x{10AF0}-\\x{10AF6}\\x{10AF7}-\\x{10AFF}\\x{10B00}-\\x{10B35}\\x{10B36}-\\x{10B38}\\x{10B39}-\\x{10B3F}\\x{10B40}-\\x{10B55}\\x{10B56}-\\x{10B57}\\x{10B58}-\\x{10B5F}\\x{10B60}-\\x{10B72}\\x{10B73}-\\x{10B77}\\x{10B78}-\\x{10B7F}\\x{10B80}-\\x{10B91}\\x{10B92}-\\x{10B98}\\x{10B99}-\\x{10B9C}\\x{10B9D}-\\x{10BA8}\\x{10BA9}-\\x{10BAF}\\x{10BB0}-\\x{10BFF}\\x{10C00}-\\x{10C48}\\x{10C49}-\\x{10C7F}\\x{10C80}-\\x{10CB2}\\x{10CB3}-\\x{10CBF}\\x{10CC0}-\\x{10CF2}\\x{10CF3}-\\x{10CF9}\\x{10CFA}-\\x{10CFF}\\x{10D00}-\\x{10D23}\\x{10D24}-\\x{10D27}\\x{10D28}-\\x{10D2F}\\x{10D30}-\\x{10D39}\\x{10D3A}-\\x{10D3F}\\x{10D40}-\\x{10E5F}\\x{10E60}-\\x{10E7E}\\x{10E7F}\\x{10E80}-\\x{10EA9}\\x{10EAA}\\x{10EAB}-\\x{10EAC}\\x{10EAD}\\x{10EAE}-\\x{10EAF}\\x{10EB0}-\\x{10EB1}\\x{10EB2}-\\x{10EFF}\\x{10F00}-\\x{10F1C}\\x{10F1D}-\\x{10F26}\\x{10F27}\\x{10F28}-\\x{10F2F}\\x{10F30}-\\x{10F45}\\x{10F46}-\\x{10F50}\\x{10F51}-\\x{10F54}\\x{10F55}-\\x{10F59}\\x{10F5A}-\\x{10F6F}\\x{10F70}-\\x{10FAF}\\x{10FB0}-\\x{10FC4}\\x{10FC5}-\\x{10FCB}\\x{10FCC}-\\x{10FDF}\\x{10FE0}-\\x{10FF6}\\x{10FF7}-\\x{10FFF}\\x{11001}\\x{11038}-\\x{11046}\\x{11052}-\\x{11065}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{111CF}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{11660}-\\x{1166C}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{1193B}-\\x{1193C}\\x{1193E}\\x{11943}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119E0}\\x{11A01}-\\x{11A06}\\x{11A09}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{11FD5}-\\x{11FDC}\\x{11FDD}-\\x{11FE0}\\x{11FE1}-\\x{11FF1}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F8F}-\\x{16F92}\\x{16FE2}\\x{16FE4}\\x{1BC9D}-\\x{1BC9E}\\x{1BCA0}-\\x{1BCA3}\\x{1D167}-\\x{1D169}\\x{1D173}-\\x{1D17A}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D200}-\\x{1D241}\\x{1D242}-\\x{1D244}\\x{1D245}\\x{1D300}-\\x{1D356}\\x{1D6DB}\\x{1D715}\\x{1D74F}\\x{1D789}\\x{1D7C3}\\x{1D7CE}-\\x{1D7FF}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E2FF}\\x{1E800}-\\x{1E8C4}\\x{1E8C5}-\\x{1E8C6}\\x{1E8C7}-\\x{1E8CF}\\x{1E8D0}-\\x{1E8D6}\\x{1E8D7}-\\x{1E8FF}\\x{1E900}-\\x{1E943}\\x{1E944}-\\x{1E94A}\\x{1E94B}\\x{1E94C}-\\x{1E94F}\\x{1E950}-\\x{1E959}\\x{1E95A}-\\x{1E95D}\\x{1E95E}-\\x{1E95F}\\x{1E960}-\\x{1EC6F}\\x{1EC70}\\x{1EC71}-\\x{1ECAB}\\x{1ECAC}\\x{1ECAD}-\\x{1ECAF}\\x{1ECB0}\\x{1ECB1}-\\x{1ECB4}\\x{1ECB5}-\\x{1ECBF}\\x{1ECC0}-\\x{1ECFF}\\x{1ED00}\\x{1ED01}-\\x{1ED2D}\\x{1ED2E}\\x{1ED2F}-\\x{1ED3D}\\x{1ED3E}-\\x{1ED4F}\\x{1ED50}-\\x{1EDFF}\\x{1EE00}-\\x{1EE03}\\x{1EE04}\\x{1EE05}-\\x{1EE1F}\\x{1EE20}\\x{1EE21}-\\x{1EE22}\\x{1EE23}\\x{1EE24}\\x{1EE25}-\\x{1EE26}\\x{1EE27}\\x{1EE28}\\x{1EE29}-\\x{1EE32}\\x{1EE33}\\x{1EE34}-\\x{1EE37}\\x{1EE38}\\x{1EE39}\\x{1EE3A}\\x{1EE3B}\\x{1EE3C}-\\x{1EE41}\\x{1EE42}\\x{1EE43}-\\x{1EE46}\\x{1EE47}\\x{1EE48}\\x{1EE49}\\x{1EE4A}\\x{1EE4B}\\x{1EE4C}\\x{1EE4D}-\\x{1EE4F}\\x{1EE50}\\x{1EE51}-\\x{1EE52}\\x{1EE53}\\x{1EE54}\\x{1EE55}-\\x{1EE56}\\x{1EE57}\\x{1EE58}\\x{1EE59}\\x{1EE5A}\\x{1EE5B}\\x{1EE5C}\\x{1EE5D}\\x{1EE5E}\\x{1EE5F}\\x{1EE60}\\x{1EE61}-\\x{1EE62}\\x{1EE63}\\x{1EE64}\\x{1EE65}-\\x{1EE66}\\x{1EE67}-\\x{1EE6A}\\x{1EE6B}\\x{1EE6C}-\\x{1EE72}\\x{1EE73}\\x{1EE74}-\\x{1EE77}\\x{1EE78}\\x{1EE79}-\\x{1EE7C}\\x{1EE7D}\\x{1EE7E}\\x{1EE7F}\\x{1EE80}-\\x{1EE89}\\x{1EE8A}\\x{1EE8B}-\\x{1EE9B}\\x{1EE9C}-\\x{1EEA0}\\x{1EEA1}-\\x{1EEA3}\\x{1EEA4}\\x{1EEA5}-\\x{1EEA9}\\x{1EEAA}\\x{1EEAB}-\\x{1EEBB}\\x{1EEBC}-\\x{1EEEF}\\x{1EEF0}-\\x{1EEF1}\\x{1EEF2}-\\x{1EEFF}\\x{1EF00}-\\x{1EFFF}\\x{1F000}-\\x{1F02B}\\x{1F030}-\\x{1F093}\\x{1F0A0}-\\x{1F0AE}\\x{1F0B1}-\\x{1F0BF}\\x{1F0C1}-\\x{1F0CF}\\x{1F0D1}-\\x{1F0F5}\\x{1F100}-\\x{1F10A}\\x{1F10B}-\\x{1F10C}\\x{1F10D}-\\x{1F10F}\\x{1F12F}\\x{1F16A}-\\x{1F16F}\\x{1F1AD}\\x{1F260}-\\x{1F265}\\x{1F300}-\\x{1F3FA}\\x{1F3FB}-\\x{1F3FF}\\x{1F400}-\\x{1F6D7}\\x{1F6E0}-\\x{1F6EC}\\x{1F6F0}-\\x{1F6FC}\\x{1F700}-\\x{1F773}\\x{1F780}-\\x{1F7D8}\\x{1F7E0}-\\x{1F7EB}\\x{1F800}-\\x{1F80B}\\x{1F810}-\\x{1F847}\\x{1F850}-\\x{1F859}\\x{1F860}-\\x{1F887}\\x{1F890}-\\x{1F8AD}\\x{1F8B0}-\\x{1F8B1}\\x{1F900}-\\x{1F978}\\x{1F97A}-\\x{1F9CB}\\x{1F9CD}-\\x{1FA53}\\x{1FA60}-\\x{1FA6D}\\x{1FA70}-\\x{1FA74}\\x{1FA78}-\\x{1FA7A}\\x{1FA80}-\\x{1FA86}\\x{1FA90}-\\x{1FAA8}\\x{1FAB0}-\\x{1FAB6}\\x{1FAC0}-\\x{1FAC2}\\x{1FAD0}-\\x{1FAD6}\\x{1FB00}-\\x{1FB92}\\x{1FB94}-\\x{1FBCA}\\x{1FBF0}-\\x{1FBF9}\\x{1FFFE}-\\x{1FFFF}\\x{2FFFE}-\\x{2FFFF}\\x{3FFFE}-\\x{3FFFF}\\x{4FFFE}-\\x{4FFFF}\\x{5FFFE}-\\x{5FFFF}\\x{6FFFE}-\\x{6FFFF}\\x{7FFFE}-\\x{7FFFF}\\x{8FFFE}-\\x{8FFFF}\\x{9FFFE}-\\x{9FFFF}\\x{AFFFE}-\\x{AFFFF}\\x{BFFFE}-\\x{BFFFF}\\x{CFFFE}-\\x{CFFFF}\\x{DFFFE}-\\x{E0000}\\x{E0001}\\x{E0002}-\\x{E001F}\\x{E0020}-\\x{E007F}\\x{E0080}-\\x{E00FF}\\x{E0100}-\\x{E01EF}\\x{E01F0}-\\x{E0FFF}\\x{EFFFE}-\\x{EFFFF}\\x{FFFFE}-\\x{FFFFF}\\x{10FFFE}-\\x{10FFFF}]/u'; + const BIDI_STEP_3 = '/[\\x{0030}-\\x{0039}\\x{00B2}-\\x{00B3}\\x{00B9}\\x{0590}\\x{05BE}\\x{05C0}\\x{05C3}\\x{05C6}\\x{05C8}-\\x{05CF}\\x{05D0}-\\x{05EA}\\x{05EB}-\\x{05EE}\\x{05EF}-\\x{05F2}\\x{05F3}-\\x{05F4}\\x{05F5}-\\x{05FF}\\x{0600}-\\x{0605}\\x{0608}\\x{060B}\\x{060D}\\x{061B}\\x{061C}\\x{061D}\\x{061E}-\\x{061F}\\x{0620}-\\x{063F}\\x{0640}\\x{0641}-\\x{064A}\\x{0660}-\\x{0669}\\x{066B}-\\x{066C}\\x{066D}\\x{066E}-\\x{066F}\\x{0671}-\\x{06D3}\\x{06D4}\\x{06D5}\\x{06DD}\\x{06E5}-\\x{06E6}\\x{06EE}-\\x{06EF}\\x{06F0}-\\x{06F9}\\x{06FA}-\\x{06FC}\\x{06FD}-\\x{06FE}\\x{06FF}\\x{0700}-\\x{070D}\\x{070E}\\x{070F}\\x{0710}\\x{0712}-\\x{072F}\\x{074B}-\\x{074C}\\x{074D}-\\x{07A5}\\x{07B1}\\x{07B2}-\\x{07BF}\\x{07C0}-\\x{07C9}\\x{07CA}-\\x{07EA}\\x{07F4}-\\x{07F5}\\x{07FA}\\x{07FB}-\\x{07FC}\\x{07FE}-\\x{07FF}\\x{0800}-\\x{0815}\\x{081A}\\x{0824}\\x{0828}\\x{082E}-\\x{082F}\\x{0830}-\\x{083E}\\x{083F}\\x{0840}-\\x{0858}\\x{085C}-\\x{085D}\\x{085E}\\x{085F}\\x{0860}-\\x{086A}\\x{086B}-\\x{086F}\\x{0870}-\\x{089F}\\x{08A0}-\\x{08B4}\\x{08B5}\\x{08B6}-\\x{08C7}\\x{08C8}-\\x{08D2}\\x{08E2}\\x{200F}\\x{2070}\\x{2074}-\\x{2079}\\x{2080}-\\x{2089}\\x{2488}-\\x{249B}\\x{FB1D}\\x{FB1F}-\\x{FB28}\\x{FB2A}-\\x{FB36}\\x{FB37}\\x{FB38}-\\x{FB3C}\\x{FB3D}\\x{FB3E}\\x{FB3F}\\x{FB40}-\\x{FB41}\\x{FB42}\\x{FB43}-\\x{FB44}\\x{FB45}\\x{FB46}-\\x{FB4F}\\x{FB50}-\\x{FBB1}\\x{FBB2}-\\x{FBC1}\\x{FBC2}-\\x{FBD2}\\x{FBD3}-\\x{FD3D}\\x{FD40}-\\x{FD4F}\\x{FD50}-\\x{FD8F}\\x{FD90}-\\x{FD91}\\x{FD92}-\\x{FDC7}\\x{FDC8}-\\x{FDCF}\\x{FDF0}-\\x{FDFB}\\x{FDFC}\\x{FDFE}-\\x{FDFF}\\x{FE70}-\\x{FE74}\\x{FE75}\\x{FE76}-\\x{FEFC}\\x{FEFD}-\\x{FEFE}\\x{FF10}-\\x{FF19}\\x{102E1}-\\x{102FB}\\x{10800}-\\x{10805}\\x{10806}-\\x{10807}\\x{10808}\\x{10809}\\x{1080A}-\\x{10835}\\x{10836}\\x{10837}-\\x{10838}\\x{10839}-\\x{1083B}\\x{1083C}\\x{1083D}-\\x{1083E}\\x{1083F}-\\x{10855}\\x{10856}\\x{10857}\\x{10858}-\\x{1085F}\\x{10860}-\\x{10876}\\x{10877}-\\x{10878}\\x{10879}-\\x{1087F}\\x{10880}-\\x{1089E}\\x{1089F}-\\x{108A6}\\x{108A7}-\\x{108AF}\\x{108B0}-\\x{108DF}\\x{108E0}-\\x{108F2}\\x{108F3}\\x{108F4}-\\x{108F5}\\x{108F6}-\\x{108FA}\\x{108FB}-\\x{108FF}\\x{10900}-\\x{10915}\\x{10916}-\\x{1091B}\\x{1091C}-\\x{1091E}\\x{10920}-\\x{10939}\\x{1093A}-\\x{1093E}\\x{1093F}\\x{10940}-\\x{1097F}\\x{10980}-\\x{109B7}\\x{109B8}-\\x{109BB}\\x{109BC}-\\x{109BD}\\x{109BE}-\\x{109BF}\\x{109C0}-\\x{109CF}\\x{109D0}-\\x{109D1}\\x{109D2}-\\x{109FF}\\x{10A00}\\x{10A04}\\x{10A07}-\\x{10A0B}\\x{10A10}-\\x{10A13}\\x{10A14}\\x{10A15}-\\x{10A17}\\x{10A18}\\x{10A19}-\\x{10A35}\\x{10A36}-\\x{10A37}\\x{10A3B}-\\x{10A3E}\\x{10A40}-\\x{10A48}\\x{10A49}-\\x{10A4F}\\x{10A50}-\\x{10A58}\\x{10A59}-\\x{10A5F}\\x{10A60}-\\x{10A7C}\\x{10A7D}-\\x{10A7E}\\x{10A7F}\\x{10A80}-\\x{10A9C}\\x{10A9D}-\\x{10A9F}\\x{10AA0}-\\x{10ABF}\\x{10AC0}-\\x{10AC7}\\x{10AC8}\\x{10AC9}-\\x{10AE4}\\x{10AE7}-\\x{10AEA}\\x{10AEB}-\\x{10AEF}\\x{10AF0}-\\x{10AF6}\\x{10AF7}-\\x{10AFF}\\x{10B00}-\\x{10B35}\\x{10B36}-\\x{10B38}\\x{10B40}-\\x{10B55}\\x{10B56}-\\x{10B57}\\x{10B58}-\\x{10B5F}\\x{10B60}-\\x{10B72}\\x{10B73}-\\x{10B77}\\x{10B78}-\\x{10B7F}\\x{10B80}-\\x{10B91}\\x{10B92}-\\x{10B98}\\x{10B99}-\\x{10B9C}\\x{10B9D}-\\x{10BA8}\\x{10BA9}-\\x{10BAF}\\x{10BB0}-\\x{10BFF}\\x{10C00}-\\x{10C48}\\x{10C49}-\\x{10C7F}\\x{10C80}-\\x{10CB2}\\x{10CB3}-\\x{10CBF}\\x{10CC0}-\\x{10CF2}\\x{10CF3}-\\x{10CF9}\\x{10CFA}-\\x{10CFF}\\x{10D00}-\\x{10D23}\\x{10D28}-\\x{10D2F}\\x{10D30}-\\x{10D39}\\x{10D3A}-\\x{10D3F}\\x{10D40}-\\x{10E5F}\\x{10E60}-\\x{10E7E}\\x{10E7F}\\x{10E80}-\\x{10EA9}\\x{10EAA}\\x{10EAD}\\x{10EAE}-\\x{10EAF}\\x{10EB0}-\\x{10EB1}\\x{10EB2}-\\x{10EFF}\\x{10F00}-\\x{10F1C}\\x{10F1D}-\\x{10F26}\\x{10F27}\\x{10F28}-\\x{10F2F}\\x{10F30}-\\x{10F45}\\x{10F51}-\\x{10F54}\\x{10F55}-\\x{10F59}\\x{10F5A}-\\x{10F6F}\\x{10F70}-\\x{10FAF}\\x{10FB0}-\\x{10FC4}\\x{10FC5}-\\x{10FCB}\\x{10FCC}-\\x{10FDF}\\x{10FE0}-\\x{10FF6}\\x{10FF7}-\\x{10FFF}\\x{1D7CE}-\\x{1D7FF}\\x{1E800}-\\x{1E8C4}\\x{1E8C5}-\\x{1E8C6}\\x{1E8C7}-\\x{1E8CF}\\x{1E8D7}-\\x{1E8FF}\\x{1E900}-\\x{1E943}\\x{1E94B}\\x{1E94C}-\\x{1E94F}\\x{1E950}-\\x{1E959}\\x{1E95A}-\\x{1E95D}\\x{1E95E}-\\x{1E95F}\\x{1E960}-\\x{1EC6F}\\x{1EC70}\\x{1EC71}-\\x{1ECAB}\\x{1ECAC}\\x{1ECAD}-\\x{1ECAF}\\x{1ECB0}\\x{1ECB1}-\\x{1ECB4}\\x{1ECB5}-\\x{1ECBF}\\x{1ECC0}-\\x{1ECFF}\\x{1ED00}\\x{1ED01}-\\x{1ED2D}\\x{1ED2E}\\x{1ED2F}-\\x{1ED3D}\\x{1ED3E}-\\x{1ED4F}\\x{1ED50}-\\x{1EDFF}\\x{1EE00}-\\x{1EE03}\\x{1EE04}\\x{1EE05}-\\x{1EE1F}\\x{1EE20}\\x{1EE21}-\\x{1EE22}\\x{1EE23}\\x{1EE24}\\x{1EE25}-\\x{1EE26}\\x{1EE27}\\x{1EE28}\\x{1EE29}-\\x{1EE32}\\x{1EE33}\\x{1EE34}-\\x{1EE37}\\x{1EE38}\\x{1EE39}\\x{1EE3A}\\x{1EE3B}\\x{1EE3C}-\\x{1EE41}\\x{1EE42}\\x{1EE43}-\\x{1EE46}\\x{1EE47}\\x{1EE48}\\x{1EE49}\\x{1EE4A}\\x{1EE4B}\\x{1EE4C}\\x{1EE4D}-\\x{1EE4F}\\x{1EE50}\\x{1EE51}-\\x{1EE52}\\x{1EE53}\\x{1EE54}\\x{1EE55}-\\x{1EE56}\\x{1EE57}\\x{1EE58}\\x{1EE59}\\x{1EE5A}\\x{1EE5B}\\x{1EE5C}\\x{1EE5D}\\x{1EE5E}\\x{1EE5F}\\x{1EE60}\\x{1EE61}-\\x{1EE62}\\x{1EE63}\\x{1EE64}\\x{1EE65}-\\x{1EE66}\\x{1EE67}-\\x{1EE6A}\\x{1EE6B}\\x{1EE6C}-\\x{1EE72}\\x{1EE73}\\x{1EE74}-\\x{1EE77}\\x{1EE78}\\x{1EE79}-\\x{1EE7C}\\x{1EE7D}\\x{1EE7E}\\x{1EE7F}\\x{1EE80}-\\x{1EE89}\\x{1EE8A}\\x{1EE8B}-\\x{1EE9B}\\x{1EE9C}-\\x{1EEA0}\\x{1EEA1}-\\x{1EEA3}\\x{1EEA4}\\x{1EEA5}-\\x{1EEA9}\\x{1EEAA}\\x{1EEAB}-\\x{1EEBB}\\x{1EEBC}-\\x{1EEEF}\\x{1EEF2}-\\x{1EEFF}\\x{1EF00}-\\x{1EFFF}\\x{1F100}-\\x{1F10A}\\x{1FBF0}-\\x{1FBF9}][\\x{0300}-\\x{036F}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{0591}-\\x{05BD}\\x{05BF}\\x{05C1}-\\x{05C2}\\x{05C4}-\\x{05C5}\\x{05C7}\\x{0610}-\\x{061A}\\x{064B}-\\x{065F}\\x{0670}\\x{06D6}-\\x{06DC}\\x{06DF}-\\x{06E4}\\x{06E7}-\\x{06E8}\\x{06EA}-\\x{06ED}\\x{0711}\\x{0730}-\\x{074A}\\x{07A6}-\\x{07B0}\\x{07EB}-\\x{07F3}\\x{07FD}\\x{0816}-\\x{0819}\\x{081B}-\\x{0823}\\x{0825}-\\x{0827}\\x{0829}-\\x{082D}\\x{0859}-\\x{085B}\\x{08D3}-\\x{08E1}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C81}\\x{0CBC}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{135D}-\\x{135F}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17DD}\\x{180B}-\\x{180D}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2CEF}-\\x{2CF1}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{302A}-\\x{302D}\\x{3099}-\\x{309A}\\x{A66F}\\x{A670}-\\x{A672}\\x{A674}-\\x{A67D}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A82C}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}-\\x{A9BD}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEC}-\\x{AAED}\\x{AAF6}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1E}\\x{FE00}-\\x{FE0F}\\x{FE20}-\\x{FE2F}\\x{101FD}\\x{102E0}\\x{10376}-\\x{1037A}\\x{10A01}-\\x{10A03}\\x{10A05}-\\x{10A06}\\x{10A0C}-\\x{10A0F}\\x{10A38}-\\x{10A3A}\\x{10A3F}\\x{10AE5}-\\x{10AE6}\\x{10D24}-\\x{10D27}\\x{10EAB}-\\x{10EAC}\\x{10F46}-\\x{10F50}\\x{11001}\\x{11038}-\\x{11046}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{111CF}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{1193B}-\\x{1193C}\\x{1193E}\\x{11943}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119E0}\\x{11A01}-\\x{11A06}\\x{11A09}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F8F}-\\x{16F92}\\x{16FE4}\\x{1BC9D}-\\x{1BC9E}\\x{1D167}-\\x{1D169}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D242}-\\x{1D244}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E8D0}-\\x{1E8D6}\\x{1E944}-\\x{1E94A}\\x{E0100}-\\x{E01EF}]*$/u'; + const BIDI_STEP_4_AN = '/[\\x{0600}-\\x{0605}\\x{0660}-\\x{0669}\\x{066B}-\\x{066C}\\x{06DD}\\x{08E2}\\x{10D30}-\\x{10D39}\\x{10E60}-\\x{10E7E}]/u'; + const BIDI_STEP_4_EN = '/[\\x{0030}-\\x{0039}\\x{00B2}-\\x{00B3}\\x{00B9}\\x{06F0}-\\x{06F9}\\x{2070}\\x{2074}-\\x{2079}\\x{2080}-\\x{2089}\\x{2488}-\\x{249B}\\x{FF10}-\\x{FF19}\\x{102E1}-\\x{102FB}\\x{1D7CE}-\\x{1D7FF}\\x{1F100}-\\x{1F10A}\\x{1FBF0}-\\x{1FBF9}]/u'; + const BIDI_STEP_5 = '/[\\x{0009}\\x{000A}\\x{000B}\\x{000C}\\x{000D}\\x{001C}-\\x{001E}\\x{001F}\\x{0020}\\x{0085}\\x{0590}\\x{05BE}\\x{05C0}\\x{05C3}\\x{05C6}\\x{05C8}-\\x{05CF}\\x{05D0}-\\x{05EA}\\x{05EB}-\\x{05EE}\\x{05EF}-\\x{05F2}\\x{05F3}-\\x{05F4}\\x{05F5}-\\x{05FF}\\x{0600}-\\x{0605}\\x{0608}\\x{060B}\\x{060D}\\x{061B}\\x{061C}\\x{061D}\\x{061E}-\\x{061F}\\x{0620}-\\x{063F}\\x{0640}\\x{0641}-\\x{064A}\\x{0660}-\\x{0669}\\x{066B}-\\x{066C}\\x{066D}\\x{066E}-\\x{066F}\\x{0671}-\\x{06D3}\\x{06D4}\\x{06D5}\\x{06DD}\\x{06E5}-\\x{06E6}\\x{06EE}-\\x{06EF}\\x{06FA}-\\x{06FC}\\x{06FD}-\\x{06FE}\\x{06FF}\\x{0700}-\\x{070D}\\x{070E}\\x{070F}\\x{0710}\\x{0712}-\\x{072F}\\x{074B}-\\x{074C}\\x{074D}-\\x{07A5}\\x{07B1}\\x{07B2}-\\x{07BF}\\x{07C0}-\\x{07C9}\\x{07CA}-\\x{07EA}\\x{07F4}-\\x{07F5}\\x{07FA}\\x{07FB}-\\x{07FC}\\x{07FE}-\\x{07FF}\\x{0800}-\\x{0815}\\x{081A}\\x{0824}\\x{0828}\\x{082E}-\\x{082F}\\x{0830}-\\x{083E}\\x{083F}\\x{0840}-\\x{0858}\\x{085C}-\\x{085D}\\x{085E}\\x{085F}\\x{0860}-\\x{086A}\\x{086B}-\\x{086F}\\x{0870}-\\x{089F}\\x{08A0}-\\x{08B4}\\x{08B5}\\x{08B6}-\\x{08C7}\\x{08C8}-\\x{08D2}\\x{08E2}\\x{1680}\\x{2000}-\\x{200A}\\x{200F}\\x{2028}\\x{2029}\\x{202A}\\x{202B}\\x{202C}\\x{202D}\\x{202E}\\x{205F}\\x{2066}\\x{2067}\\x{2068}\\x{2069}\\x{3000}\\x{FB1D}\\x{FB1F}-\\x{FB28}\\x{FB2A}-\\x{FB36}\\x{FB37}\\x{FB38}-\\x{FB3C}\\x{FB3D}\\x{FB3E}\\x{FB3F}\\x{FB40}-\\x{FB41}\\x{FB42}\\x{FB43}-\\x{FB44}\\x{FB45}\\x{FB46}-\\x{FB4F}\\x{FB50}-\\x{FBB1}\\x{FBB2}-\\x{FBC1}\\x{FBC2}-\\x{FBD2}\\x{FBD3}-\\x{FD3D}\\x{FD40}-\\x{FD4F}\\x{FD50}-\\x{FD8F}\\x{FD90}-\\x{FD91}\\x{FD92}-\\x{FDC7}\\x{FDC8}-\\x{FDCF}\\x{FDF0}-\\x{FDFB}\\x{FDFC}\\x{FDFE}-\\x{FDFF}\\x{FE70}-\\x{FE74}\\x{FE75}\\x{FE76}-\\x{FEFC}\\x{FEFD}-\\x{FEFE}\\x{10800}-\\x{10805}\\x{10806}-\\x{10807}\\x{10808}\\x{10809}\\x{1080A}-\\x{10835}\\x{10836}\\x{10837}-\\x{10838}\\x{10839}-\\x{1083B}\\x{1083C}\\x{1083D}-\\x{1083E}\\x{1083F}-\\x{10855}\\x{10856}\\x{10857}\\x{10858}-\\x{1085F}\\x{10860}-\\x{10876}\\x{10877}-\\x{10878}\\x{10879}-\\x{1087F}\\x{10880}-\\x{1089E}\\x{1089F}-\\x{108A6}\\x{108A7}-\\x{108AF}\\x{108B0}-\\x{108DF}\\x{108E0}-\\x{108F2}\\x{108F3}\\x{108F4}-\\x{108F5}\\x{108F6}-\\x{108FA}\\x{108FB}-\\x{108FF}\\x{10900}-\\x{10915}\\x{10916}-\\x{1091B}\\x{1091C}-\\x{1091E}\\x{10920}-\\x{10939}\\x{1093A}-\\x{1093E}\\x{1093F}\\x{10940}-\\x{1097F}\\x{10980}-\\x{109B7}\\x{109B8}-\\x{109BB}\\x{109BC}-\\x{109BD}\\x{109BE}-\\x{109BF}\\x{109C0}-\\x{109CF}\\x{109D0}-\\x{109D1}\\x{109D2}-\\x{109FF}\\x{10A00}\\x{10A04}\\x{10A07}-\\x{10A0B}\\x{10A10}-\\x{10A13}\\x{10A14}\\x{10A15}-\\x{10A17}\\x{10A18}\\x{10A19}-\\x{10A35}\\x{10A36}-\\x{10A37}\\x{10A3B}-\\x{10A3E}\\x{10A40}-\\x{10A48}\\x{10A49}-\\x{10A4F}\\x{10A50}-\\x{10A58}\\x{10A59}-\\x{10A5F}\\x{10A60}-\\x{10A7C}\\x{10A7D}-\\x{10A7E}\\x{10A7F}\\x{10A80}-\\x{10A9C}\\x{10A9D}-\\x{10A9F}\\x{10AA0}-\\x{10ABF}\\x{10AC0}-\\x{10AC7}\\x{10AC8}\\x{10AC9}-\\x{10AE4}\\x{10AE7}-\\x{10AEA}\\x{10AEB}-\\x{10AEF}\\x{10AF0}-\\x{10AF6}\\x{10AF7}-\\x{10AFF}\\x{10B00}-\\x{10B35}\\x{10B36}-\\x{10B38}\\x{10B40}-\\x{10B55}\\x{10B56}-\\x{10B57}\\x{10B58}-\\x{10B5F}\\x{10B60}-\\x{10B72}\\x{10B73}-\\x{10B77}\\x{10B78}-\\x{10B7F}\\x{10B80}-\\x{10B91}\\x{10B92}-\\x{10B98}\\x{10B99}-\\x{10B9C}\\x{10B9D}-\\x{10BA8}\\x{10BA9}-\\x{10BAF}\\x{10BB0}-\\x{10BFF}\\x{10C00}-\\x{10C48}\\x{10C49}-\\x{10C7F}\\x{10C80}-\\x{10CB2}\\x{10CB3}-\\x{10CBF}\\x{10CC0}-\\x{10CF2}\\x{10CF3}-\\x{10CF9}\\x{10CFA}-\\x{10CFF}\\x{10D00}-\\x{10D23}\\x{10D28}-\\x{10D2F}\\x{10D30}-\\x{10D39}\\x{10D3A}-\\x{10D3F}\\x{10D40}-\\x{10E5F}\\x{10E60}-\\x{10E7E}\\x{10E7F}\\x{10E80}-\\x{10EA9}\\x{10EAA}\\x{10EAD}\\x{10EAE}-\\x{10EAF}\\x{10EB0}-\\x{10EB1}\\x{10EB2}-\\x{10EFF}\\x{10F00}-\\x{10F1C}\\x{10F1D}-\\x{10F26}\\x{10F27}\\x{10F28}-\\x{10F2F}\\x{10F30}-\\x{10F45}\\x{10F51}-\\x{10F54}\\x{10F55}-\\x{10F59}\\x{10F5A}-\\x{10F6F}\\x{10F70}-\\x{10FAF}\\x{10FB0}-\\x{10FC4}\\x{10FC5}-\\x{10FCB}\\x{10FCC}-\\x{10FDF}\\x{10FE0}-\\x{10FF6}\\x{10FF7}-\\x{10FFF}\\x{1E800}-\\x{1E8C4}\\x{1E8C5}-\\x{1E8C6}\\x{1E8C7}-\\x{1E8CF}\\x{1E8D7}-\\x{1E8FF}\\x{1E900}-\\x{1E943}\\x{1E94B}\\x{1E94C}-\\x{1E94F}\\x{1E950}-\\x{1E959}\\x{1E95A}-\\x{1E95D}\\x{1E95E}-\\x{1E95F}\\x{1E960}-\\x{1EC6F}\\x{1EC70}\\x{1EC71}-\\x{1ECAB}\\x{1ECAC}\\x{1ECAD}-\\x{1ECAF}\\x{1ECB0}\\x{1ECB1}-\\x{1ECB4}\\x{1ECB5}-\\x{1ECBF}\\x{1ECC0}-\\x{1ECFF}\\x{1ED00}\\x{1ED01}-\\x{1ED2D}\\x{1ED2E}\\x{1ED2F}-\\x{1ED3D}\\x{1ED3E}-\\x{1ED4F}\\x{1ED50}-\\x{1EDFF}\\x{1EE00}-\\x{1EE03}\\x{1EE04}\\x{1EE05}-\\x{1EE1F}\\x{1EE20}\\x{1EE21}-\\x{1EE22}\\x{1EE23}\\x{1EE24}\\x{1EE25}-\\x{1EE26}\\x{1EE27}\\x{1EE28}\\x{1EE29}-\\x{1EE32}\\x{1EE33}\\x{1EE34}-\\x{1EE37}\\x{1EE38}\\x{1EE39}\\x{1EE3A}\\x{1EE3B}\\x{1EE3C}-\\x{1EE41}\\x{1EE42}\\x{1EE43}-\\x{1EE46}\\x{1EE47}\\x{1EE48}\\x{1EE49}\\x{1EE4A}\\x{1EE4B}\\x{1EE4C}\\x{1EE4D}-\\x{1EE4F}\\x{1EE50}\\x{1EE51}-\\x{1EE52}\\x{1EE53}\\x{1EE54}\\x{1EE55}-\\x{1EE56}\\x{1EE57}\\x{1EE58}\\x{1EE59}\\x{1EE5A}\\x{1EE5B}\\x{1EE5C}\\x{1EE5D}\\x{1EE5E}\\x{1EE5F}\\x{1EE60}\\x{1EE61}-\\x{1EE62}\\x{1EE63}\\x{1EE64}\\x{1EE65}-\\x{1EE66}\\x{1EE67}-\\x{1EE6A}\\x{1EE6B}\\x{1EE6C}-\\x{1EE72}\\x{1EE73}\\x{1EE74}-\\x{1EE77}\\x{1EE78}\\x{1EE79}-\\x{1EE7C}\\x{1EE7D}\\x{1EE7E}\\x{1EE7F}\\x{1EE80}-\\x{1EE89}\\x{1EE8A}\\x{1EE8B}-\\x{1EE9B}\\x{1EE9C}-\\x{1EEA0}\\x{1EEA1}-\\x{1EEA3}\\x{1EEA4}\\x{1EEA5}-\\x{1EEA9}\\x{1EEAA}\\x{1EEAB}-\\x{1EEBB}\\x{1EEBC}-\\x{1EEEF}\\x{1EEF2}-\\x{1EEFF}\\x{1EF00}-\\x{1EFFF}]/u'; + const BIDI_STEP_6 = '/[^\\x{0000}-\\x{0008}\\x{0009}\\x{000A}\\x{000B}\\x{000C}\\x{000D}\\x{000E}-\\x{001B}\\x{001C}-\\x{001E}\\x{001F}\\x{0020}\\x{0021}-\\x{0022}\\x{0023}\\x{0024}\\x{0025}\\x{0026}-\\x{0027}\\x{0028}\\x{0029}\\x{002A}\\x{002B}\\x{002C}\\x{002D}\\x{002E}-\\x{002F}\\x{003A}\\x{003B}\\x{003C}-\\x{003E}\\x{003F}-\\x{0040}\\x{005B}\\x{005C}\\x{005D}\\x{005E}\\x{005F}\\x{0060}\\x{007B}\\x{007C}\\x{007D}\\x{007E}\\x{007F}-\\x{0084}\\x{0085}\\x{0086}-\\x{009F}\\x{00A0}\\x{00A1}\\x{00A2}-\\x{00A5}\\x{00A6}\\x{00A7}\\x{00A8}\\x{00A9}\\x{00AB}\\x{00AC}\\x{00AD}\\x{00AE}\\x{00AF}\\x{00B0}\\x{00B1}\\x{00B4}\\x{00B6}-\\x{00B7}\\x{00B8}\\x{00BB}\\x{00BC}-\\x{00BE}\\x{00BF}\\x{00D7}\\x{00F7}\\x{02B9}-\\x{02BA}\\x{02C2}-\\x{02C5}\\x{02C6}-\\x{02CF}\\x{02D2}-\\x{02DF}\\x{02E5}-\\x{02EB}\\x{02EC}\\x{02ED}\\x{02EF}-\\x{02FF}\\x{0300}-\\x{036F}\\x{0374}\\x{0375}\\x{037E}\\x{0384}-\\x{0385}\\x{0387}\\x{03F6}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{058A}\\x{058D}-\\x{058E}\\x{058F}\\x{0590}\\x{0591}-\\x{05BD}\\x{05BE}\\x{05BF}\\x{05C0}\\x{05C1}-\\x{05C2}\\x{05C3}\\x{05C4}-\\x{05C5}\\x{05C6}\\x{05C7}\\x{05C8}-\\x{05CF}\\x{05D0}-\\x{05EA}\\x{05EB}-\\x{05EE}\\x{05EF}-\\x{05F2}\\x{05F3}-\\x{05F4}\\x{05F5}-\\x{05FF}\\x{0600}-\\x{0605}\\x{0606}-\\x{0607}\\x{0608}\\x{0609}-\\x{060A}\\x{060B}\\x{060C}\\x{060D}\\x{060E}-\\x{060F}\\x{0610}-\\x{061A}\\x{061B}\\x{061C}\\x{061D}\\x{061E}-\\x{061F}\\x{0620}-\\x{063F}\\x{0640}\\x{0641}-\\x{064A}\\x{064B}-\\x{065F}\\x{0660}-\\x{0669}\\x{066A}\\x{066B}-\\x{066C}\\x{066D}\\x{066E}-\\x{066F}\\x{0670}\\x{0671}-\\x{06D3}\\x{06D4}\\x{06D5}\\x{06D6}-\\x{06DC}\\x{06DD}\\x{06DE}\\x{06DF}-\\x{06E4}\\x{06E5}-\\x{06E6}\\x{06E7}-\\x{06E8}\\x{06E9}\\x{06EA}-\\x{06ED}\\x{06EE}-\\x{06EF}\\x{06FA}-\\x{06FC}\\x{06FD}-\\x{06FE}\\x{06FF}\\x{0700}-\\x{070D}\\x{070E}\\x{070F}\\x{0710}\\x{0711}\\x{0712}-\\x{072F}\\x{0730}-\\x{074A}\\x{074B}-\\x{074C}\\x{074D}-\\x{07A5}\\x{07A6}-\\x{07B0}\\x{07B1}\\x{07B2}-\\x{07BF}\\x{07C0}-\\x{07C9}\\x{07CA}-\\x{07EA}\\x{07EB}-\\x{07F3}\\x{07F4}-\\x{07F5}\\x{07F6}\\x{07F7}-\\x{07F9}\\x{07FA}\\x{07FB}-\\x{07FC}\\x{07FD}\\x{07FE}-\\x{07FF}\\x{0800}-\\x{0815}\\x{0816}-\\x{0819}\\x{081A}\\x{081B}-\\x{0823}\\x{0824}\\x{0825}-\\x{0827}\\x{0828}\\x{0829}-\\x{082D}\\x{082E}-\\x{082F}\\x{0830}-\\x{083E}\\x{083F}\\x{0840}-\\x{0858}\\x{0859}-\\x{085B}\\x{085C}-\\x{085D}\\x{085E}\\x{085F}\\x{0860}-\\x{086A}\\x{086B}-\\x{086F}\\x{0870}-\\x{089F}\\x{08A0}-\\x{08B4}\\x{08B5}\\x{08B6}-\\x{08C7}\\x{08C8}-\\x{08D2}\\x{08D3}-\\x{08E1}\\x{08E2}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09F2}-\\x{09F3}\\x{09FB}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AF1}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0BF3}-\\x{0BF8}\\x{0BF9}\\x{0BFA}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C78}-\\x{0C7E}\\x{0C81}\\x{0CBC}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E3F}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F3A}\\x{0F3B}\\x{0F3C}\\x{0F3D}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{135D}-\\x{135F}\\x{1390}-\\x{1399}\\x{1400}\\x{1680}\\x{169B}\\x{169C}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17DB}\\x{17DD}\\x{17F0}-\\x{17F9}\\x{1800}-\\x{1805}\\x{1806}\\x{1807}-\\x{180A}\\x{180B}-\\x{180D}\\x{180E}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1940}\\x{1944}-\\x{1945}\\x{19DE}-\\x{19FF}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{1FBD}\\x{1FBF}-\\x{1FC1}\\x{1FCD}-\\x{1FCF}\\x{1FDD}-\\x{1FDF}\\x{1FED}-\\x{1FEF}\\x{1FFD}-\\x{1FFE}\\x{2000}-\\x{200A}\\x{200B}-\\x{200D}\\x{200F}\\x{2010}-\\x{2015}\\x{2016}-\\x{2017}\\x{2018}\\x{2019}\\x{201A}\\x{201B}-\\x{201C}\\x{201D}\\x{201E}\\x{201F}\\x{2020}-\\x{2027}\\x{2028}\\x{2029}\\x{202A}\\x{202B}\\x{202C}\\x{202D}\\x{202E}\\x{202F}\\x{2030}-\\x{2034}\\x{2035}-\\x{2038}\\x{2039}\\x{203A}\\x{203B}-\\x{203E}\\x{203F}-\\x{2040}\\x{2041}-\\x{2043}\\x{2044}\\x{2045}\\x{2046}\\x{2047}-\\x{2051}\\x{2052}\\x{2053}\\x{2054}\\x{2055}-\\x{205E}\\x{205F}\\x{2060}-\\x{2064}\\x{2065}\\x{2066}\\x{2067}\\x{2068}\\x{2069}\\x{206A}-\\x{206F}\\x{207A}-\\x{207B}\\x{207C}\\x{207D}\\x{207E}\\x{208A}-\\x{208B}\\x{208C}\\x{208D}\\x{208E}\\x{20A0}-\\x{20BF}\\x{20C0}-\\x{20CF}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2100}-\\x{2101}\\x{2103}-\\x{2106}\\x{2108}-\\x{2109}\\x{2114}\\x{2116}-\\x{2117}\\x{2118}\\x{211E}-\\x{2123}\\x{2125}\\x{2127}\\x{2129}\\x{212E}\\x{213A}-\\x{213B}\\x{2140}-\\x{2144}\\x{214A}\\x{214B}\\x{214C}-\\x{214D}\\x{2150}-\\x{215F}\\x{2189}\\x{218A}-\\x{218B}\\x{2190}-\\x{2194}\\x{2195}-\\x{2199}\\x{219A}-\\x{219B}\\x{219C}-\\x{219F}\\x{21A0}\\x{21A1}-\\x{21A2}\\x{21A3}\\x{21A4}-\\x{21A5}\\x{21A6}\\x{21A7}-\\x{21AD}\\x{21AE}\\x{21AF}-\\x{21CD}\\x{21CE}-\\x{21CF}\\x{21D0}-\\x{21D1}\\x{21D2}\\x{21D3}\\x{21D4}\\x{21D5}-\\x{21F3}\\x{21F4}-\\x{2211}\\x{2212}\\x{2213}\\x{2214}-\\x{22FF}\\x{2300}-\\x{2307}\\x{2308}\\x{2309}\\x{230A}\\x{230B}\\x{230C}-\\x{231F}\\x{2320}-\\x{2321}\\x{2322}-\\x{2328}\\x{2329}\\x{232A}\\x{232B}-\\x{2335}\\x{237B}\\x{237C}\\x{237D}-\\x{2394}\\x{2396}-\\x{239A}\\x{239B}-\\x{23B3}\\x{23B4}-\\x{23DB}\\x{23DC}-\\x{23E1}\\x{23E2}-\\x{2426}\\x{2440}-\\x{244A}\\x{2460}-\\x{2487}\\x{24EA}-\\x{24FF}\\x{2500}-\\x{25B6}\\x{25B7}\\x{25B8}-\\x{25C0}\\x{25C1}\\x{25C2}-\\x{25F7}\\x{25F8}-\\x{25FF}\\x{2600}-\\x{266E}\\x{266F}\\x{2670}-\\x{26AB}\\x{26AD}-\\x{2767}\\x{2768}\\x{2769}\\x{276A}\\x{276B}\\x{276C}\\x{276D}\\x{276E}\\x{276F}\\x{2770}\\x{2771}\\x{2772}\\x{2773}\\x{2774}\\x{2775}\\x{2776}-\\x{2793}\\x{2794}-\\x{27BF}\\x{27C0}-\\x{27C4}\\x{27C5}\\x{27C6}\\x{27C7}-\\x{27E5}\\x{27E6}\\x{27E7}\\x{27E8}\\x{27E9}\\x{27EA}\\x{27EB}\\x{27EC}\\x{27ED}\\x{27EE}\\x{27EF}\\x{27F0}-\\x{27FF}\\x{2900}-\\x{2982}\\x{2983}\\x{2984}\\x{2985}\\x{2986}\\x{2987}\\x{2988}\\x{2989}\\x{298A}\\x{298B}\\x{298C}\\x{298D}\\x{298E}\\x{298F}\\x{2990}\\x{2991}\\x{2992}\\x{2993}\\x{2994}\\x{2995}\\x{2996}\\x{2997}\\x{2998}\\x{2999}-\\x{29D7}\\x{29D8}\\x{29D9}\\x{29DA}\\x{29DB}\\x{29DC}-\\x{29FB}\\x{29FC}\\x{29FD}\\x{29FE}-\\x{2AFF}\\x{2B00}-\\x{2B2F}\\x{2B30}-\\x{2B44}\\x{2B45}-\\x{2B46}\\x{2B47}-\\x{2B4C}\\x{2B4D}-\\x{2B73}\\x{2B76}-\\x{2B95}\\x{2B97}-\\x{2BFF}\\x{2CE5}-\\x{2CEA}\\x{2CEF}-\\x{2CF1}\\x{2CF9}-\\x{2CFC}\\x{2CFD}\\x{2CFE}-\\x{2CFF}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{2E00}-\\x{2E01}\\x{2E02}\\x{2E03}\\x{2E04}\\x{2E05}\\x{2E06}-\\x{2E08}\\x{2E09}\\x{2E0A}\\x{2E0B}\\x{2E0C}\\x{2E0D}\\x{2E0E}-\\x{2E16}\\x{2E17}\\x{2E18}-\\x{2E19}\\x{2E1A}\\x{2E1B}\\x{2E1C}\\x{2E1D}\\x{2E1E}-\\x{2E1F}\\x{2E20}\\x{2E21}\\x{2E22}\\x{2E23}\\x{2E24}\\x{2E25}\\x{2E26}\\x{2E27}\\x{2E28}\\x{2E29}\\x{2E2A}-\\x{2E2E}\\x{2E2F}\\x{2E30}-\\x{2E39}\\x{2E3A}-\\x{2E3B}\\x{2E3C}-\\x{2E3F}\\x{2E40}\\x{2E41}\\x{2E42}\\x{2E43}-\\x{2E4F}\\x{2E50}-\\x{2E51}\\x{2E52}\\x{2E80}-\\x{2E99}\\x{2E9B}-\\x{2EF3}\\x{2F00}-\\x{2FD5}\\x{2FF0}-\\x{2FFB}\\x{3000}\\x{3001}-\\x{3003}\\x{3004}\\x{3008}\\x{3009}\\x{300A}\\x{300B}\\x{300C}\\x{300D}\\x{300E}\\x{300F}\\x{3010}\\x{3011}\\x{3012}-\\x{3013}\\x{3014}\\x{3015}\\x{3016}\\x{3017}\\x{3018}\\x{3019}\\x{301A}\\x{301B}\\x{301C}\\x{301D}\\x{301E}-\\x{301F}\\x{3020}\\x{302A}-\\x{302D}\\x{3030}\\x{3036}-\\x{3037}\\x{303D}\\x{303E}-\\x{303F}\\x{3099}-\\x{309A}\\x{309B}-\\x{309C}\\x{30A0}\\x{30FB}\\x{31C0}-\\x{31E3}\\x{321D}-\\x{321E}\\x{3250}\\x{3251}-\\x{325F}\\x{327C}-\\x{327E}\\x{32B1}-\\x{32BF}\\x{32CC}-\\x{32CF}\\x{3377}-\\x{337A}\\x{33DE}-\\x{33DF}\\x{33FF}\\x{4DC0}-\\x{4DFF}\\x{A490}-\\x{A4C6}\\x{A60D}-\\x{A60F}\\x{A66F}\\x{A670}-\\x{A672}\\x{A673}\\x{A674}-\\x{A67D}\\x{A67E}\\x{A67F}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A700}-\\x{A716}\\x{A717}-\\x{A71F}\\x{A720}-\\x{A721}\\x{A788}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A828}-\\x{A82B}\\x{A82C}\\x{A838}\\x{A839}\\x{A874}-\\x{A877}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}-\\x{A9BD}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEC}-\\x{AAED}\\x{AAF6}\\x{AB6A}-\\x{AB6B}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1D}\\x{FB1E}\\x{FB1F}-\\x{FB28}\\x{FB29}\\x{FB2A}-\\x{FB36}\\x{FB37}\\x{FB38}-\\x{FB3C}\\x{FB3D}\\x{FB3E}\\x{FB3F}\\x{FB40}-\\x{FB41}\\x{FB42}\\x{FB43}-\\x{FB44}\\x{FB45}\\x{FB46}-\\x{FB4F}\\x{FB50}-\\x{FBB1}\\x{FBB2}-\\x{FBC1}\\x{FBC2}-\\x{FBD2}\\x{FBD3}-\\x{FD3D}\\x{FD3E}\\x{FD3F}\\x{FD40}-\\x{FD4F}\\x{FD50}-\\x{FD8F}\\x{FD90}-\\x{FD91}\\x{FD92}-\\x{FDC7}\\x{FDC8}-\\x{FDCF}\\x{FDD0}-\\x{FDEF}\\x{FDF0}-\\x{FDFB}\\x{FDFC}\\x{FDFD}\\x{FDFE}-\\x{FDFF}\\x{FE00}-\\x{FE0F}\\x{FE10}-\\x{FE16}\\x{FE17}\\x{FE18}\\x{FE19}\\x{FE20}-\\x{FE2F}\\x{FE30}\\x{FE31}-\\x{FE32}\\x{FE33}-\\x{FE34}\\x{FE35}\\x{FE36}\\x{FE37}\\x{FE38}\\x{FE39}\\x{FE3A}\\x{FE3B}\\x{FE3C}\\x{FE3D}\\x{FE3E}\\x{FE3F}\\x{FE40}\\x{FE41}\\x{FE42}\\x{FE43}\\x{FE44}\\x{FE45}-\\x{FE46}\\x{FE47}\\x{FE48}\\x{FE49}-\\x{FE4C}\\x{FE4D}-\\x{FE4F}\\x{FE50}\\x{FE51}\\x{FE52}\\x{FE54}\\x{FE55}\\x{FE56}-\\x{FE57}\\x{FE58}\\x{FE59}\\x{FE5A}\\x{FE5B}\\x{FE5C}\\x{FE5D}\\x{FE5E}\\x{FE5F}\\x{FE60}-\\x{FE61}\\x{FE62}\\x{FE63}\\x{FE64}-\\x{FE66}\\x{FE68}\\x{FE69}\\x{FE6A}\\x{FE6B}\\x{FE70}-\\x{FE74}\\x{FE75}\\x{FE76}-\\x{FEFC}\\x{FEFD}-\\x{FEFE}\\x{FEFF}\\x{FF01}-\\x{FF02}\\x{FF03}\\x{FF04}\\x{FF05}\\x{FF06}-\\x{FF07}\\x{FF08}\\x{FF09}\\x{FF0A}\\x{FF0B}\\x{FF0C}\\x{FF0D}\\x{FF0E}-\\x{FF0F}\\x{FF1A}\\x{FF1B}\\x{FF1C}-\\x{FF1E}\\x{FF1F}-\\x{FF20}\\x{FF3B}\\x{FF3C}\\x{FF3D}\\x{FF3E}\\x{FF3F}\\x{FF40}\\x{FF5B}\\x{FF5C}\\x{FF5D}\\x{FF5E}\\x{FF5F}\\x{FF60}\\x{FF61}\\x{FF62}\\x{FF63}\\x{FF64}-\\x{FF65}\\x{FFE0}-\\x{FFE1}\\x{FFE2}\\x{FFE3}\\x{FFE4}\\x{FFE5}-\\x{FFE6}\\x{FFE8}\\x{FFE9}-\\x{FFEC}\\x{FFED}-\\x{FFEE}\\x{FFF0}-\\x{FFF8}\\x{FFF9}-\\x{FFFB}\\x{FFFC}-\\x{FFFD}\\x{FFFE}-\\x{FFFF}\\x{10101}\\x{10140}-\\x{10174}\\x{10175}-\\x{10178}\\x{10179}-\\x{10189}\\x{1018A}-\\x{1018B}\\x{1018C}\\x{10190}-\\x{1019C}\\x{101A0}\\x{101FD}\\x{102E0}\\x{10376}-\\x{1037A}\\x{10800}-\\x{10805}\\x{10806}-\\x{10807}\\x{10808}\\x{10809}\\x{1080A}-\\x{10835}\\x{10836}\\x{10837}-\\x{10838}\\x{10839}-\\x{1083B}\\x{1083C}\\x{1083D}-\\x{1083E}\\x{1083F}-\\x{10855}\\x{10856}\\x{10857}\\x{10858}-\\x{1085F}\\x{10860}-\\x{10876}\\x{10877}-\\x{10878}\\x{10879}-\\x{1087F}\\x{10880}-\\x{1089E}\\x{1089F}-\\x{108A6}\\x{108A7}-\\x{108AF}\\x{108B0}-\\x{108DF}\\x{108E0}-\\x{108F2}\\x{108F3}\\x{108F4}-\\x{108F5}\\x{108F6}-\\x{108FA}\\x{108FB}-\\x{108FF}\\x{10900}-\\x{10915}\\x{10916}-\\x{1091B}\\x{1091C}-\\x{1091E}\\x{1091F}\\x{10920}-\\x{10939}\\x{1093A}-\\x{1093E}\\x{1093F}\\x{10940}-\\x{1097F}\\x{10980}-\\x{109B7}\\x{109B8}-\\x{109BB}\\x{109BC}-\\x{109BD}\\x{109BE}-\\x{109BF}\\x{109C0}-\\x{109CF}\\x{109D0}-\\x{109D1}\\x{109D2}-\\x{109FF}\\x{10A00}\\x{10A01}-\\x{10A03}\\x{10A04}\\x{10A05}-\\x{10A06}\\x{10A07}-\\x{10A0B}\\x{10A0C}-\\x{10A0F}\\x{10A10}-\\x{10A13}\\x{10A14}\\x{10A15}-\\x{10A17}\\x{10A18}\\x{10A19}-\\x{10A35}\\x{10A36}-\\x{10A37}\\x{10A38}-\\x{10A3A}\\x{10A3B}-\\x{10A3E}\\x{10A3F}\\x{10A40}-\\x{10A48}\\x{10A49}-\\x{10A4F}\\x{10A50}-\\x{10A58}\\x{10A59}-\\x{10A5F}\\x{10A60}-\\x{10A7C}\\x{10A7D}-\\x{10A7E}\\x{10A7F}\\x{10A80}-\\x{10A9C}\\x{10A9D}-\\x{10A9F}\\x{10AA0}-\\x{10ABF}\\x{10AC0}-\\x{10AC7}\\x{10AC8}\\x{10AC9}-\\x{10AE4}\\x{10AE5}-\\x{10AE6}\\x{10AE7}-\\x{10AEA}\\x{10AEB}-\\x{10AEF}\\x{10AF0}-\\x{10AF6}\\x{10AF7}-\\x{10AFF}\\x{10B00}-\\x{10B35}\\x{10B36}-\\x{10B38}\\x{10B39}-\\x{10B3F}\\x{10B40}-\\x{10B55}\\x{10B56}-\\x{10B57}\\x{10B58}-\\x{10B5F}\\x{10B60}-\\x{10B72}\\x{10B73}-\\x{10B77}\\x{10B78}-\\x{10B7F}\\x{10B80}-\\x{10B91}\\x{10B92}-\\x{10B98}\\x{10B99}-\\x{10B9C}\\x{10B9D}-\\x{10BA8}\\x{10BA9}-\\x{10BAF}\\x{10BB0}-\\x{10BFF}\\x{10C00}-\\x{10C48}\\x{10C49}-\\x{10C7F}\\x{10C80}-\\x{10CB2}\\x{10CB3}-\\x{10CBF}\\x{10CC0}-\\x{10CF2}\\x{10CF3}-\\x{10CF9}\\x{10CFA}-\\x{10CFF}\\x{10D00}-\\x{10D23}\\x{10D24}-\\x{10D27}\\x{10D28}-\\x{10D2F}\\x{10D30}-\\x{10D39}\\x{10D3A}-\\x{10D3F}\\x{10D40}-\\x{10E5F}\\x{10E60}-\\x{10E7E}\\x{10E7F}\\x{10E80}-\\x{10EA9}\\x{10EAA}\\x{10EAB}-\\x{10EAC}\\x{10EAD}\\x{10EAE}-\\x{10EAF}\\x{10EB0}-\\x{10EB1}\\x{10EB2}-\\x{10EFF}\\x{10F00}-\\x{10F1C}\\x{10F1D}-\\x{10F26}\\x{10F27}\\x{10F28}-\\x{10F2F}\\x{10F30}-\\x{10F45}\\x{10F46}-\\x{10F50}\\x{10F51}-\\x{10F54}\\x{10F55}-\\x{10F59}\\x{10F5A}-\\x{10F6F}\\x{10F70}-\\x{10FAF}\\x{10FB0}-\\x{10FC4}\\x{10FC5}-\\x{10FCB}\\x{10FCC}-\\x{10FDF}\\x{10FE0}-\\x{10FF6}\\x{10FF7}-\\x{10FFF}\\x{11001}\\x{11038}-\\x{11046}\\x{11052}-\\x{11065}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{111CF}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{11660}-\\x{1166C}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{1193B}-\\x{1193C}\\x{1193E}\\x{11943}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119E0}\\x{11A01}-\\x{11A06}\\x{11A09}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{11FD5}-\\x{11FDC}\\x{11FDD}-\\x{11FE0}\\x{11FE1}-\\x{11FF1}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F8F}-\\x{16F92}\\x{16FE2}\\x{16FE4}\\x{1BC9D}-\\x{1BC9E}\\x{1BCA0}-\\x{1BCA3}\\x{1D167}-\\x{1D169}\\x{1D173}-\\x{1D17A}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D200}-\\x{1D241}\\x{1D242}-\\x{1D244}\\x{1D245}\\x{1D300}-\\x{1D356}\\x{1D6DB}\\x{1D715}\\x{1D74F}\\x{1D789}\\x{1D7C3}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E2FF}\\x{1E800}-\\x{1E8C4}\\x{1E8C5}-\\x{1E8C6}\\x{1E8C7}-\\x{1E8CF}\\x{1E8D0}-\\x{1E8D6}\\x{1E8D7}-\\x{1E8FF}\\x{1E900}-\\x{1E943}\\x{1E944}-\\x{1E94A}\\x{1E94B}\\x{1E94C}-\\x{1E94F}\\x{1E950}-\\x{1E959}\\x{1E95A}-\\x{1E95D}\\x{1E95E}-\\x{1E95F}\\x{1E960}-\\x{1EC6F}\\x{1EC70}\\x{1EC71}-\\x{1ECAB}\\x{1ECAC}\\x{1ECAD}-\\x{1ECAF}\\x{1ECB0}\\x{1ECB1}-\\x{1ECB4}\\x{1ECB5}-\\x{1ECBF}\\x{1ECC0}-\\x{1ECFF}\\x{1ED00}\\x{1ED01}-\\x{1ED2D}\\x{1ED2E}\\x{1ED2F}-\\x{1ED3D}\\x{1ED3E}-\\x{1ED4F}\\x{1ED50}-\\x{1EDFF}\\x{1EE00}-\\x{1EE03}\\x{1EE04}\\x{1EE05}-\\x{1EE1F}\\x{1EE20}\\x{1EE21}-\\x{1EE22}\\x{1EE23}\\x{1EE24}\\x{1EE25}-\\x{1EE26}\\x{1EE27}\\x{1EE28}\\x{1EE29}-\\x{1EE32}\\x{1EE33}\\x{1EE34}-\\x{1EE37}\\x{1EE38}\\x{1EE39}\\x{1EE3A}\\x{1EE3B}\\x{1EE3C}-\\x{1EE41}\\x{1EE42}\\x{1EE43}-\\x{1EE46}\\x{1EE47}\\x{1EE48}\\x{1EE49}\\x{1EE4A}\\x{1EE4B}\\x{1EE4C}\\x{1EE4D}-\\x{1EE4F}\\x{1EE50}\\x{1EE51}-\\x{1EE52}\\x{1EE53}\\x{1EE54}\\x{1EE55}-\\x{1EE56}\\x{1EE57}\\x{1EE58}\\x{1EE59}\\x{1EE5A}\\x{1EE5B}\\x{1EE5C}\\x{1EE5D}\\x{1EE5E}\\x{1EE5F}\\x{1EE60}\\x{1EE61}-\\x{1EE62}\\x{1EE63}\\x{1EE64}\\x{1EE65}-\\x{1EE66}\\x{1EE67}-\\x{1EE6A}\\x{1EE6B}\\x{1EE6C}-\\x{1EE72}\\x{1EE73}\\x{1EE74}-\\x{1EE77}\\x{1EE78}\\x{1EE79}-\\x{1EE7C}\\x{1EE7D}\\x{1EE7E}\\x{1EE7F}\\x{1EE80}-\\x{1EE89}\\x{1EE8A}\\x{1EE8B}-\\x{1EE9B}\\x{1EE9C}-\\x{1EEA0}\\x{1EEA1}-\\x{1EEA3}\\x{1EEA4}\\x{1EEA5}-\\x{1EEA9}\\x{1EEAA}\\x{1EEAB}-\\x{1EEBB}\\x{1EEBC}-\\x{1EEEF}\\x{1EEF0}-\\x{1EEF1}\\x{1EEF2}-\\x{1EEFF}\\x{1EF00}-\\x{1EFFF}\\x{1F000}-\\x{1F02B}\\x{1F030}-\\x{1F093}\\x{1F0A0}-\\x{1F0AE}\\x{1F0B1}-\\x{1F0BF}\\x{1F0C1}-\\x{1F0CF}\\x{1F0D1}-\\x{1F0F5}\\x{1F10B}-\\x{1F10C}\\x{1F10D}-\\x{1F10F}\\x{1F12F}\\x{1F16A}-\\x{1F16F}\\x{1F1AD}\\x{1F260}-\\x{1F265}\\x{1F300}-\\x{1F3FA}\\x{1F3FB}-\\x{1F3FF}\\x{1F400}-\\x{1F6D7}\\x{1F6E0}-\\x{1F6EC}\\x{1F6F0}-\\x{1F6FC}\\x{1F700}-\\x{1F773}\\x{1F780}-\\x{1F7D8}\\x{1F7E0}-\\x{1F7EB}\\x{1F800}-\\x{1F80B}\\x{1F810}-\\x{1F847}\\x{1F850}-\\x{1F859}\\x{1F860}-\\x{1F887}\\x{1F890}-\\x{1F8AD}\\x{1F8B0}-\\x{1F8B1}\\x{1F900}-\\x{1F978}\\x{1F97A}-\\x{1F9CB}\\x{1F9CD}-\\x{1FA53}\\x{1FA60}-\\x{1FA6D}\\x{1FA70}-\\x{1FA74}\\x{1FA78}-\\x{1FA7A}\\x{1FA80}-\\x{1FA86}\\x{1FA90}-\\x{1FAA8}\\x{1FAB0}-\\x{1FAB6}\\x{1FAC0}-\\x{1FAC2}\\x{1FAD0}-\\x{1FAD6}\\x{1FB00}-\\x{1FB92}\\x{1FB94}-\\x{1FBCA}\\x{1FFFE}-\\x{1FFFF}\\x{2FFFE}-\\x{2FFFF}\\x{3FFFE}-\\x{3FFFF}\\x{4FFFE}-\\x{4FFFF}\\x{5FFFE}-\\x{5FFFF}\\x{6FFFE}-\\x{6FFFF}\\x{7FFFE}-\\x{7FFFF}\\x{8FFFE}-\\x{8FFFF}\\x{9FFFE}-\\x{9FFFF}\\x{AFFFE}-\\x{AFFFF}\\x{BFFFE}-\\x{BFFFF}\\x{CFFFE}-\\x{CFFFF}\\x{DFFFE}-\\x{E0000}\\x{E0001}\\x{E0002}-\\x{E001F}\\x{E0020}-\\x{E007F}\\x{E0080}-\\x{E00FF}\\x{E0100}-\\x{E01EF}\\x{E01F0}-\\x{E0FFF}\\x{EFFFE}-\\x{EFFFF}\\x{FFFFE}-\\x{FFFFF}\\x{10FFFE}-\\x{10FFFF}][\\x{0300}-\\x{036F}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{0591}-\\x{05BD}\\x{05BF}\\x{05C1}-\\x{05C2}\\x{05C4}-\\x{05C5}\\x{05C7}\\x{0610}-\\x{061A}\\x{064B}-\\x{065F}\\x{0670}\\x{06D6}-\\x{06DC}\\x{06DF}-\\x{06E4}\\x{06E7}-\\x{06E8}\\x{06EA}-\\x{06ED}\\x{0711}\\x{0730}-\\x{074A}\\x{07A6}-\\x{07B0}\\x{07EB}-\\x{07F3}\\x{07FD}\\x{0816}-\\x{0819}\\x{081B}-\\x{0823}\\x{0825}-\\x{0827}\\x{0829}-\\x{082D}\\x{0859}-\\x{085B}\\x{08D3}-\\x{08E1}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C81}\\x{0CBC}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{135D}-\\x{135F}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17DD}\\x{180B}-\\x{180D}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2CEF}-\\x{2CF1}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{302A}-\\x{302D}\\x{3099}-\\x{309A}\\x{A66F}\\x{A670}-\\x{A672}\\x{A674}-\\x{A67D}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A82C}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}-\\x{A9BD}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEC}-\\x{AAED}\\x{AAF6}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1E}\\x{FE00}-\\x{FE0F}\\x{FE20}-\\x{FE2F}\\x{101FD}\\x{102E0}\\x{10376}-\\x{1037A}\\x{10A01}-\\x{10A03}\\x{10A05}-\\x{10A06}\\x{10A0C}-\\x{10A0F}\\x{10A38}-\\x{10A3A}\\x{10A3F}\\x{10AE5}-\\x{10AE6}\\x{10D24}-\\x{10D27}\\x{10EAB}-\\x{10EAC}\\x{10F46}-\\x{10F50}\\x{11001}\\x{11038}-\\x{11046}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{111CF}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{1193B}-\\x{1193C}\\x{1193E}\\x{11943}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119E0}\\x{11A01}-\\x{11A06}\\x{11A09}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F8F}-\\x{16F92}\\x{16FE4}\\x{1BC9D}-\\x{1BC9E}\\x{1D167}-\\x{1D169}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D242}-\\x{1D244}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E8D0}-\\x{1E8D6}\\x{1E944}-\\x{1E94A}\\x{E0100}-\\x{E01EF}]*$/u'; + const ZWNJ = '/([\\x{A872}\\x{10ACD}\\x{10AD7}\\x{10D00}\\x{10FCB}\\x{0620}\\x{0626}\\x{0628}\\x{062A}-\\x{062E}\\x{0633}-\\x{063F}\\x{0641}-\\x{0647}\\x{0649}-\\x{064A}\\x{066E}-\\x{066F}\\x{0678}-\\x{0687}\\x{069A}-\\x{06BF}\\x{06C1}-\\x{06C2}\\x{06CC}\\x{06CE}\\x{06D0}-\\x{06D1}\\x{06FA}-\\x{06FC}\\x{06FF}\\x{0712}-\\x{0714}\\x{071A}-\\x{071D}\\x{071F}-\\x{0727}\\x{0729}\\x{072B}\\x{072D}-\\x{072E}\\x{074E}-\\x{0758}\\x{075C}-\\x{076A}\\x{076D}-\\x{0770}\\x{0772}\\x{0775}-\\x{0777}\\x{077A}-\\x{077F}\\x{07CA}-\\x{07EA}\\x{0841}-\\x{0845}\\x{0848}\\x{084A}-\\x{0853}\\x{0855}\\x{0860}\\x{0862}-\\x{0865}\\x{0868}\\x{08A0}-\\x{08A9}\\x{08AF}-\\x{08B0}\\x{08B3}-\\x{08B4}\\x{08B6}-\\x{08B8}\\x{08BA}-\\x{08C7}\\x{1807}\\x{1820}-\\x{1842}\\x{1843}\\x{1844}-\\x{1878}\\x{1887}-\\x{18A8}\\x{18AA}\\x{A840}-\\x{A871}\\x{10AC0}-\\x{10AC4}\\x{10AD3}-\\x{10AD6}\\x{10AD8}-\\x{10ADC}\\x{10ADE}-\\x{10AE0}\\x{10AEB}-\\x{10AEE}\\x{10B80}\\x{10B82}\\x{10B86}-\\x{10B88}\\x{10B8A}-\\x{10B8B}\\x{10B8D}\\x{10B90}\\x{10BAD}-\\x{10BAE}\\x{10D01}-\\x{10D21}\\x{10D23}\\x{10F30}-\\x{10F32}\\x{10F34}-\\x{10F44}\\x{10F51}-\\x{10F53}\\x{10FB0}\\x{10FB2}-\\x{10FB3}\\x{10FB8}\\x{10FBB}-\\x{10FBC}\\x{10FBE}-\\x{10FBF}\\x{10FC1}\\x{10FC4}\\x{10FCA}\\x{1E900}-\\x{1E943}][\\x{00AD}\\x{0300}-\\x{036F}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{0591}-\\x{05BD}\\x{05BF}\\x{05C1}-\\x{05C2}\\x{05C4}-\\x{05C5}\\x{05C7}\\x{0610}-\\x{061A}\\x{061C}\\x{064B}-\\x{065F}\\x{0670}\\x{06D6}-\\x{06DC}\\x{06DF}-\\x{06E4}\\x{06E7}-\\x{06E8}\\x{06EA}-\\x{06ED}\\x{070F}\\x{0711}\\x{0730}-\\x{074A}\\x{07A6}-\\x{07B0}\\x{07EB}-\\x{07F3}\\x{07FD}\\x{0816}-\\x{0819}\\x{081B}-\\x{0823}\\x{0825}-\\x{0827}\\x{0829}-\\x{082D}\\x{0859}-\\x{085B}\\x{08D3}-\\x{08E1}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C81}\\x{0CBC}\\x{0CBF}\\x{0CC6}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{135D}-\\x{135F}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17DD}\\x{180B}-\\x{180D}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{200B}\\x{200E}-\\x{200F}\\x{202A}-\\x{202E}\\x{2060}-\\x{2064}\\x{206A}-\\x{206F}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2CEF}-\\x{2CF1}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{302A}-\\x{302D}\\x{3099}-\\x{309A}\\x{A66F}\\x{A670}-\\x{A672}\\x{A674}-\\x{A67D}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A82C}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}-\\x{A9BD}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEC}-\\x{AAED}\\x{AAF6}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1E}\\x{FE00}-\\x{FE0F}\\x{FE20}-\\x{FE2F}\\x{FEFF}\\x{FFF9}-\\x{FFFB}\\x{101FD}\\x{102E0}\\x{10376}-\\x{1037A}\\x{10A01}-\\x{10A03}\\x{10A05}-\\x{10A06}\\x{10A0C}-\\x{10A0F}\\x{10A38}-\\x{10A3A}\\x{10A3F}\\x{10AE5}-\\x{10AE6}\\x{10D24}-\\x{10D27}\\x{10EAB}-\\x{10EAC}\\x{10F46}-\\x{10F50}\\x{11001}\\x{11038}-\\x{11046}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{111CF}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{1193B}-\\x{1193C}\\x{1193E}\\x{11943}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119E0}\\x{11A01}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C3F}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{13430}-\\x{13438}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F8F}-\\x{16F92}\\x{16FE4}\\x{1BC9D}-\\x{1BC9E}\\x{1BCA0}-\\x{1BCA3}\\x{1D167}-\\x{1D169}\\x{1D173}-\\x{1D17A}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D242}-\\x{1D244}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E8D0}-\\x{1E8D6}\\x{1E944}-\\x{1E94A}\\x{1E94B}\\x{E0001}\\x{E0020}-\\x{E007F}\\x{E0100}-\\x{E01EF}]*\\x{200C}[\\x{00AD}\\x{0300}-\\x{036F}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{0591}-\\x{05BD}\\x{05BF}\\x{05C1}-\\x{05C2}\\x{05C4}-\\x{05C5}\\x{05C7}\\x{0610}-\\x{061A}\\x{061C}\\x{064B}-\\x{065F}\\x{0670}\\x{06D6}-\\x{06DC}\\x{06DF}-\\x{06E4}\\x{06E7}-\\x{06E8}\\x{06EA}-\\x{06ED}\\x{070F}\\x{0711}\\x{0730}-\\x{074A}\\x{07A6}-\\x{07B0}\\x{07EB}-\\x{07F3}\\x{07FD}\\x{0816}-\\x{0819}\\x{081B}-\\x{0823}\\x{0825}-\\x{0827}\\x{0829}-\\x{082D}\\x{0859}-\\x{085B}\\x{08D3}-\\x{08E1}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B55}-\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C81}\\x{0CBC}\\x{0CBF}\\x{0CC6}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0D81}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EBC}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{135D}-\\x{135F}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17DD}\\x{180B}-\\x{180D}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1ABF}-\\x{1AC0}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{200B}\\x{200E}-\\x{200F}\\x{202A}-\\x{202E}\\x{2060}-\\x{2064}\\x{206A}-\\x{206F}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2CEF}-\\x{2CF1}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{302A}-\\x{302D}\\x{3099}-\\x{309A}\\x{A66F}\\x{A670}-\\x{A672}\\x{A674}-\\x{A67D}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A82C}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}-\\x{A9BD}\\x{A9E5}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AAEC}-\\x{AAED}\\x{AAF6}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1E}\\x{FE00}-\\x{FE0F}\\x{FE20}-\\x{FE2F}\\x{FEFF}\\x{FFF9}-\\x{FFFB}\\x{101FD}\\x{102E0}\\x{10376}-\\x{1037A}\\x{10A01}-\\x{10A03}\\x{10A05}-\\x{10A06}\\x{10A0C}-\\x{10A0F}\\x{10A38}-\\x{10A3A}\\x{10A3F}\\x{10AE5}-\\x{10AE6}\\x{10D24}-\\x{10D27}\\x{10EAB}-\\x{10EAC}\\x{10F46}-\\x{10F50}\\x{11001}\\x{11038}-\\x{11046}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{111CF}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{1193B}-\\x{1193C}\\x{1193E}\\x{11943}\\x{119D4}-\\x{119D7}\\x{119DA}-\\x{119DB}\\x{119E0}\\x{11A01}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C3F}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{13430}-\\x{13438}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16F4F}\\x{16F8F}-\\x{16F92}\\x{16FE4}\\x{1BC9D}-\\x{1BC9E}\\x{1BCA0}-\\x{1BCA3}\\x{1D167}-\\x{1D169}\\x{1D173}-\\x{1D17A}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D242}-\\x{1D244}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E130}-\\x{1E136}\\x{1E2EC}-\\x{1E2EF}\\x{1E8D0}-\\x{1E8D6}\\x{1E944}-\\x{1E94A}\\x{1E94B}\\x{E0001}\\x{E0020}-\\x{E007F}\\x{E0100}-\\x{E01EF}]*)[\\x{0622}-\\x{0625}\\x{0627}\\x{0629}\\x{062F}-\\x{0632}\\x{0648}\\x{0671}-\\x{0673}\\x{0675}-\\x{0677}\\x{0688}-\\x{0699}\\x{06C0}\\x{06C3}-\\x{06CB}\\x{06CD}\\x{06CF}\\x{06D2}-\\x{06D3}\\x{06D5}\\x{06EE}-\\x{06EF}\\x{0710}\\x{0715}-\\x{0719}\\x{071E}\\x{0728}\\x{072A}\\x{072C}\\x{072F}\\x{074D}\\x{0759}-\\x{075B}\\x{076B}-\\x{076C}\\x{0771}\\x{0773}-\\x{0774}\\x{0778}-\\x{0779}\\x{0840}\\x{0846}-\\x{0847}\\x{0849}\\x{0854}\\x{0856}-\\x{0858}\\x{0867}\\x{0869}-\\x{086A}\\x{08AA}-\\x{08AC}\\x{08AE}\\x{08B1}-\\x{08B2}\\x{08B9}\\x{10AC5}\\x{10AC7}\\x{10AC9}-\\x{10ACA}\\x{10ACE}-\\x{10AD2}\\x{10ADD}\\x{10AE1}\\x{10AE4}\\x{10AEF}\\x{10B81}\\x{10B83}-\\x{10B85}\\x{10B89}\\x{10B8C}\\x{10B8E}-\\x{10B8F}\\x{10B91}\\x{10BA9}-\\x{10BAC}\\x{10D22}\\x{10F33}\\x{10F54}\\x{10FB4}-\\x{10FB6}\\x{10FB9}-\\x{10FBA}\\x{10FBD}\\x{10FC2}-\\x{10FC3}\\x{10FC9}\\x{0620}\\x{0626}\\x{0628}\\x{062A}-\\x{062E}\\x{0633}-\\x{063F}\\x{0641}-\\x{0647}\\x{0649}-\\x{064A}\\x{066E}-\\x{066F}\\x{0678}-\\x{0687}\\x{069A}-\\x{06BF}\\x{06C1}-\\x{06C2}\\x{06CC}\\x{06CE}\\x{06D0}-\\x{06D1}\\x{06FA}-\\x{06FC}\\x{06FF}\\x{0712}-\\x{0714}\\x{071A}-\\x{071D}\\x{071F}-\\x{0727}\\x{0729}\\x{072B}\\x{072D}-\\x{072E}\\x{074E}-\\x{0758}\\x{075C}-\\x{076A}\\x{076D}-\\x{0770}\\x{0772}\\x{0775}-\\x{0777}\\x{077A}-\\x{077F}\\x{07CA}-\\x{07EA}\\x{0841}-\\x{0845}\\x{0848}\\x{084A}-\\x{0853}\\x{0855}\\x{0860}\\x{0862}-\\x{0865}\\x{0868}\\x{08A0}-\\x{08A9}\\x{08AF}-\\x{08B0}\\x{08B3}-\\x{08B4}\\x{08B6}-\\x{08B8}\\x{08BA}-\\x{08C7}\\x{1807}\\x{1820}-\\x{1842}\\x{1843}\\x{1844}-\\x{1878}\\x{1887}-\\x{18A8}\\x{18AA}\\x{A840}-\\x{A871}\\x{10AC0}-\\x{10AC4}\\x{10AD3}-\\x{10AD6}\\x{10AD8}-\\x{10ADC}\\x{10ADE}-\\x{10AE0}\\x{10AEB}-\\x{10AEE}\\x{10B80}\\x{10B82}\\x{10B86}-\\x{10B88}\\x{10B8A}-\\x{10B8B}\\x{10B8D}\\x{10B90}\\x{10BAD}-\\x{10BAE}\\x{10D01}-\\x{10D21}\\x{10D23}\\x{10F30}-\\x{10F32}\\x{10F34}-\\x{10F44}\\x{10F51}-\\x{10F53}\\x{10FB0}\\x{10FB2}-\\x{10FB3}\\x{10FB8}\\x{10FBB}-\\x{10FBC}\\x{10FBE}-\\x{10FBF}\\x{10FC1}\\x{10FC4}\\x{10FCA}\\x{1E900}-\\x{1E943}]/u'; +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/deviation.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/deviation.php new file mode 100644 index 0000000..edd5a4a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/deviation.php @@ -0,0 +1,5 @@ + 'ss', 962 => 'σ', 8204 => '', 8205 => ''); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php new file mode 100644 index 0000000..5f9eddd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php @@ -0,0 +1,5 @@ + \true, 889 => \true, 896 => \true, 897 => \true, 898 => \true, 899 => \true, 907 => \true, 909 => \true, 930 => \true, 1216 => \true, 1328 => \true, 1367 => \true, 1368 => \true, 1419 => \true, 1420 => \true, 1424 => \true, 1480 => \true, 1481 => \true, 1482 => \true, 1483 => \true, 1484 => \true, 1485 => \true, 1486 => \true, 1487 => \true, 1515 => \true, 1516 => \true, 1517 => \true, 1518 => \true, 1525 => \true, 1526 => \true, 1527 => \true, 1528 => \true, 1529 => \true, 1530 => \true, 1531 => \true, 1532 => \true, 1533 => \true, 1534 => \true, 1535 => \true, 1536 => \true, 1537 => \true, 1538 => \true, 1539 => \true, 1540 => \true, 1541 => \true, 1564 => \true, 1565 => \true, 1757 => \true, 1806 => \true, 1807 => \true, 1867 => \true, 1868 => \true, 1970 => \true, 1971 => \true, 1972 => \true, 1973 => \true, 1974 => \true, 1975 => \true, 1976 => \true, 1977 => \true, 1978 => \true, 1979 => \true, 1980 => \true, 1981 => \true, 1982 => \true, 1983 => \true, 2043 => \true, 2044 => \true, 2094 => \true, 2095 => \true, 2111 => \true, 2140 => \true, 2141 => \true, 2143 => \true, 2229 => \true, 2248 => \true, 2249 => \true, 2250 => \true, 2251 => \true, 2252 => \true, 2253 => \true, 2254 => \true, 2255 => \true, 2256 => \true, 2257 => \true, 2258 => \true, 2274 => \true, 2436 => \true, 2445 => \true, 2446 => \true, 2449 => \true, 2450 => \true, 2473 => \true, 2481 => \true, 2483 => \true, 2484 => \true, 2485 => \true, 2490 => \true, 2491 => \true, 2501 => \true, 2502 => \true, 2505 => \true, 2506 => \true, 2511 => \true, 2512 => \true, 2513 => \true, 2514 => \true, 2515 => \true, 2516 => \true, 2517 => \true, 2518 => \true, 2520 => \true, 2521 => \true, 2522 => \true, 2523 => \true, 2526 => \true, 2532 => \true, 2533 => \true, 2559 => \true, 2560 => \true, 2564 => \true, 2571 => \true, 2572 => \true, 2573 => \true, 2574 => \true, 2577 => \true, 2578 => \true, 2601 => \true, 2609 => \true, 2612 => \true, 2615 => \true, 2618 => \true, 2619 => \true, 2621 => \true, 2627 => \true, 2628 => \true, 2629 => \true, 2630 => \true, 2633 => \true, 2634 => \true, 2638 => \true, 2639 => \true, 2640 => \true, 2642 => \true, 2643 => \true, 2644 => \true, 2645 => \true, 2646 => \true, 2647 => \true, 2648 => \true, 2653 => \true, 2655 => \true, 2656 => \true, 2657 => \true, 2658 => \true, 2659 => \true, 2660 => \true, 2661 => \true, 2679 => \true, 2680 => \true, 2681 => \true, 2682 => \true, 2683 => \true, 2684 => \true, 2685 => \true, 2686 => \true, 2687 => \true, 2688 => \true, 2692 => \true, 2702 => \true, 2706 => \true, 2729 => \true, 2737 => \true, 2740 => \true, 2746 => \true, 2747 => \true, 2758 => \true, 2762 => \true, 2766 => \true, 2767 => \true, 2769 => \true, 2770 => \true, 2771 => \true, 2772 => \true, 2773 => \true, 2774 => \true, 2775 => \true, 2776 => \true, 2777 => \true, 2778 => \true, 2779 => \true, 2780 => \true, 2781 => \true, 2782 => \true, 2783 => \true, 2788 => \true, 2789 => \true, 2802 => \true, 2803 => \true, 2804 => \true, 2805 => \true, 2806 => \true, 2807 => \true, 2808 => \true, 2816 => \true, 2820 => \true, 2829 => \true, 2830 => \true, 2833 => \true, 2834 => \true, 2857 => \true, 2865 => \true, 2868 => \true, 2874 => \true, 2875 => \true, 2885 => \true, 2886 => \true, 2889 => \true, 2890 => \true, 2894 => \true, 2895 => \true, 2896 => \true, 2897 => \true, 2898 => \true, 2899 => \true, 2900 => \true, 2904 => \true, 2905 => \true, 2906 => \true, 2907 => \true, 2910 => \true, 2916 => \true, 2917 => \true, 2936 => \true, 2937 => \true, 2938 => \true, 2939 => \true, 2940 => \true, 2941 => \true, 2942 => \true, 2943 => \true, 2944 => \true, 2945 => \true, 2948 => \true, 2955 => \true, 2956 => \true, 2957 => \true, 2961 => \true, 2966 => \true, 2967 => \true, 2968 => \true, 2971 => \true, 2973 => \true, 2976 => \true, 2977 => \true, 2978 => \true, 2981 => \true, 2982 => \true, 2983 => \true, 2987 => \true, 2988 => \true, 2989 => \true, 3002 => \true, 3003 => \true, 3004 => \true, 3005 => \true, 3011 => \true, 3012 => \true, 3013 => \true, 3017 => \true, 3022 => \true, 3023 => \true, 3025 => \true, 3026 => \true, 3027 => \true, 3028 => \true, 3029 => \true, 3030 => \true, 3032 => \true, 3033 => \true, 3034 => \true, 3035 => \true, 3036 => \true, 3037 => \true, 3038 => \true, 3039 => \true, 3040 => \true, 3041 => \true, 3042 => \true, 3043 => \true, 3044 => \true, 3045 => \true, 3067 => \true, 3068 => \true, 3069 => \true, 3070 => \true, 3071 => \true, 3085 => \true, 3089 => \true, 3113 => \true, 3130 => \true, 3131 => \true, 3132 => \true, 3141 => \true, 3145 => \true, 3150 => \true, 3151 => \true, 3152 => \true, 3153 => \true, 3154 => \true, 3155 => \true, 3156 => \true, 3159 => \true, 3163 => \true, 3164 => \true, 3165 => \true, 3166 => \true, 3167 => \true, 3172 => \true, 3173 => \true, 3184 => \true, 3185 => \true, 3186 => \true, 3187 => \true, 3188 => \true, 3189 => \true, 3190 => \true, 3213 => \true, 3217 => \true, 3241 => \true, 3252 => \true, 3258 => \true, 3259 => \true, 3269 => \true, 3273 => \true, 3278 => \true, 3279 => \true, 3280 => \true, 3281 => \true, 3282 => \true, 3283 => \true, 3284 => \true, 3287 => \true, 3288 => \true, 3289 => \true, 3290 => \true, 3291 => \true, 3292 => \true, 3293 => \true, 3295 => \true, 3300 => \true, 3301 => \true, 3312 => \true, 3315 => \true, 3316 => \true, 3317 => \true, 3318 => \true, 3319 => \true, 3320 => \true, 3321 => \true, 3322 => \true, 3323 => \true, 3324 => \true, 3325 => \true, 3326 => \true, 3327 => \true, 3341 => \true, 3345 => \true, 3397 => \true, 3401 => \true, 3408 => \true, 3409 => \true, 3410 => \true, 3411 => \true, 3428 => \true, 3429 => \true, 3456 => \true, 3460 => \true, 3479 => \true, 3480 => \true, 3481 => \true, 3506 => \true, 3516 => \true, 3518 => \true, 3519 => \true, 3527 => \true, 3528 => \true, 3529 => \true, 3531 => \true, 3532 => \true, 3533 => \true, 3534 => \true, 3541 => \true, 3543 => \true, 3552 => \true, 3553 => \true, 3554 => \true, 3555 => \true, 3556 => \true, 3557 => \true, 3568 => \true, 3569 => \true, 3573 => \true, 3574 => \true, 3575 => \true, 3576 => \true, 3577 => \true, 3578 => \true, 3579 => \true, 3580 => \true, 3581 => \true, 3582 => \true, 3583 => \true, 3584 => \true, 3643 => \true, 3644 => \true, 3645 => \true, 3646 => \true, 3715 => \true, 3717 => \true, 3723 => \true, 3748 => \true, 3750 => \true, 3774 => \true, 3775 => \true, 3781 => \true, 3783 => \true, 3790 => \true, 3791 => \true, 3802 => \true, 3803 => \true, 3912 => \true, 3949 => \true, 3950 => \true, 3951 => \true, 3952 => \true, 3992 => \true, 4029 => \true, 4045 => \true, 4294 => \true, 4296 => \true, 4297 => \true, 4298 => \true, 4299 => \true, 4300 => \true, 4302 => \true, 4303 => \true, 4447 => \true, 4448 => \true, 4681 => \true, 4686 => \true, 4687 => \true, 4695 => \true, 4697 => \true, 4702 => \true, 4703 => \true, 4745 => \true, 4750 => \true, 4751 => \true, 4785 => \true, 4790 => \true, 4791 => \true, 4799 => \true, 4801 => \true, 4806 => \true, 4807 => \true, 4823 => \true, 4881 => \true, 4886 => \true, 4887 => \true, 4955 => \true, 4956 => \true, 4989 => \true, 4990 => \true, 4991 => \true, 5018 => \true, 5019 => \true, 5020 => \true, 5021 => \true, 5022 => \true, 5023 => \true, 5110 => \true, 5111 => \true, 5118 => \true, 5119 => \true, 5760 => \true, 5789 => \true, 5790 => \true, 5791 => \true, 5881 => \true, 5882 => \true, 5883 => \true, 5884 => \true, 5885 => \true, 5886 => \true, 5887 => \true, 5901 => \true, 5909 => \true, 5910 => \true, 5911 => \true, 5912 => \true, 5913 => \true, 5914 => \true, 5915 => \true, 5916 => \true, 5917 => \true, 5918 => \true, 5919 => \true, 5943 => \true, 5944 => \true, 5945 => \true, 5946 => \true, 5947 => \true, 5948 => \true, 5949 => \true, 5950 => \true, 5951 => \true, 5972 => \true, 5973 => \true, 5974 => \true, 5975 => \true, 5976 => \true, 5977 => \true, 5978 => \true, 5979 => \true, 5980 => \true, 5981 => \true, 5982 => \true, 5983 => \true, 5997 => \true, 6001 => \true, 6004 => \true, 6005 => \true, 6006 => \true, 6007 => \true, 6008 => \true, 6009 => \true, 6010 => \true, 6011 => \true, 6012 => \true, 6013 => \true, 6014 => \true, 6015 => \true, 6068 => \true, 6069 => \true, 6110 => \true, 6111 => \true, 6122 => \true, 6123 => \true, 6124 => \true, 6125 => \true, 6126 => \true, 6127 => \true, 6138 => \true, 6139 => \true, 6140 => \true, 6141 => \true, 6142 => \true, 6143 => \true, 6150 => \true, 6158 => \true, 6159 => \true, 6170 => \true, 6171 => \true, 6172 => \true, 6173 => \true, 6174 => \true, 6175 => \true, 6265 => \true, 6266 => \true, 6267 => \true, 6268 => \true, 6269 => \true, 6270 => \true, 6271 => \true, 6315 => \true, 6316 => \true, 6317 => \true, 6318 => \true, 6319 => \true, 6390 => \true, 6391 => \true, 6392 => \true, 6393 => \true, 6394 => \true, 6395 => \true, 6396 => \true, 6397 => \true, 6398 => \true, 6399 => \true, 6431 => \true, 6444 => \true, 6445 => \true, 6446 => \true, 6447 => \true, 6460 => \true, 6461 => \true, 6462 => \true, 6463 => \true, 6465 => \true, 6466 => \true, 6467 => \true, 6510 => \true, 6511 => \true, 6517 => \true, 6518 => \true, 6519 => \true, 6520 => \true, 6521 => \true, 6522 => \true, 6523 => \true, 6524 => \true, 6525 => \true, 6526 => \true, 6527 => \true, 6572 => \true, 6573 => \true, 6574 => \true, 6575 => \true, 6602 => \true, 6603 => \true, 6604 => \true, 6605 => \true, 6606 => \true, 6607 => \true, 6619 => \true, 6620 => \true, 6621 => \true, 6684 => \true, 6685 => \true, 6751 => \true, 6781 => \true, 6782 => \true, 6794 => \true, 6795 => \true, 6796 => \true, 6797 => \true, 6798 => \true, 6799 => \true, 6810 => \true, 6811 => \true, 6812 => \true, 6813 => \true, 6814 => \true, 6815 => \true, 6830 => \true, 6831 => \true, 6988 => \true, 6989 => \true, 6990 => \true, 6991 => \true, 7037 => \true, 7038 => \true, 7039 => \true, 7156 => \true, 7157 => \true, 7158 => \true, 7159 => \true, 7160 => \true, 7161 => \true, 7162 => \true, 7163 => \true, 7224 => \true, 7225 => \true, 7226 => \true, 7242 => \true, 7243 => \true, 7244 => \true, 7305 => \true, 7306 => \true, 7307 => \true, 7308 => \true, 7309 => \true, 7310 => \true, 7311 => \true, 7355 => \true, 7356 => \true, 7368 => \true, 7369 => \true, 7370 => \true, 7371 => \true, 7372 => \true, 7373 => \true, 7374 => \true, 7375 => \true, 7419 => \true, 7420 => \true, 7421 => \true, 7422 => \true, 7423 => \true, 7674 => \true, 7958 => \true, 7959 => \true, 7966 => \true, 7967 => \true, 8006 => \true, 8007 => \true, 8014 => \true, 8015 => \true, 8024 => \true, 8026 => \true, 8028 => \true, 8030 => \true, 8062 => \true, 8063 => \true, 8117 => \true, 8133 => \true, 8148 => \true, 8149 => \true, 8156 => \true, 8176 => \true, 8177 => \true, 8181 => \true, 8191 => \true, 8206 => \true, 8207 => \true, 8228 => \true, 8229 => \true, 8230 => \true, 8232 => \true, 8233 => \true, 8234 => \true, 8235 => \true, 8236 => \true, 8237 => \true, 8238 => \true, 8289 => \true, 8290 => \true, 8291 => \true, 8293 => \true, 8294 => \true, 8295 => \true, 8296 => \true, 8297 => \true, 8298 => \true, 8299 => \true, 8300 => \true, 8301 => \true, 8302 => \true, 8303 => \true, 8306 => \true, 8307 => \true, 8335 => \true, 8349 => \true, 8350 => \true, 8351 => \true, 8384 => \true, 8385 => \true, 8386 => \true, 8387 => \true, 8388 => \true, 8389 => \true, 8390 => \true, 8391 => \true, 8392 => \true, 8393 => \true, 8394 => \true, 8395 => \true, 8396 => \true, 8397 => \true, 8398 => \true, 8399 => \true, 8433 => \true, 8434 => \true, 8435 => \true, 8436 => \true, 8437 => \true, 8438 => \true, 8439 => \true, 8440 => \true, 8441 => \true, 8442 => \true, 8443 => \true, 8444 => \true, 8445 => \true, 8446 => \true, 8447 => \true, 8498 => \true, 8579 => \true, 8588 => \true, 8589 => \true, 8590 => \true, 8591 => \true, 9255 => \true, 9256 => \true, 9257 => \true, 9258 => \true, 9259 => \true, 9260 => \true, 9261 => \true, 9262 => \true, 9263 => \true, 9264 => \true, 9265 => \true, 9266 => \true, 9267 => \true, 9268 => \true, 9269 => \true, 9270 => \true, 9271 => \true, 9272 => \true, 9273 => \true, 9274 => \true, 9275 => \true, 9276 => \true, 9277 => \true, 9278 => \true, 9279 => \true, 9291 => \true, 9292 => \true, 9293 => \true, 9294 => \true, 9295 => \true, 9296 => \true, 9297 => \true, 9298 => \true, 9299 => \true, 9300 => \true, 9301 => \true, 9302 => \true, 9303 => \true, 9304 => \true, 9305 => \true, 9306 => \true, 9307 => \true, 9308 => \true, 9309 => \true, 9310 => \true, 9311 => \true, 9352 => \true, 9353 => \true, 9354 => \true, 9355 => \true, 9356 => \true, 9357 => \true, 9358 => \true, 9359 => \true, 9360 => \true, 9361 => \true, 9362 => \true, 9363 => \true, 9364 => \true, 9365 => \true, 9366 => \true, 9367 => \true, 9368 => \true, 9369 => \true, 9370 => \true, 9371 => \true, 11124 => \true, 11125 => \true, 11158 => \true, 11311 => \true, 11359 => \true, 11508 => \true, 11509 => \true, 11510 => \true, 11511 => \true, 11512 => \true, 11558 => \true, 11560 => \true, 11561 => \true, 11562 => \true, 11563 => \true, 11564 => \true, 11566 => \true, 11567 => \true, 11624 => \true, 11625 => \true, 11626 => \true, 11627 => \true, 11628 => \true, 11629 => \true, 11630 => \true, 11633 => \true, 11634 => \true, 11635 => \true, 11636 => \true, 11637 => \true, 11638 => \true, 11639 => \true, 11640 => \true, 11641 => \true, 11642 => \true, 11643 => \true, 11644 => \true, 11645 => \true, 11646 => \true, 11671 => \true, 11672 => \true, 11673 => \true, 11674 => \true, 11675 => \true, 11676 => \true, 11677 => \true, 11678 => \true, 11679 => \true, 11687 => \true, 11695 => \true, 11703 => \true, 11711 => \true, 11719 => \true, 11727 => \true, 11735 => \true, 11743 => \true, 11930 => \true, 12020 => \true, 12021 => \true, 12022 => \true, 12023 => \true, 12024 => \true, 12025 => \true, 12026 => \true, 12027 => \true, 12028 => \true, 12029 => \true, 12030 => \true, 12031 => \true, 12246 => \true, 12247 => \true, 12248 => \true, 12249 => \true, 12250 => \true, 12251 => \true, 12252 => \true, 12253 => \true, 12254 => \true, 12255 => \true, 12256 => \true, 12257 => \true, 12258 => \true, 12259 => \true, 12260 => \true, 12261 => \true, 12262 => \true, 12263 => \true, 12264 => \true, 12265 => \true, 12266 => \true, 12267 => \true, 12268 => \true, 12269 => \true, 12270 => \true, 12271 => \true, 12272 => \true, 12273 => \true, 12274 => \true, 12275 => \true, 12276 => \true, 12277 => \true, 12278 => \true, 12279 => \true, 12280 => \true, 12281 => \true, 12282 => \true, 12283 => \true, 12284 => \true, 12285 => \true, 12286 => \true, 12287 => \true, 12352 => \true, 12439 => \true, 12440 => \true, 12544 => \true, 12545 => \true, 12546 => \true, 12547 => \true, 12548 => \true, 12592 => \true, 12644 => \true, 12687 => \true, 12772 => \true, 12773 => \true, 12774 => \true, 12775 => \true, 12776 => \true, 12777 => \true, 12778 => \true, 12779 => \true, 12780 => \true, 12781 => \true, 12782 => \true, 12783 => \true, 12831 => \true, 13250 => \true, 13255 => \true, 13272 => \true, 40957 => \true, 40958 => \true, 40959 => \true, 42125 => \true, 42126 => \true, 42127 => \true, 42183 => \true, 42184 => \true, 42185 => \true, 42186 => \true, 42187 => \true, 42188 => \true, 42189 => \true, 42190 => \true, 42191 => \true, 42540 => \true, 42541 => \true, 42542 => \true, 42543 => \true, 42544 => \true, 42545 => \true, 42546 => \true, 42547 => \true, 42548 => \true, 42549 => \true, 42550 => \true, 42551 => \true, 42552 => \true, 42553 => \true, 42554 => \true, 42555 => \true, 42556 => \true, 42557 => \true, 42558 => \true, 42559 => \true, 42744 => \true, 42745 => \true, 42746 => \true, 42747 => \true, 42748 => \true, 42749 => \true, 42750 => \true, 42751 => \true, 42944 => \true, 42945 => \true, 43053 => \true, 43054 => \true, 43055 => \true, 43066 => \true, 43067 => \true, 43068 => \true, 43069 => \true, 43070 => \true, 43071 => \true, 43128 => \true, 43129 => \true, 43130 => \true, 43131 => \true, 43132 => \true, 43133 => \true, 43134 => \true, 43135 => \true, 43206 => \true, 43207 => \true, 43208 => \true, 43209 => \true, 43210 => \true, 43211 => \true, 43212 => \true, 43213 => \true, 43226 => \true, 43227 => \true, 43228 => \true, 43229 => \true, 43230 => \true, 43231 => \true, 43348 => \true, 43349 => \true, 43350 => \true, 43351 => \true, 43352 => \true, 43353 => \true, 43354 => \true, 43355 => \true, 43356 => \true, 43357 => \true, 43358 => \true, 43389 => \true, 43390 => \true, 43391 => \true, 43470 => \true, 43482 => \true, 43483 => \true, 43484 => \true, 43485 => \true, 43519 => \true, 43575 => \true, 43576 => \true, 43577 => \true, 43578 => \true, 43579 => \true, 43580 => \true, 43581 => \true, 43582 => \true, 43583 => \true, 43598 => \true, 43599 => \true, 43610 => \true, 43611 => \true, 43715 => \true, 43716 => \true, 43717 => \true, 43718 => \true, 43719 => \true, 43720 => \true, 43721 => \true, 43722 => \true, 43723 => \true, 43724 => \true, 43725 => \true, 43726 => \true, 43727 => \true, 43728 => \true, 43729 => \true, 43730 => \true, 43731 => \true, 43732 => \true, 43733 => \true, 43734 => \true, 43735 => \true, 43736 => \true, 43737 => \true, 43738 => \true, 43767 => \true, 43768 => \true, 43769 => \true, 43770 => \true, 43771 => \true, 43772 => \true, 43773 => \true, 43774 => \true, 43775 => \true, 43776 => \true, 43783 => \true, 43784 => \true, 43791 => \true, 43792 => \true, 43799 => \true, 43800 => \true, 43801 => \true, 43802 => \true, 43803 => \true, 43804 => \true, 43805 => \true, 43806 => \true, 43807 => \true, 43815 => \true, 43823 => \true, 43884 => \true, 43885 => \true, 43886 => \true, 43887 => \true, 44014 => \true, 44015 => \true, 44026 => \true, 44027 => \true, 44028 => \true, 44029 => \true, 44030 => \true, 44031 => \true, 55204 => \true, 55205 => \true, 55206 => \true, 55207 => \true, 55208 => \true, 55209 => \true, 55210 => \true, 55211 => \true, 55212 => \true, 55213 => \true, 55214 => \true, 55215 => \true, 55239 => \true, 55240 => \true, 55241 => \true, 55242 => \true, 55292 => \true, 55293 => \true, 55294 => \true, 55295 => \true, 64110 => \true, 64111 => \true, 64263 => \true, 64264 => \true, 64265 => \true, 64266 => \true, 64267 => \true, 64268 => \true, 64269 => \true, 64270 => \true, 64271 => \true, 64272 => \true, 64273 => \true, 64274 => \true, 64280 => \true, 64281 => \true, 64282 => \true, 64283 => \true, 64284 => \true, 64311 => \true, 64317 => \true, 64319 => \true, 64322 => \true, 64325 => \true, 64450 => \true, 64451 => \true, 64452 => \true, 64453 => \true, 64454 => \true, 64455 => \true, 64456 => \true, 64457 => \true, 64458 => \true, 64459 => \true, 64460 => \true, 64461 => \true, 64462 => \true, 64463 => \true, 64464 => \true, 64465 => \true, 64466 => \true, 64832 => \true, 64833 => \true, 64834 => \true, 64835 => \true, 64836 => \true, 64837 => \true, 64838 => \true, 64839 => \true, 64840 => \true, 64841 => \true, 64842 => \true, 64843 => \true, 64844 => \true, 64845 => \true, 64846 => \true, 64847 => \true, 64912 => \true, 64913 => \true, 64968 => \true, 64969 => \true, 64970 => \true, 64971 => \true, 64972 => \true, 64973 => \true, 64974 => \true, 64975 => \true, 65022 => \true, 65023 => \true, 65042 => \true, 65049 => \true, 65050 => \true, 65051 => \true, 65052 => \true, 65053 => \true, 65054 => \true, 65055 => \true, 65072 => \true, 65106 => \true, 65107 => \true, 65127 => \true, 65132 => \true, 65133 => \true, 65134 => \true, 65135 => \true, 65141 => \true, 65277 => \true, 65278 => \true, 65280 => \true, 65440 => \true, 65471 => \true, 65472 => \true, 65473 => \true, 65480 => \true, 65481 => \true, 65488 => \true, 65489 => \true, 65496 => \true, 65497 => \true, 65501 => \true, 65502 => \true, 65503 => \true, 65511 => \true, 65519 => \true, 65520 => \true, 65521 => \true, 65522 => \true, 65523 => \true, 65524 => \true, 65525 => \true, 65526 => \true, 65527 => \true, 65528 => \true, 65529 => \true, 65530 => \true, 65531 => \true, 65532 => \true, 65533 => \true, 65534 => \true, 65535 => \true, 65548 => \true, 65575 => \true, 65595 => \true, 65598 => \true, 65614 => \true, 65615 => \true, 65787 => \true, 65788 => \true, 65789 => \true, 65790 => \true, 65791 => \true, 65795 => \true, 65796 => \true, 65797 => \true, 65798 => \true, 65844 => \true, 65845 => \true, 65846 => \true, 65935 => \true, 65949 => \true, 65950 => \true, 65951 => \true, 66205 => \true, 66206 => \true, 66207 => \true, 66257 => \true, 66258 => \true, 66259 => \true, 66260 => \true, 66261 => \true, 66262 => \true, 66263 => \true, 66264 => \true, 66265 => \true, 66266 => \true, 66267 => \true, 66268 => \true, 66269 => \true, 66270 => \true, 66271 => \true, 66300 => \true, 66301 => \true, 66302 => \true, 66303 => \true, 66340 => \true, 66341 => \true, 66342 => \true, 66343 => \true, 66344 => \true, 66345 => \true, 66346 => \true, 66347 => \true, 66348 => \true, 66379 => \true, 66380 => \true, 66381 => \true, 66382 => \true, 66383 => \true, 66427 => \true, 66428 => \true, 66429 => \true, 66430 => \true, 66431 => \true, 66462 => \true, 66500 => \true, 66501 => \true, 66502 => \true, 66503 => \true, 66718 => \true, 66719 => \true, 66730 => \true, 66731 => \true, 66732 => \true, 66733 => \true, 66734 => \true, 66735 => \true, 66772 => \true, 66773 => \true, 66774 => \true, 66775 => \true, 66812 => \true, 66813 => \true, 66814 => \true, 66815 => \true, 66856 => \true, 66857 => \true, 66858 => \true, 66859 => \true, 66860 => \true, 66861 => \true, 66862 => \true, 66863 => \true, 66916 => \true, 66917 => \true, 66918 => \true, 66919 => \true, 66920 => \true, 66921 => \true, 66922 => \true, 66923 => \true, 66924 => \true, 66925 => \true, 66926 => \true, 67383 => \true, 67384 => \true, 67385 => \true, 67386 => \true, 67387 => \true, 67388 => \true, 67389 => \true, 67390 => \true, 67391 => \true, 67414 => \true, 67415 => \true, 67416 => \true, 67417 => \true, 67418 => \true, 67419 => \true, 67420 => \true, 67421 => \true, 67422 => \true, 67423 => \true, 67590 => \true, 67591 => \true, 67593 => \true, 67638 => \true, 67641 => \true, 67642 => \true, 67643 => \true, 67645 => \true, 67646 => \true, 67670 => \true, 67743 => \true, 67744 => \true, 67745 => \true, 67746 => \true, 67747 => \true, 67748 => \true, 67749 => \true, 67750 => \true, 67827 => \true, 67830 => \true, 67831 => \true, 67832 => \true, 67833 => \true, 67834 => \true, 67868 => \true, 67869 => \true, 67870 => \true, 67898 => \true, 67899 => \true, 67900 => \true, 67901 => \true, 67902 => \true, 68024 => \true, 68025 => \true, 68026 => \true, 68027 => \true, 68048 => \true, 68049 => \true, 68100 => \true, 68103 => \true, 68104 => \true, 68105 => \true, 68106 => \true, 68107 => \true, 68116 => \true, 68120 => \true, 68150 => \true, 68151 => \true, 68155 => \true, 68156 => \true, 68157 => \true, 68158 => \true, 68169 => \true, 68170 => \true, 68171 => \true, 68172 => \true, 68173 => \true, 68174 => \true, 68175 => \true, 68185 => \true, 68186 => \true, 68187 => \true, 68188 => \true, 68189 => \true, 68190 => \true, 68191 => \true, 68327 => \true, 68328 => \true, 68329 => \true, 68330 => \true, 68343 => \true, 68344 => \true, 68345 => \true, 68346 => \true, 68347 => \true, 68348 => \true, 68349 => \true, 68350 => \true, 68351 => \true, 68406 => \true, 68407 => \true, 68408 => \true, 68438 => \true, 68439 => \true, 68467 => \true, 68468 => \true, 68469 => \true, 68470 => \true, 68471 => \true, 68498 => \true, 68499 => \true, 68500 => \true, 68501 => \true, 68502 => \true, 68503 => \true, 68504 => \true, 68509 => \true, 68510 => \true, 68511 => \true, 68512 => \true, 68513 => \true, 68514 => \true, 68515 => \true, 68516 => \true, 68517 => \true, 68518 => \true, 68519 => \true, 68520 => \true, 68787 => \true, 68788 => \true, 68789 => \true, 68790 => \true, 68791 => \true, 68792 => \true, 68793 => \true, 68794 => \true, 68795 => \true, 68796 => \true, 68797 => \true, 68798 => \true, 68799 => \true, 68851 => \true, 68852 => \true, 68853 => \true, 68854 => \true, 68855 => \true, 68856 => \true, 68857 => \true, 68904 => \true, 68905 => \true, 68906 => \true, 68907 => \true, 68908 => \true, 68909 => \true, 68910 => \true, 68911 => \true, 69247 => \true, 69290 => \true, 69294 => \true, 69295 => \true, 69416 => \true, 69417 => \true, 69418 => \true, 69419 => \true, 69420 => \true, 69421 => \true, 69422 => \true, 69423 => \true, 69580 => \true, 69581 => \true, 69582 => \true, 69583 => \true, 69584 => \true, 69585 => \true, 69586 => \true, 69587 => \true, 69588 => \true, 69589 => \true, 69590 => \true, 69591 => \true, 69592 => \true, 69593 => \true, 69594 => \true, 69595 => \true, 69596 => \true, 69597 => \true, 69598 => \true, 69599 => \true, 69623 => \true, 69624 => \true, 69625 => \true, 69626 => \true, 69627 => \true, 69628 => \true, 69629 => \true, 69630 => \true, 69631 => \true, 69710 => \true, 69711 => \true, 69712 => \true, 69713 => \true, 69744 => \true, 69745 => \true, 69746 => \true, 69747 => \true, 69748 => \true, 69749 => \true, 69750 => \true, 69751 => \true, 69752 => \true, 69753 => \true, 69754 => \true, 69755 => \true, 69756 => \true, 69757 => \true, 69758 => \true, 69821 => \true, 69826 => \true, 69827 => \true, 69828 => \true, 69829 => \true, 69830 => \true, 69831 => \true, 69832 => \true, 69833 => \true, 69834 => \true, 69835 => \true, 69836 => \true, 69837 => \true, 69838 => \true, 69839 => \true, 69865 => \true, 69866 => \true, 69867 => \true, 69868 => \true, 69869 => \true, 69870 => \true, 69871 => \true, 69882 => \true, 69883 => \true, 69884 => \true, 69885 => \true, 69886 => \true, 69887 => \true, 69941 => \true, 69960 => \true, 69961 => \true, 69962 => \true, 69963 => \true, 69964 => \true, 69965 => \true, 69966 => \true, 69967 => \true, 70007 => \true, 70008 => \true, 70009 => \true, 70010 => \true, 70011 => \true, 70012 => \true, 70013 => \true, 70014 => \true, 70015 => \true, 70112 => \true, 70133 => \true, 70134 => \true, 70135 => \true, 70136 => \true, 70137 => \true, 70138 => \true, 70139 => \true, 70140 => \true, 70141 => \true, 70142 => \true, 70143 => \true, 70162 => \true, 70279 => \true, 70281 => \true, 70286 => \true, 70302 => \true, 70314 => \true, 70315 => \true, 70316 => \true, 70317 => \true, 70318 => \true, 70319 => \true, 70379 => \true, 70380 => \true, 70381 => \true, 70382 => \true, 70383 => \true, 70394 => \true, 70395 => \true, 70396 => \true, 70397 => \true, 70398 => \true, 70399 => \true, 70404 => \true, 70413 => \true, 70414 => \true, 70417 => \true, 70418 => \true, 70441 => \true, 70449 => \true, 70452 => \true, 70458 => \true, 70469 => \true, 70470 => \true, 70473 => \true, 70474 => \true, 70478 => \true, 70479 => \true, 70481 => \true, 70482 => \true, 70483 => \true, 70484 => \true, 70485 => \true, 70486 => \true, 70488 => \true, 70489 => \true, 70490 => \true, 70491 => \true, 70492 => \true, 70500 => \true, 70501 => \true, 70509 => \true, 70510 => \true, 70511 => \true, 70748 => \true, 70754 => \true, 70755 => \true, 70756 => \true, 70757 => \true, 70758 => \true, 70759 => \true, 70760 => \true, 70761 => \true, 70762 => \true, 70763 => \true, 70764 => \true, 70765 => \true, 70766 => \true, 70767 => \true, 70768 => \true, 70769 => \true, 70770 => \true, 70771 => \true, 70772 => \true, 70773 => \true, 70774 => \true, 70775 => \true, 70776 => \true, 70777 => \true, 70778 => \true, 70779 => \true, 70780 => \true, 70781 => \true, 70782 => \true, 70783 => \true, 70856 => \true, 70857 => \true, 70858 => \true, 70859 => \true, 70860 => \true, 70861 => \true, 70862 => \true, 70863 => \true, 71094 => \true, 71095 => \true, 71237 => \true, 71238 => \true, 71239 => \true, 71240 => \true, 71241 => \true, 71242 => \true, 71243 => \true, 71244 => \true, 71245 => \true, 71246 => \true, 71247 => \true, 71258 => \true, 71259 => \true, 71260 => \true, 71261 => \true, 71262 => \true, 71263 => \true, 71277 => \true, 71278 => \true, 71279 => \true, 71280 => \true, 71281 => \true, 71282 => \true, 71283 => \true, 71284 => \true, 71285 => \true, 71286 => \true, 71287 => \true, 71288 => \true, 71289 => \true, 71290 => \true, 71291 => \true, 71292 => \true, 71293 => \true, 71294 => \true, 71295 => \true, 71353 => \true, 71354 => \true, 71355 => \true, 71356 => \true, 71357 => \true, 71358 => \true, 71359 => \true, 71451 => \true, 71452 => \true, 71468 => \true, 71469 => \true, 71470 => \true, 71471 => \true, 71923 => \true, 71924 => \true, 71925 => \true, 71926 => \true, 71927 => \true, 71928 => \true, 71929 => \true, 71930 => \true, 71931 => \true, 71932 => \true, 71933 => \true, 71934 => \true, 71943 => \true, 71944 => \true, 71946 => \true, 71947 => \true, 71956 => \true, 71959 => \true, 71990 => \true, 71993 => \true, 71994 => \true, 72007 => \true, 72008 => \true, 72009 => \true, 72010 => \true, 72011 => \true, 72012 => \true, 72013 => \true, 72014 => \true, 72015 => \true, 72104 => \true, 72105 => \true, 72152 => \true, 72153 => \true, 72165 => \true, 72166 => \true, 72167 => \true, 72168 => \true, 72169 => \true, 72170 => \true, 72171 => \true, 72172 => \true, 72173 => \true, 72174 => \true, 72175 => \true, 72176 => \true, 72177 => \true, 72178 => \true, 72179 => \true, 72180 => \true, 72181 => \true, 72182 => \true, 72183 => \true, 72184 => \true, 72185 => \true, 72186 => \true, 72187 => \true, 72188 => \true, 72189 => \true, 72190 => \true, 72191 => \true, 72264 => \true, 72265 => \true, 72266 => \true, 72267 => \true, 72268 => \true, 72269 => \true, 72270 => \true, 72271 => \true, 72355 => \true, 72356 => \true, 72357 => \true, 72358 => \true, 72359 => \true, 72360 => \true, 72361 => \true, 72362 => \true, 72363 => \true, 72364 => \true, 72365 => \true, 72366 => \true, 72367 => \true, 72368 => \true, 72369 => \true, 72370 => \true, 72371 => \true, 72372 => \true, 72373 => \true, 72374 => \true, 72375 => \true, 72376 => \true, 72377 => \true, 72378 => \true, 72379 => \true, 72380 => \true, 72381 => \true, 72382 => \true, 72383 => \true, 72713 => \true, 72759 => \true, 72774 => \true, 72775 => \true, 72776 => \true, 72777 => \true, 72778 => \true, 72779 => \true, 72780 => \true, 72781 => \true, 72782 => \true, 72783 => \true, 72813 => \true, 72814 => \true, 72815 => \true, 72848 => \true, 72849 => \true, 72872 => \true, 72967 => \true, 72970 => \true, 73015 => \true, 73016 => \true, 73017 => \true, 73019 => \true, 73022 => \true, 73032 => \true, 73033 => \true, 73034 => \true, 73035 => \true, 73036 => \true, 73037 => \true, 73038 => \true, 73039 => \true, 73050 => \true, 73051 => \true, 73052 => \true, 73053 => \true, 73054 => \true, 73055 => \true, 73062 => \true, 73065 => \true, 73103 => \true, 73106 => \true, 73113 => \true, 73114 => \true, 73115 => \true, 73116 => \true, 73117 => \true, 73118 => \true, 73119 => \true, 73649 => \true, 73650 => \true, 73651 => \true, 73652 => \true, 73653 => \true, 73654 => \true, 73655 => \true, 73656 => \true, 73657 => \true, 73658 => \true, 73659 => \true, 73660 => \true, 73661 => \true, 73662 => \true, 73663 => \true, 73714 => \true, 73715 => \true, 73716 => \true, 73717 => \true, 73718 => \true, 73719 => \true, 73720 => \true, 73721 => \true, 73722 => \true, 73723 => \true, 73724 => \true, 73725 => \true, 73726 => \true, 74863 => \true, 74869 => \true, 74870 => \true, 74871 => \true, 74872 => \true, 74873 => \true, 74874 => \true, 74875 => \true, 74876 => \true, 74877 => \true, 74878 => \true, 74879 => \true, 78895 => \true, 78896 => \true, 78897 => \true, 78898 => \true, 78899 => \true, 78900 => \true, 78901 => \true, 78902 => \true, 78903 => \true, 78904 => \true, 92729 => \true, 92730 => \true, 92731 => \true, 92732 => \true, 92733 => \true, 92734 => \true, 92735 => \true, 92767 => \true, 92778 => \true, 92779 => \true, 92780 => \true, 92781 => \true, 92910 => \true, 92911 => \true, 92918 => \true, 92919 => \true, 92920 => \true, 92921 => \true, 92922 => \true, 92923 => \true, 92924 => \true, 92925 => \true, 92926 => \true, 92927 => \true, 92998 => \true, 92999 => \true, 93000 => \true, 93001 => \true, 93002 => \true, 93003 => \true, 93004 => \true, 93005 => \true, 93006 => \true, 93007 => \true, 93018 => \true, 93026 => \true, 93048 => \true, 93049 => \true, 93050 => \true, 93051 => \true, 93052 => \true, 94027 => \true, 94028 => \true, 94029 => \true, 94030 => \true, 94088 => \true, 94089 => \true, 94090 => \true, 94091 => \true, 94092 => \true, 94093 => \true, 94094 => \true, 94181 => \true, 94182 => \true, 94183 => \true, 94184 => \true, 94185 => \true, 94186 => \true, 94187 => \true, 94188 => \true, 94189 => \true, 94190 => \true, 94191 => \true, 94194 => \true, 94195 => \true, 94196 => \true, 94197 => \true, 94198 => \true, 94199 => \true, 94200 => \true, 94201 => \true, 94202 => \true, 94203 => \true, 94204 => \true, 94205 => \true, 94206 => \true, 94207 => \true, 100344 => \true, 100345 => \true, 100346 => \true, 100347 => \true, 100348 => \true, 100349 => \true, 100350 => \true, 100351 => \true, 110931 => \true, 110932 => \true, 110933 => \true, 110934 => \true, 110935 => \true, 110936 => \true, 110937 => \true, 110938 => \true, 110939 => \true, 110940 => \true, 110941 => \true, 110942 => \true, 110943 => \true, 110944 => \true, 110945 => \true, 110946 => \true, 110947 => \true, 110952 => \true, 110953 => \true, 110954 => \true, 110955 => \true, 110956 => \true, 110957 => \true, 110958 => \true, 110959 => \true, 113771 => \true, 113772 => \true, 113773 => \true, 113774 => \true, 113775 => \true, 113789 => \true, 113790 => \true, 113791 => \true, 113801 => \true, 113802 => \true, 113803 => \true, 113804 => \true, 113805 => \true, 113806 => \true, 113807 => \true, 113818 => \true, 113819 => \true, 119030 => \true, 119031 => \true, 119032 => \true, 119033 => \true, 119034 => \true, 119035 => \true, 119036 => \true, 119037 => \true, 119038 => \true, 119039 => \true, 119079 => \true, 119080 => \true, 119155 => \true, 119156 => \true, 119157 => \true, 119158 => \true, 119159 => \true, 119160 => \true, 119161 => \true, 119162 => \true, 119273 => \true, 119274 => \true, 119275 => \true, 119276 => \true, 119277 => \true, 119278 => \true, 119279 => \true, 119280 => \true, 119281 => \true, 119282 => \true, 119283 => \true, 119284 => \true, 119285 => \true, 119286 => \true, 119287 => \true, 119288 => \true, 119289 => \true, 119290 => \true, 119291 => \true, 119292 => \true, 119293 => \true, 119294 => \true, 119295 => \true, 119540 => \true, 119541 => \true, 119542 => \true, 119543 => \true, 119544 => \true, 119545 => \true, 119546 => \true, 119547 => \true, 119548 => \true, 119549 => \true, 119550 => \true, 119551 => \true, 119639 => \true, 119640 => \true, 119641 => \true, 119642 => \true, 119643 => \true, 119644 => \true, 119645 => \true, 119646 => \true, 119647 => \true, 119893 => \true, 119965 => \true, 119968 => \true, 119969 => \true, 119971 => \true, 119972 => \true, 119975 => \true, 119976 => \true, 119981 => \true, 119994 => \true, 119996 => \true, 120004 => \true, 120070 => \true, 120075 => \true, 120076 => \true, 120085 => \true, 120093 => \true, 120122 => \true, 120127 => \true, 120133 => \true, 120135 => \true, 120136 => \true, 120137 => \true, 120145 => \true, 120486 => \true, 120487 => \true, 120780 => \true, 120781 => \true, 121484 => \true, 121485 => \true, 121486 => \true, 121487 => \true, 121488 => \true, 121489 => \true, 121490 => \true, 121491 => \true, 121492 => \true, 121493 => \true, 121494 => \true, 121495 => \true, 121496 => \true, 121497 => \true, 121498 => \true, 121504 => \true, 122887 => \true, 122905 => \true, 122906 => \true, 122914 => \true, 122917 => \true, 123181 => \true, 123182 => \true, 123183 => \true, 123198 => \true, 123199 => \true, 123210 => \true, 123211 => \true, 123212 => \true, 123213 => \true, 123642 => \true, 123643 => \true, 123644 => \true, 123645 => \true, 123646 => \true, 125125 => \true, 125126 => \true, 125260 => \true, 125261 => \true, 125262 => \true, 125263 => \true, 125274 => \true, 125275 => \true, 125276 => \true, 125277 => \true, 126468 => \true, 126496 => \true, 126499 => \true, 126501 => \true, 126502 => \true, 126504 => \true, 126515 => \true, 126520 => \true, 126522 => \true, 126524 => \true, 126525 => \true, 126526 => \true, 126527 => \true, 126528 => \true, 126529 => \true, 126531 => \true, 126532 => \true, 126533 => \true, 126534 => \true, 126536 => \true, 126538 => \true, 126540 => \true, 126544 => \true, 126547 => \true, 126549 => \true, 126550 => \true, 126552 => \true, 126554 => \true, 126556 => \true, 126558 => \true, 126560 => \true, 126563 => \true, 126565 => \true, 126566 => \true, 126571 => \true, 126579 => \true, 126584 => \true, 126589 => \true, 126591 => \true, 126602 => \true, 126620 => \true, 126621 => \true, 126622 => \true, 126623 => \true, 126624 => \true, 126628 => \true, 126634 => \true, 127020 => \true, 127021 => \true, 127022 => \true, 127023 => \true, 127124 => \true, 127125 => \true, 127126 => \true, 127127 => \true, 127128 => \true, 127129 => \true, 127130 => \true, 127131 => \true, 127132 => \true, 127133 => \true, 127134 => \true, 127135 => \true, 127151 => \true, 127152 => \true, 127168 => \true, 127184 => \true, 127222 => \true, 127223 => \true, 127224 => \true, 127225 => \true, 127226 => \true, 127227 => \true, 127228 => \true, 127229 => \true, 127230 => \true, 127231 => \true, 127232 => \true, 127491 => \true, 127492 => \true, 127493 => \true, 127494 => \true, 127495 => \true, 127496 => \true, 127497 => \true, 127498 => \true, 127499 => \true, 127500 => \true, 127501 => \true, 127502 => \true, 127503 => \true, 127548 => \true, 127549 => \true, 127550 => \true, 127551 => \true, 127561 => \true, 127562 => \true, 127563 => \true, 127564 => \true, 127565 => \true, 127566 => \true, 127567 => \true, 127570 => \true, 127571 => \true, 127572 => \true, 127573 => \true, 127574 => \true, 127575 => \true, 127576 => \true, 127577 => \true, 127578 => \true, 127579 => \true, 127580 => \true, 127581 => \true, 127582 => \true, 127583 => \true, 128728 => \true, 128729 => \true, 128730 => \true, 128731 => \true, 128732 => \true, 128733 => \true, 128734 => \true, 128735 => \true, 128749 => \true, 128750 => \true, 128751 => \true, 128765 => \true, 128766 => \true, 128767 => \true, 128884 => \true, 128885 => \true, 128886 => \true, 128887 => \true, 128888 => \true, 128889 => \true, 128890 => \true, 128891 => \true, 128892 => \true, 128893 => \true, 128894 => \true, 128895 => \true, 128985 => \true, 128986 => \true, 128987 => \true, 128988 => \true, 128989 => \true, 128990 => \true, 128991 => \true, 129004 => \true, 129005 => \true, 129006 => \true, 129007 => \true, 129008 => \true, 129009 => \true, 129010 => \true, 129011 => \true, 129012 => \true, 129013 => \true, 129014 => \true, 129015 => \true, 129016 => \true, 129017 => \true, 129018 => \true, 129019 => \true, 129020 => \true, 129021 => \true, 129022 => \true, 129023 => \true, 129036 => \true, 129037 => \true, 129038 => \true, 129039 => \true, 129096 => \true, 129097 => \true, 129098 => \true, 129099 => \true, 129100 => \true, 129101 => \true, 129102 => \true, 129103 => \true, 129114 => \true, 129115 => \true, 129116 => \true, 129117 => \true, 129118 => \true, 129119 => \true, 129160 => \true, 129161 => \true, 129162 => \true, 129163 => \true, 129164 => \true, 129165 => \true, 129166 => \true, 129167 => \true, 129198 => \true, 129199 => \true, 129401 => \true, 129484 => \true, 129620 => \true, 129621 => \true, 129622 => \true, 129623 => \true, 129624 => \true, 129625 => \true, 129626 => \true, 129627 => \true, 129628 => \true, 129629 => \true, 129630 => \true, 129631 => \true, 129646 => \true, 129647 => \true, 129653 => \true, 129654 => \true, 129655 => \true, 129659 => \true, 129660 => \true, 129661 => \true, 129662 => \true, 129663 => \true, 129671 => \true, 129672 => \true, 129673 => \true, 129674 => \true, 129675 => \true, 129676 => \true, 129677 => \true, 129678 => \true, 129679 => \true, 129705 => \true, 129706 => \true, 129707 => \true, 129708 => \true, 129709 => \true, 129710 => \true, 129711 => \true, 129719 => \true, 129720 => \true, 129721 => \true, 129722 => \true, 129723 => \true, 129724 => \true, 129725 => \true, 129726 => \true, 129727 => \true, 129731 => \true, 129732 => \true, 129733 => \true, 129734 => \true, 129735 => \true, 129736 => \true, 129737 => \true, 129738 => \true, 129739 => \true, 129740 => \true, 129741 => \true, 129742 => \true, 129743 => \true, 129939 => \true, 131070 => \true, 131071 => \true, 177973 => \true, 177974 => \true, 177975 => \true, 177976 => \true, 177977 => \true, 177978 => \true, 177979 => \true, 177980 => \true, 177981 => \true, 177982 => \true, 177983 => \true, 178206 => \true, 178207 => \true, 183970 => \true, 183971 => \true, 183972 => \true, 183973 => \true, 183974 => \true, 183975 => \true, 183976 => \true, 183977 => \true, 183978 => \true, 183979 => \true, 183980 => \true, 183981 => \true, 183982 => \true, 183983 => \true, 194664 => \true, 194676 => \true, 194847 => \true, 194911 => \true, 195007 => \true, 196606 => \true, 196607 => \true, 262142 => \true, 262143 => \true, 327678 => \true, 327679 => \true, 393214 => \true, 393215 => \true, 458750 => \true, 458751 => \true, 524286 => \true, 524287 => \true, 589822 => \true, 589823 => \true, 655358 => \true, 655359 => \true, 720894 => \true, 720895 => \true, 786430 => \true, 786431 => \true, 851966 => \true, 851967 => \true, 917502 => \true, 917503 => \true, 917504 => \true, 917505 => \true, 917506 => \true, 917507 => \true, 917508 => \true, 917509 => \true, 917510 => \true, 917511 => \true, 917512 => \true, 917513 => \true, 917514 => \true, 917515 => \true, 917516 => \true, 917517 => \true, 917518 => \true, 917519 => \true, 917520 => \true, 917521 => \true, 917522 => \true, 917523 => \true, 917524 => \true, 917525 => \true, 917526 => \true, 917527 => \true, 917528 => \true, 917529 => \true, 917530 => \true, 917531 => \true, 917532 => \true, 917533 => \true, 917534 => \true, 917535 => \true, 983038 => \true, 983039 => \true, 1048574 => \true, 1048575 => \true, 1114110 => \true, 1114111 => \true); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php new file mode 100644 index 0000000..1584aa5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php @@ -0,0 +1,5 @@ + ' ', 168 => ' ̈', 175 => ' Ì„', 180 => ' Ì', 184 => ' ̧', 728 => ' ̆', 729 => ' ̇', 730 => ' ÌŠ', 731 => ' ̨', 732 => ' ̃', 733 => ' Ì‹', 890 => ' ι', 894 => ';', 900 => ' Ì', 901 => ' ̈Ì', 8125 => ' Ì“', 8127 => ' Ì“', 8128 => ' Í‚', 8129 => ' ̈͂', 8141 => ' ̓̀', 8142 => ' Ì“Ì', 8143 => ' ̓͂', 8157 => ' ̔̀', 8158 => ' Ì”Ì', 8159 => ' ̔͂', 8173 => ' ̈̀', 8174 => ' ̈Ì', 8175 => '`', 8189 => ' Ì', 8190 => ' Ì”', 8192 => ' ', 8193 => ' ', 8194 => ' ', 8195 => ' ', 8196 => ' ', 8197 => ' ', 8198 => ' ', 8199 => ' ', 8200 => ' ', 8201 => ' ', 8202 => ' ', 8215 => ' ̳', 8239 => ' ', 8252 => '!!', 8254 => ' Ì…', 8263 => '??', 8264 => '?!', 8265 => '!?', 8287 => ' ', 8314 => '+', 8316 => '=', 8317 => '(', 8318 => ')', 8330 => '+', 8332 => '=', 8333 => '(', 8334 => ')', 8448 => 'a/c', 8449 => 'a/s', 8453 => 'c/o', 8454 => 'c/u', 9332 => '(1)', 9333 => '(2)', 9334 => '(3)', 9335 => '(4)', 9336 => '(5)', 9337 => '(6)', 9338 => '(7)', 9339 => '(8)', 9340 => '(9)', 9341 => '(10)', 9342 => '(11)', 9343 => '(12)', 9344 => '(13)', 9345 => '(14)', 9346 => '(15)', 9347 => '(16)', 9348 => '(17)', 9349 => '(18)', 9350 => '(19)', 9351 => '(20)', 9372 => '(a)', 9373 => '(b)', 9374 => '(c)', 9375 => '(d)', 9376 => '(e)', 9377 => '(f)', 9378 => '(g)', 9379 => '(h)', 9380 => '(i)', 9381 => '(j)', 9382 => '(k)', 9383 => '(l)', 9384 => '(m)', 9385 => '(n)', 9386 => '(o)', 9387 => '(p)', 9388 => '(q)', 9389 => '(r)', 9390 => '(s)', 9391 => '(t)', 9392 => '(u)', 9393 => '(v)', 9394 => '(w)', 9395 => '(x)', 9396 => '(y)', 9397 => '(z)', 10868 => '::=', 10869 => '==', 10870 => '===', 12288 => ' ', 12443 => ' ã‚™', 12444 => ' ゚', 12800 => '(á„€)', 12801 => '(á„‚)', 12802 => '(ᄃ)', 12803 => '(á„…)', 12804 => '(ᄆ)', 12805 => '(ᄇ)', 12806 => '(ᄉ)', 12807 => '(á„‹)', 12808 => '(ᄌ)', 12809 => '(ᄎ)', 12810 => '(á„)', 12811 => '(á„)', 12812 => '(á„‘)', 12813 => '(á„’)', 12814 => '(ê°€)', 12815 => '(나)', 12816 => '(다)', 12817 => '(ë¼)', 12818 => '(마)', 12819 => '(ë°”)', 12820 => '(사)', 12821 => '(ì•„)', 12822 => '(ìž)', 12823 => '(ì°¨)', 12824 => '(ì¹´)', 12825 => '(타)', 12826 => '(파)', 12827 => '(하)', 12828 => '(주)', 12829 => '(오전)', 12830 => '(오후)', 12832 => '(一)', 12833 => '(二)', 12834 => '(三)', 12835 => '(å››)', 12836 => '(五)', 12837 => '(å…­)', 12838 => '(七)', 12839 => '(å…«)', 12840 => '(ä¹)', 12841 => '(å)', 12842 => '(月)', 12843 => '(ç«)', 12844 => '(æ°´)', 12845 => '(木)', 12846 => '(金)', 12847 => '(土)', 12848 => '(æ—¥)', 12849 => '(æ ª)', 12850 => '(有)', 12851 => '(社)', 12852 => '(å)', 12853 => '(特)', 12854 => '(財)', 12855 => '(ç¥)', 12856 => '(労)', 12857 => '(代)', 12858 => '(呼)', 12859 => '(å­¦)', 12860 => '(監)', 12861 => '(ä¼)', 12862 => '(資)', 12863 => '(å”)', 12864 => '(祭)', 12865 => '(休)', 12866 => '(自)', 12867 => '(至)', 64297 => '+', 64606 => ' ٌّ', 64607 => ' ÙÙ‘', 64608 => ' ÙŽÙ‘', 64609 => ' ÙÙ‘', 64610 => ' ÙÙ‘', 64611 => ' ّٰ', 65018 => 'صلى الله عليه وسلم', 65019 => 'جل جلاله', 65040 => ',', 65043 => ':', 65044 => ';', 65045 => '!', 65046 => '?', 65075 => '_', 65076 => '_', 65077 => '(', 65078 => ')', 65079 => '{', 65080 => '}', 65095 => '[', 65096 => ']', 65097 => ' Ì…', 65098 => ' Ì…', 65099 => ' Ì…', 65100 => ' Ì…', 65101 => '_', 65102 => '_', 65103 => '_', 65104 => ',', 65108 => ';', 65109 => ':', 65110 => '?', 65111 => '!', 65113 => '(', 65114 => ')', 65115 => '{', 65116 => '}', 65119 => '#', 65120 => '&', 65121 => '*', 65122 => '+', 65124 => '<', 65125 => '>', 65126 => '=', 65128 => '\\', 65129 => '$', 65130 => '%', 65131 => '@', 65136 => ' Ù‹', 65138 => ' ÙŒ', 65140 => ' Ù', 65142 => ' ÙŽ', 65144 => ' Ù', 65146 => ' Ù', 65148 => ' Ù‘', 65150 => ' Ù’', 65281 => '!', 65282 => '"', 65283 => '#', 65284 => '$', 65285 => '%', 65286 => '&', 65287 => '\'', 65288 => '(', 65289 => ')', 65290 => '*', 65291 => '+', 65292 => ',', 65295 => '/', 65306 => ':', 65307 => ';', 65308 => '<', 65309 => '=', 65310 => '>', 65311 => '?', 65312 => '@', 65339 => '[', 65340 => '\\', 65341 => ']', 65342 => '^', 65343 => '_', 65344 => '`', 65371 => '{', 65372 => '|', 65373 => '}', 65374 => '~', 65507 => ' Ì„', 127233 => '0,', 127234 => '1,', 127235 => '2,', 127236 => '3,', 127237 => '4,', 127238 => '5,', 127239 => '6,', 127240 => '7,', 127241 => '8,', 127242 => '9,', 127248 => '(a)', 127249 => '(b)', 127250 => '(c)', 127251 => '(d)', 127252 => '(e)', 127253 => '(f)', 127254 => '(g)', 127255 => '(h)', 127256 => '(i)', 127257 => '(j)', 127258 => '(k)', 127259 => '(l)', 127260 => '(m)', 127261 => '(n)', 127262 => '(o)', 127263 => '(p)', 127264 => '(q)', 127265 => '(r)', 127266 => '(s)', 127267 => '(t)', 127268 => '(u)', 127269 => '(v)', 127270 => '(w)', 127271 => '(x)', 127272 => '(y)', 127273 => '(z)'); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php new file mode 100644 index 0000000..a40e36a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php @@ -0,0 +1,5 @@ + \true, 1 => \true, 2 => \true, 3 => \true, 4 => \true, 5 => \true, 6 => \true, 7 => \true, 8 => \true, 9 => \true, 10 => \true, 11 => \true, 12 => \true, 13 => \true, 14 => \true, 15 => \true, 16 => \true, 17 => \true, 18 => \true, 19 => \true, 20 => \true, 21 => \true, 22 => \true, 23 => \true, 24 => \true, 25 => \true, 26 => \true, 27 => \true, 28 => \true, 29 => \true, 30 => \true, 31 => \true, 32 => \true, 33 => \true, 34 => \true, 35 => \true, 36 => \true, 37 => \true, 38 => \true, 39 => \true, 40 => \true, 41 => \true, 42 => \true, 43 => \true, 44 => \true, 47 => \true, 58 => \true, 59 => \true, 60 => \true, 61 => \true, 62 => \true, 63 => \true, 64 => \true, 91 => \true, 92 => \true, 93 => \true, 94 => \true, 95 => \true, 96 => \true, 123 => \true, 124 => \true, 125 => \true, 126 => \true, 127 => \true, 8800 => \true, 8814 => \true, 8815 => \true); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/ignored.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/ignored.php new file mode 100644 index 0000000..7259c4f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/ignored.php @@ -0,0 +1,5 @@ + \true, 847 => \true, 6155 => \true, 6156 => \true, 6157 => \true, 8203 => \true, 8288 => \true, 8292 => \true, 65024 => \true, 65025 => \true, 65026 => \true, 65027 => \true, 65028 => \true, 65029 => \true, 65030 => \true, 65031 => \true, 65032 => \true, 65033 => \true, 65034 => \true, 65035 => \true, 65036 => \true, 65037 => \true, 65038 => \true, 65039 => \true, 65279 => \true, 113824 => \true, 113825 => \true, 113826 => \true, 113827 => \true, 917760 => \true, 917761 => \true, 917762 => \true, 917763 => \true, 917764 => \true, 917765 => \true, 917766 => \true, 917767 => \true, 917768 => \true, 917769 => \true, 917770 => \true, 917771 => \true, 917772 => \true, 917773 => \true, 917774 => \true, 917775 => \true, 917776 => \true, 917777 => \true, 917778 => \true, 917779 => \true, 917780 => \true, 917781 => \true, 917782 => \true, 917783 => \true, 917784 => \true, 917785 => \true, 917786 => \true, 917787 => \true, 917788 => \true, 917789 => \true, 917790 => \true, 917791 => \true, 917792 => \true, 917793 => \true, 917794 => \true, 917795 => \true, 917796 => \true, 917797 => \true, 917798 => \true, 917799 => \true, 917800 => \true, 917801 => \true, 917802 => \true, 917803 => \true, 917804 => \true, 917805 => \true, 917806 => \true, 917807 => \true, 917808 => \true, 917809 => \true, 917810 => \true, 917811 => \true, 917812 => \true, 917813 => \true, 917814 => \true, 917815 => \true, 917816 => \true, 917817 => \true, 917818 => \true, 917819 => \true, 917820 => \true, 917821 => \true, 917822 => \true, 917823 => \true, 917824 => \true, 917825 => \true, 917826 => \true, 917827 => \true, 917828 => \true, 917829 => \true, 917830 => \true, 917831 => \true, 917832 => \true, 917833 => \true, 917834 => \true, 917835 => \true, 917836 => \true, 917837 => \true, 917838 => \true, 917839 => \true, 917840 => \true, 917841 => \true, 917842 => \true, 917843 => \true, 917844 => \true, 917845 => \true, 917846 => \true, 917847 => \true, 917848 => \true, 917849 => \true, 917850 => \true, 917851 => \true, 917852 => \true, 917853 => \true, 917854 => \true, 917855 => \true, 917856 => \true, 917857 => \true, 917858 => \true, 917859 => \true, 917860 => \true, 917861 => \true, 917862 => \true, 917863 => \true, 917864 => \true, 917865 => \true, 917866 => \true, 917867 => \true, 917868 => \true, 917869 => \true, 917870 => \true, 917871 => \true, 917872 => \true, 917873 => \true, 917874 => \true, 917875 => \true, 917876 => \true, 917877 => \true, 917878 => \true, 917879 => \true, 917880 => \true, 917881 => \true, 917882 => \true, 917883 => \true, 917884 => \true, 917885 => \true, 917886 => \true, 917887 => \true, 917888 => \true, 917889 => \true, 917890 => \true, 917891 => \true, 917892 => \true, 917893 => \true, 917894 => \true, 917895 => \true, 917896 => \true, 917897 => \true, 917898 => \true, 917899 => \true, 917900 => \true, 917901 => \true, 917902 => \true, 917903 => \true, 917904 => \true, 917905 => \true, 917906 => \true, 917907 => \true, 917908 => \true, 917909 => \true, 917910 => \true, 917911 => \true, 917912 => \true, 917913 => \true, 917914 => \true, 917915 => \true, 917916 => \true, 917917 => \true, 917918 => \true, 917919 => \true, 917920 => \true, 917921 => \true, 917922 => \true, 917923 => \true, 917924 => \true, 917925 => \true, 917926 => \true, 917927 => \true, 917928 => \true, 917929 => \true, 917930 => \true, 917931 => \true, 917932 => \true, 917933 => \true, 917934 => \true, 917935 => \true, 917936 => \true, 917937 => \true, 917938 => \true, 917939 => \true, 917940 => \true, 917941 => \true, 917942 => \true, 917943 => \true, 917944 => \true, 917945 => \true, 917946 => \true, 917947 => \true, 917948 => \true, 917949 => \true, 917950 => \true, 917951 => \true, 917952 => \true, 917953 => \true, 917954 => \true, 917955 => \true, 917956 => \true, 917957 => \true, 917958 => \true, 917959 => \true, 917960 => \true, 917961 => \true, 917962 => \true, 917963 => \true, 917964 => \true, 917965 => \true, 917966 => \true, 917967 => \true, 917968 => \true, 917969 => \true, 917970 => \true, 917971 => \true, 917972 => \true, 917973 => \true, 917974 => \true, 917975 => \true, 917976 => \true, 917977 => \true, 917978 => \true, 917979 => \true, 917980 => \true, 917981 => \true, 917982 => \true, 917983 => \true, 917984 => \true, 917985 => \true, 917986 => \true, 917987 => \true, 917988 => \true, 917989 => \true, 917990 => \true, 917991 => \true, 917992 => \true, 917993 => \true, 917994 => \true, 917995 => \true, 917996 => \true, 917997 => \true, 917998 => \true, 917999 => \true); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/mapped.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/mapped.php new file mode 100644 index 0000000..e87e92a --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/mapped.php @@ -0,0 +1,5 @@ + 'a', 66 => 'b', 67 => 'c', 68 => 'd', 69 => 'e', 70 => 'f', 71 => 'g', 72 => 'h', 73 => 'i', 74 => 'j', 75 => 'k', 76 => 'l', 77 => 'm', 78 => 'n', 79 => 'o', 80 => 'p', 81 => 'q', 82 => 'r', 83 => 's', 84 => 't', 85 => 'u', 86 => 'v', 87 => 'w', 88 => 'x', 89 => 'y', 90 => 'z', 170 => 'a', 178 => '2', 179 => '3', 181 => 'μ', 185 => '1', 186 => 'o', 188 => '1â„4', 189 => '1â„2', 190 => '3â„4', 192 => 'à', 193 => 'á', 194 => 'â', 195 => 'ã', 196 => 'ä', 197 => 'Ã¥', 198 => 'æ', 199 => 'ç', 200 => 'è', 201 => 'é', 202 => 'ê', 203 => 'ë', 204 => 'ì', 205 => 'í', 206 => 'î', 207 => 'ï', 208 => 'ð', 209 => 'ñ', 210 => 'ò', 211 => 'ó', 212 => 'ô', 213 => 'õ', 214 => 'ö', 216 => 'ø', 217 => 'ù', 218 => 'ú', 219 => 'û', 220 => 'ü', 221 => 'ý', 222 => 'þ', 256 => 'Ä', 258 => 'ă', 260 => 'Ä…', 262 => 'ć', 264 => 'ĉ', 266 => 'Ä‹', 268 => 'Ä', 270 => 'Ä', 272 => 'Ä‘', 274 => 'Ä“', 276 => 'Ä•', 278 => 'Ä—', 280 => 'Ä™', 282 => 'Ä›', 284 => 'Ä', 286 => 'ÄŸ', 288 => 'Ä¡', 290 => 'Ä£', 292 => 'Ä¥', 294 => 'ħ', 296 => 'Ä©', 298 => 'Ä«', 300 => 'Ä­', 302 => 'į', 304 => 'i̇', 306 => 'ij', 307 => 'ij', 308 => 'ĵ', 310 => 'Ä·', 313 => 'ĺ', 315 => 'ļ', 317 => 'ľ', 319 => 'l·', 320 => 'l·', 321 => 'Å‚', 323 => 'Å„', 325 => 'ņ', 327 => 'ň', 329 => 'ʼn', 330 => 'Å‹', 332 => 'Å', 334 => 'Å', 336 => 'Å‘', 338 => 'Å“', 340 => 'Å•', 342 => 'Å—', 344 => 'Å™', 346 => 'Å›', 348 => 'Å', 350 => 'ÅŸ', 352 => 'Å¡', 354 => 'Å£', 356 => 'Å¥', 358 => 'ŧ', 360 => 'Å©', 362 => 'Å«', 364 => 'Å­', 366 => 'ů', 368 => 'ű', 370 => 'ų', 372 => 'ŵ', 374 => 'Å·', 376 => 'ÿ', 377 => 'ź', 379 => 'ż', 381 => 'ž', 383 => 's', 385 => 'É“', 386 => 'ƃ', 388 => 'Æ…', 390 => 'É”', 391 => 'ƈ', 393 => 'É–', 394 => 'É—', 395 => 'ÆŒ', 398 => 'Ç', 399 => 'É™', 400 => 'É›', 401 => 'Æ’', 403 => 'É ', 404 => 'É£', 406 => 'É©', 407 => 'ɨ', 408 => 'Æ™', 412 => 'ɯ', 413 => 'ɲ', 415 => 'ɵ', 416 => 'Æ¡', 418 => 'Æ£', 420 => 'Æ¥', 422 => 'Ê€', 423 => 'ƨ', 425 => 'ʃ', 428 => 'Æ­', 430 => 'ʈ', 431 => 'ư', 433 => 'ÊŠ', 434 => 'Ê‹', 435 => 'Æ´', 437 => 'ƶ', 439 => 'Ê’', 440 => 'ƹ', 444 => 'ƽ', 452 => 'dž', 453 => 'dž', 454 => 'dž', 455 => 'lj', 456 => 'lj', 457 => 'lj', 458 => 'nj', 459 => 'nj', 460 => 'nj', 461 => 'ÇŽ', 463 => 'Ç', 465 => 'Ç’', 467 => 'Ç”', 469 => 'Ç–', 471 => 'ǘ', 473 => 'Çš', 475 => 'Çœ', 478 => 'ÇŸ', 480 => 'Ç¡', 482 => 'Ç£', 484 => 'Ç¥', 486 => 'ǧ', 488 => 'Ç©', 490 => 'Ç«', 492 => 'Ç­', 494 => 'ǯ', 497 => 'dz', 498 => 'dz', 499 => 'dz', 500 => 'ǵ', 502 => 'Æ•', 503 => 'Æ¿', 504 => 'ǹ', 506 => 'Ç»', 508 => 'ǽ', 510 => 'Ç¿', 512 => 'È', 514 => 'ȃ', 516 => 'È…', 518 => 'ȇ', 520 => 'ȉ', 522 => 'È‹', 524 => 'È', 526 => 'È', 528 => 'È‘', 530 => 'È“', 532 => 'È•', 534 => 'È—', 536 => 'È™', 538 => 'È›', 540 => 'È', 542 => 'ÈŸ', 544 => 'Æž', 546 => 'È£', 548 => 'È¥', 550 => 'ȧ', 552 => 'È©', 554 => 'È«', 556 => 'È­', 558 => 'ȯ', 560 => 'ȱ', 562 => 'ȳ', 570 => 'â±¥', 571 => 'ȼ', 573 => 'Æš', 574 => 'ⱦ', 577 => 'É‚', 579 => 'Æ€', 580 => 'ʉ', 581 => 'ÊŒ', 582 => 'ɇ', 584 => 'ɉ', 586 => 'É‹', 588 => 'É', 590 => 'É', 688 => 'h', 689 => 'ɦ', 690 => 'j', 691 => 'r', 692 => 'ɹ', 693 => 'É»', 694 => 'Ê', 695 => 'w', 696 => 'y', 736 => 'É£', 737 => 'l', 738 => 's', 739 => 'x', 740 => 'Ê•', 832 => 'Ì€', 833 => 'Ì', 835 => 'Ì“', 836 => '̈Ì', 837 => 'ι', 880 => 'ͱ', 882 => 'ͳ', 884 => 'ʹ', 886 => 'Í·', 895 => 'ϳ', 902 => 'ά', 903 => '·', 904 => 'έ', 905 => 'ή', 906 => 'ί', 908 => 'ÏŒ', 910 => 'Ï', 911 => 'ÏŽ', 913 => 'α', 914 => 'β', 915 => 'γ', 916 => 'δ', 917 => 'ε', 918 => 'ζ', 919 => 'η', 920 => 'θ', 921 => 'ι', 922 => 'κ', 923 => 'λ', 924 => 'μ', 925 => 'ν', 926 => 'ξ', 927 => 'ο', 928 => 'Ï€', 929 => 'Ï', 931 => 'σ', 932 => 'Ï„', 933 => 'Ï…', 934 => 'φ', 935 => 'χ', 936 => 'ψ', 937 => 'ω', 938 => 'ÏŠ', 939 => 'Ï‹', 975 => 'Ï—', 976 => 'β', 977 => 'θ', 978 => 'Ï…', 979 => 'Ï', 980 => 'Ï‹', 981 => 'φ', 982 => 'Ï€', 984 => 'Ï™', 986 => 'Ï›', 988 => 'Ï', 990 => 'ÏŸ', 992 => 'Ï¡', 994 => 'Ï£', 996 => 'Ï¥', 998 => 'ϧ', 1000 => 'Ï©', 1002 => 'Ï«', 1004 => 'Ï­', 1006 => 'ϯ', 1008 => 'κ', 1009 => 'Ï', 1010 => 'σ', 1012 => 'θ', 1013 => 'ε', 1015 => 'ϸ', 1017 => 'σ', 1018 => 'Ï»', 1021 => 'Í»', 1022 => 'ͼ', 1023 => 'ͽ', 1024 => 'Ñ', 1025 => 'Ñ‘', 1026 => 'Ñ’', 1027 => 'Ñ“', 1028 => 'Ñ”', 1029 => 'Ñ•', 1030 => 'Ñ–', 1031 => 'Ñ—', 1032 => 'ј', 1033 => 'Ñ™', 1034 => 'Ñš', 1035 => 'Ñ›', 1036 => 'Ñœ', 1037 => 'Ñ', 1038 => 'Ñž', 1039 => 'ÑŸ', 1040 => 'а', 1041 => 'б', 1042 => 'в', 1043 => 'г', 1044 => 'д', 1045 => 'е', 1046 => 'ж', 1047 => 'з', 1048 => 'и', 1049 => 'й', 1050 => 'к', 1051 => 'л', 1052 => 'м', 1053 => 'н', 1054 => 'о', 1055 => 'п', 1056 => 'Ñ€', 1057 => 'Ñ', 1058 => 'Ñ‚', 1059 => 'у', 1060 => 'Ñ„', 1061 => 'Ñ…', 1062 => 'ц', 1063 => 'ч', 1064 => 'ш', 1065 => 'щ', 1066 => 'ÑŠ', 1067 => 'Ñ‹', 1068 => 'ÑŒ', 1069 => 'Ñ', 1070 => 'ÑŽ', 1071 => 'Ñ', 1120 => 'Ñ¡', 1122 => 'Ñ£', 1124 => 'Ñ¥', 1126 => 'ѧ', 1128 => 'Ñ©', 1130 => 'Ñ«', 1132 => 'Ñ­', 1134 => 'ѯ', 1136 => 'ѱ', 1138 => 'ѳ', 1140 => 'ѵ', 1142 => 'Ñ·', 1144 => 'ѹ', 1146 => 'Ñ»', 1148 => 'ѽ', 1150 => 'Ñ¿', 1152 => 'Ò', 1162 => 'Ò‹', 1164 => 'Ò', 1166 => 'Ò', 1168 => 'Ò‘', 1170 => 'Ò“', 1172 => 'Ò•', 1174 => 'Ò—', 1176 => 'Ò™', 1178 => 'Ò›', 1180 => 'Ò', 1182 => 'ÒŸ', 1184 => 'Ò¡', 1186 => 'Ò£', 1188 => 'Ò¥', 1190 => 'Ò§', 1192 => 'Ò©', 1194 => 'Ò«', 1196 => 'Ò­', 1198 => 'Ò¯', 1200 => 'Ò±', 1202 => 'Ò³', 1204 => 'Òµ', 1206 => 'Ò·', 1208 => 'Ò¹', 1210 => 'Ò»', 1212 => 'Ò½', 1214 => 'Ò¿', 1217 => 'Ó‚', 1219 => 'Ó„', 1221 => 'Ó†', 1223 => 'Óˆ', 1225 => 'ÓŠ', 1227 => 'ÓŒ', 1229 => 'ÓŽ', 1232 => 'Ó‘', 1234 => 'Ó“', 1236 => 'Ó•', 1238 => 'Ó—', 1240 => 'Ó™', 1242 => 'Ó›', 1244 => 'Ó', 1246 => 'ÓŸ', 1248 => 'Ó¡', 1250 => 'Ó£', 1252 => 'Ó¥', 1254 => 'Ó§', 1256 => 'Ó©', 1258 => 'Ó«', 1260 => 'Ó­', 1262 => 'Ó¯', 1264 => 'Ó±', 1266 => 'Ó³', 1268 => 'Óµ', 1270 => 'Ó·', 1272 => 'Ó¹', 1274 => 'Ó»', 1276 => 'Ó½', 1278 => 'Ó¿', 1280 => 'Ô', 1282 => 'Ôƒ', 1284 => 'Ô…', 1286 => 'Ô‡', 1288 => 'Ô‰', 1290 => 'Ô‹', 1292 => 'Ô', 1294 => 'Ô', 1296 => 'Ô‘', 1298 => 'Ô“', 1300 => 'Ô•', 1302 => 'Ô—', 1304 => 'Ô™', 1306 => 'Ô›', 1308 => 'Ô', 1310 => 'ÔŸ', 1312 => 'Ô¡', 1314 => 'Ô£', 1316 => 'Ô¥', 1318 => 'Ô§', 1320 => 'Ô©', 1322 => 'Ô«', 1324 => 'Ô­', 1326 => 'Ô¯', 1329 => 'Õ¡', 1330 => 'Õ¢', 1331 => 'Õ£', 1332 => 'Õ¤', 1333 => 'Õ¥', 1334 => 'Õ¦', 1335 => 'Õ§', 1336 => 'Õ¨', 1337 => 'Õ©', 1338 => 'Õª', 1339 => 'Õ«', 1340 => 'Õ¬', 1341 => 'Õ­', 1342 => 'Õ®', 1343 => 'Õ¯', 1344 => 'Õ°', 1345 => 'Õ±', 1346 => 'Õ²', 1347 => 'Õ³', 1348 => 'Õ´', 1349 => 'Õµ', 1350 => 'Õ¶', 1351 => 'Õ·', 1352 => 'Õ¸', 1353 => 'Õ¹', 1354 => 'Õº', 1355 => 'Õ»', 1356 => 'Õ¼', 1357 => 'Õ½', 1358 => 'Õ¾', 1359 => 'Õ¿', 1360 => 'Ö€', 1361 => 'Ö', 1362 => 'Ö‚', 1363 => 'Öƒ', 1364 => 'Ö„', 1365 => 'Ö…', 1366 => 'Ö†', 1415 => 'Õ¥Ö‚', 1653 => 'اٴ', 1654 => 'وٴ', 1655 => 'Û‡Ù´', 1656 => 'يٴ', 2392 => 'क़', 2393 => 'ख़', 2394 => 'ग़', 2395 => 'ज़', 2396 => 'ड़', 2397 => 'ढ़', 2398 => 'फ़', 2399 => 'य़', 2524 => 'ড়', 2525 => 'ঢ়', 2527 => 'য়', 2611 => 'ਲ਼', 2614 => 'ਸ਼', 2649 => 'ਖ਼', 2650 => 'ਗ਼', 2651 => 'ਜ਼', 2654 => 'ਫ਼', 2908 => 'ଡ଼', 2909 => 'ଢ଼', 3635 => 'à¹à¸²', 3763 => 'à»àº²', 3804 => 'ຫນ', 3805 => 'ຫມ', 3852 => '་', 3907 => 'གྷ', 3917 => 'ཌྷ', 3922 => 'དྷ', 3927 => 'བྷ', 3932 => 'ཛྷ', 3945 => 'ཀྵ', 3955 => 'ཱི', 3957 => 'ཱུ', 3958 => 'ྲྀ', 3959 => 'ྲཱྀ', 3960 => 'ླྀ', 3961 => 'ླཱྀ', 3969 => 'ཱྀ', 3987 => 'ྒྷ', 3997 => 'ྜྷ', 4002 => 'ྡྷ', 4007 => 'ྦྷ', 4012 => 'ྫྷ', 4025 => 'à¾à¾µ', 4295 => 'â´§', 4301 => 'â´­', 4348 => 'ნ', 5112 => 'á°', 5113 => 'á±', 5114 => 'á²', 5115 => 'á³', 5116 => 'á´', 5117 => 'áµ', 7296 => 'в', 7297 => 'д', 7298 => 'о', 7299 => 'Ñ', 7300 => 'Ñ‚', 7301 => 'Ñ‚', 7302 => 'ÑŠ', 7303 => 'Ñ£', 7304 => 'ꙋ', 7312 => 'áƒ', 7313 => 'ბ', 7314 => 'გ', 7315 => 'დ', 7316 => 'ე', 7317 => 'ვ', 7318 => 'ზ', 7319 => 'თ', 7320 => 'ი', 7321 => 'კ', 7322 => 'ლ', 7323 => 'მ', 7324 => 'ნ', 7325 => 'áƒ', 7326 => 'პ', 7327 => 'ჟ', 7328 => 'რ', 7329 => 'ს', 7330 => 'ტ', 7331 => 'უ', 7332 => 'ფ', 7333 => 'ქ', 7334 => 'ღ', 7335 => 'ყ', 7336 => 'შ', 7337 => 'ჩ', 7338 => 'ც', 7339 => 'ძ', 7340 => 'წ', 7341 => 'ჭ', 7342 => 'ხ', 7343 => 'ჯ', 7344 => 'ჰ', 7345 => 'ჱ', 7346 => 'ჲ', 7347 => 'ჳ', 7348 => 'ჴ', 7349 => 'ჵ', 7350 => 'ჶ', 7351 => 'ჷ', 7352 => 'ჸ', 7353 => 'ჹ', 7354 => 'ჺ', 7357 => 'ჽ', 7358 => 'ჾ', 7359 => 'ჿ', 7468 => 'a', 7469 => 'æ', 7470 => 'b', 7472 => 'd', 7473 => 'e', 7474 => 'Ç', 7475 => 'g', 7476 => 'h', 7477 => 'i', 7478 => 'j', 7479 => 'k', 7480 => 'l', 7481 => 'm', 7482 => 'n', 7484 => 'o', 7485 => 'È£', 7486 => 'p', 7487 => 'r', 7488 => 't', 7489 => 'u', 7490 => 'w', 7491 => 'a', 7492 => 'É', 7493 => 'É‘', 7494 => 'á´‚', 7495 => 'b', 7496 => 'd', 7497 => 'e', 7498 => 'É™', 7499 => 'É›', 7500 => 'Éœ', 7501 => 'g', 7503 => 'k', 7504 => 'm', 7505 => 'Å‹', 7506 => 'o', 7507 => 'É”', 7508 => 'á´–', 7509 => 'á´—', 7510 => 'p', 7511 => 't', 7512 => 'u', 7513 => 'á´', 7514 => 'ɯ', 7515 => 'v', 7516 => 'á´¥', 7517 => 'β', 7518 => 'γ', 7519 => 'δ', 7520 => 'φ', 7521 => 'χ', 7522 => 'i', 7523 => 'r', 7524 => 'u', 7525 => 'v', 7526 => 'β', 7527 => 'γ', 7528 => 'Ï', 7529 => 'φ', 7530 => 'χ', 7544 => 'н', 7579 => 'É’', 7580 => 'c', 7581 => 'É•', 7582 => 'ð', 7583 => 'Éœ', 7584 => 'f', 7585 => 'ÉŸ', 7586 => 'É¡', 7587 => 'É¥', 7588 => 'ɨ', 7589 => 'É©', 7590 => 'ɪ', 7591 => 'áµ»', 7592 => 'Ê', 7593 => 'É­', 7594 => 'á¶…', 7595 => 'ÊŸ', 7596 => 'ɱ', 7597 => 'ɰ', 7598 => 'ɲ', 7599 => 'ɳ', 7600 => 'É´', 7601 => 'ɵ', 7602 => 'ɸ', 7603 => 'Ê‚', 7604 => 'ʃ', 7605 => 'Æ«', 7606 => 'ʉ', 7607 => 'ÊŠ', 7608 => 'á´œ', 7609 => 'Ê‹', 7610 => 'ÊŒ', 7611 => 'z', 7612 => 'Ê', 7613 => 'Ê‘', 7614 => 'Ê’', 7615 => 'θ', 7680 => 'á¸', 7682 => 'ḃ', 7684 => 'ḅ', 7686 => 'ḇ', 7688 => 'ḉ', 7690 => 'ḋ', 7692 => 'á¸', 7694 => 'á¸', 7696 => 'ḑ', 7698 => 'ḓ', 7700 => 'ḕ', 7702 => 'ḗ', 7704 => 'ḙ', 7706 => 'ḛ', 7708 => 'á¸', 7710 => 'ḟ', 7712 => 'ḡ', 7714 => 'ḣ', 7716 => 'ḥ', 7718 => 'ḧ', 7720 => 'ḩ', 7722 => 'ḫ', 7724 => 'ḭ', 7726 => 'ḯ', 7728 => 'ḱ', 7730 => 'ḳ', 7732 => 'ḵ', 7734 => 'ḷ', 7736 => 'ḹ', 7738 => 'ḻ', 7740 => 'ḽ', 7742 => 'ḿ', 7744 => 'á¹', 7746 => 'ṃ', 7748 => 'á¹…', 7750 => 'ṇ', 7752 => 'ṉ', 7754 => 'ṋ', 7756 => 'á¹', 7758 => 'á¹', 7760 => 'ṑ', 7762 => 'ṓ', 7764 => 'ṕ', 7766 => 'á¹—', 7768 => 'á¹™', 7770 => 'á¹›', 7772 => 'á¹', 7774 => 'ṟ', 7776 => 'ṡ', 7778 => 'á¹£', 7780 => 'á¹¥', 7782 => 'á¹§', 7784 => 'ṩ', 7786 => 'ṫ', 7788 => 'á¹­', 7790 => 'ṯ', 7792 => 'á¹±', 7794 => 'á¹³', 7796 => 'á¹µ', 7798 => 'á¹·', 7800 => 'á¹¹', 7802 => 'á¹»', 7804 => 'á¹½', 7806 => 'ṿ', 7808 => 'áº', 7810 => 'ẃ', 7812 => 'ẅ', 7814 => 'ẇ', 7816 => 'ẉ', 7818 => 'ẋ', 7820 => 'áº', 7822 => 'áº', 7824 => 'ẑ', 7826 => 'ẓ', 7828 => 'ẕ', 7834 => 'aʾ', 7835 => 'ṡ', 7838 => 'ss', 7840 => 'ạ', 7842 => 'ả', 7844 => 'ấ', 7846 => 'ầ', 7848 => 'ẩ', 7850 => 'ẫ', 7852 => 'ậ', 7854 => 'ắ', 7856 => 'ằ', 7858 => 'ẳ', 7860 => 'ẵ', 7862 => 'ặ', 7864 => 'ẹ', 7866 => 'ẻ', 7868 => 'ẽ', 7870 => 'ế', 7872 => 'á»', 7874 => 'ể', 7876 => 'á»…', 7878 => 'ệ', 7880 => 'ỉ', 7882 => 'ị', 7884 => 'á»', 7886 => 'á»', 7888 => 'ố', 7890 => 'ồ', 7892 => 'ổ', 7894 => 'á»—', 7896 => 'á»™', 7898 => 'á»›', 7900 => 'á»', 7902 => 'ở', 7904 => 'ỡ', 7906 => 'ợ', 7908 => 'ụ', 7910 => 'á»§', 7912 => 'ứ', 7914 => 'ừ', 7916 => 'á»­', 7918 => 'ữ', 7920 => 'á»±', 7922 => 'ỳ', 7924 => 'ỵ', 7926 => 'á»·', 7928 => 'ỹ', 7930 => 'á»»', 7932 => 'ỽ', 7934 => 'ỿ', 7944 => 'á¼€', 7945 => 'á¼', 7946 => 'ἂ', 7947 => 'ἃ', 7948 => 'ἄ', 7949 => 'á¼…', 7950 => 'ἆ', 7951 => 'ἇ', 7960 => 'á¼', 7961 => 'ἑ', 7962 => 'á¼’', 7963 => 'ἓ', 7964 => 'á¼”', 7965 => 'ἕ', 7976 => 'á¼ ', 7977 => 'ἡ', 7978 => 'á¼¢', 7979 => 'á¼£', 7980 => 'ἤ', 7981 => 'á¼¥', 7982 => 'ἦ', 7983 => 'á¼§', 7992 => 'á¼°', 7993 => 'á¼±', 7994 => 'á¼²', 7995 => 'á¼³', 7996 => 'á¼´', 7997 => 'á¼µ', 7998 => 'á¼¶', 7999 => 'á¼·', 8008 => 'á½€', 8009 => 'á½', 8010 => 'ὂ', 8011 => 'ὃ', 8012 => 'ὄ', 8013 => 'á½…', 8025 => 'ὑ', 8027 => 'ὓ', 8029 => 'ὕ', 8031 => 'á½—', 8040 => 'á½ ', 8041 => 'ὡ', 8042 => 'á½¢', 8043 => 'á½£', 8044 => 'ὤ', 8045 => 'á½¥', 8046 => 'ὦ', 8047 => 'á½§', 8049 => 'ά', 8051 => 'έ', 8053 => 'ή', 8055 => 'ί', 8057 => 'ÏŒ', 8059 => 'Ï', 8061 => 'ÏŽ', 8064 => 'ἀι', 8065 => 'á¼Î¹', 8066 => 'ἂι', 8067 => 'ἃι', 8068 => 'ἄι', 8069 => 'ἅι', 8070 => 'ἆι', 8071 => 'ἇι', 8072 => 'ἀι', 8073 => 'á¼Î¹', 8074 => 'ἂι', 8075 => 'ἃι', 8076 => 'ἄι', 8077 => 'ἅι', 8078 => 'ἆι', 8079 => 'ἇι', 8080 => 'ἠι', 8081 => 'ἡι', 8082 => 'ἢι', 8083 => 'ἣι', 8084 => 'ἤι', 8085 => 'ἥι', 8086 => 'ἦι', 8087 => 'ἧι', 8088 => 'ἠι', 8089 => 'ἡι', 8090 => 'ἢι', 8091 => 'ἣι', 8092 => 'ἤι', 8093 => 'ἥι', 8094 => 'ἦι', 8095 => 'ἧι', 8096 => 'ὠι', 8097 => 'ὡι', 8098 => 'ὢι', 8099 => 'ὣι', 8100 => 'ὤι', 8101 => 'ὥι', 8102 => 'ὦι', 8103 => 'ὧι', 8104 => 'ὠι', 8105 => 'ὡι', 8106 => 'ὢι', 8107 => 'ὣι', 8108 => 'ὤι', 8109 => 'ὥι', 8110 => 'ὦι', 8111 => 'ὧι', 8114 => 'ὰι', 8115 => 'αι', 8116 => 'άι', 8119 => 'ᾶι', 8120 => 'á¾°', 8121 => 'á¾±', 8122 => 'á½°', 8123 => 'ά', 8124 => 'αι', 8126 => 'ι', 8130 => 'ὴι', 8131 => 'ηι', 8132 => 'ήι', 8135 => 'ῆι', 8136 => 'á½²', 8137 => 'έ', 8138 => 'á½´', 8139 => 'ή', 8140 => 'ηι', 8147 => 'Î', 8152 => 'á¿', 8153 => 'á¿‘', 8154 => 'á½¶', 8155 => 'ί', 8163 => 'ΰ', 8168 => 'á¿ ', 8169 => 'á¿¡', 8170 => 'ὺ', 8171 => 'Ï', 8172 => 'á¿¥', 8178 => 'ὼι', 8179 => 'ωι', 8180 => 'ώι', 8183 => 'ῶι', 8184 => 'ὸ', 8185 => 'ÏŒ', 8186 => 'á½¼', 8187 => 'ÏŽ', 8188 => 'ωι', 8209 => 'â€', 8243 => '′′', 8244 => '′′′', 8246 => '‵‵', 8247 => '‵‵‵', 8279 => '′′′′', 8304 => '0', 8305 => 'i', 8308 => '4', 8309 => '5', 8310 => '6', 8311 => '7', 8312 => '8', 8313 => '9', 8315 => '−', 8319 => 'n', 8320 => '0', 8321 => '1', 8322 => '2', 8323 => '3', 8324 => '4', 8325 => '5', 8326 => '6', 8327 => '7', 8328 => '8', 8329 => '9', 8331 => '−', 8336 => 'a', 8337 => 'e', 8338 => 'o', 8339 => 'x', 8340 => 'É™', 8341 => 'h', 8342 => 'k', 8343 => 'l', 8344 => 'm', 8345 => 'n', 8346 => 'p', 8347 => 's', 8348 => 't', 8360 => 'rs', 8450 => 'c', 8451 => '°c', 8455 => 'É›', 8457 => '°f', 8458 => 'g', 8459 => 'h', 8460 => 'h', 8461 => 'h', 8462 => 'h', 8463 => 'ħ', 8464 => 'i', 8465 => 'i', 8466 => 'l', 8467 => 'l', 8469 => 'n', 8470 => 'no', 8473 => 'p', 8474 => 'q', 8475 => 'r', 8476 => 'r', 8477 => 'r', 8480 => 'sm', 8481 => 'tel', 8482 => 'tm', 8484 => 'z', 8486 => 'ω', 8488 => 'z', 8490 => 'k', 8491 => 'Ã¥', 8492 => 'b', 8493 => 'c', 8495 => 'e', 8496 => 'e', 8497 => 'f', 8499 => 'm', 8500 => 'o', 8501 => '×', 8502 => 'ב', 8503 => '×’', 8504 => 'ד', 8505 => 'i', 8507 => 'fax', 8508 => 'Ï€', 8509 => 'γ', 8510 => 'γ', 8511 => 'Ï€', 8512 => '∑', 8517 => 'd', 8518 => 'd', 8519 => 'e', 8520 => 'i', 8521 => 'j', 8528 => '1â„7', 8529 => '1â„9', 8530 => '1â„10', 8531 => '1â„3', 8532 => '2â„3', 8533 => '1â„5', 8534 => '2â„5', 8535 => '3â„5', 8536 => '4â„5', 8537 => '1â„6', 8538 => '5â„6', 8539 => '1â„8', 8540 => '3â„8', 8541 => '5â„8', 8542 => '7â„8', 8543 => '1â„', 8544 => 'i', 8545 => 'ii', 8546 => 'iii', 8547 => 'iv', 8548 => 'v', 8549 => 'vi', 8550 => 'vii', 8551 => 'viii', 8552 => 'ix', 8553 => 'x', 8554 => 'xi', 8555 => 'xii', 8556 => 'l', 8557 => 'c', 8558 => 'd', 8559 => 'm', 8560 => 'i', 8561 => 'ii', 8562 => 'iii', 8563 => 'iv', 8564 => 'v', 8565 => 'vi', 8566 => 'vii', 8567 => 'viii', 8568 => 'ix', 8569 => 'x', 8570 => 'xi', 8571 => 'xii', 8572 => 'l', 8573 => 'c', 8574 => 'd', 8575 => 'm', 8585 => '0â„3', 8748 => '∫∫', 8749 => '∫∫∫', 8751 => '∮∮', 8752 => '∮∮∮', 9001 => '〈', 9002 => '〉', 9312 => '1', 9313 => '2', 9314 => '3', 9315 => '4', 9316 => '5', 9317 => '6', 9318 => '7', 9319 => '8', 9320 => '9', 9321 => '10', 9322 => '11', 9323 => '12', 9324 => '13', 9325 => '14', 9326 => '15', 9327 => '16', 9328 => '17', 9329 => '18', 9330 => '19', 9331 => '20', 9398 => 'a', 9399 => 'b', 9400 => 'c', 9401 => 'd', 9402 => 'e', 9403 => 'f', 9404 => 'g', 9405 => 'h', 9406 => 'i', 9407 => 'j', 9408 => 'k', 9409 => 'l', 9410 => 'm', 9411 => 'n', 9412 => 'o', 9413 => 'p', 9414 => 'q', 9415 => 'r', 9416 => 's', 9417 => 't', 9418 => 'u', 9419 => 'v', 9420 => 'w', 9421 => 'x', 9422 => 'y', 9423 => 'z', 9424 => 'a', 9425 => 'b', 9426 => 'c', 9427 => 'd', 9428 => 'e', 9429 => 'f', 9430 => 'g', 9431 => 'h', 9432 => 'i', 9433 => 'j', 9434 => 'k', 9435 => 'l', 9436 => 'm', 9437 => 'n', 9438 => 'o', 9439 => 'p', 9440 => 'q', 9441 => 'r', 9442 => 's', 9443 => 't', 9444 => 'u', 9445 => 'v', 9446 => 'w', 9447 => 'x', 9448 => 'y', 9449 => 'z', 9450 => '0', 10764 => '∫∫∫∫', 10972 => 'â«Ì¸', 11264 => 'â°°', 11265 => 'â°±', 11266 => 'â°²', 11267 => 'â°³', 11268 => 'â°´', 11269 => 'â°µ', 11270 => 'â°¶', 11271 => 'â°·', 11272 => 'â°¸', 11273 => 'â°¹', 11274 => 'â°º', 11275 => 'â°»', 11276 => 'â°¼', 11277 => 'â°½', 11278 => 'â°¾', 11279 => 'â°¿', 11280 => 'â±€', 11281 => 'â±', 11282 => 'ⱂ', 11283 => 'ⱃ', 11284 => 'ⱄ', 11285 => 'â±…', 11286 => 'ⱆ', 11287 => 'ⱇ', 11288 => 'ⱈ', 11289 => 'ⱉ', 11290 => 'ⱊ', 11291 => 'ⱋ', 11292 => 'ⱌ', 11293 => 'â±', 11294 => 'ⱎ', 11295 => 'â±', 11296 => 'â±', 11297 => 'ⱑ', 11298 => 'â±’', 11299 => 'ⱓ', 11300 => 'â±”', 11301 => 'ⱕ', 11302 => 'â±–', 11303 => 'â±—', 11304 => 'ⱘ', 11305 => 'â±™', 11306 => 'ⱚ', 11307 => 'â±›', 11308 => 'ⱜ', 11309 => 'â±', 11310 => 'ⱞ', 11360 => 'ⱡ', 11362 => 'É«', 11363 => 'áµ½', 11364 => 'ɽ', 11367 => 'ⱨ', 11369 => 'ⱪ', 11371 => 'ⱬ', 11373 => 'É‘', 11374 => 'ɱ', 11375 => 'É', 11376 => 'É’', 11378 => 'â±³', 11381 => 'â±¶', 11388 => 'j', 11389 => 'v', 11390 => 'È¿', 11391 => 'É€', 11392 => 'â²', 11394 => 'ⲃ', 11396 => 'â²…', 11398 => 'ⲇ', 11400 => 'ⲉ', 11402 => 'ⲋ', 11404 => 'â²', 11406 => 'â²', 11408 => 'ⲑ', 11410 => 'ⲓ', 11412 => 'ⲕ', 11414 => 'â²—', 11416 => 'â²™', 11418 => 'â²›', 11420 => 'â²', 11422 => 'ⲟ', 11424 => 'ⲡ', 11426 => 'â²£', 11428 => 'â²¥', 11430 => 'â²§', 11432 => 'ⲩ', 11434 => 'ⲫ', 11436 => 'â²­', 11438 => 'ⲯ', 11440 => 'â²±', 11442 => 'â²³', 11444 => 'â²µ', 11446 => 'â²·', 11448 => 'â²¹', 11450 => 'â²»', 11452 => 'â²½', 11454 => 'ⲿ', 11456 => 'â³', 11458 => 'ⳃ', 11460 => 'â³…', 11462 => 'ⳇ', 11464 => 'ⳉ', 11466 => 'ⳋ', 11468 => 'â³', 11470 => 'â³', 11472 => 'ⳑ', 11474 => 'ⳓ', 11476 => 'ⳕ', 11478 => 'â³—', 11480 => 'â³™', 11482 => 'â³›', 11484 => 'â³', 11486 => 'ⳟ', 11488 => 'ⳡ', 11490 => 'â³£', 11499 => 'ⳬ', 11501 => 'â³®', 11506 => 'â³³', 11631 => 'ⵡ', 11935 => 'æ¯', 12019 => '龟', 12032 => '一', 12033 => '丨', 12034 => '丶', 12035 => '丿', 12036 => 'ä¹™', 12037 => '亅', 12038 => '二', 12039 => '亠', 12040 => '人', 12041 => 'å„¿', 12042 => 'å…¥', 12043 => 'å…«', 12044 => '冂', 12045 => '冖', 12046 => '冫', 12047 => '几', 12048 => '凵', 12049 => '刀', 12050 => '力', 12051 => '勹', 12052 => '匕', 12053 => '匚', 12054 => '匸', 12055 => 'å', 12056 => 'åœ', 12057 => 'å©', 12058 => '厂', 12059 => '厶', 12060 => 'åˆ', 12061 => 'å£', 12062 => 'å›—', 12063 => '土', 12064 => '士', 12065 => '夂', 12066 => '夊', 12067 => '夕', 12068 => '大', 12069 => '女', 12070 => 'å­', 12071 => '宀', 12072 => '寸', 12073 => 'å°', 12074 => 'å°¢', 12075 => 'å°¸', 12076 => 'å±®', 12077 => 'å±±', 12078 => 'å·›', 12079 => 'å·¥', 12080 => 'å·±', 12081 => 'å·¾', 12082 => 'å¹²', 12083 => '幺', 12084 => '广', 12085 => 'å»´', 12086 => '廾', 12087 => '弋', 12088 => '弓', 12089 => 'å½', 12090 => '彡', 12091 => 'å½³', 12092 => '心', 12093 => '戈', 12094 => '戶', 12095 => '手', 12096 => '支', 12097 => 'æ”´', 12098 => 'æ–‡', 12099 => 'æ–—', 12100 => 'æ–¤', 12101 => 'æ–¹', 12102 => 'æ— ', 12103 => 'æ—¥', 12104 => 'æ›°', 12105 => '月', 12106 => '木', 12107 => '欠', 12108 => 'æ­¢', 12109 => 'æ­¹', 12110 => '殳', 12111 => '毋', 12112 => '比', 12113 => '毛', 12114 => 'æ°', 12115 => 'æ°”', 12116 => 'æ°´', 12117 => 'ç«', 12118 => '爪', 12119 => '父', 12120 => '爻', 12121 => '爿', 12122 => '片', 12123 => '牙', 12124 => '牛', 12125 => '犬', 12126 => '玄', 12127 => '玉', 12128 => '瓜', 12129 => '瓦', 12130 => '甘', 12131 => '生', 12132 => '用', 12133 => 'ç”°', 12134 => 'ç–‹', 12135 => 'ç–’', 12136 => 'ç™¶', 12137 => '白', 12138 => 'çš®', 12139 => 'çš¿', 12140 => 'ç›®', 12141 => '矛', 12142 => '矢', 12143 => '石', 12144 => '示', 12145 => '禸', 12146 => '禾', 12147 => 'ç©´', 12148 => 'ç«‹', 12149 => '竹', 12150 => 'ç±³', 12151 => '糸', 12152 => 'ç¼¶', 12153 => '网', 12154 => '羊', 12155 => 'ç¾½', 12156 => 'è€', 12157 => '而', 12158 => '耒', 12159 => '耳', 12160 => 'è¿', 12161 => '肉', 12162 => '臣', 12163 => '自', 12164 => '至', 12165 => '臼', 12166 => '舌', 12167 => '舛', 12168 => '舟', 12169 => '艮', 12170 => '色', 12171 => '艸', 12172 => 'è™', 12173 => '虫', 12174 => 'è¡€', 12175 => '行', 12176 => 'è¡£', 12177 => '襾', 12178 => '見', 12179 => 'è§’', 12180 => '言', 12181 => 'è°·', 12182 => '豆', 12183 => '豕', 12184 => '豸', 12185 => 'è²', 12186 => '赤', 12187 => 'èµ°', 12188 => 'è¶³', 12189 => '身', 12190 => '車', 12191 => 'è¾›', 12192 => 'è¾°', 12193 => 'è¾µ', 12194 => 'é‚‘', 12195 => 'é…‰', 12196 => '釆', 12197 => '里', 12198 => '金', 12199 => 'é•·', 12200 => 'é–€', 12201 => '阜', 12202 => 'éš¶', 12203 => 'éš¹', 12204 => '雨', 12205 => 'é‘', 12206 => 'éž', 12207 => 'é¢', 12208 => 'é©', 12209 => '韋', 12210 => '韭', 12211 => '音', 12212 => 'é ', 12213 => '風', 12214 => '飛', 12215 => '食', 12216 => '首', 12217 => '香', 12218 => '馬', 12219 => '骨', 12220 => '高', 12221 => '髟', 12222 => '鬥', 12223 => '鬯', 12224 => '鬲', 12225 => '鬼', 12226 => 'é­š', 12227 => 'é³¥', 12228 => 'é¹µ', 12229 => '鹿', 12230 => '麥', 12231 => '麻', 12232 => '黃', 12233 => 'é»', 12234 => '黑', 12235 => '黹', 12236 => '黽', 12237 => '鼎', 12238 => '鼓', 12239 => 'é¼ ', 12240 => 'é¼»', 12241 => '齊', 12242 => 'é½’', 12243 => 'é¾', 12244 => '龜', 12245 => 'é¾ ', 12290 => '.', 12342 => '〒', 12344 => 'å', 12345 => 'å„', 12346 => 'å…', 12447 => 'より', 12543 => 'コト', 12593 => 'á„€', 12594 => 'á„', 12595 => 'ᆪ', 12596 => 'á„‚', 12597 => 'ᆬ', 12598 => 'ᆭ', 12599 => 'ᄃ', 12600 => 'á„„', 12601 => 'á„…', 12602 => 'ᆰ', 12603 => 'ᆱ', 12604 => 'ᆲ', 12605 => 'ᆳ', 12606 => 'ᆴ', 12607 => 'ᆵ', 12608 => 'ᄚ', 12609 => 'ᄆ', 12610 => 'ᄇ', 12611 => 'ᄈ', 12612 => 'á„¡', 12613 => 'ᄉ', 12614 => 'ᄊ', 12615 => 'á„‹', 12616 => 'ᄌ', 12617 => 'á„', 12618 => 'ᄎ', 12619 => 'á„', 12620 => 'á„', 12621 => 'á„‘', 12622 => 'á„’', 12623 => 'á…¡', 12624 => 'á…¢', 12625 => 'á…£', 12626 => 'á…¤', 12627 => 'á…¥', 12628 => 'á…¦', 12629 => 'á…§', 12630 => 'á…¨', 12631 => 'á…©', 12632 => 'á…ª', 12633 => 'á…«', 12634 => 'á…¬', 12635 => 'á…­', 12636 => 'á…®', 12637 => 'á…¯', 12638 => 'á…°', 12639 => 'á…±', 12640 => 'á…²', 12641 => 'á…³', 12642 => 'á…´', 12643 => 'á…µ', 12645 => 'á„”', 12646 => 'á„•', 12647 => 'ᇇ', 12648 => 'ᇈ', 12649 => 'ᇌ', 12650 => 'ᇎ', 12651 => 'ᇓ', 12652 => 'ᇗ', 12653 => 'ᇙ', 12654 => 'ᄜ', 12655 => 'á‡', 12656 => 'ᇟ', 12657 => 'á„', 12658 => 'ᄞ', 12659 => 'á„ ', 12660 => 'á„¢', 12661 => 'á„£', 12662 => 'á„§', 12663 => 'á„©', 12664 => 'á„«', 12665 => 'ᄬ', 12666 => 'á„­', 12667 => 'á„®', 12668 => 'ᄯ', 12669 => 'ᄲ', 12670 => 'á„¶', 12671 => 'á…€', 12672 => 'á…‡', 12673 => 'á…Œ', 12674 => 'ᇱ', 12675 => 'ᇲ', 12676 => 'á…—', 12677 => 'á…˜', 12678 => 'á…™', 12679 => 'ᆄ', 12680 => 'ᆅ', 12681 => 'ᆈ', 12682 => 'ᆑ', 12683 => 'ᆒ', 12684 => 'ᆔ', 12685 => 'ᆞ', 12686 => 'ᆡ', 12690 => '一', 12691 => '二', 12692 => '三', 12693 => 'å››', 12694 => '上', 12695 => '中', 12696 => '下', 12697 => '甲', 12698 => 'ä¹™', 12699 => '丙', 12700 => 'ä¸', 12701 => '天', 12702 => '地', 12703 => '人', 12868 => 'å•', 12869 => 'å¹¼', 12870 => 'æ–‡', 12871 => 'ç®', 12880 => 'pte', 12881 => '21', 12882 => '22', 12883 => '23', 12884 => '24', 12885 => '25', 12886 => '26', 12887 => '27', 12888 => '28', 12889 => '29', 12890 => '30', 12891 => '31', 12892 => '32', 12893 => '33', 12894 => '34', 12895 => '35', 12896 => 'á„€', 12897 => 'á„‚', 12898 => 'ᄃ', 12899 => 'á„…', 12900 => 'ᄆ', 12901 => 'ᄇ', 12902 => 'ᄉ', 12903 => 'á„‹', 12904 => 'ᄌ', 12905 => 'ᄎ', 12906 => 'á„', 12907 => 'á„', 12908 => 'á„‘', 12909 => 'á„’', 12910 => 'ê°€', 12911 => '나', 12912 => '다', 12913 => 'ë¼', 12914 => '마', 12915 => 'ë°”', 12916 => '사', 12917 => 'ì•„', 12918 => 'ìž', 12919 => 'ì°¨', 12920 => 'ì¹´', 12921 => '타', 12922 => '파', 12923 => '하', 12924 => '참고', 12925 => '주ì˜', 12926 => 'ìš°', 12928 => '一', 12929 => '二', 12930 => '三', 12931 => 'å››', 12932 => '五', 12933 => 'å…­', 12934 => '七', 12935 => 'å…«', 12936 => 'ä¹', 12937 => 'å', 12938 => '月', 12939 => 'ç«', 12940 => 'æ°´', 12941 => '木', 12942 => '金', 12943 => '土', 12944 => 'æ—¥', 12945 => 'æ ª', 12946 => '有', 12947 => '社', 12948 => 'å', 12949 => '特', 12950 => '財', 12951 => 'ç¥', 12952 => '労', 12953 => '秘', 12954 => 'ç”·', 12955 => '女', 12956 => 'é©', 12957 => '優', 12958 => 'å°', 12959 => '注', 12960 => 'é …', 12961 => '休', 12962 => '写', 12963 => 'æ­£', 12964 => '上', 12965 => '中', 12966 => '下', 12967 => 'å·¦', 12968 => 'å³', 12969 => '医', 12970 => 'å®—', 12971 => 'å­¦', 12972 => '監', 12973 => 'ä¼', 12974 => '資', 12975 => 'å”', 12976 => '夜', 12977 => '36', 12978 => '37', 12979 => '38', 12980 => '39', 12981 => '40', 12982 => '41', 12983 => '42', 12984 => '43', 12985 => '44', 12986 => '45', 12987 => '46', 12988 => '47', 12989 => '48', 12990 => '49', 12991 => '50', 12992 => '1月', 12993 => '2月', 12994 => '3月', 12995 => '4月', 12996 => '5月', 12997 => '6月', 12998 => '7月', 12999 => '8月', 13000 => '9月', 13001 => '10月', 13002 => '11月', 13003 => '12月', 13004 => 'hg', 13005 => 'erg', 13006 => 'ev', 13007 => 'ltd', 13008 => 'ã‚¢', 13009 => 'イ', 13010 => 'ウ', 13011 => 'エ', 13012 => 'オ', 13013 => 'ã‚«', 13014 => 'ã‚­', 13015 => 'ク', 13016 => 'ケ', 13017 => 'コ', 13018 => 'サ', 13019 => 'ã‚·', 13020 => 'ス', 13021 => 'ã‚»', 13022 => 'ソ', 13023 => 'ã‚¿', 13024 => 'ãƒ', 13025 => 'ツ', 13026 => 'テ', 13027 => 'ト', 13028 => 'ナ', 13029 => 'ニ', 13030 => 'ヌ', 13031 => 'ãƒ', 13032 => 'ノ', 13033 => 'ãƒ', 13034 => 'ヒ', 13035 => 'フ', 13036 => 'ヘ', 13037 => 'ホ', 13038 => 'マ', 13039 => 'ミ', 13040 => 'ム', 13041 => 'メ', 13042 => 'モ', 13043 => 'ヤ', 13044 => 'ユ', 13045 => 'ヨ', 13046 => 'ラ', 13047 => 'リ', 13048 => 'ル', 13049 => 'レ', 13050 => 'ロ', 13051 => 'ワ', 13052 => 'ヰ', 13053 => 'ヱ', 13054 => 'ヲ', 13055 => '令和', 13056 => 'アパート', 13057 => 'アルファ', 13058 => 'アンペア', 13059 => 'アール', 13060 => 'イニング', 13061 => 'インãƒ', 13062 => 'ウォン', 13063 => 'エスクード', 13064 => 'エーカー', 13065 => 'オンス', 13066 => 'オーム', 13067 => 'カイリ', 13068 => 'カラット', 13069 => 'カロリー', 13070 => 'ガロン', 13071 => 'ガンマ', 13072 => 'ギガ', 13073 => 'ギニー', 13074 => 'キュリー', 13075 => 'ギルダー', 13076 => 'キロ', 13077 => 'キログラム', 13078 => 'キロメートル', 13079 => 'キロワット', 13080 => 'グラム', 13081 => 'グラムトン', 13082 => 'クルゼイロ', 13083 => 'クローãƒ', 13084 => 'ケース', 13085 => 'コルナ', 13086 => 'コーãƒ', 13087 => 'サイクル', 13088 => 'サンãƒãƒ¼ãƒ ', 13089 => 'シリング', 13090 => 'センãƒ', 13091 => 'セント', 13092 => 'ダース', 13093 => 'デシ', 13094 => 'ドル', 13095 => 'トン', 13096 => 'ナノ', 13097 => 'ノット', 13098 => 'ãƒã‚¤ãƒ„', 13099 => 'パーセント', 13100 => 'パーツ', 13101 => 'ãƒãƒ¼ãƒ¬ãƒ«', 13102 => 'ピアストル', 13103 => 'ピクル', 13104 => 'ピコ', 13105 => 'ビル', 13106 => 'ファラッド', 13107 => 'フィート', 13108 => 'ブッシェル', 13109 => 'フラン', 13110 => 'ヘクタール', 13111 => 'ペソ', 13112 => 'ペニヒ', 13113 => 'ヘルツ', 13114 => 'ペンス', 13115 => 'ページ', 13116 => 'ベータ', 13117 => 'ãƒã‚¤ãƒ³ãƒˆ', 13118 => 'ボルト', 13119 => 'ホン', 13120 => 'ãƒãƒ³ãƒ‰', 13121 => 'ホール', 13122 => 'ホーン', 13123 => 'マイクロ', 13124 => 'マイル', 13125 => 'マッãƒ', 13126 => 'マルク', 13127 => 'マンション', 13128 => 'ミクロン', 13129 => 'ミリ', 13130 => 'ミリãƒãƒ¼ãƒ«', 13131 => 'メガ', 13132 => 'メガトン', 13133 => 'メートル', 13134 => 'ヤード', 13135 => 'ヤール', 13136 => 'ユアン', 13137 => 'リットル', 13138 => 'リラ', 13139 => 'ルピー', 13140 => 'ルーブル', 13141 => 'レム', 13142 => 'レントゲン', 13143 => 'ワット', 13144 => '0点', 13145 => '1点', 13146 => '2点', 13147 => '3点', 13148 => '4点', 13149 => '5点', 13150 => '6点', 13151 => '7点', 13152 => '8点', 13153 => '9点', 13154 => '10点', 13155 => '11点', 13156 => '12点', 13157 => '13点', 13158 => '14点', 13159 => '15点', 13160 => '16点', 13161 => '17点', 13162 => '18点', 13163 => '19点', 13164 => '20点', 13165 => '21点', 13166 => '22点', 13167 => '23点', 13168 => '24点', 13169 => 'hpa', 13170 => 'da', 13171 => 'au', 13172 => 'bar', 13173 => 'ov', 13174 => 'pc', 13175 => 'dm', 13176 => 'dm2', 13177 => 'dm3', 13178 => 'iu', 13179 => 'å¹³æˆ', 13180 => '昭和', 13181 => '大正', 13182 => '明治', 13183 => 'æ ªå¼ä¼šç¤¾', 13184 => 'pa', 13185 => 'na', 13186 => 'μa', 13187 => 'ma', 13188 => 'ka', 13189 => 'kb', 13190 => 'mb', 13191 => 'gb', 13192 => 'cal', 13193 => 'kcal', 13194 => 'pf', 13195 => 'nf', 13196 => 'μf', 13197 => 'μg', 13198 => 'mg', 13199 => 'kg', 13200 => 'hz', 13201 => 'khz', 13202 => 'mhz', 13203 => 'ghz', 13204 => 'thz', 13205 => 'μl', 13206 => 'ml', 13207 => 'dl', 13208 => 'kl', 13209 => 'fm', 13210 => 'nm', 13211 => 'μm', 13212 => 'mm', 13213 => 'cm', 13214 => 'km', 13215 => 'mm2', 13216 => 'cm2', 13217 => 'm2', 13218 => 'km2', 13219 => 'mm3', 13220 => 'cm3', 13221 => 'm3', 13222 => 'km3', 13223 => 'm∕s', 13224 => 'm∕s2', 13225 => 'pa', 13226 => 'kpa', 13227 => 'mpa', 13228 => 'gpa', 13229 => 'rad', 13230 => 'rad∕s', 13231 => 'rad∕s2', 13232 => 'ps', 13233 => 'ns', 13234 => 'μs', 13235 => 'ms', 13236 => 'pv', 13237 => 'nv', 13238 => 'μv', 13239 => 'mv', 13240 => 'kv', 13241 => 'mv', 13242 => 'pw', 13243 => 'nw', 13244 => 'μw', 13245 => 'mw', 13246 => 'kw', 13247 => 'mw', 13248 => 'kω', 13249 => 'mω', 13251 => 'bq', 13252 => 'cc', 13253 => 'cd', 13254 => 'c∕kg', 13256 => 'db', 13257 => 'gy', 13258 => 'ha', 13259 => 'hp', 13260 => 'in', 13261 => 'kk', 13262 => 'km', 13263 => 'kt', 13264 => 'lm', 13265 => 'ln', 13266 => 'log', 13267 => 'lx', 13268 => 'mb', 13269 => 'mil', 13270 => 'mol', 13271 => 'ph', 13273 => 'ppm', 13274 => 'pr', 13275 => 'sr', 13276 => 'sv', 13277 => 'wb', 13278 => 'v∕m', 13279 => 'a∕m', 13280 => '1æ—¥', 13281 => '2æ—¥', 13282 => '3æ—¥', 13283 => '4æ—¥', 13284 => '5æ—¥', 13285 => '6æ—¥', 13286 => '7æ—¥', 13287 => '8æ—¥', 13288 => '9æ—¥', 13289 => '10æ—¥', 13290 => '11æ—¥', 13291 => '12æ—¥', 13292 => '13æ—¥', 13293 => '14æ—¥', 13294 => '15æ—¥', 13295 => '16æ—¥', 13296 => '17æ—¥', 13297 => '18æ—¥', 13298 => '19æ—¥', 13299 => '20æ—¥', 13300 => '21æ—¥', 13301 => '22æ—¥', 13302 => '23æ—¥', 13303 => '24æ—¥', 13304 => '25æ—¥', 13305 => '26æ—¥', 13306 => '27æ—¥', 13307 => '28æ—¥', 13308 => '29æ—¥', 13309 => '30æ—¥', 13310 => '31æ—¥', 13311 => 'gal', 42560 => 'ê™', 42562 => 'ꙃ', 42564 => 'ê™…', 42566 => 'ꙇ', 42568 => 'ꙉ', 42570 => 'ꙋ', 42572 => 'ê™', 42574 => 'ê™', 42576 => 'ꙑ', 42578 => 'ꙓ', 42580 => 'ꙕ', 42582 => 'ê™—', 42584 => 'ê™™', 42586 => 'ê™›', 42588 => 'ê™', 42590 => 'ꙟ', 42592 => 'ꙡ', 42594 => 'ꙣ', 42596 => 'ꙥ', 42598 => 'ê™§', 42600 => 'ꙩ', 42602 => 'ꙫ', 42604 => 'ê™­', 42624 => 'êš', 42626 => 'ꚃ', 42628 => 'êš…', 42630 => 'ꚇ', 42632 => 'ꚉ', 42634 => 'êš‹', 42636 => 'êš', 42638 => 'êš', 42640 => 'êš‘', 42642 => 'êš“', 42644 => 'êš•', 42646 => 'êš—', 42648 => 'êš™', 42650 => 'êš›', 42652 => 'ÑŠ', 42653 => 'ÑŒ', 42786 => 'ꜣ', 42788 => 'ꜥ', 42790 => 'ꜧ', 42792 => 'ꜩ', 42794 => 'ꜫ', 42796 => 'ꜭ', 42798 => 'ꜯ', 42802 => 'ꜳ', 42804 => 'ꜵ', 42806 => 'ꜷ', 42808 => 'ꜹ', 42810 => 'ꜻ', 42812 => 'ꜽ', 42814 => 'ꜿ', 42816 => 'ê', 42818 => 'êƒ', 42820 => 'ê…', 42822 => 'ê‡', 42824 => 'ê‰', 42826 => 'ê‹', 42828 => 'ê', 42830 => 'ê', 42832 => 'ê‘', 42834 => 'ê“', 42836 => 'ê•', 42838 => 'ê—', 42840 => 'ê™', 42842 => 'ê›', 42844 => 'ê', 42846 => 'êŸ', 42848 => 'ê¡', 42850 => 'ê£', 42852 => 'ê¥', 42854 => 'ê§', 42856 => 'ê©', 42858 => 'ê«', 42860 => 'ê­', 42862 => 'ê¯', 42864 => 'ê¯', 42873 => 'êº', 42875 => 'ê¼', 42877 => 'áµ¹', 42878 => 'ê¿', 42880 => 'êž', 42882 => 'ꞃ', 42884 => 'êž…', 42886 => 'ꞇ', 42891 => 'ꞌ', 42893 => 'É¥', 42896 => 'êž‘', 42898 => 'êž“', 42902 => 'êž—', 42904 => 'êž™', 42906 => 'êž›', 42908 => 'êž', 42910 => 'ꞟ', 42912 => 'êž¡', 42914 => 'ꞣ', 42916 => 'ꞥ', 42918 => 'êž§', 42920 => 'êž©', 42922 => 'ɦ', 42923 => 'Éœ', 42924 => 'É¡', 42925 => 'ɬ', 42926 => 'ɪ', 42928 => 'Êž', 42929 => 'ʇ', 42930 => 'Ê', 42931 => 'ê­“', 42932 => 'êžµ', 42934 => 'êž·', 42936 => 'êž¹', 42938 => 'êž»', 42940 => 'êž½', 42942 => 'êž¿', 42946 => 'ꟃ', 42948 => 'êž”', 42949 => 'Ê‚', 42950 => 'á¶Ž', 42951 => 'ꟈ', 42953 => 'ꟊ', 42997 => 'ꟶ', 43000 => 'ħ', 43001 => 'Å“', 43868 => 'ꜧ', 43869 => 'ꬷ', 43870 => 'É«', 43871 => 'ê­’', 43881 => 'Ê', 43888 => 'Ꭰ', 43889 => 'Ꭱ', 43890 => 'Ꭲ', 43891 => 'Ꭳ', 43892 => 'Ꭴ', 43893 => 'Ꭵ', 43894 => 'Ꭶ', 43895 => 'Ꭷ', 43896 => 'Ꭸ', 43897 => 'Ꭹ', 43898 => 'Ꭺ', 43899 => 'Ꭻ', 43900 => 'Ꭼ', 43901 => 'Ꭽ', 43902 => 'Ꭾ', 43903 => 'Ꭿ', 43904 => 'Ꮀ', 43905 => 'Ꮁ', 43906 => 'Ꮂ', 43907 => 'Ꮃ', 43908 => 'Ꮄ', 43909 => 'Ꮅ', 43910 => 'Ꮆ', 43911 => 'Ꮇ', 43912 => 'Ꮈ', 43913 => 'Ꮉ', 43914 => 'Ꮊ', 43915 => 'Ꮋ', 43916 => 'Ꮌ', 43917 => 'Ꮍ', 43918 => 'Ꮎ', 43919 => 'Ꮏ', 43920 => 'á€', 43921 => 'á', 43922 => 'á‚', 43923 => 'áƒ', 43924 => 'á„', 43925 => 'á…', 43926 => 'á†', 43927 => 'á‡', 43928 => 'áˆ', 43929 => 'á‰', 43930 => 'áŠ', 43931 => 'á‹', 43932 => 'áŒ', 43933 => 'á', 43934 => 'áŽ', 43935 => 'á', 43936 => 'á', 43937 => 'á‘', 43938 => 'á’', 43939 => 'á“', 43940 => 'á”', 43941 => 'á•', 43942 => 'á–', 43943 => 'á—', 43944 => 'á˜', 43945 => 'á™', 43946 => 'áš', 43947 => 'á›', 43948 => 'áœ', 43949 => 'á', 43950 => 'áž', 43951 => 'áŸ', 43952 => 'á ', 43953 => 'á¡', 43954 => 'á¢', 43955 => 'á£', 43956 => 'á¤', 43957 => 'á¥', 43958 => 'á¦', 43959 => 'á§', 43960 => 'á¨', 43961 => 'á©', 43962 => 'áª', 43963 => 'á«', 43964 => 'á¬', 43965 => 'á­', 43966 => 'á®', 43967 => 'á¯', 63744 => '豈', 63745 => 'æ›´', 63746 => '車', 63747 => '賈', 63748 => '滑', 63749 => '串', 63750 => 'å¥', 63751 => '龜', 63752 => '龜', 63753 => '契', 63754 => '金', 63755 => 'å–‡', 63756 => '奈', 63757 => '懶', 63758 => '癩', 63759 => 'ç¾…', 63760 => '蘿', 63761 => '螺', 63762 => '裸', 63763 => 'é‚', 63764 => '樂', 63765 => 'æ´›', 63766 => '烙', 63767 => 'çž', 63768 => 'è½', 63769 => 'é…ª', 63770 => 'é§±', 63771 => '亂', 63772 => 'åµ', 63773 => '欄', 63774 => '爛', 63775 => '蘭', 63776 => '鸞', 63777 => 'åµ', 63778 => 'æ¿«', 63779 => 'è—', 63780 => '襤', 63781 => '拉', 63782 => '臘', 63783 => 'è Ÿ', 63784 => '廊', 63785 => '朗', 63786 => '浪', 63787 => '狼', 63788 => '郎', 63789 => '來', 63790 => '冷', 63791 => '勞', 63792 => 'æ“„', 63793 => 'æ«“', 63794 => 'çˆ', 63795 => 'ç›§', 63796 => 'è€', 63797 => '蘆', 63798 => '虜', 63799 => 'è·¯', 63800 => '露', 63801 => 'é­¯', 63802 => 'é·º', 63803 => '碌', 63804 => '祿', 63805 => 'ç¶ ', 63806 => 'è‰', 63807 => '錄', 63808 => '鹿', 63809 => 'è«–', 63810 => '壟', 63811 => '弄', 63812 => 'ç± ', 63813 => 'è¾', 63814 => '牢', 63815 => '磊', 63816 => '賂', 63817 => 'é›·', 63818 => '壘', 63819 => 'å±¢', 63820 => '樓', 63821 => 'æ·š', 63822 => 'æ¼', 63823 => 'ç´¯', 63824 => '縷', 63825 => '陋', 63826 => 'å‹’', 63827 => 'è‚‹', 63828 => '凜', 63829 => '凌', 63830 => '稜', 63831 => 'ç¶¾', 63832 => 'è±', 63833 => '陵', 63834 => '讀', 63835 => 'æ‹', 63836 => '樂', 63837 => '諾', 63838 => '丹', 63839 => '寧', 63840 => '怒', 63841 => '率', 63842 => 'ç•°', 63843 => '北', 63844 => '磻', 63845 => '便', 63846 => '復', 63847 => 'ä¸', 63848 => '泌', 63849 => '數', 63850 => 'ç´¢', 63851 => 'åƒ', 63852 => '塞', 63853 => 'çœ', 63854 => '葉', 63855 => '說', 63856 => '殺', 63857 => 'è¾°', 63858 => '沈', 63859 => '拾', 63860 => 'è‹¥', 63861 => '掠', 63862 => 'ç•¥', 63863 => '亮', 63864 => 'å…©', 63865 => '凉', 63866 => 'æ¢', 63867 => 'ç³§', 63868 => '良', 63869 => 'è«’', 63870 => 'é‡', 63871 => '勵', 63872 => 'å‘‚', 63873 => '女', 63874 => '廬', 63875 => 'æ—…', 63876 => '濾', 63877 => '礪', 63878 => 'é–­', 63879 => '驪', 63880 => '麗', 63881 => '黎', 63882 => '力', 63883 => '曆', 63884 => 'æ­·', 63885 => 'è½¢', 63886 => 'å¹´', 63887 => 'æ†', 63888 => '戀', 63889 => 'æ’š', 63890 => 'æ¼£', 63891 => 'ç…‰', 63892 => 'ç’‰', 63893 => 'ç§Š', 63894 => 'ç·´', 63895 => 'è¯', 63896 => '輦', 63897 => 'è“®', 63898 => '連', 63899 => 'éŠ', 63900 => '列', 63901 => '劣', 63902 => 'å’½', 63903 => '烈', 63904 => '裂', 63905 => '說', 63906 => '廉', 63907 => '念', 63908 => 'æ»', 63909 => 'æ®®', 63910 => 'ç°¾', 63911 => 'çµ', 63912 => '令', 63913 => '囹', 63914 => '寧', 63915 => '嶺', 63916 => '怜', 63917 => '玲', 63918 => 'ç‘©', 63919 => '羚', 63920 => 'è†', 63921 => '鈴', 63922 => 'é›¶', 63923 => 'éˆ', 63924 => 'é ˜', 63925 => '例', 63926 => '禮', 63927 => '醴', 63928 => '隸', 63929 => '惡', 63930 => '了', 63931 => '僚', 63932 => '寮', 63933 => 'å°¿', 63934 => 'æ–™', 63935 => '樂', 63936 => '燎', 63937 => '療', 63938 => '蓼', 63939 => 'é¼', 63940 => 'é¾', 63941 => '暈', 63942 => '阮', 63943 => '劉', 63944 => 'æ»', 63945 => '柳', 63946 => 'æµ', 63947 => '溜', 63948 => 'ç‰', 63949 => 'ç•™', 63950 => 'ç¡«', 63951 => 'ç´', 63952 => '類', 63953 => 'å…­', 63954 => '戮', 63955 => '陸', 63956 => '倫', 63957 => 'å´™', 63958 => 'æ·ª', 63959 => '輪', 63960 => '律', 63961 => 'æ…„', 63962 => 'æ —', 63963 => '率', 63964 => '隆', 63965 => '利', 63966 => 'å', 63967 => 'å±¥', 63968 => '易', 63969 => 'æŽ', 63970 => '梨', 63971 => 'æ³¥', 63972 => 'ç†', 63973 => 'ç—¢', 63974 => 'ç½¹', 63975 => 'è£', 63976 => '裡', 63977 => '里', 63978 => '離', 63979 => '匿', 63980 => '溺', 63981 => 'å', 63982 => 'ç‡', 63983 => 'ç’˜', 63984 => 'è—º', 63985 => '隣', 63986 => 'é±—', 63987 => '麟', 63988 => 'æž—', 63989 => 'æ·‹', 63990 => '臨', 63991 => 'ç«‹', 63992 => '笠', 63993 => 'ç²’', 63994 => 'ç‹€', 63995 => 'ç‚™', 63996 => 'è­˜', 63997 => '什', 63998 => '茶', 63999 => '刺', 64000 => '切', 64001 => '度', 64002 => 'æ‹“', 64003 => 'ç³–', 64004 => 'å®…', 64005 => 'æ´ž', 64006 => 'æš´', 64007 => 'è¼»', 64008 => '行', 64009 => 'é™', 64010 => '見', 64011 => '廓', 64012 => 'å…€', 64013 => 'å—€', 64016 => '塚', 64018 => 'æ™´', 64021 => '凞', 64022 => '猪', 64023 => '益', 64024 => '礼', 64025 => '神', 64026 => '祥', 64027 => 'ç¦', 64028 => 'é–', 64029 => 'ç²¾', 64030 => 'ç¾½', 64032 => '蘒', 64034 => '諸', 64037 => '逸', 64038 => '都', 64042 => '飯', 64043 => '飼', 64044 => '館', 64045 => 'é¶´', 64046 => '郞', 64047 => 'éš·', 64048 => 'ä¾®', 64049 => '僧', 64050 => 'å…', 64051 => '勉', 64052 => '勤', 64053 => 'å‘', 64054 => 'å–', 64055 => '嘆', 64056 => '器', 64057 => 'å¡€', 64058 => '墨', 64059 => '層', 64060 => 'å±®', 64061 => 'æ‚”', 64062 => 'æ…¨', 64063 => '憎', 64064 => '懲', 64065 => 'æ•', 64066 => 'æ—¢', 64067 => 'æš‘', 64068 => '梅', 64069 => 'æµ·', 64070 => '渚', 64071 => 'æ¼¢', 64072 => 'ç…®', 64073 => '爫', 64074 => 'ç¢', 64075 => '碑', 64076 => '社', 64077 => '祉', 64078 => '祈', 64079 => 'ç¥', 64080 => '祖', 64081 => 'ç¥', 64082 => 'ç¦', 64083 => '禎', 64084 => 'ç©€', 64085 => 'çª', 64086 => '節', 64087 => 'ç·´', 64088 => '縉', 64089 => 'ç¹', 64090 => 'ç½²', 64091 => '者', 64092 => '臭', 64093 => '艹', 64094 => '艹', 64095 => 'è‘—', 64096 => 'è¤', 64097 => '視', 64098 => 'è¬', 64099 => '謹', 64100 => '賓', 64101 => 'è´ˆ', 64102 => 'è¾¶', 64103 => '逸', 64104 => '難', 64105 => '響', 64106 => 'é »', 64107 => 'æµ', 64108 => '𤋮', 64109 => '舘', 64112 => '並', 64113 => '况', 64114 => 'å…¨', 64115 => 'ä¾€', 64116 => 'å……', 64117 => '冀', 64118 => '勇', 64119 => '勺', 64120 => 'å–', 64121 => 'å••', 64122 => 'å–™', 64123 => 'å—¢', 64124 => '塚', 64125 => '墳', 64126 => '奄', 64127 => '奔', 64128 => 'å©¢', 64129 => '嬨', 64130 => 'å»’', 64131 => 'å»™', 64132 => '彩', 64133 => 'å¾­', 64134 => '惘', 64135 => 'æ…Ž', 64136 => '愈', 64137 => '憎', 64138 => 'æ… ', 64139 => '懲', 64140 => '戴', 64141 => 'æ„', 64142 => 'æœ', 64143 => 'æ‘’', 64144 => 'æ•–', 64145 => 'æ™´', 64146 => '朗', 64147 => '望', 64148 => 'æ–', 64149 => 'æ­¹', 64150 => '殺', 64151 => 'æµ', 64152 => 'æ»›', 64153 => '滋', 64154 => 'æ¼¢', 64155 => '瀞', 64156 => 'ç…®', 64157 => 'çž§', 64158 => '爵', 64159 => '犯', 64160 => '猪', 64161 => '瑱', 64162 => '甆', 64163 => 'ç”»', 64164 => 'ç˜', 64165 => '瘟', 64166 => '益', 64167 => 'ç››', 64168 => 'ç›´', 64169 => 'çŠ', 64170 => 'ç€', 64171 => '磌', 64172 => '窱', 64173 => '節', 64174 => 'ç±»', 64175 => 'çµ›', 64176 => 'ç·´', 64177 => 'ç¼¾', 64178 => '者', 64179 => 'è’', 64180 => 'è¯', 64181 => 'è¹', 64182 => 'è¥', 64183 => '覆', 64184 => '視', 64185 => '調', 64186 => '諸', 64187 => 'è«‹', 64188 => 'è¬', 64189 => '諾', 64190 => 'è«­', 64191 => '謹', 64192 => '變', 64193 => 'è´ˆ', 64194 => '輸', 64195 => 'é²', 64196 => '醙', 64197 => '鉶', 64198 => '陼', 64199 => '難', 64200 => 'é–', 64201 => '韛', 64202 => '響', 64203 => 'é ‹', 64204 => 'é »', 64205 => '鬒', 64206 => '龜', 64207 => '𢡊', 64208 => '𢡄', 64209 => 'ð£•', 64210 => 'ã®', 64211 => '䀘', 64212 => '䀹', 64213 => '𥉉', 64214 => 'ð¥³', 64215 => '𧻓', 64216 => '齃', 64217 => '龎', 64256 => 'ff', 64257 => 'fi', 64258 => 'fl', 64259 => 'ffi', 64260 => 'ffl', 64261 => 'st', 64262 => 'st', 64275 => 'Õ´Õ¶', 64276 => 'Õ´Õ¥', 64277 => 'Õ´Õ«', 64278 => 'Õ¾Õ¶', 64279 => 'Õ´Õ­', 64285 => '×™Ö´', 64287 => 'ײַ', 64288 => '×¢', 64289 => '×', 64290 => 'ד', 64291 => '×”', 64292 => '×›', 64293 => 'ל', 64294 => '×', 64295 => 'ר', 64296 => 'ת', 64298 => 'ש×', 64299 => 'שׂ', 64300 => 'שּ×', 64301 => 'שּׂ', 64302 => '×Ö·', 64303 => '×Ö¸', 64304 => '×Ö¼', 64305 => 'בּ', 64306 => '×’Ö¼', 64307 => 'דּ', 64308 => '×”Ö¼', 64309 => 'וּ', 64310 => '×–Ö¼', 64312 => 'טּ', 64313 => '×™Ö¼', 64314 => 'ךּ', 64315 => '×›Ö¼', 64316 => 'לּ', 64318 => 'מּ', 64320 => '× Ö¼', 64321 => 'סּ', 64323 => '×£Ö¼', 64324 => 'פּ', 64326 => 'צּ', 64327 => '×§Ö¼', 64328 => 'רּ', 64329 => 'שּ', 64330 => 'תּ', 64331 => 'וֹ', 64332 => 'בֿ', 64333 => '×›Ö¿', 64334 => 'פֿ', 64335 => '×ל', 64336 => 'Ù±', 64337 => 'Ù±', 64338 => 'Ù»', 64339 => 'Ù»', 64340 => 'Ù»', 64341 => 'Ù»', 64342 => 'Ù¾', 64343 => 'Ù¾', 64344 => 'Ù¾', 64345 => 'Ù¾', 64346 => 'Ú€', 64347 => 'Ú€', 64348 => 'Ú€', 64349 => 'Ú€', 64350 => 'Ùº', 64351 => 'Ùº', 64352 => 'Ùº', 64353 => 'Ùº', 64354 => 'Ù¿', 64355 => 'Ù¿', 64356 => 'Ù¿', 64357 => 'Ù¿', 64358 => 'Ù¹', 64359 => 'Ù¹', 64360 => 'Ù¹', 64361 => 'Ù¹', 64362 => 'Ú¤', 64363 => 'Ú¤', 64364 => 'Ú¤', 64365 => 'Ú¤', 64366 => 'Ú¦', 64367 => 'Ú¦', 64368 => 'Ú¦', 64369 => 'Ú¦', 64370 => 'Ú„', 64371 => 'Ú„', 64372 => 'Ú„', 64373 => 'Ú„', 64374 => 'Úƒ', 64375 => 'Úƒ', 64376 => 'Úƒ', 64377 => 'Úƒ', 64378 => 'Ú†', 64379 => 'Ú†', 64380 => 'Ú†', 64381 => 'Ú†', 64382 => 'Ú‡', 64383 => 'Ú‡', 64384 => 'Ú‡', 64385 => 'Ú‡', 64386 => 'Ú', 64387 => 'Ú', 64388 => 'ÚŒ', 64389 => 'ÚŒ', 64390 => 'ÚŽ', 64391 => 'ÚŽ', 64392 => 'Úˆ', 64393 => 'Úˆ', 64394 => 'Ú˜', 64395 => 'Ú˜', 64396 => 'Ú‘', 64397 => 'Ú‘', 64398 => 'Ú©', 64399 => 'Ú©', 64400 => 'Ú©', 64401 => 'Ú©', 64402 => 'Ú¯', 64403 => 'Ú¯', 64404 => 'Ú¯', 64405 => 'Ú¯', 64406 => 'Ú³', 64407 => 'Ú³', 64408 => 'Ú³', 64409 => 'Ú³', 64410 => 'Ú±', 64411 => 'Ú±', 64412 => 'Ú±', 64413 => 'Ú±', 64414 => 'Úº', 64415 => 'Úº', 64416 => 'Ú»', 64417 => 'Ú»', 64418 => 'Ú»', 64419 => 'Ú»', 64420 => 'Û€', 64421 => 'Û€', 64422 => 'Û', 64423 => 'Û', 64424 => 'Û', 64425 => 'Û', 64426 => 'Ú¾', 64427 => 'Ú¾', 64428 => 'Ú¾', 64429 => 'Ú¾', 64430 => 'Û’', 64431 => 'Û’', 64432 => 'Û“', 64433 => 'Û“', 64467 => 'Ú­', 64468 => 'Ú­', 64469 => 'Ú­', 64470 => 'Ú­', 64471 => 'Û‡', 64472 => 'Û‡', 64473 => 'Û†', 64474 => 'Û†', 64475 => 'Ûˆ', 64476 => 'Ûˆ', 64477 => 'Û‡Ù´', 64478 => 'Û‹', 64479 => 'Û‹', 64480 => 'Û…', 64481 => 'Û…', 64482 => 'Û‰', 64483 => 'Û‰', 64484 => 'Û', 64485 => 'Û', 64486 => 'Û', 64487 => 'Û', 64488 => 'Ù‰', 64489 => 'Ù‰', 64490 => 'ئا', 64491 => 'ئا', 64492 => 'ئە', 64493 => 'ئە', 64494 => 'ئو', 64495 => 'ئو', 64496 => 'ئۇ', 64497 => 'ئۇ', 64498 => 'ئۆ', 64499 => 'ئۆ', 64500 => 'ئۈ', 64501 => 'ئۈ', 64502 => 'ئÛ', 64503 => 'ئÛ', 64504 => 'ئÛ', 64505 => 'ئى', 64506 => 'ئى', 64507 => 'ئى', 64508 => 'ÛŒ', 64509 => 'ÛŒ', 64510 => 'ÛŒ', 64511 => 'ÛŒ', 64512 => 'ئج', 64513 => 'ئح', 64514 => 'ئم', 64515 => 'ئى', 64516 => 'ئي', 64517 => 'بج', 64518 => 'بح', 64519 => 'بخ', 64520 => 'بم', 64521 => 'بى', 64522 => 'بي', 64523 => 'تج', 64524 => 'تح', 64525 => 'تخ', 64526 => 'تم', 64527 => 'تى', 64528 => 'تي', 64529 => 'ثج', 64530 => 'ثم', 64531 => 'ثى', 64532 => 'ثي', 64533 => 'جح', 64534 => 'جم', 64535 => 'حج', 64536 => 'حم', 64537 => 'خج', 64538 => 'خح', 64539 => 'خم', 64540 => 'سج', 64541 => 'سح', 64542 => 'سخ', 64543 => 'سم', 64544 => 'صح', 64545 => 'صم', 64546 => 'ضج', 64547 => 'ضح', 64548 => 'ضخ', 64549 => 'ضم', 64550 => 'طح', 64551 => 'طم', 64552 => 'ظم', 64553 => 'عج', 64554 => 'عم', 64555 => 'غج', 64556 => 'غم', 64557 => 'ÙØ¬', 64558 => 'ÙØ­', 64559 => 'ÙØ®', 64560 => 'ÙÙ…', 64561 => 'ÙÙ‰', 64562 => 'ÙÙŠ', 64563 => 'قح', 64564 => 'قم', 64565 => 'قى', 64566 => 'قي', 64567 => 'كا', 64568 => 'كج', 64569 => 'كح', 64570 => 'كخ', 64571 => 'كل', 64572 => 'كم', 64573 => 'كى', 64574 => 'كي', 64575 => 'لج', 64576 => 'لح', 64577 => 'لخ', 64578 => 'لم', 64579 => 'لى', 64580 => 'لي', 64581 => 'مج', 64582 => 'مح', 64583 => 'مخ', 64584 => 'مم', 64585 => 'مى', 64586 => 'مي', 64587 => 'نج', 64588 => 'نح', 64589 => 'نخ', 64590 => 'نم', 64591 => 'نى', 64592 => 'ني', 64593 => 'هج', 64594 => 'هم', 64595 => 'هى', 64596 => 'هي', 64597 => 'يج', 64598 => 'يح', 64599 => 'يخ', 64600 => 'يم', 64601 => 'يى', 64602 => 'يي', 64603 => 'ذٰ', 64604 => 'رٰ', 64605 => 'ىٰ', 64612 => 'ئر', 64613 => 'ئز', 64614 => 'ئم', 64615 => 'ئن', 64616 => 'ئى', 64617 => 'ئي', 64618 => 'بر', 64619 => 'بز', 64620 => 'بم', 64621 => 'بن', 64622 => 'بى', 64623 => 'بي', 64624 => 'تر', 64625 => 'تز', 64626 => 'تم', 64627 => 'تن', 64628 => 'تى', 64629 => 'تي', 64630 => 'ثر', 64631 => 'ثز', 64632 => 'ثم', 64633 => 'ثن', 64634 => 'ثى', 64635 => 'ثي', 64636 => 'ÙÙ‰', 64637 => 'ÙÙŠ', 64638 => 'قى', 64639 => 'قي', 64640 => 'كا', 64641 => 'كل', 64642 => 'كم', 64643 => 'كى', 64644 => 'كي', 64645 => 'لم', 64646 => 'لى', 64647 => 'لي', 64648 => 'ما', 64649 => 'مم', 64650 => 'نر', 64651 => 'نز', 64652 => 'نم', 64653 => 'نن', 64654 => 'نى', 64655 => 'ني', 64656 => 'ىٰ', 64657 => 'ير', 64658 => 'يز', 64659 => 'يم', 64660 => 'ين', 64661 => 'يى', 64662 => 'يي', 64663 => 'ئج', 64664 => 'ئح', 64665 => 'ئخ', 64666 => 'ئم', 64667 => 'ئه', 64668 => 'بج', 64669 => 'بح', 64670 => 'بخ', 64671 => 'بم', 64672 => 'به', 64673 => 'تج', 64674 => 'تح', 64675 => 'تخ', 64676 => 'تم', 64677 => 'ته', 64678 => 'ثم', 64679 => 'جح', 64680 => 'جم', 64681 => 'حج', 64682 => 'حم', 64683 => 'خج', 64684 => 'خم', 64685 => 'سج', 64686 => 'سح', 64687 => 'سخ', 64688 => 'سم', 64689 => 'صح', 64690 => 'صخ', 64691 => 'صم', 64692 => 'ضج', 64693 => 'ضح', 64694 => 'ضخ', 64695 => 'ضم', 64696 => 'طح', 64697 => 'ظم', 64698 => 'عج', 64699 => 'عم', 64700 => 'غج', 64701 => 'غم', 64702 => 'ÙØ¬', 64703 => 'ÙØ­', 64704 => 'ÙØ®', 64705 => 'ÙÙ…', 64706 => 'قح', 64707 => 'قم', 64708 => 'كج', 64709 => 'كح', 64710 => 'كخ', 64711 => 'كل', 64712 => 'كم', 64713 => 'لج', 64714 => 'لح', 64715 => 'لخ', 64716 => 'لم', 64717 => 'له', 64718 => 'مج', 64719 => 'مح', 64720 => 'مخ', 64721 => 'مم', 64722 => 'نج', 64723 => 'نح', 64724 => 'نخ', 64725 => 'نم', 64726 => 'نه', 64727 => 'هج', 64728 => 'هم', 64729 => 'هٰ', 64730 => 'يج', 64731 => 'يح', 64732 => 'يخ', 64733 => 'يم', 64734 => 'يه', 64735 => 'ئم', 64736 => 'ئه', 64737 => 'بم', 64738 => 'به', 64739 => 'تم', 64740 => 'ته', 64741 => 'ثم', 64742 => 'ثه', 64743 => 'سم', 64744 => 'سه', 64745 => 'شم', 64746 => 'شه', 64747 => 'كل', 64748 => 'كم', 64749 => 'لم', 64750 => 'نم', 64751 => 'نه', 64752 => 'يم', 64753 => 'يه', 64754 => 'Ù€ÙŽÙ‘', 64755 => 'Ù€ÙÙ‘', 64756 => 'Ù€ÙÙ‘', 64757 => 'طى', 64758 => 'طي', 64759 => 'عى', 64760 => 'عي', 64761 => 'غى', 64762 => 'غي', 64763 => 'سى', 64764 => 'سي', 64765 => 'شى', 64766 => 'شي', 64767 => 'حى', 64768 => 'حي', 64769 => 'جى', 64770 => 'جي', 64771 => 'خى', 64772 => 'خي', 64773 => 'صى', 64774 => 'صي', 64775 => 'ضى', 64776 => 'ضي', 64777 => 'شج', 64778 => 'شح', 64779 => 'شخ', 64780 => 'شم', 64781 => 'شر', 64782 => 'سر', 64783 => 'صر', 64784 => 'ضر', 64785 => 'طى', 64786 => 'طي', 64787 => 'عى', 64788 => 'عي', 64789 => 'غى', 64790 => 'غي', 64791 => 'سى', 64792 => 'سي', 64793 => 'شى', 64794 => 'شي', 64795 => 'حى', 64796 => 'حي', 64797 => 'جى', 64798 => 'جي', 64799 => 'خى', 64800 => 'خي', 64801 => 'صى', 64802 => 'صي', 64803 => 'ضى', 64804 => 'ضي', 64805 => 'شج', 64806 => 'شح', 64807 => 'شخ', 64808 => 'شم', 64809 => 'شر', 64810 => 'سر', 64811 => 'صر', 64812 => 'ضر', 64813 => 'شج', 64814 => 'شح', 64815 => 'شخ', 64816 => 'شم', 64817 => 'سه', 64818 => 'شه', 64819 => 'طم', 64820 => 'سج', 64821 => 'سح', 64822 => 'سخ', 64823 => 'شج', 64824 => 'شح', 64825 => 'شخ', 64826 => 'طم', 64827 => 'ظم', 64828 => 'اً', 64829 => 'اً', 64848 => 'تجم', 64849 => 'تحج', 64850 => 'تحج', 64851 => 'تحم', 64852 => 'تخم', 64853 => 'تمج', 64854 => 'تمح', 64855 => 'تمخ', 64856 => 'جمح', 64857 => 'جمح', 64858 => 'حمي', 64859 => 'حمى', 64860 => 'سحج', 64861 => 'سجح', 64862 => 'سجى', 64863 => 'سمح', 64864 => 'سمح', 64865 => 'سمج', 64866 => 'سمم', 64867 => 'سمم', 64868 => 'صحح', 64869 => 'صحح', 64870 => 'صمم', 64871 => 'شحم', 64872 => 'شحم', 64873 => 'شجي', 64874 => 'شمخ', 64875 => 'شمخ', 64876 => 'شمم', 64877 => 'شمم', 64878 => 'ضحى', 64879 => 'ضخم', 64880 => 'ضخم', 64881 => 'طمح', 64882 => 'طمح', 64883 => 'طمم', 64884 => 'طمي', 64885 => 'عجم', 64886 => 'عمم', 64887 => 'عمم', 64888 => 'عمى', 64889 => 'غمم', 64890 => 'غمي', 64891 => 'غمى', 64892 => 'ÙØ®Ù…', 64893 => 'ÙØ®Ù…', 64894 => 'قمح', 64895 => 'قمم', 64896 => 'لحم', 64897 => 'لحي', 64898 => 'لحى', 64899 => 'لجج', 64900 => 'لجج', 64901 => 'لخم', 64902 => 'لخم', 64903 => 'لمح', 64904 => 'لمح', 64905 => 'محج', 64906 => 'محم', 64907 => 'محي', 64908 => 'مجح', 64909 => 'مجم', 64910 => 'مخج', 64911 => 'مخم', 64914 => 'مجخ', 64915 => 'همج', 64916 => 'همم', 64917 => 'نحم', 64918 => 'نحى', 64919 => 'نجم', 64920 => 'نجم', 64921 => 'نجى', 64922 => 'نمي', 64923 => 'نمى', 64924 => 'يمم', 64925 => 'يمم', 64926 => 'بخي', 64927 => 'تجي', 64928 => 'تجى', 64929 => 'تخي', 64930 => 'تخى', 64931 => 'تمي', 64932 => 'تمى', 64933 => 'جمي', 64934 => 'جحى', 64935 => 'جمى', 64936 => 'سخى', 64937 => 'صحي', 64938 => 'شحي', 64939 => 'ضحي', 64940 => 'لجي', 64941 => 'لمي', 64942 => 'يحي', 64943 => 'يجي', 64944 => 'يمي', 64945 => 'ممي', 64946 => 'قمي', 64947 => 'نحي', 64948 => 'قمح', 64949 => 'لحم', 64950 => 'عمي', 64951 => 'كمي', 64952 => 'نجح', 64953 => 'مخي', 64954 => 'لجم', 64955 => 'كمم', 64956 => 'لجم', 64957 => 'نجح', 64958 => 'جحي', 64959 => 'حجي', 64960 => 'مجي', 64961 => 'Ùمي', 64962 => 'بحي', 64963 => 'كمم', 64964 => 'عجم', 64965 => 'صمم', 64966 => 'سخي', 64967 => 'نجي', 65008 => 'صلے', 65009 => 'قلے', 65010 => 'الله', 65011 => 'اكبر', 65012 => 'محمد', 65013 => 'صلعم', 65014 => 'رسول', 65015 => 'عليه', 65016 => 'وسلم', 65017 => 'صلى', 65020 => 'ریال', 65041 => 'ã€', 65047 => '〖', 65048 => '〗', 65073 => '—', 65074 => '–', 65081 => '〔', 65082 => '〕', 65083 => 'ã€', 65084 => '】', 65085 => '《', 65086 => '》', 65087 => '〈', 65088 => '〉', 65089 => '「', 65090 => 'ã€', 65091 => '『', 65092 => 'ã€', 65105 => 'ã€', 65112 => '—', 65117 => '〔', 65118 => '〕', 65123 => '-', 65137 => 'ـً', 65143 => 'Ù€ÙŽ', 65145 => 'Ù€Ù', 65147 => 'Ù€Ù', 65149 => 'ـّ', 65151 => 'ـْ', 65152 => 'Ø¡', 65153 => 'Ø¢', 65154 => 'Ø¢', 65155 => 'Ø£', 65156 => 'Ø£', 65157 => 'ؤ', 65158 => 'ؤ', 65159 => 'Ø¥', 65160 => 'Ø¥', 65161 => 'ئ', 65162 => 'ئ', 65163 => 'ئ', 65164 => 'ئ', 65165 => 'ا', 65166 => 'ا', 65167 => 'ب', 65168 => 'ب', 65169 => 'ب', 65170 => 'ب', 65171 => 'Ø©', 65172 => 'Ø©', 65173 => 'ت', 65174 => 'ت', 65175 => 'ت', 65176 => 'ت', 65177 => 'Ø«', 65178 => 'Ø«', 65179 => 'Ø«', 65180 => 'Ø«', 65181 => 'ج', 65182 => 'ج', 65183 => 'ج', 65184 => 'ج', 65185 => 'Ø­', 65186 => 'Ø­', 65187 => 'Ø­', 65188 => 'Ø­', 65189 => 'Ø®', 65190 => 'Ø®', 65191 => 'Ø®', 65192 => 'Ø®', 65193 => 'د', 65194 => 'د', 65195 => 'ذ', 65196 => 'ذ', 65197 => 'ر', 65198 => 'ر', 65199 => 'ز', 65200 => 'ز', 65201 => 'س', 65202 => 'س', 65203 => 'س', 65204 => 'س', 65205 => 'Ø´', 65206 => 'Ø´', 65207 => 'Ø´', 65208 => 'Ø´', 65209 => 'ص', 65210 => 'ص', 65211 => 'ص', 65212 => 'ص', 65213 => 'ض', 65214 => 'ض', 65215 => 'ض', 65216 => 'ض', 65217 => 'Ø·', 65218 => 'Ø·', 65219 => 'Ø·', 65220 => 'Ø·', 65221 => 'ظ', 65222 => 'ظ', 65223 => 'ظ', 65224 => 'ظ', 65225 => 'ع', 65226 => 'ع', 65227 => 'ع', 65228 => 'ع', 65229 => 'غ', 65230 => 'غ', 65231 => 'غ', 65232 => 'غ', 65233 => 'Ù', 65234 => 'Ù', 65235 => 'Ù', 65236 => 'Ù', 65237 => 'Ù‚', 65238 => 'Ù‚', 65239 => 'Ù‚', 65240 => 'Ù‚', 65241 => 'Ùƒ', 65242 => 'Ùƒ', 65243 => 'Ùƒ', 65244 => 'Ùƒ', 65245 => 'Ù„', 65246 => 'Ù„', 65247 => 'Ù„', 65248 => 'Ù„', 65249 => 'Ù…', 65250 => 'Ù…', 65251 => 'Ù…', 65252 => 'Ù…', 65253 => 'Ù†', 65254 => 'Ù†', 65255 => 'Ù†', 65256 => 'Ù†', 65257 => 'Ù‡', 65258 => 'Ù‡', 65259 => 'Ù‡', 65260 => 'Ù‡', 65261 => 'Ùˆ', 65262 => 'Ùˆ', 65263 => 'Ù‰', 65264 => 'Ù‰', 65265 => 'ÙŠ', 65266 => 'ÙŠ', 65267 => 'ÙŠ', 65268 => 'ÙŠ', 65269 => 'لآ', 65270 => 'لآ', 65271 => 'لأ', 65272 => 'لأ', 65273 => 'لإ', 65274 => 'لإ', 65275 => 'لا', 65276 => 'لا', 65293 => '-', 65294 => '.', 65296 => '0', 65297 => '1', 65298 => '2', 65299 => '3', 65300 => '4', 65301 => '5', 65302 => '6', 65303 => '7', 65304 => '8', 65305 => '9', 65313 => 'a', 65314 => 'b', 65315 => 'c', 65316 => 'd', 65317 => 'e', 65318 => 'f', 65319 => 'g', 65320 => 'h', 65321 => 'i', 65322 => 'j', 65323 => 'k', 65324 => 'l', 65325 => 'm', 65326 => 'n', 65327 => 'o', 65328 => 'p', 65329 => 'q', 65330 => 'r', 65331 => 's', 65332 => 't', 65333 => 'u', 65334 => 'v', 65335 => 'w', 65336 => 'x', 65337 => 'y', 65338 => 'z', 65345 => 'a', 65346 => 'b', 65347 => 'c', 65348 => 'd', 65349 => 'e', 65350 => 'f', 65351 => 'g', 65352 => 'h', 65353 => 'i', 65354 => 'j', 65355 => 'k', 65356 => 'l', 65357 => 'm', 65358 => 'n', 65359 => 'o', 65360 => 'p', 65361 => 'q', 65362 => 'r', 65363 => 's', 65364 => 't', 65365 => 'u', 65366 => 'v', 65367 => 'w', 65368 => 'x', 65369 => 'y', 65370 => 'z', 65375 => '⦅', 65376 => '⦆', 65377 => '.', 65378 => '「', 65379 => 'ã€', 65380 => 'ã€', 65381 => '・', 65382 => 'ヲ', 65383 => 'ã‚¡', 65384 => 'ã‚£', 65385 => 'ã‚¥', 65386 => 'ã‚§', 65387 => 'ã‚©', 65388 => 'ャ', 65389 => 'ュ', 65390 => 'ョ', 65391 => 'ッ', 65392 => 'ー', 65393 => 'ã‚¢', 65394 => 'イ', 65395 => 'ウ', 65396 => 'エ', 65397 => 'オ', 65398 => 'ã‚«', 65399 => 'ã‚­', 65400 => 'ク', 65401 => 'ケ', 65402 => 'コ', 65403 => 'サ', 65404 => 'ã‚·', 65405 => 'ス', 65406 => 'ã‚»', 65407 => 'ソ', 65408 => 'ã‚¿', 65409 => 'ãƒ', 65410 => 'ツ', 65411 => 'テ', 65412 => 'ト', 65413 => 'ナ', 65414 => 'ニ', 65415 => 'ヌ', 65416 => 'ãƒ', 65417 => 'ノ', 65418 => 'ãƒ', 65419 => 'ヒ', 65420 => 'フ', 65421 => 'ヘ', 65422 => 'ホ', 65423 => 'マ', 65424 => 'ミ', 65425 => 'ム', 65426 => 'メ', 65427 => 'モ', 65428 => 'ヤ', 65429 => 'ユ', 65430 => 'ヨ', 65431 => 'ラ', 65432 => 'リ', 65433 => 'ル', 65434 => 'レ', 65435 => 'ロ', 65436 => 'ワ', 65437 => 'ン', 65438 => 'ã‚™', 65439 => '゚', 65441 => 'á„€', 65442 => 'á„', 65443 => 'ᆪ', 65444 => 'á„‚', 65445 => 'ᆬ', 65446 => 'ᆭ', 65447 => 'ᄃ', 65448 => 'á„„', 65449 => 'á„…', 65450 => 'ᆰ', 65451 => 'ᆱ', 65452 => 'ᆲ', 65453 => 'ᆳ', 65454 => 'ᆴ', 65455 => 'ᆵ', 65456 => 'ᄚ', 65457 => 'ᄆ', 65458 => 'ᄇ', 65459 => 'ᄈ', 65460 => 'á„¡', 65461 => 'ᄉ', 65462 => 'ᄊ', 65463 => 'á„‹', 65464 => 'ᄌ', 65465 => 'á„', 65466 => 'ᄎ', 65467 => 'á„', 65468 => 'á„', 65469 => 'á„‘', 65470 => 'á„’', 65474 => 'á…¡', 65475 => 'á…¢', 65476 => 'á…£', 65477 => 'á…¤', 65478 => 'á…¥', 65479 => 'á…¦', 65482 => 'á…§', 65483 => 'á…¨', 65484 => 'á…©', 65485 => 'á…ª', 65486 => 'á…«', 65487 => 'á…¬', 65490 => 'á…­', 65491 => 'á…®', 65492 => 'á…¯', 65493 => 'á…°', 65494 => 'á…±', 65495 => 'á…²', 65498 => 'á…³', 65499 => 'á…´', 65500 => 'á…µ', 65504 => '¢', 65505 => '£', 65506 => '¬', 65508 => '¦', 65509 => 'Â¥', 65510 => 'â‚©', 65512 => '│', 65513 => 'â†', 65514 => '↑', 65515 => '→', 65516 => '↓', 65517 => 'â– ', 65518 => 'â—‹', 66560 => 'ð¨', 66561 => 'ð©', 66562 => 'ðª', 66563 => 'ð«', 66564 => 'ð¬', 66565 => 'ð­', 66566 => 'ð®', 66567 => 'ð¯', 66568 => 'ð°', 66569 => 'ð±', 66570 => 'ð²', 66571 => 'ð³', 66572 => 'ð´', 66573 => 'ðµ', 66574 => 'ð¶', 66575 => 'ð·', 66576 => 'ð¸', 66577 => 'ð¹', 66578 => 'ðº', 66579 => 'ð»', 66580 => 'ð¼', 66581 => 'ð½', 66582 => 'ð¾', 66583 => 'ð¿', 66584 => 'ð‘€', 66585 => 'ð‘', 66586 => 'ð‘‚', 66587 => 'ð‘ƒ', 66588 => 'ð‘„', 66589 => 'ð‘…', 66590 => 'ð‘†', 66591 => 'ð‘‡', 66592 => 'ð‘ˆ', 66593 => 'ð‘‰', 66594 => 'ð‘Š', 66595 => 'ð‘‹', 66596 => 'ð‘Œ', 66597 => 'ð‘', 66598 => 'ð‘Ž', 66599 => 'ð‘', 66736 => 'ð“˜', 66737 => 'ð“™', 66738 => 'ð“š', 66739 => 'ð“›', 66740 => 'ð“œ', 66741 => 'ð“', 66742 => 'ð“ž', 66743 => 'ð“Ÿ', 66744 => 'ð“ ', 66745 => 'ð“¡', 66746 => 'ð“¢', 66747 => 'ð“£', 66748 => 'ð“¤', 66749 => 'ð“¥', 66750 => 'ð“¦', 66751 => 'ð“§', 66752 => 'ð“¨', 66753 => 'ð“©', 66754 => 'ð“ª', 66755 => 'ð“«', 66756 => 'ð“¬', 66757 => 'ð“­', 66758 => 'ð“®', 66759 => 'ð“¯', 66760 => 'ð“°', 66761 => 'ð“±', 66762 => 'ð“²', 66763 => 'ð“³', 66764 => 'ð“´', 66765 => 'ð“µ', 66766 => 'ð“¶', 66767 => 'ð“·', 66768 => 'ð“¸', 66769 => 'ð“¹', 66770 => 'ð“º', 66771 => 'ð“»', 68736 => 'ð³€', 68737 => 'ð³', 68738 => 'ð³‚', 68739 => 'ð³ƒ', 68740 => 'ð³„', 68741 => 'ð³…', 68742 => 'ð³†', 68743 => 'ð³‡', 68744 => 'ð³ˆ', 68745 => 'ð³‰', 68746 => 'ð³Š', 68747 => 'ð³‹', 68748 => 'ð³Œ', 68749 => 'ð³', 68750 => 'ð³Ž', 68751 => 'ð³', 68752 => 'ð³', 68753 => 'ð³‘', 68754 => 'ð³’', 68755 => 'ð³“', 68756 => 'ð³”', 68757 => 'ð³•', 68758 => 'ð³–', 68759 => 'ð³—', 68760 => 'ð³˜', 68761 => 'ð³™', 68762 => 'ð³š', 68763 => 'ð³›', 68764 => 'ð³œ', 68765 => 'ð³', 68766 => 'ð³ž', 68767 => 'ð³Ÿ', 68768 => 'ð³ ', 68769 => 'ð³¡', 68770 => 'ð³¢', 68771 => 'ð³£', 68772 => 'ð³¤', 68773 => 'ð³¥', 68774 => 'ð³¦', 68775 => 'ð³§', 68776 => 'ð³¨', 68777 => 'ð³©', 68778 => 'ð³ª', 68779 => 'ð³«', 68780 => 'ð³¬', 68781 => 'ð³­', 68782 => 'ð³®', 68783 => 'ð³¯', 68784 => 'ð³°', 68785 => 'ð³±', 68786 => 'ð³²', 71840 => 'ð‘£€', 71841 => 'ð‘£', 71842 => '𑣂', 71843 => '𑣃', 71844 => '𑣄', 71845 => 'ð‘£…', 71846 => '𑣆', 71847 => '𑣇', 71848 => '𑣈', 71849 => '𑣉', 71850 => '𑣊', 71851 => '𑣋', 71852 => '𑣌', 71853 => 'ð‘£', 71854 => '𑣎', 71855 => 'ð‘£', 71856 => 'ð‘£', 71857 => '𑣑', 71858 => 'ð‘£’', 71859 => '𑣓', 71860 => 'ð‘£”', 71861 => '𑣕', 71862 => 'ð‘£–', 71863 => 'ð‘£—', 71864 => '𑣘', 71865 => 'ð‘£™', 71866 => '𑣚', 71867 => 'ð‘£›', 71868 => '𑣜', 71869 => 'ð‘£', 71870 => '𑣞', 71871 => '𑣟', 93760 => 'ð–¹ ', 93761 => '𖹡', 93762 => 'ð–¹¢', 93763 => 'ð–¹£', 93764 => '𖹤', 93765 => 'ð–¹¥', 93766 => '𖹦', 93767 => 'ð–¹§', 93768 => '𖹨', 93769 => '𖹩', 93770 => '𖹪', 93771 => '𖹫', 93772 => '𖹬', 93773 => 'ð–¹­', 93774 => 'ð–¹®', 93775 => '𖹯', 93776 => 'ð–¹°', 93777 => 'ð–¹±', 93778 => 'ð–¹²', 93779 => 'ð–¹³', 93780 => 'ð–¹´', 93781 => 'ð–¹µ', 93782 => 'ð–¹¶', 93783 => 'ð–¹·', 93784 => '𖹸', 93785 => 'ð–¹¹', 93786 => '𖹺', 93787 => 'ð–¹»', 93788 => 'ð–¹¼', 93789 => 'ð–¹½', 93790 => 'ð–¹¾', 93791 => '𖹿', 119134 => 'ð…—ð…¥', 119135 => 'ð…˜ð…¥', 119136 => 'ð…˜ð…¥ð…®', 119137 => 'ð…˜ð…¥ð…¯', 119138 => 'ð…˜ð…¥ð…°', 119139 => 'ð…˜ð…¥ð…±', 119140 => 'ð…˜ð…¥ð…²', 119227 => 'ð†¹ð…¥', 119228 => 'ð†ºð…¥', 119229 => 'ð†¹ð…¥ð…®', 119230 => 'ð†ºð…¥ð…®', 119231 => 'ð†¹ð…¥ð…¯', 119232 => 'ð†ºð…¥ð…¯', 119808 => 'a', 119809 => 'b', 119810 => 'c', 119811 => 'd', 119812 => 'e', 119813 => 'f', 119814 => 'g', 119815 => 'h', 119816 => 'i', 119817 => 'j', 119818 => 'k', 119819 => 'l', 119820 => 'm', 119821 => 'n', 119822 => 'o', 119823 => 'p', 119824 => 'q', 119825 => 'r', 119826 => 's', 119827 => 't', 119828 => 'u', 119829 => 'v', 119830 => 'w', 119831 => 'x', 119832 => 'y', 119833 => 'z', 119834 => 'a', 119835 => 'b', 119836 => 'c', 119837 => 'd', 119838 => 'e', 119839 => 'f', 119840 => 'g', 119841 => 'h', 119842 => 'i', 119843 => 'j', 119844 => 'k', 119845 => 'l', 119846 => 'm', 119847 => 'n', 119848 => 'o', 119849 => 'p', 119850 => 'q', 119851 => 'r', 119852 => 's', 119853 => 't', 119854 => 'u', 119855 => 'v', 119856 => 'w', 119857 => 'x', 119858 => 'y', 119859 => 'z', 119860 => 'a', 119861 => 'b', 119862 => 'c', 119863 => 'd', 119864 => 'e', 119865 => 'f', 119866 => 'g', 119867 => 'h', 119868 => 'i', 119869 => 'j', 119870 => 'k', 119871 => 'l', 119872 => 'm', 119873 => 'n', 119874 => 'o', 119875 => 'p', 119876 => 'q', 119877 => 'r', 119878 => 's', 119879 => 't', 119880 => 'u', 119881 => 'v', 119882 => 'w', 119883 => 'x', 119884 => 'y', 119885 => 'z', 119886 => 'a', 119887 => 'b', 119888 => 'c', 119889 => 'd', 119890 => 'e', 119891 => 'f', 119892 => 'g', 119894 => 'i', 119895 => 'j', 119896 => 'k', 119897 => 'l', 119898 => 'm', 119899 => 'n', 119900 => 'o', 119901 => 'p', 119902 => 'q', 119903 => 'r', 119904 => 's', 119905 => 't', 119906 => 'u', 119907 => 'v', 119908 => 'w', 119909 => 'x', 119910 => 'y', 119911 => 'z', 119912 => 'a', 119913 => 'b', 119914 => 'c', 119915 => 'd', 119916 => 'e', 119917 => 'f', 119918 => 'g', 119919 => 'h', 119920 => 'i', 119921 => 'j', 119922 => 'k', 119923 => 'l', 119924 => 'm', 119925 => 'n', 119926 => 'o', 119927 => 'p', 119928 => 'q', 119929 => 'r', 119930 => 's', 119931 => 't', 119932 => 'u', 119933 => 'v', 119934 => 'w', 119935 => 'x', 119936 => 'y', 119937 => 'z', 119938 => 'a', 119939 => 'b', 119940 => 'c', 119941 => 'd', 119942 => 'e', 119943 => 'f', 119944 => 'g', 119945 => 'h', 119946 => 'i', 119947 => 'j', 119948 => 'k', 119949 => 'l', 119950 => 'm', 119951 => 'n', 119952 => 'o', 119953 => 'p', 119954 => 'q', 119955 => 'r', 119956 => 's', 119957 => 't', 119958 => 'u', 119959 => 'v', 119960 => 'w', 119961 => 'x', 119962 => 'y', 119963 => 'z', 119964 => 'a', 119966 => 'c', 119967 => 'd', 119970 => 'g', 119973 => 'j', 119974 => 'k', 119977 => 'n', 119978 => 'o', 119979 => 'p', 119980 => 'q', 119982 => 's', 119983 => 't', 119984 => 'u', 119985 => 'v', 119986 => 'w', 119987 => 'x', 119988 => 'y', 119989 => 'z', 119990 => 'a', 119991 => 'b', 119992 => 'c', 119993 => 'd', 119995 => 'f', 119997 => 'h', 119998 => 'i', 119999 => 'j', 120000 => 'k', 120001 => 'l', 120002 => 'm', 120003 => 'n', 120005 => 'p', 120006 => 'q', 120007 => 'r', 120008 => 's', 120009 => 't', 120010 => 'u', 120011 => 'v', 120012 => 'w', 120013 => 'x', 120014 => 'y', 120015 => 'z', 120016 => 'a', 120017 => 'b', 120018 => 'c', 120019 => 'd', 120020 => 'e', 120021 => 'f', 120022 => 'g', 120023 => 'h', 120024 => 'i', 120025 => 'j', 120026 => 'k', 120027 => 'l', 120028 => 'm', 120029 => 'n', 120030 => 'o', 120031 => 'p', 120032 => 'q', 120033 => 'r', 120034 => 's', 120035 => 't', 120036 => 'u', 120037 => 'v', 120038 => 'w', 120039 => 'x', 120040 => 'y', 120041 => 'z', 120042 => 'a', 120043 => 'b', 120044 => 'c', 120045 => 'd', 120046 => 'e', 120047 => 'f', 120048 => 'g', 120049 => 'h', 120050 => 'i', 120051 => 'j', 120052 => 'k', 120053 => 'l', 120054 => 'm', 120055 => 'n', 120056 => 'o', 120057 => 'p', 120058 => 'q', 120059 => 'r', 120060 => 's', 120061 => 't', 120062 => 'u', 120063 => 'v', 120064 => 'w', 120065 => 'x', 120066 => 'y', 120067 => 'z', 120068 => 'a', 120069 => 'b', 120071 => 'd', 120072 => 'e', 120073 => 'f', 120074 => 'g', 120077 => 'j', 120078 => 'k', 120079 => 'l', 120080 => 'm', 120081 => 'n', 120082 => 'o', 120083 => 'p', 120084 => 'q', 120086 => 's', 120087 => 't', 120088 => 'u', 120089 => 'v', 120090 => 'w', 120091 => 'x', 120092 => 'y', 120094 => 'a', 120095 => 'b', 120096 => 'c', 120097 => 'd', 120098 => 'e', 120099 => 'f', 120100 => 'g', 120101 => 'h', 120102 => 'i', 120103 => 'j', 120104 => 'k', 120105 => 'l', 120106 => 'm', 120107 => 'n', 120108 => 'o', 120109 => 'p', 120110 => 'q', 120111 => 'r', 120112 => 's', 120113 => 't', 120114 => 'u', 120115 => 'v', 120116 => 'w', 120117 => 'x', 120118 => 'y', 120119 => 'z', 120120 => 'a', 120121 => 'b', 120123 => 'd', 120124 => 'e', 120125 => 'f', 120126 => 'g', 120128 => 'i', 120129 => 'j', 120130 => 'k', 120131 => 'l', 120132 => 'm', 120134 => 'o', 120138 => 's', 120139 => 't', 120140 => 'u', 120141 => 'v', 120142 => 'w', 120143 => 'x', 120144 => 'y', 120146 => 'a', 120147 => 'b', 120148 => 'c', 120149 => 'd', 120150 => 'e', 120151 => 'f', 120152 => 'g', 120153 => 'h', 120154 => 'i', 120155 => 'j', 120156 => 'k', 120157 => 'l', 120158 => 'm', 120159 => 'n', 120160 => 'o', 120161 => 'p', 120162 => 'q', 120163 => 'r', 120164 => 's', 120165 => 't', 120166 => 'u', 120167 => 'v', 120168 => 'w', 120169 => 'x', 120170 => 'y', 120171 => 'z', 120172 => 'a', 120173 => 'b', 120174 => 'c', 120175 => 'd', 120176 => 'e', 120177 => 'f', 120178 => 'g', 120179 => 'h', 120180 => 'i', 120181 => 'j', 120182 => 'k', 120183 => 'l', 120184 => 'm', 120185 => 'n', 120186 => 'o', 120187 => 'p', 120188 => 'q', 120189 => 'r', 120190 => 's', 120191 => 't', 120192 => 'u', 120193 => 'v', 120194 => 'w', 120195 => 'x', 120196 => 'y', 120197 => 'z', 120198 => 'a', 120199 => 'b', 120200 => 'c', 120201 => 'd', 120202 => 'e', 120203 => 'f', 120204 => 'g', 120205 => 'h', 120206 => 'i', 120207 => 'j', 120208 => 'k', 120209 => 'l', 120210 => 'm', 120211 => 'n', 120212 => 'o', 120213 => 'p', 120214 => 'q', 120215 => 'r', 120216 => 's', 120217 => 't', 120218 => 'u', 120219 => 'v', 120220 => 'w', 120221 => 'x', 120222 => 'y', 120223 => 'z', 120224 => 'a', 120225 => 'b', 120226 => 'c', 120227 => 'd', 120228 => 'e', 120229 => 'f', 120230 => 'g', 120231 => 'h', 120232 => 'i', 120233 => 'j', 120234 => 'k', 120235 => 'l', 120236 => 'm', 120237 => 'n', 120238 => 'o', 120239 => 'p', 120240 => 'q', 120241 => 'r', 120242 => 's', 120243 => 't', 120244 => 'u', 120245 => 'v', 120246 => 'w', 120247 => 'x', 120248 => 'y', 120249 => 'z', 120250 => 'a', 120251 => 'b', 120252 => 'c', 120253 => 'd', 120254 => 'e', 120255 => 'f', 120256 => 'g', 120257 => 'h', 120258 => 'i', 120259 => 'j', 120260 => 'k', 120261 => 'l', 120262 => 'm', 120263 => 'n', 120264 => 'o', 120265 => 'p', 120266 => 'q', 120267 => 'r', 120268 => 's', 120269 => 't', 120270 => 'u', 120271 => 'v', 120272 => 'w', 120273 => 'x', 120274 => 'y', 120275 => 'z', 120276 => 'a', 120277 => 'b', 120278 => 'c', 120279 => 'd', 120280 => 'e', 120281 => 'f', 120282 => 'g', 120283 => 'h', 120284 => 'i', 120285 => 'j', 120286 => 'k', 120287 => 'l', 120288 => 'm', 120289 => 'n', 120290 => 'o', 120291 => 'p', 120292 => 'q', 120293 => 'r', 120294 => 's', 120295 => 't', 120296 => 'u', 120297 => 'v', 120298 => 'w', 120299 => 'x', 120300 => 'y', 120301 => 'z', 120302 => 'a', 120303 => 'b', 120304 => 'c', 120305 => 'd', 120306 => 'e', 120307 => 'f', 120308 => 'g', 120309 => 'h', 120310 => 'i', 120311 => 'j', 120312 => 'k', 120313 => 'l', 120314 => 'm', 120315 => 'n', 120316 => 'o', 120317 => 'p', 120318 => 'q', 120319 => 'r', 120320 => 's', 120321 => 't', 120322 => 'u', 120323 => 'v', 120324 => 'w', 120325 => 'x', 120326 => 'y', 120327 => 'z', 120328 => 'a', 120329 => 'b', 120330 => 'c', 120331 => 'd', 120332 => 'e', 120333 => 'f', 120334 => 'g', 120335 => 'h', 120336 => 'i', 120337 => 'j', 120338 => 'k', 120339 => 'l', 120340 => 'm', 120341 => 'n', 120342 => 'o', 120343 => 'p', 120344 => 'q', 120345 => 'r', 120346 => 's', 120347 => 't', 120348 => 'u', 120349 => 'v', 120350 => 'w', 120351 => 'x', 120352 => 'y', 120353 => 'z', 120354 => 'a', 120355 => 'b', 120356 => 'c', 120357 => 'd', 120358 => 'e', 120359 => 'f', 120360 => 'g', 120361 => 'h', 120362 => 'i', 120363 => 'j', 120364 => 'k', 120365 => 'l', 120366 => 'm', 120367 => 'n', 120368 => 'o', 120369 => 'p', 120370 => 'q', 120371 => 'r', 120372 => 's', 120373 => 't', 120374 => 'u', 120375 => 'v', 120376 => 'w', 120377 => 'x', 120378 => 'y', 120379 => 'z', 120380 => 'a', 120381 => 'b', 120382 => 'c', 120383 => 'd', 120384 => 'e', 120385 => 'f', 120386 => 'g', 120387 => 'h', 120388 => 'i', 120389 => 'j', 120390 => 'k', 120391 => 'l', 120392 => 'm', 120393 => 'n', 120394 => 'o', 120395 => 'p', 120396 => 'q', 120397 => 'r', 120398 => 's', 120399 => 't', 120400 => 'u', 120401 => 'v', 120402 => 'w', 120403 => 'x', 120404 => 'y', 120405 => 'z', 120406 => 'a', 120407 => 'b', 120408 => 'c', 120409 => 'd', 120410 => 'e', 120411 => 'f', 120412 => 'g', 120413 => 'h', 120414 => 'i', 120415 => 'j', 120416 => 'k', 120417 => 'l', 120418 => 'm', 120419 => 'n', 120420 => 'o', 120421 => 'p', 120422 => 'q', 120423 => 'r', 120424 => 's', 120425 => 't', 120426 => 'u', 120427 => 'v', 120428 => 'w', 120429 => 'x', 120430 => 'y', 120431 => 'z', 120432 => 'a', 120433 => 'b', 120434 => 'c', 120435 => 'd', 120436 => 'e', 120437 => 'f', 120438 => 'g', 120439 => 'h', 120440 => 'i', 120441 => 'j', 120442 => 'k', 120443 => 'l', 120444 => 'm', 120445 => 'n', 120446 => 'o', 120447 => 'p', 120448 => 'q', 120449 => 'r', 120450 => 's', 120451 => 't', 120452 => 'u', 120453 => 'v', 120454 => 'w', 120455 => 'x', 120456 => 'y', 120457 => 'z', 120458 => 'a', 120459 => 'b', 120460 => 'c', 120461 => 'd', 120462 => 'e', 120463 => 'f', 120464 => 'g', 120465 => 'h', 120466 => 'i', 120467 => 'j', 120468 => 'k', 120469 => 'l', 120470 => 'm', 120471 => 'n', 120472 => 'o', 120473 => 'p', 120474 => 'q', 120475 => 'r', 120476 => 's', 120477 => 't', 120478 => 'u', 120479 => 'v', 120480 => 'w', 120481 => 'x', 120482 => 'y', 120483 => 'z', 120484 => 'ı', 120485 => 'È·', 120488 => 'α', 120489 => 'β', 120490 => 'γ', 120491 => 'δ', 120492 => 'ε', 120493 => 'ζ', 120494 => 'η', 120495 => 'θ', 120496 => 'ι', 120497 => 'κ', 120498 => 'λ', 120499 => 'μ', 120500 => 'ν', 120501 => 'ξ', 120502 => 'ο', 120503 => 'Ï€', 120504 => 'Ï', 120505 => 'θ', 120506 => 'σ', 120507 => 'Ï„', 120508 => 'Ï…', 120509 => 'φ', 120510 => 'χ', 120511 => 'ψ', 120512 => 'ω', 120513 => '∇', 120514 => 'α', 120515 => 'β', 120516 => 'γ', 120517 => 'δ', 120518 => 'ε', 120519 => 'ζ', 120520 => 'η', 120521 => 'θ', 120522 => 'ι', 120523 => 'κ', 120524 => 'λ', 120525 => 'μ', 120526 => 'ν', 120527 => 'ξ', 120528 => 'ο', 120529 => 'Ï€', 120530 => 'Ï', 120531 => 'σ', 120532 => 'σ', 120533 => 'Ï„', 120534 => 'Ï…', 120535 => 'φ', 120536 => 'χ', 120537 => 'ψ', 120538 => 'ω', 120539 => '∂', 120540 => 'ε', 120541 => 'θ', 120542 => 'κ', 120543 => 'φ', 120544 => 'Ï', 120545 => 'Ï€', 120546 => 'α', 120547 => 'β', 120548 => 'γ', 120549 => 'δ', 120550 => 'ε', 120551 => 'ζ', 120552 => 'η', 120553 => 'θ', 120554 => 'ι', 120555 => 'κ', 120556 => 'λ', 120557 => 'μ', 120558 => 'ν', 120559 => 'ξ', 120560 => 'ο', 120561 => 'Ï€', 120562 => 'Ï', 120563 => 'θ', 120564 => 'σ', 120565 => 'Ï„', 120566 => 'Ï…', 120567 => 'φ', 120568 => 'χ', 120569 => 'ψ', 120570 => 'ω', 120571 => '∇', 120572 => 'α', 120573 => 'β', 120574 => 'γ', 120575 => 'δ', 120576 => 'ε', 120577 => 'ζ', 120578 => 'η', 120579 => 'θ', 120580 => 'ι', 120581 => 'κ', 120582 => 'λ', 120583 => 'μ', 120584 => 'ν', 120585 => 'ξ', 120586 => 'ο', 120587 => 'Ï€', 120588 => 'Ï', 120589 => 'σ', 120590 => 'σ', 120591 => 'Ï„', 120592 => 'Ï…', 120593 => 'φ', 120594 => 'χ', 120595 => 'ψ', 120596 => 'ω', 120597 => '∂', 120598 => 'ε', 120599 => 'θ', 120600 => 'κ', 120601 => 'φ', 120602 => 'Ï', 120603 => 'Ï€', 120604 => 'α', 120605 => 'β', 120606 => 'γ', 120607 => 'δ', 120608 => 'ε', 120609 => 'ζ', 120610 => 'η', 120611 => 'θ', 120612 => 'ι', 120613 => 'κ', 120614 => 'λ', 120615 => 'μ', 120616 => 'ν', 120617 => 'ξ', 120618 => 'ο', 120619 => 'Ï€', 120620 => 'Ï', 120621 => 'θ', 120622 => 'σ', 120623 => 'Ï„', 120624 => 'Ï…', 120625 => 'φ', 120626 => 'χ', 120627 => 'ψ', 120628 => 'ω', 120629 => '∇', 120630 => 'α', 120631 => 'β', 120632 => 'γ', 120633 => 'δ', 120634 => 'ε', 120635 => 'ζ', 120636 => 'η', 120637 => 'θ', 120638 => 'ι', 120639 => 'κ', 120640 => 'λ', 120641 => 'μ', 120642 => 'ν', 120643 => 'ξ', 120644 => 'ο', 120645 => 'Ï€', 120646 => 'Ï', 120647 => 'σ', 120648 => 'σ', 120649 => 'Ï„', 120650 => 'Ï…', 120651 => 'φ', 120652 => 'χ', 120653 => 'ψ', 120654 => 'ω', 120655 => '∂', 120656 => 'ε', 120657 => 'θ', 120658 => 'κ', 120659 => 'φ', 120660 => 'Ï', 120661 => 'Ï€', 120662 => 'α', 120663 => 'β', 120664 => 'γ', 120665 => 'δ', 120666 => 'ε', 120667 => 'ζ', 120668 => 'η', 120669 => 'θ', 120670 => 'ι', 120671 => 'κ', 120672 => 'λ', 120673 => 'μ', 120674 => 'ν', 120675 => 'ξ', 120676 => 'ο', 120677 => 'Ï€', 120678 => 'Ï', 120679 => 'θ', 120680 => 'σ', 120681 => 'Ï„', 120682 => 'Ï…', 120683 => 'φ', 120684 => 'χ', 120685 => 'ψ', 120686 => 'ω', 120687 => '∇', 120688 => 'α', 120689 => 'β', 120690 => 'γ', 120691 => 'δ', 120692 => 'ε', 120693 => 'ζ', 120694 => 'η', 120695 => 'θ', 120696 => 'ι', 120697 => 'κ', 120698 => 'λ', 120699 => 'μ', 120700 => 'ν', 120701 => 'ξ', 120702 => 'ο', 120703 => 'Ï€', 120704 => 'Ï', 120705 => 'σ', 120706 => 'σ', 120707 => 'Ï„', 120708 => 'Ï…', 120709 => 'φ', 120710 => 'χ', 120711 => 'ψ', 120712 => 'ω', 120713 => '∂', 120714 => 'ε', 120715 => 'θ', 120716 => 'κ', 120717 => 'φ', 120718 => 'Ï', 120719 => 'Ï€', 120720 => 'α', 120721 => 'β', 120722 => 'γ', 120723 => 'δ', 120724 => 'ε', 120725 => 'ζ', 120726 => 'η', 120727 => 'θ', 120728 => 'ι', 120729 => 'κ', 120730 => 'λ', 120731 => 'μ', 120732 => 'ν', 120733 => 'ξ', 120734 => 'ο', 120735 => 'Ï€', 120736 => 'Ï', 120737 => 'θ', 120738 => 'σ', 120739 => 'Ï„', 120740 => 'Ï…', 120741 => 'φ', 120742 => 'χ', 120743 => 'ψ', 120744 => 'ω', 120745 => '∇', 120746 => 'α', 120747 => 'β', 120748 => 'γ', 120749 => 'δ', 120750 => 'ε', 120751 => 'ζ', 120752 => 'η', 120753 => 'θ', 120754 => 'ι', 120755 => 'κ', 120756 => 'λ', 120757 => 'μ', 120758 => 'ν', 120759 => 'ξ', 120760 => 'ο', 120761 => 'Ï€', 120762 => 'Ï', 120763 => 'σ', 120764 => 'σ', 120765 => 'Ï„', 120766 => 'Ï…', 120767 => 'φ', 120768 => 'χ', 120769 => 'ψ', 120770 => 'ω', 120771 => '∂', 120772 => 'ε', 120773 => 'θ', 120774 => 'κ', 120775 => 'φ', 120776 => 'Ï', 120777 => 'Ï€', 120778 => 'Ï', 120779 => 'Ï', 120782 => '0', 120783 => '1', 120784 => '2', 120785 => '3', 120786 => '4', 120787 => '5', 120788 => '6', 120789 => '7', 120790 => '8', 120791 => '9', 120792 => '0', 120793 => '1', 120794 => '2', 120795 => '3', 120796 => '4', 120797 => '5', 120798 => '6', 120799 => '7', 120800 => '8', 120801 => '9', 120802 => '0', 120803 => '1', 120804 => '2', 120805 => '3', 120806 => '4', 120807 => '5', 120808 => '6', 120809 => '7', 120810 => '8', 120811 => '9', 120812 => '0', 120813 => '1', 120814 => '2', 120815 => '3', 120816 => '4', 120817 => '5', 120818 => '6', 120819 => '7', 120820 => '8', 120821 => '9', 120822 => '0', 120823 => '1', 120824 => '2', 120825 => '3', 120826 => '4', 120827 => '5', 120828 => '6', 120829 => '7', 120830 => '8', 120831 => '9', 125184 => '𞤢', 125185 => '𞤣', 125186 => '𞤤', 125187 => '𞤥', 125188 => '𞤦', 125189 => '𞤧', 125190 => '𞤨', 125191 => '𞤩', 125192 => '𞤪', 125193 => '𞤫', 125194 => '𞤬', 125195 => '𞤭', 125196 => '𞤮', 125197 => '𞤯', 125198 => '𞤰', 125199 => '𞤱', 125200 => '𞤲', 125201 => '𞤳', 125202 => '𞤴', 125203 => '𞤵', 125204 => '𞤶', 125205 => '𞤷', 125206 => '𞤸', 125207 => '𞤹', 125208 => '𞤺', 125209 => '𞤻', 125210 => '𞤼', 125211 => '𞤽', 125212 => '𞤾', 125213 => '𞤿', 125214 => '𞥀', 125215 => 'ðž¥', 125216 => '𞥂', 125217 => '𞥃', 126464 => 'ا', 126465 => 'ب', 126466 => 'ج', 126467 => 'د', 126469 => 'Ùˆ', 126470 => 'ز', 126471 => 'Ø­', 126472 => 'Ø·', 126473 => 'ÙŠ', 126474 => 'Ùƒ', 126475 => 'Ù„', 126476 => 'Ù…', 126477 => 'Ù†', 126478 => 'س', 126479 => 'ع', 126480 => 'Ù', 126481 => 'ص', 126482 => 'Ù‚', 126483 => 'ر', 126484 => 'Ø´', 126485 => 'ت', 126486 => 'Ø«', 126487 => 'Ø®', 126488 => 'ذ', 126489 => 'ض', 126490 => 'ظ', 126491 => 'غ', 126492 => 'Ù®', 126493 => 'Úº', 126494 => 'Ú¡', 126495 => 'Ù¯', 126497 => 'ب', 126498 => 'ج', 126500 => 'Ù‡', 126503 => 'Ø­', 126505 => 'ÙŠ', 126506 => 'Ùƒ', 126507 => 'Ù„', 126508 => 'Ù…', 126509 => 'Ù†', 126510 => 'س', 126511 => 'ع', 126512 => 'Ù', 126513 => 'ص', 126514 => 'Ù‚', 126516 => 'Ø´', 126517 => 'ت', 126518 => 'Ø«', 126519 => 'Ø®', 126521 => 'ض', 126523 => 'غ', 126530 => 'ج', 126535 => 'Ø­', 126537 => 'ÙŠ', 126539 => 'Ù„', 126541 => 'Ù†', 126542 => 'س', 126543 => 'ع', 126545 => 'ص', 126546 => 'Ù‚', 126548 => 'Ø´', 126551 => 'Ø®', 126553 => 'ض', 126555 => 'غ', 126557 => 'Úº', 126559 => 'Ù¯', 126561 => 'ب', 126562 => 'ج', 126564 => 'Ù‡', 126567 => 'Ø­', 126568 => 'Ø·', 126569 => 'ÙŠ', 126570 => 'Ùƒ', 126572 => 'Ù…', 126573 => 'Ù†', 126574 => 'س', 126575 => 'ع', 126576 => 'Ù', 126577 => 'ص', 126578 => 'Ù‚', 126580 => 'Ø´', 126581 => 'ت', 126582 => 'Ø«', 126583 => 'Ø®', 126585 => 'ض', 126586 => 'ظ', 126587 => 'غ', 126588 => 'Ù®', 126590 => 'Ú¡', 126592 => 'ا', 126593 => 'ب', 126594 => 'ج', 126595 => 'د', 126596 => 'Ù‡', 126597 => 'Ùˆ', 126598 => 'ز', 126599 => 'Ø­', 126600 => 'Ø·', 126601 => 'ÙŠ', 126603 => 'Ù„', 126604 => 'Ù…', 126605 => 'Ù†', 126606 => 'س', 126607 => 'ع', 126608 => 'Ù', 126609 => 'ص', 126610 => 'Ù‚', 126611 => 'ر', 126612 => 'Ø´', 126613 => 'ت', 126614 => 'Ø«', 126615 => 'Ø®', 126616 => 'ذ', 126617 => 'ض', 126618 => 'ظ', 126619 => 'غ', 126625 => 'ب', 126626 => 'ج', 126627 => 'د', 126629 => 'Ùˆ', 126630 => 'ز', 126631 => 'Ø­', 126632 => 'Ø·', 126633 => 'ÙŠ', 126635 => 'Ù„', 126636 => 'Ù…', 126637 => 'Ù†', 126638 => 'س', 126639 => 'ع', 126640 => 'Ù', 126641 => 'ص', 126642 => 'Ù‚', 126643 => 'ر', 126644 => 'Ø´', 126645 => 'ت', 126646 => 'Ø«', 126647 => 'Ø®', 126648 => 'ذ', 126649 => 'ض', 126650 => 'ظ', 126651 => 'غ', 127274 => '〔s〕', 127275 => 'c', 127276 => 'r', 127277 => 'cd', 127278 => 'wz', 127280 => 'a', 127281 => 'b', 127282 => 'c', 127283 => 'd', 127284 => 'e', 127285 => 'f', 127286 => 'g', 127287 => 'h', 127288 => 'i', 127289 => 'j', 127290 => 'k', 127291 => 'l', 127292 => 'm', 127293 => 'n', 127294 => 'o', 127295 => 'p', 127296 => 'q', 127297 => 'r', 127298 => 's', 127299 => 't', 127300 => 'u', 127301 => 'v', 127302 => 'w', 127303 => 'x', 127304 => 'y', 127305 => 'z', 127306 => 'hv', 127307 => 'mv', 127308 => 'sd', 127309 => 'ss', 127310 => 'ppv', 127311 => 'wc', 127338 => 'mc', 127339 => 'md', 127340 => 'mr', 127376 => 'dj', 127488 => 'ã»ã‹', 127489 => 'ココ', 127490 => 'サ', 127504 => '手', 127505 => 'å­—', 127506 => 'åŒ', 127507 => 'デ', 127508 => '二', 127509 => '多', 127510 => 'è§£', 127511 => '天', 127512 => '交', 127513 => '映', 127514 => 'ç„¡', 127515 => 'æ–™', 127516 => 'å‰', 127517 => '後', 127518 => 'å†', 127519 => 'æ–°', 127520 => 'åˆ', 127521 => '終', 127522 => '生', 127523 => '販', 127524 => '声', 127525 => 'å¹', 127526 => 'æ¼”', 127527 => '投', 127528 => 'æ•', 127529 => '一', 127530 => '三', 127531 => 'éŠ', 127532 => 'å·¦', 127533 => '中', 127534 => 'å³', 127535 => '指', 127536 => 'èµ°', 127537 => '打', 127538 => 'ç¦', 127539 => '空', 127540 => 'åˆ', 127541 => '満', 127542 => '有', 127543 => '月', 127544 => '申', 127545 => '割', 127546 => 'å–¶', 127547 => 'é…', 127552 => '〔本〕', 127553 => '〔三〕', 127554 => '〔二〕', 127555 => '〔安〕', 127556 => '〔点〕', 127557 => '〔打〕', 127558 => '〔盗〕', 127559 => '〔å‹ã€•', 127560 => '〔敗〕', 127568 => 'å¾—', 127569 => 'å¯', 130032 => '0', 130033 => '1', 130034 => '2', 130035 => '3', 130036 => '4', 130037 => '5', 130038 => '6', 130039 => '7', 130040 => '8', 130041 => '9', 194560 => '丽', 194561 => '丸', 194562 => 'ä¹', 194563 => 'ð „¢', 194564 => 'ä½ ', 194565 => 'ä¾®', 194566 => 'ä¾»', 194567 => '倂', 194568 => 'åº', 194569 => 'å‚™', 194570 => '僧', 194571 => 'åƒ', 194572 => 'ã’ž', 194573 => '𠘺', 194574 => 'å…', 194575 => 'å…”', 194576 => 'å…¤', 194577 => 'å…·', 194578 => '𠔜', 194579 => 'ã’¹', 194580 => 'å…§', 194581 => 'å†', 194582 => 'ð •‹', 194583 => '冗', 194584 => '冤', 194585 => '仌', 194586 => '冬', 194587 => '况', 194588 => '𩇟', 194589 => '凵', 194590 => '刃', 194591 => '㓟', 194592 => '刻', 194593 => '剆', 194594 => '割', 194595 => '剷', 194596 => '㔕', 194597 => '勇', 194598 => '勉', 194599 => '勤', 194600 => '勺', 194601 => '包', 194602 => '匆', 194603 => '北', 194604 => 'å‰', 194605 => 'å‘', 194606 => 'åš', 194607 => 'å³', 194608 => 'å½', 194609 => 'å¿', 194610 => 'å¿', 194611 => 'å¿', 194612 => '𠨬', 194613 => 'ç°', 194614 => 'åŠ', 194615 => 'åŸ', 194616 => 'ð ­£', 194617 => 'å«', 194618 => 'å±', 194619 => 'å†', 194620 => 'å’ž', 194621 => 'å¸', 194622 => '呈', 194623 => '周', 194624 => 'å’¢', 194625 => 'å“¶', 194626 => 'å”', 194627 => 'å•“', 194628 => 'å•£', 194629 => 'å–„', 194630 => 'å–„', 194631 => 'å–™', 194632 => 'å–«', 194633 => 'å–³', 194634 => 'å—‚', 194635 => '圖', 194636 => '嘆', 194637 => '圗', 194638 => '噑', 194639 => 'å™´', 194640 => '切', 194641 => '壮', 194642 => '城', 194643 => '埴', 194644 => 'å ', 194645 => 'åž‹', 194646 => 'å ²', 194647 => 'å ±', 194648 => '墬', 194649 => '𡓤', 194650 => '売', 194651 => '壷', 194652 => '夆', 194653 => '多', 194654 => '夢', 194655 => '奢', 194656 => '𡚨', 194657 => '𡛪', 194658 => '姬', 194659 => '娛', 194660 => '娧', 194661 => '姘', 194662 => '婦', 194663 => 'ã›®', 194665 => '嬈', 194666 => '嬾', 194667 => '嬾', 194668 => '𡧈', 194669 => '寃', 194670 => '寘', 194671 => '寧', 194672 => '寳', 194673 => '𡬘', 194674 => '寿', 194675 => 'å°†', 194677 => 'å°¢', 194678 => 'ãž', 194679 => 'å± ', 194680 => 'å±®', 194681 => 'å³€', 194682 => 'å²', 194683 => 'ð¡·¤', 194684 => '嵃', 194685 => 'ð¡·¦', 194686 => 'åµ®', 194687 => '嵫', 194688 => 'åµ¼', 194689 => 'å·¡', 194690 => 'å·¢', 194691 => 'ã ¯', 194692 => 'å·½', 194693 => '帨', 194694 => '帽', 194695 => '幩', 194696 => 'ã¡¢', 194697 => '𢆃', 194698 => '㡼', 194699 => '庰', 194700 => '庳', 194701 => '庶', 194702 => '廊', 194703 => '𪎒', 194704 => '廾', 194705 => '𢌱', 194706 => '𢌱', 194707 => 'èˆ', 194708 => 'å¼¢', 194709 => 'å¼¢', 194710 => '㣇', 194711 => '𣊸', 194712 => '𦇚', 194713 => 'å½¢', 194714 => '彫', 194715 => '㣣', 194716 => '徚', 194717 => 'å¿', 194718 => 'å¿—', 194719 => '忹', 194720 => 'æ‚', 194721 => '㤺', 194722 => '㤜', 194723 => 'æ‚”', 194724 => '𢛔', 194725 => '惇', 194726 => 'æ…ˆ', 194727 => 'æ…Œ', 194728 => 'æ…Ž', 194729 => 'æ…Œ', 194730 => 'æ…º', 194731 => '憎', 194732 => '憲', 194733 => '憤', 194734 => '憯', 194735 => '懞', 194736 => '懲', 194737 => '懶', 194738 => 'æˆ', 194739 => '戛', 194740 => 'æ‰', 194741 => '抱', 194742 => 'æ‹”', 194743 => 'æ', 194744 => '𢬌', 194745 => '挽', 194746 => '拼', 194747 => 'æ¨', 194748 => '掃', 194749 => 'æ¤', 194750 => '𢯱', 194751 => 'æ¢', 194752 => 'æ…', 194753 => '掩', 194754 => '㨮', 194755 => 'æ‘©', 194756 => '摾', 194757 => 'æ’', 194758 => 'æ‘·', 194759 => '㩬', 194760 => 'æ•', 194761 => '敬', 194762 => '𣀊', 194763 => 'æ—£', 194764 => '書', 194765 => '晉', 194766 => '㬙', 194767 => 'æš‘', 194768 => '㬈', 194769 => '㫤', 194770 => '冒', 194771 => '冕', 194772 => '最', 194773 => 'æšœ', 194774 => 'è‚­', 194775 => 'ä™', 194776 => '朗', 194777 => '望', 194778 => '朡', 194779 => 'æž', 194780 => 'æ“', 194781 => 'ð£ƒ', 194782 => 'ã­‰', 194783 => '柺', 194784 => 'æž…', 194785 => 'æ¡’', 194786 => '梅', 194787 => '𣑭', 194788 => '梎', 194789 => 'æ Ÿ', 194790 => '椔', 194791 => 'ã®', 194792 => '楂', 194793 => '榣', 194794 => '槪', 194795 => '檨', 194796 => '𣚣', 194797 => 'æ«›', 194798 => 'ã°˜', 194799 => '次', 194800 => '𣢧', 194801 => 'æ­”', 194802 => '㱎', 194803 => 'æ­²', 194804 => '殟', 194805 => '殺', 194806 => 'æ®»', 194807 => 'ð£ª', 194808 => 'ð¡´‹', 194809 => '𣫺', 194810 => '汎', 194811 => '𣲼', 194812 => '沿', 194813 => 'æ³', 194814 => 'æ±§', 194815 => 'æ´–', 194816 => 'æ´¾', 194817 => 'æµ·', 194818 => 'æµ', 194819 => '浩', 194820 => '浸', 194821 => 'æ¶…', 194822 => '𣴞', 194823 => 'æ´´', 194824 => '港', 194825 => 'æ¹®', 194826 => 'ã´³', 194827 => '滋', 194828 => '滇', 194829 => '𣻑', 194830 => 'æ·¹', 194831 => 'æ½®', 194832 => '𣽞', 194833 => '𣾎', 194834 => '濆', 194835 => '瀹', 194836 => '瀞', 194837 => '瀛', 194838 => 'ã¶–', 194839 => 'çŠ', 194840 => 'ç½', 194841 => 'ç·', 194842 => 'ç‚­', 194843 => '𠔥', 194844 => 'ç……', 194845 => '𤉣', 194846 => '熜', 194848 => '爨', 194849 => '爵', 194850 => 'ç‰', 194851 => '𤘈', 194852 => '犀', 194853 => '犕', 194854 => '𤜵', 194855 => '𤠔', 194856 => 'çº', 194857 => '王', 194858 => '㺬', 194859 => '玥', 194860 => '㺸', 194861 => '㺸', 194862 => '瑇', 194863 => '瑜', 194864 => '瑱', 194865 => 'ç’…', 194866 => '瓊', 194867 => 'ã¼›', 194868 => '甤', 194869 => '𤰶', 194870 => '甾', 194871 => '𤲒', 194872 => 'ç•°', 194873 => '𢆟', 194874 => 'ç˜', 194875 => '𤾡', 194876 => '𤾸', 194877 => 'ð¥„', 194878 => '㿼', 194879 => '䀈', 194880 => 'ç›´', 194881 => '𥃳', 194882 => '𥃲', 194883 => '𥄙', 194884 => '𥄳', 194885 => '眞', 194886 => '真', 194887 => '真', 194888 => 'çŠ', 194889 => '䀹', 194890 => 'çž‹', 194891 => 'ä†', 194892 => 'ä‚–', 194893 => 'ð¥', 194894 => '硎', 194895 => '碌', 194896 => '磌', 194897 => '䃣', 194898 => '𥘦', 194899 => '祖', 194900 => '𥚚', 194901 => '𥛅', 194902 => 'ç¦', 194903 => 'ç§«', 194904 => '䄯', 194905 => 'ç©€', 194906 => '穊', 194907 => 'ç©', 194908 => '𥥼', 194909 => '𥪧', 194910 => '𥪧', 194912 => '䈂', 194913 => '𥮫', 194914 => '篆', 194915 => '築', 194916 => '䈧', 194917 => '𥲀', 194918 => 'ç³’', 194919 => '䊠', 194920 => '糨', 194921 => 'ç³£', 194922 => 'ç´€', 194923 => '𥾆', 194924 => 'çµ£', 194925 => 'äŒ', 194926 => 'ç·‡', 194927 => '縂', 194928 => 'ç¹…', 194929 => '䌴', 194930 => '𦈨', 194931 => '𦉇', 194932 => 'ä™', 194933 => '𦋙', 194934 => '罺', 194935 => '𦌾', 194936 => '羕', 194937 => '翺', 194938 => '者', 194939 => '𦓚', 194940 => '𦔣', 194941 => 'è ', 194942 => '𦖨', 194943 => 'è°', 194944 => 'ð£Ÿ', 194945 => 'ä•', 194946 => '育', 194947 => '脃', 194948 => 'ä‹', 194949 => '脾', 194950 => '媵', 194951 => '𦞧', 194952 => '𦞵', 194953 => '𣎓', 194954 => '𣎜', 194955 => 'èˆ', 194956 => '舄', 194957 => '辞', 194958 => 'ä‘«', 194959 => '芑', 194960 => '芋', 194961 => 'èŠ', 194962 => '劳', 194963 => '花', 194964 => '芳', 194965 => '芽', 194966 => '苦', 194967 => '𦬼', 194968 => 'è‹¥', 194969 => 'èŒ', 194970 => 'è£', 194971 => '莭', 194972 => '茣', 194973 => '莽', 194974 => 'è§', 194975 => 'è‘—', 194976 => 'è“', 194977 => 'èŠ', 194978 => 'èŒ', 194979 => 'èœ', 194980 => '𦰶', 194981 => '𦵫', 194982 => '𦳕', 194983 => '䔫', 194984 => '蓱', 194985 => '蓳', 194986 => 'è”–', 194987 => 'ð§Š', 194988 => '蕤', 194989 => '𦼬', 194990 => 'ä•', 194991 => 'ä•¡', 194992 => '𦾱', 194993 => '𧃒', 194994 => 'ä•«', 194995 => 'è™', 194996 => '虜', 194997 => 'è™§', 194998 => '虩', 194999 => 'èš©', 195000 => '蚈', 195001 => '蜎', 195002 => '蛢', 195003 => 'è¹', 195004 => '蜨', 195005 => 'è«', 195006 => '螆', 195008 => '蟡', 195009 => 'è ', 195010 => 'ä—¹', 195011 => 'è¡ ', 195012 => 'è¡£', 195013 => 'ð§™§', 195014 => '裗', 195015 => '裞', 195016 => '䘵', 195017 => '裺', 195018 => 'ã’»', 195019 => 'ð§¢®', 195020 => '𧥦', 195021 => 'äš¾', 195022 => '䛇', 195023 => '誠', 195024 => 'è«­', 195025 => '變', 195026 => '豕', 195027 => '𧲨', 195028 => '貫', 195029 => 'è³', 195030 => 'è´›', 195031 => 'èµ·', 195032 => '𧼯', 195033 => 'ð  „', 195034 => 'è·‹', 195035 => 'è¶¼', 195036 => 'è·°', 195037 => '𠣞', 195038 => 'è»”', 195039 => '輸', 195040 => '𨗒', 195041 => '𨗭', 195042 => 'é‚”', 195043 => '郱', 195044 => 'é„‘', 195045 => '𨜮', 195046 => 'é„›', 195047 => '鈸', 195048 => 'é‹—', 195049 => '鋘', 195050 => '鉼', 195051 => 'é¹', 195052 => 'é•', 195053 => '𨯺', 195054 => 'é–‹', 195055 => '䦕', 195056 => 'é–·', 195057 => '𨵷', 195058 => '䧦', 195059 => '雃', 195060 => 'å¶²', 195061 => '霣', 195062 => 'ð©……', 195063 => '𩈚', 195064 => 'ä©®', 195065 => 'ä©¶', 195066 => '韠', 195067 => 'ð©Š', 195068 => '䪲', 195069 => 'ð©’–', 195070 => 'é ‹', 195071 => 'é ‹', 195072 => 'é ©', 195073 => 'ð©–¶', 195074 => '飢', 195075 => '䬳', 195076 => '餩', 195077 => '馧', 195078 => 'é§‚', 195079 => 'é§¾', 195080 => '䯎', 195081 => '𩬰', 195082 => '鬒', 195083 => 'é±€', 195084 => 'é³½', 195085 => '䳎', 195086 => 'ä³­', 195087 => 'éµ§', 195088 => '𪃎', 195089 => '䳸', 195090 => '𪄅', 195091 => '𪈎', 195092 => '𪊑', 195093 => '麻', 195094 => 'äµ–', 195095 => '黹', 195096 => '黾', 195097 => 'é¼…', 195098 => 'é¼', 195099 => 'é¼–', 195100 => 'é¼»', 195101 => '𪘀'); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/virama.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/virama.php new file mode 100644 index 0000000..70ec59f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/Resources/unidata/virama.php @@ -0,0 +1,5 @@ + 9, 2509 => 9, 2637 => 9, 2765 => 9, 2893 => 9, 3021 => 9, 3149 => 9, 3277 => 9, 3387 => 9, 3388 => 9, 3405 => 9, 3530 => 9, 3642 => 9, 3770 => 9, 3972 => 9, 4153 => 9, 4154 => 9, 5908 => 9, 5940 => 9, 6098 => 9, 6752 => 9, 6980 => 9, 7082 => 9, 7083 => 9, 7154 => 9, 7155 => 9, 11647 => 9, 43014 => 9, 43052 => 9, 43204 => 9, 43347 => 9, 43456 => 9, 43766 => 9, 44013 => 9, 68159 => 9, 69702 => 9, 69759 => 9, 69817 => 9, 69939 => 9, 69940 => 9, 70080 => 9, 70197 => 9, 70378 => 9, 70477 => 9, 70722 => 9, 70850 => 9, 71103 => 9, 71231 => 9, 71350 => 9, 71467 => 9, 71737 => 9, 71997 => 9, 71998 => 9, 72160 => 9, 72244 => 9, 72263 => 9, 72345 => 9, 72767 => 9, 73028 => 9, 73029 => 9, 73111 => 9); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/bootstrap.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/bootstrap.php new file mode 100644 index 0000000..11a4db2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/bootstrap.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn as p; + +if (extension_loaded('intl')) { + return; +} + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!defined('U_IDNA_PROHIBITED_ERROR')) { + define('U_IDNA_PROHIBITED_ERROR', 66560); +} +if (!defined('U_IDNA_ERROR_START')) { + define('U_IDNA_ERROR_START', 66560); +} +if (!defined('U_IDNA_UNASSIGNED_ERROR')) { + define('U_IDNA_UNASSIGNED_ERROR', 66561); +} +if (!defined('U_IDNA_CHECK_BIDI_ERROR')) { + define('U_IDNA_CHECK_BIDI_ERROR', 66562); +} +if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) { + define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563); +} +if (!defined('U_IDNA_ACE_PREFIX_ERROR')) { + define('U_IDNA_ACE_PREFIX_ERROR', 66564); +} +if (!defined('U_IDNA_VERIFICATION_ERROR')) { + define('U_IDNA_VERIFICATION_ERROR', 66565); +} +if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) { + define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566); +} +if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) { + define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567); +} +if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) { + define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568); +} +if (!defined('U_IDNA_ERROR_LIMIT')) { + define('U_IDNA_ERROR_LIMIT', 66569); +} +if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) { + define('U_STRINGPREP_PROHIBITED_ERROR', 66560); +} +if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) { + define('U_STRINGPREP_UNASSIGNED_ERROR', 66561); +} +if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) { + define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562); +} +if (!defined('IDNA_DEFAULT')) { + define('IDNA_DEFAULT', 0); +} +if (!defined('IDNA_ALLOW_UNASSIGNED')) { + define('IDNA_ALLOW_UNASSIGNED', 1); +} +if (!defined('IDNA_USE_STD3_RULES')) { + define('IDNA_USE_STD3_RULES', 2); +} +if (!defined('IDNA_CHECK_BIDI')) { + define('IDNA_CHECK_BIDI', 4); +} +if (!defined('IDNA_CHECK_CONTEXTJ')) { + define('IDNA_CHECK_CONTEXTJ', 8); +} +if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) { + define('IDNA_NONTRANSITIONAL_TO_ASCII', 16); +} +if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) { + define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32); +} +if (!defined('INTL_IDNA_VARIANT_2003')) { + define('INTL_IDNA_VARIANT_2003', 0); +} +if (!defined('INTL_IDNA_VARIANT_UTS46')) { + define('INTL_IDNA_VARIANT_UTS46', 1); +} +if (!defined('IDNA_ERROR_EMPTY_LABEL')) { + define('IDNA_ERROR_EMPTY_LABEL', 1); +} +if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) { + define('IDNA_ERROR_LABEL_TOO_LONG', 2); +} +if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) { + define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4); +} +if (!defined('IDNA_ERROR_LEADING_HYPHEN')) { + define('IDNA_ERROR_LEADING_HYPHEN', 8); +} +if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) { + define('IDNA_ERROR_TRAILING_HYPHEN', 16); +} +if (!defined('IDNA_ERROR_HYPHEN_3_4')) { + define('IDNA_ERROR_HYPHEN_3_4', 32); +} +if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) { + define('IDNA_ERROR_LEADING_COMBINING_MARK', 64); +} +if (!defined('IDNA_ERROR_DISALLOWED')) { + define('IDNA_ERROR_DISALLOWED', 128); +} +if (!defined('IDNA_ERROR_PUNYCODE')) { + define('IDNA_ERROR_PUNYCODE', 256); +} +if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) { + define('IDNA_ERROR_LABEL_HAS_DOT', 512); +} +if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) { + define('IDNA_ERROR_INVALID_ACE_LABEL', 1024); +} +if (!defined('IDNA_ERROR_BIDI')) { + define('IDNA_ERROR_BIDI', 2048); +} +if (!defined('IDNA_ERROR_CONTEXTJ')) { + define('IDNA_ERROR_CONTEXTJ', 4096); +} + +if (\PHP_VERSION_ID < 70400) { + if (!function_exists('idn_to_ascii')) { + function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } + } + if (!function_exists('idn_to_utf8')) { + function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_2003, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } + } +} else { + if (!function_exists('idn_to_ascii')) { + function idn_to_ascii($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } + } + if (!function_exists('idn_to_utf8')) { + function idn_to_utf8($domain, $flags = 0, $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/bootstrap80.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/bootstrap80.php new file mode 100644 index 0000000..5b5638f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-intl-idn/bootstrap80.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +use PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn as p; +if (!\defined('U_IDNA_PROHIBITED_ERROR')) { + \define('U_IDNA_PROHIBITED_ERROR', 66560); +} +if (!\defined('U_IDNA_ERROR_START')) { + \define('U_IDNA_ERROR_START', 66560); +} +if (!\defined('U_IDNA_UNASSIGNED_ERROR')) { + \define('U_IDNA_UNASSIGNED_ERROR', 66561); +} +if (!\defined('U_IDNA_CHECK_BIDI_ERROR')) { + \define('U_IDNA_CHECK_BIDI_ERROR', 66562); +} +if (!\defined('U_IDNA_STD3_ASCII_RULES_ERROR')) { + \define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563); +} +if (!\defined('U_IDNA_ACE_PREFIX_ERROR')) { + \define('U_IDNA_ACE_PREFIX_ERROR', 66564); +} +if (!\defined('U_IDNA_VERIFICATION_ERROR')) { + \define('U_IDNA_VERIFICATION_ERROR', 66565); +} +if (!\defined('U_IDNA_LABEL_TOO_LONG_ERROR')) { + \define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566); +} +if (!\defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) { + \define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567); +} +if (!\defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) { + \define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568); +} +if (!\defined('U_IDNA_ERROR_LIMIT')) { + \define('U_IDNA_ERROR_LIMIT', 66569); +} +if (!\defined('U_STRINGPREP_PROHIBITED_ERROR')) { + \define('U_STRINGPREP_PROHIBITED_ERROR', 66560); +} +if (!\defined('U_STRINGPREP_UNASSIGNED_ERROR')) { + \define('U_STRINGPREP_UNASSIGNED_ERROR', 66561); +} +if (!\defined('U_STRINGPREP_CHECK_BIDI_ERROR')) { + \define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562); +} +if (!\defined('IDNA_DEFAULT')) { + \define('IDNA_DEFAULT', 0); +} +if (!\defined('IDNA_ALLOW_UNASSIGNED')) { + \define('IDNA_ALLOW_UNASSIGNED', 1); +} +if (!\defined('IDNA_USE_STD3_RULES')) { + \define('IDNA_USE_STD3_RULES', 2); +} +if (!\defined('IDNA_CHECK_BIDI')) { + \define('IDNA_CHECK_BIDI', 4); +} +if (!\defined('IDNA_CHECK_CONTEXTJ')) { + \define('IDNA_CHECK_CONTEXTJ', 8); +} +if (!\defined('IDNA_NONTRANSITIONAL_TO_ASCII')) { + \define('IDNA_NONTRANSITIONAL_TO_ASCII', 16); +} +if (!\defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) { + \define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32); +} +if (!\defined('INTL_IDNA_VARIANT_UTS46')) { + \define('INTL_IDNA_VARIANT_UTS46', 1); +} +if (!\defined('IDNA_ERROR_EMPTY_LABEL')) { + \define('IDNA_ERROR_EMPTY_LABEL', 1); +} +if (!\defined('IDNA_ERROR_LABEL_TOO_LONG')) { + \define('IDNA_ERROR_LABEL_TOO_LONG', 2); +} +if (!\defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) { + \define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4); +} +if (!\defined('IDNA_ERROR_LEADING_HYPHEN')) { + \define('IDNA_ERROR_LEADING_HYPHEN', 8); +} +if (!\defined('IDNA_ERROR_TRAILING_HYPHEN')) { + \define('IDNA_ERROR_TRAILING_HYPHEN', 16); +} +if (!\defined('IDNA_ERROR_HYPHEN_3_4')) { + \define('IDNA_ERROR_HYPHEN_3_4', 32); +} +if (!\defined('IDNA_ERROR_LEADING_COMBINING_MARK')) { + \define('IDNA_ERROR_LEADING_COMBINING_MARK', 64); +} +if (!\defined('IDNA_ERROR_DISALLOWED')) { + \define('IDNA_ERROR_DISALLOWED', 128); +} +if (!\defined('IDNA_ERROR_PUNYCODE')) { + \define('IDNA_ERROR_PUNYCODE', 256); +} +if (!\defined('IDNA_ERROR_LABEL_HAS_DOT')) { + \define('IDNA_ERROR_LABEL_HAS_DOT', 512); +} +if (!\defined('IDNA_ERROR_INVALID_ACE_LABEL')) { + \define('IDNA_ERROR_INVALID_ACE_LABEL', 1024); +} +if (!\defined('IDNA_ERROR_BIDI')) { + \define('IDNA_ERROR_BIDI', 2048); +} +if (!\defined('IDNA_ERROR_CONTEXTJ')) { + \define('IDNA_ERROR_CONTEXTJ', 4096); +} +if (!\function_exists('idn_to_ascii')) { + function idn_to_ascii(?string $domain, ?int $flags = \IDNA_DEFAULT, ?int $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Idn::idn_to_ascii((string) $domain, (int) $flags, (int) $variant, $idna_info); + } +} +if (!\function_exists('idn_to_utf8')) { + function idn_to_utf8(?string $domain, ?int $flags = \IDNA_DEFAULT, ?int $variant = \INTL_IDNA_VARIANT_UTS46, &$idna_info = null) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Idn::idn_to_utf8((string) $domain, (int) $flags, (int) $variant, $idna_info); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/LICENSE b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/LICENSE new file mode 100644 index 0000000..6e3afce --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Mbstring.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Mbstring.php new file mode 100644 index 0000000..ad01f9f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Mbstring.php @@ -0,0 +1,753 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Symfony\Polyfill\Mbstring; + +/** + * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. + * + * Implemented: + * - mb_chr - Returns a specific character from its Unicode code point + * - mb_convert_encoding - Convert character encoding + * - mb_convert_variables - Convert character code in variable(s) + * - mb_decode_mimeheader - Decode string in MIME header field + * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED + * - mb_decode_numericentity - Decode HTML numeric string reference to character + * - mb_encode_numericentity - Encode character to HTML numeric string reference + * - mb_convert_case - Perform case folding on a string + * - mb_detect_encoding - Detect character encoding + * - mb_get_info - Get internal settings of mbstring + * - mb_http_input - Detect HTTP input character encoding + * - mb_http_output - Set/Get HTTP output character encoding + * - mb_internal_encoding - Set/Get internal character encoding + * - mb_list_encodings - Returns an array of all supported encodings + * - mb_ord - Returns the Unicode code point of a character + * - mb_output_handler - Callback function converts character encoding in output buffer + * - mb_scrub - Replaces ill-formed byte sequences with substitute characters + * - mb_strlen - Get string length + * - mb_strpos - Find position of first occurrence of string in a string + * - mb_strrpos - Find position of last occurrence of a string in a string + * - mb_str_split - Convert a string to an array + * - mb_strtolower - Make a string lowercase + * - mb_strtoupper - Make a string uppercase + * - mb_substitute_character - Set/Get substitution character + * - mb_substr - Get part of string + * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive + * - mb_stristr - Finds first occurrence of a string within another, case insensitive + * - mb_strrchr - Finds the last occurrence of a character in a string within another + * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive + * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive + * - mb_strstr - Finds first occurrence of a string within another + * - mb_strwidth - Return width of string + * - mb_substr_count - Count the number of substring occurrences + * + * Not implemented: + * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) + * - mb_ereg_* - Regular expression with multibyte support + * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable + * - mb_preferred_mime_name - Get MIME charset string + * - mb_regex_encoding - Returns current encoding for multibyte regex as string + * - mb_regex_set_options - Set/Get the default options for mbregex functions + * - mb_send_mail - Send encoded mail + * - mb_split - Split multibyte string using regular expression + * - mb_strcut - Get part of string + * - mb_strimwidth - Get truncated string with specified width + * + * @author Nicolas Grekas + * + * @internal + */ +final class Mbstring +{ + public const MB_CASE_FOLD = \PHP_INT_MAX; + private const SIMPLE_CASE_FOLD = [['µ', 'Å¿', "Í…", 'Ï‚', "Ï", "Ï‘", "Ï•", "Ï–", "ϰ", "ϱ", "ϵ", "ẛ", "á¾¾"], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'Ï€', 'κ', 'Ï', 'ε', "ṡ", 'ι']]; + private static $encodingList = ['ASCII', 'UTF-8']; + private static $language = 'neutral'; + private static $internalEncoding = 'UTF-8'; + public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) + { + if (\is_array($fromEncoding) || null !== $fromEncoding && \false !== \strpos($fromEncoding, ',')) { + $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); + } else { + $fromEncoding = self::getEncoding($fromEncoding); + } + $toEncoding = self::getEncoding($toEncoding); + if ('BASE64' === $fromEncoding) { + $s = \base64_decode($s); + $fromEncoding = $toEncoding; + } + if ('BASE64' === $toEncoding) { + return \base64_encode($s); + } + if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) { + if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) { + $fromEncoding = 'Windows-1252'; + } + if ('UTF-8' !== $fromEncoding) { + $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s); + } + return \preg_replace_callback('/[\\x80-\\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); + } + if ('HTML-ENTITIES' === $fromEncoding) { + $s = \html_entity_decode($s, \ENT_COMPAT, 'UTF-8'); + $fromEncoding = 'UTF-8'; + } + return \iconv($fromEncoding, $toEncoding . '//IGNORE', $s); + } + public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) + { + $ok = \true; + \array_walk_recursive($vars, function (&$v) use(&$ok, $toEncoding, $fromEncoding) { + if (\false === ($v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding))) { + $ok = \false; + } + }); + return $ok ? $fromEncoding : \false; + } + public static function mb_decode_mimeheader($s) + { + return \iconv_mime_decode($s, 2, self::$internalEncoding); + } + public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) + { + \trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING); + } + public static function mb_decode_numericentity($s, $convmap, $encoding = null) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { + \trigger_error('mb_decode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + } + if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) { + return \false; + } + if (null !== $encoding && !\is_scalar($encoding)) { + \trigger_error('mb_decode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return ''; + // Instead of null (cf. mb_encode_numericentity). + } + $s = (string) $s; + if ('' === $s) { + return ''; + } + $encoding = self::getEncoding($encoding); + if ('UTF-8' === $encoding) { + $encoding = null; + if (!\preg_match('//u', $s)) { + $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + $cnt = \floor(\count($convmap) / 4) * 4; + for ($i = 0; $i < $cnt; $i += 4) { + // collector_decode_htmlnumericentity ignores $convmap[$i + 3] + $convmap[$i] += $convmap[$i + 2]; + $convmap[$i + 1] += $convmap[$i + 2]; + } + $s = \preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use($cnt, $convmap) { + $c = isset($m[2]) ? (int) \hexdec($m[2]) : $m[1]; + for ($i = 0; $i < $cnt; $i += 4) { + if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) { + return self::mb_chr($c - $convmap[$i + 2]); + } + } + return $m[0]; + }, $s); + if (null === $encoding) { + return $s; + } + return \iconv('UTF-8', $encoding . '//IGNORE', $s); + } + public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = \false) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) { + \trigger_error('mb_encode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + } + if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) { + return \false; + } + if (null !== $encoding && !\is_scalar($encoding)) { + \trigger_error('mb_encode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + // Instead of '' (cf. mb_decode_numericentity). + } + if (null !== $is_hex && !\is_scalar($is_hex)) { + \trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, ' . \gettype($s) . ' given', \E_USER_WARNING); + return null; + } + $s = (string) $s; + if ('' === $s) { + return ''; + } + $encoding = self::getEncoding($encoding); + if ('UTF-8' === $encoding) { + $encoding = null; + if (!\preg_match('//u', $s)) { + $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + static $ulenMask = ["�" => 2, "�" => 2, "�" => 3, "�" => 4]; + $cnt = \floor(\count($convmap) / 4) * 4; + $i = 0; + $len = \strlen($s); + $result = ''; + while ($i < $len) { + $ulen = $s[$i] < "�" ? 1 : $ulenMask[$s[$i] & "�"]; + $uchr = \substr($s, $i, $ulen); + $i += $ulen; + $c = self::mb_ord($uchr); + for ($j = 0; $j < $cnt; $j += 4) { + if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) { + $cOffset = $c + $convmap[$j + 2] & $convmap[$j + 3]; + $result .= $is_hex ? \sprintf('&#x%X;', $cOffset) : '&#' . $cOffset . ';'; + continue 2; + } + } + $result .= $uchr; + } + if (null === $encoding) { + return $result; + } + return \iconv('UTF-8', $encoding . '//IGNORE', $result); + } + public static function mb_convert_case($s, $mode, $encoding = null) + { + $s = (string) $s; + if ('' === $s) { + return ''; + } + $encoding = self::getEncoding($encoding); + if ('UTF-8' === $encoding) { + $encoding = null; + if (!\preg_match('//u', $s)) { + $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + if (\MB_CASE_TITLE == $mode) { + static $titleRegexp = null; + if (null === $titleRegexp) { + $titleRegexp = self::getData('titleCaseRegexp'); + } + $s = \preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s); + } else { + if (\MB_CASE_UPPER == $mode) { + static $upper = null; + if (null === $upper) { + $upper = self::getData('upperCase'); + } + $map = $upper; + } else { + if (self::MB_CASE_FOLD === $mode) { + static $caseFolding = null; + if (null === $caseFolding) { + $caseFolding = self::getData('caseFolding'); + } + $s = \strtr($s, $caseFolding); + } + static $lower = null; + if (null === $lower) { + $lower = self::getData('lowerCase'); + } + $map = $lower; + } + static $ulenMask = ["�" => 2, "�" => 2, "�" => 3, "�" => 4]; + $i = 0; + $len = \strlen($s); + while ($i < $len) { + $ulen = $s[$i] < "�" ? 1 : $ulenMask[$s[$i] & "�"]; + $uchr = \substr($s, $i, $ulen); + $i += $ulen; + if (isset($map[$uchr])) { + $uchr = $map[$uchr]; + $nlen = \strlen($uchr); + if ($nlen == $ulen) { + $nlen = $i; + do { + $s[--$nlen] = $uchr[--$ulen]; + } while ($ulen); + } else { + $s = \substr_replace($s, $uchr, $i - $ulen, $ulen); + $len += $nlen - $ulen; + $i += $nlen - $ulen; + } + } + } + } + if (null === $encoding) { + return $s; + } + return \iconv('UTF-8', $encoding . '//IGNORE', $s); + } + public static function mb_internal_encoding($encoding = null) + { + if (null === $encoding) { + return self::$internalEncoding; + } + $normalizedEncoding = self::getEncoding($encoding); + if ('UTF-8' === $normalizedEncoding || \false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) { + self::$internalEncoding = $normalizedEncoding; + return \true; + } + if (80000 > \PHP_VERSION_ID) { + return \false; + } + throw new \ValueError(\sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + public static function mb_language($lang = null) + { + if (null === $lang) { + return self::$language; + } + switch ($normalizedLang = \strtolower($lang)) { + case 'uni': + case 'neutral': + self::$language = $normalizedLang; + return \true; + } + if (80000 > \PHP_VERSION_ID) { + return \false; + } + throw new \ValueError(\sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang)); + } + public static function mb_list_encodings() + { + return ['UTF-8']; + } + public static function mb_encoding_aliases($encoding) + { + switch (\strtoupper($encoding)) { + case 'UTF8': + case 'UTF-8': + return ['utf8']; + } + return \false; + } + public static function mb_check_encoding($var = null, $encoding = null) + { + if (\PHP_VERSION_ID < 70200 && \is_array($var)) { + \trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); + return null; + } + if (null === $encoding) { + if (null === $var) { + return \false; + } + $encoding = self::$internalEncoding; + } + if (!\is_array($var)) { + return self::mb_detect_encoding($var, [$encoding]) || \false !== @\iconv($encoding, $encoding, $var); + } + foreach ($var as $key => $value) { + if (!self::mb_check_encoding($key, $encoding)) { + return \false; + } + if (!self::mb_check_encoding($value, $encoding)) { + return \false; + } + } + return \true; + } + public static function mb_detect_encoding($str, $encodingList = null, $strict = \false) + { + if (null === $encodingList) { + $encodingList = self::$encodingList; + } else { + if (!\is_array($encodingList)) { + $encodingList = \array_map('trim', \explode(',', $encodingList)); + } + $encodingList = \array_map('strtoupper', $encodingList); + } + foreach ($encodingList as $enc) { + switch ($enc) { + case 'ASCII': + if (!\preg_match('/[\\x80-\\xFF]/', $str)) { + return $enc; + } + break; + case 'UTF8': + case 'UTF-8': + if (\preg_match('//u', $str)) { + return 'UTF-8'; + } + break; + default: + if (0 === \strncmp($enc, 'ISO-8859-', 9)) { + return $enc; + } + } + } + return \false; + } + public static function mb_detect_order($encodingList = null) + { + if (null === $encodingList) { + return self::$encodingList; + } + if (!\is_array($encodingList)) { + $encodingList = \array_map('trim', \explode(',', $encodingList)); + } + $encodingList = \array_map('strtoupper', $encodingList); + foreach ($encodingList as $enc) { + switch ($enc) { + default: + if (\strncmp($enc, 'ISO-8859-', 9)) { + return \false; + } + // no break + case 'ASCII': + case 'UTF8': + case 'UTF-8': + } + } + self::$encodingList = $encodingList; + return \true; + } + public static function mb_strlen($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strlen($s); + } + return @\iconv_strlen($s, $encoding); + } + public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strpos($haystack, $needle, $offset); + } + $needle = (string) $needle; + if ('' === $needle) { + if (80000 > \PHP_VERSION_ID) { + \trigger_error(__METHOD__ . ': Empty delimiter', \E_USER_WARNING); + return \false; + } + return 0; + } + return \iconv_strpos($haystack, $needle, $offset, $encoding); + } + public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strrpos($haystack, $needle, $offset); + } + if ($offset != (int) $offset) { + $offset = 0; + } elseif ($offset = (int) $offset) { + if ($offset < 0) { + if (0 > ($offset += self::mb_strlen($needle))) { + $haystack = self::mb_substr($haystack, 0, $offset, $encoding); + } + $offset = 0; + } else { + $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding); + } + } + $pos = '' !== $needle || 80000 > \PHP_VERSION_ID ? \iconv_strrpos($haystack, $needle, $encoding) : self::mb_strlen($haystack, $encoding); + return \false !== $pos ? $offset + $pos : \false; + } + public static function mb_str_split($string, $split_length = 1, $encoding = null) + { + if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) { + \trigger_error('mb_str_split() expects parameter 1 to be string, ' . \gettype($string) . ' given', \E_USER_WARNING); + return null; + } + if (1 > ($split_length = (int) $split_length)) { + if (80000 > \PHP_VERSION_ID) { + \trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); + return \false; + } + throw new \ValueError('Argument #2 ($length) must be greater than 0'); + } + if (null === $encoding) { + $encoding = \mb_internal_encoding(); + } + if ('UTF-8' === ($encoding = self::getEncoding($encoding))) { + $rx = '/('; + while (65535 < $split_length) { + $rx .= '.{65535}'; + $split_length -= 65535; + } + $rx .= '.{' . $split_length . '})/us'; + return \preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); + } + $result = []; + $length = \mb_strlen($string, $encoding); + for ($i = 0; $i < $length; $i += $split_length) { + $result[] = \mb_substr($string, $i, $split_length, $encoding); + } + return $result; + } + public static function mb_strtolower($s, $encoding = null) + { + return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding); + } + public static function mb_strtoupper($s, $encoding = null) + { + return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding); + } + public static function mb_substitute_character($c = null) + { + if (null === $c) { + return 'none'; + } + if (0 === \strcasecmp($c, 'none')) { + return \true; + } + if (80000 > \PHP_VERSION_ID) { + return \false; + } + if (\is_int($c) || 'long' === $c || 'entity' === $c) { + return \false; + } + throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint'); + } + public static function mb_substr($s, $start, $length = null, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return (string) \substr($s, $start, null === $length ? 2147483647 : $length); + } + if ($start < 0) { + $start = \iconv_strlen($s, $encoding) + $start; + if ($start < 0) { + $start = 0; + } + } + if (null === $length) { + $length = 2147483647; + } elseif ($length < 0) { + $length = \iconv_strlen($s, $encoding) + $length - $start; + if ($length < 0) { + return ''; + } + } + return (string) \iconv_substr($s, $start, $length, $encoding); + } + public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) + { + [$haystack, $needle] = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding)]); + return self::mb_strpos($haystack, $needle, $offset, $encoding); + } + public static function mb_stristr($haystack, $needle, $part = \false, $encoding = null) + { + $pos = self::mb_stripos($haystack, $needle, 0, $encoding); + return self::getSubpart($pos, $part, $haystack, $encoding); + } + public static function mb_strrchr($haystack, $needle, $part = \false, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + $pos = \strrpos($haystack, $needle); + } else { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = \iconv_strrpos($haystack, $needle, $encoding); + } + return self::getSubpart($pos, $part, $haystack, $encoding); + } + public static function mb_strrichr($haystack, $needle, $part = \false, $encoding = null) + { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = self::mb_strripos($haystack, $needle, $encoding); + return self::getSubpart($pos, $part, $haystack, $encoding); + } + public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) + { + $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding); + $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding); + $haystack = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack); + $needle = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle); + return self::mb_strrpos($haystack, $needle, $offset, $encoding); + } + public static function mb_strstr($haystack, $needle, $part = \false, $encoding = null) + { + $pos = \strpos($haystack, $needle); + if (\false === $pos) { + return \false; + } + if ($part) { + return \substr($haystack, 0, $pos); + } + return \substr($haystack, $pos); + } + public static function mb_get_info($type = 'all') + { + $info = ['internal_encoding' => self::$internalEncoding, 'http_output' => 'pass', 'http_output_conv_mimetypes' => '^(text/|application/xhtml\\+xml)', 'func_overload' => 0, 'func_overload_list' => 'no overload', 'mail_charset' => 'UTF-8', 'mail_header_encoding' => 'BASE64', 'mail_body_encoding' => 'BASE64', 'illegal_chars' => 0, 'encoding_translation' => 'Off', 'language' => self::$language, 'detect_order' => self::$encodingList, 'substitute_character' => 'none', 'strict_detection' => 'Off']; + if ('all' === $type) { + return $info; + } + if (isset($info[$type])) { + return $info[$type]; + } + return \false; + } + public static function mb_http_input($type = '') + { + return \false; + } + public static function mb_http_output($encoding = null) + { + return null !== $encoding ? 'pass' === $encoding : 'pass'; + } + public static function mb_strwidth($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('UTF-8' !== $encoding) { + $s = \iconv($encoding, 'UTF-8//IGNORE', $s); + } + $s = \preg_replace('/[\\x{1100}-\\x{115F}\\x{2329}\\x{232A}\\x{2E80}-\\x{303E}\\x{3040}-\\x{A4CF}\\x{AC00}-\\x{D7A3}\\x{F900}-\\x{FAFF}\\x{FE10}-\\x{FE19}\\x{FE30}-\\x{FE6F}\\x{FF00}-\\x{FF60}\\x{FFE0}-\\x{FFE6}\\x{20000}-\\x{2FFFD}\\x{30000}-\\x{3FFFD}]/u', '', $s, -1, $wide); + return ($wide << 1) + \iconv_strlen($s, 'UTF-8'); + } + public static function mb_substr_count($haystack, $needle, $encoding = null) + { + return \substr_count($haystack, $needle); + } + public static function mb_output_handler($contents, $status) + { + return $contents; + } + public static function mb_chr($code, $encoding = null) + { + if (0x80 > ($code %= 0x200000)) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f); + } elseif (0x10000 > $code) { + $s = \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } else { + $s = \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } + if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) { + $s = \mb_convert_encoding($s, $encoding, 'UTF-8'); + } + return $s; + } + public static function mb_ord($s, $encoding = null) + { + if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) { + $s = \mb_convert_encoding($s, 'UTF-8', $encoding); + } + if (1 === \strlen($s)) { + return \ord($s); + } + $code = ($s = \unpack('C*', \substr($s, 0, 4))) ? $s[1] : 0; + if (0xf0 <= $code) { + return ($code - 0xf0 << 18) + ($s[2] - 0x80 << 12) + ($s[3] - 0x80 << 6) + $s[4] - 0x80; + } + if (0xe0 <= $code) { + return ($code - 0xe0 << 12) + ($s[2] - 0x80 << 6) + $s[3] - 0x80; + } + if (0xc0 <= $code) { + return ($code - 0xc0 << 6) + $s[2] - 0x80; + } + return $code; + } + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null) : string + { + if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], \true)) { + throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); + } + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + if (self::mb_strlen($pad_string, $encoding) <= 0) { + throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); + } + $paddingRequired = $length - self::mb_strlen($string, $encoding); + if ($paddingRequired < 1) { + return $string; + } + switch ($pad_type) { + case \STR_PAD_LEFT: + return self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding) . $string; + case \STR_PAD_RIGHT: + return $string . self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding); + default: + $leftPaddingLength = \floor($paddingRequired / 2); + $rightPaddingLength = $paddingRequired - $leftPaddingLength; + return self::mb_substr(\str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding) . $string . self::mb_substr(\str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding); + } + } + private static function getSubpart($pos, $part, $haystack, $encoding) + { + if (\false === $pos) { + return \false; + } + if ($part) { + return self::mb_substr($haystack, 0, $pos, $encoding); + } + return self::mb_substr($haystack, $pos, null, $encoding); + } + private static function html_encoding_callback(array $m) + { + $i = 1; + $entities = ''; + $m = \unpack('C*', \htmlentities($m[0], \ENT_COMPAT, 'UTF-8')); + while (isset($m[$i])) { + if (0x80 > $m[$i]) { + $entities .= \chr($m[$i++]); + continue; + } + if (0xf0 <= $m[$i]) { + $c = ($m[$i++] - 0xf0 << 18) + ($m[$i++] - 0x80 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80; + } elseif (0xe0 <= $m[$i]) { + $c = ($m[$i++] - 0xe0 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80; + } else { + $c = ($m[$i++] - 0xc0 << 6) + $m[$i++] - 0x80; + } + $entities .= '&#' . $c . ';'; + } + return $entities; + } + private static function title_case(array $s) + { + return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8') . self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8'); + } + private static function getData($file) + { + if (\file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) { + return require $file; + } + return \false; + } + private static function getEncoding($encoding) + { + if (null === $encoding) { + return self::$internalEncoding; + } + if ('UTF-8' === $encoding) { + return 'UTF-8'; + } + $encoding = \strtoupper($encoding); + if ('8BIT' === $encoding || 'BINARY' === $encoding) { + return 'CP850'; + } + if ('UTF8' === $encoding) { + return 'UTF-8'; + } + return $encoding; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8 b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8 new file mode 100644 index 0000000..fdea6f0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/mb_convert_variables.php8 @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PostSMTP\Vendor\Symfony\Polyfill\Mbstring as p; + +if (!function_exists('mb_convert_variables')) { + /** + * Convert character code in variable(s) + */ + function mb_convert_variables($to_encoding, $from_encoding, &$var, &...$vars) + { + $vars = [&$var, ...$vars]; + + $ok = true; + array_walk_recursive($vars, function (&$v) use (&$ok, $to_encoding, $from_encoding) { + if (false === $v = p\Mbstring::mb_convert_encoding($v, $to_encoding, $from_encoding)) { + $ok = false; + } + }); + + return $ok ? $from_encoding : false; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php new file mode 100644 index 0000000..644a9af --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php @@ -0,0 +1,5 @@ + 'i̇', 'µ' => 'μ', 'Å¿' => 's', 'Í…' => 'ι', 'Ï‚' => 'σ', 'Ï' => 'β', 'Ï‘' => 'θ', 'Ï•' => 'φ', 'Ï–' => 'Ï€', 'ϰ' => 'κ', 'ϱ' => 'Ï', 'ϵ' => 'ε', 'ẛ' => 'ṡ', 'á¾¾' => 'ι', 'ß' => 'ss', 'ʼn' => 'ʼn', 'ǰ' => 'ǰ', 'Î' => 'Î', 'ΰ' => 'ΰ', 'Ö‡' => 'Õ¥Ö‚', 'ẖ' => 'ẖ', 'ẗ' => 'ẗ', 'ẘ' => 'ẘ', 'ẙ' => 'ẙ', 'ẚ' => 'aʾ', 'ẞ' => 'ss', 'á½' => 'á½', 'á½’' => 'á½’', 'á½”' => 'á½”', 'á½–' => 'á½–', 'á¾€' => 'ἀι', 'á¾' => 'á¼Î¹', 'ᾂ' => 'ἂι', 'ᾃ' => 'ἃι', 'ᾄ' => 'ἄι', 'á¾…' => 'ἅι', 'ᾆ' => 'ἆι', 'ᾇ' => 'ἇι', 'ᾈ' => 'ἀι', 'ᾉ' => 'á¼Î¹', 'ᾊ' => 'ἂι', 'ᾋ' => 'ἃι', 'ᾌ' => 'ἄι', 'á¾' => 'ἅι', 'ᾎ' => 'ἆι', 'á¾' => 'ἇι', 'á¾' => 'ἠι', 'ᾑ' => 'ἡι', 'á¾’' => 'ἢι', 'ᾓ' => 'ἣι', 'á¾”' => 'ἤι', 'ᾕ' => 'ἥι', 'á¾–' => 'ἦι', 'á¾—' => 'ἧι', 'ᾘ' => 'ἠι', 'á¾™' => 'ἡι', 'ᾚ' => 'ἢι', 'á¾›' => 'ἣι', 'ᾜ' => 'ἤι', 'á¾' => 'ἥι', 'ᾞ' => 'ἦι', 'ᾟ' => 'ἧι', 'á¾ ' => 'ὠι', 'ᾡ' => 'ὡι', 'á¾¢' => 'ὢι', 'á¾£' => 'ὣι', 'ᾤ' => 'ὤι', 'á¾¥' => 'ὥι', 'ᾦ' => 'ὦι', 'á¾§' => 'ὧι', 'ᾨ' => 'ὠι', 'ᾩ' => 'ὡι', 'ᾪ' => 'ὢι', 'ᾫ' => 'ὣι', 'ᾬ' => 'ὤι', 'á¾­' => 'ὥι', 'á¾®' => 'ὦι', 'ᾯ' => 'ὧι', 'á¾²' => 'ὰι', 'á¾³' => 'αι', 'á¾´' => 'άι', 'á¾¶' => 'á¾¶', 'á¾·' => 'ᾶι', 'á¾¼' => 'αι', 'á¿‚' => 'ὴι', 'ῃ' => 'ηι', 'á¿„' => 'ήι', 'ῆ' => 'ῆ', 'ῇ' => 'ῆι', 'ῌ' => 'ηι', 'á¿’' => 'á¿’', 'á¿–' => 'á¿–', 'á¿—' => 'á¿—', 'á¿¢' => 'á¿¢', 'ῤ' => 'ῤ', 'ῦ' => 'ῦ', 'á¿§' => 'á¿§', 'ῲ' => 'ὼι', 'ῳ' => 'ωι', 'á¿´' => 'ώι', 'á¿¶' => 'á¿¶', 'á¿·' => 'ῶι', 'ῼ' => 'ωι', 'ff' => 'ff', 'ï¬' => 'fi', 'fl' => 'fl', 'ffi' => 'ffi', 'ffl' => 'ffl', 'ſt' => 'st', 'st' => 'st', 'ﬓ' => 'Õ´Õ¶', 'ﬔ' => 'Õ´Õ¥', 'ﬕ' => 'Õ´Õ«', 'ﬖ' => 'Õ¾Õ¶', 'ﬗ' => 'Õ´Õ­']; diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php new file mode 100644 index 0000000..b50127b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php @@ -0,0 +1,5 @@ + 'a', 'B' => 'b', 'C' => 'c', 'D' => 'd', 'E' => 'e', 'F' => 'f', 'G' => 'g', 'H' => 'h', 'I' => 'i', 'J' => 'j', 'K' => 'k', 'L' => 'l', 'M' => 'm', 'N' => 'n', 'O' => 'o', 'P' => 'p', 'Q' => 'q', 'R' => 'r', 'S' => 's', 'T' => 't', 'U' => 'u', 'V' => 'v', 'W' => 'w', 'X' => 'x', 'Y' => 'y', 'Z' => 'z', 'À' => 'à', 'Ã' => 'á', 'Â' => 'â', 'Ã' => 'ã', 'Ä' => 'ä', 'Ã…' => 'Ã¥', 'Æ' => 'æ', 'Ç' => 'ç', 'È' => 'è', 'É' => 'é', 'Ê' => 'ê', 'Ë' => 'ë', 'ÃŒ' => 'ì', 'Ã' => 'í', 'ÃŽ' => 'î', 'Ã' => 'ï', 'Ã' => 'ð', 'Ñ' => 'ñ', 'Ã’' => 'ò', 'Ó' => 'ó', 'Ô' => 'ô', 'Õ' => 'õ', 'Ö' => 'ö', 'Ø' => 'ø', 'Ù' => 'ù', 'Ú' => 'ú', 'Û' => 'û', 'Ü' => 'ü', 'Ã' => 'ý', 'Þ' => 'þ', 'Ä€' => 'Ä', 'Ä‚' => 'ă', 'Ä„' => 'Ä…', 'Ć' => 'ć', 'Ĉ' => 'ĉ', 'ÄŠ' => 'Ä‹', 'ÄŒ' => 'Ä', 'ÄŽ' => 'Ä', 'Ä' => 'Ä‘', 'Ä’' => 'Ä“', 'Ä”' => 'Ä•', 'Ä–' => 'Ä—', 'Ę' => 'Ä™', 'Äš' => 'Ä›', 'Äœ' => 'Ä', 'Äž' => 'ÄŸ', 'Ä ' => 'Ä¡', 'Ä¢' => 'Ä£', 'Ĥ' => 'Ä¥', 'Ħ' => 'ħ', 'Ĩ' => 'Ä©', 'Ī' => 'Ä«', 'Ĭ' => 'Ä­', 'Ä®' => 'į', 'İ' => 'i̇', 'IJ' => 'ij', 'Ä´' => 'ĵ', 'Ķ' => 'Ä·', 'Ĺ' => 'ĺ', 'Ä»' => 'ļ', 'Ľ' => 'ľ', 'Ä¿' => 'Å€', 'Å' => 'Å‚', 'Ń' => 'Å„', 'Å…' => 'ņ', 'Ň' => 'ň', 'ÅŠ' => 'Å‹', 'ÅŒ' => 'Å', 'ÅŽ' => 'Å', 'Å' => 'Å‘', 'Å’' => 'Å“', 'Å”' => 'Å•', 'Å–' => 'Å—', 'Ř' => 'Å™', 'Åš' => 'Å›', 'Åœ' => 'Å', 'Åž' => 'ÅŸ', 'Å ' => 'Å¡', 'Å¢' => 'Å£', 'Ť' => 'Å¥', 'Ŧ' => 'ŧ', 'Ũ' => 'Å©', 'Ū' => 'Å«', 'Ŭ' => 'Å­', 'Å®' => 'ů', 'Ű' => 'ű', 'Ų' => 'ų', 'Å´' => 'ŵ', 'Ŷ' => 'Å·', 'Ÿ' => 'ÿ', 'Ź' => 'ź', 'Å»' => 'ż', 'Ž' => 'ž', 'Æ' => 'É“', 'Æ‚' => 'ƃ', 'Æ„' => 'Æ…', 'Ɔ' => 'É”', 'Ƈ' => 'ƈ', 'Ɖ' => 'É–', 'ÆŠ' => 'É—', 'Æ‹' => 'ÆŒ', 'ÆŽ' => 'Ç', 'Æ' => 'É™', 'Æ' => 'É›', 'Æ‘' => 'Æ’', 'Æ“' => 'É ', 'Æ”' => 'É£', 'Æ–' => 'É©', 'Æ—' => 'ɨ', 'Ƙ' => 'Æ™', 'Æœ' => 'ɯ', 'Æ' => 'ɲ', 'ÆŸ' => 'ɵ', 'Æ ' => 'Æ¡', 'Æ¢' => 'Æ£', 'Ƥ' => 'Æ¥', 'Ʀ' => 'Ê€', 'Ƨ' => 'ƨ', 'Æ©' => 'ʃ', 'Ƭ' => 'Æ­', 'Æ®' => 'ʈ', 'Ư' => 'ư', 'Ʊ' => 'ÊŠ', 'Ʋ' => 'Ê‹', 'Ƴ' => 'Æ´', 'Ƶ' => 'ƶ', 'Æ·' => 'Ê’', 'Ƹ' => 'ƹ', 'Ƽ' => 'ƽ', 'Ç„' => 'dž', 'Ç…' => 'dž', 'LJ' => 'lj', 'Lj' => 'lj', 'ÇŠ' => 'ÇŒ', 'Ç‹' => 'ÇŒ', 'Ç' => 'ÇŽ', 'Ç' => 'Ç', 'Ç‘' => 'Ç’', 'Ç“' => 'Ç”', 'Ç•' => 'Ç–', 'Ç—' => 'ǘ', 'Ç™' => 'Çš', 'Ç›' => 'Çœ', 'Çž' => 'ÇŸ', 'Ç ' => 'Ç¡', 'Ç¢' => 'Ç£', 'Ǥ' => 'Ç¥', 'Ǧ' => 'ǧ', 'Ǩ' => 'Ç©', 'Ǫ' => 'Ç«', 'Ǭ' => 'Ç­', 'Ç®' => 'ǯ', 'DZ' => 'dz', 'Dz' => 'dz', 'Ç´' => 'ǵ', 'Ƕ' => 'Æ•', 'Ç·' => 'Æ¿', 'Ǹ' => 'ǹ', 'Ǻ' => 'Ç»', 'Ǽ' => 'ǽ', 'Ǿ' => 'Ç¿', 'È€' => 'È', 'È‚' => 'ȃ', 'È„' => 'È…', 'Ȇ' => 'ȇ', 'Ȉ' => 'ȉ', 'ÈŠ' => 'È‹', 'ÈŒ' => 'È', 'ÈŽ' => 'È', 'È' => 'È‘', 'È’' => 'È“', 'È”' => 'È•', 'È–' => 'È—', 'Ș' => 'È™', 'Èš' => 'È›', 'Èœ' => 'È', 'Èž' => 'ÈŸ', 'È ' => 'Æž', 'È¢' => 'È£', 'Ȥ' => 'È¥', 'Ȧ' => 'ȧ', 'Ȩ' => 'È©', 'Ȫ' => 'È«', 'Ȭ' => 'È­', 'È®' => 'ȯ', 'Ȱ' => 'ȱ', 'Ȳ' => 'ȳ', 'Ⱥ' => 'â±¥', 'È»' => 'ȼ', 'Ƚ' => 'Æš', 'Ⱦ' => 'ⱦ', 'É' => 'É‚', 'Ƀ' => 'Æ€', 'É„' => 'ʉ', 'É…' => 'ÊŒ', 'Ɇ' => 'ɇ', 'Ɉ' => 'ɉ', 'ÉŠ' => 'É‹', 'ÉŒ' => 'É', 'ÉŽ' => 'É', 'Ͱ' => 'ͱ', 'Ͳ' => 'ͳ', 'Ͷ' => 'Í·', 'Í¿' => 'ϳ', 'Ά' => 'ά', 'Έ' => 'έ', 'Ή' => 'ή', 'Ί' => 'ί', 'ÎŒ' => 'ÏŒ', 'ÎŽ' => 'Ï', 'Î' => 'ÏŽ', 'Α' => 'α', 'Î’' => 'β', 'Γ' => 'γ', 'Δ' => 'δ', 'Ε' => 'ε', 'Ζ' => 'ζ', 'Η' => 'η', 'Θ' => 'θ', 'Ι' => 'ι', 'Κ' => 'κ', 'Λ' => 'λ', 'Μ' => 'μ', 'Î' => 'ν', 'Ξ' => 'ξ', 'Ο' => 'ο', 'Π' => 'Ï€', 'Ρ' => 'Ï', 'Σ' => 'σ', 'Τ' => 'Ï„', 'Î¥' => 'Ï…', 'Φ' => 'φ', 'Χ' => 'χ', 'Ψ' => 'ψ', 'Ω' => 'ω', 'Ϊ' => 'ÏŠ', 'Ϋ' => 'Ï‹', 'Ï' => 'Ï—', 'Ϙ' => 'Ï™', 'Ïš' => 'Ï›', 'Ïœ' => 'Ï', 'Ïž' => 'ÏŸ', 'Ï ' => 'Ï¡', 'Ï¢' => 'Ï£', 'Ϥ' => 'Ï¥', 'Ϧ' => 'ϧ', 'Ϩ' => 'Ï©', 'Ϫ' => 'Ï«', 'Ϭ' => 'Ï­', 'Ï®' => 'ϯ', 'Ï´' => 'θ', 'Ï·' => 'ϸ', 'Ϲ' => 'ϲ', 'Ϻ' => 'Ï»', 'Ͻ' => 'Í»', 'Ͼ' => 'ͼ', 'Ï¿' => 'ͽ', 'Ѐ' => 'Ñ', 'Ð' => 'Ñ‘', 'Ђ' => 'Ñ’', 'Ѓ' => 'Ñ“', 'Є' => 'Ñ”', 'Ð…' => 'Ñ•', 'І' => 'Ñ–', 'Ї' => 'Ñ—', 'Ј' => 'ј', 'Љ' => 'Ñ™', 'Њ' => 'Ñš', 'Ћ' => 'Ñ›', 'ÐŒ' => 'Ñœ', 'Ð' => 'Ñ', 'ÐŽ' => 'Ñž', 'Ð' => 'ÑŸ', 'Ð' => 'а', 'Б' => 'б', 'Ð’' => 'в', 'Г' => 'г', 'Д' => 'д', 'Е' => 'е', 'Ж' => 'ж', 'З' => 'з', 'И' => 'и', 'Й' => 'й', 'К' => 'к', 'Л' => 'л', 'М' => 'м', 'Ð' => 'н', 'О' => 'о', 'П' => 'п', 'Р' => 'Ñ€', 'С' => 'Ñ', 'Т' => 'Ñ‚', 'У' => 'у', 'Ф' => 'Ñ„', 'Ð¥' => 'Ñ…', 'Ц' => 'ц', 'Ч' => 'ч', 'Ш' => 'ш', 'Щ' => 'щ', 'Ъ' => 'ÑŠ', 'Ы' => 'Ñ‹', 'Ь' => 'ÑŒ', 'Э' => 'Ñ', 'Ю' => 'ÑŽ', 'Я' => 'Ñ', 'Ñ ' => 'Ñ¡', 'Ñ¢' => 'Ñ£', 'Ѥ' => 'Ñ¥', 'Ѧ' => 'ѧ', 'Ѩ' => 'Ñ©', 'Ѫ' => 'Ñ«', 'Ѭ' => 'Ñ­', 'Ñ®' => 'ѯ', 'Ѱ' => 'ѱ', 'Ѳ' => 'ѳ', 'Ñ´' => 'ѵ', 'Ѷ' => 'Ñ·', 'Ѹ' => 'ѹ', 'Ѻ' => 'Ñ»', 'Ѽ' => 'ѽ', 'Ѿ' => 'Ñ¿', 'Ò€' => 'Ò', 'ÒŠ' => 'Ò‹', 'ÒŒ' => 'Ò', 'ÒŽ' => 'Ò', 'Ò' => 'Ò‘', 'Ò’' => 'Ò“', 'Ò”' => 'Ò•', 'Ò–' => 'Ò—', 'Ò˜' => 'Ò™', 'Òš' => 'Ò›', 'Òœ' => 'Ò', 'Òž' => 'ÒŸ', 'Ò ' => 'Ò¡', 'Ò¢' => 'Ò£', 'Ò¤' => 'Ò¥', 'Ò¦' => 'Ò§', 'Ò¨' => 'Ò©', 'Òª' => 'Ò«', 'Ò¬' => 'Ò­', 'Ò®' => 'Ò¯', 'Ò°' => 'Ò±', 'Ò²' => 'Ò³', 'Ò´' => 'Òµ', 'Ò¶' => 'Ò·', 'Ò¸' => 'Ò¹', 'Òº' => 'Ò»', 'Ò¼' => 'Ò½', 'Ò¾' => 'Ò¿', 'Ó€' => 'Ó', 'Ó' => 'Ó‚', 'Óƒ' => 'Ó„', 'Ó…' => 'Ó†', 'Ó‡' => 'Óˆ', 'Ó‰' => 'ÓŠ', 'Ó‹' => 'ÓŒ', 'Ó' => 'ÓŽ', 'Ó' => 'Ó‘', 'Ó’' => 'Ó“', 'Ó”' => 'Ó•', 'Ó–' => 'Ó—', 'Ó˜' => 'Ó™', 'Óš' => 'Ó›', 'Óœ' => 'Ó', 'Óž' => 'ÓŸ', 'Ó ' => 'Ó¡', 'Ó¢' => 'Ó£', 'Ó¤' => 'Ó¥', 'Ó¦' => 'Ó§', 'Ó¨' => 'Ó©', 'Óª' => 'Ó«', 'Ó¬' => 'Ó­', 'Ó®' => 'Ó¯', 'Ó°' => 'Ó±', 'Ó²' => 'Ó³', 'Ó´' => 'Óµ', 'Ó¶' => 'Ó·', 'Ó¸' => 'Ó¹', 'Óº' => 'Ó»', 'Ó¼' => 'Ó½', 'Ó¾' => 'Ó¿', 'Ô€' => 'Ô', 'Ô‚' => 'Ôƒ', 'Ô„' => 'Ô…', 'Ô†' => 'Ô‡', 'Ôˆ' => 'Ô‰', 'ÔŠ' => 'Ô‹', 'ÔŒ' => 'Ô', 'ÔŽ' => 'Ô', 'Ô' => 'Ô‘', 'Ô’' => 'Ô“', 'Ô”' => 'Ô•', 'Ô–' => 'Ô—', 'Ô˜' => 'Ô™', 'Ôš' => 'Ô›', 'Ôœ' => 'Ô', 'Ôž' => 'ÔŸ', 'Ô ' => 'Ô¡', 'Ô¢' => 'Ô£', 'Ô¤' => 'Ô¥', 'Ô¦' => 'Ô§', 'Ô¨' => 'Ô©', 'Ôª' => 'Ô«', 'Ô¬' => 'Ô­', 'Ô®' => 'Ô¯', 'Ô±' => 'Õ¡', 'Ô²' => 'Õ¢', 'Ô³' => 'Õ£', 'Ô´' => 'Õ¤', 'Ôµ' => 'Õ¥', 'Ô¶' => 'Õ¦', 'Ô·' => 'Õ§', 'Ô¸' => 'Õ¨', 'Ô¹' => 'Õ©', 'Ôº' => 'Õª', 'Ô»' => 'Õ«', 'Ô¼' => 'Õ¬', 'Ô½' => 'Õ­', 'Ô¾' => 'Õ®', 'Ô¿' => 'Õ¯', 'Õ€' => 'Õ°', 'Õ' => 'Õ±', 'Õ‚' => 'Õ²', 'Õƒ' => 'Õ³', 'Õ„' => 'Õ´', 'Õ…' => 'Õµ', 'Õ†' => 'Õ¶', 'Õ‡' => 'Õ·', 'Õˆ' => 'Õ¸', 'Õ‰' => 'Õ¹', 'ÕŠ' => 'Õº', 'Õ‹' => 'Õ»', 'ÕŒ' => 'Õ¼', 'Õ' => 'Õ½', 'ÕŽ' => 'Õ¾', 'Õ' => 'Õ¿', 'Õ' => 'Ö€', 'Õ‘' => 'Ö', 'Õ’' => 'Ö‚', 'Õ“' => 'Öƒ', 'Õ”' => 'Ö„', 'Õ•' => 'Ö…', 'Õ–' => 'Ö†', 'á‚ ' => 'â´€', 'á‚¡' => 'â´', 'á‚¢' => 'â´‚', 'á‚£' => 'â´ƒ', 'Ⴄ' => 'â´„', 'á‚¥' => 'â´…', 'Ⴆ' => 'â´†', 'á‚§' => 'â´‡', 'Ⴈ' => 'â´ˆ', 'á‚©' => 'â´‰', 'Ⴊ' => 'â´Š', 'á‚«' => 'â´‹', 'Ⴌ' => 'â´Œ', 'á‚­' => 'â´', 'á‚®' => 'â´Ž', 'Ⴏ' => 'â´', 'á‚°' => 'â´', 'Ⴑ' => 'â´‘', 'Ⴒ' => 'â´’', 'Ⴓ' => 'â´“', 'á‚´' => 'â´”', 'Ⴕ' => 'â´•', 'á‚¶' => 'â´–', 'á‚·' => 'â´—', 'Ⴘ' => 'â´˜', 'Ⴙ' => 'â´™', 'Ⴚ' => 'â´š', 'á‚»' => 'â´›', 'Ⴜ' => 'â´œ', 'Ⴝ' => 'â´', 'Ⴞ' => 'â´ž', 'á‚¿' => 'â´Ÿ', 'Ⴠ' => 'â´ ', 'áƒ' => 'â´¡', 'Ⴢ' => 'â´¢', 'Ⴣ' => 'â´£', 'Ⴤ' => 'â´¤', 'Ⴥ' => 'â´¥', 'Ⴧ' => 'â´§', 'áƒ' => 'â´­', 'Ꭰ' => 'ê­°', 'Ꭱ' => 'ê­±', 'Ꭲ' => 'ê­²', 'Ꭳ' => 'ê­³', 'Ꭴ' => 'ê­´', 'Ꭵ' => 'ê­µ', 'Ꭶ' => 'ê­¶', 'Ꭷ' => 'ê­·', 'Ꭸ' => 'ê­¸', 'Ꭹ' => 'ê­¹', 'Ꭺ' => 'ê­º', 'Ꭻ' => 'ê­»', 'Ꭼ' => 'ê­¼', 'Ꭽ' => 'ê­½', 'Ꭾ' => 'ê­¾', 'Ꭿ' => 'ê­¿', 'Ꮀ' => 'ꮀ', 'Ꮁ' => 'ê®', 'Ꮂ' => 'ꮂ', 'Ꮃ' => 'ꮃ', 'Ꮄ' => 'ꮄ', 'Ꮅ' => 'ê®…', 'Ꮆ' => 'ꮆ', 'Ꮇ' => 'ꮇ', 'Ꮈ' => 'ꮈ', 'Ꮉ' => 'ꮉ', 'Ꮊ' => 'ꮊ', 'Ꮋ' => 'ꮋ', 'Ꮌ' => 'ꮌ', 'Ꮍ' => 'ê®', 'Ꮎ' => 'ꮎ', 'Ꮏ' => 'ê®', 'á€' => 'ê®', 'á' => 'ꮑ', 'á‚' => 'ê®’', 'áƒ' => 'ꮓ', 'á„' => 'ê®”', 'á…' => 'ꮕ', 'á†' => 'ê®–', 'á‡' => 'ê®—', 'áˆ' => 'ꮘ', 'á‰' => 'ê®™', 'áŠ' => 'ꮚ', 'á‹' => 'ê®›', 'áŒ' => 'ꮜ', 'á' => 'ê®', 'áŽ' => 'ꮞ', 'á' => 'ꮟ', 'á' => 'ê® ', 'á‘' => 'ꮡ', 'á’' => 'ꮢ', 'á“' => 'ꮣ', 'á”' => 'ꮤ', 'á•' => 'ꮥ', 'á–' => 'ꮦ', 'á—' => 'ê®§', 'á˜' => 'ꮨ', 'á™' => 'ꮩ', 'áš' => 'ꮪ', 'á›' => 'ꮫ', 'áœ' => 'ꮬ', 'á' => 'ê®­', 'áž' => 'ê®®', 'áŸ' => 'ꮯ', 'á ' => 'ê®°', 'á¡' => 'ê®±', 'á¢' => 'ꮲ', 'á£' => 'ꮳ', 'á¤' => 'ê®´', 'á¥' => 'ꮵ', 'á¦' => 'ê®¶', 'á§' => 'ê®·', 'á¨' => 'ꮸ', 'á©' => 'ꮹ', 'áª' => 'ꮺ', 'á«' => 'ê®»', 'á¬' => 'ꮼ', 'á­' => 'ꮽ', 'á®' => 'ꮾ', 'á¯' => 'ꮿ', 'á°' => 'á¸', 'á±' => 'á¹', 'á²' => 'áº', 'á³' => 'á»', 'á´' => 'á¼', 'áµ' => 'á½', 'á²' => 'áƒ', 'Ბ' => 'ბ', 'á²’' => 'გ', 'Დ' => 'დ', 'á²”' => 'ე', 'Ვ' => 'ვ', 'á²–' => 'ზ', 'á²—' => 'თ', 'Ი' => 'ი', 'á²™' => 'კ', 'Ლ' => 'ლ', 'á²›' => 'მ', 'Ნ' => 'ნ', 'á²' => 'áƒ', 'Პ' => 'პ', 'Ჟ' => 'ჟ', 'á² ' => 'რ', 'Ს' => 'ს', 'á²¢' => 'ტ', 'á²£' => 'უ', 'Ფ' => 'ფ', 'á²¥' => 'ქ', 'Ღ' => 'ღ', 'á²§' => 'ყ', 'Შ' => 'შ', 'Ჩ' => 'ჩ', 'Ც' => 'ც', 'Ძ' => 'ძ', 'Წ' => 'წ', 'á²­' => 'ჭ', 'á²®' => 'ხ', 'Ჯ' => 'ჯ', 'á²°' => 'ჰ', 'á²±' => 'ჱ', 'á²²' => 'ჲ', 'á²³' => 'ჳ', 'á²´' => 'ჴ', 'á²µ' => 'ჵ', 'á²¶' => 'ჶ', 'á²·' => 'ჷ', 'Ჸ' => 'ჸ', 'á²¹' => 'ჹ', 'Ჺ' => 'ჺ', 'á²½' => 'ჽ', 'á²¾' => 'ჾ', 'Ჿ' => 'ჿ', 'Ḁ' => 'á¸', 'Ḃ' => 'ḃ', 'Ḅ' => 'ḅ', 'Ḇ' => 'ḇ', 'Ḉ' => 'ḉ', 'Ḋ' => 'ḋ', 'Ḍ' => 'á¸', 'Ḏ' => 'á¸', 'á¸' => 'ḑ', 'Ḓ' => 'ḓ', 'Ḕ' => 'ḕ', 'Ḗ' => 'ḗ', 'Ḙ' => 'ḙ', 'Ḛ' => 'ḛ', 'Ḝ' => 'á¸', 'Ḟ' => 'ḟ', 'Ḡ' => 'ḡ', 'Ḣ' => 'ḣ', 'Ḥ' => 'ḥ', 'Ḧ' => 'ḧ', 'Ḩ' => 'ḩ', 'Ḫ' => 'ḫ', 'Ḭ' => 'ḭ', 'Ḯ' => 'ḯ', 'Ḱ' => 'ḱ', 'Ḳ' => 'ḳ', 'Ḵ' => 'ḵ', 'Ḷ' => 'ḷ', 'Ḹ' => 'ḹ', 'Ḻ' => 'ḻ', 'Ḽ' => 'ḽ', 'Ḿ' => 'ḿ', 'á¹€' => 'á¹', 'Ṃ' => 'ṃ', 'Ṅ' => 'á¹…', 'Ṇ' => 'ṇ', 'Ṉ' => 'ṉ', 'Ṋ' => 'ṋ', 'Ṍ' => 'á¹', 'Ṏ' => 'á¹', 'á¹' => 'ṑ', 'á¹’' => 'ṓ', 'á¹”' => 'ṕ', 'á¹–' => 'á¹—', 'Ṙ' => 'á¹™', 'Ṛ' => 'á¹›', 'Ṝ' => 'á¹', 'Ṟ' => 'ṟ', 'á¹ ' => 'ṡ', 'á¹¢' => 'á¹£', 'Ṥ' => 'á¹¥', 'Ṧ' => 'á¹§', 'Ṩ' => 'ṩ', 'Ṫ' => 'ṫ', 'Ṭ' => 'á¹­', 'á¹®' => 'ṯ', 'á¹°' => 'á¹±', 'á¹²' => 'á¹³', 'á¹´' => 'á¹µ', 'á¹¶' => 'á¹·', 'Ṹ' => 'á¹¹', 'Ṻ' => 'á¹»', 'á¹¼' => 'á¹½', 'á¹¾' => 'ṿ', 'Ẁ' => 'áº', 'Ẃ' => 'ẃ', 'Ẅ' => 'ẅ', 'Ẇ' => 'ẇ', 'Ẉ' => 'ẉ', 'Ẋ' => 'ẋ', 'Ẍ' => 'áº', 'Ẏ' => 'áº', 'áº' => 'ẑ', 'Ẓ' => 'ẓ', 'Ẕ' => 'ẕ', 'ẞ' => 'ß', 'Ạ' => 'ạ', 'Ả' => 'ả', 'Ấ' => 'ấ', 'Ầ' => 'ầ', 'Ẩ' => 'ẩ', 'Ẫ' => 'ẫ', 'Ậ' => 'ậ', 'Ắ' => 'ắ', 'Ằ' => 'ằ', 'Ẳ' => 'ẳ', 'Ẵ' => 'ẵ', 'Ặ' => 'ặ', 'Ẹ' => 'ẹ', 'Ẻ' => 'ẻ', 'Ẽ' => 'ẽ', 'Ế' => 'ế', 'Ề' => 'á»', 'Ể' => 'ể', 'Ễ' => 'á»…', 'Ệ' => 'ệ', 'Ỉ' => 'ỉ', 'Ị' => 'ị', 'Ọ' => 'á»', 'Ỏ' => 'á»', 'á»' => 'ố', 'á»’' => 'ồ', 'á»”' => 'ổ', 'á»–' => 'á»—', 'Ộ' => 'á»™', 'Ớ' => 'á»›', 'Ờ' => 'á»', 'Ở' => 'ở', 'á» ' => 'ỡ', 'Ợ' => 'ợ', 'Ụ' => 'ụ', 'Ủ' => 'á»§', 'Ứ' => 'ứ', 'Ừ' => 'ừ', 'Ử' => 'á»­', 'á»®' => 'ữ', 'á»°' => 'á»±', 'Ỳ' => 'ỳ', 'á»´' => 'ỵ', 'á»¶' => 'á»·', 'Ỹ' => 'ỹ', 'Ỻ' => 'á»»', 'Ỽ' => 'ỽ', 'Ỿ' => 'ỿ', 'Ἀ' => 'á¼€', 'Ἁ' => 'á¼', 'Ἂ' => 'ἂ', 'Ἃ' => 'ἃ', 'Ἄ' => 'ἄ', 'á¼' => 'á¼…', 'Ἆ' => 'ἆ', 'á¼' => 'ἇ', 'Ἐ' => 'á¼', 'á¼™' => 'ἑ', 'Ἒ' => 'á¼’', 'á¼›' => 'ἓ', 'Ἔ' => 'á¼”', 'á¼' => 'ἕ', 'Ἠ' => 'á¼ ', 'Ἡ' => 'ἡ', 'Ἢ' => 'á¼¢', 'Ἣ' => 'á¼£', 'Ἤ' => 'ἤ', 'á¼­' => 'á¼¥', 'á¼®' => 'ἦ', 'Ἧ' => 'á¼§', 'Ἰ' => 'á¼°', 'á¼¹' => 'á¼±', 'Ἲ' => 'á¼²', 'á¼»' => 'á¼³', 'á¼¼' => 'á¼´', 'á¼½' => 'á¼µ', 'á¼¾' => 'á¼¶', 'Ἷ' => 'á¼·', 'Ὀ' => 'á½€', 'Ὁ' => 'á½', 'Ὂ' => 'ὂ', 'Ὃ' => 'ὃ', 'Ὄ' => 'ὄ', 'á½' => 'á½…', 'á½™' => 'ὑ', 'á½›' => 'ὓ', 'á½' => 'ὕ', 'Ὗ' => 'á½—', 'Ὠ' => 'á½ ', 'Ὡ' => 'ὡ', 'Ὢ' => 'á½¢', 'Ὣ' => 'á½£', 'Ὤ' => 'ὤ', 'á½­' => 'á½¥', 'á½®' => 'ὦ', 'Ὧ' => 'á½§', 'ᾈ' => 'á¾€', 'ᾉ' => 'á¾', 'ᾊ' => 'ᾂ', 'ᾋ' => 'ᾃ', 'ᾌ' => 'ᾄ', 'á¾' => 'á¾…', 'ᾎ' => 'ᾆ', 'á¾' => 'ᾇ', 'ᾘ' => 'á¾', 'á¾™' => 'ᾑ', 'ᾚ' => 'á¾’', 'á¾›' => 'ᾓ', 'ᾜ' => 'á¾”', 'á¾' => 'ᾕ', 'ᾞ' => 'á¾–', 'ᾟ' => 'á¾—', 'ᾨ' => 'á¾ ', 'ᾩ' => 'ᾡ', 'ᾪ' => 'á¾¢', 'ᾫ' => 'á¾£', 'ᾬ' => 'ᾤ', 'á¾­' => 'á¾¥', 'á¾®' => 'ᾦ', 'ᾯ' => 'á¾§', 'Ᾰ' => 'á¾°', 'á¾¹' => 'á¾±', 'Ὰ' => 'á½°', 'á¾»' => 'á½±', 'á¾¼' => 'á¾³', 'Ὲ' => 'á½²', 'Έ' => 'á½³', 'Ὴ' => 'á½´', 'á¿‹' => 'á½µ', 'ῌ' => 'ῃ', 'Ῐ' => 'á¿', 'á¿™' => 'á¿‘', 'Ὶ' => 'á½¶', 'á¿›' => 'á½·', 'Ῠ' => 'á¿ ', 'á¿©' => 'á¿¡', 'Ὺ' => 'ὺ', 'á¿«' => 'á½»', 'Ῥ' => 'á¿¥', 'Ὸ' => 'ὸ', 'Ό' => 'á½¹', 'Ὼ' => 'á½¼', 'á¿»' => 'á½½', 'ῼ' => 'ῳ', 'Ω' => 'ω', 'K' => 'k', 'â„«' => 'Ã¥', 'Ⅎ' => 'â…Ž', 'â… ' => 'â…°', 'â…¡' => 'â…±', 'â…¢' => 'â…²', 'â…£' => 'â…³', 'â…¤' => 'â…´', 'â…¥' => 'â…µ', 'â…¦' => 'â…¶', 'â…§' => 'â…·', 'â…¨' => 'â…¸', 'â…©' => 'â…¹', 'â…ª' => 'â…º', 'â…«' => 'â…»', 'â…¬' => 'â…¼', 'â…­' => 'â…½', 'â…®' => 'â…¾', 'â…¯' => 'â…¿', 'Ↄ' => 'ↄ', 'â’¶' => 'â“', 'â’·' => 'â“‘', 'â’¸' => 'â“’', 'â’¹' => 'â““', 'â’º' => 'â“”', 'â’»' => 'â“•', 'â’¼' => 'â“–', 'â’½' => 'â“—', 'â’¾' => 'ⓘ', 'â’¿' => 'â“™', 'â“€' => 'ⓚ', 'â“' => 'â“›', 'â“‚' => 'ⓜ', 'Ⓝ' => 'â“', 'â“„' => 'ⓞ', 'â“…' => 'ⓟ', 'Ⓠ' => 'â“ ', 'Ⓡ' => 'â“¡', 'Ⓢ' => 'â“¢', 'Ⓣ' => 'â“£', 'Ⓤ' => 'ⓤ', 'â“‹' => 'â“¥', 'Ⓦ' => 'ⓦ', 'â“' => 'â“§', 'Ⓨ' => 'ⓨ', 'â“' => 'â“©', 'â°€' => 'â°°', 'â°' => 'â°±', 'â°‚' => 'â°²', 'â°ƒ' => 'â°³', 'â°„' => 'â°´', 'â°…' => 'â°µ', 'â°†' => 'â°¶', 'â°‡' => 'â°·', 'â°ˆ' => 'â°¸', 'â°‰' => 'â°¹', 'â°Š' => 'â°º', 'â°‹' => 'â°»', 'â°Œ' => 'â°¼', 'â°' => 'â°½', 'â°Ž' => 'â°¾', 'â°' => 'â°¿', 'â°' => 'â±€', 'â°‘' => 'â±', 'â°’' => 'ⱂ', 'â°“' => 'ⱃ', 'â°”' => 'ⱄ', 'â°•' => 'â±…', 'â°–' => 'ⱆ', 'â°—' => 'ⱇ', 'â°˜' => 'ⱈ', 'â°™' => 'ⱉ', 'â°š' => 'ⱊ', 'â°›' => 'ⱋ', 'â°œ' => 'ⱌ', 'â°' => 'â±', 'â°ž' => 'ⱎ', 'â°Ÿ' => 'â±', 'â° ' => 'â±', 'â°¡' => 'ⱑ', 'â°¢' => 'â±’', 'â°£' => 'ⱓ', 'â°¤' => 'â±”', 'â°¥' => 'ⱕ', 'â°¦' => 'â±–', 'â°§' => 'â±—', 'â°¨' => 'ⱘ', 'â°©' => 'â±™', 'â°ª' => 'ⱚ', 'â°«' => 'â±›', 'â°¬' => 'ⱜ', 'â°­' => 'â±', 'â°®' => 'ⱞ', 'â± ' => 'ⱡ', 'â±¢' => 'É«', 'â±£' => 'áµ½', 'Ɽ' => 'ɽ', 'â±§' => 'ⱨ', 'Ⱪ' => 'ⱪ', 'Ⱬ' => 'ⱬ', 'â±­' => 'É‘', 'â±®' => 'ɱ', 'Ɐ' => 'É', 'â±°' => 'É’', 'â±²' => 'â±³', 'â±µ' => 'â±¶', 'â±¾' => 'È¿', 'Ɀ' => 'É€', 'â²€' => 'â²', 'Ⲃ' => 'ⲃ', 'Ⲅ' => 'â²…', 'Ⲇ' => 'ⲇ', 'Ⲉ' => 'ⲉ', 'Ⲋ' => 'ⲋ', 'Ⲍ' => 'â²', 'Ⲏ' => 'â²', 'â²' => 'ⲑ', 'â²’' => 'ⲓ', 'â²”' => 'ⲕ', 'â²–' => 'â²—', 'Ⲙ' => 'â²™', 'Ⲛ' => 'â²›', 'Ⲝ' => 'â²', 'Ⲟ' => 'ⲟ', 'â² ' => 'ⲡ', 'â²¢' => 'â²£', 'Ⲥ' => 'â²¥', 'Ⲧ' => 'â²§', 'Ⲩ' => 'ⲩ', 'Ⲫ' => 'ⲫ', 'Ⲭ' => 'â²­', 'â²®' => 'ⲯ', 'â²°' => 'â²±', 'â²²' => 'â²³', 'â²´' => 'â²µ', 'â²¶' => 'â²·', 'Ⲹ' => 'â²¹', 'Ⲻ' => 'â²»', 'â²¼' => 'â²½', 'â²¾' => 'ⲿ', 'â³€' => 'â³', 'Ⳃ' => 'ⳃ', 'Ⳅ' => 'â³…', 'Ⳇ' => 'ⳇ', 'Ⳉ' => 'ⳉ', 'Ⳋ' => 'ⳋ', 'Ⳍ' => 'â³', 'Ⳏ' => 'â³', 'â³' => 'ⳑ', 'â³’' => 'ⳓ', 'â³”' => 'ⳕ', 'â³–' => 'â³—', 'Ⳙ' => 'â³™', 'Ⳛ' => 'â³›', 'Ⳝ' => 'â³', 'Ⳟ' => 'ⳟ', 'â³ ' => 'ⳡ', 'â³¢' => 'â³£', 'Ⳬ' => 'ⳬ', 'â³­' => 'â³®', 'â³²' => 'â³³', 'Ꙁ' => 'ê™', 'Ꙃ' => 'ꙃ', 'Ꙅ' => 'ê™…', 'Ꙇ' => 'ꙇ', 'Ꙉ' => 'ꙉ', 'Ꙋ' => 'ꙋ', 'Ꙍ' => 'ê™', 'Ꙏ' => 'ê™', 'ê™' => 'ꙑ', 'ê™’' => 'ꙓ', 'ê™”' => 'ꙕ', 'ê™–' => 'ê™—', 'Ꙙ' => 'ê™™', 'Ꙛ' => 'ê™›', 'Ꙝ' => 'ê™', 'Ꙟ' => 'ꙟ', 'ê™ ' => 'ꙡ', 'Ꙣ' => 'ꙣ', 'Ꙥ' => 'ꙥ', 'Ꙧ' => 'ê™§', 'Ꙩ' => 'ꙩ', 'Ꙫ' => 'ꙫ', 'Ꙭ' => 'ê™­', 'Ꚁ' => 'êš', 'êš‚' => 'ꚃ', 'êš„' => 'êš…', 'Ꚇ' => 'ꚇ', 'Ꚉ' => 'ꚉ', 'Ꚋ' => 'êš‹', 'Ꚍ' => 'êš', 'Ꚏ' => 'êš', 'êš' => 'êš‘', 'êš’' => 'êš“', 'êš”' => 'êš•', 'êš–' => 'êš—', 'Ꚙ' => 'êš™', 'êšš' => 'êš›', 'Ꜣ' => 'ꜣ', 'Ꜥ' => 'ꜥ', 'Ꜧ' => 'ꜧ', 'Ꜩ' => 'ꜩ', 'Ꜫ' => 'ꜫ', 'Ꜭ' => 'ꜭ', 'Ꜯ' => 'ꜯ', 'Ꜳ' => 'ꜳ', 'Ꜵ' => 'ꜵ', 'Ꜷ' => 'ꜷ', 'Ꜹ' => 'ꜹ', 'Ꜻ' => 'ꜻ', 'Ꜽ' => 'ꜽ', 'Ꜿ' => 'ꜿ', 'ê€' => 'ê', 'ê‚' => 'êƒ', 'ê„' => 'ê…', 'ê†' => 'ê‡', 'êˆ' => 'ê‰', 'êŠ' => 'ê‹', 'êŒ' => 'ê', 'êŽ' => 'ê', 'ê' => 'ê‘', 'ê’' => 'ê“', 'ê”' => 'ê•', 'ê–' => 'ê—', 'ê˜' => 'ê™', 'êš' => 'ê›', 'êœ' => 'ê', 'êž' => 'êŸ', 'ê ' => 'ê¡', 'ê¢' => 'ê£', 'ê¤' => 'ê¥', 'ê¦' => 'ê§', 'ê¨' => 'ê©', 'êª' => 'ê«', 'ê¬' => 'ê­', 'ê®' => 'ê¯', 'ê¹' => 'êº', 'ê»' => 'ê¼', 'ê½' => 'áµ¹', 'ê¾' => 'ê¿', 'Ꞁ' => 'êž', 'êž‚' => 'ꞃ', 'êž„' => 'êž…', 'Ꞇ' => 'ꞇ', 'êž‹' => 'ꞌ', 'êž' => 'É¥', 'êž' => 'êž‘', 'êž’' => 'êž“', 'êž–' => 'êž—', 'Ꞙ' => 'êž™', 'êžš' => 'êž›', 'êžœ' => 'êž', 'êžž' => 'ꞟ', 'êž ' => 'êž¡', 'Ꞣ' => 'ꞣ', 'Ꞥ' => 'ꞥ', 'Ꞧ' => 'êž§', 'Ꞩ' => 'êž©', 'Ɦ' => 'ɦ', 'êž«' => 'Éœ', 'Ɡ' => 'É¡', 'êž­' => 'ɬ', 'êž®' => 'ɪ', 'êž°' => 'Êž', 'êž±' => 'ʇ', 'êž²' => 'Ê', 'êž³' => 'ê­“', 'êž´' => 'êžµ', 'êž¶' => 'êž·', 'Ꞹ' => 'êž¹', 'Ꞻ' => 'êž»', 'êž¼' => 'êž½', 'êž¾' => 'êž¿', 'Ꟃ' => 'ꟃ', 'Ꞔ' => 'êž”', 'Ʂ' => 'Ê‚', 'Ᶎ' => 'á¶Ž', 'Ꟈ' => 'ꟈ', 'Ꟊ' => 'ꟊ', 'Ꟶ' => 'ꟶ', 'A' => 'ï½', 'ï¼¢' => 'b', 'ï¼£' => 'c', 'D' => 'd', 'ï¼¥' => 'ï½…', 'F' => 'f', 'ï¼§' => 'g', 'H' => 'h', 'I' => 'i', 'J' => 'j', 'K' => 'k', 'L' => 'l', 'ï¼­' => 'ï½', 'ï¼®' => 'n', 'O' => 'ï½', 'ï¼°' => 'ï½', 'ï¼±' => 'q', 'ï¼²' => 'ï½’', 'ï¼³' => 's', 'ï¼´' => 'ï½”', 'ï¼µ' => 'u', 'ï¼¶' => 'ï½–', 'ï¼·' => 'ï½—', 'X' => 'x', 'ï¼¹' => 'ï½™', 'Z' => 'z', 'ð€' => 'ð¨', 'ð' => 'ð©', 'ð‚' => 'ðª', 'ðƒ' => 'ð«', 'ð„' => 'ð¬', 'ð…' => 'ð­', 'ð†' => 'ð®', 'ð‡' => 'ð¯', 'ðˆ' => 'ð°', 'ð‰' => 'ð±', 'ðŠ' => 'ð²', 'ð‹' => 'ð³', 'ðŒ' => 'ð´', 'ð' => 'ðµ', 'ðŽ' => 'ð¶', 'ð' => 'ð·', 'ð' => 'ð¸', 'ð‘' => 'ð¹', 'ð’' => 'ðº', 'ð“' => 'ð»', 'ð”' => 'ð¼', 'ð•' => 'ð½', 'ð–' => 'ð¾', 'ð—' => 'ð¿', 'ð˜' => 'ð‘€', 'ð™' => 'ð‘', 'ðš' => 'ð‘‚', 'ð›' => 'ð‘ƒ', 'ðœ' => 'ð‘„', 'ð' => 'ð‘…', 'ðž' => 'ð‘†', 'ðŸ' => 'ð‘‡', 'ð ' => 'ð‘ˆ', 'ð¡' => 'ð‘‰', 'ð¢' => 'ð‘Š', 'ð£' => 'ð‘‹', 'ð¤' => 'ð‘Œ', 'ð¥' => 'ð‘', 'ð¦' => 'ð‘Ž', 'ð§' => 'ð‘', 'ð’°' => 'ð“˜', 'ð’±' => 'ð“™', 'ð’²' => 'ð“š', 'ð’³' => 'ð“›', 'ð’´' => 'ð“œ', 'ð’µ' => 'ð“', 'ð’¶' => 'ð“ž', 'ð’·' => 'ð“Ÿ', 'ð’¸' => 'ð“ ', 'ð’¹' => 'ð“¡', 'ð’º' => 'ð“¢', 'ð’»' => 'ð“£', 'ð’¼' => 'ð“¤', 'ð’½' => 'ð“¥', 'ð’¾' => 'ð“¦', 'ð’¿' => 'ð“§', 'ð“€' => 'ð“¨', 'ð“' => 'ð“©', 'ð“‚' => 'ð“ª', 'ð“ƒ' => 'ð“«', 'ð“„' => 'ð“¬', 'ð“…' => 'ð“­', 'ð“†' => 'ð“®', 'ð“‡' => 'ð“¯', 'ð“ˆ' => 'ð“°', 'ð“‰' => 'ð“±', 'ð“Š' => 'ð“²', 'ð“‹' => 'ð“³', 'ð“Œ' => 'ð“´', 'ð“' => 'ð“µ', 'ð“Ž' => 'ð“¶', 'ð“' => 'ð“·', 'ð“' => 'ð“¸', 'ð“‘' => 'ð“¹', 'ð“’' => 'ð“º', 'ð““' => 'ð“»', 'ð²€' => 'ð³€', 'ð²' => 'ð³', 'ð²‚' => 'ð³‚', 'ð²ƒ' => 'ð³ƒ', 'ð²„' => 'ð³„', 'ð²…' => 'ð³…', 'ð²†' => 'ð³†', 'ð²‡' => 'ð³‡', 'ð²ˆ' => 'ð³ˆ', 'ð²‰' => 'ð³‰', 'ð²Š' => 'ð³Š', 'ð²‹' => 'ð³‹', 'ð²Œ' => 'ð³Œ', 'ð²' => 'ð³', 'ð²Ž' => 'ð³Ž', 'ð²' => 'ð³', 'ð²' => 'ð³', 'ð²‘' => 'ð³‘', 'ð²’' => 'ð³’', 'ð²“' => 'ð³“', 'ð²”' => 'ð³”', 'ð²•' => 'ð³•', 'ð²–' => 'ð³–', 'ð²—' => 'ð³—', 'ð²˜' => 'ð³˜', 'ð²™' => 'ð³™', 'ð²š' => 'ð³š', 'ð²›' => 'ð³›', 'ð²œ' => 'ð³œ', 'ð²' => 'ð³', 'ð²ž' => 'ð³ž', 'ð²Ÿ' => 'ð³Ÿ', 'ð² ' => 'ð³ ', 'ð²¡' => 'ð³¡', 'ð²¢' => 'ð³¢', 'ð²£' => 'ð³£', 'ð²¤' => 'ð³¤', 'ð²¥' => 'ð³¥', 'ð²¦' => 'ð³¦', 'ð²§' => 'ð³§', 'ð²¨' => 'ð³¨', 'ð²©' => 'ð³©', 'ð²ª' => 'ð³ª', 'ð²«' => 'ð³«', 'ð²¬' => 'ð³¬', 'ð²­' => 'ð³­', 'ð²®' => 'ð³®', 'ð²¯' => 'ð³¯', 'ð²°' => 'ð³°', 'ð²±' => 'ð³±', 'ð²²' => 'ð³²', 'ð‘¢ ' => 'ð‘£€', '𑢡' => 'ð‘£', 'ð‘¢¢' => '𑣂', 'ð‘¢£' => '𑣃', '𑢤' => '𑣄', 'ð‘¢¥' => 'ð‘£…', '𑢦' => '𑣆', 'ð‘¢§' => '𑣇', '𑢨' => '𑣈', '𑢩' => '𑣉', '𑢪' => '𑣊', '𑢫' => '𑣋', '𑢬' => '𑣌', 'ð‘¢­' => 'ð‘£', 'ð‘¢®' => '𑣎', '𑢯' => 'ð‘£', 'ð‘¢°' => 'ð‘£', 'ð‘¢±' => '𑣑', 'ð‘¢²' => 'ð‘£’', 'ð‘¢³' => '𑣓', 'ð‘¢´' => 'ð‘£”', 'ð‘¢µ' => '𑣕', 'ð‘¢¶' => 'ð‘£–', 'ð‘¢·' => 'ð‘£—', '𑢸' => '𑣘', 'ð‘¢¹' => 'ð‘£™', '𑢺' => '𑣚', 'ð‘¢»' => 'ð‘£›', 'ð‘¢¼' => '𑣜', 'ð‘¢½' => 'ð‘£', 'ð‘¢¾' => '𑣞', '𑢿' => '𑣟', 'ð–¹€' => 'ð–¹ ', 'ð–¹' => '𖹡', '𖹂' => 'ð–¹¢', '𖹃' => 'ð–¹£', '𖹄' => '𖹤', 'ð–¹…' => 'ð–¹¥', '𖹆' => '𖹦', '𖹇' => 'ð–¹§', '𖹈' => '𖹨', '𖹉' => '𖹩', '𖹊' => '𖹪', '𖹋' => '𖹫', '𖹌' => '𖹬', 'ð–¹' => 'ð–¹­', '𖹎' => 'ð–¹®', 'ð–¹' => '𖹯', 'ð–¹' => 'ð–¹°', '𖹑' => 'ð–¹±', 'ð–¹’' => 'ð–¹²', '𖹓' => 'ð–¹³', 'ð–¹”' => 'ð–¹´', '𖹕' => 'ð–¹µ', 'ð–¹–' => 'ð–¹¶', 'ð–¹—' => 'ð–¹·', '𖹘' => '𖹸', 'ð–¹™' => 'ð–¹¹', '𖹚' => '𖹺', 'ð–¹›' => 'ð–¹»', '𖹜' => 'ð–¹¼', 'ð–¹' => 'ð–¹½', '𖹞' => 'ð–¹¾', '𖹟' => '𖹿', '𞤀' => '𞤢', 'ðž¤' => '𞤣', '𞤂' => '𞤤', '𞤃' => '𞤥', '𞤄' => '𞤦', '𞤅' => '𞤧', '𞤆' => '𞤨', '𞤇' => '𞤩', '𞤈' => '𞤪', '𞤉' => '𞤫', '𞤊' => '𞤬', '𞤋' => '𞤭', '𞤌' => '𞤮', 'ðž¤' => '𞤯', '𞤎' => '𞤰', 'ðž¤' => '𞤱', 'ðž¤' => '𞤲', '𞤑' => '𞤳', '𞤒' => '𞤴', '𞤓' => '𞤵', '𞤔' => '𞤶', '𞤕' => '𞤷', '𞤖' => '𞤸', '𞤗' => '𞤹', '𞤘' => '𞤺', '𞤙' => '𞤻', '𞤚' => '𞤼', '𞤛' => '𞤽', '𞤜' => '𞤾', 'ðž¤' => '𞤿', '𞤞' => '𞥀', '𞤟' => 'ðž¥', '𞤠' => '𞥂', '𞤡' => '𞥃'); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php new file mode 100644 index 0000000..ec483ad --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php @@ -0,0 +1,6 @@ + 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D', 'e' => 'E', 'f' => 'F', 'g' => 'G', 'h' => 'H', 'i' => 'I', 'j' => 'J', 'k' => 'K', 'l' => 'L', 'm' => 'M', 'n' => 'N', 'o' => 'O', 'p' => 'P', 'q' => 'Q', 'r' => 'R', 's' => 'S', 't' => 'T', 'u' => 'U', 'v' => 'V', 'w' => 'W', 'x' => 'X', 'y' => 'Y', 'z' => 'Z', 'µ' => 'Μ', 'à' => 'À', 'á' => 'Ã', 'â' => 'Â', 'ã' => 'Ã', 'ä' => 'Ä', 'Ã¥' => 'Ã…', 'æ' => 'Æ', 'ç' => 'Ç', 'è' => 'È', 'é' => 'É', 'ê' => 'Ê', 'ë' => 'Ë', 'ì' => 'ÃŒ', 'í' => 'Ã', 'î' => 'ÃŽ', 'ï' => 'Ã', 'ð' => 'Ã', 'ñ' => 'Ñ', 'ò' => 'Ã’', 'ó' => 'Ó', 'ô' => 'Ô', 'õ' => 'Õ', 'ö' => 'Ö', 'ø' => 'Ø', 'ù' => 'Ù', 'ú' => 'Ú', 'û' => 'Û', 'ü' => 'Ü', 'ý' => 'Ã', 'þ' => 'Þ', 'ÿ' => 'Ÿ', 'Ä' => 'Ä€', 'ă' => 'Ä‚', 'Ä…' => 'Ä„', 'ć' => 'Ć', 'ĉ' => 'Ĉ', 'Ä‹' => 'ÄŠ', 'Ä' => 'ÄŒ', 'Ä' => 'ÄŽ', 'Ä‘' => 'Ä', 'Ä“' => 'Ä’', 'Ä•' => 'Ä”', 'Ä—' => 'Ä–', 'Ä™' => 'Ę', 'Ä›' => 'Äš', 'Ä' => 'Äœ', 'ÄŸ' => 'Äž', 'Ä¡' => 'Ä ', 'Ä£' => 'Ä¢', 'Ä¥' => 'Ĥ', 'ħ' => 'Ħ', 'Ä©' => 'Ĩ', 'Ä«' => 'Ī', 'Ä­' => 'Ĭ', 'į' => 'Ä®', 'ı' => 'I', 'ij' => 'IJ', 'ĵ' => 'Ä´', 'Ä·' => 'Ķ', 'ĺ' => 'Ĺ', 'ļ' => 'Ä»', 'ľ' => 'Ľ', 'Å€' => 'Ä¿', 'Å‚' => 'Å', 'Å„' => 'Ń', 'ņ' => 'Å…', 'ň' => 'Ň', 'Å‹' => 'ÅŠ', 'Å' => 'ÅŒ', 'Å' => 'ÅŽ', 'Å‘' => 'Å', 'Å“' => 'Å’', 'Å•' => 'Å”', 'Å—' => 'Å–', 'Å™' => 'Ř', 'Å›' => 'Åš', 'Å' => 'Åœ', 'ÅŸ' => 'Åž', 'Å¡' => 'Å ', 'Å£' => 'Å¢', 'Å¥' => 'Ť', 'ŧ' => 'Ŧ', 'Å©' => 'Ũ', 'Å«' => 'Ū', 'Å­' => 'Ŭ', 'ů' => 'Å®', 'ű' => 'Ű', 'ų' => 'Ų', 'ŵ' => 'Å´', 'Å·' => 'Ŷ', 'ź' => 'Ź', 'ż' => 'Å»', 'ž' => 'Ž', 'Å¿' => 'S', 'Æ€' => 'Ƀ', 'ƃ' => 'Æ‚', 'Æ…' => 'Æ„', 'ƈ' => 'Ƈ', 'ÆŒ' => 'Æ‹', 'Æ’' => 'Æ‘', 'Æ•' => 'Ƕ', 'Æ™' => 'Ƙ', 'Æš' => 'Ƚ', 'Æž' => 'È ', 'Æ¡' => 'Æ ', 'Æ£' => 'Æ¢', 'Æ¥' => 'Ƥ', 'ƨ' => 'Ƨ', 'Æ­' => 'Ƭ', 'ư' => 'Ư', 'Æ´' => 'Ƴ', 'ƶ' => 'Ƶ', 'ƹ' => 'Ƹ', 'ƽ' => 'Ƽ', 'Æ¿' => 'Ç·', 'Ç…' => 'Ç„', 'dž' => 'Ç„', 'Lj' => 'LJ', 'lj' => 'LJ', 'Ç‹' => 'ÇŠ', 'ÇŒ' => 'ÇŠ', 'ÇŽ' => 'Ç', 'Ç' => 'Ç', 'Ç’' => 'Ç‘', 'Ç”' => 'Ç“', 'Ç–' => 'Ç•', 'ǘ' => 'Ç—', 'Çš' => 'Ç™', 'Çœ' => 'Ç›', 'Ç' => 'ÆŽ', 'ÇŸ' => 'Çž', 'Ç¡' => 'Ç ', 'Ç£' => 'Ç¢', 'Ç¥' => 'Ǥ', 'ǧ' => 'Ǧ', 'Ç©' => 'Ǩ', 'Ç«' => 'Ǫ', 'Ç­' => 'Ǭ', 'ǯ' => 'Ç®', 'Dz' => 'DZ', 'dz' => 'DZ', 'ǵ' => 'Ç´', 'ǹ' => 'Ǹ', 'Ç»' => 'Ǻ', 'ǽ' => 'Ǽ', 'Ç¿' => 'Ǿ', 'È' => 'È€', 'ȃ' => 'È‚', 'È…' => 'È„', 'ȇ' => 'Ȇ', 'ȉ' => 'Ȉ', 'È‹' => 'ÈŠ', 'È' => 'ÈŒ', 'È' => 'ÈŽ', 'È‘' => 'È', 'È“' => 'È’', 'È•' => 'È”', 'È—' => 'È–', 'È™' => 'Ș', 'È›' => 'Èš', 'È' => 'Èœ', 'ÈŸ' => 'Èž', 'È£' => 'È¢', 'È¥' => 'Ȥ', 'ȧ' => 'Ȧ', 'È©' => 'Ȩ', 'È«' => 'Ȫ', 'È­' => 'Ȭ', 'ȯ' => 'È®', 'ȱ' => 'Ȱ', 'ȳ' => 'Ȳ', 'ȼ' => 'È»', 'È¿' => 'â±¾', 'É€' => 'Ɀ', 'É‚' => 'É', 'ɇ' => 'Ɇ', 'ɉ' => 'Ɉ', 'É‹' => 'ÉŠ', 'É' => 'ÉŒ', 'É' => 'ÉŽ', 'É' => 'Ɐ', 'É‘' => 'â±­', 'É’' => 'â±°', 'É“' => 'Æ', 'É”' => 'Ɔ', 'É–' => 'Ɖ', 'É—' => 'ÆŠ', 'É™' => 'Æ', 'É›' => 'Æ', 'Éœ' => 'êž«', 'É ' => 'Æ“', 'É¡' => 'Ɡ', 'É£' => 'Æ”', 'É¥' => 'êž', 'ɦ' => 'Ɦ', 'ɨ' => 'Æ—', 'É©' => 'Æ–', 'ɪ' => 'êž®', 'É«' => 'â±¢', 'ɬ' => 'êž­', 'ɯ' => 'Æœ', 'ɱ' => 'â±®', 'ɲ' => 'Æ', 'ɵ' => 'ÆŸ', 'ɽ' => 'Ɽ', 'Ê€' => 'Ʀ', 'Ê‚' => 'Ʂ', 'ʃ' => 'Æ©', 'ʇ' => 'êž±', 'ʈ' => 'Æ®', 'ʉ' => 'É„', 'ÊŠ' => 'Ʊ', 'Ê‹' => 'Ʋ', 'ÊŒ' => 'É…', 'Ê’' => 'Æ·', 'Ê' => 'êž²', 'Êž' => 'êž°', 'Í…' => 'Ι', 'ͱ' => 'Ͱ', 'ͳ' => 'Ͳ', 'Í·' => 'Ͷ', 'Í»' => 'Ͻ', 'ͼ' => 'Ͼ', 'ͽ' => 'Ï¿', 'ά' => 'Ά', 'έ' => 'Έ', 'ή' => 'Ή', 'ί' => 'Ί', 'α' => 'Α', 'β' => 'Î’', 'γ' => 'Γ', 'δ' => 'Δ', 'ε' => 'Ε', 'ζ' => 'Ζ', 'η' => 'Η', 'θ' => 'Θ', 'ι' => 'Ι', 'κ' => 'Κ', 'λ' => 'Λ', 'μ' => 'Μ', 'ν' => 'Î', 'ξ' => 'Ξ', 'ο' => 'Ο', 'Ï€' => 'Π', 'Ï' => 'Ρ', 'Ï‚' => 'Σ', 'σ' => 'Σ', 'Ï„' => 'Τ', 'Ï…' => 'Î¥', 'φ' => 'Φ', 'χ' => 'Χ', 'ψ' => 'Ψ', 'ω' => 'Ω', 'ÏŠ' => 'Ϊ', 'Ï‹' => 'Ϋ', 'ÏŒ' => 'ÎŒ', 'Ï' => 'ÎŽ', 'ÏŽ' => 'Î', 'Ï' => 'Î’', 'Ï‘' => 'Θ', 'Ï•' => 'Φ', 'Ï–' => 'Π', 'Ï—' => 'Ï', 'Ï™' => 'Ϙ', 'Ï›' => 'Ïš', 'Ï' => 'Ïœ', 'ÏŸ' => 'Ïž', 'Ï¡' => 'Ï ', 'Ï£' => 'Ï¢', 'Ï¥' => 'Ϥ', 'ϧ' => 'Ϧ', 'Ï©' => 'Ϩ', 'Ï«' => 'Ϫ', 'Ï­' => 'Ϭ', 'ϯ' => 'Ï®', 'ϰ' => 'Κ', 'ϱ' => 'Ρ', 'ϲ' => 'Ϲ', 'ϳ' => 'Í¿', 'ϵ' => 'Ε', 'ϸ' => 'Ï·', 'Ï»' => 'Ϻ', 'а' => 'Ð', 'б' => 'Б', 'в' => 'Ð’', 'г' => 'Г', 'д' => 'Д', 'е' => 'Е', 'ж' => 'Ж', 'з' => 'З', 'и' => 'И', 'й' => 'Й', 'к' => 'К', 'л' => 'Л', 'м' => 'М', 'н' => 'Ð', 'о' => 'О', 'п' => 'П', 'Ñ€' => 'Р', 'Ñ' => 'С', 'Ñ‚' => 'Т', 'у' => 'У', 'Ñ„' => 'Ф', 'Ñ…' => 'Ð¥', 'ц' => 'Ц', 'ч' => 'Ч', 'ш' => 'Ш', 'щ' => 'Щ', 'ÑŠ' => 'Ъ', 'Ñ‹' => 'Ы', 'ÑŒ' => 'Ь', 'Ñ' => 'Э', 'ÑŽ' => 'Ю', 'Ñ' => 'Я', 'Ñ' => 'Ѐ', 'Ñ‘' => 'Ð', 'Ñ’' => 'Ђ', 'Ñ“' => 'Ѓ', 'Ñ”' => 'Є', 'Ñ•' => 'Ð…', 'Ñ–' => 'І', 'Ñ—' => 'Ї', 'ј' => 'Ј', 'Ñ™' => 'Љ', 'Ñš' => 'Њ', 'Ñ›' => 'Ћ', 'Ñœ' => 'ÐŒ', 'Ñ' => 'Ð', 'Ñž' => 'ÐŽ', 'ÑŸ' => 'Ð', 'Ñ¡' => 'Ñ ', 'Ñ£' => 'Ñ¢', 'Ñ¥' => 'Ѥ', 'ѧ' => 'Ѧ', 'Ñ©' => 'Ѩ', 'Ñ«' => 'Ѫ', 'Ñ­' => 'Ѭ', 'ѯ' => 'Ñ®', 'ѱ' => 'Ѱ', 'ѳ' => 'Ѳ', 'ѵ' => 'Ñ´', 'Ñ·' => 'Ѷ', 'ѹ' => 'Ѹ', 'Ñ»' => 'Ѻ', 'ѽ' => 'Ѽ', 'Ñ¿' => 'Ѿ', 'Ò' => 'Ò€', 'Ò‹' => 'ÒŠ', 'Ò' => 'ÒŒ', 'Ò' => 'ÒŽ', 'Ò‘' => 'Ò', 'Ò“' => 'Ò’', 'Ò•' => 'Ò”', 'Ò—' => 'Ò–', 'Ò™' => 'Ò˜', 'Ò›' => 'Òš', 'Ò' => 'Òœ', 'ÒŸ' => 'Òž', 'Ò¡' => 'Ò ', 'Ò£' => 'Ò¢', 'Ò¥' => 'Ò¤', 'Ò§' => 'Ò¦', 'Ò©' => 'Ò¨', 'Ò«' => 'Òª', 'Ò­' => 'Ò¬', 'Ò¯' => 'Ò®', 'Ò±' => 'Ò°', 'Ò³' => 'Ò²', 'Òµ' => 'Ò´', 'Ò·' => 'Ò¶', 'Ò¹' => 'Ò¸', 'Ò»' => 'Òº', 'Ò½' => 'Ò¼', 'Ò¿' => 'Ò¾', 'Ó‚' => 'Ó', 'Ó„' => 'Óƒ', 'Ó†' => 'Ó…', 'Óˆ' => 'Ó‡', 'ÓŠ' => 'Ó‰', 'ÓŒ' => 'Ó‹', 'ÓŽ' => 'Ó', 'Ó' => 'Ó€', 'Ó‘' => 'Ó', 'Ó“' => 'Ó’', 'Ó•' => 'Ó”', 'Ó—' => 'Ó–', 'Ó™' => 'Ó˜', 'Ó›' => 'Óš', 'Ó' => 'Óœ', 'ÓŸ' => 'Óž', 'Ó¡' => 'Ó ', 'Ó£' => 'Ó¢', 'Ó¥' => 'Ó¤', 'Ó§' => 'Ó¦', 'Ó©' => 'Ó¨', 'Ó«' => 'Óª', 'Ó­' => 'Ó¬', 'Ó¯' => 'Ó®', 'Ó±' => 'Ó°', 'Ó³' => 'Ó²', 'Óµ' => 'Ó´', 'Ó·' => 'Ó¶', 'Ó¹' => 'Ó¸', 'Ó»' => 'Óº', 'Ó½' => 'Ó¼', 'Ó¿' => 'Ó¾', 'Ô' => 'Ô€', 'Ôƒ' => 'Ô‚', 'Ô…' => 'Ô„', 'Ô‡' => 'Ô†', 'Ô‰' => 'Ôˆ', 'Ô‹' => 'ÔŠ', 'Ô' => 'ÔŒ', 'Ô' => 'ÔŽ', 'Ô‘' => 'Ô', 'Ô“' => 'Ô’', 'Ô•' => 'Ô”', 'Ô—' => 'Ô–', 'Ô™' => 'Ô˜', 'Ô›' => 'Ôš', 'Ô' => 'Ôœ', 'ÔŸ' => 'Ôž', 'Ô¡' => 'Ô ', 'Ô£' => 'Ô¢', 'Ô¥' => 'Ô¤', 'Ô§' => 'Ô¦', 'Ô©' => 'Ô¨', 'Ô«' => 'Ôª', 'Ô­' => 'Ô¬', 'Ô¯' => 'Ô®', 'Õ¡' => 'Ô±', 'Õ¢' => 'Ô²', 'Õ£' => 'Ô³', 'Õ¤' => 'Ô´', 'Õ¥' => 'Ôµ', 'Õ¦' => 'Ô¶', 'Õ§' => 'Ô·', 'Õ¨' => 'Ô¸', 'Õ©' => 'Ô¹', 'Õª' => 'Ôº', 'Õ«' => 'Ô»', 'Õ¬' => 'Ô¼', 'Õ­' => 'Ô½', 'Õ®' => 'Ô¾', 'Õ¯' => 'Ô¿', 'Õ°' => 'Õ€', 'Õ±' => 'Õ', 'Õ²' => 'Õ‚', 'Õ³' => 'Õƒ', 'Õ´' => 'Õ„', 'Õµ' => 'Õ…', 'Õ¶' => 'Õ†', 'Õ·' => 'Õ‡', 'Õ¸' => 'Õˆ', 'Õ¹' => 'Õ‰', 'Õº' => 'ÕŠ', 'Õ»' => 'Õ‹', 'Õ¼' => 'ÕŒ', 'Õ½' => 'Õ', 'Õ¾' => 'ÕŽ', 'Õ¿' => 'Õ', 'Ö€' => 'Õ', 'Ö' => 'Õ‘', 'Ö‚' => 'Õ’', 'Öƒ' => 'Õ“', 'Ö„' => 'Õ”', 'Ö…' => 'Õ•', 'Ö†' => 'Õ–', 'áƒ' => 'á²', 'ბ' => 'Ბ', 'გ' => 'á²’', 'დ' => 'Დ', 'ე' => 'á²”', 'ვ' => 'Ვ', 'ზ' => 'á²–', 'თ' => 'á²—', 'ი' => 'Ი', 'კ' => 'á²™', 'ლ' => 'Ლ', 'მ' => 'á²›', 'ნ' => 'Ნ', 'áƒ' => 'á²', 'პ' => 'Პ', 'ჟ' => 'Ჟ', 'რ' => 'á² ', 'ს' => 'Ს', 'ტ' => 'á²¢', 'უ' => 'á²£', 'ფ' => 'Ფ', 'ქ' => 'á²¥', 'ღ' => 'Ღ', 'ყ' => 'á²§', 'შ' => 'Შ', 'ჩ' => 'Ჩ', 'ც' => 'Ც', 'ძ' => 'Ძ', 'წ' => 'Წ', 'ჭ' => 'á²­', 'ხ' => 'á²®', 'ჯ' => 'Ჯ', 'ჰ' => 'á²°', 'ჱ' => 'á²±', 'ჲ' => 'á²²', 'ჳ' => 'á²³', 'ჴ' => 'á²´', 'ჵ' => 'á²µ', 'ჶ' => 'á²¶', 'ჷ' => 'á²·', 'ჸ' => 'Ჸ', 'ჹ' => 'á²¹', 'ჺ' => 'Ჺ', 'ჽ' => 'á²½', 'ჾ' => 'á²¾', 'ჿ' => 'Ჿ', 'á¸' => 'á°', 'á¹' => 'á±', 'áº' => 'á²', 'á»' => 'á³', 'á¼' => 'á´', 'á½' => 'áµ', 'á²€' => 'Ð’', 'á²' => 'Д', 'ᲂ' => 'О', 'ᲃ' => 'С', 'ᲄ' => 'Т', 'á²…' => 'Т', 'ᲆ' => 'Ъ', 'ᲇ' => 'Ñ¢', 'ᲈ' => 'Ꙋ', 'áµ¹' => 'ê½', 'áµ½' => 'â±£', 'á¶Ž' => 'Ᶎ', 'á¸' => 'Ḁ', 'ḃ' => 'Ḃ', 'ḅ' => 'Ḅ', 'ḇ' => 'Ḇ', 'ḉ' => 'Ḉ', 'ḋ' => 'Ḋ', 'á¸' => 'Ḍ', 'á¸' => 'Ḏ', 'ḑ' => 'á¸', 'ḓ' => 'Ḓ', 'ḕ' => 'Ḕ', 'ḗ' => 'Ḗ', 'ḙ' => 'Ḙ', 'ḛ' => 'Ḛ', 'á¸' => 'Ḝ', 'ḟ' => 'Ḟ', 'ḡ' => 'Ḡ', 'ḣ' => 'Ḣ', 'ḥ' => 'Ḥ', 'ḧ' => 'Ḧ', 'ḩ' => 'Ḩ', 'ḫ' => 'Ḫ', 'ḭ' => 'Ḭ', 'ḯ' => 'Ḯ', 'ḱ' => 'Ḱ', 'ḳ' => 'Ḳ', 'ḵ' => 'Ḵ', 'ḷ' => 'Ḷ', 'ḹ' => 'Ḹ', 'ḻ' => 'Ḻ', 'ḽ' => 'Ḽ', 'ḿ' => 'Ḿ', 'á¹' => 'á¹€', 'ṃ' => 'Ṃ', 'á¹…' => 'Ṅ', 'ṇ' => 'Ṇ', 'ṉ' => 'Ṉ', 'ṋ' => 'Ṋ', 'á¹' => 'Ṍ', 'á¹' => 'Ṏ', 'ṑ' => 'á¹', 'ṓ' => 'á¹’', 'ṕ' => 'á¹”', 'á¹—' => 'á¹–', 'á¹™' => 'Ṙ', 'á¹›' => 'Ṛ', 'á¹' => 'Ṝ', 'ṟ' => 'Ṟ', 'ṡ' => 'á¹ ', 'á¹£' => 'á¹¢', 'á¹¥' => 'Ṥ', 'á¹§' => 'Ṧ', 'ṩ' => 'Ṩ', 'ṫ' => 'Ṫ', 'á¹­' => 'Ṭ', 'ṯ' => 'á¹®', 'á¹±' => 'á¹°', 'á¹³' => 'á¹²', 'á¹µ' => 'á¹´', 'á¹·' => 'á¹¶', 'á¹¹' => 'Ṹ', 'á¹»' => 'Ṻ', 'á¹½' => 'á¹¼', 'ṿ' => 'á¹¾', 'áº' => 'Ẁ', 'ẃ' => 'Ẃ', 'ẅ' => 'Ẅ', 'ẇ' => 'Ẇ', 'ẉ' => 'Ẉ', 'ẋ' => 'Ẋ', 'áº' => 'Ẍ', 'áº' => 'Ẏ', 'ẑ' => 'áº', 'ẓ' => 'Ẓ', 'ẕ' => 'Ẕ', 'ẛ' => 'á¹ ', 'ạ' => 'Ạ', 'ả' => 'Ả', 'ấ' => 'Ấ', 'ầ' => 'Ầ', 'ẩ' => 'Ẩ', 'ẫ' => 'Ẫ', 'ậ' => 'Ậ', 'ắ' => 'Ắ', 'ằ' => 'Ằ', 'ẳ' => 'Ẳ', 'ẵ' => 'Ẵ', 'ặ' => 'Ặ', 'ẹ' => 'Ẹ', 'ẻ' => 'Ẻ', 'ẽ' => 'Ẽ', 'ế' => 'Ế', 'á»' => 'Ề', 'ể' => 'Ể', 'á»…' => 'Ễ', 'ệ' => 'Ệ', 'ỉ' => 'Ỉ', 'ị' => 'Ị', 'á»' => 'Ọ', 'á»' => 'Ỏ', 'ố' => 'á»', 'ồ' => 'á»’', 'ổ' => 'á»”', 'á»—' => 'á»–', 'á»™' => 'Ộ', 'á»›' => 'Ớ', 'á»' => 'Ờ', 'ở' => 'Ở', 'ỡ' => 'á» ', 'ợ' => 'Ợ', 'ụ' => 'Ụ', 'á»§' => 'Ủ', 'ứ' => 'Ứ', 'ừ' => 'Ừ', 'á»­' => 'Ử', 'ữ' => 'á»®', 'á»±' => 'á»°', 'ỳ' => 'Ỳ', 'ỵ' => 'á»´', 'á»·' => 'á»¶', 'ỹ' => 'Ỹ', 'á»»' => 'Ỻ', 'ỽ' => 'Ỽ', 'ỿ' => 'Ỿ', 'á¼€' => 'Ἀ', 'á¼' => 'Ἁ', 'ἂ' => 'Ἂ', 'ἃ' => 'Ἃ', 'ἄ' => 'Ἄ', 'á¼…' => 'á¼', 'ἆ' => 'Ἆ', 'ἇ' => 'á¼', 'á¼' => 'Ἐ', 'ἑ' => 'á¼™', 'á¼’' => 'Ἒ', 'ἓ' => 'á¼›', 'á¼”' => 'Ἔ', 'ἕ' => 'á¼', 'á¼ ' => 'Ἠ', 'ἡ' => 'Ἡ', 'á¼¢' => 'Ἢ', 'á¼£' => 'Ἣ', 'ἤ' => 'Ἤ', 'á¼¥' => 'á¼­', 'ἦ' => 'á¼®', 'á¼§' => 'Ἧ', 'á¼°' => 'Ἰ', 'á¼±' => 'á¼¹', 'á¼²' => 'Ἲ', 'á¼³' => 'á¼»', 'á¼´' => 'á¼¼', 'á¼µ' => 'á¼½', 'á¼¶' => 'á¼¾', 'á¼·' => 'Ἷ', 'á½€' => 'Ὀ', 'á½' => 'Ὁ', 'ὂ' => 'Ὂ', 'ὃ' => 'Ὃ', 'ὄ' => 'Ὄ', 'á½…' => 'á½', 'ὑ' => 'á½™', 'ὓ' => 'á½›', 'ὕ' => 'á½', 'á½—' => 'Ὗ', 'á½ ' => 'Ὠ', 'ὡ' => 'Ὡ', 'á½¢' => 'Ὢ', 'á½£' => 'Ὣ', 'ὤ' => 'Ὤ', 'á½¥' => 'á½­', 'ὦ' => 'á½®', 'á½§' => 'Ὧ', 'á½°' => 'Ὰ', 'á½±' => 'á¾»', 'á½²' => 'Ὲ', 'á½³' => 'Έ', 'á½´' => 'Ὴ', 'á½µ' => 'á¿‹', 'á½¶' => 'Ὶ', 'á½·' => 'á¿›', 'ὸ' => 'Ὸ', 'á½¹' => 'Ό', 'ὺ' => 'Ὺ', 'á½»' => 'á¿«', 'á½¼' => 'Ὼ', 'á½½' => 'á¿»', 'á¾€' => 'ἈΙ', 'á¾' => 'ἉΙ', 'ᾂ' => 'ἊΙ', 'ᾃ' => 'ἋΙ', 'ᾄ' => 'ἌΙ', 'á¾…' => 'á¼Î™', 'ᾆ' => 'ἎΙ', 'ᾇ' => 'á¼Î™', 'á¾' => 'ἨΙ', 'ᾑ' => 'ἩΙ', 'á¾’' => 'ἪΙ', 'ᾓ' => 'ἫΙ', 'á¾”' => 'ἬΙ', 'ᾕ' => 'ἭΙ', 'á¾–' => 'ἮΙ', 'á¾—' => 'ἯΙ', 'á¾ ' => 'ὨΙ', 'ᾡ' => 'ὩΙ', 'á¾¢' => 'ὪΙ', 'á¾£' => 'ὫΙ', 'ᾤ' => 'ὬΙ', 'á¾¥' => 'ὭΙ', 'ᾦ' => 'ὮΙ', 'á¾§' => 'ὯΙ', 'á¾°' => 'Ᾰ', 'á¾±' => 'á¾¹', 'á¾³' => 'ΑΙ', 'á¾¾' => 'Ι', 'ῃ' => 'ΗΙ', 'á¿' => 'Ῐ', 'á¿‘' => 'á¿™', 'á¿ ' => 'Ῠ', 'á¿¡' => 'á¿©', 'á¿¥' => 'Ῥ', 'ῳ' => 'ΩΙ', 'â…Ž' => 'Ⅎ', 'â…°' => 'â… ', 'â…±' => 'â…¡', 'â…²' => 'â…¢', 'â…³' => 'â…£', 'â…´' => 'â…¤', 'â…µ' => 'â…¥', 'â…¶' => 'â…¦', 'â…·' => 'â…§', 'â…¸' => 'â…¨', 'â…¹' => 'â…©', 'â…º' => 'â…ª', 'â…»' => 'â…«', 'â…¼' => 'â…¬', 'â…½' => 'â…­', 'â…¾' => 'â…®', 'â…¿' => 'â…¯', 'ↄ' => 'Ↄ', 'â“' => 'â’¶', 'â“‘' => 'â’·', 'â“’' => 'â’¸', 'â““' => 'â’¹', 'â“”' => 'â’º', 'â“•' => 'â’»', 'â“–' => 'â’¼', 'â“—' => 'â’½', 'ⓘ' => 'â’¾', 'â“™' => 'â’¿', 'ⓚ' => 'â“€', 'â“›' => 'â“', 'ⓜ' => 'â“‚', 'â“' => 'Ⓝ', 'ⓞ' => 'â“„', 'ⓟ' => 'â“…', 'â“ ' => 'Ⓠ', 'â“¡' => 'Ⓡ', 'â“¢' => 'Ⓢ', 'â“£' => 'Ⓣ', 'ⓤ' => 'Ⓤ', 'â“¥' => 'â“‹', 'ⓦ' => 'Ⓦ', 'â“§' => 'â“', 'ⓨ' => 'Ⓨ', 'â“©' => 'â“', 'â°°' => 'â°€', 'â°±' => 'â°', 'â°²' => 'â°‚', 'â°³' => 'â°ƒ', 'â°´' => 'â°„', 'â°µ' => 'â°…', 'â°¶' => 'â°†', 'â°·' => 'â°‡', 'â°¸' => 'â°ˆ', 'â°¹' => 'â°‰', 'â°º' => 'â°Š', 'â°»' => 'â°‹', 'â°¼' => 'â°Œ', 'â°½' => 'â°', 'â°¾' => 'â°Ž', 'â°¿' => 'â°', 'â±€' => 'â°', 'â±' => 'â°‘', 'ⱂ' => 'â°’', 'ⱃ' => 'â°“', 'ⱄ' => 'â°”', 'â±…' => 'â°•', 'ⱆ' => 'â°–', 'ⱇ' => 'â°—', 'ⱈ' => 'â°˜', 'ⱉ' => 'â°™', 'ⱊ' => 'â°š', 'ⱋ' => 'â°›', 'ⱌ' => 'â°œ', 'â±' => 'â°', 'ⱎ' => 'â°ž', 'â±' => 'â°Ÿ', 'â±' => 'â° ', 'ⱑ' => 'â°¡', 'â±’' => 'â°¢', 'ⱓ' => 'â°£', 'â±”' => 'â°¤', 'ⱕ' => 'â°¥', 'â±–' => 'â°¦', 'â±—' => 'â°§', 'ⱘ' => 'â°¨', 'â±™' => 'â°©', 'ⱚ' => 'â°ª', 'â±›' => 'â°«', 'ⱜ' => 'â°¬', 'â±' => 'â°­', 'ⱞ' => 'â°®', 'ⱡ' => 'â± ', 'â±¥' => 'Ⱥ', 'ⱦ' => 'Ⱦ', 'ⱨ' => 'â±§', 'ⱪ' => 'Ⱪ', 'ⱬ' => 'Ⱬ', 'â±³' => 'â±²', 'â±¶' => 'â±µ', 'â²' => 'â²€', 'ⲃ' => 'Ⲃ', 'â²…' => 'Ⲅ', 'ⲇ' => 'Ⲇ', 'ⲉ' => 'Ⲉ', 'ⲋ' => 'Ⲋ', 'â²' => 'Ⲍ', 'â²' => 'Ⲏ', 'ⲑ' => 'â²', 'ⲓ' => 'â²’', 'ⲕ' => 'â²”', 'â²—' => 'â²–', 'â²™' => 'Ⲙ', 'â²›' => 'Ⲛ', 'â²' => 'Ⲝ', 'ⲟ' => 'Ⲟ', 'ⲡ' => 'â² ', 'â²£' => 'â²¢', 'â²¥' => 'Ⲥ', 'â²§' => 'Ⲧ', 'ⲩ' => 'Ⲩ', 'ⲫ' => 'Ⲫ', 'â²­' => 'Ⲭ', 'ⲯ' => 'â²®', 'â²±' => 'â²°', 'â²³' => 'â²²', 'â²µ' => 'â²´', 'â²·' => 'â²¶', 'â²¹' => 'Ⲹ', 'â²»' => 'Ⲻ', 'â²½' => 'â²¼', 'ⲿ' => 'â²¾', 'â³' => 'â³€', 'ⳃ' => 'Ⳃ', 'â³…' => 'Ⳅ', 'ⳇ' => 'Ⳇ', 'ⳉ' => 'Ⳉ', 'ⳋ' => 'Ⳋ', 'â³' => 'Ⳍ', 'â³' => 'Ⳏ', 'ⳑ' => 'â³', 'ⳓ' => 'â³’', 'ⳕ' => 'â³”', 'â³—' => 'â³–', 'â³™' => 'Ⳙ', 'â³›' => 'Ⳛ', 'â³' => 'Ⳝ', 'ⳟ' => 'Ⳟ', 'ⳡ' => 'â³ ', 'â³£' => 'â³¢', 'ⳬ' => 'Ⳬ', 'â³®' => 'â³­', 'â³³' => 'â³²', 'â´€' => 'á‚ ', 'â´' => 'á‚¡', 'â´‚' => 'á‚¢', 'â´ƒ' => 'á‚£', 'â´„' => 'Ⴄ', 'â´…' => 'á‚¥', 'â´†' => 'Ⴆ', 'â´‡' => 'á‚§', 'â´ˆ' => 'Ⴈ', 'â´‰' => 'á‚©', 'â´Š' => 'Ⴊ', 'â´‹' => 'á‚«', 'â´Œ' => 'Ⴌ', 'â´' => 'á‚­', 'â´Ž' => 'á‚®', 'â´' => 'Ⴏ', 'â´' => 'á‚°', 'â´‘' => 'Ⴑ', 'â´’' => 'Ⴒ', 'â´“' => 'Ⴓ', 'â´”' => 'á‚´', 'â´•' => 'Ⴕ', 'â´–' => 'á‚¶', 'â´—' => 'á‚·', 'â´˜' => 'Ⴘ', 'â´™' => 'Ⴙ', 'â´š' => 'Ⴚ', 'â´›' => 'á‚»', 'â´œ' => 'Ⴜ', 'â´' => 'Ⴝ', 'â´ž' => 'Ⴞ', 'â´Ÿ' => 'á‚¿', 'â´ ' => 'Ⴠ', 'â´¡' => 'áƒ', 'â´¢' => 'Ⴢ', 'â´£' => 'Ⴣ', 'â´¤' => 'Ⴤ', 'â´¥' => 'Ⴥ', 'â´§' => 'Ⴧ', 'â´­' => 'áƒ', 'ê™' => 'Ꙁ', 'ꙃ' => 'Ꙃ', 'ê™…' => 'Ꙅ', 'ꙇ' => 'Ꙇ', 'ꙉ' => 'Ꙉ', 'ꙋ' => 'Ꙋ', 'ê™' => 'Ꙍ', 'ê™' => 'Ꙏ', 'ꙑ' => 'ê™', 'ꙓ' => 'ê™’', 'ꙕ' => 'ê™”', 'ê™—' => 'ê™–', 'ê™™' => 'Ꙙ', 'ê™›' => 'Ꙛ', 'ê™' => 'Ꙝ', 'ꙟ' => 'Ꙟ', 'ꙡ' => 'ê™ ', 'ꙣ' => 'Ꙣ', 'ꙥ' => 'Ꙥ', 'ê™§' => 'Ꙧ', 'ꙩ' => 'Ꙩ', 'ꙫ' => 'Ꙫ', 'ê™­' => 'Ꙭ', 'êš' => 'Ꚁ', 'ꚃ' => 'êš‚', 'êš…' => 'êš„', 'ꚇ' => 'Ꚇ', 'ꚉ' => 'Ꚉ', 'êš‹' => 'Ꚋ', 'êš' => 'Ꚍ', 'êš' => 'Ꚏ', 'êš‘' => 'êš', 'êš“' => 'êš’', 'êš•' => 'êš”', 'êš—' => 'êš–', 'êš™' => 'Ꚙ', 'êš›' => 'êšš', 'ꜣ' => 'Ꜣ', 'ꜥ' => 'Ꜥ', 'ꜧ' => 'Ꜧ', 'ꜩ' => 'Ꜩ', 'ꜫ' => 'Ꜫ', 'ꜭ' => 'Ꜭ', 'ꜯ' => 'Ꜯ', 'ꜳ' => 'Ꜳ', 'ꜵ' => 'Ꜵ', 'ꜷ' => 'Ꜷ', 'ꜹ' => 'Ꜹ', 'ꜻ' => 'Ꜻ', 'ꜽ' => 'Ꜽ', 'ꜿ' => 'Ꜿ', 'ê' => 'ê€', 'êƒ' => 'ê‚', 'ê…' => 'ê„', 'ê‡' => 'ê†', 'ê‰' => 'êˆ', 'ê‹' => 'êŠ', 'ê' => 'êŒ', 'ê' => 'êŽ', 'ê‘' => 'ê', 'ê“' => 'ê’', 'ê•' => 'ê”', 'ê—' => 'ê–', 'ê™' => 'ê˜', 'ê›' => 'êš', 'ê' => 'êœ', 'êŸ' => 'êž', 'ê¡' => 'ê ', 'ê£' => 'ê¢', 'ê¥' => 'ê¤', 'ê§' => 'ê¦', 'ê©' => 'ê¨', 'ê«' => 'êª', 'ê­' => 'ê¬', 'ê¯' => 'ê®', 'êº' => 'ê¹', 'ê¼' => 'ê»', 'ê¿' => 'ê¾', 'êž' => 'Ꞁ', 'ꞃ' => 'êž‚', 'êž…' => 'êž„', 'ꞇ' => 'Ꞇ', 'ꞌ' => 'êž‹', 'êž‘' => 'êž', 'êž“' => 'êž’', 'êž”' => 'Ꞔ', 'êž—' => 'êž–', 'êž™' => 'Ꞙ', 'êž›' => 'êžš', 'êž' => 'êžœ', 'ꞟ' => 'êžž', 'êž¡' => 'êž ', 'ꞣ' => 'Ꞣ', 'ꞥ' => 'Ꞥ', 'êž§' => 'Ꞧ', 'êž©' => 'Ꞩ', 'êžµ' => 'êž´', 'êž·' => 'êž¶', 'êž¹' => 'Ꞹ', 'êž»' => 'Ꞻ', 'êž½' => 'êž¼', 'êž¿' => 'êž¾', 'ꟃ' => 'Ꟃ', 'ꟈ' => 'Ꟈ', 'ꟊ' => 'Ꟊ', 'ꟶ' => 'Ꟶ', 'ê­“' => 'êž³', 'ê­°' => 'Ꭰ', 'ê­±' => 'Ꭱ', 'ê­²' => 'Ꭲ', 'ê­³' => 'Ꭳ', 'ê­´' => 'Ꭴ', 'ê­µ' => 'Ꭵ', 'ê­¶' => 'Ꭶ', 'ê­·' => 'Ꭷ', 'ê­¸' => 'Ꭸ', 'ê­¹' => 'Ꭹ', 'ê­º' => 'Ꭺ', 'ê­»' => 'Ꭻ', 'ê­¼' => 'Ꭼ', 'ê­½' => 'Ꭽ', 'ê­¾' => 'Ꭾ', 'ê­¿' => 'Ꭿ', 'ꮀ' => 'Ꮀ', 'ê®' => 'Ꮁ', 'ꮂ' => 'Ꮂ', 'ꮃ' => 'Ꮃ', 'ꮄ' => 'Ꮄ', 'ê®…' => 'Ꮅ', 'ꮆ' => 'Ꮆ', 'ꮇ' => 'Ꮇ', 'ꮈ' => 'Ꮈ', 'ꮉ' => 'Ꮉ', 'ꮊ' => 'Ꮊ', 'ꮋ' => 'Ꮋ', 'ꮌ' => 'Ꮌ', 'ê®' => 'Ꮍ', 'ꮎ' => 'Ꮎ', 'ê®' => 'Ꮏ', 'ê®' => 'á€', 'ꮑ' => 'á', 'ê®’' => 'á‚', 'ꮓ' => 'áƒ', 'ê®”' => 'á„', 'ꮕ' => 'á…', 'ê®–' => 'á†', 'ê®—' => 'á‡', 'ꮘ' => 'áˆ', 'ê®™' => 'á‰', 'ꮚ' => 'áŠ', 'ê®›' => 'á‹', 'ꮜ' => 'áŒ', 'ê®' => 'á', 'ꮞ' => 'áŽ', 'ꮟ' => 'á', 'ê® ' => 'á', 'ꮡ' => 'á‘', 'ꮢ' => 'á’', 'ꮣ' => 'á“', 'ꮤ' => 'á”', 'ꮥ' => 'á•', 'ꮦ' => 'á–', 'ê®§' => 'á—', 'ꮨ' => 'á˜', 'ꮩ' => 'á™', 'ꮪ' => 'áš', 'ꮫ' => 'á›', 'ꮬ' => 'áœ', 'ê®­' => 'á', 'ê®®' => 'áž', 'ꮯ' => 'áŸ', 'ê®°' => 'á ', 'ê®±' => 'á¡', 'ꮲ' => 'á¢', 'ꮳ' => 'á£', 'ê®´' => 'á¤', 'ꮵ' => 'á¥', 'ê®¶' => 'á¦', 'ê®·' => 'á§', 'ꮸ' => 'á¨', 'ꮹ' => 'á©', 'ꮺ' => 'áª', 'ê®»' => 'á«', 'ꮼ' => 'á¬', 'ꮽ' => 'á­', 'ꮾ' => 'á®', 'ꮿ' => 'á¯', 'ï½' => 'A', 'b' => 'ï¼¢', 'c' => 'ï¼£', 'd' => 'D', 'ï½…' => 'ï¼¥', 'f' => 'F', 'g' => 'ï¼§', 'h' => 'H', 'i' => 'I', 'j' => 'J', 'k' => 'K', 'l' => 'L', 'ï½' => 'ï¼­', 'n' => 'ï¼®', 'ï½' => 'O', 'ï½' => 'ï¼°', 'q' => 'ï¼±', 'ï½’' => 'ï¼²', 's' => 'ï¼³', 'ï½”' => 'ï¼´', 'u' => 'ï¼µ', 'ï½–' => 'ï¼¶', 'ï½—' => 'ï¼·', 'x' => 'X', 'ï½™' => 'ï¼¹', 'z' => 'Z', 'ð¨' => 'ð€', 'ð©' => 'ð', 'ðª' => 'ð‚', 'ð«' => 'ðƒ', 'ð¬' => 'ð„', 'ð­' => 'ð…', 'ð®' => 'ð†', 'ð¯' => 'ð‡', 'ð°' => 'ðˆ', 'ð±' => 'ð‰', 'ð²' => 'ðŠ', 'ð³' => 'ð‹', 'ð´' => 'ðŒ', 'ðµ' => 'ð', 'ð¶' => 'ðŽ', 'ð·' => 'ð', 'ð¸' => 'ð', 'ð¹' => 'ð‘', 'ðº' => 'ð’', 'ð»' => 'ð“', 'ð¼' => 'ð”', 'ð½' => 'ð•', 'ð¾' => 'ð–', 'ð¿' => 'ð—', 'ð‘€' => 'ð˜', 'ð‘' => 'ð™', 'ð‘‚' => 'ðš', 'ð‘ƒ' => 'ð›', 'ð‘„' => 'ðœ', 'ð‘…' => 'ð', 'ð‘†' => 'ðž', 'ð‘‡' => 'ðŸ', 'ð‘ˆ' => 'ð ', 'ð‘‰' => 'ð¡', 'ð‘Š' => 'ð¢', 'ð‘‹' => 'ð£', 'ð‘Œ' => 'ð¤', 'ð‘' => 'ð¥', 'ð‘Ž' => 'ð¦', 'ð‘' => 'ð§', 'ð“˜' => 'ð’°', 'ð“™' => 'ð’±', 'ð“š' => 'ð’²', 'ð“›' => 'ð’³', 'ð“œ' => 'ð’´', 'ð“' => 'ð’µ', 'ð“ž' => 'ð’¶', 'ð“Ÿ' => 'ð’·', 'ð“ ' => 'ð’¸', 'ð“¡' => 'ð’¹', 'ð“¢' => 'ð’º', 'ð“£' => 'ð’»', 'ð“¤' => 'ð’¼', 'ð“¥' => 'ð’½', 'ð“¦' => 'ð’¾', 'ð“§' => 'ð’¿', 'ð“¨' => 'ð“€', 'ð“©' => 'ð“', 'ð“ª' => 'ð“‚', 'ð“«' => 'ð“ƒ', 'ð“¬' => 'ð“„', 'ð“­' => 'ð“…', 'ð“®' => 'ð“†', 'ð“¯' => 'ð“‡', 'ð“°' => 'ð“ˆ', 'ð“±' => 'ð“‰', 'ð“²' => 'ð“Š', 'ð“³' => 'ð“‹', 'ð“´' => 'ð“Œ', 'ð“µ' => 'ð“', 'ð“¶' => 'ð“Ž', 'ð“·' => 'ð“', 'ð“¸' => 'ð“', 'ð“¹' => 'ð“‘', 'ð“º' => 'ð“’', 'ð“»' => 'ð““', 'ð³€' => 'ð²€', 'ð³' => 'ð²', 'ð³‚' => 'ð²‚', 'ð³ƒ' => 'ð²ƒ', 'ð³„' => 'ð²„', 'ð³…' => 'ð²…', 'ð³†' => 'ð²†', 'ð³‡' => 'ð²‡', 'ð³ˆ' => 'ð²ˆ', 'ð³‰' => 'ð²‰', 'ð³Š' => 'ð²Š', 'ð³‹' => 'ð²‹', 'ð³Œ' => 'ð²Œ', 'ð³' => 'ð²', 'ð³Ž' => 'ð²Ž', 'ð³' => 'ð²', 'ð³' => 'ð²', 'ð³‘' => 'ð²‘', 'ð³’' => 'ð²’', 'ð³“' => 'ð²“', 'ð³”' => 'ð²”', 'ð³•' => 'ð²•', 'ð³–' => 'ð²–', 'ð³—' => 'ð²—', 'ð³˜' => 'ð²˜', 'ð³™' => 'ð²™', 'ð³š' => 'ð²š', 'ð³›' => 'ð²›', 'ð³œ' => 'ð²œ', 'ð³' => 'ð²', 'ð³ž' => 'ð²ž', 'ð³Ÿ' => 'ð²Ÿ', 'ð³ ' => 'ð² ', 'ð³¡' => 'ð²¡', 'ð³¢' => 'ð²¢', 'ð³£' => 'ð²£', 'ð³¤' => 'ð²¤', 'ð³¥' => 'ð²¥', 'ð³¦' => 'ð²¦', 'ð³§' => 'ð²§', 'ð³¨' => 'ð²¨', 'ð³©' => 'ð²©', 'ð³ª' => 'ð²ª', 'ð³«' => 'ð²«', 'ð³¬' => 'ð²¬', 'ð³­' => 'ð²­', 'ð³®' => 'ð²®', 'ð³¯' => 'ð²¯', 'ð³°' => 'ð²°', 'ð³±' => 'ð²±', 'ð³²' => 'ð²²', 'ð‘£€' => 'ð‘¢ ', 'ð‘£' => '𑢡', '𑣂' => 'ð‘¢¢', '𑣃' => 'ð‘¢£', '𑣄' => '𑢤', 'ð‘£…' => 'ð‘¢¥', '𑣆' => '𑢦', '𑣇' => 'ð‘¢§', '𑣈' => '𑢨', '𑣉' => '𑢩', '𑣊' => '𑢪', '𑣋' => '𑢫', '𑣌' => '𑢬', 'ð‘£' => 'ð‘¢­', '𑣎' => 'ð‘¢®', 'ð‘£' => '𑢯', 'ð‘£' => 'ð‘¢°', '𑣑' => 'ð‘¢±', 'ð‘£’' => 'ð‘¢²', '𑣓' => 'ð‘¢³', 'ð‘£”' => 'ð‘¢´', '𑣕' => 'ð‘¢µ', 'ð‘£–' => 'ð‘¢¶', 'ð‘£—' => 'ð‘¢·', '𑣘' => '𑢸', 'ð‘£™' => 'ð‘¢¹', '𑣚' => '𑢺', 'ð‘£›' => 'ð‘¢»', '𑣜' => 'ð‘¢¼', 'ð‘£' => 'ð‘¢½', '𑣞' => 'ð‘¢¾', '𑣟' => '𑢿', 'ð–¹ ' => 'ð–¹€', '𖹡' => 'ð–¹', 'ð–¹¢' => '𖹂', 'ð–¹£' => '𖹃', '𖹤' => '𖹄', 'ð–¹¥' => 'ð–¹…', '𖹦' => '𖹆', 'ð–¹§' => '𖹇', '𖹨' => '𖹈', '𖹩' => '𖹉', '𖹪' => '𖹊', '𖹫' => '𖹋', '𖹬' => '𖹌', 'ð–¹­' => 'ð–¹', 'ð–¹®' => '𖹎', '𖹯' => 'ð–¹', 'ð–¹°' => 'ð–¹', 'ð–¹±' => '𖹑', 'ð–¹²' => 'ð–¹’', 'ð–¹³' => '𖹓', 'ð–¹´' => 'ð–¹”', 'ð–¹µ' => '𖹕', 'ð–¹¶' => 'ð–¹–', 'ð–¹·' => 'ð–¹—', '𖹸' => '𖹘', 'ð–¹¹' => 'ð–¹™', '𖹺' => '𖹚', 'ð–¹»' => 'ð–¹›', 'ð–¹¼' => '𖹜', 'ð–¹½' => 'ð–¹', 'ð–¹¾' => '𖹞', '𖹿' => '𖹟', '𞤢' => '𞤀', '𞤣' => 'ðž¤', '𞤤' => '𞤂', '𞤥' => '𞤃', '𞤦' => '𞤄', '𞤧' => '𞤅', '𞤨' => '𞤆', '𞤩' => '𞤇', '𞤪' => '𞤈', '𞤫' => '𞤉', '𞤬' => '𞤊', '𞤭' => '𞤋', '𞤮' => '𞤌', '𞤯' => 'ðž¤', '𞤰' => '𞤎', '𞤱' => 'ðž¤', '𞤲' => 'ðž¤', '𞤳' => '𞤑', '𞤴' => '𞤒', '𞤵' => '𞤓', '𞤶' => '𞤔', '𞤷' => '𞤕', '𞤸' => '𞤖', '𞤹' => '𞤗', '𞤺' => '𞤘', '𞤻' => '𞤙', '𞤼' => '𞤚', '𞤽' => '𞤛', '𞤾' => '𞤜', '𞤿' => 'ðž¤', '𞥀' => '𞤞', 'ðž¥' => '𞤟', '𞥂' => '𞤠', '𞥃' => '𞤡', 'ß' => 'SS', 'ff' => 'FF', 'ï¬' => 'FI', 'fl' => 'FL', 'ffi' => 'FFI', 'ffl' => 'FFL', 'ſt' => 'ST', 'st' => 'ST', 'Ö‡' => 'ÔµÕ’', 'ﬓ' => 'Õ„Õ†', 'ﬔ' => 'Õ„Ôµ', 'ﬕ' => 'Õ„Ô»', 'ﬖ' => 'ÕŽÕ†', 'ﬗ' => 'Õ„Ô½', 'ʼn' => 'ʼN', 'Î' => 'ΪÌ', 'ΰ' => 'ΫÌ', 'ǰ' => 'JÌŒ', 'ẖ' => 'H̱', 'ẗ' => 'T̈', 'ẘ' => 'WÌŠ', 'ẙ' => 'YÌŠ', 'ẚ' => 'Aʾ', 'á½' => 'Υ̓', 'á½’' => 'Υ̓̀', 'á½”' => 'Υ̓Ì', 'á½–' => 'Υ̓͂', 'á¾¶' => 'Α͂', 'ῆ' => 'Η͂', 'á¿’' => 'Ϊ̀', 'á¿“' => 'ΪÌ', 'á¿–' => 'Ι͂', 'á¿—' => 'Ϊ͂', 'á¿¢' => 'Ϋ̀', 'á¿£' => 'ΫÌ', 'ῤ' => 'Ρ̓', 'ῦ' => 'Υ͂', 'á¿§' => 'Ϋ͂', 'á¿¶' => 'Ω͂', 'ᾈ' => 'ἈΙ', 'ᾉ' => 'ἉΙ', 'ᾊ' => 'ἊΙ', 'ᾋ' => 'ἋΙ', 'ᾌ' => 'ἌΙ', 'á¾' => 'á¼Î™', 'ᾎ' => 'ἎΙ', 'á¾' => 'á¼Î™', 'ᾘ' => 'ἨΙ', 'á¾™' => 'ἩΙ', 'ᾚ' => 'ἪΙ', 'á¾›' => 'ἫΙ', 'ᾜ' => 'ἬΙ', 'á¾' => 'ἭΙ', 'ᾞ' => 'ἮΙ', 'ᾟ' => 'ἯΙ', 'ᾨ' => 'ὨΙ', 'ᾩ' => 'ὩΙ', 'ᾪ' => 'ὪΙ', 'ᾫ' => 'ὫΙ', 'ᾬ' => 'ὬΙ', 'á¾­' => 'ὭΙ', 'á¾®' => 'ὮΙ', 'ᾯ' => 'ὯΙ', 'á¾¼' => 'ΑΙ', 'ῌ' => 'ΗΙ', 'ῼ' => 'ΩΙ', 'á¾²' => 'ᾺΙ', 'á¾´' => 'ΆΙ', 'á¿‚' => 'ῊΙ', 'á¿„' => 'ΉΙ', 'ῲ' => 'ῺΙ', 'á¿´' => 'ÎΙ', 'á¾·' => 'Α͂Ι', 'ῇ' => 'Η͂Ι', 'á¿·' => 'Ω͂Ι'); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/bootstrap.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/bootstrap.php new file mode 100644 index 0000000..6addf61 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/bootstrap.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PostSMTP\Vendor\Symfony\Polyfill\Mbstring as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('mb_convert_encoding')) { + function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + function mb_language($language = null) { return p\Mbstring::mb_language($language); } +} +if (!function_exists('mb_list_encodings')) { + function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } +} +if (!function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } +} +if (!function_exists('mb_check_encoding')) { + function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } +} +if (!function_exists('mb_detect_order')) { + function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } +} +if (!function_exists('mb_strpos')) { + function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_get_info')) { + function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } +} +if (!function_exists('mb_http_output')) { + function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } +} +if (!function_exists('mb_http_input')) { + function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } +} + +if (!function_exists('mb_ord')) { + function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (extension_loaded('mbstring')) { + return; +} + +if (!defined('MB_CASE_UPPER')) { + define('MB_CASE_UPPER', 0); +} +if (!defined('MB_CASE_LOWER')) { + define('MB_CASE_LOWER', 1); +} +if (!defined('MB_CASE_TITLE')) { + define('MB_CASE_TITLE', 2); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/bootstrap80.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/bootstrap80.php new file mode 100644 index 0000000..108d56b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-mbstring/bootstrap80.php @@ -0,0 +1,261 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +use PostSMTP\Vendor\Symfony\Polyfill\Mbstring as p; +if (!\function_exists('mb_convert_encoding')) { + function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null) : array|string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); + } +} +if (!\function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader(?string $string) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_decode_mimeheader((string) $string); + } +} +if (!\function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); + } +} +if (!\function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); + } +} +if (!\function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = \false) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); + } +} +if (!\function_exists('mb_convert_case')) { + function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); + } +} +if (!\function_exists('mb_internal_encoding')) { + function mb_internal_encoding(?string $encoding = null) : string|bool + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_internal_encoding($encoding); + } +} +if (!\function_exists('mb_language')) { + function mb_language(?string $language = null) : string|bool + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_language($language); + } +} +if (!\function_exists('mb_list_encodings')) { + function mb_list_encodings() : array + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_list_encodings(); + } +} +if (!\function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases(?string $encoding) : array + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_encoding_aliases((string) $encoding); + } +} +if (!\function_exists('mb_check_encoding')) { + function mb_check_encoding(array|string|null $value = null, ?string $encoding = null) : bool + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_check_encoding($value, $encoding); + } +} +if (!\function_exists('mb_detect_encoding')) { + function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = \false) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); + } +} +if (!\function_exists('mb_detect_order')) { + function mb_detect_order(array|string|null $encoding = null) : array|bool + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_detect_order($encoding); + } +} +if (!\function_exists('mb_parse_str')) { + function mb_parse_str(?string $string, &$result = []) : bool + { + \parse_str((string) $string, $result); + return (bool) $result; + } +} +if (!\function_exists('mb_strlen')) { + function mb_strlen(?string $string, ?string $encoding = null) : int + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strlen((string) $string, $encoding); + } +} +if (!\function_exists('mb_strpos')) { + function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); + } +} +if (!\function_exists('mb_strtolower')) { + function mb_strtolower(?string $string, ?string $encoding = null) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strtolower((string) $string, $encoding); + } +} +if (!\function_exists('mb_strtoupper')) { + function mb_strtoupper(?string $string, ?string $encoding = null) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strtoupper((string) $string, $encoding); + } +} +if (!\function_exists('mb_substitute_character')) { + function mb_substitute_character(string|int|null $substitute_character = null) : string|int|bool + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_substitute_character($substitute_character); + } +} +if (!\function_exists('mb_substr')) { + function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); + } +} +if (!\function_exists('mb_stripos')) { + function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); + } +} +if (!\function_exists('mb_stristr')) { + function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); + } +} +if (!\function_exists('mb_strrchr')) { + function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); + } +} +if (!\function_exists('mb_strrichr')) { + function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); + } +} +if (!\function_exists('mb_strripos')) { + function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); + } +} +if (!\function_exists('mb_strrpos')) { + function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); + } +} +if (!\function_exists('mb_strstr')) { + function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); + } +} +if (!\function_exists('mb_get_info')) { + function mb_get_info(?string $type = 'all') : array|string|int|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_get_info((string) $type); + } +} +if (!\function_exists('mb_http_output')) { + function mb_http_output(?string $encoding = null) : string|bool + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_http_output($encoding); + } +} +if (!\function_exists('mb_strwidth')) { + function mb_strwidth(?string $string, ?string $encoding = null) : int + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_strwidth((string) $string, $encoding); + } +} +if (!\function_exists('mb_substr_count')) { + function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null) : int + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); + } +} +if (!\function_exists('mb_output_handler')) { + function mb_output_handler(?string $string, ?int $status) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_output_handler((string) $string, (int) $status); + } +} +if (!\function_exists('mb_http_input')) { + function mb_http_input(?string $type = null) : array|string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_http_input($type); + } +} +if (!\function_exists('mb_convert_variables')) { + function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); + } +} +if (!\function_exists('mb_ord')) { + function mb_ord(?string $string, ?string $encoding = null) : int|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_ord((string) $string, $encoding); + } +} +if (!\function_exists('mb_chr')) { + function mb_chr(?int $codepoint, ?string $encoding = null) : string|false + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_chr((int) $codepoint, $encoding); + } +} +if (!\function_exists('mb_scrub')) { + function mb_scrub(?string $string, ?string $encoding = null) : string + { + $encoding ??= \mb_internal_encoding(); + return \mb_convert_encoding((string) $string, $encoding, $encoding); + } +} +if (!\function_exists('mb_str_split')) { + function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null) : array + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); + } +} +if (!\function_exists('PostSMTP\\Vendor\\mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) : string + { + return \PostSMTP\Vendor\Symfony\Polyfill\Mbstring\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); + } +} +if (\extension_loaded('mbstring')) { + return; +} +if (!\defined('MB_CASE_UPPER')) { + \define('MB_CASE_UPPER', 0); +} +if (!\defined('MB_CASE_LOWER')) { + \define('MB_CASE_LOWER', 1); +} +if (!\defined('MB_CASE_TITLE')) { + \define('MB_CASE_TITLE', 2); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/LICENSE b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/LICENSE new file mode 100644 index 0000000..6e3afce --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/Php72.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/Php72.php new file mode 100644 index 0000000..a789df0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/Php72.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PostSMTP\Vendor\Symfony\Polyfill\Php72; + +/** + * @author Nicolas Grekas + * @author Dariusz RumiÅ„ski + * + * @internal + */ +final class Php72 +{ + private static $hashMask; + public static function utf8_encode($s) + { + $s .= $s; + $len = \strlen($s); + for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) { + switch (\true) { + case $s[$i] < "�": + $s[$j] = $s[$i]; + break; + case $s[$i] < "�": + $s[$j] = "�"; + $s[++$j] = $s[$i]; + break; + default: + $s[$j] = "�"; + $s[++$j] = \chr(\ord($s[$i]) - 64); + break; + } + } + return \substr($s, 0, $j); + } + public static function utf8_decode($s) + { + $s = (string) $s; + $len = \strlen($s); + for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) { + switch ($s[$i] & "�") { + case "�": + case "�": + $c = \ord($s[$i] & "\37") << 6 | \ord($s[++$i] & "?"); + $s[$j] = $c < 256 ? \chr($c) : '?'; + break; + case "�": + ++$i; + // no break + case "�": + $s[$j] = '?'; + $i += 2; + break; + default: + $s[$j] = $s[$i]; + } + } + return \substr($s, 0, $j); + } + public static function php_os_family() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + return 'Windows'; + } + $map = ['Darwin' => 'Darwin', 'DragonFly' => 'BSD', 'FreeBSD' => 'BSD', 'NetBSD' => 'BSD', 'OpenBSD' => 'BSD', 'Linux' => 'Linux', 'SunOS' => 'Solaris']; + return $map[\PHP_OS] ?? 'Unknown'; + } + public static function spl_object_id($object) + { + if (null === self::$hashMask) { + self::initHashMask(); + } + if (null === ($hash = \spl_object_hash($object))) { + return; + } + // On 32-bit systems, PHP_INT_SIZE is 4, + return self::$hashMask ^ \hexdec(\substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); + } + public static function sapi_windows_vt100_support($stream, $enable = null) + { + if (!\is_resource($stream)) { + \trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, ' . \gettype($stream) . ' given', \E_USER_WARNING); + return \false; + } + $meta = \stream_get_meta_data($stream); + if ('STDIO' !== $meta['stream_type']) { + \trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING); + return \false; + } + // We cannot actually disable vt100 support if it is set + if (\false === $enable || !self::stream_isatty($stream)) { + return \false; + } + // The native function does not apply to stdin + $meta = \array_map('strtolower', $meta); + $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri']; + return !$stdin && (\false !== \getenv('ANSICON') || 'ON' === \getenv('ConEmuANSI') || 'xterm' === \getenv('TERM') || 'Hyper' === \getenv('TERM_PROGRAM')); + } + public static function stream_isatty($stream) + { + if (!\is_resource($stream)) { + \trigger_error('stream_isatty() expects parameter 1 to be resource, ' . \gettype($stream) . ' given', \E_USER_WARNING); + return \false; + } + if ('\\' === \DIRECTORY_SEPARATOR) { + $stat = @\fstat($stream); + // Check if formatted mode is S_IFCHR + return $stat ? 020000 === ($stat['mode'] & 0170000) : \false; + } + return \function_exists('posix_isatty') && @\posix_isatty($stream); + } + private static function initHashMask() + { + $obj = (object) []; + self::$hashMask = -1; + // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below + $obFuncs = ['ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush']; + foreach (\debug_backtrace(\PHP_VERSION_ID >= 50400 ? \DEBUG_BACKTRACE_IGNORE_ARGS : \false) as $frame) { + if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) { + $frame['line'] = 0; + break; + } + } + if (!empty($frame['line'])) { + \ob_start(); + \debug_zval_dump($obj); + self::$hashMask = (int) \substr(\ob_get_clean(), 17); + } + self::$hashMask ^= \hexdec(\substr(\spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1)); + } + public static function mb_chr($code, $encoding = null) + { + if (0x80 > ($code %= 0x200000)) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f); + } elseif (0x10000 > $code) { + $s = \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } else { + $s = \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f); + } + if ('UTF-8' !== ($encoding = $encoding ?? \mb_internal_encoding())) { + $s = \mb_convert_encoding($s, $encoding, 'UTF-8'); + } + return $s; + } + public static function mb_ord($s, $encoding = null) + { + if (null === $encoding) { + $s = \mb_convert_encoding($s, 'UTF-8'); + } elseif ('UTF-8' !== $encoding) { + $s = \mb_convert_encoding($s, 'UTF-8', $encoding); + } + if (1 === \strlen($s)) { + return \ord($s); + } + $code = ($s = \unpack('C*', \substr($s, 0, 4))) ? $s[1] : 0; + if (0xf0 <= $code) { + return ($code - 0xf0 << 18) + ($s[2] - 0x80 << 12) + ($s[3] - 0x80 << 6) + $s[4] - 0x80; + } + if (0xe0 <= $code) { + return ($code - 0xe0 << 12) + ($s[2] - 0x80 << 6) + $s[3] - 0x80; + } + if (0xc0 <= $code) { + return ($code - 0xc0 << 6) + $s[2] - 0x80; + } + return $code; + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/bootstrap.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/bootstrap.php new file mode 100644 index 0000000..3c39e9d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/libs/vendor_prefixed/symfony/polyfill-php72/bootstrap.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PostSMTP\Vendor\Symfony\Polyfill\Php72 as p; + +if (\PHP_VERSION_ID >= 70200) { + return; +} + +if (!defined('PHP_FLOAT_DIG')) { + define('PHP_FLOAT_DIG', 15); +} +if (!defined('PHP_FLOAT_EPSILON')) { + define('PHP_FLOAT_EPSILON', 2.2204460492503E-16); +} +if (!defined('PHP_FLOAT_MIN')) { + define('PHP_FLOAT_MIN', 2.2250738585072E-308); +} +if (!defined('PHP_FLOAT_MAX')) { + define('PHP_FLOAT_MAX', 1.7976931348623157E+308); +} +if (!defined('PHP_OS_FAMILY')) { + define('PHP_OS_FAMILY', p\Php72::php_os_family()); +} + +if ('\\' === \DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) { + function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); } +} +if (!function_exists('stream_isatty')) { + function stream_isatty($stream) { return p\Php72::stream_isatty($stream); } +} +if (!function_exists('utf8_encode')) { + function utf8_encode($string) { return p\Php72::utf8_encode($string); } +} +if (!function_exists('utf8_decode')) { + function utf8_decode($string) { return p\Php72::utf8_decode($string); } +} +if (!function_exists('spl_object_id')) { + function spl_object_id($object) { return p\Php72::spl_object_id($object); } +} +if (!function_exists('mb_ord')) { + function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-elasticemail.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-elasticemail.js new file mode 100644 index 0000000..7766f47 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-elasticemail.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('elasticemail_api_key', 'toggleElasticEmailApiKey'); + + // define the PostmanMandrill class + var PostmanSendGrid = function() { + + } + + // behavior for handling the user's transport change + PostmanSendGrid.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'elasticemail_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#elasticemail_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanSendGrid.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'elasticemail_api' ) { + show( 'section.wizard_elasticemail' ); + } else { + hide( 'section.wizard_elasticemail' ); + } + } + + // add this class to the global transports + var transport = new PostmanSendGrid(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-emailit.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-emailit.js new file mode 100644 index 0000000..ae86528 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-emailit.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('emailit_api_key', 'toggleEmailitApiKey'); + + // define the PostmanEmailit class + var PostmanEmailit = function() { + + } + + // behavior for handling the user's transport change + PostmanEmailit.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'emailit_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#emailit_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanEmailit.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'emailit_api' ) { + show( 'section.wizard_emailit' ); + } else { + hide( 'section.wizard_emailit' ); + } + } + + // add this class to the global transports + var transport = new PostmanEmailit(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-maileroo.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-maileroo.js new file mode 100644 index 0000000..fe92223 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-maileroo.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('maileroo_api_key', 'toggleMailerooApiKey'); + + // define the PostmanMaileroo class + var PostmanMaileroo = function() { + + } + + // behavior for handling the user's transport change + PostmanMaileroo.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'maileroo_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#maileroo_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanMaileroo.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'maileroo_api' ) { + show( 'section.wizard_maileroo' ); + } else { + hide( 'section.wizard_maileroo' ); + } + } + + // add this class to the global transports + var transport = new PostmanMaileroo(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-mailjet.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-mailjet.js new file mode 100644 index 0000000..080f19d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-mailjet.js @@ -0,0 +1,41 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('mailjet_api_key', 'toggleMailjetApiKey'); + enablePasswordDisplayOnEntry('mailjet_secret_key', 'toggleMailjetSecretKey'); + + // define the PostmanMandrill class + var PostmanMailjet = function() { + + } + + // behavior for handling the user's transport change + PostmanMailjet.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'mailjet_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#mailjet_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanMailjet.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'mailjet_api' ) { + show( 'section.wizard_mailjet' ); + } else { + hide( 'section.wizard_mailjet' ); + } + } + + // add this class to the global transports + var transport = new PostmanMailjet(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-mailtrap.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-mailtrap.js new file mode 100644 index 0000000..d54d744 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-mailtrap.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('mailtrap_api_key', 'toggleMailtrapApiKey'); + + // define the PostmanMailtrap class + var PostmanMailtrap = function() { + + } + + // behavior for handling the user's transport change + PostmanMailtrap.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'mailtrap_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#mailtrap_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanMailtrap.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'mailtrap_api' ) { + show( 'section.wizard_mailtrap' ); + } else { + hide( 'section.wizard_mailtrap' ); + } + } + + // add this class to the global transports + var transport = new PostmanMailtrap(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-postmark.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-postmark.js new file mode 100644 index 0000000..dd518e1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-postmark.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('postmark_api_key', 'togglePostmarkApiKey'); + + // define the PostmanMandrill class + var PostmanPostmark = function() { + + } + + // behavior for handling the user's transport change + PostmanPostmark.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'postmark_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#postmark_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanPostmark.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'postmark_api' ) { + show( 'section.wizard_postmark' ); + } else { + hide( 'section.wizard_postmark' ); + } + } + + // add this class to the global transports + var transport = new PostmanPostmark(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-resend.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-resend.js new file mode 100644 index 0000000..8a7e875 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-resend.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('resend_api_key', 'toggleResendApiKey'); + + // define the PostmanResend class + var PostmanResend = function() { + + } + + // behavior for handling the user's transport change + PostmanResend.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'resend_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#resend_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanResend.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'resend_api' ) { + show( 'section.wizard_resend' ); + } else { + hide( 'section.wizard_resend' ); + } + } + + // add this class to the global transports + var transport = new PostmanResend(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sendinblue.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sendinblue.js new file mode 100644 index 0000000..9743a07 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sendinblue.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('sendinblue_api_key', 'toggleSendinblueApiKey'); + + // define the PostmanMandrill class + var PostmanSendGrid = function() { + + } + + // behavior for handling the user's transport change + PostmanSendGrid.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'sendinblue_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#sendinblue_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanSendGrid.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'sendinblue_api' ) { + show( 'section.wizard_sendinblue' ); + } else { + hide( 'section.wizard_sendinblue' ); + } + } + + // add this class to the global transports + var transport = new PostmanSendGrid(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sendpulse.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sendpulse.js new file mode 100644 index 0000000..6371a1d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sendpulse.js @@ -0,0 +1,43 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('sendpulse_api_key', 'toggleSendpulseApiKey'); + + // enable toggling of the Secret Key field from password to plain text + enablePasswordDisplayOnEntry('sendpulse_secret_key', 'toggleSendpulseSecretKey'); + + // define the PostmanSendPulse class + var PostmanSendPulse = function() { + + } + + // behavior for handling the user's transport change + PostmanSendPulse.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'sendpulse_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#sendpulse_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanSendPulse.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'sendpulse_api' ) { + show( 'section.wizard_sendpulse' ); + } else { + hide( 'section.wizard_sendpulse' ); + } + } + + // add this class to the global transports + var transport = new PostmanSendPulse(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sparkpost.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sparkpost.js new file mode 100644 index 0000000..f259346 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sparkpost.js @@ -0,0 +1,40 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('sparkpost_api_key', 'toggleSparkPostApiKey'); + + // define the PostmanMandrill class + var PostmanSparkPost = function() { + + } + + // behavior for handling the user's transport change + PostmanSparkPost.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'sparkpost_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#sparkpost_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanSparkPost.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'sparkpost_api' ) { + show( 'section.wizard_sparkpost' ); + } else { + hide( 'section.wizard_sparkpost' ); + } + } + + // add this class to the global transports + var transport = new PostmanSparkPost(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sweego.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sweego.js new file mode 100644 index 0000000..82fa2bc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman-sweego.js @@ -0,0 +1,41 @@ +jQuery( document ).ready( function(){ + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('sweego_api_key', 'toggleSweegoApiKey'); + + // define the PostmanSweego class + var PostmanSweego = function() { + + } + + // behavior for handling the user's transport change + PostmanSweego.prototype.handleTransportChange = function( transportName ) { + if ( transportName == 'sweego_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#sweego_settings' ); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanSweego.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'sweego_api' ) { + show( 'section.wizard_sweego' ); + } else { + hide( 'section.wizard_sweego' ); + } + } + + // add this class to the global transports + var transport = new PostmanSweego(); + transports.push( transport ); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); + +} ) + diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_gmail.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_gmail.js new file mode 100644 index 0000000..365bcdd --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_gmail.js @@ -0,0 +1,35 @@ +jQuery(document).ready(function() { + postmanGmailInit(); +}); + +function postmanGmailInit() { + + // define the PostmanMandrill class + var PostmanGmail = function() { + this.slug = 'gmail_api'; + } + + // behavior for handling the user's transport change + PostmanGmail.prototype.handleTransportChange = function(transportName) { + if (transportName == this.slug) { + hide('div.transport_setting'); + hide('div.authentication_setting'); + show('div#oauth_settings'); + } + } + + PostmanGmail.prototype.handleConfigurationResponse = function(response) { + // handled by PostmanSmtp + } + + // add this class to the global transports + var transport = new PostmanGmail(); + transports.push(transport); + + // since we are initialize the screen, check if needs to be modded + // by this + // transport + var transportName = jQuery('select#input_transport_type').val(); + transport.handleTransportChange(transportName); + +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mailersend.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mailersend.js new file mode 100644 index 0000000..db615a5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mailersend.js @@ -0,0 +1,40 @@ +jQuery(document).ready(function() { + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('mailersend_api_key', 'toggleMailerSendApiKey'); + + // define the PostmanMailerSend class + var PostmanMailerSend = function() { + + } + + // behavior for handling the user's transport change + PostmanMailerSend.prototype.handleTransportChange = function(transportName) { + if (transportName == 'mailersend_api') { + hide('div.transport_setting'); + hide('div.authentication_setting'); + show('div#mailersend_settings'); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanMailerSend.prototype.handleConfigurationResponse = function(response) { + var transportName = response.configuration.transport_type; + if (transportName == 'mailersend_api') { + show('section.wizard_mailersend'); + } else { + hide('section.wizard_mailersend'); + } + } + + // add this class to the global transports + var transport = new PostmanMailerSend(); + transports.push(transport); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery('select#input_transport_type').val(); + transport.handleTransportChange(transportName); + +}); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mailgun.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mailgun.js new file mode 100644 index 0000000..d87e256 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mailgun.js @@ -0,0 +1,40 @@ +jQuery(document).ready(function() { + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('mailgun_api_key', 'toggleMailgunApiKey'); + + // define the PostmanMandrill class + var PostmanMailgun = function() { + + } + + // behavior for handling the user's transport change + PostmanMailgun.prototype.handleTransportChange = function(transportName) { + if (transportName == 'mailgun_api') { + hide('div.transport_setting'); + hide('div.authentication_setting'); + show('div#mailgun_settings'); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanMailgun.prototype.handleConfigurationResponse = function(response) { + var transportName = response.configuration.transport_type; + if (transportName == 'mailgun_api') { + show('section.wizard_mailgun'); + } else { + hide('section.wizard_mailgun'); + } + } + + // add this class to the global transports + var transport = new PostmanMailgun(); + transports.push(transport); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery('select#input_transport_type').val(); + transport.handleTransportChange(transportName); + +}); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mandrill.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mandrill.js new file mode 100644 index 0000000..5154246 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_mandrill.js @@ -0,0 +1,40 @@ +jQuery(document).ready(function() { + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('mandrill_api_key', 'toggleMandrillApiKey'); + + // define the PostmanMandrill class + var PostmanMandrill = function() { + this.slug = 'mandrill_api'; + } + + // behavior for handling the user's transport change + PostmanMandrill.prototype.handleTransportChange = function(transportName) { + if (transportName == this.slug) { + hide('div.transport_setting'); + hide('div.authentication_setting'); + show('div#mandrill_settings'); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanMandrill.prototype.handleConfigurationResponse = function(response) { + var transportName = response.configuration.transport_type; + if (transportName == this.slug) { + show('section.wizard_mandrill'); + } else { + hide('section.wizard_mandrill'); + } + } + + // add this class to the global transports + var transport = new PostmanMandrill(); + transports.push(transport); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery('select#input_transport_type').val(); + transport.handleTransportChange(transportName); + +}); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_sendgrid.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_sendgrid.js new file mode 100644 index 0000000..9cbdef3 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_sendgrid.js @@ -0,0 +1,40 @@ +jQuery(document).ready(function() { + + // enable toggling of the API field from password to plain text + enablePasswordDisplayOnEntry('sendgrid_api_key', 'toggleSendGridApiKey'); + + // define the PostmanMandrill class + var PostmanSendGrid = function() { + + } + + // behavior for handling the user's transport change + PostmanSendGrid.prototype.handleTransportChange = function(transportName) { + if (transportName == 'sendgrid_api') { + hide('div.transport_setting'); + hide('div.authentication_setting'); + show('div#sendgrid_settings'); + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanSendGrid.prototype.handleConfigurationResponse = function(response) { + var transportName = response.configuration.transport_type; + if (transportName == 'sendgrid_api') { + show('section.wizard_sendgrid'); + } else { + hide('section.wizard_sendgrid'); + } + } + + // add this class to the global transports + var transport = new PostmanSendGrid(); + transports.push(transport); + + // since we are initialize the screen, check if needs to be modded by this + // transport + var transportName = jQuery('select#input_transport_type').val(); + transport.handleTransportChange(transportName); + +}); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_smtp.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_smtp.js new file mode 100644 index 0000000..c963270 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_smtp.js @@ -0,0 +1,89 @@ +jQuery(document).ready(function() { + postmanSmtpInit(); +}); + +function postmanSmtpInit() { + // define the PostmanMandrill class + var PostmanSmtp = function(name) { + this.slug = name; + } + + // behavior for handling the user's transport change + PostmanSmtp.prototype.handleTransportChange = function(transportName) { + if (transportName == 'default') { + hide('div.transport_setting'); + hide('div.authentication_setting'); + } else if (transportName == this.slug) { + show('div#smtp_config'); + var $choice = jQuery('select#input_auth_type').val(); + if ($choice == 'none') { + hide('div.authentication_setting'); + } else if ($choice != 'oauth2') { + show('div#password_settings'); + hide('div.authentication_setting.non-basic'); + } else { + hide('div.authentication_setting.non-oauth2'); + show('div#oauth_settings'); + } + } + } + + // behavior for handling the wizard configuration from the + // server (after the port test) + PostmanSmtp.prototype.handleConfigurationResponse = function(response) { + var transportName = response.configuration.transport_type; + if (!(transportName == this.slug || transportName == 'gmail_api')) { + hide('.wizard-auth-oauth2'); + hide('.wizard-auth-basic'); + return; + } + console.debug('prepping screen for smtp transport '); + if (response.configuration.display_auth == 'oauth2') { + show('p#wizard_oauth2_help'); + jQuery('p#wizard_oauth2_help').html( + response.configuration.help_text); + jQuery(post_smtp_localize.postman_redirect_url_el).val( + response.configuration.redirect_url); + jQuery('#input_oauth_callback_domain').val( + response.configuration.callback_domain); + jQuery('#client_id').html(response.configuration.client_id_label); + jQuery('#client_secret').html( + response.configuration.client_secret_label); + jQuery('#redirect_url').html( + response.configuration.redirect_url_label); + jQuery('#callback_domain').html( + response.configuration.callback_domain_label); + } + redirectUrlWarning = response.configuration.dot_notation_url; + jQuery('#input_transport_type').val( + response.configuration.transport_type); + jQuery('#input_auth_type').val(response.configuration.auth_type); + jQuery('#input_enc_type').val(response.configuration.enc_type); + jQuery('#input_port').val(response.configuration.port); + + // hide the fields we don't use so validation + // will work + if (response.configuration.display_auth == 'oauth2') { + // where authentication is oauth2 + show('.wizard-auth-oauth2'); + hide('.wizard-auth-basic'); + } else if (response.configuration.display_auth == 'password') { + // where authentication is password + hide('.wizard-auth-oauth2'); + show('.wizard-auth-basic'); + } else { + // where authentication is none + hide('.wizard-auth-oauth2'); + hide('.wizard-auth-basic'); + } + } + + // add this class to the global transports + var transport = new PostmanSmtp('smtp'); + transports.push(transport); + + // since we are initialize the screen, check if needs to be + // modded by this transport + var transportName = jQuery('select#input_transport_type').val(); + transport.handleTransportChange(transportName); +} diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_smtp2go.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_smtp2go.js new file mode 100644 index 0000000..5b5e461 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Mail/postman_smtp2go.js @@ -0,0 +1,32 @@ + +jQuery( document ).ready( function( $ ) { + enablePasswordDisplayOnEntry( 'smtp2go_api_key', 'toggleSmtp2goApiKey' ); + + var PostmanSmtp2go = function() { + + } + + PostmanSmtp2go.prototype.handleTransportChange = function( transportName ) { + console.log( transportName ); + if ( transportName == 'smtp2go_api' ) { + hide( 'div.transport_setting' ); + hide( 'div.authentication_setting' ); + show( 'div#smtp2go_settings' ); + } + } + + PostmanSmtp2go.prototype.handleConfigurationResponse = function( response ) { + var transportName = response.configuration.transport_type; + if ( transportName == 'smtp2go_api' ) { + show( 'section.wizard_smtp2go' ); + } else { + hide( 'section.wizard_smtp2go' ); + } + } + + var transport = new PostmanSmtp2go(); + transports.push( transport ); + + var transportName = jQuery( 'select#input_transport_type' ).val(); + transport.handleTransportChange( transportName ); +} ); diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/PostmanSendTestEmailController.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/PostmanSendTestEmailController.php new file mode 100644 index 0000000..e4e1655 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/PostmanSendTestEmailController.php @@ -0,0 +1,494 @@ + array( + 'type' => array(), + 'id' => array(), + 'name' => array(), + 'value' => array(), + 'class' => array(), + 'placeholder' => array(), + 'size' => array(), + ) + ); + + // Holds the values to be used in the fields callbacks + private $rootPluginFilenameAndPath; + + /** + * Constructor + * + * @param mixed $rootPluginFilenameAndPath + */ + public function __construct( $rootPluginFilenameAndPath ) { + assert( ! empty( $rootPluginFilenameAndPath ) ); + assert( PostmanUtils::isAdmin() ); + assert( is_admin() ); + + $this->logger = new PostmanLogger( get_class( $this ) ); + $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath; + $this->options = PostmanOptions::getInstance(); + + PostmanUtils::registerAdminMenu( $this, 'addEmailTestSubmenu' ); + + // hook on the init event + add_action( 'init', array( + $this, + 'on_init', + ) ); + + // initialize the scripts, stylesheets and form fields + add_action( 'admin_init', array( + $this, + 'on_admin_init', + ) ); + } + + /** + * Functions to execute on the init event + * + * "Typically used by plugins to initialize. The current user is already authenticated by this time." + * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request + */ + public function on_init() { + // register Ajax handlers + new PostmanSendTestEmailAjaxController(); + } + + /** + * Fires on the admin_init method + */ + public function on_admin_init() { + $this->registerStylesAndScripts(); + } + + /** + * Get the settings option array and print one of its values + */ + public function test_email_callback() { + return sprintf( + '', + esc_attr( self::RECIPIENT_EMAIL_FIELD_NAME ), + esc_attr( wp_get_current_user()->user_email ) + ); + } + + /** + * Register and add settings + */ + private function registerStylesAndScripts() { + if ( $this->logger->isTrace() ) { + $this->logger->trace( 'registerStylesAndScripts()' ); + } + + $pluginData = apply_filters( 'postman_get_plugin_metadata', null ); + + // register the stylesheet resource + wp_register_style( 'postman_send_test_email', plugins_url( 'Postman/Postman-Send-Test-Email/postman_send_test_email.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, $pluginData ['version'] ); + + // register the javascript resource + wp_register_script( 'postman_test_email_wizard_script', plugins_url( 'Postman/Postman-Send-Test-Email/postman_send_test_email.js', $this->rootPluginFilenameAndPath ), array( + PostmanViewController::JQUERY_SCRIPT, + 'jquery_validation', + 'jquery_steps_script', + PostmanViewController::POSTMAN_SCRIPT, + ), $pluginData ['version'] ); + } + + /** + * Register the Email Test screen + */ + public function addEmailTestSubmenu() { + $page = add_submenu_page( + ' ', + sprintf( '%s', esc_html__( 'Postman SMTP Setup', 'post-smtp' ) ), + esc_html__( 'Postman SMTP', 'post-smtp' ), + Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanSendTestEmailController::EMAIL_TEST_SLUG, array( + $this, + 'outputTestEmailContent', + ) ); + // When the plugin options page is loaded, also load the stylesheet + add_action( 'admin_print_styles-' . $page, array( + $this, + 'enqueueEmailTestResources', + ) ); + } + + /** + */ + function enqueueEmailTestResources() { + wp_enqueue_style( 'jquery_steps_style' ); + wp_enqueue_style( PostmanViewController::POSTMAN_STYLE ); + wp_enqueue_style( 'postman_send_test_email' ); + wp_enqueue_script( 'postman_test_email_wizard_script' ); + wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_email_test', array( + 'recipient' => '#' . self::RECIPIENT_EMAIL_FIELD_NAME, + 'not_started' => _x( 'In Outbox', 'Email Test Status', 'post-smtp' ), + 'sending' => _x( 'Sending...', 'Email Test Status', 'post-smtp' ), + 'success' => _x( 'Success', 'Email Test Status', 'post-smtp' ), + //'failed' => _x( 'Failed', 'Email Test Status', 'post-smtp' ), + 'failed' => sprintf( 'Failed - Check the plugin email log for more info: %s', 'Here' ), + 'ajax_error' => __( 'Ajax Error', 'post-smtp' ), + ) ); + } + + /** + */ + public function outputTestEmailContent() { + $page_url = add_query_arg( + array( + 'page' => 'postman', + ), + admin_url( 'admin.php' ) + ); + + $user_email = wp_get_current_user()->user_email; + + $nonce_field = wp_nonce_field( 'post-smtp', 'security', true, false ); + echo ' +
        + + + +
        + +
        + +
        + + + + + + +
        + + + ' . esc_html__( 'Send Test Email', 'post-smtp' ) . ' +
        + +
        + +
        + +
        + +
        +
        + +

        + ' . esc_html__( 'This step allows you to send an email message for testing. If there is a problem, Post SMTP will give up after 60 seconds.', 'post-smtp' ) . ' +

        + +
        + +
        + +
        + +
        + + + ' . $nonce_field . ' + + + ' . esc_html__( 'Enter the email address where you want to send the test email.', 'post-smtp' ) . ' + + +

        + ' . esc_html__( 'Are your WordPress emails getting broken? Check out our guide on', 'post-smtp' ) . ' + ' . esc_html__( 'how to Fix Broken Emails', 'post-smtp' ) . ' + . +

        +
        + + + + + + +
        +

        +

        +
        + + +
        + +
        +
        + +
        + +
        + + + +
        + + +
        +
        + '; + } +} + +/** + * + * @author jasonhendriks + */ +class PostmanSendTestEmailAjaxController extends PostmanAbstractAjaxHandler { + + /** + * Constructor + * + * @param PostmanOptions $options + * @param PostmanOAuthToken $authorizationToken + * @param PostmanConfigTextHelper $oauthScribe + */ + function __construct() { + parent::__construct(); + PostmanUtils::registerAjaxHandler( 'postman_send_test_email', $this, 'sendTestEmailViaAjax' ); + } + + /** + * Yes, this procedure is just for testing. + * + * @return boolean + */ + function test_mode() { + return true; + } + + /** + * This Ajax sends a test email + * + * @since 1.0 + * @since 2.0.25 @filter `postman_test_email_args` + * @version 1.0 + */ + function sendTestEmailViaAjax() { + + check_admin_referer('post-smtp', 'security'); + + if( !current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_NAME ) ) { + wp_send_json_error( + array( + 'Message' => 'Unauthorized.' + ), + 401 + ); + } + + // get the email address of the recipient from the HTTP Request + $email = $this->getRequestParameter( 'email' ); + + // get the name of the server from the HTTP Request + $serverName = PostmanUtils::postmanGetServerName(); + + /* translators: where %s is the domain name of the site */ + $subject = sprintf( _x( 'Postman SMTP Test (%s)', 'Test Email Subject', 'post-smtp' ), $serverName ); + + // Postman API: indicate to Postman this is just for testing + add_filter( 'postman_test_email', array( + $this, + 'test_mode', + ) ); + + // this header specifies that there are many parts (one text part, one html part) + $header = 'Content-Type: multipart/alternative;' . "\r\n"; + $header .= 'MIME-Version: 1.0' . "\r\n"; + + // createt the message content + $message = $this->createMessageContent(); + + $email_args = apply_filters( 'postman_test_email_args', compact( 'email', 'subject', 'message', 'header' ) ); + extract( $email_args ); + + // send the message + $success = wp_mail( $email, $subject, $message, $header ); + + // Postman API: remove the testing indicator + remove_filter( 'postman_test_email', array( + $this, + 'test_mode', + ) ); + + // Postman API: retrieve the result of sending this message from Postman + $result = apply_filters( 'postman_wp_mail_result', null ); + + // post-handling + if ( $success ) { + $this->logger->debug( 'Test Email delivered to server' ); + // the message was sent successfully, generate an appropriate message for the user + $statusMessage = sprintf( __( 'Your message was delivered (%d ms) to the SMTP server! Congratulations :)', 'post-smtp' ), $result ['time'] ); + + $this->logger->debug( 'statusmessage: ' . $statusMessage ); + + // compose the JSON response for the caller + $response = array( + 'message' => $statusMessage, + 'transcript' => $result ['transcript'], + ); + + // log the response + if ( $this->logger->isTrace() ) { + $this->logger->trace( 'Ajax Response:' ); + $this->logger->trace( $response ); + } + + // send the JSON response + wp_send_json_success( $response ); + } else { + $this->logger->error( 'Test Email NOT delivered to server - ' . $result ['exception']->getCode() ); + // the message was NOT sent successfully, generate an appropriate message for the user + $statusMessage = $result ['exception']->getMessage(); + + $this->logger->debug( 'statusmessage: ' . $statusMessage ); + + // compose the JSON response for the caller + $response = array( + 'message' => $statusMessage, + 'transcript' => $result ['transcript'], + ); + + // log the response + if ( $this->logger->isTrace() ) { + $this->logger->trace( 'Ajax Response:' ); + $this->logger->trace( $response ); + } + + // send the JSON response + wp_send_json_error( $response ); + } + } + + /** + * Create the multipart message content + * + * @return string + */ + private function createMessageContent() { + // Postman API: Get the plugin metadata + $pluginData = apply_filters( 'postman_get_plugin_metadata', null ); + + /* + translators: where %s is the Postman plugin version number (e.g. 1.4) */ + // English - Mandarin - French - Hindi - Spanish - Portuguese - Russian - Japanese + // http://www.pinyin.info/tools/converter/chars2uninumbers.html + $greeting = 'Hello! - 你好 - Bonjour! - नमस्ते - ¡Hola! - Olá - Привет! - 今日は'; + $sentBy = sprintf( _x( 'Sent by Postman %s', 'Test Email Tagline', 'post-smtp' ), $pluginData ['version'] ); + $imageSource = __( 'Image source', 'post-smtp' ); + $withPermission = __( 'Used with permission', 'post-smtp' ); + $emailBody = ' + + + + + + + + + + + + + + + + + + + + + + + + + ', + '', + '', + '', + '', + '', + '', + '
        ', + $emailBody, + '', + '', + ); + return implode( PostmanMessage::EOL, $messageArray ); + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/postman_send_test_email.css b/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/postman_send_test_email.css new file mode 100644 index 0000000..617548c --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/postman_send_test_email.css @@ -0,0 +1,191 @@ +/*!*******************************************************************!*\ + !*** css ./node_modules/css-loader/dist/cjs.js!./src/css/app.css ***! + \*******************************************************************/ + + .float-left { + float: left; +} + +.float-right { + float: right; +} + +.send-test-email { + margin-top: 50px; +} + +.send-test-email .ps-outer { + border: 2px solid #375caf; + border-radius: 7px; + width: 907px; + margin: 0 auto; +} + +.ps-body-section { + margin: 25px 0; +} + +.ps-body-section::after { + content: ""; + display: table; + clear: both; +} + +.ps-body-section .ps-nav { + height: 350px; +} + +.send-test-email .ps-nav table { + padding: 0 25px; +} + +.send-test-email .ps-nav { + border-right: 1px solid #d9d9d9; + width: 32%; +} + +.send-test-email .ps-nav table td { + padding: 12px 6px; + vertical-align: center; +} + +.send-test-email .ps-circle { + text-align: center; +} + +.send-test-email .ps-circle .ps-tick { + display: inline-block; + width: 48px; + height: 48px; + font-size: 44px; + color: #375caf; + position: relative; + z-index: 8; +} + +.send-test-email .ps-circle .ps-tick::before { + content: ''; + height: 35px; + width: 35px; + border-radius: 40px; + display: inline-block; + vertical-align: top; + line-height: 1; + margin: auto; + background-color: #375caf; +} + +.send-test-email .ps-circle .birth-check.ps-tick::before { + content: '\f12a'; + height: 35px; + width: 35px; + border-radius: 40px; + display: inline-block; + vertical-align: top; + line-height: 1; + margin: auto; + background-color: transparent; +} + +.send-test-email .ps-text { + padding: 12px 6px; + vertical-align: middle; + font-weight: 600; +} + +.send-test-email .ps-footer { + padding: 17px 0; + /*background: #f1f1f1;*/ +} + +.send-test-email .ps-footer-content.float-left { + width: 32%; +} + +.send-test-email .ps-footer-content .ps-nav table { + padding: 0 25px; +} + +.send-test-email .ps-footer-content .ps-nav { + border: none; +} + +.send-test-email .ps-footer::after { + content: ""; + display: table; + clear: both; +} + +.send-test-email .ps-line::after { + content: ''; + position: absolute; + width: 3px; + height: 360px; + left: 26px; + bottom: 41px; + background: #d9d9d9; + z-index: -3; +} + +.send-test-email .ps-pages { + min-height: 351px; + width: 67%; +} + +.send-test-email .ps-footer-content.float-right { + width: 67%; +} + +.send-test-email .ps-footer-content .ps-step { + padding: 15px 10px; +} + +.send-test-email .ps-screens-container { + padding: 0 25px; +} + +.send-test-email .ps-blue-button { + border: #485b87; + background: #375caf; + border-radius: 0px; + line-height: 40px; + width: 184px; +} + +.send-test-email .ps-blue-button:hover { + background: #4c6fbd; + border-color: #4c6fbd; +} + +.send-test-email .ps-blue-button span { + vertical-align: middle; + font-size: 16px; +} + +.send-test-email .ps-success { + font-weight: 600; + font-size: 12px; + display: inline-block; + color: green; +} + +.send-test-email .ps-error { + font-weight: 600; + font-size: 12px; + display: inline-block; + color: red; +} + +.need-more-line::after { + height: 491px !important; +} + +.ps-ste-clearfix::after { + clear: both; + display: table; + content: ''; +} + + +/*# This is auto generated css by webpack please don't change anything */ +/*# sourceMappingURL=app.css.map*/ \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/postman_send_test_email.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/postman_send_test_email.js new file mode 100644 index 0000000..ed80225 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Send-Test-Email/postman_send_test_email.js @@ -0,0 +1,63 @@ +( function( $ ) { + $( document ).ready( function( $e ) { + + $( document ).on( 'click', '.send-test-email .ps-next-button', function( e ) { + e.preventDefault(); + + var $this = $( this ); + + $( '#when-button-clicked' ).addClass( 'is-active' ).css( 'display', 'block' ); + $( this ).attr( 'disabled', 'disabled' ); + + $( '.ps-line' ).removeClass( 'need-more-line' ); + $( '.ps-transcript' ).hide(); + + let security = $( '#security' ).val(), + email = $( '#postman_test_options_test_email' ).val(); + + $.ajax( { + url : ajaxurl, + method : 'POST', + data : { + action : 'postman_send_test_email', + security : security, + email : email, + }, + success : function( response ) { + $( '.show-when-email-sent' ).css( 'display', 'block' ); + $( '#when-button-clicked' ).removeClass( 'is-active' ).css( 'display', 'none' ); + $this.removeAttr( 'disabled' ); + if ( ! response.success ) { + var message = response.data.message; + var icon = ''; + $( '.send-test-email .ps-success' ).empty(); + $( '.send-test-email .ps-error' ).html( icon + message ); + + $( '#ps-transcript-container' ).hide(); + $( '#ps-show-transcript' ).hide(); + } + + if ( response.success ) { + var message = response.data.message; + var icon = ''; + $( '.send-test-email .ps-error' ).empty(); + $( '.send-test-email .ps-success' ).html( icon + message ); + + $( '#ps-transcript-container' ).show(); + $( '#ps-show-transcript' ).show(); + + $( '.ps-transcript textarea' ).text( response.data.transcript ); + $( '.ps-ste-bm' ).addClass( 'birth-check' ) + } + }, + } ); + } ); + + $( document ).on( 'click', '.send-test-email #ps-show-transcript', function( e ) { + e.preventDefault(); + + $( '.ps-transcript' ).toggle(); + $( '.ps-line' ).toggleClass( 'need-more-line' ); + } ); + } ); +} )( jQuery ); \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/PostmanPromotionManager.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/PostmanPromotionManager.php new file mode 100644 index 0000000..4236ba5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/PostmanPromotionManager.php @@ -0,0 +1,112 @@ + array( + 'title' => 'Black Friday 2024', + 'start_time' => 1732752000, + 'end_time' => 1733270340, + ) + ); + + /** + * The promotion manager instance. + * + * @since 2.9.10 + */ + public static function get_instance() { + + if ( ! isset( self::$instance ) ) { + + self::$instance = new Postman_Promotion_Manager(); + + } + + return self::$instance; + + } + + /** + * The promotion manager constructor. + * + * @since 2.9.10 + */ + public function __construct() { + + add_action( 'admin_action_ps-skip-bfcm', array( $this, 'skip_bfcm' ) ); + + } + + /** + * Get the promotion. + * + * @since 2.9.10 + */ + public function get_promotion( $promotion ) { + + if ( ! isset( $this->promotions[$promotion] ) ) { + + return false; + + } + + return $this->promotions[$promotion]; + + } + + /** + * Check if the promotion is active. + * + * @since 2.9.10 + */ + public function is_promotion_active( $promotion ) { + + if ( isset( $this->promotions[$promotion] ) ) { + + $current_time = time(); + + $start_time = $this->promotions[$promotion]['start_time']; + $end_time = $this->promotions[$promotion]['end_time']; + + if ( $current_time >= $start_time && $current_time <= $end_time ) { + + return true; + + } + + } + + return false; + + } + + /** + * Skip the promotion | Action Callback + * + * @since 2.9.10 + */ + public function skip_bfcm() { + + if( isset( $_GET['action'] ) && $_GET['action'] == 'ps-skip-bfcm' ) { + + set_transient( 'ps-skip-bfcm', true, 604800 ); + + wp_redirect( wp_get_referer() ); + + } + + } + +} + +Postman_Promotion_Manager::get_instance(); + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/PostmanSuggestProSocket.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/PostmanSuggestProSocket.php new file mode 100644 index 0000000..89db506 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/PostmanSuggestProSocket.php @@ -0,0 +1,494 @@ +pro_extenstions(); + $this->fs = freemius( 10461 ); + $hide_notice = get_transient( 'post_smtp_skip_banner' ); + + add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); + $this->fs->add_action( 'addons/after_addons', array( $this, 'promote_bundles_fs' ) ); + + + if( !post_smtp_has_pro() ) { + + add_action( 'admin_menu', array( $this, 'add_menu' ), 22 ); + + } + if( !post_smtp_has_pro() && !$hide_notice ){ + + add_action( 'post_smtp_dashboard_after_config', array( $this, 'promote_bundles_dashboard' ) ); + + } + + add_filter( 'gettext', array( $this, 'change_fs_submenu_text' ), 10, 3 ); + add_action( 'admin_action_ps_skip_pro_banner', array( $this, 'skip_pro_banner' ) ); + + } + + /** + * Gather pro extenstions + * + * @since 2.2 + * @version 1.0 + */ + public function pro_extenstions() { + + if( !class_exists( 'Post_Smtp_Office365' ) ) { + $this->data[] = array( + 'extenstion' => 'Office365 API (Pro)', + 'logo' => POST_SMTP_ASSETS . 'images/logos/office365.png', + 'pro' => POST_SMTP_ASSETS . 'images/icons/pro.png', + 'url' => 'https://postmansmtp.com/extensions/office-365-extension-for-post-smtp/' + ); + } + + if( !class_exists( 'Post_Smtp_Amazon_Ses' ) ) { + $this->data[] = array( + 'extenstion' => 'Amazon SES (Pro)', + 'logo' => POST_SMTP_ASSETS . 'images/logos/amazonses.png', + 'pro' => POST_SMTP_ASSETS . 'images/icons/pro.png', + 'url' => 'https://postmansmtp.com/extensions/post-smtp-extension-for-amazon-ses/' + ); + } + + if( !class_exists( 'PostSMTP_ZohoMail' ) ) { + $this->data[] = array( + 'extenstion' => 'Zoho (Pro)', + 'logo' => POST_SMTP_ASSETS . 'images/logos/zoho.jpg', + 'pro' => POST_SMTP_ASSETS . 'images/icons/pro.png', + 'url' => 'https://postmansmtp.com/extensions/zoho-mail-pro-extension/' + ); + } + + + } + + /** + * Enqueue Script | Action call-back + * + * @since 2.2 + * @version 1.0 + */ + public function admin_enqueue_scripts( $hook ) { + + $pluginData = apply_filters( 'postman_get_plugin_metadata', null ); + + wp_register_script( 'postman-suggest-pro-sockets', POST_SMTP_ASSETS . 'js/postman-admin.js', array( 'jquery' ), '1.2.5' , true ); + + wp_enqueue_script( 'postman-suggest-pro-sockets' ); + + $this->data['lessSecureNotice'] = wp_create_nonce( 'less-secure-security' ); + + wp_localize_script( + 'postman-suggest-pro-sockets', + 'postmanPro', + $this->data + ); + + wp_register_style( 'extension-ui-fonts', 'https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap', array(), $pluginData['version'], 'all' ); + + if ( 'post-smtp_page_extensions' === $hook ) { + wp_enqueue_style( 'extensions-ui', plugin_dir_url( __FILE__ ) . 'assets/css/extensions-ui.css', array( 'extension-ui-fonts' ), $pluginData['version'], 'all' ); + wp_enqueue_script( 'extensions-ui', plugin_dir_url( __FILE__ ) . 'assets/js/extensions-ui.js', array( 'jquery' ), $pluginData['version'], true ); + } + + } + + /** + * Promote bundles HTML + * + * @since 2.5.9.3 + * @version 1.0.1 + */ + public function promote_bundles_html() { + + ?> + + +
        +
        + promote_bundles_html(); ?> +
        + +
        + promote_bundles_html(); ?> +
        +
        + + %s', + esc_html__( 'Get', 'post-smtp' ), + esc_html__( 'Pro Bundle', 'post-smtp' ) + ); + + } + + return $translated_text; + + } + + /** + * Skip Pro banner + * + * @since 2.6.0 + * @version 1.0.0 + */ + public function skip_pro_banner() { + + if( isset( $_GET['action'] ) && $_GET['action'] == 'ps_skip_pro_banner' ) { + + set_transient( 'post_smtp_skip_banner', 23668200 ); + + wp_redirect( admin_url( 'admin.php?page=postman' ) ); + + } + + } + + /** + * Add menu + * + * @since 2.8.6 + * @version 1.0.0 + */ + public function add_menu() { + + if( postman_is_bfcm() ) { + + $menu_text = sprintf( + '%1$s%2$s', + __( 'Extensions', 'post-smtp' ), + '24%OFF' + ); + + } + else { + + $menu_text = sprintf( ' %1$s', __( 'Extensions', 'post-smtp' ) ); + + } + + add_submenu_page( + PostmanViewController::POSTMAN_MENU_SLUG, + __( 'Extensions', 'post-smtp' ), + $menu_text, + 'manage_options', + 'extensions', + array( $this, 'extensions' ), + 99 + ); + + } + + public function extensions() { + $images_url = plugin_dir_url( __FILE__ ) . 'assets/images/'; + $sockets = array( + array( + 'logo' => $images_url . 'logos/office365.png', + 'title' => esc_html__( 'Office / Microsoft 365', 'post-smtp' ), + 'description' => esc_html__( 'Integrate your WordPress site with your Office 365 / Microsoft 365 account to improve email deliverability.', 'post-smtp' ), + ), + array( + 'logo' => $images_url . 'logos/amazonses.png', + 'title' => esc_html__( 'Amazon SES', 'post-smtp' ), + 'description' => esc_html__( 'Integrate your WordPress site with your Amazon SES account to improve email deliverability.', 'post-smtp' ), + ), + array( + 'logo' => $images_url . 'logos/zoho.png', + 'title' => esc_html__( 'Zoho Mail', 'post-smtp' ), + 'description' => esc_html__( 'Integrate your WordPress site with your Zoho Mail account to improve email deliverability.', 'post-smtp' ), + ), + array( + 'logo' => $images_url . 'logos/wizard-google.png', + 'title' => __( 'Google One-Click SMTP', 'post-smtp-pro' ), + 'description' => __( 'Instantly connect with Google Workspace (Gmail) SMTP by authorizing your Google account.', 'post-smtp-pro' ), + ), + array( + 'logo' => $images_url . 'logos/office365.png', + 'title' => __( 'Microsoft 365 One-Click SMTP', 'post-smtp-pro' ), + 'description' => __( 'Instantly connect with your Microsoft 365/ Office 365 account without manually configuring your own app.', 'post-smtp-pro' ), + ), + ); + + $bonus = array( + + 'email-logs-attachment' => + array( + 'logo' => $images_url . 'logos/email-delivery-log.png', + 'title' => __( 'Email Log Attachment', 'post-smtp-pro' ), + 'description' => __( 'View and resend any email attachment right from you email log screen to streamline email communication.', 'post-smtp-pro' ) + ), + array( + 'logo' => $images_url . 'logos/advance-logs-filter.svg', + 'title' => esc_html__( 'Advance Logs\' Filter', 'post-smtp-pro' ), + 'description' => esc_html__( 'Get more advance logs filter with all technical details', 'post-smtp' ), + ), + array( + 'logo' => $images_url . 'logos/report-tracking.png', + 'title' => esc_html__( 'Reporting and Tracking', 'post-smtp' ), + 'description' => esc_html__( 'Monitor email delivery status with daily, weekly, and monthly reports and track opened emails to analyze email performance.', 'post-smtp' ), + ), + array( + 'logo' => $images_url . 'logos/twilio-sms-notification.png', + 'title' => esc_html__( 'Twilio SMS Notification', 'post-smtp' ), + 'description' => esc_html__( 'Configure and receive all your WordPress email failure alerts through SMS by connecting your Twilio account.', 'post-smtp' ), + ), + array( + 'logo' => $images_url . 'logos/email-delivery-and-logs.png', + 'title' => esc_html__( 'Email Delivery and Logs', 'post-smtp' ), + 'description' => esc_html__( 'Send emails from the back-end, manage your email quota, retry failed emails, and delete log history to optimize email delivery.', 'post-smtp' ), + ), + array( + 'logo' => $images_url . 'logos/microsoft-teams.png', + 'title' => esc_html__( 'Microsoft Teams Notification', 'post-smtp' ), + 'description' => esc_html__( 'Set up and receive all your WordPress email failure alerts through webhook URL of your MS Teams.', 'post-smtp' ), + ), + ); + $features = array( + esc_attr__( 'Office365, Amazon SES, and Zoho SMTP', 'post-smtp' ), + esc_attr__( 'Resend failed emails in bulk', 'post-smtp' ), + esc_attr__( 'Auto-resend failed emails', 'post-smtp' ), + esc_attr__( 'Open emails tracking', 'post-smtp' ), + esc_attr__( 'Google / Microsoft One-Click Setup', 'post-smtp' ), + esc_attr__( 'Post SMTP Mobile App Pro', 'post-smtp' ), + ); + + ob_start(); + ?> + +
        +
        + Post SMTP Logo +
        + +
        + +
        +
        +

        + + PRO +

        + +

        +
        + + +
        + +
        + + +
        + +
        + <?php echo esc_attr( $socket['title'] ); ?> + +

        + +

        + +

        + +

        + +
        + +
        +
        + +
        + +
        +
        + +
        + +
        + +
        +
        + +
        + + +
        + +
        + +
        +

        + + PRO +

        + +

        +
        + +
        + +
        + + +
        + +
        + <?php echo esc_attr( $socket['title'] ); ?> + +

        + +

        + +

        + +

        + +
        + +
        +
        + +
        + +
        +
        + +
        + +
        + +
        +
        + +
        + +
        + +
        + + Go back + + +
        +
        + +
        + + +
        +
        + + × + + + +
        + +

        + +

        + +
          + +
        • + Check + +
        • + +
        + +
        + +
        + + + + arrow + +
        +
        +
        + + + + + + + + + + + + + + + + diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/amazonses.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/amazonses.png new file mode 100644 index 0000000..22d5bfe Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/amazonses.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-delivery-and-logs.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-delivery-and-logs.png new file mode 100644 index 0000000..39b24cc Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-delivery-and-logs.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-delivery-log.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-delivery-log.png new file mode 100644 index 0000000..2c380dc Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-delivery-log.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-log-attachments.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-log-attachments.png new file mode 100644 index 0000000..d812ea9 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/email-log-attachments.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/microsoft-teams.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/microsoft-teams.png new file mode 100644 index 0000000..b9cc04f Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/microsoft-teams.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/office365.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/office365.png new file mode 100644 index 0000000..44b1254 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/office365.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/report-tracking.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/report-tracking.png new file mode 100644 index 0000000..24f458b Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/report-tracking.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/twilio-sms-notification.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/twilio-sms-notification.png new file mode 100644 index 0000000..6ce55bd Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/twilio-sms-notification.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/wizard-google.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/wizard-google.png new file mode 100644 index 0000000..d157976 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/wizard-google.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/zoho.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/zoho.png new file mode 100644 index 0000000..7e74953 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/logos/zoho.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/magic-wand.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/magic-wand.png new file mode 100644 index 0000000..719acb4 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/magic-wand.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/popup-background.png b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/popup-background.png new file mode 100644 index 0000000..be1f426 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/images/popup-background.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/js/extensions-ui.js b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/js/extensions-ui.js new file mode 100644 index 0000000..0009df8 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/assets/js/extensions-ui.js @@ -0,0 +1,18 @@ +( function ( $ ) { + $( document ).ready( function() { + $( '.post-smtp-open-popup' ).on( 'click', function( e ) { + e.preventDefault(); + + $( '.post-smtp-popup-wrapper' ).css( { 'display': 'flex' } ); + } ); + + $( '.post-smtp-socket-wrapper' ).on( 'click', function() { + $( '.post-smtp-popup-wrapper' ).css( { 'display': 'flex' } ); + } ); + + $( '.post-smtp-close-button' ).on( 'click', function() { + $( '.post-smtp-popup-wrapper' ).css( { 'display': 'none' } ); + } ); + + } ); +} )( jQuery ); \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/index.php b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/index.php new file mode 100644 index 0000000..21191eb --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Postman-Suggest-Pro/index.php @@ -0,0 +1,2 @@ +rootPluginFilenameAndPath = $rootPluginFilenameAndPath; + self::$rootPlugin = $rootPluginFilenameAndPath; + + require_once POST_SMTP_PATH . '/Postman/Postman-Suggest-Pro/PostmanPromotionManager.php'; + //Load helper functions file :D + require_once POST_SMTP_PATH . '/includes/postman-functions.php'; + + // load the dependencies + require_once 'PostmanOptions.php'; + require_once 'PostmanState.php'; + require_once 'PostmanLogger.php'; + require_once 'PostmanUtils.php'; + require_once 'Postman-Mail/PostmanTransportRegistry.php'; + require_once 'Postman-Mail/PostmanDefaultModuleTransport.php'; + require_once 'Postman-Mail/PostmanSmtpModuleTransport.php'; + require_once 'Postman-Mail/PostmanGmailApiModuleTransport.php'; + require_once 'Postman-Mail/PostmanMandrillTransport.php'; + require_once 'Postman-Mail/PostmanSendGridTransport.php'; + require_once 'Postman-Mail/PostmanMailerSendTransport.php'; + require_once 'Postman-Mail/PostmanMailgunTransport.php'; + require_once 'Postman-Mail/PostmanSendinblueTransport.php'; + require_once 'Postman-Mail/PostmanMailtrapTransport.php'; + require_once 'Postman-Mail/PostmanResendTransport.php'; + require_once 'Postman-Mail/PostmanMailjetTransport.php'; + require_once 'Postman-Mail/PostmanEmailitTransport.php'; + require_once 'Postman-Mail/PostmanMailerooTransport.php'; + require_once 'Postman-Mail/PostmanSweegoTransport.php'; + require_once 'Postman-Mail/PostmanSendpulseTransport.php'; + require_once 'Postman-Suggest-Pro/PostmanSuggestProSocket.php'; + require_once 'Postman-Mail/PostmanPostmarkTransport.php'; + require_once 'Postman-Mail/PostmanSparkPostTransport.php'; + require_once 'Postman-Mail/PostmanElasticEmailTransport.php'; + require_once 'Postman-Mail/PostmanSmtp2GoTransport.php'; + require_once 'PostmanOAuthToken.php'; + require_once 'PostmanWpMailBinder.php'; + require_once 'PostmanConfigTextHelper.php'; + require_once 'Postman-Email-Log/PostmanEmailLogPostType.php'; + require_once 'Postman-Mail/PostmanMyMailConnector.php'; + require_once 'Postman-Mail/PostmanContactForm7.php'; + require_once 'Phpmailer/PostsmtpMailer.php'; + //require_once 'Postman-Mail/PostmanWooCommerce.php'; + require_once 'Postman-Mail/Services/PostmanServiceRequest.php'; + + //New Wizard + require_once 'Wizard/NewWizard.php'; + //load MainWP Child Files + require_once 'Extensions/MainWP-Child/mainwp-child.php'; + + //Mobile Application + require_once 'Mobile/mobile.php'; + + //Email Reporting + require_once 'Postman-Email-Health-Report/PostmanEmailReporting.php'; + require_once 'Postman-Email-Health-Report/PostmanEmailReportSending.php'; + + // New Dashboard + require_once 'Dashboard/NewDashboard.php'; + + // Email Tester + require_once 'Postman-Mail-Tester/PostmanEmailTester.php'; + + + // get plugin metadata - alternative to get_plugin_data + $this->pluginData = array( + 'name' => 'Post SMTP', + 'version' => $version, + ); + + // register the plugin metadata filter (part of the Postman API) + add_filter( 'postman_get_plugin_metadata', array( + $this, + 'getPluginMetaData', + ) ); + + // create an instance of the logger + $this->logger = new PostmanLogger( get_class( $this ) ); + if ( $this->logger->isDebug() ) { + $this->logger->debug( sprintf( '%1$s v%2$s starting', $this->pluginData ['name'], $this->pluginData ['version'] ) ); + } + + if ( isset( $_REQUEST ['page'] ) && $this->logger->isTrace() ) { + $this->logger->trace( 'Current page: ' . sanitize_text_field($_REQUEST ['page']) ); + } + + // register the email transports + + // store an instance of the WpMailBinder + $this->wpMailBinder = PostmanWpMailBinder::getInstance(); + + if( apply_filters( 'post_smtp_declare_wp_mail', true ) ) { + + $mailer = PostmanOptions::getInstance()->getSmtpMailer(); + $this->logger->trace( 'SMTP Mailer: ' . $mailer ); + + if ( $mailer && $mailer !== 'phpmailer') { + + // bind to wp_mail - this has to happen before the "init" action + // this design allows other plugins to register a Postman transport and call bind() + // bind may be called more than once + $this->wpMailBinder->bind(); + } else { + PostmanWpMailBinder::getInstance()->bound = true; + } + + } + + // registers the custom post type for all callers + PostmanEmailLogPostType::automaticallyCreatePostType(); + + // run the DatastoreUpgrader any time there is a version mismatch + if ( PostmanState::getInstance()->getVersion() != $this->pluginData ['version'] ) { + // manually trigger the activation hook + if ( $this->logger->isInfo() ) { + $this->logger->info( sprintf( 'Upgrading datastore from version %s to %s', PostmanState::getInstance()->getVersion(), $this->pluginData ['version'] ) ); + } + require_once 'PostmanInstaller.php'; + $upgrader = new PostmanInstaller(); + $upgrader->activatePostman(); + } + + // MyMail integration + new PostmanMyMailConnector( $rootPluginFilenameAndPath ); + + // WooCommerce Integration + //new PostmanWoocommerce(); + + // register the shortcode handler on the add_shortcode event + add_shortcode( 'postman-version', array( + $this, + 'version_shortcode', + ) ); + + // hook on the plugins_loaded event + add_action( 'init', array( + $this, + 'on_init', + ), 0 ); + + //Conflicting with backupbuddy, will be removed soon + //add_filter( 'extra_plugin_headers', [ $this, 'add_extension_headers' ] ); + + // hook on the wp_loaded event + add_action( 'wp_loaded', array( + $this, + 'on_wp_loaded', + ) ); + + // hook on the acivation event + register_activation_hook( $rootPluginFilenameAndPath, array( + $this, + 'on_activation', + ) ); + + // hook on the deactivation event + register_deactivation_hook( $rootPluginFilenameAndPath, array( + $this, + 'on_deactivation', + ) ); + + add_action( 'admin_head', array( $this, 'hide_wizard_notices' ) ); + + } + + /** + * Hide all admin notices on the setup wizard page. + */ + public function hide_wizard_notices() { + + if ( ! is_admin() ) { + return; + } + + if ( isset( $_GET['page'] ) && $_GET['page'] === 'postman/configuration_wizard' ) { + remove_all_actions( 'admin_notices' ); + remove_all_actions( 'all_admin_notices' ); + } + } + + function add_extension_headers($headers) { + $headers[] = 'Class'; + $headers[] = 'Slug'; + + return $headers; + } + + /** + * Functions to execute on the plugins_loaded event + * + * "After active plugins and pluggable functions are loaded" + * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request + */ + public function on_init() { + + // register the email transports + $this->registerTransports( $this->rootPluginFilenameAndPath ); + + // register the setup_admin function on plugins_loaded because we need to call + // current_user_can to verify the capability of the current user + if ( PostmanUtils::isAdmin() && is_admin() ) { + $this->setup_admin(); + } + + } + + /** + * Functions to execute on the wp_loaded event + * + * "After WordPress is fully loaded" + * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request + */ + public function on_wp_loaded() { + // register the check for configuration errors on the wp_loaded hook, + // because we want it to run after the OAuth Grant Code check on the init hook + $this->check_for_configuration_errors(); + } + + /** + * Functions to execute on the register_activation_hook + * ref: https://codex.wordpress.org/Function_Reference/register_activation_hook + */ + public function on_activation() { + + if ( $this->logger->isInfo() ) { + $this->logger->info( 'Activating plugin' ); + } + require_once 'PostmanInstaller.php'; + $upgrader = new PostmanInstaller(); + $upgrader->activatePostman(); + } + + /** + * Functions to execute on the register_deactivation_hook + * ref: https://codex.wordpress.org/Function_Reference/register_deactivation_hook + */ + public function on_deactivation() { + if ( $this->logger->isInfo() ) { + $this->logger->info( 'Deactivating plugin' ); + } + require_once 'PostmanInstaller.php'; + $upgrader = new PostmanInstaller(); + $upgrader->deactivatePostman(); + } + + /** + * If the user is on the WordPress Admin page, creates the Admin screens + */ + public function setup_admin() { + $this->logger->debug( 'Admin start-up sequence' ); + + $options = PostmanOptions::getInstance(); + $authToken = PostmanOAuthToken::getInstance(); + $rootPluginFilenameAndPath = $this->rootPluginFilenameAndPath; + + // load the dependencies + require_once 'PostmanMessageHandler.php'; + require_once 'PostmanAdminController.php'; + require_once 'Postman-Controller/PostmanWelcomeController.php'; + require_once 'Postman-Controller/PostmanDashboardWidgetController.php'; + require_once 'Postman-Controller/PostmanAdminPointer.php'; + require_once 'Postman-Email-Log/PostmanEmailLogController.php'; + require_once 'Postman-Connectivity-Test/PostmanConnectivityTestController.php'; + require_once 'Postman-Configuration/PostmanConfigurationController.php'; + require_once 'Postman-Send-Test-Email/PostmanSendTestEmailController.php'; + require_once 'Postman-Diagnostic-Test/PostmanDiagnosticTestController.php'; + require_once 'PostmanSMTPConflictManager.php'; + + // create and store an instance of the MessageHandler + $this->messageHandler = new PostmanMessageHandler(); + + // create the Admin Controllers + new PostmanWelcomeController( $rootPluginFilenameAndPath ); + new PostmanDashboardWidgetController( $rootPluginFilenameAndPath, $options, $authToken, $this->wpMailBinder ); + new PostmanAdminController( $rootPluginFilenameAndPath, $options, $authToken, $this->messageHandler, $this->wpMailBinder ); + new PostmanEmailLogController( $rootPluginFilenameAndPath ); + new PostmanConnectivityTestController( $rootPluginFilenameAndPath ); + new PostmanConfigurationController( $rootPluginFilenameAndPath ); + new PostmanSendTestEmailController( $rootPluginFilenameAndPath ); + new PostmanDiagnosticTestController( $rootPluginFilenameAndPath ); + + // Initialize SMTP Conflict Manager to detect and warn about conflicting plugins + new PostmanSMTPConflictManager(); + + // register the Postman signature (only if we're on a postman admin screen) on the in_admin_footer event + if ( PostmanUtils::isCurrentPagePostmanAdmin() ) { + add_action( 'in_admin_footer', array( + $this, + 'print_signature', + ) ); + } + } + + /** + * Check for configuration errors and displays messages to the user + */ + public function check_for_configuration_errors() { + $options = PostmanOptions::getInstance(); + $authToken = PostmanOAuthToken::getInstance(); + + $transport = PostmanTransportRegistry::getInstance()->getCurrentTransport(); + $scribe = $transport->getScribe(); + + $virgin = $options->isNew(); + if ( ! $transport->isConfiguredAndReady() ) { + // if the configuration is broken, and the user has started to configure the plugin + // show this error message + $messages = $transport->getConfigurationMessages(); + foreach ( $messages as $message ) { + if ( $message ) { + // log the warning message + $this->logger->warn( sprintf( '%s Transport has a configuration problem: %s', $transport->getName(), $message ) ); + + if ( PostmanUtils::isAdmin() && PostmanUtils::isCurrentPagePostmanAdmin() ) { + // on pages that are Postman admin pages only, show this error message + $this->messageHandler->addError( $message ); + } + } + } + } + + // on pages that are NOT Postman admin pages only, show this error message + if ( PostmanUtils::isAdmin() && ! PostmanUtils::isCurrentPagePostmanAdmin() && ! $transport->isConfiguredAndReady() ) { + // on pages that are *NOT* Postman admin pages only.... + // if the configuration is broken show this error message + add_action( 'admin_notices', array( + $this, + 'display_configuration_required_warning', + ) ); + } + } + + public static function getMailerTypeRecommend() { + ?> +
        +

        Please notice

        +

        + Mailer Type.', 'post-smtp' ); ?>
        + TEST Post SMTP with the value PHPMailer.', 'post-smtp' ); ?>
        + ONLY if the default mailer type is not working for you.', 'post-smtp' ); ?>
        + +

        + +

        +
        + pluginData; + } + + /** + * This is the general message that Postman requires configuration, to warn users who think + * the plugin is ready-to-go as soon as it is activated. + * This message only goes away once the plugin is configured. + */ + public function display_configuration_required_warning() { + if ( PostmanUtils::isAdmin() ) { + if ( $this->logger->isDebug() ) { + $this->logger->debug( 'Displaying configuration required warning' ); + } + $msg = PostmanTransportRegistry::getInstance()->getReadyMessage(); + $message = sprintf( $msg['message'] ); + $goToSettings = sprintf( '%s', PostmanUtils::getSettingsPageUrl(), __( 'Settings', 'post-smtp' ) ); + $goToEmailLog = sprintf( '%s', _x( 'Email Log', 'The log of Emails that have been delivered', 'post-smtp' ) ); + if ( PostmanOptions::getInstance()->isMailLoggingEnabled() ) { + $goToEmailLog = sprintf( '%s', PostmanUtils::getEmailLogPageUrl(), $goToEmailLog ); + } + $message .= (sprintf( ' %s | %s', $goToEmailLog, $goToSettings )); + $message .= ''; + + $hide = get_option('postman_release_version' ); + + if ( $msg['error'] == true && ! $hide ) { + $this->messageHandler->printMessage( $message, 'postman-not-configured-notice notice notice-error is-dismissible' ); + } + } + } + + /** + * Register the email transports. + * + * The Gmail API used to be a separate plugin which was registered when that plugin + * was loaded. But now both the SMTP, Gmail API and other transports are registered here. + * @since 2.0.25 require `PostmanAdminController.php` if not exists. + * @param mixed $pluginData + */ + private function registerTransports( $rootPluginFilenameAndPath ) { + + if( !class_exists( 'PostmanAdminController' ) ) { + require_once 'PostmanAdminController.php'; + } + + $postman_transport_registry = PostmanTransportRegistry::getInstance(); + + $postman_transport_registry->registerTransport( new PostmanDefaultModuleTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanSmtpModuleTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanGmailApiModuleTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanMandrillTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanSendGridTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanMailerSendTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanMailgunTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanSendinblueTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanMailtrapTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanResendTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanMailjetTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanSendpulseTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanPostmarkTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanSparkPostTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanElasticEmailTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanSmtp2GoTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanEmailitTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanMailerooTransport( $rootPluginFilenameAndPath ) ); + $postman_transport_registry->registerTransport( new PostmanSweegoTransport( $rootPluginFilenameAndPath ) ); + + do_action( 'postsmtp_register_transport', $postman_transport_registry ); + } + + /** + * Print the Postman signature on the bottom of the page + * + * http://striderweb.com/nerdaphernalia/2008/06/give-your-wordpress-plugin-credit/ + */ + function print_signature() { + printf( '%s %s
        ', $this->pluginData ['name'], $this->pluginData ['version'] ); + } + + /** + * Shortcode to return the current plugin version. + * + * From http://code.garyjones.co.uk/get-wordpress-plugin-version/ + * + * @return string Plugin version + */ + function version_shortcode() { + return $this->pluginData ['version']; + } +} + +if ( ! function_exists( 'str_getcsv' ) ) { + /** + * PHP version less than 5.3 don't have str_getcsv natively. + * + * @param mixed $string + * @return multitype: + */ + function str_getcsv( $string ) { + $logger = new PostmanLogger( 'postman-common-functions' ); + if ( $logger->isDebug() ) { + $logger->debug( 'Using custom str_getcsv' ); + } + return PostmanUtils::postman_strgetcsv_impl( $string ); + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanAdminController.php b/html/wp-content/plugins/post-smtp/Postman/PostmanAdminController.php new file mode 100644 index 0000000..31b6f74 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanAdminController.php @@ -0,0 +1,484 @@ +logger = new PostmanLogger( get_class( $this ) ); + $this->options = $options; + $this->authorizationToken = $authorizationToken; + $this->messageHandler = $messageHandler; + $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath; + $this->wpMailBinder = $binder; + + // check if the user saved data, and if validation was successful + $session = PostmanSession::getInstance(); + if ( $session->isSetAction() ) { + $this->logger->debug( sprintf( 'session action: %s', $session->getAction() ) ); + } + if ( $session->getAction() == PostmanInputSanitizer::VALIDATION_SUCCESS ) { + // unset the action + $session->unsetAction(); + // do a redirect on the init hook + $this->registerInitFunction( 'handleSuccessfulSave' ); + // add a saved message to be shown after the redirect + $this->messageHandler->addMessage( _x( 'Settings saved.', 'The plugin successfully saved new settings.', 'post-smtp' ) ); + return; + } else { + // unset the action in the failed case as well + $session->unsetAction(); + } + + // test to see if an OAuth authentication is in progress + if ( $session->isSetOauthInProgress() ) { + // there is only a three minute window that Postman will expect a Grant Code, once Grant is clicked by the user + $this->logger->debug( 'Looking for grant code' ); + if ( isset( $_GET ['code'] ) ) { + $this->logger->debug( 'Found authorization grant code' ); + + // queue the function that processes the incoming grant code + $this->registerInitFunction( 'handleAuthorizationGrant' ); + return; + } + } + do_action('post_smtp_handle_oauth', $this->messageHandler ); + + // continue to initialize the AdminController + add_action( 'init', array( + $this, + 'on_init', + ) ); + + // continue to initialize the AdminController + add_action( 'wpmu_options', array( + $this, + 'wpmu_options', + ) ); + + add_action( 'update_wpmu_options', array( + $this, + 'update_wpmu_options', + ) ); + + // Adds "Settings" link to the plugin action page + add_filter( 'plugin_action_links_' . plugin_basename( $this->rootPluginFilenameAndPath ), array( + $this, + 'postmanModifyLinksOnPluginsListPage', + ) ); + + require_once( 'PostmanPluginFeedback.php' ); + } + + + function wpmu_options() { + $options = get_site_option( PostmanOptions::POSTMAN_NETWORK_OPTIONS ); + ?> + + +

        +
        + +
        Hey there 👋,

        Congrats! Your test email was sent successfully

        Thank you for using Post SMTP. Our mission is to enhance you email deliverability.
        + + + +
        + This email was sent from your website '.get_bloginfo().' to test your email functionality. +
        + + + + + + + + + + $value ) { + $options[$key] = sanitize_text_field( $value ); + + if ( $value == 'null' ) { + unset( $options[$key] ); + } + } + + update_site_option( PostmanOptions::POSTMAN_NETWORK_OPTIONS, $options ); + } else { + update_site_option( PostmanOptions::POSTMAN_NETWORK_OPTIONS, array() ); + } + } + + /** + * Functions to execute on the init event + * + * "Typically used by plugins to initialize. The current user is already authenticated by this time." + * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request + */ + public function on_init() { + // only administrators should be able to trigger this + if ( PostmanUtils::isAdmin() ) { + $transport = PostmanTransportRegistry::getInstance()->getCurrentTransport(); + $this->oauthScribe = $transport->getScribe(); + + // register content handlers + $viewController = new PostmanViewController( $this->rootPluginFilenameAndPath, $this->options, $this->authorizationToken, $this->oauthScribe, $this ); + + // register action handlers + $this->registerAdminPostAction( self::PURGE_DATA_SLUG, 'handlePurgeDataAction' ); + $this->registerAdminPostAction( self::IMPORT_SETTINGS_SLUG, 'importSettingsAction' ); + $this->registerAdminPostAction( PostmanUtils::REQUEST_OAUTH2_GRANT_SLUG, 'handleOAuthPermissionRequestAction' ); + + if ( PostmanUtils::isCurrentPagePostmanAdmin() ) { + $this->checkPreRequisites(); + } + } + } + + /** + * + */ + private function checkPreRequisites() { + $states = PostmanPreRequisitesCheck::getState(); + foreach ( $states as $state ) { + if ( ! $state ['ready'] ) { + /* Translators: where %1$s is the name of the library */ + $message = sprintf( __( 'This PHP installation requires the %1$s library.', 'post-smtp' ), $state ['name'] ); + if ( $state ['required'] ) { + $this->messageHandler->addError( $message ); + } else { + // $this->messageHandler->addWarning ( $message ); + } + } + } + } + + /** + * + * @param mixed $actionName + * @param mixed $callbackName + */ + private function registerInitFunction( $callbackName ) { + $this->logger->debug( 'Registering init function ' . $callbackName ); + add_action( 'init', array( + $this, + $callbackName, + ) ); + } + + /** + * Registers actions posted by am HTML FORM with the WordPress 'action' parameter + * + * @param mixed $actionName + * @param mixed $callbankName + */ + private function registerAdminPostAction( $actionName, $callbankName ) { + // $this->logger->debug ( 'Registering ' . $actionName . ' Action Post handler' ); + add_action( 'admin_post_' . $actionName, array( + $this, + $callbankName, + ) ); + } + + /** + * Add "Settings" link to the plugin action page + * + * @param mixed $links + * @return multitype: + */ + public function postmanModifyLinksOnPluginsListPage( $links ) { + // only administrators should be able to trigger this + if ( PostmanUtils::isAdmin() ) { + $mylinks = array( + //sprintf( '%s', 'https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=yehudahas@gmail.com&item_name=Donation+for+PostSMTP', __( 'Donate', 'post-smtp' ) ), + sprintf( '%s', admin_url( 'admin.php?page=postman%2Fconfiguration' ), __( 'Settings', 'post-smtp' ) ), + sprintf( '%s', 'https://postmansmtp.com', __( 'Visit us', 'post-smtp' ) ), + ); + return array_merge( $mylinks, $links ); + } + } + + /** + * This function runs after a successful, error-free save + */ + public function handleSuccessfulSave() { + // WordPress likes to keep GET parameters around for a long time + // (something in the call to settings_fields() does this) + // here we redirect after a successful save to clear those parameters + PostmanUtils::redirect( PostmanUtils::POSTMAN_HOME_PAGE_RELATIVE_URL ); + } + + /** + * This function handle the request to import plugin data + */ + public function importSettingsAction() { + $this->logger->debug( 'is wpnonce import-settings?' ); + $success = true; + if ( wp_verify_nonce( $_REQUEST ['_wpnonce'], PostmanAdminController::IMPORT_SETTINGS_SLUG ) ) { + $success = PostmanOptions::getInstance()->import( sanitize_textarea_field($_POST ['settings']) ); + } else { + $success = false; + } + if ( ! $success ) { + $this->messageHandler->addError( __( 'There was an error importing the data.', 'post-smtp' ) ); + $this->logger->error( 'There was an error importing the data' ); + } + PostmanUtils::redirect( PostmanUtils::POSTMAN_HOME_PAGE_RELATIVE_URL ); + } + /** + * This function handle the request to purge plugin data + */ + public function handlePurgeDataAction() { + $this->logger->debug( 'is wpnonce purge-data?' ); + if ( wp_verify_nonce( $_REQUEST ['_wpnonce'], PostmanAdminController::PURGE_DATA_SLUG ) ) { + + /** + * Fires before resetting pluign + * + * @since 2.1.4 + */ + do_action( 'post_smtp_before_reset_plugin' ); + + $this->logger->debug( 'Purging stored data' ); + delete_option( PostmanOptions::POSTMAN_OPTIONS ); + delete_option( PostmanOAuthToken::OPTIONS_NAME ); + delete_option( PostmanAdminController::TEST_OPTIONS ); + + //delete logs as well + if( !isset( $_REQUEST['ps_preserve_email_logs'] ) ) { + + $logPurger = new PostmanEmailLogPurger(); + $logPurger->removeAll(); + + } + + //delete postman health report settings on reset + delete_option( 'postman_rat' ); + delete_transient( 'ps_rat_has_sent' ); + delete_transient( 'ps_rat_has_sent' ); + + $this->messageHandler->addMessage( __( 'Plugin data was removed.', 'post-smtp' ) ); + + /** + * Fires after resetting pluign + * + * @since 2.1.4 + */ + do_action( 'post_smtp_after_reset_plugin' ); + + PostmanUtils::redirect( PostmanUtils::POSTMAN_HOME_PAGE_RELATIVE_URL ); + } + } + + /** + * Handles the authorization grant + */ + function handleAuthorizationGrant() { + $logger = $this->logger; + $options = $this->options; + $authorizationToken = $this->authorizationToken; + $logger->debug( 'Authorization in progress' ); + $transactionId = PostmanSession::getInstance()->getOauthInProgress(); + $message = ''; + $redirect_uri = admin_url( "admin.php?page=postman/configuration_wizard&socket=gmail_api&step=2" ); + + // begin transaction + PostmanUtils::lock(); + + $authenticationManager = PostmanAuthenticationManagerFactory::getInstance()->createAuthenticationManager(); + try { + if ( $authenticationManager->processAuthorizationGrantCode( $transactionId ) ) { + $logger->debug( 'Authorization successful' ); + // save to database + $authorizationToken->save(); + $message = __( 'The OAuth 2.0 authorization was successful. Ready to send e-mail.', 'post-smtp' ); + $this->messageHandler->addMessage( $message ); + + //Let's redirect to New Wizard + if( !apply_filters( 'post_smtp_legacy_wizard', true ) ) { + + wp_redirect( "{$redirect_uri}&msg={$message}&success=1" ); + exit(); + + } + + } else { + + $message = __( 'Your email provider did not grant Postman permission. Try again.', 'post-smtp' ); + + $this->messageHandler->addError( $message ); + + //Let's redirect to New Wizard + if( !apply_filters( 'post_smtp_legacy_wizard', true ) ) { + + wp_redirect( "{$redirect_uri}&msg={$message}" ); + exit(); + + } + + } + } catch ( PostmanStateIdMissingException $e ) { + + $message = __( 'The grant code from Google had no accompanying state and may be a forgery', 'post-smtp' ); + + $this->messageHandler->addError( $message ); + + //Let's redirect to New Wizard + if( !apply_filters( 'post_smtp_legacy_wizard', true ) ) { + + wp_redirect( "{$redirect_uri}&msg={$message}" ); + exit(); + + } + + } catch ( Exception $e ) { + $logger->error( 'Error: ' . get_class( $e ) . ' code=' . $e->getCode() . ' message=' . $e->getMessage() ); + + $message = sprintf( __( 'Error authenticating with this Client ID. [%s]', 'post-smtp' ), '' . $e->getMessage() . '' ); + + /* translators: %s is the error message */ + $this->messageHandler->addError( $message ); + + //Let's redirect to New Wizard + if( !apply_filters( 'post_smtp_legacy_wizard', true ) ) { + + wp_redirect( "{$redirect_uri}&msg={$message}" ); + exit(); + + } + + } + + // clean-up + PostmanUtils::unlock(); + PostmanSession::getInstance()->unsetOauthInProgress(); + + // redirect home + PostmanUtils::redirect( PostmanUtils::POSTMAN_HOME_PAGE_RELATIVE_URL ); + } + + /** + * This method is called when a user clicks on a "Request Permission from Google" link. + * This link will create a remote API call for Google and redirect the user from WordPress to Google. + * Google will redirect back to WordPress after the user responds. + */ + public function handleOAuthPermissionRequestAction() { + $this->logger->debug( 'handling OAuth Permission request' ); + $authenticationManager = PostmanAuthenticationManagerFactory::getInstance()->createAuthenticationManager(); + $transactionId = $authenticationManager->generateRequestTransactionId(); + PostmanSession::getInstance()->setOauthInProgress( $transactionId ); + $authenticationManager->requestVerificationCode( $transactionId ); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanAjaxController.php b/html/wp-content/plugins/post-smtp/Postman/PostmanAjaxController.php new file mode 100644 index 0000000..ad63464 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanAjaxController.php @@ -0,0 +1,68 @@ +logger = new PostmanLogger ( get_class ( $this ) ); + } + /** + * + * @param mixed $actionName + * @param mixed $callbackName + */ + protected function registerAjaxHandler($actionName, $class, $callbackName) { + if (is_admin ()) { + $fullname = 'wp_ajax_' . $actionName; + // $this->logger->debug ( 'Registering ' . 'wp_ajax_' . $fullname . ' Ajax handler' ); + add_action ( $fullname, array ( + $class, + $callbackName + ) ); + } + } + + /** + * + * @param mixed $parameterName + * @return mixed + */ + protected function getBooleanRequestParameter($parameterName) { + return filter_var ( $this->getRequestParameter ( $parameterName ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * + * @param mixed $parameterName + * @return mixed + */ + protected function getRequestParameter($parameterName) { + if (isset ( $_POST [$parameterName] )) { + if ( is_array($_POST [$parameterName] ) ) { + array_walk_recursive( $_POST [$parameterName], 'sanitize_text_field' ); + $value = $_POST [$parameterName]; + } else { + $value = sanitize_text_field($_POST[$parameterName]); + } + + $this->logger->trace ( sprintf ( 'Found parameter "%s"', $parameterName ) ); + $this->logger->trace ( $value ); + + return $value; + } + } + } +} + +require_once ('Postman-Controller/PostmanManageConfigurationAjaxHandler.php'); diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanConfigTextHelper.php b/html/wp-content/plugins/post-smtp/Postman/PostmanConfigTextHelper.php new file mode 100644 index 0000000..8ba5ef0 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanConfigTextHelper.php @@ -0,0 +1,308 @@ +Read Here', 'post-smtp' ), 'https://postmansmtp.com/how-to-configure-post-smtp-with-gmailgsuite-using-oauth/' ); + $text = sprintf( '%s! %s', $attention, $errorMessage ); + + return $text; + } + function isOauthHost() { + return false; + } + function isGoogle() { + return false; + } + function isMicrosoft() { + return false; + } + function isYahoo() { + return false; + } + public function getRequestPermissionLinkText() { + /* translators: where %s is the Email Service Owner (e.g. Google, Microsoft or Yahoo) */ + return sprintf( _x( 'Grant permission with %s', 'Command to initiate OAuth authentication', 'post-smtp' ), $this->getOwnerName() ); + } + } +} +if ( ! class_exists( 'PostmanGoogleOAuthScribe' ) ) { + class PostmanGoogleOAuthScribe extends PostmanAbstractConfigTextHelper { + public function isGoogle() { + return true; + } + function isOauthHost() { + return true; + } + public function getCallbackUrl() { + // see https://codex.wordpress.org/Function_Reference/admin_url#Related + return admin_url( 'options-general.php' ) . '?page=postman'; + } + function getCallbackDomain() { + $urlParts = parse_url( $this->getCallbackUrl() ); + if ( isset( $urlParts ['scheme'] ) && isset( $urlParts ['host'] ) ) { + return $urlParts ['scheme'] . '://' . $urlParts ['host']; + } else { + throw new Exception(); + } + } + public function getClientIdLabel() { + /* Translators: This description is specific to Google */ + return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', 'post-smtp' ); + } + public function getClientSecretLabel() { + /* Translators: This description is specific to Google */ + return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', 'post-smtp' ); + } + public function getCallbackUrlLabel() { + /* Translators: This description is specific to Google */ + return _x( 'Authorized redirect URI', 'Name of the Application Callback URI', 'post-smtp' ); + } + public function getCallbackDomainLabel() { + /* Translators: This description is specific to Google */ + return _x( 'Authorized JavaScript origins', 'Name of the Application Callback Domain', 'post-smtp' ); + } + public function getOwnerName() { + /* Translators: This description is specific to Google */ + return _x( 'Google', 'Name of the email service owner', 'post-smtp' ); + } + public function getServiceName() { + /* Translators: This description is specific to Google */ + return _x( 'Gmail', 'Name of the email service', 'post-smtp' ); + } + public function getApplicationDescription() { + /* Translators: This description is specific to Google */ + return _x( 'a Client ID for web application', 'Description of the email service OAuth 2.0 Application', 'post-smtp' ); + } + public function getApplicationPortalName() { + /* Translators: This description is specific to Google */ + return _x( 'Google Developers Console Gmail Wizard', 'Name of the email service portal', 'post-smtp' ); + } + public function getApplicationPortalUrl() { + return 'https://www.google.com/accounts/Logout?continue=https://console.developers.google.com/start/api?id=gmail'; + } + public function getOAuthPort() { + return 465; + } + public function getEncryptionType() { + return PostmanOptions::SECURITY_TYPE_SMTPS; + } + } +} +if ( ! class_exists( 'PostmanMicrosoftOAuthScribe' ) ) { + class PostmanMicrosoftOAuthScribe extends PostmanAbstractConfigTextHelper { + public function isMicrosoft() { + return true; + } + function isOauthHost() { + return true; + } + public function getCallbackUrl() { + return admin_url( 'options-general.php' ); + } + function getCallbackDomain() { + $urlParts = parse_url( $this->getCallbackUrl() ); + if ( isset( $urlParts ['host'] ) ) { + return $urlParts ['host']; + } else { + throw new Exception(); + } + } + public function getClientIdLabel() { + /* Translators: This description is specific to Microsoft */ + return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', 'post-smtp' ); + } + public function getClientSecretLabel() { + /* Translators: This description is specific to Microsoft */ + return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', 'post-smtp' ); + } + public function getCallbackUrlLabel() { + /* Translators: This description is specific to Microsoft */ + return _x( 'Redirect URL', 'Name of the Application Callback URI', 'post-smtp' ); + } + public function getCallbackDomainLabel() { + /* Translators: This description is specific to Microsoft */ + return _x( 'Root Domain', 'Name of the Application Callback Domain', 'post-smtp' ); + } + public function getOwnerName() { + /* Translators: This description is specific to Microsoft */ + return _x( 'Microsoft', 'Name of the email service owner', 'post-smtp' ); + } + public function getServiceName() { + /* Translators: This description is specific to Microsoft */ + return _x( 'Outlook.com', 'Name of the email service', 'post-smtp' ); + } + public function getApplicationDescription() { + /* Translators: This description is specific to Microsoft */ + return _x( 'an Application', 'Description of the email service OAuth 2.0 Application', 'post-smtp' ); + } + public function getApplicationPortalName() { + /* Translators: This description is specific to Microsoft */ + return _x( 'Microsoft Developer Center', 'Name of the email service portal', 'post-smtp' ); + } + public function getApplicationPortalUrl() { + return 'https://account.live.com/developers/applications/index'; + } + public function getOAuthPort() { + return 587; + } + public function getEncryptionType() { + return PostmanOptions::SECURITY_TYPE_STARTTLS; + } + } +} +if ( ! class_exists( 'PostmanYahooOAuthScribe' ) ) { + class PostmanYahooOAuthScribe extends PostmanAbstractConfigTextHelper { + public function isYahoo() { + return true; + } + function isOauthHost() { + return true; + } + public function getCallbackUrl() { + return admin_url( 'options-general.php' ) . '?page=postman'; + } + function getCallbackDomain() { + $urlParts = parse_url( $this->getCallbackUrl() ); + if ( isset( $urlParts ['host'] ) ) { + return $urlParts ['host']; + } else { + throw new Exception(); + } + } + public function getClientIdLabel() { + /* Translators: This description is specific to Yahoo */ + return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', 'post-smtp' ); + } + public function getClientSecretLabel() { + /* Translators: This description is specific to Yahoo */ + return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', 'post-smtp' ); + } + public function getCallbackUrlLabel() { + /* Translators: This description is specific to Yahoo */ + return _x( 'Home Page URL', 'Name of the Application Callback URI', 'post-smtp' ); + } + public function getCallbackDomainLabel() { + /* Translators: This description is specific to Yahoo */ + return _x( 'Callback Domain', 'Name of the Application Callback Domain', 'post-smtp' ); + } + public function getOwnerName() { + /* Translators: This description is specific to Yahoo */ + return _x( 'Yahoo', 'Name of the email service owner', 'post-smtp' ); + } + public function getServiceName() { + /* Translators: This description is specific to Yahoo */ + return _x( 'Yahoo Mail', 'Name of the email service', 'post-smtp' ); + } + public function getApplicationDescription() { + /* Translators: This description is specific to Yahoo */ + return _x( 'an Application', 'Description of the email service OAuth 2.0 Application', 'post-smtp' ); + } + public function getApplicationPortalName() { + /* Translators: This description is specific to Yahoo */ + return _x( 'Yahoo Developer Network', 'Name of the email service portal', 'post-smtp' ); + } + public function getApplicationPortalUrl() { + return 'https://developer.yahoo.com/apps/'; + } + public function getOAuthPort() { + return 465; + } + public function getEncryptionType() { + return PostmanOptions::SECURITY_TYPE_SMTPS; + } + } +} +if ( ! class_exists( 'PostmanNonOAuthScribe' ) ) { + class PostmanNonOAuthScribe extends PostmanAbstractConfigTextHelper { + protected $hostname; + public function __construct( $hostname ) { + $this->hostname = $hostname; + } + public function isGoogle() { + return PostmanUtils::endsWith( $this->hostname, 'gmail.com' ); + } + public function isMicrosoft() { + return PostmanUtils::endsWith( $this->hostname, 'live.com' ); + } + public function isYahoo() { + return PostmanUtils::endsWith( $this->hostname, 'yahoo.com' ); + } + public function getOAuthHelp() { + $text = __( 'Enter an Outgoing Mail Server with OAuth2 capabilities.', 'post-smtp' ); + return sprintf( '%s', $text ); + } + public function getCallbackUrl() { + return ''; + } + function getCallbackDomain() { + return ''; + } + public function getClientIdLabel() { + return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', 'post-smtp' ); + } + public function getClientSecretLabel() { + return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', 'post-smtp' ); + } + public function getCallbackUrlLabel() { + return _x( 'Redirect URI', 'Name of the Application Callback URI', 'post-smtp' ); + } + public function getCallbackDomainLabel() { + return _x( 'Website Domain', 'Name of the Application Callback Domain', 'post-smtp' ); + } + public function getOwnerName() { + return ''; + } + public function getServiceName() { + return ''; + } + public function getApplicationDescription() { + return ''; + } + public function getApplicationPortalName() { + return ''; + } + public function getApplicationPortalUrl() { + return ''; + } + public function getOAuthPort() { + return ''; + } + public function getEncryptionType() { + return ''; + } + public function getRequestPermissionLinkText() { + return __( 'Grant OAuth 2.0 Permission', 'post-smtp' ); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanEmailLogs.php b/html/wp-content/plugins/post-smtp/Postman/PostmanEmailLogs.php new file mode 100644 index 0000000..2ff14e5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanEmailLogs.php @@ -0,0 +1,893 @@ +db = $wpdb; + $this->logger = new PostmanLogger( get_class( $this ) ); + + //Render Message body in iframe + if( + isset( $_GET['page'] ) && $_GET['page'] == 'postman_email_log' + && + isset( $_GET['view'] ) && $_GET['view'] == 'log' + && + isset( $_GET['log_id'] ) && !empty( $_GET['log_id'] ) + ) { + + // Check if user has permission to view email logs + if ( ! current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ) ) { + wp_die( __( 'Sorry, you are not allowed to access this page.', 'post-smtp' ) ); + } + + // Print + if( isset( $_GET['print'] ) && $_GET['print'] == 1 ) { + + echo ""; + + } + + $id = sanitize_text_field( $_GET['log_id'] ); + $email_query_log = new PostmanEmailQueryLog(); + $log = $email_query_log->get_log( $id, '' ); + $header = $log['original_headers']; + $msg = $log['original_message']; + $msg = $this->purify_html( $msg ); + echo ( isset ( $header ) && strpos( $header, "text/html" ) ) ? $msg : '' . $msg . '' ; + + die; + + } + + } + + /** + * + * Purifies and sanitizes HTML content using HTMLPurifier. + * + * @param string $html_content The potentially unsafe HTML content. + * @return string The purified and sanitized HTML content. + * @since 3.1.2 + * @version 1.0.0 + * + */ + public function purify_html( $html_content ) { + // Configure HTMLPurifier. + $config = HTMLPurifier_Config::createDefault(); + $config->set('Core.Encoding', 'UTF-8'); + $config->set('HTML.Doctype', 'XHTML 1.0 Transitional'); + + // ✅ Allow all standard email template elements + $config->set('HTML.AllowedElements', null); + + // ✅ Allow all attributes except JavaScript-based ones + $config->set('HTML.AllowedAttributes', null); + $config->set('CSS.AllowedProperties', 'border-radius, background'); + + // ⌠Block JavaScript-based attacks + $config->set( 'HTML.ForbiddenElements', ['script'] ); + + $config->set( 'HTML.ForbiddenAttributes', ['on*'] ); + // ⌠Prevent JavaScript in links and images. + $config->set('URI.AllowedSchemes', [ + 'http' => true, + 'https' => true, + 'mailto' => true, + 'tel' => true, + ]); + + $config->set( 'URI.SafeIframeRegexp', '' ); + // ✅ Allow inline styles but prevent unsafe styles + $config->set( 'CSS.Trusted', false ); // Block dangerous inline styles. + $config->set( 'CSS.AllowedProperties', null ); // NULL means allow all CSS properties. + $config->set( 'CSS.MaxImgLength', null ); + // this library is removing display:flex how can we fix it? + $config->set( 'CSS.AllowTricky', true ); + + // Initialize HTMLPurifier. + $purifier = new HTMLPurifier( $config); + + // Purify the dirty HTML. + return $purifier->purify( $html_content ); + } + + /** + * Installs the Table | Creates the Table + * + * @since 2.5.0 + * @version 1.0.0 + */ + public function install_table() { + + if( !function_exists( 'dbDelta' ) ) { + + require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); + + } + + $sql = "CREATE TABLE IF NOT EXISTS `{$this->db->prefix}{$this->db_name}` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT,"; + + foreach ( $this->fields as $field ) { + + if( $field == 'time' ) { + + $sql .= "`" . $field . "` BIGINT(20) DEFAULT NULL,"; + continue; + + } + + $sql .= "`" . $field . "` longtext DEFAULT NULL,"; + + } + + $sql .= "PRIMARY KEY (`id`)) ENGINE=InnoDB"; + $sql .= empty( $this->db->charset ) ? '' : " CHARSET={$this->db->charset}"; + $sql .= empty( $this->db->collate ) ? '' : " COLLATE={$this->db->collate}"; + $sql .= ";"; + + $response = dbDelta( $sql ); + + if( !$this->db->last_error ) { + + $sql = " + CREATE TABLE IF NOT EXISTS `{$this->db->prefix}{$this->meta_table}` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `log_id` bigint(20) NOT NULL, + `meta_key` longtext DEFAULT NULL, + `meta_value` longtext DEFAULT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB"; + + $sql .= empty( $this->db->charset ) ? '' : " CHARSET={$this->db->charset}"; + $sql .= empty( $this->db->collate ) ? '' : " COLLATE={$this->db->collate}"; + $sql .= ";"; + + $response = dbDelta( $sql ); + + } + + if( !$this->db->last_error ) { + + update_option( 'postman_db_version', POST_SMTP_DB_VERSION ); + + } + + } + + + /** + * Update Table + * + * @since 2.5.1 + * @version 1.0.0 + */ + public function update_table() { + + $sql = "ALTER TABLE `{$this->db->prefix}{$this->db_name}` + MODIFY COLUMN solution longtext DEFAULT NULL, + MODIFY COLUMN success longtext DEFAULT NULL, + MODIFY COLUMN from_header longtext DEFAULT NULL, + MODIFY COLUMN to_header longtext DEFAULT NULL, + MODIFY COLUMN cc_header longtext DEFAULT NULL, + MODIFY COLUMN bcc_header longtext DEFAULT NULL, + MODIFY COLUMN reply_to_header longtext DEFAULT NULL, + MODIFY COLUMN transport_uri longtext DEFAULT NULL, + MODIFY COLUMN original_to longtext DEFAULT NULL, + MODIFY COLUMN original_subject longtext DEFAULT NULL, + MODIFY COLUMN original_headers longtext DEFAULT NULL;"; + + $response = $this->db->query( $sql ); + + if( !$this->db->last_error ) { + + $sql = "ALTER TABLE `{$this->db->prefix}{$this->meta_table}` + MODIFY COLUMN meta_key longtext, + MODIFY COLUMN meta_value longtext;"; + + $response = $this->db->query( $sql ); + + } + + if( !$this->db->last_error ) { + + update_option( 'postman_db_version', POST_SMTP_DB_VERSION ); + + } + + } + + + public static function get_data( $post_id ) { + $fields = array(); + foreach ( self::$fields as $field ) { + $fields[$field][0] = get_post_meta( $post_id, $field, true ); + } + + return $fields; + } + + public static function get_fields() { + return self::$fields; + } + + function migrate_data() { + $args = array( + 'post_type' => 'postman_sent_mail', + 'posts_per_page' => -1, + ); + + $logs = new WP_Query($args); + + $failed_records = 0; + foreach ( $logs->posts as $log ) { + + foreach ($this->fields as $key ) { + $value = $this->get_meta( $log->ID, $key, true ); + + if ( $this->add_meta( $log->ID, $key, $value ) ) { + delete_post_meta( $log->ID, $key ); + } else { + $failed_records++; + } + } + } + } + + + /** + * Delete Log Items, But Keeps recent $keep + * + * @since 2.5.0 + * @version 1.0.0 + */ + public function truncate_log_items( $keep ) { + + return $this->db->get_results( + $this->db->prepare( + "DELETE logs FROM `{$this->db->prefix}{$this->db_name}` logs + LEFT JOIN + (SELECT id + FROM `{$this->db->prefix}{$this->db_name}` + ORDER BY id DESC + LIMIT %d) logs2 USING(id) + WHERE logs2.id IS NULL;", + $keep + ) + ); + + } + + + /** + * Insert Log Into table + * + * @param array $data + * @param int $id (Update Existing Record) + * @since 2.5.0 + * @version 1.0.0 + */ + public function save( $data, $id = '' ) { + + $data['time'] = !isset( $data['time'] ) ? current_time( 'timestamp' ) : $data['time']; + + if( !empty( $id ) ) { + return $this->update( $data, $id ); + } + else { + return $this->db->insert( $this->db->prefix . $this->db_name, $data ) ? $this->db->insert_id : false; + } + + } + + + /** + * Update Log + * + * @param array $data + * @param int $id + * @since 2.5.0 + * @version 1.0.0 + */ + public function update( $data, $id ) { + + $result = $this->db->update( + $this->db->prefix . $this->db_name, + $data, + array( 'id' => $id ) + ); + + return $result !== false ? $id : false; + + } + + + /** + * Get Logs + * + * @since 2.5.0 + * @version 1.0 + */ + public function get_logs_ajax() { + if( !wp_verify_nonce( $_GET['security'], 'security' ) ) { + + return; + + } + + // Check if user has permission to view email logs + if ( ! current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ) ) { + wp_send_json_error( __( 'Sorry, you are not allowed to access email logs.', 'post-smtp' ) ); + return; + } + + if( isset( $_GET['action'] ) && $_GET['action'] == 'ps-get-email-logs' ) { + + $logs_query = new PostmanEmailQueryLog; + + $query = array(); + $query['start'] = sanitize_text_field( $_GET['start'] ); + $query['end'] = sanitize_text_field( $_GET['length'] ); + $query['search'] = sanitize_text_field( $_GET['search']['value'] ); + $query['order'] = sanitize_text_field( $_GET['order'][0]['dir'] ); + $query['status'] = isset( $_GET['status'] ) ? sanitize_text_field( $_GET['status'] ) : ''; + + //MainWP | Get Sites + if( isset( $_GET['site_id'] ) ) { + + $query['site_id'] = sanitize_text_field( $_GET['site_id'] ); + + } + + //Column Name + $query['order_by'] = sanitize_text_field( $_GET['columns'][$_GET['order'][0]['column']]['data'] ); + + //Date Filter :) + if( isset( $_GET['from'] ) && !empty( $_GET['from'] ) ) { + + $query['from'] = strtotime( sanitize_text_field( $_GET['from'] ) ); + + } + + if( isset( $_GET['to'] ) && !empty( $_GET['to'] ) ) { + + $query['to'] = strtotime( sanitize_text_field( $_GET['to'] ) ) + 86400; + + } + + if( isset( $_GET['filter_by'] ) && !empty( $_GET['filter_by'] ) ) { + + $query['filter_by'] = sanitize_text_field( $_GET['filter_by'] ); + + } + + $data = $logs_query->get_logs( $query ); + //WordPress Date, Time Format + $date_format = get_option( 'date_format' ); + $time_format = get_option( 'time_format' ); + $search = array( + '<', + '>', + '"', + "'" + ); + $replace = array( + '<', + '>', + '"', + ''' + ); + + //Lets manage the Date format :) + foreach( $data as $row ) { + + $row->time = date( "{$date_format} {$time_format}", $row->time ); + + if( $row->success == 1 ) { + + $row->success = 'Success'; + + } else if( $row->success == 'Sent ( ** Fallback ** )' ){ + + $row->success = 'SuccessView details'; + + } + elseif( $row->success == 'In Queue' ) { + + $row->success = 'In Queue'; + + } + else { + + $row->success = 'FailedView details'; + + } + + + $row->actions = ''; + + /** + * Filter the row data + * + * @since 2.5.0 + * @version 1.0.0 + */ + $row = apply_filters( 'ps_email_logs_row', $row ); + + //Escape HTML + $row->original_subject = esc_html( $row->original_subject ); + + } + + $total_rows = $logs_query->get_total_row_count(); + $total_rows = ( is_array( $total_rows ) && !empty( $total_rows ) ) ? $total_rows[0] : ''; + $total_rows = isset( $total_rows->count ) ? (int)$total_rows->count : ''; + + $filtered_rows = $logs_query->get_filtered_rows_count(); + $filtered_rows = ( is_array( $filtered_rows ) && !empty( $filtered_rows ) ) ? $filtered_rows[0] : ''; + $filtered_rows = isset( $filtered_rows->count ) ? (int)$filtered_rows->count : ''; + + $logs['data'] = $data; + $logs['recordsTotal'] = $total_rows; + $logs['recordsFiltered'] = $filtered_rows; + $logs['draw'] = sanitize_text_field( $_GET['draw'] ); + + echo json_encode( $logs ); + die; + + } + + } + + + /** + * Delete Logs | AJAX callback + * + * @since 2.5.0 + * @version 1.0.0 + */ + public function delete_logs_ajax() { + + if( !wp_verify_nonce( $_POST['security'], 'security' ) ) { + + return; + + } + + // Check if user has permission to manage email logs + if ( ! current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ) ) { + wp_send_json_error( __( 'Sorry, you are not allowed to delete email logs.', 'post-smtp' ) ); + return; + } + + if( isset( $_POST['action'] ) && $_POST['action'] == 'ps-delete-email-logs' ) { + + $args = array(); + $deleted_all = false; + + //Delete all + if( !isset( $_POST['selected'] ) ) { + + $args = array( -1 ); + $deleted_all = true; + + } + //Delete selected + else { + + $args = wp_parse_id_list( $_POST['selected'] ); + + } + + $email_query_log = new PostmanEmailQueryLog(); + $delete = $email_query_log->delete_logs( $args ); + + if( $delete ) { + + /** + * Fires after deleting logs + * + * @param array $args + * @since 2.5.0 + * @version 1.0.0 + */ + do_action( 'postman_delete_logs_successfully', $args ); + + $response = array( + 'success' => true, + 'message' => __( 'Logs deleted successfully', 'post-smtp' ), + 'deleted_all' => $deleted_all + ); + + } + else { + + $response = array( + 'success' => false, + 'message' => __( 'Error deleting logs', 'post-smtp' ), + 'deleted_all' => $deleted_all + ); + + } + + wp_send_json( $response ); + + } + + } + + + /** + * Export Logs | AJAX callback + * + * @since 2.5.0 + * @version 1.0.0 + */ + public function export_log_ajax() { + + if( !wp_verify_nonce( $_POST['security'], 'security' ) ) { + + return; + + } + + // Check if user has permission to export email logs + if ( ! current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ) ) { + wp_send_json_error( __( 'Sorry, you are not allowed to export email logs.', 'post-smtp' ) ); + return; + } + + if( isset( $_POST['action'] ) && $_POST['action'] == 'ps-export-email-logs' ) { + + $args = array(); + + //Export all + if( !isset( $_POST['selected'] ) ) { + + $args = array( -1 ); + + } + //Export selected + else { + + $args = wp_parse_id_list( $_POST['selected'] ); + + } + + $email_query_log = new PostmanEmailQueryLog(); + $logs = $email_query_log->get_all_logs( $args ); + $csv_headers = array( + 'solution', + 'response', + 'from_header', + 'to_header', + 'cc_header', + 'bcc_header', + 'reply_to_header', + 'transport_uri', + 'original_to', + 'original_subject', + 'original_message', + 'original_headers', + 'session_transcript', + 'delivery_time' + ); + + header('Content-Type: text/csv'); + header('Content-Disposition: attachment; filename="email-logs.csv"'); + + $fp = fopen('php://output', 'wb'); + + $headers = $csv_headers; + + fputcsv($fp, $headers); + + $date_format = get_option( 'date_format' ); + $time_format = get_option( 'time_format' ); + + foreach ( $logs as $log ) { + + $data[0] = $log->solution; + $data[1] = $log->success == 1 ? 'Sent' : $log->success; + $data[2] = $log->from_header; + $data[3] = $log->to_header; + $data[4] = $log->cc_header; + $data[5] = $log->bcc_header; + $data[6] = $log->reply_to_header; + $data[7] = $log->transport_uri; + $data[8] = $log->original_to; + $data[9] = $log->original_subject; + $data[10] = $log->original_message; + $data[11] = $log->original_headers; + $data[12] = $log->session_transcript; + $data[13] = date( "$date_format $time_format", $log->time ); + + fputcsv($fp, $data); + + } + + fclose($fp); + + exit(); + + } + + } + + + /** + * View Log | AJAX callback + * + * @since 2.5.0 + * @version 1.0.0 + */ + public function view_log_ajax() { + + if( !wp_verify_nonce( $_POST['security'], 'security' ) ) { + + return; + + } + + // Check if user has permission to view email logs + if ( ! current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ) ) { + wp_send_json_error( __( 'Sorry, you are not allowed to view email logs.', 'post-smtp' ) ); + return; + } + + if( isset( $_POST['action'] ) && $_POST['action'] == 'ps-view-log' ) { + + $id = sanitize_text_field( $_POST['id'] ); + $type = array( sanitize_text_field( $_POST['type'] ) ); + $type = $type[0] == 'original_message' ? '' : $type; + + $email_query_log = new PostmanEmailQueryLog(); + $log = $email_query_log->get_log( $id, $type ); + $_log = $log; + + //Escape HTML + foreach( $_log as $key => $value ) { + + if( $key == 'original_message') { + + $log['log_url'] = admin_url( "admin.php?page=postman_email_log&view=log&log_id={$id}" ); + + } + else { + + $log[$key] = esc_html( $value ); + + } + + } + + if( isset( $log['time'] ) ) { + + //WordPress Date, Time Format + $date_format = get_option( 'date_format' ); + $time_format = get_option( 'time_format' ); + + $log['time'] = date( "{$date_format} {$time_format}", $log['time'] ); + + } + + if( $log ) { + + /** + * Fires before viewing logs + * + * @param array $log + * @param string $type + * @since 2.5.9 + * @version 1.0.0 + */ + $log = apply_filters( 'post_smtp_before_view_log', $log, $type ); + + $response = array( + 'success' => true, + 'data' => $log, + ); + + } + else { + + $response = array( + 'success' => false, + 'message' => __( 'Error Viewing', 'post-smtp' ) + ); + + } + + wp_send_json( $response ); + + } + + } + + + /** + * Resend Email | AJAX callback + * + * @since 2.5.0 + * @version 1.0.0 + */ + public function resend_email() { + + if( !wp_verify_nonce( $_POST['security'], 'security' ) ) { + + return; + + } + + // Check if user has permission to resend emails + if ( ! current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ) ) { + wp_send_json_error( __( 'Sorry, you are not allowed to resend emails.', 'post-smtp' ) ); + return; + } + + if( isset( $_POST['action'] ) && $_POST['action'] == 'ps-resend-email' ) { + + $id = intval( $_POST['id'] ); + $response = ''; + $email_query_log = new PostmanEmailQueryLog(); + $log = $email_query_log->get_log( $id ); + $to = ''; + $headers = ''; + + if( $log ) { + + if( isset( $_POST['to'] ) ) { + + $emails = explode( ',', $_POST['to'] ); + $to = array_map( 'sanitize_email', $emails ); + + } + else { + + $to = $log['original_to']; + + } + + if( $log['original_headers'] ){ + + $headers = is_serialized( $log['original_headers'] ) ? unserialize( $log['original_headers'] ) : $log['original_headers']; + + } + + /** + * Fires before resending email + * + * @param array attachments + * @since 2.5.9 + * @version 1.0.0 + */ + $attachments = apply_filters( 'post_smtp_resend_attachments', array(), $id ); + + $success = wp_mail( $to, $log['original_subject'], $log['original_message'], $headers, $attachments ); + + // Postman API: retrieve the result of sending this message from Postman + $result = apply_filters( 'postman_wp_mail_result', null ); + $transcript = $result ['transcript']; + + // post-handling + if ( $success ) { + + $this->logger->debug( 'Email was successfully re-sent' ); + // the message was sent successfully, generate an appropriate message for the user + $statusMessage = sprintf( __( 'Your message was delivered (%d ms) to the SMTP server! Congratulations :)', 'post-smtp' ), $result ['time'] ); + + // compose the JSON response for the caller + $response = array( + 'success' => true, + 'message' => $statusMessage, + 'transcript' => $transcript, + ); + $this->logger->trace( 'AJAX response' ); + $this->logger->trace( $response ); + + } + else { + + $this->logger->error( 'Email was not successfully re-sent - ' . $result ['exception']->getCode() ); + // the message was NOT sent successfully, generate an appropriate message for the user + $statusMessage = $result ['exception']->getMessage(); + + // compose the JSON response for the caller + $response = array( + 'message' => $statusMessage, + 'transcript' => $transcript, + ); + $this->logger->trace( 'AJAX response' ); + $this->logger->trace( $response ); + + } + + } + else { + + $response = array( + 'success' => false, + 'message' => __( 'Error Resending Email', 'post-smtp' ) + ); + + } + + wp_send_json( $response ); + + } + + } + + + /** + * Drop Tables + * + * @since 2.5.2 + * @version 1.0.0 + */ + public function uninstall_tables() { + + $sql = "DROP TABLE IF EXISTS `{$this->db->prefix}{$this->db_name}`;"; + $response = $this->db->query( $sql ); + + if( !$this->db->last_error ) { + + $sql = "DROP TABLE IF EXISTS `{$this->db->prefix}{$this->meta_table}`;"; + $response = $this->db->query( $sql ); + + } + + if( !$this->db->last_error ) { + + delete_option( 'postman_db_version' ); + + return true; + + } + + return false; + + } + +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanInputSanitizer.php b/html/wp-content/plugins/post-smtp/Postman/PostmanInputSanitizer.php new file mode 100644 index 0000000..d687ec1 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanInputSanitizer.php @@ -0,0 +1,237 @@ +logger = new PostmanLogger( get_class( $this ) ); + $this->options = PostmanOptions::getInstance(); + } + + /** + * Sanitize each setting field as needed + * + * @param array $input + * Contains all settings fields as array keys + */ + public function sanitize( $input ) { + + if ( array_key_exists( 'external_option', $input ) ) { + return $input; + } + + $this->logger->debug( 'Sanitizing data before storage' ); + + $new_input = array(); + $success = true; + + $this->sanitizeString( 'Encryption Type', PostmanOptions::SECURITY_TYPE, $input, $new_input ); + $this->sanitizeString( 'Hostname', PostmanOptions::HOSTNAME, $input, $new_input ); + if ( ! empty( $input [ PostmanOptions::PORT ] ) ) { + $port = absint( $input [ PostmanOptions::PORT ] ); + if ( $port > 0 ) { + $this->sanitizeInt( 'Port', PostmanOptions::PORT, $input, $new_input ); + } else { + $new_input [ PostmanOptions::PORT ] = $this->options->getPort(); + add_settings_error( PostmanOptions::PORT, PostmanOptions::PORT, 'Invalid TCP Port', 'error' ); + $success = false; + } + } + // check the auth type AFTER the hostname because we reset the hostname if auth is bad + $this->sanitizeString( 'From Email', PostmanOptions::MESSAGE_SENDER_EMAIL, $input, $new_input ); + // the wizard doesn't set an envelope sender, so we'll default it to From Email + $new_input [ PostmanOptions::ENVELOPE_SENDER ] = $new_input [ PostmanOptions::MESSAGE_SENDER_EMAIL ]; + $this->sanitizeString( 'Sender Email', PostmanOptions::ENVELOPE_SENDER, $input, $new_input ); + $this->sanitizeString( 'Transport Type', PostmanOptions::TRANSPORT_TYPE, $input, $new_input ); + $this->sanitizeString( 'SMTP Mailers', 'smtp_mailers', $input, $new_input ); + $this->sanitizeString( 'Authorization Type', PostmanOptions::AUTHENTICATION_TYPE, $input, $new_input ); + $this->sanitizeString( 'From Name', PostmanOptions::MESSAGE_SENDER_NAME, $input, $new_input ); + $this->sanitizeString( 'Client ID', PostmanOptions::CLIENT_ID, $input, $new_input ); + $this->sanitizeString( 'Client Secret', PostmanOptions::CLIENT_SECRET, $input, $new_input ); + $this->sanitizeString( 'Username', PostmanOptions::BASIC_AUTH_USERNAME, $input, $new_input ); + $this->sanitizeString( 'SendGrid Region', PostmanOptions::SENDGRID_REGION, $input, $new_input, $this->options->getSendGridRegion() ); + $this->sanitizePassword( 'Password', PostmanOptions::BASIC_AUTH_PASSWORD, $input, $new_input, $this->options->getPassword() ); + $this->sanitizePassword( 'Mandrill API Key', PostmanOptions::MANDRILL_API_KEY, $input, $new_input, $this->options->getMandrillApiKey() ); + $this->sanitizePassword( 'SendGrid API Key', PostmanOptions::SENDGRID_API_KEY, $input, $new_input, $this->options->getSendGridApiKey() ); + $this->sanitizePassword( 'Resend API Key', PostmanOptions::RESEND_API_KEY, $input, $new_input, $this->options->getResendApiKey() ); + $this->sanitizePassword( 'Emailit API Key', PostmanOptions::EMAILIT_API_KEY, $input, $new_input, $this->options->getEmailitApiKey() ); + $this->sanitizePassword( 'Maileroo API Key', PostmanOptions::MAILEROO_API_KEY, $input, $new_input, $this->options->getMailerooApiKey() ); + $this->sanitizePassword( 'Mailtrap API Key', PostmanOptions::MAILTRAP_API_KEY, $input, $new_input, $this->options->getMailtrapApiKey() ); + $this->sanitizePassword( 'Sweego API Key', PostmanOptions::SWEEGO_API_KEY, $input, $new_input, $this->options->getSweegoApiKey() ); + $this->sanitizePassword( 'MailerSend API Key', PostmanOptions::MAILERSEND_API_KEY, $input, $new_input, $this->options->getMailerSendApiKey() ); + $this->sanitizePassword( 'Brevo API Key', PostmanOptions::SENDINBLUE_API_KEY, $input, $new_input, $this->options->getSendinblueApiKey() ); + $this->sanitizePassword( 'Mailjet API Key', PostmanOptions::MAILJET_API_KEY, $input, $new_input, $this->options->getMailjetApiKey() ); + $this->sanitizePassword( 'Mailjet Secret Key', PostmanOptions::MAILJET_SECRET_KEY, $input, $new_input, $this->options->getMailjetSecretKey() ); + $this->sanitizePassword( 'Sendpulse API Key', PostmanOptions::SENDPULSE_API_KEY, $input, $new_input, $this->options->getSendpulseApiKey() ); + $this->sanitizePassword( 'Sendpulse Secret Key', PostmanOptions::SENDPULSE_SECRET_KEY, $input, $new_input, $this->options->getSendpulseSecretKey() ); + $this->sanitizePassword( 'Postmark API Key', PostmanOptions::POSTMARK_API_KEY, $input, $new_input, $this->options->getPostmarkApiKey() ); + $this->sanitizePassword( 'SparkPost API Key', PostmanOptions::SPARKPOST_API_KEY, $input, $new_input, $this->options->getSparkPostApiKey() ); + $this->sanitizePassword( 'Mailgun API Key', PostmanOptions::MAILGUN_API_KEY, $input, $new_input, $this->options->getMailgunApiKey() ); + $this->sanitizePassword( 'ElasticEmail API Key', PostmanOptions::ELASTICEMAIL_API_KEY, $input, $new_input, $this->options->getElasticEmailApiKey() ); + $this->sanitizePassword( 'Smtp2go Api Key', PostmanOptions::SMTP2GO_API_KEY, $input, $new_input, $this->options->getSmtp2goApiKey() ); + $this->sanitizeString( 'Mailgun Domain Name', PostmanOptions::MAILGUN_DOMAIN_NAME, $input, $new_input ); + $this->sanitizeString( 'Reply-To', PostmanOptions::REPLY_TO, $input, $new_input ); + $this->sanitizeString( 'From Name Override', PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE, $input, $new_input ); + $this->sanitizeString( 'From Email Override', PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE, $input, $new_input ); + $this->sanitizeString( 'Disable Email Validation', PostmanOptions::DISABLE_EMAIL_VALIDAITON, $input, $new_input ); + $this->sanitizeString( 'Mailgun Europe Region', PostmanOptions::MAILGUN_REGION, $input, $new_input ); + $this->sanitizeString( 'Forced To Recipients', PostmanOptions::FORCED_TO_RECIPIENTS, $input, $new_input ); + $this->sanitizeString( 'Forced CC Recipients', PostmanOptions::FORCED_CC_RECIPIENTS, $input, $new_input ); + $this->sanitizeString( 'Forced BCC Recipients', PostmanOptions::FORCED_BCC_RECIPIENTS, $input, $new_input ); + $this->sanitizeTextarea( 'Additional Headers', PostmanOptions::ADDITIONAL_HEADERS, $input, $new_input ); + $this->sanitizeInt( 'Read Timeout', PostmanOptions::READ_TIMEOUT, $input, $new_input ); + $this->sanitizeInt( 'Conenction Timeout', PostmanOptions::CONNECTION_TIMEOUT, $input, $new_input ); + $this->sanitizeInt( 'Log Level', PostmanOptions::LOG_LEVEL, $input, $new_input ); + $this->sanitizeString( 'Email Log Enabled', PostmanOptions::MAIL_LOG_ENABLED_OPTION, $input, $new_input ); + $this->sanitizeLogMax( 'Email Log Max Entries', PostmanOptions::MAIL_LOG_MAX_ENTRIES, $input, $new_input ); + $this->sanitizeString( 'Run Mode', PostmanOptions::RUN_MODE, $input, $new_input ); + $this->sanitizeString( 'Stealth Mode', PostmanOptions::STEALTH_MODE, $input, $new_input ); + $this->sanitizeString( 'Broken Email Fix', PostmanOptions::INCOMPATIBLE_PHP_VERSION, $input, $new_input ); + $this->sanitizeInt( 'Transcript Size', PostmanOptions::TRANSCRIPT_SIZE, $input, $new_input ); + $this->sanitizeString( 'Temporary Directory', PostmanOptions::TEMPORARY_DIRECTORY, $input, $new_input ); + + // Fallback + $this->sanitizeString( 'Use fallback', PostmanOptions::FALLBACK_SMTP_ENABLED, $input, $new_input ); + $this->sanitizeString( 'Fallback hostname', PostmanOptions::FALLBACK_SMTP_HOSTNAME, $input, $new_input ); + $this->sanitizeInt( 'Fallback port', PostmanOptions::FALLBACK_SMTP_PORT, $input, $new_input ); + $this->sanitizeString( 'Fallback security', PostmanOptions::FALLBACK_SMTP_SECURITY, $input, $new_input ); + $this->sanitizeString( 'Fallback auth', PostmanOptions::FALLBACK_SMTP_USE_AUTH, $input, $new_input ); + $this->sanitizeString( 'Fallback username', PostmanOptions::FALLBACK_FROM_EMAIL, $input, $new_input ); + $this->sanitizeString( 'Fallback username', PostmanOptions::FALLBACK_SMTP_USERNAME, $input, $new_input ); + $this->sanitizePassword( 'Fallback password', PostmanOptions::FALLBACK_SMTP_PASSWORD, $input, $new_input, $this->options->getFallbackPassword() ); + + $new_input = apply_filters( 'post_smtp_sanitize', $new_input, $input, $this ); + delete_transient( 'sendpulse_token' ); + + if ( $new_input [ PostmanOptions::CLIENT_ID ] != $this->options->getClientId() || $new_input [ PostmanOptions::CLIENT_SECRET ] != $this->options->getClientSecret() || $new_input [ PostmanOptions::HOSTNAME ] != $this->options->getHostname() ) { + $this->logger->debug( 'Recognized new Client ID' ); + // the user entered a new client id and we should destroy the stored auth token + delete_option( PostmanOAuthToken::OPTIONS_NAME ); + } + + // can we create a tmp file? - this code is duplicated in ActivationHandler + if( isset( $new_input [ PostmanOptions::TEMPORARY_DIRECTORY ] ) ) { + + PostmanUtils::deleteLockFile( $new_input [ PostmanOptions::TEMPORARY_DIRECTORY ] ); + $lockSuccess = PostmanUtils::createLockFile( $new_input [ PostmanOptions::TEMPORARY_DIRECTORY ] ); + // &= does not work as expected in my PHP + $lockSuccess = $lockSuccess && PostmanUtils::deleteLockFile( $new_input [ PostmanOptions::TEMPORARY_DIRECTORY ] ); + $this->logger->debug( 'FileLocking=' . $lockSuccess ); + PostmanState::getInstance()->setFileLockingEnabled( $lockSuccess ); + + } + + if ( $success ) { + PostmanSession::getInstance()->setAction( self::VALIDATION_SUCCESS ); + } else { + PostmanSession::getInstance()->setAction( self::VALIDATION_FAILED ); + } + + return $new_input; + } + + public function sanitizeString( $desc, $key, $input, &$new_input ) { + if ( isset( $input [ $key ] ) ) { + $this->logSanitize( $desc, $input [ $key ] ); + $new_input [ $key ] = sanitize_text_field( trim( $input [ $key ] ) ); + } + } + + public function sanitizeTextarea( $desc, $key, $input, &$new_input ) { + if ( isset( $input [ $key ] ) ) { + $this->logSanitize( $desc, $input [ $key ] ); + $new_input [ $key ] = sanitize_textarea_field( trim( $input [ $key ] ) ); + } + } + + /** + * Sanitize a Basic Auth password, and base64-encode it + * + * @param mixed $desc + * @param mixed $key + * @param mixed $input + * @param mixed $new_input + */ + public function sanitizePassword( $desc, $key, $input, &$new_input, $existingPassword ) { + + // WordPress calling Sanitize twice is a known issue + // https://core.trac.wordpress.org/ticket/21989 + $action = PostmanSession::getInstance()->getAction(); + // if $action is not empty, then sanitize has already run + if ( ! empty( $action ) ) { + // use the already encoded password in the $input + $new_input[$key] = isset( $input[$key] ) ? $input[$key] : ''; + // log it + $this->logger->debug( 'Warning, second sanitizePassword attempt detected' ); + } else if ( isset( $input [ $key ] ) ) { + if ( strlen( $input [ $key ] ) > 0 && preg_match( '/^\**$/', $input [ $key ] ) ) { + // if the password is all stars, then keep the existing password + $new_input [ $key ] = $existingPassword; + } else { + // otherwise the password is new, so trim it + $new_input [ $key ] = sanitize_text_field( trim( $input [ $key ] ) ); + } + // log it + $this->logSanitize( $desc, $new_input [ $key ] ); + // base-64 scramble password + $new_input [ $key ] = base64_encode( $new_input [ $key ] ); + + $this->logger->debug( sprintf( 'Encoding %s as %s', $desc, $new_input [ $key ] ) ); + } + } + + private function sanitizeLogMax( $desc, $key, $input, &$new_input ) { + if ( isset( $input [ $key ] ) ) { + $value = absint( $input [ $key ] ); + if ( $value <= 0 ) { + $new_input [ $key ] = PostmanOptions::getInstance()->getMailLoggingMaxEntries(); + $h = new PostmanMessageHandler(); + $h->addError( sprintf( '%s %s', __( 'Maximum Log Entries', 'post-smtp' ), __( 'must be greater than 0', 'post-smtp' ) ) ); + } else { + $this->logSanitize( $desc, $input [ $key ] ); + $new_input [ $key ] = absint($value); + } + } + } + + /** + * Sanitizes a URL field in an input array and stores the sanitized value in the output array. + * + * This function checks if the specified key exists in the input array and is not empty. + * If it does, it logs the original value for debugging or audit purposes, + * trims any leading or trailing whitespace, and sanitizes the URL. + * The sanitized URL is then stored in the output array under the specified key. + * + * @param string $desc Description or label of the field for logging purposes. + * @param string $key The key in the input array that corresponds to the URL field to be sanitized. + * @param array $input The input array containing the data to be sanitized. + * @param array &$new_input The output array where the sanitized data will be stored by reference. + * + * @return void + */ + public function sanitizeUrl( $desc, $key, $input, &$new_input ) { + if ( isset( $input[ $key ] ) && ! empty( $input[ $key ] ) ) { + // Log the sanitization process with the original value for auditing. + $this->logSanitize( $desc, $input[ $key ] ); + + // Sanitize the URL by trimming whitespace and ensuring it is in a valid URL format. + $new_input[ $key ] = esc_url_raw( trim( $input[ $key ] ) ); + } + } + + private function sanitizeInt( $desc, $key, $input, &$new_input ) { + if ( isset( $input [ $key ] ) ) { + $this->logSanitize( $desc, $input [ $key ] ); + $new_input [ $key ] = absint( $input [ $key ] ); + } + } + private function logSanitize( $desc, $value ) { + $this->logger->trace( 'Sanitize ' . $desc . ' ' . $value ); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanInstaller.php b/html/wp-content/plugins/post-smtp/Postman/PostmanInstaller.php new file mode 100644 index 0000000..1546dba --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanInstaller.php @@ -0,0 +1,315 @@ +logger = new PostmanLogger( get_class( $this ) ); + } + + /** + * Handle activation of the plugin + */ + public function activatePostman() { + + delete_option( 'postman_release_version' ); + delete_option( 'postman_dismiss_donation' ); + + $table_version = get_option( 'postman_db_version' ); + + //If no logs in _posts table + global $wpdb; + + $have_old_logs = $wpdb->get_results( + "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'postman_sent_mail' LIMIT 1;" + ); + + if( !class_exists( 'PostmanEmailLogs' ) ) { + + require 'PostmanEmailLogs.php'; + + } + + $email_logs = new PostmanEmailLogs(); + $logs_table = $wpdb->prefix . $email_logs->db_name; + $meta_table = $wpdb->prefix . $email_logs->meta_table; + // Check if the table exists + $logs_table = $wpdb->get_var( "SHOW TABLES LIKE '$logs_table'" ); + $meta_table = $wpdb->get_var( "SHOW TABLES LIKE '$meta_table'" ); + + //Lets Install New Fresh Logs Table + //Doesn't have table? but wp_options has postman_db_version + if( ( empty( $have_old_logs ) && !$table_version ) || ( !$logs_table || !$meta_table ) ) { + + $email_logs->install_table(); + + } + //Need to Update Table? + elseif( $table_version && version_compare( POST_SMTP_DB_VERSION, $table_version, '>' ) ) { + + $email_logs->update_table(); + + } + + $options = get_option( PostmanOptions::POSTMAN_OPTIONS ); + $args = array( + 'fallback_smtp_enabled' => 'no', + ); + + if ( empty( $options ) ) { + add_option( 'postman_options', $args ); + + } else { + if ( empty( $options['fallback_smtp_enabled'] ) ) { + $result = array_merge($options, $args); + update_option( PostmanOptions::POSTMAN_OPTIONS, $result ); + } + } + + if ( function_exists( 'is_multisite' ) && is_multisite() ) { + + $network_options = get_site_option( PostmanOptions::POSTMAN_NETWORK_OPTIONS ); + + if( isset( $network_options['post_smtp_global_settings']) ) { + $options['post_smtp_global_settings'] = '1'; + } + + $options['post_smtp_allow_overwrite'] = '1'; + update_site_option( PostmanOptions::POSTMAN_NETWORK_OPTIONS, $options ); + + // handle network activation + // from https://wordpress.org/support/topic/new-function-wp_get_sites?replies=11 + // run the activation function for each blog id + $old_blog = get_current_blog_id(); + // Get all blog ids + $subsites = get_sites(); + foreach ( $subsites as $subsite ) { + $this->logger->trace( 'multisite: switching to blog ' . $subsite->blog_id ); + switch_to_blog( $subsite->blog_id ); + $this->handleOptionUpdates(); + $this->addCapability(); + } + switch_to_blog( $old_blog ); + } else { + // handle single-site activation + $this->handleOptionUpdates(); + $this->addCapability(); + } + + } + + + /** + * Handle deactivation of the plugin + */ + public function deactivatePostman() { + if ( function_exists( 'is_multisite' ) && is_multisite() ) { + // handle network deactivation + // from https://wordpress.org/support/topic/new-function-wp_get_sites?replies=11 + // run the deactivation function for each blog id + $old_blog = get_current_blog_id(); + // Get all blog ids + $subsites = get_sites(); + foreach ( $subsites as $subsite ) { + $this->logger->trace( 'multisite: switching to blog ' . $subsite->blog_id ); + switch_to_blog( $subsite->blog_id ); + $this->removeCapability(); + } + switch_to_blog( $old_blog ); + } else { + // handle single-site deactivation + $this->removeCapability(); + } + } + + /** + * Add the capability to manage postman + */ + public function addCapability() { + if ( $this->logger->isDebug() ) { + $this->logger->debug( 'Adding admin capability' ); + } + // ref: https://codex.wordpress.org/Function_Reference/add_cap + // NB: This setting is saved to the database, so it might be better to run this on theme/plugin activation + // add the custom capability to the administrator role + $role = get_role( Postman::ADMINISTRATOR_ROLE_NAME ); + $role->add_cap( Postman::MANAGE_POSTMAN_CAPABILITY_NAME ); + $role->add_cap( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ); + } + + /** + * Remove the capability to manage postman + */ + public function removeCapability() { + if ( $this->logger->isDebug() ) { + $this->logger->debug( 'Removing admin capability' ); + } + // ref: https://codex.wordpress.org/Function_Reference/add_cap + // NB: This setting is saved to the database, so it might be better to run this on theme/plugin activation + // remove the custom capability from the administrator role + $role = get_role( Postman::ADMINISTRATOR_ROLE_NAME ); + $role->remove_cap( Postman::MANAGE_POSTMAN_CAPABILITY_NAME ); + $role->remove_cap( Postman::MANAGE_POSTMAN_CAPABILITY_LOGS ); + } + + /** + * Handle activation of plugin + */ + private function handleOptionUpdates() { + $this->logger->debug( 'Activating plugin' ); + // prior to version 0.2.5, $authOptions did not exist + $authOptions = get_option( 'postman_auth_token' ); + $options = get_option( 'postman_options' ); + $postmanState = get_option( 'postman_state' ); + if ( $postmanState === false ) { + $postmanState = array(); + } + if ( empty( $authOptions ) && ! (empty( $options )) && ! empty( $options ['access_token'] ) ) { + $this->logger->debug( 'Upgrading database: copying Authorization token from postman_options to postman_auth_token' ); + // copy the variables from $options to $authToken + $authOptions ['access_token'] = $options ['access_token']; + $authOptions ['refresh_token'] = $options ['refresh_token']; + // there was a bug where we weren't setting the expiry time + if ( ! empty( $options ['auth_token_expires'] ) ) { + $authOptions ['auth_token_expires'] = $options ['auth_token_expires']; + } + update_option( 'postman_auth_token', $authOptions ); + } + if ( ! isset( $options ['authorization_type'] ) && ! isset( $options ['auth_type'] ) ) { + // prior to 1.0.0, access tokens were saved in authOptions without an auth type + // prior to 0.2.5, access tokens were save in options without an auth type + // either way, only oauth2 was supported + if ( isset( $authOptions ['access_token'] ) || isset( $options ['access_token'] ) ) { + $this->logger->debug( "Upgrading database: setting authorization_type to 'oauth2'" ); + $options ['authorization_type'] = 'oauth2'; + update_option( 'postman_options', $options ); + } + } + if ( ! isset( $options ['enc_type'] ) ) { + // prior to 1.3, encryption type was combined with authentication type + if ( isset( $options ['authorization_type'] ) ) { + $this->logger->debug( 'Upgrading database: creating auth_type and enc_type from authorization_type' ); + $authType = $options ['authorization_type']; + switch ( $authType ) { + case 'none' : + $options ['auth_type'] = 'none'; + $options ['enc_type'] = 'none'; + break; + case 'basic-ssl' : + $options ['auth_type'] = 'login'; + $options ['enc_type'] = 'ssl'; + break; + case 'basic-tls' : + $options ['auth_type'] = 'login'; + $options ['enc_type'] = 'tls'; + break; + case 'oauth2' : + $options ['auth_type'] = 'oauth2'; + $options ['enc_type'] = 'ssl'; + break; + default : + } + update_option( 'postman_options', $options ); + } + } + // prior to 1.3.3, the version identifier was not stored and the passwords were plaintext + if ( isset( $options ['enc_type'] ) && ! (isset( $options ['version'] ) || isset( $postmanState ['version'] )) ) { + $this->logger->debug( 'Upgrading database: added plugin version and encoding password' ); + $options ['version'] = '1.3.3'; + if ( isset( $options ['basic_auth_password'] ) ) { + $options ['basic_auth_password'] = base64_encode( $options ['basic_auth_password'] ); + } + update_option( 'postman_options', $options ); + } + // prior to 1.4.2, the transport was not identified and the auth token had no vendor + if ( isset( $options ['auth_type'] ) && ! isset( $options ['transport_type'] ) ) { + $this->logger->debug( 'Upgrading database: added transport_type and vendor_name' ); + $options ['transport_type'] = 'smtp'; + update_option( 'postman_options', $options ); + if ( isset( $authOptions ['access_token'] ) && isset( $options ['oauth_client_id'] ) ) { + // if there is a stored token.. + if ( PostmanUtils::endsWith( $options ['oauth_client_id'], 'googleusercontent.com' ) ) { + $authOptions ['vendor_name'] = 'google'; } else if ( strlen( $options ['oauth_client_id'] < strlen( $options ['oauth_client_secret'] ) ) ) { + $authOptions ['vendor_name'] = 'microsoft'; + } else { $authOptions ['vendor_name'] = 'yahoo'; } + update_option( 'postman_auth_token', $authOptions ); + } + } + + // for version 1.6.18, the envelope from was introduced + if ( ! empty( $options ['sender_email'] ) && empty( $options ['envelope_sender'] ) ) { + $this->logger->debug( 'Upgrading database: adding envelope_sender' ); + $options ['envelope_sender'] = $options ['sender_email']; + update_option( 'postman_options', $options ); + } + + if ( isset( $postmanState ['version'] ) && version_compare( $postmanState ['version'], '1.7.0', '<' ) ) { + if ( $options ['mail_log_max_entries'] == 10 ) { + $options ['mail_log_max_entries'] = 250; + } + $postmanStats = get_option( 'postman_stats' ); + $stateCleared = false; + if ( ! isset( $postmanState ['delivery_success_total'] ) && isset( $postmanStats ['delivery_success_total'] ) ) { + $postmanState ['delivery_success_total'] = $postmanStats ['delivery_success_total']; + $stateCleared = true; + } + if ( ! isset( $postmanState ['delivery_fail_total'] ) && isset( $postmanStats ['delivery_fail_total'] ) ) { + $postmanState ['delivery_fail_total'] = $postmanStats ['delivery_fail_total']; + $stateCleared = true; + } + if ( $stateCleared ) { + delete_option( 'postman_stats' ); + } + } + + // can we create a tmp file? - this code is duplicated in InputSanitizer + PostmanUtils::deleteLockFile(); + $lockSuccess = PostmanUtils::createLockFile(); + // &= does not work as expected in my PHP + $lockSuccess = $lockSuccess && PostmanUtils::deleteLockFile(); + + if( $postmanState ) { + + $postmanState ['locking_enabled'] = $lockSuccess; + + } + + // always update the version number + if ( ! isset( $postmanState ['install_date'] ) ) { + $this->logger->debug( 'Upgrading database: adding install_date' ); + $postmanState ['install_date'] = time(); + } + $pluginData = apply_filters( 'postman_get_plugin_metadata', null ); + + if( $postmanState ) { + + $postmanState ['version'] = $pluginData ['version']; + + } + + update_option( 'postman_state', $postmanState ); + delete_option( 'postman_session' ); + + // reload options + PostmanState::getInstance()->reload(); + PostmanOptions::getInstance()->reload(); + } + +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanLogFields.php b/html/wp-content/plugins/post-smtp/Postman/PostmanLogFields.php new file mode 100644 index 0000000..5116bac --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanLogFields.php @@ -0,0 +1,160 @@ + 'sanitize_text_field', + 'solution' => [ 'PostmanLogFields', 'sanitize_message' ], + 'from_header' => [ 'PostmanLogFields', 'email_header_sanitize' ], + 'to_header' => [ 'PostmanLogFields', 'email_header_sanitize' ], + 'cc_header' => [ 'PostmanLogFields', 'email_header_sanitize' ], + 'bcc_header' => [ 'PostmanLogFields', 'email_header_sanitize' ], + 'reply_to_header' => [ 'PostmanLogFields', 'email_header_sanitize' ], + 'transport_uri' => 'sanitize_text_field', + 'original_to' => 'sanitize_text_field', + 'original_subject' => 'sanitize_text_field', + 'original_message' => '', // only sent to viewed + 'original_headers' => '', // only sent to viewed + 'session_transcript' => '', // escaped when viewed + ); + + /** + * Exclude from Getting and Setting in JSON fromat + * + * @since 2.1 + */ + private $exclude_json = array( + 'original_headers' + ); + + private static $instance = null; + + public static function get_instance() { + if ( ! self::$instance ) { + self::$instance = new static(); + } + + return self::$instance; + } + + private function __construct() + { + + } + + public function get( $post_id ) { + $data = []; + foreach ( $this->fields as $key => $sanitize_callback ) { + + $meta = get_post_meta( $post_id, $key, true ); + + if( in_array( $key, $this->exclude_json ) ) + $data[$key][] = $meta; + else + $data[$key][] = $this->maybe_json( $meta ); + + } + + return $data; + } + + public function get_fields() { + return $this->fields; + } + + /** + * Update log entry + * + * @since 2.1 removed `$this->encode()` was breaking data + */ + public function update( $post_id, $key, $value ) { + + if( in_array( $key, $this->exclude_json ) ) + $sanitized = $value; + else + $sanitized = $this->sanitize( $key, $value ); + + update_post_meta( $post_id, $key, $sanitized ); + + } + + /** + * If json return decoded json + * + * @since 2.1 removed json_decode and maybe_serialize + */ + private function maybe_json( $json ) { + + if ( is_array( $json ) ) { + return implode( ',', $json ); + } + + return $json; + } + + private function sanitize( $key, $value ) { + + $callback = is_array( $value ) ? 'array_map' : 'call_user_func'; + + if ( ! empty( $this->fields[$key] ) ) { + return $callback( $this->fields[$key], $value ); + } + + return $value; + } + + private function sanitize_message( $message ) { + $allowed_tags = wp_kses_allowed_html( 'post' ); + $allowed_tags['style'] = array(); + + return wp_kses( $message, $allowed_tags ); + } + + private function sanitize_html( $value ) { + $allowed_html = array( + 'a' => array( + 'href' => array(), + ), + 'br' => array(), + ); + + return wp_kses( $value, $allowed_html ); + } + + public function get_string_between($string, $start, $end){ + $string = ' ' . $string; + $ini = strpos($string, $start); + + if ($ini == 0) { + return ''; + } + + $ini += strlen($start); + $len = strpos($string, $end, $ini) - $ini; + + return substr($string, $ini, $len); + } + + public function email_header_sanitize($value) { + + $parts = explode( ',', $value ); + + $sanitized = []; + foreach ( $parts as $part ) { + + if ( strpos( $part, '<' ) !== false ) { + $email = $this->get_string_between( $part, '<', '>' ); + $clean_email = $this->sanitize_email($email); + preg_match('/(.*)"; + } + } + + return ! empty( $sanitized ) ? implode( ',', $sanitized ) : implode( ',', array_map( [ $this, 'sanitize_email'], $parts ) ); + } + + public function sanitize_email( $email ) { + return filter_var( $email, FILTER_SANITIZE_EMAIL ); + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanLogger.php b/html/wp-content/plugins/post-smtp/Postman/PostmanLogger.php new file mode 100644 index 0000000..5454c60 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanLogger.php @@ -0,0 +1,73 @@ +name = $name; + $this->wpDebug = defined ( 'WP_DEBUG' ); + if (class_exists ( 'PostmanOptions' )) { + $this->logLevel = PostmanOptions::getInstance ()->getLogLevel (); + } else { + $this->logLevel = self::OFF_INT; + } + } + function trace($text) { + $this->printLog ( $text, self::TRACE_INT, 'TRACE' ); + } + function debug($text) { + $this->printLog ( $text, self::DEBUG_INT, 'DEBUG' ); + } + function info($text) { + $this->printLog ( $text, self::INFO_INT, 'INFO' ); + } + function warn($text) { + $this->printLog ( $text, self::WARN_INT, 'WARN' ); + } + function error($text) { + $this->printLog ( $text, self::ERROR_INT, 'ERROR' ); + } + function fatal($text) { + $this->printLog ( $text, self::FATAL_INT, 'FATAL' ); + } + /** + * better logging thanks to http://www.smashingmagazine.com/2011/03/08/ten-things-every-wordpress-plugin-developer-should-know/ + * + * @param mixed $intLogLevel + * @param mixed $logLevelName + */ + private function printLog($text, $intLogLevel, $logLevelName) { + if ($this->wpDebug && $intLogLevel >= $this->logLevel) { + if (is_array ( $text ) || is_object ( $text )) { + error_log ( $logLevelName . ' ' . $this->name . ': ' . print_r ( $text, true ) ); + } else { + error_log ( $logLevelName . ' ' . $this->name . ': ' . $text ); + } + } + } + public function isDebug() { + return self::DEBUG_INT >= $this->logLevel; + } + public function isTrace() { + return self::TRACE_INT >= $this->logLevel; + } + public function isInfo() { + return self::INFO_INT >= $this->logLevel; + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanMessageHandler.php b/html/wp-content/plugins/post-smtp/Postman/PostmanMessageHandler.php new file mode 100644 index 0000000..cd9220d --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanMessageHandler.php @@ -0,0 +1,115 @@ +logger = new PostmanLogger ( get_class ( $this ) ); + + // we'll let the 'init' functions run first; some of them may end the request + add_action ( 'admin_notices', Array ( + $this, + 'displayAllMessages' + ) ); + } + + /** + * + * @param mixed $message + */ + public function addError($message) { + $this->storeMessage ( $message, 'error' ); + } + /** + * + * @param mixed $message + */ + public function addWarning($message) { + $this->storeMessage ( $message, 'warning' ); + } + /** + * + * @param mixed $message + */ + public function addMessage($message) { + $this->storeMessage ( $message, 'notify' ); + } + + /** + * store messages for display later + * + * @param mixed $message + * @param mixed $type + */ + private function storeMessage($message, $type) { + $messageArray = array (); + $oldMessageArray = PostmanSession::getInstance ()->getMessage (); + if ($oldMessageArray) { + $messageArray = $oldMessageArray; + } + $weGotIt = false; + foreach ( $messageArray as $storedMessage ) { + if ($storedMessage ['message'] === $message) { + $weGotIt = true; + } + } + if (! $weGotIt) { + $m = array ( + 'type' => $type, + 'message' => $message + ); + array_push ( $messageArray, $m ); + PostmanSession::getInstance ()->setMessage ( $messageArray ); + } + } + /** + * Retrieve the messages and show them + */ + public function displayAllMessages() { + $messageArray = PostmanSession::getInstance ()->getMessage (); + if ($messageArray) { + PostmanSession::getInstance ()->unsetMessage (); + foreach ( $messageArray as $m ) { + $type = $m ['type']; + switch ($type) { + case 'error' : + $className = self::ERROR_CLASS; + break; + case 'warning' : + $className = self::WARNING_CLASS; + break; + default : + $className = self::SUCCESS_CLASS; + break; + } + $message = $m ['message']; + $this->printMessage ( $message, $className ); + } + } + } + + /** + * putput message + * + * @param mixed $message + * @param mixed $className + */ + public function printMessage($message, $className) { + printf ( '

        %s

        ', $className, $message ); + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanOAuthToken.php b/html/wp-content/plugins/post-smtp/Postman/PostmanOAuthToken.php new file mode 100644 index 0000000..81efbfe --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanOAuthToken.php @@ -0,0 +1,105 @@ +load (); + } + + /** + * Is there a valid access token and refresh token + */ + public function isValid() { + $accessToken = $this->getAccessToken (); + $refreshToken = $this->getRefreshToken (); + return ! (empty ( $accessToken ) || empty ( $refreshToken )); + } + + /** + * Load the Postman OAuth token properties to the database + */ + private function load() { + $a = get_option ( PostmanOAuthToken::OPTIONS_NAME ); + + if ( ! is_array( $a ) ) { + return; + } + + if ( isset( $a [PostmanOAuthToken::ACCESS_TOKEN] ) ) { + $this->setAccessToken ( $a [PostmanOAuthToken::ACCESS_TOKEN] ); + } + + if ( isset( $a [PostmanOAuthToken::REFRESH_TOKEN] ) ) { + $this->setRefreshToken($a [PostmanOAuthToken::REFRESH_TOKEN]); + } + + if ( isset( $a [PostmanOAuthToken::EXPIRY_TIME] ) ) { + $this->setExpiryTime($a [PostmanOAuthToken::EXPIRY_TIME]); + } + + if ( isset( $a [PostmanOAuthToken::VENDOR_NAME] ) ) { + $this->setVendorName($a [PostmanOAuthToken::VENDOR_NAME]); + } + } + + /** + * Save the Postman OAuth token properties to the database + */ + public function save() { + $a [PostmanOAuthToken::ACCESS_TOKEN] = $this->getAccessToken (); + $a [PostmanOAuthToken::REFRESH_TOKEN] = $this->getRefreshToken (); + $a [PostmanOAuthToken::EXPIRY_TIME] = $this->getExpiryTime (); + $a [PostmanOAuthToken::VENDOR_NAME] = $this->getVendorName (); + update_option ( PostmanOAuthToken::OPTIONS_NAME, $a ); + } + public function getVendorName() { + return $this->vendorName; + } + public function getExpiryTime() { + return $this->expiryTime; + } + public function getAccessToken() { + return $this->accessToken; + } + public function getRefreshToken() { + return $this->refreshToken; + } + public function setVendorName($name) { + $this->vendorName = sanitize_text_field ( $name ); + } + public function setExpiryTime($time) { + $this->expiryTime = sanitize_text_field ( $time ); + } + public function setAccessToken($token) { + $this->accessToken = sanitize_text_field ( $token ); + } + public function setRefreshToken($token) { + $this->refreshToken = sanitize_text_field ( $token ); + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanOptions.php b/html/wp-content/plugins/post-smtp/Postman/PostmanOptions.php new file mode 100644 index 0000000..8666103 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanOptions.php @@ -0,0 +1,993 @@ + 'PHPMailer', + 'postsmtp' => 'PostSMTP' + ]; + + public $is_fallback = false; + + // options data + private $options; + + // singleton instance + public static function getInstance() { + static $inst = null; + if ( $inst === null ) { + $inst = new PostmanOptions(); + } + return $inst; + } + + /** + * private constructor + */ + private function __construct() { + $this->load(); + } + + public function save() { + update_option( PostmanOptions::POSTMAN_OPTIONS, $this->options ); + } + + public function reload() { + $this->load(); + } + + public function load() { + + $options = get_option( self::POSTMAN_OPTIONS ); + + if ( is_multisite() ) { + $network_options = get_site_option( self::POSTMAN_NETWORK_OPTIONS ); + + $blog_id = get_current_blog_id(); + if ( isset( $network_options['post_smtp_global_settings'] ) ) { + $blog_id = apply_filters( 'post_smtp_default_site_option', 1 ); + } + + switch_to_blog($blog_id); + $options = get_option( self::POSTMAN_OPTIONS ); + restore_current_blog(); + } + + $this->options = $options; + } + + public function isNew() { + return ! isset( $this->options [ PostmanOptions::TRANSPORT_TYPE ] ); + } + public function isMailLoggingEnabled() { + if ( defined( 'POST_SMTP_CORE_MAIL_LOG' ) ) { + return POST_SMTP_CORE_MAIL_LOG; + } + + $allowed = $this->isMailLoggingAllowed(); + $enabled = $this->getMailLoggingEnabled() == self::MAIL_LOG_ENABLED_OPTION_YES; + return $allowed && $enabled; + } + public function getTempDirectory() { + if ( isset( $this->options [ self::TEMPORARY_DIRECTORY ] ) ) { + return $this->options [ self::TEMPORARY_DIRECTORY ]; + } else { return self::DEFAULT_TEMP_DIRECTORY; } + } + public function isMailLoggingAllowed() { + return true; + } + public function isStealthModeEnabled() { + if ( isset( $this->options [ PostmanOptions::STEALTH_MODE ] ) ) { + return $this->options [ PostmanOptions::STEALTH_MODE ]; + } else { return self::DEFAULT_STEALTH_MODE; } + } + public function getMailLoggingEnabled() { + if ( isset( $this->options [ PostmanOptions::MAIL_LOG_ENABLED_OPTION ] ) ) { + return $this->options [ PostmanOptions::MAIL_LOG_ENABLED_OPTION ]; + } else { + return self::DEFAULT_MAIL_LOG_ENABLED; + } + } + public function getRunMode() { + if ( defined( 'POST_SMTP_RUN_MODE' ) ) { + return POST_SMTP_RUN_MODE; + } + + if ( isset( $this->options [ self::RUN_MODE ] ) ) { + return $this->options [ self::RUN_MODE ]; + } else { return self::DEFAULT_RUN_MODE; } + } + public function getMailLoggingMaxEntries() { + if ( isset( $this->options [ PostmanOptions::MAIL_LOG_MAX_ENTRIES ] ) ) { + return $this->options [ PostmanOptions::MAIL_LOG_MAX_ENTRIES ]; + } else { return self::DEFAULT_MAIL_LOG_ENTRIES; } + } + public function getTranscriptSize() { + if ( isset( $this->options [ PostmanOptions::TRANSCRIPT_SIZE ] ) ) { + return $this->options [ PostmanOptions::TRANSCRIPT_SIZE ]; + } else { return self::DEFAULT_TRANSCRIPT_SIZE; } + } + + public function getLogLevel() { + if ( isset( $this->options [ PostmanOptions::LOG_LEVEL ] ) ) { + return $this->options [ PostmanOptions::LOG_LEVEL ]; + } else { return self::DEFAULT_LOG_LEVEL; } + } + + + public function getForcedToRecipients() { + if ( isset( $this->options [ self::FORCED_TO_RECIPIENTS ] ) ) { + return $this->options [ self::FORCED_TO_RECIPIENTS ]; } + } + public function getForcedCcRecipients() { + if ( isset( $this->options [ self::FORCED_CC_RECIPIENTS ] ) ) { + return $this->options [ self::FORCED_CC_RECIPIENTS ]; } + } + public function getForcedBccRecipients() { + if ( isset( $this->options [ self::FORCED_BCC_RECIPIENTS ] ) ) { + return $this->options [ self::FORCED_BCC_RECIPIENTS ]; } + } + public function getAdditionalHeaders() { + if ( isset( $this->options [ self::ADDITIONAL_HEADERS ] ) ) { + return $this->options [ self::ADDITIONAL_HEADERS ]; } + } + public function getHostname() { + + if ( $this->is_fallback ) { + return $this->getFallbackHostname(); + } + + if ( isset( $this->options [ PostmanOptions::HOSTNAME ] ) ) { + return $this->options [ PostmanOptions::HOSTNAME ]; } + } + + public function getPort() { + + if ( $this->is_fallback ) { + return $this->getFallbackPort(); + } + + if ( isset( $this->options [ PostmanOptions::PORT ] ) ) { + return $this->options [ PostmanOptions::PORT ]; } + } + + public function getEnvelopeSender() { + + if ( $this->is_fallback ) { + return $this->getFallbackFromEmail(); + } + + if ( isset( $this->options [ PostmanOptions::ENVELOPE_SENDER ] ) ) { + return $this->options [ PostmanOptions::ENVELOPE_SENDER ]; } + } + + public function getMessageSenderEmail() { + + if ( $this->is_fallback ) { + return $this->getFallbackFromEmail(); + } + + if ( isset( $this->options [ PostmanOptions::MESSAGE_SENDER_EMAIL ] ) ) { + + /** + * Filters the From Email Address | This address, like the letterhead printed on a letter, identifies the sender to the recipient. Change this when you are sending on behalf of someone else, for example to use Google's Send Mail As feature. Other plugins, especially Contact Forms, may override this field to be your visitor's address. + * + * @since 2.5.0 + * @version 1.0.0 + */ + return apply_filters( 'post_smtp_from_email_address', $this->options[PostmanOptions::MESSAGE_SENDER_EMAIL] ); + + } + } + + public function getFallbackFromEmail() { + if ( isset( $this->options [ PostmanOptions::FALLBACK_FROM_EMAIL ] ) ) { + return $this->options [ PostmanOptions::FALLBACK_FROM_EMAIL ]; } + } + + public function getMessageSenderName() { + if ( isset( $this->options [ PostmanOptions::MESSAGE_SENDER_NAME ] ) ) { + + /** + * Filters the From Name + * + * @since 2.5.0 + * @version 1.0.0 + */ + return apply_filters( 'post_smtp_from_name', $this->options[PostmanOptions::MESSAGE_SENDER_NAME] ); + + } + } + public function getClientId() { + if ( isset( $this->options [ PostmanOptions::CLIENT_ID ] ) ) { + return $this->options [ PostmanOptions::CLIENT_ID ]; } + } + public function getClientSecret() { + if ( isset( $this->options [ PostmanOptions::CLIENT_SECRET ] ) ) { + return $this->options [ PostmanOptions::CLIENT_SECRET ]; } + } + + public function getTransportType() { + + if ( $this->is_fallback ) { + return 'smtp'; + } + + if ( isset( $this->options [ PostmanOptions::TRANSPORT_TYPE ] ) ) { + return $this->options [ PostmanOptions::TRANSPORT_TYPE ]; } + } + + public function getAuthenticationType() { + + if ( $this->is_fallback ) { + return $this->getFallbackAuth(); + } + + if ( isset( $this->options [ PostmanOptions::AUTHENTICATION_TYPE ] ) ) { + return $this->options [ PostmanOptions::AUTHENTICATION_TYPE ]; } + } + + public function getEncryptionType() { + + if ( $this->is_fallback ) { + return $this->getFallbackSecurity(); + } + + + if ( isset( $this->options [ PostmanOptions::SECURITY_TYPE ] ) ) { + return $this->options [ PostmanOptions::SECURITY_TYPE ]; + } + } + + public function getUsername() { + + if ( $this->is_fallback ) { + return $this->getFallbackUsername(); + } + + if ( defined( 'POST_SMTP_AUTH_USERNAME' ) ) { + return POST_SMTP_AUTH_USERNAME; + } + + if ( isset( $this->options [ PostmanOptions::BASIC_AUTH_USERNAME ] ) ) { + return $this->options [ PostmanOptions::BASIC_AUTH_USERNAME ]; + } + } + + public function getPassword() { + + if ( $this->is_fallback ) { + return $this->getFallbackPassword(); + } + + if ( defined( 'POST_SMTP_AUTH_PASSWORD' ) ) { + return POST_SMTP_AUTH_PASSWORD; + } + + if ( isset( $this->options [ PostmanOptions::BASIC_AUTH_PASSWORD ] ) ) { + return base64_decode( $this->options [ PostmanOptions::BASIC_AUTH_PASSWORD ] ); + } + } + + // Fallback + public function getFallbackIsEnabled() { + if ( isset( $this->options [ PostmanOptions::FALLBACK_SMTP_ENABLED ] ) ) { + return $this->options [ PostmanOptions::FALLBACK_SMTP_ENABLED ]; + } + return false; + } + + public function getFallbackHostname() { + if ( isset( $this->options [ PostmanOptions::FALLBACK_SMTP_HOSTNAME ] ) ) { + return $this->options [ PostmanOptions::FALLBACK_SMTP_HOSTNAME ]; + } + } + + public function getFallbackPort() { + if ( isset( $this->options [ PostmanOptions::FALLBACK_SMTP_PORT ] ) ) { + return $this->options [ PostmanOptions::FALLBACK_SMTP_PORT ]; + } + } + + public function getFallbackSecurity() { + if ( isset( $this->options [ PostmanOptions::FALLBACK_SMTP_SECURITY ] ) ) { + return $this->options [ PostmanOptions::FALLBACK_SMTP_SECURITY ]; + } + } + + public function getFallbackAuth() { + if ( isset( $this->options [ PostmanOptions::FALLBACK_SMTP_USE_AUTH ] ) ) { + return $this->options [ PostmanOptions::FALLBACK_SMTP_USE_AUTH ]; + } + } + + public function getFallbackUsername() { + if ( defined( 'POST_SMTP_FALLBACK_AUTH_USERNAME' ) ) { + return POST_SMTP_FALLBACK_AUTH_USERNAME; + } + + if ( isset( $this->options [ PostmanOptions::FALLBACK_SMTP_USERNAME ] ) ) { + return $this->options [ PostmanOptions::FALLBACK_SMTP_USERNAME ]; + } + } + + + public function getFallbackPassword() { + if ( defined( 'POST_SMTP_FALLBACK_AUTH_PASSWORD' ) ) { + return POST_SMTP_FALLBACK_AUTH_PASSWORD; + } + + if ( isset( $this->options[ PostmanOptions::FALLBACK_SMTP_PASSWORD ] ) ) { + $value = $this->options[ PostmanOptions::FALLBACK_SMTP_PASSWORD ]; + + // First decode + $decoded = base64_decode( $value, true ); + + // If decoding fails, return as is + if ( $decoded === false ) { + return $value; + } + + // Check if it looks like another base64 string (only base64 chars and length multiple of 4) + if ( preg_match( '/^[A-Za-z0-9\/\r\n+]*={0,2}$/', $decoded ) && strlen( $decoded ) % 4 === 0 ) { + $double_decoded = base64_decode( $decoded, true ); + if ( $double_decoded !== false ) { + return $double_decoded; + } + } + + return $decoded; + } + + return null; + } + + + // End Fallback + + public function getMandrillApiKey() { + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options [ PostmanOptions::MANDRILL_API_KEY ] ) ) { + return base64_decode( $this->options [ PostmanOptions::MANDRILL_API_KEY ] ); } + } + public function getSendGridApiKey() { + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options [ PostmanOptions::SENDGRID_API_KEY ] ) ) { + return base64_decode( $this->options [ PostmanOptions::SENDGRID_API_KEY ] ); } + } + public function getMailerSendApiKey() { + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + if ( isset( $this->options [ PostmanOptions::MAILERSEND_API_KEY ] ) ) { + return base64_decode( $this->options [ PostmanOptions::MAILERSEND_API_KEY ] ); + } + } + + /** + * Retrieves the configured SendGrid region. + * + * Checks if the `POST_SMTP_API_KEY` is defined or returns the region from options. + * + * @since 3.1.0 + * @version 1.0.0 + * + * @return string|null The SendGrid region or null if not set. + */ + public function getSendGridRegion() { + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options [ PostmanOptions::SENDGRID_REGION ] ) ) { + return esc_attr( $this->options[ PostmanOptions::SENDGRID_REGION ] ); + } + + return null; // Default to null if no region is set. + } + + public function getMailgunApiKey() { + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options [ PostmanOptions::MAILGUN_API_KEY ] ) ) { + return base64_decode( $this->options [ PostmanOptions::MAILGUN_API_KEY ] ); } + } + public function getMailgunDomainName() { + if ( isset( $this->options [ PostmanOptions::MAILGUN_DOMAIN_NAME ] ) ) { + return $this->options [ PostmanOptions::MAILGUN_DOMAIN_NAME ]; + } + } + + public function getMailgunRegion() { + if ( isset( $this->options [ PostmanOptions::MAILGUN_REGION ] ) ) { + return $this->options [ PostmanOptions::MAILGUN_REGION ]; + } + } + + public function getReplyTo() { + if ( isset( $this->options [ PostmanOptions::REPLY_TO ] ) ) { + + /** + * Filters Reply-To + * + * @since 2.5.0 + * @version 1.0.0 + */ + return apply_filters( 'post_smtp_reply_to', $this->options[PostmanOptions::REPLY_TO] ); + + } + } + public function getConnectionTimeout() { + if ( ! empty( $this->options [ self::CONNECTION_TIMEOUT ] ) ) { + return $this->options [ self::CONNECTION_TIMEOUT ]; + } else { return self::DEFAULT_TCP_CONNECTION_TIMEOUT; } + } + public function getReadTimeout() { + if ( ! empty( $this->options [ self::READ_TIMEOUT ] ) ) { + return $this->options [ self::READ_TIMEOUT ]; + } else { return self::DEFAULT_TCP_READ_TIMEOUT; } + } + public function isPluginSenderNameEnforced() { + if ( $this->isNew() ) { + return self::DEFAULT_PLUGIN_MESSAGE_SENDER_NAME_ENFORCED; } + if ( isset( $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE ] ) ) { + return $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE ]; } + } + + public function isEmailValidationDisabled() { + if ( isset( $this->options [ PostmanOptions::DISABLE_EMAIL_VALIDAITON ] ) ) { + return $this->options [ PostmanOptions::DISABLE_EMAIL_VALIDAITON ]; } + } + + /** + * @since 2.1 + * @version 1.0 + */ + public function getSendinblueApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::SENDINBLUE_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::SENDINBLUE_API_KEY] ); + } + + } + + /** + * Get Mailtrap API Key + * @since 2.9.0 + * @version 1.0 + * @return string|null + */ + public function getMailtrapApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::MAILTRAP_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::MAILTRAP_API_KEY] ); + } + + } + + /** + * Get Emailit API Key + * @return string|null + */ + public function getEmailitApiKey() { if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[ PostmanOptions::EMAILIT_API_KEY ] ) ) { + return base64_decode( $this->options[ PostmanOptions::EMAILIT_API_KEY ] ); + } + return null; + } + + /** + * Get Maileroo API Key + * @return string|null + */ + public function getMailerooApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[ PostmanOptions::MAILEROO_API_KEY ] ) ) { + return base64_decode( $this->options[ PostmanOptions::MAILEROO_API_KEY ] ); + } + return null; + } + + + + /** + * Get Maileroo API Key + * @return string|null + */ + public function getSweegoApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[ PostmanOptions::SWEEGO_API_KEY ] ) ) { + return base64_decode( $this->options[ PostmanOptions::SWEEGO_API_KEY ] ); + } + return null; + } + + /** + * Get Resend API Key + * + * @since 3.2.0 + * @version 1.0 + */ + public function getResendApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::RESEND_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::RESEND_API_KEY] ); + } + + } + + /** + * Gets Mailjet API key + * + * @since 2.7 + * @version 1.0 + */ + + public function getMailjetApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::MAILJET_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::MAILJET_API_KEY] ); + } + + } + + /** + * Get SendPulse API key + * + * @since 2.7 + * @version 1.0 + */ + public function getSendpulseApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::SENDPULSE_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::SENDPULSE_API_KEY] ); + } + + } + + /** + * Gets Mailjet Secret key + * + * @since 2.7 + * @version 1.0 + */ + public function getMailjetSecretKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::MAILJET_SECRET_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::MAILJET_SECRET_KEY] ); + } + + } + + /** + * Gets SendPulse Secret key + * + * @since 2.7 + * @version 1.0 + */ + public function getSendpulseSecretKey() { + + if ( defined( 'POST_SMTP_SECRET_KEY' ) ) { + return POST_SMTP_SECRET_KEY; + } + + if ( isset( $this->options[PostmanOptions::SENDPULSE_SECRET_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::SENDPULSE_SECRET_KEY] ); + } + + } + + /** + * Gets SparkPost API key + * + * @since 2.2 + * @version 1.0 + */ + public function getSparkPostApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::SPARKPOST_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::SPARKPOST_API_KEY] ); + } + + } + + + /** + * @since 2.6.0 + * @version 1.0 + */ + public function getElasticEmailApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::ELASTICEMAIL_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::ELASTICEMAIL_API_KEY] ); + } + + } + + /** + * (non-PHPdoc) + * + * @deprecated by isPluginSenderNameEnforced + * + */ + public function isSenderNameOverridePrevented() { + return $this->isPluginSenderNameEnforced(); + } + public function isPluginSenderEmailEnforced() { + + if ( $this->isNew() ) { + return self::DEFAULT_PLUGIN_MESSAGE_SENDER_EMAIL_ENFORCED; } + if ( isset( $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE ] ) ) { + return $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE ]; } + } + /** + * + * @deprecated by isPluginSenderEmailEnforced + */ + public function isSenderEmailOverridePrevented() { + return $this->isPluginSenderEmailEnforced(); + } + private function setSenderEmail( $senderEmail ) { + $this->options [ PostmanOptions::MESSAGE_SENDER_EMAIL ] = $senderEmail; + } + public function setMessageSenderEmailIfEmpty( $senderEmail ) { + if ( empty( $this->options [ PostmanOptions::MESSAGE_SENDER_EMAIL ] ) ) { + $this->setSenderEmail( $senderEmail ); + } + } + private function setSenderName( $senderName ) { + $this->options [ PostmanOptions::MESSAGE_SENDER_NAME ] = $senderName; + } + public function setMessageSenderNameIfEmpty( $senderName ) { + if ( empty( $this->options [ PostmanOptions::MESSAGE_SENDER_NAME ] ) ) { + $this->setSenderName( $senderName ); + } + } + + public function getSmtpMailer() { + if ( empty($this->options [ 'smtp_mailers' ]) ) { + return 'postsmtp'; + } + + return $this->options [ 'smtp_mailers' ]; + } + + public function isAuthTypePassword() { + return $this->isAuthTypeLogin() || $this->isAuthTypeCrammd5() || $this->isAuthTypePlain(); + } + public function isAuthTypeOAuth2() { + return PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType(); + } + public function isAuthTypeLogin() { + return PostmanOptions::AUTHENTICATION_TYPE_LOGIN == $this->getAuthenticationType(); + } + public function isAuthTypePlain() { + return PostmanOptions::AUTHENTICATION_TYPE_PLAIN == $this->getAuthenticationType(); + } + public function isAuthTypeCrammd5() { + return PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5 == $this->getAuthenticationType(); + } + public function isAuthTypeNone() { + return PostmanOptions::AUTHENTICATION_TYPE_NONE == $this->getAuthenticationType(); + } + /** + * + * @deprecated Required by the Postman Gmail Extension + * + * @see PostmanOptionsInterface::getSenderEmail() + */ + public function getSenderEmail() { + return $this->getMessageSenderEmail(); + } + /** + * + * @deprecated Required by the Postman Gmail Extension + * + * @see PostmanOptionsInterface::getSenderEmail() + */ + public function getSenderName() { + return $this->getMessageSenderName(); + } + + /** + * + * @return string + */ + public function export() { + if ( PostmanPreRequisitesCheck::checkZlibEncode() ) { + $data = $this->options; + $data ['version'] = PostmanState::getInstance()->getVersion(); + foreach ( PostmanTransportRegistry::getInstance()->getTransports() as $transport ) { + $data = $transport->prepareOptionsForExport( $data ); + } + $data = base64_encode( gzcompress( json_encode( $data ), 9 ) ); + return $data; + } + } + + /** + * + * @param mixed $data + */ + public function import( $data ) { + if ( PostmanPreRequisitesCheck::checkZlibEncode() ) { + $logger = new PostmanLogger( get_class( $this ) ); + $logger->debug( 'Importing Settings' ); + $base64 = $data; + $logger->trace( $base64 ); + $gz = base64_decode( $base64 ); + $logger->trace( $gz ); + $json = @gzuncompress( $gz ); + $logger->trace( $json ); + if ( ! empty( $json ) ) { + $data = json_decode( $json, true ); + $logger->trace( $data ); + { + // overwrite the current version with the version from the imported options + // this way database upgrading can occur + $postmanState = get_option( 'postman_state' ); + $postmanState ['version'] = $data ['version']; + $logger->trace( sprintf( 'Setting Postman version to %s', $postmanState ['version'] ) ); + assert( $postmanState ['version'] == $data ['version'] ); + update_option( 'postman_state', $postmanState ); + } + $this->options = $data; + $logger->info( 'Imported data' ); + $this->save(); + return true; + } else { + $logger->error( 'Could not import data - data error' ); + return false; + } + } + } + + public function getPostmarkApiKey() { + + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[PostmanOptions::POSTMARK_API_KEY] ) ) { + return base64_decode( $this->options[PostmanOptions::POSTMARK_API_KEY] ); + } + + } + + + /** + * Is the PHP Compatibility Mode enabled? + * + * @since 2.5.0 + * @version 1.0.0 + */ + public function is_php_compatibility_enabled() { + + if ( isset( $this->options [ PostmanOptions::INCOMPATIBLE_PHP_VERSION ] ) ) { + + return $this->options [ PostmanOptions::INCOMPATIBLE_PHP_VERSION ]; + + } + else { + + return self::DEFAULT_PHP_COMPATIBILITY_MODE; + + } + + } + + public function getSmtp2GoApiKey() { + if ( defined( 'POST_SMTP_API_KEY' ) ) { + return POST_SMTP_API_KEY; + } + + if ( isset( $this->options[ PostmanOptions::SMTP2GO_API_KEY ] ) ) { + return base64_decode( $this->options [ PostmanOptions::SMTP2GO_API_KEY ] ); + } + } + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanPluginFeedback.php b/html/wp-content/plugins/post-smtp/Postman/PostmanPluginFeedback.php new file mode 100644 index 0000000..95ea06f --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanPluginFeedback.php @@ -0,0 +1,157 @@ + admin_url( 'admin-ajax.php' ) ) ); + wp_enqueue_script( 'post-feedback' ); + } + + function post_user_feedback() { + if ( ! check_ajax_referer() ) { + die( 'security error' ); + } + + $payload = array( + 'reason' => sanitize_text_field( $_POST['reason'] ), + 'other_input' => isset( $_POST['other_input'] ) ? sanitize_text_field( $_POST['other_input'] ) : '', + ); + + if ( isset( $_POST['support'] ) ) { + $payload['support']['email'] = sanitize_email( $_POST['support']['email'] ); + $payload['support']['title'] = sanitize_text_field( $_POST['support']['title'] ); + $payload['support']['text'] = sanitize_textarea_field( $_POST['support']['text'] ); + } + + $args = array( + 'body' => $payload, + 'timeout' => 20, + ); + $result = wp_remote_post( 'https://postmansmtp.com/feedback', $args ); + die( 'success' ); + } + + function admin_head() { + ?> + + + + x,ready=>true|false,required=true|false] + */ + public static function getState() { + $state = array (); + array_push ( $state, array ( + 'name' => 'iconv', + 'ready' => self::checkIconv (), + 'required' => true + ) ); + array_push ( $state, array ( + 'name' => 'spl_autoload', + 'ready' => self::checkSpl (), + 'required' => true + ) ); + array_push ( $state, array ( + 'name' => 'openssl', + 'ready' => self::checkOpenSsl (), + 'required' => false + ) ); + array_push ( $state, array ( + 'name' => 'sockets', + 'ready' => self::checkSockets (), + 'required' => false + ) ); + array_push ( $state, array ( + 'name' => 'allow_url_fopen', + 'ready' => self::checkAllowUrlFopen (), + 'required' => false + ) ); + array_push ( $state, array ( + 'name' => 'mcrypt', + 'ready' => self::checkMcrypt (), + 'required' => false + ) ); + array_push ( $state, array ( + 'name' => 'zlib_encode', + 'ready' => self::checkZlibEncode (), + 'required' => false + ) ); + return $state; + } + /** + * + * @return boolean + */ + public static function isReady() { + $states = self::getState (); + foreach ( $states as $state ) { + if ($state ['ready'] == false && $state ['required'] == true) { + return false; + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanSMTPConflictManager.php b/html/wp-content/plugins/post-smtp/Postman/PostmanSMTPConflictManager.php new file mode 100644 index 0000000..f96156b --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanSMTPConflictManager.php @@ -0,0 +1,728 @@ +logger = new PostmanLogger( get_class( $this ) ); + + // Hook into admin_notices to display warnings + add_action( 'admin_notices', array( $this, 'display_smtp_conflict_notices' ) ); + + // Hook into AJAX for dismissing notices + add_action( 'wp_ajax_dismiss_smtp_conflict_notice', array( $this, 'dismiss_notice_ajax' ) ); + + // Enqueue scripts for dismissing notices + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_dismiss_script' ) ); + + } + + /** + * Get list of known SMTP plugins that could conflict with Post SMTP + * + * @return array + */ + private function get_smtp_plugins_list() { + return array( + /** + * Url: https://wordpress.org/plugins/easy-wp-smtp/ + */ + array( + 'name' => 'Easy WP SMTP', + 'slug' => 'easy-wp-smtp/easy-wp-smtp.php', + 'class' => 'EasyWPSMTP', + ), + + /** + * Closed. + * + * Url: https://wordpress.org/plugins/postman-smtp/ + */ + array( + 'name' => 'Postman SMTP', + 'slug' => 'postman-smtp/postman-smtp.php', + 'function' => 'postman_start', + ), + + /** + * Url: https://wordpress.org/plugins/wp-mail-bank/ + */ + array( + 'name' => 'Mail Bank', + 'slug' => 'wp-mail-bank/wp-mail-bank.php', + 'function' => 'mail_bank', + ), + + /** + * Url: https://wordpress.org/plugins/smtp-mailer/ + */ + array( + 'name' => 'SMTP Mailer', + 'slug' => 'smtp-mailer/main.php', + 'class' => 'SMTP_MAILER', + ), + + /** + * Url: https://wordpress.org/plugins/gmail-smtp/ + */ + array( + 'name' => 'Gmail SMTP', + 'slug' => 'gmail-smtp/main.php', + 'class' => 'GMAIL_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/wp-email-smtp/ + */ + array( + 'name' => 'WP Email SMTP', + 'class' => 'WP_Email_Smtp', + ), + + /** + * Url: https://wordpress.org/plugins/smtp-mail/ + */ + array( + 'name' => 'SMTP Mail', + 'slug' => 'smtp-mail/index.php', + 'function' => 'smtpmail_include', + ), + + /** + * Url: https://wordpress.org/plugins/bws-smtp/ + */ + array( + 'name' => 'SMTP by BestWebSoft', + 'slug' => 'bws-smtp/bws-smtp.php', + 'function' => 'bwssmtp_init', + ), + + /** + * Url: https://wordpress.org/plugins/wp-sendgrid-smtp/ + */ + array( + 'name' => 'WP SendGrid SMTP', + 'slug' => 'wp-sendgrid-smtp/wp-sendgrid-smtp.php', + 'class' => 'WPSendGrid_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/sar-friendly-smtp/ + */ + array( + 'name' => 'SAR Friendly SMTP', + 'slug' => 'sar-friendly-smtp/sar-friendly-smtp.php', + 'function' => 'sar_friendly_smtp', + ), + + /** + * Url: https://wordpress.org/plugins/wp-gmail-smtp/ + */ + array( + 'name' => 'WP Gmail SMTP', + 'slug' => 'wp-gmail-smtp/wp-gmail-smtp.php', + 'class' => 'WPGmail_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/cimy-swift-smtp/ + */ + array( + 'name' => 'Cimy Swift SMTP', + 'slug' => 'cimy-swift-smtp/cimy_swift_smtp.php', + 'function' => 'st_smtp_check_config', + ), + + /** + * Closed. + * + * Url: https://wordpress.org/plugins/wp-easy-smtp/ + */ + array( + 'name' => 'WP Easy SMTP', + 'slug' => 'wp-easy-smtp/wp-easy-smtp.php', + 'class' => 'WP_Easy_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/wp-mailgun-smtp/ + */ + array( + 'name' => 'WP Mailgun SMTP', + 'slug' => 'wp-mailgun-smtp/wp-mailgun-smtp.php', + 'class' => 'WPMailgun_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/my-smtp-wp/ + */ + array( + 'name' => 'MY SMTP WP', + 'slug' => 'my-smtp-wp/my-smtp-wp.php', + 'function' => 'my_smtp_wp', + ), + + /** + * Closed. + * + * Url: https://wordpress.org/plugins/wp-mail-booster/ + */ + array( + 'name' => 'WP Mail Booster', + 'slug' => 'wp-mail-booster/wp-mail-booster.php', + 'function' => 'mail_booster', + ), + + /** + * Url: https://wordpress.org/plugins/sendgrid-email-delivery-simplified/ + */ + array( + 'name' => 'SendGrid', + 'slug' => 'sendgrid-email-delivery-simplified/wpsendgrid.php', + 'class' => 'Sendgrid_Settings', + ), + + /** + * Url: https://wordpress.org/plugins/wp-mail-smtp/ + */ + array( + 'name' => 'WP Mail Smtp', + 'slug' => 'wp-mail-smtp/wp_mail_smtp.php', + 'function' => 'WPMS_php_mailer', + ), + + /** + * Closed. + * + * Url: https://wordpress.org/plugins/wp-amazon-ses-smtp/ + */ + array( + 'name' => 'WP Amazon SES SMTP', + 'slug' => 'wp-amazon-ses-smtp/wp-amazon-ses.php', + 'class' => 'WPAmazonSES_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/postmark-approved-wordpress-plugin/ + */ + array( + 'name' => 'Postmark (Official)', + 'slug' => 'postmark-approved-wordpress-plugin/postmark.php', + 'class' => 'Postmark_Mail', + ), + + /** + * Url: https://wordpress.org/plugins/mailgun/ + */ + array( + 'name' => 'Mailgun', + 'slug' => 'mailgun/mailgun.php', + 'class' => 'Mailgun', + ), + + /** + * Url: https://wordpress.org/plugins/sparkpost/ + */ + array( + 'name' => 'SparkPost', + 'slug' => 'sparkpost/wordpress-sparkpost.php', + 'class' => 'WPSparkPost\SparkPost', + ), + + /** + * Url: https://wordpress.org/plugins/wp-yahoo-smtp/ + */ + array( + 'name' => 'WP Yahoo SMTP', + 'slug' => 'wp-yahoo-smtp/wp-yahoo-smtp.php', + 'class' => 'WPYahoo_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/wp-ses/ + */ + array( + 'name' => 'WP Offload SES Lite', + 'slug' => 'wp-ses/wp-ses.php', + 'function' => 'wp_offload_ses_lite_init', + ), + + /** + * Url: https://deliciousbrains.com/wp-offload-ses/ + */ + array( + 'name' => 'WP Offload SES', + 'slug' => 'wp-offload-ses/wp-offload-ses.php', + ), + + /** + * Url: https://wordpress.org/plugins/turbosmtp/ + */ + array( + 'name' => 'turboSMTP', + 'slug' => 'turbosmtp/turbosmtp.php', + 'function' => 'TSPHPMailer', + ), + + /** + * Url: https://wordpress.org/plugins/wp-smtp/ + */ + array( + 'name' => 'Solid Mail', + 'slug' => 'wp-smtp/wp-smtp.php', + 'class' => 'WP_SMTP', + ), + + /** + * This plugin can be used along with our plugin if disable next option + * WooCommerce -> Settings -> Sendinblue -> Email Options -> Enable Sendinblue to send WooCommerce emails. + * + * Url: https://wordpress.org/plugins/woocommerce-sendinblue-newsletter-subscription + */ + array( + 'name' => 'Sendinblue - WooCommerce Email Marketing', + 'slug' => 'woocommerce-sendinblue-newsletter-subscription/woocommerce-sendinblue.php', + 'class' => 'WC_Sendinblue_Integration', + 'test' => 'test_wc_sendinblue_integration', + 'message' => esc_html__( 'Or disable the Sendinblue email sending setting in WooCommerce > Settings > Sendinblue (tab) > Email Options (tab) > Enable Sendinblue to send WooCommerce emails.', 'post-smtp' ), + ), + + /** + * Url: https://wordpress.org/plugins/disable-emails/ + */ + array( + 'name' => 'Disable Emails', + 'slug' => 'disable-emails/disable-emails.php', + 'class' => '\webaware\disable_emails\Plugin', + ), + + /** + * Url: https://wordpress.org/plugins/fluent-smtp/ + */ + array( + 'name' => 'FluentSMTP', + 'slug' => 'fluent-smtp/fluent-smtp.php', + 'function' => 'fluentSmtpInit', + ), + + /** + * This plugin can be used along with our plugin if enable next option + * Settings > Email template > Sender (tab) -> Do not change email sender by default. + * + * Url: https://wordpress.org/plugins/wp-html-mail/ + */ + array( + 'name' => 'WP HTML Mail - Email Template Designer', + 'function' => 'Haet_Mail', + 'test' => 'test_wp_html_mail_integration', + 'message' => esc_html__( 'Or enable "Do not change email sender by default" setting in Settings > Email template > Sender (tab).', 'post-smtp' ), + ), + + /** + * This plugin can be used along with our plugin if "SMTP" module is deactivated. + * + * Url: https://wordpress.org/plugins/branda-white-labeling/ + */ + array( + 'name' => 'Branda', + 'slug' => 'branda-white-labeling/ultimate-branding.php', + 'function' => 'set_ultimate_branding', + 'test' => 'test_branda_integration', + 'message' => esc_html__( 'Or deactivate "SMTP" module in Branda > Emails > SMTP.', 'post-smtp' ), + ), + + /** + * Url: https://wordpress.org/plugins/zoho-mail/ + */ + array( + 'name' => 'Zoho Mail for WordPress', + 'slug' => 'zoho-mail/zohoMail.php', + 'function' => 'zmail_send_mail_callback', + ), + + /** + * Url: https://elementor.com/products/site-mailer/ + */ + array( + 'name' => 'Site Mailer - SMTP Replacement, Email API Deliverability & Email Log', + 'slug' => 'site-mailer/site-mailer.php', + 'class' => 'SiteMailer', + ), + + /** + * Url: https://wordpress.org/plugins/suremails/ + */ + array( + 'name' => 'SureMail', + 'slug' => 'suremails/suremails.php', + 'class' => 'MailHandler', + ), + + /** + * Url: https://www.gravityforms.com/gravity-smtp/ + */ + array( + 'name' => 'Gravity SMTP', + 'slug' => 'gravitysmtp/gravitysmtp.php', + 'class' => 'Gravity_SMTP', + ), + + /** + * Url: https://wordpress.org/plugins/pro-mail-smtp/ + */ + array( + 'name' => 'Pro Mail SMTP', + 'slug' => 'pro-mail-smtp/pro-mail-smtp.php', + 'function' => 'pro-mail-smtp', + ), + ); + } + + /** + * Check if a plugin is active and conflicts with Post SMTP + * + * @param array $plugin Plugin configuration array + * @return bool + */ + private function is_plugin_conflicting( $plugin ) { + // Skip our own plugin + if ( isset( $plugin['slug'] ) && $plugin['slug'] === 'post-smtp/postman-smtp.php' ) { + return false; + } + + // Check if plugin is active by slug + if ( isset( $plugin['slug'] ) && is_plugin_active( $plugin['slug'] ) ) { + return true; + } + + // Check if plugin class exists + if ( isset( $plugin['class'] ) && class_exists( $plugin['class'] ) ) { + return true; + } + + // Check if plugin function exists + if ( isset( $plugin['function'] ) && function_exists( $plugin['function'] ) ) { + return true; + } + + return false; + } + + /** + * Get all currently conflicting plugins + * + * @return array + */ + private function get_conflicting_plugins() { + if ( ! empty( $this->conflicting_plugins ) ) { + return $this->conflicting_plugins; + } + + $smtp_plugins = $this->get_smtp_plugins_list(); + $conflicting = array(); + + foreach ( $smtp_plugins as $plugin ) { + if ( $this->is_plugin_conflicting( $plugin ) ) { + $conflicting[] = $plugin; + + // Log the conflict detection + if ( $this->logger->isDebug() ) { + $this->logger->debug( sprintf( + 'SMTP plugin conflict detected: %s (%s)', + $plugin['name'], + isset( $plugin['slug'] ) ? $plugin['slug'] : 'no slug' + ) ); + } + } + } + + $this->conflicting_plugins = $conflicting; + + // Log summary if conflicts found + if ( ! empty( $conflicting ) && $this->logger->isInfo() ) { + $this->logger->info( sprintf( + 'Found %d conflicting SMTP plugin(s): %s', + count( $conflicting ), + implode( ', ', array_column( $conflicting, 'name' ) ) + ) ); + } + + return $conflicting; + } + + /** + * Display SMTP conflict admin notices + */ + public function display_smtp_conflict_notices() { + // Allow disabling conflict detection via filter + if ( ! apply_filters( 'post_smtp_enable_conflict_detection', true ) ) { + return; + } + + // Only show in admin area and to users who can manage options + if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) { + return; + } + + $conflicting_plugins = $this->get_conflicting_plugins(); + + foreach ( $conflicting_plugins as $plugin ) { + $notice_id = sanitize_key( $plugin['name'] ); + + // Skip if notice has been dismissed and not expired + if ( $this->is_notice_dismissed( $notice_id ) ) { + continue; + } + + $this->display_conflict_notice( $plugin, $notice_id ); + } + } + + /** + * Display individual conflict notice + * + * @param array $plugin Plugin configuration + * @param string $notice_id Unique notice ID + */ + private function display_conflict_notice( $plugin, $notice_id ) { + $plugin_name = esc_html( $plugin['name'] ); + $plugin_slug = isset( $plugin['slug'] ) ? $plugin['slug'] : ''; + + // Build deactivate link if plugin slug is available + $deactivate_link = ''; + if ( ! empty( $plugin_slug ) ) { + $deactivate_url = wp_nonce_url( + admin_url( 'plugins.php?action=deactivate&plugin=' . urlencode( $plugin_slug ) . '&plugin_status=all&paged=1&s=' ), + 'deactivate-plugin_' . $plugin_slug + ); + $deactivate_link = '' . esc_html__( 'Deactivate', 'post-smtp' ) . ' ' . $plugin_name . ''; + } + + echo '
        '; + echo '

        ' . esc_html__( 'Post SMTP Notice:', 'post-smtp' ) . '

        '; + echo '

        '; + printf( + /* translators: %1$s: conflicting plugin name */ + esc_html__( 'wp_mail() is being overridden by another plugin (%1$s). Please deactivate it to use Post SMTP.', 'post-smtp' ), + '' . $plugin_name . '' + ); + echo '

        '; + if ( ! empty( $deactivate_link ) ) { + echo '

        ' . $deactivate_link . '

        '; + } + echo '
        '; + } + + /** + * Handle AJAX request to dismiss notice + */ + public function dismiss_notice_ajax() { + // Verify nonce + if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'postman_smtp_conflict_nonce' ) ) { + wp_send_json_error( array( 'message' => 'Security check failed' ) ); + } + + // Check user capability + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Insufficient permissions' ) ); + } + + // Validate notice ID + if ( ! isset( $_POST['notice_id'] ) ) { + wp_send_json_error( array( 'message' => 'Notice ID is required' ) ); + } + + $notice_id = sanitize_key( $_POST['notice_id'] ); + if ( empty( $notice_id ) ) { + wp_send_json_error( array( 'message' => 'Invalid notice ID' ) ); + } + + $dismissed_notices = get_option( self::DISMISSED_NOTICES_OPTION, array() ); + + // Store dismissal with current timestamp (7 days expiration) + $dismissed_notices[ $notice_id ] = time(); + + if ( update_option( self::DISMISSED_NOTICES_OPTION, $dismissed_notices ) ) { + wp_send_json_success( array( 'message' => 'Notice dismissed successfully' ) ); + } else { + wp_send_json_error( array( 'message' => 'Failed to save dismissal' ) ); + } + } + + /** + * Check if a notice is dismissed and not expired + * + * @param string $notice_id Notice ID to check + * @return bool True if dismissed and not expired, false otherwise + */ + private function is_notice_dismissed( $notice_id ) { + $dismissed_notices = get_option( self::DISMISSED_NOTICES_OPTION, array() ); + + // Handle old format (array of notice IDs) - migrate to new format + if ( ! empty( $dismissed_notices ) && is_array( $dismissed_notices ) ) { + $keys = array_keys( $dismissed_notices ); + $needs_migration = false; + + // Check if old format (numeric keys or string keys with non-numeric values) + foreach ( $keys as $key ) { + if ( is_numeric( $key ) || ! is_numeric( $dismissed_notices[ $key ] ) ) { + $needs_migration = true; + break; + } + } + + if ( $needs_migration ) { + // Old format detected - convert to new format with current timestamp + $new_format = array(); + foreach ( $dismissed_notices as $key => $value ) { + if ( is_numeric( $key ) ) { + $new_format[ $value ] = time(); + } else { + $new_format[ $key ] = is_numeric( $value ) ? $value : time(); + } + } + $dismissed_notices = $new_format; + update_option( self::DISMISSED_NOTICES_OPTION, $dismissed_notices ); + } + } + + if ( ! isset( $dismissed_notices[ $notice_id ] ) ) { + return false; + } + + $dismissed_time = $dismissed_notices[ $notice_id ]; + + // Check if 7 days have passed (7 days = 604800 seconds) + $expiration_time = 7 * DAY_IN_SECONDS; + if ( ( time() - $dismissed_time ) > $expiration_time ) { + // Expired - remove from dismissed notices + unset( $dismissed_notices[ $notice_id ] ); + update_option( self::DISMISSED_NOTICES_OPTION, $dismissed_notices ); + return false; + } + + return true; + } + + + /** + * Get count of conflicting plugins + * + * @return int + */ + public function get_conflicts_count() { + return count( $this->get_conflicting_plugins() ); + } + + /** + * Check if there are any conflicts + * + * @return bool + */ + public function has_conflicts() { + return $this->get_conflicts_count() > 0; + } + + /** + * Reset dismissed notices (for testing or admin purposes) + */ + public function reset_dismissed_notices() { + delete_option( self::DISMISSED_NOTICES_OPTION ); + } + + /** + * Get detailed information about all SMTP plugins (for debugging/admin purposes) + * + * @return array + */ + public function get_smtp_plugins_status() { + $smtp_plugins = $this->get_smtp_plugins_list(); + $status = array(); + + foreach ( $smtp_plugins as $plugin ) { + $plugin_status = array( + 'name' => $plugin['name'], + 'slug' => isset( $plugin['slug'] ) ? $plugin['slug'] : '', + 'is_active' => false, + 'conflict' => false, + 'detection' => array() + ); + + // Check plugin activation status + if ( isset( $plugin['slug'] ) && is_plugin_active( $plugin['slug'] ) ) { + $plugin_status['is_active'] = true; + $plugin_status['detection'][] = 'Active plugin'; + } + + // Check class existence + if ( isset( $plugin['class'] ) && class_exists( $plugin['class'] ) ) { + $plugin_status['detection'][] = 'Class exists: ' . $plugin['class']; + } + + // Check function existence + if ( isset( $plugin['function'] ) && function_exists( $plugin['function'] ) ) { + $plugin_status['detection'][] = 'Function exists: ' . $plugin['function']; + } + + // Determine if it's conflicting + $plugin_status['conflict'] = $this->is_plugin_conflicting( $plugin ); + + $status[] = $plugin_status; + } + + return $status; + } + + /** + * Enqueue JavaScript for handling notice dismissal + */ + public function enqueue_dismiss_script( $hook ) { + // Only enqueue if there are conflicts + if ( ! $this->has_conflicts() ) { + return; + } + + // Get plugin data for version + $plugin_data = apply_filters( 'postman_get_plugin_metadata', null ); + $version = isset( $plugin_data['version'] ) ? $plugin_data['version'] : '1.0.0'; + + // Enqueue the script + wp_enqueue_script( + 'postman-smtp-conflict-notice', + POST_SMTP_URL . '/script/postman-smtp-conflict-notice.js', + array( 'jquery' ), + $version, + true + ); + + // Localize script with nonce + wp_localize_script( + 'postman-smtp-conflict-notice', + 'postmanSmtpConflict', + array( + 'nonce' => wp_create_nonce( 'postman_smtp_conflict_nonce' ) + ) + ); + } +} diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanSession.php b/html/wp-content/plugins/post-smtp/Postman/PostmanSession.php new file mode 100644 index 0000000..f1128b4 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanSession.php @@ -0,0 +1,95 @@ +logger = new PostmanLogger(get_class($this)); + $this->load(); + } + // + public function save() { + update_option ( self::SLUG, $this->options ); + } + public function reload() { + $this->load (); + } + private function load() { + $this->options = get_option ( self::SLUG ); + } + /** + * Shows the review feature of Postman up to thirty days after install + * + * @return boolean + */ + public function isTimeToReviewPostman() { + if (! empty ( $this->options [self::INSTALL_DATE] )) { + $successful = PostmanState::getInstance ()->getSuccessfulDeliveries () > 0; + $maxTime = $this->options [self::INSTALL_DATE] + self::TOO_LONG_SEC; + return $successful && time () <= $maxTime; + } + } + public function isFileLockingEnabled() { + if (isset ( $this->options [self::FILE_LOCKING_ENABLED] )) + return $this->options [self::FILE_LOCKING_ENABLED]; + else + return false; + } + public function setFileLockingEnabled($enabled) { + $this->options [self::FILE_LOCKING_ENABLED] = $enabled; + $this->save (); + } + public function getVersion() { + if (! empty ( $this->options [self::VERSION] )) { + return $this->options [self::VERSION]; + } + } + function getSuccessfulDeliveries() { + if (isset ( $this->options [PostmanState::DELIVERY_SUCCESS_TOTAL] )) + return $this->options [PostmanState::DELIVERY_SUCCESS_TOTAL]; + else + return 0; + } + function setSuccessfulDelivery($total) { + $this->options [PostmanState::DELIVERY_SUCCESS_TOTAL] = $total; + } + function incrementSuccessfulDelivery() { + $this->setSuccessfulDelivery ( $this->getSuccessfulDeliveries () + 1 ); + $this->logger->debug ( 'incrementing success count: ' . $this->getSuccessfulDeliveries () ); + $this->save (); + } + function getFailedDeliveries() { + if (isset ( $this->options [PostmanState::DELIVERY_FAILURE_TOTAL] )) + return $this->options [PostmanState::DELIVERY_FAILURE_TOTAL]; + else + return 0; + } + function setFailedDelivery($total) { + $this->options [PostmanState::DELIVERY_FAILURE_TOTAL] = $total; + } + function incrementFailedDelivery() { + $this->setFailedDelivery ( $this->getFailedDeliveries () + 1 ); + $this->logger->debug ( 'incrementing failure count: ' . $this->getFailedDeliveries () ); + $this->save (); + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanUtils.php b/html/wp-content/plugins/post-smtp/Postman/PostmanUtils.php new file mode 100644 index 0000000..b8730ef --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanUtils.php @@ -0,0 +1,504 @@ + PostmanOptions::getInstance()->getConnectionTimeout(), + 'headers' => $headers, + 'body' => $parameters, + ); + if ( PostmanUtils::$logger->isTrace() ) { + PostmanUtils::$logger->trace( sprintf( 'Posting to %s', $url ) ); + PostmanUtils::$logger->trace( 'Post header:' ); + PostmanUtils::$logger->trace( $headers ); + PostmanUtils::$logger->trace( 'Posting args:' ); + PostmanUtils::$logger->trace( $parameters ); + } + $response = wp_remote_post( $url, $args ); + + // pre-process the response + if ( is_wp_error( $response ) ) { + PostmanUtils::$logger->error( $response->get_error_message() ); + throw new Exception( 'Error executing wp_remote_post: ' . $response->get_error_message() ); + } else { + return $response; + } + } + /** + * A facade function that handles redirects. + * Inside WordPress we can use wp_redirect(). Outside WordPress, not so much. **Load it before postman-core.php** + * + * @param mixed $url + */ + static function redirect( $url ) { + // redirections back to THIS SITE should always be relative because of IIS bug + if ( PostmanUtils::$logger->isTrace() ) { + PostmanUtils::$logger->trace( sprintf( "Redirecting to '%s'", $url ) ); + } + wp_redirect( $url ); + exit(); + } + static function parseBoolean( $var ) { + return filter_var( $var, FILTER_VALIDATE_BOOLEAN ); + } + static function logMemoryUse( $startingMemory, $description ) { + PostmanUtils::$logger->trace( sprintf( $description . ' memory used: %s', PostmanUtils::roundBytes( memory_get_usage() - $startingMemory ) ) ); + } + + /** + * Rounds the bytes returned from memory_get_usage to smaller amounts used IEC binary prefixes + * See http://en.wikipedia.org/wiki/Binary_prefix + * + * @param mixed $size + * @return string + */ + static function roundBytes( $size ) { + $size = intval( $size ); + $unit = array( + 'B', + 'KiB', + 'MiB', + 'GiB', + 'TiB', + 'PiB', + ); + + $log = log( $size, 1024 ); + $unit_key = floor( $log ); + $pow = pow( 1024, $unit_key ); + $pow = floor( $pow ); + + return @round( $size / $pow, 2 ) . ' ' . $unit[$unit_key]; + } + + /** + * Unblock threads waiting on lock() + */ + static function unlock() { + if ( PostmanState::getInstance()->isFileLockingEnabled() ) { + PostmanUtils::deleteLockFile(); + } + } + + /** + * Processes will block on this method until unlock() is called + * Inspired by http://cubicspot.blogspot.ca/2010/10/forget-flock-and-system-v-semaphores.html + * + * @throws Exception + */ + static function lock() { + if ( PostmanState::getInstance()->isFileLockingEnabled() ) { + $attempts = 0; + while ( true ) { + // create the semaphore + $lock = PostmanUtils::createLockFile(); + if ( $lock ) { + // if we got the lock, return + return; + } else { + $attempts ++; + if ( $attempts >= 10 ) { + throw new Exception( sprintf( 'Could not create lockfile %s', '/tmp' . '/.postman.lock' ) ); + } + sleep( 1 ); + } + } + } + } + + static function lockFileExists() { + $path = PostmanUtils::calculateTemporaryLockPath( null ); + + return file_exists($path); + } + + static function deleteLockFile( $tempDirectory = null ) { + $path = PostmanUtils::calculateTemporaryLockPath( $tempDirectory ); + $success = file_exists($path) ? @unlink($path) : true; + if ( PostmanUtils::$logger->isTrace() ) { + PostmanUtils::$logger->trace( sprintf( 'Deleting file %s : %s', $path, $success ) ); + } + return $success; + } + static function createLockFile( $tempDirectory = null ) { + if ( self::lockFileExists() ) { + self::deleteLockFile(); + } + $path = PostmanUtils::calculateTemporaryLockPath( $tempDirectory ); + $success = @fopen( $path, 'xb' ); + if ( PostmanUtils::$logger->isTrace() ) { + PostmanUtils::$logger->trace( sprintf( 'Creating file %s : %s', $path, $success ) ); + } + return $success; + } + + /** + * Creates the pathname of the lockfile + * + * @param mixed $tempDirectory + * @return string + */ + private static function calculateTemporaryLockPath( $tempDirectory ) { + if ( empty( $tempDirectory ) ) { + $options = PostmanOptions::getInstance(); + $tempDirectory = $options->getTempDirectory(); + } + $fullPath = sprintf( '%s/.postman_%s.lock', $tempDirectory, self::generateUniqueLockKey() ); + return $fullPath; + } + + /** + * + * @return string + */ + private static function generateUniqueLockKey() { + // for single sites, use the network_site_url to generate the key because + // it is unique for every wordpress site unlike the blog ID which may be the same + $key = hash( 'crc32', network_site_url( '/' ) ); + // TODO for multisites + // if the subsite is sharing the config - use the network_site_url of site 0 + // if the subsite has its own config - use the network_site_url of the subsite + return $key; + } + + /** + * From http://stackoverflow.com/a/381275/4368109 + * + * @param mixed $text + * @return boolean + */ + public static function isEmpty( $text ) { + // Function for basic field validation (present and neither empty nor only white space + return ( ! isset( $text ) || trim( $text ) === ''); + } + + /** + * Warning! This can only be called on hook 'init' or later + */ + public static function isAdmin() { + /** + * is_admin() will return false when trying to access wp-login.php. + * is_admin() will return true when trying to make an ajax request. + * is_admin() will return true for calls to load-scripts.php and load-styles.php. + * is_admin() is not intended to be used for security checks. It will return true + * whenever the current URL is for a page on the admin side of WordPress. It does + * not check if the user is logged in, nor if the user even has access to the page + * being requested. It is a convenience function for plugins and themes to use for + * various purposes, but it is not suitable for validating secured requests. + * + * Good to know. + */ + $logger = PostmanUtils::$logger = new PostmanLogger( 'PostmanUtils' ); + if ( $logger->isTrace() ) { + $logger->trace( 'calling current_user_can' ); + } + return current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_NAME ) && is_admin(); + } + + /** + * Validate an e-mail address + * + * @param mixed $email + * @return string|bool + */ + static function validateEmail( $email ) { + if ( PostmanOptions::getInstance()->isEmailValidationDisabled() ) { + return true; + } + require_once 'Postman-Mail/Zend-1.12.10/Exception.php'; + require_once 'Postman-Mail/Zend-1.12.10/Registry.php'; + require_once 'Postman-Mail/Zend-1.12.10/Validate/Exception.php'; + require_once 'Postman-Mail/Zend-1.12.10/Validate/Interface.php'; + require_once 'Postman-Mail/Zend-1.12.10/Validate/Abstract.php'; + require_once 'Postman-Mail/Zend-1.12.10/Validate/Ip.php'; + require_once 'Postman-Mail/Zend-1.12.10/Validate/Hostname.php'; + require_once 'Postman-Mail/Zend-1.12.10/Validate/EmailAddress.php'; + if ( ! isset( PostmanUtils::$emailValidator ) ) { + PostmanUtils::$emailValidator = new Postman_Zend_Validate_EmailAddress(); + } + if ( strpos( $email, ',' ) !== false ) { + $emails = explode(',', $email); + $result = []; + foreach ( $emails as $email ) { + $result[] = PostmanUtils::$emailValidator->isValid( $email ); + } + + return ! in_array(false, $result ); + } + return PostmanUtils::$emailValidator->isValid( $email ); + } + + /** + * From http://stackoverflow.com/questions/13430120/str-getcsv-alternative-for-older-php-version-gives-me-an-empty-array-at-the-e + * + * @param mixed $string + * @return multitype: + */ + static function postman_strgetcsv_impl( $string ) { + $fh = fopen( 'php://temp', 'r+' ); + fwrite( $fh, $string ); + rewind( $fh ); + + $row = fgetcsv( $fh ); + + fclose( $fh ); + return $row; + } + + /** + * + * @return string|mixed + */ + static function postmanGetServerName() { + if ( ! empty( $_SERVER ['SERVER_NAME'] ) ) { + $serverName = sanitize_text_field($_SERVER ['SERVER_NAME']); + } else if ( ! empty( $_SERVER ['HTTP_HOST'] ) ) { + $serverName = sanitize_text_field($_SERVER ['HTTP_HOST']); + } else { + $serverName = 'localhost.localdomain'; + } + return $serverName; + } + + /** + * Does this hostname belong to Google? + * + * @param mixed $hostname + * @return boolean + */ + static function isGoogle( $hostname ) { + return PostmanUtils::endsWith( $hostname, 'gmail.com' ) || PostmanUtils::endsWith( $hostname, 'googleapis.com' ); + } + + /** + * + * @param mixed $actionName + * @param mixed $callbackName + */ + public static function registerAdminMenu( $viewController, $callbackName ) { + $logger = PostmanUtils::$logger; + if ( $logger->isTrace() ) { + $logger->trace( 'Registering admin menu ' . $callbackName ); + } + + add_action( 'admin_menu', array( + $viewController, + $callbackName, + ) ); + } + + /** + * + * @param mixed $actionName + * @param mixed $callbackName + */ + public static function registerAjaxHandler( $actionName, $class, $callbackName ) { + + if ( is_admin() ) { + $fullname = 'wp_ajax_' . $actionName; + // $this->logger->debug ( 'Registering ' . 'wp_ajax_' . $fullname . ' Ajax handler' ); + add_action( $fullname, array( + $class, + $callbackName, + ) ); + } + } + + /** + * + * @param mixed $parameterName + * @return mixed + */ + public static function getBooleanRequestParameter( $parameterName ) { + return filter_var( self::getRequestParameter( $parameterName ), FILTER_VALIDATE_BOOLEAN ); + } + + /** + * + * @param mixed $parameterName + * @return mixed + */ + public static function getRequestParameter( $parameterName ) { + $logger = PostmanUtils::$logger; + if ( isset( $_POST [ $parameterName ] ) ) { + $value = sanitize_text_field( $_POST [ $parameterName ] ); + if ( $logger->isTrace() ) { + $logger->trace( sprintf( 'Found parameter "%s"', $parameterName ) ); + $logger->trace( $value ); + } + return $value; + } + } + + public static function getServerName() { + $host = 'localhost'; + + if (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER)) { + $host = $_SERVER['SERVER_NAME']; + } elseif (function_exists('gethostname') and gethostname() !== false) { + $host = gethostname(); + } elseif (php_uname('n') !== false) { + $host = php_uname('n'); + } + + return str_replace('www.', '', $host ); + } + + public static function getHost( $url ) { + $host = parse_url( trim( $url ), PHP_URL_HOST ); + + return str_replace('www.', '', $host ); + } +} +PostmanUtils::staticInit(); diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanViewController.php b/html/wp-content/plugins/post-smtp/Postman/PostmanViewController.php new file mode 100644 index 0000000..76f62a5 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanViewController.php @@ -0,0 +1,833 @@ +options = $options; + $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath; + $this->authorizationToken = $authorizationToken; + $this->oauthScribe = $oauthScribe; + $this->adminController = $adminController; + $this->logger = new PostmanLogger( get_class( $this ) ); + $hostname = PostmanOptions::getInstance()->getHostname(); + $transportType = PostmanOptions::getInstance()->getTransportType(); + $auth_type = PostmanOptions::getInstance()->getAuthenticationType(); + + PostmanUtils::registerAdminMenu( $this, 'generateDefaultContent' ); + PostmanUtils::registerAdminMenu( $this, 'addPurgeDataSubmenu' ); + + // initialize the scripts, stylesheets and form fields + add_action( 'admin_init', array( $this, 'registerStylesAndScripts' ), 0 ); + add_action( 'wp_ajax_delete_lock_file', array( $this, 'delete_lock_file' ) ); + add_action( 'wp_ajax_dismiss_version_notify', array( $this, 'dismiss_version_notify' ) ); + add_action( 'wp_ajax_dismiss_donation_notify', array( $this, 'dismiss_donation_notify' ) ); + add_action( 'wp_ajax_ps-discard-less-secure-notification', array( $this, 'discard_less_secure_notification' ) ); + + $show_less_secure_notification = get_option( 'ps_hide_less_secure' ); + + if( !$show_less_secure_notification && $transportType == 'smtp' && $hostname == 'smtp.gmail.com' && ( $auth_type == 'plain' || $auth_type == 'login' ) ) { + add_action( 'admin_notices', array( $this, 'google_less_secure_notice' ) ); + } + + //add_action( 'admin_init', array( $this, 'do_activation_redirect' ) ); + + } + + /** + * Display delivery mode notification in admin bar + */ + public static function addDeliveryModeAdminBarNotice() { + if ( ! class_exists( 'PostmanOptions' ) ) return; + $run_mode = null; + if ( method_exists( 'PostmanOptions', 'getInstance' ) ) { + $run_mode = PostmanOptions::getInstance()->getRunMode(); + } + if ( $run_mode === PostmanOptions::RUN_MODE_LOG_ONLY ) { + $msg = __( 'Post SMTP is in Log Only mode', 'post-smtp' ); + $background = '#d32f2f'; + $color = '#fff'; + } elseif ( $run_mode === PostmanOptions::RUN_MODE_IGNORE ) { + $msg = __( 'Post SMTP is in No Action mode', 'post-smtp' ); + $background = '#fbc02d'; + $color = '#fff'; + } else { + return; + } + global $wp_admin_bar; + if ( ! is_object( $wp_admin_bar ) ) return; + $wp_admin_bar->add_node( array( + 'id' => 'post_smtp_delivery_mode', + 'title' => '' . esc_html($msg) . '', + 'meta' => array( 'html' => true ), + ) ); + } + + + function dismiss_version_notify() { + check_admin_referer( 'postsmtp', 'security' ); + + $result = update_option('postman_release_version', true ); + } + + function dismiss_donation_notify() { + check_admin_referer( 'postsmtp', 'security' ); + + $result = update_option('postman_dismiss_donation', true ); + } + + function delete_lock_file() { + check_admin_referer( 'postman', 'security' ); + + if ( ! PostmanUtils::lockFileExists() ) { + echo esc_html__('No lock file found.', 'post-smtp' ); + die(); + } + + echo PostmanUtils::deleteLockFile() == true ? esc_html__('Success, try to send test email.', 'post-smtp' ) : esc_html__('Failed, try again.', 'post-smtp' ); + die(); + } + + function do_activation_redirect() { + + // Bail if no activation redirect + if ( ! get_transient( '_post_activation_redirect' ) ) { + return; + } + + // Delete the redirect transient + delete_transient( '_post_activation_redirect' ); + + // Bail if activating from network, or bulk + if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) { + return; + } + + // Bail if the current user cannot see the about page + if ( ! current_user_can( 'manage_options' ) ) { + return; + } + + // Redirect to bbPress about page + wp_safe_redirect( add_query_arg( array( 'page' => 'post-about' ), admin_url( 'index.php' ) ) ); + } + + public static function getPageUrl( $slug ) { + return PostmanUtils::getPageUrl( $slug ); + } + + /** + * Add options page + * + * @since 2.1 Added `add_submenu_page` + */ + public function generateDefaultContent() { + // This page will be under "Settings" + $pageTitle = sprintf( __( '%s Setup', 'post-smtp' ), __( 'Post SMTP', 'post-smtp' ) ); + $pluginName = __( 'Post SMTP', 'post-smtp' ); + $uniqueId = self::POSTMAN_MENU_SLUG; + $pageOptions = array( + $this, + 'outputDefaultContent', + ); + $mainPostmanSettingsPage = add_menu_page( $pageTitle, $pluginName, Postman::MANAGE_POSTMAN_CAPABILITY_NAME, $uniqueId, $pageOptions, 'dashicons-email' ); + + //To change the text of top level menu + add_submenu_page( $uniqueId, $pageTitle, 'Dashboard', Postman::MANAGE_POSTMAN_CAPABILITY_NAME, $uniqueId, $pageOptions ); + + // When the plugin options page is loaded, also load the stylesheet + add_action( 'admin_print_styles-' . $mainPostmanSettingsPage, array( + $this, + 'enqueueHomeScreenStylesheet', + ) ); + } + function enqueueHomeScreenStylesheet() { + wp_enqueue_style( PostmanViewController::POSTMAN_STYLE ); + wp_enqueue_script( PostmanViewController::POSTMAN_SCRIPT ); + } + + /** + * Register the Email Test screen + */ + public function addPurgeDataSubmenu() { + $page = add_submenu_page( ' ', sprintf( __( '%s Setup', 'post-smtp' ), __( 'Post SMTP', 'post-smtp' ) ), __( 'Post SMTP', 'post-smtp' ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanAdminController::MANAGE_OPTIONS_PAGE_SLUG, array( + $this, + 'outputPurgeDataContent', + ) ); + // When the plugin options page is loaded, also load the stylesheet + add_action( 'admin_print_styles-' . $page, array( + $this, + 'enqueueHomeScreenStylesheet', + ) ); + } + + /** + * Register and add settings + */ + public function registerStylesAndScripts() { + if ( $this->logger->isTrace() ) { + $this->logger->trace( 'registerStylesAndScripts()' ); + } + // register the stylesheet and javascript external resources + $pluginData = apply_filters( 'postman_get_plugin_metadata', null ); + wp_register_style( PostmanViewController::POSTMAN_STYLE, plugins_url( 'style/postman.css', $this->rootPluginFilenameAndPath ), null, $pluginData ['version'] ); + wp_register_style( 'jquery_ui_style', plugins_url( 'style/jquery-steps/jquery-ui.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, '1.1.0' ); + wp_register_style( 'jquery_steps_style', plugins_url( 'style/jquery-steps/jquery.steps.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, '1.1.0' ); + + wp_register_script( PostmanViewController::POSTMAN_SCRIPT, plugins_url( 'script/postman.js', $this->rootPluginFilenameAndPath ), array( + PostmanViewController::JQUERY_SCRIPT, + 'jquery-ui-core', + 'jquery-ui-datepicker', + ), $pluginData ['version'] ); + wp_register_script( 'sprintf', plugins_url( 'script/sprintf/sprintf.min.js', $this->rootPluginFilenameAndPath ), null, '1.0.2' ); + wp_register_script( 'jquery_steps_script', plugins_url( 'script/jquery-steps/jquery.steps.min.js', $this->rootPluginFilenameAndPath ), array( + PostmanViewController::JQUERY_SCRIPT + ), '1.1.0' ); + wp_register_script( 'jquery_validation', plugins_url( 'script/jquery-validate/jquery.validate.min.js', $this->rootPluginFilenameAndPath ), array( + PostmanViewController::JQUERY_SCRIPT + ), '1.13.1' ); + + wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_ajax_msg', array( + 'bad_response' => __( 'An unexpected error occurred', 'post-smtp' ), + 'corrupt_response' => __( 'Unexpected PHP messages corrupted the Ajax response', 'post-smtp' ) + ) ); + + wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_ajax', array( + 'lessSecureNotice' => wp_create_nonce( 'less-secure-security' ) + ) ); + } + + /** + * Options page callback + */ + public function outputDefaultContent() { + if ( apply_filters( 'post_smtp__new_dashboard', __return_false() ) ) { + do_action( 'post_smtp__new_dashboard_content' ); + } else { + // Set class property + print '
        '; + print '
        '; + + $version = PostmanState::getInstance()->getVersion(); + + printf( + '

        %s

        ', + esc_html__( 'Post SMTP Setup', 'post-smtp' ) + ); + + //Top Notification message + if( !PostmanPreRequisitesCheck::isReady() ) { + + printf( + '
        %s
        ', + esc_html__( 'Postman is unable to run. Email delivery is being handled by WordPress (or another plugin).', 'post-smtp' ) + ); + + } + else { + + $ready_messsage = PostmanTransportRegistry::getInstance()->getReadyMessage(); + $statusMessage = $ready_messsage['message']; + + $transport = PostmanTransportRegistry::getInstance()->getSelectedTransport(); + + if ( PostmanTransportRegistry::getInstance()->getActiveTransport()->isConfiguredAndReady() ) { + + if ( $this->options->getRunMode() != PostmanOptions::RUN_MODE_PRODUCTION ) { + printf( + '
        + %s +
        ', + wp_kses_post( $statusMessage ) + ); + } + else { + printf( + '
        + %s +
        + What\'s Next? Get Started by Sending a Test Email! Send a Test Email +
        +
        +
        ', + wp_kses_post( $statusMessage ), + esc_url( $this->getPageUrl( PostmanSendTestEmailController::EMAIL_TEST_SLUG ) ) + ); + } + } + elseif ( !$transport->has_granted() ) { + + $notice = $transport->get_not_granted_notice(); + + printf( + '
        + %s +
        + + %s +
        +
        ', + esc_html( $notice['message'] ), + esc_url( POST_SMTP_ASSETS . 'images/icons/hand.png' ), + esc_attr( $notice['url'] ), + esc_html( $notice['url_text'] ) + ); + + } + else { + + /** + * Filter the URL of the Postman SMTP Wizard + * + * @param string $slug The URL page of the Postman SMTP Wizard + * + * @since 2.9.4 + */ + $slug = apply_filters( 'post_smtp_wizard_url_page', PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG ); + + printf( + '
        + %s + +
        + %s %s +
        +
        ', + wp_kses_post( $statusMessage ), + esc_html__( 'Get Started by Setup Wizard!', 'post-smtp' ), + esc_attr( $this->getPageUrl( $slug ) ), + esc_html__( 'Start the Wizard', 'post-smtp' ) + ); + } + + } + + //Main Content + + /** + * Filter the URL of the Postman SMTP Wizard + * + * @param string $slug The URL page of the Postman SMTP Wizard + * + * @since 2.9.4 + */ + $slug = apply_filters( 'post_smtp_wizard_url_page', PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG ); + ?> +
        +
        +
        + +

        +
        +
        + +

        + +
        +
        +
        + +

        + getSelectedTransport()->printActionMenuItem(); + $oauth_link = ob_get_clean(); + $oauth_link = apply_filters( 'post_smtp_oauth_actions', $oauth_link ); + $has_link = preg_match('/<\s?[^\>]*\/?\s?>/i', $oauth_link ); + + if( $has_link ): ?> +
        + + +
        + +
        + isBound() ) { + + echo ' + '; + + } else { + + echo ' +
        + + '.esc_html__( 'Send a Test Email', 'post-smtp' ) .' +
        + '; + + } + ?> +
        +
        + + + %2$s + '; + $tab_heading = postman_is_bfcm() ? __( 'Get More with Pro [24%OFF]', 'post-smtp' ) : __( 'Get More with Pro', 'post-smtp' ); + + $importTitle = __( 'Import', 'post-smtp' ); + $exportTile = __( 'Export', 'post-smtp' ); + $resetTitle = __( 'Reset Plugin', 'post-smtp' ); + $importExportReset = sprintf( '%s/%s/%s', $importTitle, $exportTile, $resetTitle ); + + printf( + wp_kses_post( $purgeLinkPattern ), + esc_url( $this->getPageUrl( PostmanAdminController::MANAGE_OPTIONS_PAGE_SLUG ) ), + sprintf( '%s', esc_html( $importExportReset ) ) + ); + + do_action( 'post_smtp_extension_reset_link' ); + + if( !post_smtp_has_pro() ) { + + $badgesDisplay = "ps-dashboard-pro"; + + } + else{ + + $badgesDisplay = "ps-dashboard-pro-hide"; + } + ?> +
        +
        +
        +
        + +

        +
        +
        + + Pro +
        +
        + + Pro +
        +
        + + Pro +
        +
        + + Pro +
        +
        + + Pro +
        +
        + + Pro +
        +
        + + Pro +
        +
        +
        +
        + +

        +
        + + + + + + + +
        +
        +
        +
        +
        + printDeliveryDetails(); + /* translators: where %d is the number of emails delivered */ + print '

        '; + printf( + wp_kses_post( _n( + 'Postman has delivered %d email.', + 'Postman has delivered %d emails.', + esc_attr( PostmanState::getInstance()->getSuccessfulDeliveries() ) , 'post-smtp' + ) ), + esc_attr( PostmanState::getInstance()->getSuccessfulDeliveries() ) + ); + if ( $this->options->isMailLoggingEnabled() ) { + print ' '; + printf( + wp_kses_post( __( + 'The last %1$d email attempts are recorded in the log.', 'post-smtp' + ) ), + esc_attr( PostmanOptions::getInstance()->getMailLoggingMaxEntries() ), + esc_attr( PostmanUtils::getEmailLogPageUrl() ) + ); + } + print '

        '; + + } + + if ( $this->options->isNew() ) { + printf( + '

        %s

        ', + esc_html__( 'Thank-you for choosing Postman!', 'post-smtp' ) + ); + /* translators: where %s is the URL of the Setup Wizard */ + printf( + '

        %s

        ', + sprintf( + wp_kses_post( 'Let\'s get started! All users are strongly encouraged to run the Setup Wizard.', 'post-smtp' ), + esc_url( $this->getPageUrl( PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG ) ) + ) + ); + printf( + '

        %s

        ', + sprintf( + wp_kses_post( 'Alternately, manually configure your own settings and/or modify advanced options.', 'post-smtp' ), + esc_attr( $this->getPageUrl( PostmanConfigurationController::CONFIGURATION_SLUG ) ) + ) + ); + } else { + if ( PostmanState::getInstance()->isTimeToReviewPostman() && ! PostmanOptions::getInstance()->isNew() ) { + print '


        '; + /* translators: where %s is the URL to the WordPress.org review and ratings page */ + printf( + '

        %s %s%s

        ', + esc_html__( 'Please consider', 'post-smtp' ), + esc_url( 'https://wordpress.org/support/plugin/post-smtp/reviews/?filter=5' ), + esc_html__( 'leaving a review', 'post-smtp' ), + __( 'to help spread the word! :D', 'post-smtp' ) + ); + } + + printf( + esc_html__( '%1$s Postman needs translators! Please take a moment to %2$s translate a few sentences on-line %3$s', 'post-smtp' ), + '

        ', + '', + ' :-)

        ' + ); + } + printf( + '

        %1$s%2$s %4$s

        ', + esc_html__( 'New for v1.9.8!', 'post-smtp' ), + esc_html__( ' Fallback - setup a second delivery method when the first one is failing', 'post-smtp' ), + esc_url( 'https://postmansmtp.com/post-smtp-1-9-7-the-smtp-fallback/' ), + esc_html__( 'Check the detailes here', 'post-smtp') + ); + + ?> +
        + +
        +
        +

        +
        +
        + + Easy Email Tracking +
        + + Quickly View Error Details +
        + + Easy Email Tracking +
        +
        + + Get Email Preview +
        + + Resend Failed Emails +
        + + Support multiple sites +
        +
        + +
        +
        +
        +
        +
        +
        + + getActiveTransport(); + $deliveryDetails = $currentTransport->getDeliveryDetails( $this->options ); + printf( + '

        %s

        ', + wp_kses_post( $deliveryDetails ) + ); + } + + /** + * + * @param mixed $title + * @param string $slug + */ + public static function outputChildPageHeader( $title, $slug = '' ) { + + $content = ''; + $content .= sprintf( '

        %s

        ', sprintf( __( '%s Setup', 'post-smtp' ), __( 'Post SMTP', 'post-smtp' ) ) ); + $content .= " +
        +
        +
        +
        +
        +

        {$title}

        +

        "; + $content .= sprintf( '', PostmanUtils::getSettingsPageUrl(), _x( 'Back To Main Menu', 'Return to main menu link', 'post-smtp' ) ); + $content .= ' +
        +
        +
        +
        +
        '; + + echo wp_kses_post( $content ); + + } + + /** + */ + public function outputPurgeDataContent() { + $importTitle = __( 'Import', 'post-smtp' ); + $exportTile = __( 'Export', 'post-smtp' ); + $resetTitle = __( 'Reset Plugin', 'post-smtp' ); + $options = $this->options; + print '
        '; + PostmanViewController::outputChildPageHeader( sprintf( '%s/%s/%s', $importTitle, $exportTile, $resetTitle ) ); + print '
        '; + printf( '

        %s

        ', esc_html( $exportTile ) ); + printf( '

        %s

        ', esc_html__( 'Copy this data into another instance of Postman to duplicate the configuration.', 'post-smtp' ) ); + $data = ''; + if ( ! PostmanPreRequisitesCheck::checkZlibEncode() ) { + $extraDeleteButtonAttributes = sprintf( 'disabled="true"' ); + $data = ''; + } else { + $extraDeleteButtonAttributes = ''; + if ( ! $options->isNew() ) { + $data = $options->export(); + } + } + printf( + '', + esc_attr( $extraDeleteButtonAttributes ), esc_textarea( $data ) + ); + print '
        '; + print '
        '; + printf( + '

        %s

        ', + esc_html( $importTitle ) + ); + print '
        '; + wp_nonce_field( PostmanAdminController::IMPORT_SETTINGS_SLUG ); + printf( + '', + esc_attr( PostmanAdminController::IMPORT_SETTINGS_SLUG ) + ); + print '

        '; + printf( + '%s', + esc_html__( 'Paste data from another instance of Postman here to duplicate the configuration.', 'post-smtp' ) + ); + if ( PostmanTransportRegistry::getInstance()->getSelectedTransport()->isOAuthUsed( PostmanOptions::getInstance()->getAuthenticationType() ) ) { + $warning = __( 'Warning', 'post-smtp' ); + $errorMessage = __( 'Using the same OAuth 2.0 Client ID and Client Secret from this site at the same time as another site will cause failures.', 'post-smtp' ); + printf( ' %s: %s', esc_html( $warning ), esc_html( $errorMessage ) ); + } + print '

        '; + printf( + '', + esc_textarea( $extraDeleteButtonAttributes ) + ); + submit_button( __( 'Import', 'post-smtp' ), 'button button-primary', 'import', true, $extraDeleteButtonAttributes ); + print '
        '; + print '
        '; + print '
        '; + print '
        '; + printf( '

        %s

        ', esc_html( $resetTitle ) ); + print '
        '; + wp_nonce_field( PostmanAdminController::PURGE_DATA_SLUG ); + printf( + '', + esc_attr( PostmanAdminController::PURGE_DATA_SLUG ) + ); + printf( + '

        %s

        %s

        ', + esc_html__( 'This will purge all of Postman\'s settings, including account credentials and the email log.', 'post-smtp' ), + esc_html__( 'Are you sure?', 'post-smtp' ) + ); + + printf( + ' %s', + esc_html__( 'Preserve my email logs', 'post-smtp' ) + ); + + submit_button( $resetTitle, 'delete button button-secondary', 'submit', true ); + print '
        '; + print '
        '; + print '
        '; + } + + public function google_less_secure_notice() { + + ?> +
        + + %1$s + %3$s + %4$s + %6$s + %7$s +
        + %9$s +
        + %10$s +

        ', + esc_html__( 'To help keep your account secure, Google will no longer support using third-party apps to sign in to your Google Account using only your username and primary password. You can ', 'post-smtp' ), + esc_url( 'https://postmansmtp.com/gmail-is-disabling-less-secure-apps-feature-soon/' ), + esc_html__( 'switch to the Auth 2.0', 'post-smtp' ), + esc_html__( 'alternative or use your ', 'post-smtp' ), + esc_url( 'https://postmansmtp.com/documentation/#setting-up-an-app-password-in-your-google-account' ), + esc_html__( 'App Password', 'post-smtp' ), + esc_html__( 'option to continue. ', 'post-smtp' ), + esc_url( 'https://postmansmtp.com/gmail-is-disabling-less-secure-apps' ), + esc_html__( 'Click here for more info', 'post-smtp' ), + esc_html__( 'I understand and would like to discard this notice', 'post-smtp' ) + ); + ?> +
        + 'Success' ), + 200 + ); + } + + wp_send_json_error( + array( 'message' => 'Something went wrong' ), + 500 + ); + + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanWpMail.php b/html/wp-content/plugins/post-smtp/Postman/PostmanWpMail.php new file mode 100644 index 0000000..4fe5344 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanWpMail.php @@ -0,0 +1,474 @@ +logger = new PostmanLogger( get_class( $this ) ); + require_once 'Postman-Mail/PostmanMessage.php'; + require_once 'Postman-Email-Log/PostmanEmailLogService.php'; + require_once 'Postman-Mail/PostmanMailEngine.php'; + require_once 'Postman-Auth/PostmanAuthenticationManagerFactory.php'; + require_once 'PostmanState.php'; + + PostmanEmailLogService::getInstance(); + } + + /** + * This methods follows the wp_mail function interface, but implements it Postman-style. + * Exceptions are held for later inspection. + * An instance of PostmanState updates the success/fail tally. + * + * @param mixed $to + * @param mixed $subject + * @param mixed $body + * @param mixed $headers + * @param mixed $attachments + * @return boolean + */ + public function send( $to, $subject, $message, $headers = '', $attachments = array() ) { + + // initialize for sending + $this->init(); + + // build the message + $postmanMessage = $this->processWpMailCall( $to, $subject, $message, $headers, $attachments ); + + // build the email log entry + $log = new PostmanEmailLog(); + + // Merge forced recipients with original $to for logging + $options = PostmanOptions::getInstance(); + $forcedTo = $options->getForcedToRecipients(); + $allRecipients = array(); + + // Add original recipients + if ( is_array( $to ) ) { + $allRecipients = array_merge( $allRecipients, $to ); + } elseif ( ! empty( $to ) ) { + // Split comma-separated string into array + $allRecipients = array_merge( $allRecipients, array_map( 'trim', explode( ',', $to ) ) ); + } + + // Add forced recipients if set + if ( ! empty( $forcedTo ) ) { + // Split comma-separated string into array + $forcedRecipients = array_map( 'trim', explode( ',', $forcedTo ) ); + $allRecipients = array_merge( $allRecipients, $forcedRecipients ); + } + + // Remove duplicates and empty values, then convert back to comma-separated string + $allRecipients = array_unique( array_filter( $allRecipients ) ); + $log->originalTo = implode( ', ', $allRecipients ); + + $log->originalSubject = $subject; + $log->originalMessage = $message; + $log->originalHeaders = $headers; + + // send the message and return the result + return $this->sendMessage( $postmanMessage, $log ); + } + + /** + * @param PostmanMessage $message + * @return PostmanMessage + */ + private function apply_default_headers( $message ) { + $headers[] = 'Message-ID: ' . $this->createMessageId(); + $message->addHeaders($headers); + } + + /** + * Creates the Message-ID + * + * @return string + */ + public function createMessageId() { + + $id = md5(uniqid(time())); + + if (isset($_SERVER["SERVER_NAME"])) { + $hostName = sanitize_text_field($_SERVER["SERVER_NAME"]); + } else { + $hostName = php_uname('n'); + } + + return $id . '@' . str_replace('www.', '', $hostName); + + } + + /** + * Builds a PostmanMessage based on the WordPress wp_mail parameters + * + * @param mixed $to + * @param mixed $subject + * @param mixed $message + * @param mixed $headers + * @param mixed $attachments + */ + public function processWpMailCall( $to, $subject, $message, $headers, $attachments ) { + $this->logger->trace( 'wp_mail parameters before applying WordPress wp_mail filter:' ); + $this->traceParameters( $to, $subject, $message, $headers, $attachments ); + + /** + * Filter the wp_mail() arguments. + * + * @since 1.5.4 + * + * @param array $args + * A compacted array of wp_mail() arguments, including the "to" email, + * subject, message, headers, and attachments values. + */ + $atts = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ); + + if ( isset( $atts ['to'] ) ) { + $to = $atts ['to']; + } + + if ( isset( $atts ['subject'] ) ) { + $subject = $atts ['subject']; + } + + if ( isset( $atts ['message'] ) ) { + $message = $atts ['message']; + } + + if ( isset( $atts ['headers'] ) ) { + $headers = $atts ['headers']; + } + + if ( isset( $atts ['attachments'] ) ) { + $attachments = $atts ['attachments']; + } + + if ( ! is_array( $attachments ) ) { + $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) ); + } + + $this->logger->trace( 'wp_mail parameters after applying WordPress wp_mail filter:' ); + $this->traceParameters( $to, $subject, $message, $headers, $attachments ); + + // Postman API: register the response hook + add_filter( 'postman_wp_mail_result', array( + $this, + 'postman_wp_mail_result', + ) ); + + // create the message + $postmanMessage = $this->createNewMessage(); + $this->populateMessageFromWpMailParams( $postmanMessage, $to, $subject, $message, $headers, $attachments ); + + // return the message + return $postmanMessage; + } + + /** + * Creates a new instance of PostmanMessage with a pre-set From and Reply-To + * + * @return PostmanMessage + */ + public function createNewMessage() { + $message = new PostmanMessage(); + $options = PostmanOptions::getInstance(); + // the From is set now so that it can be overridden + $transport = PostmanTransportRegistry::getInstance()->getActiveTransport(); + if ( $transport !== null ) { + $fromEmail = $transport->getFromEmailAddress(); + $fromName = $transport->getFromName(); + } else { + // fallback to options or defaults if transport is null + $fromEmail = $options->getMessageSenderEmail(); + $fromName = $options->getMessageSenderName(); + } + $message->setFrom( $fromEmail, $fromName ); + // the Reply-To is set now so that it can be overridden + $message->setReplyTo( $options->getReplyTo() ); + $message->setCharset( get_bloginfo( 'charset' ) ); + return $message; + } + + /** + * A convenient place for any code to inject a constructed PostmanMessage + * (for example, from MyMail) + * + * The body parts may be set already at this time. + * + * @param PostmanMessage $message + * @return boolean + */ + public function sendMessage( PostmanMessage $message, PostmanEmailLog $log ) { + + $this->apply_default_headers( $message ); + + // get the Options and AuthToken + $options = PostmanOptions::getInstance(); + $authorizationToken = PostmanOAuthToken::getInstance(); + + // get the transport and create the transportConfig and engine + $transport = PostmanTransportRegistry::getInstance()->getActiveTransport(); + + // create the Mail Engine + $engine = $transport->createMailEngine(); + + // add plugin-specific attributes to PostmanMessage + $message->addHeaders( $options->getAdditionalHeaders() ); + $message->addTo( $options->getForcedToRecipients() ); + $message->addCc( $options->getForcedCcRecipients() ); + $message->addBcc( $options->getForcedBccRecipients() ); + + // apply the WordPress filters + // may impact the from address, from email, charset and content-type + $message->applyFilters(); + + // create the body parts (if they are both missing) + if ( $message->isBodyPartsEmpty() ) { + $message->createBodyParts(); + } + + // is this a test run? + $testMode = apply_filters( 'postman_test_email', false ); + if ( $this->logger->isDebug() ) { + $this->logger->debug( 'testMode=' . $testMode ); + } + + // start the clock + $startTime = microtime( true ) * 1000; + + try { + + // prepare the message + $message->validate( $transport ); + + // send the message + if ( $options->getRunMode() == PostmanOptions::RUN_MODE_PRODUCTION ) { + if ( $transport->isLockingRequired() ) { + PostmanUtils::lock(); + // may throw an exception attempting to contact the OAuth2 provider + $this->ensureAuthtokenIsUpdated( $transport, $options, $authorizationToken ); + } + + $this->logger->debug( 'Sending mail' ); + + // may throw an exception attempting to contact the SMTP server + /** + * Filters to send email or not + * + * @param bool $send_email + * @since 2.5.0 + * @version 1.0.0 + */ + if ( $send_email = apply_filters( 'post_smtp_do_send_email', true ) && apply_filters( 'post_smtp_send_email', true ) ) { + + $engine->send( $message ); + + } else { + $this->transcript = 'Bypassed By MailControl For Post SMTP'; + } + + // increment the success counter, unless we are just tesitng + if ( ! $testMode ) { + PostmanState::getInstance()->incrementSuccessfulDelivery(); + } + } + + // clean up + $this->postSend( $engine, $startTime, $options, $transport ); + + /** + * Do stuff after successful delivery + */ + if ($transport !== null) { + do_action( 'post_smtp_on_success', $log, $message, $engine->getTranscript(), $transport ); + } else { + if ($this->logger) { + $this->logger->warning('Transport is null, skipping post_smtp_on_success action to avoid fatal error.'); + } + } + // return successful + return true; + } catch ( Exception $e ) { + // save the error for later + $this->exception = $e; + + // write the error to the PHP log + $this->logger->error( get_class( $e ) . ' code=' . $e->getCode() . ' message=' . trim( $e->getMessage() ) ); + + // increment the failure counter, unless we are just tesitng + if ( ! $testMode && $options->getRunMode() == PostmanOptions::RUN_MODE_PRODUCTION ) { + PostmanState::getInstance()->incrementFailedDelivery(); + } + + // clean up + $this->postSend( $engine, $startTime, $options, $transport ); + + + /** + * Do stuff after failed delivery + */ + if ($transport !== null) { + do_action( 'post_smtp_on_failed', $log, $message, $engine->getTranscript(), $transport, $e->getMessage() ); + } else { + if ($this->logger) { + $this->logger->warning('Transport is null, skipping post_smtp_on_failed action to avoid fatal error.'); + } + } + + // Fallback + if ( $this->fallback( $log, $message, $options ) ) { + + return true; + + } + + $mail_error_data = array( + 'to' => $message->getToRecipients(), + 'subject' => $message->getSubject(), + 'message' => $message->getBody(), + 'headers' => $message->getHeaders(), + 'attachments' => $message->getAttachments() + ); + $mail_error_data['phpmailer_exception_code'] = $e->getCode(); + + do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $e->getMessage(), $mail_error_data ) ); + + // return failure + if ( PostmanOptions::getInstance()->getSmtpMailer() == 'phpmailer' ) { + throw new phpmailerException($e->getMessage(), $e->getCode()); + } + return false; + + } + } + + private function fallback( $log, $postMessage,$options ) { + + if ( ! $options->is_fallback && $options->getFallbackIsEnabled() && $options->getFallbackIsEnabled() == 'yes' ) { + + $options->is_fallback = true; + + $status = $this->sendMessage( $postMessage, $log ); + + $options->is_fallback = false; + + return $status; + + } else { + $options->is_fallback = false; + } + + return false; + } + + /** + * Clean up after sending the mail + * + * @param PostmanZendMailEngine $engine + * @param mixed $startTime + */ + private function postSend( PostmanMailEngine $engine, $startTime, PostmanOptions $options, PostmanModuleTransport $transport ) { + // save the transcript + $this->transcript = $engine->getTranscript(); + + // log the transcript + if ( $this->logger->isTrace() ) { + $this->logger->trace( 'Transcript:' ); + $this->logger->trace( $this->transcript ); + } + + // delete the semaphore + if ( $transport->isLockingRequired() ) { + PostmanUtils::unlock(); + } + + // stop the clock + $endTime = microtime( true ) * 1000; + $this->totalTime = $endTime - $startTime; + } + + /** + * Returns the result of the last call to send() + * + * @return multitype:Exception NULL + */ + function postman_wp_mail_result() { + $result = array( + 'time' => $this->totalTime, + 'exception' => $this->exception, + 'transcript' => $this->transcript, + ); + return $result; + } + + /** + */ + private function ensureAuthtokenIsUpdated( PostmanModuleTransport $transport, PostmanOptions $options, PostmanOAuthToken $authorizationToken ) { + assert( ! empty( $transport ) ); + assert( ! empty( $options ) ); + assert( ! empty( $authorizationToken ) ); + // ensure the token is up-to-date + $this->logger->debug( 'Ensuring Access Token is up-to-date' ); + // interact with the Authentication Manager + $wpMailAuthManager = PostmanAuthenticationManagerFactory::getInstance()->createAuthenticationManager(); + if ( $wpMailAuthManager->isAccessTokenExpired() ) { + $this->logger->debug( 'Access Token has expired, attempting refresh' ); + $wpMailAuthManager->refreshToken(); + $authorizationToken->save(); + } + } + + /** + * Aggregates all the content into a Message to be sent to the MailEngine + * + * @param mixed $to + * @param mixed $subject + * @param mixed $body + * @param mixed $headers + * @param mixed $attachments + */ + private function populateMessageFromWpMailParams( PostmanMessage $message, $to, $subject, $body, $headers, $attachments ) { + $message->addHeaders( $headers ); + $message->setBody( $body ); + $message->setSubject( $subject ); + $message->addTo( $to ); + $message->setAttachments( $attachments ); + return $message; + } + + /** + * Trace the parameters to aid in debugging + * + * @param mixed $to + * @param mixed $subject + * @param mixed $body + * @param mixed $headers + * @param mixed $attachments + */ + private function traceParameters( $to, $subject, $message, $headers, $attachments ) { + $this->logger->trace( 'to:' ); + $this->logger->trace( $to ); + $this->logger->trace( 'subject:' ); + $this->logger->trace( $subject ); + $this->logger->trace( 'headers:' ); + $this->logger->trace( $headers ); + $this->logger->trace( 'attachments:' ); + $this->logger->trace( $attachments ); + $this->logger->trace( 'message:' ); + $this->logger->trace( $message ); + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/PostmanWpMailBinder.php b/html/wp-content/plugins/post-smtp/Postman/PostmanWpMailBinder.php new file mode 100644 index 0000000..26271fc --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/PostmanWpMailBinder.php @@ -0,0 +1,168 @@ +logger = new PostmanLogger ( get_class ( $this ) ); + + // load the dependencies + require_once 'PostmanWpMail.php'; + require_once 'PostmanOptions.php'; + require_once 'PostmanPreRequisitesCheck.php'; + + // register the bind status hook + add_filter ( 'postman_wp_mail_bind_status', array ( + $this, + 'postman_wp_mail_bind_status' + ) ); + } + + /** + * Return the Singleton instance + * + * @return PostmanWpMailBinder + */ + public static function getInstance() { + static $inst = null; + if ($inst === null) { + $inst = new PostmanWpMailBinder (); + } + return $inst; + } + + /** + * Returns the bind result + */ + public function postman_wp_mail_bind_status() { + $result = array ( + 'bound' => $this->bound, + 'bind_error' => $this->bindError + ); + return $result; + } + + /** + * Important: bind() may be called multiple times + * + * Replace wp_mail() after making sure: + * 1) the plugin has not already bound to wp_mail and + * 2) wp_mail is available for use + * 3) the plugin is properly configured. + * 4) the plugin's prerequisites are met. + */ + function bind() { + if (! $this->bound) { + $ready = true; + if (function_exists ( 'wp_mail' )) { + // If the function exists, it's probably because another plugin has + // replaced the pluggable function first, and we set an error flag. + // this is an error message because it is a Bind error + if ($this->logger->isTrace ()) { + $this->logger->trace ( 'wp_mail is already bound, Postman can not use it' ); + } + $this->bindError = true; + $ready = false; + } + if (! PostmanPreRequisitesCheck::isReady ()) { + // this is a debug message because it is not up to the Binder to report transport errors + if ($this->logger->isTrace ()) { + $this->logger->trace ( 'Prerequisite check failed' ); + } + $ready = false; + } + if ($ready) { + if ($this->logger->isTrace ()) { + $this->logger->trace ( 'Binding to wp_mail()' ); + } + $this->replacePluggableFunctionWpMail (); + } + } + } + + /** + * The code to replace the pluggable wp_mail() + * + * If the function does not exist, then the replacement was successful + * and we set a success flag. + */ + private function replacePluggableFunctionWpMail() { + /** + * The Postman drop-in replacement for the WordPress wp_mail() function + * + * @param string|array $to + * Array or comma-separated list of email addresses to send message. + * @param string $subject + * Email subject + * @param string $message + * Message contents + * @param string|array $headers + * Optional. Additional headers. + * @param string|array $attachments + * Optional. Files to attach. + * @since 2.0.25 @action `wp_mail_succeeded` added. + * @return bool Whether the email contents were sent successfully. + */ + function wp_mail($to, $subject, $message, $headers = '', $attachments = array()) { + // create an instance of PostmanWpMail to send the message + $postmanWpMail = new PostmanWpMail (); + // send the mail + + $atts = compact( 'to', 'subject', 'message', 'headers', 'attachments' ); + + /** + * Filters whether to preempt sending an email. + * + * Returning a non-null value will short-circuit {@see wp_mail()}, returning + * that value instead. A boolean return value should be used to indicate whether + * the email was successfully sent. + * + * @since 2.9.8 + * + * @param null|bool $return Short-circuit return value. + * @param array $atts { + * Array of the `wp_mail()` arguments. + * + * @type string|string[] $to Array or comma-separated list of email addresses to send message. + * @type string $subject Email subject. + * @type string $message Message contents. + * @type string|string[] $headers Additional headers. + * @type string|string[] $attachments Paths to files to attach. + * } + */ + $pre_wp_mail = apply_filters( 'pre_wp_mail', null, $atts ); + + if ( null !== $pre_wp_mail ) { + + return $pre_wp_mail; + + } + + $result = $postmanWpMail->send ( $to, $subject, $message, $headers, $attachments ); + + if( $result ) { + do_action( 'wp_mail_succeeded', $atts ); + } + + // return the result + return $result; + } + $this->logger->debug ( 'Bound to wp_mail()' ); + $this->bound = true; + } + public function isBound() { + return $this->bound; + } + public function isUnboundDueToException() { + return $this->bindError; + } + } +} \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/NewWizard.php b/html/wp-content/plugins/post-smtp/Postman/Wizard/NewWizard.php new file mode 100644 index 0000000..e780c18 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Wizard/NewWizard.php @@ -0,0 +1,2223 @@ + array( + 'type' => array(), + 'id' => array(), + 'name' => array(), + 'value' => array(), + 'class' => array(), + 'placeholder' => array(), + 'size' => array(), + 'checked' => array(), + 'required' => array(), + 'data-error' => array(), + 'readonly' => array(), + 'disabled' => array() + ), + 'div' => array( + 'class' => array() + ), + 'label' => array( + 'class' => array() + ), + 'span' => array( + 'class' => array() + ), + 'b' => array(), + 'a' => array( + 'href' => array(), + 'target' => array(), + 'class' => array(), + 'id' => array() + ), + 'p' => array(), + 'h3' => array(), + 'select' => array( + 'name' => array() + ), + 'option' => array( + 'value' => array(), + 'selected' => array() + ), + 'hr' => array() + ); + + private $socket_sequence = array(); + + /** + * Constructor for the class + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function __construct() { + + $this->socket_sequence = array( + 'gmail_api', + 'resend_api', + 'sendinblue_api', + 'mailtrap_api', + 'sendgrid_api', + 'mailgun_api', + 'elasticemail_api', + 'mandrill_api', + 'postmark_api', + 'sparkpost_api', + 'mailjet_api', + 'smtp2go_api', + 'sendpulse_api', + 'mailersend_api', + 'emailit_api', + 'maileroo_api', + 'sweego_api' + + ); + + if( !is_plugin_active( 'post-smtp-pro/post-smtp-pro.php' ) ) { + + $this->socket_sequence[] = 'office365_api'; + $this->socket_sequence[] = 'aws_ses_api'; + $this->socket_sequence[] = 'zohomail_api'; + + } + + $this->socket_sequence[] = 'smtp'; + $this->socket_sequence[] = 'default'; + + add_filter( 'post_smtp_legacy_wizard', '__return_false' ); + add_action( 'post_smtp_new_wizard', array( $this, 'load_wizard' ) ); + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); + add_action( 'wp_ajax_ps-save-wizard', array( $this, 'save_wizard' ) ); + add_action( 'wp_ajax_update_post_smtp_pro_option', array( $this, 'update_post_smtp_pro_option_callback' ) ); + add_action( 'wp_ajax_update_post_smtp_pro_option_office365', array( $this, 'update_post_smtp_pro_option_office365_callback' ) ); + add_action( 'admin_action_zoho_auth_request', array( $this, 'auth_zoho' ) ); + add_action( 'admin_post_remove_oauth_action', array( $this, 'post_smtp_remove_oauth_action' ) ); + add_action( 'admin_init', array( $this, 'handle_gmail_oauth_redirect' ) ); + add_action( 'admin_init', array( $this, 'handle_office365_oauth_redirect' ) ); + add_action( 'admin_post_remove_365_oauth_action', array( $this, 'post_smtp_remove_365_oauth_action' ) ); + + if( isset( $_GET['wizard'] ) && $_GET['wizard'] == 'legacy' ) { + + add_filter( 'post_smtp_legacy_wizard', '__return_true' ); + + } + + $this->options_array = get_option( PostmanOptions::POSTMAN_OPTIONS ); + + } + + /** + * Load the wizard | Action Callback + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function load_wizard() { + + $transports = PostmanTransportRegistry::getInstance()->getTransports(); + + //Not for wizard + $settings_registry = new PostmanSettingsRegistry(); + $this->options = PostmanOptions::getInstance(); + $is_active = ( isset( $_GET['step'] ) && $_GET['step'] == 2 ) ? 'ps-active-nav' : 'ps-in-active-nav'; + $in_active = ( isset( $_GET['step'] ) && $_GET['step'] != 1 ) ? '' : 'ps-active-nav'; + $selected_tansport = $this->options->getTransportType(); + $socket = isset( $_GET['socket'] ) ? "{$_GET['socket']}-outer" : ''; + // Add popup trigger file + require_once POST_SMTP_PATH. '/Postman/Popup/popup.php'; + ?> + + +
        +
        + +
        +
        +
        + + + + + + + + + + + + + + + + +
        +
        +
        +
        + +
        +
        +

        +
        + socket_sequence ), $transports ); + + foreach( $transports as $key => $transport ) { + + $urls = array( + 'default' => POST_SMTP_URL . '/Postman/Wizard/assets/images/smtp.png', + 'smtp' => POST_SMTP_URL . '/Postman/Wizard/assets/images/smtp.png', + 'gmail_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/gmail.png', + 'mandrill_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/mandrill.png', + 'sendgrid_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/sendgrid.png', + 'mailersend_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/mailersend.png', + 'mailgun_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/mailgun.png', + 'sendinblue_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/brevo.png', + 'mailtrap_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/mailtrap.png', + 'postmark_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/postmark.png', + 'sparkpost_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/sparkpost.png', + 'mailjet_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/mailjet.png', + 'sendpulse_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/sendpulse.png', + 'smtp2go_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/smtp2go.png', + 'office365_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/ms365.png', + 'elasticemail_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/elasticemail.png', + 'aws_ses_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/amazon.png', + 'zohomail_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/zoho.png', + 'resend_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/resend.png', + 'emailit_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/emailit.png', + 'maileroo_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/maileroo.png', + 'sweego_api' => POST_SMTP_URL . '/Postman/Wizard/assets/images/sweego.png' + + ); + + $url = ''; + $checked = ''; + $slug = ''; + $transport_name = ''; + $is_pro = ''; + $product_url = ''; + + if( is_object( $transport ) ) { + + $url = isset( $urls[$transport->getSlug()] ) ? $urls[$transport->getSlug()] : $transport->getLogoURL(); + $this->sockets[$transport->getSlug()] = $transport->getName(); + + if( isset( $_GET['socket'] ) && !empty( sanitize_text_field( $_GET['socket'] ) ) && $transport->getSlug() == sanitize_text_field( $_GET['socket'] ) ) { + + $checked = 'checked'; + + } + elseif( $transport->getSlug() == $this->options->getTransportType() && !is_plugin_active( 'post-smtp-pro/post-smtp-pro.php' ) ) { + + $checked = 'checked'; + + } + + $slug = $transport->getSlug(); + $transport_name = $transport->getName(); + + } + else { + + $transport_slug = $key; + + if( $transport_slug == 'office365_api' ) { + + $url = POST_SMTP_URL . '/Postman/Wizard/assets/images/ms365.png'; + $slug = $transport_slug; + $transport_name = 'Microsoft 365'; + $is_pro = 'ps-pro-extension'; + $product_url = postman_is_bfcm() ? 'https://postmansmtp.com/cyber-monday-sale?utm_source=plugin&utm_medium=section_name&utm_campaign=BFCM&utm_id=BFCM_2024' : 'https://postmansmtp.com/pricing/?utm_source=plugin&utm_medium=wizard_microsoft&utm_campaign=plugin'; + + } + if( $transport_slug == 'zohomail_api' ) { + + $url = POST_SMTP_URL . '/Postman/Wizard/assets/images/zoho.png'; + $slug = $transport_slug; + $transport_name = 'Zoho'; + $is_pro = 'ps-pro-extension'; + $product_url = postman_is_bfcm() ? 'https://postmansmtp.com/cyber-monday-sale?utm_source=plugin&utm_medium=section_name&utm_campaign=BFCM&utm_id=BFCM_2024' : 'https://postmansmtp.com/pricing/?utm_source=plugin&utm_medium=wizard_zoho&utm_campaign=plugin'; + + } + if( !class_exists( 'Post_Smtp_Amazon_Ses' ) && $transport_slug == 'aws_ses_api' ) { + + $url = POST_SMTP_URL . '/Postman/Wizard/assets/images/amazon.png'; + $slug = $transport_slug; + $transport_name = 'Amazon SES'; + $is_pro = 'ps-pro-extension'; + $product_url = postman_is_bfcm() ? 'https://postmansmtp.com/cyber-monday-sale?utm_source=plugin&utm_medium=section_name&utm_campaign=BFCM&utm_id=BFCM_2024' : 'https://postmansmtp.com/pricing/?utm_source=plugin&utm_medium=wizard_amazonses&utm_campaign=plugin'; + + } + + } + + if( $row >= 4 ) { + + $row = 0; + + ?> +
        +
        + +
        +
        > + + PRO + + +
        +
        + +
        +

        + %3$s', + __( 'Need help in choosing one?', 'post-smtp' ), + esc_url( admin_url( 'admin.php?page=postman-contact' ) ), + __( 'Check out our Mailer Guide.', 'post-smtp' ) + ); ?> +

        + +

        + +

        +
        +
        + Back + sockets ) ) { + + $this->render_name_email_settings(); + + foreach( $this->sockets as $key => $title ) { + + $active_socket = ( isset( $_GET['socket'] ) && $_GET['socket'] == $key ) ? 'style="display: block;"' : ''; + + ?> +
        > + +

        + render_socket_settings( $key ); ?> +
        + +
        +
        + +

        +
        +
        +
        + + +

        .

        +
        + +
        +

        +

        +

        +
        +
        +
        +
        +

        â¤

        +

        %3$s', + __( 'We value your opinion on your experience with Post SMTP and would appreciate your feedback. ', 'post-smtp' ), + esc_url( 'https://wordpress.org/support/plugin/post-smtp/reviews/#new-post' ), + __( 'Leave a review here.', 'post-smtp' ) + ) ?>

        +
        +
        +

        +
        +
        + + +
        + + +
        + + +
        +
        + + +
        + + +
        + + +
        +
        + +
        +
        +
        +
        +
        + +
        +
        +
        + +
        + +
        +
        + + __( 'Select a socket type to continue.', 'post-smtp' ), + 'Step2E2' => __( 'Please enter From Email.', 'post-smtp' ), + 'Step2E3' => __( 'Please try again, something went wrong.', 'post-smtp' ), + 'Step3E4' => __( 'Please enter recipient email address.', 'post-smtp' ), + 'finish' => __( 'Finish', 'post-smtp' ), + 'adminURL' => admin_url(), + 'connectivityTestMsg' => sprintf( + '%1$s %2$s %4$s %5$s', + '', + __( 'Take the', 'post-smtp' ), + esc_url( admin_url( 'admin.php?page=postman/port_test' ) ), + __( 'connectivity test', 'post-smtp' ), + __( 'of your site to get more information about this failure.', 'post-smtp' ) + ), + // Add the nonce for pro option AJAX + 'pro_option_nonce' => wp_create_nonce('update_post_smtp_pro_option'), + ); + + if( class_exists( 'Post_Smtp_Office365' ) ) { + + //Office 365 URL Params | State + $state = get_transient( Post_Smtp_Office365::STATE ); + + if ( $state === false ) { + + $state = bin2hex( random_bytes( 32 / 2 ) ); + set_transient( Post_Smtp_Office365::STATE, $state, 5 * MINUTE_IN_SECONDS ); + + } + + $localized['office365State'] = $state; + + } + $gmail_icon_url = POST_SMTP_URL . '/Postman/Wizard/assets/images/gmail.png'; + $localized['gmail_icon'] = $gmail_icon_url; + $localized['tenantId'] = apply_filters( 'post_smtp_office365_tenant_id', 'common' ); + + $office365_icon_url = POST_SMTP_URL . '/Postman/Wizard/assets/images/ms365.png'; + $localized['office365_icon'] = $office365_icon_url; + + wp_enqueue_style( 'post-smtp-wizard', POST_SMTP_URL . '/Postman/Wizard/assets/css/wizard.css', array(), POST_SMTP_VER ); + wp_enqueue_script( 'post-smtp-wizard', POST_SMTP_URL . '/Postman/Wizard/assets/js/wizard.js', array( 'jquery' ), POST_SMTP_VER ); + wp_localize_script( 'post-smtp-wizard', 'PostSMTPWizard', $localized ); + + } + + + /** + * Render Name and Email Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_name_email_settings() { + + $from_name = null !== $this->options->getMessageSenderName() ? esc_attr( $this->options->getMessageSenderName() ) : ''; + $from_email = null !== $this->options->getMessageSenderEmail() ? esc_attr( $this->options->getMessageSenderEmail() ) : ''; + $from_name_enforced = $this->options->isPluginSenderNameEnforced() ? 'checked' : ''; + $from_email_enforced = $this->options->isPluginSenderEmailEnforced() ? 'checked' : ''; + + $html = ' +
        +
        +

        From Address

        +

        '. sprintf( + '%1$s', + esc_html__( 'It is important to indicate the origin (email and name) of a message for the receiver. The From Address provides these details.', 'post-smtp' ) + ) .'

        +

        '. sprintf( + '%1$s', + esc_html__( 'You may edit the following field if you do not wish to use default settings.', 'post-smtp' ) + ) .'

        +
        + + '.__( 'The email address that emails are sent from.', 'post-smtp' ).' +
        '.__( 'Please note that other plugins may override this field, to prevent this use the setting below.', 'post-smtp' ).'
        +
        +
        + +
        + '. + sprintf( + '%1$s %2$s %3$s %4$s %5$s %6$s', + __( 'Check this to prevent changes on the', 'post-smtp' ), + __( 'From Email', 'post-smtp' ), + __( 'field by other', 'post-smtp' ), + __( 'Plugins', 'post-smtp' ), + __( 'and', 'post-smtp' ), + __( 'Themes', 'post-smtp' ) + ). + ' +
        +
        +
        +
        + + '.__( 'The name that emails are sent from.', 'post-smtp' ).' +
        +
        + +
        + '. + sprintf( + '%1$s %2$s %3$s %4$s %5$s %6$s', + __( 'Check this to prevent changes on the', 'post-smtp' ), + __( 'From Name', 'post-smtp' ), + __( 'field by other', 'post-smtp' ), + __( 'Plugins', 'post-smtp' ), + __( 'and', 'post-smtp' ), + __( 'Themes', 'post-smtp' ) + ). + ' +
        +
        +
        + '; + + echo wp_kses( $html, $this->allowed_tags ); + + } + + + /** + * Render Socket Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_socket_settings( $socket ) { + + switch ( $socket ) { + + case 'default': + echo wp_kses( $this->render_default_settings(), $this->allowed_tags ); + break; + case 'smtp': + echo wp_kses( $this->render_smtp_settings(), $this->allowed_tags ); + break; + case 'gmail_api': + echo wp_kses( $this->render_gmail_settings(), $this->allowed_tags ); + break; + case 'mandrill_api': + echo wp_kses( $this->render_mandrill_settings(), $this->allowed_tags ); + break; + case 'emailit_api': + echo wp_kses( $this->render_emailit_settings(), $this->allowed_tags ); + break; + case 'maileroo_api': + echo wp_kses( $this->render_maileroo_settings(), $this->allowed_tags ); + break; + case 'sweego_api': + echo wp_kses( $this->render_sweego_settings(), $this->allowed_tags ); + break; + case 'sendgrid_api': + echo wp_kses( $this->render_sendgrid_settings(), $this->allowed_tags ); + break; + case 'mailersend_api': + echo wp_kses( $this->render_mailersend_settings(), $this->allowed_tags ); + break; + case 'mailgun_api': + echo wp_kses( $this->render_mailgun_settings(), $this->allowed_tags ); + break; + case 'sendinblue_api': + echo wp_kses( $this->render_brevo_settings(), $this->allowed_tags ); + break; + case 'mailtrap_api': + echo wp_kses( $this->render_mailtrap_settings(), $this->allowed_tags ); + break; + case 'resend_api': + echo wp_kses( $this->render_resend_settings(), $this->allowed_tags ); + break; + case 'postmark_api': + echo wp_kses( $this->render_postmark_settings(), $this->allowed_tags ); + break; + case 'sparkpost_api': + echo wp_kses( $this->render_sparkpost_settings(), $this->allowed_tags ); + break; + case 'mailjet_api': + echo wp_kses( $this->render_mailjet_settings(), $this->allowed_tags ); + break; + case 'sendpulse_api': + echo wp_kses( $this->render_sendpulse_settings(), $this->allowed_tags ); + break; + case 'elasticemail_api': + echo wp_kses( $this->render_elasticemail_settings(), $this->allowed_tags ); + break; + case 'aws_ses_api'; + echo wp_kses( $this->render_amazonses_settings(), $this->allowed_tags ); + break; + case 'office365_api'; + echo wp_kses( $this->render_office365_settings(), $this->allowed_tags ); + break; + case 'zohomail_api'; + echo wp_kses( $this->render_zoho_settings(), $this->allowed_tags ); + break; + case 'smtp2go_api': + echo wp_kses( $this->render_smtp2go_settings(), $this->allowed_tags ); + break; + } + + } + + /** + * Render default Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_default_settings() { + + $html = ''; + + return $html; + + } + + + /** + * Render SMTP Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_smtp_settings() { + + $hostname = null !== $this->options->getHostname() ? esc_attr ( $this->options->getHostname() ) : ''; + $port = null !== $this->options->getPort() ? esc_attr ( $this->options->getPort() ) : ''; + $username = null !== $this->options->getUsername() ? esc_attr ( $this->options->getUsername() ) : ''; + $password = null !== $this->options->getPassword() ? esc_attr ( $this->options->getPassword() ) : ''; + + + $html = '

        ' . esc_html__( 'You can set up any SMTP of your choice, but it is important to remember that custom SMTP may not have adequate security.', 'post-smtp' ) . '

        '; + $html .= '

        ' . esc_html__( 'Kindly check our ', 'post-smtp' ) . '' . esc_html__( 'SMTP documentation', 'post-smtp' ) . '' . esc_html__( ' before implementation.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + + + '.__( 'Outgoing Mail Server Hostname', 'post-smtp' ).' + +
        + '; + + $html .= ' +
        +
        + + + '.__( 'Outgoing Mail Server Port', 'post-smtp' ).' + +
        + '; + + $html .= ' +
        +
        + + + '.__( 'The Username is usually the same as the Envelope-From Email Address.', 'post-smtp' ).' + +
        + '; + + $html .= ' +
        +
        + + + '.__( 'Password or App Password.', 'post-smtp' ).' + +
        + '; + + return $html; + + } + + + /** + * Render Gmail API Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ +public function render_gmail_settings() { + // Get the Client ID and Client Secret from options + $client_id = ! is_null( $this->options->getClientId() ) ? esc_attr( $this->options->getClientId() ) : ''; + $client_secret = ! is_null( $this->options->getClientSecret() ) ? esc_attr( $this->options->getClientSecret() ) : ''; + // Check if the 'success' parameter exists in URL + $required = isset( $_GET['success'] ) && $_GET['success'] == 1 ? '' : 'required'; + + // Retrieve options for premium features and extensions + $post_smtp_pro_options = get_option( 'post_smtp_pro', [] ); + $postman_auth_token = get_option( 'postman_auth_token' ); + $bonus_extensions = isset( $post_smtp_pro_options['extensions'] ) ? $post_smtp_pro_options['extensions'] : []; + $gmail_oneclick_enabled = in_array( 'gmail-oneclick', $bonus_extensions ); + $auth_url = get_option( 'post_smtp_gmail_auth_url' ); + + // Setup classes and attributes for form visibility + $hidden_class = $gmail_oneclick_enabled ? 'ps-hidden' : ''; + $client_id_required = $gmail_oneclick_enabled ? '' : 'required'; + $client_secret_required = $gmail_oneclick_enabled ? '' : 'required'; + $one_click_class = 'ps-enable-gmail-one-click'; + $url = POST_SMTP_URL . '/Postman/Wizard/assets/images/wizard-google.png'; + $transport_name = __( '1-Click Google Mailer Setup?', 'post-smtp' ); + $product_url = postman_is_bfcm() ? + 'https://postmansmtp.com/cyber-monday-sale?utm_source=plugin&utm_medium=section_name&utm_campaign=BFCM&utm_id=BFCM_2024' : + 'https://postmansmtp.com/pricing/?utm_source=plugin&utm_medium=wizard_gmail_one_click&utm_campaign=plugin'; + + + if ( isset( $_GET['success'] ) && $_GET['success'] == 1 ) { + $client_id_required = ''; + $client_secret_required = ''; + } + + // Prepare data for JSON encoding + $data = [ + 'url' => $url, + 'transport_name' => $transport_name, + 'product_url' => $product_url + ]; + $json_data = htmlspecialchars( json_encode( $data ), ENT_QUOTES, 'UTF-8' ); + + // Begin HTML output + $html = '

        ' . esc_html__( 'Post SMTP offers two ways to connect Gmail API with WordPress: One-Click Setup (fastest) and Manual (free).', 'post-smtp' ) . '

        '; + $html .= '
        '; + if ( post_smtp_has_pro() ) { + $one_click = true; + $html .= sprintf( '

        %1$s

        ', __( 'One-Click Setup', 'post-smtp' ) ); + } else { + $html .= sprintf( + '

        %1$s %2$s

        ', + __( 'One-Click Setup', 'post-smtp' ), + __( 'PRO', 'post-smtp' ) + ); + $one_click = 'disabled'; + $one_click_class .= ' disabled'; + } + + $html .= __( '

        Enable the option for a quick and easy way to connect with Google without the need of manually creating an app.

        ', 'post-smtp' ); + + // One-click switch control + $html .= "

        +
        + +
        +
        "; + // Client ID and Secret inputs + $html .= '
        + +

        ' . esc_html__( 'Manual Setup (FREE)', 'post-smtp' ) . '

        ' . esc_html__( 'The free Gmail mailer requires you to create an app manually to generate the Client ID and Client Secret.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + +
        '; + + $html .= ' +
        +
        + +
        '; + + $html .= ' +
        +
        + +
        '; + + $html .= ' +
        +
        + + + ' . __( 'Please copy this URL into the "Authorized redirect URL" field of your Gmail account settings.', 'post-smtp' ) . ' + +
        '; + + $html .= ' +

        ' . __( 'Authorization (Required)', 'post-smtp' ) . '

        +

        ' . __( 'Before continuing, you\'ll need to allow this plugin to send emails using Gmail API.', 'post-smtp' ) . '

        + + ' . __( 'Connect to Gmail API', 'post-smtp' ) . ''; + + // Remove OAuth action button + $html .= '
        '; + $html .= '
        '; + if ( post_smtp_has_pro() ) { + if ( $postman_auth_token && isset( $postman_auth_token['user_email'] ) ) { + $nonce = wp_create_nonce( 'remove_oauth_action' ); + $action_url = esc_url( add_query_arg( + [ + '_wpnonce' => $nonce, + 'action' => 'remove_oauth_action', + ], + admin_url( 'admin-post.php' ) + ) ); + if ( isset( $postman_auth_token['user_email'] ) ) { + $html .= ' ' . sprintf( esc_html__('Connected with: %s', 'post-smtp'), esc_html( $postman_auth_token['user_email'] ) ) . ''; + } + $html .= ''; + $html .= esc_html__( 'Remove Authorization', 'post-smtp' ); + $html .= ''; + }else { + $html .= '

        ' . esc_html__( 'Authorization (Required)', 'post-smtp' ) . '

        '; + $html .= '

        ' . esc_html__( 'Before continuing, you\'ll need to allow this plugin to send emails using Gmail API.', 'post-smtp' ) . '

        '; + $html .= ''; + $html .= ''; + $html .= esc_html__( 'Sign in with Google', 'post-smtp' ); + $html .= ''; + $html .= "

        By signing in with Google, you can send emails using different 'From' addresses. To do this, disable the 'Force From Email' setting and use your registered aliases as the 'From' address across your WordPress site.

        Removing the OAuth connection will give you the ability to redo the OAuth connection or link to another Google account.

        "; + } + } + + $html .= '
        '; + + return $html; +} + + /** + * Render Emailit Settings + */ + public function render_emailit_settings() { + $api_key = null !== $this->options->getEmailitApiKey() ? esc_attr ( $this->options->getEmailitApiKey() ) : ''; + $html = sprintf( + '

        %2$s %3$s

        ', + esc_url( 'https://emailit.com/' ), + __( 'Emailit', 'post-smtp' ), + __( 'is a transactional email provider. Enter your API Key and Endpoint below.', 'post-smtp' ) + ); + $html .= ' +
        +
        + +
        '; + return $html; + } + + /** + * Render Emailit Settings + */ + public function render_sweego_settings() { + $api_key = null !== $this->options->getSweegoApiKey() ? esc_attr ( $this->options->getSweegoApiKey() ) : ''; + $html = sprintf( + '

        + %1$s %3$s %4$s +

        ', + __( 'Integrating Sweego with your WordPress site. We recommend checking the', 'post-smtp' ), + esc_url( 'https://postmansmtp.com/docs/mailers/how-to-setup-sweego-with-post-smtp/' ), + __( 'documentation', 'post-smtp' ), + __( 'for a successful integration.', 'post-smtp' ) + ); + $html .= ' +
        +
        + +
        '; + return $html; + } + + /** + * Render Maileroo Settings + */ + public function render_maileroo_settings() { + $api_key = null !== $this->options->getMailerooApiKey() ? esc_attr ( $this->options->getMailerooApiKey() ) : ''; + $html = sprintf( + '

        %2$s %3$s

        ', + esc_url( 'https://maileroo.com/' ), + __( 'Maileroo', 'post-smtp' ), + __( 'is a transactional email provider. Enter your API Key and Endpoint below.', 'post-smtp' ) + ); + $html .= ' +
        +
        + +
        '; + return $html; + } + + /** + * Render Mandrill Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_mandrill_settings() { + + $api_key = null !== $this->options->getMandrillApiKey() ? esc_attr ( $this->options->getMandrillApiKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate Mandrill mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API key', 'post-smtp' ) . '' . esc_html__( ' in your Mandrill account.', 'post-smtp' ) . '
        ' + .' +
        + '; + + return $html; + + } + + + /** + * Render SendGrid Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_sendgrid_settings() { + + $api_key = null !== $this->options->getSendGridApiKey() ? esc_attr ( $this->options->getSendGridApiKey() ) : ''; + $selected_region = $this->options->getSendGridRegion() ? esc_attr( $this->options->getSendGridRegion() ) : 'AG'; + + $html = '

        ' . esc_html__( 'It is easy to integrate SendGrid mailer to your WordPress website. We recommend you to check the ', 'post-smtp' ) . '' . esc_html__( 'documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + + + $html .= ' +
        +
        + +
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API key above', 'post-smtp' ) . ' ' . esc_html__( 'in your SendGrid account.', 'post-smtp' ) . '
        ' . + '
        '; + + // Region dropdown. + $html .= '
        '; + $html .= '
        '; + $html .= ''; + $html .= '
        '; + + + return $html; + + } + + + /** + * Render MailerSend Settings + * + * @since 3.3.0 + * @version 1.0.0 + */ + public function render_mailersend_settings() { + + $api_key = null !== $this->options->getMailerSendApiKey() ? esc_attr ( $this->options->getMailerSendApiKey() ) : ''; + + $html = '

        ' . esc_html__( 'It is easy to integrate MailerSend API mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API key', 'post-smtp' ) . '' . esc_html__( ' in your Mailersend account.', 'post-smtp' ) . '
        ' + .' +
        + '; + + return $html; + + } + + + /** + * Render Mailgun Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_mailgun_settings() { + + $api_key = null !== $this->options->getMailgunApiKey() ? esc_attr ( $this->options->getMailgunApiKey() ) : ''; + $domain_name = null !== $this->options->getMailgunDomainName() ? esc_attr ( $this->options->getMailgunDomainName() ) : ''; + $region = null !== $this->options->getMailgunRegion() ? ' checked' : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate Mailgun mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + sprintf( + '
        %1$s %3$s
        %4$s %6$s
        ', + __( 'Create an account at', 'post-smtp' ), + esc_url( 'https://www.mailgun.com/' ), + esc_attr( 'Mailgun' ), + __( 'If you are already logged in follow this link to get an', 'post-smtp' ), + esc_url( 'https://app.mailgun.com/settings/api_security' ), + __( 'API Key.', 'post-smtp' ) + ) + .' +
        + '; + + $html .= ' +
        +
        + + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + sprintf( + '%1$s %3$s', + __( ' Follow this link to get the Mailgun', 'post-smtp' ), + esc_url( 'https://app.mailgun.com/app/sending/domains' ), + __( 'Domain Name.', 'post-smtp' ) + ) + .' +
        + '; + + $html .= ' +
        +
        +
        + +
        + '. + + '
        ' . esc_html__( 'Set your endpoint in Europe if your business operates under EU laws. ', 'post-smtp' ) . '' . esc_html__( 'Learn', 'post-smtp' ) . '
        ' + .' +
        + '; + + return $html; + + } + + + /** + * Render Brevo Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_brevo_settings() { + + $api_key = null !== $this->options->getSendinblueApiKey() ? esc_attr ( $this->options->getSendinblueApiKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate Brevo mailer to your WordPress website. We recommend you to check the documentation for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API key', 'post-smtp' ) . '' . esc_html__( ' in your Brevo account.', 'post-smtp' ) . '
        ' + . + '
        + '; + + return $html; + + } + + /** + * Render Mailtrap Settings + * + * @since 2.9.0 + * @version 1.0.0 + */ + public function render_mailtrap_settings() { + + $api_key = null !== $this->options->getMailtrapApiKey() ? esc_attr ( $this->options->getMailtrapApiKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate Mailtrap mailer to your WordPress website. We recommend you to check the documentation for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API token', 'post-smtp' ) . '' . esc_html__( ' in your Mailtrap account.', 'post-smtp' ) . '
        ' + . + '
        + '; + + return $html; + + } + + + /** + * Render Resend Settings + * + * @since 3.2.0 + * @version 1.0.0 + */ + public function render_resend_settings() { + + $api_key = null !== $this->options->getResendApiKey() ? esc_attr ( $this->options->getResendApiKey() ) : ''; + + $html = sprintf( + '

        Resend %2$s

        %3$s

        %4$s %6$s', + esc_url( 'https://resend.com/' ), + __( 'is a modern email API provider built for developers. It provides reliable email delivery with simple APIs and excellent deliverability.', 'post-smtp' ), + __( 'Resend offers a free plan to send up to 100 emails per day and 3,000 emails per month. You can start testing immediately and upgrade when needed.', 'post-smtp' ), + __( 'Let\'s get started with our', 'post-smtp' ), + esc_url( 'https://postmansmtp.com/documentation/sockets-addons/how-to-setup-resend-with-post-smtp/' ), + __( 'Resend Documentation', 'post-smtp' ) + ); + + $html .= ' +

        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + sprintf( + '
        %1$s %3$s
        %4$s %6$s
        ', + __( 'Create an account at', 'post-smtp' ), + esc_url( 'https://resend.com/' ), + esc_attr( 'Resend.com' ), + __( 'If you are already logged in follow this link to get an', 'post-smtp' ), + esc_url( 'https://resend.com/api-keys' ), + __( 'API Key.', 'post-smtp' ) + ) + . + '
        + '; + + return $html; + + } + + + /** + * Render Postmark Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_postmark_settings() { + + $api_key = null !== $this->options->getPostmarkApiKey() ? esc_attr ( $this->options->getPostmarkApiKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate Postmark mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API tokens', 'post-smtp' ) . '' . esc_html__( ' in your Postmark account.', 'post-smtp' ) . '
        ' + .' +
        + '; + + return $html; + + } + + + /** + * Render Sparkpost Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_sparkpost_settings() { + + $api_key = null !== $this->options->getSparkPostApiKey() ? esc_attr ( $this->options->getSparkPostApiKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate SparkPost mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API key', 'post-smtp' ) . '' . esc_html__( ' in your SparkPost account.', 'post-smtp' ) . '
        ' + .' +
        + '; + + return $html; + + } + + /** + * Render ElasticEmail Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_elasticemail_settings() { + + $api_key = null !== $this->options->getElasticEmailApiKey() ? esc_attr ( $this->options->getElasticEmailApiKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate Elastic Email mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API key', 'post-smtp' ) . '' . esc_html__( ' in your Elastic Email account.', 'post-smtp' ) . '
        ' + . + '
        + '; + + return $html; + + } + + /** + * Render Mailjet Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_mailjet_settings() { + + $api_key = null !== $this->options->getMailjetApiKey() ? esc_attr ( $this->options->getMailjetApiKey() ) : ''; + $secret_key = null !== $this->options->getMailjetApiKey() ? esc_attr ( $this->options->getMailjetSecretKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate Mailjet mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        +
        + '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'API and Access information', 'post-smtp' ) . '' . esc_html__( ' in your Mailjet account.', 'post-smtp' ) . '
        ' + . + '
        + '; + + return $html; + + } + + /** + * Render SendPulse Settings + * + * @since 2.9.0 + * @version 1.0.0 + */ + public function render_sendpulse_settings() { + + $api_key = null !== $this->options->getSendpulseApiKey() ? esc_attr ( $this->options->getSendpulseApiKey() ) : ''; + $secret_key = null !== $this->options->getSendpulseSecretKey() ? esc_attr ( $this->options->getSendpulseSecretKey() ) : ''; + + + $html = '

        ' . esc_html__( 'It is easy to integrate SendPulse mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        + + '. + sprintf( + '
        %2$s %3$s
        ', + esc_url( 'https://sendpulse.com/features/transactional' ), + __( 'Click here', 'post-smtp' ), + __( 'to create an account at SendPulse', 'post-smtp' ) + ). + sprintf( + '
        %1$s%3$s
        ', + __( 'If you are already logged in follow this ink to get your API ID from Sendpulse ', 'post-smtp' ), + esc_url( 'https://login.sendpulse.com/settings/#api' ), + __( 'Get API ID', 'post-smtp' ) + ). + '
        ' + ; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + + '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API credentials', 'post-smtp' ) . '' . esc_html__( ' in your SendPulse account.', 'post-smtp' ) . '
        ' + . + '
        + '; + + return $html; + + } + + /** + * Render Amazon SES Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_amazonses_settings() { + + $access_key_id = isset( $this->options_array[ PostSMTPSES\PostSmtpAmazonSesTransport::OPTION_ACCESS_KEY_ID ] ) ? base64_decode( $this->options_array[ PostSMTPSES\PostSmtpAmazonSesTransport::OPTION_ACCESS_KEY_ID ] ) : ''; + $access_key_secret = isset( $this->options_array[ PostSMTPSES\PostSmtpAmazonSesTransport::OPTION_SECRET_ACCESS_KEY ] ) ? base64_decode( $this->options_array[ PostSMTPSES\PostSmtpAmazonSesTransport::OPTION_SECRET_ACCESS_KEY ] ) : ''; + $region = isset( $this->options_array[ PostSMTPSES\PostSmtpAmazonSesTransport::OPTION_REGION ] ) ? $this->options_array[ PostSMTPSES\PostSmtpAmazonSesTransport::OPTION_REGION ] : ''; + + + $html = '

        ' . esc_html__( 'Due to the technical nature of this SMTP implementation, it is recommended to study this step-by-step guide at the time of setup.', 'post-smtp' ) . '

        '; + $html .= '

        âš ï¸ ' . esc_html__( 'You must have a working SSL certificate installed on your WordPress site to use it with Amazon SES.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        +
        '; + + $html .= ' +
        +
        + '. + /** + * Translators: %1$s Text, %2$s URL, %3$s URL Text, %4$s Text, %5$s URL, %6$s URL Text + */ + + '
        ' . esc_html__( 'If you are already logged in, ', 'post-smtp' ) . '' . esc_html__( 'visit this link', 'post-smtp' ) . '' . esc_html__( ' to get the Access Key ID and Secret Access Key.', 'post-smtp' ) . '
        ' + . + '
        + '; + + + $html .= ' +
        +
        + + ' . esc_html__( 'Enter the correct region', 'post-smtp' ) . ' +
        + '; + + return $html; + + } + + + /** + * Render Office365 Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_office365_settings() { + $options = get_option( PostmanOptions::POSTMAN_OPTIONS ); + $app_client_id = isset( $options['office365_app_id'] ) ? base64_decode( $options['office365_app_id'] ) : ''; + $app_client_secret = isset( $options['office365_app_password'] ) ? base64_decode( $options['office365_app_password'] ) : ''; + $redirect_uri = admin_url(); + + // Check if access token exists for Office 365 + $office365_oauth = get_option( 'postman_office365_oauth' ); + $has_access_token = $office365_oauth && isset( $office365_oauth['access_token'] ) && ! empty( $office365_oauth['access_token'] ); + + // Retrieve options for premium features and extensions + $post_smtp_pro_options = get_option( 'post_smtp_pro', [] ); + $postman_office365_auth_token = get_option( 'postman_office365_oauth' ); + $extensions = isset( $post_smtp_pro_options['extensions'] ) ? $post_smtp_pro_options['extensions'] : []; + $office365_oneclick_enabled = in_array( 'microsoft-one-click', $extensions ); + $office365_auth_url = get_option( 'post_smtp_office365_auth_url' ); + + + $html = '

        ' . esc_html__( 'To establish a SMTP connection, you will need to create an app in your Azure account. This step-by-step guide will walk you through the whole process.', 'post-smtp' ) . '

        '; + + // Setup classes and attributes for form visibility + $hidden_class = $office365_oneclick_enabled ? 'ps-hidden' : ''; + // Conditional 'required' attribute for the fields - consider access token when one-click is enabled + $client_secret_required = $office365_oneclick_enabled ? '' : 'required'; + $client_id_required = $office365_oneclick_enabled ? '' : 'required'; + $one_click_class = 'ps-enable-office365-one-click'; + $url = POST_SMTP_URL . '/Postman/Wizard/assets/images/ms365.png'; + $transport_name = __( 'One-Click Microsoft Mailer Setup?', 'post-smtp' ); + $product_url = postman_is_bfcm() ? + 'https://postmansmtp.com/cyber-monday-sale?utm_source=plugin&utm_medium=section_name&utm_campaign=BFCM&utm_id=BFCM_2024' : + 'https://postmansmtp.com/pricing/?utm_source=plugin&utm_medium=wizard_microsoft&utm_campaign=plugin'; + + // Prepare data for JSON encoding + $data = [ + 'url' => $url, + 'transport_name' => $transport_name, + 'product_url' => $product_url + ]; + $json_data = htmlspecialchars( json_encode( $data ), ENT_QUOTES, 'UTF-8' ); + + // Determine whether we have both token and email stored for Office365 + // Only treat stored user_email as valid when one-click is enabled. + $has_email = false; + if ( $office365_oneclick_enabled && $office365_oauth && isset( $office365_oauth['user_email'] ) && ! empty( $office365_oauth['user_email'] ) ) { + $has_email = true; + } + + // Set required based on context: + // - For one-click: skip if success param is set OR both access token and email exist + // - For normal setup: skip if success param is set OR both access token and email exist + if ( $office365_oneclick_enabled ) { + $required = ( ( isset( $_GET['success'] ) && $_GET['success'] == 1 ) || ( $has_access_token && $has_email ) ) ? '' : 'required'; + } else { + $required = ( ( isset( $_GET['success'] ) && $_GET['success'] == 1 ) || ( $has_access_token && $has_email ) ) && $client_id_required ? '' : 'required'; + } + + $html .= __( 'The configuration steps are more technical than other options, so our detailed guide will walk you through the whole process.', 'post-smtp' ); + $html .= '
        '; + + if ( post_smtp_has_pro() ) { + $one_click = true; + $html .= sprintf( '

        %1$s

        ', __( 'One-Click Setup', 'post-smtp' ) ); + } else { + $html .= sprintf( + '

        %1$s %2$s

        ', + __( 'One-Click Setup', 'post-smtp' ), + __( 'PRO', 'post-smtp' ) + ); + $one_click = 'disabled'; + $one_click_class .= ' disabled'; + } + + $html .= __( 'Enable the option for a quick and easy way to connect with Microsoft 365 / Outlook without the need of manually creating an app', 'post-smtp' ); + + // Check if user has business plan for Office 365 one-click + $is_business_plan = false; + if ( function_exists( 'pspro_fs' ) && pspro_fs()->is_plan( 'business' ) ) { + $is_business_plan = true; + } + + // Check Post SMTP Pro version if user has business plan + $show_version_warning = false; + $required_pro_version = '1.5.0'; + if ( $is_business_plan && defined( 'POST_SMTP_PRO_VERSION' ) ) { + $current_pro_version = POST_SMTP_PRO_VERSION; + if ( version_compare( $current_pro_version, $required_pro_version, '<' ) ) { + $show_version_warning = true; + } + } + + // One-click switch control + $html .= "
        +
        + +
        +
        "; + + // Show business plan upgrade notice if needed + if ( post_smtp_has_pro() && !$is_business_plan ) { + $html .= '
        '; + $html .= '

        ' . __( 'Microsoft 365 (Outlook)', 'post-smtp' ) . '
        '; + $html .= __( ' One-Click Setup is available only with Business plan. Click on the toggle to update.', 'post-smtp' ) . '

        '; + $html .= '
        '; + // Inject conditional CSS + add_action( 'admin_footer', function () { + echo ''; + }); + + } + + // Show version warning if user has business plan but outdated Post SMTP Pro version + if ( $show_version_warning ) { + $html .= '
        '; + $html .= '

        ' . __( 'Please update your Post SMTP Pro plugin to use this feature.', 'post-smtp' ) . '

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

        %2$s %3$s

        %5$s', + esc_url( 'https://azure.microsoft.com/en-us/pricing/purchase-options/azure-account?icid=azurefreeaccount' ), + __( 'Office 365', 'post-smtp' ), + __( 'is a popular transactional email provider that sends more than 35 billion emails every month. If you\'re just starting out, the free plan allows you to send up to 100 emails each day without entering your credit card details', 'post-smtp' ), + esc_url( 'https://postmansmtp.com/docs/mailers/microsoft-365-one-click-smtp/' ), + __( 'Read how to setup Office 365', 'post-smtp' ) + ); + + + $html .= ' +
        +
        + + '. + '
        ' . esc_html__( 'You can find the ', 'post-smtp' ) . '' . esc_html__( 'client id', 'post-smtp' ) . '' . esc_html__( ' here.', 'post-smtp' ) . '
        ' + .'
        +
        + '; + + $html .= ' +
        +
        + + '. + /** + * Translators: %1$s URL, %2$s URL Text, %3$s Text + */ + + '
        ' . esc_html__( 'You can find the ', 'post-smtp' ) . '' . esc_html__( 'client secret', 'post-smtp' ) . '' . esc_html__( ' here.', 'post-smtp' ) . '
        ' + .'
        +
        + '; + + + $html .= ' +
        +
        + + '. + /** + * Translators: %1$s URL, %2$s URL Text, %3$s Text + */ + + '
        ' . esc_html__( 'You can place the ', 'post-smtp' ) . '' . esc_html__( 'redirect url', 'post-smtp' ) . '' . esc_html__( ' as needed.', 'post-smtp' ) . '
        ' + .'
        +
        + '; + + $html .= ' +

        '.__( 'Authorization (Required)', 'post-smtp' ).'

        +

        '.__( 'Before continuing, you\'ll need to allow this plugin to send emails using your Office 365 account.', 'post-smtp' ).'

        + + Connect to Office 365'; + + $html .= '
        '; + + $html .= '
        '; + if ( post_smtp_has_pro() ) { + if ( $postman_office365_auth_token && isset( $postman_office365_auth_token['user_email'] ) ) { + $nonce = wp_create_nonce( 'remove_365_oauth_action' ); + $action_url = esc_url( add_query_arg( + [ + '_wpnonce' => $nonce, + 'action' => 'remove_365_oauth_action', + ], + admin_url( 'admin-post.php' ) + ) ); + if ( isset( $postman_office365_auth_token['user_email'] ) ) { + $html .= ' ' . sprintf( esc_html__('Connected with: %s', 'post-smtp'), esc_html( $postman_office365_auth_token['user_email'] ) ) . ''; + } + $html .= ''; + $html .= esc_html__( 'Remove Authorization', 'post-smtp' ); + $html .= ''; + }else { + $html .= '

        ' . esc_html__( 'Authorization (Required)', 'post-smtp' ) . '

        '; + $html .= '

        ' . esc_html__( 'Before continuing, you\'ll need to allow this plugin to send emails using Office 365 API.', 'post-smtp' ) . '

        '; + $html .= ''; + $html .= ''; + $html .= esc_html__( 'Sign in with Microsoft', 'post-smtp' ); + $html .= ''; + } + } + + $html .= '
        '; + + return $html; + + } + + + /** + * Render Gmail API Settings + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function render_zoho_settings() { + + $regions = array( + 'com' => __( 'United States (US)', 'postsmtp-zoho' ), + 'eu' => __( 'Europe (EU)', 'postsmtp-zoho' ), + 'in' => __( 'India (IN)', 'postsmtp-zoho' ), + 'com.cn' => __( 'China (CN)', 'postsmtp-zoho' ), + 'com.au' => __( 'Australia (AU)', 'postsmtp-zoho' ), + 'jp' => __( 'Japan (JP)', 'postsmtp-zoho' ), + ); + $selected_region = isset( $this->options_array[ ZohoMailPostSMTP\ZohoMailTransport::OPTION_REGION ] ) ? $this->options_array[ ZohoMailPostSMTP\ZohoMailTransport::OPTION_REGION ]: ''; + + $client_id = isset( $this->options_array[ ZohoMailPostSMTP\ZohoMailTransport::OPTION_CLIENT_ID ] ) ? $this->options_array[ ZohoMailPostSMTP\ZohoMailTransport::OPTION_CLIENT_ID ] : ''; + $client_secret = isset( $this->options_array[ ZohoMailPostSMTP\ZohoMailTransport::OPTION_CLIENT_SECRET ] ) ? base64_decode( $this->options_array[ ZohoMailPostSMTP\ZohoMailTransport::OPTION_CLIENT_SECRET ] ) : ''; + $required = ( isset( $_GET['success'] ) && $_GET['success'] == 1 ) ? '' : 'required'; + + + $html = '

        ' . esc_html__( 'It is recommended to study the ', 'post-smtp' ) . '' . esc_html__( 'Zoho Mail integration doc', 'post-smtp' ) . '' . esc_html__( ' at the time of setup.', 'post-smtp' ) . '

        '; + + $html .= ' +
        +
        +
        + '; + + $html .= ' +
        +
        + +
        + '; + + $html .= ' +
        +
        + +
        + ' . esc_html__( 'Check your ', 'post-smtp' ) . '' . esc_html__( 'Zoho API credentials', 'post-smtp' ) . '' . esc_html__( ' to find the Client ID and Secret.', 'post-smtp' ) . ' +
        +
        + '; + + $html .= ' +
        +
        + + + '.__( 'Please copy this URL into the "Redirect URL" field of your Zoho account settings.', 'post-smtp' ).' + +
        + '; + + $html .= ' +

        '.__( 'Authorization (Required)', 'post-smtp' ).'

        +

        '.__( 'Before continuing, you\'ll need to allow this plugin to send emails using Zoho.', 'post-smtp' ).'

        + + Connect to Zoho'; + + return $html; + + } + + public function render_smtp2go_settings() { + ob_start(); + + $api_key = null === $this->options->getSmtp2GoApiKey() ? '' : esc_attr( $this->options->getSmtp2GoApiKey() ); + + + echo '

        ' . esc_html__( 'It is easy to integrate SMTP2GO mailer to your WordPress website. We recommend you to ', 'post-smtp' ) . '' . esc_html__( 'check the documentation', 'post-smtp' ) . '' . esc_html__( ' for a successful integration.', 'post-smtp' ) . '

        '; + + echo '
        +
        + '; + + echo '
        ' . esc_html__( 'You can find ', 'post-smtp' ) . '' . esc_html__( 'the API key', 'post-smtp' ) . '' . esc_html__( ' in your SMTP2GO account.', 'post-smtp' ) . '
        '; + + echo '
        '; + + return ob_get_clean(); + } + + + /** + * Save Wizard | AJAX Callback + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function save_wizard() { + + $form_data = array(); + parse_str( $_POST['FormData'], $form_data ); + $response = false; + + if( + isset( $_POST['action'] ) + && + 'ps-save-wizard' == $_POST['action'] + && + isset( $form_data['security'] ) + && + wp_verify_nonce( $form_data['security'], 'post-smtp' ) + ) { + + if( isset( $form_data['postman_options'] ) && !empty( $form_data['postman_options'] ) ) { + + $sanitized = post_smtp_sanitize_array( $form_data['postman_options'] ); + + $options = get_option( PostmanOptions::POSTMAN_OPTIONS ); + $_options = $options; + $options = $options ? $options : array(); + + //for the checkboxes + $sanitized['prevent_sender_email_override'] = isset( $sanitized['prevent_sender_email_override'] ) ? 1 : ''; + $sanitized['prevent_sender_name_override'] = isset( $sanitized['prevent_sender_name_override'] ) ? 1 : ''; + + //Envelop Email Address + $sanitized['envelope_sender'] = isset( $sanitized['sender_email'] ) ? $sanitized['sender_email'] : ''; + + //Encode API Keys + $sanitized['office365_app_id'] = isset( $sanitized['office365_app_id'] ) ? $sanitized['office365_app_id'] : ''; + $sanitized['office365_app_password'] = isset( $sanitized['office365_app_password'] ) ? $sanitized['office365_app_password'] : ''; + $sanitized[PostmanOptions::SENDINBLUE_API_KEY] = isset( $sanitized[PostmanOptions::SENDINBLUE_API_KEY] ) ? $sanitized[PostmanOptions::SENDINBLUE_API_KEY] : ''; + $sanitized[PostmanOptions::MAILTRAP_API_KEY] = isset( $sanitized[PostmanOptions::MAILTRAP_API_KEY] ) ? $sanitized[PostmanOptions::MAILTRAP_API_KEY] : ''; + $sanitized['sparkpost_api_key'] = isset( $sanitized['sparkpost_api_key'] ) ? $sanitized['sparkpost_api_key'] : ''; + $sanitized['postmark_api_key'] = isset( $sanitized['postmark_api_key'] ) ? $sanitized['postmark_api_key'] : ''; + $sanitized['mailgun_api_key'] = isset( $sanitized['mailgun_api_key'] ) ? $sanitized['mailgun_api_key'] : ''; + $sanitized[PostmanOptions::SENDGRID_API_KEY] = isset( $sanitized[PostmanOptions::SENDGRID_API_KEY] ) ? $sanitized[PostmanOptions::SENDGRID_API_KEY] : ''; + $sanitized['sendgrid_region'] = isset( $sanitized['sendgrid_region'] ) ? $sanitized['sendgrid_region'] : ''; + $sanitized['resend_api_key'] = isset( $sanitized['resend_api_key'] ) ? $sanitized['resend_api_key'] : ''; + $sanitized[PostmanOptions::EMAILIT_API_KEY] = isset( $sanitized[PostmanOptions::EMAILIT_API_KEY] ) ? $sanitized[PostmanOptions::EMAILIT_API_KEY] : ''; + $sanitized[PostmanOptions::MAILEROO_API_KEY] = isset( $sanitized[PostmanOptions::MAILEROO_API_KEY] ) ? $sanitized[PostmanOptions::MAILEROO_API_KEY] : ''; + $sanitized[PostmanOptions::SWEEGO_API_KEY] = isset( $sanitized[PostmanOptions::SWEEGO_API_KEY] ) ? $sanitized[PostmanOptions::SWEEGO_API_KEY] : ''; + $sanitized['mandrill_api_key'] = isset( $sanitized['mandrill_api_key'] ) ? $sanitized['mandrill_api_key'] : ''; + $sanitized[PostmanOptions::MAILERSEND_API_KEY] = isset( $sanitized[PostmanOptions::MAILERSEND_API_KEY] ) ? $sanitized[PostmanOptions::MAILERSEND_API_KEY] : ''; + $sanitized['elasticemail_api_key'] = isset( $sanitized['elasticemail_api_key'] ) ? $sanitized['elasticemail_api_key'] : ''; + $sanitized[PostmanOptions::MAILJET_API_KEY] = isset( $sanitized[PostmanOptions::MAILJET_API_KEY] ) ? $sanitized[PostmanOptions::MAILJET_API_KEY] : ''; + $sanitized[PostmanOptions::MAILJET_SECRET_KEY] = isset( $sanitized[PostmanOptions::MAILJET_SECRET_KEY] ) ? $sanitized[PostmanOptions::MAILJET_SECRET_KEY] : ''; + $sanitized['basic_auth_password'] = isset( $sanitized['basic_auth_password'] ) ? $sanitized['basic_auth_password'] : ''; + $sanitized['ses_access_key_id'] = isset( $sanitized['ses_access_key_id'] ) ? $sanitized['ses_access_key_id'] : ''; + $sanitized['ses_secret_access_key'] = isset( $sanitized['ses_secret_access_key'] ) ? $sanitized['ses_secret_access_key'] : ''; + $sanitized['ses_region'] = isset( $sanitized['ses_region'] ) ? $sanitized['ses_region'] : ''; + $sanitized['enc_type'] = 'tls'; + $sanitized['auth_type'] = 'login'; + $sanitized['slack_token'] = base64_decode( isset( $options['slack_token'] ) ? $options['slack_token'] : '' ); + $sanitized['pushover_user'] = base64_decode( isset( $options['pushover_user'] ) ? $options['pushover_user'] : '' ); + $sanitized['pushover_token'] = base64_decode( isset( $options['pushover_token'] ) ? $options['pushover_token'] : '' ); + foreach( $sanitized as $key => $value ) { + $options[$key] = $value; + } + + if( $options == $_options ) { + $response = true; + } else { + $response = update_option( PostmanOptions::POSTMAN_OPTIONS , $options ); + } + + } + + } + //Prevent redirection + delete_transient( PostmanSession::ACTION ); + + wp_send_json( array(), 200 ); + + } + + /** + * Callback function to handle AJAX requests for updating the 'post_smtp_pro' option. + * + * This function listens for AJAX requests and updates the 'bonus_extensions' array + * in the 'post_smtp_pro' option. It adds or removes the 'gmail-oneclick' extension + * based on whether the checkbox is checked or not. + * + * @return void + */ + public function update_post_smtp_pro_option_callback() { + + // Capability check: Only allow admins + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized.' ) ); + return; + } + + // Nonce check for CSRF protection + if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'update_post_smtp_pro_option' ) ) { + wp_send_json_error( array( 'message' => 'Invalid or missing nonce.' ) ); + return; + } + + if ( ! isset( $_POST['enabled'] ) ) { + wp_send_json_error( array( 'message' => 'Invalid request.' ) ); + return; + } + + $options = get_option( 'post_smtp_pro', [] ); + if ( ! isset( $options['extensions'] ) ) { + $options['extensions'] = []; + } + + $enabled_value = sanitize_text_field( $_POST['enabled'] ); + + if ( ! empty( $enabled_value ) ) { + if ( ! in_array( $enabled_value, $options['extensions'] ) ) { + $options['extensions'][] = $enabled_value; + } + } else { + $options['extensions'] = array_diff( $options['extensions'], ['gmail-oneclick'] ); + } + + update_option( 'post_smtp_pro', $options ); + + wp_send_json_success( array( 'message' => 'Option updated successfully!' ) ); + } + + /** + * Update Post SMTP Pro Option for Office365 One-Click + * + * @since 2.7.0 + * @version 1.0.0 + * + * @return void + */ + public function update_post_smtp_pro_option_office365_callback() { + + // Capability check: Only allow admins + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized.' ) ); + return; + } + + // Nonce check for CSRF protection + if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'update_post_smtp_pro_option' ) ) { + wp_send_json_error( array( 'message' => 'Invalid or missing nonce.' ) ); + return; + } + + if ( ! isset( $_POST['enabled'] ) ) { + wp_send_json_error( array( 'message' => 'Invalid request.' ) ); + return; + } + + $options = get_option( 'post_smtp_pro', [] ); + if ( ! isset( $options['extensions'] ) ) { + $options['extensions'] = []; + } + + $enabled_value = sanitize_text_field( $_POST['enabled'] ); + + // Check version requirement for Office 365 one-click + if ( ! empty( $enabled_value ) ) { + $required_pro_version = '1.5.0'; + if ( defined( 'POST_SMTP_PRO_VERSION' ) ) { + $current_pro_version = POST_SMTP_PRO_VERSION; + if ( version_compare( $current_pro_version, $required_pro_version, '<' ) ) { + wp_send_json_error( array( + 'message' => sprintf( + __( 'Post SMTP Pro version %1$s or higher is required for Office 365 One-Click Setup. Current version: %2$s', 'post-smtp' ), + $required_pro_version, + $current_pro_version + ) + ) ); + return; + } + } else { + wp_send_json_error( array( 'message' => 'Post SMTP Pro version could not be determined.' ) ); + return; + } + } + + // Remove existing Office 365 related extensions + $options['extensions'] = array_diff( $options['extensions'], ['microsoft-365', 'microsoft-one-click'] ); + + if ( ! empty( $enabled_value ) ) { + // If one-click is enabled, add both microsoft-365 and microsoft-one-click + $options['extensions'][] = 'microsoft-365'; + $options['extensions'][] = 'microsoft-one-click'; + } else { + // If one-click is disabled, only add microsoft-365 + $options['extensions'][] = 'microsoft-365'; + } + + // Remove duplicates + $options['extensions'] = array_unique( $options['extensions'] ); + + update_option( 'post_smtp_pro', $options ); + + // Check for Office 365 OAuth token and user email + $office365_oauth = get_option( 'postman_office365_oauth' ); + $has_access_token = false; + $has_email = false; + $user_email = ''; + + if ( $office365_oauth && is_array( $office365_oauth ) ) { + if ( isset( $office365_oauth['access_token'] ) && ! empty( $office365_oauth['access_token'] ) ) { + $has_access_token = true; + } + + if ( isset( $office365_oauth['user_email'] ) && ! empty( $office365_oauth['user_email'] ) ) { + $has_email = true; + $user_email = sanitize_email( $office365_oauth['user_email'] ); + } + } + + wp_send_json_success( array( + 'message' => 'Option updated successfully!', + 'has_access_token' => $has_access_token, + 'has_email' => $has_email, + 'user_email' => $user_email, + ) ); + } + + + /** + * Redirect to Zoho Authentication + * + * @since 2.7.0 + * @version 1.0.0 + */ + public function auth_zoho() { + + $zoho_mailer = new PostSMTP_ZohoMail(); + $oauthClient = $zoho_mailer->zohomail_configuration(); + $PostmanOauthClient = new ZohoMailPostSMTP\ZohoMailOauth( $oauthClient ); + $state = get_transient( PostSMTP_ZohoMail::STATE ); + // Save client state so we can validate in response + + if ( $state === false ) { + $state = bin2hex( random_bytes( 32 / 2 ) ); + set_transient( PostSMTP_ZohoMail::STATE, $state, 5 * MINUTE_IN_SECONDS ); + } + + // // Generate the auth URL + $redirect_url = $PostmanOauthClient->getZohoMailAuthURL( array( + 'state' => $state, + ) ); + + wp_redirect( $redirect_url ); + + } + + /** + * Handles the removal of Office 365 OAuth credentials from the WordPress database. + * + * This function removes only the sensitive fields (tokens, email, and expiration) + * from the stored Office 365 OAuth option instead of deleting the entire record. + */ + public function post_smtp_remove_365_oauth_action() { + // Verify nonce for security + if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'remove_365_oauth_action' ) ) { + wp_die( esc_html__( 'Nonce verification failed. Please try again.', 'post-smtp' ) ); + } + + // Get the saved Office 365 OAuth data + $oauth_data = get_option( 'postman_office365_oauth', [] ); + + if ( ! empty( $oauth_data ) && is_array( $oauth_data ) ) { + // Unset only sensitive fields + unset( + $oauth_data['access_token'], + $oauth_data['refresh_token'], + $oauth_data['token_expires'], + $oauth_data['user_email'] + ); + + // Update the option with sanitized data + update_option( 'postman_office365_oauth', $oauth_data ); + } + + // Redirect back to configuration wizard page + wp_redirect( admin_url( "admin.php?socket=office365_api&step=2&page=postman/configuration_wizard" ) ); + exit; + } + + /** + * Handles the Office 365 OAuth redirect, retrieves the token parameters from the URL, + * saves them in WordPress options, and redirects the user to a settings page. + * + * This function is used when OAuth authorization is completed and the user is + * redirected back with the access token, refresh token, expiration time, message, + * and user email. It sanitizes the URL parameters and saves them to the WordPress + * options table to be used later in the application. + * + * After processing, the user is redirected to a settings page for confirmation. + */ + public function handle_office365_oauth_redirect() { + // Check if the required OAuth parameters are present in the URL. + if ( isset( $_GET['action'] ) && $_GET['action'] === 'office365_oauth_redirect' ) { + // Sanitize and retrieve URL parameters + $access_token = sanitize_text_field( $_GET['access_token'] ); + $refresh_token = isset( $_GET['refresh_token'] ) ? sanitize_text_field( $_GET['refresh_token'] ) : null; + $expires_in = isset( $_GET['expires_in'] ) ? intval( $_GET['expires_in'] ) : 0; + $msg = isset( $_GET['msg'] ) ? sanitize_text_field( $_GET['msg'] ) : ''; + $user_email = isset( $_GET['user_email'] ) ? sanitize_email( $_GET['user_email'] ) : ''; + $auth_token_expires = time() + $expires_in; + $redirect_uri = admin_url(); + // Prepare the OAuth data array for storing in WordPress options + $oauth_data = array( + 'access_token' => $access_token, + 'refresh_token' => $refresh_token, + 'token_expires' => $auth_token_expires, + 'user_email' => $user_email, + 'OAUTH_REDIRECT_URI' => $redirect_uri, + 'OAUTH_SCOPES' => 'openid profile offline_access Mail.Send Mail.Send.Shared', + 'OAUTH_AUTHORITY' => 'https://login.microsoftonline.com/common', + 'OAUTH_AUTHORIZE_ENDPOINT' => '/oauth2/v2.0/authorize', + 'OAUTH_TOKEN_ENDPOINT' => '/oauth2/v2.0/token', + ); + + // Save the OAuth parameters to the WordPress options table. + update_option( 'postman_office365_oauth', $oauth_data ); + } + } + + + + /** + * Handles the removal of Gmail OAuth credentials from the WordPress database. + * + * This function processes a form submission to delete the stored OAuth access token + * and user email associated with Gmail API integration. It validates the request's + * nonce for security, performs the deletion, and redirects the user back to the settings + * page with a success message. + */ + public function post_smtp_remove_oauth_action() { + // Verify the nonce to ensure the request is secure and valid. + if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'remove_oauth_action' ) ) { + wp_die( esc_html__( 'Nonce verification failed. Please try again.', 'post-smtp' ) ); + } + + // Remove the OAuth access token option from the WordPress database. + delete_option( 'postman_auth_token' ); + + // Redirect the user back to the settings page with a success query parameter. + wp_redirect( admin_url( "admin.php?socket=gmail_api&step=2&page=postman/configuration_wizard" ) ); + + // Terminate script execution to prevent further processing after the redirect. + exit; + } + + /** + * Handles the OAuth redirect, retrieves the token parameters from the URL, + * saves them in WordPress options, and redirects the user to a settings page. + * + * This function is used when OAuth authorization is completed and the user is + * redirected back with the access token, refresh token, expiration time, message, + * and user email. It sanitizes the URL parameters and saves them to the WordPress + * options table to be used later in the application. + * + * After processing, the user is redirected to a settings page for confirmation. + */ + public function handle_gmail_oauth_redirect() { + // Check if the required OAuth parameters are present in the URL. + if ( isset( $_GET['action'] ) && $_GET['action'] === 'gmail_oauth_redirect' ) { + + // Capability check: Only allow administrators to update OAuth tokens + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'post-smtp' ) ); + } + + // CSRF protection: Verify nonce (required by security report) + if ( ! isset( $_GET['_wpnonce'] ) || empty( $_GET['_wpnonce'] ) ) { + wp_die( esc_html__( 'Security check failed. Nonce is missing.', 'post-smtp' ) ); + } + + // Verify the nonce + $nonce = sanitize_text_field( $_GET['_wpnonce'] ); + if ( ! wp_verify_nonce( $nonce, 'gmail_oauth_redirect' ) ) { + wp_die( esc_html__( 'Security check failed. Invalid nonce. Please try again.', 'post-smtp' ) ); + } + + // Sanitize and retrieve URL parameters + $access_token = isset( $_GET['access_token'] ) ? sanitize_text_field( $_GET['access_token'] ) : null; + $refresh_token = isset( $_GET['refresh_token'] ) ? sanitize_text_field( $_GET['refresh_token'] ) : null; + $expires_in = isset( $_GET['expires_in'] ) ? intval( $_GET['expires_in'] ) : 0; + $msg = isset( $_GET['msg'] ) ? sanitize_text_field( $_GET['msg'] ) : ''; + $user_email = isset( $_GET['user_email'] ) ? sanitize_email( $_GET['user_email'] ) : ''; + $auth_token_expires = time() + $expires_in; + + if ( $access_token ) { + $oauth_data = array( + 'access_token' => $access_token, + 'refresh_token' => $refresh_token, + 'auth_token_expires'=> $auth_token_expires, + 'vendor_name' => 'google', + 'user_email' => $user_email, + ); + // Save the OAuth parameters to the WordPress options table. + update_option( 'postman_auth_token', $oauth_data ); + } + } + } + + + +} + +new Post_SMTP_New_Wizard(); + +endif; \ No newline at end of file diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/css/images/office-once-click.gif b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/css/images/office-once-click.gif new file mode 100644 index 0000000..1e5e99b Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/css/images/office-once-click.gif differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/css/wizard.css b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/css/wizard.css new file mode 100644 index 0000000..cb10733 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/css/wizard.css @@ -0,0 +1,1048 @@ +@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); +.admin_page_postman-configuration_wizard { + -ms-overflow-style: none; /* Internet Explorer 10+ */ + scrollbar-width: none; /* Firefox */ +} +.admin_page_postman-configuration_wizard::-webkit-scrollbar { + display: none; /* Safari and Chrome */ +} + +.ps-logo { + text-align: center; + margin: 50px 0; +} + +.ps-wizard-outer { + border: 2px solid #375caf; + border-radius: 7px; + width: 875px; + margin: 0 auto; +} + +.ps-wizard-nav { + width: 32%; + float: left; +} + +.ps-wizard-pages { + width: 67%; + float: right; +} + +.ps-wizard-section { + margin: 25px 0; +} + +.ps-wizard-footer { + background: #f1f1f1; + padding: 17px 0; +} + +.ps-wizard-nav { + border-right: 1px solid #d9d9d9; +} + +.ps-wizard-section .ps-wizard-nav { + height: 484px; +} + +.smtp-outer .ps-wizard-section .ps-wizard-nav { + height: 978px; +} + +.gmail_api-outer .ps-wizard-section .ps-wizard-nav { + height: 1087px; +} + +.mandrill_api-outer .ps-wizard-section .ps-wizard-nav { + height: 676px; +} + +.sendgrid_api-outer .ps-wizard-section .ps-wizard-nav { + height: 676px; +} + +.mailersend_api-outer .ps-wizard-section .ps-wizard-nav { + height: 676px; +} + +.mailgun_api-outer .ps-wizard-section .ps-wizard-nav { + height: 904px; +} + +.sendinblue_api-outer .ps-wizard-section .ps-wizard-nav { + height: 724px; +} + +.postmark_api-outer .ps-wizard-section .ps-wizard-nav { + height: 676px; +} + +.sparkpost_api-outer .ps-wizard-section .ps-wizard-nav { + height: 676px; +} + +.elasticemail_api-outer .ps-wizard-section .ps-wizard-nav { + height: 676px; +} + +.office365_api-outer .ps-wizard-section .ps-wizard-nav { + height: 978px; +} + +.zohomail_api-outer .ps-wizard-section .ps-wizard-nav { + height: 1087px; +} + +.aws_ses_api-outer .ps-wizard-section .ps-wizard-nav { + height: 887px; +} + +.mailjet_api-outer .ps-wizard-section .ps-wizard-nav { + height: 778px; +} + +.sendpulse_api-outer .ps-wizard-section .ps-wizard-nav { + height: 775px; +} + +.ps-wizard-footer .ps-wizard-nav { + border-right: none; +} + +.ps-wizard-nav table, +.ps-wizard-footer table { + padding: 0 25px; +} + +.ps-wizard-edit span { + color: #375caf; + font-size: 25px; +} + +.ps-wizard-nav table td, +.ps-wizard-footer table td { + padding: 12px 6px; + vertical-align: middle; +} + +.ps-wizard-circle { + text-align: center; +} + +.ps-active-nav .ps-wizard-circle span.ps-tick:before { + background-color: #375caf; +} + +.ps-in-active-nav .ps-wizard-circle span.ps-tick:before { + background-color: #d9d9d9; +} + +.ps-active-nav .ps-wizard-circle span.ps-tick:before, +.ps-in-active-nav .ps-wizard-circle span.ps-tick:before + { + content: ''; + height: 35px; + width: 35px; + border-radius: 40px; + display: inline-block; + vertical-align: top; + line-height: 1; + margin: 4.4px 4.6px; +} + +.ps-active-nav .ps-wizard-circle span.ps-tick, +.ps-in-active-nav .ps-wizard-circle span.ps-tick + { + display: inline-table; + width: 48px; + height: 48px; +} + +.ps-wizard-circle span.ps-tick { + font-size: 44px; + display: inline-table; + color: #375caf; +} + +.ps-wizard-text { + font-weight: 600; +} + +.ps-wizard-footer-left { + width: 32%; + float: left; +} + +.ps-wizard-footer-right { + float: right; + width: 67%; +} + +.ps-in-active-nav .ps-wizard-edit, +.ps-active-nav .ps-wizard-edit, +.ps-wizard-footer .ps-in-active-nav .ps-wizard-text { + display: none; +} + +.ps-tick { + position: relative; + z-index: 8; +} + +.ps-in-active-nav .ps-wizard-line:after, +.ps-active-nav .ps-wizard-line:after { + content: ''; + position: absolute; + width: 3px; + height: 39px; + left: 23px; + bottom: 41px; + z-index: -3; +} + +.ps-in-active-nav .ps-wizard-line:after { + background: #d9d9d9; +} + +.ps-active-nav .ps-wizard-line:after, +.ps-wizard-line:after { + background: #375caf; +} + +.ps-wizard-footer .ps-active-nav .ps-wizard-line:after { + height: 342px; +} + +.ps-wizard-screens-container { + padding: 0 25px; +} + +.ps-wizard-step { + display: none; +} + +.ps-wizard-pages p { + font-weight: 600; + font-size: 12px; +} + +.ps-wizard-pages a { + color: #000; +} + +.smtp-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 842px !important; +} + +.gmail_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 1088px !important; +} + +.mandrill_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 540px !important; +} + +.sendgrid_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 608px !important; +} + +.mailersend_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 608px !important; +} + +.mailgun_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 770px !important; +} + +.sendinblue_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 590px !important; +} + +.resend_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 583px !important; +} + +.postmark_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 540px !important; +} + +.sparkpost_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 540px !important; +} + +.elasticemail_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 540px !important; +} + +.office365_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 1047px !important; +} + +.zohomail_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 950px !important; +} + +.aws_ses_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 750px !important; +} + +.mailjet_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 645px !important; +} + +.sendpulse_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 640px !important; +} +.emailit_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 494px !important; +} +.maileroo_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 494px !important; +} +.mailtrap_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 494px !important; +} +.sweego_api-outer .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 494px !important; +} +.gmail-enabled .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 1021px !important; +} +.office-enabled .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 840px !important +} + +/* .ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after { + height: 429px !important; +} */ + +.ps-wizard-footer-left .ps-in-active-nav .ps-email-tester-line.ps-wizard-line:after { + height: 417px !important; +} + +.ps-wizard-sockets { + display: flex; + margin: 15px 0 15px 0; +} + +.ps-wizard-socket-radio label { + margin: 0; + overflow: hidden; + position: relative; +} + +.ps-wizard-socket-radio img { + width: 31px; + cursor: pointer; + transition: transform 1s; + object-fit: cover; + padding: 8px 20px 3px 20px; +} + +.ps-wizard-socket-tick-container { + transition: .5s ease; + opacity: 0; + position: absolute; + top: 29%; + left: 29%; + transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + cursor: pointer; +} + +.ps-wizard-socket-check:checked + label > .ps-wizard-socket-tick-container { + opacity: 1; +} + +.ps-wizard-socket-radio { + border: 2px solid #000; + width: 100px; + height: 66px; + margin-right: 15px; +} + +.ps-wizard-socket-radio input { + display: none!important; +} + +.ps-wizard-socket-radio label { + margin: 0!important; + display: inline-block; +} + +.ps-wizard-socket-tick span { + font-size: 15px; + background-color: #4caf50; + color: #fff; + border-radius: 100%; + height: 15px; + width: 15px; + border: 2px solid #fff; +} + +.ps-wizard-socket-radio-outer { + text-align: center; +} + +.ps-wizard-sockets h4 { + margin: 0; +} + +.ps-wizard-socket-radio:has(.ps-wizard-socket-check:checked) { + border: 2px solid #4db556; +} + +.button-primary.ps-blue-btn { + border: #485b87; + background: #375caf; + border-radius: 0px; + line-height: 40px; + width: 184px; +} + +.button-primary.ps-blue-btn.focus, +.button-primary.ps-blue-btn.hover, +.button-primary.ps-blue-btn:focus, +.button-primary.ps-blue-btn:hover { + background: #4c6fbd; + border-color: #4c6fbd; +} + +.button-primary.ps-yellow-btn { + border: #ff9900; + background: #fa8900; + border-radius: 50px; + line-height: 35px; + width: 170px; + color: #000 !important; +} + +.button-primary.ps-yellow-btn.focus, +.button-primary.ps-yellow-btn.hover, +.button-primary.ps-yellow-btn:focus, +.button-primary.ps-yellow-btn:hover { + background: #ffac31; + border-color: #000000; +} + +.button-primary.ps-blue-btn .dashicons, +.button-primary.ps-yellow-btn .dashicons { + vertical-align: middle; + font-size: 15px; +} + +.button-primary { + text-align: center; +} + +.ps-wizard-footer-right button { + float: right; +} + +.ps-wizard-footer-right .ps-wizard-step-1, +.ps-wizard-footer-right .ps-wizard-step-2, +.ps-wizard-footer-right .ps-wizard-step-3, +.ps-wizard-footer-right .ps-wizard-step-4 { + padding: 15px 10px; +} + +.ps-wizard-error { + color: red; +} + +.ps-wizard-success { + color: green; +} + +.ps-wizard-error, +.ps-wizard-success { + display: inline-block; + font-weight: 600;; +} + +.ps-loading-test-report { + display: inline-flex; + align-items: center; +} + +.ps-wizard-pages { + min-height: 351px; +} + +.ps-wizard-edit .dashicons-edit { + cursor: pointer; +} + +.ps-wizard-socket { + display: none; +} + +.ps-wizard-back { + font-size: 12px; + text-decoration: none; + color: #375caf!important; +} + +.ps-wizard-back span { + font-size: 13px; + vertical-align: sub; +} + +.ps-wizard-socket h3 { + margin: 5px 0; +} + +.ps-form-ui label { + font-weight: 600; +} + +.ps-form-ui input[type="text"], +.ps-form-ui select { + width: 100%!important; + max-width: 100%!important; + height: 37px; + margin-top: 5px; + border: 1px solid #000; + border-radius: 0; +} + +.ps-form-control { + margin-bottom: 25px; +} + +.ps-form-control-info { + color: #979797; + font-size: 10px; +} + +.ps-wizard-socket { + line-height: 22px; +} + +.ps-form-switch-control { + display: inline-block; +} + +.ps-form-switch-control .ps-switch-1 input:checked + .slider { + background-color: #375caf; +} + +.ps-wizard-congrates { + float: left; +} + +.ps-wizard-view-logs { + float: right; +} + +.ps-wizard-pages .ps-wizard-step-4 a { + color: #375caf; +} + +.ps-wizard-card { + background: whitesmoke; + padding: 8px 15px; +} + +.ps-wizard-card p { + margin-bottom: 30px; +} + +.ps-wizard-page-footer { + width: 875px; + text-align: center; + margin: 45px auto; +} + +.ps-wizard-page-footer a { + margin: 0 25px; + color: #949494; +} + +.ps-wizard-footer .ps-active-nav .ps-wizard-circle span.ps-tick:before { + content: "\f12a"; + background-color: transparent; + margin: 0; + height: auto; + width: auto; +} + +.ps-pro-extension-outer { + position: relative; +} + +.ps-pro-extension-tag { + position: absolute; + left: 0; + top: 0; + background: #FF9900; + color: #ffffff; +} + +.ps-pro-extension-tag { + position: absolute; + left: 1px; + top: 1px; + background: #FF9900; + color: #ffffff; + font-size: 11px; + font-weight: bold; + font-family: sans-serif; + padding: 0px 3px; +} + +.ps-pro-popup-overlay { + display: none; + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + background: #bfbfbfa1; + z-index: 9990; +} + +.ps-pro-popup-container { + position: relative; + width: 100%; + height: 100%; +} + +.ps-pro-popup-outer { + position: absolute; + width: 550px; + height: 400px; + background: #fff; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; + border-radius: 7px; +} + +span.ps-pro-close-popup { + position: absolute; + right: 25px; + top: 25px; + color: #222222; + border: 1px solid #e2e4ea; + border-radius: 50px; + cursor: pointer; +} + +.ps-pro-popup-body { + position: relative; + line-height: 30px; +} + +.ps-pro-popup-content { + width: 100%; + text-align: center; + padding: 30px 90px 24px; + box-sizing: border-box; +} + +.ps-pro-popup-content h1 { + color: #214A72; + font-weight: 500; + font-size: 20px; + margin: 15px 0; + line-height: 26px; + padding: 0; +} + +.ps-pro-popup-content p { + font-size: 11px; + color: #6A788B; + margin: 25px 0; + font-weight: 400; + width: 75%; + margin: 25px auto; +} + +.ps-pro-promo-area { + margin: 10px 0; + display: flex; + justify-content: center; + position: relative; +} + +.ps-pro-promo-area p { + color: #214a72; + font-size: 12px; + margin: 0 auto; +} + +.ps-pro-promo-area b { + font-weight: bolder; +} + +.ps-pro-coupon { + background: #5e7cbf; + display: inline-block; + padding: 0px 35px 0 14px; + border-radius: 7px; + position: relative; + overflow: hidden; + border: 1px solid #5E7CBF; +} + +.ps-pro-coupon b { + color: #fff; +} + +.ps-pro-discount { + background: #121FCF; + background: linear-gradient(298.51deg, #8ED2F5 -7.43%, #46519E 78.45%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-weight: bolder; +} +#ps-pro-code-copy-notification .dashicons { + vertical-align: middle; +} + +.ps-click-to-copy { + vertical-align: sub; +} + +.ps-click-to-copy { + cursor: pointer; +} + +.ps-wizard-connectivity-information { + border: 1px solid #EFB3B3; + padding: 8px; + background: #FFE4E4; + color: #000; + margin-top: 15px; +} + +.ps-wizard-connectivity-information .dashicons { + color: #E57373; +} + +.ps-wizard-outer.smtp2go_api-outer .ps-wizard-footer-left .ps-wizard-line::after { + height: 534px !important; +} +.ps-wizard-outer.default-outer .ps-wizard-footer-left .ps-wizard-line::after { + height: 418px !important; +} + +.ps-wizard-pro-tag { + background: #ffbf00; + color: #ffffff; + font-size: 11px; + padding: 0px 8px; + border-radius: 50px; +} +.ps-enable-gmail-one-click.disabled { + pointer-events: all; + opacity: 0; + cursor: not-allowed; +} +.ps-hidden { + display: none; +} + +.ps-office365-btn{ + background-color: #4285f4 !important; + border-radius: 0px !important; + line-height: 40px !important; + font-size: 15px !important; + width: 215px; + display: inline-flex !important; + align-items: center; + text-decoration: none; + height: 50px; +} +.ps-office365-btn::before { + content: ''; + font-size: 20px; + display: inline-block; + background-size: auto; + background-repeat: no-repeat; + width: 36px; + height: 34px; + margin-right: 10px; + background-color: white; +} + +.ps-gmail-btn{ + background-color: #4285f4 !important; + border-radius: 0px !important; + line-height: 40px !important; + font-size: 15px !important; + width: 184px; + display: inline-flex !important; + align-items: center; + text-decoration: none; +} + +.ps-gmail-btn::before { + content: ''; + display: inline-block; + background-size: contain; + background-repeat: no-repeat; + width: 35px; + height: 20px; + margin-right: 10px; + background-color: white; + padding-top: 5px; +} +.ps-remove-gmail-btn{ +} + +.ps-remove-office365-btn{ + background: none !important; + color: red !important; + font-size: 10px !important; + margin-left: 20px !important; + border: none !important; + margin-top: 30px !important; + text-decoration: underline !important; +} + + +.ps-wizard-socket .ps-remove-gmail-btn{ + margin-top:20px !important +} +.ps-disable-gmail-setup b{ + display: inline-block; + margin-left: 5px; + margin-top: 30px !important; + color: green; +} +.ps-connect-with{ + margin-left: 20px; +} + +/* Lets make wiz3rd responsive */ +.ps-dns-results p { + margin: 0; +} + +.ps-dns-heading { + border-left: 2px solid #3a5eaf; + background: #d8e1e8; + color: #585858; + padding: 7px 15px; +} + +.ps-dns-results { + width: 510px; +} + +.ps-dns-record { + border-left: 2px solid #d9d9d9; + border-bottom: 2px solid #d9d9d9; + padding: 12px 13px; + position: relative; +} + +.ps-dns-record p { + color: #6E6E6E; + font-size: 11px; + font-weight: 450; +} + +.ps-dns-record b { + color: #6E6E6E; + font-size: 11px; + font-weight: bold; +} + +.ps-dns-footer { + font-size: 11px; + font-weight: bold; + color: #6E6E6E; + margin-top: 15px; + display: block; +} + +.ps-dns-footer a { + color: #5171b9; + font-weight: bold; +} + +.ps-dns-footer span { + font-size: 18px; + color: #375caf; + vertical-align: middle; +} + +.ps-dns-pass { + color: #74B27B; +} + +.ps-dns-fail { + color: #e57373; +} + +.ps-dns-pass, +.ps-dns-fail { + text-transform: capitalize; +} + +.ps-dns-status-icon { + position: absolute; + left: -10px; + top: 0; + bottom: 0; + margin: auto; + font-size: 17px; +} +.ps-pro-popup-body .ps-pro-popup-content *:not(.dashicons){ + font-family: "Poppins", sans-serif; +} +.ps-pro-popup-content h4 { + font-weight: 400; + font-size: 14px; + color: #6A788B; + margin: 0; + line-height: 100%; +} + +.ps-pro-popup-content .smily strong { + background: -webkit-linear-gradient(0deg, #46519E 50%, #8ED2F5 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + font-weight: 700; +} + +.ps-pro-popup-content .smily { + font-size: 14px; + font-weight: 700; +} + +.ps-pro-popup-body .ps-pro-popup-content strong { + font-weight: 700; +} +.ps-pro-coupon span.copy-icon { + position: absolute; + width: 25px; + height: 100%; + background: #D3E1FF; + right: 0; + display: flex; + top: 0; + align-items: center; + justify-content: center; + color: #5E7CBF; +} +.ps-pro-coupon span.copy-icon svg { + width: 15px; + height: 15px; +} +.ps-pro-popup-content a.button { + font-weight: 600; + color: #fff !important; + padding: 12px 28px; + width: auto; + line-height: normal; +} +div#ps-pro-code-copy-notification { + position: absolute; + color: rgb(179, 213, 182); + border-radius: 3px; + right: 0; + left: 85%; + bottom: 4px; + margin: auto; + width: 100px; + font-size: 11px; + border: 1px solid rgb(179, 213, 182); + line-height: 22px; + background: rgb(225, 253, 228); + display: none; +} +/* Lets make wizard responsive */ + +.wizard-btn-css{ + background: none !important; + color: red !important; + font-size: 10px !important; + margin-left: 100px; +} +.wizard-btn{ + margin-left: 0px !important; +} +.icon-circle { + width: 24px; + height: 24px; + background-color: #28a745; + border-radius: 50%; + display: inline-flex; + align-items: center; + justify-content: center; + margin-top: 4px; + flex-shrink: 0; +} + +.icon-check { + width: 6px; + height: 12px; + border: solid #fff; + border-width: 0 2px 2px 0; + transform: rotate(45deg); + display: inline-block; +} +.ps-wizard-send-test-email:disabled{ + background: #cccccc; + border: 1px solid #999999; + color: #666666; + cursor: not-allowed; + opacity: 0.6; +} + +.ps-disable-office365-setup b{ + display: inline-block; + margin-left: 5px; + margin-top: 30px !important; + color: green; +} + +/* Office 365 Business Plan Upgrade Styles */ +.ps-office365-upgrade-required { + + cursor: not-allowed; +} + +.ps-office365-upgrade-required input[type="checkbox"] { + pointer-events: none; +} + +label.ps-office365-upgrade-required:hover:before { + content: ""; + position: absolute; + left: 160px; + right: 0; + width: 400px; + height: 288px; + background: url(images/office-once-click.gif) no-repeat #ffff; + box-shadow: 0px 3px 36px -7px #000; + border-radius: 5px; + z-index: 2; + top: -40px; + background-size: 100%; + +} +.ps-wizard .ps-wizard-footer .ps-wizard-nav .ps-wizard-line:after{ + height: 540px; +} +.ps-wizard .ps-wizard-send-email .ps-wizard-footer .ps-wizard-nav .ps-wizard-line:after{ + height: 345px; +} +span.ps-wizard-line:after { + content: ''; + position: absolute; + width: 3px; + height: 39px; + left: 23px; + bottom: 41px; + z-index: -3; +} + +/* Lets make wizard responsive */ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/amazon-popup.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/amazon-popup.png new file mode 100644 index 0000000..418228f Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/amazon-popup.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/amazon.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/amazon.png new file mode 100644 index 0000000..cc25db0 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/amazon.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/android-icon.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/android-icon.png new file mode 100644 index 0000000..39a347e Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/android-icon.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/apple-icon.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/apple-icon.png new file mode 100644 index 0000000..96d5e81 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/apple-icon.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/brevo.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/brevo.png new file mode 100644 index 0000000..f22d00b Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/brevo.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/elasticemail-.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/elasticemail-.png new file mode 100644 index 0000000..0f1e697 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/elasticemail-.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/elasticemail.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/elasticemail.png new file mode 100644 index 0000000..c221d1a Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/elasticemail.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/emailit.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/emailit.png new file mode 100644 index 0000000..836c52f Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/emailit.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/gmail.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/gmail.png new file mode 100644 index 0000000..5b76e65 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/gmail.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/google.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/google.png new file mode 100644 index 0000000..f6c07a3 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/google.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/maileroo.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/maileroo.png new file mode 100644 index 0000000..6ddc10d Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/maileroo.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailersend.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailersend.png new file mode 100644 index 0000000..b0ef565 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailersend.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailgun.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailgun.png new file mode 100644 index 0000000..602789f Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailgun.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailjet.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailjet.png new file mode 100644 index 0000000..544f9e5 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailjet.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailtrap.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailtrap.png new file mode 100644 index 0000000..a84ea6d Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mailtrap.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mandrill.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mandrill.png new file mode 100644 index 0000000..0b08f5a Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/mandrill.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/ms365-popup.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/ms365-popup.png new file mode 100644 index 0000000..7afe300 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/ms365-popup.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/ms365.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/ms365.png new file mode 100644 index 0000000..0b739e8 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/ms365.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/postmark.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/postmark.png new file mode 100644 index 0000000..9cd31b1 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/postmark.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/resend.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/resend.png new file mode 100644 index 0000000..a8150ad Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/resend.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sendgrid.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sendgrid.png new file mode 100644 index 0000000..20bed38 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sendgrid.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sendpulse.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sendpulse.png new file mode 100644 index 0000000..1c4957e Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sendpulse.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/smtp.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/smtp.png new file mode 100644 index 0000000..23ec4c2 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/smtp.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/smtp2go.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/smtp2go.png new file mode 100644 index 0000000..b4be3c2 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/smtp2go.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sparkpost.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sparkpost.png new file mode 100644 index 0000000..a2ef6ec Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sparkpost.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sweego.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sweego.png new file mode 100644 index 0000000..c0ba2d5 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/sweego.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/wizard-google.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/wizard-google.png new file mode 100644 index 0000000..f639daf Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/wizard-google.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/zoho-popup.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/zoho-popup.png new file mode 100644 index 0000000..fa599e7 Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/zoho-popup.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/zoho.png b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/zoho.png new file mode 100644 index 0000000..78f272c Binary files /dev/null and b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/images/zoho.png differ diff --git a/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/js/wizard.js b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/js/wizard.js new file mode 100644 index 0000000..ad929f2 --- /dev/null +++ b/html/wp-content/plugins/post-smtp/Postman/Wizard/assets/js/wizard.js @@ -0,0 +1,1065 @@ +jQuery( document ).ready(function() { + jQuery( '.ps-wizard-socket-check:checked' ).siblings( '.ps-wizard-socket-tick-container' ).css( { 'opacity': 1 } ); + + jQuery( document ).on( 'click', '.ps-wizard-socket-radio label', function() { + + jQuery( '.ps-wizard-socket-tick-container' ).css( { 'opacity': 0 } ); + jQuery( this ).find( '.ps-wizard-socket-tick-container' ).css( { 'opacity': 1 } ); + + } ) + + var enabled_gmail = jQuery('.ps-enable-gmail-one-click').is(':checked'); + if (enabled_gmail) { + jQuery('.gmail_api-outer').addClass('gmail-enabled'); + } + + var enabled_office = jQuery('.ps-enable-office365-one-click').is(':checked'); + if (enabled_office) { + jQuery('.office365_api-outer').addClass('office-enabled'); + } + + jQuery(document).on('click', 'table tr:last-child .ps-wizard-edit', function (e) { + e.preventDefault(); + jQuery('.ps-wizard-outer').addClass('ps-wizard-send-email'); + }); + + /** + * Refresh the wizard to show the current step + * + * @return void + * @since 2.0.0 + * @version 1.0.0 + */ + const refreshWizard = function() { + + var tableRow = jQuery( '.ps-wizard-nav table tr.ps-active-nav' ); + var activeTab = jQuery( tableRow ).hasClass( 'ps-active-nav' ); + + if( activeTab ) { + + var stepID = jQuery( tableRow ).find( '.dashicons-edit' ).data( 'step' ); + jQuery( '.ps-wizard-step' ).hide(); + jQuery( `.ps-wizard-step-${stepID}` ).fadeIn( 'slow' ); + + } + + jQuery( '.ps-wizard-line' ).removeClass( 'ps-email-tester-line' ); + jQuery( '.ps-dns-results' ).remove(); + + } + + + /** + * Validate the current step + * + * @param {int} stepID Current Step ID + * @return bool + * @since 2.0.0 + * @version 1.0.0 + */ + const validateStep = function( stepID ) { + + //Validate step 1 + if( stepID == 1 ) { + + if( jQuery( '.ps-wizard-socket-check' ).is( ':checked' ) ) { + + var selectedSocket = jQuery( '.ps-wizard-socket-check:checked' ).val(); + var _element = jQuery( '.ps-wizard-outer' ).removeClass(); + jQuery( _element ).addClass( 'ps-wizard-outer' ); + jQuery( _element ).addClass( `${selectedSocket}-outer` ); + //Remove Warning (if has), and contiue to next step + jQuery( '.ps-wizard-error' ).html( '' ); + jQuery( '.ps-wizard-page-footer' ).fadeOut(); + renderSocketSettings(); + return true; + + } + else { + + jQuery( '.ps-wizard-error' ).html( ` ${PostSMTPWizard.Step1E1}` ); + + } + + } + + //Validate step 2 + if( stepID == 2 ) { + + var selectedSocket = jQuery( '.ps-wizard-socket-check:checked' ).val(); + selectedSocket = jQuery( `.${selectedSocket}` ).find( 'input' ); + var validated = false; + + jQuery( selectedSocket ).each( function( index, element ) { + + var attr = jQuery( element ).attr( 'required' ); + + if( typeof attr !== 'undefined' && attr !== false && jQuery( element ).val() == '' ) { + + var error = jQuery( element ).data( 'error' ); + jQuery( '.ps-wizard-error' ).html( ` ${error}` ); + validated = false; + jQuery( element ).focus(); + return false; + + } + else { + + //Validate From Name, From Email + jQuery( '.ps-name-email-settings' ).find( 'input' ).each( function( index, element ) { + + var attr = jQuery( element ).attr( 'required' ); + + if( typeof attr !== 'undefined' && attr !== false && jQuery( element ).val() == '' ) { + + var error = jQuery( element ).data( 'error' ); + jQuery( '.ps-wizard-error' ).html( ` ${error}` ); + validated = false; + jQuery( element ).focus(); + return false; + + } + else { + + //remove error, since everything is good to go :). + jQuery( '.ps-wizard-error' ).html( '' ); + validated = true; + + } + + } ); + + } + + } ); + + //If everything is good to go, lets save settings. + if( validated === true ) { + + var button = jQuery( '.ps-wizard-step-2' ).find( '.ps-wizard-next-btn' ); + var buttonHTML = jQuery( button ).html(); + jQuery( button ).html( 'Saving...' ); + + // Step 1: Get selected socket from step 1 + var $step1 = jQuery('.ps-wizard-step-1'); + var selectedSocket = $step1.attr('data-socket'); + + if ( selectedSocket ) { + // Convert socket key to match input class (e.g., sendgrid_api -> ps-sendgrid-api-key) + var classSelector = '.ps-' + selectedSocket.replace('_', '-') + '-key'; + var apiKeyInput = jQuery(classSelector); + + if ( apiKeyInput.length > 0 ) { + var apiKey = apiKeyInput.val(); + $step1.attr( 'data-apikey', apiKey ); + } + } + + //Lets AJAX request. + jQuery.ajax( { + + url: ajaxurl, + type: 'POST', + async: true, + data: { + action: 'ps-save-wizard', + FormData: jQuery( '#ps-wizard-form' ).serialize(), + }, + + success: function( response ) { + + jQuery( '.ps-wizard-error' ).html( '' ); + nextStep( stepID ); + var _element = jQuery( '.ps-wizard-outer' ).removeClass(); + jQuery( _element ).addClass( 'ps-wizard-outer ps-wizard-send-email' ); + + }, + error: function( response ) { + + jQuery( '.ps-wizard-error' ).html( ` ${PostSMTPWizard.Step2E3}` ); + + }, + complete: function( response ) { + + jQuery( button ).html( buttonHTML ); + + } + + } ); + + } + + } + + //Validate step 3 | No validation required, we can skip this step. + if( stepID == 3 ) { + + return true; + + } + + } + + + /** + * Switch to next step + * + * @param {int} stepID Current Step ID + * @return void + * @since 2.0.0 + * @version 1.0.0 + */ + const nextStep = function( stepID ) { + + var nextStep = stepID + 1; + + jQuery( `*[data-step="${stepID}"]` ).closest( 'tr' ).removeClass(); + jQuery( `*[data-step="${nextStep}"]` ).closest( 'tr' ).removeClass(); + jQuery( `*[data-step="${nextStep}"]` ).closest( 'tr' ).addClass( 'ps-active-nav' ); + refreshWizard(); + + } + + + /** + * Switch to step + * + * @param {int} stepID Step ID to be switched to + * @return void + * @since 2.0.0 + * @version 1.0.0 + */ + const switchStep = function( stepID ) { + + jQuery( '.ps-wizard-nav table tr.ps-active-nav' ).addClass( 'ps-in-active-nav' ); + jQuery( '.ps-wizard-nav table tr.ps-active-nav' ).removeClass( 'ps-active-nav' ); + jQuery( `*[data-step="${stepID}"]` ).closest( 'tr' ).addClass( 'ps-active-nav' ); + jQuery( '.ps-wizard-success' ).html( '' ); + jQuery( '.ps-wizard-error' ).html( '' ); + jQuery( '.ps-wizard-connectivity-information' ).remove(); + refreshWizard(); + + } + + + /** + * Render Socket Settings + * + * @return void + * @since 2.0.0 + * @version 1.0.0 + */ + const renderSocketSettings = function() { + + var selectedSocket = jQuery( '.ps-wizard-socket-check:checked' ).val(); + jQuery( '.ps-wizard-socket' ).hide(); + jQuery( `.${selectedSocket}` ).fadeIn( 'slow' ); + + } + + /** + * Gets URL Parameter + * + * @return void + * @since 2.0.0 + * @version 1.0.0 + */ + const getUrlParameter = function getUrlParameter(sParam) { + + var sPageURL = window.location.search.substring(1), + sURLVariables = sPageURL.split('&'), + sParameterName, + i; + + for (i = 0; i < sURLVariables.length; i++) { + sParameterName = sURLVariables[i].split('='); + + if (sParameterName[0] === sParam) { + return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); + } + } + return false; + + }; + + //Switch to next step + jQuery( document ).on( 'click', '.ps-wizard-next-btn', function( e ) { + + e.preventDefault(); + + var stepID = jQuery( this ).data( 'step' ); + var selectedSocket = jQuery( '.ps-wizard-socket-check:checked' ).val(); + jQuery('.ps-wizard-step-1').attr('data-socket', selectedSocket); + + if( validateStep( stepID ) === true ) { + + nextStep( stepID ); + + } + var enabled_gmail = jQuery('.ps-enable-gmail-one-click').is(':checked'); + if (enabled_gmail) { + jQuery('.gmail_api-outer').addClass('gmail-enabled'); + } + + var enabled_office = jQuery('.ps-enable-office365-one-click').is(':checked'); + if (enabled_office) { + jQuery('.office365_api-outer').addClass('office-enabled'); + } + + } ); + + + //Switch to step | Edit Step + jQuery( document ).on( 'click', '.ps-wizard-nav table tr td .dashicons-edit, .ps-wizard-back', function( e ) { + + e.preventDefault(); + + var stepID = jQuery( this ).data( 'step' ); + + if( stepID == 1 ) { + + jQuery( '.ps-wizard-page-footer' ).fadeIn( 'slow' ); + + } + + if( stepID !== 2 ) { + + var _element = jQuery( '.ps-wizard-outer' ).removeClass(); + jQuery( _element ).addClass( 'ps-wizard-outer' ); + + } + if( stepID == 2 ) { + + var selectedSocket = jQuery( '.ps-wizard-socket-check:checked' ).val(); + var _element = jQuery( '.ps-wizard-outer' ).removeClass(); + jQuery( _element ).addClass( 'ps-wizard-outer' ); + jQuery( _element ).addClass( `${selectedSocket}-outer` ); + + } + + switchStep( stepID ); + + var enabled_gmail = jQuery('.ps-enable-gmail-one-click').is(':checked'); + if (enabled_gmail) { + jQuery('.gmail_api-outer').addClass('gmail-enabled'); + } + + var enabled_office = jQuery('.ps-enable-office365-one-click').is(':checked'); + if (enabled_office) { + jQuery('.office365_api-outer').addClass('office-enabled'); + } + + } ); + + + //Send test email + jQuery( document ).on( 'click', '.ps-wizard-send-test-email', function( e ) { + + e.preventDefault(); + jQuery('#ps-dns-results__el_id').empty(); + var sendTo = jQuery( '.ps-test-to' ).val(); + var security = jQuery( '#security' ).val(); + var socket = jQuery( '.ps-wizard-step-1' ).attr( 'data-socket' ); + var apikey = jQuery( '.ps-wizard-step-1' ).attr( 'data-apikey' ); + var $btn = jQuery( this ); + $btn.prop( 'disabled', true ); + + if( sendTo == '' ) { + jQuery( '.ps-wizard-error' ).html( ` ${PostSMTPWizard.Step3E4}` ); + return; + + } + + jQuery.ajax( { + + url: ajaxurl, + type: 'POST', + data: { + action: 'postman_send_test_email', + email: sendTo, + security: security, + }, + success: function( response ) { + + jQuery( '.ps-wizard-success' ).html( '' ); + + if( response.success === true ) { + + jQuery( '.ps-wizard-success' ).html( ` ${response.data.message}` ); + jQuery( '.ps-finish-wizard' ).html( `${PostSMTPWizard.finish} ` ); + + jQuery( '.ps-wizard-error' ).html(''); + jQuery( '.ps-wizard-health-report' ).html( + `
        + +

        Please wait, we are checking your email health.

        +
        ` + ); + jQuery.ajax( { + url: ajaxurl, + type: 'POST', + data: { + action: 'ps-mail-test', + email: sendTo, + security: security, + socket: socket, + apikey: apikey + }, + success: function( response ) { + + jQuery( '.ps-loading-test-report' ).remove(); + $btn.prop( 'disabled', false ) + if( response.data.message !== undefined && response.data.message === 'test_email_sent' ) { + + var title = response.data.data.title; + var spf = response.data.data.spf; + var dkim = response.data.data.dkim; + var dmarc = response.data.data.dmarc; + + var successIcon = 'dashicons-yes-alt'; + var warningIcon = 'dashicons-warning'; + var successClass = 'ps-dns-pass'; + var warningClass = 'ps-dns-fail'; + var spfIcon = spf === 'pass' ? `` : ``; + var dkimIcon = dkim === 'pass' ? `` : ``; + var dmarcIcon = dmarc === 'pass' ? `` : ``; + var spfStatus = spf === 'pass' ? 'ps-dns-pass' : 'ps-dns-fail'; + var dkimStatus = dkim === 'pass' ? 'ps-dns-pass' : 'ps-dns-fail'; + var dmarcStatus = dmarc === 'pass' ? 'ps-dns-pass' : 'ps-dns-fail'; + var spfDescription = ''; + var dkimDescription = ''; + var dmarcDescription = ''; + + // SPF + if( spf === 'pass' ) { + spfDescription = 'Great! Your SPF is valid.'; + } + if( spf === 'none' ) { + spfDescription = 'We found an SPF entry on your server but it has still not been propagated.'; + } + if( spf === 'neutral' ) { + spfDescription = 'SPF: sender does not match SPF record (neutral).'; + } + if( spf === 'softfail' ) { + spfDescription = 'SPF: sender does not match SPF record (softfail).'; + } + if( spf === 'permerror' ) { + spfDescription = 'SPF: test of record failed (permerror).'; + } + + // DKIM + if( dkim === 'pass' ) { + dkimDescription = 'Your DKIM signature is valid.'; + } + if( dkim === 'none' ) { + dkimDescription = 'Your message is not signed with DKIM.'; + } + if( dkim === 'fail' ) { + dkimDescription = 'Your DKIM signature is not valid.'; + } + + // DMARC + if( dmarc === 'pass' ) { + dmarcDescription = 'Your message passed the DMARC test.'; + } + if( dmarc === 'missingentry' ) { + dmarcDescription = 'You do not have a DMARC record.'; + } + if( dmarc === 'alignment' ) { + dmarcDescription = 'Your domains are not aligned. We can\'t check DMARC.'; + } + if( dmarc === 'dkimmissing' ) { + dmarcDescription = 'Your message is not signed with DKIM.'; + } + if( dmarc === 'unkown' ) { + dmarcDescription = 'Your message failed the DMARC verification.'; + } + + if( dmarc === 'fail' ) { + dmarcDescription = 'Your message failed the DMARC verification.'; + } + + + var ps_dns_results = `
        +

        ${title}

        +
        + ${spfIcon} + SPF record status: ${spf} +

        SPF record description: ${spfDescription}

        +
        +
        + ${dkimIcon} + DKIM record status: ${dkim} +

        DKIM record description: ${dkimDescription}

        +
        +
        + ${dmarcIcon} + DMARC record status: ${dmarc} +

        DMARC record description: ${dmarcDescription}

        +
        + To check and improve your email spam score! Click Here +
        `; + if ( jQuery( '#ps-dns-results__el_id' ).length ) { + jQuery( '#ps-dns-results__el_id' ).remove(); + } + jQuery( '.ps-wizard-success:nth(0)' ).after( + ps_dns_results + ); + + //jQuery( '.ps-wizard-footer-left .ps-in-active-nav .ps-wizard-line:after' ).css( { 'height': '417px' } ); + jQuery( '.ps-wizard-footer-left' ).find( '.ps-in-active-nav' ).find( '.ps-wizard-line' ).addClass( 'ps-email-tester-line' ); + + } + else { + $btn.prop('disabled', false); + if ( jQuery( '#ps-dns-results__el_id' ).length ) { + jQuery( '#ps-dns-results__el_id' ).remove(); + } + + jQuery( '.ps-wizard-success:nth(0)' ).after( + `
        + Limit Exceed! To check and improve your email spam score! Click Here +
        ` + ); + + } + + }, + error: function(jqXHR, textStatus, errorThrown) { + $btn.prop( 'disabled', false); + jQuery( '.ps-loading-test-report' ).remove(); + if (jqXHR.status === 429) { + + if ( jQuery( '#ps-dns-results__el_id' ).length ) { + jQuery( '#ps-dns-results__el_id' ).remove(); + } + jQuery('.ps-wizard-health-report').after( + `
        + Limit Exceed! Please try again later. + Click Here + +
        ` + ); + } else { + console.log("Error: ", errorThrown); + } + } + } ); + + } + if( response.success === false ) { + $btn.prop( 'disabled', false); + var selectedSocket = jQuery( '.ps-wizard-socket-check:checked' ).val(); + jQuery( '.ps-wizard-error' ).html( ` ${response.data.message}

        ` ); + jQuery( '.ps-wizard-error' ).append( ` Test email failed. Please check and correct your SMTP configuration. The Email Health Checker cannot proceed until a test email is successfully sent.` ); + + if( selectedSocket === 'smtp' ) { + + jQuery( '.ps-wizard-error' ).after( `
        ${PostSMTPWizard.connectivityTestMsg}
        ` ); + + } + + } + + } + + } ); + + } ); + + + //Connect to Office 365 | Auth + jQuery( document ).on( 'click', '#ps-wizard-connect-office365', function( e ) { + + e.preventDefault(); + + var office365_app_id = jQuery( '.ps-office365-client-id' ).val(); + var office365_app_password = jQuery( '.ps-office365-client-secret' ).val(); + var _button = jQuery( this ).html(); + + if( office365_app_id == '' ) { + + jQuery( '.ps-office365-client-id' ).focus(); + return; + + } + if( office365_app_password == '' ) { + + jQuery( '.ps-office365-client-secret' ).focus(); + return; + + } + + jQuery( this ).html( 'Redirecting...' ); + var tenant = PostSMTPWizard.tenantId || 'common'; + var authURL = `https://login.microsoftonline.com/${tenant}/oauth2/v2.0/authorize?state=${PostSMTPWizard.office365State}&scope=openid profile offline_access Mail.Send Mail.Send.Shared&response_type=code&approval_prompt=auto&redirect_uri=${PostSMTPWizard.adminURL}&client_id=${office365_app_id}`; + + jQuery.ajax( { + + url: ajaxurl, + type: 'POST', + async: true, + data: { + action: 'ps-save-wizard', + FormData: jQuery( '#ps-wizard-form' ).serialize(), + }, + + success: function( response ) { + + window.location.assign( authURL ); + + }, + + } ); + + } ); + + + //Connect to Gmail API | Auth + jQuery( document ).on( 'click', '#ps-wizard-connect-gmail', function( e ) { + + e.preventDefault(); + + var clientID = jQuery( '.ps-gmail-api-client-id' ).val(); + var clientSecret = jQuery( '.ps-gmail-client-secret' ).val(); + var redirectURI = jQuery( this ).attr( 'href' ); + + if( clientID == '' ) { + + jQuery( '.ps-gmail-api-client-id' ).focus(); + return; + + } + if( clientSecret == '' ) { + + jQuery( '.ps-gmail-client-secret' ).focus(); + return; + + } + + jQuery( this ).html( 'Redirecting...' ); + + jQuery.ajax( { + + url: ajaxurl, + type: 'POST', + async: true, + data: { + action: 'ps-save-wizard', + FormData: jQuery( '#ps-wizard-form' ).serialize(), + }, + + success: function( response ) { + + window.location.assign( redirectURI ); + + }, + + } ); + + } ); + + //Connect to Zoho | Auth + jQuery( document ).on( 'click', '#ps-wizard-connect-zoho', function( e ) { + + e.preventDefault(); + + var clientID = jQuery( '.ps-zoho-client-id' ).val(); + var clientSecret = jQuery( '.ps-zoho-client-secret' ).val(); + var redirectURI = jQuery( this ).attr( 'href' ); + + if( clientID == '' ) { + + jQuery( '.ps-zoho-client-id' ).focus(); + return; + + } + if( clientSecret == '' ) { + + jQuery( '.ps-zoho-client-secret' ).focus(); + return; + + } + + jQuery( this ).html( 'Redirecting...' ); + + jQuery.ajax( { + + url: ajaxurl, + type: 'POST', + async: true, + data: { + action: 'ps-save-wizard', + FormData: jQuery( '#ps-wizard-form' ).serialize(), + }, + + success: function( response ) { + + window.location.assign( redirectURI ); + + }, + + } ); + + } ); + + refreshWizard(); + + if( getUrlParameter( 'socket' ) ) { + + jQuery( document ).scrollTop( jQuery( document ).height() ); + + } + + jQuery( document ).on( 'click', '.ps-pro-extension-outer', function(){ + + var placeholder = jQuery( this ).find( 'h4' ).text(); + var imgSrc = jQuery( this ).find( 'img' ).attr( 'src' ); + var productURL = jQuery( this ).data( 'url' ); + imgSrc = imgSrc.replace( '.png', '-popup.png' ); + + console.log(placeholder); + // placeholder = "Google Mailer Setup?"; + if(placeholder == "Amazon SES") { + placeholder = 'Amazon SES Mailer?'; + } + if(placeholder == "Zoho") { + placeholder = 'Zoho Mailer?'; + } + if(placeholder == "Microsoft 365") { + placeholder = 'Microsoft 365 One-Click / Manual Setup?'; + } + + jQuery( '.ps-pro-for-img' ).attr( 'src', imgSrc ); + jQuery( '.ps-pro-product-url' ).attr( 'href', productURL ); + jQuery( '.ps-pro-for' ).html( placeholder ); + jQuery( '.ps-pro-popup-overlay' ).fadeIn(); + + } ); + + + jQuery(document).on('click', '.ps-enable-gmail-one-click', function (e) { + + if (jQuery(this).hasClass('disabled')) { + e.preventDefault(); + var data = jQuery('#ps-one-click-data').val(); + var parsedData = JSON.parse(data); + jQuery('.ps-pro-for-img').attr('src', parsedData.url); + jQuery('.ps-pro-product-url').attr('href', parsedData.product_url); + jQuery('.ps-pro-for').html(parsedData.transport_name); + jQuery( '.ps-pro-popup-overlay' ).fadeIn(); + + return; + } + jQuery(this).prop('disabled', false); + jQuery(this).removeClass('disabled'); + + var enabled = jQuery(this).is(':checked'); + if (enabled) { + jQuery('.ps-disable-gmail-setup').show(); + jQuery('.gmail_api-outer').addClass('gmail-enabled'); + jQuery('.ps-disable-one-click-setup').hide(); + jQuery('.ps-gmail-api-client-id').removeAttr('required'); + jQuery('.ps-gmail-api-client-secret').removeAttr('required') + jQuery('#ps-gmail-auth-buttons').show(); + } else { + jQuery('.gmail_api-outer').removeClass('gmail-enabled'); + jQuery('.ps-disable-one-click-setup').show(); + jQuery('.ps-disable-gmail-setup').hide(); + jQuery('.ps-gmail-api-client-id').attr('required', 'required'); + jQuery('#ps-gmail-auth-buttons').hide(); + } + + jQuery.ajax({ + url: ajaxurl, + type: 'POST', + async: true, + data: { + action: 'update_post_smtp_pro_option', + enabled: enabled ? 'gmail-oneclick' : '', + _wpnonce: (typeof PostSMTPWizard !== 'undefined' && PostSMTPWizard.pro_option_nonce) ? PostSMTPWizard.pro_option_nonce : '' + }, + success: function(response) { + if (response.success) { + console.log('Option updated successfully!'); + } else { + console.log('Failed to update option.'); + } + } + }); + }); + + jQuery( document ).on( 'click', '.ps-pro-close-popup', function( e ){ + + e.preventDefault(); + jQuery( '.ps-pro-popup-overlay' ).fadeOut(); + + } ); + + jQuery( '.ps-click-to-copy' ).click( function() { + + // Get the coupon code text + var couponCode = jQuery( '.ps-pro-coupon-code' ).text(); + + // Create a temporary textarea element to copy the text + var $temp = jQuery( ' + +

        + +